|
|
@ -44,6 +44,7 @@ using namespace std;
|
|
|
|
#include "MiscUtils.h"
|
|
|
|
#include "MiscUtils.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "modules/Buildings.h"
|
|
|
|
#include "modules/Buildings.h"
|
|
|
|
|
|
|
|
#include "modules/Materials.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "DataDefs.h"
|
|
|
|
#include "DataDefs.h"
|
|
|
|
#include "df/world_data.h"
|
|
|
|
#include "df/world_data.h"
|
|
|
@ -178,19 +179,27 @@ void MapExtras::Block::init_tiles(bool basemat)
|
|
|
|
|
|
|
|
|
|
|
|
MapExtras::Block::TileInfo::TileInfo()
|
|
|
|
MapExtras::Block::TileInfo::TileInfo()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
frozen.clear();
|
|
|
|
|
|
|
|
dirty_raw.clear();
|
|
|
|
dirty_raw.clear();
|
|
|
|
memset(raw_tiles,0,sizeof(raw_tiles));
|
|
|
|
memset(raw_tiles,0,sizeof(raw_tiles));
|
|
|
|
|
|
|
|
ice_info = NULL;
|
|
|
|
con_info = NULL;
|
|
|
|
con_info = NULL;
|
|
|
|
dirty_base.clear();
|
|
|
|
|
|
|
|
memset(base_tiles,0,sizeof(base_tiles));
|
|
|
|
memset(base_tiles,0,sizeof(base_tiles));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MapExtras::Block::TileInfo::~TileInfo()
|
|
|
|
MapExtras::Block::TileInfo::~TileInfo()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
delete ice_info;
|
|
|
|
delete con_info;
|
|
|
|
delete con_info;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void MapExtras::Block::TileInfo::init_iceinfo()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (ice_info)
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ice_info = new IceInfo();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MapExtras::Block::TileInfo::init_coninfo()
|
|
|
|
void MapExtras::Block::TileInfo::init_coninfo()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (con_info)
|
|
|
|
if (con_info)
|
|
|
@ -242,7 +251,7 @@ bool MapExtras::Block::setVeinMaterialAt(df::coord2d pos, int16_t mat, df::inclu
|
|
|
|
auto &cur_mat = basemats->veinmat[pos.x][pos.y];
|
|
|
|
auto &cur_mat = basemats->veinmat[pos.x][pos.y];
|
|
|
|
auto &cur_type = basemats->veintype[pos.x][pos.y];
|
|
|
|
auto &cur_type = basemats->veintype[pos.x][pos.y];
|
|
|
|
|
|
|
|
|
|
|
|
if (cur_mat == mat && cur_type == type)
|
|
|
|
if (cur_mat == mat && (mat < 0 || cur_type == type))
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
if (mat >= 0)
|
|
|
|
if (mat >= 0)
|
|
|
@ -252,11 +261,7 @@ bool MapExtras::Block::setVeinMaterialAt(df::coord2d pos, int16_t mat, df::inclu
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
// Bad material?
|
|
|
|
// Bad material?
|
|
|
|
auto raw = df::inorganic_raw::find(mat);
|
|
|
|
if (!isStoneInorganic(mat))
|
|
|
|
if (!raw ||
|
|
|
|
|
|
|
|
raw->flags.is_set(inorganic_flags::SOIL_ANY) ||
|
|
|
|
|
|
|
|
raw->material.flags.is_set(material_flags::IS_METAL) ||
|
|
|
|
|
|
|
|
raw->material.flags.is_set(material_flags::NO_STONE_STOCKPILE))
|
|
|
|
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -266,7 +271,97 @@ bool MapExtras::Block::setVeinMaterialAt(df::coord2d pos, int16_t mat, df::inclu
|
|
|
|
basemats->vein_dirty.setassignment(pos, true);
|
|
|
|
basemats->vein_dirty.setassignment(pos, true);
|
|
|
|
|
|
|
|
|
|
|
|
if (tileMaterial(tiles->base_tiles[pos.x][pos.y]) == MINERAL)
|
|
|
|
if (tileMaterial(tiles->base_tiles[pos.x][pos.y]) == MINERAL)
|
|
|
|
basemats->mat_index[pos.x][pos.y] = mat;
|
|
|
|
basemats->set_base_mat(tiles, pos, 0, mat);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool MapExtras::Block::setStoneAt(df::coord2d pos, df::tiletype tile, int16_t mat, df::inclusion_type type, bool force_vein, bool kill_veins)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
using namespace df::enums::tiletype_material;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!block)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!isStoneInorganic(mat) || !isCoreMaterial(tile))
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!basemats)
|
|
|
|
|
|
|
|
init_tiles(true);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check if anything needs to be done
|
|
|
|
|
|
|
|
pos = pos & 15;
|
|
|
|
|
|
|
|
auto &cur_tile = tiles->base_tiles[pos.x][pos.y];
|
|
|
|
|
|
|
|
auto &cur_mattype = basemats->mat_type[pos.x][pos.y];
|
|
|
|
|
|
|
|
auto &cur_matidx = basemats->mat_index[pos.x][pos.y];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!force_vein && cur_tile == tile && cur_mattype == 0 && cur_matidx == mat)
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool vein = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (force_vein && type != inclusion_type::CLUSTER)
|
|
|
|
|
|
|
|
vein = true;
|
|
|
|
|
|
|
|
else if (mat == lavaStoneAt(pos))
|
|
|
|
|
|
|
|
tile = matchTileMaterial(tile, LAVA_STONE);
|
|
|
|
|
|
|
|
else if (mat == layerMaterialAt(pos))
|
|
|
|
|
|
|
|
tile = matchTileMaterial(tile, STONE);
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
vein = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (vein)
|
|
|
|
|
|
|
|
tile = matchTileMaterial(tile, MINERAL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (tile == tiletype::Void)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if ((vein || kill_veins) && !setVeinMaterialAt(pos, vein ? mat : -1, type))
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (cur_tile != tile)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
dirty_tiles = true;
|
|
|
|
|
|
|
|
tiles->set_base_tile(pos, tile);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
basemats->set_base_mat(tiles, pos, 0, mat);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool MapExtras::Block::setSoilAt(df::coord2d pos, df::tiletype tile, bool kill_veins)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
using namespace df::enums::tiletype_material;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!block)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!isCoreMaterial(tile))
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!basemats)
|
|
|
|
|
|
|
|
init_tiles(true);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pos = pos & 15;
|
|
|
|
|
|
|
|
auto &cur_tile = tiles->base_tiles[pos.x][pos.y];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tile = matchTileMaterial(tile, SOIL);
|
|
|
|
|
|
|
|
if (tile == tiletype::Void)
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (kill_veins && !setVeinMaterialAt(pos, -1))
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (cur_tile != tile)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
dirty_tiles = true;
|
|
|
|
|
|
|
|
tiles->set_base_tile(pos, tile);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int mat = layerMaterialAt(pos);
|
|
|
|
|
|
|
|
if (BlockInfo::getGroundType(mat) == BlockInfo::G_STONE)
|
|
|
|
|
|
|
|
mat = biomeInfoAt(pos).default_soil;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
basemats->set_base_mat(tiles, pos, 0, mat);
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -290,7 +385,9 @@ void MapExtras::Block::ParseTiles(TileInfo *tiles)
|
|
|
|
// Frozen liquid comes topmost
|
|
|
|
// Frozen liquid comes topmost
|
|
|
|
if (tileMaterial(tt) == FROZEN_LIQUID)
|
|
|
|
if (tileMaterial(tt) == FROZEN_LIQUID)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
tiles->frozen.setassignment(x,y,true);
|
|
|
|
tiles->init_iceinfo();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tiles->ice_info->frozen.setassignment(x,y,true);
|
|
|
|
if (icetiles[x][y] != tiletype::Void)
|
|
|
|
if (icetiles[x][y] != tiletype::Void)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
tt = icetiles[x][y];
|
|
|
|
tt = icetiles[x][y];
|
|
|
@ -328,11 +425,92 @@ void MapExtras::Block::ParseTiles(TileInfo *tiles)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void MapExtras::Block::TileInfo::set_base_tile(df::coord2d pos, df::tiletype tile)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
base_tiles[pos.x][pos.y] = tile;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (con_info)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (con_info->constructed.getassignment(pos))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
con_info->dirty.setassignment(pos, true);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
con_info->tiles[pos.x][pos.y] = tile;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (ice_info && ice_info->frozen.getassignment(pos))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
ice_info->dirty.setassignment(pos, true);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dirty_raw.setassignment(pos, true);
|
|
|
|
|
|
|
|
raw_tiles[pos.x][pos.y] = tile;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MapExtras::Block::WriteTiles(TileInfo *tiles)
|
|
|
|
void MapExtras::Block::WriteTiles(TileInfo *tiles)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int x = 0; x < 16; x++)
|
|
|
|
if (tiles->con_info)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int y = 0; y < 16; y++)
|
|
|
|
for (int y = 0; y < 16; y++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!tiles->con_info->dirty[y])
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int x = 0; x < 16; x++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!tiles->con_info->dirty.getassignment(x,y))
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
df::coord coord = block->map_pos + df::coord(x,y,0);
|
|
|
|
|
|
|
|
df::construction *con = df::construction::find(coord);
|
|
|
|
|
|
|
|
if (con)
|
|
|
|
|
|
|
|
con->original_tile = tiles->base_tiles[x][y];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tiles->con_info->dirty.clear();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (tiles->ice_info && tiles->ice_info->dirty.has_assignments())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
df::tiletype (*newtiles)[16] = (tiles->con_info ? tiles->con_info->tiles : tiles->base_tiles);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = block->block_events.size()-1; i >= 0; i--)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
auto event = block->block_events[i];
|
|
|
|
|
|
|
|
auto ice = strict_virtual_cast<df::block_square_event_frozen_liquidst>(event);
|
|
|
|
|
|
|
|
if (!ice)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int y = 0; y < 16; y++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!tiles->ice_info->dirty[y])
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int x = 0; x < 16; x++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!tiles->ice_info->dirty.getassignment(x,y))
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (ice->tiles[x][y] == tiletype::Void)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ice->tiles[x][y] = newtiles[x][y];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tiles->ice_info->dirty.clear();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int y = 0; y < 16; y++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!tiles->dirty_raw[y])
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int x = 0; x < 16; x++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (tiles->dirty_raw.getassignment(x,y))
|
|
|
|
if (tiles->dirty_raw.getassignment(x,y))
|
|
|
|
block->tiletype[x][y] = tiles->raw_tiles[x][y];
|
|
|
|
block->tiletype[x][y] = tiles->raw_tiles[x][y];
|
|
|
@ -358,19 +536,24 @@ void MapExtras::Block::ParseBasemats(TileInfo *tiles, BasematInfo *bmats)
|
|
|
|
auto tt = tiles->base_tiles[x][y];
|
|
|
|
auto tt = tiles->base_tiles[x][y];
|
|
|
|
auto mat = info.getBaseMaterial(tt, df::coord2d(x,y));
|
|
|
|
auto mat = info.getBaseMaterial(tt, df::coord2d(x,y));
|
|
|
|
|
|
|
|
|
|
|
|
bmats->mat_type[x][y] = mat.mat_type;
|
|
|
|
bmats->set_base_mat(tiles, df::coord2d(x,y), mat.mat_type, mat.mat_index);
|
|
|
|
bmats->mat_index[x][y] = mat.mat_index;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Copy base info back to construction layer
|
|
|
|
|
|
|
|
if (tiles->con_info && !tiles->con_info->constructed.getassignment(x,y))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
tiles->con_info->mat_type[x][y] = mat.mat_type;
|
|
|
|
|
|
|
|
tiles->con_info->mat_index[x][y] = mat.mat_index;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void MapExtras::Block::BasematInfo::set_base_mat(TileInfo *tiles, df::coord2d pos, int16_t type, int16_t idx)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
mat_type[pos.x][pos.y] = type;
|
|
|
|
|
|
|
|
mat_index[pos.x][pos.y] = idx;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Copy base info back to construction layer
|
|
|
|
|
|
|
|
if (tiles->con_info && !tiles->con_info->constructed.getassignment(pos))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
tiles->con_info->mat_type[pos.x][pos.y] = type;
|
|
|
|
|
|
|
|
tiles->con_info->mat_index[pos.x][pos.y] = idx;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MapExtras::Block::WriteVeins(TileInfo *tiles, BasematInfo *bmats)
|
|
|
|
void MapExtras::Block::WriteVeins(TileInfo *tiles, BasematInfo *bmats)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Classify modified tiles into distinct buckets
|
|
|
|
// Classify modified tiles into distinct buckets
|
|
|
|