125 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
			
		
		
	
	
			125 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
| // All above-ground soil not covered by buildings will be covered with grass.
 | |
| // Necessary for worlds generated prior to version 0.31.19 - otherwise, outdoor shrubs and trees no longer grow.
 | |
| 
 | |
| #include "Core.h"
 | |
| #include "Console.h"
 | |
| #include "Export.h"
 | |
| #include "PluginManager.h"
 | |
| 
 | |
| #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 <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)
 | |
| {
 | |
|     bool max = false;
 | |
|     if (!parameters.empty())
 | |
|     {
 | |
|         if(parameters[0] == "max")
 | |
|             max = true;
 | |
|         else
 | |
|             return CR_WRONG_USAGE;
 | |
|     }
 | |
| 
 | |
|     CoreSuspender suspend;
 | |
| 
 | |
|     int count = 0;
 | |
|     for (size_t i = 0; i < world->map.map_blocks.size(); i++)
 | |
|     {
 | |
|         df::map_block *cur = world->map.map_blocks[i];
 | |
| 
 | |
|         // 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)
 | |
|         {
 | |
|             // 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
 | |
|                     || cur->designation[x][y].bits.subterranean
 | |
|                     || cur->occupancy[x][y].bits.building)
 | |
|                     continue;
 | |
| 
 | |
|                 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; 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);
 | |
|                 count++;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (count)
 | |
|         out.print("Regrew %d tiles of grass.\n", count);
 | |
|     return CR_OK;
 | |
| }
 |