BVB Source Codes

CRYENGINE Show ActorSystem.cpp Source code

Return Download CRYENGINE: download ActorSystem.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. /*************************************************************************
  4.    -------------------------------------------------------------------------
  5.    $Id$
  6.    $DateTime$
  7.  
  8.    -------------------------------------------------------------------------
  9.    History:
  10.    - 23:8:2004   15:52 : Created by M谩rcio Martins
  11.  
  12. *************************************************************************/
  13. #include "StdAfx.h"
  14. #include "ActorSystem.h"
  15. #include "Network/GameServerChannel.h"
  16. #include "Network/GameServerNub.h"
  17. #include <CryString/CryPath.h>
  18. #include "CryAction.h"
  19.  
  20. //------------------------------------------------------------------------
  21. void CActorSystem::DemoSpectatorSystem::SwitchSpectator(TActorMap* pActors, EntityId id)
  22. {
  23.         if (pActors->size() <= 1)
  24.                 return;
  25.  
  26.         IActor* nextActor, * lastActor;
  27.  
  28.         lastActor = (*pActors)[m_currentActor];
  29.  
  30.         if (id == 0)
  31.         {
  32.                 TActorMap::const_iterator it = pActors->begin();
  33.                 while (it->first != m_currentActor)
  34.                         ++it;
  35.                 ++it;
  36.                 if (it == pActors->end())
  37.                         it = pActors->begin();
  38.                 nextActor = it->second;
  39.         }
  40.         else
  41.         {
  42.                 nextActor = (*pActors)[id];
  43.                 if (!nextActor)
  44.                         return;
  45.         }
  46.  
  47.         if (nextActor == lastActor)
  48.                 return;
  49.  
  50.         m_currentActor = nextActor->GetEntityId();
  51.         if (IView* view = gEnv->pGameFramework->GetIViewSystem()->GetActiveView())
  52.                 view->LinkTo(nextActor->GetEntity());
  53.  
  54.         nextActor->SwitchDemoModeSpectator(true);
  55.         lastActor->SwitchDemoModeSpectator(false);
  56. }
  57.  
  58. //------------------------------------------------------------------------
  59. CActorSystem::CActorSystem(ISystem* pSystem, IEntitySystem* pEntitySystem)
  60.         : m_pSystem(pSystem),
  61.         m_pEntitySystem(pEntitySystem)
  62. {
  63.         m_demoPlaybackMappedOriginalServerPlayer = 0;
  64.  
  65.         if (gEnv->pEntitySystem)
  66.         {
  67.                 gEnv->pEntitySystem->AddSink(this, IEntitySystem::OnReused, 0);
  68.         }
  69. }
  70.  
  71. // Iterators now have their destructors called before they enter the pool - so we only need to free the memory here {2008/12/09}
  72. void DeleteActorIterator(IActorIterator* ptr) { operator delete(ptr); }
  73.  
  74. //------------------------------------------------------------------------
  75. CActorSystem::~CActorSystem()
  76. {
  77.         if (gEnv->pEntitySystem)
  78.         {
  79.                 gEnv->pEntitySystem->RemoveSink(this);
  80.         }
  81.  
  82.         std::for_each(m_iteratorPool.begin(), m_iteratorPool.end(), DeleteActorIterator);
  83.         // delete the created userdata in each class
  84.         for (TActorClassMap::iterator it = m_classes.begin(); it != m_classes.end(); ++it)
  85.         {
  86.                 IEntityClass* pClass = m_pEntitySystem->GetClassRegistry()->FindClass(it->first.c_str());
  87.                 if (pClass)
  88.                         delete (char*)pClass->GetUserProxyData();
  89.         }
  90. }
  91.  
  92. void CActorSystem::Reset()
  93. {
  94.         if (GetISystem()->IsSerializingFile() == 1)
  95.         {
  96.                 TActorMap::iterator it = m_actors.begin();
  97.                 IEntitySystem* pEntitySystem = gEnv->pEntitySystem;
  98.                 for (; it != m_actors.end(); )
  99.                 {
  100.                         EntityId id = it->first;
  101.                         IEntity* pEntity = pEntitySystem->GetEntity(id);
  102.                         if (pEntity != NULL)
  103.                         {
  104.                                 ++it;
  105.                         }
  106.                         else
  107.                         {
  108.                                 TActorMap::iterator eraseIt = it++;
  109.                                 m_actors.erase(eraseIt);
  110.                         }
  111.                 }
  112.         }
  113.  
  114.         std::for_each(m_iteratorPool.begin(), m_iteratorPool.end(), DeleteActorIterator);
  115.         stl::free_container(m_iteratorPool);
  116. }
  117.  
  118. //------------------------------------------------------------------------
  119. IActor* CActorSystem::GetActor(EntityId entityId)
  120. {
  121.         TActorMap::iterator it = m_actors.find(entityId);
  122.  
  123.         if (it != m_actors.end())
  124.         {
  125.                 return it->second;
  126.         }
  127.  
  128.         return 0;
  129. }
  130.  
  131. //------------------------------------------------------------------------
  132. IActor* CActorSystem::GetActorByChannelId(uint16 channelId)
  133. {
  134.         for (TActorMap::iterator it = m_actors.begin(); it != m_actors.end(); ++it)
  135.         {
  136.                 if (it->second->GetGameObject()->GetChannelId() == channelId)
  137.                 {
  138.                         return it->second;
  139.                 }
  140.         }
  141.  
  142.         return 0;
  143. }
  144.  
  145. //------------------------------------------------------------------------
  146. IActor* CActorSystem::CreateActor(uint16 channelId, const char* name, const char* actorClass, const Vec3& pos, const Quat& rot, const Vec3& scale, EntityId id)
  147. {
  148.         // get the entity class
  149.         IEntityClass* pEntityClass = m_pEntitySystem->GetClassRegistry()->FindClass(actorClass);
  150.  
  151.         if (!pEntityClass)
  152.         {
  153.                 CRY_ASSERT(pEntityClass);
  154.  
  155.                 return 0;
  156.         }
  157.  
  158.         // if a channel is specified and already has a player,
  159.         // use that entity id
  160.  
  161.         bool bIsClient = false;
  162.         if (channelId)
  163.         {
  164.                 if (CGameServerNub* pGameServerNub = CCryAction::GetCryAction()->GetGameServerNub())
  165.                         if (CGameServerChannel* pGameServerChannel = pGameServerNub->GetChannel(channelId))
  166.                                 if (pGameServerChannel->GetNetChannel()->IsLocal())
  167.                                 {
  168.                                         id = LOCAL_PLAYER_ENTITY_ID;
  169.                                         bIsClient = true;
  170.                                         if (IsDemoPlayback()) //if playing a demo - spectator id is changed
  171.                                                 m_demoSpectatorSystem.m_currentActor = m_demoSpectatorSystem.m_originalActor = id;
  172.                                 }
  173.         }
  174.  
  175.         IGameObjectSystem::SEntitySpawnParamsForGameObjectWithPreactivatedExtension userData;
  176.         userData.hookFunction = HookCreateActor;
  177.         userData.pUserData = &channelId;
  178.  
  179.         SEntitySpawnParams params;
  180.         params.id = id;
  181.         params.pUserData = (void*)&userData;
  182.         params.sName = name;
  183.         params.vPosition = pos;
  184.         params.qRotation = rot;
  185.         params.vScale = scale;
  186.         params.nFlags = ENTITY_FLAG_TRIGGER_AREAS;
  187.         params.nFlagsExtended = ENTITY_FLAG_EXTENDED_NEEDS_MOVEINSIDE; // ensures the audio triggered on the actor entity will get proper environment values
  188.  
  189.         if (channelId)
  190.                 params.nFlags |= ENTITY_FLAG_NEVER_NETWORK_STATIC;
  191.         params.pClass = pEntityClass;
  192.  
  193.         IEntity* pEntity = m_pEntitySystem->SpawnEntity(params);
  194.         CRY_ASSERT(pEntity);
  195.  
  196.         if (!pEntity)
  197.         {
  198.                 return 0;
  199.         }
  200.        
  201.         return GetActor(pEntity->GetId());
  202. }
  203.  
  204. //------------------------------------------------------------------------
  205. void CActorSystem::SetDemoPlaybackMappedOriginalServerPlayer(EntityId id)
  206. {
  207.         m_demoPlaybackMappedOriginalServerPlayer = id;
  208. }
  209.  
  210. EntityId CActorSystem::GetDemoPlaybackMappedOriginalServerPlayer() const
  211. {
  212.         return m_demoPlaybackMappedOriginalServerPlayer;
  213. }
  214.  
  215. //------------------------------------------------------------------------
  216. void CActorSystem::SwitchDemoSpectator(EntityId id)
  217. {
  218.         m_demoSpectatorSystem.SwitchSpectator(&m_actors, id);
  219. }
  220.  
  221. //------------------------------------------------------------------------
  222. IActor* CActorSystem::GetCurrentDemoSpectator()
  223. {
  224.         return m_actors[m_demoSpectatorSystem.m_currentActor];
  225. }
  226.  
  227. //------------------------------------------------------------------------
  228. IActor* CActorSystem::GetOriginalDemoSpectator()
  229. {
  230.         return m_actors[m_demoSpectatorSystem.m_originalActor];
  231. }
  232.  
  233. //------------------------------------------------------------------------
  234. void CActorSystem::RegisterActorClass(const char* name, IGameFramework::IActorCreator* pCreator, bool isAI)
  235. {
  236.         IEntityClassRegistry::SEntityClassDesc actorClass;
  237.  
  238.         char scriptName[1024] = { 0 };
  239.         if (!isAI)
  240.                 cry_sprintf(scriptName, "Scripts/Entities/Actor/%s.lua", name);
  241.         else
  242.                 cry_sprintf(scriptName, "Scripts/Entities/AI/%s.lua", name);
  243.  
  244.         // Allow the name to contain relative path, but use only the name part as class name.
  245.         string className(PathUtil::GetFile(name));
  246.         actorClass.sName = className.c_str();
  247.         actorClass.sScriptFile = scriptName;
  248.         if (!isAI)
  249.                 actorClass.flags |= ECLF_INVISIBLE;
  250.  
  251.         CCryAction::GetCryAction()->GetIGameObjectSystem()->RegisterExtension(className.c_str(), pCreator, &actorClass);
  252.  
  253.         SActorClassDesc classDesc;
  254.         classDesc.pEntityClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(className.c_str());
  255.         classDesc.pCreator = pCreator;
  256.  
  257.         m_classes.insert(TActorClassMap::value_type(name, classDesc));
  258.  
  259.         // Automatically register scheduling profile
  260.         gEnv->pGameFramework->GetIGameObjectSystem()->RegisterSchedulingProfile(actorClass.sName, "dude", "own");
  261. }
  262.  
  263. //------------------------------------------------------------------------
  264. void CActorSystem::AddActor(EntityId entityId, IActor* pProxy)
  265. {
  266.         m_actors.insert(TActorMap::value_type(entityId, pProxy));
  267. }
  268.  
  269. //------------------------------------------------------------------------
  270. void CActorSystem::RemoveActor(EntityId entityId)
  271. {
  272.         stl::member_find_and_erase(m_actors, entityId);
  273. }
  274.  
  275. //------------------------------------------------------------------------
  276. bool CActorSystem::HookCreateActor(IEntity* pEntity, IGameObject* pGameObject, void* pUserData)
  277. {
  278.         pGameObject->SetChannelId(*reinterpret_cast<uint16*>(pUserData));
  279.         return true;
  280. }
  281.  
  282. //---------------------------------------------------------------------
  283. void CActorSystem::Reload()
  284. {
  285.         Reset();
  286.         Scan(m_actorParamsFolder.c_str());
  287. }
  288.  
  289. //---------------------------------------------------------------------
  290. void CActorSystem::Scan(const char* folderName)
  291. {
  292.         stack_string folder = folderName;
  293.         stack_string search = folder;
  294.         stack_string subName;
  295.         stack_string xmlFile;
  296.         search += "/*.*";
  297.  
  298.         ICryPak* pPak = gEnv->pCryPak;
  299.  
  300.         _finddata_t fd;
  301.         intptr_t handle = pPak->FindFirst(search.c_str(), &fd);
  302.         //Scan only one directory, not recursion supported (add it if need it)
  303.         if (handle > -1)
  304.         {
  305.                 do
  306.                 {
  307.                         if (!strcmp(fd.name, ".") || !strcmp(fd.name, ".."))
  308.                                 continue;
  309.  
  310.                         const char* fileExtension = PathUtil::GetExt(fd.name);
  311.                         if (stricmp(fileExtension, "xml"))
  312.                         {
  313.                                 if (stricmp(fileExtension, "binxml"))
  314.                                         GameWarning("ActorSystem: File '%s' does not have 'xml' extension, skipping.", fd.name);
  315.  
  316.                                 continue;
  317.                         }
  318.  
  319.                         xmlFile = folder + "/" + fd.name;
  320.                         XmlNodeRef rootNode = gEnv->pSystem->LoadXmlFromFile(xmlFile.c_str());
  321.  
  322.                         if (!rootNode)
  323.                         {
  324.                                 ActorSystemErrorMessage(xmlFile.c_str(), "Root xml node couldn't be loaded", true);
  325.                                 continue;
  326.                         }
  327.  
  328.                         if (!ScanXML(rootNode, xmlFile.c_str()))
  329.                         {
  330.                                 continue;
  331.                         }
  332.  
  333.                 }
  334.                 while (pPak->FindNext(handle, &fd) >= 0);
  335.         }
  336.  
  337.         m_actorParamsFolder = folderName;
  338. }
  339.  
  340. //--------------------------------------------------------------------
  341. bool CActorSystem::ScanXML(const XmlNodeRef& root, const char* xmlFile)
  342. {
  343.         if (strcmpi(root->getTag(), "ActorParams") && strcmpi(root->getTag(), "EntityClassParams"))
  344.         {
  345.                 CryFixedStringT<128> errorBuffer;
  346.                 errorBuffer.Format("Root tag is '%s', expecting 'ActorParams' or 'EntityClassParams', Skipping...");
  347.                 ActorSystemErrorMessage(xmlFile, errorBuffer.c_str(), true);
  348.                 return false;
  349.         }
  350.  
  351.         const char* type = root->getAttr("type");
  352.         if (!type)
  353.         {
  354.                 ActorSystemErrorMessage(xmlFile, "Actor/EntityClass params file does not contain attribute 'type'! Skipping...", true);
  355.                 return false;
  356.         }
  357.  
  358.         TActorParamsMap::iterator dit = m_actorParams.find(CONST_TEMP_STRING(type));
  359.  
  360.         //Insert only if new, might be reloading...
  361.         if (dit == m_actorParams.end())
  362.         {
  363.                 std::pair<TActorParamsMap::iterator, bool> result = m_actorParams.insert(TActorParamsMap::value_type(type, SActorParamsDesc()));
  364.                 dit = result.first;
  365.         }
  366.  
  367.         SActorParamsDesc& desc = dit->second;
  368.  
  369.         if (desc.params)
  370.                 desc.params->Release();
  371.  
  372.         desc.params = new CItemParamsNode();
  373.         desc.params->ConvertFromXML(root);
  374.  
  375.         return true;
  376. }
  377.  
  378. //-----------------------------------------------------------------
  379. const IItemParamsNode* CActorSystem::GetActorParams(const char* actorClass) const
  380. {
  381.         TActorParamsMap::const_iterator it = m_actorParams.find(CONST_TEMP_STRING(actorClass));
  382.         if (it != m_actorParams.end())
  383.         {
  384.                 return it->second.params;
  385.         }
  386.  
  387.         return 0;
  388. }
  389.  
  390. //-----------------------------------------------------------------
  391. bool CActorSystem::IsActorClass(IEntityClass* pClass) const
  392. {
  393.         bool bResult = false;
  394.  
  395.         TActorClassMap::const_iterator itClass = m_classes.begin();
  396.         TActorClassMap::const_iterator itClassEnd = m_classes.end();
  397.         for (; !bResult && itClass != itClassEnd; ++itClass)
  398.         {
  399.                 const SActorClassDesc& classDesc = itClass->second;
  400.                 bResult = (pClass == classDesc.pEntityClass);
  401.         }
  402.  
  403.         return bResult;
  404. }
  405.  
  406. //------------------------------------------------------------------------
  407. bool CActorSystem::OnBeforeSpawn(SEntitySpawnParams& params)
  408. {
  409.         return true;  // nothing else (but needed to implement IEntitySystemSink)
  410. }
  411.  
  412. //------------------------------------------------------------------------
  413. void CActorSystem::OnSpawn(IEntity* pEntity, SEntitySpawnParams& params)
  414. {
  415.         // nothing (but needed to implement IEntitySystemSink)
  416. }
  417.  
  418. //------------------------------------------------------------------------
  419. bool CActorSystem::OnRemove(IEntity* pEntity)
  420. {
  421.         return true;  // nothing else (but needed to implement IEntitySystemSink)
  422. }
  423.  
  424. //------------------------------------------------------------------------
  425. void CActorSystem::OnReused(IEntity* pEntity, SEntitySpawnParams& params)
  426. {
  427.         for (TActorMap::const_iterator it = m_actors.begin(); it != m_actors.end(); ++it)
  428.         {
  429.                 IActor* actor = it->second;
  430.                 IEntity* ent = actor->GetEntity();
  431.  
  432.                 if (ent && ent == pEntity)
  433.                 {
  434.                         actor->OnReused(pEntity, params);
  435.                 }
  436.         }
  437. }
  438.  
  439. //------------------------------------------------------------------------
  440. void CActorSystem::OnEvent(IEntity* pEntity, SEntityEvent& event)
  441. {
  442.         // nothing (but needed to implement IEntitySystemSink)
  443. }
  444.  
  445. //------------------------------------------------------------------------
  446. void CActorSystem::GetMemoryUsage(class ICrySizer* pSizer) const
  447. {
  448.         pSizer->Add(sizeof *this);
  449. }
  450.  
  451. IActorIteratorPtr CActorSystem::CreateActorIterator()
  452. {
  453.         if (m_iteratorPool.empty())
  454.         {
  455.                 return new CActorIterator(this);
  456.         }
  457.         else
  458.         {
  459.                 CActorIterator* pIter = m_iteratorPool.back();
  460.                 m_iteratorPool.pop_back();
  461.                 new(pIter) CActorIterator(this);
  462.                 return pIter;
  463.         }
  464. }
  465.  
  466. void CActorSystem::ActorSystemErrorMessage(const char* fileName, const char* errorInfo, bool displayErrorDialog)
  467. {
  468.         if ((fileName == NULL) || (errorInfo == NULL))
  469.                 return;
  470.  
  471.         CryFixedStringT<1024> messageBuffer;
  472.         messageBuffer.Format("ERROR: Failed to load '%s'. Required data missing, which could lead to un-expected game behavior or crashes. ( %s )", fileName, errorInfo);
  473.  
  474.         CryLogAlways("%s", messageBuffer.c_str());
  475.  
  476.         if (displayErrorDialog)
  477.         {
  478.                 gEnv->pSystem->ShowMessage(messageBuffer.c_str(), "Error", eMB_Error);
  479.         }
  480. }
  481.  
  482. void CActorSystem::GetMemoryStatistics(ICrySizer* pSizer)
  483. {
  484.         SIZER_SUBCOMPONENT_NAME(pSizer, "ActorSystem");
  485.         pSizer->AddObject(this, sizeof(*this));
  486.         pSizer->AddObject(m_actors);
  487. }
  488.  
downloadActorSystem.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