diff --git a/plugins/devel/regrass.cpp b/plugins/devel/regrass.cpp index f4143f465..4c8f19346 100644 --- a/plugins/devel/regrass.cpp +++ b/plugins/devel/regrass.cpp @@ -8,19 +8,47 @@ #include "DataDefs.h" #include "df/world.h" +#include "df/world_raws.h" +#include "df/plant_raw.h" + #include "df/map_block.h" +#include "df/block_square_event.h" +//#include "df/block_square_event_type.h" +#include "df/block_square_event_grassst.h" #include "TileTypes.h" using std::string; using std::vector; +using namespace std; using namespace DFHack; using df::global::world; +DFHACK_PLUGIN("regrass"); + +command_result df_regrass (color_ostream &out, vector & parameters); + +DFhackCExport command_result plugin_init (color_ostream &out, std::vector &commands) +{ + commands.push_back(PluginCommand("regrass", "Regrows surface grass.", df_regrass)); + return CR_OK; +} + +DFhackCExport command_result plugin_shutdown ( color_ostream &out ) +{ + return CR_OK; +} + command_result df_regrass (color_ostream &out, vector & parameters) { + bool max = false; if (!parameters.empty()) - return CR_WRONG_USAGE; + { + if(parameters[0] == "max") + max = true; + else + return CR_WRONG_USAGE; + } CoreSuspender suspend; @@ -28,19 +56,62 @@ command_result df_regrass (color_ostream &out, vector & parameters) for (size_t i = 0; i < world->map.map_blocks.size(); i++) { df::map_block *cur = world->map.map_blocks[i]; - for (int x = 0; x < 16; x++) + + // check block for grass events before looking at 16x16 tiles + df::block_square_event_grassst * grev = NULL; + for(size_t e=0; eblock_events.size(); e++) + { + df::block_square_event * blev = cur->block_events[e]; + df::block_square_event_type blevtype = blev->getType(); + if(blevtype == df::block_square_event_type::grass) + { + grev = (df::block_square_event_grassst *)blev; + break; + } + } + if(!grev) { - for (int y = 0; y < 16; y++) + // in this worst case we should check other blocks, create a new event etc + // but looking at some maps that should happen very very rarely if at all + // a standard map block seems to always have up to 10 grass events we can refresh + continue; + } + + for (int y = 0; y < 16; y++) + { + for (int x = 0; x < 16; x++) { - if (tileShape(cur->tiletype[x][y]) != tiletype_shape::FLOOR) - continue; - if (tileMaterial(cur->tiletype[x][y]) != tiletype_material::SOIL) + if ( tileShape(cur->tiletype[x][y]) != tiletype_shape::FLOOR + || cur->designation[x][y].bits.subterranean + || cur->occupancy[x][y].bits.building) continue; - if (cur->designation[x][y].bits.subterranean) - continue; - if (cur->occupancy[x][y].bits.building) + + int mat = tileMaterial(cur->tiletype[x][y]); + if ( mat != tiletype_material::SOIL + && mat != tiletype_material::GRASS_DARK // refill existing grass, too + && mat != tiletype_material::GRASS_LIGHT // refill existing grass, too + ) continue; + // max = set amounts of all grass events on that tile to 100 + if(max) + { + for(size_t e=0; eblock_events.size(); e++) + { + df::block_square_event * blev = cur->block_events[e]; + df::block_square_event_type blevtype = blev->getType(); + if(blevtype == df::block_square_event_type::grass) + { + df::block_square_event_grassst * gr_ev = (df::block_square_event_grassst *)blev; + gr_ev->amount[x][y] = 100; + break; + } + } + } + else + { + grev->amount[x][y]=100; + } cur->tiletype[x][y] = findRandomVariant((rand() & 1) ? tiletype::GrassLightFloor1 : tiletype::GrassDarkFloor1); count++; } @@ -51,16 +122,3 @@ command_result df_regrass (color_ostream &out, vector & parameters) out.print("Regrew %d tiles of grass.\n", count); return CR_OK; } - -DFHACK_PLUGIN("regrass"); - -DFhackCExport command_result plugin_init (color_ostream &out, std::vector &commands) -{ - commands.push_back(PluginCommand("regrass", "Regrows all surface grass, restoring outdoor plant growth for pre-0.31.19 worlds.", df_regrass)); - return CR_OK; -} - -DFhackCExport command_result plugin_shutdown ( color_ostream &out ) -{ - return CR_OK; -} diff --git a/plugins/zone.cpp b/plugins/zone.cpp index 5d5c196c0..c668abe99 100644 --- a/plugins/zone.cpp +++ b/plugins/zone.cpp @@ -341,7 +341,7 @@ bool isForest(df::unit* creature); bool isActivityZone(df::building * building); bool isPenPasture(df::building * building); -bool isPit(df::building * building); +bool isPitPond(df::building * building); bool isActive(df::building * building); int32_t findBuildingIndexById(int32_t id); @@ -727,14 +727,14 @@ bool isPenPasture(df::building * building) return false; } -bool isPit(df::building * building) +bool isPitPond(df::building * building) { if(!isActivityZone(building)) return false; df::building_civzonest * civ = (df::building_civzonest *) building; - if(civ->zone_flags.bits.pit_pond && civ->pit_flags==0) + if(civ->zone_flags.bits.pit_pond) // && civ->pit_flags==0) return true; else return false; @@ -790,7 +790,7 @@ int32_t findPenPitAtCursor() building->z == cursor->z)) continue; - if(isPenPasture(building) || isPit(building)) + if(isPenPasture(building) || isPitPond(building)) { foundID = building->id; break; @@ -1198,9 +1198,9 @@ bool unassignUnitFromBuilding(df::unit* unit) command_result assignUnitToZone(color_ostream& out, df::unit* unit, df::building* building, bool verbose = false) { // building must be a pen/pasture or pit - if(!isPenPasture(building) && !isPit(building)) + if(!isPenPasture(building) && !isPitPond(building)) { - out << "Invalid building type. This is not a pen/pasture or pit." << endl; + out << "Invalid building type. This is not a pen/pasture or pit/pond." << endl; return CR_WRONG_USAGE; } @@ -1238,8 +1238,8 @@ command_result assignUnitToZone(color_ostream& out, df::unit* unit, df::building out << "Unit " << unit->id << "(" << getRaceName(unit) << ")" << " assigned to zone " << building->id; - if(isPit(building)) - out << " (pit)."; + if(isPitPond(building)) + out << " (pit/pond)."; if(isPenPasture(building)) out << " (pen/pasture)."; out << endl; @@ -1341,10 +1341,14 @@ void zoneInfo(color_ostream & out, df::building* building, bool verbose) if(civ->zone_flags.bits.pen_pasture) out << ", pen/pasture"; - else if (civ->zone_flags.bits.pit_pond && civ->pit_flags==0) - out << ", pit"; - else - return; + else if (civ->zone_flags.bits.pit_pond) + { + out << " (pit flags:" << civ->pit_flags << ")"; + if(civ->pit_flags & 1) + out << ", pond"; + else + out << ", pit"; + } out << endl; out << "x1:" <x1 << " x2:" <x2