Structureddata stuff. Not the best implementation, but better than our old one :P
This commit is contained in:
parent
b4be34c8a8
commit
c1ef716e5c
@ -13,8 +13,8 @@ namespace Components
|
|||||||
virtual void Load(Game::XAssetHeader* header, std::string name, ZoneBuilder::Zone* builder) { /*ErrorTypeNotSupported(this);*/ };
|
virtual void Load(Game::XAssetHeader* header, std::string name, ZoneBuilder::Zone* builder) { /*ErrorTypeNotSupported(this);*/ };
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Game::XAssetHeader(*Callback)(Game::XAssetType, const char*);
|
typedef Game::XAssetHeader(*Callback)(Game::XAssetType type, std::string name);
|
||||||
typedef bool(*RestrictCallback)(Game::XAssetType type, Game::XAssetHeader asset, const char* name);
|
typedef bool(*RestrictCallback)(Game::XAssetType type, Game::XAssetHeader asset, std::string name);
|
||||||
|
|
||||||
AssetHandler();
|
AssetHandler();
|
||||||
~AssetHandler();
|
~AssetHandler();
|
||||||
|
@ -10,6 +10,11 @@ namespace Components
|
|||||||
std::vector<Game::XZoneInfo> data;
|
std::vector<Game::XZoneInfo> data;
|
||||||
Utils::Merge(&data, zoneInfo, zoneCount);
|
Utils::Merge(&data, zoneInfo, zoneCount);
|
||||||
|
|
||||||
|
if (FastFiles::Exists("patch_iw4x"))
|
||||||
|
{
|
||||||
|
data.push_back({ "patch_iw4x", 1, 0 });
|
||||||
|
}
|
||||||
|
|
||||||
// Load custom weapons, if present (force that later on)
|
// Load custom weapons, if present (force that later on)
|
||||||
if (FastFiles::Exists("weapons_mp"))
|
if (FastFiles::Exists("weapons_mp"))
|
||||||
{
|
{
|
||||||
|
@ -116,7 +116,7 @@ namespace Components
|
|||||||
|
|
||||||
Localization::Localization()
|
Localization::Localization()
|
||||||
{
|
{
|
||||||
AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_LOCALIZE, [] (Game::XAssetType, const char* filename)
|
AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_LOCALIZE, [] (Game::XAssetType, std::string filename)
|
||||||
{
|
{
|
||||||
Game::XAssetHeader header = { 0 };
|
Game::XAssetHeader header = { 0 };
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ namespace Components
|
|||||||
return FastFiles::LoadLocalizeZones(data.data(), data.size(), sync);
|
return FastFiles::LoadLocalizeZones(data.data(), data.size(), sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Maps::LoadAssetRestrict(Game::XAssetType type, Game::XAssetHeader asset, const char* name)
|
bool Maps::LoadAssetRestrict(Game::XAssetType type, Game::XAssetHeader asset, std::string name)
|
||||||
{
|
{
|
||||||
if (std::find(Maps::CurrentDependencies.begin(), Maps::CurrentDependencies.end(), FastFiles::Current()) != Maps::CurrentDependencies.end())
|
if (std::find(Maps::CurrentDependencies.begin(), Maps::CurrentDependencies.end(), FastFiles::Current()) != Maps::CurrentDependencies.end())
|
||||||
{
|
{
|
||||||
@ -63,7 +63,7 @@ namespace Components
|
|||||||
if (type == Game::XAssetType::ASSET_TYPE_MAP_ENTS)
|
if (type == Game::XAssetType::ASSET_TYPE_MAP_ENTS)
|
||||||
{
|
{
|
||||||
static std::string mapEntities;
|
static std::string mapEntities;
|
||||||
FileSystem::File ents(Utils::VA("%s.ents", name));
|
FileSystem::File ents(name + ".ents");
|
||||||
if (ents.Exists())
|
if (ents.Exists())
|
||||||
{
|
{
|
||||||
mapEntities = ents.GetBuffer();
|
mapEntities = ents.GetBuffer();
|
||||||
|
@ -19,7 +19,7 @@ namespace Components
|
|||||||
static std::vector<std::string> CurrentDependencies;
|
static std::vector<std::string> CurrentDependencies;
|
||||||
|
|
||||||
static void GetBSPName(char* buffer, size_t size, const char* format, const char* mapname);
|
static void GetBSPName(char* buffer, size_t size, const char* format, const char* mapname);
|
||||||
static bool LoadAssetRestrict(Game::XAssetType type, Game::XAssetHeader asset, const char* name);
|
static bool LoadAssetRestrict(Game::XAssetType type, Game::XAssetHeader asset, std::string name);
|
||||||
static void LoadMapZones(Game::XZoneInfo *zoneInfo, unsigned int zoneCount, int sync);
|
static void LoadMapZones(Game::XZoneInfo *zoneInfo, unsigned int zoneCount, int sync);
|
||||||
|
|
||||||
void ReallocateEntryPool();
|
void ReallocateEntryPool();
|
||||||
|
@ -506,16 +506,16 @@ namespace Components
|
|||||||
Menus::MenuList.clear();
|
Menus::MenuList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::XAssetHeader Menus::MenuLoad(Game::XAssetType type, const char* filename)
|
Game::XAssetHeader Menus::MenuLoad(Game::XAssetType type, std::string filename)
|
||||||
{
|
{
|
||||||
return { Game::Menus_FindByName(Game::uiContext, filename) };
|
return { Game::Menus_FindByName(Game::uiContext, filename.data()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::XAssetHeader Menus::MenuFileLoad(Game::XAssetType type, const char* filename)
|
Game::XAssetHeader Menus::MenuFileLoad(Game::XAssetType type, std::string filename)
|
||||||
{
|
{
|
||||||
Game::XAssetHeader header = { 0 };
|
Game::XAssetHeader header = { 0 };
|
||||||
|
|
||||||
Game::MenuList* menuList = Game::DB_FindXAssetHeader(type, filename).menuList;
|
Game::MenuList* menuList = Game::DB_FindXAssetHeader(type, filename.data()).menuList;
|
||||||
header.menuList = menuList;
|
header.menuList = menuList;
|
||||||
|
|
||||||
// Free the last menulist and ui context, as we have to rebuild it with the new menus
|
// Free the last menulist and ui context, as we have to rebuild it with the new menus
|
||||||
@ -538,7 +538,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
if (FileSystem::File(filename).Exists())
|
if (FileSystem::File(filename).Exists())
|
||||||
{
|
{
|
||||||
header.menuList = Menus::LoadScriptMenu(filename);
|
header.menuList = Menus::LoadScriptMenu(filename.data());
|
||||||
|
|
||||||
// Reset, if we didn't find scriptmenus
|
// Reset, if we didn't find scriptmenus
|
||||||
if (!header.menuList)
|
if (!header.menuList)
|
||||||
|
@ -19,8 +19,8 @@ namespace Components
|
|||||||
static std::map<std::string, Game::MenuList*> MenuListList;
|
static std::map<std::string, Game::MenuList*> MenuListList;
|
||||||
static std::vector<std::string> CustomMenus;
|
static std::vector<std::string> CustomMenus;
|
||||||
|
|
||||||
static Game::XAssetHeader MenuLoad(Game::XAssetType type, const char* filename);
|
static Game::XAssetHeader MenuLoad(Game::XAssetType type, std::string filename);
|
||||||
static Game::XAssetHeader MenuFileLoad(Game::XAssetType type, const char* filename);
|
static Game::XAssetHeader MenuFileLoad(Game::XAssetType type, std::string filename);
|
||||||
|
|
||||||
static Game::MenuList* LoadMenuList(Game::MenuList* menuList);
|
static Game::MenuList* LoadMenuList(Game::MenuList* menuList);
|
||||||
static Game::MenuList* LoadScriptMenu(const char* menu);
|
static Game::MenuList* LoadScriptMenu(const char* menu);
|
||||||
|
@ -9,13 +9,13 @@ namespace Components
|
|||||||
MusicalTalent::SoundAliasList[Utils::StrToLower(sound)] = file;
|
MusicalTalent::SoundAliasList[Utils::StrToLower(sound)] = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::XAssetHeader MusicalTalent::ManipulateAliases(Game::XAssetType type, const char* filename)
|
Game::XAssetHeader MusicalTalent::ModifyAliases(Game::XAssetType type, std::string filename)
|
||||||
{
|
{
|
||||||
Game::XAssetHeader header = { 0 };
|
Game::XAssetHeader header = { 0 };
|
||||||
|
|
||||||
if (MusicalTalent::SoundAliasList.find(Utils::StrToLower(filename)) != MusicalTalent::SoundAliasList.end())
|
if (MusicalTalent::SoundAliasList.find(Utils::StrToLower(filename)) != MusicalTalent::SoundAliasList.end())
|
||||||
{
|
{
|
||||||
Game::snd_alias_list_t* aliases = Game::DB_FindXAssetHeader(type, filename).aliasList;
|
Game::snd_alias_list_t* aliases = Game::DB_FindXAssetHeader(type, filename.data()).aliasList;
|
||||||
|
|
||||||
if (aliases)
|
if (aliases)
|
||||||
{
|
{
|
||||||
@ -33,7 +33,7 @@ namespace Components
|
|||||||
|
|
||||||
MusicalTalent::MusicalTalent()
|
MusicalTalent::MusicalTalent()
|
||||||
{
|
{
|
||||||
AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_SOUND, MusicalTalent::ManipulateAliases);
|
AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_SOUND, MusicalTalent::ModifyAliases);
|
||||||
|
|
||||||
MusicalTalent::Replace("music_mainmenu_mp", "hz_boneyard_intro_LR_1.mp3");
|
MusicalTalent::Replace("music_mainmenu_mp", "hz_boneyard_intro_LR_1.mp3");
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,6 @@ namespace Components
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static std::map<std::string, const char*> SoundAliasList;
|
static std::map<std::string, const char*> SoundAliasList;
|
||||||
static Game::XAssetHeader ManipulateAliases(Game::XAssetType type, const char* filename);
|
static Game::XAssetHeader ModifyAliases(Game::XAssetType type, std::string filename);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -18,14 +18,14 @@ namespace Components
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::StringTable* StringTable::LoadObject(const char* filename)
|
Game::StringTable* StringTable::LoadObject(std::string filename)
|
||||||
{
|
{
|
||||||
Game::StringTable* table = nullptr;
|
Game::StringTable* table = nullptr;
|
||||||
FileSystem::File rawTable(filename);
|
FileSystem::File rawTable(filename);
|
||||||
|
|
||||||
if (rawTable.Exists())
|
if (rawTable.Exists())
|
||||||
{
|
{
|
||||||
Utils::CSV parsedTable(rawTable.GetBuffer(), false);
|
Utils::CSV parsedTable(rawTable.GetBuffer(), false, false);
|
||||||
|
|
||||||
table = Utils::Memory::AllocateArray<Game::StringTable>(1);
|
table = Utils::Memory::AllocateArray<Game::StringTable>(1);
|
||||||
|
|
||||||
@ -67,10 +67,7 @@ namespace Components
|
|||||||
|
|
||||||
StringTable::StringTable()
|
StringTable::StringTable()
|
||||||
{
|
{
|
||||||
// Disable StringTable loading until our StructuredData handler is finished!
|
AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_STRINGTABLE, [] (Game::XAssetType, std::string filename)
|
||||||
#ifdef ENABLE_STRINGTABLES
|
|
||||||
|
|
||||||
AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_STRINGTABLE, [] (Game::XAssetType, const char* filename)
|
|
||||||
{
|
{
|
||||||
Game::XAssetHeader header = { 0 };
|
Game::XAssetHeader header = { 0 };
|
||||||
|
|
||||||
@ -85,7 +82,6 @@ namespace Components
|
|||||||
|
|
||||||
return header;
|
return header;
|
||||||
});
|
});
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StringTable::~StringTable()
|
StringTable::~StringTable()
|
||||||
|
@ -11,6 +11,6 @@ namespace Components
|
|||||||
static std::map<std::string, Game::StringTable*> StringTableMap;
|
static std::map<std::string, Game::StringTable*> StringTableMap;
|
||||||
|
|
||||||
static int Hash(const char* data);
|
static int Hash(const char* data);
|
||||||
static Game::StringTable* LoadObject(const char* filename);
|
static Game::StringTable* LoadObject(std::string filename);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,92 @@
|
|||||||
|
|
||||||
namespace Components
|
namespace Components
|
||||||
{
|
{
|
||||||
|
StructuredData* StructuredData::Singleton = nullptr;
|
||||||
|
|
||||||
|
int StructuredData::IndexCount[StructuredData::ENUM_MAX];
|
||||||
|
Game::structuredDataEnumIndex_t* StructuredData::Indices[StructuredData::ENUM_MAX];
|
||||||
|
std::vector<StructuredData::EnumEntry> StructuredData::Entries[StructuredData::ENUM_MAX];
|
||||||
|
|
||||||
|
void StructuredData::AddPlayerDataEntry(StructuredData::PlayerDataType type, int index, std::string name)
|
||||||
|
{
|
||||||
|
if (type >= StructuredData::ENUM_MAX) return;
|
||||||
|
|
||||||
|
// Check for duplications
|
||||||
|
for (auto entry : StructuredData::Entries[type])
|
||||||
|
{
|
||||||
|
if (entry.name == name || entry.statOffset == index)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StructuredData::Entries[type].push_back({ name, index });
|
||||||
|
}
|
||||||
|
|
||||||
|
void StructuredData::PatchPlayerDataEnum(Game::structuredDataDef_t* data, StructuredData::PlayerDataType type, std::vector<StructuredData::EnumEntry>& entries)
|
||||||
|
{
|
||||||
|
if (!data || !data->data) return;
|
||||||
|
|
||||||
|
Game::structuredDataEnum_t* dataEnum = &data->data->enums[type];
|
||||||
|
|
||||||
|
if (StructuredData::IndexCount[type])
|
||||||
|
{
|
||||||
|
dataEnum->numIndices = StructuredData::IndexCount[type];
|
||||||
|
dataEnum->indices = StructuredData::Indices[type];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find last index so we can add our offset to it.
|
||||||
|
// This whole procedure is potentially unsafe.
|
||||||
|
// If any index changes, everything gets shifted and the stats are fucked.
|
||||||
|
int lastIndex = 0;
|
||||||
|
for (int i = 0; i < dataEnum->numIndices; i++)
|
||||||
|
{
|
||||||
|
if (dataEnum->indices[i].index > lastIndex)
|
||||||
|
{
|
||||||
|
lastIndex = dataEnum->indices[i].index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate new count
|
||||||
|
StructuredData::IndexCount[type] = dataEnum->numIndices + entries.size();
|
||||||
|
|
||||||
|
// Allocate new entries
|
||||||
|
StructuredData::Indices[type] = StructuredData::GetSingleton()->MemAllocator.AllocateArray<Game::structuredDataEnumIndex_t>(StructuredData::IndexCount[type]);
|
||||||
|
memcpy(StructuredData::Indices[type], dataEnum->indices, sizeof(Game::structuredDataEnumIndex_t) * dataEnum->numIndices);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < entries.size(); i++)
|
||||||
|
{
|
||||||
|
unsigned int pos = 0;
|
||||||
|
|
||||||
|
for (; pos < (dataEnum->numIndices + i); pos++)
|
||||||
|
{
|
||||||
|
if (StructuredData::Indices[type][pos].key == entries[i].name)
|
||||||
|
{
|
||||||
|
Logger::Error("Duplicate playerdatadef entry found: %s", entries[i].name.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
// We found our position
|
||||||
|
if (entries[i].name < StructuredData::Indices[type][pos].key)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int j = dataEnum->numIndices + i; j > pos; j--)
|
||||||
|
{
|
||||||
|
StructuredData::Indices[type][j] = StructuredData::Indices[type][j - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
StructuredData::Indices[type][pos].index = entries[i].statOffset + lastIndex;
|
||||||
|
StructuredData::Indices[type][pos].key = StructuredData::GetSingleton()->MemAllocator.DuplicateString(entries[i].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply our patches
|
||||||
|
dataEnum->numIndices = StructuredData::IndexCount[type];
|
||||||
|
dataEnum->indices = StructuredData::Indices[type];
|
||||||
|
}
|
||||||
|
|
||||||
void StructuredData::DumpDataDef(Game::structuredDataDef_t* dataDef)
|
void StructuredData::DumpDataDef(Game::structuredDataDef_t* dataDef)
|
||||||
{
|
{
|
||||||
if (!dataDef || !dataDef->data) return;
|
if (!dataDef || !dataDef->data) return;
|
||||||
@ -16,17 +102,72 @@ namespace Components
|
|||||||
Utils::WriteFile(Utils::VA("raw/%s.json", dataDef->name), definition.dump());
|
Utils::WriteFile(Utils::VA("raw/%s.json", dataDef->name), definition.dump());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StructuredData* StructuredData::GetSingleton()
|
||||||
|
{
|
||||||
|
if (!StructuredData::Singleton)
|
||||||
|
{
|
||||||
|
Logger::Error("StructuredData singleton is null!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return StructuredData::Singleton;
|
||||||
|
}
|
||||||
|
|
||||||
StructuredData::StructuredData()
|
StructuredData::StructuredData()
|
||||||
{
|
{
|
||||||
|
StructuredData::Singleton = this;
|
||||||
|
ZeroMemory(StructuredData::IndexCount, sizeof(StructuredData));
|
||||||
|
|
||||||
|
AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_STRUCTUREDDATADEF, [] (Game::XAssetType type, std::string filename)
|
||||||
|
{
|
||||||
|
Game::XAssetHeader header = { 0 };
|
||||||
|
|
||||||
|
if (filename == "mp/playerdata.def")
|
||||||
|
{
|
||||||
|
Game::structuredDataDef_t* data = AssetHandler::FindOriginalAsset(Game::XAssetType::ASSET_TYPE_STRUCTUREDDATADEF, filename.data()).structuredData;
|
||||||
|
header.structuredData = data;
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ARR_SIZE(StructuredData::Entries); i++)
|
||||||
|
{
|
||||||
|
if (StructuredData::Entries[i].size())
|
||||||
|
{
|
||||||
|
StructuredData::PatchPlayerDataEnum(data, static_cast<StructuredData::PlayerDataType>(i), StructuredData::Entries[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return header;
|
||||||
|
});
|
||||||
|
|
||||||
Command::Add("dumpDataDef", [] (Command::Params params)
|
Command::Add("dumpDataDef", [] (Command::Params params)
|
||||||
{
|
{
|
||||||
if (params.Length() < 2) return;
|
if (params.Length() < 2) return;
|
||||||
StructuredData::DumpDataDef(Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_STRUCTUREDDATADEF, params[1]).structuredData);
|
StructuredData::DumpDataDef(Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_STRUCTUREDDATADEF, params[1]).structuredData);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ---------- Weapons ----------
|
||||||
|
StructuredData::AddPlayerDataEntry(StructuredData::ENUM_WEAPONS, 1, "m40a3");
|
||||||
|
StructuredData::AddPlayerDataEntry(StructuredData::ENUM_WEAPONS, 2, "ak47classic");
|
||||||
|
//StructuredData::AddPlayerDataEntry(StructuredData::ENUM_WEAPONS, 3, "ak74u");
|
||||||
|
//StructuredData::AddPlayerDataEntry(StructuredData::ENUM_WEAPONS, 4, "peacekeeper");
|
||||||
|
|
||||||
|
// ---------- Cardicons ----------
|
||||||
|
StructuredData::AddPlayerDataEntry(StructuredData::ENUM_CARDICONS, 1, "cardicon_rtrolling");
|
||||||
|
|
||||||
|
// ---------- Cardtitles ----------
|
||||||
|
StructuredData::AddPlayerDataEntry(StructuredData::ENUM_CARDTITLES, 1, "cardtitle_evilchicken");
|
||||||
|
StructuredData::AddPlayerDataEntry(StructuredData::ENUM_CARDTITLES, 2, "cardtitle_nolaststand");
|
||||||
}
|
}
|
||||||
|
|
||||||
StructuredData::~StructuredData()
|
StructuredData::~StructuredData()
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < ARR_SIZE(StructuredData::Entries); i++)
|
||||||
|
{
|
||||||
|
StructuredData::Entries[i].clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
StructuredData::Singleton = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,47 @@ namespace Components
|
|||||||
class StructuredData : public Component
|
class StructuredData : public Component
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum PlayerDataType
|
||||||
|
{
|
||||||
|
ENUM_FEATURES,
|
||||||
|
ENUM_WEAPONS,
|
||||||
|
ENUM_ATTACHEMENTS,
|
||||||
|
ENUM_CHALLENGES,
|
||||||
|
ENUM_CAMOS,
|
||||||
|
ENUM_PERKS,
|
||||||
|
ENUM_KILLSTREAKS,
|
||||||
|
ENUM_ACCOLADES,
|
||||||
|
ENUM_CARDICONS,
|
||||||
|
ENUM_CARDTITLES,
|
||||||
|
ENUM_CARDNAMEPLATES,
|
||||||
|
ENUM_TEAMS,
|
||||||
|
ENUM_GAMETYPES,
|
||||||
|
ENUM_MAX
|
||||||
|
};
|
||||||
|
|
||||||
StructuredData();
|
StructuredData();
|
||||||
~StructuredData();
|
~StructuredData();
|
||||||
const char* GetName() { return "StructuredData"; };
|
const char* GetName() { return "StructuredData"; };
|
||||||
|
|
||||||
|
void AddPlayerDataEntry(PlayerDataType type, int index, std::string name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct EnumEntry
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
int statOffset;
|
||||||
|
};
|
||||||
|
|
||||||
static void DumpDataDef(Game::structuredDataDef_t* dataDef);
|
static void DumpDataDef(Game::structuredDataDef_t* dataDef);
|
||||||
|
static void PatchPlayerDataEnum(Game::structuredDataDef_t* data, PlayerDataType type, std::vector<EnumEntry>& entries);
|
||||||
|
static StructuredData* GetSingleton();
|
||||||
|
|
||||||
|
Utils::Memory::Allocator MemAllocator;
|
||||||
|
|
||||||
|
static int IndexCount[ENUM_MAX];
|
||||||
|
static Game::structuredDataEnumIndex_t* Indices[ENUM_MAX];
|
||||||
|
static std::vector<EnumEntry> Entries[ENUM_MAX];
|
||||||
|
|
||||||
|
static StructuredData* Singleton;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
namespace Components
|
namespace Components
|
||||||
{
|
{
|
||||||
Game::XAssetHeader Weapon::WeaponFileLoad(Game::XAssetType type, const char* filename)
|
Game::XAssetHeader Weapon::WeaponFileLoad(Game::XAssetType type, std::string filename)
|
||||||
{
|
{
|
||||||
Game::XAssetHeader header = { 0 };
|
Game::XAssetHeader header = { 0 };
|
||||||
|
|
||||||
// Try loading raw weapon
|
// Try loading raw weapon
|
||||||
if (FileSystem::File(Utils::VA("weapons/mp/%s", filename)).Exists())
|
if (FileSystem::File(Utils::VA("weapons/mp/%s", filename.data())).Exists())
|
||||||
{
|
{
|
||||||
header.data = Game::BG_LoadWeaponDef_LoadObj(filename);
|
header.data = Game::BG_LoadWeaponDef_LoadObj(filename.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
return header;
|
return header;
|
||||||
|
@ -7,6 +7,6 @@ namespace Components
|
|||||||
const char* GetName() { return "Weapon"; };
|
const char* GetName() { return "Weapon"; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Game::XAssetHeader WeaponFileLoad(Game::XAssetType type, const char* filename);
|
static Game::XAssetHeader WeaponFileLoad(Game::XAssetType type, std::string filename);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -447,7 +447,7 @@ namespace Components
|
|||||||
static_assert(sizeof(Game::XFile) == 40, "Invalid XFile structure!");
|
static_assert(sizeof(Game::XFile) == 40, "Invalid XFile structure!");
|
||||||
static_assert(Game::MAX_XFILE_COUNT == 8, "XFile block enum is invalid!");
|
static_assert(Game::MAX_XFILE_COUNT == 8, "XFile block enum is invalid!");
|
||||||
|
|
||||||
AssetHandler::OnLoad([] (Game::XAssetType type, Game::XAssetHeader asset, const char* name)
|
AssetHandler::OnLoad([] (Game::XAssetType type, Game::XAssetHeader asset, std::string name)
|
||||||
{
|
{
|
||||||
// static void* blocTable = 0;
|
// static void* blocTable = 0;
|
||||||
//
|
//
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace Utils
|
namespace Utils
|
||||||
{
|
{
|
||||||
CSV::CSV(std::string file, bool isFile)
|
CSV::CSV(std::string file, bool isFile, bool allowComments)
|
||||||
{
|
{
|
||||||
CSV::Parse(file, isFile);
|
CSV::Parse(file, isFile, allowComments);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSV::~CSV()
|
CSV::~CSV()
|
||||||
@ -64,7 +64,7 @@ namespace Utils
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSV::Parse(std::string file, bool isFile)
|
void CSV::Parse(std::string file, bool isFile, bool allowComments)
|
||||||
{
|
{
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
|
|
||||||
@ -84,12 +84,12 @@ namespace Utils
|
|||||||
|
|
||||||
for (auto row : rows)
|
for (auto row : rows)
|
||||||
{
|
{
|
||||||
CSV::ParseRow(row);
|
CSV::ParseRow(row, allowComments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSV::ParseRow(std::string row)
|
void CSV::ParseRow(std::string row, bool allowComments)
|
||||||
{
|
{
|
||||||
bool isString = false;
|
bool isString = false;
|
||||||
std::string element;
|
std::string element;
|
||||||
@ -119,7 +119,7 @@ namespace Utils
|
|||||||
//++i;
|
//++i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (!isString && row[i] == '#') // Skip comments. I know CSVs usually don't have comments, but in this case it's useful
|
else if (!isString && row[i] == '#' && allowComments) // Skip comments. I know CSVs usually don't have comments, but in this case it's useful
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ namespace Utils
|
|||||||
class CSV
|
class CSV
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CSV(std::string file, bool isFile = true);
|
CSV(std::string file, bool isFile = true, bool allowComments = true);
|
||||||
~CSV();
|
~CSV();
|
||||||
|
|
||||||
int GetRows();
|
int GetRows();
|
||||||
@ -14,8 +14,8 @@ namespace Utils
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void Parse(std::string file, bool isFile = true);
|
void Parse(std::string file, bool isFile = true, bool allowComments = true);
|
||||||
void ParseRow(std::string row);
|
void ParseRow(std::string row, bool allowComments = true);
|
||||||
std::vector<std::vector<std::string>> DataMap;
|
std::vector<std::vector<std::string>> DataMap;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,9 @@ namespace Utils
|
|||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EndsWith(const char* haystack, const char* needle)
|
bool EndsWith(std::string haystack, std::string needle)
|
||||||
{
|
{
|
||||||
return (strstr(haystack, needle) == (haystack + strlen(haystack) - strlen(needle)));
|
return (strstr(haystack.data(), needle.data()) == (haystack.data() + haystack.size() - needle.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> Explode(const std::string& str, char delim)
|
std::vector<std::string> Explode(const std::string& str, char delim)
|
||||||
|
@ -4,7 +4,7 @@ namespace Utils
|
|||||||
{
|
{
|
||||||
const char *VA(const char *fmt, ...);
|
const char *VA(const char *fmt, ...);
|
||||||
std::string StrToLower(std::string input);
|
std::string StrToLower(std::string input);
|
||||||
bool EndsWith(const char* haystack, const char* needle);
|
bool EndsWith(std::string haystack, std::string needle);
|
||||||
std::vector<std::string> Explode(const std::string& str, char delim);
|
std::vector<std::string> Explode(const std::string& str, char delim);
|
||||||
void Replace(std::string &string, std::string find, std::string replace);
|
void Replace(std::string &string, std::string find, std::string replace);
|
||||||
bool StartsWith(std::string haystack, std::string needle);
|
bool StartsWith(std::string haystack, std::string needle);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user