Experimental creation of map blocks in gui/liquids script.

develop
Alexander Gavrilov 2012-09-06 22:45:19 +04:00
parent d0e630d4c3
commit c971a819de
8 changed files with 125 additions and 3 deletions

@ -995,6 +995,10 @@ Maps module
Returns a map block object for given df::coord or x,y,z in local tile coordinates.
* ``dfhack.maps.ensureTileBlock(coords)``, or ``ensureTileBlock(x,y,z)``
Like ``getTileBlock``, but if the block is not allocated, try creating it.
* ``dfhack.maps.getRegionBiome(region_coord2d)``, or ``getRegionBiome(x,y)``
Returns the biome info struct for the given global map region.

@ -1207,6 +1207,9 @@ Returns <em>false</em> in case of error.</p>
<li><p class="first"><tt class="docutils literal">dfhack.maps.getTileBlock(coords)</tt>, or <tt class="docutils literal">getTileBlock(x,y,z)</tt></p>
<p>Returns a map block object for given df::coord or x,y,z in local tile coordinates.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.maps.ensureTileBlock(coords)</tt>, or <tt class="docutils literal">ensureTileBlock(x,y,z)</tt></p>
<p>Like <tt class="docutils literal">getTileBlock</tt>, but if the block is not allocated, try creating it.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.maps.getRegionBiome(region_coord2d)</tt>, or <tt class="docutils literal">getRegionBiome(x,y)</tt></p>
<p>Returns the biome info struct for the given global map region.</p>
</li>

