diff options
author | Foghrye4 <foghrye4@gmail.com> | 2016-10-08 16:51:25 +0400 |
---|---|---|
committer | Ner'zhul <nerzhul@users.noreply.github.com> | 2016-10-08 14:51:25 +0200 |
commit | ad163ee5c3f7d6ca31e0add052fb76466a9bfcc8 (patch) | |
tree | 6eebdb83bb210f4f57caa4a0f57189d95666d9c2 | |
parent | 9978d0796fa61eabb235d715a56ad6e5396d2e1e (diff) | |
download | minetest-ad163ee5c3f7d6ca31e0add052fb76466a9bfcc8.tar.gz minetest-ad163ee5c3f7d6ca31e0add052fb76466a9bfcc8.tar.bz2 minetest-ad163ee5c3f7d6ca31e0add052fb76466a9bfcc8.zip |
Prevent attached models from disappearing during parent reload (#4128)
-rw-r--r-- | src/content_cao.cpp | 41 | ||||
-rw-r--r-- | src/content_sao.cpp | 20 | ||||
-rw-r--r-- | src/content_sao.h | 8 | ||||
-rw-r--r-- | src/genericobject.cpp | 12 | ||||
-rw-r--r-- | src/genericobject.h | 5 | ||||
-rw-r--r-- | src/script/lua_api/l_object.cpp | 4 | ||||
-rw-r--r-- | src/serverobject.h | 4 |
7 files changed, 62 insertions, 32 deletions
diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 33dae6822..207a630d7 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -1567,8 +1567,7 @@ void GenericCAO::processMessage(const std::string &data) std::istringstream is(data, std::ios::binary); // command u8 cmd = readU8(is); - if(cmd == GENERIC_CMD_SET_PROPERTIES) - { + if (cmd == GENERIC_CMD_SET_PROPERTIES) { m_prop = gob_read_set_properties(is); m_selection_box = m_prop.collisionbox; @@ -1587,9 +1586,7 @@ void GenericCAO::processMessage(const std::string &data) m_prop.nametag = m_name; expireVisuals(); - } - else if(cmd == GENERIC_CMD_UPDATE_POSITION) - { + } else if (cmd == GENERIC_CMD_UPDATE_POSITION) { // Not sent by the server if this object is an attachment. // We might however get here if the server notices the object being detached before the client. m_position = readV3F1000(is); @@ -1619,12 +1616,10 @@ void GenericCAO::processMessage(const std::string &data) pos_translator.init(m_position); } updateNodePos(); - } - else if(cmd == GENERIC_CMD_SET_TEXTURE_MOD) { + } else if (cmd == GENERIC_CMD_SET_TEXTURE_MOD) { std::string mod = deSerializeString(is); updateTextures(mod); - } - else if(cmd == GENERIC_CMD_SET_SPRITE) { + } else if (cmd == GENERIC_CMD_SET_SPRITE) { v2s16 p = readV2S16(is); int num_frames = readU16(is); float framelength = readF1000(is); @@ -1636,8 +1631,7 @@ void GenericCAO::processMessage(const std::string &data) m_tx_select_horiz_by_yawpitch = select_horiz_by_yawpitch; updateTexturePos(); - } - else if(cmd == GENERIC_CMD_SET_PHYSICS_OVERRIDE) { + } else if (cmd == GENERIC_CMD_SET_PHYSICS_OVERRIDE) { float override_speed = readF1000(is); float override_jump = readF1000(is); float override_gravity = readF1000(is); @@ -1655,8 +1649,7 @@ void GenericCAO::processMessage(const std::string &data) player->physics_override_sneak = sneak; player->physics_override_sneak_glitch = sneak_glitch; } - } - else if(cmd == GENERIC_CMD_SET_ANIMATION) { + } else if (cmd == GENERIC_CMD_SET_ANIMATION) { // TODO: change frames send as v2s32 value v2f range = readV2F1000(is); if (!m_is_local_player) { @@ -1690,8 +1683,7 @@ void GenericCAO::processMessage(const std::string &data) updateAnimation(); } } - } - else if(cmd == GENERIC_CMD_SET_BONE_POSITION) { + } else if (cmd == GENERIC_CMD_SET_BONE_POSITION) { std::string bone = deSerializeString(is); v3f position = readV3F1000(is); v3f rotation = readV3F1000(is); @@ -1724,8 +1716,7 @@ void GenericCAO::processMessage(const std::string &data) } updateAttachments(); - } - else if(cmd == GENERIC_CMD_PUNCHED) { + } else if (cmd == GENERIC_CMD_PUNCHED) { /*s16 damage =*/ readS16(is); s16 result_hp = readS16(is); @@ -1753,8 +1744,7 @@ void GenericCAO::processMessage(const std::string &data) updateTextures("^[brighten"); } } - } - else if(cmd == GENERIC_CMD_UPDATE_ARMOR_GROUPS) { + } else if (cmd == GENERIC_CMD_UPDATE_ARMOR_GROUPS) { m_armor_groups.clear(); int armor_groups_size = readU16(is); for(int i=0; i<armor_groups_size; i++) @@ -1770,6 +1760,19 @@ void GenericCAO::processMessage(const std::string &data) if (m_nametag != NULL) { m_nametag->nametag_color = m_prop.nametag_color; } + } else if (cmd == GENERIC_CMD_SPAWN_INFANT) { + u16 child_id = readU16(is); + u8 type = readU8(is); + + if (GenericCAO *childobj = m_env->getGenericCAO(child_id)) { + childobj->initialize(deSerializeLongString(is)); + } else { + m_env->addActiveObject(child_id, type, deSerializeLongString(is)); + } + } else { + warningstream << FUNCTION_NAME + << ": unknown command or outdated client \"" + << cmd << std::endl; } } diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 2317cbdfe..1664f5993 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -380,7 +380,7 @@ std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version) writeF1000(os, m_yaw); writeS16(os, m_hp); - writeU8(os, 4 + m_bone_position.size()); // number of messages stuffed in here + writeU8(os, 4 + m_bone_position.size() + m_attachment_child_ids.size()); // number of messages stuffed in here os<<serializeLongString(getPropertyPacket()); // message 1 os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2 os<<serializeLongString(gob_cmd_update_animation( @@ -391,6 +391,12 @@ std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version) (*ii).second.X, (*ii).second.Y)); // m_bone_position.size } os<<serializeLongString(gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation)); // 4 + for (UNORDERED_SET<int>::const_iterator ii = m_attachment_child_ids.begin(); + (ii != m_attachment_child_ids.end()); ++ii) { + if (ServerActiveObject *obj = m_env->getActiveObject(*ii)) { + os << serializeLongString(gob_cmd_update_infant(*ii, obj->getSendType(), obj->getClientInitializationData(protocol_version))); + } + } } else { @@ -618,7 +624,7 @@ void LuaEntitySAO::removeAttachmentChild(int child_id) m_attachment_child_ids.erase(child_id); } -std::set<int> LuaEntitySAO::getAttachmentChildIds() +UNORDERED_SET<int> LuaEntitySAO::getAttachmentChildIds() { return m_attachment_child_ids; } @@ -860,7 +866,7 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version) writeF1000(os, m_player->getYaw()); writeS16(os, getHP()); - writeU8(os, 6 + m_bone_position.size()); // number of messages stuffed in here + writeU8(os, 6 + m_bone_position.size() + m_attachment_child_ids.size()); // number of messages stuffed in here os<<serializeLongString(getPropertyPacket()); // message 1 os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2 os<<serializeLongString(gob_cmd_update_animation( @@ -874,6 +880,12 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version) m_physics_override_jump, m_physics_override_gravity, m_physics_override_sneak, m_physics_override_sneak_glitch)); // 5 os << serializeLongString(gob_cmd_update_nametag_attributes(m_prop.nametag_color)); // 6 (GENERIC_CMD_UPDATE_NAMETAG_ATTRIBUTES) : Deprecated, for backwards compatibility only. + for (UNORDERED_SET<int>::const_iterator ii = m_attachment_child_ids.begin(); + ii != m_attachment_child_ids.end(); ++ii) { + if (ServerActiveObject *obj = m_env->getActiveObject(*ii)) { + os << serializeLongString(gob_cmd_update_infant(*ii, obj->getSendType(), obj->getClientInitializationData(protocol_version))); + } + } } else { @@ -1266,7 +1278,7 @@ void PlayerSAO::removeAttachmentChild(int child_id) m_attachment_child_ids.erase(child_id); } -std::set<int> PlayerSAO::getAttachmentChildIds() +UNORDERED_SET<int> PlayerSAO::getAttachmentChildIds() { return m_attachment_child_ids; } diff --git a/src/content_sao.h b/src/content_sao.h index c97db4922..341ebb5da 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -67,7 +67,7 @@ public: void getAttachment(int *parent_id, std::string *bone, v3f *position, v3f *rotation); void addAttachmentChild(int child_id); void removeAttachmentChild(int child_id); - std::set<int> getAttachmentChildIds(); + UNORDERED_SET<int> getAttachmentChildIds(); ObjectProperties* accessObjectProperties(); void notifyObjectPropertiesModified(); /* LuaEntitySAO-specific */ @@ -116,7 +116,7 @@ private: bool m_bone_position_sent; int m_attachment_parent_id; - std::set<int> m_attachment_child_ids; + UNORDERED_SET<int> m_attachment_child_ids; std::string m_attachment_bone; v3f m_attachment_position; v3f m_attachment_rotation; @@ -210,7 +210,7 @@ public: void getAttachment(int *parent_id, std::string *bone, v3f *position, v3f *rotation); void addAttachmentChild(int child_id); void removeAttachmentChild(int child_id); - std::set<int> getAttachmentChildIds(); + UNORDERED_SET<int> getAttachmentChildIds(); ObjectProperties* accessObjectProperties(); void notifyObjectPropertiesModified(); @@ -320,7 +320,7 @@ private: bool m_bone_position_sent; int m_attachment_parent_id; - std::set<int> m_attachment_child_ids; + UNORDERED_SET<int> m_attachment_child_ids; std::string m_attachment_bone; v3f m_attachment_position; v3f m_attachment_rotation; diff --git a/src/genericobject.cpp b/src/genericobject.cpp index 368cae1ff..c4660cf44 100644 --- a/src/genericobject.cpp +++ b/src/genericobject.cpp @@ -182,3 +182,15 @@ std::string gob_cmd_update_nametag_attributes(video::SColor color) writeARGB8(os, color); return os.str(); } + +std::string gob_cmd_update_infant(u16 id, u8 type, std::string client_initialization_data) +{ + std::ostringstream os(std::ios::binary); + // command + writeU8(os, GENERIC_CMD_SPAWN_INFANT); + // parameters + writeU16(os, id); + writeU8(os, type); + os<<serializeLongString(client_initialization_data); + return os.str(); +} diff --git a/src/genericobject.h b/src/genericobject.h index b92570831..48e71db75 100644 --- a/src/genericobject.h +++ b/src/genericobject.h @@ -35,7 +35,8 @@ enum GenericCMD { GENERIC_CMD_SET_BONE_POSITION, GENERIC_CMD_ATTACH_TO, GENERIC_CMD_SET_PHYSICS_OVERRIDE, - GENERIC_CMD_UPDATE_NAMETAG_ATTRIBUTES + GENERIC_CMD_UPDATE_NAMETAG_ATTRIBUTES, + GENERIC_CMD_SPAWN_INFANT }; #include "object_properties.h" @@ -77,5 +78,7 @@ std::string gob_cmd_update_attachment(int parent_id, std::string bone, v3f posit std::string gob_cmd_update_nametag_attributes(video::SColor color); +std::string gob_cmd_update_infant(u16 id, u8 type, std::string client_initialization_data); + #endif diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 4e1a1c159..34e175ad0 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -137,8 +137,8 @@ int ObjectRef::l_remove(lua_State *L) if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER) return 0; - std::set<int> child_ids = co->getAttachmentChildIds(); - std::set<int>::iterator it; + UNORDERED_SET<int> child_ids = co->getAttachmentChildIds(); + UNORDERED_SET<int>::iterator it; for (it = child_ids.begin(); it != child_ids.end(); ++it) { ServerActiveObject *child = env->getActiveObject(*it); child->setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0)); diff --git a/src/serverobject.h b/src/serverobject.h index 597eb63a8..9f8d5403c 100644 --- a/src/serverobject.h +++ b/src/serverobject.h @@ -167,8 +167,8 @@ public: {} virtual void removeAttachmentChild(int child_id) {} - virtual std::set<int> getAttachmentChildIds() - { return std::set<int>(); } + virtual UNORDERED_SET<int> getAttachmentChildIds() + { return UNORDERED_SET<int>(); } virtual ObjectProperties* accessObjectProperties() { return NULL; } virtual void notifyObjectPropertiesModified() |