]> git.lizzy.rs Git - dragonfireclient.git/commitdiff
Include tile definitions in get_node_def; Client-side minetest.object_refs table
authorElias Fleckenstein <eliasfleckenstein@web.de>
Tue, 11 May 2021 12:07:30 +0000 (14:07 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Tue, 11 May 2021 12:07:30 +0000 (14:07 +0200)
15 files changed:
builtin/client/register.lua
builtin/common/misc_helpers.lua
builtin/game/item.lua
doc/client_lua_api.txt
src/client/clientenvironment.cpp
src/client/game.cpp
src/script/common/c_content.cpp
src/script/cpp_api/s_base.cpp
src/script/cpp_api/s_base.h
src/script/cpp_api/s_client.cpp
src/script/lua_api/l_client.cpp
src/script/lua_api/l_clientobject.cpp
src/script/lua_api/l_clientobject.h
src/script/lua_api/l_localplayer.cpp
src/serverenvironment.cpp

index 835ec5002c1d6c41fbe9bc3b3004937680597d0e..6a6d8e13c3ce6e9470fc4119689d3d7c5f90db4e 100644 (file)
@@ -110,3 +110,4 @@ core.registered_on_object_hp_change, core.register_on_object_hp_change = make_re
 
 core.registered_nodes = {}
 core.registered_items = {}
+core.object_refs = {}
index b86d68f5f50fe5d32c42bca4cabf8f9fe14df52b..308e2c7c787dd526648d5868221c452a194fee6c 100644 (file)
@@ -785,3 +785,12 @@ end
 function core.is_nan(number)
        return number ~= number
 end
+
+function core.inventorycube(img1, img2, img3)
+       img2 = img2 or img1
+       img3 = img3 or img1
+       return "[inventorycube"
+                       .. "{" .. img1:gsub("%^", "&")
+                       .. "{" .. img2:gsub("%^", "&")
+                       .. "{" .. img3:gsub("%^", "&")
+end
index dc0247e5fcb265dcb21a1b0bca892f82492f0507..cc0314e673b0ecb605292fc1f4a671f5493da561 100644 (file)
@@ -15,15 +15,6 @@ end
 -- Item definition helpers
 --
 
-function core.inventorycube(img1, img2, img3)
-       img2 = img2 or img1
-       img3 = img3 or img1
-       return "[inventorycube"
-                       .. "{" .. img1:gsub("%^", "&")
-                       .. "{" .. img2:gsub("%^", "&")
-                       .. "{" .. img3:gsub("%^", "&")
-end
-
 function core.dir_to_facedir(dir, is6d)
        --account for y if requested
        if is6d and math.abs(dir.y) > math.abs(dir.x) and math.abs(dir.y) > math.abs(dir.z) then
index 2e347ec47fcc4903ebea65f9097c13c6e592a365..e33fe0e3a37bc8bc8d4c0f14c92b5571f4f3becd 100644 (file)
@@ -934,6 +934,8 @@ Call these functions only at load time!
     * Convert between two privilege representations
 
 ### Client Environment
+* `minetest.object_refs`
+    * Map of object references, indexed by active object id
 * `minetest.get_player_names()`
     * Returns list of player names on server (nil if CSM_RF_READ_PLAYERINFO is enabled by server)
 * `minetest.get_objects_inside_radius(pos, radius)`: returns a list of
@@ -1454,6 +1456,8 @@ It can be created via `Raycast(pos1, pos2, objects, liquids)` or
 
 -----------------
 ### Definitions
+* `minetest.inventorycube(img1, img2, img3)`
+    * Returns a string for making an image of a cube (useful as an item image)
 * `minetest.get_node_def(nodename)`
        * Returns [node definition](#node-definition) table of `nodename`
 * `minetest.get_item_def(itemstring)`
@@ -1465,10 +1469,67 @@ It can be created via `Raycast(pos1, pos2, objects, liquids)` or
       {light_source=minetest.LIGHT_MAX})`
     * Doesnt really work yet an causes strange bugs, I'm working to make is better
 
+
+#### Tile definition
+
+* `"image.png"`
+* `{name="image.png", animation={Tile Animation definition}}`
+* `{name="image.png", backface_culling=bool, align_style="node"/"world"/"user", scale=int}`
+    * backface culling enabled by default for most nodes
+    * align style determines whether the texture will be rotated with the node
+      or kept aligned with its surroundings. "user" means that client
+      setting will be used, similar to `glasslike_framed_optional`.
+      Note: supported by solid nodes and nodeboxes only.
+    * scale is used to make texture span several (exactly `scale`) nodes,
+      instead of just one, in each direction. Works for world-aligned
+      textures only.
+      Note that as the effect is applied on per-mapblock basis, `16` should
+      be equally divisible by `scale` or you may get wrong results.
+* `{name="image.png", color=ColorSpec}`
+    * the texture's color will be multiplied with this color.
+    * the tile's color overrides the owning node's color in all cases.
+
+##### Tile definition
+
+    {
+        type = "vertical_frames",
+
+        aspect_w = 16,
+        -- Width of a frame in pixels
+
+        aspect_h = 16,
+        -- Height of a frame in pixels
+
+        length = 3.0,
+        -- Full loop length
+    }
+
+    {
+        type = "sheet_2d",
+
+        frames_w = 5,
+        -- Width in number of frames
+
+        frames_h = 3,
+        -- Height in number of frames
+
+        frame_length = 0.5,
+        -- Length of a single frame
+    }
+
 #### Node Definition
 
 ```lua
        {
+        tiles = {tile definition 1, def2, def3, def4, def5, def6},
+        -- Textures of node; +Y, -Y, +X, -X, +Z, -Z
+        overlay_tiles = {tile definition 1, def2, def3, def4, def5, def6},
+        -- Same as `tiles`, but these textures are drawn on top of the base
+        -- tiles. This is used to colorize only specific parts of the
+        -- texture. If the texture name is an empty string, that overlay is not
+        -- drawn
+        special_tiles = {tile definition 1, Tile definition 2},
+        -- Special textures of node; used rarely.
                has_on_construct = bool,        -- Whether the node has the on_construct callback defined
                has_on_destruct = bool,         -- Whether the node has the on_destruct callback defined
                has_after_destruct = bool,      -- Whether the node has the after_destruct callback defined
index fd56c8f44a22defdf4448a1290de97bb089e6227..8e0d00bc9a0f82ebcdd677cf7958aad67fe0ab8e 100644 (file)
@@ -352,6 +352,7 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type,
 {
        ClientActiveObject* obj =
                ClientActiveObject::create((ActiveObjectType) type, m_client, this);
+
        if(obj == NULL)
        {
                infostream<<"ClientEnvironment::addActiveObject(): "
@@ -362,6 +363,9 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type,
 
        obj->setId(id);
 
+       if (m_client->modsLoaded())
+               m_client->getScript()->addObjectReference(dynamic_cast<ActiveObject*>(obj));
+
        try
        {
                obj->initialize(init_data);
@@ -394,9 +398,14 @@ void ClientEnvironment::removeActiveObject(u16 id)
 {
        // Get current attachment childs to detach them visually
        std::unordered_set<int> attachment_childs;
-       if (auto *obj = getActiveObject(id))
+       auto *obj = getActiveObject(id);
+       if (obj) {
                attachment_childs = obj->getAttachmentChildIds();
 
+               if (m_client->modsLoaded())
+                       m_client->getScript()->removeObjectReference(dynamic_cast<ActiveObject*>(obj));
+       }
+
        m_ao_manager.removeObject(id);
 
        // Perform a proper detach in Irrlicht
index 104a6e374e6c9f097868426167c2ba6288856a18..e1f2fbe75c0d0f93dcd0359a915dcdc917abe17a 100644 (file)
@@ -734,7 +734,7 @@ bool Game::connectToServer(const GameStartData &start_data,
                        } else {
                                wait_time += dtime;
                                // Only time out if we aren't waiting for the server we started
-                               if (!start_data.isSinglePlayer() && wait_time > 10) {
+                               if (!start_data.local_server && !start_data.isSinglePlayer() && wait_time > 10) {
                                        *error_message = "Connection timed out.";
                                        errorstream << *error_message << std::endl;
                                        break;
index 8543b70ced4a810ca5ad71972235f8361eb2a642..e56d07cc6867f03c393c4a7bdb236d62adad0ac9 100644 (file)
@@ -515,6 +515,35 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype)
        return tiledef;
 }
 
+/******************************************************************************/
+void push_tiledef(lua_State *L, TileDef tiledef)
+{
+       lua_newtable(L);
+       setstringfield(L, -1, "name", tiledef.name);
+       setboolfield(L, -1, "backface_culling", tiledef.backface_culling);
+       setboolfield(L, -1, "tileable_horizontal", tiledef.tileable_horizontal);
+       setboolfield(L, -1, "tileable_vertical", tiledef.tileable_vertical);
+       std::string align_style;
+       switch (tiledef.align_style) {
+       case ALIGN_STYLE_USER_DEFINED:
+                       align_style = "user";
+                       break;
+       case ALIGN_STYLE_WORLD:
+                       align_style = "world";
+                       break;
+       default:
+                       align_style = "node";
+       }
+       setstringfield(L, -1, "align_style", align_style);
+       setintfield(L, -1, "scale", tiledef.scale);
+       if (tiledef.has_color) {
+               push_ARGB8(L, tiledef.color);
+               lua_setfield(L, -2, "color");
+       }
+       push_animation_definition(L, tiledef.animation);
+       lua_setfield(L, -2, "animation");
+}
+
 /******************************************************************************/
 void read_content_features(lua_State *L, ContentFeatures &f, int index)
 {
@@ -835,9 +864,32 @@ void push_content_features(lua_State *L, const ContentFeatures &c)
        std::string drawtype(ScriptApiNode::es_DrawType[(int)c.drawtype].str);
        std::string liquid_type(ScriptApiNode::es_LiquidType[(int)c.liquid_type].str);
 
-       /* Missing "tiles" because I don't see a usecase (at least not yet). */
+       lua_newtable(L);
 
+       // tiles
        lua_newtable(L);
+       for (int i = 0; i < 6; i++) {
+               push_tiledef(L, c.tiledef[i]);
+               lua_rawseti(L, -2, i + 1);
+       }
+       lua_setfield(L, -2, "tiles");
+
+       // overlay_tiles
+       lua_newtable(L);
+       for (int i = 0; i < 6; i++) {
+               push_tiledef(L, c.tiledef_overlay[i]);
+               lua_rawseti(L, -2, i + 1);
+       }
+       lua_setfield(L, -2, "overlay_tiles");
+
+       // special_tiles
+       lua_newtable(L);
+       for (int i = 0; i < CF_SPECIAL_COUNT; i++) {
+               push_tiledef(L, c.tiledef_special[i]);
+               lua_rawseti(L, -2, i + 1);
+       }
+       lua_setfield(L, -2, "special_tiles");
+
        lua_pushboolean(L, c.has_on_construct);
        lua_setfield(L, -2, "has_on_construct");
        lua_pushboolean(L, c.has_on_destruct);
@@ -1886,14 +1938,7 @@ void push_pointed_thing(lua_State *L, const PointedThing &pointed, bool csm,
        } else if (pointed.type == POINTEDTHING_OBJECT) {
                lua_pushstring(L, "object");
                lua_setfield(L, -2, "type");
-               if (csm) {
-#ifndef SERVER
-                       ClientObjectRef::create(L, pointed.object_id);
-#endif
-               } else {
-                       push_objectRef(L, pointed.object_id);
-               }
-
+               push_objectRef(L, pointed.object_id);
                lua_setfield(L, -2, "ref");
        } else {
                lua_pushstring(L, "nothing");
index 1d62d8b65e280bd485721976f3dee2f494fd56d8..867f61e0c6d56bdc1e54d6030f03a3657697f697 100644 (file)
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "cpp_api/s_internal.h"
 #include "cpp_api/s_security.h"
 #include "lua_api/l_object.h"
+#include "lua_api/l_clientobject.h"
 #include "common/c_converter.h"
 #include "server/player_sao.h"
 #include "filesys.h"
@@ -354,13 +355,16 @@ void ScriptApiBase::setOriginFromTableRaw(int index, const char *fxn)
  *     since we lose control over the ref and the contained pointer.
  */
 
-void ScriptApiBase::addObjectReference(ServerActiveObject *cobj)
+void ScriptApiBase::addObjectReference(ActiveObject *cobj)
 {
        SCRIPTAPI_PRECHECKHEADER
        //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
 
        // Create object on stack
-       ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
+       if (m_type == ScriptingType::Client)
+               ClientObjectRef::create(L, dynamic_cast<ClientActiveObject *>(cobj));
+       else
+               ObjectRef::create(L, dynamic_cast<ServerActiveObject *>(cobj)); // Puts ObjectRef (as userdata) on stack
        int object = lua_gettop(L);
 
        // Get core.object_refs table
@@ -375,7 +379,7 @@ void ScriptApiBase::addObjectReference(ServerActiveObject *cobj)
        lua_settable(L, objectstable);
 }
 
-void ScriptApiBase::removeObjectReference(ServerActiveObject *cobj)
+void ScriptApiBase::removeObjectReference(ActiveObject *cobj)
 {
        SCRIPTAPI_PRECHECKHEADER
        //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
@@ -390,7 +394,10 @@ void ScriptApiBase::removeObjectReference(ServerActiveObject *cobj)
        lua_pushnumber(L, cobj->getId()); // Push id
        lua_gettable(L, objectstable);
        // Set object reference to NULL
-       ObjectRef::set_null(L);
+       if (m_type == ScriptingType::Client)
+               ClientObjectRef::set_null(L);
+       else
+               ObjectRef::set_null(L);
        lua_pop(L, 1); // pop object
 
        // Set object_refs[id] = nil
@@ -413,7 +420,6 @@ void ScriptApiBase::objectrefGetOrCreate(lua_State *L,
                                        << ", this is probably a bug." << std::endl;
        }
 }
-
 void ScriptApiBase::pushPlayerHPChangeReason(lua_State *L, const PlayerHPChangeReason &reason)
 {
        if (reason.hasLuaReference())
index 36331ad37eda9153018043d85cb7801f99136f6b..a7a2c7203e890a439847a9ae46e3251fdff8d7f4 100644 (file)
@@ -73,6 +73,7 @@ class Game;
 class IGameDef;
 class Environment;
 class GUIEngine;
+class ActiveObject;
 class ServerActiveObject;
 struct PlayerHPChangeReason;
 
@@ -99,8 +100,8 @@ class ScriptApiBase : protected LuaHelper {
                RunCallbacksMode mode, const char *fxn);
 
        /* object */
-       void addObjectReference(ServerActiveObject *cobj);
-       void removeObjectReference(ServerActiveObject *cobj);
+       void addObjectReference(ActiveObject *cobj);
+       void removeObjectReference(ActiveObject *cobj);
 
        IGameDef *getGameDef() { return m_gamedef; }
        Server* getServer();
index 2231cf5730a965ee2fd582283b6b4d920ea80247..7971e4081891a99587477c3fd7508ac6efc03f0b 100644 (file)
@@ -302,7 +302,7 @@ void ScriptApiClient::on_object_properties_change(s16 id)
        lua_getfield(L, -1, "registered_on_object_properties_change");
 
        // Push data
-       ClientObjectRef::create(L, id);
+       push_objectRef(L, id);
 
        // Call functions
        runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
@@ -317,7 +317,7 @@ void ScriptApiClient::on_object_hp_change(s16 id)
        lua_getfield(L, -1, "registered_on_object_hp_change");
 
        // Push data
-       ClientObjectRef::create(L, id);
+       push_objectRef(L, id);
 
        // Call functions
        runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
index 484af2ec35e64fc055a9ff10ebed83e0677e2e26..91698398246d590ece9e4078617efcfa719000ce 100644 (file)
@@ -520,7 +520,7 @@ int ModApiClient::l_get_objects_inside_radius(lua_State *L)
        int i = 0;
        lua_createtable(L, objs.size(), 0);
        for (const auto obj : objs) {
-               ClientObjectRef::create(L, obj.obj);                                                    // TODO: getObjectRefOrCreate
+               push_objectRef(L, obj.obj->getId());
                lua_rawseti(L, -2, ++i);
        }
        return 1;
index 8a4647d456265b9fbdd1b6e31eeaa4c324e57565..5a11231690378501bc7e38191d9eb91504739c12 100644 (file)
@@ -48,6 +48,8 @@ ClientActiveObject *ClientObjectRef::get_cao(ClientObjectRef *ref)
 GenericCAO *ClientObjectRef::get_generic_cao(ClientObjectRef *ref, lua_State *L)
 {
        ClientActiveObject *obj = get_cao(ref);
+       if (! obj)
+               return nullptr;
        ClientEnvironment &env = getClient(L)->getEnv();
        GenericCAO *gcao = env.getGenericCAO(obj->getId());
        return gcao;
@@ -57,6 +59,8 @@ int ClientObjectRef::l_get_pos(lua_State *L)
 {
        ClientObjectRef *ref = checkobject(L, 1);
        ClientActiveObject *cao = get_cao(ref);
+       if (! cao)
+               return 0;
        push_v3f(L, cao->getPosition() / BS);
        return 1;
 }
@@ -65,6 +69,8 @@ int ClientObjectRef::l_get_velocity(lua_State *L)
 {
        ClientObjectRef *ref = checkobject(L, 1);
        GenericCAO *gcao = get_generic_cao(ref, L);
+       if (! gcao)
+               return 0;
        push_v3f(L, gcao->getVelocity() / BS);
        return 1;
 }
@@ -73,6 +79,8 @@ int ClientObjectRef::l_get_acceleration(lua_State *L)
 {
        ClientObjectRef *ref = checkobject(L, 1);
        GenericCAO *gcao = get_generic_cao(ref, L);
+       if (! gcao)
+               return 0;
        push_v3f(L, gcao->getAcceleration() / BS);
        return 1;
 }
@@ -81,6 +89,8 @@ int ClientObjectRef::l_get_rotation(lua_State *L)
 {
        ClientObjectRef *ref = checkobject(L, 1);
        GenericCAO *gcao = get_generic_cao(ref, L);
+       if (! gcao)
+               return 0;
        push_v3f(L, gcao->getRotation());
        return 1;
 }
@@ -89,6 +99,8 @@ int ClientObjectRef::l_is_player(lua_State *L)
 {
        ClientObjectRef *ref = checkobject(L, 1);
        GenericCAO *gcao = get_generic_cao(ref, L);
+       if (! gcao)
+               return 0;
        lua_pushboolean(L, gcao->isPlayer());
        return 1;
 }
@@ -97,6 +109,8 @@ int ClientObjectRef::l_is_local_player(lua_State *L)
 {
        ClientObjectRef *ref = checkobject(L, 1);
        GenericCAO *gcao = get_generic_cao(ref, L);
+       if (! gcao)
+               return 0;
        lua_pushboolean(L, gcao->isLocalPlayer());
        return 1;
 }
@@ -105,6 +119,8 @@ int ClientObjectRef::l_get_name(lua_State *L)
 {
        ClientObjectRef *ref = checkobject(L, 1);
        GenericCAO *gcao = get_generic_cao(ref, L);
+       if (! gcao)
+               return 0;
        lua_pushstring(L, gcao->getName().c_str());
        return 1;
 }
@@ -113,7 +129,12 @@ int ClientObjectRef::l_get_attach(lua_State *L)
 {
        ClientObjectRef *ref = checkobject(L, 1);
        GenericCAO *gcao = get_generic_cao(ref, L);
-       create(L, gcao->getParent());
+       if (! gcao)
+               return 0;
+       ClientActiveObject *parent = gcao->getParent();
+       if (! parent)
+               return 0;
+       push_objectRef(L, parent->getId());
        return 1;
 }
 
@@ -122,6 +143,8 @@ int ClientObjectRef::l_get_nametag(lua_State *L)
        log_deprecated(L,"Deprecated call to get_nametag, use get_properties().nametag instead");
        ClientObjectRef *ref = checkobject(L, 1);
        GenericCAO *gcao = get_generic_cao(ref, L);
+       if (! gcao)
+               return 0;
        ObjectProperties *props = gcao->getProperties();
        lua_pushstring(L, props->nametag.c_str());
        return 1;
@@ -132,6 +155,8 @@ int ClientObjectRef::l_get_item_textures(lua_State *L)
        log_deprecated(L,"Deprecated call to get_item_textures, use get_properties().textures instead");
        ClientObjectRef *ref = checkobject(L, 1);
        GenericCAO *gcao = get_generic_cao(ref, L);
+       if (! gcao)
+               return 0;
        ObjectProperties *props = gcao->getProperties();
        lua_newtable(L);
 
@@ -146,6 +171,8 @@ int ClientObjectRef::l_get_max_hp(lua_State *L)
        log_deprecated(L,"Deprecated call to get_max_hp, use get_properties().hp_max instead");
        ClientObjectRef *ref = checkobject(L, 1);
        GenericCAO *gcao = get_generic_cao(ref, L);
+       if (! gcao)
+               return 0;
        ObjectProperties *props = gcao->getProperties();
        lua_pushnumber(L, props->hp_max);
        return 1;
@@ -155,6 +182,8 @@ int ClientObjectRef::l_get_properties(lua_State *L)
 {
        ClientObjectRef *ref = checkobject(L, 1);
        GenericCAO *gcao = get_generic_cao(ref, L);
+       if (! gcao)
+               return 0;
        ObjectProperties *prop = gcao->getProperties();
        push_object_properties(L, prop);
        return 1;
@@ -164,6 +193,8 @@ int ClientObjectRef::l_set_properties(lua_State *L)
 {
        ClientObjectRef *ref = checkobject(L, 1);
        GenericCAO *gcao = get_generic_cao(ref, L);
+       if (! gcao)
+               return 0;
        ObjectProperties prop = *gcao->getProperties();
        read_object_properties(L, 2, nullptr, &prop, getClient(L)->idef());
        gcao->setProperties(prop);
@@ -174,6 +205,8 @@ int ClientObjectRef::l_get_hp(lua_State *L)
 {
        ClientObjectRef *ref = checkobject(L, 1);
        GenericCAO *gcao = get_generic_cao(ref, L);
+       if (! gcao)
+               return 0;
        lua_pushnumber(L, gcao->getHp());
        return 1;
 }
@@ -182,6 +215,8 @@ int ClientObjectRef::l_punch(lua_State *L)
 {
        ClientObjectRef *ref = checkobject(L, 1);
        GenericCAO *gcao = get_generic_cao(ref, L);
+       if (! gcao)
+               return 0;
        PointedThing pointed(gcao->getId(), v3f(0, 0, 0), v3s16(0, 0, 0), 0);
        getClient(L)->interact(INTERACT_START_DIGGING, pointed);
        return 0;
@@ -191,6 +226,8 @@ int ClientObjectRef::l_rightclick(lua_State *L)
 {
        ClientObjectRef *ref = checkobject(L, 1);
        GenericCAO *gcao = get_generic_cao(ref, L);
+       if (! gcao)
+               return 0;
        PointedThing pointed(gcao->getId(), v3f(0, 0, 0), v3s16(0, 0, 0), 0);
        getClient(L)->interact(INTERACT_PLACE, pointed);
        return 0;
@@ -200,6 +237,8 @@ int ClientObjectRef::l_remove(lua_State *L)
 {
        ClientObjectRef *ref = checkobject(L, 1);
        ClientActiveObject *cao = get_cao(ref);
+       if (! cao)
+               return 0;
        getClient(L)->getEnv().removeActiveObject(cao->getId());
 
        return 0;
@@ -209,6 +248,8 @@ int ClientObjectRef::l_set_nametag_images(lua_State *L)
 {
        ClientObjectRef *ref = checkobject(L, 1);
        GenericCAO *gcao = get_generic_cao(ref, L);
+       if (! gcao)
+               return 0;
        gcao->nametag_images.clear();
        if(lua_istable(L, 2)){
                lua_pushnil(L);
@@ -228,12 +269,10 @@ ClientObjectRef::ClientObjectRef(ClientActiveObject *object) : m_object(object)
 
 void ClientObjectRef::create(lua_State *L, ClientActiveObject *object)
 {
-       if (object) {
-               ClientObjectRef *o = new ClientObjectRef(object);
-               *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
-               luaL_getmetatable(L, className);
-               lua_setmetatable(L, -2);
-       }
+       ClientObjectRef *o = new ClientObjectRef(object);
+       *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+       luaL_getmetatable(L, className);
+       lua_setmetatable(L, -2);
 }
 
 void ClientObjectRef::create(lua_State *L, s16 id)
@@ -241,6 +280,12 @@ void ClientObjectRef::create(lua_State *L, s16 id)
        create(L, ((ClientEnvironment *)getEnv(L))->getActiveObject(id));
 }
 
+void ClientObjectRef::set_null(lua_State *L)
+{
+       ClientObjectRef *obj = checkobject(L, -1);
+       obj->m_object = nullptr;
+}
+
 int ClientObjectRef::gc_object(lua_State *L)
 {
        ClientObjectRef *obj = *(ClientObjectRef **)(lua_touserdata(L, 1));
index 60d10dcf6d0453dd0c4e40d7e84363fea937df54..c4c95cb4182b7a1ece2592048b84876e1dabb5bf 100644 (file)
@@ -35,6 +35,8 @@ class ClientObjectRef : public ModApiBase
        static void create(lua_State *L, ClientActiveObject *object);
        static void create(lua_State *L, s16 id);
 
+       static void set_null(lua_State *L);
+
        static ClientObjectRef *checkobject(lua_State *L, int narg);
 
 private:
index 74765701608e52606036618cb2d4b90e713a1d15..b8673379a91eca47d5f842725d3b955521bd5a4b 100644 (file)
@@ -483,7 +483,7 @@ int LuaLocalPlayer::l_get_object(lua_State *L)
        ClientEnvironment &env = getClient(L)->getEnv();
        ClientActiveObject *obj = env.getGenericCAO(player->getCAO()->getId());
 
-       ClientObjectRef::create(L, obj);
+       push_objectRef(L, obj->getId());
 
        return 1;
 }
index 3d9ba132b3f6e539f04057914de7ff9cbc3a1ab8..cd5ac0753f96fd5f28aba4f84b6ff598f68bcb53 100644 (file)
@@ -1170,7 +1170,7 @@ void ServerEnvironment::clearObjects(ClearObjectsMode mode)
                // Tell the object about removal
                obj->removingFromEnvironment();
                // Deregister in scripting api
-               m_script->removeObjectReference(obj);
+               m_script->removeObjectReference(dynamic_cast<ActiveObject *>(obj));
 
                // Delete active object
                if (obj->environmentDeletes())
@@ -1736,7 +1736,7 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
        }
 
        // Register reference in scripting api (must be done before post-init)
-       m_script->addObjectReference(object);
+       m_script->addObjectReference(dynamic_cast<ActiveObject *>(object));
        // Post-initialize object
        object->addedToEnvironment(dtime_s);
 
@@ -1826,7 +1826,7 @@ void ServerEnvironment::removeRemovedObjects()
                // Tell the object about removal
                obj->removingFromEnvironment();
                // Deregister in scripting api
-               m_script->removeObjectReference(obj);
+               m_script->removeObjectReference(dynamic_cast<ActiveObject *>(obj));
 
                // Delete
                if (obj->environmentDeletes())
@@ -2091,7 +2091,7 @@ void ServerEnvironment::deactivateFarObjects(bool _force_delete)
                // Tell the object about removal
                obj->removingFromEnvironment();
                // Deregister in scripting api
-               m_script->removeObjectReference(obj);
+               m_script->removeObjectReference(dynamic_cast<ActiveObject *>(obj));
 
                // Delete active object
                if (obj->environmentDeletes())