Significant cleanup of Maps module - next step will be to kill it properly

develop
Quietust 2012-01-19 14:11:52 -06:00
parent e2d7359bdd
commit 4bb724cd6c
13 changed files with 319 additions and 883 deletions

@ -0,0 +1,19 @@
inline bool getassignment( DFCoord & xy )
{
return getassignment(xy.x,xy.y);
}
inline bool getassignment( int x, int y )
{
return (tile_bitmask[y] & (1 << x));
}
inline void setassignment( DFCoord & xy, bool bit )
{
return setassignment(xy.x,xy.y, bit);
}
inline void setassignment( int x, int y, bool bit )
{
if(bit)
tile_bitmask[y] |= (1 << x);
else
tile_bitmask[y] &= 0xFFFF ^ (1 << x);
}

@ -30,12 +30,14 @@ distribution.
#include "TileTypes.h" #include "TileTypes.h"
#include <stdint.h> #include <stdint.h>
#include <cstring> #include <cstring>
#include "df/map_block.h"
#include "df/block_square_event_mineralst.h"
namespace MapExtras namespace MapExtras
{ {
void SquashVeins (DFHack::Maps *m, DFHack::DFCoord bcoord, DFHack::mapblock40d & mb, DFHack::t_blockmaterials & materials) void SquashVeins (DFHack::Maps *m, DFHack::DFCoord bcoord, DFHack::mapblock40d & mb, DFHack::t_blockmaterials & materials)
{ {
memset(materials,-1,sizeof(materials)); memset(materials,-1,sizeof(materials));
std::vector <DFHack::t_vein *> veins; std::vector <df::block_square_event_mineralst *> veins;
m->SortBlockEvents(bcoord.x,bcoord.y,bcoord.z,&veins); m->SortBlockEvents(bcoord.x,bcoord.y,bcoord.z,&veins);
//iterate through block rows //iterate through block rows
for(uint32_t j = 0;j<16;j++) for(uint32_t j = 0;j<16;j++)
@ -48,9 +50,9 @@ void SquashVeins (DFHack::Maps *m, DFHack::DFCoord bcoord, DFHack::mapblock40d &
{ {
for(int i = (int) veins.size() - 1; i >= 0;i--) for(int i = (int) veins.size() - 1; i >= 0;i--)
{ {
if(!!(((1 << k) & veins[i]->assignment[j]) >> k)) if(!!(((1 << k) & veins[i]->tile_bitmask[j]) >> k))
{ {
materials[k][j] = veins[i]->type; materials[k][j] = veins[i]->inorganic_mat;
i = -1; i = -1;
} }
} }
@ -152,11 +154,11 @@ class Block
return true; return true;
} }
DFHack::t_designation DesignationAt(DFHack::DFCoord p) df::tile_designation DesignationAt(DFHack::DFCoord p)
{ {
return raw.designation[p.x][p.y]; return raw.designation[p.x][p.y];
} }
bool setDesignationAt(DFHack::DFCoord p, DFHack::t_designation des) bool setDesignationAt(DFHack::DFCoord p, df::tile_designation des)
{ {
if(!valid) return false; if(!valid) return false;
dirty_designations = true; dirty_designations = true;
@ -170,11 +172,11 @@ class Block
return true; return true;
} }
DFHack::t_occupancy OccupancyAt(DFHack::DFCoord p) df::tile_occupancy OccupancyAt(DFHack::DFCoord p)
{ {
return raw.occupancy[p.x][p.y]; return raw.occupancy[p.x][p.y];
} }
bool setOccupancyAt(DFHack::DFCoord p, DFHack::t_occupancy des) bool setOccupancyAt(DFHack::DFCoord p, df::tile_occupancy des)
{ {
if(!valid) return false; if(!valid) return false;
dirty_occupancies = true; dirty_occupancies = true;
@ -373,18 +375,18 @@ class MapCache
return 0; return 0;
} }
DFHack::t_designation designationAt (DFHack::DFCoord tilecoord) df::tile_designation designationAt (DFHack::DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)
{ {
return b->DesignationAt(tilecoord % 16); return b->DesignationAt(tilecoord % 16);
} }
DFHack:: t_designation temp; df::tile_designation temp;
temp.whole = 0; temp.whole = 0;
return temp; return temp;
} }
bool setDesignationAt (DFHack::DFCoord tilecoord, DFHack::t_designation des) bool setDesignationAt (DFHack::DFCoord tilecoord, df::tile_designation des)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)
@ -395,18 +397,18 @@ class MapCache
return false; return false;
} }
DFHack::t_occupancy occupancyAt (DFHack::DFCoord tilecoord) df::tile_occupancy occupancyAt (DFHack::DFCoord tilecoord)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)
{ {
return b->OccupancyAt(tilecoord % 16); return b->OccupancyAt(tilecoord % 16);
} }
DFHack:: t_occupancy temp; df::tile_occupancy temp;
temp.whole = 0; temp.whole = 0;
return temp; return temp;
} }
bool setOccupancyAt (DFHack::DFCoord tilecoord, DFHack::t_occupancy occ) bool setOccupancyAt (DFHack::DFCoord tilecoord, df::tile_occupancy occ)
{ {
Block * b= BlockAt(tilecoord / 16); Block * b= BlockAt(tilecoord / 16);
if(b && b->valid) if(b && b->valid)

@ -36,7 +36,20 @@ distribution.
#include <vector> #include <vector>
#include "Virtual.h" #include "Virtual.h"
#include "BitArray.h" #include "BitArray.h"
#include "Materials.h" #include "modules/Materials.h"
#include "df/world.h"
#include "df/feature_type.h"
#include "df/map_block.h"
#include "df/block_square_event.h"
#include "df/block_square_event_mineralst.h"
#include "df/block_square_event_frozen_liquidst.h"
#include "df/block_square_event_world_constructionst.h"
#include "df/block_square_event_material_spatterst.h"
#include "df/block_square_event_grassst.h"
#include "df/tile_liquid.h"
#include "df/tile_dig_designation.h"
#include "df/tile_traffic.h"
/** /**
* \defgroup grp_maps Maps module and its types * \defgroup grp_maps Maps module and its types
@ -48,21 +61,11 @@ namespace DFHack
/*************************************************************************** /***************************************************************************
T Y P E S T Y P E S
***************************************************************************/ ***************************************************************************/
/**
* \ingroup grp_maps
*/
enum e_feature
{
feature_Other,
feature_Adamantine_Tube,
feature_Underworld,
feature_Hell_Temple
};
/** /**
* Function for translating feature index to its name * Function for translating feature index to its name
* \ingroup grp_maps * \ingroup grp_maps
*/ */
extern DFHACK_EXPORT const char * sa_feature(e_feature index); extern DFHACK_EXPORT const char * sa_feature(df::feature_type index);
/** /**
* Class for holding a world coordinate. Can do math with coordinates and can be used as an index for std::map * Class for holding a world coordinate. Can do math with coordinates and can be used as an index for std::map
@ -141,7 +144,7 @@ namespace DFHack
*/ */
struct t_feature struct t_feature
{ {
e_feature type; df::feature_type type;
/// main material type - decides between stuff like bodily fluids, inorganics, vomit, amber, etc. /// main material type - decides between stuff like bodily fluids, inorganics, vomit, amber, etc.
int16_t main_material; int16_t main_material;
/// generally some index to a vector of material types. /// generally some index to a vector of material types.
@ -152,97 +155,6 @@ namespace DFHack
void * origin; void * origin;
}; };
/**
* mineral vein object - bitmap with a material type
* \ingroup grp_maps
*/
struct t_vein : public t_virtual
{
/// index into the inorganic material vector
int32_t type;
/// bit mask describing how the vein maps to the map block
/// assignment[y] & (1 << x) describes the tile (x, y) of the block
int16_t assignment[16];
uint32_t flags; // FIXME: figure those out
//zilpin: Functions to more conveniently check the assignment flags of the vein.
//Coordinates are given in tile within the block.
//Important to make these inline.
inline bool getassignment( DFCoord & xy )
{
return getassignment(xy.x,xy.y);
}
inline bool getassignment( int x, int y )
{
return (assignment[y] & (1 << x));
}
inline void setassignment( DFCoord & xy, bool bit )
{
return setassignment(xy.x,xy.y, bit);
}
inline void setassignment( int x, int y, bool bit )
{
if(bit)
assignment[y] |= (1 << x);
else
assignment[y] &= 0xFFFF ^ (1 << x);
}
};
/**
* stores what tiles should appear when the ice melts - bitmap of material types
* \ingroup grp_maps
*/
struct t_frozenliquidvein : public t_virtual
{
/// a 16x16 array of the original tile types
int16_t tiles[16][16];
};
/**
* a 'spattervein' defines what coverings the individual map tiles have (snow, blood, etc)
* bitmap of intensity with matrial type
* \ingroup grp_maps
* @see PrintSplatterType
*/
struct t_spattervein : public t_virtual
{
/// generic material.
t_materialType mat1;
/// material vector index
t_materialIndex mat2;
/**
* matter state - liquid/solid/etc.
* @ref e_matter_state
*/
uint16_t matter_state;
/// 16x16 array of covering 'intensity'
uint8_t intensity[16][16];
};
/**
* a 'grass vein' defines the grass coverage of a map block
* bitmap of density (max = 100) with plant material type
* \ingroup grp_maps
*/
struct t_grassvein : public t_virtual
{
/// material vector index
t_materialIndex material;
/// 16x16 array of covering 'intensity'
uint8_t intensity[16][16];
};
/**
* defines the world constructions present. The material member is a mystery.
* \ingroup grp_maps
*/
struct t_worldconstruction : public t_virtual
{
/// material vector index
uint32_t material;
/// 16x16 array of bits
uint16_t assignment[16];
};
/** /**
* \ingroup grp_maps * \ingroup grp_maps
*/ */
@ -260,184 +172,6 @@ namespace DFHack
eBiomeCount eBiomeCount
}; };
/**
* \ingroup grp_maps
*/
enum e_traffic
{
traffic_normal,
traffic_low,
traffic_high,
traffic_restricted
};
/**
* type of a designation for a tile
* \ingroup grp_maps
*/
enum e_designation
{
/// no designation
designation_no,
/// dig walls, remove stairs and ramps, gather plants, fell trees. depends on tile type
designation_default,
/// dig up/down stairs
designation_ud_stair,
/// dig a channel
designation_channel,
/// dig ramp out of a wall
designation_ramp,
/// dig a stair down
designation_d_stair,
/// dig a stair up
designation_u_stair,
/// whatever. for completenes I guess
designation_7
};
/**
* type of liquid in a tile
* \ingroup grp_maps
*/
enum e_liquidtype
{
liquid_water,
liquid_magma
};
/**
* designation bit field
* \ingroup grp_maps
*/
struct naked_designation
{
unsigned int flow_size : 3; // how much liquid is here?
unsigned int pile : 1; // stockpile?
/// All the different dig designations
e_designation dig : 3;
unsigned int smooth : 2;
unsigned int hidden : 1;
/**
* This one is rather involved, but necessary to retrieve the base layer matgloss index
* @see http://www.bay12games.com/forum/index.php?topic=608.msg253284#msg253284
*/
unsigned int geolayer_index :4;
unsigned int light : 1;
unsigned int subterranean : 1; // never seen the light of day?
unsigned int skyview : 1; // sky is visible now, it rains in here when it rains
/**
* Probably similar to the geolayer_index. Only with a different set of offsets and different data.
* we don't use this yet
*/
unsigned int biome : 4;
/**
* 0 = water
* 1 = magma
*/
e_liquidtype liquid_type : 1;
unsigned int water_table : 1; // srsly. wtf?
unsigned int rained : 1; // does this mean actual rain (as in the blue blocks) or a wet tile?
e_traffic traffic : 2;
/// the tile is not evaluated when calculating flows?
unsigned int flow_forbid : 1;
/// no liquid spreading
unsigned int liquid_static : 1;
/// this tile is a part of a local feature. can be combined with 'featstone' tiles
unsigned int feature_local : 1;
/// this tile is a part of a global feature. can be combined with 'featstone' tiles
unsigned int feature_global : 1;
unsigned int water_stagnant : 1;
unsigned int water_salt : 1;
};
/**
* designation bit field wrapper
* \ingroup grp_maps
*/
union t_designation
{
uint32_t whole;
naked_designation bits;
};
/**
* occupancy flags (rat,dwarf,horse,built wall,not build wall,etc)
* \ingroup grp_maps
*/
struct naked_occupancy
{
/// 0-2: building type... should be an enum.
unsigned int building : 3;// 0-2
/// 3: the tile contains a standing creature
unsigned int unit : 1; // 3
/// 4: the tile contains a prone creature
unsigned int unit_grounded : 1;
/// 5: the tile contains an item
unsigned int item : 1;
/// 6: set on magma sea tiles, cavern lake tiles, rivers. not set on pools. probably something like 'inhibit growth'?
unsigned int unk6 : 1;
/// 7: mossy!
unsigned int moss : 1;
/// 8-11: arrow color. 0 = no arrow
unsigned int arrow_color : 4;
/// 12: arrow orientaton
unsigned int broken_arrows_variant : 1;
/// 13
unsigned int unk13 : 1;
/// 14: A monster lair. Items placed won't be moved.
unsigned int monster_lair : 1;
/**
* 15: seems to be set on terrain tiles where grass growth is impossible
* pebbles, boulders, rock floors in the middle of grass. also shrubs. but not trees
*/
unsigned int no_grow : 1;
/// 16
unsigned int unk16 : 1;
/// 17
unsigned int unk17 : 1;
/// 18
unsigned int unk18 : 1;
/// 19
unsigned int unk19 : 1;
/// 20
unsigned int unk20 : 1;
/// 21
unsigned int unk21 : 1;
/// 22
unsigned int unk22 : 1;
/// 23
unsigned int unk23 : 1;
/// 24
unsigned int unk24 : 1;
/// 25
unsigned int unk25 : 1;
/// 26
unsigned int unk26 : 1;
/// 27
unsigned int unk27 : 1;
/// 28
unsigned int unk28 : 1;
/// 29
unsigned int unk29 : 1;
/// 30
unsigned int unk30 : 1;
/// 31
unsigned int unk31 : 1;
};
/**
* occupancy flags (rat,dwarf,horse,built wall,not build wall,etc) wrapper
* \ingroup grp_maps
*/
union t_occupancy
{
uint32_t whole;
naked_occupancy bits;
};
/** /**
* map block flags * map block flags
* \ingroup grp_maps * \ingroup grp_maps
@ -454,16 +188,6 @@ namespace DFHack
/// rest of the flags is completely unknown /// rest of the flags is completely unknown
unsigned int unk_2: 4; unsigned int unk_2: 4;
}; };
enum e_block_flags
{
/// designated for jobs (digging and stuff like that)
BLOCK_DESIGNATED,
/// possibly related to the designated flag
BLOCK_UNKN1,
/// two flags required for liquid flow.
BLOCK_LIQUIDFLOW_1,
BLOCK_LIQUIDFLOW_2,
};
/** /**
* map block flags wrapper * map block flags wrapper
* \ingroup grp_maps * \ingroup grp_maps
@ -488,12 +212,12 @@ namespace DFHack
* 16x16 array of designation flags * 16x16 array of designation flags
* \ingroup grp_maps * \ingroup grp_maps
*/ */
typedef DFHack::t_designation designations40d [16][16]; typedef df::tile_designation designations40d [16][16];
/** /**
* 16x16 array of occupancy flags * 16x16 array of occupancy flags
* \ingroup grp_maps * \ingroup grp_maps
*/ */
typedef DFHack::t_occupancy occupancies40d [16][16]; typedef df::tile_occupancy occupancies40d [16][16];
/** /**
* array of 16 biome indexes valid for the block * array of 16 biome indexes valid for the block
* \ingroup grp_maps * \ingroup grp_maps
@ -520,107 +244,15 @@ namespace DFHack
/// values used for geology/biome assignment /// values used for geology/biome assignment
biome_indices40d biome_indices; biome_indices40d biome_indices;
/// the address where the block came from /// the address where the block came from
uint32_t origin; void * origin;
t_blockflags blockflags; t_blockflags blockflags;
/// index into the global feature vector /// index into the global feature vector
int16_t global_feature; int32_t global_feature;
/// index into the local feature vector... complicated /// index into the local feature vector... complicated
int16_t local_feature; int32_t local_feature;
int32_t mystery; int32_t mystery;
} mapblock40d; } mapblock40d;
// A raw DF block.
// one of the vector is the 'effects' vector. another should be item id/index vector
struct df_block
{
BitArray <e_block_flags> flags;
// how to handle this virtual mess?
std::vector <t_virtual *> block_events;
// no idea what these are
long unk1;
long unk2;
long unk3;
// feature indexes
signed long local_feature; // local feature index, -1 = no local feature
signed long global_feature; // global feature index, -1 = no global feature
signed long mystery; // no idea. couldn't manage to catch its use in debugger.
// more mysterious numbers
long unk4;
long unk5;
long unk6;
std::vector <unsigned long> items; // item related - probly item IDs
std::vector <void *> effects;
signed long unk7; // -1 most of the time, another index?
unsigned long unk8; // again, index?
std::vector<df_plant *> plants;
unsigned short map_x;
unsigned short map_y;
unsigned short map_z;
unsigned short region_x;
unsigned short region_y;
unsigned short tiletype[16][16]; // weird 2-byte alignment here
t_designation designation[16][16];
t_occupancy occupancy[16][16];
// following is uncertain, but total length should be fixed.
unsigned char unk9[16][16];
unsigned long pathfinding[16][16];
unsigned short unk10[16][16];
unsigned short unk11[16][16];
unsigned short unk12[16][16];
// end uncertain section
unsigned short temperature_1[16][16];
unsigned short temperature_2[16][16];
// no idea again. needs research...
unsigned short unk13[16][16];
unsigned short unk14[16][16];
unsigned char region_offset[9];
};
template <typename T>
struct df_array
{
inline T& operator[] (uint32_t index)
{
return array[index];
};
T * array;
};
template <typename T>
struct df_2darray
{
inline df_array<T>& operator[] (uint32_t index)
{
return array[index];
};
df_array <T> * array;
};
template <typename T>
struct df_3darray
{
inline df_2darray<T>& operator[] (uint32_t index)
{
return array[index];
};
inline bool operator! ()
{
return !array;
}
df_2darray <T> * array;
};
struct map_data
{
df_3darray<df_block *> map;
std::vector <void *> unk1;
void * unk2;
uint32_t x_size_blocks;
uint32_t y_size_blocks;
uint32_t z_size_blocks;
uint32_t x_size;
uint32_t y_size;
uint32_t z_size;
int32_t x_area_offset;
int32_t y_area_offset;
int32_t z_area_offset;
};
/** /**
* The Maps module * The Maps module
* \ingroup grp_modules * \ingroup grp_modules
@ -629,9 +261,6 @@ namespace DFHack
class DFHACK_EXPORT Maps : public Module class DFHACK_EXPORT Maps : public Module
{ {
public: public:
// the map data of DF, as we know it.
map_data * mdata;
Maps(); Maps();
~Maps(); ~Maps();
bool Start(); bool Start();
@ -730,7 +359,8 @@ namespace DFHack
/** /**
* Get the map block or NULL if block is not valid * Get the map block or NULL if block is not valid
*/ */
df_block * getBlock (uint32_t blockx, uint32_t blocky, uint32_t blockz); df::map_block * getBlock (int32_t blockx, int32_t blocky, int32_t blockz);
df::map_block * getBlockAbs (int32_t x, int32_t y, int32_t z);
/// copy the whole map block at block coords (see DFTypes.h for the block structure) /// copy the whole map block at block coords (see DFTypes.h for the block structure)
bool ReadBlock40d(uint32_t blockx, uint32_t blocky, uint32_t blockz, mapblock40d * buffer); bool ReadBlock40d(uint32_t blockx, uint32_t blocky, uint32_t blockz, mapblock40d * buffer);
@ -770,15 +400,15 @@ namespace DFHack
/// sorts the block event vector into multiple vectors by type /// sorts the block event vector into multiple vectors by type
/// mineral veins, what's under ice, blood smears and mud /// mineral veins, what's under ice, blood smears and mud
bool SortBlockEvents(uint32_t x, uint32_t y, uint32_t z, bool SortBlockEvents(uint32_t x, uint32_t y, uint32_t z,
std::vector<t_vein *>* veins, std::vector<df::block_square_event_mineralst *>* veins,
std::vector<t_frozenliquidvein *>* ices = 0, std::vector<df::block_square_event_frozen_liquidst *>* ices = 0,
std::vector<t_spattervein *>* splatter = 0, std::vector<df::block_square_event_material_spatterst *>* splatter = 0,
std::vector<t_grassvein *>* grass = 0, std::vector<df::block_square_event_grassst *>* grass = 0,
std::vector<t_worldconstruction *>* constructions = 0 std::vector<df::block_square_event_world_constructionst *>* constructions = 0
); );
/// remove a block event from the block by address /// remove a block event from the block by address
bool RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, t_virtual * which ); bool RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, df::block_square_event * which );
/// read all plants in this block /// read all plants in this block
bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df_plant *>*& plants); bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df_plant *>*& plants);

