mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-11-24 21:52:06 +00:00
Merge fixup
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#include "AssetCreationContext.h"
|
||||
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
@@ -65,7 +67,7 @@ std::unique_ptr<XAssetInfoGeneric> GenericAssetRegistration::CreateXAssetInfo()
|
||||
AssetCreationContext::AssetCreationContext(Zone& zone, const AssetCreatorCollection* creators, const IgnoredAssetLookup* ignoredAssetLookup)
|
||||
: ZoneAssetCreationStateContainer(zone),
|
||||
m_zone(zone),
|
||||
m_forced_asset_pools(ZoneAssetPools::CreateForGame(zone.m_game->GetId(), &zone, zone.m_priority)),
|
||||
m_forced_asset_pools(ZoneAssetPools::CreateForGame(zone.m_game_id, &zone, zone.m_priority)),
|
||||
m_creators(creators),
|
||||
m_ignored_asset_lookup(ignoredAssetLookup),
|
||||
m_forced_load_depth(0u)
|
||||
@@ -87,7 +89,7 @@ XAssetInfoGeneric* AssetCreationContext::AddAssetGeneric(GenericAssetRegistratio
|
||||
addedAsset = m_zone.m_pools->AddAsset(std::move(xAssetInfo));
|
||||
|
||||
if (addedAsset == nullptr)
|
||||
std::cerr << std::format("Failed to add asset of type \"{}\" to pool: \"{}\"\n", *m_zone.m_pools->GetAssetTypeName(assetType), pAssetName);
|
||||
con::error("Failed to add asset of type \"{}\" to pool: \"{}\"", *m_zone.m_pools->GetAssetTypeName(assetType), pAssetName);
|
||||
return addedAsset;
|
||||
}
|
||||
|
||||
@@ -97,7 +99,7 @@ XAssetInfoGeneric* AssetCreationContext::LoadDefaultAssetDependency(const asset_
|
||||
if (result.HasTakenAction() && !result.HasFailed())
|
||||
return result.GetAssetInfo();
|
||||
|
||||
std::cerr << std::format("Failed to create default asset of type {}\n", *m_zone.m_pools->GetAssetTypeName(assetType));
|
||||
con::error("Failed to create default asset of type {}", *m_zone.m_pools->GetAssetTypeName(assetType));
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@@ -127,11 +129,11 @@ XAssetInfoGeneric* AssetCreationContext::LoadDependencyGeneric(const asset_type_
|
||||
if (!result.HasFailed())
|
||||
return result.GetAssetInfo();
|
||||
|
||||
std::cerr << std::format("Could not load asset \"{}\" of type \"{}\"\n", assetName, *m_zone.m_pools->GetAssetTypeName(assetType));
|
||||
con::error("Could not load asset \"{}\" of type \"{}\"", assetName, *m_zone.m_pools->GetAssetTypeName(assetType));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << std::format("Missing asset \"{}\" of type \"{}\"\n", assetName, *m_zone.m_pools->GetAssetTypeName(assetType));
|
||||
con::error("Missing asset \"{}\" of type \"{}\"", assetName, *m_zone.m_pools->GetAssetTypeName(assetType));
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@@ -149,7 +151,7 @@ IndirectAssetReference AssetCreationContext::LoadIndirectAssetReferenceGeneric(c
|
||||
const auto result = m_creators->CreateAsset(assetType, assetName, *this);
|
||||
if (!result.HasTakenAction() && !result.HasFailed())
|
||||
{
|
||||
std::cerr << std::format("Could not load indirectly referenced asset \"{}\" of type \"{}\"\n", assetName, *m_zone.m_pools->GetAssetTypeName(assetType));
|
||||
con::warn("Could not load indirectly referenced asset \"{}\" of type \"{}\"", assetName, *m_zone.m_pools->GetAssetTypeName(assetType));
|
||||
}
|
||||
return IndirectAssetReference(assetType, assetName);
|
||||
}
|
||||
@@ -185,11 +187,11 @@ XAssetInfoGeneric* AssetCreationContext::ForceLoadDependencyGeneric(const asset_
|
||||
if (!result.HasFailed())
|
||||
return result.GetAssetInfo();
|
||||
|
||||
std::cerr << std::format("Could not load asset \"{}\" of type \"{}\"\n", assetName, *m_zone.m_pools->GetAssetTypeName(assetType));
|
||||
con::error("Could not load asset \"{}\" of type \"{}\"", assetName, *m_zone.m_pools->GetAssetTypeName(assetType));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << std::format("Missing asset \"{}\" of type \"{}\"\n", assetName, *m_zone.m_pools->GetAssetTypeName(assetType));
|
||||
con::error("Missing asset \"{}\" of type \"{}\"", assetName, *m_zone.m_pools->GetAssetTypeName(assetType));
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
@@ -52,14 +52,15 @@ public:
|
||||
static_assert(std::is_base_of_v<IZoneAssetCreationState, T>, "T must inherit IZoneAssetCreationState");
|
||||
// T must also have a public default constructor
|
||||
|
||||
const auto foundEntry = m_zone_asset_creation_states.find(typeid(T));
|
||||
std::type_index typeId = typeid(T);
|
||||
const auto foundEntry = m_zone_asset_creation_states.find(typeId);
|
||||
if (foundEntry != m_zone_asset_creation_states.end())
|
||||
return *dynamic_cast<T*>(foundEntry->second.get());
|
||||
|
||||
auto newState = std::make_unique<T>();
|
||||
newState->Inject(m_injection);
|
||||
auto* newStatePtr = newState.get();
|
||||
m_zone_asset_creation_states.emplace(std::make_pair<std::type_index, std::unique_ptr<IZoneAssetCreationState>>(typeid(T), std::move(newState)));
|
||||
m_zone_asset_creation_states.emplace(std::move(typeId), std::move(newState));
|
||||
|
||||
return *newStatePtr;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "Image/DdsLoader.h"
|
||||
#include "Image/IwiTypes.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
@@ -40,7 +41,7 @@ namespace
|
||||
const auto texture = dds::LoadDds(*file.m_stream);
|
||||
if (!texture)
|
||||
{
|
||||
std::cerr << std::format("Failed to load dds file for image asset \"{}\"\n", assetName);
|
||||
con::error("Failed to load dds file for image asset \"{}\"", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
@@ -122,10 +123,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW3
|
||||
namespace image
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetImage>> CreateImageLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetImage>> CreateLoaderIW3(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<ImageLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW3
|
||||
} // namespace image
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW3
|
||||
namespace image
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetImage>> CreateImageLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW3
|
||||
std::unique_ptr<AssetCreator<IW3::AssetImage>> CreateLoaderIW3(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace image
|
||||
|
||||
@@ -36,10 +36,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW3
|
||||
namespace localize
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLocalize>> CreateLocalizeLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
std::unique_ptr<AssetCreator<AssetLocalize>> CreateLoaderIW3(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
{
|
||||
return std::make_unique<LocalizeLoader>(memory, searchPath, zone);
|
||||
}
|
||||
} // namespace IW3
|
||||
} // namespace localize
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW3
|
||||
namespace localize
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLocalize>> CreateLocalizeLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
} // namespace IW3
|
||||
std::unique_ptr<AssetCreator<IW3::AssetLocalize>> CreateLoaderIW3(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
} // namespace localize
|
||||
|
||||
55
src/ObjLoading/Game/IW3/Material/LoaderMaterialIW3.cpp
Normal file
55
src/ObjLoading/Game/IW3/Material/LoaderMaterialIW3.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#include "LoaderMaterialIW3.h"
|
||||
|
||||
#include "Game/IW3/IW3.h"
|
||||
#include "Game/IW3/Material/JsonMaterialLoaderIW3.h"
|
||||
#include "Material/MaterialCommon.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW3;
|
||||
|
||||
namespace
|
||||
{
|
||||
class MaterialLoader final : public AssetCreator<AssetMaterial>
|
||||
{
|
||||
public:
|
||||
MaterialLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
: m_memory(memory),
|
||||
m_search_path(searchPath)
|
||||
{
|
||||
}
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto file = m_search_path.Open(material::GetFileNameForAssetName(assetName));
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
auto* material = m_memory.Alloc<Material>();
|
||||
material->info.name = m_memory.Dup(assetName.c_str());
|
||||
|
||||
AssetRegistration<AssetMaterial> registration(assetName, material);
|
||||
if (!LoadMaterialAsJson(*file.m_stream, *material, m_memory, context, registration))
|
||||
{
|
||||
con::error("Failed to load material \"{}\"", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryManager& m_memory;
|
||||
ISearchPath& m_search_path;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace material
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMaterial>> CreateLoaderIW3(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<MaterialLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace material
|
||||
12
src/ObjLoading/Game/IW3/Material/LoaderMaterialIW3.h
Normal file
12
src/ObjLoading/Game/IW3/Material/LoaderMaterialIW3.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/IW3/IW3.h"
|
||||
#include "Gdt/IGdtQueryable.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
namespace material
|
||||
{
|
||||
std::unique_ptr<AssetCreator<IW3::AssetMaterial>> CreateLoaderIW3(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace material
|
||||
@@ -3,8 +3,10 @@
|
||||
#include "Asset/GlobalAssetPoolsLoader.h"
|
||||
#include "Game/IW3/GameIW3.h"
|
||||
#include "Game/IW3/IW3.h"
|
||||
#include "Game/IW3/XModel/LoaderXModelIW3.h"
|
||||
#include "Image/AssetLoaderImageIW3.h"
|
||||
#include "Localize/AssetLoaderLocalizeIW3.h"
|
||||
#include "Material/LoaderMaterialIW3.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "RawFile/AssetLoaderRawFileIW3.h"
|
||||
#include "StringTable/AssetLoaderStringTableIW3.h"
|
||||
@@ -89,10 +91,10 @@ namespace
|
||||
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderPhysPreset>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderXAnim>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderXModel>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderMaterial>(memory));
|
||||
collection.AddAssetCreator(xmodel::CreateLoaderIW3(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(material::CreateLoaderIW3(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderTechniqueSet>(memory));
|
||||
collection.AddAssetCreator(CreateImageLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(image::CreateLoaderIW3(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderSound>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderSoundCurve>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderLoadedSound>(memory));
|
||||
@@ -106,13 +108,13 @@ namespace
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderFont>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderMenuList>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderMenu>(memory));
|
||||
collection.AddAssetCreator(CreateLocalizeLoader(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(localize::CreateLoaderIW3(memory, searchPath, zone));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderWeapon>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderSoundDriverGlobals>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderFx>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderImpactFx>(memory));
|
||||
collection.AddAssetCreator(CreateRawFileLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(CreateStringTableLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(raw_file::CreateLoaderIW3(memory, searchPath));
|
||||
collection.AddAssetCreator(string_table::CreateLoaderIW3(memory, searchPath));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -44,10 +44,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW3
|
||||
namespace raw_file
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetRawFile>> CreateRawFileLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetRawFile>> CreateLoaderIW3(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<RawFileLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW3
|
||||
} // namespace raw_file
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW3
|
||||
namespace raw_file
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetRawFile>> CreateRawFileLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW3
|
||||
std::unique_ptr<AssetCreator<IW3::AssetRawFile>> CreateLoaderIW3(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace raw_file
|
||||
|
||||
@@ -38,10 +38,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW3
|
||||
namespace string_table
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetStringTable>> CreateStringTableLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetStringTable>> CreateLoaderIW3(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<StringTableLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW3
|
||||
} // namespace string_table
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW3
|
||||
namespace string_table
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetStringTable>> CreateStringTableLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW3
|
||||
std::unique_ptr<AssetCreator<IW3::AssetStringTable>> CreateLoaderIW3(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace string_table
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "InfoStringToStructConverter.h"
|
||||
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
@@ -63,7 +65,7 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
|
||||
if (fx == nullptr)
|
||||
{
|
||||
std::cerr << std::format("Failed to load fx asset \"{}\"\n", value);
|
||||
con::error("Failed to load fx asset \"{}\"", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -85,7 +87,7 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
|
||||
if (xmodel == nullptr)
|
||||
{
|
||||
std::cerr << std::format("Failed to load xmodel asset \"{}\"\n", value);
|
||||
con::error("Failed to load xmodel asset \"{}\"", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -107,7 +109,7 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
|
||||
if (material == nullptr)
|
||||
{
|
||||
std::cerr << std::format("Failed to load material asset \"{}\"\n", value);
|
||||
con::error("Failed to load material asset \"{}\"", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -129,7 +131,7 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
|
||||
if (tracer == nullptr)
|
||||
{
|
||||
std::cerr << std::format("Failed to load tracer asset \"{}\"\n", value);
|
||||
con::error("Failed to load tracer asset \"{}\"", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -146,7 +148,7 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
|
||||
if (endPtr != &value[value.size()])
|
||||
{
|
||||
std::cerr << std::format("Failed to parse value \"{}\" as mph\n", value);
|
||||
con::error("Failed to parse value \"{}\" as mph", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -165,7 +167,7 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
|
||||
if (collmap == nullptr)
|
||||
{
|
||||
std::cerr << std::format("Failed to load collmap asset \"{}\"\n", value);
|
||||
con::error("Failed to load collmap asset \"{}\"", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
#include "JsonLeaderboardDefLoader.h"
|
||||
|
||||
#include "Game/IW4/CommonIW4.h"
|
||||
#include "Game/IW4/Leaderboard/JsonLeaderboardDef.h"
|
||||
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using namespace nlohmann;
|
||||
using namespace IW4;
|
||||
|
||||
namespace
|
||||
{
|
||||
class JsonLoader
|
||||
{
|
||||
public:
|
||||
JsonLoader(std::istream& stream, MemoryManager& memory)
|
||||
: m_stream(stream),
|
||||
m_memory(memory)
|
||||
{
|
||||
}
|
||||
|
||||
bool Load(LeaderboardDef& leaderboardDef) const
|
||||
{
|
||||
const auto jRoot = json::parse(m_stream);
|
||||
std::string type;
|
||||
unsigned version;
|
||||
|
||||
jRoot.at("_type").get_to(type);
|
||||
jRoot.at("_version").get_to(version);
|
||||
|
||||
if (type != "leaderboard" || version != 1u)
|
||||
{
|
||||
std::cerr << std::format("Tried to load leaderboard \"{}\" but did not find expected type leaderboard of version 1\n", leaderboardDef.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
const auto jLeaderboard = jRoot.get<JsonLeaderboardDef>();
|
||||
return CreateLeaderboardFromJson(jLeaderboard, leaderboardDef);
|
||||
}
|
||||
catch (const json::exception& e)
|
||||
{
|
||||
std::cerr << std::format("Failed to parse json of leaderboard: {}\n", e.what());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
bool CreateColumnDefFromJson(const JsonColumnDef& jColumn, LbColumnDef& lbColumnDef, LeaderboardDef& leaderboardDef) const
|
||||
{
|
||||
lbColumnDef.name = m_memory.Dup(jColumn.name.c_str());
|
||||
|
||||
lbColumnDef.id = jColumn.colId;
|
||||
lbColumnDef.propertyId = jColumn.propertyId.value_or(0);
|
||||
lbColumnDef.hidden = jColumn.hidden.value_or(false);
|
||||
|
||||
if (jColumn.statName)
|
||||
lbColumnDef.statName = m_memory.Dup(jColumn.statName->c_str());
|
||||
else
|
||||
lbColumnDef.statName = nullptr;
|
||||
|
||||
lbColumnDef.type = jColumn.type;
|
||||
|
||||
lbColumnDef.precision = jColumn.precision.value_or(0);
|
||||
lbColumnDef.agg = jColumn.aggregationFunction;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateLeaderboardFromJson(const JsonLeaderboardDef& jLeaderboardDef, LeaderboardDef& leaderboardDef) const
|
||||
{
|
||||
leaderboardDef.id = jLeaderboardDef.id;
|
||||
|
||||
leaderboardDef.xpColId = jLeaderboardDef.xpColId.value_or(-1);
|
||||
leaderboardDef.prestigeColId = jLeaderboardDef.prestigeColId.value_or(-1);
|
||||
|
||||
if (!jLeaderboardDef.columns.empty())
|
||||
{
|
||||
leaderboardDef.columnCount = static_cast<int>(jLeaderboardDef.columns.size());
|
||||
leaderboardDef.columns = m_memory.Alloc<LbColumnDef>(leaderboardDef.columnCount);
|
||||
|
||||
for (auto i = 0; i < leaderboardDef.columnCount; i++)
|
||||
{
|
||||
if (!CreateColumnDefFromJson(jLeaderboardDef.columns[i], leaderboardDef.columns[i], leaderboardDef))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
leaderboardDef.columnCount = 0;
|
||||
leaderboardDef.columns = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::istream& m_stream;
|
||||
MemoryManager& m_memory;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
bool LoadLeaderboardAsJson(std::istream& stream, LeaderboardDef& leaderboard, MemoryManager* memory)
|
||||
{
|
||||
const JsonLoader loader(stream, *memory);
|
||||
|
||||
return loader.Load(leaderboard);
|
||||
}
|
||||
} // namespace IW4
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <istream>
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
bool LoadLeaderboardAsJson(std::istream& stream, LeaderboardDef& leaderboard, MemoryManager* memory);
|
||||
} // namespace IW4
|
||||
@@ -1,16 +1,110 @@
|
||||
#include "LoaderLeaderboardIW4.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "JsonLeaderboardDefLoader.h"
|
||||
#include "Game/IW4/Leaderboard/JsonLeaderboardDef.h"
|
||||
#include "Leaderboard/LeaderboardCommon.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using namespace nlohmann;
|
||||
using namespace IW4;
|
||||
|
||||
namespace
|
||||
{
|
||||
class JsonLoader
|
||||
{
|
||||
public:
|
||||
JsonLoader(std::istream& stream, MemoryManager& memory)
|
||||
: m_stream(stream),
|
||||
m_memory(memory)
|
||||
{
|
||||
}
|
||||
|
||||
bool Load(LeaderboardDef& leaderboardDef) const
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto jRoot = json::parse(m_stream);
|
||||
std::string type;
|
||||
unsigned version;
|
||||
|
||||
jRoot.at("_type").get_to(type);
|
||||
jRoot.at("_version").get_to(version);
|
||||
|
||||
if (type != "leaderboard" || version != 1u)
|
||||
{
|
||||
con::error("Tried to load leaderboard \"{}\" but did not find expected type leaderboard of version 1", leaderboardDef.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto jLeaderboard = jRoot.get<JsonLeaderboardDef>();
|
||||
return CreateLeaderboardFromJson(jLeaderboard, leaderboardDef);
|
||||
}
|
||||
catch (const json::exception& e)
|
||||
{
|
||||
con::error("Failed to parse json of leaderboard: {}", e.what());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
bool CreateColumnDefFromJson(const JsonColumnDef& jColumn, LbColumnDef& lbColumnDef, LeaderboardDef& leaderboardDef) const
|
||||
{
|
||||
lbColumnDef.name = m_memory.Dup(jColumn.name.c_str());
|
||||
|
||||
lbColumnDef.id = jColumn.colId;
|
||||
lbColumnDef.propertyId = jColumn.propertyId.value_or(0);
|
||||
lbColumnDef.hidden = jColumn.hidden.value_or(false);
|
||||
|
||||
if (jColumn.statName)
|
||||
lbColumnDef.statName = m_memory.Dup(jColumn.statName->c_str());
|
||||
else
|
||||
lbColumnDef.statName = nullptr;
|
||||
|
||||
lbColumnDef.type = jColumn.type;
|
||||
|
||||
lbColumnDef.precision = jColumn.precision.value_or(0);
|
||||
lbColumnDef.agg = jColumn.aggregationFunction;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateLeaderboardFromJson(const JsonLeaderboardDef& jLeaderboardDef, LeaderboardDef& leaderboardDef) const
|
||||
{
|
||||
leaderboardDef.id = jLeaderboardDef.id;
|
||||
|
||||
leaderboardDef.xpColId = jLeaderboardDef.xpColId.value_or(-1);
|
||||
leaderboardDef.prestigeColId = jLeaderboardDef.prestigeColId.value_or(-1);
|
||||
|
||||
if (!jLeaderboardDef.columns.empty())
|
||||
{
|
||||
leaderboardDef.columnCount = static_cast<int>(jLeaderboardDef.columns.size());
|
||||
leaderboardDef.columns = m_memory.Alloc<LbColumnDef>(leaderboardDef.columnCount);
|
||||
|
||||
for (auto i = 0; i < leaderboardDef.columnCount; i++)
|
||||
{
|
||||
if (!CreateColumnDefFromJson(jLeaderboardDef.columns[i], leaderboardDef.columns[i], leaderboardDef))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
leaderboardDef.columnCount = 0;
|
||||
leaderboardDef.columns = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::istream& m_stream;
|
||||
MemoryManager& m_memory;
|
||||
};
|
||||
|
||||
class LeaderboardLoader final : public AssetCreator<AssetLeaderboard>
|
||||
{
|
||||
public:
|
||||
@@ -22,16 +116,17 @@ namespace
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto file = m_search_path.Open(std::format("leaderboards/{}.json", assetName));
|
||||
const auto file = m_search_path.Open(leaderboard::GetJsonFileNameForAsset(assetName));
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
auto* leaderboardDef = m_memory.Alloc<LeaderboardDef>();
|
||||
leaderboardDef->name = m_memory.Dup(assetName.c_str());
|
||||
|
||||
if (!LoadLeaderboardAsJson(*file.m_stream, *leaderboardDef, &m_memory))
|
||||
const JsonLoader loader(*file.m_stream, m_memory);
|
||||
if (!loader.Load(*leaderboardDef))
|
||||
{
|
||||
std::cerr << std::format("Failed to load leaderboard \"{}\"\n", assetName);
|
||||
con::error("Failed to load leaderboard \"{}\"", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
@@ -44,10 +139,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW4
|
||||
namespace leaderboard
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLeaderboard>> CreateLeaderboardLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetLeaderboard>> CreateLoaderIW4(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<LeaderboardLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW4
|
||||
} // namespace leaderboard
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW4
|
||||
namespace leaderboard
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLeaderboard>> CreateLeaderboardLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW4
|
||||
std::unique_ptr<AssetCreator<IW4::AssetLeaderboard>> CreateLoaderIW4(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace leaderboard
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "LoaderLightDefIW4.h"
|
||||
#include "LightDefLoaderIW4.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "LightDef/LightDefCommon.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
@@ -23,7 +25,7 @@ namespace
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto filename = GetAssetFilename(assetName);
|
||||
const auto filename = light_def::GetFileNameForAsset(assetName);
|
||||
const auto file = m_search_path.Open(filename);
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
@@ -48,7 +50,7 @@ namespace
|
||||
auto* imageDependency = context.LoadDependency<AssetImage>(imageName);
|
||||
if (!imageDependency)
|
||||
{
|
||||
std::cerr << std::format("Could not load GfxLightDef \"{}\" due to missing image \"{}\"\n", assetName, imageName);
|
||||
con::error("Could not load GfxLightDef \"{}\" due to missing image \"{}\"", assetName, imageName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
registration.AddDependency(imageDependency);
|
||||
@@ -61,20 +63,15 @@ namespace
|
||||
}
|
||||
|
||||
private:
|
||||
std::string GetAssetFilename(const std::string& assetName)
|
||||
{
|
||||
return std::format("lights/{}", assetName);
|
||||
}
|
||||
|
||||
MemoryManager& m_memory;
|
||||
ISearchPath& m_search_path;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW4
|
||||
namespace light_def
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLightDef>> CreateLightDefLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetLightDef>> CreateLoaderIW4(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<LoaderLightDef>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW4
|
||||
} // namespace light_def
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW4
|
||||
namespace light_def
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLightDef>> CreateLightDefLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW4
|
||||
std::unique_ptr<AssetCreator<IW4::AssetLightDef>> CreateLoaderIW4(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace light_def
|
||||
@@ -35,10 +35,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW4
|
||||
namespace localize
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLocalize>> CreateLocalizeLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
std::unique_ptr<AssetCreator<AssetLocalize>> CreateLoaderIW4(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
{
|
||||
return std::make_unique<LocalizeLoader>(memory, searchPath, zone);
|
||||
}
|
||||
} // namespace IW4
|
||||
} // namespace localize
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW4
|
||||
namespace localize
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLocalize>> CreateLocalizeLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
} // namespace IW4
|
||||
std::unique_ptr<AssetCreator<IW4::AssetLocalize>> CreateLoaderIW4(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
} // namespace localize
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Game/IW4/Material/JsonMaterialLoaderIW4.h"
|
||||
#include "Material/MaterialCommon.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
@@ -32,7 +33,7 @@ namespace
|
||||
AssetRegistration<AssetMaterial> registration(assetName, material);
|
||||
if (!LoadMaterialAsJson(*file.m_stream, *material, m_memory, context, registration))
|
||||
{
|
||||
std::cerr << std::format("Failed to load material \"{}\"\n", assetName);
|
||||
con::error("Failed to load material \"{}\"", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
@@ -45,10 +46,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW4
|
||||
namespace material
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMaterial>> CreateMaterialLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetMaterial>> CreateLoaderIW4(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<MaterialLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW4
|
||||
} // namespace material
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
namespace IW4
|
||||
namespace material
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMaterial>> CreateMaterialLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW4
|
||||
std::unique_ptr<AssetCreator<IW4::AssetMaterial>> CreateLoaderIW4(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace material
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Game/IW4/Menu/MenuConverterIW4.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Parsing/Menu/MenuFileReader.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
@@ -88,7 +89,7 @@ namespace
|
||||
const auto alreadyLoadedMenuFile = conversionState.m_menus_by_filename.find(menuFilePath);
|
||||
if (alreadyLoadedMenuFile != conversionState.m_menus_by_filename.end())
|
||||
{
|
||||
std::cout << std::format("Already loaded \"{}\", skipping\n", menuFilePath);
|
||||
con::debug("Already loaded \"{}\", skipping", menuFilePath);
|
||||
for (auto* menu : alreadyLoadedMenuFile->second)
|
||||
{
|
||||
menus.emplace_back(menu->Asset());
|
||||
@@ -100,7 +101,7 @@ namespace
|
||||
const auto file = m_search_path.Open(menuFilePath);
|
||||
if (!file.IsOpen())
|
||||
{
|
||||
std::cerr << std::format("Could not open menu file \"{}\"\n", menuFilePath);
|
||||
con::error("Could not open menu file \"{}\"", menuFilePath);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -109,12 +110,12 @@ namespace
|
||||
{
|
||||
ProcessParsedResults(menuFilePath, context, *menuFileResult, zoneState, conversionState, menus, registration);
|
||||
if (!menuFileResult->m_menus_to_load.empty())
|
||||
std::cout << std::format("WARNING: Menu file has menus to load even though it is not a menu list, ignoring: \"{}\"\n", menuFilePath);
|
||||
con::warn("Menu file has menus to load even though it is not a menu list, ignoring: \"{}\"", menuFilePath);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
std::cerr << std::format("Could not read menu file \"{}\"\n", menuFilePath);
|
||||
con::error("Could not read menu file \"{}\"", menuFilePath);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -134,12 +135,12 @@ namespace
|
||||
for (const auto& menu : parsingResult.m_menus)
|
||||
totalItemCount += menu->m_items.size();
|
||||
|
||||
std::cout << std::format("Successfully read menu file \"{}\" ({} loads, {} menus, {} functions, {} items)\n",
|
||||
fileName,
|
||||
menuLoadCount,
|
||||
menuCount,
|
||||
functionCount,
|
||||
totalItemCount);
|
||||
con::info("Successfully read menu file \"{}\" ({} loads, {} menus, {} functions, {} items)",
|
||||
fileName,
|
||||
menuLoadCount,
|
||||
menuCount,
|
||||
functionCount,
|
||||
totalItemCount);
|
||||
|
||||
// Add all functions to the zone state to make them available for all menus to be converted
|
||||
for (auto& function : parsingResult.m_functions)
|
||||
@@ -160,7 +161,7 @@ namespace
|
||||
converter->ConvertMenu(*commonMenu, *menuAsset, menuRegistration);
|
||||
if (menuAsset == nullptr)
|
||||
{
|
||||
std::cerr << std::format("Failed to convert menu file \"{}\"\n", commonMenu->m_name);
|
||||
con::error("Failed to convert menu file \"{}\"", commonMenu->m_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -212,10 +213,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW4
|
||||
namespace menu
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMenuList>> CreateMenuListLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetMenuList>> CreateMenuListLoaderIW4(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<MenuListLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW4
|
||||
} // namespace menu
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW4
|
||||
namespace menu
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMenuList>> CreateMenuListLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW4
|
||||
std::unique_ptr<AssetCreator<IW4::AssetMenuList>> CreateMenuListLoaderIW4(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace menu
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
#include "Asset/GlobalAssetPoolsLoader.h"
|
||||
#include "Game/IW4/GameIW4.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Game/IW4/XModel/LoaderXModelIW4.h"
|
||||
#include "Leaderboard/LoaderLeaderboardIW4.h"
|
||||
#include "LightDef/LoaderLightDefIW4.h"
|
||||
#include "LightDef/LightDefLoaderIW4.h"
|
||||
#include "Localize/LoaderLocalizeIW4.h"
|
||||
#include "Material/LoaderMaterialIW4.h"
|
||||
#include "Menu/LoaderMenuListIW4.h"
|
||||
@@ -118,19 +119,19 @@ namespace
|
||||
{
|
||||
auto& memory = zone.Memory();
|
||||
|
||||
collection.AddAssetCreator(std::make_unique<RawLoaderPhysPreset>(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(std::make_unique<GdtLoaderPhysPreset>(memory, gdt, zone));
|
||||
collection.AddAssetCreator(phys_preset::CreateRawLoaderIW4(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(phys_preset::CreateGdtLoaderIW4(memory, gdt, zone));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderPhysCollMap>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderXAnim>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderXModelSurfs>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderXModel>(memory));
|
||||
collection.AddAssetCreator(CreateMaterialLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(CreatePixelShaderLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(CreateVertexShaderLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(xmodel::CreateLoaderIW4(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(material::CreateLoaderIW4(memory, searchPath));
|
||||
collection.AddAssetCreator(shader::CreatePixelShaderLoaderIW4(memory, searchPath));
|
||||
collection.AddAssetCreator(shader::CreateVertexShaderLoaderIW4(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderTechset>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderImage>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderSound>(memory));
|
||||
collection.AddAssetCreator(CreateSoundCurveLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(sound_curve::CreateLoaderIW4(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderLoadedSound>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderClipMap>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderComWorld>(memory));
|
||||
@@ -139,19 +140,19 @@ namespace
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderMapEnts>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderFxWorld>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderGfxWorld>(memory));
|
||||
collection.AddAssetCreator(CreateLightDefLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(light_def::CreateLoaderIW4(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderFont>(memory));
|
||||
collection.AddAssetCreator(CreateMenuListLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(menu::CreateMenuListLoaderIW4(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderMenu>(memory));
|
||||
collection.AddAssetCreator(CreateLocalizeLoader(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(CreateRawWeaponLoader(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(CreateGdtWeaponLoader(memory, searchPath, gdt, zone));
|
||||
collection.AddAssetCreator(localize::CreateLoaderIW4(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(weapon::CreateRawLoaderIW4(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(weapon::CreateGdtLoaderIW4(memory, searchPath, gdt, zone));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderFx>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderImpactFx>(memory));
|
||||
collection.AddAssetCreator(CreateRawFileLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(CreateStringTableLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(CreateLeaderboardLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(CreateStructuredDataDefLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(raw_file::CreateLoaderIW4(memory, searchPath));
|
||||
collection.AddAssetCreator(string_table::CreateLoaderIW4(memory, searchPath));
|
||||
collection.AddAssetCreator(leaderboard::CreateLoaderIW4(memory, searchPath));
|
||||
collection.AddAssetCreator(structured_data_def::CreateLoaderIW4(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderTracer>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderVehicle>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderAddonMapEnts>(memory));
|
||||
|
||||
@@ -4,32 +4,50 @@
|
||||
#include "Game/IW4/ObjConstantsIW4.h"
|
||||
#include "InfoString/InfoString.h"
|
||||
#include "InfoStringLoaderPhysPresetIW4.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
GdtLoaderPhysPreset::GdtLoaderPhysPreset(MemoryManager& memory, IGdtQueryable& gdt, Zone& zone)
|
||||
: m_memory(memory),
|
||||
m_gdt(gdt),
|
||||
m_zone(zone)
|
||||
namespace
|
||||
{
|
||||
}
|
||||
|
||||
AssetCreationResult GdtLoaderPhysPreset::CreateAsset(const std::string& assetName, AssetCreationContext& context)
|
||||
{
|
||||
auto* gdtEntry = m_gdt.GetGdtEntryByGdfAndName(ObjConstants::GDF_FILENAME_PHYS_PRESET, assetName);
|
||||
if (gdtEntry == nullptr)
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
InfoString infoString;
|
||||
if (!infoString.FromGdtProperties(*gdtEntry))
|
||||
class GdtLoaderPhysPreset final : public AssetCreator<AssetPhysPreset>
|
||||
{
|
||||
std::cerr << std::format("Failed to read phys preset gdt entry: \"{}\"\n", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
public:
|
||||
GdtLoaderPhysPreset(MemoryManager& memory, IGdtQueryable& gdt, Zone& zone)
|
||||
: m_gdt(gdt),
|
||||
m_info_string_loader(memory, zone)
|
||||
{
|
||||
}
|
||||
|
||||
InfoStringLoaderPhysPreset infoStringLoader(m_memory, m_zone);
|
||||
return infoStringLoader.CreateAsset(assetName, infoString, context);
|
||||
}
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto* gdtEntry = m_gdt.GetGdtEntryByGdfAndName(ObjConstants::GDF_FILENAME_PHYS_PRESET, assetName);
|
||||
if (gdtEntry == nullptr)
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
InfoString infoString;
|
||||
if (!infoString.FromGdtProperties(*gdtEntry))
|
||||
{
|
||||
con::error("Failed to read phys preset gdt entry: \"{}\"", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
return m_info_string_loader.CreateAsset(assetName, infoString, context);
|
||||
}
|
||||
|
||||
private:
|
||||
IGdtQueryable& m_gdt;
|
||||
phys_preset::InfoStringLoaderIW4 m_info_string_loader;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace phys_preset
|
||||
{
|
||||
std::unique_ptr<AssetCreator<IW4::AssetPhysPreset>> CreateGdtLoaderIW4(MemoryManager& memory, IGdtQueryable& gdt, Zone& zone)
|
||||
{
|
||||
return std::make_unique<GdtLoaderPhysPreset>(memory, gdt, zone);
|
||||
}
|
||||
} // namespace phys_preset
|
||||
|
||||
@@ -3,20 +3,12 @@
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Gdt/IGdtQueryable.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
namespace IW4
|
||||
#include <memory>
|
||||
|
||||
namespace phys_preset
|
||||
{
|
||||
class GdtLoaderPhysPreset final : public AssetCreator<AssetPhysPreset>
|
||||
{
|
||||
public:
|
||||
GdtLoaderPhysPreset(MemoryManager& memory, IGdtQueryable& gdt, Zone& zone);
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override;
|
||||
|
||||
private:
|
||||
MemoryManager& m_memory;
|
||||
IGdtQueryable& m_gdt;
|
||||
Zone& m_zone;
|
||||
};
|
||||
} // namespace IW4
|
||||
std::unique_ptr<AssetCreator<IW4::AssetPhysPreset>> CreateGdtLoaderIW4(MemoryManager& memory, IGdtQueryable& gdt, Zone& zone);
|
||||
} // namespace phys_preset
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Game/IW4/InfoString/InfoStringToStructConverter.h"
|
||||
#include "Game/IW4/PhysPreset/PhysPresetFields.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
@@ -58,30 +59,33 @@ namespace
|
||||
}
|
||||
} // namespace
|
||||
|
||||
InfoStringLoaderPhysPreset::InfoStringLoaderPhysPreset(MemoryManager& memory, Zone& zone)
|
||||
: m_memory(memory),
|
||||
m_zone(zone)
|
||||
namespace phys_preset
|
||||
{
|
||||
}
|
||||
|
||||
AssetCreationResult InfoStringLoaderPhysPreset::CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context)
|
||||
{
|
||||
PhysPresetInfo presetInfo;
|
||||
std::memset(&presetInfo, 0, sizeof(presetInfo));
|
||||
|
||||
auto* physPreset = m_memory.Alloc<PhysPreset>();
|
||||
AssetRegistration<AssetPhysPreset> registration(assetName, physPreset);
|
||||
|
||||
InfoStringToPhysPresetConverter converter(
|
||||
infoString, &presetInfo, m_zone.m_script_strings, m_memory, context, registration, phys_preset_fields, std::extent_v<decltype(phys_preset_fields)>);
|
||||
if (!converter.Convert())
|
||||
InfoStringLoaderIW4::InfoStringLoaderIW4(MemoryManager& memory, Zone& zone)
|
||||
: m_memory(memory),
|
||||
m_zone(zone)
|
||||
{
|
||||
std::cerr << std::format("Failed to parse phys preset: \"{}\"\n", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
CopyFromPhysPresetInfo(presetInfo, *physPreset);
|
||||
physPreset->name = m_memory.Dup(assetName.c_str());
|
||||
AssetCreationResult InfoStringLoaderIW4::CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context)
|
||||
{
|
||||
PhysPresetInfo presetInfo;
|
||||
std::memset(&presetInfo, 0, sizeof(presetInfo));
|
||||
|
||||
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||
}
|
||||
auto* physPreset = m_memory.Alloc<PhysPreset>();
|
||||
AssetRegistration<AssetPhysPreset> registration(assetName, physPreset);
|
||||
|
||||
InfoStringToPhysPresetConverter converter(
|
||||
infoString, &presetInfo, m_zone.m_script_strings, m_memory, context, registration, phys_preset_fields, std::extent_v<decltype(phys_preset_fields)>);
|
||||
if (!converter.Convert())
|
||||
{
|
||||
con::error("Failed to parse phys preset: \"{}\"", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
CopyFromPhysPresetInfo(presetInfo, *physPreset);
|
||||
physPreset->name = m_memory.Dup(assetName.c_str());
|
||||
|
||||
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||
}
|
||||
} // namespace phys_preset
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
#include "Asset/AssetCreationResult.h"
|
||||
#include "InfoString/InfoString.h"
|
||||
|
||||
namespace IW4
|
||||
namespace phys_preset
|
||||
{
|
||||
class InfoStringLoaderPhysPreset
|
||||
class InfoStringLoaderIW4
|
||||
{
|
||||
public:
|
||||
InfoStringLoaderPhysPreset(MemoryManager& memory, Zone& zone);
|
||||
InfoStringLoaderIW4(MemoryManager& memory, Zone& zone);
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context);
|
||||
|
||||
@@ -17,4 +17,4 @@ namespace IW4
|
||||
MemoryManager& m_memory;
|
||||
Zone& m_zone;
|
||||
};
|
||||
} // namespace IW4
|
||||
} // namespace phys_preset
|
||||
|
||||
@@ -4,33 +4,52 @@
|
||||
#include "Game/IW4/ObjConstantsIW4.h"
|
||||
#include "InfoString/InfoString.h"
|
||||
#include "InfoStringLoaderPhysPresetIW4.h"
|
||||
#include "PhysPreset/PhysPresetCommon.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
RawLoaderPhysPreset::RawLoaderPhysPreset(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
: m_memory(memory),
|
||||
m_search_path(searchPath),
|
||||
m_zone(zone)
|
||||
namespace
|
||||
{
|
||||
}
|
||||
|
||||
AssetCreationResult RawLoaderPhysPreset::CreateAsset(const std::string& assetName, AssetCreationContext& context)
|
||||
{
|
||||
const auto fileName = std::format("physic/{}", assetName);
|
||||
const auto file = m_search_path.Open(fileName);
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
InfoString infoString;
|
||||
if (!infoString.FromStream(ObjConstants::INFO_STRING_PREFIX_PHYS_PRESET, *file.m_stream))
|
||||
class RawLoaderPhysPreset final : public AssetCreator<AssetPhysPreset>
|
||||
{
|
||||
std::cerr << std::format("Could not parse as info string file: \"{}\"\n", fileName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
public:
|
||||
RawLoaderPhysPreset(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
: m_search_path(searchPath),
|
||||
m_info_string_loader(memory, zone)
|
||||
{
|
||||
}
|
||||
|
||||
InfoStringLoaderPhysPreset infoStringLoader(m_memory, m_zone);
|
||||
return infoStringLoader.CreateAsset(assetName, infoString, context);
|
||||
}
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto fileName = phys_preset::GetFileNameForAssetName(assetName);
|
||||
const auto file = m_search_path.Open(fileName);
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
InfoString infoString;
|
||||
if (!infoString.FromStream(ObjConstants::INFO_STRING_PREFIX_PHYS_PRESET, *file.m_stream))
|
||||
{
|
||||
con::error("Could not parse as info string file: \"{}\"", fileName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
return m_info_string_loader.CreateAsset(assetName, infoString, context);
|
||||
}
|
||||
|
||||
private:
|
||||
ISearchPath& m_search_path;
|
||||
phys_preset::InfoStringLoaderIW4 m_info_string_loader;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace phys_preset
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetPhysPreset>> CreateRawLoaderIW4(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
{
|
||||
return std::make_unique<RawLoaderPhysPreset>(memory, searchPath, zone);
|
||||
}
|
||||
} // namespace phys_preset
|
||||
|
||||
@@ -5,18 +5,9 @@
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
namespace IW4
|
||||
#include <memory>
|
||||
|
||||
namespace phys_preset
|
||||
{
|
||||
class RawLoaderPhysPreset final : public AssetCreator<AssetPhysPreset>
|
||||
{
|
||||
public:
|
||||
RawLoaderPhysPreset(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override;
|
||||
|
||||
private:
|
||||
MemoryManager& m_memory;
|
||||
ISearchPath& m_search_path;
|
||||
Zone& m_zone;
|
||||
};
|
||||
} // namespace IW4
|
||||
std::unique_ptr<AssetCreator<IW4::AssetPhysPreset>> CreateRawLoaderIW4(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
} // namespace phys_preset
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "LoaderRawFileIW4.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
@@ -58,7 +59,7 @@ namespace
|
||||
|
||||
if (ret != Z_STREAM_END)
|
||||
{
|
||||
std::cerr << std::format("Deflate failed for loading rawfile \"{}\"\n", assetName);
|
||||
con::error("Deflate failed for loading rawfile \"{}\"", assetName);
|
||||
deflateEnd(&zs);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
@@ -82,10 +83,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW4
|
||||
namespace raw_file
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetRawFile>> CreateRawFileLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetRawFile>> CreateLoaderIW4(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<RawFileLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW4
|
||||
} // namespace raw_file
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW4
|
||||
namespace raw_file
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetRawFile>> CreateRawFileLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW4
|
||||
std::unique_ptr<AssetCreator<IW4::AssetRawFile>> CreateLoaderIW4(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace raw_file
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "LoaderPixelShaderIW4.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Shader/ShaderCommon.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <format>
|
||||
@@ -21,14 +23,14 @@ namespace
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto fileName = GetPixelShaderFileName(assetName);
|
||||
const auto fileName = shader::GetFileNameForPixelShaderAssetName(assetName);
|
||||
const auto file = m_search_path.Open(fileName);
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
if (file.m_length % sizeof(uint32_t) != 0)
|
||||
{
|
||||
std::cerr << std::format("Invalid pixel shader \"{}\": Size must be dividable by {}\n", assetName, sizeof(uint32_t));
|
||||
con::error("Invalid pixel shader \"{}\": Size must be dividable by {}", assetName, sizeof(uint32_t));
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
@@ -53,15 +55,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW4
|
||||
namespace shader
|
||||
{
|
||||
std::string GetPixelShaderFileName(const std::string& pixelShaderAssetName)
|
||||
{
|
||||
return std::format("shader_bin/ps_{}.cso", pixelShaderAssetName);
|
||||
}
|
||||
|
||||
std::unique_ptr<AssetCreator<AssetPixelShader>> CreatePixelShaderLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetPixelShader>> CreatePixelShaderLoaderIW4(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<PixelShaderLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW4
|
||||
} // namespace shader
|
||||
|
||||
@@ -7,9 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW4
|
||||
namespace shader
|
||||
{
|
||||
[[nodiscard]] std::string GetPixelShaderFileName(const std::string& pixelShaderAssetName);
|
||||
|
||||
std::unique_ptr<AssetCreator<AssetPixelShader>> CreatePixelShaderLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW4
|
||||
std::unique_ptr<AssetCreator<IW4::AssetPixelShader>> CreatePixelShaderLoaderIW4(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace shader
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "LoaderVertexShaderIW4.h"
|
||||
|
||||
#include "Game/IW4/IW4.h"
|
||||
#include "Shader/ShaderCommon.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <format>
|
||||
@@ -21,14 +23,14 @@ namespace
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto fileName = GetVertexShaderFileName(assetName);
|
||||
const auto fileName = shader::GetFileNameForVertexShaderAssetName(assetName);
|
||||
const auto file = m_search_path.Open(fileName);
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
if (file.m_length % sizeof(uint32_t) != 0)
|
||||
{
|
||||
std::cerr << std::format("Invalid vertex shader \"{}\": Size must be dividable by {}\n", assetName, sizeof(uint32_t));
|
||||
con::error("Invalid vertex shader \"{}\": Size must be dividable by {}", assetName, sizeof(uint32_t));
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
@@ -53,15 +55,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW4
|
||||
namespace shader
|
||||
{
|
||||
std::string GetVertexShaderFileName(const std::string& vertexShaderAssetName)
|
||||
{
|
||||
return std::format("shader_bin/vs_{}.cso", vertexShaderAssetName);
|
||||
}
|
||||
|
||||
std::unique_ptr<AssetCreator<AssetVertexShader>> CreateVertexShaderLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetVertexShader>> CreateVertexShaderLoaderIW4(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<VertexShaderLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW4
|
||||
} // namespace shader
|
||||
|
||||
@@ -7,9 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW4
|
||||
namespace shader
|
||||
{
|
||||
[[nodiscard]] std::string GetVertexShaderFileName(const std::string& vertexShaderAssetName);
|
||||
|
||||
std::unique_ptr<AssetCreator<AssetVertexShader>> CreateVertexShaderLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW4
|
||||
std::unique_ptr<AssetCreator<IW4::AssetVertexShader>> CreateVertexShaderLoaderIW4(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace shader
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include "ObjLoading.h"
|
||||
#include "Parsing/Graph2D/Graph2DReader.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
#include "Sound/SoundCurveCommon.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
@@ -25,7 +27,7 @@ namespace
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto fileName = std::format("soundaliases/{}.vfcurve", assetName);
|
||||
const auto fileName = sound_curve::GetFileNameForAssetName(assetName);
|
||||
const auto file = m_search_path.Open(fileName);
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
@@ -37,7 +39,7 @@ namespace
|
||||
|
||||
if (sndCurveData->knots.size() > std::extent_v<decltype(SndCurve::knots)>)
|
||||
{
|
||||
std::cerr << std::format("Failed to load SndCurve \"{}\": Too many knots ({})\n", assetName, sndCurveData->knots.size());
|
||||
con::error("Failed to load SndCurve \"{}\": Too many knots ({})", assetName, sndCurveData->knots.size());
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
@@ -69,10 +71,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW4
|
||||
namespace sound_curve
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetSoundCurve>> CreateSoundCurveLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetSoundCurve>> CreateLoaderIW4(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<LoaderSoundCurve>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW4
|
||||
} // namespace sound_curve
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW4
|
||||
namespace sound_curve
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetSoundCurve>> CreateSoundCurveLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW4
|
||||
std::unique_ptr<AssetCreator<IW4::AssetSoundCurve>> CreateLoaderIW4(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace sound_curve
|
||||
|
||||
@@ -38,10 +38,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW4
|
||||
namespace string_table
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetStringTable>> CreateStringTableLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetStringTable>> CreateLoaderIW4(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<LoaderStringTable>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW4
|
||||
} // namespace string_table
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW4
|
||||
namespace string_table
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetStringTable>> CreateStringTableLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW4
|
||||
std::unique_ptr<AssetCreator<IW4::AssetStringTable>> CreateLoaderIW4(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace string_table
|
||||
|
||||
@@ -207,10 +207,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW4
|
||||
namespace structured_data_def
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetStructuredDataDef>> CreateStructuredDataDefLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetStructuredDataDef>> CreateLoaderIW4(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<StructuredDataDefLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW4
|
||||
} // namespace structured_data_def
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW4
|
||||
namespace structured_data_def
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetStructuredDataDef>> CreateStructuredDataDefLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW4
|
||||
std::unique_ptr<AssetCreator<IW4::AssetStructuredDataDef>> CreateLoaderIW4(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace structured_data_def
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "Game/IW4/ObjConstantsIW4.h"
|
||||
#include "InfoString/InfoString.h"
|
||||
#include "InfoStringLoaderWeaponIW4.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
@@ -31,7 +32,7 @@ namespace
|
||||
InfoString infoString;
|
||||
if (!infoString.FromGdtProperties(*gdtEntry))
|
||||
{
|
||||
std::cerr << std::format("Failed to read weapon gdt entry: \"{}\"\n", assetName);
|
||||
con::error("Failed to read weapon gdt entry: \"{}\"", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
@@ -40,14 +41,14 @@ namespace
|
||||
|
||||
private:
|
||||
IGdtQueryable& m_gdt;
|
||||
InfoStringLoaderWeapon m_info_string_loader;
|
||||
weapon::InfoStringLoaderIW4 m_info_string_loader;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW4
|
||||
namespace weapon
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetWeapon>> CreateGdtWeaponLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone)
|
||||
std::unique_ptr<AssetCreator<IW4::AssetWeapon>> CreateGdtLoaderIW4(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone)
|
||||
{
|
||||
return std::make_unique<GdtLoaderWeapon>(memory, searchPath, gdt, zone);
|
||||
}
|
||||
} // namespace IW4
|
||||
} // namespace weapon
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW4
|
||||
namespace weapon
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetWeapon>> CreateGdtWeaponLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone);
|
||||
} // namespace IW4
|
||||
std::unique_ptr<AssetCreator<IW4::AssetWeapon>> CreateGdtLoaderIW4(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone);
|
||||
} // namespace weapon
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "Game/IW4/InfoString/EnumStrings.h"
|
||||
#include "Game/IW4/InfoString/InfoStringToStructConverter.h"
|
||||
#include "Game/IW4/Weapon/WeaponFields.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
#include "Weapon/AccuracyGraphLoader.h"
|
||||
|
||||
#include <cassert>
|
||||
@@ -23,13 +24,13 @@ namespace
|
||||
std::vector<std::string> valueArray;
|
||||
if (!ParseAsArray(value, valueArray))
|
||||
{
|
||||
std::cerr << "Failed to parse hide tags as array\n";
|
||||
con::error("Failed to parse hide tags as array");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (valueArray.size() > std::extent_v<decltype(WeaponFullDef::hideTags)>)
|
||||
{
|
||||
std::cerr << std::format("Cannot have more than {} hide tags!\n", std::extent_v<decltype(WeaponFullDef::hideTags)>);
|
||||
con::error("Cannot have more than {} hide tags!", std::extent_v<decltype(WeaponFullDef::hideTags)>);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -85,14 +86,13 @@ namespace
|
||||
std::vector<std::array<std::string, 2>> pairs;
|
||||
if (!ParseAsArray(value, pairs))
|
||||
{
|
||||
std::cerr << std::format("Failed to parse notetrack{}map as pairs\n", mapName);
|
||||
con::error("Failed to parse notetrack{}map as pairs", mapName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pairs.size() > std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>)
|
||||
{
|
||||
std::cerr << std::format(
|
||||
"Cannot have more than {} notetrack{}map entries!\n", std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>, mapName);
|
||||
con::error("Cannot have more than {} notetrack{}map entries!", std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>, mapName);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -267,28 +267,27 @@ namespace
|
||||
void CheckProjectileValues(const WeaponCompleteDef& weaponCompleteDef, const WeaponDef& weaponDef)
|
||||
{
|
||||
if (weaponDef.iProjectileSpeed <= 0)
|
||||
std::cerr << std::format("Projectile speed for WeapType {} must be greater than 0.0", weaponCompleteDef.szDisplayName);
|
||||
con::error("Projectile speed for WeapType {} must be greater than 0.0", weaponCompleteDef.szDisplayName);
|
||||
if (weaponDef.destabilizationCurvatureMax >= 1000000000.0f || weaponDef.destabilizationCurvatureMax < 0.0f)
|
||||
std::cerr << std::format("Destabilization angle for for WeapType {} must be between 0 and 45 degrees", weaponCompleteDef.szDisplayName);
|
||||
con::error("Destabilization angle for for WeapType {} must be between 0 and 45 degrees", weaponCompleteDef.szDisplayName);
|
||||
if (weaponDef.destabilizationRateTime < 0.0f)
|
||||
std::cerr << std::format("Destabilization rate time for for WeapType {} must be non-negative", weaponCompleteDef.szDisplayName);
|
||||
con::error("Destabilization rate time for for WeapType {} must be non-negative", weaponCompleteDef.szDisplayName);
|
||||
}
|
||||
|
||||
void CheckTurretBarrelSpin(const WeaponCompleteDef& weaponCompleteDef, const WeaponDef& weaponDef)
|
||||
{
|
||||
if (weaponDef.weapClass != WEAPCLASS_TURRET)
|
||||
std::cerr << std::format("Rotating barrel set for non-turret weapon {}.", weaponCompleteDef.szInternalName);
|
||||
con::error("Rotating barrel set for non-turret weapon {}.", weaponCompleteDef.szInternalName);
|
||||
|
||||
if (0.0f == weaponDef.turretBarrelSpinSpeed)
|
||||
{
|
||||
std::cerr << std::format(
|
||||
"Rotating barrel spin speed '{}' is invalid for weapon {}.", weaponDef.turretBarrelSpinSpeed, weaponCompleteDef.szInternalName);
|
||||
con::error("Rotating barrel spin speed '{}' is invalid for weapon {}.", weaponDef.turretBarrelSpinSpeed, weaponCompleteDef.szInternalName);
|
||||
}
|
||||
if (0.0f < weaponDef.turretOverheatUpRate && 0.0f >= weaponDef.turretOverheatDownRate)
|
||||
{
|
||||
std::cerr << std::format("Turret overheat Up rate is set, but the down rate '{}' is invalid for weapon {}.",
|
||||
weaponDef.turretOverheatDownRate,
|
||||
weaponCompleteDef.szInternalName);
|
||||
con::error("Turret overheat Up rate is set, but the down rate '{}' is invalid for weapon {}.",
|
||||
weaponDef.turretOverheatDownRate,
|
||||
weaponCompleteDef.szInternalName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,18 +295,18 @@ namespace
|
||||
{
|
||||
if (0.0f != weaponDef.fAdsZoomInFrac)
|
||||
{
|
||||
std::cerr << std::format("Weapon {} ({}) has thermal scope set. ADS Zoom In frac should be 0 to prevent zoom-in blur ({}).\n",
|
||||
weaponCompleteDef.szInternalName,
|
||||
weaponCompleteDef.szDisplayName,
|
||||
weaponDef.fAdsZoomInFrac);
|
||||
con::error("Weapon {} ({}) has thermal scope set. ADS Zoom In frac should be 0 to prevent zoom-in blur ({}).",
|
||||
weaponCompleteDef.szInternalName,
|
||||
weaponCompleteDef.szDisplayName,
|
||||
weaponDef.fAdsZoomInFrac);
|
||||
}
|
||||
|
||||
if (0.0f != weaponDef.fAdsZoomOutFrac)
|
||||
{
|
||||
std::cerr << std::format("Weapon {} ({}) has thermal scope set. ADS Zoom Out frac should be 0 to prevent zoom-out blur ({}).\n",
|
||||
weaponCompleteDef.szInternalName,
|
||||
weaponCompleteDef.szDisplayName,
|
||||
weaponDef.fAdsZoomOutFrac);
|
||||
con::error("Weapon {} ({}) has thermal scope set. ADS Zoom Out frac should be 0 to prevent zoom-out blur ({}).",
|
||||
weaponCompleteDef.szInternalName,
|
||||
weaponCompleteDef.szDisplayName,
|
||||
weaponDef.fAdsZoomOutFrac);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,7 +336,7 @@ namespace
|
||||
weaponDef.fMinDamageRange = 999999.12f;
|
||||
|
||||
if (weaponDef.enemyCrosshairRange > 15000.0f)
|
||||
std::cerr << std::format("Enemy crosshair ranges should be less than {}\n", 15000.0f);
|
||||
con::error("Enemy crosshair ranges should be less than {}", 15000.0f);
|
||||
|
||||
if (weaponDef.weapType == WEAPTYPE_PROJECTILE)
|
||||
CheckProjectileValues(weaponCompleteDef, weaponDef);
|
||||
@@ -350,22 +349,21 @@ namespace
|
||||
|
||||
if (weaponDef.offhandClass && !weaponDef.bClipOnly)
|
||||
{
|
||||
std::cerr << std::format(
|
||||
"Weapon {} ({}) is an offhand weapon but is not set to clip only, which is not supported since we can't reload the offhand slot.\n",
|
||||
weaponCompleteDef.szInternalName,
|
||||
weaponCompleteDef.szDisplayName);
|
||||
con::error("Weapon {} ({}) is an offhand weapon but is not set to clip only, which is not supported since we can't reload the offhand slot.",
|
||||
weaponCompleteDef.szInternalName,
|
||||
weaponCompleteDef.szDisplayName);
|
||||
}
|
||||
|
||||
if (weaponDef.weapType == WEAPTYPE_BULLET)
|
||||
{
|
||||
if (weaponDef.bulletExplDmgMult <= 0.0f)
|
||||
std::cerr << std::format("Detected invalid bulletExplDmgMult of '{}' for weapon '{}'; please update weapon settings.\n",
|
||||
weaponDef.bulletExplDmgMult,
|
||||
weaponCompleteDef.szInternalName);
|
||||
con::error("Detected invalid bulletExplDmgMult of '{}' for weapon '{}'; please update weapon settings.",
|
||||
weaponDef.bulletExplDmgMult,
|
||||
weaponCompleteDef.szInternalName);
|
||||
if (weaponDef.bulletExplRadiusMult <= 0.0f)
|
||||
std::cerr << std::format("Detected invalid bulletExplRadiusMult of '{}' for weapon '{}'; please update weapon settings.\n",
|
||||
weaponDef.bulletExplRadiusMult,
|
||||
weaponCompleteDef.szInternalName);
|
||||
con::error("Detected invalid bulletExplRadiusMult of '{}' for weapon '{}'; please update weapon settings.",
|
||||
weaponDef.bulletExplRadiusMult,
|
||||
weaponCompleteDef.szInternalName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,33 +424,36 @@ namespace
|
||||
}
|
||||
} // namespace
|
||||
|
||||
InfoStringLoaderWeapon::InfoStringLoaderWeapon(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
: m_memory(memory),
|
||||
m_search_path(searchPath),
|
||||
m_zone(zone)
|
||||
namespace weapon
|
||||
{
|
||||
}
|
||||
|
||||
AssetCreationResult InfoStringLoaderWeapon::CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context)
|
||||
{
|
||||
auto* weaponFullDef = m_memory.Alloc<WeaponFullDef>();
|
||||
|
||||
InitWeaponFullDef(*weaponFullDef);
|
||||
weaponFullDef->weapCompleteDef.szInternalName = m_memory.Dup(assetName.c_str());
|
||||
|
||||
AssetRegistration<AssetWeapon> registration(assetName, &weaponFullDef->weapCompleteDef);
|
||||
|
||||
InfoStringToWeaponConverter converter(
|
||||
infoString, *weaponFullDef, m_zone.m_script_strings, m_memory, context, registration, weapon_fields, std::extent_v<decltype(weapon_fields)>);
|
||||
if (!converter.Convert())
|
||||
InfoStringLoaderIW4::InfoStringLoaderIW4(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
: m_memory(memory),
|
||||
m_search_path(searchPath),
|
||||
m_zone(zone)
|
||||
{
|
||||
std::cerr << std::format("Failed to parse weapon: \"{}\"\n", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
CalculateWeaponFields(*weaponFullDef, m_memory);
|
||||
AssetCreationResult InfoStringLoaderIW4::CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context)
|
||||
{
|
||||
auto* weaponFullDef = m_memory.Alloc<WeaponFullDef>();
|
||||
|
||||
LoadAccuracyGraphs(*weaponFullDef, m_memory, m_search_path, context);
|
||||
InitWeaponFullDef(*weaponFullDef);
|
||||
weaponFullDef->weapCompleteDef.szInternalName = m_memory.Dup(assetName.c_str());
|
||||
|
||||
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||
}
|
||||
AssetRegistration<AssetWeapon> registration(assetName, &weaponFullDef->weapCompleteDef);
|
||||
|
||||
InfoStringToWeaponConverter converter(
|
||||
infoString, *weaponFullDef, m_zone.m_script_strings, m_memory, context, registration, weapon_fields, std::extent_v<decltype(weapon_fields)>);
|
||||
if (!converter.Convert())
|
||||
{
|
||||
con::error("Failed to parse weapon: \"{}\"", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
CalculateWeaponFields(*weaponFullDef, m_memory);
|
||||
|
||||
LoadAccuracyGraphs(*weaponFullDef, m_memory, m_search_path, context);
|
||||
|
||||
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||
}
|
||||
} // namespace weapon
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
#include "Asset/AssetCreationResult.h"
|
||||
#include "InfoString/InfoString.h"
|
||||
|
||||
namespace IW4
|
||||
namespace weapon
|
||||
{
|
||||
class InfoStringLoaderWeapon
|
||||
class InfoStringLoaderIW4
|
||||
{
|
||||
public:
|
||||
InfoStringLoaderWeapon(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
InfoStringLoaderIW4(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context);
|
||||
|
||||
@@ -18,4 +18,4 @@ namespace IW4
|
||||
ISearchPath& m_search_path;
|
||||
Zone& m_zone;
|
||||
};
|
||||
} // namespace IW4
|
||||
} // namespace weapon
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include "Game/IW4/ObjConstantsIW4.h"
|
||||
#include "InfoString/InfoString.h"
|
||||
#include "InfoStringLoaderWeaponIW4.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
#include "Weapon/WeaponCommon.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
@@ -24,7 +26,7 @@ namespace
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto fileName = std::format("weapons/{}", assetName);
|
||||
const auto fileName = weapon::GetFileNameForAssetName(assetName);
|
||||
const auto file = m_search_path.Open(fileName);
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
@@ -32,7 +34,7 @@ namespace
|
||||
InfoString infoString;
|
||||
if (!infoString.FromStream(ObjConstants::INFO_STRING_PREFIX_WEAPON, *file.m_stream))
|
||||
{
|
||||
std::cerr << std::format("Could not parse as info string file: \"{}\"\n", fileName);
|
||||
con::error("Could not parse as info string file: \"{}\"", fileName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
@@ -41,14 +43,14 @@ namespace
|
||||
|
||||
private:
|
||||
ISearchPath& m_search_path;
|
||||
InfoStringLoaderWeapon m_info_string_loader;
|
||||
weapon::InfoStringLoaderIW4 m_info_string_loader;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW4
|
||||
namespace weapon
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetWeapon>> CreateRawWeaponLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
std::unique_ptr<AssetCreator<AssetWeapon>> CreateRawLoaderIW4(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
{
|
||||
return std::make_unique<RawLoaderWeapon>(memory, searchPath, zone);
|
||||
}
|
||||
} // namespace IW4
|
||||
} // namespace weapon
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW4
|
||||
namespace weapon
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetWeapon>> CreateRawWeaponLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
} // namespace IW4
|
||||
std::unique_ptr<AssetCreator<IW4::AssetWeapon>> CreateRawLoaderIW4(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
} // namespace weapon
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#include "LoaderImageIW5.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Image/ImageCommon.h"
|
||||
#include "Image/IwiLoader.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
@@ -25,7 +27,7 @@ namespace
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto fileName = std::format("images/{}.iwi", assetName);
|
||||
const auto fileName = image::GetFileNameForAsset(assetName, ".iwi");
|
||||
const auto file = m_search_path.Open(fileName);
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
@@ -38,7 +40,7 @@ namespace
|
||||
const auto texture = iwi::LoadIwi(ss);
|
||||
if (!texture)
|
||||
{
|
||||
std::cerr << std::format("Failed to load texture from: {}\n", fileName);
|
||||
con::error("Failed to load texture from: {}", fileName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
@@ -60,10 +62,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
namespace image
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetImage>> CreateImageLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetImage>> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<ImageLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW5
|
||||
} // namespace image
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW5
|
||||
namespace image
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetImage>> CreateImageLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW5
|
||||
std::unique_ptr<AssetCreator<IW5::AssetImage>> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace image
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "InfoStringToStructConverter.h"
|
||||
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
@@ -63,7 +65,7 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
|
||||
if (fx == nullptr)
|
||||
{
|
||||
std::cerr << std::format("Failed to load fx asset \"{}\"\n", value);
|
||||
con::error("Failed to load fx asset \"{}\"", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -85,7 +87,7 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
|
||||
if (xmodel == nullptr)
|
||||
{
|
||||
std::cerr << std::format("Failed to load xmodel asset \"{}\"\n", value);
|
||||
con::error("Failed to load xmodel asset \"{}\"", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -107,7 +109,7 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
|
||||
if (material == nullptr)
|
||||
{
|
||||
std::cerr << std::format("Failed to load material asset \"{}\"\n", value);
|
||||
con::error("Failed to load material asset \"{}\"", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -129,7 +131,7 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
|
||||
if (tracer == nullptr)
|
||||
{
|
||||
std::cerr << std::format("Failed to load tracer asset \"{}\"\n", value);
|
||||
con::error("Failed to load tracer asset \"{}\"", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -146,7 +148,7 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
|
||||
if (endPtr != &value[value.size()])
|
||||
{
|
||||
std::cout << "Failed to parse value \"" << value << "\" as mph\n";
|
||||
con::error("Failed to parse value \"{}\" as mph", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -165,7 +167,7 @@ bool InfoStringToStructConverter::ConvertBaseField(const cspField_t& field, cons
|
||||
|
||||
if (collmap == nullptr)
|
||||
{
|
||||
std::cerr << std::format("Failed to load collmap asset \"{}\"\n", value);
|
||||
con::error("Failed to load collmap asset \"{}\"", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
#include "JsonLeaderboardDefLoader.h"
|
||||
|
||||
#include "Game/IW5/CommonIW5.h"
|
||||
#include "Game/IW5/Leaderboard/JsonLeaderboardDef.h"
|
||||
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using namespace nlohmann;
|
||||
using namespace IW5;
|
||||
|
||||
namespace
|
||||
{
|
||||
class JsonLoader
|
||||
{
|
||||
public:
|
||||
JsonLoader(std::istream& stream, MemoryManager& memory)
|
||||
: m_stream(stream),
|
||||
m_memory(memory)
|
||||
{
|
||||
}
|
||||
|
||||
bool Load(LeaderboardDef& leaderboardDef) const
|
||||
{
|
||||
const auto jRoot = json::parse(m_stream);
|
||||
std::string type;
|
||||
unsigned version;
|
||||
|
||||
jRoot.at("_type").get_to(type);
|
||||
jRoot.at("_version").get_to(version);
|
||||
|
||||
if (type != "leaderboard" || version != 1u)
|
||||
{
|
||||
std::cerr << std::format("Tried to load leaderboard \"{}\" but did not find expected type leaderboard of version 1\n", leaderboardDef.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
const auto jLeaderboard = jRoot.get<JsonLeaderboardDef>();
|
||||
return CreateLeaderboardFromJson(jLeaderboard, leaderboardDef);
|
||||
}
|
||||
catch (const json::exception& e)
|
||||
{
|
||||
std::cerr << std::format("Failed to parse json of leaderboard: {}\n", e.what());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
static bool CreateTrackTypeFlagsFromJson(const JsonLeaderboardDef& jLeaderboardDef, int& trackTypeFlags)
|
||||
{
|
||||
for (const auto trackType : jLeaderboardDef.trackTypes)
|
||||
trackTypeFlags |= 1 << trackType;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateColumnDefFromJson(const JsonColumnDef& jColumn, LbColumnDef& lbColumnDef, LeaderboardDef& leaderboardDef) const
|
||||
{
|
||||
lbColumnDef.name = m_memory.Dup(jColumn.name.c_str());
|
||||
|
||||
lbColumnDef.id = jColumn.colId;
|
||||
lbColumnDef.propertyId = jColumn.propertyId.value_or(0);
|
||||
lbColumnDef.hidden = jColumn.hidden.value_or(false);
|
||||
|
||||
if (jColumn.statName)
|
||||
lbColumnDef.statName = m_memory.Dup(jColumn.statName->c_str());
|
||||
else
|
||||
lbColumnDef.statName = nullptr;
|
||||
|
||||
lbColumnDef.type = jColumn.type;
|
||||
|
||||
lbColumnDef.precision = jColumn.precision.value_or(0);
|
||||
|
||||
lbColumnDef.agg = jColumn.aggregationFunction;
|
||||
|
||||
lbColumnDef.uiCalColX = jColumn.uiCalColX.value_or(0);
|
||||
lbColumnDef.uiCalColY = jColumn.uiCalColY.value_or(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateLeaderboardFromJson(const JsonLeaderboardDef& jLeaderboardDef, LeaderboardDef& leaderboardDef) const
|
||||
{
|
||||
leaderboardDef.id = jLeaderboardDef.id;
|
||||
|
||||
leaderboardDef.xpColId = jLeaderboardDef.xpColId.value_or(-1);
|
||||
leaderboardDef.prestigeColId = jLeaderboardDef.prestigeColId.value_or(-1);
|
||||
|
||||
if (!jLeaderboardDef.columns.empty())
|
||||
{
|
||||
leaderboardDef.columnCount = static_cast<int>(jLeaderboardDef.columns.size());
|
||||
leaderboardDef.columns = m_memory.Alloc<LbColumnDef>(leaderboardDef.columnCount);
|
||||
|
||||
for (auto i = 0; i < leaderboardDef.columnCount; i++)
|
||||
{
|
||||
if (!CreateColumnDefFromJson(jLeaderboardDef.columns[i], leaderboardDef.columns[i], leaderboardDef))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
leaderboardDef.columnCount = 0;
|
||||
leaderboardDef.columns = nullptr;
|
||||
}
|
||||
|
||||
leaderboardDef.updateType = jLeaderboardDef.updateType;
|
||||
|
||||
if (!CreateTrackTypeFlagsFromJson(jLeaderboardDef, leaderboardDef.trackTypes))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::istream& m_stream;
|
||||
MemoryManager& m_memory;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
bool LoadLeaderboardAsJson(std::istream& stream, LeaderboardDef& leaderboard, MemoryManager& memory)
|
||||
{
|
||||
const JsonLoader loader(stream, memory);
|
||||
|
||||
return loader.Load(leaderboard);
|
||||
}
|
||||
} // namespace IW5
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <istream>
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
bool LoadLeaderboardAsJson(std::istream& stream, LeaderboardDef& leaderboard, MemoryManager& memory);
|
||||
} // namespace IW5
|
||||
@@ -1,16 +1,127 @@
|
||||
#include "LoaderLeaderboardIW5.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "JsonLeaderboardDefLoader.h"
|
||||
#include "Game/IW5/Leaderboard/JsonLeaderboardDef.h"
|
||||
#include "Leaderboard/LeaderboardCommon.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using namespace nlohmann;
|
||||
using namespace IW5;
|
||||
|
||||
namespace
|
||||
{
|
||||
class JsonLoader
|
||||
{
|
||||
public:
|
||||
JsonLoader(std::istream& stream, MemoryManager& memory)
|
||||
: m_stream(stream),
|
||||
m_memory(memory)
|
||||
{
|
||||
}
|
||||
|
||||
bool Load(LeaderboardDef& leaderboardDef) const
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto jRoot = json::parse(m_stream);
|
||||
std::string type;
|
||||
unsigned version;
|
||||
|
||||
jRoot.at("_type").get_to(type);
|
||||
jRoot.at("_version").get_to(version);
|
||||
|
||||
if (type != "leaderboard" || version != 1u)
|
||||
{
|
||||
con::error("Tried to load leaderboard \"{}\" but did not find expected type leaderboard of version 1", leaderboardDef.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto jLeaderboard = jRoot.get<JsonLeaderboardDef>();
|
||||
return CreateLeaderboardFromJson(jLeaderboard, leaderboardDef);
|
||||
}
|
||||
catch (const json::exception& e)
|
||||
{
|
||||
con::error("Failed to parse json of leaderboard: {}", e.what());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
static bool CreateTrackTypeFlagsFromJson(const JsonLeaderboardDef& jLeaderboardDef, int& trackTypeFlags)
|
||||
{
|
||||
for (const auto trackType : jLeaderboardDef.trackTypes)
|
||||
trackTypeFlags |= 1 << trackType;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateColumnDefFromJson(const JsonColumnDef& jColumn, LbColumnDef& lbColumnDef, LeaderboardDef& leaderboardDef) const
|
||||
{
|
||||
lbColumnDef.name = m_memory.Dup(jColumn.name.c_str());
|
||||
|
||||
lbColumnDef.id = jColumn.colId;
|
||||
lbColumnDef.propertyId = jColumn.propertyId.value_or(0);
|
||||
lbColumnDef.hidden = jColumn.hidden.value_or(false);
|
||||
|
||||
if (jColumn.statName)
|
||||
lbColumnDef.statName = m_memory.Dup(jColumn.statName->c_str());
|
||||
else
|
||||
lbColumnDef.statName = nullptr;
|
||||
|
||||
lbColumnDef.type = jColumn.type;
|
||||
|
||||
lbColumnDef.precision = jColumn.precision.value_or(0);
|
||||
|
||||
lbColumnDef.agg = jColumn.aggregationFunction;
|
||||
|
||||
lbColumnDef.uiCalColX = jColumn.uiCalColX.value_or(0);
|
||||
lbColumnDef.uiCalColY = jColumn.uiCalColY.value_or(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateLeaderboardFromJson(const JsonLeaderboardDef& jLeaderboardDef, LeaderboardDef& leaderboardDef) const
|
||||
{
|
||||
leaderboardDef.id = jLeaderboardDef.id;
|
||||
|
||||
leaderboardDef.xpColId = jLeaderboardDef.xpColId.value_or(-1);
|
||||
leaderboardDef.prestigeColId = jLeaderboardDef.prestigeColId.value_or(-1);
|
||||
|
||||
if (!jLeaderboardDef.columns.empty())
|
||||
{
|
||||
leaderboardDef.columnCount = static_cast<int>(jLeaderboardDef.columns.size());
|
||||
leaderboardDef.columns = m_memory.Alloc<LbColumnDef>(leaderboardDef.columnCount);
|
||||
|
||||
for (auto i = 0; i < leaderboardDef.columnCount; i++)
|
||||
{
|
||||
if (!CreateColumnDefFromJson(jLeaderboardDef.columns[i], leaderboardDef.columns[i], leaderboardDef))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
leaderboardDef.columnCount = 0;
|
||||
leaderboardDef.columns = nullptr;
|
||||
}
|
||||
|
||||
leaderboardDef.updateType = jLeaderboardDef.updateType;
|
||||
|
||||
if (!CreateTrackTypeFlagsFromJson(jLeaderboardDef, leaderboardDef.trackTypes))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::istream& m_stream;
|
||||
MemoryManager& m_memory;
|
||||
};
|
||||
|
||||
class LeaderboardLoader final : public AssetCreator<AssetLeaderboard>
|
||||
{
|
||||
public:
|
||||
@@ -22,16 +133,17 @@ namespace
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto file = m_search_path.Open(std::format("leaderboards/{}.json", assetName));
|
||||
const auto file = m_search_path.Open(leaderboard::GetJsonFileNameForAsset(assetName));
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
auto* leaderboardDef = m_memory.Alloc<LeaderboardDef>();
|
||||
leaderboardDef->name = m_memory.Dup(assetName.c_str());
|
||||
|
||||
if (!LoadLeaderboardAsJson(*file.m_stream, *leaderboardDef, m_memory))
|
||||
const JsonLoader loader(*file.m_stream, m_memory);
|
||||
if (!loader.Load(*leaderboardDef))
|
||||
{
|
||||
std::cerr << std::format("Failed to load leaderboard \"{}\"\n", assetName);
|
||||
con::error("Failed to load leaderboard \"{}\"", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
@@ -44,10 +156,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
namespace leaderboard
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLeaderboard>> CreateLeaderboardLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetLeaderboard>> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<LeaderboardLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW5
|
||||
} // namespace leaderboard
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW5
|
||||
namespace leaderboard
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLeaderboard>> CreateLeaderboardLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW5
|
||||
std::unique_ptr<AssetCreator<IW5::AssetLeaderboard>> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace leaderboard
|
||||
|
||||
@@ -35,10 +35,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
namespace localize
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLocalize>> CreateLocalizeLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
std::unique_ptr<AssetCreator<AssetLocalize>> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
{
|
||||
return std::make_unique<LocalizeLoader>(memory, searchPath, zone);
|
||||
}
|
||||
} // namespace IW5
|
||||
} // namespace localize
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW5
|
||||
namespace localize
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLocalize>> CreateLocalizeLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
} // namespace IW5
|
||||
std::unique_ptr<AssetCreator<IW5::AssetLocalize>> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
} // namespace localize
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Game/IW5/Material/JsonMaterialLoaderIW5.h"
|
||||
#include "Material/MaterialCommon.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
@@ -32,7 +33,7 @@ namespace
|
||||
AssetRegistration<AssetMaterial> registration(assetName, material);
|
||||
if (!LoadMaterialAsJson(*file.m_stream, *material, m_memory, context, registration))
|
||||
{
|
||||
std::cerr << std::format("Failed to load material \"{}\"\n", assetName);
|
||||
con::error("Failed to load material \"{}\"", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
@@ -45,10 +46,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
namespace material
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMaterial>> CreateMaterialLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetMaterial>> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<MaterialLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW5
|
||||
} // namespace material
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW5
|
||||
namespace material
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMaterial>> CreateMaterialLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW5
|
||||
std::unique_ptr<AssetCreator<IW5::AssetMaterial>> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace material
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Game/IW5/Menu/MenuConverterIW5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "Parsing/Menu/MenuFileReader.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
@@ -88,7 +89,7 @@ namespace
|
||||
const auto alreadyLoadedMenuFile = conversionState.m_menus_by_filename.find(menuFilePath);
|
||||
if (alreadyLoadedMenuFile != conversionState.m_menus_by_filename.end())
|
||||
{
|
||||
std::cout << std::format("Already loaded \"{}\", skipping\n", menuFilePath);
|
||||
con::debug("Already loaded \"{}\", skipping", menuFilePath);
|
||||
for (auto* menu : alreadyLoadedMenuFile->second)
|
||||
{
|
||||
menus.emplace_back(menu->Asset());
|
||||
@@ -100,7 +101,7 @@ namespace
|
||||
const auto file = m_search_path.Open(menuFilePath);
|
||||
if (!file.IsOpen())
|
||||
{
|
||||
std::cerr << std::format("Could not open menu file \"{}\"\n", menuFilePath);
|
||||
con::error("Could not open menu file \"{}\"", menuFilePath);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -109,12 +110,12 @@ namespace
|
||||
{
|
||||
ProcessParsedResults(menuFilePath, context, *menuFileResult, zoneState, conversionState, menus, registration);
|
||||
if (!menuFileResult->m_menus_to_load.empty())
|
||||
std::cout << std::format("WARNING: Menu file has menus to load even though it is not a menu list, ignoring: \"{}\"\n", menuFilePath);
|
||||
con::warn("Menu file has menus to load even though it is not a menu list, ignoring: \"{}\"", menuFilePath);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
std::cerr << std::format("Could not read menu file \"{}\"\n", menuFilePath);
|
||||
con::error("Could not read menu file \"{}\"", menuFilePath);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -134,12 +135,12 @@ namespace
|
||||
for (const auto& menu : parsingResult.m_menus)
|
||||
totalItemCount += static_cast<unsigned>(menu->m_items.size());
|
||||
|
||||
std::cout << std::format("Successfully read menu file \"{}\" ({} loads, {} menus, {} functions, {} items)\n",
|
||||
fileName,
|
||||
menuLoadCount,
|
||||
menuCount,
|
||||
functionCount,
|
||||
totalItemCount);
|
||||
con::info("Successfully read menu file \"{}\" ({} loads, {} menus, {} functions, {} items)",
|
||||
fileName,
|
||||
menuLoadCount,
|
||||
menuCount,
|
||||
functionCount,
|
||||
totalItemCount);
|
||||
|
||||
// Add all functions to the zone state to make them available for all menus to be converted
|
||||
for (auto& function : parsingResult.m_functions)
|
||||
@@ -160,7 +161,7 @@ namespace
|
||||
converter->ConvertMenu(*commonMenu, *menuAsset, menuRegistration);
|
||||
if (menuAsset == nullptr)
|
||||
{
|
||||
std::cerr << std::format("Failed to convert menu file \"{}\"\n", commonMenu->m_name);
|
||||
con::error("Failed to convert menu file \"{}\"", commonMenu->m_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -212,10 +213,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
namespace menu
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMenuList>> CreateMenuListLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetMenuList>> CreateMenuListLoaderIW5(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<MenuListLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW5
|
||||
} // namespace menu
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW5
|
||||
namespace menu
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMenuList>> CreateMenuListLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW5
|
||||
std::unique_ptr<AssetCreator<IW5::AssetMenuList>> CreateMenuListLoaderIW5(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace menu
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace IW5
|
||||
IMenuConverter() = default;
|
||||
virtual ~IMenuConverter() = default;
|
||||
|
||||
virtual void ConvertMenu(const menu::CommonMenuDef& commonMenu, menuDef_t& menu, AssetRegistration<AssetMenu>& registration) = 0;
|
||||
virtual void ConvertMenu(const ::menu::CommonMenuDef& commonMenu, menuDef_t& menu, AssetRegistration<AssetMenu>& registration) = 0;
|
||||
|
||||
static std::unique_ptr<IMenuConverter> Create(bool disableOptimizations, ISearchPath& searchPath, MemoryManager& memory, AssetCreationContext& context);
|
||||
};
|
||||
|
||||
@@ -125,13 +125,13 @@ namespace
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderPhysCollMap>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderXAnim>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderXModelSurfs>(memory));
|
||||
collection.AddAssetCreator(CreateXModelLoader(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(CreateMaterialLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(xmodel::CreateLoaderIW5(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(material::CreateLoaderIW5(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderPixelShader>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderVertexShader>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderVertexDecl>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderTechniqueSet>(memory));
|
||||
collection.AddAssetCreator(CreateImageLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(image::CreateLoaderIW5(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderSound>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderSoundCurve>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderLoadedSound>(memory));
|
||||
@@ -145,19 +145,19 @@ namespace
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderGfxWorld>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderLightDef>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderFont>(memory));
|
||||
collection.AddAssetCreator(CreateMenuListLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(menu::CreateMenuListLoaderIW5(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderMenu>(memory));
|
||||
collection.AddAssetCreator(CreateLocalizeLoader(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(CreateAttachmentLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(CreateRawWeaponLoader(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(CreateGdtWeaponLoader(memory, searchPath, gdt, zone));
|
||||
collection.AddAssetCreator(localize::CreateLoaderIW5(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(attachment::CreateLoaderIW5(memory, searchPath));
|
||||
collection.AddAssetCreator(weapon::CreateRawLoaderIW5(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(weapon::CreateGdtLoaderIW5(memory, searchPath, gdt, zone));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderFx>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderImpactFx>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderSurfaceFx>(memory));
|
||||
collection.AddAssetCreator(CreateRawFileLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(CreateScriptLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(CreateStringTableLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(CreateLeaderboardLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(raw_file::CreateLoaderIW5(memory, searchPath));
|
||||
collection.AddAssetCreator(script::CreateLoaderIW5(memory, searchPath));
|
||||
collection.AddAssetCreator(string_table::CreateLoaderIW5(memory, searchPath));
|
||||
collection.AddAssetCreator(leaderboard::CreateLoaderIW5(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderStructuredDataDef>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderTracer>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderVehicle>(memory));
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
@@ -57,7 +58,7 @@ namespace
|
||||
|
||||
if (ret != Z_STREAM_END)
|
||||
{
|
||||
std::cerr << std::format("Deflate failed for loading rawfile \"{}\"\n", assetName);
|
||||
con::error("Deflate failed for loading rawfile \"{}\"", assetName);
|
||||
deflateEnd(&zs);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
@@ -81,10 +82,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
namespace raw_file
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetRawFile>> CreateRawFileLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetRawFile>> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<RawFileLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW5
|
||||
} // namespace raw_file
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW5
|
||||
namespace raw_file
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetRawFile>> CreateRawFileLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW5
|
||||
std::unique_ptr<AssetCreator<IW5::AssetRawFile>> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace raw_file
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Pool/GlobalAssetPool.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
@@ -53,13 +54,13 @@ namespace
|
||||
|
||||
if (scriptFile->compressedLen <= 0 || scriptFile->bytecodeLen <= 0)
|
||||
{
|
||||
std::cerr << std::format("Error: Invalid length of the buffers in {} specified\n", assetName);
|
||||
con::error("Invalid length of the buffers in {} specified", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
if (offset + static_cast<size_t>(scriptFile->compressedLen + scriptFile->bytecodeLen) > static_cast<size_t>(file.m_length))
|
||||
{
|
||||
std::cerr << std::format("Error: Specified length in {} GSC BIN structure exceeds the actual file size\n", assetName);
|
||||
con::error("Specified length in {} GSC BIN structure exceeds the actual file size", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
@@ -79,10 +80,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
namespace script
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetScript>> CreateScriptLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetScript>> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<ScriptLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW5
|
||||
} // namespace script
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW5
|
||||
namespace script
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetScript>> CreateScriptLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW5
|
||||
std::unique_ptr<AssetCreator<IW5::AssetScript>> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace script
|
||||
|
||||
@@ -40,10 +40,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
namespace string_table
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetStringTable>> CreateStringTableLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetStringTable>> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<StringTableLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW5
|
||||
} // namespace string_table
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW5
|
||||
namespace string_table
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetStringTable>> CreateStringTableLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW5
|
||||
std::unique_ptr<AssetCreator<IW5::AssetStringTable>> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace string_table
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "Game/IW5/ObjConstantsIW5.h"
|
||||
#include "InfoString/InfoString.h"
|
||||
#include "InfoStringLoaderWeaponIW5.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
@@ -31,7 +32,7 @@ namespace
|
||||
InfoString infoString;
|
||||
if (!infoString.FromGdtProperties(*gdtEntry))
|
||||
{
|
||||
std::cerr << std::format("Failed to read weapon gdt entry: \"{}\"\n", assetName);
|
||||
con::error("Failed to read weapon gdt entry: \"{}\"", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
@@ -40,14 +41,14 @@ namespace
|
||||
|
||||
private:
|
||||
IGdtQueryable& m_gdt;
|
||||
InfoStringLoaderWeapon m_info_string_loader;
|
||||
weapon::InfoStringLoaderIW5 m_info_string_loader;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
namespace weapon
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetWeapon>> CreateGdtWeaponLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone)
|
||||
std::unique_ptr<AssetCreator<AssetWeapon>> CreateGdtLoaderIW5(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone)
|
||||
{
|
||||
return std::make_unique<GdtLoaderWeapon>(memory, searchPath, gdt, zone);
|
||||
}
|
||||
} // namespace IW5
|
||||
} // namespace weapon
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW5
|
||||
namespace weapon
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetWeapon>> CreateGdtWeaponLoader(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone);
|
||||
} // namespace IW5
|
||||
std::unique_ptr<AssetCreator<IW5::AssetWeapon>> CreateGdtLoaderIW5(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone);
|
||||
} // namespace weapon
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Game/IW5/InfoString/InfoStringToStructConverter.h"
|
||||
#include "Game/IW5/Weapon/WeaponFields.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
#include "Weapon/AccuracyGraphLoader.h"
|
||||
|
||||
#include <cassert>
|
||||
@@ -22,13 +23,13 @@ namespace
|
||||
std::vector<std::string> valueArray;
|
||||
if (!ParseAsArray(value, valueArray))
|
||||
{
|
||||
std::cerr << "Failed to parse hide tags as array\n";
|
||||
con::error("Failed to parse hide tags as array");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (valueArray.size() > std::extent_v<decltype(WeaponFullDef::hideTags)>)
|
||||
{
|
||||
std::cerr << std::format("Cannot have more than {} hide tags!\n", std::extent_v<decltype(WeaponFullDef::hideTags)>);
|
||||
con::error("Cannot have more than {} hide tags!", std::extent_v<decltype(WeaponFullDef::hideTags)>);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -83,14 +84,13 @@ namespace
|
||||
std::vector<std::array<std::string, 2>> pairs;
|
||||
if (!ParseAsArray(value, pairs))
|
||||
{
|
||||
std::cerr << std::format("Failed to parse notetrack{}map as pairs\n", mapName);
|
||||
con::error("Failed to parse notetrack{}map as pairs", mapName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pairs.size() > std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>)
|
||||
{
|
||||
std::cerr << std::format(
|
||||
"Cannot have more than {} notetrack{}map entries!\n", std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>, mapName);
|
||||
con::error("Cannot have more than {} notetrack{}map entries!", std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>, mapName);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ namespace
|
||||
std::vector<std::string> valueArray;
|
||||
if (!ParseAsArray(value, valueArray))
|
||||
{
|
||||
std::cerr << "Failed to parse attachments as array\n";
|
||||
con::error("Failed to parse attachments as array");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ namespace
|
||||
{
|
||||
if (currentScope >= std::extent_v<decltype(WeaponFullDef::scopes)>)
|
||||
{
|
||||
std::cerr << std::format("Cannot have more than {} scopes\n", std::extent_v<decltype(WeaponFullDef::scopes)>);
|
||||
con::error("Cannot have more than {} scopes", std::extent_v<decltype(WeaponFullDef::scopes)>);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ namespace
|
||||
{
|
||||
if (currentUnderBarrel >= std::extent_v<decltype(WeaponFullDef::underBarrels)>)
|
||||
{
|
||||
std::cerr << std::format("Cannot have more than {} under barrels\n", std::extent_v<decltype(WeaponFullDef::underBarrels)>);
|
||||
con::error("Cannot have more than {} under barrels", std::extent_v<decltype(WeaponFullDef::underBarrels)>);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ namespace
|
||||
{
|
||||
if (currentOther >= std::extent_v<decltype(WeaponFullDef::others)>)
|
||||
{
|
||||
std::cerr << std::format("Cannot have more than {} other attachments\n", std::extent_v<decltype(WeaponFullDef::others)>);
|
||||
con::error("Cannot have more than {} other attachments", std::extent_v<decltype(WeaponFullDef::others)>);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace
|
||||
std::vector<std::array<std::string, 7>> valueArray;
|
||||
if (!ParseAsArray(value, valueArray))
|
||||
{
|
||||
std::cerr << "Failed to parse anim overrides as array\n";
|
||||
con::error("Failed to parse anim overrides as array");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ namespace
|
||||
std::vector<std::array<std::string, 5>> valueArray;
|
||||
if (!ParseAsArray(value, valueArray))
|
||||
{
|
||||
std::cerr << "Failed to parse sound overrides as array\n";
|
||||
con::error("Failed to parse sound overrides as array");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ namespace
|
||||
std::vector<std::array<std::string, 5>> valueArray;
|
||||
if (!ParseAsArray(value, valueArray))
|
||||
{
|
||||
std::cerr << "Failed to parse attachments as array\n";
|
||||
con::error("Failed to parse attachments as array");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -315,7 +315,7 @@ namespace
|
||||
std::vector<std::array<std::string, 3>> valueArray;
|
||||
if (!ParseAsArray(value, valueArray))
|
||||
{
|
||||
std::cerr << "Failed to parse reload overrides as array\n";
|
||||
con::error("Failed to parse reload overrides as array");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ namespace
|
||||
std::vector<std::array<std::string, 3>> valueArray;
|
||||
if (!ParseAsArray(value, valueArray))
|
||||
{
|
||||
std::cerr << "Failed to parse note track overrides as array\n";
|
||||
con::error("Failed to parse note track overrides as array");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -378,7 +378,7 @@ namespace
|
||||
|
||||
if (currentOverrideKeyOffset >= 24u)
|
||||
{
|
||||
std::cerr << std::format("Cannot have more than {} note track overrides per attachment\n", 24u);
|
||||
con::error("Cannot have more than {} note track overrides per attachment", 24u);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -433,7 +433,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << std::format("Weapon does not have attachment \"{}\"\n", value);
|
||||
con::error("Weapon does not have attachment \"{}\"", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -473,7 +473,7 @@ namespace
|
||||
auto* fxInfo = m_context.LoadDependency<AssetFx>(value);
|
||||
if (!fxInfo)
|
||||
{
|
||||
std::cerr << std::format("Failed to load fx for override \"{}\"\n", value);
|
||||
con::error("Failed to load fx for override \"{}\"", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -494,7 +494,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << std::format("Unknown anim file \"{}\"\n", value);
|
||||
con::error("Unknown anim file \"{}\"", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -509,7 +509,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << std::format("Unknown sound type \"{}\"\n", value);
|
||||
con::error("Unknown sound type \"{}\"", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -524,7 +524,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << std::format("Unknown fx type \"{}\"\n", value);
|
||||
con::error("Unknown fx type \"{}\"", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -535,7 +535,7 @@ namespace
|
||||
|
||||
if (size != value.size())
|
||||
{
|
||||
std::cerr << std::format("Invalid int value: \"{}\"\n", value);
|
||||
con::error("Invalid int value: \"{}\"", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -697,28 +697,27 @@ namespace
|
||||
void CheckProjectileValues(const WeaponCompleteDef& weaponCompleteDef, const WeaponDef& weaponDef)
|
||||
{
|
||||
if (weaponDef.iProjectileSpeed <= 0)
|
||||
std::cerr << std::format("Projectile speed for WeapType {} must be greater than 0.0", weaponCompleteDef.szDisplayName);
|
||||
con::error("Projectile speed for WeapType {} must be greater than 0.0", weaponCompleteDef.szDisplayName);
|
||||
if (weaponDef.destabilizationCurvatureMax >= 1000000000.0f || weaponDef.destabilizationCurvatureMax < 0.0f)
|
||||
std::cerr << std::format("Destabilization angle for for WeapType {} must be between 0 and 45 degrees", weaponCompleteDef.szDisplayName);
|
||||
con::error("Destabilization angle for for WeapType {} must be between 0 and 45 degrees", weaponCompleteDef.szDisplayName);
|
||||
if (weaponDef.destabilizationRateTime < 0.0f)
|
||||
std::cerr << std::format("Destabilization rate time for for WeapType {} must be non-negative", weaponCompleteDef.szDisplayName);
|
||||
con::error("Destabilization rate time for for WeapType {} must be non-negative", weaponCompleteDef.szDisplayName);
|
||||
}
|
||||
|
||||
void CheckTurretBarrelSpin(const WeaponCompleteDef& weaponCompleteDef, const WeaponDef& weaponDef)
|
||||
{
|
||||
if (weaponDef.weapClass != WEAPCLASS_TURRET)
|
||||
std::cerr << std::format("Rotating barrel set for non-turret weapon {}.", weaponCompleteDef.szInternalName);
|
||||
con::error("Rotating barrel set for non-turret weapon {}.", weaponCompleteDef.szInternalName);
|
||||
|
||||
if (0.0f == weaponDef.turretBarrelSpinSpeed)
|
||||
{
|
||||
std::cerr << std::format(
|
||||
"Rotating barrel spin speed '{}' is invalid for weapon {}.", weaponDef.turretBarrelSpinSpeed, weaponCompleteDef.szInternalName);
|
||||
con::error("Rotating barrel spin speed '{}' is invalid for weapon {}.", weaponDef.turretBarrelSpinSpeed, weaponCompleteDef.szInternalName);
|
||||
}
|
||||
if (0.0f < weaponDef.turretOverheatUpRate && 0.0f >= weaponDef.turretOverheatDownRate)
|
||||
{
|
||||
std::cerr << std::format("Turret overheat Up rate is set, but the down rate '{}' is invalid for weapon {}.",
|
||||
weaponDef.turretOverheatDownRate,
|
||||
weaponCompleteDef.szInternalName);
|
||||
con::error("Turret overheat Up rate is set, but the down rate '{}' is invalid for weapon {}.",
|
||||
weaponDef.turretOverheatDownRate,
|
||||
weaponCompleteDef.szInternalName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -726,18 +725,18 @@ namespace
|
||||
{
|
||||
if (0.0f != weaponDef.fAdsZoomInFrac)
|
||||
{
|
||||
std::cerr << std::format("Weapon {} ({}) has thermal scope set. ADS Zoom In frac should be 0 to prevent zoom-in blur ({}).\n",
|
||||
weaponCompleteDef.szInternalName,
|
||||
weaponCompleteDef.szDisplayName,
|
||||
weaponDef.fAdsZoomInFrac);
|
||||
con::error("Weapon {} ({}) has thermal scope set. ADS Zoom In frac should be 0 to prevent zoom-in blur ({}).",
|
||||
weaponCompleteDef.szInternalName,
|
||||
weaponCompleteDef.szDisplayName,
|
||||
weaponDef.fAdsZoomInFrac);
|
||||
}
|
||||
|
||||
if (0.0f != weaponDef.fAdsZoomOutFrac)
|
||||
{
|
||||
std::cerr << std::format("Weapon {} ({}) has thermal scope set. ADS Zoom Out frac should be 0 to prevent zoom-out blur ({}).\n",
|
||||
weaponCompleteDef.szInternalName,
|
||||
weaponCompleteDef.szDisplayName,
|
||||
weaponDef.fAdsZoomOutFrac);
|
||||
con::error("Weapon {} ({}) has thermal scope set. ADS Zoom Out frac should be 0 to prevent zoom-out blur ({}).",
|
||||
weaponCompleteDef.szInternalName,
|
||||
weaponCompleteDef.szDisplayName,
|
||||
weaponDef.fAdsZoomOutFrac);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -767,7 +766,7 @@ namespace
|
||||
weaponDef.fMinDamageRange = 999999.12f;
|
||||
|
||||
if (weaponDef.enemyCrosshairRange > 15000.0f)
|
||||
std::cerr << std::format("Enemy crosshair ranges should be less than {}\n", 15000.0f);
|
||||
con::error("Enemy crosshair ranges should be less than {}", 15000.0f);
|
||||
|
||||
if (weaponDef.weapType == WEAPTYPE_PROJECTILE)
|
||||
CheckProjectileValues(weaponCompleteDef, weaponDef);
|
||||
@@ -780,22 +779,21 @@ namespace
|
||||
|
||||
if (weaponDef.offhandClass && !weaponDef.bClipOnly)
|
||||
{
|
||||
std::cerr << std::format(
|
||||
"Weapon {} ({}) is an offhand weapon but is not set to clip only, which is not supported since we can't reload the offhand slot.\n",
|
||||
weaponCompleteDef.szInternalName,
|
||||
weaponCompleteDef.szDisplayName);
|
||||
con::error("Weapon {} ({}) is an offhand weapon but is not set to clip only, which is not supported since we can't reload the offhand slot.",
|
||||
weaponCompleteDef.szInternalName,
|
||||
weaponCompleteDef.szDisplayName);
|
||||
}
|
||||
|
||||
if (weaponDef.weapType == WEAPTYPE_BULLET)
|
||||
{
|
||||
if (weaponDef.bulletExplDmgMult <= 0.0f)
|
||||
std::cerr << std::format("Detected invalid bulletExplDmgMult of '{}' for weapon '{}'; please update weapon settings.\n",
|
||||
weaponDef.bulletExplDmgMult,
|
||||
weaponCompleteDef.szInternalName);
|
||||
con::error("Detected invalid bulletExplDmgMult of '{}' for weapon '{}'; please update weapon settings.",
|
||||
weaponDef.bulletExplDmgMult,
|
||||
weaponCompleteDef.szInternalName);
|
||||
if (weaponDef.bulletExplRadiusMult <= 0.0f)
|
||||
std::cerr << std::format("Detected invalid bulletExplRadiusMult of '{}' for weapon '{}'; please update weapon settings.\n",
|
||||
weaponDef.bulletExplRadiusMult,
|
||||
weaponCompleteDef.szInternalName);
|
||||
con::error("Detected invalid bulletExplRadiusMult of '{}' for weapon '{}'; please update weapon settings.",
|
||||
weaponDef.bulletExplRadiusMult,
|
||||
weaponCompleteDef.szInternalName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -856,33 +854,36 @@ namespace
|
||||
}
|
||||
} // namespace
|
||||
|
||||
InfoStringLoaderWeapon::InfoStringLoaderWeapon(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
: m_memory(memory),
|
||||
m_search_path(searchPath),
|
||||
m_zone(zone)
|
||||
namespace weapon
|
||||
{
|
||||
}
|
||||
|
||||
AssetCreationResult InfoStringLoaderWeapon::CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context) const
|
||||
{
|
||||
auto* weaponFullDef = m_memory.Alloc<WeaponFullDef>();
|
||||
|
||||
InitWeaponFullDef(*weaponFullDef);
|
||||
weaponFullDef->weapCompleteDef.szInternalName = m_memory.Dup(assetName.c_str());
|
||||
|
||||
AssetRegistration<AssetWeapon> registration(assetName, &weaponFullDef->weapCompleteDef);
|
||||
|
||||
InfoStringToWeaponConverter converter(
|
||||
infoString, *weaponFullDef, m_zone.m_script_strings, m_memory, context, registration, weapon_fields, std::extent_v<decltype(weapon_fields)>);
|
||||
if (!converter.Convert())
|
||||
InfoStringLoaderIW5::InfoStringLoaderIW5(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
: m_memory(memory),
|
||||
m_search_path(searchPath),
|
||||
m_zone(zone)
|
||||
{
|
||||
std::cerr << std::format("Failed to parse weapon: \"{}\"\n", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
CalculateWeaponFields(*weaponFullDef, m_memory);
|
||||
AssetCreationResult InfoStringLoaderIW5::CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context) const
|
||||
{
|
||||
auto* weaponFullDef = m_memory.Alloc<WeaponFullDef>();
|
||||
|
||||
LoadAccuracyGraphs(*weaponFullDef, m_memory, m_search_path, context);
|
||||
InitWeaponFullDef(*weaponFullDef);
|
||||
weaponFullDef->weapCompleteDef.szInternalName = m_memory.Dup(assetName.c_str());
|
||||
|
||||
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||
}
|
||||
AssetRegistration<AssetWeapon> registration(assetName, &weaponFullDef->weapCompleteDef);
|
||||
|
||||
InfoStringToWeaponConverter converter(
|
||||
infoString, *weaponFullDef, m_zone.m_script_strings, m_memory, context, registration, weapon_fields, std::extent_v<decltype(weapon_fields)>);
|
||||
if (!converter.Convert())
|
||||
{
|
||||
con::error("Failed to parse weapon: \"{}\"", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
CalculateWeaponFields(*weaponFullDef, m_memory);
|
||||
|
||||
LoadAccuracyGraphs(*weaponFullDef, m_memory, m_search_path, context);
|
||||
|
||||
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||
}
|
||||
} // namespace weapon
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
#include "Asset/AssetCreationResult.h"
|
||||
#include "InfoString/InfoString.h"
|
||||
|
||||
namespace IW5
|
||||
namespace weapon
|
||||
{
|
||||
class InfoStringLoaderWeapon
|
||||
class InfoStringLoaderIW5
|
||||
{
|
||||
public:
|
||||
InfoStringLoaderWeapon(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
InfoStringLoaderIW5(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context) const;
|
||||
|
||||
@@ -18,4 +18,4 @@ namespace IW5
|
||||
ISearchPath& m_search_path;
|
||||
Zone& m_zone;
|
||||
};
|
||||
} // namespace IW5
|
||||
} // namespace weapon
|
||||
|
||||
@@ -1,645 +0,0 @@
|
||||
#include "JsonWeaponAttachmentLoader.h"
|
||||
|
||||
#include "Game/IW5/CommonIW5.h"
|
||||
#include "Game/IW5/Weapon/JsonWeaponAttachment.h"
|
||||
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using namespace nlohmann;
|
||||
using namespace IW5;
|
||||
|
||||
namespace
|
||||
{
|
||||
class JsonLoader
|
||||
{
|
||||
public:
|
||||
JsonLoader(std::istream& stream, MemoryManager& memory, AssetCreationContext& context, AssetRegistration<AssetAttachment>& registration)
|
||||
: m_stream(stream),
|
||||
m_memory(memory),
|
||||
m_context(context),
|
||||
m_registration(registration)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
bool Load(WeaponAttachment& attachment) const
|
||||
{
|
||||
const auto jRoot = json::parse(m_stream);
|
||||
std::string type;
|
||||
unsigned version;
|
||||
|
||||
jRoot.at("_type").get_to(type);
|
||||
jRoot.at("_version").get_to(version);
|
||||
|
||||
if (type != "attachment" || version != 1u)
|
||||
{
|
||||
std::cerr << "Tried to load attachment \"" << attachment.szInternalName << "\" but did not find expected type attachment of version 1\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
const auto jAttachment = jRoot.get<JsonWeaponAttachment>();
|
||||
return CreateWeaponAttachmentFromJson(jAttachment, attachment);
|
||||
}
|
||||
catch (const json::exception& e)
|
||||
{
|
||||
std::cerr << std::format("Failed to parse json of attachment: {}\n", e.what());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
static void PrintError(const WeaponAttachment& attachment, const std::string& message)
|
||||
{
|
||||
std::cerr << "Cannot load attachment \"" << attachment.szInternalName << "\": " << message << "\n";
|
||||
}
|
||||
|
||||
bool CreateWeaponAttachmentFromJson(const JsonWeaponAttachment& jAttachment, WeaponAttachment& attachment) const
|
||||
{
|
||||
#define CONVERT_XMODEL_ARRAY(propertyName, count) \
|
||||
CreateXModelArrayFromJson(jAttachment.propertyName, attachment.propertyName, #propertyName, count, attachment);
|
||||
|
||||
#define CONVERT_ATTRIBUTE(attributeClass, attributeName) \
|
||||
if (jAttachment.attributeName) \
|
||||
{ \
|
||||
using AttributeType = std::remove_pointer_t<decltype(attachment.attributeName)>; \
|
||||
attachment.attributeName = m_memory.Alloc<AttributeType>(); \
|
||||
if (!Create##attributeClass##FromJson(jAttachment.attributeName.value(), *attachment.attributeName, attachment)) \
|
||||
return false; \
|
||||
} \
|
||||
else \
|
||||
attachment.attributeName = nullptr;
|
||||
|
||||
attachment.szDisplayName = m_memory.Dup(jAttachment.displayName.c_str());
|
||||
attachment.type = jAttachment.type;
|
||||
attachment.weaponType = jAttachment.weaponType;
|
||||
attachment.weapClass = jAttachment.weapClass;
|
||||
|
||||
CONVERT_XMODEL_ARRAY(worldModels, ATTACHMENT_WORLD_MODEL_COUNT)
|
||||
CONVERT_XMODEL_ARRAY(viewModels, ATTACHMENT_VIEW_MODEL_COUNT)
|
||||
CONVERT_XMODEL_ARRAY(reticleViewModels, ATTACHMENT_RETICLE_VIEW_MODEL_COUNT)
|
||||
|
||||
CONVERT_ATTRIBUTE(AttAmmoGeneral, ammoGeneral)
|
||||
CONVERT_ATTRIBUTE(AttSight, sight)
|
||||
CONVERT_ATTRIBUTE(AttReload, reload)
|
||||
CONVERT_ATTRIBUTE(AttAddOns, addOns)
|
||||
CONVERT_ATTRIBUTE(AttGeneral, general)
|
||||
CONVERT_ATTRIBUTE(AttAimAssist, aimAssist)
|
||||
CONVERT_ATTRIBUTE(AttAmmunition, ammunition)
|
||||
CONVERT_ATTRIBUTE(AttDamage, damage)
|
||||
CONVERT_ATTRIBUTE(AttLocationDamage, locationDamage)
|
||||
CONVERT_ATTRIBUTE(AttIdleSettings, idleSettings)
|
||||
CONVERT_ATTRIBUTE(AttADSSettings, adsSettings)
|
||||
CONVERT_ATTRIBUTE(AttADSSettings, adsSettingsMain)
|
||||
CONVERT_ATTRIBUTE(AttHipSpread, hipSpread)
|
||||
CONVERT_ATTRIBUTE(AttGunKick, gunKick)
|
||||
CONVERT_ATTRIBUTE(AttViewKick, viewKick)
|
||||
CONVERT_ATTRIBUTE(AttADSOverlay, adsOverlay)
|
||||
CONVERT_ATTRIBUTE(AttUI, ui)
|
||||
CONVERT_ATTRIBUTE(AttRumbles, rumbles)
|
||||
CONVERT_ATTRIBUTE(AttProjectile, projectile)
|
||||
|
||||
attachment.ammunitionScale = jAttachment.ammunitionScale;
|
||||
attachment.damageScale = jAttachment.damageScale;
|
||||
attachment.damageScaleMin = jAttachment.damageScaleMin;
|
||||
attachment.stateTimersScale = jAttachment.stateTimersScale;
|
||||
attachment.fireTimersScale = jAttachment.fireTimersScale;
|
||||
attachment.idleSettingsScale = jAttachment.idleSettingsScale;
|
||||
attachment.adsSettingsScale = jAttachment.adsSettingsScale;
|
||||
attachment.adsSettingsScaleMain = jAttachment.adsSettingsScaleMain;
|
||||
attachment.hipSpreadScale = jAttachment.hipSpreadScale;
|
||||
attachment.gunKickScale = jAttachment.gunKickScale;
|
||||
attachment.viewKickScale = jAttachment.viewKickScale;
|
||||
attachment.viewCenterScale = jAttachment.viewCenterScale;
|
||||
attachment.loadIndex = jAttachment.loadIndex;
|
||||
attachment.hideIronSightsWithThisAttachment = jAttachment.hideIronSightsWithThisAttachment;
|
||||
attachment.shareAmmoWithAlt = jAttachment.shareAmmoWithAlt;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateTracerFromJson(const std::string& assetName, TracerDef*& tracerPtr, const WeaponAttachment& attachment) const
|
||||
{
|
||||
auto* tracer = m_context.LoadDependency<AssetTracer>(assetName);
|
||||
if (!tracer)
|
||||
{
|
||||
PrintError(attachment, std::format("Could not find tracer {}", assetName));
|
||||
return false;
|
||||
}
|
||||
m_registration.AddDependency(tracer);
|
||||
tracerPtr = tracer->Asset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateMaterialFromJson(const std::string& assetName, Material*& materialPtr, const WeaponAttachment& attachment) const
|
||||
{
|
||||
auto* material = m_context.LoadDependency<AssetMaterial>(assetName);
|
||||
if (!material)
|
||||
{
|
||||
PrintError(attachment, std::format("Could not find material {}", assetName));
|
||||
return false;
|
||||
}
|
||||
m_registration.AddDependency(material);
|
||||
materialPtr = material->Asset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateFxFromJson(const std::string& assetName, FxEffectDef*& fxPtr, const WeaponAttachment& attachment) const
|
||||
{
|
||||
auto* fx = m_context.LoadDependency<AssetFx>(assetName);
|
||||
if (!fx)
|
||||
{
|
||||
PrintError(attachment, std::format("Could not find fx {}", assetName));
|
||||
return false;
|
||||
}
|
||||
m_registration.AddDependency(fx);
|
||||
fxPtr = fx->Asset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateSoundFromJson(const std::string& assetName, SndAliasCustom& sndAliasCustom, const WeaponAttachment& attachment) const
|
||||
{
|
||||
m_registration.AddIndirectAssetReference(m_context.LoadIndirectAssetReference<AssetSound>(assetName));
|
||||
sndAliasCustom.name = m_memory.Alloc<snd_alias_list_name>();
|
||||
sndAliasCustom.name->soundName = m_memory.Dup(assetName.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateXModelFromJson(const std::string& assetName, XModel*& xmodelPtr, const WeaponAttachment& attachment) const
|
||||
{
|
||||
auto* xmodel = m_context.LoadDependency<AssetXModel>(assetName);
|
||||
if (!xmodel)
|
||||
{
|
||||
PrintError(attachment, std::format("Could not find xmodel {}", assetName));
|
||||
return false;
|
||||
}
|
||||
m_registration.AddDependency(xmodel);
|
||||
xmodelPtr = xmodel->Asset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateXModelArrayFromJson(const std::vector<std::string>& jXmodelArray,
|
||||
XModel**& xmodelArray,
|
||||
const char* propertyName,
|
||||
size_t propertyCount,
|
||||
const WeaponAttachment& attachment) const
|
||||
{
|
||||
if (!jXmodelArray.empty())
|
||||
{
|
||||
const auto arraySize = jXmodelArray.size();
|
||||
if (arraySize > propertyCount)
|
||||
{
|
||||
PrintError(attachment, std::format("{} size cannot exceed {}", propertyName, propertyCount));
|
||||
return false;
|
||||
}
|
||||
xmodelArray = m_memory.Alloc<XModel*>(propertyCount);
|
||||
memset(xmodelArray, 0, sizeof(void*) * propertyCount);
|
||||
|
||||
for (auto i = 0u; i < arraySize; i++)
|
||||
{
|
||||
if (!CreateXModelFromJson(jXmodelArray[i], xmodelArray[i], attachment))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xmodelArray = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateAttAmmoGeneralFromJson(const JsonAttAmmoGeneral& jAmmoGeneral, AttAmmoGeneral& ammoGeneral, const WeaponAttachment& attachment) const
|
||||
{
|
||||
ammoGeneral.penetrateType = jAmmoGeneral.penetrateType;
|
||||
ammoGeneral.penetrateMultiplier = jAmmoGeneral.penetrateMultiplier;
|
||||
ammoGeneral.impactType = jAmmoGeneral.impactType;
|
||||
ammoGeneral.fireType = jAmmoGeneral.fireType;
|
||||
|
||||
if (jAmmoGeneral.tracerType)
|
||||
{
|
||||
if (!CreateTracerFromJson(jAmmoGeneral.tracerType.value(), ammoGeneral.tracerType, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
ammoGeneral.tracerType = nullptr;
|
||||
|
||||
ammoGeneral.rifleBullet = jAmmoGeneral.rifleBullet;
|
||||
ammoGeneral.armorPiercing = jAmmoGeneral.armorPiercing;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttSightFromJson(const JsonAttSight& jSight, AttSight& sight, const WeaponAttachment& attachment)
|
||||
{
|
||||
sight.aimDownSight = jSight.aimDownSight;
|
||||
sight.adsFire = jSight.adsFire;
|
||||
sight.rechamberWhileAds = jSight.rechamberWhileAds;
|
||||
sight.noAdsWhenMagEmpty = jSight.noAdsWhenMagEmpty;
|
||||
sight.canHoldBreath = jSight.canHoldBreath;
|
||||
sight.canVariableZoom = jSight.canVariableZoom;
|
||||
sight.hideRailWithThisScope = jSight.hideRailWithThisScope;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttReloadFromJson(const JsonAttReload& jReload, AttReload& reload, const WeaponAttachment& attachment)
|
||||
{
|
||||
reload.noPartialReload = jReload.noPartialReload;
|
||||
reload.segmentedReload = jReload.segmentedReload;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttAddOnsFromJson(const JsonAttAddOns& jAddOns, AttAddOns& addOns, const WeaponAttachment& attachment)
|
||||
{
|
||||
addOns.motionTracker = jAddOns.motionTracker;
|
||||
addOns.silenced = jAddOns.silenced;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateAttGeneralFromJson(const JsonAttGeneral& jGeneral, AttGeneral& general, const WeaponAttachment& attachment) const
|
||||
{
|
||||
general.boltAction = jGeneral.boltAction;
|
||||
general.inheritsPerks = jGeneral.inheritsPerks;
|
||||
general.enemyCrosshairRange = jGeneral.enemyCrosshairRange;
|
||||
|
||||
if (jGeneral.reticleCenter)
|
||||
{
|
||||
if (!CreateMaterialFromJson(jGeneral.reticleCenter.value(), general.reticleCenter, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
general.reticleCenter = nullptr;
|
||||
|
||||
if (jGeneral.reticleSide)
|
||||
{
|
||||
if (!CreateMaterialFromJson(jGeneral.reticleSide.value(), general.reticleSide, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
general.reticleSide = nullptr;
|
||||
|
||||
general.reticleCenterSize = jGeneral.reticleCenterSize;
|
||||
general.reticleSideSize = jGeneral.reticleSideSize;
|
||||
general.moveSpeedScale = jGeneral.moveSpeedScale;
|
||||
general.adsMoveSpeedScale = jGeneral.adsMoveSpeedScale;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttAimAssistFromJson(const JsonAttAimAssist& jAimAssist, AttAimAssist& aimAssist, const WeaponAttachment& attachment)
|
||||
{
|
||||
aimAssist.autoAimRange = jAimAssist.autoAimRange;
|
||||
aimAssist.aimAssistRange = jAimAssist.aimAssistRange;
|
||||
aimAssist.aimAssistRangeAds = jAimAssist.aimAssistRangeAds;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttAmmunitionFromJson(const JsonAttAmmunition& jAmmunition, AttAmmunition& ammunition, const WeaponAttachment& attachment)
|
||||
{
|
||||
ammunition.maxAmmo = jAmmunition.maxAmmo;
|
||||
ammunition.startAmmo = jAmmunition.startAmmo;
|
||||
ammunition.clipSize = jAmmunition.clipSize;
|
||||
ammunition.shotCount = jAmmunition.shotCount;
|
||||
ammunition.reloadAmmoAdd = jAmmunition.reloadAmmoAdd;
|
||||
ammunition.reloadStartAdd = jAmmunition.reloadStartAdd;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttDamageFromJson(const JsonAttDamage& jDamage, AttDamage& damage, const WeaponAttachment& attachment)
|
||||
{
|
||||
damage.damage = jDamage.damage;
|
||||
damage.minDamage = jDamage.minDamage;
|
||||
damage.meleeDamage = jDamage.meleeDamage;
|
||||
damage.maxDamageRange = jDamage.maxDamageRange;
|
||||
damage.minDamageRange = jDamage.minDamageRange;
|
||||
damage.playerDamage = jDamage.playerDamage;
|
||||
damage.minPlayerDamage = jDamage.minPlayerDamage;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CreateAttLocationDamageFromJson(const JsonAttLocationDamage& jLocationDamage, AttLocationDamage& locationDamage, const WeaponAttachment& attachment)
|
||||
{
|
||||
locationDamage.locNone = jLocationDamage.locNone;
|
||||
locationDamage.locHelmet = jLocationDamage.locHelmet;
|
||||
locationDamage.locHead = jLocationDamage.locHead;
|
||||
locationDamage.locNeck = jLocationDamage.locNeck;
|
||||
locationDamage.locTorsoUpper = jLocationDamage.locTorsoUpper;
|
||||
locationDamage.locTorsoLower = jLocationDamage.locTorsoLower;
|
||||
locationDamage.locRightArmUpper = jLocationDamage.locRightArmUpper;
|
||||
locationDamage.locRightArmLower = jLocationDamage.locRightArmLower;
|
||||
locationDamage.locRightHand = jLocationDamage.locRightHand;
|
||||
locationDamage.locLeftArmUpper = jLocationDamage.locLeftArmUpper;
|
||||
locationDamage.locLeftArmLower = jLocationDamage.locLeftArmLower;
|
||||
locationDamage.locLeftHand = jLocationDamage.locLeftHand;
|
||||
locationDamage.locRightLegUpper = jLocationDamage.locRightLegUpper;
|
||||
locationDamage.locRightLegLower = jLocationDamage.locRightLegLower;
|
||||
locationDamage.locRightFoot = jLocationDamage.locRightFoot;
|
||||
locationDamage.locLeftLegUpper = jLocationDamage.locLeftLegUpper;
|
||||
locationDamage.locLeftLegLower = jLocationDamage.locLeftLegLower;
|
||||
locationDamage.locLeftFoot = jLocationDamage.locLeftFoot;
|
||||
locationDamage.locGun = jLocationDamage.locGun;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttIdleSettingsFromJson(const JsonAttIdleSettings& jIdleSettings, AttIdleSettings& idleSettings, const WeaponAttachment& attachment)
|
||||
{
|
||||
idleSettings.hipIdleAmount = jIdleSettings.hipIdleAmount;
|
||||
idleSettings.hipIdleSpeed = jIdleSettings.hipIdleSpeed;
|
||||
idleSettings.idleCrouchFactor = jIdleSettings.idleCrouchFactor;
|
||||
idleSettings.idleProneFactor = jIdleSettings.idleProneFactor;
|
||||
idleSettings.adsIdleLerpStartTime = jIdleSettings.adsIdleLerpStartTime;
|
||||
idleSettings.adsIdleLerpTime = jIdleSettings.adsIdleLerpTime;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttADSSettingsFromJson(const JsonAttADSSettings& jAdsSettings, AttADSSettings& adsSettings, const WeaponAttachment& attachment)
|
||||
{
|
||||
adsSettings.adsSpread = jAdsSettings.adsSpread;
|
||||
adsSettings.adsAimPitch = jAdsSettings.adsAimPitch;
|
||||
adsSettings.adsTransInTime = jAdsSettings.adsTransInTime;
|
||||
adsSettings.adsTransOutTime = jAdsSettings.adsTransOutTime;
|
||||
adsSettings.adsReloadTransTime = jAdsSettings.adsReloadTransTime;
|
||||
adsSettings.adsCrosshairInFrac = jAdsSettings.adsCrosshairInFrac;
|
||||
adsSettings.adsCrosshairOutFrac = jAdsSettings.adsCrosshairOutFrac;
|
||||
adsSettings.adsZoomFov = jAdsSettings.adsZoomFov;
|
||||
adsSettings.adsZoomInFrac = jAdsSettings.adsZoomInFrac;
|
||||
adsSettings.adsZoomOutFrac = jAdsSettings.adsZoomOutFrac;
|
||||
adsSettings.adsBobFactor = jAdsSettings.adsBobFactor;
|
||||
adsSettings.adsViewBobMult = jAdsSettings.adsViewBobMult;
|
||||
adsSettings.adsViewErrorMin = jAdsSettings.adsViewErrorMin;
|
||||
adsSettings.adsViewErrorMax = jAdsSettings.adsViewErrorMax;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttHipSpreadFromJson(const JsonAttHipSpread& jHipSpread, AttHipSpread& hipSpread, const WeaponAttachment& attachment)
|
||||
{
|
||||
hipSpread.hipSpreadStandMin = jHipSpread.hipSpreadStandMin;
|
||||
hipSpread.hipSpreadDuckedMin = jHipSpread.hipSpreadDuckedMin;
|
||||
hipSpread.hipSpreadProneMin = jHipSpread.hipSpreadProneMin;
|
||||
hipSpread.hipSpreadMax = jHipSpread.hipSpreadMax;
|
||||
hipSpread.hipSpreadDuckedMax = jHipSpread.hipSpreadDuckedMax;
|
||||
hipSpread.hipSpreadProneMax = jHipSpread.hipSpreadProneMax;
|
||||
hipSpread.hipSpreadFireAdd = jHipSpread.hipSpreadFireAdd;
|
||||
hipSpread.hipSpreadTurnAdd = jHipSpread.hipSpreadTurnAdd;
|
||||
hipSpread.hipSpreadMoveAdd = jHipSpread.hipSpreadMoveAdd;
|
||||
hipSpread.hipSpreadDecayRate = jHipSpread.hipSpreadDecayRate;
|
||||
hipSpread.hipSpreadDuckedDecay = jHipSpread.hipSpreadDuckedDecay;
|
||||
hipSpread.hipSpreadProneDecay = jHipSpread.hipSpreadProneDecay;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttGunKickFromJson(const JsonAttGunKick& jGunKick, AttGunKick& gunKick, const WeaponAttachment& attachment)
|
||||
{
|
||||
gunKick.hipGunKickReducedKickBullets = jGunKick.hipGunKickReducedKickBullets;
|
||||
gunKick.hipGunKickReducedKickPercent = jGunKick.hipGunKickReducedKickPercent;
|
||||
gunKick.hipGunKickPitchMin = jGunKick.hipGunKickPitchMin;
|
||||
gunKick.hipGunKickPitchMax = jGunKick.hipGunKickPitchMax;
|
||||
gunKick.hipGunKickYawMin = jGunKick.hipGunKickYawMin;
|
||||
gunKick.hipGunKickYawMax = jGunKick.hipGunKickYawMax;
|
||||
gunKick.hipGunKickAccel = jGunKick.hipGunKickAccel;
|
||||
gunKick.hipGunKickSpeedMax = jGunKick.hipGunKickSpeedMax;
|
||||
gunKick.hipGunKickSpeedDecay = jGunKick.hipGunKickSpeedDecay;
|
||||
gunKick.hipGunKickStaticDecay = jGunKick.hipGunKickStaticDecay;
|
||||
gunKick.adsGunKickReducedKickBullets = jGunKick.adsGunKickReducedKickBullets;
|
||||
gunKick.adsGunKickReducedKickPercent = jGunKick.adsGunKickReducedKickPercent;
|
||||
gunKick.adsGunKickPitchMin = jGunKick.adsGunKickPitchMin;
|
||||
gunKick.adsGunKickPitchMax = jGunKick.adsGunKickPitchMax;
|
||||
gunKick.adsGunKickYawMin = jGunKick.adsGunKickYawMin;
|
||||
gunKick.adsGunKickYawMax = jGunKick.adsGunKickYawMax;
|
||||
gunKick.adsGunKickAccel = jGunKick.adsGunKickAccel;
|
||||
gunKick.adsGunKickSpeedMax = jGunKick.adsGunKickSpeedMax;
|
||||
gunKick.adsGunKickSpeedDecay = jGunKick.adsGunKickSpeedDecay;
|
||||
gunKick.adsGunKickStaticDecay = jGunKick.adsGunKickStaticDecay;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttViewKickFromJson(const JsonAttViewKick& jViewKick, AttViewKick& viewKick, const WeaponAttachment& attachment)
|
||||
{
|
||||
viewKick.hipViewKickPitchMin = jViewKick.hipViewKickPitchMin;
|
||||
viewKick.hipViewKickPitchMax = jViewKick.hipViewKickPitchMax;
|
||||
viewKick.hipViewKickYawMin = jViewKick.hipViewKickYawMin;
|
||||
viewKick.hipViewKickYawMax = jViewKick.hipViewKickYawMax;
|
||||
viewKick.hipViewKickCenterSpeed = jViewKick.hipViewKickCenterSpeed;
|
||||
viewKick.adsViewKickPitchMin = jViewKick.adsViewKickPitchMin;
|
||||
viewKick.adsViewKickPitchMax = jViewKick.adsViewKickPitchMax;
|
||||
viewKick.adsViewKickYawMin = jViewKick.adsViewKickYawMin;
|
||||
viewKick.adsViewKickYawMax = jViewKick.adsViewKickYawMax;
|
||||
viewKick.adsViewKickCenterSpeed = jViewKick.adsViewKickCenterSpeed;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateAttADSOverlayFromJson(const JsonAttADSOverlay& jAdsOverlay, AttADSOverlay& adsOverlay, const WeaponAttachment& attachment) const
|
||||
{
|
||||
if (jAdsOverlay.shader)
|
||||
{
|
||||
if (!CreateMaterialFromJson(jAdsOverlay.shader.value(), adsOverlay.overlay.shader, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
adsOverlay.overlay.shader = nullptr;
|
||||
|
||||
if (jAdsOverlay.shaderLowRes)
|
||||
{
|
||||
if (!CreateMaterialFromJson(jAdsOverlay.shaderLowRes.value(), adsOverlay.overlay.shaderLowRes, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
adsOverlay.overlay.shaderLowRes = nullptr;
|
||||
|
||||
if (jAdsOverlay.shaderEMP)
|
||||
{
|
||||
if (!CreateMaterialFromJson(jAdsOverlay.shaderEMP.value(), adsOverlay.overlay.shaderEMP, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
adsOverlay.overlay.shaderEMP = nullptr;
|
||||
|
||||
if (jAdsOverlay.shaderEMPLowRes)
|
||||
{
|
||||
if (!CreateMaterialFromJson(jAdsOverlay.shaderEMPLowRes.value(), adsOverlay.overlay.shaderEMPLowRes, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
adsOverlay.overlay.shaderEMPLowRes = nullptr;
|
||||
|
||||
adsOverlay.overlay.reticle = jAdsOverlay.reticle;
|
||||
adsOverlay.overlay.width = jAdsOverlay.width;
|
||||
adsOverlay.overlay.height = jAdsOverlay.height;
|
||||
adsOverlay.overlay.widthSplitscreen = jAdsOverlay.widthSplitscreen;
|
||||
adsOverlay.overlay.heightSplitscreen = jAdsOverlay.heightSplitscreen;
|
||||
adsOverlay.thermalScope = jAdsOverlay.thermalScope;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateAttUIFromJson(const JsonAttUI& jUi, AttUI& ui, const WeaponAttachment& attachment) const
|
||||
{
|
||||
if (jUi.dpadIcon)
|
||||
{
|
||||
if (!CreateMaterialFromJson(jUi.dpadIcon.value(), ui.dpadIcon, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
ui.dpadIcon = nullptr;
|
||||
|
||||
if (jUi.ammoCounterIcon)
|
||||
{
|
||||
if (!CreateMaterialFromJson(jUi.ammoCounterIcon.value(), ui.ammoCounterIcon, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
ui.ammoCounterIcon = nullptr;
|
||||
|
||||
ui.dpadIconRatio = jUi.dpadIconRatio;
|
||||
ui.ammoCounterIconRatio = jUi.ammoCounterIconRatio;
|
||||
ui.ammoCounterClip = jUi.ammoCounterClip;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateAttRumblesFromJson(const JsonAttRumbles& jRumbles, AttRumbles& rumbles, const WeaponAttachment& attachment) const
|
||||
{
|
||||
if (jRumbles.fireRumble)
|
||||
rumbles.fireRumble = m_memory.Dup(jRumbles.fireRumble.value().c_str());
|
||||
else
|
||||
rumbles.fireRumble = nullptr;
|
||||
|
||||
if (jRumbles.meleeImpactRumble)
|
||||
rumbles.meleeImpactRumble = m_memory.Dup(jRumbles.meleeImpactRumble.value().c_str());
|
||||
else
|
||||
rumbles.meleeImpactRumble = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateAttProjectileFromJson(const JsonAttProjectile& jProjectile, AttProjectile& projectile, const WeaponAttachment& attachment) const
|
||||
{
|
||||
projectile.explosionRadius = jProjectile.explosionRadius;
|
||||
projectile.explosionInnerDamage = jProjectile.explosionInnerDamage;
|
||||
projectile.explosionOuterDamage = jProjectile.explosionOuterDamage;
|
||||
projectile.damageConeAngle = jProjectile.damageConeAngle;
|
||||
projectile.projectileSpeed = jProjectile.projectileSpeed;
|
||||
projectile.projectileSpeedUp = jProjectile.projectileSpeedUp;
|
||||
projectile.projectileActivateDist = jProjectile.projectileActivateDist;
|
||||
projectile.projectileLifetime = jProjectile.projectileLifetime;
|
||||
|
||||
if (jProjectile.projectileModel)
|
||||
{
|
||||
if (!CreateXModelFromJson(jProjectile.projectileModel.value(), projectile.projectileModel, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
projectile.projectileModel = nullptr;
|
||||
|
||||
projectile.projExplosionType = jProjectile.projExplosionType;
|
||||
|
||||
if (jProjectile.projExplosionEffect)
|
||||
{
|
||||
if (!CreateFxFromJson(jProjectile.projExplosionEffect.value(), projectile.projExplosionEffect, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
projectile.projExplosionEffect = nullptr;
|
||||
|
||||
projectile.projExplosionEffectForceNormalUp = jProjectile.projExplosionEffectForceNormalUp;
|
||||
|
||||
if (jProjectile.projExplosionSound)
|
||||
{
|
||||
if (!CreateSoundFromJson(jProjectile.projExplosionSound.value(), projectile.projExplosionSound, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
projectile.projExplosionSound.name = nullptr;
|
||||
|
||||
if (jProjectile.projDudEffect)
|
||||
{
|
||||
if (!CreateFxFromJson(jProjectile.projDudEffect.value(), projectile.projDudEffect, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
projectile.projDudEffect = nullptr;
|
||||
|
||||
if (jProjectile.projDudSound)
|
||||
{
|
||||
if (!CreateSoundFromJson(jProjectile.projDudSound.value(), projectile.projDudSound, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
projectile.projDudSound.name = nullptr;
|
||||
|
||||
projectile.projImpactExplode = jProjectile.projImpactExplode;
|
||||
projectile.destabilizationRateTime = jProjectile.destabilizationRateTime;
|
||||
projectile.destabilizationCurvatureMax = jProjectile.destabilizationCurvatureMax;
|
||||
projectile.destabilizeDistance = jProjectile.destabilizeDistance;
|
||||
|
||||
if (jProjectile.projTrailEffect)
|
||||
{
|
||||
if (!CreateFxFromJson(jProjectile.projTrailEffect.value(), projectile.projTrailEffect, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
projectile.projTrailEffect = nullptr;
|
||||
|
||||
projectile.projIgnitionDelay = jProjectile.projIgnitionDelay;
|
||||
|
||||
if (jProjectile.projIgnitionEffect)
|
||||
{
|
||||
if (!CreateFxFromJson(jProjectile.projIgnitionEffect.value(), projectile.projIgnitionEffect, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
projectile.projIgnitionEffect = nullptr;
|
||||
|
||||
if (jProjectile.projIgnitionSound)
|
||||
{
|
||||
if (!CreateSoundFromJson(jProjectile.projIgnitionSound.value(), projectile.projIgnitionSound, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
projectile.projIgnitionSound.name = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::istream& m_stream;
|
||||
MemoryManager& m_memory;
|
||||
AssetCreationContext& m_context;
|
||||
AssetRegistration<AssetAttachment>& m_registration;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
bool LoadWeaponAttachmentAsJson(std::istream& stream,
|
||||
WeaponAttachment& attachment,
|
||||
MemoryManager& memory,
|
||||
AssetCreationContext& context,
|
||||
AssetRegistration<AssetAttachment>& registration)
|
||||
{
|
||||
const JsonLoader loader(stream, memory, context, registration);
|
||||
|
||||
return loader.Load(attachment);
|
||||
}
|
||||
} // namespace IW5
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/AssetCreationContext.h"
|
||||
#include "Asset/AssetRegistration.h"
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <istream>
|
||||
|
||||
namespace IW5
|
||||
{
|
||||
bool LoadWeaponAttachmentAsJson(std::istream& stream,
|
||||
WeaponAttachment& attachment,
|
||||
MemoryManager& memory,
|
||||
AssetCreationContext& context,
|
||||
AssetRegistration<AssetAttachment>& registration);
|
||||
} // namespace IW5
|
||||
@@ -1,16 +1,637 @@
|
||||
#include "LoaderAttachmentIW5.h"
|
||||
|
||||
#include "Game/IW5/IW5.h"
|
||||
#include "JsonWeaponAttachmentLoader.h"
|
||||
#include "Game/IW5/Weapon/JsonWeaponAttachment.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
#include "Weapon/AttachmentCommon.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using namespace nlohmann;
|
||||
using namespace IW5;
|
||||
|
||||
namespace
|
||||
{
|
||||
class JsonLoader
|
||||
{
|
||||
public:
|
||||
JsonLoader(std::istream& stream, MemoryManager& memory, AssetCreationContext& context, AssetRegistration<AssetAttachment>& registration)
|
||||
: m_stream(stream),
|
||||
m_memory(memory),
|
||||
m_context(context),
|
||||
m_registration(registration)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
bool Load(WeaponAttachment& attachment) const
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto jRoot = json::parse(m_stream);
|
||||
std::string type;
|
||||
unsigned version;
|
||||
|
||||
jRoot.at("_type").get_to(type);
|
||||
jRoot.at("_version").get_to(version);
|
||||
|
||||
if (type != "attachment" || version != 1u)
|
||||
{
|
||||
con::error("Tried to load attachment \"{}\" but did not find expected type attachment of version 1", attachment.szInternalName);
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto jAttachment = jRoot.get<JsonWeaponAttachment>();
|
||||
return CreateWeaponAttachmentFromJson(jAttachment, attachment);
|
||||
}
|
||||
catch (const json::exception& e)
|
||||
{
|
||||
con::error("Failed to parse json of attachment: {}", e.what());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
static void PrintError(const WeaponAttachment& attachment, const std::string& message)
|
||||
{
|
||||
con::error("Cannot load attachment \"{}\": {}", attachment.szInternalName, message);
|
||||
}
|
||||
|
||||
bool CreateWeaponAttachmentFromJson(const JsonWeaponAttachment& jAttachment, WeaponAttachment& attachment) const
|
||||
{
|
||||
#define CONVERT_XMODEL_ARRAY(propertyName, count) \
|
||||
CreateXModelArrayFromJson(jAttachment.propertyName, attachment.propertyName, #propertyName, count, attachment);
|
||||
|
||||
#define CONVERT_ATTRIBUTE(attributeClass, attributeName) \
|
||||
if (jAttachment.attributeName) \
|
||||
{ \
|
||||
using AttributeType = std::remove_pointer_t<decltype(attachment.attributeName)>; \
|
||||
attachment.attributeName = m_memory.Alloc<AttributeType>(); \
|
||||
if (!Create##attributeClass##FromJson(jAttachment.attributeName.value(), *attachment.attributeName, attachment)) \
|
||||
return false; \
|
||||
} \
|
||||
else \
|
||||
attachment.attributeName = nullptr;
|
||||
|
||||
attachment.szDisplayName = m_memory.Dup(jAttachment.displayName.c_str());
|
||||
attachment.type = jAttachment.type;
|
||||
attachment.weaponType = jAttachment.weaponType;
|
||||
attachment.weapClass = jAttachment.weapClass;
|
||||
|
||||
CONVERT_XMODEL_ARRAY(worldModels, ATTACHMENT_WORLD_MODEL_COUNT)
|
||||
CONVERT_XMODEL_ARRAY(viewModels, ATTACHMENT_VIEW_MODEL_COUNT)
|
||||
CONVERT_XMODEL_ARRAY(reticleViewModels, ATTACHMENT_RETICLE_VIEW_MODEL_COUNT)
|
||||
|
||||
CONVERT_ATTRIBUTE(AttAmmoGeneral, ammoGeneral)
|
||||
CONVERT_ATTRIBUTE(AttSight, sight)
|
||||
CONVERT_ATTRIBUTE(AttReload, reload)
|
||||
CONVERT_ATTRIBUTE(AttAddOns, addOns)
|
||||
CONVERT_ATTRIBUTE(AttGeneral, general)
|
||||
CONVERT_ATTRIBUTE(AttAimAssist, aimAssist)
|
||||
CONVERT_ATTRIBUTE(AttAmmunition, ammunition)
|
||||
CONVERT_ATTRIBUTE(AttDamage, damage)
|
||||
CONVERT_ATTRIBUTE(AttLocationDamage, locationDamage)
|
||||
CONVERT_ATTRIBUTE(AttIdleSettings, idleSettings)
|
||||
CONVERT_ATTRIBUTE(AttADSSettings, adsSettings)
|
||||
CONVERT_ATTRIBUTE(AttADSSettings, adsSettingsMain)
|
||||
CONVERT_ATTRIBUTE(AttHipSpread, hipSpread)
|
||||
CONVERT_ATTRIBUTE(AttGunKick, gunKick)
|
||||
CONVERT_ATTRIBUTE(AttViewKick, viewKick)
|
||||
CONVERT_ATTRIBUTE(AttADSOverlay, adsOverlay)
|
||||
CONVERT_ATTRIBUTE(AttUI, ui)
|
||||
CONVERT_ATTRIBUTE(AttRumbles, rumbles)
|
||||
CONVERT_ATTRIBUTE(AttProjectile, projectile)
|
||||
|
||||
attachment.ammunitionScale = jAttachment.ammunitionScale;
|
||||
attachment.damageScale = jAttachment.damageScale;
|
||||
attachment.damageScaleMin = jAttachment.damageScaleMin;
|
||||
attachment.stateTimersScale = jAttachment.stateTimersScale;
|
||||
attachment.fireTimersScale = jAttachment.fireTimersScale;
|
||||
attachment.idleSettingsScale = jAttachment.idleSettingsScale;
|
||||
attachment.adsSettingsScale = jAttachment.adsSettingsScale;
|
||||
attachment.adsSettingsScaleMain = jAttachment.adsSettingsScaleMain;
|
||||
attachment.hipSpreadScale = jAttachment.hipSpreadScale;
|
||||
attachment.gunKickScale = jAttachment.gunKickScale;
|
||||
attachment.viewKickScale = jAttachment.viewKickScale;
|
||||
attachment.viewCenterScale = jAttachment.viewCenterScale;
|
||||
attachment.loadIndex = jAttachment.loadIndex;
|
||||
attachment.hideIronSightsWithThisAttachment = jAttachment.hideIronSightsWithThisAttachment;
|
||||
attachment.shareAmmoWithAlt = jAttachment.shareAmmoWithAlt;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateTracerFromJson(const std::string& assetName, TracerDef*& tracerPtr, const WeaponAttachment& attachment) const
|
||||
{
|
||||
auto* tracer = m_context.LoadDependency<AssetTracer>(assetName);
|
||||
if (!tracer)
|
||||
{
|
||||
PrintError(attachment, std::format("Could not find tracer {}", assetName));
|
||||
return false;
|
||||
}
|
||||
m_registration.AddDependency(tracer);
|
||||
tracerPtr = tracer->Asset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateMaterialFromJson(const std::string& assetName, Material*& materialPtr, const WeaponAttachment& attachment) const
|
||||
{
|
||||
auto* material = m_context.LoadDependency<AssetMaterial>(assetName);
|
||||
if (!material)
|
||||
{
|
||||
PrintError(attachment, std::format("Could not find material {}", assetName));
|
||||
return false;
|
||||
}
|
||||
m_registration.AddDependency(material);
|
||||
materialPtr = material->Asset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateFxFromJson(const std::string& assetName, FxEffectDef*& fxPtr, const WeaponAttachment& attachment) const
|
||||
{
|
||||
auto* fx = m_context.LoadDependency<AssetFx>(assetName);
|
||||
if (!fx)
|
||||
{
|
||||
PrintError(attachment, std::format("Could not find fx {}", assetName));
|
||||
return false;
|
||||
}
|
||||
m_registration.AddDependency(fx);
|
||||
fxPtr = fx->Asset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateSoundFromJson(const std::string& assetName, SndAliasCustom& sndAliasCustom, const WeaponAttachment& attachment) const
|
||||
{
|
||||
m_registration.AddIndirectAssetReference(m_context.LoadIndirectAssetReference<AssetSound>(assetName));
|
||||
sndAliasCustom.name = m_memory.Alloc<snd_alias_list_name>();
|
||||
sndAliasCustom.name->soundName = m_memory.Dup(assetName.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateXModelFromJson(const std::string& assetName, XModel*& xmodelPtr, const WeaponAttachment& attachment) const
|
||||
{
|
||||
auto* xmodel = m_context.LoadDependency<AssetXModel>(assetName);
|
||||
if (!xmodel)
|
||||
{
|
||||
PrintError(attachment, std::format("Could not find xmodel {}", assetName));
|
||||
return false;
|
||||
}
|
||||
m_registration.AddDependency(xmodel);
|
||||
xmodelPtr = xmodel->Asset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateXModelArrayFromJson(const std::vector<std::string>& jXmodelArray,
|
||||
XModel**& xmodelArray,
|
||||
const char* propertyName,
|
||||
size_t propertyCount,
|
||||
const WeaponAttachment& attachment) const
|
||||
{
|
||||
if (!jXmodelArray.empty())
|
||||
{
|
||||
const auto arraySize = jXmodelArray.size();
|
||||
if (arraySize > propertyCount)
|
||||
{
|
||||
PrintError(attachment, std::format("{} size cannot exceed {}", propertyName, propertyCount));
|
||||
return false;
|
||||
}
|
||||
xmodelArray = m_memory.Alloc<XModel*>(propertyCount);
|
||||
memset(xmodelArray, 0, sizeof(void*) * propertyCount);
|
||||
|
||||
for (auto i = 0u; i < arraySize; i++)
|
||||
{
|
||||
if (!CreateXModelFromJson(jXmodelArray[i], xmodelArray[i], attachment))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xmodelArray = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateAttAmmoGeneralFromJson(const JsonAttAmmoGeneral& jAmmoGeneral, AttAmmoGeneral& ammoGeneral, const WeaponAttachment& attachment) const
|
||||
{
|
||||
ammoGeneral.penetrateType = jAmmoGeneral.penetrateType;
|
||||
ammoGeneral.penetrateMultiplier = jAmmoGeneral.penetrateMultiplier;
|
||||
ammoGeneral.impactType = jAmmoGeneral.impactType;
|
||||
ammoGeneral.fireType = jAmmoGeneral.fireType;
|
||||
|
||||
if (jAmmoGeneral.tracerType)
|
||||
{
|
||||
if (!CreateTracerFromJson(jAmmoGeneral.tracerType.value(), ammoGeneral.tracerType, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
ammoGeneral.tracerType = nullptr;
|
||||
|
||||
ammoGeneral.rifleBullet = jAmmoGeneral.rifleBullet;
|
||||
ammoGeneral.armorPiercing = jAmmoGeneral.armorPiercing;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttSightFromJson(const JsonAttSight& jSight, AttSight& sight, const WeaponAttachment& attachment)
|
||||
{
|
||||
sight.aimDownSight = jSight.aimDownSight;
|
||||
sight.adsFire = jSight.adsFire;
|
||||
sight.rechamberWhileAds = jSight.rechamberWhileAds;
|
||||
sight.noAdsWhenMagEmpty = jSight.noAdsWhenMagEmpty;
|
||||
sight.canHoldBreath = jSight.canHoldBreath;
|
||||
sight.canVariableZoom = jSight.canVariableZoom;
|
||||
sight.hideRailWithThisScope = jSight.hideRailWithThisScope;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttReloadFromJson(const JsonAttReload& jReload, AttReload& reload, const WeaponAttachment& attachment)
|
||||
{
|
||||
reload.noPartialReload = jReload.noPartialReload;
|
||||
reload.segmentedReload = jReload.segmentedReload;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttAddOnsFromJson(const JsonAttAddOns& jAddOns, AttAddOns& addOns, const WeaponAttachment& attachment)
|
||||
{
|
||||
addOns.motionTracker = jAddOns.motionTracker;
|
||||
addOns.silenced = jAddOns.silenced;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateAttGeneralFromJson(const JsonAttGeneral& jGeneral, AttGeneral& general, const WeaponAttachment& attachment) const
|
||||
{
|
||||
general.boltAction = jGeneral.boltAction;
|
||||
general.inheritsPerks = jGeneral.inheritsPerks;
|
||||
general.enemyCrosshairRange = jGeneral.enemyCrosshairRange;
|
||||
|
||||
if (jGeneral.reticleCenter)
|
||||
{
|
||||
if (!CreateMaterialFromJson(jGeneral.reticleCenter.value(), general.reticleCenter, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
general.reticleCenter = nullptr;
|
||||
|
||||
if (jGeneral.reticleSide)
|
||||
{
|
||||
if (!CreateMaterialFromJson(jGeneral.reticleSide.value(), general.reticleSide, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
general.reticleSide = nullptr;
|
||||
|
||||
general.reticleCenterSize = jGeneral.reticleCenterSize;
|
||||
general.reticleSideSize = jGeneral.reticleSideSize;
|
||||
general.moveSpeedScale = jGeneral.moveSpeedScale;
|
||||
general.adsMoveSpeedScale = jGeneral.adsMoveSpeedScale;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttAimAssistFromJson(const JsonAttAimAssist& jAimAssist, AttAimAssist& aimAssist, const WeaponAttachment& attachment)
|
||||
{
|
||||
aimAssist.autoAimRange = jAimAssist.autoAimRange;
|
||||
aimAssist.aimAssistRange = jAimAssist.aimAssistRange;
|
||||
aimAssist.aimAssistRangeAds = jAimAssist.aimAssistRangeAds;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttAmmunitionFromJson(const JsonAttAmmunition& jAmmunition, AttAmmunition& ammunition, const WeaponAttachment& attachment)
|
||||
{
|
||||
ammunition.maxAmmo = jAmmunition.maxAmmo;
|
||||
ammunition.startAmmo = jAmmunition.startAmmo;
|
||||
ammunition.clipSize = jAmmunition.clipSize;
|
||||
ammunition.shotCount = jAmmunition.shotCount;
|
||||
ammunition.reloadAmmoAdd = jAmmunition.reloadAmmoAdd;
|
||||
ammunition.reloadStartAdd = jAmmunition.reloadStartAdd;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttDamageFromJson(const JsonAttDamage& jDamage, AttDamage& damage, const WeaponAttachment& attachment)
|
||||
{
|
||||
damage.damage = jDamage.damage;
|
||||
damage.minDamage = jDamage.minDamage;
|
||||
damage.meleeDamage = jDamage.meleeDamage;
|
||||
damage.maxDamageRange = jDamage.maxDamageRange;
|
||||
damage.minDamageRange = jDamage.minDamageRange;
|
||||
damage.playerDamage = jDamage.playerDamage;
|
||||
damage.minPlayerDamage = jDamage.minPlayerDamage;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CreateAttLocationDamageFromJson(const JsonAttLocationDamage& jLocationDamage, AttLocationDamage& locationDamage, const WeaponAttachment& attachment)
|
||||
{
|
||||
locationDamage.locNone = jLocationDamage.locNone;
|
||||
locationDamage.locHelmet = jLocationDamage.locHelmet;
|
||||
locationDamage.locHead = jLocationDamage.locHead;
|
||||
locationDamage.locNeck = jLocationDamage.locNeck;
|
||||
locationDamage.locTorsoUpper = jLocationDamage.locTorsoUpper;
|
||||
locationDamage.locTorsoLower = jLocationDamage.locTorsoLower;
|
||||
locationDamage.locRightArmUpper = jLocationDamage.locRightArmUpper;
|
||||
locationDamage.locRightArmLower = jLocationDamage.locRightArmLower;
|
||||
locationDamage.locRightHand = jLocationDamage.locRightHand;
|
||||
locationDamage.locLeftArmUpper = jLocationDamage.locLeftArmUpper;
|
||||
locationDamage.locLeftArmLower = jLocationDamage.locLeftArmLower;
|
||||
locationDamage.locLeftHand = jLocationDamage.locLeftHand;
|
||||
locationDamage.locRightLegUpper = jLocationDamage.locRightLegUpper;
|
||||
locationDamage.locRightLegLower = jLocationDamage.locRightLegLower;
|
||||
locationDamage.locRightFoot = jLocationDamage.locRightFoot;
|
||||
locationDamage.locLeftLegUpper = jLocationDamage.locLeftLegUpper;
|
||||
locationDamage.locLeftLegLower = jLocationDamage.locLeftLegLower;
|
||||
locationDamage.locLeftFoot = jLocationDamage.locLeftFoot;
|
||||
locationDamage.locGun = jLocationDamage.locGun;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttIdleSettingsFromJson(const JsonAttIdleSettings& jIdleSettings, AttIdleSettings& idleSettings, const WeaponAttachment& attachment)
|
||||
{
|
||||
idleSettings.hipIdleAmount = jIdleSettings.hipIdleAmount;
|
||||
idleSettings.hipIdleSpeed = jIdleSettings.hipIdleSpeed;
|
||||
idleSettings.idleCrouchFactor = jIdleSettings.idleCrouchFactor;
|
||||
idleSettings.idleProneFactor = jIdleSettings.idleProneFactor;
|
||||
idleSettings.adsIdleLerpStartTime = jIdleSettings.adsIdleLerpStartTime;
|
||||
idleSettings.adsIdleLerpTime = jIdleSettings.adsIdleLerpTime;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttADSSettingsFromJson(const JsonAttADSSettings& jAdsSettings, AttADSSettings& adsSettings, const WeaponAttachment& attachment)
|
||||
{
|
||||
adsSettings.adsSpread = jAdsSettings.adsSpread;
|
||||
adsSettings.adsAimPitch = jAdsSettings.adsAimPitch;
|
||||
adsSettings.adsTransInTime = jAdsSettings.adsTransInTime;
|
||||
adsSettings.adsTransOutTime = jAdsSettings.adsTransOutTime;
|
||||
adsSettings.adsReloadTransTime = jAdsSettings.adsReloadTransTime;
|
||||
adsSettings.adsCrosshairInFrac = jAdsSettings.adsCrosshairInFrac;
|
||||
adsSettings.adsCrosshairOutFrac = jAdsSettings.adsCrosshairOutFrac;
|
||||
adsSettings.adsZoomFov = jAdsSettings.adsZoomFov;
|
||||
adsSettings.adsZoomInFrac = jAdsSettings.adsZoomInFrac;
|
||||
adsSettings.adsZoomOutFrac = jAdsSettings.adsZoomOutFrac;
|
||||
adsSettings.adsBobFactor = jAdsSettings.adsBobFactor;
|
||||
adsSettings.adsViewBobMult = jAdsSettings.adsViewBobMult;
|
||||
adsSettings.adsViewErrorMin = jAdsSettings.adsViewErrorMin;
|
||||
adsSettings.adsViewErrorMax = jAdsSettings.adsViewErrorMax;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttHipSpreadFromJson(const JsonAttHipSpread& jHipSpread, AttHipSpread& hipSpread, const WeaponAttachment& attachment)
|
||||
{
|
||||
hipSpread.hipSpreadStandMin = jHipSpread.hipSpreadStandMin;
|
||||
hipSpread.hipSpreadDuckedMin = jHipSpread.hipSpreadDuckedMin;
|
||||
hipSpread.hipSpreadProneMin = jHipSpread.hipSpreadProneMin;
|
||||
hipSpread.hipSpreadMax = jHipSpread.hipSpreadMax;
|
||||
hipSpread.hipSpreadDuckedMax = jHipSpread.hipSpreadDuckedMax;
|
||||
hipSpread.hipSpreadProneMax = jHipSpread.hipSpreadProneMax;
|
||||
hipSpread.hipSpreadFireAdd = jHipSpread.hipSpreadFireAdd;
|
||||
hipSpread.hipSpreadTurnAdd = jHipSpread.hipSpreadTurnAdd;
|
||||
hipSpread.hipSpreadMoveAdd = jHipSpread.hipSpreadMoveAdd;
|
||||
hipSpread.hipSpreadDecayRate = jHipSpread.hipSpreadDecayRate;
|
||||
hipSpread.hipSpreadDuckedDecay = jHipSpread.hipSpreadDuckedDecay;
|
||||
hipSpread.hipSpreadProneDecay = jHipSpread.hipSpreadProneDecay;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttGunKickFromJson(const JsonAttGunKick& jGunKick, AttGunKick& gunKick, const WeaponAttachment& attachment)
|
||||
{
|
||||
gunKick.hipGunKickReducedKickBullets = jGunKick.hipGunKickReducedKickBullets;
|
||||
gunKick.hipGunKickReducedKickPercent = jGunKick.hipGunKickReducedKickPercent;
|
||||
gunKick.hipGunKickPitchMin = jGunKick.hipGunKickPitchMin;
|
||||
gunKick.hipGunKickPitchMax = jGunKick.hipGunKickPitchMax;
|
||||
gunKick.hipGunKickYawMin = jGunKick.hipGunKickYawMin;
|
||||
gunKick.hipGunKickYawMax = jGunKick.hipGunKickYawMax;
|
||||
gunKick.hipGunKickAccel = jGunKick.hipGunKickAccel;
|
||||
gunKick.hipGunKickSpeedMax = jGunKick.hipGunKickSpeedMax;
|
||||
gunKick.hipGunKickSpeedDecay = jGunKick.hipGunKickSpeedDecay;
|
||||
gunKick.hipGunKickStaticDecay = jGunKick.hipGunKickStaticDecay;
|
||||
gunKick.adsGunKickReducedKickBullets = jGunKick.adsGunKickReducedKickBullets;
|
||||
gunKick.adsGunKickReducedKickPercent = jGunKick.adsGunKickReducedKickPercent;
|
||||
gunKick.adsGunKickPitchMin = jGunKick.adsGunKickPitchMin;
|
||||
gunKick.adsGunKickPitchMax = jGunKick.adsGunKickPitchMax;
|
||||
gunKick.adsGunKickYawMin = jGunKick.adsGunKickYawMin;
|
||||
gunKick.adsGunKickYawMax = jGunKick.adsGunKickYawMax;
|
||||
gunKick.adsGunKickAccel = jGunKick.adsGunKickAccel;
|
||||
gunKick.adsGunKickSpeedMax = jGunKick.adsGunKickSpeedMax;
|
||||
gunKick.adsGunKickSpeedDecay = jGunKick.adsGunKickSpeedDecay;
|
||||
gunKick.adsGunKickStaticDecay = jGunKick.adsGunKickStaticDecay;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CreateAttViewKickFromJson(const JsonAttViewKick& jViewKick, AttViewKick& viewKick, const WeaponAttachment& attachment)
|
||||
{
|
||||
viewKick.hipViewKickPitchMin = jViewKick.hipViewKickPitchMin;
|
||||
viewKick.hipViewKickPitchMax = jViewKick.hipViewKickPitchMax;
|
||||
viewKick.hipViewKickYawMin = jViewKick.hipViewKickYawMin;
|
||||
viewKick.hipViewKickYawMax = jViewKick.hipViewKickYawMax;
|
||||
viewKick.hipViewKickCenterSpeed = jViewKick.hipViewKickCenterSpeed;
|
||||
viewKick.adsViewKickPitchMin = jViewKick.adsViewKickPitchMin;
|
||||
viewKick.adsViewKickPitchMax = jViewKick.adsViewKickPitchMax;
|
||||
viewKick.adsViewKickYawMin = jViewKick.adsViewKickYawMin;
|
||||
viewKick.adsViewKickYawMax = jViewKick.adsViewKickYawMax;
|
||||
viewKick.adsViewKickCenterSpeed = jViewKick.adsViewKickCenterSpeed;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateAttADSOverlayFromJson(const JsonAttADSOverlay& jAdsOverlay, AttADSOverlay& adsOverlay, const WeaponAttachment& attachment) const
|
||||
{
|
||||
if (jAdsOverlay.shader)
|
||||
{
|
||||
if (!CreateMaterialFromJson(jAdsOverlay.shader.value(), adsOverlay.overlay.shader, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
adsOverlay.overlay.shader = nullptr;
|
||||
|
||||
if (jAdsOverlay.shaderLowRes)
|
||||
{
|
||||
if (!CreateMaterialFromJson(jAdsOverlay.shaderLowRes.value(), adsOverlay.overlay.shaderLowRes, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
adsOverlay.overlay.shaderLowRes = nullptr;
|
||||
|
||||
if (jAdsOverlay.shaderEMP)
|
||||
{
|
||||
if (!CreateMaterialFromJson(jAdsOverlay.shaderEMP.value(), adsOverlay.overlay.shaderEMP, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
adsOverlay.overlay.shaderEMP = nullptr;
|
||||
|
||||
if (jAdsOverlay.shaderEMPLowRes)
|
||||
{
|
||||
if (!CreateMaterialFromJson(jAdsOverlay.shaderEMPLowRes.value(), adsOverlay.overlay.shaderEMPLowRes, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
adsOverlay.overlay.shaderEMPLowRes = nullptr;
|
||||
|
||||
adsOverlay.overlay.reticle = jAdsOverlay.reticle;
|
||||
adsOverlay.overlay.width = jAdsOverlay.width;
|
||||
adsOverlay.overlay.height = jAdsOverlay.height;
|
||||
adsOverlay.overlay.widthSplitscreen = jAdsOverlay.widthSplitscreen;
|
||||
adsOverlay.overlay.heightSplitscreen = jAdsOverlay.heightSplitscreen;
|
||||
adsOverlay.thermalScope = jAdsOverlay.thermalScope;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateAttUIFromJson(const JsonAttUI& jUi, AttUI& ui, const WeaponAttachment& attachment) const
|
||||
{
|
||||
if (jUi.dpadIcon)
|
||||
{
|
||||
if (!CreateMaterialFromJson(jUi.dpadIcon.value(), ui.dpadIcon, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
ui.dpadIcon = nullptr;
|
||||
|
||||
if (jUi.ammoCounterIcon)
|
||||
{
|
||||
if (!CreateMaterialFromJson(jUi.ammoCounterIcon.value(), ui.ammoCounterIcon, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
ui.ammoCounterIcon = nullptr;
|
||||
|
||||
ui.dpadIconRatio = jUi.dpadIconRatio;
|
||||
ui.ammoCounterIconRatio = jUi.ammoCounterIconRatio;
|
||||
ui.ammoCounterClip = jUi.ammoCounterClip;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateAttRumblesFromJson(const JsonAttRumbles& jRumbles, AttRumbles& rumbles, const WeaponAttachment& attachment) const
|
||||
{
|
||||
if (jRumbles.fireRumble)
|
||||
rumbles.fireRumble = m_memory.Dup(jRumbles.fireRumble.value().c_str());
|
||||
else
|
||||
rumbles.fireRumble = nullptr;
|
||||
|
||||
if (jRumbles.meleeImpactRumble)
|
||||
rumbles.meleeImpactRumble = m_memory.Dup(jRumbles.meleeImpactRumble.value().c_str());
|
||||
else
|
||||
rumbles.meleeImpactRumble = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateAttProjectileFromJson(const JsonAttProjectile& jProjectile, AttProjectile& projectile, const WeaponAttachment& attachment) const
|
||||
{
|
||||
projectile.explosionRadius = jProjectile.explosionRadius;
|
||||
projectile.explosionInnerDamage = jProjectile.explosionInnerDamage;
|
||||
projectile.explosionOuterDamage = jProjectile.explosionOuterDamage;
|
||||
projectile.damageConeAngle = jProjectile.damageConeAngle;
|
||||
projectile.projectileSpeed = jProjectile.projectileSpeed;
|
||||
projectile.projectileSpeedUp = jProjectile.projectileSpeedUp;
|
||||
projectile.projectileActivateDist = jProjectile.projectileActivateDist;
|
||||
projectile.projectileLifetime = jProjectile.projectileLifetime;
|
||||
|
||||
if (jProjectile.projectileModel)
|
||||
{
|
||||
if (!CreateXModelFromJson(jProjectile.projectileModel.value(), projectile.projectileModel, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
projectile.projectileModel = nullptr;
|
||||
|
||||
projectile.projExplosionType = jProjectile.projExplosionType;
|
||||
|
||||
if (jProjectile.projExplosionEffect)
|
||||
{
|
||||
if (!CreateFxFromJson(jProjectile.projExplosionEffect.value(), projectile.projExplosionEffect, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
projectile.projExplosionEffect = nullptr;
|
||||
|
||||
projectile.projExplosionEffectForceNormalUp = jProjectile.projExplosionEffectForceNormalUp;
|
||||
|
||||
if (jProjectile.projExplosionSound)
|
||||
{
|
||||
if (!CreateSoundFromJson(jProjectile.projExplosionSound.value(), projectile.projExplosionSound, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
projectile.projExplosionSound.name = nullptr;
|
||||
|
||||
if (jProjectile.projDudEffect)
|
||||
{
|
||||
if (!CreateFxFromJson(jProjectile.projDudEffect.value(), projectile.projDudEffect, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
projectile.projDudEffect = nullptr;
|
||||
|
||||
if (jProjectile.projDudSound)
|
||||
{
|
||||
if (!CreateSoundFromJson(jProjectile.projDudSound.value(), projectile.projDudSound, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
projectile.projDudSound.name = nullptr;
|
||||
|
||||
projectile.projImpactExplode = jProjectile.projImpactExplode;
|
||||
projectile.destabilizationRateTime = jProjectile.destabilizationRateTime;
|
||||
projectile.destabilizationCurvatureMax = jProjectile.destabilizationCurvatureMax;
|
||||
projectile.destabilizeDistance = jProjectile.destabilizeDistance;
|
||||
|
||||
if (jProjectile.projTrailEffect)
|
||||
{
|
||||
if (!CreateFxFromJson(jProjectile.projTrailEffect.value(), projectile.projTrailEffect, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
projectile.projTrailEffect = nullptr;
|
||||
|
||||
projectile.projIgnitionDelay = jProjectile.projIgnitionDelay;
|
||||
|
||||
if (jProjectile.projIgnitionEffect)
|
||||
{
|
||||
if (!CreateFxFromJson(jProjectile.projIgnitionEffect.value(), projectile.projIgnitionEffect, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
projectile.projIgnitionEffect = nullptr;
|
||||
|
||||
if (jProjectile.projIgnitionSound)
|
||||
{
|
||||
if (!CreateSoundFromJson(jProjectile.projIgnitionSound.value(), projectile.projIgnitionSound, attachment))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
projectile.projIgnitionSound.name = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::istream& m_stream;
|
||||
MemoryManager& m_memory;
|
||||
AssetCreationContext& m_context;
|
||||
AssetRegistration<AssetAttachment>& m_registration;
|
||||
};
|
||||
|
||||
class AttachmentLoader final : public AssetCreator<AssetAttachment>
|
||||
{
|
||||
public:
|
||||
@@ -22,7 +643,7 @@ namespace
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto file = m_search_path.Open(std::format("attachment/{}.json", assetName));
|
||||
const auto file = m_search_path.Open(attachment::GetJsonFileNameForAssetName(assetName));
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
@@ -30,9 +651,10 @@ namespace
|
||||
attachment->szInternalName = m_memory.Dup(assetName.c_str());
|
||||
|
||||
AssetRegistration<AssetAttachment> registration(assetName, attachment);
|
||||
if (!LoadWeaponAttachmentAsJson(*file.m_stream, *attachment, m_memory, context, registration))
|
||||
const JsonLoader loader(*file.m_stream, m_memory, context, registration);
|
||||
if (!loader.Load(*attachment))
|
||||
{
|
||||
std::cerr << std::format("Failed to load attachment \"{}\"\n", assetName);
|
||||
con::error("Failed to load attachment \"{}\"", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
@@ -45,10 +667,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
namespace attachment
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetAttachment>> CreateAttachmentLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetAttachment>> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<AttachmentLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace IW5
|
||||
} // namespace attachment
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW5
|
||||
namespace attachment
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetAttachment>> CreateAttachmentLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace IW5
|
||||
std::unique_ptr<AssetCreator<IW5::AssetAttachment>> CreateLoaderIW5(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace attachment
|
||||
|
||||
@@ -4,12 +4,15 @@
|
||||
#include "Game/IW5/ObjConstantsIW5.h"
|
||||
#include "InfoString/InfoString.h"
|
||||
#include "InfoStringLoaderWeaponIW5.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
#include "Weapon/WeaponCommon.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace IW5;
|
||||
using namespace ::weapon;
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -24,7 +27,7 @@ namespace
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto fileName = std::format("weapons/{}", assetName);
|
||||
const auto fileName = GetFileNameForAssetName(assetName);
|
||||
const auto file = m_search_path.Open(fileName);
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
@@ -32,7 +35,7 @@ namespace
|
||||
InfoString infoString;
|
||||
if (!infoString.FromStream(ObjConstants::INFO_STRING_PREFIX_WEAPON, *file.m_stream))
|
||||
{
|
||||
std::cerr << std::format("Could not parse as info string file: \"{}\"\n", fileName);
|
||||
con::error("Could not parse as info string file: \"{}\"", fileName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
@@ -41,14 +44,14 @@ namespace
|
||||
|
||||
private:
|
||||
ISearchPath& m_search_path;
|
||||
InfoStringLoaderWeapon m_info_string_loader;
|
||||
weapon::InfoStringLoaderIW5 m_info_string_loader;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace IW5
|
||||
namespace weapon
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetWeapon>> CreateRawWeaponLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
std::unique_ptr<AssetCreator<AssetWeapon>> CreateRawLoaderIW5(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
{
|
||||
return std::make_unique<RawLoaderWeapon>(memory, searchPath, zone);
|
||||
}
|
||||
} // namespace IW5
|
||||
} // namespace weapon
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace IW5
|
||||
namespace weapon
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetWeapon>> CreateRawWeaponLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
} // namespace IW5
|
||||
std::unique_ptr<AssetCreator<IW5::AssetWeapon>> CreateRawLoaderIW5(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
} // namespace weapon
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
// #include "LoaderXModelIW5.h"
|
||||
|
||||
// #include "Game/IW5/IW5.h"
|
||||
// #include "Game/IW5/XModel/XModelLoaderIW5.h"
|
||||
// #include "Pool/GlobalAssetPool.h"
|
||||
|
||||
// #include <cstring>
|
||||
// #include <format>
|
||||
// #include <iostream>
|
||||
|
||||
// using namespace IW5;
|
||||
|
||||
// namespace
|
||||
// {
|
||||
// class XModelLoader final : public AssetCreator<AssetXModel>
|
||||
// {
|
||||
// public:
|
||||
// XModelLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
// : m_memory(memory),
|
||||
// m_search_path(searchPath)
|
||||
// {
|
||||
// }
|
||||
|
||||
// AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
// {
|
||||
// const auto file = m_search_path.Open(std::format("xmodel/{}.json", assetName));
|
||||
// if (!file.IsOpen())
|
||||
// return AssetCreationResult::NoAction();
|
||||
|
||||
// auto* xmodel = m_memory.Alloc<XModel>();
|
||||
// xmodel->name = m_memory.Dup(assetName.c_str());
|
||||
|
||||
// AssetRegistration<AssetXModel> registration(assetName, xmodel);
|
||||
// if (!LoadXModel(*file.m_stream, *xmodel, m_memory, context, registration))
|
||||
// {
|
||||
// std::cerr << std::format("Failed to load xmodel \"{}\"\n", assetName);
|
||||
// return AssetCreationResult::Failure();
|
||||
// }
|
||||
|
||||
// return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||
// }
|
||||
|
||||
// private:
|
||||
// MemoryManager& m_memory;
|
||||
// ISearchPath& m_search_path;
|
||||
// };
|
||||
// } // namespace
|
||||
|
||||
// namespace IW5
|
||||
// {
|
||||
// std::unique_ptr<AssetCreator<AssetXModel>> CreateXModelLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
// {
|
||||
// return std::make_unique<XModelLoader>(memory, searchPath);
|
||||
// }
|
||||
// } // namespace IW5
|
||||
@@ -1,13 +0,0 @@
|
||||
// #pragma once
|
||||
|
||||
// #include "Asset/IAssetCreator.h"
|
||||
// #include "Game/IW5/IW5.h"
|
||||
// #include "SearchPath/ISearchPath.h"
|
||||
// #include "Utils/MemoryManager.h"
|
||||
|
||||
// #include <memory>
|
||||
|
||||
// namespace IW5
|
||||
// {
|
||||
// std::unique_ptr<AssetCreator<AssetXModel>> CreateXModelLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
// } // namespace IW5
|
||||
@@ -35,10 +35,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace T5
|
||||
namespace localize
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLocalize>> CreateLocalizeLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
std::unique_ptr<AssetCreator<AssetLocalize>> CreateLoaderT5(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||
{
|
||||
return std::make_unique<LocalizeLoader>(memory, searchPath, zone);
|
||||
}
|
||||
} // namespace T5
|
||||
} // namespace localize
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace T5
|
||||
namespace localize
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetLocalize>> CreateLocalizeLoader(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
} // namespace T5
|
||||
std::unique_ptr<AssetCreator<T5::AssetLocalize>> CreateLoaderT5(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||
} // namespace localize
|
||||
|
||||
55
src/ObjLoading/Game/T5/Material/LoaderMaterialT5.cpp
Normal file
55
src/ObjLoading/Game/T5/Material/LoaderMaterialT5.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#include "LoaderMaterialT5.h"
|
||||
|
||||
#include "Game/T5/Material/JsonMaterialLoaderT5.h"
|
||||
#include "Game/T5/T5.h"
|
||||
#include "Material/MaterialCommon.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
using namespace T5;
|
||||
|
||||
namespace
|
||||
{
|
||||
class MaterialLoader final : public AssetCreator<AssetMaterial>
|
||||
{
|
||||
public:
|
||||
MaterialLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
: m_memory(memory),
|
||||
m_search_path(searchPath)
|
||||
{
|
||||
}
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto file = m_search_path.Open(material::GetFileNameForAssetName(assetName));
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
auto* material = m_memory.Alloc<Material>();
|
||||
material->info.name = m_memory.Dup(assetName.c_str());
|
||||
|
||||
AssetRegistration<AssetMaterial> registration(assetName, material);
|
||||
if (!LoadMaterialAsJson(*file.m_stream, *material, m_memory, context, registration))
|
||||
{
|
||||
con::error("Failed to load material \"{}\"", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryManager& m_memory;
|
||||
ISearchPath& m_search_path;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace material
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetMaterial>> CreateLoaderT5(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<MaterialLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace material
|
||||
12
src/ObjLoading/Game/T5/Material/LoaderMaterialT5.h
Normal file
12
src/ObjLoading/Game/T5/Material/LoaderMaterialT5.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/T5/T5.h"
|
||||
#include "Gdt/IGdtQueryable.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
namespace material
|
||||
{
|
||||
std::unique_ptr<AssetCreator<T5::AssetMaterial>> CreateLoaderT5(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace material
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Game/T5/T5.h"
|
||||
#include "Game/T5/XModel/LoaderXModelT5.h"
|
||||
#include "Localize/LoaderLocalizeT5.h"
|
||||
#include "Material/LoaderMaterialT5.h"
|
||||
#include "ObjLoading.h"
|
||||
#include "RawFile/LoaderRawFileT5.h"
|
||||
#include "StringTable/LoaderStringTableT5.h"
|
||||
@@ -103,8 +104,8 @@ namespace
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderPhysConstraints>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderDestructibleDef>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderXAnim>(memory));
|
||||
collection.AddAssetCreator(CreateXModelLoader(memory, searchPath, zone));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderMaterial>(memory));
|
||||
collection.AddAssetCreator(xmodel::CreateLoaderT5(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(material::CreateLoaderT5(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderTechniqueSet>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderImage>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderSoundBank>(memory));
|
||||
@@ -119,13 +120,13 @@ namespace
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderFont>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderMenuList>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderMenu>(memory));
|
||||
collection.AddAssetCreator(CreateLocalizeLoader(memory, searchPath, zone));
|
||||
collection.AddAssetCreator(localize::CreateLoaderT5(memory, searchPath, zone));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderWeapon>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderSoundDriverGlobals>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderFx>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderImpactFx>(memory));
|
||||
collection.AddAssetCreator(CreateRawFileLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(CreateStringTableLoader(memory, searchPath));
|
||||
collection.AddAssetCreator(raw_file::CreateLoaderT5(memory, searchPath));
|
||||
collection.AddAssetCreator(string_table::CreateLoaderT5(memory, searchPath));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderPackIndex>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderXGlobals>(memory));
|
||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderDDL>(memory));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "LoaderRawFileT5.h"
|
||||
|
||||
#include "Game/T5/T5.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
@@ -71,7 +72,7 @@ namespace
|
||||
|
||||
if (ret != Z_STREAM_END)
|
||||
{
|
||||
std::cerr << std::format("Deflate failed for loading gsc file \"{}\"\n", assetName);
|
||||
con::error("Deflate failed for loading gsc file \"{}\"", assetName);
|
||||
deflateEnd(&zs);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
@@ -114,10 +115,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace T5
|
||||
namespace raw_file
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetRawFile>> CreateRawFileLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetRawFile>> CreateLoaderT5(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<RawFileLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace T5
|
||||
} // namespace raw_file
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace T5
|
||||
namespace raw_file
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetRawFile>> CreateRawFileLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace T5
|
||||
std::unique_ptr<AssetCreator<T5::AssetRawFile>> CreateLoaderT5(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace raw_file
|
||||
|
||||
@@ -37,10 +37,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace T5
|
||||
namespace string_table
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetStringTable>> CreateStringTableLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetStringTable>> CreateLoaderT5(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<StringTableLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace T5
|
||||
} // namespace string_table
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace T5
|
||||
namespace string_table
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetStringTable>> CreateStringTableLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace T5
|
||||
std::unique_ptr<AssetCreator<T5::AssetStringTable>> CreateLoaderT5(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace string_table
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include "LoaderFontIconT6.h"
|
||||
#include "CsvLoaderFontIconT6.h"
|
||||
|
||||
#include "Csv/CsvStream.h"
|
||||
#include "Game/T6/CommonT6.h"
|
||||
#include "Game/T6/T6.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <format>
|
||||
@@ -30,10 +31,10 @@ namespace
|
||||
constexpr unsigned COL_COUNT_ALIAS = 4;
|
||||
constexpr unsigned COL_COUNT_MIN = std::min(COL_COUNT_ICON, COL_COUNT_ALIAS);
|
||||
|
||||
class FontIconLoader final : public AssetCreator<AssetFontIcon>
|
||||
class CsvFontIconLoader final : public AssetCreator<AssetFontIcon>
|
||||
{
|
||||
public:
|
||||
FontIconLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
CsvFontIconLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
: m_memory(memory),
|
||||
m_search_path(searchPath)
|
||||
{
|
||||
@@ -65,14 +66,14 @@ namespace
|
||||
|
||||
if (currentRow.size() < COL_COUNT_MIN)
|
||||
{
|
||||
std::cerr << std::format("{} Column count lower than min column count ({})\n", ErrorPrefix(assetName, currentRowIndex), COL_COUNT_MIN);
|
||||
con::error("{} Column count lower than min column count ({})", ErrorPrefix(assetName, currentRowIndex), COL_COUNT_MIN);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
int index;
|
||||
if (!ParseInt(index, currentRow[ROW_INDEX]) || index < 0)
|
||||
{
|
||||
std::cerr << std::format("{} Failed to parse index\n", ErrorPrefix(assetName, currentRowIndex));
|
||||
con::error("{} Failed to parse index", ErrorPrefix(assetName, currentRowIndex));
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
@@ -118,7 +119,7 @@ namespace
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << std::format("{} Unknown row type \"{}\"\n", ErrorPrefix(assetName, currentRowIndex), currentRow[ROW_TYPE]);
|
||||
con::error("{} Unknown row type \"{}\"", ErrorPrefix(assetName, currentRowIndex), currentRow[ROW_TYPE]);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
}
|
||||
@@ -222,26 +223,26 @@ namespace
|
||||
{
|
||||
if (row.size() < COL_COUNT_ICON)
|
||||
{
|
||||
std::cerr << std::format("{} Column count lower than min column count for entries ({})\n", ErrorPrefix(assetName, rowIndex), COL_COUNT_ICON);
|
||||
con::error("{} Column count lower than min column count for entries ({})", ErrorPrefix(assetName, rowIndex), COL_COUNT_ICON);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ParseInt(icon.fontIconSize, row[ROW_ICON_SIZE]))
|
||||
{
|
||||
std::cerr << std::format("{} Failed to parse size\n", ErrorPrefix(assetName, rowIndex));
|
||||
con::error("{} Failed to parse size", ErrorPrefix(assetName, rowIndex));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ParseFloat(icon.xScale, row[ROW_ICON_XSCALE]) || !ParseFloat(icon.yScale, row[ROW_ICON_YSCALE]))
|
||||
{
|
||||
std::cerr << std::format("{} Failed to parse scale\n", ErrorPrefix(assetName, rowIndex));
|
||||
con::error("{} Failed to parse scale", ErrorPrefix(assetName, rowIndex));
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* materialDependency = context.LoadDependency<AssetMaterial>(row[ROW_ICON_MATERIAL]);
|
||||
if (materialDependency == nullptr)
|
||||
{
|
||||
std::cerr << std::format("{} Failed to load material \"{}\"\n", ErrorPrefix(assetName, rowIndex), row[ROW_ICON_MATERIAL]);
|
||||
con::error("{} Failed to load material \"{}\"", ErrorPrefix(assetName, rowIndex), row[ROW_ICON_MATERIAL]);
|
||||
return false;
|
||||
}
|
||||
registration.AddDependency(materialDependency);
|
||||
@@ -258,19 +259,19 @@ namespace
|
||||
{
|
||||
if (row.size() < COL_COUNT_ALIAS)
|
||||
{
|
||||
std::cerr << std::format("{} Column count lower than min column count for aliases ({})\n", ErrorPrefix(assetName, rowIndex), COL_COUNT_ALIAS);
|
||||
con::error("{} Column count lower than min column count for aliases ({})", ErrorPrefix(assetName, rowIndex), COL_COUNT_ALIAS);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ParseHashStr(alias.aliasHash, row[ROW_ALIAS_NAME]))
|
||||
{
|
||||
std::cerr << std::format("{} Failed to parse alias \"{}\"\n", ErrorPrefix(assetName, rowIndex), row[ROW_ALIAS_NAME]);
|
||||
con::error("{} Failed to parse alias \"{}\"", ErrorPrefix(assetName, rowIndex), row[ROW_ALIAS_NAME]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ParseHashStr(alias.buttonHash, row[ROW_ALIAS_BUTTON]))
|
||||
{
|
||||
std::cerr << std::format("{} Failed to parse button \"{}\"\n", ErrorPrefix(assetName, rowIndex), row[ROW_ALIAS_BUTTON]);
|
||||
con::error("{} Failed to parse button \"{}\"", ErrorPrefix(assetName, rowIndex), row[ROW_ALIAS_BUTTON]);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -282,10 +283,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace T6
|
||||
namespace font_icon
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetFontIcon>> CreateFontIconLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetFontIcon>> CreateCsvLoaderT6(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<FontIconLoader>(memory, searchPath);
|
||||
return std::make_unique<CsvFontIconLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace T6
|
||||
} // namespace font_icon
|
||||
13
src/ObjLoading/Game/T6/FontIcon/CsvLoaderFontIconT6.h
Normal file
13
src/ObjLoading/Game/T6/FontIcon/CsvLoaderFontIconT6.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/T6/T6.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace font_icon
|
||||
{
|
||||
std::unique_ptr<AssetCreator<T6::AssetFontIcon>> CreateCsvLoaderT6(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace font_icon
|
||||
151
src/ObjLoading/Game/T6/FontIcon/JsonLoaderFontIconT6.cpp
Normal file
151
src/ObjLoading/Game/T6/FontIcon/JsonLoaderFontIconT6.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
#include "JsonLoaderFontIconT6.h"
|
||||
|
||||
#include "FontIcon/FontIconCommon.h"
|
||||
#include "Game/T6/CommonT6.h"
|
||||
#include "Game/T6/FontIcon/JsonFontIconT6.h"
|
||||
#include "Game/T6/T6.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using namespace nlohmann;
|
||||
using namespace T6;
|
||||
|
||||
namespace
|
||||
{
|
||||
class JsonFontIconLoader final : public AssetCreator<AssetFontIcon>
|
||||
{
|
||||
public:
|
||||
JsonFontIconLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
: m_memory(memory),
|
||||
m_search_path(searchPath)
|
||||
{
|
||||
}
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
const auto file = m_search_path.Open(font_icon::GetJsonFileNameForAssetName(assetName));
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
|
||||
auto* fontIcon = m_memory.Alloc<FontIcon>();
|
||||
fontIcon->name = m_memory.Dup(assetName.c_str());
|
||||
AssetRegistration<AssetFontIcon> registration(assetName, fontIcon);
|
||||
|
||||
try
|
||||
{
|
||||
const auto jRoot = json::parse(*file.m_stream);
|
||||
std::string type;
|
||||
unsigned version;
|
||||
|
||||
jRoot.at("_type").get_to(type);
|
||||
jRoot.at("_version").get_to(version);
|
||||
|
||||
if (type != "font-icon" || version != 1u)
|
||||
{
|
||||
con::error("Tried to load font icon \"{}\" but did not find expected type font-icon of version 1", assetName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
const auto jFontIcon = jRoot.get<JsonFontIcon>();
|
||||
if (CreateFontIconFromJson(jFontIcon, *fontIcon, registration, context))
|
||||
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||
}
|
||||
catch (const json::exception& e)
|
||||
{
|
||||
con::error("Failed to parse json of font icon: {}", e.what());
|
||||
}
|
||||
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
private:
|
||||
bool CreateFontIconFromJson(const JsonFontIcon& jFontIcon,
|
||||
FontIcon& fontIcon,
|
||||
AssetRegistration<AssetFontIcon>& registration,
|
||||
AssetCreationContext& context) const
|
||||
{
|
||||
std::vector<FontIconAlias> aliases;
|
||||
|
||||
fontIcon.numEntries = static_cast<unsigned>(jFontIcon.entries.size());
|
||||
fontIcon.fontIconEntry = m_memory.Alloc<FontIconEntry>(fontIcon.numEntries);
|
||||
|
||||
for (auto entryIndex = 0u; entryIndex < fontIcon.numEntries; entryIndex++)
|
||||
{
|
||||
if (!CreateFontIconEntryFromJson(jFontIcon.entries[entryIndex], fontIcon.fontIconEntry[entryIndex], aliases, registration, context))
|
||||
return false;
|
||||
}
|
||||
|
||||
std::sort(fontIcon.fontIconEntry,
|
||||
&fontIcon.fontIconEntry[fontIcon.numEntries],
|
||||
[](const FontIconEntry& e0, const FontIconEntry& e1) -> bool
|
||||
{
|
||||
return e0.fontIconName.hash < e1.fontIconName.hash;
|
||||
});
|
||||
|
||||
if (!aliases.empty())
|
||||
{
|
||||
fontIcon.numAliasEntries = static_cast<unsigned>(aliases.size());
|
||||
fontIcon.fontIconAlias = m_memory.Alloc<FontIconAlias>(fontIcon.numAliasEntries);
|
||||
std::memcpy(fontIcon.fontIconAlias, aliases.data(), sizeof(FontIconAlias) * fontIcon.numAliasEntries);
|
||||
|
||||
std::sort(fontIcon.fontIconAlias,
|
||||
&fontIcon.fontIconAlias[fontIcon.numAliasEntries],
|
||||
[](const FontIconAlias& a0, const FontIconAlias& a1) -> bool
|
||||
{
|
||||
return a0.aliasHash < a1.aliasHash;
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateFontIconEntryFromJson(const JsonFontIconEntry& jFontIconEntry,
|
||||
FontIconEntry& fontIconEntry,
|
||||
std::vector<FontIconAlias>& aliases,
|
||||
AssetRegistration<AssetFontIcon>& registration,
|
||||
AssetCreationContext& context) const
|
||||
{
|
||||
fontIconEntry.fontIconName.string = m_memory.Dup(jFontIconEntry.name.c_str());
|
||||
fontIconEntry.fontIconName.hash = Common::Com_HashString(jFontIconEntry.name.c_str());
|
||||
|
||||
auto* materialDependency = context.LoadDependency<AssetMaterial>(jFontIconEntry.material);
|
||||
if (materialDependency == nullptr)
|
||||
{
|
||||
con::error("Failed to load material \"{}\" for font icon entry \"{}\"", jFontIconEntry.material, jFontIconEntry.name);
|
||||
return false;
|
||||
}
|
||||
registration.AddDependency(materialDependency);
|
||||
fontIconEntry.fontIconMaterialHandle = materialDependency->Asset();
|
||||
|
||||
fontIconEntry.fontIconSize = static_cast<int>(jFontIconEntry.size);
|
||||
fontIconEntry.xScale = jFontIconEntry.scale.has_value() ? jFontIconEntry.scale->x : 0;
|
||||
fontIconEntry.yScale = jFontIconEntry.scale.has_value() ? jFontIconEntry.scale->y : 0;
|
||||
|
||||
for (const auto& alias : jFontIconEntry.aliases)
|
||||
aliases.emplace_back(Common::Com_HashString(alias.c_str()), fontIconEntry.fontIconName.hash);
|
||||
|
||||
if (jFontIconEntry.aliasHashes.has_value())
|
||||
{
|
||||
for (const auto aliasHash : *jFontIconEntry.aliasHashes)
|
||||
aliases.emplace_back(aliasHash, fontIconEntry.fontIconName.hash);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
MemoryManager& m_memory;
|
||||
ISearchPath& m_search_path;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace font_icon
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetFontIcon>> CreateJsonLoaderT6(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<JsonFontIconLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace font_icon
|
||||
13
src/ObjLoading/Game/T6/FontIcon/JsonLoaderFontIconT6.h
Normal file
13
src/ObjLoading/Game/T6/FontIcon/JsonLoaderFontIconT6.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/T6/T6.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace font_icon
|
||||
{
|
||||
std::unique_ptr<AssetCreator<T6::AssetFontIcon>> CreateJsonLoaderT6(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace font_icon
|
||||
@@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Asset/IAssetCreator.h"
|
||||
#include "Game/T6/T6.h"
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace T6
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetFontIcon>> CreateFontIconLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace T6
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
#include "Game/T6/CommonT6.h"
|
||||
#include "Game/T6/T6.h"
|
||||
#include "Image/ImageCommon.h"
|
||||
#include "Image/IwiLoader.h"
|
||||
#include "Image/IwiTypes.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
@@ -26,12 +27,7 @@ namespace
|
||||
|
||||
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||
{
|
||||
auto fileName = std::format("images/{}.iwi", assetName);
|
||||
|
||||
for (size_t i = 0; i < fileName.size(); i++)
|
||||
if (fileName[i] == '*')
|
||||
fileName[i] = '_';
|
||||
|
||||
const auto fileName = image::GetFileNameForAsset(assetName, ".iwi");
|
||||
const auto file = m_search_path.Open(fileName);
|
||||
if (!file.IsOpen())
|
||||
return AssetCreationResult::NoAction();
|
||||
@@ -45,7 +41,7 @@ namespace
|
||||
const auto texture = iwi::LoadIwi(ss);
|
||||
if (!texture)
|
||||
{
|
||||
std::cerr << std::format("Failed to load texture from: {}\n", fileName);
|
||||
con::error("Failed to load texture from: {}", fileName);
|
||||
return AssetCreationResult::Failure();
|
||||
}
|
||||
|
||||
@@ -59,47 +55,11 @@ namespace
|
||||
image->height = static_cast<uint16_t>(texture->GetHeight());
|
||||
image->depth = static_cast<uint16_t>(texture->GetDepth());
|
||||
|
||||
if (texture->GetTextureType() == TextureType::T_2D)
|
||||
image->mapType = 3;
|
||||
else if (texture->GetTextureType() == TextureType::T_3D)
|
||||
image->mapType = 4;
|
||||
else if (texture->GetTextureType() == TextureType::T_CUBE)
|
||||
image->mapType = 5;
|
||||
else
|
||||
_ASSERT(false);
|
||||
|
||||
//image->streaming = 1;
|
||||
//image->streamedParts[0].levelCount = 1;
|
||||
//image->streamedParts[0].levelSize = static_cast<uint32_t>(fileSize);
|
||||
//image->streamedParts[0].hash = dataHash & 0x1FFFFFFF;
|
||||
//image->streamedPartCount = 1;
|
||||
|
||||
int mipMapCount = texture->HasMipMaps() ? texture->GetMipMapCount() : 1;
|
||||
size_t textureSize = 0;
|
||||
for (int previousMipLevel = 0; previousMipLevel < mipMapCount; previousMipLevel++)
|
||||
{
|
||||
textureSize += texture->GetSizeOfMipLevel(previousMipLevel) * texture->GetFaceCount();
|
||||
}
|
||||
|
||||
image->streaming = 0;
|
||||
image->texture.loadDef = (GfxImageLoadDef*)malloc(sizeof(GfxImageLoadDef) + textureSize);
|
||||
memset(image->texture.loadDef, 0, sizeof(GfxImageLoadDef) + textureSize);
|
||||
image->texture.loadDef->format = texture->GetFormat()->GetDxgiFormat();
|
||||
image->texture.loadDef->levelCount = 1;
|
||||
image->texture.loadDef->resourceSize = textureSize;
|
||||
memcpy(image->texture.loadDef->data,
|
||||
texture->GetBufferForMipLevel(0),
|
||||
textureSize); // GetBufferForMipLevel(0) returns a pointer to the start of the image
|
||||
|
||||
image->texture.loadDef->flags = 0;
|
||||
if (image->noPicmip)
|
||||
image->texture.loadDef->flags |= iwi27::IMG_FLAG_NOMIPMAPS;
|
||||
|
||||
if (texture->GetTextureType() == TextureType::T_3D)
|
||||
image->texture.loadDef->flags |= iwi27::IMG_FLAG_VOLMAP;
|
||||
|
||||
if (texture->GetTextureType() == TextureType::T_CUBE)
|
||||
image->texture.loadDef->flags |= iwi27::IMG_FLAG_CUBEMAP;
|
||||
image->streaming = 1;
|
||||
image->streamedParts[0].levelCount = 1;
|
||||
image->streamedParts[0].levelSize = static_cast<uint32_t>(fileSize);
|
||||
image->streamedParts[0].hash = dataHash & 0x1FFFFFFF;
|
||||
image->streamedPartCount = 1;
|
||||
|
||||
return AssetCreationResult::Success(context.AddAsset<AssetImage>(assetName, image));
|
||||
}
|
||||
@@ -110,10 +70,10 @@ namespace
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace T6
|
||||
namespace image
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetImage>> CreateImageLoader(MemoryManager& memory, ISearchPath& searchPath)
|
||||
std::unique_ptr<AssetCreator<AssetImage>> CreateLoaderT6(MemoryManager& memory, ISearchPath& searchPath)
|
||||
{
|
||||
return std::make_unique<ImageLoader>(memory, searchPath);
|
||||
}
|
||||
} // namespace T6
|
||||
} // namespace image
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace T6
|
||||
namespace image
|
||||
{
|
||||
std::unique_ptr<AssetCreator<AssetImage>> CreateImageLoader(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace T6
|
||||
std::unique_ptr<AssetCreator<T6::AssetImage>> CreateLoaderT6(MemoryManager& memory, ISearchPath& searchPath);
|
||||
} // namespace image
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user