Skip to content

Commit

Permalink
Merge pull request #4958 from Birkow/tweak/material_size_for_melting
Browse files Browse the repository at this point in the history
adjust material size for melting for armor parts, weapons, trap components and tools...
  • Loading branch information
myk002 authored Sep 28, 2024
2 parents 9c69796 + 6b553c6 commit 77817be
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 0 deletions.
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`: ``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

## Fixes

Expand Down
13 changes: 13 additions & 0 deletions docs/plugins/tweak.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@ 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`)
``realistic-melting``
Makes amortized metal bar returns for melting uniform across all item types.
Affects weapons, shields, armor parts, tools, and trap components. The target
amount of metal produced by melting is 95% of the metal used for production
of the item. Each level of wear decreases melt return by a further 10%. The game
has a fixed granularity of 0.3 for metal bar returns, so individual items will
randomly return an amount that may be above or below the target. For example
a metal cap with item size 1 will produce 0.9 of a bar with a 16.6% chance of
producing an additional 0.3 of a bar. Over time, the average return for melting
these types of caps will be ~0.95 of a bar. Calculations for melting return are
done for items with base game production cost. Melting return might not be
calculated correctly for modded items or items created in custom reactions
that don't respect vanilla production costs. (:bug:`6027`)
``named-codices``
Displays titles for books instead of the default material description.
``partial-items``
Expand Down
10 changes: 10 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,15 @@ DFhackCExport command_result plugin_init(color_ostream &out, vector<PluginComman

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

TWEAK_HOOK("realistic-melting", material_size_for_melting_armor_hook, getMaterialSizeForMelting);
TWEAK_HOOK("realistic-melting", material_size_for_melting_gloves_hook, getMaterialSizeForMelting);
TWEAK_HOOK("realistic-melting", material_size_for_melting_shoes_hook, getMaterialSizeForMelting);
TWEAK_HOOK("realistic-melting", material_size_for_melting_helm_hook, getMaterialSizeForMelting);
TWEAK_HOOK("realistic-melting", material_size_for_melting_pants_hook, getMaterialSizeForMelting);
TWEAK_HOOK("realistic-melting", material_size_for_melting_weapon_hook, getMaterialSizeForMelting);
TWEAK_HOOK("realistic-melting", material_size_for_melting_trapcomp_hook, getMaterialSizeForMelting);
TWEAK_HOOK("realistic-melting", material_size_for_melting_tool_hook, getMaterialSizeForMelting);

return CR_OK;
}

Expand Down
69 changes: 69 additions & 0 deletions plugins/tweak/tweaks/material-size-for-melting.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#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"

struct Mrng {
Random::MersenneRNG rng;
Mrng() { rng.init(); }
};

static float get_random() {
static Mrng mrng;
return static_cast <float> (mrng.rng.drandom1());
}

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) // bail if not INORGANIC
return base_material_size;

float forging_cost_per_item;
if (auto inorganic = df::inorganic_raw::find(item->mat_index);
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;
}

float 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;
}

#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);\
}\
};\
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)

0 comments on commit 77817be

Please sign in to comment.