chore: dump iw5 weapon anim overrides

This commit is contained in:
Jan 2024-04-07 14:07:53 +02:00
parent a27241701b
commit 8554939c91
No known key found for this signature in database
GPG Key ID: 44B581F78FF5C57C
5 changed files with 130 additions and 15 deletions

View File

@ -116,6 +116,7 @@ namespace IW5
// Custom // Custom
WFT_ANIM_NAME, WFT_ANIM_NAME,
WFT_ATTACHMENT, WFT_ATTACHMENT,
WFT_ANIM_OVERRIDES,
WFT_NUM_FIELD_TYPES, WFT_NUM_FIELD_TYPES,
}; };

View File

@ -3383,7 +3383,7 @@ namespace IW5
MISSILE_GUIDANCE_COUNT MISSILE_GUIDANCE_COUNT
}; };
enum weapAnimFiles_t enum weapAnimFiles_t : unsigned int
{ {
WEAP_ANIM_ROOT = 0x0, WEAP_ANIM_ROOT = 0x0,
WEAP_ANIM_IDLE = 0x1, WEAP_ANIM_IDLE = 0x1,
@ -3428,7 +3428,7 @@ namespace IW5
WEAP_ANIM_ADS_DOWN = 0x28, WEAP_ANIM_ADS_DOWN = 0x28,
WEAP_ALT_ANIM_ADJUST = 0x29, WEAP_ALT_ANIM_ADJUST = 0x29,
NUM_WEAP_ANIMS WEAP_ANIM_COUNT
}; };
enum hitLocation_t enum hitLocation_t
@ -3895,13 +3895,30 @@ namespace IW5
XModel* stowOffsetModel; XModel* stowOffsetModel;
}; };
union WeaponAttachmentCombination
{
struct
{
// Specifies the index as a number
// since there can only be one scope
unsigned short scope : 3;
// Specifies the index as a number
// since there can only be one under barrel
unsigned short underBarrel : 2;
// Specifies all other attachments as a bit array
unsigned short other : 4;
};
unsigned short fields;
};
struct AnimOverrideEntry struct AnimOverrideEntry
{ {
unsigned short attachment1; WeaponAttachmentCombination attachment1;
unsigned short attachment2; WeaponAttachmentCombination attachment2;
const char* overrideAnim; const char* overrideAnim;
const char* altmodeAnim; const char* altmodeAnim;
unsigned int animTreeType; weapAnimFiles_t animTreeType;
int animTime; int animTime;
int altTime; int altTime;
}; };

View File

@ -4,7 +4,6 @@
namespace IW5 namespace IW5
{ {
// WeaponCompleteDef: // WeaponCompleteDef:
// TODO: animOverrides
// TODO: soundOverrides // TODO: soundOverrides
// TODO: fxOverrides // TODO: fxOverrides
// TODO: reloadOverrides // TODO: reloadOverrides
@ -734,6 +733,7 @@ namespace IW5
{"missileConeSoundCrossfadeTopSize", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeTopSize), CSPFT_FLOAT }, {"missileConeSoundCrossfadeTopSize", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeTopSize), CSPFT_FLOAT },
{"missileConeSoundCrossfadeBottomSize", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeBottomSize), CSPFT_FLOAT }, {"missileConeSoundCrossfadeBottomSize", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeBottomSize), CSPFT_FLOAT },
{"attachments", offsetof(WeaponFullDef, scopes), WFT_ATTACHMENT }, {"attachments", offsetof(WeaponFullDef, scopes), WFT_ATTACHMENT },
{"animOverrides", offsetof(WeaponFullDef, weapCompleteDef.animOverrides), WFT_ANIM_OVERRIDES },
}; };
inline const char* szWeapTypeNames[]{ inline const char* szWeapTypeNames[]{
@ -914,4 +914,15 @@ namespace IW5
"_gravel", "_ice", "_metal", "_mud", "_paper", "_plaster", "_rock", "_sand", "_snow", "_water", "_wood", "_gravel", "_ice", "_metal", "_mud", "_paper", "_plaster", "_rock", "_sand", "_snow", "_water", "_wood",
"_asphalt", "_ceramic", "_plastic", "_rubber", "_cushion", "_fruit", "_painted_metal", "_riot_shield", "_slush", "_asphalt", "_ceramic", "_plastic", "_rubber", "_cushion", "_fruit", "_painted_metal", "_riot_shield", "_slush",
}; };
static_assert(std::extent_v<decltype(bounceSoundSuffixes)> == SURF_TYPE_COUNT);
inline const char* weapAnimFilesNames[]{
"root", "idle", "empty_idle", "fire", "hold_fire", "lastshot", "rechamber", "melee",
"melee_charge", "reload", "reload_empty", "reload_start", "reload_end", "raise", "first_raise", "breach_raise",
"drop", "alt_raise", "alt_drop", "quick_raise", "quick_drop", "empty_raise", "empty_drop", "sprint_in",
"sprint_loop", "sprint_out", "stunned_start", "stunned_loop", "stunned_end", "detonate", "nightvision_wear", "nightvision_remove",
"ads_fire", "ads_lastshot", "ads_rechamber", "blast_front", "blast_right", "blast_back", "blast_left", "ads_up",
"ads_down", "alt_adjust",
};
static_assert(std::extent_v<decltype(weapAnimFilesNames)> == WEAP_ANIM_COUNT);
} // namespace IW5 } // namespace IW5

