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

@ -10,9 +10,16 @@
#include "modules/World.h"
#include "modules/MapCache.h"
#include "modules/Gui.h"
#include "df/construction.h"
#include "df/block_square_event_frozen_liquidst.h"
using MapExtras::MapCache;
using std::string;
using std::vector;
using namespace DFHack;
using namespace df::enums;
using df::global::world;
/*
@ -20,8 +27,8 @@ using df::global::world;
*/
bool isSafe(df::coord c)
{
DFHack::t_feature local_feature;
DFHack::t_feature global_feature;
t_feature local_feature;
t_feature global_feature;
// get features of block
// error -> obviously not safe to manipulate
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
uint32_t x_max, y_max, z_max;
std::vector <hideblock> hidesaved;
vector <hideblock> hidesaved;
bool nopause_state = false;
enum revealstate
@ -58,16 +65,16 @@ enum revealstate
revealstate revealed = NOT_REVEALED;
command_result reveal(color_ostream &out, std::vector<std::string> & params);
command_result unreveal(color_ostream &out, std::vector<std::string> & params);
command_result revtoggle(color_ostream &out, std::vector<std::string> & params);
command_result revflood(color_ostream &out, std::vector<std::string> & params);
command_result revforget(color_ostream &out, std::vector<std::string> & params);
command_result nopause(color_ostream &out, std::vector<std::string> & params);
command_result reveal(color_ostream &out, vector<string> & params);
command_result unreveal(color_ostream &out, vector<string> & params);
command_result revtoggle(color_ostream &out, vector<string> & params);
command_result revflood(color_ostream &out, vector<string> & params);
command_result revforget(color_ostream &out, vector<string> & params);
command_result nopause(color_ostream &out, vector<string> & params);
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.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 )
{
DFHack::World *World = Core::getInstance().getWorld();
World *World = Core::getInstance().getWorld();
t_gamemodes gm;
World->ReadGameMode(gm);
if(gm.g_mode == GAMEMODE_DWARF)
@ -104,7 +111,7 @@ DFhackCExport command_result plugin_shutdown ( color_ostream &out )
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"))
{
@ -130,7 +137,7 @@ void revealAdventure(color_ostream &out)
// in 'no-hell'/'safe' mode, don't reveal blocks with hell and adamantine
if (!isSafe(block->map_pos))
continue;
DFHack::designations40d & designations = block->designation;
designations40d & designations = block->designation;
// for each tile in block
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");
}
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 pause = true;
@ -179,7 +186,7 @@ command_result reveal(color_ostream &out, std::vector<std::string> & params)
CoreSuspender suspend;
DFHack::World *World = Core::getInstance().getWorld();
World *World = Core::getInstance().getWorld();
if (!Maps::IsValid())
{
out.printerr("Map is not available!\n");
@ -208,7 +215,7 @@ command_result reveal(color_ostream &out, std::vector<std::string> & params)
continue;
hideblock hb;
hb.c = block->map_pos;
DFHack::designations40d & designations = block->designation;
designations40d & designations = block->designation;
// for each tile in block
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;
}
command_result unreveal(color_ostream &out, std::vector<std::string> & params)
command_result unreveal(color_ostream &out, vector<string> & params)
{
auto & con = out;
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;
DFHack::World *World = Core::getInstance().getWorld();
World *World = Core::getInstance().getWorld();
if (!Maps::IsValid())
{
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;
}
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++)
{
@ -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++)
{
@ -396,7 +403,7 @@ command_result revflood(color_ostream &out, std::vector<std::string> & params)
if(!MCache->testCoord(current))
continue;
df::tiletype tt = MCache->tiletypeAt(current);
df::tiletype tt = MCache->baseTiletypeAt(current);
df::tile_designation des = MCache->designationAt(current);
if(!des.bits.hidden)
{
@ -469,7 +476,7 @@ command_result revflood(color_ostream &out, std::vector<std::string> & params)
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;
for(size_t i = 0; i < params.size();i++)