diff --git a/luprex/core/cpp/world.cpp b/luprex/core/cpp/world.cpp index d52ba0ac..11a12a64 100644 --- a/luprex/core/cpp/world.cpp +++ b/luprex/core/cpp/world.cpp @@ -37,6 +37,12 @@ World::World() { assert (lua_gettop(state()) == 0); } +void Tangible::update_plane_item() { + util::XYZ xyz = anim_queue_.get_xyz(); + std::string plane = anim_queue_.get_plane(); + plane_item_.set_pos(plane, xyz.x, xyz.y, xyz.z); +} + void Tangible::be_a_player() { if (id_player_pool_ == nullptr) { id_player_pool_.reset(new IdPlayerPool(&world_->id_global_pool_)); @@ -78,6 +84,25 @@ Tangible *World::tangible_get(int64_t id) { } } +Tangible *World::tangible_get(lua_State *L, int idx) { + Tangible *result = nullptr; + int top = lua_gettop(L); + if (lua_istable(L, idx)) { + lua_getmetatable(L, idx); + if (lua_istable(L, -1)) { + lua_pushstring(L, "id"); + lua_rawget(L, -2); + lua_Number id = lua_tonumber(L, -1); + result = tangible_get(int64_t(id)); + } + } + lua_settop(L, top); + if (result == nullptr) { + luaL_error(L, "parameter is not a tangible"); + } + return result; +} + std::vector World::get_near(int64_t player_id, float radius) { Tangible *player = tangible_get(player_id); @@ -327,14 +352,31 @@ void World::run_scheduled_threads(int64_t clk) { LS.result(); } -LuaDefine(tangible_get, "c") { - LuaArg id; - LuaRet database; - LuaVar tangibles; - LuaStack LS(L, id, database, tangibles); +LuaDefine(tangible_xyz, "c") { + LuaArg tanobj; + LuaRet X, Y, Z; + LuaStack LS(L, tanobj, X, Y, Z); + World *w = World::fetch_global_pointer(L); + Tangible *tan = w->tangible_get(L, tanobj.index()); + util::XYZ xyz = tan->anim_queue_.get_xyz(); + LS.set(X, xyz.x); + LS.set(Y, xyz.y); + LS.set(Z, xyz.z); + return LS.result(); +} - LS.rawget(tangibles, LuaRegistry, "tangibles"); - LS.rawget(database, tangibles, id); +LuaDefine(tangible_walkto, "c") { + LuaArg tanobj, x, y, z; + LuaStack LS(L, tanobj, x, y, z); + World *w = World::fetch_global_pointer(L); + lua_Number nx = LS.cknumber(x); + lua_Number ny = LS.cknumber(y); + lua_Number nz = LS.cknumber(z); + Tangible *tan = w->tangible_get(L, tanobj.index()); + int64_t id = w->id_global_pool_.alloc_id_for_thread(L); + tan->anim_queue_.add(id, "walk"); + tan->anim_queue_.set_xyz(util::XYZ(nx, ny, nz)); + tan->update_plane_item(); return LS.result(); } diff --git a/luprex/core/cpp/world.hpp b/luprex/core/cpp/world.hpp index d8b94bda..8a7a7ae1 100644 --- a/luprex/core/cpp/world.hpp +++ b/luprex/core/cpp/world.hpp @@ -43,6 +43,7 @@ public: std::unique_ptr id_player_pool_; void be_a_player(); + void update_plane_item(); }; class World { @@ -110,6 +111,13 @@ public: // Get a pointer to the specified tangible. // Tangible *tangible_get(int64_t id); + + // Get a pointer to the specified tangible. + // + // The value on the lua stack should be a valid lua tangible. If not, + // a lua error is generated. + // + Tangible *tangible_get(lua_State *L, int idx); // Delete a tangible with the specified ID. // diff --git a/luprex/core/lua/player.lua b/luprex/core/lua/player.lua index 74f293e2..a092d1dc 100644 --- a/luprex/core/lua/player.lua +++ b/luprex/core/lua/player.lua @@ -9,18 +9,26 @@ end function player.action.north(actor, place, dialog) print("Moving north") + x,y,z = tangible.xyz(place); + tangible.walkto(place, x, y+1, z); end function player.action.south(actor, place, dialog) print("Moving south") + x,y,z = tangible.xyz(place); + tangible.walkto(place, x, y-1, z); end function player.action.east(actor, place, dialog) print("Moving east") + x,y,z = tangible.xyz(place); + tangible.walkto(place, x+1, y, z); end function player.action.west(actor, place, dialog) print("Moving west") + x,y,z = tangible.xyz(place) + tangible.walkto(place, x-1, y, z); wait(0) print("Moving west again") end