View File

@ -5,6 +5,7 @@
#include "Game/IW5/InfoString/WeaponFields.h" #include "Game/IW5/InfoString/WeaponFields.h"
#include "Game/IW5/ObjConstantsIW5.h" #include "Game/IW5/ObjConstantsIW5.h"
#include <bit>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <sstream> #include <sstream>
@ -216,6 +217,10 @@ namespace IW5
FillFromAttachments(std::string(field.szName)); FillFromAttachments(std::string(field.szName));
break; break;
case WFT_ANIM_OVERRIDES:
FillFromAnimOverrides(std::string(field.szName));
break;
case WFT_NUM_FIELD_TYPES: case WFT_NUM_FIELD_TYPES:
default: default:
assert(false); assert(false);
@ -271,6 +276,87 @@ namespace IW5
m_info_string.SetValueForKey(key, ss.str()); m_info_string.SetValueForKey(key, ss.str());
} }
[[nodiscard]] std::string GetNameForSingleWeaponAttachment(const WeaponAttachmentCombination& combination) const
{
// Only one attachment type can be set
assert(combination.scope == 0 || (combination.underBarrel == 0 && combination.other == 0));
assert(combination.underBarrel == 0 || (combination.scope == 0 && combination.other == 0));
assert(combination.other == 0 || (combination.scope == 0 && std::popcount(combination.other) == 1));
if (combination.scope > 0 && m_weapon->weapCompleteDef.scopes)
{
const auto attachment = m_weapon->weapCompleteDef.scopes[combination.scope - 1];
if (attachment && attachment->szInternalName)
return attachment->szInternalName;
}
else if (combination.underBarrel > 0 && m_weapon->weapCompleteDef.underBarrels)
{
const auto attachment = m_weapon->weapCompleteDef.underBarrels[combination.underBarrel - 1];
if (attachment && attachment->szInternalName)
return attachment->szInternalName;
}
else if (combination.other > 0 && m_weapon->weapCompleteDef.others)
{
const auto attachment = m_weapon->weapCompleteDef.others[std::countr_zero(combination.other)];
if (attachment && attachment->szInternalName)
return attachment->szInternalName;
}
return {};
}
void FillFromAnimOverrides(const std::string& key)
{
std::stringstream ss;
bool first = true;
for (auto i = 0u; i < m_weapon->weapCompleteDef.numAnimOverrides; i++)
{
const auto& animOverride = m_weapon->weapCompleteDef.animOverrides[i];
if (!first)
ss << "\n";
else
first = false;
assert(animOverride.attachment1.fields);
assert(animOverride.animTreeType < WEAP_ANIM_COUNT);
if (animOverride.attachment1.fields)
ss << GetNameForSingleWeaponAttachment(animOverride.attachment1);
else
ss << "none";
ss << ' ';
if (animOverride.attachment2.fields)
ss << GetNameForSingleWeaponAttachment(animOverride.attachment2);
else
ss << "none";
ss << ' ';
if (animOverride.animTreeType < WEAP_ANIM_COUNT)
ss << weapAnimFilesNames[animOverride.animTreeType] << ' ';
if (animOverride.overrideAnim && animOverride.overrideAnim[0])
ss << animOverride.overrideAnim;
else
ss << "none";
ss << ' ';
if (animOverride.altmodeAnim && animOverride.altmodeAnim[0])
ss << animOverride.altmodeAnim;
else
ss << "none";
ss << ' ' << animOverride.animTime << ' ' << animOverride.altTime;
}
m_info_string.SetValueForKey(key, ss.str());
}
const WeaponFullDef* m_weapon; const WeaponFullDef* m_weapon;
}; };
} // namespace IW5 } // namespace IW5
@ -293,8 +379,8 @@ void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFul
if (weapon->szXAnims) if (weapon->szXAnims)
{ {
static_assert(std::extent_v<decltype(WeaponFullDef::szXAnims)> == NUM_WEAP_ANIMS); static_assert(std::extent_v<decltype(WeaponFullDef::szXAnims)> == WEAP_ANIM_COUNT);
memcpy(fullDef->szXAnims, weapon->szXAnims, sizeof(void*) * NUM_WEAP_ANIMS); memcpy(fullDef->szXAnims, weapon->szXAnims, sizeof(void*) * WEAP_ANIM_COUNT);
fullDef->weapCompleteDef.szXAnims = fullDef->szXAnims; fullDef->weapCompleteDef.szXAnims = fullDef->szXAnims;
} }
@ -306,15 +392,15 @@ void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFul
if (fullDef->weapDef.szXAnimsRightHanded) if (fullDef->weapDef.szXAnimsRightHanded)
{ {
static_assert(std::extent_v<decltype(WeaponFullDef::szXAnimsRightHanded)> == NUM_WEAP_ANIMS); static_assert(std::extent_v<decltype(WeaponFullDef::szXAnimsRightHanded)> == WEAP_ANIM_COUNT);
memcpy(fullDef->szXAnimsRightHanded, fullDef->weapDef.szXAnimsRightHanded, sizeof(void*) * NUM_WEAP_ANIMS); memcpy(fullDef->szXAnimsRightHanded, fullDef->weapDef.szXAnimsRightHanded, sizeof(void*) * WEAP_ANIM_COUNT);
fullDef->weapDef.szXAnimsRightHanded = fullDef->szXAnimsRightHanded; fullDef->weapDef.szXAnimsRightHanded = fullDef->szXAnimsRightHanded;
} }
if (fullDef->weapDef.szXAnimsLeftHanded) if (fullDef->weapDef.szXAnimsLeftHanded)
{ {
static_assert(std::extent_v<decltype(WeaponFullDef::szXAnimsLeftHanded)> == NUM_WEAP_ANIMS); static_assert(std::extent_v<decltype(WeaponFullDef::szXAnimsLeftHanded)> == WEAP_ANIM_COUNT);
memcpy(fullDef->szXAnimsLeftHanded, fullDef->weapDef.szXAnimsLeftHanded, sizeof(void*) * NUM_WEAP_ANIMS); memcpy(fullDef->szXAnimsLeftHanded, fullDef->weapDef.szXAnimsLeftHanded, sizeof(void*) * WEAP_ANIM_COUNT);
fullDef->weapDef.szXAnimsLeftHanded = fullDef->szXAnimsLeftHanded; fullDef->weapDef.szXAnimsLeftHanded = fullDef->szXAnimsLeftHanded;
} }

