151 lines
4.4 KiB
C++
151 lines
4.4 KiB
C++
#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);
|