diff --git a/LUA_API.rst b/LUA_API.rst
index ee3b1077c..fc86070c3 100644
--- a/LUA_API.rst
+++ b/LUA_API.rst
@@ -686,3 +686,80 @@ Units module
* ``dfhack.units.isSane(unit)``
The unit is capable of rational action, i.e. not dead, insane or zombie.
+
+* ``dfhack.units.isInBurrow(unit,burrow)``
+
+ Checks if the unit is in the burrow.
+
+* ``dfhack.units.setInBurrow(unit,burrow,enable)``
+
+ Adds or removes the unit from the burrow.
+
+
+Items module
+------------
+
+* ``dfhack.items.getOwner(item)``
+
+ Returns the owner unit or *nil*.
+
+* ``dfhack.items.setOwner(item,unit)``
+
+ Replaces the owner of the item. If unit is *nil*, removes ownership.
+ Returns *false* in case of error.
+
+
+Maps module
+-----------
+
+* ``dfhack.maps.getSize()``
+
+ Returns map size in blocks: *x, y, z*
+
+* ``dfhack.maps.getTileSize()``
+
+ Returns map size in tiles: *x, y, z*
+
+* ``dfhack.maps.getBlock(x,y,z)``
+
+ Returns a map block object for given x,y,z in local block coordinates.
+
+* ``dfhack.maps.getTileBlock(coords)``
+
+ Returns a map block object for given df::coord in local tile coordinates.
+
+* ``dfhack.maps.getRegionBiome(region_coord2d)``
+
+ Returns the biome info struct for the given global map region.
+
+* ``dfhack.maps.getGlobalInitFeature(index)``
+
+ Returns the global feature object with the given index.
+
+* ``dfhack.maps.getLocalInitFeature(region_coord2d,index)``
+
+ Returns the local feature object with the given region coords and index.
+
+* ``dfhack.maps.findBurrowByName(name)``
+
+ Returns the burrow pointer or *nil*.
+
+* ``dfhack.maps.listBurrowBlocks(burrow)``
+
+ Returns a table of map block pointers.
+
+* ``dfhack.maps.isBurrowTile(burrow,tile_coord)``
+
+ Checks if the tile is in burrow.
+
+* ``dfhack.maps.setBurrowTile(burrow,tile_coord,enable)``
+
+ Adds or removes the tile from the burrow. Returns *false* if invalid coords.
+
+* ``dfhack.maps.isBlockBurrowTile(burrow,block,x,y)``
+
+ Checks if the tile within the block is in burrow.
+
+* ``dfhack.maps.setBlockBurrowTile(burrow,block,x,y,enable)``
+
+ Adds or removes the tile from the burrow. Returns *false* if invalid coords.
diff --git a/Lua API.html b/Lua API.html
index 89e158037..7c3eeddb9 100644
--- a/Lua API.html
+++ b/Lua API.html
@@ -340,6 +340,8 @@ ul.auto-toc {
Gui module
Job module
Units module
+Items module
+Maps module
@@ -916,6 +918,68 @@ a lua list containing them.
dfhack.units.isSane(unit)
The unit is capable of rational action, i.e. not dead, insane or zombie.
+dfhack.units.isInBurrow(unit,burrow)
+Checks if the unit is in the burrow.
+
+dfhack.units.setInBurrow(unit,burrow,enable)
+Adds or removes the unit from the burrow.
+
+
+
+
+
+
+dfhack.items.getOwner(item)
+Returns the owner unit or nil.
+
+dfhack.items.setOwner(item,unit)
+Replaces the owner of the item. If unit is nil, removes ownership.
+Returns false in case of error.
+
+
+
+
+
+
+dfhack.maps.getSize()
+Returns map size in blocks: x, y, z
+
+dfhack.maps.getTileSize()
+Returns map size in tiles: x, y, z
+
+dfhack.maps.getBlock(x,y,z)
+Returns a map block object for given x,y,z in local block coordinates.
+
+dfhack.maps.getTileBlock(coords)
+Returns a map block object for given df::coord in local tile coordinates.
+
+dfhack.maps.getRegionBiome(region_coord2d)
+Returns the biome info struct for the given global map region.
+
+dfhack.maps.getGlobalInitFeature(index)
+Returns the global feature object with the given index.
+
+dfhack.maps.getLocalInitFeature(region_coord2d,index)
+Returns the local feature object with the given region coords and index.
+
+dfhack.maps.findBurrowByName(name)
+Returns the burrow pointer or nil.
+
+dfhack.maps.listBurrowBlocks(burrow)
+Returns a table of map block pointers.
+
+dfhack.maps.isBurrowTile(burrow,tile_coord)
+Checks if the tile is in burrow.
+
+dfhack.maps.setBurrowTile(burrow,tile_coord,enable)
+Adds or removes the tile from the burrow. Returns false if invalid coords.
+
+dfhack.maps.isBlockBurrowTile(burrow,block,x,y)
+Checks if the tile within the block is in burrow.
+
+dfhack.maps.setBlockBurrowTile(burrow,block,x,y,enable)
+Adds or removes the tile from the burrow. Returns false if invalid coords.
+
diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp
index c336e309c..febc59026 100644
--- a/library/LuaApi.cpp
+++ b/library/LuaApi.cpp
@@ -42,7 +42,9 @@ distribution.
#include "modules/Job.h"
#include "modules/Translation.h"
#include "modules/Units.h"
+#include "modules/Items.h"
#include "modules/Materials.h"
+#include "modules/Maps.h"
#include "LuaWrapper.h"
#include "LuaTools.h"
@@ -62,6 +64,7 @@ distribution.
#include "df/inorganic_raw.h"
#include "df/dfhack_material_category.h"
#include "df/job_material_category.h"
+#include "df/burrow.h"
#include
#include
@@ -70,6 +73,18 @@ distribution.
using namespace DFHack;
using namespace DFHack::LuaWrapper;
+template
+void push_pointer_vector(lua_State *state, const std::vector &pvec)
+{
+ lua_createtable(state,pvec.size(),0);
+
+ for (size_t i = 0; i < pvec.size(); i++)
+ {
+ Lua::PushDFObject(state, pvec[i]);
+ lua_rawseti(state, -2, i+1);
+ }
+}
+
/**************************************************
* Per-world persistent configuration storage API *
**************************************************/
@@ -527,9 +542,9 @@ static void OpenModule(lua_State *state, const char *mname,
lua_pop(state, 1);
}
-#define WRAPM(module, function) { #function, df::wrap_function(&module::function) }
-#define WRAP(function) { #function, df::wrap_function(&function) }
-#define WRAPN(name, function) { #name, df::wrap_function(&function) }
+#define WRAPM(module, function) { #function, df::wrap_function(module::function) }
+#define WRAP(function) { #function, df::wrap_function(function) }
+#define WRAPN(name, function) { #name, df::wrap_function(function) }
static const LuaWrapper::FunctionReg dfhack_module[] = {
WRAPM(Translation, TranslateName),
@@ -570,14 +585,7 @@ static int job_listNewlyCreated(lua_State *state)
if (Job::listNewlyCreated(&pvec, &nxid))
{
lua_pushinteger(state, nxid);
- lua_newtable(state);
-
- for (size_t i = 0; i < pvec.size(); i++)
- {
- Lua::PushDFObject(state, pvec[i]);
- lua_rawseti(state, -2, i+1);
- }
-
+ push_pointer_vector(state, pvec);
return 2;
}
else
@@ -597,9 +605,61 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = {
WRAPM(Units, isDead),
WRAPM(Units, isAlive),
WRAPM(Units, isSane),
+ WRAPM(Units, isInBurrow),
+ WRAPM(Units, setInBurrow),
{ NULL, NULL }
};
+static const LuaWrapper::FunctionReg dfhack_items_module[] = {
+ WRAPM(Items, getOwner),
+ WRAPM(Items, setOwner),
+ { NULL, NULL }
+};
+
+static bool maps_isBlockBurrowTile(df::burrow *burrow, df::map_block *block, int x, int y)
+{
+ return Maps::isBlockBurrowTile(burrow, block, df::coord2d(x,y));
+}
+
+static bool maps_setBlockBurrowTile(df::burrow *burrow, df::map_block *block, int x, int y, bool enable)
+{
+ return Maps::setBlockBurrowTile(burrow, block, df::coord2d(x,y), enable);
+}
+
+static const LuaWrapper::FunctionReg dfhack_maps_module[] = {
+ WRAPN(getBlock, (df::map_block* (*)(int32_t,int32_t,int32_t))Maps::getBlock),
+ WRAPN(getTileBlock, (df::map_block* (*)(df::coord))Maps::getTileBlock),
+ WRAPM(Maps, getRegionBiome),
+ WRAPM(Maps, getGlobalInitFeature),
+ WRAPM(Maps, getLocalInitFeature),
+ WRAPM(Maps, findBurrowByName),
+ WRAPN(isBlockBurrowTile, maps_isBlockBurrowTile),
+ WRAPN(setBlockBurrowTile, maps_setBlockBurrowTile),
+ WRAPM(Maps, isBurrowTile),
+ WRAPM(Maps, setBurrowTile),
+ { NULL, NULL }
+};
+
+static int maps_listBurrowBlocks(lua_State *state)
+{
+ luaL_checkany(state, 1);
+
+ auto ptr = Lua::GetDFObject(state, 1);
+ if (!ptr)
+ luaL_argerror(state, 1, "invalid burrow type");
+
+ std::vector pvec;
+ Maps::listBurrowBlocks(&pvec, ptr);
+ push_pointer_vector(state, pvec);
+ return 1;
+}
+
+static const luaL_Reg dfhack_maps_funcs[] = {
+ { "listBurrowBlocks", maps_listBurrowBlocks },
+ { NULL, NULL }
+};
+
+
/************************
* Main Open function *
************************/
@@ -613,4 +673,6 @@ void OpenDFHackApi(lua_State *state)
OpenModule(state, "gui", dfhack_gui_module);
OpenModule(state, "job", dfhack_job_module, dfhack_job_funcs);
OpenModule(state, "units", dfhack_units_module);
+ OpenModule(state, "items", dfhack_items_module);
+ OpenModule(state, "maps", dfhack_maps_module, dfhack_maps_funcs);
}
diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp
index 2f9ef9e81..40269da80 100644
--- a/library/LuaTypes.cpp
+++ b/library/LuaTypes.cpp
@@ -80,6 +80,15 @@ void constructed_identity::lua_write(lua_State *state, int fname_idx, void *ptr,
{
invoke_assign(state, this, ptr, val_index);
}
+ // Allow by-value assignment for wrapped function parameters
+ else if (fname_idx == UPVAL_METHOD_NAME && lua_isuserdata(state, val_index))
+ {
+ void *nval = get_object_internal(state, this, val_index, false);
+ if (!nval)
+ field_error(state, fname_idx, "incompatible type in complex assignment", "write");
+ if (!copy(ptr, nval))
+ field_error(state, fname_idx, "no copy support", "write");
+ }
else
field_error(state, fname_idx, "complex object", "write");
}
diff --git a/library/include/DataDefs.h b/library/include/DataDefs.h
index b9b4707d9..d4d757d94 100644
--- a/library/include/DataDefs.h
+++ b/library/include/DataDefs.h
@@ -425,6 +425,9 @@ namespace df
static compound_identity *get() { return &T::_identity; }
};
+ template
+ inline T* allocate() { return (T*)identity_traits::get()->allocate(); }
+
template
struct enum_traits {};
diff --git a/library/include/DataFuncs.h b/library/include/DataFuncs.h
index 6cd7d42f4..d78fe9e27 100644
--- a/library/include/DataFuncs.h
+++ b/library/include/DataFuncs.h
@@ -139,6 +139,14 @@ INSTANTIATE_WRAPPERS(3, (OSTREAM_ARG,A1,A2,A3), (out,vA1,vA2,vA3),
INSTANTIATE_RETURN_TYPE((A1,A2,A3,A4))
INSTANTIATE_WRAPPERS(4, (A1,A2,A3,A4), (vA1,vA2,vA3,vA4),
LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3); LOAD_ARG(A4);)
+INSTANTIATE_WRAPPERS(4, (OSTREAM_ARG,A1,A2,A3,A4), (out,vA1,vA2,vA3,vA4),
+ LOAD_OSTREAM(out); LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3); LOAD_ARG(A4);)
+#undef FW_TARGS
+
+#define FW_TARGS class A1, class A2, class A3, class A4, class A5
+INSTANTIATE_RETURN_TYPE((A1,A2,A3,A4,A5))
+INSTANTIATE_WRAPPERS(5, (A1,A2,A3,A4,A5), (vA1,vA2,vA3,vA4,vA5),
+ LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3); LOAD_ARG(A4); LOAD_ARG(A5);)
#undef FW_TARGS
#undef FW_TARGSC
diff --git a/library/include/MiscUtils.h b/library/include/MiscUtils.h
index c2a153eb1..0cf34c489 100644
--- a/library/include/MiscUtils.h
+++ b/library/include/MiscUtils.h
@@ -207,6 +207,22 @@ unsigned insert_into_vector(std::vector &vec, FT CT::*field, CT *obj, bool
return pos;
}
+template
+bool erase_from_vector(std::vector &vec, FT key)
+{
+ int pos = binsearch_index(vec, key);
+ vector_erase_at(vec, pos);
+ return pos >= 0;
+}
+
+template
+bool erase_from_vector(std::vector &vec, FT CT::*field, FT key)
+{
+ int pos = binsearch_index(vec, field, key);
+ vector_erase_at(vec, pos);
+ return pos >= 0;
+}
+
template
CT *binsearch_in_vector(const std::vector &vec, KT value)
{
diff --git a/library/include/df/custom/block_burrow.methods.inc b/library/include/df/custom/block_burrow.methods.inc
new file mode 100644
index 000000000..7754ab0db
--- /dev/null
+++ b/library/include/df/custom/block_burrow.methods.inc
@@ -0,0 +1,19 @@
+inline bool getassignment( const df::coord2d &xy )
+{
+ return getassignment(xy.x,xy.y);
+}
+inline bool getassignment( int x, int y )
+{
+ return (tile_bitmask[y] & (1 << x));
+}
+inline void setassignment( const df::coord2d &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] &= ~(1 << x);
+}
\ No newline at end of file
diff --git a/library/include/df/custom/block_square_event_mineralst.methods.inc b/library/include/df/custom/block_square_event_mineralst.methods.inc
index e01d22f72..7754ab0db 100644
--- a/library/include/df/custom/block_square_event_mineralst.methods.inc
+++ b/library/include/df/custom/block_square_event_mineralst.methods.inc
@@ -15,5 +15,5 @@ inline void setassignment( int x, int y, bool bit )
if(bit)
tile_bitmask[y] |= (1 << x);
else
- tile_bitmask[y] &= 0xFFFF ^ (1 << x);
+ tile_bitmask[y] &= ~(1 << x);
}
\ No newline at end of file
diff --git a/library/include/df/custom/coord2d.methods.inc b/library/include/df/custom/coord2d.methods.inc
index c27629458..f15475b6f 100644
--- a/library/include/df/custom/coord2d.methods.inc
+++ b/library/include/df/custom/coord2d.methods.inc
@@ -39,3 +39,7 @@ coord2d operator%(int number) const
{
return coord2d((x+number)%number, (y+number)%number);
}
+coord2d operator&(int number) const
+{
+ return coord2d(x&number, y&number);
+}
\ No newline at end of file
diff --git a/library/include/modules/Items.h b/library/include/modules/Items.h
index e58c9214b..9bab02cc8 100644
--- a/library/include/modules/Items.h
+++ b/library/include/modules/Items.h
@@ -122,16 +122,17 @@ DFHACK_EXPORT bool copyItem(df::item * source, dfh_item & target);
/// write copied item back to its origin
DFHACK_EXPORT bool writeItem(const dfh_item & item);
-/// who owns this item we already read?
-DFHACK_EXPORT int32_t getItemOwnerID(const df::item * item);
-DFHACK_EXPORT df::unit *getItemOwner(const df::item * item);
+/// Retrieve the owner of the item.
+DFHACK_EXPORT df::unit *getOwner(df::item *item);
+/// Set the owner of the item. Pass NULL as unit to remove the owner.
+DFHACK_EXPORT bool setOwner(df::item *item, df::unit *unit);
+
/// which item is it contained in?
DFHACK_EXPORT int32_t getItemContainerID(const df::item * item);
DFHACK_EXPORT df::item *getItemContainer(const df::item * item);
/// which items does it contain?
DFHACK_EXPORT bool getContainedItems(const df::item * item, /*output*/ std::vector &items);
-/// wipe out the owner records
-DFHACK_EXPORT bool removeItemOwner(df::item * item);
+
/// read item references, filtered by class
DFHACK_EXPORT bool readItemRefs(const df::item * item, const df::general_ref_type type,
/*output*/ std::vector &values);
diff --git a/library/include/modules/MapCache.h b/library/include/modules/MapCache.h
index b847d63f5..8eac514be 100644
--- a/library/include/modules/MapCache.h
+++ b/library/include/modules/MapCache.h
@@ -33,251 +33,187 @@ distribution.
#include "df/map_block.h"
#include "df/block_square_event_mineralst.h"
#include "df/construction.h"
+#include "df/item.h"
+
using namespace DFHack;
+
namespace MapExtras
{
-void SquashVeins (DFCoord bcoord, mapblock40d & mb, t_blockmaterials & materials)
-{
- memset(materials,-1,sizeof(materials));
- std::vector veins;
- Maps::SortBlockEvents(bcoord.x,bcoord.y,bcoord.z,&veins);
- for (uint32_t x = 0;x<16;x++) for (uint32_t y = 0; y< 16;y++)
- {
- df::tiletype tt = mb.tiletypes[x][y];
- if (tileMaterial(tt) == tiletype_material::MINERAL)
- {
- for (size_t i = 0; i < veins.size(); i++)
- {
- if (veins[i]->getassignment(x,y))
- materials[x][y] = veins[i]->inorganic_mat;
- }
- }
- }
-}
-void SquashFrozenLiquids (DFCoord bcoord, mapblock40d & mb, tiletypes40d & frozen)
-{
- std::vector ices;
- Maps::SortBlockEvents(bcoord.x,bcoord.y,bcoord.z,NULL,&ices);
- for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
- {
- df::tiletype tt = mb.tiletypes[x][y];
- frozen[x][y] = tiletype::Void;
- if (tileMaterial(tt) == tiletype_material::FROZEN_LIQUID)
- {
- for (size_t i = 0; i < ices.size(); i++)
- {
- df::tiletype tt2 = ices[i]->tiles[x][y];
- if (tt2 != tiletype::Void)
- {
- frozen[x][y] = tt2;
- break;
- }
- }
- }
- }
-}
+class DFHACK_EXPORT MapCache;
-void SquashConstructions (DFCoord bcoord, mapblock40d & mb, tiletypes40d & constructions)
-{
- for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
- {
- df::tiletype tt = mb.tiletypes[x][y];
- constructions[x][y] = tiletype::Void;
- if (tileMaterial(tt) == tiletype_material::CONSTRUCTION)
- {
- DFCoord coord(bcoord.x*16 + x, bcoord.y*16 + y, bcoord.z);
- df::construction *con = df::construction::find(coord);
- if (con)
- constructions[x][y] = con->original_tile;
- }
- }
+template inline R index_tile(T &v, df::coord2d p) {
+ return v[p.x&15][p.y&15];
}
-void SquashRocks ( std::vector< std::vector > * layerassign, mapblock40d & mb, t_blockmaterials & materials)
-{
- // get the layer materials
- for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
- {
- materials[x][y] = -1;
- uint8_t test = mb.designation[x][y].bits.biome;
- if ((test < sizeof(mb.biome_indices)) && (mb.biome_indices[test] < layerassign->size()))
- materials[x][y] = layerassign->at(mb.biome_indices[test])[mb.designation[x][y].bits.geolayer_index];
- }
+inline bool is_valid_tile_coord(df::coord2d p) {
+ return (p.x & ~15) == 0 && (p.y & ~15) == 0;
}
-class Block
+class DFHACK_EXPORT Block
{
- public:
- Block(DFCoord _bcoord, std::vector< std::vector > * layerassign = 0)
- {
- dirty_designations = false;
- dirty_tiletypes = false;
- dirty_temperatures = false;
- dirty_blockflags = false;
- dirty_occupancies = false;
- valid = false;
- bcoord = _bcoord;
- if(Maps::ReadBlock40d(bcoord.x,bcoord.y,bcoord.z,&raw))
- {
- Maps::ReadTemperatures(bcoord.x,bcoord.y, bcoord.z,&temp1,&temp2);
- SquashVeins(bcoord,raw,veinmats);
- SquashConstructions(bcoord, raw, contiles);
- SquashFrozenLiquids(bcoord, raw, icetiles);
- if(layerassign)
- SquashRocks(layerassign,raw,basemats);
- else
- memset(basemats,-1,sizeof(basemats));
- valid = true;
- }
+public:
+ Block(MapCache *parent, DFCoord _bcoord);
+ ~Block();
+
+ /*
+ * All coordinates are taken mod 16.
+ */
+
+ //Arbitrary tag field for flood fills etc.
+ int16_t &tag(df::coord2d p) {
+ return index_tile(tags, p);
}
+
int16_t veinMaterialAt(df::coord2d p)
{
- return veinmats[p.x][p.y];
+ return index_tile(veinmats,p);
}
int16_t baseMaterialAt(df::coord2d p)
{
- return basemats[p.x][p.y];
- }
-
- // the clear methods are used by the floodfill in digv and digl to mark tiles which were processed
- void ClearBaseMaterialAt(df::coord2d p)
- {
- basemats[p.x][p.y] = -1;
- }
- void ClearVeinMaterialAt(df::coord2d p)
- {
- veinmats[p.x][p.y] = -1;
+ return index_tile(basemats,p);
}
df::tiletype BaseTileTypeAt(df::coord2d p)
{
- if (contiles[p.x][p.y] != tiletype::Void)
- return contiles[p.x][p.y];
- else if (icetiles[p.x][p.y] != tiletype::Void)
- return icetiles[p.x][p.y];
- else
- return raw.tiletypes[p.x][p.y];
+ auto tt = index_tile(contiles,p);
+ if (tt != tiletype::Void) return tt;
+ tt = index_tile(icetiles,p);
+ if (tt != tiletype::Void) return tt;
+ return index_tile(rawtiles,p);
}
df::tiletype TileTypeAt(df::coord2d p)
{
- return raw.tiletypes[p.x][p.y];
+ return index_tile(rawtiles,p);
}
bool setTiletypeAt(df::coord2d p, df::tiletype tiletype)
{
if(!valid) return false;
dirty_tiletypes = true;
//printf("setting block %d/%d/%d , %d %d\n",x,y,z, p.x, p.y);
- raw.tiletypes[p.x][p.y] = tiletype;
+ index_tile(rawtiles,p) = tiletype;
return true;
}
uint16_t temperature1At(df::coord2d p)
{
- return temp1[p.x][p.y];
+ return index_tile(temp1,p);
}
bool setTemp1At(df::coord2d p, uint16_t temp)
{
if(!valid) return false;
dirty_temperatures = true;
- temp1[p.x][p.y] = temp;
+ index_tile(temp1,p) = temp;
return true;
}
uint16_t temperature2At(df::coord2d p)
{
- return temp2[p.x][p.y];
+ return index_tile(temp2,p);
}
bool setTemp2At(df::coord2d p, uint16_t temp)
{
if(!valid) return false;
dirty_temperatures = true;
- temp2[p.x][p.y] = temp;
+ index_tile(temp2,p) = temp;
return true;
}
df::tile_designation DesignationAt(df::coord2d p)
{
- return raw.designation[p.x][p.y];
+ return index_tile(designation,p);
}
bool setDesignationAt(df::coord2d p, df::tile_designation des)
{
if(!valid) return false;
dirty_designations = true;
//printf("setting block %d/%d/%d , %d %d\n",x,y,z, p.x, p.y);
- raw.designation[p.x][p.y] = des;
+ index_tile(designation,p) = des;
if(des.bits.dig)
{
dirty_blockflags = true;
- raw.blockflags.bits.designated = true;
+ blockflags.bits.designated = true;
}
return true;
}
df::tile_occupancy OccupancyAt(df::coord2d p)
{
- return raw.occupancy[p.x][p.y];
+ return index_tile(occupancy,p);
}
bool setOccupancyAt(df::coord2d p, df::tile_occupancy des)
{
if(!valid) return false;
dirty_occupancies = true;
- raw.occupancy[p.x][p.y] = des;
+ index_tile(occupancy,p) = des;
return true;
}
+ int itemCountAt(df::coord2d p)
+ {
+ if (!item_counts) init_item_counts();
+ return index_tile(item_counts,p);
+ }
+
t_blockflags BlockFlags()
{
- return raw.blockflags;
+ return blockflags;
}
bool setBlockFlags(t_blockflags des)
{
if(!valid) return false;
dirty_blockflags = true;
//printf("setting block %d/%d/%d , %d %d\n",x,y,z, p.x, p.y);
- raw.blockflags = des;
+ blockflags = des;
return true;
}
- bool Write ()
- {
- if(!valid) return false;
- if(dirty_designations)
- {
- Maps::WriteDesignations(bcoord.x,bcoord.y,bcoord.z, &raw.designation);
- Maps::WriteDirtyBit(bcoord.x,bcoord.y,bcoord.z,true);
- dirty_designations = false;
- }
- if(dirty_tiletypes)
- {
- Maps::WriteTileTypes(bcoord.x,bcoord.y,bcoord.z, &raw.tiletypes);
- dirty_tiletypes = false;
- }
- if(dirty_temperatures)
- {
- Maps::WriteTemperatures(bcoord.x,bcoord.y,bcoord.z, &temp1, &temp2);
- dirty_temperatures = false;
- }
- if(dirty_blockflags)
- {
- Maps::WriteBlockFlags(bcoord.x,bcoord.y,bcoord.z,raw.blockflags);
- dirty_blockflags = false;
- }
- if(dirty_occupancies)
- {
- Maps::WriteOccupancy(bcoord.x,bcoord.y,bcoord.z,&raw.occupancy);
- dirty_occupancies = false;
- }
- return true;
- }
- bool valid:1;
+ bool Write();
+
+ df::coord2d biomeRegionAt(df::coord2d p);
+ int16_t GeoIndexAt(df::coord2d p);
+
+ bool GetGlobalFeature(t_feature *out);
+ bool GetLocalFeature(t_feature *out);
+
+ bool is_valid() { return valid; }
+ df::map_block *getRaw() { return block; }
+
+private:
+ friend class MapCache;
+
+ MapCache *parent;
+ df::map_block *block;
+
+ static void SquashVeins(df::map_block *mb, t_blockmaterials & materials);
+ static void SquashFrozenLiquids (df::map_block *mb, tiletypes40d & frozen);
+ static void SquashConstructions (df::map_block *mb, tiletypes40d & constructions);
+ static void SquashRocks (df::map_block *mb, t_blockmaterials & materials,
+ std::vector< std::vector > * layerassign);
+
+ bool valid;
bool dirty_designations:1;
bool dirty_tiletypes:1;
bool dirty_temperatures:1;
bool dirty_blockflags:1;
bool dirty_occupancies:1;
- mapblock40d raw;
+
DFCoord bcoord;
+
+ int16_t tags[16][16];
+
+ typedef int T_item_counts[16];
+ T_item_counts *item_counts;
+ void init_item_counts();
+
+ bool addItemOnGround(df::item *item);
+ bool removeItemOnGround(df::item *item);
+
+ tiletypes40d rawtiles;
+ designations40d designation;
+ occupancies40d occupancy;
+ t_blockflags blockflags;
+
t_blockmaterials veinmats;
t_blockmaterials basemats;
t_temperatures temp1;
@@ -286,14 +222,15 @@ class Block
tiletypes40d icetiles; // what's underneath ice
};
-class MapCache
+class DFHACK_EXPORT MapCache
{
public:
MapCache()
{
valid = 0;
Maps::getSize(x_bmax, y_bmax, z_max);
- validgeo = Maps::ReadGeology( layerassign );
+ x_tmax = x_bmax*16; y_tmax = y_bmax*16;
+ validgeo = Maps::ReadGeology(&layer_mats, &geoidx);
valid = true;
};
~MapCache()
@@ -304,192 +241,116 @@ class MapCache
{
return valid;
}
+
/// get the map block at a *block* coord. Block coord = tile coord / 16
- Block * BlockAt (DFCoord blockcoord)
- {
- if(!valid)
- return 0;
- std::map ::iterator iter = blocks.find(blockcoord);
- if(iter != blocks.end())
- {
- return (*iter).second;
- }
- else
- {
- if(blockcoord.x >= 0 && blockcoord.x < x_bmax &&
- blockcoord.y >= 0 && blockcoord.y < y_bmax &&
- blockcoord.z >= 0 && blockcoord.z < z_max)
- {
- Block * nblo;
- if(validgeo)
- nblo = new Block(blockcoord, &layerassign);
- else
- nblo = new Block(blockcoord);
- blocks[blockcoord] = nblo;
- return nblo;
- }
- return 0;
- }
+ Block *BlockAt(DFCoord blockcoord);
+ /// get the map block at a tile coord.
+ Block *BlockAtTile(DFCoord coord) {
+ return BlockAt(df::coord(coord.x>>4,coord.y>>4,coord.z));
}
+
df::tiletype baseTiletypeAt (DFCoord tilecoord)
{
- Block * b= BlockAt(tilecoord / 16);
- if(b && b->valid)
- {
- return b->BaseTileTypeAt(tilecoord % 16);
- }
- return tiletype::Void;
+ Block * b= BlockAtTile(tilecoord);
+ return b ? b->BaseTileTypeAt(tilecoord) : tiletype::Void;
}
df::tiletype tiletypeAt (DFCoord tilecoord)
{
- Block * b= BlockAt(tilecoord / 16);
- if(b && b->valid)
- {
- return b->TileTypeAt(tilecoord % 16);
- }
- return tiletype::Void;
+ Block * b= BlockAtTile(tilecoord);
+ return b ? b->TileTypeAt(tilecoord) : tiletype::Void;
}
bool setTiletypeAt(DFCoord tilecoord, df::tiletype tiletype)
{
- Block * b= BlockAt(tilecoord / 16);
- if(b && b->valid)
- {
- b->setTiletypeAt(tilecoord % 16, tiletype);
- return true;
- }
+ if (Block * b= BlockAtTile(tilecoord))
+ return b->setTiletypeAt(tilecoord, tiletype);
return false;
}
uint16_t temperature1At (DFCoord tilecoord)
{
- Block * b= BlockAt(tilecoord / 16);
- if(b && b->valid)
- {
- return b->temperature1At(tilecoord % 16);
- }
- return 0;
+ Block * b= BlockAtTile(tilecoord);
+ return b ? b->temperature1At(tilecoord) : 0;
}
bool setTemp1At(DFCoord tilecoord, uint16_t temperature)
{
- Block * b= BlockAt(tilecoord / 16);
- if(b && b->valid)
- {
- b->setTemp1At(tilecoord % 16, temperature);
- return true;
- }
+ if (Block * b= BlockAtTile(tilecoord))
+ return b->setTemp1At(tilecoord, temperature);
return false;
}
uint16_t temperature2At (DFCoord tilecoord)
{
- Block * b= BlockAt(tilecoord / 16);
- if(b && b->valid)
- {
- return b->temperature2At(tilecoord % 16);
- }
- return 0;
+ Block * b= BlockAtTile(tilecoord);
+ return b ? b->temperature2At(tilecoord) : 0;
}
bool setTemp2At(DFCoord tilecoord, uint16_t temperature)
{
- Block * b= BlockAt(tilecoord / 16);
- if(b && b->valid)
- {
- b->setTemp2At(tilecoord % 16, temperature);
- return true;
- }
+ if (Block * b= BlockAtTile(tilecoord))
+ return b->setTemp2At(tilecoord, temperature);
return false;
}
int16_t veinMaterialAt (DFCoord tilecoord)
{
- Block * b= BlockAt(tilecoord / 16);
- if(b && b->valid)
- {
- return b->veinMaterialAt(tilecoord % 16);
- }
- return 0;
+ Block * b= BlockAtTile(tilecoord);
+ return b ? b->veinMaterialAt(tilecoord) : -1;
}
int16_t baseMaterialAt (DFCoord tilecoord)
{
- Block * b= BlockAt(tilecoord / 16);
- if(b && b->valid)
- {
- return b->baseMaterialAt(tilecoord % 16);
- }
- return 0;
+ Block * b= BlockAtTile(tilecoord);
+ return b ? b->baseMaterialAt(tilecoord) : -1;
}
- bool clearVeinMaterialAt (DFCoord tilecoord)
+
+ int16_t tagAt(DFCoord tilecoord)
{
- Block * b= BlockAt(tilecoord / 16);
- if(b && b->valid)
- {
- b->ClearVeinMaterialAt(tilecoord % 16);
- }
- return 0;
+ Block * b= BlockAtTile(tilecoord);
+ return b ? b->tag(tilecoord) : 0;
}
- bool clearBaseMaterialAt (DFCoord tilecoord)
+ void setTagAt(DFCoord tilecoord, int16_t val)
{
- Block * b= BlockAt(tilecoord / 16);
- if(b && b->valid)
- {
- b->ClearBaseMaterialAt(tilecoord % 16);
- }
- return 0;
+ Block * b= BlockAtTile(tilecoord);
+ if (b) b->tag(tilecoord) = val;
}
-
+
df::tile_designation designationAt (DFCoord tilecoord)
{
- Block * b= BlockAt(tilecoord / 16);
- if(b && b->valid)
- {
- return b->DesignationAt(tilecoord % 16);
- }
- df::tile_designation temp;
- temp.whole = 0;
- return temp;
+ Block * b= BlockAtTile(tilecoord);
+ return b ? b->DesignationAt(tilecoord) : df::tile_designation(0);
}
bool setDesignationAt (DFCoord tilecoord, df::tile_designation des)
{
- Block * b= BlockAt(tilecoord / 16);
- if(b && b->valid)
- {
- b->setDesignationAt(tilecoord % 16, des);
- return true;
- }
+ if(Block * b= BlockAtTile(tilecoord))
+ return b->setDesignationAt(tilecoord, des);
return false;
}
-
+
df::tile_occupancy occupancyAt (DFCoord tilecoord)
{
- Block * b= BlockAt(tilecoord / 16);
- if(b && b->valid)
- {
- return b->OccupancyAt(tilecoord % 16);
- }
- df::tile_occupancy temp;
- temp.whole = 0;
- return temp;
+ Block * b= BlockAtTile(tilecoord);
+ return b ? b->OccupancyAt(tilecoord) : df::tile_occupancy(0);
}
bool setOccupancyAt (DFCoord tilecoord, df::tile_occupancy occ)
{
- Block * b= BlockAt(tilecoord / 16);
- if(b && b->valid)
- {
- b->setOccupancyAt(tilecoord % 16, occ);
- return true;
- }
+ if (Block * b= BlockAtTile(tilecoord))
+ return b->setOccupancyAt(tilecoord, occ);
return false;
}
-
+
bool testCoord (DFCoord tilecoord)
{
- Block * b= BlockAt(tilecoord / 16);
- if(b && b->valid)
- {
- return true;
- }
- return false;
+ Block * b= BlockAtTile(tilecoord);
+ return (b && b->valid);
}
+
+ bool addItemOnGround(df::item *item) {
+ Block * b= BlockAtTile(item->pos);
+ return b ? b->addItemOnGround(item) : false;
+ }
+ bool removeItemOnGround(df::item *item) {
+ Block * b= BlockAtTile(item->pos);
+ return b ? b->removeItemOnGround(item) : false;
+ }
+
bool WriteAll()
{
std::map::iterator p;
@@ -508,15 +369,25 @@ class MapCache
}
blocks.clear();
}
- private:
- volatile bool valid;
- volatile bool validgeo;
+
+ uint32_t maxBlockX() { return x_bmax; }
+ uint32_t maxBlockY() { return y_bmax; }
+ uint32_t maxTileX() { return x_tmax; }
+ uint32_t maxTileY() { return y_tmax; }
+ uint32_t maxZ() { return z_max; }
+
+private:
+ friend class Block;
+
+ bool valid;
+ bool validgeo;
uint32_t x_bmax;
uint32_t y_bmax;
uint32_t x_tmax;
uint32_t y_tmax;
uint32_t z_max;
- std::vector< std::vector > layerassign;
+ std::vector geoidx;
+ std::vector< std::vector > layer_mats;
std::map blocks;
};
}
diff --git a/library/include/modules/Maps.h b/library/include/modules/Maps.h
index 873da7a9e..0de262264 100644
--- a/library/include/modules/Maps.h
+++ b/library/include/modules/Maps.h
@@ -38,7 +38,7 @@ distribution.
#include "modules/Materials.h"
#include "df/world.h"
-#include "df/feature_init.h"
+#include "df/world_data.h"
#include "df/map_block.h"
#include "df/block_square_event.h"
#include "df/block_square_event_mineralst.h"
@@ -49,12 +49,20 @@ distribution.
#include "df/tile_liquid.h"
#include "df/tile_dig_designation.h"
#include "df/tile_traffic.h"
+#include "df/feature_init.h"
/**
* \defgroup grp_maps Maps module and its types
* @ingroup grp_modules
*/
+namespace df
+{
+ struct burrow;
+ struct world_data;
+ struct block_burrow;
+}
+
namespace DFHack
{
/***************************************************************************
@@ -103,31 +111,11 @@ enum BiomeOffset
eBiomeCount
};
-/**
- * map block flags
- * \ingroup grp_maps
- */
-struct naked_blockflags
-{
- /// designated for jobs (digging and stuff like that)
- unsigned int designated : 1;
- /// possibly related to the designated flag
- unsigned int unk_1 : 1;
- /// two flags required for liquid flow.
- unsigned int liquid_1 : 1;
- unsigned int liquid_2 : 1;
- /// rest of the flags is completely unknown
- unsigned int unk_2: 4;
-};
/**
* map block flags wrapper
* \ingroup grp_maps
*/
-union t_blockflags
-{
- uint32_t whole;
- naked_blockflags bits;
-};
+typedef df::block_flags t_blockflags;
/**
* 16x16 array of tile types
@@ -161,30 +149,6 @@ typedef uint8_t biome_indices40d [9];
* \ingroup grp_maps
*/
typedef uint16_t t_temperatures [16][16];
-/**
- * structure for holding whole blocks
- * \ingroup grp_maps
- */
-typedef struct
-{
- DFCoord position;
- /// type of the tiles
- tiletypes40d tiletypes;
- /// flags determining the state of the tiles
- designations40d designation;
- /// flags determining what's on the tiles
- occupancies40d occupancy;
- /// values used for geology/biome assignment
- biome_indices40d biome_indices;
- /// the address where the block came from
- df::map_block * origin;
- t_blockflags blockflags;
- /// index into the global feature vector
- int32_t global_feature;
- /// index into the local feature vector... complicated
- int32_t local_feature;
- int32_t mystery;
-} mapblock40d;
/**
* The Maps module
@@ -231,30 +195,33 @@ void DfMap::applyGeoMatgloss(Block * b)
* @endcode
*/
-extern DFHACK_EXPORT bool ReadGeology( std::vector < std::vector >& assign );
-
+extern DFHACK_EXPORT bool ReadGeology(std::vector > *layer_mats,
+ std::vector *geoidx);
/**
- * Get the feature indexes of a block
+ * Get pointers to features of a block
*/
-extern DFHACK_EXPORT bool ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int32_t & local, int32_t & global);
+extern DFHACK_EXPORT bool ReadFeatures(uint32_t x, uint32_t y, uint32_t z, t_feature * local, t_feature * global);
/**
- * Set the feature indexes of a block
+ * Get pointers to features of an already read block
*/
-extern DFHACK_EXPORT bool WriteFeatures(uint32_t x, uint32_t y, uint32_t z, const int32_t & local, const int32_t & global);
+extern DFHACK_EXPORT bool ReadFeatures(df::map_block * block,t_feature * local, t_feature * global);
+
+
/**
- * Get pointers to features of a block
+ * Get a pointer to a specific global feature directly.
*/
-extern DFHACK_EXPORT bool ReadFeatures(uint32_t x, uint32_t y, uint32_t z, t_feature * local, t_feature * global);
+DFHACK_EXPORT df::feature_init *getGlobalInitFeature(int32_t index);
/**
- * Get pointers to features of an already read block
+ * Get a pointer to a specific local feature directly. rgn_coord is in the world region grid.
*/
-extern DFHACK_EXPORT bool ReadFeatures(mapblock40d * block,t_feature * local, t_feature * global);
+DFHACK_EXPORT df::feature_init *getLocalInitFeature(df::coord2d rgn_coord, int32_t index);
/**
* Read a specific global or local feature directly
*/
extern DFHACK_EXPORT bool GetGlobalFeature(t_feature &feature, int32_t index);
-extern DFHACK_EXPORT bool GetLocalFeature(t_feature &feature, df::coord2d coord, int32_t index);
+//extern DFHACK_EXPORT bool GetLocalFeature(t_feature &feature, df::coord2d rgn_coord, int32_t index);
+
/*
* BLOCK DATA
@@ -269,48 +236,16 @@ extern DFHACK_EXPORT void getPosition(int32_t& x, int32_t& y, int32_t& z);
* Get the map block or NULL if block is not valid
*/
extern DFHACK_EXPORT df::map_block * getBlock (int32_t blockx, int32_t blocky, int32_t blockz);
-extern DFHACK_EXPORT df::map_block * getBlockAbs (int32_t x, int32_t y, int32_t z);
+extern DFHACK_EXPORT df::map_block * getTileBlock (int32_t x, int32_t y, int32_t z);
inline df::map_block * getBlock (df::coord pos) { return getBlock(pos.x, pos.y, pos.z); }
-inline df::map_block * getBlockAbs (df::coord pos) { return getBlockAbs(pos.x, pos.y, pos.z); }
-
-/// copy the whole map block at block coords (see DFTypes.h for the block structure)
-extern DFHACK_EXPORT bool ReadBlock40d(uint32_t blockx, uint32_t blocky, uint32_t blockz, mapblock40d * buffer);
-
-/// copy/write block tile types
-extern DFHACK_EXPORT bool ReadTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, tiletypes40d *buffer);
-extern DFHACK_EXPORT bool WriteTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, tiletypes40d *buffer);
-
-/// copy/write block designations
-extern DFHACK_EXPORT bool ReadDesignations(uint32_t blockx, uint32_t blocky, uint32_t blockz, designations40d *buffer);
-extern DFHACK_EXPORT bool WriteDesignations (uint32_t blockx, uint32_t blocky, uint32_t blockz, designations40d *buffer);
-
-/// copy/write temperatures
-extern DFHACK_EXPORT bool ReadTemperatures(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_temperatures *temp1, t_temperatures *temp2);
-extern DFHACK_EXPORT bool WriteTemperatures (uint32_t blockx, uint32_t blocky, uint32_t blockz, t_temperatures *temp1, t_temperatures *temp2);
-
-/// copy/write block occupancies
-extern DFHACK_EXPORT bool ReadOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, occupancies40d *buffer);
-extern DFHACK_EXPORT bool WriteOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, occupancies40d *buffer);
-
-/// copy/write the block dirty bit - this is used to mark a map block so that DF scans it for designated jobs like digging
-extern DFHACK_EXPORT bool ReadDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool &dirtybit);
-extern DFHACK_EXPORT bool WriteDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool dirtybit);
-
-/// copy/write the block flags
-extern DFHACK_EXPORT bool ReadBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags &blockflags);
-extern DFHACK_EXPORT bool WriteBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags blockflags);
+inline df::map_block * getTileBlock (df::coord pos) { return getTileBlock(pos.x, pos.y, pos.z); }
-/// copy/write features
-extern DFHACK_EXPORT bool SetBlockLocalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int32_t local = -1);
-extern DFHACK_EXPORT bool SetBlockGlobalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int32_t global = -1);
-
-/// copy region offsets of a block - used for determining layer stone matgloss
-extern DFHACK_EXPORT bool ReadRegionOffsets(uint32_t blockx, uint32_t blocky, uint32_t blockz, biome_indices40d *buffer);
+DFHACK_EXPORT df::world_data::T_region_map *getRegionBiome(df::coord2d rgn_pos);
/// sorts the block event vector into multiple vectors by type
/// mineral veins, what's under ice, blood smears and mud
-extern DFHACK_EXPORT bool SortBlockEvents(uint32_t x, uint32_t y, uint32_t z,
+extern DFHACK_EXPORT bool SortBlockEvents(df::map_block *block,
std::vector* veins,
std::vector* ices = 0,
std::vector* splatter = 0,
@@ -321,8 +256,25 @@ extern DFHACK_EXPORT bool SortBlockEvents(uint32_t x, uint32_t y, uint32_t z,
/// remove a block event from the block by address
extern DFHACK_EXPORT bool RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, df::block_square_event * which );
-/// read all plants in this block
-extern DFHACK_EXPORT bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector*& plants);
+/*
+ * BURROWS
+ */
+
+DFHACK_EXPORT df::burrow *findBurrowByName(std::string name);
+
+void listBurrowBlocks(std::vector *pvec, df::burrow *burrow);
+
+df::block_burrow *getBlockBurrowMask(df::burrow *burrow, df::map_block *block, bool create = false);
+
+bool isBlockBurrowTile(df::burrow *burrow, df::map_block *block, df::coord2d tile);
+bool setBlockBurrowTile(df::burrow *burrow, df::map_block *block, df::coord2d tile, bool enable);
+
+inline bool isBurrowTile(df::burrow *burrow, df::coord tile) {
+ return isBlockBurrowTile(burrow, getTileBlock(tile), tile);
+}
+inline bool setBurrowTile(df::burrow *burrow, df::coord tile, bool enable) {
+ return setBlockBurrowTile(burrow, getTileBlock(tile), tile, enable);
+}
}
}
diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h
index 838d1d596..12e687112 100644
--- a/library/include/modules/Units.h
+++ b/library/include/modules/Units.h
@@ -36,6 +36,7 @@ distribution.
namespace df
{
struct nemesis_record;
+ struct burrow;
}
/**
@@ -184,9 +185,6 @@ DFHACK_EXPORT bool ReadJob(const df::unit * unit, std::vector & mat)
DFHACK_EXPORT bool ReadInventoryByIdx(const uint32_t index, std::vector & item);
DFHACK_EXPORT bool ReadInventoryByPtr(const df::unit * unit, std::vector & item);
-DFHACK_EXPORT bool ReadOwnedItemsByIdx(const uint32_t index, std::vector & item);
-DFHACK_EXPORT bool ReadOwnedItemsByPtr(const df::unit * unit, std::vector & item);
-
DFHACK_EXPORT int32_t FindIndexById(int32_t id);
/* Getters */
@@ -195,9 +193,6 @@ DFHACK_EXPORT int32_t GetDwarfCivId ( void );
DFHACK_EXPORT void CopyNameTo(df::unit *creature, df::language_name * target);
-DFHACK_EXPORT bool RemoveOwnedItemByIdx(const uint32_t index, int32_t id);
-DFHACK_EXPORT bool RemoveOwnedItemByPtr(df::unit * unit, int32_t id);
-
DFHACK_EXPORT void setNickname(df::unit *unit, std::string nick);
DFHACK_EXPORT df::language_name *getVisibleName(df::unit *unit);
@@ -206,6 +201,10 @@ DFHACK_EXPORT df::nemesis_record *getNemesis(df::unit *unit);
DFHACK_EXPORT bool isDead(df::unit *unit);
DFHACK_EXPORT bool isAlive(df::unit *unit);
DFHACK_EXPORT bool isSane(df::unit *unit);
+
+DFHACK_EXPORT bool isInBurrow(df::unit *unit, df::burrow *burrow);
+DFHACK_EXPORT void setInBurrow(df::unit *unit, df::burrow *burrow, bool enable);
+
}
}
#endif
diff --git a/library/lua/dfhack.lua b/library/lua/dfhack.lua
index b37183cb6..a6606d152 100644
--- a/library/lua/dfhack.lua
+++ b/library/lua/dfhack.lua
@@ -80,6 +80,12 @@ function printall(table)
end
end
+function copyall(table)
+ local rv = {}
+ for k,v in pairs(table) do rv[k] = v end
+ return rv
+end
+
function dfhack.persistent:__tostring()
return ""
@@ -89,5 +95,15 @@ function dfhack.matinfo:__tostring()
return ""
end
+function dfhack.maps.getSize()
+ local map = df.global.world.map
+ return map.x_count_block, map.y_count_block, map.z_count_block
+end
+
+function dfhack.maps.getTileSize()
+ local map = df.global.world.map
+ return map.x_count, map.y_count, map.z_count
+end
+
-- Feed the table back to the require() mechanism.
return dfhack
diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp
index 19618fc10..d884a734e 100644
--- a/library/modules/Items.cpp
+++ b/library/modules/Items.cpp
@@ -41,6 +41,7 @@ using namespace std;
#include "modules/Units.h"
#include "ModuleFactory.h"
#include "Core.h"
+#include "Error.h"
#include "MiscUtils.h"
#include "df/world.h"
@@ -63,6 +64,7 @@ using namespace std;
#include "df/trapcomp_flags.h"
#include "df/job_item.h"
#include "df/general_ref.h"
+#include "df/general_ref_unit_itemownerst.h"
using namespace DFHack;
using namespace df::enums;
@@ -415,28 +417,62 @@ bool Items::copyItem(df::item * itembase, DFHack::dfh_item &item)
return true;
}
-int32_t Items::getItemOwnerID(const df::item * item)
+df::unit *Items::getOwner(df::item * item)
{
+ CHECK_NULL_POINTER(item);
+
for (size_t i = 0; i < item->itemrefs.size(); i++)
{
df::general_ref *ref = item->itemrefs[i];
- if (ref->getType() == general_ref_type::UNIT_ITEMOWNER)
- return ref->getID();
+ if (strict_virtual_cast(ref))
+ return ref->getUnit();
}
- return -1;
+
+ return NULL;
}
-df::unit *Items::getItemOwner(const df::item * item)
+bool Items::setOwner(df::item *item, df::unit *unit)
{
- for (size_t i = 0; i < item->itemrefs.size(); i++)
+ CHECK_NULL_POINTER(item);
+
+ for (int i = item->itemrefs.size()-1; i >= 0; i--)
{
df::general_ref *ref = item->itemrefs[i];
- if (ref->getType() == general_ref_type::UNIT_ITEMOWNER)
- return ref->getUnit();
+
+ if (!strict_virtual_cast(ref))
+ continue;
+
+ if (auto cur = ref->getUnit())
+ {
+ if (cur == unit)
+ return true;
+
+ erase_from_vector(cur->owned_items, item->id);
+ }
+
+ delete ref;
+ vector_erase_at(item->itemrefs, i);
}
- return NULL;
+
+ if (unit)
+ {
+ auto ref = df::allocate();
+ if (!ref)
+ return false;
+
+ item->flags.bits.owned = true;
+ ref->unit_id = unit->id;
+
+ insert_into_vector(unit->owned_items, item->id);
+ item->itemrefs.push_back(ref);
+ }
+ else
+ item->flags.bits.owned = false;
+
+ return true;
}
+
int32_t Items::getItemContainerID(const df::item * item)
{
for (size_t i = 0; i < item->itemrefs.size(); i++)
@@ -477,27 +513,3 @@ bool Items::readItemRefs(const df::item * item, df::general_ref_type type, std::
return !values.empty();
}
-
-bool Items::removeItemOwner(df::item * item)
-{
- for (size_t i = 0; i < item->itemrefs.size(); i++)
- {
- df::general_ref *ref = item->itemrefs[i];
- if (ref->getType() != general_ref_type::UNIT_ITEMOWNER)
- continue;
-
- df::unit *unit = ref->getUnit();
-
- if (unit == NULL || !Units::RemoveOwnedItemByPtr(unit, item->id))
- {
- cerr << "RemoveOwnedItemIdx: CREATURE " << ref->getID() << " ID " << item->id << " FAILED!" << endl;
- return false;
- }
- delete ref;
- item->itemrefs.erase(item->itemrefs.begin() + i--);
- }
-
- item->flags.bits.owned = 0;
-
- return true;
-}
diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp
index db66086e0..c0aa9b634 100644
--- a/library/modules/Maps.cpp
+++ b/library/modules/Maps.cpp
@@ -33,11 +33,13 @@ distribution.
using namespace std;
#include "modules/Maps.h"
+#include "modules/MapCache.h"
#include "Error.h"
#include "VersionInfo.h"
#include "MemAccess.h"
#include "ModuleFactory.h"
#include "Core.h"
+#include "MiscUtils.h"
#include "DataDefs.h"
#include "df/world_data.h"
@@ -45,6 +47,10 @@ using namespace std;
#include "df/world_geo_biome.h"
#include "df/world_geo_layer.h"
#include "df/feature_init.h"
+#include "df/world_data.h"
+#include "df/burrow.h"
+#include "df/block_burrow.h"
+#include "df/block_burrow_link.h"
using namespace DFHack;
using namespace df::enums;
@@ -125,7 +131,7 @@ df::map_block *Maps::getBlock (int32_t blockx, int32_t blocky, int32_t blockz)
return world->map.block_index[blockx][blocky][blockz];
}
-df::map_block *Maps::getBlockAbs (int32_t x, int32_t y, int32_t z)
+df::map_block *Maps::getTileBlock (int32_t x, int32_t y, int32_t z)
{
if (!IsValid())
return NULL;
@@ -136,207 +142,40 @@ df::map_block *Maps::getBlockAbs (int32_t x, int32_t y, int32_t z)
return world->map.block_index[x >> 4][y >> 4][z];
}
-bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer)
-{
- df::map_block * block = getBlock(x,y,z);
- if (block)
- {
- buffer->position = DFCoord(x,y,z);
- memcpy(buffer->tiletypes,block->tiletype, sizeof(tiletypes40d));
- memcpy(buffer->designation,block->designation, sizeof(designations40d));
- memcpy(buffer->occupancy,block->occupancy, sizeof(occupancies40d));
- memcpy(buffer->biome_indices,block->region_offset, sizeof(block->region_offset));
- buffer->global_feature = block->global_feature;
- buffer->local_feature = block->local_feature;
- buffer->mystery = block->unk2;
- buffer->origin = block;
- buffer->blockflags.whole = block->flags.whole;
- return true;
- }
- return false;
-}
-
-/*
- * Tiletypes
- */
-
-bool Maps::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer)
-{
- df::map_block *block = getBlock(x,y,z);
- if (block)
- {
- memcpy(buffer, block->tiletype, sizeof(tiletypes40d));
- return true;
- }
- return false;
-}
-
-bool Maps::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer)
-{
- df::map_block *block = getBlock(x,y,z);
- if (block)
- {
- memcpy(block->tiletype, buffer, sizeof(tiletypes40d));
- return true;
- }
- return false;
-}
-
-/*
- * Dirty bit
- */
-bool Maps::ReadDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool &dirtybit)
-{
- df::map_block *block = getBlock(x,y,z);
- if (block)
- {
- dirtybit = block->flags.bits.designated;
- return true;
- }
- return false;
-}
-
-bool Maps::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit)
+df::world_data::T_region_map *Maps::getRegionBiome(df::coord2d rgn_pos)
{
- df::map_block *block = getBlock(x,y,z);
- if (block)
- {
- block->flags.bits.designated = true;
- return true;
- }
- return false;
-}
-/*
- * Block flags
- */
-// FIXME: maybe truncates, still bullshit
-bool Maps::ReadBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags &blockflags)
-{
- df::map_block *block = getBlock(x,y,z);
- if (block)
- {
- blockflags.whole = block->flags.whole;
- return true;
- }
- return false;
-}
-//FIXME: maybe truncated, still bullshit
-bool Maps::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags blockflags)
-{
- df::map_block *block = getBlock(x,y,z);
- if (block)
- {
- block->flags.whole = blockflags.whole;
- return true;
- }
- return false;
-}
-
-/*
- * Designations
- */
-bool Maps::ReadDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer)
-{
- df::map_block *block = getBlock(x,y,z);
- if (block)
- {
- memcpy(buffer, block->designation, sizeof(designations40d));
- return true;
- }
- return false;
-}
+ auto data = world->world_data;
+ if (!data)
+ return NULL;
-bool Maps::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer)
-{
- df::map_block *block = getBlock(x,y,z);
- if (block)
- {
- memcpy(block->designation, buffer, sizeof(designations40d));
- return true;
- }
- return false;
-}
+ if (rgn_pos.x < 0 || rgn_pos.x >= data->world_width ||
+ rgn_pos.y < 0 || rgn_pos.y >= data->world_height)
+ return NULL;
-/*
- * Occupancies
- */
-bool Maps::ReadOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer)
-{
- df::map_block *block = getBlock(x,y,z);
- if (block)
- {
- memcpy(buffer, block->occupancy, sizeof(occupancies40d));
- return true;
- }
- return false;
+ return &data->region_map[rgn_pos.x][rgn_pos.y];
}
-bool Maps::WriteOccupancy (uint32_t x, uint32_t y, uint32_t z, occupancies40d *buffer)
+df::feature_init *Maps::getGlobalInitFeature(int32_t index)
{
- df::map_block *block = getBlock(x,y,z);
- if (block)
- {
- memcpy(block->occupancy, buffer, sizeof(occupancies40d));
- return true;
- }
- return false;
-}
+ auto data = world->world_data;
+ if (!data)
+ return NULL;
-/*
- * Temperatures
- */
-bool Maps::ReadTemperatures(uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2)
-{
- df::map_block *block = getBlock(x,y,z);
- if (block)
- {
- if(temp1)
- memcpy(temp1, block->temperature_1, sizeof(t_temperatures));
- if(temp2)
- memcpy(temp2, block->temperature_2, sizeof(t_temperatures));
- return true;
- }
- return false;
-}
-bool Maps::WriteTemperatures (uint32_t x, uint32_t y, uint32_t z, t_temperatures *temp1, t_temperatures *temp2)
-{
- df::map_block *block = getBlock(x,y,z);
- if (block)
- {
- if(temp1)
- memcpy(block->temperature_1, temp1, sizeof(t_temperatures));
- if(temp2)
- memcpy(block->temperature_2, temp2, sizeof(t_temperatures));
- return true;
- }
- return false;
-}
+ auto rgn = vector_get(data->underground_regions, index);
+ if (!rgn)
+ return NULL;
-/*
- * Region Offsets - used for layer geology
- */
-bool Maps::ReadRegionOffsets (uint32_t x, uint32_t y, uint32_t z, biome_indices40d *buffer)
-{
- df::map_block *block = getBlock(x,y,z);
- if (block)
- {
- memcpy(buffer, block->region_offset,sizeof(biome_indices40d));
- return true;
- }
- return false;
+ return rgn->feature_init;
}
bool Maps::GetGlobalFeature(t_feature &feature, int32_t index)
{
feature.type = (df::feature_type)-1;
- if (!world->world_data)
- return false;
- if ((index < 0) || (index >= world->world_data->underground_regions.size()))
+ auto f = Maps::getGlobalInitFeature(index);
+ if (!f)
return false;
- df::feature_init *f = world->world_data->underground_regions[index]->feature_init;
-
feature.discovered = false;
feature.origin = f;
feature.type = f->getType();
@@ -344,35 +183,38 @@ bool Maps::GetGlobalFeature(t_feature &feature, int32_t index)
return true;
}
-bool Maps::GetLocalFeature(t_feature &feature, df::coord2d coord, int32_t index)
+df::feature_init *Maps::getLocalInitFeature(df::coord2d rgn_pos, int32_t index)
{
- feature.type = (df::feature_type)-1;
- if (!world->world_data)
- return false;
-
- // regionX and regionY are in embark squares!
- // we convert to full region tiles
- // this also works in adventure mode
- // region X coord - whole regions
- uint32_t region_x = ( (coord.x / 3) + world->map.region_x ) / 16;
- // region Y coord - whole regions
- uint32_t region_y = ( (coord.y / 3) + world->map.region_y ) / 16;
+ auto data = world->world_data;
+ if (!data)
+ return NULL;
- uint32_t bigregion_x = region_x / 16;
- uint32_t bigregion_y = region_y / 16;
+ if (rgn_pos.x < 0 || rgn_pos.x >= data->world_width ||
+ rgn_pos.y < 0 || rgn_pos.y >= data->world_height)
+ return NULL;
- uint32_t sub_x = region_x % 16;
- uint32_t sub_y = region_y % 16;
// megaregions = 16x16 squares of regions = 256x256 squares of embark squares
+ df::coord2d bigregion = rgn_pos / 16;
// bigregion is 16x16 regions. for each bigregion in X dimension:
- if (!world->world_data->unk_204[bigregion_x][bigregion_y].features)
- return false;
+ auto fptr = data->unk_204[bigregion.x][bigregion.y].features;
+ if (!fptr)
+ return NULL;
+
+ df::coord2d sub = rgn_pos & 15;
+
+ vector &features = fptr->feature_init[sub.x][sub.y];
+
+ return vector_get(features, index);
+}
+
+static bool GetLocalFeature(t_feature &feature, df::coord2d rgn_pos, int32_t index)
+{
+ feature.type = (df::feature_type)-1;
- vector &features = world->world_data->unk_204[bigregion_x][bigregion_y].features->feature_init[sub_x][sub_y];
- if ((index < 0) || (index >= features.size()))
+ auto f = Maps::getLocalInitFeature(rgn_pos, index);
+ if (!f)
return false;
- df::feature_init *f = features[index];
feature.discovered = false;
feature.origin = f;
@@ -381,58 +223,15 @@ bool Maps::GetLocalFeature(t_feature &feature, df::coord2d coord, int32_t index)
return true;
}
-bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, int32_t & local, int32_t & global)
-{
- df::map_block *block = getBlock(x,y,z);
- if (block)
- {
- local = block->local_feature;
- global = block->global_feature;
- return true;
- }
- return false;
-}
-
-bool Maps::WriteFeatures(uint32_t x, uint32_t y, uint32_t z, const int32_t & local, const int32_t & global)
-{
- df::map_block *block = getBlock(x,y,z);
- if (block)
- {
- block->local_feature = local;
- block->global_feature = global;
- return true;
- }
- return false;
-}
-
bool Maps::ReadFeatures(uint32_t x, uint32_t y, uint32_t z, t_feature *local, t_feature *global)
{
- int32_t loc, glob;
- if (!ReadFeatures(x, y, z, loc, glob))
+ df::map_block *block = getBlock(x,y,z);
+ if (!block)
return false;
-
- bool result = true;
- if (global)
- {
- if (glob != -1)
- result &= GetGlobalFeature(*global, glob);
- else
- global->type = (df::feature_type)-1;
- }
- if (local)
- {
- if (loc != -1)
- {
- df::coord2d coord(x,y);
- result &= GetLocalFeature(*local, coord, loc);
- }
- else
- local->type = (df::feature_type)-1;
- }
- return result;
+ return ReadFeatures(block, local, global);
}
-bool Maps::ReadFeatures(mapblock40d * block, t_feature * local, t_feature * global)
+bool Maps::ReadFeatures(df::map_block * block, t_feature * local, t_feature * global)
{
bool result = true;
if (global)
@@ -445,39 +244,17 @@ bool Maps::ReadFeatures(mapblock40d * block, t_feature * local, t_feature * glob
if (local)
{
if (block->local_feature != -1)
- result &= GetLocalFeature(*local, block->position, block->local_feature);
+ result &= GetLocalFeature(*local, block->region_pos, block->local_feature);
else
local->type = (df::feature_type)-1;
}
return result;
}
-bool Maps::SetBlockLocalFeature(uint32_t x, uint32_t y, uint32_t z, int32_t local)
-{
- df::map_block *block = getBlock(x,y,z);
- if (block)
- {
- block->local_feature = local;
- return true;
- }
- return false;
-}
-
-bool Maps::SetBlockGlobalFeature(uint32_t x, uint32_t y, uint32_t z, int32_t global)
-{
- df::map_block *block = getBlock(x,y,z);
- if (block)
- {
- block->global_feature = global;
- return true;
- }
- return false;
-}
-
/*
* Block events
*/
-bool Maps::SortBlockEvents(uint32_t x, uint32_t y, uint32_t z,
+bool Maps::SortBlockEvents(df::map_block *block,
vector * veins,
vector * ices,
vector *splatter,
@@ -495,7 +272,6 @@ bool Maps::SortBlockEvents(uint32_t x, uint32_t y, uint32_t z,
if (constructions)
constructions->clear();
- df::map_block * block = getBlock(x,y,z);
if (!block)
return false;
@@ -535,27 +311,38 @@ bool Maps::RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, df::block_square
df::map_block * block = getBlock(x,y,z);
if (!block)
return false;
- for (size_t i = 0; i < block->block_events.size(); i++)
+
+ int idx = linear_index(block->block_events, which);
+ if (idx >= 0)
{
- if (block->block_events[i] == which)
- {
- delete which;
- block->block_events.erase(block->block_events.begin() + i);
- return true;
- }
+ delete which;
+ vector_erase_at(block->block_events, idx);
+ return true;
}
- return false;
+ else
+ return false;
}
/*
* Layer geology
*/
-bool Maps::ReadGeology (vector < vector >& assign)
+bool Maps::ReadGeology(vector > *layer_mats, vector *geoidx)
{
if (!world->world_data)
return false;
- vector v_geology[eBiomeCount];
+ layer_mats->resize(eBiomeCount);
+ geoidx->resize(eBiomeCount);
+
+ for (int i = 0; i < eBiomeCount; i++)
+ {
+ (*layer_mats)[i].clear();
+ (*geoidx)[i] = df::coord2d(-30000,-30000);
+ }
+
+ int world_width = world->world_data->world_width;
+ int world_height = world->world_data->world_height;
+
// iterate over 8 surrounding regions + local region
for (int i = eNorthWest; i < eBiomeCount; i++)
{
@@ -564,14 +351,18 @@ bool Maps::ReadGeology (vector < vector >& assign)
// regionX/16 is in 16x16 embark square regions
// i provides -1 .. +1 offset from the current region
int bioRX = world->map.region_x / 16 + ((i % 3) - 1);
- if (bioRX < 0) bioRX = 0;
- if (bioRX >= world->world_data->world_width) bioRX = world->world_data->world_width - 1;
int bioRY = world->map.region_y / 16 + ((i / 3) - 1);
- if (bioRY < 0) bioRY = 0;
- if (bioRY >= world->world_data->world_height) bioRY = world->world_data->world_height - 1;
+
+ df::coord2d rgn_pos(clip_range(bioRX,0,world_width-1),clip_range(bioRX,0,world_height-1));
+
+ (*geoidx)[i] = rgn_pos;
+
+ auto biome = getRegionBiome(rgn_pos);
+ if (!biome)
+ continue;
// get index into geoblock vector
- uint16_t geoindex = world->world_data->region_map[bioRX][bioRY].geo_index;
+ int16_t geoindex = biome->geo_index;
/// geology blocks have a vector of layer descriptors
// get the vector with pointer to layers
@@ -579,29 +370,412 @@ bool Maps::ReadGeology (vector < vector >& assign)
if (!geo_biome)
continue;
- vector &geolayers = geo_biome->layers;
+ auto &geolayers = geo_biome->layers;
+ auto &matvec = (*layer_mats)[i];
/// layer descriptor has a field that determines the type of stone/soil
- v_geology[i].reserve(geolayers.size());
+ matvec.resize(geolayers.size());
// finally, read the layer matgloss
for (size_t j = 0; j < geolayers.size(); j++)
- v_geology[i].push_back(geolayers[j]->mat_index);
+ matvec[j] = geolayers[j]->mat_index;
}
- assign.clear();
- assign.reserve(eBiomeCount);
- for (int i = 0; i < eBiomeCount; i++)
- assign.push_back(v_geology[i]);
return true;
}
-bool Maps::ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector*& plants)
+#define COPY(a,b) memcpy(&a,&b,sizeof(a))
+
+MapExtras::Block::Block(MapCache *parent, DFCoord _bcoord) : parent(parent)
+{
+ dirty_designations = false;
+ dirty_tiletypes = false;
+ dirty_temperatures = false;
+ dirty_blockflags = false;
+ dirty_occupancies = false;
+ valid = false;
+ bcoord = _bcoord;
+ block = Maps::getBlock(bcoord);
+ item_counts = NULL;
+
+ memset(tags,0,sizeof(tags));
+
+ if(block)
+ {
+ COPY(rawtiles, block->tiletype);
+ COPY(designation, block->designation);
+ COPY(occupancy, block->occupancy);
+ blockflags = block->flags;
+
+ COPY(temp1, block->temperature_1);
+ COPY(temp2, block->temperature_2);
+
+ SquashVeins(block,veinmats);
+ SquashConstructions(block, contiles);
+ SquashFrozenLiquids(block, icetiles);
+ if(parent->validgeo)
+ SquashRocks(block,basemats,&parent->layer_mats);
+ else
+ memset(basemats,-1,sizeof(basemats));
+ valid = true;
+ }
+ else
+ {
+ blockflags.whole = 0;
+ memset(rawtiles,0,sizeof(rawtiles));
+ memset(designation,0,sizeof(designation));
+ memset(occupancy,0,sizeof(occupancy));
+ memset(temp1,0,sizeof(temp1));
+ memset(temp2,0,sizeof(temp2));
+ memset(veinmats,-1,sizeof(veinmats));
+ memset(contiles,0,sizeof(contiles));
+ memset(icetiles,0,sizeof(icetiles));
+ memset(basemats,-1,sizeof(basemats));
+ }
+}
+
+MapExtras::Block::~Block()
+{
+ delete[] item_counts;
+}
+
+bool MapExtras::Block::Write ()
+{
+ if(!valid) return false;
+
+ if(dirty_blockflags)
+ {
+ block->flags = blockflags;
+ dirty_blockflags = false;
+ }
+ if(dirty_designations)
+ {
+ COPY(block->designation, designation);
+ block->flags.bits.designated = true;
+ dirty_designations = false;
+ }
+ if(dirty_tiletypes)
+ {
+ COPY(block->tiletype, rawtiles);
+ dirty_tiletypes = false;
+ }
+ if(dirty_temperatures)
+ {
+ COPY(block->temperature_1, temp1);
+ COPY(block->temperature_2, temp2);
+ dirty_temperatures = false;
+ }
+ if(dirty_occupancies)
+ {
+ COPY(block->occupancy, occupancy);
+ dirty_occupancies = false;
+ }
+ return true;
+}
+
+void MapExtras::Block::SquashVeins(df::map_block *mb, t_blockmaterials & materials)
+{
+ memset(materials,-1,sizeof(materials));
+ std::vector veins;
+ Maps::SortBlockEvents(mb,&veins);
+ for (uint32_t x = 0;x<16;x++) for (uint32_t y = 0; y< 16;y++)
+ {
+ df::tiletype tt = mb->tiletype[x][y];
+ if (tileMaterial(tt) == tiletype_material::MINERAL)
+ {
+ for (size_t i = 0; i < veins.size(); i++)
+ {
+ if (veins[i]->getassignment(x,y))
+ materials[x][y] = veins[i]->inorganic_mat;
+ }
+ }
+ }
+}
+
+void MapExtras::Block::SquashFrozenLiquids(df::map_block *mb, tiletypes40d & frozen)
+{
+ std::vector ices;
+ Maps::SortBlockEvents(mb,NULL,&ices);
+ for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
+ {
+ df::tiletype tt = mb->tiletype[x][y];
+ frozen[x][y] = tiletype::Void;
+ if (tileMaterial(tt) == tiletype_material::FROZEN_LIQUID)
+ {
+ for (size_t i = 0; i < ices.size(); i++)
+ {
+ df::tiletype tt2 = ices[i]->tiles[x][y];
+ if (tt2 != tiletype::Void)
+ {
+ frozen[x][y] = tt2;
+ break;
+ }
+ }
+ }
+ }
+}
+
+void MapExtras::Block::SquashConstructions (df::map_block *mb, tiletypes40d & constructions)
+{
+ for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
+ {
+ df::tiletype tt = mb->tiletype[x][y];
+ constructions[x][y] = tiletype::Void;
+ if (tileMaterial(tt) == tiletype_material::CONSTRUCTION)
+ {
+ DFCoord coord = mb->map_pos + df::coord(x,y,0);
+ df::construction *con = df::construction::find(coord);
+ if (con)
+ constructions[x][y] = con->original_tile;
+ }
+ }
+}
+
+void MapExtras::Block::SquashRocks (df::map_block *mb, t_blockmaterials & materials,
+ std::vector< std::vector > * layerassign)
+{
+ // get the layer materials
+ for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
+ {
+ materials[x][y] = -1;
+ uint8_t test = mb->designation[x][y].bits.biome;
+ if (test >= 9)
+ continue;
+ uint8_t idx = mb->region_offset[test];
+ if (idx < layerassign->size())
+ materials[x][y] = layerassign->at(idx)[mb->designation[x][y].bits.geolayer_index];
+ }
+}
+
+df::coord2d MapExtras::Block::biomeRegionAt(df::coord2d p)
+{
+ if (!block)
+ return df::coord2d(-30000,-30000);
+
+ auto des = index_tile(designation,p);
+ uint8_t idx = des.bits.biome;
+ if (idx >= 9)
+ return block->region_pos;
+ idx = block->region_offset[idx];
+ if (idx >= parent->geoidx.size())
+ return block->region_pos;
+ return parent->geoidx[idx];
+}
+
+int16_t MapExtras::Block::GeoIndexAt(df::coord2d p)
+{
+ df::coord2d biome = biomeRegionAt(p);
+ if (!biome.isValid())
+ return -1;
+
+ auto pinfo = Maps::getRegionBiome(biome);
+ if (!pinfo)
+ return -1;
+
+ return pinfo->geo_index;
+}
+
+bool MapExtras::Block::GetGlobalFeature(t_feature *out)
+{
+ out->type = (df::feature_type)-1;
+ if (!valid || block->global_feature < 0)
+ return false;
+ return Maps::GetGlobalFeature(*out, block->global_feature);
+}
+
+bool MapExtras::Block::GetLocalFeature(t_feature *out)
+{
+ out->type = (df::feature_type)-1;
+ if (!valid || block->local_feature < 0)
+ return false;
+ return ::GetLocalFeature(*out, block->region_pos, block->local_feature);
+}
+
+void MapExtras::Block::init_item_counts()
+{
+ if (item_counts) return;
+
+ item_counts = new T_item_counts[16];
+ memset(item_counts, 0, sizeof(T_item_counts));
+
+ if (!block) return;
+
+ for (size_t i = 0; i < block->items.size(); i++)
+ {
+ auto it = df::item::find(block->items[i]);
+ if (!it || !it->flags.bits.on_ground)
+ continue;
+
+ df::coord tidx = it->pos - block->map_pos;
+ if (!is_valid_tile_coord(tidx) || tidx.z != 0)
+ continue;
+
+ item_counts[tidx.x][tidx.y]++;
+ }
+}
+
+bool MapExtras::Block::addItemOnGround(df::item *item)
+{
+ if (!block)
+ return false;
+
+ init_item_counts();
+
+ bool inserted;
+ insert_into_vector(block->items, item->id, &inserted);
+
+ if (inserted)
+ {
+ int &count = index_tile(item_counts,item->pos);
+
+ if (count++ == 0)
+ {
+ index_tile(occupancy,item->pos).bits.item = true;
+ index_tile(block->occupancy,item->pos).bits.item = true;
+ }
+ }
+
+ return inserted;
+}
+
+bool MapExtras::Block::removeItemOnGround(df::item *item)
{
- df::map_block *block = getBlock(x,y,z);
if (!block)
return false;
- plants = &block->plants;
+ init_item_counts();
+
+ int idx = binsearch_index(block->items, item->id);
+ if (idx < 0)
+ return false;
+
+ vector_erase_at(block->items, idx);
+
+ int &count = index_tile(item_counts,item->pos);
+
+ if (--count == 0)
+ {
+ index_tile(occupancy,item->pos).bits.item = false;
+ index_tile(block->occupancy,item->pos).bits.item = false;
+ }
+
return true;
}
+
+MapExtras::Block *MapExtras::MapCache::BlockAt(DFCoord blockcoord)
+{
+ if(!valid)
+ return 0;
+ std::map ::iterator iter = blocks.find(blockcoord);
+ if(iter != blocks.end())
+ {
+ return (*iter).second;
+ }
+ else
+ {
+ if(blockcoord.x >= 0 && blockcoord.x < x_bmax &&
+ blockcoord.y >= 0 && blockcoord.y < y_bmax &&
+ blockcoord.z >= 0 && blockcoord.z < z_max)
+ {
+ Block * nblo = new Block(this, blockcoord);
+ blocks[blockcoord] = nblo;
+ return nblo;
+ }
+ return 0;
+ }
+}
+
+df::burrow *Maps::findBurrowByName(std::string name)
+{
+ auto &vec = df::burrow::get_vector();
+
+ for (size_t i = 0; i < vec.size(); i++)
+ if (vec[i]->name == name)
+ return vec[i];
+
+ return NULL;
+}
+
+void Maps::listBurrowBlocks(std::vector *pvec, df::burrow *burrow)
+{
+ CHECK_NULL_POINTER(burrow);
+
+ pvec->clear();
+ pvec->reserve(burrow->block_x.size());
+
+ df::coord base(world->map.region_x*3,world->map.region_y*3,world->map.region_z);
+
+ for (size_t i = 0; i < burrow->block_x.size(); i++)
+ {
+ df::coord pos(burrow->block_x[i], burrow->block_y[i], burrow->block_z[i]);
+
+ auto block = getBlock(pos - base);
+ if (block)
+ pvec->push_back(block);
+ }
+}
+
+df::block_burrow *Maps::getBlockBurrowMask(df::burrow *burrow, df::map_block *block, bool create)
+{
+ CHECK_NULL_POINTER(burrow);
+ CHECK_NULL_POINTER(block);
+
+ int32_t id = burrow->id;
+ df::block_burrow_link *prev = &block->block_burrows;
+ df::block_burrow_link *link = prev->next;
+
+ for (; link; prev = link, link = link->next)
+ if (link->item->id == id)
+ return link->item;
+
+ if (create)
+ {
+ link = new df::block_burrow_link;
+ link->item = new df::block_burrow;
+
+ link->item->id = burrow->id;
+ memset(link->item->tile_bitmask,0,sizeof(link->item->tile_bitmask));
+ link->item->link = link;
+
+ link->next = NULL;
+ link->prev = prev;
+ prev->next = link;
+
+ df::coord base(world->map.region_x*3,world->map.region_y*3,world->map.region_z);
+ df::coord pos = base + block->map_pos/16;
+
+ burrow->block_x.push_back(pos.x);
+ burrow->block_y.push_back(pos.y);
+ burrow->block_z.push_back(pos.z);
+
+ return link->item;
+ }
+
+ return NULL;
+}
+
+bool Maps::isBlockBurrowTile(df::burrow *burrow, df::map_block *block, df::coord2d tile)
+{
+ CHECK_NULL_POINTER(burrow);
+
+ if (!block) return false;
+
+ auto mask = getBlockBurrowMask(burrow, block);
+
+ return mask ? mask->getassignment(tile & 15) : false;
+}
+
+bool Maps::setBlockBurrowTile(df::burrow *burrow, df::map_block *block, df::coord2d tile, bool enable)
+{
+ CHECK_NULL_POINTER(burrow);
+
+ if (!block) return false;
+
+ auto mask = getBlockBurrowMask(burrow, block, enable);
+
+ if (mask)
+ mask->setassignment(tile & 15, enable);
+
+ return true;
+}
+
diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp
index e210a9028..3e58e0d5c 100644
--- a/library/modules/Units.cpp
+++ b/library/modules/Units.cpp
@@ -44,6 +44,7 @@ using namespace std;
#include "modules/Translation.h"
#include "ModuleFactory.h"
#include "Core.h"
+#include "MiscUtils.h"
#include "df/world.h"
#include "df/ui.h"
@@ -54,6 +55,7 @@ using namespace std;
#include "df/historical_figure.h"
#include "df/historical_figure_info.h"
#include "df/assumed_identity.h"
+#include "df/burrow.h"
using namespace DFHack;
using namespace df::enums;
@@ -493,37 +495,6 @@ bool Units::ReadInventoryByPtr(const df::unit * unit, std::vector &
return true;
}
-bool Units::ReadOwnedItemsByIdx(const uint32_t index, std::vector & item)
-{
- if(index >= world->units.all.size()) return false;
- df::unit * temp = world->units.all[index];
- return ReadOwnedItemsByPtr(temp, item);
-}
-
-bool Units::ReadOwnedItemsByPtr(const df::unit * unit, std::vector & items)
-{
- if(!isValid()) return false;
- if(!unit) return false;
- items = unit->owned_items;
- return true;
-}
-
-bool Units::RemoveOwnedItemByIdx(const uint32_t index, int32_t id)
-{
- if(index >= world->units.all.size()) return false;
- df::unit * temp = world->units.all[index];
- return RemoveOwnedItemByPtr(temp, id);
-}
-
-bool Units::RemoveOwnedItemByPtr(df::unit * unit, int32_t id)
-{
- if(!isValid()) return false;
- if(!unit) return false;
- vector & vec = unit->owned_items;
- vec.erase(std::remove(vec.begin(), vec.end(), id), vec.end());
- return true;
-}
-
void Units::CopyNameTo(df::unit * creature, df::language_name * target)
{
Translation::copyName(&creature->name, target);
@@ -652,3 +623,40 @@ bool DFHack::Units::isSane(df::unit *unit)
return true;
}
+
+bool DFHack::Units::isInBurrow(df::unit *unit, df::burrow *burrow)
+{
+ CHECK_NULL_POINTER(unit);
+ CHECK_NULL_POINTER(burrow);
+
+ return binsearch_index(unit->burrows, burrow->id) >= 0;
+}
+
+void DFHack::Units::setInBurrow(df::unit *unit, df::burrow *burrow, bool enable)
+{
+ using df::global::ui;
+
+ CHECK_NULL_POINTER(unit);
+ CHECK_NULL_POINTER(burrow);
+
+ if (enable)
+ {
+ insert_into_vector(unit->burrows, burrow->id);
+ insert_into_vector(burrow->units, unit->id);
+ }
+ else
+ {
+ erase_from_vector(unit->burrows, burrow->id);
+ erase_from_vector(burrow->units, unit->id);
+ }
+
+ // Sync ui if active
+ if (ui && ui->main.mode == ui_sidebar_mode::Burrows &&
+ ui->burrows.in_add_units_mode && ui->burrows.sel_id == burrow->id)
+ {
+ int idx = linear_index(ui->burrows.list_units, unit);
+ if (idx >= 0)
+ ui->burrows.sel_units[idx] = enable;
+ }
+}
+
diff --git a/library/xml b/library/xml
index baeee2ce1..27fec9797 160000
--- a/library/xml
+++ b/library/xml
@@ -1 +1 @@
-Subproject commit baeee2ce115e0b3432e5b66b843e8883e5f03b34
+Subproject commit 27fec9797d7d1215bd3f5530b44a55a9d394fe75
diff --git a/plugins/advtools.cpp b/plugins/advtools.cpp
index ffb428fd8..69841849a 100644
--- a/plugins/advtools.cpp
+++ b/plugins/advtools.cpp
@@ -780,7 +780,7 @@ command_result adv_tools (color_ostream &out, std::vector & parame
if (!num)
continue;
- df::map_block *block = Maps::getBlockAbs(item->pos);
+ df::map_block *block = Maps::getTileBlock(item->pos);
if (!block)
continue;
diff --git a/plugins/autodump.cpp b/plugins/autodump.cpp
index 9d42694a3..a71555b7a 100644
--- a/plugins/autodump.cpp
+++ b/plugins/autodump.cpp
@@ -147,26 +147,13 @@ static command_result autodump_main(color_ostream &out, vector & parame
}
}
}
- coordmap counts;
+
// proceed with the dumpification operation
for(size_t i=0; i< numItems; i++)
{
df::item * itm = world->items.all[i];
DFCoord pos_item(itm->pos.x, itm->pos.y, itm->pos.z);
- // keep track how many items are at places. all items.
- coordmap::iterator it = counts.find(pos_item);
- if(it == counts.end())
- {
- pair< coordmap::iterator, bool > inserted = counts.insert(make_pair(pos_item,1));
- it = inserted.first;
- }
- else
- {
- it->second ++;
- }
- // iterator is valid here, we use it later to decrement the pile counter if the item is moved
-
// only dump the stuff marked for dumping and laying on the ground
if ( !itm->flags.bits.dump
|| !itm->flags.bits.on_ground
@@ -194,38 +181,16 @@ static command_result autodump_main(color_ostream &out, vector & parame
itm->flags.bits.forbid = true;
// Don't move items if they're already at the cursor
- if (pos_cursor == pos_item)
- continue;
-
- // Do we need to fix block-local item ID vector?
- if(pos_item/16 != pos_cursor/16)
+ if (pos_cursor != pos_item)
{
- // yes...
- cerr << "Moving from block to block!" << endl;
- df::map_block * bl_src = Maps::getBlockAbs(itm->pos.x, itm->pos.y, itm->pos.z);
- df::map_block * bl_tgt = Maps::getBlockAbs(cx, cy, cz);
- if(bl_src)
- {
- remove(bl_src->items.begin(), bl_src->items.end(),itm->id);
- }
- else
- {
- cerr << "No source block" << endl;
- }
- if(bl_tgt)
- {
- bl_tgt->items.push_back(itm->id);
- }
- else
- {
- cerr << "No target block" << endl;
- }
- }
+ if (!MC.removeItemOnGround(itm))
+ out.printerr("Item %d wasn't in the source block.\n", itm->id);
- // Move the item
- itm->pos.x = pos_cursor.x;
- itm->pos.y = pos_cursor.y;
- itm->pos.z = pos_cursor.z;
+ itm->pos = pos_cursor;
+
+ if (!MC.addItemOnGround(itm))
+ out.printerr("Could not add item %d to destination block.\n", itm->id);
+ }
}
else // destroy
{
@@ -238,42 +203,14 @@ static command_result autodump_main(color_ostream &out, vector & parame
itm->flags.bits.forbid = true;
itm->flags.bits.hidden = true;
}
- // keeping track of item pile sizes ;)
- it->second --;
+
dumped_total++;
}
- if(!destroy) // TODO: do we have to do any of this when destroying items?
- {
- // for each item pile, see if it reached zero. if so, unset item flag on the tile it's on
- coordmap::iterator it = counts.begin();
- coordmap::iterator end = counts.end();
- while(it != end)
- {
- if(it->second == 0)
- {
- df::tile_occupancy occ = MC.occupancyAt(it->first);
- occ.bits.item = false;
- MC.setOccupancyAt(it->first, occ);
- }
- it++;
- }
- // Set "item here" flag on target tile, if we moved any items to the target tile.
- if (dumped_total > 0)
- {
- // assume there is a possibility the cursor points at some weird location with missing block data
- Block * b = MC.BlockAt(pos_cursor / 16);
- if(b)
- {
- df::tile_occupancy occ = MC.occupancyAt(pos_cursor);
- occ.bits.item = 1;
- MC.setOccupancyAt(pos_cursor,occ);
- }
- }
- // write map changes back to DF.
+
+ // write map changes back to DF.
+ if(!destroy)
MC.WriteAll();
- // Is this necessary? Is "forbid" a dirtyable attribute like "dig" is?
- Maps::WriteDirtyBit(cx/16, cy/16, cz, true);
- }
+
out.print("Done. %d items %s.\n", dumped_total, destroy ? "marked for destruction" : "quickdumped");
return CR_OK;
}
diff --git a/plugins/changelayer.cpp b/plugins/changelayer.cpp
index d56360d83..317a0fa36 100644
--- a/plugins/changelayer.cpp
+++ b/plugins/changelayer.cpp
@@ -189,13 +189,13 @@ command_result changelayer (color_ostream &out, std::vector & para
uint32_t tileY = cursorY % 16;
MapExtras::Block * b = mc.BlockAt(cursor/16);
- if(!b && !b->valid)
+ if(!b || !b->is_valid())
{
out.printerr("No data.\n");
return CR_OK;
}
- mapblock40d & block = b->raw;
- df::tile_designation &des = block.designation[tileX][tileY];
+
+ df::tile_designation des = b->DesignationAt(cursor%16);
// get biome and geolayer at cursor position
uint32_t biome = des.bits.biome;
diff --git a/plugins/changevein.cpp b/plugins/changevein.cpp
index 133d7ef4a..1d08cfeaf 100644
--- a/plugins/changevein.cpp
+++ b/plugins/changevein.cpp
@@ -50,7 +50,7 @@ command_result df_changevein (color_ostream &out, vector & parameters)
return CR_FAILURE;
}
- df::map_block *block = Maps::getBlockAbs(cursor->x, cursor->y, cursor->z);
+ df::map_block *block = Maps::getTileBlock(cursor->x, cursor->y, cursor->z);
if (!block)
{
out.printerr("Invalid tile selected.\n");
diff --git a/plugins/cleaners.cpp b/plugins/cleaners.cpp
index ea5edc991..30befab2f 100644
--- a/plugins/cleaners.cpp
+++ b/plugins/cleaners.cpp
@@ -127,7 +127,7 @@ command_result spotclean (color_ostream &out, vector & parameters)
out.printerr("Map is not available.\n");
return CR_FAILURE;
}
- df::map_block *block = Maps::getBlockAbs(cursor->x, cursor->y, cursor->z);
+ df::map_block *block = Maps::getTileBlock(cursor->x, cursor->y, cursor->z);
if (block == NULL)
{
out.printerr("Invalid map block selected!\n");
diff --git a/plugins/cleanowned.cpp b/plugins/cleanowned.cpp
index 280f2e1c5..c1521b8de 100644
--- a/plugins/cleanowned.cpp
+++ b/plugins/cleanowned.cpp
@@ -98,8 +98,7 @@ command_result df_cleanowned (color_ostream &out, vector & parameters)
if (!item->flags.bits.owned)
{
- int32_t owner = Items::getItemOwnerID(item);
- if (owner >= 0)
+ if (Items::getOwner(item))
{
out.print("Fixing a misflagged item: \t");
confiscate = true;
@@ -168,14 +167,14 @@ command_result df_cleanowned (color_ostream &out, vector & parameters)
item->getWear()
);
- df::unit *owner = Items::getItemOwner(item);
+ df::unit *owner = Items::getOwner(item);
if (owner)
out.print(", owner %s", Translation::TranslateName(&owner->name,false).c_str());
if (!dry_run)
{
- if (!Items::removeItemOwner(item))
+ if (!Items::setOwner(item,NULL))
out.print("(unsuccessfully) ");
if (dump)
item->flags.bits.dump = 1;
diff --git a/plugins/deramp.cpp b/plugins/deramp.cpp
index c872f33dd..e5d0331d9 100644
--- a/plugins/deramp.cpp
+++ b/plugins/deramp.cpp
@@ -38,7 +38,7 @@ command_result df_deramp (color_ostream &out, vector & parameters)
for (int i = 0; i < blocks_total; i++)
{
df::map_block *block = world->map.map_blocks[i];
- df::map_block *above = Maps::getBlockAbs(block->map_pos.x, block->map_pos.y, block->map_pos.z + 1);
+ df::map_block *above = Maps::getTileBlock(block->map_pos + df::coord(0,0,1));
for (int x = 0; x < 16; x++)
{
diff --git a/plugins/dig.cpp b/plugins/dig.cpp
index 91d963fc3..64161a3aa 100644
--- a/plugins/dig.cpp
+++ b/plugins/dig.cpp
@@ -90,7 +90,7 @@ bool dig (MapExtras::MapCache & MCache,
{
DFCoord at (x,y,z);
auto b = MCache.BlockAt(at/16);
- if(!b || !b->valid)
+ if(!b || !b->is_valid())
return false;
if(x == 0 || x == x_max * 16 - 1)
{
@@ -1027,6 +1027,8 @@ command_result digv (color_ostream &out, vector & parameters)
{
DFHack::DFCoord current = flood.top();
flood.pop();
+ if (MCache->tagAt(current))
+ continue;
int16_t vmat2 = MCache->veinMaterialAt(current);
tt = MCache->tiletypeAt(current);
if(!DFHack::isWallTerrain(tt))
@@ -1061,7 +1063,8 @@ command_result digv (color_ostream &out, vector & parameters)
}
if(MCache->testCoord(current))
{
- MCache->clearVeinMaterialAt(current);
+ MCache->setTagAt(current, 1);
+
if(current.x < tx_max - 2)
{
flood.push(DFHack::DFCoord(current.x + 1, current.y, current.z));
@@ -1209,6 +1212,8 @@ command_result digl (color_ostream &out, vector & parameters)
{
DFHack::DFCoord current = flood.top();
flood.pop();
+ if (MCache->tagAt(current))
+ continue;
int16_t vmat2 = MCache->veinMaterialAt(current);
int16_t bmat2 = MCache->baseMaterialAt(current);
tt = MCache->tiletypeAt(current);
@@ -1239,7 +1244,7 @@ command_result digl (color_ostream &out, vector & parameters)
if(MCache->testCoord(current))
{
- MCache->clearBaseMaterialAt(current);
+ MCache->setTagAt(current, 1);
if(current.x < tx_max - 2)
{
flood.push(DFHack::DFCoord(current.x + 1, current.y, current.z));
diff --git a/plugins/fixveins.cpp b/plugins/fixveins.cpp
index 474201a81..f02f61673 100644
--- a/plugins/fixveins.cpp
+++ b/plugins/fixveins.cpp
@@ -65,8 +65,7 @@ command_result df_fixveins (color_ostream &out, vector & parameters)
has_mineral[k] |= mineral->tile_bitmask[k];
}
t_feature local, global;
- Maps::GetGlobalFeature(global, block->global_feature);
- Maps::GetLocalFeature(local, df::coord2d(block->map_pos.x / 16, block->map_pos.y / 16), block->local_feature);
+ Maps::ReadFeatures(block, &local, &global);
for (int x = 0; x < 16; x++)
{
for (int y = 0; y < 16; y++)
diff --git a/plugins/liquids.cpp b/plugins/liquids.cpp
index a7483a886..6be432a5b 100644
--- a/plugins/liquids.cpp
+++ b/plugins/liquids.cpp
@@ -413,8 +413,8 @@ command_result df_liquids_execute(color_ostream &out)
Block * b = mcache.BlockAt((*iter)/16);
DFHack::t_blockflags bf = b->BlockFlags();
- bf.bits.liquid_1 = true;
- bf.bits.liquid_2 = true;
+ bf.bits.update_liquid = true;
+ bf.bits.update_liquid_twice = true;
b->setBlockFlags(bf);
iter++;
@@ -500,20 +500,20 @@ command_result df_liquids_execute(color_ostream &out)
DFHack::t_blockflags bflags = (*biter)->BlockFlags();
if(flowmode == "f+")
{
- bflags.bits.liquid_1 = true;
- bflags.bits.liquid_2 = true;
+ bflags.bits.update_liquid = true;
+ bflags.bits.update_liquid_twice = true;
(*biter)->setBlockFlags(bflags);
}
else if(flowmode == "f-")
{
- bflags.bits.liquid_1 = false;
- bflags.bits.liquid_2 = false;
+ bflags.bits.update_liquid = false;
+ bflags.bits.update_liquid_twice = false;
(*biter)->setBlockFlags(bflags);
}
else
{
- out << "flow bit 1 = " << bflags.bits.liquid_1 << endl;
- out << "flow bit 2 = " << bflags.bits.liquid_2 << endl;
+ out << "flow bit 1 = " << bflags.bits.update_liquid << endl;
+ out << "flow bit 2 = " << bflags.bits.update_liquid_twice << endl;
}
biter ++;
}
diff --git a/plugins/mapexport/mapexport.cpp b/plugins/mapexport/mapexport.cpp
index d7d9daea9..e0a7e5e69 100644
--- a/plugins/mapexport/mapexport.cpp
+++ b/plugins/mapexport/mapexport.cpp
@@ -151,7 +151,7 @@ command_result mapexport (color_ostream &out, std::vector & parame
// Get the map block
df::coord2d blockCoord(b_x, b_y);
MapExtras::Block *b = map.BlockAt(DFHack::DFCoord(b_x, b_y, z));
- if (!b || !b->valid)
+ if (!b || !b->is_valid())
{
continue;
}
@@ -161,15 +161,9 @@ command_result mapexport (color_ostream &out, std::vector & parame
protoblock.set_y(b_y);
protoblock.set_z(z);
- { // Find features
- uint32_t index = b->raw.global_feature;
- if (index != -1)
- Maps::GetGlobalFeature(blockFeatureGlobal, index);
-
- index = b->raw.local_feature;
- if (index != -1)
- Maps::GetLocalFeature(blockFeatureLocal, blockCoord, index);
- }
+ // Find features
+ b->GetGlobalFeature(&blockFeatureGlobal);
+ b->GetLocalFeature(&blockFeatureLocal);
int global_z = df::global::world->map.region_z + z;
@@ -247,9 +241,9 @@ command_result mapexport (color_ostream &out, std::vector & parame
}
}
- PlantList *plants;
- if (Maps::ReadVegetation(b_x, b_y, z, plants))
+ if (b->getRaw())
{
+ PlantList *plants = &b->getRaw()->plants;
for (PlantList::const_iterator it = plants->begin(); it != plants->end(); it++)
{
const df::plant & plant = *(*it);
diff --git a/plugins/plants.cpp b/plugins/plants.cpp
index 09220c653..5ab09868f 100644
--- a/plugins/plants.cpp
+++ b/plugins/plants.cpp
@@ -125,8 +125,9 @@ static command_result immolations (color_ostream &out, do_what what, bool shrubs
int32_t x,y,z;
if(Gui::getCursorCoords(x,y,z))
{
- vector * alltrees;
- if(Maps::ReadVegetation(x/16,y/16,z,alltrees))
+ auto block = Maps::getTileBlock(x,y,z);
+ vector *alltrees = block ? &block->plants : NULL;
+ if(alltrees)
{
bool didit = false;
for(size_t i = 0 ; i < alltrees->size(); i++)
@@ -206,8 +207,9 @@ command_result df_grow (color_ostream &out, vector & parameters)
int32_t x,y,z;
if(Gui::getCursorCoords(x,y,z))
{
- vector * alltrees;
- if(Maps::ReadVegetation(x/16,y/16,z,alltrees))
+ auto block = Maps::getTileBlock(x,y,z);
+ vector *alltrees = block ? &block->plants : NULL;
+ if(alltrees)
{
for(size_t i = 0 ; i < alltrees->size(); i++)
{
diff --git a/plugins/probe.cpp b/plugins/probe.cpp
index d5f03b81f..37df180da 100644
--- a/plugins/probe.cpp
+++ b/plugins/probe.cpp
@@ -147,13 +147,14 @@ command_result df_probe (color_ostream &out, vector & parameters)
uint32_t tileY = cursorY % 16;
MapExtras::Block * b = mc.BlockAt(cursor/16);
- if(!b && !b->valid)
+ if(!b || !b->is_valid())
{
out.printerr("No data.\n");
return CR_OK;
}
- mapblock40d & block = b->raw;
- out.print("block addr: 0x%x\n\n", block.origin);
+
+ auto &block = *b->getRaw();
+ out.print("block addr: 0x%x\n\n", &block);
/*
if (showBlock)
{
@@ -270,7 +271,7 @@ command_result df_probe (color_ostream &out, vector & parameters)
t_feature local;
t_feature global;
- Maps::ReadFeatures(&(b->raw),&local,&global);
+ Maps::ReadFeatures(&block,&local,&global);
PRINT_FLAG( des, feature_local );
if(local.type != -1)
{
@@ -293,7 +294,6 @@ command_result df_probe (color_ostream &out, vector & parameters)
<< endl;
out << "global feature idx: " << block.global_feature
<< endl;
- out << "mystery: " << block.mystery << endl;
out << std::endl;
return CR_OK;
}
diff --git a/plugins/prospector.cpp b/plugins/prospector.cpp
index 5afbd2d0a..c90a66c5a 100644
--- a/plugins/prospector.cpp
+++ b/plugins/prospector.cpp
@@ -426,20 +426,14 @@ command_result prospector (color_ostream &con, vector & parameters)
// Get the map block
df::coord2d blockCoord(b_x, b_y);
MapExtras::Block *b = map.BlockAt(DFHack::DFCoord(b_x, b_y, z));
- if (!b || !b->valid)
+ if (!b || !b->is_valid())
{
continue;
}
- { // Find features
- uint32_t index = b->raw.global_feature;
- if (index != -1)
- Maps::GetGlobalFeature(blockFeatureGlobal, index);
-
- index = b->raw.local_feature;
- if (index != -1)
- Maps::GetLocalFeature(blockFeatureLocal, blockCoord, index);
- }
+ // Find features
+ b->GetGlobalFeature(&blockFeatureGlobal);
+ b->GetLocalFeature(&blockFeatureLocal);
int global_z = world->map.region_z + z;
@@ -550,8 +544,9 @@ command_result prospector (color_ostream &con, vector & parameters)
// and we can check visibility more easily here
if (showPlants)
{
- PlantList * plants;
- if (Maps::ReadVegetation(b_x, b_y, z, plants))
+ auto block = Maps::getBlock(b_x,b_y,z);
+ vector *plants = block ? &block->plants : NULL;
+ if(plants)
{
for (PlantList::const_iterator it = plants->begin(); it != plants->end(); it++)
{
diff --git a/plugins/reveal.cpp b/plugins/reveal.cpp
index 39a2ed9cd..513eededb 100644
--- a/plugins/reveal.cpp
+++ b/plugins/reveal.cpp
@@ -290,7 +290,7 @@ command_result unreveal(color_ostream &out, vector & params)
for(size_t i = 0; i < hidesaved.size();i++)
{
hideblock & hb = hidesaved[i];
- df::map_block * b = Maps::getBlockAbs(hb.c.x,hb.c.y,hb.c.z);
+ df::map_block * b = Maps::getTileBlock(hb.c.x,hb.c.y,hb.c.z);
for (uint32_t x = 0; x < 16;x++) for (uint32_t y = 0; y < 16;y++)
{
b->designation[x][y].bits.hidden = hb.hiddens[x][y];
diff --git a/plugins/tubefill.cpp b/plugins/tubefill.cpp
index 0dd045343..0d20136de 100644
--- a/plugins/tubefill.cpp
+++ b/plugins/tubefill.cpp
@@ -59,12 +59,9 @@ command_result tubefill(color_ostream &out, std::vector & params)
for (size_t i = 0; i < world->map.map_blocks.size(); i++)
{
df::map_block *block = world->map.map_blocks[i];
- df::map_block *above = Maps::getBlockAbs(block->map_pos.x, block->map_pos.y, block->map_pos.z + 1);
- if (block->local_feature == -1)
- continue;
+ df::map_block *above = Maps::getTileBlock(block->map_pos + df::coord(0,0,1));
DFHack::t_feature feature;
- DFCoord coord(block->map_pos.x >> 4, block->map_pos.y >> 4, block->map_pos.z);
- if (!Maps::GetLocalFeature(feature, coord, block->local_feature))
+ if (!Maps::ReadFeatures(block, &feature, NULL))
continue;
if (feature.type != feature_type::deep_special_tube)
continue;