From 7be21ebb20c6171963d6335887a8286ede56cbef Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 6 Apr 2024 11:46:39 +0200 Subject: [PATCH 01/17] feat: dump iw5 weapons on iw4 level --- src/Common/Game/IW5/IW5.h | 35 + src/Common/Game/IW5/IW5_Assets.h | 56 ++ .../Game/IW5/InfoString/WeaponFields.h | 874 ++++++++++++++++++ .../IW5/AssetDumpers/AssetDumperWeapon.cpp | 383 ++++++++ .../Game/IW5/AssetDumpers/AssetDumperWeapon.h | 18 + .../InfoStringFromStructConverter.cpp | 11 + src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp | 3 +- 7 files changed, 1379 insertions(+), 1 deletion(-) create mode 100644 src/ObjCommon/Game/IW5/InfoString/WeaponFields.h create mode 100644 src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp create mode 100644 src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.h diff --git a/src/Common/Game/IW5/IW5.h b/src/Common/Game/IW5/IW5.h index c6ef6e71..6b850094 100644 --- a/src/Common/Game/IW5/IW5.h +++ b/src/Common/Game/IW5/IW5.h @@ -78,9 +78,44 @@ namespace IW5 CSPFT_FX, CSPFT_XMODEL, CSPFT_MATERIAL, + CSPFT_PHYS_COLLMAP, CSPFT_SOUND, CSPFT_TRACER, CSPFT_NUM_BASE_FIELD_TYPES, }; + + enum weapFieldType_t + { + WFT_WEAPONTYPE = CSPFT_NUM_BASE_FIELD_TYPES, + WFT_WEAPONCLASS, + WFT_OVERLAYRETICLE, + WFT_PENETRATE_TYPE, + WFT_IMPACT_TYPE, + WFT_STANCE, + WFT_PROJ_EXPLOSION, + WFT_OFFHAND_CLASS, + WFT_ANIMTYPE, + WFT_ACTIVE_RETICLE_TYPE, + WFT_GUIDED_MISSILE_TYPE, + WFT_BOUNCE_SOUND, + WFT_STICKINESS, + WFT_OVERLAYINTERFACE, + WFT_INVENTORYTYPE, + WFT_FIRETYPE, + WFT_AMMOCOUNTER_CLIPTYPE, + WFT_ICONRATIO_HUD, + WFT_ICONRATIO_PICKUP, + WFT_ICONRATIO_AMMOCOUNTER, + WFT_ICONRATIO_KILL, + WFT_ICONRATIO_DPAD, + WFT_HIDETAGS, + WFT_NOTETRACKSOUNDMAP, + WFT_NOTETRACKRUMBLEMAP, + + // Custom + WFT_ANIM_NAME, + + WFT_NUM_FIELD_TYPES, + }; } // namespace IW5 diff --git a/src/Common/Game/IW5/IW5_Assets.h b/src/Common/Game/IW5/IW5_Assets.h index 6c5bbdec..de213a72 100644 --- a/src/Common/Game/IW5/IW5_Assets.h +++ b/src/Common/Game/IW5/IW5_Assets.h @@ -3457,6 +3457,43 @@ namespace IW5 HITLOC_NUM }; + enum materialSurfType_t + { + SURF_TYPE_DEFAULT, + SURF_TYPE_BARK, + SURF_TYPE_BRICK, + SURF_TYPE_CARPET, + SURF_TYPE_CLOTH, + SURF_TYPE_CONCRETE, + SURF_TYPE_DIRT, + SURF_TYPE_FLESH, + SURF_TYPE_FOLIAGE, + SURF_TYPE_GLASS, + SURF_TYPE_GRASS, + SURF_TYPE_GRAVEL, + SURF_TYPE_ICE, + SURF_TYPE_METAL, + SURF_TYPE_MUD, + SURF_TYPE_PAPER, + SURF_TYPE_PLASTER, + SURF_TYPE_ROCK, + SURF_TYPE_SAND, + SURF_TYPE_SNOW, + SURF_TYPE_WATER, + SURF_TYPE_WOOD, + SURF_TYPE_ASPHALT, + SURF_TYPE_CERAMIC, + SURF_TYPE_PLASTIC, + SURF_TYPE_RUBBER, + SURF_TYPE_CUSHION, + SURF_TYPE_FRUIT, + SURF_TYPE_PAINTED_METAL, + SURF_TYPE_RIOT_SHIELD, + SURF_TYPE_SLUSH, + + SURF_TYPE_NUM + }; + struct WeaponDef { const char* szOverlayName; @@ -3952,6 +3989,25 @@ namespace IW5 bool dpadIconShowsAmmo; }; + struct WeaponFullDef + { + WeaponCompleteDef weapCompleteDef; + WeaponDef weapDef; + uint16_t hideTags[32]; + const char* szXAnims[42]; + XModel* gunXModel[16]; + const char* szXAnimsRightHanded[42]; + const char* szXAnimsLeftHanded[42]; + uint16_t notetrackSoundMapKeys[16]; + uint16_t notetrackSoundMapValues[16]; + uint16_t notetrackRumbleMapKeys[16]; + uint16_t notetrackRumbleMapValues[16]; + XModel* worldModel[16]; + float parallelBounce[31]; + float perpendicularBounce[31]; + float locationDamageMultipliers[20]; + }; + struct FxFloatRange { float base; diff --git a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h new file mode 100644 index 00000000..48eae411 --- /dev/null +++ b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h @@ -0,0 +1,874 @@ +#pragma once +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + inline cspField_t weapon_fields[]{ + {"displayName", offsetof(WeaponFullDef, weapCompleteDef.szDisplayName), CSPFT_STRING }, + {"AIOverlayDescription", offsetof(WeaponFullDef, weapDef.szOverlayName), CSPFT_STRING }, + {"modeName", offsetof(WeaponFullDef, weapDef.szModeName), CSPFT_STRING }, + {"playerAnimType", offsetof(WeaponFullDef, weapDef.playerAnimType), WFT_ANIMTYPE }, + {"gunModel", offsetof(WeaponFullDef, gunXModel[0]), CSPFT_XMODEL }, + {"gunModel2", offsetof(WeaponFullDef, gunXModel[1]), CSPFT_XMODEL }, + {"gunModel3", offsetof(WeaponFullDef, gunXModel[2]), CSPFT_XMODEL }, + {"gunModel4", offsetof(WeaponFullDef, gunXModel[3]), CSPFT_XMODEL }, + {"gunModel5", offsetof(WeaponFullDef, gunXModel[4]), CSPFT_XMODEL }, + {"gunModel6", offsetof(WeaponFullDef, gunXModel[5]), CSPFT_XMODEL }, + {"gunModel7", offsetof(WeaponFullDef, gunXModel[6]), CSPFT_XMODEL }, + {"gunModel8", offsetof(WeaponFullDef, gunXModel[7]), CSPFT_XMODEL }, + {"gunModel9", offsetof(WeaponFullDef, gunXModel[8]), CSPFT_XMODEL }, + {"gunModel10", offsetof(WeaponFullDef, gunXModel[9]), CSPFT_XMODEL }, + {"gunModel11", offsetof(WeaponFullDef, gunXModel[10]), CSPFT_XMODEL }, + {"gunModel12", offsetof(WeaponFullDef, gunXModel[11]), CSPFT_XMODEL }, + {"gunModel13", offsetof(WeaponFullDef, gunXModel[12]), CSPFT_XMODEL }, + {"gunModel14", offsetof(WeaponFullDef, gunXModel[13]), CSPFT_XMODEL }, + {"gunModel15", offsetof(WeaponFullDef, gunXModel[14]), CSPFT_XMODEL }, + {"gunModel16", offsetof(WeaponFullDef, gunXModel[15]), CSPFT_XMODEL }, + {"handModel", offsetof(WeaponFullDef, weapDef.handXModel), CSPFT_XMODEL }, + {"hideTags", offsetof(WeaponFullDef, hideTags), WFT_HIDETAGS }, + {"notetrackSoundMap", offsetof(WeaponFullDef, notetrackSoundMapKeys), WFT_NOTETRACKSOUNDMAP }, + {"notetrackRumbleMap", offsetof(WeaponFullDef, notetrackRumbleMapKeys), WFT_NOTETRACKRUMBLEMAP }, + {"idleAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_IDLE]), WFT_ANIM_NAME }, + {"emptyIdleAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_EMPTY_IDLE]), WFT_ANIM_NAME }, + {"fireAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_FIRE]), WFT_ANIM_NAME }, + {"holdFireAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_HOLD_FIRE]), WFT_ANIM_NAME }, + {"lastShotAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_LASTSHOT]), WFT_ANIM_NAME }, + {"detonateAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_DETONATE]), WFT_ANIM_NAME }, + {"rechamberAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RECHAMBER]), WFT_ANIM_NAME }, + {"meleeAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_MELEE]), WFT_ANIM_NAME }, + {"meleeChargeAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_MELEE_CHARGE]), WFT_ANIM_NAME }, + {"reloadAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RELOAD]), WFT_ANIM_NAME }, + {"reloadEmptyAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RELOAD_EMPTY]), WFT_ANIM_NAME }, + {"reloadStartAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RELOAD_START]), WFT_ANIM_NAME }, + {"reloadEndAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RELOAD_END]), WFT_ANIM_NAME }, + {"raiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RAISE]), WFT_ANIM_NAME }, + {"dropAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_DROP]), WFT_ANIM_NAME }, + {"firstRaiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_FIRST_RAISE]), WFT_ANIM_NAME }, + {"breachRaiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_BREACH_RAISE]), WFT_ANIM_NAME }, + {"altRaiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ALT_RAISE]), WFT_ANIM_NAME }, + {"altDropAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ALT_DROP]), WFT_ANIM_NAME }, + {"quickRaiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_QUICK_RAISE]), WFT_ANIM_NAME }, + {"quickDropAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_QUICK_DROP]), WFT_ANIM_NAME }, + {"emptyRaiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_EMPTY_RAISE]), WFT_ANIM_NAME }, + {"emptyDropAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_EMPTY_DROP]), WFT_ANIM_NAME }, + {"sprintInAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_SPRINT_IN]), WFT_ANIM_NAME }, + {"sprintLoopAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_SPRINT_LOOP]), WFT_ANIM_NAME }, + {"sprintOutAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_SPRINT_OUT]), WFT_ANIM_NAME }, + {"stunnedAnimStart", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_STUNNED_START]), WFT_ANIM_NAME }, + {"stunnedAnimLoop", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_STUNNED_LOOP]), WFT_ANIM_NAME }, + {"stunnedAnimEnd", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_STUNNED_END]), WFT_ANIM_NAME }, + {"nightVisionWearAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_NIGHTVISION_WEAR]), WFT_ANIM_NAME }, + {"nightVisionRemoveAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_NIGHTVISION_REMOVE]), WFT_ANIM_NAME }, + {"adsFireAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ADS_FIRE]), WFT_ANIM_NAME }, + {"adsLastShotAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ADS_LASTSHOT]), WFT_ANIM_NAME }, + {"adsRechamberAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ADS_RECHAMBER]), WFT_ANIM_NAME }, + {"blastFrontAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_BLAST_FRONT]), WFT_ANIM_NAME }, + {"blastRightAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_BLAST_RIGHT]), WFT_ANIM_NAME }, + {"blastBackAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_BLAST_BACK]), WFT_ANIM_NAME }, + {"blastLeftAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_BLAST_LEFT]), WFT_ANIM_NAME }, + {"adsUpAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ADS_UP]), WFT_ANIM_NAME }, + {"adsDownAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ADS_DOWN]), WFT_ANIM_NAME }, + {"altAdjustAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ALT_ANIM_ADJUST]), WFT_ANIM_NAME }, + {"idleAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_IDLE]), WFT_ANIM_NAME }, + {"emptyIdleAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_EMPTY_IDLE]), WFT_ANIM_NAME }, + {"fireAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_FIRE]), WFT_ANIM_NAME }, + {"holdFireAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_HOLD_FIRE]), WFT_ANIM_NAME }, + {"lastShotAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_LASTSHOT]), WFT_ANIM_NAME }, + {"detonateAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_DETONATE]), WFT_ANIM_NAME }, + {"rechamberAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RECHAMBER]), WFT_ANIM_NAME }, + {"meleeAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_MELEE]), WFT_ANIM_NAME }, + {"meleeChargeAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_MELEE_CHARGE]), WFT_ANIM_NAME }, + {"reloadAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RELOAD]), WFT_ANIM_NAME }, + {"reloadEmptyAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RELOAD_EMPTY]), WFT_ANIM_NAME }, + {"reloadStartAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RELOAD_START]), WFT_ANIM_NAME }, + {"reloadEndAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RELOAD_END]), WFT_ANIM_NAME }, + {"raiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RAISE]), WFT_ANIM_NAME }, + {"dropAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_DROP]), WFT_ANIM_NAME }, + {"firstRaiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_FIRST_RAISE]), WFT_ANIM_NAME }, + {"breachRaiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_BREACH_RAISE]), WFT_ANIM_NAME }, + {"altRaiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ALT_RAISE]), WFT_ANIM_NAME }, + {"altDropAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ALT_DROP]), WFT_ANIM_NAME }, + {"quickRaiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_QUICK_RAISE]), WFT_ANIM_NAME }, + {"quickDropAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_QUICK_DROP]), WFT_ANIM_NAME }, + {"emptyRaiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_EMPTY_RAISE]), WFT_ANIM_NAME }, + {"emptyDropAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_EMPTY_DROP]), WFT_ANIM_NAME }, + {"sprintInAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_SPRINT_IN]), WFT_ANIM_NAME }, + {"sprintLoopAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_SPRINT_LOOP]), WFT_ANIM_NAME }, + {"sprintOutAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_SPRINT_OUT]), WFT_ANIM_NAME }, + {"stunnedAnimStartR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_STUNNED_START]), WFT_ANIM_NAME }, + {"stunnedAnimLoopR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_STUNNED_LOOP]), WFT_ANIM_NAME }, + {"stunnedAnimEndR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_STUNNED_END]), WFT_ANIM_NAME }, + {"nightVisionWearAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_NIGHTVISION_WEAR]), WFT_ANIM_NAME }, + {"nightVisionRemoveAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_NIGHTVISION_REMOVE]), WFT_ANIM_NAME }, + {"adsFireAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ADS_FIRE]), WFT_ANIM_NAME }, + {"adsLastShotAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ADS_LASTSHOT]), WFT_ANIM_NAME }, + {"adsRechamberAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ADS_RECHAMBER]), WFT_ANIM_NAME }, + {"adsUpAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ADS_UP]), WFT_ANIM_NAME }, + {"blastFrontAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_BLAST_FRONT]), WFT_ANIM_NAME }, + {"blastRightAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_BLAST_RIGHT]), WFT_ANIM_NAME }, + {"blastBackAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_BLAST_BACK]), WFT_ANIM_NAME }, + {"blastLeftAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_BLAST_LEFT]), WFT_ANIM_NAME }, + {"adsDownAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ADS_DOWN]), WFT_ANIM_NAME }, + {"altAdjustAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ALT_ANIM_ADJUST]), WFT_ANIM_NAME }, + {"idleAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_IDLE]), WFT_ANIM_NAME }, + {"emptyIdleAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_EMPTY_IDLE]), WFT_ANIM_NAME }, + {"fireAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_FIRE]), WFT_ANIM_NAME }, + {"holdFireAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_HOLD_FIRE]), WFT_ANIM_NAME }, + {"lastShotAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_LASTSHOT]), WFT_ANIM_NAME }, + {"detonateAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_DETONATE]), WFT_ANIM_NAME }, + {"rechamberAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RECHAMBER]), WFT_ANIM_NAME }, + {"meleeAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_MELEE]), WFT_ANIM_NAME }, + {"meleeChargeAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_MELEE_CHARGE]), WFT_ANIM_NAME }, + {"reloadAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RELOAD]), WFT_ANIM_NAME }, + {"reloadEmptyAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RELOAD_EMPTY]), WFT_ANIM_NAME }, + {"reloadStartAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RELOAD_START]), WFT_ANIM_NAME }, + {"reloadEndAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RELOAD_END]), WFT_ANIM_NAME }, + {"raiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RAISE]), WFT_ANIM_NAME }, + {"dropAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_DROP]), WFT_ANIM_NAME }, + {"firstRaiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_FIRST_RAISE]), WFT_ANIM_NAME }, + {"breachRaiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_BREACH_RAISE]), WFT_ANIM_NAME }, + {"altRaiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ALT_RAISE]), WFT_ANIM_NAME }, + {"altDropAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ALT_DROP]), WFT_ANIM_NAME }, + {"quickRaiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_QUICK_RAISE]), WFT_ANIM_NAME }, + {"quickDropAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_QUICK_DROP]), WFT_ANIM_NAME }, + {"emptyRaiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_EMPTY_RAISE]), WFT_ANIM_NAME }, + {"emptyDropAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_EMPTY_DROP]), WFT_ANIM_NAME }, + {"sprintInAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_SPRINT_IN]), WFT_ANIM_NAME }, + {"sprintLoopAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_SPRINT_LOOP]), WFT_ANIM_NAME }, + {"sprintOutAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_SPRINT_OUT]), WFT_ANIM_NAME }, + {"stunnedAnimStartL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_STUNNED_START]), WFT_ANIM_NAME }, + {"stunnedAnimLoopL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_STUNNED_LOOP]), WFT_ANIM_NAME }, + {"stunnedAnimEndL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_STUNNED_END]), WFT_ANIM_NAME }, + {"nightVisionWearAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_NIGHTVISION_WEAR]), WFT_ANIM_NAME }, + {"nightVisionRemoveAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_NIGHTVISION_REMOVE]), WFT_ANIM_NAME }, + {"adsFireAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ADS_FIRE]), WFT_ANIM_NAME }, + {"adsLastShotAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ADS_LASTSHOT]), WFT_ANIM_NAME }, + {"adsRechamberAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ADS_RECHAMBER]), WFT_ANIM_NAME }, + {"blastFrontAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_BLAST_FRONT]), WFT_ANIM_NAME }, + {"blastRightAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_BLAST_RIGHT]), WFT_ANIM_NAME }, + {"blastBackAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_BLAST_BACK]), WFT_ANIM_NAME }, + {"blastLeftAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_BLAST_LEFT]), WFT_ANIM_NAME }, + {"adsUpAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ADS_UP]), WFT_ANIM_NAME }, + {"adsDownAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ADS_DOWN]), WFT_ANIM_NAME }, + {"altAdjustAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ALT_ANIM_ADJUST]), WFT_ANIM_NAME }, + {"script", offsetof(WeaponFullDef, weapDef.szScript), CSPFT_STRING }, + {"weaponType", offsetof(WeaponFullDef, weapDef.weapType), WFT_WEAPONTYPE }, + {"weaponClass", offsetof(WeaponFullDef, weapDef.weapClass), WFT_WEAPONCLASS }, + {"penetrateType", offsetof(WeaponFullDef, weapDef.penetrateType), WFT_PENETRATE_TYPE }, + {"penetrateMultiplier", offsetof(WeaponFullDef, weapCompleteDef.penetrateMultiplier), CSPFT_FLOAT }, + {"impactType", offsetof(WeaponFullDef, weapCompleteDef.impactType), WFT_IMPACT_TYPE }, + {"inventoryType", offsetof(WeaponFullDef, weapDef.inventoryType), WFT_INVENTORYTYPE }, + {"fireType", offsetof(WeaponFullDef, weapDef.fireType), WFT_FIRETYPE }, + {"offhandClass", offsetof(WeaponFullDef, weapDef.offhandClass), WFT_OFFHAND_CLASS }, + {"viewFlashEffect", offsetof(WeaponFullDef, weapDef.viewFlashEffect), CSPFT_FX }, + {"worldFlashEffect", offsetof(WeaponFullDef, weapDef.worldFlashEffect), CSPFT_FX }, + {"pickupSound", offsetof(WeaponFullDef, weapDef.pickupSound), CSPFT_SOUND }, + {"pickupSoundPlayer", offsetof(WeaponFullDef, weapDef.pickupSoundPlayer), CSPFT_SOUND }, + {"ammoPickupSound", offsetof(WeaponFullDef, weapDef.ammoPickupSound), CSPFT_SOUND }, + {"ammoPickupSoundPlayer", offsetof(WeaponFullDef, weapDef.ammoPickupSoundPlayer), CSPFT_SOUND }, + {"projectileSound", offsetof(WeaponFullDef, weapDef.projectileSound), CSPFT_SOUND }, + {"pullbackSound", offsetof(WeaponFullDef, weapDef.pullbackSound), CSPFT_SOUND }, + {"pullbackSoundPlayer", offsetof(WeaponFullDef, weapDef.pullbackSoundPlayer), CSPFT_SOUND }, + {"fireSound", offsetof(WeaponFullDef, weapDef.fireSound), CSPFT_SOUND }, + {"fireSoundPlayer", offsetof(WeaponFullDef, weapDef.fireSoundPlayer), CSPFT_SOUND }, + {"fireSoundPlayerAkimbo", offsetof(WeaponFullDef, weapDef.fireSoundPlayerAkimbo), CSPFT_SOUND }, + {"loopFireSound", offsetof(WeaponFullDef, weapDef.fireLoopSound), CSPFT_SOUND }, + {"loopFireSoundPlayer", offsetof(WeaponFullDef, weapDef.fireLoopSoundPlayer), CSPFT_SOUND }, + {"stopFireSound", offsetof(WeaponFullDef, weapDef.fireStopSound), CSPFT_SOUND }, + {"stopFireSoundPlayer", offsetof(WeaponFullDef, weapDef.fireStopSoundPlayer), CSPFT_SOUND }, + {"lastShotSound", offsetof(WeaponFullDef, weapDef.fireLastSound), CSPFT_SOUND }, + {"lastShotSoundPlayer", offsetof(WeaponFullDef, weapDef.fireLastSoundPlayer), CSPFT_SOUND }, + {"emptyFireSound", offsetof(WeaponFullDef, weapDef.emptyFireSound), CSPFT_SOUND }, + {"emptyFireSoundPlayer", offsetof(WeaponFullDef, weapDef.emptyFireSoundPlayer), CSPFT_SOUND }, + {"meleeSwipeSound", offsetof(WeaponFullDef, weapDef.meleeSwipeSound), CSPFT_SOUND }, + {"meleeSwipeSoundPlayer", offsetof(WeaponFullDef, weapDef.meleeSwipeSoundPlayer), CSPFT_SOUND }, + {"meleeHitSound", offsetof(WeaponFullDef, weapDef.meleeHitSound), CSPFT_SOUND }, + {"meleeMissSound", offsetof(WeaponFullDef, weapDef.meleeMissSound), CSPFT_SOUND }, + {"rechamberSound", offsetof(WeaponFullDef, weapDef.rechamberSound), CSPFT_SOUND }, + {"rechamberSoundPlayer", offsetof(WeaponFullDef, weapDef.rechamberSoundPlayer), CSPFT_SOUND }, + {"reloadSound", offsetof(WeaponFullDef, weapDef.reloadSound), CSPFT_SOUND }, + {"reloadSoundPlayer", offsetof(WeaponFullDef, weapDef.reloadSoundPlayer), CSPFT_SOUND }, + {"reloadEmptySound", offsetof(WeaponFullDef, weapDef.reloadEmptySound), CSPFT_SOUND }, + {"reloadEmptySoundPlayer", offsetof(WeaponFullDef, weapDef.reloadEmptySoundPlayer), CSPFT_SOUND }, + {"reloadStartSound", offsetof(WeaponFullDef, weapDef.reloadStartSound), CSPFT_SOUND }, + {"reloadStartSoundPlayer", offsetof(WeaponFullDef, weapDef.reloadStartSoundPlayer), CSPFT_SOUND }, + {"reloadEndSound", offsetof(WeaponFullDef, weapDef.reloadEndSound), CSPFT_SOUND }, + {"reloadEndSoundPlayer", offsetof(WeaponFullDef, weapDef.reloadEndSoundPlayer), CSPFT_SOUND }, + {"detonateSound", offsetof(WeaponFullDef, weapDef.detonateSound), CSPFT_SOUND }, + {"detonateSoundPlayer", offsetof(WeaponFullDef, weapDef.detonateSoundPlayer), CSPFT_SOUND }, + {"nightVisionWearSound", offsetof(WeaponFullDef, weapDef.nightVisionWearSound), CSPFT_SOUND }, + {"nightVisionWearSoundPlayer", offsetof(WeaponFullDef, weapDef.nightVisionWearSoundPlayer), CSPFT_SOUND }, + {"nightVisionRemoveSound", offsetof(WeaponFullDef, weapDef.nightVisionRemoveSound), CSPFT_SOUND }, + {"nightVisionRemoveSoundPlayer", offsetof(WeaponFullDef, weapDef.nightVisionRemoveSoundPlayer), CSPFT_SOUND }, + {"raiseSound", offsetof(WeaponFullDef, weapDef.raiseSound), CSPFT_SOUND }, + {"raiseSoundPlayer", offsetof(WeaponFullDef, weapDef.raiseSoundPlayer), CSPFT_SOUND }, + {"firstRaiseSound", offsetof(WeaponFullDef, weapDef.firstRaiseSound), CSPFT_SOUND }, + {"firstRaiseSoundPlayer", offsetof(WeaponFullDef, weapDef.firstRaiseSoundPlayer), CSPFT_SOUND }, + {"altSwitchSound", offsetof(WeaponFullDef, weapDef.altSwitchSound), CSPFT_SOUND }, + {"altSwitchSoundPlayer", offsetof(WeaponFullDef, weapDef.altSwitchSoundPlayer), CSPFT_SOUND }, + {"putawaySound", offsetof(WeaponFullDef, weapDef.putawaySound), CSPFT_SOUND }, + {"putawaySoundPlayer", offsetof(WeaponFullDef, weapDef.putawaySoundPlayer), CSPFT_SOUND }, + {"scanSound", offsetof(WeaponFullDef, weapDef.scanSound), CSPFT_SOUND }, + {"bounceSound", offsetof(WeaponFullDef, weapDef.bounceSound), WFT_BOUNCE_SOUND }, + {"viewShellEjectEffect", offsetof(WeaponFullDef, weapDef.viewShellEjectEffect), CSPFT_FX }, + {"worldShellEjectEffect", offsetof(WeaponFullDef, weapDef.worldShellEjectEffect), CSPFT_FX }, + {"viewLastShotEjectEffect", offsetof(WeaponFullDef, weapDef.viewLastShotEjectEffect), CSPFT_FX }, + {"worldLastShotEjectEffect", offsetof(WeaponFullDef, weapDef.worldLastShotEjectEffect), CSPFT_FX }, + {"reticleCenter", offsetof(WeaponFullDef, weapDef.reticleCenter), CSPFT_MATERIAL }, + {"reticleSide", offsetof(WeaponFullDef, weapDef.reticleSide), CSPFT_MATERIAL }, + {"reticleCenterSize", offsetof(WeaponFullDef, weapDef.iReticleCenterSize), CSPFT_INT }, + {"reticleSideSize", offsetof(WeaponFullDef, weapDef.iReticleSideSize), CSPFT_INT }, + {"reticleMinOfs", offsetof(WeaponFullDef, weapDef.iReticleMinOfs), CSPFT_INT }, + {"activeReticleType", offsetof(WeaponFullDef, weapDef.activeReticleType), WFT_ACTIVE_RETICLE_TYPE }, + {"standMoveF", offsetof(WeaponFullDef, weapDef.vStandMove[0]), CSPFT_FLOAT }, + {"standMoveR", offsetof(WeaponFullDef, weapDef.vStandMove[1]), CSPFT_FLOAT }, + {"standMoveU", offsetof(WeaponFullDef, weapDef.vStandMove[2]), CSPFT_FLOAT }, + {"standRotP", offsetof(WeaponFullDef, weapDef.vStandRot[0]), CSPFT_FLOAT }, + {"standRotY", offsetof(WeaponFullDef, weapDef.vStandRot[1]), CSPFT_FLOAT }, + {"standRotR", offsetof(WeaponFullDef, weapDef.vStandRot[2]), CSPFT_FLOAT }, + {"strafeMoveF", offsetof(WeaponFullDef, weapDef.strafeMove[0]), CSPFT_FLOAT }, + {"strafeMoveR", offsetof(WeaponFullDef, weapDef.strafeMove[1]), CSPFT_FLOAT }, + {"strafeMoveU", offsetof(WeaponFullDef, weapDef.strafeMove[2]), CSPFT_FLOAT }, + {"strafeRotP", offsetof(WeaponFullDef, weapDef.strafeRot[0]), CSPFT_FLOAT }, + {"strafeRotY", offsetof(WeaponFullDef, weapDef.strafeRot[1]), CSPFT_FLOAT }, + {"strafeRotR", offsetof(WeaponFullDef, weapDef.strafeRot[2]), CSPFT_FLOAT }, + {"duckedOfsF", offsetof(WeaponFullDef, weapDef.vDuckedOfs[0]), CSPFT_FLOAT }, + {"duckedOfsR", offsetof(WeaponFullDef, weapDef.vDuckedOfs[1]), CSPFT_FLOAT }, + {"duckedOfsU", offsetof(WeaponFullDef, weapDef.vDuckedOfs[2]), CSPFT_FLOAT }, + {"duckedMoveF", offsetof(WeaponFullDef, weapDef.vDuckedMove[0]), CSPFT_FLOAT }, + {"duckedMoveR", offsetof(WeaponFullDef, weapDef.vDuckedMove[1]), CSPFT_FLOAT }, + {"duckedMoveU", offsetof(WeaponFullDef, weapDef.vDuckedMove[2]), CSPFT_FLOAT }, + {"duckedRotP", offsetof(WeaponFullDef, weapDef.vDuckedRot[0]), CSPFT_FLOAT }, + {"duckedRotY", offsetof(WeaponFullDef, weapDef.vDuckedRot[1]), CSPFT_FLOAT }, + {"duckedRotR", offsetof(WeaponFullDef, weapDef.vDuckedRot[2]), CSPFT_FLOAT }, + {"proneOfsF", offsetof(WeaponFullDef, weapDef.vProneOfs[0]), CSPFT_FLOAT }, + {"proneOfsR", offsetof(WeaponFullDef, weapDef.vProneOfs[1]), CSPFT_FLOAT }, + {"proneOfsU", offsetof(WeaponFullDef, weapDef.vProneOfs[2]), CSPFT_FLOAT }, + {"proneMoveF", offsetof(WeaponFullDef, weapDef.vProneMove[0]), CSPFT_FLOAT }, + {"proneMoveR", offsetof(WeaponFullDef, weapDef.vProneMove[1]), CSPFT_FLOAT }, + {"proneMoveU", offsetof(WeaponFullDef, weapDef.vProneMove[2]), CSPFT_FLOAT }, + {"proneRotP", offsetof(WeaponFullDef, weapDef.vProneRot[0]), CSPFT_FLOAT }, + {"proneRotY", offsetof(WeaponFullDef, weapDef.vProneRot[1]), CSPFT_FLOAT }, + {"proneRotR", offsetof(WeaponFullDef, weapDef.vProneRot[2]), CSPFT_FLOAT }, + {"posMoveRate", offsetof(WeaponFullDef, weapDef.fPosMoveRate), CSPFT_FLOAT }, + {"posProneMoveRate", offsetof(WeaponFullDef, weapDef.fPosProneMoveRate), CSPFT_FLOAT }, + {"standMoveMinSpeed", offsetof(WeaponFullDef, weapDef.fStandMoveMinSpeed), CSPFT_FLOAT }, + {"duckedMoveMinSpeed", offsetof(WeaponFullDef, weapDef.fDuckedMoveMinSpeed), CSPFT_FLOAT }, + {"proneMoveMinSpeed", offsetof(WeaponFullDef, weapDef.fProneMoveMinSpeed), CSPFT_FLOAT }, + {"posRotRate", offsetof(WeaponFullDef, weapDef.fPosRotRate), CSPFT_FLOAT }, + {"posProneRotRate", offsetof(WeaponFullDef, weapDef.fPosProneRotRate), CSPFT_FLOAT }, + {"standRotMinSpeed", offsetof(WeaponFullDef, weapDef.fStandRotMinSpeed), CSPFT_FLOAT }, + {"duckedRotMinSpeed", offsetof(WeaponFullDef, weapDef.fDuckedRotMinSpeed), CSPFT_FLOAT }, + {"proneRotMinSpeed", offsetof(WeaponFullDef, weapDef.fProneRotMinSpeed), CSPFT_FLOAT }, + {"worldModel", offsetof(WeaponFullDef, worldModel[0]), CSPFT_XMODEL }, + {"worldModel2", offsetof(WeaponFullDef, worldModel[1]), CSPFT_XMODEL }, + {"worldModel3", offsetof(WeaponFullDef, worldModel[2]), CSPFT_XMODEL }, + {"worldModel4", offsetof(WeaponFullDef, worldModel[3]), CSPFT_XMODEL }, + {"worldModel5", offsetof(WeaponFullDef, worldModel[4]), CSPFT_XMODEL }, + {"worldModel6", offsetof(WeaponFullDef, worldModel[5]), CSPFT_XMODEL }, + {"worldModel7", offsetof(WeaponFullDef, worldModel[6]), CSPFT_XMODEL }, + {"worldModel8", offsetof(WeaponFullDef, worldModel[7]), CSPFT_XMODEL }, + {"worldModel9", offsetof(WeaponFullDef, worldModel[8]), CSPFT_XMODEL }, + {"worldModel10", offsetof(WeaponFullDef, worldModel[9]), CSPFT_XMODEL }, + {"worldModel11", offsetof(WeaponFullDef, worldModel[10]), CSPFT_XMODEL }, + {"worldModel12", offsetof(WeaponFullDef, worldModel[11]), CSPFT_XMODEL }, + {"worldModel13", offsetof(WeaponFullDef, worldModel[12]), CSPFT_XMODEL }, + {"worldModel14", offsetof(WeaponFullDef, worldModel[13]), CSPFT_XMODEL }, + {"worldModel15", offsetof(WeaponFullDef, worldModel[14]), CSPFT_XMODEL }, + {"worldModel16", offsetof(WeaponFullDef, worldModel[15]), CSPFT_XMODEL }, + {"worldClipModel", offsetof(WeaponFullDef, weapDef.worldClipModel), CSPFT_XMODEL }, + {"rocketModel", offsetof(WeaponFullDef, weapDef.rocketModel), CSPFT_XMODEL }, + {"knifeModel", offsetof(WeaponFullDef, weapDef.knifeModel), CSPFT_XMODEL }, + {"worldKnifeModel", offsetof(WeaponFullDef, weapDef.worldKnifeModel), CSPFT_XMODEL }, + {"hudIcon", offsetof(WeaponFullDef, weapDef.hudIcon), CSPFT_MATERIAL }, + {"hudIconRatio", offsetof(WeaponFullDef, weapDef.hudIconRatio), WFT_ICONRATIO_HUD }, + {"pickupIcon", offsetof(WeaponFullDef, weapDef.pickupIcon), CSPFT_MATERIAL }, + {"pickupIconRatio", offsetof(WeaponFullDef, weapDef.pickupIconRatio), WFT_ICONRATIO_PICKUP }, + {"ammoCounterIcon", offsetof(WeaponFullDef, weapDef.ammoCounterIcon), CSPFT_MATERIAL }, + {"ammoCounterIconRatio", offsetof(WeaponFullDef, weapDef.ammoCounterIconRatio), WFT_ICONRATIO_AMMOCOUNTER}, + {"ammoCounterClip", offsetof(WeaponFullDef, weapDef.ammoCounterClip), WFT_AMMOCOUNTER_CLIPTYPE }, + {"startAmmo", offsetof(WeaponFullDef, weapDef.iStartAmmo), CSPFT_INT }, + {"shareAmmo", offsetof(WeaponFullDef, weapDef.sharedAmmo), CSPFT_BOOL }, + {"ammoName", offsetof(WeaponFullDef, weapDef.szAmmoName), CSPFT_STRING }, + {"clipName", offsetof(WeaponFullDef, weapDef.szClipName), CSPFT_STRING }, + {"maxAmmo", offsetof(WeaponFullDef, weapDef.iMaxAmmo), CSPFT_INT }, + {"clipSize", offsetof(WeaponFullDef, weapCompleteDef.iClipSize), CSPFT_INT }, + {"shotCount", offsetof(WeaponFullDef, weapDef.shotCount), CSPFT_INT }, + {"sharedAmmoCapName", offsetof(WeaponFullDef, weapDef.szSharedAmmoCapName), CSPFT_STRING }, + {"sharedAmmoCap", offsetof(WeaponFullDef, weapDef.iSharedAmmoCap), CSPFT_INT }, + {"damage", offsetof(WeaponFullDef, weapDef.damage), CSPFT_INT }, + {"playerDamage", offsetof(WeaponFullDef, weapDef.playerDamage), CSPFT_INT }, + {"meleeDamage", offsetof(WeaponFullDef, weapDef.iMeleeDamage), CSPFT_INT }, + {"minDamage", offsetof(WeaponFullDef, weapDef.minDamage), CSPFT_INT }, + {"minPlayerDamage", offsetof(WeaponFullDef, weapDef.minPlayerDamage), CSPFT_INT }, + {"maxDamageRange", offsetof(WeaponFullDef, weapDef.fMaxDamageRange), CSPFT_FLOAT }, + {"minDamageRange", offsetof(WeaponFullDef, weapDef.fMinDamageRange), CSPFT_FLOAT }, + {"destabilizationRateTime", offsetof(WeaponFullDef, weapDef.destabilizationRateTime), CSPFT_FLOAT }, + {"destabilizationCurvatureMax", offsetof(WeaponFullDef, weapDef.destabilizationCurvatureMax), CSPFT_FLOAT }, + {"destabilizeDistance", offsetof(WeaponFullDef, weapDef.destabilizeDistance), CSPFT_INT }, + {"fireDelay", offsetof(WeaponFullDef, weapDef.stateTimers.iFireDelay), CSPFT_MILLISECONDS }, + {"meleeDelay", offsetof(WeaponFullDef, weapDef.stateTimers.iMeleeDelay), CSPFT_MILLISECONDS }, + {"meleeChargeDelay", offsetof(WeaponFullDef, weapDef.stateTimers.meleeChargeDelay), CSPFT_MILLISECONDS }, + {"fireTime", offsetof(WeaponFullDef, weapCompleteDef.iFireTime), CSPFT_MILLISECONDS }, + {"rechamberTime", offsetof(WeaponFullDef, weapDef.stateTimers.iRechamberTime), CSPFT_MILLISECONDS }, + {"rechamberTimeOneHanded", offsetof(WeaponFullDef, weapDef.stateTimers.rechamberTimeOneHanded), CSPFT_MILLISECONDS }, + {"rechamberBoltTime", offsetof(WeaponFullDef, weapDef.stateTimers.iRechamberBoltTime), CSPFT_MILLISECONDS }, + {"holdFireTime", offsetof(WeaponFullDef, weapDef.stateTimers.iHoldFireTime), CSPFT_MILLISECONDS }, + {"detonateTime", offsetof(WeaponFullDef, weapDef.stateTimers.iDetonateTime), CSPFT_MILLISECONDS }, + {"detonateDelay", offsetof(WeaponFullDef, weapDef.stateTimers.iDetonateDelay), CSPFT_MILLISECONDS }, + {"meleeTime", offsetof(WeaponFullDef, weapDef.stateTimers.iMeleeTime), CSPFT_MILLISECONDS }, + {"meleeChargeTime", offsetof(WeaponFullDef, weapDef.stateTimers.meleeChargeTime), CSPFT_MILLISECONDS }, + {"reloadTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadTime), CSPFT_MILLISECONDS }, + {"reloadShowRocketTime", offsetof(WeaponFullDef, weapDef.stateTimers.reloadShowRocketTime), CSPFT_MILLISECONDS }, + {"reloadEmptyTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadEmptyTime), CSPFT_MILLISECONDS }, + {"reloadAddTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadAddTime), CSPFT_MILLISECONDS }, + {"reloadStartTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadStartTime), CSPFT_MILLISECONDS }, + {"reloadStartAddTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadStartAddTime), CSPFT_MILLISECONDS }, + {"reloadEndTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadEndTime), CSPFT_MILLISECONDS }, + {"dropTime", offsetof(WeaponFullDef, weapDef.stateTimers.iDropTime), CSPFT_MILLISECONDS }, + {"raiseTime", offsetof(WeaponFullDef, weapDef.stateTimers.iRaiseTime), CSPFT_MILLISECONDS }, + {"altDropTime", offsetof(WeaponFullDef, weapDef.stateTimers.iAltDropTime), CSPFT_MILLISECONDS }, + {"altRaiseTime", offsetof(WeaponFullDef, weapCompleteDef.iAltRaiseTime), CSPFT_MILLISECONDS }, + {"quickDropTime", offsetof(WeaponFullDef, weapDef.stateTimers.quickDropTime), CSPFT_MILLISECONDS }, + {"quickRaiseTime", offsetof(WeaponFullDef, weapDef.stateTimers.quickRaiseTime), CSPFT_MILLISECONDS }, + {"firstRaiseTime", offsetof(WeaponFullDef, weapCompleteDef.iFirstRaiseTime), CSPFT_MILLISECONDS }, + {"breachRaiseTime", offsetof(WeaponFullDef, weapDef.stateTimers.iBreachRaiseTime), CSPFT_MILLISECONDS }, + {"emptyRaiseTime", offsetof(WeaponFullDef, weapDef.stateTimers.iEmptyRaiseTime), CSPFT_MILLISECONDS }, + {"emptyDropTime", offsetof(WeaponFullDef, weapDef.stateTimers.iEmptyDropTime), CSPFT_MILLISECONDS }, + {"sprintInTime", offsetof(WeaponFullDef, weapDef.stateTimers.sprintInTime), CSPFT_MILLISECONDS }, + {"sprintLoopTime", offsetof(WeaponFullDef, weapDef.stateTimers.sprintLoopTime), CSPFT_MILLISECONDS }, + {"sprintOutTime", offsetof(WeaponFullDef, weapDef.stateTimers.sprintOutTime), CSPFT_MILLISECONDS }, + {"stunnedTimeBegin", offsetof(WeaponFullDef, weapDef.stateTimers.stunnedTimeBegin), CSPFT_MILLISECONDS }, + {"stunnedTimeLoop", offsetof(WeaponFullDef, weapDef.stateTimers.stunnedTimeLoop), CSPFT_MILLISECONDS }, + {"stunnedTimeEnd", offsetof(WeaponFullDef, weapDef.stateTimers.stunnedTimeEnd), CSPFT_MILLISECONDS }, + {"nightVisionWearTime", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionWearTime), CSPFT_MILLISECONDS }, + {"nightVisionWearTimeFadeOutEnd", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionWearTimeFadeOutEnd), CSPFT_MILLISECONDS }, + {"nightVisionWearTimePowerUp", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionWearTimePowerUp), CSPFT_MILLISECONDS }, + {"nightVisionRemoveTime", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionRemoveTime), CSPFT_MILLISECONDS }, + {"nightVisionRemoveTimePowerDown", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionRemoveTimePowerDown), CSPFT_MILLISECONDS }, + {"nightVisionRemoveTimeFadeInStart", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionRemoveTimeFadeInStart), CSPFT_MILLISECONDS }, + {"fuseTime", offsetof(WeaponFullDef, weapDef.stateTimers.fuseTime), CSPFT_MILLISECONDS }, + {"aifuseTime", offsetof(WeaponFullDef, weapDef.stateTimers.aiFuseTime), CSPFT_MILLISECONDS }, + {"lockonSupported", offsetof(WeaponFullDef, weapDef.lockonSupported), CSPFT_BOOL }, + {"requireLockonToFire", offsetof(WeaponFullDef, weapDef.requireLockonToFire), CSPFT_BOOL }, + {"bigExplosion", offsetof(WeaponFullDef, weapDef.bigExplosion), CSPFT_BOOL }, + {"noAdsWhenMagEmpty", offsetof(WeaponFullDef, weapDef.noAdsWhenMagEmpty), CSPFT_BOOL }, + {"inheritsPerks", offsetof(WeaponFullDef, weapDef.inheritsPerks), CSPFT_BOOL }, + {"avoidDropCleanup", offsetof(WeaponFullDef, weapDef.avoidDropCleanup), CSPFT_BOOL }, + {"autoAimRange", offsetof(WeaponFullDef, weapDef.autoAimRange), CSPFT_FLOAT }, + {"aimAssistRange", offsetof(WeaponFullDef, weapDef.aimAssistRange), CSPFT_FLOAT }, + {"aimAssistRangeAds", offsetof(WeaponFullDef, weapDef.aimAssistRangeAds), CSPFT_FLOAT }, + {"aimPadding", offsetof(WeaponFullDef, weapDef.aimPadding), CSPFT_FLOAT }, + {"enemyCrosshairRange", offsetof(WeaponFullDef, weapDef.enemyCrosshairRange), CSPFT_FLOAT }, + {"crosshairColorChange", offsetof(WeaponFullDef, weapDef.crosshairColorChange), CSPFT_BOOL }, + {"moveSpeedScale", offsetof(WeaponFullDef, weapDef.moveSpeedScale), CSPFT_FLOAT }, + {"adsMoveSpeedScale", offsetof(WeaponFullDef, weapDef.adsMoveSpeedScale), CSPFT_FLOAT }, + {"sprintDurationScale", offsetof(WeaponFullDef, weapDef.sprintDurationScale), CSPFT_FLOAT }, + {"idleCrouchFactor", offsetof(WeaponFullDef, weapDef.fIdleCrouchFactor), CSPFT_FLOAT }, + {"idleProneFactor", offsetof(WeaponFullDef, weapDef.fIdleProneFactor), CSPFT_FLOAT }, + {"gunMaxPitch", offsetof(WeaponFullDef, weapDef.fGunMaxPitch), CSPFT_FLOAT }, + {"gunMaxYaw", offsetof(WeaponFullDef, weapDef.fGunMaxYaw), CSPFT_FLOAT }, + {"swayMaxAngle", offsetof(WeaponFullDef, weapDef.swayMaxAngle), CSPFT_FLOAT }, + {"swayLerpSpeed", offsetof(WeaponFullDef, weapDef.swayLerpSpeed), CSPFT_FLOAT }, + {"swayPitchScale", offsetof(WeaponFullDef, weapDef.swayPitchScale), CSPFT_FLOAT }, + {"swayYawScale", offsetof(WeaponFullDef, weapDef.swayYawScale), CSPFT_FLOAT }, + {"swayHorizScale", offsetof(WeaponFullDef, weapDef.swayHorizScale), CSPFT_FLOAT }, + {"swayVertScale", offsetof(WeaponFullDef, weapDef.swayVertScale), CSPFT_FLOAT }, + {"swayShellShockScale", offsetof(WeaponFullDef, weapDef.swayShellShockScale), CSPFT_FLOAT }, + {"adsSwayMaxAngle", offsetof(WeaponFullDef, weapDef.adsSwayMaxAngle), CSPFT_FLOAT }, + {"adsSwayLerpSpeed", offsetof(WeaponFullDef, weapDef.adsSwayLerpSpeed), CSPFT_FLOAT }, + {"adsSwayPitchScale", offsetof(WeaponFullDef, weapDef.adsSwayPitchScale), CSPFT_FLOAT }, + {"adsSwayYawScale", offsetof(WeaponFullDef, weapDef.adsSwayYawScale), CSPFT_FLOAT }, + {"adsSwayHorizScale", offsetof(WeaponFullDef, weapDef.adsSwayHorizScale), CSPFT_FLOAT }, + {"adsSwayVertScale", offsetof(WeaponFullDef, weapDef.adsSwayVertScale), CSPFT_FLOAT }, + {"rifleBullet", offsetof(WeaponFullDef, weapDef.bRifleBullet), CSPFT_BOOL }, + {"armorPiercing", offsetof(WeaponFullDef, weapDef.armorPiercing), CSPFT_BOOL }, + {"boltAction", offsetof(WeaponFullDef, weapDef.bBoltAction), CSPFT_BOOL }, + {"aimDownSight", offsetof(WeaponFullDef, weapDef.aimDownSight), CSPFT_BOOL }, + {"rechamberWhileAds", offsetof(WeaponFullDef, weapDef.bRechamberWhileAds), CSPFT_BOOL }, + {"bBulletExplosiveDamage", offsetof(WeaponFullDef, weapDef.bBulletExplosiveDamage), CSPFT_BOOL }, + {"adsViewErrorMin", offsetof(WeaponFullDef, weapDef.adsViewErrorMin), CSPFT_FLOAT }, + {"adsViewErrorMax", offsetof(WeaponFullDef, weapDef.adsViewErrorMax), CSPFT_FLOAT }, + {"clipOnly", offsetof(WeaponFullDef, weapDef.bClipOnly), CSPFT_BOOL }, + {"noAmmoPickup", offsetof(WeaponFullDef, weapDef.noAmmoPickup), CSPFT_BOOL }, + {"cookOffHold", offsetof(WeaponFullDef, weapDef.bCookOffHold), CSPFT_BOOL }, + {"adsFire", offsetof(WeaponFullDef, weapDef.adsFireOnly), CSPFT_BOOL }, + {"cancelAutoHolsterWhenEmpty", offsetof(WeaponFullDef, weapDef.cancelAutoHolsterWhenEmpty), CSPFT_BOOL }, + {"disableSwitchToWhenEmpty", offsetof(WeaponFullDef, weapDef.disableSwitchToWhenEmpty), CSPFT_BOOL }, + {"suppressAmmoReserveDisplay", offsetof(WeaponFullDef, weapDef.suppressAmmoReserveDisplay), CSPFT_BOOL }, + {"enhanced", offsetof(WeaponFullDef, weapCompleteDef.enhanced), CSPFT_BOOL }, + {"motionTracker", offsetof(WeaponFullDef, weapCompleteDef.motionTracker), CSPFT_BOOL }, + {"laserSightDuringNightvision", offsetof(WeaponFullDef, weapDef.laserSightDuringNightvision), CSPFT_BOOL }, + {"markableViewmodel", offsetof(WeaponFullDef, weapDef.markableViewmodel), CSPFT_BOOL }, + {"physCollmap", offsetof(WeaponFullDef, weapDef.physCollmap), CSPFT_PHYS_COLLMAP }, + {"noDualWield", offsetof(WeaponFullDef, weapDef.noDualWield), CSPFT_BOOL }, + {"dualWieldViewModelOffset", offsetof(WeaponFullDef, weapDef.dualWieldViewModelOffset), CSPFT_FLOAT }, + {"killIcon", offsetof(WeaponFullDef, weapCompleteDef.killIcon), CSPFT_MATERIAL }, + {"killIconRatio", offsetof(WeaponFullDef, weapDef.killIconRatio), WFT_ICONRATIO_KILL }, + {"flipKillIcon", offsetof(WeaponFullDef, weapDef.flipKillIcon), CSPFT_BOOL }, + {"dpadIcon", offsetof(WeaponFullDef, weapCompleteDef.dpadIcon), CSPFT_MATERIAL }, + {"dpadIconRatio", offsetof(WeaponFullDef, weapCompleteDef.dpadIconRatio), WFT_ICONRATIO_DPAD }, + {"dpadIconShowsAmmo", offsetof(WeaponFullDef, weapCompleteDef.dpadIconShowsAmmo), CSPFT_BOOL }, + {"noPartialReload", offsetof(WeaponFullDef, weapDef.bNoPartialReload), CSPFT_BOOL }, + {"segmentedReload", offsetof(WeaponFullDef, weapDef.bSegmentedReload), CSPFT_BOOL }, + {"reloadAmmoAdd", offsetof(WeaponFullDef, weapDef.iReloadAmmoAdd), CSPFT_INT }, + {"reloadStartAdd", offsetof(WeaponFullDef, weapDef.iReloadStartAdd), CSPFT_INT }, + {"altWeapon", offsetof(WeaponFullDef, weapCompleteDef.szAltWeaponName), CSPFT_STRING }, + {"dropAmmoMin", offsetof(WeaponFullDef, weapDef.ammoDropStockMin), CSPFT_INT }, + {"dropAmmoMax", offsetof(WeaponFullDef, weapCompleteDef.ammoDropStockMax), CSPFT_INT }, + {"ammoDropClipPercentMin", offsetof(WeaponFullDef, weapDef.ammoDropClipPercentMin), CSPFT_INT }, + {"ammoDropClipPercentMax", offsetof(WeaponFullDef, weapDef.ammoDropClipPercentMax), CSPFT_INT }, + {"blocksProne", offsetof(WeaponFullDef, weapDef.blocksProne), CSPFT_BOOL }, + {"silenced", offsetof(WeaponFullDef, weapDef.silenced), CSPFT_BOOL }, + {"isRollingGrenade", offsetof(WeaponFullDef, weapDef.isRollingGrenade), CSPFT_BOOL }, + {"explosionRadius", offsetof(WeaponFullDef, weapDef.iExplosionRadius), CSPFT_INT }, + {"explosionRadiusMin", offsetof(WeaponFullDef, weapDef.iExplosionRadiusMin), CSPFT_INT }, + {"explosionInnerDamage", offsetof(WeaponFullDef, weapDef.iExplosionInnerDamage), CSPFT_INT }, + {"explosionOuterDamage", offsetof(WeaponFullDef, weapDef.iExplosionOuterDamage), CSPFT_INT }, + {"damageConeAngle", offsetof(WeaponFullDef, weapDef.damageConeAngle), CSPFT_FLOAT }, + {"bulletExplDmgMult", offsetof(WeaponFullDef, weapDef.bulletExplDmgMult), CSPFT_FLOAT }, + {"bulletExplRadiusMult", offsetof(WeaponFullDef, weapDef.bulletExplRadiusMult), CSPFT_FLOAT }, + {"projectileSpeed", offsetof(WeaponFullDef, weapDef.iProjectileSpeed), CSPFT_INT }, + {"projectileSpeedUp", offsetof(WeaponFullDef, weapDef.iProjectileSpeedUp), CSPFT_INT }, + {"projectileSpeedForward", offsetof(WeaponFullDef, weapDef.iProjectileSpeedForward), CSPFT_INT }, + {"projectileActivateDist", offsetof(WeaponFullDef, weapDef.iProjectileActivateDist), CSPFT_INT }, + {"projectileLifetime", offsetof(WeaponFullDef, weapDef.projLifetime), CSPFT_FLOAT }, + {"timeToAccelerate", offsetof(WeaponFullDef, weapDef.timeToAccelerate), CSPFT_FLOAT }, + {"projectileCurvature", offsetof(WeaponFullDef, weapDef.projectileCurvature), CSPFT_FLOAT }, + {"projectileModel", offsetof(WeaponFullDef, weapDef.projectileModel), CSPFT_XMODEL }, + {"projExplosionType", offsetof(WeaponFullDef, weapDef.projExplosion), WFT_PROJ_EXPLOSION }, + {"projExplosionEffect", offsetof(WeaponFullDef, weapDef.projExplosionEffect), CSPFT_FX }, + {"projExplosionEffectForceNormalUp", offsetof(WeaponFullDef, weapDef.projExplosionEffectForceNormalUp), CSPFT_BOOL }, + {"projExplosionSound", offsetof(WeaponFullDef, weapDef.projExplosionSound), CSPFT_SOUND }, + {"projDudEffect", offsetof(WeaponFullDef, weapDef.projDudEffect), CSPFT_FX }, + {"projDudSound", offsetof(WeaponFullDef, weapDef.projDudSound), CSPFT_SOUND }, + {"projImpactExplode", offsetof(WeaponFullDef, weapDef.bProjImpactExplode), CSPFT_BOOL }, + {"stickiness", offsetof(WeaponFullDef, weapDef.stickiness), WFT_STICKINESS }, + {"stickToPlayers", offsetof(WeaponFullDef, weapDef.stickToPlayers), CSPFT_BOOL }, + {"hasDetonator", offsetof(WeaponFullDef, weapDef.hasDetonator), CSPFT_BOOL }, + {"disableFiring", offsetof(WeaponFullDef, weapDef.disableFiring), CSPFT_BOOL }, + {"timedDetonation", offsetof(WeaponFullDef, weapDef.timedDetonation), CSPFT_BOOL }, + {"rotate", offsetof(WeaponFullDef, weapDef.rotate), CSPFT_BOOL }, + {"holdButtonToThrow", offsetof(WeaponFullDef, weapDef.holdButtonToThrow), CSPFT_BOOL }, + {"freezeMovementWhenFiring", offsetof(WeaponFullDef, weapDef.freezeMovementWhenFiring), CSPFT_BOOL }, + {"lowAmmoWarningThreshold", offsetof(WeaponFullDef, weapDef.lowAmmoWarningThreshold), CSPFT_FLOAT }, + {"ricochetChance", offsetof(WeaponFullDef, weapDef.ricochetChance), CSPFT_FLOAT }, + {"offhandHoldIsCancelable", offsetof(WeaponFullDef, weapDef.offhandHoldIsCancelable), CSPFT_BOOL }, + {"parallelDefaultBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_DEFAULT]), CSPFT_FLOAT }, + {"parallelBarkBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_BARK]), CSPFT_FLOAT }, + {"parallelBrickBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_BRICK]), CSPFT_FLOAT }, + {"parallelCarpetBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_CARPET]), CSPFT_FLOAT }, + {"parallelClothBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_CLOTH]), CSPFT_FLOAT }, + {"parallelConcreteBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_CONCRETE]), CSPFT_FLOAT }, + {"parallelDirtBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_DIRT]), CSPFT_FLOAT }, + {"parallelFleshBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_FLESH]), CSPFT_FLOAT }, + {"parallelFoliageBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_FOLIAGE]), CSPFT_FLOAT }, + {"parallelGlassBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_GLASS]), CSPFT_FLOAT }, + {"parallelGrassBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_GRASS]), CSPFT_FLOAT }, + {"parallelGravelBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_GRAVEL]), CSPFT_FLOAT }, + {"parallelIceBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_ICE]), CSPFT_FLOAT }, + {"parallelMetalBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_METAL]), CSPFT_FLOAT }, + {"parallelMudBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_MUD]), CSPFT_FLOAT }, + {"parallelPaperBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_PAPER]), CSPFT_FLOAT }, + {"parallelPlasterBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_PLASTER]), CSPFT_FLOAT }, + {"parallelRockBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_ROCK]), CSPFT_FLOAT }, + {"parallelSandBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_SAND]), CSPFT_FLOAT }, + {"parallelSnowBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_SNOW]), CSPFT_FLOAT }, + {"parallelWaterBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_WATER]), CSPFT_FLOAT }, + {"parallelWoodBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_WOOD]), CSPFT_FLOAT }, + {"parallelAsphaltBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_ASPHALT]), CSPFT_FLOAT }, + {"parallelCeramicBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_CERAMIC]), CSPFT_FLOAT }, + {"parallelPlasticBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_PLASTIC]), CSPFT_FLOAT }, + {"parallelRubberBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_RUBBER]), CSPFT_FLOAT }, + {"parallelCushionBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_CUSHION]), CSPFT_FLOAT }, + {"parallelFruitBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_FRUIT]), CSPFT_FLOAT }, + {"parallelPaintedMetalBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_PAINTED_METAL]), CSPFT_FLOAT }, + {"parallelRiotShieldBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_RIOT_SHIELD]), CSPFT_FLOAT }, + {"parallelSlushBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_SLUSH]), CSPFT_FLOAT }, + {"perpendicularDefaultBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_DEFAULT]), CSPFT_FLOAT }, + {"perpendicularBarkBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_BARK]), CSPFT_FLOAT }, + {"perpendicularBrickBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_BRICK]), CSPFT_FLOAT }, + {"perpendicularCarpetBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_CARPET]), CSPFT_FLOAT }, + {"perpendicularClothBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_CLOTH]), CSPFT_FLOAT }, + {"perpendicularConcreteBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_CONCRETE]), CSPFT_FLOAT }, + {"perpendicularDirtBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_DIRT]), CSPFT_FLOAT }, + {"perpendicularFleshBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_FLESH]), CSPFT_FLOAT }, + {"perpendicularFoliageBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_FOLIAGE]), CSPFT_FLOAT }, + {"perpendicularGlassBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_GLASS]), CSPFT_FLOAT }, + {"perpendicularGrassBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_GRASS]), CSPFT_FLOAT }, + {"perpendicularGravelBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_GRAVEL]), CSPFT_FLOAT }, + {"perpendicularIceBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_ICE]), CSPFT_FLOAT }, + {"perpendicularMetalBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_METAL]), CSPFT_FLOAT }, + {"perpendicularMudBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_MUD]), CSPFT_FLOAT }, + {"perpendicularPaperBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_PAPER]), CSPFT_FLOAT }, + {"perpendicularPlasterBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_PLASTER]), CSPFT_FLOAT }, + {"perpendicularRockBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_ROCK]), CSPFT_FLOAT }, + {"perpendicularSandBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_SAND]), CSPFT_FLOAT }, + {"perpendicularSnowBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_SNOW]), CSPFT_FLOAT }, + {"perpendicularWaterBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_WATER]), CSPFT_FLOAT }, + {"perpendicularWoodBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_WOOD]), CSPFT_FLOAT }, + {"perpendicularAsphaltBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_ASPHALT]), CSPFT_FLOAT }, + {"perpendicularCeramicBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_CERAMIC]), CSPFT_FLOAT }, + {"perpendicularPlasticBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_PLASTIC]), CSPFT_FLOAT }, + {"perpendicularRubberBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_RUBBER]), CSPFT_FLOAT }, + {"perpendicularCushionBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_CUSHION]), CSPFT_FLOAT }, + {"perpendicularFruitBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_FRUIT]), CSPFT_FLOAT }, + {"perpendicularPaintedMetalBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_PAINTED_METAL]), CSPFT_FLOAT }, + {"perpendicularRiotShieldBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_RIOT_SHIELD]), CSPFT_FLOAT }, + {"perpendicularSlushBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_SLUSH]), CSPFT_FLOAT }, + {"projTrailEffect", offsetof(WeaponFullDef, weapDef.projTrailEffect), CSPFT_FX }, + {"projBeaconEffect", offsetof(WeaponFullDef, weapDef.projBeaconEffect), CSPFT_FX }, + {"projectileRed", offsetof(WeaponFullDef, weapDef.vProjectileColor[0]), CSPFT_FLOAT }, + {"projectileGreen", offsetof(WeaponFullDef, weapDef.vProjectileColor[1]), CSPFT_FLOAT }, + {"projectileBlue", offsetof(WeaponFullDef, weapDef.vProjectileColor[2]), CSPFT_FLOAT }, + {"guidedMissileType", offsetof(WeaponFullDef, weapDef.guidedMissileType), WFT_GUIDED_MISSILE_TYPE }, + {"maxSteeringAccel", offsetof(WeaponFullDef, weapDef.maxSteeringAccel), CSPFT_FLOAT }, + {"projIgnitionDelay", offsetof(WeaponFullDef, weapDef.projIgnitionDelay), CSPFT_INT }, + {"projIgnitionEffect", offsetof(WeaponFullDef, weapDef.projIgnitionEffect), CSPFT_FX }, + {"projIgnitionSound", offsetof(WeaponFullDef, weapDef.projIgnitionSound), CSPFT_SOUND }, + {"adsTransInTime", offsetof(WeaponFullDef, weapCompleteDef.iAdsTransInTime), CSPFT_MILLISECONDS }, + {"adsTransOutTime", offsetof(WeaponFullDef, weapCompleteDef.iAdsTransOutTime), CSPFT_MILLISECONDS }, + {"adsIdleAmount", offsetof(WeaponFullDef, weapDef.fAdsIdleAmount), CSPFT_FLOAT }, + {"adsIdleSpeed", offsetof(WeaponFullDef, weapDef.adsIdleSpeed), CSPFT_FLOAT }, + {"adsZoomFov", offsetof(WeaponFullDef, weapCompleteDef.fAdsZoomFov), CSPFT_FLOAT }, + {"adsZoomInFrac", offsetof(WeaponFullDef, weapDef.fAdsZoomInFrac), CSPFT_FLOAT }, + {"adsZoomOutFrac", offsetof(WeaponFullDef, weapDef.fAdsZoomOutFrac), CSPFT_FLOAT }, + {"adsOverlayShader", offsetof(WeaponFullDef, weapDef.overlay.shader), CSPFT_MATERIAL }, + {"adsOverlayShaderLowRes", offsetof(WeaponFullDef, weapDef.overlay.shaderLowRes), CSPFT_MATERIAL }, + {"adsOverlayShaderEMP", offsetof(WeaponFullDef, weapDef.overlay.shaderEMP), CSPFT_MATERIAL }, + {"adsOverlayShaderEMPLowRes", offsetof(WeaponFullDef, weapDef.overlay.shaderEMPLowRes), CSPFT_MATERIAL }, + {"adsOverlayReticle", offsetof(WeaponFullDef, weapDef.overlay.reticle), WFT_OVERLAYRETICLE }, + {"adsOverlayInterface", offsetof(WeaponFullDef, weapDef.overlayInterface), WFT_OVERLAYINTERFACE }, + {"adsOverlayWidth", offsetof(WeaponFullDef, weapDef.overlay.width), CSPFT_FLOAT }, + {"adsOverlayHeight", offsetof(WeaponFullDef, weapDef.overlay.height), CSPFT_FLOAT }, + {"adsOverlayWidthSplitscreen", offsetof(WeaponFullDef, weapDef.overlay.widthSplitscreen), CSPFT_FLOAT }, + {"adsOverlayHeightSplitscreen", offsetof(WeaponFullDef, weapDef.overlay.heightSplitscreen), CSPFT_FLOAT }, + {"adsBobFactor", offsetof(WeaponFullDef, weapDef.fAdsBobFactor), CSPFT_FLOAT }, + {"adsViewBobMult", offsetof(WeaponFullDef, weapDef.fAdsViewBobMult), CSPFT_FLOAT }, + {"adsAimPitch", offsetof(WeaponFullDef, weapDef.fAdsAimPitch), CSPFT_FLOAT }, + {"adsCrosshairInFrac", offsetof(WeaponFullDef, weapDef.fAdsCrosshairInFrac), CSPFT_FLOAT }, + {"adsCrosshairOutFrac", offsetof(WeaponFullDef, weapDef.fAdsCrosshairOutFrac), CSPFT_FLOAT }, + {"adsReloadTransTime", offsetof(WeaponFullDef, weapDef.iPositionReloadTransTime), CSPFT_MILLISECONDS }, + {"adsGunKickReducedKickBullets", offsetof(WeaponFullDef, weapDef.adsGunKickReducedKickBullets), CSPFT_INT }, + {"adsGunKickReducedKickPercent", offsetof(WeaponFullDef, weapDef.adsGunKickReducedKickPercent), CSPFT_FLOAT }, + {"adsGunKickPitchMin", offsetof(WeaponFullDef, weapDef.fAdsGunKickPitchMin), CSPFT_FLOAT }, + {"adsGunKickPitchMax", offsetof(WeaponFullDef, weapDef.fAdsGunKickPitchMax), CSPFT_FLOAT }, + {"adsGunKickYawMin", offsetof(WeaponFullDef, weapDef.fAdsGunKickYawMin), CSPFT_FLOAT }, + {"adsGunKickYawMax", offsetof(WeaponFullDef, weapDef.fAdsGunKickYawMax), CSPFT_FLOAT }, + {"adsGunKickAccel", offsetof(WeaponFullDef, weapDef.fAdsGunKickAccel), CSPFT_FLOAT }, + {"adsGunKickSpeedMax", offsetof(WeaponFullDef, weapDef.fAdsGunKickSpeedMax), CSPFT_FLOAT }, + {"adsGunKickSpeedDecay", offsetof(WeaponFullDef, weapDef.fAdsGunKickSpeedDecay), CSPFT_FLOAT }, + {"adsGunKickStaticDecay", offsetof(WeaponFullDef, weapDef.fAdsGunKickStaticDecay), CSPFT_FLOAT }, + {"adsViewKickPitchMin", offsetof(WeaponFullDef, weapDef.fAdsViewKickPitchMin), CSPFT_FLOAT }, + {"adsViewKickPitchMax", offsetof(WeaponFullDef, weapDef.fAdsViewKickPitchMax), CSPFT_FLOAT }, + {"adsViewKickYawMin", offsetof(WeaponFullDef, weapDef.fAdsViewKickYawMin), CSPFT_FLOAT }, + {"adsViewKickYawMax", offsetof(WeaponFullDef, weapDef.fAdsViewKickYawMax), CSPFT_FLOAT }, + {"adsViewKickCenterSpeed", offsetof(WeaponFullDef, weapCompleteDef.fAdsViewKickCenterSpeed), CSPFT_FLOAT }, + {"adsSpread", offsetof(WeaponFullDef, weapDef.fAdsSpread), CSPFT_FLOAT }, + {"guidedMissileType", offsetof(WeaponFullDef, weapDef.guidedMissileType), WFT_GUIDED_MISSILE_TYPE }, + {"hipSpreadStandMin", offsetof(WeaponFullDef, weapDef.fHipSpreadStandMin), CSPFT_FLOAT }, + {"hipSpreadDuckedMin", offsetof(WeaponFullDef, weapDef.fHipSpreadDuckedMin), CSPFT_FLOAT }, + {"hipSpreadProneMin", offsetof(WeaponFullDef, weapDef.fHipSpreadProneMin), CSPFT_FLOAT }, + {"hipSpreadMax", offsetof(WeaponFullDef, weapDef.hipSpreadStandMax), CSPFT_FLOAT }, + {"hipSpreadDuckedMax", offsetof(WeaponFullDef, weapDef.hipSpreadDuckedMax), CSPFT_FLOAT }, + {"hipSpreadProneMax", offsetof(WeaponFullDef, weapDef.hipSpreadProneMax), CSPFT_FLOAT }, + {"hipSpreadDecayRate", offsetof(WeaponFullDef, weapDef.fHipSpreadDecayRate), CSPFT_FLOAT }, + {"hipSpreadFireAdd", offsetof(WeaponFullDef, weapDef.fHipSpreadFireAdd), CSPFT_FLOAT }, + {"hipSpreadTurnAdd", offsetof(WeaponFullDef, weapDef.fHipSpreadTurnAdd), CSPFT_FLOAT }, + {"hipSpreadMoveAdd", offsetof(WeaponFullDef, weapDef.fHipSpreadMoveAdd), CSPFT_FLOAT }, + {"hipSpreadDuckedDecay", offsetof(WeaponFullDef, weapDef.fHipSpreadDuckedDecay), CSPFT_FLOAT }, + {"hipSpreadProneDecay", offsetof(WeaponFullDef, weapDef.fHipSpreadProneDecay), CSPFT_FLOAT }, + {"hipReticleSidePos", offsetof(WeaponFullDef, weapDef.fHipReticleSidePos), CSPFT_FLOAT }, + {"hipIdleAmount", offsetof(WeaponFullDef, weapDef.fHipIdleAmount), CSPFT_FLOAT }, + {"hipIdleSpeed", offsetof(WeaponFullDef, weapDef.hipIdleSpeed), CSPFT_FLOAT }, + {"hipGunKickReducedKickBullets", offsetof(WeaponFullDef, weapDef.hipGunKickReducedKickBullets), CSPFT_INT }, + {"hipGunKickReducedKickPercent", offsetof(WeaponFullDef, weapDef.hipGunKickReducedKickPercent), CSPFT_FLOAT }, + {"hipGunKickPitchMin", offsetof(WeaponFullDef, weapDef.fHipGunKickPitchMin), CSPFT_FLOAT }, + {"hipGunKickPitchMax", offsetof(WeaponFullDef, weapDef.fHipGunKickPitchMax), CSPFT_FLOAT }, + {"hipGunKickYawMin", offsetof(WeaponFullDef, weapDef.fHipGunKickYawMin), CSPFT_FLOAT }, + {"hipGunKickYawMax", offsetof(WeaponFullDef, weapDef.fHipGunKickYawMax), CSPFT_FLOAT }, + {"hipGunKickAccel", offsetof(WeaponFullDef, weapDef.fHipGunKickAccel), CSPFT_FLOAT }, + {"hipGunKickSpeedMax", offsetof(WeaponFullDef, weapDef.fHipGunKickSpeedMax), CSPFT_FLOAT }, + {"hipGunKickSpeedDecay", offsetof(WeaponFullDef, weapDef.fHipGunKickSpeedDecay), CSPFT_FLOAT }, + {"hipGunKickStaticDecay", offsetof(WeaponFullDef, weapDef.fHipGunKickStaticDecay), CSPFT_FLOAT }, + {"hipViewKickPitchMin", offsetof(WeaponFullDef, weapDef.fHipViewKickPitchMin), CSPFT_FLOAT }, + {"hipViewKickPitchMax", offsetof(WeaponFullDef, weapDef.fHipViewKickPitchMax), CSPFT_FLOAT }, + {"hipViewKickYawMin", offsetof(WeaponFullDef, weapDef.fHipViewKickYawMin), CSPFT_FLOAT }, + {"hipViewKickYawMax", offsetof(WeaponFullDef, weapDef.fHipViewKickYawMax), CSPFT_FLOAT }, + {"hipViewKickCenterSpeed", offsetof(WeaponFullDef, weapCompleteDef.fHipViewKickCenterSpeed), CSPFT_FLOAT }, + {"leftArc", offsetof(WeaponFullDef, weapDef.leftArc), CSPFT_FLOAT }, + {"rightArc", offsetof(WeaponFullDef, weapDef.rightArc), CSPFT_FLOAT }, + {"topArc", offsetof(WeaponFullDef, weapDef.topArc), CSPFT_FLOAT }, + {"bottomArc", offsetof(WeaponFullDef, weapDef.bottomArc), CSPFT_FLOAT }, + {"accuracy", offsetof(WeaponFullDef, weapDef.accuracy), CSPFT_FLOAT }, + {"aiSpread", offsetof(WeaponFullDef, weapDef.aiSpread), CSPFT_FLOAT }, + {"playerSpread", offsetof(WeaponFullDef, weapDef.playerSpread), CSPFT_FLOAT }, + {"maxVertTurnSpeed", offsetof(WeaponFullDef, weapDef.maxTurnSpeed[0]), CSPFT_FLOAT }, + {"maxHorTurnSpeed", offsetof(WeaponFullDef, weapDef.maxTurnSpeed[1]), CSPFT_FLOAT }, + {"minVertTurnSpeed", offsetof(WeaponFullDef, weapDef.minTurnSpeed[0]), CSPFT_FLOAT }, + {"minHorTurnSpeed", offsetof(WeaponFullDef, weapDef.minTurnSpeed[1]), CSPFT_FLOAT }, + {"pitchConvergenceTime", offsetof(WeaponFullDef, weapDef.pitchConvergenceTime), CSPFT_FLOAT }, + {"yawConvergenceTime", offsetof(WeaponFullDef, weapDef.yawConvergenceTime), CSPFT_FLOAT }, + {"suppressionTime", offsetof(WeaponFullDef, weapDef.suppressTime), CSPFT_FLOAT }, + {"maxRange", offsetof(WeaponFullDef, weapDef.maxRange), CSPFT_FLOAT }, + {"animHorRotateInc", offsetof(WeaponFullDef, weapDef.fAnimHorRotateInc), CSPFT_FLOAT }, + {"playerPositionDist", offsetof(WeaponFullDef, weapDef.fPlayerPositionDist), CSPFT_FLOAT }, + {"stance", offsetof(WeaponFullDef, weapDef.stance), WFT_STANCE }, + {"useHintString", offsetof(WeaponFullDef, weapDef.szUseHintString), CSPFT_STRING }, + {"dropHintString", offsetof(WeaponFullDef, weapDef.dropHintString), CSPFT_STRING }, + {"horizViewJitter", offsetof(WeaponFullDef, weapDef.horizViewJitter), CSPFT_FLOAT }, + {"vertViewJitter", offsetof(WeaponFullDef, weapDef.vertViewJitter), CSPFT_FLOAT }, + {"scanSpeed", offsetof(WeaponFullDef, weapDef.scanSpeed), CSPFT_FLOAT }, + {"scanAccel", offsetof(WeaponFullDef, weapDef.scanAccel), CSPFT_FLOAT }, + {"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 }, + {"locNone", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_NONE]), CSPFT_FLOAT }, + {"locHelmet", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_HELMET]), CSPFT_FLOAT }, + {"locHead", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_HEAD]), CSPFT_FLOAT }, + {"locNeck", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_NECK]), CSPFT_FLOAT }, + {"locTorsoUpper", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_TORSO_UPR]), CSPFT_FLOAT }, + {"locTorsoLower", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_TORSO_LWR]), CSPFT_FLOAT }, + {"locRightArmUpper", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_ARM_UPR]), CSPFT_FLOAT }, + {"locRightArmLower", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_ARM_LWR]), CSPFT_FLOAT }, + {"locRightHand", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_HAND]), CSPFT_FLOAT }, + {"locLeftArmUpper", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_ARM_UPR]), CSPFT_FLOAT }, + {"locLeftArmLower", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_ARM_LWR]), CSPFT_FLOAT }, + {"locLeftHand", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_HAND]), CSPFT_FLOAT }, + {"locRightLegUpper", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_LEG_UPR]), CSPFT_FLOAT }, + {"locRightLegLower", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_LEG_LWR]), CSPFT_FLOAT }, + {"locRightFoot", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_FOOT]), CSPFT_FLOAT }, + {"locLeftLegUpper", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_LEG_UPR]), CSPFT_FLOAT }, + {"locLeftLegLower", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_LEG_LWR]), CSPFT_FLOAT }, + {"locLeftFoot", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_FOOT]), CSPFT_FLOAT }, + {"locGun", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_GUN]), CSPFT_FLOAT }, + {"fireRumble", offsetof(WeaponFullDef, weapDef.fireRumble), CSPFT_STRING }, + {"meleeImpactRumble", offsetof(WeaponFullDef, weapDef.meleeImpactRumble), CSPFT_STRING }, + {"tracerType", offsetof(WeaponFullDef, weapDef.tracerType), CSPFT_TRACER }, + {"adsDofStart", offsetof(WeaponFullDef, weapCompleteDef.adsDofStart), CSPFT_FLOAT }, + {"adsDofEnd", offsetof(WeaponFullDef, weapCompleteDef.adsDofEnd), CSPFT_FLOAT }, + {"turretScopeZoomRate", offsetof(WeaponFullDef, weapDef.turretScopeZoomRate), CSPFT_FLOAT }, + {"turretScopeZoomMin", offsetof(WeaponFullDef, weapDef.turretScopeZoomMin), CSPFT_FLOAT }, + {"turretScopeZoomMax", offsetof(WeaponFullDef, weapDef.turretScopeZoomMax), CSPFT_FLOAT }, + {"thermalScope", offsetof(WeaponFullDef, weapDef.thermalScope), CSPFT_BOOL }, + {"altModeSameWeapon", offsetof(WeaponFullDef, weapDef.altModeSameWeapon), CSPFT_BOOL }, + {"turretOverheatUpRate", offsetof(WeaponFullDef, weapDef.turretOverheatUpRate), CSPFT_FLOAT }, + {"turretOverheatDownRate", offsetof(WeaponFullDef, weapDef.turretOverheatDownRate), CSPFT_FLOAT }, + {"turretOverheatPenalty", offsetof(WeaponFullDef, weapDef.turretOverheatPenalty), CSPFT_FLOAT }, + {"turretOverheatSound", offsetof(WeaponFullDef, weapDef.turretOverheatSound), CSPFT_SOUND }, + {"turretOverheatEffect", offsetof(WeaponFullDef, weapDef.turretOverheatEffect), CSPFT_FX }, + {"turretBarrelSpinEnabled", offsetof(WeaponFullDef, weapDef.turretBarrelSpinEnabled), CSPFT_BOOL }, + {"turretBarrelSpinUpTime", offsetof(WeaponFullDef, weapDef.turretBarrelSpinUpTime), CSPFT_FLOAT }, + {"turretBarrelSpinDownTime", offsetof(WeaponFullDef, weapDef.turretBarrelSpinDownTime), CSPFT_FLOAT }, + {"turretBarrelSpinRumble", offsetof(WeaponFullDef, weapDef.turretBarrelSpinRumble), CSPFT_STRING }, + {"turretBarrelSpinSpeed", offsetof(WeaponFullDef, weapDef.turretBarrelSpinSpeed), CSPFT_FLOAT }, + {"turretBarrelSpinMaxSnd", offsetof(WeaponFullDef, weapDef.turretBarrelSpinMaxSnd), CSPFT_SOUND }, + {"turretBarrelSpinUpSnd1", offsetof(WeaponFullDef, weapDef.turretBarrelSpinUpSnd[0]), CSPFT_SOUND }, + {"turretBarrelSpinUpSnd2", offsetof(WeaponFullDef, weapDef.turretBarrelSpinUpSnd[1]), CSPFT_SOUND }, + {"turretBarrelSpinUpSnd3", offsetof(WeaponFullDef, weapDef.turretBarrelSpinUpSnd[2]), CSPFT_SOUND }, + {"turretBarrelSpinUpSnd4", offsetof(WeaponFullDef, weapDef.turretBarrelSpinUpSnd[3]), CSPFT_SOUND }, + {"turretBarrelSpinDownSnd1", offsetof(WeaponFullDef, weapDef.turretBarrelSpinDownSnd[0]), CSPFT_SOUND }, + {"turretBarrelSpinDownSnd2", offsetof(WeaponFullDef, weapDef.turretBarrelSpinDownSnd[1]), CSPFT_SOUND }, + {"turretBarrelSpinDownSnd3", offsetof(WeaponFullDef, weapDef.turretBarrelSpinDownSnd[2]), CSPFT_SOUND }, + {"turretBarrelSpinDownSnd4", offsetof(WeaponFullDef, weapDef.turretBarrelSpinDownSnd[3]), CSPFT_SOUND }, + {"missileConeSoundEnabled", offsetof(WeaponFullDef, weapDef.missileConeSoundEnabled), CSPFT_BOOL }, + {"missileConeSoundAlias", offsetof(WeaponFullDef, weapDef.missileConeSoundAlias), CSPFT_SOUND }, + {"missileConeSoundAliasAtBase", offsetof(WeaponFullDef, weapDef.missileConeSoundAliasAtBase), CSPFT_SOUND }, + {"missileConeSoundRadiusAtTop", offsetof(WeaponFullDef, weapDef.missileConeSoundRadiusAtTop), CSPFT_FLOAT }, + {"missileConeSoundRadiusAtBase", offsetof(WeaponFullDef, weapDef.missileConeSoundRadiusAtBase), CSPFT_FLOAT }, + {"missileConeSoundHeight", offsetof(WeaponFullDef, weapDef.missileConeSoundHeight), CSPFT_FLOAT }, + {"missileConeSoundOriginOffset", offsetof(WeaponFullDef, weapDef.missileConeSoundOriginOffset), CSPFT_FLOAT }, + {"missileConeSoundVolumescaleAtCore", offsetof(WeaponFullDef, weapDef.missileConeSoundVolumescaleAtCore), CSPFT_FLOAT }, + {"missileConeSoundVolumescaleAtEdge", offsetof(WeaponFullDef, weapDef.missileConeSoundVolumescaleAtEdge), CSPFT_FLOAT }, + {"missileConeSoundVolumescaleCoreSize", offsetof(WeaponFullDef, weapDef.missileConeSoundVolumescaleCoreSize), CSPFT_FLOAT }, + {"missileConeSoundPitchshiftEnabled", offsetof(WeaponFullDef, weapDef.missileConeSoundPitchshiftEnabled), CSPFT_BOOL }, + {"missileConeSoundPitchAtTop", offsetof(WeaponFullDef, weapDef.missileConeSoundPitchAtTop), CSPFT_FLOAT }, + {"missileConeSoundPitchAtBottom", offsetof(WeaponFullDef, weapDef.missileConeSoundPitchAtBottom), CSPFT_FLOAT }, + {"missileConeSoundPitchTopSize", offsetof(WeaponFullDef, weapDef.missileConeSoundPitchTopSize), CSPFT_FLOAT }, + {"missileConeSoundPitchBottomSize", offsetof(WeaponFullDef, weapDef.missileConeSoundPitchBottomSize), CSPFT_FLOAT }, + {"missileConeSoundCrossfadeEnabled", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeEnabled), CSPFT_BOOL }, + {"missileConeSoundCrossfadeTopSize", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeTopSize), CSPFT_FLOAT }, + {"missileConeSoundCrossfadeBottomSize", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeBottomSize), CSPFT_FLOAT }, + }; + + inline const char* szWeapTypeNames[]{ + "none", + "bullet", + "grenade", + "projectile", + "riotshield", + }; + + inline const char* szWeapClassNames[]{ + "rifle", + "sniper", + "mg", + "smg", + "spread", + "pistol", + "grenade", + "rocketlauncher", + "turret", + "throwingknife", + "non-player", + "item", + }; + + inline const char* szWeapOverlayReticleNames[]{ + "none", + "crosshair", + }; + + inline const char* szWeapInventoryTypeNames[]{ + "primary", + "offhand", + "item", + "altmode", + "exclusive", + "scavenger", + }; + + inline const char* szWeapFireTypeNames[]{ + "Full Auto", + "Single Shot", + "2-Round Burst", + "3-Round Burst", + "4-Round Burst", + "Double Barrel", + }; + + inline const char* penetrateTypeNames[]{ + "none", + "small", + "medium", + "large", + }; + + inline const char* impactTypeNames[]{ + "none", + "bullet_small", + "bullet_large", + "bullet_ap", + "bullet_explode", + "shotgun", + "shotgun_explode", + "grenade_bounce", + "grenade_explode", + "rocket_explode", + "projectile_dud", + }; + + inline const char* szWeapStanceNames[]{ + "stand", + "duck", + "prone", + }; + + inline const char* szProjectileExplosionNames[]{ + "grenade", + "rocket", + "flashbang", + "none", + "dud", + "smoke", + "heavy explosive", + }; + + inline const char* offhandClassNames[]{ + "None", + "Frag Grenade", + "Smoke Grenade", + "Flash Grenade", + "Throwing Knife", + "Other", + }; + + inline const char* playerAnimTypeNames[]{ + "none", + "other", + "pistol", + "smg", + "autorifle", + "mg", + "sniper", + "rocketlauncher", + "explosive", + "grenade", + "turret", + "c4", + "m203", + "hold", + "briefcase", + "riotshield", + "laptop", + "throwingknife", + }; + + inline const char* activeReticleNames[]{ + "None", + "Pip-On-A-Stick", + "Bouncing diamond", + }; + + inline const char* guidedMissileNames[]{ + "None", + "Sidewinder", + "Hellfire", + "Javelin", + }; + + inline const char* stickinessNames[]{ + "Don't stick", + "Stick to all", + "Stick to all, orient to surface", + "Stick to ground", + "Stick to ground, maintain yaw", + "Knife", + }; + + inline const char* overlayInterfaceNames[]{ + "None", + "Javelin", + "Turret Scope", + }; + + inline const char* ammoCounterClipNames[]{ + "None", + "Magazine", + "ShortMagazine", + "Shotgun", + "Rocket", + "Beltfed", + "AltWeapon", + }; + + inline const char* weapIconRatioNames[]{ + "1:1", + "2:1", + "4:1", + }; + + inline const char* s_vehicleClassNames[]{ + "4 wheel", + "tank", + "plane", + "boat", + "artillery", + "helicopter", + "snowmobile", + }; + + inline const char* s_vehicleAxleTypeNames[]{ + "front", + "rear", + "all", + }; + + inline const char* bounceSoundSuffixes[]{ + "_default", "_bark", "_brick", "_carpet", "_cloth", "_concrete", "_dirt", "_flesh", "_foliage", "_glass", "_grass", + "_gravel", "_ice", "_metal", "_mud", "_paper", "_plaster", "_rock", "_sand", "_snow", "_water", "_wood", + "_asphalt", "_ceramic", "_plastic", "_rubber", "_cushion", "_fruit", "_painted_metal", "_riot_shield", "_slush", + }; +} // namespace IW5 diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp new file mode 100644 index 00000000..243e645e --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp @@ -0,0 +1,383 @@ +#include "AssetDumperWeapon.h" + +#include "Game/IW5/CommonIW5.h" +#include "Game/IW5/InfoString/InfoStringFromStructConverter.h" +#include "Game/IW5/InfoString/WeaponFields.h" +#include "Game/IW5/ObjConstantsIW5.h" + +#include +#include +#include +#include + +using namespace IW5; + +namespace IW5 +{ + class InfoStringFromWeaponConverter final : public InfoStringFromStructConverter + { + protected: + void FillFromExtensionField(const cspField_t& field) override + { + switch (static_cast(field.iFieldType)) + { + case WFT_WEAPONTYPE: + FillFromEnumInt(std::string(field.szName), field.iOffset, szWeapTypeNames, std::extent_v); + break; + + case WFT_WEAPONCLASS: + FillFromEnumInt(std::string(field.szName), field.iOffset, szWeapClassNames, std::extent_v); + break; + + case WFT_OVERLAYRETICLE: + FillFromEnumInt(std::string(field.szName), field.iOffset, szWeapOverlayReticleNames, std::extent_v); + break; + + case WFT_PENETRATE_TYPE: + FillFromEnumInt(std::string(field.szName), field.iOffset, penetrateTypeNames, std::extent_v); + break; + + case WFT_IMPACT_TYPE: + FillFromEnumInt(std::string(field.szName), field.iOffset, impactTypeNames, std::extent_v); + break; + + case WFT_STANCE: + FillFromEnumInt(std::string(field.szName), field.iOffset, szWeapStanceNames, std::extent_v); + break; + + case WFT_PROJ_EXPLOSION: + FillFromEnumInt(std::string(field.szName), field.iOffset, szProjectileExplosionNames, std::extent_v); + break; + + case WFT_OFFHAND_CLASS: + FillFromEnumInt(std::string(field.szName), field.iOffset, offhandClassNames, std::extent_v); + break; + + case WFT_ANIMTYPE: + FillFromEnumInt(std::string(field.szName), field.iOffset, playerAnimTypeNames, std::extent_v); + break; + + case WFT_ACTIVE_RETICLE_TYPE: + FillFromEnumInt(std::string(field.szName), field.iOffset, activeReticleNames, std::extent_v); + break; + + case WFT_GUIDED_MISSILE_TYPE: + FillFromEnumInt(std::string(field.szName), field.iOffset, guidedMissileNames, std::extent_v); + break; + + case WFT_BOUNCE_SOUND: + { + const auto* bounceSound = *reinterpret_cast(reinterpret_cast(m_structure) + field.iOffset); + + if (bounceSound && bounceSound->name) + { + const std::string firstBounceSound(bounceSound->name->soundName); + const auto endOfBouncePrefix = firstBounceSound.rfind("_default"); + assert(endOfBouncePrefix != std::string::npos); + + if (endOfBouncePrefix != std::string::npos) + { + m_info_string.SetValueForKey(std::string(field.szName), firstBounceSound.substr(0, endOfBouncePrefix)); + } + else + m_info_string.SetValueForKey(std::string(field.szName), ""); + } + else + m_info_string.SetValueForKey(std::string(field.szName), ""); + + break; + } + + case WFT_STICKINESS: + FillFromEnumInt(std::string(field.szName), field.iOffset, stickinessNames, std::extent_v); + break; + + case WFT_OVERLAYINTERFACE: + FillFromEnumInt(std::string(field.szName), field.iOffset, overlayInterfaceNames, std::extent_v); + break; + + case WFT_INVENTORYTYPE: + FillFromEnumInt(std::string(field.szName), field.iOffset, szWeapInventoryTypeNames, std::extent_v); + break; + + case WFT_FIRETYPE: + FillFromEnumInt(std::string(field.szName), field.iOffset, szWeapFireTypeNames, std::extent_v); + break; + + case WFT_AMMOCOUNTER_CLIPTYPE: + FillFromEnumInt(std::string(field.szName), field.iOffset, ammoCounterClipNames, std::extent_v); + break; + + case WFT_ICONRATIO_HUD: + case WFT_ICONRATIO_PICKUP: + case WFT_ICONRATIO_AMMOCOUNTER: + case WFT_ICONRATIO_KILL: + case WFT_ICONRATIO_DPAD: + FillFromEnumInt(std::string(field.szName), field.iOffset, weapIconRatioNames, std::extent_v); + break; + + case WFT_HIDETAGS: + { + const auto* hideTags = reinterpret_cast(reinterpret_cast(m_structure) + field.iOffset); + std::stringstream ss; + bool first = true; + + for (auto i = 0u; i < std::extent_v; i++) + { + const auto& str = m_get_scr_string(hideTags[i]); + if (!str.empty()) + { + if (!first) + ss << "\n"; + else + first = false; + + ss << str; + } + } + + m_info_string.SetValueForKey(std::string(field.szName), ss.str()); + break; + } + + case WFT_NOTETRACKSOUNDMAP: + { + const auto* keys = reinterpret_cast(reinterpret_cast(m_structure) + field.iOffset); + const auto* values = &keys[std::extent_v]; + std::stringstream ss; + bool first = true; + + for (auto i = 0u; i < std::extent_v; i++) + { + const auto& key = m_get_scr_string(keys[i]); + const auto& value = m_get_scr_string(values[i]); + if (!key.empty()) + { + if (!first) + ss << "\n"; + else + first = false; + + ss << key; + + if (!value.empty()) + ss << " " << value; + } + } + + m_info_string.SetValueForKey(std::string(field.szName), ss.str()); + break; + } + + case WFT_NOTETRACKRUMBLEMAP: + { + const auto* keys = reinterpret_cast(reinterpret_cast(m_structure) + field.iOffset); + const auto* values = &keys[std::extent_v]; + std::stringstream ss; + bool first = true; + + for (auto i = 0u; i < std::extent_v; i++) + { + const auto& key = m_get_scr_string(keys[i]); + const auto& value = m_get_scr_string(values[i]); + if (!key.empty()) + { + if (!first) + ss << "\n"; + else + first = false; + + ss << key; + + if (!value.empty()) + ss << " " << value; + } + } + + m_info_string.SetValueForKey(std::string(field.szName), ss.str()); + break; + } + + case WFT_ANIM_NAME: + FillFromString(std::string(field.szName), field.iOffset); + break; + + case WFT_NUM_FIELD_TYPES: + default: + assert(false); + break; + } + } + + public: + InfoStringFromWeaponConverter(const WeaponFullDef* structure, + const cspField_t* fields, + const size_t fieldCount, + std::function scriptStringValueCallback) + : InfoStringFromStructConverter(structure, fields, fieldCount, std::move(scriptStringValueCallback)) + { + } + }; +} // namespace IW5 + +void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFullDef* fullDef) +{ + fullDef->weapCompleteDef = *weapon; + + if (weapon->weapDef) + { + fullDef->weapDef = *weapon->weapDef; + fullDef->weapCompleteDef.weapDef = &fullDef->weapDef; + } + + if (weapon->hideTags) + { + assert(sizeof(WeaponFullDef::hideTags) >= sizeof(scr_string_t) * std::extent_v); + memcpy(fullDef->hideTags, weapon->hideTags, sizeof(scr_string_t) * std::extent_v); + fullDef->weapCompleteDef.hideTags = fullDef->hideTags; + } + + if (weapon->szXAnims) + { + assert(sizeof(WeaponFullDef::szXAnims) >= sizeof(void*) * NUM_WEAP_ANIMS); + memcpy(fullDef->szXAnims, weapon->szXAnims, sizeof(void*) * NUM_WEAP_ANIMS); + fullDef->weapCompleteDef.szXAnims = fullDef->szXAnims; + } + + if (fullDef->weapDef.gunXModel) + { + assert(sizeof(WeaponFullDef::gunXModel) >= sizeof(void*) * std::extent_v); + memcpy(fullDef->gunXModel, fullDef->weapDef.gunXModel, sizeof(void*) * std::extent_v); + fullDef->weapDef.gunXModel = fullDef->gunXModel; + } + + if (fullDef->weapDef.szXAnimsRightHanded) + { + assert(sizeof(WeaponFullDef::szXAnimsRightHanded) >= sizeof(void*) * NUM_WEAP_ANIMS); + memcpy(fullDef->szXAnimsRightHanded, fullDef->weapDef.szXAnimsRightHanded, sizeof(void*) * NUM_WEAP_ANIMS); + fullDef->weapDef.szXAnimsRightHanded = fullDef->szXAnimsRightHanded; + } + + if (fullDef->weapDef.szXAnimsLeftHanded) + { + assert(sizeof(WeaponFullDef::szXAnimsLeftHanded) >= sizeof(void*) * NUM_WEAP_ANIMS); + memcpy(fullDef->szXAnimsLeftHanded, fullDef->weapDef.szXAnimsLeftHanded, sizeof(void*) * NUM_WEAP_ANIMS); + fullDef->weapDef.szXAnimsLeftHanded = fullDef->szXAnimsLeftHanded; + } + + if (fullDef->weapDef.notetrackSoundMapKeys) + { + assert(sizeof(WeaponFullDef::notetrackSoundMapKeys) >= sizeof(scr_string_t) * std::extent_v); + memcpy(fullDef->notetrackSoundMapKeys, + fullDef->weapDef.notetrackSoundMapKeys, + sizeof(scr_string_t) * std::extent_v); + fullDef->weapDef.notetrackSoundMapKeys = fullDef->notetrackSoundMapKeys; + } + + if (fullDef->weapDef.notetrackSoundMapValues) + { + assert(sizeof(WeaponFullDef::notetrackSoundMapValues) >= sizeof(scr_string_t) * std::extent_v); + memcpy(fullDef->notetrackSoundMapValues, + fullDef->weapDef.notetrackSoundMapValues, + sizeof(scr_string_t) * std::extent_v); + fullDef->weapDef.notetrackSoundMapValues = fullDef->notetrackSoundMapValues; + } + + if (fullDef->weapDef.notetrackRumbleMapKeys) + { + assert(sizeof(WeaponFullDef::notetrackRumbleMapKeys) >= sizeof(scr_string_t) * std::extent_v); + memcpy(fullDef->notetrackRumbleMapKeys, + fullDef->weapDef.notetrackRumbleMapKeys, + sizeof(scr_string_t) * std::extent_v); + fullDef->weapDef.notetrackRumbleMapKeys = fullDef->notetrackRumbleMapKeys; + } + + if (fullDef->weapDef.notetrackRumbleMapValues) + { + assert(sizeof(WeaponFullDef::notetrackRumbleMapValues) >= sizeof(scr_string_t) * std::extent_v); + memcpy(fullDef->notetrackRumbleMapValues, + fullDef->weapDef.notetrackRumbleMapValues, + sizeof(scr_string_t) * std::extent_v); + fullDef->weapDef.notetrackRumbleMapValues = fullDef->notetrackRumbleMapValues; + } + + if (fullDef->weapDef.worldModel) + { + assert(sizeof(WeaponFullDef::worldModel) >= sizeof(void*) * std::extent_v); + memcpy(fullDef->worldModel, fullDef->weapDef.worldModel, sizeof(void*) * std::extent_v); + fullDef->weapDef.worldModel = fullDef->worldModel; + } + + if (fullDef->weapDef.parallelBounce) + { + assert(sizeof(WeaponFullDef::parallelBounce) >= sizeof(float) * std::extent_v); + memcpy(fullDef->parallelBounce, fullDef->weapDef.parallelBounce, sizeof(float) * std::extent_v); + fullDef->weapDef.parallelBounce = fullDef->parallelBounce; + } + + if (fullDef->weapDef.perpendicularBounce) + { + assert(sizeof(WeaponFullDef::perpendicularBounce) >= sizeof(float) * std::extent_v); + memcpy(fullDef->perpendicularBounce, fullDef->weapDef.perpendicularBounce, sizeof(float) * std::extent_v); + fullDef->weapDef.perpendicularBounce = fullDef->perpendicularBounce; + } + + if (fullDef->weapDef.locationDamageMultipliers) + { + assert(sizeof(WeaponFullDef::locationDamageMultipliers) >= sizeof(float) * std::extent_v); + memcpy(fullDef->locationDamageMultipliers, + fullDef->weapDef.locationDamageMultipliers, + sizeof(float) * std::extent_v); + fullDef->weapDef.locationDamageMultipliers = fullDef->locationDamageMultipliers; + } +} + +InfoString AssetDumperWeapon::CreateInfoString(XAssetInfo* asset) +{ + const auto fullDef = std::make_unique(); + memset(fullDef.get(), 0, sizeof(WeaponFullDef)); + CopyToFullDef(asset->Asset(), fullDef.get()); + + InfoStringFromWeaponConverter converter(fullDef.get(), + weapon_fields, + std::extent_v, + [asset](const scr_string_t scrStr) -> std::string + { + assert(scrStr < asset->m_zone->m_script_strings.Count()); + if (scrStr >= asset->m_zone->m_script_strings.Count()) + return ""; + + return asset->m_zone->m_script_strings[scrStr]; + }); + + return converter.Convert(); +} + +bool AssetDumperWeapon::ShouldDump(XAssetInfo* asset) +{ + return true; +} + +void AssetDumperWeapon::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) +{ + // Only dump raw when no gdt available + if (context.m_gdt) + { + const auto infoString = CreateInfoString(asset); + GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_WEAPON); + infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_WEAPON, gdtEntry); + context.m_gdt->WriteEntry(gdtEntry); + } + else + { + const auto assetFile = context.OpenAssetFile("weapons/" + asset->m_name); + + if (!assetFile) + return; + + auto& stream = *assetFile; + const auto infoString = CreateInfoString(asset); + const auto stringValue = infoString.ToString(ObjConstants::INFO_STRING_PREFIX_WEAPON); + stream.write(stringValue.c_str(), stringValue.size()); + } +} diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.h b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.h new file mode 100644 index 00000000..4d827436 --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.h @@ -0,0 +1,18 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/IW5/IW5.h" +#include "InfoString/InfoString.h" + +namespace IW5 +{ + class AssetDumperWeapon final : public AbstractAssetDumper + { + static void CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFullDef* fullDef); + static InfoString CreateInfoString(XAssetInfo* asset); + + protected: + bool ShouldDump(XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + }; +} // namespace IW5 diff --git a/src/ObjWriting/Game/IW5/InfoString/InfoStringFromStructConverter.cpp b/src/ObjWriting/Game/IW5/InfoString/InfoStringFromStructConverter.cpp index 046c164e..c1171c37 100644 --- a/src/ObjWriting/Game/IW5/InfoString/InfoStringFromStructConverter.cpp +++ b/src/ObjWriting/Game/IW5/InfoString/InfoStringFromStructConverter.cpp @@ -84,6 +84,17 @@ void InfoStringFromStructConverter::FillFromBaseField(const cspField_t& field) break; } + case CSPFT_PHYS_COLLMAP: + { + const auto* physCollMap = *reinterpret_cast(reinterpret_cast(m_structure) + field.iOffset); + + if (physCollMap) + m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(physCollMap->name))); + else + m_info_string.SetValueForKey(std::string(field.szName), ""); + break; + } + case CSPFT_SOUND: { const auto* sndAlias = reinterpret_cast(reinterpret_cast(m_structure) + field.iOffset); diff --git a/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp b/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp index 809cdf91..f03d1db1 100644 --- a/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp @@ -9,6 +9,7 @@ #include "AssetDumpers/AssetDumperRawFile.h" #include "AssetDumpers/AssetDumperScriptFile.h" #include "AssetDumpers/AssetDumperStringTable.h" +#include "AssetDumpers/AssetDumperWeapon.h" #include "AssetDumpers/AssetDumperXModel.h" #include "Game/IW5/GameAssetPoolIW5.h" #include "Game/IW5/GameIW5.h" @@ -59,7 +60,7 @@ bool ZoneDumper::DumpZone(AssetDumpingContext& context) const DUMP_ASSET_POOL(AssetDumperMenuDef, m_menu_def, ASSET_TYPE_MENU) DUMP_ASSET_POOL(AssetDumperLocalizeEntry, m_localize, ASSET_TYPE_LOCALIZE_ENTRY) // DUMP_ASSET_POOL(AssetDumperWeaponAttachment, m_attachment, ASSET_TYPE_ATTACHMENT) - // DUMP_ASSET_POOL(AssetDumperWeaponCompleteDef, m_weapon, ASSET_TYPE_WEAPON) + DUMP_ASSET_POOL(AssetDumperWeapon, m_weapon, ASSET_TYPE_WEAPON) // DUMP_ASSET_POOL(AssetDumperFxEffectDef, m_fx, ASSET_TYPE_FX) // DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table, ASSET_TYPE_IMPACT_FX) // DUMP_ASSET_POOL(AssetDumperSurfaceFxTable, m_surface_fx_table, ASSET_TYPE_SURFACE_FX) From 9c4128b830aa7c83617724e18b31430332cfd8e9 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 7 Apr 2024 09:49:53 +0200 Subject: [PATCH 02/17] chore: update iw5 weapon fulldef sizes --- src/Common/Game/IW5/IW5_Assets.h | 4 ++-- .../Game/IW5/AssetDumpers/AssetDumperWeapon.cpp | 16 ++++++---------- .../Game/IW4/XAssets/WeaponCompleteDef.txt | 6 +++--- .../Game/IW5/XAssets/WeaponCompleteDef.txt | 8 ++++---- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/Common/Game/IW5/IW5_Assets.h b/src/Common/Game/IW5/IW5_Assets.h index de213a72..c62599f6 100644 --- a/src/Common/Game/IW5/IW5_Assets.h +++ b/src/Common/Game/IW5/IW5_Assets.h @@ -3998,8 +3998,8 @@ namespace IW5 XModel* gunXModel[16]; const char* szXAnimsRightHanded[42]; const char* szXAnimsLeftHanded[42]; - uint16_t notetrackSoundMapKeys[16]; - uint16_t notetrackSoundMapValues[16]; + uint16_t notetrackSoundMapKeys[24]; + uint16_t notetrackSoundMapValues[24]; uint16_t notetrackRumbleMapKeys[16]; uint16_t notetrackRumbleMapValues[16]; XModel* worldModel[16]; diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp index 243e645e..59017ed2 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp @@ -232,42 +232,39 @@ void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFul if (weapon->hideTags) { - assert(sizeof(WeaponFullDef::hideTags) >= sizeof(scr_string_t) * std::extent_v); memcpy(fullDef->hideTags, weapon->hideTags, sizeof(scr_string_t) * std::extent_v); fullDef->weapCompleteDef.hideTags = fullDef->hideTags; } if (weapon->szXAnims) { - assert(sizeof(WeaponFullDef::szXAnims) >= sizeof(void*) * NUM_WEAP_ANIMS); + static_assert(std::extent_v == NUM_WEAP_ANIMS); memcpy(fullDef->szXAnims, weapon->szXAnims, sizeof(void*) * NUM_WEAP_ANIMS); fullDef->weapCompleteDef.szXAnims = fullDef->szXAnims; } if (fullDef->weapDef.gunXModel) { - assert(sizeof(WeaponFullDef::gunXModel) >= sizeof(void*) * std::extent_v); memcpy(fullDef->gunXModel, fullDef->weapDef.gunXModel, sizeof(void*) * std::extent_v); fullDef->weapDef.gunXModel = fullDef->gunXModel; } if (fullDef->weapDef.szXAnimsRightHanded) { - assert(sizeof(WeaponFullDef::szXAnimsRightHanded) >= sizeof(void*) * NUM_WEAP_ANIMS); + static_assert(std::extent_v == NUM_WEAP_ANIMS); memcpy(fullDef->szXAnimsRightHanded, fullDef->weapDef.szXAnimsRightHanded, sizeof(void*) * NUM_WEAP_ANIMS); fullDef->weapDef.szXAnimsRightHanded = fullDef->szXAnimsRightHanded; } if (fullDef->weapDef.szXAnimsLeftHanded) { - assert(sizeof(WeaponFullDef::szXAnimsLeftHanded) >= sizeof(void*) * NUM_WEAP_ANIMS); + static_assert(std::extent_v == NUM_WEAP_ANIMS); memcpy(fullDef->szXAnimsLeftHanded, fullDef->weapDef.szXAnimsLeftHanded, sizeof(void*) * NUM_WEAP_ANIMS); fullDef->weapDef.szXAnimsLeftHanded = fullDef->szXAnimsLeftHanded; } if (fullDef->weapDef.notetrackSoundMapKeys) { - assert(sizeof(WeaponFullDef::notetrackSoundMapKeys) >= sizeof(scr_string_t) * std::extent_v); memcpy(fullDef->notetrackSoundMapKeys, fullDef->weapDef.notetrackSoundMapKeys, sizeof(scr_string_t) * std::extent_v); @@ -276,7 +273,6 @@ void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFul if (fullDef->weapDef.notetrackSoundMapValues) { - assert(sizeof(WeaponFullDef::notetrackSoundMapValues) >= sizeof(scr_string_t) * std::extent_v); memcpy(fullDef->notetrackSoundMapValues, fullDef->weapDef.notetrackSoundMapValues, sizeof(scr_string_t) * std::extent_v); @@ -285,7 +281,6 @@ void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFul if (fullDef->weapDef.notetrackRumbleMapKeys) { - assert(sizeof(WeaponFullDef::notetrackRumbleMapKeys) >= sizeof(scr_string_t) * std::extent_v); memcpy(fullDef->notetrackRumbleMapKeys, fullDef->weapDef.notetrackRumbleMapKeys, sizeof(scr_string_t) * std::extent_v); @@ -294,7 +289,6 @@ void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFul if (fullDef->weapDef.notetrackRumbleMapValues) { - assert(sizeof(WeaponFullDef::notetrackRumbleMapValues) >= sizeof(scr_string_t) * std::extent_v); memcpy(fullDef->notetrackRumbleMapValues, fullDef->weapDef.notetrackRumbleMapValues, sizeof(scr_string_t) * std::extent_v); @@ -303,13 +297,13 @@ void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFul if (fullDef->weapDef.worldModel) { - assert(sizeof(WeaponFullDef::worldModel) >= sizeof(void*) * std::extent_v); memcpy(fullDef->worldModel, fullDef->weapDef.worldModel, sizeof(void*) * std::extent_v); fullDef->weapDef.worldModel = fullDef->worldModel; } if (fullDef->weapDef.parallelBounce) { + static_assert(std::extent_v == SURF_TYPE_NUM); assert(sizeof(WeaponFullDef::parallelBounce) >= sizeof(float) * std::extent_v); memcpy(fullDef->parallelBounce, fullDef->weapDef.parallelBounce, sizeof(float) * std::extent_v); fullDef->weapDef.parallelBounce = fullDef->parallelBounce; @@ -317,6 +311,7 @@ void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFul if (fullDef->weapDef.perpendicularBounce) { + static_assert(std::extent_v == SURF_TYPE_NUM); assert(sizeof(WeaponFullDef::perpendicularBounce) >= sizeof(float) * std::extent_v); memcpy(fullDef->perpendicularBounce, fullDef->weapDef.perpendicularBounce, sizeof(float) * std::extent_v); fullDef->weapDef.perpendicularBounce = fullDef->perpendicularBounce; @@ -324,6 +319,7 @@ void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFul if (fullDef->weapDef.locationDamageMultipliers) { + static_assert(std::extent_v == HITLOC_NUM); assert(sizeof(WeaponFullDef::locationDamageMultipliers) >= sizeof(float) * std::extent_v); memcpy(fullDef->locationDamageMultipliers, fullDef->weapDef.locationDamageMultipliers, diff --git a/src/ZoneCode/Game/IW4/XAssets/WeaponCompleteDef.txt b/src/ZoneCode/Game/IW4/XAssets/WeaponCompleteDef.txt index 17164c84..51d9a0c2 100644 --- a/src/ZoneCode/Game/IW4/XAssets/WeaponCompleteDef.txt +++ b/src/ZoneCode/Game/IW4/XAssets/WeaponCompleteDef.txt @@ -46,16 +46,16 @@ set reusable notetrackRumbleMapValues; set scriptstring notetrackRumbleMapValues; set count notetrackRumbleMapValues 16; set reusable bounceSound; -set count bounceSound 31; +set count bounceSound SURF_TYPE_NUM; set reusable worldModel; set count worldModel 16; set string szAmmoName; set string szClipName; set string szSharedAmmoCapName; set reusable parallelBounce; -set count parallelBounce 31; +set count parallelBounce SURF_TYPE_NUM; set reusable perpendicularBounce; -set count perpendicularBounce 31; +set count perpendicularBounce SURF_TYPE_NUM; set string accuracyGraphName0; set string accuracyGraphName1; set reusable originalAccuracyGraphKnots0; diff --git a/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt b/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt index 7d37e025..120dcda9 100644 --- a/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt +++ b/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt @@ -76,18 +76,18 @@ set reusable notetrackRumbleMapValues; set scriptstring notetrackRumbleMapValues; set count notetrackRumbleMapValues 16; set reusable bounceSound; -set count bounceSound 31; +set count bounceSound SURF_TYPE_NUM; set reusable rollingSound; -set count rollingSound 31; +set count rollingSound SURF_TYPE_NUM; set reusable worldModel; set count worldModel 16; set string szAmmoName; set string szClipName; set string szSharedAmmoCapName; set reusable parallelBounce; -set count parallelBounce 31; +set count parallelBounce SURF_TYPE_NUM; set reusable perpendicularBounce; -set count perpendicularBounce 31; +set count perpendicularBounce SURF_TYPE_NUM; set string accuracyGraphName0; set string accuracyGraphName1; set reusable originalAccuracyGraphKnots0; From 3dad9d60da6c862d7eb47277a246875769a951a4 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 7 Apr 2024 10:54:04 +0200 Subject: [PATCH 03/17] chore: fix typo in structs --- src/Common/Game/IW4/IW4_Assets.h | 4 ++-- src/Common/Game/IW5/IW5_Assets.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Common/Game/IW4/IW4_Assets.h b/src/Common/Game/IW4/IW4_Assets.h index c65a0018..7f606455 100644 --- a/src/Common/Game/IW4/IW4_Assets.h +++ b/src/Common/Game/IW4/IW4_Assets.h @@ -3933,7 +3933,7 @@ namespace IW4 WEAPOVERLAYRETICLE_NUM }; - enum WeapOverlayInteface_t + enum WeapOverlayInterface_t { WEAPOVERLAYINTERFACE_NONE = 0x0, WEAPOVERLAYINTERFACE_JAVELIN = 0x1, @@ -4275,7 +4275,7 @@ namespace IW4 Material* overlayMaterialEMP; Material* overlayMaterialEMPLowRes; weapOverlayReticle_t overlayReticle; - WeapOverlayInteface_t overlayInterface; + WeapOverlayInterface_t overlayInterface; float overlayWidth; float overlayHeight; float overlayWidthSplitscreen; diff --git a/src/Common/Game/IW5/IW5_Assets.h b/src/Common/Game/IW5/IW5_Assets.h index c62599f6..ae42784e 100644 --- a/src/Common/Game/IW5/IW5_Assets.h +++ b/src/Common/Game/IW5/IW5_Assets.h @@ -3352,7 +3352,7 @@ namespace IW5 int fireInterruptableTime; }; - enum WeapOverlayInteface_t + enum WeapOverlayInterface_t { WEAPOVERLAYINTERFACE_NONE = 0x0, WEAPOVERLAYINTERFACE_JAVELIN = 0x1, @@ -3635,7 +3635,7 @@ namespace IW5 float fAdsZoomInFrac; float fAdsZoomOutFrac; ADSOverlay overlay; - WeapOverlayInteface_t overlayInterface; + WeapOverlayInterface_t overlayInterface; float fAdsBobFactor; float fAdsViewBobMult; float fHipSpreadStandMin; From c68f4015d2280f7f0a8ae63abb6dcda1d17f5d78 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 7 Apr 2024 10:54:28 +0200 Subject: [PATCH 04/17] chore: add comment about iw5 missing weapon fields --- .../Game/IW5/InfoString/WeaponFields.h | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h index 48eae411..b47a7ce0 100644 --- a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h +++ b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h @@ -3,6 +3,51 @@ namespace IW5 { + // WeaponCompleteDef: + // TODO: scopes + // TODO: underBarrels + // TODO: others + // TODO: animOverrides + // TODO: soundOverrides + // TODO: fxOverrides + // TODO: reloadOverrides + // TODO: notetrackOverrides + // TODO: iFireTimeAkimbo + // TODO: iAltRaiseTimeAkimbo + // TODO: fireAnimLengthAkimbo + // TODO: iFirstRaiseTimeAkimbo + // WeaponDef: + // TODO: changeVariableZoomSound + // TODO: rollingSound + // TODO: akimboStateTimers + // TODO: adsIdleLerpStartTime + // TODO: adsIdleLerpTime + // TODO: riotShieldEnableDamage + // TODO: riotShieldHealth + // TODO: riotShieldDamageMult + // TODO: turretADSEnabled + // TODO: turretADSTime + // TODO: turretFov + // TODO: turretFovADS + // TODO: isAirburstWeapon + // TODO: canHoldBreath + // TODO: canVariableZoom + // TODO: stickToVehicles + // TODO: stickToTurrets + // TODO: doNotAllowAttachmentsToOverrideSpread + // TODO: stowTag + // TODO: stowOffsetModel + // StateTimers: + // TODO: blastFrontTime; + // TODO: blastRightTime; + // TODO: blastBackTime; + // TODO: blastLeftTime; + // TODO: raiseInterruptableTime; + // TODO: firstRaiseInterruptableTime; + // TODO: reloadInterruptableTime; + // TODO: reloadEmptyInterruptableTime; + // TODO: fireInterruptableTime; + inline cspField_t weapon_fields[]{ {"displayName", offsetof(WeaponFullDef, weapCompleteDef.szDisplayName), CSPFT_STRING }, {"AIOverlayDescription", offsetof(WeaponFullDef, weapDef.szOverlayName), CSPFT_STRING }, From fecd486f44ba886b2678fc83d67246e0cc720895 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 7 Apr 2024 13:28:26 +0200 Subject: [PATCH 05/17] chore: dump iw5 attachments that are used by weapons --- src/Common/Game/IW5/IW5.h | 1 + src/Common/Game/IW5/IW5_Assets.h | 3 + .../Game/IW5/InfoString/WeaponFields.h | 4 +- .../IW5/AssetDumpers/AssetDumperWeapon.cpp | 85 +++++++++++++++++-- 4 files changed, 84 insertions(+), 9 deletions(-) diff --git a/src/Common/Game/IW5/IW5.h b/src/Common/Game/IW5/IW5.h index 6b850094..a3cdbf2f 100644 --- a/src/Common/Game/IW5/IW5.h +++ b/src/Common/Game/IW5/IW5.h @@ -115,6 +115,7 @@ namespace IW5 // Custom WFT_ANIM_NAME, + WFT_ATTACHMENT, WFT_NUM_FIELD_TYPES, }; diff --git a/src/Common/Game/IW5/IW5_Assets.h b/src/Common/Game/IW5/IW5_Assets.h index ae42784e..fed67893 100644 --- a/src/Common/Game/IW5/IW5_Assets.h +++ b/src/Common/Game/IW5/IW5_Assets.h @@ -4006,6 +4006,9 @@ namespace IW5 float parallelBounce[31]; float perpendicularBounce[31]; float locationDamageMultipliers[20]; + WeaponAttachment* scopes[6]; + WeaponAttachment* underBarrels[3]; + WeaponAttachment* others[4]; }; struct FxFloatRange diff --git a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h index b47a7ce0..b1e7b837 100644 --- a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h +++ b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h @@ -4,9 +4,6 @@ namespace IW5 { // WeaponCompleteDef: - // TODO: scopes - // TODO: underBarrels - // TODO: others // TODO: animOverrides // TODO: soundOverrides // TODO: fxOverrides @@ -736,6 +733,7 @@ namespace IW5 {"missileConeSoundCrossfadeEnabled", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeEnabled), CSPFT_BOOL }, {"missileConeSoundCrossfadeTopSize", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeTopSize), CSPFT_FLOAT }, {"missileConeSoundCrossfadeBottomSize", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeBottomSize), CSPFT_FLOAT }, + {"attachments", offsetof(WeaponFullDef, scopes), WFT_ATTACHMENT }, }; inline const char* szWeapTypeNames[]{ diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp index 59017ed2..4733ff99 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp @@ -16,6 +16,16 @@ namespace IW5 { class InfoStringFromWeaponConverter final : public InfoStringFromStructConverter { + public: + InfoStringFromWeaponConverter(const WeaponFullDef* structure, + const cspField_t* fields, + const size_t fieldCount, + std::function scriptStringValueCallback) + : InfoStringFromStructConverter(structure, fields, fieldCount, std::move(scriptStringValueCallback)), + m_weapon(structure) + { + } + protected: void FillFromExtensionField(const cspField_t& field) override { @@ -202,6 +212,10 @@ namespace IW5 FillFromString(std::string(field.szName), field.iOffset); break; + case WFT_ATTACHMENT: + FillFromAttachments(std::string(field.szName)); + break; + case WFT_NUM_FIELD_TYPES: default: assert(false); @@ -209,14 +223,55 @@ namespace IW5 } } - public: - InfoStringFromWeaponConverter(const WeaponFullDef* structure, - const cspField_t* fields, - const size_t fieldCount, - std::function scriptStringValueCallback) - : InfoStringFromStructConverter(structure, fields, fieldCount, std::move(scriptStringValueCallback)) + private: + void FillFromAttachments(const std::string& key) { + std::stringstream ss; + bool first = true; + + for (const auto& scope : m_weapon->scopes) + { + if (scope && scope->szInternalName) + { + if (!first) + ss << "\n"; + else + first = false; + + ss << scope->szInternalName; + } + } + + for (const auto& underBarrel : m_weapon->underBarrels) + { + if (underBarrel && underBarrel->szInternalName) + { + if (!first) + ss << "\n"; + else + first = false; + + ss << underBarrel->szInternalName; + } + } + + for (const auto& other : m_weapon->others) + { + if (other && other->szInternalName) + { + if (!first) + ss << "\n"; + else + first = false; + + ss << other->szInternalName; + } + } + + m_info_string.SetValueForKey(key, ss.str()); } + + const WeaponFullDef* m_weapon; }; } // namespace IW5 @@ -326,6 +381,24 @@ void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFul sizeof(float) * std::extent_v); fullDef->weapDef.locationDamageMultipliers = fullDef->locationDamageMultipliers; } + + if (fullDef->weapCompleteDef.scopes) + { + memcpy(fullDef->scopes, fullDef->weapCompleteDef.scopes, sizeof(void*) * std::extent_v); + fullDef->weapCompleteDef.scopes = fullDef->scopes; + } + + if (fullDef->weapCompleteDef.underBarrels) + { + memcpy(fullDef->underBarrels, fullDef->weapCompleteDef.underBarrels, sizeof(void*) * std::extent_v); + fullDef->weapCompleteDef.underBarrels = fullDef->underBarrels; + } + + if (fullDef->weapCompleteDef.others) + { + memcpy(fullDef->others, fullDef->weapCompleteDef.others, sizeof(void*) * std::extent_v); + fullDef->weapCompleteDef.others = fullDef->others; + } } InfoString AssetDumperWeapon::CreateInfoString(XAssetInfo* asset) From a27241701b7ed47845380660670e597e7eea3b3d Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 7 Apr 2024 14:00:20 +0200 Subject: [PATCH 06/17] chore: add iw5 weapon indirect asset references --- src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt b/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt index 120dcda9..b06f4966 100644 --- a/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt +++ b/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt @@ -39,6 +39,8 @@ set count accuracyGraphKnots[1] accuracyGraphKnotCount[1]; use AnimOverrideEntry; set string overrideAnim; set string altmodeAnim; +set assetref overrideAnim ASSET_TYPE_XANIMPARTS; +set assetref altmodeAnim ASSET_TYPE_XANIMPARTS; // NoteTrackToSoundEntry use NoteTrackToSoundEntry; @@ -117,4 +119,6 @@ set reusable name; set condition sound never; // snd_alias_list_name -set string snd_alias_list_name::soundName; \ No newline at end of file +use snd_alias_list_name; +set string soundName; +set assetref soundName ASSET_TYPE_SOUND; From 8554939c91058d7f55c67f2ebb25c598559a92d6 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 7 Apr 2024 14:07:53 +0200 Subject: [PATCH 07/17] chore: dump iw5 weapon anim overrides --- src/Common/Game/IW5/IW5.h | 1 + src/Common/Game/IW5/IW5_Assets.h | 27 ++++- .../Game/IW5/InfoString/WeaponFields.h | 13 ++- .../IW5/AssetDumpers/AssetDumperWeapon.cpp | 98 +++++++++++++++++-- .../Game/IW5/XAssets/WeaponCompleteDef.txt | 6 +- 5 files changed, 130 insertions(+), 15 deletions(-) diff --git a/src/Common/Game/IW5/IW5.h b/src/Common/Game/IW5/IW5.h index a3cdbf2f..33f0f237 100644 --- a/src/Common/Game/IW5/IW5.h +++ b/src/Common/Game/IW5/IW5.h @@ -116,6 +116,7 @@ namespace IW5 // Custom WFT_ANIM_NAME, WFT_ATTACHMENT, + WFT_ANIM_OVERRIDES, WFT_NUM_FIELD_TYPES, }; diff --git a/src/Common/Game/IW5/IW5_Assets.h b/src/Common/Game/IW5/IW5_Assets.h index fed67893..cfaf08f8 100644 --- a/src/Common/Game/IW5/IW5_Assets.h +++ b/src/Common/Game/IW5/IW5_Assets.h @@ -3383,7 +3383,7 @@ namespace IW5 MISSILE_GUIDANCE_COUNT }; - enum weapAnimFiles_t + enum weapAnimFiles_t : unsigned int { WEAP_ANIM_ROOT = 0x0, WEAP_ANIM_IDLE = 0x1, @@ -3428,7 +3428,7 @@ namespace IW5 WEAP_ANIM_ADS_DOWN = 0x28, WEAP_ALT_ANIM_ADJUST = 0x29, - NUM_WEAP_ANIMS + WEAP_ANIM_COUNT }; enum hitLocation_t @@ -3895,13 +3895,30 @@ namespace IW5 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 { - unsigned short attachment1; - unsigned short attachment2; + WeaponAttachmentCombination attachment1; + WeaponAttachmentCombination attachment2; const char* overrideAnim; const char* altmodeAnim; - unsigned int animTreeType; + weapAnimFiles_t animTreeType; int animTime; int altTime; }; diff --git a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h index b1e7b837..97daf1e7 100644 --- a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h +++ b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h @@ -4,7 +4,6 @@ namespace IW5 { // WeaponCompleteDef: - // TODO: animOverrides // TODO: soundOverrides // TODO: fxOverrides // TODO: reloadOverrides @@ -734,6 +733,7 @@ namespace IW5 {"missileConeSoundCrossfadeTopSize", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeTopSize), CSPFT_FLOAT }, {"missileConeSoundCrossfadeBottomSize", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeBottomSize), CSPFT_FLOAT }, {"attachments", offsetof(WeaponFullDef, scopes), WFT_ATTACHMENT }, + {"animOverrides", offsetof(WeaponFullDef, weapCompleteDef.animOverrides), WFT_ANIM_OVERRIDES }, }; inline const char* szWeapTypeNames[]{ @@ -914,4 +914,15 @@ namespace IW5 "_gravel", "_ice", "_metal", "_mud", "_paper", "_plaster", "_rock", "_sand", "_snow", "_water", "_wood", "_asphalt", "_ceramic", "_plastic", "_rubber", "_cushion", "_fruit", "_painted_metal", "_riot_shield", "_slush", }; + static_assert(std::extent_v == 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 == WEAP_ANIM_COUNT); } // namespace IW5 diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp index 4733ff99..04e217b9 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp @@ -5,6 +5,7 @@ #include "Game/IW5/InfoString/WeaponFields.h" #include "Game/IW5/ObjConstantsIW5.h" +#include #include #include #include @@ -216,6 +217,10 @@ namespace IW5 FillFromAttachments(std::string(field.szName)); break; + case WFT_ANIM_OVERRIDES: + FillFromAnimOverrides(std::string(field.szName)); + break; + case WFT_NUM_FIELD_TYPES: default: assert(false); @@ -271,6 +276,87 @@ namespace IW5 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; }; } // namespace IW5 @@ -293,8 +379,8 @@ void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFul if (weapon->szXAnims) { - static_assert(std::extent_v == NUM_WEAP_ANIMS); - memcpy(fullDef->szXAnims, weapon->szXAnims, sizeof(void*) * NUM_WEAP_ANIMS); + static_assert(std::extent_v == WEAP_ANIM_COUNT); + memcpy(fullDef->szXAnims, weapon->szXAnims, sizeof(void*) * WEAP_ANIM_COUNT); fullDef->weapCompleteDef.szXAnims = fullDef->szXAnims; } @@ -306,15 +392,15 @@ void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFul if (fullDef->weapDef.szXAnimsRightHanded) { - static_assert(std::extent_v == NUM_WEAP_ANIMS); - memcpy(fullDef->szXAnimsRightHanded, fullDef->weapDef.szXAnimsRightHanded, sizeof(void*) * NUM_WEAP_ANIMS); + static_assert(std::extent_v == WEAP_ANIM_COUNT); + memcpy(fullDef->szXAnimsRightHanded, fullDef->weapDef.szXAnimsRightHanded, sizeof(void*) * WEAP_ANIM_COUNT); fullDef->weapDef.szXAnimsRightHanded = fullDef->szXAnimsRightHanded; } if (fullDef->weapDef.szXAnimsLeftHanded) { - static_assert(std::extent_v == NUM_WEAP_ANIMS); - memcpy(fullDef->szXAnimsLeftHanded, fullDef->weapDef.szXAnimsLeftHanded, sizeof(void*) * NUM_WEAP_ANIMS); + static_assert(std::extent_v == WEAP_ANIM_COUNT); + memcpy(fullDef->szXAnimsLeftHanded, fullDef->weapDef.szXAnimsLeftHanded, sizeof(void*) * WEAP_ANIM_COUNT); fullDef->weapDef.szXAnimsLeftHanded = fullDef->szXAnimsLeftHanded; } diff --git a/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt b/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt index b06f4966..87af2e94 100644 --- a/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt +++ b/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt @@ -19,7 +19,7 @@ set count others 4; set string szXAnims; set assetref szXAnims ASSET_TYPE_XANIMPARTS; set reusable szXAnims; -set count szXAnims NUM_WEAP_ANIMS; +set count szXAnims WEAP_ANIM_COUNT; set reusable animOverrides; set count animOverrides numAnimOverrides; set reusable soundOverrides; @@ -59,11 +59,11 @@ set count gunXModel 16; set reusable szXAnimsRightHanded; set string szXAnimsRightHanded; set assetref szXAnimsRightHanded ASSET_TYPE_XANIMPARTS; -set count szXAnimsRightHanded NUM_WEAP_ANIMS; +set count szXAnimsRightHanded WEAP_ANIM_COUNT; set reusable szXAnimsLeftHanded; set string szXAnimsLeftHanded; set assetref szXAnimsLeftHanded ASSET_TYPE_XANIMPARTS; -set count szXAnimsLeftHanded NUM_WEAP_ANIMS; +set count szXAnimsLeftHanded WEAP_ANIM_COUNT; set string szModeName; set reusable notetrackSoundMapKeys; set scriptstring notetrackSoundMapKeys; From ea0cb66eae592456e1c9187082bb09c490bb1f86 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 7 Apr 2024 14:08:06 +0200 Subject: [PATCH 08/17] chore: dump iw5 weapon sound overrides --- src/Common/Game/IW5/IW5.h | 1 + src/Common/Game/IW5/IW5_Assets.h | 17 ++++-- .../Game/IW5/InfoString/WeaponFields.h | 11 +++- .../IW5/AssetDumpers/AssetDumperWeapon.cpp | 53 +++++++++++++++++++ 4 files changed, 78 insertions(+), 4 deletions(-) diff --git a/src/Common/Game/IW5/IW5.h b/src/Common/Game/IW5/IW5.h index 33f0f237..01917beb 100644 --- a/src/Common/Game/IW5/IW5.h +++ b/src/Common/Game/IW5/IW5.h @@ -117,6 +117,7 @@ namespace IW5 WFT_ANIM_NAME, WFT_ATTACHMENT, WFT_ANIM_OVERRIDES, + WFT_SOUND_OVERRIDES, WFT_NUM_FIELD_TYPES, }; diff --git a/src/Common/Game/IW5/IW5_Assets.h b/src/Common/Game/IW5/IW5_Assets.h index cfaf08f8..67c224b3 100644 --- a/src/Common/Game/IW5/IW5_Assets.h +++ b/src/Common/Game/IW5/IW5_Assets.h @@ -3923,13 +3923,24 @@ namespace IW5 int altTime; }; + enum SoundOverrideTypes : unsigned int + { + SNDTYPE_NONE = 0x0, + SNDTYPE_FIRE = 0x1, + SNDTYPE_PLAYER_FIRE = 0x2, + SNDTYPE_PLAYER_AKIMBO = 0x3, + SNDTYPE_PLAYER_LASTSHOT = 0x4, + + SNDTYPE_PLAYER_COUNT + }; + struct SoundOverrideEntry { - unsigned short attachment1; - unsigned short attachment2; + WeaponAttachmentCombination attachment1; + WeaponAttachmentCombination attachment2; SndAliasCustom overrideSound; SndAliasCustom altmodeSound; - unsigned int soundType; + SoundOverrideTypes soundType; }; struct FXOverrideEntry diff --git a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h index 97daf1e7..b75514df 100644 --- a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h +++ b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h @@ -4,7 +4,6 @@ namespace IW5 { // WeaponCompleteDef: - // TODO: soundOverrides // TODO: fxOverrides // TODO: reloadOverrides // TODO: notetrackOverrides @@ -734,6 +733,7 @@ namespace IW5 {"missileConeSoundCrossfadeBottomSize", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeBottomSize), CSPFT_FLOAT }, {"attachments", offsetof(WeaponFullDef, scopes), WFT_ATTACHMENT }, {"animOverrides", offsetof(WeaponFullDef, weapCompleteDef.animOverrides), WFT_ANIM_OVERRIDES }, + {"soundOverrides", offsetof(WeaponFullDef, weapCompleteDef.soundOverrides), WFT_SOUND_OVERRIDES }, }; inline const char* szWeapTypeNames[]{ @@ -925,4 +925,13 @@ namespace IW5 "ads_down", "alt_adjust", }; static_assert(std::extent_v == WEAP_ANIM_COUNT); + + inline const char* soundOverrideTypeNames[]{ + "none", + "fire", + "player_fire", + "player_akimbo", + "player_lastshot", + }; + static_assert(std::extent_v == SNDTYPE_PLAYER_COUNT); } // namespace IW5 diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp index 04e217b9..6cf3167f 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp @@ -221,6 +221,10 @@ namespace IW5 FillFromAnimOverrides(std::string(field.szName)); break; + case WFT_SOUND_OVERRIDES: + FillFromSoundOverrides(std::string(field.szName)); + break; + case WFT_NUM_FIELD_TYPES: default: assert(false); @@ -357,6 +361,55 @@ namespace IW5 m_info_string.SetValueForKey(key, ss.str()); } + void FillFromSoundOverrides(const std::string& key) + { + std::stringstream ss; + bool first = true; + + for (auto i = 0u; i < m_weapon->weapCompleteDef.numSoundOverrides; i++) + { + const auto& soundOverride = m_weapon->weapCompleteDef.soundOverrides[i]; + + if (!first) + ss << "\n"; + else + first = false; + + assert(soundOverride.soundType < SNDTYPE_PLAYER_COUNT); + + if (soundOverride.attachment1.fields) + ss << GetNameForSingleWeaponAttachment(soundOverride.attachment1); + else + ss << "none"; + + ss << ' '; + + if (soundOverride.attachment2.fields) + ss << GetNameForSingleWeaponAttachment(soundOverride.attachment2); + else + ss << "none"; + + ss << ' '; + + if (soundOverride.soundType < SNDTYPE_PLAYER_COUNT) + ss << soundOverrideTypeNames[soundOverride.soundType] << ' '; + + if (soundOverride.overrideSound.name && soundOverride.overrideSound.name->soundName && soundOverride.overrideSound.name->soundName[0]) + ss << soundOverride.overrideSound.name->soundName; + else + ss << "none"; + + ss << ' '; + + if (soundOverride.altmodeSound.name && soundOverride.altmodeSound.name->soundName && soundOverride.altmodeSound.name->soundName[0]) + ss << soundOverride.altmodeSound.name->soundName; + else + ss << "none"; + } + + m_info_string.SetValueForKey(key, ss.str()); + } + const WeaponFullDef* m_weapon; }; } // namespace IW5 From 4f0d9674ff0e9e66476e731a85c5fce74d7eacf9 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 7 Apr 2024 14:04:12 +0200 Subject: [PATCH 09/17] chore: dump iw5 weapon fx overrides --- src/Common/Game/IW5/IW5.h | 3 ++ src/Common/Game/IW5/IW5_Assets.h | 17 ++++-- .../Game/IW5/InfoString/WeaponFields.h | 11 +++- .../IW5/AssetDumpers/AssetDumperWeapon.cpp | 53 +++++++++++++++++++ 4 files changed, 80 insertions(+), 4 deletions(-) diff --git a/src/Common/Game/IW5/IW5.h b/src/Common/Game/IW5/IW5.h index 01917beb..e6c58928 100644 --- a/src/Common/Game/IW5/IW5.h +++ b/src/Common/Game/IW5/IW5.h @@ -118,6 +118,9 @@ namespace IW5 WFT_ATTACHMENT, WFT_ANIM_OVERRIDES, WFT_SOUND_OVERRIDES, + WFT_FX_OVERRIDES, + WFT_RELOAD_OVERRIDES, + WFT_NOTE_TRACK_OVERRIDES, WFT_NUM_FIELD_TYPES, }; diff --git a/src/Common/Game/IW5/IW5_Assets.h b/src/Common/Game/IW5/IW5_Assets.h index 67c224b3..8084e044 100644 --- a/src/Common/Game/IW5/IW5_Assets.h +++ b/src/Common/Game/IW5/IW5_Assets.h @@ -3943,13 +3943,24 @@ namespace IW5 SoundOverrideTypes soundType; }; + enum FXOverrideTypes : unsigned int + { + FXTYPE_NONE = 0x0, + FXTYPE_VIEW_FLASH = 0x1, + FXTYPE_WORLD_FLASH = 0x2, + FXTYPE_VIEW_SHELL_EJECT = 0x3, + FXTYPE_WORLD_SHELL_EJECT = 0x4, + + FXTYPE_COUNT + }; + struct FXOverrideEntry { - unsigned short attachment1; - unsigned short attachment2; + WeaponAttachmentCombination attachment1; + WeaponAttachmentCombination attachment2; FxEffectDef* overrideFX; FxEffectDef* altmodeFX; - unsigned int fxType; + FXOverrideTypes fxType; }; struct ReloadStateTimerEntry diff --git a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h index b75514df..1d762862 100644 --- a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h +++ b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h @@ -4,7 +4,6 @@ namespace IW5 { // WeaponCompleteDef: - // TODO: fxOverrides // TODO: reloadOverrides // TODO: notetrackOverrides // TODO: iFireTimeAkimbo @@ -734,6 +733,7 @@ namespace IW5 {"attachments", offsetof(WeaponFullDef, scopes), WFT_ATTACHMENT }, {"animOverrides", offsetof(WeaponFullDef, weapCompleteDef.animOverrides), WFT_ANIM_OVERRIDES }, {"soundOverrides", offsetof(WeaponFullDef, weapCompleteDef.soundOverrides), WFT_SOUND_OVERRIDES }, + {"fxOverrides", offsetof(WeaponFullDef, weapCompleteDef.fxOverrides), WFT_FX_OVERRIDES }, }; inline const char* szWeapTypeNames[]{ @@ -934,4 +934,13 @@ namespace IW5 "player_lastshot", }; static_assert(std::extent_v == SNDTYPE_PLAYER_COUNT); + + inline const char* fxOverrideTypeNames[]{ + "none", + "view_flash", + "world_flash", + "view_shell_eject", + "world_shell_eject", + }; + static_assert(std::extent_v == FXTYPE_COUNT); } // namespace IW5 diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp index 6cf3167f..9599b95d 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp @@ -225,6 +225,10 @@ namespace IW5 FillFromSoundOverrides(std::string(field.szName)); break; + case WFT_FX_OVERRIDES: + FillFromFxOverrides(std::string(field.szName)); + break; + case WFT_NUM_FIELD_TYPES: default: assert(false); @@ -410,6 +414,55 @@ namespace IW5 m_info_string.SetValueForKey(key, ss.str()); } + void FillFromFxOverrides(const std::string& key) + { + std::stringstream ss; + bool first = true; + + for (auto i = 0u; i < m_weapon->weapCompleteDef.numFXOverrides; i++) + { + const auto& fxOverride = m_weapon->weapCompleteDef.fxOverrides[i]; + + if (!first) + ss << "\n"; + else + first = false; + + assert(fxOverride.fxType < FXTYPE_COUNT); + + if (fxOverride.attachment1.fields) + ss << GetNameForSingleWeaponAttachment(fxOverride.attachment1); + else + ss << "none"; + + ss << ' '; + + if (fxOverride.attachment2.fields) + ss << GetNameForSingleWeaponAttachment(fxOverride.attachment2); + else + ss << "none"; + + ss << ' '; + + if (fxOverride.fxType < FXTYPE_COUNT) + ss << fxOverrideTypeNames[fxOverride.fxType] << ' '; + + if (fxOverride.overrideFX && fxOverride.overrideFX->name && fxOverride.overrideFX->name[0]) + ss << fxOverride.overrideFX->name; + else + ss << "none"; + + ss << ' '; + + if (fxOverride.altmodeFX && fxOverride.altmodeFX->name && fxOverride.altmodeFX->name[0]) + ss << fxOverride.altmodeFX->name; + else + ss << "none"; + } + + m_info_string.SetValueForKey(key, ss.str()); + } + const WeaponFullDef* m_weapon; }; } // namespace IW5 From c1a487479171c3ba5257638e9b11c78c420970bc Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 7 Apr 2024 15:09:51 +0200 Subject: [PATCH 10/17] =?UTF-8?q?=EF=BB=BFchore:=20add=20static=20assertio?= =?UTF-8?q?ns=20for=20weapon=20field=20names?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Common/Game/IW5/IW5_Assets.h | 26 +++++++++---------- .../Game/IW5/InfoString/WeaponFields.h | 20 ++++++++++++++ .../IW5/AssetDumpers/AssetDumperWeapon.cpp | 4 +-- .../Game/IW5/XAssets/WeaponCompleteDef.txt | 8 +++--- 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/Common/Game/IW5/IW5_Assets.h b/src/Common/Game/IW5/IW5_Assets.h index 8084e044..bc2892f5 100644 --- a/src/Common/Game/IW5/IW5_Assets.h +++ b/src/Common/Game/IW5/IW5_Assets.h @@ -2852,7 +2852,7 @@ namespace IW5 WEAPTYPE_PROJECTILE = 0x3, WEAPTYPE_RIOTSHIELD = 0x4, - WEAPTYPE_NUM + WEAPTYPE_COUNT }; enum weapClass_t @@ -2870,7 +2870,7 @@ namespace IW5 WEAPCLASS_NON_PLAYER = 0xA, WEAPCLASS_ITEM = 0xB, - WEAPCLASS_NUM + WEAPCLASS_COUNT }; enum PenetrateType @@ -2909,9 +2909,7 @@ namespace IW5 WEAPON_FIRETYPE_BURSTFIRE4 = 0x4, WEAPON_FIRETYPE_DOUBLEBARREL = 0x5, - WEAPON_FIRETYPECOUNT, - WEAPON_FIRETYPE_BURSTFIRE_FIRST = WEAPON_FIRETYPE_BURSTFIRE2, - WEAPON_FIRETYPE_BURSTFIRE_LAST = WEAPON_FIRETYPE_BURSTFIRE4 + WEAPON_FIRETYPE_COUNT }; struct AttAmmoGeneral @@ -3099,7 +3097,7 @@ namespace IW5 WEAPOVERLAYRETICLE_NONE = 0x0, WEAPOVERLAYRETICLE_CROSSHAIR = 0x1, - WEAPOVERLAYRETICLE_NUM + WEAPOVERLAYRETICLE_COUNT }; struct ADSOverlay @@ -3168,7 +3166,7 @@ namespace IW5 WEAPPROJEXP_SMOKE = 0x5, WEAPPROJEXP_HEAVY = 0x6, - WEAPPROJEXP_NUM + WEAPPROJEXP_COUNT }; struct snd_alias_list_name @@ -3266,7 +3264,7 @@ namespace IW5 WEAPINVENTORY_EXCLUSIVE = 0x4, WEAPINVENTORY_SCAVENGER = 0x5, - WEAPINVENTORYCOUNT + WEAPINVENTORY_COUNT }; enum OffhandClass @@ -3287,7 +3285,7 @@ namespace IW5 WEAPSTANCE_DUCK = 0x1, WEAPSTANCE_PRONE = 0x2, - WEAPSTANCE_NUM + WEAPSTANCE_COUNT }; enum activeReticleType_t @@ -3358,7 +3356,7 @@ namespace IW5 WEAPOVERLAYINTERFACE_JAVELIN = 0x1, WEAPOVERLAYINTERFACE_TURRETSCOPE = 0x2, - WEAPOVERLAYINTERFACECOUNT + WEAPOVERLAYINTERFACE_COUNT }; enum WeapStickinessType @@ -3491,7 +3489,7 @@ namespace IW5 SURF_TYPE_RIOT_SHIELD, SURF_TYPE_SLUSH, - SURF_TYPE_NUM + SURF_TYPE_COUNT }; struct WeaponDef @@ -4524,7 +4522,8 @@ namespace IW5 VEH_SNOWMOBILE = 0x6, VEH_SUBMARINE = 0x7, VEH_UGV = 0x8, - VEH_TYPE_COUNT = 0x9 + + VEH_TYPE_COUNT }; enum VehicleAxleType @@ -4532,7 +4531,8 @@ namespace IW5 VEH_AXLE_FRONT = 0x0, VEH_AXLE_REAR = 0x1, VEH_AXLE_ALL = 0x2, - VEH_AXLE_COUNT = 0x3 + + VEH_AXLE_COUNT }; enum VehCamZOffsetMode diff --git a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h index 1d762862..b4171233 100644 --- a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h +++ b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h @@ -743,6 +743,7 @@ namespace IW5 "projectile", "riotshield", }; + static_assert(std::extent_v == WEAPTYPE_COUNT); inline const char* szWeapClassNames[]{ "rifle", @@ -758,11 +759,13 @@ namespace IW5 "non-player", "item", }; + static_assert(std::extent_v == WEAPCLASS_COUNT); inline const char* szWeapOverlayReticleNames[]{ "none", "crosshair", }; + static_assert(std::extent_v == WEAPOVERLAYRETICLE_COUNT); inline const char* szWeapInventoryTypeNames[]{ "primary", @@ -772,6 +775,7 @@ namespace IW5 "exclusive", "scavenger", }; + static_assert(std::extent_v == WEAPINVENTORY_COUNT); inline const char* szWeapFireTypeNames[]{ "Full Auto", @@ -781,6 +785,7 @@ namespace IW5 "4-Round Burst", "Double Barrel", }; + static_assert(std::extent_v == WEAPON_FIRETYPE_COUNT); inline const char* penetrateTypeNames[]{ "none", @@ -788,6 +793,7 @@ namespace IW5 "medium", "large", }; + static_assert(std::extent_v == PENETRATE_TYPE_COUNT); inline const char* impactTypeNames[]{ "none", @@ -802,12 +808,14 @@ namespace IW5 "rocket_explode", "projectile_dud", }; + static_assert(std::extent_v == IMPACT_TYPE_COUNT); inline const char* szWeapStanceNames[]{ "stand", "duck", "prone", }; + static_assert(std::extent_v == WEAPSTANCE_COUNT); inline const char* szProjectileExplosionNames[]{ "grenade", @@ -818,6 +826,7 @@ namespace IW5 "smoke", "heavy explosive", }; + static_assert(std::extent_v == WEAPPROJEXP_COUNT); inline const char* offhandClassNames[]{ "None", @@ -827,6 +836,7 @@ namespace IW5 "Throwing Knife", "Other", }; + static_assert(std::extent_v == OFFHAND_CLASS_COUNT); inline const char* playerAnimTypeNames[]{ "none", @@ -854,6 +864,7 @@ namespace IW5 "Pip-On-A-Stick", "Bouncing diamond", }; + static_assert(std::extent_v == VEH_ACTIVE_RETICLE_COUNT); inline const char* guidedMissileNames[]{ "None", @@ -861,6 +872,7 @@ namespace IW5 "Hellfire", "Javelin", }; + static_assert(std::extent_v == MISSILE_GUIDANCE_COUNT); inline const char* stickinessNames[]{ "Don't stick", @@ -870,12 +882,14 @@ namespace IW5 "Stick to ground, maintain yaw", "Knife", }; + static_assert(std::extent_v == WEAPSTICKINESS_COUNT); inline const char* overlayInterfaceNames[]{ "None", "Javelin", "Turret Scope", }; + static_assert(std::extent_v == WEAPOVERLAYINTERFACE_COUNT); inline const char* ammoCounterClipNames[]{ "None", @@ -886,12 +900,14 @@ namespace IW5 "Beltfed", "AltWeapon", }; + static_assert(std::extent_v == AMMO_COUNTER_CLIP_COUNT); inline const char* weapIconRatioNames[]{ "1:1", "2:1", "4:1", }; + static_assert(std::extent_v == WEAPON_ICON_RATIO_COUNT); inline const char* s_vehicleClassNames[]{ "4 wheel", @@ -901,13 +917,17 @@ namespace IW5 "artillery", "helicopter", "snowmobile", + "submarine", + "ugv", }; + static_assert(std::extent_v == VEH_TYPE_COUNT); inline const char* s_vehicleAxleTypeNames[]{ "front", "rear", "all", }; + static_assert(std::extent_v == VEH_AXLE_COUNT); inline const char* bounceSoundSuffixes[]{ "_default", "_bark", "_brick", "_carpet", "_cloth", "_concrete", "_dirt", "_flesh", "_foliage", "_glass", "_grass", diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp index 9599b95d..a762d23f 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp @@ -550,7 +550,7 @@ void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFul if (fullDef->weapDef.parallelBounce) { - static_assert(std::extent_v == SURF_TYPE_NUM); + static_assert(std::extent_v == SURF_TYPE_COUNT); assert(sizeof(WeaponFullDef::parallelBounce) >= sizeof(float) * std::extent_v); memcpy(fullDef->parallelBounce, fullDef->weapDef.parallelBounce, sizeof(float) * std::extent_v); fullDef->weapDef.parallelBounce = fullDef->parallelBounce; @@ -558,7 +558,7 @@ void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFul if (fullDef->weapDef.perpendicularBounce) { - static_assert(std::extent_v == SURF_TYPE_NUM); + static_assert(std::extent_v == SURF_TYPE_COUNT); assert(sizeof(WeaponFullDef::perpendicularBounce) >= sizeof(float) * std::extent_v); memcpy(fullDef->perpendicularBounce, fullDef->weapDef.perpendicularBounce, sizeof(float) * std::extent_v); fullDef->weapDef.perpendicularBounce = fullDef->perpendicularBounce; diff --git a/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt b/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt index 87af2e94..fef404d0 100644 --- a/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt +++ b/src/ZoneCode/Game/IW5/XAssets/WeaponCompleteDef.txt @@ -78,18 +78,18 @@ set reusable notetrackRumbleMapValues; set scriptstring notetrackRumbleMapValues; set count notetrackRumbleMapValues 16; set reusable bounceSound; -set count bounceSound SURF_TYPE_NUM; +set count bounceSound SURF_TYPE_COUNT; set reusable rollingSound; -set count rollingSound SURF_TYPE_NUM; +set count rollingSound SURF_TYPE_COUNT; set reusable worldModel; set count worldModel 16; set string szAmmoName; set string szClipName; set string szSharedAmmoCapName; set reusable parallelBounce; -set count parallelBounce SURF_TYPE_NUM; +set count parallelBounce SURF_TYPE_COUNT; set reusable perpendicularBounce; -set count perpendicularBounce SURF_TYPE_NUM; +set count perpendicularBounce SURF_TYPE_COUNT; set string accuracyGraphName0; set string accuracyGraphName1; set reusable originalAccuracyGraphKnots0; From 7b23461e2a126ec9f4883bfdf2f943d14ae4dd65 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 7 Apr 2024 19:58:49 +0200 Subject: [PATCH 11/17] chore: dump iw5 weapon reload overrides --- src/Common/Game/IW5/IW5_Assets.h | 3 +- .../Game/IW5/InfoString/WeaponFields.h | 2 +- .../IW5/AssetDumpers/AssetDumperWeapon.cpp | 29 +++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/Common/Game/IW5/IW5_Assets.h b/src/Common/Game/IW5/IW5_Assets.h index bc2892f5..350a2dea 100644 --- a/src/Common/Game/IW5/IW5_Assets.h +++ b/src/Common/Game/IW5/IW5_Assets.h @@ -3963,7 +3963,8 @@ namespace IW5 struct ReloadStateTimerEntry { - int attachment; + WeaponAttachmentCombination attachment; + short unused; int reloadAddTime; int reloadStartAddTime; }; diff --git a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h index b4171233..9e6a34a7 100644 --- a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h +++ b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h @@ -4,7 +4,6 @@ namespace IW5 { // WeaponCompleteDef: - // TODO: reloadOverrides // TODO: notetrackOverrides // TODO: iFireTimeAkimbo // TODO: iAltRaiseTimeAkimbo @@ -734,6 +733,7 @@ namespace IW5 {"animOverrides", offsetof(WeaponFullDef, weapCompleteDef.animOverrides), WFT_ANIM_OVERRIDES }, {"soundOverrides", offsetof(WeaponFullDef, weapCompleteDef.soundOverrides), WFT_SOUND_OVERRIDES }, {"fxOverrides", offsetof(WeaponFullDef, weapCompleteDef.fxOverrides), WFT_FX_OVERRIDES }, + {"reloadOverrides", offsetof(WeaponFullDef, weapCompleteDef.reloadOverrides), WFT_RELOAD_OVERRIDES }, }; inline const char* szWeapTypeNames[]{ diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp index a762d23f..06de0a3c 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp @@ -229,6 +229,10 @@ namespace IW5 FillFromFxOverrides(std::string(field.szName)); break; + case WFT_RELOAD_OVERRIDES: + FillFromReloadOverrides(std::string(field.szName)); + break; + case WFT_NUM_FIELD_TYPES: default: assert(false); @@ -463,6 +467,31 @@ namespace IW5 m_info_string.SetValueForKey(key, ss.str()); } + void FillFromReloadOverrides(const std::string& key) + { + std::stringstream ss; + bool first = true; + + for (auto i = 0u; i < m_weapon->weapCompleteDef.numReloadStateTimerOverrides; i++) + { + const auto& reloadOverride = m_weapon->weapCompleteDef.reloadOverrides[i]; + + if (!first) + ss << "\n"; + else + first = false; + + if (reloadOverride.attachment.fields) + ss << GetNameForSingleWeaponAttachment(reloadOverride.attachment); + else + ss << "none"; + + ss << ' ' << reloadOverride.reloadAddTime << ' ' << reloadOverride.reloadStartAddTime; + } + + m_info_string.SetValueForKey(key, ss.str()); + } + const WeaponFullDef* m_weapon; }; } // namespace IW5 From cca67ebafa68aa622674bb7984c2a3318c79a6f1 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 7 Apr 2024 20:17:23 +0200 Subject: [PATCH 12/17] chore: dump iw5 weapon notetrack overrides --- src/Common/Game/IW5/IW5.h | 2 +- src/Common/Game/IW5/IW5_Assets.h | 3 +- .../Game/IW5/InfoString/WeaponFields.h | 2 +- .../IW5/AssetDumpers/AssetDumperWeapon.cpp | 38 +++++++++++++++++++ 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/Common/Game/IW5/IW5.h b/src/Common/Game/IW5/IW5.h index e6c58928..9b019bbf 100644 --- a/src/Common/Game/IW5/IW5.h +++ b/src/Common/Game/IW5/IW5.h @@ -120,7 +120,7 @@ namespace IW5 WFT_SOUND_OVERRIDES, WFT_FX_OVERRIDES, WFT_RELOAD_OVERRIDES, - WFT_NOTE_TRACK_OVERRIDES, + WFT_NOTETRACK_OVERRIDES, WFT_NUM_FIELD_TYPES, }; diff --git a/src/Common/Game/IW5/IW5_Assets.h b/src/Common/Game/IW5/IW5_Assets.h index 350a2dea..2ed9b192 100644 --- a/src/Common/Game/IW5/IW5_Assets.h +++ b/src/Common/Game/IW5/IW5_Assets.h @@ -3971,7 +3971,8 @@ namespace IW5 struct NoteTrackToSoundEntry { - int attachment; + WeaponAttachmentCombination attachment; + short unused; ScriptString* notetrackSoundMapKeys; ScriptString* notetrackSoundMapValues; }; diff --git a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h index 9e6a34a7..19eaecbf 100644 --- a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h +++ b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h @@ -4,7 +4,6 @@ namespace IW5 { // WeaponCompleteDef: - // TODO: notetrackOverrides // TODO: iFireTimeAkimbo // TODO: iAltRaiseTimeAkimbo // TODO: fireAnimLengthAkimbo @@ -734,6 +733,7 @@ namespace IW5 {"soundOverrides", offsetof(WeaponFullDef, weapCompleteDef.soundOverrides), WFT_SOUND_OVERRIDES }, {"fxOverrides", offsetof(WeaponFullDef, weapCompleteDef.fxOverrides), WFT_FX_OVERRIDES }, {"reloadOverrides", offsetof(WeaponFullDef, weapCompleteDef.reloadOverrides), WFT_RELOAD_OVERRIDES }, + {"notetrackOverrides", offsetof(WeaponFullDef, weapCompleteDef.notetrackOverrides), WFT_NOTETRACK_OVERRIDES }, }; inline const char* szWeapTypeNames[]{ diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp index 06de0a3c..5afb7d22 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp @@ -233,6 +233,10 @@ namespace IW5 FillFromReloadOverrides(std::string(field.szName)); break; + case WFT_NOTETRACK_OVERRIDES: + FillFromNoteTrackOverrides(std::string(field.szName)); + break; + case WFT_NUM_FIELD_TYPES: default: assert(false); @@ -492,6 +496,40 @@ namespace IW5 m_info_string.SetValueForKey(key, ss.str()); } + void FillFromNoteTrackOverrides(const std::string& key) + { + std::stringstream ss; + bool first = true; + + for (auto i = 0u; i < m_weapon->weapCompleteDef.numNotetrackOverrides; i++) + { + const auto& noteTrackOverrides = m_weapon->weapCompleteDef.notetrackOverrides[i]; + + assert(noteTrackOverrides.notetrackSoundMapKeys || noteTrackOverrides.notetrackSoundMapValues); + if (!noteTrackOverrides.notetrackSoundMapKeys || !noteTrackOverrides.notetrackSoundMapValues) + continue; + + const auto attachmentName = noteTrackOverrides.attachment.fields ? GetNameForSingleWeaponAttachment(noteTrackOverrides.attachment) : "none"; + for (auto j = 0u; j < 24u; j++) + { + const auto& noteTrackKey = m_get_scr_string(noteTrackOverrides.notetrackSoundMapKeys[j]); + const auto& noteTrackValue = m_get_scr_string(noteTrackOverrides.notetrackSoundMapValues[j]); + + if (noteTrackKey.empty() || noteTrackValue.empty()) + continue; + + if (!first) + ss << "\n"; + else + first = false; + + ss << attachmentName << ' ' << noteTrackKey << ' ' << noteTrackValue; + } + } + + m_info_string.SetValueForKey(key, ss.str()); + } + const WeaponFullDef* m_weapon; }; } // namespace IW5 From dc99acd3f61510ecd8e541c59bba6a0e9a605888 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 7 Apr 2024 23:01:46 +0200 Subject: [PATCH 13/17] chore: fix using extent of keys instead of values --- src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp index 5afb7d22..bdd24ad6 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp @@ -589,7 +589,7 @@ void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFul { memcpy(fullDef->notetrackSoundMapValues, fullDef->weapDef.notetrackSoundMapValues, - sizeof(scr_string_t) * std::extent_v); + sizeof(scr_string_t) * std::extent_v); fullDef->weapDef.notetrackSoundMapValues = fullDef->notetrackSoundMapValues; } @@ -605,7 +605,7 @@ void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFul { memcpy(fullDef->notetrackRumbleMapValues, fullDef->weapDef.notetrackRumbleMapValues, - sizeof(scr_string_t) * std::extent_v); + sizeof(scr_string_t) * std::extent_v); fullDef->weapDef.notetrackRumbleMapValues = fullDef->notetrackRumbleMapValues; } From f63e7c7f35a8b9489834d8252e3861fb055f85b5 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 7 Apr 2024 23:09:29 +0200 Subject: [PATCH 14/17] chore: dump missing WeaponCompleteDef fields --- src/ObjCommon/Game/IW5/InfoString/WeaponFields.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h index 19eaecbf..ea084fd2 100644 --- a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h +++ b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h @@ -3,11 +3,6 @@ namespace IW5 { - // WeaponCompleteDef: - // TODO: iFireTimeAkimbo - // TODO: iAltRaiseTimeAkimbo - // TODO: fireAnimLengthAkimbo - // TODO: iFirstRaiseTimeAkimbo // WeaponDef: // TODO: changeVariableZoomSound // TODO: rollingSound @@ -347,6 +342,7 @@ namespace IW5 {"meleeDelay", offsetof(WeaponFullDef, weapDef.stateTimers.iMeleeDelay), CSPFT_MILLISECONDS }, {"meleeChargeDelay", offsetof(WeaponFullDef, weapDef.stateTimers.meleeChargeDelay), CSPFT_MILLISECONDS }, {"fireTime", offsetof(WeaponFullDef, weapCompleteDef.iFireTime), CSPFT_MILLISECONDS }, + {"fireTimeAkimbo", offsetof(WeaponFullDef, weapCompleteDef.iFireTimeAkimbo), CSPFT_MILLISECONDS }, {"rechamberTime", offsetof(WeaponFullDef, weapDef.stateTimers.iRechamberTime), CSPFT_MILLISECONDS }, {"rechamberTimeOneHanded", offsetof(WeaponFullDef, weapDef.stateTimers.rechamberTimeOneHanded), CSPFT_MILLISECONDS }, {"rechamberBoltTime", offsetof(WeaponFullDef, weapDef.stateTimers.iRechamberBoltTime), CSPFT_MILLISECONDS }, @@ -366,9 +362,11 @@ namespace IW5 {"raiseTime", offsetof(WeaponFullDef, weapDef.stateTimers.iRaiseTime), CSPFT_MILLISECONDS }, {"altDropTime", offsetof(WeaponFullDef, weapDef.stateTimers.iAltDropTime), CSPFT_MILLISECONDS }, {"altRaiseTime", offsetof(WeaponFullDef, weapCompleteDef.iAltRaiseTime), CSPFT_MILLISECONDS }, + {"altRaiseTimeAkimbo", offsetof(WeaponFullDef, weapCompleteDef.iAltRaiseTimeAkimbo), CSPFT_MILLISECONDS }, {"quickDropTime", offsetof(WeaponFullDef, weapDef.stateTimers.quickDropTime), CSPFT_MILLISECONDS }, {"quickRaiseTime", offsetof(WeaponFullDef, weapDef.stateTimers.quickRaiseTime), CSPFT_MILLISECONDS }, {"firstRaiseTime", offsetof(WeaponFullDef, weapCompleteDef.iFirstRaiseTime), CSPFT_MILLISECONDS }, + {"firstRaiseTimeAkimbo", offsetof(WeaponFullDef, weapCompleteDef.iFirstRaiseTimeAkimbo), CSPFT_MILLISECONDS }, {"breachRaiseTime", offsetof(WeaponFullDef, weapDef.stateTimers.iBreachRaiseTime), CSPFT_MILLISECONDS }, {"emptyRaiseTime", offsetof(WeaponFullDef, weapDef.stateTimers.iEmptyRaiseTime), CSPFT_MILLISECONDS }, {"emptyDropTime", offsetof(WeaponFullDef, weapDef.stateTimers.iEmptyDropTime), CSPFT_MILLISECONDS }, From f8c9e62624aa66b7c478cc45e4b1b6b490954ee7 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 7 Apr 2024 23:40:34 +0200 Subject: [PATCH 15/17] chore: add missing iw5 weapon fields --- src/Common/Game/IW5/IW5.h | 3 +- .../Game/IW5/InfoString/WeaponFields.h | 1501 +++++++++-------- .../IW5/AssetDumpers/AssetDumperWeapon.cpp | 8 +- .../InfoStringFromStructConverter.cpp | 4 + 4 files changed, 783 insertions(+), 733 deletions(-) diff --git a/src/Common/Game/IW5/IW5.h b/src/Common/Game/IW5/IW5.h index 9b019bbf..06388124 100644 --- a/src/Common/Game/IW5/IW5.h +++ b/src/Common/Game/IW5/IW5.h @@ -81,6 +81,7 @@ namespace IW5 CSPFT_PHYS_COLLMAP, CSPFT_SOUND, CSPFT_TRACER, + CSPFT_SCRIPT_STRING, CSPFT_NUM_BASE_FIELD_TYPES, }; @@ -98,7 +99,7 @@ namespace IW5 WFT_ANIMTYPE, WFT_ACTIVE_RETICLE_TYPE, WFT_GUIDED_MISSILE_TYPE, - WFT_BOUNCE_SOUND, + WFT_PER_SURFACE_TYPE_SOUND, WFT_STICKINESS, WFT_OVERLAYINTERFACE, WFT_INVENTORYTYPE, diff --git a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h index ea084fd2..e08f9b2c 100644 --- a/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h +++ b/src/ObjCommon/Game/IW5/InfoString/WeaponFields.h @@ -3,735 +3,780 @@ namespace IW5 { - // WeaponDef: - // TODO: changeVariableZoomSound - // TODO: rollingSound - // TODO: akimboStateTimers - // TODO: adsIdleLerpStartTime - // TODO: adsIdleLerpTime - // TODO: riotShieldEnableDamage - // TODO: riotShieldHealth - // TODO: riotShieldDamageMult - // TODO: turretADSEnabled - // TODO: turretADSTime - // TODO: turretFov - // TODO: turretFovADS - // TODO: isAirburstWeapon - // TODO: canHoldBreath - // TODO: canVariableZoom - // TODO: stickToVehicles - // TODO: stickToTurrets - // TODO: doNotAllowAttachmentsToOverrideSpread - // TODO: stowTag - // TODO: stowOffsetModel - // StateTimers: - // TODO: blastFrontTime; - // TODO: blastRightTime; - // TODO: blastBackTime; - // TODO: blastLeftTime; - // TODO: raiseInterruptableTime; - // TODO: firstRaiseInterruptableTime; - // TODO: reloadInterruptableTime; - // TODO: reloadEmptyInterruptableTime; - // TODO: fireInterruptableTime; - inline cspField_t weapon_fields[]{ - {"displayName", offsetof(WeaponFullDef, weapCompleteDef.szDisplayName), CSPFT_STRING }, - {"AIOverlayDescription", offsetof(WeaponFullDef, weapDef.szOverlayName), CSPFT_STRING }, - {"modeName", offsetof(WeaponFullDef, weapDef.szModeName), CSPFT_STRING }, - {"playerAnimType", offsetof(WeaponFullDef, weapDef.playerAnimType), WFT_ANIMTYPE }, - {"gunModel", offsetof(WeaponFullDef, gunXModel[0]), CSPFT_XMODEL }, - {"gunModel2", offsetof(WeaponFullDef, gunXModel[1]), CSPFT_XMODEL }, - {"gunModel3", offsetof(WeaponFullDef, gunXModel[2]), CSPFT_XMODEL }, - {"gunModel4", offsetof(WeaponFullDef, gunXModel[3]), CSPFT_XMODEL }, - {"gunModel5", offsetof(WeaponFullDef, gunXModel[4]), CSPFT_XMODEL }, - {"gunModel6", offsetof(WeaponFullDef, gunXModel[5]), CSPFT_XMODEL }, - {"gunModel7", offsetof(WeaponFullDef, gunXModel[6]), CSPFT_XMODEL }, - {"gunModel8", offsetof(WeaponFullDef, gunXModel[7]), CSPFT_XMODEL }, - {"gunModel9", offsetof(WeaponFullDef, gunXModel[8]), CSPFT_XMODEL }, - {"gunModel10", offsetof(WeaponFullDef, gunXModel[9]), CSPFT_XMODEL }, - {"gunModel11", offsetof(WeaponFullDef, gunXModel[10]), CSPFT_XMODEL }, - {"gunModel12", offsetof(WeaponFullDef, gunXModel[11]), CSPFT_XMODEL }, - {"gunModel13", offsetof(WeaponFullDef, gunXModel[12]), CSPFT_XMODEL }, - {"gunModel14", offsetof(WeaponFullDef, gunXModel[13]), CSPFT_XMODEL }, - {"gunModel15", offsetof(WeaponFullDef, gunXModel[14]), CSPFT_XMODEL }, - {"gunModel16", offsetof(WeaponFullDef, gunXModel[15]), CSPFT_XMODEL }, - {"handModel", offsetof(WeaponFullDef, weapDef.handXModel), CSPFT_XMODEL }, - {"hideTags", offsetof(WeaponFullDef, hideTags), WFT_HIDETAGS }, - {"notetrackSoundMap", offsetof(WeaponFullDef, notetrackSoundMapKeys), WFT_NOTETRACKSOUNDMAP }, - {"notetrackRumbleMap", offsetof(WeaponFullDef, notetrackRumbleMapKeys), WFT_NOTETRACKRUMBLEMAP }, - {"idleAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_IDLE]), WFT_ANIM_NAME }, - {"emptyIdleAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_EMPTY_IDLE]), WFT_ANIM_NAME }, - {"fireAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_FIRE]), WFT_ANIM_NAME }, - {"holdFireAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_HOLD_FIRE]), WFT_ANIM_NAME }, - {"lastShotAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_LASTSHOT]), WFT_ANIM_NAME }, - {"detonateAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_DETONATE]), WFT_ANIM_NAME }, - {"rechamberAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RECHAMBER]), WFT_ANIM_NAME }, - {"meleeAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_MELEE]), WFT_ANIM_NAME }, - {"meleeChargeAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_MELEE_CHARGE]), WFT_ANIM_NAME }, - {"reloadAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RELOAD]), WFT_ANIM_NAME }, - {"reloadEmptyAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RELOAD_EMPTY]), WFT_ANIM_NAME }, - {"reloadStartAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RELOAD_START]), WFT_ANIM_NAME }, - {"reloadEndAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RELOAD_END]), WFT_ANIM_NAME }, - {"raiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RAISE]), WFT_ANIM_NAME }, - {"dropAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_DROP]), WFT_ANIM_NAME }, - {"firstRaiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_FIRST_RAISE]), WFT_ANIM_NAME }, - {"breachRaiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_BREACH_RAISE]), WFT_ANIM_NAME }, - {"altRaiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ALT_RAISE]), WFT_ANIM_NAME }, - {"altDropAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ALT_DROP]), WFT_ANIM_NAME }, - {"quickRaiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_QUICK_RAISE]), WFT_ANIM_NAME }, - {"quickDropAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_QUICK_DROP]), WFT_ANIM_NAME }, - {"emptyRaiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_EMPTY_RAISE]), WFT_ANIM_NAME }, - {"emptyDropAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_EMPTY_DROP]), WFT_ANIM_NAME }, - {"sprintInAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_SPRINT_IN]), WFT_ANIM_NAME }, - {"sprintLoopAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_SPRINT_LOOP]), WFT_ANIM_NAME }, - {"sprintOutAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_SPRINT_OUT]), WFT_ANIM_NAME }, - {"stunnedAnimStart", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_STUNNED_START]), WFT_ANIM_NAME }, - {"stunnedAnimLoop", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_STUNNED_LOOP]), WFT_ANIM_NAME }, - {"stunnedAnimEnd", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_STUNNED_END]), WFT_ANIM_NAME }, - {"nightVisionWearAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_NIGHTVISION_WEAR]), WFT_ANIM_NAME }, - {"nightVisionRemoveAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_NIGHTVISION_REMOVE]), WFT_ANIM_NAME }, - {"adsFireAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ADS_FIRE]), WFT_ANIM_NAME }, - {"adsLastShotAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ADS_LASTSHOT]), WFT_ANIM_NAME }, - {"adsRechamberAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ADS_RECHAMBER]), WFT_ANIM_NAME }, - {"blastFrontAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_BLAST_FRONT]), WFT_ANIM_NAME }, - {"blastRightAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_BLAST_RIGHT]), WFT_ANIM_NAME }, - {"blastBackAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_BLAST_BACK]), WFT_ANIM_NAME }, - {"blastLeftAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_BLAST_LEFT]), WFT_ANIM_NAME }, - {"adsUpAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ADS_UP]), WFT_ANIM_NAME }, - {"adsDownAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ADS_DOWN]), WFT_ANIM_NAME }, - {"altAdjustAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ALT_ANIM_ADJUST]), WFT_ANIM_NAME }, - {"idleAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_IDLE]), WFT_ANIM_NAME }, - {"emptyIdleAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_EMPTY_IDLE]), WFT_ANIM_NAME }, - {"fireAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_FIRE]), WFT_ANIM_NAME }, - {"holdFireAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_HOLD_FIRE]), WFT_ANIM_NAME }, - {"lastShotAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_LASTSHOT]), WFT_ANIM_NAME }, - {"detonateAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_DETONATE]), WFT_ANIM_NAME }, - {"rechamberAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RECHAMBER]), WFT_ANIM_NAME }, - {"meleeAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_MELEE]), WFT_ANIM_NAME }, - {"meleeChargeAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_MELEE_CHARGE]), WFT_ANIM_NAME }, - {"reloadAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RELOAD]), WFT_ANIM_NAME }, - {"reloadEmptyAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RELOAD_EMPTY]), WFT_ANIM_NAME }, - {"reloadStartAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RELOAD_START]), WFT_ANIM_NAME }, - {"reloadEndAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RELOAD_END]), WFT_ANIM_NAME }, - {"raiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RAISE]), WFT_ANIM_NAME }, - {"dropAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_DROP]), WFT_ANIM_NAME }, - {"firstRaiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_FIRST_RAISE]), WFT_ANIM_NAME }, - {"breachRaiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_BREACH_RAISE]), WFT_ANIM_NAME }, - {"altRaiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ALT_RAISE]), WFT_ANIM_NAME }, - {"altDropAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ALT_DROP]), WFT_ANIM_NAME }, - {"quickRaiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_QUICK_RAISE]), WFT_ANIM_NAME }, - {"quickDropAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_QUICK_DROP]), WFT_ANIM_NAME }, - {"emptyRaiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_EMPTY_RAISE]), WFT_ANIM_NAME }, - {"emptyDropAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_EMPTY_DROP]), WFT_ANIM_NAME }, - {"sprintInAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_SPRINT_IN]), WFT_ANIM_NAME }, - {"sprintLoopAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_SPRINT_LOOP]), WFT_ANIM_NAME }, - {"sprintOutAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_SPRINT_OUT]), WFT_ANIM_NAME }, - {"stunnedAnimStartR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_STUNNED_START]), WFT_ANIM_NAME }, - {"stunnedAnimLoopR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_STUNNED_LOOP]), WFT_ANIM_NAME }, - {"stunnedAnimEndR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_STUNNED_END]), WFT_ANIM_NAME }, - {"nightVisionWearAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_NIGHTVISION_WEAR]), WFT_ANIM_NAME }, - {"nightVisionRemoveAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_NIGHTVISION_REMOVE]), WFT_ANIM_NAME }, - {"adsFireAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ADS_FIRE]), WFT_ANIM_NAME }, - {"adsLastShotAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ADS_LASTSHOT]), WFT_ANIM_NAME }, - {"adsRechamberAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ADS_RECHAMBER]), WFT_ANIM_NAME }, - {"adsUpAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ADS_UP]), WFT_ANIM_NAME }, - {"blastFrontAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_BLAST_FRONT]), WFT_ANIM_NAME }, - {"blastRightAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_BLAST_RIGHT]), WFT_ANIM_NAME }, - {"blastBackAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_BLAST_BACK]), WFT_ANIM_NAME }, - {"blastLeftAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_BLAST_LEFT]), WFT_ANIM_NAME }, - {"adsDownAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ADS_DOWN]), WFT_ANIM_NAME }, - {"altAdjustAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ALT_ANIM_ADJUST]), WFT_ANIM_NAME }, - {"idleAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_IDLE]), WFT_ANIM_NAME }, - {"emptyIdleAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_EMPTY_IDLE]), WFT_ANIM_NAME }, - {"fireAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_FIRE]), WFT_ANIM_NAME }, - {"holdFireAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_HOLD_FIRE]), WFT_ANIM_NAME }, - {"lastShotAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_LASTSHOT]), WFT_ANIM_NAME }, - {"detonateAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_DETONATE]), WFT_ANIM_NAME }, - {"rechamberAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RECHAMBER]), WFT_ANIM_NAME }, - {"meleeAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_MELEE]), WFT_ANIM_NAME }, - {"meleeChargeAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_MELEE_CHARGE]), WFT_ANIM_NAME }, - {"reloadAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RELOAD]), WFT_ANIM_NAME }, - {"reloadEmptyAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RELOAD_EMPTY]), WFT_ANIM_NAME }, - {"reloadStartAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RELOAD_START]), WFT_ANIM_NAME }, - {"reloadEndAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RELOAD_END]), WFT_ANIM_NAME }, - {"raiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RAISE]), WFT_ANIM_NAME }, - {"dropAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_DROP]), WFT_ANIM_NAME }, - {"firstRaiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_FIRST_RAISE]), WFT_ANIM_NAME }, - {"breachRaiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_BREACH_RAISE]), WFT_ANIM_NAME }, - {"altRaiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ALT_RAISE]), WFT_ANIM_NAME }, - {"altDropAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ALT_DROP]), WFT_ANIM_NAME }, - {"quickRaiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_QUICK_RAISE]), WFT_ANIM_NAME }, - {"quickDropAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_QUICK_DROP]), WFT_ANIM_NAME }, - {"emptyRaiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_EMPTY_RAISE]), WFT_ANIM_NAME }, - {"emptyDropAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_EMPTY_DROP]), WFT_ANIM_NAME }, - {"sprintInAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_SPRINT_IN]), WFT_ANIM_NAME }, - {"sprintLoopAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_SPRINT_LOOP]), WFT_ANIM_NAME }, - {"sprintOutAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_SPRINT_OUT]), WFT_ANIM_NAME }, - {"stunnedAnimStartL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_STUNNED_START]), WFT_ANIM_NAME }, - {"stunnedAnimLoopL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_STUNNED_LOOP]), WFT_ANIM_NAME }, - {"stunnedAnimEndL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_STUNNED_END]), WFT_ANIM_NAME }, - {"nightVisionWearAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_NIGHTVISION_WEAR]), WFT_ANIM_NAME }, - {"nightVisionRemoveAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_NIGHTVISION_REMOVE]), WFT_ANIM_NAME }, - {"adsFireAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ADS_FIRE]), WFT_ANIM_NAME }, - {"adsLastShotAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ADS_LASTSHOT]), WFT_ANIM_NAME }, - {"adsRechamberAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ADS_RECHAMBER]), WFT_ANIM_NAME }, - {"blastFrontAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_BLAST_FRONT]), WFT_ANIM_NAME }, - {"blastRightAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_BLAST_RIGHT]), WFT_ANIM_NAME }, - {"blastBackAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_BLAST_BACK]), WFT_ANIM_NAME }, - {"blastLeftAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_BLAST_LEFT]), WFT_ANIM_NAME }, - {"adsUpAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ADS_UP]), WFT_ANIM_NAME }, - {"adsDownAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ADS_DOWN]), WFT_ANIM_NAME }, - {"altAdjustAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ALT_ANIM_ADJUST]), WFT_ANIM_NAME }, - {"script", offsetof(WeaponFullDef, weapDef.szScript), CSPFT_STRING }, - {"weaponType", offsetof(WeaponFullDef, weapDef.weapType), WFT_WEAPONTYPE }, - {"weaponClass", offsetof(WeaponFullDef, weapDef.weapClass), WFT_WEAPONCLASS }, - {"penetrateType", offsetof(WeaponFullDef, weapDef.penetrateType), WFT_PENETRATE_TYPE }, - {"penetrateMultiplier", offsetof(WeaponFullDef, weapCompleteDef.penetrateMultiplier), CSPFT_FLOAT }, - {"impactType", offsetof(WeaponFullDef, weapCompleteDef.impactType), WFT_IMPACT_TYPE }, - {"inventoryType", offsetof(WeaponFullDef, weapDef.inventoryType), WFT_INVENTORYTYPE }, - {"fireType", offsetof(WeaponFullDef, weapDef.fireType), WFT_FIRETYPE }, - {"offhandClass", offsetof(WeaponFullDef, weapDef.offhandClass), WFT_OFFHAND_CLASS }, - {"viewFlashEffect", offsetof(WeaponFullDef, weapDef.viewFlashEffect), CSPFT_FX }, - {"worldFlashEffect", offsetof(WeaponFullDef, weapDef.worldFlashEffect), CSPFT_FX }, - {"pickupSound", offsetof(WeaponFullDef, weapDef.pickupSound), CSPFT_SOUND }, - {"pickupSoundPlayer", offsetof(WeaponFullDef, weapDef.pickupSoundPlayer), CSPFT_SOUND }, - {"ammoPickupSound", offsetof(WeaponFullDef, weapDef.ammoPickupSound), CSPFT_SOUND }, - {"ammoPickupSoundPlayer", offsetof(WeaponFullDef, weapDef.ammoPickupSoundPlayer), CSPFT_SOUND }, - {"projectileSound", offsetof(WeaponFullDef, weapDef.projectileSound), CSPFT_SOUND }, - {"pullbackSound", offsetof(WeaponFullDef, weapDef.pullbackSound), CSPFT_SOUND }, - {"pullbackSoundPlayer", offsetof(WeaponFullDef, weapDef.pullbackSoundPlayer), CSPFT_SOUND }, - {"fireSound", offsetof(WeaponFullDef, weapDef.fireSound), CSPFT_SOUND }, - {"fireSoundPlayer", offsetof(WeaponFullDef, weapDef.fireSoundPlayer), CSPFT_SOUND }, - {"fireSoundPlayerAkimbo", offsetof(WeaponFullDef, weapDef.fireSoundPlayerAkimbo), CSPFT_SOUND }, - {"loopFireSound", offsetof(WeaponFullDef, weapDef.fireLoopSound), CSPFT_SOUND }, - {"loopFireSoundPlayer", offsetof(WeaponFullDef, weapDef.fireLoopSoundPlayer), CSPFT_SOUND }, - {"stopFireSound", offsetof(WeaponFullDef, weapDef.fireStopSound), CSPFT_SOUND }, - {"stopFireSoundPlayer", offsetof(WeaponFullDef, weapDef.fireStopSoundPlayer), CSPFT_SOUND }, - {"lastShotSound", offsetof(WeaponFullDef, weapDef.fireLastSound), CSPFT_SOUND }, - {"lastShotSoundPlayer", offsetof(WeaponFullDef, weapDef.fireLastSoundPlayer), CSPFT_SOUND }, - {"emptyFireSound", offsetof(WeaponFullDef, weapDef.emptyFireSound), CSPFT_SOUND }, - {"emptyFireSoundPlayer", offsetof(WeaponFullDef, weapDef.emptyFireSoundPlayer), CSPFT_SOUND }, - {"meleeSwipeSound", offsetof(WeaponFullDef, weapDef.meleeSwipeSound), CSPFT_SOUND }, - {"meleeSwipeSoundPlayer", offsetof(WeaponFullDef, weapDef.meleeSwipeSoundPlayer), CSPFT_SOUND }, - {"meleeHitSound", offsetof(WeaponFullDef, weapDef.meleeHitSound), CSPFT_SOUND }, - {"meleeMissSound", offsetof(WeaponFullDef, weapDef.meleeMissSound), CSPFT_SOUND }, - {"rechamberSound", offsetof(WeaponFullDef, weapDef.rechamberSound), CSPFT_SOUND }, - {"rechamberSoundPlayer", offsetof(WeaponFullDef, weapDef.rechamberSoundPlayer), CSPFT_SOUND }, - {"reloadSound", offsetof(WeaponFullDef, weapDef.reloadSound), CSPFT_SOUND }, - {"reloadSoundPlayer", offsetof(WeaponFullDef, weapDef.reloadSoundPlayer), CSPFT_SOUND }, - {"reloadEmptySound", offsetof(WeaponFullDef, weapDef.reloadEmptySound), CSPFT_SOUND }, - {"reloadEmptySoundPlayer", offsetof(WeaponFullDef, weapDef.reloadEmptySoundPlayer), CSPFT_SOUND }, - {"reloadStartSound", offsetof(WeaponFullDef, weapDef.reloadStartSound), CSPFT_SOUND }, - {"reloadStartSoundPlayer", offsetof(WeaponFullDef, weapDef.reloadStartSoundPlayer), CSPFT_SOUND }, - {"reloadEndSound", offsetof(WeaponFullDef, weapDef.reloadEndSound), CSPFT_SOUND }, - {"reloadEndSoundPlayer", offsetof(WeaponFullDef, weapDef.reloadEndSoundPlayer), CSPFT_SOUND }, - {"detonateSound", offsetof(WeaponFullDef, weapDef.detonateSound), CSPFT_SOUND }, - {"detonateSoundPlayer", offsetof(WeaponFullDef, weapDef.detonateSoundPlayer), CSPFT_SOUND }, - {"nightVisionWearSound", offsetof(WeaponFullDef, weapDef.nightVisionWearSound), CSPFT_SOUND }, - {"nightVisionWearSoundPlayer", offsetof(WeaponFullDef, weapDef.nightVisionWearSoundPlayer), CSPFT_SOUND }, - {"nightVisionRemoveSound", offsetof(WeaponFullDef, weapDef.nightVisionRemoveSound), CSPFT_SOUND }, - {"nightVisionRemoveSoundPlayer", offsetof(WeaponFullDef, weapDef.nightVisionRemoveSoundPlayer), CSPFT_SOUND }, - {"raiseSound", offsetof(WeaponFullDef, weapDef.raiseSound), CSPFT_SOUND }, - {"raiseSoundPlayer", offsetof(WeaponFullDef, weapDef.raiseSoundPlayer), CSPFT_SOUND }, - {"firstRaiseSound", offsetof(WeaponFullDef, weapDef.firstRaiseSound), CSPFT_SOUND }, - {"firstRaiseSoundPlayer", offsetof(WeaponFullDef, weapDef.firstRaiseSoundPlayer), CSPFT_SOUND }, - {"altSwitchSound", offsetof(WeaponFullDef, weapDef.altSwitchSound), CSPFT_SOUND }, - {"altSwitchSoundPlayer", offsetof(WeaponFullDef, weapDef.altSwitchSoundPlayer), CSPFT_SOUND }, - {"putawaySound", offsetof(WeaponFullDef, weapDef.putawaySound), CSPFT_SOUND }, - {"putawaySoundPlayer", offsetof(WeaponFullDef, weapDef.putawaySoundPlayer), CSPFT_SOUND }, - {"scanSound", offsetof(WeaponFullDef, weapDef.scanSound), CSPFT_SOUND }, - {"bounceSound", offsetof(WeaponFullDef, weapDef.bounceSound), WFT_BOUNCE_SOUND }, - {"viewShellEjectEffect", offsetof(WeaponFullDef, weapDef.viewShellEjectEffect), CSPFT_FX }, - {"worldShellEjectEffect", offsetof(WeaponFullDef, weapDef.worldShellEjectEffect), CSPFT_FX }, - {"viewLastShotEjectEffect", offsetof(WeaponFullDef, weapDef.viewLastShotEjectEffect), CSPFT_FX }, - {"worldLastShotEjectEffect", offsetof(WeaponFullDef, weapDef.worldLastShotEjectEffect), CSPFT_FX }, - {"reticleCenter", offsetof(WeaponFullDef, weapDef.reticleCenter), CSPFT_MATERIAL }, - {"reticleSide", offsetof(WeaponFullDef, weapDef.reticleSide), CSPFT_MATERIAL }, - {"reticleCenterSize", offsetof(WeaponFullDef, weapDef.iReticleCenterSize), CSPFT_INT }, - {"reticleSideSize", offsetof(WeaponFullDef, weapDef.iReticleSideSize), CSPFT_INT }, - {"reticleMinOfs", offsetof(WeaponFullDef, weapDef.iReticleMinOfs), CSPFT_INT }, - {"activeReticleType", offsetof(WeaponFullDef, weapDef.activeReticleType), WFT_ACTIVE_RETICLE_TYPE }, - {"standMoveF", offsetof(WeaponFullDef, weapDef.vStandMove[0]), CSPFT_FLOAT }, - {"standMoveR", offsetof(WeaponFullDef, weapDef.vStandMove[1]), CSPFT_FLOAT }, - {"standMoveU", offsetof(WeaponFullDef, weapDef.vStandMove[2]), CSPFT_FLOAT }, - {"standRotP", offsetof(WeaponFullDef, weapDef.vStandRot[0]), CSPFT_FLOAT }, - {"standRotY", offsetof(WeaponFullDef, weapDef.vStandRot[1]), CSPFT_FLOAT }, - {"standRotR", offsetof(WeaponFullDef, weapDef.vStandRot[2]), CSPFT_FLOAT }, - {"strafeMoveF", offsetof(WeaponFullDef, weapDef.strafeMove[0]), CSPFT_FLOAT }, - {"strafeMoveR", offsetof(WeaponFullDef, weapDef.strafeMove[1]), CSPFT_FLOAT }, - {"strafeMoveU", offsetof(WeaponFullDef, weapDef.strafeMove[2]), CSPFT_FLOAT }, - {"strafeRotP", offsetof(WeaponFullDef, weapDef.strafeRot[0]), CSPFT_FLOAT }, - {"strafeRotY", offsetof(WeaponFullDef, weapDef.strafeRot[1]), CSPFT_FLOAT }, - {"strafeRotR", offsetof(WeaponFullDef, weapDef.strafeRot[2]), CSPFT_FLOAT }, - {"duckedOfsF", offsetof(WeaponFullDef, weapDef.vDuckedOfs[0]), CSPFT_FLOAT }, - {"duckedOfsR", offsetof(WeaponFullDef, weapDef.vDuckedOfs[1]), CSPFT_FLOAT }, - {"duckedOfsU", offsetof(WeaponFullDef, weapDef.vDuckedOfs[2]), CSPFT_FLOAT }, - {"duckedMoveF", offsetof(WeaponFullDef, weapDef.vDuckedMove[0]), CSPFT_FLOAT }, - {"duckedMoveR", offsetof(WeaponFullDef, weapDef.vDuckedMove[1]), CSPFT_FLOAT }, - {"duckedMoveU", offsetof(WeaponFullDef, weapDef.vDuckedMove[2]), CSPFT_FLOAT }, - {"duckedRotP", offsetof(WeaponFullDef, weapDef.vDuckedRot[0]), CSPFT_FLOAT }, - {"duckedRotY", offsetof(WeaponFullDef, weapDef.vDuckedRot[1]), CSPFT_FLOAT }, - {"duckedRotR", offsetof(WeaponFullDef, weapDef.vDuckedRot[2]), CSPFT_FLOAT }, - {"proneOfsF", offsetof(WeaponFullDef, weapDef.vProneOfs[0]), CSPFT_FLOAT }, - {"proneOfsR", offsetof(WeaponFullDef, weapDef.vProneOfs[1]), CSPFT_FLOAT }, - {"proneOfsU", offsetof(WeaponFullDef, weapDef.vProneOfs[2]), CSPFT_FLOAT }, - {"proneMoveF", offsetof(WeaponFullDef, weapDef.vProneMove[0]), CSPFT_FLOAT }, - {"proneMoveR", offsetof(WeaponFullDef, weapDef.vProneMove[1]), CSPFT_FLOAT }, - {"proneMoveU", offsetof(WeaponFullDef, weapDef.vProneMove[2]), CSPFT_FLOAT }, - {"proneRotP", offsetof(WeaponFullDef, weapDef.vProneRot[0]), CSPFT_FLOAT }, - {"proneRotY", offsetof(WeaponFullDef, weapDef.vProneRot[1]), CSPFT_FLOAT }, - {"proneRotR", offsetof(WeaponFullDef, weapDef.vProneRot[2]), CSPFT_FLOAT }, - {"posMoveRate", offsetof(WeaponFullDef, weapDef.fPosMoveRate), CSPFT_FLOAT }, - {"posProneMoveRate", offsetof(WeaponFullDef, weapDef.fPosProneMoveRate), CSPFT_FLOAT }, - {"standMoveMinSpeed", offsetof(WeaponFullDef, weapDef.fStandMoveMinSpeed), CSPFT_FLOAT }, - {"duckedMoveMinSpeed", offsetof(WeaponFullDef, weapDef.fDuckedMoveMinSpeed), CSPFT_FLOAT }, - {"proneMoveMinSpeed", offsetof(WeaponFullDef, weapDef.fProneMoveMinSpeed), CSPFT_FLOAT }, - {"posRotRate", offsetof(WeaponFullDef, weapDef.fPosRotRate), CSPFT_FLOAT }, - {"posProneRotRate", offsetof(WeaponFullDef, weapDef.fPosProneRotRate), CSPFT_FLOAT }, - {"standRotMinSpeed", offsetof(WeaponFullDef, weapDef.fStandRotMinSpeed), CSPFT_FLOAT }, - {"duckedRotMinSpeed", offsetof(WeaponFullDef, weapDef.fDuckedRotMinSpeed), CSPFT_FLOAT }, - {"proneRotMinSpeed", offsetof(WeaponFullDef, weapDef.fProneRotMinSpeed), CSPFT_FLOAT }, - {"worldModel", offsetof(WeaponFullDef, worldModel[0]), CSPFT_XMODEL }, - {"worldModel2", offsetof(WeaponFullDef, worldModel[1]), CSPFT_XMODEL }, - {"worldModel3", offsetof(WeaponFullDef, worldModel[2]), CSPFT_XMODEL }, - {"worldModel4", offsetof(WeaponFullDef, worldModel[3]), CSPFT_XMODEL }, - {"worldModel5", offsetof(WeaponFullDef, worldModel[4]), CSPFT_XMODEL }, - {"worldModel6", offsetof(WeaponFullDef, worldModel[5]), CSPFT_XMODEL }, - {"worldModel7", offsetof(WeaponFullDef, worldModel[6]), CSPFT_XMODEL }, - {"worldModel8", offsetof(WeaponFullDef, worldModel[7]), CSPFT_XMODEL }, - {"worldModel9", offsetof(WeaponFullDef, worldModel[8]), CSPFT_XMODEL }, - {"worldModel10", offsetof(WeaponFullDef, worldModel[9]), CSPFT_XMODEL }, - {"worldModel11", offsetof(WeaponFullDef, worldModel[10]), CSPFT_XMODEL }, - {"worldModel12", offsetof(WeaponFullDef, worldModel[11]), CSPFT_XMODEL }, - {"worldModel13", offsetof(WeaponFullDef, worldModel[12]), CSPFT_XMODEL }, - {"worldModel14", offsetof(WeaponFullDef, worldModel[13]), CSPFT_XMODEL }, - {"worldModel15", offsetof(WeaponFullDef, worldModel[14]), CSPFT_XMODEL }, - {"worldModel16", offsetof(WeaponFullDef, worldModel[15]), CSPFT_XMODEL }, - {"worldClipModel", offsetof(WeaponFullDef, weapDef.worldClipModel), CSPFT_XMODEL }, - {"rocketModel", offsetof(WeaponFullDef, weapDef.rocketModel), CSPFT_XMODEL }, - {"knifeModel", offsetof(WeaponFullDef, weapDef.knifeModel), CSPFT_XMODEL }, - {"worldKnifeModel", offsetof(WeaponFullDef, weapDef.worldKnifeModel), CSPFT_XMODEL }, - {"hudIcon", offsetof(WeaponFullDef, weapDef.hudIcon), CSPFT_MATERIAL }, - {"hudIconRatio", offsetof(WeaponFullDef, weapDef.hudIconRatio), WFT_ICONRATIO_HUD }, - {"pickupIcon", offsetof(WeaponFullDef, weapDef.pickupIcon), CSPFT_MATERIAL }, - {"pickupIconRatio", offsetof(WeaponFullDef, weapDef.pickupIconRatio), WFT_ICONRATIO_PICKUP }, - {"ammoCounterIcon", offsetof(WeaponFullDef, weapDef.ammoCounterIcon), CSPFT_MATERIAL }, - {"ammoCounterIconRatio", offsetof(WeaponFullDef, weapDef.ammoCounterIconRatio), WFT_ICONRATIO_AMMOCOUNTER}, - {"ammoCounterClip", offsetof(WeaponFullDef, weapDef.ammoCounterClip), WFT_AMMOCOUNTER_CLIPTYPE }, - {"startAmmo", offsetof(WeaponFullDef, weapDef.iStartAmmo), CSPFT_INT }, - {"shareAmmo", offsetof(WeaponFullDef, weapDef.sharedAmmo), CSPFT_BOOL }, - {"ammoName", offsetof(WeaponFullDef, weapDef.szAmmoName), CSPFT_STRING }, - {"clipName", offsetof(WeaponFullDef, weapDef.szClipName), CSPFT_STRING }, - {"maxAmmo", offsetof(WeaponFullDef, weapDef.iMaxAmmo), CSPFT_INT }, - {"clipSize", offsetof(WeaponFullDef, weapCompleteDef.iClipSize), CSPFT_INT }, - {"shotCount", offsetof(WeaponFullDef, weapDef.shotCount), CSPFT_INT }, - {"sharedAmmoCapName", offsetof(WeaponFullDef, weapDef.szSharedAmmoCapName), CSPFT_STRING }, - {"sharedAmmoCap", offsetof(WeaponFullDef, weapDef.iSharedAmmoCap), CSPFT_INT }, - {"damage", offsetof(WeaponFullDef, weapDef.damage), CSPFT_INT }, - {"playerDamage", offsetof(WeaponFullDef, weapDef.playerDamage), CSPFT_INT }, - {"meleeDamage", offsetof(WeaponFullDef, weapDef.iMeleeDamage), CSPFT_INT }, - {"minDamage", offsetof(WeaponFullDef, weapDef.minDamage), CSPFT_INT }, - {"minPlayerDamage", offsetof(WeaponFullDef, weapDef.minPlayerDamage), CSPFT_INT }, - {"maxDamageRange", offsetof(WeaponFullDef, weapDef.fMaxDamageRange), CSPFT_FLOAT }, - {"minDamageRange", offsetof(WeaponFullDef, weapDef.fMinDamageRange), CSPFT_FLOAT }, - {"destabilizationRateTime", offsetof(WeaponFullDef, weapDef.destabilizationRateTime), CSPFT_FLOAT }, - {"destabilizationCurvatureMax", offsetof(WeaponFullDef, weapDef.destabilizationCurvatureMax), CSPFT_FLOAT }, - {"destabilizeDistance", offsetof(WeaponFullDef, weapDef.destabilizeDistance), CSPFT_INT }, - {"fireDelay", offsetof(WeaponFullDef, weapDef.stateTimers.iFireDelay), CSPFT_MILLISECONDS }, - {"meleeDelay", offsetof(WeaponFullDef, weapDef.stateTimers.iMeleeDelay), CSPFT_MILLISECONDS }, - {"meleeChargeDelay", offsetof(WeaponFullDef, weapDef.stateTimers.meleeChargeDelay), CSPFT_MILLISECONDS }, - {"fireTime", offsetof(WeaponFullDef, weapCompleteDef.iFireTime), CSPFT_MILLISECONDS }, - {"fireTimeAkimbo", offsetof(WeaponFullDef, weapCompleteDef.iFireTimeAkimbo), CSPFT_MILLISECONDS }, - {"rechamberTime", offsetof(WeaponFullDef, weapDef.stateTimers.iRechamberTime), CSPFT_MILLISECONDS }, - {"rechamberTimeOneHanded", offsetof(WeaponFullDef, weapDef.stateTimers.rechamberTimeOneHanded), CSPFT_MILLISECONDS }, - {"rechamberBoltTime", offsetof(WeaponFullDef, weapDef.stateTimers.iRechamberBoltTime), CSPFT_MILLISECONDS }, - {"holdFireTime", offsetof(WeaponFullDef, weapDef.stateTimers.iHoldFireTime), CSPFT_MILLISECONDS }, - {"detonateTime", offsetof(WeaponFullDef, weapDef.stateTimers.iDetonateTime), CSPFT_MILLISECONDS }, - {"detonateDelay", offsetof(WeaponFullDef, weapDef.stateTimers.iDetonateDelay), CSPFT_MILLISECONDS }, - {"meleeTime", offsetof(WeaponFullDef, weapDef.stateTimers.iMeleeTime), CSPFT_MILLISECONDS }, - {"meleeChargeTime", offsetof(WeaponFullDef, weapDef.stateTimers.meleeChargeTime), CSPFT_MILLISECONDS }, - {"reloadTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadTime), CSPFT_MILLISECONDS }, - {"reloadShowRocketTime", offsetof(WeaponFullDef, weapDef.stateTimers.reloadShowRocketTime), CSPFT_MILLISECONDS }, - {"reloadEmptyTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadEmptyTime), CSPFT_MILLISECONDS }, - {"reloadAddTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadAddTime), CSPFT_MILLISECONDS }, - {"reloadStartTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadStartTime), CSPFT_MILLISECONDS }, - {"reloadStartAddTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadStartAddTime), CSPFT_MILLISECONDS }, - {"reloadEndTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadEndTime), CSPFT_MILLISECONDS }, - {"dropTime", offsetof(WeaponFullDef, weapDef.stateTimers.iDropTime), CSPFT_MILLISECONDS }, - {"raiseTime", offsetof(WeaponFullDef, weapDef.stateTimers.iRaiseTime), CSPFT_MILLISECONDS }, - {"altDropTime", offsetof(WeaponFullDef, weapDef.stateTimers.iAltDropTime), CSPFT_MILLISECONDS }, - {"altRaiseTime", offsetof(WeaponFullDef, weapCompleteDef.iAltRaiseTime), CSPFT_MILLISECONDS }, - {"altRaiseTimeAkimbo", offsetof(WeaponFullDef, weapCompleteDef.iAltRaiseTimeAkimbo), CSPFT_MILLISECONDS }, - {"quickDropTime", offsetof(WeaponFullDef, weapDef.stateTimers.quickDropTime), CSPFT_MILLISECONDS }, - {"quickRaiseTime", offsetof(WeaponFullDef, weapDef.stateTimers.quickRaiseTime), CSPFT_MILLISECONDS }, - {"firstRaiseTime", offsetof(WeaponFullDef, weapCompleteDef.iFirstRaiseTime), CSPFT_MILLISECONDS }, - {"firstRaiseTimeAkimbo", offsetof(WeaponFullDef, weapCompleteDef.iFirstRaiseTimeAkimbo), CSPFT_MILLISECONDS }, - {"breachRaiseTime", offsetof(WeaponFullDef, weapDef.stateTimers.iBreachRaiseTime), CSPFT_MILLISECONDS }, - {"emptyRaiseTime", offsetof(WeaponFullDef, weapDef.stateTimers.iEmptyRaiseTime), CSPFT_MILLISECONDS }, - {"emptyDropTime", offsetof(WeaponFullDef, weapDef.stateTimers.iEmptyDropTime), CSPFT_MILLISECONDS }, - {"sprintInTime", offsetof(WeaponFullDef, weapDef.stateTimers.sprintInTime), CSPFT_MILLISECONDS }, - {"sprintLoopTime", offsetof(WeaponFullDef, weapDef.stateTimers.sprintLoopTime), CSPFT_MILLISECONDS }, - {"sprintOutTime", offsetof(WeaponFullDef, weapDef.stateTimers.sprintOutTime), CSPFT_MILLISECONDS }, - {"stunnedTimeBegin", offsetof(WeaponFullDef, weapDef.stateTimers.stunnedTimeBegin), CSPFT_MILLISECONDS }, - {"stunnedTimeLoop", offsetof(WeaponFullDef, weapDef.stateTimers.stunnedTimeLoop), CSPFT_MILLISECONDS }, - {"stunnedTimeEnd", offsetof(WeaponFullDef, weapDef.stateTimers.stunnedTimeEnd), CSPFT_MILLISECONDS }, - {"nightVisionWearTime", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionWearTime), CSPFT_MILLISECONDS }, - {"nightVisionWearTimeFadeOutEnd", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionWearTimeFadeOutEnd), CSPFT_MILLISECONDS }, - {"nightVisionWearTimePowerUp", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionWearTimePowerUp), CSPFT_MILLISECONDS }, - {"nightVisionRemoveTime", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionRemoveTime), CSPFT_MILLISECONDS }, - {"nightVisionRemoveTimePowerDown", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionRemoveTimePowerDown), CSPFT_MILLISECONDS }, - {"nightVisionRemoveTimeFadeInStart", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionRemoveTimeFadeInStart), CSPFT_MILLISECONDS }, - {"fuseTime", offsetof(WeaponFullDef, weapDef.stateTimers.fuseTime), CSPFT_MILLISECONDS }, - {"aifuseTime", offsetof(WeaponFullDef, weapDef.stateTimers.aiFuseTime), CSPFT_MILLISECONDS }, - {"lockonSupported", offsetof(WeaponFullDef, weapDef.lockonSupported), CSPFT_BOOL }, - {"requireLockonToFire", offsetof(WeaponFullDef, weapDef.requireLockonToFire), CSPFT_BOOL }, - {"bigExplosion", offsetof(WeaponFullDef, weapDef.bigExplosion), CSPFT_BOOL }, - {"noAdsWhenMagEmpty", offsetof(WeaponFullDef, weapDef.noAdsWhenMagEmpty), CSPFT_BOOL }, - {"inheritsPerks", offsetof(WeaponFullDef, weapDef.inheritsPerks), CSPFT_BOOL }, - {"avoidDropCleanup", offsetof(WeaponFullDef, weapDef.avoidDropCleanup), CSPFT_BOOL }, - {"autoAimRange", offsetof(WeaponFullDef, weapDef.autoAimRange), CSPFT_FLOAT }, - {"aimAssistRange", offsetof(WeaponFullDef, weapDef.aimAssistRange), CSPFT_FLOAT }, - {"aimAssistRangeAds", offsetof(WeaponFullDef, weapDef.aimAssistRangeAds), CSPFT_FLOAT }, - {"aimPadding", offsetof(WeaponFullDef, weapDef.aimPadding), CSPFT_FLOAT }, - {"enemyCrosshairRange", offsetof(WeaponFullDef, weapDef.enemyCrosshairRange), CSPFT_FLOAT }, - {"crosshairColorChange", offsetof(WeaponFullDef, weapDef.crosshairColorChange), CSPFT_BOOL }, - {"moveSpeedScale", offsetof(WeaponFullDef, weapDef.moveSpeedScale), CSPFT_FLOAT }, - {"adsMoveSpeedScale", offsetof(WeaponFullDef, weapDef.adsMoveSpeedScale), CSPFT_FLOAT }, - {"sprintDurationScale", offsetof(WeaponFullDef, weapDef.sprintDurationScale), CSPFT_FLOAT }, - {"idleCrouchFactor", offsetof(WeaponFullDef, weapDef.fIdleCrouchFactor), CSPFT_FLOAT }, - {"idleProneFactor", offsetof(WeaponFullDef, weapDef.fIdleProneFactor), CSPFT_FLOAT }, - {"gunMaxPitch", offsetof(WeaponFullDef, weapDef.fGunMaxPitch), CSPFT_FLOAT }, - {"gunMaxYaw", offsetof(WeaponFullDef, weapDef.fGunMaxYaw), CSPFT_FLOAT }, - {"swayMaxAngle", offsetof(WeaponFullDef, weapDef.swayMaxAngle), CSPFT_FLOAT }, - {"swayLerpSpeed", offsetof(WeaponFullDef, weapDef.swayLerpSpeed), CSPFT_FLOAT }, - {"swayPitchScale", offsetof(WeaponFullDef, weapDef.swayPitchScale), CSPFT_FLOAT }, - {"swayYawScale", offsetof(WeaponFullDef, weapDef.swayYawScale), CSPFT_FLOAT }, - {"swayHorizScale", offsetof(WeaponFullDef, weapDef.swayHorizScale), CSPFT_FLOAT }, - {"swayVertScale", offsetof(WeaponFullDef, weapDef.swayVertScale), CSPFT_FLOAT }, - {"swayShellShockScale", offsetof(WeaponFullDef, weapDef.swayShellShockScale), CSPFT_FLOAT }, - {"adsSwayMaxAngle", offsetof(WeaponFullDef, weapDef.adsSwayMaxAngle), CSPFT_FLOAT }, - {"adsSwayLerpSpeed", offsetof(WeaponFullDef, weapDef.adsSwayLerpSpeed), CSPFT_FLOAT }, - {"adsSwayPitchScale", offsetof(WeaponFullDef, weapDef.adsSwayPitchScale), CSPFT_FLOAT }, - {"adsSwayYawScale", offsetof(WeaponFullDef, weapDef.adsSwayYawScale), CSPFT_FLOAT }, - {"adsSwayHorizScale", offsetof(WeaponFullDef, weapDef.adsSwayHorizScale), CSPFT_FLOAT }, - {"adsSwayVertScale", offsetof(WeaponFullDef, weapDef.adsSwayVertScale), CSPFT_FLOAT }, - {"rifleBullet", offsetof(WeaponFullDef, weapDef.bRifleBullet), CSPFT_BOOL }, - {"armorPiercing", offsetof(WeaponFullDef, weapDef.armorPiercing), CSPFT_BOOL }, - {"boltAction", offsetof(WeaponFullDef, weapDef.bBoltAction), CSPFT_BOOL }, - {"aimDownSight", offsetof(WeaponFullDef, weapDef.aimDownSight), CSPFT_BOOL }, - {"rechamberWhileAds", offsetof(WeaponFullDef, weapDef.bRechamberWhileAds), CSPFT_BOOL }, - {"bBulletExplosiveDamage", offsetof(WeaponFullDef, weapDef.bBulletExplosiveDamage), CSPFT_BOOL }, - {"adsViewErrorMin", offsetof(WeaponFullDef, weapDef.adsViewErrorMin), CSPFT_FLOAT }, - {"adsViewErrorMax", offsetof(WeaponFullDef, weapDef.adsViewErrorMax), CSPFT_FLOAT }, - {"clipOnly", offsetof(WeaponFullDef, weapDef.bClipOnly), CSPFT_BOOL }, - {"noAmmoPickup", offsetof(WeaponFullDef, weapDef.noAmmoPickup), CSPFT_BOOL }, - {"cookOffHold", offsetof(WeaponFullDef, weapDef.bCookOffHold), CSPFT_BOOL }, - {"adsFire", offsetof(WeaponFullDef, weapDef.adsFireOnly), CSPFT_BOOL }, - {"cancelAutoHolsterWhenEmpty", offsetof(WeaponFullDef, weapDef.cancelAutoHolsterWhenEmpty), CSPFT_BOOL }, - {"disableSwitchToWhenEmpty", offsetof(WeaponFullDef, weapDef.disableSwitchToWhenEmpty), CSPFT_BOOL }, - {"suppressAmmoReserveDisplay", offsetof(WeaponFullDef, weapDef.suppressAmmoReserveDisplay), CSPFT_BOOL }, - {"enhanced", offsetof(WeaponFullDef, weapCompleteDef.enhanced), CSPFT_BOOL }, - {"motionTracker", offsetof(WeaponFullDef, weapCompleteDef.motionTracker), CSPFT_BOOL }, - {"laserSightDuringNightvision", offsetof(WeaponFullDef, weapDef.laserSightDuringNightvision), CSPFT_BOOL }, - {"markableViewmodel", offsetof(WeaponFullDef, weapDef.markableViewmodel), CSPFT_BOOL }, - {"physCollmap", offsetof(WeaponFullDef, weapDef.physCollmap), CSPFT_PHYS_COLLMAP }, - {"noDualWield", offsetof(WeaponFullDef, weapDef.noDualWield), CSPFT_BOOL }, - {"dualWieldViewModelOffset", offsetof(WeaponFullDef, weapDef.dualWieldViewModelOffset), CSPFT_FLOAT }, - {"killIcon", offsetof(WeaponFullDef, weapCompleteDef.killIcon), CSPFT_MATERIAL }, - {"killIconRatio", offsetof(WeaponFullDef, weapDef.killIconRatio), WFT_ICONRATIO_KILL }, - {"flipKillIcon", offsetof(WeaponFullDef, weapDef.flipKillIcon), CSPFT_BOOL }, - {"dpadIcon", offsetof(WeaponFullDef, weapCompleteDef.dpadIcon), CSPFT_MATERIAL }, - {"dpadIconRatio", offsetof(WeaponFullDef, weapCompleteDef.dpadIconRatio), WFT_ICONRATIO_DPAD }, - {"dpadIconShowsAmmo", offsetof(WeaponFullDef, weapCompleteDef.dpadIconShowsAmmo), CSPFT_BOOL }, - {"noPartialReload", offsetof(WeaponFullDef, weapDef.bNoPartialReload), CSPFT_BOOL }, - {"segmentedReload", offsetof(WeaponFullDef, weapDef.bSegmentedReload), CSPFT_BOOL }, - {"reloadAmmoAdd", offsetof(WeaponFullDef, weapDef.iReloadAmmoAdd), CSPFT_INT }, - {"reloadStartAdd", offsetof(WeaponFullDef, weapDef.iReloadStartAdd), CSPFT_INT }, - {"altWeapon", offsetof(WeaponFullDef, weapCompleteDef.szAltWeaponName), CSPFT_STRING }, - {"dropAmmoMin", offsetof(WeaponFullDef, weapDef.ammoDropStockMin), CSPFT_INT }, - {"dropAmmoMax", offsetof(WeaponFullDef, weapCompleteDef.ammoDropStockMax), CSPFT_INT }, - {"ammoDropClipPercentMin", offsetof(WeaponFullDef, weapDef.ammoDropClipPercentMin), CSPFT_INT }, - {"ammoDropClipPercentMax", offsetof(WeaponFullDef, weapDef.ammoDropClipPercentMax), CSPFT_INT }, - {"blocksProne", offsetof(WeaponFullDef, weapDef.blocksProne), CSPFT_BOOL }, - {"silenced", offsetof(WeaponFullDef, weapDef.silenced), CSPFT_BOOL }, - {"isRollingGrenade", offsetof(WeaponFullDef, weapDef.isRollingGrenade), CSPFT_BOOL }, - {"explosionRadius", offsetof(WeaponFullDef, weapDef.iExplosionRadius), CSPFT_INT }, - {"explosionRadiusMin", offsetof(WeaponFullDef, weapDef.iExplosionRadiusMin), CSPFT_INT }, - {"explosionInnerDamage", offsetof(WeaponFullDef, weapDef.iExplosionInnerDamage), CSPFT_INT }, - {"explosionOuterDamage", offsetof(WeaponFullDef, weapDef.iExplosionOuterDamage), CSPFT_INT }, - {"damageConeAngle", offsetof(WeaponFullDef, weapDef.damageConeAngle), CSPFT_FLOAT }, - {"bulletExplDmgMult", offsetof(WeaponFullDef, weapDef.bulletExplDmgMult), CSPFT_FLOAT }, - {"bulletExplRadiusMult", offsetof(WeaponFullDef, weapDef.bulletExplRadiusMult), CSPFT_FLOAT }, - {"projectileSpeed", offsetof(WeaponFullDef, weapDef.iProjectileSpeed), CSPFT_INT }, - {"projectileSpeedUp", offsetof(WeaponFullDef, weapDef.iProjectileSpeedUp), CSPFT_INT }, - {"projectileSpeedForward", offsetof(WeaponFullDef, weapDef.iProjectileSpeedForward), CSPFT_INT }, - {"projectileActivateDist", offsetof(WeaponFullDef, weapDef.iProjectileActivateDist), CSPFT_INT }, - {"projectileLifetime", offsetof(WeaponFullDef, weapDef.projLifetime), CSPFT_FLOAT }, - {"timeToAccelerate", offsetof(WeaponFullDef, weapDef.timeToAccelerate), CSPFT_FLOAT }, - {"projectileCurvature", offsetof(WeaponFullDef, weapDef.projectileCurvature), CSPFT_FLOAT }, - {"projectileModel", offsetof(WeaponFullDef, weapDef.projectileModel), CSPFT_XMODEL }, - {"projExplosionType", offsetof(WeaponFullDef, weapDef.projExplosion), WFT_PROJ_EXPLOSION }, - {"projExplosionEffect", offsetof(WeaponFullDef, weapDef.projExplosionEffect), CSPFT_FX }, - {"projExplosionEffectForceNormalUp", offsetof(WeaponFullDef, weapDef.projExplosionEffectForceNormalUp), CSPFT_BOOL }, - {"projExplosionSound", offsetof(WeaponFullDef, weapDef.projExplosionSound), CSPFT_SOUND }, - {"projDudEffect", offsetof(WeaponFullDef, weapDef.projDudEffect), CSPFT_FX }, - {"projDudSound", offsetof(WeaponFullDef, weapDef.projDudSound), CSPFT_SOUND }, - {"projImpactExplode", offsetof(WeaponFullDef, weapDef.bProjImpactExplode), CSPFT_BOOL }, - {"stickiness", offsetof(WeaponFullDef, weapDef.stickiness), WFT_STICKINESS }, - {"stickToPlayers", offsetof(WeaponFullDef, weapDef.stickToPlayers), CSPFT_BOOL }, - {"hasDetonator", offsetof(WeaponFullDef, weapDef.hasDetonator), CSPFT_BOOL }, - {"disableFiring", offsetof(WeaponFullDef, weapDef.disableFiring), CSPFT_BOOL }, - {"timedDetonation", offsetof(WeaponFullDef, weapDef.timedDetonation), CSPFT_BOOL }, - {"rotate", offsetof(WeaponFullDef, weapDef.rotate), CSPFT_BOOL }, - {"holdButtonToThrow", offsetof(WeaponFullDef, weapDef.holdButtonToThrow), CSPFT_BOOL }, - {"freezeMovementWhenFiring", offsetof(WeaponFullDef, weapDef.freezeMovementWhenFiring), CSPFT_BOOL }, - {"lowAmmoWarningThreshold", offsetof(WeaponFullDef, weapDef.lowAmmoWarningThreshold), CSPFT_FLOAT }, - {"ricochetChance", offsetof(WeaponFullDef, weapDef.ricochetChance), CSPFT_FLOAT }, - {"offhandHoldIsCancelable", offsetof(WeaponFullDef, weapDef.offhandHoldIsCancelable), CSPFT_BOOL }, - {"parallelDefaultBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_DEFAULT]), CSPFT_FLOAT }, - {"parallelBarkBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_BARK]), CSPFT_FLOAT }, - {"parallelBrickBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_BRICK]), CSPFT_FLOAT }, - {"parallelCarpetBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_CARPET]), CSPFT_FLOAT }, - {"parallelClothBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_CLOTH]), CSPFT_FLOAT }, - {"parallelConcreteBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_CONCRETE]), CSPFT_FLOAT }, - {"parallelDirtBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_DIRT]), CSPFT_FLOAT }, - {"parallelFleshBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_FLESH]), CSPFT_FLOAT }, - {"parallelFoliageBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_FOLIAGE]), CSPFT_FLOAT }, - {"parallelGlassBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_GLASS]), CSPFT_FLOAT }, - {"parallelGrassBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_GRASS]), CSPFT_FLOAT }, - {"parallelGravelBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_GRAVEL]), CSPFT_FLOAT }, - {"parallelIceBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_ICE]), CSPFT_FLOAT }, - {"parallelMetalBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_METAL]), CSPFT_FLOAT }, - {"parallelMudBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_MUD]), CSPFT_FLOAT }, - {"parallelPaperBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_PAPER]), CSPFT_FLOAT }, - {"parallelPlasterBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_PLASTER]), CSPFT_FLOAT }, - {"parallelRockBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_ROCK]), CSPFT_FLOAT }, - {"parallelSandBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_SAND]), CSPFT_FLOAT }, - {"parallelSnowBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_SNOW]), CSPFT_FLOAT }, - {"parallelWaterBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_WATER]), CSPFT_FLOAT }, - {"parallelWoodBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_WOOD]), CSPFT_FLOAT }, - {"parallelAsphaltBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_ASPHALT]), CSPFT_FLOAT }, - {"parallelCeramicBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_CERAMIC]), CSPFT_FLOAT }, - {"parallelPlasticBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_PLASTIC]), CSPFT_FLOAT }, - {"parallelRubberBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_RUBBER]), CSPFT_FLOAT }, - {"parallelCushionBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_CUSHION]), CSPFT_FLOAT }, - {"parallelFruitBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_FRUIT]), CSPFT_FLOAT }, - {"parallelPaintedMetalBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_PAINTED_METAL]), CSPFT_FLOAT }, - {"parallelRiotShieldBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_RIOT_SHIELD]), CSPFT_FLOAT }, - {"parallelSlushBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_SLUSH]), CSPFT_FLOAT }, - {"perpendicularDefaultBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_DEFAULT]), CSPFT_FLOAT }, - {"perpendicularBarkBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_BARK]), CSPFT_FLOAT }, - {"perpendicularBrickBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_BRICK]), CSPFT_FLOAT }, - {"perpendicularCarpetBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_CARPET]), CSPFT_FLOAT }, - {"perpendicularClothBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_CLOTH]), CSPFT_FLOAT }, - {"perpendicularConcreteBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_CONCRETE]), CSPFT_FLOAT }, - {"perpendicularDirtBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_DIRT]), CSPFT_FLOAT }, - {"perpendicularFleshBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_FLESH]), CSPFT_FLOAT }, - {"perpendicularFoliageBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_FOLIAGE]), CSPFT_FLOAT }, - {"perpendicularGlassBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_GLASS]), CSPFT_FLOAT }, - {"perpendicularGrassBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_GRASS]), CSPFT_FLOAT }, - {"perpendicularGravelBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_GRAVEL]), CSPFT_FLOAT }, - {"perpendicularIceBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_ICE]), CSPFT_FLOAT }, - {"perpendicularMetalBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_METAL]), CSPFT_FLOAT }, - {"perpendicularMudBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_MUD]), CSPFT_FLOAT }, - {"perpendicularPaperBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_PAPER]), CSPFT_FLOAT }, - {"perpendicularPlasterBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_PLASTER]), CSPFT_FLOAT }, - {"perpendicularRockBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_ROCK]), CSPFT_FLOAT }, - {"perpendicularSandBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_SAND]), CSPFT_FLOAT }, - {"perpendicularSnowBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_SNOW]), CSPFT_FLOAT }, - {"perpendicularWaterBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_WATER]), CSPFT_FLOAT }, - {"perpendicularWoodBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_WOOD]), CSPFT_FLOAT }, - {"perpendicularAsphaltBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_ASPHALT]), CSPFT_FLOAT }, - {"perpendicularCeramicBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_CERAMIC]), CSPFT_FLOAT }, - {"perpendicularPlasticBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_PLASTIC]), CSPFT_FLOAT }, - {"perpendicularRubberBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_RUBBER]), CSPFT_FLOAT }, - {"perpendicularCushionBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_CUSHION]), CSPFT_FLOAT }, - {"perpendicularFruitBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_FRUIT]), CSPFT_FLOAT }, - {"perpendicularPaintedMetalBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_PAINTED_METAL]), CSPFT_FLOAT }, - {"perpendicularRiotShieldBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_RIOT_SHIELD]), CSPFT_FLOAT }, - {"perpendicularSlushBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_SLUSH]), CSPFT_FLOAT }, - {"projTrailEffect", offsetof(WeaponFullDef, weapDef.projTrailEffect), CSPFT_FX }, - {"projBeaconEffect", offsetof(WeaponFullDef, weapDef.projBeaconEffect), CSPFT_FX }, - {"projectileRed", offsetof(WeaponFullDef, weapDef.vProjectileColor[0]), CSPFT_FLOAT }, - {"projectileGreen", offsetof(WeaponFullDef, weapDef.vProjectileColor[1]), CSPFT_FLOAT }, - {"projectileBlue", offsetof(WeaponFullDef, weapDef.vProjectileColor[2]), CSPFT_FLOAT }, - {"guidedMissileType", offsetof(WeaponFullDef, weapDef.guidedMissileType), WFT_GUIDED_MISSILE_TYPE }, - {"maxSteeringAccel", offsetof(WeaponFullDef, weapDef.maxSteeringAccel), CSPFT_FLOAT }, - {"projIgnitionDelay", offsetof(WeaponFullDef, weapDef.projIgnitionDelay), CSPFT_INT }, - {"projIgnitionEffect", offsetof(WeaponFullDef, weapDef.projIgnitionEffect), CSPFT_FX }, - {"projIgnitionSound", offsetof(WeaponFullDef, weapDef.projIgnitionSound), CSPFT_SOUND }, - {"adsTransInTime", offsetof(WeaponFullDef, weapCompleteDef.iAdsTransInTime), CSPFT_MILLISECONDS }, - {"adsTransOutTime", offsetof(WeaponFullDef, weapCompleteDef.iAdsTransOutTime), CSPFT_MILLISECONDS }, - {"adsIdleAmount", offsetof(WeaponFullDef, weapDef.fAdsIdleAmount), CSPFT_FLOAT }, - {"adsIdleSpeed", offsetof(WeaponFullDef, weapDef.adsIdleSpeed), CSPFT_FLOAT }, - {"adsZoomFov", offsetof(WeaponFullDef, weapCompleteDef.fAdsZoomFov), CSPFT_FLOAT }, - {"adsZoomInFrac", offsetof(WeaponFullDef, weapDef.fAdsZoomInFrac), CSPFT_FLOAT }, - {"adsZoomOutFrac", offsetof(WeaponFullDef, weapDef.fAdsZoomOutFrac), CSPFT_FLOAT }, - {"adsOverlayShader", offsetof(WeaponFullDef, weapDef.overlay.shader), CSPFT_MATERIAL }, - {"adsOverlayShaderLowRes", offsetof(WeaponFullDef, weapDef.overlay.shaderLowRes), CSPFT_MATERIAL }, - {"adsOverlayShaderEMP", offsetof(WeaponFullDef, weapDef.overlay.shaderEMP), CSPFT_MATERIAL }, - {"adsOverlayShaderEMPLowRes", offsetof(WeaponFullDef, weapDef.overlay.shaderEMPLowRes), CSPFT_MATERIAL }, - {"adsOverlayReticle", offsetof(WeaponFullDef, weapDef.overlay.reticle), WFT_OVERLAYRETICLE }, - {"adsOverlayInterface", offsetof(WeaponFullDef, weapDef.overlayInterface), WFT_OVERLAYINTERFACE }, - {"adsOverlayWidth", offsetof(WeaponFullDef, weapDef.overlay.width), CSPFT_FLOAT }, - {"adsOverlayHeight", offsetof(WeaponFullDef, weapDef.overlay.height), CSPFT_FLOAT }, - {"adsOverlayWidthSplitscreen", offsetof(WeaponFullDef, weapDef.overlay.widthSplitscreen), CSPFT_FLOAT }, - {"adsOverlayHeightSplitscreen", offsetof(WeaponFullDef, weapDef.overlay.heightSplitscreen), CSPFT_FLOAT }, - {"adsBobFactor", offsetof(WeaponFullDef, weapDef.fAdsBobFactor), CSPFT_FLOAT }, - {"adsViewBobMult", offsetof(WeaponFullDef, weapDef.fAdsViewBobMult), CSPFT_FLOAT }, - {"adsAimPitch", offsetof(WeaponFullDef, weapDef.fAdsAimPitch), CSPFT_FLOAT }, - {"adsCrosshairInFrac", offsetof(WeaponFullDef, weapDef.fAdsCrosshairInFrac), CSPFT_FLOAT }, - {"adsCrosshairOutFrac", offsetof(WeaponFullDef, weapDef.fAdsCrosshairOutFrac), CSPFT_FLOAT }, - {"adsReloadTransTime", offsetof(WeaponFullDef, weapDef.iPositionReloadTransTime), CSPFT_MILLISECONDS }, - {"adsGunKickReducedKickBullets", offsetof(WeaponFullDef, weapDef.adsGunKickReducedKickBullets), CSPFT_INT }, - {"adsGunKickReducedKickPercent", offsetof(WeaponFullDef, weapDef.adsGunKickReducedKickPercent), CSPFT_FLOAT }, - {"adsGunKickPitchMin", offsetof(WeaponFullDef, weapDef.fAdsGunKickPitchMin), CSPFT_FLOAT }, - {"adsGunKickPitchMax", offsetof(WeaponFullDef, weapDef.fAdsGunKickPitchMax), CSPFT_FLOAT }, - {"adsGunKickYawMin", offsetof(WeaponFullDef, weapDef.fAdsGunKickYawMin), CSPFT_FLOAT }, - {"adsGunKickYawMax", offsetof(WeaponFullDef, weapDef.fAdsGunKickYawMax), CSPFT_FLOAT }, - {"adsGunKickAccel", offsetof(WeaponFullDef, weapDef.fAdsGunKickAccel), CSPFT_FLOAT }, - {"adsGunKickSpeedMax", offsetof(WeaponFullDef, weapDef.fAdsGunKickSpeedMax), CSPFT_FLOAT }, - {"adsGunKickSpeedDecay", offsetof(WeaponFullDef, weapDef.fAdsGunKickSpeedDecay), CSPFT_FLOAT }, - {"adsGunKickStaticDecay", offsetof(WeaponFullDef, weapDef.fAdsGunKickStaticDecay), CSPFT_FLOAT }, - {"adsViewKickPitchMin", offsetof(WeaponFullDef, weapDef.fAdsViewKickPitchMin), CSPFT_FLOAT }, - {"adsViewKickPitchMax", offsetof(WeaponFullDef, weapDef.fAdsViewKickPitchMax), CSPFT_FLOAT }, - {"adsViewKickYawMin", offsetof(WeaponFullDef, weapDef.fAdsViewKickYawMin), CSPFT_FLOAT }, - {"adsViewKickYawMax", offsetof(WeaponFullDef, weapDef.fAdsViewKickYawMax), CSPFT_FLOAT }, - {"adsViewKickCenterSpeed", offsetof(WeaponFullDef, weapCompleteDef.fAdsViewKickCenterSpeed), CSPFT_FLOAT }, - {"adsSpread", offsetof(WeaponFullDef, weapDef.fAdsSpread), CSPFT_FLOAT }, - {"guidedMissileType", offsetof(WeaponFullDef, weapDef.guidedMissileType), WFT_GUIDED_MISSILE_TYPE }, - {"hipSpreadStandMin", offsetof(WeaponFullDef, weapDef.fHipSpreadStandMin), CSPFT_FLOAT }, - {"hipSpreadDuckedMin", offsetof(WeaponFullDef, weapDef.fHipSpreadDuckedMin), CSPFT_FLOAT }, - {"hipSpreadProneMin", offsetof(WeaponFullDef, weapDef.fHipSpreadProneMin), CSPFT_FLOAT }, - {"hipSpreadMax", offsetof(WeaponFullDef, weapDef.hipSpreadStandMax), CSPFT_FLOAT }, - {"hipSpreadDuckedMax", offsetof(WeaponFullDef, weapDef.hipSpreadDuckedMax), CSPFT_FLOAT }, - {"hipSpreadProneMax", offsetof(WeaponFullDef, weapDef.hipSpreadProneMax), CSPFT_FLOAT }, - {"hipSpreadDecayRate", offsetof(WeaponFullDef, weapDef.fHipSpreadDecayRate), CSPFT_FLOAT }, - {"hipSpreadFireAdd", offsetof(WeaponFullDef, weapDef.fHipSpreadFireAdd), CSPFT_FLOAT }, - {"hipSpreadTurnAdd", offsetof(WeaponFullDef, weapDef.fHipSpreadTurnAdd), CSPFT_FLOAT }, - {"hipSpreadMoveAdd", offsetof(WeaponFullDef, weapDef.fHipSpreadMoveAdd), CSPFT_FLOAT }, - {"hipSpreadDuckedDecay", offsetof(WeaponFullDef, weapDef.fHipSpreadDuckedDecay), CSPFT_FLOAT }, - {"hipSpreadProneDecay", offsetof(WeaponFullDef, weapDef.fHipSpreadProneDecay), CSPFT_FLOAT }, - {"hipReticleSidePos", offsetof(WeaponFullDef, weapDef.fHipReticleSidePos), CSPFT_FLOAT }, - {"hipIdleAmount", offsetof(WeaponFullDef, weapDef.fHipIdleAmount), CSPFT_FLOAT }, - {"hipIdleSpeed", offsetof(WeaponFullDef, weapDef.hipIdleSpeed), CSPFT_FLOAT }, - {"hipGunKickReducedKickBullets", offsetof(WeaponFullDef, weapDef.hipGunKickReducedKickBullets), CSPFT_INT }, - {"hipGunKickReducedKickPercent", offsetof(WeaponFullDef, weapDef.hipGunKickReducedKickPercent), CSPFT_FLOAT }, - {"hipGunKickPitchMin", offsetof(WeaponFullDef, weapDef.fHipGunKickPitchMin), CSPFT_FLOAT }, - {"hipGunKickPitchMax", offsetof(WeaponFullDef, weapDef.fHipGunKickPitchMax), CSPFT_FLOAT }, - {"hipGunKickYawMin", offsetof(WeaponFullDef, weapDef.fHipGunKickYawMin), CSPFT_FLOAT }, - {"hipGunKickYawMax", offsetof(WeaponFullDef, weapDef.fHipGunKickYawMax), CSPFT_FLOAT }, - {"hipGunKickAccel", offsetof(WeaponFullDef, weapDef.fHipGunKickAccel), CSPFT_FLOAT }, - {"hipGunKickSpeedMax", offsetof(WeaponFullDef, weapDef.fHipGunKickSpeedMax), CSPFT_FLOAT }, - {"hipGunKickSpeedDecay", offsetof(WeaponFullDef, weapDef.fHipGunKickSpeedDecay), CSPFT_FLOAT }, - {"hipGunKickStaticDecay", offsetof(WeaponFullDef, weapDef.fHipGunKickStaticDecay), CSPFT_FLOAT }, - {"hipViewKickPitchMin", offsetof(WeaponFullDef, weapDef.fHipViewKickPitchMin), CSPFT_FLOAT }, - {"hipViewKickPitchMax", offsetof(WeaponFullDef, weapDef.fHipViewKickPitchMax), CSPFT_FLOAT }, - {"hipViewKickYawMin", offsetof(WeaponFullDef, weapDef.fHipViewKickYawMin), CSPFT_FLOAT }, - {"hipViewKickYawMax", offsetof(WeaponFullDef, weapDef.fHipViewKickYawMax), CSPFT_FLOAT }, - {"hipViewKickCenterSpeed", offsetof(WeaponFullDef, weapCompleteDef.fHipViewKickCenterSpeed), CSPFT_FLOAT }, - {"leftArc", offsetof(WeaponFullDef, weapDef.leftArc), CSPFT_FLOAT }, - {"rightArc", offsetof(WeaponFullDef, weapDef.rightArc), CSPFT_FLOAT }, - {"topArc", offsetof(WeaponFullDef, weapDef.topArc), CSPFT_FLOAT }, - {"bottomArc", offsetof(WeaponFullDef, weapDef.bottomArc), CSPFT_FLOAT }, - {"accuracy", offsetof(WeaponFullDef, weapDef.accuracy), CSPFT_FLOAT }, - {"aiSpread", offsetof(WeaponFullDef, weapDef.aiSpread), CSPFT_FLOAT }, - {"playerSpread", offsetof(WeaponFullDef, weapDef.playerSpread), CSPFT_FLOAT }, - {"maxVertTurnSpeed", offsetof(WeaponFullDef, weapDef.maxTurnSpeed[0]), CSPFT_FLOAT }, - {"maxHorTurnSpeed", offsetof(WeaponFullDef, weapDef.maxTurnSpeed[1]), CSPFT_FLOAT }, - {"minVertTurnSpeed", offsetof(WeaponFullDef, weapDef.minTurnSpeed[0]), CSPFT_FLOAT }, - {"minHorTurnSpeed", offsetof(WeaponFullDef, weapDef.minTurnSpeed[1]), CSPFT_FLOAT }, - {"pitchConvergenceTime", offsetof(WeaponFullDef, weapDef.pitchConvergenceTime), CSPFT_FLOAT }, - {"yawConvergenceTime", offsetof(WeaponFullDef, weapDef.yawConvergenceTime), CSPFT_FLOAT }, - {"suppressionTime", offsetof(WeaponFullDef, weapDef.suppressTime), CSPFT_FLOAT }, - {"maxRange", offsetof(WeaponFullDef, weapDef.maxRange), CSPFT_FLOAT }, - {"animHorRotateInc", offsetof(WeaponFullDef, weapDef.fAnimHorRotateInc), CSPFT_FLOAT }, - {"playerPositionDist", offsetof(WeaponFullDef, weapDef.fPlayerPositionDist), CSPFT_FLOAT }, - {"stance", offsetof(WeaponFullDef, weapDef.stance), WFT_STANCE }, - {"useHintString", offsetof(WeaponFullDef, weapDef.szUseHintString), CSPFT_STRING }, - {"dropHintString", offsetof(WeaponFullDef, weapDef.dropHintString), CSPFT_STRING }, - {"horizViewJitter", offsetof(WeaponFullDef, weapDef.horizViewJitter), CSPFT_FLOAT }, - {"vertViewJitter", offsetof(WeaponFullDef, weapDef.vertViewJitter), CSPFT_FLOAT }, - {"scanSpeed", offsetof(WeaponFullDef, weapDef.scanSpeed), CSPFT_FLOAT }, - {"scanAccel", offsetof(WeaponFullDef, weapDef.scanAccel), CSPFT_FLOAT }, - {"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 }, - {"locNone", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_NONE]), CSPFT_FLOAT }, - {"locHelmet", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_HELMET]), CSPFT_FLOAT }, - {"locHead", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_HEAD]), CSPFT_FLOAT }, - {"locNeck", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_NECK]), CSPFT_FLOAT }, - {"locTorsoUpper", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_TORSO_UPR]), CSPFT_FLOAT }, - {"locTorsoLower", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_TORSO_LWR]), CSPFT_FLOAT }, - {"locRightArmUpper", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_ARM_UPR]), CSPFT_FLOAT }, - {"locRightArmLower", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_ARM_LWR]), CSPFT_FLOAT }, - {"locRightHand", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_HAND]), CSPFT_FLOAT }, - {"locLeftArmUpper", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_ARM_UPR]), CSPFT_FLOAT }, - {"locLeftArmLower", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_ARM_LWR]), CSPFT_FLOAT }, - {"locLeftHand", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_HAND]), CSPFT_FLOAT }, - {"locRightLegUpper", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_LEG_UPR]), CSPFT_FLOAT }, - {"locRightLegLower", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_LEG_LWR]), CSPFT_FLOAT }, - {"locRightFoot", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_FOOT]), CSPFT_FLOAT }, - {"locLeftLegUpper", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_LEG_UPR]), CSPFT_FLOAT }, - {"locLeftLegLower", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_LEG_LWR]), CSPFT_FLOAT }, - {"locLeftFoot", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_FOOT]), CSPFT_FLOAT }, - {"locGun", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_GUN]), CSPFT_FLOAT }, - {"fireRumble", offsetof(WeaponFullDef, weapDef.fireRumble), CSPFT_STRING }, - {"meleeImpactRumble", offsetof(WeaponFullDef, weapDef.meleeImpactRumble), CSPFT_STRING }, - {"tracerType", offsetof(WeaponFullDef, weapDef.tracerType), CSPFT_TRACER }, - {"adsDofStart", offsetof(WeaponFullDef, weapCompleteDef.adsDofStart), CSPFT_FLOAT }, - {"adsDofEnd", offsetof(WeaponFullDef, weapCompleteDef.adsDofEnd), CSPFT_FLOAT }, - {"turretScopeZoomRate", offsetof(WeaponFullDef, weapDef.turretScopeZoomRate), CSPFT_FLOAT }, - {"turretScopeZoomMin", offsetof(WeaponFullDef, weapDef.turretScopeZoomMin), CSPFT_FLOAT }, - {"turretScopeZoomMax", offsetof(WeaponFullDef, weapDef.turretScopeZoomMax), CSPFT_FLOAT }, - {"thermalScope", offsetof(WeaponFullDef, weapDef.thermalScope), CSPFT_BOOL }, - {"altModeSameWeapon", offsetof(WeaponFullDef, weapDef.altModeSameWeapon), CSPFT_BOOL }, - {"turretOverheatUpRate", offsetof(WeaponFullDef, weapDef.turretOverheatUpRate), CSPFT_FLOAT }, - {"turretOverheatDownRate", offsetof(WeaponFullDef, weapDef.turretOverheatDownRate), CSPFT_FLOAT }, - {"turretOverheatPenalty", offsetof(WeaponFullDef, weapDef.turretOverheatPenalty), CSPFT_FLOAT }, - {"turretOverheatSound", offsetof(WeaponFullDef, weapDef.turretOverheatSound), CSPFT_SOUND }, - {"turretOverheatEffect", offsetof(WeaponFullDef, weapDef.turretOverheatEffect), CSPFT_FX }, - {"turretBarrelSpinEnabled", offsetof(WeaponFullDef, weapDef.turretBarrelSpinEnabled), CSPFT_BOOL }, - {"turretBarrelSpinUpTime", offsetof(WeaponFullDef, weapDef.turretBarrelSpinUpTime), CSPFT_FLOAT }, - {"turretBarrelSpinDownTime", offsetof(WeaponFullDef, weapDef.turretBarrelSpinDownTime), CSPFT_FLOAT }, - {"turretBarrelSpinRumble", offsetof(WeaponFullDef, weapDef.turretBarrelSpinRumble), CSPFT_STRING }, - {"turretBarrelSpinSpeed", offsetof(WeaponFullDef, weapDef.turretBarrelSpinSpeed), CSPFT_FLOAT }, - {"turretBarrelSpinMaxSnd", offsetof(WeaponFullDef, weapDef.turretBarrelSpinMaxSnd), CSPFT_SOUND }, - {"turretBarrelSpinUpSnd1", offsetof(WeaponFullDef, weapDef.turretBarrelSpinUpSnd[0]), CSPFT_SOUND }, - {"turretBarrelSpinUpSnd2", offsetof(WeaponFullDef, weapDef.turretBarrelSpinUpSnd[1]), CSPFT_SOUND }, - {"turretBarrelSpinUpSnd3", offsetof(WeaponFullDef, weapDef.turretBarrelSpinUpSnd[2]), CSPFT_SOUND }, - {"turretBarrelSpinUpSnd4", offsetof(WeaponFullDef, weapDef.turretBarrelSpinUpSnd[3]), CSPFT_SOUND }, - {"turretBarrelSpinDownSnd1", offsetof(WeaponFullDef, weapDef.turretBarrelSpinDownSnd[0]), CSPFT_SOUND }, - {"turretBarrelSpinDownSnd2", offsetof(WeaponFullDef, weapDef.turretBarrelSpinDownSnd[1]), CSPFT_SOUND }, - {"turretBarrelSpinDownSnd3", offsetof(WeaponFullDef, weapDef.turretBarrelSpinDownSnd[2]), CSPFT_SOUND }, - {"turretBarrelSpinDownSnd4", offsetof(WeaponFullDef, weapDef.turretBarrelSpinDownSnd[3]), CSPFT_SOUND }, - {"missileConeSoundEnabled", offsetof(WeaponFullDef, weapDef.missileConeSoundEnabled), CSPFT_BOOL }, - {"missileConeSoundAlias", offsetof(WeaponFullDef, weapDef.missileConeSoundAlias), CSPFT_SOUND }, - {"missileConeSoundAliasAtBase", offsetof(WeaponFullDef, weapDef.missileConeSoundAliasAtBase), CSPFT_SOUND }, - {"missileConeSoundRadiusAtTop", offsetof(WeaponFullDef, weapDef.missileConeSoundRadiusAtTop), CSPFT_FLOAT }, - {"missileConeSoundRadiusAtBase", offsetof(WeaponFullDef, weapDef.missileConeSoundRadiusAtBase), CSPFT_FLOAT }, - {"missileConeSoundHeight", offsetof(WeaponFullDef, weapDef.missileConeSoundHeight), CSPFT_FLOAT }, - {"missileConeSoundOriginOffset", offsetof(WeaponFullDef, weapDef.missileConeSoundOriginOffset), CSPFT_FLOAT }, - {"missileConeSoundVolumescaleAtCore", offsetof(WeaponFullDef, weapDef.missileConeSoundVolumescaleAtCore), CSPFT_FLOAT }, - {"missileConeSoundVolumescaleAtEdge", offsetof(WeaponFullDef, weapDef.missileConeSoundVolumescaleAtEdge), CSPFT_FLOAT }, - {"missileConeSoundVolumescaleCoreSize", offsetof(WeaponFullDef, weapDef.missileConeSoundVolumescaleCoreSize), CSPFT_FLOAT }, - {"missileConeSoundPitchshiftEnabled", offsetof(WeaponFullDef, weapDef.missileConeSoundPitchshiftEnabled), CSPFT_BOOL }, - {"missileConeSoundPitchAtTop", offsetof(WeaponFullDef, weapDef.missileConeSoundPitchAtTop), CSPFT_FLOAT }, - {"missileConeSoundPitchAtBottom", offsetof(WeaponFullDef, weapDef.missileConeSoundPitchAtBottom), CSPFT_FLOAT }, - {"missileConeSoundPitchTopSize", offsetof(WeaponFullDef, weapDef.missileConeSoundPitchTopSize), CSPFT_FLOAT }, - {"missileConeSoundPitchBottomSize", offsetof(WeaponFullDef, weapDef.missileConeSoundPitchBottomSize), CSPFT_FLOAT }, - {"missileConeSoundCrossfadeEnabled", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeEnabled), CSPFT_BOOL }, - {"missileConeSoundCrossfadeTopSize", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeTopSize), CSPFT_FLOAT }, - {"missileConeSoundCrossfadeBottomSize", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeBottomSize), CSPFT_FLOAT }, - {"attachments", offsetof(WeaponFullDef, scopes), WFT_ATTACHMENT }, - {"animOverrides", offsetof(WeaponFullDef, weapCompleteDef.animOverrides), WFT_ANIM_OVERRIDES }, - {"soundOverrides", offsetof(WeaponFullDef, weapCompleteDef.soundOverrides), WFT_SOUND_OVERRIDES }, - {"fxOverrides", offsetof(WeaponFullDef, weapCompleteDef.fxOverrides), WFT_FX_OVERRIDES }, - {"reloadOverrides", offsetof(WeaponFullDef, weapCompleteDef.reloadOverrides), WFT_RELOAD_OVERRIDES }, - {"notetrackOverrides", offsetof(WeaponFullDef, weapCompleteDef.notetrackOverrides), WFT_NOTETRACK_OVERRIDES }, + {"displayName", offsetof(WeaponFullDef, weapCompleteDef.szDisplayName), CSPFT_STRING }, + {"AIOverlayDescription", offsetof(WeaponFullDef, weapDef.szOverlayName), CSPFT_STRING }, + {"modeName", offsetof(WeaponFullDef, weapDef.szModeName), CSPFT_STRING }, + {"playerAnimType", offsetof(WeaponFullDef, weapDef.playerAnimType), WFT_ANIMTYPE }, + {"gunModel", offsetof(WeaponFullDef, gunXModel[0]), CSPFT_XMODEL }, + {"gunModel2", offsetof(WeaponFullDef, gunXModel[1]), CSPFT_XMODEL }, + {"gunModel3", offsetof(WeaponFullDef, gunXModel[2]), CSPFT_XMODEL }, + {"gunModel4", offsetof(WeaponFullDef, gunXModel[3]), CSPFT_XMODEL }, + {"gunModel5", offsetof(WeaponFullDef, gunXModel[4]), CSPFT_XMODEL }, + {"gunModel6", offsetof(WeaponFullDef, gunXModel[5]), CSPFT_XMODEL }, + {"gunModel7", offsetof(WeaponFullDef, gunXModel[6]), CSPFT_XMODEL }, + {"gunModel8", offsetof(WeaponFullDef, gunXModel[7]), CSPFT_XMODEL }, + {"gunModel9", offsetof(WeaponFullDef, gunXModel[8]), CSPFT_XMODEL }, + {"gunModel10", offsetof(WeaponFullDef, gunXModel[9]), CSPFT_XMODEL }, + {"gunModel11", offsetof(WeaponFullDef, gunXModel[10]), CSPFT_XMODEL }, + {"gunModel12", offsetof(WeaponFullDef, gunXModel[11]), CSPFT_XMODEL }, + {"gunModel13", offsetof(WeaponFullDef, gunXModel[12]), CSPFT_XMODEL }, + {"gunModel14", offsetof(WeaponFullDef, gunXModel[13]), CSPFT_XMODEL }, + {"gunModel15", offsetof(WeaponFullDef, gunXModel[14]), CSPFT_XMODEL }, + {"gunModel16", offsetof(WeaponFullDef, gunXModel[15]), CSPFT_XMODEL }, + {"handModel", offsetof(WeaponFullDef, weapDef.handXModel), CSPFT_XMODEL }, + {"hideTags", offsetof(WeaponFullDef, hideTags), WFT_HIDETAGS }, + {"notetrackSoundMap", offsetof(WeaponFullDef, notetrackSoundMapKeys), WFT_NOTETRACKSOUNDMAP }, + {"notetrackRumbleMap", offsetof(WeaponFullDef, notetrackRumbleMapKeys), WFT_NOTETRACKRUMBLEMAP }, + {"idleAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_IDLE]), WFT_ANIM_NAME }, + {"emptyIdleAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_EMPTY_IDLE]), WFT_ANIM_NAME }, + {"fireAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_FIRE]), WFT_ANIM_NAME }, + {"holdFireAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_HOLD_FIRE]), WFT_ANIM_NAME }, + {"lastShotAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_LASTSHOT]), WFT_ANIM_NAME }, + {"detonateAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_DETONATE]), WFT_ANIM_NAME }, + {"rechamberAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RECHAMBER]), WFT_ANIM_NAME }, + {"meleeAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_MELEE]), WFT_ANIM_NAME }, + {"meleeChargeAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_MELEE_CHARGE]), WFT_ANIM_NAME }, + {"reloadAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RELOAD]), WFT_ANIM_NAME }, + {"reloadEmptyAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RELOAD_EMPTY]), WFT_ANIM_NAME }, + {"reloadStartAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RELOAD_START]), WFT_ANIM_NAME }, + {"reloadEndAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RELOAD_END]), WFT_ANIM_NAME }, + {"raiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_RAISE]), WFT_ANIM_NAME }, + {"dropAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_DROP]), WFT_ANIM_NAME }, + {"firstRaiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_FIRST_RAISE]), WFT_ANIM_NAME }, + {"breachRaiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_BREACH_RAISE]), WFT_ANIM_NAME }, + {"altRaiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ALT_RAISE]), WFT_ANIM_NAME }, + {"altDropAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ALT_DROP]), WFT_ANIM_NAME }, + {"quickRaiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_QUICK_RAISE]), WFT_ANIM_NAME }, + {"quickDropAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_QUICK_DROP]), WFT_ANIM_NAME }, + {"emptyRaiseAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_EMPTY_RAISE]), WFT_ANIM_NAME }, + {"emptyDropAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_EMPTY_DROP]), WFT_ANIM_NAME }, + {"sprintInAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_SPRINT_IN]), WFT_ANIM_NAME }, + {"sprintLoopAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_SPRINT_LOOP]), WFT_ANIM_NAME }, + {"sprintOutAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_SPRINT_OUT]), WFT_ANIM_NAME }, + {"stunnedAnimStart", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_STUNNED_START]), WFT_ANIM_NAME }, + {"stunnedAnimLoop", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_STUNNED_LOOP]), WFT_ANIM_NAME }, + {"stunnedAnimEnd", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_STUNNED_END]), WFT_ANIM_NAME }, + {"nightVisionWearAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_NIGHTVISION_WEAR]), WFT_ANIM_NAME }, + {"nightVisionRemoveAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_NIGHTVISION_REMOVE]), WFT_ANIM_NAME }, + {"adsFireAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ADS_FIRE]), WFT_ANIM_NAME }, + {"adsLastShotAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ADS_LASTSHOT]), WFT_ANIM_NAME }, + {"adsRechamberAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ADS_RECHAMBER]), WFT_ANIM_NAME }, + {"blastFrontAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_BLAST_FRONT]), WFT_ANIM_NAME }, + {"blastRightAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_BLAST_RIGHT]), WFT_ANIM_NAME }, + {"blastBackAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_BLAST_BACK]), WFT_ANIM_NAME }, + {"blastLeftAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_BLAST_LEFT]), WFT_ANIM_NAME }, + {"adsUpAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ADS_UP]), WFT_ANIM_NAME }, + {"adsDownAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ANIM_ADS_DOWN]), WFT_ANIM_NAME }, + {"altAdjustAnim", offsetof(WeaponFullDef, szXAnims[WEAP_ALT_ANIM_ADJUST]), WFT_ANIM_NAME }, + {"idleAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_IDLE]), WFT_ANIM_NAME }, + {"emptyIdleAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_EMPTY_IDLE]), WFT_ANIM_NAME }, + {"fireAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_FIRE]), WFT_ANIM_NAME }, + {"holdFireAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_HOLD_FIRE]), WFT_ANIM_NAME }, + {"lastShotAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_LASTSHOT]), WFT_ANIM_NAME }, + {"detonateAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_DETONATE]), WFT_ANIM_NAME }, + {"rechamberAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RECHAMBER]), WFT_ANIM_NAME }, + {"meleeAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_MELEE]), WFT_ANIM_NAME }, + {"meleeChargeAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_MELEE_CHARGE]), WFT_ANIM_NAME }, + {"reloadAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RELOAD]), WFT_ANIM_NAME }, + {"reloadEmptyAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RELOAD_EMPTY]), WFT_ANIM_NAME }, + {"reloadStartAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RELOAD_START]), WFT_ANIM_NAME }, + {"reloadEndAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RELOAD_END]), WFT_ANIM_NAME }, + {"raiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_RAISE]), WFT_ANIM_NAME }, + {"dropAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_DROP]), WFT_ANIM_NAME }, + {"firstRaiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_FIRST_RAISE]), WFT_ANIM_NAME }, + {"breachRaiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_BREACH_RAISE]), WFT_ANIM_NAME }, + {"altRaiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ALT_RAISE]), WFT_ANIM_NAME }, + {"altDropAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ALT_DROP]), WFT_ANIM_NAME }, + {"quickRaiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_QUICK_RAISE]), WFT_ANIM_NAME }, + {"quickDropAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_QUICK_DROP]), WFT_ANIM_NAME }, + {"emptyRaiseAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_EMPTY_RAISE]), WFT_ANIM_NAME }, + {"emptyDropAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_EMPTY_DROP]), WFT_ANIM_NAME }, + {"sprintInAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_SPRINT_IN]), WFT_ANIM_NAME }, + {"sprintLoopAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_SPRINT_LOOP]), WFT_ANIM_NAME }, + {"sprintOutAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_SPRINT_OUT]), WFT_ANIM_NAME }, + {"stunnedAnimStartR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_STUNNED_START]), WFT_ANIM_NAME }, + {"stunnedAnimLoopR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_STUNNED_LOOP]), WFT_ANIM_NAME }, + {"stunnedAnimEndR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_STUNNED_END]), WFT_ANIM_NAME }, + {"nightVisionWearAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_NIGHTVISION_WEAR]), WFT_ANIM_NAME }, + {"nightVisionRemoveAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_NIGHTVISION_REMOVE]), WFT_ANIM_NAME }, + {"adsFireAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ADS_FIRE]), WFT_ANIM_NAME }, + {"adsLastShotAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ADS_LASTSHOT]), WFT_ANIM_NAME }, + {"adsRechamberAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ADS_RECHAMBER]), WFT_ANIM_NAME }, + {"adsUpAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ADS_UP]), WFT_ANIM_NAME }, + {"blastFrontAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_BLAST_FRONT]), WFT_ANIM_NAME }, + {"blastRightAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_BLAST_RIGHT]), WFT_ANIM_NAME }, + {"blastBackAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_BLAST_BACK]), WFT_ANIM_NAME }, + {"blastLeftAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_BLAST_LEFT]), WFT_ANIM_NAME }, + {"adsDownAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ANIM_ADS_DOWN]), WFT_ANIM_NAME }, + {"altAdjustAnimR", offsetof(WeaponFullDef, szXAnimsRightHanded[WEAP_ALT_ANIM_ADJUST]), WFT_ANIM_NAME }, + {"idleAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_IDLE]), WFT_ANIM_NAME }, + {"emptyIdleAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_EMPTY_IDLE]), WFT_ANIM_NAME }, + {"fireAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_FIRE]), WFT_ANIM_NAME }, + {"holdFireAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_HOLD_FIRE]), WFT_ANIM_NAME }, + {"lastShotAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_LASTSHOT]), WFT_ANIM_NAME }, + {"detonateAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_DETONATE]), WFT_ANIM_NAME }, + {"rechamberAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RECHAMBER]), WFT_ANIM_NAME }, + {"meleeAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_MELEE]), WFT_ANIM_NAME }, + {"meleeChargeAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_MELEE_CHARGE]), WFT_ANIM_NAME }, + {"reloadAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RELOAD]), WFT_ANIM_NAME }, + {"reloadEmptyAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RELOAD_EMPTY]), WFT_ANIM_NAME }, + {"reloadStartAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RELOAD_START]), WFT_ANIM_NAME }, + {"reloadEndAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RELOAD_END]), WFT_ANIM_NAME }, + {"raiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_RAISE]), WFT_ANIM_NAME }, + {"dropAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_DROP]), WFT_ANIM_NAME }, + {"firstRaiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_FIRST_RAISE]), WFT_ANIM_NAME }, + {"breachRaiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_BREACH_RAISE]), WFT_ANIM_NAME }, + {"altRaiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ALT_RAISE]), WFT_ANIM_NAME }, + {"altDropAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ALT_DROP]), WFT_ANIM_NAME }, + {"quickRaiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_QUICK_RAISE]), WFT_ANIM_NAME }, + {"quickDropAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_QUICK_DROP]), WFT_ANIM_NAME }, + {"emptyRaiseAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_EMPTY_RAISE]), WFT_ANIM_NAME }, + {"emptyDropAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_EMPTY_DROP]), WFT_ANIM_NAME }, + {"sprintInAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_SPRINT_IN]), WFT_ANIM_NAME }, + {"sprintLoopAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_SPRINT_LOOP]), WFT_ANIM_NAME }, + {"sprintOutAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_SPRINT_OUT]), WFT_ANIM_NAME }, + {"stunnedAnimStartL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_STUNNED_START]), WFT_ANIM_NAME }, + {"stunnedAnimLoopL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_STUNNED_LOOP]), WFT_ANIM_NAME }, + {"stunnedAnimEndL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_STUNNED_END]), WFT_ANIM_NAME }, + {"nightVisionWearAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_NIGHTVISION_WEAR]), WFT_ANIM_NAME }, + {"nightVisionRemoveAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_NIGHTVISION_REMOVE]), WFT_ANIM_NAME }, + {"adsFireAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ADS_FIRE]), WFT_ANIM_NAME }, + {"adsLastShotAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ADS_LASTSHOT]), WFT_ANIM_NAME }, + {"adsRechamberAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ADS_RECHAMBER]), WFT_ANIM_NAME }, + {"blastFrontAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_BLAST_FRONT]), WFT_ANIM_NAME }, + {"blastRightAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_BLAST_RIGHT]), WFT_ANIM_NAME }, + {"blastBackAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_BLAST_BACK]), WFT_ANIM_NAME }, + {"blastLeftAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_BLAST_LEFT]), WFT_ANIM_NAME }, + {"adsUpAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ADS_UP]), WFT_ANIM_NAME }, + {"adsDownAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ANIM_ADS_DOWN]), WFT_ANIM_NAME }, + {"altAdjustAnimL", offsetof(WeaponFullDef, szXAnimsLeftHanded[WEAP_ALT_ANIM_ADJUST]), WFT_ANIM_NAME }, + {"script", offsetof(WeaponFullDef, weapDef.szScript), CSPFT_STRING }, + {"weaponType", offsetof(WeaponFullDef, weapDef.weapType), WFT_WEAPONTYPE }, + {"weaponClass", offsetof(WeaponFullDef, weapDef.weapClass), WFT_WEAPONCLASS }, + {"penetrateType", offsetof(WeaponFullDef, weapDef.penetrateType), WFT_PENETRATE_TYPE }, + {"penetrateMultiplier", offsetof(WeaponFullDef, weapCompleteDef.penetrateMultiplier), CSPFT_FLOAT }, + {"impactType", offsetof(WeaponFullDef, weapCompleteDef.impactType), WFT_IMPACT_TYPE }, + {"inventoryType", offsetof(WeaponFullDef, weapDef.inventoryType), WFT_INVENTORYTYPE }, + {"fireType", offsetof(WeaponFullDef, weapDef.fireType), WFT_FIRETYPE }, + {"offhandClass", offsetof(WeaponFullDef, weapDef.offhandClass), WFT_OFFHAND_CLASS }, + {"viewFlashEffect", offsetof(WeaponFullDef, weapDef.viewFlashEffect), CSPFT_FX }, + {"worldFlashEffect", offsetof(WeaponFullDef, weapDef.worldFlashEffect), CSPFT_FX }, + {"pickupSound", offsetof(WeaponFullDef, weapDef.pickupSound), CSPFT_SOUND }, + {"pickupSoundPlayer", offsetof(WeaponFullDef, weapDef.pickupSoundPlayer), CSPFT_SOUND }, + {"ammoPickupSound", offsetof(WeaponFullDef, weapDef.ammoPickupSound), CSPFT_SOUND }, + {"ammoPickupSoundPlayer", offsetof(WeaponFullDef, weapDef.ammoPickupSoundPlayer), CSPFT_SOUND }, + {"projectileSound", offsetof(WeaponFullDef, weapDef.projectileSound), CSPFT_SOUND }, + {"pullbackSound", offsetof(WeaponFullDef, weapDef.pullbackSound), CSPFT_SOUND }, + {"pullbackSoundPlayer", offsetof(WeaponFullDef, weapDef.pullbackSoundPlayer), CSPFT_SOUND }, + {"fireSound", offsetof(WeaponFullDef, weapDef.fireSound), CSPFT_SOUND }, + {"fireSoundPlayer", offsetof(WeaponFullDef, weapDef.fireSoundPlayer), CSPFT_SOUND }, + {"fireSoundPlayerAkimbo", offsetof(WeaponFullDef, weapDef.fireSoundPlayerAkimbo), CSPFT_SOUND }, + {"loopFireSound", offsetof(WeaponFullDef, weapDef.fireLoopSound), CSPFT_SOUND }, + {"loopFireSoundPlayer", offsetof(WeaponFullDef, weapDef.fireLoopSoundPlayer), CSPFT_SOUND }, + {"stopFireSound", offsetof(WeaponFullDef, weapDef.fireStopSound), CSPFT_SOUND }, + {"stopFireSoundPlayer", offsetof(WeaponFullDef, weapDef.fireStopSoundPlayer), CSPFT_SOUND }, + {"lastShotSound", offsetof(WeaponFullDef, weapDef.fireLastSound), CSPFT_SOUND }, + {"lastShotSoundPlayer", offsetof(WeaponFullDef, weapDef.fireLastSoundPlayer), CSPFT_SOUND }, + {"emptyFireSound", offsetof(WeaponFullDef, weapDef.emptyFireSound), CSPFT_SOUND }, + {"emptyFireSoundPlayer", offsetof(WeaponFullDef, weapDef.emptyFireSoundPlayer), CSPFT_SOUND }, + {"meleeSwipeSound", offsetof(WeaponFullDef, weapDef.meleeSwipeSound), CSPFT_SOUND }, + {"meleeSwipeSoundPlayer", offsetof(WeaponFullDef, weapDef.meleeSwipeSoundPlayer), CSPFT_SOUND }, + {"meleeHitSound", offsetof(WeaponFullDef, weapDef.meleeHitSound), CSPFT_SOUND }, + {"meleeMissSound", offsetof(WeaponFullDef, weapDef.meleeMissSound), CSPFT_SOUND }, + {"rechamberSound", offsetof(WeaponFullDef, weapDef.rechamberSound), CSPFT_SOUND }, + {"rechamberSoundPlayer", offsetof(WeaponFullDef, weapDef.rechamberSoundPlayer), CSPFT_SOUND }, + {"reloadSound", offsetof(WeaponFullDef, weapDef.reloadSound), CSPFT_SOUND }, + {"reloadSoundPlayer", offsetof(WeaponFullDef, weapDef.reloadSoundPlayer), CSPFT_SOUND }, + {"reloadEmptySound", offsetof(WeaponFullDef, weapDef.reloadEmptySound), CSPFT_SOUND }, + {"reloadEmptySoundPlayer", offsetof(WeaponFullDef, weapDef.reloadEmptySoundPlayer), CSPFT_SOUND }, + {"reloadStartSound", offsetof(WeaponFullDef, weapDef.reloadStartSound), CSPFT_SOUND }, + {"reloadStartSoundPlayer", offsetof(WeaponFullDef, weapDef.reloadStartSoundPlayer), CSPFT_SOUND }, + {"reloadEndSound", offsetof(WeaponFullDef, weapDef.reloadEndSound), CSPFT_SOUND }, + {"reloadEndSoundPlayer", offsetof(WeaponFullDef, weapDef.reloadEndSoundPlayer), CSPFT_SOUND }, + {"detonateSound", offsetof(WeaponFullDef, weapDef.detonateSound), CSPFT_SOUND }, + {"detonateSoundPlayer", offsetof(WeaponFullDef, weapDef.detonateSoundPlayer), CSPFT_SOUND }, + {"nightVisionWearSound", offsetof(WeaponFullDef, weapDef.nightVisionWearSound), CSPFT_SOUND }, + {"nightVisionWearSoundPlayer", offsetof(WeaponFullDef, weapDef.nightVisionWearSoundPlayer), CSPFT_SOUND }, + {"nightVisionRemoveSound", offsetof(WeaponFullDef, weapDef.nightVisionRemoveSound), CSPFT_SOUND }, + {"nightVisionRemoveSoundPlayer", offsetof(WeaponFullDef, weapDef.nightVisionRemoveSoundPlayer), CSPFT_SOUND }, + {"raiseSound", offsetof(WeaponFullDef, weapDef.raiseSound), CSPFT_SOUND }, + {"raiseSoundPlayer", offsetof(WeaponFullDef, weapDef.raiseSoundPlayer), CSPFT_SOUND }, + {"firstRaiseSound", offsetof(WeaponFullDef, weapDef.firstRaiseSound), CSPFT_SOUND }, + {"firstRaiseSoundPlayer", offsetof(WeaponFullDef, weapDef.firstRaiseSoundPlayer), CSPFT_SOUND }, + {"altSwitchSound", offsetof(WeaponFullDef, weapDef.altSwitchSound), CSPFT_SOUND }, + {"altSwitchSoundPlayer", offsetof(WeaponFullDef, weapDef.altSwitchSoundPlayer), CSPFT_SOUND }, + {"putawaySound", offsetof(WeaponFullDef, weapDef.putawaySound), CSPFT_SOUND }, + {"putawaySoundPlayer", offsetof(WeaponFullDef, weapDef.putawaySoundPlayer), CSPFT_SOUND }, + {"scanSound", offsetof(WeaponFullDef, weapDef.scanSound), CSPFT_SOUND }, + {"changeVariableZoomSound", offsetof(WeaponFullDef, weapDef.changeVariableZoomSound), CSPFT_SOUND }, + {"bounceSound", offsetof(WeaponFullDef, weapDef.bounceSound), WFT_PER_SURFACE_TYPE_SOUND}, + {"rollingSound", offsetof(WeaponFullDef, weapDef.rollingSound), WFT_PER_SURFACE_TYPE_SOUND}, + {"viewShellEjectEffect", offsetof(WeaponFullDef, weapDef.viewShellEjectEffect), CSPFT_FX }, + {"worldShellEjectEffect", offsetof(WeaponFullDef, weapDef.worldShellEjectEffect), CSPFT_FX }, + {"viewLastShotEjectEffect", offsetof(WeaponFullDef, weapDef.viewLastShotEjectEffect), CSPFT_FX }, + {"worldLastShotEjectEffect", offsetof(WeaponFullDef, weapDef.worldLastShotEjectEffect), CSPFT_FX }, + {"reticleCenter", offsetof(WeaponFullDef, weapDef.reticleCenter), CSPFT_MATERIAL }, + {"reticleSide", offsetof(WeaponFullDef, weapDef.reticleSide), CSPFT_MATERIAL }, + {"reticleCenterSize", offsetof(WeaponFullDef, weapDef.iReticleCenterSize), CSPFT_INT }, + {"reticleSideSize", offsetof(WeaponFullDef, weapDef.iReticleSideSize), CSPFT_INT }, + {"reticleMinOfs", offsetof(WeaponFullDef, weapDef.iReticleMinOfs), CSPFT_INT }, + {"activeReticleType", offsetof(WeaponFullDef, weapDef.activeReticleType), WFT_ACTIVE_RETICLE_TYPE }, + {"standMoveF", offsetof(WeaponFullDef, weapDef.vStandMove[0]), CSPFT_FLOAT }, + {"standMoveR", offsetof(WeaponFullDef, weapDef.vStandMove[1]), CSPFT_FLOAT }, + {"standMoveU", offsetof(WeaponFullDef, weapDef.vStandMove[2]), CSPFT_FLOAT }, + {"standRotP", offsetof(WeaponFullDef, weapDef.vStandRot[0]), CSPFT_FLOAT }, + {"standRotY", offsetof(WeaponFullDef, weapDef.vStandRot[1]), CSPFT_FLOAT }, + {"standRotR", offsetof(WeaponFullDef, weapDef.vStandRot[2]), CSPFT_FLOAT }, + {"strafeMoveF", offsetof(WeaponFullDef, weapDef.strafeMove[0]), CSPFT_FLOAT }, + {"strafeMoveR", offsetof(WeaponFullDef, weapDef.strafeMove[1]), CSPFT_FLOAT }, + {"strafeMoveU", offsetof(WeaponFullDef, weapDef.strafeMove[2]), CSPFT_FLOAT }, + {"strafeRotP", offsetof(WeaponFullDef, weapDef.strafeRot[0]), CSPFT_FLOAT }, + {"strafeRotY", offsetof(WeaponFullDef, weapDef.strafeRot[1]), CSPFT_FLOAT }, + {"strafeRotR", offsetof(WeaponFullDef, weapDef.strafeRot[2]), CSPFT_FLOAT }, + {"duckedOfsF", offsetof(WeaponFullDef, weapDef.vDuckedOfs[0]), CSPFT_FLOAT }, + {"duckedOfsR", offsetof(WeaponFullDef, weapDef.vDuckedOfs[1]), CSPFT_FLOAT }, + {"duckedOfsU", offsetof(WeaponFullDef, weapDef.vDuckedOfs[2]), CSPFT_FLOAT }, + {"duckedMoveF", offsetof(WeaponFullDef, weapDef.vDuckedMove[0]), CSPFT_FLOAT }, + {"duckedMoveR", offsetof(WeaponFullDef, weapDef.vDuckedMove[1]), CSPFT_FLOAT }, + {"duckedMoveU", offsetof(WeaponFullDef, weapDef.vDuckedMove[2]), CSPFT_FLOAT }, + {"duckedRotP", offsetof(WeaponFullDef, weapDef.vDuckedRot[0]), CSPFT_FLOAT }, + {"duckedRotY", offsetof(WeaponFullDef, weapDef.vDuckedRot[1]), CSPFT_FLOAT }, + {"duckedRotR", offsetof(WeaponFullDef, weapDef.vDuckedRot[2]), CSPFT_FLOAT }, + {"proneOfsF", offsetof(WeaponFullDef, weapDef.vProneOfs[0]), CSPFT_FLOAT }, + {"proneOfsR", offsetof(WeaponFullDef, weapDef.vProneOfs[1]), CSPFT_FLOAT }, + {"proneOfsU", offsetof(WeaponFullDef, weapDef.vProneOfs[2]), CSPFT_FLOAT }, + {"proneMoveF", offsetof(WeaponFullDef, weapDef.vProneMove[0]), CSPFT_FLOAT }, + {"proneMoveR", offsetof(WeaponFullDef, weapDef.vProneMove[1]), CSPFT_FLOAT }, + {"proneMoveU", offsetof(WeaponFullDef, weapDef.vProneMove[2]), CSPFT_FLOAT }, + {"proneRotP", offsetof(WeaponFullDef, weapDef.vProneRot[0]), CSPFT_FLOAT }, + {"proneRotY", offsetof(WeaponFullDef, weapDef.vProneRot[1]), CSPFT_FLOAT }, + {"proneRotR", offsetof(WeaponFullDef, weapDef.vProneRot[2]), CSPFT_FLOAT }, + {"posMoveRate", offsetof(WeaponFullDef, weapDef.fPosMoveRate), CSPFT_FLOAT }, + {"posProneMoveRate", offsetof(WeaponFullDef, weapDef.fPosProneMoveRate), CSPFT_FLOAT }, + {"standMoveMinSpeed", offsetof(WeaponFullDef, weapDef.fStandMoveMinSpeed), CSPFT_FLOAT }, + {"duckedMoveMinSpeed", offsetof(WeaponFullDef, weapDef.fDuckedMoveMinSpeed), CSPFT_FLOAT }, + {"proneMoveMinSpeed", offsetof(WeaponFullDef, weapDef.fProneMoveMinSpeed), CSPFT_FLOAT }, + {"posRotRate", offsetof(WeaponFullDef, weapDef.fPosRotRate), CSPFT_FLOAT }, + {"posProneRotRate", offsetof(WeaponFullDef, weapDef.fPosProneRotRate), CSPFT_FLOAT }, + {"standRotMinSpeed", offsetof(WeaponFullDef, weapDef.fStandRotMinSpeed), CSPFT_FLOAT }, + {"duckedRotMinSpeed", offsetof(WeaponFullDef, weapDef.fDuckedRotMinSpeed), CSPFT_FLOAT }, + {"proneRotMinSpeed", offsetof(WeaponFullDef, weapDef.fProneRotMinSpeed), CSPFT_FLOAT }, + {"worldModel", offsetof(WeaponFullDef, worldModel[0]), CSPFT_XMODEL }, + {"worldModel2", offsetof(WeaponFullDef, worldModel[1]), CSPFT_XMODEL }, + {"worldModel3", offsetof(WeaponFullDef, worldModel[2]), CSPFT_XMODEL }, + {"worldModel4", offsetof(WeaponFullDef, worldModel[3]), CSPFT_XMODEL }, + {"worldModel5", offsetof(WeaponFullDef, worldModel[4]), CSPFT_XMODEL }, + {"worldModel6", offsetof(WeaponFullDef, worldModel[5]), CSPFT_XMODEL }, + {"worldModel7", offsetof(WeaponFullDef, worldModel[6]), CSPFT_XMODEL }, + {"worldModel8", offsetof(WeaponFullDef, worldModel[7]), CSPFT_XMODEL }, + {"worldModel9", offsetof(WeaponFullDef, worldModel[8]), CSPFT_XMODEL }, + {"worldModel10", offsetof(WeaponFullDef, worldModel[9]), CSPFT_XMODEL }, + {"worldModel11", offsetof(WeaponFullDef, worldModel[10]), CSPFT_XMODEL }, + {"worldModel12", offsetof(WeaponFullDef, worldModel[11]), CSPFT_XMODEL }, + {"worldModel13", offsetof(WeaponFullDef, worldModel[12]), CSPFT_XMODEL }, + {"worldModel14", offsetof(WeaponFullDef, worldModel[13]), CSPFT_XMODEL }, + {"worldModel15", offsetof(WeaponFullDef, worldModel[14]), CSPFT_XMODEL }, + {"worldModel16", offsetof(WeaponFullDef, worldModel[15]), CSPFT_XMODEL }, + {"worldClipModel", offsetof(WeaponFullDef, weapDef.worldClipModel), CSPFT_XMODEL }, + {"rocketModel", offsetof(WeaponFullDef, weapDef.rocketModel), CSPFT_XMODEL }, + {"knifeModel", offsetof(WeaponFullDef, weapDef.knifeModel), CSPFT_XMODEL }, + {"worldKnifeModel", offsetof(WeaponFullDef, weapDef.worldKnifeModel), CSPFT_XMODEL }, + {"hudIcon", offsetof(WeaponFullDef, weapDef.hudIcon), CSPFT_MATERIAL }, + {"hudIconRatio", offsetof(WeaponFullDef, weapDef.hudIconRatio), WFT_ICONRATIO_HUD }, + {"pickupIcon", offsetof(WeaponFullDef, weapDef.pickupIcon), CSPFT_MATERIAL }, + {"pickupIconRatio", offsetof(WeaponFullDef, weapDef.pickupIconRatio), WFT_ICONRATIO_PICKUP }, + {"ammoCounterIcon", offsetof(WeaponFullDef, weapDef.ammoCounterIcon), CSPFT_MATERIAL }, + {"ammoCounterIconRatio", offsetof(WeaponFullDef, weapDef.ammoCounterIconRatio), WFT_ICONRATIO_AMMOCOUNTER }, + {"ammoCounterClip", offsetof(WeaponFullDef, weapDef.ammoCounterClip), WFT_AMMOCOUNTER_CLIPTYPE }, + {"startAmmo", offsetof(WeaponFullDef, weapDef.iStartAmmo), CSPFT_INT }, + {"shareAmmo", offsetof(WeaponFullDef, weapDef.sharedAmmo), CSPFT_BOOL }, + {"ammoName", offsetof(WeaponFullDef, weapDef.szAmmoName), CSPFT_STRING }, + {"clipName", offsetof(WeaponFullDef, weapDef.szClipName), CSPFT_STRING }, + {"maxAmmo", offsetof(WeaponFullDef, weapDef.iMaxAmmo), CSPFT_INT }, + {"clipSize", offsetof(WeaponFullDef, weapCompleteDef.iClipSize), CSPFT_INT }, + {"shotCount", offsetof(WeaponFullDef, weapDef.shotCount), CSPFT_INT }, + {"sharedAmmoCapName", offsetof(WeaponFullDef, weapDef.szSharedAmmoCapName), CSPFT_STRING }, + {"sharedAmmoCap", offsetof(WeaponFullDef, weapDef.iSharedAmmoCap), CSPFT_INT }, + {"damage", offsetof(WeaponFullDef, weapDef.damage), CSPFT_INT }, + {"playerDamage", offsetof(WeaponFullDef, weapDef.playerDamage), CSPFT_INT }, + {"meleeDamage", offsetof(WeaponFullDef, weapDef.iMeleeDamage), CSPFT_INT }, + {"minDamage", offsetof(WeaponFullDef, weapDef.minDamage), CSPFT_INT }, + {"minPlayerDamage", offsetof(WeaponFullDef, weapDef.minPlayerDamage), CSPFT_INT }, + {"maxDamageRange", offsetof(WeaponFullDef, weapDef.fMaxDamageRange), CSPFT_FLOAT }, + {"minDamageRange", offsetof(WeaponFullDef, weapDef.fMinDamageRange), CSPFT_FLOAT }, + {"destabilizationRateTime", offsetof(WeaponFullDef, weapDef.destabilizationRateTime), CSPFT_FLOAT }, + {"destabilizationCurvatureMax", offsetof(WeaponFullDef, weapDef.destabilizationCurvatureMax), CSPFT_FLOAT }, + {"destabilizeDistance", offsetof(WeaponFullDef, weapDef.destabilizeDistance), CSPFT_INT }, + {"fireTime", offsetof(WeaponFullDef, weapCompleteDef.iFireTime), CSPFT_MILLISECONDS }, + {"fireTimeAkimbo", offsetof(WeaponFullDef, weapCompleteDef.iFireTimeAkimbo), CSPFT_MILLISECONDS }, + {"altRaiseTime", offsetof(WeaponFullDef, weapCompleteDef.iAltRaiseTime), CSPFT_MILLISECONDS }, + {"altRaiseTimeAkimbo", offsetof(WeaponFullDef, weapCompleteDef.iAltRaiseTimeAkimbo), CSPFT_MILLISECONDS }, + {"firstRaiseTime", offsetof(WeaponFullDef, weapCompleteDef.iFirstRaiseTime), CSPFT_MILLISECONDS }, + {"firstRaiseTimeAkimbo", offsetof(WeaponFullDef, weapCompleteDef.iFirstRaiseTimeAkimbo), CSPFT_MILLISECONDS }, + {"fireDelay", offsetof(WeaponFullDef, weapDef.stateTimers.iFireDelay), CSPFT_MILLISECONDS }, + {"meleeDelay", offsetof(WeaponFullDef, weapDef.stateTimers.iMeleeDelay), CSPFT_MILLISECONDS }, + {"meleeChargeDelay", offsetof(WeaponFullDef, weapDef.stateTimers.meleeChargeDelay), CSPFT_MILLISECONDS }, + {"rechamberTime", offsetof(WeaponFullDef, weapDef.stateTimers.iRechamberTime), CSPFT_MILLISECONDS }, + {"rechamberTimeOneHanded", offsetof(WeaponFullDef, weapDef.stateTimers.rechamberTimeOneHanded), CSPFT_MILLISECONDS }, + {"rechamberBoltTime", offsetof(WeaponFullDef, weapDef.stateTimers.iRechamberBoltTime), CSPFT_MILLISECONDS }, + {"holdFireTime", offsetof(WeaponFullDef, weapDef.stateTimers.iHoldFireTime), CSPFT_MILLISECONDS }, + {"detonateTime", offsetof(WeaponFullDef, weapDef.stateTimers.iDetonateTime), CSPFT_MILLISECONDS }, + {"detonateDelay", offsetof(WeaponFullDef, weapDef.stateTimers.iDetonateDelay), CSPFT_MILLISECONDS }, + {"meleeTime", offsetof(WeaponFullDef, weapDef.stateTimers.iMeleeTime), CSPFT_MILLISECONDS }, + {"meleeChargeTime", offsetof(WeaponFullDef, weapDef.stateTimers.meleeChargeTime), CSPFT_MILLISECONDS }, + {"reloadTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadTime), CSPFT_MILLISECONDS }, + {"reloadShowRocketTime", offsetof(WeaponFullDef, weapDef.stateTimers.reloadShowRocketTime), CSPFT_MILLISECONDS }, + {"reloadEmptyTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadEmptyTime), CSPFT_MILLISECONDS }, + {"reloadAddTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadAddTime), CSPFT_MILLISECONDS }, + {"reloadStartTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadStartTime), CSPFT_MILLISECONDS }, + {"reloadStartAddTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadStartAddTime), CSPFT_MILLISECONDS }, + {"reloadEndTime", offsetof(WeaponFullDef, weapDef.stateTimers.iReloadEndTime), CSPFT_MILLISECONDS }, + {"dropTime", offsetof(WeaponFullDef, weapDef.stateTimers.iDropTime), CSPFT_MILLISECONDS }, + {"raiseTime", offsetof(WeaponFullDef, weapDef.stateTimers.iRaiseTime), CSPFT_MILLISECONDS }, + {"altDropTime", offsetof(WeaponFullDef, weapDef.stateTimers.iAltDropTime), CSPFT_MILLISECONDS }, + {"quickDropTime", offsetof(WeaponFullDef, weapDef.stateTimers.quickDropTime), CSPFT_MILLISECONDS }, + {"quickRaiseTime", offsetof(WeaponFullDef, weapDef.stateTimers.quickRaiseTime), CSPFT_MILLISECONDS }, + {"breachRaiseTime", offsetof(WeaponFullDef, weapDef.stateTimers.iBreachRaiseTime), CSPFT_MILLISECONDS }, + {"emptyRaiseTime", offsetof(WeaponFullDef, weapDef.stateTimers.iEmptyRaiseTime), CSPFT_MILLISECONDS }, + {"emptyDropTime", offsetof(WeaponFullDef, weapDef.stateTimers.iEmptyDropTime), CSPFT_MILLISECONDS }, + {"sprintInTime", offsetof(WeaponFullDef, weapDef.stateTimers.sprintInTime), CSPFT_MILLISECONDS }, + {"sprintLoopTime", offsetof(WeaponFullDef, weapDef.stateTimers.sprintLoopTime), CSPFT_MILLISECONDS }, + {"sprintOutTime", offsetof(WeaponFullDef, weapDef.stateTimers.sprintOutTime), CSPFT_MILLISECONDS }, + {"stunnedTimeBegin", offsetof(WeaponFullDef, weapDef.stateTimers.stunnedTimeBegin), CSPFT_MILLISECONDS }, + {"stunnedTimeLoop", offsetof(WeaponFullDef, weapDef.stateTimers.stunnedTimeLoop), CSPFT_MILLISECONDS }, + {"stunnedTimeEnd", offsetof(WeaponFullDef, weapDef.stateTimers.stunnedTimeEnd), CSPFT_MILLISECONDS }, + {"nightVisionWearTime", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionWearTime), CSPFT_MILLISECONDS }, + {"nightVisionWearTimeFadeOutEnd", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionWearTimeFadeOutEnd), CSPFT_MILLISECONDS }, + {"nightVisionWearTimePowerUp", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionWearTimePowerUp), CSPFT_MILLISECONDS }, + {"nightVisionRemoveTime", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionRemoveTime), CSPFT_MILLISECONDS }, + {"nightVisionRemoveTimePowerDown", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionRemoveTimePowerDown), CSPFT_MILLISECONDS }, + {"nightVisionRemoveTimeFadeInStart", offsetof(WeaponFullDef, weapDef.stateTimers.nightVisionRemoveTimeFadeInStart), CSPFT_MILLISECONDS }, + {"fuseTime", offsetof(WeaponFullDef, weapDef.stateTimers.fuseTime), CSPFT_MILLISECONDS }, + {"aifuseTime", offsetof(WeaponFullDef, weapDef.stateTimers.aiFuseTime), CSPFT_MILLISECONDS }, + {"blastFrontTime", offsetof(WeaponFullDef, weapDef.stateTimers.blastFrontTime), CSPFT_MILLISECONDS }, + {"blastRightTime", offsetof(WeaponFullDef, weapDef.stateTimers.blastRightTime), CSPFT_MILLISECONDS }, + {"blastBackTime", offsetof(WeaponFullDef, weapDef.stateTimers.blastBackTime), CSPFT_MILLISECONDS }, + {"blastLeftTime", offsetof(WeaponFullDef, weapDef.stateTimers.blastLeftTime), CSPFT_MILLISECONDS }, + {"raiseInterruptableTime", offsetof(WeaponFullDef, weapDef.stateTimers.raiseInterruptableTime), CSPFT_MILLISECONDS }, + {"firstRaiseInterruptableTime", offsetof(WeaponFullDef, weapDef.stateTimers.firstRaiseInterruptableTime), CSPFT_MILLISECONDS }, + {"reloadInterruptableTime", offsetof(WeaponFullDef, weapDef.stateTimers.reloadInterruptableTime), CSPFT_MILLISECONDS }, + {"reloadEmptyInterruptableTime", offsetof(WeaponFullDef, weapDef.stateTimers.reloadEmptyInterruptableTime), CSPFT_MILLISECONDS }, + {"fireInterruptableTime", offsetof(WeaponFullDef, weapDef.stateTimers.fireInterruptableTime), CSPFT_MILLISECONDS }, + {"fireDelayAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iFireDelay), CSPFT_MILLISECONDS }, + {"meleeDelayAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iMeleeDelay), CSPFT_MILLISECONDS }, + {"meleeChargeDelayAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.meleeChargeDelay), CSPFT_MILLISECONDS }, + {"rechamberTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iRechamberTime), CSPFT_MILLISECONDS }, + {"rechamberTimeOneHandedAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.rechamberTimeOneHanded), CSPFT_MILLISECONDS }, + {"rechamberBoltTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iRechamberBoltTime), CSPFT_MILLISECONDS }, + {"holdFireTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iHoldFireTime), CSPFT_MILLISECONDS }, + {"detonateTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iDetonateTime), CSPFT_MILLISECONDS }, + {"detonateDelayAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iDetonateDelay), CSPFT_MILLISECONDS }, + {"meleeTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iMeleeTime), CSPFT_MILLISECONDS }, + {"meleeChargeTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.meleeChargeTime), CSPFT_MILLISECONDS }, + {"reloadTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iReloadTime), CSPFT_MILLISECONDS }, + {"reloadShowRocketTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.reloadShowRocketTime), CSPFT_MILLISECONDS }, + {"reloadEmptyTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iReloadEmptyTime), CSPFT_MILLISECONDS }, + {"reloadAddTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iReloadAddTime), CSPFT_MILLISECONDS }, + {"reloadStartTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iReloadStartTime), CSPFT_MILLISECONDS }, + {"reloadStartAddTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iReloadStartAddTime), CSPFT_MILLISECONDS }, + {"reloadEndTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iReloadEndTime), CSPFT_MILLISECONDS }, + {"dropTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iDropTime), CSPFT_MILLISECONDS }, + {"raiseTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iRaiseTime), CSPFT_MILLISECONDS }, + {"altDropTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iAltDropTime), CSPFT_MILLISECONDS }, + {"quickDropTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.quickDropTime), CSPFT_MILLISECONDS }, + {"quickRaiseTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.quickRaiseTime), CSPFT_MILLISECONDS }, + {"breachRaiseTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iBreachRaiseTime), CSPFT_MILLISECONDS }, + {"emptyRaiseTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iEmptyRaiseTime), CSPFT_MILLISECONDS }, + {"emptyDropTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.iEmptyDropTime), CSPFT_MILLISECONDS }, + {"sprintInTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.sprintInTime), CSPFT_MILLISECONDS }, + {"sprintLoopTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.sprintLoopTime), CSPFT_MILLISECONDS }, + {"sprintOutTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.sprintOutTime), CSPFT_MILLISECONDS }, + {"stunnedTimeBeginAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.stunnedTimeBegin), CSPFT_MILLISECONDS }, + {"stunnedTimeLoopAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.stunnedTimeLoop), CSPFT_MILLISECONDS }, + {"stunnedTimeEndAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.stunnedTimeEnd), CSPFT_MILLISECONDS }, + {"nightVisionWearTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.nightVisionWearTime), CSPFT_MILLISECONDS }, + {"nightVisionWearTimeFadeOutEndAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.nightVisionWearTimeFadeOutEnd), CSPFT_MILLISECONDS }, + {"nightVisionWearTimePowerUpAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.nightVisionWearTimePowerUp), CSPFT_MILLISECONDS }, + {"nightVisionRemoveTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.nightVisionRemoveTime), CSPFT_MILLISECONDS }, + {"nightVisionRemoveTimePowerDownAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.nightVisionRemoveTimePowerDown), CSPFT_MILLISECONDS }, + {"nightVisionRemoveTimeFadeInStartAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.nightVisionRemoveTimeFadeInStart), CSPFT_MILLISECONDS }, + {"fuseTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.fuseTime), CSPFT_MILLISECONDS }, + {"aifuseTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.aiFuseTime), CSPFT_MILLISECONDS }, + {"blastFrontTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.blastFrontTime), CSPFT_MILLISECONDS }, + {"blastRightTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.blastRightTime), CSPFT_MILLISECONDS }, + {"blastBackTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.blastBackTime), CSPFT_MILLISECONDS }, + {"blastLeftTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.blastLeftTime), CSPFT_MILLISECONDS }, + {"raiseInterruptableTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.raiseInterruptableTime), CSPFT_MILLISECONDS }, + {"firstRaiseInterruptableTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.firstRaiseInterruptableTime), CSPFT_MILLISECONDS }, + {"reloadInterruptableTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.reloadInterruptableTime), CSPFT_MILLISECONDS }, + {"reloadEmptyInterruptableTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.reloadEmptyInterruptableTime), CSPFT_MILLISECONDS }, + {"fireInterruptableTimeAkimbo", offsetof(WeaponFullDef, weapDef.akimboStateTimers.fireInterruptableTime), CSPFT_MILLISECONDS }, + {"lockonSupported", offsetof(WeaponFullDef, weapDef.lockonSupported), CSPFT_BOOL }, + {"requireLockonToFire", offsetof(WeaponFullDef, weapDef.requireLockonToFire), CSPFT_BOOL }, + {"isAirburstWeapon", offsetof(WeaponFullDef, weapDef.isAirburstWeapon), CSPFT_BOOL }, + {"bigExplosion", offsetof(WeaponFullDef, weapDef.bigExplosion), CSPFT_BOOL }, + {"noAdsWhenMagEmpty", offsetof(WeaponFullDef, weapDef.noAdsWhenMagEmpty), CSPFT_BOOL }, + {"inheritsPerks", offsetof(WeaponFullDef, weapDef.inheritsPerks), CSPFT_BOOL }, + {"avoidDropCleanup", offsetof(WeaponFullDef, weapDef.avoidDropCleanup), CSPFT_BOOL }, + {"autoAimRange", offsetof(WeaponFullDef, weapDef.autoAimRange), CSPFT_FLOAT }, + {"aimAssistRange", offsetof(WeaponFullDef, weapDef.aimAssistRange), CSPFT_FLOAT }, + {"aimAssistRangeAds", offsetof(WeaponFullDef, weapDef.aimAssistRangeAds), CSPFT_FLOAT }, + {"aimPadding", offsetof(WeaponFullDef, weapDef.aimPadding), CSPFT_FLOAT }, + {"enemyCrosshairRange", offsetof(WeaponFullDef, weapDef.enemyCrosshairRange), CSPFT_FLOAT }, + {"crosshairColorChange", offsetof(WeaponFullDef, weapDef.crosshairColorChange), CSPFT_BOOL }, + {"moveSpeedScale", offsetof(WeaponFullDef, weapDef.moveSpeedScale), CSPFT_FLOAT }, + {"adsMoveSpeedScale", offsetof(WeaponFullDef, weapDef.adsMoveSpeedScale), CSPFT_FLOAT }, + {"sprintDurationScale", offsetof(WeaponFullDef, weapDef.sprintDurationScale), CSPFT_FLOAT }, + {"idleCrouchFactor", offsetof(WeaponFullDef, weapDef.fIdleCrouchFactor), CSPFT_FLOAT }, + {"idleProneFactor", offsetof(WeaponFullDef, weapDef.fIdleProneFactor), CSPFT_FLOAT }, + {"gunMaxPitch", offsetof(WeaponFullDef, weapDef.fGunMaxPitch), CSPFT_FLOAT }, + {"gunMaxYaw", offsetof(WeaponFullDef, weapDef.fGunMaxYaw), CSPFT_FLOAT }, + {"adsIdleLerpStartTime", offsetof(WeaponFullDef, weapDef.adsIdleLerpStartTime), CSPFT_FLOAT }, + {"adsIdleLerpTime", offsetof(WeaponFullDef, weapDef.adsIdleLerpTime), CSPFT_FLOAT }, + {"swayMaxAngle", offsetof(WeaponFullDef, weapDef.swayMaxAngle), CSPFT_FLOAT }, + {"swayLerpSpeed", offsetof(WeaponFullDef, weapDef.swayLerpSpeed), CSPFT_FLOAT }, + {"swayPitchScale", offsetof(WeaponFullDef, weapDef.swayPitchScale), CSPFT_FLOAT }, + {"swayYawScale", offsetof(WeaponFullDef, weapDef.swayYawScale), CSPFT_FLOAT }, + {"swayHorizScale", offsetof(WeaponFullDef, weapDef.swayHorizScale), CSPFT_FLOAT }, + {"swayVertScale", offsetof(WeaponFullDef, weapDef.swayVertScale), CSPFT_FLOAT }, + {"swayShellShockScale", offsetof(WeaponFullDef, weapDef.swayShellShockScale), CSPFT_FLOAT }, + {"adsSwayMaxAngle", offsetof(WeaponFullDef, weapDef.adsSwayMaxAngle), CSPFT_FLOAT }, + {"adsSwayLerpSpeed", offsetof(WeaponFullDef, weapDef.adsSwayLerpSpeed), CSPFT_FLOAT }, + {"adsSwayPitchScale", offsetof(WeaponFullDef, weapDef.adsSwayPitchScale), CSPFT_FLOAT }, + {"adsSwayYawScale", offsetof(WeaponFullDef, weapDef.adsSwayYawScale), CSPFT_FLOAT }, + {"adsSwayHorizScale", offsetof(WeaponFullDef, weapDef.adsSwayHorizScale), CSPFT_FLOAT }, + {"adsSwayVertScale", offsetof(WeaponFullDef, weapDef.adsSwayVertScale), CSPFT_FLOAT }, + {"rifleBullet", offsetof(WeaponFullDef, weapDef.bRifleBullet), CSPFT_BOOL }, + {"armorPiercing", offsetof(WeaponFullDef, weapDef.armorPiercing), CSPFT_BOOL }, + {"boltAction", offsetof(WeaponFullDef, weapDef.bBoltAction), CSPFT_BOOL }, + {"aimDownSight", offsetof(WeaponFullDef, weapDef.aimDownSight), CSPFT_BOOL }, + {"canHoldBreath", offsetof(WeaponFullDef, weapDef.canHoldBreath), CSPFT_BOOL }, + {"canVariableZoom", offsetof(WeaponFullDef, weapDef.canVariableZoom), CSPFT_BOOL }, + {"rechamberWhileAds", offsetof(WeaponFullDef, weapDef.bRechamberWhileAds), CSPFT_BOOL }, + {"bBulletExplosiveDamage", offsetof(WeaponFullDef, weapDef.bBulletExplosiveDamage), CSPFT_BOOL }, + {"adsViewErrorMin", offsetof(WeaponFullDef, weapDef.adsViewErrorMin), CSPFT_FLOAT }, + {"adsViewErrorMax", offsetof(WeaponFullDef, weapDef.adsViewErrorMax), CSPFT_FLOAT }, + {"clipOnly", offsetof(WeaponFullDef, weapDef.bClipOnly), CSPFT_BOOL }, + {"noAmmoPickup", offsetof(WeaponFullDef, weapDef.noAmmoPickup), CSPFT_BOOL }, + {"cookOffHold", offsetof(WeaponFullDef, weapDef.bCookOffHold), CSPFT_BOOL }, + {"adsFire", offsetof(WeaponFullDef, weapDef.adsFireOnly), CSPFT_BOOL }, + {"cancelAutoHolsterWhenEmpty", offsetof(WeaponFullDef, weapDef.cancelAutoHolsterWhenEmpty), CSPFT_BOOL }, + {"disableSwitchToWhenEmpty", offsetof(WeaponFullDef, weapDef.disableSwitchToWhenEmpty), CSPFT_BOOL }, + {"suppressAmmoReserveDisplay", offsetof(WeaponFullDef, weapDef.suppressAmmoReserveDisplay), CSPFT_BOOL }, + {"enhanced", offsetof(WeaponFullDef, weapCompleteDef.enhanced), CSPFT_BOOL }, + {"motionTracker", offsetof(WeaponFullDef, weapCompleteDef.motionTracker), CSPFT_BOOL }, + {"laserSightDuringNightvision", offsetof(WeaponFullDef, weapDef.laserSightDuringNightvision), CSPFT_BOOL }, + {"markableViewmodel", offsetof(WeaponFullDef, weapDef.markableViewmodel), CSPFT_BOOL }, + {"physCollmap", offsetof(WeaponFullDef, weapDef.physCollmap), CSPFT_PHYS_COLLMAP }, + {"noDualWield", offsetof(WeaponFullDef, weapDef.noDualWield), CSPFT_BOOL }, + {"dualWieldViewModelOffset", offsetof(WeaponFullDef, weapDef.dualWieldViewModelOffset), CSPFT_FLOAT }, + {"killIcon", offsetof(WeaponFullDef, weapCompleteDef.killIcon), CSPFT_MATERIAL }, + {"killIconRatio", offsetof(WeaponFullDef, weapDef.killIconRatio), WFT_ICONRATIO_KILL }, + {"flipKillIcon", offsetof(WeaponFullDef, weapDef.flipKillIcon), CSPFT_BOOL }, + {"dpadIcon", offsetof(WeaponFullDef, weapCompleteDef.dpadIcon), CSPFT_MATERIAL }, + {"dpadIconRatio", offsetof(WeaponFullDef, weapCompleteDef.dpadIconRatio), WFT_ICONRATIO_DPAD }, + {"dpadIconShowsAmmo", offsetof(WeaponFullDef, weapCompleteDef.dpadIconShowsAmmo), CSPFT_BOOL }, + {"noPartialReload", offsetof(WeaponFullDef, weapDef.bNoPartialReload), CSPFT_BOOL }, + {"segmentedReload", offsetof(WeaponFullDef, weapDef.bSegmentedReload), CSPFT_BOOL }, + {"reloadAmmoAdd", offsetof(WeaponFullDef, weapDef.iReloadAmmoAdd), CSPFT_INT }, + {"reloadStartAdd", offsetof(WeaponFullDef, weapDef.iReloadStartAdd), CSPFT_INT }, + {"altWeapon", offsetof(WeaponFullDef, weapCompleteDef.szAltWeaponName), CSPFT_STRING }, + {"dropAmmoMin", offsetof(WeaponFullDef, weapDef.ammoDropStockMin), CSPFT_INT }, + {"dropAmmoMax", offsetof(WeaponFullDef, weapCompleteDef.ammoDropStockMax), CSPFT_INT }, + {"ammoDropClipPercentMin", offsetof(WeaponFullDef, weapDef.ammoDropClipPercentMin), CSPFT_INT }, + {"ammoDropClipPercentMax", offsetof(WeaponFullDef, weapDef.ammoDropClipPercentMax), CSPFT_INT }, + {"blocksProne", offsetof(WeaponFullDef, weapDef.blocksProne), CSPFT_BOOL }, + {"silenced", offsetof(WeaponFullDef, weapDef.silenced), CSPFT_BOOL }, + {"isRollingGrenade", offsetof(WeaponFullDef, weapDef.isRollingGrenade), CSPFT_BOOL }, + {"explosionRadius", offsetof(WeaponFullDef, weapDef.iExplosionRadius), CSPFT_INT }, + {"explosionRadiusMin", offsetof(WeaponFullDef, weapDef.iExplosionRadiusMin), CSPFT_INT }, + {"explosionInnerDamage", offsetof(WeaponFullDef, weapDef.iExplosionInnerDamage), CSPFT_INT }, + {"explosionOuterDamage", offsetof(WeaponFullDef, weapDef.iExplosionOuterDamage), CSPFT_INT }, + {"damageConeAngle", offsetof(WeaponFullDef, weapDef.damageConeAngle), CSPFT_FLOAT }, + {"bulletExplDmgMult", offsetof(WeaponFullDef, weapDef.bulletExplDmgMult), CSPFT_FLOAT }, + {"bulletExplRadiusMult", offsetof(WeaponFullDef, weapDef.bulletExplRadiusMult), CSPFT_FLOAT }, + {"projectileSpeed", offsetof(WeaponFullDef, weapDef.iProjectileSpeed), CSPFT_INT }, + {"projectileSpeedUp", offsetof(WeaponFullDef, weapDef.iProjectileSpeedUp), CSPFT_INT }, + {"projectileSpeedForward", offsetof(WeaponFullDef, weapDef.iProjectileSpeedForward), CSPFT_INT }, + {"projectileActivateDist", offsetof(WeaponFullDef, weapDef.iProjectileActivateDist), CSPFT_INT }, + {"projectileLifetime", offsetof(WeaponFullDef, weapDef.projLifetime), CSPFT_FLOAT }, + {"timeToAccelerate", offsetof(WeaponFullDef, weapDef.timeToAccelerate), CSPFT_FLOAT }, + {"projectileCurvature", offsetof(WeaponFullDef, weapDef.projectileCurvature), CSPFT_FLOAT }, + {"projectileModel", offsetof(WeaponFullDef, weapDef.projectileModel), CSPFT_XMODEL }, + {"projExplosionType", offsetof(WeaponFullDef, weapDef.projExplosion), WFT_PROJ_EXPLOSION }, + {"projExplosionEffect", offsetof(WeaponFullDef, weapDef.projExplosionEffect), CSPFT_FX }, + {"projExplosionEffectForceNormalUp", offsetof(WeaponFullDef, weapDef.projExplosionEffectForceNormalUp), CSPFT_BOOL }, + {"projExplosionSound", offsetof(WeaponFullDef, weapDef.projExplosionSound), CSPFT_SOUND }, + {"projDudEffect", offsetof(WeaponFullDef, weapDef.projDudEffect), CSPFT_FX }, + {"projDudSound", offsetof(WeaponFullDef, weapDef.projDudSound), CSPFT_SOUND }, + {"projImpactExplode", offsetof(WeaponFullDef, weapDef.bProjImpactExplode), CSPFT_BOOL }, + {"stickiness", offsetof(WeaponFullDef, weapDef.stickiness), WFT_STICKINESS }, + {"stickToPlayers", offsetof(WeaponFullDef, weapDef.stickToPlayers), CSPFT_BOOL }, + {"stickToVehicles", offsetof(WeaponFullDef, weapDef.stickToVehicles), CSPFT_BOOL }, + {"stickToTurrets", offsetof(WeaponFullDef, weapDef.stickToTurrets), CSPFT_BOOL }, + {"hasDetonator", offsetof(WeaponFullDef, weapDef.hasDetonator), CSPFT_BOOL }, + {"disableFiring", offsetof(WeaponFullDef, weapDef.disableFiring), CSPFT_BOOL }, + {"timedDetonation", offsetof(WeaponFullDef, weapDef.timedDetonation), CSPFT_BOOL }, + {"rotate", offsetof(WeaponFullDef, weapDef.rotate), CSPFT_BOOL }, + {"holdButtonToThrow", offsetof(WeaponFullDef, weapDef.holdButtonToThrow), CSPFT_BOOL }, + {"freezeMovementWhenFiring", offsetof(WeaponFullDef, weapDef.freezeMovementWhenFiring), CSPFT_BOOL }, + {"lowAmmoWarningThreshold", offsetof(WeaponFullDef, weapDef.lowAmmoWarningThreshold), CSPFT_FLOAT }, + {"ricochetChance", offsetof(WeaponFullDef, weapDef.ricochetChance), CSPFT_FLOAT }, + {"riotShieldEnableDamage", offsetof(WeaponFullDef, weapDef.riotShieldEnableDamage), CSPFT_BOOL }, + {"riotShieldHealth", offsetof(WeaponFullDef, weapDef.riotShieldHealth), CSPFT_INT }, + {"riotShieldDamageMult", offsetof(WeaponFullDef, weapDef.riotShieldDamageMult), CSPFT_FLOAT }, + {"offhandHoldIsCancelable", offsetof(WeaponFullDef, weapDef.offhandHoldIsCancelable), CSPFT_BOOL }, + {"doNotAllowAttachmentsToOverrideSpread", offsetof(WeaponFullDef, weapDef.doNotAllowAttachmentsToOverrideSpread), CSPFT_BOOL }, + {"parallelDefaultBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_DEFAULT]), CSPFT_FLOAT }, + {"parallelBarkBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_BARK]), CSPFT_FLOAT }, + {"parallelBrickBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_BRICK]), CSPFT_FLOAT }, + {"parallelCarpetBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_CARPET]), CSPFT_FLOAT }, + {"parallelClothBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_CLOTH]), CSPFT_FLOAT }, + {"parallelConcreteBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_CONCRETE]), CSPFT_FLOAT }, + {"parallelDirtBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_DIRT]), CSPFT_FLOAT }, + {"parallelFleshBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_FLESH]), CSPFT_FLOAT }, + {"parallelFoliageBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_FOLIAGE]), CSPFT_FLOAT }, + {"parallelGlassBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_GLASS]), CSPFT_FLOAT }, + {"parallelGrassBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_GRASS]), CSPFT_FLOAT }, + {"parallelGravelBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_GRAVEL]), CSPFT_FLOAT }, + {"parallelIceBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_ICE]), CSPFT_FLOAT }, + {"parallelMetalBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_METAL]), CSPFT_FLOAT }, + {"parallelMudBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_MUD]), CSPFT_FLOAT }, + {"parallelPaperBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_PAPER]), CSPFT_FLOAT }, + {"parallelPlasterBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_PLASTER]), CSPFT_FLOAT }, + {"parallelRockBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_ROCK]), CSPFT_FLOAT }, + {"parallelSandBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_SAND]), CSPFT_FLOAT }, + {"parallelSnowBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_SNOW]), CSPFT_FLOAT }, + {"parallelWaterBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_WATER]), CSPFT_FLOAT }, + {"parallelWoodBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_WOOD]), CSPFT_FLOAT }, + {"parallelAsphaltBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_ASPHALT]), CSPFT_FLOAT }, + {"parallelCeramicBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_CERAMIC]), CSPFT_FLOAT }, + {"parallelPlasticBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_PLASTIC]), CSPFT_FLOAT }, + {"parallelRubberBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_RUBBER]), CSPFT_FLOAT }, + {"parallelCushionBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_CUSHION]), CSPFT_FLOAT }, + {"parallelFruitBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_FRUIT]), CSPFT_FLOAT }, + {"parallelPaintedMetalBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_PAINTED_METAL]), CSPFT_FLOAT }, + {"parallelRiotShieldBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_RIOT_SHIELD]), CSPFT_FLOAT }, + {"parallelSlushBounce", offsetof(WeaponFullDef, parallelBounce[SURF_TYPE_SLUSH]), CSPFT_FLOAT }, + {"perpendicularDefaultBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_DEFAULT]), CSPFT_FLOAT }, + {"perpendicularBarkBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_BARK]), CSPFT_FLOAT }, + {"perpendicularBrickBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_BRICK]), CSPFT_FLOAT }, + {"perpendicularCarpetBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_CARPET]), CSPFT_FLOAT }, + {"perpendicularClothBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_CLOTH]), CSPFT_FLOAT }, + {"perpendicularConcreteBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_CONCRETE]), CSPFT_FLOAT }, + {"perpendicularDirtBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_DIRT]), CSPFT_FLOAT }, + {"perpendicularFleshBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_FLESH]), CSPFT_FLOAT }, + {"perpendicularFoliageBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_FOLIAGE]), CSPFT_FLOAT }, + {"perpendicularGlassBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_GLASS]), CSPFT_FLOAT }, + {"perpendicularGrassBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_GRASS]), CSPFT_FLOAT }, + {"perpendicularGravelBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_GRAVEL]), CSPFT_FLOAT }, + {"perpendicularIceBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_ICE]), CSPFT_FLOAT }, + {"perpendicularMetalBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_METAL]), CSPFT_FLOAT }, + {"perpendicularMudBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_MUD]), CSPFT_FLOAT }, + {"perpendicularPaperBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_PAPER]), CSPFT_FLOAT }, + {"perpendicularPlasterBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_PLASTER]), CSPFT_FLOAT }, + {"perpendicularRockBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_ROCK]), CSPFT_FLOAT }, + {"perpendicularSandBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_SAND]), CSPFT_FLOAT }, + {"perpendicularSnowBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_SNOW]), CSPFT_FLOAT }, + {"perpendicularWaterBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_WATER]), CSPFT_FLOAT }, + {"perpendicularWoodBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_WOOD]), CSPFT_FLOAT }, + {"perpendicularAsphaltBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_ASPHALT]), CSPFT_FLOAT }, + {"perpendicularCeramicBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_CERAMIC]), CSPFT_FLOAT }, + {"perpendicularPlasticBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_PLASTIC]), CSPFT_FLOAT }, + {"perpendicularRubberBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_RUBBER]), CSPFT_FLOAT }, + {"perpendicularCushionBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_CUSHION]), CSPFT_FLOAT }, + {"perpendicularFruitBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_FRUIT]), CSPFT_FLOAT }, + {"perpendicularPaintedMetalBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_PAINTED_METAL]), CSPFT_FLOAT }, + {"perpendicularRiotShieldBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_RIOT_SHIELD]), CSPFT_FLOAT }, + {"perpendicularSlushBounce", offsetof(WeaponFullDef, perpendicularBounce[SURF_TYPE_SLUSH]), CSPFT_FLOAT }, + {"projTrailEffect", offsetof(WeaponFullDef, weapDef.projTrailEffect), CSPFT_FX }, + {"projBeaconEffect", offsetof(WeaponFullDef, weapDef.projBeaconEffect), CSPFT_FX }, + {"projectileRed", offsetof(WeaponFullDef, weapDef.vProjectileColor[0]), CSPFT_FLOAT }, + {"projectileGreen", offsetof(WeaponFullDef, weapDef.vProjectileColor[1]), CSPFT_FLOAT }, + {"projectileBlue", offsetof(WeaponFullDef, weapDef.vProjectileColor[2]), CSPFT_FLOAT }, + {"guidedMissileType", offsetof(WeaponFullDef, weapDef.guidedMissileType), WFT_GUIDED_MISSILE_TYPE }, + {"maxSteeringAccel", offsetof(WeaponFullDef, weapDef.maxSteeringAccel), CSPFT_FLOAT }, + {"projIgnitionDelay", offsetof(WeaponFullDef, weapDef.projIgnitionDelay), CSPFT_INT }, + {"projIgnitionEffect", offsetof(WeaponFullDef, weapDef.projIgnitionEffect), CSPFT_FX }, + {"projIgnitionSound", offsetof(WeaponFullDef, weapDef.projIgnitionSound), CSPFT_SOUND }, + {"adsTransInTime", offsetof(WeaponFullDef, weapCompleteDef.iAdsTransInTime), CSPFT_MILLISECONDS }, + {"adsTransOutTime", offsetof(WeaponFullDef, weapCompleteDef.iAdsTransOutTime), CSPFT_MILLISECONDS }, + {"adsIdleAmount", offsetof(WeaponFullDef, weapDef.fAdsIdleAmount), CSPFT_FLOAT }, + {"adsIdleSpeed", offsetof(WeaponFullDef, weapDef.adsIdleSpeed), CSPFT_FLOAT }, + {"adsZoomFov", offsetof(WeaponFullDef, weapCompleteDef.fAdsZoomFov), CSPFT_FLOAT }, + {"adsZoomInFrac", offsetof(WeaponFullDef, weapDef.fAdsZoomInFrac), CSPFT_FLOAT }, + {"adsZoomOutFrac", offsetof(WeaponFullDef, weapDef.fAdsZoomOutFrac), CSPFT_FLOAT }, + {"adsOverlayShader", offsetof(WeaponFullDef, weapDef.overlay.shader), CSPFT_MATERIAL }, + {"adsOverlayShaderLowRes", offsetof(WeaponFullDef, weapDef.overlay.shaderLowRes), CSPFT_MATERIAL }, + {"adsOverlayShaderEMP", offsetof(WeaponFullDef, weapDef.overlay.shaderEMP), CSPFT_MATERIAL }, + {"adsOverlayShaderEMPLowRes", offsetof(WeaponFullDef, weapDef.overlay.shaderEMPLowRes), CSPFT_MATERIAL }, + {"adsOverlayReticle", offsetof(WeaponFullDef, weapDef.overlay.reticle), WFT_OVERLAYRETICLE }, + {"adsOverlayInterface", offsetof(WeaponFullDef, weapDef.overlayInterface), WFT_OVERLAYINTERFACE }, + {"adsOverlayWidth", offsetof(WeaponFullDef, weapDef.overlay.width), CSPFT_FLOAT }, + {"adsOverlayHeight", offsetof(WeaponFullDef, weapDef.overlay.height), CSPFT_FLOAT }, + {"adsOverlayWidthSplitscreen", offsetof(WeaponFullDef, weapDef.overlay.widthSplitscreen), CSPFT_FLOAT }, + {"adsOverlayHeightSplitscreen", offsetof(WeaponFullDef, weapDef.overlay.heightSplitscreen), CSPFT_FLOAT }, + {"adsBobFactor", offsetof(WeaponFullDef, weapDef.fAdsBobFactor), CSPFT_FLOAT }, + {"adsViewBobMult", offsetof(WeaponFullDef, weapDef.fAdsViewBobMult), CSPFT_FLOAT }, + {"adsAimPitch", offsetof(WeaponFullDef, weapDef.fAdsAimPitch), CSPFT_FLOAT }, + {"adsCrosshairInFrac", offsetof(WeaponFullDef, weapDef.fAdsCrosshairInFrac), CSPFT_FLOAT }, + {"adsCrosshairOutFrac", offsetof(WeaponFullDef, weapDef.fAdsCrosshairOutFrac), CSPFT_FLOAT }, + {"adsReloadTransTime", offsetof(WeaponFullDef, weapDef.iPositionReloadTransTime), CSPFT_MILLISECONDS }, + {"adsGunKickReducedKickBullets", offsetof(WeaponFullDef, weapDef.adsGunKickReducedKickBullets), CSPFT_INT }, + {"adsGunKickReducedKickPercent", offsetof(WeaponFullDef, weapDef.adsGunKickReducedKickPercent), CSPFT_FLOAT }, + {"adsGunKickPitchMin", offsetof(WeaponFullDef, weapDef.fAdsGunKickPitchMin), CSPFT_FLOAT }, + {"adsGunKickPitchMax", offsetof(WeaponFullDef, weapDef.fAdsGunKickPitchMax), CSPFT_FLOAT }, + {"adsGunKickYawMin", offsetof(WeaponFullDef, weapDef.fAdsGunKickYawMin), CSPFT_FLOAT }, + {"adsGunKickYawMax", offsetof(WeaponFullDef, weapDef.fAdsGunKickYawMax), CSPFT_FLOAT }, + {"adsGunKickAccel", offsetof(WeaponFullDef, weapDef.fAdsGunKickAccel), CSPFT_FLOAT }, + {"adsGunKickSpeedMax", offsetof(WeaponFullDef, weapDef.fAdsGunKickSpeedMax), CSPFT_FLOAT }, + {"adsGunKickSpeedDecay", offsetof(WeaponFullDef, weapDef.fAdsGunKickSpeedDecay), CSPFT_FLOAT }, + {"adsGunKickStaticDecay", offsetof(WeaponFullDef, weapDef.fAdsGunKickStaticDecay), CSPFT_FLOAT }, + {"adsViewKickPitchMin", offsetof(WeaponFullDef, weapDef.fAdsViewKickPitchMin), CSPFT_FLOAT }, + {"adsViewKickPitchMax", offsetof(WeaponFullDef, weapDef.fAdsViewKickPitchMax), CSPFT_FLOAT }, + {"adsViewKickYawMin", offsetof(WeaponFullDef, weapDef.fAdsViewKickYawMin), CSPFT_FLOAT }, + {"adsViewKickYawMax", offsetof(WeaponFullDef, weapDef.fAdsViewKickYawMax), CSPFT_FLOAT }, + {"adsViewKickCenterSpeed", offsetof(WeaponFullDef, weapCompleteDef.fAdsViewKickCenterSpeed), CSPFT_FLOAT }, + {"adsSpread", offsetof(WeaponFullDef, weapDef.fAdsSpread), CSPFT_FLOAT }, + {"guidedMissileType", offsetof(WeaponFullDef, weapDef.guidedMissileType), WFT_GUIDED_MISSILE_TYPE }, + {"hipSpreadStandMin", offsetof(WeaponFullDef, weapDef.fHipSpreadStandMin), CSPFT_FLOAT }, + {"hipSpreadDuckedMin", offsetof(WeaponFullDef, weapDef.fHipSpreadDuckedMin), CSPFT_FLOAT }, + {"hipSpreadProneMin", offsetof(WeaponFullDef, weapDef.fHipSpreadProneMin), CSPFT_FLOAT }, + {"hipSpreadMax", offsetof(WeaponFullDef, weapDef.hipSpreadStandMax), CSPFT_FLOAT }, + {"hipSpreadDuckedMax", offsetof(WeaponFullDef, weapDef.hipSpreadDuckedMax), CSPFT_FLOAT }, + {"hipSpreadProneMax", offsetof(WeaponFullDef, weapDef.hipSpreadProneMax), CSPFT_FLOAT }, + {"hipSpreadDecayRate", offsetof(WeaponFullDef, weapDef.fHipSpreadDecayRate), CSPFT_FLOAT }, + {"hipSpreadFireAdd", offsetof(WeaponFullDef, weapDef.fHipSpreadFireAdd), CSPFT_FLOAT }, + {"hipSpreadTurnAdd", offsetof(WeaponFullDef, weapDef.fHipSpreadTurnAdd), CSPFT_FLOAT }, + {"hipSpreadMoveAdd", offsetof(WeaponFullDef, weapDef.fHipSpreadMoveAdd), CSPFT_FLOAT }, + {"hipSpreadDuckedDecay", offsetof(WeaponFullDef, weapDef.fHipSpreadDuckedDecay), CSPFT_FLOAT }, + {"hipSpreadProneDecay", offsetof(WeaponFullDef, weapDef.fHipSpreadProneDecay), CSPFT_FLOAT }, + {"hipReticleSidePos", offsetof(WeaponFullDef, weapDef.fHipReticleSidePos), CSPFT_FLOAT }, + {"hipIdleAmount", offsetof(WeaponFullDef, weapDef.fHipIdleAmount), CSPFT_FLOAT }, + {"hipIdleSpeed", offsetof(WeaponFullDef, weapDef.hipIdleSpeed), CSPFT_FLOAT }, + {"hipGunKickReducedKickBullets", offsetof(WeaponFullDef, weapDef.hipGunKickReducedKickBullets), CSPFT_INT }, + {"hipGunKickReducedKickPercent", offsetof(WeaponFullDef, weapDef.hipGunKickReducedKickPercent), CSPFT_FLOAT }, + {"hipGunKickPitchMin", offsetof(WeaponFullDef, weapDef.fHipGunKickPitchMin), CSPFT_FLOAT }, + {"hipGunKickPitchMax", offsetof(WeaponFullDef, weapDef.fHipGunKickPitchMax), CSPFT_FLOAT }, + {"hipGunKickYawMin", offsetof(WeaponFullDef, weapDef.fHipGunKickYawMin), CSPFT_FLOAT }, + {"hipGunKickYawMax", offsetof(WeaponFullDef, weapDef.fHipGunKickYawMax), CSPFT_FLOAT }, + {"hipGunKickAccel", offsetof(WeaponFullDef, weapDef.fHipGunKickAccel), CSPFT_FLOAT }, + {"hipGunKickSpeedMax", offsetof(WeaponFullDef, weapDef.fHipGunKickSpeedMax), CSPFT_FLOAT }, + {"hipGunKickSpeedDecay", offsetof(WeaponFullDef, weapDef.fHipGunKickSpeedDecay), CSPFT_FLOAT }, + {"hipGunKickStaticDecay", offsetof(WeaponFullDef, weapDef.fHipGunKickStaticDecay), CSPFT_FLOAT }, + {"hipViewKickPitchMin", offsetof(WeaponFullDef, weapDef.fHipViewKickPitchMin), CSPFT_FLOAT }, + {"hipViewKickPitchMax", offsetof(WeaponFullDef, weapDef.fHipViewKickPitchMax), CSPFT_FLOAT }, + {"hipViewKickYawMin", offsetof(WeaponFullDef, weapDef.fHipViewKickYawMin), CSPFT_FLOAT }, + {"hipViewKickYawMax", offsetof(WeaponFullDef, weapDef.fHipViewKickYawMax), CSPFT_FLOAT }, + {"hipViewKickCenterSpeed", offsetof(WeaponFullDef, weapCompleteDef.fHipViewKickCenterSpeed), CSPFT_FLOAT }, + {"leftArc", offsetof(WeaponFullDef, weapDef.leftArc), CSPFT_FLOAT }, + {"rightArc", offsetof(WeaponFullDef, weapDef.rightArc), CSPFT_FLOAT }, + {"topArc", offsetof(WeaponFullDef, weapDef.topArc), CSPFT_FLOAT }, + {"bottomArc", offsetof(WeaponFullDef, weapDef.bottomArc), CSPFT_FLOAT }, + {"accuracy", offsetof(WeaponFullDef, weapDef.accuracy), CSPFT_FLOAT }, + {"aiSpread", offsetof(WeaponFullDef, weapDef.aiSpread), CSPFT_FLOAT }, + {"playerSpread", offsetof(WeaponFullDef, weapDef.playerSpread), CSPFT_FLOAT }, + {"maxVertTurnSpeed", offsetof(WeaponFullDef, weapDef.maxTurnSpeed[0]), CSPFT_FLOAT }, + {"maxHorTurnSpeed", offsetof(WeaponFullDef, weapDef.maxTurnSpeed[1]), CSPFT_FLOAT }, + {"minVertTurnSpeed", offsetof(WeaponFullDef, weapDef.minTurnSpeed[0]), CSPFT_FLOAT }, + {"minHorTurnSpeed", offsetof(WeaponFullDef, weapDef.minTurnSpeed[1]), CSPFT_FLOAT }, + {"pitchConvergenceTime", offsetof(WeaponFullDef, weapDef.pitchConvergenceTime), CSPFT_FLOAT }, + {"yawConvergenceTime", offsetof(WeaponFullDef, weapDef.yawConvergenceTime), CSPFT_FLOAT }, + {"suppressionTime", offsetof(WeaponFullDef, weapDef.suppressTime), CSPFT_FLOAT }, + {"maxRange", offsetof(WeaponFullDef, weapDef.maxRange), CSPFT_FLOAT }, + {"animHorRotateInc", offsetof(WeaponFullDef, weapDef.fAnimHorRotateInc), CSPFT_FLOAT }, + {"playerPositionDist", offsetof(WeaponFullDef, weapDef.fPlayerPositionDist), CSPFT_FLOAT }, + {"stance", offsetof(WeaponFullDef, weapDef.stance), WFT_STANCE }, + {"useHintString", offsetof(WeaponFullDef, weapDef.szUseHintString), CSPFT_STRING }, + {"dropHintString", offsetof(WeaponFullDef, weapDef.dropHintString), CSPFT_STRING }, + {"horizViewJitter", offsetof(WeaponFullDef, weapDef.horizViewJitter), CSPFT_FLOAT }, + {"vertViewJitter", offsetof(WeaponFullDef, weapDef.vertViewJitter), CSPFT_FLOAT }, + {"scanSpeed", offsetof(WeaponFullDef, weapDef.scanSpeed), CSPFT_FLOAT }, + {"scanAccel", offsetof(WeaponFullDef, weapDef.scanAccel), CSPFT_FLOAT }, + {"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 }, + {"locNone", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_NONE]), CSPFT_FLOAT }, + {"locHelmet", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_HELMET]), CSPFT_FLOAT }, + {"locHead", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_HEAD]), CSPFT_FLOAT }, + {"locNeck", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_NECK]), CSPFT_FLOAT }, + {"locTorsoUpper", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_TORSO_UPR]), CSPFT_FLOAT }, + {"locTorsoLower", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_TORSO_LWR]), CSPFT_FLOAT }, + {"locRightArmUpper", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_ARM_UPR]), CSPFT_FLOAT }, + {"locRightArmLower", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_ARM_LWR]), CSPFT_FLOAT }, + {"locRightHand", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_HAND]), CSPFT_FLOAT }, + {"locLeftArmUpper", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_ARM_UPR]), CSPFT_FLOAT }, + {"locLeftArmLower", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_ARM_LWR]), CSPFT_FLOAT }, + {"locLeftHand", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_HAND]), CSPFT_FLOAT }, + {"locRightLegUpper", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_LEG_UPR]), CSPFT_FLOAT }, + {"locRightLegLower", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_LEG_LWR]), CSPFT_FLOAT }, + {"locRightFoot", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_R_FOOT]), CSPFT_FLOAT }, + {"locLeftLegUpper", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_LEG_UPR]), CSPFT_FLOAT }, + {"locLeftLegLower", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_LEG_LWR]), CSPFT_FLOAT }, + {"locLeftFoot", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_L_FOOT]), CSPFT_FLOAT }, + {"locGun", offsetof(WeaponFullDef, locationDamageMultipliers[HITLOC_GUN]), CSPFT_FLOAT }, + {"fireRumble", offsetof(WeaponFullDef, weapDef.fireRumble), CSPFT_STRING }, + {"meleeImpactRumble", offsetof(WeaponFullDef, weapDef.meleeImpactRumble), CSPFT_STRING }, + {"tracerType", offsetof(WeaponFullDef, weapDef.tracerType), CSPFT_TRACER }, + {"adsDofStart", offsetof(WeaponFullDef, weapCompleteDef.adsDofStart), CSPFT_FLOAT }, + {"adsDofEnd", offsetof(WeaponFullDef, weapCompleteDef.adsDofEnd), CSPFT_FLOAT }, + {"turretADSEnabled", offsetof(WeaponFullDef, weapDef.turretADSEnabled), CSPFT_BOOL }, + {"turretADSTime", offsetof(WeaponFullDef, weapDef.turretADSTime), CSPFT_FLOAT }, + {"turretFov", offsetof(WeaponFullDef, weapDef.turretFov), CSPFT_FLOAT }, + {"turretFovADS", offsetof(WeaponFullDef, weapDef.turretFovADS), CSPFT_FLOAT }, + {"turretScopeZoomRate", offsetof(WeaponFullDef, weapDef.turretScopeZoomRate), CSPFT_FLOAT }, + {"turretScopeZoomMin", offsetof(WeaponFullDef, weapDef.turretScopeZoomMin), CSPFT_FLOAT }, + {"turretScopeZoomMax", offsetof(WeaponFullDef, weapDef.turretScopeZoomMax), CSPFT_FLOAT }, + {"thermalScope", offsetof(WeaponFullDef, weapDef.thermalScope), CSPFT_BOOL }, + {"altModeSameWeapon", offsetof(WeaponFullDef, weapDef.altModeSameWeapon), CSPFT_BOOL }, + {"turretOverheatUpRate", offsetof(WeaponFullDef, weapDef.turretOverheatUpRate), CSPFT_FLOAT }, + {"turretOverheatDownRate", offsetof(WeaponFullDef, weapDef.turretOverheatDownRate), CSPFT_FLOAT }, + {"turretOverheatPenalty", offsetof(WeaponFullDef, weapDef.turretOverheatPenalty), CSPFT_FLOAT }, + {"turretOverheatSound", offsetof(WeaponFullDef, weapDef.turretOverheatSound), CSPFT_SOUND }, + {"turretOverheatEffect", offsetof(WeaponFullDef, weapDef.turretOverheatEffect), CSPFT_FX }, + {"turretBarrelSpinEnabled", offsetof(WeaponFullDef, weapDef.turretBarrelSpinEnabled), CSPFT_BOOL }, + {"turretBarrelSpinUpTime", offsetof(WeaponFullDef, weapDef.turretBarrelSpinUpTime), CSPFT_FLOAT }, + {"turretBarrelSpinDownTime", offsetof(WeaponFullDef, weapDef.turretBarrelSpinDownTime), CSPFT_FLOAT }, + {"turretBarrelSpinRumble", offsetof(WeaponFullDef, weapDef.turretBarrelSpinRumble), CSPFT_STRING }, + {"turretBarrelSpinSpeed", offsetof(WeaponFullDef, weapDef.turretBarrelSpinSpeed), CSPFT_FLOAT }, + {"turretBarrelSpinMaxSnd", offsetof(WeaponFullDef, weapDef.turretBarrelSpinMaxSnd), CSPFT_SOUND }, + {"turretBarrelSpinUpSnd1", offsetof(WeaponFullDef, weapDef.turretBarrelSpinUpSnd[0]), CSPFT_SOUND }, + {"turretBarrelSpinUpSnd2", offsetof(WeaponFullDef, weapDef.turretBarrelSpinUpSnd[1]), CSPFT_SOUND }, + {"turretBarrelSpinUpSnd3", offsetof(WeaponFullDef, weapDef.turretBarrelSpinUpSnd[2]), CSPFT_SOUND }, + {"turretBarrelSpinUpSnd4", offsetof(WeaponFullDef, weapDef.turretBarrelSpinUpSnd[3]), CSPFT_SOUND }, + {"turretBarrelSpinDownSnd1", offsetof(WeaponFullDef, weapDef.turretBarrelSpinDownSnd[0]), CSPFT_SOUND }, + {"turretBarrelSpinDownSnd2", offsetof(WeaponFullDef, weapDef.turretBarrelSpinDownSnd[1]), CSPFT_SOUND }, + {"turretBarrelSpinDownSnd3", offsetof(WeaponFullDef, weapDef.turretBarrelSpinDownSnd[2]), CSPFT_SOUND }, + {"turretBarrelSpinDownSnd4", offsetof(WeaponFullDef, weapDef.turretBarrelSpinDownSnd[3]), CSPFT_SOUND }, + {"missileConeSoundEnabled", offsetof(WeaponFullDef, weapDef.missileConeSoundEnabled), CSPFT_BOOL }, + {"missileConeSoundAlias", offsetof(WeaponFullDef, weapDef.missileConeSoundAlias), CSPFT_SOUND }, + {"missileConeSoundAliasAtBase", offsetof(WeaponFullDef, weapDef.missileConeSoundAliasAtBase), CSPFT_SOUND }, + {"missileConeSoundRadiusAtTop", offsetof(WeaponFullDef, weapDef.missileConeSoundRadiusAtTop), CSPFT_FLOAT }, + {"missileConeSoundRadiusAtBase", offsetof(WeaponFullDef, weapDef.missileConeSoundRadiusAtBase), CSPFT_FLOAT }, + {"missileConeSoundHeight", offsetof(WeaponFullDef, weapDef.missileConeSoundHeight), CSPFT_FLOAT }, + {"missileConeSoundOriginOffset", offsetof(WeaponFullDef, weapDef.missileConeSoundOriginOffset), CSPFT_FLOAT }, + {"missileConeSoundVolumescaleAtCore", offsetof(WeaponFullDef, weapDef.missileConeSoundVolumescaleAtCore), CSPFT_FLOAT }, + {"missileConeSoundVolumescaleAtEdge", offsetof(WeaponFullDef, weapDef.missileConeSoundVolumescaleAtEdge), CSPFT_FLOAT }, + {"missileConeSoundVolumescaleCoreSize", offsetof(WeaponFullDef, weapDef.missileConeSoundVolumescaleCoreSize), CSPFT_FLOAT }, + {"missileConeSoundPitchshiftEnabled", offsetof(WeaponFullDef, weapDef.missileConeSoundPitchshiftEnabled), CSPFT_BOOL }, + {"missileConeSoundPitchAtTop", offsetof(WeaponFullDef, weapDef.missileConeSoundPitchAtTop), CSPFT_FLOAT }, + {"missileConeSoundPitchAtBottom", offsetof(WeaponFullDef, weapDef.missileConeSoundPitchAtBottom), CSPFT_FLOAT }, + {"missileConeSoundPitchTopSize", offsetof(WeaponFullDef, weapDef.missileConeSoundPitchTopSize), CSPFT_FLOAT }, + {"missileConeSoundPitchBottomSize", offsetof(WeaponFullDef, weapDef.missileConeSoundPitchBottomSize), CSPFT_FLOAT }, + {"missileConeSoundCrossfadeEnabled", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeEnabled), CSPFT_BOOL }, + {"missileConeSoundCrossfadeTopSize", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeTopSize), CSPFT_FLOAT }, + {"missileConeSoundCrossfadeBottomSize", offsetof(WeaponFullDef, weapDef.missileConeSoundCrossfadeBottomSize), CSPFT_FLOAT }, + {"stowTag", offsetof(WeaponFullDef, weapDef.stowTag), CSPFT_SCRIPT_STRING }, + {"stowOffsetModel", offsetof(WeaponFullDef, weapDef.stowOffsetModel), CSPFT_XMODEL }, + {"attachments", offsetof(WeaponFullDef, scopes), WFT_ATTACHMENT }, + {"animOverrides", offsetof(WeaponFullDef, weapCompleteDef.animOverrides), WFT_ANIM_OVERRIDES }, + {"soundOverrides", offsetof(WeaponFullDef, weapCompleteDef.soundOverrides), WFT_SOUND_OVERRIDES }, + {"fxOverrides", offsetof(WeaponFullDef, weapCompleteDef.fxOverrides), WFT_FX_OVERRIDES }, + {"reloadOverrides", offsetof(WeaponFullDef, weapCompleteDef.reloadOverrides), WFT_RELOAD_OVERRIDES }, + {"notetrackOverrides", offsetof(WeaponFullDef, weapCompleteDef.notetrackOverrides), WFT_NOTETRACK_OVERRIDES }, }; inline const char* szWeapTypeNames[]{ diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp index bdd24ad6..ad16bdd4 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeapon.cpp @@ -76,13 +76,13 @@ namespace IW5 FillFromEnumInt(std::string(field.szName), field.iOffset, guidedMissileNames, std::extent_v); break; - case WFT_BOUNCE_SOUND: + case WFT_PER_SURFACE_TYPE_SOUND: { - const auto* bounceSound = *reinterpret_cast(reinterpret_cast(m_structure) + field.iOffset); + const auto* perSurfaceTypeSound = *reinterpret_cast(reinterpret_cast(m_structure) + field.iOffset); - if (bounceSound && bounceSound->name) + if (perSurfaceTypeSound && perSurfaceTypeSound->name) { - const std::string firstBounceSound(bounceSound->name->soundName); + const std::string firstBounceSound(perSurfaceTypeSound->name->soundName); const auto endOfBouncePrefix = firstBounceSound.rfind("_default"); assert(endOfBouncePrefix != std::string::npos); diff --git a/src/ObjWriting/Game/IW5/InfoString/InfoStringFromStructConverter.cpp b/src/ObjWriting/Game/IW5/InfoString/InfoStringFromStructConverter.cpp index c1171c37..6b2aaf8e 100644 --- a/src/ObjWriting/Game/IW5/InfoString/InfoStringFromStructConverter.cpp +++ b/src/ObjWriting/Game/IW5/InfoString/InfoStringFromStructConverter.cpp @@ -117,6 +117,10 @@ void InfoStringFromStructConverter::FillFromBaseField(const cspField_t& field) break; } + case CSPFT_SCRIPT_STRING: + FillFromScriptString(std::string(field.szName), field.iOffset); + break; + case CSPFT_NUM_BASE_FIELD_TYPES: default: assert(false); From a2d649ed662984b771aa15a91d738a80597a77dc Mon Sep 17 00:00:00 2001 From: Jan Date: Mon, 1 Apr 2024 14:58:57 +0200 Subject: [PATCH 16/17] chore: change std optional json serialization to not include property if unset --- src/ObjCommon/Game/T6/Json/JsonMaterial.h | 108 ++++++++++---------- src/ObjCommon/Game/T6/Json/JsonWeaponCamo.h | 12 +-- src/ObjCommon/Json/JsonCommon.h | 7 +- src/ObjCommon/Json/JsonExtension.h | 58 +++++++++++ src/ObjCommon/Json/JsonOptional.h | 37 ------- 5 files changed, 122 insertions(+), 100 deletions(-) create mode 100644 src/ObjCommon/Json/JsonExtension.h delete mode 100644 src/ObjCommon/Json/JsonOptional.h diff --git a/src/ObjCommon/Game/T6/Json/JsonMaterial.h b/src/ObjCommon/Game/T6/Json/JsonMaterial.h index 83762f74..e210676d 100644 --- a/src/ObjCommon/Game/T6/Json/JsonMaterial.h +++ b/src/ObjCommon/Game/T6/Json/JsonMaterial.h @@ -2,7 +2,7 @@ #include "Game/T6/T6.h" -#include "Json/JsonOptional.h" +#include "Json/JsonExtension.h" #include #include #include @@ -44,7 +44,7 @@ namespace T6 GfxStencilFunc func; }; - NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonStencil, pass, fail, zfail, func); + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonStencil, pass, fail, zfail, func); enum class JsonAlphaTest { @@ -154,24 +154,24 @@ namespace T6 std::optional stencilBack; }; - NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonStateBitsTableEntry, - srcBlendRgb, - dstBlendRgb, - blendOpRgb, - alphaTest, - cullFace, - srcBlendAlpha, - dstBlendAlpha, - blendOpAlpha, - colorWriteRgb, - colorWriteAlpha, - polymodeLine, - depthWrite, - depthWrite, - depthTest, - polygonOffset, - stencilFront, - stencilBack); + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonStateBitsTableEntry, + srcBlendRgb, + dstBlendRgb, + blendOpRgb, + alphaTest, + cullFace, + srcBlendAlpha, + dstBlendAlpha, + blendOpAlpha, + colorWriteRgb, + colorWriteAlpha, + polymodeLine, + depthWrite, + depthWrite, + depthTest, + polygonOffset, + stencilFront, + stencilBack); class JsonConstant { @@ -186,12 +186,12 @@ namespace T6 { if (in.name.has_value()) { - out["name"] = in.name; + optional_to_json(out, "name", in.name); } else { - out["nameFragment"] = in.nameFragment; - out["nameHash"] = in.nameHash; + optional_to_json(out, "nameFragment", in.nameFragment); + optional_to_json(out, "nameHash", in.nameHash); } out["literal"] = in.literal; @@ -199,9 +199,9 @@ namespace T6 inline void from_json(const nlohmann::json& in, JsonConstant& out) { - in.value("name", nlohmann::json()).get_to(out.name); - in.value("nameFragment", nlohmann::json()).get_to(out.nameFragment); - in.value("nameHash", nlohmann::json()).get_to(out.nameHash); + optional_from_json(in, "name", out.name); + optional_from_json(in, "nameFragment", out.nameFragment); + optional_from_json(in, "nameHash", out.nameHash); in.at("literal").get_to(out.literal); }; @@ -232,7 +232,7 @@ namespace T6 bool clampW; }; - NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonSamplerState, filter, mipMap, clampU, clampV, clampW); + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonSamplerState, filter, mipMap, clampU, clampV, clampW); NLOHMANN_JSON_SERIALIZE_ENUM(TextureSemantic, { @@ -284,13 +284,13 @@ namespace T6 { if (in.name.has_value()) { - out["name"] = in.name; + optional_to_json(out, "name", in.name); } else { - out["nameHash"] = in.nameHash; - out["nameStart"] = in.nameStart; - out["nameEnd"] = in.nameEnd; + optional_to_json(out, "nameHash", in.nameHash); + optional_to_json(out, "nameStart", in.nameStart); + optional_to_json(out, "nameEnd", in.nameEnd); } out["semantic"] = in.semantic; @@ -301,10 +301,10 @@ namespace T6 inline void from_json(const nlohmann::json& in, JsonTexture& out) { - in.value("name", nlohmann::json()).get_to(out.name); - in.value("nameHash", nlohmann::json()).get_to(out.nameHash); - in.value("nameStart", nlohmann::json()).get_to(out.nameStart); - in.value("nameEnd", nlohmann::json()).get_to(out.nameEnd); + optional_from_json(in, "name", out.name); + optional_from_json(in, "nameHash", out.nameHash); + optional_from_json(in, "nameStart", out.nameStart); + optional_from_json(in, "nameEnd", out.nameEnd); in.at("semantic").get_to(out.semantic); in.at("isMatureContent").get_to(out.isMatureContent); in.at("samplerState").get_to(out.samplerState); @@ -318,7 +318,7 @@ namespace T6 uint8_t columns; }; - NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonTextureAtlas, rows, columns); + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonTextureAtlas, rows, columns); NLOHMANN_JSON_SERIALIZE_ENUM(MaterialGameFlags, { @@ -376,22 +376,22 @@ namespace T6 std::optional thermalMaterial; }; - NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonMaterial, - gameFlags, - sortKey, - textureAtlas, - surfaceTypeBits, - layeredSurfaceTypes, - hashIndex, - surfaceFlags, - contents, - stateBitsEntry, - stateFlags, - cameraRegion, - probeMipBits, - techniqueSet, - textures, - constants, - stateBits, - thermalMaterial); + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonMaterial, + gameFlags, + sortKey, + textureAtlas, + surfaceTypeBits, + layeredSurfaceTypes, + hashIndex, + surfaceFlags, + contents, + stateBitsEntry, + stateFlags, + cameraRegion, + probeMipBits, + techniqueSet, + textures, + constants, + stateBits, + thermalMaterial); } // namespace T6 diff --git a/src/ObjCommon/Game/T6/Json/JsonWeaponCamo.h b/src/ObjCommon/Game/T6/Json/JsonWeaponCamo.h index eb9f72af..6b76cc2f 100644 --- a/src/ObjCommon/Game/T6/Json/JsonWeaponCamo.h +++ b/src/ObjCommon/Game/T6/Json/JsonWeaponCamo.h @@ -3,7 +3,7 @@ #include "Game/T6/T6.h" #include "Json/JsonCommon.h" -#include "Json/JsonOptional.h" +#include "Json/JsonExtension.h" #include #include #include @@ -21,7 +21,7 @@ namespace T6 float patternScale; }; - NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonWeaponCamoSet, solidCamoImage, patternCamoImage, patternOffset, patternScale); + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWeaponCamoSet, solidCamoImage, patternCamoImage, patternOffset, patternScale); class JsonWeaponCamoMaterialOverride { @@ -30,7 +30,7 @@ namespace T6 std::string camoMaterial; }; - NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonWeaponCamoMaterialOverride, baseMaterial, camoMaterial); + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWeaponCamoMaterialOverride, baseMaterial, camoMaterial); constexpr auto SHADER_CONST_COUNT = 8; @@ -46,7 +46,7 @@ namespace T6 static_assert(SHADER_CONST_COUNT == std::extent_v); - NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonWeaponCamoMaterial, useColorMap, useNormalMap, useSpecularMap, materialOverrides, shaderConsts); + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWeaponCamoMaterial, useColorMap, useNormalMap, useSpecularMap, materialOverrides, shaderConsts); class JsonWeaponCamoMaterialSet { @@ -54,7 +54,7 @@ namespace T6 std::vector materials; }; - NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonWeaponCamoMaterialSet, materials); + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWeaponCamoMaterialSet, materials); class JsonWeaponCamo { @@ -65,5 +65,5 @@ namespace T6 std::vector camoMaterials; }; - NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonWeaponCamo, solidBaseImage, patternBaseImage, camoSets, camoMaterials); + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWeaponCamo, solidBaseImage, patternBaseImage, camoSets, camoMaterials); } // namespace T6 diff --git a/src/ObjCommon/Json/JsonCommon.h b/src/ObjCommon/Json/JsonCommon.h index 57df18d1..f1a9291e 100644 --- a/src/ObjCommon/Json/JsonCommon.h +++ b/src/ObjCommon/Json/JsonCommon.h @@ -1,5 +1,6 @@ #pragma once +#include "Json/JsonExtension.h" #include class JsonVec2 @@ -9,7 +10,7 @@ public: float y; }; -NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonVec2, x, y); +NLOHMANN_DEFINE_TYPE_EXTENSION(JsonVec2, x, y); class JsonVec3 { @@ -19,7 +20,7 @@ public: float z; }; -NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonVec3, x, y, z); +NLOHMANN_DEFINE_TYPE_EXTENSION(JsonVec3, x, y, z); class JsonVec4 { @@ -30,4 +31,4 @@ public: float w; }; -NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonVec4, x, y, z, w); +NLOHMANN_DEFINE_TYPE_EXTENSION(JsonVec4, x, y, z, w); diff --git a/src/ObjCommon/Json/JsonExtension.h b/src/ObjCommon/Json/JsonExtension.h new file mode 100644 index 00000000..3b84b35a --- /dev/null +++ b/src/ObjCommon/Json/JsonExtension.h @@ -0,0 +1,58 @@ +#pragma once + +// Credits to +// https://www.kdab.com/jsonify-with-nlohmann-json/ + +#include +#include + +// partial specialization (full specialization works too) +namespace nlohmann +{ + template void optional_to_json(nlohmann::json& j, const char* name, const std::optional& value) + { + if (value) + j[name] = *value; + } + + template void optional_from_json(const nlohmann::json& j, const char* name, std::optional& value) + { + const auto it = j.find(name); + if (it != j.end()) + value = it->get(); + else + value = std::nullopt; + } + + template constexpr bool is_optional = false; + template constexpr bool is_optional> = true; + + template void extended_to_json(const char* key, nlohmann::json& j, const T& value) + { + if constexpr (is_optional) + nlohmann::optional_to_json(j, key, value); + else + j[key] = value; + } + + template void extended_from_json(const char* key, const nlohmann::json& j, T& value) + { + if constexpr (is_optional) + nlohmann::optional_from_json(j, key, value); + else + j.at(key).get_to(value); + } +} // namespace nlohmann + +#define EXTEND_JSON_TO(v1) extended_to_json(#v1, nlohmann_json_j, nlohmann_json_t.v1); +#define EXTEND_JSON_FROM(v1) extended_from_json(#v1, nlohmann_json_j, nlohmann_json_t.v1); + +#define NLOHMANN_DEFINE_TYPE_EXTENSION(Type, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) \ + { \ + NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(EXTEND_JSON_TO, __VA_ARGS__)) \ + } \ + inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) \ + { \ + NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(EXTEND_JSON_FROM, __VA_ARGS__)) \ + } diff --git a/src/ObjCommon/Json/JsonOptional.h b/src/ObjCommon/Json/JsonOptional.h deleted file mode 100644 index df1cef8a..00000000 --- a/src/ObjCommon/Json/JsonOptional.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include -#include - -// partial specialization (full specialization works too) -namespace nlohmann -{ - template struct adl_serializer> - { - static void to_json(json& j, const std::optional& opt) - { - if (!opt.has_value()) - { - j = nullptr; - } - else - { - j = *opt; // this will call adl_serializer::to_json which will - // find the free function to_json in T's namespace! - } - } - - static void from_json(const json& j, std::optional& opt) - { - if (j.is_null()) - { - opt = std::nullopt; - } - else - { - opt = j.template get(); // same as above, but with - // adl_serializer::from_json - } - } - }; -} // namespace nlohmann From 9248cc323c294d300fef665dc3abd4982a3554f8 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 14 Apr 2024 12:34:18 +0200 Subject: [PATCH 17/17] feat: dump iw5 weapon attachments as json --- src/Common/Game/IW5/IW5.h | 12 + src/Common/Game/IW5/IW5_Assets.h | 2 +- .../Game/IW5/Weapon/JsonWeaponAttachment.h | 601 ++++++++++++++++++ .../AssetDumperWeaponAttachment.cpp | 22 + .../AssetDumperWeaponAttachment.h | 14 + .../IW5/Weapon/JsonWeaponAttachmentWriter.cpp | 401 ++++++++++++ .../IW5/Weapon/JsonWeaponAttachmentWriter.h | 11 + src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp | 3 +- 8 files changed, 1064 insertions(+), 2 deletions(-) create mode 100644 src/ObjCommon/Game/IW5/Weapon/JsonWeaponAttachment.h create mode 100644 src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeaponAttachment.cpp create mode 100644 src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeaponAttachment.h create mode 100644 src/ObjWriting/Game/IW5/Weapon/JsonWeaponAttachmentWriter.cpp create mode 100644 src/ObjWriting/Game/IW5/Weapon/JsonWeaponAttachmentWriter.h diff --git a/src/Common/Game/IW5/IW5.h b/src/Common/Game/IW5/IW5.h index 06388124..40b98fac 100644 --- a/src/Common/Game/IW5/IW5.h +++ b/src/Common/Game/IW5/IW5.h @@ -125,4 +125,16 @@ namespace IW5 WFT_NUM_FIELD_TYPES, }; + + enum weaponAttachmentFieldType_t + { + WAFT_ATTACHMENT_TYPE = CSPFT_NUM_BASE_FIELD_TYPES, + WAFT_WEAPONTYPE, + WAFT_WEAPONCLASS, + WAFT_PENETRATE_TYPE, + WAFT_IMPACT_TYPE, + WAFT_FIRETYPE, + + WAFT_NUM_FIELD_TYPES, + }; } // namespace IW5 diff --git a/src/Common/Game/IW5/IW5_Assets.h b/src/Common/Game/IW5/IW5_Assets.h index 2ed9b192..08cc2db1 100644 --- a/src/Common/Game/IW5/IW5_Assets.h +++ b/src/Common/Game/IW5/IW5_Assets.h @@ -3219,7 +3219,7 @@ namespace IW5 XModel** worldModels; XModel** viewModels; XModel** reticleViewModels; - AttAmmoGeneral* ammogeneral; + AttAmmoGeneral* ammoGeneral; AttSight4* sight; AttReload* reload; AttAddOns* addOns; diff --git a/src/ObjCommon/Game/IW5/Weapon/JsonWeaponAttachment.h b/src/ObjCommon/Game/IW5/Weapon/JsonWeaponAttachment.h new file mode 100644 index 00000000..0c13e9a6 --- /dev/null +++ b/src/ObjCommon/Game/IW5/Weapon/JsonWeaponAttachment.h @@ -0,0 +1,601 @@ +#pragma once + +#include "Game/IW5/IW5.h" + +#include "Json/JsonCommon.h" +#include +#include +#include +#include +#include + +namespace IW5 +{ + NLOHMANN_JSON_SERIALIZE_ENUM(PenetrateType, + { + {PENETRATE_TYPE_NONE, "none" }, + {PENETRATE_TYPE_SMALL, "small" }, + {PENETRATE_TYPE_MEDIUM, "medium"}, + {PENETRATE_TYPE_LARGE, "large" }, + }); + + NLOHMANN_JSON_SERIALIZE_ENUM(ImpactType, + { + {IMPACT_TYPE_NONE, "none" }, + {IMPACT_TYPE_BULLET_SMALL, "bulletSmall" }, + {IMPACT_TYPE_BULLET_LARGE, "bulletLarge" }, + {IMPACT_TYPE_BULLET_AP, "bulletAp" }, + {IMPACT_TYPE_BULLET_EXPLODE, "bulletExplode" }, + {IMPACT_TYPE_SHOTGUN, "shotgun" }, + {IMPACT_TYPE_SHOTGUN_EXPLODE, "shotgunExplode"}, + {IMPACT_TYPE_GRENADE_BOUNCE, "grenadeBounce" }, + {IMPACT_TYPE_GRENADE_EXPLODE, "grenadeExplode"}, + {IMPACT_TYPE_ROCKET_EXPLODE, "rocketExplode" }, + {IMPACT_TYPE_PROJECTILE_DUD, "projectileDud" }, + }); + + NLOHMANN_JSON_SERIALIZE_ENUM(weapFireType_t, + { + {WEAPON_FIRETYPE_FULLAUTO, "fullauto" }, + {WEAPON_FIRETYPE_SINGLESHOT, "singleshot" }, + {WEAPON_FIRETYPE_BURSTFIRE2, "burstfire2" }, + {WEAPON_FIRETYPE_BURSTFIRE3, "burstfire3" }, + {WEAPON_FIRETYPE_BURSTFIRE4, "burstfire4" }, + {WEAPON_FIRETYPE_DOUBLEBARREL, "doublebarrel"}, + }); + + class JsonAttAmmoGeneral + { + public: + PenetrateType penetrateType; + float penetrateMultiplier; + ImpactType impactType; + weapFireType_t fireType; + std::optional tracerType; + bool rifleBullet; + bool armorPiercing; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttAmmoGeneral, penetrateType, penetrateMultiplier, impactType, fireType, tracerType, rifleBullet, armorPiercing); + + class JsonAttSight + { + public: + bool aimDownSight; + bool adsFire; + bool rechamberWhileAds; + bool noAdsWhenMagEmpty; + bool canHoldBreath; + bool canVariableZoom; + bool hideRailWithThisScope; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION( + JsonAttSight, aimDownSight, adsFire, rechamberWhileAds, noAdsWhenMagEmpty, canHoldBreath, canVariableZoom, hideRailWithThisScope); + + class JsonAttReload + { + public: + bool noPartialReload; + bool segmentedReload; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttReload, noPartialReload, segmentedReload); + + class JsonAttAddOns + { + public: + bool motionTracker; + bool silenced; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttAddOns, motionTracker, silenced); + + class JsonAttGeneral + { + public: + bool boltAction; + bool inheritsPerks; + float enemyCrosshairRange; + std::optional reticleCenter; + std::optional reticleSide; + int reticleCenterSize; + int reticleSideSize; + float moveSpeedScale; + float adsMoveSpeedScale; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttGeneral, + boltAction, + inheritsPerks, + enemyCrosshairRange, + reticleCenter, + reticleSide, + reticleCenterSize, + reticleSideSize, + moveSpeedScale, + adsMoveSpeedScale); + + class JsonAttAimAssist + { + public: + float autoAimRange; + float aimAssistRange; + float aimAssistRangeAds; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttAimAssist, autoAimRange, aimAssistRange, aimAssistRangeAds); + + class JsonAttAmmunition + { + public: + int maxAmmo; + int startAmmo; + int clipSize; + int shotCount; + int reloadAmmoAdd; + int reloadStartAdd; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttAmmunition, maxAmmo, startAmmo, clipSize, shotCount, reloadAmmoAdd, reloadStartAdd); + + class JsonAttDamage + { + public: + int damage; + int minDamage; + int meleeDamage; + float maxDamageRange; + float minDamageRange; + int playerDamage; + int minPlayerDamage; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttDamage, damage, minDamage, meleeDamage, maxDamageRange, minDamageRange, playerDamage, minPlayerDamage); + + class JsonAttLocationDamage + { + public: + float locNone; + float locHelmet; + float locHead; + float locNeck; + float locTorsoUpper; + float locTorsoLower; + float locRightArmUpper; + float locRightArmLower; + float locRightHand; + float locLeftArmUpper; + float locLeftArmLower; + float locLeftHand; + float locRightLegUpper; + float locRightLegLower; + float locRightFoot; + float locLeftLegUpper; + float locLeftLegLower; + float locLeftFoot; + float locGun; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttLocationDamage, + locNone, + locHelmet, + locHead, + locNeck, + locTorsoUpper, + locTorsoLower, + locRightArmUpper, + locRightArmLower, + locRightHand, + locLeftArmUpper, + locLeftArmLower, + locLeftHand, + locRightLegUpper, + locRightLegLower, + locRightFoot, + locLeftLegUpper, + locLeftLegLower, + locLeftFoot, + locGun); + + class JsonAttIdleSettings + { + public: + float hipIdleAmount; + float hipIdleSpeed; + float idleCrouchFactor; + float idleProneFactor; + float adsIdleLerpStartTime; + float adsIdleLerpTime; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttIdleSettings, hipIdleAmount, hipIdleSpeed, idleCrouchFactor, idleProneFactor, adsIdleLerpStartTime, adsIdleLerpTime); + + class JsonAttADSSettings + { + public: + float adsSpread; + float adsAimPitch; + float adsTransInTime; + float adsTransOutTime; + int adsReloadTransTime; + float adsCrosshairInFrac; + float adsCrosshairOutFrac; + float adsZoomFov; + float adsZoomInFrac; + float adsZoomOutFrac; + float adsBobFactor; + float adsViewBobMult; + float adsViewErrorMin; + float adsViewErrorMax; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttADSSettings, + adsSpread, + adsAimPitch, + adsTransInTime, + adsTransOutTime, + adsReloadTransTime, + adsCrosshairInFrac, + adsCrosshairOutFrac, + adsZoomFov, + adsZoomInFrac, + adsZoomOutFrac, + adsBobFactor, + adsViewBobMult, + adsViewErrorMin, + adsViewErrorMax); + + class JsonAttHipSpread + { + public: + float hipSpreadStandMin; + float hipSpreadDuckedMin; + float hipSpreadProneMin; + float hipSpreadMax; + float hipSpreadDuckedMax; + float hipSpreadProneMax; + float hipSpreadFireAdd; + float hipSpreadTurnAdd; + float hipSpreadMoveAdd; + float hipSpreadDecayRate; + float hipSpreadDuckedDecay; + float hipSpreadProneDecay; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttHipSpread, + hipSpreadStandMin, + hipSpreadDuckedMin, + hipSpreadProneMin, + hipSpreadMax, + hipSpreadDuckedMax, + hipSpreadProneMax, + hipSpreadFireAdd, + hipSpreadTurnAdd, + hipSpreadMoveAdd, + hipSpreadDecayRate, + hipSpreadDuckedDecay, + hipSpreadProneDecay); + + class JsonAttGunKick + { + public: + int hipGunKickReducedKickBullets; + float hipGunKickReducedKickPercent; + float hipGunKickPitchMin; + float hipGunKickPitchMax; + float hipGunKickYawMin; + float hipGunKickYawMax; + float hipGunKickAccel; + float hipGunKickSpeedMax; + float hipGunKickSpeedDecay; + float hipGunKickStaticDecay; + int adsGunKickReducedKickBullets; + float adsGunKickReducedKickPercent; + float adsGunKickPitchMin; + float adsGunKickPitchMax; + float adsGunKickYawMin; + float adsGunKickYawMax; + float adsGunKickAccel; + float adsGunKickSpeedMax; + float adsGunKickSpeedDecay; + float adsGunKickStaticDecay; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttGunKick, + hipGunKickReducedKickBullets, + hipGunKickReducedKickPercent, + hipGunKickPitchMin, + hipGunKickPitchMax, + hipGunKickYawMin, + hipGunKickYawMax, + hipGunKickAccel, + hipGunKickSpeedMax, + hipGunKickSpeedDecay, + hipGunKickStaticDecay, + adsGunKickReducedKickBullets, + adsGunKickReducedKickPercent, + adsGunKickPitchMin, + adsGunKickPitchMax, + adsGunKickYawMin, + adsGunKickYawMax, + adsGunKickAccel, + adsGunKickSpeedMax, + adsGunKickSpeedDecay, + adsGunKickStaticDecay); + + class JsonAttViewKick + { + public: + float hipViewKickPitchMin; + float hipViewKickPitchMax; + float hipViewKickYawMin; + float hipViewKickYawMax; + float hipViewKickCenterSpeed; + float adsViewKickPitchMin; + float adsViewKickPitchMax; + float adsViewKickYawMin; + float adsViewKickYawMax; + float adsViewKickCenterSpeed; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttViewKick, + hipViewKickPitchMin, + hipViewKickPitchMax, + hipViewKickYawMin, + hipViewKickYawMax, + hipViewKickCenterSpeed, + adsViewKickPitchMin, + adsViewKickPitchMax, + adsViewKickYawMin, + adsViewKickYawMax, + adsViewKickCenterSpeed); + + NLOHMANN_JSON_SERIALIZE_ENUM(weapOverlayReticle_t, + { + {WEAPOVERLAYRETICLE_NONE, "none" }, + {WEAPOVERLAYRETICLE_CROSSHAIR, "crosshair"}, + }); + + class JsonAttADSOverlay + { + public: + std::optional shader; + std::optional shaderLowRes; + std::optional shaderEMP; + std::optional shaderEMPLowRes; + weapOverlayReticle_t reticle; + float width; + float height; + float widthSplitscreen; + float heightSplitscreen; + bool thermalScope; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION( + JsonAttADSOverlay, shader, shaderLowRes, shaderEMP, shaderEMPLowRes, reticle, width, height, widthSplitscreen, heightSplitscreen, thermalScope); + + NLOHMANN_JSON_SERIALIZE_ENUM(weaponIconRatioType_t, + { + {WEAPON_ICON_RATIO_1TO1, "1:1"}, + {WEAPON_ICON_RATIO_2TO1, "2:1"}, + {WEAPON_ICON_RATIO_4TO1, "4:1"}, + }); + + NLOHMANN_JSON_SERIALIZE_ENUM(ammoCounterClipType_t, + { + {AMMO_COUNTER_CLIP_NONE, "none" }, + {AMMO_COUNTER_CLIP_MAGAZINE, "magazine" }, + {AMMO_COUNTER_CLIP_SHORTMAGAZINE, "shortmagazine"}, + {AMMO_COUNTER_CLIP_SHOTGUN, "shotgun" }, + {AMMO_COUNTER_CLIP_ROCKET, "rocket" }, + {AMMO_COUNTER_CLIP_BELTFED, "beltfed" }, + {AMMO_COUNTER_CLIP_ALTWEAPON, "altweapon" }, + }); + + class JsonAttUI + { + public: + std::optional dpadIcon; + std::optional ammoCounterIcon; + weaponIconRatioType_t dpadIconRatio; + weaponIconRatioType_t ammoCounterIconRatio; + ammoCounterClipType_t ammoCounterClip; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttUI, dpadIcon, ammoCounterIcon, dpadIconRatio, ammoCounterIconRatio, ammoCounterClip); + + class JsonAttRumbles + { + public: + std::optional fireRumble; + std::optional meleeImpactRumble; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttRumbles, fireRumble, meleeImpactRumble); + + NLOHMANN_JSON_SERIALIZE_ENUM(weapProjExposion_t, + { + {WEAPPROJEXP_GRENADE, "grenade" }, + {WEAPPROJEXP_ROCKET, "rocket" }, + {WEAPPROJEXP_FLASHBANG, "flashbang"}, + {WEAPPROJEXP_NONE, "none" }, + {WEAPPROJEXP_DUD, "dud" }, + {WEAPPROJEXP_SMOKE, "smoke" }, + {WEAPPROJEXP_HEAVY, "heavy" }, + }); + + class JsonAttProjectile + { + public: + int explosionRadius; + int explosionInnerDamage; + int explosionOuterDamage; + float damageConeAngle; + int projectileSpeed; + int projectileSpeedUp; + int projectileActivateDist; + float projectileLifetime; + std::optional projectileModel; + weapProjExposion_t projExplosionType; + std::optional projExplosionEffect; + bool projExplosionEffectForceNormalUp; + std::optional projExplosionSound; + std::optional projDudEffect; + std::optional projDudSound; + bool projImpactExplode; + float destabilizationRateTime; + float destabilizationCurvatureMax; + int destabilizeDistance; + std::optional projTrailEffect; + int projIgnitionDelay; + std::optional projIgnitionEffect; + std::optional projIgnitionSound; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttProjectile, + explosionRadius, + explosionInnerDamage, + explosionOuterDamage, + damageConeAngle, + projectileSpeed, + projectileSpeedUp, + projectileActivateDist, + projectileLifetime, + projectileModel, + projExplosionType, + projExplosionEffect, + projExplosionEffectForceNormalUp, + projExplosionSound, + projDudEffect, + projDudSound, + projImpactExplode, + destabilizationRateTime, + destabilizationCurvatureMax, + destabilizeDistance, + projTrailEffect, + projIgnitionDelay, + projIgnitionEffect, + projIgnitionSound); + + NLOHMANN_JSON_SERIALIZE_ENUM(AttachmentType, + { + {ATTACHMENT_SCOPE, "scope" }, + {ATTACHMENT_UNDERBARREL, "underbarrel"}, + {ATTACHMENT_OTHER, "other" }, + }); + + NLOHMANN_JSON_SERIALIZE_ENUM(weapType_t, + { + {WEAPTYPE_NONE, "none" }, + {WEAPTYPE_BULLET, "bullet" }, + {WEAPTYPE_GRENADE, "grenade" }, + {WEAPTYPE_PROJECTILE, "projectile"}, + {WEAPTYPE_RIOTSHIELD, "riotshield"}, + }); + + NLOHMANN_JSON_SERIALIZE_ENUM(weapClass_t, + { + {WEAPCLASS_RIFLE, "rifle" }, + {WEAPCLASS_SNIPER, "sniper" }, + {WEAPCLASS_MG, "mg" }, + {WEAPCLASS_SMG, "smg" }, + {WEAPCLASS_SPREAD, "spread" }, + {WEAPCLASS_PISTOL, "pistol" }, + {WEAPCLASS_GRENADE, "grenade" }, + {WEAPCLASS_ROCKETLAUNCHER, "rocketlauncher"}, + {WEAPCLASS_TURRET, "turret" }, + {WEAPCLASS_THROWINGKNIFE, "throwingknife" }, + {WEAPCLASS_NON_PLAYER, "nonPlayer" }, + {WEAPCLASS_ITEM, "item" }, + }); + + class JsonWeaponAttachment + { + public: + std::string displayName; + AttachmentType type; + weapType_t weaponType; + weapClass_t weapClass; + std::vector worldModels; + std::vector viewModels; + std::vector reticleViewModels; + std::optional ammoGeneral; + std::optional sight; + std::optional reload; + std::optional addOns; + std::optional general; + std::optional aimAssist; + std::optional ammunition; + std::optional damage; + std::optional locationDamage; + std::optional idleSettings; + std::optional adsSettings; + std::optional adsSettingsMain; + std::optional hipSpread; + std::optional gunKick; + std::optional viewKick; + std::optional adsOverlay; + std::optional ui; + std::optional rumbles; + std::optional projectile; + float ammunitionScale; + float damageScale; + float damageScaleMin; + float stateTimersScale; + float fireTimersScale; + float idleSettingsScale; + float adsSettingsScale; + float adsSettingsScaleMain; + float hipSpreadScale; + float gunKickScale; + float viewKickScale; + float viewCenterScale; + int loadIndex; + bool hideIronSightsWithThisAttachment; + bool shareAmmoWithAlt; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWeaponAttachment, + displayName, + type, + weaponType, + weapClass, + worldModels, + viewModels, + reticleViewModels, + ammoGeneral, + sight, + reload, + addOns, + general, + aimAssist, + ammunition, + damage, + locationDamage, + idleSettings, + adsSettings, + adsSettingsMain, + hipSpread, + gunKick, + viewKick, + adsOverlay, + ui, + rumbles, + projectile, + ammunitionScale, + damageScale, + damageScaleMin, + stateTimersScale, + fireTimersScale, + idleSettingsScale, + adsSettingsScale, + adsSettingsScaleMain, + hipSpreadScale, + gunKickScale, + viewKickScale, + viewCenterScale, + loadIndex, + hideIronSightsWithThisAttachment, + shareAmmoWithAlt); +} // namespace IW5 diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeaponAttachment.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeaponAttachment.cpp new file mode 100644 index 00000000..d63e1649 --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeaponAttachment.cpp @@ -0,0 +1,22 @@ +#include "AssetDumperWeaponAttachment.h" + +#include "Game/IW5/Weapon/JsonWeaponAttachmentWriter.h" + +#include + +using namespace IW5; + +bool AssetDumperWeaponAttachment::ShouldDump(XAssetInfo* asset) +{ + return true; +} + +void AssetDumperWeaponAttachment::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) +{ + const auto assetFile = context.OpenAssetFile(std::format("attachment/{}.json", asset->m_name)); + + if (!assetFile) + return; + + DumpWeaponAttachmentAsJson(*assetFile, asset->Asset(), context); +} diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeaponAttachment.h b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeaponAttachment.h new file mode 100644 index 00000000..11f32004 --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperWeaponAttachment.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + class AssetDumperWeaponAttachment final : public AbstractAssetDumper + { + protected: + bool ShouldDump(XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + }; +} // namespace IW5 diff --git a/src/ObjWriting/Game/IW5/Weapon/JsonWeaponAttachmentWriter.cpp b/src/ObjWriting/Game/IW5/Weapon/JsonWeaponAttachmentWriter.cpp new file mode 100644 index 00000000..86f0df79 --- /dev/null +++ b/src/ObjWriting/Game/IW5/Weapon/JsonWeaponAttachmentWriter.cpp @@ -0,0 +1,401 @@ +#include "JsonWeaponAttachmentWriter.h" + +#include "Game/IW5/CommonIW5.h" +#include "Game/IW5/Weapon/JsonWeaponAttachment.h" + +#include +#include + +using namespace nlohmann; +using namespace IW5; + +namespace +{ + class JsonDumper + { + public: + JsonDumper(AssetDumpingContext& context, std::ostream& stream) + : m_stream(stream) + { + } + + void Dump(const WeaponAttachment* attachment) const + { + JsonWeaponAttachment jsonWeaponAttachment; + CreateJsonAttachment(jsonWeaponAttachment, *attachment); + json jRoot = jsonWeaponAttachment; + + jRoot["_type"] = "attachment"; + jRoot["_version"] = 1; + + m_stream << std::setw(4) << jRoot << "\n"; + } + + private: + static const char* AssetName(const char* input) + { + if (input && input[0] == ',') + return &input[1]; + + return input; + } + + static void CreateJsonAttachment(JsonWeaponAttachment& jAttachment, const WeaponAttachment& attachment) + { +#define CONVERT_XMODEL_ARRAY(propertyName, count) \ + if (attachment.propertyName) \ + { \ + for (auto i = 0u; i < (count); i++) \ + { \ + const auto* model = attachment.propertyName[i]; \ + if (model && model->name) \ + jAttachment.propertyName.emplace_back(AssetName(model->name)); \ + } \ + } + +#define CONVERT_ATTRIBUTE(attributeJsonClass, attributeName) \ + if (attachment.attributeName) \ + { \ + attributeJsonClass attribute; \ + Convert##attributeJsonClass(attribute, *attachment.attributeName); \ + jAttachment.attributeName = std::move(attribute); \ + } + + if (attachment.szDisplayName) + jAttachment.displayName = attachment.szDisplayName; + + jAttachment.type = attachment.type; + jAttachment.weaponType = attachment.weaponType; + jAttachment.weapClass = attachment.weapClass; + + CONVERT_XMODEL_ARRAY(worldModels, 16u) + CONVERT_XMODEL_ARRAY(viewModels, 16u) + CONVERT_XMODEL_ARRAY(reticleViewModels, 8u) + + CONVERT_ATTRIBUTE(JsonAttAmmoGeneral, ammoGeneral) + CONVERT_ATTRIBUTE(JsonAttSight, sight) + CONVERT_ATTRIBUTE(JsonAttReload, reload) + CONVERT_ATTRIBUTE(JsonAttAddOns, addOns) + CONVERT_ATTRIBUTE(JsonAttGeneral, general) + CONVERT_ATTRIBUTE(JsonAttAimAssist, aimAssist) + CONVERT_ATTRIBUTE(JsonAttAmmunition, ammunition) + CONVERT_ATTRIBUTE(JsonAttDamage, damage) + CONVERT_ATTRIBUTE(JsonAttLocationDamage, locationDamage) + CONVERT_ATTRIBUTE(JsonAttIdleSettings, idleSettings) + CONVERT_ATTRIBUTE(JsonAttADSSettings, adsSettings) + CONVERT_ATTRIBUTE(JsonAttADSSettings, adsSettingsMain) + CONVERT_ATTRIBUTE(JsonAttHipSpread, hipSpread) + CONVERT_ATTRIBUTE(JsonAttGunKick, gunKick) + CONVERT_ATTRIBUTE(JsonAttViewKick, viewKick) + CONVERT_ATTRIBUTE(JsonAttADSOverlay, adsOverlay) + CONVERT_ATTRIBUTE(JsonAttUI, ui) + CONVERT_ATTRIBUTE(JsonAttRumbles, rumbles) + CONVERT_ATTRIBUTE(JsonAttProjectile, projectile) + + jAttachment.ammunitionScale = attachment.ammunitionScale; + jAttachment.damageScale = attachment.damageScale; + jAttachment.damageScaleMin = attachment.damageScaleMin; + jAttachment.stateTimersScale = attachment.stateTimersScale; + jAttachment.fireTimersScale = attachment.fireTimersScale; + jAttachment.idleSettingsScale = attachment.idleSettingsScale; + jAttachment.adsSettingsScale = attachment.adsSettingsScale; + jAttachment.adsSettingsScaleMain = attachment.adsSettingsScaleMain; + jAttachment.hipSpreadScale = attachment.hipSpreadScale; + jAttachment.gunKickScale = attachment.gunKickScale; + jAttachment.viewKickScale = attachment.viewKickScale; + jAttachment.viewCenterScale = attachment.viewCenterScale; + jAttachment.loadIndex = attachment.loadIndex; + jAttachment.hideIronSightsWithThisAttachment = attachment.hideIronSightsWithThisAttachment; + jAttachment.shareAmmoWithAlt = attachment.shareAmmoWithAlt; + } + + static void ConvertJsonAttAmmoGeneral(JsonAttAmmoGeneral& jAmmoGeneral, const AttAmmoGeneral& ammoGeneral) + { + jAmmoGeneral.penetrateType = ammoGeneral.penetrateType; + jAmmoGeneral.penetrateMultiplier = ammoGeneral.penetrateMultiplier; + jAmmoGeneral.impactType = ammoGeneral.impactType; + jAmmoGeneral.fireType = ammoGeneral.fireType; + + if (ammoGeneral.tracerType && ammoGeneral.tracerType->name) + jAmmoGeneral.tracerType = AssetName(ammoGeneral.tracerType->name); + + jAmmoGeneral.rifleBullet = ammoGeneral.rifleBullet; + jAmmoGeneral.armorPiercing = ammoGeneral.armorPiercing; + } + + static void ConvertJsonAttSight(JsonAttSight& jSight, const AttSight& sight) + { + jSight.aimDownSight = sight.aimDownSight; + jSight.adsFire = sight.adsFire; + jSight.rechamberWhileAds = sight.rechamberWhileAds; + jSight.noAdsWhenMagEmpty = sight.noAdsWhenMagEmpty; + jSight.canHoldBreath = sight.canHoldBreath; + jSight.canVariableZoom = sight.canVariableZoom; + jSight.hideRailWithThisScope = sight.hideRailWithThisScope; + } + + static void ConvertJsonAttReload(JsonAttReload& jAttReload, const AttReload& reload) + { + jAttReload.noPartialReload = reload.noPartialReload; + jAttReload.segmentedReload = reload.segmentedReload; + } + + static void ConvertJsonAttAddOns(JsonAttAddOns& jAddOns, const AttAddOns& addOns) + { + jAddOns.motionTracker = addOns.motionTracker; + jAddOns.silenced = addOns.silenced; + } + + static void ConvertJsonAttGeneral(JsonAttGeneral& jGeneral, const AttGeneral& general) + { + jGeneral.boltAction = general.boltAction; + jGeneral.inheritsPerks = general.inheritsPerks; + jGeneral.enemyCrosshairRange = general.enemyCrosshairRange; + + if (general.reticleCenter && general.reticleCenter->info.name) + jGeneral.reticleCenter = AssetName(general.reticleCenter->info.name); + + if (general.reticleSide && general.reticleSide->info.name) + jGeneral.reticleSide = AssetName(general.reticleSide->info.name); + + jGeneral.reticleCenterSize = general.reticleCenterSize; + jGeneral.reticleSideSize = general.reticleSideSize; + jGeneral.moveSpeedScale = general.moveSpeedScale; + jGeneral.adsMoveSpeedScale = general.adsMoveSpeedScale; + } + + static void ConvertJsonAttAimAssist(JsonAttAimAssist& jAimAssist, const AttAimAssist& aimAssist) + { + jAimAssist.autoAimRange = aimAssist.autoAimRange; + jAimAssist.aimAssistRange = aimAssist.aimAssistRange; + jAimAssist.aimAssistRangeAds = aimAssist.aimAssistRangeAds; + } + + static void ConvertJsonAttAmmunition(JsonAttAmmunition& jAmmunition, const AttAmmunition& ammunition) + { + jAmmunition.maxAmmo = ammunition.maxAmmo; + jAmmunition.startAmmo = ammunition.startAmmo; + jAmmunition.clipSize = ammunition.clipSize; + jAmmunition.shotCount = ammunition.shotCount; + jAmmunition.reloadAmmoAdd = ammunition.reloadAmmoAdd; + jAmmunition.reloadStartAdd = ammunition.reloadStartAdd; + } + + static void ConvertJsonAttDamage(JsonAttDamage& jDamage, const AttDamage& damage) + { + jDamage.damage = damage.damage; + jDamage.minDamage = damage.minDamage; + jDamage.meleeDamage = damage.meleeDamage; + jDamage.maxDamageRange = damage.maxDamageRange; + jDamage.minDamageRange = damage.minDamageRange; + jDamage.playerDamage = damage.playerDamage; + jDamage.minPlayerDamage = damage.minPlayerDamage; + } + + static void ConvertJsonAttLocationDamage(JsonAttLocationDamage& jLocationDamage, const AttLocationDamage& locationDamage) + { + jLocationDamage.locNone = locationDamage.locNone; + jLocationDamage.locHelmet = locationDamage.locHelmet; + jLocationDamage.locHead = locationDamage.locHead; + jLocationDamage.locNeck = locationDamage.locNeck; + jLocationDamage.locTorsoUpper = locationDamage.locTorsoUpper; + jLocationDamage.locTorsoLower = locationDamage.locTorsoLower; + jLocationDamage.locRightArmUpper = locationDamage.locRightArmUpper; + jLocationDamage.locRightArmLower = locationDamage.locRightArmLower; + jLocationDamage.locRightHand = locationDamage.locRightHand; + jLocationDamage.locLeftArmUpper = locationDamage.locLeftArmUpper; + jLocationDamage.locLeftArmLower = locationDamage.locLeftArmLower; + jLocationDamage.locLeftHand = locationDamage.locLeftHand; + jLocationDamage.locRightLegUpper = locationDamage.locRightLegUpper; + jLocationDamage.locRightLegLower = locationDamage.locRightLegLower; + jLocationDamage.locRightFoot = locationDamage.locRightFoot; + jLocationDamage.locLeftLegUpper = locationDamage.locLeftLegUpper; + jLocationDamage.locLeftLegLower = locationDamage.locLeftLegLower; + jLocationDamage.locLeftFoot = locationDamage.locLeftFoot; + jLocationDamage.locGun = locationDamage.locGun; + } + + static void ConvertJsonAttIdleSettings(JsonAttIdleSettings& jIdleSettings, const AttIdleSettings& idleSettings) + { + jIdleSettings.hipIdleAmount = idleSettings.hipIdleAmount; + jIdleSettings.hipIdleSpeed = idleSettings.hipIdleSpeed; + jIdleSettings.idleCrouchFactor = idleSettings.idleCrouchFactor; + jIdleSettings.idleProneFactor = idleSettings.idleProneFactor; + jIdleSettings.adsIdleLerpStartTime = idleSettings.adsIdleLerpStartTime; + jIdleSettings.adsIdleLerpTime = idleSettings.adsIdleLerpTime; + } + + static void ConvertJsonAttADSSettings(JsonAttADSSettings& jAdsSettings, const AttADSSettings& adsSettings) + { + jAdsSettings.adsSpread = adsSettings.adsSpread; + jAdsSettings.adsAimPitch = adsSettings.adsAimPitch; + jAdsSettings.adsTransInTime = adsSettings.adsTransInTime; + jAdsSettings.adsTransOutTime = adsSettings.adsTransOutTime; + jAdsSettings.adsReloadTransTime = adsSettings.adsReloadTransTime; + jAdsSettings.adsCrosshairInFrac = adsSettings.adsCrosshairInFrac; + jAdsSettings.adsCrosshairOutFrac = adsSettings.adsCrosshairOutFrac; + jAdsSettings.adsZoomFov = adsSettings.adsZoomFov; + jAdsSettings.adsZoomInFrac = adsSettings.adsZoomInFrac; + jAdsSettings.adsZoomOutFrac = adsSettings.adsZoomOutFrac; + jAdsSettings.adsBobFactor = adsSettings.adsBobFactor; + jAdsSettings.adsViewBobMult = adsSettings.adsViewBobMult; + jAdsSettings.adsViewErrorMin = adsSettings.adsViewErrorMin; + jAdsSettings.adsViewErrorMax = adsSettings.adsViewErrorMax; + } + + static void ConvertJsonAttHipSpread(JsonAttHipSpread& jHipSpread, const AttHipSpread& hipSpread) + { + jHipSpread.hipSpreadStandMin = hipSpread.hipSpreadStandMin; + jHipSpread.hipSpreadDuckedMin = hipSpread.hipSpreadDuckedMin; + jHipSpread.hipSpreadProneMin = hipSpread.hipSpreadProneMin; + jHipSpread.hipSpreadMax = hipSpread.hipSpreadMax; + jHipSpread.hipSpreadDuckedMax = hipSpread.hipSpreadDuckedMax; + jHipSpread.hipSpreadProneMax = hipSpread.hipSpreadProneMax; + jHipSpread.hipSpreadFireAdd = hipSpread.hipSpreadFireAdd; + jHipSpread.hipSpreadTurnAdd = hipSpread.hipSpreadTurnAdd; + jHipSpread.hipSpreadMoveAdd = hipSpread.hipSpreadMoveAdd; + jHipSpread.hipSpreadDecayRate = hipSpread.hipSpreadDecayRate; + jHipSpread.hipSpreadDuckedDecay = hipSpread.hipSpreadDuckedDecay; + jHipSpread.hipSpreadProneDecay = hipSpread.hipSpreadProneDecay; + } + + static void ConvertJsonAttGunKick(JsonAttGunKick& jGunKick, const AttGunKick& gunKick) + { + jGunKick.hipGunKickReducedKickBullets = gunKick.hipGunKickReducedKickBullets; + jGunKick.hipGunKickReducedKickPercent = gunKick.hipGunKickReducedKickPercent; + jGunKick.hipGunKickPitchMin = gunKick.hipGunKickPitchMin; + jGunKick.hipGunKickPitchMax = gunKick.hipGunKickPitchMax; + jGunKick.hipGunKickYawMin = gunKick.hipGunKickYawMin; + jGunKick.hipGunKickYawMax = gunKick.hipGunKickYawMax; + jGunKick.hipGunKickAccel = gunKick.hipGunKickAccel; + jGunKick.hipGunKickSpeedMax = gunKick.hipGunKickSpeedMax; + jGunKick.hipGunKickSpeedDecay = gunKick.hipGunKickSpeedDecay; + jGunKick.hipGunKickStaticDecay = gunKick.hipGunKickStaticDecay; + jGunKick.adsGunKickReducedKickBullets = gunKick.adsGunKickReducedKickBullets; + jGunKick.adsGunKickReducedKickPercent = gunKick.adsGunKickReducedKickPercent; + jGunKick.adsGunKickPitchMin = gunKick.adsGunKickPitchMin; + jGunKick.adsGunKickPitchMax = gunKick.adsGunKickPitchMax; + jGunKick.adsGunKickYawMin = gunKick.adsGunKickYawMin; + jGunKick.adsGunKickYawMax = gunKick.adsGunKickYawMax; + jGunKick.adsGunKickAccel = gunKick.adsGunKickAccel; + jGunKick.adsGunKickSpeedMax = gunKick.adsGunKickSpeedMax; + jGunKick.adsGunKickSpeedDecay = gunKick.adsGunKickSpeedDecay; + jGunKick.adsGunKickStaticDecay = gunKick.adsGunKickStaticDecay; + } + + static void ConvertJsonAttViewKick(JsonAttViewKick& jViewKick, const AttViewKick& viewKick) + { + jViewKick.hipViewKickPitchMin = viewKick.hipViewKickPitchMin; + jViewKick.hipViewKickPitchMax = viewKick.hipViewKickPitchMax; + jViewKick.hipViewKickYawMin = viewKick.hipViewKickYawMin; + jViewKick.hipViewKickYawMax = viewKick.hipViewKickYawMax; + jViewKick.hipViewKickCenterSpeed = viewKick.hipViewKickCenterSpeed; + jViewKick.adsViewKickPitchMin = viewKick.adsViewKickPitchMin; + jViewKick.adsViewKickPitchMax = viewKick.adsViewKickPitchMax; + jViewKick.adsViewKickYawMin = viewKick.adsViewKickYawMin; + jViewKick.adsViewKickYawMax = viewKick.adsViewKickYawMax; + jViewKick.adsViewKickCenterSpeed = viewKick.adsViewKickCenterSpeed; + } + + static void ConvertJsonAttADSOverlay(JsonAttADSOverlay& jAdsOverlay, const AttADSOverlay& adsOverlay) + { + if (adsOverlay.overlay.shader && adsOverlay.overlay.shader->info.name) + jAdsOverlay.shader = AssetName(adsOverlay.overlay.shader->info.name); + + if (adsOverlay.overlay.shaderLowRes && adsOverlay.overlay.shaderLowRes->info.name) + jAdsOverlay.shaderLowRes = AssetName(adsOverlay.overlay.shaderLowRes->info.name); + + if (adsOverlay.overlay.shaderEMP && adsOverlay.overlay.shaderEMP->info.name) + jAdsOverlay.shaderEMP = AssetName(adsOverlay.overlay.shaderEMP->info.name); + + if (adsOverlay.overlay.shaderEMPLowRes && adsOverlay.overlay.shaderEMPLowRes->info.name) + jAdsOverlay.shaderEMPLowRes = AssetName(adsOverlay.overlay.shaderEMPLowRes->info.name); + + jAdsOverlay.reticle = adsOverlay.overlay.reticle; + jAdsOverlay.width = adsOverlay.overlay.width; + jAdsOverlay.height = adsOverlay.overlay.height; + jAdsOverlay.widthSplitscreen = adsOverlay.overlay.widthSplitscreen; + jAdsOverlay.heightSplitscreen = adsOverlay.overlay.heightSplitscreen; + jAdsOverlay.thermalScope = adsOverlay.thermalScope; + } + + static void ConvertJsonAttUI(JsonAttUI& jUi, const AttUI& ui) + { + if (ui.dpadIcon && ui.dpadIcon->info.name) + jUi.dpadIcon = AssetName(ui.dpadIcon->info.name); + if (ui.ammoCounterIcon && ui.ammoCounterIcon->info.name) + jUi.ammoCounterIcon = AssetName(ui.ammoCounterIcon->info.name); + + jUi.dpadIconRatio = ui.dpadIconRatio; + jUi.ammoCounterIconRatio = ui.ammoCounterIconRatio; + jUi.ammoCounterClip = ui.ammoCounterClip; + } + + static void ConvertJsonAttRumbles(JsonAttRumbles& jRumbles, const AttRumbles& rumbles) + { + if (rumbles.fireRumble) + jRumbles.fireRumble = rumbles.fireRumble; + + if (rumbles.meleeImpactRumble) + jRumbles.meleeImpactRumble = rumbles.meleeImpactRumble; + } + + static void ConvertJsonAttProjectile(JsonAttProjectile& jProjectile, const AttProjectile& projectile) + { + jProjectile.explosionRadius = projectile.explosionRadius; + jProjectile.explosionInnerDamage = projectile.explosionInnerDamage; + jProjectile.explosionOuterDamage = projectile.explosionOuterDamage; + jProjectile.damageConeAngle = projectile.damageConeAngle; + jProjectile.projectileSpeed = projectile.projectileSpeed; + jProjectile.projectileSpeedUp = projectile.projectileSpeedUp; + jProjectile.projectileActivateDist = projectile.projectileActivateDist; + jProjectile.projectileLifetime = projectile.projectileLifetime; + + if (projectile.projectileModel && projectile.projectileModel->name) + jProjectile.projectileModel = AssetName(projectile.projectileModel->name); + + jProjectile.projExplosionType = projectile.projExplosionType; + + if (projectile.projExplosionEffect && projectile.projExplosionEffect->name) + jProjectile.projExplosionEffect = AssetName(projectile.projExplosionEffect->name); + + jProjectile.projExplosionEffectForceNormalUp = projectile.projExplosionEffectForceNormalUp; + + if (projectile.projExplosionSound.name && projectile.projExplosionSound.name->soundName) + jProjectile.projExplosionSound = projectile.projExplosionSound.name->soundName; + + if (projectile.projDudEffect && projectile.projDudEffect->name) + jProjectile.projDudEffect = AssetName(projectile.projDudEffect->name); + + if (projectile.projDudSound.name && projectile.projDudSound.name->soundName) + jProjectile.projDudSound = projectile.projDudSound.name->soundName; + + jProjectile.projImpactExplode = projectile.projImpactExplode; + jProjectile.destabilizationRateTime = projectile.destabilizationRateTime; + jProjectile.destabilizationCurvatureMax = projectile.destabilizationCurvatureMax; + jProjectile.destabilizeDistance = projectile.destabilizeDistance; + + if (projectile.projTrailEffect && projectile.projTrailEffect->name) + jProjectile.projTrailEffect = AssetName(projectile.projTrailEffect->name); + + jProjectile.projIgnitionDelay = projectile.projIgnitionDelay; + + if (projectile.projIgnitionEffect && projectile.projIgnitionEffect->name) + jProjectile.projIgnitionEffect = AssetName(projectile.projIgnitionEffect->name); + + if (projectile.projIgnitionSound.name && projectile.projIgnitionSound.name->soundName) + jProjectile.projIgnitionSound = projectile.projIgnitionSound.name->soundName; + } + + std::ostream& m_stream; + }; +} // namespace + +namespace IW5 +{ + void DumpWeaponAttachmentAsJson(std::ostream& stream, const WeaponAttachment* attachment, AssetDumpingContext& context) + { + const JsonDumper dumper(context, stream); + dumper.Dump(attachment); + } +} // namespace IW5 diff --git a/src/ObjWriting/Game/IW5/Weapon/JsonWeaponAttachmentWriter.h b/src/ObjWriting/Game/IW5/Weapon/JsonWeaponAttachmentWriter.h new file mode 100644 index 00000000..dc0a84c2 --- /dev/null +++ b/src/ObjWriting/Game/IW5/Weapon/JsonWeaponAttachmentWriter.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Dumping/AssetDumpingContext.h" +#include "Game/IW5/IW5.h" + +#include + +namespace IW5 +{ + void DumpWeaponAttachmentAsJson(std::ostream& stream, const WeaponAttachment* attachment, AssetDumpingContext& context); +} // namespace IW5 diff --git a/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp b/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp index f03d1db1..b3cc16d3 100644 --- a/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp @@ -10,6 +10,7 @@ #include "AssetDumpers/AssetDumperScriptFile.h" #include "AssetDumpers/AssetDumperStringTable.h" #include "AssetDumpers/AssetDumperWeapon.h" +#include "AssetDumpers/AssetDumperWeaponAttachment.h" #include "AssetDumpers/AssetDumperXModel.h" #include "Game/IW5/GameAssetPoolIW5.h" #include "Game/IW5/GameIW5.h" @@ -59,7 +60,7 @@ bool ZoneDumper::DumpZone(AssetDumpingContext& context) const DUMP_ASSET_POOL(AssetDumperMenuList, m_menu_list, ASSET_TYPE_MENULIST) DUMP_ASSET_POOL(AssetDumperMenuDef, m_menu_def, ASSET_TYPE_MENU) DUMP_ASSET_POOL(AssetDumperLocalizeEntry, m_localize, ASSET_TYPE_LOCALIZE_ENTRY) - // DUMP_ASSET_POOL(AssetDumperWeaponAttachment, m_attachment, ASSET_TYPE_ATTACHMENT) + DUMP_ASSET_POOL(AssetDumperWeaponAttachment, m_attachment, ASSET_TYPE_ATTACHMENT) DUMP_ASSET_POOL(AssetDumperWeapon, m_weapon, ASSET_TYPE_WEAPON) // DUMP_ASSET_POOL(AssetDumperFxEffectDef, m_fx, ASSET_TYPE_FX) // DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table, ASSET_TYPE_IMPACT_FX)