[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15610] trunk/blender/source/gameengine/ Ketsji/KX_Scene.cpp: BGE bug fix (good for 2.47): fix logic reconnection after replication.

Benoit Bolsee benoit.bolsee at online.be
Thu Jul 17 14:29:43 CEST 2008


Revision: 15610
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15610
Author:   ben2610
Date:     2008-07-17 14:29:42 +0200 (Thu, 17 Jul 2008)

Log Message:
-----------
BGE bug fix (good for 2.47): fix logic reconnection after replication. The old method was matching the bricks by name assuming they are unique but it is not always the case, especially with the new dupligroup feature. The new method matches the bricks by objects and position.

Modified Paths:
--------------
    trunk/blender/source/gameengine/Ketsji/KX_Scene.cpp

Modified: trunk/blender/source/gameengine/Ketsji/KX_Scene.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_Scene.cpp	2008-07-17 06:35:30 UTC (rev 15609)
+++ trunk/blender/source/gameengine/Ketsji/KX_Scene.cpp	2008-07-17 12:29:42 UTC (rev 15610)
@@ -508,6 +508,11 @@
 // hierarchy that's because first ALL bricks must exist in the new
 // replica of the hierarchy in order to make cross-links work properly
 // !
+// It is VERY important that the order of sensors and actuators in
+// the replicated object is preserved: it is is used to reconnect the logic.
+// This method is more robust then using the bricks name in case of complex 
+// group replication. The replication of logic bricks is done in 
+// SCA_IObject::ReParentLogic(), make sure it preserves the order of the bricks.
 void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
 {
 	// also relink the controller to sensors/actuators
@@ -530,37 +535,36 @@
 		for (vector<SCA_ISensor*>::iterator its = linkedsensors.begin();!(its==linkedsensors.end());its++)
 		{
 			SCA_ISensor* oldsensor = (*its);
-			STR_String name = oldsensor->GetName();
-			//find this name in the list
-			SCA_ISensor* newsensor = newobj->FindSensor(name);
+			SCA_IObject* oldsensorobj = oldsensor->GetParent();
+			SCA_IObject* newsensorobj = NULL;
 		
-			if (newsensor)
+			// the original owner of the sensor has been replicated?
+			void **h_obj = m_map_gameobject_to_replica[oldsensorobj];
+			if (h_obj)
+				newsensorobj = (SCA_IObject*)(*h_obj);
+			if (!newsensorobj)
 			{
-				// relink this newsensor to the controller
-				m_logicmgr->RegisterToSensor(cont,newsensor);
+				// no, then the sensor points outside the hierachy, keep it the same
+				m_logicmgr->RegisterToSensor(cont,oldsensor);
 			}
 			else
 			{
-				// it can be linked somewhere in the hierarchy or...
-				for (vector<KX_GameObject*>::iterator git = m_logicHierarchicalGameObjects.begin();
-				!(git==m_logicHierarchicalGameObjects.end());++git)
+				// yes, then the new sensor has the same position
+				SCA_SensorList& sensorlist = oldsensorobj->GetSensors();
+				SCA_SensorList::iterator sit;
+				SCA_ISensor* newsensor = NULL;
+				int sensorpos;
+
+				for (sensorpos=0, sit=sensorlist.begin(); sit!=sensorlist.end(); sit++, sensorpos++)
 				{
-					newsensor = (*git)->FindSensor(name);
-					if (newsensor)
+					if ((*sit) == oldsensor) 
+					{
+						newsensor = newsensorobj->GetSensors().at(sensorpos);
 						break;
-				} 
-
-				if (newsensor)
-				{
-					// relink this newsensor to the controller somewhere else within this
-					// hierarchy
-					m_logicmgr->RegisterToSensor(cont,newsensor);
+					}
 				}
-				else
-				{
-					// must be an external sensor, so...
-					m_logicmgr->RegisterToSensor(cont,oldsensor);
-				}
+				assert(newsensor != NULL);
+				m_logicmgr->RegisterToSensor(cont,newsensor);
 			}
 		}
 		
@@ -568,38 +572,38 @@
 		for (vector<SCA_IActuator*>::iterator ita = linkedactuators.begin();!(ita==linkedactuators.end());ita++)
 		{
 			SCA_IActuator* oldactuator = (*ita);
-			STR_String name = oldactuator->GetName();
-			//find this name in the list
-			SCA_IActuator* newactuator = newobj->FindActuator(name);
-			if (newactuator)
+			SCA_IObject* oldactuatorobj = oldactuator->GetParent();
+			SCA_IObject* newactuatorobj = NULL;
+
+			// the original owner of the sensor has been replicated?
+			void **h_obj = m_map_gameobject_to_replica[oldactuatorobj];
+			if (h_obj)
+				newactuatorobj = (SCA_IObject*)(*h_obj);
+
+			if (!newactuatorobj)
 			{
-				// relink this newsensor to the controller
-				m_logicmgr->RegisterToActuator(cont,newactuator);
-				newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
+				// no, then the sensor points outside the hierachy, keep it the same
+				m_logicmgr->RegisterToActuator(cont,oldactuator);
 			}
 			else
 			{
-				// it can be linked somewhere in the hierarchy or...
-				for (vector<KX_GameObject*>::iterator git = m_logicHierarchicalGameObjects.begin();
-				!(git==m_logicHierarchicalGameObjects.end());++git)
+				// yes, then the new sensor has the same position
+				SCA_ActuatorList& actuatorlist = oldactuatorobj->GetActuators();
+				SCA_ActuatorList::iterator ait;
+				SCA_IActuator* newactuator = NULL;
+				int actuatorpos;
+
+				for (actuatorpos=0, ait=actuatorlist.begin(); ait!=actuatorlist.end(); ait++, actuatorpos++)
 				{
-					newactuator= (*git)->FindActuator(name);
-					if (newactuator)
+					if ((*ait) == oldactuator) 
+					{
+						newactuator = newactuatorobj->GetActuators().at(actuatorpos);
 						break;
-				} 
-
-				if (newactuator)
-				{
-					// relink this actuator to the controller somewhere else within this
-					// hierarchy
-					m_logicmgr->RegisterToActuator(cont,newactuator);
-					newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
+					}
 				}
-				else
-				{
-					// must be an external actuator, so...
-					m_logicmgr->RegisterToActuator(cont,oldactuator);
-				}
+				assert(newactuator != NULL);
+				m_logicmgr->RegisterToActuator(cont,newactuator);
+				newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
 			}
 		}
 	}





More information about the Bf-blender-cvs mailing list