From 3241ad3ae8da687262db32776a1da2ef7403b3e9 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Fri, 30 Mar 2012 13:26:40 +0300 Subject: [PATCH] ObjectRef:set_armor_groups() and ObjectRef:set_properties() - works on players too! --- doc/lua_api.txt | 17 ++- games/minimal/mods/experimental/init.lua | 16 +++ src/content_sao.cpp | 20 +++ src/content_sao.h | 5 + src/scriptapi.cpp | 155 ++++++++++++++--------- src/serverobject.h | 5 + 6 files changed, 154 insertions(+), 64 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 740f73b07..1199f8108 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -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, } diff --git a/games/minimal/mods/experimental/init.lua b/games/minimal/mods/experimental/init.lua index 5dab41354..f1b8ec44a 100644 --- a/games/minimal/mods/experimental/init.lua +++ b/games/minimal/mods/experimental/init.lua @@ -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() diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 054e4944f..c6419c1dd 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -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; diff --git a/src/content_sao.h b/src/content_sao.h index f0788cbd5..f3b9f8b2f 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -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 diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index 1ef6d0e72..65894e284 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -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) diff --git a/src/serverobject.h b/src/serverobject.h index 110f67f5b..8029cf584 100644 --- a/src/serverobject.h +++ b/src/serverobject.h @@ -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()