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
This commit is contained in:
Jan
2026-06-20 17:16:37 +02:00
committed by GitHub
parent b5acacf680
commit b4477ac1a9
29 changed files with 464 additions and 354 deletions
@@ -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<WeaponCompleteDef>& asset)
{
auto* accuracyGraphWriter = context.GetZoneAssetDumperState<AccuracyGraphWriter>();
@@ -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
@@ -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<WeaponCompleteDef>& asset)
{
auto* accuracyGraphWriter = context.GetZoneAssetDumperState<AccuracyGraphWriter>();
@@ -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
@@ -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<WeaponVariantDef>& asset)
{
auto* accuracyGraphWriter = context.GetZoneAssetDumperState<AccuracyGraphWriter>();
@@ -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);
}
}
}
@@ -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;
}
}
@@ -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<WeaponVariantDef>& asset)
{
auto* accuracyGraphWriter = context.GetZoneAssetDumperState<AccuracyGraphWriter>();
@@ -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);
}
}
}
+9 -17
View File
@@ -1,6 +1,8 @@
#include "AccuracyGraphWriter.h"
#include "Game/IW4/Weapon/WeaponDumperIW4.h"
#include "Utils/Logging/Log.h"
#include "Weapon/WeaponCommon.h"
#include <format>
@@ -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);
}
+4 -6
View File
@@ -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<std::string> m_dumped_ai_vs_ai_graphs;
std::unordered_set<std::string> m_dumped_ai_vs_player_graphs;
std::unordered_set<std::string> m_dumped_graphs;
};