summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/content_cao.cpp111
-rw-r--r--src/content_cao.h2
-rw-r--r--src/environment.cpp10
-rw-r--r--src/environment.h2
4 files changed, 48 insertions, 77 deletions
diff --git a/src/content_cao.cpp b/src/content_cao.cpp
index b7923ff80..bd90e96a5 100644
--- a/src/content_cao.cpp
+++ b/src/content_cao.cpp
@@ -723,52 +723,29 @@ void GenericCAO::setAttachments()
ClientActiveObject* GenericCAO::getParent()
{
ClientActiveObject *obj = NULL;
- for(std::vector<core::vector2d<int> >::const_iterator cii = m_env->attachment_list.begin(); cii != m_env->attachment_list.end(); cii++)
- {
- if(cii->X == getId()) // This ID is our child
- {
- if(cii->Y > 0) // A parent ID exists for our child
- {
- if(cii->X != cii->Y) // The parent and child ID are not the same
- {
- obj = m_env->getActiveObject(cii->Y);
- }
- }
- break;
- }
+
+ u16 attached_id = m_env->m_attachements[getId()];
+
+ if ((attached_id != 0) &&
+ (attached_id != getId())) {
+ obj = m_env->getActiveObject(attached_id);
}
- if(obj)
- return obj;
- return NULL;
+ return obj;
}
void GenericCAO::removeFromScene(bool permanent)
{
if(permanent) // Should be true when removing the object permanently and false when refreshing (eg: updating visuals)
{
- // Detach this object's children
- for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin();
- ii != m_env->attachment_list.end(); ii++)
- {
- if(ii->Y == getId()) // Is a child of our object
- {
- ii->Y = 0;
- // Get the object of the child
- ClientActiveObject *obj = m_env->getActiveObject(ii->X);
- if(obj)
- obj->setAttachments();
- }
- }
- // Delete this object from the attachments list
- for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin();
- ii != m_env->attachment_list.end(); ii++)
+ for(std::vector<u16>::iterator ci = m_children.begin();
+ ci != m_children.end(); ci++)
{
- if(ii->X == getId()) // Is our object
- {
- m_env->attachment_list.erase(ii);
- break;
+ if (m_env->m_attachements[*ci] == getId()) {
+ m_env->m_attachements[*ci] = 0;
}
}
+
+ m_env->m_attachements[getId()] = 0;
}
if(m_meshnode)
@@ -1098,45 +1075,43 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
// Attachments, part 1: All attached objects must be unparented first,
// or Irrlicht causes a segmentation fault
- for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin();
- ii != m_env->attachment_list.end(); ii++)
+ for(std::vector<u16>::iterator ci = m_children.begin();
+ ci != m_children.end();)
{
- if(ii->Y == getId()) // This is a child of our parent
+ if (m_env->m_attachements[*ci] != getId()) {
+ ci = m_children.erase(ci);
+ continue;
+ }
+ ClientActiveObject *obj = m_env->getActiveObject(*ci);
+ if(obj)
{
- // Get the object of the child
- ClientActiveObject *obj = m_env->getActiveObject(ii->X);
- if(obj)
- {
- scene::IMeshSceneNode *m_child_meshnode
- = obj->getMeshSceneNode();
- scene::IAnimatedMeshSceneNode *m_child_animated_meshnode
- = obj->getAnimatedMeshSceneNode();
- scene::IBillboardSceneNode *m_child_spritenode
- = obj->getSpriteSceneNode();
- if(m_child_meshnode)
- m_child_meshnode->setParent(m_smgr->getRootSceneNode());
- if(m_child_animated_meshnode)
- m_child_animated_meshnode->setParent(m_smgr->getRootSceneNode());
- if(m_child_spritenode)
- m_child_spritenode->setParent(m_smgr->getRootSceneNode());
- }
+ scene::IMeshSceneNode *m_child_meshnode
+ = obj->getMeshSceneNode();
+ scene::IAnimatedMeshSceneNode *m_child_animated_meshnode
+ = obj->getAnimatedMeshSceneNode();
+ scene::IBillboardSceneNode *m_child_spritenode
+ = obj->getSpriteSceneNode();
+ if(m_child_meshnode)
+ m_child_meshnode->setParent(m_smgr->getRootSceneNode());
+ if(m_child_animated_meshnode)
+ m_child_animated_meshnode->setParent(m_smgr->getRootSceneNode());
+ if(m_child_spritenode)
+ m_child_spritenode->setParent(m_smgr->getRootSceneNode());
}
+ ++ci;
}
removeFromScene(false);
addToScene(m_smgr, m_gamedef->tsrc(), m_irr);
// Attachments, part 2: Now that the parent has been refreshed, put its attachments back
- for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin();
- ii != m_env->attachment_list.end(); ii++)
+ for(std::vector<u16>::iterator ci = m_children.begin();
+ ci != m_children.end(); ci++)
{
- if(ii->Y == getId()) // This is a child of our parent
- {
// Get the object of the child
- ClientActiveObject *obj = m_env->getActiveObject(ii->X);
+ ClientActiveObject *obj = m_env->getActiveObject(*ci);
if(obj)
obj->setAttachments();
- }
}
}
@@ -1803,16 +1778,8 @@ void GenericCAO::processMessage(const std::string &data)
updateBonePosition();
}
else if(cmd == GENERIC_CMD_SET_ATTACHMENT) {
- // If an entry already exists for this object, delete it first to avoid duplicates
- for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++)
- {
- if(ii->X == getId()) // This is the ID of our object
- {
- m_env->attachment_list.erase(ii);
- break;
- }
- }
- m_env->attachment_list.push_back(core::vector2d<int>(getId(), readS16(is)));
+ m_env->m_attachements[getId()] = readS16(is);
+ m_children.push_back(m_env->m_attachements[getId()]);
m_attachment_bone = deSerializeString(is);
m_attachment_position = readV3F1000(is);
m_attachment_rotation = readV3F1000(is);
diff --git a/src/content_cao.h b/src/content_cao.h
index 1e55babf2..bf27ed79a 100644
--- a/src/content_cao.h
+++ b/src/content_cao.h
@@ -102,6 +102,8 @@ private:
u8 m_last_light;
bool m_is_visible;
+ std::vector<u16> m_children;
+
public:
GenericCAO(IGameDef *gamedef, ClientEnvironment *env);
diff --git a/src/environment.cpp b/src/environment.cpp
index fa7ce2ae5..8103998c3 100644
--- a/src/environment.cpp
+++ b/src/environment.cpp
@@ -1379,7 +1379,7 @@ bool ServerEnvironment::addActiveObjectAsStatic(ServerActiveObject *obj)
{
assert(obj);
- v3f objectpos = obj->getBasePosition();
+ v3f objectpos = obj->getBasePosition();
// The block in which the object resides in
v3s16 blockpos_o = getNodeBlockPos(floatToInt(objectpos, BS));
@@ -1591,7 +1591,7 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
object->m_static_block = blockpos;
if(set_changed)
- block->raiseModified(MOD_STATE_WRITE_NEEDED,
+ block->raiseModified(MOD_STATE_WRITE_NEEDED,
"addActiveObjectRaw");
} else {
v3s16 p = floatToInt(objectpos, BS);
@@ -1828,7 +1828,7 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
If force_delete is set, active object is deleted nevertheless. It
shall only be set so in the destructor of the environment.
- If block wasn't generated (not in memory or on disk),
+ If block wasn't generated (not in memory or on disk),
*/
void ServerEnvironment::deactivateFarObjects(bool force_delete)
{
@@ -1849,7 +1849,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
continue;
u16 id = i->first;
- v3f objectpos = obj->getBasePosition();
+ v3f objectpos = obj->getBasePosition();
// The block in which the object resides in
v3s16 blockpos_o = getNodeBlockPos(floatToInt(objectpos, BS));
@@ -2078,6 +2078,8 @@ ClientEnvironment::ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr,
m_gamedef(gamedef),
m_irr(irr)
{
+ char zero = 0;
+ memset(m_attachements, zero, sizeof(m_attachements));
}
ClientEnvironment::~ClientEnvironment()
diff --git a/src/environment.h b/src/environment.h
index 5062b9c37..cecc9133a 100644
--- a/src/environment.h
+++ b/src/environment.h
@@ -492,7 +492,7 @@ public:
// Get event from queue. CEE_NONE is returned if queue is empty.
ClientEnvEvent getClientEvent();
- std::vector<core::vector2d<int> > attachment_list; // X is child ID, Y is parent ID
+ u16 m_attachements[USHRT_MAX];
std::list<std::string> getPlayerNames()
{ return m_player_names; }