BVB Source Codes

CRYENGINE Show ItemSystem.cpp Source code

Return Download CRYENGINE: download ItemSystem.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.    - 29:9:2004   18:02 : Created by Mrcio Martins
  11.  
  12.  *************************************************************************/
  13. #include "StdAfx.h"
  14. #include "ItemSystem.h"
  15. #include <CryString/CryPath.h>
  16. //#include "ScriptBind_ItemSystem.h"
  17. #include "IActionMapManager.h"
  18. #include "GameObjects/GameObject.h"
  19. #include "CryAction.h"
  20. #include "IGameObjectSystem.h"
  21. #include "IActorSystem.h"
  22.  
  23. #include <CryEntitySystem/IEntitySystem.h>
  24. #include <CryAnimation/ICryAnimation.h>
  25. #include <IVehicleSystem.h>
  26. #include "ItemParams.h"
  27. #include "EquipmentManager.h"
  28. #include "CryActionCVars.h"
  29.  
  30. #include "IGameRulesSystem.h"
  31.  
  32. ICVar* CItemSystem::m_pPrecache = 0;
  33. ICVar* CItemSystem::m_pItemLimitMP = 0;
  34. ICVar* CItemSystem::m_pItemLimitSP = 0;
  35.  
  36. //This is used for AI offhands, if we want more classes, perhaps it's better
  37. //if every class can specify the size of its shared pool
  38. #define ITEM_SHARED_POOL_MAX_SIZE 5
  39.  
  40. //------------------------------------------------------------------------
  41.  
  42. #if !defined(_RELEASE)
  43. // Auto complete for i_giveitem cmd.
  44. struct SItemListAutoComplete : public IConsoleArgumentAutoComplete
  45. {
  46.         // Gets number of matches for the argument to auto complete.
  47.         virtual int GetCount() const
  48.         {
  49.                 IGameFramework* pGameFramework = gEnv->pGameFramework;
  50.                 IItemSystem* pItemSystem = pGameFramework->GetIItemSystem();
  51.                 return pItemSystem->GetItemParamsCount();
  52.         }
  53.  
  54.         // Gets argument value by index, nIndex must be in 0 <= nIndex < GetCount()
  55.         virtual const char* GetValue(int nIndex) const
  56.         {
  57.                 IGameFramework* pGameFramework = gEnv->pGameFramework;
  58.                 IItemSystem* pItemSystem = pGameFramework->GetIItemSystem();
  59.                 return pItemSystem->GetItemParamName(nIndex);
  60.         }
  61. };
  62.  
  63. static SItemListAutoComplete s_itemListAutoComplete;
  64. #endif // !defined(_RELEASE)
  65.  
  66. //------------------------------------------------------------------------
  67. CItemSystem::CItemSystem(IGameFramework* pGameFramework, ISystem* pSystem)
  68.         : m_pGameFramework(pGameFramework),
  69.         m_pSystem(pSystem),
  70.         m_pEntitySystem(gEnv->pEntitySystem),
  71.         m_spawnCount(0),
  72.         m_precacheTime(0.0f),
  73.         m_reloading(false),
  74.         m_recursing(false),
  75.         m_listeners(2)
  76. {
  77. #ifndef USE_LTL_PRECACHING
  78.         m_itemParamsFlushed = false;
  79. #else
  80.         m_itemParamsFlushed = true;
  81.         m_LTLPrecacheState = LTLCS_FORSAVEGAME; // sanity. Irrelevant as the list is empty anyway at this point
  82. #endif
  83.  
  84.         RegisterCVars();
  85.         m_pEquipmentManager = new CEquipmentManager(this);
  86.         m_itemClassIterator = m_params.begin();
  87. }
  88.  
  89. //------------------------------------------------------------------------
  90. CItemSystem::~CItemSystem()
  91. {
  92.         SAFE_DELETE(m_pEquipmentManager);
  93.         UnregisterCVars();
  94.  
  95.         ClearGeometryCache();
  96.         ClearSoundCache();
  97. }
  98.  
  99. //------------------------------------------------------------------------
  100. void CItemSystem::OnLoadingStart(ILevelInfo* pLevelInfo)
  101. {
  102.         Reset();
  103.  
  104.         ClearGeometryCache();
  105.         ClearSoundCache();
  106. }
  107.  
  108. //------------------------------------------------------------------------
  109. void CItemSystem::OnLoadingComplete(ILevelInfo* pLevel)
  110. {
  111.         // marcio: precaching of items enabled by default for now
  112.         //      ICVar *sys_preload=gEnv->pConsole->GetCVar("sys_preload");
  113.         //      if ((!sys_preload || sys_preload->GetIVal()) && m_pPrecache->GetIVal())
  114.         {
  115.                 PrecacheLevel();
  116.         }
  117. }
  118.  
  119. //------------------------------------------------------------------------
  120. void CItemSystem::OnUnloadComplete(ILevelInfo* pLevel)
  121. {
  122.         m_listeners.Clear(true);
  123. #ifdef USE_LTL_PRECACHING
  124.         if (m_LTLPrecacheState == LTLCS_FORSAVEGAME)
  125.                 m_precacheLevelToLevelItemList.clear(); // just for sanity reasons.
  126. #endif
  127. }
  128.  
  129. //------------------------------------------------------------------------
  130. void CItemSystem::RegisterItemClass(const char* name, IGameFramework::IItemCreator* pCreator)
  131. {
  132.         m_classes.insert(TItemClassMap::value_type(name, SItemClassDesc(pCreator)));
  133. }
  134.  
  135. //------------------------------------------------------------------------
  136. void CItemSystem::Update()
  137. {
  138.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  139.  
  140.         ITimer* pTimer = gEnv->pTimer;
  141.         IActor* pActor = m_pGameFramework->GetClientActor();
  142.  
  143.         if (pActor)
  144.         {
  145.                 IInventory* pInventory = pActor->GetInventory();
  146.                 if (pInventory)
  147.                 {
  148.                         IItem* pCurrentItem = GetItem(pInventory->GetCurrentItem());
  149.                         if (pCurrentItem && pCurrentItem->IsSelected())
  150.                                 pCurrentItem->UpdateFPView(pTimer->GetFrameTime());
  151.  
  152.                         IItem* pLastItem = GetItem(pInventory->GetLastItem());
  153.                         if (pLastItem && pLastItem != pCurrentItem && pLastItem->IsSelected())
  154.                                 pLastItem->UpdateFPView(pTimer->GetFrameTime());
  155.  
  156.                         // marcok: argh ... we depend on Crysis game stuff here ... REMOVE
  157.                         IEntityClass* pOffHandClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("OffHand");
  158.                         IItem* pOffHandItem = GetItem(pInventory->GetItemByClass(pOffHandClass));
  159.  
  160.                         // HAX: update offhand - shouldn't be here
  161.                         if (pOffHandItem)
  162.                                 pOffHandItem->UpdateFPView(pTimer->GetFrameTime());
  163.                 }
  164.         }
  165.  
  166.         if (CCryActionCVars::Get().debugItemMemStats != 0)
  167.         {
  168.                 DisplayItemSystemStats();
  169.         }
  170.  
  171. }
  172.  
  173. //------------------------------------------------------------------------
  174. const IItemParamsNode* CItemSystem::GetItemParams(const char* itemName) const
  175. {
  176.         TItemParamsMap::const_iterator it = m_params.find(CONST_TEMP_STRING(itemName));
  177.         if (it != m_params.end())
  178.         {
  179.                 if (m_config.empty())
  180.                 {
  181.                         return it->second.params;
  182.                 }
  183.  
  184.                 std::map<string, CItemParamsNode*>::const_iterator cit = it->second.configurations.find(m_config);
  185.                 if (cit != it->second.configurations.end())
  186.                 {
  187.                         return cit->second;
  188.                 }
  189.  
  190.                 return it->second.params;
  191.         }
  192.  
  193.         GameWarning("Trying to get xml description for item '%s'! Something very wrong has happened!", itemName);
  194.         return 0;
  195. }
  196.  
  197. //------------------------------------------------------------------------
  198. uint8 CItemSystem::GetItemPriority(const char* itemName) const
  199. {
  200.         TItemParamsMap::const_iterator it = m_params.find(CONST_TEMP_STRING(itemName));
  201.         if (it != m_params.end())
  202.                 return it->second.priority;
  203.  
  204.         GameWarning("Trying to get priority for item '%s'! Something very wrong has happened!", itemName);
  205.         return 0;
  206. }
  207.  
  208. //------------------------------------------------------------------------
  209. const char* CItemSystem::GetItemCategory(const char* itemName) const
  210. {
  211.         TItemParamsMap::const_iterator it = m_params.find(CONST_TEMP_STRING(itemName));
  212.         if (it != m_params.end())
  213.                 return it->second.category.c_str();
  214.  
  215.         GameWarning("Trying to get category for item '%s'! Something very wrong has happened!", itemName);
  216.         return 0;
  217. }
  218.  
  219. //-------------------------------------------------------------------------
  220. uint8 CItemSystem::GetItemUniqueId(const char* itemName) const
  221. {
  222.         TItemParamsMap::const_iterator it = m_params.find(CONST_TEMP_STRING(itemName));
  223.         if (it != m_params.end())
  224.                 return it->second.uniqueId;
  225.  
  226.         GameWarning("Trying to get uniqueId for item '%s'! Something very wrong has happened!", itemName);
  227.         return 0;
  228. }
  229.  
  230. //------------------------------------------------------------------------
  231. bool CItemSystem::IsItemClass(const char* name) const
  232. {
  233.         TItemParamsMap::const_iterator it = m_params.find(CONST_TEMP_STRING(name));
  234.         return (it != m_params.end());
  235. }
  236.  
  237. //------------------------------------------------------------------------
  238. const char* CItemSystem::GetFirstItemClass()
  239. {
  240.         m_itemClassIterator = m_params.begin();
  241.  
  242.         if (m_itemClassIterator != m_params.end())
  243.                 return m_itemClassIterator->first;
  244.         return 0;
  245. }
  246.  
  247. //------------------------------------------------------------------------
  248. const char* CItemSystem::GetNextItemClass()
  249. {
  250.         if (m_itemClassIterator != m_params.end())
  251.         {
  252.                 ++m_itemClassIterator;
  253.                 if (m_itemClassIterator != m_params.end())
  254.                         return m_itemClassIterator->first;
  255.         }
  256.         return 0;
  257. }
  258.  
  259. //------------------------------------------------------------------------
  260. void CItemSystem::RegisterForCollection(EntityId itemId)
  261. {
  262. #if _DEBUG
  263.         IItem* pItem = GetItem(itemId);
  264.         CRY_ASSERT(pItem);
  265.  
  266.         if (pItem)
  267.         {
  268.                 CRY_ASSERT(!pItem->GetOwnerId());
  269.         }
  270. #endif
  271.  
  272.         CTimeValue now = gEnv->pTimer->GetFrameStartTime();
  273.  
  274.         TCollectionMap::iterator cit = m_collectionmap.find(itemId);
  275.         if (cit == m_collectionmap.end())
  276.                 m_collectionmap.insert(TCollectionMap::value_type(itemId, now));
  277.         else
  278.                 cit->second = now;
  279.  
  280.         if (gEnv->bServer)
  281.         {
  282.                 int limit = 0;
  283.                 const ICVar* pItemLimit = gEnv->bMultiplayer ? m_pItemLimitMP : m_pItemLimitSP;
  284.                 if (pItemLimit)
  285.                         limit = pItemLimit->GetIVal();
  286.  
  287.                 if (limit > 0)
  288.                 {
  289.                         int size = (int)m_collectionmap.size();
  290.                         if (size > limit)
  291.                         {
  292.                                 EntityId nItemId = 0;
  293.                                 for (TCollectionMap::const_iterator it = m_collectionmap.begin(); it != m_collectionmap.end(); ++it)
  294.                                 {
  295.                                         if (it->second < now)
  296.                                         {
  297.                                                 now = it->second;
  298.                                                 nItemId = it->first;
  299.                                         }
  300.                                 }
  301.  
  302.                                 if (IItem* pItem = GetItem(nItemId))
  303.                                 {
  304.                                         CRY_ASSERT(!pItem->GetOwnerId());
  305.  
  306.                                         CryLogAlways("[game] Removing item %s due to i_lying_item_limit!", pItem->GetEntity()->GetName());
  307.                                         UnregisterForCollection(nItemId);
  308.                                         gEnv->pEntitySystem->RemoveEntity(nItemId);
  309.                                 }
  310.                         }
  311.                 }
  312.         }
  313. }
  314.  
  315. //------------------------------------------------------------------------
  316. void CItemSystem::UnregisterForCollection(EntityId itemId)
  317. {
  318.         stl::member_find_and_erase(m_collectionmap, itemId);
  319. }
  320.  
  321. //------------------------------------------------------------------------
  322. void CItemSystem::Reload()
  323. {
  324.         m_reloading = true;
  325.  
  326.         m_params.clear();
  327.  
  328.         for (TFolderList::iterator fit = m_folders.begin(); fit != m_folders.end(); ++fit)
  329.                 Scan(fit->c_str());
  330.  
  331.         SEntityEvent event(ENTITY_EVENT_RESET);
  332.  
  333.         for (TItemMap::iterator it = m_items.begin(); it != m_items.end(); ++it)
  334.         {
  335.                 IEntity* pEntity = m_pEntitySystem->GetEntity(it->first);
  336.                 if (pEntity)
  337.                         pEntity->SendEvent(event);
  338.         }
  339.  
  340.         m_reloading = false;
  341. }
  342.  
  343. //------------------------------------------------------------------------
  344. void CItemSystem::PreReload()
  345. {
  346.         m_reloading = true;
  347.  
  348.         m_params.clear();
  349.  
  350.         for (TFolderList::iterator fit = m_folders.begin(); fit != m_folders.end(); ++fit)
  351.                 Scan(fit->c_str());
  352.  
  353.         for (TItemMap::iterator it = m_items.begin(); it != m_items.end(); ++it)
  354.         {
  355.                 IItem* pItem = it->second;
  356.                 if (pItem)
  357.                         pItem->PreResetParams();
  358.         }
  359. }
  360.  
  361. //------------------------------------------------------------------------
  362. void CItemSystem::PostReload()
  363. {
  364.         SEntityEvent event(ENTITY_EVENT_RESET);
  365.  
  366.         for (TItemMap::iterator it = m_items.begin(); it != m_items.end(); ++it)
  367.         {
  368.                 IItem* pItem = it->second;
  369.                 if (pItem)
  370.                         pItem->ResetParams();
  371.         }
  372.  
  373.         for (TItemMap::iterator it = m_items.begin(); it != m_items.end(); ++it)
  374.         {
  375.                 IEntity* pEntity = m_pEntitySystem->GetEntity(it->first);
  376.                 if (pEntity)
  377.                         pEntity->SendEvent(event);
  378.         }
  379.  
  380.         m_reloading = false;
  381. }
  382.  
  383. //------------------------------------------------------------------------
  384. void CItemSystem::Reset()
  385. {
  386.         if (GetISystem()->IsSerializingFile() == 1)
  387.         {
  388.                 IEntitySystem* pEntitySystem = gEnv->pEntitySystem;
  389.                 TItemMap::iterator it = m_items.begin();
  390.                 TItemMap::iterator endIt = m_items.end();
  391.  
  392.                 for (; it != endIt; )
  393.                 {
  394.                         EntityId id = it->first;
  395.                         IEntity* pEntity = pEntitySystem->GetEntity(id);
  396.                         it->second->Reset();
  397.  
  398.                         if (!pEntity)
  399.                         {
  400.                                 TItemMap::iterator here = it++;
  401.                                 m_items.erase(here);
  402.                         }
  403.                         else
  404.                         {
  405.                                 ++it;
  406.                         }
  407.                 }
  408.         }
  409.  
  410.         m_pEquipmentManager->Reset();
  411. }
  412.  
  413. //------------------------------------------------------------------------
  414. void CItemSystem::Scan(const char* folderName)
  415. {
  416.         string folder = folderName;
  417.         string search = folder;
  418.         search += "/*.*";
  419.  
  420.         ICryPak* pPak = gEnv->pCryPak;
  421.  
  422.         _finddata_t fd;
  423.         intptr_t handle = pPak->FindFirst(search.c_str(), &fd);
  424.  
  425.         INDENT_LOG_DURING_SCOPE(!m_recursing, "Scanning '%s' for item files...", folderName);
  426.  
  427.         if (!m_recursing)
  428.                 CryComment("Loading item XML definitions from '%s'!", folderName);
  429.  
  430.         if (handle > -1)
  431.         {
  432.                 do
  433.                 {
  434.                         if (!strcmp(fd.name, ".") || !strcmp(fd.name, ".."))
  435.                                 continue;
  436.  
  437.                         if (fd.attrib & _A_SUBDIR)
  438.                         {
  439.                                 string subName = folder + "/" + fd.name;
  440.                                 if (m_recursing)
  441.                                         Scan(subName.c_str());
  442.                                 else
  443.                                 {
  444.                                         m_recursing = true;
  445.                                         Scan(subName.c_str());
  446.                                         m_recursing = false;
  447.                                 }
  448.                                 continue;
  449.                         }
  450.  
  451.                         const char* fileExtension = PathUtil::GetExt(fd.name);
  452.                         if (stricmp(fileExtension, "xml"))
  453.                         {
  454.                                 if (stricmp(fileExtension, "binxml"))
  455.                                         GameWarning("ItemSystem: File '%s' does not have 'xml' extension, skipping.", fd.name);
  456.  
  457.                                 continue;
  458.                         }
  459.  
  460.                         string xmlFile = folder + string("/") + string(fd.name);
  461.                         XmlNodeRef rootNode = m_pSystem->LoadXmlFromFile(xmlFile.c_str());
  462.  
  463.                         if (!rootNode)
  464.                         {
  465.                                 ItemSystemErrorMessage(xmlFile.c_str(), "Root xml node couldn't be loaded", true);
  466.                                 continue;
  467.                         }
  468.  
  469.                         if (!ScanXML(rootNode, xmlFile.c_str()))
  470.                         {
  471.                                 continue;
  472.                         }
  473.  
  474.                 }
  475.                 while (pPak->FindNext(handle, &fd) >= 0);
  476.         }
  477.  
  478.         if (!m_recursing)
  479.                 CryLog("Finished loading item XML definitions from '%s'!", folderName);
  480.  
  481.         if (!m_reloading && !m_recursing)
  482.         {
  483.                 InsertFolder(folderName);
  484.         }
  485. }
  486.  
  487. //------------------------------------------------------------------------
  488. bool CItemSystem::ScanXML(XmlNodeRef& root, const char* xmlFile)
  489. {
  490.         MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Other, 0, "ItemSystem");
  491.         MEMSTAT_CONTEXT_FMT(EMemStatContextTypes::MSC_Other, 0, "Item XML (%s)", xmlFile);
  492.  
  493.         if (strcmpi(root->getTag(), "item"))
  494.         {
  495.                 // We don't want to report error here, we have other files in the same folder like ammo with different tag
  496.                 return false;
  497.         }
  498.  
  499.         const char* name = root->getAttr("name");
  500.         if (!name)
  501.         {
  502.                 ItemSystemErrorMessage(xmlFile, "Item definition file does not contain attribute 'name'! Skipping...", true);
  503.                 return false;
  504.         }
  505.  
  506.         const char* className = root->getAttr("class");
  507.  
  508.         if (!className)
  509.         {
  510.                 ItemSystemErrorMessage(xmlFile, "Item definition file does not contain attribute 'class'! Skipping...", true);
  511.                 return false;
  512.         }
  513.  
  514.         INDENT_LOG_DURING_SCOPE(true, "Item system parsing '%s' file (name='%s' class='%s')", xmlFile, name, className);
  515.  
  516.         TItemClassMap::iterator it = m_classes.find(CONST_TEMP_STRING(className));
  517.         if (it == m_classes.end())
  518.         {
  519.                 CryFixedStringT<128> errorBuffer;
  520.                 errorBuffer.Format("Unknown item class '%s'! Skipping...", className);
  521.                 ItemSystemErrorMessage(xmlFile, errorBuffer.c_str(), true);
  522.                 return false;
  523.         }
  524.  
  525.         TItemParamsMap::iterator dit = m_params.find(CONST_TEMP_STRING(name));
  526.  
  527.         if (dit == m_params.end())
  528.         {
  529.                 const char* scriptName = root->getAttr("script");
  530.                 IEntityClassRegistry::SEntityClassDesc classDesc;
  531.                 classDesc.sName = name;
  532.                 if (scriptName && scriptName[0])
  533.                         classDesc.sScriptFile = scriptName;
  534.                 else
  535.                 {
  536.                         classDesc.sScriptFile = DEFAULT_ITEM_SCRIPT;
  537.                         CreateItemTable(name);
  538.                 }
  539.  
  540.                 int invisible = 0;
  541.                 root->getAttr("invisible", invisible);
  542.  
  543.                 classDesc.pUserProxyCreateFunc = (IEntityClass::UserProxyCreateFunc)it->second.pCreator;
  544.                 classDesc.flags |= invisible ? ECLF_INVISIBLE : 0;
  545.  
  546.                 if (!m_reloading)
  547.                         CCryAction::GetCryAction()->GetIGameObjectSystem()->RegisterExtension(name, it->second.pCreator, &classDesc);
  548.  
  549.                 std::pair<TItemParamsMap::iterator, bool> result = m_params.insert(TItemParamsMap::value_type(name, SItemParamsDesc()));
  550.                 dit = result.first;
  551.         }
  552.  
  553.         SItemParamsDesc& desc = dit->second;
  554.  
  555. #if 0
  556.         // deprecated and won't compile at all...
  557.         if (!configName || !configName[0])
  558.         {
  559.                 SAFE_RELEASE(desc.params);
  560.  
  561.                 desc.params = new CItemParamsNode();
  562.                 bool filterMP = desc.params->ConvertFromXMLWithFiltering(root, "SP");
  563.  
  564.                 desc.priority = 0;
  565.                 int p = 0;
  566.                 if (desc.params->GetAttribute("priority", p))
  567.                 {
  568.                         desc.priority = (uint8)p;
  569.                 }
  570.                 desc.category = desc.params->GetAttribute("category");
  571.                 desc.uniqueId = 0;
  572.                 int id = 0;
  573.                 if (desc.params->GetAttribute("uniqueId", id))
  574.                 {
  575.                         desc.uniqueId = (uint8)id;
  576.                 }
  577.  
  578.                 if (filterMP)
  579.                 {
  580.                         CItemParamsNode* params = new CItemParamsNode();
  581.                         params->ConvertFromXMLWithFiltering(root, "MP");
  582.                         desc.configurations.insert(std::make_pair<string, CItemParamsNode*>("mp", params));
  583.                 }
  584.         }
  585.         else
  586.         {
  587.                 // to check that a weapon has multiple configuration (we support that for different game modes)
  588.                 //              CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "Non-empty configuration found in \"%s\"!!!", xmlFile);
  589.  
  590.                 CItemParamsNode* params = new CItemParamsNode();
  591.                 params->ConvertFromXML(root);
  592.                 desc.configurations.insert(std::make_pair<string, CItemParamsNode*>(configName, params));
  593.         }
  594. #else
  595.         {
  596.                 CRY_ASSERT(desc.params == NULL);
  597.  
  598.                 int priority = 0;
  599.                 if (root->getAttr("priority", priority))
  600.                 {
  601.                         desc.priority = (uint8)priority;
  602.                 }
  603.                 else
  604.                 {
  605.                         desc.priority = 0;
  606.                 }
  607.  
  608.                 desc.category = root->getAttr("category");
  609.  
  610.                 int uniqueId = 0;
  611.                 if (root->getAttr("uniqueId", uniqueId))
  612.                 {
  613.                         desc.uniqueId = (uint8)uniqueId;
  614.                 }
  615.                 else
  616.                 {
  617.                         desc.uniqueId = 0;
  618.                 }
  619.  
  620.                 desc.filePath = xmlFile;
  621.         }
  622. #endif
  623.  
  624.         return true;
  625. }
  626.  
  627. //------------------------------------------------------------------------
  628. void CItemSystem::AddItem(EntityId itemId, IItem* pItem)
  629. {
  630.         m_items.insert(TItemMap::value_type(itemId, pItem));
  631.  
  632. }
  633.  
  634. //------------------------------------------------------------------------
  635. void CItemSystem::RemoveItem(EntityId itemId, const char* itemName)
  636. {
  637.         stl::member_find_and_erase(m_items, itemId);
  638.         stl::member_find_and_erase(m_collectionmap, itemId);
  639. }
  640.  
  641. //------------------------------------------------------------------------
  642. IItem* CItemSystem::GetItem(EntityId itemId) const
  643. {
  644.         TItemMap::const_iterator it = m_items.find(itemId);
  645.  
  646.         if (it != m_items.end())
  647.         {
  648.                 return it->second;
  649.         }
  650.         return 0;
  651. }
  652.  
  653. //------------------------------------------------------------------------
  654. EntityId CItemSystem::GiveItem(IActor* pActor, const char* item, bool sound, bool select, bool keepHistory, const char* setup, EEntityFlags entityFlags)
  655. {
  656.         if (!gEnv->bServer && !(entityFlags & ENTITY_FLAG_CLIENT_ONLY))
  657.         {
  658.                 GameWarning("Trying to spawn item of class '%s' on a process which is not server!", item);
  659.                 return 0;
  660.         }
  661.  
  662.         if (gEnv->pSystem->IsSerializingFile())
  663.                 return 0;
  664.  
  665.         CRY_ASSERT(item && pActor);
  666.  
  667.         INDENT_LOG_DURING_SCOPE(true, "Giving %s a new item of class %s (sound=%u select=%u keepHistory=%u setup='%s')", pActor->GetEntity()->GetEntityTextDescription().c_str(), item, sound, select, keepHistory, setup ? setup : "N/A");
  668.  
  669.         static char itemName[65];
  670.         cry_sprintf(itemName, "%s%.03u", item, ++m_spawnCount);
  671.         SEntitySpawnParams params;
  672.         params.sName = itemName;
  673.         params.pClass = m_pEntitySystem->GetClassRegistry()->FindClass(item);
  674.         params.nFlags |= (ENTITY_FLAG_NO_PROXIMITY | ENTITY_FLAG_NEVER_NETWORK_STATIC | entityFlags);
  675.         if (!params.pClass)
  676.         {
  677.                 GameWarning("Trying to spawn item of class '%s' which is unknown!", item);
  678.                 return 0;
  679.         }
  680.  
  681.         if (IEntity* pItemEnt = m_pEntitySystem->SpawnEntity(params))
  682.         {
  683.                 EntityId itemEntId = pItemEnt->GetId();
  684.                 IItem* pItem = GetItem(itemEntId);
  685.                 CRY_ASSERT_MESSAGE(pItem, "Just spawned an entity assuming it was an item but it isn't");
  686.                 if (pItem)
  687.                 {
  688.                         // this may remove the entity
  689.                         pItem->PickUp(pActor->GetEntityId(), sound, select, keepHistory, setup);
  690.  
  691.                         //[kirill] make sure AI gets notified about new item
  692.                         if (gEnv->pAISystem)
  693.                         {
  694.                                 if (IAIObject* pActorAI = pActor->GetEntity()->GetAI())
  695.                                         gEnv->pAISystem->SendSignal(SIGNALFILTER_SENDER, 0, "OnUpdateItems", pActorAI);
  696.                         }
  697.  
  698.                         if ((pItemEnt = gEnv->pEntitySystem->GetEntity(itemEntId)) && !pItemEnt->IsGarbage())
  699.                         {
  700.                                 // set properties table to null, since they'll not be used [timur's request]
  701.                                 if (pItemEnt->GetScriptTable())
  702.                                         pItemEnt->GetScriptTable()->SetToNull("Properties");
  703.  
  704.                                 return pItemEnt->GetId();
  705.                         }
  706.                 }
  707.         }
  708.  
  709.         return 0;
  710. }
  711.  
  712. //------------------------------------------------------------------------
  713. void CItemSystem::SetActorItem(IActor* pActor, EntityId itemId, bool keepHistory)
  714. {
  715.         if (!pActor)
  716.                 return;
  717.         IInventory* pInventory = pActor->GetInventory();
  718.         if (!pInventory)
  719.                 return;
  720.  
  721.         EntityId currentItemId = pInventory->GetCurrentItem();
  722.  
  723.         IItem* pItem = GetItem(itemId);
  724.  
  725.         if (currentItemId == itemId)
  726.         {
  727.                 if (keepHistory)
  728.                         pInventory->SetLastItem(currentItemId);
  729.  
  730.                 if (pItem)
  731.                         pItem->Select(true);
  732.                 return;
  733.         }
  734.  
  735.         if (currentItemId)
  736.         {
  737.                 IItem* pCurrentItem = GetItem(currentItemId);
  738.                 if (pCurrentItem)
  739.                 {
  740.                         pInventory->SetCurrentItem(0);
  741.                         pCurrentItem->Select(false);
  742.                         if (keepHistory)
  743.                                 pInventory->SetLastItem(currentItemId);
  744.                 }
  745.         }
  746.  
  747.         for (TListeners::Notifier notifier(m_listeners); notifier.IsValid(); notifier.Next())
  748.         {
  749.                 notifier->OnSetActorItem(pActor, pItem);
  750.         }
  751.  
  752.         if (pItem == nullptr && itemId != INVALID_ENTITYID)
  753.         {
  754. #ifndef _RELEASE
  755.                 IEntity* pEntity = gEnv->pEntitySystem->GetEntity(itemId);
  756.                 CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "%s tried to select item ID %u but that ID does not belong to an item, it belongs to %s", pActor->GetEntity()->GetName(), itemId, pEntity ? pEntity->GetEntityTextDescription().c_str() : "nothing");
  757. #endif
  758.                 return;
  759.         }
  760.  
  761.         CCryAction::GetCryAction()->GetIGameplayRecorder()->Event(pActor->GetEntity(), GameplayEvent(eGE_ItemSelected, 0, 0, (void*)(EXPAND_PTR)itemId));
  762.         pActor->NotifyCurrentItemChanged(pItem);
  763.  
  764.         if (!pItem)
  765.                 return;
  766.  
  767.         pInventory->SetCurrentItem(itemId);
  768.  
  769.         pItem->SetHand(IItem::eIH_Right);
  770.         pItem->Select(true);
  771. }
  772.  
  773. //------------------------------------------------------------------------
  774. void CItemSystem::SetActorAccessory(IActor* pActor, EntityId itemId, bool keepHistory)
  775. {
  776.         if (!pActor)
  777.                 return;
  778.  
  779.         IInventory* pInventory = pActor->GetInventory();
  780.         if (!pInventory)
  781.                 return;
  782.  
  783.         IItem* pItem = GetItem(itemId);
  784.         for (TListeners::Notifier notifier(m_listeners); notifier.IsValid(); notifier.Next())
  785.         {
  786.                 notifier->OnSetActorAccessory(pActor, pItem);
  787.         }
  788. }
  789.  
  790. //------------------------------------------------------------------------
  791.  
  792. void CItemSystem::DropActorItem(IActor* pActor, EntityId itemId)
  793. {
  794.         if (!pActor)
  795.                 return;
  796.  
  797.         IInventory* pInventory = pActor->GetInventory();
  798.         if (!pInventory)
  799.                 return;
  800.  
  801.         IItem* pItem = GetItem(itemId);
  802.         if (!pItem)
  803.                 return;
  804.  
  805.         for (TListeners::Notifier notifier(m_listeners); notifier.IsValid(); notifier.Next())
  806.         {
  807.                 notifier->OnDropActorItem(pActor, pItem);
  808.         }
  809. }
  810.  
  811. //------------------------------------------------------------------------
  812.  
  813. void CItemSystem::DropActorAccessory(IActor* pActor, EntityId itemId)
  814. {
  815.         if (!pActor)
  816.                 return;
  817.  
  818.         IInventory* pInventory = pActor->GetInventory();
  819.         if (!pInventory)
  820.                 return;
  821.  
  822.         IItem* pItem = GetItem(itemId);
  823.         if (!pItem) return;
  824.  
  825.         for (TListeners::Notifier notifier(m_listeners); notifier.IsValid(); notifier.Next())
  826.         {
  827.                 notifier->OnDropActorAccessory(pActor, pItem);
  828.         }
  829. }
  830.  
  831. //------------------------------------------------------------------------
  832. void CItemSystem::SetActorItem(IActor* pActor, const char* name, bool keepHistory)
  833. {
  834.         IInventory* pInventory = (pActor != NULL) ? pActor->GetInventory() : NULL;
  835.         if (!pInventory)
  836.                 return;
  837.  
  838.         IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(name);
  839.         EntityId itemId = pInventory->GetItemByClass(pClass);
  840.         if (!itemId)
  841.                 return;
  842.  
  843.         SetActorItem(pActor, itemId, keepHistory);
  844. }
  845.  
  846. //------------------------------------------------------------------------
  847. void CItemSystem::CacheGeometry(const IItemParamsNode* geometry)
  848. {
  849.         if (!geometry)
  850.                 return;
  851.  
  852.         int n = geometry->GetChildCount();
  853.         if (n > 0)
  854.         {
  855.                 for (int i = 0; i < n; i++)
  856.                 {
  857.                         const IItemParamsNode* slot = geometry->GetChild(i);
  858.                         const char* name = slot->GetAttribute("name");
  859.                         int useStreaming = 1;
  860.                         slot->GetAttribute("useStreaming", useStreaming);
  861.  
  862.                         if (name && name[0])
  863.                                 CacheObject(name, (useStreaming != 0));
  864.                 }
  865.         }
  866. }
  867.  
  868. //------------------------------------------------------------------------
  869. void CItemSystem::CacheItemGeometry(const char* className)
  870. {
  871.         LOADING_TIME_PROFILE_SECTION(gEnv->pSystem);
  872.         if (m_itemParamsFlushed)
  873.                 return;
  874.  
  875.         TItemParamsMap::iterator it = m_params.find(CONST_TEMP_STRING(className));
  876.         if (it == m_params.end())
  877.                 return;
  878.  
  879.         if ((it->second.precacheFlags & SItemParamsDesc::eIF_PreCached_Geometry) == 0)
  880.         {
  881.                 if (const IItemParamsNode* root = GetItemParams(className))
  882.                 {
  883.                         const IItemParamsNode* geometry = root->GetChild("geometry");
  884.                         if (geometry)
  885.                                 CacheGeometry(geometry);
  886.                 }
  887.  
  888.                 it->second.precacheFlags |= SItemParamsDesc::eIF_PreCached_Geometry;
  889.         }
  890. }
  891.  
  892. //------------------------------------------------------------------------
  893. void CItemSystem::CacheItemSound(const char* className)
  894. {
  895.         LOADING_TIME_PROFILE_SECTION(gEnv->pSystem);
  896.         if (m_itemParamsFlushed)
  897.                 return;
  898.  
  899.         TItemParamsMap::iterator it = m_params.find(CONST_TEMP_STRING(className));
  900.         if (it == m_params.end())
  901.                 return;
  902.  
  903.         if ((it->second.precacheFlags & SItemParamsDesc::eIF_PreCached_Sound) == 0)
  904.         {
  905.                 if (const IItemParamsNode* root = GetItemParams(className))
  906.                 {
  907.                         const IItemParamsNode* actions = root->GetChild("actions");
  908.                         if (actions)
  909.                         {
  910.                                 int n = actions->GetChildCount();
  911.                                 for (int i = 0; i < n; i++)
  912.                                 {
  913.                                         const IItemParamsNode* action = actions->GetChild(i);
  914.                                         if (!stricmp(action->GetName(), "action"))
  915.                                         {
  916.                                                 int na = action->GetChildCount();
  917.                                                 for (int a = 0; a < na; a++)
  918.                                                 {
  919.                                                         const IItemParamsNode* sound = actions->GetChild(i);
  920.                                                         if (!stricmp(sound->GetName(), "sound"))
  921.                                                         {
  922.                                                                 const char* soundName = sound->GetNameAttribute();
  923.                                                                 REINST("do we still need this type of data priming?")
  924.                                                                 //gEnv->pSoundSystem->Precache(soundName, 0, FLAG_SOUND_PRECACHE_EVENT_DEFAULT);
  925.                                                         }
  926.                                                 }
  927.                                         }
  928.                                 }
  929.  
  930.                         }
  931.                 }
  932.  
  933.                 it->second.precacheFlags |= SItemParamsDesc::eIF_PreCached_Sound;
  934.         }
  935. }
  936.  
  937. //------------------------------------------------------------------------
  938. void CItemSystem::ClearSoundCache()
  939. {
  940.         for (TItemParamsMap::iterator it = m_params.begin(); it != m_params.end(); ++it)
  941.                 it->second.precacheFlags &= ~SItemParamsDesc::eIF_PreCached_Sound;
  942. }
  943.  
  944. //------------------------------------------------------------------------
  945. ICharacterInstance* CItemSystem::GetCachedCharacter(const char* fileName)
  946. {
  947.         CryFixedStringT<256> name(fileName);
  948.         name.replace('\\', '/');
  949.         name.MakeLower();
  950.  
  951.         TCharacterCacheIt cit = m_characterCache.find(CONST_TEMP_STRING(name.c_str()));
  952.  
  953.         if (cit == m_characterCache.end())
  954.                 return 0;
  955.  
  956.         return cit->second;
  957. }
  958.  
  959. //------------------------------------------------------------------------
  960. IStatObj* CItemSystem::GetCachedObject(const char* fileName)
  961. {
  962.         CryFixedStringT<256> name = fileName;
  963.         name.replace('\\', '/');
  964.         name.MakeLower();
  965.  
  966.         TObjectCacheIt oit = m_objectCache.find(CONST_TEMP_STRING(name.c_str()));
  967.  
  968.         if (oit == m_objectCache.end())
  969.                 return 0;
  970.  
  971.         return oit->second;
  972. }
  973.  
  974. //------------------------------------------------------------------------
  975. void CItemSystem::CacheObject(const char* fileName, bool useCgfStreaming)
  976. {
  977.         string name = PathUtil::ToUnixPath(string(fileName));
  978.         name.MakeLower();
  979.  
  980.         TObjectCacheIt oit = m_objectCache.find(name);
  981.         TCharacterCacheIt cit = m_characterCache.find(name);
  982.  
  983.         if ((oit != m_objectCache.end()) || (cit != m_characterCache.end()))
  984.         {
  985.                 return;
  986.         }
  987.  
  988.         stack_string ext(PathUtil::GetExt(name.c_str()));
  989.  
  990.         if ((ext == "cdf") || (ext == "chr") || (ext == "cga"))
  991.         {
  992.                 ICharacterInstance* pChar = gEnv->pCharacterManager->CreateInstance(fileName);
  993.                 if (pChar)
  994.                 {
  995.                         pChar->AddRef();
  996.                         m_characterCache.insert(TCharacterCache::value_type(name, pChar));
  997.                 }
  998.         }
  999.         else
  1000.         {
  1001.                 IStatObj* pStatObj = gEnv->p3DEngine->LoadStatObj(fileName, 0, 0, useCgfStreaming);
  1002.                 if (pStatObj)
  1003.                 {
  1004.                         pStatObj->AddRef();
  1005.                         m_objectCache.insert(TObjectCache::value_type(name, pStatObj));
  1006.                 }
  1007.         }
  1008. }
  1009.  
  1010. //------------------------------------------------------------------------
  1011. void CItemSystem::ClearGeometryCache()
  1012. {
  1013.         for (TObjectCacheIt oit = m_objectCache.begin(); oit != m_objectCache.end(); ++oit)
  1014.         {
  1015.                 if (oit->second)
  1016.                         oit->second->Release();
  1017.         }
  1018.         m_objectCache.clear();
  1019.  
  1020.         for (TCharacterCacheIt cit = m_characterCache.begin(); cit != m_characterCache.end(); ++cit)
  1021.         {
  1022.                 cit->second->Release();
  1023.         }
  1024.         m_characterCache.clear();
  1025.  
  1026.         for (TItemParamsMap::iterator it = m_params.begin(); it != m_params.end(); ++it)
  1027.         {
  1028.                 it->second.precacheFlags &= ~SItemParamsDesc::eIF_PreCached_Geometry;
  1029.         }
  1030. }
  1031.  
  1032. //------------------------------------------------------------------------
  1033. void CItemSystem::PrecacheLevel()
  1034. {
  1035.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  1036.  
  1037.         IEntitySystem* pEntitySystem = gEnv->pEntitySystem;
  1038.  
  1039.         TItemMap::iterator it = m_items.begin();
  1040.         TItemMap::iterator end = m_items.end();
  1041.  
  1042.         for (; it != end; ++it)
  1043.         {
  1044.                 if (IEntity* pEntity = pEntitySystem->GetEntity(it->first))
  1045.                 {
  1046.                         CacheItemGeometry(pEntity->GetClass()->GetName());
  1047.                         CacheItemSound(pEntity->GetClass()->GetName());
  1048.                 }
  1049.         }
  1050.  
  1051. #ifdef USE_LTL_PRECACHING
  1052.         if (m_LTLPrecacheState == LTLCS_FORNEXTLEVELLOAD)
  1053.         {
  1054.                 PreCacheLevelToLevelLoadout();
  1055.                 m_LTLPrecacheState = LTLCS_FORSAVEGAME;
  1056.         }
  1057.         else
  1058.                 m_precacheLevelToLevelItemList.clear();
  1059.  
  1060. #endif
  1061.  
  1062. }
  1063.  
  1064. #ifdef USE_LTL_PRECACHING
  1065. void CItemSystem::PreCacheLevelToLevelLoadout()
  1066. {
  1067.         IGameRules* pGameRules = CCryAction::GetCryAction()->GetIGameRulesSystem()->GetCurrentGameRules();
  1068.  
  1069.         CRY_ASSERT_MESSAGE(pGameRules != NULL, "No game rules active, can not preload resources");
  1070.  
  1071.         if (pGameRules)
  1072.         {
  1073.                 //Level to level inventory resource pre-loading
  1074.                 unsigned int numberOfElements = m_precacheLevelToLevelItemList.size();
  1075.                 if (numberOfElements > 0)
  1076.                 {
  1077.                         for (unsigned int i = 0; i < numberOfElements; ++i)
  1078.                         {
  1079.                                 CRY_ASSERT(m_precacheLevelToLevelItemList[i]);
  1080.  
  1081.                                 pGameRules->PrecacheLevelResource(m_precacheLevelToLevelItemList[i]->GetName(), eGameResourceType_Item);
  1082.                         }
  1083.                 }
  1084.         }
  1085. }
  1086. #endif
  1087. //------------------------------------------------------------------------
  1088. void CItemSystem::CreateItemTable(const char* name)
  1089. {
  1090.         IScriptSystem* pScriptSystem = gEnv->pScriptSystem;
  1091.         pScriptSystem->ExecuteFile(DEFAULT_ITEM_SCRIPT);
  1092.         pScriptSystem->BeginCall(DEFAULT_ITEM_CREATEFUNC);
  1093.         pScriptSystem->PushFuncParam(name);
  1094.         pScriptSystem->EndCall();
  1095. }
  1096.  
  1097. //------------------------------------------------------------------------
  1098. void CItemSystem::RegisterCVars()
  1099. {
  1100.         REGISTER_CVAR2("i_inventory_capacity", &i_inventory_capacity, 64, VF_CHEAT, "Players inventory capacity");
  1101.         REGISTER_COMMAND("i_giveitem", (ConsoleCommandFunc)GiveItemCmd, VF_CHEAT, "Gives specified item to the player!");
  1102.         REGISTER_COMMAND("i_dropitem", (ConsoleCommandFunc)DropItemCmd, VF_CHEAT, "Drops the current selected item!");
  1103.         REGISTER_COMMAND("i_giveallitems", (ConsoleCommandFunc)GiveAllItemsCmd, VF_CHEAT, "Gives all available items to the player!");
  1104.         REGISTER_COMMAND("i_givedebugitems", (ConsoleCommandFunc)GiveDebugItemsCmd, VF_CHEAT, "Gives special debug items to the player!");
  1105.         REGISTER_COMMAND("i_listitems", ListItemNames, VF_CHEAT, "List all item names matching the string provided as parameter.");
  1106.         REGISTER_COMMAND("i_saveweaponposition", (ConsoleCommandFunc)SaveWeaponPositionCmd, VF_CHEAT, "Saves weapon offset");
  1107.         REGISTER_COMMAND("i_giveammo", (ConsoleCommandFunc)GiveAmmoCmd, VF_CHEAT,
  1108.                          "Sets specified ammo to the specified amount in the player's inventory.\n"
  1109.                          "Usage: i_giveammo PistolBullet 999");
  1110.  
  1111.         // Auto complete
  1112. #if !defined(_RELEASE)
  1113.         assert(gEnv->pConsole);
  1114.         PREFAST_ASSUME(gEnv->pConsole);
  1115.         gEnv->pConsole->RegisterAutoComplete("i_giveitem", &s_itemListAutoComplete);
  1116. #endif // !defined(_RELEASE)
  1117.  
  1118.         m_pPrecache = REGISTER_INT("i_precache", 1, VF_DUMPTODISK, "Enables precaching of items during level loading.");
  1119.         m_pItemLimitMP = REGISTER_INT("i_lying_item_limit_mp", 64, 0, "Max number of items lying around in a level (<= 0 means no limit). Only works in multiplayer.");
  1120.         m_pItemLimitSP = REGISTER_INT("i_lying_item_limit_sp", 64, 0, "Max number of items lying around in a level (<= 0 means no limit). Only works in singleplayer.");
  1121. }
  1122.  
  1123. //------------------------------------------------------------------------
  1124. void CItemSystem::UnregisterCVars()
  1125. {
  1126.         gEnv->pConsole->RemoveCommand("i_giveitem");
  1127.         gEnv->pConsole->RemoveCommand("i_dropitem");
  1128.         gEnv->pConsole->RemoveCommand("i_giveallitems");
  1129.         gEnv->pConsole->RemoveCommand("i_givedebugitems");
  1130.         gEnv->pConsole->RemoveCommand("i_listitems");
  1131.         gEnv->pConsole->RemoveCommand("i_giveammo");
  1132.         gEnv->pConsole->UnregisterVariable("i_precache", true);
  1133.         gEnv->pConsole->UnregisterVariable("i_inventory_capacity", true);
  1134. }
  1135.  
  1136. //------------------------------------------------------------------------
  1137. void CItemSystem::GiveItemCmd(IConsoleCmdArgs* args)
  1138. {
  1139.         if (args->GetArgCount() < 2)
  1140.                 return;
  1141.  
  1142.         IGameFramework* pGameFramework = gEnv->pGameFramework;
  1143.         IActorSystem* pActorSystem = pGameFramework->GetIActorSystem();
  1144.         IItemSystem* pItemSystem = pGameFramework->GetIItemSystem();
  1145.  
  1146.         const char* itemName = args->GetArg(1);
  1147.         const char* actorName = 0;
  1148.  
  1149.         if (args->GetArgCount() > 2)
  1150.                 actorName = args->GetArg(2);
  1151.  
  1152.         IActor* pActor = 0;
  1153.  
  1154.         if (actorName)
  1155.         {
  1156.                 IEntity* pEntity = gEnv->pEntitySystem->FindEntityByName(actorName);
  1157.                 if (pEntity)
  1158.                 {
  1159.                         pActor = pGameFramework->GetIActorSystem()->GetActor(pEntity->GetId());
  1160.                 }
  1161.         }
  1162.         else
  1163.                 pActor = pGameFramework->GetClientActor();
  1164.  
  1165.         if (!pActor)
  1166.                 return;
  1167.  
  1168.         //Check item name before giving (it will resolve case sensitive 'issues')
  1169.         itemName = (const char*)(pItemSystem->Query(eISQ_Find_Item_By_Name, itemName));
  1170.  
  1171.         if (itemName != NULL)
  1172.                 pItemSystem->GiveItem(pActor, itemName, true, true, true);
  1173.         else
  1174.                 GameWarning("Trying to spawn item of class '%s' which is unknown!", args->GetArg(1));
  1175. }
  1176.  
  1177. //------------------------------------------------------------------------
  1178. void CItemSystem::DropItemCmd(IConsoleCmdArgs* args)
  1179. {
  1180.         IGameFramework* pGameFramework = gEnv->pGameFramework;
  1181.         IActorSystem* pActorSystem = pGameFramework->GetIActorSystem();
  1182.         IItemSystem* pItemSystem = pGameFramework->GetIItemSystem();
  1183.  
  1184.         const char* actorName = 0;
  1185.  
  1186.         if (args->GetArgCount() > 1)
  1187.                 actorName = args->GetArg(1);
  1188.  
  1189.         IActor* pActor = 0;
  1190.  
  1191.         if (actorName)
  1192.         {
  1193.                 IEntity* pEntity = gEnv->pEntitySystem->FindEntityByName(actorName);
  1194.                 if (pEntity)
  1195.                 {
  1196.                         pActor = pGameFramework->GetIActorSystem()->GetActor(pEntity->GetId());
  1197.                 }
  1198.         }
  1199.         else
  1200.                 pActor = pGameFramework->GetClientActor();
  1201.  
  1202.         if (!pActor)
  1203.                 return;
  1204.  
  1205.         IItem* pCurrentItem = pActor->GetCurrentItem();
  1206.         if (!pCurrentItem)
  1207.                 return;
  1208.  
  1209.         pCurrentItem->Drop();
  1210. }
  1211.  
  1212. //------------------------------------------------------------------------
  1213. void CItemSystem::ListItemNames(IConsoleCmdArgs* args)
  1214. {
  1215.         IGameFramework* pGameFramework = gEnv->pGameFramework;
  1216.         IItemSystem* pItemSystem = pGameFramework->GetIItemSystem();
  1217.  
  1218.         const char* itemName = NULL;
  1219.  
  1220.         if (args->GetArgCount() > 0)
  1221.                 itemName = args->GetArg(1);
  1222.         ;
  1223.  
  1224.         pItemSystem->Query(eISQ_Dump_Item_Names, itemName);
  1225.  
  1226. }
  1227.  
  1228. //--------------------------------------------------------------------
  1229. void CItemSystem::GiveItemsHelper(IConsoleCmdArgs* args, bool useGiveable, bool useDebug)
  1230. {
  1231.         if (args->GetArgCount() < 1)
  1232.                 return;
  1233.  
  1234.         IGameFramework* pGameFramework = gEnv->pGameFramework;
  1235.         IActorSystem* pActorSystem = pGameFramework->GetIActorSystem();
  1236.         CItemSystem* pItemSystem = static_cast<CItemSystem*>(pGameFramework->GetIItemSystem());
  1237.  
  1238.         const char* actorName = 0;
  1239.  
  1240.         if (args->GetArgCount() > 1)
  1241.                 actorName = args->GetArg(1);
  1242.  
  1243.         IActor* pActor = 0;
  1244.  
  1245.         if (actorName)
  1246.         {
  1247.                 IEntity* pEntity = gEnv->pEntitySystem->FindEntityByName(actorName);
  1248.                 if (pEntity)
  1249.                 {
  1250.                         pActor = pGameFramework->GetIActorSystem()->GetActor(pEntity->GetId());
  1251.                 }
  1252.         }
  1253.         else
  1254.                 pActor = pGameFramework->GetClientActor();
  1255.  
  1256.         if (!pActor)
  1257.                 return;
  1258.  
  1259.         for (TItemParamsMap::iterator it = pItemSystem->m_params.begin(); it != pItemSystem->m_params.end(); ++it)
  1260.         {
  1261.                 CItemParamsNode* params = it->second.params;
  1262.                 if (!params)
  1263.                         continue;
  1264.  
  1265.                 const IItemParamsNode* itemParams = params->GetChild("params");
  1266.  
  1267.                 bool give = false;
  1268.                 bool debug = false;
  1269.                 if (itemParams)
  1270.                 {
  1271.                         int n = itemParams->GetChildCount();
  1272.                         for (int i = 0; i < n; i++)
  1273.                         {
  1274.                                 const IItemParamsNode* param = itemParams->GetChild(i);
  1275.                                 const char* name = param->GetAttribute("name");
  1276.                                 if (!stricmp(name ? name : "", "giveable") && useGiveable)
  1277.                                 {
  1278.                                         int val = 0;
  1279.                                         param->GetAttribute("value", val);
  1280.                                         give = val != 0;
  1281.                                 }
  1282.                                 if (!stricmp(name ? name : "", "debug") && useDebug)
  1283.                                 {
  1284.                                         int val = 0;
  1285.                                         param->GetAttribute("value", val);
  1286.                                         debug = val != 0;
  1287.                                 }
  1288.                         }
  1289.                 }
  1290.  
  1291.                 if (give || debug)
  1292.                 {
  1293.                         pItemSystem->GiveItem(pActor, it->first.c_str(), false);
  1294.                 }
  1295.         }
  1296. }
  1297.  
  1298. //------------------------------------------------------------------------
  1299. void CItemSystem::GiveAllItemsCmd(IConsoleCmdArgs* args)
  1300. {
  1301.         GiveItemsHelper(args, true, false);
  1302. }
  1303.  
  1304. //------------------------------------------------------------------------
  1305. void CItemSystem::GiveDebugItemsCmd(IConsoleCmdArgs* args)
  1306. {
  1307.         GiveItemsHelper(args, false, true);
  1308. }
  1309.  
  1310. //------------------------------------------------------------------------
  1311. void CItemSystem::SaveWeaponPositionCmd(IConsoleCmdArgs* args)
  1312. {
  1313.         IGameFramework* pGameFramework = gEnv->pGameFramework;
  1314.         if (IActor* pActor = pGameFramework->GetClientActor())
  1315.         {
  1316.                 if (IItem* pItem = pActor->GetCurrentItem())
  1317.                         if (IWeapon* pWeapon = pItem->GetIWeapon())
  1318.                                 pWeapon->SaveWeaponPosition();
  1319.         }
  1320. }
  1321.  
  1322. //------------------------------------------------------------------------
  1323. void CItemSystem::GiveAmmoCmd(IConsoleCmdArgs* args)
  1324. {
  1325.         if (args->GetArgCount() < 3)
  1326.                 return;
  1327.  
  1328.         const char* ammo = args->GetArg(1);
  1329.         int amount = atoi(args->GetArg(2));
  1330.  
  1331.         IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(ammo);
  1332.         if (!pClass)
  1333.                 return;
  1334.  
  1335.         IActor* pActor = gEnv->pGameFramework->GetClientActor();
  1336.         if (!pActor)
  1337.                 return;
  1338.  
  1339.         if (IInventory* pInventory = pActor->GetInventory())
  1340.                 pInventory->SetAmmoCount(pClass, amount);
  1341. }
  1342.  
  1343. //------------------------------------------------------------------------
  1344. void CItemSystem::RegisterListener(IItemSystemListener* pListener)
  1345. {
  1346.         m_listeners.Add(pListener);
  1347. }
  1348.  
  1349. //------------------------------------------------------------------------
  1350. void CItemSystem::UnregisterListener(IItemSystemListener* pListener)
  1351. {
  1352.         m_listeners.Remove(pListener);
  1353. }
  1354.  
  1355. void CItemSystem::Serialize(TSerialize ser)
  1356. {
  1357.         if (ser.GetSerializationTarget() != eST_Network)
  1358.         {
  1359.                 if (ser.IsReading())
  1360.                         m_playerLevelToLevelSave = 0;
  1361.  
  1362.                 bool hasInventoryNode = m_playerLevelToLevelSave ? true : false;
  1363.                 ser.Value("hasInventoryNode", hasInventoryNode);
  1364.  
  1365.                 if (hasInventoryNode)
  1366.                 {
  1367.                         if (ser.IsWriting())
  1368.                         {
  1369.                                 IXmlStringData* xmlData = m_playerLevelToLevelSave->getXMLData(50000);
  1370.                                 string data(xmlData->GetString());
  1371.                                 ser.Value("LTLInventoryData", data);
  1372.                                 xmlData->Release();
  1373.  
  1374. #ifdef USE_LTL_PRECACHING
  1375.                                 ser.BeginGroup("LTLPrecacheClasses");
  1376.                                 if (m_LTLPrecacheState == LTLCS_FORSAVEGAME)
  1377.                                 {
  1378.                                         uint32 numClasses = m_precacheLevelToLevelItemList.size();
  1379.                                         ser.Value("numClasses", numClasses);
  1380.                                         for (uint32 i = 0; i < numClasses; ++i)
  1381.                                         {
  1382.                                                 ser.BeginGroup("class");
  1383.                                                 string name = m_precacheLevelToLevelItemList[i]->GetName();
  1384.                                                 ser.Value("name", name);
  1385.                                                 ser.EndGroup();
  1386.                                         }
  1387.                                 }
  1388.                                 ser.EndGroup();
  1389. #endif
  1390.  
  1391.                         }
  1392.                         else
  1393.                         {
  1394.                                 string data;
  1395.                                 ser.Value("LTLInventoryData", data);
  1396.                                 m_playerLevelToLevelSave = gEnv->pSystem->LoadXmlFromBuffer(data.c_str(), data.length());
  1397.  
  1398. #ifdef USE_LTL_PRECACHING
  1399.                                 m_precacheLevelToLevelItemList.clear();
  1400.                                 ser.BeginGroup("LTLPrecacheClasses");
  1401.                                 uint32 numClasses = 0;
  1402.                                 ser.Value("numClasses", numClasses);
  1403.                                 for (uint32 i = 0; i < numClasses; ++i)
  1404.                                 {
  1405.                                         ser.BeginGroup("class");
  1406.                                         string name;
  1407.                                         ser.Value("name", name);
  1408.                                         const IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(name.c_str());
  1409.                                         if (pClass)
  1410.                                                 m_precacheLevelToLevelItemList.push_back(pClass);
  1411.                                         ser.EndGroup();
  1412.                                 }
  1413.                                 ser.EndGroup();
  1414.                                 PreCacheLevelToLevelLoadout();
  1415.                                 m_LTLPrecacheState = LTLCS_FORSAVEGAME;
  1416. #endif
  1417.                         }
  1418.                 }
  1419.         }
  1420. }
  1421.  
  1422. void CItemSystem::SerializePlayerLTLInfo(bool bReading)
  1423. {
  1424.         if (bReading && !m_playerLevelToLevelSave)
  1425.                 return;
  1426.  
  1427.         if (gEnv->bMultiplayer)
  1428.                 return;
  1429.  
  1430.         if (!bReading)
  1431.         {
  1432.                 m_playerLevelToLevelSave = gEnv->pSystem->CreateXmlNode("Inventory");
  1433.         }
  1434.  
  1435.         IXmlSerializer* pSerializer = gEnv->pSystem->GetXmlUtils()->CreateXmlSerializer();
  1436.         IActor* pActor = gEnv->pGameFramework->GetClientActor();
  1437.         ISerialize* pSer = NULL;
  1438.         if (!bReading)
  1439.                 pSer = pSerializer->GetWriter(m_playerLevelToLevelSave);
  1440.         else
  1441.         {
  1442.                 pSer = pSerializer->GetReader(m_playerLevelToLevelSave);
  1443.                 m_pEquipmentManager->OnBeginGiveEquipmentPack();
  1444.         }
  1445.         TSerialize ser = TSerialize(pSer);
  1446.         if (pActor)
  1447.         {
  1448.                 pActor->SerializeLevelToLevel(ser);
  1449.         }
  1450.         pSerializer->Release();
  1451.  
  1452.         if (bReading)
  1453.                 m_pEquipmentManager->OnEndGiveEquipmentPack();
  1454.  
  1455. #ifdef USE_LTL_PRECACHING
  1456.         if (!bReading)
  1457.         {
  1458.                 m_precacheLevelToLevelItemList.clear();
  1459.                 m_LTLPrecacheState = LTLCS_FORNEXTLEVELLOAD;
  1460.  
  1461.                 IInventory* pInventory = pActor ? pActor->GetInventory() : NULL;
  1462.                 if (pInventory)
  1463.                 {
  1464.                         //Items
  1465.                         const int numberOfItems = pInventory->GetCount();
  1466.                         for (int i = 0; i < numberOfItems; ++i)
  1467.                         {
  1468.                                 const EntityId itemId = pInventory->GetItem(i);
  1469.                                 IEntity* pEntity = gEnv->pEntitySystem->GetEntity(itemId);
  1470.  
  1471.                                 if (pEntity)
  1472.                                 {
  1473.                                         m_precacheLevelToLevelItemList.push_back(pEntity->GetClass());
  1474.                                 }
  1475.                         }
  1476.  
  1477.                         //Accessories
  1478.                         const int numberOfAccessories = pInventory->GetAccessoryCount();
  1479.                         for (int i = 0; i < numberOfAccessories; ++i)
  1480.                         {
  1481.                                 const IEntityClass* pAccessoryClass = pInventory->GetAccessoryClass(i);
  1482.                                 if (pAccessoryClass)
  1483.                                 {
  1484.                                         m_precacheLevelToLevelItemList.push_back(pAccessoryClass);
  1485.                                 }
  1486.                         }
  1487.                 }
  1488.         }
  1489. #endif
  1490. }
  1491.  
  1492. //------------------------------------------------------------------------
  1493. int CItemSystem::GetItemParamsCount() const
  1494. {
  1495.         return m_params.size();
  1496. }
  1497.  
  1498. //------------------------------------------------------------------------
  1499. const char* CItemSystem::GetItemParamName(int index) const
  1500. {
  1501.         // FIXME: maybe return an iterator class, so get rid of advance (it's a map, argh)
  1502.         assert(index >= 0 && index < m_params.size());
  1503.         TItemParamsMap::const_iterator iter = m_params.begin();
  1504.         std::advance(iter, index);
  1505.         return iter->first.c_str();
  1506. }
  1507.  
  1508. //------------------------------------------------------------------------
  1509. const char* CItemSystem::GetItemParamsDescriptionFile(const char* itemName) const
  1510. {
  1511.         TItemParamsMap::const_iterator it = m_params.find(CONST_TEMP_STRING(itemName));
  1512.         if (it != m_params.end())
  1513.         {
  1514.                 return it->second.filePath.c_str();
  1515.         }
  1516.  
  1517.         GameWarning("Trying to get xml description file for item '%s'! Something very wrong has happened!", itemName);
  1518.         return NULL;
  1519. }
  1520.  
  1521. //----------------------------------------------------------------------
  1522. void* CItemSystem::Query(IItemSystemQuery query, const void* param /* = NULL */)
  1523. {
  1524.         static CryFixedStringT<64> lastItemName = "";
  1525.  
  1526.         switch (query)
  1527.         {
  1528.         case eISQ_Dump_Item_Names:
  1529.                 {
  1530.                         const char* filterName = param ? (const char*)(param) : NULL;
  1531.                         DumpItemList(filterName);
  1532.                 }
  1533.                 break;
  1534.  
  1535.         case eISQ_Find_Item_By_Name:
  1536.                 {
  1537.                         CryFixedStringT<32> filterName = param ? (const char*)(param) : "";
  1538.                         if (filterName.empty())
  1539.                                 return NULL;
  1540.  
  1541.                         TItemParamsMap::const_iterator cit = m_params.find(CONST_TEMP_STRING(filterName.c_str()));
  1542.  
  1543.                         //If not found, make lower case and make a non-case sensitive search
  1544.                         if (cit == m_params.end())
  1545.                         {
  1546.                                 filterName.MakeLower();
  1547.                                 cit = m_params.begin();
  1548.                                 while (cit != m_params.end())
  1549.                                 {
  1550.                                         CryFixedStringT<32> itemName = cit->first.c_str();
  1551.                                         itemName.MakeLower();
  1552.                                         if (itemName == filterName)
  1553.                                         {
  1554.                                                 break;
  1555.                                         }
  1556.                                         ++cit;
  1557.                                 }
  1558.                         }
  1559.  
  1560.                         //We don't find any match
  1561.                         if (cit == m_params.end())
  1562.                                 return NULL;
  1563.  
  1564.                         //Found a match, return its name
  1565.                         lastItemName = cit->first.c_str();
  1566.                         return (void*)(lastItemName.c_str());
  1567.                 }
  1568.                 break;
  1569.  
  1570.         default:
  1571.                 break;
  1572.         }
  1573.  
  1574.         return NULL;
  1575. }
  1576.  
  1577. //--------------------------------------------------------------------
  1578. void CItemSystem::DumpItemList(const char* filter)
  1579. {
  1580.         CryFixedStringT<32> filterName = "";
  1581.  
  1582.         if (filter != NULL)
  1583.         {
  1584.                 filterName = filter;
  1585.                 filterName.MakeLower();
  1586.         }
  1587.  
  1588.         TItemParamsMap::const_iterator cit = m_params.begin();
  1589.         if (filterName.empty())
  1590.         {
  1591.                 while (cit != m_params.end())
  1592.                 {
  1593.                         CryLog("\t- %s", cit->first.c_str());
  1594.                         ++cit;
  1595.                 }
  1596.         }
  1597.         else
  1598.         {
  1599.                 while (cit != m_params.end())
  1600.                 {
  1601.                         CryFixedStringT<32> itemName = cit->first.c_str();
  1602.                         itemName.MakeLower();
  1603.                         if (itemName.find(CONST_TEMP_STRING(filterName.c_str())) != string::npos)
  1604.                         {
  1605.                                 CryLog("\t- %s", cit->first.c_str());
  1606.                         }
  1607.                         ++cit;
  1608.                 }
  1609.         }
  1610.  
  1611. }
  1612.  
  1613. //----------------------------------------------------------------------
  1614. typedef struct classMemData
  1615. {
  1616.         uint32 countOfClass;
  1617.         uint32 memSize;
  1618.  
  1619.         classMemData() : countOfClass(0), memSize(0){}
  1620. }t_classMemData;
  1621.  
  1622. typedef std::map<IEntityClass*, t_classMemData> TDebugClassesMem;
  1623.  
  1624. void CItemSystem::DisplayItemSystemStats()
  1625. {
  1626.         const float kbInvert = 1.0f / 1024.0f;
  1627.  
  1628.         TDebugClassesMem debugClassesMap;
  1629.         t_classMemData tempData;
  1630.  
  1631.         ICrySizer* pSizer = gEnv->pSystem->CreateSizer();
  1632.  
  1633.         GetMemoryUsage(pSizer);
  1634.  
  1635.         int itemSystemMem = pSizer->GetTotalSize();
  1636.  
  1637.         uint32 itemCount = 0;
  1638.         uint32 weaponCount = 0;
  1639.  
  1640.         uint32 weaponMemSize = 0;
  1641.         uint32 lastSizerSize = 0;
  1642.  
  1643.         TItemMap::const_iterator cit = m_items.begin();
  1644.         TItemMap::const_iterator citEnd = m_items.end();
  1645.         while (cit != citEnd)
  1646.         {
  1647.                 IItem* pItem = GetItem(cit->first);
  1648.                 lastSizerSize = pSizer->GetTotalSize();
  1649.                 pItem->GetMemoryUsage(pSizer);
  1650.                 uint32 itemSize = (pSizer->GetTotalSize() - lastSizerSize);
  1651.  
  1652.                 if (pItem->GetIWeapon())
  1653.                 {
  1654.                         itemCount++;
  1655.                         weaponCount++;
  1656.                         weaponMemSize += itemSize;
  1657.                 }
  1658.                 else
  1659.                 {
  1660.                         itemCount++;
  1661.                 }
  1662.  
  1663.                 TDebugClassesMem::iterator it = debugClassesMap.find(pItem->GetEntity()->GetClass());
  1664.                 if (it != debugClassesMap.end())
  1665.                 {
  1666.                         it->second.countOfClass++;
  1667.                         it->second.memSize += itemSize;
  1668.                 }
  1669.                 else
  1670.                 {
  1671.                         tempData.countOfClass = 1;
  1672.                         tempData.memSize = itemSize;
  1673.                         debugClassesMap.insert(TDebugClassesMem::value_type(pItem->GetEntity()->GetClass(), tempData));
  1674.                 }
  1675.  
  1676.                 ++cit;
  1677.         }
  1678.         float white[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
  1679.  
  1680.         //Global
  1681.         IRenderAuxText::Draw2dLabel(50.0f, 50.0f, 1.5f, white, false, "Item system mem:         %.2f Kb.", itemSystemMem * kbInvert);
  1682.  
  1683.         IRenderAuxText::Draw2dLabel(50.0f, 65.0f, 1.5f, white, false, "Num. Item instances:             %d.             Total mem: %.2f Kb", itemCount, (float)(pSizer->GetTotalSize() - itemSystemMem) * kbInvert);
  1684.         IRenderAuxText::Draw2dLabel(50.0f, 80.0f, 1.5f, white, false, "Num. Weapon instances:   %d.             Total mem: %.2f Kb", weaponCount, (float)weaponMemSize * kbInvert);
  1685.  
  1686.         //Per item class
  1687.         TDebugClassesMem::const_iterator cit2 = debugClassesMap.begin();
  1688.         TDebugClassesMem::const_iterator citEnd2 = debugClassesMap.end();
  1689.  
  1690.         int i = 0;
  1691.         while (cit2 != citEnd2)
  1692.         {
  1693.                 float grey[4] = { 0.7f, 0.7f, 0.7f, 1.0f };
  1694.  
  1695.                 float midSize = (float)cit2->second.memSize / (float)cit2->second.countOfClass;
  1696.                 IRenderAuxText::Draw2dLabel(50.0f, 100.0f + (10.0f * i), 1.2f, grey, false, "Class %s:  Instances: %d.  MemSize: %.2f Kb.       Instance Size:%.3f Kb", cit2->first->GetName(), cit2->second.countOfClass, (float)cit2->second.memSize * kbInvert, midSize * kbInvert);
  1697.  
  1698.                 ++cit2;
  1699.                 i++;
  1700.         }
  1701.  
  1702.         pSizer->Release();
  1703. }
  1704.  
  1705. //-----------------------------------------------------------------------
  1706.  
  1707. void CItemSystem::GetMemoryUsage(ICrySizer* pSizer) const
  1708. {
  1709.         SIZER_COMPONENT_NAME(pSizer, "ItemSystem");
  1710.  
  1711.         pSizer->AddObject(this, sizeof(*this));
  1712.         pSizer->AddContainer(m_objectCache);
  1713.         pSizer->AddContainer(m_characterCache);
  1714.         pSizer->AddContainer(m_classes);
  1715.         pSizer->AddContainer(m_params);
  1716.         pSizer->AddContainer(m_items);
  1717.         m_listeners.GetMemoryUsage(pSizer);
  1718.         pSizer->AddContainer(m_folders);
  1719.         pSizer->AddObject(m_pEquipmentManager);
  1720. }
  1721.  
  1722. uint32 CItemSystem::GetItemSocketCount(const char* item) const
  1723. {
  1724.         if (m_itemParamsFlushed)
  1725.                 return 0;
  1726.  
  1727.         const IItemParamsNode* root = GetItemParams(item);
  1728.         if (!root)
  1729.                 return 0;
  1730.  
  1731.         const IItemParamsNode* sockets = root->GetChild("sockets");
  1732.         if (!sockets)
  1733.                 return 0;
  1734.  
  1735.         int count = 0;
  1736.         for (int i = 0; i < sockets->GetChildCount(); ++i)
  1737.         {
  1738.                 const char* name = sockets->GetChildName(i);
  1739.                 if (name != 0 && !stricmp(name, "socket"))
  1740.                         ++count;
  1741.         }
  1742.         return count;
  1743. }
  1744.  
  1745. const char* CItemSystem::GetItemSocketName(const char* item, int idx) const
  1746. {
  1747.         if (m_itemParamsFlushed)
  1748.                 return NULL;
  1749.  
  1750.         const IItemParamsNode* root = GetItemParams(item);
  1751.         if (!root)
  1752.                 return NULL;
  1753.  
  1754.         const IItemParamsNode* sockets = root->GetChild("sockets");
  1755.         if (!sockets)
  1756.                 return NULL;
  1757.  
  1758.         return sockets->GetChild(idx)->GetAttribute("name");
  1759. }
  1760.  
  1761. bool CItemSystem::IsCompatible(const char* item, const char* attachment) const
  1762. {
  1763.         if (m_itemParamsFlushed)
  1764.                 return false;
  1765.  
  1766.         const IItemParamsNode* rootItem = GetItemParams(item);
  1767.         if (!rootItem)
  1768.                 return false;
  1769.  
  1770.         const IItemParamsNode* sockets = rootItem->GetChild("sockets");
  1771.         if (!sockets)
  1772.                 return false;
  1773.  
  1774.         const IItemParamsNode* rootAtt = GetItemParams(attachment);
  1775.         if (!rootAtt)
  1776.                 return false;
  1777.  
  1778.         const IItemParamsNode* types = rootAtt->GetChild("types");
  1779.         if (!types)
  1780.                 return false;
  1781.  
  1782.         for (int i = 0; i < sockets->GetChildCount(); ++i)
  1783.         {
  1784.                 const IItemParamsNode* socket = sockets->GetChild(i);
  1785.                 for (int j = 0; j < socket->GetChildCount(); ++j)
  1786.                 {
  1787.                         const char* socketName = socket->GetChild(j)->GetAttribute("type");
  1788.                         if (socketName)
  1789.                                 for (int k = 0; k < types->GetChildCount(); ++k)
  1790.                                 {
  1791.                                         const char* typeName = types->GetChild(k)->GetAttribute("name");
  1792.                                         if (typeName != 0 && !stricmp(socketName, typeName))
  1793.                                                 return true;
  1794.                                 }
  1795.                 }
  1796.         }
  1797.         return false;
  1798. }
  1799.  
  1800. bool CItemSystem::GetItemSocketCompatibility(const char* item, const char* socket) const
  1801. {
  1802.         if (m_itemParamsFlushed)
  1803.                 return false;
  1804.  
  1805.         const IItemParamsNode* itemAtt = GetItemParams(item);
  1806.         if (!itemAtt)
  1807.                 return false;
  1808.  
  1809.         const IItemParamsNode* itemTypes = itemAtt->GetChild("types");
  1810.         if (!itemTypes)
  1811.                 return false;
  1812.  
  1813.         std::set<string> itemSockets;
  1814.         for (int i = 0; i < itemTypes->GetChildCount(); ++i)
  1815.         {
  1816.                 const char* socketName = itemTypes->GetChild(i)->GetAttribute("name");
  1817.                 itemSockets.insert(socketName);
  1818.         }
  1819.  
  1820.         for (TItemParamsMap::const_iterator it = m_params.begin(), eIt = m_params.end(); it != eIt; ++it)
  1821.         {
  1822.                 if (it->first == item)
  1823.                         continue;
  1824.  
  1825.                 if (const IItemParamsNode* itemParams = it->second.params)
  1826.                 {
  1827.                         if (const IItemParamsNode* socketsNode = itemParams->GetChild("sockets"))
  1828.                         {
  1829.                                 for (int i = 0; i < socketsNode->GetChildCount(); ++i)
  1830.                                 {
  1831.                                         const IItemParamsNode* childNode = socketsNode->GetChild(i);
  1832.                                         if (const char* childName = childNode->GetAttribute("name"))
  1833.                                                 if (CONST_TEMP_STRING(childName) == socket)
  1834.                                                         for (int j = 0; j < childNode->GetChildCount(); ++j)
  1835.                                                                 if (const IItemParamsNode* innerNode = childNode->GetChild(j))
  1836.                                                                         if (const char* supportType = innerNode->GetAttribute("type"))
  1837.                                                                                 if (itemSockets.find(supportType) != itemSockets.end())
  1838.                                                                                         return true;
  1839.                                 }
  1840.                         }
  1841.                 }
  1842.         }
  1843.  
  1844.         return false;
  1845. }
  1846.  
  1847. bool CItemSystem::CanSocketBeEmpty(const char* item, const char* socket) const
  1848. {
  1849.         if (m_itemParamsFlushed)
  1850.                 return true;
  1851.  
  1852.         const IItemParamsNode* root = GetItemParams(item);
  1853.         if (!root)
  1854.                 return true;
  1855.  
  1856.         const IItemParamsNode* sockets = root->GetChild("sockets");
  1857.         if (!sockets)
  1858.                 return true;
  1859.  
  1860.         for (int i = 0; i < sockets->GetChildCount(); ++i)
  1861.         {
  1862.                 const char* socketName = sockets->GetChild(i)->GetAttribute("name");
  1863.                 if (socketName != 0 && !stricmp(socketName, socket))
  1864.                 {
  1865.                         int canBeEmpty = 1;
  1866.                         sockets->GetChild(i)->GetAttribute("can_be_empty", canBeEmpty);
  1867.                         return canBeEmpty != 0;
  1868.                 }
  1869.         }
  1870.         return true;
  1871. }
  1872.  
  1873. void CItemSystem::ItemSystemErrorMessage(const char* fileName, const char* errorInfo, bool displayErrorDialog)
  1874. {
  1875.         if ((fileName == NULL) || (errorInfo == NULL))
  1876.                 return;
  1877.  
  1878.         CryFixedStringT<1024> messageBuffer;
  1879.         messageBuffer.Format("Failed to load '%s'. Required data missing, which could lead to un-expected game behavior or crashes. (%s)", fileName, errorInfo);
  1880.  
  1881.         CryLogAlways("%s", messageBuffer.c_str());
  1882.  
  1883.         if (displayErrorDialog)
  1884.         {
  1885.                 gEnv->pSystem->ShowMessage(messageBuffer.c_str(), "Error", eMB_Error);
  1886.         }
  1887. }
  1888.  
  1889. void CItemSystem::InsertFolder(const char* folder)
  1890. {
  1891.         for (TFolderList::const_iterator folderCit = m_folders.begin(); folderCit != m_folders.end(); ++folderCit)
  1892.         {
  1893.                 if (stricmp(folderCit->c_str(), folder) == 0)
  1894.                         return;
  1895.         }
  1896.  
  1897.         m_folders.push_back(folder);
  1898. }
  1899.  
downloadItemSystem.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