diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 2b2b6c6f1..5515669d8 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1116,6 +1116,7 @@ LuaEntitySAO-only: (no-op for other objects) - select_horiz_by_yawpitch=false) ^ Select sprite from spritesheet with optional animation and DM-style texture selection based on yaw relative to camera +- setanimations(frame_start, frame_end, frame_speed, frame_blend) - get_entity_name() (DEPRECATED: Will be removed in a future version) - get_luaentity() Player-only: (no-op for other objects) @@ -1230,9 +1231,6 @@ Object Properties visual = "cube"/"sprite"/"upright_sprite"/"mesh", visual_size = {x=1, y=1}, mesh = "model", - animation_frames = {1, 1}, - animation_speed = 15, - animation_blend = 0, animation_bone_position = {"", {x=0, y=0, z=0}}, -- bone name followed by position vector animation_bone_rotation = {"", {x=0, y=0, z=0}}, -- bone name followed by rotation vector textures = {}, -- number of required textures depends on visual diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 4df238b24..1cd3926ca 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -924,7 +924,6 @@ public: m_visuals_expired = false; removeFromScene(); addToScene(m_smgr, m_gamedef->tsrc(), m_irr); - updateAnimations(); } if(m_prop.physical){ @@ -1137,22 +1136,34 @@ public: } } - void updateAnimations() + void updateAnimations(int frame_start, int frame_end, float frame_speed, float frame_blend) { if(!m_animated_meshnode) return; - m_animated_meshnode->setFrameLoop(m_prop.animation_frames.X, m_prop.animation_frames.Y); - m_animated_meshnode->setAnimationSpeed(m_prop.animation_speed); - m_animated_meshnode->setTransitionTime(m_prop.animation_blend); + m_animated_meshnode->setFrameLoop(frame_start, frame_end); + m_animated_meshnode->setAnimationSpeed(frame_speed); + m_animated_meshnode->setTransitionTime(frame_blend); - for(std::map::const_iterator ii = m_prop.animation_bone_position.begin(); ii != m_prop.animation_bone_position.end(); ++ii){ - if((*ii).second.X || (*ii).second.Y || (*ii).second.Z) { } - // Bone positioning code will go here + if(m_prop.animation_bone_position.size() > 0) + { + for(std::map::const_iterator ii = m_prop.animation_bone_position.begin(); ii != m_prop.animation_bone_position.end(); ++ii){ + m_animated_meshnode->setJointMode(irr::scene::EJUOR_CONTROL); // To write positions to the mesh on render + std::string bone_name = (*ii).first; + v3f bone_pos = (*ii).second; + irr::scene::IBoneSceneNode* bone = m_animated_meshnode->getJointNode(bone_name.c_str()); + bone->setPosition(bone_pos); + } } - for(std::map::const_iterator ii = m_prop.animation_bone_rotation.begin(); ii != m_prop.animation_bone_rotation.end(); ++ii){ - if((*ii).second.X || (*ii).second.Y || (*ii).second.Z) { } - // Bone rotation code will go here + if(m_prop.animation_bone_rotation.size() > 0) + { + for(std::map::const_iterator ii = m_prop.animation_bone_rotation.begin(); ii != m_prop.animation_bone_rotation.end(); ++ii){ + m_animated_meshnode->setJointMode(irr::scene::EJUOR_CONTROL); // To write positions to the mesh on render + std::string bone_name = (*ii).first; + v3f bone_rot = (*ii).second; + irr::scene::IBoneSceneNode* bone = m_animated_meshnode->getJointNode(bone_name.c_str()); + bone->setRotation(bone_rot); + } } } @@ -1223,6 +1234,15 @@ public: updateTexturePos(); } + else if(cmd == GENERIC_CMD_SET_ANIMATIONS) + { + int frame_start = readU16(is); + int frame_end = readU16(is); + float frame_speed = readF1000(is); + float frame_blend = readF1000(is); + + updateAnimations(frame_start, frame_end, frame_speed, frame_blend); + } else if(cmd == GENERIC_CMD_PUNCHED) { /*s16 damage =*/ readS16(is); diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 6c2abf8f6..9aeb88e71 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -706,6 +706,14 @@ void LuaEntitySAO::setSprite(v2s16 p, int num_frames, float framelength, m_messages_out.push_back(aom); } +void LuaEntitySAO::setAnimations(int frame_start, int frame_end, float frame_speed, float frame_blend) +{ + std::string str = gob_cmd_set_animations(frame_start, frame_end, frame_speed, frame_blend); + // create message and add to list + ActiveObjectMessage aom(getId(), true, str); + m_messages_out.push_back(aom); +} + std::string LuaEntitySAO::getName() { return m_init_name; diff --git a/src/content_sao.h b/src/content_sao.h index 05c77e2cb..1cbf492b1 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -73,6 +73,7 @@ public: void setTextureMod(const std::string &mod); void setSprite(v2s16 p, int num_frames, float framelength, bool select_horiz_by_yawpitch); + void setAnimations(int frame_start, int frame_end, float frame_speed, float frame_blend); std::string getName(); private: std::string getPropertyPacket(); diff --git a/src/genericobject.cpp b/src/genericobject.cpp index 4ab031b5d..0914a13c5 100644 --- a/src/genericobject.cpp +++ b/src/genericobject.cpp @@ -92,6 +92,19 @@ std::string gob_cmd_set_sprite( return os.str(); } +std::string gob_cmd_set_animations(int frame_start, int frame_end, float frame_speed, float frame_blend) +{ + std::ostringstream os(std::ios::binary); + // command + writeU8(os, GENERIC_CMD_SET_ANIMATIONS); + // parameters + writeU16(os, frame_start); + writeU16(os, frame_end); + writeF1000(os, frame_speed); + writeF1000(os, frame_blend); + return os.str(); +} + std::string gob_cmd_punched(s16 damage, s16 result_hp) { std::ostringstream os(std::ios::binary); diff --git a/src/genericobject.h b/src/genericobject.h index 81563c19b..c57cce8ba 100644 --- a/src/genericobject.h +++ b/src/genericobject.h @@ -28,8 +28,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #define GENERIC_CMD_UPDATE_POSITION 1 #define GENERIC_CMD_SET_TEXTURE_MOD 2 #define GENERIC_CMD_SET_SPRITE 3 -#define GENERIC_CMD_PUNCHED 4 -#define GENERIC_CMD_UPDATE_ARMOR_GROUPS 5 +#define GENERIC_CMD_SET_ANIMATIONS 4 +#define GENERIC_CMD_PUNCHED 5 +#define GENERIC_CMD_UPDATE_ARMOR_GROUPS 6 #include "object_properties.h" std::string gob_cmd_set_properties(const ObjectProperties &prop); @@ -54,6 +55,8 @@ std::string gob_cmd_set_sprite( bool select_horiz_by_yawpitch ); +std::string gob_cmd_set_animations(int frame_start, int frame_end, float frame_speed, float frame_blend); + std::string gob_cmd_punched(s16 damage, s16 result_hp); #include "itemgroup.h" diff --git a/src/object_properties.cpp b/src/object_properties.cpp index eb26db8d3..6b98356ac 100644 --- a/src/object_properties.cpp +++ b/src/object_properties.cpp @@ -32,9 +32,6 @@ ObjectProperties::ObjectProperties(): collisionbox(-0.5,-0.5,-0.5, 0.5,0.5,0.5), visual("sprite"), mesh(""), - animation_frames(1,1), - animation_speed(15), - animation_blend(0), visual_size(1,1), spritediv(1,1), initial_sprite_basepos(0,0), @@ -42,8 +39,8 @@ ObjectProperties::ObjectProperties(): makes_footstep_sound(false), automatic_rotate(0) { - animation_bone_position[""] = v3f(0,0,0); - animation_bone_rotation[""] = v3f(0,0,0); + // Nothing to do for animation_bone_position + // Nothing to do for animation_bone_rotation textures.push_back("unknown_object.png"); } @@ -56,9 +53,6 @@ std::string ObjectProperties::dump() os<<", collisionbox="<::const_iterator ii = animation_bone_position.begin(); ii != animation_bone_position.end(); ++ii){ @@ -140,10 +130,6 @@ void ObjectProperties::deSerialize(std::istream &is) collisionbox.MaxEdge = readV3F1000(is); visual = deSerializeString(is); mesh = deSerializeString(is); - animation_frames.X = readF1000(is); - animation_frames.Y = readF1000(is); - animation_speed = readF1000(is); - animation_blend = readF1000(is); u32 animation_bone_position_count = readU16(is); for(u32 i=0; i collisionbox; std::string visual; std::string mesh; - core::vector2d animation_frames; - float animation_speed; - float animation_blend; std::map animation_bone_position; std::map animation_bone_rotation; v2f visual_size; diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index 74de50ef8..32fb6e9bd 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -944,21 +944,6 @@ static void read_object_properties(lua_State *L, int index, prop->visual_size = read_v2f(L, -1); lua_pop(L, 1); - lua_getfield(L, -1, "animation_frames"); - if(lua_istable(L, -1)) - { - lua_rawgeti (L, -1, 1); - lua_rawgeti (L, -2, 2); - prop->animation_frames.X = lua_tonumber(L, -2); - prop->animation_frames.Y = lua_tonumber(L, -1); - lua_pop(L, 2); - } - lua_pop(L, 1); - - getfloatfield(L, -1, "animation_speed", prop->animation_speed); - - getfloatfield(L, -1, "animation_blend", prop->animation_blend); - lua_getfield(L, -1, "animation_bone_position"); if(lua_istable(L, -1)) { @@ -2863,6 +2848,30 @@ private: return 0; } + // setanimations(self, mod) + static int l_setanimations(lua_State *L) + { + ObjectRef *ref = checkobject(L, 1); + LuaEntitySAO *co = getluaobject(ref); + if(co == NULL) return 0; + // Do it + v2s16 p(0,0); + int frame_start = 0; + if(!lua_isnil(L, 2)) + frame_start = lua_tonumber(L, 2); + int frame_end = 0; + if(!lua_isnil(L, 3)) + frame_end = lua_tonumber(L, 3); + float frame_speed = 15; + if(!lua_isnil(L, 4)) + frame_speed = lua_tonumber(L, 4); + float frame_blend = 0; + if(!lua_isnil(L, 5)) + frame_blend = lua_tonumber(L, 5); + co->setAnimations(frame_start, frame_end, frame_speed, frame_blend); + return 0; + } + // DEPRECATED // get_entity_name(self) static int l_get_entity_name(lua_State *L) @@ -3062,6 +3071,7 @@ const luaL_reg ObjectRef::methods[] = { method(ObjectRef, getyaw), method(ObjectRef, settexturemod), method(ObjectRef, setsprite), + method(ObjectRef, setanimations), method(ObjectRef, get_entity_name), method(ObjectRef, get_luaentity), // Player-only