mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-07-02 22:08:11 +00:00
feat: IW3 weapon loading and dumping (#867)
* feat: IW3 weapon loading and dumping * chore: adjust weapon strings for iw3 * chore: use original capitalization for aifuseTime * chore: remove unused alternative iw3 csp fields * chore: add missing checks and style the code similar to t5 * chore: small code smells in t5 weapon loader * feat: add iw3 gdt loader * chore: adjust weapon loader file names to t5 style * feat: add gdt dumper for iw3 weapons --------- Co-authored-by: Jan Laupetin <jan@laupetin.net>
This commit is contained in:
@@ -32,7 +32,7 @@ using `Linker`):
|
|||||||
| MenuList | ❌ | ❌ | |
|
| MenuList | ❌ | ❌ | |
|
||||||
| menuDef_t | ❌ | ❌ | |
|
| menuDef_t | ❌ | ❌ | |
|
||||||
| LocalizeEntry | ✅ | ✅ | |
|
| LocalizeEntry | ✅ | ✅ | |
|
||||||
| WeaponDef | ❌ | ❌ | |
|
| WeaponDef | ✅ | ✅ | |
|
||||||
| FxEffectDef | ❌ | ❌ | |
|
| FxEffectDef | ❌ | ❌ | |
|
||||||
| FxImpactTable | ❌ | ❌ | |
|
| FxImpactTable | ❌ | ❌ | |
|
||||||
| RawFile | ✅ | ✅ | |
|
| RawFile | ✅ | ✅ | |
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ namespace
|
|||||||
"vertexdecl",
|
"vertexdecl",
|
||||||
"vertexshader",
|
"vertexshader",
|
||||||
"pixelshader",
|
"pixelshader",
|
||||||
|
"accuracygraph",
|
||||||
};
|
};
|
||||||
static_assert(std::extent_v<decltype(SUB_ASSET_TYPE_NAMES)> == SUB_ASSET_TYPE_COUNT);
|
static_assert(std::extent_v<decltype(SUB_ASSET_TYPE_NAMES)> == SUB_ASSET_TYPE_COUNT);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ namespace IW3
|
|||||||
SUB_ASSET_TYPE_VERTEX_DECL,
|
SUB_ASSET_TYPE_VERTEX_DECL,
|
||||||
SUB_ASSET_TYPE_VERTEX_SHADER,
|
SUB_ASSET_TYPE_VERTEX_SHADER,
|
||||||
SUB_ASSET_TYPE_PIXEL_SHADER,
|
SUB_ASSET_TYPE_PIXEL_SHADER,
|
||||||
|
SUB_ASSET_TYPE_ACCURACY_GRAPH,
|
||||||
|
|
||||||
SUB_ASSET_TYPE_COUNT
|
SUB_ASSET_TYPE_COUNT
|
||||||
};
|
};
|
||||||
@@ -156,9 +157,18 @@ namespace IW3
|
|||||||
WFT_HIDETAGS,
|
WFT_HIDETAGS,
|
||||||
WFT_NOTETRACKSOUNDMAP,
|
WFT_NOTETRACKSOUNDMAP,
|
||||||
|
|
||||||
|
// Custom
|
||||||
|
WFT_ANIM_NAME,
|
||||||
|
|
||||||
WFT_NUM_FIELD_TYPES
|
WFT_NUM_FIELD_TYPES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AccuracyGraph
|
||||||
|
{
|
||||||
|
vec2_t* graphKnots;
|
||||||
|
int graphKnotCount;
|
||||||
|
};
|
||||||
|
|
||||||
using AssetPhysPreset = Asset<ASSET_TYPE_PHYSPRESET, PhysPreset>;
|
using AssetPhysPreset = Asset<ASSET_TYPE_PHYSPRESET, PhysPreset>;
|
||||||
using AssetXAnim = Asset<ASSET_TYPE_XANIMPARTS, XAnimParts>;
|
using AssetXAnim = Asset<ASSET_TYPE_XANIMPARTS, XAnimParts>;
|
||||||
using AssetXModel = Asset<ASSET_TYPE_XMODEL, XModel>;
|
using AssetXModel = Asset<ASSET_TYPE_XMODEL, XModel>;
|
||||||
@@ -191,6 +201,7 @@ namespace IW3
|
|||||||
using SubAssetVertexDecl = SubAsset<SUB_ASSET_TYPE_VERTEX_DECL, MaterialVertexDeclaration>;
|
using SubAssetVertexDecl = SubAsset<SUB_ASSET_TYPE_VERTEX_DECL, MaterialVertexDeclaration>;
|
||||||
using SubAssetVertexShader = SubAsset<SUB_ASSET_TYPE_VERTEX_SHADER, MaterialVertexShader>;
|
using SubAssetVertexShader = SubAsset<SUB_ASSET_TYPE_VERTEX_SHADER, MaterialVertexShader>;
|
||||||
using SubAssetPixelShader = SubAsset<SUB_ASSET_TYPE_PIXEL_SHADER, MaterialPixelShader>;
|
using SubAssetPixelShader = SubAsset<SUB_ASSET_TYPE_PIXEL_SHADER, MaterialPixelShader>;
|
||||||
|
using SubAssetAccuracyGraph = SubAsset<SUB_ASSET_TYPE_ACCURACY_GRAPH, AccuracyGraph>;
|
||||||
} // namespace IW3
|
} // namespace IW3
|
||||||
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetPhysPreset, name);
|
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetPhysPreset, name);
|
||||||
|
|||||||
@@ -2731,7 +2731,8 @@ namespace IW3
|
|||||||
WEAPTYPE_GRENADE = 0x1,
|
WEAPTYPE_GRENADE = 0x1,
|
||||||
WEAPTYPE_PROJECTILE = 0x2,
|
WEAPTYPE_PROJECTILE = 0x2,
|
||||||
WEAPTYPE_BINOCULARS = 0x3,
|
WEAPTYPE_BINOCULARS = 0x3,
|
||||||
WEAPTYPE_NUM = 0x4,
|
|
||||||
|
WEAPTYPE_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum weapClass_t
|
enum weapClass_t
|
||||||
@@ -2746,7 +2747,8 @@ namespace IW3
|
|||||||
WEAPCLASS_TURRET = 0x7,
|
WEAPCLASS_TURRET = 0x7,
|
||||||
WEAPCLASS_NON_PLAYER = 0x8,
|
WEAPCLASS_NON_PLAYER = 0x8,
|
||||||
WEAPCLASS_ITEM = 0x9,
|
WEAPCLASS_ITEM = 0x9,
|
||||||
WEAPCLASS_NUM = 0xA,
|
|
||||||
|
WEAPCLASS_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PenetrateType
|
enum PenetrateType
|
||||||
@@ -2755,7 +2757,8 @@ namespace IW3
|
|||||||
PENETRATE_TYPE_SMALL = 0x1,
|
PENETRATE_TYPE_SMALL = 0x1,
|
||||||
PENETRATE_TYPE_MEDIUM = 0x2,
|
PENETRATE_TYPE_MEDIUM = 0x2,
|
||||||
PENETRATE_TYPE_LARGE = 0x3,
|
PENETRATE_TYPE_LARGE = 0x3,
|
||||||
PENETRATE_TYPE_COUNT = 0x4,
|
|
||||||
|
PENETRATE_TYPE_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ImpactType
|
enum ImpactType
|
||||||
@@ -2769,7 +2772,8 @@ namespace IW3
|
|||||||
IMPACT_TYPE_GRENADE_EXPLODE = 0x6,
|
IMPACT_TYPE_GRENADE_EXPLODE = 0x6,
|
||||||
IMPACT_TYPE_ROCKET_EXPLODE = 0x7,
|
IMPACT_TYPE_ROCKET_EXPLODE = 0x7,
|
||||||
IMPACT_TYPE_PROJECTILE_DUD = 0x8,
|
IMPACT_TYPE_PROJECTILE_DUD = 0x8,
|
||||||
IMPACT_TYPE_COUNT = 0x9,
|
|
||||||
|
IMPACT_TYPE_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum weapInventoryType_t
|
enum weapInventoryType_t
|
||||||
@@ -2778,7 +2782,8 @@ namespace IW3
|
|||||||
WEAPINVENTORY_OFFHAND = 0x1,
|
WEAPINVENTORY_OFFHAND = 0x1,
|
||||||
WEAPINVENTORY_ITEM = 0x2,
|
WEAPINVENTORY_ITEM = 0x2,
|
||||||
WEAPINVENTORY_ALTMODE = 0x3,
|
WEAPINVENTORY_ALTMODE = 0x3,
|
||||||
WEAPINVENTORYCOUNT = 0x4,
|
|
||||||
|
WEAPINVENTORY_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum weapFireType_t
|
enum weapFireType_t
|
||||||
@@ -2788,7 +2793,8 @@ namespace IW3
|
|||||||
WEAPON_FIRETYPE_BURSTFIRE2 = 0x2,
|
WEAPON_FIRETYPE_BURSTFIRE2 = 0x2,
|
||||||
WEAPON_FIRETYPE_BURSTFIRE3 = 0x3,
|
WEAPON_FIRETYPE_BURSTFIRE3 = 0x3,
|
||||||
WEAPON_FIRETYPE_BURSTFIRE4 = 0x4,
|
WEAPON_FIRETYPE_BURSTFIRE4 = 0x4,
|
||||||
WEAPON_FIRETYPECOUNT = 0x5,
|
|
||||||
|
WEAPON_FIRETYPE_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum OffhandClass
|
enum OffhandClass
|
||||||
@@ -2797,7 +2803,8 @@ namespace IW3
|
|||||||
OFFHAND_CLASS_FRAG_GRENADE = 0x1,
|
OFFHAND_CLASS_FRAG_GRENADE = 0x1,
|
||||||
OFFHAND_CLASS_SMOKE_GRENADE = 0x2,
|
OFFHAND_CLASS_SMOKE_GRENADE = 0x2,
|
||||||
OFFHAND_CLASS_FLASH_GRENADE = 0x3,
|
OFFHAND_CLASS_FLASH_GRENADE = 0x3,
|
||||||
OFFHAND_CLASS_COUNT = 0x4,
|
|
||||||
|
OFFHAND_CLASS_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum weapStance_t
|
enum weapStance_t
|
||||||
@@ -2805,7 +2812,8 @@ namespace IW3
|
|||||||
WEAPSTANCE_STAND = 0x0,
|
WEAPSTANCE_STAND = 0x0,
|
||||||
WEAPSTANCE_DUCK = 0x1,
|
WEAPSTANCE_DUCK = 0x1,
|
||||||
WEAPSTANCE_PRONE = 0x2,
|
WEAPSTANCE_PRONE = 0x2,
|
||||||
WEAPSTANCE_NUM = 0x3,
|
|
||||||
|
WEAPSTANCE_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum activeReticleType_t
|
enum activeReticleType_t
|
||||||
@@ -2813,7 +2821,8 @@ namespace IW3
|
|||||||
VEH_ACTIVE_RETICLE_NONE = 0x0,
|
VEH_ACTIVE_RETICLE_NONE = 0x0,
|
||||||
VEH_ACTIVE_RETICLE_PIP_ON_A_STICK = 0x1,
|
VEH_ACTIVE_RETICLE_PIP_ON_A_STICK = 0x1,
|
||||||
VEH_ACTIVE_RETICLE_BOUNCING_DIAMOND = 0x2,
|
VEH_ACTIVE_RETICLE_BOUNCING_DIAMOND = 0x2,
|
||||||
VEH_ACTIVE_RETICLE_COUNT = 0x3,
|
|
||||||
|
VEH_ACTIVE_RETICLE_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum weaponIconRatioType_t
|
enum weaponIconRatioType_t
|
||||||
@@ -2821,7 +2830,8 @@ namespace IW3
|
|||||||
WEAPON_ICON_RATIO_1TO1 = 0x0,
|
WEAPON_ICON_RATIO_1TO1 = 0x0,
|
||||||
WEAPON_ICON_RATIO_2TO1 = 0x1,
|
WEAPON_ICON_RATIO_2TO1 = 0x1,
|
||||||
WEAPON_ICON_RATIO_4TO1 = 0x2,
|
WEAPON_ICON_RATIO_4TO1 = 0x2,
|
||||||
WEAPON_ICON_RATIO_COUNT = 0x3,
|
|
||||||
|
WEAPON_ICON_RATIO_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ammoCounterClipType_t
|
enum ammoCounterClipType_t
|
||||||
@@ -2833,14 +2843,16 @@ namespace IW3
|
|||||||
AMMO_COUNTER_CLIP_ROCKET = 0x4,
|
AMMO_COUNTER_CLIP_ROCKET = 0x4,
|
||||||
AMMO_COUNTER_CLIP_BELTFED = 0x5,
|
AMMO_COUNTER_CLIP_BELTFED = 0x5,
|
||||||
AMMO_COUNTER_CLIP_ALTWEAPON = 0x6,
|
AMMO_COUNTER_CLIP_ALTWEAPON = 0x6,
|
||||||
AMMO_COUNTER_CLIP_COUNT = 0x7,
|
|
||||||
|
AMMO_COUNTER_CLIP_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum weapOverlayReticle_t
|
enum weapOverlayReticle_t
|
||||||
{
|
{
|
||||||
WEAPOVERLAYRETICLE_NONE = 0x0,
|
WEAPOVERLAYRETICLE_NONE = 0x0,
|
||||||
WEAPOVERLAYRETICLE_CROSSHAIR = 0x1,
|
WEAPOVERLAYRETICLE_CROSSHAIR = 0x1,
|
||||||
WEAPOVERLAYRETICLE_NUM = 0x2,
|
|
||||||
|
WEAPOVERLAYRETICLE_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum WeapOverlayInteface_t
|
enum WeapOverlayInteface_t
|
||||||
@@ -2848,7 +2860,8 @@ namespace IW3
|
|||||||
WEAPOVERLAYINTERFACE_NONE = 0x0,
|
WEAPOVERLAYINTERFACE_NONE = 0x0,
|
||||||
WEAPOVERLAYINTERFACE_JAVELIN = 0x1,
|
WEAPOVERLAYINTERFACE_JAVELIN = 0x1,
|
||||||
WEAPOVERLAYINTERFACE_TURRETSCOPE = 0x2,
|
WEAPOVERLAYINTERFACE_TURRETSCOPE = 0x2,
|
||||||
WEAPOVERLAYINTERFACECOUNT = 0x3,
|
|
||||||
|
WEAPOVERLAYINTERFACE_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum weapProjExposion_t
|
enum weapProjExposion_t
|
||||||
@@ -2860,7 +2873,8 @@ namespace IW3
|
|||||||
WEAPPROJEXP_DUD = 0x4,
|
WEAPPROJEXP_DUD = 0x4,
|
||||||
WEAPPROJEXP_SMOKE = 0x5,
|
WEAPPROJEXP_SMOKE = 0x5,
|
||||||
WEAPPROJEXP_HEAVY = 0x6,
|
WEAPPROJEXP_HEAVY = 0x6,
|
||||||
WEAPPROJEXP_NUM = 0x7,
|
|
||||||
|
WEAPPROJEXP_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum WeapStickinessType
|
enum WeapStickinessType
|
||||||
@@ -2869,7 +2883,8 @@ namespace IW3
|
|||||||
WEAPSTICKINESS_ALL = 0x1,
|
WEAPSTICKINESS_ALL = 0x1,
|
||||||
WEAPSTICKINESS_GROUND = 0x2,
|
WEAPSTICKINESS_GROUND = 0x2,
|
||||||
WEAPSTICKINESS_GROUND_WITH_YAW = 0x3,
|
WEAPSTICKINESS_GROUND_WITH_YAW = 0x3,
|
||||||
WEAPSTICKINESS_COUNT = 0x4,
|
|
||||||
|
WEAPSTICKINESS_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum guidedMissileType_t
|
enum guidedMissileType_t
|
||||||
@@ -2878,7 +2893,47 @@ namespace IW3
|
|||||||
MISSILE_GUIDANCE_SIDEWINDER = 0x1,
|
MISSILE_GUIDANCE_SIDEWINDER = 0x1,
|
||||||
MISSILE_GUIDANCE_HELLFIRE = 0x2,
|
MISSILE_GUIDANCE_HELLFIRE = 0x2,
|
||||||
MISSILE_GUIDANCE_JAVELIN = 0x3,
|
MISSILE_GUIDANCE_JAVELIN = 0x3,
|
||||||
MISSILE_GUIDANCE_COUNT = 0x4,
|
|
||||||
|
MISSILE_GUIDANCE_NUM,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum WeaponAnimSlot
|
||||||
|
{
|
||||||
|
WEAP_ANIM_ROOT = 0x0,
|
||||||
|
WEAP_ANIM_IDLE = 0x1,
|
||||||
|
WEAP_ANIM_EMPTY_IDLE = 0x2,
|
||||||
|
WEAP_ANIM_FIRE = 0x3,
|
||||||
|
WEAP_ANIM_HOLD_FIRE = 0x4,
|
||||||
|
WEAP_ANIM_LASTSHOT = 0x5,
|
||||||
|
WEAP_ANIM_RECHAMBER = 0x6,
|
||||||
|
WEAP_ANIM_MELEE = 0x7,
|
||||||
|
WEAP_ANIM_MELEE_CHARGE = 0x8,
|
||||||
|
WEAP_ANIM_RELOAD = 0x9,
|
||||||
|
WEAP_ANIM_RELOAD_EMPTY = 0xA,
|
||||||
|
WEAP_ANIM_RELOAD_START = 0xB,
|
||||||
|
WEAP_ANIM_RELOAD_END = 0xC,
|
||||||
|
WEAP_ANIM_RAISE = 0xD,
|
||||||
|
WEAP_ANIM_FIRST_RAISE = 0xE,
|
||||||
|
WEAP_ANIM_DROP = 0xF,
|
||||||
|
WEAP_ANIM_ALT_RAISE = 0x10,
|
||||||
|
WEAP_ANIM_ALT_DROP = 0x11,
|
||||||
|
WEAP_ANIM_QUICK_RAISE = 0x12,
|
||||||
|
WEAP_ANIM_QUICK_DROP = 0x13,
|
||||||
|
WEAP_ANIM_EMPTY_RAISE = 0x14,
|
||||||
|
WEAP_ANIM_EMPTY_DROP = 0x15,
|
||||||
|
WEAP_ANIM_SPRINT_IN = 0x16,
|
||||||
|
WEAP_ANIM_SPRINT_LOOP = 0x17,
|
||||||
|
WEAP_ANIM_SPRINT_OUT = 0x18,
|
||||||
|
WEAP_ANIM_DETONATE = 0x19,
|
||||||
|
WEAP_ANIM_NIGHTVISION_WEAR = 0x1A,
|
||||||
|
WEAP_ANIM_NIGHTVISION_REMOVE = 0x1B,
|
||||||
|
WEAP_ANIM_ADS_FIRE = 0x1C,
|
||||||
|
WEAP_ANIM_ADS_LASTSHOT = 0x1D,
|
||||||
|
WEAP_ANIM_ADS_RECHAMBER = 0x1E,
|
||||||
|
WEAP_ANIM_ADS_UP = 0x1F,
|
||||||
|
WEAP_ANIM_ADS_DOWN = 0x20,
|
||||||
|
|
||||||
|
NUM_WEAP_ANIMS,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum hitLocation_t
|
enum hitLocation_t
|
||||||
|
|||||||
@@ -0,0 +1,511 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Game/IW3/IW3.h"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace IW3
|
||||||
|
{
|
||||||
|
inline cspField_t weapon_fields[]{
|
||||||
|
{"displayName", offsetof(WeaponDef, szDisplayName), CSPFT_STRING },
|
||||||
|
{"AIOverlayDescription", offsetof(WeaponDef, szOverlayName), CSPFT_STRING },
|
||||||
|
{"modeName", offsetof(WeaponDef, szModeName), CSPFT_STRING },
|
||||||
|
{"playerAnimType", offsetof(WeaponDef, playerAnimType), WFT_ANIMTYPE },
|
||||||
|
{"gunModel", offsetof(WeaponDef, gunXModel[0]), CSPFT_XMODEL },
|
||||||
|
{"gunModel2", offsetof(WeaponDef, gunXModel[1]), CSPFT_XMODEL },
|
||||||
|
{"gunModel3", offsetof(WeaponDef, gunXModel[2]), CSPFT_XMODEL },
|
||||||
|
{"gunModel4", offsetof(WeaponDef, gunXModel[3]), CSPFT_XMODEL },
|
||||||
|
{"gunModel5", offsetof(WeaponDef, gunXModel[4]), CSPFT_XMODEL },
|
||||||
|
{"gunModel6", offsetof(WeaponDef, gunXModel[5]), CSPFT_XMODEL },
|
||||||
|
{"gunModel7", offsetof(WeaponDef, gunXModel[6]), CSPFT_XMODEL },
|
||||||
|
{"gunModel8", offsetof(WeaponDef, gunXModel[7]), CSPFT_XMODEL },
|
||||||
|
{"gunModel9", offsetof(WeaponDef, gunXModel[8]), CSPFT_XMODEL },
|
||||||
|
{"gunModel10", offsetof(WeaponDef, gunXModel[9]), CSPFT_XMODEL },
|
||||||
|
{"gunModel11", offsetof(WeaponDef, gunXModel[10]), CSPFT_XMODEL },
|
||||||
|
{"gunModel12", offsetof(WeaponDef, gunXModel[11]), CSPFT_XMODEL },
|
||||||
|
{"gunModel13", offsetof(WeaponDef, gunXModel[12]), CSPFT_XMODEL },
|
||||||
|
{"gunModel14", offsetof(WeaponDef, gunXModel[13]), CSPFT_XMODEL },
|
||||||
|
{"gunModel15", offsetof(WeaponDef, gunXModel[14]), CSPFT_XMODEL },
|
||||||
|
{"gunModel16", offsetof(WeaponDef, gunXModel[15]), CSPFT_XMODEL },
|
||||||
|
{"handModel", offsetof(WeaponDef, handXModel), CSPFT_XMODEL },
|
||||||
|
{"hideTags", offsetof(WeaponDef, hideTags), WFT_HIDETAGS },
|
||||||
|
{"notetrackSoundMap", offsetof(WeaponDef, notetrackSoundMapKeys), WFT_NOTETRACKSOUNDMAP },
|
||||||
|
{"idleAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_IDLE]), WFT_ANIM_NAME },
|
||||||
|
{"emptyIdleAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_EMPTY_IDLE]), WFT_ANIM_NAME },
|
||||||
|
{"fireAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_FIRE]), WFT_ANIM_NAME },
|
||||||
|
{"holdFireAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_HOLD_FIRE]), WFT_ANIM_NAME },
|
||||||
|
{"lastShotAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_LASTSHOT]), WFT_ANIM_NAME },
|
||||||
|
{"detonateAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_DETONATE]), WFT_ANIM_NAME },
|
||||||
|
{"rechamberAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_RECHAMBER]), WFT_ANIM_NAME },
|
||||||
|
{"meleeAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_MELEE]), WFT_ANIM_NAME },
|
||||||
|
{"meleeChargeAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_MELEE_CHARGE]), WFT_ANIM_NAME },
|
||||||
|
{"reloadAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_RELOAD]), WFT_ANIM_NAME },
|
||||||
|
{"reloadEmptyAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_RELOAD_EMPTY]), WFT_ANIM_NAME },
|
||||||
|
{"reloadStartAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_RELOAD_START]), WFT_ANIM_NAME },
|
||||||
|
{"reloadEndAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_RELOAD_END]), WFT_ANIM_NAME },
|
||||||
|
{"raiseAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_RAISE]), WFT_ANIM_NAME },
|
||||||
|
{"dropAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_DROP]), WFT_ANIM_NAME },
|
||||||
|
{"firstRaiseAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_FIRST_RAISE]), WFT_ANIM_NAME },
|
||||||
|
{"altRaiseAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_ALT_RAISE]), WFT_ANIM_NAME },
|
||||||
|
{"altDropAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_ALT_DROP]), WFT_ANIM_NAME },
|
||||||
|
{"quickRaiseAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_QUICK_RAISE]), WFT_ANIM_NAME },
|
||||||
|
{"quickDropAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_QUICK_DROP]), WFT_ANIM_NAME },
|
||||||
|
{"emptyRaiseAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_EMPTY_RAISE]), WFT_ANIM_NAME },
|
||||||
|
{"emptyDropAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_EMPTY_DROP]), WFT_ANIM_NAME },
|
||||||
|
{"sprintInAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_SPRINT_IN]), WFT_ANIM_NAME },
|
||||||
|
{"sprintLoopAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_SPRINT_LOOP]), WFT_ANIM_NAME },
|
||||||
|
{"sprintOutAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_SPRINT_OUT]), WFT_ANIM_NAME },
|
||||||
|
{"nightVisionWearAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_NIGHTVISION_WEAR]), WFT_ANIM_NAME },
|
||||||
|
{"nightVisionRemoveAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_NIGHTVISION_REMOVE]), WFT_ANIM_NAME },
|
||||||
|
{"adsFireAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_ADS_FIRE]), WFT_ANIM_NAME },
|
||||||
|
{"adsLastShotAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_ADS_LASTSHOT]), WFT_ANIM_NAME },
|
||||||
|
{"adsRechamberAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_ADS_RECHAMBER]), WFT_ANIM_NAME },
|
||||||
|
{"adsUpAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_ADS_UP]), WFT_ANIM_NAME },
|
||||||
|
{"adsDownAnim", offsetof(WeaponDef, szXAnims[WEAP_ANIM_ADS_DOWN]), WFT_ANIM_NAME },
|
||||||
|
{"script", offsetof(WeaponDef, szScript), CSPFT_STRING },
|
||||||
|
{"weaponType", offsetof(WeaponDef, weapType), WFT_WEAPONTYPE },
|
||||||
|
{"weaponClass", offsetof(WeaponDef, weapClass), WFT_WEAPONCLASS },
|
||||||
|
{"penetrateType", offsetof(WeaponDef, penetrateType), WFT_PENETRATE_TYPE },
|
||||||
|
{"impactType", offsetof(WeaponDef, impactType), WFT_IMPACT_TYPE },
|
||||||
|
{"inventoryType", offsetof(WeaponDef, inventoryType), WFT_INVENTORYTYPE },
|
||||||
|
{"fireType", offsetof(WeaponDef, fireType), WFT_FIRETYPE },
|
||||||
|
{"offhandClass", offsetof(WeaponDef, offhandClass), WFT_OFFHAND_CLASS },
|
||||||
|
{"viewFlashEffect", offsetof(WeaponDef, viewFlashEffect), CSPFT_FX },
|
||||||
|
{"worldFlashEffect", offsetof(WeaponDef, worldFlashEffect), CSPFT_FX },
|
||||||
|
{"pickupSound", offsetof(WeaponDef, pickupSound), CSPFT_SOUND },
|
||||||
|
{"pickupSoundPlayer", offsetof(WeaponDef, pickupSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"ammoPickupSound", offsetof(WeaponDef, ammoPickupSound), CSPFT_SOUND },
|
||||||
|
{"ammoPickupSoundPlayer", offsetof(WeaponDef, ammoPickupSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"projectileSound", offsetof(WeaponDef, projectileSound), CSPFT_SOUND },
|
||||||
|
{"pullbackSound", offsetof(WeaponDef, pullbackSound), CSPFT_SOUND },
|
||||||
|
{"pullbackSoundPlayer", offsetof(WeaponDef, pullbackSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"fireSound", offsetof(WeaponDef, fireSound), CSPFT_SOUND },
|
||||||
|
{"fireSoundPlayer", offsetof(WeaponDef, fireSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"loopFireSound", offsetof(WeaponDef, fireLoopSound), CSPFT_SOUND },
|
||||||
|
{"loopFireSoundPlayer", offsetof(WeaponDef, fireLoopSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"stopFireSound", offsetof(WeaponDef, fireStopSound), CSPFT_SOUND },
|
||||||
|
{"stopFireSoundPlayer", offsetof(WeaponDef, fireStopSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"lastShotSound", offsetof(WeaponDef, fireLastSound), CSPFT_SOUND },
|
||||||
|
{"lastShotSoundPlayer", offsetof(WeaponDef, fireLastSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"emptyFireSound", offsetof(WeaponDef, emptyFireSound), CSPFT_SOUND },
|
||||||
|
{"emptyFireSoundPlayer", offsetof(WeaponDef, emptyFireSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"meleeSwipeSound", offsetof(WeaponDef, meleeSwipeSound), CSPFT_SOUND },
|
||||||
|
{"meleeSwipeSoundPlayer", offsetof(WeaponDef, meleeSwipeSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"meleeHitSound", offsetof(WeaponDef, meleeHitSound), CSPFT_SOUND },
|
||||||
|
{"meleeMissSound", offsetof(WeaponDef, meleeMissSound), CSPFT_SOUND },
|
||||||
|
{"rechamberSound", offsetof(WeaponDef, rechamberSound), CSPFT_SOUND },
|
||||||
|
{"rechamberSoundPlayer", offsetof(WeaponDef, rechamberSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"reloadSound", offsetof(WeaponDef, reloadSound), CSPFT_SOUND },
|
||||||
|
{"reloadSoundPlayer", offsetof(WeaponDef, reloadSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"reloadEmptySound", offsetof(WeaponDef, reloadEmptySound), CSPFT_SOUND },
|
||||||
|
{"reloadEmptySoundPlayer", offsetof(WeaponDef, reloadEmptySoundPlayer), CSPFT_SOUND },
|
||||||
|
{"reloadStartSound", offsetof(WeaponDef, reloadStartSound), CSPFT_SOUND },
|
||||||
|
{"reloadStartSoundPlayer", offsetof(WeaponDef, reloadStartSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"reloadEndSound", offsetof(WeaponDef, reloadEndSound), CSPFT_SOUND },
|
||||||
|
{"reloadEndSoundPlayer", offsetof(WeaponDef, reloadEndSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"detonateSound", offsetof(WeaponDef, detonateSound), CSPFT_SOUND },
|
||||||
|
{"detonateSoundPlayer", offsetof(WeaponDef, detonateSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"nightVisionWearSound", offsetof(WeaponDef, nightVisionWearSound), CSPFT_SOUND },
|
||||||
|
{"nightVisionWearSoundPlayer", offsetof(WeaponDef, nightVisionWearSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"nightVisionRemoveSound", offsetof(WeaponDef, nightVisionRemoveSound), CSPFT_SOUND },
|
||||||
|
{"nightVisionRemoveSoundPlayer", offsetof(WeaponDef, nightVisionRemoveSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"raiseSound", offsetof(WeaponDef, raiseSound), CSPFT_SOUND },
|
||||||
|
{"raiseSoundPlayer", offsetof(WeaponDef, raiseSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"firstRaiseSound", offsetof(WeaponDef, firstRaiseSound), CSPFT_SOUND },
|
||||||
|
{"firstRaiseSoundPlayer", offsetof(WeaponDef, firstRaiseSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"altSwitchSound", offsetof(WeaponDef, altSwitchSound), CSPFT_SOUND },
|
||||||
|
{"altSwitchSoundPlayer", offsetof(WeaponDef, altSwitchSoundPlayer), CSPFT_SOUND },
|
||||||
|
{"putawaySound", offsetof(WeaponDef, putawaySound), CSPFT_SOUND },
|
||||||
|
{"putawaySoundPlayer", offsetof(WeaponDef, putawaySoundPlayer), CSPFT_SOUND },
|
||||||
|
{"bounceSound", offsetof(WeaponDef, bounceSound), WFT_BOUNCE_SOUND },
|
||||||
|
{"viewShellEjectEffect", offsetof(WeaponDef, viewShellEjectEffect), CSPFT_FX },
|
||||||
|
{"worldShellEjectEffect", offsetof(WeaponDef, worldShellEjectEffect), CSPFT_FX },
|
||||||
|
{"viewLastShotEjectEffect", offsetof(WeaponDef, viewLastShotEjectEffect), CSPFT_FX },
|
||||||
|
{"worldLastShotEjectEffect", offsetof(WeaponDef, worldLastShotEjectEffect), CSPFT_FX },
|
||||||
|
{"reticleCenter", offsetof(WeaponDef, reticleCenter), CSPFT_MATERIAL },
|
||||||
|
{"reticleSide", offsetof(WeaponDef, reticleSide), CSPFT_MATERIAL },
|
||||||
|
{"reticleCenterSize", offsetof(WeaponDef, iReticleCenterSize), CSPFT_INT },
|
||||||
|
{"reticleSideSize", offsetof(WeaponDef, iReticleSideSize), CSPFT_INT },
|
||||||
|
{"reticleMinOfs", offsetof(WeaponDef, iReticleMinOfs), CSPFT_INT },
|
||||||
|
{"activeReticleType", offsetof(WeaponDef, activeReticleType), WFT_ACTIVE_RETICLE_TYPE },
|
||||||
|
{"standMoveF", offsetof(WeaponDef, vStandMove[0]), CSPFT_FLOAT },
|
||||||
|
{"standMoveR", offsetof(WeaponDef, vStandMove[1]), CSPFT_FLOAT },
|
||||||
|
{"standMoveU", offsetof(WeaponDef, vStandMove[2]), CSPFT_FLOAT },
|
||||||
|
{"standRotP", offsetof(WeaponDef, vStandRot[0]), CSPFT_FLOAT },
|
||||||
|
{"standRotY", offsetof(WeaponDef, vStandRot[1]), CSPFT_FLOAT },
|
||||||
|
{"standRotR", offsetof(WeaponDef, vStandRot[2]), CSPFT_FLOAT },
|
||||||
|
{"duckedOfsF", offsetof(WeaponDef, vDuckedOfs[0]), CSPFT_FLOAT },
|
||||||
|
{"duckedOfsR", offsetof(WeaponDef, vDuckedOfs[1]), CSPFT_FLOAT },
|
||||||
|
{"duckedOfsU", offsetof(WeaponDef, vDuckedOfs[2]), CSPFT_FLOAT },
|
||||||
|
{"duckedMoveF", offsetof(WeaponDef, vDuckedMove[0]), CSPFT_FLOAT },
|
||||||
|
{"duckedMoveR", offsetof(WeaponDef, vDuckedMove[1]), CSPFT_FLOAT },
|
||||||
|
{"duckedMoveU", offsetof(WeaponDef, vDuckedMove[2]), CSPFT_FLOAT },
|
||||||
|
{"duckedRotP", offsetof(WeaponDef, vDuckedRot[0]), CSPFT_FLOAT },
|
||||||
|
{"duckedRotY", offsetof(WeaponDef, vDuckedRot[1]), CSPFT_FLOAT },
|
||||||
|
{"duckedRotR", offsetof(WeaponDef, vDuckedRot[2]), CSPFT_FLOAT },
|
||||||
|
{"proneOfsF", offsetof(WeaponDef, vProneOfs[0]), CSPFT_FLOAT },
|
||||||
|
{"proneOfsR", offsetof(WeaponDef, vProneOfs[1]), CSPFT_FLOAT },
|
||||||
|
{"proneOfsU", offsetof(WeaponDef, vProneOfs[2]), CSPFT_FLOAT },
|
||||||
|
{"proneMoveF", offsetof(WeaponDef, vProneMove[0]), CSPFT_FLOAT },
|
||||||
|
{"proneMoveR", offsetof(WeaponDef, vProneMove[1]), CSPFT_FLOAT },
|
||||||
|
{"proneMoveU", offsetof(WeaponDef, vProneMove[2]), CSPFT_FLOAT },
|
||||||
|
{"proneRotP", offsetof(WeaponDef, vProneRot[0]), CSPFT_FLOAT },
|
||||||
|
{"proneRotY", offsetof(WeaponDef, vProneRot[1]), CSPFT_FLOAT },
|
||||||
|
{"proneRotR", offsetof(WeaponDef, vProneRot[2]), CSPFT_FLOAT },
|
||||||
|
{"posMoveRate", offsetof(WeaponDef, fPosMoveRate), CSPFT_FLOAT },
|
||||||
|
{"posProneMoveRate", offsetof(WeaponDef, fPosProneMoveRate), CSPFT_FLOAT },
|
||||||
|
{"standMoveMinSpeed", offsetof(WeaponDef, fStandMoveMinSpeed), CSPFT_FLOAT },
|
||||||
|
{"duckedMoveMinSpeed", offsetof(WeaponDef, fDuckedMoveMinSpeed), CSPFT_FLOAT },
|
||||||
|
{"proneMoveMinSpeed", offsetof(WeaponDef, fProneMoveMinSpeed), CSPFT_FLOAT },
|
||||||
|
{"posRotRate", offsetof(WeaponDef, fPosRotRate), CSPFT_FLOAT },
|
||||||
|
{"posProneRotRate", offsetof(WeaponDef, fPosProneRotRate), CSPFT_FLOAT },
|
||||||
|
{"standRotMinSpeed", offsetof(WeaponDef, fStandRotMinSpeed), CSPFT_FLOAT },
|
||||||
|
{"duckedRotMinSpeed", offsetof(WeaponDef, fDuckedRotMinSpeed), CSPFT_FLOAT },
|
||||||
|
{"proneRotMinSpeed", offsetof(WeaponDef, fProneRotMinSpeed), CSPFT_FLOAT },
|
||||||
|
{"worldModel", offsetof(WeaponDef, worldModel[0]), CSPFT_XMODEL },
|
||||||
|
{"worldModel2", offsetof(WeaponDef, worldModel[1]), CSPFT_XMODEL },
|
||||||
|
{"worldModel3", offsetof(WeaponDef, worldModel[2]), CSPFT_XMODEL },
|
||||||
|
{"worldModel4", offsetof(WeaponDef, worldModel[3]), CSPFT_XMODEL },
|
||||||
|
{"worldModel5", offsetof(WeaponDef, worldModel[4]), CSPFT_XMODEL },
|
||||||
|
{"worldModel6", offsetof(WeaponDef, worldModel[5]), CSPFT_XMODEL },
|
||||||
|
{"worldModel7", offsetof(WeaponDef, worldModel[6]), CSPFT_XMODEL },
|
||||||
|
{"worldModel8", offsetof(WeaponDef, worldModel[7]), CSPFT_XMODEL },
|
||||||
|
{"worldModel9", offsetof(WeaponDef, worldModel[8]), CSPFT_XMODEL },
|
||||||
|
{"worldModel10", offsetof(WeaponDef, worldModel[9]), CSPFT_XMODEL },
|
||||||
|
{"worldModel11", offsetof(WeaponDef, worldModel[10]), CSPFT_XMODEL },
|
||||||
|
{"worldModel12", offsetof(WeaponDef, worldModel[11]), CSPFT_XMODEL },
|
||||||
|
{"worldModel13", offsetof(WeaponDef, worldModel[12]), CSPFT_XMODEL },
|
||||||
|
{"worldModel14", offsetof(WeaponDef, worldModel[13]), CSPFT_XMODEL },
|
||||||
|
{"worldModel15", offsetof(WeaponDef, worldModel[14]), CSPFT_XMODEL },
|
||||||
|
{"worldModel16", offsetof(WeaponDef, worldModel[15]), CSPFT_XMODEL },
|
||||||
|
{"worldClipModel", offsetof(WeaponDef, worldClipModel), CSPFT_XMODEL },
|
||||||
|
{"rocketModel", offsetof(WeaponDef, rocketModel), CSPFT_XMODEL },
|
||||||
|
{"knifeModel", offsetof(WeaponDef, knifeModel), CSPFT_XMODEL },
|
||||||
|
{"worldKnifeModel", offsetof(WeaponDef, worldKnifeModel), CSPFT_XMODEL },
|
||||||
|
{"hudIcon", offsetof(WeaponDef, hudIcon), CSPFT_MATERIAL },
|
||||||
|
{"hudIconRatio", offsetof(WeaponDef, hudIconRatio), WFT_ICONRATIO_HUD },
|
||||||
|
{"ammoCounterIcon", offsetof(WeaponDef, ammoCounterIcon), CSPFT_MATERIAL },
|
||||||
|
{"ammoCounterIconRatio", offsetof(WeaponDef, ammoCounterIconRatio), WFT_ICONRATIO_AMMOCOUNTER},
|
||||||
|
{"ammoCounterClip", offsetof(WeaponDef, ammoCounterClip), WFT_AMMOCOUNTER_CLIPTYPE },
|
||||||
|
{"startAmmo", offsetof(WeaponDef, iStartAmmo), CSPFT_INT },
|
||||||
|
{"ammoName", offsetof(WeaponDef, szAmmoName), CSPFT_STRING },
|
||||||
|
{"clipName", offsetof(WeaponDef, szClipName), CSPFT_STRING },
|
||||||
|
{"maxAmmo", offsetof(WeaponDef, iMaxAmmo), CSPFT_INT },
|
||||||
|
{"clipSize", offsetof(WeaponDef, iClipSize), CSPFT_INT },
|
||||||
|
{"shotCount", offsetof(WeaponDef, shotCount), CSPFT_INT },
|
||||||
|
{"sharedAmmoCapName", offsetof(WeaponDef, szSharedAmmoCapName), CSPFT_STRING },
|
||||||
|
{"sharedAmmoCap", offsetof(WeaponDef, iSharedAmmoCap), CSPFT_INT },
|
||||||
|
{"damage", offsetof(WeaponDef, damage), CSPFT_INT },
|
||||||
|
{"playerDamage", offsetof(WeaponDef, playerDamage), CSPFT_INT },
|
||||||
|
{"meleeDamage", offsetof(WeaponDef, iMeleeDamage), CSPFT_INT },
|
||||||
|
{"minDamage", offsetof(WeaponDef, minDamage), CSPFT_INT },
|
||||||
|
{"minPlayerDamage", offsetof(WeaponDef, minPlayerDamage), CSPFT_INT },
|
||||||
|
{"maxDamageRange", offsetof(WeaponDef, fMaxDamageRange), CSPFT_FLOAT },
|
||||||
|
{"minDamageRange", offsetof(WeaponDef, fMinDamageRange), CSPFT_FLOAT },
|
||||||
|
{"destabilizationRateTime", offsetof(WeaponDef, destabilizationRateTime), CSPFT_FLOAT },
|
||||||
|
{"destabilizationCurvatureMax", offsetof(WeaponDef, destabilizationCurvatureMax), CSPFT_FLOAT },
|
||||||
|
{"destabilizeDistance", offsetof(WeaponDef, destabilizeDistance), CSPFT_INT },
|
||||||
|
{"fireDelay", offsetof(WeaponDef, iFireDelay), CSPFT_MILLISECONDS },
|
||||||
|
{"meleeDelay", offsetof(WeaponDef, iMeleeDelay), CSPFT_MILLISECONDS },
|
||||||
|
{"meleeChargeDelay", offsetof(WeaponDef, meleeChargeDelay), CSPFT_MILLISECONDS },
|
||||||
|
{"fireTime", offsetof(WeaponDef, iFireTime), CSPFT_MILLISECONDS },
|
||||||
|
{"rechamberTime", offsetof(WeaponDef, iRechamberTime), CSPFT_MILLISECONDS },
|
||||||
|
{"rechamberBoltTime", offsetof(WeaponDef, iRechamberBoltTime), CSPFT_MILLISECONDS },
|
||||||
|
{"holdFireTime", offsetof(WeaponDef, iHoldFireTime), CSPFT_MILLISECONDS },
|
||||||
|
{"detonateTime", offsetof(WeaponDef, iDetonateTime), CSPFT_MILLISECONDS },
|
||||||
|
{"detonateDelay", offsetof(WeaponDef, iDetonateDelay), CSPFT_MILLISECONDS },
|
||||||
|
{"meleeTime", offsetof(WeaponDef, iMeleeTime), CSPFT_MILLISECONDS },
|
||||||
|
{"meleeChargeTime", offsetof(WeaponDef, meleeChargeTime), CSPFT_MILLISECONDS },
|
||||||
|
{"reloadTime", offsetof(WeaponDef, iReloadTime), CSPFT_MILLISECONDS },
|
||||||
|
{"reloadShowRocketTime", offsetof(WeaponDef, reloadShowRocketTime), CSPFT_MILLISECONDS },
|
||||||
|
{"reloadEmptyTime", offsetof(WeaponDef, iReloadEmptyTime), CSPFT_MILLISECONDS },
|
||||||
|
{"reloadAddTime", offsetof(WeaponDef, iReloadAddTime), CSPFT_MILLISECONDS },
|
||||||
|
{"reloadStartTime", offsetof(WeaponDef, iReloadStartTime), CSPFT_MILLISECONDS },
|
||||||
|
{"reloadStartAddTime", offsetof(WeaponDef, iReloadStartAddTime), CSPFT_MILLISECONDS },
|
||||||
|
{"reloadEndTime", offsetof(WeaponDef, iReloadEndTime), CSPFT_MILLISECONDS },
|
||||||
|
{"dropTime", offsetof(WeaponDef, iDropTime), CSPFT_MILLISECONDS },
|
||||||
|
{"raiseTime", offsetof(WeaponDef, iRaiseTime), CSPFT_MILLISECONDS },
|
||||||
|
{"altDropTime", offsetof(WeaponDef, iAltDropTime), CSPFT_MILLISECONDS },
|
||||||
|
{"altRaiseTime", offsetof(WeaponDef, iAltRaiseTime), CSPFT_MILLISECONDS },
|
||||||
|
{"quickDropTime", offsetof(WeaponDef, quickDropTime), CSPFT_MILLISECONDS },
|
||||||
|
{"quickRaiseTime", offsetof(WeaponDef, quickRaiseTime), CSPFT_MILLISECONDS },
|
||||||
|
{"firstRaiseTime", offsetof(WeaponDef, iFirstRaiseTime), CSPFT_MILLISECONDS },
|
||||||
|
{"emptyRaiseTime", offsetof(WeaponDef, iEmptyRaiseTime), CSPFT_MILLISECONDS },
|
||||||
|
{"emptyDropTime", offsetof(WeaponDef, iEmptyDropTime), CSPFT_MILLISECONDS },
|
||||||
|
{"sprintInTime", offsetof(WeaponDef, sprintInTime), CSPFT_MILLISECONDS },
|
||||||
|
{"sprintLoopTime", offsetof(WeaponDef, sprintLoopTime), CSPFT_MILLISECONDS },
|
||||||
|
{"sprintOutTime", offsetof(WeaponDef, sprintOutTime), CSPFT_MILLISECONDS },
|
||||||
|
{"nightVisionWearTime", offsetof(WeaponDef, nightVisionWearTime), CSPFT_MILLISECONDS },
|
||||||
|
{"nightVisionWearTimeFadeOutEnd", offsetof(WeaponDef, nightVisionWearTimeFadeOutEnd), CSPFT_MILLISECONDS },
|
||||||
|
{"nightVisionWearTimePowerUp", offsetof(WeaponDef, nightVisionWearTimePowerUp), CSPFT_MILLISECONDS },
|
||||||
|
{"nightVisionRemoveTime", offsetof(WeaponDef, nightVisionRemoveTime), CSPFT_MILLISECONDS },
|
||||||
|
{"nightVisionRemoveTimePowerDown", offsetof(WeaponDef, nightVisionRemoveTimePowerDown), CSPFT_MILLISECONDS },
|
||||||
|
{"nightVisionRemoveTimeFadeInStart", offsetof(WeaponDef, nightVisionRemoveTimeFadeInStart), CSPFT_MILLISECONDS },
|
||||||
|
{"fuseTime", offsetof(WeaponDef, fuseTime), CSPFT_MILLISECONDS },
|
||||||
|
{"aifuseTime", offsetof(WeaponDef, aiFuseTime), CSPFT_MILLISECONDS },
|
||||||
|
{"requireLockonToFire", offsetof(WeaponDef, requireLockonToFire), CSPFT_QBOOLEAN },
|
||||||
|
{"noAdsWhenMagEmpty", offsetof(WeaponDef, noAdsWhenMagEmpty), CSPFT_QBOOLEAN },
|
||||||
|
{"avoidDropCleanup", offsetof(WeaponDef, avoidDropCleanup), CSPFT_QBOOLEAN },
|
||||||
|
{"autoAimRange", offsetof(WeaponDef, autoAimRange), CSPFT_FLOAT },
|
||||||
|
{"aimAssistRange", offsetof(WeaponDef, aimAssistRange), CSPFT_FLOAT },
|
||||||
|
{"aimAssistRangeAds", offsetof(WeaponDef, aimAssistRangeAds), CSPFT_FLOAT },
|
||||||
|
{"aimPadding", offsetof(WeaponDef, aimPadding), CSPFT_FLOAT },
|
||||||
|
{"enemyCrosshairRange", offsetof(WeaponDef, enemyCrosshairRange), CSPFT_FLOAT },
|
||||||
|
{"crosshairColorChange", offsetof(WeaponDef, crosshairColorChange), CSPFT_QBOOLEAN },
|
||||||
|
{"moveSpeedScale", offsetof(WeaponDef, moveSpeedScale), CSPFT_FLOAT },
|
||||||
|
{"adsMoveSpeedScale", offsetof(WeaponDef, adsMoveSpeedScale), CSPFT_FLOAT },
|
||||||
|
{"sprintDurationScale", offsetof(WeaponDef, sprintDurationScale), CSPFT_FLOAT },
|
||||||
|
{"idleCrouchFactor", offsetof(WeaponDef, fIdleCrouchFactor), CSPFT_FLOAT },
|
||||||
|
{"idleProneFactor", offsetof(WeaponDef, fIdleProneFactor), CSPFT_FLOAT },
|
||||||
|
{"gunMaxPitch", offsetof(WeaponDef, fGunMaxPitch), CSPFT_FLOAT },
|
||||||
|
{"gunMaxYaw", offsetof(WeaponDef, fGunMaxYaw), CSPFT_FLOAT },
|
||||||
|
{"swayMaxAngle", offsetof(WeaponDef, swayMaxAngle), CSPFT_FLOAT },
|
||||||
|
{"swayLerpSpeed", offsetof(WeaponDef, swayLerpSpeed), CSPFT_FLOAT },
|
||||||
|
{"swayPitchScale", offsetof(WeaponDef, swayPitchScale), CSPFT_FLOAT },
|
||||||
|
{"swayYawScale", offsetof(WeaponDef, swayYawScale), CSPFT_FLOAT },
|
||||||
|
{"swayHorizScale", offsetof(WeaponDef, swayHorizScale), CSPFT_FLOAT },
|
||||||
|
{"swayVertScale", offsetof(WeaponDef, swayVertScale), CSPFT_FLOAT },
|
||||||
|
{"swayShellShockScale", offsetof(WeaponDef, swayShellShockScale), CSPFT_FLOAT },
|
||||||
|
{"adsSwayMaxAngle", offsetof(WeaponDef, adsSwayMaxAngle), CSPFT_FLOAT },
|
||||||
|
{"adsSwayLerpSpeed", offsetof(WeaponDef, adsSwayLerpSpeed), CSPFT_FLOAT },
|
||||||
|
{"adsSwayPitchScale", offsetof(WeaponDef, adsSwayPitchScale), CSPFT_FLOAT },
|
||||||
|
{"adsSwayYawScale", offsetof(WeaponDef, adsSwayYawScale), CSPFT_FLOAT },
|
||||||
|
{"adsSwayHorizScale", offsetof(WeaponDef, adsSwayHorizScale), CSPFT_FLOAT },
|
||||||
|
{"adsSwayVertScale", offsetof(WeaponDef, adsSwayVertScale), CSPFT_FLOAT },
|
||||||
|
{"rifleBullet", offsetof(WeaponDef, bRifleBullet), CSPFT_QBOOLEAN },
|
||||||
|
{"armorPiercing", offsetof(WeaponDef, armorPiercing), CSPFT_QBOOLEAN },
|
||||||
|
{"boltAction", offsetof(WeaponDef, bBoltAction), CSPFT_QBOOLEAN },
|
||||||
|
{"aimDownSight", offsetof(WeaponDef, aimDownSight), CSPFT_QBOOLEAN },
|
||||||
|
{"rechamberWhileAds", offsetof(WeaponDef, bRechamberWhileAds), CSPFT_QBOOLEAN },
|
||||||
|
{"adsViewErrorMin", offsetof(WeaponDef, adsViewErrorMin), CSPFT_FLOAT },
|
||||||
|
{"adsViewErrorMax", offsetof(WeaponDef, adsViewErrorMax), CSPFT_FLOAT },
|
||||||
|
{"clipOnly", offsetof(WeaponDef, bClipOnly), CSPFT_QBOOLEAN },
|
||||||
|
{"cookOffHold", offsetof(WeaponDef, bCookOffHold), CSPFT_QBOOLEAN },
|
||||||
|
{"adsFire", offsetof(WeaponDef, adsFireOnly), CSPFT_QBOOLEAN },
|
||||||
|
{"cancelAutoHolsterWhenEmpty", offsetof(WeaponDef, cancelAutoHolsterWhenEmpty), CSPFT_QBOOLEAN },
|
||||||
|
{"suppressAmmoReserveDisplay", offsetof(WeaponDef, suppressAmmoReserveDisplay), CSPFT_QBOOLEAN },
|
||||||
|
{"enhanced", offsetof(WeaponDef, enhanced), CSPFT_QBOOLEAN },
|
||||||
|
{"laserSightDuringNightvision", offsetof(WeaponDef, laserSightDuringNightvision), CSPFT_QBOOLEAN },
|
||||||
|
{"killIcon", offsetof(WeaponDef, killIcon), CSPFT_MATERIAL },
|
||||||
|
{"killIconRatio", offsetof(WeaponDef, killIconRatio), WFT_ICONRATIO_KILL },
|
||||||
|
{"flipKillIcon", offsetof(WeaponDef, flipKillIcon), CSPFT_QBOOLEAN },
|
||||||
|
{"dpadIcon", offsetof(WeaponDef, dpadIcon), CSPFT_MATERIAL },
|
||||||
|
{"dpadIconRatio", offsetof(WeaponDef, dpadIconRatio), WFT_ICONRATIO_DPAD },
|
||||||
|
{"noPartialReload", offsetof(WeaponDef, bNoPartialReload), CSPFT_QBOOLEAN },
|
||||||
|
{"segmentedReload", offsetof(WeaponDef, bSegmentedReload), CSPFT_QBOOLEAN },
|
||||||
|
{"reloadAmmoAdd", offsetof(WeaponDef, iReloadAmmoAdd), CSPFT_INT },
|
||||||
|
{"reloadStartAdd", offsetof(WeaponDef, iReloadStartAdd), CSPFT_INT },
|
||||||
|
{"altWeapon", offsetof(WeaponDef, szAltWeaponName), CSPFT_STRING },
|
||||||
|
{"dropAmmoMin", offsetof(WeaponDef, iDropAmmoMin), CSPFT_INT },
|
||||||
|
{"dropAmmoMax", offsetof(WeaponDef, iDropAmmoMax), CSPFT_INT },
|
||||||
|
{"blocksProne", offsetof(WeaponDef, blocksProne), CSPFT_QBOOLEAN },
|
||||||
|
{"silenced", offsetof(WeaponDef, silenced), CSPFT_QBOOLEAN },
|
||||||
|
{"explosionRadius", offsetof(WeaponDef, iExplosionRadius), CSPFT_INT },
|
||||||
|
{"explosionRadiusMin", offsetof(WeaponDef, iExplosionRadiusMin), CSPFT_INT },
|
||||||
|
{"explosionInnerDamage", offsetof(WeaponDef, iExplosionInnerDamage), CSPFT_INT },
|
||||||
|
{"explosionOuterDamage", offsetof(WeaponDef, iExplosionOuterDamage), CSPFT_INT },
|
||||||
|
{"damageConeAngle", offsetof(WeaponDef, damageConeAngle), CSPFT_FLOAT },
|
||||||
|
{"projectileSpeed", offsetof(WeaponDef, iProjectileSpeed), CSPFT_INT },
|
||||||
|
{"projectileSpeedUp", offsetof(WeaponDef, iProjectileSpeedUp), CSPFT_INT },
|
||||||
|
{"projectileSpeedForward", offsetof(WeaponDef, iProjectileSpeedForward), CSPFT_INT },
|
||||||
|
{"projectileActivateDist", offsetof(WeaponDef, iProjectileActivateDist), CSPFT_INT },
|
||||||
|
{"projectileLifetime", offsetof(WeaponDef, projLifetime), CSPFT_FLOAT },
|
||||||
|
{"timeToAccelerate", offsetof(WeaponDef, timeToAccelerate), CSPFT_FLOAT },
|
||||||
|
{"projectileCurvature", offsetof(WeaponDef, projectileCurvature), CSPFT_FLOAT },
|
||||||
|
{"projectileModel", offsetof(WeaponDef, projectileModel), CSPFT_XMODEL },
|
||||||
|
{"projExplosionType", offsetof(WeaponDef, projExplosion), WFT_PROJ_EXPLOSION },
|
||||||
|
{"projExplosionEffect", offsetof(WeaponDef, projExplosionEffect), CSPFT_FX },
|
||||||
|
{"projExplosionEffectForceNormalUp", offsetof(WeaponDef, projExplosionEffectForceNormalUp), CSPFT_QBOOLEAN },
|
||||||
|
{"projExplosionSound", offsetof(WeaponDef, projExplosionSound), CSPFT_SOUND },
|
||||||
|
{"projDudEffect", offsetof(WeaponDef, projDudEffect), CSPFT_FX },
|
||||||
|
{"projDudSound", offsetof(WeaponDef, projDudSound), CSPFT_SOUND },
|
||||||
|
{"projImpactExplode", offsetof(WeaponDef, bProjImpactExplode), CSPFT_QBOOLEAN },
|
||||||
|
{"stickiness", offsetof(WeaponDef, stickiness), WFT_STICKINESS },
|
||||||
|
{"hasDetonator", offsetof(WeaponDef, hasDetonator), CSPFT_QBOOLEAN },
|
||||||
|
{"timedDetonation", offsetof(WeaponDef, timedDetonation), CSPFT_QBOOLEAN },
|
||||||
|
{"rotate", offsetof(WeaponDef, rotate), CSPFT_QBOOLEAN },
|
||||||
|
{"holdButtonToThrow", offsetof(WeaponDef, holdButtonToThrow), CSPFT_QBOOLEAN },
|
||||||
|
{"freezeMovementWhenFiring", offsetof(WeaponDef, freezeMovementWhenFiring), CSPFT_QBOOLEAN },
|
||||||
|
{"lowAmmoWarningThreshold", offsetof(WeaponDef, lowAmmoWarningThreshold), CSPFT_FLOAT },
|
||||||
|
{"parallelDefaultBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_DEFAULT]), CSPFT_FLOAT },
|
||||||
|
{"parallelBarkBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_BARK]), CSPFT_FLOAT },
|
||||||
|
{"parallelBrickBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_BRICK]), CSPFT_FLOAT },
|
||||||
|
{"parallelCarpetBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_CARPET]), CSPFT_FLOAT },
|
||||||
|
{"parallelClothBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_CLOTH]), CSPFT_FLOAT },
|
||||||
|
{"parallelConcreteBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_CONCRETE]), CSPFT_FLOAT },
|
||||||
|
{"parallelDirtBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_DIRT]), CSPFT_FLOAT },
|
||||||
|
{"parallelFleshBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_FLESH]), CSPFT_FLOAT },
|
||||||
|
{"parallelFoliageBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_FOLIAGE]), CSPFT_FLOAT },
|
||||||
|
{"parallelGlassBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_GLASS]), CSPFT_FLOAT },
|
||||||
|
{"parallelGrassBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_GRASS]), CSPFT_FLOAT },
|
||||||
|
{"parallelGravelBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_GRAVEL]), CSPFT_FLOAT },
|
||||||
|
{"parallelIceBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_ICE]), CSPFT_FLOAT },
|
||||||
|
{"parallelMetalBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_METAL]), CSPFT_FLOAT },
|
||||||
|
{"parallelMudBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_MUD]), CSPFT_FLOAT },
|
||||||
|
{"parallelPaperBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_PAPER]), CSPFT_FLOAT },
|
||||||
|
{"parallelPlasterBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_PLASTER]), CSPFT_FLOAT },
|
||||||
|
{"parallelRockBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_ROCK]), CSPFT_FLOAT },
|
||||||
|
{"parallelSandBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_SAND]), CSPFT_FLOAT },
|
||||||
|
{"parallelSnowBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_SNOW]), CSPFT_FLOAT },
|
||||||
|
{"parallelWaterBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_WATER]), CSPFT_FLOAT },
|
||||||
|
{"parallelWoodBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_WOOD]), CSPFT_FLOAT },
|
||||||
|
{"parallelAsphaltBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_ASPHALT]), CSPFT_FLOAT },
|
||||||
|
{"parallelCeramicBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_CERAMIC]), CSPFT_FLOAT },
|
||||||
|
{"parallelPlasticBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_PLASTIC]), CSPFT_FLOAT },
|
||||||
|
{"parallelRubberBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_RUBBER]), CSPFT_FLOAT },
|
||||||
|
{"parallelCushionBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_CUSHION]), CSPFT_FLOAT },
|
||||||
|
{"parallelFruitBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_FRUIT]), CSPFT_FLOAT },
|
||||||
|
{"parallelPaintedMetalBounce", offsetof(WeaponDef, parallelBounce[SURF_TYPE_PAINTED_METAL]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularDefaultBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_DEFAULT]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularBarkBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_BARK]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularBrickBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_BRICK]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularCarpetBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_CARPET]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularClothBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_CLOTH]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularConcreteBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_CONCRETE]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularDirtBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_DIRT]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularFleshBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_FLESH]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularFoliageBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_FOLIAGE]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularGlassBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_GLASS]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularGrassBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_GRASS]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularGravelBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_GRAVEL]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularIceBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_ICE]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularMetalBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_METAL]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularMudBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_MUD]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularPaperBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_PAPER]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularPlasterBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_PLASTER]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularRockBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_ROCK]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularSandBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_SAND]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularSnowBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_SNOW]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularWaterBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_WATER]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularWoodBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_WOOD]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularAsphaltBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_ASPHALT]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularCeramicBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_CERAMIC]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularPlasticBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_PLASTIC]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularRubberBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_RUBBER]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularCushionBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_CUSHION]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularFruitBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_FRUIT]), CSPFT_FLOAT },
|
||||||
|
{"perpendicularPaintedMetalBounce", offsetof(WeaponDef, perpendicularBounce[SURF_TYPE_PAINTED_METAL]), CSPFT_FLOAT },
|
||||||
|
{"projTrailEffect", offsetof(WeaponDef, projTrailEffect), CSPFT_FX },
|
||||||
|
{"projectileRed", offsetof(WeaponDef, vProjectileColor[0]), CSPFT_FLOAT },
|
||||||
|
{"projectileGreen", offsetof(WeaponDef, vProjectileColor[1]), CSPFT_FLOAT },
|
||||||
|
{"projectileBlue", offsetof(WeaponDef, vProjectileColor[2]), CSPFT_FLOAT },
|
||||||
|
{"guidedMissileType", offsetof(WeaponDef, guidedMissileType), WFT_GUIDED_MISSILE_TYPE },
|
||||||
|
{"maxSteeringAccel", offsetof(WeaponDef, maxSteeringAccel), CSPFT_FLOAT },
|
||||||
|
{"projIgnitionDelay", offsetof(WeaponDef, projIgnitionDelay), CSPFT_INT },
|
||||||
|
{"projIgnitionEffect", offsetof(WeaponDef, projIgnitionEffect), CSPFT_FX },
|
||||||
|
{"projIgnitionSound", offsetof(WeaponDef, projIgnitionSound), CSPFT_SOUND },
|
||||||
|
{"adsTransInTime", offsetof(WeaponDef, iAdsTransInTime), CSPFT_MILLISECONDS },
|
||||||
|
{"adsTransOutTime", offsetof(WeaponDef, iAdsTransOutTime), CSPFT_MILLISECONDS },
|
||||||
|
{"adsIdleAmount", offsetof(WeaponDef, fAdsIdleAmount), CSPFT_FLOAT },
|
||||||
|
{"adsIdleSpeed", offsetof(WeaponDef, adsIdleSpeed), CSPFT_FLOAT },
|
||||||
|
{"adsZoomFov", offsetof(WeaponDef, fAdsZoomFov), CSPFT_FLOAT },
|
||||||
|
{"adsZoomInFrac", offsetof(WeaponDef, fAdsZoomInFrac), CSPFT_FLOAT },
|
||||||
|
{"adsZoomOutFrac", offsetof(WeaponDef, fAdsZoomOutFrac), CSPFT_FLOAT },
|
||||||
|
{"adsOverlayShader", offsetof(WeaponDef, overlayMaterial), CSPFT_MATERIAL },
|
||||||
|
{"adsOverlayShaderLowRes", offsetof(WeaponDef, overlayMaterialLowRes), CSPFT_MATERIAL },
|
||||||
|
{"adsOverlayReticle", offsetof(WeaponDef, overlayReticle), WFT_OVERLAYRETICLE },
|
||||||
|
{"adsOverlayInterface", offsetof(WeaponDef, overlayInterface), WFT_OVERLAYINTERFACE },
|
||||||
|
{"adsOverlayWidth", offsetof(WeaponDef, overlayWidth), CSPFT_FLOAT },
|
||||||
|
{"adsOverlayHeight", offsetof(WeaponDef, overlayHeight), CSPFT_FLOAT },
|
||||||
|
{"adsBobFactor", offsetof(WeaponDef, fAdsBobFactor), CSPFT_FLOAT },
|
||||||
|
{"adsViewBobMult", offsetof(WeaponDef, fAdsViewBobMult), CSPFT_FLOAT },
|
||||||
|
{"adsAimPitch", offsetof(WeaponDef, fAdsAimPitch), CSPFT_FLOAT },
|
||||||
|
{"adsCrosshairInFrac", offsetof(WeaponDef, fAdsCrosshairInFrac), CSPFT_FLOAT },
|
||||||
|
{"adsCrosshairOutFrac", offsetof(WeaponDef, fAdsCrosshairOutFrac), CSPFT_FLOAT },
|
||||||
|
{"adsReloadTransTime", offsetof(WeaponDef, iPositionReloadTransTime), CSPFT_MILLISECONDS },
|
||||||
|
{"adsGunKickReducedKickBullets", offsetof(WeaponDef, adsGunKickReducedKickBullets), CSPFT_INT },
|
||||||
|
{"adsGunKickReducedKickPercent", offsetof(WeaponDef, adsGunKickReducedKickPercent), CSPFT_FLOAT },
|
||||||
|
{"adsGunKickPitchMin", offsetof(WeaponDef, fAdsGunKickPitchMin), CSPFT_FLOAT },
|
||||||
|
{"adsGunKickPitchMax", offsetof(WeaponDef, fAdsGunKickPitchMax), CSPFT_FLOAT },
|
||||||
|
{"adsGunKickYawMin", offsetof(WeaponDef, fAdsGunKickYawMin), CSPFT_FLOAT },
|
||||||
|
{"adsGunKickYawMax", offsetof(WeaponDef, fAdsGunKickYawMax), CSPFT_FLOAT },
|
||||||
|
{"adsGunKickAccel", offsetof(WeaponDef, fAdsGunKickAccel), CSPFT_FLOAT },
|
||||||
|
{"adsGunKickSpeedMax", offsetof(WeaponDef, fAdsGunKickSpeedMax), CSPFT_FLOAT },
|
||||||
|
{"adsGunKickSpeedDecay", offsetof(WeaponDef, fAdsGunKickSpeedDecay), CSPFT_FLOAT },
|
||||||
|
{"adsGunKickStaticDecay", offsetof(WeaponDef, fAdsGunKickStaticDecay), CSPFT_FLOAT },
|
||||||
|
{"adsViewKickPitchMin", offsetof(WeaponDef, fAdsViewKickPitchMin), CSPFT_FLOAT },
|
||||||
|
{"adsViewKickPitchMax", offsetof(WeaponDef, fAdsViewKickPitchMax), CSPFT_FLOAT },
|
||||||
|
{"adsViewKickYawMin", offsetof(WeaponDef, fAdsViewKickYawMin), CSPFT_FLOAT },
|
||||||
|
{"adsViewKickYawMax", offsetof(WeaponDef, fAdsViewKickYawMax), CSPFT_FLOAT },
|
||||||
|
{"adsViewKickCenterSpeed", offsetof(WeaponDef, fAdsViewKickCenterSpeed), CSPFT_FLOAT },
|
||||||
|
{"adsSpread", offsetof(WeaponDef, fAdsSpread), CSPFT_FLOAT },
|
||||||
|
{"hipSpreadStandMin", offsetof(WeaponDef, fHipSpreadStandMin), CSPFT_FLOAT },
|
||||||
|
{"hipSpreadDuckedMin", offsetof(WeaponDef, fHipSpreadDuckedMin), CSPFT_FLOAT },
|
||||||
|
{"hipSpreadProneMin", offsetof(WeaponDef, fHipSpreadProneMin), CSPFT_FLOAT },
|
||||||
|
{"hipSpreadMax", offsetof(WeaponDef, hipSpreadStandMax), CSPFT_FLOAT },
|
||||||
|
{"hipSpreadDuckedMax", offsetof(WeaponDef, hipSpreadDuckedMax), CSPFT_FLOAT },
|
||||||
|
{"hipSpreadProneMax", offsetof(WeaponDef, hipSpreadProneMax), CSPFT_FLOAT },
|
||||||
|
{"hipSpreadDecayRate", offsetof(WeaponDef, fHipSpreadDecayRate), CSPFT_FLOAT },
|
||||||
|
{"hipSpreadFireAdd", offsetof(WeaponDef, fHipSpreadFireAdd), CSPFT_FLOAT },
|
||||||
|
{"hipSpreadTurnAdd", offsetof(WeaponDef, fHipSpreadTurnAdd), CSPFT_FLOAT },
|
||||||
|
{"hipSpreadMoveAdd", offsetof(WeaponDef, fHipSpreadMoveAdd), CSPFT_FLOAT },
|
||||||
|
{"hipSpreadDuckedDecay", offsetof(WeaponDef, fHipSpreadDuckedDecay), CSPFT_FLOAT },
|
||||||
|
{"hipSpreadProneDecay", offsetof(WeaponDef, fHipSpreadProneDecay), CSPFT_FLOAT },
|
||||||
|
{"hipReticleSidePos", offsetof(WeaponDef, fHipReticleSidePos), CSPFT_FLOAT },
|
||||||
|
{"hipIdleAmount", offsetof(WeaponDef, fHipIdleAmount), CSPFT_FLOAT },
|
||||||
|
{"hipIdleSpeed", offsetof(WeaponDef, hipIdleSpeed), CSPFT_FLOAT },
|
||||||
|
{"hipGunKickReducedKickBullets", offsetof(WeaponDef, hipGunKickReducedKickBullets), CSPFT_INT },
|
||||||
|
{"hipGunKickReducedKickPercent", offsetof(WeaponDef, hipGunKickReducedKickPercent), CSPFT_FLOAT },
|
||||||
|
{"hipGunKickPitchMin", offsetof(WeaponDef, fHipGunKickPitchMin), CSPFT_FLOAT },
|
||||||
|
{"hipGunKickPitchMax", offsetof(WeaponDef, fHipGunKickPitchMax), CSPFT_FLOAT },
|
||||||
|
{"hipGunKickYawMin", offsetof(WeaponDef, fHipGunKickYawMin), CSPFT_FLOAT },
|
||||||
|
{"hipGunKickYawMax", offsetof(WeaponDef, fHipGunKickYawMax), CSPFT_FLOAT },
|
||||||
|
{"hipGunKickAccel", offsetof(WeaponDef, fHipGunKickAccel), CSPFT_FLOAT },
|
||||||
|
{"hipGunKickSpeedMax", offsetof(WeaponDef, fHipGunKickSpeedMax), CSPFT_FLOAT },
|
||||||
|
{"hipGunKickSpeedDecay", offsetof(WeaponDef, fHipGunKickSpeedDecay), CSPFT_FLOAT },
|
||||||
|
{"hipGunKickStaticDecay", offsetof(WeaponDef, fHipGunKickStaticDecay), CSPFT_FLOAT },
|
||||||
|
{"hipViewKickPitchMin", offsetof(WeaponDef, fHipViewKickPitchMin), CSPFT_FLOAT },
|
||||||
|
{"hipViewKickPitchMax", offsetof(WeaponDef, fHipViewKickPitchMax), CSPFT_FLOAT },
|
||||||
|
{"hipViewKickYawMin", offsetof(WeaponDef, fHipViewKickYawMin), CSPFT_FLOAT },
|
||||||
|
{"hipViewKickYawMax", offsetof(WeaponDef, fHipViewKickYawMax), CSPFT_FLOAT },
|
||||||
|
{"hipViewKickCenterSpeed", offsetof(WeaponDef, fHipViewKickCenterSpeed), CSPFT_FLOAT },
|
||||||
|
{"leftArc", offsetof(WeaponDef, leftArc), CSPFT_FLOAT },
|
||||||
|
{"rightArc", offsetof(WeaponDef, rightArc), CSPFT_FLOAT },
|
||||||
|
{"topArc", offsetof(WeaponDef, topArc), CSPFT_FLOAT },
|
||||||
|
{"bottomArc", offsetof(WeaponDef, bottomArc), CSPFT_FLOAT },
|
||||||
|
{"accuracy", offsetof(WeaponDef, accuracy), CSPFT_FLOAT },
|
||||||
|
{"aiSpread", offsetof(WeaponDef, aiSpread), CSPFT_FLOAT },
|
||||||
|
{"playerSpread", offsetof(WeaponDef, playerSpread), CSPFT_FLOAT },
|
||||||
|
{"maxVertTurnSpeed", offsetof(WeaponDef, maxTurnSpeed[0]), CSPFT_FLOAT },
|
||||||
|
{"maxHorTurnSpeed", offsetof(WeaponDef, maxTurnSpeed[1]), CSPFT_FLOAT },
|
||||||
|
{"minVertTurnSpeed", offsetof(WeaponDef, minTurnSpeed[0]), CSPFT_FLOAT },
|
||||||
|
{"minHorTurnSpeed", offsetof(WeaponDef, minTurnSpeed[1]), CSPFT_FLOAT },
|
||||||
|
{"pitchConvergenceTime", offsetof(WeaponDef, pitchConvergenceTime), CSPFT_FLOAT },
|
||||||
|
{"yawConvergenceTime", offsetof(WeaponDef, yawConvergenceTime), CSPFT_FLOAT },
|
||||||
|
{"suppressionTime", offsetof(WeaponDef, suppressTime), CSPFT_FLOAT },
|
||||||
|
{"maxRange", offsetof(WeaponDef, maxRange), CSPFT_FLOAT },
|
||||||
|
{"animHorRotateInc", offsetof(WeaponDef, fAnimHorRotateInc), CSPFT_FLOAT },
|
||||||
|
{"playerPositionDist", offsetof(WeaponDef, fPlayerPositionDist), CSPFT_FLOAT },
|
||||||
|
{"stance", offsetof(WeaponDef, stance), WFT_STANCE },
|
||||||
|
{"useHintString", offsetof(WeaponDef, szUseHintString), CSPFT_STRING },
|
||||||
|
{"dropHintString", offsetof(WeaponDef, dropHintString), CSPFT_STRING },
|
||||||
|
{"horizViewJitter", offsetof(WeaponDef, horizViewJitter), CSPFT_FLOAT },
|
||||||
|
{"vertViewJitter", offsetof(WeaponDef, vertViewJitter), CSPFT_FLOAT },
|
||||||
|
{"fightDist", offsetof(WeaponDef, fightDist), CSPFT_FLOAT },
|
||||||
|
{"maxDist", offsetof(WeaponDef, maxDist), CSPFT_FLOAT },
|
||||||
|
{"aiVsAiAccuracyGraph", offsetof(WeaponDef, aiVsAiAccuracyGraphName), CSPFT_STRING },
|
||||||
|
{"aiVsPlayerAccuracyGraph", offsetof(WeaponDef, aiVsPlayerAccuracyGraphName), CSPFT_STRING },
|
||||||
|
{"locNone", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_NONE]), CSPFT_FLOAT },
|
||||||
|
{"locHelmet", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_HELMET]), CSPFT_FLOAT },
|
||||||
|
{"locHead", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_HEAD]), CSPFT_FLOAT },
|
||||||
|
{"locNeck", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_NECK]), CSPFT_FLOAT },
|
||||||
|
{"locTorsoUpper", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_TORSO_UPR]), CSPFT_FLOAT },
|
||||||
|
{"locTorsoLower", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_TORSO_LWR]), CSPFT_FLOAT },
|
||||||
|
{"locRightArmUpper", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_R_ARM_UPR]), CSPFT_FLOAT },
|
||||||
|
{"locRightArmLower", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_R_ARM_LWR]), CSPFT_FLOAT },
|
||||||
|
{"locRightHand", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_R_HAND]), CSPFT_FLOAT },
|
||||||
|
{"locLeftArmUpper", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_L_ARM_UPR]), CSPFT_FLOAT },
|
||||||
|
{"locLeftArmLower", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_L_ARM_LWR]), CSPFT_FLOAT },
|
||||||
|
{"locLeftHand", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_L_HAND]), CSPFT_FLOAT },
|
||||||
|
{"locRightLegUpper", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_R_LEG_UPR]), CSPFT_FLOAT },
|
||||||
|
{"locRightLegLower", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_R_LEG_LWR]), CSPFT_FLOAT },
|
||||||
|
{"locRightFoot", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_R_FOOT]), CSPFT_FLOAT },
|
||||||
|
{"locLeftLegUpper", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_L_LEG_UPR]), CSPFT_FLOAT },
|
||||||
|
{"locLeftLegLower", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_L_LEG_LWR]), CSPFT_FLOAT },
|
||||||
|
{"locLeftFoot", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_L_FOOT]), CSPFT_FLOAT },
|
||||||
|
{"locGun", offsetof(WeaponDef, locationDamageMultipliers[HITLOC_GUN]), CSPFT_FLOAT },
|
||||||
|
{"fireRumble", offsetof(WeaponDef, fireRumble), CSPFT_STRING },
|
||||||
|
{"meleeImpactRumble", offsetof(WeaponDef, meleeImpactRumble), CSPFT_STRING },
|
||||||
|
{"adsDofStart", offsetof(WeaponDef, adsDofStart), CSPFT_FLOAT },
|
||||||
|
{"adsDofEnd", offsetof(WeaponDef, adsDofEnd), CSPFT_FLOAT },
|
||||||
|
};
|
||||||
|
} // namespace IW3
|
||||||
@@ -0,0 +1,172 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Game/IW3/IW3.h"
|
||||||
|
|
||||||
|
namespace IW3
|
||||||
|
{
|
||||||
|
inline const char* szWeapTypeNames[]{
|
||||||
|
"bullet",
|
||||||
|
"grenade",
|
||||||
|
"projectile",
|
||||||
|
"binoculars",
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(szWeapTypeNames)> == WEAPTYPE_NUM);
|
||||||
|
|
||||||
|
inline const char* szWeapClassNames[]{
|
||||||
|
"rifle",
|
||||||
|
"mg",
|
||||||
|
"smg",
|
||||||
|
"spread",
|
||||||
|
"pistol",
|
||||||
|
"grenade",
|
||||||
|
"rocketlauncher",
|
||||||
|
"turret",
|
||||||
|
"non-player",
|
||||||
|
"item",
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(szWeapClassNames)> == WEAPCLASS_NUM);
|
||||||
|
|
||||||
|
inline const char* szWeapOverlayReticleNames[]{
|
||||||
|
"none",
|
||||||
|
"crosshair",
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(szWeapOverlayReticleNames)> == WEAPOVERLAYRETICLE_NUM);
|
||||||
|
|
||||||
|
inline const char* penetrateTypeNames[]{
|
||||||
|
"none",
|
||||||
|
"small",
|
||||||
|
"medium",
|
||||||
|
"large",
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(penetrateTypeNames)> == PENETRATE_TYPE_NUM);
|
||||||
|
|
||||||
|
inline const char* impactTypeNames[]{
|
||||||
|
"none",
|
||||||
|
"bullet_small",
|
||||||
|
"bullet_large",
|
||||||
|
"bullet_ap",
|
||||||
|
"shotgun",
|
||||||
|
"grenade_bounce",
|
||||||
|
"grenade_explode",
|
||||||
|
"rocket_explode",
|
||||||
|
"projectile_dud",
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(impactTypeNames)> == IMPACT_TYPE_NUM);
|
||||||
|
|
||||||
|
inline const char* szWeapStanceNames[]{
|
||||||
|
"stand",
|
||||||
|
"duck",
|
||||||
|
"prone",
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(szWeapStanceNames)> == WEAPSTANCE_NUM);
|
||||||
|
|
||||||
|
inline const char* szProjectileExplosionNames[]{
|
||||||
|
"grenade",
|
||||||
|
"rocket",
|
||||||
|
"flashbang",
|
||||||
|
"none",
|
||||||
|
"dud",
|
||||||
|
"smoke",
|
||||||
|
"heavy explosive",
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(szProjectileExplosionNames)> == WEAPPROJEXP_NUM);
|
||||||
|
|
||||||
|
inline const char* offhandClassNames[]{
|
||||||
|
"None",
|
||||||
|
"Frag Grenade",
|
||||||
|
"Smoke Grenade",
|
||||||
|
"Flash Grenade",
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(offhandClassNames)> == OFFHAND_CLASS_NUM);
|
||||||
|
|
||||||
|
// mp/playeranimtypes.txt
|
||||||
|
inline const char* playerAnimTypeNames[]{
|
||||||
|
"none",
|
||||||
|
"other",
|
||||||
|
"pistol",
|
||||||
|
"smg",
|
||||||
|
"autorifle",
|
||||||
|
"mg",
|
||||||
|
"sniper",
|
||||||
|
"rocketlauncher",
|
||||||
|
"explosive",
|
||||||
|
"grenade",
|
||||||
|
"turret",
|
||||||
|
"c4",
|
||||||
|
"m203",
|
||||||
|
"hold",
|
||||||
|
"briefcase",
|
||||||
|
};
|
||||||
|
|
||||||
|
inline const char* activeReticleNames[]{
|
||||||
|
"None",
|
||||||
|
"Pip-On-A-Stick",
|
||||||
|
"Bouncing diamond",
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(activeReticleNames)> == VEH_ACTIVE_RETICLE_NUM);
|
||||||
|
|
||||||
|
inline const char* guidedMissileNames[]{
|
||||||
|
"None",
|
||||||
|
"Sidewinder",
|
||||||
|
"Hellfire",
|
||||||
|
"Javelin",
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(guidedMissileNames)> == MISSILE_GUIDANCE_NUM);
|
||||||
|
|
||||||
|
inline const char* stickinessNames[]{
|
||||||
|
"Don't stick",
|
||||||
|
"Stick to all",
|
||||||
|
"Stick to ground",
|
||||||
|
"Stick to ground, maintain yaw",
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(stickinessNames)> == WEAPSTICKINESS_NUM);
|
||||||
|
|
||||||
|
inline const char* overlayInterfaceNames[]{
|
||||||
|
"None",
|
||||||
|
"Javelin",
|
||||||
|
"Turret Scope",
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(overlayInterfaceNames)> == WEAPOVERLAYINTERFACE_NUM);
|
||||||
|
|
||||||
|
inline const char* szWeapInventoryTypeNames[]{
|
||||||
|
"primary",
|
||||||
|
"offhand",
|
||||||
|
"item",
|
||||||
|
"altmode",
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(szWeapInventoryTypeNames)> == WEAPINVENTORY_NUM);
|
||||||
|
|
||||||
|
inline const char* szWeapFireTypeNames[]{
|
||||||
|
"Full Auto",
|
||||||
|
"Single Shot",
|
||||||
|
"2-Round Burst",
|
||||||
|
"3-Round Burst",
|
||||||
|
"4-Round Burst",
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(szWeapFireTypeNames)> == WEAPON_FIRETYPE_NUM);
|
||||||
|
|
||||||
|
inline const char* ammoCounterClipNames[]{
|
||||||
|
"None",
|
||||||
|
"Magazine",
|
||||||
|
"ShortMagazine",
|
||||||
|
"Shotgun",
|
||||||
|
"Rocket",
|
||||||
|
"Beltfed",
|
||||||
|
"AltWeapon",
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(ammoCounterClipNames)> == AMMO_COUNTER_CLIP_NUM);
|
||||||
|
|
||||||
|
inline const char* weapIconRatioNames[]{
|
||||||
|
"1:1",
|
||||||
|
"2:1",
|
||||||
|
"4:1",
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(weapIconRatioNames)> == WEAPON_ICON_RATIO_NUM);
|
||||||
|
|
||||||
|
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",
|
||||||
|
};
|
||||||
|
static_assert(std::extent_v<decltype(bounceSoundSuffixes)> == SURF_TYPE_NUM);
|
||||||
|
} // namespace IW3
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "Game/IW3/Image/ImageLoaderExternalIW3.h"
|
#include "Game/IW3/Image/ImageLoaderExternalIW3.h"
|
||||||
#include "Game/IW3/Techset/PixelShaderLoaderIW3.h"
|
#include "Game/IW3/Techset/PixelShaderLoaderIW3.h"
|
||||||
#include "Game/IW3/Techset/VertexShaderLoaderIW3.h"
|
#include "Game/IW3/Techset/VertexShaderLoaderIW3.h"
|
||||||
|
#include "Game/IW3/Weapon/AccuracyGraphLoaderIW3.h"
|
||||||
#include "Game/IW3/XAnim/XAnimLoaderIW3.h"
|
#include "Game/IW3/XAnim/XAnimLoaderIW3.h"
|
||||||
#include "Game/IW3/XModel/LoaderXModelIW3.h"
|
#include "Game/IW3/XModel/LoaderXModelIW3.h"
|
||||||
#include "LightDef/LightDefLoaderIW3.h"
|
#include "LightDef/LightDefLoaderIW3.h"
|
||||||
@@ -19,6 +20,8 @@
|
|||||||
#include "RawFile/AssetLoaderRawFileIW3.h"
|
#include "RawFile/AssetLoaderRawFileIW3.h"
|
||||||
#include "Sound/LoaderSoundCurveIW3.h"
|
#include "Sound/LoaderSoundCurveIW3.h"
|
||||||
#include "StringTable/AssetLoaderStringTableIW3.h"
|
#include "StringTable/AssetLoaderStringTableIW3.h"
|
||||||
|
#include "Weapon/WeaponGdtLoaderIW3.h"
|
||||||
|
#include "Weapon/WeaponRawLoaderIW3.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -120,7 +123,8 @@ namespace
|
|||||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderMenuList>(memory));
|
// collection.AddAssetCreator(std::make_unique<AssetLoaderMenuList>(memory));
|
||||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderMenu>(memory));
|
// collection.AddAssetCreator(std::make_unique<AssetLoaderMenu>(memory));
|
||||||
collection.AddAssetCreator(localize::CreateLoaderIW3(memory, searchPath, zone));
|
collection.AddAssetCreator(localize::CreateLoaderIW3(memory, searchPath, zone));
|
||||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderWeapon>(memory));
|
collection.AddAssetCreator(weapon::CreateRawLoaderIW3(memory, searchPath, zone));
|
||||||
|
collection.AddAssetCreator(weapon::CreateGdtLoaderIW3(memory, searchPath, gdt, zone));
|
||||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderSoundDriverGlobals>(memory));
|
// collection.AddAssetCreator(std::make_unique<AssetLoaderSoundDriverGlobals>(memory));
|
||||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderFx>(memory));
|
// collection.AddAssetCreator(std::make_unique<AssetLoaderFx>(memory));
|
||||||
// collection.AddAssetCreator(std::make_unique<AssetLoaderImpactFx>(memory));
|
// collection.AddAssetCreator(std::make_unique<AssetLoaderImpactFx>(memory));
|
||||||
@@ -129,6 +133,7 @@ namespace
|
|||||||
|
|
||||||
collection.AddSubAssetCreator(techset::CreateVertexShaderLoaderIW3(memory, searchPath));
|
collection.AddSubAssetCreator(techset::CreateVertexShaderLoaderIW3(memory, searchPath));
|
||||||
collection.AddSubAssetCreator(techset::CreatePixelShaderLoaderIW3(memory, searchPath));
|
collection.AddSubAssetCreator(techset::CreatePixelShaderLoaderIW3(memory, searchPath));
|
||||||
|
collection.AddSubAssetCreator(weapon::CreateAccuracyGraphLoaderIW3(memory, searchPath));
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#include "WeaponGdtLoaderIW3.h"
|
||||||
|
|
||||||
|
#include "Game/IW3/IW3.h"
|
||||||
|
#include "Game/IW3/ObjConstantsIW3.h"
|
||||||
|
#include "InfoString/InfoString.h"
|
||||||
|
#include "Utils/Logging/Log.h"
|
||||||
|
#include "WeaponInfoStringLoaderIW3.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <format>
|
||||||
|
|
||||||
|
using namespace IW3;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class GdtLoaderWeapon final : public AssetCreator<AssetWeapon>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GdtLoaderWeapon(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone)
|
||||||
|
: m_gdt(gdt),
|
||||||
|
m_info_string_loader(memory, searchPath, zone)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||||
|
{
|
||||||
|
const auto* gdtEntry = m_gdt.GetGdtEntryByGdfAndName(GDF_FILENAME_WEAPON, assetName);
|
||||||
|
if (gdtEntry == nullptr)
|
||||||
|
return AssetCreationResult::NoAction();
|
||||||
|
|
||||||
|
InfoString infoString;
|
||||||
|
if (!infoString.FromGdtProperties(*gdtEntry))
|
||||||
|
{
|
||||||
|
con::error("Failed to read weapon gdt entry: \"{}\"", assetName);
|
||||||
|
return AssetCreationResult::Failure();
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_info_string_loader.CreateAsset(assetName, infoString, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
IGdtQueryable& m_gdt;
|
||||||
|
weapon::InfoStringLoaderIW3 m_info_string_loader;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace weapon
|
||||||
|
{
|
||||||
|
std::unique_ptr<AssetCreator<AssetWeapon>> CreateGdtLoaderIW3(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone)
|
||||||
|
{
|
||||||
|
return std::make_unique<GdtLoaderWeapon>(memory, searchPath, gdt, zone);
|
||||||
|
}
|
||||||
|
} // namespace weapon
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Asset/IAssetCreator.h"
|
||||||
|
#include "Game/IW3/IW3.h"
|
||||||
|
#include "Gdt/IGdtQueryable.h"
|
||||||
|
#include "SearchPath/ISearchPath.h"
|
||||||
|
#include "Utils/MemoryManager.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace weapon
|
||||||
|
{
|
||||||
|
std::unique_ptr<AssetCreator<IW3::AssetWeapon>> CreateGdtLoaderIW3(MemoryManager& memory, ISearchPath& searchPath, IGdtQueryable& gdt, Zone& zone);
|
||||||
|
} // namespace weapon
|
||||||
@@ -0,0 +1,432 @@
|
|||||||
|
#include "WeaponInfoStringLoaderIW3.h"
|
||||||
|
|
||||||
|
#include "Game/IW3/IW3.h"
|
||||||
|
#include "Game/IW3/InfoString/InfoStringToStructConverter.h"
|
||||||
|
#include "Game/IW3/Weapon/WeaponFields.h"
|
||||||
|
#include "Game/IW3/Weapon/WeaponStrings.h"
|
||||||
|
#include "Utils/Logging/Log.h"
|
||||||
|
#include "Weapon/WeaponCommon.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace IW3;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class InfoStringToWeaponConverter final : public InfoStringToStructConverter
|
||||||
|
{
|
||||||
|
bool ConvertHideTags(const cspField_t& field, const std::string& value)
|
||||||
|
{
|
||||||
|
std::vector<std::string> valueArray;
|
||||||
|
if (!ParseAsArray(value, valueArray))
|
||||||
|
{
|
||||||
|
con::error("Failed to parse hide tags as array");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueArray.size() > std::extent_v<decltype(WeaponDef::hideTags)>)
|
||||||
|
{
|
||||||
|
con::error("Cannot have more than {} hide tags!", std::extent_v<decltype(WeaponDef::hideTags)>);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* hideTags = reinterpret_cast<scr_string_t*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||||
|
|
||||||
|
if (valueArray.size() < std::extent_v<decltype(WeaponDef::hideTags)>)
|
||||||
|
m_registration.AddScriptString(m_zone_script_strings.AddOrGetScriptString(nullptr));
|
||||||
|
|
||||||
|
auto currentHideTag = 0u;
|
||||||
|
for (; currentHideTag < valueArray.size(); currentHideTag++)
|
||||||
|
{
|
||||||
|
const auto& currentValue = valueArray[currentHideTag];
|
||||||
|
const auto scrString =
|
||||||
|
!currentValue.empty() ? m_zone_script_strings.AddOrGetScriptString(currentValue) : m_zone_script_strings.AddOrGetScriptString(nullptr);
|
||||||
|
hideTags[currentHideTag] = scrString;
|
||||||
|
m_registration.AddScriptString(scrString);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; currentHideTag < std::extent_v<decltype(WeaponDef::hideTags)>; currentHideTag++)
|
||||||
|
hideTags[currentHideTag] = m_zone_script_strings.GetScriptString(nullptr);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool ConvertBounceSounds(const cspField_t& field, const std::string& value) const
|
||||||
|
{
|
||||||
|
auto** bounceSound = reinterpret_cast<SndAliasCustom**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||||
|
if (value.empty())
|
||||||
|
{
|
||||||
|
*bounceSound = nullptr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(std::extent_v<decltype(bounceSoundSuffixes)> == SURF_TYPE_NUM);
|
||||||
|
*bounceSound = m_memory.Alloc<SndAliasCustom>(SURF_TYPE_NUM);
|
||||||
|
for (auto i = 0u; i < SURF_TYPE_NUM; i++)
|
||||||
|
{
|
||||||
|
const auto currentBounceSound = value + bounceSoundSuffixes[i];
|
||||||
|
|
||||||
|
(*bounceSound)[i].name = m_memory.Alloc<snd_alias_list_name>();
|
||||||
|
(*bounceSound)[i].name->soundName = m_memory.Dup(currentBounceSound.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConvertNotetrackSoundMap(const cspField_t& field, const std::string& value)
|
||||||
|
{
|
||||||
|
std::vector<std::array<std::string, 2>> pairs;
|
||||||
|
if (!ParseAsArray(value, pairs))
|
||||||
|
{
|
||||||
|
con::error("Failed to parse notetracksoundmap as pairs");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pairs.size() > std::extent_v<decltype(WeaponDef::notetrackSoundMapKeys)>)
|
||||||
|
{
|
||||||
|
con::error("Cannot have more than {} notetracksoundmap entries!", std::extent_v<decltype(WeaponDef::notetrackSoundMapKeys)>);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* keys = reinterpret_cast<scr_string_t*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||||
|
auto* values = &keys[std::extent_v<decltype(WeaponDef::notetrackSoundMapKeys)>];
|
||||||
|
auto currentEntryNum = 0u;
|
||||||
|
|
||||||
|
if (pairs.size() < std::extent_v<decltype(WeaponDef::notetrackSoundMapKeys)>)
|
||||||
|
m_registration.AddScriptString(m_zone_script_strings.AddOrGetScriptString(nullptr));
|
||||||
|
|
||||||
|
for (; currentEntryNum < pairs.size(); currentEntryNum++)
|
||||||
|
{
|
||||||
|
const auto& currentValue = pairs[currentEntryNum];
|
||||||
|
const auto keyScriptString = !currentValue[0].empty() ? m_zone_script_strings.AddOrGetScriptString(currentValue[0])
|
||||||
|
: m_zone_script_strings.AddOrGetScriptString(nullptr);
|
||||||
|
const auto valueScriptString = !currentValue[1].empty() ? m_zone_script_strings.AddOrGetScriptString(currentValue[1])
|
||||||
|
: m_zone_script_strings.AddOrGetScriptString(nullptr);
|
||||||
|
|
||||||
|
keys[currentEntryNum] = keyScriptString;
|
||||||
|
m_registration.AddScriptString(keyScriptString);
|
||||||
|
|
||||||
|
values[currentEntryNum] = valueScriptString;
|
||||||
|
m_registration.AddScriptString(valueScriptString);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; currentEntryNum < std::extent_v<decltype(WeaponDef::notetrackSoundMapKeys)>; currentEntryNum++)
|
||||||
|
{
|
||||||
|
const auto emptyScr = m_zone_script_strings.GetScriptString(nullptr);
|
||||||
|
keys[currentEntryNum] = emptyScr;
|
||||||
|
values[currentEntryNum] = emptyScr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConvertAnimName(const cspField_t& field, const std::string& value)
|
||||||
|
{
|
||||||
|
if (ConvertString(value, field.iOffset))
|
||||||
|
{
|
||||||
|
if (!value.empty())
|
||||||
|
m_registration.AddIndirectAssetReference(m_context.LoadIndirectAssetReference<AssetXAnim>(value));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool ConvertExtensionField(const cspField_t& field, const std::string& value) override
|
||||||
|
{
|
||||||
|
switch (static_cast<weapFieldType_t>(field.iFieldType))
|
||||||
|
{
|
||||||
|
case WFT_WEAPONTYPE:
|
||||||
|
return ConvertEnumInt(field.szName, value, field.iOffset, szWeapTypeNames, std::extent_v<decltype(szWeapTypeNames)>);
|
||||||
|
|
||||||
|
case WFT_WEAPONCLASS:
|
||||||
|
return ConvertEnumInt(field.szName, value, field.iOffset, szWeapClassNames, std::extent_v<decltype(szWeapClassNames)>);
|
||||||
|
|
||||||
|
case WFT_OVERLAYRETICLE:
|
||||||
|
return ConvertEnumInt(field.szName, value, field.iOffset, szWeapOverlayReticleNames, std::extent_v<decltype(szWeapOverlayReticleNames)>);
|
||||||
|
|
||||||
|
case WFT_PENETRATE_TYPE:
|
||||||
|
return ConvertEnumInt(field.szName, value, field.iOffset, penetrateTypeNames, std::extent_v<decltype(penetrateTypeNames)>);
|
||||||
|
|
||||||
|
case WFT_IMPACT_TYPE:
|
||||||
|
return ConvertEnumInt(field.szName, value, field.iOffset, impactTypeNames, std::extent_v<decltype(impactTypeNames)>);
|
||||||
|
|
||||||
|
case WFT_STANCE:
|
||||||
|
return ConvertEnumInt(field.szName, value, field.iOffset, szWeapStanceNames, std::extent_v<decltype(szWeapStanceNames)>);
|
||||||
|
|
||||||
|
case WFT_PROJ_EXPLOSION:
|
||||||
|
return ConvertEnumInt(field.szName, value, field.iOffset, szProjectileExplosionNames, std::extent_v<decltype(szProjectileExplosionNames)>);
|
||||||
|
|
||||||
|
case WFT_OFFHAND_CLASS:
|
||||||
|
return ConvertEnumInt(field.szName, value, field.iOffset, offhandClassNames, std::extent_v<decltype(offhandClassNames)>);
|
||||||
|
|
||||||
|
case WFT_ANIMTYPE:
|
||||||
|
return ConvertEnumInt(field.szName, value, field.iOffset, playerAnimTypeNames, std::extent_v<decltype(playerAnimTypeNames)>);
|
||||||
|
|
||||||
|
case WFT_ACTIVE_RETICLE_TYPE:
|
||||||
|
return ConvertEnumInt(field.szName, value, field.iOffset, activeReticleNames, std::extent_v<decltype(activeReticleNames)>);
|
||||||
|
|
||||||
|
case WFT_GUIDED_MISSILE_TYPE:
|
||||||
|
return ConvertEnumInt(field.szName, value, field.iOffset, guidedMissileNames, std::extent_v<decltype(guidedMissileNames)>);
|
||||||
|
|
||||||
|
case WFT_BOUNCE_SOUND:
|
||||||
|
return ConvertBounceSounds(field, value);
|
||||||
|
|
||||||
|
case WFT_STICKINESS:
|
||||||
|
return ConvertEnumInt(field.szName, value, field.iOffset, stickinessNames, std::extent_v<decltype(stickinessNames)>);
|
||||||
|
|
||||||
|
case WFT_OVERLAYINTERFACE:
|
||||||
|
return ConvertEnumInt(field.szName, value, field.iOffset, overlayInterfaceNames, std::extent_v<decltype(overlayInterfaceNames)>);
|
||||||
|
|
||||||
|
case WFT_INVENTORYTYPE:
|
||||||
|
return ConvertEnumInt(field.szName, value, field.iOffset, szWeapInventoryTypeNames, std::extent_v<decltype(szWeapInventoryTypeNames)>);
|
||||||
|
|
||||||
|
case WFT_FIRETYPE:
|
||||||
|
return ConvertEnumInt(field.szName, value, field.iOffset, szWeapFireTypeNames, std::extent_v<decltype(szWeapFireTypeNames)>);
|
||||||
|
|
||||||
|
case WFT_AMMOCOUNTER_CLIPTYPE:
|
||||||
|
return ConvertEnumInt(field.szName, value, field.iOffset, ammoCounterClipNames, std::extent_v<decltype(ammoCounterClipNames)>);
|
||||||
|
|
||||||
|
case WFT_ICONRATIO_HUD:
|
||||||
|
case WFT_ICONRATIO_AMMOCOUNTER:
|
||||||
|
case WFT_ICONRATIO_KILL:
|
||||||
|
case WFT_ICONRATIO_DPAD:
|
||||||
|
return ConvertEnumInt(field.szName, value, field.iOffset, weapIconRatioNames, std::extent_v<decltype(weapIconRatioNames)>);
|
||||||
|
|
||||||
|
case WFT_HIDETAGS:
|
||||||
|
return ConvertHideTags(field, value);
|
||||||
|
|
||||||
|
case WFT_NOTETRACKSOUNDMAP:
|
||||||
|
return ConvertNotetrackSoundMap(field, value);
|
||||||
|
|
||||||
|
case WFT_ANIM_NAME:
|
||||||
|
return ConvertAnimName(field, value);
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
InfoStringToWeaponConverter(const InfoString& infoString,
|
||||||
|
WeaponDef& weaponDef,
|
||||||
|
ZoneScriptStrings& zoneScriptStrings,
|
||||||
|
MemoryManager& memory,
|
||||||
|
AssetCreationContext& context,
|
||||||
|
AssetRegistration<AssetWeapon>& registration,
|
||||||
|
const cspField_t* fields,
|
||||||
|
const size_t fieldCount)
|
||||||
|
: InfoStringToStructConverter(infoString, &weaponDef, zoneScriptStrings, memory, context, registration, fields, fieldCount)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void InitWeaponDef(WeaponDef& weapon)
|
||||||
|
{
|
||||||
|
for (const auto& field : weapon_fields)
|
||||||
|
{
|
||||||
|
if (field.iFieldType != CSPFT_STRING && field.iFieldType != WFT_ANIM_NAME)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
*reinterpret_cast<const char**>(reinterpret_cast<char*>(&weapon) + field.iOffset) = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
weapon.szXAnims[WEAP_ANIM_ROOT] = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadAccuracyGraph(const std::string& graphName,
|
||||||
|
vec2_t*& originalGraphKnots,
|
||||||
|
int& originalGraphKnotCount,
|
||||||
|
vec2_t*& graphKnots,
|
||||||
|
int& graphKnotCount,
|
||||||
|
AssetCreationContext& context)
|
||||||
|
{
|
||||||
|
auto* accuracyGraphAsset = context.LoadSubAsset<SubAssetAccuracyGraph>(graphName);
|
||||||
|
if (!accuracyGraphAsset)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto* accuracyGraph = accuracyGraphAsset->Asset();
|
||||||
|
|
||||||
|
assert(accuracyGraphAsset->m_dependencies.empty());
|
||||||
|
assert(accuracyGraphAsset->m_used_script_strings.empty());
|
||||||
|
assert(accuracyGraphAsset->m_indirect_asset_references.empty());
|
||||||
|
|
||||||
|
originalGraphKnots = accuracyGraph->graphKnots;
|
||||||
|
originalGraphKnotCount = accuracyGraph->graphKnotCount;
|
||||||
|
|
||||||
|
graphKnots = accuracyGraph->graphKnots;
|
||||||
|
graphKnotCount = accuracyGraph->graphKnotCount;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadAccuracyGraphs(WeaponDef& weaponDef, AssetCreationContext& context)
|
||||||
|
{
|
||||||
|
if (weaponDef.aiVsAiAccuracyGraphName && weaponDef.aiVsAiAccuracyGraphName[0])
|
||||||
|
{
|
||||||
|
if (!LoadAccuracyGraph(weapon::GetAssetNameForAiVsAiAccuracyGraph(weaponDef.aiVsAiAccuracyGraphName),
|
||||||
|
weaponDef.originalAiVsAiAccuracyGraphKnots,
|
||||||
|
weaponDef.originalAiVsAiAccuracyGraphKnotCount,
|
||||||
|
weaponDef.aiVsAiAccuracyGraphKnots,
|
||||||
|
weaponDef.aiVsAiAccuracyGraphKnotCount,
|
||||||
|
context))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weaponDef.aiVsPlayerAccuracyGraphName && weaponDef.aiVsPlayerAccuracyGraphName[0])
|
||||||
|
{
|
||||||
|
if (!LoadAccuracyGraph(weapon::GetAssetNameForAiVsPlayerAccuracyGraph(weaponDef.aiVsPlayerAccuracyGraphName),
|
||||||
|
weaponDef.originalAiVsPlayerAccuracyGraphKnots,
|
||||||
|
weaponDef.originalAiVsPlayerAccuracyGraphKnotCount,
|
||||||
|
weaponDef.aiVsPlayerAccuracyGraphKnots,
|
||||||
|
weaponDef.aiVsPlayerAccuracyGraphKnotCount,
|
||||||
|
context))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsDefaultWeapon(const WeaponDef& weapon)
|
||||||
|
{
|
||||||
|
return strcmp(weapon.szInternalName, "defaultweapon") == 0 || strcmp(weapon.szInternalName, "defaultweapon_mp") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_alias_list_name* SetDefaultSound(const char* name, MemoryManager& memory)
|
||||||
|
{
|
||||||
|
auto* aliasListName = memory.Alloc<snd_alias_list_name>();
|
||||||
|
aliasListName->soundName = name;
|
||||||
|
|
||||||
|
return aliasListName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetWeaponDefaults(WeaponDef& weapon, MemoryManager& memory)
|
||||||
|
{
|
||||||
|
if (IsDefaultWeapon(weapon))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!weapon.viewLastShotEjectEffect)
|
||||||
|
weapon.viewLastShotEjectEffect = weapon.viewShellEjectEffect;
|
||||||
|
if (!weapon.worldLastShotEjectEffect)
|
||||||
|
weapon.worldLastShotEjectEffect = weapon.worldShellEjectEffect;
|
||||||
|
if (!weapon.raiseSound.name)
|
||||||
|
SetDefaultSound("weap_raise", memory);
|
||||||
|
if (!weapon.putawaySound.name)
|
||||||
|
SetDefaultSound("weap_putaway", memory);
|
||||||
|
if (!weapon.pickupSound.name)
|
||||||
|
SetDefaultSound("weap_pickup", memory);
|
||||||
|
if (!weapon.ammoPickupSound.name)
|
||||||
|
SetDefaultSound("weap_ammo_pickup", memory);
|
||||||
|
if (!weapon.emptyFireSound.name)
|
||||||
|
SetDefaultSound("weap_dryfire_smg_npc", memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupTransitionTimes(WeaponDef& weapon)
|
||||||
|
{
|
||||||
|
if (weapon.iAdsTransInTime <= 0)
|
||||||
|
weapon.fOOPosAnimLength[0] = 1.0f / 300.0f; // 0.0033333334f;
|
||||||
|
else
|
||||||
|
weapon.fOOPosAnimLength[0] = 1.0f / static_cast<float>(weapon.iAdsTransInTime);
|
||||||
|
|
||||||
|
if (weapon.iAdsTransOutTime <= 0)
|
||||||
|
weapon.fOOPosAnimLength[1] = 1.0f / 500.0f; // 0.0020000001f
|
||||||
|
else
|
||||||
|
weapon.fOOPosAnimLength[1] = 1.0f / static_cast<float>(weapon.iAdsTransOutTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckWeaponDamageRanges(WeaponDef& weapon)
|
||||||
|
{
|
||||||
|
if (strcmp(weapon.szInternalName, "none") == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (weapon.fMaxDamageRange <= 0.0)
|
||||||
|
weapon.fMaxDamageRange = 999999.0f;
|
||||||
|
if (weapon.fMinDamageRange <= 0.0)
|
||||||
|
weapon.fMinDamageRange = 999999.12f; // oddly specific number, no clue
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckCrosshairValues(WeaponDef& weapon)
|
||||||
|
{
|
||||||
|
if (weapon.enemyCrosshairRange > 15000.0f)
|
||||||
|
con::warn("Weapon {}: Enemy crosshair ranges should be less than 15000", weapon.szInternalName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckProjectileValues(WeaponDef& weapon)
|
||||||
|
{
|
||||||
|
if (weapon.weapType != WEAPTYPE_PROJECTILE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (weapon.iProjectileSpeed <= 0)
|
||||||
|
con::warn("Weapon {}: Projectile speed must be greater than 0.0", weapon.szDisplayName);
|
||||||
|
|
||||||
|
if (weapon.destabilizationCurvatureMax >= 1000000000.0f || weapon.destabilizationCurvatureMax < 0.0f)
|
||||||
|
con::warn("Weapon {}: Destabilization angle must be between 0 and 45 degrees", weapon.szDisplayName);
|
||||||
|
|
||||||
|
if (weapon.destabilizationRateTime < 0.0f)
|
||||||
|
con::warn("Weapon {}: Destabilization rate time must be non-negative", weapon.szDisplayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckSharedAmmoValues(const WeaponDef& weapon)
|
||||||
|
{
|
||||||
|
if (weapon.szAmmoName)
|
||||||
|
utils::MakeStringLowerCase(const_cast<char*>(weapon.szAmmoName));
|
||||||
|
|
||||||
|
if (weapon.szClipName)
|
||||||
|
utils::MakeStringLowerCase(const_cast<char*>(weapon.szClipName));
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace weapon
|
||||||
|
{
|
||||||
|
InfoStringLoaderIW3::InfoStringLoaderIW3(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||||
|
: m_memory(memory),
|
||||||
|
m_search_path(searchPath),
|
||||||
|
m_zone(zone)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetCreationResult InfoStringLoaderIW3::CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context) const
|
||||||
|
{
|
||||||
|
auto* weaponDef = m_memory.Alloc<WeaponDef>();
|
||||||
|
memset(weaponDef, 0, sizeof(WeaponDef));
|
||||||
|
|
||||||
|
InitWeaponDef(*weaponDef);
|
||||||
|
weaponDef->szInternalName = m_memory.Dup(assetName.c_str());
|
||||||
|
|
||||||
|
AssetRegistration<AssetWeapon> registration(assetName, weaponDef);
|
||||||
|
|
||||||
|
InfoStringToWeaponConverter converter(
|
||||||
|
infoString, *weaponDef, m_zone.m_script_strings, m_memory, context, registration, weapon_fields, std::extent_v<decltype(weapon_fields)>);
|
||||||
|
if (!converter.Convert())
|
||||||
|
{
|
||||||
|
con::error("Failed to parse weapon: \"{}\"", assetName);
|
||||||
|
return AssetCreationResult::Failure();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!LoadAccuracyGraphs(*weaponDef, context))
|
||||||
|
{
|
||||||
|
con::error("Failed to load accuracy tables of weapon: \"{}\"", assetName);
|
||||||
|
return AssetCreationResult::Failure();
|
||||||
|
}
|
||||||
|
|
||||||
|
SetWeaponDefaults(*weaponDef, m_memory);
|
||||||
|
SetupTransitionTimes(*weaponDef);
|
||||||
|
CheckWeaponDamageRanges(*weaponDef);
|
||||||
|
CheckCrosshairValues(*weaponDef);
|
||||||
|
CheckProjectileValues(*weaponDef);
|
||||||
|
CheckSharedAmmoValues(*weaponDef);
|
||||||
|
|
||||||
|
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||||
|
}
|
||||||
|
} // namespace weapon
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Asset/AssetCreationContext.h"
|
||||||
|
#include "Asset/AssetCreationResult.h"
|
||||||
|
#include "InfoString/InfoString.h"
|
||||||
|
|
||||||
|
namespace weapon
|
||||||
|
{
|
||||||
|
class InfoStringLoaderIW3
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InfoStringLoaderIW3(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||||
|
|
||||||
|
AssetCreationResult CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
MemoryManager& m_memory;
|
||||||
|
ISearchPath& m_search_path;
|
||||||
|
Zone& m_zone;
|
||||||
|
};
|
||||||
|
} // namespace weapon
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#include "WeaponRawLoaderIW3.h"
|
||||||
|
|
||||||
|
#include "Game/IW3/IW3.h"
|
||||||
|
#include "Game/IW3/ObjConstantsIW3.h"
|
||||||
|
#include "InfoString/InfoString.h"
|
||||||
|
#include "Utils/Logging/Log.h"
|
||||||
|
#include "Weapon/WeaponCommon.h"
|
||||||
|
#include "WeaponInfoStringLoaderIW3.h"
|
||||||
|
|
||||||
|
using namespace IW3;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
SearchPathOpenFile OpenWeaponFile(ISearchPath& searchPath, const std::string& assetName, std::string& fileName)
|
||||||
|
{
|
||||||
|
fileName = weapon::GetFileNameForAssetName(assetName);
|
||||||
|
return searchPath.Open(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
class RawLoaderWeapon final : public AssetCreator<AssetWeapon>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RawLoaderWeapon(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||||
|
: m_search_path(searchPath),
|
||||||
|
m_info_string_loader(memory, searchPath, zone)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||||
|
{
|
||||||
|
std::string fileName;
|
||||||
|
const auto file = OpenWeaponFile(m_search_path, assetName, fileName);
|
||||||
|
if (!file.IsOpen())
|
||||||
|
return AssetCreationResult::NoAction();
|
||||||
|
|
||||||
|
InfoString infoString;
|
||||||
|
if (!infoString.FromStream(INFO_STRING_PREFIX_WEAPON, *file.m_stream))
|
||||||
|
{
|
||||||
|
con::error("Could not parse as info string file: \"{}\"", fileName);
|
||||||
|
return AssetCreationResult::Failure();
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_info_string_loader.CreateAsset(assetName, infoString, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ISearchPath& m_search_path;
|
||||||
|
weapon::InfoStringLoaderIW3 m_info_string_loader;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace weapon
|
||||||
|
{
|
||||||
|
std::unique_ptr<AssetCreator<AssetWeapon>> CreateRawLoaderIW3(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||||
|
{
|
||||||
|
return std::make_unique<RawLoaderWeapon>(memory, searchPath, zone);
|
||||||
|
}
|
||||||
|
} // namespace weapon
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Asset/IAssetCreator.h"
|
||||||
|
#include "Game/IW3/IW3.h"
|
||||||
|
#include "SearchPath/ISearchPath.h"
|
||||||
|
#include "Utils/MemoryManager.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace weapon
|
||||||
|
{
|
||||||
|
std::unique_ptr<AssetCreator<IW3::AssetWeapon>> CreateRawLoaderIW3(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||||
|
} // namespace weapon
|
||||||
@@ -268,7 +268,7 @@ namespace
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadAccuracyGraphs(WeaponFullDef& weaponFullDef, MemoryManager& memory, ISearchPath& searchPath, AssetCreationContext& context)
|
bool LoadAccuracyGraphs(WeaponFullDef& weaponFullDef, AssetCreationContext& context)
|
||||||
{
|
{
|
||||||
if (weaponFullDef.weapDef.aiVsAiAccuracyGraphName && weaponFullDef.weapDef.aiVsAiAccuracyGraphName[0])
|
if (weaponFullDef.weapDef.aiVsAiAccuracyGraphName && weaponFullDef.weapDef.aiVsAiAccuracyGraphName[0])
|
||||||
{
|
{
|
||||||
@@ -437,7 +437,7 @@ namespace weapon
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetCreationResult InfoStringLoaderT5::CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context)
|
AssetCreationResult InfoStringLoaderT5::CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context) const
|
||||||
{
|
{
|
||||||
auto* weaponFullDef = m_memory.Alloc<WeaponFullDef>();
|
auto* weaponFullDef = m_memory.Alloc<WeaponFullDef>();
|
||||||
weaponFullDef->weapVariantDef.szInternalName = m_memory.Dup(assetName.c_str());
|
weaponFullDef->weapVariantDef.szInternalName = m_memory.Dup(assetName.c_str());
|
||||||
@@ -454,7 +454,7 @@ namespace weapon
|
|||||||
return AssetCreationResult::Failure();
|
return AssetCreationResult::Failure();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!LoadAccuracyGraphs(*weaponFullDef, m_memory, m_search_path, context))
|
if (!LoadAccuracyGraphs(*weaponFullDef, context))
|
||||||
{
|
{
|
||||||
con::error("Failed to load accuracy tables of weapon: \"{}\"", assetName);
|
con::error("Failed to load accuracy tables of weapon: \"{}\"", assetName);
|
||||||
return AssetCreationResult::Failure();
|
return AssetCreationResult::Failure();
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace weapon
|
|||||||
public:
|
public:
|
||||||
InfoStringLoaderT5(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
InfoStringLoaderT5(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||||
|
|
||||||
AssetCreationResult CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context);
|
AssetCreationResult CreateAsset(const std::string& assetName, const InfoString& infoString, AssetCreationContext& context) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MemoryManager& m_memory;
|
MemoryManager& m_memory;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#options GAME(IW4, IW5, T5, T6)
|
#options GAME(IW3, IW4, IW5, T5, T6)
|
||||||
|
|
||||||
#filename "Game/" + GAME + "/Weapon/AccuracyGraphLoader" + GAME + ".cpp"
|
#filename "Game/" + GAME + "/Weapon/AccuracyGraphLoader" + GAME + ".cpp"
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "Sound/LoadedSoundDumperIW3.h"
|
#include "Sound/LoadedSoundDumperIW3.h"
|
||||||
#include "Sound/SndCurveDumperIW3.h"
|
#include "Sound/SndCurveDumperIW3.h"
|
||||||
#include "StringTable/StringTableDumperIW3.h"
|
#include "StringTable/StringTableDumperIW3.h"
|
||||||
|
#include "Weapon/WeaponDumperIW3.h"
|
||||||
|
|
||||||
using namespace IW3;
|
using namespace IW3;
|
||||||
|
|
||||||
@@ -44,7 +45,7 @@ void ObjWriter::RegisterAssetDumpers(AssetDumpingContext& context)
|
|||||||
// REGISTER_DUMPER(AssetDumperMenuList)
|
// REGISTER_DUMPER(AssetDumperMenuList)
|
||||||
// REGISTER_DUMPER(AssetDumpermenuDef_t)
|
// REGISTER_DUMPER(AssetDumpermenuDef_t)
|
||||||
RegisterAssetDumper(std::make_unique<localize::DumperIW3>());
|
RegisterAssetDumper(std::make_unique<localize::DumperIW3>());
|
||||||
// REGISTER_DUMPER(AssetDumperWeapon)
|
RegisterAssetDumper(std::make_unique<weapon::DumperIW3>());
|
||||||
// REGISTER_DUMPER(AssetDumperSndDriverGlobals)
|
// REGISTER_DUMPER(AssetDumperSndDriverGlobals)
|
||||||
// REGISTER_DUMPER(AssetDumperFxEffectDef)
|
// REGISTER_DUMPER(AssetDumperFxEffectDef)
|
||||||
// REGISTER_DUMPER(AssetDumperFxImpactTable)
|
// REGISTER_DUMPER(AssetDumperFxImpactTable)
|
||||||
|
|||||||
@@ -0,0 +1,286 @@
|
|||||||
|
#include "WeaponDumperIW3.h"
|
||||||
|
|
||||||
|
#include "Game/IW3/CommonIW3.h"
|
||||||
|
#include "Game/IW3/InfoString/InfoStringFromStructConverter.h"
|
||||||
|
#include "Game/IW3/ObjConstantsIW3.h"
|
||||||
|
#include "Game/IW3/Weapon/WeaponFields.h"
|
||||||
|
#include "Game/IW3/Weapon/WeaponStrings.h"
|
||||||
|
#include "Weapon/AccuracyGraphWriter.h"
|
||||||
|
#include "Weapon/WeaponCommon.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <functional>
|
||||||
|
#include <sstream>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
using namespace IW3;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class InfoStringFromWeaponConverter final : public InfoStringFromStructConverter
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void FillFromExtensionField(const cspField_t& field) override
|
||||||
|
{
|
||||||
|
switch (static_cast<weapFieldType_t>(field.iFieldType))
|
||||||
|
{
|
||||||
|
case WFT_WEAPONTYPE:
|
||||||
|
FillFromEnumInt(std::string(field.szName), field.iOffset, szWeapTypeNames, std::extent_v<decltype(szWeapTypeNames)>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WFT_WEAPONCLASS:
|
||||||
|
FillFromEnumInt(std::string(field.szName), field.iOffset, szWeapClassNames, std::extent_v<decltype(szWeapClassNames)>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WFT_OVERLAYRETICLE:
|
||||||
|
FillFromEnumInt(std::string(field.szName), field.iOffset, szWeapOverlayReticleNames, std::extent_v<decltype(szWeapOverlayReticleNames)>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WFT_PENETRATE_TYPE:
|
||||||
|
FillFromEnumInt(std::string(field.szName), field.iOffset, penetrateTypeNames, std::extent_v<decltype(penetrateTypeNames)>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WFT_IMPACT_TYPE:
|
||||||
|
FillFromEnumInt(std::string(field.szName), field.iOffset, impactTypeNames, std::extent_v<decltype(impactTypeNames)>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WFT_STANCE:
|
||||||
|
FillFromEnumInt(std::string(field.szName), field.iOffset, szWeapStanceNames, std::extent_v<decltype(szWeapStanceNames)>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WFT_PROJ_EXPLOSION:
|
||||||
|
FillFromEnumInt(std::string(field.szName), field.iOffset, szProjectileExplosionNames, std::extent_v<decltype(szProjectileExplosionNames)>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WFT_OFFHAND_CLASS:
|
||||||
|
FillFromEnumInt(std::string(field.szName), field.iOffset, offhandClassNames, std::extent_v<decltype(offhandClassNames)>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WFT_ANIMTYPE:
|
||||||
|
FillFromEnumInt(std::string(field.szName), field.iOffset, playerAnimTypeNames, std::extent_v<decltype(playerAnimTypeNames)>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WFT_ACTIVE_RETICLE_TYPE:
|
||||||
|
FillFromEnumInt(std::string(field.szName), field.iOffset, activeReticleNames, std::extent_v<decltype(activeReticleNames)>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WFT_GUIDED_MISSILE_TYPE:
|
||||||
|
FillFromEnumInt(std::string(field.szName), field.iOffset, guidedMissileNames, std::extent_v<decltype(guidedMissileNames)>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WFT_BOUNCE_SOUND:
|
||||||
|
{
|
||||||
|
const auto* bounceSound = *reinterpret_cast<SndAliasCustom**>(reinterpret_cast<uintptr_t>(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<decltype(stickinessNames)>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WFT_OVERLAYINTERFACE:
|
||||||
|
FillFromEnumInt(std::string(field.szName), field.iOffset, overlayInterfaceNames, std::extent_v<decltype(overlayInterfaceNames)>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WFT_INVENTORYTYPE:
|
||||||
|
FillFromEnumInt(std::string(field.szName), field.iOffset, szWeapInventoryTypeNames, std::extent_v<decltype(szWeapInventoryTypeNames)>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WFT_FIRETYPE:
|
||||||
|
FillFromEnumInt(std::string(field.szName), field.iOffset, szWeapFireTypeNames, std::extent_v<decltype(szWeapFireTypeNames)>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WFT_AMMOCOUNTER_CLIPTYPE:
|
||||||
|
FillFromEnumInt(std::string(field.szName), field.iOffset, ammoCounterClipNames, std::extent_v<decltype(ammoCounterClipNames)>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WFT_ICONRATIO_HUD:
|
||||||
|
case WFT_ICONRATIO_AMMOCOUNTER:
|
||||||
|
case WFT_ICONRATIO_KILL:
|
||||||
|
case WFT_ICONRATIO_DPAD:
|
||||||
|
FillFromEnumInt(std::string(field.szName), field.iOffset, weapIconRatioNames, std::extent_v<decltype(weapIconRatioNames)>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WFT_HIDETAGS:
|
||||||
|
{
|
||||||
|
const auto* hideTags = reinterpret_cast<scr_string_t*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||||
|
std::stringstream ss;
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
for (auto i = 0u; i < std::extent_v<decltype(WeaponDef::hideTags)>; 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<scr_string_t*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||||
|
const auto* values = &keys[std::extent_v<decltype(WeaponDef::notetrackSoundMapKeys)>];
|
||||||
|
std::stringstream ss;
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
for (auto i = 0u; i < std::extent_v<decltype(WeaponDef::notetrackSoundMapKeys)>; 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 WeaponDef* structure,
|
||||||
|
const cspField_t* fields,
|
||||||
|
const size_t fieldCount,
|
||||||
|
std::function<std::string(scr_string_t)> scriptStringValueCallback)
|
||||||
|
: InfoStringFromStructConverter(structure, fields, fieldCount, std::move(scriptStringValueCallback))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
InfoString CreateInfoString(const XAssetInfo<WeaponDef>& asset)
|
||||||
|
{
|
||||||
|
InfoStringFromWeaponConverter converter(asset.Asset(),
|
||||||
|
weapon_fields,
|
||||||
|
std::extent_v<decltype(weapon_fields)>,
|
||||||
|
[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();
|
||||||
|
}
|
||||||
|
|
||||||
|
GenericGraph2D ConvertAccuracyGraph(std::string graphName, const vec2_t* originalKnots, const unsigned originalKnotCount)
|
||||||
|
{
|
||||||
|
GenericGraph2D graph;
|
||||||
|
|
||||||
|
graph.name = std::move(graphName);
|
||||||
|
graph.knots.resize(originalKnotCount);
|
||||||
|
|
||||||
|
for (auto i = 0u; i < originalKnotCount; i++)
|
||||||
|
{
|
||||||
|
auto& knot = graph.knots[i];
|
||||||
|
knot.x = originalKnots[i].x;
|
||||||
|
knot.y = originalKnots[i].y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpAccuracyGraphs(AssetDumpingContext& context, const XAssetInfo<WeaponDef>& asset)
|
||||||
|
{
|
||||||
|
auto* accuracyGraphWriter = context.GetZoneAssetDumperState<AccuracyGraphWriter>();
|
||||||
|
const auto* weapon = asset.Asset();
|
||||||
|
|
||||||
|
if (weapon->aiVsAiAccuracyGraphName && weapon->originalAiVsAiAccuracyGraphKnots)
|
||||||
|
{
|
||||||
|
auto graphName = weapon::GetAssetNameForAiVsAiAccuracyGraph(weapon->aiVsAiAccuracyGraphName);
|
||||||
|
if (accuracyGraphWriter->ShouldDumpGraph(graphName))
|
||||||
|
{
|
||||||
|
const auto graph =
|
||||||
|
ConvertAccuracyGraph(std::move(graphName), weapon->originalAiVsAiAccuracyGraphKnots, weapon->originalAiVsAiAccuracyGraphKnotCount);
|
||||||
|
AccuracyGraphWriter::DumpGraph(context, graph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weapon->aiVsPlayerAccuracyGraphName && weapon->originalAiVsPlayerAccuracyGraphKnots)
|
||||||
|
{
|
||||||
|
auto graphName = weapon::GetAssetNameForAiVsPlayerAccuracyGraph(weapon->aiVsPlayerAccuracyGraphName);
|
||||||
|
if (accuracyGraphWriter->ShouldDumpGraph(graphName))
|
||||||
|
{
|
||||||
|
const auto graph =
|
||||||
|
ConvertAccuracyGraph(std::move(graphName), weapon->originalAiVsPlayerAccuracyGraphKnots, weapon->originalAiVsPlayerAccuracyGraphKnotCount);
|
||||||
|
AccuracyGraphWriter::DumpGraph(context, graph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace weapon
|
||||||
|
{
|
||||||
|
void DumperIW3::DumpAsset(AssetDumpingContext& context, const XAssetInfo<AssetWeapon::Type>& asset)
|
||||||
|
{
|
||||||
|
// Only dump raw when no gdt available
|
||||||
|
if (context.m_gdt)
|
||||||
|
{
|
||||||
|
const auto infoString = CreateInfoString(asset);
|
||||||
|
GdtEntry gdtEntry(asset.m_name, GDF_FILENAME_WEAPON);
|
||||||
|
infoString.ToGdtProperties(INFO_STRING_PREFIX_WEAPON, gdtEntry);
|
||||||
|
context.m_gdt->WriteEntry(gdtEntry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto assetFile = context.OpenAssetFile(GetFileNameForAssetName(asset.m_name));
|
||||||
|
|
||||||
|
if (!assetFile)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto& stream = *assetFile;
|
||||||
|
const auto infoString = CreateInfoString(asset);
|
||||||
|
const auto stringValue = infoString.ToString(INFO_STRING_PREFIX_WEAPON);
|
||||||
|
stream.write(stringValue.c_str(), stringValue.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
DumpAccuracyGraphs(context, asset);
|
||||||
|
}
|
||||||
|
} // namespace weapon
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
|
#include "Game/IW3/IW3.h"
|
||||||
|
|
||||||
|
namespace weapon
|
||||||
|
{
|
||||||
|
class DumperIW3 final : public AbstractAssetDumper<IW3::AssetWeapon>
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<IW3::AssetWeapon::Type>& asset) override;
|
||||||
|
};
|
||||||
|
} // namespace weapon
|
||||||
Reference in New Issue
Block a user