@ -40,6 +40,13 @@ using namespace std;
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include "Core.h" #include "Core.h"
#include "DataDefs.h"
#include "df/world_data.h"
#include "df/world_underground_region.h"
#include "df/feature_init.h"
using df::global::world;
#define MAPS_GUARD if(!d->Started) throw DFHack::Error::ModuleNotInitialized(); #define MAPS_GUARD if(!d->Started) throw DFHack::Error::ModuleNotInitialized();
using namespace DFHack; using namespace DFHack;
@ -49,18 +56,30 @@ Module* DFHack::createMaps()
return new Maps(); return new Maps();
} }
const char * DFHack::sa_feature(e_feature index) const char * DFHack::sa_feature(df::feature_type index)
{ {
switch(index) switch(index)
{ {
case feature_Other: case df::feature_type::outdoor_river:
return "Other"; return "River";
case feature_Adamantine_Tube: case df::feature_type::cave:
return "Adamantine Tube"; return "Cave";
case feature_Underworld: case df::feature_type::pit:
return "Pit";
case df::feature_type::magma_pool:
return "Magma pool";
case df::feature_type::volcano:
return "Volcano";
case df::feature_type::deep_special_tube:
return "Adamantine deposit";
case df::feature_type::deep_surface_portal:
return "Underworld portal";
case df::feature_type::subterranean_from_layer:
return "Cavern";
case df::feature_type::magma_core_from_layer:
return "Magma sea";
case df::feature_type::feature_underworld_from_layer:
return "Underworld"; return "Underworld";
case feature_Hell_Temple:
return "Hell Temple";
default: default:
return "Unknown/Error"; return "Unknown/Error";
} }
@ -71,46 +90,8 @@ struct Maps::Private
uint32_t worldSizeX, worldSizeY; uint32_t worldSizeX, worldSizeY;
uint32_t maps_module; uint32_t maps_module;
struct t_offsets
{
// FIXME: those need a rework really. Why did Toady use virtual inheritance for such vastly different types anyway?
void * vein_mineral_vptr;
void * vein_ice_vptr;
void * vein_spatter_vptr;
void * vein_grass_vptr;
void * vein_worldconstruction_vptr;
/*
GEOLOGY
*/
uint32_t world_regions;// mem->getAddress ("ptr2_region_array");
uint32_t region_size;// = minfo->getHexValue ("region_size");
uint32_t region_geo_index_offset;// = minfo->getOffset ("region_geo_index_off");
uint32_t world_geoblocks_vector;// = minfo->getOffset ("geoblock_vector");
uint32_t world_size_x;// = minfo->getOffset ("world_size_x");
uint32_t world_size_y;// = minfo->getOffset ("world_size_y");
uint32_t geolayer_geoblock_offset;// = minfo->getOffset ("geolayer_geoblock_offset");
uint32_t type_inside_geolayer;// = mem->getOffset ("type_inside_geolayer");
/*
FEATURES
*/
// FIXME: replace with a struct pointer, eventually. needs to be mapped out first
char * world_data;
uint32_t local_f_start; // offset from world_data
// FIXME: replace by virtual function call
uint32_t local_material;
// FIXME: replace by virtual function call
uint32_t local_submaterial;
uint32_t global_vector; // offset from world_data
uint32_t global_funcptr;
// FIXME: replace by virtual function call
uint32_t global_material;
// FIXME: replace by virtual function call
uint32_t global_submaterial;
} offsets;
Process * owner; Process * owner;
OffsetGroup *OG_vector;
bool Inited; bool Inited;
bool FeaturesStarted; bool FeaturesStarted;
bool Started; bool Started;
@ -118,8 +99,6 @@ struct Maps::Private
bool hasFeatures; bool hasFeatures;
bool hasVeggies; bool hasVeggies;
set <uint32_t> unknown_veins;
// map between feature address and the read object // map between feature address and the read object
map <void *, t_feature> local_feature_store; map <void *, t_feature> local_feature_store;
map <DFCoord, vector <t_feature *> > m_local_feature; map <DFCoord, vector <t_feature *> > m_local_feature;
@ -136,62 +115,8 @@ Maps::Maps()
d->Inited = d->FeaturesStarted = d->Started = false; d->Inited = d->FeaturesStarted = d->Started = false;
DFHack::VersionInfo * mem = c.vinfo; DFHack::VersionInfo * mem = c.vinfo;
Private::t_offsets &off = d->offsets;
d->hasFeatures = d->hasGeology = d->hasVeggies = true; d->hasFeatures = d->hasGeology = d->hasVeggies = true;
// get the offsets once here
OffsetGroup *OG_Maps = mem->getGroup("Maps");
off.world_data = OG_Maps->getAddress("world_data");
{
mdata = (map_data *) OG_Maps->getAddress ("map_data");
off.world_size_x = OG_Maps->getOffset ("world_size_x_from_wdata");
off.world_size_y = OG_Maps->getOffset ("world_size_y_from_wdata");
try
{
OffsetGroup *OG_Geology = OG_Maps->getGroup("geology");
off.world_regions = OG_Geology->getOffset ("ptr2_region_array_from_wdata");
off.world_geoblocks_vector = OG_Geology->getOffset ("geoblock_vector_from_wdata");
off.region_size = OG_Geology->getHexValue ("region_size");
off.region_geo_index_offset = OG_Geology->getOffset ("region_geo_index_off");
off.geolayer_geoblock_offset = OG_Geology->getOffset ("geolayer_geoblock_offset");
off.type_inside_geolayer = OG_Geology->getOffset ("type_inside_geolayer");
}
catch(Error::AllMemdef &)
{
d->hasGeology = false;
}
OffsetGroup *OG_global_features = OG_Maps->getGroup("features")->getGroup("global");
OffsetGroup *OG_local_features = OG_Maps->getGroup("features")->getGroup("local");
try
{
off.local_f_start = OG_local_features->getOffset("start_ptr_from_wdata");
off.global_vector = OG_global_features->getOffset("vector_from_wdata");
off.local_material = OG_local_features->getOffset("material");
off.local_submaterial = OG_local_features->getOffset("submaterial");
off.global_funcptr = OG_global_features->getOffset("funcptr");
off.global_material = OG_global_features->getOffset("material");
off.global_submaterial = OG_global_features->getOffset("submaterial");
}
catch(Error::AllMemdef &)
{
d->hasFeatures = false;
}
}
d->OG_vector = mem->getGroup("vector");
// these can (will) fail and will be found when looking at the actual veins later
// basically a cache
off.vein_ice_vptr = 0;
mem->resolveClassnameToVPtr("block_square_event_frozen_liquid", off.vein_ice_vptr);
off.vein_mineral_vptr = 0;
mem->resolveClassnameToVPtr("block_square_event_mineral",off.vein_mineral_vptr);
off.vein_spatter_vptr = 0;
mem->resolveClassnameToVPtr("block_square_event_material_spatterst",off.vein_spatter_vptr);
off.vein_grass_vptr = 0;
mem->resolveClassnameToVPtr("block_square_event_grassst",off.vein_grass_vptr);
off.vein_worldconstruction_vptr = 0;
mem->resolveClassnameToVPtr("block_square_event_world_constructionst",off.vein_worldconstruction_vptr);
d->Inited = true; d->Inited = true;
} }
@ -215,19 +140,11 @@ bool Maps::Start()
Finish(); Finish();
Process *p = d->owner; Process *p = d->owner;
Private::t_offsets &off = d->offsets;
// is there a map?
//uint32_t x_array_loc = p->readDWord (off.map_offset);
if (!mdata->map)
{
return false;
}
// get the size // get the size
uint32_t & mx = mdata->x_size_blocks; int32_t & mx = world->map.x_count_block;
uint32_t & my = mdata->y_size_blocks; int32_t & my = world->map.y_count_block;
uint32_t & mz = mdata->z_size_blocks; int32_t & mz = world->map.z_count_block;
// test for wrong map dimensions // test for wrong map dimensions
if (mx == 0 || mx > 48 || my == 0 || my > 48 || mz == 0) if (mx == 0 || mx > 48 || my == 0 || my > 48 || mz == 0)
@ -245,18 +162,18 @@ bool Maps::Start()
void Maps::getSize (uint32_t& x, uint32_t& y, uint32_t& z) void Maps::getSize (uint32_t& x, uint32_t& y, uint32_t& z)
{ {
MAPS_GUARD MAPS_GUARD
x = mdata->x_size_blocks; x = world->map.x_count_block;
y = mdata->y_size_blocks; y = world->map.y_count_block;
z = mdata->z_size_blocks; z = world->map.z_count_block;
} }
// getter for map position // getter for map position
void Maps::getPosition (int32_t& x, int32_t& y, int32_t& z) void Maps::getPosition (int32_t& x, int32_t& y, int32_t& z)
{ {
MAPS_GUARD MAPS_GUARD
x = mdata->x_area_offset; x = world->map.region_x;
y = mdata->y_area_offset; y = world->map.region_y;
z = mdata->z_area_offset; z = world->map.region_z;
} }
bool Maps::Finish() bool Maps::Finish()
@ -268,19 +185,29 @@ bool Maps::Finish()
* Block reading * Block reading
*/ */
df_block* Maps::getBlock (uint32_t x, uint32_t y, uint32_t z) df::map_block* Maps::getBlock (int32_t blockx, int32_t blocky, int32_t blockz)
{ {
MAPS_GUARD if ((blockx < 0) || (blocky < 0) || (blockz < 0))
if(x >= mdata->x_size_blocks || y >= mdata->y_size_blocks || z >= mdata->z_size_blocks) return NULL;
return 0; if ((blockx >= world->map.x_count_block) || (blocky << 4 >= world->map.y_count_block) || (blockz >= world->map.z_count_block))
return mdata->map[x][y][z]; return NULL;
return world->map.block_index[blockx][blocky][blockz];
}
df::map_block *Maps::getBlockAbs (int32_t x, int32_t y, int32_t z)
{
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];
} }
bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer) bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer)
{ {
MAPS_GUARD MAPS_GUARD
Process *p = d->owner; Process *p = d->owner;
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
buffer->position = DFCoord(x,y,z); buffer->position = DFCoord(x,y,z);
@ -290,9 +217,9 @@ bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer
memcpy(buffer->biome_indices,block->region_offset, sizeof(block->region_offset)); memcpy(buffer->biome_indices,block->region_offset, sizeof(block->region_offset));
buffer->global_feature = block->global_feature; buffer->global_feature = block->global_feature;
buffer->local_feature = block->local_feature; buffer->local_feature = block->local_feature;
buffer->mystery = block->mystery; buffer->mystery = block->unk2;
// FIXME: not 64-bit safe // FIXME: not 64-bit safe
buffer->origin = (uint32_t) &block; buffer->origin = &block;
//uint32_t addr_of_struct = p->readDWord(addr); //uint32_t addr_of_struct = p->readDWord(addr);
// FIXME: maybe truncates // FIXME: maybe truncates
buffer->blockflags.whole = block->flags; buffer->blockflags.whole = block->flags;
@ -308,7 +235,7 @@ bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer
bool Maps::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer) bool Maps::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
memcpy(buffer, block->tiletype, sizeof(tiletypes40d)); memcpy(buffer, block->tiletype, sizeof(tiletypes40d));
@ -320,7 +247,7 @@ bool Maps::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buff
bool Maps::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer) bool Maps::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
memcpy(block->tiletype, buffer, sizeof(tiletypes40d)); memcpy(block->tiletype, buffer, sizeof(tiletypes40d));
@ -335,10 +262,10 @@ bool Maps::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buf
bool Maps::ReadDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool &dirtybit) bool Maps::ReadDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool &dirtybit)
{ {
MAPS_GUARD MAPS_GUARD
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
dirtybit = block->flags.is_set(BLOCK_DESIGNATED); dirtybit = block->flags.is_set(df::block_flags::Designated);
return true; return true;
} }
return false; return false;
@ -347,10 +274,10 @@ bool Maps::ReadDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool &dirtybit)
bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit) bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit)
{ {
MAPS_GUARD MAPS_GUARD
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
block->flags.set(BLOCK_DESIGNATED,dirtybit); block->flags.set(df::block_flags::Designated, dirtybit);
return true; return true;
} }
return false; return false;
@ -363,7 +290,7 @@ bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit)
bool Maps::ReadBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags &blockflags) bool Maps::ReadBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags &blockflags)
{ {
MAPS_GUARD MAPS_GUARD
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
blockflags.whole = block->flags; blockflags.whole = block->flags;
@ -375,7 +302,7 @@ bool Maps::ReadBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags &bloc
bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags blockflags) bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags blockflags)
{ {
MAPS_GUARD MAPS_GUARD
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
return (block->flags = blockflags.whole); return (block->flags = blockflags.whole);
@ -389,7 +316,7 @@ bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags bloc
bool Maps::ReadDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer) bool Maps::ReadDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
memcpy(buffer, block->designation, sizeof(designations40d)); memcpy(buffer, block->designation, sizeof(designations40d));
@ -401,7 +328,7 @@ bool Maps::ReadDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d
bool Maps::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer) bool Maps::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
memcpy(block->designation, buffer, sizeof(designations40d)); memcpy(block->designation, buffer, sizeof(designations40d));
@ -416,7 +343,7 @@ bool Maps::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40
bool Maps::ReadOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer) bool Maps::ReadOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
memcpy(buffer, block->occupancy, sizeof(occupancies40d)); memcpy(buffer, block->occupancy, sizeof(occupancies40d));
@ -428,7 +355,7 @@ bool Maps::ReadOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *bu
bool Maps::WriteOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer) bool Maps::WriteOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
memcpy(block->occupancy, buffer, sizeof(occupancies40d)); memcpy(block->occupancy, buffer, sizeof(occupancies40d));
@ -443,7 +370,7 @@ bool Maps::WriteOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *b
bool Maps::ReadTemperatures(uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2) bool Maps::ReadTemperatures(uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2)
{ {
MAPS_GUARD MAPS_GUARD
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
if(temp1) if(temp1)
@ -457,7 +384,7 @@ bool Maps::ReadTemperatures(uint32_t x, uint32_t y, uint32_t z, t_temperatures *
bool Maps::WriteTemperatures (uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2) bool Maps::WriteTemperatures (uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2)
{ {
MAPS_GUARD MAPS_GUARD
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
if(temp1) if(temp1)
@ -475,7 +402,7 @@ bool Maps::WriteTemperatures (uint32_t x, uint32_t y, uint32_t z, t_temperatures
bool Maps::ReadRegionOffsets (uint32_t x, uint32_t y, uint32_t z, biome_indices40d *buffer) bool Maps::ReadRegionOffsets (uint32_t x, uint32_t y, uint32_t z, biome_indices40d *buffer)
{ {
MAPS_GUARD MAPS_GUARD
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
memcpy(buffer, block->region_offset,sizeof(biome_indices40d)); memcpy(buffer, block->region_offset,sizeof(biome_indices40d));
@ -501,45 +428,22 @@ bool Maps::StartFeatures()
MAPS_GUARD MAPS_GUARD
if(d->FeaturesStarted) return true; if(d->FeaturesStarted) return true;
if(!d->hasFeatures) return false; if(!d->hasFeatures) return false;
// can't be used without a map!
if(!mdata->map)
return false;
Process * p = d->owner;
Private::t_offsets &off = d->offsets;
char * base = 0;
char * global_feature_vector = 0;
char * world = p->readPtr( (void *) off.world_data);
if(!world) return false;
base = p->readPtr(world + off.local_f_start);
global_feature_vector = p->readPtr(off.world_data) + off.global_vector;
// deref pointer to the humongo-structure
if(!base)
return false;
// regionX and regionY are in embark squares! // regionX and regionY are in embark squares!
// we convert to full region tiles // we convert to full region tiles
// this also works in adventure mode // this also works in adventure mode
// region X coord - whole regions // region X coord - whole regions
const uint32_t sizeof_vec = d->OG_vector->getHexValue("sizeof");
const uint32_t sizeof_elem = 16;
const uint32_t offset_elem = 4;
const uint32_t loc_main_mat_offset = off.local_material;
const uint32_t loc_sub_mat_offset = off.local_submaterial;
const uint32_t sizeof_16vec = 16* sizeof_vec;
for(uint32_t blockX = 0; blockX < mdata->x_size_blocks; blockX ++) for(uint32_t blockX = 0; blockX < world->map.x_count_block; blockX ++)
for(uint32_t blockY = 0; blockY < mdata->y_size_blocks; blockY ++) for(uint32_t blockY = 0; blockY < world->map.y_count_block; blockY ++)
{ {
// regionX and regionY are in embark squares! // regionX and regionY are in embark squares!
// we convert to full region tiles // we convert to full region tiles
// this also works in adventure mode // this also works in adventure mode
// region X coord - whole regions // region X coord - whole regions
uint32_t region_x = ( (blockX / 3) + mdata->x_area_offset ) / 16; uint32_t region_x = ( (blockX / 3) + world->map.region_x ) / 16;
// region Y coord - whole regions // region Y coord - whole regions
uint32_t region_y = ( (blockY / 3) + mdata->y_area_offset ) / 16; uint32_t region_y = ( (blockY / 3) + world->map.region_y ) / 16;
uint32_t bigregion_x = region_x / 16; uint32_t bigregion_x = region_x / 16;
uint32_t bigregion_y = region_y / 16; uint32_t bigregion_y = region_y / 16;
uint32_t sub_x = region_x % 16; uint32_t sub_x = region_x % 16;
@ -548,19 +452,16 @@ bool Maps::StartFeatures()
// base = pointer to local feature structure (inside world data struct) // base = pointer to local feature structure (inside world data struct)
// bigregion is 16x16 regions. for each bigregion in X dimension: // bigregion is 16x16 regions. for each bigregion in X dimension:
char * mega_column = p->readPtr(base + bigregion_x * 4);
// 16B structs, second DWORD of the struct is a pointer if(world->world_data->unk_204[bigregion_x][bigregion_y].features)
char * loc_f_array16x16 = p->readPtr(mega_column + offset_elem + (sizeof_elem * bigregion_y));
if(loc_f_array16x16)
{ {
vector <char *> * p_features = (vector <char *> *) (loc_f_array16x16 + sizeof_16vec * sub_x + sizeof_vec * sub_y); vector <df::feature_init *> *features = &world->world_data->unk_204[bigregion_x][bigregion_y].features->feature_init[sub_x][sub_y];
uint32_t size = p_features->size(); uint32_t size = features->size();
DFCoord pc(blockX,blockY); DFCoord pc(blockX,blockY);
std::vector<t_feature *> tempvec; std::vector<t_feature *> tempvec;
for(uint32_t i = 0; i < size; i++) for(uint32_t i = 0; i < size; i++)
{ {
char * cur_ptr = p_features->at(i); df::feature_init * cur_ptr = features->at(i);
map <void *, t_feature>::iterator it; map <void *, t_feature>::iterator it;
it = d->local_feature_store.find(cur_ptr); it = d->local_feature_store.find(cur_ptr);
@ -573,30 +474,11 @@ bool Maps::StartFeatures()
// no? // no?
else else
{ {
//FIXME: replace with accessors
// create, add to store
t_feature tftemp; t_feature tftemp;
tftemp.discovered = false; //= p->readDWord(cur_ptr + 4); tftemp.discovered = false;
tftemp.origin = (t_feature *) cur_ptr; tftemp.origin = cur_ptr;
string name = p->readClassName((void *)p->readDWord( cur_ptr )); tftemp.type = cur_ptr->getType();
if(name == "feature_init_deep_special_tubest") cur_ptr->getMaterial(&tftemp.main_material, &tftemp.sub_material);
{
tftemp.main_material = p->readWord( cur_ptr + loc_main_mat_offset );
tftemp.sub_material = p->readDWord( cur_ptr + loc_sub_mat_offset );
tftemp.type = feature_Adamantine_Tube;
}
else if(name == "feature_init_deep_surface_portalst")
{
tftemp.main_material = p->readWord( cur_ptr + loc_main_mat_offset );
tftemp.sub_material = p->readDWord( cur_ptr + loc_sub_mat_offset );
tftemp.type = feature_Hell_Temple;
}
else
{
tftemp.main_material = -1;
tftemp.sub_material = -1;
tftemp.type = feature_Other;
}
d->local_feature_store[cur_ptr] = tftemp; d->local_feature_store[cur_ptr] = tftemp;
// push pointer // push pointer
tempvec.push_back(&(d->local_feature_store[cur_ptr])); tempvec.push_back(&(d->local_feature_store[cur_ptr]));
@ -605,35 +487,19 @@ bool Maps::StartFeatures()
d->m_local_feature[pc] = tempvec; d->m_local_feature[pc] = tempvec;
} }
} }
// deref pointer to the humongo-structure
const uint32_t global_feature_funcptr = off.global_funcptr; // enumerate global features
const uint32_t glob_main_mat_offset = off.global_material; uint32_t size = world->world_data->underground_regions.size();
const uint32_t glob_sub_mat_offset = off.global_submaterial;
vector <char *> * p_features = (vector <char *> *) global_feature_vector;
d->v_global_feature.clear(); d->v_global_feature.clear();
uint32_t size = p_features->size();
d->v_global_feature.reserve(size); d->v_global_feature.reserve(size);
for (uint32_t i = 0; i < size; i++) for (uint32_t i = 0; i < size; i++)
{ {
t_feature temp; t_feature temp;
char * feat_ptr = p->readPtr(p_features->at(i) + global_feature_funcptr ); df::feature_init * feat_ptr = world->world_data->underground_regions[i]->feature_init;
temp.origin = feat_ptr; temp.origin = feat_ptr;
temp.discovered = false; temp.discovered = false;
temp.type = feat_ptr->getType();
// FIXME: use the memory_info cache mechanisms feat_ptr->getMaterial(&temp.main_material, &temp.sub_material);
string name = p->readClassName((void *)p->readDWord( feat_ptr));
if(name == "feature_init_underworld_from_layerst")
{
temp.main_material = p->readWord( feat_ptr + glob_main_mat_offset );
temp.sub_material = p->readDWord( feat_ptr + glob_sub_mat_offset );
temp.type = feature_Underworld;
}
else
{
temp.main_material = -1;
temp.sub_material = -1;
temp.type = feature_Other;
}
d->v_global_feature.push_back(temp); d->v_global_feature.push_back(temp);
} }
d->FeaturesStarted = true; d->FeaturesStarted = true;
@ -663,7 +529,7 @@ std::vector <t_feature *> * Maps::GetLocalFeatures(DFCoord coord)
bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int16_t & global) bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int16_t & global)
{ {
MAPS_GUARD MAPS_GUARD
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
local = block->local_feature; local = block->local_feature;
@ -676,7 +542,7 @@ bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int16_t & local, int
bool Maps::WriteFeatures(uint32_t x, uint32_t y, uint32_t z, const int16_t & local, const int16_t & global) bool Maps::WriteFeatures(uint32_t x, uint32_t y, uint32_t z, const int16_t & local, const int16_t & global)
{ {
MAPS_GUARD MAPS_GUARD
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
block->local_feature = local; block->local_feature = local;
@ -737,7 +603,7 @@ bool Maps::ReadFeatures(mapblock40d * block, t_feature ** local, t_feature ** gl
bool Maps::SetBlockLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t local) bool Maps::SetBlockLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t local)
{ {
MAPS_GUARD MAPS_GUARD
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
block->local_feature = local; block->local_feature = local;
@ -749,7 +615,7 @@ bool Maps::SetBlockLocalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t loca
bool Maps::SetBlockGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t global) bool Maps::SetBlockGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t global)
{ {
MAPS_GUARD MAPS_GUARD
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if (block) if (block)
{ {
block->global_feature = global; block->global_feature = global;
@ -761,112 +627,63 @@ bool Maps::SetBlockGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int16_t glo
/* /*
* Block events * Block events
*/ */
bool Maps::SortBlockEvents(uint32_t x, uint32_t y, uint32_t z, vector <t_vein *>* veins, vector <t_frozenliquidvein *>* ices, vector <t_spattervein *> *splatter, vector <t_grassvein *> *grass, vector <t_worldconstruction *> *constructions) bool Maps::SortBlockEvents(uint32_t x, uint32_t y, uint32_t z,
vector <df::block_square_event_mineralst *>* veins,
vector <df::block_square_event_frozen_liquidst *>* ices,
vector <df::block_square_event_material_spatterst *> *splatter,
vector <df::block_square_event_grassst *> *grass,
vector <df::block_square_event_world_constructionst *> *constructions)
{ {
MAPS_GUARD MAPS_GUARD
Process* p = d->owner; Process* p = d->owner;
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if(veins) veins->clear(); if(veins) veins->clear();
if(ices) ices->clear(); if(ices) ices->clear();
if(splatter) splatter->clear(); if(splatter) splatter->clear();
if(grass) grass->clear(); if(grass) grass->clear();
if(constructions) constructions->clear(); if(constructions) constructions->clear();
Private::t_offsets &off = d->offsets;
if (!block) if (!block)
return false; return false;
uint32_t size = block->block_events.size(); uint32_t size = block->block_events.size();
// read all veins // read all veins
for (uint32_t i = 0; i < size;i++) for (uint32_t i = 0; i < size;i++)
{ {
retry: df::block_square_event *evt = block->block_events[i];
// read the vein pointer from the vector switch (evt->getType())
t_virtual * temp = block->block_events[i]; {
void * type = temp->vptr; case df::block_square_event_type::mineral:
if(type == (void *) off.vein_mineral_vptr) if (veins)
{ veins->push_back((df::block_square_event_mineralst *)evt);
if(!veins) continue; break;
// store it in the vector case df::block_square_event_type::frozen_liquid:
veins->push_back ((t_vein *) temp); if (ices)
} ices->push_back((df::block_square_event_frozen_liquidst *)evt);
else if(type == (void *) off.vein_ice_vptr) break;
{ case df::block_square_event_type::material_spatter:
if(!ices) continue; if (splatter)
ices->push_back ((t_frozenliquidvein *) temp); splatter->push_back((df::block_square_event_material_spatterst *)evt);
} break;
else if(type == (void *) off.vein_spatter_vptr) case df::block_square_event_type::grass:
{ if (grass)
if(!splatter) continue; grass->push_back((df::block_square_event_grassst *)evt);
splatter->push_back ( (t_spattervein *)temp); break;
} case df::block_square_event_type::world_construction:
else if(type == (void *) off.vein_grass_vptr) if (constructions)
{ constructions->push_back((df::block_square_event_world_constructionst *)evt);
if(!grass) continue; break;
grass->push_back ((t_grassvein *) temp);
}
else if(type == (void *) off.vein_worldconstruction_vptr)
{
if(!constructions) continue;
constructions->push_back ((t_worldconstruction *) temp);
}
// previously unseen type of vein
else
{
string cname = p->readClassName(type);
//string cname = typeid(*(blockevent *)temp).name();
//Core::getInstance().con.printerr("%s\n",cname.c_str());
if(!off.vein_ice_vptr && cname == "block_square_event_frozen_liquidst")
{
off.vein_ice_vptr = type;
//Core::getInstance().con.printerr("%s %x\n",cname.c_str(), type);
goto retry;
}
else if(!off.vein_mineral_vptr &&cname == "block_square_event_mineralst")
{
off.vein_mineral_vptr = type;
//Core::getInstance().con.printerr("%s %x\n",cname.c_str(), type);
goto retry;
}
else if(!off.vein_spatter_vptr && cname == "block_square_event_material_spatterst")
{
off.vein_spatter_vptr = type;
//Core::getInstance().con.printerr("%s %x\n",cname.c_str(), type);
goto retry;
}
else if(!off.vein_grass_vptr && cname=="block_square_event_grassst")
{
off.vein_grass_vptr = type;
//Core::getInstance().con.printerr("%s %x\n",cname.c_str(), type);
goto retry;
}
else if(!off.vein_worldconstruction_vptr && cname=="block_square_event_world_constructionst")
{
off.vein_worldconstruction_vptr = type;
//Core::getInstance().con.printerr("%s %x\n",cname.c_str(), type);
goto retry;
}
#ifdef DEBUG
else // this is something we've never seen before
{
if(!d->unknown_veins.count(type))
{
cerr << "unknown vein " << cname << hex << " 0x" << temp << " block: 0x" << addr << dec << endl;
d->unknown_veins.insert(type);
}
}
#endif
} }
} }
return true; return true;
} }
bool Maps::RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, t_virtual * which) bool Maps::RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, df::block_square_event * which)
{ {
MAPS_GUARD MAPS_GUARD
Process* p = d->owner; Process* p = d->owner;
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if(block) if(block)
{ {
for(int i = 0; i < block->block_events.size();i++) for(int i = 0; i < block->block_events.size();i++)
@ -889,21 +706,6 @@ bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
{ {
MAPS_GUARD MAPS_GUARD
if(!d->hasGeology) return false; if(!d->hasGeology) return false;
Process *p = d->owner;
// get needed addresses and offsets. Now this is what I call crazy.
uint16_t worldSizeX, worldSizeY;
char *regions;
char *geoblocks_vector_addr;
Private::t_offsets &off = d->offsets;
// get world size
char * world = p->readPtr(off.world_data);
p->readWord (world + off.world_size_x, worldSizeX);
p->readWord (world + off.world_size_y, worldSizeY);
regions = p->readPtr ( world + off.world_regions); // ptr2_region_array
geoblocks_vector_addr = world + off.world_geoblocks_vector;
// read the geoblock vector
vector <char *> & geoblocks = *(vector <char *> *)(geoblocks_vector_addr);
// iterate over 8 surrounding regions + local region // iterate over 8 surrounding regions + local region
for (int i = eNorthWest; i < eBiomeCount; i++) for (int i = eNorthWest; i < eBiomeCount; i++)
@ -912,43 +714,26 @@ bool Maps::ReadGeology (vector < vector <uint16_t> >& assign)
// regionX is in embark squares // regionX is in embark squares
// regionX/16 is in 16x16 embark square regions // regionX/16 is in 16x16 embark square regions
// i provides -1 .. +1 offset from the current region // i provides -1 .. +1 offset from the current region
int bioRX = mdata->x_area_offset / 16 + ((i % 3) - 1); int bioRX = world->map.region_x / 16 + ((i % 3) - 1);
if (bioRX < 0) bioRX = 0; if (bioRX < 0) bioRX = 0;
if (bioRX >= worldSizeX) bioRX = worldSizeX - 1; if (bioRX >= world->world_data->world_width) bioRX = world->world_data->world_width - 1;
int bioRY = mdata->y_area_offset / 16 + ((i / 3) - 1); int bioRY = world->map.region_y / 16 + ((i / 3) - 1);
if (bioRY < 0) bioRY = 0; if (bioRY < 0) bioRY = 0;
if (bioRY >= worldSizeY) bioRY = worldSizeY - 1; if (bioRY >= world->world_data->world_height) bioRY = world->world_data->world_height - 1;
/// regions are a 2d array. consists of pointers to arrays of regions
/// regions are of region_size size
// get pointer to column of regions
char * geoX;
p->readPtr (regions + bioRX*4, geoX);
// get index into geoblock vector // get index into geoblock vector
uint16_t geoindex; uint16_t geoindex = world->world_data->unk_1c0[bioRX][bioRY].geo_index;
p->readWord (geoX + bioRY*off.region_size + off.region_geo_index_offset, geoindex);
/// geology blocks are assigned to regions from a vector
// get the geoblock from the geoblock vector using the geoindex
// read the matgloss pointer from the vector into temp
char * geoblock_off = geoblocks[geoindex];
/// geology blocks have a vector of layer descriptors /// geology blocks have a vector of layer descriptors
// get the vector with pointer to layers // get the vector with pointer to layers
vector <char *> & geolayers = *(vector <char *> *)(geoblock_off + off.geolayer_geoblock_offset); vector <df::world_data::T_unk_190::T_unk_4 *> *geolayers = &world->world_data->unk_190[geoindex]->unk_4;
// make sure we don't load crap
assert (geolayers.size() > 0 && geolayers.size() <= 16);
/// layer descriptor has a field that determines the type of stone/soil /// layer descriptor has a field that determines the type of stone/soil
d->v_geology[i].reserve (geolayers.size()); d->v_geology[i].reserve (geolayers->size());
// finally, read the layer matgloss // finally, read the layer matgloss
for (uint32_t j = 0;j < geolayers.size();j++) for (uint32_t j = 0;j < geolayers->size();j++)
{ {
// read pointer to a layer d->v_geology[i].push_back (geolayers->at(j)->unk_4);
char * geol_offset = geolayers[j];
// read word at pointer + 2, store in our geology vectors
d->v_geology[i].push_back (p->readWord (geol_offset + off.type_inside_geolayer));
} }
} }
assign.clear(); assign.clear();
@ -988,10 +773,10 @@ bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector<df_pla
{ {
if(!d->hasVeggies || !d->Started) if(!d->hasVeggies || !d->Started)
return false; return false;
df_block * block = getBlock(x,y,z); df::map_block * block = getBlock(x,y,z);
if(!block) if(!block)
return false; return false;
Private::t_offsets &off = d->offsets;
plants = &block->plants; plants = (vector<DFHack::df_plant *> *)&block->plants;
return true; return true;
} }

@ -185,8 +185,8 @@ static command_result autodump_main(Core * c, vector <string> & parameters)
{ {
// yes... // yes...
cerr << "Moving from block to block!" << endl; cerr << "Moving from block to block!" << endl;
df_block * bl_src = Maps->getBlock(itm->pos.x /16, itm->pos.y/16, itm->pos.z); df::map_block * bl_src = Maps->getBlock(itm->pos.x /16, itm->pos.y/16, itm->pos.z);
df_block * bl_tgt = Maps->getBlock(cx /16, cy/16, cz); df::map_block * bl_tgt = Maps->getBlock(cx /16, cy/16, cz);
if(bl_src) if(bl_src)
{ {
std::remove(bl_src->items.begin(), bl_src->items.end(),itm->id); std::remove(bl_src->items.begin(), bl_src->items.end(),itm->id);
@ -234,7 +234,7 @@ static command_result autodump_main(Core * c, vector <string> & parameters)
{ {
if(it->second == 0) if(it->second == 0)
{ {
t_occupancy occ = MC.occupancyAt(it->first); df::tile_occupancy occ = MC.occupancyAt(it->first);
occ.bits.item = false; occ.bits.item = false;
MC.setOccupancyAt(it->first, occ); MC.setOccupancyAt(it->first, occ);
} }
@ -247,7 +247,7 @@ static command_result autodump_main(Core * c, vector <string> & parameters)
Block * b = MC.BlockAt(pos_cursor / 16); Block * b = MC.BlockAt(pos_cursor / 16);
if(b) if(b)
{ {
t_occupancy occ = MC.occupancyAt(pos_cursor); df::tile_occupancy occ = MC.occupancyAt(pos_cursor);
occ.bits.item = 1; occ.bits.item = 1;
MC.setOccupancyAt(pos_cursor,occ); MC.setOccupancyAt(pos_cursor,occ);
} }

@ -57,8 +57,8 @@ DFhackCExport command_result filltraffic(DFHack::Core * c, std::vector<std::stri
//Maximum map size. //Maximum map size.
uint32_t x_max,y_max,z_max; uint32_t x_max,y_max,z_max;
//Source and target traffic types. //Source and target traffic types.
e_traffic source = traffic_normal; df::tile_traffic source = df::tile_traffic::Normal;
e_traffic target = traffic_normal; df::tile_traffic target = df::tile_traffic::Normal;
//Option flags //Option flags
bool updown = false; bool updown = false;
bool checkpit = true; bool checkpit = true;
@ -89,13 +89,13 @@ DFhackCExport command_result filltraffic(DFHack::Core * c, std::vector<std::stri
switch (toupper(params[i][0])) switch (toupper(params[i][0]))
{ {
case 'H': case 'H':
target = traffic_high; break; target = df::tile_traffic::High; break;
case 'N': case 'N':
target = traffic_normal; break; target = df::tile_traffic::Normal; break;
case 'L': case 'L':
target = traffic_low; break; target = df::tile_traffic::Low; break;
case 'R': case 'R':
target = traffic_restricted; break; target = df::tile_traffic::Restricted; break;
case 'X': case 'X':
updown = true; break; updown = true; break;
case 'B': case 'B':
@ -133,14 +133,14 @@ DFhackCExport command_result filltraffic(DFHack::Core * c, std::vector<std::stri
DFHack::DFCoord xy ((uint32_t)cx,(uint32_t)cy,cz); DFHack::DFCoord xy ((uint32_t)cx,(uint32_t)cy,cz);
MapExtras::MapCache * MCache = new MapExtras::MapCache(Maps); MapExtras::MapCache * MCache = new MapExtras::MapCache(Maps);
DFHack::t_designation des = MCache->designationAt(xy); df::tile_designation des = MCache->designationAt(xy);
int16_t tt = MCache->tiletypeAt(xy); int16_t tt = MCache->tiletypeAt(xy);
DFHack::t_occupancy oc; df::tile_occupancy oc;
if (checkbuilding) if (checkbuilding)
oc = MCache->occupancyAt(xy); oc = MCache->occupancyAt(xy);
source = des.bits.traffic; source = (df::tile_traffic)des.bits.traffic;
if(source == target) if(source == target)
{ {
c->con.printerr("This tile is already set to the target traffic type.\n"); c->con.printerr("This tile is already set to the target traffic type.\n");
@ -356,25 +356,25 @@ DFhackCExport command_result setAllMatching(DFHack::Core * c, checkTile checkPro
//Unconditionally set map to target traffic type //Unconditionally set map to target traffic type
void allHigh(DFHack::DFCoord coord, MapExtras::MapCache * map) void allHigh(DFHack::DFCoord coord, MapExtras::MapCache * map)
{ {
DFHack::t_designation des = map->designationAt(coord); df::tile_designation des = map->designationAt(coord);
des.bits.traffic = traffic_high; des.bits.traffic = df::tile_traffic::High;
map->setDesignationAt(coord, des); map->setDesignationAt(coord, des);
} }
void allNormal(DFHack::DFCoord coord, MapExtras::MapCache * map) void allNormal(DFHack::DFCoord coord, MapExtras::MapCache * map)
{ {
DFHack::t_designation des = map->designationAt(coord); df::tile_designation des = map->designationAt(coord);
des.bits.traffic = traffic_normal; des.bits.traffic = df::tile_traffic::Normal;
map->setDesignationAt(coord, des); map->setDesignationAt(coord, des);
} }
void allLow(DFHack::DFCoord coord, MapExtras::MapCache * map) void allLow(DFHack::DFCoord coord, MapExtras::MapCache * map)
{ {
DFHack::t_designation des = map->designationAt(coord); df::tile_designation des = map->designationAt(coord);
des.bits.traffic = traffic_low; des.bits.traffic = df::tile_traffic::Low;
map->setDesignationAt(coord, des); map->setDesignationAt(coord, des);
} }
void allRestricted(DFHack::DFCoord coord, MapExtras::MapCache * map) void allRestricted(DFHack::DFCoord coord, MapExtras::MapCache * map)
{ {
DFHack::t_designation des = map->designationAt(coord); df::tile_designation des = map->designationAt(coord);
des.bits.traffic = traffic_restricted; des.bits.traffic = df::tile_traffic::Restricted;
map->setDesignationAt(coord, des); map->setDesignationAt(coord, des);
} }

@ -389,7 +389,7 @@ DFhackCExport command_result df_liquids (Core * c, vector <string> & parameters)
mcache.setTiletypeAt(*iter, 331); mcache.setTiletypeAt(*iter, 331);
mcache.setTemp1At(*iter,10015); mcache.setTemp1At(*iter,10015);
mcache.setTemp2At(*iter,10015); mcache.setTemp2At(*iter,10015);
DFHack::t_designation des = mcache.designationAt(*iter); df::tile_designation des = mcache.designationAt(*iter);
des.bits.flow_size = 0; des.bits.flow_size = 0;
mcache.setDesignationAt(*iter, des); mcache.setDesignationAt(*iter, des);
iter ++; iter ++;
@ -411,8 +411,8 @@ DFhackCExport command_result df_liquids (Core * c, vector <string> & parameters)
{ {
mcache.setTiletypeAt(*iter, 90); mcache.setTiletypeAt(*iter, 90);
DFHack::t_designation a = mcache.designationAt(*iter); df::tile_designation a = mcache.designationAt(*iter);
a.bits.liquid_type = DFHack::liquid_water; a.bits.liquid_type = df::tile_liquid::Water;
a.bits.liquid_static = false; a.bits.liquid_static = false;
a.bits.flow_size = 7; a.bits.flow_size = 7;
mcache.setTemp1At(*iter,10015); mcache.setTemp1At(*iter,10015);
@ -434,7 +434,7 @@ DFhackCExport command_result df_liquids (Core * c, vector <string> & parameters)
while (iter != all_tiles.end()) while (iter != all_tiles.end())
{ {
DFHack::DFCoord current = *iter; DFHack::DFCoord current = *iter;
DFHack::t_designation des = mcache.designationAt(current); df::tile_designation des = mcache.designationAt(current);
des.bits.water_salt = false; des.bits.water_salt = false;
des.bits.water_stagnant = false; des.bits.water_stagnant = false;
mcache.setDesignationAt(current,des); mcache.setDesignationAt(current,des);
@ -455,9 +455,8 @@ DFhackCExport command_result df_liquids (Core * c, vector <string> & parameters)
iter ++; iter ++;
continue; continue;
} }
DFHack::t_designation des = mcache.designationAt(current); df::tile_designation des = mcache.designationAt(current);
uint16_t tt = mcache.tiletypeAt(current); uint16_t tt = mcache.tiletypeAt(current);
DFHack::naked_designation & flow = des.bits;
// don't put liquids into places where they don't belong... // don't put liquids into places where they don't belong...
if(!DFHack::FlowPassable(tt)) if(!DFHack::FlowPassable(tt))
{ {
@ -468,27 +467,27 @@ DFhackCExport command_result df_liquids (Core * c, vector <string> & parameters)
{ {
if(setmode == "s.") if(setmode == "s.")
{ {
flow.flow_size = amount; des.bits.flow_size = amount;
} }
else if(setmode == "s+") else if(setmode == "s+")
{ {
if(flow.flow_size < amount) if(des.bits.flow_size < amount)
flow.flow_size = amount; des.bits.flow_size = amount;
} }
else if(setmode == "s-") else if(setmode == "s-")
{ {
if (flow.flow_size > amount) if (des.bits.flow_size > amount)
flow.flow_size = amount; des.bits.flow_size = amount;
} }
if(amount != 0 && mode == "magma") if(amount != 0 && mode == "magma")
{ {
flow.liquid_type = DFHack::liquid_magma; des.bits.liquid_type = df::tile_liquid::Magma;
mcache.setTemp1At(current,12000); mcache.setTemp1At(current,12000);
mcache.setTemp2At(current,12000); mcache.setTemp2At(current,12000);
} }
else if(amount != 0 && mode == "water") else if(amount != 0 && mode == "water")
{ {
flow.liquid_type = DFHack::liquid_water; des.bits.liquid_type = df::tile_liquid::Water;
mcache.setTemp1At(current,10015); mcache.setTemp1At(current,10015);
mcache.setTemp2At(current,10015); mcache.setTemp2At(current,10015);
} }

@ -145,7 +145,7 @@ DFhackCExport command_result df_probe (Core * c, vector <string> & parameters)
} }
*/ */
int16_t tiletype = mc.tiletypeAt(cursor); int16_t tiletype = mc.tiletypeAt(cursor);
naked_designation &des = block.designation[tileX][tileY].bits; df::tile_designation &des = block.designation[tileX][tileY];
/* /*
if(showDesig) if(showDesig)
{ {
@ -189,8 +189,8 @@ DFhackCExport command_result df_probe (Core * c, vector <string> & parameters)
con.print("temperature2: %d U\n",mc.temperature2At(cursor)); con.print("temperature2: %d U\n",mc.temperature2At(cursor));
// biome, geolayer // biome, geolayer
con << "biome: " << des.biome << std::endl; con << "biome: " << des.bits.biome << std::endl;
con << "geolayer: " << des.geolayer_index con << "geolayer: " << des.bits.geolayer_index
<< std::endl; << std::endl;
int16_t base_rock = mc.baseMaterialAt(cursor); int16_t base_rock = mc.baseMaterialAt(cursor);
if(base_rock != -1) if(base_rock != -1)
@ -217,33 +217,33 @@ DFhackCExport command_result df_probe (Core * c, vector <string> & parameters)
con << endl; con << endl;
} }
// liquids // liquids
if(des.flow_size) if(des.bits.flow_size)
{ {
if(des.liquid_type == DFHack::liquid_magma) if(des.bits.liquid_type == df::tile_liquid::Magma)
con <<"magma: "; con <<"magma: ";
else con <<"water: "; else con <<"water: ";
con << des.flow_size << std::endl; con << des.bits.flow_size << std::endl;
} }
if(des.flow_forbid) if(des.bits.flow_forbid)
con << "flow forbid" << std::endl; con << "flow forbid" << std::endl;
if(des.pile) if(des.bits.pile)
con << "stockpile?" << std::endl; con << "stockpile?" << std::endl;
if(des.rained) if(des.bits.rained)
con << "rained?" << std::endl; con << "rained?" << std::endl;
if(des.smooth) if(des.bits.smooth)
con << "smooth?" << std::endl; con << "smooth?" << std::endl;
if(des.water_salt) if(des.bits.water_salt)
con << "salty" << endl; con << "salty" << endl;
if(des.water_stagnant) if(des.bits.water_stagnant)
con << "stagnant" << endl; con << "stagnant" << endl;
#define PRINT_FLAG( X ) con.print("%-16s= %c\n", #X , ( des.X ? 'Y' : ' ' ) ) #define PRINT_FLAG( X ) con.print("%-16s= %c\n", #X , ( des.X ? 'Y' : ' ' ) )
PRINT_FLAG( hidden ); PRINT_FLAG( bits.hidden );
PRINT_FLAG( light ); PRINT_FLAG( bits.light );
PRINT_FLAG( skyview ); PRINT_FLAG( bits.outside );
PRINT_FLAG( subterranean ); PRINT_FLAG( bits.subterranean );
PRINT_FLAG( water_table ); PRINT_FLAG( bits.water_table );
PRINT_FLAG( rained ); PRINT_FLAG( bits.rained );
DFCoord pc(blockX, blockY); DFCoord pc(blockX, blockY);
@ -252,7 +252,7 @@ DFhackCExport command_result df_probe (Core * c, vector <string> & parameters)
t_feature * local = 0; t_feature * local = 0;
t_feature * global = 0; t_feature * global = 0;
Maps->ReadFeatures(&(b->raw),&local,&global); Maps->ReadFeatures(&(b->raw),&local,&global);
PRINT_FLAG( feature_local ); PRINT_FLAG( bits.feature_local );
if(local) if(local)
{ {
con.print("%-16s", ""); con.print("%-16s", "");
@ -261,7 +261,7 @@ DFhackCExport command_result df_probe (Core * c, vector <string> & parameters)
con.print(" addr 0x%X ", local->origin); con.print(" addr 0x%X ", local->origin);
con.print(" %s\n", sa_feature(local->type)); con.print(" %s\n", sa_feature(local->type));
} }
PRINT_FLAG( feature_global ); PRINT_FLAG( bits.feature_global );
if(global) if(global)
{ {
con.print("%-16s", ""); con.print("%-16s", "");
@ -272,8 +272,8 @@ DFhackCExport command_result df_probe (Core * c, vector <string> & parameters)
} }
else else
{ {
PRINT_FLAG( feature_local ); PRINT_FLAG( bits.feature_local );
PRINT_FLAG( feature_global ); PRINT_FLAG( bits.feature_global );
} }
#undef PRINT_FLAG #undef PRINT_FLAG
con << "local feature idx: " << block.local_feature con << "local feature idx: " << block.local_feature

@ -321,8 +321,8 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
for(uint32_t x = 0; x < 16; x++) for(uint32_t x = 0; x < 16; x++)
{ {
DFHack::DFCoord coord(x, y); DFHack::DFCoord coord(x, y);
DFHack::t_designation des = b->DesignationAt(coord); df::tile_designation des = b->DesignationAt(coord);
DFHack::t_occupancy occ = b->OccupancyAt(coord); df::tile_occupancy occ = b->OccupancyAt(coord);
// Skip hidden tiles // Skip hidden tiles
if (!showHidden && des.bits.hidden) if (!showHidden && des.bits.hidden)
@ -346,7 +346,7 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
// Check for liquid // Check for liquid
if (des.bits.flow_size) if (des.bits.flow_size)
{ {
if (des.bits.liquid_type == liquid_magma) if (des.bits.liquid_type == df::tile_liquid::Magma)
liquidMagma.add(global_z); liquidMagma.add(global_z);
else else
liquidWater.add(global_z); liquidWater.add(global_z);
@ -388,20 +388,20 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
case DFHack::FEATSTONE: case DFHack::FEATSTONE:
if (blockFeatureLocal && des.bits.feature_local) if (blockFeatureLocal && des.bits.feature_local)
{ {
if (blockFeatureLocal->type == DFHack::feature_Adamantine_Tube if (blockFeatureLocal->type == df::feature_type::deep_special_tube
&& blockFeatureLocal->main_material == 0) // stone && blockFeatureLocal->main_material == 0) // stone
{ {
veinMats[blockFeatureLocal->sub_material].add(global_z); veinMats[blockFeatureLocal->sub_material].add(global_z);
} }
else if (showTemple else if (showTemple
&& blockFeatureLocal->type == DFHack::feature_Hell_Temple) && blockFeatureLocal->type == df::feature_type::deep_surface_portal)
{ {
hasDemonTemple = true; hasDemonTemple = true;
} }
} }
if (showSlade && blockFeatureGlobal && des.bits.feature_global if (showSlade && blockFeatureGlobal && des.bits.feature_global
&& blockFeatureGlobal->type == DFHack::feature_Underworld && blockFeatureGlobal->type == df::feature_type::feature_underworld_from_layer
&& blockFeatureGlobal->main_material == 0) // stone && blockFeatureGlobal->main_material == 0) // stone
{ {
layerMats[blockFeatureGlobal->sub_material].add(global_z); layerMats[blockFeatureGlobal->sub_material].add(global_z);

@ -27,10 +27,10 @@ bool isSafe(uint32_t x, uint32_t y, uint32_t z, DFHack::Maps *Maps)
return false; return false;
} }
// Adamantine tubes and temples lead to Hell // Adamantine tubes and temples lead to Hell
if (local_feature && local_feature->type != DFHack::feature_Other) if (local_feature && (local_feature->type == df::feature_type::deep_special_tube || local_feature->type == df::feature_type::deep_surface_portal))
return false; return false;
// And Hell *is* Hell. // And Hell *is* Hell.
if (global_feature && global_feature->type == DFHack::feature_Underworld) if (global_feature && global_feature->type == df::feature_type::feature_underworld_from_layer)
return false; return false;
// otherwise it's safe. // otherwise it's safe.
return true; return true;
@ -192,7 +192,7 @@ DFhackCExport command_result reveal(DFHack::Core * c, std::vector<std::string> &
{ {
for(uint32_t z = 0; z< z_max;z++) for(uint32_t z = 0; z< z_max;z++)
{ {
df_block *block = Maps->getBlock(x,y,z); df::map_block *block = Maps->getBlock(x,y,z);
if(block) if(block)
{ {
// 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
@ -288,7 +288,7 @@ DFhackCExport command_result unreveal(DFHack::Core * c, std::vector<std::string>
for(size_t i = 0; i < hidesaved.size();i++) for(size_t i = 0; i < hidesaved.size();i++)
{ {
hideblock & hb = hidesaved[i]; hideblock & hb = hidesaved[i];
df_block * b = Maps->getBlock(hb.x,hb.y,hb.z); df::map_block * b = Maps->getBlock(hb.x,hb.y,hb.z);
for (uint32_t i = 0; i < 16;i++) for (uint32_t j = 0; j < 16;j++) for (uint32_t i = 0; i < 16;i++) for (uint32_t j = 0; j < 16;j++)
{ {
b->designation[i][j].bits.hidden = hb.hiddens[i][j]; b->designation[i][j].bits.hidden = hb.hiddens[i][j];
@ -391,7 +391,7 @@ DFhackCExport command_result revflood(DFHack::Core * c, std::vector<std::string>
{ {
for(uint32_t z = 0; z< z_max;z++) for(uint32_t z = 0; z< z_max;z++)
{ {
df_block * b = Maps->getBlock(x,y,z); df::map_block * b = Maps->getBlock(x,y,z);
if(b) if(b)
{ {
// change the hidden flag to 0 // change the hidden flag to 0
@ -419,7 +419,7 @@ DFhackCExport command_result revflood(DFHack::Core * c, std::vector<std::string>
if(!MCache->testCoord(current)) if(!MCache->testCoord(current))
continue; continue;
int16_t tt = MCache->tiletypeAt(current); int16_t tt = MCache->tiletypeAt(current);
t_designation des = MCache->designationAt(current); df::tile_designation des = MCache->designationAt(current);
if(!des.bits.hidden) if(!des.bits.hidden)
{ {
continue; continue;

@ -19,6 +19,7 @@ using std::set;
#include "modules/Gui.h" #include "modules/Gui.h"
#include "TileTypes.h" #include "TileTypes.h"
#include "modules/MapCache.h" #include "modules/MapCache.h"
#include "df/tile_dig_designation.h"
using namespace MapExtras; using namespace MapExtras;
using namespace DFHack; using namespace DFHack;
@ -780,13 +781,13 @@ DFhackCExport command_result df_tiletypes (Core * c, vector <string> & parameter
for (coord_vec::iterator iter = all_tiles.begin(); iter != all_tiles.end(); ++iter) for (coord_vec::iterator iter = all_tiles.begin(); iter != all_tiles.end(); ++iter)
{ {
const DFHack::TileRow *source = DFHack::getTileRow(map.tiletypeAt(*iter)); const DFHack::TileRow *source = DFHack::getTileRow(map.tiletypeAt(*iter));
DFHack::t_designation des = map.designationAt(*iter); df::tile_designation des = map.designationAt(*iter);
if ((filter.shape > -1 && filter.shape != source->shape) if ((filter.shape > -1 && filter.shape != source->shape)
|| (filter.material > -1 && filter.material != source->material) || (filter.material > -1 && filter.material != source->material)
|| (filter.special > -1 && filter.special != source->special) || (filter.special > -1 && filter.special != source->special)
|| (filter.variant > -1 && filter.variant != source->variant) || (filter.variant > -1 && filter.variant != source->variant)
|| (filter.dig > -1 && (filter.dig != 0) != (des.bits.dig != DFHack::designation_no)) || (filter.dig > -1 && (filter.dig != 0) != (des.bits.dig != df::tile_dig_designation::No))
) )
{ {
continue; continue;
@ -865,7 +866,7 @@ DFhackCExport command_result df_tiletypes (Core * c, vector <string> & parameter
if (paint.skyview > -1) if (paint.skyview > -1)
{ {
des.bits.skyview = paint.skyview; des.bits.outside = paint.skyview;
} }
// Remove liquid from walls, etc // Remove liquid from walls, etc

@ -86,7 +86,7 @@ DFhackCExport command_result tubefill(DFHack::Core * c, std::vector<std::string>
{ {
// we're looking for addy tubes // we're looking for addy tubes
if(!locf) continue; if(!locf) continue;
if(locf->type != DFHack::feature_Adamantine_Tube) continue; if(locf->type != df::feature_type::deep_special_tube) continue;
dirty=0; dirty=0;
Mapz->ReadDesignations(x,y,z, &designations); Mapz->ReadDesignations(x,y,z, &designations);

@ -70,7 +70,7 @@ enum circle_what
bool dig (MapExtras::MapCache & MCache, bool dig (MapExtras::MapCache & MCache,
circle_what what, circle_what what,
e_designation type, df::tile_dig_designation type,
int32_t x, int32_t y, int32_t z, int32_t x, int32_t y, int32_t z,
int x_max, int y_max int x_max, int y_max
) )
@ -90,7 +90,7 @@ bool dig (MapExtras::MapCache & MCache,
return false; return false;
} }
uint16_t tt = MCache.tiletypeAt(at); uint16_t tt = MCache.tiletypeAt(at);
t_designation des = MCache.designationAt(at); df::tile_designation des = MCache.designationAt(at);
// could be potentially used to locate hidden constructions? // could be potentially used to locate hidden constructions?
if(tileMaterial(tt) == CONSTRUCTED && !des.bits.hidden) if(tileMaterial(tt) == CONSTRUCTED && !des.bits.hidden)
return false; return false;
@ -107,7 +107,7 @@ bool dig (MapExtras::MapCache & MCache,
break; break;
} }
if(isFloorTerrain(tt) if(isFloorTerrain(tt)
&& (type == designation_d_stair || type == designation_channel) && (type == df::tile_dig_designation::DownStair || type == df::tile_dig_designation::Channel)
&& ts != TREE_OK && ts != TREE_OK
&& ts != TREE_DEAD && ts != TREE_DEAD
) )
@ -115,7 +115,7 @@ bool dig (MapExtras::MapCache & MCache,
std::cerr << "allowing tt" << tt << ", is floor\n"; std::cerr << "allowing tt" << tt << ", is floor\n";
break; break;
} }
if(isStairTerrain(tt) && type == designation_channel ) if(isStairTerrain(tt) && type == df::tile_dig_designation::Channel )
break; break;
return false; return false;
} }
@ -124,25 +124,25 @@ bool dig (MapExtras::MapCache & MCache,
switch(what) switch(what)
{ {
case circle_set: case circle_set:
if(des.bits.dig == designation_no) if(des.bits.dig == df::tile_dig_designation::No)
{ {
des.bits.dig = type; des.bits.dig = type;
} }
break; break;
case circle_unset: case circle_unset:
if (des.bits.dig != designation_no) if (des.bits.dig != df::tile_dig_designation::No)
{ {
des.bits.dig = designation_no; des.bits.dig = df::tile_dig_designation::No;
} }
break; break;
case circle_invert: case circle_invert:
if(des.bits.dig == designation_no) if(des.bits.dig == df::tile_dig_designation::No)
{ {
des.bits.dig = type; des.bits.dig = type;
} }
else else
{ {
des.bits.dig = designation_no; des.bits.dig = df::tile_dig_designation::No;
} }
break; break;
} }
@ -153,7 +153,7 @@ bool dig (MapExtras::MapCache & MCache,
bool lineX (MapExtras::MapCache & MCache, bool lineX (MapExtras::MapCache & MCache,
circle_what what, circle_what what,
e_designation type, df::tile_dig_designation type,
int32_t y1, int32_t y2, int32_t x, int32_t z, int32_t y1, int32_t y2, int32_t x, int32_t z,
int x_max, int y_max int x_max, int y_max
) )
@ -167,7 +167,7 @@ bool lineX (MapExtras::MapCache & MCache,
bool lineY (MapExtras::MapCache & MCache, bool lineY (MapExtras::MapCache & MCache,
circle_what what, circle_what what,
e_designation type, df::tile_dig_designation type,
int32_t x1, int32_t x2, int32_t y, int32_t z, int32_t x1, int32_t x2, int32_t y, int32_t z,
int x_max, int y_max int x_max, int y_max
) )
@ -183,7 +183,7 @@ DFhackCExport command_result digcircle (Core * c, vector <string> & parameters)
{ {
static bool filled = false; static bool filled = false;
static circle_what what = circle_set; static circle_what what = circle_set;
static e_designation type = designation_default; static df::tile_dig_designation type = df::tile_dig_designation::Default;
static int diameter = 0; static int diameter = 0;
auto saved_d = diameter; auto saved_d = diameter;
bool force_help = false; bool force_help = false;
@ -215,27 +215,27 @@ DFhackCExport command_result digcircle (Core * c, vector <string> & parameters)
} }
else if(parameters[i] == "dig") else if(parameters[i] == "dig")
{ {
type = designation_default; type = df::tile_dig_designation::Default;
} }
else if(parameters[i] == "ramp") else if(parameters[i] == "ramp")
{ {
type = designation_ramp; type = df::tile_dig_designation::Ramp;
} }
else if(parameters[i] == "dstair") else if(parameters[i] == "dstair")
{ {
type = designation_d_stair; type = df::tile_dig_designation::DownStair;
} }
else if(parameters[i] == "ustair") else if(parameters[i] == "ustair")
{ {
type = designation_u_stair; type = df::tile_dig_designation::UpStair;
} }
else if(parameters[i] == "xstair") else if(parameters[i] == "xstair")
{ {
type = designation_ud_stair; type = df::tile_dig_designation::UpDownStair;
} }
else if(parameters[i] == "chan") else if(parameters[i] == "chan")
{ {
type = designation_channel; type = df::tile_dig_designation::Channel;
} }
else if (!from_string(diameter,parameters[i], std::dec)) else if (!from_string(diameter,parameters[i], std::dec))
{ {
@ -732,7 +732,7 @@ bool stamp_pattern (DFHack::Maps * maps,
int x_max, int y_max int x_max, int y_max
) )
{ {
df_block * bl = maps->getBlock(bx,by,z_level); df::map_block * bl = maps->getBlock(bx,by,z_level);
if(!bl) if(!bl)
return false; return false;
int x = 0,mx = 16; int x = 0,mx = 16;
@ -749,34 +749,34 @@ bool stamp_pattern (DFHack::Maps * maps,
my = 15; my = 15;
for(; y < my; y++) for(; y < my; y++)
{ {
naked_designation & des = bl->designation[x][y].bits; df::tile_designation & des = bl->designation[x][y];
short unsigned int tt = bl->tiletype[x][y]; short unsigned int tt = bl->tiletype[x][y];
// could be potentially used to locate hidden constructions? // could be potentially used to locate hidden constructions?
if(tileMaterial(tt) == CONSTRUCTED && !des.hidden) if(tileMaterial(tt) == CONSTRUCTED && !des.bits.hidden)
continue; continue;
if(!isWallTerrain(tt) && !des.hidden) if(!isWallTerrain(tt) && !des.bits.hidden)
continue; continue;
if(how == EXPLO_CLEAR) if(how == EXPLO_CLEAR)
{ {
des.dig = designation_no; des.bits.dig = df::tile_dig_designation::No;
continue; continue;
} }
if(dm[y][x]) if(dm[y][x])
{ {
if(what == EXPLO_ALL if(what == EXPLO_ALL
|| des.dig == designation_default && what == EXPLO_DESIGNATED || des.bits.dig == df::tile_dig_designation::Default && what == EXPLO_DESIGNATED
|| des.hidden && what == EXPLO_HIDDEN) || des.bits.hidden && what == EXPLO_HIDDEN)
{ {
des.dig = designation_default; des.bits.dig = df::tile_dig_designation::Default;
} }
} }
else if(what == EXPLO_DESIGNATED) else if(what == EXPLO_DESIGNATED)
{ {
des.dig = designation_no; des.bits.dig = df::tile_dig_designation::No;
} }
} }
} }
bl->flags.set(BLOCK_DESIGNATED); bl->flags.set(df::block_flags::Designated);
return true; return true;
}; };
@ -935,14 +935,14 @@ DFhackCExport command_result expdig (Core * c, vector <string> & parameters)
short unsigned int tt = mx.tiletypeAt(pos); short unsigned int tt = mx.tiletypeAt(pos);
if(tt == 0) if(tt == 0)
continue; continue;
t_designation des = mx.designationAt(pos); df::tile_designation des = mx.designationAt(pos);
if(tileMaterial(tt) == CONSTRUCTED && !des.bits.hidden) if(tileMaterial(tt) == CONSTRUCTED && !des.bits.hidden)
continue; continue;
if(!isWallTerrain(tt) && !des.bits.hidden) if(!isWallTerrain(tt) && !des.bits.hidden)
continue; continue;
if(cross[y][x]) if(cross[y][x])
{ {
des.bits.dig = designation_default; des.bits.dig = df::tile_dig_designation::Default;
mx.setDesignationAt(pos,des); mx.setDesignationAt(pos,des);
} }
} }
@ -1009,7 +1009,7 @@ DFhackCExport command_result vdig (Core * c, vector <string> & parameters)
return CR_FAILURE; return CR_FAILURE;
} }
MapExtras::MapCache * MCache = new MapExtras::MapCache(Maps); MapExtras::MapCache * MCache = new MapExtras::MapCache(Maps);
DFHack::t_designation des = MCache->designationAt(xy); df::tile_designation des = MCache->designationAt(xy);
int16_t tt = MCache->tiletypeAt(xy); int16_t tt = MCache->tiletypeAt(xy);
int16_t veinmat = MCache->veinMaterialAt(xy); int16_t veinmat = MCache->veinMaterialAt(xy);
if( veinmat == -1 ) if( veinmat == -1 )
@ -1034,9 +1034,9 @@ DFhackCExport command_result vdig (Core * c, vector <string> & parameters)
continue; continue;
// found a good tile, dig+unset material // found a good tile, dig+unset material
DFHack::t_designation des = MCache->designationAt(current); df::tile_designation des = MCache->designationAt(current);
DFHack::t_designation des_minus; df::tile_designation des_minus;
DFHack::t_designation des_plus; df::tile_designation des_plus;
des_plus.whole = des_minus.whole = 0; des_plus.whole = des_minus.whole = 0;
int16_t vmat_minus = -1; int16_t vmat_minus = -1;
int16_t vmat_plus = -1; int16_t vmat_plus = -1;
@ -1095,32 +1095,32 @@ DFhackCExport command_result vdig (Core * c, vector <string> & parameters)
{ {
flood.push(current-1); flood.push(current-1);
if(des_minus.bits.dig == DFHack::designation_d_stair) if(des_minus.bits.dig == df::tile_dig_designation::DownStair)
des_minus.bits.dig = DFHack::designation_ud_stair; des_minus.bits.dig = df::tile_dig_designation::UpDownStair;
else else
des_minus.bits.dig = DFHack::designation_u_stair; des_minus.bits.dig = df::tile_dig_designation::UpStair;
MCache->setDesignationAt(current-1,des_minus); MCache->setDesignationAt(current-1,des_minus);
des.bits.dig = DFHack::designation_d_stair; des.bits.dig = df::tile_dig_designation::DownStair;
} }
if(current.z < z_max - 1 && above && vmat_plus == vmat2) if(current.z < z_max - 1 && above && vmat_plus == vmat2)
{ {
flood.push(current+ 1); flood.push(current+ 1);
if(des_plus.bits.dig == DFHack::designation_u_stair) if(des_plus.bits.dig == df::tile_dig_designation::UpStair)
des_plus.bits.dig = DFHack::designation_ud_stair; des_plus.bits.dig = df::tile_dig_designation::UpDownStair;
else else
des_plus.bits.dig = DFHack::designation_d_stair; des_plus.bits.dig = df::tile_dig_designation::DownStair;
MCache->setDesignationAt(current+1,des_plus); MCache->setDesignationAt(current+1,des_plus);
if(des.bits.dig == DFHack::designation_d_stair) if(des.bits.dig == df::tile_dig_designation::DownStair)
des.bits.dig = DFHack::designation_ud_stair; des.bits.dig = df::tile_dig_designation::UpDownStair;
else else
des.bits.dig = DFHack::designation_u_stair; des.bits.dig = df::tile_dig_designation::UpStair;
} }
} }
if(des.bits.dig == DFHack::designation_no) if(des.bits.dig == df::tile_dig_designation::No)
des.bits.dig = DFHack::designation_default; des.bits.dig = df::tile_dig_designation::Default;
MCache->setDesignationAt(current,des); MCache->setDesignationAt(current,des);
} }
} }