Rename autolabor2 to labormanager and bring up to date with current

develop
Kelly Kinkade 2016-06-27 12:04:51 -05:00
parent 261da66660
commit 2072dcc38d
2 changed files with 354 additions and 135 deletions

@ -3,13 +3,13 @@ DFHACK_PLUGIN(vectors vectors.cpp)
endif() endif()
ADD_DEFINITIONS(-DDEV_PLUGIN) ADD_DEFINITIONS(-DDEV_PLUGIN)
#DFHACK_PLUGIN(autolabor2 autolabor2.cpp)
DFHACK_PLUGIN(buildprobe buildprobe.cpp) DFHACK_PLUGIN(buildprobe buildprobe.cpp)
DFHACK_PLUGIN(color-dfhack-text color-dfhack-text.cpp) DFHACK_PLUGIN(color-dfhack-text color-dfhack-text.cpp)
DFHACK_PLUGIN(counters counters.cpp) DFHACK_PLUGIN(counters counters.cpp)
DFHACK_PLUGIN(dumpmats dumpmats.cpp) DFHACK_PLUGIN(dumpmats dumpmats.cpp)
DFHACK_PLUGIN(eventExample eventExample.cpp) DFHACK_PLUGIN(eventExample eventExample.cpp)
DFHACK_PLUGIN(frozen frozen.cpp) DFHACK_PLUGIN(frozen frozen.cpp)
DFHACK_PLUGIN(labormanager labormanager.cpp)
DFHACK_PLUGIN(kittens kittens.cpp) DFHACK_PLUGIN(kittens kittens.cpp)
DFHACK_PLUGIN(memview memview.cpp) DFHACK_PLUGIN(memview memview.cpp)
DFHACK_PLUGIN(nestboxes nestboxes.cpp) DFHACK_PLUGIN(nestboxes nestboxes.cpp)

