zone: fixed assigning to pit/pond. regrass: look for grass events in the map block, increase amount of grass at map position instead of simply changing the tile type

develop
Robert Heinrich 2012-04-11 14:08:47 +02:00
parent 7d0cfb7e80
commit ae7ce9e5d7
2 changed files with 96 additions and 34 deletions

@ -8,19 +8,47 @@
#include "DataDefs.h" #include "DataDefs.h"
#include "df/world.h" #include "df/world.h"
#include "df/world_raws.h"
#include "df/plant_raw.h"
#include "df/map_block.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" #include "TileTypes.h"
using std::string; using std::string;
using std::vector; using std::vector;
using namespace std;
using namespace DFHack; using namespace DFHack;
using df::global::world; using df::global::world;
DFHACK_PLUGIN("regrass");
command_result df_regrass (color_ostream &out, vector <string> & parameters);
DFhackCExport command_result plugin_init (color_ostream &out, std::vector<PluginCommand> &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 <string> & parameters) command_result df_regrass (color_ostream &out, vector <string> & parameters)
{ {
bool max = false;
if (!parameters.empty()) if (!parameters.empty())
return CR_WRONG_USAGE; {
if(parameters[0] == "max")
max = true;
else
return CR_WRONG_USAGE;
}
CoreSuspender suspend; CoreSuspender suspend;
@ -28,19 +56,62 @@ command_result df_regrass (color_ostream &out, vector <string> & parameters)
for (size_t i = 0; i < world->map.map_blocks.size(); i++) for (size_t i = 0; i < world->map.map_blocks.size(); i++)
{ {
df::map_block *cur = world->map.map_blocks[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; e<cur->block_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) if ( tileShape(cur->tiletype[x][y]) != tiletype_shape::FLOOR
continue; || cur->designation[x][y].bits.subterranean
if (tileMaterial(cur->tiletype[x][y]) != tiletype_material::SOIL) || cur->occupancy[x][y].bits.building)
continue; continue;
if (cur->designation[x][y].bits.subterranean)
continue; int mat = tileMaterial(cur->tiletype[x][y]);
if (cur->occupancy[x][y].bits.building) if ( mat != tiletype_material::SOIL
&& mat != tiletype_material::GRASS_DARK // refill existing grass, too
&& mat != tiletype_material::GRASS_LIGHT // refill existing grass, too
)
continue; continue;
// max = set amounts of all grass events on that tile to 100
if(max)
{
for(size_t e=0; e<cur->block_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); cur->tiletype[x][y] = findRandomVariant((rand() & 1) ? tiletype::GrassLightFloor1 : tiletype::GrassDarkFloor1);
count++; count++;
} }
@ -51,16 +122,3 @@ command_result df_regrass (color_ostream &out, vector <string> & parameters)
out.print("Regrew %d tiles of grass.\n", count); out.print("Regrew %d tiles of grass.\n", count);
return CR_OK; return CR_OK;
} }
DFHACK_PLUGIN("regrass");
DFhackCExport command_result plugin_init (color_ostream &out, std::vector<PluginCommand> &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;
}

@ -341,7 +341,7 @@ bool isForest(df::unit* creature);
bool isActivityZone(df::building * building); bool isActivityZone(df::building * building);
bool isPenPasture(df::building * building); bool isPenPasture(df::building * building);
bool isPit(df::building * building); bool isPitPond(df::building * building);
bool isActive(df::building * building); bool isActive(df::building * building);
int32_t findBuildingIndexById(int32_t id); int32_t findBuildingIndexById(int32_t id);
@ -727,14 +727,14 @@ bool isPenPasture(df::building * building)
return false; return false;
} }
bool isPit(df::building * building) bool isPitPond(df::building * building)
{ {
if(!isActivityZone(building)) if(!isActivityZone(building))
return false; return false;
df::building_civzonest * civ = (df::building_civzonest *) building; 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; return true;
else else
return false; return false;
@ -790,7 +790,7 @@ int32_t findPenPitAtCursor()
building->z == cursor->z)) building->z == cursor->z))
continue; continue;
if(isPenPasture(building) || isPit(building)) if(isPenPasture(building) || isPitPond(building))
{ {
foundID = building->id; foundID = building->id;
break; 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) command_result assignUnitToZone(color_ostream& out, df::unit* unit, df::building* building, bool verbose = false)
{ {
// building must be a pen/pasture or pit // 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; return CR_WRONG_USAGE;
} }
@ -1238,8 +1238,8 @@ command_result assignUnitToZone(color_ostream& out, df::unit* unit, df::building
out << "Unit " << unit->id out << "Unit " << unit->id
<< "(" << getRaceName(unit) << ")" << "(" << getRaceName(unit) << ")"
<< " assigned to zone " << building->id; << " assigned to zone " << building->id;
if(isPit(building)) if(isPitPond(building))
out << " (pit)."; out << " (pit/pond).";
if(isPenPasture(building)) if(isPenPasture(building))
out << " (pen/pasture)."; out << " (pen/pasture).";
out << endl; out << endl;
@ -1341,10 +1341,14 @@ void zoneInfo(color_ostream & out, df::building* building, bool verbose)
if(civ->zone_flags.bits.pen_pasture) if(civ->zone_flags.bits.pen_pasture)
out << ", pen/pasture"; out << ", pen/pasture";
else if (civ->zone_flags.bits.pit_pond && civ->pit_flags==0) else if (civ->zone_flags.bits.pit_pond)
out << ", pit"; {
else out << " (pit flags:" << civ->pit_flags << ")";
return; if(civ->pit_flags & 1)
out << ", pond";
else
out << ", pit";
}
out << endl; out << endl;
out << "x1:" <<building->x1 out << "x1:" <<building->x1
<< " x2:" <<building->x2 << " x2:" <<building->x2