mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 00:02:55 +00:00
chore: dump iw5 weapon anim overrides
This commit is contained in:
parent
a27241701b
commit
8554939c91
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user