|
|
|
@ -52,6 +52,8 @@ DFhackCExport command_result plugin_init(color_ostream & out, std::vector<Plugin
|
|
|
|
|
" Exports the current list of manager orders to a file named dfhack-config/orders/[name].json.\n"
|
|
|
|
|
" orders import [name]\n"
|
|
|
|
|
" Imports manager orders from a file named dfhack-config/orders/[name].json.\n"
|
|
|
|
|
" orders clear\n"
|
|
|
|
|
" Deletes all manager orders in the current embark.\n"
|
|
|
|
|
));
|
|
|
|
|
return CR_OK;
|
|
|
|
|
}
|
|
|
|
@ -63,6 +65,7 @@ DFhackCExport command_result plugin_shutdown(color_ostream & out)
|
|
|
|
|
|
|
|
|
|
static command_result orders_export_command(color_ostream & out, const std::string & name);
|
|
|
|
|
static command_result orders_import_command(color_ostream & out, const std::string & name);
|
|
|
|
|
static command_result orders_clear_command(color_ostream & out);
|
|
|
|
|
|
|
|
|
|
static command_result orders_command(color_ostream & out, std::vector<std::string> & parameters)
|
|
|
|
|
{
|
|
|
|
@ -90,6 +93,11 @@ static command_result orders_command(color_ostream & out, std::vector<std::strin
|
|
|
|
|
return orders_import_command(out, parameters[1]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parameters[0] == "clear" && parameters.size() == 1)
|
|
|
|
|
{
|
|
|
|
|
return orders_clear_command(out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return CR_WRONG_USAGE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -101,16 +109,16 @@ static bool is_safe_filename(color_ostream & out, const std::string & name)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (auto it = name.begin(); it != name.end(); it++)
|
|
|
|
|
for (auto it : name)
|
|
|
|
|
{
|
|
|
|
|
if (isalnum(*it))
|
|
|
|
|
if (isalnum(it))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (*it != ' ' && *it != '.' && *it != '-' && *it != '_')
|
|
|
|
|
if (it != ' ' && it != '.' && it != '-' && it != '_')
|
|
|
|
|
{
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid symbol in name: " << *it << std::endl;
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid symbol in name: " << it << std::endl;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -124,9 +132,9 @@ static void bitfield_to_json_array(Json::Value & out, B bits)
|
|
|
|
|
std::vector<std::string> names;
|
|
|
|
|
bitfield_to_string(&names, bits);
|
|
|
|
|
|
|
|
|
|
for (auto it = names.begin(); it != names.end(); it++)
|
|
|
|
|
for (auto & it : names)
|
|
|
|
|
{
|
|
|
|
|
out.append(*it);
|
|
|
|
|
out.append(it);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -161,11 +169,11 @@ static df::itemdef *get_itemdef(int16_t subtype)
|
|
|
|
|
template<typename D>
|
|
|
|
|
static df::itemdef *get_itemdef(const std::string & subtype)
|
|
|
|
|
{
|
|
|
|
|
for (auto it = D::get_vector().begin(); it != D::get_vector().end(); it++)
|
|
|
|
|
for (auto it : D::get_vector())
|
|
|
|
|
{
|
|
|
|
|
if ((*it)->id == subtype)
|
|
|
|
|
if (it->id == subtype)
|
|
|
|
|
{
|
|
|
|
|
return *it;
|
|
|
|
|
return it;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nullptr;
|
|
|
|
@ -222,24 +230,24 @@ static command_result orders_export_command(color_ostream & out, const std::stri
|
|
|
|
|
{
|
|
|
|
|
CoreSuspender suspend;
|
|
|
|
|
|
|
|
|
|
for (auto it = world->manager_orders.begin(); it != world->manager_orders.end(); it++)
|
|
|
|
|
for (auto it : world->manager_orders)
|
|
|
|
|
{
|
|
|
|
|
Json::Value order(Json::objectValue);
|
|
|
|
|
|
|
|
|
|
order["id"] = (*it)->id;
|
|
|
|
|
order["job"] = enum_item_key((*it)->job_type);
|
|
|
|
|
if (!(*it)->reaction_name.empty())
|
|
|
|
|
order["id"] = it->id;
|
|
|
|
|
order["job"] = enum_item_key(it->job_type);
|
|
|
|
|
if (!it->reaction_name.empty())
|
|
|
|
|
{
|
|
|
|
|
order["reaction"] = (*it)->reaction_name;
|
|
|
|
|
order["reaction"] = it->reaction_name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((*it)->item_type != item_type::NONE)
|
|
|
|
|
if (it->item_type != item_type::NONE)
|
|
|
|
|
{
|
|
|
|
|
order["item_type"] = enum_item_key((*it)->item_type);
|
|
|
|
|
order["item_type"] = enum_item_key(it->item_type);
|
|
|
|
|
}
|
|
|
|
|
if ((*it)->item_subtype != -1)
|
|
|
|
|
if (it->item_subtype != -1)
|
|
|
|
|
{
|
|
|
|
|
df::itemdef *def = get_itemdef(out, (*it)->item_type == item_type::NONE ? ENUM_ATTR(job_type, item, (*it)->job_type) : (*it)->item_type, (*it)->item_subtype);
|
|
|
|
|
df::itemdef *def = get_itemdef(out, it->item_type == item_type::NONE ? ENUM_ATTR(job_type, item, it->job_type) : it->item_type, it->item_subtype);
|
|
|
|
|
|
|
|
|
|
if (def)
|
|
|
|
|
{
|
|
|
|
@ -247,89 +255,89 @@ static command_result orders_export_command(color_ostream & out, const std::stri
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((*it)->job_type == job_type::PrepareMeal)
|
|
|
|
|
if (it->job_type == job_type::PrepareMeal)
|
|
|
|
|
{
|
|
|
|
|
order["meal_ingredients"] = (*it)->mat_type;
|
|
|
|
|
order["meal_ingredients"] = it->mat_type;
|
|
|
|
|
}
|
|
|
|
|
else if ((*it)->mat_type != -1 || (*it)->mat_index != -1)
|
|
|
|
|
else if (it->mat_type != -1 || it->mat_index != -1)
|
|
|
|
|
{
|
|
|
|
|
order["material"] = MaterialInfo(*it).getToken();
|
|
|
|
|
order["material"] = MaterialInfo(it).getToken();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((*it)->item_category.whole != 0)
|
|
|
|
|
if (it->item_category.whole != 0)
|
|
|
|
|
{
|
|
|
|
|
bitfield_to_json_array(order["item_category"], (*it)->item_category);
|
|
|
|
|
bitfield_to_json_array(order["item_category"], it->item_category);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((*it)->hist_figure_id != -1)
|
|
|
|
|
if (it->hist_figure_id != -1)
|
|
|
|
|
{
|
|
|
|
|
order["hist_figure"] = (*it)->hist_figure_id;
|
|
|
|
|
order["hist_figure"] = it->hist_figure_id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((*it)->material_category.whole != 0)
|
|
|
|
|
if (it->material_category.whole != 0)
|
|
|
|
|
{
|
|
|
|
|
bitfield_to_json_array(order["material_category"], (*it)->material_category);
|
|
|
|
|
bitfield_to_json_array(order["material_category"], it->material_category);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((*it)->art_spec.type != df::job_art_specification::None)
|
|
|
|
|
if (it->art_spec.type != df::job_art_specification::None)
|
|
|
|
|
{
|
|
|
|
|
Json::Value art(Json::objectValue);
|
|
|
|
|
|
|
|
|
|
art["type"] = enum_item_key((*it)->art_spec.type);
|
|
|
|
|
art["id"] = (*it)->art_spec.id;
|
|
|
|
|
if ((*it)->art_spec.subid != -1)
|
|
|
|
|
art["type"] = enum_item_key(it->art_spec.type);
|
|
|
|
|
art["id"] = it->art_spec.id;
|
|
|
|
|
if (it->art_spec.subid != -1)
|
|
|
|
|
{
|
|
|
|
|
art["subid"] = (*it)->art_spec.subid;
|
|
|
|
|
art["subid"] = it->art_spec.subid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
order["art"] = art;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
order["amount_left"] = (*it)->amount_left;
|
|
|
|
|
order["amount_total"] = (*it)->amount_total;
|
|
|
|
|
order["is_validated"] = bool((*it)->status.bits.validated);
|
|
|
|
|
order["is_active"] = bool((*it)->status.bits.active);
|
|
|
|
|
order["amount_left"] = it->amount_left;
|
|
|
|
|
order["amount_total"] = it->amount_total;
|
|
|
|
|
order["is_validated"] = bool(it->status.bits.validated);
|
|
|
|
|
order["is_active"] = bool(it->status.bits.active);
|
|
|
|
|
|
|
|
|
|
order["frequency"] = enum_item_key((*it)->frequency);
|
|
|
|
|
order["frequency"] = enum_item_key(it->frequency);
|
|
|
|
|
|
|
|
|
|
// TODO: finished_year, finished_year_tick
|
|
|
|
|
|
|
|
|
|
if ((*it)->workshop_id != -1)
|
|
|
|
|
if (it->workshop_id != -1)
|
|
|
|
|
{
|
|
|
|
|
order["workshop_id"] = (*it)->workshop_id;
|
|
|
|
|
order["workshop_id"] = it->workshop_id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((*it)->max_workshops != 0)
|
|
|
|
|
if (it->max_workshops != 0)
|
|
|
|
|
{
|
|
|
|
|
order["max_workshops"] = (*it)->max_workshops;
|
|
|
|
|
order["max_workshops"] = it->max_workshops;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!(*it)->item_conditions.empty())
|
|
|
|
|
if (!it->item_conditions.empty())
|
|
|
|
|
{
|
|
|
|
|
Json::Value conditions(Json::arrayValue);
|
|
|
|
|
|
|
|
|
|
for (auto it2 = (*it)->item_conditions.begin(); it2 != (*it)->item_conditions.end(); it2++)
|
|
|
|
|
for (auto it2 : it->item_conditions)
|
|
|
|
|
{
|
|
|
|
|
Json::Value condition(Json::objectValue);
|
|
|
|
|
|
|
|
|
|
condition["condition"] = enum_item_key((*it2)->compare_type);
|
|
|
|
|
condition["value"] = (*it2)->compare_val;
|
|
|
|
|
condition["condition"] = enum_item_key(it2->compare_type);
|
|
|
|
|
condition["value"] = it2->compare_val;
|
|
|
|
|
|
|
|
|
|
if ((*it2)->flags1.whole != 0 || (*it2)->flags2.whole != 0 || (*it2)->flags3.whole != 0)
|
|
|
|
|
if (it2->flags1.whole != 0 || it2->flags2.whole != 0 || it2->flags3.whole != 0)
|
|
|
|
|
{
|
|
|
|
|
bitfield_to_json_array(condition["flags"], (*it2)->flags1);
|
|
|
|
|
bitfield_to_json_array(condition["flags"], (*it2)->flags2);
|
|
|
|
|
bitfield_to_json_array(condition["flags"], (*it2)->flags3);
|
|
|
|
|
bitfield_to_json_array(condition["flags"], it2->flags1);
|
|
|
|
|
bitfield_to_json_array(condition["flags"], it2->flags2);
|
|
|
|
|
bitfield_to_json_array(condition["flags"], it2->flags3);
|
|
|
|
|
// TODO: flags4, flags5
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((*it2)->item_type != item_type::NONE)
|
|
|
|
|
if (it2->item_type != item_type::NONE)
|
|
|
|
|
{
|
|
|
|
|
condition["item_type"] = enum_item_key((*it2)->item_type);
|
|
|
|
|
condition["item_type"] = enum_item_key(it2->item_type);
|
|
|
|
|
}
|
|
|
|
|
if ((*it2)->item_subtype != -1)
|
|
|
|
|
if (it2->item_subtype != -1)
|
|
|
|
|
{
|
|
|
|
|
df::itemdef *def = get_itemdef(out, (*it2)->item_type, (*it2)->item_subtype);
|
|
|
|
|
df::itemdef *def = get_itemdef(out, it2->item_type, it2->item_subtype);
|
|
|
|
|
|
|
|
|
|
if (def)
|
|
|
|
|
{
|
|
|
|
@ -337,29 +345,29 @@ static command_result orders_export_command(color_ostream & out, const std::stri
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((*it2)->mat_type != -1 || (*it2)->mat_index != -1)
|
|
|
|
|
if (it2->mat_type != -1 || it2->mat_index != -1)
|
|
|
|
|
{
|
|
|
|
|
condition["material"] = MaterialInfo(*it2).getToken();
|
|
|
|
|
condition["material"] = MaterialInfo(it2).getToken();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((*it2)->inorganic_bearing != -1)
|
|
|
|
|
if (it2->inorganic_bearing != -1)
|
|
|
|
|
{
|
|
|
|
|
condition["bearing"] = df::inorganic_raw::find((*it2)->inorganic_bearing)->id;
|
|
|
|
|
condition["bearing"] = df::inorganic_raw::find(it2->inorganic_bearing)->id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!(*it2)->reaction_class.empty())
|
|
|
|
|
if (!it2->reaction_class.empty())
|
|
|
|
|
{
|
|
|
|
|
condition["reaction_class"] = (*it2)->reaction_class;
|
|
|
|
|
condition["reaction_class"] = it2->reaction_class;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!(*it2)->has_material_reaction_product.empty())
|
|
|
|
|
if (!it2->has_material_reaction_product.empty())
|
|
|
|
|
{
|
|
|
|
|
condition["reaction_product"] = (*it2)->has_material_reaction_product;
|
|
|
|
|
condition["reaction_product"] = it2->has_material_reaction_product;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((*it2)->has_tool_use != tool_uses::NONE)
|
|
|
|
|
if (it2->has_tool_use != tool_uses::NONE)
|
|
|
|
|
{
|
|
|
|
|
condition["tool"] = enum_item_key((*it2)->has_tool_use);
|
|
|
|
|
condition["tool"] = enum_item_key(it2->has_tool_use);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: anon_1, anon_2, anon_3
|
|
|
|
@ -370,16 +378,16 @@ static command_result orders_export_command(color_ostream & out, const std::stri
|
|
|
|
|
order["item_conditions"] = conditions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!(*it)->order_conditions.empty())
|
|
|
|
|
if (!it->order_conditions.empty())
|
|
|
|
|
{
|
|
|
|
|
Json::Value conditions(Json::arrayValue);
|
|
|
|
|
|
|
|
|
|
for (auto it2 = (*it)->order_conditions.begin(); it2 != (*it)->order_conditions.end(); it2++)
|
|
|
|
|
for (auto it2 : it->order_conditions)
|
|
|
|
|
{
|
|
|
|
|
Json::Value condition(Json::objectValue);
|
|
|
|
|
|
|
|
|
|
condition["order"] = (*it2)->order_id;
|
|
|
|
|
condition["condition"] = enum_item_key((*it2)->condition);
|
|
|
|
|
condition["order"] = it2->order_id;
|
|
|
|
|
condition["condition"] = enum_item_key(it2->condition);
|
|
|
|
|
|
|
|
|
|
// TODO: anon_1
|
|
|
|
|
|
|
|
|
@ -439,65 +447,47 @@ static command_result orders_import_command(color_ostream & out, const std::stri
|
|
|
|
|
|
|
|
|
|
CoreSuspender suspend;
|
|
|
|
|
|
|
|
|
|
for (auto it = world->manager_orders.begin(); it != world->manager_orders.end(); it++)
|
|
|
|
|
{
|
|
|
|
|
for (auto it2 = (*it)->item_conditions.begin(); it2 != (*it)->item_conditions.end(); it2++)
|
|
|
|
|
{
|
|
|
|
|
delete *it2;
|
|
|
|
|
}
|
|
|
|
|
for (auto it2 = (*it)->order_conditions.begin(); it2 != (*it)->order_conditions.end(); it2++)
|
|
|
|
|
{
|
|
|
|
|
delete *it2;
|
|
|
|
|
}
|
|
|
|
|
if ((*it)->anon_1)
|
|
|
|
|
std::map<int32_t, int32_t> id_mapping;
|
|
|
|
|
for (auto it : orders)
|
|
|
|
|
{
|
|
|
|
|
for (auto it2 = (*it)->anon_1->begin(); it2 != (*it)->anon_1->end(); it2++)
|
|
|
|
|
{
|
|
|
|
|
delete *it2;
|
|
|
|
|
}
|
|
|
|
|
delete (*it)->anon_1;
|
|
|
|
|
id_mapping[it["id"].asInt()] = world->manager_order_next_id;
|
|
|
|
|
world->manager_order_next_id++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete *it;
|
|
|
|
|
}
|
|
|
|
|
world->manager_orders.clear();
|
|
|
|
|
world->manager_order_next_id = 0;
|
|
|
|
|
|
|
|
|
|
for (auto it = orders.begin(); it != orders.end(); it++)
|
|
|
|
|
for (auto & it : orders)
|
|
|
|
|
{
|
|
|
|
|
df::manager_order *order = new df::manager_order();
|
|
|
|
|
|
|
|
|
|
order->id = (*it)["id"].asInt();
|
|
|
|
|
world->manager_order_next_id = order->id + 1;
|
|
|
|
|
order->id = id_mapping.at(it["id"].asInt());
|
|
|
|
|
|
|
|
|
|
if (!find_enum_item(&order->job_type, (*it)["job"].asString()))
|
|
|
|
|
if (!find_enum_item(&order->job_type, it["job"].asString()))
|
|
|
|
|
{
|
|
|
|
|
delete order;
|
|
|
|
|
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid job type for imported manager order: " << (*it)["job"].asString() << std::endl;
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid job type for imported manager order: " << it["job"].asString() << std::endl;
|
|
|
|
|
|
|
|
|
|
return CR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it->isMember("reaction"))
|
|
|
|
|
if (it.isMember("reaction"))
|
|
|
|
|
{
|
|
|
|
|
order->reaction_name = (*it)["reaction"].asString();
|
|
|
|
|
order->reaction_name = it["reaction"].asString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it->isMember("item_type"))
|
|
|
|
|
if (it.isMember("item_type"))
|
|
|
|
|
{
|
|
|
|
|
if (!find_enum_item(&order->item_type, (*it)["item_type"].asString()) || order->item_type == item_type::NONE)
|
|
|
|
|
if (!find_enum_item(&order->item_type, it["item_type"].asString()) || order->item_type == item_type::NONE)
|
|
|
|
|
{
|
|
|
|
|
delete order;
|
|
|
|
|
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid item type for imported manager order: " << (*it)["item_type"].asString() << std::endl;
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid item type for imported manager order: " << it["item_type"].asString() << std::endl;
|
|
|
|
|
|
|
|
|
|
return CR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (it->isMember("item_subtype"))
|
|
|
|
|
if (it.isMember("item_subtype"))
|
|
|
|
|
{
|
|
|
|
|
df::itemdef *def = get_itemdef(out, order->item_type == item_type::NONE ? ENUM_ATTR(job_type, item, order->job_type) : order->item_type, (*it)["item_subtype"].asString());
|
|
|
|
|
df::itemdef *def = get_itemdef(out, order->item_type == item_type::NONE ? ENUM_ATTR(job_type, item, order->job_type) : order->item_type, it["item_subtype"].asString());
|
|
|
|
|
|
|
|
|
|
if (def)
|
|
|
|
|
{
|
|
|
|
@ -507,25 +497,25 @@ static command_result orders_import_command(color_ostream & out, const std::stri
|
|
|
|
|
{
|
|
|
|
|
delete order;
|
|
|
|
|
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid item subtype for imported manager order: " << enum_item_key(order->item_type) << ":" << (*it)["item_subtype"].asString() << std::endl;
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid item subtype for imported manager order: " << enum_item_key(order->item_type) << ":" << it["item_subtype"].asString() << std::endl;
|
|
|
|
|
|
|
|
|
|
return CR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it->isMember("meal_ingredients"))
|
|
|
|
|
if (it.isMember("meal_ingredients"))
|
|
|
|
|
{
|
|
|
|
|
order->mat_type = (*it)["meal_ingredients"].asInt();
|
|
|
|
|
order->mat_type = it["meal_ingredients"].asInt();
|
|
|
|
|
order->mat_index = -1;
|
|
|
|
|
}
|
|
|
|
|
else if (it->isMember("material"))
|
|
|
|
|
else if (it.isMember("material"))
|
|
|
|
|
{
|
|
|
|
|
MaterialInfo mat;
|
|
|
|
|
if (!mat.find((*it)["material"].asString()))
|
|
|
|
|
if (!mat.find(it["material"].asString()))
|
|
|
|
|
{
|
|
|
|
|
delete order;
|
|
|
|
|
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid material for imported manager order: " << (*it)["material"].asString() << std::endl;
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid material for imported manager order: " << it["material"].asString() << std::endl;
|
|
|
|
|
|
|
|
|
|
return CR_FAILURE;
|
|
|
|
|
}
|
|
|
|
@ -533,147 +523,147 @@ static command_result orders_import_command(color_ostream & out, const std::stri
|
|
|
|
|
order->mat_index = mat.index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it->isMember("item_category"))
|
|
|
|
|
if (it.isMember("item_category"))
|
|
|
|
|
{
|
|
|
|
|
json_array_to_bitfield(order->item_category, (*it)["item_category"]);
|
|
|
|
|
if (!(*it)["item_category"].empty())
|
|
|
|
|
json_array_to_bitfield(order->item_category, it["item_category"]);
|
|
|
|
|
if (!it["item_category"].empty())
|
|
|
|
|
{
|
|
|
|
|
delete order;
|
|
|
|
|
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid item_category value for imported manager order: " << (*it)["item_category"] << std::endl;
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid item_category value for imported manager order: " << it["item_category"] << std::endl;
|
|
|
|
|
|
|
|
|
|
return CR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it->isMember("hist_figure"))
|
|
|
|
|
if (it.isMember("hist_figure"))
|
|
|
|
|
{
|
|
|
|
|
if (!df::historical_figure::find((*it)["hist_figure"].asInt()))
|
|
|
|
|
if (!df::historical_figure::find(it["hist_figure"].asInt()))
|
|
|
|
|
{
|
|
|
|
|
delete order;
|
|
|
|
|
|
|
|
|
|
out << COLOR_YELLOW << "Missing historical figure for imported manager order: " << (*it)["hist_figure"].asInt() << std::endl;
|
|
|
|
|
out << COLOR_YELLOW << "Missing historical figure for imported manager order: " << it["hist_figure"].asInt() << std::endl;
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
order->hist_figure_id = (*it)["hist_figure"].asInt();
|
|
|
|
|
order->hist_figure_id = it["hist_figure"].asInt();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it->isMember("material_category"))
|
|
|
|
|
if (it.isMember("material_category"))
|
|
|
|
|
{
|
|
|
|
|
json_array_to_bitfield(order->material_category, (*it)["material_category"]);
|
|
|
|
|
if (!(*it)["material_category"].empty())
|
|
|
|
|
json_array_to_bitfield(order->material_category, it["material_category"]);
|
|
|
|
|
if (!it["material_category"].empty())
|
|
|
|
|
{
|
|
|
|
|
delete order;
|
|
|
|
|
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid material_category value for imported manager order: " << (*it)["material_category"] << std::endl;
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid material_category value for imported manager order: " << it["material_category"] << std::endl;
|
|
|
|
|
|
|
|
|
|
return CR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it->isMember("art"))
|
|
|
|
|
if (it.isMember("art"))
|
|
|
|
|
{
|
|
|
|
|
if (!find_enum_item(&order->art_spec.type, (*it)["art"]["type"].asString()))
|
|
|
|
|
if (!find_enum_item(&order->art_spec.type, it["art"]["type"].asString()))
|
|
|
|
|
{
|
|
|
|
|
delete order;
|
|
|
|
|
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid art type value for imported manager order: " << (*it)["art"]["type"].asString() << std::endl;
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid art type value for imported manager order: " << it["art"]["type"].asString() << std::endl;
|
|
|
|
|
|
|
|
|
|
return CR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
order->art_spec.id = (*it)["art"]["id"].asInt();
|
|
|
|
|
if ((*it)["art"].isMember("subid"))
|
|
|
|
|
order->art_spec.id = it["art"]["id"].asInt();
|
|
|
|
|
if (it["art"].isMember("subid"))
|
|
|
|
|
{
|
|
|
|
|
order->art_spec.subid = (*it)["art"]["subid"].asInt();
|
|
|
|
|
order->art_spec.subid = it["art"]["subid"].asInt();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
order->amount_left = (*it)["amount_left"].asInt();
|
|
|
|
|
order->amount_total = (*it)["amount_total"].asInt();
|
|
|
|
|
order->status.bits.validated = (*it)["is_validated"].asBool();
|
|
|
|
|
order->status.bits.active = (*it)["is_active"].asBool();
|
|
|
|
|
order->amount_left = it["amount_left"].asInt();
|
|
|
|
|
order->amount_total = it["amount_total"].asInt();
|
|
|
|
|
order->status.bits.validated = it["is_validated"].asBool();
|
|
|
|
|
order->status.bits.active = it["is_active"].asBool();
|
|
|
|
|
|
|
|
|
|
if (!find_enum_item(&order->frequency, (*it)["frequency"].asString()))
|
|
|
|
|
if (!find_enum_item(&order->frequency, it["frequency"].asString()))
|
|
|
|
|
{
|
|
|
|
|
delete order;
|
|
|
|
|
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid frequency value for imported manager order: " << (*it)["frequency"].asString() << std::endl;
|
|
|
|
|
out << COLOR_LIGHTRED << "Invalid frequency value for imported manager order: " << it["frequency"].asString() << std::endl;
|
|
|
|
|
|
|
|
|
|
return CR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: finished_year, finished_year_tick
|
|
|
|
|
|
|
|
|
|
if (it->isMember("workshop_id"))
|
|
|
|
|
if (it.isMember("workshop_id"))
|
|
|
|
|
{
|
|
|
|
|
if (!df::building::find((*it)["workshop_id"].asInt()))
|
|
|
|
|
if (!df::building::find(it["workshop_id"].asInt()))
|
|
|
|
|
{
|
|
|
|
|
delete order;
|
|
|
|
|
|
|
|
|
|
out << COLOR_YELLOW << "Missing workshop for imported manager order: " << (*it)["workshop_id"].asInt() << std::endl;
|
|
|
|
|
out << COLOR_YELLOW << "Missing workshop for imported manager order: " << it["workshop_id"].asInt() << std::endl;
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
order->workshop_id = (*it)["workshop_id"].asInt();
|
|
|
|
|
order->workshop_id = it["workshop_id"].asInt();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it->isMember("max_workshops"))
|
|
|
|
|
if (it.isMember("max_workshops"))
|
|
|
|
|
{
|
|
|
|
|
order->max_workshops = (*it)["max_workshops"].asInt();
|
|
|
|
|
order->max_workshops = it["max_workshops"].asInt();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it->isMember("item_conditions"))
|
|
|
|
|
if (it.isMember("item_conditions"))
|
|
|
|
|
{
|
|
|
|
|
for (auto it2 = (*it)["item_conditions"].begin(); it2 != (*it)["item_conditions"].end(); it2++)
|
|
|
|
|
for (auto & it2 : it["item_conditions"])
|
|
|
|
|
{
|
|
|
|
|
df::manager_order_condition_item *condition = new df::manager_order_condition_item();
|
|
|
|
|
|
|
|
|
|
if (!find_enum_item(&condition->compare_type, (*it2)["condition"].asString()))
|
|
|
|
|
if (!find_enum_item(&condition->compare_type, it2["condition"].asString()))
|
|
|
|
|
{
|
|
|
|
|
delete condition;
|
|
|
|
|
|
|
|
|
|
out << COLOR_YELLOW << "Invalid item condition condition for imported manager order: " << (*it2)["condition"].asString() << std::endl;
|
|
|
|
|
out << COLOR_YELLOW << "Invalid item condition condition for imported manager order: " << it2["condition"].asString() << std::endl;
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
condition->compare_val = (*it2)["value"].asInt();
|
|
|
|
|
condition->compare_val = it2["value"].asInt();
|
|
|
|
|
|
|
|
|
|
if (it2->isMember("flags"))
|
|
|
|
|
if (it2.isMember("flags"))
|
|
|
|
|
{
|
|
|
|
|
json_array_to_bitfield(condition->flags1, (*it2)["flags"]);
|
|
|
|
|
json_array_to_bitfield(condition->flags2, (*it2)["flags"]);
|
|
|
|
|
json_array_to_bitfield(condition->flags3, (*it2)["flags"]);
|
|
|
|
|
json_array_to_bitfield(condition->flags1, it2["flags"]);
|
|
|
|
|
json_array_to_bitfield(condition->flags2, it2["flags"]);
|
|
|
|
|
json_array_to_bitfield(condition->flags3, it2["flags"]);
|
|
|
|
|
// TODO: flags4, flags5
|
|
|
|
|
|
|
|
|
|
if (!(*it2)["flags"].empty())
|
|
|
|
|
if (!it2["flags"].empty())
|
|
|
|
|
{
|
|
|
|
|
delete condition;
|
|
|
|
|
|
|
|
|
|
out << COLOR_YELLOW << "Invalid item condition flags for imported manager order: " << (*it2)["flags"] << std::endl;
|
|
|
|
|
out << COLOR_YELLOW << "Invalid item condition flags for imported manager order: " << it2["flags"] << std::endl;
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it2->isMember("item_type"))
|
|
|
|
|
if (it2.isMember("item_type"))
|
|
|
|
|
{
|
|
|
|
|
if (!find_enum_item(&condition->item_type, (*it2)["item_type"].asString()) || condition->item_type == item_type::NONE)
|
|
|
|
|
if (!find_enum_item(&condition->item_type, it2["item_type"].asString()) || condition->item_type == item_type::NONE)
|
|
|
|
|
{
|
|
|
|
|
delete condition;
|
|
|
|
|
|
|
|
|
|
out << COLOR_YELLOW << "Invalid item condition item type for imported manager order: " << (*it2)["item_type"].asString() << std::endl;
|
|
|
|
|
out << COLOR_YELLOW << "Invalid item condition item type for imported manager order: " << it2["item_type"].asString() << std::endl;
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (it2->isMember("item_subtype"))
|
|
|
|
|
if (it2.isMember("item_subtype"))
|
|
|
|
|
{
|
|
|
|
|
df::itemdef *def = get_itemdef(out, condition->item_type, (*it2)["item_subtype"].asString());
|
|
|
|
|
df::itemdef *def = get_itemdef(out, condition->item_type, it2["item_subtype"].asString());
|
|
|
|
|
|
|
|
|
|
if (def)
|
|
|
|
|
{
|
|
|
|
@ -683,20 +673,20 @@ static command_result orders_import_command(color_ostream & out, const std::stri
|
|
|
|
|
{
|
|
|
|
|
delete condition;
|
|
|
|
|
|
|
|
|
|
out << COLOR_YELLOW << "Invalid item condition item subtype for imported manager order: " << enum_item_key(condition->item_type) << ":" << (*it2)["item_subtype"].asString() << std::endl;
|
|
|
|
|
out << COLOR_YELLOW << "Invalid item condition item subtype for imported manager order: " << enum_item_key(condition->item_type) << ":" << it2["item_subtype"].asString() << std::endl;
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it2->isMember("material"))
|
|
|
|
|
if (it2.isMember("material"))
|
|
|
|
|
{
|
|
|
|
|
MaterialInfo mat;
|
|
|
|
|
if (!mat.find((*it2)["material"].asString()))
|
|
|
|
|
if (!mat.find(it2["material"].asString()))
|
|
|
|
|
{
|
|
|
|
|
delete condition;
|
|
|
|
|
|
|
|
|
|
out << COLOR_YELLOW << "Invalid item condition material for imported manager order: " << (*it2)["material"].asString() << std::endl;
|
|
|
|
|
out << COLOR_YELLOW << "Invalid item condition material for imported manager order: " << it2["material"].asString() << std::endl;
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
@ -704,38 +694,38 @@ static command_result orders_import_command(color_ostream & out, const std::stri
|
|
|
|
|
condition->mat_index = mat.index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it2->isMember("bearing"))
|
|
|
|
|
if (it2.isMember("bearing"))
|
|
|
|
|
{
|
|
|
|
|
std::string bearing((*it2)["bearing"].asString());
|
|
|
|
|
std::string bearing(it2["bearing"].asString());
|
|
|
|
|
auto found = std::find_if(world->raws.inorganics.begin(), world->raws.inorganics.end(), [bearing](df::inorganic_raw *raw) -> bool { return raw->id == bearing; });
|
|
|
|
|
if (found == world->raws.inorganics.end())
|
|
|
|
|
{
|
|
|
|
|
delete condition;
|
|
|
|
|
|
|
|
|
|
out << COLOR_YELLOW << "Invalid item condition inorganic bearing type for imported manager order: " << (*it2)["bearing"].asString() << std::endl;
|
|
|
|
|
out << COLOR_YELLOW << "Invalid item condition inorganic bearing type for imported manager order: " << it2["bearing"].asString() << std::endl;
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
condition->inorganic_bearing = found - world->raws.inorganics.begin();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it2->isMember("reaction_class"))
|
|
|
|
|
if (it2.isMember("reaction_class"))
|
|
|
|
|
{
|
|
|
|
|
condition->reaction_class = (*it2)["reaction_class"].asString();
|
|
|
|
|
condition->reaction_class = it2["reaction_class"].asString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it2->isMember("reaction_product"))
|
|
|
|
|
if (it2.isMember("reaction_product"))
|
|
|
|
|
{
|
|
|
|
|
condition->has_material_reaction_product = (*it2)["reaction_product"].asString();
|
|
|
|
|
condition->has_material_reaction_product = it2["reaction_product"].asString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it2->isMember("tool"))
|
|
|
|
|
if (it2.isMember("tool"))
|
|
|
|
|
{
|
|
|
|
|
if (!find_enum_item(&condition->has_tool_use, (*it2)["tool"].asString()) || condition->has_tool_use == tool_uses::NONE)
|
|
|
|
|
if (!find_enum_item(&condition->has_tool_use, it2["tool"].asString()) || condition->has_tool_use == tool_uses::NONE)
|
|
|
|
|
{
|
|
|
|
|
delete condition;
|
|
|
|
|
|
|
|
|
|
out << COLOR_YELLOW << "Invalid item condition tool use for imported manager order: " << (*it2)["tool"].asString() << std::endl;
|
|
|
|
|
out << COLOR_YELLOW << "Invalid item condition tool use for imported manager order: " << it2["tool"].asString() << std::endl;
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
@ -747,28 +737,28 @@ static command_result orders_import_command(color_ostream & out, const std::stri
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (it->isMember("order_conditions"))
|
|
|
|
|
if (it.isMember("order_conditions"))
|
|
|
|
|
{
|
|
|
|
|
for (auto it2 = (*it)["order_conditions"].begin(); it2 != (*it)["order_conditions"].end(); it2++)
|
|
|
|
|
for (auto & it2 : it["order_conditions"])
|
|
|
|
|
{
|
|
|
|
|
df::manager_order_condition_order *condition = new df::manager_order_condition_order();
|
|
|
|
|
|
|
|
|
|
int32_t id = (*it2)["order"].asInt();
|
|
|
|
|
if (id == order->id || std::find_if(orders.begin(), orders.end(), [id](const Json::Value & o) -> bool { return o["id"].asInt() == id; }) == orders.end())
|
|
|
|
|
int32_t id = it2["order"].asInt();
|
|
|
|
|
if (id == it["id"].asInt() || !id_mapping.count(id))
|
|
|
|
|
{
|
|
|
|
|
delete condition;
|
|
|
|
|
|
|
|
|
|
out << COLOR_YELLOW << "Missing order condition target for imported manager order: " << (*it2)["order"].asInt() << std::endl;
|
|
|
|
|
out << COLOR_YELLOW << "Missing order condition target for imported manager order: " << it2["order"].asInt() << std::endl;
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
condition->order_id = id;
|
|
|
|
|
condition->order_id = id_mapping.at(id);
|
|
|
|
|
|
|
|
|
|
if (!find_enum_item(&condition->condition, (*it2)["condition"].asString()))
|
|
|
|
|
if (!find_enum_item(&condition->condition, it2["condition"].asString()))
|
|
|
|
|
{
|
|
|
|
|
delete condition;
|
|
|
|
|
|
|
|
|
|
out << COLOR_YELLOW << "Invalid order condition type for imported manager order: " << (*it2)["condition"].asString() << std::endl;
|
|
|
|
|
out << COLOR_YELLOW << "Invalid order condition type for imported manager order: " << it2["condition"].asString() << std::endl;
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
@ -786,3 +776,36 @@ static command_result orders_import_command(color_ostream & out, const std::stri
|
|
|
|
|
|
|
|
|
|
return CR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static command_result orders_clear_command(color_ostream & out)
|
|
|
|
|
{
|
|
|
|
|
CoreSuspender suspend;
|
|
|
|
|
|
|
|
|
|
for (auto order : world->manager_orders)
|
|
|
|
|
{
|
|
|
|
|
for (auto condition : order->item_conditions)
|
|
|
|
|
{
|
|
|
|
|
delete condition;
|
|
|
|
|
}
|
|
|
|
|
for (auto condition : order->order_conditions)
|
|
|
|
|
{
|
|
|
|
|
delete condition;
|
|
|
|
|
}
|
|
|
|
|
if (order->anon_1)
|
|
|
|
|
{
|
|
|
|
|
for (auto anon_1 : *order->anon_1)
|
|
|
|
|
{
|
|
|
|
|
delete anon_1;
|
|
|
|
|
}
|
|
|
|
|
delete order->anon_1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete order;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out << "Deleted " << world->manager_orders.size() << " manager orders." << std::endl;
|
|
|
|
|
|
|
|
|
|
world->manager_orders.clear();
|
|
|
|
|
|
|
|
|
|
return CR_OK;
|
|
|
|
|
}
|
|
|
|
|