From 99490aff418c6afd20ef382e579b08ae61998f1b Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Mon, 30 Jul 2018 21:32:15 -0500 Subject: [PATCH 1/3] add support for craft item from pearl jobs (fixes #1162) --- plugins/labormanager/joblabormapper.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/labormanager/joblabormapper.cpp b/plugins/labormanager/joblabormapper.cpp index 2328e14ef..b1af48b4d 100644 --- a/plugins/labormanager/joblabormapper.cpp +++ b/plugins/labormanager/joblabormapper.cpp @@ -516,7 +516,8 @@ public: if (j->material_category.bits.bone || j->material_category.bits.horn || j->material_category.bits.tooth || - j->material_category.bits.shell) + j->material_category.bits.shell || + j->material_category.bits.pearl) return df::unit_labor::BONE_CARVE; else { From a6067c20c1ada4b1297801a9bf6888ba810f2757 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Mon, 30 Jul 2018 22:36:59 -0500 Subject: [PATCH 2/3] (labormanager) only assign valid labors (fix #1142) Add a number of tests to ensure that only assignable labors are assigned to units, and that only units that are eligible to be assigned labors are considered at all. I borrowed logic from Dwarf Manipulator to identify units eligible to be assigned labors. This should prevent pets., ghosts, visitors, or any other noneligible entities from being assigned labors by labormanager, and should thus fix #1142. --- plugins/labormanager/labormanager.cpp | 82 +++++++++++++++++++-------- 1 file changed, 57 insertions(+), 25 deletions(-) diff --git a/plugins/labormanager/labormanager.cpp b/plugins/labormanager/labormanager.cpp index 9f874edc0..3ff8c0862 100644 --- a/plugins/labormanager/labormanager.cpp +++ b/plugins/labormanager/labormanager.cpp @@ -945,6 +945,15 @@ private: { if (labor >= 0 && labor <= ENUM_LAST_ITEM(unit_labor)) { + if (!Units::isValidLabor(dwarf->dwarf, labor)) + { + debug("WARN(labormanager): Attempted to %s dwarf %s with ineligible labor %s\n", + value ? "set" : "unset", + dwarf->dwarf->name.first_name.c_str(), + ENUM_KEY_STR(unit_labor, labor).c_str()); + return; + } + bool old = dwarf->dwarf->status.labors[labor]; dwarf->dwarf->status.labors[labor] = value; if (old != value) @@ -1182,7 +1191,17 @@ private: { df::unit* cre = *u; - if (Units::isCitizen(cre)) + // following tests shamelessly stolen from Dwarf Manipulator plugin + + bool isAssignable = + (Units::isOwnCiv(cre)) && + (Units::isOwnGroup(cre)) && + (Units::isActive(cre)) && + (!cre->flags2.bits.visitor) && + (!cre->flags3.bits.ghostly) && + (ENUM_ATTR(profession, can_assign_labor, cre->profession)); + + if (isAssignable) { dwarf_info_t* dwarf = add_dwarf(cre); @@ -1438,8 +1457,8 @@ private: { if (labor == unit_labor::NONE) continue; - - set_labor(dwarf, labor, false); + if (Units::isValidLabor(dwarf->dwarf, labor)) + set_labor(dwarf, labor, false); } } else { @@ -1690,12 +1709,15 @@ public: { dwarf_info_t* d = (*k); - int score = score_labor(d, df::unit_labor::HAUL_FOOD); - - if (score > best_score) + if (Units::isValidLabor(d->dwarf, df::unit_labor::HAUL_FOOD)) { - bestdwarf = k; - best_score = score; + int score = score_labor(d, df::unit_labor::HAUL_FOOD); + + if (score > best_score) + { + bestdwarf = k; + best_score = score; + } } } @@ -1708,8 +1730,8 @@ public: { if (l == df::unit_labor::NONE) continue; - - set_labor(*bestdwarf, l, l == df::unit_labor::HAUL_FOOD); + if (Units::isValidLabor((*bestdwarf)->dwarf, l)) + set_labor(*bestdwarf, l, l == df::unit_labor::HAUL_FOOD); } available_dwarfs.erase(bestdwarf); @@ -1822,12 +1844,15 @@ public: for (std::list::iterator k = available_dwarfs.begin(); k != available_dwarfs.end(); k++) { dwarf_info_t* d = (*k); - int score = score_labor(d, labor); - if (score > best_score) + if (Units::isValidLabor(d->dwarf, labor)) { - bestdwarf = k; - best_score = score; - best_labor = labor; + int score = score_labor(d, labor); + if (score > best_score) + { + bestdwarf = k; + best_score = score; + best_labor = labor; + } } } } @@ -1845,7 +1870,9 @@ 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 && + Units::isValidLabor((*bestdwarf)->dwarf, l) && + (t == TOOL_NONE || tool_in_use[t] < tool_count[t])) { set_labor(*bestdwarf, l, true); if (t != TOOL_NONE && !((*bestdwarf)->has_tool[t])) @@ -1865,7 +1892,8 @@ public: } else if ((*bestdwarf)->state == IDLE) { - set_labor(*bestdwarf, l, false); + if (Units::isValidLabor((*bestdwarf)->dwarf, l)) + set_labor(*bestdwarf, l, false); } } @@ -1897,6 +1925,8 @@ public: continue; if (labor_needed[l] <= 0) continue; + if (!Units::isValidLabor((*d)->dwarf, l)) + continue; int score = score_labor(*d, l); @@ -1934,7 +1964,8 @@ public: FOR_ENUM_ITEMS(unit_labor, l) { if (l >= df::unit_labor::HAUL_STONE && l <= df::unit_labor::HAUL_ANIMALS && - canary & (1 << l)) + canary & (1 << l) && + Units::isValidLabor(canary_dwarf->dwarf, l)) set_labor(canary_dwarf, l, true); } @@ -1967,13 +1998,14 @@ public: if (l == df::unit_labor::NONE) continue; - set_labor(*d, l, - (l >= df::unit_labor::HAUL_STONE && l <= df::unit_labor::HAUL_ANIMALS) || - l == df::unit_labor::CLEAN || - l == df::unit_labor::HAUL_WATER || - l == df::unit_labor::REMOVE_CONSTRUCTION || - l == df::unit_labor::PULL_LEVER || - l == df::unit_labor::HAUL_TRADE); + if (Units::isValidLabor((*d)->dwarf, l)) + set_labor(*d, l, + (l >= df::unit_labor::HAUL_STONE && l <= df::unit_labor::HAUL_ANIMALS) || + l == df::unit_labor::CLEAN || + l == df::unit_labor::HAUL_WATER || + l == df::unit_labor::REMOVE_CONSTRUCTION || + l == df::unit_labor::PULL_LEVER || + l == df::unit_labor::HAUL_TRADE); } } From 214b0c4bc651b5923d0d3fe70cce5029c68ea15c Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Tue, 31 Jul 2018 19:12:07 -0500 Subject: [PATCH 3/3] (labormanager) respect NATURE value Units with values regarding NATURE will be preferenced or dispreferenced for jobs which might give them a good/bad feeling because of that value --- plugins/labormanager/labormanager.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/plugins/labormanager/labormanager.cpp b/plugins/labormanager/labormanager.cpp index 9f874edc0..262f7930f 100644 --- a/plugins/labormanager/labormanager.cpp +++ b/plugins/labormanager/labormanager.cpp @@ -70,6 +70,7 @@ #include #include #include +#include #include "labormanager.h" #include "joblabormapper.h" @@ -1518,6 +1519,26 @@ private: else if (altruism <= 24) score -= 50000; } + + // Favor/disfavor BUTCHER (covers slaughtering), HAUL_ANIMALS (covers caging), and CUTWOOD based on NATURE value + + if (labor == df::unit_labor::BUTCHER || labor == df::unit_labor::HAUL_ANIMALS || labor == df::unit_labor::CUTWOOD) + { + int nature = 0; + for (auto i = d->dwarf->status.current_soul->personality.values.begin(); + i != d->dwarf->status.current_soul->personality.values.end(); + i++) + { + if ((*i)->type == df::value_type::NATURE) + nature = (*i)->strength; + } + + if (nature <= -11) + score += 5000; + else if (nature >= 26) + score -= 50000; + } + // This should reweight assigning CUTWOOD jobs based on a citizen's ethic toward killing plants if (labor == df::unit_labor::CUTWOOD)