diff --git a/plugins/createitem.cpp b/plugins/createitem.cpp index 6032383d7..f32c51c03 100644 --- a/plugins/createitem.cpp +++ b/plugins/createitem.cpp @@ -26,6 +26,9 @@ #include "df/reaction_reagent.h" #include "df/reaction_product_itemst.h" #include "df/tool_uses.h" +#include "df/item_plant_growthst.h" +#include "df/plant_growth.h" +#include "df/plant_growth_print.h" using std::string; using std::vector; @@ -37,6 +40,7 @@ REQUIRE_GLOBAL(cursor); REQUIRE_GLOBAL(world); REQUIRE_GLOBAL(ui); REQUIRE_GLOBAL(gametype); +REQUIRE_GLOBAL(cur_year_tick); int dest_container = -1, dest_building = -1; @@ -51,6 +55,7 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector - The material you want the item to be made of, as specified\n" " in custom reactions. For REMAINS, FISH, FISH_RAW, VERMIN,\n" " PET, and EGG, replace this with a creature ID and caste.\n" + " For PLANT_GROWTH, replace this with a plant ID and growth ID.\n" " [count] - How many of the item you wish to create.\n" "\n" "To obtain the item and material of an existing item, run \n" @@ -72,7 +77,7 @@ DFhackCExport command_result plugin_shutdown ( color_ostream &out ) return CR_OK; } -bool makeItem (df::reaction_product_itemst *prod, df::unit *unit, bool second_item = false, bool move_to_cursor = false) +bool makeItem (df::reaction_product_itemst *prod, df::unit *unit, bool second_item = false, bool move_to_cursor = false, int32_t growth_print = -1) { vector out_products; vector out_items; @@ -118,6 +123,8 @@ bool makeItem (df::reaction_product_itemst *prod, df::unit *unit, bool second_it out_items[i]->moveToGround(cursor->x, cursor->y, cursor->z); else out_items[i]->moveToGround(unit->pos.x, unit->pos.y, unit->pos.z); + + // Special logic for making gloves if (is_gloves) { // if the reaction creates gloves without handedness, then create 2 sets (left and right) @@ -126,9 +133,14 @@ bool makeItem (df::reaction_product_itemst *prod, df::unit *unit, bool second_it else out_items[i]->setGloveHandedness(second_item ? 2 : 1); } + + // Special logic for making plant growths + auto growth = virtual_cast(out_items[i]); + if (growth) + growth->growth_print = growth_print; } if ((is_gloves || is_shoes) && !second_item) - return makeItem(prod, unit, true, move_to_cursor); + return makeItem(prod, unit, true, move_to_cursor, growth_print); return true; } @@ -140,6 +152,7 @@ command_result df_createitem (color_ostream &out, vector & parameters) int16_t item_subtype = -1; int16_t mat_type = -1; int32_t mat_index = -1; + int32_t growth_print = -1; int count = 1; bool move_to_cursor = false; @@ -370,6 +383,73 @@ command_result df_createitem (color_ostream &out, vector & parameters) } break; + case item_type::PLANT_GROWTH: + split_string(&tokens, material_str, ":"); + if (tokens.size() == 1) + { + // default to empty to display a list of valid growths later + tokens.push_back(""); + } + else if (tokens.size() != 2) + { + out.printerr("You must specify a plant and growth ID for this item type!\n"); + return CR_FAILURE; + } + + for (size_t i = 0; i < world->raws.plants.all.size(); i++) + { + string growths = ""; + df::plant_raw *plant = world->raws.plants.all[i]; + if (plant->id != tokens[0]) + continue; + + for (size_t j = 0; j < plant->growths.size(); j++) + { + df::plant_growth *growth = plant->growths[j]; + growths += " " + growth->id; + if (growth->id != tokens[1]) + continue; + + // Plant growths specify the actual item type/subtype + // so that certain growths can drop as SEEDS items + item_type = growth->item_type; + item_subtype = growth->item_subtype; + mat_type = growth->mat_type; + mat_index = growth->mat_index; + + // Try and find a growth print matching the current time + // (in practice, only tree leaves use this for autumn color changes) + for (size_t k = 0; k < growth->prints.size(); k++) + { + df::plant_growth_print *print = growth->prints[k]; + if (print->timing_start <= *cur_year_tick && *cur_year_tick <= print->timing_end) + { + growth_print = k; + break; + } + } + // If we didn't find one, then pick the first one (if it exists) + if (growth_print == -1 && growth->prints.size() > 0) + growth_print = 0; + break; + } + if (mat_type == -1) + { + if (tokens[1].empty()) + out.printerr("You must also specify a growth ID.\n"); + else + out.printerr("The plant you specified has no such growth!\n"); + out.printerr("Valid growths:%s\n", growths.c_str()); + return CR_FAILURE; + } + } + if (mat_type == -1) + { + out.printerr("Unrecognized plant ID!\n"); + return CR_FAILURE; + } + break; + case item_type::CORPSE: case item_type::CORPSEPIECE: case item_type::FOOD: @@ -449,7 +529,7 @@ command_result df_createitem (color_ostream &out, vector & parameters) out.printerr("Previously selected building no longer exists - item will be placed on the floor.\n"); } - bool result = makeItem(prod, unit, false, move_to_cursor); + bool result = makeItem(prod, unit, false, move_to_cursor, growth_print); delete prod; if (!result) {