BVB Source Codes

CRYENGINE Show AIObjectManager.cpp Source code

Return Download CRYENGINE: download AIObjectManager.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #include "StdAfx.h"
  4. #include "AIObjectManager.h"
  5.  
  6. //TODO should be removed so no knowledge of these are here:
  7. #include "Puppet.h"
  8. #include "AIVehicle.h"
  9. #include "AIFlyingVehicle.h"
  10. #include "AIPlayer.h"
  11. #include "AIObjectIterators.h"//TODO get rid of this file totally!
  12. #include "PerceptionManager.h"
  13. #include "ObjectContainer.h"
  14. #include "./TargetSelection/TargetTrackManager.h"
  15.  
  16. //////////////////////////////////////////////////////////////////////////
  17. //      SAIObjectCreationHelper - helper for serializing AI objects
  18. //      (used for both normal and bookmark serialization)
  19. //////////////////////////////////////////////////////////////////////////
  20. SAIObjectCreationHelper::SAIObjectCreationHelper(CAIObject* pObject)
  21. {
  22.         if (pObject)
  23.         {
  24.                 name = pObject->GetName();
  25.                 objectId = pObject->GetAIObjectID();
  26.  
  27.                 // Working from child to parent through the hierarchy is essential here - each object can be many types
  28.                 // This could all be much neater with a different type system to fastcast.
  29.                 if (pObject->CastToCAIVehicle())  aiClass = eAIC_AIVehicle;
  30.                 else if (pObject->CastToCAIFlyingVehicle())
  31.                         aiClass = eAIC_AIFlyingVehicle;
  32.                 else if (pObject->CastToCPuppet())
  33.                         aiClass = eAIC_Puppet;
  34.                 else if (pObject->CastToCPipeUser())
  35.                         aiClass = eAIC_PipeUser;
  36.                 else if (pObject->CastToCAIPlayer())
  37.                         aiClass = eAIC_AIPlayer;
  38.                 else if (pObject->CastToCLeader())
  39.                         aiClass = eAIC_Leader;
  40.                 else if (pObject->CastToCAIActor())
  41.                         aiClass = eAIC_AIActor;
  42.                 else /* CAIObject */ aiClass = eAIC_AIObject;
  43.         }
  44.         else
  45.         {
  46.                 objectId = INVALID_AIOBJECTID;
  47.                 name = "Unset";
  48.                 aiClass = eAIC_Invalid;
  49.         }
  50. }
  51.  
  52. void SAIObjectCreationHelper::Serialize(TSerialize ser)
  53. {
  54.         ser.BeginGroup("ObjectHeader");
  55.         ser.Value("name", name);  // debug mainly, could be removed
  56.         ser.EnumValue("class", aiClass, eAIC_FIRST, eAIC_LAST);
  57.         ser.Value("objectId", objectId);
  58.         ser.EndGroup();
  59. }
  60.  
  61. CAIObject* SAIObjectCreationHelper::RecreateObject(void* pAlloc /*=NULL*/)
  62. {
  63.         // skip unset ones (eg from a nil CStrongRef)
  64.         if (objectId == INVALID_AIOBJECTID && aiClass == eAIC_Invalid)
  65.                 return NULL;
  66.  
  67.         // first verify it doesn't already exist
  68.         // cppcheck-suppress assertWithSideEffect
  69.         assert(gAIEnv.pAIObjectManager->GetAIObject(objectId) == NULL);
  70.  
  71.         CAIObject* pObject = NULL;
  72.         switch (aiClass)
  73.         {
  74.         case eAIC_AIVehicle:
  75.                 pObject = pAlloc ? new(pAlloc) CAIVehicle : new CAIVehicle;
  76.                 break;
  77.         case eAIC_Puppet:
  78.                 pObject = pAlloc ? new(pAlloc) CPuppet : new CPuppet;
  79.                 break;
  80.         case eAIC_PipeUser:
  81.                 pObject = pAlloc ? new(pAlloc) CPipeUser : new CPipeUser;
  82.                 break;
  83.         case eAIC_AIPlayer:
  84.                 pObject = pAlloc ? new(pAlloc) CAIPlayer : new CAIPlayer;
  85.                 break;
  86.         case eAIC_Leader:
  87.                 pObject = pAlloc ? new(pAlloc) CLeader(0) : new CLeader(0);
  88.                 break;                                                                                // Groupid is reqd
  89.         case eAIC_AIActor:
  90.                 pObject = pAlloc ? new(pAlloc) CAIActor : new CAIActor;
  91.                 break;
  92.         case eAIC_AIObject:
  93.                 pObject = pAlloc ? new(pAlloc) CAIObject : new CAIObject;
  94.                 break;
  95.         case eAIC_AIFlyingVehicle:
  96.                 pObject = pAlloc ? new(pAlloc) CAIFlyingVehicle : new CAIFlyingVehicle;
  97.                 break;
  98.         default:
  99.                 assert(false);
  100.         }
  101.  
  102.         return pObject;
  103. }
  104.  
  105. //////////////////////////////////////////////////////////////////////////
  106. //      CAIObjectManager
  107. //////////////////////////////////////////////////////////////////////////
  108.  
  109. CAIObjectManager::CAIObjectManager()
  110. {
  111. }
  112.  
  113. CAIObjectManager::~CAIObjectManager()
  114. {
  115.         m_mapDummyObjects.clear();
  116. }
  117.  
  118. void CAIObjectManager::Init()
  119. {
  120. }
  121.  
  122. void CAIObjectManager::Reset(bool includingPooled /*=true*/)
  123. {
  124.         m_mapDummyObjects.clear();
  125.         m_Objects.clear();
  126. }
  127.  
  128. IAIObject* CAIObjectManager::CreateAIObject(const AIObjectParams& params)
  129. {
  130.         CCCPOINT(CreateAIObject);
  131.  
  132.         if (!GetAISystem()->IsEnabled())
  133.                 return 0;
  134.  
  135.         if (!GetAISystem()->m_bInitialized)
  136.         {
  137.                 AIError("CAISystem::CreateAIObject called on an uninitialized AI system [Code bug]");
  138.                 return 0;
  139.         }
  140.  
  141.         CAIObject* pObject = NULL;
  142.         CLeader* pLeader = NULL;
  143.  
  144.         tAIObjectID idToUse = INVALID_AIOBJECTID;
  145.  
  146.         IEntity* pEntity = gEnv->pEntitySystem->GetEntity(params.entityID);
  147.         uint16 type = params.type;
  148.  
  149.         switch (type)
  150.         {
  151.         case AIOBJECT_DUMMY:
  152.                 CRY_ASSERT_MESSAGE(false, "Creating dummy object through the AI object manager (use CAISystem::CreateDummyObject instead)");
  153.                 return 0;
  154.         case AIOBJECT_ACTOR:
  155.                 type = AIOBJECT_ACTOR;
  156.                 pObject = new CPuppet;
  157.                 break;
  158.         case AIOBJECT_2D_FLY:
  159.                 type = AIOBJECT_ACTOR;
  160.                 pObject = new CPuppet;
  161.                 pObject->SetSubType(CAIObject::STP_2D_FLY);
  162.                 break;
  163.         case AIOBJECT_LEADER:
  164.                 {
  165.                         int iGroup = params.association ? static_cast<CPuppet*>(params.association)->GetGroupId() : -1;
  166.                         pLeader = new CLeader(iGroup);
  167.                         pObject = pLeader;
  168.                 }
  169.                 break;
  170.         case AIOBJECT_BOAT:
  171.                 type = AIOBJECT_VEHICLE;
  172.                 pObject = new CAIVehicle;
  173.                 pObject->SetSubType(CAIObject::STP_BOAT);
  174.                 //                              pObject->m_bNeedsPathOutdoor = false;
  175.                 break;
  176.         case AIOBJECT_CAR:
  177.                 type = AIOBJECT_VEHICLE;
  178.                 pObject = new CAIVehicle;
  179.                 pObject->SetSubType(CAIObject::STP_CAR);
  180.                 break;
  181.         case AIOBJECT_HELICOPTER:
  182.                 type = AIOBJECT_VEHICLE;
  183.                 pObject = new CAIVehicle;
  184.                 pObject->SetSubType(CAIObject::STP_HELI);
  185.                 break;
  186.         case AIOBJECT_INFECTED:
  187.                 type = AIOBJECT_ACTOR;
  188.                 pObject = new CAIActor;
  189.                 break;
  190.         case AIOBJECT_PLAYER:
  191.                 pObject = new CAIPlayer; // just a dummy for the player
  192.                 break;
  193.         case AIOBJECT_RPG:
  194.         case AIOBJECT_GRENADE:
  195.                 pObject = new CAIObject;
  196.                 break;
  197.         case AIOBJECT_WAYPOINT:
  198.         case AIOBJECT_HIDEPOINT:
  199.         case AIOBJECT_SNDSUPRESSOR:
  200.         case AIOBJECT_NAV_SEED:
  201.                 pObject = new CAIObject;
  202.                 break;
  203.         case AIOBJECT_ALIENTICK:
  204.                 type = AIOBJECT_ACTOR;
  205.                 pObject = new CPipeUser;
  206.                 break;
  207.         case AIOBJECT_HELICOPTERCRYSIS2:
  208.                 type = AIOBJECT_ACTOR;
  209.                 pObject = new CAIFlyingVehicle;
  210.                 pObject->SetSubType(CAIObject::STP_HELICRYSIS2);
  211.                 break;
  212.         default:
  213.                 // try to create an object of user defined type
  214.                 pObject = new CAIObject;
  215.                 break;
  216.         }
  217.  
  218.         assert(pObject);
  219.  
  220.         // Register the object
  221.         CStrongRef<CAIObject> object;
  222.         gAIEnv.pObjectContainer->RegisterObject(pObject, object, idToUse);
  223.  
  224.         CCountedRef<CAIObject> countedRef = object;
  225.  
  226.         // insert object into map under key type
  227.         // this is a multimap
  228.         m_Objects.insert(AIObjectOwners::iterator::value_type(type, countedRef));
  229.  
  230.         // Reset the object after registration, so other systems can reference back to it if needed
  231.         pObject->SetType(type);
  232.         pObject->SetEntityID(params.entityID);
  233.         pObject->SetName(params.name);
  234.         pObject->SetAssociation(GetWeakRef((CAIObject*)params.association));
  235.  
  236.         if (pEntity)
  237.         {
  238.                 pObject->SetPos(pEntity->GetWorldPos());
  239.         }
  240.  
  241.         if (CAIActor* actor = pObject->CastToCAIActor())
  242.                 actor->ParseParameters(params);
  243.  
  244.         // Non-puppets and players need to be updated at least once for delayed initialization (Reset sets this to false!)
  245.         if (type != AIOBJECT_PLAYER && type != AIOBJECT_ACTOR)  //&& type != AIOBJECT_VEHICLE )
  246.                 pObject->m_bUpdatedOnce = true;
  247.  
  248.         if ((type == AIOBJECT_LEADER) && params.association && pLeader)
  249.                 GetAISystem()->AddToGroup(pLeader);
  250.  
  251.         pObject->Reset(AIOBJRESET_INIT);
  252.  
  253.         AILogComment("CAISystem::CreateAIObject %p of type %d", pObject, type);
  254.  
  255.         if (type == AIOBJECT_PLAYER)
  256.                 pObject->Event(AIEVENT_ENABLE, NULL);
  257.  
  258.         return pObject;
  259. }
  260.  
  261. void CAIObjectManager::CreateDummyObject(CCountedRef<CAIObject>& ref, const char* name, CAIObject::ESubType type, tAIObjectID requiredID /*= INVALID_AIOBJECTID*/)
  262. {
  263.         CStrongRef<CAIObject> refTemp;
  264.         CreateDummyObject(refTemp, name, type, requiredID);
  265.         ref = refTemp;
  266. }
  267.  
  268. void CAIObjectManager::CreateDummyObject(CStrongRef<CAIObject>& ref, const char* name /*=""*/, CAIObject::ESubType type /*= CAIObject::STP_NONE*/, tAIObjectID requiredID /*= INVALID_AIOBJECTID*/)
  269. {
  270.         CCCPOINT(CreateDummyObject);
  271.  
  272.         CAIObject* pObject = new CAIObject;
  273.         gAIEnv.pObjectContainer->RegisterObject(pObject, ref, requiredID);
  274.  
  275.         pObject->SetType(AIOBJECT_DUMMY);
  276.         pObject->SetSubType(type);
  277.  
  278.         pObject->SetAssociation(NILREF);
  279.         if (name && *name)
  280.                 pObject->SetName(name);
  281.  
  282.         // check whether it was added before
  283.         AIObjects::iterator itEntry = m_mapDummyObjects.find(type);
  284.         while ((itEntry != m_mapDummyObjects.end()) && (itEntry->first == type))
  285.         {
  286.                 if (itEntry->second == ref)
  287.                         return;
  288.                 ++itEntry;
  289.         }
  290.  
  291.         // make sure it is not in with another types already
  292.         itEntry = m_mapDummyObjects.begin();
  293.         for (; itEntry != m_mapDummyObjects.end(); ++itEntry)
  294.         {
  295.                 if (itEntry->second == ref)
  296.                 {
  297.                         m_mapDummyObjects.erase(itEntry);
  298.                         break;
  299.                 }
  300.         }
  301.  
  302.         // insert object into map under key type
  303.         m_mapDummyObjects.insert(AIObjects::iterator::value_type(type, ref));
  304.  
  305.         AILogComment("CAIObjectManager::CreateDummyObject %s (%p)", pObject->GetName(), pObject);
  306. }
  307.  
  308. void CAIObjectManager::RemoveObject(tAIObjectID objectID)
  309. {
  310.         EntityId entityId = 0;
  311.  
  312.         // Find the element in the owners list and erase it from there
  313.         // This is strong, so will trigger removal/deregister/release in normal fashion
  314.         // (MATT) Really not very efficient because the multimaps aren't very suitable for this.
  315.         // I think a different container might be better as primary owner. {2009/05/22}
  316.         AIObjectOwners::iterator it = m_Objects.begin();
  317.         AIObjectOwners::iterator itEnd = m_Objects.end();
  318.         for (; it != itEnd; ++it)
  319.         {
  320.                 if (it->second.GetObjectID() == objectID)
  321.                 {
  322.                         entityId = it->second->GetEntityID();
  323.                         break;
  324.                 }
  325.         }
  326.  
  327.         // Check we found one
  328.         if (it == itEnd)
  329.         {
  330.                 AIError("AI system asked to erase AI object with unknown AIObjectID");
  331.                 assert(false);
  332.                 return;
  333.         }
  334.  
  335.         m_Objects.erase(it);
  336.  
  337.         // Because Action doesn't yet handle a delayed removal of the Proxies, we should perform cleanup immediately.
  338.         // Note that this only happens when triggered externally, when an entity is refreshed/removed
  339.         gAIEnv.pObjectContainer->ReleaseDeregisteredObjects(false);
  340. }
  341.  
  342. // Get an AI object by it's AI object ID
  343. IAIObject* CAIObjectManager::GetAIObject(tAIObjectID aiObjectID)
  344. {
  345.         return gAIEnv.pObjectContainer->GetAIObject(aiObjectID);
  346. }
  347.  
  348. IAIObject* CAIObjectManager::GetAIObjectByName(unsigned short type, const char* pName) const
  349. {
  350.         AIObjectOwners::const_iterator ai;
  351.  
  352.         if (m_Objects.empty()) return 0;
  353.  
  354.         if (!type)
  355.                 return (IAIObject*) GetAIObjectByName(pName);
  356.  
  357.         if ((ai = m_Objects.find(type)) != m_Objects.end())
  358.         {
  359.                 for (; ai != m_Objects.end(); )
  360.                 {
  361.                         if (ai->first != type)
  362.                                 break;
  363.                         CAIObject* pObject = ai->second.GetAIObject();
  364.  
  365.                         if (strcmp(pName, pObject->GetName()) == 0)
  366.                                 return (IAIObject*) pObject;
  367.                         ++ai;
  368.                 }
  369.         }
  370.         return 0;
  371.  
  372. }
  373.  
  374. CAIObject* CAIObjectManager::GetAIObjectByName(const char* pName) const
  375. {
  376.         AIObjectOwners::const_iterator ai = m_Objects.begin();
  377.         while (ai != m_Objects.end())
  378.         {
  379.                 CAIObject* pObject = ai->second.GetAIObject();
  380.  
  381.                 if ((pObject != NULL) && (strcmp(pName, pObject->GetName()) == 0))
  382.                         return pObject;
  383.                 ++ai;
  384.         }
  385.  
  386.         // Try dummy object map as well
  387.         AIObjects::const_iterator aiDummy = m_mapDummyObjects.begin();
  388.         while (aiDummy != m_mapDummyObjects.end())
  389.         {
  390.                 CAIObject* pObject = aiDummy->second.GetAIObject();
  391.  
  392.                 if ((pObject != NULL) && (strcmp(pName, pObject->GetName()) == 0))
  393.                         return pObject;
  394.                 ++aiDummy;
  395.         }
  396.  
  397.         return 0;
  398. }
  399.  
  400. IAIObjectIter* CAIObjectManager::GetFirstAIObject(EGetFirstFilter filter, short n)
  401. {
  402.         if (filter == OBJFILTER_GROUP)
  403.         {
  404.                 return SAIObjectMapIterOfType<CWeakRef>::Allocate(n, GetAISystem()->m_mapGroups.find(n), GetAISystem()->m_mapGroups.end());
  405.         }
  406.         else if (filter == OBJFILTER_FACTION)
  407.         {
  408.                 return SAIObjectMapIterOfType<CWeakRef>::Allocate(n, GetAISystem()->m_mapFaction.find(n), GetAISystem()->m_mapFaction.end());
  409.         }
  410.         else if (filter == OBJFILTER_DUMMYOBJECTS)
  411.         {
  412.                 return SAIObjectMapIterOfType<CWeakRef>::Allocate(n, m_mapDummyObjects.find(n), m_mapDummyObjects.end());
  413.         }
  414.         else
  415.         {
  416.                 if (n == 0)
  417.                         return SAIObjectMapIter<CCountedRef>::Allocate(m_Objects.begin(), m_Objects.end());
  418.                 else
  419.                         return SAIObjectMapIterOfType<CCountedRef>::Allocate(n, m_Objects.find(n), m_Objects.end());
  420.         }
  421. }
  422.  
  423. IAIObjectIter* CAIObjectManager::GetFirstAIObjectInRange(EGetFirstFilter filter, short n, const Vec3& pos, float rad, bool check2D)
  424. {
  425.         if (filter == OBJFILTER_GROUP)
  426.         {
  427.                 return SAIObjectMapIterOfTypeInRange<CWeakRef>::Allocate(n, GetAISystem()->m_mapGroups.find(n), GetAISystem()->m_mapGroups.end(), pos, rad, check2D);
  428.         }
  429.         else if (filter == OBJFILTER_FACTION)
  430.         {
  431.                 return SAIObjectMapIterOfTypeInRange<CWeakRef>::Allocate(n, GetAISystem()->m_mapFaction.find(n), GetAISystem()->m_mapFaction.end(), pos, rad, check2D);
  432.         }
  433.         else if (filter == OBJFILTER_DUMMYOBJECTS)
  434.         {
  435.                 return SAIObjectMapIterOfTypeInRange<CWeakRef>::Allocate(n, m_mapDummyObjects.find(n), m_mapDummyObjects.end(), pos, rad, check2D);
  436.         }
  437.         else // if(filter == OBJFILTER_TYPE)
  438.         {
  439.                 if (n == 0)
  440.                         return SAIObjectMapIterInRange<CCountedRef>::Allocate(m_Objects.begin(), m_Objects.end(), pos, rad, check2D);
  441.                 else
  442.                         return SAIObjectMapIterOfTypeInRange<CCountedRef>::Allocate(n, m_Objects.find(n), m_Objects.end(), pos, rad, check2D);
  443.         }
  444. }
  445.  
  446. void CAIObjectManager::OnObjectRemoved(CAIObject* pObject)
  447. {
  448.         FUNCTION_PROFILER(gEnv->pSystem, PROFILE_AI);
  449.         CCCPOINT(OnObjectRemoved);
  450.  
  451.         if (!pObject)
  452.                 return;
  453.  
  454.         RemoveObjectFromAllOfType(AIOBJECT_ACTOR, pObject);
  455.         RemoveObjectFromAllOfType(AIOBJECT_VEHICLE, pObject);
  456.         RemoveObjectFromAllOfType(AIOBJECT_ATTRIBUTE, pObject);
  457.         RemoveObjectFromAllOfType(AIOBJECT_LEADER, pObject);
  458.  
  459.         // (MATT) Remove from player - especially as attention target {2009/02/05}
  460.         CAIPlayer* pPlayer = CastToCAIPlayerSafe(GetAISystem()->GetPlayer());
  461.         if (pPlayer)
  462.                 pPlayer->OnObjectRemoved(pObject);
  463.  
  464.         for (CAISystem::AIGroupMap::iterator it = GetAISystem()->m_mapAIGroups.begin(); it != GetAISystem()->m_mapAIGroups.end(); ++it)
  465.                 it->second->OnObjectRemoved(pObject);
  466.  
  467.         AIObjects::iterator oi;
  468.         for (oi = GetAISystem()->m_mapFaction.begin(); oi != GetAISystem()->m_mapFaction.end(); ++oi)
  469.         {
  470.                 if (oi->second == pObject)
  471.                 {
  472.                         GetAISystem()->m_mapFaction.erase(oi);
  473.                         break;
  474.                 }
  475.         }
  476.  
  477.         for (oi = GetAISystem()->m_mapGroups.begin(); oi != GetAISystem()->m_mapGroups.end(); ++oi)
  478.         {
  479.                 if (oi->second == pObject)
  480.                 {
  481.                         GetAISystem()->m_mapGroups.erase(oi);
  482.                         break;
  483.                 }
  484.         }
  485.  
  486.         for (oi = m_mapDummyObjects.begin(); oi != m_mapDummyObjects.end(); ++oi)
  487.         {
  488.                 if (oi->second == pObject)
  489.                 {
  490.                         m_mapDummyObjects.erase(oi);
  491.                         break;
  492.                 }
  493.         }
  494.  
  495.         CLeader* pLeader = pObject->CastToCLeader();
  496.         if (pLeader)
  497.         {
  498.                 if (CAIGroup* pAIGroup = pLeader->GetAIGroup())
  499.                 {
  500.                         pAIGroup->SetLeader(0);
  501.                 }
  502.         }
  503.         CAISystem::FormationMap::iterator fi;
  504.         for (fi = GetAISystem()->m_mapActiveFormations.begin(); fi != GetAISystem()->m_mapActiveFormations.end(); ++fi)
  505.                 fi->second->OnObjectRemoved(pObject);
  506.  
  507.         //remove this object from any pending paths generated for him
  508.         CAIActor* pActor = pObject->CastToCAIActor();
  509.         if (pActor)
  510.         {
  511.                 pActor->CancelRequestedPath(true);
  512.         }
  513.  
  514.         // (MATT) Try to do implicitly {2009/02/05}
  515.         /*
  516.            // check if this object owned any beacons and remove them if so
  517.            if (!m_mapBeacons.empty())
  518.            {
  519.            BeaconMap::iterator bi,biend = m_mapBeacons.end();
  520.            for (bi=m_mapBeacons.begin();bi!=biend;)
  521.            {
  522.             if ((bi->second).pOwner == pObject)
  523.             {
  524.               BeaconMap::iterator eraseme = bi;
  525.            ++bi;
  526.               RemoveObject((eraseme->second).pBeacon);
  527.               m_mapBeacons.erase(bi);
  528.             }
  529.             else
  530.            ++bi;
  531.            }
  532.            }
  533.          */
  534.  
  535.         if (gAIEnv.pTargetTrackManager)
  536.                 gAIEnv.pTargetTrackManager->OnObjectRemoved(pObject);
  537.  
  538.         CPuppet* pPuppet = pObject->CastToCPuppet();
  539.         if (pPuppet)
  540.         {
  541.                 for (unsigned i = 0; i < GetAISystem()->m_delayedExpAccessoryUpdates.size(); )
  542.                 {
  543.                         if (GetAISystem()->m_delayedExpAccessoryUpdates[i].pPuppet = pPuppet)
  544.                         {
  545.                                 GetAISystem()->m_delayedExpAccessoryUpdates[i] = GetAISystem()->m_delayedExpAccessoryUpdates.back();
  546.                                 GetAISystem()->m_delayedExpAccessoryUpdates.pop_back();
  547.                         }
  548.                         else
  549.                                 ++i;
  550.                 }
  551.         }
  552. }
  553.  
  554. // it removes all references to this object from all objects of the specified type
  555. //
  556. //-----------------------------------------------------------------------------------------------------------
  557. void CAIObjectManager::RemoveObjectFromAllOfType(int nType, CAIObject* pRemovedObject)
  558. {
  559.         AIObjectOwners::iterator ai = m_Objects.lower_bound(nType);
  560.         AIObjectOwners::iterator end = m_Objects.end();
  561.         for (; ai != end && ai->first == nType; ++ai)
  562.                 ai->second.GetAIObject()->OnObjectRemoved(pRemovedObject);
  563. }
  564.  
downloadAIObjectManager.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top