Skip to content

Commit 77817be

Browse files
authored
Merge pull request #4958 from Birkow/tweak/material_size_for_melting
adjust material size for melting for armor parts, weapons, trap components and tools...
2 parents 9c69796 + 6b553c6 commit 77817be

4 files changed

Lines changed: 93 additions & 0 deletions

File tree

docs/changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ Template for new versions:
5454
## New Tools
5555

5656
## New Features
57+
- `tweak`: ``realistic-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
5758

5859
## Fixes
5960

docs/plugins/tweak.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,19 @@ Commands
5353
Names filled waterskins, flasks, and vials according to their contents,
5454
the same way other containers such as barrels, bins, and cages are named.
5555
(:bug:`4914`)
56+
``realistic-melting``
57+
Makes amortized metal bar returns for melting uniform across all item types.
58+
Affects weapons, shields, armor parts, tools, and trap components. The target
59+
amount of metal produced by melting is 95% of the metal used for production
60+
of the item. Each level of wear decreases melt return by a further 10%. The game
61+
has a fixed granularity of 0.3 for metal bar returns, so individual items will
62+
randomly return an amount that may be above or below the target. For example
63+
a metal cap with item size 1 will produce 0.9 of a bar with a 16.6% chance of
64+
producing an additional 0.3 of a bar. Over time, the average return for melting
65+
these types of caps will be ~0.95 of a bar. Calculations for melting return are
66+
done for items with base game production cost. Melting return might not be
67+
calculated correctly for modded items or items created in custom reactions
68+
that don't respect vanilla production costs. (:bug:`6027`)
5669
``named-codices``
5770
Displays titles for books instead of the default material description.
5871
``partial-items``

plugins/tweak/tweak.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ using namespace DFHack;
1717
#include "tweaks/eggs-fertile.h"
1818
#include "tweaks/fast-heat.h"
1919
#include "tweaks/flask-contents.h"
20+
#include "tweaks/material-size-for-melting.h"
2021
#include "tweaks/named-codices.h"
2122
#include "tweaks/partial-items.h"
2223
#include "tweaks/reaction-gloves.h"
@@ -74,6 +75,15 @@ DFhackCExport command_result plugin_init(color_ostream &out, vector<PluginComman
7475

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

78+
TWEAK_HOOK("realistic-melting", material_size_for_melting_armor_hook, getMaterialSizeForMelting);
79+
TWEAK_HOOK("realistic-melting", material_size_for_melting_gloves_hook, getMaterialSizeForMelting);
80+
TWEAK_HOOK("realistic-melting", material_size_for_melting_shoes_hook, getMaterialSizeForMelting);
81+
TWEAK_HOOK("realistic-melting", material_size_for_melting_helm_hook, getMaterialSizeForMelting);
82+
TWEAK_HOOK("realistic-melting", material_size_for_melting_pants_hook, getMaterialSizeForMelting);
83+
TWEAK_HOOK("realistic-melting", material_size_for_melting_weapon_hook, getMaterialSizeForMelting);
84+
TWEAK_HOOK("realistic-melting", material_size_for_melting_trapcomp_hook, getMaterialSizeForMelting);
85+
TWEAK_HOOK("realistic-melting", material_size_for_melting_tool_hook, getMaterialSizeForMelting);
86+
7787
return CR_OK;
7888
}
7989

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include <cmath>
2+
3+
#include "modules/Materials.h"
4+
#include "modules/Random.h"
5+
6+
#include "df/inorganic_raw.h"
7+
#include "df/item_armorst.h"
8+
#include "df/item_constructed.h"
9+
#include "df/item_glovesst.h"
10+
#include "df/item_helmst.h"
11+
#include "df/item_pantsst.h"
12+
#include "df/item_shieldst.h"
13+
#include "df/item_shoesst.h"
14+
#include "df/item_toolst.h"
15+
#include "df/item_trapcompst.h"
16+
#include "df/item_weaponst.h"
17+
18+
struct Mrng {
19+
Random::MersenneRNG rng;
20+
Mrng() { rng.init(); }
21+
};
22+
23+
static float get_random() {
24+
static Mrng mrng;
25+
return static_cast <float> (mrng.rng.drandom1());
26+
}
27+
28+
static int32_t get_material_size_for_melting(df::item_constructed *item, int32_t base_material_size, float production_stack_size) {
29+
const float melt_return_per_material_size = 0.3f, base_melt_recovery = 0.95f, loss_per_wear_level = 0.1f;
30+
31+
if (item->mat_type != 0) // bail if not INORGANIC
32+
return base_material_size;
33+
34+
float forging_cost_per_item;
35+
if (auto inorganic = df::inorganic_raw::find(item->mat_index);
36+
inorganic && inorganic->flags.is_set(df::inorganic_flags::DEEP_SPECIAL))
37+
{
38+
// adamantine items
39+
forging_cost_per_item = static_cast<float>(base_material_size) / production_stack_size;
40+
} else {
41+
// non adamantine items
42+
forging_cost_per_item = std::max(std::floor(static_cast<float>(base_material_size) / 3.0f), 1.0f);
43+
forging_cost_per_item /= production_stack_size;
44+
}
45+
46+
float calculated_size = forging_cost_per_item / melt_return_per_material_size;
47+
float melt_recovery = base_melt_recovery - static_cast<float>(item->wear) * loss_per_wear_level;
48+
calculated_size *= melt_recovery;
49+
int32_t random_part = ((modff(calculated_size, &calculated_size) > get_random()) ? 1 : 0);
50+
return static_cast<int32_t>(calculated_size) + random_part;
51+
}
52+
53+
#define DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(TYPE, PRODUCTION_STACK_SIZE) \
54+
struct material_size_for_melting_##TYPE##_hook : df::item_##TYPE##st {\
55+
typedef df::item_##TYPE##st interpose_base;\
56+
DEFINE_VMETHOD_INTERPOSE(int32_t, getMaterialSizeForMelting, ()) {\
57+
return get_material_size_for_melting(this, INTERPOSE_NEXT(getMaterialSizeForMelting)(), PRODUCTION_STACK_SIZE);\
58+
}\
59+
};\
60+
IMPLEMENT_VMETHOD_INTERPOSE(material_size_for_melting_##TYPE##_hook, getMaterialSizeForMelting);
61+
62+
DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(armor, 1.0f)
63+
DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(gloves, 2.0f)
64+
DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(shoes, 2.0f)
65+
DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(helm, 1.0f)
66+
DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(pants, 1.0f)
67+
DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(weapon, 1.0f)
68+
DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(trapcomp, 1.0f)
69+
DEFINE_MATERIAL_SIZE_FOR_MELTING_TWEAK(tool, 1.0f)

0 commit comments

Comments
 (0)