ObjectRef:set_armor_groups() and ObjectRef:set_properties() - works on players too!
authorPerttu Ahola <celeron55@gmail.com>
Fri, 30 Mar 2012 10:26:40 +0000 (13:26 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Fri, 30 Mar 2012 10:34:21 +0000 (13:34 +0300)
doc/lua_api.txt
games/minimal/mods/experimental/init.lua
src/content_sao.cpp
src/content_sao.h
src/scriptapi.cpp
src/serverobject.h

index 740f73b07a72a92635e1410799acfa657ca155d9..1199f8108ece4df96dd7b0c0739f0e93da6127dc 100644 (file)
@@ -614,6 +614,7 @@ methods:
 - get_wielded_item() -> ItemStack
 - set_wielded_item(item): replaces the wielded item, returns true if successful
 - set_armor_groups({group1=rating, group2=rating, ...})
+- set_properties(object property table)
 LuaEntitySAO-only: (no-op for other objects)
 - setvelocity({x=num, y=num, z=num})
 - getvelocity() -> {x=num, y=num, z=num}
@@ -716,20 +717,30 @@ Registered entities
 Definition tables
 ------------------
 
-Entity definition (register_entity)
+Object Properties
 {
     physical = true,
     collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
-    visual = "cube"/"sprite",
+    visual = "cube"/"sprite"/"upright_sprite",
     visual_size = {x=1, y=1},
-    textures = {texture,texture,texture,texture,texture,texture},
+    textures = {}, -- number of required textures depends on visual
     spritediv = {x=1, y=1},
     initial_sprite_basepos = {x=0, y=0},
+    is_visible = true,
+    makes_footstep_sound = false,
+}
+
+Entity definition (register_entity)
+{
+    Everything from object properties,
+    -- entity specific --
     on_activate = function(self, staticdata),
     on_step = function(self, dtime),
     on_punch = function(self, hitter),
     on_rightclick = function(self, clicker),
     get_staticdata = function(self),
+    ^ Called sometimes; the string returned is passed to on_activate when
+      the entity is re-activated from static state
     # Also you can define arbitrary member variables here
     myvariable = whatever,
 }
index 5dab41354b6fddabf533c75e3dfd9f0561ed2482..f1b8ec44ae7e620a297bc18fd119181747cb7ebc 100644 (file)
@@ -6,6 +6,22 @@
 
 experimental = {}
 
+experimental.player_visual_index = 0
+function switch_player_visual()
+       for _, obj in pairs(minetest.env:get_objects_inside_radius({x=0,y=0,z=0}, 1000000)) do
+               if obj:get_player_name() then
+                       if experimental.player_visual_index == 0 then
+                               obj:set_properties({visual="upright_sprite"})
+                       else
+                               obj:set_properties({visual="cube"})
+                       end
+               end
+       end
+       experimental.player_visual_index = (experimental.player_visual_index + 1) % 2
+       minetest.after(1.0, switch_player_visual)
+end
+minetest.after(1.0, switch_player_visual)
+
 --[[
 stepsound = -1
 function test_sound()
index 054e4944fda1800f1dc7e5106d921ef0fcc71da9..c6419c1dd5bb22ff397a94ceee084741eccbc023 100644 (file)
@@ -643,6 +643,16 @@ void LuaEntitySAO::setArmorGroups(const ItemGroupList &armor_groups)
        m_armor_groups_sent = false;
 }
 
+ObjectProperties* LuaEntitySAO::accessObjectProperties()
+{
+       return &m_prop;
+}
+
+void LuaEntitySAO::notifyObjectPropertiesModified()
+{
+       m_properties_sent = false;
+}
+
 void LuaEntitySAO::setVelocity(v3f velocity)
 {
        m_velocity = velocity;
@@ -1038,6 +1048,16 @@ void PlayerSAO::setArmorGroups(const ItemGroupList &armor_groups)
        m_armor_groups_sent = false;
 }
 
+ObjectProperties* PlayerSAO::accessObjectProperties()
+{
+       return &m_prop;
+}
+
+void PlayerSAO::notifyObjectPropertiesModified()
+{
+       m_properties_sent = false;
+}
+
 Inventory* PlayerSAO::getInventory()
 {
        return m_inventory;
index f0788cbd52f6375c933d33123b22fb8a99763d66..f3b9f8b2f353af6641fddd20fa9dfc998ebfb3c9 100644 (file)
@@ -61,6 +61,8 @@ public:
        void setHP(s16 hp);
        s16 getHP() const;
        void setArmorGroups(const ItemGroupList &armor_groups);
+       ObjectProperties* accessObjectProperties();
+       void notifyObjectPropertiesModified();
        /* LuaEntitySAO-specific */
        void setVelocity(v3f velocity);
        v3f getVelocity();
@@ -137,7 +139,10 @@ public:
        void rightClick(ServerActiveObject *clicker);
        s16 getHP() const;
        void setHP(s16 hp);
+       
        void setArmorGroups(const ItemGroupList &armor_groups);
+       ObjectProperties* accessObjectProperties();
+       void notifyObjectPropertiesModified();
 
        /*
                Inventory interface
index 1ef6d0e72de082c75d7552cc4f01d2804764e62d..65894e28444b9193e07eeadcfd0ecca4c13c1838 100644 (file)
@@ -835,6 +835,67 @@ static void read_soundspec(lua_State *L, int index, SimpleSoundSpec &spec)
        }
 }
 
+/*
+       ObjectProperties
+*/
+
+static void read_object_properties(lua_State *L, int index,
+               ObjectProperties *prop)
+{
+       if(index < 0)
+               index = lua_gettop(L) + 1 + index;
+       if(!lua_istable(L, index))
+               return;
+
+       prop->hp_max = getintfield_default(L, -1, "hp_max", 10);
+
+       getboolfield(L, -1, "physical", prop->physical);
+
+       getfloatfield(L, -1, "weight", prop->weight);
+
+       lua_getfield(L, -1, "collisionbox");
+       if(lua_istable(L, -1))
+               prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
+       lua_pop(L, 1);
+
+       getstringfield(L, -1, "visual", prop->visual);
+       
+       lua_getfield(L, -1, "visual_size");
+       if(lua_istable(L, -1))
+               prop->visual_size = read_v2f(L, -1);
+       lua_pop(L, 1);
+
+       lua_getfield(L, -1, "textures");
+       if(lua_istable(L, -1)){
+               prop->textures.clear();
+               int table = lua_gettop(L);
+               lua_pushnil(L);
+               while(lua_next(L, table) != 0){
+                       // key at index -2 and value at index -1
+                       if(lua_isstring(L, -1))
+                               prop->textures.push_back(lua_tostring(L, -1));
+                       else
+                               prop->textures.push_back("");
+                       // removes value, keeps key for next iteration
+                       lua_pop(L, 1);
+               }
+       }
+       lua_pop(L, 1);
+       
+       lua_getfield(L, -1, "spritediv");
+       if(lua_istable(L, -1))
+               prop->spritediv = read_v2s16(L, -1);
+       lua_pop(L, 1);
+
+       lua_getfield(L, -1, "initial_sprite_basepos");
+       if(lua_istable(L, -1))
+               prop->initial_sprite_basepos = read_v2s16(L, -1);
+       lua_pop(L, 1);
+       
+       getboolfield(L, -1, "is_visible", prop->is_visible);
+       getboolfield(L, -1, "makes_footstep_sound", prop->makes_footstep_sound);
+}
+
 /*
        ItemDefinition
 */
@@ -2471,6 +2532,33 @@ private:
                return 1;
        }
 
+       // set_armor_groups(self, groups)
+       static int l_set_armor_groups(lua_State *L)
+       {
+               ObjectRef *ref = checkobject(L, 1);
+               ServerActiveObject *co = getobject(ref);
+               if(co == NULL) return 0;
+               // Do it
+               ItemGroupList groups;
+               read_groups(L, 2, groups);
+               co->setArmorGroups(groups);
+               return 0;
+       }
+
+       // set_properties(self, properties)
+       static int l_set_properties(lua_State *L)
+       {
+               ObjectRef *ref = checkobject(L, 1);
+               ServerActiveObject *co = getobject(ref);
+               if(co == NULL) return 0;
+               ObjectProperties *prop = co->accessObjectProperties();
+               if(!prop)
+                       return 0;
+               read_object_properties(L, 2, prop);
+               co->notifyObjectPropertiesModified();
+               return 0;
+       }
+
        /* LuaEntitySAO-only */
 
        // setvelocity(self, {x=num, y=num, z=num})
@@ -2479,7 +2567,6 @@ private:
                ObjectRef *ref = checkobject(L, 1);
                LuaEntitySAO *co = getluaobject(ref);
                if(co == NULL) return 0;
-               // pos
                v3f pos = checkFloatPos(L, 2);
                // Do it
                co->setVelocity(pos);
@@ -2529,7 +2616,6 @@ private:
                ObjectRef *ref = checkobject(L, 1);
                LuaEntitySAO *co = getluaobject(ref);
                if(co == NULL) return 0;
-               // pos
                float yaw = luaL_checknumber(L, 2) * core::RADTODEG;
                // Do it
                co->setYaw(yaw);
@@ -2584,19 +2670,6 @@ private:
                return 0;
        }
 
-       // set_armor_groups(self, groups)
-       static int l_set_armor_groups(lua_State *L)
-       {
-               ObjectRef *ref = checkobject(L, 1);
-               LuaEntitySAO *co = getluaobject(ref);
-               if(co == NULL) return 0;
-               // Do it
-               ItemGroupList groups;
-               read_groups(L, 2, groups);
-               co->setArmorGroups(groups);
-               return 0;
-       }
-
        // DEPRECATED
        // get_entity_name(self)
        static int l_get_entity_name(lua_State *L)
@@ -2750,6 +2823,8 @@ const luaL_reg ObjectRef::methods[] = {
        method(ObjectRef, get_wield_index),
        method(ObjectRef, get_wielded_item),
        method(ObjectRef, set_wielded_item),
+       method(ObjectRef, set_armor_groups),
+       method(ObjectRef, set_properties),
        // LuaEntitySAO-only
        method(ObjectRef, setvelocity),
        method(ObjectRef, getvelocity),
@@ -2759,7 +2834,6 @@ const luaL_reg ObjectRef::methods[] = {
        method(ObjectRef, getyaw),
        method(ObjectRef, settexturemod),
        method(ObjectRef, setsprite),
-       method(ObjectRef, set_armor_groups),
        method(ObjectRef, get_entity_name),
        method(ObjectRef, get_luaentity),
        // Player-only
@@ -4689,52 +4763,11 @@ void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
        luaentity_get(L, id);
        //int object = lua_gettop(L);
 
-       /* Read stuff */
+       // Set default values that differ from ObjectProperties defaults
+       prop->hp_max = 10;
        
-       prop->hp_max = getintfield_default(L, -1, "hp_max", 10);
-
-       getboolfield(L, -1, "physical", prop->physical);
-
-       getfloatfield(L, -1, "weight", prop->weight);
-
-       lua_getfield(L, -1, "collisionbox");
-       if(lua_istable(L, -1))
-               prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
-       lua_pop(L, 1);
-
-       getstringfield(L, -1, "visual", prop->visual);
-       
-       lua_getfield(L, -1, "visual_size");
-       if(lua_istable(L, -1))
-               prop->visual_size = read_v2f(L, -1);
-       lua_pop(L, 1);
-
-       lua_getfield(L, -1, "textures");
-       if(lua_istable(L, -1)){
-               prop->textures.clear();
-               int table = lua_gettop(L);
-               lua_pushnil(L);
-               while(lua_next(L, table) != 0){
-                       // key at index -2 and value at index -1
-                       if(lua_isstring(L, -1))
-                               prop->textures.push_back(lua_tostring(L, -1));
-                       else
-                               prop->textures.push_back("");
-                       // removes value, keeps key for next iteration
-                       lua_pop(L, 1);
-               }
-       }
-       lua_pop(L, 1);
-       
-       lua_getfield(L, -1, "spritediv");
-       if(lua_istable(L, -1))
-               prop->spritediv = read_v2s16(L, -1);
-       lua_pop(L, 1);
-
-       lua_getfield(L, -1, "initial_sprite_basepos");
-       if(lua_istable(L, -1))
-               prop->initial_sprite_basepos = read_v2s16(L, -1);
-       lua_pop(L, 1);
+       // Read stuff
+       read_object_properties(L, -1, prop);
 }
 
 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
index 110f67f5bd0ddbe1abfad2af761a6acab04ad0d1..8029cf584e49036d3b5924bc5254650e49eeb79b 100644 (file)
@@ -46,6 +46,7 @@ class ServerEnvironment;
 struct ItemStack;
 class Player;
 struct ToolCapabilities;
+struct ObjectProperties;
 
 class ServerActiveObject : public ActiveObject
 {
@@ -152,6 +153,10 @@ public:
 
        virtual void setArmorGroups(const ItemGroupList &armor_groups)
        {}
+       virtual ObjectProperties* accessObjectProperties()
+       { return NULL; }
+       virtual void notifyObjectPropertiesModified()
+       {}
 
        // Inventory and wielded item
        virtual Inventory* getInventory()