Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adjust material size for melting for armor parts, weapons, trap components and tools... #4958

Merged
merged 18 commits into from
Sep 28, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Template for new versions:
## New Tools

## New Features
- `tweak`: ``material-size-for-melting``: change melting return for inorganic armor parts, shields, weapons, trap components and tools to stop smelters from creating metal, bring melt return for adamantine in line with other metals to ~95% of forging cost. wear reduces melt return by 10% per level

## Fixes

Expand Down
11 changes: 11 additions & 0 deletions docs/plugins/tweak.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ Commands
Names filled waterskins, flasks, and vials according to their contents,
the same way other containers such as barrels, bins, and cages are named.
(:bug:`4914`)
``material-size-for-melting``
Birkow marked this conversation as resolved.
Show resolved Hide resolved
Changes how item size for melting is calculated. Affects weapons, shields,
armor parts, tools, trap components including items made from adamantine.
As result base return for melting is equal to 95% of production cost.
Each level of wear decreases melt return by further 10%.
Limitation of melting return being handled by game in 0,3 bar increments is
solved by adding random component to material size. E.g. for cap with item
size 1 melting return will be equal to 0,9 bar base return with 16,(6)%
chance for additional 0,3 bar. As result average return for melting cap
will be ~0,95 bar.
(:bug:`6027`).
Birkow marked this conversation as resolved.
Show resolved Hide resolved
``named-codices``
Displays titles for books instead of the default material description.
``partial-items``
Expand Down
11 changes: 11 additions & 0 deletions plugins/tweak/tweak.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ using namespace DFHack;
#include "tweaks/eggs-fertile.h"
#include "tweaks/fast-heat.h"
#include "tweaks/flask-contents.h"
#include "tweaks/material-size-for-melting.h"
#include "tweaks/named-codices.h"
#include "tweaks/partial-items.h"
#include "tweaks/reaction-gloves.h"
Expand Down Expand Up @@ -74,6 +75,16 @@ DFhackCExport command_result plugin_init(color_ostream &out, vector<PluginComman

TWEAK_HOOK("reaction-gloves", reaction_gloves_hook, produce);

TWEAK_HOOK("material-size-for-melting", material_size_for_melting_armor_hook, getMaterialSizeForMelting);
TWEAK_HOOK("material-size-for-melting", material_size_for_melting_gloves_hook, getMaterialSizeForMelting);
TWEAK_HOOK("material-size-for-melting", material_size_for_melting_shoes_hook, getMaterialSizeForMelting);
TWEAK_HOOK("material-size-for-melting", material_size_for_melting_helm_hook, getMaterialSizeForMelting);
TWEAK_HOOK("material-size-for-melting", material_size_for_melting_pants_hook, getMaterialSizeForMelting);
TWEAK_HOOK("material-size-for-melting", material_size_for_melting_weapon_hook, getMaterialSizeForMelting);
TWEAK_HOOK("material-size-for-melting", material_size_for_melting_trapcomp_hook, getMaterialSizeForMelting);
TWEAK_HOOK("material-size-for-melting", material_size_for_melting_tool_hook, getMaterialSizeForMelting);
rng.init();
Birkow marked this conversation as resolved.
Show resolved Hide resolved

return CR_OK;
}

Expand Down
65 changes: 65 additions & 0 deletions plugins/tweak/tweaks/material-size-for-melting.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include <cmath>

#include "modules/Materials.h"
#include "modules/Random.h"

#include "df/inorganic_raw.h"
#include "df/item_armorst.h"
#include "df/item_constructed.h"
#include "df/item_glovesst.h"
#include "df/item_helmst.h"
#include "df/item_pantsst.h"
#include "df/item_shieldst.h"
#include "df/item_shoesst.h"
#include "df/item_toolst.h"
#include "df/item_trapcompst.h"
#include "df/item_weaponst.h"

static Random::MersenneRNG rng;
static float get_random() {
return static_cast <float> (rng.drandom1());
}
Birkow marked this conversation as resolved.
Show resolved Hide resolved

static int32_t get_material_size_for_melting(df::item_constructed *item, int32_t base_material_size, float production_stack_size) {
const float melt_return_per_material_size = 0.3f, base_melt_recovery = 0.95f, loss_per_wear_level = 0.1f;

if (item->mat_type == 0) // INORGANIC only
{
float calculated_size, forging_cost_per_item;

auto inorganic = df::inorganic_raw::find(item->mat_index);
if (inorganic && inorganic->flags.is_set(df::inorganic_flags::DEEP_SPECIAL)){
//adamantine items
forging_cost_per_item = static_cast<float>(base_material_size) / production_stack_size;
}
else {
// non adamantine items
forging_cost_per_item = std::max(std::floor(static_cast<float>(base_material_size) / 3.0f), 1.0f);
forging_cost_per_item /= production_stack_size;
}
calculated_size = forging_cost_per_item / melt_return_per_material_size;
float melt_recovery = base_melt_recovery - static_cast<float>(item->wear) * loss_per_wear_level;
calculated_size *= melt_recovery;
int32_t random_part = ((modff(calculated_size, &calculated_size) > get_random()) ? 1 : 0);
return static_cast<int32_t>(calculated_size) + random_part;
}
return base_material_size;
Birkow marked this conversation as resolved.
Show resolved Hide resolved
}

#define DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(TYPE, PRODUCTION_STACK_SIZE) \
struct material_size_for_melting_##TYPE##_hook : df::item_##TYPE##st {\
typedef df::item_##TYPE##st interpose_base;\
DEFINE_VMETHOD_INTERPOSE(int32_t, getMaterialSizeForMelting, ()) {\
return get_material_size_for_melting(this, INTERPOSE_NEXT(getMaterialSizeForMelting)(),PRODUCTION_STACK_SIZE);\
Birkow marked this conversation as resolved.
Show resolved Hide resolved
}\
};\
IMPLEMENT_VMETHOD_INTERPOSE(material_size_for_melting_##TYPE##_hook, getMaterialSizeForMelting);

DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(armor, 1.0f)
DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(gloves, 2.0f)
DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(shoes, 2.0f)
DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(helm, 1.0f)
DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(pants, 1.0f)
DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(weapon, 1.0f)
DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(trapcomp, 1.0f)
DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(tool, 1.0f)
Comment on lines +62 to +69
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can these vary if the game is modded?

Copy link
Contributor Author

@Birkow Birkow Sep 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No idea, will have to look into it and probably factor in if reaction-gloves tweak is enabled. It looks like it could alter how many gloves are produced in custom reactions.

Copy link
Contributor Author

@Birkow Birkow Sep 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting forging cost for modded in items created in custom reactions should be possible. If vanilla items are created in modded reactions this can be challenging. Not sure if it is possible to determine what reaction was used to create item if multiple ones exist with different forging cost per item. Probably should use one with lowest forging unit cost as base.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added information in description that melting returns are calculated for base game production cost., Might not be correct for modded items or custom reactions.