View File

@ -19,7 +19,7 @@ set count others 4;
set string szXAnims; set string szXAnims;
set assetref szXAnims ASSET_TYPE_XANIMPARTS; set assetref szXAnims ASSET_TYPE_XANIMPARTS;
set reusable szXAnims; set reusable szXAnims;
set count szXAnims NUM_WEAP_ANIMS; set count szXAnims WEAP_ANIM_COUNT;
set reusable animOverrides; set reusable animOverrides;
set count animOverrides numAnimOverrides; set count animOverrides numAnimOverrides;
set reusable soundOverrides; set reusable soundOverrides;
@ -59,11 +59,11 @@ set count gunXModel 16;
set reusable szXAnimsRightHanded; set reusable szXAnimsRightHanded;
set string szXAnimsRightHanded; set string szXAnimsRightHanded;
set assetref szXAnimsRightHanded ASSET_TYPE_XANIMPARTS; set assetref szXAnimsRightHanded ASSET_TYPE_XANIMPARTS;
set count szXAnimsRightHanded NUM_WEAP_ANIMS; set count szXAnimsRightHanded WEAP_ANIM_COUNT;
set reusable szXAnimsLeftHanded; set reusable szXAnimsLeftHanded;
set string szXAnimsLeftHanded; set string szXAnimsLeftHanded;
set assetref szXAnimsLeftHanded ASSET_TYPE_XANIMPARTS; set assetref szXAnimsLeftHanded ASSET_TYPE_XANIMPARTS;
set count szXAnimsLeftHanded NUM_WEAP_ANIMS; set count szXAnimsLeftHanded WEAP_ANIM_COUNT;
set string szModeName; set string szModeName;
set reusable notetrackSoundMapKeys; set reusable notetrackSoundMapKeys;
set scriptstring notetrackSoundMapKeys; set scriptstring notetrackSoundMapKeys;