378 lines
14 KiB
C++
378 lines
14 KiB
C++
/*******************************************************************************
|
|
M A P S
|
|
Read and write DF's map
|
|
*******************************************************************************/
|
|
#ifndef CL_MOD_MAPS
|
|
#define CL_MOD_MAPS
|
|
|
|
#include "dfhack/DFExport.h"
|
|
namespace DFHack
|
|
{
|
|
/***************************************************************************
|
|
T Y P E S
|
|
***************************************************************************/
|
|
|
|
enum e_feature
|
|
{
|
|
feature_Other,
|
|
feature_Adamantine_Tube,
|
|
feature_Underworld,
|
|
feature_Hell_Temple
|
|
};
|
|
static const char * sa_feature[]=
|
|
{
|
|
(char*)"Other",
|
|
(char*)"Adamantine Tube",
|
|
(char*)"Underworld",
|
|
(char*)"Hell Temple"
|
|
};
|
|
union planecoord
|
|
{
|
|
uint32_t xy;
|
|
struct
|
|
{
|
|
uint16_t x;
|
|
uint16_t y;
|
|
} dim;
|
|
bool operator<(const planecoord &other) const
|
|
{
|
|
if(other.xy < xy) return true;
|
|
return false;
|
|
}
|
|
};
|
|
struct t_feature
|
|
{
|
|
e_feature type;
|
|
int16_t main_material;
|
|
int32_t sub_material;
|
|
bool discovered; // placeholder.
|
|
uint32_t origin;
|
|
};
|
|
|
|
struct t_vein
|
|
{
|
|
uint32_t vtable;
|
|
int32_t type;
|
|
int16_t assignment[16];
|
|
uint32_t flags;
|
|
uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
|
|
};
|
|
// stores what tiles should appear when the ice melts
|
|
struct t_frozenliquidvein
|
|
{
|
|
uint32_t vtable;
|
|
int16_t tiles[16][16];
|
|
uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
|
|
};
|
|
|
|
struct t_spattervein
|
|
{
|
|
uint32_t vtable;
|
|
uint16_t mat1;
|
|
uint16_t unk1;
|
|
uint32_t mat2;
|
|
uint16_t mat3;
|
|
uint8_t intensity[16][16];
|
|
uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
|
|
};
|
|
|
|
enum BiomeOffset
|
|
{
|
|
eNorthWest,
|
|
eNorth,
|
|
eNorthEast,
|
|
eWest,
|
|
eHere,
|
|
eEast,
|
|
eSouthWest,
|
|
eSouth,
|
|
eSouthEast,
|
|
eBiomeCount
|
|
};
|
|
|
|
enum e_traffic
|
|
{
|
|
traffic_normal,
|
|
traffic_low,
|
|
traffic_high,
|
|
traffic_restricted
|
|
};
|
|
|
|
enum e_designation
|
|
{
|
|
designation_no,
|
|
designation_default, // dig walls, remove stairs and ramps, gather plants, fell trees
|
|
designation_ud_stair, // dig up/down stairs
|
|
designation_channel, // dig a channel
|
|
designation_ramp, // dig ramp out of a wall
|
|
designation_d_stair, // dig a stair down
|
|
designation_u_stair, // dig a stair up
|
|
designation_7 // whatever
|
|
};
|
|
|
|
enum e_liquidtype
|
|
{
|
|
liquid_water,
|
|
liquid_magma
|
|
};
|
|
|
|
struct naked_designation
|
|
{
|
|
unsigned int flow_size : 3; // how much liquid is here?
|
|
unsigned int pile : 1; // stockpile?
|
|
/*
|
|
* All the different dig designations... needs more info, probably an enum
|
|
*/
|
|
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 for details
|
|
*/
|
|
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; // needs enum
|
|
unsigned int flow_forbid : 1; // what?
|
|
unsigned int liquid_static : 1;
|
|
unsigned int feature_local : 1; // this tile is a part of a feature
|
|
unsigned int feature_global : 1; // this tile is a part of a feature
|
|
unsigned int liquid_character : 2; // those ripples on streams?
|
|
|
|
};
|
|
|
|
union t_designation
|
|
{
|
|
uint32_t whole;
|
|
naked_designation bits;
|
|
};
|
|
|
|
// occupancy flags (rat,dwarf,horse,built wall,not build wall,etc)
|
|
struct naked_occupancy
|
|
{
|
|
unsigned int building : 3;// building type... should be an enum?
|
|
// 7 = door
|
|
unsigned int unit : 1;
|
|
unsigned int unit_grounded : 1;
|
|
unsigned int item : 1;
|
|
// splatter. everyone loves splatter.
|
|
unsigned int mud : 1;
|
|
unsigned int vomit :1;
|
|
unsigned int broken_arrows_color :4;
|
|
unsigned int blood_g : 1;
|
|
unsigned int blood_g2 : 1;
|
|
unsigned int blood_b : 1;
|
|
unsigned int blood_b2 : 1;
|
|
unsigned int blood_y : 1;
|
|
unsigned int blood_y2 : 1;
|
|
unsigned int blood_m : 1;
|
|
unsigned int blood_m2 : 1;
|
|
unsigned int blood_c : 1;
|
|
unsigned int blood_c2 : 1;
|
|
unsigned int blood_w : 1;
|
|
unsigned int blood_w2 : 1;
|
|
unsigned int blood_o : 1;
|
|
unsigned int blood_o2 : 1;
|
|
unsigned int slime : 1;
|
|
unsigned int slime2 : 1;
|
|
unsigned int blood : 1;
|
|
unsigned int blood2 : 1;
|
|
unsigned int broken_arrows_variant : 1;
|
|
unsigned int snow : 1;
|
|
};
|
|
|
|
struct naked_occupancy_grouped
|
|
{
|
|
unsigned int building : 3;// building type... should be an enum?
|
|
// 7 = door
|
|
unsigned int unit : 1;
|
|
unsigned int unit_grounded : 1;
|
|
unsigned int item : 1;
|
|
// splatter. everyone loves splatter.
|
|
unsigned int splatter : 26;
|
|
};
|
|
|
|
union t_occupancy
|
|
{
|
|
uint32_t whole;
|
|
naked_occupancy bits;
|
|
naked_occupancy_grouped unibits;
|
|
};
|
|
|
|
// map block flags
|
|
struct naked_blockflags
|
|
{
|
|
unsigned int designated : 1;// designated for jobs (digging and stuff like that)
|
|
unsigned int unk_1 : 1; // possibly related to the designated flag
|
|
// two flags required for liquid flow. no idea why
|
|
unsigned int liquid_1 : 1;
|
|
unsigned int liquid_2 : 1;
|
|
unsigned int unk_2: 28; // rest of the flags is completely unknown
|
|
// there's a possibility that this flags field is shorter than 32 bits
|
|
};
|
|
|
|
union t_blockflags
|
|
{
|
|
uint32_t whole;
|
|
naked_blockflags bits;
|
|
};
|
|
|
|
typedef int16_t tiletypes40d [16][16];
|
|
typedef DFHack::t_designation designations40d [16][16];
|
|
typedef DFHack::t_occupancy occupancies40d [16][16];
|
|
typedef uint8_t biome_indices40d [16];
|
|
typedef uint16_t t_temperatures [16][16];
|
|
|
|
typedef struct
|
|
{
|
|
tiletypes40d tiletypes;
|
|
designations40d designation;
|
|
occupancies40d occupancy;
|
|
biome_indices40d biome_indices;
|
|
uint32_t origin; // the address where it came from
|
|
t_blockflags blockflags;
|
|
int16_t global_feature;
|
|
int16_t local_feature;
|
|
} mapblock40d;
|
|
|
|
/***************************************************************************
|
|
C L I E N T M O D U L E
|
|
***************************************************************************/
|
|
|
|
class DFContextPrivate;
|
|
struct t_viewscreen;
|
|
class DFHACK_EXPORT Maps
|
|
{
|
|
public:
|
|
|
|
Maps(DFHack::DFContextPrivate * d);
|
|
~Maps();
|
|
bool Start();
|
|
bool Finish();
|
|
|
|
// read region surroundings, get their vectors of geolayers so we can do translation (or just hand the translation table to the client)
|
|
// returns an array of 9 vectors of indices into stone matgloss
|
|
/**
|
|
Method for reading the geological surrounding of the currently loaded region.
|
|
assign is a reference to an array of nine vectors of unsigned words that are to be filled with the data
|
|
array is indexed by the BiomeOffset enum
|
|
|
|
I omitted resolving the layer matgloss in this API, because it would
|
|
introduce overhead by calling some method for each tile. You have to do it
|
|
yourself. First get the stuff from ReadGeology and then for each block get
|
|
the RegionOffsets. For each tile get the real region from RegionOffsets and
|
|
cross-reference it with the geology stuff (region -- array of vectors, depth --
|
|
vector). I'm thinking about turning that Geology stuff into a
|
|
two-dimensional array with static size.
|
|
|
|
this is the algorithm for applying matgloss:
|
|
void DfMap::applyGeoMatgloss(Block * b)
|
|
{
|
|
// load layer matgloss
|
|
for(int x_b = 0; x_b < BLOCK_SIZE; x_b++)
|
|
{
|
|
for(int y_b = 0; y_b < BLOCK_SIZE; y_b++)
|
|
{
|
|
int geolayer = b->designation[x_b][y_b].bits.geolayer_index;
|
|
int biome = b->designation[x_b][y_b].bits.biome;
|
|
b->material[x_b][y_b].type = Mat_Stone;
|
|
b->material[x_b][y_b].index = v_geology[b->RegionOffsets[biome]][geolayer];
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
bool ReadGeology( std::vector < std::vector <uint16_t> >& assign );
|
|
std::vector <t_feature> global_features;
|
|
// map between feature address and the read object
|
|
std::map <uint32_t, t_feature> local_feature_store;
|
|
// map between mangled coords and pointer to feature
|
|
|
|
bool ReadGlobalFeatures( std::vector <t_feature> & features);
|
|
bool ReadLocalFeatures( std::map <planecoord, std::vector<t_feature *> > & local_features );
|
|
/*
|
|
* BLOCK DATA
|
|
*/
|
|
/*
|
|
/// allocate and read pointers to map blocks
|
|
bool InitMap();
|
|
/// destroy the mapblock cache
|
|
bool DestroyMap();
|
|
*/
|
|
/// get size of the map in tiles
|
|
void getSize(uint32_t& x, uint32_t& y, uint32_t& z);
|
|
|
|
/**
|
|
* Return false/0 on failure, buffer allocated by client app, 256 items long
|
|
*/
|
|
bool isValidBlock(uint32_t blockx, uint32_t blocky, uint32_t blockz);
|
|
/**
|
|
* Get the address of a block or 0 if block is not valid
|
|
*/
|
|
uint32_t getBlockPtr (uint32_t blockx, uint32_t blocky, uint32_t blockz);
|
|
|
|
/// read 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);
|
|
|
|
/// read/write block tile types
|
|
bool ReadTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, tiletypes40d *buffer);
|
|
bool WriteTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, tiletypes40d *buffer);
|
|
|
|
/// read/write block designations
|
|
bool ReadDesignations(uint32_t blockx, uint32_t blocky, uint32_t blockz, designations40d *buffer);
|
|
bool WriteDesignations (uint32_t blockx, uint32_t blocky, uint32_t blockz, designations40d *buffer);
|
|
|
|
/// read/write temperatures
|
|
bool ReadTemperatures(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_temperatures *temp1, t_temperatures *temp2);
|
|
bool WriteTemperatures (uint32_t blockx, uint32_t blocky, uint32_t blockz, t_temperatures *temp1, t_temperatures *temp2);
|
|
|
|
/// read/write block occupancies
|
|
bool ReadOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, occupancies40d *buffer);
|
|
bool WriteOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, occupancies40d *buffer);
|
|
|
|
/// read/write the block dirty bit - this is used to mark a map block so that DF scans it for designated jobs like digging
|
|
bool ReadDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool &dirtybit);
|
|
bool WriteDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool dirtybit);
|
|
|
|
/// read/write the block flags
|
|
bool ReadBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz,
|
|
t_blockflags &blockflags);
|
|
bool WriteBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz,
|
|
t_blockflags blockflags);
|
|
/// read/write features
|
|
bool ReadFeatures(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t & local, int16_t & global);
|
|
bool WriteLocalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t local = -1);
|
|
bool WriteGlobalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t local = -1);
|
|
|
|
/// read region offsets of a block - used for determining layer stone matgloss
|
|
bool ReadRegionOffsets(uint32_t blockx, uint32_t blocky, uint32_t blockz,
|
|
biome_indices40d *buffer);
|
|
|
|
/// block event reading - mineral veins, what's under ice, blood smears and mud
|
|
bool ReadVeins(uint32_t x, uint32_t y, uint32_t z,
|
|
std::vector<t_vein>* veins,
|
|
std::vector<t_frozenliquidvein>* ices = 0,
|
|
std::vector<t_spattervein>* splatter = 0);
|
|
|
|
private:
|
|
struct Private;
|
|
Private *d;
|
|
};
|
|
}
|
|
#endif
|