Improve lua api for tile biome access.

develop
Alexander Gavrilov 2012-05-13 13:58:41 +04:00
parent c6b52067bd
commit 87ec1de891
7 changed files with 120 additions and 18 deletions

@ -807,7 +807,7 @@ Maps module
Returns a map block object for given df::coord or x,y,z in local tile coordinates.
* ``dfhack.maps.getRegionBiome(region_coord2d)``
* ``dfhack.maps.getRegionBiome(region_coord2d)``, or ``getRegionBiome(x,y)``
Returns the biome info struct for the given global map region.
@ -823,6 +823,10 @@ Maps module
Returns the local feature object with the given region coords and index.
* ``dfhack.maps.getTileBiomeRgn(coords)``, or ``getTileBiomeRgn(x,y,z)``
Returns *x, y* for use with ``getRegionBiome``.
* ``dfhack.maps.canWalkBetween(pos1, pos2)``
Checks if a dwarf may be able to walk between the two tiles,

@ -1026,7 +1026,7 @@ 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.getRegionBiome(region_coord2d)</tt></p>
<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>
<li><p class="first"><tt class="docutils literal"><span class="pre">dfhack.maps.enableBlockUpdates(block[,flow,temperature])</span></tt></p>
@ -1038,6 +1038,9 @@ Returns <em>false</em> in case of error.</p>
<li><p class="first"><tt class="docutils literal">dfhack.maps.getLocalInitFeature(region_coord2d,index)</tt></p>
<p>Returns the local feature object with the given region coords and index.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.maps.getTileBiomeRgn(coords)</tt>, or <tt class="docutils literal">getTileBiomeRgn(x,y,z)</tt></p>
<p>Returns <em>x, y</em> for use with <tt class="docutils literal">getRegionBiome</tt>.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.maps.canWalkBetween(pos1, pos2)</tt></p>
<p>Checks if a dwarf may be able to walk between the two tiles,
using a pathfinding cache maintained by the game. Note that

