Add 'allow fishing' and 'allow hunting' config options. Protect against accidentially trying to set or unset the NONE labor or any other invalid labor value (which corrupts DF). Add traction benches. Change prioritization around quite a bit.

develop
Kelly Martin 2012-12-04 20:23:19 -06:00
parent 0f1aaa6ec4
commit f8d6b83088
1 changed files with 114 additions and 48 deletions

@ -82,6 +82,8 @@ static PersistentDataItem config;
enum ConfigFlags {
CF_ENABLED = 1,
CF_ALLOW_FISHING = 2,
CF_ALLOW_HUNTING = 4,
};
@ -482,6 +484,8 @@ struct dwarf_info_t
}
void set_labor(df::unit_labor labor)
{
if (labor >= 0 && labor <= ENUM_LAST_ITEM(unit_labor))
{
dwarf->status.labors[labor] = true;
if ((labor == df::unit_labor::MINE && !has_pick) ||
@ -489,8 +493,11 @@ struct dwarf_info_t
(labor == df::unit_labor::HUNT && !has_crossbow))
dwarf->military.pickup_flags.bits.update = 1;
}
}
void clear_labor(df::unit_labor labor)
{
if (labor >= 0 && labor <= ENUM_LAST_ITEM(unit_labor))
{
dwarf->status.labors[labor] = false;
if ((labor == df::unit_labor::MINE && has_pick) ||
@ -498,6 +505,7 @@ struct dwarf_info_t
(labor == df::unit_labor::HUNT && has_crossbow))
dwarf->military.pickup_flags.bits.update = 1;
}
}
};
@ -752,6 +760,7 @@ private:
case df::building_type::WindowGem:
case df::building_type::Cage:
case df::building_type::NestBox:
case df::building_type::TractionBench:
return df::unit_labor::HAUL_FURNITURE;
case df::building_type::Trap:
return df::unit_labor::MECHANIC;
@ -1736,7 +1745,7 @@ private:
FOR_ENUM_ITEMS (job_skill, skill)
{
int skill_level = Units::getEffectiveSkill(dwarf->dwarf, skill);
int skill_level = Units::getNominalSkill(dwarf->dwarf, skill, false);
high_skill = std::max(high_skill, skill_level);
}
@ -1866,6 +1875,14 @@ public:
if ((*v)->route_id != -1)
labor_needed[df::unit_labor::PUSH_HAUL_VEHICLE]++;
// add fishing & hunting
if (isOptionEnabled(CF_ALLOW_FISHING) && has_fishery)
labor_needed[df::unit_labor::FISH] ++;
if (isOptionEnabled(CF_ALLOW_HUNTING) && has_butchers)
labor_needed[df::unit_labor::HUNT] ++;
if (print_debug)
{
for (auto i = labor_needed.begin(); i != labor_needed.end(); i++)
@ -1893,6 +1910,31 @@ public:
if (print_debug)
out.print("available count = %d, distinct labors needed = %d\n", available_dwarfs.size(), pq.size());
std::map<df::unit_labor, int> to_assign;
to_assign.clear();
int av = available_dwarfs.size();
while (!pq.empty() && av > 0)
{
df::unit_labor labor = pq.top().second;
int priority = pq.top().first;
to_assign[labor]++;
pq.pop();
av--;
if (print_debug)
out.print("Will assign: %s priority %d (%d)\n", ENUM_KEY_STR(unit_labor, labor).c_str(), priority, to_assign[labor]);
if (--labor_needed[labor] > 0)
{
priority /= 2;
pq.push(make_pair(priority, labor));
}
}
int canary = (1 << df::unit_labor::HAUL_STONE) |
(1 << df::unit_labor::HAUL_WOOD) |
(1 << df::unit_labor::HAUL_BODY) |
@ -1902,18 +1944,20 @@ public:
(1 << df::unit_labor::HAUL_FURNITURE) |
(1 << df::unit_labor::HAUL_ANIMAL);
while (!available_dwarfs.empty() && !pq.empty())
while (!available_dwarfs.empty())
{
df::unit_labor labor = pq.top().second;
int priority = pq.top().first;
df::job_skill skill = labor_to_skill[labor];
if (print_debug)
out.print("labor %s skill %s priority %d\n", ENUM_KEY_STR(unit_labor, labor).c_str(), ENUM_KEY_STR(job_skill, skill).c_str(), priority);
std::list<dwarf_info_t*>::iterator bestdwarf = available_dwarfs.begin();
int best_score = -10000;
df::unit_labor best_labor = df::unit_labor::NONE;
for (auto j = to_assign.begin(); j != to_assign.end(); j++)
{
if (j->second <= 0)
continue;
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++)
{
@ -1921,44 +1965,44 @@ public:
int skill_level = 0;
if (skill != df::job_skill::NONE)
{
int skill_level = Units::getEffectiveSkill(d->dwarf, skill);
skill_level = Units::getEffectiveSkill(d->dwarf, skill);
}
int score = skill_level * 100 - (d->high_skill - skill_level) * 200;
int score = skill_level * 100 - (d->high_skill - skill_level) * 500;
if (d->dwarf->status.labors[labor])
score += 500;
if ((labor == df::unit_labor::MINE && d->has_pick) ||
(labor == df::unit_labor::CUTWOOD && d->has_axe) ||
(labor == df::unit_labor::HUNT && d->has_crossbow))
score += 500;
if (score > best_score)
{
bestdwarf = k;
best_score = score;
best_labor = labor;
}
}
}
if (print_debug)
out.print("assign \"%s\" labor %s score=%d\n", (*bestdwarf)->dwarf->name.first_name.c_str(), ENUM_KEY_STR(unit_labor, labor).c_str(), best_score);
out.print("assign \"%s\" labor %s score=%d\n", (*bestdwarf)->dwarf->name.first_name.c_str(), ENUM_KEY_STR(unit_labor, best_labor).c_str(), best_score);
FOR_ENUM_ITEMS(unit_labor, l)
{
if (l == labor)
if (l == df::unit_labor::NONE)
continue;
if (l == best_labor)
(*bestdwarf)->set_labor(l);
else
(*bestdwarf)->clear_labor(l);
}
if (labor >= df::unit_labor::HAUL_STONE && labor <= df::unit_labor::HAUL_ANIMAL)
canary &= ~(1 << labor);
labor_infos[labor].active_dwarfs++;
if (best_labor >= df::unit_labor::HAUL_STONE && best_labor <= df::unit_labor::HAUL_ANIMAL)
canary &= ~(1 << best_labor);
labor_infos[best_labor].active_dwarfs++;
to_assign[best_labor]--;
available_dwarfs.erase(bestdwarf);
pq.pop();
if (--labor_needed[labor] > 0)
{
priority /= 2;
pq.push(make_pair(priority, labor));
}
}
if (canary != 0)
@ -2125,6 +2169,28 @@ command_result autolabor (color_ostream &out, std::vector <std::string> & parame
print_labor(labor, out);
return CR_OK;
}
else if (parameters.size() == 1 && (parameters[0] == "allow-fishing" || parameters[0] == "forbid-fishing"))
{
if (!enable_autolabor)
{
out << "Error: The plugin is not enabled." << endl;
return CR_FAILURE;
}
setOptionEnabled(CF_ALLOW_FISHING, (parameters[0] == "allow-fishing"));
return CR_OK;
}
else if (parameters.size() == 1 && (parameters[0] == "allow-hunting" || parameters[0] == "forbid-hunting"))
{
if (!enable_autolabor)
{
out << "Error: The plugin is not enabled." << endl;
return CR_FAILURE;
}
setOptionEnabled(CF_ALLOW_HUNTING, (parameters[0] == "allow-hunting"));
return CR_OK;
}
else if (parameters.size() == 1 && parameters[0] == "reset-all")
{
if (!enable_autolabor)