From 3201cefd5be1c39c73c893cca8e6a19c9d2c7277 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 18 May 2024 22:43:55 +0200 Subject: [PATCH 1/7] chore: rename accuracy table properties in weapon structs --- src/Common/Game/IW3/IW3_Assets.h | 24 ++++++-------- src/Common/Game/IW4/IW4_Assets.h | 21 ++++++------ src/Common/Game/IW5/IW5_Assets.h | 21 ++++++------ src/Common/Game/T5/T5_Assets.h | 24 ++++++-------- src/Common/Game/T6/T6_Assets.h | 24 ++++++-------- .../Game/IW4/InfoString/WeaponFields.h | 4 +-- .../Game/IW5/InfoString/WeaponFields.h | 4 +-- .../Game/T6/InfoString/WeaponFields.h | 4 +-- src/ZoneCode/Game/IW3/XAssets/WeaponDef.txt | 32 +++++++++---------- .../Game/IW4/XAssets/WeaponCompleteDef.txt | 27 ++++++++-------- .../Game/IW5/XAssets/WeaponCompleteDef.txt | 27 ++++++++-------- .../Game/T5/XAssets/WeaponVariantDef.txt | 32 +++++++++---------- .../Game/T6/XAssets/WeaponVariantDef.txt | 32 +++++++++---------- 13 files changed, 132 insertions(+), 144 deletions(-) diff --git a/src/Common/Game/IW3/IW3_Assets.h b/src/Common/Game/IW3/IW3_Assets.h index a2007ba7..f2ef4fd5 100644 --- a/src/Common/Game/IW3/IW3_Assets.h +++ b/src/Common/Game/IW3/IW3_Assets.h @@ -3091,20 +3091,16 @@ namespace IW3 float fHipViewScatterMax; float fightDist; float maxDist; - // TODO: Order is accuracyGraphName[0] -> originalAccuracyGraphKnots[0] -> accuracyGraphName[1] -> ... - // Which is currently not possible to do in code generation. Afaik this is the only place where this is the case. - // So might be something to fix but on the other hand it might be too much work for this little inconvenience. - // const char* accuracyGraphName[2]; - const char* accuracyGraphName0; - const char* accuracyGraphName1; - // float(*accuracyGraphKnots[2])[2]; - vec2_t* accuracyGraphKnots0; - vec2_t* accuracyGraphKnots1; - // float(*originalAccuracyGraphKnots[2])[2]; - vec2_t* originalAccuracyGraphKnots0; - vec2_t* originalAccuracyGraphKnots1; - int accuracyGraphKnotCount[2]; - int originalAccuracyGraphKnotCount[2]; + const char* aiVsAiAccuracyGraphName; + const char* aiVsPlayerAccuracyGraphName; + vec2_t* aiVsAiAccuracyGraphKnots; + vec2_t* aiVsPlayerAccuracyGraphKnots; + vec2_t* originalAiVsAiAccuracyGraphKnots; + vec2_t* originalAiVsPlayerAccuracyGraphKnots; + int aiVsAiAccuracyGraphKnotCount; + int aiVsPlayerAccuracyGraphKnotCount; + int originalAiVsAiAccuracyGraphKnotCount; + int originalAiVsPlayerAccuracyGraphKnotCount; int iPositionReloadTransTime; float leftArc; float rightArc; diff --git a/src/Common/Game/IW4/IW4_Assets.h b/src/Common/Game/IW4/IW4_Assets.h index ca60a53a..fd2e0479 100644 --- a/src/Common/Game/IW4/IW4_Assets.h +++ b/src/Common/Game/IW4/IW4_Assets.h @@ -4399,15 +4399,12 @@ namespace IW4 float fHipViewScatterMax; float fightDist; float maxDist; - // const char* accuracyGraphName[2];// TODO: Order is accuracyGraphName[0] -> originalAccuracyGraphKnots[0] -> accuracyGraphName[1] -> ... - // Which is currently not possible to do in code generation. Afaik this is the only place where this is the case. - // So might be something to fix but on the other hand it might be too much work for this little inconvenience. - // vec2_t* originalAccuracyGraphKnots[2]; - const char* accuracyGraphName0; - const char* accuracyGraphName1; - vec2_t* originalAccuracyGraphKnots0; - vec2_t* originalAccuracyGraphKnots1; - uint16_t originalAccuracyGraphKnotCount[2]; + const char* aiVsAiAccuracyGraphName; + const char* aiVsPlayerAccuracyGraphName; + vec2_t* originalAiVsAiAccuracyGraphKnots; + vec2_t* originalAiVsPlayerAccuracyGraphKnots; + uint16_t originalAiVsAiAccuracyGraphKnotCount; + uint16_t originalAiVsPlayerAccuracyGraphKnotCount; int iPositionReloadTransTime; float leftArc; float rightArc; @@ -4551,8 +4548,10 @@ namespace IW4 int ammoDropStockMax; float adsDofStart; float adsDofEnd; - uint16_t accuracyGraphKnotCount[2]; - vec2_t* accuracyGraphKnots[2]; + uint16_t aiVsAiAccuracyGraphKnotCount; + uint16_t aiVsPlayerAccuracyGraphKnotCount; + vec2_t* aiVsAiAccuracyGraphKnots; + vec2_t* aiVsPlayerAccuracyGraphKnots; bool motionTracker; bool enhanced; bool dpadIconShowsAmmo; diff --git a/src/Common/Game/IW5/IW5_Assets.h b/src/Common/Game/IW5/IW5_Assets.h index fea3e995..e7555ea3 100644 --- a/src/Common/Game/IW5/IW5_Assets.h +++ b/src/Common/Game/IW5/IW5_Assets.h @@ -3756,15 +3756,12 @@ namespace IW5 float fHipViewScatterMax; float fightDist; float maxDist; - // const char* accuracyGraphName[2];// TODO: Order is accuracyGraphName[0] -> originalAccuracyGraphKnots[0] -> accuracyGraphName[1] -> ... - // Which is currently not possible to do in code generation. Afaik this is the only place where this is the case. - // So might be something to fix but on the other hand it might be too much work for this little inconvenience. - // vec2_t* originalAccuracyGraphKnots[2]; - const char* accuracyGraphName0; - const char* accuracyGraphName1; - vec2_t* originalAccuracyGraphKnots0; - vec2_t* originalAccuracyGraphKnots1; - unsigned short originalAccuracyGraphKnotCount[2]; + const char* aiVsAiAccuracyGraphName; + const char* aiVsPlayerAccuracyGraphName; + vec2_t* originalAiVsAiAccuracyGraphKnots; + vec2_t* originalAiVsPlayerAccuracyGraphKnots; + unsigned short originalAiVsAiAccuracyGraphKnotCount; + unsigned short originalAiVsPlayerAccuracyGraphKnotCount; int iPositionReloadTransTime; float leftArc; float rightArc; @@ -4021,8 +4018,10 @@ namespace IW5 int ammoDropStockMax; float adsDofStart; float adsDofEnd; - unsigned short accuracyGraphKnotCount[2]; - vec2_t* accuracyGraphKnots[2]; + uint16_t aiVsAiAccuracyGraphKnotCount; + uint16_t aiVsPlayerAccuracyGraphKnotCount; + vec2_t* aiVsAiAccuracyGraphKnots; + vec2_t* aiVsPlayerAccuracyGraphKnots; bool motionTracker; bool enhanced; bool dpadIconShowsAmmo; diff --git a/src/Common/Game/T5/T5_Assets.h b/src/Common/Game/T5/T5_Assets.h index 42166cea..fd18616b 100644 --- a/src/Common/Game/T5/T5_Assets.h +++ b/src/Common/Game/T5/T5_Assets.h @@ -3861,20 +3861,16 @@ namespace T5 float fHipViewScatterMax; float fightDist; float maxDist; - // const char *accuracyGraphName[2]; // TODO: Order is accuracyGraphName[0] -> accuracyGraphKnots[0] -> originalAccuracyGraphKnots[0] -> - // accuracyGraphName[1] -> ... - // Which is currently not possible to do in code generation. Afaik this is the only place where this is the case. - // So might be something to fix but on the other hand it might be too much work for this little inconvenience. - const char* accuracyGraphName0; - const char* accuracyGraphName1; - // vec2_t *accuracyGraphKnots[2]; - vec2_t* accuracyGraphKnots0; - vec2_t* accuracyGraphKnots1; - // vec2_t *originalAccuracyGraphKnots[2]; - vec2_t* originalAccuracyGraphKnots0; - vec2_t* originalAccuracyGraphKnots1; - int accuracyGraphKnotCount[2]; - int originalAccuracyGraphKnotCount[2]; + const char* aiVsAiAccuracyGraphName; + const char* aiVsPlayerAccuracyGraphName; + vec2_t* aiVsAiAccuracyGraphKnots; + vec2_t* aiVsPlayerAccuracyGraphKnots; + vec2_t* originalAiVsAiAccuracyGraphKnots; + vec2_t* originalAiVsPlayerAccuracyGraphKnots; + int aiVsAiAccuracyGraphKnotCount; + int aiVsPlayerAccuracyGraphKnotCount; + int originalAiVsAiAccuracyGraphKnotCount; + int originalAiVsPlayerAccuracyGraphKnotCount; int iPositionReloadTransTime; float leftArc; float rightArc; diff --git a/src/Common/Game/T6/T6_Assets.h b/src/Common/Game/T6/T6_Assets.h index 08105163..54fb2a22 100644 --- a/src/Common/Game/T6/T6_Assets.h +++ b/src/Common/Game/T6/T6_Assets.h @@ -4860,20 +4860,16 @@ namespace T6 float fAntiQuickScopeSwayFactor; float fightDist; float maxDist; - // const char *accuracyGraphName[2]; // TODO: Order is accuracyGraphName[0] -> accuracyGraphKnots[0] -> originalAccuracyGraphKnots[0] -> - // accuracyGraphName[1] -> ... - // Which is currently not possible to do in code generation. Afaik this is the only place where this is the case. - // So might be something to fix but on the other hand it might be too much work for this little inconvenience. - const char* accuracyGraphName0; - const char* accuracyGraphName1; - // vec2_t *accuracyGraphKnots[2]; - vec2_t* accuracyGraphKnots0; - vec2_t* accuracyGraphKnots1; - // vec2_t *originalAccuracyGraphKnots[2]; - vec2_t* originalAccuracyGraphKnots0; - vec2_t* originalAccuracyGraphKnots1; - int accuracyGraphKnotCount[2]; - int originalAccuracyGraphKnotCount[2]; + const char* aiVsAiAccuracyGraphName; + const char* aiVsPlayerAccuracyGraphName; + vec2_t* aiVsAiAccuracyGraphKnots; + vec2_t* aiVsPlayerAccuracyGraphKnots; + vec2_t* originalAiVsAiAccuracyGraphKnots; + vec2_t* originalAiVsPlayerAccuracyGraphKnots; + int aiVsAiAccuracyGraphKnotCount; + int aiVsPlayerAccuracyGraphKnotCount; + int originalAiVsAiAccuracyGraphKnotCount; + int originalAiVsPlayerAccuracyGraphKnotCount; int iPositionReloadTransTime; float leftArc; float rightArc; diff --git a/src/ObjCommon/Game/IW4/InfoString/WeaponFields.h b/src/ObjCommon/Game/IW4/InfoString/WeaponFields.h index c1845ea6..98170f45 100644 --- a/src/ObjCommon/Game/IW4/InfoString/WeaponFields.h +++ b/src/ObjCommon/Game/IW4/InfoString/WeaponFields.h @@ -608,8 +608,8 @@ namespace IW4 {"scanPauseTime", offsetof(WeaponFullDef, weapDef.scanPauseTime), CSPFT_MILLISECONDS }, {"fightDist", offsetof(WeaponFullDef, weapDef.fightDist), CSPFT_FLOAT }, {"maxDist", offsetof(WeaponFullDef, weapDef.maxDist), CSPFT_FLOAT }, - {"aiVsAiAccuracyGraph", offsetof(WeaponFullDef, weapDef.accuracyGraphName0), CSPFT_STRING }, - {"aiVsPlayerAccuracyGraph", offsetof(WeaponFullDef, weapDef.accuracyGraphName1), CSPFT_STRING }, + {"aiVsAiAccuracyGraph", offsetof(WeaponFullDef, weapDef.aiVsAiAccuracyGraphName), CSPFT_STRING }, + {"aiVsPlayerAccuracyGraph", offsetof(WeaponFullDef, weapDef.aiVsPlayerAccuracyGraphName), CSPFT_STRING }, {"locNone", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_NONE]), CSPFT_FLOAT }, {"locHelmet", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_HELMET]), CSPFT_FLOAT }, {"locHead", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_HEAD]), CSPFT_FLOAT }, diff --git a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h index ed07cf4b..6dbdce66 100644 --- a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h +++ b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h @@ -697,8 +697,8 @@ namespace IW5 {"scanPauseTime", offsetof(WeaponFullDef, weapDef.scanPauseTime), CSPFT_MILLISECONDS }, {"fightDist", offsetof(WeaponFullDef, weapDef.fightDist), CSPFT_FLOAT }, {"maxDist", offsetof(WeaponFullDef, weapDef.maxDist), CSPFT_FLOAT }, - {"aiVsAiAccuracyGraph", offsetof(WeaponFullDef, weapDef.accuracyGraphName0), CSPFT_STRING }, - {"aiVsPlayerAccuracyGraph", offsetof(WeaponFullDef, weapDef.accuracyGraphName1), CSPFT_STRING }, + {"aiVsAiAccuracyGraph", offsetof(WeaponFullDef, weapDef.aiVsAiAccuracyGraphName), CSPFT_STRING }, + {"aiVsPlayerAccuracyGraph", offsetof(WeaponFullDef, weapDef.aiVsPlayerAccuracyGraphName), CSPFT_STRING }, {"locNone", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_NONE]), CSPFT_FLOAT }, {"locHelmet", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_HELMET]), CSPFT_FLOAT }, {"locHead", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_HEAD]), CSPFT_FLOAT }, diff --git a/src/ObjCommon/Game/T6/InfoString/WeaponFields.h b/src/ObjCommon/Game/T6/InfoString/WeaponFields.h index cb8f4757..913e81a4 100644 --- a/src/ObjCommon/Game/T6/InfoString/WeaponFields.h +++ b/src/ObjCommon/Game/T6/InfoString/WeaponFields.h @@ -952,8 +952,8 @@ namespace T6 {"explosionCameraShakeRadius", offsetof(WeaponFullDef, weapDef.explosionCameraShakeRadius), CSPFT_INT }, {"fightDist", offsetof(WeaponFullDef, weapDef.fightDist), CSPFT_FLOAT }, {"maxDist", offsetof(WeaponFullDef, weapDef.maxDist), CSPFT_FLOAT }, - {"aiVsAiAccuracyGraph", offsetof(WeaponFullDef, weapDef.accuracyGraphName0), CSPFT_STRING }, - {"aiVsPlayerAccuracyGraph", offsetof(WeaponFullDef, weapDef.accuracyGraphName1), CSPFT_STRING }, + {"aiVsAiAccuracyGraph", offsetof(WeaponFullDef, weapDef.aiVsAiAccuracyGraphName), CSPFT_STRING }, + {"aiVsPlayerAccuracyGraph", offsetof(WeaponFullDef, weapDef.aiVsPlayerAccuracyGraphName), CSPFT_STRING }, {"locNone", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_NONE]), CSPFT_FLOAT }, {"locHelmet", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_HELMET]), CSPFT_FLOAT }, {"locHead", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_HEAD]), CSPFT_FLOAT }, diff --git a/src/ZoneCode/Game/IW3/XAssets/WeaponDef.txt b/src/ZoneCode/Game/IW3/XAssets/WeaponDef.txt index 8b4d4a9a..797d6682 100644 --- a/src/ZoneCode/Game/IW3/XAssets/WeaponDef.txt +++ b/src/ZoneCode/Game/IW3/XAssets/WeaponDef.txt @@ -19,16 +19,16 @@ set string szAmmoName; set string szClipName; set string szSharedAmmoCapName; set string szAltWeaponName; -set string accuracyGraphName0; -set string accuracyGraphName1; -set reusable accuracyGraphKnots0; -set reusable accuracyGraphKnots1; -set reusable originalAccuracyGraphKnots0; -set reusable originalAccuracyGraphKnots1; -set count accuracyGraphKnots0 accuracyGraphKnotCount[0]; -set count accuracyGraphKnots1 accuracyGraphKnotCount[1]; -set count originalAccuracyGraphKnots0 accuracyGraphKnotCount[0]; // yeah it uses accuracyGraphKnotCount -set count originalAccuracyGraphKnots1 accuracyGraphKnotCount[1]; +set string aiVsAiAccuracyGraphName; +set string aiVsPlayerAccuracyGraphName; +set reusable aiVsAiAccuracyGraphKnots; +set count aiVsAiAccuracyGraphKnots aiVsAiAccuracyGraphKnotCount; +set reusable aiVsPlayerAccuracyGraphKnots; +set count aiVsPlayerAccuracyGraphKnots aiVsPlayerAccuracyGraphKnotCount; +set reusable originalAiVsAiAccuracyGraphKnots; +set count originalAiVsAiAccuracyGraphKnots aiVsAiAccuracyGraphKnotCount; // yeah it does not use original count +set reusable originalAiVsPlayerAccuracyGraphKnots; +set count originalAiVsPlayerAccuracyGraphKnots aiVsPlayerAccuracyGraphKnotCount; // yeah it does not use original count set string szUseHintString; set string dropHintString; set string szScript; @@ -37,12 +37,12 @@ set string meleeImpactRumble; reorder: ... -accuracyGraphName0 -accuracyGraphKnots0 -originalAccuracyGraphKnots0 -accuracyGraphName1 -accuracyGraphKnots1 -originalAccuracyGraphKnots1; +aiVsAiAccuracyGraphName +aiVsAiAccuracyGraphKnots +originalAiVsAiAccuracyGraphKnots +aiVsPlayerAccuracyGraphName +aiVsPlayerAccuracyGraphKnots +originalAiVsPlayerAccuracyGraphKnots; // SndAliasCustom use SndAliasCustom; diff --git a/src/ZoneCode/Game/IW4/XAssets/WeaponCompleteDef.txt b/src/ZoneCode/Game/IW4/XAssets/WeaponCompleteDef.txt index 51d9a0c2..14ec6659 100644 --- a/src/ZoneCode/Game/IW4/XAssets/WeaponCompleteDef.txt +++ b/src/ZoneCode/Game/IW4/XAssets/WeaponCompleteDef.txt @@ -15,9 +15,10 @@ set assetref szXAnims ASSET_TYPE_XANIMPARTS; set reusable szXAnims; set count szXAnims 37; set string szAltWeaponName; -set reusable accuracyGraphKnots; -set count accuracyGraphKnots[0] accuracyGraphKnotCount[0]; -set count accuracyGraphKnots[1] accuracyGraphKnotCount[1]; +set reusable aiVsAiAccuracyGraphKnots; +set count aiVsAiAccuracyGraphKnots aiVsAiAccuracyGraphKnotCount; +set reusable aiVsPlayerAccuracyGraphKnots; +set count aiVsPlayerAccuracyGraphKnots aiVsPlayerAccuracyGraphKnotCount; // WeaponDef use WeaponDef; @@ -56,12 +57,12 @@ set reusable parallelBounce; set count parallelBounce SURF_TYPE_NUM; set reusable perpendicularBounce; set count perpendicularBounce SURF_TYPE_NUM; -set string accuracyGraphName0; -set string accuracyGraphName1; -set reusable originalAccuracyGraphKnots0; -set reusable originalAccuracyGraphKnots1; -set count originalAccuracyGraphKnots0 WeaponCompleteDef::accuracyGraphKnotCount[0]; -set count originalAccuracyGraphKnots1 WeaponCompleteDef::accuracyGraphKnotCount[1]; +set string aiVsAiAccuracyGraphName; +set string aiVsPlayerAccuracyGraphName; +set reusable originalAiVsAiAccuracyGraphKnots; +set count originalAiVsAiAccuracyGraphKnots WeaponCompleteDef::aiVsAiAccuracyGraphKnotCount; +set reusable originalAiVsPlayerAccuracyGraphKnots; +set count originalAiVsPlayerAccuracyGraphKnots WeaponCompleteDef::aiVsPlayerAccuracyGraphKnotCount; set string szUseHintString; set string dropHintString; set string szScript; @@ -72,10 +73,10 @@ set string meleeImpactRumble; set string turretBarrelSpinRumble; reorder: ... - accuracyGraphName0 - originalAccuracyGraphKnots0 - accuracyGraphName1 - originalAccuracyGraphKnots1; + aiVsAiAccuracyGraphName + originalAiVsAiAccuracyGraphKnots + aiVsPlayerAccuracyGraphName + originalAiVsPlayerAccuracyGraphKnots; // SndAliasCustom use SndAliasCustom; diff --git a/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt b/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt index 4e69504f..857cae9d 100644 --- a/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt +++ b/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt @@ -31,9 +31,10 @@ set count reloadOverrides numReloadStateTimerOverrides; set reusable notetrackOverrides; set count notetrackOverrides numNotetrackOverrides; set string szAltWeaponName; -set reusable accuracyGraphKnots; -set count accuracyGraphKnots[0] accuracyGraphKnotCount[0]; -set count accuracyGraphKnots[1] accuracyGraphKnotCount[1]; +set reusable aiVsAiAccuracyGraphKnots; +set count aiVsAiAccuracyGraphKnots aiVsAiAccuracyGraphKnotCount; +set reusable aiVsPlayerAccuracyGraphKnots; +set count aiVsPlayerAccuracyGraphKnots aiVsPlayerAccuracyGraphKnotCount; // AnimOverrideEntry use AnimOverrideEntry; @@ -90,12 +91,12 @@ set reusable parallelBounce; set count parallelBounce SURF_TYPE_COUNT; set reusable perpendicularBounce; set count perpendicularBounce SURF_TYPE_COUNT; -set string accuracyGraphName0; -set string accuracyGraphName1; -set reusable originalAccuracyGraphKnots0; -set reusable originalAccuracyGraphKnots1; -set count originalAccuracyGraphKnots0 WeaponCompleteDef::accuracyGraphKnotCount[0]; -set count originalAccuracyGraphKnots1 WeaponCompleteDef::accuracyGraphKnotCount[1]; +set string aiVsAiAccuracyGraphName; +set string aiVsPlayerAccuracyGraphName; +set reusable originalAiVsAiAccuracyGraphKnots; +set count originalAiVsAiAccuracyGraphKnots WeaponCompleteDef::aiVsAiAccuracyGraphKnotCount; +set reusable originalAiVsPlayerAccuracyGraphKnots; +set count originalAiVsPlayerAccuracyGraphKnots WeaponCompleteDef::aiVsPlayerAccuracyGraphKnotCount; set string szUseHintString; set string dropHintString; set string szScript; @@ -107,10 +108,10 @@ set string turretBarrelSpinRumble; set scriptstring stowTag; reorder: ... - accuracyGraphName0 - originalAccuracyGraphKnots0 - accuracyGraphName1 - originalAccuracyGraphKnots1; + aiVsAiAccuracyGraphName + originalAiVsAiAccuracyGraphKnots + aiVsPlayerAccuracyGraphName + originalAiVsPlayerAccuracyGraphKnots; // SndAliasCustom use SndAliasCustom; diff --git a/src/ZoneCode/Game/T5/XAssets/WeaponVariantDef.txt b/src/ZoneCode/Game/T5/XAssets/WeaponVariantDef.txt index 6a3899d6..5789c9e6 100644 --- a/src/ZoneCode/Game/T5/XAssets/WeaponVariantDef.txt +++ b/src/ZoneCode/Game/T5/XAssets/WeaponVariantDef.txt @@ -126,16 +126,16 @@ set reusable parallelBounce; set count perpendicularBounce SURF_TYPE_NUM; set reusable perpendicularBounce; set string projIgnitionSound; -set string accuracyGraphName0; -set string accuracyGraphName1; -set reusable accuracyGraphKnots0; -set reusable accuracyGraphKnots1; -set count accuracyGraphKnots0 accuracyGraphKnotCount[0]; -set count accuracyGraphKnots1 accuracyGraphKnotCount[1]; -set reusable originalAccuracyGraphKnots0; -set reusable originalAccuracyGraphKnots1; -set count originalAccuracyGraphKnots0 accuracyGraphKnotCount[0]; -set count originalAccuracyGraphKnots1 accuracyGraphKnotCount[1]; +set string aiVsAiAccuracyGraphName; +set string aiVsPlayerAccuracyGraphName; +set reusable aiVsAiAccuracyGraphKnots; +set count aiVsAiAccuracyGraphKnots aiVsAiAccuracyGraphKnotCount; +set reusable aiVsPlayerAccuracyGraphKnots; +set count aiVsPlayerAccuracyGraphKnots aiVsPlayerAccuracyGraphKnotCount; +set reusable originalAiVsAiAccuracyGraphKnots; +set count originalAiVsAiAccuracyGraphKnots aiVsAiAccuracyGraphKnotCount; // yeah it does not use original count +set reusable originalAiVsPlayerAccuracyGraphKnots; +set count originalAiVsPlayerAccuracyGraphKnots aiVsPlayerAccuracyGraphKnotCount; // yeah it does not use original count set string szUseHintString; set string dropHintString; set string szScript; @@ -151,12 +151,12 @@ set reusable flameTableThirdPersonPtr; reorder: ... -accuracyGraphName0 -accuracyGraphKnots0 -originalAccuracyGraphKnots0 -accuracyGraphName1 -accuracyGraphKnots1 -originalAccuracyGraphKnots1; +aiVsAiAccuracyGraphName +aiVsAiAccuracyGraphKnots +originalAiVsAiAccuracyGraphKnots +aiVsPlayerAccuracyGraphName +aiVsPlayerAccuracyGraphKnots +originalAiVsPlayerAccuracyGraphKnots; reorder: ... diff --git a/src/ZoneCode/Game/T6/XAssets/WeaponVariantDef.txt b/src/ZoneCode/Game/T6/XAssets/WeaponVariantDef.txt index 590bbb7c..49eee990 100644 --- a/src/ZoneCode/Game/T6/XAssets/WeaponVariantDef.txt +++ b/src/ZoneCode/Game/T6/XAssets/WeaponVariantDef.txt @@ -147,16 +147,16 @@ set reusable parallelBounce; set count perpendicularBounce SURF_TYPE_NUM; set reusable perpendicularBounce; set string projIgnitionSound; -set string accuracyGraphName0; -set string accuracyGraphName1; -set reusable accuracyGraphKnots0; -set reusable accuracyGraphKnots1; -set count accuracyGraphKnots0 accuracyGraphKnotCount[0]; -set count accuracyGraphKnots1 accuracyGraphKnotCount[1]; -set reusable originalAccuracyGraphKnots0; -set reusable originalAccuracyGraphKnots1; -set count originalAccuracyGraphKnots0 accuracyGraphKnotCount[0]; -set count originalAccuracyGraphKnots1 accuracyGraphKnotCount[1]; +set string aiVsAiAccuracyGraphName; +set string aiVsPlayerAccuracyGraphName; +set reusable aiVsAiAccuracyGraphKnots; +set count aiVsAiAccuracyGraphKnots aiVsAiAccuracyGraphKnotCount; +set reusable aiVsPlayerAccuracyGraphKnots; +set count aiVsPlayerAccuracyGraphKnots aiVsPlayerAccuracyGraphKnotCount; +set reusable originalAiVsAiAccuracyGraphKnots; +set count originalAiVsAiAccuracyGraphKnots aiVsAiAccuracyGraphKnotCount; // yeah it does not use original count +set reusable originalAiVsPlayerAccuracyGraphKnots; +set count originalAiVsPlayerAccuracyGraphKnots aiVsPlayerAccuracyGraphKnotCount; // yeah it does not use original count set string szUseHintString; set string dropHintString; set string szScript; @@ -174,12 +174,12 @@ set string throwBackType; reorder: ... -accuracyGraphName0 -accuracyGraphKnots0 -originalAccuracyGraphKnots0 -accuracyGraphName1 -accuracyGraphKnots1 -originalAccuracyGraphKnots1; +aiVsAiAccuracyGraphName +aiVsAiAccuracyGraphKnots +originalAiVsAiAccuracyGraphKnots +aiVsPlayerAccuracyGraphName +aiVsPlayerAccuracyGraphKnots +originalAiVsPlayerAccuracyGraphKnots; reorder: ... From 5c0d1e4d99ca113caaced78cd5c7d31690028840 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 18 May 2024 23:38:57 +0200 Subject: [PATCH 2/7] chore: add writer for accuracy graphs --- src/ObjCommon/Weapon/GenericAccuracyGraph.h | 17 ++++++ src/ObjWriting/Weapon/AccuracyGraphWriter.cpp | 57 +++++++++++++++++++ src/ObjWriting/Weapon/AccuracyGraphWriter.h | 21 +++++++ 3 files changed, 95 insertions(+) create mode 100644 src/ObjCommon/Weapon/GenericAccuracyGraph.h create mode 100644 src/ObjWriting/Weapon/AccuracyGraphWriter.cpp create mode 100644 src/ObjWriting/Weapon/AccuracyGraphWriter.h diff --git a/src/ObjCommon/Weapon/GenericAccuracyGraph.h b/src/ObjCommon/Weapon/GenericAccuracyGraph.h new file mode 100644 index 00000000..2f827204 --- /dev/null +++ b/src/ObjCommon/Weapon/GenericAccuracyGraph.h @@ -0,0 +1,17 @@ +#pragma once +#include +#include + +class GenericAccuracyGraphKnot +{ +public: + float x; + float y; +}; + +class GenericAccuracyGraph +{ +public: + std::string name; + std::vector knots; +}; diff --git a/src/ObjWriting/Weapon/AccuracyGraphWriter.cpp b/src/ObjWriting/Weapon/AccuracyGraphWriter.cpp new file mode 100644 index 00000000..b6f0583f --- /dev/null +++ b/src/ObjWriting/Weapon/AccuracyGraphWriter.cpp @@ -0,0 +1,57 @@ +#include "AccuracyGraphWriter.h" + +#include + +namespace +{ + bool ShouldDumpAccuracyGraph(std::unordered_set& dumpedGraphs, const std::string& graphName) + { + if (graphName.empty()) + return false; + + const auto existingEntry = dumpedGraphs.find(graphName); + if (existingEntry == dumpedGraphs.end()) + { + dumpedGraphs.emplace(graphName); + return true; + } + + return false; + } + + void DumpAccuracyGraph(const AssetDumpingContext& context, const GenericAccuracyGraph& graph, const std::string& subFolder) + { + const auto file = context.OpenAssetFile(std::format("accuracy/{}/{}", subFolder, graph.name)); + if (!file) + { + std::cerr << "Failed to open file for accuracy graph: " << subFolder << "/" << graph.name << "\n"; + return; + } + + *file << "WEAPONACCUFILE\n\n"; + *file << graph.knots.size() << "\n"; + + for (const auto& knot : graph.knots) + *file << std::format("{:.4f} {:.4f}\n", knot.x, knot.y); + } +} // namespace + +bool AccuracyGraphWriter::ShouldDumpAiVsAiGraph(const std::string& graphName) +{ + return ShouldDumpAccuracyGraph(m_dumped_ai_vs_ai_graphs, graphName); +} + +bool AccuracyGraphWriter::ShouldDumpAiVsPlayerGraph(const std::string& graphName) +{ + return ShouldDumpAccuracyGraph(m_dumped_ai_vs_player_graphs, graphName); +} + +void AccuracyGraphWriter::DumpAiVsAiGraph(const AssetDumpingContext& context, const GenericAccuracyGraph& aiVsAiGraph) +{ + DumpAccuracyGraph(context, aiVsAiGraph, "aivsai"); +} + +void AccuracyGraphWriter::DumpAiVsPlayerGraph(const AssetDumpingContext& context, const GenericAccuracyGraph& aiVsPlayerGraph) +{ + DumpAccuracyGraph(context, aiVsPlayerGraph, "aivsplayer"); +} diff --git a/src/ObjWriting/Weapon/AccuracyGraphWriter.h b/src/ObjWriting/Weapon/AccuracyGraphWriter.h new file mode 100644 index 00000000..a5e2edc3 --- /dev/null +++ b/src/ObjWriting/Weapon/AccuracyGraphWriter.h @@ -0,0 +1,21 @@ +#pragma once +#include "Dumping/AssetDumpingContext.h" +#include "Dumping/IZoneAssetDumperState.h" +#include "Weapon/GenericAccuracyGraph.h" + +#include +#include + +class AccuracyGraphWriter final : public IZoneAssetDumperState +{ +public: + bool ShouldDumpAiVsAiGraph(const std::string& graphName); + bool ShouldDumpAiVsPlayerGraph(const std::string& graphName); + + static void DumpAiVsAiGraph(const AssetDumpingContext& context, const GenericAccuracyGraph& aiVsAiGraph); + static void DumpAiVsPlayerGraph(const AssetDumpingContext& context, const GenericAccuracyGraph& aiVsPlayerGraph); + +private: + std::unordered_set m_dumped_ai_vs_ai_graphs; + std::unordered_set m_dumped_ai_vs_player_graphs; +}; From 36a2e48e5baaaf1ff6674c6530adf5c9f9c5f375 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 18 May 2024 23:39:17 +0200 Subject: [PATCH 3/7] feat: dump iw5 accuracy graphs --- .../IW5/AssetDumpers/AssetDumperWeapon.cpp | 48 +++++++++++++++++++ .../Game/IW5/AssetDumpers/AssetDumperWeapon.h | 1 + 2 files changed, 49 insertions(+) diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp index 519d00f5..eb66f1e4 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp @@ -4,12 +4,14 @@ #include "Game/IW5/InfoString/InfoStringFromStructConverter.h" #include "Game/IW5/InfoString/WeaponFields.h" #include "Game/IW5/ObjConstantsIW5.h" +#include "Weapon/AccuracyGraphWriter.h" #include #include #include #include #include +#include using namespace IW5; @@ -532,6 +534,23 @@ namespace IW5 const WeaponFullDef* m_weapon; }; + + GenericAccuracyGraph ConvertAccuracyGraph(const char* graphName, const vec2_t* originalKnots, const unsigned originalKnotCount) + { + GenericAccuracyGraph graph; + + graph.name = graphName; + graph.knots.resize(originalKnotCount); + + for (auto i = 0u; i < originalKnotCount; i++) + { + auto& knot = graph.knots[i]; + knot.x = originalKnots[i][0]; + knot.y = originalKnots[i][1]; + } + + return graph; + } } // namespace IW5 void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFullDef* fullDef) @@ -681,6 +700,33 @@ InfoString AssetDumperWeapon::CreateInfoString(XAssetInfo* as return converter.Convert(); } +void AssetDumperWeapon::DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo* asset) +{ + auto* accuracyGraphWriter = context.GetZoneAssetDumperState(); + const auto weapon = asset->Asset(); + const auto* weapDef = weapon->weapDef; + + if (!weapDef) + return; + + if (weapDef->aiVsAiAccuracyGraphName && weapDef->originalAiVsAiAccuracyGraphKnots + && accuracyGraphWriter->ShouldDumpAiVsAiGraph(weapDef->aiVsAiAccuracyGraphName)) + { + AccuracyGraphWriter::DumpAiVsAiGraph( + context, + ConvertAccuracyGraph(weapDef->aiVsAiAccuracyGraphName, weapDef->originalAiVsAiAccuracyGraphKnots, weapDef->originalAiVsAiAccuracyGraphKnotCount)); + } + + if (weapDef->aiVsPlayerAccuracyGraphName && weapDef->originalAiVsPlayerAccuracyGraphKnots + && accuracyGraphWriter->ShouldDumpAiVsPlayerGraph(weapDef->aiVsPlayerAccuracyGraphName)) + { + AccuracyGraphWriter::DumpAiVsPlayerGraph(context, + ConvertAccuracyGraph(weapDef->aiVsPlayerAccuracyGraphName, + weapDef->originalAiVsPlayerAccuracyGraphKnots, + weapDef->originalAiVsPlayerAccuracyGraphKnotCount)); + } +} + bool AssetDumperWeapon::ShouldDump(XAssetInfo* asset) { return true; @@ -710,4 +756,6 @@ void AssetDumperWeapon::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset); + static void DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo* asset); protected: bool ShouldDump(XAssetInfo* asset) override; From 879acd35bbd1d9cb5846b0712ead870776831685 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 18 May 2024 23:41:23 +0200 Subject: [PATCH 4/7] feat: dump t6 accuracy graphs --- .../T6/AssetDumpers/AssetDumperWeapon.cpp | 47 +++++++++++++++++++ .../Game/T6/AssetDumpers/AssetDumperWeapon.h | 1 + 2 files changed, 48 insertions(+) diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeapon.cpp index d067b584..030cb80d 100644 --- a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeapon.cpp @@ -4,6 +4,7 @@ #include "Game/T6/InfoString/InfoStringFromStructConverter.h" #include "Game/T6/InfoString/WeaponFields.h" #include "Game/T6/ObjConstantsT6.h" +#include "Weapon/AccuracyGraphWriter.h" #include #include @@ -263,6 +264,23 @@ namespace T6 { } }; + + GenericAccuracyGraph ConvertAccuracyGraph(const char* graphName, const vec2_t* originalKnots, const unsigned originalKnotCount) + { + GenericAccuracyGraph 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; + } } // namespace T6 void AssetDumperWeapon::CopyToFullDef(const WeaponVariantDef* weapon, WeaponFullDef* fullDef) @@ -411,6 +429,33 @@ InfoString AssetDumperWeapon::CreateInfoString(XAssetInfo* ass return converter.Convert(); } +void AssetDumperWeapon::DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo* asset) +{ + auto* accuracyGraphWriter = context.GetZoneAssetDumperState(); + const auto weapon = asset->Asset(); + const auto* weapDef = weapon->weapDef; + + if (!weapDef) + return; + + if (weapDef->aiVsAiAccuracyGraphName && weapDef->originalAiVsAiAccuracyGraphKnots + && accuracyGraphWriter->ShouldDumpAiVsAiGraph(weapDef->aiVsAiAccuracyGraphName)) + { + AccuracyGraphWriter::DumpAiVsAiGraph( + context, + ConvertAccuracyGraph(weapDef->aiVsAiAccuracyGraphName, weapDef->originalAiVsAiAccuracyGraphKnots, weapDef->originalAiVsAiAccuracyGraphKnotCount)); + } + + if (weapDef->aiVsPlayerAccuracyGraphName && weapDef->originalAiVsPlayerAccuracyGraphKnots + && accuracyGraphWriter->ShouldDumpAiVsPlayerGraph(weapDef->aiVsPlayerAccuracyGraphName)) + { + AccuracyGraphWriter::DumpAiVsPlayerGraph(context, + ConvertAccuracyGraph(weapDef->aiVsPlayerAccuracyGraphName, + weapDef->originalAiVsPlayerAccuracyGraphKnots, + weapDef->originalAiVsPlayerAccuracyGraphKnotCount)); + } +} + bool AssetDumperWeapon::ShouldDump(XAssetInfo* asset) { return true; @@ -438,4 +483,6 @@ void AssetDumperWeapon::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset); + static void DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo* asset); protected: bool ShouldDump(XAssetInfo* asset) override; From fcb73347c202aff56fd61a8da20507164cdf506c Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 18 May 2024 23:43:34 +0200 Subject: [PATCH 5/7] feat: dump iw4 accuracy graphs --- .../IW4/AssetDumpers/AssetDumperWeapon.cpp | 47 +++++++++++++++++++ .../Game/IW4/AssetDumpers/AssetDumperWeapon.h | 1 + 2 files changed, 48 insertions(+) diff --git a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperWeapon.cpp index c3b1dcc5..41e55a2d 100644 --- a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperWeapon.cpp @@ -5,6 +5,7 @@ #include "Game/IW4/InfoString/InfoStringFromStructConverter.h" #include "Game/IW4/InfoString/WeaponFields.h" #include "Game/IW4/ObjConstantsIW4.h" +#include "Weapon/AccuracyGraphWriter.h" #include #include @@ -219,6 +220,23 @@ namespace IW4 { } }; + + GenericAccuracyGraph ConvertAccuracyGraph(const char* graphName, const vec2_t* originalKnots, const unsigned originalKnotCount) + { + GenericAccuracyGraph graph; + + graph.name = graphName; + graph.knots.resize(originalKnotCount); + + for (auto i = 0u; i < originalKnotCount; i++) + { + auto& knot = graph.knots[i]; + knot.x = originalKnots[i][0]; + knot.y = originalKnots[i][1]; + } + + return graph; + } } // namespace IW4 void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFullDef* fullDef) @@ -354,6 +372,33 @@ InfoString AssetDumperWeapon::CreateInfoString(XAssetInfo* as return converter.Convert(); } +void AssetDumperWeapon::DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo* asset) +{ + auto* accuracyGraphWriter = context.GetZoneAssetDumperState(); + const auto weapon = asset->Asset(); + const auto* weapDef = weapon->weapDef; + + if (!weapDef) + return; + + if (weapDef->aiVsAiAccuracyGraphName && weapDef->originalAiVsAiAccuracyGraphKnots + && accuracyGraphWriter->ShouldDumpAiVsAiGraph(weapDef->aiVsAiAccuracyGraphName)) + { + AccuracyGraphWriter::DumpAiVsAiGraph( + context, + ConvertAccuracyGraph(weapDef->aiVsAiAccuracyGraphName, weapDef->originalAiVsAiAccuracyGraphKnots, weapDef->originalAiVsAiAccuracyGraphKnotCount)); + } + + if (weapDef->aiVsPlayerAccuracyGraphName && weapDef->originalAiVsPlayerAccuracyGraphKnots + && accuracyGraphWriter->ShouldDumpAiVsPlayerGraph(weapDef->aiVsPlayerAccuracyGraphName)) + { + AccuracyGraphWriter::DumpAiVsPlayerGraph(context, + ConvertAccuracyGraph(weapDef->aiVsPlayerAccuracyGraphName, + weapDef->originalAiVsPlayerAccuracyGraphKnots, + weapDef->originalAiVsPlayerAccuracyGraphKnotCount)); + } +} + bool AssetDumperWeapon::ShouldDump(XAssetInfo* asset) { return true; @@ -381,4 +426,6 @@ void AssetDumperWeapon::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset); + static void DumpAccuracyGraphs(AssetDumpingContext& context, XAssetInfo* asset); protected: bool ShouldDump(XAssetInfo* asset) override; From 6f6a70c21291abf3e85206a1904559f3cffc9d64 Mon Sep 17 00:00:00 2001 From: Jan Date: Mon, 20 May 2024 13:21:58 +0200 Subject: [PATCH 6/7] chore: restructure sound curve loader to load generic 2D graphs instead --- src/ObjCommon/Parsing/GenericGraph2D.h | 25 ++ .../AssetLoading/SndCurve/SndCurveReader.cpp | 214 ---------------- .../AssetLoading/SndCurve/SndCurveReader.h | 32 --- .../IW4/AssetLoaders/AssetLoaderSndCurve.cpp | 30 +-- .../IW4/AssetLoaders/AssetLoaderSndCurve.h | 2 - .../Parsing/Graph2D/Graph2DReader.cpp | 229 ++++++++++++++++++ .../Parsing/Graph2D/Graph2DReader.h | 12 + src/ObjLoading/Sound/SoundCurveLoader.cpp | 23 ++ src/ObjLoading/Sound/SoundCurveLoader.h | 11 + 9 files changed, 307 insertions(+), 271 deletions(-) create mode 100644 src/ObjCommon/Parsing/GenericGraph2D.h delete mode 100644 src/ObjLoading/AssetLoading/SndCurve/SndCurveReader.cpp delete mode 100644 src/ObjLoading/AssetLoading/SndCurve/SndCurveReader.h create mode 100644 src/ObjLoading/Parsing/Graph2D/Graph2DReader.cpp create mode 100644 src/ObjLoading/Parsing/Graph2D/Graph2DReader.h create mode 100644 src/ObjLoading/Sound/SoundCurveLoader.cpp create mode 100644 src/ObjLoading/Sound/SoundCurveLoader.h diff --git a/src/ObjCommon/Parsing/GenericGraph2D.h b/src/ObjCommon/Parsing/GenericGraph2D.h new file mode 100644 index 00000000..854ee620 --- /dev/null +++ b/src/ObjCommon/Parsing/GenericGraph2D.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +class GenericGraph2DKnot +{ +public: + double x; + double y; + + GenericGraph2DKnot() = default; + + GenericGraph2DKnot(const double x, const double y) + : x(x), + y(y) + { + } +}; + +class GenericGraph2D +{ +public: + std::string name; + std::vector knots; +}; diff --git a/src/ObjLoading/AssetLoading/SndCurve/SndCurveReader.cpp b/src/ObjLoading/AssetLoading/SndCurve/SndCurveReader.cpp deleted file mode 100644 index 36d52b56..00000000 --- a/src/ObjLoading/AssetLoading/SndCurve/SndCurveReader.cpp +++ /dev/null @@ -1,214 +0,0 @@ -#include "SndCurveReader.h" - -#include "Parsing/Impl/AbstractParser.h" -#include "Parsing/Impl/ParserSingleInputStream.h" -#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" -#include "Parsing/Simple/SimpleLexer.h" -#include "Parsing/Simple/SimpleParserValue.h" - -enum class SndCurveParserStatus -{ - EXPECT_MAGIC, - EXPECT_KNOT_COUNT, - KNOTS -}; - -class SndCurveParserState -{ -public: - SndCurveParserStatus m_status; - size_t m_knot_count; - SndCurveReader::Result m_result; - - SndCurveParserState() - : m_status(SndCurveParserStatus::EXPECT_MAGIC), - m_knot_count(0u) - { - } -}; - -using snd_sequence_t = AbstractSequence; - -class SndCurveMagicSequence final : public snd_sequence_t -{ -public: - SndCurveMagicSequence() - { - const SimpleMatcherFactory create(this); - AddMatchers({ - create.Keyword("SNDCURVE"), - }); - } - -protected: - void ProcessMatch(SndCurveParserState* state, SequenceResult& result) const override - { - state->m_status = SndCurveParserStatus::EXPECT_KNOT_COUNT; - } -}; - -class SndCurveKnotCountSequence final : public snd_sequence_t -{ - static constexpr auto CAPTURE_KNOT_COUNT = 1; - -public: - SndCurveKnotCountSequence() - { - const SimpleMatcherFactory create(this); - AddMatchers({ - create.Integer().Capture(CAPTURE_KNOT_COUNT), - }); - } - -protected: - void ProcessMatch(SndCurveParserState* state, SequenceResult& result) const override - { - state->m_status = SndCurveParserStatus::KNOTS; - - const auto& knotCountToken = result.NextCapture(CAPTURE_KNOT_COUNT); - if (knotCountToken.IntegerValue() < 0) - throw ParsingException(knotCountToken.GetPos(), "Negative knot count is invalid"); - - state->m_knot_count = static_cast(knotCountToken.IntegerValue()); - state->m_result.m_knots.reserve(state->m_knot_count); - } -}; - -class SndCurveKnotSequence final : public snd_sequence_t -{ - static constexpr auto CAPTURE_X = 1; - static constexpr auto CAPTURE_Y = 2; - -public: - SndCurveKnotSequence() - { - const SimpleMatcherFactory create(this); - AddMatchers({ - create - .Or({ - create.FloatingPoint(), - create.Integer(), - }) - .Capture(CAPTURE_X), - - create - .Or({ - create.FloatingPoint(), - create.Integer(), - }) - .Capture(CAPTURE_Y), - }); - } - -private: - static double GetValue(const SimpleParserValue& token) - { - if (token.m_type == SimpleParserValueType::INTEGER) - return static_cast(token.IntegerValue()); - - return token.FloatingPointValue(); - } - -protected: - void ProcessMatch(SndCurveParserState* state, SequenceResult& result) const override - { - const auto& xToken = result.NextCapture(CAPTURE_X); - const auto& yToken = result.NextCapture(CAPTURE_Y); - - if (state->m_result.m_knots.size() >= state->m_knot_count) - throw ParsingException(xToken.GetPos(), "Too many knots"); - - const auto xValue = GetValue(xToken); - const auto yValue = GetValue(yToken); - - state->m_result.m_knots.push_back(SndCurveReader::Result::Knot{xValue, yValue}); - } -}; - -class SndCurveParser final : public AbstractParser -{ -public: - explicit SndCurveParser(ILexer* lexer) - : AbstractParser(lexer, std::make_unique()) - { - } - -protected: - const std::vector& GetTestsForState() override - { - switch (m_state->m_status) - { - case SndCurveParserStatus::EXPECT_MAGIC: - { - static std::vector expectMagicSequences{ - new SndCurveMagicSequence(), - }; - return expectMagicSequences; - } - - case SndCurveParserStatus::EXPECT_KNOT_COUNT: - { - static std::vector expectKnotCountSequences{ - new SndCurveKnotCountSequence(), - }; - return expectKnotCountSequences; - } - - case SndCurveParserStatus::KNOTS: - { - static std::vector knotsSequences{ - new SndCurveKnotSequence(), - }; - return knotsSequences; - } - } - - assert(false); - throw std::runtime_error("Invalid parsing status"); - } - -public: - _NODISCARD SndCurveReader::Result& GetResult() const - { - return m_state->m_result; - } - - _NODISCARD bool HasExpectedKnotCount() const - { - return m_state->m_knot_count == m_state->m_result.m_knots.size(); - } -}; - -SndCurveReader::SndCurveReader(std::istream& stream, const std::string& filename) - : m_stream(stream), - m_filename(filename) -{ -} - -std::unique_ptr SndCurveReader::Read() const -{ - ParserSingleInputStream parserStream(m_stream, m_filename); - - SimpleLexer::Config lexerConfig; - lexerConfig.m_emit_new_line_tokens = false; - lexerConfig.m_read_strings = false; - lexerConfig.m_read_integer_numbers = true; - lexerConfig.m_read_floating_point_numbers = true; - - SimpleLexer lexer(&parserStream, std::move(lexerConfig)); - SndCurveParser parser(&lexer); - - if (!parser.Parse()) - { - std::cerr << "Failed to parse SndCurve \"" << m_filename << "\"\n"; - return nullptr; - } - - if (!parser.HasExpectedKnotCount()) - { - std::cerr << "Failed to load SndCurve: Actual knot count differs from expected: \"" << m_filename << "\"\n"; - return nullptr; - } - - return std::make_unique(std::move(parser.GetResult())); -} diff --git a/src/ObjLoading/AssetLoading/SndCurve/SndCurveReader.h b/src/ObjLoading/AssetLoading/SndCurve/SndCurveReader.h deleted file mode 100644 index c8067927..00000000 --- a/src/ObjLoading/AssetLoading/SndCurve/SndCurveReader.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "Utils/ClassUtils.h" - -#include -#include -#include - -class SndCurveReader -{ -public: - class Result - { - public: - struct Knot - { - double m_x; - double m_y; - }; - - std::vector m_knots; - }; - -private: - std::istream& m_stream; - const std::string& m_filename; - -public: - SndCurveReader(std::istream& stream, const std::string& filename); - - _NODISCARD std::unique_ptr Read() const; -}; diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderSndCurve.cpp b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderSndCurve.cpp index 53822d4a..e21d5190 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderSndCurve.cpp +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderSndCurve.cpp @@ -1,9 +1,9 @@ #include "AssetLoaderSndCurve.h" -#include "AssetLoading/SndCurve/SndCurveReader.h" #include "Game/IW4/IW4.h" #include "ObjLoading.h" #include "Pool/GlobalAssetPool.h" +#include "Sound/SoundCurveLoader.h" #include #include @@ -11,15 +11,6 @@ using namespace IW4; -std::string AssetLoaderSndCurve::GetAssetFilename(const std::string& assetName) -{ - std::ostringstream ss; - - ss << "soundaliases/" << assetName << ".vfcurve"; - - return ss.str(); -} - void* AssetLoaderSndCurve::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) { auto* sndCurve = memory->Create(); @@ -36,33 +27,26 @@ bool AssetLoaderSndCurve::CanLoadFromRaw() const bool AssetLoaderSndCurve::LoadFromRaw( const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const { - const auto filename = GetAssetFilename(assetName); - const auto file = searchPath->Open(filename); - if (!file.IsOpen()) - return false; - - const SndCurveReader reader(*file.m_stream, filename); - - const auto sndCurveData = reader.Read(); + const auto sndCurveData = sound_curve::LoadSoundCurve(manager, assetName); if (!sndCurveData) return false; - if (sndCurveData->m_knots.size() > std::extent_v) + if (sndCurveData->knots.size() > std::extent_v) { - std::cerr << "Failed to load SndCurve \"" << assetName << "\": Too many knots (" << sndCurveData->m_knots.size() << ")\n"; + std::cerr << "Failed to load SndCurve \"" << assetName << "\": Too many knots (" << sndCurveData->knots.size() << ")\n"; return false; } auto* sndCurve = memory->Create(); sndCurve->filename = memory->Dup(assetName.c_str()); - sndCurve->knotCount = static_cast(sndCurveData->m_knots.size()); + sndCurve->knotCount = static_cast(sndCurveData->knots.size()); for (auto i = 0u; i < std::extent_v; i++) { - if (i < sndCurveData->m_knots.size()) + if (i < sndCurveData->knots.size()) { - const auto& [x, y] = sndCurveData->m_knots[i]; + const auto& [x, y] = sndCurveData->knots[i]; sndCurve->knots[i][0] = static_cast(x); sndCurve->knots[i][1] = static_cast(y); } diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderSndCurve.h b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderSndCurve.h index e261327c..5dea47ab 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderSndCurve.h +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderSndCurve.h @@ -8,8 +8,6 @@ namespace IW4 { class AssetLoaderSndCurve final : public BasicAssetLoader { - static std::string GetAssetFilename(const std::string& assetName); - public: _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; _NODISCARD bool CanLoadFromRaw() const override; diff --git a/src/ObjLoading/Parsing/Graph2D/Graph2DReader.cpp b/src/ObjLoading/Parsing/Graph2D/Graph2DReader.cpp new file mode 100644 index 00000000..f6803f80 --- /dev/null +++ b/src/ObjLoading/Parsing/Graph2D/Graph2DReader.cpp @@ -0,0 +1,229 @@ +#include "Graph2DReader.h" + +#include "Parsing/Impl/AbstractParser.h" +#include "Parsing/Impl/ParserSingleInputStream.h" +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" +#include "Parsing/Simple/SimpleLexer.h" +#include "Parsing/Simple/SimpleParserValue.h" + +#include + +namespace graph2d +{ + enum class SndCurveParserStatus + { + EXPECT_MAGIC, + EXPECT_KNOT_COUNT, + KNOTS + }; + + class SndCurveParserState + { + public: + SndCurveParserStatus m_status; + size_t m_expected_knot_count; + GenericGraph2D m_result; + + SndCurveParserState() + : m_status(SndCurveParserStatus::EXPECT_MAGIC), + m_expected_knot_count(0u) + { + } + }; + + using snd_sequence_t = AbstractSequence; + + class SndCurveMagicSequence final : public snd_sequence_t + { + public: + explicit SndCurveMagicSequence(std::string magicWord) + { + const SimpleMatcherFactory create(this); + AddMatchers({ + create.Keyword(std::move(magicWord)), + }); + } + + protected: + void ProcessMatch(SndCurveParserState* state, SequenceResult& result) const override + { + state->m_status = SndCurveParserStatus::EXPECT_KNOT_COUNT; + } + }; + + class SndCurveKnotCountSequence final : public snd_sequence_t + { + static constexpr auto CAPTURE_KNOT_COUNT = 1; + + public: + SndCurveKnotCountSequence() + { + const SimpleMatcherFactory create(this); + AddMatchers({ + create.Integer().Capture(CAPTURE_KNOT_COUNT), + }); + } + + protected: + void ProcessMatch(SndCurveParserState* state, SequenceResult& result) const override + { + state->m_status = SndCurveParserStatus::KNOTS; + + const auto& knotCountToken = result.NextCapture(CAPTURE_KNOT_COUNT); + if (knotCountToken.IntegerValue() < 0) + throw ParsingException(knotCountToken.GetPos(), "Negative knot count is invalid"); + + state->m_expected_knot_count = static_cast(knotCountToken.IntegerValue()); + state->m_result.knots.reserve(state->m_expected_knot_count); + } + }; + + class SndCurveKnotSequence final : public snd_sequence_t + { + static constexpr auto CAPTURE_X = 1; + static constexpr auto CAPTURE_Y = 2; + + public: + SndCurveKnotSequence() + { + const SimpleMatcherFactory create(this); + AddMatchers({ + create + .Or({ + create.FloatingPoint(), + create.Integer(), + }) + .Capture(CAPTURE_X), + + create + .Or({ + create.FloatingPoint(), + create.Integer(), + }) + .Capture(CAPTURE_Y), + }); + } + + private: + static double GetValue(const SimpleParserValue& token) + { + if (token.m_type == SimpleParserValueType::INTEGER) + return token.IntegerValue(); + + return token.FloatingPointValue(); + } + + protected: + void ProcessMatch(SndCurveParserState* state, SequenceResult& result) const override + { + const auto& xToken = result.NextCapture(CAPTURE_X); + const auto& yToken = result.NextCapture(CAPTURE_Y); + + if (state->m_result.knots.size() >= state->m_expected_knot_count) + throw ParsingException(xToken.GetPos(), std::format("More knots than expected ({})", state->m_expected_knot_count)); + + const auto xValue = GetValue(xToken); + const auto yValue = GetValue(yToken); + + state->m_result.knots.emplace_back(xValue, yValue); + } + }; + + class SndCurveParser final : public AbstractParser + { + public: + explicit SndCurveParser(ILexer* lexer, std::string magicWord) + : AbstractParser(lexer, std::make_unique()), + m_magic_sequence(std::move(magicWord)), + m_magic_sequences({&m_magic_sequence}) + { + } + + protected: + const std::vector& GetTestsForState() override + { + switch (m_state->m_status) + { + case SndCurveParserStatus::EXPECT_MAGIC: + return m_magic_sequences; + + case SndCurveParserStatus::EXPECT_KNOT_COUNT: + { + static std::vector expectKnotCountSequences{ + new SndCurveKnotCountSequence(), + }; + return expectKnotCountSequences; + } + + case SndCurveParserStatus::KNOTS: + { + static std::vector knotsSequences{ + new SndCurveKnotSequence(), + }; + return knotsSequences; + } + } + + assert(false); + throw std::runtime_error("Invalid parsing status"); + } + + public: + _NODISCARD GenericGraph2D& GetResult() const + { + return m_state->m_result; + } + + _NODISCARD bool HasExpectedKnotCount() const + { + return GetExpectedKnotCount() == GetActualKnotCount(); + } + + [[nodiscard]] size_t GetExpectedKnotCount() const + { + return m_state->m_expected_knot_count; + } + + [[nodiscard]] size_t GetActualKnotCount() const + { + return m_state->m_result.knots.size(); + } + + private: + SndCurveMagicSequence m_magic_sequence; + std::vector m_magic_sequences; + }; + + std::unique_ptr + Read(const std::string& graphTypeName, std::string graphMagicWord, std::istream& stream, const std::string& fileName, std::string graphName) + { + ParserSingleInputStream parserStream(stream, fileName); + + SimpleLexer::Config lexerConfig; + lexerConfig.m_emit_new_line_tokens = false; + lexerConfig.m_read_strings = false; + lexerConfig.m_read_integer_numbers = true; + lexerConfig.m_read_floating_point_numbers = true; + + SimpleLexer lexer(&parserStream, std::move(lexerConfig)); + SndCurveParser parser(&lexer, std::move(graphMagicWord)); + + if (!parser.Parse()) + { + std::cerr << std::format("Failed to parse {} \"{}\"\n", graphTypeName, graphName); + return nullptr; + } + + if (!parser.HasExpectedKnotCount()) + { + std::cerr << std::format("Failed to load {} \"{}\": Actual knot count ({}) differs from expected ({})\n", + graphTypeName, + graphName, + parser.GetActualKnotCount(), + parser.GetExpectedKnotCount()); + return nullptr; + } + + return std::make_unique(std::move(parser.GetResult())); + } +} // namespace graph2d diff --git a/src/ObjLoading/Parsing/Graph2D/Graph2DReader.h b/src/ObjLoading/Parsing/Graph2D/Graph2DReader.h new file mode 100644 index 00000000..43e80472 --- /dev/null +++ b/src/ObjLoading/Parsing/Graph2D/Graph2DReader.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Parsing/GenericGraph2D.h" + +#include +#include + +namespace graph2d +{ + [[nodiscard]] std::unique_ptr + Read(const std::string& graphTypeName, std::string graphMagicWord, std::istream& stream, const std::string& fileName, std::string graphName); +} diff --git a/src/ObjLoading/Sound/SoundCurveLoader.cpp b/src/ObjLoading/Sound/SoundCurveLoader.cpp new file mode 100644 index 00000000..17b2efdc --- /dev/null +++ b/src/ObjLoading/Sound/SoundCurveLoader.cpp @@ -0,0 +1,23 @@ +#include "SoundCurveLoader.h" + +#include "Parsing/Graph2D/Graph2DReader.h" + +#include +#include + +namespace sound_curve +{ + std::unique_ptr LoadSoundCurve(const IAssetLoadingManager* manager, const std::string& soundCurveName) + { + auto* searchPath = manager->GetAssetLoadingContext()->m_raw_search_path; + const auto fileName = std::format("soundaliases/{}.vfcurve", soundCurveName); + const auto file = searchPath->Open(fileName); + if (!file.IsOpen()) + { + std::cerr << std::format("Failed to open file for sound curve \"{}\"\n", soundCurveName); + return nullptr; + } + + return graph2d::Read("sound curve", "SNDCURVE", *file.m_stream, fileName, soundCurveName); + } +} // namespace sound_curve diff --git a/src/ObjLoading/Sound/SoundCurveLoader.h b/src/ObjLoading/Sound/SoundCurveLoader.h new file mode 100644 index 00000000..7982e780 --- /dev/null +++ b/src/ObjLoading/Sound/SoundCurveLoader.h @@ -0,0 +1,11 @@ +#pragma once + +#include "AssetLoading/IAssetLoadingManager.h" +#include "Parsing/GenericGraph2D.h" + +#include + +namespace sound_curve +{ + std::unique_ptr LoadSoundCurve(const IAssetLoadingManager* manager, const std::string& soundCurveName); +} From e68a7303b62cf1d4c42681bbcaba760e02bee618 Mon Sep 17 00:00:00 2001 From: Jan Date: Mon, 20 May 2024 13:27:34 +0200 Subject: [PATCH 7/7] feat: load accuracy graphs using generic 2d graph loader --- src/ObjCommon/Weapon/GenericAccuracyGraph.h | 17 ------ .../IW4/AssetLoaders/AssetLoaderWeapon.cpp | 59 +++++++++++++++++++ .../IW5/AssetLoaders/AssetLoaderWeapon.cpp | 59 +++++++++++++++++++ .../T6/AssetLoaders/AssetLoaderWeapon.cpp | 57 +++++++++++++++++- src/ObjLoading/Weapon/AccuracyGraphLoader.cpp | 55 +++++++++++++++++ src/ObjLoading/Weapon/AccuracyGraphLoader.h | 17 ++++++ .../IW4/AssetDumpers/AssetDumperWeapon.cpp | 4 +- .../IW5/AssetDumpers/AssetDumperWeapon.cpp | 4 +- .../T6/AssetDumpers/AssetDumperWeapon.cpp | 4 +- src/ObjWriting/Weapon/AccuracyGraphWriter.cpp | 6 +- src/ObjWriting/Weapon/AccuracyGraphWriter.h | 6 +- 11 files changed, 258 insertions(+), 30 deletions(-) delete mode 100644 src/ObjCommon/Weapon/GenericAccuracyGraph.h create mode 100644 src/ObjLoading/Weapon/AccuracyGraphLoader.cpp create mode 100644 src/ObjLoading/Weapon/AccuracyGraphLoader.h diff --git a/src/ObjCommon/Weapon/GenericAccuracyGraph.h b/src/ObjCommon/Weapon/GenericAccuracyGraph.h deleted file mode 100644 index 2f827204..00000000 --- a/src/ObjCommon/Weapon/GenericAccuracyGraph.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include -#include - -class GenericAccuracyGraphKnot -{ -public: - float x; - float y; -}; - -class GenericAccuracyGraph -{ -public: - std::string name; - std::vector knots; -}; diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderWeapon.cpp b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderWeapon.cpp index db91158a..b46bc66e 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderWeapon.cpp +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderWeapon.cpp @@ -9,6 +9,7 @@ #include "ObjLoading.h" #include "Pool/GlobalAssetPool.h" #include "Utils/StringUtils.h" +#include "Weapon/AccuracyGraphLoader.h" #include #include @@ -370,6 +371,62 @@ namespace } } + void ConvertAccuracyGraph(const GenericGraph2D& graph, + vec2_t*& originalGraphKnots, + uint16_t& originalGraphKnotCount, + vec2_t*& graphKnots, + uint16_t& graphKnotCount, + MemoryManager* memory) + { + originalGraphKnotCount = static_cast(graph.knots.size()); + originalGraphKnots = memory->Alloc(originalGraphKnotCount); + + for (auto i = 0u; i < originalGraphKnotCount; i++) + { + const auto& commonKnot = graph.knots[i]; + originalGraphKnots[i][0] = static_cast(commonKnot.x); + originalGraphKnots[i][1] = static_cast(commonKnot.y); + } + + graphKnots = originalGraphKnots; + graphKnotCount = originalGraphKnotCount; + } + + bool LoadAccuracyGraphs(WeaponFullDef* weaponFullDef, MemoryManager* memory, const IAssetLoadingManager* manager) + { + auto* accuracyGraphLoader = manager->GetAssetLoadingContext()->GetZoneAssetLoaderState(); + + if (weaponFullDef->weapDef.aiVsAiAccuracyGraphName && weaponFullDef->weapDef.aiVsAiAccuracyGraphName[0]) + { + const auto* graph = accuracyGraphLoader->LoadAiVsAiGraph(manager, weaponFullDef->weapDef.aiVsAiAccuracyGraphName); + if (!graph) + 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(manager, weaponFullDef->weapDef.aiVsPlayerAccuracyGraphName); + if (!graph) + return false; + + ConvertAccuracyGraph(*graph, + weaponFullDef->weapDef.originalAiVsPlayerAccuracyGraphKnots, + weaponFullDef->weapDef.originalAiVsPlayerAccuracyGraphKnotCount, + weaponFullDef->weapCompleteDef.aiVsPlayerAccuracyGraphKnots, + weaponFullDef->weapCompleteDef.aiVsPlayerAccuracyGraphKnotCount, + memory); + } + + return true; + } + bool LoadFromInfoString(const InfoString& infoString, const std::string& assetName, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) { auto* weaponFullDef = memory->Create(); @@ -387,6 +444,8 @@ namespace CalculateWeaponFields(weaponFullDef, memory); + LoadAccuracyGraphs(weaponFullDef, memory, manager); + manager->AddAsset( assetName, &weaponFullDef->weapCompleteDef, converter.GetDependencies(), converter.GetUsedScriptStrings(), converter.GetIndirectAssetReferences()); diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeapon.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeapon.cpp index 7343589f..18b3007a 100644 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeapon.cpp +++ b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderWeapon.cpp @@ -8,6 +8,7 @@ #include "ObjLoading.h" #include "Pool/GlobalAssetPool.h" #include "Utils/StringUtils.h" +#include "Weapon/AccuracyGraphLoader.h" #include #include @@ -800,6 +801,62 @@ namespace } } + void ConvertAccuracyGraph(const GenericGraph2D& graph, + vec2_t*& originalGraphKnots, + uint16_t& originalGraphKnotCount, + vec2_t*& graphKnots, + uint16_t& graphKnotCount, + MemoryManager* memory) + { + originalGraphKnotCount = static_cast(graph.knots.size()); + originalGraphKnots = memory->Alloc(originalGraphKnotCount); + + for (auto i = 0u; i < originalGraphKnotCount; i++) + { + const auto& commonKnot = graph.knots[i]; + originalGraphKnots[i][0] = static_cast(commonKnot.x); + originalGraphKnots[i][1] = static_cast(commonKnot.y); + } + + graphKnots = originalGraphKnots; + graphKnotCount = originalGraphKnotCount; + } + + bool LoadAccuracyGraphs(WeaponFullDef* weaponFullDef, MemoryManager* memory, const IAssetLoadingManager* manager) + { + auto* accuracyGraphLoader = manager->GetAssetLoadingContext()->GetZoneAssetLoaderState(); + + if (weaponFullDef->weapDef.aiVsAiAccuracyGraphName && weaponFullDef->weapDef.aiVsAiAccuracyGraphName[0]) + { + const auto* graph = accuracyGraphLoader->LoadAiVsAiGraph(manager, weaponFullDef->weapDef.aiVsAiAccuracyGraphName); + if (!graph) + 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(manager, weaponFullDef->weapDef.aiVsPlayerAccuracyGraphName); + if (!graph) + return false; + + ConvertAccuracyGraph(*graph, + weaponFullDef->weapDef.originalAiVsPlayerAccuracyGraphKnots, + weaponFullDef->weapDef.originalAiVsPlayerAccuracyGraphKnotCount, + weaponFullDef->weapCompleteDef.aiVsPlayerAccuracyGraphKnots, + weaponFullDef->weapCompleteDef.aiVsPlayerAccuracyGraphKnotCount, + memory); + } + + return true; + } + bool LoadFromInfoString(const InfoString& infoString, const std::string& assetName, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) { auto* weaponFullDef = memory->Create(); @@ -817,6 +874,8 @@ namespace CalculateWeaponFields(weaponFullDef, memory); + LoadAccuracyGraphs(weaponFullDef, memory, manager); + manager->AddAsset( assetName, &weaponFullDef->weapCompleteDef, converter.GetDependencies(), converter.GetUsedScriptStrings(), converter.GetIndirectAssetReferences()); diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderWeapon.cpp b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderWeapon.cpp index dc2ab93d..524042f8 100644 --- a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderWeapon.cpp +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderWeapon.cpp @@ -9,6 +9,7 @@ #include "InfoString/InfoString.h" #include "Utils/ClassUtils.h" #include "Utils/StringUtils.h" +#include "Weapon/AccuracyGraphLoader.h" #include #include @@ -385,6 +386,58 @@ namespace T6 { } }; + + void ConvertAccuracyGraph( + const GenericGraph2D& graph, vec2_t*& originalGraphKnots, int& originalGraphKnotCount, vec2_t*& graphKnots, int& graphKnotCount, MemoryManager* memory) + { + originalGraphKnotCount = static_cast(graph.knots.size()); + originalGraphKnots = memory->Alloc(originalGraphKnotCount); + + 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); + } + + graphKnots = originalGraphKnots; + graphKnotCount = originalGraphKnotCount; + } + + bool LoadAccuracyGraphs(WeaponFullDef* weaponFullDef, MemoryManager* memory, const IAssetLoadingManager* manager) + { + auto* accuracyGraphLoader = manager->GetAssetLoadingContext()->GetZoneAssetLoaderState(); + + if (weaponFullDef->weapDef.aiVsAiAccuracyGraphName && weaponFullDef->weapDef.aiVsAiAccuracyGraphName[0]) + { + const auto* graph = accuracyGraphLoader->LoadAiVsAiGraph(manager, weaponFullDef->weapDef.aiVsAiAccuracyGraphName); + if (!graph) + 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(manager, weaponFullDef->weapDef.aiVsPlayerAccuracyGraphName); + if (!graph) + return false; + + ConvertAccuracyGraph(*graph, + weaponFullDef->weapDef.originalAiVsPlayerAccuracyGraphKnots, + weaponFullDef->weapDef.originalAiVsPlayerAccuracyGraphKnotCount, + weaponFullDef->weapDef.aiVsPlayerAccuracyGraphKnots, + weaponFullDef->weapDef.aiVsPlayerAccuracyGraphKnotCount, + memory); + } + + return true; + } } // namespace T6 void AssetLoaderWeapon::LinkWeaponFullDefSubStructs(WeaponFullDef* weapon) @@ -563,10 +616,12 @@ bool AssetLoaderWeapon::LoadFromInfoString( weaponFullDef->weapVariantDef.szInternalName = memory->Dup(assetName.c_str()); - // TODO: Load accuracy graph and flametable + // TODO: Load flametable CalculateWeaponFields(weaponFullDef); CalculateAttachmentFields(weaponFullDef); + LoadAccuracyGraphs(weaponFullDef, memory, manager); + manager->AddAsset( assetName, &weaponFullDef->weapVariantDef, converter.GetDependencies(), converter.GetUsedScriptStrings(), converter.GetIndirectAssetReferences()); diff --git a/src/ObjLoading/Weapon/AccuracyGraphLoader.cpp b/src/ObjLoading/Weapon/AccuracyGraphLoader.cpp new file mode 100644 index 00000000..4ffae119 --- /dev/null +++ b/src/ObjLoading/Weapon/AccuracyGraphLoader.cpp @@ -0,0 +1,55 @@ +#include "AccuracyGraphLoader.h" + +#include "Parsing/Graph2D/Graph2DReader.h" + +#include +#include + +namespace +{ + std::unique_ptr LoadAccuracyGraph(const IAssetLoadingManager* manager, const std::string& graphName, const std::string& subFolder) + { + auto* searchPath = manager->GetAssetLoadingContext()->m_raw_search_path; + const auto fileName = std::format("accuracy/{}/{}", subFolder, graphName); + const auto file = searchPath->Open(fileName); + if (!file.IsOpen()) + { + std::cerr << std::format("Failed to open file for accuracy graph: {}/{}\n", subFolder, graphName); + return nullptr; + } + + return graph2d::Read("accuracy graph", "WEAPONACCUFILE", *file.m_stream, fileName, graphName); + } +} // namespace + +const GenericGraph2D* AccuracyGraphLoader::LoadAiVsAiGraph(const IAssetLoadingManager* manager, 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(manager, 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(const IAssetLoadingManager* manager, 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(manager, 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.h b/src/ObjLoading/Weapon/AccuracyGraphLoader.h new file mode 100644 index 00000000..216e6618 --- /dev/null +++ b/src/ObjLoading/Weapon/AccuracyGraphLoader.h @@ -0,0 +1,17 @@ +#pragma once +#include "AssetLoading/IAssetLoadingManager.h" +#include "AssetLoading/IZoneAssetLoaderState.h" +#include "Parsing/GenericGraph2D.h" + +#include + +class AccuracyGraphLoader final : public IZoneAssetLoaderState +{ +public: + const GenericGraph2D* LoadAiVsAiGraph(const IAssetLoadingManager* manager, const std::string& graphName); + const GenericGraph2D* LoadAiVsPlayerGraph(const IAssetLoadingManager* manager, 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/ObjWriting/Game/IW4/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperWeapon.cpp index 41e55a2d..b61f03a3 100644 --- a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperWeapon.cpp @@ -221,9 +221,9 @@ namespace IW4 } }; - GenericAccuracyGraph ConvertAccuracyGraph(const char* graphName, const vec2_t* originalKnots, const unsigned originalKnotCount) + GenericGraph2D ConvertAccuracyGraph(const char* graphName, const vec2_t* originalKnots, const unsigned originalKnotCount) { - GenericAccuracyGraph graph; + GenericGraph2D graph; graph.name = graphName; graph.knots.resize(originalKnotCount); diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp index eb66f1e4..4749d79d 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp @@ -535,9 +535,9 @@ namespace IW5 const WeaponFullDef* m_weapon; }; - GenericAccuracyGraph ConvertAccuracyGraph(const char* graphName, const vec2_t* originalKnots, const unsigned originalKnotCount) + GenericGraph2D ConvertAccuracyGraph(const char* graphName, const vec2_t* originalKnots, const unsigned originalKnotCount) { - GenericAccuracyGraph graph; + GenericGraph2D graph; graph.name = graphName; graph.knots.resize(originalKnotCount); diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeapon.cpp index 030cb80d..eb458716 100644 --- a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeapon.cpp @@ -265,9 +265,9 @@ namespace T6 } }; - GenericAccuracyGraph ConvertAccuracyGraph(const char* graphName, const vec2_t* originalKnots, const unsigned originalKnotCount) + GenericGraph2D ConvertAccuracyGraph(const char* graphName, const vec2_t* originalKnots, const unsigned originalKnotCount) { - GenericAccuracyGraph graph; + GenericGraph2D graph; graph.name = graphName; graph.knots.resize(originalKnotCount); diff --git a/src/ObjWriting/Weapon/AccuracyGraphWriter.cpp b/src/ObjWriting/Weapon/AccuracyGraphWriter.cpp index b6f0583f..4da6e353 100644 --- a/src/ObjWriting/Weapon/AccuracyGraphWriter.cpp +++ b/src/ObjWriting/Weapon/AccuracyGraphWriter.cpp @@ -19,7 +19,7 @@ namespace return false; } - void DumpAccuracyGraph(const AssetDumpingContext& context, const GenericAccuracyGraph& graph, const std::string& subFolder) + void DumpAccuracyGraph(const AssetDumpingContext& context, const GenericGraph2D& graph, const std::string& subFolder) { const auto file = context.OpenAssetFile(std::format("accuracy/{}/{}", subFolder, graph.name)); if (!file) @@ -46,12 +46,12 @@ bool AccuracyGraphWriter::ShouldDumpAiVsPlayerGraph(const std::string& graphName return ShouldDumpAccuracyGraph(m_dumped_ai_vs_player_graphs, graphName); } -void AccuracyGraphWriter::DumpAiVsAiGraph(const AssetDumpingContext& context, const GenericAccuracyGraph& aiVsAiGraph) +void AccuracyGraphWriter::DumpAiVsAiGraph(const AssetDumpingContext& context, const GenericGraph2D& aiVsAiGraph) { DumpAccuracyGraph(context, aiVsAiGraph, "aivsai"); } -void AccuracyGraphWriter::DumpAiVsPlayerGraph(const AssetDumpingContext& context, const GenericAccuracyGraph& aiVsPlayerGraph) +void AccuracyGraphWriter::DumpAiVsPlayerGraph(const AssetDumpingContext& context, const GenericGraph2D& aiVsPlayerGraph) { DumpAccuracyGraph(context, aiVsPlayerGraph, "aivsplayer"); } diff --git a/src/ObjWriting/Weapon/AccuracyGraphWriter.h b/src/ObjWriting/Weapon/AccuracyGraphWriter.h index a5e2edc3..054d5dea 100644 --- a/src/ObjWriting/Weapon/AccuracyGraphWriter.h +++ b/src/ObjWriting/Weapon/AccuracyGraphWriter.h @@ -1,7 +1,7 @@ #pragma once #include "Dumping/AssetDumpingContext.h" #include "Dumping/IZoneAssetDumperState.h" -#include "Weapon/GenericAccuracyGraph.h" +#include "Parsing/GenericGraph2D.h" #include #include @@ -12,8 +12,8 @@ public: bool ShouldDumpAiVsAiGraph(const std::string& graphName); bool ShouldDumpAiVsPlayerGraph(const std::string& graphName); - static void DumpAiVsAiGraph(const AssetDumpingContext& context, const GenericAccuracyGraph& aiVsAiGraph); - static void DumpAiVsPlayerGraph(const AssetDumpingContext& context, const GenericAccuracyGraph& aiVsPlayerGraph); + static void DumpAiVsAiGraph(const AssetDumpingContext& context, const GenericGraph2D& aiVsAiGraph); + static void DumpAiVsPlayerGraph(const AssetDumpingContext& context, const GenericGraph2D& aiVsPlayerGraph); private: std::unordered_set m_dumped_ai_vs_ai_graphs;