BVB Source Codes

CRYENGINE Show EquipmentManager.cpp Source code

Return Download CRYENGINE: download EquipmentManager.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // -------------------------------------------------------------------------
  4. //  File name:   EquipmentManager.cpp
  5. //  Version:     v1.00
  6. //  Created:     07/07/2006 by AlexL
  7. //  Compilers:   Visual Studio.NET
  8. //  Description: EquipmentManager to handle item packs
  9. // -------------------------------------------------------------------------
  10. //  History:
  11. //
  12. ////////////////////////////////////////////////////////////////////////////
  13.  
  14. #include "StdAfx.h"
  15. #include "EquipmentManager.h"
  16. #include "ItemSystem.h"
  17. #include "IActorSystem.h"
  18. #include "Inventory.h"
  19.  
  20. namespace
  21. {
  22. void DumpPacks(IConsoleCmdArgs* pArgs)
  23. {
  24.         CEquipmentManager* pMgr = static_cast<CEquipmentManager*>(CCryAction::GetCryAction()->GetIItemSystem()->GetIEquipmentManager());
  25.         if (pMgr)
  26.         {
  27.                 pMgr->DumpPacks();
  28.         }
  29. }
  30.  
  31. bool InitConsole()
  32. {
  33.         REGISTER_COMMAND("eqp_DumpPacks", DumpPacks, VF_NULL, "Prints all equipment pack information to console");
  34.         return true;
  35. }
  36.  
  37. bool ShutdownConsole()
  38. {
  39.         gEnv->pConsole->RemoveCommand("eqp_DumpPacks");
  40.         return true;
  41. }
  42. };
  43.  
  44. // helper class to make sure begin and end callbacks get called correctly
  45. struct CGiveEquipmentPackNotifier
  46. {
  47.         CEquipmentManager* pEM;
  48.  
  49.         CGiveEquipmentPackNotifier(CEquipmentManager* pEM_, IActor* pActor) : pEM(pEM_){ if (pEM && pActor->IsClient()) pEM->OnBeginGiveEquipmentPack(); }
  50.         ~CGiveEquipmentPackNotifier() { if (pEM) pEM->OnEndGiveEquipmentPack(); }
  51. };
  52.  
  53. CEquipmentManager::CEquipmentManager(CItemSystem* pItemSystem)
  54.         : m_pItemSystem(pItemSystem)
  55. {
  56.         static bool sInitVars(InitConsole());
  57. }
  58.  
  59. CEquipmentManager::~CEquipmentManager()
  60. {
  61.         ShutdownConsole();
  62. }
  63.  
  64. void CEquipmentManager::Reset()
  65. {
  66.         stl::free_container(m_listeners);
  67. }
  68.  
  69. // Clear all equipment packs
  70. void CEquipmentManager::DeleteAllEquipmentPacks()
  71. {
  72.         std::for_each(m_equipmentPacks.begin(), m_equipmentPacks.end(), stl::container_object_deleter());
  73.         m_equipmentPacks.clear();
  74. }
  75.  
  76. // Loads equipment packs from rootNode
  77. void CEquipmentManager::LoadEquipmentPacks(const XmlNodeRef& rootNode)
  78. {
  79.         MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Other, 0, "Equipment Packs");
  80.  
  81.         if (rootNode->isTag("EquipPacks") == false)
  82.                 return;
  83.  
  84.         for (int i = 0; i < rootNode->getChildCount(); ++i)
  85.         {
  86.                 XmlNodeRef packNode = rootNode->getChild(i);
  87.                 LoadEquipmentPack(packNode, true);
  88.         }
  89. }
  90.  
  91. // Load all equipment packs from a certain folder
  92. void CEquipmentManager::LoadEquipmentPacksFromPath(const char* path)
  93. {
  94.         MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Other, 0, "Equipment Packs");
  95.  
  96.         ICryPak* pCryPak = gEnv->pCryPak;
  97.         _finddata_t fd;
  98.         string realPath(path);
  99.         realPath.TrimRight("/\\");
  100.         string search(realPath);
  101.         search += "/*.xml";
  102.  
  103.         intptr_t handle = pCryPak->FindFirst(search.c_str(), &fd);
  104.         if (handle != -1)
  105.         {
  106.                 do
  107.                 {
  108.                         // fd.name contains the profile name
  109.                         string filename = path;
  110.                         filename += "/";
  111.                         filename += fd.name;
  112.  
  113.                         MEMSTAT_CONTEXT_FMT(EMemStatContextTypes::MSC_Other, 0, "EquipmentPack XML (%s)", filename.c_str());
  114.  
  115.                         XmlNodeRef rootNode = gEnv->pSystem->LoadXmlFromFile(filename.c_str());
  116.  
  117.                         // load from XML node
  118.                         const bool ok = rootNode ? LoadEquipmentPack(rootNode) : false;
  119.                         if (!ok)
  120.                         {
  121.                                 GameWarning("[EquipmentMgr]: Cannot load XML file '%s'. Skipping.", filename.c_str());
  122.                         }
  123.                 }
  124.                 while (pCryPak->FindNext(handle, &fd) >= 0);
  125.  
  126.                 pCryPak->FindClose(handle);
  127.         }
  128. }
  129.  
  130. // Load an equipment pack from an XML node
  131. bool CEquipmentManager::LoadEquipmentPack(const XmlNodeRef& rootNode, bool bOverrideExisting)
  132. {
  133.         if (rootNode->isTag("EquipPack") == false)
  134.                 return false;
  135.  
  136.         const char* packName = rootNode->getAttr("name");
  137.         const char* primaryName = rootNode->getAttr("primary");
  138.  
  139.         if (!packName || packName[0] == 0)
  140.                 return false;
  141.  
  142.         // re-use existing pack
  143.         SEquipmentPack* pPack = GetPack(packName);
  144.         if (pPack == 0)
  145.         {
  146.                 pPack = new SEquipmentPack;
  147.                 m_equipmentPacks.push_back(pPack);
  148.         }
  149.         else if (bOverrideExisting == false)
  150.                 return false;
  151.  
  152.         pPack->Init(packName);
  153.  
  154.         for (int iChild = 0; iChild < rootNode->getChildCount(); ++iChild)
  155.         {
  156.                 const XmlNodeRef childNode = rootNode->getChild(iChild);
  157.                 if (childNode == 0)
  158.                         continue;
  159.  
  160.                 if (childNode->isTag("Items"))
  161.                 {
  162.                         pPack->PrepareForItems(childNode->getChildCount());
  163.                         for (int i = 0; i < childNode->getChildCount(); ++i)
  164.                         {
  165.                                 XmlNodeRef itemNode = childNode->getChild(i);
  166.                                 const char* itemName = itemNode->getTag();
  167.                                 const char* itemType = itemNode->getAttr("type");
  168.                                 const char* itemSetup = itemNode->getAttr("setup");
  169.                                 pPack->AddItem(itemName, itemType, itemSetup);
  170.                         }
  171.                 }
  172.                 else if (childNode->isTag("Ammo")) // legacy
  173.                 {
  174.                         const char* ammoName = "";
  175.                         const char* ammoCount = "";
  176.                         int nAttr = childNode->getNumAttributes();
  177.                         for (int j = 0; j < nAttr; ++j)
  178.                         {
  179.                                 if (childNode->getAttributeByIndex(j, &ammoName, &ammoCount))
  180.                                 {
  181.                                         int nAmmoCount = atoi(ammoCount);
  182.                                         pPack->m_ammoCount[ammoName] = nAmmoCount;
  183.                                 }
  184.                         }
  185.                 }
  186.                 else if (childNode->isTag("Ammos"))
  187.                 {
  188.                         for (int i = 0; i < childNode->getChildCount(); ++i)
  189.                         {
  190.                                 XmlNodeRef ammoNode = childNode->getChild(i);
  191.                                 if (ammoNode->isTag("Ammo") == false)
  192.                                         continue;
  193.                                 const char* ammoName = ammoNode->getAttr("name");
  194.                                 if (ammoName == 0 || ammoName[0] == '\0')
  195.                                         continue;
  196.                                 int nAmmoCount = 0;
  197.                                 ammoNode->getAttr("amount", nAmmoCount);
  198.                                 pPack->m_ammoCount[ammoName] = nAmmoCount;
  199.                         }
  200.                 }
  201.         }
  202.         // assign primary.
  203.         if (pPack->HasItem(primaryName))
  204.                 pPack->m_primaryItem = primaryName;
  205.         else
  206.                 pPack->m_primaryItem = "";
  207.  
  208.         return true;
  209. }
  210.  
  211. // Give an equipment pack (resp. items/ammo) to an actor
  212. bool CEquipmentManager::GiveEquipmentPack(IActor* pActor, const char* packName, bool bAdd, bool selectPrimary)
  213. {
  214.         if (!pActor)
  215.                 return false;
  216.  
  217.         // causes side effects, don't remove
  218.         CGiveEquipmentPackNotifier notifier(this, pActor);
  219.  
  220.         SEquipmentPack* pPack = GetPack(packName);
  221.  
  222.         if (pPack == 0)
  223.         {
  224.                 const IEntity* pEntity = pActor->GetEntity();
  225.                 GameWarning("[EquipmentMgr]: Cannot give pack '%s' to Actor '%s'. Pack not found.", packName, pEntity ? pEntity->GetName() : "<unnamed>");
  226.                 return false;
  227.         }
  228.  
  229.         IInventory* pInventory = pActor->GetInventory();
  230.         if (pInventory == 0)
  231.         {
  232.                 const IEntity* pEntity = pActor->GetEntity();
  233.                 GameWarning("[EquipmentMgr]: Cannot give pack '%s' to Actor '%s'. No inventory.", packName, pEntity ? pEntity->GetName() : "<unnamed>");
  234.                 return false;
  235.         }
  236.  
  237.         bool bHasNoWeapon = false;
  238.         bool bHasAnySelected = false;
  239.         const char* strNoWeapon = "NoWeapon";
  240.  
  241.         if (bAdd == false)
  242.         {
  243.                 IItem* pItem = m_pItemSystem->GetItem(pInventory->GetCurrentItem());
  244.                 if (pItem)
  245.                 {
  246.                         pItem->Select(false);
  247.                         m_pItemSystem->SetActorItem(pActor, (EntityId)0, false);
  248.                 }
  249.                 pInventory->RemoveAllItems(true);
  250.                 pInventory->ResetAmmo();
  251.         }
  252.         else
  253.         {
  254.                 // Since we're adding items, check on the current status of NoWeapon
  255.                 bHasNoWeapon = pInventory->GetCountOfClass(strNoWeapon) > 0;
  256.         }
  257.  
  258.         std::vector<SEquipmentPack::SEquipmentItem>::const_iterator itemIter = pPack->m_items.begin();
  259.         std::vector<SEquipmentPack::SEquipmentItem>::const_iterator itemIterEnd = pPack->m_items.end();
  260.  
  261.         for (; itemIter != itemIterEnd; ++itemIter)
  262.         {
  263.                 const SEquipmentPack::SEquipmentItem& item = *itemIter;
  264.  
  265.                 // If the equipmentPack specifies a primary weapon then select this item if it's the specified item, if
  266.                 // the equipmentPack doesn't specify a primary weapon then just select the first item of the set (fallback)
  267.                 bool bPrimaryItem = (itemIter == pPack->m_items.begin());
  268.                 if (!pPack->m_primaryItem.empty())
  269.                         bPrimaryItem = (pPack->m_primaryItem.compare(item.m_name) == 0);
  270.  
  271.                 EntityId itemId = m_pItemSystem->GiveItem(pActor, item.m_name, false, bPrimaryItem, true); // don't select
  272.  
  273.                 // Update state of NoWeapon
  274.                 bHasNoWeapon |= (item.m_name == strNoWeapon);
  275.                 bHasAnySelected |= bPrimaryItem;
  276.  
  277.                 if (!item.m_setup.empty())
  278.                 {
  279.                         if (IItem* pItem = m_pItemSystem->GetItem(itemId))
  280.                         {
  281.                                 //remove all current accessories (initial setup in xml) and attach the specified list
  282.                                 pItem->DetachAllAccessories();
  283.  
  284.                                 int numAccessories = item.m_setup.size();
  285.  
  286.                                 for (int i = 0; i < numAccessories; i++)
  287.                                 {
  288.                                         m_pItemSystem->GiveItem(pActor, item.m_setup[i]->GetName(), false, false, false);
  289.                                         pItem->AttachAccessory(item.m_setup[i], true, true, true, true);
  290.                                 }
  291.                         }
  292.                 }
  293.         }
  294.  
  295.         // Handle the case where NoWeapon is not currently in possession of the actor (CE-1290)
  296.         // In this case, give the NoWeapon item anyway, and then select it if nothing else is selected
  297.         if (bHasNoWeapon == false)
  298.         {
  299.                 GameWarning("[EquipmentMgr]: The pack '%s' does not contain '%s', given it anyway because it's required.", packName, strNoWeapon);
  300.                 m_pItemSystem->GiveItem(pActor, strNoWeapon, false, !bHasAnySelected);
  301.         }
  302.  
  303.         // Handle ammo
  304.         std::map<string, int>::const_iterator iter = pPack->m_ammoCount.begin();
  305.         std::map<string, int>::const_iterator iterEnd = pPack->m_ammoCount.end();
  306.  
  307.         if (bAdd)
  308.         {
  309.                 while (iter != iterEnd)
  310.                 {
  311.                         if (iter->second > 0)
  312.                         {
  313.                                 IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(iter->first);
  314.                                 if (pClass)
  315.                                 {
  316.                                         const int count = pInventory->GetAmmoCount(pClass) + iter->second;
  317.                                         pInventory->SetAmmoCount(pClass, count);
  318.                                         if (gEnv->bServer)
  319.                                         {
  320.                                                 pActor->GetGameObject()->InvokeRMI(CInventory::Cl_SetAmmoCount(),
  321.                                                                                    TRMIInventory_Ammo(pClass->GetName(), count),
  322.                                                                                    eRMI_ToRemoteClients);
  323.                                         }
  324.                                         /*
  325.                                                   if(IActor* pIventoryActor = pInventory->GetActor())
  326.                                                     if(pIventoryActor->IsClient())
  327.                                                       pIventoryActor->NotifyInventoryAmmoChange(pClass, iter->second);
  328.                                          */
  329.                                 }
  330.                                 else
  331.                                 {
  332.                                         GameWarning("[EquipmentMgr]: Invalid AmmoType '%s' in Pack '%s'.", iter->first.c_str(), packName);
  333.                                 }
  334.                         }
  335.                         ++iter;
  336.                 }
  337.         }
  338.         else
  339.         {
  340.                 while (iter != iterEnd)
  341.                 {
  342.                         if (iter->second > 0)
  343.                         {
  344.                                 IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(iter->first);
  345.                                 if (pClass)
  346.                                 {
  347.                                         pInventory->SetAmmoCount(pClass, iter->second);
  348.                                         /*
  349.                                                   if(IActor* pIventoryActor = pInventory->GetActor())
  350.                                                     if(pIventoryActor->IsClient())
  351.                                                       pIventoryActor->NotifyInventoryAmmoChange(pClass, iter->second);
  352.                                          */
  353.                                 }
  354.                                 else
  355.                                 {
  356.                                         GameWarning("[EquipmentMgr]: Invalid AmmoType '%s' in Pack '%s'.", iter->first.c_str(), packName);
  357.                                 }
  358.                         }
  359.                         ++iter;
  360.                 }
  361.         }
  362.  
  363.         return true;
  364. }
  365.  
  366. CEquipmentManager::SEquipmentPack* CEquipmentManager::GetPack(const char* packName) const
  367. {
  368.         for (TEquipmentPackVec::const_iterator iter = m_equipmentPacks.begin();
  369.              iter != m_equipmentPacks.end(); ++iter)
  370.         {
  371.                 if (stricmp((*iter)->m_name.c_str(), packName) == 0)
  372.                         return *iter;
  373.         }
  374.         return 0;
  375. }
  376.  
  377. void CEquipmentManager::PreCacheEquipmentPackResources(const char* packName, IEquipmentPackPreCacheCallback& preCacheCallback)
  378. {
  379.         SEquipmentPack* pEquipPack = GetPack(packName);
  380.         if (pEquipPack)
  381.         {
  382.                 const int itemCount = pEquipPack->m_items.size();
  383.                 for (int i = 0; i < itemCount; ++i)
  384.                 {
  385.                         const SEquipmentPack::SEquipmentItem& item = pEquipPack->m_items[i];
  386.                         preCacheCallback.PreCacheItemResources(item.m_name.c_str());
  387.  
  388.                         int numSetup = pEquipPack->m_items[i].m_setup.size();
  389.                         for (int j = 0; j < numSetup; j++)
  390.                         {
  391.                                 preCacheCallback.PreCacheItemResources(pEquipPack->m_items[i].m_setup[j]->GetName());
  392.                         }
  393.                 }
  394.         }
  395. }
  396.  
  397. // return iterator with all available equipment packs
  398. IEquipmentManager::IEquipmentPackIteratorPtr
  399. CEquipmentManager::CreateEquipmentPackIterator()
  400. {
  401.         class CEquipmentIterator : public IEquipmentPackIterator
  402.         {
  403.         public:
  404.                 CEquipmentIterator(CEquipmentManager* pMgr)
  405.                 {
  406.                         m_nRefs = 0;
  407.                         m_pMgr = pMgr;
  408.                         m_cur = m_pMgr->m_equipmentPacks.begin();
  409.                 }
  410.                 void AddRef()
  411.                 {
  412.                         ++m_nRefs;
  413.                 }
  414.                 void Release()
  415.                 {
  416.                         if (0 == --m_nRefs)
  417.                                 delete this;
  418.                 }
  419.                 int GetCount()
  420.                 {
  421.                         return m_pMgr->m_equipmentPacks.size();
  422.                 }
  423.                 const char* Next()
  424.                 {
  425.                         const char* name = 0;
  426.                         if (m_cur != m_end)
  427.                         {
  428.                                 name = (*m_cur)->m_name.c_str();
  429.                                 ++m_cur;
  430.                         }
  431.                         return name;
  432.                 }
  433.                 int                         m_nRefs;
  434.                 CEquipmentManager*          m_pMgr;
  435.                 TEquipmentPackVec::iterator m_cur;
  436.                 TEquipmentPackVec::iterator m_end;
  437.         };
  438.         return new CEquipmentIterator(this);
  439. }
  440.  
  441. void CEquipmentManager::RegisterListener(IEquipmentManager::IListener* pListener)
  442. {
  443.         stl::push_back_unique(m_listeners, pListener);
  444. }
  445.  
  446. void CEquipmentManager::UnregisterListener(IEquipmentManager::IListener* pListener)
  447. {
  448.         stl::find_and_erase(m_listeners, pListener);
  449. }
  450.  
  451. void CEquipmentManager::OnBeginGiveEquipmentPack()
  452. {
  453.         TListenerVec::iterator iter = m_listeners.begin();
  454.         while (iter != m_listeners.end())
  455.         {
  456.                 (*iter)->OnBeginGiveEquipmentPack();
  457.                 ++iter;
  458.         }
  459. }
  460.  
  461. void CEquipmentManager::OnEndGiveEquipmentPack()
  462. {
  463.         TListenerVec::iterator iter = m_listeners.begin();
  464.         while (iter != m_listeners.end())
  465.         {
  466.                 (*iter)->OnEndGiveEquipmentPack();
  467.                 ++iter;
  468.         }
  469. }
  470.  
  471. void CEquipmentManager::DumpPack(const SEquipmentPack* pPack) const
  472. {
  473.         CryLogAlways("Pack: '%s' Primary='%s' ItemCount=%" PRISIZE_T " AmmoCount=%" PRISIZE_T,
  474.                      pPack->m_name.c_str(), pPack->m_primaryItem.c_str(), pPack->m_items.size(), pPack->m_ammoCount.size());
  475.  
  476.         CryLogAlways("   Items:");
  477.         for (std::vector<SEquipmentPack::SEquipmentItem>::const_iterator iter = pPack->m_items.begin();
  478.              iter != pPack->m_items.end(); ++iter)
  479.         {
  480.                 CryLogAlways("   '%s' : '%s'", iter->m_name.c_str(), iter->m_type.c_str());
  481.  
  482.                 int numAccessories = iter->m_setup.size();
  483.  
  484.                 for (int i = 0; i < numAccessories; i++)
  485.                 {
  486.                         CryLogAlways("                  Accessory: '%s'", iter->m_setup[i]->GetName());
  487.                 }
  488.         }
  489.  
  490.         CryLogAlways("   Ammo:");
  491.         for (std::map<string, int>::const_iterator iter = pPack->m_ammoCount.begin();
  492.              iter != pPack->m_ammoCount.end(); ++iter)
  493.         {
  494.                 CryLogAlways("   '%s'=%d", iter->first.c_str(), iter->second);
  495.         }
  496. }
  497.  
  498. void CEquipmentManager::DumpPacks()
  499. {
  500.         // all sessions
  501.         CryLogAlways("[EQP] PackCount=%" PRISIZE_T, m_equipmentPacks.size());
  502.         for (TEquipmentPackVec::const_iterator iter = m_equipmentPacks.begin();
  503.              iter != m_equipmentPacks.end(); ++iter)
  504.         {
  505.                 const SEquipmentPack* pPack = *iter;
  506.                 DumpPack(pPack);
  507.         }
  508. }
  509.  
  510. void CEquipmentManager::GetMemoryUsage(ICrySizer* pSizer) const
  511. {
  512.         SIZER_SUBCOMPONENT_NAME(pSizer, "EquipmentManager");
  513.         pSizer->AddObject(this, sizeof(*this));
  514.         pSizer->AddObject(m_equipmentPacks);
  515. }
  516.  
downloadEquipmentManager.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