fix autofarm berry problem

Update autofarm to count PLANT_GROWTHS as well as PLANTS for threshold purposes. This addresses #1902.

Also addresses some pointer hygiene issues in autofarm.
develop
Kelly Kinkade 2021-08-07 15:32:43 -05:00
parent 8b14fbe544
commit ce50bbdfde
1 changed files with 42 additions and 19 deletions

@ -12,6 +12,8 @@
#include "df/global_objects.h"
#include "df/item.h"
#include "df/item_plantst.h"
#include "df/item_plant_growthst.h"
#include "df/item_seedsst.h"
#include "df/items_other_id.h"
#include "df/unit.h"
#include "df/building.h"
@ -179,18 +181,18 @@ public:
for (auto ii : world->items.other[df::items_other_id::SEEDS])
{
df::item_plantst* i = (df::item_plantst*)ii;
if ((i->flags.whole & bad_flags.whole) == 0)
auto i = virtual_cast<df::item_seedsst>(ii);
if (i && (i->flags.whole & bad_flags.whole) == 0)
counts[i->mat_index] += i->stack_size;
}
for (auto ci : counts)
for (auto &ci : counts)
{
if (df::global::ui->tasks.discovered_plants[ci.first])
{
df::plant_raw* plant = world->raws.plants.all[ci.first];
if (is_plantable(plant))
for (auto flagmap : biomeFlagMap)
for (auto &flagmap : biomeFlagMap)
if (plant->flags.is_set(flagmap.first))
plantable_plants[plant->index].insert(flagmap.second);
}
@ -291,20 +293,35 @@ public:
F(in_building); F(construction); F(artifact);
#undef F
// have to scan both items[PLANT] and items[PLANT_GROWTH] because agricultural products can be either
for (auto ii : world->items.other[df::items_other_id::PLANT])
{
df::item_plantst* i = (df::item_plantst*)ii;
if ((i->flags.whole & bad_flags.whole) == 0 &&
auto i = virtual_cast<df::item_plantst>(ii);
if (i &&
(i->flags.whole & bad_flags.whole) == 0 &&
plantable_plants.count(i->mat_index) > 0)
{
lastCounts[i->mat_index] += i->stack_size;
}
}
for (auto ii : world->items.other[df::items_other_id::PLANT_GROWTH])
{
auto i = virtual_cast<df::item_plant_growthst>(ii);
if (i &&
(i->flags.whole & bad_flags.whole) == 0 &&
plantable_plants.count(i->mat_index) > 0)
{
lastCounts[i->mat_index] += i->stack_size;
}
}
map<df::biome_type, set<int>> plants;
plants.clear();
for (auto plantable : plantable_plants)
for (auto &plantable : plantable_plants)
{
df::plant_raw* plant = world->raws.plants.all[plantable.first];
if (lastCounts[plant->index] < getThreshold(plant->index))
@ -319,7 +336,7 @@ public:
for (auto bb : world->buildings.other[df::buildings_other_id::FARM_PLOT])
{
df::building_farmplotst* farm = (df::building_farmplotst*) bb;
auto farm = virtual_cast<df::building_farmplotst>(bb);
if (farm->flags.bits.exists)
{
df::biome_type biome;
@ -333,7 +350,7 @@ public:
}
}
for (auto ff : farms)
for (auto &ff : farms)
{
set_farms(out, plants[ff.first], ff.second);
}
@ -342,13 +359,13 @@ public:
void status(color_ostream& out)
{
out << (enabled ? "Running." : "Stopped.") << endl;
for (auto lc : lastCounts)
for (auto &lc : lastCounts)
{
auto plant = world->raws.plants.all[lc.first];
out << plant->id << " limit " << getThreshold(lc.first) << " current " << lc.second << endl;
}
for (auto th : thresholds)
for (auto &th : thresholds)
{
if (lastCounts[th.first] > 0)
continue;
@ -359,7 +376,7 @@ public:
}
};
static AutoFarm* autofarmInstance;
static std::unique_ptr<AutoFarm> autofarmInstance;
DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands)
@ -371,13 +388,13 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
)
);
}
autofarmInstance = new AutoFarm();
autofarmInstance = std::move(std::make_unique<AutoFarm>());
return CR_OK;
}
DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{
delete autofarmInstance;
autofarmInstance.release();
return CR_OK;
}
@ -442,15 +459,21 @@ static command_result autofarm(color_ostream &out, vector <string> & parameters)
CoreSuspender suspend;
if (parameters.size() == 1 && parameters[0] == "runonce")
autofarmInstance->process(out);
{
if (autofarmInstance) autofarmInstance->process(out);
}
else if (parameters.size() == 1 && parameters[0] == "enable")
plugin_enable(out, true);
else if (parameters.size() == 1 && parameters[0] == "disable")
plugin_enable(out, false);
else if (parameters.size() == 2 && parameters[0] == "default")
autofarmInstance->setDefault(atoi(parameters[1].c_str()));
{
if (autofarmInstance) autofarmInstance->setDefault(atoi(parameters[1].c_str()));
}
else if (parameters.size() >= 3 && parameters[0] == "threshold")
return setThresholds(out, parameters);
{
if (autofarmInstance) return setThresholds(out, parameters);
}
else if (parameters.size() == 0 || (parameters.size() == 1 && parameters[0] == "status"))
autofarmInstance->status(out);
else