|
|
@ -61,7 +61,25 @@ namespace DFHack {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static const string CONFIG_KEY = string(plugin_name) + "/config";
|
|
|
|
static const string CONFIG_KEY = string(plugin_name) + "/config";
|
|
|
|
|
|
|
|
enum ConfigValues {
|
|
|
|
|
|
|
|
CONFIG_IS_ENABLED = 0,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//static int get_config_val(PersistentDataItem& c, int index) {
|
|
|
|
|
|
|
|
// if (!c.isValid())
|
|
|
|
|
|
|
|
// return -1;
|
|
|
|
|
|
|
|
// return c.ival(index);
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
//static bool get_config_bool(PersistentDataItem& c, int index) {
|
|
|
|
|
|
|
|
// return get_config_val(c, index) == 1;
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
static void set_config_val(PersistentDataItem& c, int index, int value) {
|
|
|
|
|
|
|
|
if (c.isValid())
|
|
|
|
|
|
|
|
c.ival(index) = value;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void set_config_bool(PersistentDataItem& c, int index, bool value) {
|
|
|
|
|
|
|
|
set_config_val(c, index, value ? 1 : 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
@ -250,6 +268,29 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DFhackCExport command_result plugin_enable(color_ostream& out, bool enable) {
|
|
|
|
|
|
|
|
if (!Core::getInstance().isWorldLoaded()) {
|
|
|
|
|
|
|
|
out.printerr("Cannot enable %s without a loaded world.\n", plugin_name);
|
|
|
|
|
|
|
|
return CR_FAILURE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (enable != autoclothing_enabled) {
|
|
|
|
|
|
|
|
auto enabled = World::GetPersistentData("autoclothing/enabled");
|
|
|
|
|
|
|
|
autoclothing_enabled = enable;
|
|
|
|
|
|
|
|
DEBUG(report, out).print("%s from the API; persisting\n",
|
|
|
|
|
|
|
|
autoclothing_enabled ? "enabled" : "disabled");
|
|
|
|
|
|
|
|
set_config_bool(enabled, CONFIG_IS_ENABLED, autoclothing_enabled);
|
|
|
|
|
|
|
|
if (enable)
|
|
|
|
|
|
|
|
do_autoclothing();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
DEBUG(report, out).print("%s from the API, but already %s; no action\n",
|
|
|
|
|
|
|
|
autoclothing_enabled ? "enabled" : "disabled",
|
|
|
|
|
|
|
|
autoclothing_enabled ? "enabled" : "disabled");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return CR_OK;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Whatever you put here will be done in each game step. Don't abuse it.
|
|
|
|
// Whatever you put here will be done in each game step. Don't abuse it.
|
|
|
|
// It's optional, so you can just comment it out like this if you don't need it.
|
|
|
|
// It's optional, so you can just comment it out like this if you don't need it.
|
|
|
|
|
|
|
|
|
|
|
@ -389,6 +430,7 @@ command_result autoclothing(color_ostream &out, vector <string> & parameters)
|
|
|
|
if (parameters.size() == 0)
|
|
|
|
if (parameters.size() == 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
CoreSuspender suspend;
|
|
|
|
CoreSuspender suspend;
|
|
|
|
|
|
|
|
out << "Automatic clothing management is currently " << (autoclothing_enabled ? "enabled" : "disabled") << "." << endl;
|
|
|
|
out << "Currently set " << clothingOrders.size() << " automatic clothing orders" << endl;
|
|
|
|
out << "Currently set " << clothingOrders.size() << " automatic clothing orders" << endl;
|
|
|
|
for (size_t i = 0; i < clothingOrders.size(); i++)
|
|
|
|
for (size_t i = 0; i < clothingOrders.size(); i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -523,7 +565,7 @@ static void find_needed_clothing_items()
|
|
|
|
|
|
|
|
|
|
|
|
if (!item)
|
|
|
|
if (!item)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
WARN(cycle).print("Invalid inventory item ID: %d\n", ownedItem);
|
|
|
|
WARN(cycle).print("autoclothing: Invalid inventory item ID: %d\n", ownedItem);
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -728,34 +770,28 @@ static void list_unit_counts(color_ostream& out, map<int, int>& unitList)
|
|
|
|
|
|
|
|
|
|
|
|
static bool isAvailableItem(df::item* item)
|
|
|
|
static bool isAvailableItem(df::item* item)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (item->flags.bits.in_job)
|
|
|
|
static struct BadFlags {
|
|
|
|
return false;
|
|
|
|
uint32_t whole;
|
|
|
|
if (item->flags.bits.hostile)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
BadFlags() {
|
|
|
|
if (item->flags.bits.in_building)
|
|
|
|
df::item_flags flags;
|
|
|
|
return false;
|
|
|
|
#define F(x) flags.bits.x = true;
|
|
|
|
if (item->flags.bits.in_building)
|
|
|
|
F(in_job); F(hostile); F(in_building); F(encased);
|
|
|
|
return false;
|
|
|
|
F(foreign); F(trader); F(owned); F(forbid);
|
|
|
|
if (item->flags.bits.encased)
|
|
|
|
F(dump); F(on_fire); F(melt); F(hidden);
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (item->flags.bits.foreign)
|
|
|
|
F(garbage_collect); F(rotten); F(construction);
|
|
|
|
return false;
|
|
|
|
F(in_chest); F(removed); F(spider_web);
|
|
|
|
if (item->flags.bits.trader)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
// F(artifact); -- TODO: should this be included?
|
|
|
|
if (item->flags.bits.owned)
|
|
|
|
#undef F
|
|
|
|
return false;
|
|
|
|
whole = flags.whole;
|
|
|
|
if (item->flags.bits.artifact)
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
} badFlags;
|
|
|
|
if (item->flags.bits.forbid)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
if ((item->flags.whole & badFlags.whole) != 0)
|
|
|
|
if (item->flags.bits.dump)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (item->flags.bits.on_fire)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (item->flags.bits.melt)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (item->flags.bits.hidden)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
if (item->getWear() > 1)
|
|
|
|
if (item->getWear() > 1)
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
if (!item->isClothing())
|
|
|
|
if (!item->isClothing())
|
|
|
@ -782,7 +818,7 @@ static void generate_report(color_ostream& out)
|
|
|
|
auto item = Items::findItemByID(itemId);
|
|
|
|
auto item = Items::findItemByID(itemId);
|
|
|
|
if (!item)
|
|
|
|
if (!item)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
WARN(cycle,out).print("Invalid inventory item ID: %d\n", itemId);
|
|
|
|
WARN(cycle,out).print("autoclothing: Invalid inventory item ID: %d\n", itemId);
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (item->getWear() >= 1)
|
|
|
|
if (item->getWear() >= 1)
|
|
|
@ -915,3 +951,23 @@ static void generate_report(color_ostream& out)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// Lua API
|
|
|
|
|
|
|
|
// TODO: implement Lua hooks to manipulate the persistent order configuration
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void autoclothing_doCycle(color_ostream& out) {
|
|
|
|
|
|
|
|
DEBUG(report, out).print("entering autoclothing_doCycle\n");
|
|
|
|
|
|
|
|
do_autoclothing();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DFHACK_PLUGIN_LUA_FUNCTIONS{
|
|
|
|
|
|
|
|
DFHACK_LUA_FUNCTION(autoclothing_doCycle),
|
|
|
|
|
|
|
|
DFHACK_LUA_END
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DFHACK_PLUGIN_LUA_COMMANDS{
|
|
|
|
|
|
|
|
DFHACK_LUA_END
|
|
|
|
|
|
|
|
};
|
|
|
|