Fix createitem to properly create plant growths (#898)

develop
Quietust 2020-09-20 16:11:41 -06:00
parent 9cf0508b90
commit d3520a2f5f
1 changed files with 83 additions and 3 deletions

@ -26,6 +26,9 @@
#include "df/reaction_reagent.h" #include "df/reaction_reagent.h"
#include "df/reaction_product_itemst.h" #include "df/reaction_product_itemst.h"
#include "df/tool_uses.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::string;
using std::vector; using std::vector;
@ -37,6 +40,7 @@ REQUIRE_GLOBAL(cursor);
REQUIRE_GLOBAL(world); REQUIRE_GLOBAL(world);
REQUIRE_GLOBAL(ui); REQUIRE_GLOBAL(ui);
REQUIRE_GLOBAL(gametype); REQUIRE_GLOBAL(gametype);
REQUIRE_GLOBAL(cur_year_tick);
int dest_container = -1, dest_building = -1; int dest_container = -1, dest_building = -1;
@ -51,6 +55,7 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector<Plugin
" <material> - The material you want the item to be made of, as specified\n" " <material> - The material you want the item to be made of, as specified\n"
" in custom reactions. For REMAINS, FISH, FISH_RAW, VERMIN,\n" " in custom reactions. For REMAINS, FISH, FISH_RAW, VERMIN,\n"
" PET, and EGG, replace this with a creature ID and caste.\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" " [count] - How many of the item you wish to create.\n"
"\n" "\n"
"To obtain the item and material of an existing item, run \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; 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<df::reaction_product*> out_products; vector<df::reaction_product*> out_products;
vector<df::item *> out_items; vector<df::item *> 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); out_items[i]->moveToGround(cursor->x, cursor->y, cursor->z);
else else
out_items[i]->moveToGround(unit->pos.x, unit->pos.y, unit->pos.z); out_items[i]->moveToGround(unit->pos.x, unit->pos.y, unit->pos.z);
// Special logic for making gloves
if (is_gloves) if (is_gloves)
{ {
// if the reaction creates gloves without handedness, then create 2 sets (left and right) // 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 else
out_items[i]->setGloveHandedness(second_item ? 2 : 1); out_items[i]->setGloveHandedness(second_item ? 2 : 1);
} }
// Special logic for making plant growths
auto growth = virtual_cast<df::item_plant_growthst>(out_items[i]);
if (growth)
growth->growth_print = growth_print;
} }
if ((is_gloves || is_shoes) && !second_item) 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; return true;
} }
@ -140,6 +152,7 @@ command_result df_createitem (color_ostream &out, vector <string> & parameters)
int16_t item_subtype = -1; int16_t item_subtype = -1;
int16_t mat_type = -1; int16_t mat_type = -1;
int32_t mat_index = -1; int32_t mat_index = -1;
int32_t growth_print = -1;
int count = 1; int count = 1;
bool move_to_cursor = false; bool move_to_cursor = false;
@ -370,6 +383,73 @@ command_result df_createitem (color_ostream &out, vector <string> & parameters)
} }
break; 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::CORPSE:
case item_type::CORPSEPIECE: case item_type::CORPSEPIECE:
case item_type::FOOD: case item_type::FOOD:
@ -449,7 +529,7 @@ command_result df_createitem (color_ostream &out, vector <string> & parameters)
out.printerr("Previously selected building no longer exists - item will be placed on the floor.\n"); 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; delete prod;
if (!result) if (!result)
{ {