#include "ZoneCreatorT6.h" #include #include "ObjLoading.h" #include "Game/T6/CommonT6.h" #include "Game/T6/T6.h" #include "Game/T6/GameT6.h" #include "Game/T6/GameAssetPoolT6.h" using namespace T6; ZoneCreator::ZoneCreator() { for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++) { AddAssetTypeName(assetType, GameAssetPoolT6::AssetTypeNameByType(assetType)); } } void ZoneCreator::AddAssetTypeName(asset_type_t assetType, std::string name) { m_asset_types_by_name.emplace(std::make_pair(std::move(name), assetType)); } std::vector ZoneCreator::CreateGdtList(ZoneCreationContext& context) { std::vector gdtList; gdtList.reserve(context.m_gdt_files.size()); for (const auto& gdt : context.m_gdt_files) gdtList.push_back(gdt.get()); return gdtList; } bool ZoneCreator::CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const { for (const auto& ignoreEntry : context.m_ignored_assets) { const auto foundAssetTypeEntry = m_asset_types_by_name.find(ignoreEntry.m_type); if (foundAssetTypeEntry == m_asset_types_by_name.end()) { std::cout << "Unknown asset type \"" << ignoreEntry.m_type << "\" for ignore \"" << ignoreEntry.m_name << "\"" << std::endl; return false; } ignoredAssetMap[ignoreEntry.m_name] = foundAssetTypeEntry->second; } return true; } void ZoneCreator::CreateZoneAssetPools(Zone* zone) const { zone->m_pools = std::make_unique(zone, zone->m_priority); for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++) zone->m_pools->InitPoolDynamic(assetType); } void ZoneCreator::HandleMetadata(Zone* zone, ZoneCreationContext& context) const { std::vector kvpList; for (const auto& metaData : context.m_definition->m_metadata) { if (metaData->m_key.rfind("level.", 0) == 0) { const std::string strValue = metaData->m_key.substr(std::char_traits::length("level.")); if (strValue.empty()) continue; int keyHash; if (strValue[0] == '@') { char* endPtr; keyHash = strtol(&strValue[1], &endPtr, 16); if (endPtr != &strValue[strValue.size()]) { std::cout << "Could not parse metadata key \"" << metaData->m_key << "\" as hash" << std::endl; continue; } } else { keyHash = Common::Com_HashKey(strValue.c_str(), 64); } KeyValuePair kvp { keyHash, Common::Com_HashKey(zone->m_name.c_str(), 64), zone->GetMemory()->Dup(metaData->m_value.c_str()) }; kvpList.push_back(kvp); } } if (!kvpList.empty()) { auto* kvps = zone->GetMemory()->Create(); kvps->name = zone->GetMemory()->Dup(zone->m_name.c_str()); kvps->numVariables = kvpList.size(); kvps->keyValuePairs = static_cast(zone->GetMemory()->Alloc(sizeof(KeyValuePair) * kvpList.size())); for (auto i = 0u; i < kvpList.size(); i++) kvps->keyValuePairs[i] = kvpList[i]; zone->m_pools->AddAsset(ASSET_TYPE_KEYVALUEPAIRS, zone->m_name, kvps, std::vector(), std::vector()); } } bool ZoneCreator::SupportsGame(const std::string& gameName) const { return gameName == g_GameT6.GetShortName(); } std::unique_ptr ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const { auto zone = std::make_unique(context.m_definition->m_name, 0, &g_GameT6); CreateZoneAssetPools(zone.get()); for (const auto& assetEntry : context.m_definition->m_assets) { if (!assetEntry.m_is_reference) continue; context.m_ignored_assets.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name); } const auto assetLoadingContext = std::make_unique(zone.get(), context.m_asset_search_path, CreateGdtList(context)); if (!CreateIgnoredAssetMap(context, assetLoadingContext->m_ignored_asset_map)) return nullptr; HandleMetadata(zone.get(), context); for (const auto& assetEntry : context.m_definition->m_assets) { const auto foundAssetTypeEntry = m_asset_types_by_name.find(assetEntry.m_asset_type); if (foundAssetTypeEntry == m_asset_types_by_name.end()) { std::cout << "Unknown asset type \"" << assetEntry.m_asset_type << "\"" << std::endl; return nullptr; } if (!ObjLoading::LoadAssetForZone(assetLoadingContext.get(), foundAssetTypeEntry->second, assetEntry.m_asset_name)) return nullptr; } ObjLoading::FinalizeAssetsForZone(assetLoadingContext.get()); return zone; }