|  |  | @ -68,6 +68,16 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | //#include "df/building_hivest.h"
 |  |  |  | //#include "df/building_hivest.h"
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <stdlib.h> |  |  |  | #include <stdlib.h> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include <unordered_map> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include "tweaks/adamantine-cloth-wear.h" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include "tweaks/advmode-contained.h" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include "tweaks/craft-age-wear.h" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include "tweaks/fast-heat.h" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include "tweaks/fast-trade.h" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include "tweaks/manager-quantity.h" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include "tweaks/military-assign.h" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include "tweaks/stable-cursor.h" | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | using std::set; |  |  |  | using std::set; | 
			
		
	
		
		
			
				
					
					|  |  |  | using std::vector; |  |  |  | using std::vector; | 
			
		
	
	
		
		
			
				
					|  |  | @ -83,12 +93,15 @@ using df::global::ui_menu_width; | 
			
		
	
		
		
			
				
					
					|  |  |  | using df::global::ui_area_map_width; |  |  |  | using df::global::ui_area_map_width; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | using namespace DFHack::Gui; |  |  |  | using namespace DFHack::Gui; | 
			
		
	
		
		
			
				
					
					|  |  |  | using Screen::Pen; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static command_result tweak(color_ostream &out, vector <string> & parameters); |  |  |  | static command_result tweak(color_ostream &out, vector <string> & parameters); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | static std::multimap<std::string, VMethodInterposeLinkBase> tweak_hooks; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | DFHACK_PLUGIN("tweak"); |  |  |  | DFHACK_PLUGIN("tweak"); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #define TWEAK_HOOK(tweak, cls, func) tweak_hooks.insert(std::pair<std::string, VMethodInterposeLinkBase>\ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     (tweak, INTERPOSE_HOOK(cls, func))) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands) |  |  |  | DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     commands.push_back(PluginCommand( |  |  |  |     commands.push_back(PluginCommand( | 
			
		
	
	
		
		
			
				
					|  |  | @ -115,14 +128,6 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi | 
			
		
	
		
		
			
				
					
					|  |  |  |         "  tweak stable-cursor [disable]\n" |  |  |  |         "  tweak stable-cursor [disable]\n" | 
			
		
	
		
		
			
				
					
					|  |  |  |         "    Keeps exact position of dwarfmode cursor during exits to main menu.\n" |  |  |  |         "    Keeps exact position of dwarfmode cursor during exits to main menu.\n" | 
			
		
	
		
		
			
				
					
					|  |  |  |         "    E.g. allows switching between t/q/k/d without losing position.\n" |  |  |  |         "    E.g. allows switching between t/q/k/d without losing position.\n" | 
			
		
	
		
		
			
				
					
					|  |  |  |         "  tweak patrol-duty [disable]\n" |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         "    Causes 'Train' orders to no longer be considered 'patrol duty' so\n" |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         "    soldiers will stop getting unhappy thoughts. Does NOT fix the problem\n" |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         "    when soldiers go off-duty (i.e. civilian).\n" |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         "  tweak confirm-embark [disable]\n" |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         "    Asks for confirmation on the embark setup screen before embarking\n" |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         "  tweak stable-temp [disable]\n" |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         "    Fixes performance bug 6012 by squashing jitter in temperature updates.\n" |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         "  tweak fast-heat <max-ticks>\n" |  |  |  |         "  tweak fast-heat <max-ticks>\n" | 
			
		
	
		
		
			
				
					
					|  |  |  |         "    Further improves temperature updates by ensuring that 1 degree of\n" |  |  |  |         "    Further improves temperature updates by ensuring that 1 degree of\n" | 
			
		
	
		
		
			
				
					
					|  |  |  |         "    item temperature is crossed in no more than specified number of frames\n" |  |  |  |         "    item temperature is crossed in no more than specified number of frames\n" | 
			
		
	
	
		
		
			
				
					|  |  | @ -146,11 +151,39 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi | 
			
		
	
		
		
			
				
					
					|  |  |  |         "    to make them stand out more in the list.\n" |  |  |  |         "    to make them stand out more in the list.\n" | 
			
		
	
		
		
			
				
					
					|  |  |  | //        "  tweak military-training [disable]\n"
 |  |  |  | //        "  tweak military-training [disable]\n"
 | 
			
		
	
		
		
			
				
					
					|  |  |  | //        "    Speed up melee squad training, removing inverse dependency on unit count.\n"
 |  |  |  | //        "    Speed up melee squad training, removing inverse dependency on unit count.\n"
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         "  tweak manager-quantity [disable]\n" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         "    Removes the limit of 30 jobs per manager order\n" | 
			
		
	
		
		
			
				
					
					|  |  |  |         "  tweak craft-age-wear [disable]\n" |  |  |  |         "  tweak craft-age-wear [disable]\n" | 
			
		
	
		
		
			
				
					
					|  |  |  |         "    Makes cloth and leather items wear out at the correct rate (bug 6003).\n" |  |  |  |         "    Makes cloth and leather items wear out at the correct rate (bug 6003).\n" | 
			
		
	
		
		
			
				
					
					|  |  |  |         "  tweak adamantine-cloth-wear [disable]\n" |  |  |  |         "  tweak adamantine-cloth-wear [disable]\n" | 
			
		
	
		
		
			
				
					
					|  |  |  |         "    Stops adamantine clothing from wearing out while being worn (bug 6481).\n" |  |  |  |         "    Stops adamantine clothing from wearing out while being worn (bug 6481).\n" | 
			
		
	
		
		
			
				
					
					|  |  |  |     )); |  |  |  |     )); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     TWEAK_HOOK("adamantine-cloth-wear", adamantine_cloth_wear_armor_hook, incWearTimer); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     TWEAK_HOOK("adamantine-cloth-wear", adamantine_cloth_wear_helm_hook, incWearTimer); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     TWEAK_HOOK("adamantine-cloth-wear", adamantine_cloth_wear_gloves_hook, incWearTimer); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     TWEAK_HOOK("adamantine-cloth-wear", adamantine_cloth_wear_shoes_hook, incWearTimer); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     TWEAK_HOOK("adamantine-cloth-wear", adamantine_cloth_wear_pants_hook, incWearTimer); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     TWEAK_HOOK("advmode-contained", advmode_contained_hook, feed); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     TWEAK_HOOK("craft-age-wear", craft_age_wear_hook, ageItem); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     TWEAK_HOOK("fast-heat", fast_heat_hook, updateTempFromMap); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     TWEAK_HOOK("fast-heat", fast_heat_hook, updateTemperature); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     TWEAK_HOOK("fast-heat", fast_heat_hook, adjustTemperature); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     TWEAK_HOOK("fast-trade", fast_trade_assign_hook, feed); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     TWEAK_HOOK("fast-trade", fast_trade_select_hook, feed); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     TWEAK_HOOK("manager-quantity", manager_quantity_hook, feed); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     TWEAK_HOOK("military-color-assigned", military_assign_hook, render); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     TWEAK_HOOK("military-stable-assign", military_assign_hook, feed); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     TWEAK_HOOK("stable-cursor", stable_cursor_hook, feed); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     return CR_OK; |  |  |  |     return CR_OK; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -216,271 +249,6 @@ command_result fix_clothing_ownership(color_ostream &out, df::unit* unit) | 
			
		
	
		
		
			
				
					
					|  |  |  |     return CR_OK; |  |  |  |     return CR_OK; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | /*
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  * Save or restore cursor position on change to/from main dwarfmode menu. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  */ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static df::coord last_view, last_cursor; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | struct stable_cursor_hook : df::viewscreen_dwarfmodest |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     typedef df::viewscreen_dwarfmodest interpose_base; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     bool check_default() |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         switch (ui->main.mode) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             case ui_sidebar_mode::Default: |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return true; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             case ui_sidebar_mode::Build: |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return ui_build_selector && |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                        (ui_build_selector->building_type < 0 || |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         ui_build_selector->stage < 1); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             default: |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(void, feed, (set<df::interface_key> *input)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         bool was_default = check_default(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         df::coord view = Gui::getViewportPos(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         df::coord cursor = Gui::getCursorPos(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         INTERPOSE_NEXT(feed)(input); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         bool is_default = check_default(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         df::coord cur_cursor = Gui::getCursorPos(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (is_default && !was_default) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             last_view = view; last_cursor = cursor; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         else if (!is_default && was_default && |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                  Gui::getViewportPos() == last_view && |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                  last_cursor.isValid() && cur_cursor.isValid()) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             Gui::setCursorCoords(last_cursor.x, last_cursor.y, last_cursor.z); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             // Force update of ui state
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             set<df::interface_key> tmp; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (last_cursor.z < 2) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 tmp.insert(interface_key::CURSOR_UP_Z); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 tmp.insert(interface_key::CURSOR_DOWN_Z); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             INTERPOSE_NEXT(feed)(&tmp); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             tmp.clear(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (last_cursor.z < 2) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 tmp.insert(interface_key::CURSOR_DOWN_Z); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 tmp.insert(interface_key::CURSOR_UP_Z); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             INTERPOSE_NEXT(feed)(&tmp); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         else if (!is_default && cur_cursor.isValid()) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             last_cursor = df::coord(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(stable_cursor_hook, feed); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | struct patrol_duty_hook : df::squad_order_trainst |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     typedef df::squad_order_trainst interpose_base; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(bool, isPatrol, ()) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(patrol_duty_hook, isPatrol); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | enum confirm_embark_states |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     ECS_INACTIVE = 0, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     ECS_CONFIRM, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     ECS_ACCEPTED |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static confirm_embark_states confirm_embark_state = ECS_INACTIVE; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | struct confirm_embark_hook : df::viewscreen_setupdwarfgamest |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     typedef df::viewscreen_setupdwarfgamest interpose_base; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     void OutputString(int8_t fg, int &x, int y, std::string text) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         Screen::paintString(Screen::Pen(' ', fg, COLOR_BLACK), x, y, text); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         x += text.length(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(void, feed, (set<df::interface_key> *input)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         bool intercept = false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (this->show_play_now == 0) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (confirm_embark_state == ECS_INACTIVE) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (input->count(df::interface_key::SETUP_EMBARK)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     confirm_embark_state = ECS_CONFIRM; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     intercept = true; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             else if (confirm_embark_state == ECS_CONFIRM) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 intercept = true; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (input->count(df::interface_key::MENU_CONFIRM)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     confirm_embark_state = ECS_ACCEPTED; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 else if (input->size()) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     confirm_embark_state = ECS_INACTIVE; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (!intercept) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             INTERPOSE_NEXT(feed)(input); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(bool, key_conflict, (df::interface_key key)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (confirm_embark_state == ECS_CONFIRM) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (key == df::interface_key::OPTIONS) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return true; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return INTERPOSE_NEXT(key_conflict)(key); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(void, render, ()) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         INTERPOSE_NEXT(render)(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         auto dim = Screen::getWindowSize(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         int x = 0, y = 0; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (confirm_embark_state != ECS_INACTIVE) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             Screen::fillRect(Screen::Pen(' ', COLOR_BLACK, COLOR_BLACK), 0, 0, dim.x - 1, dim.y - 1); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (confirm_embark_state == ECS_CONFIRM) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             x = 2, y = 2; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             OutputString(COLOR_WHITE, x, y, "Really embark? ("); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             OutputString(COLOR_LIGHTGREEN, x, y, Screen::getKeyDisplay(df::interface_key::MENU_CONFIRM)); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             OutputString(COLOR_WHITE, x, y, " = yes, other = no)"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             x = 2, y = 4; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             int32_t points = this->points_remaining; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             OutputString(COLOR_WHITE, x, y, "Points left: "); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             OutputString((points ? COLOR_YELLOW : COLOR_LIGHTGREEN), x, y, std::to_string((unsigned long long/*won't compile on windows otherwise*/)points)); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             x = dim.x - 10, y = dim.y - 1; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             OutputString(COLOR_WHITE, x, y, "DFHack"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         else if (confirm_embark_state == ECS_ACCEPTED) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             std::set<df::interface_key> input; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             input.insert(df::interface_key::SETUP_EMBARK); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             this->feed(&input); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             confirm_embark_state = ECS_INACTIVE; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(confirm_embark_hook, feed); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(confirm_embark_hook, key_conflict); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(confirm_embark_hook, render); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | struct stable_temp_hook : df::item_actual { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     typedef df::item_actual interpose_base; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(bool, adjustTemperature, (uint16_t temp, int32_t rate_mult)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (temperature.whole != temp) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             // Bug 6012 is caused by fixed-point precision mismatch jitter
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             // when an item is being pushed by two sources at N and N+1.
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             // This check suppresses it altogether.
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (temp == temperature.whole+1 || |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 (temp == temperature.whole-1 && temperature.fraction == 0)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 temp = temperature.whole; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             // When SPEC_HEAT is NONE, the original function seems to not
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             // change the temperature, yet return true, which is silly.
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             else if (getSpecHeat() == 60001) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 temp = temperature.whole; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return INTERPOSE_NEXT(adjustTemperature)(temp, rate_mult); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(bool, updateContaminants, ()) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (contaminants) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             // Force 1-degree difference in contaminant temperature to 0
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             for (size_t i = 0; i < contaminants->size(); i++) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 auto obj = (*contaminants)[i]; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (abs(obj->temperature.whole - temperature.whole) == 1) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     obj->temperature.whole = temperature.whole; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     obj->temperature.fraction = temperature.fraction; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return INTERPOSE_NEXT(updateContaminants)(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(stable_temp_hook, adjustTemperature); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(stable_temp_hook, updateContaminants); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static int map_temp_mult = -1; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static int max_heat_ticks = 0; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | struct fast_heat_hook : df::item_actual { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     typedef df::item_actual interpose_base; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE( |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         bool, updateTempFromMap, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         (bool local, bool contained, bool adjust, int32_t rate_mult) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     ) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         int cmult = map_temp_mult; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         map_temp_mult = rate_mult; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         bool rv = INTERPOSE_NEXT(updateTempFromMap)(local, contained, adjust, rate_mult); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         map_temp_mult = cmult; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return rv; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE( |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         bool, updateTemperature, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         (uint16_t temp, bool local, bool contained, bool adjust, int32_t rate_mult) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     ) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         // Some items take ages to cross the last degree, so speed them up
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (map_temp_mult > 0 && temp != temperature.whole && max_heat_ticks > 0) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             int spec = getSpecHeat(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (spec != 60001) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 rate_mult = std::max(map_temp_mult, spec/max_heat_ticks/abs(temp - temperature.whole)); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return INTERPOSE_NEXT(updateTemperature)(temp, local, contained, adjust, rate_mult); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(bool, adjustTemperature, (uint16_t temp, int32_t rate_mult)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (map_temp_mult > 0) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             rate_mult = map_temp_mult; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return INTERPOSE_NEXT(adjustTemperature)(temp, rate_mult); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(fast_heat_hook, updateTempFromMap); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(fast_heat_hook, updateTemperature); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(fast_heat_hook, adjustTemperature); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static void correct_dimension(df::item_actual *self, int32_t &delta, int32_t dim) |  |  |  | static void correct_dimension(df::item_actual *self, int32_t &delta, int32_t dim) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Zero dimension or remainder?
 |  |  |  |     // Zero dimension or remainder?
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -570,201 +338,6 @@ struct dimension_cloth_hook : df::item_clothst { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(dimension_cloth_hook, subtractDimension); |  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(dimension_cloth_hook, subtractDimension); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | struct advmode_contained_hook : df::viewscreen_layer_unit_actionst { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     typedef df::viewscreen_layer_unit_actionst interpose_base; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(void, feed, (set<df::interface_key> *input)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         auto old_reaction = cur_reaction; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         auto old_reagent = reagent; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         INTERPOSE_NEXT(feed)(input); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (cur_reaction && (cur_reaction != old_reaction || reagent != old_reagent)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             old_reagent = reagent; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             // Skip reagents already contained by others
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             while (reagent < (int)cur_reaction->reagents.size()-1) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (!cur_reaction->reagents[reagent]->flags.bits.IN_CONTAINER) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     break; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 reagent++; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (old_reagent != reagent) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 // Reproduces a tiny part of the orginal screen code
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 choice_items.clear(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 auto preagent = cur_reaction->reagents[reagent]; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 reagent_amnt_left = preagent->quantity; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 for (int i = held_items.size()-1; i >= 0; i--) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if (!preagent->matchesRoot(held_items[i], cur_reaction->index)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         continue; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if (linear_index(sel_items, held_items[i]) >= 0) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         continue; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     choice_items.push_back(held_items[i]); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 layer_objects[6]->setListLength(choice_items.size()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (!choice_items.empty()) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     layer_objects[4]->active = layer_objects[5]->active = false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     layer_objects[6]->active = true; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 else if (layer_objects[6]->active) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     layer_objects[6]->active = false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     layer_objects[5]->active = true; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(advmode_contained_hook, feed); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | struct fast_trade_assign_hook : df::viewscreen_layer_assigntradest { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     typedef df::viewscreen_layer_assigntradest interpose_base; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(void, feed, (set<df::interface_key> *input)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (layer_objects[1]->active && input->count(interface_key::SELECT_ALL)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             set<df::interface_key> tmp; tmp.insert(interface_key::SELECT); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             INTERPOSE_NEXT(feed)(&tmp); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             tmp.clear(); tmp.insert(interface_key::STANDARDSCROLL_DOWN); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             INTERPOSE_NEXT(feed)(&tmp); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             INTERPOSE_NEXT(feed)(input); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(fast_trade_assign_hook, feed); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | struct fast_trade_select_hook : df::viewscreen_tradegoodsst { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     typedef df::viewscreen_tradegoodsst interpose_base; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(void, feed, (set<df::interface_key> *input)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (!(is_unloading || !has_traders || in_edit_count) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             && input->count(interface_key::SELECT_ALL)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             set<df::interface_key> tmp; tmp.insert(interface_key::SELECT); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             INTERPOSE_NEXT(feed)(&tmp); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (in_edit_count) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 INTERPOSE_NEXT(feed)(&tmp); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             tmp.clear(); tmp.insert(interface_key::STANDARDSCROLL_DOWN); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             INTERPOSE_NEXT(feed)(&tmp); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             INTERPOSE_NEXT(feed)(input); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(fast_trade_select_hook, feed); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | struct military_assign_hook : df::viewscreen_layer_militaryst { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     typedef df::viewscreen_layer_militaryst interpose_base; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     inline bool inPositionsMode() { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return page == Positions && !(in_create_squad || in_new_squad); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(void, feed, (set<df::interface_key> *input)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (inPositionsMode() && !layer_objects[0]->active) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             auto pos_list = layer_objects[1]; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             auto plist = layer_objects[2]; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             auto &cand = positions.candidates; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             // Save the candidate list and cursors
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             std::vector<df::unit*> copy = cand; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             int cursor = plist->getListCursor(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             int pos_cursor = pos_list->getListCursor(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             INTERPOSE_NEXT(feed)(input); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (inPositionsMode() && !layer_objects[0]->active) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 bool is_select = input->count(interface_key::SELECT); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 // Resort the candidate list and restore cursor
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 // on add to squad OR scroll in the position list.
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (!plist->active || is_select) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     // Since we don't know the actual sorting order, preserve
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     // the ordering of the items in the list before keypress.
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     // This does the right thing even if the list was sorted
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     // with sort-units.
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     std::set<df::unit*> prev, next; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     prev.insert(copy.begin(), copy.end()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     next.insert(cand.begin(), cand.end()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     std::vector<df::unit*> out; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     // (old-before-cursor) (new) |cursor| (old-after-cursor)
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     for (int i = 0; i < cursor && i < (int)copy.size(); i++) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         if (next.count(copy[i])) out.push_back(copy[i]); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     for (size_t i = 0; i < cand.size(); i++) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         if (!prev.count(cand[i])) out.push_back(cand[i]); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     int new_cursor = out.size(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     for (int i = cursor; i < (int)copy.size(); i++) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         if (next.count(copy[i])) out.push_back(copy[i]); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     cand.swap(out); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     plist->setListLength(cand.size()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if (new_cursor < (int)cand.size()) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         plist->setListCursor(new_cursor); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 // Preserve the position list index on remove from squad
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (pos_list->active && is_select) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     pos_list->setListCursor(pos_cursor); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             INTERPOSE_NEXT(feed)(input); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(void, render, ()) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         INTERPOSE_NEXT(render)(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (inPositionsMode()) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             auto plist = layer_objects[2]; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             int x1 = plist->getX1(), y1 = plist->getY1(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             int x2 = plist->getX2(), y2 = plist->getY2(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             int i1 = plist->getFirstVisible(), i2 = plist->getLastVisible(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             int si = plist->getListCursor(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             for (int y = y1, i = i1; i <= i2; i++, y++) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 auto unit = vector_get(positions.candidates, i); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (!unit || unit->military.squad_id < 0) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     continue; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 for (int x = x1; x <= x2; x++) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     Pen cur_tile = Screen::readTile(x, y); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if (!cur_tile.valid()) continue; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     cur_tile.fg = (i == si) ? COLOR_BROWN : COLOR_GREEN; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     Screen::paintTile(cur_tile, x, y); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(military_assign_hook, feed); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(military_assign_hook, render); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | // Unit updates are executed based on an action divisor variable,
 |  |  |  | // Unit updates are executed based on an action divisor variable,
 | 
			
		
	
		
		
			
				
					
					|  |  |  | // which is computed from the alive unit count and has range 10-100.
 |  |  |  | // which is computed from the alive unit count and has range 10-100.
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static int adjust_unit_divisor(int value) { |  |  |  | static int adjust_unit_divisor(int value) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -1007,104 +580,6 @@ struct military_training_id_hook : df::activity_event_individual_skill_drillst { | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(military_training_id_hook, process); |  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(military_training_id_hook, process); | 
			
		
	
		
		
			
				
					
					|  |  |  | */ |  |  |  | */ | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | struct craft_age_wear_hook : df::item_crafted { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     typedef df::item_crafted interpose_base; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(bool, ageItem, (int amount)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         int orig_age = age; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         age += amount; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (age > 200000000) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             age = 200000000; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (age == orig_age) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             return false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         MaterialInfo mat(mat_type, mat_index); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (!mat.isValid()) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             return false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         int wear = 0; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (mat.material->flags.is_set(material_flags::WOOD)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             wear = 5; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         else if (mat.material->flags.is_set(material_flags::LEATHER) || |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             mat.material->flags.is_set(material_flags::THREAD_PLANT) || |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             mat.material->flags.is_set(material_flags::SILK) || |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             mat.material->flags.is_set(material_flags::YARN)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             wear = 1; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             return false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         wear = ((orig_age % wear) + (age - orig_age)) / wear; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (wear > 0) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             return incWearTimer(wear); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             return false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(craft_age_wear_hook, ageItem); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static bool inc_wear_timer (df::item_constructed *item, int amount) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (item->flags.bits.artifact) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     MaterialInfo mat(item->mat_type, item->mat_index); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (mat.isInorganic() && mat.inorganic->flags.is_set(inorganic_flags::DEEP_SPECIAL)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     item->wear_timer += amount; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     return (item->wear_timer > 806400); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | struct adamantine_cloth_wear_armor_hook : df::item_armorst { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     typedef df::item_armorst interpose_base; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(bool, incWearTimer, (int amount)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return inc_wear_timer(this, amount); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(adamantine_cloth_wear_armor_hook, incWearTimer); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | struct adamantine_cloth_wear_helm_hook : df::item_helmst { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     typedef df::item_helmst interpose_base; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(bool, incWearTimer, (int amount)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return inc_wear_timer(this, amount); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(adamantine_cloth_wear_helm_hook, incWearTimer); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | struct adamantine_cloth_wear_gloves_hook : df::item_glovesst { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     typedef df::item_glovesst interpose_base; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(bool, incWearTimer, (int amount)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return inc_wear_timer(this, amount); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(adamantine_cloth_wear_gloves_hook, incWearTimer); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | struct adamantine_cloth_wear_shoes_hook : df::item_shoesst { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     typedef df::item_shoesst interpose_base; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(bool, incWearTimer, (int amount)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return inc_wear_timer(this, amount); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(adamantine_cloth_wear_shoes_hook, incWearTimer); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | struct adamantine_cloth_wear_pants_hook : df::item_pantsst { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     typedef df::item_pantsst interpose_base; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     DEFINE_VMETHOD_INTERPOSE(bool, incWearTimer, (int amount)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return inc_wear_timer(this, amount); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | IMPLEMENT_VMETHOD_INTERPOSE(adamantine_cloth_wear_pants_hook, incWearTimer); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static void enable_hook(color_ostream &out, VMethodInterposeLinkBase &hook, vector <string> ¶meters) |  |  |  | static void enable_hook(color_ostream &out, VMethodInterposeLinkBase &hook, vector <string> ¶meters) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (vector_get(parameters, 1) == "disable") |  |  |  |     if (vector_get(parameters, 1) == "disable") | 
			
		
	
	
		
		
			
				
					|  |  | @ -1121,6 +596,26 @@ static void enable_hook(color_ostream &out, VMethodInterposeLinkBase &hook, vect | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | static command_result enable_tweak(string tweak, color_ostream &out, vector <string> ¶meters) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     bool recognized = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     string cmd = parameters[0]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     for (auto it = tweak_hooks.begin(); it != tweak_hooks.end(); ++it) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if (it->first == cmd) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             recognized = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             enable_hook(out, it->second, parameters); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if (!recognized) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         out.printerr("Unrecognized tweak: %s\n", cmd.c_str()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         return CR_WRONG_USAGE; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     return CR_OK; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static command_result tweak(color_ostream &out, vector <string> ¶meters) |  |  |  | static command_result tweak(color_ostream &out, vector <string> ¶meters) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     CoreSuspender suspend; |  |  |  |     CoreSuspender suspend; | 
			
		
	
	
		
		
			
				
					|  |  | @ -1219,25 +714,6 @@ static command_result tweak(color_ostream &out, vector <string> ¶meters) | 
			
		
	
		
		
			
				
					
					|  |  |  |             unit->profession2 = df::profession::TRADER; |  |  |  |             unit->profession2 = df::profession::TRADER; | 
			
		
	
		
		
			
				
					
					|  |  |  |         return fix_clothing_ownership(out, unit); |  |  |  |         return fix_clothing_ownership(out, unit); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     else if (cmd == "stable-cursor") |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(stable_cursor_hook, feed), parameters); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     else if (cmd == "patrol-duty") |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(patrol_duty_hook, isPatrol), parameters); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     else if (cmd == "confirm-embark") |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(confirm_embark_hook, feed), parameters); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(confirm_embark_hook, key_conflict), parameters); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(confirm_embark_hook, render), parameters); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     else if (cmd == "stable-temp") |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(stable_temp_hook, adjustTemperature), parameters); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(stable_temp_hook, updateContaminants), parameters); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     else if (cmd == "fast-heat") |  |  |  |     else if (cmd == "fast-heat") | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (parameters.size() < 2) |  |  |  |         if (parameters.size() < 2) | 
			
		
	
	
		
		
			
				
					|  |  | @ -1245,9 +721,8 @@ static command_result tweak(color_ostream &out, vector <string> ¶meters) | 
			
		
	
		
		
			
				
					
					|  |  |  |         max_heat_ticks = atoi(parameters[1].c_str()); |  |  |  |         max_heat_ticks = atoi(parameters[1].c_str()); | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (max_heat_ticks <= 0) |  |  |  |         if (max_heat_ticks <= 0) | 
			
		
	
		
		
			
				
					
					|  |  |  |             parameters[1] = "disable"; |  |  |  |             parameters[1] = "disable"; | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(fast_heat_hook, updateTempFromMap), parameters); |  |  |  |         enable_tweak(cmd, out, parameters); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(fast_heat_hook, updateTemperature), parameters); |  |  |  |         return CR_OK; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(fast_heat_hook, adjustTemperature), parameters); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     /*else if (cmd == "fix-dimensions")
 |  |  |  |     /*else if (cmd == "fix-dimensions")
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
	
		
		
			
				
					|  |  | @ -1257,23 +732,6 @@ static command_result tweak(color_ostream &out, vector <string> ¶meters) | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(dimension_thread_hook, subtractDimension), parameters); |  |  |  |         enable_hook(out, INTERPOSE_HOOK(dimension_thread_hook, subtractDimension), parameters); | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(dimension_cloth_hook, subtractDimension), parameters); |  |  |  |         enable_hook(out, INTERPOSE_HOOK(dimension_cloth_hook, subtractDimension), parameters); | 
			
		
	
		
		
			
				
					
					|  |  |  |     }*/ |  |  |  |     }*/ | 
			
		
	
		
		
			
				
					
					|  |  |  |     else if (cmd == "advmode-contained") |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(advmode_contained_hook, feed), parameters); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     else if (cmd == "fast-trade") |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(fast_trade_assign_hook, feed), parameters); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(fast_trade_select_hook, feed), parameters); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     else if (cmd == "military-stable-assign") |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(military_assign_hook, feed), parameters); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     else if (cmd == "military-color-assigned") |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(military_assign_hook, render), parameters); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /*
 |  |  |  | /*
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     else if (cmd == "military-training") |  |  |  |     else if (cmd == "military-training") | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
	
		
		
			
				
					|  |  | @ -1282,20 +740,10 @@ static command_result tweak(color_ostream &out, vector <string> ¶meters) | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(military_training_sp_hook, process), parameters); |  |  |  |         enable_hook(out, INTERPOSE_HOOK(military_training_sp_hook, process), parameters); | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(military_training_id_hook, process), parameters); |  |  |  |         enable_hook(out, INTERPOSE_HOOK(military_training_id_hook, process), parameters); | 
			
		
	
		
		
			
				
					
					|  |  |  |     }*/ |  |  |  |     }*/ | 
			
		
	
		
		
			
				
					
					|  |  |  |     else if (cmd == "craft-age-wear") |  |  |  |     else | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(craft_age_wear_hook, ageItem), parameters); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     else if (cmd == "adamantine-cloth-wear") |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(adamantine_cloth_wear_armor_hook, incWearTimer), parameters); |  |  |  |         return enable_tweak(cmd, out, parameters); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(adamantine_cloth_wear_helm_hook, incWearTimer), parameters); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(adamantine_cloth_wear_gloves_hook, incWearTimer), parameters); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(adamantine_cloth_wear_shoes_hook, incWearTimer), parameters); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         enable_hook(out, INTERPOSE_HOOK(adamantine_cloth_wear_pants_hook, incWearTimer), parameters); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return CR_WRONG_USAGE; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     return CR_OK; |  |  |  |     return CR_OK; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } |