Files
integration/luprex/core/cpp/world-accessor.cpp
2021-10-13 20:16:30 -04:00

191 lines
5.4 KiB
C++

#include "world.hpp"
LuaDefine(tangible_animstate, "c") {
LuaArg tanobj;
LuaRet graphic, plane, x, y, z, facing;
LuaStack LS(L, tanobj, graphic, plane, x, y, z, facing);
World *w = World::fetch_global_pointer(L);
Tangible *tan = w->tangible_get(LS, tanobj);
const AnimStep &aqback = tan->anim_queue_.back();
LS.set(graphic, aqback.graphic());
LS.set(plane, aqback.plane());
LS.set(x, aqback.xyz().x);
LS.set(y, aqback.xyz().y);
LS.set(z, aqback.xyz().z);
LS.set(facing, aqback.facing());
return LS.result();
}
LuaDefine(tangible_animate, "c") {
LuaArg tanobj, config;
LuaStack LS(L, tanobj, config);
World *w = World::fetch_global_pointer(L);
Tangible *tan = w->tangible_get(LS, tanobj);
int64_t id = w->id_global_pool_.alloc_id_for_thread(L);
const AnimStep &prev = tan->anim_queue_.back();
AnimStep step;
step.from_lua(L, config.index(), prev);
if (step.action() == "") {
luaL_error(L, "animation action must be specified");
}
tan->anim_queue_.add(id, step);
tan->update_plane_item();
return LS.result();
}
LuaDefine(tangible_setclass, "c") {
LuaArg tanobj, classname;
LuaVar classtab, mt;
LuaStack LS(L, tanobj, classname, classtab, mt);
World *w = World::fetch_global_pointer(L);
w->tangible_get(LS, tanobj);
if (LS.classname(classname) != "") {
LS.set(classtab, classname);
} else {
LS.getclass(classtab, classname);
}
LS.getmetatable(mt, tanobj);
LS.rawset(mt, "__index", classtab);
return LS.result();
}
LuaDefine(tangible_delete, "c") {
LuaArg tanobj;
LuaStack LS(L, tanobj);
World *w = World::fetch_global_pointer(L);
Tangible *tan = w->tangible_get(LS, tanobj);
assert(tan != nullptr); // this should be checked above.
if (tan->is_an_actor()) {
luaL_error(L, "Cannot delete a player using tangible.delete, use tangible.redirect instead.");
return 0;
}
w->tangible_delete(tan->id());
return LS.result();
}
LuaDefine(tangible_build, "c") {
LuaArg config;
LuaVar classname, classtab, mt;
LuaRet database;
LuaStack LS(L, config, classname, classtab, database, mt);
LS.checktable(config);
// Get the class of the new tangible.
LS.rawget(classname, config, "class");
if (LS.isnil(classname)) {
luaL_error(L, "must specify a class name");
}
LS.getclass(classtab, classname);
// Parse the initial animation step.
AnimStep initstep, blank;
initstep.from_lua(L, config.index(), blank);
if (!initstep.has_xyz()) {
luaL_error(L, "You must specify (X,Y,Z) for new tangible");
}
if (!initstep.has_plane()) {
luaL_error(L, "You must specify plane for new tangible");
}
if (!initstep.has_graphic()) {
luaL_error(L, "You must specify graphic for new tangible");
}
// TODO: generate error if there's extra crap in the config table.
World *w = World::fetch_global_pointer(L);
Tangible *tan = w->tangible_make(L, 0, "nowhere", true);
lua_replace(L, database.index());
// Update the class of the new tangible.
LS.getmetatable(mt, database);
LS.rawset(mt, "__index", classtab);
// Update the animation queue and planemap of the new tangible.
int64_t stepid = w->id_global_pool_.alloc_id_for_thread(L);
tan->anim_queue_.add(stepid, initstep);
tan->update_plane_item();
return LS.result();
}
LuaDefine(tangible_get, "c") {
LuaArg id;
LuaVar tangibles;
LuaRet database;
LuaStack LS(L, id, tangibles, database);
int64_t nid = LS.ckinteger(id);
LS.rawget(tangibles, LuaRegistry, "tangibles");
LS.rawget(database, tangibles, id);
if (!LS.istable(database)) {
luaL_error(L, "Not a tangible ID: %d", nid);
}
return LS.result();
}
LuaDefine(tangible_redirect, "c") {
LuaArg actor1, actor2, bldz;
LuaStack LS(L, actor1, actor2, bldz);
World *w = World::fetch_global_pointer(L);
bool bulldoze = LS.ckboolean(bldz);
Tangible *tan1 = w->tangible_get(LS, actor1);
if (!tan1->is_an_actor()) {
luaL_error(L, "redirect source is not an actor");
}
if (LS.isnil(actor2)) {
w->redirects_[tan1->id()] = 0;
} else {
Tangible *tan2 = w->tangible_get(LS, actor2);
tan2->configure_id_pool_for_actor();
w->redirects_[tan1->id()] = tan2->id();
}
if (bulldoze) {
w->tangible_delete(tan1->id());
}
return LS.result();
}
LuaDefine(tangible_id, "c") {
LuaArg tanobj;
LuaRet id;
LuaStack LS(L, tanobj, id);
LS.set(id, World::tangible_id(LS, tanobj));
return LS.result();
}
LuaDefine(world_wait, "f") {
if ((lua_gettop(L) != 1) || (lua_type(L, -1) != LUA_TNUMBER)) {
luaL_error(L, "Argument to wait must be a number.");
}
return lua_yield(L, 1);
}
LuaDefine(world_getregistry, "f") {
lua_pushvalue(L, LUA_REGISTRYINDEX);
return 1;
}
LuaDefine(world_xtype, "f") {
LuaArg tab;
LuaRet rtype;
LuaStack LS(L, tab, rtype);
int xt = LS.xtype(tab);
LS.set(rtype, xt);
return LS.result();
}
LuaDefine(world_settabletype, "f") {
LuaArg tab, ttype;
LuaStack LS(L, tab, ttype);
if (!LS.istable(tab)) {
luaL_error(L, "Not a table");
}
int tt = LS.ckinteger(ttype);
if ((tt < LUA_TT_GENERAL) || (tt > LUA_TT_CLASS)) {
luaL_error(L, "table type out of range");
}
LS.settabletype(tab, tt);
return LS.result();
}