@ -94,6 +94,26 @@ void Lua::Push(lua_State *state, const Units::NoblePosition &pos)
lua_setfield(state, -2, "position");
}
void Lua::Push(lua_State *state, df::coord pos)
{
lua_createtable(state, 0, 3);
lua_pushinteger(state, pos.x);
lua_setfield(state, -2, "x");
lua_pushinteger(state, pos.y);
lua_setfield(state, -2, "y");
lua_pushinteger(state, pos.z);
lua_setfield(state, -2, "z");
}
void Lua::Push(lua_State *state, df::coord2d pos)
{
lua_createtable(state, 0, 2);
lua_pushinteger(state, pos.x);
lua_setfield(state, -2, "x");
lua_pushinteger(state, pos.y);
lua_setfield(state, -2, "y");
}
int Lua::PushPosXYZ(lua_State *state, df::coord pos)
{
if (!pos.isValid())
@ -110,6 +130,21 @@ int Lua::PushPosXYZ(lua_State *state, df::coord pos)
}
}
int Lua::PushPosXY(lua_State *state, df::coord2d pos)
{
if (!pos.isValid())
{
lua_pushnil(state);
return 1;
}
else
{
lua_pushinteger(state, pos.x);
lua_pushinteger(state, pos.y);
return 2;
}
}
static df::coord2d CheckCoordXY(lua_State *state, int base, bool vararg = false)
{
df::coord2d p;
@ -754,7 +789,6 @@ static const luaL_Reg dfhack_items_funcs[] = {
static const LuaWrapper::FunctionReg dfhack_maps_module[] = {
WRAPN(getBlock, (df::map_block* (*)(int32_t,int32_t,int32_t))Maps::getBlock),
WRAPM(Maps, getRegionBiome),
WRAPM(Maps, enableBlockUpdates),
WRAPM(Maps, getGlobalInitFeature),
WRAPM(Maps, getLocalInitFeature),
@ -769,8 +803,24 @@ static int maps_getTileBlock(lua_State *L)
return 1;
}
static int maps_getRegionBiome(lua_State *L)
{
auto pos = CheckCoordXY(L, 1, true);
Lua::PushDFObject(L, Maps::getRegionBiome(pos));
return 1;
}
static int maps_getTileBiomeRgn(lua_State *L)
{
auto pos = CheckCoordXYZ(L, 1, true);
Lua::PushPosXY(L, Maps::getTileBiomeRgn(pos));
return 1;
}
static const luaL_Reg dfhack_maps_funcs[] = {
{ "getTileBlock", maps_getTileBlock },
{ "getRegionBiome", maps_getRegionBiome },
{ "getTileBiomeRgn", maps_getTileBiomeRgn },
{ NULL, NULL }
};

@ -264,11 +264,14 @@ namespace DFHack {namespace Lua {
inline void Push(lua_State *state, bool value) {
lua_pushboolean(state, value);
}
inline void Push(lua_State *state, const char *str) {
lua_pushstring(state, str);
}
inline void Push(lua_State *state, const std::string &str) {
lua_pushlstring(state, str.data(), str.size());
}
inline void Push(lua_State *state, df::coord &obj) { PushDFObject(state, &obj); }
inline void Push(lua_State *state, df::coord2d &obj) { PushDFObject(state, &obj); }
DFHACK_EXPORT void Push(lua_State *state, df::coord obj);
DFHACK_EXPORT void Push(lua_State *state, df::coord2d obj);
void Push(lua_State *state, const Units::NoblePosition &pos);
template<class T> inline void Push(lua_State *state, T *ptr) {
PushDFObject(state, ptr);
@ -293,6 +296,7 @@ namespace DFHack {namespace Lua {
}
DFHACK_EXPORT int PushPosXYZ(lua_State *state, df::coord pos);
DFHACK_EXPORT int PushPosXY(lua_State *state, df::coord2d pos);
DFHACK_EXPORT bool IsCoreContext(lua_State *state);

@ -255,8 +255,20 @@ inline df::tile_occupancy *getTileOccupancy(df::coord pos) {
return getTileOccupancy(pos.x, pos.y, pos.z);
}
/**
* Returns biome info about the specified world region.
*/
DFHACK_EXPORT df::world_data::T_region_map *getRegionBiome(df::coord2d rgn_pos);
/**
* Returns biome world region coordinates for the given tile within given block.
*/
DFHACK_EXPORT df::coord2d getBlockTileBiomeRgn(df::map_block *block, df::coord2d pos);
inline df::coord2d getTileBiomeRgn(df::coord pos) {
return getBlockTileBiomeRgn(getTileBlock(pos), pos);
}
// Enables per-frame updates for liquid flow and/or temperature.
DFHACK_EXPORT void enableBlockUpdates(df::map_block *blk, bool flow = false, bool temperature = false);

@ -111,9 +111,11 @@ function copyall(table)
end
function pos2xyz(pos)
local x = pos.x
if x and x ~= -30000 then
return x, pos.y, pos.z
if pos then
local x = pos.x
if x and x ~= -30000 then
return x, pos.y, pos.z
end
end
end

@ -369,6 +369,39 @@ bool Maps::RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, df::block_square
return false;
}
static df::coord2d biome_offsets[9] = {
df::coord2d(-1,-1), df::coord2d(0,-1), df::coord2d(1,-1),
df::coord2d(-1,0), df::coord2d(0,0), df::coord2d(1,0),
df::coord2d(-1,1), df::coord2d(0,1), df::coord2d(1,1)
};
inline df::coord2d getBiomeRgnPos(df::coord2d base, int idx)
{
auto r = base + biome_offsets[idx];
int world_width = world->world_data->world_width;
int world_height = world->world_data->world_height;
return df::coord2d(clip_range(r.x,0,world_width-1),clip_range(r.y,0,world_height-1));
}
df::coord2d Maps::getBlockTileBiomeRgn(df::map_block *block, df::coord2d pos)
{
if (!block || !world->world_data)
return df::coord2d();
auto des = MapExtras::index_tile<df::tile_designation>(block->designation,pos);
unsigned idx = des.bits.biome;
if (idx < 9)
{
idx = block->region_offset[idx];
if (idx < 9)
return getBiomeRgnPos(block->region_pos, idx);
}
return df::coord2d();
}
/*
* Layer geology
*/
@ -386,20 +419,14 @@ bool Maps::ReadGeology(vector<vector<int16_t> > *layer_mats, vector<df::coord2d>
(*geoidx)[i] = df::coord2d(-30000,-30000);
}
int world_width = world->world_data->world_width;
int world_height = world->world_data->world_height;
// regionX is in embark squares
// regionX/16 is in 16x16 embark square regions
df::coord2d map_region(world->map.region_x / 16, world->map.region_y / 16);
// iterate over 8 surrounding regions + local region
for (int i = eNorthWest; i < eBiomeCount; i++)
{
// check against worldmap boundaries, fix if needed
// regionX is in embark squares
// 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);
int bioRY = world->map.region_y / 16 + ((i / 3) - 1);
df::coord2d rgn_pos(clip_range(bioRX,0,world_width-1),clip_range(bioRY,0,world_height-1));
df::coord2d rgn_pos = getBiomeRgnPos(map_region, i);
(*geoidx)[i] = rgn_pos;