From ce1158780f524401d5bb424f24cfd7c27843d5a9 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 13 Jul 2017 13:07:58 -0400 Subject: [PATCH 01/66] Fix crash in stl_vsprintf() from reusing va_list --- library/MiscUtils.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/MiscUtils.cpp b/library/MiscUtils.cpp index 5348086c1..cb3150152 100644 --- a/library/MiscUtils.cpp +++ b/library/MiscUtils.cpp @@ -61,7 +61,10 @@ std::string stl_vsprintf(const char *fmt, va_list args) { std::vector buf; buf.resize(4096); for (;;) { - int rsz = vsnprintf(&buf[0], buf.size(), fmt, args); + va_list args2; + va_copy(args2, args); + int rsz = vsnprintf(&buf[0], buf.size(), fmt, args2); + va_end(args2); if (rsz < 0) buf.resize(buf.size()*2); From 15ed1bfd67f5bf87694aab5370210bd9d7f86fa5 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 13 Jul 2017 13:08:27 -0400 Subject: [PATCH 02/66] stl_vsprintf: avoid truncating 4096-byte strings --- library/MiscUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/MiscUtils.cpp b/library/MiscUtils.cpp index cb3150152..a6bb4b412 100644 --- a/library/MiscUtils.cpp +++ b/library/MiscUtils.cpp @@ -68,7 +68,7 @@ std::string stl_vsprintf(const char *fmt, va_list args) { if (rsz < 0) buf.resize(buf.size()*2); - else if (unsigned(rsz) > buf.size()) + else if (unsigned(rsz) >= buf.size()) buf.resize(rsz+1); else return std::string(&buf[0], rsz); From 1ee5debfbabbd57f7b750fe458d09bddfc20c0d9 Mon Sep 17 00:00:00 2001 From: Japa Illo Date: Mon, 17 Jul 2017 15:29:23 +0530 Subject: [PATCH 03/66] Send the existence of all buildings on the map. --- plugins/remotefortressreader/building_reader.cpp | 2 +- plugins/remotefortressreader/remotefortressreader.cpp | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/plugins/remotefortressreader/building_reader.cpp b/plugins/remotefortressreader/building_reader.cpp index a8d15597a..12598ea81 100644 --- a/plugins/remotefortressreader/building_reader.cpp +++ b/plugins/remotefortressreader/building_reader.cpp @@ -287,7 +287,7 @@ DFHack::command_result GetBuildingDefList(DFHack::color_ostream &stream, const D void CopyBuilding(int buildingIndex, RemoteFortressReader::BuildingInstance * remote_build) { df::building * local_build = df::global::world->buildings.all[buildingIndex]; - remote_build->set_index(buildingIndex); + remote_build->set_index(local_build->id); int minZ = local_build->z; if (local_build->getType() == df::enums::building_type::Well) { diff --git a/plugins/remotefortressreader/remotefortressreader.cpp b/plugins/remotefortressreader/remotefortressreader.cpp index 025658aa6..9b19edcc6 100644 --- a/plugins/remotefortressreader/remotefortressreader.cpp +++ b/plugins/remotefortressreader/remotefortressreader.cpp @@ -1,5 +1,5 @@ #include "df_version_int.h" -#define RFR_VERSION "0.17.0" +#define RFR_VERSION "0.17.1" #include #include @@ -1179,7 +1179,11 @@ void CopyBuildings(DFCoord min, DFCoord max, RemoteFortressReader::MapBlock * Ne { df::building * bld = df::global::world->buildings.all[i]; if (bld->x1 >= max.x || bld->y1 >= max.y || bld->x2 < min.x || bld->y2 < min.y) + { + auto out_bld = NetBlock->add_buildings(); + out_bld->set_index(bld->id); continue; + } int z2 = bld->z; @@ -1192,7 +1196,11 @@ void CopyBuildings(DFCoord min, DFCoord max, RemoteFortressReader::MapBlock * Ne } } if (bld->z < min.z || z2 >= max.z) + { + auto out_bld = NetBlock->add_buildings(); + out_bld->set_index(bld->id); continue; + } auto out_bld = NetBlock->add_buildings(); CopyBuilding(i, out_bld); df::building_actual* actualBuilding = virtual_cast(bld); From 90dd9e932e03e18cb29196a4f5a2941649662099 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Thu, 20 Jul 2017 03:53:45 -0500 Subject: [PATCH 04/66] exclude on-duty military personnel from health labor check --- plugins/labormanager.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/labormanager.cpp b/plugins/labormanager.cpp index 699e04605..cec70ab1e 100644 --- a/plugins/labormanager.cpp +++ b/plugins/labormanager.cpp @@ -2224,8 +2224,12 @@ private: out.print("Dwarf \"%s\": state %s %d\n", dwarf->dwarf->name.first_name.c_str(), state_names[dwarf->state], dwarf->clear_all); // determine if dwarf has medical needs - // babies cannot currently receive health care even if they need it - if (dwarf->dwarf->profession != profession::BABY && dwarf->dwarf->health) + if (dwarf->dwarf->health && !( + // on-duty military will not necessarily break to get minor injuries attended + ENUM_ATTR(profession, military, dwarf->dwarf->profession) || + // babies cannot currently receive health care even if they need it + dwarf->dwarf->profession == profession::BABY) + ) { if (dwarf->dwarf->health->flags.bits.needs_recovery) cnt_recover_wounded++; From ac1d6f947fb84de102d321e81152d5fca144d3fa Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Fri, 21 Jul 2017 10:24:00 -0500 Subject: [PATCH 05/66] Update clsocket submodule. See DFHack/clsocket#10. --- depends/clsocket | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/clsocket b/depends/clsocket index d1565a3b7..0f0ad78c4 160000 --- a/depends/clsocket +++ b/depends/clsocket @@ -1 +1 @@ -Subproject commit d1565a3b711514048477e11bc04f60f6218af37f +Subproject commit 0f0ad78c4fd429caacd0694b5c868dbeacea16b6 From 17a7885ef2356b3bbdf286ff67d63edc4ff2a168 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Fri, 21 Jul 2017 13:30:05 -0500 Subject: [PATCH 06/66] Fix a bunch of 64-bit Windows warnings --- library/include/Pragma.h | 2 ++ library/modules/Filesystem.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/library/include/Pragma.h b/library/include/Pragma.h index 8f82b8d3c..00472e732 100644 --- a/library/include/Pragma.h +++ b/library/include/Pragma.h @@ -58,6 +58,8 @@ distribution. #pragma warning( disable: 4482) // nonstandard extension used: 'extern' before template explicit instantiation #pragma warning( disable: 4231) + // ignore warnings about putting a vector index into an int + #pragma warning( disable: 4267) #endif #endif diff --git a/library/modules/Filesystem.cpp b/library/modules/Filesystem.cpp index 05d4e4fda..430e6351e 100644 --- a/library/modules/Filesystem.cpp +++ b/library/modules/Filesystem.cpp @@ -53,7 +53,7 @@ using namespace DFHack; bool Filesystem::chdir (std::string path) { - return !(bool)::chdir(path.c_str()); + return ::chdir(path.c_str()) == 0; } std::string Filesystem::getcwd () @@ -79,7 +79,7 @@ bool Filesystem::mkdir (std::string path) fail = ::mkdir(path.c_str(), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH); #endif - return !(bool)fail; + return fail == 0; } bool Filesystem::rmdir (std::string path) @@ -90,7 +90,7 @@ bool Filesystem::rmdir (std::string path) #else fail = ::rmdir(path.c_str()); #endif - return !(bool)fail; + return fail == 0; } #ifdef _WIN32 @@ -116,13 +116,13 @@ _filetype mode2type (mode_t mode) { bool Filesystem::stat (std::string path, STAT_STRUCT &info) { - return !(bool)(STAT_FUNC(path.c_str(), &info)); + return (STAT_FUNC(path.c_str(), &info)) == 0; } bool Filesystem::exists (std::string path) { STAT_STRUCT info; - return (bool)Filesystem::stat(path, info); + return Filesystem::stat(path, info); } _filetype Filesystem::filetype (std::string path) From 15ae72edec0c0a84d9ea358ca8177c254d20844e Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Sat, 22 Jul 2017 04:31:30 -0500 Subject: [PATCH 07/66] labormanager: Refactor source, separating the job labor mapper into a separate source file. --- plugins/CMakeLists.txt | 2 +- plugins/labormanager.cpp | 1041 ++--------------------- plugins/labormanager.h | 4 + plugins/labormanager_joblabormapper.cpp | 919 ++++++++++++++++++++ plugins/labormanager_joblabormapper.h | 21 + 5 files changed, 1033 insertions(+), 954 deletions(-) create mode 100644 plugins/labormanager.h create mode 100644 plugins/labormanager_joblabormapper.cpp create mode 100644 plugins/labormanager_joblabormapper.h diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index d94dc52c6..b09651678 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -128,7 +128,7 @@ if (BUILD_SUPPORTED) DFHACK_PLUGIN(infiniteSky infiniteSky.cpp) DFHACK_PLUGIN(isoworldremote isoworldremote.cpp PROTOBUFS isoworldremote) DFHACK_PLUGIN(jobutils jobutils.cpp) - DFHACK_PLUGIN(labormanager labormanager.cpp) + DFHACK_PLUGIN(labormanager labormanager.cpp labormanager.h labormanager_joblabormapper.cpp labormanager_joblabormapper.h) DFHACK_PLUGIN(lair lair.cpp) DFHACK_PLUGIN(liquids liquids.cpp Brushes.h LINK_LIBRARIES lua) DFHACK_PLUGIN(luasocket luasocket.cpp LINK_LIBRARIES clsocket lua dfhack-tinythread) diff --git a/plugins/labormanager.cpp b/plugins/labormanager.cpp index cec70ab1e..f791fe398 100644 --- a/plugins/labormanager.cpp +++ b/plugins/labormanager.cpp @@ -68,6 +68,9 @@ #include #include +#include "labormanager.h" +#include "labormanager_joblabormapper.h" + using namespace std; using std::string; using std::endl; @@ -96,7 +99,7 @@ enum ConfigFlags { // Here go all the command declarations... // mostly to allow having the mandatory stuff on top of the file and commands on the bottom -command_result labormanager (color_ostream &out, std::vector & parameters); +command_result labormanager(color_ostream &out, std::vector & parameters); // A plugin must be able to return its name and version. // The name string provided must correspond to the filename - labormanager.plug.so or labormanager.plug.dll in this case @@ -393,8 +396,8 @@ struct labor_info return (*df::global::cur_year - config.ival(3)) * 403200 + *df::global::cur_year_tick - config.ival(4); } void mark_assigned() { - config.ival(3) = (* df::global::cur_year); - config.ival(4) = (* df::global::cur_year_tick); + config.ival(3) = (*df::global::cur_year); + config.ival(4) = (*df::global::cur_year_tick); } }; @@ -500,7 +503,7 @@ static const struct labor_default default_labor_infos[] = { /* BOOKBINDING */ {100, 0, TOOL_NONE} }; -void debug (char* fmt, ...); + struct dwarf_info_t { @@ -531,189 +534,20 @@ struct dwarf_info_t }; -/* -* Here starts all the complicated stuff to try to deduce labors from jobs. -* This is all way more complicated than it really ought to be, but I have -* not found a way to make it simpler. -*/ - -static df::unit_labor hauling_labor_map[] = -{ - df::unit_labor::HAUL_ITEM, /* BAR */ - df::unit_labor::HAUL_STONE, /* SMALLGEM */ - df::unit_labor::HAUL_ITEM, /* BLOCKS */ - df::unit_labor::HAUL_STONE, /* ROUGH */ - df::unit_labor::HAUL_STONE, /* BOULDER */ - df::unit_labor::HAUL_WOOD, /* WOOD */ - df::unit_labor::HAUL_FURNITURE, /* DOOR */ - df::unit_labor::HAUL_FURNITURE, /* FLOODGATE */ - df::unit_labor::HAUL_FURNITURE, /* BED */ - df::unit_labor::HAUL_FURNITURE, /* CHAIR */ - df::unit_labor::HAUL_ITEM, /* CHAIN */ - df::unit_labor::HAUL_ITEM, /* FLASK */ - df::unit_labor::HAUL_ITEM, /* GOBLET */ - df::unit_labor::HAUL_ITEM, /* INSTRUMENT */ - df::unit_labor::HAUL_ITEM, /* TOY */ - df::unit_labor::HAUL_FURNITURE, /* WINDOW */ - df::unit_labor::HAUL_ANIMALS, /* CAGE */ - df::unit_labor::HAUL_ITEM, /* BARREL */ - df::unit_labor::HAUL_ITEM, /* BUCKET */ - df::unit_labor::HAUL_ANIMALS, /* ANIMALTRAP */ - df::unit_labor::HAUL_FURNITURE, /* TABLE */ - df::unit_labor::HAUL_FURNITURE, /* COFFIN */ - df::unit_labor::HAUL_FURNITURE, /* STATUE */ - df::unit_labor::HAUL_REFUSE, /* CORPSE */ - df::unit_labor::HAUL_ITEM, /* WEAPON */ - df::unit_labor::HAUL_ITEM, /* ARMOR */ - df::unit_labor::HAUL_ITEM, /* SHOES */ - df::unit_labor::HAUL_ITEM, /* SHIELD */ - df::unit_labor::HAUL_ITEM, /* HELM */ - df::unit_labor::HAUL_ITEM, /* GLOVES */ - df::unit_labor::HAUL_FURNITURE, /* BOX */ - df::unit_labor::HAUL_ITEM, /* BIN */ - df::unit_labor::HAUL_FURNITURE, /* ARMORSTAND */ - df::unit_labor::HAUL_FURNITURE, /* WEAPONRACK */ - df::unit_labor::HAUL_FURNITURE, /* CABINET */ - df::unit_labor::HAUL_ITEM, /* FIGURINE */ - df::unit_labor::HAUL_ITEM, /* AMULET */ - df::unit_labor::HAUL_ITEM, /* SCEPTER */ - df::unit_labor::HAUL_ITEM, /* AMMO */ - df::unit_labor::HAUL_ITEM, /* CROWN */ - df::unit_labor::HAUL_ITEM, /* RING */ - df::unit_labor::HAUL_ITEM, /* EARRING */ - df::unit_labor::HAUL_ITEM, /* BRACELET */ - df::unit_labor::HAUL_ITEM, /* GEM */ - df::unit_labor::HAUL_FURNITURE, /* ANVIL */ - df::unit_labor::HAUL_REFUSE, /* CORPSEPIECE */ - df::unit_labor::HAUL_REFUSE, /* REMAINS */ - df::unit_labor::HAUL_FOOD, /* MEAT */ - df::unit_labor::HAUL_FOOD, /* FISH */ - df::unit_labor::HAUL_FOOD, /* FISH_RAW */ - df::unit_labor::HAUL_REFUSE, /* VERMIN */ - df::unit_labor::HAUL_ITEM, /* PET */ - df::unit_labor::HAUL_ITEM, /* SEEDS */ - df::unit_labor::HAUL_FOOD, /* PLANT */ - df::unit_labor::HAUL_ITEM, /* SKIN_TANNED */ - df::unit_labor::HAUL_FOOD, /* LEAVES */ - df::unit_labor::HAUL_ITEM, /* THREAD */ - df::unit_labor::HAUL_ITEM, /* CLOTH */ - df::unit_labor::HAUL_ITEM, /* TOTEM */ - df::unit_labor::HAUL_ITEM, /* PANTS */ - df::unit_labor::HAUL_ITEM, /* BACKPACK */ - df::unit_labor::HAUL_ITEM, /* QUIVER */ - df::unit_labor::HAUL_FURNITURE, /* CATAPULTPARTS */ - df::unit_labor::HAUL_FURNITURE, /* BALLISTAPARTS */ - df::unit_labor::HAUL_FURNITURE, /* SIEGEAMMO */ - df::unit_labor::HAUL_FURNITURE, /* BALLISTAARROWHEAD */ - df::unit_labor::HAUL_FURNITURE, /* TRAPPARTS */ - df::unit_labor::HAUL_FURNITURE, /* TRAPCOMP */ - df::unit_labor::HAUL_FOOD, /* DRINK */ - df::unit_labor::HAUL_FOOD, /* POWDER_MISC */ - df::unit_labor::HAUL_FOOD, /* CHEESE */ - df::unit_labor::HAUL_FOOD, /* FOOD */ - df::unit_labor::HAUL_FOOD, /* LIQUID_MISC */ - df::unit_labor::HAUL_ITEM, /* COIN */ - df::unit_labor::HAUL_FOOD, /* GLOB */ - df::unit_labor::HAUL_STONE, /* ROCK */ - df::unit_labor::HAUL_FURNITURE, /* PIPE_SECTION */ - df::unit_labor::HAUL_FURNITURE, /* HATCH_COVER */ - df::unit_labor::HAUL_FURNITURE, /* GRATE */ - df::unit_labor::HAUL_FURNITURE, /* QUERN */ - df::unit_labor::HAUL_FURNITURE, /* MILLSTONE */ - df::unit_labor::HAUL_ITEM, /* SPLINT */ - df::unit_labor::HAUL_ITEM, /* CRUTCH */ - df::unit_labor::HAUL_FURNITURE, /* TRACTION_BENCH */ - df::unit_labor::HAUL_ITEM, /* ORTHOPEDIC_CAST */ - df::unit_labor::HAUL_ITEM, /* TOOL */ - df::unit_labor::HAUL_FURNITURE, /* SLAB */ - df::unit_labor::HAUL_FOOD, /* EGG */ - df::unit_labor::HAUL_ITEM, /* BOOK */ -}; - -static df::unit_labor workshop_build_labor[] = -{ - /* Carpenters */ df::unit_labor::CARPENTER, - /* Farmers */ df::unit_labor::PROCESS_PLANT, - /* Masons */ df::unit_labor::MASON, - /* Craftsdwarfs */ df::unit_labor::STONE_CRAFT, - /* Jewelers */ df::unit_labor::CUT_GEM, - /* MetalsmithsForge */ df::unit_labor::METAL_CRAFT, - /* MagmaForge */ df::unit_labor::METAL_CRAFT, - /* Bowyers */ df::unit_labor::BOWYER, - /* Mechanics */ df::unit_labor::MECHANIC, - /* Siege */ df::unit_labor::SIEGECRAFT, - /* Butchers */ df::unit_labor::BUTCHER, - /* Leatherworks */ df::unit_labor::LEATHER, - /* Tanners */ df::unit_labor::TANNER, - /* Clothiers */ df::unit_labor::CLOTHESMAKER, - /* Fishery */ df::unit_labor::CLEAN_FISH, - /* Still */ df::unit_labor::BREWER, - /* Loom */ df::unit_labor::WEAVER, - /* Quern */ df::unit_labor::MILLER, - /* Kennels */ df::unit_labor::ANIMALTRAIN, - /* Kitchen */ df::unit_labor::COOK, - /* Ashery */ df::unit_labor::LYE_MAKING, - /* Dyers */ df::unit_labor::DYER, - /* Millstone */ df::unit_labor::MILLER, - /* Custom */ df::unit_labor::NONE, - /* Tool */ df::unit_labor::NONE -}; - -static df::building* get_building_from_job(df::job* j) -{ - for (auto r = j->general_refs.begin(); r != j->general_refs.end(); r++) - { - if ((*r)->getType() == df::general_ref_type::BUILDING_HOLDER) - { - int32_t id = ((df::general_ref_building_holderst*)(*r))->building_id; - df::building* bld = binsearch_in_vector(world->buildings.all, id); - return bld; - } - } - return 0; -} - -static df::unit_labor construction_build_labor (df::building_actual* b) -{ - if (b->getType() == df::building_type::RoadPaved) - return df::unit_labor::BUILD_ROAD; - // Find last item in building with use mode appropriate to the building's constructions state - // For screw pumps contained_items[0] = pipe, 1 corkscrew, 2 block - // For wells 0 mechanism, 1 rope, 2 bucket, 3 block - // Trade depots and bridges use the last one too - // Must check use mode b/c buildings may have items in them that are not part of the building - - df::item* i = 0; - for (auto p = b->contained_items.begin(); p != b->contained_items.end(); p++) - if (b->construction_stage > 0 && (*p)->use_mode == 2 || - b->construction_stage == 0 && (*p)->use_mode == 0) - i = (*p)->item; - - MaterialInfo matinfo; - if (i && matinfo.decode(i)) - { - if (matinfo.material->flags.is_set(df::material_flags::IS_METAL)) - return df::unit_labor::METAL_CRAFT; - if (matinfo.material->flags.is_set(df::material_flags::WOOD)) - return df::unit_labor::CARPENTER; - } - return df::unit_labor::MASON; -} - color_ostream* debug_stream; -void debug (const char* fmt, ...) +void debug(const char* fmt, ...) { if (debug_stream) { va_list args; - va_start(args,fmt); + va_start(args, fmt); debug_stream->vprint(fmt, args); va_end(args); } } -void debug_pause () +void debug_pause() { if (pause_on_error) { @@ -722,707 +556,6 @@ void debug_pause () } } -class JobLaborMapper { - -private: - class jlfunc - { - public: - virtual df::unit_labor get_labor(df::job* j) = 0; - }; - - class jlfunc_const : public jlfunc - { - private: - df::unit_labor labor; - public: - df::unit_labor get_labor(df::job* j) - { - return labor; - } - jlfunc_const(df::unit_labor l) : labor(l) {}; - }; - - class jlfunc_hauling : public jlfunc - { - public: - df::unit_labor get_labor(df::job* j) - { - df::item* item = 0; - if (j->job_type == df::job_type::StoreItemInStockpile && j->item_subtype != -1) - return (df::unit_labor) j->item_subtype; - - for (auto i = j->items.begin(); i != j->items.end(); i++) - { - if ((*i)->role == 7) - { - item = (*i)->item; - break; - } - } - - if (item && item->flags.bits.container) - { - for (auto a = item->general_refs.begin(); a != item->general_refs.end(); a++) - { - if ((*a)->getType() == df::general_ref_type::CONTAINS_ITEM) - { - int item_id = ((df::general_ref_contains_itemst *) (*a))->item_id; - item = binsearch_in_vector(world->items.all, item_id); - break; - } - } - } - - df::unit_labor l = item ? hauling_labor_map[item->getType()] : df::unit_labor::HAUL_ITEM; - if (item && l == df::unit_labor::HAUL_REFUSE && item->flags.bits.dead_dwarf) - l = df::unit_labor::HAUL_BODY; - return l; - } - jlfunc_hauling() {}; - }; - - class jlfunc_construct_bld : public jlfunc - { - public: - df::unit_labor get_labor(df::job* j) - { - if (j->flags.bits.item_lost) - return df::unit_labor::NONE; - - df::building* bld = get_building_from_job (j); - switch (bld->getType()) - { - case df::building_type::Hive: - return df::unit_labor::BEEKEEPING; - case df::building_type::Workshop: - { - df::building_workshopst* ws = (df::building_workshopst*) bld; - if (ws->design && !ws->design->flags.bits.designed) - return df::unit_labor::ARCHITECT; - if (ws->type == df::workshop_type::Custom) - { - df::building_def* def = df::building_def::find(ws->custom_type); - return def->build_labors[0]; - } - else - return workshop_build_labor[ws->type]; - } - break; - case df::building_type::Construction: - return df::unit_labor::BUILD_CONSTRUCTION; - case df::building_type::Furnace: - case df::building_type::TradeDepot: - case df::building_type::Bridge: - case df::building_type::ArcheryTarget: - case df::building_type::WaterWheel: - case df::building_type::RoadPaved: - case df::building_type::Well: - case df::building_type::ScrewPump: - case df::building_type::Wagon: - case df::building_type::Shop: - case df::building_type::Support: - case df::building_type::Windmill: - { - df::building_actual* b = (df::building_actual*) bld; - if (b->design && !b->design->flags.bits.designed) - return df::unit_labor::ARCHITECT; - return construction_build_labor(b); - } - break; - case df::building_type::FarmPlot: - return df::unit_labor::PLANT; - case df::building_type::Chair: - case df::building_type::Bed: - case df::building_type::Table: - case df::building_type::Coffin: - case df::building_type::Door: - case df::building_type::Floodgate: - case df::building_type::Box: - case df::building_type::Weaponrack: - case df::building_type::Armorstand: - case df::building_type::Cabinet: - case df::building_type::Statue: - case df::building_type::WindowGlass: - case df::building_type::WindowGem: - case df::building_type::Cage: - case df::building_type::NestBox: - case df::building_type::TractionBench: - case df::building_type::Slab: - case df::building_type::Chain: - case df::building_type::GrateFloor: - case df::building_type::Hatch: - case df::building_type::BarsFloor: - case df::building_type::BarsVertical: - case df::building_type::GrateWall: - case df::building_type::Bookcase: - case df::building_type::Instrument: - return df::unit_labor::HAUL_FURNITURE; - case df::building_type::Trap: - case df::building_type::GearAssembly: - case df::building_type::AxleHorizontal: - case df::building_type::AxleVertical: - case df::building_type::Rollers: - return df::unit_labor::MECHANIC; - case df::building_type::AnimalTrap: - return df::unit_labor::TRAPPER; - case df::building_type::Civzone: - case df::building_type::Nest: - case df::building_type::Stockpile: - case df::building_type::Weapon: - return df::unit_labor::NONE; - case df::building_type::SiegeEngine: - return df::unit_labor::SIEGECRAFT; - case df::building_type::RoadDirt: - return df::unit_labor::BUILD_ROAD; - } - - debug ("LABORMANAGER: Cannot deduce labor for construct building job of type %s\n", - ENUM_KEY_STR(building_type, bld->getType()).c_str()); - debug_pause(); - - return df::unit_labor::NONE; - } - jlfunc_construct_bld() {} - }; - - class jlfunc_destroy_bld : public jlfunc - { - public: - df::unit_labor get_labor(df::job* j) - { - df::building* bld = get_building_from_job (j); - df::building_type type = bld->getType(); - - switch (bld->getType()) - { - case df::building_type::Hive: - return df::unit_labor::BEEKEEPING; - case df::building_type::Workshop: - { - df::building_workshopst* ws = (df::building_workshopst*) bld; - if (ws->type == df::workshop_type::Custom) - { - df::building_def* def = df::building_def::find(ws->custom_type); - return def->build_labors[0]; - } - else - return workshop_build_labor[ws->type]; - } - break; - case df::building_type::Construction: - return df::unit_labor::REMOVE_CONSTRUCTION; - case df::building_type::Furnace: - case df::building_type::TradeDepot: - case df::building_type::Wagon: - case df::building_type::Bridge: - case df::building_type::ScrewPump: - case df::building_type::ArcheryTarget: - case df::building_type::RoadPaved: - case df::building_type::Shop: - case df::building_type::Support: - case df::building_type::WaterWheel: - case df::building_type::Well: - case df::building_type::Windmill: - { - auto b = (df::building_actual*) bld; - return construction_build_labor(b); - } - break; - case df::building_type::FarmPlot: - return df::unit_labor::PLANT; - case df::building_type::Trap: - case df::building_type::AxleHorizontal: - case df::building_type::AxleVertical: - case df::building_type::GearAssembly: - case df::building_type::Rollers: - return df::unit_labor::MECHANIC; - case df::building_type::Chair: - case df::building_type::Bed: - case df::building_type::Table: - case df::building_type::Coffin: - case df::building_type::Door: - case df::building_type::Floodgate: - case df::building_type::Box: - case df::building_type::Weaponrack: - case df::building_type::Armorstand: - case df::building_type::Cabinet: - case df::building_type::Statue: - case df::building_type::WindowGlass: - case df::building_type::WindowGem: - case df::building_type::Cage: - case df::building_type::NestBox: - case df::building_type::TractionBench: - case df::building_type::Slab: - case df::building_type::Chain: - case df::building_type::Hatch: - case df::building_type::BarsFloor: - case df::building_type::BarsVertical: - case df::building_type::GrateFloor: - case df::building_type::GrateWall: - case df::building_type::Bookcase: - case df::building_type::Instrument: - return df::unit_labor::HAUL_FURNITURE; - case df::building_type::AnimalTrap: - return df::unit_labor::TRAPPER; - case df::building_type::Civzone: - case df::building_type::Nest: - case df::building_type::RoadDirt: - case df::building_type::Stockpile: - case df::building_type::Weapon: - return df::unit_labor::NONE; - case df::building_type::SiegeEngine: - return df::unit_labor::SIEGECRAFT; - } - - debug ("LABORMANAGER: Cannot deduce labor for destroy building job of type %s\n", - ENUM_KEY_STR(building_type, bld->getType()).c_str()); - debug_pause(); - - return df::unit_labor::NONE; - } - jlfunc_destroy_bld() {} - }; - - class jlfunc_make : public jlfunc - { - private: - df::unit_labor metaltype; - public: - df::unit_labor get_labor(df::job* j) - { - df::building* bld = get_building_from_job(j); - if (bld->getType() == df::building_type::Workshop) - { - df::workshop_type type = ((df::building_workshopst*)(bld))->type; - switch (type) - { - case df::workshop_type::Craftsdwarfs: - { - df::item_type jobitem = j->job_items[0]->item_type; - switch (jobitem) - { - case df::item_type::BOULDER: - return df::unit_labor::STONE_CRAFT; - case df::item_type::NONE: - if (j->material_category.bits.bone || - j->material_category.bits.horn || - j->material_category.bits.tooth || - j->material_category.bits.shell) - return df::unit_labor::BONE_CARVE; - else - { - debug ("LABORMANAGER: Cannot deduce labor for make crafts job (not bone)\n"); - debug_pause(); - return df::unit_labor::NONE; - } - case df::item_type::WOOD: - return df::unit_labor::WOOD_CRAFT; - case df::item_type::CLOTH: - return df::unit_labor::CLOTHESMAKER; - case df::item_type::SKIN_TANNED: - return df::unit_labor::LEATHER; - default: - debug ("LABORMANAGER: Cannot deduce labor for make crafts job, item type %s\n", - ENUM_KEY_STR(item_type, jobitem).c_str()); - debug_pause(); - return df::unit_labor::NONE; - } - } - case df::workshop_type::Masons: - return df::unit_labor::MASON; - case df::workshop_type::Carpenters: - return df::unit_labor::CARPENTER; - case df::workshop_type::Leatherworks: - return df::unit_labor::LEATHER; - case df::workshop_type::Clothiers: - return df::unit_labor::CLOTHESMAKER; - case df::workshop_type::Bowyers: - return df::unit_labor::BOWYER; - case df::workshop_type::MagmaForge: - case df::workshop_type::MetalsmithsForge: - return metaltype; - default: - debug ("LABORMANAGER: Cannot deduce labor for make job, workshop type %s\n", - ENUM_KEY_STR(workshop_type, type).c_str()); - debug_pause(); - return df::unit_labor::NONE; - } - } - else if (bld->getType() == df::building_type::Furnace) - { - df::furnace_type type = ((df::building_furnacest*)(bld))->type; - switch (type) - { - case df::furnace_type::MagmaGlassFurnace: - case df::furnace_type::GlassFurnace: - return df::unit_labor::GLASSMAKER; - default: - debug ("LABORMANAGER: Cannot deduce labor for make job, furnace type %s\n", - ENUM_KEY_STR(furnace_type, type).c_str()); - debug_pause(); - return df::unit_labor::NONE; - } - } - - debug ("LABORMANAGER: Cannot deduce labor for make job, building type %s\n", - ENUM_KEY_STR(building_type, bld->getType()).c_str()); - debug_pause(); - - return df::unit_labor::NONE; - } - - jlfunc_make (df::unit_labor mt) : metaltype(mt) {} - }; - - class jlfunc_custom : public jlfunc - { - public: - df::unit_labor get_labor(df::job* j) - { - for (auto r = world->raws.reactions.begin(); r != world->raws.reactions.end(); r++) - { - if ((*r)->code == j->reaction_name) - { - df::job_skill skill = (*r)->skill; - df::unit_labor labor = ENUM_ATTR(job_skill, labor, skill); - return labor; - } - } - return df::unit_labor::NONE; - } - jlfunc_custom() {} - }; - - map jlf_cache; - - jlfunc* jlf_const(df::unit_labor l) { - jlfunc* jlf; - if (jlf_cache.count(l) == 0) - { - jlf = new jlfunc_const(l); - jlf_cache[l] = jlf; - } - else - jlf = jlf_cache[l]; - - return jlf; - } -private: - std::map job_to_labor_table; - -public: - ~JobLaborMapper() - { - std::set log; - - for (auto i = jlf_cache.begin(); i != jlf_cache.end(); i++) - { - if (!log.count(i->second)) - { - log.insert(i->second); - delete i->second; - } - i->second = 0; - } - - FOR_ENUM_ITEMS (job_type, j) - { - if (j < 0) - continue; - - jlfunc* p = job_to_labor_table[j]; - if (!log.count(p)) - { - log.insert(p); - delete p; - } - job_to_labor_table[j] = 0; - } - } - - JobLaborMapper() - { - jlfunc* jlf_hauling = new jlfunc_hauling(); - jlfunc* jlf_make_furniture = new jlfunc_make(df::unit_labor::FORGE_FURNITURE); - jlfunc* jlf_make_object = new jlfunc_make(df::unit_labor::METAL_CRAFT); - jlfunc* jlf_make_armor = new jlfunc_make(df::unit_labor::FORGE_ARMOR); - jlfunc* jlf_make_weapon = new jlfunc_make(df::unit_labor::FORGE_WEAPON); - - jlfunc* jlf_no_labor = jlf_const(df::unit_labor::NONE); - - job_to_labor_table[df::job_type::CarveFortification] = jlf_const(df::unit_labor::DETAIL); - job_to_labor_table[df::job_type::DetailWall] = jlf_const(df::unit_labor::DETAIL); - job_to_labor_table[df::job_type::DetailFloor] = jlf_const(df::unit_labor::DETAIL); - job_to_labor_table[df::job_type::Dig] = jlf_const(df::unit_labor::MINE); - job_to_labor_table[df::job_type::CarveUpwardStaircase] = jlf_const(df::unit_labor::MINE); - job_to_labor_table[df::job_type::CarveDownwardStaircase] = jlf_const(df::unit_labor::MINE); - job_to_labor_table[df::job_type::CarveUpDownStaircase] = jlf_const(df::unit_labor::MINE); - job_to_labor_table[df::job_type::CarveRamp] = jlf_const(df::unit_labor::MINE); - job_to_labor_table[df::job_type::DigChannel] = jlf_const(df::unit_labor::MINE); - job_to_labor_table[df::job_type::FellTree] = jlf_const(df::unit_labor::CUTWOOD); - job_to_labor_table[df::job_type::GatherPlants] = jlf_const(df::unit_labor::HERBALIST); - job_to_labor_table[df::job_type::RemoveConstruction] = jlf_const(df::unit_labor::REMOVE_CONSTRUCTION); - job_to_labor_table[df::job_type::CollectWebs] = jlf_const(df::unit_labor::WEAVER); - job_to_labor_table[df::job_type::BringItemToDepot] = jlf_const(df::unit_labor::HAUL_TRADE); - job_to_labor_table[df::job_type::BringItemToShop] = jlf_no_labor; - job_to_labor_table[df::job_type::Eat] = jlf_no_labor; - job_to_labor_table[df::job_type::GetProvisions] = jlf_no_labor; - job_to_labor_table[df::job_type::Drink] = jlf_no_labor; - job_to_labor_table[df::job_type::Drink2] = jlf_no_labor; - job_to_labor_table[df::job_type::FillWaterskin] = jlf_no_labor; - job_to_labor_table[df::job_type::FillWaterskin2] = jlf_no_labor; - job_to_labor_table[df::job_type::Sleep] = jlf_no_labor; - job_to_labor_table[df::job_type::CollectSand] = jlf_const(df::unit_labor::HAUL_ITEM); - job_to_labor_table[df::job_type::Fish] = jlf_const(df::unit_labor::FISH); - job_to_labor_table[df::job_type::Hunt] = jlf_const(df::unit_labor::HUNT); - job_to_labor_table[df::job_type::HuntVermin] = jlf_no_labor; - job_to_labor_table[df::job_type::Kidnap] = jlf_no_labor; - job_to_labor_table[df::job_type::BeatCriminal] = jlf_no_labor; - job_to_labor_table[df::job_type::StartingFistFight] = jlf_no_labor; - job_to_labor_table[df::job_type::CollectTaxes] = jlf_no_labor; - job_to_labor_table[df::job_type::GuardTaxCollector] = jlf_no_labor; - job_to_labor_table[df::job_type::CatchLiveLandAnimal] = jlf_const(df::unit_labor::HUNT); - job_to_labor_table[df::job_type::CatchLiveFish] = jlf_const(df::unit_labor::FISH); - job_to_labor_table[df::job_type::ReturnKill] = jlf_no_labor; - job_to_labor_table[df::job_type::CheckChest] = jlf_no_labor; - job_to_labor_table[df::job_type::StoreOwnedItem] = jlf_no_labor; - job_to_labor_table[df::job_type::PlaceItemInTomb] = jlf_const(df::unit_labor::HAUL_BODY); - job_to_labor_table[df::job_type::StoreItemInStockpile] = jlf_hauling; - job_to_labor_table[df::job_type::StoreItemInBag] = jlf_hauling; - job_to_labor_table[df::job_type::StoreItemInHospital] = jlf_hauling; - job_to_labor_table[df::job_type::StoreWeapon] = jlf_hauling; - job_to_labor_table[df::job_type::StoreArmor] = jlf_hauling; - job_to_labor_table[df::job_type::StoreItemInBarrel] = jlf_hauling; - job_to_labor_table[df::job_type::StoreItemInBin] = jlf_hauling; - job_to_labor_table[df::job_type::SeekArtifact] = jlf_no_labor; - job_to_labor_table[df::job_type::SeekInfant] = jlf_no_labor; - job_to_labor_table[df::job_type::AttendParty] = jlf_no_labor; - job_to_labor_table[df::job_type::GoShopping] = jlf_no_labor; - job_to_labor_table[df::job_type::GoShopping2] = jlf_no_labor; - job_to_labor_table[df::job_type::Clean] = jlf_const(df::unit_labor::CLEAN); - job_to_labor_table[df::job_type::Rest] = jlf_no_labor; - job_to_labor_table[df::job_type::PickupEquipment] = jlf_no_labor; - job_to_labor_table[df::job_type::DumpItem] = jlf_const(df::unit_labor::HAUL_REFUSE); - job_to_labor_table[df::job_type::StrangeMoodCrafter] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodJeweller] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodForge] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodMagmaForge] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodBrooding] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodFell] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodCarpenter] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodMason] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodBowyer] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodTanner] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodWeaver] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodGlassmaker] = jlf_no_labor; - job_to_labor_table[df::job_type::StrangeMoodMechanics] = jlf_no_labor; - job_to_labor_table[df::job_type::ConstructBuilding] = new jlfunc_construct_bld(); - job_to_labor_table[df::job_type::ConstructDoor] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructFloodgate] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructBed] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructThrone] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructCoffin] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructTable] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructChest] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructBin] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructArmorStand] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructWeaponRack] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructCabinet] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructStatue] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructBlocks] = jlf_make_furniture; - job_to_labor_table[df::job_type::MakeRawGlass] = jlf_const(df::unit_labor::GLASSMAKER); - job_to_labor_table[df::job_type::MakeCrafts] = jlf_make_object; - job_to_labor_table[df::job_type::MintCoins] = jlf_const(df::unit_labor::METAL_CRAFT); - job_to_labor_table[df::job_type::CutGems] = jlf_const(df::unit_labor::CUT_GEM); - job_to_labor_table[df::job_type::CutGlass] = jlf_const(df::unit_labor::CUT_GEM); - job_to_labor_table[df::job_type::EncrustWithGems] = jlf_const(df::unit_labor::ENCRUST_GEM); - job_to_labor_table[df::job_type::EncrustWithGlass] = jlf_const(df::unit_labor::ENCRUST_GEM); - job_to_labor_table[df::job_type::DestroyBuilding] = new jlfunc_destroy_bld(); - job_to_labor_table[df::job_type::SmeltOre] = jlf_const(df::unit_labor::SMELT); - job_to_labor_table[df::job_type::MeltMetalObject] = jlf_const(df::unit_labor::SMELT); - job_to_labor_table[df::job_type::ExtractMetalStrands] = jlf_const(df::unit_labor::EXTRACT_STRAND); - job_to_labor_table[df::job_type::PlantSeeds] = jlf_const(df::unit_labor::PLANT); - job_to_labor_table[df::job_type::HarvestPlants] = jlf_const(df::unit_labor::PLANT); - job_to_labor_table[df::job_type::TrainHuntingAnimal] = jlf_const(df::unit_labor::ANIMALTRAIN); - job_to_labor_table[df::job_type::TrainWarAnimal] = jlf_const(df::unit_labor::ANIMALTRAIN); - job_to_labor_table[df::job_type::MakeWeapon] = jlf_make_weapon; - job_to_labor_table[df::job_type::ForgeAnvil] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructCatapultParts] = jlf_const(df::unit_labor::SIEGECRAFT); - job_to_labor_table[df::job_type::ConstructBallistaParts] = jlf_const(df::unit_labor::SIEGECRAFT); - job_to_labor_table[df::job_type::MakeArmor] = jlf_make_armor; - job_to_labor_table[df::job_type::MakeHelm] = jlf_make_armor; - job_to_labor_table[df::job_type::MakePants] = jlf_make_armor; - job_to_labor_table[df::job_type::StudWith] = jlf_make_object; - job_to_labor_table[df::job_type::ButcherAnimal] = jlf_const(df::unit_labor::BUTCHER); - job_to_labor_table[df::job_type::PrepareRawFish] = jlf_const(df::unit_labor::CLEAN_FISH); - job_to_labor_table[df::job_type::MillPlants] = jlf_const(df::unit_labor::MILLER); - job_to_labor_table[df::job_type::BaitTrap] = jlf_const(df::unit_labor::TRAPPER); - job_to_labor_table[df::job_type::MilkCreature] = jlf_const(df::unit_labor::MILK); - job_to_labor_table[df::job_type::MakeCheese] = jlf_const(df::unit_labor::MAKE_CHEESE); - job_to_labor_table[df::job_type::ProcessPlants] = jlf_const(df::unit_labor::PROCESS_PLANT); - job_to_labor_table[df::job_type::ProcessPlantsVial] = jlf_const(df::unit_labor::PROCESS_PLANT); - job_to_labor_table[df::job_type::ProcessPlantsBarrel] = jlf_const(df::unit_labor::PROCESS_PLANT); - job_to_labor_table[df::job_type::PrepareMeal] = jlf_const(df::unit_labor::COOK); - job_to_labor_table[df::job_type::WeaveCloth] = jlf_const(df::unit_labor::WEAVER); - job_to_labor_table[df::job_type::MakeGloves] = jlf_make_armor; - job_to_labor_table[df::job_type::MakeShoes] = jlf_make_armor; - job_to_labor_table[df::job_type::MakeShield] = jlf_make_armor; - job_to_labor_table[df::job_type::MakeCage] = jlf_make_furniture; - job_to_labor_table[df::job_type::MakeChain] = jlf_make_object; - job_to_labor_table[df::job_type::MakeFlask] = jlf_make_object; - job_to_labor_table[df::job_type::MakeGoblet] = jlf_make_object; - job_to_labor_table[df::job_type::MakeToy] = jlf_make_object; - job_to_labor_table[df::job_type::MakeAnimalTrap] = jlf_const(df::unit_labor::TRAPPER); - job_to_labor_table[df::job_type::MakeBarrel] = jlf_make_furniture; - job_to_labor_table[df::job_type::MakeBucket] = jlf_make_furniture; - job_to_labor_table[df::job_type::MakeWindow] = jlf_make_furniture; - job_to_labor_table[df::job_type::MakeTotem] = jlf_const(df::unit_labor::BONE_CARVE); - job_to_labor_table[df::job_type::MakeAmmo] = jlf_make_weapon; - job_to_labor_table[df::job_type::DecorateWith] = jlf_make_object; - job_to_labor_table[df::job_type::MakeBackpack] = jlf_make_object; - job_to_labor_table[df::job_type::MakeQuiver] = jlf_make_armor; - job_to_labor_table[df::job_type::MakeBallistaArrowHead] = jlf_make_weapon; - job_to_labor_table[df::job_type::AssembleSiegeAmmo] = jlf_const(df::unit_labor::SIEGECRAFT); - job_to_labor_table[df::job_type::LoadCatapult] = jlf_const(df::unit_labor::SIEGEOPERATE); - job_to_labor_table[df::job_type::LoadBallista] = jlf_const(df::unit_labor::SIEGEOPERATE); - job_to_labor_table[df::job_type::FireCatapult] = jlf_const(df::unit_labor::SIEGEOPERATE); - job_to_labor_table[df::job_type::FireBallista] = jlf_const(df::unit_labor::SIEGEOPERATE); - job_to_labor_table[df::job_type::ConstructMechanisms] = jlf_const(df::unit_labor::MECHANIC); - job_to_labor_table[df::job_type::MakeTrapComponent] = jlf_make_weapon; - job_to_labor_table[df::job_type::LoadCageTrap] = jlf_const(df::unit_labor::MECHANIC) ; - job_to_labor_table[df::job_type::LoadStoneTrap] = jlf_const(df::unit_labor::MECHANIC) ; - job_to_labor_table[df::job_type::LoadWeaponTrap] = jlf_const(df::unit_labor::MECHANIC) ; - job_to_labor_table[df::job_type::CleanTrap] = jlf_const(df::unit_labor::MECHANIC) ; - job_to_labor_table[df::job_type::CastSpell] = jlf_no_labor; - job_to_labor_table[df::job_type::LinkBuildingToTrigger] = jlf_const(df::unit_labor::MECHANIC) ; - job_to_labor_table[df::job_type::PullLever] = jlf_const(df::unit_labor::PULL_LEVER); - job_to_labor_table[df::job_type::ExtractFromPlants] = jlf_const(df::unit_labor::HERBALIST) ; - job_to_labor_table[df::job_type::ExtractFromRawFish] = jlf_const(df::unit_labor::DISSECT_FISH) ; - job_to_labor_table[df::job_type::ExtractFromLandAnimal] = jlf_const(df::unit_labor::DISSECT_VERMIN) ; - job_to_labor_table[df::job_type::TameVermin] = jlf_const(df::unit_labor::ANIMALTRAIN) ; - job_to_labor_table[df::job_type::TameAnimal] = jlf_const(df::unit_labor::ANIMALTRAIN) ; - job_to_labor_table[df::job_type::ChainAnimal] = jlf_const(df::unit_labor::HAUL_ANIMALS); - job_to_labor_table[df::job_type::UnchainAnimal] = jlf_const(df::unit_labor::HAUL_ANIMALS); - job_to_labor_table[df::job_type::UnchainPet] = jlf_no_labor; - job_to_labor_table[df::job_type::ReleaseLargeCreature] = jlf_const(df::unit_labor::HAUL_ANIMALS); - job_to_labor_table[df::job_type::ReleasePet] = jlf_no_labor; - job_to_labor_table[df::job_type::ReleaseSmallCreature] = jlf_no_labor; - job_to_labor_table[df::job_type::HandleSmallCreature] = jlf_no_labor; - job_to_labor_table[df::job_type::HandleLargeCreature] = jlf_const(df::unit_labor::HAUL_ANIMALS); - job_to_labor_table[df::job_type::CageLargeCreature] = jlf_const(df::unit_labor::HAUL_ANIMALS); - job_to_labor_table[df::job_type::CageSmallCreature] = jlf_no_labor; - job_to_labor_table[df::job_type::RecoverWounded] = jlf_const(df::unit_labor::RECOVER_WOUNDED); - job_to_labor_table[df::job_type::DiagnosePatient] = jlf_const(df::unit_labor::DIAGNOSE) ; - job_to_labor_table[df::job_type::ImmobilizeBreak] = jlf_const(df::unit_labor::BONE_SETTING) ; - job_to_labor_table[df::job_type::DressWound] = jlf_const(df::unit_labor::DRESSING_WOUNDS) ; - job_to_labor_table[df::job_type::CleanPatient] = jlf_const(df::unit_labor::DRESSING_WOUNDS) ; - job_to_labor_table[df::job_type::Surgery] = jlf_const(df::unit_labor::SURGERY) ; - job_to_labor_table[df::job_type::Suture] = jlf_const(df::unit_labor::SUTURING); - job_to_labor_table[df::job_type::SetBone] = jlf_const(df::unit_labor::BONE_SETTING) ; - job_to_labor_table[df::job_type::PlaceInTraction] = jlf_const(df::unit_labor::BONE_SETTING) ; - job_to_labor_table[df::job_type::DrainAquarium] = jlf_no_labor; - job_to_labor_table[df::job_type::FillAquarium] = jlf_no_labor; - job_to_labor_table[df::job_type::FillPond] = jlf_no_labor; - job_to_labor_table[df::job_type::GiveWater] = jlf_const(df::unit_labor::FEED_WATER_CIVILIANS) ; - job_to_labor_table[df::job_type::GiveFood] = jlf_const(df::unit_labor::FEED_WATER_CIVILIANS) ; - job_to_labor_table[df::job_type::GiveWater2] = jlf_no_labor; - job_to_labor_table[df::job_type::GiveFood2] = jlf_no_labor; - job_to_labor_table[df::job_type::RecoverPet] = jlf_no_labor; - job_to_labor_table[df::job_type::PitLargeAnimal] = jlf_const(df::unit_labor::HAUL_ANIMALS); - job_to_labor_table[df::job_type::PitSmallAnimal] = jlf_no_labor; - job_to_labor_table[df::job_type::SlaughterAnimal] = jlf_const(df::unit_labor::BUTCHER); - job_to_labor_table[df::job_type::MakeCharcoal] = jlf_const(df::unit_labor::BURN_WOOD); - job_to_labor_table[df::job_type::MakeAsh] = jlf_const(df::unit_labor::BURN_WOOD); - job_to_labor_table[df::job_type::MakeLye] = jlf_const(df::unit_labor::LYE_MAKING); - job_to_labor_table[df::job_type::MakePotashFromLye] = jlf_const(df::unit_labor::POTASH_MAKING); - job_to_labor_table[df::job_type::FertilizeField] = jlf_const(df::unit_labor::PLANT); - job_to_labor_table[df::job_type::MakePotashFromAsh] = jlf_const(df::unit_labor::POTASH_MAKING); - job_to_labor_table[df::job_type::DyeThread] = jlf_const(df::unit_labor::DYER); - job_to_labor_table[df::job_type::DyeCloth] = jlf_const(df::unit_labor::DYER); - job_to_labor_table[df::job_type::SewImage] = jlf_make_object; - job_to_labor_table[df::job_type::MakePipeSection] = jlf_make_furniture; - job_to_labor_table[df::job_type::OperatePump] = jlf_const(df::unit_labor::OPERATE_PUMP); - job_to_labor_table[df::job_type::ManageWorkOrders] = jlf_no_labor; - job_to_labor_table[df::job_type::UpdateStockpileRecords] = jlf_no_labor; - job_to_labor_table[df::job_type::TradeAtDepot] = jlf_no_labor; - job_to_labor_table[df::job_type::ConstructHatchCover] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructGrate] = jlf_make_furniture; - job_to_labor_table[df::job_type::RemoveStairs] = jlf_const(df::unit_labor::MINE); - job_to_labor_table[df::job_type::ConstructQuern] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructMillstone] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructSplint] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructCrutch] = jlf_make_furniture; - job_to_labor_table[df::job_type::ConstructTractionBench] = jlf_const(df::unit_labor::MECHANIC); - job_to_labor_table[df::job_type::CleanSelf] = jlf_no_labor; - job_to_labor_table[df::job_type::BringCrutch] = jlf_const(df::unit_labor::BONE_SETTING); - job_to_labor_table[df::job_type::ApplyCast] = jlf_const(df::unit_labor::BONE_SETTING); - job_to_labor_table[df::job_type::CustomReaction] = new jlfunc_custom(); - job_to_labor_table[df::job_type::ConstructSlab] = jlf_make_furniture; - job_to_labor_table[df::job_type::EngraveSlab] = jlf_const(df::unit_labor::DETAIL); - job_to_labor_table[df::job_type::ShearCreature] = jlf_const(df::unit_labor::SHEARER); - job_to_labor_table[df::job_type::SpinThread] = jlf_const(df::unit_labor::SPINNER); - job_to_labor_table[df::job_type::PenLargeAnimal] = jlf_const(df::unit_labor::HAUL_ANIMALS); - job_to_labor_table[df::job_type::PenSmallAnimal] = jlf_no_labor; - job_to_labor_table[df::job_type::MakeTool] = jlf_make_object; - job_to_labor_table[df::job_type::CollectClay] = jlf_const(df::unit_labor::POTTERY); - job_to_labor_table[df::job_type::InstallColonyInHive] = jlf_const(df::unit_labor::BEEKEEPING); - job_to_labor_table[df::job_type::CollectHiveProducts] = jlf_const(df::unit_labor::BEEKEEPING); - job_to_labor_table[df::job_type::CauseTrouble] = jlf_no_labor; - job_to_labor_table[df::job_type::DrinkBlood] = jlf_no_labor; - job_to_labor_table[df::job_type::ReportCrime] = jlf_no_labor; - job_to_labor_table[df::job_type::ExecuteCriminal] = jlf_no_labor; - job_to_labor_table[df::job_type::TrainAnimal] = jlf_const(df::unit_labor::ANIMALTRAIN); - job_to_labor_table[df::job_type::CarveTrack] = jlf_const(df::unit_labor::DETAIL); - job_to_labor_table[df::job_type::PushTrackVehicle] = jlf_const(df::unit_labor::HANDLE_VEHICLES); - job_to_labor_table[df::job_type::PlaceTrackVehicle] = jlf_const(df::unit_labor::HANDLE_VEHICLES); - job_to_labor_table[df::job_type::StoreItemInVehicle] = jlf_hauling; - job_to_labor_table[df::job_type::GeldAnimal] = jlf_const(df::unit_labor::GELD); - job_to_labor_table[df::job_type::MakeFigurine] = jlf_make_object; - job_to_labor_table[df::job_type::MakeAmulet] = jlf_make_object; - job_to_labor_table[df::job_type::MakeScepter] = jlf_make_object; - job_to_labor_table[df::job_type::MakeCrown] = jlf_make_object; - job_to_labor_table[df::job_type::MakeRing] = jlf_make_object; - job_to_labor_table[df::job_type::MakeEarring] = jlf_make_object; - job_to_labor_table[df::job_type::MakeBracelet] = jlf_make_object; - job_to_labor_table[df::job_type::MakeGem] = jlf_make_object; - - job_to_labor_table[df::job_type::StoreItemInLocation] = jlf_no_labor; // StoreItemInLocation - }; - - df::unit_labor find_job_labor(df::job* j) - { - if (j->job_type == df::job_type::CustomReaction) - { - for (auto r = world->raws.reactions.begin(); r != world->raws.reactions.end(); r++) - { - if ((*r)->code == j->reaction_name) - { - df::job_skill skill = (*r)->skill; - return ENUM_ATTR(job_skill, labor, skill); - } - } - return df::unit_labor::NONE; - } - - - df::unit_labor labor; - if (job_to_labor_table.count(j->job_type) == 0) - { - debug("LABORMANAGER: job has no job to labor table entry: %s (%d)\n", ENUM_KEY_STR(job_type, j->job_type).c_str(), j->job_type); - debug_pause(); - labor = df::unit_labor::NONE; - } else { - - labor = job_to_labor_table[j->job_type]->get_labor(j); - } - - return labor; - } -}; - -/* End of labor deducer */ - static JobLaborMapper* labor_mapper = 0; static bool initialized = false; @@ -1527,8 +660,8 @@ static void generate_labor_to_skill_map() } struct skill_attr_weight { - int phys_attr_weights [6]; - int mental_attr_weights [13]; + int phys_attr_weights[6]; + int mental_attr_weights[13]; }; static struct skill_attr_weight skill_attr_weights[ENUM_LAST_ITEM(job_skill) + 1] = @@ -1687,10 +820,10 @@ static void enable_plugin(color_ostream &out) init_state(); } -DFhackCExport command_result plugin_init ( color_ostream &out, std::vector &commands) +DFhackCExport command_result plugin_init(color_ostream &out, std::vector &commands) { // initialize labor infos table from default table - if(ARRAY_COUNT(default_labor_infos) != ENUM_LAST_ITEM(unit_labor) + 1) + if (ARRAY_COUNT(default_labor_infos) != ENUM_LAST_ITEM(unit_labor) + 1) return CR_FAILURE; // Fill the command list with your commands. @@ -1721,7 +854,7 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector busy_dwarfs; private: - void set_labor (dwarf_info_t* dwarf, df::unit_labor labor, bool value) + void set_labor(dwarf_info_t* dwarf, df::unit_labor labor, bool value) { if (labor >= 0 && labor <= ENUM_LAST_ITEM(unit_labor)) { @@ -1821,7 +954,7 @@ private: } } - void process_job (df::job* j) + void process_job(df::job* j) { if (j->flags.bits.suspend || j->flags.bits.item_lost) return; @@ -1860,7 +993,7 @@ private: } } - df::unit_labor labor = labor_mapper->find_job_labor (j); + df::unit_labor labor = labor_mapper->find_job_labor(j); if (labor != df::unit_labor::NONE) { @@ -1873,7 +1006,8 @@ private: if (d->bits.outside) labor_outside[labor] = true; } - } else { + } + else { labor_infos[labor].mark_assigned(); labor_in_use[labor]++; } @@ -1937,7 +1071,7 @@ private: if (bl->designation[x][y].bits.hidden) { df::coord p = bl->map_pos; - df::coord c(p.x, p.y, p.z-1); + df::coord c(p.x, p.y, p.z - 1); if (Maps::getTileDesignation(c)->bits.hidden) continue; } @@ -2145,7 +1279,7 @@ private: if (dwarf->dwarf->social_activities.size() > 0) { if (print_debug) - out.print ("Dwarf %s is engaged in a social activity. Info only.\n", dwarf->dwarf->name.first_name.c_str()); + out.print("Dwarf %s is engaged in a social activity. Info only.\n", dwarf->dwarf->name.first_name.c_str()); } if (dwarf->dwarf->profession == profession::BABY || @@ -2173,7 +1307,7 @@ private: state = OTHER; // dwarfs unable to grasp are incapable of nearly all labors dwarf->clear_all = true; if (print_debug) - out.print ("Dwarf %s is disabled, will not be assigned labors\n", dwarf->dwarf->name.first_name.c_str()); + out.print("Dwarf %s is disabled, will not be assigned labors\n", dwarf->dwarf->name.first_name.c_str()); } else { @@ -2260,7 +1394,7 @@ private: int high_skill = 0; - FOR_ENUM_ITEMS (unit_labor, labor) + FOR_ENUM_ITEMS(unit_labor, labor) { if (labor == df::unit_labor::NONE) continue; @@ -2287,7 +1421,8 @@ private: set_labor(dwarf, labor, false); } - } else { + } + else { if (state == IDLE) available_dwarfs.push_back(dwarf); @@ -2310,7 +1445,7 @@ private: busy_dwarfs.clear(); } - int score_labor (dwarf_info_t* d, df::unit_labor labor) + int score_labor(dwarf_info_t* d, df::unit_labor labor) { int skill_level = 0; int xp = 0; @@ -2405,51 +1540,51 @@ public: // add job entries for designation-related jobs - labor_needed[df::unit_labor::MINE] += dig_count; - labor_needed[df::unit_labor::CUTWOOD] += tree_count; - labor_needed[df::unit_labor::DETAIL] += detail_count; + labor_needed[df::unit_labor::MINE] += dig_count; + labor_needed[df::unit_labor::CUTWOOD] += tree_count; + labor_needed[df::unit_labor::DETAIL] += detail_count; labor_needed[df::unit_labor::HERBALIST] += plant_count; // add job entries for health care labor_needed[df::unit_labor::RECOVER_WOUNDED] += cnt_recover_wounded; - labor_needed[df::unit_labor::DIAGNOSE] += cnt_diagnosis; - labor_needed[df::unit_labor::BONE_SETTING] += cnt_immobilize; + labor_needed[df::unit_labor::DIAGNOSE] += cnt_diagnosis; + labor_needed[df::unit_labor::BONE_SETTING] += cnt_immobilize; labor_needed[df::unit_labor::DRESSING_WOUNDS] += cnt_dressing; labor_needed[df::unit_labor::DRESSING_WOUNDS] += cnt_cleaning; - labor_needed[df::unit_labor::SURGERY] += cnt_surgery; - labor_needed[df::unit_labor::SUTURING] += cnt_suture; - labor_needed[df::unit_labor::BONE_SETTING] += cnt_setting; - labor_needed[df::unit_labor::BONE_SETTING] += cnt_traction; - labor_needed[df::unit_labor::BONE_SETTING] += cnt_crutch; + labor_needed[df::unit_labor::SURGERY] += cnt_surgery; + labor_needed[df::unit_labor::SUTURING] += cnt_suture; + labor_needed[df::unit_labor::BONE_SETTING] += cnt_setting; + labor_needed[df::unit_labor::BONE_SETTING] += cnt_traction; + labor_needed[df::unit_labor::BONE_SETTING] += cnt_crutch; labor_needed[df::unit_labor::FEED_WATER_CIVILIANS] += need_food_water; // add entries for hauling jobs - labor_needed[df::unit_labor::HAUL_STONE] += world->stockpile.num_jobs[1]; - labor_needed[df::unit_labor::HAUL_WOOD] += world->stockpile.num_jobs[2]; - labor_needed[df::unit_labor::HAUL_ITEM] += world->stockpile.num_jobs[3]; - labor_needed[df::unit_labor::HAUL_ITEM] += world->stockpile.num_jobs[4]; - labor_needed[df::unit_labor::HAUL_BODY] += world->stockpile.num_jobs[5]; - labor_needed[df::unit_labor::HAUL_FOOD] += world->stockpile.num_jobs[6]; - labor_needed[df::unit_labor::HAUL_REFUSE] += world->stockpile.num_jobs[7]; + labor_needed[df::unit_labor::HAUL_STONE] += world->stockpile.num_jobs[1]; + labor_needed[df::unit_labor::HAUL_WOOD] += world->stockpile.num_jobs[2]; + labor_needed[df::unit_labor::HAUL_ITEM] += world->stockpile.num_jobs[3]; + labor_needed[df::unit_labor::HAUL_ITEM] += world->stockpile.num_jobs[4]; + labor_needed[df::unit_labor::HAUL_BODY] += world->stockpile.num_jobs[5]; + labor_needed[df::unit_labor::HAUL_FOOD] += world->stockpile.num_jobs[6]; + labor_needed[df::unit_labor::HAUL_REFUSE] += world->stockpile.num_jobs[7]; labor_needed[df::unit_labor::HAUL_FURNITURE] += world->stockpile.num_jobs[8]; - labor_needed[df::unit_labor::HAUL_ANIMALS] += world->stockpile.num_jobs[9]; - - labor_needed[df::unit_labor::HAUL_STONE] += (world->stockpile.num_jobs[1] >= world->stockpile.num_haulers[1]) ? 1 : 0; - labor_needed[df::unit_labor::HAUL_WOOD] += (world->stockpile.num_jobs[2] >= world->stockpile.num_haulers[2]) ? 1 : 0; - labor_needed[df::unit_labor::HAUL_ITEM] += (world->stockpile.num_jobs[3] >= world->stockpile.num_haulers[3]) ? 1 : 0; - labor_needed[df::unit_labor::HAUL_BODY] += (world->stockpile.num_jobs[5] >= world->stockpile.num_haulers[5]) ? 1 : 0; - labor_needed[df::unit_labor::HAUL_FOOD] += (world->stockpile.num_jobs[6] >= world->stockpile.num_haulers[6]) ? 1 : 0; - labor_needed[df::unit_labor::HAUL_REFUSE] += (world->stockpile.num_jobs[7] >= world->stockpile.num_haulers[7]) ? 1 : 0; + labor_needed[df::unit_labor::HAUL_ANIMALS] += world->stockpile.num_jobs[9]; + + labor_needed[df::unit_labor::HAUL_STONE] += (world->stockpile.num_jobs[1] >= world->stockpile.num_haulers[1]) ? 1 : 0; + labor_needed[df::unit_labor::HAUL_WOOD] += (world->stockpile.num_jobs[2] >= world->stockpile.num_haulers[2]) ? 1 : 0; + labor_needed[df::unit_labor::HAUL_ITEM] += (world->stockpile.num_jobs[3] >= world->stockpile.num_haulers[3]) ? 1 : 0; + labor_needed[df::unit_labor::HAUL_BODY] += (world->stockpile.num_jobs[5] >= world->stockpile.num_haulers[5]) ? 1 : 0; + labor_needed[df::unit_labor::HAUL_FOOD] += (world->stockpile.num_jobs[6] >= world->stockpile.num_haulers[6]) ? 1 : 0; + labor_needed[df::unit_labor::HAUL_REFUSE] += (world->stockpile.num_jobs[7] >= world->stockpile.num_haulers[7]) ? 1 : 0; labor_needed[df::unit_labor::HAUL_FURNITURE] += (world->stockpile.num_jobs[8] >= world->stockpile.num_haulers[8]) ? 1 : 0; - labor_needed[df::unit_labor::HAUL_ANIMALS] += (world->stockpile.num_jobs[9] >= world->stockpile.num_haulers[9]) ? 1 : 0; + labor_needed[df::unit_labor::HAUL_ANIMALS] += (world->stockpile.num_jobs[9] >= world->stockpile.num_haulers[9]) ? 1 : 0; int binjobs = world->stockpile.num_jobs[4] + ((world->stockpile.num_jobs[4] >= world->stockpile.num_haulers[4]) ? 1 : 0); - labor_needed[df::unit_labor::HAUL_ITEM] += binjobs; - labor_needed[df::unit_labor::HAUL_FOOD] += priority_food; + labor_needed[df::unit_labor::HAUL_ITEM] += binjobs; + labor_needed[df::unit_labor::HAUL_FOOD] += priority_food; // add entries for vehicle hauling @@ -2488,7 +1623,7 @@ public: labor_needed[l] = std::min(labor_needed[l], tool_count[default_labor_infos[l].tool] - tool_in_use[default_labor_infos[l].tool]); if (print_debug && before != labor_needed[l]) - out.print ("labor %s reduced from %d to %d\n", ENUM_KEY_STR(unit_labor, l).c_str(), before, labor_needed[l]); + out.print("labor %s reduced from %d to %d\n", ENUM_KEY_STR(unit_labor, l).c_str(), before, labor_needed[l]); } @@ -2498,7 +1633,7 @@ public: priority_food = 1; if (print_debug) - out.print ("priority food count = %d\n", priority_food); + out.print("priority food count = %d\n", priority_food); while (!available_dwarfs.empty() && priority_food > 0) { @@ -2529,7 +1664,7 @@ public: if (l == df::unit_labor::NONE) continue; - set_labor (*bestdwarf, l, l == df::unit_labor::HAUL_FOOD); + set_labor(*bestdwarf, l, l == df::unit_labor::HAUL_FOOD); } available_dwarfs.erase(bestdwarf); @@ -2544,7 +1679,7 @@ public: { for (auto i = labor_needed.begin(); i != labor_needed.end(); i++) { - out.print ("labor_needed [%s] = %d, busy = %d, outside = %d, idle = %d\n", ENUM_KEY_STR(unit_labor, i->first).c_str(), i->second, + out.print("labor_needed [%s] = %d, busy = %d, outside = %d, idle = %d\n", ENUM_KEY_STR(unit_labor, i->first).c_str(), i->second, labor_infos[i->first].busy_dwarfs, labor_outside[i->first], labor_infos[i->first].idle_dwarfs); } } @@ -2565,7 +1700,7 @@ public: int priority = labor_infos[l].priority(); - priority += labor_infos[l].time_since_last_assigned()/12; + priority += labor_infos[l].time_since_last_assigned() / 12; priority -= labor_infos[l].busy_dwarfs; base_priority[l] = priority; @@ -2583,7 +1718,7 @@ public: to_assign.clear(); - int av = available_dwarfs.size(); + size_t av = available_dwarfs.size(); while (!pq.empty() && av > 0) { @@ -2598,12 +1733,12 @@ public: if (--labor_needed[labor] > 0) { - priority-=10; + priority -= 10; pq2.push(make_pair(priority, labor)); } if (pq.empty()) - while(!pq2.empty()) + while (!pq2.empty()) { pq.push(pq2.top()); pq2.pop(); @@ -2665,7 +1800,7 @@ public: tools_enum t = default_labor_infos[l].tool; - if (l == best_labor && ( t == TOOL_NONE || tool_in_use[t] < tool_count[t]) ) + if (l == best_labor && (t == TOOL_NONE || tool_in_use[t] < tool_count[t])) { set_labor(*bestdwarf, l, true); if (t != TOOL_NONE && !((*bestdwarf)->has_tool[t])) @@ -2707,9 +1842,9 @@ public: for (auto d = busy_dwarfs.begin(); d != busy_dwarfs.end(); d++) { - int current_score = score_labor (*d, (*d)->using_labor); + int current_score = score_labor(*d, (*d)->using_labor); - FOR_ENUM_ITEMS (unit_labor, l) + FOR_ENUM_ITEMS(unit_labor, l) { if (l == df::unit_labor::NONE) continue; @@ -2718,7 +1853,7 @@ public: if (labor_needed[l] <= 0) continue; - int score = score_labor (*d, l); + int score = score_labor(*d, l); if (l == df::unit_labor::HAUL_FOOD && priority_food > 0) score += 1000000; @@ -2751,7 +1886,7 @@ public: if (canary_dwarf) { - FOR_ENUM_ITEMS (unit_labor, l) + FOR_ENUM_ITEMS(unit_labor, l) { if (l >= df::unit_labor::HAUL_STONE && l <= df::unit_labor::HAUL_ANIMALS && canary & (1 << l)) @@ -2763,22 +1898,22 @@ public: set_labor(canary_dwarf, df::unit_labor::REMOVE_CONSTRUCTION, true); if (print_debug) - out.print ("Setting %s as the hauling canary\n", canary_dwarf->dwarf->name.first_name.c_str()); + out.print("Setting %s as the hauling canary\n", canary_dwarf->dwarf->name.first_name.c_str()); } else { if (print_debug) - out.print ("No dwarf available to set as the hauling canary!\n"); + out.print("No dwarf available to set as the hauling canary!\n"); } /* Assign any leftover dwarfs to "standard" labors */ if (print_debug) - out.print ("After assignment, %d dwarfs left over\n", available_dwarfs.size()); + out.print("After assignment, %d dwarfs left over\n", available_dwarfs.size()); for (auto d = available_dwarfs.begin(); d != available_dwarfs.end(); d++) { - FOR_ENUM_ITEMS (unit_labor, l) + FOR_ENUM_ITEMS(unit_labor, l) { if (l == df::unit_labor::NONE) continue; @@ -2789,7 +1924,7 @@ public: l == df::unit_labor::REMOVE_CONSTRUCTION || l == df::unit_labor::PULL_LEVER || l == df::unit_labor::HAUL_TRADE); - } + } } /* check for dwarfs assigned no labors and assign them the bucket list if there are */ @@ -2799,7 +1934,7 @@ public: continue; bool any = false; - FOR_ENUM_ITEMS (unit_labor, l) + FOR_ENUM_ITEMS(unit_labor, l) { if (l == df::unit_labor::NONE) continue; @@ -2810,11 +1945,11 @@ public: } } - set_labor (*d, df::unit_labor::PULL_LEVER, true); + set_labor(*d, df::unit_labor::PULL_LEVER, true); if (any) continue; - FOR_ENUM_ITEMS (unit_labor, l) + FOR_ENUM_ITEMS(unit_labor, l) { if (l == df::unit_labor::NONE) continue; @@ -2835,7 +1970,7 @@ public: if ((*d)->dwarf->military.pickup_flags.bits.update) continue; - FOR_ENUM_ITEMS (unit_labor, l) + FOR_ENUM_ITEMS(unit_labor, l) { if (l == df::unit_labor::NONE) continue; @@ -2903,18 +2038,18 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan return CR_OK; } -DFhackCExport command_result plugin_onupdate ( color_ostream &out ) +DFhackCExport command_result plugin_onupdate(color_ostream &out) { static int step_count = 0; // check run conditions - if(!initialized || !world || !world->map.block_index || !enable_labormanager) + if (!initialized || !world || !world->map.block_index || !enable_labormanager) { // give up if we shouldn't be running' return CR_OK; } -// if (++step_count < 60) -// return CR_OK; + // if (++step_count < 60) + // return CR_OK; if (*df::global::process_jobs) return CR_OK; @@ -2928,7 +2063,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) return CR_OK; } -void print_labor (df::unit_labor labor, color_ostream &out) +void print_labor(df::unit_labor labor, color_ostream &out) { string labor_name = ENUM_KEY_STR(unit_labor, labor); out << labor_name << ": "; @@ -2942,7 +2077,7 @@ void print_labor (df::unit_labor labor, color_ostream &out) << endl; } -df::unit_labor lookup_labor_by_name (std::string& name) +df::unit_labor lookup_labor_by_name(std::string& name) { df::unit_labor labor = df::unit_labor::NONE; @@ -2955,7 +2090,7 @@ df::unit_labor lookup_labor_by_name (std::string& name) return labor; } -DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable ) +DFhackCExport command_result plugin_enable(color_ostream &out, bool enable) { if (!Core::getInstance().isWorldLoaded()) { out.printerr("World is not loaded: please load a fort first.\n"); @@ -2966,7 +2101,7 @@ DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable ) { enable_plugin(out); } - else if(!enable && enable_labormanager) + else if (!enable && enable_labormanager) { enable_labormanager = false; setOptionEnabled(CF_ENABLED, false); @@ -2977,7 +2112,7 @@ DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable ) return CR_OK; } -command_result labormanager (color_ostream &out, std::vector & parameters) +command_result labormanager(color_ostream &out, std::vector & parameters) { CoreSuspender suspend; @@ -3014,7 +2149,7 @@ command_result labormanager (color_ostream &out, std::vector & par if (parameters[2] == "none") v = 0; else - v = atoi (parameters[2].c_str()); + v = atoi(parameters[2].c_str()); if (parameters[0] == "max") labor_infos[labor].set_maximum_dwarfs(v); diff --git a/plugins/labormanager.h b/plugins/labormanager.h new file mode 100644 index 000000000..c958900b1 --- /dev/null +++ b/plugins/labormanager.h @@ -0,0 +1,4 @@ +#pragma once + +void debug(const char* fmt, ...); +void debug_pause(); diff --git a/plugins/labormanager_joblabormapper.cpp b/plugins/labormanager_joblabormapper.cpp new file mode 100644 index 000000000..c3e21c962 --- /dev/null +++ b/plugins/labormanager_joblabormapper.cpp @@ -0,0 +1,919 @@ +/*a + * This file contains the logic to attempt to intuit the labor required for + * a given job. This is way more complicated than it should be, but I have + * not figured out how to make it simpler. + * + * Usage: + * Instantiate an instance of the JobLaborMapper class + * Call the find_job_labor method of that class instance, + * passing the job as the only argument, to determine the labor for that job + * When done, destroy the instance + * + * The class should allow you to create multiple instances, although there is + * little benefit to doing so. jlfuncs are not reused across instances. + * + */ + + +#include "DataDefs.h" +#include "MiscUtils.h" +#include "modules/Materials.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include + +#include + +#include + +#include +#include + +using namespace std; +using std::string; +using std::endl; +using namespace DFHack; +using namespace df::enums; +using df::global::ui; +using df::global::world; + +#include "labormanager.h" +#include "labormanager_joblabormapper.h" + +static df::unit_labor hauling_labor_map[] = +{ + df::unit_labor::HAUL_ITEM, /* BAR */ + df::unit_labor::HAUL_STONE, /* SMALLGEM */ + df::unit_labor::HAUL_ITEM, /* BLOCKS */ + df::unit_labor::HAUL_STONE, /* ROUGH */ + df::unit_labor::HAUL_STONE, /* BOULDER */ + df::unit_labor::HAUL_WOOD, /* WOOD */ + df::unit_labor::HAUL_FURNITURE, /* DOOR */ + df::unit_labor::HAUL_FURNITURE, /* FLOODGATE */ + df::unit_labor::HAUL_FURNITURE, /* BED */ + df::unit_labor::HAUL_FURNITURE, /* CHAIR */ + df::unit_labor::HAUL_ITEM, /* CHAIN */ + df::unit_labor::HAUL_ITEM, /* FLASK */ + df::unit_labor::HAUL_ITEM, /* GOBLET */ + df::unit_labor::HAUL_ITEM, /* INSTRUMENT */ + df::unit_labor::HAUL_ITEM, /* TOY */ + df::unit_labor::HAUL_FURNITURE, /* WINDOW */ + df::unit_labor::HAUL_ANIMALS, /* CAGE */ + df::unit_labor::HAUL_ITEM, /* BARREL */ + df::unit_labor::HAUL_ITEM, /* BUCKET */ + df::unit_labor::HAUL_ANIMALS, /* ANIMALTRAP */ + df::unit_labor::HAUL_FURNITURE, /* TABLE */ + df::unit_labor::HAUL_FURNITURE, /* COFFIN */ + df::unit_labor::HAUL_FURNITURE, /* STATUE */ + df::unit_labor::HAUL_REFUSE, /* CORPSE */ + df::unit_labor::HAUL_ITEM, /* WEAPON */ + df::unit_labor::HAUL_ITEM, /* ARMOR */ + df::unit_labor::HAUL_ITEM, /* SHOES */ + df::unit_labor::HAUL_ITEM, /* SHIELD */ + df::unit_labor::HAUL_ITEM, /* HELM */ + df::unit_labor::HAUL_ITEM, /* GLOVES */ + df::unit_labor::HAUL_FURNITURE, /* BOX */ + df::unit_labor::HAUL_ITEM, /* BIN */ + df::unit_labor::HAUL_FURNITURE, /* ARMORSTAND */ + df::unit_labor::HAUL_FURNITURE, /* WEAPONRACK */ + df::unit_labor::HAUL_FURNITURE, /* CABINET */ + df::unit_labor::HAUL_ITEM, /* FIGURINE */ + df::unit_labor::HAUL_ITEM, /* AMULET */ + df::unit_labor::HAUL_ITEM, /* SCEPTER */ + df::unit_labor::HAUL_ITEM, /* AMMO */ + df::unit_labor::HAUL_ITEM, /* CROWN */ + df::unit_labor::HAUL_ITEM, /* RING */ + df::unit_labor::HAUL_ITEM, /* EARRING */ + df::unit_labor::HAUL_ITEM, /* BRACELET */ + df::unit_labor::HAUL_ITEM, /* GEM */ + df::unit_labor::HAUL_FURNITURE, /* ANVIL */ + df::unit_labor::HAUL_REFUSE, /* CORPSEPIECE */ + df::unit_labor::HAUL_REFUSE, /* REMAINS */ + df::unit_labor::HAUL_FOOD, /* MEAT */ + df::unit_labor::HAUL_FOOD, /* FISH */ + df::unit_labor::HAUL_FOOD, /* FISH_RAW */ + df::unit_labor::HAUL_REFUSE, /* VERMIN */ + df::unit_labor::HAUL_ITEM, /* PET */ + df::unit_labor::HAUL_ITEM, /* SEEDS */ + df::unit_labor::HAUL_FOOD, /* PLANT */ + df::unit_labor::HAUL_ITEM, /* SKIN_TANNED */ + df::unit_labor::HAUL_FOOD, /* LEAVES */ + df::unit_labor::HAUL_ITEM, /* THREAD */ + df::unit_labor::HAUL_ITEM, /* CLOTH */ + df::unit_labor::HAUL_ITEM, /* TOTEM */ + df::unit_labor::HAUL_ITEM, /* PANTS */ + df::unit_labor::HAUL_ITEM, /* BACKPACK */ + df::unit_labor::HAUL_ITEM, /* QUIVER */ + df::unit_labor::HAUL_FURNITURE, /* CATAPULTPARTS */ + df::unit_labor::HAUL_FURNITURE, /* BALLISTAPARTS */ + df::unit_labor::HAUL_FURNITURE, /* SIEGEAMMO */ + df::unit_labor::HAUL_FURNITURE, /* BALLISTAARROWHEAD */ + df::unit_labor::HAUL_FURNITURE, /* TRAPPARTS */ + df::unit_labor::HAUL_FURNITURE, /* TRAPCOMP */ + df::unit_labor::HAUL_FOOD, /* DRINK */ + df::unit_labor::HAUL_FOOD, /* POWDER_MISC */ + df::unit_labor::HAUL_FOOD, /* CHEESE */ + df::unit_labor::HAUL_FOOD, /* FOOD */ + df::unit_labor::HAUL_FOOD, /* LIQUID_MISC */ + df::unit_labor::HAUL_ITEM, /* COIN */ + df::unit_labor::HAUL_FOOD, /* GLOB */ + df::unit_labor::HAUL_STONE, /* ROCK */ + df::unit_labor::HAUL_FURNITURE, /* PIPE_SECTION */ + df::unit_labor::HAUL_FURNITURE, /* HATCH_COVER */ + df::unit_labor::HAUL_FURNITURE, /* GRATE */ + df::unit_labor::HAUL_FURNITURE, /* QUERN */ + df::unit_labor::HAUL_FURNITURE, /* MILLSTONE */ + df::unit_labor::HAUL_ITEM, /* SPLINT */ + df::unit_labor::HAUL_ITEM, /* CRUTCH */ + df::unit_labor::HAUL_FURNITURE, /* TRACTION_BENCH */ + df::unit_labor::HAUL_ITEM, /* ORTHOPEDIC_CAST */ + df::unit_labor::HAUL_ITEM, /* TOOL */ + df::unit_labor::HAUL_FURNITURE, /* SLAB */ + df::unit_labor::HAUL_FOOD, /* EGG */ + df::unit_labor::HAUL_ITEM, /* BOOK */ +}; + +static df::unit_labor workshop_build_labor[] = +{ + /* Carpenters */ df::unit_labor::CARPENTER, + /* Farmers */ df::unit_labor::PROCESS_PLANT, + /* Masons */ df::unit_labor::MASON, + /* Craftsdwarfs */ df::unit_labor::STONE_CRAFT, + /* Jewelers */ df::unit_labor::CUT_GEM, + /* MetalsmithsForge */ df::unit_labor::METAL_CRAFT, + /* MagmaForge */ df::unit_labor::METAL_CRAFT, + /* Bowyers */ df::unit_labor::BOWYER, + /* Mechanics */ df::unit_labor::MECHANIC, + /* Siege */ df::unit_labor::SIEGECRAFT, + /* Butchers */ df::unit_labor::BUTCHER, + /* Leatherworks */ df::unit_labor::LEATHER, + /* Tanners */ df::unit_labor::TANNER, + /* Clothiers */ df::unit_labor::CLOTHESMAKER, + /* Fishery */ df::unit_labor::CLEAN_FISH, + /* Still */ df::unit_labor::BREWER, + /* Loom */ df::unit_labor::WEAVER, + /* Quern */ df::unit_labor::MILLER, + /* Kennels */ df::unit_labor::ANIMALTRAIN, + /* Kitchen */ df::unit_labor::COOK, + /* Ashery */ df::unit_labor::LYE_MAKING, + /* Dyers */ df::unit_labor::DYER, + /* Millstone */ df::unit_labor::MILLER, + /* Custom */ df::unit_labor::NONE, + /* Tool */ df::unit_labor::NONE +}; + +static df::building* get_building_from_job(df::job* j) +{ + for (auto r = j->general_refs.begin(); r != j->general_refs.end(); r++) + { + if ((*r)->getType() == df::general_ref_type::BUILDING_HOLDER) + { + int32_t id = ((df::general_ref_building_holderst*)(*r))->building_id; + df::building* bld = binsearch_in_vector(world->buildings.all, id); + return bld; + } + } + return 0; +} + +static df::unit_labor construction_build_labor(df::building_actual* b) +{ + if (b->getType() == df::building_type::RoadPaved) + return df::unit_labor::BUILD_ROAD; + // Find last item in building with use mode appropriate to the building's constructions state + // For screw pumps contained_items[0] = pipe, 1 corkscrew, 2 block + // For wells 0 mechanism, 1 rope, 2 bucket, 3 block + // Trade depots and bridges use the last one too + // Must check use mode b/c buildings may have items in them that are not part of the building + + df::item* i = 0; + for (auto p = b->contained_items.begin(); p != b->contained_items.end(); p++) + if (b->construction_stage > 0 && (*p)->use_mode == 2 || + b->construction_stage == 0 && (*p)->use_mode == 0) + i = (*p)->item; + + MaterialInfo matinfo; + if (i && matinfo.decode(i)) + { + if (matinfo.material->flags.is_set(df::material_flags::IS_METAL)) + return df::unit_labor::METAL_CRAFT; + if (matinfo.material->flags.is_set(df::material_flags::WOOD)) + return df::unit_labor::CARPENTER; + } + return df::unit_labor::MASON; +} + + +class jlfunc +{ +public: + virtual df::unit_labor get_labor(df::job* j) = 0; +}; + +class jlfunc_const : public jlfunc +{ +private: + df::unit_labor labor; +public: + df::unit_labor get_labor(df::job* j) + { + return labor; + } + jlfunc_const(df::unit_labor l) : labor(l) {}; +}; + +class jlfunc_hauling : public jlfunc +{ +public: + df::unit_labor get_labor(df::job* j) + { + df::item* item = 0; + if (j->job_type == df::job_type::StoreItemInStockpile && j->item_subtype != -1) + return (df::unit_labor) j->item_subtype; + + for (auto i = j->items.begin(); i != j->items.end(); i++) + { + if ((*i)->role == 7) + { + item = (*i)->item; + break; + } + } + + if (item && item->flags.bits.container) + { + for (auto a = item->general_refs.begin(); a != item->general_refs.end(); a++) + { + if ((*a)->getType() == df::general_ref_type::CONTAINS_ITEM) + { + int item_id = ((df::general_ref_contains_itemst *) (*a))->item_id; + item = binsearch_in_vector(world->items.all, item_id); + break; + } + } + } + + df::unit_labor l = item ? hauling_labor_map[item->getType()] : df::unit_labor::HAUL_ITEM; + if (item && l == df::unit_labor::HAUL_REFUSE && item->flags.bits.dead_dwarf) + l = df::unit_labor::HAUL_BODY; + return l; + } + jlfunc_hauling() {}; +}; + +class jlfunc_construct_bld : public jlfunc +{ +public: + df::unit_labor get_labor(df::job* j) + { + if (j->flags.bits.item_lost) + return df::unit_labor::NONE; + + df::building* bld = get_building_from_job(j); + switch (bld->getType()) + { + case df::building_type::Hive: + return df::unit_labor::BEEKEEPING; + case df::building_type::Workshop: + { + df::building_workshopst* ws = (df::building_workshopst*) bld; + if (ws->design && !ws->design->flags.bits.designed) + return df::unit_labor::ARCHITECT; + if (ws->type == df::workshop_type::Custom) + { + df::building_def* def = df::building_def::find(ws->custom_type); + return def->build_labors[0]; + } + else + return workshop_build_labor[ws->type]; + } + break; + case df::building_type::Construction: + return df::unit_labor::BUILD_CONSTRUCTION; + case df::building_type::Furnace: + case df::building_type::TradeDepot: + case df::building_type::Bridge: + case df::building_type::ArcheryTarget: + case df::building_type::WaterWheel: + case df::building_type::RoadPaved: + case df::building_type::Well: + case df::building_type::ScrewPump: + case df::building_type::Wagon: + case df::building_type::Shop: + case df::building_type::Support: + case df::building_type::Windmill: + { + df::building_actual* b = (df::building_actual*) bld; + if (b->design && !b->design->flags.bits.designed) + return df::unit_labor::ARCHITECT; + return construction_build_labor(b); + } + break; + case df::building_type::FarmPlot: + return df::unit_labor::PLANT; + case df::building_type::Chair: + case df::building_type::Bed: + case df::building_type::Table: + case df::building_type::Coffin: + case df::building_type::Door: + case df::building_type::Floodgate: + case df::building_type::Box: + case df::building_type::Weaponrack: + case df::building_type::Armorstand: + case df::building_type::Cabinet: + case df::building_type::Statue: + case df::building_type::WindowGlass: + case df::building_type::WindowGem: + case df::building_type::Cage: + case df::building_type::NestBox: + case df::building_type::TractionBench: + case df::building_type::Slab: + case df::building_type::Chain: + case df::building_type::GrateFloor: + case df::building_type::Hatch: + case df::building_type::BarsFloor: + case df::building_type::BarsVertical: + case df::building_type::GrateWall: + case df::building_type::Bookcase: + case df::building_type::Instrument: + return df::unit_labor::HAUL_FURNITURE; + case df::building_type::Trap: + case df::building_type::GearAssembly: + case df::building_type::AxleHorizontal: + case df::building_type::AxleVertical: + case df::building_type::Rollers: + return df::unit_labor::MECHANIC; + case df::building_type::AnimalTrap: + return df::unit_labor::TRAPPER; + case df::building_type::Civzone: + case df::building_type::Nest: + case df::building_type::Stockpile: + case df::building_type::Weapon: + return df::unit_labor::NONE; + case df::building_type::SiegeEngine: + return df::unit_labor::SIEGECRAFT; + case df::building_type::RoadDirt: + return df::unit_labor::BUILD_ROAD; + } + + debug("LABORMANAGER: Cannot deduce labor for construct building job of type %s\n", + ENUM_KEY_STR(building_type, bld->getType()).c_str()); + debug_pause(); + + return df::unit_labor::NONE; + } + jlfunc_construct_bld() {} +}; + +class jlfunc_destroy_bld : public jlfunc +{ +public: + df::unit_labor get_labor(df::job* j) + { + df::building* bld = get_building_from_job(j); + df::building_type type = bld->getType(); + + switch (bld->getType()) + { + case df::building_type::Hive: + return df::unit_labor::BEEKEEPING; + case df::building_type::Workshop: + { + df::building_workshopst* ws = (df::building_workshopst*) bld; + if (ws->type == df::workshop_type::Custom) + { + df::building_def* def = df::building_def::find(ws->custom_type); + return def->build_labors[0]; + } + else + return workshop_build_labor[ws->type]; + } + break; + case df::building_type::Construction: + return df::unit_labor::REMOVE_CONSTRUCTION; + case df::building_type::Furnace: + case df::building_type::TradeDepot: + case df::building_type::Wagon: + case df::building_type::Bridge: + case df::building_type::ScrewPump: + case df::building_type::ArcheryTarget: + case df::building_type::RoadPaved: + case df::building_type::Shop: + case df::building_type::Support: + case df::building_type::WaterWheel: + case df::building_type::Well: + case df::building_type::Windmill: + { + auto b = (df::building_actual*) bld; + return construction_build_labor(b); + } + break; + case df::building_type::FarmPlot: + return df::unit_labor::PLANT; + case df::building_type::Trap: + case df::building_type::AxleHorizontal: + case df::building_type::AxleVertical: + case df::building_type::GearAssembly: + case df::building_type::Rollers: + return df::unit_labor::MECHANIC; + case df::building_type::Chair: + case df::building_type::Bed: + case df::building_type::Table: + case df::building_type::Coffin: + case df::building_type::Door: + case df::building_type::Floodgate: + case df::building_type::Box: + case df::building_type::Weaponrack: + case df::building_type::Armorstand: + case df::building_type::Cabinet: + case df::building_type::Statue: + case df::building_type::WindowGlass: + case df::building_type::WindowGem: + case df::building_type::Cage: + case df::building_type::NestBox: + case df::building_type::TractionBench: + case df::building_type::Slab: + case df::building_type::Chain: + case df::building_type::Hatch: + case df::building_type::BarsFloor: + case df::building_type::BarsVertical: + case df::building_type::GrateFloor: + case df::building_type::GrateWall: + case df::building_type::Bookcase: + case df::building_type::Instrument: + return df::unit_labor::HAUL_FURNITURE; + case df::building_type::AnimalTrap: + return df::unit_labor::TRAPPER; + case df::building_type::Civzone: + case df::building_type::Nest: + case df::building_type::RoadDirt: + case df::building_type::Stockpile: + case df::building_type::Weapon: + return df::unit_labor::NONE; + case df::building_type::SiegeEngine: + return df::unit_labor::SIEGECRAFT; + } + + debug("LABORMANAGER: Cannot deduce labor for destroy building job of type %s\n", + ENUM_KEY_STR(building_type, bld->getType()).c_str()); + debug_pause(); + + return df::unit_labor::NONE; + } + jlfunc_destroy_bld() {} +}; + +class jlfunc_make : public jlfunc +{ +private: + df::unit_labor metaltype; +public: + df::unit_labor get_labor(df::job* j) + { + df::building* bld = get_building_from_job(j); + if (bld->getType() == df::building_type::Workshop) + { + df::workshop_type type = ((df::building_workshopst*)(bld))->type; + switch (type) + { + case df::workshop_type::Craftsdwarfs: + { + df::item_type jobitem = j->job_items[0]->item_type; + switch (jobitem) + { + case df::item_type::BOULDER: + return df::unit_labor::STONE_CRAFT; + case df::item_type::NONE: + if (j->material_category.bits.bone || + j->material_category.bits.horn || + j->material_category.bits.tooth || + j->material_category.bits.shell) + return df::unit_labor::BONE_CARVE; + else + { + debug("LABORMANAGER: Cannot deduce labor for make crafts job (not bone)\n"); + debug_pause(); + return df::unit_labor::NONE; + } + case df::item_type::WOOD: + return df::unit_labor::WOOD_CRAFT; + case df::item_type::CLOTH: + return df::unit_labor::CLOTHESMAKER; + case df::item_type::SKIN_TANNED: + return df::unit_labor::LEATHER; + default: + debug("LABORMANAGER: Cannot deduce labor for make crafts job, item type %s\n", + ENUM_KEY_STR(item_type, jobitem).c_str()); + debug_pause(); + return df::unit_labor::NONE; + } + } + case df::workshop_type::Masons: + return df::unit_labor::MASON; + case df::workshop_type::Carpenters: + return df::unit_labor::CARPENTER; + case df::workshop_type::Leatherworks: + return df::unit_labor::LEATHER; + case df::workshop_type::Clothiers: + return df::unit_labor::CLOTHESMAKER; + case df::workshop_type::Bowyers: + return df::unit_labor::BOWYER; + case df::workshop_type::MagmaForge: + case df::workshop_type::MetalsmithsForge: + return metaltype; + default: + debug("LABORMANAGER: Cannot deduce labor for make job, workshop type %s\n", + ENUM_KEY_STR(workshop_type, type).c_str()); + debug_pause(); + return df::unit_labor::NONE; + } + } + else if (bld->getType() == df::building_type::Furnace) + { + df::furnace_type type = ((df::building_furnacest*)(bld))->type; + switch (type) + { + case df::furnace_type::MagmaGlassFurnace: + case df::furnace_type::GlassFurnace: + return df::unit_labor::GLASSMAKER; + default: + debug("LABORMANAGER: Cannot deduce labor for make job, furnace type %s\n", + ENUM_KEY_STR(furnace_type, type).c_str()); + debug_pause(); + return df::unit_labor::NONE; + } + } + + debug("LABORMANAGER: Cannot deduce labor for make job, building type %s\n", + ENUM_KEY_STR(building_type, bld->getType()).c_str()); + debug_pause(); + + return df::unit_labor::NONE; + } + + jlfunc_make(df::unit_labor mt) : metaltype(mt) {} +}; + +class jlfunc_custom : public jlfunc +{ +public: + df::unit_labor get_labor(df::job* j) + { + for (auto r = world->raws.reactions.begin(); r != world->raws.reactions.end(); r++) + { + if ((*r)->code == j->reaction_name) + { + df::job_skill skill = (*r)->skill; + df::unit_labor labor = ENUM_ATTR(job_skill, labor, skill); + return labor; + } + } + return df::unit_labor::NONE; + } + jlfunc_custom() {} +}; + +jlfunc* JobLaborMapper::jlf_const(df::unit_labor l) { + jlfunc* jlf; + if (jlf_cache.count(l) == 0) + { + jlf = new jlfunc_const(l); + jlf_cache[l] = jlf; + } + else + jlf = jlf_cache[l]; + + return jlf; +} + +JobLaborMapper::~JobLaborMapper() +{ + std::set log; + + for (auto i = jlf_cache.begin(); i != jlf_cache.end(); i++) + { + if (!log.count(i->second)) + { + log.insert(i->second); + delete i->second; + } + i->second = 0; + } + + FOR_ENUM_ITEMS(job_type, j) + { + if (j < 0) + continue; + + jlfunc* p = job_to_labor_table[j]; + if (!log.count(p)) + { + log.insert(p); + delete p; + } + job_to_labor_table[j] = 0; + } +} + +JobLaborMapper::JobLaborMapper() +{ + jlfunc* jlf_hauling = new jlfunc_hauling(); + jlfunc* jlf_make_furniture = new jlfunc_make(df::unit_labor::FORGE_FURNITURE); + jlfunc* jlf_make_object = new jlfunc_make(df::unit_labor::METAL_CRAFT); + jlfunc* jlf_make_armor = new jlfunc_make(df::unit_labor::FORGE_ARMOR); + jlfunc* jlf_make_weapon = new jlfunc_make(df::unit_labor::FORGE_WEAPON); + + jlfunc* jlf_no_labor = jlf_const(df::unit_labor::NONE); + + job_to_labor_table[df::job_type::CarveFortification] = jlf_const(df::unit_labor::DETAIL); + job_to_labor_table[df::job_type::DetailWall] = jlf_const(df::unit_labor::DETAIL); + job_to_labor_table[df::job_type::DetailFloor] = jlf_const(df::unit_labor::DETAIL); + job_to_labor_table[df::job_type::Dig] = jlf_const(df::unit_labor::MINE); + job_to_labor_table[df::job_type::CarveUpwardStaircase] = jlf_const(df::unit_labor::MINE); + job_to_labor_table[df::job_type::CarveDownwardStaircase] = jlf_const(df::unit_labor::MINE); + job_to_labor_table[df::job_type::CarveUpDownStaircase] = jlf_const(df::unit_labor::MINE); + job_to_labor_table[df::job_type::CarveRamp] = jlf_const(df::unit_labor::MINE); + job_to_labor_table[df::job_type::DigChannel] = jlf_const(df::unit_labor::MINE); + job_to_labor_table[df::job_type::FellTree] = jlf_const(df::unit_labor::CUTWOOD); + job_to_labor_table[df::job_type::GatherPlants] = jlf_const(df::unit_labor::HERBALIST); + job_to_labor_table[df::job_type::RemoveConstruction] = jlf_const(df::unit_labor::REMOVE_CONSTRUCTION); + job_to_labor_table[df::job_type::CollectWebs] = jlf_const(df::unit_labor::WEAVER); + job_to_labor_table[df::job_type::BringItemToDepot] = jlf_const(df::unit_labor::HAUL_TRADE); + job_to_labor_table[df::job_type::BringItemToShop] = jlf_no_labor; + job_to_labor_table[df::job_type::Eat] = jlf_no_labor; + job_to_labor_table[df::job_type::GetProvisions] = jlf_no_labor; + job_to_labor_table[df::job_type::Drink] = jlf_no_labor; + job_to_labor_table[df::job_type::Drink2] = jlf_no_labor; + job_to_labor_table[df::job_type::FillWaterskin] = jlf_no_labor; + job_to_labor_table[df::job_type::FillWaterskin2] = jlf_no_labor; + job_to_labor_table[df::job_type::Sleep] = jlf_no_labor; + job_to_labor_table[df::job_type::CollectSand] = jlf_const(df::unit_labor::HAUL_ITEM); + job_to_labor_table[df::job_type::Fish] = jlf_const(df::unit_labor::FISH); + job_to_labor_table[df::job_type::Hunt] = jlf_const(df::unit_labor::HUNT); + job_to_labor_table[df::job_type::HuntVermin] = jlf_no_labor; + job_to_labor_table[df::job_type::Kidnap] = jlf_no_labor; + job_to_labor_table[df::job_type::BeatCriminal] = jlf_no_labor; + job_to_labor_table[df::job_type::StartingFistFight] = jlf_no_labor; + job_to_labor_table[df::job_type::CollectTaxes] = jlf_no_labor; + job_to_labor_table[df::job_type::GuardTaxCollector] = jlf_no_labor; + job_to_labor_table[df::job_type::CatchLiveLandAnimal] = jlf_const(df::unit_labor::HUNT); + job_to_labor_table[df::job_type::CatchLiveFish] = jlf_const(df::unit_labor::FISH); + job_to_labor_table[df::job_type::ReturnKill] = jlf_no_labor; + job_to_labor_table[df::job_type::CheckChest] = jlf_no_labor; + job_to_labor_table[df::job_type::StoreOwnedItem] = jlf_no_labor; + job_to_labor_table[df::job_type::PlaceItemInTomb] = jlf_const(df::unit_labor::HAUL_BODY); + job_to_labor_table[df::job_type::StoreItemInStockpile] = jlf_hauling; + job_to_labor_table[df::job_type::StoreItemInBag] = jlf_hauling; + job_to_labor_table[df::job_type::StoreItemInHospital] = jlf_hauling; + job_to_labor_table[df::job_type::StoreWeapon] = jlf_hauling; + job_to_labor_table[df::job_type::StoreArmor] = jlf_hauling; + job_to_labor_table[df::job_type::StoreItemInBarrel] = jlf_hauling; + job_to_labor_table[df::job_type::StoreItemInBin] = jlf_hauling; + job_to_labor_table[df::job_type::SeekArtifact] = jlf_no_labor; + job_to_labor_table[df::job_type::SeekInfant] = jlf_no_labor; + job_to_labor_table[df::job_type::AttendParty] = jlf_no_labor; + job_to_labor_table[df::job_type::GoShopping] = jlf_no_labor; + job_to_labor_table[df::job_type::GoShopping2] = jlf_no_labor; + job_to_labor_table[df::job_type::Clean] = jlf_const(df::unit_labor::CLEAN); + job_to_labor_table[df::job_type::Rest] = jlf_no_labor; + job_to_labor_table[df::job_type::PickupEquipment] = jlf_no_labor; + job_to_labor_table[df::job_type::DumpItem] = jlf_const(df::unit_labor::HAUL_REFUSE); + job_to_labor_table[df::job_type::StrangeMoodCrafter] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodJeweller] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodForge] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodMagmaForge] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodBrooding] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodFell] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodCarpenter] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodMason] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodBowyer] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodTanner] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodWeaver] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodGlassmaker] = jlf_no_labor; + job_to_labor_table[df::job_type::StrangeMoodMechanics] = jlf_no_labor; + job_to_labor_table[df::job_type::ConstructBuilding] = new jlfunc_construct_bld(); + job_to_labor_table[df::job_type::ConstructDoor] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructFloodgate] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructBed] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructThrone] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructCoffin] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructTable] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructChest] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructBin] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructArmorStand] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructWeaponRack] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructCabinet] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructStatue] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructBlocks] = jlf_make_furniture; + job_to_labor_table[df::job_type::MakeRawGlass] = jlf_const(df::unit_labor::GLASSMAKER); + job_to_labor_table[df::job_type::MakeCrafts] = jlf_make_object; job_to_labor_table[df::job_type::MintCoins] = jlf_const(df::unit_labor::METAL_CRAFT); + job_to_labor_table[df::job_type::CutGems] = jlf_const(df::unit_labor::CUT_GEM); + job_to_labor_table[df::job_type::CutGlass] = jlf_const(df::unit_labor::CUT_GEM); + job_to_labor_table[df::job_type::EncrustWithGems] = jlf_const(df::unit_labor::ENCRUST_GEM); + job_to_labor_table[df::job_type::EncrustWithGlass] = jlf_const(df::unit_labor::ENCRUST_GEM); + job_to_labor_table[df::job_type::DestroyBuilding] = new jlfunc_destroy_bld(); + job_to_labor_table[df::job_type::SmeltOre] = jlf_const(df::unit_labor::SMELT); + job_to_labor_table[df::job_type::MeltMetalObject] = jlf_const(df::unit_labor::SMELT); + job_to_labor_table[df::job_type::ExtractMetalStrands] = jlf_const(df::unit_labor::EXTRACT_STRAND); + job_to_labor_table[df::job_type::PlantSeeds] = jlf_const(df::unit_labor::PLANT); + job_to_labor_table[df::job_type::HarvestPlants] = jlf_const(df::unit_labor::PLANT); + job_to_labor_table[df::job_type::TrainHuntingAnimal] = jlf_const(df::unit_labor::ANIMALTRAIN); + job_to_labor_table[df::job_type::TrainWarAnimal] = jlf_const(df::unit_labor::ANIMALTRAIN); + job_to_labor_table[df::job_type::MakeWeapon] = jlf_make_weapon; + job_to_labor_table[df::job_type::ForgeAnvil] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructCatapultParts] = jlf_const(df::unit_labor::SIEGECRAFT); + job_to_labor_table[df::job_type::ConstructBallistaParts] = jlf_const(df::unit_labor::SIEGECRAFT); + job_to_labor_table[df::job_type::MakeArmor] = jlf_make_armor; + job_to_labor_table[df::job_type::MakeHelm] = jlf_make_armor; + job_to_labor_table[df::job_type::MakePants] = jlf_make_armor; + job_to_labor_table[df::job_type::StudWith] = jlf_make_object; + job_to_labor_table[df::job_type::ButcherAnimal] = jlf_const(df::unit_labor::BUTCHER); + job_to_labor_table[df::job_type::PrepareRawFish] = jlf_const(df::unit_labor::CLEAN_FISH); + job_to_labor_table[df::job_type::MillPlants] = jlf_const(df::unit_labor::MILLER); + job_to_labor_table[df::job_type::BaitTrap] = jlf_const(df::unit_labor::TRAPPER); + job_to_labor_table[df::job_type::MilkCreature] = jlf_const(df::unit_labor::MILK); + job_to_labor_table[df::job_type::MakeCheese] = jlf_const(df::unit_labor::MAKE_CHEESE); + job_to_labor_table[df::job_type::ProcessPlants] = jlf_const(df::unit_labor::PROCESS_PLANT); + job_to_labor_table[df::job_type::ProcessPlantsVial] = jlf_const(df::unit_labor::PROCESS_PLANT); + job_to_labor_table[df::job_type::ProcessPlantsBarrel] = jlf_const(df::unit_labor::PROCESS_PLANT); + job_to_labor_table[df::job_type::PrepareMeal] = jlf_const(df::unit_labor::COOK); + job_to_labor_table[df::job_type::WeaveCloth] = jlf_const(df::unit_labor::WEAVER); + job_to_labor_table[df::job_type::MakeGloves] = jlf_make_armor; + job_to_labor_table[df::job_type::MakeShoes] = jlf_make_armor; + job_to_labor_table[df::job_type::MakeShield] = jlf_make_armor; + job_to_labor_table[df::job_type::MakeCage] = jlf_make_furniture; + job_to_labor_table[df::job_type::MakeChain] = jlf_make_object; + job_to_labor_table[df::job_type::MakeFlask] = jlf_make_object; + job_to_labor_table[df::job_type::MakeGoblet] = jlf_make_object; + job_to_labor_table[df::job_type::MakeToy] = jlf_make_object; + job_to_labor_table[df::job_type::MakeAnimalTrap] = jlf_const(df::unit_labor::TRAPPER); + job_to_labor_table[df::job_type::MakeBarrel] = jlf_make_furniture; + job_to_labor_table[df::job_type::MakeBucket] = jlf_make_furniture; + job_to_labor_table[df::job_type::MakeWindow] = jlf_make_furniture; + job_to_labor_table[df::job_type::MakeTotem] = jlf_const(df::unit_labor::BONE_CARVE); + job_to_labor_table[df::job_type::MakeAmmo] = jlf_make_weapon; + job_to_labor_table[df::job_type::DecorateWith] = jlf_make_object; + job_to_labor_table[df::job_type::MakeBackpack] = jlf_make_object; + job_to_labor_table[df::job_type::MakeQuiver] = jlf_make_armor; + job_to_labor_table[df::job_type::MakeBallistaArrowHead] = jlf_make_weapon; + job_to_labor_table[df::job_type::AssembleSiegeAmmo] = jlf_const(df::unit_labor::SIEGECRAFT); + job_to_labor_table[df::job_type::LoadCatapult] = jlf_const(df::unit_labor::SIEGEOPERATE); + job_to_labor_table[df::job_type::LoadBallista] = jlf_const(df::unit_labor::SIEGEOPERATE); + job_to_labor_table[df::job_type::FireCatapult] = jlf_const(df::unit_labor::SIEGEOPERATE); + job_to_labor_table[df::job_type::FireBallista] = jlf_const(df::unit_labor::SIEGEOPERATE); + job_to_labor_table[df::job_type::ConstructMechanisms] = jlf_const(df::unit_labor::MECHANIC); + job_to_labor_table[df::job_type::MakeTrapComponent] = jlf_make_weapon; + job_to_labor_table[df::job_type::LoadCageTrap] = jlf_const(df::unit_labor::MECHANIC); + job_to_labor_table[df::job_type::LoadStoneTrap] = jlf_const(df::unit_labor::MECHANIC); + job_to_labor_table[df::job_type::LoadWeaponTrap] = jlf_const(df::unit_labor::MECHANIC); + job_to_labor_table[df::job_type::CleanTrap] = jlf_const(df::unit_labor::MECHANIC); + job_to_labor_table[df::job_type::CastSpell] = jlf_no_labor; + job_to_labor_table[df::job_type::LinkBuildingToTrigger] = jlf_const(df::unit_labor::MECHANIC); + job_to_labor_table[df::job_type::PullLever] = jlf_const(df::unit_labor::PULL_LEVER); + job_to_labor_table[df::job_type::ExtractFromPlants] = jlf_const(df::unit_labor::HERBALIST); + job_to_labor_table[df::job_type::ExtractFromRawFish] = jlf_const(df::unit_labor::DISSECT_FISH); + job_to_labor_table[df::job_type::ExtractFromLandAnimal] = jlf_const(df::unit_labor::DISSECT_VERMIN); + job_to_labor_table[df::job_type::TameVermin] = jlf_const(df::unit_labor::ANIMALTRAIN); + job_to_labor_table[df::job_type::TameAnimal] = jlf_const(df::unit_labor::ANIMALTRAIN); + job_to_labor_table[df::job_type::ChainAnimal] = jlf_const(df::unit_labor::HAUL_ANIMALS); + job_to_labor_table[df::job_type::UnchainAnimal] = jlf_const(df::unit_labor::HAUL_ANIMALS); + job_to_labor_table[df::job_type::UnchainPet] = jlf_no_labor; + job_to_labor_table[df::job_type::ReleaseLargeCreature] = jlf_const(df::unit_labor::HAUL_ANIMALS); + job_to_labor_table[df::job_type::ReleasePet] = jlf_no_labor; + job_to_labor_table[df::job_type::ReleaseSmallCreature] = jlf_no_labor; + job_to_labor_table[df::job_type::HandleSmallCreature] = jlf_no_labor; + job_to_labor_table[df::job_type::HandleLargeCreature] = jlf_const(df::unit_labor::HAUL_ANIMALS); + job_to_labor_table[df::job_type::CageLargeCreature] = jlf_const(df::unit_labor::HAUL_ANIMALS); + job_to_labor_table[df::job_type::CageSmallCreature] = jlf_no_labor; + job_to_labor_table[df::job_type::RecoverWounded] = jlf_const(df::unit_labor::RECOVER_WOUNDED); + job_to_labor_table[df::job_type::DiagnosePatient] = jlf_const(df::unit_labor::DIAGNOSE); + job_to_labor_table[df::job_type::ImmobilizeBreak] = jlf_const(df::unit_labor::BONE_SETTING); + job_to_labor_table[df::job_type::DressWound] = jlf_const(df::unit_labor::DRESSING_WOUNDS); + job_to_labor_table[df::job_type::CleanPatient] = jlf_const(df::unit_labor::DRESSING_WOUNDS); + job_to_labor_table[df::job_type::Surgery] = jlf_const(df::unit_labor::SURGERY); + job_to_labor_table[df::job_type::Suture] = jlf_const(df::unit_labor::SUTURING); + job_to_labor_table[df::job_type::SetBone] = jlf_const(df::unit_labor::BONE_SETTING); + job_to_labor_table[df::job_type::PlaceInTraction] = jlf_const(df::unit_labor::BONE_SETTING); + job_to_labor_table[df::job_type::DrainAquarium] = jlf_no_labor; + job_to_labor_table[df::job_type::FillAquarium] = jlf_no_labor; + job_to_labor_table[df::job_type::FillPond] = jlf_no_labor; + job_to_labor_table[df::job_type::GiveWater] = jlf_const(df::unit_labor::FEED_WATER_CIVILIANS); + job_to_labor_table[df::job_type::GiveFood] = jlf_const(df::unit_labor::FEED_WATER_CIVILIANS); + job_to_labor_table[df::job_type::GiveWater2] = jlf_no_labor; + job_to_labor_table[df::job_type::GiveFood2] = jlf_no_labor; + job_to_labor_table[df::job_type::RecoverPet] = jlf_no_labor; + job_to_labor_table[df::job_type::PitLargeAnimal] = jlf_const(df::unit_labor::HAUL_ANIMALS); + job_to_labor_table[df::job_type::PitSmallAnimal] = jlf_no_labor; + job_to_labor_table[df::job_type::SlaughterAnimal] = jlf_const(df::unit_labor::BUTCHER); + job_to_labor_table[df::job_type::MakeCharcoal] = jlf_const(df::unit_labor::BURN_WOOD); + job_to_labor_table[df::job_type::MakeAsh] = jlf_const(df::unit_labor::BURN_WOOD); + job_to_labor_table[df::job_type::MakeLye] = jlf_const(df::unit_labor::LYE_MAKING); + job_to_labor_table[df::job_type::MakePotashFromLye] = jlf_const(df::unit_labor::POTASH_MAKING); + job_to_labor_table[df::job_type::FertilizeField] = jlf_const(df::unit_labor::PLANT); + job_to_labor_table[df::job_type::MakePotashFromAsh] = jlf_const(df::unit_labor::POTASH_MAKING); + job_to_labor_table[df::job_type::DyeThread] = jlf_const(df::unit_labor::DYER); + job_to_labor_table[df::job_type::DyeCloth] = jlf_const(df::unit_labor::DYER); + job_to_labor_table[df::job_type::SewImage] = jlf_make_object; + job_to_labor_table[df::job_type::MakePipeSection] = jlf_make_furniture; + job_to_labor_table[df::job_type::OperatePump] = jlf_const(df::unit_labor::OPERATE_PUMP); + job_to_labor_table[df::job_type::ManageWorkOrders] = jlf_no_labor; + job_to_labor_table[df::job_type::UpdateStockpileRecords] = jlf_no_labor; + job_to_labor_table[df::job_type::TradeAtDepot] = jlf_no_labor; + job_to_labor_table[df::job_type::ConstructHatchCover] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructGrate] = jlf_make_furniture; + job_to_labor_table[df::job_type::RemoveStairs] = jlf_const(df::unit_labor::MINE); + job_to_labor_table[df::job_type::ConstructQuern] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructMillstone] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructSplint] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructCrutch] = jlf_make_furniture; + job_to_labor_table[df::job_type::ConstructTractionBench] = jlf_const(df::unit_labor::MECHANIC); + job_to_labor_table[df::job_type::CleanSelf] = jlf_no_labor; + job_to_labor_table[df::job_type::BringCrutch] = jlf_const(df::unit_labor::BONE_SETTING); + job_to_labor_table[df::job_type::ApplyCast] = jlf_const(df::unit_labor::BONE_SETTING); + job_to_labor_table[df::job_type::CustomReaction] = new jlfunc_custom(); + job_to_labor_table[df::job_type::ConstructSlab] = jlf_make_furniture; + job_to_labor_table[df::job_type::EngraveSlab] = jlf_const(df::unit_labor::DETAIL); + job_to_labor_table[df::job_type::ShearCreature] = jlf_const(df::unit_labor::SHEARER); + job_to_labor_table[df::job_type::SpinThread] = jlf_const(df::unit_labor::SPINNER); + job_to_labor_table[df::job_type::PenLargeAnimal] = jlf_const(df::unit_labor::HAUL_ANIMALS); + job_to_labor_table[df::job_type::PenSmallAnimal] = jlf_no_labor; + job_to_labor_table[df::job_type::MakeTool] = jlf_make_object; + job_to_labor_table[df::job_type::CollectClay] = jlf_const(df::unit_labor::POTTERY); + job_to_labor_table[df::job_type::InstallColonyInHive] = jlf_const(df::unit_labor::BEEKEEPING); + job_to_labor_table[df::job_type::CollectHiveProducts] = jlf_const(df::unit_labor::BEEKEEPING); + job_to_labor_table[df::job_type::CauseTrouble] = jlf_no_labor; + job_to_labor_table[df::job_type::DrinkBlood] = jlf_no_labor; + job_to_labor_table[df::job_type::ReportCrime] = jlf_no_labor; + job_to_labor_table[df::job_type::ExecuteCriminal] = jlf_no_labor; + job_to_labor_table[df::job_type::TrainAnimal] = jlf_const(df::unit_labor::ANIMALTRAIN); + job_to_labor_table[df::job_type::CarveTrack] = jlf_const(df::unit_labor::DETAIL); + job_to_labor_table[df::job_type::PushTrackVehicle] = jlf_const(df::unit_labor::HANDLE_VEHICLES); + job_to_labor_table[df::job_type::PlaceTrackVehicle] = jlf_const(df::unit_labor::HANDLE_VEHICLES); + job_to_labor_table[df::job_type::StoreItemInVehicle] = jlf_hauling; + job_to_labor_table[df::job_type::GeldAnimal] = jlf_const(df::unit_labor::GELD); + job_to_labor_table[df::job_type::MakeFigurine] = jlf_make_object; + job_to_labor_table[df::job_type::MakeAmulet] = jlf_make_object; + job_to_labor_table[df::job_type::MakeScepter] = jlf_make_object; + job_to_labor_table[df::job_type::MakeCrown] = jlf_make_object; + job_to_labor_table[df::job_type::MakeRing] = jlf_make_object; + job_to_labor_table[df::job_type::MakeEarring] = jlf_make_object; + job_to_labor_table[df::job_type::MakeBracelet] = jlf_make_object; + job_to_labor_table[df::job_type::MakeGem] = jlf_make_object; + + job_to_labor_table[df::job_type::StoreItemInLocation] = jlf_no_labor; // StoreItemInLocation +}; + +df::unit_labor JobLaborMapper::find_job_labor(df::job* j) +{ + if (j->job_type == df::job_type::CustomReaction) + { + for (auto r = world->raws.reactions.begin(); r != world->raws.reactions.end(); r++) + { + if ((*r)->code == j->reaction_name) + { + df::job_skill skill = (*r)->skill; + return ENUM_ATTR(job_skill, labor, skill); + } + } + return df::unit_labor::NONE; + } + + + df::unit_labor labor; + if (job_to_labor_table.count(j->job_type) == 0) + { + debug("LABORMANAGER: job has no job to labor table entry: %s (%d)\n", ENUM_KEY_STR(job_type, j->job_type).c_str(), j->job_type); + debug_pause(); + labor = df::unit_labor::NONE; + } + else { + + labor = job_to_labor_table[j->job_type]->get_labor(j); + } + + return labor; +} + +/* End of labor deducer */ \ No newline at end of file diff --git a/plugins/labormanager_joblabormapper.h b/plugins/labormanager_joblabormapper.h new file mode 100644 index 000000000..5bc14d72a --- /dev/null +++ b/plugins/labormanager_joblabormapper.h @@ -0,0 +1,21 @@ +#pragma once + + +class jlfunc; + +class JobLaborMapper { + +private: + std::map job_to_labor_table; + std::map jlf_cache; + + jlfunc* JobLaborMapper::jlf_const(df::unit_labor l); + +public: + ~JobLaborMapper(); + JobLaborMapper(); + + df::unit_labor find_job_labor(df::job* j); + + +}; From fd19935fe95d5150168d1db48292d01961291da1 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Sat, 22 Jul 2017 04:54:05 -0500 Subject: [PATCH 08/66] labormanager: remove stupid --- plugins/labormanager_joblabormapper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/labormanager_joblabormapper.h b/plugins/labormanager_joblabormapper.h index 5bc14d72a..adde5c340 100644 --- a/plugins/labormanager_joblabormapper.h +++ b/plugins/labormanager_joblabormapper.h @@ -9,7 +9,7 @@ private: std::map job_to_labor_table; std::map jlf_cache; - jlfunc* JobLaborMapper::jlf_const(df::unit_labor l); + jlfunc* jlf_const(df::unit_labor l); public: ~JobLaborMapper(); From 92a962a9c028b772090973a4e8e05b0307745339 Mon Sep 17 00:00:00 2001 From: Japa Date: Tue, 25 Jul 2017 08:31:02 +0530 Subject: [PATCH 09/66] Send grass levels over RemoteFortressReader --- plugins/proto/RemoteFortressReader.proto | 1 + .../remotefortressreader/remotefortressreader.cpp | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/plugins/proto/RemoteFortressReader.proto b/plugins/proto/RemoteFortressReader.proto index a1f8e1bdb..f2218dfb6 100644 --- a/plugins/proto/RemoteFortressReader.proto +++ b/plugins/proto/RemoteFortressReader.proto @@ -256,6 +256,7 @@ message MapBlock repeated Item items = 26; repeated bool tile_dig_designation_marker = 27; repeated bool tile_dig_designation_auto = 28; + repeated int32 grass_percent = 29; } message MatPair { diff --git a/plugins/remotefortressreader/remotefortressreader.cpp b/plugins/remotefortressreader/remotefortressreader.cpp index 9b19edcc6..57f08d713 100644 --- a/plugins/remotefortressreader/remotefortressreader.cpp +++ b/plugins/remotefortressreader/remotefortressreader.cpp @@ -34,6 +34,7 @@ #include "df/army.h" #include "df/army_flags.h" #include "df/block_square_event_item_spatterst.h" +#include "df/block_square_event_grassst.h" #endif #include "df/block_square_event_material_spatterst.h" #include "df/body_appearance_modifier.h" @@ -1224,7 +1225,8 @@ void Copyspatters(df::map_block * DfBlock, RemoteFortressReader::MapBlock * NetB std::vector materials; #if DF_VERSION_INT > 34011 std::vector items; - if (!Maps::SortBlockEvents(DfBlock, NULL, NULL, &materials, NULL, NULL, NULL, &items)) + std::vector grasses; + if (!Maps::SortBlockEvents(DfBlock, NULL, NULL, &materials, &grasses, NULL, NULL, &items)) return; #else if (!Maps::SortBlockEvents(DfBlock, NULL, NULL, &materials, NULL, NULL)) @@ -1257,6 +1259,14 @@ void Copyspatters(df::map_block * DfBlock, RemoteFortressReader::MapBlock * NetB send_item->set_mat_type(item->item_type); send_item->set_mat_index(item->item_subtype); } + int grassPercent = 0; + for (int i = 0; i < grasses.size(); i++) + { + auto grass = grasses[i]; + if (grass->amount[xx][yy] > grassPercent) + grassPercent = grass->amount[xx][yy]; + } + NetBlock->add_grass_percent(grassPercent); #endif } } From 8ae7a1235df2f9fd7e7a084f7266892376ad765a Mon Sep 17 00:00:00 2001 From: Japa Date: Thu, 27 Jul 2017 18:41:46 +0530 Subject: [PATCH 10/66] Add rider ID to creatures --- plugins/proto/RemoteFortressReader.proto | 1 + plugins/remotefortressreader/remotefortressreader.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/plugins/proto/RemoteFortressReader.proto b/plugins/proto/RemoteFortressReader.proto index f2218dfb6..8e9fd4a58 100644 --- a/plugins/proto/RemoteFortressReader.proto +++ b/plugins/proto/RemoteFortressReader.proto @@ -336,6 +336,7 @@ message UnitDefinition optional UnitAppearance appearance = 16; optional int32 profession_id = 17; repeated string noble_positions = 18; + optional int32 rider_id = 19; } message UnitList diff --git a/plugins/remotefortressreader/remotefortressreader.cpp b/plugins/remotefortressreader/remotefortressreader.cpp index 57f08d713..7fe879645 100644 --- a/plugins/remotefortressreader/remotefortressreader.cpp +++ b/plugins/remotefortressreader/remotefortressreader.cpp @@ -105,6 +105,8 @@ #include "df/plant_tree_tile.h" #endif +#include "df/unit_relationship_type.h" + #include "building_reader.h" using namespace DFHack; @@ -1574,6 +1576,8 @@ static command_result GetUnitList(color_ostream &stream, const EmptyMessage *in, send_unit->add_noble_positions(noble_positon.position->code); } } + + send_unit->set_rider_id(unit->relationship_ids[df::unit_relationship_type::RiderMount]); } return CR_OK; } From a7d21fd62756fc28487041b88dfc384b2a52cf6d Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Fri, 28 Jul 2017 02:28:16 -0500 Subject: [PATCH 11/66] move labormanager into a subdirectory --- plugins/CMakeLists.txt | 2 +- plugins/labormanager/CMakeLists.txt | 34 +++++++++++++++++++ plugins/{ => labormanager}/labormanager.cpp | 0 plugins/{ => labormanager}/labormanager.h | 0 .../labormanager_joblabormapper.cpp | 0 .../labormanager_joblabormapper.h | 0 6 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 plugins/labormanager/CMakeLists.txt rename plugins/{ => labormanager}/labormanager.cpp (100%) rename plugins/{ => labormanager}/labormanager.h (100%) rename plugins/{ => labormanager}/labormanager_joblabormapper.cpp (100%) rename plugins/{ => labormanager}/labormanager_joblabormapper.h (100%) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index b09651678..6981acb89 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -128,7 +128,7 @@ if (BUILD_SUPPORTED) DFHACK_PLUGIN(infiniteSky infiniteSky.cpp) DFHACK_PLUGIN(isoworldremote isoworldremote.cpp PROTOBUFS isoworldremote) DFHACK_PLUGIN(jobutils jobutils.cpp) - DFHACK_PLUGIN(labormanager labormanager.cpp labormanager.h labormanager_joblabormapper.cpp labormanager_joblabormapper.h) + add_subdirectory(labormanager) DFHACK_PLUGIN(lair lair.cpp) DFHACK_PLUGIN(liquids liquids.cpp Brushes.h LINK_LIBRARIES lua) DFHACK_PLUGIN(luasocket luasocket.cpp LINK_LIBRARIES clsocket lua dfhack-tinythread) diff --git a/plugins/labormanager/CMakeLists.txt b/plugins/labormanager/CMakeLists.txt new file mode 100644 index 000000000..e5abb8c39 --- /dev/null +++ b/plugins/labormanager/CMakeLists.txt @@ -0,0 +1,34 @@ +PROJECT (labormanager) +# A list of source files +SET(PROJECT_SRCS + labormanager.cpp + labormanager_joblabormapper.cpp +) +# A list of headers +SET(PROJECT_HDRS + labormanager.h + labormanager_joblabormapper.h +) +SET_SOURCE_FILES_PROPERTIES( ${PROJECT_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE) + +# mash them together (headers are marked as headers and nothing will try to compile them) +LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS}) + +#linux +IF(UNIX) + add_definitions(-DLINUX_BUILD) + SET(PROJECT_LIBS + # add any extra linux libs here + ${PROJECT_LIBS} + ) +# windows +ELSE(UNIX) + SET(PROJECT_LIBS + # add any extra linux libs here + ${PROJECT_LIBS} + $(NOINHERIT) + ) +ENDIF(UNIX) +# this makes sure all the stuff is put in proper places and linked to dfhack + +DFHACK_PLUGIN(labormanager ${PROJECT_SRCS} LINK_LIBRARIES ${PROJECT_LIBS}) diff --git a/plugins/labormanager.cpp b/plugins/labormanager/labormanager.cpp similarity index 100% rename from plugins/labormanager.cpp rename to plugins/labormanager/labormanager.cpp diff --git a/plugins/labormanager.h b/plugins/labormanager/labormanager.h similarity index 100% rename from plugins/labormanager.h rename to plugins/labormanager/labormanager.h diff --git a/plugins/labormanager_joblabormapper.cpp b/plugins/labormanager/labormanager_joblabormapper.cpp similarity index 100% rename from plugins/labormanager_joblabormapper.cpp rename to plugins/labormanager/labormanager_joblabormapper.cpp diff --git a/plugins/labormanager_joblabormapper.h b/plugins/labormanager/labormanager_joblabormapper.h similarity index 100% rename from plugins/labormanager_joblabormapper.h rename to plugins/labormanager/labormanager_joblabormapper.h From d810faa4a32b54befb2e1c0f96f8da94ac301c7d Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Fri, 28 Jul 2017 02:43:32 -0500 Subject: [PATCH 12/66] whitespace --- plugins/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 6981acb89..005f9842c 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -128,7 +128,7 @@ if (BUILD_SUPPORTED) DFHACK_PLUGIN(infiniteSky infiniteSky.cpp) DFHACK_PLUGIN(isoworldremote isoworldremote.cpp PROTOBUFS isoworldremote) DFHACK_PLUGIN(jobutils jobutils.cpp) - add_subdirectory(labormanager) + add_subdirectory(labormanager) DFHACK_PLUGIN(lair lair.cpp) DFHACK_PLUGIN(liquids liquids.cpp Brushes.h LINK_LIBRARIES lua) DFHACK_PLUGIN(luasocket luasocket.cpp LINK_LIBRARIES clsocket lua dfhack-tinythread) From c5c80d5dc0a9c258202424df0df17f81addf367a Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Fri, 28 Jul 2017 23:03:23 -0500 Subject: [PATCH 13/66] Rename labormanager_joblabormapper to joblabormapper --- plugins/labormanager/CMakeLists.txt | 4 ++-- ...rmanager_joblabormapper.cpp => joblabormapper.cpp} | 3 ++- ...labormanager_joblabormapper.h => joblabormapper.h} | 11 +++++++++++ plugins/labormanager/labormanager.cpp | 2 +- 4 files changed, 16 insertions(+), 4 deletions(-) rename plugins/labormanager/{labormanager_joblabormapper.cpp => joblabormapper.cpp} (99%) rename plugins/labormanager/{labormanager_joblabormapper.h => joblabormapper.h} (66%) diff --git a/plugins/labormanager/CMakeLists.txt b/plugins/labormanager/CMakeLists.txt index e5abb8c39..8e9e28b81 100644 --- a/plugins/labormanager/CMakeLists.txt +++ b/plugins/labormanager/CMakeLists.txt @@ -2,12 +2,12 @@ PROJECT (labormanager) # A list of source files SET(PROJECT_SRCS labormanager.cpp - labormanager_joblabormapper.cpp + joblabormapper.cpp ) # A list of headers SET(PROJECT_HDRS labormanager.h - labormanager_joblabormapper.h + joblabormapper.h ) SET_SOURCE_FILES_PROPERTIES( ${PROJECT_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE) diff --git a/plugins/labormanager/labormanager_joblabormapper.cpp b/plugins/labormanager/joblabormapper.cpp similarity index 99% rename from plugins/labormanager/labormanager_joblabormapper.cpp rename to plugins/labormanager/joblabormapper.cpp index c3e21c962..051331137 100644 --- a/plugins/labormanager/labormanager_joblabormapper.cpp +++ b/plugins/labormanager/joblabormapper.cpp @@ -60,7 +60,7 @@ using df::global::ui; using df::global::world; #include "labormanager.h" -#include "labormanager_joblabormapper.h" +#include "joblabormapper.h" static df::unit_labor hauling_labor_map[] = { @@ -635,6 +635,7 @@ JobLaborMapper::~JobLaborMapper() } job_to_labor_table[j] = 0; } + } JobLaborMapper::JobLaborMapper() diff --git a/plugins/labormanager/labormanager_joblabormapper.h b/plugins/labormanager/joblabormapper.h similarity index 66% rename from plugins/labormanager/labormanager_joblabormapper.h rename to plugins/labormanager/joblabormapper.h index adde5c340..37d405f54 100644 --- a/plugins/labormanager/labormanager_joblabormapper.h +++ b/plugins/labormanager/joblabormapper.h @@ -1,5 +1,16 @@ #pragma once +#include + +#include + +using namespace DFHack; +using namespace df::enums; + +#include "df/job.h" +#include "df/job_type.h" +#include "df/unit_labor.h" + class jlfunc; diff --git a/plugins/labormanager/labormanager.cpp b/plugins/labormanager/labormanager.cpp index f791fe398..5fb8dc60e 100644 --- a/plugins/labormanager/labormanager.cpp +++ b/plugins/labormanager/labormanager.cpp @@ -69,7 +69,7 @@ #include #include "labormanager.h" -#include "labormanager_joblabormapper.h" +#include "joblabormapper.h" using namespace std; using std::string; From fe9454ff1c5a6d8de6191ad33a68ca0b33182175 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Sat, 29 Jul 2017 09:26:19 -0500 Subject: [PATCH 14/66] Fix #1103: do not idle for a meeting if the other participant is dead, asleep, resting, or on military duty --- plugins/labormanager/labormanager.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/plugins/labormanager/labormanager.cpp b/plugins/labormanager/labormanager.cpp index 5fb8dc60e..90f7f1e04 100644 --- a/plugins/labormanager/labormanager.cpp +++ b/plugins/labormanager/labormanager.cpp @@ -1212,15 +1212,28 @@ private: { df::activity_info *act = ui->activities[i]; if (!act) continue; + bool p1 = act->unit_actor == dwarf->dwarf; bool p2 = act->unit_noble == dwarf->dwarf; if (p1 || p2) { - dwarf->clear_all = true; - if (print_debug) - out.print("Dwarf \"%s\" has a meeting, will be cleared of all labors\n", dwarf->dwarf->name.first_name.c_str()); - break; + df::unit* other = p1 ? act->unit_noble : act->unit_actor; + if (other && !(other->flags1.bits.dead || + other->job.current_job->job_type == df::job_type::Sleep || + other->job.current_job->job_type == df::job_type::Rest || + ENUM_ATTR(profession, military, other->profession))) + { + dwarf->clear_all = true; + if (print_debug) + out.print("Dwarf \"%s\" has a meeting, will be cleared of all labors\n", dwarf->dwarf->name.first_name.c_str()); + break; + } + else + { + if (print_debug) + out.print("Dwarf \"%s\" has a meeting, but with someone who can't make the meeting.\n", dwarf->dwarf->name.first_name.c_str()); + } } } From 682d4b3144435fcb50f95cd5cde922da53dac920 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Sat, 29 Jul 2017 12:26:32 -0500 Subject: [PATCH 15/66] whitespace --- plugins/labormanager/labormanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/labormanager/labormanager.cpp b/plugins/labormanager/labormanager.cpp index 90f7f1e04..a81021286 100644 --- a/plugins/labormanager/labormanager.cpp +++ b/plugins/labormanager/labormanager.cpp @@ -1228,7 +1228,7 @@ private: if (print_debug) out.print("Dwarf \"%s\" has a meeting, will be cleared of all labors\n", dwarf->dwarf->name.first_name.c_str()); break; - } + } else { if (print_debug) From d98fd020485c2b8c2dc2201241dfabc8742e5ca1 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Sat, 29 Jul 2017 18:46:45 -0500 Subject: [PATCH 16/66] Weight CUTWOOD jobs by KILL_PLANT ethic; fix #1115 --- plugins/labormanager/labormanager.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/plugins/labormanager/labormanager.cpp b/plugins/labormanager/labormanager.cpp index 5fb8dc60e..c1d163cfb 100644 --- a/plugins/labormanager/labormanager.cpp +++ b/plugins/labormanager/labormanager.cpp @@ -67,6 +67,8 @@ #include #include #include +#include +#include #include "labormanager.h" #include "joblabormapper.h" @@ -1465,6 +1467,7 @@ private: for (int ma = 0; ma < 13; ma++) attr_weight += (skill_attr_weights[skill].mental_attr_weights[ma]) * (d->dwarf->status.current_soul->mental_attrs[ma].value - 1000); } + } int score = skill_level * 1000 - (d->high_skill - skill_level) * 2000 + (xp / (skill_level + 5) * 10) + attr_weight; @@ -1485,6 +1488,17 @@ private: score += 5000; } + // This should reweight assigning CUTWOOD jobs based on a citizen's ethic toward killing plants + + if (labor == df::unit_labor::CUTWOOD) + { + auto c_id = d->dwarf->cultural_identity; + auto culture = world->cultural_identities.all[c_id]; + auto ethics = culture->ethic[df::ethic_type::KILL_PLANT]; + if (ethics != df::ethic_response::NOT_APPLICABLE && ethics != df::ethic_response::REQUIRED) + score += 10000 * (df::ethic_response::ACCEPTABLE - ethics); + } + score -= Units::computeMovementSpeed(d->dwarf); return score; From 04733827a011c2e6a56bd28c8d6e9cabe5aac9e4 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Sat, 29 Jul 2017 19:54:51 -0500 Subject: [PATCH 17/66] Favor/disfavor RECOVER_WOUNDED based on ALTRUISM (fixes #1106) --- plugins/labormanager/labormanager.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/plugins/labormanager/labormanager.cpp b/plugins/labormanager/labormanager.cpp index 5fb8dc60e..a2c8a6fd7 100644 --- a/plugins/labormanager/labormanager.cpp +++ b/plugins/labormanager/labormanager.cpp @@ -67,6 +67,7 @@ #include #include #include +#include #include "labormanager.h" #include "joblabormapper.h" @@ -1485,6 +1486,17 @@ private: score += 5000; } + // Favor/disfavor RECOVER_WOUNDED based on ALTRUISM personality facet + + if (labor == df::unit_labor::RECOVER_WOUNDED) + { + int altruism = d->dwarf->status.current_soul->personality.traits[df::personality_facet_type::ALTRUISM]; + if (altruism >= 61) + score += 5000; + else if (altruism <= 24) + score -= 50000; + } + score -= Units::computeMovementSpeed(d->dwarf); return score; From b61859a55ed757af01139b427ca712cc9b8729b7 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Fri, 4 Aug 2017 11:29:48 -0500 Subject: [PATCH 18/66] labormanager/#1103: fix NPE in meeting test --- plugins/labormanager/labormanager.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/labormanager/labormanager.cpp b/plugins/labormanager/labormanager.cpp index a81021286..e7b0cd5e8 100644 --- a/plugins/labormanager/labormanager.cpp +++ b/plugins/labormanager/labormanager.cpp @@ -1220,10 +1220,10 @@ private: { df::unit* other = p1 ? act->unit_noble : act->unit_actor; if (other && !(other->flags1.bits.dead || - other->job.current_job->job_type == df::job_type::Sleep || - other->job.current_job->job_type == df::job_type::Rest || - ENUM_ATTR(profession, military, other->profession))) - { + (other->job.current_job && + (other->job.current_job->job_type == df::job_type::Sleep || + other->job.current_job->job_type == df::job_type::Rest)) || + ENUM_ATTR(profession, military, other->profession))) { dwarf->clear_all = true; if (print_debug) out.print("Dwarf \"%s\" has a meeting, will be cleared of all labors\n", dwarf->dwarf->name.first_name.c_str()); From d280863bc8bd07616e675232f4f16257aa31f2f8 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 5 Aug 2017 21:34:16 -0400 Subject: [PATCH 19/66] Avoid iterating over "has-bad-pointers" fields of IDTYPE_STRUCT and others dfhack/df-structures@4c224dd20567a9eda652ca9522bd0547be4bf358 --- library/LuaTypes.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index 5b5a174fa..6e3c5d5cf 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -1190,9 +1190,8 @@ static void IndexFields(lua_State *state, int base, struct_identity *pstruct, bo continue; case struct_field_info::POINTER: - // Skip class-typed pointers within unions - if ((fields[i].count & 2) != 0 && fields[i].type && - fields[i].type->type() == IDTYPE_CLASS) + // Skip class-typed pointers within unions and other bad pointers + if ((fields[i].count & 2) != 0 && fields[i].type) add_to_enum = false; break; From 16fb230ef61bc921add103e4c47552f6832a7e03 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 5 Aug 2017 21:38:18 -0400 Subject: [PATCH 20/66] getAnyItem: support viewscreen_textviewerst --- library/modules/Gui.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/modules/Gui.cpp b/library/modules/Gui.cpp index 5b56ee1ed..7de9a5e11 100644 --- a/library/modules/Gui.cpp +++ b/library/modules/Gui.cpp @@ -990,6 +990,18 @@ df::item *Gui::getAnyItem(df::viewscreen *top) using df::global::ui_building_item_cursor; using df::global::ui_sidebar_menus; + if (VIRTUAL_CAST_VAR(screen, df::viewscreen_textviewerst, top)) + { + // return the main item if the parent screen is a viewscreen_itemst + if (VIRTUAL_CAST_VAR(parent_screen, df::viewscreen_itemst, screen->parent)) + return parent_screen->item; + + if (screen->parent) + return getAnyItem(screen->parent); + + return NULL; + } + if (VIRTUAL_CAST_VAR(screen, df::viewscreen_itemst, top)) { df::general_ref *ref = vector_get(screen->entry_ref, screen->cursor_pos); From ab8fb9f44e1c2ce896dacaa967fa453258e2733b Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Sat, 5 Aug 2017 21:48:41 -0500 Subject: [PATCH 21/66] whitespace --- plugins/labormanager/labormanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/labormanager/labormanager.cpp b/plugins/labormanager/labormanager.cpp index e7b0cd5e8..cefdc90f9 100644 --- a/plugins/labormanager/labormanager.cpp +++ b/plugins/labormanager/labormanager.cpp @@ -1220,8 +1220,8 @@ private: { df::unit* other = p1 ? act->unit_noble : act->unit_actor; if (other && !(other->flags1.bits.dead || - (other->job.current_job && - (other->job.current_job->job_type == df::job_type::Sleep || + (other->job.current_job && + (other->job.current_job->job_type == df::job_type::Sleep || other->job.current_job->job_type == df::job_type::Rest)) || ENUM_ATTR(profession, military, other->profession))) { dwarf->clear_all = true; From a383cc9a300e45aa9c79c6a7b46fcb0f188b92e3 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sun, 6 Aug 2017 21:01:36 -0400 Subject: [PATCH 22/66] Fix diggingInvaders compilation errors (#1145, GCC 4.8) --- plugins/CMakeLists.txt | 2 +- plugins/diggingInvaders/assignJob.cpp | 4 ++++ plugins/diggingInvaders/assignJob.h | 3 ++- plugins/diggingInvaders/edgeCost.cpp | 2 ++ plugins/diggingInvaders/edgeCost.h | 4 ++-- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index d94dc52c6..9c3716314 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -108,7 +108,7 @@ if (BUILD_SUPPORTED) DFHACK_PLUGIN(deramp deramp.cpp) DFHACK_PLUGIN(dig dig.cpp) DFHACK_PLUGIN(digFlood digFlood.cpp) - # add_subdirectory(diggingInvaders) + add_subdirectory(diggingInvaders) DFHACK_PLUGIN(dwarfvet dwarfvet.cpp) DFHACK_PLUGIN(dwarfmonitor dwarfmonitor.cpp LINK_LIBRARIES lua) DFHACK_PLUGIN(embark-tools embark-tools.cpp) diff --git a/plugins/diggingInvaders/assignJob.cpp b/plugins/diggingInvaders/assignJob.cpp index 6e3874cbf..cdd3e6fc5 100644 --- a/plugins/diggingInvaders/assignJob.cpp +++ b/plugins/diggingInvaders/assignJob.cpp @@ -20,6 +20,7 @@ #include "df/item_type.h" #include "df/item_weaponst.h" #include "df/job.h" +#include "df/job_list_link.h" #include "df/job_skill.h" #include "df/job_type.h" #include "df/reaction_product_itemst.h" @@ -27,8 +28,11 @@ #include "df/ui.h" #include "df/unit.h" #include "df/unit_inventory_item.h" +#include "df/world.h" #include "df/world_site.h" +using namespace DFHack; + void getRidOfOldJob(df::unit* unit) { if ( unit->job.current_job == NULL ) { return; diff --git a/plugins/diggingInvaders/assignJob.h b/plugins/diggingInvaders/assignJob.h index 0ad6419d6..1e5750c03 100644 --- a/plugins/diggingInvaders/assignJob.h +++ b/plugins/diggingInvaders/assignJob.h @@ -2,6 +2,7 @@ #include "edgeCost.h" +#include "ColorText.h" #include "modules/MapCache.h" #include @@ -9,5 +10,5 @@ using namespace std; -int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map parentMap, unordered_map& costMap, vector& invaders, unordered_set& requiresZNeg, unordered_set& requiresZPos, MapExtras::MapCache& cache, DigAbilities& abilities); +int32_t assignJob(DFHack::color_ostream& out, Edge firstImportantEdge, unordered_map parentMap, unordered_map& costMap, vector& invaders, unordered_set& requiresZNeg, unordered_set& requiresZPos, MapExtras::MapCache& cache, DigAbilities& abilities); diff --git a/plugins/diggingInvaders/edgeCost.cpp b/plugins/diggingInvaders/edgeCost.cpp index c9e83fa14..b08227d94 100644 --- a/plugins/diggingInvaders/edgeCost.cpp +++ b/plugins/diggingInvaders/edgeCost.cpp @@ -19,6 +19,8 @@ #include +using namespace DFHack; + /* cost_t costWeight[] = { //Distance diff --git a/plugins/diggingInvaders/edgeCost.h b/plugins/diggingInvaders/edgeCost.h index 560fec109..ef4cb3168 100644 --- a/plugins/diggingInvaders/edgeCost.h +++ b/plugins/diggingInvaders/edgeCost.h @@ -93,6 +93,6 @@ struct PointHash { } }; -cost_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2, DigAbilities& abilities); -std::vector* getEdgeSet(color_ostream &out, df::coord point, MapExtras::MapCache& cache, int32_t xMax, int32_t yMax, int32_t zMax, DigAbilities& abilities); +cost_t getEdgeCost(DFHack::color_ostream& out, df::coord pt1, df::coord pt2, DigAbilities& abilities); +std::vector* getEdgeSet(DFHack::color_ostream &out, df::coord point, MapExtras::MapCache& cache, int32_t xMax, int32_t yMax, int32_t zMax, DigAbilities& abilities); From 05b238c879cafcc559978ac922b43d685270ce29 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 7 Aug 2017 09:29:46 -0400 Subject: [PATCH 23/66] Fix another diggingInvaders compiler error Windows-specific, for some strange reason Ref #1145 --- plugins/diggingInvaders/diggingInvaders.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/diggingInvaders/diggingInvaders.cpp b/plugins/diggingInvaders/diggingInvaders.cpp index 8be58fd32..4892c5e1d 100644 --- a/plugins/diggingInvaders/diggingInvaders.cpp +++ b/plugins/diggingInvaders/diggingInvaders.cpp @@ -199,7 +199,7 @@ public: } - int32_t operator()(df::coord p1, df::coord p2) { + int32_t operator()(df::coord p1, df::coord p2) const { if ( p1 == p2 ) return 0; auto i1 = pointCost->find(p1); auto i2 = pointCost->find(p2); From 95aa5bbb4742f2714bd9556b5cc99ae9ca5bebe3 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 7 Aug 2017 15:06:00 -0400 Subject: [PATCH 24/66] zoom: fix MSVC warning --- plugins/devel/zoom.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/devel/zoom.cpp b/plugins/devel/zoom.cpp index 3ee0566e8..d302d4900 100644 --- a/plugins/devel/zoom.cpp +++ b/plugins/devel/zoom.cpp @@ -77,5 +77,6 @@ command_result df_gzoom (color_ostream &out, std::vector & paramete Gui::setCursorCoords(x,y,z); } Gui::setViewCoords(x,y,z); + return CR_OK; } From 0b26e9aec705d7800b8259c8f3b82207fca7bcb6 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Mon, 7 Aug 2017 14:13:22 -0500 Subject: [PATCH 25/66] Fix a couple of MSVC warnings Use intptr_t instead of long for a handle, and add an explict cast to eliminate a narrowing conversion warning --- library/Console-windows.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/Console-windows.cpp b/library/Console-windows.cpp index c11661a30..28d98309b 100644 --- a/library/Console-windows.cpp +++ b/library/Console-windows.cpp @@ -172,7 +172,7 @@ namespace DFHack } void gotoxy(int x, int y) { - COORD coord = {x-1, y-1}; // Windows uses 0-based coordinates + COORD coord = {(SHORT)(x-1), (SHORT)(y-1)}; // Windows uses 0-based coordinates SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); } @@ -434,7 +434,7 @@ bool Console::init(bool) { d = new Private(); int hConHandle; - long lStdHandle; + intptr_t lStdHandle; CONSOLE_SCREEN_BUFFER_INFO coninfo; FILE *fp; DWORD oldMode, newMode; @@ -469,14 +469,14 @@ bool Console::init(bool) // redirect unbuffered STDOUT to the console d->console_out = GetStdHandle(STD_OUTPUT_HANDLE); - lStdHandle = (long)d->console_out; + lStdHandle = (intptr_t)d->console_out; hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); d->dfout_C = _fdopen( hConHandle, "w" ); setvbuf( d->dfout_C, NULL, _IONBF, 0 ); // redirect unbuffered STDIN to the console d->console_in = GetStdHandle(STD_INPUT_HANDLE); - lStdHandle = (long)d->console_in; + lStdHandle = (intptr_t)d->console_in; hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); fp = _fdopen( hConHandle, "r" ); *stdin = *fp; From 08656a3ca7d433c43e052920836e650880c18b90 Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 8 Aug 2017 20:08:07 -0400 Subject: [PATCH 26/66] Strip DF folder from Ruby script paths Fixes #1146 (temporarily, see #1147) --- library/Core.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/library/Core.cpp b/library/Core.cpp index fccf7f464..62d605fe6 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -388,6 +388,15 @@ static command_result runRubyScript(color_ostream &out, PluginManager *plug_mgr, if (!plug_mgr->ruby || !plug_mgr->ruby->is_enabled()) return CR_FAILURE; + // ugly temporary patch for https://github.com/DFHack/dfhack/issues/1146 + string cwd = Filesystem::getcwd(); + if (filename.find(cwd) == 0) + { + filename = filename.substr(cwd.size()); + while (!filename.empty() && (filename[0] == '/' || filename[0] == '\\')) + filename = filename.substr(1); + } + std::string rbcmd = "$script_args = ["; for (size_t i = 0; i < args.size(); i++) rbcmd += "'" + args[i] + "', "; From 55d22855a02da72e8fb20526a61d3a22b972fcc0 Mon Sep 17 00:00:00 2001 From: Japa Date: Fri, 11 Aug 2017 10:21:40 +0530 Subject: [PATCH 27/66] Add styling enums to RFR --- plugins/proto/RemoteFortressReader.proto | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/proto/RemoteFortressReader.proto b/plugins/proto/RemoteFortressReader.proto index 8e9fd4a58..d718b86d2 100644 --- a/plugins/proto/RemoteFortressReader.proto +++ b/plugins/proto/RemoteFortressReader.proto @@ -118,6 +118,15 @@ enum TileDigDesignation UP_STAIR_DIG = 6; } +enum HairStyle +{ + NEATLY_COMBED = 0; + BRAIDED = 1; + DOUBLE_BRAID = 2; + PONY_TAILS = 3; + CLEAN_SHAVEN = 4; +} + message Coord { optional int32 x = 1; From 6c5e25db13856d1d077fa874278ca6b60d2d5c43 Mon Sep 17 00:00:00 2001 From: Japa Date: Fri, 11 Aug 2017 13:50:30 +0530 Subject: [PATCH 28/66] Add hair style to units in proto --- plugins/proto/RemoteFortressReader.proto | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/plugins/proto/RemoteFortressReader.proto b/plugins/proto/RemoteFortressReader.proto index d718b86d2..b416b96ec 100644 --- a/plugins/proto/RemoteFortressReader.proto +++ b/plugins/proto/RemoteFortressReader.proto @@ -307,6 +307,12 @@ message MaterialList{ repeated MaterialDefinition material_list = 1; } +message Hair +{ + optional int32 length = 1; + optional HairStyle style = 2; +} + message BodySizeInfo { optional int32 size_cur = 1; @@ -323,6 +329,10 @@ message UnitAppearance repeated int32 bp_modifiers = 2; optional int32 size_modifier = 3; repeated int32 colors = 4; + optional Hair hair = 5; + optional Hair beard = 6; + optional Hair moustache = 7; + optional Hair sideburns = 8; } message UnitDefinition From 620cfcc8bd3bcfac46f8b717da1326ca47223fe6 Mon Sep 17 00:00:00 2001 From: Warmist Date: Sat, 12 Aug 2017 15:42:56 +0300 Subject: [PATCH 29/66] Fix luasocket receive with byte count Did not correctly detect when you typed in a number instead of pattern. --- plugins/lua/luasocket.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/lua/luasocket.lua b/plugins/lua/luasocket.lua index 1debb4dd9..bf1e919d4 100644 --- a/plugins/lua/luasocket.lua +++ b/plugins/lua/luasocket.lua @@ -47,7 +47,7 @@ function client:receive( pattern ) local pattern=pattern or "*l" local bytes=-1 - if type(pattern)== number then + if type(pattern)== 'number' then bytes=pattern end From b7783ba8b9c453d268c2b3d75b6232d512b24fde Mon Sep 17 00:00:00 2001 From: Japa Date: Sat, 12 Aug 2017 19:10:35 +0530 Subject: [PATCH 30/66] Added unkept hair to style list --- plugins/proto/RemoteFortressReader.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/proto/RemoteFortressReader.proto b/plugins/proto/RemoteFortressReader.proto index b416b96ec..963bf3bf8 100644 --- a/plugins/proto/RemoteFortressReader.proto +++ b/plugins/proto/RemoteFortressReader.proto @@ -120,6 +120,7 @@ enum TileDigDesignation enum HairStyle { + UNKEPT = -1; NEATLY_COMBED = 0; BRAIDED = 1; DOUBLE_BRAID = 2; From 5b5ac7088dbd1fd8504033d34653d367b7dd44ba Mon Sep 17 00:00:00 2001 From: Japa Date: Sat, 12 Aug 2017 19:12:14 +0530 Subject: [PATCH 31/66] correct spelling --- plugins/proto/RemoteFortressReader.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/proto/RemoteFortressReader.proto b/plugins/proto/RemoteFortressReader.proto index 963bf3bf8..bcbf46d71 100644 --- a/plugins/proto/RemoteFortressReader.proto +++ b/plugins/proto/RemoteFortressReader.proto @@ -120,7 +120,7 @@ enum TileDigDesignation enum HairStyle { - UNKEPT = -1; + UNKEMPT = -1; NEATLY_COMBED = 0; BRAIDED = 1; DOUBLE_BRAID = 2; From 737aefefea9d954f45ccc4c241ccdd56cac692bb Mon Sep 17 00:00:00 2001 From: Japa Date: Sat, 19 Aug 2017 09:38:56 +0530 Subject: [PATCH 32/66] send over beard styles --- .../remotefortressreader.cpp | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/plugins/remotefortressreader/remotefortressreader.cpp b/plugins/remotefortressreader/remotefortressreader.cpp index 7fe879645..e1f961577 100644 --- a/plugins/remotefortressreader/remotefortressreader.cpp +++ b/plugins/remotefortressreader/remotefortressreader.cpp @@ -83,6 +83,7 @@ #include "df/site_realization_building_info_trenchesst.h" #endif #include "df/tissue.h" +#include "df/tissue_style_raw.h" #include "df/ui.h" #include "df/unit.h" #include "df/viewscreen_choose_start_sitest.h" @@ -1578,6 +1579,42 @@ static command_result GetUnitList(color_ostream &stream, const EmptyMessage *in, } send_unit->set_rider_id(unit->relationship_ids[df::unit_relationship_type::RiderMount]); + + auto creatureRaw = world->raws.creatures.all[unit->race]; + auto casteRaw = creatureRaw->caste[unit->caste]; + + for (int j = 0; j < unit->appearance.tissue_style_type.size(); j++) + { + auto type = unit->appearance.tissue_style_type[j]; + if (type < 0) + continue; + int style_raw_index = binsearch_index(casteRaw->tissue_styles, &df::tissue_style_raw::id, type); + auto styleRaw = casteRaw->tissue_styles[style_raw_index]; + if (styleRaw->token == "HAIR") + { + auto send_style = appearance->mutable_hair(); + send_style->set_length(unit->appearance.tissue_length[j]); + send_style->set_style((HairStyle)unit->appearance.tissue_style[j]); + } + else if (styleRaw->token == "BEARD") + { + auto send_style = appearance->mutable_beard(); + send_style->set_length(unit->appearance.tissue_length[j]); + send_style->set_style((HairStyle)unit->appearance.tissue_style[j]); + } + else if (styleRaw->token == "MOUSTACHE") + { + auto send_style = appearance->mutable_moustache(); + send_style->set_length(unit->appearance.tissue_length[j]); + send_style->set_style((HairStyle)unit->appearance.tissue_style[j]); + } + else if (styleRaw->token == "SIDEBURNS") + { + auto send_style = appearance->mutable_sideburns(); + send_style->set_length(unit->appearance.tissue_length[j]); + send_style->set_style((HairStyle)unit->appearance.tissue_style[j]); + } + } } return CR_OK; } From 8e71cf9def0496f9977e8794b50d6c9983143637 Mon Sep 17 00:00:00 2001 From: Japa Date: Sat, 19 Aug 2017 17:48:18 +0530 Subject: [PATCH 33/66] Send Unit inventories with RFR --- plugins/proto/RemoteFortressReader.proto | 40 +++++++++++++++++++ .../remotefortressreader.cpp | 9 +++++ 2 files changed, 49 insertions(+) diff --git a/plugins/proto/RemoteFortressReader.proto b/plugins/proto/RemoteFortressReader.proto index bcbf46d71..88fd03c64 100644 --- a/plugins/proto/RemoteFortressReader.proto +++ b/plugins/proto/RemoteFortressReader.proto @@ -128,6 +128,39 @@ enum HairStyle CLEAN_SHAVEN = 4; } +enum InventoryMode +{ + Hauled = 0; + /** + * also shield, crutch + */ + Weapon = 1; + /** + * quiver + */ + Worn = 2; + Piercing = 3; + /** + * attached to clothing + */ + Flask = 4; + /** + * e.g. bandage + */ + WrappedAround = 5; + StuckIn = 6; + /** + * string descr like Worn + */ + InMouth = 7; + /** + * Left shoulder, right shoulder, or head, selected randomly using pet_seed + */ + Pet = 8; + SewnInto = 9; + Strapped = 10; +} + message Coord { optional int32 x = 1; @@ -336,6 +369,12 @@ message UnitAppearance optional Hair sideburns = 8; } +message InventoryItem +{ + optional InventoryMode mode = 1; + optional Item item = 2; +} + message UnitDefinition { required int32 id = 1; @@ -357,6 +396,7 @@ message UnitDefinition optional int32 profession_id = 17; repeated string noble_positions = 18; optional int32 rider_id = 19; + repeated InventoryItem inventory = 20; } message UnitList diff --git a/plugins/remotefortressreader/remotefortressreader.cpp b/plugins/remotefortressreader/remotefortressreader.cpp index e1f961577..035ab4322 100644 --- a/plugins/remotefortressreader/remotefortressreader.cpp +++ b/plugins/remotefortressreader/remotefortressreader.cpp @@ -86,6 +86,7 @@ #include "df/tissue_style_raw.h" #include "df/ui.h" #include "df/unit.h" +#include "df/unit_inventory_item.h" #include "df/viewscreen_choose_start_sitest.h" #include "df/world.h" #include "df/world_data.h" @@ -1615,6 +1616,14 @@ static command_result GetUnitList(color_ostream &stream, const EmptyMessage *in, send_style->set_style((HairStyle)unit->appearance.tissue_style[j]); } } + + for (int j = 0; j < unit->inventory.size(); j++) + { + auto inventory_item = unit->inventory[j]; + auto sent_item = send_unit->add_inventory(); + sent_item->set_mode((InventoryMode)inventory_item->mode); + CopyItem(sent_item->mutable_item(), inventory_item->item); + } } return CR_OK; } From a7b837f2d056ebae6fde4f97b6bc107508969ceb Mon Sep 17 00:00:00 2001 From: Japa Date: Sun, 20 Aug 2017 20:44:55 +0530 Subject: [PATCH 34/66] Increment version number --- plugins/remotefortressreader/remotefortressreader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/remotefortressreader/remotefortressreader.cpp b/plugins/remotefortressreader/remotefortressreader.cpp index 035ab4322..a07668778 100644 --- a/plugins/remotefortressreader/remotefortressreader.cpp +++ b/plugins/remotefortressreader/remotefortressreader.cpp @@ -1,5 +1,5 @@ #include "df_version_int.h" -#define RFR_VERSION "0.17.1" +#define RFR_VERSION "0.18.0" #include #include From 4f38260e8c236e0cc59bb846b14aa581373feaf1 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 21 Aug 2017 19:34:46 -0400 Subject: [PATCH 35/66] Pass the correct architecture to setarch on Linux Fixes #1129 --- CMakeLists.txt | 5 +++++ package/linux/dfhack | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e78340d5..79889dcb0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,9 +81,11 @@ ENDIF() IF("${DFHACK_BUILD_ARCH}" STREQUAL "32") SET(DFHACK_BUILD_32 1) SET(DFHACK_BUILD_64 0) + set(DFHACK_SETARCH "i386") ELSEIF("${DFHACK_BUILD_ARCH}" STREQUAL "64") SET(DFHACK_BUILD_32 0) SET(DFHACK_BUILD_64 1) + set(DFHACK_SETARCH "x86_64") ADD_DEFINITIONS(-DDFHACK64) ELSE() MESSAGE(SEND_ERROR "Invalid build architecture (should be 32/64): ${DFHACK_BUILD_ARCH}") @@ -334,6 +336,9 @@ IF(BUILD_LIBRARY) install(FILES LICENSE.rst NEWS.rst DESTINATION ${DFHACK_USERDOC_DESTINATION}) endif() +file(WRITE "${CMAKE_BINARY_DIR}/dfhack_setarch.txt" ${DFHACK_SETARCH}) +install(FILES "${CMAKE_BINARY_DIR}/dfhack_setarch.txt" DESTINATION "${DFHACK_DATA_DESTINATION}") + install(DIRECTORY dfhack-config/ DESTINATION dfhack-config/default) #build the plugins diff --git a/package/linux/dfhack b/package/linux/dfhack index 7c01fcbd7..011df22eb 100755 --- a/package/linux/dfhack +++ b/package/linux/dfhack @@ -63,6 +63,8 @@ export LD_LIBRARY_PATH="./hack/libs:./hack:$LD_LIBRARY_PATH" PRELOAD_LIB="${PRELOAD_LIB:+$PRELOAD_LIB:}./hack/libdfhack.so" +setarch_arch=$(cat hack/dfhack_setarch.txt || printf i386) + case "$1" in -g | --gdb) shift @@ -74,21 +76,21 @@ case "$1" in ;; -h | --helgrind) shift - LD_PRELOAD="$PRELOAD_LIB" setarch i386 -R valgrind $DF_HELGRIND_OPTS --tool=helgrind --log-file=helgrind.log ./libs/Dwarf_Fortress "$@" + LD_PRELOAD="$PRELOAD_LIB" setarch "$setarch_arch" -R valgrind $DF_HELGRIND_OPTS --tool=helgrind --log-file=helgrind.log ./libs/Dwarf_Fortress "$@" ret=$? ;; -v | --valgrind) shift - LD_PRELOAD="$PRELOAD_LIB" setarch i386 -R valgrind $DF_VALGRIND_OPTS --log-file=valgrind.log ./libs/Dwarf_Fortress "$@" + LD_PRELOAD="$PRELOAD_LIB" setarch "$setarch_arch" -R valgrind $DF_VALGRIND_OPTS --log-file=valgrind.log ./libs/Dwarf_Fortress "$@" ret=$? ;; -c | --callgrind) shift - LD_PRELOAD="$PRELOAD_LIB" setarch i386 -R valgrind $DF_CALLGRIND_OPTS --tool=callgrind --separate-threads=yes --dump-instr=yes --instr-atstart=no --log-file=callgrind.log ./libs/Dwarf_Fortress "$@" + LD_PRELOAD="$PRELOAD_LIB" setarch "$setarch_arch" -R valgrind $DF_CALLGRIND_OPTS --tool=callgrind --separate-threads=yes --dump-instr=yes --instr-atstart=no --log-file=callgrind.log ./libs/Dwarf_Fortress "$@" ret=$? ;; *) - setarch i386 -R env LD_PRELOAD="$PRELOAD_LIB" ./libs/Dwarf_Fortress "$@" + setarch "$setarch_arch" -R env LD_PRELOAD="$PRELOAD_LIB" ./libs/Dwarf_Fortress "$@" ret=$? ;; esac From ca481fc69f177686a01fe3c89f59532c7ba2ac66 Mon Sep 17 00:00:00 2001 From: ViTuRaS Date: Mon, 28 Aug 2017 22:33:24 +0200 Subject: [PATCH 36/66] max_barrels was serialized on max_bins position When I save and load stockpile settings with stockpile management plugin, then saved barrels count will be loaded in bins and barrels are zero. So I think this change should correct it. --- plugins/stockpiles/StockpileSerializer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/stockpiles/StockpileSerializer.cpp b/plugins/stockpiles/StockpileSerializer.cpp index fa3d648ba..e9a8143a5 100644 --- a/plugins/stockpiles/StockpileSerializer.cpp +++ b/plugins/stockpiles/StockpileSerializer.cpp @@ -465,8 +465,9 @@ int StockpileSerializer::other_mats_token ( const std::map oth void StockpileSerializer::write_general() { - mBuffer.set_max_bins ( mPile->max_barrels ); + mBuffer.set_max_bins ( mPile->max_bins ); mBuffer.set_max_wheelbarrows ( mPile->max_wheelbarrows ); + mBuffer.set_max_barrels ( mPile->max_barrels ); mBuffer.set_use_links_only ( mPile->use_links_only ); mBuffer.set_unknown1 ( mPile->settings.unk1 ); mBuffer.set_allow_inorganic ( mPile->settings.allow_inorganic ); From d3f3ebf77868d344c09b911137c8e26e4c92c2b3 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Wed, 4 Oct 2017 14:37:04 -0500 Subject: [PATCH 37/66] auto_ptr is deprecated - use unique_ptr instead --- library/RemoteServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/RemoteServer.cpp b/library/RemoteServer.cpp index df65e8e5a..bc30daff3 100644 --- a/library/RemoteServer.cpp +++ b/library/RemoteServer.cpp @@ -261,7 +261,7 @@ void ServerConnection::threadFn() break; } - std::auto_ptr buf(new uint8_t[header.size]); + std::unique_ptr buf(new uint8_t[header.size]); if (!readFullBuffer(socket, buf.get(), header.size)) { From c080da3750d923bd546f94c40c0a1b9ee88f28cc Mon Sep 17 00:00:00 2001 From: Quietust Date: Sun, 8 Oct 2017 19:54:51 -0600 Subject: [PATCH 38/66] listcolumn - adjust add(ListEntry) to take const ref, more compatible on Linux --- plugins/listcolumn.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/listcolumn.h b/plugins/listcolumn.h index 9914c8ea7..4e4815b69 100644 --- a/plugins/listcolumn.h +++ b/plugins/listcolumn.h @@ -70,7 +70,7 @@ public: display_max_rows = gps->dimy - 4 - bottom_margin; } - void add(ListEntry &entry) + void add(const ListEntry &entry) { list.push_back(entry); if (entry.text.length() > max_item_width) From cc595d7a4ed3d72f654e4474fd62563f9930983e Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Mon, 16 Oct 2017 14:01:23 -0500 Subject: [PATCH 39/66] Fix fencepost error in orders import. Fixes #1177. --- plugins/orders.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/plugins/orders.cpp b/plugins/orders.cpp index 53c1844ac..4a2e3b0c0 100644 --- a/plugins/orders.cpp +++ b/plugins/orders.cpp @@ -146,15 +146,22 @@ static void json_array_to_bitfield(B & bits, Json::Value & arr) return; } - for (Json::ArrayIndex i = arr.size() - 1; i != 0; i--) + for (Json::ArrayIndex i = arr.size(); i != 0; i--) { + if (!arr[i - 1].isString()) + { + continue; + } + + std::string str(arr[i - 1].asString()); + int current; - if (get_bitfield_field(¤t, bits, arr[i].asString())) + if (get_bitfield_field(¤t, bits, str)) { - if (!current && set_bitfield_field(&bits, arr[i].asString(), 1)) + if (!current && set_bitfield_field(&bits, str, 1)) { Json::Value removed; - arr.removeIndex(i, &removed); + arr.removeIndex(i - 1, &removed); } } } From 33a43c5bfd0bebd902b4194ed077e9666df49f32 Mon Sep 17 00:00:00 2001 From: Quietust Date: Sat, 4 Nov 2017 07:50:47 -0600 Subject: [PATCH 40/66] update structures --- library/modules/Maps.cpp | 2 +- library/xml | 2 +- plugins/prospector.cpp | 2 +- plugins/reveal.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index af2cd5183..2b2311a7c 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -91,7 +91,7 @@ const char * DFHack::sa_feature(df::feature_type index) return "Cavern"; case feature_type::magma_core_from_layer: return "Magma sea"; - case feature_type::feature_underworld_from_layer: + case feature_type::underworld_from_layer: return "Underworld"; default: return "Unknown/Error"; diff --git a/library/xml b/library/xml index 3322beb2e..888f24622 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 3322beb2e7f4b28ff8e573e9bec738c77026b8e9 +Subproject commit 888f24622990c11db5c392f5e241e0de28d2bb9e diff --git a/plugins/prospector.cpp b/plugins/prospector.cpp index 522630afe..32e360a3a 100644 --- a/plugins/prospector.cpp +++ b/plugins/prospector.cpp @@ -721,7 +721,7 @@ command_result prospector (color_ostream &con, vector & parameters) } if (showSlade && blockFeatureGlobal.type != -1 && des.bits.feature_global - && blockFeatureGlobal.type == feature_type::feature_underworld_from_layer + && blockFeatureGlobal.type == feature_type::underworld_from_layer && blockFeatureGlobal.main_material == 0) // stone { layerMats[blockFeatureGlobal.sub_material].add(global_z); diff --git a/plugins/reveal.cpp b/plugins/reveal.cpp index 314259fd4..c2479bedc 100644 --- a/plugins/reveal.cpp +++ b/plugins/reveal.cpp @@ -44,7 +44,7 @@ bool isSafe(df::coord c) if (local_feature.type == feature_type::deep_special_tube || local_feature.type == feature_type::deep_surface_portal) return false; // And Hell *is* Hell. - if (global_feature.type == feature_type::feature_underworld_from_layer) + if (global_feature.type == feature_type::underworld_from_layer) return false; // otherwise it's safe. return true; From e06644cdf4320732922b2329f5bdadbf39f30922 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Thu, 23 Nov 2017 10:55:37 -0600 Subject: [PATCH 41/66] Fix labormanager crash when a dwarf doesn't have a cultural identity --- plugins/labormanager/labormanager.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/plugins/labormanager/labormanager.cpp b/plugins/labormanager/labormanager.cpp index d7d4ffc6b..1a5323d8a 100644 --- a/plugins/labormanager/labormanager.cpp +++ b/plugins/labormanager/labormanager.cpp @@ -1175,6 +1175,8 @@ private: void collect_dwarf_list() { + state_count.clear(); + state_count.resize(NUM_STATE); for (auto u = world->units.active.begin(); u != world->units.active.end(); ++u) { @@ -1373,6 +1375,8 @@ private: if (print_debug) out.print("Dwarf \"%s\": state %s %d\n", dwarf->dwarf->name.first_name.c_str(), state_names[dwarf->state], dwarf->clear_all); + state_count[dwarf->state]++; + // determine if dwarf has medical needs if (dwarf->dwarf->health && !( // on-duty military will not necessarily break to get minor injuries attended @@ -1516,11 +1520,12 @@ private: if (labor == df::unit_labor::CUTWOOD) { - auto c_id = d->dwarf->cultural_identity; - auto culture = world->cultural_identities.all[c_id]; - auto ethics = culture->ethic[df::ethic_type::KILL_PLANT]; - if (ethics != df::ethic_response::NOT_APPLICABLE && ethics != df::ethic_response::REQUIRED) - score += 10000 * (df::ethic_response::ACCEPTABLE - ethics); + if (auto culture = df::cultural_identity::find(d->dwarf->cultural_identity)) + { + auto ethics = culture->ethic[df::ethic_type::KILL_PLANT]; + if (ethics != df::ethic_response::NOT_APPLICABLE && ethics != df::ethic_response::REQUIRED) + score += 10000 * (df::ethic_response::ACCEPTABLE - ethics); + } } score -= Units::computeMovementSpeed(d->dwarf); From 111df1312bac8ea9bb0a60bd572f82493d6eedac Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 23 Nov 2017 15:50:58 -0500 Subject: [PATCH 42/66] Update xml to 1cdab5a (last for 0.43.05) --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index 888f24622..1cdab5a16 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 888f24622990c11db5c392f5e241e0de28d2bb9e +Subproject commit 1cdab5a16467c73080553e94a651bbc2b48380a6 From 2473476f98717c04191a23582adde6140f0ae57e Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 23 Nov 2017 15:54:34 -0500 Subject: [PATCH 43/66] Update Authors.rst (#1156) --- docs/Authors.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Authors.rst b/docs/Authors.rst index 128d327ba..cb915e036 100644 --- a/docs/Authors.rst +++ b/docs/Authors.rst @@ -124,6 +124,7 @@ Travis Hoppe thoppe orthographic-pedant txtsd txtsd U-glouglou\\simon Valentin Ochs Cat-Ion +ViTuRaS ViTuRaS Vjek Warmist warmist Wes Malone wesQ3 From a3288b4b05e724551b9ae40a1caacb553b4c7a50 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 23 Nov 2017 15:54:45 -0500 Subject: [PATCH 44/66] Update Authors.rst (dfhack/scripts#32) --- docs/Authors.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Authors.rst b/docs/Authors.rst index cb915e036..948d956ba 100644 --- a/docs/Authors.rst +++ b/docs/Authors.rst @@ -26,6 +26,7 @@ Caldfir caldfir Carter Bray Qartar Chris Dombroski cdombroski Clayton Hughes +Clément Vuchener cvuchener David Corbett dscorbett David Seguin dseguin Deon From 5795a370bc7f08ce5c3073fc7038de28c439c29f Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 23 Nov 2017 16:01:27 -0500 Subject: [PATCH 45/66] Update xml again to fix GCC build error --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index 1cdab5a16..860a9041a 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 1cdab5a16467c73080553e94a651bbc2b48380a6 +Subproject commit 860a9041a75305609643d465123a4b598140dd7f From c546e5e52c9a1940ae576c4139d77522b3a387a1 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 23 Nov 2017 16:06:19 -0500 Subject: [PATCH 46/66] Update Authors.rst (dfhack/scripts#31) --- docs/Authors.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Authors.rst b/docs/Authors.rst index 948d956ba..a693646bf 100644 --- a/docs/Authors.rst +++ b/docs/Authors.rst @@ -79,6 +79,7 @@ Nick Rart nickrart comestible Nikolay Amiantov abbradar nocico nocico Omniclasm +OwnageIsMagic OwnageIsMagic Patrik Lundell PatrikLundell Paul Fenwick pjf PeridexisErrant PeridexisErrant From 1b706bc1626c27475f728890bff524d07d4f1d36 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 23 Nov 2017 16:34:22 -0500 Subject: [PATCH 47/66] Add anchor for luasocket --- docs/Lua API.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index d9bbfed55..66c2a5a07 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -3621,6 +3621,8 @@ Or with auto_gears:: auto_gears=true } +.. _luasocket: + Luasocket ========= From fb940b8836601f6a9a38807e04e3dc79496f9173 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 23 Nov 2017 16:34:28 -0500 Subject: [PATCH 48/66] Update NEWS.rst --- NEWS.rst | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index 9d8b05a78..e55ca92c5 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -36,6 +36,47 @@ Changelog .. contents:: :depth: 2 +DFHack 0.43.05-r3 +================= + +Internals +--------- +- Fixed an uncommon crash that could occur when printing text to the console +- Added lots of previously-missing DF classes +- More names for fields: https://github.com/DFHack/df-structures/compare/0.43.05-r2...0.43.05 + +Fixes +----- +- Linux: fixed argument to ``setarch`` in the ``dfhack`` launcher script +- Ruby: fixed an error that occurred when the DF path contained an apostrophe +- `diggingInvaders` now compiles again and is included +- `labormanager`: + + - stopped waiting for on-duty military dwarves with minor injuries to obtain care + - stopped waiting for meetings when participant(s) are dead + - fixed a crash for dwarves with no cultural identity + +- `luasocket`: fixed ``receive()`` with a byte count +- `orders`: fixed an error when importing orders with material categories +- `siren`: fixed an error +- `stockpiles`: fixed serialization of barrel and bin counts +- `view-item-info`: fixed a ``CHEESE_MAT``-related error + +Misc Improvements +----------------- +- `devel/export-dt-ini`: added more offsets for new DT versions +- `digfort`: added support for changing z-levels +- `exportlegends`: suppressed ABSTRACT_BUILDING warning +- `gui/dfstatus`: excluded logs in constructions +- `labormanager`: + + - stopped assigning woodcutting jobs to elves + - "recover wounded" jobs now weighted based on altruism + +- `remotefortressreader`: added support for buildings, grass, riders, and + hair/beard styles + + DFHack 0.43.05-r2 ================= From e2f705c76d34e858023e9a77071a2184a27bb3b9 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 23 Nov 2017 16:38:05 -0500 Subject: [PATCH 49/66] Update version in CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 79889dcb0..6faa01870 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,7 +141,7 @@ endif() # set up versioning. set(DF_VERSION "0.43.05") -SET(DFHACK_RELEASE "r2") +SET(DFHACK_RELEASE "r3") SET(DFHACK_PRERELEASE FALSE) set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}") From 69eb10a3e552bba0c9185737dd00fc0af4e369e3 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 24 Nov 2017 23:40:58 -0500 Subject: [PATCH 50/66] Update scripts --- scripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts b/scripts index 3baa24fec..09cf8dde9 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 3baa24fec93461218b5b658de94884ebff0a0b23 +Subproject commit 09cf8dde929e0478a869fa09ec329a27c9631113 From 7508126beffbfcf2420ff96c2e9453d6ef9a5294 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 25 Nov 2017 00:50:22 -0500 Subject: [PATCH 51/66] Change version to 0.44.02-r0 --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6faa01870..3c7838949 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,9 +140,9 @@ if (NOT EXISTS ${dfhack_SOURCE_DIR}/library/xml/codegen.pl OR NOT EXISTS ${dfhac endif() # set up versioning. -set(DF_VERSION "0.43.05") -SET(DFHACK_RELEASE "r3") -SET(DFHACK_PRERELEASE FALSE) +set(DF_VERSION "0.44.02") +SET(DFHACK_RELEASE "r0") +SET(DFHACK_PRERELEASE TRUE) set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}") From 2c95ac411e5bca1fc8cfba3008886e0c01a03b5b Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 25 Nov 2017 00:59:59 -0500 Subject: [PATCH 52/66] Update xml and all uses of job_handler --- library/include/df/custom/job_handler.methods.inc | 1 + library/modules/Buildings.cpp | 2 +- library/modules/Designations.cpp | 4 ++-- library/modules/EventManager.cpp | 4 ++-- library/modules/Job.cpp | 12 ++++++------ library/xml | 2 +- plugins/digFlood.cpp | 2 +- plugins/diggingInvaders/diggingInvaders.cpp | 2 +- plugins/labormanager/labormanager.cpp | 4 ++-- .../remotefortressreader/remotefortressreader.cpp | 8 ++++---- plugins/ruby/job.rb | 4 ++-- plugins/ruby/map.rb | 4 ++-- plugins/showmood.cpp | 2 +- plugins/stockflow.cpp | 2 +- plugins/workflow.cpp | 10 +++++----- 15 files changed, 32 insertions(+), 31 deletions(-) create mode 100644 library/include/df/custom/job_handler.methods.inc diff --git a/library/include/df/custom/job_handler.methods.inc b/library/include/df/custom/job_handler.methods.inc new file mode 100644 index 000000000..c160f5470 --- /dev/null +++ b/library/include/df/custom/job_handler.methods.inc @@ -0,0 +1 @@ +friend struct df::world; diff --git a/library/modules/Buildings.cpp b/library/modules/Buildings.cpp index 759e3acd4..e3d8e1d69 100644 --- a/library/modules/Buildings.cpp +++ b/library/modules/Buildings.cpp @@ -138,7 +138,7 @@ void buildings_onUpdate(color_ostream &out) { buildings_do_onupdate = false; - df::job_list_link *link = world->job_list.next; + df::job_list_link *link = world->jobs.list.next; for (; link; link = link->next) { df::job *job = link->item; diff --git a/library/modules/Designations.cpp b/library/modules/Designations.cpp index 3fb325096..1d41cfb49 100644 --- a/library/modules/Designations.cpp +++ b/library/modules/Designations.cpp @@ -66,7 +66,7 @@ bool Designations::isPlantMarked(const df::plant *plant) if (block->designation[des_pos.x % 16][des_pos.y % 16].bits.dig == tile_dig_designation::Default) return true; - for (auto *link = world->job_list.next; link; link = link->next) + for (auto *link = world->jobs.list.next; link; link = link->next) { df::job *job = link->item; if (!job) @@ -128,7 +128,7 @@ bool Designations::unmarkPlant(const df::plant *plant) block->designation[des_pos.x % 16][des_pos.y % 16].bits.dig = tile_dig_designation::No; block->flags.bits.designated = true; - auto *link = world->job_list.next; + auto *link = world->jobs.list.next; while (link) { auto *next = link->next; diff --git a/library/modules/EventManager.cpp b/library/modules/EventManager.cpp index e2baf9bfb..8ce2c97f4 100644 --- a/library/modules/EventManager.cpp +++ b/library/modules/EventManager.cpp @@ -381,7 +381,7 @@ static void manageJobInitiatedEvent(color_ostream& out) { } multimap copy(handlers[EventType::JOB_INITIATED].begin(), handlers[EventType::JOB_INITIATED].end()); - for ( df::job_list_link* link = &df::global::world->job_list; link != NULL; link = link->next ) { + for ( df::job_list_link* link = &df::global::world->jobs.list; link != NULL; link = link->next ) { if ( link->item == NULL ) continue; if ( link->item->id <= lastJobId ) @@ -411,7 +411,7 @@ static void manageJobCompletedEvent(color_ostream& out) { multimap copy(handlers[EventType::JOB_COMPLETED].begin(), handlers[EventType::JOB_COMPLETED].end()); map nowJobs; - for ( df::job_list_link* link = &df::global::world->job_list; link != NULL; link = link->next ) { + for ( df::job_list_link* link = &df::global::world->jobs.list; link != NULL; link = link->next ) { if ( link->item == NULL ) continue; nowJobs[link->item->id] = link->item; diff --git a/library/modules/Job.cpp b/library/modules/Job.cpp index 3f12ea2c2..132dcfc4b 100644 --- a/library/modules/Job.cpp +++ b/library/modules/Job.cpp @@ -490,10 +490,10 @@ bool DFHack::Job::linkIntoWorld(df::job *job, bool new_id) job->list_link = new df::job_list_link(); job->list_link->item = job; - linked_list_append(&world->job_list, job->list_link); + linked_list_append(&world->jobs.list, job->list_link); return true; } else { - df::job_list_link *ins_pos = &world->job_list; + df::job_list_link *ins_pos = &world->jobs.list; while (ins_pos->next && ins_pos->next->item->id < job->id) ins_pos = ins_pos->next; @@ -514,15 +514,15 @@ bool DFHack::Job::removePostings(df::job *job, bool remove_all) bool removed = false; if (!remove_all) { - if (job->posting_index >= 0 && job->posting_index < world->job_postings.size()) + if (job->posting_index >= 0 && job->posting_index < world->jobs.postings.size()) { - world->job_postings[job->posting_index]->flags.bits.dead = true; + world->jobs.postings[job->posting_index]->flags.bits.dead = true; removed = true; } } else { - for (auto it = world->job_postings.begin(); it != world->job_postings.end(); ++it) + for (auto it = world->jobs.postings.begin(); it != world->jobs.postings.end(); ++it) { if ((**it).job == job) { @@ -553,7 +553,7 @@ bool DFHack::Job::listNewlyCreated(std::vector *pvec, int *id_var) pvec->reserve(std::min(20,cur_id - old_id)); - df::job_list_link *link = world->job_list.next; + df::job_list_link *link = world->jobs.list.next; for (; link; link = link->next) { int id = link->item->id; diff --git a/library/xml b/library/xml index 860a9041a..fd6e70de5 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 860a9041a75305609643d465123a4b598140dd7f +Subproject commit fd6e70de5047a48b163ced482c8a925b6a021891 diff --git a/plugins/digFlood.cpp b/plugins/digFlood.cpp index 6668f9994..ada6213a6 100644 --- a/plugins/digFlood.cpp +++ b/plugins/digFlood.cpp @@ -89,7 +89,7 @@ void onDig(color_ostream& out, void* ptr) { return; set jobLocations; - for ( df::job_list_link* link = &world->job_list; link != NULL; link = link->next ) { + for ( df::job_list_link* link = &world->jobs.list; link != NULL; link = link->next ) { if ( link->item == NULL ) continue; diff --git a/plugins/diggingInvaders/diggingInvaders.cpp b/plugins/diggingInvaders/diggingInvaders.cpp index 4892c5e1d..9bbc5191e 100644 --- a/plugins/diggingInvaders/diggingInvaders.cpp +++ b/plugins/diggingInvaders/diggingInvaders.cpp @@ -598,7 +598,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) { lastInvasionDigger = firstInvader->id; lastInvasionJob = firstInvader->job.current_job ? firstInvader->job.current_job->id : -1; invaderJobs.erase(lastInvasionJob); - for ( df::job_list_link* link = &world->job_list; link != NULL; link = link->next ) { + for ( df::job_list_link* link = &world->jobs.list; link != NULL; link = link->next ) { if ( link->item == NULL ) continue; df::job* job = link->item; diff --git a/plugins/labormanager/labormanager.cpp b/plugins/labormanager/labormanager.cpp index 1a5323d8a..3a026d1ea 100644 --- a/plugins/labormanager/labormanager.cpp +++ b/plugins/labormanager/labormanager.cpp @@ -1155,7 +1155,7 @@ private: void collect_job_list() { - for (df::job_list_link* jll = world->job_list.next; jll; jll = jll->next) + for (df::job_list_link* jll = world->jobs.list.next; jll; jll = jll->next) { df::job* j = jll->item; if (!j) @@ -1163,7 +1163,7 @@ private: process_job(j); } - for (auto jp = world->job_postings.begin(); jp != world->job_postings.end(); jp++) + for (auto jp = world->jobs.postings.begin(); jp != world->jobs.postings.end(); jp++) { if ((*jp)->flags.bits.dead) continue; diff --git a/plugins/remotefortressreader/remotefortressreader.cpp b/plugins/remotefortressreader/remotefortressreader.cpp index a07668778..b543a2ab3 100644 --- a/plugins/remotefortressreader/remotefortressreader.cpp +++ b/plugins/remotefortressreader/remotefortressreader.cpp @@ -1127,9 +1127,9 @@ void CopyDesignation(df::map_block * DfBlock, RemoteFortressReader::MapBlock * N } } #if DF_VERSION_INT > 34011 - for (int i = 0; i < world->job_postings.size(); i++) + for (int i = 0; i < world->jobs.postings.size(); i++) { - auto job = world->job_postings[i]->job; + auto job = world->jobs.postings[i]->job; if (job == nullptr) continue; if ( @@ -1616,7 +1616,7 @@ static command_result GetUnitList(color_ostream &stream, const EmptyMessage *in, send_style->set_style((HairStyle)unit->appearance.tissue_style[j]); } } - + for (int j = 0; j < unit->inventory.size(); j++) { auto inventory_item = unit->inventory[j]; @@ -2738,7 +2738,7 @@ static command_result SendDigCommand(color_ostream &stream, const DigCommand *in #if DF_VERSION_INT >= 43005 //remove and job postings related. - for (df::job_list_link * listing = &(world->job_list); listing != NULL; listing = listing->next) + for (df::job_list_link * listing = &(world->jobs.list); listing != NULL; listing = listing->next) { if (listing->item == NULL) continue; diff --git a/plugins/ruby/job.rb b/plugins/ruby/job.rb index e489dcc91..bf033fbb3 100644 --- a/plugins/ruby/job.rb +++ b/plugins/ruby/job.rb @@ -1,9 +1,9 @@ module DFHack class << self # link a job to the world - # allocate & set job.id, allocate a JobListLink, link to job & world.job_list + # allocate & set job.id, allocate a JobListLink, link to job & world.jobs.list def job_link(job) - lastjob = world.job_list + lastjob = world.jobs.list lastjob = lastjob.next while lastjob.next joblink = JobListLink.cpp_new joblink.prev = lastjob diff --git a/plugins/ruby/map.rb b/plugins/ruby/map.rb index f6f69de75..5c6295946 100644 --- a/plugins/ruby/map.rb +++ b/plugins/ruby/map.rb @@ -269,7 +269,7 @@ module DFHack def dig(mode=:Default) if mode == :Smooth if (tilemat == :STONE or tilemat == :MINERAL) and caption !~ /smooth|pillar|fortification/i and # XXX caption.. - designation.smooth == 0 and (designation.hidden or not df.world.job_list.find { |j| + designation.smooth == 0 and (designation.hidden or not df.world.jobs.list.find { |j| # the game removes 'smooth' designation as soon as it assigns a job, if we # re-set it the game may queue another :DetailWall that will carve a fortification (j.job_type == :DetailWall or j.job_type == :DetailFloor) and df.same_pos?(j, self) @@ -279,7 +279,7 @@ module DFHack mapblock.flags.designated = true end else - return if mode != :No and designation.dig == :No and not designation.hidden and df.world.job_list.find { |j| + return if mode != :No and designation.dig == :No and not designation.hidden and df.world.jobs.list.find { |j| # someone already enroute to dig here, avoid 'Inappropriate dig square' spam JobType::Type[j.job_type] == :Digging and df.same_pos?(j, self) } diff --git a/plugins/showmood.cpp b/plugins/showmood.cpp index 05e9a67ad..d2ae73f08 100644 --- a/plugins/showmood.cpp +++ b/plugins/showmood.cpp @@ -43,7 +43,7 @@ command_result df_showmood (color_ostream &out, vector & parameters) CoreSuspender suspend; bool found = false; - for (df::job_list_link *cur = world->job_list.next; cur != NULL; cur = cur->next) + for (df::job_list_link *cur = world->jobs.list.next; cur != NULL; cur = cur->next) { df::job *job = cur->item; if ((job->job_type < job_type::StrangeMoodCrafter) || (job->job_type > job_type::StrangeMoodMechanics)) diff --git a/plugins/stockflow.cpp b/plugins/stockflow.cpp index ff87bdddc..7cfc8ce0d 100644 --- a/plugins/stockflow.cpp +++ b/plugins/stockflow.cpp @@ -69,7 +69,7 @@ public: } else { // Gather orders when the bookkeeper starts updating stockpile records, // and enqueue them when the job is done. - for (df::job_list_link* link = &world->job_list; link != NULL; link = link->next) { + for (df::job_list_link* link = &world->jobs.list; link != NULL; link = link->next) { if (link->item == NULL) continue; if (link->item->job_type == job_type::UpdateStockpileRecords) { found = true; diff --git a/plugins/workflow.cpp b/plugins/workflow.cpp index f8f9e8231..cc3ac8cd7 100644 --- a/plugins/workflow.cpp +++ b/plugins/workflow.cpp @@ -429,15 +429,15 @@ public: static int fix_job_postings (color_ostream *out, bool dry_run) { int count = 0; - df::job_list_link *link = &world->job_list; + df::job_list_link *link = &world->jobs.list; while (link) { df::job *job = link->item; if (job) { - for (size_t i = 0; i < world->job_postings.size(); ++i) + for (size_t i = 0; i < world->jobs.postings.size(); ++i) { - df::world::T_job_postings *posting = world->job_postings[i]; + df::job_handler::T_postings *posting = world->jobs.postings[i]; if (posting->job == job && i != job->posting_index && !posting->flags.bits.dead) { ++count; @@ -673,7 +673,7 @@ static void check_lost_jobs(color_ostream &out, int ticks) ProtectedJob::cur_tick_idx++; if (ticks < 0) ticks = 0; - df::job_list_link *p = world->job_list.next; + df::job_list_link *p = world->jobs.list.next; for (; p; p = p->next) { df::job *job = p->item; @@ -707,7 +707,7 @@ static void check_lost_jobs(color_ostream &out, int ticks) static void update_job_data(color_ostream &out) { - df::job_list_link *p = world->job_list.next; + df::job_list_link *p = world->jobs.list.next; for (; p; p = p->next) { ProtectedJob *pj = get_known(p->item->id); From 35b0e962ce53835092a2218262ba8ddfb2c5abb7 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 25 Nov 2017 01:10:47 -0500 Subject: [PATCH 53/66] Fix crash on empty symbol tables --- library/VersionInfoFactory.cpp | 4 ++++ library/xml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/library/VersionInfoFactory.cpp b/library/VersionInfoFactory.cpp index 707c2809f..cdfdbf774 100644 --- a/library/VersionInfoFactory.cpp +++ b/library/VersionInfoFactory.cpp @@ -116,6 +116,10 @@ void VersionInfoFactory::ParseVersion (TiXmlElement* entry, VersionInfo* mem) // process additional entries //cout << "Entry " << cstr_version << " " << cstr_os << endl; + if (!entry->FirstChildElement()) { + cerr << "Empty symbol table: " << entry->Attribute("name") << endl; + return; + } pMemEntry = entry->FirstChildElement()->ToElement(); for(;pMemEntry;pMemEntry=pMemEntry->NextSiblingElement()) { diff --git a/library/xml b/library/xml index fd6e70de5..24b87c746 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit fd6e70de5047a48b163ced482c8a925b6a021891 +Subproject commit 24b87c74675df5059b848c4a1b8764a293fdda1b From e174135133172b7875ba33cde7c133bc54242e99 Mon Sep 17 00:00:00 2001 From: Quietust Date: Sat, 2 Dec 2017 21:06:29 -0600 Subject: [PATCH 54/66] update structures --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index 24b87c746..c1e116acc 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 24b87c74675df5059b848c4a1b8764a293fdda1b +Subproject commit c1e116acc0cb6f4a968503215237310d29947502 From 4edc7a6f43959758250c17d4322960c038785984 Mon Sep 17 00:00:00 2001 From: Quietust Date: Sat, 2 Dec 2017 21:41:44 -0600 Subject: [PATCH 55/66] update DataFuncs to support vmethods with 12-13 parameters (#1192) --- library/include/DataFuncs.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/library/include/DataFuncs.h b/library/include/DataFuncs.h index bf8e6b244..6541ae900 100644 --- a/library/include/DataFuncs.h +++ b/library/include/DataFuncs.h @@ -221,6 +221,29 @@ INSTANTIATE_WRAPPERS(11, (A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11), LOAD_ARG(A9); LOAD_ARG(A10); LOAD_ARG(A11);) #undef FW_TARGS +#define FW_TARGS class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12 +INSTANTIATE_RETURN_TYPE((A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)) +INSTANTIATE_WRAPPERS(12, (A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12), + (OSTREAM_ARG,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12), + (vA1,vA2,vA3,vA4,vA5,vA6,vA7,vA8,vA9,vA10,vA11,vA12), + (out,vA1,vA2,vA3,vA4,vA5,vA6,vA7,vA8,vA9,vA10,vA11,vA12), + LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3); LOAD_ARG(A4); + LOAD_ARG(A5); LOAD_ARG(A6); LOAD_ARG(A7); LOAD_ARG(A8); + LOAD_ARG(A9); LOAD_ARG(A10); LOAD_ARG(A11); LOAD_ARG(A12);) +#undef FW_TARGS + +#define FW_TARGS class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13 +INSTANTIATE_RETURN_TYPE((A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)) +INSTANTIATE_WRAPPERS(13, (A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13), + (OSTREAM_ARG,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13), + (vA1,vA2,vA3,vA4,vA5,vA6,vA7,vA8,vA9,vA10,vA11,vA12,vA13), + (out,vA1,vA2,vA3,vA4,vA5,vA6,vA7,vA8,vA9,vA10,vA11,vA12,vA13), + LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3); LOAD_ARG(A4); + LOAD_ARG(A5); LOAD_ARG(A6); LOAD_ARG(A7); LOAD_ARG(A8); + LOAD_ARG(A9); LOAD_ARG(A10); LOAD_ARG(A11); LOAD_ARG(A12); + LOAD_ARG(A13);) +#undef FW_TARGS + #undef FW_TARGSC #undef INSTANTIATE_WRAPPERS #undef INSTANTIATE_WRAPPERS2 From 1489e7db824cc6323de14772fbf0f121ecd0860b Mon Sep 17 00:00:00 2001 From: Quietust Date: Sat, 2 Dec 2017 22:14:04 -0600 Subject: [PATCH 56/66] update structures - fix unit_personality and historical_figure_info.personality --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index c1e116acc..487eb45e2 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit c1e116acc0cb6f4a968503215237310d29947502 +Subproject commit 487eb45e2d083aee1ca104c6fb1a33942b2448d2 From ec06ed09c900a9381cb3a72ff7829bfcd5b835be Mon Sep 17 00:00:00 2001 From: Quietust Date: Sun, 3 Dec 2017 13:49:57 -0600 Subject: [PATCH 57/66] update structures - add remaining Linux 64-bit offsets --- library/xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/xml b/library/xml index 487eb45e2..3abfb36a1 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 487eb45e2d083aee1ca104c6fb1a33942b2448d2 +Subproject commit 3abfb36a129add730599cf27684b2c65ff7ba6bb From c72ae8d8a77958cbe8bc9447ae0e14fff53b9f8b Mon Sep 17 00:00:00 2001 From: Quietust Date: Sun, 3 Dec 2017 20:05:08 -0600 Subject: [PATCH 58/66] Merge "announcements" global into d_init where it belongs --- library/modules/Gui.cpp | 8 ++++---- library/xml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library/modules/Gui.cpp b/library/modules/Gui.cpp index 7de9a5e11..c3fad806f 100644 --- a/library/modules/Gui.cpp +++ b/library/modules/Gui.cpp @@ -48,12 +48,12 @@ using namespace DFHack; #include "DataDefs.h" #include "df/announcement_flags.h" -#include "df/announcements.h" #include "df/assign_trade_status.h" #include "df/building_civzonest.h" #include "df/building_furnacest.h" #include "df/building_trapst.h" #include "df/building_workshopst.h" +#include "df/d_init.h" #include "df/game_mode.h" #include "df/general_ref.h" #include "df/global_objects.h" @@ -1428,13 +1428,13 @@ void Gui::showAutoAnnouncement( df::announcement_type type, df::coord pos, std::string message, int color, bool bright, df::unit *unit1, df::unit *unit2 ) { - using df::global::announcements; + using df::global::d_init; df::announcement_flags flags; flags.bits.D_DISPLAY = flags.bits.A_DISPLAY = true; - if (is_valid_enum_item(type) && announcements) - flags = announcements->flags[type]; + if (is_valid_enum_item(type) && d_init) + flags = d_init->announcements.flags[type]; int id = makeAnnouncement(type, flags, pos, message, color, bright); diff --git a/library/xml b/library/xml index 3abfb36a1..9ffd5971b 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 3abfb36a129add730599cf27684b2c65ff7ba6bb +Subproject commit 9ffd5971bd4709abec914715cee1a23963b7ee91 From 88c7e493b8c4ed4c1449e047a466556e05f5c9f4 Mon Sep 17 00:00:00 2001 From: Quietust Date: Sun, 3 Dec 2017 20:34:59 -0600 Subject: [PATCH 59/66] Merge ui_area_map_width into ui_menu_width, now a 2-byte array --- library/lua/gui/dwarfmode.lua | 4 ++-- library/modules/Gui.cpp | 13 ++++++------- library/xml | 2 +- plugins/fix-armory.cpp | 2 -- plugins/rendermax/renderer_light.cpp | 4 ++-- plugins/rendermax/rendermax.cpp | 2 -- plugins/ruby/ui.rb | 6 +++--- plugins/tweak/tweak.cpp | 2 -- plugins/zone.cpp | 5 ++--- 9 files changed, 16 insertions(+), 24 deletions(-) diff --git a/library/lua/gui/dwarfmode.lua b/library/lua/gui/dwarfmode.lua index 3764c4df7..e98ba2080 100644 --- a/library/lua/gui/dwarfmode.lua +++ b/library/lua/gui/dwarfmode.lua @@ -18,8 +18,8 @@ refreshSidebar = dfhack.gui.refreshSidebar function getPanelLayout() local dims = dfhack.gui.getDwarfmodeViewDims() - local area_pos = df.global.ui_area_map_width - local menu_pos = df.global.ui_menu_width + local area_pos = df.global.ui_menu_width[1] + local menu_pos = df.global.ui_menu_width[0] if dims.menu_forced then menu_pos = area_pos - 1 diff --git a/library/modules/Gui.cpp b/library/modules/Gui.cpp index c3fad806f..0631e0ed7 100644 --- a/library/modules/Gui.cpp +++ b/library/modules/Gui.cpp @@ -108,7 +108,6 @@ using df::global::ui; using df::global::world; using df::global::selection_rect; using df::global::ui_menu_width; -using df::global::ui_area_map_width; using df::global::gamemode; static df::layer_object_listst *getLayerList(df::viewscreen_layer *layer, int idx) @@ -1508,8 +1507,8 @@ Gui::DwarfmodeDims getDwarfmodeViewDims_default() dims.area_x1 = dims.area_x2 = dims.menu_x1 = dims.menu_x2 = -1; dims.menu_forced = false; - int menu_pos = (ui_menu_width ? *ui_menu_width : 2); - int area_pos = (ui_area_map_width ? *ui_area_map_width : 3); + int menu_pos = (ui_menu_width ? (*ui_menu_width)[0] : 2); + int area_pos = (ui_menu_width ? (*ui_menu_width)[1] : 3); if (ui && ui->main.mode && menu_pos >= area_pos) { @@ -1715,14 +1714,14 @@ bool Gui::getWindowSize (int32_t &width, int32_t &height) bool Gui::getMenuWidth(uint8_t &menu_width, uint8_t &area_map_width) { - menu_width = *df::global::ui_menu_width; - area_map_width = *df::global::ui_area_map_width; + menu_width = (*df::global::ui_menu_width)[0]; + area_map_width = (*df::global::ui_menu_width)[1]; return true; } bool Gui::setMenuWidth(const uint8_t menu_width, const uint8_t area_map_width) { - *df::global::ui_menu_width = menu_width; - *df::global::ui_area_map_width = area_map_width; + (*df::global::ui_menu_width)[0] = menu_width; + (*df::global::ui_menu_width)[1] = area_map_width; return true; } diff --git a/library/xml b/library/xml index 9ffd5971b..0a9a57154 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 9ffd5971bd4709abec914715cee1a23963b7ee91 +Subproject commit 0a9a571545eaf1fd960366fd12dffe6b30add756 diff --git a/plugins/fix-armory.cpp b/plugins/fix-armory.cpp index 8b062290b..0f63b4d93 100644 --- a/plugins/fix-armory.cpp +++ b/plugins/fix-armory.cpp @@ -57,8 +57,6 @@ using df::global::ui; using df::global::world; using df::global::gamemode; using df::global::ui_build_selector; -using df::global::ui_menu_width; -using df::global::ui_area_map_width; using namespace DFHack::Gui; using Screen::Pen; diff --git a/plugins/rendermax/renderer_light.cpp b/plugins/rendermax/renderer_light.cpp index f0f3c92cf..199e174af 100644 --- a/plugins/rendermax/renderer_light.cpp +++ b/plugins/rendermax/renderer_light.cpp @@ -88,8 +88,8 @@ rect2d getMapViewport() int menu_x1=area_x2-MENU_WIDTH-1; int view_rb=w-1; - int area_pos=*df::global::ui_area_map_width; - int menu_pos=*df::global::ui_menu_width; + int area_pos=(*df::global::ui_menu_width)[1]; + int menu_pos=(*df::global::ui_menu_width)[0]; if(area_pos<3) { view_rb=area_x2; diff --git a/plugins/rendermax/rendermax.cpp b/plugins/rendermax/rendermax.cpp index 2140743ca..be8be07ba 100644 --- a/plugins/rendermax/rendermax.cpp +++ b/plugins/rendermax/rendermax.cpp @@ -36,8 +36,6 @@ REQUIRE_GLOBAL(enabler); REQUIRE_GLOBAL(gametype); REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(ui); -REQUIRE_GLOBAL(ui_area_map_width); -REQUIRE_GLOBAL(ui_menu_width); REQUIRE_GLOBAL(window_x); REQUIRE_GLOBAL(window_y); REQUIRE_GLOBAL(window_z); diff --git a/plugins/ruby/ui.rb b/plugins/ruby/ui.rb index a9dd05437..9268dcb9e 100644 --- a/plugins/ruby/ui.rb +++ b/plugins/ruby/ui.rb @@ -15,15 +15,15 @@ module DFHack x, y, z = x.x, x.y, x.z if x.respond_to?(:x) # compute screen 'map' size (tiles) - menuwidth = ui_menu_width + menuwidth = ui_menu_width[0] # ui_menu_width shows only the 'tab' status - menuwidth = 1 if menuwidth == 2 and ui_area_map_width == 2 and cursor.x != -30000 + menuwidth = 1 if menuwidth == 2 and ui_menu_width[1] == 2 and cursor.x != -30000 menuwidth = 2 if menuwidth == 3 and cursor.x != -30000 w_w = gps.dimx - 2 w_h = gps.dimy - 2 case menuwidth when 1; w_w -= 55 - when 2; w_w -= (ui_area_map_width == 2 ? 24 : 31) + when 2; w_w -= (ui_menu_width[1] == 2 ? 24 : 31) end # center view diff --git a/plugins/tweak/tweak.cpp b/plugins/tweak/tweak.cpp index bf044dd58..2970f3792 100644 --- a/plugins/tweak/tweak.cpp +++ b/plugins/tweak/tweak.cpp @@ -117,12 +117,10 @@ DFHACK_PLUGIN_IS_ENABLED(is_enabled); REQUIRE_GLOBAL(enabler); REQUIRE_GLOBAL(ui); -REQUIRE_GLOBAL(ui_area_map_width); REQUIRE_GLOBAL(ui_build_selector); REQUIRE_GLOBAL(ui_building_in_assign); REQUIRE_GLOBAL(ui_building_in_resize); REQUIRE_GLOBAL(ui_building_item_cursor); -REQUIRE_GLOBAL(ui_menu_width); REQUIRE_GLOBAL(ui_look_cursor); REQUIRE_GLOBAL(ui_sidebar_menus); REQUIRE_GLOBAL(ui_unit_view_mode); diff --git a/plugins/zone.cpp b/plugins/zone.cpp index e41704044..608216092 100644 --- a/plugins/zone.cpp +++ b/plugins/zone.cpp @@ -108,7 +108,6 @@ REQUIRE_GLOBAL(ui_building_assign_items); REQUIRE_GLOBAL(ui_building_in_assign); REQUIRE_GLOBAL(ui_menu_width); -REQUIRE_GLOBAL(ui_area_map_width); using namespace DFHack::Gui; @@ -3926,8 +3925,8 @@ public: return; int left_margin = gps->dimx - 30; - int8_t a = *ui_menu_width; - int8_t b = *ui_area_map_width; + int8_t a = (*ui_menu_width)[0]; + int8_t b = (*ui_menu_width)[1]; if ((a == 1 && b > 1) || (a == 2 && b == 2)) left_margin -= 24; From 5c9318654d56089abb221a65ba48537f9a52b561 Mon Sep 17 00:00:00 2001 From: lethosor Date: Mon, 4 Dec 2017 13:31:42 -0500 Subject: [PATCH 60/66] Change release to alpha0 to avoid error from prerelease-warning --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c7838949..b43de8400 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,7 +141,7 @@ endif() # set up versioning. set(DF_VERSION "0.44.02") -SET(DFHACK_RELEASE "r0") +SET(DFHACK_RELEASE "alpha0") SET(DFHACK_PRERELEASE TRUE) set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}") From fc952bc67f47f3298d45b20cce29f54df565ff9f Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 7 Dec 2017 14:36:44 -0500 Subject: [PATCH 61/66] Update NEWS-dev.rst --- docs/NEWS-dev.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/NEWS-dev.rst b/docs/NEWS-dev.rst index 2be774672..2f0c3ea97 100644 --- a/docs/NEWS-dev.rst +++ b/docs/NEWS-dev.rst @@ -37,6 +37,23 @@ Development Changelog .. contents:: :depth: 2 +DFHack 0.44.02-alpha1 +===================== + +Fixes +----- +- Fixed a crash that could occur if a symbol table in symbols.xml had no content +- The Lua API can now wrap functions with 12 or 13 parameters + +Structures +---------- +- The ``ui_menu_width`` global is now a 2-byte array; the second item is the + former ``ui_area_map_width`` global, which is now removed +- The former ``announcements`` global is now a field in ``d_init`` +- ``world`` fields formerly beginning with ``job_`` are now fields of + ``world.jobs``, e.g. ``world.job_list`` is now ``world.jobs.list`` + + DFHack 0.43.05-beta2 ==================== From 23bb8c4f3ddb5814acfdd49b08a01da16e70db67 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 7 Dec 2017 14:37:15 -0500 Subject: [PATCH 62/66] Restore REQUIRE_GLOBAL(ui_menu_width) - used in tweak stable-cursor --- plugins/tweak/tweak.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/tweak/tweak.cpp b/plugins/tweak/tweak.cpp index 2970f3792..417784efb 100644 --- a/plugins/tweak/tweak.cpp +++ b/plugins/tweak/tweak.cpp @@ -122,6 +122,7 @@ REQUIRE_GLOBAL(ui_building_in_assign); REQUIRE_GLOBAL(ui_building_in_resize); REQUIRE_GLOBAL(ui_building_item_cursor); REQUIRE_GLOBAL(ui_look_cursor); +REQUIRE_GLOBAL(ui_menu_width); REQUIRE_GLOBAL(ui_sidebar_menus); REQUIRE_GLOBAL(ui_unit_view_mode); REQUIRE_GLOBAL(ui_workshop_in_add); From 622a8dacb61d7eb5165784e5a98c8512db495760 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 7 Dec 2017 14:39:15 -0500 Subject: [PATCH 63/66] Update submodules --- library/xml | 2 +- scripts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/xml b/library/xml index 0a9a57154..e2e256066 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 0a9a571545eaf1fd960366fd12dffe6b30add756 +Subproject commit e2e256066cc4a5c427172d9d27db25b7823e4e86 diff --git a/scripts b/scripts index 09cf8dde9..252a5adbf 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 09cf8dde929e0478a869fa09ec329a27c9631113 +Subproject commit 252a5adbf1a5cae45cf7e623d3c5ce6f3aa1195d From 7721a142d8c18562ce0b7223e38240be8620cfe5 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 7 Dec 2017 14:43:27 -0500 Subject: [PATCH 64/66] Add a basic Lua console API --- NEWS.rst | 7 +++++++ docs/Lua API.rst | 12 ++++++++++++ docs/NEWS-dev.rst | 3 +++ library/LuaApi.cpp | 18 ++++++++++++++++++ 4 files changed, 40 insertions(+) diff --git a/NEWS.rst b/NEWS.rst index e55ca92c5..673ae31f9 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -36,6 +36,13 @@ Changelog .. contents:: :depth: 2 +DFHack future +============= + +Lua +--- +- Added a new ``dfhack.console`` API + DFHack 0.43.05-r3 ================= diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 66c2a5a07..a6a2ab8cd 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -1966,6 +1966,18 @@ unless otherwise noted. ``listdir_recursive()`` returns the initial path and all components following it for each entry. +Console API +----------- + +* ``dfhack.console.clear()`` + + Clears the console; equivalent to the ``cls`` built-in command. + +* ``dfhack.console.flush()`` + + Flushes all output to the console. This can be useful when printing text that + does not end in a newline but should still be displayed. + Internal API ------------ diff --git a/docs/NEWS-dev.rst b/docs/NEWS-dev.rst index 2f0c3ea97..8dfe2866b 100644 --- a/docs/NEWS-dev.rst +++ b/docs/NEWS-dev.rst @@ -53,6 +53,9 @@ Structures - ``world`` fields formerly beginning with ``job_`` are now fields of ``world.jobs``, e.g. ``world.job_list`` is now ``world.jobs.list`` +API Changes +----------- +- Lua: Added a new ``dfhack.console`` API DFHack 0.43.05-beta2 ==================== diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 39b4b41cb..0bf19e93e 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -2429,6 +2429,23 @@ static const luaL_Reg dfhack_designations_funcs[] = { {NULL, NULL} }; +/***** Console module *****/ + +namespace console { + void clear() { + Core::getInstance().getConsole().clear(); + } + void flush() { + Core::getInstance().getConsole() << std::flush; + } +} + +static const LuaWrapper::FunctionReg dfhack_console_module[] = { + WRAPM(console, clear), + WRAPM(console, flush), + { NULL, NULL } +}; + /***** Internal module *****/ static void *checkaddr(lua_State *L, int idx, bool allow_null = false) @@ -2964,5 +2981,6 @@ void OpenDFHackApi(lua_State *state) OpenModule(state, "screen", dfhack_screen_module, dfhack_screen_funcs); OpenModule(state, "filesystem", dfhack_filesystem_module, dfhack_filesystem_funcs); OpenModule(state, "designations", dfhack_designations_module, dfhack_designations_funcs); + OpenModule(state, "console", dfhack_console_module); OpenModule(state, "internal", dfhack_internal_module, dfhack_internal_funcs); } From 43b19c893aed218d3abb75ba3960402dc700fa49 Mon Sep 17 00:00:00 2001 From: lethosor Date: Thu, 7 Dec 2017 14:43:50 -0500 Subject: [PATCH 65/66] Bump version to alpha1 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b43de8400..d55cd9e43 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,7 +141,7 @@ endif() # set up versioning. set(DF_VERSION "0.44.02") -SET(DFHACK_RELEASE "alpha0") +SET(DFHACK_RELEASE "alpha1") SET(DFHACK_PRERELEASE TRUE) set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}") From ad2c939fea4292efc45abb9ff29b4f97bed3eb2b Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 8 Dec 2017 01:19:36 -0500 Subject: [PATCH 66/66] Update Authors.rst: dfhack/scripts#33 --- docs/Authors.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Authors.rst b/docs/Authors.rst index a693646bf..2537abfd1 100644 --- a/docs/Authors.rst +++ b/docs/Authors.rst @@ -84,6 +84,7 @@ Patrik Lundell PatrikLundell Paul Fenwick pjf PeridexisErrant PeridexisErrant Petr Mrázek peterix +Pfhreak Pfhreak potato Priit Laes plaes Putnam Putnam3145