Changed the serialization to use the actual enum item names instead of converting them to numbers.

develop
JapaMala 2019-08-13 17:15:06 -05:00
parent 47b43e6dd7
commit a07b568597
1 changed files with 57 additions and 28 deletions

@ -60,8 +60,8 @@ std::vector<ClothingRequirement>clothingOrders;
struct ClothingRequirement struct ClothingRequirement
{ {
df::job_type job_type; df::job_type jobType;
df::item_type item_type; df::item_type itemType;
int16_t item_subtype; int16_t item_subtype;
df::job_material_category material_category; df::job_material_category material_category;
int16_t needed_per_citizen; int16_t needed_per_citizen;
@ -69,9 +69,9 @@ struct ClothingRequirement
bool matches(ClothingRequirement * b) bool matches(ClothingRequirement * b)
{ {
if (b->job_type != this->job_type) if (b->jobType != this->jobType)
return false; return false;
if (b->item_type != this->item_type) if (b->itemType != this->itemType)
return false; return false;
if (b->item_subtype != this->item_subtype) if (b->item_subtype != this->item_subtype)
return false; return false;
@ -83,8 +83,8 @@ struct ClothingRequirement
std::string Serialize() std::string Serialize()
{ {
stringstream stream; stringstream stream;
stream << job_type << " "; stream << ENUM_KEY_STR(job_type, jobType) << " ";
stream << item_type << " "; stream << ENUM_KEY_STR(item_type,itemType) << " ";
stream << item_subtype << " "; stream << item_subtype << " ";
stream << material_category.whole << " "; stream << material_category.whole << " ";
stream << needed_per_citizen; stream << needed_per_citizen;
@ -94,8 +94,26 @@ struct ClothingRequirement
void Deserialize(std::string s) void Deserialize(std::string s)
{ {
stringstream stream(s); stringstream stream(s);
stream >> (int16_t&)job_type; std::string loadedJob;
stream >> (int16_t&)item_type; stream >> loadedJob;
FOR_ENUM_ITEMS(job_type, job)
{
if (ENUM_KEY_STR(job_type, job) == loadedJob)
{
jobType = job;
break;
}
}
std::string loadedItem;
stream >> loadedItem;
FOR_ENUM_ITEMS(item_type, item)
{
if (ENUM_KEY_STR(item_type, item) == loadedItem)
{
itemType = item;
break;
}
}
stream >> item_subtype; stream >> item_subtype;
stream >> material_category.whole; stream >> material_category.whole;
stream >> needed_per_citizen; stream >> needed_per_citizen;
@ -126,7 +144,7 @@ struct ClothingRequirement
stream << bitfield_to_string(material_category) << " "; stream << bitfield_to_string(material_category) << " ";
std::string adjective = ""; std::string adjective = "";
std::string name = ""; std::string name = "";
switch (item_type) switch (itemType)
{ {
case df::enums::item_type::ARMOR: case df::enums::item_type::ARMOR:
adjective = world->raws.itemdefs.armor[item_subtype]->adjective; adjective = world->raws.itemdefs.armor[item_subtype]->adjective;
@ -234,14 +252,14 @@ DFhackCExport command_result plugin_onupdate(color_ostream &out)
static bool setItemFromName(std::string name, ClothingRequirement* requirement) static bool setItemFromName(std::string name, ClothingRequirement* requirement)
{ {
#define SEARCH_ITEM_RAWS(rawType, jobType, itemType) \ #define SEARCH_ITEM_RAWS(rawType, job, item) \
for (auto& itemdef : world->raws.itemdefs.rawType) \ for (auto& itemdef : world->raws.itemdefs.rawType) \
{ \ { \
std::string fullName = itemdef->adjective.empty() ? itemdef->name : itemdef->adjective + " " + itemdef->name; \ std::string fullName = itemdef->adjective.empty() ? itemdef->name : itemdef->adjective + " " + itemdef->name; \
if (fullName == name) \ if (fullName == name) \
{ \ { \
requirement->job_type = job_type::jobType; \ requirement->jobType = job_type::job; \
requirement->item_type = item_type::itemType; \ requirement->itemType = item_type::item; \
requirement->item_subtype = itemdef->subtype; \ requirement->item_subtype = itemdef->subtype; \
return true; \ return true; \
} \ } \
@ -262,24 +280,24 @@ static bool setItemFromToken(std::string token, ClothingRequirement* requirement
switch (itemInfo.type) switch (itemInfo.type)
{ {
case item_type::ARMOR: case item_type::ARMOR:
requirement->job_type = job_type::MakeArmor; requirement->jobType = job_type::MakeArmor;
break; break;
case item_type::GLOVES: case item_type::GLOVES:
requirement->job_type = job_type::MakeGloves; requirement->jobType = job_type::MakeGloves;
break; break;
case item_type::SHOES: case item_type::SHOES:
requirement->job_type = job_type::MakeShoes; requirement->jobType = job_type::MakeShoes;
break; break;
case item_type::HELM: case item_type::HELM:
requirement->job_type = job_type::MakeHelm; requirement->jobType = job_type::MakeHelm;
break; break;
case item_type::PANTS: case item_type::PANTS:
requirement->job_type = job_type::MakePants; requirement->jobType = job_type::MakePants;
break; break;
default: default:
return false; return false;
} }
requirement->item_type = itemInfo.type; requirement->itemType = itemInfo.type;
requirement->item_subtype = itemInfo.subtype; requirement->item_subtype = itemInfo.subtype;
return true; return true;
} }
@ -312,8 +330,8 @@ static bool armorFlagsMatch(BitArray<df::armor_general_flags> * flags, df::job_m
static bool validateMaterialCategory(ClothingRequirement * requirement) static bool validateMaterialCategory(ClothingRequirement * requirement)
{ {
auto itemDef = getSubtypeDef(requirement->item_type, requirement->item_subtype); auto itemDef = getSubtypeDef(requirement->itemType, requirement->item_subtype);
switch (requirement->item_type) switch (requirement->itemType)
{ {
case item_type::ARMOR: case item_type::ARMOR:
if (STRICT_VIRTUAL_CAST_VAR(armor, df::itemdef_armorst, itemDef)) if (STRICT_VIRTUAL_CAST_VAR(armor, df::itemdef_armorst, itemDef))
@ -346,7 +364,16 @@ command_result autoclothing(color_ostream &out, std::vector <std::string> & para
// PluginCommand registration as show above, and then returning // PluginCommand registration as show above, and then returning
// CR_WRONG_USAGE from the function. The same string will also // CR_WRONG_USAGE from the function. The same string will also
// be used by 'help your-command'. // be used by 'help your-command'.
if (parameters.size() < 2 || parameters.size() > 3) if (parameters.size() == 0)
{
out << "Currently set " << clothingOrders.size() << " automatic clothing orders" << endl;
for (size_t i = 0; i < clothingOrders.size(); i++)
{
out << clothingOrders[i].ToReadableLabel() << endl;
}
return CR_OK;
}
else if (parameters.size() < 2 || parameters.size() > 3)
{ {
out << "Wrong number of arguments." << endl; out << "Wrong number of arguments." << endl;
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
@ -356,7 +383,9 @@ command_result autoclothing(color_ostream &out, std::vector <std::string> & para
// use CoreSuspender, it'll automatically resume DF when // use CoreSuspender, it'll automatically resume DF when
// execution leaves the current scope. // execution leaves the current scope.
CoreSuspender suspend; CoreSuspender suspend;
// Actually do something here. Yay.
// Create a new requirement from the available parameters.
ClothingRequirement newRequirement; ClothingRequirement newRequirement;
if (!newRequirement.SetFromParameters(out, parameters)) if (!newRequirement.SetFromParameters(out, parameters))
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
@ -453,7 +482,7 @@ static void find_needed_clothing_items()
{ {
auto item = findItemByID(ownedItem); auto item = findItemByID(ownedItem);
if (item->getType() != clothingOrder.item_type) if (item->getType() != clothingOrder.itemType)
continue; continue;
if (item->getSubtype() != clothingOrder.item_subtype) if (item->getSubtype() != clothingOrder.item_subtype)
continue; continue;
@ -488,7 +517,7 @@ static void remove_available_clothing()
//again, for each item, find if any clothing order matches //again, for each item, find if any clothing order matches
for (auto& clothingOrder : clothingOrders) for (auto& clothingOrder : clothingOrders)
{ {
if (item->getType() != clothingOrder.item_type) if (item->getType() != clothingOrder.itemType)
continue; continue;
if (item->getSubtype() != clothingOrder.item_subtype) if (item->getSubtype() != clothingOrder.item_subtype)
continue; continue;
@ -521,7 +550,7 @@ static void add_clothing_orders()
for (auto& managerOrder : world->manager_orders) for (auto& managerOrder : world->manager_orders)
{ {
//Annoyingly, the manager orders store the job type for clothing orders, and actual item type is left at -1; //Annoyingly, the manager orders store the job type for clothing orders, and actual item type is left at -1;
if (managerOrder->job_type != clothingOrder.job_type) if (managerOrder->job_type != clothingOrder.jobType)
continue; continue;
if (managerOrder->item_subtype != clothingOrder.item_subtype) if (managerOrder->item_subtype != clothingOrder.item_subtype)
continue; continue;
@ -544,7 +573,7 @@ static void add_clothing_orders()
newOrder->id = world->manager_order_next_id; newOrder->id = world->manager_order_next_id;
world->manager_order_next_id++; world->manager_order_next_id++;
newOrder->job_type = clothingOrder.job_type; newOrder->job_type = clothingOrder.jobType;
newOrder->item_subtype = clothingOrder.item_subtype; newOrder->item_subtype = clothingOrder.item_subtype;
newOrder->hist_figure_id = race; newOrder->hist_figure_id = race;
newOrder->material_category = clothingOrder.material_category; newOrder->material_category = clothingOrder.material_category;
@ -624,7 +653,7 @@ static void save_state(color_ostream &out)
std::vector<PersistentDataItem> items; std::vector<PersistentDataItem> items;
World::GetPersistentData(&items, "autoclothing/clothingItems"); World::GetPersistentData(&items, "autoclothing/clothingItems");
for (int i = 0; i < items.size(); i++) for (size_t i = 0; i < items.size(); i++)
{ {
if (i < clothingOrders.size()) if (i < clothingOrders.size())
{ {
@ -635,7 +664,7 @@ static void save_state(color_ostream &out)
World::DeletePersistentData(items[i]); World::DeletePersistentData(items[i]);
} }
} }
for (int i = items.size(); i < clothingOrders.size(); i++) for (size_t i = items.size(); i < clothingOrders.size(); i++)
{ {
auto item = World::AddPersistentData("autoclothing/clothingItems"); auto item = World::AddPersistentData("autoclothing/clothingItems");
item.val() = clothingOrders[i].Serialize(); item.val() = clothingOrders[i].Serialize();