@ -1,5 +1,5 @@
/* /*
* Autolabor 2.0 module for dfhack * Labor manager (formerly Autolabor 2) module for dfhack
* *
* */ * */
@ -77,7 +77,7 @@ using df::global::world;
#define ARRAY_COUNT(array) (sizeof(array)/sizeof((array)[0])) #define ARRAY_COUNT(array) (sizeof(array)/sizeof((array)[0]))
DFHACK_PLUGIN_IS_ENABLED(enable_autolabor); DFHACK_PLUGIN_IS_ENABLED(enable_labormanager);
static bool print_debug = 0; static bool print_debug = 0;
@ -94,11 +94,11 @@ enum ConfigFlags {
// Here go all the command declarations... // Here go all the command declarations...
// mostly to allow having the mandatory stuff on top of the file and commands on the bottom // mostly to allow having the mandatory stuff on top of the file and commands on the bottom
command_result autolabor (color_ostream &out, std::vector <std::string> & parameters); command_result labormanager (color_ostream &out, std::vector <std::string> & parameters);
// A plugin must be able to return its name and version. // A plugin must be able to return its name and version.
// The name string provided must correspond to the filename - autolabor2.plug.so or autolabor2.plug.dll in this case // The name string provided must correspond to the filename - labormanager.plug.so or labormanager.plug.dll in this case
DFHACK_PLUGIN("autolabor2"); DFHACK_PLUGIN("labormanager");
static void generate_labor_to_skill_map(); static void generate_labor_to_skill_map();
@ -486,9 +486,20 @@ static const struct labor_default default_labor_infos[] = {
/* PRESSING */ {200, 0, TOOL_NONE}, /* PRESSING */ {200, 0, TOOL_NONE},
/* BEEKEEPING */ {200, 0, TOOL_NONE}, /* BEEKEEPING */ {200, 0, TOOL_NONE},
/* WAX_WORKING */ {200, 0, TOOL_NONE}, /* WAX_WORKING */ {200, 0, TOOL_NONE},
/* PUSH_HAUL_VEHICLES */ {200, 0, TOOL_NONE} /* PUSH_HAUL_VEHICLES */ {200, 0, TOOL_NONE},
/* HAUL_TRADE */ {200, 0, TOOL_NONE},
/* PULL_LEVER */ {200, 0, TOOL_NONE},
/* REMOVE_CONSTRUCTION */ {200, 0, TOOL_NONE},
/* HAUL_WATER */ {200, 0, TOOL_NONE},
/* GELD */ {200, 0, TOOL_NONE},
/* BUILD_ROAD */ {200, 0, TOOL_NONE},
/* BUILD_CONSTRUCTION */ {200, 0, TOOL_NONE},
/* PAPERMAKING */ {200, 0, TOOL_NONE},
/* BOOKBINDING */ {200, 0, TOOL_NONE}
}; };
void debug (char* fmt, ...);
struct dwarf_info_t struct dwarf_info_t
{ {
df::unit* dwarf; df::unit* dwarf;
@ -506,12 +517,19 @@ struct dwarf_info_t
df::unit_labor using_labor; df::unit_labor using_labor;
dwarf_info_t(df::unit* dw) : dwarf(dw), clear_all(false), dwarf_info_t(df::unit* dw) : dwarf(dw), clear_all(false),
state(OTHER), high_skill(0), has_children(false), armed(false) state(OTHER), high_skill(0), has_children(false), armed(false), using_labor(df::unit_labor::NONE)
{ {
for (int e = TOOL_NONE; e < TOOLS_MAX; e++) for (int e = TOOL_NONE; e < TOOLS_MAX; e++)
has_tool[e] = false; has_tool[e] = false;
} }
~dwarf_info_t()
{
if (print_debug)
debug("LABORMANAGER: destroying dwarf %p\n", (void*) this);
}
void set_labor(df::unit_labor labor) void set_labor(df::unit_labor labor)
{ {
if (labor >= 0 && labor <= ENUM_LAST_ITEM(unit_labor)) if (labor >= 0 && labor <= ENUM_LAST_ITEM(unit_labor))
@ -554,10 +572,10 @@ static df::unit_labor hauling_labor_map[] =
df::unit_labor::HAUL_ITEM, /* INSTRUMENT */ df::unit_labor::HAUL_ITEM, /* INSTRUMENT */
df::unit_labor::HAUL_ITEM, /* TOY */ df::unit_labor::HAUL_ITEM, /* TOY */
df::unit_labor::HAUL_FURNITURE, /* WINDOW */ df::unit_labor::HAUL_FURNITURE, /* WINDOW */
df::unit_labor::HAUL_ANIMAL, /* CAGE */ df::unit_labor::HAUL_ANIMALS, /* CAGE */
df::unit_labor::HAUL_ITEM, /* BARREL */ df::unit_labor::HAUL_ITEM, /* BARREL */
df::unit_labor::HAUL_ITEM, /* BUCKET */ df::unit_labor::HAUL_ITEM, /* BUCKET */
df::unit_labor::HAUL_ANIMAL, /* ANIMALTRAP */ df::unit_labor::HAUL_ANIMALS, /* ANIMALTRAP */
df::unit_labor::HAUL_FURNITURE, /* TABLE */ df::unit_labor::HAUL_FURNITURE, /* TABLE */
df::unit_labor::HAUL_FURNITURE, /* COFFIN */ df::unit_labor::HAUL_FURNITURE, /* COFFIN */
df::unit_labor::HAUL_FURNITURE, /* STATUE */ df::unit_labor::HAUL_FURNITURE, /* STATUE */
@ -850,7 +868,7 @@ private:
return df::unit_labor::SIEGECRAFT; return df::unit_labor::SIEGECRAFT;
} }
debug ("AUTOLABOR: Cannot deduce labor for construct building job of type %s\n", debug ("LABORMANAGER: Cannot deduce labor for construct building job of type %s\n",
ENUM_KEY_STR(building_type, bld->getType()).c_str()); ENUM_KEY_STR(building_type, bld->getType()).c_str());
return df::unit_labor::NONE; return df::unit_labor::NONE;
@ -944,7 +962,7 @@ private:
return df::unit_labor::SIEGECRAFT; return df::unit_labor::SIEGECRAFT;
} }
debug ("AUTOLABOR: Cannot deduce labor for destroy building job of type %s\n", debug ("LABORMANAGER: Cannot deduce labor for destroy building job of type %s\n",
ENUM_KEY_STR(building_type, bld->getType()).c_str()); ENUM_KEY_STR(building_type, bld->getType()).c_str());
return df::unit_labor::NONE; return df::unit_labor::NONE;
@ -979,13 +997,13 @@ private:
return df::unit_labor::BONE_CARVE; return df::unit_labor::BONE_CARVE;
else else
{ {
debug ("AUTOLABOR: Cannot deduce labor for make crafts job (not bone)\n"); debug ("LABORMANAGER: Cannot deduce labor for make crafts job (not bone)\n");
return df::unit_labor::NONE; return df::unit_labor::NONE;
} }
case df::item_type::WOOD: case df::item_type::WOOD:
return df::unit_labor::WOOD_CRAFT; return df::unit_labor::WOOD_CRAFT;
default: default:
debug ("AUTOLABOR: Cannot deduce labor for make crafts job, item type %s\n", debug ("LABORMANAGER: Cannot deduce labor for make crafts job, item type %s\n",
ENUM_KEY_STR(item_type, jobitem).c_str()); ENUM_KEY_STR(item_type, jobitem).c_str());
return df::unit_labor::NONE; return df::unit_labor::NONE;
} }
@ -1002,7 +1020,7 @@ private:
case df::workshop_type::MetalsmithsForge: case df::workshop_type::MetalsmithsForge:
return metaltype; return metaltype;
default: default:
debug ("AUTOLABOR: Cannot deduce labor for make job, workshop type %s\n", debug ("LABORMANAGER: Cannot deduce labor for make job, workshop type %s\n",
ENUM_KEY_STR(workshop_type, type).c_str()); ENUM_KEY_STR(workshop_type, type).c_str());
return df::unit_labor::NONE; return df::unit_labor::NONE;
} }
@ -1016,13 +1034,13 @@ private:
case df::furnace_type::GlassFurnace: case df::furnace_type::GlassFurnace:
return df::unit_labor::GLASSMAKER; return df::unit_labor::GLASSMAKER;
default: default:
debug ("AUTOLABOR: Cannot deduce labor for make job, furnace type %s\n", debug ("LABORMANAGER: Cannot deduce labor for make job, furnace type %s\n",
ENUM_KEY_STR(furnace_type, type).c_str()); ENUM_KEY_STR(furnace_type, type).c_str());
return df::unit_labor::NONE; return df::unit_labor::NONE;
} }
} }
debug ("AUTOLABOR: Cannot deduce labor for make job, building type %s\n", debug ("LABORMANAGER: Cannot deduce labor for make job, building type %s\n",
ENUM_KEY_STR(building_type, bld->getType()).c_str()); ENUM_KEY_STR(building_type, bld->getType()).c_str());
return df::unit_labor::NONE; return df::unit_labor::NONE;
@ -1147,8 +1165,6 @@ public:
job_to_labor_table[df::job_type::StoreItemInStockpile] = jlf_hauling; 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::StoreItemInBag] = jlf_hauling;
job_to_labor_table[df::job_type::StoreItemInHospital] = jlf_hauling; job_to_labor_table[df::job_type::StoreItemInHospital] = jlf_hauling;
job_to_labor_table[df::job_type::StoreItemInChest] = jlf_hauling;
job_to_labor_table[df::job_type::StoreItemInCabinet] = jlf_hauling;
job_to_labor_table[df::job_type::StoreWeapon] = 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::StoreArmor] = jlf_hauling;
job_to_labor_table[df::job_type::StoreItemInBarrel] = jlf_hauling; job_to_labor_table[df::job_type::StoreItemInBarrel] = jlf_hauling;
@ -1219,7 +1235,6 @@ public:
job_to_labor_table[df::job_type::MilkCreature] = jlf_const(df::unit_labor::MILK); 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::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::ProcessPlants] = jlf_const(df::unit_labor::PROCESS_PLANT);
job_to_labor_table[df::job_type::ProcessPlantsBag] = 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::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::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::PrepareMeal] = jlf_const(df::unit_labor::COOK);
@ -1256,7 +1271,6 @@ public:
job_to_labor_table[df::job_type::CastSpell] = jlf_no_labor; 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::LinkBuildingToTrigger] = jlf_const(df::unit_labor::MECHANIC) ;
job_to_labor_table[df::job_type::PullLever] = jlf_no_labor; job_to_labor_table[df::job_type::PullLever] = jlf_no_labor;
job_to_labor_table[df::job_type::BrewDrink] = jlf_const(df::unit_labor::BREWER) ;
job_to_labor_table[df::job_type::ExtractFromPlants] = jlf_const(df::unit_labor::HERBALIST) ; 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::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::ExtractFromLandAnimal] = jlf_const(df::unit_labor::DISSECT_VERMIN) ;
@ -1334,9 +1348,9 @@ public:
job_to_labor_table[df::job_type::ExecuteCriminal] = 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::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::CarveTrack] = jlf_const(df::unit_labor::DETAIL);
job_to_labor_table[df::job_type::PushTrackVehicle] = jlf_const(df::unit_labor::PUSH_HAUL_VEHICLE); 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::PUSH_HAUL_VEHICLE); job_to_labor_table[df::job_type::PlaceTrackVehicle] = jlf_const(df::unit_labor::HANDLE_VEHICLES);
job_to_labor_table[df::job_type::StoreItemInVehicle] = jlf_const(df::unit_labor::PUSH_HAUL_VEHICLE); job_to_labor_table[df::job_type::StoreItemInVehicle] = jlf_const(df::unit_labor::HANDLE_VEHICLES);
job_to_labor_table[df::job_type::GeldAnimal] = jlf_const(df::unit_labor::GELD); 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::MakeFigurine] = jlf_make_object;
job_to_labor_table[df::job_type::MakeAmulet] = jlf_make_object; job_to_labor_table[df::job_type::MakeAmulet] = jlf_make_object;
@ -1365,7 +1379,14 @@ public:
df::unit_labor labor; 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\n", ENUM_KEY_STR(job_type, j->job_type).c_str());
labor = df::unit_labor::NONE;
} else {
labor = job_to_labor_table[j->job_type]->get_labor(j); labor = job_to_labor_table[j->job_type]->get_labor(j);
}
return labor; return labor;
} }
@ -1375,6 +1396,8 @@ public:
static JobLaborMapper* labor_mapper = 0; static JobLaborMapper* labor_mapper = 0;
static bool initialized = false;
static bool isOptionEnabled(unsigned flag) static bool isOptionEnabled(unsigned flag)
{ {
return config.isValid() && (config.ival(0) & flag) != 0; return config.isValid() && (config.ival(0) & flag) != 0;
@ -1393,8 +1416,9 @@ static void setOptionEnabled(ConfigFlags flag, bool on)
static void cleanup_state() static void cleanup_state()
{ {
enable_autolabor = false; enable_labormanager = false;
labor_infos.clear(); labor_infos.clear();
initialized = false;
} }
static void reset_labor(df::unit_labor labor) static void reset_labor(df::unit_labor labor)
@ -1405,25 +1429,25 @@ static void reset_labor(df::unit_labor labor)
static void init_state() static void init_state()
{ {
config = World::GetPersistentData("autolabor/2.0/config"); config = World::GetPersistentData("labormanager/2.0/config");
if (config.isValid() && config.ival(0) == -1) if (config.isValid() && config.ival(0) == -1)
config.ival(0) = 0; config.ival(0) = 0;
enable_autolabor = isOptionEnabled(CF_ENABLED); enable_labormanager = isOptionEnabled(CF_ENABLED);
if (!enable_autolabor) if (!enable_labormanager)
return; return;
// Load labors from save // Load labors from save
labor_infos.resize(ARRAY_COUNT(default_labor_infos)); labor_infos.resize(ARRAY_COUNT(default_labor_infos));
std::vector<PersistentDataItem> items; std::vector<PersistentDataItem> items;
World::GetPersistentData(&items, "autolabor/2.0/labors/", true); World::GetPersistentData(&items, "labormanager/2.0/labors/", true);
for (auto p = items.begin(); p != items.end(); p++) for (auto p = items.begin(); p != items.end(); p++)
{ {
string key = p->key(); string key = p->key();
df::unit_labor labor = (df::unit_labor) atoi(key.substr(strlen("autolabor/2.0/labors/")).c_str()); df::unit_labor labor = (df::unit_labor) atoi(key.substr(strlen("labormanager/2.0/labors/")).c_str());
if (labor >= 0 && labor <= labor_infos.size()) if (labor >= 0 && labor <= labor_infos.size())
{ {
labor_infos[labor].config = *p; labor_infos[labor].config = *p;
@ -1437,7 +1461,7 @@ static void init_state()
continue; continue;
std::stringstream name; std::stringstream name;
name << "autolabor/2.0/labors/" << i; name << "labormanager/2.0/labors/" << i;
labor_infos[i].config = World::AddPersistentData(name.str()); labor_infos[i].config = World::AddPersistentData(name.str());
labor_infos[i].mark_assigned(); labor_infos[i].mark_assigned();
@ -1445,6 +1469,8 @@ static void init_state()
reset_labor((df::unit_labor) i); reset_labor((df::unit_labor) i);
} }
initialized = true;
} }
static df::job_skill labor_to_skill[ENUM_LAST_ITEM(unit_labor) + 1]; static df::job_skill labor_to_skill[ENUM_LAST_ITEM(unit_labor) + 1];
@ -1477,12 +1503,12 @@ static void enable_plugin(color_ostream &out)
{ {
if (!config.isValid()) if (!config.isValid())
{ {
config = World::AddPersistentData("autolabor/2.0/config"); config = World::AddPersistentData("labormanager/2.0/config");
config.ival(0) = 0; config.ival(0) = 0;
} }
setOptionEnabled(CF_ENABLED, true); setOptionEnabled(CF_ENABLED, true);
enable_autolabor = true; enable_labormanager = true;
out << "Enabling the plugin." << endl; out << "Enabling the plugin." << endl;
cleanup_state(); cleanup_state();
@ -1497,32 +1523,32 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <Plug
// Fill the command list with your commands. // Fill the command list with your commands.
commands.push_back(PluginCommand( commands.push_back(PluginCommand(
"autolabor2", "Automatically manage dwarf labors.", "labormanager", "Automatically manage dwarf labors.",
autolabor, false, /* true means that the command can't be used from non-interactive user interface */ labormanager, false, /* true means that the command can't be used from non-interactive user interface */
// Extended help string. Used by CR_WRONG_USAGE and the help command: // Extended help string. Used by CR_WRONG_USAGE and the help command:
" autolabor2 enable\n" " labormanager enable\n"
" autolabor2 disable\n" " labormanager disable\n"
" Enables or disables the plugin.\n" " Enables or disables the plugin.\n"
" autolabor2 max <labor> <maximum>\n" " labormanager max <labor> <maximum>\n"
" Set max number of dwarves assigned to a labor.\n" " Set max number of dwarves assigned to a labor.\n"
" autolabor2 max <labor> none\n" " labormanager max <labor> none\n"
" Unrestrict the number of dwarves assigned to a labor.\n" " Unrestrict the number of dwarves assigned to a labor.\n"
" autolabor2 priority <labor> <priority>\n" " labormanager priority <labor> <priority>\n"
" Change the assignment priority of a labor (default is 100)\n" " Change the assignment priority of a labor (default is 100)\n"
" autolabor2 reset <labor>\n" " labormanager reset <labor>\n"
" Return a labor to the default handling.\n" " Return a labor to the default handling.\n"
" autolabor2 reset-all\n" " labormanager reset-all\n"
" Return all labors to the default handling.\n" " Return all labors to the default handling.\n"
" autolabor2 list\n" " labormanager list\n"
" List current status of all labors.\n" " List current status of all labors.\n"
" autolabor2 status\n" " labormanager status\n"
" Show basic status information.\n" " Show basic status information.\n"
"Function:\n" "Function:\n"
" When enabled, autolabor periodically checks your dwarves and enables or\n" " When enabled, labormanager periodically checks your dwarves and enables or\n"
" disables labors. Generally, each dwarf will be assigned exactly one labor.\n" " disables labors. Generally, each dwarf will be assigned exactly one labor.\n"
" Warning: autolabor will override any manual changes you make to labors\n" " Warning: labormanager will override any manual changes you make to labors\n"
" while it is enabled. Do not try to run both autolabor and autolabor2 at\n" " while it is enabled. Do not try to run both labormanager and labormanager at\n"
" the same time." " the same time.\n"
)); ));
generate_labor_to_skill_map(); generate_labor_to_skill_map();
@ -1594,14 +1620,21 @@ private:
int need_food_water; int need_food_water;
int priority_food;
std::map<df::unit_labor, int> labor_needed; std::map<df::unit_labor, int> labor_needed;
std::map<df::unit_labor, bool> labor_outside; std::map<df::unit_labor, bool> labor_outside;
std::vector<dwarf_info_t*> dwarf_info; std::vector<dwarf_info_t*> dwarf_info;
std::list<dwarf_info_t*> available_dwarfs; std::list<dwarf_info_t*> available_dwarfs;
std::list<dwarf_info_t*> busy_dwarfs;
private: private:
void scan_buildings() void scan_buildings()
{ {
has_butchers = false;
has_fishery = false;
trader_requested = false;
for (auto b = world->buildings.all.begin(); b != world->buildings.all.end(); b++) for (auto b = world->buildings.all.begin(); b != world->buildings.all.end(); b++)
{ {
df::building *build = *b; df::building *build = *b;
@ -1658,16 +1691,14 @@ private:
if (dig != df::enums::tile_dig_designation::No) if (dig != df::enums::tile_dig_designation::No)
{ {
df::tiletype tt = bl->tiletype[x][y]; df::tiletype tt = bl->tiletype[x][y];
df::tiletype_material ttm = ENUM_ATTR(tiletype, material, tt);
df::tiletype_shape tts = ENUM_ATTR(tiletype, shape, tt); df::tiletype_shape tts = ENUM_ATTR(tiletype, shape, tt);
switch (tts) if (ttm == df::enums::tiletype_material::TREE)
{ tree_count++;
case df::enums::tiletype_shape::TREE: else if (tts == df::enums::tiletype_shape::SHRUB)
tree_count++; break; plant_count++;
case df::enums::tiletype_shape::SHRUB: else
plant_count++; break; dig_count++;
default:
dig_count++; break;
}
} }
if (bl->designation[x][y].bits.smooth != 0) if (bl->designation[x][y].bits.smooth != 0)
detail_count++; detail_count++;
@ -1684,13 +1715,15 @@ private:
for (int e = TOOL_NONE; e < TOOLS_MAX; e++) for (int e = TOOL_NONE; e < TOOLS_MAX; e++)
tool_count[e] = 0; tool_count[e] = 0;
priority_food = 0;
df::item_flags bad_flags; df::item_flags bad_flags;
bad_flags.whole = 0; bad_flags.whole = 0;
#define F(x) bad_flags.bits.x = true; #define F(x) bad_flags.bits.x = true;
F(dump); F(forbid); F(garbage_collect); F(dump); F(forbid); F(garbage_collect);
F(hostile); F(on_fire); F(rotten); F(trader); F(hostile); F(on_fire); F(rotten); F(trader);
F(in_building); F(construction); F(artifact); F(in_building); F(construction);
#undef F #undef F
auto& v = world->items.all; auto& v = world->items.all;
@ -1704,6 +1737,11 @@ private:
if (item->flags.whole & bad_flags.whole) if (item->flags.whole & bad_flags.whole)
continue; continue;
df::item_type t = item->getType();
if (item->materialRots() && t != df::item_type::CORPSEPIECE && t != df::item_type::CORPSE && item->getRotTimer() > 1)
priority_food++;
if (!item->isWeapon()) if (!item->isWeapon())
continue; continue;
@ -1869,14 +1907,20 @@ private:
{ {
state = CHILD; state = CHILD;
} }
else if (ENUM_ATTR(profession, military, dwarf->dwarf->profession)) else if (ENUM_ATTR(profession, military, dwarf->dwarf->profession))
state = MILITARY; state = MILITARY;
else if (dwarf->dwarf->burrows.size() > 0)
state = OTHER; // dwarfs assigned to burrows are treated as if permanently busy
else if (dwarf->dwarf->job.current_job == NULL) else if (dwarf->dwarf->job.current_job == NULL)
{ {
if (is_on_break) if (is_on_break || dwarf->dwarf->flags1.bits.chained || dwarf->dwarf->flags1.bits.caged)
{
state = OTHER; state = OTHER;
else if (dwarf->dwarf->burrows.size() > 0) dwarf->clear_all = true;
state = OTHER; // dwarfs assigned to burrows are treated as if permanently busy }
else if (dwarf->dwarf->status2.limbs_grasp_count == 0) else if (dwarf->dwarf->status2.limbs_grasp_count == 0)
{ {
state = OTHER; // dwarfs unable to grasp are incapable of nearly all labors state = OTHER; // dwarfs unable to grasp are incapable of nearly all labors
@ -1902,18 +1946,23 @@ private:
if (state == BUSY) if (state == BUSY)
{ {
df::unit_labor labor = labor_mapper->find_job_labor(dwarf->dwarf->job.current_job); df::unit_labor labor = labor_mapper->find_job_labor(dwarf->dwarf->job.current_job);
dwarf->using_labor = labor;
if (labor != df::unit_labor::NONE) if (labor != df::unit_labor::NONE)
{ {
dwarf->using_labor = labor; labor_infos[labor].busy_dwarfs++;
if (!dwarf->dwarf->status.labors[labor] && print_debug) if (!dwarf->dwarf->status.labors[labor])
{ {
out.print("AUTOLABOR: dwarf %s (id %d) is doing job %s(%d) but is not enabled for labor %s(%d).\n", out.print("LABORMANAGER: dwarf %s (id %d) is doing job %s(%d) but is not enabled for labor %s(%d).\n",
dwarf->dwarf->name.first_name.c_str(), dwarf->dwarf->id, dwarf->dwarf->name.first_name.c_str(), dwarf->dwarf->id,
ENUM_KEY_STR(job_type, job).c_str(), job, ENUM_KEY_STR(unit_labor, labor).c_str(), labor); ENUM_KEY_STR(job_type, job).c_str(), job, ENUM_KEY_STR(unit_labor, labor).c_str(), labor);
} }
} }
} }
if (state == OTHER)
dwarf->clear_all = true;
} }
dwarf->state = state; dwarf->state = state;
@ -1925,8 +1974,6 @@ private:
if (dwarf->dwarf->status.labors[l]) if (dwarf->dwarf->status.labors[l])
if (state == IDLE) if (state == IDLE)
labor_infos[l].idle_dwarfs++; labor_infos[l].idle_dwarfs++;
else if (state == BUSY)
labor_infos[l].busy_dwarfs++;
} }
@ -2022,19 +2069,69 @@ private:
dwarf->clear_labor(labor); dwarf->clear_labor(labor);
} }
} } else {
else if (state == IDLE || state == BUSY) if (state == IDLE)
available_dwarfs.push_back(dwarf); available_dwarfs.push_back(dwarf);
if (state == BUSY)
busy_dwarfs.push_back(dwarf);
}
}
}
}
void release_dwarf_list()
{
while (!dwarf_info.empty()) {
auto d = dwarf_info.begin();
delete *d;
dwarf_info.erase(d);
}
available_dwarfs.clear();
busy_dwarfs.clear();
}
int score_labor (dwarf_info_t* d, df::unit_labor labor)
{
int skill_level = 0;
int xp = 0;
if (labor != df::unit_labor::NONE)
{
df::job_skill skill = labor_to_skill[labor];
if (skill != df::job_skill::NONE)
{
skill_level = Units::getEffectiveSkill(d->dwarf, skill);
xp = Units::getExperience(d->dwarf, skill, false);
} }
}
int score = skill_level * 1000 - (d->high_skill - skill_level) * 2000 + (xp / (skill_level + 5) * 10);
if (labor != df::unit_labor::NONE)
{
if (d->dwarf->status.labors[labor])
if (labor == df::unit_labor::OPERATE_PUMP)
score += 50000;
else
score += 1000;
if (default_labor_infos[labor].tool != TOOL_NONE &&
d->has_tool[default_labor_infos[labor].tool])
score += 5000;
if (d->has_children && labor_outside[labor])
score -= 15000;
if (d->armed && labor_outside[labor])
score += 5000;
} }
return score;
} }
public: public:
void process() void process()
{ {
dwarf_info.clear(); release_dwarf_list();
dig_count = tree_count = plant_count = detail_count = 0; dig_count = tree_count = plant_count = detail_count = 0;
cnt_recover_wounded = cnt_diagnosis = cnt_immobilize = cnt_dressing = cnt_cleaning = cnt_surgery = cnt_suture = cnt_recover_wounded = cnt_diagnosis = cnt_immobilize = cnt_dressing = cnt_cleaning = cnt_surgery = cnt_suture =
@ -2106,13 +2203,27 @@ public:
labor_needed[df::unit_labor::HAUL_FOOD] += world->stockpile.num_jobs[6]; 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_REFUSE] += world->stockpile.num_jobs[7];
labor_needed[df::unit_labor::HAUL_FURNITURE] += world->stockpile.num_jobs[8]; labor_needed[df::unit_labor::HAUL_FURNITURE] += world->stockpile.num_jobs[8];
labor_needed[df::unit_labor::HAUL_ANIMAL] += world->stockpile.num_jobs[9]; 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;
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;
// add entries for vehicle hauling // add entries for vehicle hauling
for (auto v = world->vehicles.all.begin(); v != world->vehicles.all.end(); v++) for (auto v = world->vehicles.all.begin(); v != world->vehicles.all.end(); v++)
if ((*v)->route_id != -1) if ((*v)->route_id != -1)
labor_needed[df::unit_labor::PUSH_HAUL_VEHICLE]++; labor_needed[df::unit_labor::HANDLE_VEHICLES]++;
// add fishing & hunting // add fishing & hunting
@ -2131,33 +2242,101 @@ public:
// note: this doesn't test to see if the trainer is actually needed, and thus will overallocate trainers. bleah. // note: this doesn't test to see if the trainer is actually needed, and thus will overallocate trainers. bleah.
} }
/* adjust for over/under */ /* move idle dwarfs ready to be assigned to busy list */
for (auto d = available_dwarfs.begin(); d != available_dwarfs.end(); )
{
bool busy = false;
FOR_ENUM_ITEMS(unit_labor, l) FOR_ENUM_ITEMS(unit_labor, l)
{ {
if (l == df::unit_labor::NONE) if (l == df::unit_labor::NONE)
continue; continue;
if (l >= df::unit_labor::HAUL_STONE && l <= df::unit_labor::HAUL_ANIMAL)
if (labor_needed[l] > 0 && (*d)->dwarf->status.labors[l])
{
busy = true;
labor_needed[l] = max(labor_needed[l]-1, 0);
}
}
if (busy)
{
busy_dwarfs.push_back(*d);
d = available_dwarfs.erase(d);
} else {
d++;
}
}
/* adjust for over/under */
FOR_ENUM_ITEMS(unit_labor, l)
{
if (l == df::unit_labor::NONE)
continue; continue;
if (labor_infos[l].idle_dwarfs > 0 && labor_needed[l] > labor_infos[l].busy_dwarfs) if (labor_infos[l].idle_dwarfs > 0)
labor_needed[l] = 0;
else
labor_needed[l] = std::max(labor_needed[l] - labor_infos[l].busy_dwarfs, 0);
}
/* assign food haulers for rotting food items */
if (priority_food > 0 && labor_infos[df::unit_labor::HAUL_FOOD].idle_dwarfs > 0)
priority_food = 1;
if (print_debug)
out.print ("priority food count = %d\n", priority_food);
while (!available_dwarfs.empty() && priority_food > 0)
{ {
int clawback = labor_infos[l].busy_dwarfs; std::list<dwarf_info_t*>::iterator bestdwarf = available_dwarfs.begin();
if (clawback == 0 && labor_needed[l] > 0)
clawback = 1; int best_score = INT_MIN;
for (std::list<dwarf_info_t*>::iterator k = available_dwarfs.begin(); k != available_dwarfs.end(); k++)
{
dwarf_info_t* d = (*k);
int score = score_labor(d, df::unit_labor::HAUL_FOOD);
if (score > best_score)
{
bestdwarf = k;
best_score = score;
}
}
if (best_score > INT_MIN)
{
if (print_debug) if (print_debug)
out.print("reducing labor %s to %d (%d needed, %d busy, %d idle)\n", ENUM_KEY_STR(unit_labor, l).c_str(), out.print("LABORMANAGER: assign \"%s\" labor %s score=%d (priority food)\n", (*bestdwarf)->dwarf->name.first_name.c_str(), ENUM_KEY_STR(unit_labor, df::unit_labor::HAUL_FOOD).c_str(), best_score);
clawback,
labor_needed[l], labor_infos[l].busy_dwarfs, labor_infos[l].idle_dwarfs); FOR_ENUM_ITEMS(unit_labor, l)
labor_needed[l] = clawback; {
if (l == df::unit_labor::NONE)
continue;
if (l == df::unit_labor::HAUL_FOOD)
(*bestdwarf)->set_labor(l);
else
(*bestdwarf)->clear_labor(l);
} }
available_dwarfs.erase(bestdwarf);
priority_food--;
}
else
break;
} }
if (print_debug) if (print_debug)
{ {
for (auto i = labor_needed.begin(); i != labor_needed.end(); i++) for (auto i = labor_needed.begin(); i != labor_needed.end(); i++)
{ {
out.print ("labor_needed [%s] = %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_outside[i->first], labor_infos[i->first].idle_dwarfs); labor_infos[i->first].busy_dwarfs, labor_outside[i->first], labor_infos[i->first].idle_dwarfs);
} }
} }
@ -2173,6 +2352,8 @@ public:
{ {
int priority = labor_infos[l].priority(); int priority = labor_infos[l].priority();
priority += labor_infos[l].time_since_last_assigned()/12; priority += labor_infos[l].time_since_last_assigned()/12;
for (int n = 0; n < labor_infos[l].busy_dwarfs; n++)
priority /= 2;
pq.push(make_pair(priority, l)); pq.push(make_pair(priority, l));
} }
} }
@ -2212,7 +2393,7 @@ public:
(1 << df::unit_labor::HAUL_REFUSE) | (1 << df::unit_labor::HAUL_REFUSE) |
(1 << df::unit_labor::HAUL_ITEM) | (1 << df::unit_labor::HAUL_ITEM) |
(1 << df::unit_labor::HAUL_FURNITURE) | (1 << df::unit_labor::HAUL_FURNITURE) |
(1 << df::unit_labor::HAUL_ANIMAL); (1 << df::unit_labor::HAUL_ANIMALS);
while (!available_dwarfs.empty()) while (!available_dwarfs.empty())
{ {
@ -2227,36 +2408,11 @@ public:
continue; continue;
df::unit_labor labor = j->first; df::unit_labor labor = j->first;
df::job_skill skill = labor_to_skill[labor];
for (std::list<dwarf_info_t*>::iterator k = available_dwarfs.begin(); k != available_dwarfs.end(); k++) for (std::list<dwarf_info_t*>::iterator k = available_dwarfs.begin(); k != available_dwarfs.end(); k++)
{ {
dwarf_info_t* d = (*k); dwarf_info_t* d = (*k);
int skill_level = 0; int score = score_labor(d, labor);
int xp = 0;
if (skill != df::job_skill::NONE)
{
skill_level = Units::getEffectiveSkill(d->dwarf, skill);
xp = Units::getExperience(d->dwarf, skill, false);
}
int score = skill_level * 1000 - (d->high_skill - skill_level) * 2000 + (xp / (skill_level + 5) * 10);
if (d->dwarf->status.labors[labor])
if (labor == df::unit_labor::OPERATE_PUMP)
score += 50000;
else
score += 1000;
if (default_labor_infos[labor].tool != TOOL_NONE &&
d->has_tool[default_labor_infos[labor].tool])
score += 5000;
if (d->has_children && labor_outside[labor])
score -= 15000;
if (d->armed && labor_outside[labor])
score += 5000;
if (d->state == BUSY)
if (d->using_labor == labor)
score += 7500;
else
score -= 7500;
if (score > best_score) if (score > best_score)
{ {
bestdwarf = k; bestdwarf = k;
@ -2289,11 +2445,15 @@ public:
(*bestdwarf)->clear_labor(l); (*bestdwarf)->clear_labor(l);
} }
if (best_labor >= df::unit_labor::HAUL_STONE && best_labor <= df::unit_labor::HAUL_ANIMAL) if (best_labor == df::unit_labor::HAUL_FOOD && priority_food > 0)
priority_food--;
if (best_labor >= df::unit_labor::HAUL_STONE && best_labor <= df::unit_labor::HAUL_ANIMALS)
canary &= ~(1 << best_labor); canary &= ~(1 << best_labor);
if (best_labor != df::unit_labor::NONE) if (best_labor != df::unit_labor::NONE)
{ {
busy_dwarfs.push_back(*bestdwarf);
labor_infos[best_labor].active_dwarfs++; labor_infos[best_labor].active_dwarfs++;
to_assign[best_labor]--; to_assign[best_labor]--;
} }
@ -2301,18 +2461,72 @@ public:
available_dwarfs.erase(bestdwarf); available_dwarfs.erase(bestdwarf);
} }
for (auto d = busy_dwarfs.begin(); d != busy_dwarfs.end(); d++)
{
int current_score = score_labor (*d, (*d)->using_labor);
FOR_ENUM_ITEMS (unit_labor, l)
{
if (l == df::unit_labor::NONE)
continue;
if (l == (*d)->using_labor)
continue;
if (labor_needed[l] <= 0)
continue;
int score = score_labor (*d, l);
score += labor_infos[l].time_since_last_assigned()/12;
if (l == df::unit_labor::HAUL_FOOD && priority_food > 0)
score += 1000000;
if (score > current_score)
{
tools_enum t = default_labor_infos[l].tool;
if (t == TOOL_NONE || (*d)->has_tool[t])
{
(*d)->set_labor (l);
if (print_debug)
out.print("assign \"%s\" extra labor %s score=%d current %s score=%d\n",
(*d)->dwarf->name.first_name.c_str(),
ENUM_KEY_STR(unit_labor, l).c_str(), score,
ENUM_KEY_STR(unit_labor, (*d)->using_labor).c_str(), current_score);
}
}
else
(*d)->clear_labor (l);
}
}
if (canary != 0) if (canary != 0)
{ {
dwarf_info_t* d = dwarf_info.front(); dwarf_info_t* d = 0;
for (auto di = busy_dwarfs.begin(); di != busy_dwarfs.end(); di++)
if (!(*di)->clear_all)
{
d = *di;
break;
}
if (d)
{
FOR_ENUM_ITEMS (unit_labor, l) FOR_ENUM_ITEMS (unit_labor, l)
{ {
if (l >= df::unit_labor::HAUL_STONE && l <= df::unit_labor::HAUL_ANIMAL && if (l >= df::unit_labor::HAUL_STONE && l <= df::unit_labor::HAUL_ANIMALS &&
canary & (1 << l)) canary & (1 << l))
d->set_labor(l); d->set_labor(l);
} }
if (print_debug) if (print_debug)
out.print ("Setting %s as the hauling canary\n", d->dwarf->name.first_name.c_str()); out.print ("Setting %s as the hauling canary\n", d->dwarf->name.first_name.c_str());
} }
else
{
if (print_debug)
out.print ("No dwarf available to set as the hauling canary!\n");
}
}
/* set reequip on any dwarfs who are carrying tools needed by others */ /* set reequip on any dwarfs who are carrying tools needed by others */
@ -2320,6 +2534,9 @@ public:
{ {
FOR_ENUM_ITEMS (unit_labor, l) FOR_ENUM_ITEMS (unit_labor, l)
{ {
if (l == df::unit_labor::NONE)
continue;
tools_enum t = default_labor_infos[l].tool; tools_enum t = default_labor_infos[l].tool;
if (t != TOOL_NONE && tool_count[t] < 0 && (*d)->has_tool[t] && !(*d)->dwarf->status.labors[l]) if (t != TOOL_NONE && tool_count[t] < 0 && (*d)->has_tool[t] && !(*d)->dwarf->status.labors[l])
{ {
@ -2329,6 +2546,8 @@ public:
} }
} }
release_dwarf_list();
*df::global::process_jobs = true; *df::global::process_jobs = true;
print_debug = 0; print_debug = 0;
@ -2359,7 +2578,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out )
{ {
static int step_count = 0; static int step_count = 0;
// check run conditions // check run conditions
if(!world || !world->map.block_index || !enable_autolabor) if(!initialized || !world || !world->map.block_index || !enable_labormanager)
{ {
// give up if we shouldn't be running' // give up if we shouldn't be running'
return CR_OK; return CR_OK;
@ -2406,26 +2625,26 @@ df::unit_labor lookup_labor_by_name (std::string& name)
DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable ) DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable )
{ {
if (!Core::getInstance().isWorldLoaded()) { if (!Core::getInstance().isWorldLoaded()) {
out.printerr("World is not loaded: please load a game first.\n"); out.printerr("World is not loaded: please load a fort first.\n");
return CR_FAILURE; return CR_FAILURE;
} }
if (enable && !enable_autolabor) if (enable && !enable_labormanager)
{ {
enable_plugin(out); enable_plugin(out);
} }
else if(!enable && enable_autolabor) else if(!enable && enable_labormanager)
{ {
enable_autolabor = false; enable_labormanager = false;
setOptionEnabled(CF_ENABLED, false); setOptionEnabled(CF_ENABLED, false);
out << "Autolabor is disabled." << endl; out << "LaborManager is disabled." << endl;
} }
return CR_OK; return CR_OK;
} }
command_result autolabor (color_ostream &out, std::vector <std::string> & parameters) command_result labormanager (color_ostream &out, std::vector <std::string> & parameters)
{ {
CoreSuspender suspend; CoreSuspender suspend;
@ -2443,7 +2662,7 @@ command_result autolabor (color_ostream &out, std::vector <std::string> & parame
else if (parameters.size() == 3 && else if (parameters.size() == 3 &&
(parameters[0] == "max" || parameters[0] == "priority")) (parameters[0] == "max" || parameters[0] == "priority"))
{ {
if (!enable_autolabor) if (!enable_labormanager)
{ {
out << "Error: The plugin is not enabled." << endl; out << "Error: The plugin is not enabled." << endl;
return CR_FAILURE; return CR_FAILURE;
@ -2474,7 +2693,7 @@ command_result autolabor (color_ostream &out, std::vector <std::string> & parame
} }
else if (parameters.size() == 2 && parameters[0] == "reset") else if (parameters.size() == 2 && parameters[0] == "reset")
{ {
if (!enable_autolabor) if (!enable_labormanager)
{ {
out << "Error: The plugin is not enabled." << endl; out << "Error: The plugin is not enabled." << endl;
return CR_FAILURE; return CR_FAILURE;
@ -2493,7 +2712,7 @@ command_result autolabor (color_ostream &out, std::vector <std::string> & parame
} }
else if (parameters.size() == 1 && (parameters[0] == "allow-fishing" || parameters[0] == "forbid-fishing")) else if (parameters.size() == 1 && (parameters[0] == "allow-fishing" || parameters[0] == "forbid-fishing"))
{ {
if (!enable_autolabor) if (!enable_labormanager)
{ {
out << "Error: The plugin is not enabled." << endl; out << "Error: The plugin is not enabled." << endl;
return CR_FAILURE; return CR_FAILURE;
@ -2504,7 +2723,7 @@ command_result autolabor (color_ostream &out, std::vector <std::string> & parame
} }
else if (parameters.size() == 1 && (parameters[0] == "allow-hunting" || parameters[0] == "forbid-hunting")) else if (parameters.size() == 1 && (parameters[0] == "allow-hunting" || parameters[0] == "forbid-hunting"))
{ {
if (!enable_autolabor) if (!enable_labormanager)
{ {
out << "Error: The plugin is not enabled." << endl; out << "Error: The plugin is not enabled." << endl;
return CR_FAILURE; return CR_FAILURE;
@ -2515,7 +2734,7 @@ command_result autolabor (color_ostream &out, std::vector <std::string> & parame
} }
else if (parameters.size() == 1 && parameters[0] == "reset-all") else if (parameters.size() == 1 && parameters[0] == "reset-all")
{ {
if (!enable_autolabor) if (!enable_labormanager)
{ {
out << "Error: The plugin is not enabled." << endl; out << "Error: The plugin is not enabled." << endl;
return CR_FAILURE; return CR_FAILURE;
@ -2530,7 +2749,7 @@ command_result autolabor (color_ostream &out, std::vector <std::string> & parame
} }
else if (parameters.size() == 1 && parameters[0] == "list" || parameters[0] == "status") else if (parameters.size() == 1 && parameters[0] == "list" || parameters[0] == "status")
{ {
if (!enable_autolabor) if (!enable_labormanager)
{ {
out << "Error: The plugin is not enabled." << endl; out << "Error: The plugin is not enabled." << endl;
return CR_FAILURE; return CR_FAILURE;
@ -2563,7 +2782,7 @@ command_result autolabor (color_ostream &out, std::vector <std::string> & parame
} }
else if (parameters.size() == 1 && parameters[0] == "debug") else if (parameters.size() == 1 && parameters[0] == "debug")
{ {
if (!enable_autolabor) if (!enable_labormanager)
{ {
out << "Error: The plugin is not enabled." << endl; out << "Error: The plugin is not enabled." << endl;
return CR_FAILURE; return CR_FAILURE;
@ -2576,8 +2795,8 @@ command_result autolabor (color_ostream &out, std::vector <std::string> & parame
else else
{ {
out.print("Automatically assigns labors to dwarves.\n" out.print("Automatically assigns labors to dwarves.\n"
"Activate with 'autolabor enable', deactivate with 'autolabor disable'.\n" "Activate with 'labormanager enable', deactivate with 'labormanager disable'.\n"
"Current state: %s.\n", enable_autolabor ? "enabled" : "disabled"); "Current state: %s.\n", enable_labormanager ? "enabled" : "disabled");
return CR_OK; return CR_OK;
} }