@ -935,6 +935,13 @@ static int maps_getTileBlock(lua_State *L)
return 1;
}
static int maps_ensureTileBlock(lua_State *L)
{
auto pos = CheckCoordXYZ(L, 1, true);
Lua::PushDFObject(L, Maps::ensureTileBlock(pos));
return 1;
}
static int maps_getRegionBiome(lua_State *L)
{
auto pos = CheckCoordXY(L, 1, true);
@ -951,6 +958,7 @@ static int maps_getTileBiomeRgn(lua_State *L)
static const luaL_Reg dfhack_maps_funcs[] = {
{ "isValidTilePos", maps_isValidTilePos },
{ "getTileBlock", maps_getTileBlock },
{ "ensureTileBlock", maps_ensureTileBlock },
{ "getRegionBiome", maps_getRegionBiome },
{ "getTileBiomeRgn", maps_getTileBiomeRgn },
{ NULL, NULL }

@ -253,6 +253,8 @@ public:
bool is_valid() { return valid; }
df::map_block *getRaw() { return block; }
bool Allocate();
MapCache *getParent() { return parent; }
private:
@ -262,6 +264,8 @@ private:
MapCache *parent;
df::map_block *block;
void init();
int biomeIndexAt(df::coord2d p);
bool valid;
@ -347,6 +351,12 @@ class DFHACK_EXPORT MapCache
return BlockAt(df::coord(coord.x>>4,coord.y>>4,coord.z));
}
bool ensureBlockAt(df::coord coord)
{
Block *b = BlockAtTile(coord);
return b ? b->Allocate() : false;
}
df::tiletype baseTiletypeAt (DFCoord tilecoord)
{
Block *b = BlockAtTile(tilecoord);

@ -241,9 +241,11 @@ inline bool isValidTilePos(df::coord pos) { return isValidTilePos(pos.x, pos.y,
*/
extern DFHACK_EXPORT df::map_block * getBlock (int32_t blockx, int32_t blocky, int32_t blockz);
extern DFHACK_EXPORT df::map_block * getTileBlock (int32_t x, int32_t y, int32_t z);
extern DFHACK_EXPORT df::map_block * ensureTileBlock (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 * getTileBlock (df::coord pos) { return getTileBlock(pos.x, pos.y, pos.z); }
inline df::map_block * ensureTileBlock (df::coord pos) { return ensureTileBlock(pos.x, pos.y, pos.z); }
extern DFHACK_EXPORT df::tiletype *getTileType(int32_t x, int32_t y, int32_t z);
extern DFHACK_EXPORT df::tile_designation *getTileDesignation(int32_t x, int32_t y, int32_t z);

@ -157,6 +157,39 @@ df::map_block *Maps::getTileBlock (int32_t x, int32_t y, int32_t z)
return world->map.block_index[x >> 4][y >> 4][z];
}
df::map_block *Maps::ensureTileBlock (int32_t x, int32_t y, int32_t z)
{
if (!isValidTilePos(x,y,z))
return NULL;
auto column = world->map.block_index[x >> 4][y >> 4];
auto &slot = column[z];
if (slot)
return slot;
// Find another block below
int z2 = z;
while (z2 >= 0 && !column[z2]) z2--;
if (z2 < 0)
return NULL;
slot = new df::map_block();
slot->region_pos = column[z2]->region_pos;
slot->map_pos = column[z2]->map_pos;
slot->map_pos.z = z;
// Assume sky
df::tile_designation dsgn(0);
dsgn.bits.light = true;
dsgn.bits.outside = true;
for (int tx = 0; tx < 16; tx++)
for (int ty = 0; ty < 16; ty++)
slot->designation[tx][ty] = dsgn;
return slot;
}
df::tiletype *Maps::getTileType(int32_t x, int32_t y, int32_t z)
{
df::map_block *block = getTileBlock(x,y,z);
@ -513,8 +546,14 @@ MapExtras::Block::Block(MapCache *parent, DFCoord _bcoord) : parent(parent)
valid = false;
bcoord = _bcoord;
block = Maps::getBlock(bcoord);
item_counts = NULL;
tags = NULL;
init();
}
void MapExtras::Block::init()
{
item_counts = NULL;
tiles = NULL;
basemats = NULL;
@ -537,6 +576,23 @@ MapExtras::Block::Block(MapCache *parent, DFCoord _bcoord) : parent(parent)
}
}
bool MapExtras::Block::Allocate()
{
if (block)
return true;
block = Maps::ensureTileBlock(bcoord.x*16, bcoord.y*16, bcoord.z);
if (!block)
return false;
delete item_counts;
delete tiles;
delete basemats;
init();
return true;
}
MapExtras::Block::~Block()
{
delete[] item_counts;

@ -1 +1 @@
Subproject commit df8178a989373ec7868d9195d82ae5f85145ef81
Subproject commit a914f3b7558335d53c0ac93f6e7267906a33cd29

@ -3,6 +3,7 @@
local utils = require 'utils'
local gui = require 'gui'
local guidm = require 'gui.dwarfmode'
local dlg = require 'gui.dialogs'
local liquids = require('plugins.liquids')
@ -199,6 +200,42 @@ function LiquidsUI:onRenderBody(dc)
dc:string("Enter", COLOR_LIGHTGREEN):string(": Paint")
end
function ensure_blocks(cursor, size, cb)
local cx,cy,cz = pos2xyz(cursor)
local all = true
for x=1,size.x or 1,16 do
for y=1,size.y or 1,16 do
for z=1,size.z do
if not dfhack.maps.getTileBlock(cx+x-1, cy+y-1, cz+z-1) then
all = false
end
end
end
end
if all then
cb()
return
end
dlg.showYesNoPrompt(
'Instantiate Blocks',
'Not all map blocks are allocated - instantiate?\n\nWarning: new untested feature.',
COLOR_YELLOW,
function()
for x=1,size.x or 1,16 do
for y=1,size.y or 1,16 do
for z=1,size.z do
dfhack.maps.ensureTileBlock(cx+x-1, cy+y-1, cz+z-1)
end
end
end
cb()
end,
function()
cb()
end
)
end
function LiquidsUI:onInput(keys)
local paint = self.paint:get()
local liquid = paint.liquid
@ -239,13 +276,15 @@ function LiquidsUI:onInput(keys)
else
guidm.clearSelection()
end
liquids.paint(
local cb = curry(
liquids.paint,
cursor,
self.brush:get().tag, self.paint:get().tag,
self.amount, size,
self.set:get().tag, self.flow:get().tag,
self.permaflow:get().tag
)
ensure_blocks(cursor, size, cb)
elseif self:propagateMoveKeys(keys) then
return
elseif keys.D_LOOK_ARENA_WATER then