Update deramp plugin, no longer relies on modules

develop
Quietust 2012-01-11 09:53:48 -06:00
parent 524b53935d
commit 9cc774fc9d
1 changed files with 76 additions and 120 deletions

@ -1,158 +1,114 @@
// De-ramp. All ramps marked for removal are replaced with given tile (presently, normal floor). // De-ramp. All ramps marked for removal are replaced with given tile (presently, normal floor).
#include <iostream>
#include <vector>
#include <map>
#include <stddef.h>
#include <assert.h>
#include <string.h>
using namespace std;
#include "Core.h" #include "Core.h"
#include <Console.h> #include <Console.h>
#include <Export.h> #include <Export.h>
#include <PluginManager.h> #include <PluginManager.h>
#include <modules/Maps.h>
#include <TileTypes.h>
using namespace DFHack;
DFhackCExport command_result df_deramp (Core * c, vector <string> & parameters); #include "DataDefs.h"
#include "df/world.h"
#include "df/map_block.h"
#include "df/tile_dig_designation.h"
#include <TileTypes.h>
DFhackCExport const char * plugin_name ( void ) using std::vector;
{ using std::string;
return "deramp"; using namespace DFHack;
}
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands) using df::global::world;
{ using namespace DFHack;
commands.clear();
commands.push_back(PluginCommand("deramp",
"De-ramp. All ramps marked for removal are replaced with floors.",
df_deramp));
return CR_OK;
}
DFhackCExport command_result plugin_shutdown ( Core * c ) // This is slightly different from what's in the Maps module - it takes tile coordinates rather than block coordinates
df::map_block *getBlock (int32_t x, int32_t y, int32_t z)
{ {
return CR_OK; if ((x < 0) || (y < 0) || (z < 0))
return NULL;
if ((x >= world->map.x_count) || (y >= world->map.y_count) || (z >= world->map.z_count))
return NULL;
return world->map.block_index[x >> 4][y >> 4][z];
} }
DFhackCExport command_result df_deramp (Core * c, vector <string> & parameters) DFhackCExport command_result df_deramp (Core * c, vector <string> & parameters)
{ {
uint32_t x_max,y_max,z_max;
uint32_t num_blocks = 0;
uint32_t bytes_read = 0;
DFHack::designations40d designations;
DFHack::tiletypes40d tiles;
DFHack::tiletypes40d tilesAbove;
//DFHack::TileRow *ptile;
int32_t oldT, newT;
bool dirty= false;
int count=0;
int countbad=0;
for(int i = 0; i < parameters.size();i++) for(int i = 0; i < parameters.size();i++)
{ {
if(parameters[i] == "help" || parameters[i] == "?") if(parameters[i] == "help" || parameters[i] == "?")
{ {
c->con.print("This command does two things:\n" c->con.print("This command does two things:\n"
"If there are any ramps designated for removal, they will be instantly removed.\n" "If there are any ramps designated for removal, they will be instantly removed.\n"
"Any ramps that don't have their counterpart will be removed (fixes bugs with caveins)\n" "Any ramps that don't have their counterpart will be removed (fixes bugs with caveins)\n"
); );
return CR_OK; return CR_OK;
} }
} }
c->Suspend();
DFHack::Maps *Mapz = c->getMaps();
// init the map
if (!Mapz->Start())
{
c->con.printerr("Can't init map.\n");
c->Resume();
return CR_FAILURE;
}
Mapz->getSize(x_max,y_max,z_max); CoreSuspender suspend(c);
uint8_t zeroes [16][16] = {0}; int count = 0;
int countbad = 0;
// walk the map int num_blocks = 0, blocks_total = world->map.map_blocks.size();
for (uint32_t x = 0; x< x_max;x++) for (int i = 0; i < blocks_total; i++)
{ {
for (uint32_t y = 0; y< y_max;y++) df::map_block *block = world->map.map_blocks[i];
df::map_block *above = getBlock(block->map_x, block->map_y, block->map_z + 1);
for (int x = 0; x < 16; x++)
{ {
for (uint32_t z = 0; z< z_max;z++) for (int y = 0; y < 16; y++)
{ {
if (Mapz->getBlock(x,y,z)) int16_t oldT = block->tiletype[x][y];
if ((tileShape(oldT) == RAMP) &&
(block->designation[x][y].bits.dig == df::tile_dig_designation::Default))
{ {
dirty= false; // Current tile is a ramp.
Mapz->ReadDesignations(x,y,z, &designations); // Set current tile, as accurately as can be expected
Mapz->ReadTileTypes(x,y,z, &tiles); int16_t newT = findSimilarTileType(oldT, FLOOR);
if (Mapz->getBlock(x,y,z+1))
{
Mapz->ReadTileTypes(x,y,z+1, &tilesAbove);
}
else
{
memset(&tilesAbove,0,sizeof(tilesAbove));
}
for (uint32_t ty=0;ty<16;++ty)
{
for (uint32_t tx=0;tx<16;++tx)
{
//Only the remove ramp designation (ignore channel designation, etc)
oldT = tiles[tx][ty];
if ( DFHack::designation_default == designations[tx][ty].bits.dig
&& DFHack::RAMP==DFHack::tileShape(oldT))
{
//Current tile is a ramp.
//Set current tile, as accurately as can be expected
newT = DFHack::findSimilarTileType(oldT,DFHack::FLOOR);
//If no change, skip it (couldn't find a good tile type) // If no change, skip it (couldn't find a good tile type)
if ( oldT == newT) continue; if (oldT == newT)
//Set new tile type, clear designation continue;
tiles[tx][ty] = newT; // Set new tile type, clear designation
designations[tx][ty].bits.dig = DFHack::designation_no; block->tiletype[x][y] = newT;
block->designation[x][y].bits.dig = df::tile_dig_designation::No;
//Check the tile above this one, in case a downward slope needs to be removed. // Check the tile above this one, in case a downward slope needs to be removed.
if ( DFHack::RAMP_TOP == DFHack::tileShape(tilesAbove[tx][ty]) ) if ((above) && (tileShape(above->tiletype[x][y]) == RAMP_TOP))
{ above->tiletype[x][y] = 32; // open space
tilesAbove[tx][ty] = 32; count++;
} }
dirty= true; // ramp fixer
++count; else if ((tileShape(oldT) != RAMP)
} && (above) && (tileShape(above->tiletype[x][y]) == RAMP_TOP))
// ramp fixer {
else if(DFHack::RAMP!=DFHack::tileShape(oldT) && DFHack::RAMP_TOP == DFHack::tileShape(tilesAbove[tx][ty])) above->tiletype[x][y] = 32; // open space
{ countbad++;
tilesAbove[tx][ty] = 32;
countbad++;
dirty = true;
}
}
}
//If anything was changed, write it all.
if (dirty)
{
Mapz->WriteDesignations(x,y,z, &designations);
Mapz->WriteTileTypes(x,y,z, &tiles);
if (Mapz->getBlock(x,y,z+1))
{
Mapz->WriteTileTypes(x,y,z+1, &tilesAbove);
}
dirty = false;
}
} }
} }
} }
} }
c->Resume(); if (count)
if(count) c->con.print("Found and changed %d tiles.\n", count);
c->con.print("Found and changed %d tiles.\n",count); if (countbad)
if(countbad) c->con.print("Fixed %d bad down ramps.\n", countbad);
c->con.print("Fixed %d bad down ramps.\n",countbad); return CR_OK;
}
DFhackCExport const char * plugin_name ( void )
{
return "deramp";
}
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands)
{
commands.clear();
commands.push_back(PluginCommand("deramp",
"De-ramp. All ramps marked for removal are replaced with floors.",
df_deramp));
return CR_OK;
}
DFhackCExport command_result plugin_shutdown ( Core * c )
{
return CR_OK; return CR_OK;
} }