Update MapCache to allow decoding tiles underneath ice and constructions, and allow revflood to take those into account

develop
Quietust 2012-03-13 15:40:38 -05:00
parent 2725fe5568
commit a4ce1fff13
2 changed files with 132 additions and 78 deletions

@ -32,6 +32,7 @@ distribution.
#include <cstring> #include <cstring>
#include "df/map_block.h" #include "df/map_block.h"
#include "df/block_square_event_mineralst.h" #include "df/block_square_event_mineralst.h"
#include "df/construction.h"
using namespace DFHack; using namespace DFHack;
namespace MapExtras namespace MapExtras
{ {
@ -40,56 +41,78 @@ void SquashVeins (DFCoord bcoord, mapblock40d & mb, t_blockmaterials & materials
memset(materials,-1,sizeof(materials)); memset(materials,-1,sizeof(materials));
std::vector <df::block_square_event_mineralst *> veins; std::vector <df::block_square_event_mineralst *> veins;
Maps::SortBlockEvents(bcoord.x,bcoord.y,bcoord.z,&veins); Maps::SortBlockEvents(bcoord.x,bcoord.y,bcoord.z,&veins);
//iterate through block rows for (uint32_t x = 0;x<16;x++) for (uint32_t y = 0; y< 16;y++)
for(uint32_t j = 0;j<16;j++)
{ {
//iterate through columns df::tiletype tt = mb.tiletypes[x][y];
for (uint32_t k = 0; k< 16;k++) if (tileMaterial(tt) == tiletype_material::MINERAL)
{ {
df::tiletype tt = mb.tiletypes[k][j]; for (size_t i = 0; i < veins.size(); i++)
if(DFHack::tileMaterial(tt) == tiletype_material::MINERAL)
{ {
for(int i = (int) veins.size() - 1; i >= 0;i--) if (veins[i]->getassignment(x,y))
{ {
if(!!(((1 << k) & veins[i]->tile_bitmask[j]) >> k)) materials[x][y] = veins[i]->inorganic_mat;
{ break;
materials[k][j] = veins[i]->inorganic_mat;
i = -1;
}
} }
} }
} }
} }
} }
void SquashRocks ( std::vector< std::vector <uint16_t> > * layerassign, DFHack::mapblock40d & mb, DFHack::t_blockmaterials & materials) void SquashFrozenLiquids (DFCoord bcoord, mapblock40d & mb, tiletypes40d & frozen)
{ {
// get the layer materials std::vector <df::block_square_event_frozen_liquidst *> ices;
for(uint32_t xx = 0;xx<16;xx++) Maps::SortBlockEvents(bcoord.x,bcoord.y,bcoord.z,NULL,&ices);
for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
{
df::tiletype tt = mb.tiletypes[x][y];
frozen[x][y] = tiletype::Void;
if (tileMaterial(tt) == tiletype_material::FROZEN_LIQUID)
{ {
for (uint32_t yy = 0; yy< 16;yy++) for (size_t i = 0; i < ices.size(); i++)
{ {
uint8_t test = mb.designation[xx][yy].bits.biome; df::tiletype tt2 = ices[i]->tiles[x][y];
if( test >= sizeof(mb.biome_indices)) if (tt2 != tiletype::Void)
{ {
materials[xx][yy] = -1; frozen[x][y] = tt2;
continue; break;
}
}
}
} }
if (mb.biome_indices[test] >= layerassign->size()) }
void SquashConstructions (DFCoord bcoord, mapblock40d & mb, tiletypes40d & constructions)
{
for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
{
df::tiletype tt = mb.tiletypes[x][y];
constructions[x][y] = tiletype::Void;
if (tileMaterial(tt) == tiletype_material::CONSTRUCTION)
{ {
materials[xx][yy] = -1; DFCoord coord(bcoord.x*16 + x, bcoord.y*16 + y, bcoord.z);
continue; df::construction *con = df::construction::find(coord);
if (con)
constructions[x][y] = con->original_tile;
} }
materials[xx][yy] =
layerassign->at(mb.biome_indices[test])[mb.designation[xx][yy].bits.geolayer_index];
} }
} }
void SquashRocks ( std::vector< std::vector <uint16_t> > * layerassign, mapblock40d & mb, t_blockmaterials & materials)
{
// get the layer materials
for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
{
materials[x][y] = -1;
uint8_t test = mb.designation[x][y].bits.biome;
if ((test < sizeof(mb.biome_indices)) && (mb.biome_indices[test] < layerassign->size()))
materials[x][y] = layerassign->at(mb.biome_indices[test])[mb.designation[x][y].bits.geolayer_index];
}
} }
class Block class Block
{ {
public: public:
Block(DFHack::DFCoord _bcoord, std::vector< std::vector <uint16_t> > * layerassign = 0) Block(DFCoord _bcoord, std::vector< std::vector <uint16_t> > * layerassign = 0)
{ {
dirty_designations = false; dirty_designations = false;
dirty_tiletypes = false; dirty_tiletypes = false;
@ -102,6 +125,8 @@ class Block
{ {
Maps::ReadTemperatures(bcoord.x,bcoord.y, bcoord.z,&temp1,&temp2); Maps::ReadTemperatures(bcoord.x,bcoord.y, bcoord.z,&temp1,&temp2);
SquashVeins(bcoord,raw,veinmats); SquashVeins(bcoord,raw,veinmats);
SquashConstructions(bcoord, raw, contiles);
SquashFrozenLiquids(bcoord, raw, icetiles);
if(layerassign) if(layerassign)
SquashRocks(layerassign,raw,basemats); SquashRocks(layerassign,raw,basemats);
else else
@ -122,6 +147,15 @@ class Block
veinmats[p.x][p.y] = -1; veinmats[p.x][p.y] = -1;
} }
df::tiletype BaseTileTypeAt(df::coord2d p)
{
if (contiles[p.x][p.y] != tiletype::Void)
return contiles[p.x][p.y];
else if (icetiles[p.x][p.y] != tiletype::Void)
return icetiles[p.x][p.y];
else
return raw.tiletypes[p.x][p.y];
}
df::tiletype TileTypeAt(df::coord2d p) df::tiletype TileTypeAt(df::coord2d p)
{ {
return raw.tiletypes[p.x][p.y]; return raw.tiletypes[p.x][p.y];
@ -189,11 +223,11 @@ class Block
return true; return true;
} }
DFHack::t_blockflags BlockFlags() t_blockflags BlockFlags()
{ {
return raw.blockflags; return raw.blockflags;
} }
bool setBlockFlags(DFHack::t_blockflags des) bool setBlockFlags(t_blockflags des)
{ {
if(!valid) return false; if(!valid) return false;
dirty_blockflags = true; dirty_blockflags = true;
@ -239,12 +273,14 @@ class Block
bool dirty_temperatures:1; bool dirty_temperatures:1;
bool dirty_blockflags:1; bool dirty_blockflags:1;
bool dirty_occupancies:1; bool dirty_occupancies:1;
DFHack::mapblock40d raw; mapblock40d raw;
DFHack::DFCoord bcoord; DFCoord bcoord;
DFHack::t_blockmaterials veinmats; t_blockmaterials veinmats;
DFHack::t_blockmaterials basemats; t_blockmaterials basemats;
DFHack::t_temperatures temp1; t_temperatures temp1;
DFHack::t_temperatures temp2; t_temperatures temp2;
tiletypes40d contiles; // what's underneath constructions
tiletypes40d icetiles; // what's underneath ice
}; };
class MapCache class MapCache
@ -266,18 +302,20 @@ class MapCache
return valid; return valid;
} }
/// get the map block at a *block* coord. Block coord = tile coord / 16 /// get the map block at a *block* coord. Block coord = tile coord / 16
Block * BlockAt (DFHack::DFCoord blockcoord) Block * BlockAt (DFCoord blockcoord)
{ {
if(!valid) if(!valid)
return 0; return 0;
std::map <DFHack::DFCoord, Block*>::iterator iter = blocks.find(blockcoord); std::map <DFCoord, Block*>::iterator iter = blocks.find(blockcoord);
if(iter != blocks.end()) if(iter != blocks.end())
{ {
return (*iter).second; return (*iter).second;
} }
else else
{ {
if(blockcoord.x < x_bmax && blockcoord.y < y_bmax && blockcoord.z < z_max) if(blockcoord.x >= 0 && blockcoord.x < x_bmax &&
blockcoord.y >= 0 && blockcoord.y < y_bmax &&
blockcoord.z >= 0 && blockcoord.z < z_max)
{ {
Block * nblo; Block * nblo;
if(validgeo) if(validgeo)
@ -290,7 +328,16 @@ class MapCache
return 0; return 0;
} }
} }
df::tiletype tiletypeAt (DFHack::DFCoord tilecoord) df::tiletype baseTiletypeAt (DFCoord tilecoord)
{
Block * b= BlockAt(tilecoord / 16);
if(b && b->valid)
{
return b->BaseTileTypeAt(tilecoord % 16);
}
return tiletype::Void;
}
df::tiletype tiletypeAt (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)
@ -299,7 +346,7 @@ class MapCache
} }
return tiletype::Void; return tiletype::Void;
} }
bool setTiletypeAt(DFHack::DFCoord tilecoord, df::tiletype tiletype) bool setTiletypeAt(DFCoord tilecoord, df::tiletype tiletype)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)
@ -310,7 +357,7 @@ class MapCache
return false; return false;
} }
uint16_t temperature1At (DFHack::DFCoord tilecoord) uint16_t temperature1At (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)
@ -319,7 +366,7 @@ class MapCache
} }
return 0; return 0;
} }
bool setTemp1At(DFHack::DFCoord tilecoord, uint16_t temperature) bool setTemp1At(DFCoord tilecoord, uint16_t temperature)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)
@ -330,7 +377,7 @@ class MapCache
return false; return false;
} }
uint16_t temperature2At (DFHack::DFCoord tilecoord) uint16_t temperature2At (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)
@ -339,7 +386,7 @@ class MapCache
} }
return 0; return 0;
} }
bool setTemp2At(DFHack::DFCoord tilecoord, uint16_t temperature) bool setTemp2At(DFCoord tilecoord, uint16_t temperature)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)
@ -350,7 +397,7 @@ class MapCache
return false; return false;
} }
int16_t veinMaterialAt (DFHack::DFCoord tilecoord) int16_t veinMaterialAt (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)
@ -359,7 +406,7 @@ class MapCache
} }
return 0; return 0;
} }
int16_t baseMaterialAt (DFHack::DFCoord tilecoord) int16_t baseMaterialAt (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)
@ -368,7 +415,7 @@ class MapCache
} }
return 0; return 0;
} }
bool clearMaterialAt (DFHack::DFCoord tilecoord) bool clearMaterialAt (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)
@ -378,7 +425,7 @@ class MapCache
return 0; return 0;
} }
df::tile_designation designationAt (DFHack::DFCoord tilecoord) df::tile_designation designationAt (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)
@ -389,7 +436,7 @@ class MapCache
temp.whole = 0; temp.whole = 0;
return temp; return temp;
} }
bool setDesignationAt (DFHack::DFCoord tilecoord, df::tile_designation des) bool setDesignationAt (DFCoord tilecoord, df::tile_designation des)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)
@ -400,7 +447,7 @@ class MapCache
return false; return false;
} }
df::tile_occupancy occupancyAt (DFHack::DFCoord tilecoord) df::tile_occupancy occupancyAt (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)
@ -411,7 +458,7 @@ class MapCache
temp.whole = 0; temp.whole = 0;
return temp; return temp;
} }
bool setOccupancyAt (DFHack::DFCoord tilecoord, df::tile_occupancy occ) bool setOccupancyAt (DFCoord tilecoord, df::tile_occupancy occ)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)
@ -422,7 +469,7 @@ class MapCache
return false; return false;
} }
bool testCoord (DFHack::DFCoord tilecoord) bool testCoord (DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)
@ -433,7 +480,7 @@ class MapCache
} }
bool WriteAll() bool WriteAll()
{ {
std::map<DFHack::DFCoord, Block *>::iterator p; std::map<DFCoord, Block *>::iterator p;
for(p = blocks.begin(); p != blocks.end(); p++) for(p = blocks.begin(); p != blocks.end(); p++)
{ {
p->second->Write(); p->second->Write();
@ -442,7 +489,7 @@ class MapCache
} }
void trash() void trash()
{ {
std::map<DFHack::DFCoord, Block *>::iterator p; std::map<DFCoord, Block *>::iterator p;
for(p = blocks.begin(); p != blocks.end(); p++) for(p = blocks.begin(); p != blocks.end(); p++)
{ {
delete p->second; delete p->second;
@ -458,7 +505,7 @@ class MapCache
uint32_t y_tmax; uint32_t y_tmax;
uint32_t z_max; uint32_t z_max;
std::vector< std::vector <uint16_t> > layerassign; std::vector< std::vector <uint16_t> > layerassign;
std::map<DFHack::DFCoord, Block *> blocks; std::map<DFCoord, Block *> blocks;
}; };
} }
#endif #endif

@ -10,9 +10,16 @@
#include "modules/World.h" #include "modules/World.h"
#include "modules/MapCache.h" #include "modules/MapCache.h"
#include "modules/Gui.h" #include "modules/Gui.h"
#include "df/construction.h"
#include "df/block_square_event_frozen_liquidst.h"
using MapExtras::MapCache; using MapExtras::MapCache;
using std::string;
using std::vector;
using namespace DFHack; using namespace DFHack;
using namespace df::enums; using namespace df::enums;
using df::global::world; using df::global::world;
/* /*
@ -20,8 +27,8 @@ using df::global::world;
*/ */
bool isSafe(df::coord c) bool isSafe(df::coord c)
{ {
DFHack::t_feature local_feature; t_feature local_feature;
DFHack::t_feature global_feature; t_feature global_feature;
// get features of block // get features of block
// error -> obviously not safe to manipulate // error -> obviously not safe to manipulate
if(!Maps::ReadFeatures(c.x >> 4,c.y >> 4,c.z,&local_feature,&global_feature)) if(!Maps::ReadFeatures(c.x >> 4,c.y >> 4,c.z,&local_feature,&global_feature))
@ -45,7 +52,7 @@ struct hideblock
// the saved data. we keep map size to check if things still match // the saved data. we keep map size to check if things still match
uint32_t x_max, y_max, z_max; uint32_t x_max, y_max, z_max;
std::vector <hideblock> hidesaved; vector <hideblock> hidesaved;
bool nopause_state = false; bool nopause_state = false;
enum revealstate enum revealstate
@ -58,16 +65,16 @@ enum revealstate
revealstate revealed = NOT_REVEALED; revealstate revealed = NOT_REVEALED;
command_result reveal(color_ostream &out, std::vector<std::string> & params); command_result reveal(color_ostream &out, vector<string> & params);
command_result unreveal(color_ostream &out, std::vector<std::string> & params); command_result unreveal(color_ostream &out, vector<string> & params);
command_result revtoggle(color_ostream &out, std::vector<std::string> & params); command_result revtoggle(color_ostream &out, vector<string> & params);
command_result revflood(color_ostream &out, std::vector<std::string> & params); command_result revflood(color_ostream &out, vector<string> & params);
command_result revforget(color_ostream &out, std::vector<std::string> & params); command_result revforget(color_ostream &out, vector<string> & params);
command_result nopause(color_ostream &out, std::vector<std::string> & params); command_result nopause(color_ostream &out, vector<string> & params);
DFHACK_PLUGIN("reveal"); DFHACK_PLUGIN("reveal");
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, vector <PluginCommand> &commands)
{ {
commands.clear(); commands.clear();
commands.push_back(PluginCommand("reveal","Reveal the map. 'reveal hell' will also reveal hell. 'reveal demon' won't pause.",reveal)); commands.push_back(PluginCommand("reveal","Reveal the map. 'reveal hell' will also reveal hell. 'reveal demon' won't pause.",reveal));
@ -81,7 +88,7 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <Plug
DFhackCExport command_result plugin_onupdate ( color_ostream &out ) DFhackCExport command_result plugin_onupdate ( color_ostream &out )
{ {
DFHack::World *World = Core::getInstance().getWorld(); World *World = Core::getInstance().getWorld();
t_gamemodes gm; t_gamemodes gm;
World->ReadGameMode(gm); World->ReadGameMode(gm);
if(gm.g_mode == GAMEMODE_DWARF) if(gm.g_mode == GAMEMODE_DWARF)
@ -104,7 +111,7 @@ DFhackCExport command_result plugin_shutdown ( color_ostream &out )
return CR_OK; return CR_OK;
} }
command_result nopause (color_ostream &out, std::vector <std::string> & parameters) command_result nopause (color_ostream &out, vector <string> & parameters)
{ {
if (parameters.size() == 1 && (parameters[0] == "0" || parameters[0] == "1")) if (parameters.size() == 1 && (parameters[0] == "0" || parameters[0] == "1"))
{ {
@ -130,7 +137,7 @@ void revealAdventure(color_ostream &out)
// in 'no-hell'/'safe' mode, don't reveal blocks with hell and adamantine // in 'no-hell'/'safe' mode, don't reveal blocks with hell and adamantine
if (!isSafe(block->map_pos)) if (!isSafe(block->map_pos))
continue; continue;
DFHack::designations40d & designations = block->designation; designations40d & designations = block->designation;
// for each tile in block // for each tile in block
for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++) for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
{ {
@ -143,7 +150,7 @@ void revealAdventure(color_ostream &out)
out.print("Local map revealed.\n"); out.print("Local map revealed.\n");
} }
command_result reveal(color_ostream &out, std::vector<std::string> & params) command_result reveal(color_ostream &out, vector<string> & params)
{ {
bool no_hell = true; bool no_hell = true;
bool pause = true; bool pause = true;
@ -179,7 +186,7 @@ command_result reveal(color_ostream &out, std::vector<std::string> & params)
CoreSuspender suspend; CoreSuspender suspend;
DFHack::World *World = Core::getInstance().getWorld(); World *World = Core::getInstance().getWorld();
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
out.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
@ -208,7 +215,7 @@ command_result reveal(color_ostream &out, std::vector<std::string> & params)
continue; continue;
hideblock hb; hideblock hb;
hb.c = block->map_pos; hb.c = block->map_pos;
DFHack::designations40d & designations = block->designation; designations40d & designations = block->designation;
// for each tile in block // for each tile in block
for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++) for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
{ {
@ -240,7 +247,7 @@ command_result reveal(color_ostream &out, std::vector<std::string> & params)
return CR_OK; return CR_OK;
} }
command_result unreveal(color_ostream &out, std::vector<std::string> & params) command_result unreveal(color_ostream &out, vector<string> & params)
{ {
auto & con = out; auto & con = out;
for(size_t i = 0; i < params.size();i++) for(size_t i = 0; i < params.size();i++)
@ -258,7 +265,7 @@ command_result unreveal(color_ostream &out, std::vector<std::string> & params)
} }
CoreSuspender suspend; CoreSuspender suspend;
DFHack::World *World = Core::getInstance().getWorld(); World *World = Core::getInstance().getWorld();
if (!Maps::IsValid()) if (!Maps::IsValid())
{ {
out.printerr("Map is not available!\n"); out.printerr("Map is not available!\n");
@ -297,7 +304,7 @@ command_result unreveal(color_ostream &out, std::vector<std::string> & params)
return CR_OK; return CR_OK;
} }
command_result revtoggle (color_ostream &out, std::vector<std::string> & params) command_result revtoggle (color_ostream &out, vector<string> & params)
{ {
for(size_t i = 0; i < params.size();i++) for(size_t i = 0; i < params.size();i++)
{ {
@ -317,7 +324,7 @@ command_result revtoggle (color_ostream &out, std::vector<std::string> & params)
} }
} }
command_result revflood(color_ostream &out, std::vector<std::string> & params) command_result revflood(color_ostream &out, vector<string> & params)
{ {
for(size_t i = 0; i < params.size();i++) for(size_t i = 0; i < params.size();i++)
{ {
@ -396,7 +403,7 @@ command_result revflood(color_ostream &out, std::vector<std::string> & params)
if(!MCache->testCoord(current)) if(!MCache->testCoord(current))
continue; continue;
df::tiletype tt = MCache->tiletypeAt(current); df::tiletype tt = MCache->baseTiletypeAt(current);
df::tile_designation des = MCache->designationAt(current); df::tile_designation des = MCache->designationAt(current);
if(!des.bits.hidden) if(!des.bits.hidden)
{ {
@ -469,7 +476,7 @@ command_result revflood(color_ostream &out, std::vector<std::string> & params)
return CR_OK; return CR_OK;
} }
command_result revforget(color_ostream &out, std::vector<std::string> & params) command_result revforget(color_ostream &out, vector<string> & params)
{ {
auto & con = out; auto & con = out;
for(size_t i = 0; i < params.size();i++) for(size_t i = 0; i < params.size();i++)