2642 lines
94 KiB
C++
2642 lines
94 KiB
C++
![]() |
//
|
||
|
// Filename: ExtraMetadataMgr.h
|
||
|
// Description: Wrapper for any type of generic extra dlc metadata needed after game release
|
||
|
//
|
||
|
//
|
||
|
|
||
|
#include "scene/ExtraMetadataMgr.h"
|
||
|
#include "scene/DataFileMgr.h"
|
||
|
|
||
|
// rage headers
|
||
|
#include "parser/manager.h"
|
||
|
#include "string/stringhash.h"
|
||
|
#include "fwsys/metadatastore.h"
|
||
|
|
||
|
// game headers
|
||
|
#include "scene/DataFileMgr.h"
|
||
|
#include "scene/dlc_channel.h"
|
||
|
#include "modelinfo/modelinfo.h"
|
||
|
#include "modelinfo/pedmodelinfo.h"
|
||
|
#include "scene/ExtraContent.h"
|
||
|
#include "script/script.h"
|
||
|
#include "scene/WarpManager.h"
|
||
|
#include "modelinfo/VehicleModelInfoEnums.h"
|
||
|
|
||
|
static const int TATTOO_COLLECTION_INITIAL_SIZE = 4;
|
||
|
static const int TATTOO_ITEM_LOOKUP_INITIAL_SIZE = 4;
|
||
|
static const int TATTOO_ITEM_LOOKUP_GROW = 4;
|
||
|
|
||
|
#if __BANK && !__SPU
|
||
|
#include "peds/rendering/PedVariationDS.h"
|
||
|
#include "peds/ped.h"
|
||
|
#include "peds/rendering/PedOverlay.h"
|
||
|
#include "scene/world/GameWorld.h"
|
||
|
#include "Vehicles/VehicleFactory.h"
|
||
|
#include "ModelInfo/ModelInfo.h"
|
||
|
#include "ModelInfo/ModelInfo_Factories.h"
|
||
|
#include "modelInfo/vehicleModelInfo.h"
|
||
|
#include "modelinfo/VehicleModelInfoColors.h"
|
||
|
#include "weapons/components/WeaponComponent.h"
|
||
|
#include "weapons/components/WeaponComponentManager.h"
|
||
|
#include "system/exec.h"
|
||
|
|
||
|
#define MAX_APPAREL_ITEMS_PER_PAGE 10
|
||
|
|
||
|
s32 CExtraMetadataMgr::m_currentOutfitPg = 0;
|
||
|
s32 CExtraMetadataMgr::m_currentComponentPg = 0;
|
||
|
s32 CExtraMetadataMgr::m_currentPropPg = 0;
|
||
|
s32 CExtraMetadataMgr::m_sWeaponListIdx = -1;
|
||
|
s32 CExtraMetadataMgr::m_sVehicleComboIdx = 0;
|
||
|
s32 CExtraMetadataMgr::m_sWeaponComboIdx = 0;
|
||
|
s32 CExtraMetadataMgr::m_sNumOfListedMods = 0;
|
||
|
s32 CExtraMetadataMgr::m_sNumOfListedGenericMods = 0;
|
||
|
s32 CExtraMetadataMgr::m_sNumOfListedWeaponComponents = 0;
|
||
|
s32 CExtraMetadataMgr::m_sNumOfListedTattoos = 0;
|
||
|
bkList* CExtraMetadataMgr::m_bankComponentList = NULL;
|
||
|
bkList* CExtraMetadataMgr::m_bankTattooList = NULL;
|
||
|
bkList* CExtraMetadataMgr::m_bankTattooLookupList = NULL;
|
||
|
bkList* CExtraMetadataMgr::m_bankPropList = NULL;
|
||
|
bkList* CExtraMetadataMgr::m_bankOutfitList = NULL;
|
||
|
bkList* CExtraMetadataMgr::m_bankWeaponComponentsList = NULL;
|
||
|
bkList* CExtraMetadataMgr::m_bankVehicleModList = NULL;
|
||
|
bkList* CExtraMetadataMgr::m_bankGenericVehicleModList = NULL;
|
||
|
bkCombo* CExtraMetadataMgr::m_bankVehicleCombo = NULL;
|
||
|
bkCombo* CExtraMetadataMgr::m_bankWeaponCombo = NULL;
|
||
|
bkCombo* CExtraMetadataMgr::m_compCharCombo = NULL;
|
||
|
s32 CExtraMetadataMgr::m_compCharComboIdx = 0;
|
||
|
bkCombo* CExtraMetadataMgr::m_compDLCNameCombo = NULL;
|
||
|
s32 CExtraMetadataMgr::m_compDLCNameComboIdx = 0;
|
||
|
bkCombo* CExtraMetadataMgr::m_propCharCombo = NULL;
|
||
|
s32 CExtraMetadataMgr::m_propCharComboIdx = 0;
|
||
|
bkCombo* CExtraMetadataMgr::m_propDLCNameCombo = NULL;
|
||
|
s32 CExtraMetadataMgr::m_propDLCNameComboIdx = 0;
|
||
|
bkCombo* CExtraMetadataMgr::m_outfitCharCombo = NULL;
|
||
|
s32 CExtraMetadataMgr::m_outfitCharComboIdx = 0;
|
||
|
bkCombo* CExtraMetadataMgr::m_outfitDLCNameCombo = NULL;
|
||
|
s32 CExtraMetadataMgr::m_outfitDLCNameComboIdx = 0;
|
||
|
atArray<const char*> CExtraMetadataMgr::ms_outfitDLCNames;
|
||
|
atArray<const char*> CExtraMetadataMgr::ms_propDLCNames;
|
||
|
atArray<const char*> CExtraMetadataMgr::ms_compDLCNames;
|
||
|
char CExtraMetadataMgr::m_shopPedComponentLookup[RAGE_MAX_PATH] = { 0 };
|
||
|
char CExtraMetadataMgr::m_shopPedPropLookup[RAGE_MAX_PATH] = { 0 };
|
||
|
char CExtraMetadataMgr::m_shopPedComponentCounts[RAGE_MAX_PATH] = { 0 };
|
||
|
char CExtraMetadataMgr::m_shopPedPropCounts[RAGE_MAX_PATH] = { 0 };
|
||
|
char CExtraMetadataMgr::m_shopPedOutfitLookup[RAGE_MAX_PATH] = { 0 };
|
||
|
char CExtraMetadataMgr::m_shopPedOutfitCounts[RAGE_MAX_PATH] = { 0 };
|
||
|
char CExtraMetadataMgr::m_proxyFromIndex[RAGE_MAX_PATH] = { 0 };
|
||
|
char CExtraMetadataMgr::m_proxyToIndex[RAGE_MAX_PATH] = { 0 };
|
||
|
bkCombo* CExtraMetadataMgr::ms_bankInteriorCombo;
|
||
|
s32 CExtraMetadataMgr::ms_dlcInteriorComboIdx = 0;
|
||
|
atArray<s32> CExtraMetadataMgr::ms_dlcInteriorMapSlots;
|
||
|
bkCombo* CExtraMetadataMgr::m_bankProxyIndicesMetaCombo = NULL;
|
||
|
bkList* CExtraMetadataMgr::m_bankProxyIndicesInFileList = NULL;
|
||
|
bkList* CExtraMetadataMgr::m_bankProxyIndicesInScratchList = NULL;
|
||
|
s32 CExtraMetadataMgr::ms_ProxyIndexComboIdx = 0;
|
||
|
atBinaryMap<const char*, u32> CExtraMetadataMgr::m_proxyOrderLookup;
|
||
|
s32 CExtraMetadataMgr::m_clickedProxyInFileHash = 0;
|
||
|
s32 CExtraMetadataMgr::m_clickedProxyInScratchHash = 0;
|
||
|
bkText* CExtraMetadataMgr::m_proxyFromIdxTxt = NULL;
|
||
|
bkText* CExtraMetadataMgr::m_proxyToIdxTxt = NULL;
|
||
|
#endif //__BANK && !__SPU
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
// Data file loader interface
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
class CExtraMetaDataFileMounter : public CDataFileMountInterface
|
||
|
{
|
||
|
virtual bool LoadDataFile(const CDataFileMgr::DataFile & file)
|
||
|
{
|
||
|
dlcDebugf3 ("CExtraMetaDataFileMounter::LoadDataFile: %s type = %d",file.m_filename, file.m_fileType);
|
||
|
switch(file.m_fileType)
|
||
|
{
|
||
|
case CDataFileMgr::TATTOO_SHOP_DLC_FILE: EXTRAMETADATAMGR.AddTattooShopItemsCollection(file.m_filename); break;
|
||
|
case CDataFileMgr::WEAPON_SHOP_INFO_METADATA_FILE: EXTRAMETADATAMGR.AddWeaponShopItemsCollection(file.m_filename); break;
|
||
|
case CDataFileMgr::SHOP_PED_APPAREL_META_FILE: EXTRAMETADATAMGR.AddShopPedApparel(file.m_filename); break;
|
||
|
case CDataFileMgr::VEHICLE_SHOP_DLC_FILE: EXTRAMETADATAMGR.AddVehiclesCollection(file.m_filename); break;
|
||
|
default: return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
virtual void UnloadDataFile(const CDataFileMgr::DataFile & file)
|
||
|
{
|
||
|
dlcDebugf3 ("CExtraMetaDataFileMounter::UnloadDataFile %s type = %d",file.m_filename, file.m_fileType);
|
||
|
switch(file.m_fileType)
|
||
|
{
|
||
|
case CDataFileMgr::TATTOO_SHOP_DLC_FILE: EXTRAMETADATAMGR.RemoveTattooShopItemsCollection(file.m_filename); break;
|
||
|
case CDataFileMgr::WEAPON_SHOP_INFO_METADATA_FILE: EXTRAMETADATAMGR.RemoveWeaponShopItemsCollection(file.m_filename); break;
|
||
|
case CDataFileMgr::SHOP_PED_APPAREL_META_FILE: EXTRAMETADATAMGR.RemoveShopPedApparel(file.m_filename); break;
|
||
|
case CDataFileMgr::VEHICLE_SHOP_DLC_FILE: EXTRAMETADATAMGR.RemoveVehiclesCollection(file.m_filename); break;
|
||
|
default: break;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
} g_ExtraMetaDataFileMounter;
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
// CExtraMetadataMgr
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
CExtraMetadataMgr* CExtraMetadataMgr::smp_Instance = NULL;
|
||
|
|
||
|
CExtraMetadataMgr::CExtraMetadataMgr()
|
||
|
{
|
||
|
m_tattooShopsItems.Reserve(TATTOO_COLLECTION_INITIAL_SIZE);
|
||
|
|
||
|
for (int i=0; i < m_tattooShopItemsLookup.size(); ++i)
|
||
|
{
|
||
|
m_tattooShopItemsLookup[i].Reserve(TATTOO_ITEM_LOOKUP_INITIAL_SIZE);
|
||
|
}
|
||
|
|
||
|
atDelegate<void (u32, bool)> onTattooContentLockChangedCB;
|
||
|
atDelegate<void (u32, bool)> onWeaponContentLockChangedCB;
|
||
|
atDelegate<void (u32, bool)> onPedApparelContentLockChangedCB;
|
||
|
atDelegate<void (u32, bool)> onVehicleContentLockChangedCB;
|
||
|
|
||
|
onTattooContentLockChangedCB.Bind(this, &CExtraMetadataMgr::OnTattooContentLockChangedCB);
|
||
|
m_contentRightData[CRT_TATTOOS].m_onLockChangedCBIdx = EXTRACONTENT.AddOnContentItemChangedCB(onTattooContentLockChangedCB);
|
||
|
|
||
|
onWeaponContentLockChangedCB.Bind(this, &CExtraMetadataMgr::OnWeaponContentLockChangedCB);
|
||
|
m_contentRightData[CRT_WEAPONS].m_onLockChangedCBIdx = EXTRACONTENT.AddOnContentItemChangedCB(onWeaponContentLockChangedCB);
|
||
|
|
||
|
onPedApparelContentLockChangedCB.Bind(this, &CExtraMetadataMgr::OnPedApparelContentLockChangedCB);
|
||
|
m_contentRightData[CRT_PED_APPAREL].m_onLockChangedCBIdx = EXTRACONTENT.AddOnContentItemChangedCB(onPedApparelContentLockChangedCB);
|
||
|
|
||
|
onVehicleContentLockChangedCB.Bind(this, &CExtraMetadataMgr::OnVehicleContentLockChangedCB);
|
||
|
m_contentRightData[CRT_VEHICLES].m_onLockChangedCBIdx = EXTRACONTENT.AddOnContentItemChangedCB(onVehicleContentLockChangedCB);
|
||
|
}
|
||
|
|
||
|
CExtraMetadataMgr::~CExtraMetadataMgr()
|
||
|
{
|
||
|
// Clean up any arrays with pointers in...
|
||
|
Reset();
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::ClassInit(unsigned initMode)
|
||
|
{
|
||
|
if (initMode == INIT_CORE && !smp_Instance)
|
||
|
{
|
||
|
smp_Instance = rage_new CExtraMetadataMgr();
|
||
|
Assert(smp_Instance);
|
||
|
CDataFileMount::RegisterMountInterface(CDataFileMgr::TATTOO_SHOP_DLC_FILE, &g_ExtraMetaDataFileMounter);
|
||
|
CDataFileMount::RegisterMountInterface(CDataFileMgr::SHOP_PED_APPAREL_META_FILE, &g_ExtraMetaDataFileMounter,eDFMI_UnloadLast);
|
||
|
CDataFileMount::RegisterMountInterface(CDataFileMgr::WEAPON_SHOP_INFO_METADATA_FILE, &g_ExtraMetaDataFileMounter);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::ClassShutdown(unsigned shutdownMode)
|
||
|
{
|
||
|
if (shutdownMode == SHUTDOWN_CORE)
|
||
|
{
|
||
|
delete smp_Instance;
|
||
|
smp_Instance = NULL;
|
||
|
}
|
||
|
else if (shutdownMode == SHUTDOWN_SESSION)
|
||
|
EXTRAMETADATAMGR.Reset();
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::ShutdownDLCMetaFiles(u32 /*mode*/)
|
||
|
{
|
||
|
if (smp_Instance)
|
||
|
EXTRAMETADATAMGR.RemoveAllPedDLCMetaFiles();
|
||
|
}
|
||
|
|
||
|
// Cleans up the contents without deleting the manager itself
|
||
|
void CExtraMetadataMgr::Reset()
|
||
|
{
|
||
|
for (u32 i = 0; i < m_tattooShopItemsLookup.size(); i++)
|
||
|
m_tattooShopItemsLookup[i].Reset();
|
||
|
|
||
|
m_tattooShopsItems.Reset();
|
||
|
|
||
|
for (u32 i = 0; i < m_shopPedApparel.size(); i++)
|
||
|
delete m_shopPedApparel[i];
|
||
|
|
||
|
m_shopPedApparel.Reset();
|
||
|
m_shopPedApparelLookup.Reset();
|
||
|
m_shopPedApparelCompQuery.Reset();
|
||
|
m_shopPedApparelPropQuery.Reset();
|
||
|
m_shopPedApparelOutfitQuery.Reset();
|
||
|
|
||
|
m_vehicles.Reset();
|
||
|
m_vehiclesLookup.Reset();
|
||
|
|
||
|
m_weaponShopItemsLookup.Reset();
|
||
|
m_weaponShopItems.Reset();
|
||
|
|
||
|
m_vehicleGenericModsLookup.Reset();
|
||
|
|
||
|
memset(m_contentRightData, 0, sizeof(m_contentRightData));
|
||
|
}
|
||
|
|
||
|
// Content lock changed callbacks...
|
||
|
void CExtraMetadataMgr::OnTattooContentLockChangedCB(u32 /*hash*/, bool /*value*/)
|
||
|
{
|
||
|
m_contentRightData[CRT_TATTOOS].m_rightsChanged = true;
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::OnWeaponContentLockChangedCB(u32 /*hash*/, bool /*value*/)
|
||
|
{
|
||
|
m_contentRightData[CRT_WEAPONS].m_rightsChanged = true;
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::OnPedApparelContentLockChangedCB(u32 /*hash*/, bool /*value*/)
|
||
|
{
|
||
|
m_contentRightData[CRT_PED_APPAREL].m_rightsChanged = true;
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::OnVehicleContentLockChangedCB(u32 /*hash*/, bool /*value*/)
|
||
|
{
|
||
|
m_contentRightData[CRT_VEHICLES].m_rightsChanged = true;
|
||
|
}
|
||
|
|
||
|
// VEHICLE Metadata helpers
|
||
|
void CExtraMetadataMgr::AddVehiclesCollection(const char* pFileName)
|
||
|
{
|
||
|
if (ShopVehicleDataArray* vehiclesArray = AddMetaItem(m_vehicles, pFileName))
|
||
|
{
|
||
|
vehiclesArray->m_nameHash.SetFromString(pFileName);
|
||
|
for(int i=0; i< vehiclesArray->m_Vehicles.GetCount(); ++i)
|
||
|
{
|
||
|
atHashString &parent = vehiclesArray->m_Vehicles[i].m_lockHash;
|
||
|
atArray<ShopVehicleMod> &modsArray = vehiclesArray->m_Vehicles[i].m_vehicleMods;
|
||
|
for(int j=0; j<modsArray.GetCount();j++)
|
||
|
{
|
||
|
if(modsArray[j].m_lockHash.GetHash() == 0)
|
||
|
modsArray[j].m_lockHash = parent;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BuildVehicleLookup();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::RemoveVehiclesCollection(const char* pFilename)
|
||
|
{
|
||
|
s32 index = FindMetaItemsCollectionIndex(m_vehicles, pFilename);
|
||
|
|
||
|
if (index != -1)
|
||
|
{
|
||
|
for (u32 i = 0; i < m_vehicles[index].m_Vehicles.GetCount(); i++)
|
||
|
EXTRACONTENT.RemoveContentLock(m_vehicles[index].m_Vehicles[i].m_lockHash);
|
||
|
|
||
|
m_vehicles.Delete(index);
|
||
|
BuildVehicleLookup();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::BuildVehicleLookup()
|
||
|
{
|
||
|
ShopVehicleDataArray* vehiclesArray = NULL;
|
||
|
|
||
|
m_vehiclesLookup.ResetCount();
|
||
|
m_vehicleGenericModsLookup.ResetCount();
|
||
|
|
||
|
for (u32 vehCount = 0; vehCount < m_vehicles.GetCount(); vehCount++)
|
||
|
{
|
||
|
vehiclesArray = &m_vehicles[vehCount];
|
||
|
|
||
|
if (vehiclesArray)
|
||
|
{
|
||
|
int l = vehiclesArray->m_Vehicles.GetCount();
|
||
|
|
||
|
for (int i = 0 ; i < l ; i++)
|
||
|
{
|
||
|
ShopVehicleData & item = vehiclesArray->m_Vehicles[i];
|
||
|
|
||
|
EXTRACONTENT.InsertContentLock(item.m_lockHash, m_contentRightData[CRT_VEHICLES].m_onLockChangedCBIdx, true);
|
||
|
|
||
|
for (u32 vehModCount = 0; vehModCount < item.m_vehicleMods.GetCount(); vehModCount++)
|
||
|
EXTRACONTENT.InsertContentLock(item.m_vehicleMods[vehModCount].m_lockHash, m_contentRightData[CRT_VEHICLES].m_onLockChangedCBIdx, true);
|
||
|
|
||
|
m_vehiclesLookup.Grow() = &item;
|
||
|
}
|
||
|
l = vehiclesArray->m_VehicleMods.GetCount();
|
||
|
|
||
|
for (int i = 0 ; i < l ; i++)
|
||
|
{
|
||
|
ShopVehicleMod & item = vehiclesArray->m_VehicleMods[i];
|
||
|
|
||
|
EXTRACONTENT.InsertContentLock(item.m_lockHash, m_contentRightData[CRT_VEHICLES].m_onLockChangedCBIdx, true);
|
||
|
m_vehicleGenericModsLookup.Grow() = &item;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const ShopVehicleData* CExtraMetadataMgr::GetShopVehicleData(int idx) const
|
||
|
{
|
||
|
if((u32)idx < (u32)(m_vehiclesLookup.GetCount()))
|
||
|
{
|
||
|
return m_vehiclesLookup[idx];
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
int CExtraMetadataMgr::GetShopVehicleModelNameHash(int idx) const
|
||
|
{
|
||
|
const ShopVehicleData* vehicleData = GetShopVehicleData(idx);
|
||
|
|
||
|
if(vehicleData)
|
||
|
return vehicleData->m_modelNameHash;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int CExtraMetadataMgr::GetNumDLCVehicleMods(int dlcIdx) const
|
||
|
{
|
||
|
if((u32)(dlcIdx) < (u32)(m_vehiclesLookup.GetCount()))
|
||
|
{
|
||
|
return m_vehiclesLookup[dlcIdx]->m_vehicleMods.GetCount();
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
const ShopVehicleMod* CExtraMetadataMgr::GetShopVehicleModData(int dlcIndex, int modIndex) const
|
||
|
{
|
||
|
if((u32)(dlcIndex) < (u32)(m_vehiclesLookup.GetCount()))
|
||
|
{
|
||
|
if((u32)(modIndex) < (u32)(m_vehiclesLookup[dlcIndex]->m_vehicleMods.GetCount()))
|
||
|
{
|
||
|
return &(m_vehiclesLookup[dlcIndex]->m_vehicleMods[modIndex]);
|
||
|
}
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
const atArray<ShopVehicleMod*>& CExtraMetadataMgr::GetGenericVehicleModList()
|
||
|
{
|
||
|
return m_vehicleGenericModsLookup;
|
||
|
}
|
||
|
|
||
|
// WEAPON Metadata helpers
|
||
|
void CExtraMetadataMgr::AddWeaponShopItemsCollection(const char* pFileName)
|
||
|
{
|
||
|
if (WeaponShopItemArray* weapons = AddMetaItem(m_weaponShopItems, pFileName))
|
||
|
{
|
||
|
for(int i=0; i< weapons->m_weaponShopItems.GetCount(); ++i)
|
||
|
{
|
||
|
atHashString &parent = weapons->m_weaponShopItems[i].m_lockHash;
|
||
|
atArray<ShopWeaponComponent> &componentsArray = weapons->m_weaponShopItems[i].m_weaponComponents;
|
||
|
for(int j=0; j<componentsArray.GetCount();j++)
|
||
|
{
|
||
|
if(componentsArray[j].m_lockHash.GetHash() == 0)
|
||
|
componentsArray[j].m_lockHash = parent;
|
||
|
}
|
||
|
}
|
||
|
BuildWeaponLookup();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::RemoveWeaponShopItemsCollection(const char* pFileName)
|
||
|
{
|
||
|
const int collectionIdx = FindMetaItemsCollectionIndex(m_weaponShopItems, pFileName);
|
||
|
|
||
|
if (collectionIdx >= 0)
|
||
|
{
|
||
|
for (u32 i = 0 ; i < m_weaponShopItems[collectionIdx].m_weaponShopItems.GetCount() ; i++)
|
||
|
EXTRACONTENT.RemoveContentLock(m_weaponShopItems[collectionIdx].m_weaponShopItems[i].m_lockHash);
|
||
|
|
||
|
m_weaponShopItems.DeleteFast(collectionIdx);
|
||
|
}
|
||
|
|
||
|
BuildWeaponLookup();
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::BuildWeaponLookup()
|
||
|
{
|
||
|
m_weaponShopItemsLookup.ResetCount();
|
||
|
|
||
|
for (u32 i = 0; i < m_weaponShopItems.GetCount(); i++)
|
||
|
{
|
||
|
for (u32 j = 0 ; j < m_weaponShopItems[i].m_weaponShopItems.GetCount() ; j++)
|
||
|
{
|
||
|
WeaponShopItem & item = m_weaponShopItems[i].m_weaponShopItems[j];
|
||
|
|
||
|
EXTRACONTENT.InsertContentLock(item.m_lockHash, m_contentRightData[CRT_WEAPONS].m_onLockChangedCBIdx, true);
|
||
|
|
||
|
for (u32 wepCompCount = 0; wepCompCount < item.m_weaponComponents.GetCount(); wepCompCount++)
|
||
|
EXTRACONTENT.InsertContentLock(item.m_weaponComponents[wepCompCount].m_lockHash, m_contentRightData[CRT_VEHICLES].m_onLockChangedCBIdx, true);
|
||
|
|
||
|
m_weaponShopItemsLookup.Grow() = &item;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int CExtraMetadataMgr::GetNumDLCWeaponsSP()const
|
||
|
{
|
||
|
int iNumSPWeapons = 0;
|
||
|
for (int i = 0; i < m_weaponShopItemsLookup.GetCount(); i++)
|
||
|
{
|
||
|
if (m_weaponShopItemsLookup[i]->m_availableInSP)
|
||
|
{
|
||
|
iNumSPWeapons++;
|
||
|
}
|
||
|
}
|
||
|
return iNumSPWeapons;
|
||
|
}
|
||
|
s32 CExtraMetadataMgr::GetIndexForSPWeapons(int index) const
|
||
|
{
|
||
|
u32 uNumOfSPWeaponsFound = 0;
|
||
|
for (int i = 0; i < m_weaponShopItemsLookup.GetCount(); i++)
|
||
|
{
|
||
|
if (m_weaponShopItemsLookup[i]->m_availableInSP)
|
||
|
{
|
||
|
if (uNumOfSPWeaponsFound == (u32)index)
|
||
|
{
|
||
|
return i;
|
||
|
}
|
||
|
uNumOfSPWeaponsFound++;
|
||
|
}
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
const WeaponShopItem* CExtraMetadataMgr::GetDLCWeaponShopItem(int idx) const
|
||
|
{
|
||
|
if((u32)(idx) < (u32)(m_weaponShopItemsLookup.GetCount()))
|
||
|
return m_weaponShopItemsLookup[idx];
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
const ShopWeaponComponent* CExtraMetadataMgr::GetShopWeaponComponentData(int dlcIdx, int componentIdx) const
|
||
|
{
|
||
|
if((u32)(dlcIdx) < (u32)(m_weaponShopItemsLookup.GetCount()))
|
||
|
{
|
||
|
if((u32)(componentIdx) < (u32)(m_weaponShopItemsLookup[dlcIdx]->m_weaponComponents.GetCount()))
|
||
|
{
|
||
|
return &(m_weaponShopItemsLookup[dlcIdx]->m_weaponComponents[componentIdx]);
|
||
|
}
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
const int CExtraMetadataMgr::GetNumDLCWeaponComponents(int idx) const
|
||
|
{
|
||
|
if((u32)(idx) < (u32)(m_weaponShopItemsLookup.GetCount()))
|
||
|
{
|
||
|
return m_weaponShopItemsLookup[idx]->m_weaponComponents.GetCount();
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
const int CExtraMetadataMgr::GetNumDLCWeaponComponentsSP(int idx) const
|
||
|
{
|
||
|
if ((u32)(idx) < (u32)(m_weaponShopItemsLookup.GetCount()))
|
||
|
{
|
||
|
if (m_weaponShopItemsLookup[idx]->m_availableInSP)
|
||
|
{
|
||
|
return m_weaponShopItemsLookup[idx]->m_weaponComponents.GetCount();
|
||
|
}
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
//TATTOO Metadata helpers
|
||
|
void CExtraMetadataMgr::AddTattooShopItemsCollection(const char* pFileName)
|
||
|
{
|
||
|
if (TattooShopItemArray* tattoos = AddMetaItem(m_tattooShopsItems, pFileName))
|
||
|
{
|
||
|
// If everything was alright, add new entries to the faction lookup. No need to rebuild in here: other indexes didn't get messed
|
||
|
const int collectionIdx = m_tattooShopsItems.GetCount() - 1;
|
||
|
|
||
|
for (int i=0; i < tattoos->TattooShopItems.GetCount(); ++i)
|
||
|
{
|
||
|
if( dlcVerifyf(tattoos->TattooShopItems[i].m_eFaction<m_tattooShopItemsLookup.size(), "CExtraMetadataMgr::AddTattooShopItemsCollection trying to add item for faction out of bounds. BAD DATA! (%s)", pFileName) )
|
||
|
{
|
||
|
tattooLookupEntry& appended = m_tattooShopItemsLookup[tattoos->TattooShopItems[i].m_eFaction].Grow(TATTOO_ITEM_LOOKUP_GROW);
|
||
|
appended.collection = (u16)collectionIdx;
|
||
|
appended.index = (u16)i;
|
||
|
}
|
||
|
|
||
|
EXTRACONTENT.InsertContentLock(tattoos->TattooShopItems[i].m_lockHash, m_contentRightData[CRT_TATTOOS].m_onLockChangedCBIdx, true);
|
||
|
}
|
||
|
|
||
|
// Also cache this collection hash
|
||
|
tattoos->m_nameHash.SetFromString(pFileName);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::RemoveTattooShopItemsCollection(const char* pFileName)
|
||
|
{
|
||
|
const int collectionIdx = FindMetaItemsCollectionIndex(m_tattooShopsItems, pFileName);
|
||
|
|
||
|
if( collectionIdx >= 0 )
|
||
|
{
|
||
|
for (u32 i = 0; i < m_tattooShopsItems[collectionIdx].TattooShopItems.GetCount(); i++)
|
||
|
EXTRACONTENT.RemoveContentLock(m_tattooShopsItems[collectionIdx].TattooShopItems[i].m_lockHash);
|
||
|
|
||
|
m_tattooShopsItems.Delete(collectionIdx);
|
||
|
|
||
|
// Rebuild whole lookup table. This is not that expensive, even if happens N times in same frame because of removing multiple collections.
|
||
|
// This also doesn't seem likely to get triggered: compatibility packs have all extra data and always need to be there. Maybe just on SP-only dlcs unmounting?
|
||
|
BuildTattooShopItemsLookup();
|
||
|
BANK_ONLY(TattooRefreshCB();)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::BuildTattooShopItemsLookup()
|
||
|
{
|
||
|
// Clean lookup tables first. Do not need to reclaim memory, just free their slots.
|
||
|
for (int iFaction=0; iFaction < m_tattooShopItemsLookup.size(); ++iFaction)
|
||
|
{
|
||
|
m_tattooShopItemsLookup[iFaction].Resize(0);
|
||
|
}
|
||
|
|
||
|
for(int iColl=0; iColl<m_tattooShopsItems.GetCount(); ++iColl)
|
||
|
{
|
||
|
const TattooShopItemArray& shopItemArray = m_tattooShopsItems[iColl];
|
||
|
for(int jItem=0; jItem<shopItemArray.TattooShopItems.GetCount(); ++jItem)
|
||
|
{
|
||
|
if( dlcVerifyf(shopItemArray.TattooShopItems[jItem].m_eFaction<m_tattooShopItemsLookup.size(), "CExtraMetadataMgr::BuildTattooShopLookup trying to add item for faction out of bounds. BAD DATA!") )
|
||
|
{
|
||
|
tattooLookupEntry& appended = m_tattooShopItemsLookup[shopItemArray.TattooShopItems[jItem].m_eFaction].Grow(TATTOO_ITEM_LOOKUP_GROW);
|
||
|
appended.collection = (u16)iColl;
|
||
|
appended.index = (u16)jItem;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::FixupGlobalIndices(const CPedModelInfo* pedModelInfo, const CPedVariationInfo* newInfo, const CPedVariationInfoCollection* varInfoCollection)
|
||
|
{
|
||
|
if (pedModelInfo && newInfo && varInfoCollection && newInfo->GetDlcNameHash() != 0)
|
||
|
{
|
||
|
for (u32 i = 0; i < m_shopPedApparel.GetCount(); i++)
|
||
|
{
|
||
|
ShopPedApparel& pedApparel = *m_shopPedApparel[i];
|
||
|
u32 pedNameHash = atStringHash(pedApparel.m_pedName.c_str());
|
||
|
u32 dlcNameHash = atStringHash(pedApparel.m_dlcName.c_str());
|
||
|
|
||
|
if (pedNameHash == pedModelInfo->GetModelNameHash() && dlcNameHash == newInfo->GetDlcNameHash())
|
||
|
{
|
||
|
for (u32 j = 0; j < pedApparel.m_pedComponents.GetCount(); j++)
|
||
|
{
|
||
|
ShopPedComponent& item = pedApparel.m_pedComponents[j];
|
||
|
u32 globalIndex = varInfoCollection->GetGlobalDrawableIndex(item.m_localDrawableIndex, (ePedVarComp)item.m_eCompType, dlcNameHash);
|
||
|
|
||
|
dlcDebugf3("FixupGlobalIndices - Globalizing drawable index from %i -> %i [%s_%s]", item.m_localDrawableIndex, globalIndex, pedApparel.m_pedName.c_str(), pedApparel.m_dlcName.c_str());
|
||
|
|
||
|
item.m_drawableIndex = globalIndex;
|
||
|
}
|
||
|
|
||
|
for (u32 j = 0; j < pedApparel.m_pedProps.GetCount(); j++)
|
||
|
{
|
||
|
ShopPedProp& item = pedApparel.m_pedProps[j];
|
||
|
u32 globalIndex = varInfoCollection->GetGlobalPropIndex(item.m_localPropIndex, (eAnchorPoints)item.m_eAnchorPoint, dlcNameHash);
|
||
|
|
||
|
dlcDebugf3("FixupGlobalIndices - Globalizing prop index from %i -> %i [%s_%s]", item.m_localPropIndex, globalIndex, pedApparel.m_pedName.c_str(), pedApparel.m_dlcName.c_str());
|
||
|
|
||
|
Assertf(globalIndex < 255, "FixupGlobalIndices[Prop] - Global index is large and likely to cause issues");
|
||
|
|
||
|
item.m_propIndex = (u8)globalIndex;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if __BANK && !__SPU
|
||
|
RefreshBankWidgets();
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::RebuildApparelLookup()
|
||
|
{
|
||
|
m_shopPedApparelLookup.ResetCount();
|
||
|
|
||
|
for (u32 i = 0; i < m_shopPedApparel.GetCount(); i++)
|
||
|
{
|
||
|
ShopPedApparel& currApparelData = *m_shopPedApparel[i];
|
||
|
|
||
|
for (u32 compIdx = 0; compIdx < currApparelData.m_pedComponents.GetCount(); compIdx++)
|
||
|
m_shopPedApparelLookup.Insert(currApparelData.m_pedComponents[compIdx].m_uniqueNameHash, ShopPedApparelLookupEntry(SHOP_PED_COMPONENT, i, compIdx));
|
||
|
|
||
|
for (u32 propIdx = 0; propIdx < currApparelData.m_pedProps.GetCount(); propIdx++)
|
||
|
m_shopPedApparelLookup.Insert(currApparelData.m_pedProps[propIdx].m_uniqueNameHash, ShopPedApparelLookupEntry(SHOP_PED_PROP, i, propIdx));
|
||
|
|
||
|
for (u32 outfitIdx = 0; outfitIdx < currApparelData.m_pedOutfits.GetCount(); outfitIdx++)
|
||
|
m_shopPedApparelLookup.Insert(currApparelData.m_pedOutfits[outfitIdx].m_uniqueNameHash, ShopPedApparelLookupEntry(SHOP_PED_OUTFIT, i, outfitIdx));
|
||
|
}
|
||
|
|
||
|
m_shopPedApparelLookup.FinishInsertion();
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::AddShopPedApparel(const char* pFilename)
|
||
|
{
|
||
|
// Reset any current queries
|
||
|
m_shopPedApparelCompQuery.ResetCount();
|
||
|
m_shopPedApparelPropQuery.ResetCount();
|
||
|
m_shopPedApparelOutfitQuery.ResetCount();
|
||
|
|
||
|
if (ShopPedApparel* newShopApparel = AddMetaItemPtr<ShopPedApparel>(m_shopPedApparel, pFilename))
|
||
|
{
|
||
|
RebuildApparelLookup();
|
||
|
|
||
|
// Insert content locks
|
||
|
for (u32 i = 0; i < newShopApparel->m_pedComponents.GetCount(); i++)
|
||
|
EXTRACONTENT.InsertContentLock(newShopApparel->m_pedComponents[i].m_lockHash, m_contentRightData[CRT_PED_APPAREL].m_onLockChangedCBIdx, true);
|
||
|
|
||
|
for (u32 i = 0; i < newShopApparel->m_pedProps.GetCount(); i++)
|
||
|
EXTRACONTENT.InsertContentLock(newShopApparel->m_pedProps[i].m_lockHash, m_contentRightData[CRT_PED_APPAREL].m_onLockChangedCBIdx, true);
|
||
|
|
||
|
for (u32 i = 0; i < newShopApparel->m_pedOutfits.GetCount(); i++)
|
||
|
EXTRACONTENT.InsertContentLock(newShopApparel->m_pedOutfits[i].m_lockHash, m_contentRightData[CRT_PED_APPAREL].m_onLockChangedCBIdx, true);
|
||
|
|
||
|
AddPedDLCMetaFiles(newShopApparel->m_pedName.c_str(), atStringHash(newShopApparel->m_dlcName),
|
||
|
newShopApparel->m_fullDlcName, newShopApparel->m_creatureMetaData);
|
||
|
}
|
||
|
|
||
|
#if __BANK && !__SPU
|
||
|
RefreshBankWidgets();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::RemoveShopPedApparel(const char* pFilename)
|
||
|
{
|
||
|
// Reset any current queries
|
||
|
m_shopPedApparelCompQuery.ResetCount();
|
||
|
m_shopPedApparelPropQuery.ResetCount();
|
||
|
m_shopPedApparelOutfitQuery.ResetCount();
|
||
|
|
||
|
s32 itemIdx = FindMetaItemsCollectionIndexPtr(m_shopPedApparel, pFilename);
|
||
|
|
||
|
if (itemIdx >= 0)
|
||
|
{
|
||
|
ShopPedApparel& shopApparelToRemove = *m_shopPedApparel[itemIdx];
|
||
|
|
||
|
// Remove content locks
|
||
|
for (u32 i = 0; i < shopApparelToRemove.m_pedComponents.GetCount(); i++)
|
||
|
EXTRACONTENT.RemoveContentLock(shopApparelToRemove.m_pedComponents[i].m_lockHash);
|
||
|
|
||
|
for (u32 i = 0; i < shopApparelToRemove.m_pedProps.GetCount(); i++)
|
||
|
EXTRACONTENT.RemoveContentLock(shopApparelToRemove.m_pedProps[i].m_lockHash);
|
||
|
|
||
|
for (u32 i = 0; i < shopApparelToRemove.m_pedOutfits.GetCount(); i++)
|
||
|
EXTRACONTENT.RemoveContentLock(shopApparelToRemove.m_pedOutfits[i].m_lockHash);
|
||
|
|
||
|
RemovePedDLCMetaFiles(shopApparelToRemove.m_pedName.c_str(), atStringHash(shopApparelToRemove.m_dlcName),
|
||
|
shopApparelToRemove.m_fullDlcName, shopApparelToRemove.m_creatureMetaData);
|
||
|
|
||
|
delete m_shopPedApparel[itemIdx];
|
||
|
m_shopPedApparel.DeleteFast(itemIdx);
|
||
|
RebuildApparelLookup();
|
||
|
}
|
||
|
|
||
|
#if __BANK && !__SPU
|
||
|
RefreshBankWidgets();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
SPedDLCMetaFiles* CExtraMetadataMgr::FindPedDLCMetaFiles(const char* pedName)
|
||
|
{
|
||
|
for (u32 i = 0; i < m_pedDLCMetaFiles.GetCount(); i++)
|
||
|
{
|
||
|
if (m_pedDLCMetaFiles[i].m_pedName == pedName)
|
||
|
return &m_pedDLCMetaFiles[i];
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
SPedDLCPackMetaFiles* CExtraMetadataMgr::FindPedDLCPackMetaFiles(SPedDLCMetaFiles* parentInfo, u32 dlcNameHash)
|
||
|
{
|
||
|
if (parentInfo)
|
||
|
{
|
||
|
for (u32 i = 0; i < parentInfo->m_pedDLCPackMetaFiles.GetCount(); i++)
|
||
|
{
|
||
|
if (parentInfo->m_pedDLCPackMetaFiles[i].m_dlcNameHash == dlcNameHash)
|
||
|
return &parentInfo->m_pedDLCPackMetaFiles[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::AddPedDLCMetaFiles(const char* pedName, u32 dlcNameHash, u32 varInfoNameHash, u32 creatureMetaNameHash)
|
||
|
{
|
||
|
fwModelId modelInfo;
|
||
|
CPedModelInfo* pedModelInfo = (CPedModelInfo*)CModelInfo::GetBaseModelInfoFromName(pedName, &modelInfo);
|
||
|
|
||
|
if (Verifyf(pedModelInfo && modelInfo.IsValid(), "CExtraMetadataMgr::AddPedDLCMetaFiles - Invalid model info! %s", pedName))
|
||
|
{
|
||
|
if (Verifyf(!IsModelInMemory(modelInfo), "CExtraMetadataMgr::AddPedDLCMetaFiles - Ped is already in memory! Ped Name: %s", pedName))
|
||
|
{
|
||
|
SPedDLCMetaFiles* dlcMetaFiles = FindPedDLCMetaFiles(pedName);
|
||
|
SPedDLCPackMetaFiles* dlcPackMetaFiles = FindPedDLCPackMetaFiles(dlcMetaFiles, dlcNameHash);
|
||
|
|
||
|
// Find or create the information about this DLC meta file for the given ped
|
||
|
if (!dlcMetaFiles)
|
||
|
{
|
||
|
dlcMetaFiles = &m_pedDLCMetaFiles.Grow(1);
|
||
|
dlcMetaFiles->Reset();
|
||
|
dlcMetaFiles->m_pedName = pedName;
|
||
|
}
|
||
|
|
||
|
if (!dlcPackMetaFiles)
|
||
|
{
|
||
|
dlcPackMetaFiles = &dlcMetaFiles->m_pedDLCPackMetaFiles.Grow(1);
|
||
|
dlcPackMetaFiles->Reset();
|
||
|
dlcPackMetaFiles->m_dlcNameHash = dlcNameHash;
|
||
|
}
|
||
|
|
||
|
s32 varInfoIndex = g_fwMetaDataStore.FindSlotFromHashKey(varInfoNameHash).Get();
|
||
|
if (varInfoIndex != -1)
|
||
|
{
|
||
|
pedModelInfo->SetPedMetaDataFile(varInfoIndex);
|
||
|
dlcPackMetaFiles->m_varInfoIndices.PushAndGrow(varInfoIndex, 1);
|
||
|
}
|
||
|
|
||
|
s32 createMetaIndex = g_fwMetaDataStore.FindSlotFromHashKey(creatureMetaNameHash).Get();
|
||
|
if (createMetaIndex != -1)
|
||
|
{
|
||
|
dlcPackMetaFiles->m_creatureIndices.PushAndGrow(createMetaIndex, 1);
|
||
|
}
|
||
|
strLocalIndex expressionSlot = g_ExpressionDictionaryStore.FindSlotFromHashKey(dlcNameHash);
|
||
|
if(expressionSlot.IsValid())
|
||
|
{
|
||
|
strIndex index = g_ExpressionDictionaryStore.GetStreamingIndex(expressionSlot);
|
||
|
strStreamingEngine::GetInfo().RequestObject(index,STRFLAG_DONTDELETE|STRFLAG_FORCE_LOAD);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::RemovePedDLCMetaFiles(const char* pedName, u32 dlcNameHash, u32 varInfoNameHash, u32 creatureMetaNameHash)
|
||
|
{
|
||
|
fwModelId modelInfo;
|
||
|
CPedModelInfo* pedModelInfo = (CPedModelInfo*)CModelInfo::GetBaseModelInfoFromName(pedName, &modelInfo);
|
||
|
strLocalIndex expressionSlot = g_ExpressionDictionaryStore.FindSlotFromHashKey(dlcNameHash);
|
||
|
if(expressionSlot.IsValid())
|
||
|
{
|
||
|
strIndex index = g_ExpressionDictionaryStore.GetStreamingIndex(expressionSlot);
|
||
|
strStreamingEngine::GetInfo().ClearRequiredFlag(index, STRFLAG_FORCE_LOAD|STRFLAG_DONTDELETE);
|
||
|
strStreamingEngine::GetInfo().RemoveObject(index);
|
||
|
}
|
||
|
if (Verifyf(pedModelInfo && modelInfo.IsValid(), "CExtraMetadataMgr::AddPedDLCMetaFiles - Invalid model info! %s", pedName))
|
||
|
{
|
||
|
if (Verifyf(!IsModelInMemory(modelInfo), "CExtraMetadataMgr::RemovePedDLCMetaFiles - Ped is already in memory! Ped Name: %s", pedName))
|
||
|
{
|
||
|
SPedDLCMetaFiles* dlcMetaFiles = FindPedDLCMetaFiles(pedName);
|
||
|
SPedDLCPackMetaFiles* dlcPackMetaFiles = FindPedDLCPackMetaFiles(dlcMetaFiles, dlcNameHash);
|
||
|
|
||
|
if (Verifyf(dlcPackMetaFiles, "CExtraMetadataMgr::RemovePedDLCMetaFiles - Could not find DLC pack meta files! %s", pedName))
|
||
|
{
|
||
|
s32 varInfoIndex = g_fwMetaDataStore.FindSlotFromHashKey(varInfoNameHash).Get();
|
||
|
if (varInfoIndex != -1)
|
||
|
{
|
||
|
pedModelInfo->RemovePedMetaDataFile(varInfoIndex);
|
||
|
dlcPackMetaFiles->m_varInfoIndices.DeleteMatches(varInfoIndex);
|
||
|
}
|
||
|
|
||
|
s32 createMetaIndex = g_fwMetaDataStore.FindSlotFromHashKey(creatureMetaNameHash).Get();
|
||
|
if (createMetaIndex != -1)
|
||
|
{
|
||
|
dlcPackMetaFiles->m_creatureIndices.DeleteMatches(createMetaIndex);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool CExtraMetadataMgr::IsModelInMemory(fwModelId modelInfo)
|
||
|
{
|
||
|
return (CModelInfo::AreAssetsLoading(modelInfo) || CModelInfo::AreAssetsRequested(modelInfo) || CModelInfo::HaveAssetsLoaded(modelInfo));
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::RemoveAllPedDLCMetaFiles()
|
||
|
{
|
||
|
fwModelId modelInfo;
|
||
|
CPedModelInfo* pedModelInfo = NULL;
|
||
|
|
||
|
for (u32 i = 0; i < m_pedDLCMetaFiles.GetCount(); i++)
|
||
|
{
|
||
|
SPedDLCMetaFiles& currPedDLCMetaFiles = m_pedDLCMetaFiles[i];
|
||
|
pedModelInfo = (CPedModelInfo*)CModelInfo::GetBaseModelInfoFromName(currPedDLCMetaFiles.m_pedName.c_str(), &modelInfo);
|
||
|
|
||
|
if (pedModelInfo && modelInfo.IsValid())
|
||
|
{
|
||
|
if (Verifyf(!IsModelInMemory(modelInfo), "CExtraMetadataMgr::RemoveAllPedDLCMetaFiles - Ped is already in memory! Ped Name: %s", currPedDLCMetaFiles.m_pedName.c_str()))
|
||
|
{
|
||
|
for (u32 j = 0; j < currPedDLCMetaFiles.m_pedDLCPackMetaFiles.GetCount(); j++)
|
||
|
{
|
||
|
SPedDLCPackMetaFiles& currPedDLCPackMetaFiles = currPedDLCMetaFiles.m_pedDLCPackMetaFiles[j];
|
||
|
|
||
|
for (u32 k = 0; k < currPedDLCPackMetaFiles.m_varInfoIndices.GetCount(); k++)
|
||
|
{
|
||
|
pedModelInfo->RemovePedMetaDataFile(currPedDLCPackMetaFiles.m_varInfoIndices[k]);
|
||
|
currPedDLCPackMetaFiles.m_varInfoIndices.DeleteMatches(currPedDLCPackMetaFiles.m_varInfoIndices[k]);
|
||
|
}
|
||
|
|
||
|
for (u32 k = 0; k < currPedDLCPackMetaFiles.m_creatureIndices.GetCount(); k++)
|
||
|
currPedDLCPackMetaFiles.m_creatureIndices.DeleteMatches(currPedDLCPackMetaFiles.m_creatureIndices[k]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_pedDLCMetaFiles.Reset();
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::GetCreatureMetaDataIndices(CPedModelInfo* lookupModelInfo, atFixedArray<SPedDLCMetaFileQueryData, STREAMING_MAX_DEPENDENCIES>& targetArray)
|
||
|
{
|
||
|
fwModelId modelInfo;
|
||
|
CPedModelInfo* currPedModelInfo = NULL;
|
||
|
s32 diskStoreIndex = lookupModelInfo->GetCreatureMetadataFileIndex().Get();
|
||
|
|
||
|
targetArray.Reset();
|
||
|
|
||
|
if (diskStoreIndex >= 0)
|
||
|
{
|
||
|
SPedDLCMetaFileQueryData& diskData = targetArray.Append();
|
||
|
|
||
|
diskData.m_dlcNameHash = 0;
|
||
|
diskData.m_storeIndex = diskStoreIndex;
|
||
|
}
|
||
|
|
||
|
for (u32 i = 0; i < m_pedDLCMetaFiles.GetCount(); i++)
|
||
|
{
|
||
|
SPedDLCMetaFiles& currDLCMetaFiles = m_pedDLCMetaFiles[i];
|
||
|
|
||
|
currPedModelInfo = (CPedModelInfo*)CModelInfo::GetBaseModelInfoFromName(currDLCMetaFiles.m_pedName.c_str(), &modelInfo);
|
||
|
|
||
|
if (currPedModelInfo == lookupModelInfo)
|
||
|
{
|
||
|
for (u32 j = 0; j < currDLCMetaFiles.m_pedDLCPackMetaFiles.GetCount(); j++)
|
||
|
{
|
||
|
SPedDLCPackMetaFiles& currDLCPackMetaFiles = currDLCMetaFiles.m_pedDLCPackMetaFiles[j];
|
||
|
|
||
|
for (u32 k = 0; k < currDLCPackMetaFiles.m_creatureIndices.GetCount(); k++)
|
||
|
{
|
||
|
SPedDLCMetaFileQueryData& dlcData = targetArray.Append();
|
||
|
|
||
|
dlcData.m_dlcNameHash = currDLCPackMetaFiles.m_dlcNameHash;
|
||
|
dlcData.m_storeIndex = currDLCPackMetaFiles.m_creatureIndices[k];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
u32 CExtraMetadataMgr::GetHashNameForComponent(s32 pedIndex, ePedVarComp componentType, u32 drawableIndex, u32 textureIndex)
|
||
|
{
|
||
|
if (const CPed* pPed = CTheScripts::GetEntityToQueryFromGUID<CPed>(pedIndex))
|
||
|
{
|
||
|
if (CPedModelInfo* pedModelInfo = pPed->GetPedModelInfo())
|
||
|
{
|
||
|
if (CPedVariationInfoCollection* pedVarInfoCollection = pedModelInfo->GetVarInfo())
|
||
|
{
|
||
|
if (const char* dlcName = pedVarInfoCollection->GetDlcNameFromDrawableIdx(componentType, drawableIndex))
|
||
|
{
|
||
|
for (u32 i = 0; i < m_shopPedApparel.GetCount(); i++)
|
||
|
{
|
||
|
ShopPedApparel& currPedApparel = *m_shopPedApparel[i];
|
||
|
|
||
|
// Try to find the shop data with this DLC name
|
||
|
if (stricmp(dlcName, currPedApparel.m_dlcName.c_str()) == 0)
|
||
|
{
|
||
|
// Try to find the component in the shop data with the specified drawable/texture indices
|
||
|
for (u32 j = 0; j < currPedApparel.m_pedComponents.GetCount(); j++)
|
||
|
{
|
||
|
ShopPedComponent& currComponent = currPedApparel.m_pedComponents[j];
|
||
|
|
||
|
if (currComponent.m_drawableIndex == drawableIndex &&
|
||
|
currComponent.m_textureIndex == textureIndex &&
|
||
|
currComponent.m_eCompType == componentType)
|
||
|
return currComponent.m_uniqueNameHash;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
u32 CExtraMetadataMgr::GetHashNameForProp(s32 pedIndex, eAnchorPoints anchorPoint, u32 propIndex, u32 textureIndex)
|
||
|
{
|
||
|
if (const CPed* pPed = CTheScripts::GetEntityToQueryFromGUID<CPed>(pedIndex))
|
||
|
{
|
||
|
return GetHashNameForProp(pPed, anchorPoint, propIndex, textureIndex);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
u32 CExtraMetadataMgr::GetHashNameForProp(const CPed* pPed, eAnchorPoints anchorPoint, u32 propIndex, u32 textureIndex)
|
||
|
{
|
||
|
if (pPed)
|
||
|
{
|
||
|
if (CPedModelInfo* pedModelInfo = pPed->GetPedModelInfo())
|
||
|
{
|
||
|
if (CPedVariationInfoCollection* pedVarInfoCollection = pedModelInfo->GetVarInfo())
|
||
|
{
|
||
|
if (const char* dlcName = pedVarInfoCollection->GetDlcNameFromPropIdx(anchorPoint, propIndex))
|
||
|
{
|
||
|
for (u32 i = 0; i < m_shopPedApparel.GetCount(); i++)
|
||
|
{
|
||
|
ShopPedApparel& currPedApparel = *m_shopPedApparel[i];
|
||
|
|
||
|
// Try to find the shop data with this DLC name
|
||
|
if (stricmp(dlcName, currPedApparel.m_dlcName.c_str()) == 0)
|
||
|
{
|
||
|
// Try to find the component in the shop data with the specified prop/texture indices
|
||
|
for (u32 j = 0; j < currPedApparel.m_pedProps.GetCount(); j++)
|
||
|
{
|
||
|
ShopPedProp& currProp = currPedApparel.m_pedProps[j];
|
||
|
|
||
|
if (currProp.m_propIndex == propIndex &&
|
||
|
currProp.m_textureIndex == textureIndex &&
|
||
|
currProp.m_eAnchorPoint == anchorPoint)
|
||
|
return currProp.m_uniqueNameHash;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
s32 CExtraMetadataMgr::GetShopPedApparelVariantPropsCount(u32 nameHash)
|
||
|
{
|
||
|
BaseShopPedApparel* baseShopItem = GetShopPedApparel(nameHash);
|
||
|
|
||
|
if (baseShopItem)
|
||
|
return baseShopItem->m_variantProps.GetCount();
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
s32 CExtraMetadataMgr::GetShopPedApparelVariantComponentsCount(u32 nameHash)
|
||
|
{
|
||
|
BaseShopPedApparel* baseShopItem = GetShopPedApparel(nameHash);
|
||
|
|
||
|
if (baseShopItem)
|
||
|
return baseShopItem->m_variantComponents.GetCount();
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::GetVariantProp(u32 nameHash, u32 variantPropIndex, s32& variantPropNameHash, s32& variantPropEnumValue, s32& variantPropAnchor)
|
||
|
{
|
||
|
BaseShopPedApparel* baseShopItem = GetShopPedApparel(nameHash);
|
||
|
|
||
|
if (baseShopItem)
|
||
|
{
|
||
|
if (Verifyf(variantPropIndex < baseShopItem->m_variantProps.GetCount(),
|
||
|
"CExtraMetadataMgr::GetVariantProp - Invalid index supplied! %u/%u", variantPropIndex, baseShopItem->m_variantProps.GetCount()))
|
||
|
{
|
||
|
variantPropNameHash = baseShopItem->m_variantProps[variantPropIndex].m_nameHash;
|
||
|
variantPropEnumValue = (s32)baseShopItem->m_variantProps[variantPropIndex].m_enumValue;
|
||
|
variantPropAnchor = (s32)baseShopItem->m_variantProps[variantPropIndex].m_eAnchorPoint;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::GetVariantComponent(u32 nameHash, u32 variantComponentIndex, s32& variantComponentNameHash, s32& variantComponentEnumValue, s32& variantComponentType)
|
||
|
{
|
||
|
BaseShopPedApparel* baseShopItem = GetShopPedApparel(nameHash);
|
||
|
|
||
|
if (baseShopItem)
|
||
|
{
|
||
|
if (Verifyf(variantComponentIndex < baseShopItem->m_variantComponents.GetCount(),
|
||
|
"CExtraMetadataMgr::GetVariantComponent - Invalid index supplied! %u/%u", variantComponentIndex, baseShopItem->m_variantComponents.GetCount()))
|
||
|
{
|
||
|
variantComponentNameHash = baseShopItem->m_variantComponents[variantComponentIndex].m_nameHash;
|
||
|
variantComponentEnumValue = (s32)baseShopItem->m_variantComponents[variantComponentIndex].m_enumValue;
|
||
|
variantComponentType = (s32)baseShopItem->m_variantComponents[variantComponentIndex].m_eCompType;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
s32 CExtraMetadataMgr::GetShopPedApparelForcedPropsCount(u32 nameHash)
|
||
|
{
|
||
|
BaseShopPedApparel* baseShopItem = GetShopPedApparel(nameHash);
|
||
|
|
||
|
if (baseShopItem)
|
||
|
return baseShopItem->m_forcedProps.GetCount();
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
s32 CExtraMetadataMgr::GetShopPedApparelForcedComponentsCount(u32 nameHash)
|
||
|
{
|
||
|
BaseShopPedApparel* baseShopItem = GetShopPedApparel(nameHash);
|
||
|
|
||
|
if (baseShopItem)
|
||
|
return baseShopItem->m_forcedComponents.GetCount();
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::GetForcedProp(u32 nameHash, u32 forcedPropIndex, s32& forcedPropNameHash, s32& forcedPropEnumValue, s32& forcedPropAnchor)
|
||
|
{
|
||
|
BaseShopPedApparel* baseShopItem = GetShopPedApparel(nameHash);
|
||
|
|
||
|
if (baseShopItem)
|
||
|
{
|
||
|
if (Verifyf(forcedPropIndex < baseShopItem->m_forcedProps.GetCount(),
|
||
|
"CExtraMetadataMgr::GetForcedProp - Invalid index supplied! %u/%u", forcedPropIndex, baseShopItem->m_forcedProps.GetCount()))
|
||
|
{
|
||
|
forcedPropNameHash = baseShopItem->m_forcedProps[forcedPropIndex].m_nameHash;
|
||
|
forcedPropEnumValue = (s32)baseShopItem->m_forcedProps[forcedPropIndex].m_enumValue;
|
||
|
forcedPropAnchor = (s32)baseShopItem->m_forcedProps[forcedPropIndex].m_eAnchorPoint;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::GetForcedComponent(u32 nameHash, u32 forcedComponentIndex, s32& forcedComponentNameHash, s32& forcedComponentEnumValue, s32& forcedComponentType)
|
||
|
{
|
||
|
BaseShopPedApparel* baseShopItem = GetShopPedApparel(nameHash);
|
||
|
|
||
|
if (baseShopItem)
|
||
|
{
|
||
|
if (Verifyf(forcedComponentIndex < baseShopItem->m_forcedComponents.GetCount(),
|
||
|
"CExtraMetadataMgr::GetForcedComponent - Invalid index supplied! %u/%u", forcedComponentIndex, baseShopItem->m_forcedComponents.GetCount()))
|
||
|
{
|
||
|
forcedComponentNameHash = baseShopItem->m_forcedComponents[forcedComponentIndex].m_nameHash;
|
||
|
forcedComponentEnumValue = (s32)baseShopItem->m_forcedComponents[forcedComponentIndex].m_enumValue;
|
||
|
forcedComponentType = (s32)baseShopItem->m_forcedComponents[forcedComponentIndex].m_eCompType;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool CExtraMetadataMgr::DoesShopPedApparelHaveRestrictionTag(u32 nameHash, u32 tagHash)
|
||
|
{
|
||
|
BaseShopPedApparel* baseShopItem = GetShopPedApparel(nameHash);
|
||
|
|
||
|
if (baseShopItem)
|
||
|
{
|
||
|
for (int i = 0; i < baseShopItem->m_restrictionTags.GetCount(); i++)
|
||
|
{
|
||
|
if (baseShopItem->m_restrictionTags[i].m_tagNameHash == tagHash)
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
s32 CExtraMetadataMgr::SetupShopPedComponentQuery(eScrCharacters character, eShopEnum shop, s32 locate, ePedVarComp componentType)
|
||
|
{
|
||
|
m_shopPedApparelCompQuery.ResetCount();
|
||
|
|
||
|
for (u32 i = 0; i < m_shopPedApparel.GetCount(); i++)
|
||
|
{
|
||
|
ShopPedApparel& currPedApparelArray = *m_shopPedApparel[i];
|
||
|
|
||
|
if (character == SCR_CHAR_ANY || character == currPedApparelArray.m_eCharacter)
|
||
|
{
|
||
|
for (u32 j = 0; j < currPedApparelArray.m_pedComponents.GetCount(); j++)
|
||
|
{
|
||
|
ShopPedComponent* currentItem = &currPedApparelArray.m_pedComponents[j];
|
||
|
|
||
|
if ((shop == CLO_SHOP_NONE || shop == currentItem->m_eShopEnum) &&
|
||
|
(locate == LOC_ANY || locate == currentItem->m_locate) &&
|
||
|
(componentType == PV_COMP_INVALID || componentType == currentItem->m_eCompType))
|
||
|
m_shopPedApparelCompQuery.PushAndGrow(ShopPedApparelLookupEntry(SHOP_PED_COMPONENT, i, j), 1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return m_shopPedApparelCompQuery.GetCount();
|
||
|
}
|
||
|
|
||
|
s32 CExtraMetadataMgr::SetupShopPedPropQuery(eScrCharacters character, eShopEnum shop, s32 locate, eAnchorPoints anchorPoint)
|
||
|
{
|
||
|
m_shopPedApparelPropQuery.ResetCount();
|
||
|
|
||
|
for (u32 i = 0; i < m_shopPedApparel.GetCount(); i++)
|
||
|
{
|
||
|
ShopPedApparel& currPedApparelArray = *m_shopPedApparel[i];
|
||
|
|
||
|
if (character == SCR_CHAR_ANY || character == currPedApparelArray.m_eCharacter)
|
||
|
{
|
||
|
for (u32 j = 0; j < currPedApparelArray.m_pedProps.GetCount(); j++)
|
||
|
{
|
||
|
ShopPedProp* currentItem = &currPedApparelArray.m_pedProps[j];
|
||
|
|
||
|
if ((shop == CLO_SHOP_NONE || shop == currentItem->m_eShopEnum) &&
|
||
|
(locate == LOC_ANY || locate == currentItem->m_locate) &&
|
||
|
(anchorPoint == ANCHOR_NONE || anchorPoint == currentItem->m_eAnchorPoint))
|
||
|
m_shopPedApparelPropQuery.PushAndGrow(ShopPedApparelLookupEntry(SHOP_PED_PROP, i, j), 1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return m_shopPedApparelPropQuery.GetCount();
|
||
|
}
|
||
|
|
||
|
s32 CExtraMetadataMgr::SetupShopPedOutfitQuery(eScrCharacters character, eShopEnum shop, s32 locate)
|
||
|
{
|
||
|
m_shopPedApparelOutfitQuery.ResetCount();
|
||
|
|
||
|
for (u32 i = 0; i < m_shopPedApparel.GetCount(); i++)
|
||
|
{
|
||
|
ShopPedApparel& currPedApparelArray = *m_shopPedApparel[i];
|
||
|
|
||
|
if (character == SCR_CHAR_ANY || character == currPedApparelArray.m_eCharacter)
|
||
|
{
|
||
|
for (u32 j = 0; j < currPedApparelArray.m_pedOutfits.GetCount(); j++)
|
||
|
{
|
||
|
ShopPedOutfit* currentItem = &currPedApparelArray.m_pedOutfits[j];
|
||
|
|
||
|
if ((shop == CLO_SHOP_NONE || shop == currentItem->m_eShopEnum) &&
|
||
|
(locate == LOC_ANY || locate == currentItem->m_locate))
|
||
|
m_shopPedApparelOutfitQuery.PushAndGrow(ShopPedApparelLookupEntry(SHOP_PED_OUTFIT, i, j), 1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return m_shopPedApparelOutfitQuery.GetCount();
|
||
|
}
|
||
|
|
||
|
#if __EXTRA_METADATA_CONTAINS_SCRIPT_SAVE_DATA_FLAGS
|
||
|
void CExtraMetadataMgr::SetShopPedApparelScriptData(u32 nameHash, u8 bitFlags)
|
||
|
{
|
||
|
BaseShopPedApparel* item = GetShopPedApparel(nameHash);
|
||
|
|
||
|
if (item)
|
||
|
item->m_scriptSaveData = bitFlags;
|
||
|
}
|
||
|
#endif // __EXTRA_METADATA_CONTAINS_SCRIPT_SAVE_DATA_FLAGS
|
||
|
|
||
|
ShopPedComponent* CExtraMetadataMgr::GetShopPedQueryComponent(u32 index)
|
||
|
{
|
||
|
if (index < m_shopPedApparelCompQuery.GetCount())
|
||
|
{
|
||
|
ShopPedApparelLookupEntry& luEntry = m_shopPedApparelCompQuery[index];
|
||
|
|
||
|
return &m_shopPedApparel[luEntry.m_shopPedApparelIndex]->m_pedComponents[luEntry.m_shopPedTypeIndex];
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
ShopPedProp* CExtraMetadataMgr::GetShopPedQueryProp(u32 index)
|
||
|
{
|
||
|
if (index < m_shopPedApparelPropQuery.GetCount())
|
||
|
{
|
||
|
ShopPedApparelLookupEntry& luEntry = m_shopPedApparelPropQuery[index];
|
||
|
|
||
|
return &m_shopPedApparel[luEntry.m_shopPedApparelIndex]->m_pedProps[luEntry.m_shopPedTypeIndex];
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
ShopPedOutfit* CExtraMetadataMgr::GetShopPedQueryOutfit(u32 index)
|
||
|
{
|
||
|
if (index < m_shopPedApparelOutfitQuery.GetCount())
|
||
|
{
|
||
|
ShopPedApparelLookupEntry& luEntry = m_shopPedApparelOutfitQuery[index];
|
||
|
|
||
|
return &m_shopPedApparel[luEntry.m_shopPedApparelIndex]->m_pedOutfits[luEntry.m_shopPedTypeIndex];
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
s32 CExtraMetadataMgr::GetShopPedQueryComponentIndex(u32 nameHash)
|
||
|
{
|
||
|
const s32 numberOfQueryResults = m_shopPedApparelCompQuery.GetCount();
|
||
|
for (s32 loop = 0; loop < numberOfQueryResults; loop++)
|
||
|
{
|
||
|
ShopPedApparelLookupEntry& luEntry = m_shopPedApparelCompQuery[loop];
|
||
|
if (m_shopPedApparel[luEntry.m_shopPedApparelIndex]->m_pedComponents[luEntry.m_shopPedTypeIndex].m_uniqueNameHash.GetHash() == nameHash)
|
||
|
{
|
||
|
return loop;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
s32 CExtraMetadataMgr::GetShopPedQueryPropIndex(u32 nameHash)
|
||
|
{
|
||
|
const s32 numberOfQueryResults = m_shopPedApparelPropQuery.GetCount();
|
||
|
for (s32 loop = 0; loop < numberOfQueryResults; loop++)
|
||
|
{
|
||
|
ShopPedApparelLookupEntry& luEntry = m_shopPedApparelPropQuery[loop];
|
||
|
if (m_shopPedApparel[luEntry.m_shopPedApparelIndex]->m_pedProps[luEntry.m_shopPedTypeIndex].m_uniqueNameHash.GetHash() == nameHash)
|
||
|
{
|
||
|
return loop;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
BaseShopPedApparel* CExtraMetadataMgr::GetShopPedApparel(u32 nameHash)
|
||
|
{
|
||
|
if (ShopPedApparelLookupEntry* luEntry = m_shopPedApparelLookup.SafeGet(nameHash))
|
||
|
{
|
||
|
if (luEntry->m_apparelType == (s8)SHOP_PED_COMPONENT)
|
||
|
{
|
||
|
return (BaseShopPedApparel*)&m_shopPedApparel[luEntry->m_shopPedApparelIndex]->m_pedComponents[luEntry->m_shopPedTypeIndex];
|
||
|
}
|
||
|
else if (luEntry->m_apparelType == (s8)SHOP_PED_PROP)
|
||
|
{
|
||
|
return (BaseShopPedApparel*)&m_shopPedApparel[luEntry->m_shopPedApparelIndex]->m_pedProps[luEntry->m_shopPedTypeIndex];
|
||
|
}
|
||
|
else if (luEntry->m_apparelType == (s8)SHOP_PED_OUTFIT)
|
||
|
{
|
||
|
return (BaseShopPedApparel*)&m_shopPedApparel[luEntry->m_shopPedApparelIndex]->m_pedOutfits[luEntry->m_shopPedTypeIndex];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
#if __EXTRA_METADATA_CONTAINS_SCRIPT_SAVE_DATA_FLAGS
|
||
|
void CExtraMetadataMgr::SetBitShopPedApparel(int nameHash, int bitFlag)
|
||
|
{
|
||
|
BaseShopPedApparel* baseShopItem = GetShopPedApparel(nameHash);
|
||
|
|
||
|
if (baseShopItem)
|
||
|
baseShopItem->m_scriptSaveData |= (1 << bitFlag);
|
||
|
}
|
||
|
|
||
|
bool CExtraMetadataMgr::IsBitSetShopPedApparel(int nameHash, int bitFlag)
|
||
|
{
|
||
|
BaseShopPedApparel* baseShopItem = GetShopPedApparel(nameHash);
|
||
|
|
||
|
if (baseShopItem)
|
||
|
return (baseShopItem) ? (((baseShopItem->m_scriptSaveData >> bitFlag) & 1) != 0) : false;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::ClearBitShopPedApparel(int nameHash, int bitFlag)
|
||
|
{
|
||
|
BaseShopPedApparel* baseShopItem = GetShopPedApparel(nameHash);
|
||
|
|
||
|
if (baseShopItem)
|
||
|
baseShopItem->m_scriptSaveData &= ~(1 << bitFlag);
|
||
|
}
|
||
|
#endif // __EXTRA_METADATA_CONTAINS_SCRIPT_SAVE_DATA_FLAGS
|
||
|
|
||
|
ShopPedComponent* CExtraMetadataMgr::GetShopPedComponent(u32 nameHash)
|
||
|
{
|
||
|
if (ShopPedApparelLookupEntry* luEntry = m_shopPedApparelLookup.SafeGet(nameHash))
|
||
|
{
|
||
|
if (luEntry->m_apparelType == (s8)SHOP_PED_COMPONENT)
|
||
|
{
|
||
|
return &m_shopPedApparel[luEntry->m_shopPedApparelIndex]->m_pedComponents[luEntry->m_shopPedTypeIndex];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
ShopPedProp* CExtraMetadataMgr::GetShopPedProp(u32 nameHash)
|
||
|
{
|
||
|
if (ShopPedApparelLookupEntry* luEntry = m_shopPedApparelLookup.SafeGet(nameHash))
|
||
|
{
|
||
|
if (luEntry->m_apparelType == (s8)SHOP_PED_PROP)
|
||
|
{
|
||
|
return &m_shopPedApparel[luEntry->m_shopPedApparelIndex]->m_pedProps[luEntry->m_shopPedTypeIndex];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
ShopPedOutfit* CExtraMetadataMgr::GetShopPedOutfit(u32 nameHash)
|
||
|
{
|
||
|
if (ShopPedApparelLookupEntry* luEntry = m_shopPedApparelLookup.SafeGet(nameHash))
|
||
|
{
|
||
|
if (luEntry->m_apparelType == (s8)SHOP_PED_OUTFIT)
|
||
|
{
|
||
|
return &m_shopPedApparel[luEntry->m_shopPedApparelIndex]->m_pedOutfits[luEntry->m_shopPedTypeIndex];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
eScrCharacters CExtraMetadataMgr::GetShopPedApparelCharacter(u32 nameHash)
|
||
|
{
|
||
|
if (ShopPedApparelLookupEntry* luEntry = m_shopPedApparelLookup.SafeGet(nameHash))
|
||
|
return m_shopPedApparel[luEntry->m_shopPedApparelIndex]->m_eCharacter;
|
||
|
|
||
|
return SCR_CHAR_ANY;
|
||
|
}
|
||
|
|
||
|
#if __BANK && !__SPU
|
||
|
void CExtraMetadataMgr::CreateBankWidgets(bkBank& bank)
|
||
|
{
|
||
|
bank.PushGroup("Extra metadata manager widgets", false);
|
||
|
{
|
||
|
EXTRAMETADATAMGR.SetupShopTattooWidgets(bank);
|
||
|
EXTRAMETADATAMGR.SetupShopPedApparelWidgets(bank);
|
||
|
EXTRAMETADATAMGR.SetupShopWeaponWidgets(bank);
|
||
|
EXTRAMETADATAMGR.SetupShopVehicleWidgets(bank);
|
||
|
EXTRAMETADATAMGR.SetupInteriorWidgets(bank);
|
||
|
}
|
||
|
bank.PopGroup();
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::RefreshBankWidgets()
|
||
|
{
|
||
|
TattooRefreshCB();
|
||
|
VehicleRefreshCB();
|
||
|
WeaponRefreshCB();
|
||
|
InteriorRefreshCB();
|
||
|
DisplayPedComponents(m_currentComponentPg, 0, false);
|
||
|
DisplayPedProps(m_currentPropPg, 0, false);
|
||
|
DisplayPedOutfits(m_currentOutfitPg, 0, false);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::TattooRefreshCB()
|
||
|
{
|
||
|
if(m_bankTattooList)
|
||
|
{
|
||
|
for( int i= 0; i<m_sNumOfListedTattoos; i++)
|
||
|
{
|
||
|
m_bankTattooList->RemoveItem(i);
|
||
|
}
|
||
|
DisplayTattoos(0,0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::WeaponRefreshCB()
|
||
|
{
|
||
|
if(m_bankWeaponCombo && m_bankWeaponComponentsList)
|
||
|
{
|
||
|
PopulateWeaponNames();
|
||
|
if(m_weaponNames.GetCount()>0)
|
||
|
{
|
||
|
m_bankWeaponCombo->UpdateCombo("Weapon Name", &m_sWeaponComboIdx,m_weaponNames.GetCount(), &m_weaponNames[0],datCallback(MFA(CExtraMetadataMgr::WeaponComboCB),(datBase*)this));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_sWeaponComboIdx = 0;
|
||
|
m_bankWeaponCombo->UpdateCombo("Weapon Name", &m_sWeaponComboIdx, 1, NULL);
|
||
|
m_bankWeaponCombo->SetString(0,"No DLC weapons loaded, hit refresh upon loading");
|
||
|
}
|
||
|
|
||
|
WeaponComboCB();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::VehicleRefreshCB()
|
||
|
{
|
||
|
if(m_bankVehicleCombo && m_bankVehicleModList && m_bankGenericVehicleModList)
|
||
|
{
|
||
|
PopulateVehicleNames();
|
||
|
if(m_vehicleNames.GetCount()>0)
|
||
|
{
|
||
|
m_bankVehicleCombo->UpdateCombo("Vehicle Name", &m_sVehicleComboIdx,m_vehicleNames.GetCount(), &m_vehicleNames[0],datCallback(MFA(CExtraMetadataMgr::VehicleComboCB),(datBase*)this));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_sVehicleComboIdx = 0;
|
||
|
m_bankVehicleCombo->UpdateCombo("Vehicle Name", &m_sVehicleComboIdx, 1, NULL);
|
||
|
m_bankVehicleCombo->SetString(0,"No DLC vehicles loaded, hit refresh upon loading");
|
||
|
}
|
||
|
|
||
|
VehicleComboCB();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void CExtraMetadataMgr::WeaponEquipCB()
|
||
|
{
|
||
|
dlcDebugf3("Attempting to equip weapon at index %d ", m_sWeaponComboIdx);
|
||
|
CPed* pPlayer = CGameWorld::FindLocalPlayer();
|
||
|
if(pPlayer && m_sWeaponComboIdx>=0 && m_sWeaponComboIdx < m_weaponShopItemsLookup.GetCount())
|
||
|
{
|
||
|
const WeaponShopItem* currentItem = m_weaponShopItemsLookup[m_sWeaponComboIdx];
|
||
|
dlcDebugf3("Equipping weapon :%p", m_weaponShopItemsLookup[m_sWeaponComboIdx]);
|
||
|
pPlayer->GetInventory()->AddWeaponAndAmmo(currentItem->m_nameHash, 100);
|
||
|
pPlayer->GetWeaponManager()->EquipWeapon(currentItem->m_nameHash,true);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::TattooDblClickCB(s32 idx)
|
||
|
{
|
||
|
extern const char* parser_eTattooFaction_Strings[];
|
||
|
extern const char* parser_eTattooFacing_Strings[];
|
||
|
int ct=0;
|
||
|
CPed* pPlayer = CGameWorld::FindLocalPlayer();
|
||
|
TattooShopItem* currentItem = NULL;
|
||
|
for(int i=0;i<m_tattooShopItemsLookup.GetMaxCount();i++)
|
||
|
{
|
||
|
for(int j= 0; j<m_tattooShopItemsLookup[i].GetCount(); j++)
|
||
|
{
|
||
|
if(ct==idx)
|
||
|
{
|
||
|
const tattooLookupEntry* entry = &(m_tattooShopItemsLookup[i][j]);
|
||
|
currentItem = &(m_tattooShopsItems[entry->collection].TattooShopItems[entry->index]);
|
||
|
break;
|
||
|
}
|
||
|
ct++;
|
||
|
}
|
||
|
}
|
||
|
dlcDebugf3("Tattoo idx: %d clicked, faction: %s , id= %d ",idx,parser_eTattooFaction_Strings[currentItem->m_eFaction],currentItem->m_id);
|
||
|
PEDDECORATIONMGR.AddPedDecoration(pPlayer,currentItem->m_collection,currentItem->m_preset);
|
||
|
}
|
||
|
void CExtraMetadataMgr::TattooClearCB()
|
||
|
{
|
||
|
CPed* pPlayer = CGameWorld::FindLocalPlayer();
|
||
|
PEDDECORATIONMGR.ClearPedDecorations(pPlayer);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::VehicleCreateCB()
|
||
|
{
|
||
|
if(m_vehiclesLookup.GetCount()>0)
|
||
|
{
|
||
|
fwModelId test;
|
||
|
CModelInfo::GetBaseModelInfoFromName(m_vehiclesLookup[m_sVehicleComboIdx]->m_modelNameHash.GetCStr(),&test);
|
||
|
CVehicleFactory::CreateCar(test.GetModelIndex());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::VehicleComboCB()
|
||
|
{
|
||
|
for(int i = 0; i<m_sNumOfListedMods;i++)
|
||
|
{
|
||
|
m_bankVehicleModList->RemoveItem(i);
|
||
|
}
|
||
|
for(int i = 0; i<m_sNumOfListedGenericMods;i++)
|
||
|
{
|
||
|
m_bankGenericVehicleModList->RemoveItem(i);
|
||
|
}
|
||
|
|
||
|
if(m_vehiclesLookup.GetCount()>0)
|
||
|
if(m_vehiclesLookup[m_sVehicleComboIdx])
|
||
|
{
|
||
|
m_sNumOfListedMods = m_vehiclesLookup[m_sVehicleComboIdx]->m_vehicleMods.GetCount();
|
||
|
for(int i=0;i<m_vehiclesLookup[m_sVehicleComboIdx]->m_vehicleMods.GetCount();++i)
|
||
|
{
|
||
|
const ShopVehicleMod* currentItem = &(m_vehiclesLookup[m_sVehicleComboIdx]->m_vehicleMods[i]);
|
||
|
if(currentItem)
|
||
|
{
|
||
|
m_bankVehicleModList->AddItem(i,0,currentItem->m_nameHash.GetCStr());//Hash
|
||
|
m_bankVehicleModList->AddItem(i,1,currentItem->m_cost);//Cost
|
||
|
m_bankVehicleModList->AddItem(i,2,m_vehiclesLookup[m_sVehicleComboIdx]->m_lockHash.TryGetCStr());//lock hash
|
||
|
m_bankVehicleModList->AddItem(i,3,currentItem->m_lockHash.TryGetCStr());//lock hash
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if(m_vehicleGenericModsLookup.GetCount()>0)
|
||
|
{
|
||
|
m_sNumOfListedGenericMods= m_vehicleGenericModsLookup.GetCount();
|
||
|
for(int i=0;i<m_vehicleGenericModsLookup.GetCount();++i)
|
||
|
{
|
||
|
const ShopVehicleMod* currentItem = (m_vehicleGenericModsLookup[i]);
|
||
|
if(currentItem)
|
||
|
{
|
||
|
m_bankGenericVehicleModList->AddItem(i,0,currentItem->m_nameHash.GetCStr());//Hash
|
||
|
m_bankGenericVehicleModList->AddItem(i,1,currentItem->m_cost);//Cost
|
||
|
m_bankGenericVehicleModList->AddItem(i,2,currentItem->m_lockHash.TryGetCStr());//lock hash
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::WeaponComboCB()
|
||
|
{
|
||
|
for(int i = 0; i<m_sNumOfListedWeaponComponents;i++)
|
||
|
{
|
||
|
m_bankWeaponComponentsList->RemoveItem(i);
|
||
|
}
|
||
|
if(m_weaponShopItemsLookup.GetCount()>0)
|
||
|
if(m_weaponShopItemsLookup[m_sWeaponComboIdx])
|
||
|
{
|
||
|
WeaponShopItem* curWeapon = m_weaponShopItemsLookup[m_sWeaponComboIdx];
|
||
|
m_sNumOfListedWeaponComponents = curWeapon->m_weaponComponents.GetCount();
|
||
|
for(int i=0;i<curWeapon->m_weaponComponents.GetCount();++i)
|
||
|
{
|
||
|
int col=0;
|
||
|
const ShopWeaponComponent* currentItem = &(curWeapon->m_weaponComponents[i]);
|
||
|
if(currentItem)
|
||
|
{
|
||
|
const CWeaponInfo* info = CWeaponInfoManager::GetInfo<CWeaponInfo>(curWeapon->m_nameHash);
|
||
|
const CWeaponComponentInfo* compInfo = CWeaponComponentManager::GetInfo<CWeaponComponentInfo>(currentItem->m_componentName);
|
||
|
|
||
|
const CWeaponComponentPoint* cPoint = info? info->GetAttachPoint(compInfo) : NULL;
|
||
|
m_bankWeaponComponentsList->AddItem(i,col++,cPoint?cPoint->GetAttachBoneName():""); //parser_eWeaponModType_Strings[currentItem->m_eModType]);//Hash
|
||
|
m_bankWeaponComponentsList->AddItem(i,col++,currentItem->m_componentName.GetCStr());//Hash
|
||
|
m_bankWeaponComponentsList->AddItem(i,col++,currentItem->m_cost);//Cost
|
||
|
m_bankWeaponComponentsList->AddItem(i,col++,curWeapon->m_ammoCost);//ammo Cost
|
||
|
const CAmmoInfo* aInfo = info ? info->GetAmmoInfo() : NULL;
|
||
|
m_bankWeaponComponentsList->AddItem(i,col++,aInfo ? aInfo->GetName():"");//ammo type;
|
||
|
m_bankWeaponComponentsList->AddItem(i,col++,info ? (info->GetIsWeaponComponentDefault(currentItem->m_componentName)?"YES":"NO"):"ERROR");
|
||
|
m_bankWeaponComponentsList->AddItem(i,col++, info ? info->GetClipSize() : 0 );//ammo type;
|
||
|
m_bankWeaponComponentsList->AddItem(i,col++, TheText.DoesTextLabelExist(currentItem->m_textLabel)? TheText.Get(currentItem->m_textLabel) : currentItem->m_textLabel);
|
||
|
m_bankWeaponComponentsList->AddItem(i,col++, TheText.DoesTextLabelExist(currentItem->m_componentDesc)? TheText.Get(currentItem->m_componentDesc) : currentItem->m_componentDesc);
|
||
|
m_bankWeaponComponentsList->AddItem(i,col++, TheText.DoesTextLabelExist(curWeapon->m_weaponDesc)? TheText.Get(curWeapon->m_weaponDesc) : curWeapon->m_weaponDesc);
|
||
|
m_bankWeaponComponentsList->AddItem(i,col++, TheText.DoesTextLabelExist(curWeapon->m_weaponTT)? TheText.Get(curWeapon->m_weaponTT) : curWeapon->m_weaponTT);
|
||
|
m_bankWeaponComponentsList->AddItem(i,col++, TheText.DoesTextLabelExist(curWeapon->m_weaponUppercase)? TheText.Get(curWeapon->m_weaponUppercase) : curWeapon->m_weaponUppercase);
|
||
|
m_bankWeaponComponentsList->AddItem(i,col++, curWeapon->m_lockHash.TryGetCStr());//lock hash
|
||
|
m_bankWeaponComponentsList->AddItem(i,col++, currentItem->m_lockHash.TryGetCStr());//lock hash
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::SetupShopVehicleWidgets(bkBank& bank)
|
||
|
{
|
||
|
bank.PushGroup("Shop Vehicles", false);
|
||
|
{
|
||
|
PopulateVehicleNames();
|
||
|
if(m_vehicleNames.GetCount()>0)
|
||
|
{
|
||
|
m_bankVehicleCombo = bank.AddCombo("Vehicle Name",&m_sVehicleComboIdx,m_vehicleNames.GetCount(),&m_vehicleNames[0],datCallback(MFA(CExtraMetadataMgr::VehicleComboCB),(datBase*)this));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_bankVehicleCombo = bank.AddCombo("Vehicle Name", &m_sVehicleComboIdx,0,NULL,rage::NullCallback);
|
||
|
m_bankVehicleCombo->SetString(0,"No DLC vehicles loaded, hit refresh upon loading");
|
||
|
}
|
||
|
m_bankVehicleModList = bank.AddList("Vehicle mods");
|
||
|
m_bankVehicleModList->AddColumnHeader(0,"Hash",bkList::STRING);
|
||
|
m_bankVehicleModList->AddColumnHeader(1,"Cost",bkList::INT);
|
||
|
m_bankVehicleModList->AddColumnHeader(2,"Vehicle Lock hash",bkList::STRING);
|
||
|
m_bankVehicleModList->AddColumnHeader(3,"Vehmod Lock hash",bkList::STRING);
|
||
|
m_bankGenericVehicleModList = bank.AddList("Generic Vehicle mods");
|
||
|
m_bankGenericVehicleModList->AddColumnHeader(0,"Hash",bkList::STRING);
|
||
|
m_bankGenericVehicleModList->AddColumnHeader(1,"Cost",bkList::INT);
|
||
|
m_bankGenericVehicleModList->AddColumnHeader(2,"Mod Lock hash",bkList::STRING);
|
||
|
bank.AddButton("Refresh",datCallback(MFA(CExtraMetadataMgr::VehicleRefreshCB),(datBase*)this));
|
||
|
bank.AddButton("Create selected vehicle",datCallback(MFA(CExtraMetadataMgr::VehicleCreateCB),(datBase*)this));
|
||
|
VehicleComboCB();
|
||
|
}
|
||
|
bank.PopGroup();
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::InteriorRefreshCB()
|
||
|
{
|
||
|
CInteriorProxy::Pool* proxyPool = CInteriorProxy::GetPool();
|
||
|
|
||
|
if (m_bankProxyIndicesMetaCombo)
|
||
|
{
|
||
|
static atArray<const char*> s_dlcProxyPathsPtr;
|
||
|
const char* currOrderDataPath = m_bankProxyIndicesMetaCombo->GetString(ms_ProxyIndexComboIdx);
|
||
|
|
||
|
ms_ProxyIndexComboIdx = 0;
|
||
|
s_dlcProxyPathsPtr.ResetCount();
|
||
|
m_proxyOrderLookup.ResetCount();
|
||
|
|
||
|
const CDataFileMgr::DataFile* pData = DATAFILEMGR.GetFirstFile(CDataFileMgr::INTERIOR_PROXY_ORDER_FILE);
|
||
|
s32 currComboIdx = 0;
|
||
|
while (DATAFILEMGR.IsValid(pData))
|
||
|
{
|
||
|
SInteriorOrderData currOrderData;
|
||
|
|
||
|
// Add proxy orders on file into the lookup table
|
||
|
if (PARSER.LoadObject(pData->m_filename, NULL, currOrderData))
|
||
|
{
|
||
|
for (u32 i = 0; i < currOrderData.m_proxies.GetCount(); i++)
|
||
|
m_proxyOrderLookup.SafeInsert(currOrderData.m_proxies[i].GetHash(), pData->m_filename);
|
||
|
}
|
||
|
|
||
|
s_dlcProxyPathsPtr.PushAndGrow(pData->m_filename);
|
||
|
|
||
|
// Try to preserve what was already selected
|
||
|
if (currOrderDataPath && strcmp(currOrderDataPath, pData->m_filename) == 0)
|
||
|
ms_ProxyIndexComboIdx = currComboIdx;
|
||
|
|
||
|
pData = DATAFILEMGR.GetNextFile(pData);
|
||
|
currComboIdx++;
|
||
|
}
|
||
|
|
||
|
// Finalise the map
|
||
|
m_proxyOrderLookup.FinishInsertion();
|
||
|
|
||
|
if (s_dlcProxyPathsPtr.GetCount() <= 0)
|
||
|
s_dlcProxyPathsPtr.PushAndGrow("No DLC proxies loaded, will refresh when some are loaded.", 1);
|
||
|
|
||
|
ms_ProxyIndexComboIdx = rage::Clamp(ms_ProxyIndexComboIdx, 0, s_dlcProxyPathsPtr.GetCount() - 1);
|
||
|
|
||
|
m_bankProxyIndicesMetaCombo->UpdateCombo("Proxy Index File: ", &ms_ProxyIndexComboIdx, s_dlcProxyPathsPtr.GetCount(),
|
||
|
s_dlcProxyPathsPtr.GetElements(), datCallback(MFA(CExtraMetadataMgr::ProxyIndexComboCB), (datBase*)this));
|
||
|
|
||
|
ProxyIndexComboCB();
|
||
|
}
|
||
|
|
||
|
if (ms_bankInteriorCombo && proxyPool)
|
||
|
{
|
||
|
const u32 maxIntNameLen = 80;
|
||
|
const u32 maxNumIntNames = 512;
|
||
|
static atFixedArray<char[maxIntNameLen], maxNumIntNames> s_dlcIntDisplayNames;
|
||
|
static atArray<const char*> s_dlcIntDisplayNamesPtr;
|
||
|
CInteriorProxy* pProxy = NULL;
|
||
|
CInteriorProxy* pPrevSelectedProxy = NULL;
|
||
|
int numProxies = proxyPool->GetSize();
|
||
|
int defaultIndex = 0;
|
||
|
|
||
|
// Try to keep the old proxy during the refresh...
|
||
|
if (ms_dlcInteriorComboIdx >= 0 && ms_dlcInteriorComboIdx < ms_dlcInteriorMapSlots.GetCount())
|
||
|
pPrevSelectedProxy = CInteriorProxy::FindProxy(ms_dlcInteriorMapSlots[ms_dlcInteriorComboIdx]);
|
||
|
|
||
|
s_dlcIntDisplayNames.Reset();
|
||
|
s_dlcIntDisplayNamesPtr.ResetCount();
|
||
|
ms_dlcInteriorMapSlots.ResetCount();
|
||
|
|
||
|
for (u32 i = 0; i < numProxies; i++)
|
||
|
{
|
||
|
pProxy = proxyPool->GetSlot(i);
|
||
|
|
||
|
if (pProxy && proxyPool->IsValidPtr(pProxy) && pProxy->GetChangeSetSource() != 0)
|
||
|
{
|
||
|
s32 currIntIndex = ms_dlcInteriorMapSlots.GetCount();
|
||
|
|
||
|
if Verifyf(currIntIndex < maxNumIntNames, "CExtraMetadataMgr::InteriorRefreshCB - Reached maximum number of RAG DLC interior names")
|
||
|
{
|
||
|
if (pPrevSelectedProxy == pProxy)
|
||
|
defaultIndex = currIntIndex;
|
||
|
|
||
|
ms_dlcInteriorMapSlots.PushAndGrow(pProxy->GetMapDataSlotIndex().Get(), 1);
|
||
|
|
||
|
char enableChar = '_';
|
||
|
enableChar = pProxy->GetIsDisabled() ? 'D' : enableChar;
|
||
|
enableChar = pProxy->GetIsCappedAtPartial() ? 'C' :enableChar;
|
||
|
|
||
|
char* newValue = s_dlcIntDisplayNames.Append();
|
||
|
|
||
|
if (pProxy->GetGroupId() == 0)
|
||
|
{
|
||
|
formatf(newValue, maxIntNameLen, "%03d %c:%c %-30.25s (id:%03d)",
|
||
|
i, (pProxy->IsContainingImapActive() ? ' ' : '!'), enableChar, pProxy->GetModelName(), proxyPool->GetJustIndex(pProxy));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
formatf(newValue, maxIntNameLen, "%03d %c:%c %-30.25s (id:%03d grp:%02d)",
|
||
|
i, (pProxy->IsContainingImapActive() ? ' ' : '!'), enableChar, pProxy->GetModelName(), proxyPool->GetJustIndex(pProxy), pProxy->GetGroupId());
|
||
|
}
|
||
|
|
||
|
s_dlcIntDisplayNamesPtr.PushAndGrow(newValue, 1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ms_dlcInteriorComboIdx = defaultIndex;
|
||
|
|
||
|
if (s_dlcIntDisplayNamesPtr.GetCount() <= 0)
|
||
|
s_dlcIntDisplayNamesPtr.PushAndGrow("No DLC interiors loaded, will refresh when some are loaded.", 1);
|
||
|
|
||
|
ms_dlcInteriorComboIdx = rage::Clamp(ms_dlcInteriorComboIdx, 0, s_dlcIntDisplayNamesPtr.GetCount() - 1);
|
||
|
|
||
|
ms_bankInteriorCombo->UpdateCombo("Interiors: ", &ms_dlcInteriorComboIdx,
|
||
|
s_dlcIntDisplayNamesPtr.GetCount(), s_dlcIntDisplayNamesPtr.GetElements());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::WarpToDLCInteriorCB()
|
||
|
{
|
||
|
if (ms_dlcInteriorComboIdx >= 0 && ms_dlcInteriorComboIdx < ms_dlcInteriorMapSlots.GetCount())
|
||
|
{
|
||
|
if (CInteriorProxy* targetProxy = CInteriorProxy::FindProxy(ms_dlcInteriorMapSlots[ms_dlcInteriorComboIdx]))
|
||
|
{
|
||
|
Vec3V proxyPos;
|
||
|
|
||
|
targetProxy->GetPosition(proxyPos);
|
||
|
CWarpManager::SetWarp(Vector3(proxyPos.GetXf(), proxyPos.GetYf(), proxyPos.GetZf()), VEC3_ZERO, 0.0, true, true, 600.0f);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::ProxyIndexComboCB()
|
||
|
{
|
||
|
static atArray<atHashString> prevDisplayedIndiciesInFile;
|
||
|
static atArray<atHashString> prevDisplayedIndiciesInScratch;
|
||
|
SInteriorOrderData currOrderData;
|
||
|
const char* currOrderDataPath = m_bankProxyIndicesMetaCombo->GetString(ms_ProxyIndexComboIdx);
|
||
|
|
||
|
m_proxyFromIndex[0] = 0;
|
||
|
m_proxyToIndex[0] = 0;
|
||
|
|
||
|
if (ASSET.Exists(currOrderDataPath, NULL) && PARSER.LoadObject(currOrderDataPath, NULL, currOrderData))
|
||
|
{
|
||
|
formatf(m_proxyFromIndex, "%i", currOrderData.m_startFrom);
|
||
|
formatf(m_proxyToIndex, "%i", currOrderData.m_startFrom + currOrderData.m_proxies.GetCount());
|
||
|
|
||
|
// Indices in file
|
||
|
for (u32 i = 0; i < prevDisplayedIndiciesInFile.GetCount(); i++)
|
||
|
m_bankProxyIndicesInFileList->RemoveItem(prevDisplayedIndiciesInFile[i]);
|
||
|
|
||
|
prevDisplayedIndiciesInFile.ResetCount();
|
||
|
|
||
|
for (u32 i = 0; i < currOrderData.m_proxies.GetCount(); i++)
|
||
|
{
|
||
|
u32 col = 0;
|
||
|
atHashString currStr = currOrderData.m_proxies[i];
|
||
|
|
||
|
m_bankProxyIndicesInFileList->AddItem(currStr.GetHash(), col++, currStr.GetCStr());
|
||
|
prevDisplayedIndiciesInFile.PushAndGrow(currStr);
|
||
|
}
|
||
|
|
||
|
// Indices in scratch
|
||
|
for (u32 i = 0; i < prevDisplayedIndiciesInScratch.GetCount(); i++)
|
||
|
m_bankProxyIndicesInScratchList->RemoveItem(prevDisplayedIndiciesInScratch[i]);
|
||
|
|
||
|
prevDisplayedIndiciesInScratch.ResetCount();
|
||
|
|
||
|
const atArray<atHashString>& unorderedProxies = CInteriorProxy::GetUnorderedProxies();
|
||
|
|
||
|
for (s32 i = 0; i < unorderedProxies.GetCount(); i++)
|
||
|
{
|
||
|
u32 col = 0;
|
||
|
atHashString currStr = unorderedProxies[i];
|
||
|
|
||
|
m_bankProxyIndicesInScratchList->AddItem(currStr.GetHash(), col++, currStr.GetCStr());
|
||
|
prevDisplayedIndiciesInScratch.PushAndGrow(currStr);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::MoveProxyFromFileCB()
|
||
|
{
|
||
|
if (m_clickedProxyInFileHash != 0)
|
||
|
{
|
||
|
if (const char** orderFilePathPtr = m_proxyOrderLookup.Access(m_clickedProxyInFileHash))
|
||
|
{
|
||
|
const char* orderFilePath = *orderFilePathPtr;
|
||
|
SInteriorOrderData currOrderData;
|
||
|
|
||
|
if (ASSET.Exists(orderFilePath, NULL) && PARSER.LoadObject(orderFilePath, NULL, currOrderData))
|
||
|
{
|
||
|
u32 attrs = ASSET.GetAttributes(orderFilePath, NULL);
|
||
|
|
||
|
if (!(attrs & FILE_ATTRIBUTE_READONLY))
|
||
|
{
|
||
|
s32 foundIdx = currOrderData.m_proxies.Find(m_clickedProxyInFileHash);
|
||
|
|
||
|
if (foundIdx >= 0)
|
||
|
currOrderData.m_proxies.Delete(foundIdx);
|
||
|
|
||
|
PARSER.SaveObject(orderFilePath, NULL, &currOrderData);
|
||
|
|
||
|
CInteriorProxy::AddUnorderedProxy(m_clickedProxyInFileHash);
|
||
|
}
|
||
|
else
|
||
|
Assertf(false, "%s is read only, please make sure it's checked out!", orderFilePath);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
InteriorRefreshCB();
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::MoveAllProxiesToFileCB()
|
||
|
{
|
||
|
const atArray<atHashString>& unorderedProxies = CInteriorProxy::GetUnorderedProxies();
|
||
|
s32 prevSize = unorderedProxies.GetCount();
|
||
|
|
||
|
for (s32 i = 0; i < unorderedProxies.GetCount(); i++)
|
||
|
{
|
||
|
m_clickedProxyInScratchHash = unorderedProxies[i];
|
||
|
MoveProxyToFileCB();
|
||
|
|
||
|
// We removed something
|
||
|
if (prevSize != unorderedProxies.GetCount())
|
||
|
{
|
||
|
i--;
|
||
|
prevSize = unorderedProxies.GetCount();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
InteriorRefreshCB();
|
||
|
m_clickedProxyInScratchHash = 0;
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::MoveProxyToFileCB()
|
||
|
{
|
||
|
if (m_clickedProxyInScratchHash != 0)
|
||
|
{
|
||
|
SInteriorOrderData currOrderData;
|
||
|
const char* currOrderDataPath = m_bankProxyIndicesMetaCombo->GetString(ms_ProxyIndexComboIdx);
|
||
|
|
||
|
if (ASSET.Exists(currOrderDataPath, NULL) && PARSER.LoadObject(currOrderDataPath, NULL, currOrderData))
|
||
|
{
|
||
|
u32 attrs = ASSET.GetAttributes(currOrderDataPath, NULL);
|
||
|
|
||
|
if (!(attrs & FILE_ATTRIBUTE_READONLY))
|
||
|
{
|
||
|
if (currOrderData.m_proxies.Find(m_clickedProxyInScratchHash) == -1)
|
||
|
{
|
||
|
currOrderData.m_proxies.PushAndGrow(m_clickedProxyInScratchHash);
|
||
|
|
||
|
CInteriorProxy::RemoveUnorderedProxy(m_clickedProxyInScratchHash);
|
||
|
}
|
||
|
|
||
|
PARSER.SaveObject(currOrderDataPath, NULL, &currOrderData);
|
||
|
}
|
||
|
else
|
||
|
Assertf(false, "%s is read only, please make sure it's checked out!", currOrderDataPath);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
InteriorRefreshCB();
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::ClickProxyInFile(s32 index)
|
||
|
{
|
||
|
m_clickedProxyInFileHash = index;
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::ClickProxyInScratch(s32 index)
|
||
|
{
|
||
|
m_clickedProxyInScratchHash = index;
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::EditProxyFromIndex()
|
||
|
{
|
||
|
SInteriorOrderData currOrderData;
|
||
|
const char* currOrderDataPath = m_bankProxyIndicesMetaCombo->GetString(ms_ProxyIndexComboIdx);
|
||
|
|
||
|
if (ASSET.Exists(currOrderDataPath, NULL) && PARSER.LoadObject(currOrderDataPath, NULL, currOrderData))
|
||
|
{
|
||
|
u32 attrs = ASSET.GetAttributes(currOrderDataPath, NULL);
|
||
|
|
||
|
if (!(attrs & FILE_ATTRIBUTE_READONLY))
|
||
|
{
|
||
|
currOrderData.m_startFrom = atoi(m_proxyFromIndex);
|
||
|
PARSER.SaveObject(currOrderDataPath, NULL, &currOrderData);
|
||
|
}
|
||
|
else
|
||
|
Assertf(false, "%s is read only, please make sure it's checked out!", currOrderDataPath);
|
||
|
}
|
||
|
|
||
|
InteriorRefreshCB();
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::CheckOutFile(const char* currOrderDataPath)
|
||
|
{
|
||
|
char remoteCmd[256] = { 0 };
|
||
|
char physicalPath[256] = { 0 };
|
||
|
const fiDevice *device = fiDevice::GetDevice(currOrderDataPath);
|
||
|
|
||
|
if (device)
|
||
|
{
|
||
|
device->FixRelativeName(physicalPath, sizeof(physicalPath), currOrderDataPath);
|
||
|
}
|
||
|
|
||
|
formatf(remoteCmd, "p4 edit %s", physicalPath);
|
||
|
|
||
|
sysExec(remoteCmd);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::CheckoutProxyFile()
|
||
|
{
|
||
|
const char* currOrderDataPath = m_bankProxyIndicesMetaCombo->GetString(ms_ProxyIndexComboIdx);
|
||
|
|
||
|
if (ASSET.Exists(currOrderDataPath, NULL))
|
||
|
{
|
||
|
CheckOutFile(currOrderDataPath);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::SetupInteriorWidgets(bkBank& bank)
|
||
|
{
|
||
|
bank.PushGroup("DLC Interiors", false);
|
||
|
{
|
||
|
// DLC interior list
|
||
|
bank.PushGroup("DLC Warp List", false);
|
||
|
{
|
||
|
ms_bankInteriorCombo = bank.AddCombo("Interiors: ", &ms_dlcInteriorComboIdx, 0, NULL, NullCB);
|
||
|
bank.AddButton("Warp", datCallback(MFA(CExtraMetadataMgr::WarpToDLCInteriorCB),(datBase*)this));
|
||
|
}
|
||
|
bank.PopGroup();
|
||
|
|
||
|
// DLC interior index tool
|
||
|
bank.PushGroup("DLC Proxy Indexing tool", false);
|
||
|
{
|
||
|
m_bankProxyIndicesMetaCombo = bank.AddCombo("Proxy Index File: ", &ms_ProxyIndexComboIdx, 0, NULL, rage::NullCallback);
|
||
|
|
||
|
m_proxyFromIdxTxt = bank.AddText("From Index:", m_proxyFromIndex, sizeof(m_proxyFromIndex),
|
||
|
false, datCallback(MFA(CExtraMetadataMgr::EditProxyFromIndex), (datBase*)this));
|
||
|
|
||
|
m_proxyToIdxTxt = bank.AddText("To Index:", m_proxyToIndex, sizeof(m_proxyToIndex), true, rage::NullCallback);
|
||
|
bank.AddButton("Checkout file", datCallback(MFA(CExtraMetadataMgr::CheckoutProxyFile),(datBase*)this));
|
||
|
|
||
|
bkList::ClickItemFuncType clickProxyInFileCB;
|
||
|
clickProxyInFileCB.Reset<CExtraMetadataMgr, &CExtraMetadataMgr::ClickProxyInFile>(this);
|
||
|
|
||
|
m_bankProxyIndicesInFileList = bank.AddList("Proxies in File");
|
||
|
m_bankProxyIndicesInFileList->AddColumnHeader(0, "Name", bkList::STRING);
|
||
|
m_bankProxyIndicesInFileList->SetSingleClickItemFunc(clickProxyInFileCB);
|
||
|
|
||
|
bank.AddButton("/\\/\\ - (All Up)", datCallback(MFA(CExtraMetadataMgr::MoveAllProxiesToFileCB),(datBase*)this));
|
||
|
bank.AddButton("/\\ - (One Up)", datCallback(MFA(CExtraMetadataMgr::MoveProxyToFileCB),(datBase*)this));
|
||
|
bank.AddButton("\\/ - (One down)", datCallback(MFA(CExtraMetadataMgr::MoveProxyFromFileCB),(datBase*)this));
|
||
|
|
||
|
bkList::ClickItemFuncType clickProxyInScratchCB;
|
||
|
clickProxyInScratchCB.Reset<CExtraMetadataMgr, &CExtraMetadataMgr::ClickProxyInScratch>(this);
|
||
|
|
||
|
m_bankProxyIndicesInScratchList = bank.AddList("Proxies in Scratch");
|
||
|
m_bankProxyIndicesInScratchList->AddColumnHeader(0, "Name", bkList::STRING);
|
||
|
m_bankProxyIndicesInScratchList->SetSingleClickItemFunc(clickProxyInScratchCB);
|
||
|
}
|
||
|
bank.PopGroup();
|
||
|
|
||
|
InteriorRefreshCB();
|
||
|
}
|
||
|
bank.PopGroup();
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::SetupShopWeaponWidgets(bkBank& bank)
|
||
|
{
|
||
|
bank.PushGroup("Shop Weapons", false);
|
||
|
{
|
||
|
PopulateWeaponNames();
|
||
|
if(m_weaponNames.GetCount()>0)
|
||
|
{
|
||
|
m_bankWeaponCombo = bank.AddCombo("Weapon Name",&m_sWeaponComboIdx,m_weaponNames.GetCount(),&m_weaponNames[0],datCallback(MFA(CExtraMetadataMgr::WeaponComboCB),(datBase*)this));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_bankWeaponCombo = bank.AddCombo("Weapon Name", &m_sWeaponComboIdx,0,NULL,rage::NullCallback);
|
||
|
m_bankWeaponCombo->SetString(0,"No DLC weapons loaded, hit refresh upon loading");
|
||
|
}
|
||
|
m_bankWeaponComponentsList = bank.AddList("Weapon Components");
|
||
|
m_bankWeaponComponentsList->AddColumnHeader(0,"Component Type",bkList::STRING);
|
||
|
m_bankWeaponComponentsList->AddColumnHeader(1,"Hash",bkList::STRING);
|
||
|
m_bankWeaponComponentsList->AddColumnHeader(2,"Cost",bkList::INT);
|
||
|
m_bankWeaponComponentsList->AddColumnHeader(3,"Ammo cost",bkList::INT);
|
||
|
m_bankWeaponComponentsList->AddColumnHeader(4,"Ammo type",bkList::STRING);
|
||
|
m_bankWeaponComponentsList->AddColumnHeader(5,"Is Default",bkList::STRING);
|
||
|
m_bankWeaponComponentsList->AddColumnHeader(6,"Default clip size",bkList::INT);
|
||
|
m_bankWeaponComponentsList->AddColumnHeader(7,"Component Name",bkList::STRING);
|
||
|
m_bankWeaponComponentsList->AddColumnHeader(8,"Component Desc",bkList::STRING);
|
||
|
m_bankWeaponComponentsList->AddColumnHeader(9,"Weapon Desc",bkList::STRING);
|
||
|
m_bankWeaponComponentsList->AddColumnHeader(10,"Weapon The Name",bkList::STRING);
|
||
|
m_bankWeaponComponentsList->AddColumnHeader(11,"Weapon Uppercase",bkList::STRING);
|
||
|
m_bankWeaponComponentsList->AddColumnHeader(12,"Weapon Lock hash",bkList::STRING);
|
||
|
m_bankWeaponComponentsList->AddColumnHeader(13,"Component Lock hash",bkList::STRING);
|
||
|
bank.AddButton("Refresh",datCallback(MFA(CExtraMetadataMgr::WeaponRefreshCB),(datBase*)this));
|
||
|
bank.AddButton("Create selected Weapon",datCallback(MFA(CExtraMetadataMgr::WeaponEquipCB),(datBase*)this));
|
||
|
WeaponRefreshCB();
|
||
|
WeaponComboCB();
|
||
|
}
|
||
|
bank.PopGroup();
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::SetupShopTattooWidgets(bkBank& bank)
|
||
|
{
|
||
|
bank.PushGroup("Shop Tattoo", false);
|
||
|
{
|
||
|
bank.AddButton("Print tattoo debug", datCallback(MFA(CExtraMetadataMgr::DebugPrintTattooShopItems),(datBase*)this));
|
||
|
bank.AddButton("Clear tattoos", datCallback(MFA(CExtraMetadataMgr::TattooClearCB),(datBase*)this));
|
||
|
m_bankTattooList = bank.AddList("Tattoo Shop Items (double click to add tattoos on the player)");
|
||
|
bkList::ClickItemFuncType tattooClickCB;
|
||
|
tattooClickCB.Reset<CExtraMetadataMgr, &CExtraMetadataMgr::TattooDblClickCB>(this);
|
||
|
m_bankTattooList->SetDoubleClickItemFunc(tattooClickCB);
|
||
|
m_bankTattooList->AddColumnHeader(0, "ID", bkList::INT);
|
||
|
m_bankTattooList->AddColumnHeader(1, "Faction", bkList::STRING);
|
||
|
m_bankTattooList->AddColumnHeader(2, "Cost", bkList::INT);
|
||
|
m_bankTattooList->AddColumnHeader(3, "Facing", bkList::STRING);
|
||
|
m_bankTattooList->AddColumnHeader(4, "DLC Label;", bkList::STRING);
|
||
|
m_bankTattooList->AddColumnHeader(5, "Preset", bkList::STRING);
|
||
|
m_bankTattooList->AddColumnHeader(6, "Collection", bkList::STRING);
|
||
|
DisplayTattoos(0,0);
|
||
|
bank.AddButton("Refresh",datCallback(MFA(CExtraMetadataMgr::TattooRefreshCB),(datBase*)this));
|
||
|
}
|
||
|
bank.PopGroup();
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::PopulateVehicleNames()
|
||
|
{
|
||
|
m_vehicleNames.ResetCount();
|
||
|
for(int i=0; i<m_vehiclesLookup.GetCount();i++)
|
||
|
{
|
||
|
const ShopVehicleData* currentItem = m_vehiclesLookup[i];
|
||
|
if(currentItem)
|
||
|
{
|
||
|
m_vehicleNames.PushAndGrow(TheText.DoesTextLabelExist(currentItem->m_textLabel)? TheText.Get(currentItem->m_textLabel) : currentItem->m_textLabel);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::PopulateWeaponNames()
|
||
|
{
|
||
|
m_weaponNames.ResetCount();
|
||
|
for(int i=0; i<m_weaponShopItemsLookup.GetCount();i++)
|
||
|
{
|
||
|
const WeaponShopItem* currentItem = m_weaponShopItemsLookup[i];
|
||
|
if(currentItem)
|
||
|
{
|
||
|
m_weaponNames.PushAndGrow(TheText.DoesTextLabelExist(currentItem->m_textLabel)? TheText.Get(currentItem->m_textLabel) : currentItem->m_textLabel);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void CExtraMetadataMgr::DisplayTattoos(s32 /*nextPage*/, u32 /*lookupHash*/)
|
||
|
{
|
||
|
m_sNumOfListedTattoos = 0;
|
||
|
extern const char* parser_eTattooFaction_Strings[];
|
||
|
extern const char* parser_eTattooFacing_Strings[];
|
||
|
if(m_bankTattooList)
|
||
|
{
|
||
|
for(int i=0;i<m_tattooShopItemsLookup.GetMaxCount();i++)
|
||
|
{
|
||
|
for(int j= 0; j<m_tattooShopItemsLookup[i].GetCount(); j++)
|
||
|
{
|
||
|
const tattooLookupEntry* entry = &(m_tattooShopItemsLookup[i][j]);
|
||
|
const TattooShopItem* currentItem = &(m_tattooShopsItems[entry->collection].TattooShopItems[entry->index]);
|
||
|
if(currentItem)
|
||
|
{
|
||
|
m_bankTattooList->AddItem(m_sNumOfListedTattoos,0,currentItem->m_id);
|
||
|
m_bankTattooList->AddItem(m_sNumOfListedTattoos,1,parser_eTattooFaction_Strings[currentItem->m_eFaction]);
|
||
|
m_bankTattooList->AddItem(m_sNumOfListedTattoos,2,currentItem->m_cost);
|
||
|
m_bankTattooList->AddItem(m_sNumOfListedTattoos,3,parser_eTattooFacing_Strings[currentItem->m_eFacing]);
|
||
|
m_bankTattooList->AddItem(m_sNumOfListedTattoos,4,currentItem->m_textLabel);
|
||
|
m_bankTattooList->AddItem(m_sNumOfListedTattoos,5,currentItem->m_preset.GetCStr());
|
||
|
m_bankTattooList->AddItem(m_sNumOfListedTattoos,6,currentItem->m_collection.GetCStr());
|
||
|
m_sNumOfListedTattoos++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
void CExtraMetadataMgr::SetupShopPedApparelWidgets(bkBank& bank)
|
||
|
{
|
||
|
extern const char* parser_eScrCharacters_Strings[];
|
||
|
|
||
|
bank.PushGroup("Shop Ped Apparel", false);
|
||
|
{
|
||
|
bank.PushGroup("Shop Ped Components", false);
|
||
|
{
|
||
|
bkList::ClickItemFuncType pedComponentblClickCB;
|
||
|
const char* emptyList = "";
|
||
|
|
||
|
bank.AddText("Lookup Component:", m_shopPedComponentLookup, sizeof(m_shopPedComponentLookup), false, datCallback(MFA(CExtraMetadataMgr::LookupShopPedComponent), (datBase*)this));
|
||
|
bank.AddText("Component Counts:", m_shopPedComponentCounts, sizeof(m_shopPedComponentCounts), true, NullCallback);
|
||
|
|
||
|
m_compCharCombo = bank.AddCombo("Character:", &m_compCharComboIdx, eScrCharacters_NUM_ENUMS, parser_eScrCharacters_Strings, datCallback(MFA(CExtraMetadataMgr::CompCharComboCB),(datBase*)this));
|
||
|
m_compDLCNameCombo = bank.AddCombo("DLC Name:", &m_compDLCNameComboIdx, 0, &emptyList, datCallback(MFA(CExtraMetadataMgr::CompDLCNameComboCB),(datBase*)this));
|
||
|
|
||
|
u32 count = 0;
|
||
|
pedComponentblClickCB.Reset<CExtraMetadataMgr, &CExtraMetadataMgr::ComponentDblClickCB>(this);
|
||
|
m_bankComponentList = bank.AddList("Component List (double click item to set variation)");
|
||
|
m_bankComponentList->SetDoubleClickItemFunc(pedComponentblClickCB);
|
||
|
m_bankComponentList->AddColumnHeader(count++, "Name", bkList::STRING);
|
||
|
m_bankComponentList->AddColumnHeader(count++, "Text", bkList::STRING);
|
||
|
m_bankComponentList->AddColumnHeader(count++, "Shop", bkList::INT);
|
||
|
m_bankComponentList->AddColumnHeader(count++, "Locate", bkList::INT);
|
||
|
m_bankComponentList->AddColumnHeader(count++, "Local Drawable Index", bkList::INT);
|
||
|
m_bankComponentList->AddColumnHeader(count++, "Global Drawable Index", bkList::INT);
|
||
|
m_bankComponentList->AddColumnHeader(count++, "Texture", bkList::INT);
|
||
|
m_bankComponentList->AddColumnHeader(count++, "Script Comp Type", bkList::INT);
|
||
|
m_bankComponentList->AddColumnHeader(count++, "Cost", bkList::INT);
|
||
|
m_bankComponentList->AddColumnHeader(count++, "In Outfit", bkList::STRING);
|
||
|
|
||
|
bank.AddButton("<< Previous Page", &ShowPreviousComponentPage);
|
||
|
bank.AddButton("Next Page >>", &ShowNextComponentPage);
|
||
|
|
||
|
DisplayPedComponents(0, 0, true);
|
||
|
}
|
||
|
bank.PopGroup();
|
||
|
|
||
|
bank.PushGroup("Shop Ped Props", false);
|
||
|
{
|
||
|
bkList::ClickItemFuncType pedPropDblClickCB;
|
||
|
const char* emptyList = "";
|
||
|
|
||
|
bank.AddText("Lookup Prop:", m_shopPedPropLookup, sizeof(m_shopPedPropLookup), false, datCallback(MFA(CExtraMetadataMgr::LookupShopPedProp), (datBase*)this));
|
||
|
bank.AddText("Prop Counts:", m_shopPedPropCounts, sizeof(m_shopPedPropCounts), true, NullCallback);
|
||
|
|
||
|
m_propCharCombo = bank.AddCombo("Character:", &m_propCharComboIdx, eScrCharacters_NUM_ENUMS, parser_eScrCharacters_Strings, datCallback(MFA(CExtraMetadataMgr::PropCharComboCB),(datBase*)this));
|
||
|
m_propDLCNameCombo = bank.AddCombo("DLC Name:", &m_propDLCNameComboIdx, 0, &emptyList, datCallback(MFA(CExtraMetadataMgr::PropDLCNameComboCB),(datBase*)this));
|
||
|
|
||
|
u32 count = 0;
|
||
|
pedPropDblClickCB.Reset<CExtraMetadataMgr, &CExtraMetadataMgr::PropDblClickCB>(this);
|
||
|
m_bankPropList = bank.AddList("Prop List (double click item to set prop)");
|
||
|
m_bankPropList->SetDoubleClickItemFunc(pedPropDblClickCB);
|
||
|
m_bankPropList->AddColumnHeader(count++, "Name", bkList::STRING);
|
||
|
m_bankPropList->AddColumnHeader(count++, "Text", bkList::STRING);
|
||
|
m_bankPropList->AddColumnHeader(count++, "Shop", bkList::INT);
|
||
|
m_bankPropList->AddColumnHeader(count++, "Locate", bkList::INT);
|
||
|
m_bankPropList->AddColumnHeader(count++, "Local Prop Index", bkList::INT);
|
||
|
m_bankPropList->AddColumnHeader(count++, "Global Prop Index", bkList::INT);
|
||
|
m_bankPropList->AddColumnHeader(count++, "Texture", bkList::INT);
|
||
|
m_bankPropList->AddColumnHeader(count++, "Anchor Point", bkList::INT);
|
||
|
m_bankPropList->AddColumnHeader(count++, "Cost", bkList::INT);
|
||
|
m_bankPropList->AddColumnHeader(count++, "In Outfit", bkList::STRING);
|
||
|
|
||
|
bank.AddButton("<< Previous Page", &ShowPreviousPropPage);
|
||
|
bank.AddButton("Next Page >>", &ShowNextPropPage);
|
||
|
|
||
|
DisplayPedProps(0, 0, true);
|
||
|
}
|
||
|
bank.PopGroup();
|
||
|
|
||
|
bank.PushGroup("Shop Ped Outfits", false);
|
||
|
{
|
||
|
bkList::ClickItemFuncType pedPrOutfitDblClickCB;
|
||
|
const char* emptyList = "";
|
||
|
|
||
|
bank.AddText("Lookup Outfit:", m_shopPedOutfitLookup, sizeof(m_shopPedOutfitLookup), false, datCallback(MFA(CExtraMetadataMgr::LookupShopPedOutfit), (datBase*)this));
|
||
|
bank.AddText("Outfit Counts:", m_shopPedOutfitCounts, sizeof(m_shopPedOutfitCounts), true, NullCallback);
|
||
|
|
||
|
m_outfitCharCombo = bank.AddCombo("Character:", &m_outfitCharComboIdx, eScrCharacters_NUM_ENUMS, parser_eScrCharacters_Strings, datCallback(MFA(CExtraMetadataMgr::OutfitCharComboCB),(datBase*)this));
|
||
|
m_outfitDLCNameCombo = bank.AddCombo("DLC Name:", &m_outfitDLCNameComboIdx, 0, &emptyList, datCallback(MFA(CExtraMetadataMgr::OutfitDLCNameComboCB),(datBase*)this));
|
||
|
|
||
|
u32 count = 0;
|
||
|
pedPrOutfitDblClickCB.Reset<CExtraMetadataMgr, &CExtraMetadataMgr::OutfitDblClickCB>(this);
|
||
|
m_bankOutfitList = bank.AddList("Outfit List (double click to set outfit)");
|
||
|
m_bankOutfitList->SetDoubleClickItemFunc(pedPrOutfitDblClickCB);
|
||
|
m_bankOutfitList->AddColumnHeader(count++,"Name", bkList::STRING);
|
||
|
m_bankOutfitList->AddColumnHeader(count++,"Cost", bkList::INT);
|
||
|
m_bankOutfitList->AddColumnHeader(count++,"Text Label", bkList::STRING);
|
||
|
m_bankOutfitList->AddColumnHeader(count++,"Number of components", bkList::INT);
|
||
|
m_bankOutfitList->AddColumnHeader(count++,"Number of props", bkList::INT);
|
||
|
|
||
|
bank.AddButton("<< Previous Page", &ShowPreviousOutfitPage);
|
||
|
bank.AddButton("Next Page >>", &ShowNextOutfitPage);
|
||
|
|
||
|
DisplayPedOutfits(0, 0, true);
|
||
|
|
||
|
}
|
||
|
bank.PopGroup();
|
||
|
}
|
||
|
bank.PopGroup();
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::BuildDLCNamesArray(atArray<const char*>& targetArray, s32 characterIdx)
|
||
|
{
|
||
|
targetArray.ResetCount();
|
||
|
|
||
|
targetArray.PushAndGrow("All", 1);
|
||
|
|
||
|
for (u32 i = 0; i < m_shopPedApparel.GetCount(); i++)
|
||
|
{
|
||
|
ShopPedApparel& currApparel = *m_shopPedApparel[i];
|
||
|
|
||
|
if (characterIdx == SCR_CHAR_ANY || currApparel.m_eCharacter == characterIdx)
|
||
|
targetArray.PushAndGrow(currApparel.m_dlcName.c_str(), 1);
|
||
|
}
|
||
|
|
||
|
Assertf(targetArray.GetCount() > 0, "CExtraMetadataMgr::BuildDLCNamesArray - Target array must have at least one entry!");
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::OutfitCharComboCB()
|
||
|
{
|
||
|
EXTRAMETADATAMGR.DisplayPedOutfits(m_currentOutfitPg, 0, true);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::OutfitDLCNameComboCB()
|
||
|
{
|
||
|
EXTRAMETADATAMGR.DisplayPedOutfits(m_currentOutfitPg, 0, false);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::CompCharComboCB()
|
||
|
{
|
||
|
EXTRAMETADATAMGR.DisplayPedComponents(m_currentComponentPg, 0, true);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::CompDLCNameComboCB()
|
||
|
{
|
||
|
EXTRAMETADATAMGR.DisplayPedComponents(m_currentComponentPg, 0, false);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::PropCharComboCB()
|
||
|
{
|
||
|
EXTRAMETADATAMGR.DisplayPedProps(m_currentPropPg, 0, true);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::PropDLCNameComboCB()
|
||
|
{
|
||
|
EXTRAMETADATAMGR.DisplayPedProps(m_currentPropPg, 0, false);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::ShowPreviousComponentPage()
|
||
|
{
|
||
|
EXTRAMETADATAMGR.DisplayPedComponents(m_currentComponentPg - 1, 0, false);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::ShowNextComponentPage()
|
||
|
{
|
||
|
EXTRAMETADATAMGR.DisplayPedComponents(m_currentComponentPg + 1, 0, false);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::ShowPreviousPropPage()
|
||
|
{
|
||
|
EXTRAMETADATAMGR.DisplayPedProps(m_currentPropPg - 1, 0, false);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::ShowNextPropPage()
|
||
|
{
|
||
|
EXTRAMETADATAMGR.DisplayPedProps(m_currentPropPg + 1, 0, false);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::ShowPreviousOutfitPage()
|
||
|
{
|
||
|
EXTRAMETADATAMGR.DisplayPedProps(m_currentOutfitPg - 1, 0, false);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::ShowNextOutfitPage()
|
||
|
{
|
||
|
EXTRAMETADATAMGR.DisplayPedProps(m_currentOutfitPg + 1, 0, false);
|
||
|
}
|
||
|
|
||
|
static u32 CURR_COMP_LIST[MAX_APPAREL_ITEMS_PER_PAGE] = { 0 };
|
||
|
|
||
|
void CExtraMetadataMgr::AddComponentToBankList(ShopPedComponent* currentItem, s32 index)
|
||
|
{
|
||
|
if (currentItem)
|
||
|
{
|
||
|
u32 count = 0;
|
||
|
m_bankComponentList->AddItem(currentItem->m_uniqueNameHash, count++, currentItem->m_uniqueNameHash.TryGetCStr());
|
||
|
m_bankComponentList->AddItem(currentItem->m_uniqueNameHash, count++, currentItem->m_textLabel);
|
||
|
m_bankComponentList->AddItem(currentItem->m_uniqueNameHash, count++, currentItem->m_eShopEnum);
|
||
|
m_bankComponentList->AddItem(currentItem->m_uniqueNameHash, count++, currentItem->m_locate);
|
||
|
m_bankComponentList->AddItem(currentItem->m_uniqueNameHash, count++, (s32)currentItem->m_localDrawableIndex);
|
||
|
m_bankComponentList->AddItem(currentItem->m_uniqueNameHash, count++, (s32)currentItem->m_drawableIndex);
|
||
|
m_bankComponentList->AddItem(currentItem->m_uniqueNameHash, count++, currentItem->m_textureIndex);
|
||
|
m_bankComponentList->AddItem(currentItem->m_uniqueNameHash, count++, currentItem->m_eCompType);
|
||
|
m_bankComponentList->AddItem(currentItem->m_uniqueNameHash, count++, currentItem->m_cost);
|
||
|
m_bankComponentList->AddItem(currentItem->m_uniqueNameHash, count++, currentItem->m_isInOutfit?"TRUE":"FALSE");
|
||
|
|
||
|
if (Verifyf(index < MAX_APPAREL_ITEMS_PER_PAGE, "CExtraMetadataMgr::AddComponentToBankList - Index out of range! %u / %u", index, MAX_APPAREL_ITEMS_PER_PAGE))
|
||
|
CURR_COMP_LIST[index] = currentItem->m_uniqueNameHash;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::DisplayPedComponents(s32 nextPage, u32 lookupHash, bool buildDLCNames)
|
||
|
{
|
||
|
if (buildDLCNames)
|
||
|
{
|
||
|
BuildDLCNamesArray(ms_compDLCNames, m_compCharComboIdx);
|
||
|
|
||
|
m_compDLCNameComboIdx = 0;
|
||
|
m_compDLCNameCombo->UpdateCombo("DLC Name:", &m_compDLCNameComboIdx, ms_compDLCNames.GetCount(), ms_compDLCNames.GetElements(), datCallback(MFA(CExtraMetadataMgr::CompDLCNameComboCB),(datBase*)this), NULL);
|
||
|
}
|
||
|
|
||
|
if (m_bankComponentList)
|
||
|
{
|
||
|
const char* currCompDLCName = m_compDLCNameCombo->GetString(m_compDLCNameComboIdx);
|
||
|
atArray<ShopPedComponent*> validComponents;
|
||
|
s32 maxPage = 1;
|
||
|
|
||
|
// remove all the items first...
|
||
|
for (int i = 0; i < MAX_APPAREL_ITEMS_PER_PAGE; i++)
|
||
|
{
|
||
|
if (CURR_COMP_LIST[i] != 0)
|
||
|
m_bankComponentList->RemoveItem(CURR_COMP_LIST[i]);
|
||
|
}
|
||
|
|
||
|
memset(CURR_COMP_LIST, 0, sizeof(CURR_COMP_LIST));
|
||
|
|
||
|
for (u32 i = 0; i < m_shopPedApparel.GetCount(); i++)
|
||
|
{
|
||
|
ShopPedApparel& currApparel = *m_shopPedApparel[i];
|
||
|
|
||
|
if ((m_compCharComboIdx == SCR_CHAR_ANY || currApparel.m_eCharacter == m_compCharComboIdx) &&
|
||
|
(stricmp(currApparel.m_dlcName.c_str(), currCompDLCName) == 0 || stricmp("All", currCompDLCName) == 0))
|
||
|
{
|
||
|
for (u32 j = 0; j < currApparel.m_pedComponents.GetCount(); j++)
|
||
|
{
|
||
|
validComponents.PushAndGrow(&currApparel.m_pedComponents[j]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (validComponents.GetCount() > 0)
|
||
|
maxPage = ((validComponents.GetCount() - 1) / MAX_APPAREL_ITEMS_PER_PAGE) + 1;
|
||
|
|
||
|
m_currentComponentPg = nextPage;
|
||
|
m_currentComponentPg = rage::Clamp(m_currentComponentPg, 0, maxPage - 1);
|
||
|
|
||
|
|
||
|
formatf(m_shopPedComponentCounts, "Count: [%i] // Page: [%i / %i]", validComponents.GetCount(), (m_currentComponentPg + 1), maxPage);
|
||
|
|
||
|
if (lookupHash == 0)
|
||
|
{
|
||
|
int startIndex = m_currentComponentPg * MAX_APPAREL_ITEMS_PER_PAGE;
|
||
|
|
||
|
for (s32 i = startIndex; (i < (startIndex + MAX_APPAREL_ITEMS_PER_PAGE)) && (i < validComponents.GetCount()); i++)
|
||
|
AddComponentToBankList(validComponents[i], i - startIndex);
|
||
|
}
|
||
|
else
|
||
|
AddComponentToBankList(GetShopPedComponent(lookupHash), 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static u32 CURR_PROP_LIST[MAX_APPAREL_ITEMS_PER_PAGE] = { 0 };
|
||
|
|
||
|
void CExtraMetadataMgr::AddPropToBankList(ShopPedProp* currentItem, s32 index)
|
||
|
{
|
||
|
if (currentItem)
|
||
|
{
|
||
|
u32 count = 0;
|
||
|
m_bankPropList->AddItem(currentItem->m_uniqueNameHash, count++, currentItem->m_uniqueNameHash.TryGetCStr());
|
||
|
m_bankPropList->AddItem(currentItem->m_uniqueNameHash, count++, currentItem->m_textLabel);
|
||
|
m_bankPropList->AddItem(currentItem->m_uniqueNameHash, count++, currentItem->m_eShopEnum);
|
||
|
m_bankPropList->AddItem(currentItem->m_uniqueNameHash, count++, currentItem->m_locate);
|
||
|
m_bankPropList->AddItem(currentItem->m_uniqueNameHash, count++, (s32)currentItem->m_localPropIndex);
|
||
|
m_bankPropList->AddItem(currentItem->m_uniqueNameHash, count++, (s32)currentItem->m_propIndex);
|
||
|
m_bankPropList->AddItem(currentItem->m_uniqueNameHash, count++, currentItem->m_textureIndex);
|
||
|
m_bankPropList->AddItem(currentItem->m_uniqueNameHash, count++, currentItem->m_eAnchorPoint);
|
||
|
m_bankPropList->AddItem(currentItem->m_uniqueNameHash, count++, currentItem->m_cost);
|
||
|
m_bankPropList->AddItem(currentItem->m_uniqueNameHash, count++, currentItem->m_isInOutfit?"TRUE":"FALSE");
|
||
|
|
||
|
if (Verifyf(index < MAX_APPAREL_ITEMS_PER_PAGE, "CExtraMetadataMgr::AddPropToBankList - Index out of range! %u / %u", index, MAX_APPAREL_ITEMS_PER_PAGE))
|
||
|
CURR_PROP_LIST[index] = currentItem->m_uniqueNameHash;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::DisplayPedProps(s32 nextPage, u32 lookupHash, bool buildDLCNames)
|
||
|
{
|
||
|
if (buildDLCNames)
|
||
|
{
|
||
|
BuildDLCNamesArray(ms_propDLCNames, m_propCharComboIdx);
|
||
|
|
||
|
m_propDLCNameComboIdx = 0;
|
||
|
m_propDLCNameCombo->UpdateCombo("DLC Name:", &m_propDLCNameComboIdx, ms_propDLCNames.GetCount(), ms_propDLCNames.GetElements(), datCallback(MFA(CExtraMetadataMgr::PropDLCNameComboCB),(datBase*)this), NULL);
|
||
|
}
|
||
|
|
||
|
if (m_bankPropList)
|
||
|
{
|
||
|
const char* currPropDLCName = m_propDLCNameCombo->GetString(m_propDLCNameComboIdx);
|
||
|
atArray<ShopPedProp*> validProps;
|
||
|
s32 maxPage = 1;
|
||
|
|
||
|
// remove all the items first...
|
||
|
for (u32 i = 0; i < MAX_APPAREL_ITEMS_PER_PAGE; i++)
|
||
|
{
|
||
|
if (CURR_PROP_LIST[i] != 0)
|
||
|
m_bankPropList->RemoveItem(CURR_PROP_LIST[i]);
|
||
|
}
|
||
|
|
||
|
memset(CURR_PROP_LIST, 0, sizeof(CURR_PROP_LIST));
|
||
|
|
||
|
for (u32 i = 0; i < m_shopPedApparel.GetCount(); i++)
|
||
|
{
|
||
|
ShopPedApparel& currApparel = *m_shopPedApparel[i];
|
||
|
|
||
|
if ((m_propCharComboIdx == SCR_CHAR_ANY || currApparel.m_eCharacter == m_propCharComboIdx) &&
|
||
|
(stricmp(currApparel.m_dlcName.c_str(), currPropDLCName) == 0 || stricmp("All", currPropDLCName) == 0))
|
||
|
{
|
||
|
for (u32 j = 0; j < currApparel.m_pedProps.GetCount(); j++)
|
||
|
{
|
||
|
validProps.PushAndGrow(&currApparel.m_pedProps[j]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (validProps.GetCount() > 0)
|
||
|
maxPage = ((validProps.GetCount() - 1) / MAX_APPAREL_ITEMS_PER_PAGE) + 1;
|
||
|
|
||
|
m_currentPropPg = nextPage;
|
||
|
m_currentPropPg = rage::Clamp(m_currentPropPg, 0, maxPage - 1);
|
||
|
|
||
|
formatf(m_shopPedPropCounts, "Count: [%i] // Page: [%i / %i]", validProps.GetCount(), (m_currentPropPg + 1), maxPage);
|
||
|
|
||
|
if (lookupHash == 0)
|
||
|
{
|
||
|
int startIndex = m_currentPropPg * MAX_APPAREL_ITEMS_PER_PAGE;
|
||
|
|
||
|
for (int i = startIndex; (i < (startIndex + MAX_APPAREL_ITEMS_PER_PAGE)) && (i < validProps.GetCount()); i++)
|
||
|
AddPropToBankList(validProps[i], i - startIndex);
|
||
|
}
|
||
|
else
|
||
|
AddPropToBankList(GetShopPedProp(lookupHash), 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static u32 CURR_OUTFIT_LIST[MAX_APPAREL_ITEMS_PER_PAGE] = { 0 };
|
||
|
|
||
|
void CExtraMetadataMgr::AddOutfitToBankList(ShopPedOutfit* currentItem, s32 index)
|
||
|
{
|
||
|
if (currentItem)
|
||
|
{
|
||
|
u32 count = 0;
|
||
|
m_bankOutfitList->RemoveItem(currentItem->m_uniqueNameHash);
|
||
|
m_bankOutfitList->AddItem(currentItem->m_uniqueNameHash,count++,currentItem->m_uniqueNameHash.TryGetCStr());
|
||
|
m_bankOutfitList->AddItem(currentItem->m_uniqueNameHash,count++,currentItem->m_cost);
|
||
|
m_bankOutfitList->AddItem(currentItem->m_uniqueNameHash,count++,currentItem->m_textLabel);
|
||
|
m_bankOutfitList->AddItem(currentItem->m_uniqueNameHash,count++,currentItem->m_includedPedComponents.GetCount());
|
||
|
m_bankOutfitList->AddItem(currentItem->m_uniqueNameHash,count++,currentItem->m_includedPedProps.GetCount());
|
||
|
|
||
|
if (Verifyf(index < MAX_APPAREL_ITEMS_PER_PAGE, "CExtraMetadataMgr::AddOutfitToBankList - Index out of range! %u / %u", index, MAX_APPAREL_ITEMS_PER_PAGE))
|
||
|
CURR_OUTFIT_LIST[index] = currentItem->m_uniqueNameHash;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::DisplayPedOutfits(s32 nextPage, u32 lookupHash, bool buildDLCNames)
|
||
|
{
|
||
|
if (buildDLCNames)
|
||
|
{
|
||
|
BuildDLCNamesArray(ms_outfitDLCNames, m_outfitCharComboIdx);
|
||
|
|
||
|
m_outfitDLCNameComboIdx = 0;
|
||
|
m_outfitDLCNameCombo->UpdateCombo("DLC Name:", &m_outfitDLCNameComboIdx, ms_outfitDLCNames.GetCount(), ms_outfitDLCNames.GetElements(), datCallback(MFA(CExtraMetadataMgr::OutfitDLCNameComboCB),(datBase*)this), NULL);
|
||
|
}
|
||
|
|
||
|
if (m_bankOutfitList)
|
||
|
{
|
||
|
const char* currOutfitDLCName = m_outfitDLCNameCombo->GetString(m_outfitDLCNameComboIdx);
|
||
|
atArray<ShopPedOutfit*> validOutfits;
|
||
|
s32 maxPage = 1;
|
||
|
|
||
|
// remove all the items first...
|
||
|
for (u32 i = 0; i < MAX_APPAREL_ITEMS_PER_PAGE; i++)
|
||
|
{
|
||
|
if (CURR_OUTFIT_LIST[i] != 0)
|
||
|
m_bankOutfitList->RemoveItem(CURR_OUTFIT_LIST[i]);
|
||
|
}
|
||
|
|
||
|
memset(CURR_OUTFIT_LIST, 0, sizeof(CURR_OUTFIT_LIST));
|
||
|
|
||
|
for (u32 i = 0; i < m_shopPedApparel.GetCount(); i++)
|
||
|
{
|
||
|
ShopPedApparel& currApparel = *m_shopPedApparel[i];
|
||
|
|
||
|
if ((m_outfitCharComboIdx == SCR_CHAR_ANY || currApparel.m_eCharacter == m_outfitCharComboIdx) &&
|
||
|
(stricmp(currApparel.m_dlcName.c_str(), currOutfitDLCName) == 0 || stricmp("All", currOutfitDLCName) == 0))
|
||
|
{
|
||
|
for (u32 j = 0; j < currApparel.m_pedOutfits.GetCount(); j++)
|
||
|
{
|
||
|
validOutfits.PushAndGrow(&currApparel.m_pedOutfits[j]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (validOutfits.GetCount() > 0)
|
||
|
maxPage = ((validOutfits.GetCount() - 1) / MAX_APPAREL_ITEMS_PER_PAGE) + 1;
|
||
|
|
||
|
m_currentOutfitPg = nextPage;
|
||
|
m_currentOutfitPg = rage::Clamp(m_currentOutfitPg, 0, maxPage - 1);
|
||
|
|
||
|
formatf(m_shopPedOutfitCounts, "Count: [%i] // Page: [%i / %i]", validOutfits.GetCount(), (m_currentOutfitPg + 1), maxPage);
|
||
|
|
||
|
if (lookupHash == 0)
|
||
|
{
|
||
|
int startIndex = m_currentOutfitPg * MAX_APPAREL_ITEMS_PER_PAGE;
|
||
|
|
||
|
for (int i = startIndex; (i < (startIndex + MAX_APPAREL_ITEMS_PER_PAGE)) && (i < validOutfits.GetCount()); i++)
|
||
|
AddOutfitToBankList(validOutfits[i], i - startIndex);
|
||
|
}
|
||
|
else
|
||
|
AddOutfitToBankList(GetShopPedOutfit(lookupHash), 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::ComponentDblClickCB(s32 nameHash)
|
||
|
{
|
||
|
ShopPedComponent* clickedItem = GetShopPedComponent((u32)nameHash);
|
||
|
CPed* pPlayer = CGameWorld::FindLocalPlayer();
|
||
|
|
||
|
if (pPlayer && clickedItem)
|
||
|
pPlayer->SetVariation(clickedItem->m_eCompType, clickedItem->m_drawableIndex, 0, clickedItem->m_textureIndex, 0, 0, false);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::PropDblClickCB(s32 nameHash)
|
||
|
{
|
||
|
ShopPedProp* clickedItem = GetShopPedProp((u32)nameHash);
|
||
|
CPed* pPlayer = CGameWorld::FindLocalPlayer();
|
||
|
|
||
|
if (pPlayer && clickedItem)
|
||
|
{
|
||
|
if (CPedPropsMgr::IsPropValid(pPlayer, (eAnchorPoints)clickedItem->m_eAnchorPoint, clickedItem->m_propIndex, clickedItem->m_textureIndex))
|
||
|
CPedPropsMgr::SetPedProp(pPlayer, (eAnchorPoints)clickedItem->m_eAnchorPoint, clickedItem->m_propIndex, clickedItem->m_textureIndex, ANCHOR_NONE, NULL, NULL);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::OutfitDblClickCB(s32 nameHash)
|
||
|
{
|
||
|
ShopPedOutfit* clickedItem = GetShopPedOutfit((u32)nameHash);
|
||
|
CPed* pPlayer = CGameWorld::FindLocalPlayer();
|
||
|
if(pPlayer && clickedItem)
|
||
|
{
|
||
|
for(int i=0;i<clickedItem->m_includedPedComponents.GetCount();i++)
|
||
|
{
|
||
|
ComponentDblClickCB(clickedItem->m_includedPedComponents[i].m_nameHash);
|
||
|
}
|
||
|
for(int i=0;i<clickedItem->m_includedPedProps.GetCount();i++)
|
||
|
{
|
||
|
PropDblClickCB(clickedItem->m_includedPedProps[i].m_nameHash);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::LookupShopPedComponent()
|
||
|
{
|
||
|
DisplayPedComponents(m_currentComponentPg, atStringHash(m_shopPedComponentLookup), false);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::LookupShopPedProp()
|
||
|
{
|
||
|
DisplayPedProps(m_currentPropPg, atStringHash(m_shopPedPropLookup), false);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::LookupShopPedOutfit()
|
||
|
{
|
||
|
DisplayPedOutfits(m_currentOutfitPg, atStringHash(m_shopPedOutfitLookup), false);
|
||
|
}
|
||
|
|
||
|
void CExtraMetadataMgr::DebugPrintTattooShopItems() const
|
||
|
{
|
||
|
extern const char* parser_eTattooFaction_Strings[];
|
||
|
extern const char* parser_eTattooFacing_Strings[];
|
||
|
Displayf("--------------------------------------------");
|
||
|
Displayf("------------ TATTOO SHOP ITEMS -------------");
|
||
|
Displayf("---------------- (UNSORTED) ----------------");
|
||
|
|
||
|
for(int i=0; i<m_tattooShopsItems.GetCount(); ++i)
|
||
|
{
|
||
|
Displayf("---- DLC Collection Hash 0x%X", m_tattooShopsItems[i].m_nameHash.GetHash());
|
||
|
for(int j=0; j<m_tattooShopsItems[i].TattooShopItems.GetCount(); ++j)
|
||
|
{
|
||
|
Displayf("- %d: 0x%d 0x%X %s %d %s 0x%X \"%s\"",
|
||
|
m_tattooShopsItems[i].TattooShopItems[j].m_id,
|
||
|
m_tattooShopsItems[i].TattooShopItems[j].m_collection.GetHash(),
|
||
|
m_tattooShopsItems[i].TattooShopItems[j].m_preset.GetHash(),
|
||
|
parser_eTattooFaction_Strings[m_tattooShopsItems[i].TattooShopItems[j].m_eFaction],
|
||
|
m_tattooShopsItems[i].TattooShopItems[j].m_cost,
|
||
|
parser_eTattooFacing_Strings[m_tattooShopsItems[i].TattooShopItems[j].m_eFacing],
|
||
|
m_tattooShopsItems[i].TattooShopItems[j].m_updateGroup.GetHash(),
|
||
|
m_tattooShopsItems[i].TattooShopItems[j].m_textLabel.c_str() );
|
||
|
}
|
||
|
Displayf("");
|
||
|
}
|
||
|
|
||
|
Displayf("--------------------------------------------");
|
||
|
Displayf("------------ TATTOO SHOP ITEMS -------------");
|
||
|
Displayf("----------------- (LOOKUP) -----------------");
|
||
|
for(int iFaction=0; iFaction<m_tattooShopItemsLookup.size(); ++iFaction)
|
||
|
{
|
||
|
Displayf("---- Faction %s", parser_eTattooFaction_Strings[iFaction]);
|
||
|
for(int j=0; j<m_tattooShopItemsLookup[iFaction].GetCount(); ++j)
|
||
|
{
|
||
|
const TattooShopItem* pTattooItem = GetTattooShopItem((eTattooFaction)iFaction, j);
|
||
|
Displayf("- %d: 0x%X 0x%X %s %d %s 0x%X \"%s\"",
|
||
|
pTattooItem->m_id,
|
||
|
pTattooItem->m_collection.GetHash(),
|
||
|
pTattooItem->m_preset.GetHash(),
|
||
|
parser_eTattooFaction_Strings[pTattooItem->m_eFaction],
|
||
|
pTattooItem->m_cost,
|
||
|
parser_eTattooFacing_Strings[pTattooItem->m_eFacing],
|
||
|
pTattooItem->m_updateGroup.GetHash(),
|
||
|
pTattooItem->m_textLabel.c_str() );
|
||
|
}
|
||
|
Displayf("");
|
||
|
}
|
||
|
}
|
||
|
#endif // __BANK && !__SPU
|
||
|
|
||
|
int CExtraMetadataMgr::GetNumTattooShopItemsInFaction(eTattooFaction faction) const
|
||
|
{
|
||
|
if((u32)faction < (u32)m_tattooShopItemsLookup.size())
|
||
|
{
|
||
|
return m_tattooShopItemsLookup[faction].GetCount();
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
const TattooShopItem* CExtraMetadataMgr::GetTattooShopItem(eTattooFaction faction, int idx) const
|
||
|
{
|
||
|
if((u32)faction < (u32)m_tattooShopItemsLookup.size()
|
||
|
&& (u32)idx < (u32)m_tattooShopItemsLookup[faction].GetCount())
|
||
|
{
|
||
|
const tattooLookupEntry& slotReferences = m_tattooShopItemsLookup[faction][idx];
|
||
|
Assert(slotReferences.collection < m_tattooShopsItems.GetCount() && slotReferences.index < m_tattooShopsItems[slotReferences.collection].TattooShopItems.GetCount());
|
||
|
return &m_tattooShopsItems[slotReferences.collection].TattooShopItems[slotReferences.index];
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
s32 CExtraMetadataMgr::GetTattooShopItemIndex(eTattooFaction faction, s32 collectionHash, s32 presetHash) const
|
||
|
{
|
||
|
const s32 numberOfTattoosForThisFaction = GetNumTattooShopItemsInFaction(faction);
|
||
|
|
||
|
bool bIgnoreCollectionHash = false;
|
||
|
if (collectionHash == -1)
|
||
|
{
|
||
|
bIgnoreCollectionHash = true;
|
||
|
}
|
||
|
|
||
|
u32 unsignedCollectionHash = static_cast<u32>(collectionHash);
|
||
|
u32 unsignedPresetHash = static_cast<u32>(presetHash);
|
||
|
|
||
|
for (s32 loop = 0; loop < numberOfTattoosForThisFaction; loop++)
|
||
|
{
|
||
|
const TattooShopItem *pTattoo = GetTattooShopItem(faction, loop);
|
||
|
if (pTattoo)
|
||
|
{
|
||
|
if ( (bIgnoreCollectionHash || (pTattoo->m_collection.GetHash() == unsignedCollectionHash) )
|
||
|
&& (pTattoo->m_preset.GetHash() == unsignedPresetHash) )
|
||
|
{
|
||
|
return loop;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|