Files
integration/luprex/syscpp/cellgrid.cpp

151 lines
4.4 KiB
C++
Raw Normal View History

2021-01-02 13:31:18 -05:00
#include "luastack.hpp"
#include "cellgrid.hpp"
#include "table.hpp"
#include <math.h>
#include <cfloat>
LuaDefine(cellgrid_initregistry, "a") {
LuaVar grid;
LuaStack LS(L, grid);
LS.getfield(grid, LuaRegistry, "cellgrid_cells");
if (LS.isnil(grid)) {
LS.newtable(grid);
LS.setfield(LuaRegistry, "cellgrid_cells", grid);
}
return LS.result();
}
LuaDefine(cellgrid_addplane, "c") {
LuaArg grid, plane;
LuaVar planegrid;
LuaStack LS(L, grid, plane, planegrid);
// Get the grid.
if (LS.isnil(grid)) LS.getfield(grid, LuaRegistry, "cellgrid_cells");
LS.checktable(grid);
// Check for the plane. If not present, add it.
LS.checkstring(plane);
LS.rawget(planegrid, grid, plane);
if (LS.isnil(planegrid)) {
LS.rawset(grid, plane, LuaNewTable);
}
return LS.result();
}
#define CELL_SCALE 10.0
#define CELL_INVALID 0
LuaDefine(cellgrid_scale, "c") {
LuaRet scale;
LuaStack LS(L, scale);
LS.set(scale, CELL_SCALE);
return LS.result();
}
lua_Number calc_cellid(lua_Number x, lua_Number y, lua_Number z) {
lua_Number cellx = floor(x / CELL_SCALE);
lua_Number celly = floor(y / CELL_SCALE);
lua_Number cellz = floor(z / CELL_SCALE);
if ((cellx > 32767)||(celly > 32767)||(cellz > 32767)) {
return CELL_INVALID;
}
if ((cellx < -32767)||(celly < -32767)||(cellz < -32767)) {
return CELL_INVALID;
}
int64_t icellx = int64_t(cellx) & 0xFFFF;
int64_t icelly = int64_t(celly) & 0xFFFF;
int64_t icellz = int64_t(cellz) & 0xFFFF;
return lua_Number(0x0001000000000000 | (icellx << 32) | (icelly << 16) | (icellz << 0));
}
LuaDefine(cellgrid_cellid, "c") {
LuaArg x, y, z;
LuaRet cellid;
LuaStack LS(L, x, y, z, cellid);
lua_Number nx = LS.cknumber(x);
lua_Number ny = LS.cknumber(y);
lua_Number nz = LS.cknumber(z);
LS.set(cellid, calc_cellid(nx, ny, nz));
return LS.result();
}
LuaDefine(cellgrid_setpos, "c") {
LuaArg grid, sprite, x, y, z, nplane;
LuaVar smt, oplane, planegrid, cell;
LuaStack LS(L, grid, sprite, x, y, z, nplane, smt, oplane, planegrid, cell);
// Get the grid.
if (LS.isnil(grid)) LS.getfield(grid, LuaRegistry, "cellgrid_cells");
LS.checktable(grid);
// Calculate the new plane and cell ID.
lua_Number nx, ny, nz;
nx = LS.cknumber(x);
ny = LS.cknumber(y);
nz = LS.cknumber(z);
if (!LS.isnil(nplane)) LS.checkstring(nplane);
lua_Number ncellid = calc_cellid(nx, ny, nz);
// Check that the new plane is an existing plane.
LS.rawget(planegrid, grid, nplane);
if (!LS.istable(planegrid)) {
luaL_error(L, "invalid plane");
}
// Get the sprite metatable.
LS.checktable(sprite);
LS.getmetatable(smt, sprite);
LS.checktable(smt);
// Get the sprite's old plane and cell ID.
lua_Number ox, oy, oz;
LS.getfield(LuaAcceptNil(ox), smt, "x");
LS.getfield(LuaAcceptNil(oy), smt, "y");
LS.getfield(LuaAcceptNil(oz), smt, "z");
LS.getfield(oplane, smt, "plane");
lua_Number ocellid = calc_cellid(ox, oy, oz);
// The sprite 'moved' if it's in a new cell.
bool moved = (!LS.equal(nplane, oplane)) || (ncellid != ocellid);
// Change the sprite position.
LS.rawset(smt, "x", x);
LS.rawset(smt, "y", y);
LS.rawset(smt, "z", z);
LS.rawset(smt, "plane", nplane);
// Remove sprite from the old cell.
if (moved && LS.isstring(oplane) && (ocellid != CELL_INVALID)) {
LS.rawget(planegrid, grid, oplane);
if (LS.istable(planegrid)) {
LS.rawget(cell, planegrid, ocellid);
if (LS.istable(cell)) {
LS.call(LuaDiscard, table_findremove, cell, sprite);
if (LS.isemptytable(cell)) {
LS.rawset(planegrid, ocellid, LuaNil);
}
}
}
}
// Insert sprite into the new cell
if (moved && LS.isstring(nplane) && (ncellid != CELL_INVALID)) {
LS.rawget(planegrid, grid, nplane);
if (LS.istable(planegrid)) {
LS.rawget(cell, planegrid, ncellid);
if (!LS.istable(cell)) {
LS.newtable(cell);
LS.rawset(planegrid, ncellid, cell);
}
LS.call(table_append, cell, sprite);
}
}
return LS.result();
}
int cellgrid_scanradius(lua_State *L);
int cellgrid_scanregion(lua_State *L);