diff --git a/dfhack.init-example b/dfhack.init-example index a9b69b826..b8b53cad7 100644 --- a/dfhack.init-example +++ b/dfhack.init-example @@ -59,6 +59,9 @@ keybinding add Alt-L@dwarfmode/LookAround gui/liquids # machine power sensitive pressure plate construction keybinding add Ctrl-Shift-M@dwarfmode/Build/Position/Trap gui/power-meter +# siege engine control +keybinding add Alt-A@dwarfmode/QueryBuilding/Some/SiegeEngine gui/siege-engine + ############################ # UI and game logic tweaks # ############################ @@ -79,3 +82,7 @@ tweak stable-temp # capping the rate to no less than 1 degree change per 500 frames # Note: will also cause stuff to melt faster in magma etc tweak fast-heat 500 + +# stop stacked liquid/bar/thread/cloth items from lasting forever +# if used in reactions that use only a fraction of the dimension. +tweak fix-dimensions diff --git a/plugins/tweak.cpp b/plugins/tweak.cpp index bebc346c5..4fef285f9 100644 --- a/plugins/tweak.cpp +++ b/plugins/tweak.cpp @@ -33,6 +33,10 @@ #include "df/ui_build_selector.h" #include "df/building_trapst.h" #include "df/item_actual.h" +#include "df/item_liquipowder.h" +#include "df/item_barst.h" +#include "df/item_threadst.h" +#include "df/item_clothst.h" #include "df/contaminant.h" #include @@ -93,6 +97,9 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector stack_size <= 1) return; + int rem = delta % dim; + if (rem == 0) return; + // If destroys, pass through + int intv = delta / dim; + if (intv >= self->stack_size) return; + // Subtract int part + delta = rem; + self->stack_size -= intv; + if (self->stack_size <= 1) return; + + // If kills the item or cannot split, round up. + if (!self->flags.bits.in_inventory || !Items::getContainer(self)) + { + delta = dim; + return; + } + + // Otherwise split the stack + color_ostream_proxy out(Core::getInstance().getConsole()); + out.print("fix-dimensions: splitting stack #%d for delta %d.\n", self->id, delta); + + auto copy = self->splitStack(self->stack_size-1, true); + if (copy) copy->categorize(true); +} + +struct dimension_lqp_hook : df::item_liquipowder { + typedef df::item_liquipowder interpose_base; + + DEFINE_VMETHOD_INTERPOSE(bool, subtractDimension, (int32_t delta)) + { + correct_dimension(this, delta, dimension); + return INTERPOSE_NEXT(subtractDimension)(delta); + } +}; + +IMPLEMENT_VMETHOD_INTERPOSE(dimension_lqp_hook, subtractDimension); + +struct dimension_bar_hook : df::item_barst { + typedef df::item_barst interpose_base; + + DEFINE_VMETHOD_INTERPOSE(bool, subtractDimension, (int32_t delta)) + { + correct_dimension(this, delta, dimension); + return INTERPOSE_NEXT(subtractDimension)(delta); + } +}; + +IMPLEMENT_VMETHOD_INTERPOSE(dimension_bar_hook, subtractDimension); + +struct dimension_thread_hook : df::item_threadst { + typedef df::item_threadst interpose_base; + + DEFINE_VMETHOD_INTERPOSE(bool, subtractDimension, (int32_t delta)) + { + correct_dimension(this, delta, dimension); + return INTERPOSE_NEXT(subtractDimension)(delta); + } +}; + +IMPLEMENT_VMETHOD_INTERPOSE(dimension_thread_hook, subtractDimension); + +struct dimension_cloth_hook : df::item_clothst { + typedef df::item_clothst interpose_base; + + DEFINE_VMETHOD_INTERPOSE(bool, subtractDimension, (int32_t delta)) + { + correct_dimension(this, delta, dimension); + return INTERPOSE_NEXT(subtractDimension)(delta); + } +}; + +IMPLEMENT_VMETHOD_INTERPOSE(dimension_cloth_hook, subtractDimension); + static void enable_hook(color_ostream &out, VMethodInterposeLinkBase &hook, vector ¶meters) { if (vector_get(parameters, 1) == "disable") @@ -491,6 +575,13 @@ static command_result tweak(color_ostream &out, vector ¶meters) enable_hook(out, INTERPOSE_HOOK(fast_heat_hook, updateTemperature), parameters); enable_hook(out, INTERPOSE_HOOK(fast_heat_hook, adjustTemperature), parameters); } + else if (cmd == "fix-dimensions") + { + enable_hook(out, INTERPOSE_HOOK(dimension_lqp_hook, subtractDimension), parameters); + enable_hook(out, INTERPOSE_HOOK(dimension_bar_hook, subtractDimension), parameters); + enable_hook(out, INTERPOSE_HOOK(dimension_thread_hook, subtractDimension), parameters); + enable_hook(out, INTERPOSE_HOOK(dimension_cloth_hook, subtractDimension), parameters); + } else return CR_WRONG_USAGE;