From b4477ac1a917a9835079437e8a706f4f3b4f6a40 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 20 Jun 2026 17:16:37 +0200 Subject: [PATCH] refactor: accuracy graph subassets (#847) * refactor: use subassets to load accuracy graphs for iw4,iw5,t5,t6 * fix: not dumping anim names for t5 weapons and t6 attachment unique * refactor: dump accuracy graphs like a subasset * refactor: use shared method for accuracy graph filenames --- src/Common/Game/IW4/GameIW4.cpp | 1 + src/Common/Game/IW4/IW4.h | 8 ++ src/Common/Game/IW5/GameIW5.cpp | 1 + src/Common/Game/IW5/IW5.h | 8 ++ src/Common/Game/T5/GameT5.cpp | 1 + src/Common/Game/T5/T5.h | 8 ++ src/Common/Game/T6/GameT6.cpp | 1 + src/Common/Game/T6/T6.h | 8 ++ src/ObjCommon/Weapon/WeaponCommon.cpp | 15 ++++ src/ObjCommon/Weapon/WeaponCommon.h | 5 ++ src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp | 3 + .../IW4/Weapon/InfoStringLoaderWeaponIW4.cpp | 75 ++++++++++--------- src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp | 3 + .../IW5/Weapon/InfoStringLoaderWeaponIW5.cpp | 75 ++++++++++--------- src/ObjLoading/Game/T5/ObjLoaderT5.cpp | 2 + .../T5/Weapon/WeaponInfoStringLoaderT5.cpp | 71 ++++++++++-------- src/ObjLoading/Game/T6/ObjLoaderT6.cpp | 2 + .../T6/Weapon/WeaponInfoStringLoaderT6.cpp | 71 ++++++++++-------- src/ObjLoading/Weapon/AccuracyGraphLoader.cpp | 55 -------------- .../Weapon/AccuracyGraphLoader.cpp.template | 71 ++++++++++++++++++ src/ObjLoading/Weapon/AccuracyGraphLoader.h | 20 ----- .../Weapon/AccuracyGraphLoader.h.template | 21 ++++++ .../Game/IW4/Weapon/WeaponDumperIW4.cpp | 62 ++++++++------- .../Game/IW5/Weapon/WeaponDumperIW5.cpp | 62 ++++++++------- .../Game/T5/Weapon/WeaponDumperT5.cpp | 66 +++++++++------- .../T6/Weapon/AttachmentUniqueDumperT6.cpp | 5 ++ .../Game/T6/Weapon/WeaponDumperT6.cpp | 62 ++++++++------- src/ObjWriting/Weapon/AccuracyGraphWriter.cpp | 26 +++---- src/ObjWriting/Weapon/AccuracyGraphWriter.h | 10 +-- 29 files changed, 464 insertions(+), 354 deletions(-) delete mode 100644 src/ObjLoading/Weapon/AccuracyGraphLoader.cpp create mode 100644 src/ObjLoading/Weapon/AccuracyGraphLoader.cpp.template delete mode 100644 src/ObjLoading/Weapon/AccuracyGraphLoader.h create mode 100644 src/ObjLoading/Weapon/AccuracyGraphLoader.h.template diff --git a/src/Common/Game/IW4/GameIW4.cpp b/src/Common/Game/IW4/GameIW4.cpp index 0b562457..b1a738fe 100644 --- a/src/Common/Game/IW4/GameIW4.cpp +++ b/src/Common/Game/IW4/GameIW4.cpp @@ -23,6 +23,7 @@ namespace constexpr const char* SUB_ASSET_TYPE_NAMES[]{ "technique", + "accuracygraph", }; static_assert(std::extent_v == SUB_ASSET_TYPE_COUNT); } // namespace diff --git a/src/Common/Game/IW4/IW4.h b/src/Common/Game/IW4/IW4.h index d30ba9aa..f31f46cc 100644 --- a/src/Common/Game/IW4/IW4.h +++ b/src/Common/Game/IW4/IW4.h @@ -63,6 +63,7 @@ namespace IW4 enum SubAssetType { SUB_ASSET_TYPE_TECHNIQUE, + SUB_ASSET_TYPE_ACCURACY_GRAPH, SUB_ASSET_TYPE_COUNT }; @@ -186,6 +187,12 @@ namespace IW4 VFT_NUM, }; + struct AccuracyGraph + { + vec2_t* graphKnots; + int graphKnotCount; + }; + using AssetPhysPreset = Asset; using AssetPhysCollMap = Asset; using AssetXAnim = Asset; @@ -225,6 +232,7 @@ namespace IW4 using AssetAddonMapEnts = Asset; using SubAssetTechnique = SubAsset; + using SubAssetAccuracyGraph = SubAsset; } // namespace IW4 DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetPhysPreset, name); diff --git a/src/Common/Game/IW5/GameIW5.cpp b/src/Common/Game/IW5/GameIW5.cpp index 8b76c24c..5d0b6ff0 100644 --- a/src/Common/Game/IW5/GameIW5.cpp +++ b/src/Common/Game/IW5/GameIW5.cpp @@ -60,6 +60,7 @@ namespace constexpr const char* SUB_ASSET_TYPE_NAMES[]{ "technique", + "accuracygraph", }; static_assert(std::extent_v == SUB_ASSET_TYPE_COUNT); } // namespace diff --git a/src/Common/Game/IW5/IW5.h b/src/Common/Game/IW5/IW5.h index 3984d481..b6d2c619 100644 --- a/src/Common/Game/IW5/IW5.h +++ b/src/Common/Game/IW5/IW5.h @@ -66,6 +66,7 @@ namespace IW5 enum SubAssetType { SUB_ASSET_TYPE_TECHNIQUE, + SUB_ASSET_TYPE_ACCURACY_GRAPH, SUB_ASSET_TYPE_COUNT }; @@ -204,6 +205,12 @@ namespace IW5 PPFT_NUM_FIELD_TYPES, }; + struct AccuracyGraph + { + vec2_t* graphKnots; + int graphKnotCount; + }; + using AssetPhysPreset = Asset; using AssetPhysCollMap = Asset; using AssetXAnim = Asset; @@ -246,6 +253,7 @@ namespace IW5 using AssetAddonMapEnts = Asset; using SubAssetTechnique = SubAsset; + using SubAssetAccuracyGraph = SubAsset; } // namespace IW5 DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetPhysPreset, name); diff --git a/src/Common/Game/T5/GameT5.cpp b/src/Common/Game/T5/GameT5.cpp index a128f3dc..b24eec28 100644 --- a/src/Common/Game/T5/GameT5.cpp +++ b/src/Common/Game/T5/GameT5.cpp @@ -24,6 +24,7 @@ namespace "vertexdecl", "vertexshader", "pixelshader", + "accuracygraph", "flametable", }; static_assert(std::extent_v == SUB_ASSET_TYPE_COUNT); diff --git a/src/Common/Game/T5/T5.h b/src/Common/Game/T5/T5.h index 9dd19b8b..af81eeb5 100644 --- a/src/Common/Game/T5/T5.h +++ b/src/Common/Game/T5/T5.h @@ -66,6 +66,7 @@ namespace T5 SUB_ASSET_TYPE_VERTEX_DECL, SUB_ASSET_TYPE_VERTEX_SHADER, SUB_ASSET_TYPE_PIXEL_SHADER, + SUB_ASSET_TYPE_ACCURACY_GRAPH, SUB_ASSET_TYPE_FLAME_TABLE, SUB_ASSET_TYPE_COUNT @@ -176,6 +177,12 @@ namespace T5 CFT_NUM_FIELD_TYPES }; + struct AccuracyGraph + { + vec2_t* graphKnots; + int graphKnotCount; + }; + using AssetPhysPreset = Asset; using AssetPhysConstraints = Asset; using AssetDestructibleDef = Asset; @@ -214,6 +221,7 @@ namespace T5 using SubAssetVertexDecl = SubAsset; using SubAssetVertexShader = SubAsset; using SubAssetPixelShader = SubAsset; + using SubAssetAccuracyGraph = SubAsset; using SubAssetFlameTable = SubAsset; } // namespace T5 diff --git a/src/Common/Game/T6/GameT6.cpp b/src/Common/Game/T6/GameT6.cpp index c69c81b7..eacdcbbf 100644 --- a/src/Common/Game/T6/GameT6.cpp +++ b/src/Common/Game/T6/GameT6.cpp @@ -77,6 +77,7 @@ namespace "vertexdecl", "vertexshader", "pixelshader", + "accuracygraph", "flametable", }; static_assert(std::extent_v == SUB_ASSET_TYPE_COUNT); diff --git a/src/Common/Game/T6/T6.h b/src/Common/Game/T6/T6.h index fe1c8654..d33a6455 100644 --- a/src/Common/Game/T6/T6.h +++ b/src/Common/Game/T6/T6.h @@ -86,6 +86,7 @@ namespace T6 SUB_ASSET_TYPE_VERTEX_DECL, SUB_ASSET_TYPE_VERTEX_SHADER, SUB_ASSET_TYPE_PIXEL_SHADER, + SUB_ASSET_TYPE_ACCURACY_GRAPH, SUB_ASSET_TYPE_FLAME_TABLE, SUB_ASSET_TYPE_COUNT @@ -239,6 +240,12 @@ namespace T6 AUFT_NUM_FIELD_TYPES, }; + struct AccuracyGraph + { + vec2_t* graphKnots; + int graphKnotCount; + }; + using AssetPhysPreset = Asset; using AssetPhysConstraints = Asset; using AssetDestructibleDef = Asset; @@ -293,6 +300,7 @@ namespace T6 using SubAssetVertexDecl = SubAsset; using SubAssetVertexShader = SubAsset; using SubAssetPixelShader = SubAsset; + using SubAssetAccuracyGraph = SubAsset; using SubAssetFlameTable = SubAsset; } // namespace T6 diff --git a/src/ObjCommon/Weapon/WeaponCommon.cpp b/src/ObjCommon/Weapon/WeaponCommon.cpp index df2dc4d2..3f7ae39e 100644 --- a/src/ObjCommon/Weapon/WeaponCommon.cpp +++ b/src/ObjCommon/Weapon/WeaponCommon.cpp @@ -9,6 +9,21 @@ namespace weapon return std::format("weapons/{}", assetName); } + std::string GetFileNameForAccuracyGraph(const std::string& assetName) + { + return std::format("accuracy/{}", assetName); + } + + std::string GetAssetNameForAiVsAiAccuracyGraph(const std::string& graphName) + { + return std::format("aivsai/{}", graphName); + } + + std::string GetAssetNameForAiVsPlayerAccuracyGraph(const std::string& graphName) + { + return std::format("aivsplayer/{}", graphName); + } + std::string GetFileNameForFlameTable(const std::string& flameTableName) { return std::format("weapons/{}", flameTableName); diff --git a/src/ObjCommon/Weapon/WeaponCommon.h b/src/ObjCommon/Weapon/WeaponCommon.h index 1fd65457..61e7cacb 100644 --- a/src/ObjCommon/Weapon/WeaponCommon.h +++ b/src/ObjCommon/Weapon/WeaponCommon.h @@ -5,5 +5,10 @@ namespace weapon { std::string GetFileNameForAssetName(const std::string& assetName); + + std::string GetFileNameForAccuracyGraph(const std::string& assetName); + std::string GetAssetNameForAiVsAiAccuracyGraph(const std::string& graphName); + std::string GetAssetNameForAiVsPlayerAccuracyGraph(const std::string& graphName); + std::string GetFileNameForFlameTable(const std::string& flameTableName); } // namespace weapon diff --git a/src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp b/src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp index d183bc61..cb92ce6b 100644 --- a/src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp +++ b/src/ObjLoading/Game/IW4/ObjLoaderIW4.cpp @@ -8,6 +8,7 @@ #include "Game/IW4/Image/ImageLoaderExternalIW4.h" #include "Game/IW4/Techset/PixelShaderLoaderIW4.h" #include "Game/IW4/Techset/VertexShaderLoaderIW4.h" +#include "Game/IW4/Weapon/AccuracyGraphLoaderIW4.h" #include "Game/IW4/XAnim/XAnimLoaderIW4.h" #include "Game/IW4/XModel/LoaderXModelIW4.h" #include "Leaderboard/LoaderLeaderboardIW4.h" @@ -160,6 +161,8 @@ namespace // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); + + collection.AddSubAssetCreator(weapon::CreateAccuracyGraphLoaderIW4(memory, searchPath)); } } // namespace diff --git a/src/ObjLoading/Game/IW4/Weapon/InfoStringLoaderWeaponIW4.cpp b/src/ObjLoading/Game/IW4/Weapon/InfoStringLoaderWeaponIW4.cpp index ee42d20d..e4dd749f 100644 --- a/src/ObjLoading/Game/IW4/Weapon/InfoStringLoaderWeaponIW4.cpp +++ b/src/ObjLoading/Game/IW4/Weapon/InfoStringLoaderWeaponIW4.cpp @@ -5,7 +5,7 @@ #include "Game/IW4/InfoString/InfoStringToStructConverter.h" #include "Game/IW4/Weapon/WeaponFields.h" #include "Utils/Logging/Log.h" -#include "Weapon/AccuracyGraphLoader.h" +#include "Weapon/WeaponCommon.h" #include #include @@ -367,57 +367,58 @@ namespace } } - void ConvertAccuracyGraph(const GenericGraph2D& graph, - vec2_t*& originalGraphKnots, - uint16_t& originalGraphKnotCount, - vec2_t*& graphKnots, - uint16_t& graphKnotCount, - MemoryManager& memory) + bool LoadAccuracyGraph(const std::string& graphName, + vec2_t*& originalGraphKnots, + uint16_t& originalGraphKnotCount, + vec2_t*& graphKnots, + uint16_t& graphKnotCount, + AssetCreationContext& context) { - originalGraphKnotCount = static_cast(graph.knots.size()); - originalGraphKnots = memory.Alloc(originalGraphKnotCount); + auto* accuracyGraphAsset = context.LoadSubAsset(graphName); + if (!accuracyGraphAsset) + return false; - for (auto i = 0u; i < originalGraphKnotCount; i++) - { - const auto& commonKnot = graph.knots[i]; - originalGraphKnots[i].x = static_cast(commonKnot.x); - originalGraphKnots[i].y = static_cast(commonKnot.y); - } + const auto* accuracyGraph = accuracyGraphAsset->Asset(); - graphKnots = originalGraphKnots; - graphKnotCount = originalGraphKnotCount; + assert(accuracyGraphAsset->m_dependencies.empty()); + assert(accuracyGraphAsset->m_used_script_strings.empty()); + assert(accuracyGraphAsset->m_indirect_asset_references.empty()); + + originalGraphKnots = accuracyGraph->graphKnots; + originalGraphKnotCount = static_cast(accuracyGraph->graphKnotCount); + + graphKnots = accuracyGraph->graphKnots; + graphKnotCount = static_cast(accuracyGraph->graphKnotCount); + + return true; } bool LoadAccuracyGraphs(WeaponFullDef& weaponFullDef, MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context) { - auto& accuracyGraphLoader = context.GetZoneAssetCreationState(); - if (weaponFullDef.weapDef.aiVsAiAccuracyGraphName && weaponFullDef.weapDef.aiVsAiAccuracyGraphName[0]) { - const auto* graph = accuracyGraphLoader.LoadAiVsAiGraph(searchPath, weaponFullDef.weapDef.aiVsAiAccuracyGraphName); - if (!graph) + if (!LoadAccuracyGraph(weapon::GetAssetNameForAiVsAiAccuracyGraph(weaponFullDef.weapDef.aiVsAiAccuracyGraphName), + weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnots, + weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnotCount, + weaponFullDef.weapCompleteDef.aiVsAiAccuracyGraphKnots, + weaponFullDef.weapCompleteDef.aiVsAiAccuracyGraphKnotCount, + context)) + { return false; - - ConvertAccuracyGraph(*graph, - weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnots, - weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnotCount, - weaponFullDef.weapCompleteDef.aiVsAiAccuracyGraphKnots, - weaponFullDef.weapCompleteDef.aiVsAiAccuracyGraphKnotCount, - memory); + } } if (weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName && weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName[0]) { - const auto* graph = accuracyGraphLoader.LoadAiVsPlayerGraph(searchPath, weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName); - if (!graph) + if (!LoadAccuracyGraph(weapon::GetAssetNameForAiVsPlayerAccuracyGraph(weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName), + weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnots, + weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnotCount, + weaponFullDef.weapCompleteDef.aiVsPlayerAccuracyGraphKnots, + weaponFullDef.weapCompleteDef.aiVsPlayerAccuracyGraphKnotCount, + context)) + { return false; - - ConvertAccuracyGraph(*graph, - weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnots, - weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnotCount, - weaponFullDef.weapCompleteDef.aiVsPlayerAccuracyGraphKnots, - weaponFullDef.weapCompleteDef.aiVsPlayerAccuracyGraphKnotCount, - memory); + } } return true; diff --git a/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp b/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp index f9084f30..f9d406a1 100644 --- a/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp +++ b/src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp @@ -8,6 +8,7 @@ #include "Game/IW5/Image/ImageLoaderExternalIW5.h" #include "Game/IW5/Techset/PixelShaderLoaderIW5.h" #include "Game/IW5/Techset/VertexShaderLoaderIW5.h" +#include "Game/IW5/Weapon/AccuracyGraphLoaderIW5.h" #include "Game/IW5/XAnim/XAnimLoaderIW5.h" #include "Game/IW5/XModel/LoaderXModelIW5.h" #include "Leaderboard/LoaderLeaderboardIW5.h" @@ -171,6 +172,8 @@ namespace // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); + + collection.AddSubAssetCreator(weapon::CreateAccuracyGraphLoaderIW5(memory, searchPath)); } } // namespace diff --git a/src/ObjLoading/Game/IW5/Weapon/InfoStringLoaderWeaponIW5.cpp b/src/ObjLoading/Game/IW5/Weapon/InfoStringLoaderWeaponIW5.cpp index 7a6617fb..de5e9cb6 100644 --- a/src/ObjLoading/Game/IW5/Weapon/InfoStringLoaderWeaponIW5.cpp +++ b/src/ObjLoading/Game/IW5/Weapon/InfoStringLoaderWeaponIW5.cpp @@ -4,7 +4,7 @@ #include "Game/IW5/InfoString/InfoStringToStructConverter.h" #include "Game/IW5/Weapon/WeaponFields.h" #include "Utils/Logging/Log.h" -#include "Weapon/AccuracyGraphLoader.h" +#include "Weapon/WeaponCommon.h" #include #include @@ -797,57 +797,58 @@ namespace } } - void ConvertAccuracyGraph(const GenericGraph2D& graph, - vec2_t*& originalGraphKnots, - uint16_t& originalGraphKnotCount, - vec2_t*& graphKnots, - uint16_t& graphKnotCount, - MemoryManager& memory) + bool LoadAccuracyGraph(const std::string& graphName, + vec2_t*& originalGraphKnots, + uint16_t& originalGraphKnotCount, + vec2_t*& graphKnots, + uint16_t& graphKnotCount, + AssetCreationContext& context) { - originalGraphKnotCount = static_cast(graph.knots.size()); - originalGraphKnots = memory.Alloc(originalGraphKnotCount); + auto* accuracyGraphAsset = context.LoadSubAsset(graphName); + if (!accuracyGraphAsset) + return false; - for (auto i = 0u; i < originalGraphKnotCount; i++) - { - const auto& commonKnot = graph.knots[i]; - originalGraphKnots[i].x = static_cast(commonKnot.x); - originalGraphKnots[i].y = static_cast(commonKnot.y); - } + const auto* accuracyGraph = accuracyGraphAsset->Asset(); - graphKnots = originalGraphKnots; - graphKnotCount = originalGraphKnotCount; + assert(accuracyGraphAsset->m_dependencies.empty()); + assert(accuracyGraphAsset->m_used_script_strings.empty()); + assert(accuracyGraphAsset->m_indirect_asset_references.empty()); + + originalGraphKnots = accuracyGraph->graphKnots; + originalGraphKnotCount = static_cast(accuracyGraph->graphKnotCount); + + graphKnots = accuracyGraph->graphKnots; + graphKnotCount = static_cast(accuracyGraph->graphKnotCount); + + return true; } bool LoadAccuracyGraphs(WeaponFullDef& weaponFullDef, MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context) { - auto& accuracyGraphLoader = context.GetZoneAssetCreationState(); - if (weaponFullDef.weapDef.aiVsAiAccuracyGraphName && weaponFullDef.weapDef.aiVsAiAccuracyGraphName[0]) { - const auto* graph = accuracyGraphLoader.LoadAiVsAiGraph(searchPath, weaponFullDef.weapDef.aiVsAiAccuracyGraphName); - if (!graph) + if (!LoadAccuracyGraph(weapon::GetAssetNameForAiVsAiAccuracyGraph(weaponFullDef.weapDef.aiVsAiAccuracyGraphName), + weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnots, + weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnotCount, + weaponFullDef.weapCompleteDef.aiVsAiAccuracyGraphKnots, + weaponFullDef.weapCompleteDef.aiVsAiAccuracyGraphKnotCount, + context)) + { return false; - - ConvertAccuracyGraph(*graph, - weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnots, - weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnotCount, - weaponFullDef.weapCompleteDef.aiVsAiAccuracyGraphKnots, - weaponFullDef.weapCompleteDef.aiVsAiAccuracyGraphKnotCount, - memory); + } } if (weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName && weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName[0]) { - const auto* graph = accuracyGraphLoader.LoadAiVsPlayerGraph(searchPath, weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName); - if (!graph) + if (!LoadAccuracyGraph(weapon::GetAssetNameForAiVsPlayerAccuracyGraph(weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName), + weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnots, + weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnotCount, + weaponFullDef.weapCompleteDef.aiVsPlayerAccuracyGraphKnots, + weaponFullDef.weapCompleteDef.aiVsPlayerAccuracyGraphKnotCount, + context)) + { return false; - - ConvertAccuracyGraph(*graph, - weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnots, - weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnotCount, - weaponFullDef.weapCompleteDef.aiVsPlayerAccuracyGraphKnots, - weaponFullDef.weapCompleteDef.aiVsPlayerAccuracyGraphKnotCount, - memory); + } } return true; diff --git a/src/ObjLoading/Game/T5/ObjLoaderT5.cpp b/src/ObjLoading/Game/T5/ObjLoaderT5.cpp index d25ac544..6508efe5 100644 --- a/src/ObjLoading/Game/T5/ObjLoaderT5.cpp +++ b/src/ObjLoading/Game/T5/ObjLoaderT5.cpp @@ -8,6 +8,7 @@ #include "Game/T5/T5.h" #include "Game/T5/Techset/PixelShaderLoaderT5.h" #include "Game/T5/Techset/VertexShaderLoaderT5.h" +#include "Game/T5/Weapon/AccuracyGraphLoaderT5.h" #include "Game/T5/XAnim/XAnimLoaderT5.h" #include "Game/T5/XModel/LoaderXModelT5.h" #include "LightDef/LightDefLoaderT5.h" @@ -150,6 +151,7 @@ namespace collection.AddSubAssetCreator(techset::CreateVertexShaderLoaderT5(memory, searchPath)); collection.AddSubAssetCreator(techset::CreatePixelShaderLoaderT5(memory, searchPath)); + collection.AddSubAssetCreator(weapon::CreateAccuracyGraphLoaderT5(memory, searchPath)); collection.AddSubAssetCreator(weapon::CreateFlameTableLoaderT5(memory, searchPath, zone)); } } // namespace diff --git a/src/ObjLoading/Game/T5/Weapon/WeaponInfoStringLoaderT5.cpp b/src/ObjLoading/Game/T5/Weapon/WeaponInfoStringLoaderT5.cpp index 0c04c3b4..30f9086f 100644 --- a/src/ObjLoading/Game/T5/Weapon/WeaponInfoStringLoaderT5.cpp +++ b/src/ObjLoading/Game/T5/Weapon/WeaponInfoStringLoaderT5.cpp @@ -6,7 +6,7 @@ #include "Game/T5/Weapon/WeaponStrings.h" #include "Utils/Logging/Log.h" #include "Utils/StringUtils.h" -#include "Weapon/AccuracyGraphLoader.h" +#include "Weapon/WeaponCommon.h" #include #include @@ -242,53 +242,58 @@ namespace } }; - void ConvertAccuracyGraph( - const GenericGraph2D& graph, vec2_t*& originalGraphKnots, int& originalGraphKnotCount, vec2_t*& graphKnots, int& graphKnotCount, MemoryManager& memory) + bool LoadAccuracyGraph(const std::string& graphName, + vec2_t*& originalGraphKnots, + int& originalGraphKnotCount, + vec2_t*& graphKnots, + int& graphKnotCount, + AssetCreationContext& context) { - originalGraphKnotCount = static_cast(graph.knots.size()); - originalGraphKnots = memory.Alloc(originalGraphKnotCount); + auto* accuracyGraphAsset = context.LoadSubAsset(graphName); + if (!accuracyGraphAsset) + return false; - for (auto i = 0; i < originalGraphKnotCount; i++) - { - const auto& commonKnot = graph.knots[i]; - originalGraphKnots[i].x = static_cast(commonKnot.x); - originalGraphKnots[i].y = static_cast(commonKnot.y); - } + const auto* accuracyGraph = accuracyGraphAsset->Asset(); - graphKnots = originalGraphKnots; - graphKnotCount = originalGraphKnotCount; + assert(accuracyGraphAsset->m_dependencies.empty()); + assert(accuracyGraphAsset->m_used_script_strings.empty()); + assert(accuracyGraphAsset->m_indirect_asset_references.empty()); + + originalGraphKnots = accuracyGraph->graphKnots; + originalGraphKnotCount = accuracyGraph->graphKnotCount; + + graphKnots = accuracyGraph->graphKnots; + graphKnotCount = accuracyGraph->graphKnotCount; + + return true; } bool LoadAccuracyGraphs(WeaponFullDef& weaponFullDef, MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context) { - auto& accuracyGraphLoader = context.GetZoneAssetCreationState(); - if (weaponFullDef.weapDef.aiVsAiAccuracyGraphName && weaponFullDef.weapDef.aiVsAiAccuracyGraphName[0]) { - const auto* graph = accuracyGraphLoader.LoadAiVsAiGraph(searchPath, weaponFullDef.weapDef.aiVsAiAccuracyGraphName); - if (!graph) + if (!LoadAccuracyGraph(weapon::GetAssetNameForAiVsAiAccuracyGraph(weaponFullDef.weapDef.aiVsAiAccuracyGraphName), + weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnots, + weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnotCount, + weaponFullDef.weapDef.aiVsAiAccuracyGraphKnots, + weaponFullDef.weapDef.aiVsAiAccuracyGraphKnotCount, + context)) + { return false; - - ConvertAccuracyGraph(*graph, - weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnots, - weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnotCount, - weaponFullDef.weapDef.aiVsAiAccuracyGraphKnots, - weaponFullDef.weapDef.aiVsAiAccuracyGraphKnotCount, - memory); + } } if (weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName && weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName[0]) { - const auto* graph = accuracyGraphLoader.LoadAiVsPlayerGraph(searchPath, weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName); - if (!graph) + if (!LoadAccuracyGraph(weapon::GetAssetNameForAiVsPlayerAccuracyGraph(weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName), + weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnots, + weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnotCount, + weaponFullDef.weapDef.aiVsPlayerAccuracyGraphKnots, + weaponFullDef.weapDef.aiVsPlayerAccuracyGraphKnotCount, + context)) + { return false; - - ConvertAccuracyGraph(*graph, - weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnots, - weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnotCount, - weaponFullDef.weapDef.aiVsPlayerAccuracyGraphKnots, - weaponFullDef.weapDef.aiVsPlayerAccuracyGraphKnotCount, - memory); + } } return true; diff --git a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp index e229c05a..9d448942 100644 --- a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp +++ b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp @@ -11,6 +11,7 @@ #include "Game/T6/T6.h" #include "Game/T6/Techset/PixelShaderLoaderT6.h" #include "Game/T6/Techset/VertexShaderLoaderT6.h" +#include "Game/T6/Weapon/AccuracyGraphLoaderT6.h" #include "Game/T6/XAnim/XAnimLoaderT6.h" #include "Game/T6/XModel/LoaderXModelT6.h" #include "Image/Dx12TextureLoader.h" @@ -442,6 +443,7 @@ namespace T6 collection.AddSubAssetCreator(techset::CreateVertexShaderLoaderT6(memory, searchPath)); collection.AddSubAssetCreator(techset::CreatePixelShaderLoaderT6(memory, searchPath)); + collection.AddSubAssetCreator(weapon::CreateAccuracyGraphLoaderT6(memory, searchPath)); collection.AddSubAssetCreator(weapon::CreateFlameTableLoaderT6(memory, searchPath, zone)); } } // namespace diff --git a/src/ObjLoading/Game/T6/Weapon/WeaponInfoStringLoaderT6.cpp b/src/ObjLoading/Game/T6/Weapon/WeaponInfoStringLoaderT6.cpp index 596912c2..8913af24 100644 --- a/src/ObjLoading/Game/T6/Weapon/WeaponInfoStringLoaderT6.cpp +++ b/src/ObjLoading/Game/T6/Weapon/WeaponInfoStringLoaderT6.cpp @@ -7,7 +7,7 @@ #include "Game/T6/Weapon/WeaponStrings.h" #include "Utils/Logging/Log.h" #include "Utils/StringUtils.h" -#include "Weapon/AccuracyGraphLoader.h" +#include "Weapon/WeaponCommon.h" #include #include @@ -391,53 +391,58 @@ namespace } }; - void ConvertAccuracyGraph( - const GenericGraph2D& graph, vec2_t*& originalGraphKnots, int& originalGraphKnotCount, vec2_t*& graphKnots, int& graphKnotCount, MemoryManager& memory) + bool LoadAccuracyGraph(const std::string& graphName, + vec2_t*& originalGraphKnots, + int& originalGraphKnotCount, + vec2_t*& graphKnots, + int& graphKnotCount, + AssetCreationContext& context) { - originalGraphKnotCount = static_cast(graph.knots.size()); - originalGraphKnots = memory.Alloc(originalGraphKnotCount); + auto* accuracyGraphAsset = context.LoadSubAsset(graphName); + if (!accuracyGraphAsset) + return false; - for (auto i = 0; i < originalGraphKnotCount; i++) - { - const auto& commonKnot = graph.knots[i]; - originalGraphKnots[i].x = static_cast(commonKnot.x); - originalGraphKnots[i].y = static_cast(commonKnot.y); - } + const auto* accuracyGraph = accuracyGraphAsset->Asset(); - graphKnots = originalGraphKnots; - graphKnotCount = originalGraphKnotCount; + assert(accuracyGraphAsset->m_dependencies.empty()); + assert(accuracyGraphAsset->m_used_script_strings.empty()); + assert(accuracyGraphAsset->m_indirect_asset_references.empty()); + + originalGraphKnots = accuracyGraph->graphKnots; + originalGraphKnotCount = accuracyGraph->graphKnotCount; + + graphKnots = accuracyGraph->graphKnots; + graphKnotCount = accuracyGraph->graphKnotCount; + + return true; } bool LoadAccuracyGraphs(WeaponFullDef& weaponFullDef, MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context) { - auto& accuracyGraphLoader = context.GetZoneAssetCreationState(); - if (weaponFullDef.weapDef.aiVsAiAccuracyGraphName && weaponFullDef.weapDef.aiVsAiAccuracyGraphName[0]) { - const auto* graph = accuracyGraphLoader.LoadAiVsAiGraph(searchPath, weaponFullDef.weapDef.aiVsAiAccuracyGraphName); - if (!graph) + if (!LoadAccuracyGraph(weapon::GetAssetNameForAiVsAiAccuracyGraph(weaponFullDef.weapDef.aiVsAiAccuracyGraphName), + weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnots, + weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnotCount, + weaponFullDef.weapDef.aiVsAiAccuracyGraphKnots, + weaponFullDef.weapDef.aiVsAiAccuracyGraphKnotCount, + context)) + { return false; - - ConvertAccuracyGraph(*graph, - weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnots, - weaponFullDef.weapDef.originalAiVsAiAccuracyGraphKnotCount, - weaponFullDef.weapDef.aiVsAiAccuracyGraphKnots, - weaponFullDef.weapDef.aiVsAiAccuracyGraphKnotCount, - memory); + } } if (weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName && weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName[0]) { - const auto* graph = accuracyGraphLoader.LoadAiVsPlayerGraph(searchPath, weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName); - if (!graph) + if (!LoadAccuracyGraph(weapon::GetAssetNameForAiVsPlayerAccuracyGraph(weaponFullDef.weapDef.aiVsPlayerAccuracyGraphName), + weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnots, + weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnotCount, + weaponFullDef.weapDef.aiVsPlayerAccuracyGraphKnots, + weaponFullDef.weapDef.aiVsPlayerAccuracyGraphKnotCount, + context)) + { return false; - - ConvertAccuracyGraph(*graph, - weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnots, - weaponFullDef.weapDef.originalAiVsPlayerAccuracyGraphKnotCount, - weaponFullDef.weapDef.aiVsPlayerAccuracyGraphKnots, - weaponFullDef.weapDef.aiVsPlayerAccuracyGraphKnotCount, - memory); + } } return true; diff --git a/src/ObjLoading/Weapon/AccuracyGraphLoader.cpp b/src/ObjLoading/Weapon/AccuracyGraphLoader.cpp deleted file mode 100644 index 9c05316f..00000000 --- a/src/ObjLoading/Weapon/AccuracyGraphLoader.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "AccuracyGraphLoader.h" - -#include "Parsing/Graph2D/Graph2DReader.h" -#include "Utils/Logging/Log.h" - -#include -#include - -namespace -{ - std::unique_ptr LoadAccuracyGraph(ISearchPath& searchPath, const std::string& graphName, const std::string& subFolder) - { - const auto fileName = std::format("accuracy/{}/{}", subFolder, graphName); - const auto file = searchPath.Open(fileName); - if (!file.IsOpen()) - { - con::error("Failed to open file for accuracy graph: {}/{}", subFolder, graphName); - return nullptr; - } - - return graph2d::Read("accuracy graph", "WEAPONACCUFILE", *file.m_stream, fileName, graphName); - } -} // namespace - -const GenericGraph2D* AccuracyGraphLoader::LoadAiVsAiGraph(ISearchPath& searchPath, const std::string& graphName) -{ - const auto alreadyLoadedGraph = m_loaded_ai_vs_ai_graphs.find(graphName); - if (alreadyLoadedGraph != m_loaded_ai_vs_ai_graphs.end()) - return alreadyLoadedGraph->second.get(); - - auto graph = LoadAccuracyGraph(searchPath, graphName, "aivsai"); - if (!graph) - return nullptr; - - const auto* graphPtr = graph.get(); - m_loaded_ai_vs_ai_graphs.emplace(graphName, std::move(graph)); - - return graphPtr; -} - -const GenericGraph2D* AccuracyGraphLoader::LoadAiVsPlayerGraph(ISearchPath& searchPath, const std::string& graphName) -{ - const auto alreadyLoadedGraph = m_loaded_ai_vs_player_graphs.find(graphName); - if (alreadyLoadedGraph != m_loaded_ai_vs_player_graphs.end()) - return alreadyLoadedGraph->second.get(); - - auto graph = LoadAccuracyGraph(searchPath, graphName, "aivsplayer"); - if (!graph) - return nullptr; - - const auto* graphPtr = graph.get(); - m_loaded_ai_vs_player_graphs.emplace(graphName, std::move(graph)); - - return graphPtr; -} diff --git a/src/ObjLoading/Weapon/AccuracyGraphLoader.cpp.template b/src/ObjLoading/Weapon/AccuracyGraphLoader.cpp.template new file mode 100644 index 00000000..8e616d6e --- /dev/null +++ b/src/ObjLoading/Weapon/AccuracyGraphLoader.cpp.template @@ -0,0 +1,71 @@ +#options GAME(IW4, IW5, T5, T6) + +#filename "Game/" + GAME + "/Weapon/AccuracyGraphLoader" + GAME + ".cpp" + +#set LOADER_HEADER "\"AccuracyGraphLoader" + GAME + ".h\"" + +#include LOADER_HEADER + +#include "Parsing/Graph2D/Graph2DReader.h" +#include "Utils/Logging/Log.h" +#include "Weapon/WeaponCommon.h" + +#include +#include + +using namespace GAME; + +namespace +{ + class AccuracyGraphLoader final : public SubAssetCreator + { + public: + AccuracyGraphLoader(MemoryManager& memory, ISearchPath& searchPath) + : m_memory(memory), + m_search_path(searchPath) + { + } + + AssetCreationResult CreateSubAsset(const std::string& assetName, AssetCreationContext& context) override + { + const auto fileName = weapon::GetFileNameForAccuracyGraph(assetName); + const auto file = m_search_path.Open(fileName); + if (!file.IsOpen()) + return AssetCreationResult::NoAction(); + + auto* accuracyGraph = m_memory.Alloc(); + const auto commonAccuracyGraph = graph2d::Read("accuracy graph", "WEAPONACCUFILE", *file.m_stream, fileName, assetName); + if (!commonAccuracyGraph) + { + con::error("Failed to load accuracy graph \"{}\"", assetName); + return AssetCreationResult::Failure(); + } + + accuracyGraph->graphKnotCount = static_cast(commonAccuracyGraph->knots.size()); + accuracyGraph->graphKnots = m_memory.Alloc(accuracyGraph->graphKnotCount); + + for (auto i = 0; i < accuracyGraph->graphKnotCount; i++) + { + const auto& commonKnot = commonAccuracyGraph->knots[i]; + accuracyGraph->graphKnots[i].x = static_cast(commonKnot.x); + accuracyGraph->graphKnots[i].y = static_cast(commonKnot.y); + } + + return AssetCreationResult::Success(context.AddSubAsset(assetName, accuracyGraph)); + } + + private: + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +#set CREATE_LOADER_METHOD "CreateAccuracyGraphLoader" + GAME + +namespace weapon +{ + std::unique_ptr> CREATE_LOADER_METHOD (MemoryManager& memory, ISearchPath& searchPath) + { + return std::make_unique(memory, searchPath); + } +} diff --git a/src/ObjLoading/Weapon/AccuracyGraphLoader.h b/src/ObjLoading/Weapon/AccuracyGraphLoader.h deleted file mode 100644 index 99610f22..00000000 --- a/src/ObjLoading/Weapon/AccuracyGraphLoader.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "Asset/IZoneAssetCreationState.h" -#include "Parsing/GenericGraph2D.h" -#include "SearchPath/ISearchPath.h" - -#include -#include -#include - -class AccuracyGraphLoader final : public IZoneAssetCreationState -{ -public: - const GenericGraph2D* LoadAiVsAiGraph(ISearchPath& searchPath, const std::string& graphName); - const GenericGraph2D* LoadAiVsPlayerGraph(ISearchPath& searchPath, const std::string& graphName); - -private: - std::unordered_map> m_loaded_ai_vs_ai_graphs; - std::unordered_map> m_loaded_ai_vs_player_graphs; -}; diff --git a/src/ObjLoading/Weapon/AccuracyGraphLoader.h.template b/src/ObjLoading/Weapon/AccuracyGraphLoader.h.template new file mode 100644 index 00000000..89e2d295 --- /dev/null +++ b/src/ObjLoading/Weapon/AccuracyGraphLoader.h.template @@ -0,0 +1,21 @@ +#options GAME (IW3, IW4, IW5, T5, T6) + +#filename "Game/" + GAME + "/Weapon/AccuracyGraphLoader" + GAME + ".h" + +#set GAME_HEADER "\"Game/" + GAME + "/" + GAME + ".h\"" + +#pragma once + +#include "Asset/IAssetCreator.h" +#include GAME_HEADER +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +#set CREATE_LOADER_METHOD "CreateAccuracyGraphLoader" + GAME + +namespace weapon +{ + std::unique_ptr> CREATE_LOADER_METHOD (MemoryManager& memory, ISearchPath& searchPath); +} // namespace GAME diff --git a/src/ObjWriting/Game/IW4/Weapon/WeaponDumperIW4.cpp b/src/ObjWriting/Game/IW4/Weapon/WeaponDumperIW4.cpp index 86cc6479..863f83aa 100644 --- a/src/ObjWriting/Game/IW4/Weapon/WeaponDumperIW4.cpp +++ b/src/ObjWriting/Game/IW4/Weapon/WeaponDumperIW4.cpp @@ -222,23 +222,6 @@ namespace } }; - GenericGraph2D ConvertAccuracyGraph(const char* graphName, const vec2_t* originalKnots, const unsigned originalKnotCount) - { - GenericGraph2D graph; - - graph.name = graphName; - graph.knots.resize(originalKnotCount); - - for (auto i = 0u; i < originalKnotCount; i++) - { - auto& knot = graph.knots[i]; - knot.x = originalKnots[i].x; - knot.y = originalKnots[i].y; - } - - return graph; - } - void CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFullDef* fullDef) { fullDef->weapCompleteDef = *weapon; @@ -374,6 +357,23 @@ namespace return converter.Convert(); } + GenericGraph2D ConvertAccuracyGraph(std::string graphName, const vec2_t* originalKnots, const unsigned originalKnotCount) + { + GenericGraph2D graph; + + graph.name = std::move(graphName); + graph.knots.resize(originalKnotCount); + + for (auto i = 0u; i < originalKnotCount; i++) + { + auto& knot = graph.knots[i]; + knot.x = originalKnots[i].x; + knot.y = originalKnots[i].y; + } + + return graph; + } + void DumpAccuracyGraphs(AssetDumpingContext& context, const XAssetInfo& asset) { auto* accuracyGraphWriter = context.GetZoneAssetDumperState(); @@ -383,22 +383,26 @@ namespace if (!weapDef) return; - if (weapDef->aiVsAiAccuracyGraphName && weapDef->originalAiVsAiAccuracyGraphKnots - && accuracyGraphWriter->ShouldDumpAiVsAiGraph(weapDef->aiVsAiAccuracyGraphName)) + if (weapDef->aiVsAiAccuracyGraphName && weapDef->originalAiVsAiAccuracyGraphKnots) { - AccuracyGraphWriter::DumpAiVsAiGraph(context, - ConvertAccuracyGraph(weapDef->aiVsAiAccuracyGraphName, - weapDef->originalAiVsAiAccuracyGraphKnots, - weapDef->originalAiVsAiAccuracyGraphKnotCount)); + auto graphName = weapon::GetAssetNameForAiVsAiAccuracyGraph(weapDef->aiVsAiAccuracyGraphName); + if (accuracyGraphWriter->ShouldDumpGraph(graphName)) + { + const auto graph = + ConvertAccuracyGraph(std::move(graphName), weapDef->originalAiVsAiAccuracyGraphKnots, weapDef->originalAiVsAiAccuracyGraphKnotCount); + AccuracyGraphWriter::DumpGraph(context, graph); + } } - if (weapDef->aiVsPlayerAccuracyGraphName && weapDef->originalAiVsPlayerAccuracyGraphKnots - && accuracyGraphWriter->ShouldDumpAiVsPlayerGraph(weapDef->aiVsPlayerAccuracyGraphName)) + if (weapDef->aiVsPlayerAccuracyGraphName && weapDef->originalAiVsPlayerAccuracyGraphKnots) { - AccuracyGraphWriter::DumpAiVsPlayerGraph(context, - ConvertAccuracyGraph(weapDef->aiVsPlayerAccuracyGraphName, - weapDef->originalAiVsPlayerAccuracyGraphKnots, - weapDef->originalAiVsPlayerAccuracyGraphKnotCount)); + auto graphName = weapon::GetAssetNameForAiVsPlayerAccuracyGraph(weapDef->aiVsPlayerAccuracyGraphName); + if (accuracyGraphWriter->ShouldDumpGraph(graphName)) + { + const auto graph = ConvertAccuracyGraph( + std::move(graphName), weapDef->originalAiVsPlayerAccuracyGraphKnots, weapDef->originalAiVsPlayerAccuracyGraphKnotCount); + AccuracyGraphWriter::DumpGraph(context, graph); + } } } } // namespace diff --git a/src/ObjWriting/Game/IW5/Weapon/WeaponDumperIW5.cpp b/src/ObjWriting/Game/IW5/Weapon/WeaponDumperIW5.cpp index 7221ff70..b32025cb 100644 --- a/src/ObjWriting/Game/IW5/Weapon/WeaponDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/Weapon/WeaponDumperIW5.cpp @@ -536,23 +536,6 @@ namespace const WeaponFullDef* m_weapon; }; - GenericGraph2D ConvertAccuracyGraph(const char* graphName, const vec2_t* originalKnots, const unsigned originalKnotCount) - { - GenericGraph2D graph; - - graph.name = graphName; - graph.knots.resize(originalKnotCount); - - for (auto i = 0u; i < originalKnotCount; i++) - { - auto& knot = graph.knots[i]; - knot.x = originalKnots[i].x; - knot.y = originalKnots[i].y; - } - - return graph; - } - void CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFullDef* fullDef) { fullDef->weapCompleteDef = *weapon; @@ -702,6 +685,23 @@ namespace return converter.Convert(); } + GenericGraph2D ConvertAccuracyGraph(std::string graphName, const vec2_t* originalKnots, const unsigned originalKnotCount) + { + GenericGraph2D graph; + + graph.name = std::move(graphName); + graph.knots.resize(originalKnotCount); + + for (auto i = 0u; i < originalKnotCount; i++) + { + auto& knot = graph.knots[i]; + knot.x = originalKnots[i].x; + knot.y = originalKnots[i].y; + } + + return graph; + } + void DumpAccuracyGraphs(AssetDumpingContext& context, const XAssetInfo& asset) { auto* accuracyGraphWriter = context.GetZoneAssetDumperState(); @@ -711,22 +711,26 @@ namespace if (!weapDef) return; - if (weapDef->aiVsAiAccuracyGraphName && weapDef->originalAiVsAiAccuracyGraphKnots - && accuracyGraphWriter->ShouldDumpAiVsAiGraph(weapDef->aiVsAiAccuracyGraphName)) + if (weapDef->aiVsAiAccuracyGraphName && weapDef->originalAiVsAiAccuracyGraphKnots) { - AccuracyGraphWriter::DumpAiVsAiGraph(context, - ConvertAccuracyGraph(weapDef->aiVsAiAccuracyGraphName, - weapDef->originalAiVsAiAccuracyGraphKnots, - weapDef->originalAiVsAiAccuracyGraphKnotCount)); + auto graphName = weapon::GetAssetNameForAiVsAiAccuracyGraph(weapDef->aiVsAiAccuracyGraphName); + if (accuracyGraphWriter->ShouldDumpGraph(graphName)) + { + const auto graph = + ConvertAccuracyGraph(std::move(graphName), weapDef->originalAiVsAiAccuracyGraphKnots, weapDef->originalAiVsAiAccuracyGraphKnotCount); + AccuracyGraphWriter::DumpGraph(context, graph); + } } - if (weapDef->aiVsPlayerAccuracyGraphName && weapDef->originalAiVsPlayerAccuracyGraphKnots - && accuracyGraphWriter->ShouldDumpAiVsPlayerGraph(weapDef->aiVsPlayerAccuracyGraphName)) + if (weapDef->aiVsPlayerAccuracyGraphName && weapDef->originalAiVsPlayerAccuracyGraphKnots) { - AccuracyGraphWriter::DumpAiVsPlayerGraph(context, - ConvertAccuracyGraph(weapDef->aiVsPlayerAccuracyGraphName, - weapDef->originalAiVsPlayerAccuracyGraphKnots, - weapDef->originalAiVsPlayerAccuracyGraphKnotCount)); + auto graphName = weapon::GetAssetNameForAiVsPlayerAccuracyGraph(weapDef->aiVsPlayerAccuracyGraphName); + if (accuracyGraphWriter->ShouldDumpGraph(graphName)) + { + const auto graph = ConvertAccuracyGraph( + std::move(graphName), weapDef->originalAiVsPlayerAccuracyGraphKnots, weapDef->originalAiVsPlayerAccuracyGraphKnotCount); + AccuracyGraphWriter::DumpGraph(context, graph); + } } } } // namespace diff --git a/src/ObjWriting/Game/T5/Weapon/WeaponDumperT5.cpp b/src/ObjWriting/Game/T5/Weapon/WeaponDumperT5.cpp index eb582a67..5639f290 100644 --- a/src/ObjWriting/Game/T5/Weapon/WeaponDumperT5.cpp +++ b/src/ObjWriting/Game/T5/Weapon/WeaponDumperT5.cpp @@ -190,6 +190,10 @@ namespace break; } + case WFT_ANIM_NAME: + FillFromString(std::string(field.szName), field.iOffset); + break; + case WFT_NUM_FIELD_TYPES: default: assert(false); @@ -225,23 +229,6 @@ namespace } }; - GenericGraph2D ConvertAccuracyGraph(const char* graphName, const vec2_t* originalKnots, const unsigned originalKnotCount) - { - GenericGraph2D graph; - - graph.name = graphName; - graph.knots.resize(originalKnotCount); - - for (auto i = 0u; i < originalKnotCount; i++) - { - auto& knot = graph.knots[i]; - knot.x = originalKnots[i].x; - knot.y = originalKnots[i].y; - } - - return graph; - } - void CopyToFullDef(const WeaponVariantDef* weapon, WeaponFullDef* fullDef) { fullDef->weapVariantDef = *weapon; @@ -341,6 +328,23 @@ namespace return converter.Convert(); } + GenericGraph2D ConvertAccuracyGraph(std::string graphName, const vec2_t* originalKnots, const unsigned originalKnotCount) + { + GenericGraph2D graph; + + graph.name = std::move(graphName); + graph.knots.resize(originalKnotCount); + + for (auto i = 0u; i < originalKnotCount; i++) + { + auto& knot = graph.knots[i]; + knot.x = originalKnots[i].x; + knot.y = originalKnots[i].y; + } + + return graph; + } + void DumpAccuracyGraphs(AssetDumpingContext& context, const XAssetInfo& asset) { auto* accuracyGraphWriter = context.GetZoneAssetDumperState(); @@ -350,22 +354,26 @@ namespace if (!weapDef) return; - if (weapDef->aiVsAiAccuracyGraphName && weapDef->originalAiVsAiAccuracyGraphKnots - && accuracyGraphWriter->ShouldDumpAiVsAiGraph(weapDef->aiVsAiAccuracyGraphName)) + if (weapDef->aiVsAiAccuracyGraphName && weapDef->originalAiVsAiAccuracyGraphKnots) { - AccuracyGraphWriter::DumpAiVsAiGraph(context, - ConvertAccuracyGraph(weapDef->aiVsAiAccuracyGraphName, - weapDef->originalAiVsAiAccuracyGraphKnots, - weapDef->originalAiVsAiAccuracyGraphKnotCount)); + auto graphName = weapon::GetAssetNameForAiVsAiAccuracyGraph(weapDef->aiVsAiAccuracyGraphName); + if (accuracyGraphWriter->ShouldDumpGraph(graphName)) + { + const auto graph = + ConvertAccuracyGraph(std::move(graphName), weapDef->originalAiVsAiAccuracyGraphKnots, weapDef->originalAiVsAiAccuracyGraphKnotCount); + AccuracyGraphWriter::DumpGraph(context, graph); + } } - if (weapDef->aiVsPlayerAccuracyGraphName && weapDef->originalAiVsPlayerAccuracyGraphKnots - && accuracyGraphWriter->ShouldDumpAiVsPlayerGraph(weapDef->aiVsPlayerAccuracyGraphName)) + if (weapDef->aiVsPlayerAccuracyGraphName && weapDef->originalAiVsPlayerAccuracyGraphKnots) { - AccuracyGraphWriter::DumpAiVsPlayerGraph(context, - ConvertAccuracyGraph(weapDef->aiVsPlayerAccuracyGraphName, - weapDef->originalAiVsPlayerAccuracyGraphKnots, - weapDef->originalAiVsPlayerAccuracyGraphKnotCount)); + auto graphName = weapon::GetAssetNameForAiVsPlayerAccuracyGraph(weapDef->aiVsPlayerAccuracyGraphName); + if (accuracyGraphWriter->ShouldDumpGraph(graphName)) + { + const auto graph = ConvertAccuracyGraph( + std::move(graphName), weapDef->originalAiVsPlayerAccuracyGraphKnots, weapDef->originalAiVsPlayerAccuracyGraphKnotCount); + AccuracyGraphWriter::DumpGraph(context, graph); + } } } diff --git a/src/ObjWriting/Game/T6/Weapon/AttachmentUniqueDumperT6.cpp b/src/ObjWriting/Game/T6/Weapon/AttachmentUniqueDumperT6.cpp index a3eeb37e..c06c08a2 100644 --- a/src/ObjWriting/Game/T6/Weapon/AttachmentUniqueDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Weapon/AttachmentUniqueDumperT6.cpp @@ -65,9 +65,14 @@ namespace break; } + case AUFT_NUM_FIELD_TYPES: default: assert(false); break; + + case AUFT_ANIM_NAME: + FillFromString(std::string(field.szName), field.iOffset); + break; } } diff --git a/src/ObjWriting/Game/T6/Weapon/WeaponDumperT6.cpp b/src/ObjWriting/Game/T6/Weapon/WeaponDumperT6.cpp index c9f2a689..a483126d 100644 --- a/src/ObjWriting/Game/T6/Weapon/WeaponDumperT6.cpp +++ b/src/ObjWriting/Game/T6/Weapon/WeaponDumperT6.cpp @@ -287,23 +287,6 @@ namespace } }; - GenericGraph2D ConvertAccuracyGraph(const char* graphName, const vec2_t* originalKnots, const unsigned originalKnotCount) - { - GenericGraph2D graph; - - graph.name = graphName; - graph.knots.resize(originalKnotCount); - - for (auto i = 0u; i < originalKnotCount; i++) - { - auto& knot = graph.knots[i]; - knot.x = originalKnots[i].x; - knot.y = originalKnots[i].y; - } - - return graph; - } - void CopyToFullDef(const WeaponVariantDef* weapon, WeaponFullDef* fullDef) { fullDef->weapVariantDef = *weapon; @@ -450,6 +433,23 @@ namespace return converter.Convert(); } + GenericGraph2D ConvertAccuracyGraph(std::string graphName, const vec2_t* originalKnots, const unsigned originalKnotCount) + { + GenericGraph2D graph; + + graph.name = std::move(graphName); + graph.knots.resize(originalKnotCount); + + for (auto i = 0u; i < originalKnotCount; i++) + { + auto& knot = graph.knots[i]; + knot.x = originalKnots[i].x; + knot.y = originalKnots[i].y; + } + + return graph; + } + void DumpAccuracyGraphs(AssetDumpingContext& context, const XAssetInfo& asset) { auto* accuracyGraphWriter = context.GetZoneAssetDumperState(); @@ -459,22 +459,26 @@ namespace if (!weapDef) return; - if (weapDef->aiVsAiAccuracyGraphName && weapDef->originalAiVsAiAccuracyGraphKnots - && accuracyGraphWriter->ShouldDumpAiVsAiGraph(weapDef->aiVsAiAccuracyGraphName)) + if (weapDef->aiVsAiAccuracyGraphName && weapDef->originalAiVsAiAccuracyGraphKnots) { - AccuracyGraphWriter::DumpAiVsAiGraph(context, - ConvertAccuracyGraph(weapDef->aiVsAiAccuracyGraphName, - weapDef->originalAiVsAiAccuracyGraphKnots, - weapDef->originalAiVsAiAccuracyGraphKnotCount)); + auto graphName = weapon::GetAssetNameForAiVsAiAccuracyGraph(weapDef->aiVsAiAccuracyGraphName); + if (accuracyGraphWriter->ShouldDumpGraph(graphName)) + { + const auto graph = + ConvertAccuracyGraph(std::move(graphName), weapDef->originalAiVsAiAccuracyGraphKnots, weapDef->originalAiVsAiAccuracyGraphKnotCount); + AccuracyGraphWriter::DumpGraph(context, graph); + } } - if (weapDef->aiVsPlayerAccuracyGraphName && weapDef->originalAiVsPlayerAccuracyGraphKnots - && accuracyGraphWriter->ShouldDumpAiVsPlayerGraph(weapDef->aiVsPlayerAccuracyGraphName)) + if (weapDef->aiVsPlayerAccuracyGraphName && weapDef->originalAiVsPlayerAccuracyGraphKnots) { - AccuracyGraphWriter::DumpAiVsPlayerGraph(context, - ConvertAccuracyGraph(weapDef->aiVsPlayerAccuracyGraphName, - weapDef->originalAiVsPlayerAccuracyGraphKnots, - weapDef->originalAiVsPlayerAccuracyGraphKnotCount)); + auto graphName = weapon::GetAssetNameForAiVsPlayerAccuracyGraph(weapDef->aiVsPlayerAccuracyGraphName); + if (accuracyGraphWriter->ShouldDumpGraph(graphName)) + { + const auto graph = ConvertAccuracyGraph( + std::move(graphName), weapDef->originalAiVsPlayerAccuracyGraphKnots, weapDef->originalAiVsPlayerAccuracyGraphKnotCount); + AccuracyGraphWriter::DumpGraph(context, graph); + } } } diff --git a/src/ObjWriting/Weapon/AccuracyGraphWriter.cpp b/src/ObjWriting/Weapon/AccuracyGraphWriter.cpp index 29f70050..932c1a70 100644 --- a/src/ObjWriting/Weapon/AccuracyGraphWriter.cpp +++ b/src/ObjWriting/Weapon/AccuracyGraphWriter.cpp @@ -1,6 +1,8 @@ #include "AccuracyGraphWriter.h" +#include "Game/IW4/Weapon/WeaponDumperIW4.h" #include "Utils/Logging/Log.h" +#include "Weapon/WeaponCommon.h" #include @@ -21,12 +23,12 @@ namespace return false; } - void DumpAccuracyGraph(const AssetDumpingContext& context, const GenericGraph2D& graph, const std::string& subFolder) + void DumpAccuracyGraph(const AssetDumpingContext& context, const GenericGraph2D& graph) { - const auto file = context.OpenAssetFile(std::format("accuracy/{}/{}", subFolder, graph.name)); + const auto file = context.OpenAssetFile(weapon::GetFileNameForAccuracyGraph(graph.name)); if (!file) { - con::error("Failed to open file for accuracy graph: {}/{}", subFolder, graph.name); + con::error("Failed to open file for accuracy graph: {}", graph.name); return; } @@ -38,22 +40,12 @@ namespace } } // namespace -bool AccuracyGraphWriter::ShouldDumpAiVsAiGraph(const std::string& graphName) +bool AccuracyGraphWriter::ShouldDumpGraph(const std::string& graphName) { - return ShouldDumpAccuracyGraph(m_dumped_ai_vs_ai_graphs, graphName); + return ShouldDumpAccuracyGraph(m_dumped_graphs, graphName); } -bool AccuracyGraphWriter::ShouldDumpAiVsPlayerGraph(const std::string& graphName) +void AccuracyGraphWriter::DumpGraph(const AssetDumpingContext& context, const GenericGraph2D& aiVsAiGraph) { - return ShouldDumpAccuracyGraph(m_dumped_ai_vs_player_graphs, graphName); -} - -void AccuracyGraphWriter::DumpAiVsAiGraph(const AssetDumpingContext& context, const GenericGraph2D& aiVsAiGraph) -{ - DumpAccuracyGraph(context, aiVsAiGraph, "aivsai"); -} - -void AccuracyGraphWriter::DumpAiVsPlayerGraph(const AssetDumpingContext& context, const GenericGraph2D& aiVsPlayerGraph) -{ - DumpAccuracyGraph(context, aiVsPlayerGraph, "aivsplayer"); + DumpAccuracyGraph(context, aiVsAiGraph); } diff --git a/src/ObjWriting/Weapon/AccuracyGraphWriter.h b/src/ObjWriting/Weapon/AccuracyGraphWriter.h index 054d5dea..1ddcb7b6 100644 --- a/src/ObjWriting/Weapon/AccuracyGraphWriter.h +++ b/src/ObjWriting/Weapon/AccuracyGraphWriter.h @@ -1,4 +1,5 @@ #pragma once + #include "Dumping/AssetDumpingContext.h" #include "Dumping/IZoneAssetDumperState.h" #include "Parsing/GenericGraph2D.h" @@ -9,13 +10,10 @@ class AccuracyGraphWriter final : public IZoneAssetDumperState { public: - bool ShouldDumpAiVsAiGraph(const std::string& graphName); - bool ShouldDumpAiVsPlayerGraph(const std::string& graphName); + bool ShouldDumpGraph(const std::string& graphName); - static void DumpAiVsAiGraph(const AssetDumpingContext& context, const GenericGraph2D& aiVsAiGraph); - static void DumpAiVsPlayerGraph(const AssetDumpingContext& context, const GenericGraph2D& aiVsPlayerGraph); + static void DumpGraph(const AssetDumpingContext& context, const GenericGraph2D& graph); private: - std::unordered_set m_dumped_ai_vs_ai_graphs; - std::unordered_set m_dumped_ai_vs_player_graphs; + std::unordered_set m_dumped_graphs; };