Merge pull request #164 from Laupetin/feature/iw5-weapons

feat: dump iw5 weapons and attachments
This commit is contained in:
Jan 2024-04-14 13:36:47 +02:00 committed by GitHub
commit 7de33880d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 3127 additions and 143 deletions

View File

@ -3933,7 +3933,7 @@ namespace IW4
WEAPOVERLAYRETICLE_NUM WEAPOVERLAYRETICLE_NUM
}; };
enum WeapOverlayInteface_t enum WeapOverlayInterface_t
{ {
WEAPOVERLAYINTERFACE_NONE = 0x0, WEAPOVERLAYINTERFACE_NONE = 0x0,
WEAPOVERLAYINTERFACE_JAVELIN = 0x1, WEAPOVERLAYINTERFACE_JAVELIN = 0x1,
@ -4275,7 +4275,7 @@ namespace IW4
Material* overlayMaterialEMP; Material* overlayMaterialEMP;
Material* overlayMaterialEMPLowRes; Material* overlayMaterialEMPLowRes;
weapOverlayReticle_t overlayReticle; weapOverlayReticle_t overlayReticle;
WeapOverlayInteface_t overlayInterface; WeapOverlayInterface_t overlayInterface;
float overlayWidth; float overlayWidth;
float overlayHeight; float overlayHeight;
float overlayWidthSplitscreen; float overlayWidthSplitscreen;

View File

@ -78,9 +78,63 @@ namespace IW5
CSPFT_FX, CSPFT_FX,
CSPFT_XMODEL, CSPFT_XMODEL,
CSPFT_MATERIAL, CSPFT_MATERIAL,
CSPFT_PHYS_COLLMAP,
CSPFT_SOUND, CSPFT_SOUND,
CSPFT_TRACER, CSPFT_TRACER,
CSPFT_SCRIPT_STRING,
CSPFT_NUM_BASE_FIELD_TYPES, CSPFT_NUM_BASE_FIELD_TYPES,
}; };
enum weapFieldType_t
{
WFT_WEAPONTYPE = CSPFT_NUM_BASE_FIELD_TYPES,
WFT_WEAPONCLASS,
WFT_OVERLAYRETICLE,
WFT_PENETRATE_TYPE,
WFT_IMPACT_TYPE,
WFT_STANCE,
WFT_PROJ_EXPLOSION,
WFT_OFFHAND_CLASS,
WFT_ANIMTYPE,
WFT_ACTIVE_RETICLE_TYPE,
WFT_GUIDED_MISSILE_TYPE,
WFT_PER_SURFACE_TYPE_SOUND,
WFT_STICKINESS,
WFT_OVERLAYINTERFACE,
WFT_INVENTORYTYPE,
WFT_FIRETYPE,
WFT_AMMOCOUNTER_CLIPTYPE,
WFT_ICONRATIO_HUD,
WFT_ICONRATIO_PICKUP,
WFT_ICONRATIO_AMMOCOUNTER,
WFT_ICONRATIO_KILL,
WFT_ICONRATIO_DPAD,
WFT_HIDETAGS,
WFT_NOTETRACKSOUNDMAP,
WFT_NOTETRACKRUMBLEMAP,
// Custom
WFT_ANIM_NAME,
WFT_ATTACHMENT,
WFT_ANIM_OVERRIDES,
WFT_SOUND_OVERRIDES,
WFT_FX_OVERRIDES,
WFT_RELOAD_OVERRIDES,
WFT_NOTETRACK_OVERRIDES,
WFT_NUM_FIELD_TYPES,
};
enum weaponAttachmentFieldType_t
{
WAFT_ATTACHMENT_TYPE = CSPFT_NUM_BASE_FIELD_TYPES,
WAFT_WEAPONTYPE,
WAFT_WEAPONCLASS,
WAFT_PENETRATE_TYPE,
WAFT_IMPACT_TYPE,
WAFT_FIRETYPE,
WAFT_NUM_FIELD_TYPES,
};
} // namespace IW5 } // namespace IW5

View File

@ -2852,7 +2852,7 @@ namespace IW5
WEAPTYPE_PROJECTILE = 0x3, WEAPTYPE_PROJECTILE = 0x3,
WEAPTYPE_RIOTSHIELD = 0x4, WEAPTYPE_RIOTSHIELD = 0x4,
WEAPTYPE_NUM WEAPTYPE_COUNT
}; };
enum weapClass_t enum weapClass_t
@ -2870,7 +2870,7 @@ namespace IW5
WEAPCLASS_NON_PLAYER = 0xA, WEAPCLASS_NON_PLAYER = 0xA,
WEAPCLASS_ITEM = 0xB, WEAPCLASS_ITEM = 0xB,
WEAPCLASS_NUM WEAPCLASS_COUNT
}; };
enum PenetrateType enum PenetrateType
@ -2909,9 +2909,7 @@ namespace IW5
WEAPON_FIRETYPE_BURSTFIRE4 = 0x4, WEAPON_FIRETYPE_BURSTFIRE4 = 0x4,
WEAPON_FIRETYPE_DOUBLEBARREL = 0x5, WEAPON_FIRETYPE_DOUBLEBARREL = 0x5,
WEAPON_FIRETYPECOUNT, WEAPON_FIRETYPE_COUNT
WEAPON_FIRETYPE_BURSTFIRE_FIRST = WEAPON_FIRETYPE_BURSTFIRE2,
WEAPON_FIRETYPE_BURSTFIRE_LAST = WEAPON_FIRETYPE_BURSTFIRE4
}; };
struct AttAmmoGeneral struct AttAmmoGeneral
@ -3099,7 +3097,7 @@ namespace IW5
WEAPOVERLAYRETICLE_NONE = 0x0, WEAPOVERLAYRETICLE_NONE = 0x0,
WEAPOVERLAYRETICLE_CROSSHAIR = 0x1, WEAPOVERLAYRETICLE_CROSSHAIR = 0x1,
WEAPOVERLAYRETICLE_NUM WEAPOVERLAYRETICLE_COUNT
}; };
struct ADSOverlay struct ADSOverlay
@ -3168,7 +3166,7 @@ namespace IW5
WEAPPROJEXP_SMOKE = 0x5, WEAPPROJEXP_SMOKE = 0x5,
WEAPPROJEXP_HEAVY = 0x6, WEAPPROJEXP_HEAVY = 0x6,
WEAPPROJEXP_NUM WEAPPROJEXP_COUNT
}; };
struct snd_alias_list_name struct snd_alias_list_name
@ -3221,7 +3219,7 @@ namespace IW5
XModel** worldModels; XModel** worldModels;
XModel** viewModels; XModel** viewModels;
XModel** reticleViewModels; XModel** reticleViewModels;
AttAmmoGeneral* ammogeneral; AttAmmoGeneral* ammoGeneral;
AttSight4* sight; AttSight4* sight;
AttReload* reload; AttReload* reload;
AttAddOns* addOns; AttAddOns* addOns;
@ -3266,7 +3264,7 @@ namespace IW5
WEAPINVENTORY_EXCLUSIVE = 0x4, WEAPINVENTORY_EXCLUSIVE = 0x4,
WEAPINVENTORY_SCAVENGER = 0x5, WEAPINVENTORY_SCAVENGER = 0x5,
WEAPINVENTORYCOUNT WEAPINVENTORY_COUNT
}; };
enum OffhandClass enum OffhandClass
@ -3287,7 +3285,7 @@ namespace IW5
WEAPSTANCE_DUCK = 0x1, WEAPSTANCE_DUCK = 0x1,
WEAPSTANCE_PRONE = 0x2, WEAPSTANCE_PRONE = 0x2,
WEAPSTANCE_NUM WEAPSTANCE_COUNT
}; };
enum activeReticleType_t enum activeReticleType_t
@ -3352,13 +3350,13 @@ namespace IW5
int fireInterruptableTime; int fireInterruptableTime;
}; };
enum WeapOverlayInteface_t enum WeapOverlayInterface_t
{ {
WEAPOVERLAYINTERFACE_NONE = 0x0, WEAPOVERLAYINTERFACE_NONE = 0x0,
WEAPOVERLAYINTERFACE_JAVELIN = 0x1, WEAPOVERLAYINTERFACE_JAVELIN = 0x1,
WEAPOVERLAYINTERFACE_TURRETSCOPE = 0x2, WEAPOVERLAYINTERFACE_TURRETSCOPE = 0x2,
WEAPOVERLAYINTERFACECOUNT WEAPOVERLAYINTERFACE_COUNT
}; };
enum WeapStickinessType enum WeapStickinessType
@ -3383,7 +3381,7 @@ namespace IW5
MISSILE_GUIDANCE_COUNT MISSILE_GUIDANCE_COUNT
}; };
enum weapAnimFiles_t enum weapAnimFiles_t : unsigned int
{ {
WEAP_ANIM_ROOT = 0x0, WEAP_ANIM_ROOT = 0x0,
WEAP_ANIM_IDLE = 0x1, WEAP_ANIM_IDLE = 0x1,
@ -3428,7 +3426,7 @@ namespace IW5
WEAP_ANIM_ADS_DOWN = 0x28, WEAP_ANIM_ADS_DOWN = 0x28,
WEAP_ALT_ANIM_ADJUST = 0x29, WEAP_ALT_ANIM_ADJUST = 0x29,
NUM_WEAP_ANIMS WEAP_ANIM_COUNT
}; };
enum hitLocation_t enum hitLocation_t
@ -3457,6 +3455,43 @@ namespace IW5
HITLOC_NUM HITLOC_NUM
}; };
enum materialSurfType_t
{
SURF_TYPE_DEFAULT,
SURF_TYPE_BARK,
SURF_TYPE_BRICK,
SURF_TYPE_CARPET,
SURF_TYPE_CLOTH,
SURF_TYPE_CONCRETE,
SURF_TYPE_DIRT,
SURF_TYPE_FLESH,
SURF_TYPE_FOLIAGE,
SURF_TYPE_GLASS,
SURF_TYPE_GRASS,
SURF_TYPE_GRAVEL,
SURF_TYPE_ICE,
SURF_TYPE_METAL,
SURF_TYPE_MUD,
SURF_TYPE_PAPER,
SURF_TYPE_PLASTER,
SURF_TYPE_ROCK,
SURF_TYPE_SAND,
SURF_TYPE_SNOW,
SURF_TYPE_WATER,
SURF_TYPE_WOOD,
SURF_TYPE_ASPHALT,
SURF_TYPE_CERAMIC,
SURF_TYPE_PLASTIC,
SURF_TYPE_RUBBER,
SURF_TYPE_CUSHION,
SURF_TYPE_FRUIT,
SURF_TYPE_PAINTED_METAL,
SURF_TYPE_RIOT_SHIELD,
SURF_TYPE_SLUSH,
SURF_TYPE_COUNT
};
struct WeaponDef struct WeaponDef
{ {
const char* szOverlayName; const char* szOverlayName;
@ -3598,7 +3633,7 @@ namespace IW5
float fAdsZoomInFrac; float fAdsZoomInFrac;
float fAdsZoomOutFrac; float fAdsZoomOutFrac;
ADSOverlay overlay; ADSOverlay overlay;
WeapOverlayInteface_t overlayInterface; WeapOverlayInterface_t overlayInterface;
float fAdsBobFactor; float fAdsBobFactor;
float fAdsViewBobMult; float fAdsViewBobMult;
float fHipSpreadStandMin; float fHipSpreadStandMin;
@ -3858,45 +3893,86 @@ namespace IW5
XModel* stowOffsetModel; XModel* stowOffsetModel;
}; };
union WeaponAttachmentCombination
{
struct
{
// Specifies the index as a number
// since there can only be one scope
unsigned short scope : 3;
// Specifies the index as a number
// since there can only be one under barrel
unsigned short underBarrel : 2;
// Specifies all other attachments as a bit array
unsigned short other : 4;
};
unsigned short fields;
};
struct AnimOverrideEntry struct AnimOverrideEntry
{ {
unsigned short attachment1; WeaponAttachmentCombination attachment1;
unsigned short attachment2; WeaponAttachmentCombination attachment2;
const char* overrideAnim; const char* overrideAnim;
const char* altmodeAnim; const char* altmodeAnim;
unsigned int animTreeType; weapAnimFiles_t animTreeType;
int animTime; int animTime;
int altTime; int altTime;
}; };
enum SoundOverrideTypes : unsigned int
{
SNDTYPE_NONE = 0x0,
SNDTYPE_FIRE = 0x1,
SNDTYPE_PLAYER_FIRE = 0x2,
SNDTYPE_PLAYER_AKIMBO = 0x3,
SNDTYPE_PLAYER_LASTSHOT = 0x4,
SNDTYPE_PLAYER_COUNT
};
struct SoundOverrideEntry struct SoundOverrideEntry
{ {
unsigned short attachment1; WeaponAttachmentCombination attachment1;
unsigned short attachment2; WeaponAttachmentCombination attachment2;
SndAliasCustom overrideSound; SndAliasCustom overrideSound;
SndAliasCustom altmodeSound; SndAliasCustom altmodeSound;
unsigned int soundType; SoundOverrideTypes soundType;
};
enum FXOverrideTypes : unsigned int
{
FXTYPE_NONE = 0x0,
FXTYPE_VIEW_FLASH = 0x1,
FXTYPE_WORLD_FLASH = 0x2,
FXTYPE_VIEW_SHELL_EJECT = 0x3,
FXTYPE_WORLD_SHELL_EJECT = 0x4,
FXTYPE_COUNT
}; };
struct FXOverrideEntry struct FXOverrideEntry
{ {
unsigned short attachment1; WeaponAttachmentCombination attachment1;
unsigned short attachment2; WeaponAttachmentCombination attachment2;
FxEffectDef* overrideFX; FxEffectDef* overrideFX;
FxEffectDef* altmodeFX; FxEffectDef* altmodeFX;
unsigned int fxType; FXOverrideTypes fxType;
}; };
struct ReloadStateTimerEntry struct ReloadStateTimerEntry
{ {
int attachment; WeaponAttachmentCombination attachment;
short unused;
int reloadAddTime; int reloadAddTime;
int reloadStartAddTime; int reloadStartAddTime;
}; };
struct NoteTrackToSoundEntry struct NoteTrackToSoundEntry
{ {
int attachment; WeaponAttachmentCombination attachment;
short unused;
ScriptString* notetrackSoundMapKeys; ScriptString* notetrackSoundMapKeys;
ScriptString* notetrackSoundMapValues; ScriptString* notetrackSoundMapValues;
}; };
@ -3952,6 +4028,28 @@ namespace IW5
bool dpadIconShowsAmmo; bool dpadIconShowsAmmo;
}; };
struct WeaponFullDef
{
WeaponCompleteDef weapCompleteDef;
WeaponDef weapDef;
uint16_t hideTags[32];
const char* szXAnims[42];
XModel* gunXModel[16];
const char* szXAnimsRightHanded[42];
const char* szXAnimsLeftHanded[42];
uint16_t notetrackSoundMapKeys[24];
uint16_t notetrackSoundMapValues[24];
uint16_t notetrackRumbleMapKeys[16];
uint16_t notetrackRumbleMapValues[16];
XModel* worldModel[16];
float parallelBounce[31];
float perpendicularBounce[31];
float locationDamageMultipliers[20];
WeaponAttachment* scopes[6];
WeaponAttachment* underBarrels[3];
WeaponAttachment* others[4];
};
struct FxFloatRange struct FxFloatRange
{ {
float base; float base;
@ -4426,7 +4524,8 @@ namespace IW5
VEH_SNOWMOBILE = 0x6, VEH_SNOWMOBILE = 0x6,
VEH_SUBMARINE = 0x7, VEH_SUBMARINE = 0x7,
VEH_UGV = 0x8, VEH_UGV = 0x8,
VEH_TYPE_COUNT = 0x9
VEH_TYPE_COUNT
}; };
enum VehicleAxleType enum VehicleAxleType
@ -4434,7 +4533,8 @@ namespace IW5
VEH_AXLE_FRONT = 0x0, VEH_AXLE_FRONT = 0x0,
VEH_AXLE_REAR = 0x1, VEH_AXLE_REAR = 0x1,
VEH_AXLE_ALL = 0x2, VEH_AXLE_ALL = 0x2,
VEH_AXLE_COUNT = 0x3
VEH_AXLE_COUNT
}; };
enum VehCamZOffsetMode enum VehCamZOffsetMode

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,601 @@
#pragma once
#include "Game/IW5/IW5.h"
#include "Json/JsonCommon.h"
#include <memory>
#include <nlohmann/json.hpp>
#include <optional>
#include <string>
#include <vector>
namespace IW5
{
NLOHMANN_JSON_SERIALIZE_ENUM(PenetrateType,
{
{PENETRATE_TYPE_NONE, "none" },
{PENETRATE_TYPE_SMALL, "small" },
{PENETRATE_TYPE_MEDIUM, "medium"},
{PENETRATE_TYPE_LARGE, "large" },
});
NLOHMANN_JSON_SERIALIZE_ENUM(ImpactType,
{
{IMPACT_TYPE_NONE, "none" },
{IMPACT_TYPE_BULLET_SMALL, "bulletSmall" },
{IMPACT_TYPE_BULLET_LARGE, "bulletLarge" },
{IMPACT_TYPE_BULLET_AP, "bulletAp" },
{IMPACT_TYPE_BULLET_EXPLODE, "bulletExplode" },
{IMPACT_TYPE_SHOTGUN, "shotgun" },
{IMPACT_TYPE_SHOTGUN_EXPLODE, "shotgunExplode"},
{IMPACT_TYPE_GRENADE_BOUNCE, "grenadeBounce" },
{IMPACT_TYPE_GRENADE_EXPLODE, "grenadeExplode"},
{IMPACT_TYPE_ROCKET_EXPLODE, "rocketExplode" },
{IMPACT_TYPE_PROJECTILE_DUD, "projectileDud" },
});
NLOHMANN_JSON_SERIALIZE_ENUM(weapFireType_t,
{
{WEAPON_FIRETYPE_FULLAUTO, "fullauto" },
{WEAPON_FIRETYPE_SINGLESHOT, "singleshot" },
{WEAPON_FIRETYPE_BURSTFIRE2, "burstfire2" },
{WEAPON_FIRETYPE_BURSTFIRE3, "burstfire3" },
{WEAPON_FIRETYPE_BURSTFIRE4, "burstfire4" },
{WEAPON_FIRETYPE_DOUBLEBARREL, "doublebarrel"},
});
class JsonAttAmmoGeneral
{
public:
PenetrateType penetrateType;
float penetrateMultiplier;
ImpactType impactType;
weapFireType_t fireType;
std::optional<std::string> tracerType;
bool rifleBullet;
bool armorPiercing;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttAmmoGeneral, penetrateType, penetrateMultiplier, impactType, fireType, tracerType, rifleBullet, armorPiercing);
class JsonAttSight
{
public:
bool aimDownSight;
bool adsFire;
bool rechamberWhileAds;
bool noAdsWhenMagEmpty;
bool canHoldBreath;
bool canVariableZoom;
bool hideRailWithThisScope;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(
JsonAttSight, aimDownSight, adsFire, rechamberWhileAds, noAdsWhenMagEmpty, canHoldBreath, canVariableZoom, hideRailWithThisScope);
class JsonAttReload
{
public:
bool noPartialReload;
bool segmentedReload;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttReload, noPartialReload, segmentedReload);
class JsonAttAddOns
{
public:
bool motionTracker;
bool silenced;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttAddOns, motionTracker, silenced);
class JsonAttGeneral
{
public:
bool boltAction;
bool inheritsPerks;
float enemyCrosshairRange;
std::optional<std::string> reticleCenter;
std::optional<std::string> reticleSide;
int reticleCenterSize;
int reticleSideSize;
float moveSpeedScale;
float adsMoveSpeedScale;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttGeneral,
boltAction,
inheritsPerks,
enemyCrosshairRange,
reticleCenter,
reticleSide,
reticleCenterSize,
reticleSideSize,
moveSpeedScale,
adsMoveSpeedScale);
class JsonAttAimAssist
{
public:
float autoAimRange;
float aimAssistRange;
float aimAssistRangeAds;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttAimAssist, autoAimRange, aimAssistRange, aimAssistRangeAds);
class JsonAttAmmunition
{
public:
int maxAmmo;
int startAmmo;
int clipSize;
int shotCount;
int reloadAmmoAdd;
int reloadStartAdd;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttAmmunition, maxAmmo, startAmmo, clipSize, shotCount, reloadAmmoAdd, reloadStartAdd);
class JsonAttDamage
{
public:
int damage;
int minDamage;
int meleeDamage;
float maxDamageRange;
float minDamageRange;
int playerDamage;
int minPlayerDamage;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttDamage, damage, minDamage, meleeDamage, maxDamageRange, minDamageRange, playerDamage, minPlayerDamage);
class JsonAttLocationDamage
{
public:
float locNone;
float locHelmet;
float locHead;
float locNeck;
float locTorsoUpper;
float locTorsoLower;
float locRightArmUpper;
float locRightArmLower;
float locRightHand;
float locLeftArmUpper;
float locLeftArmLower;
float locLeftHand;
float locRightLegUpper;
float locRightLegLower;
float locRightFoot;
float locLeftLegUpper;
float locLeftLegLower;
float locLeftFoot;
float locGun;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttLocationDamage,
locNone,
locHelmet,
locHead,
locNeck,
locTorsoUpper,
locTorsoLower,
locRightArmUpper,
locRightArmLower,
locRightHand,
locLeftArmUpper,
locLeftArmLower,
locLeftHand,
locRightLegUpper,
locRightLegLower,
locRightFoot,
locLeftLegUpper,
locLeftLegLower,
locLeftFoot,
locGun);
class JsonAttIdleSettings
{
public:
float hipIdleAmount;
float hipIdleSpeed;
float idleCrouchFactor;
float idleProneFactor;
float adsIdleLerpStartTime;
float adsIdleLerpTime;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttIdleSettings, hipIdleAmount, hipIdleSpeed, idleCrouchFactor, idleProneFactor, adsIdleLerpStartTime, adsIdleLerpTime);
class JsonAttADSSettings
{
public:
float adsSpread;
float adsAimPitch;
float adsTransInTime;
float adsTransOutTime;
int adsReloadTransTime;
float adsCrosshairInFrac;
float adsCrosshairOutFrac;
float adsZoomFov;
float adsZoomInFrac;
float adsZoomOutFrac;
float adsBobFactor;
float adsViewBobMult;
float adsViewErrorMin;
float adsViewErrorMax;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttADSSettings,
adsSpread,
adsAimPitch,
adsTransInTime,
adsTransOutTime,
adsReloadTransTime,
adsCrosshairInFrac,
adsCrosshairOutFrac,
adsZoomFov,
adsZoomInFrac,
adsZoomOutFrac,
adsBobFactor,
adsViewBobMult,
adsViewErrorMin,
adsViewErrorMax);
class JsonAttHipSpread
{
public:
float hipSpreadStandMin;
float hipSpreadDuckedMin;
float hipSpreadProneMin;
float hipSpreadMax;
float hipSpreadDuckedMax;
float hipSpreadProneMax;
float hipSpreadFireAdd;
float hipSpreadTurnAdd;
float hipSpreadMoveAdd;
float hipSpreadDecayRate;
float hipSpreadDuckedDecay;
float hipSpreadProneDecay;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttHipSpread,
hipSpreadStandMin,
hipSpreadDuckedMin,
hipSpreadProneMin,
hipSpreadMax,
hipSpreadDuckedMax,
hipSpreadProneMax,
hipSpreadFireAdd,
hipSpreadTurnAdd,
hipSpreadMoveAdd,
hipSpreadDecayRate,
hipSpreadDuckedDecay,
hipSpreadProneDecay);
class JsonAttGunKick
{
public:
int hipGunKickReducedKickBullets;
float hipGunKickReducedKickPercent;
float hipGunKickPitchMin;
float hipGunKickPitchMax;
float hipGunKickYawMin;
float hipGunKickYawMax;
float hipGunKickAccel;
float hipGunKickSpeedMax;
float hipGunKickSpeedDecay;
float hipGunKickStaticDecay;
int adsGunKickReducedKickBullets;
float adsGunKickReducedKickPercent;
float adsGunKickPitchMin;
float adsGunKickPitchMax;
float adsGunKickYawMin;
float adsGunKickYawMax;
float adsGunKickAccel;
float adsGunKickSpeedMax;
float adsGunKickSpeedDecay;
float adsGunKickStaticDecay;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttGunKick,
hipGunKickReducedKickBullets,
hipGunKickReducedKickPercent,
hipGunKickPitchMin,
hipGunKickPitchMax,
hipGunKickYawMin,
hipGunKickYawMax,
hipGunKickAccel,
hipGunKickSpeedMax,
hipGunKickSpeedDecay,
hipGunKickStaticDecay,
adsGunKickReducedKickBullets,
adsGunKickReducedKickPercent,
adsGunKickPitchMin,
adsGunKickPitchMax,
adsGunKickYawMin,
adsGunKickYawMax,
adsGunKickAccel,
adsGunKickSpeedMax,
adsGunKickSpeedDecay,
adsGunKickStaticDecay);
class JsonAttViewKick
{
public:
float hipViewKickPitchMin;
float hipViewKickPitchMax;
float hipViewKickYawMin;
float hipViewKickYawMax;
float hipViewKickCenterSpeed;
float adsViewKickPitchMin;
float adsViewKickPitchMax;
float adsViewKickYawMin;
float adsViewKickYawMax;
float adsViewKickCenterSpeed;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttViewKick,
hipViewKickPitchMin,
hipViewKickPitchMax,
hipViewKickYawMin,
hipViewKickYawMax,
hipViewKickCenterSpeed,
adsViewKickPitchMin,
adsViewKickPitchMax,
adsViewKickYawMin,
adsViewKickYawMax,
adsViewKickCenterSpeed);
NLOHMANN_JSON_SERIALIZE_ENUM(weapOverlayReticle_t,
{
{WEAPOVERLAYRETICLE_NONE, "none" },
{WEAPOVERLAYRETICLE_CROSSHAIR, "crosshair"},
});
class JsonAttADSOverlay
{
public:
std::optional<std::string> shader;
std::optional<std::string> shaderLowRes;
std::optional<std::string> shaderEMP;
std::optional<std::string> shaderEMPLowRes;
weapOverlayReticle_t reticle;
float width;
float height;
float widthSplitscreen;
float heightSplitscreen;
bool thermalScope;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(
JsonAttADSOverlay, shader, shaderLowRes, shaderEMP, shaderEMPLowRes, reticle, width, height, widthSplitscreen, heightSplitscreen, thermalScope);
NLOHMANN_JSON_SERIALIZE_ENUM(weaponIconRatioType_t,
{
{WEAPON_ICON_RATIO_1TO1, "1:1"},
{WEAPON_ICON_RATIO_2TO1, "2:1"},
{WEAPON_ICON_RATIO_4TO1, "4:1"},
});
NLOHMANN_JSON_SERIALIZE_ENUM(ammoCounterClipType_t,
{
{AMMO_COUNTER_CLIP_NONE, "none" },
{AMMO_COUNTER_CLIP_MAGAZINE, "magazine" },
{AMMO_COUNTER_CLIP_SHORTMAGAZINE, "shortmagazine"},
{AMMO_COUNTER_CLIP_SHOTGUN, "shotgun" },
{AMMO_COUNTER_CLIP_ROCKET, "rocket" },
{AMMO_COUNTER_CLIP_BELTFED, "beltfed" },
{AMMO_COUNTER_CLIP_ALTWEAPON, "altweapon" },
});
class JsonAttUI
{
public:
std::optional<std::string> dpadIcon;
std::optional<std::string> ammoCounterIcon;
weaponIconRatioType_t dpadIconRatio;
weaponIconRatioType_t ammoCounterIconRatio;
ammoCounterClipType_t ammoCounterClip;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttUI, dpadIcon, ammoCounterIcon, dpadIconRatio, ammoCounterIconRatio, ammoCounterClip);
class JsonAttRumbles
{
public:
std::optional<std::string> fireRumble;
std::optional<std::string> meleeImpactRumble;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttRumbles, fireRumble, meleeImpactRumble);
NLOHMANN_JSON_SERIALIZE_ENUM(weapProjExposion_t,
{
{WEAPPROJEXP_GRENADE, "grenade" },
{WEAPPROJEXP_ROCKET, "rocket" },
{WEAPPROJEXP_FLASHBANG, "flashbang"},
{WEAPPROJEXP_NONE, "none" },
{WEAPPROJEXP_DUD, "dud" },
{WEAPPROJEXP_SMOKE, "smoke" },
{WEAPPROJEXP_HEAVY, "heavy" },
});
class JsonAttProjectile
{
public:
int explosionRadius;
int explosionInnerDamage;
int explosionOuterDamage;
float damageConeAngle;
int projectileSpeed;
int projectileSpeedUp;
int projectileActivateDist;
float projectileLifetime;
std::optional<std::string> projectileModel;
weapProjExposion_t projExplosionType;
std::optional<std::string> projExplosionEffect;
bool projExplosionEffectForceNormalUp;
std::optional<std::string> projExplosionSound;
std::optional<std::string> projDudEffect;
std::optional<std::string> projDudSound;
bool projImpactExplode;
float destabilizationRateTime;
float destabilizationCurvatureMax;
int destabilizeDistance;
std::optional<std::string> projTrailEffect;
int projIgnitionDelay;
std::optional<std::string> projIgnitionEffect;
std::optional<std::string> projIgnitionSound;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAttProjectile,
explosionRadius,
explosionInnerDamage,
explosionOuterDamage,
damageConeAngle,
projectileSpeed,
projectileSpeedUp,
projectileActivateDist,
projectileLifetime,
projectileModel,
projExplosionType,
projExplosionEffect,
projExplosionEffectForceNormalUp,
projExplosionSound,
projDudEffect,
projDudSound,
projImpactExplode,
destabilizationRateTime,
destabilizationCurvatureMax,
destabilizeDistance,
projTrailEffect,
projIgnitionDelay,
projIgnitionEffect,
projIgnitionSound);
NLOHMANN_JSON_SERIALIZE_ENUM(AttachmentType,
{
{ATTACHMENT_SCOPE, "scope" },
{ATTACHMENT_UNDERBARREL, "underbarrel"},
{ATTACHMENT_OTHER, "other" },
});
NLOHMANN_JSON_SERIALIZE_ENUM(weapType_t,
{
{WEAPTYPE_NONE, "none" },
{WEAPTYPE_BULLET, "bullet" },
{WEAPTYPE_GRENADE, "grenade" },
{WEAPTYPE_PROJECTILE, "projectile"},
{WEAPTYPE_RIOTSHIELD, "riotshield"},
});
NLOHMANN_JSON_SERIALIZE_ENUM(weapClass_t,
{
{WEAPCLASS_RIFLE, "rifle" },
{WEAPCLASS_SNIPER, "sniper" },
{WEAPCLASS_MG, "mg" },
{WEAPCLASS_SMG, "smg" },
{WEAPCLASS_SPREAD, "spread" },
{WEAPCLASS_PISTOL, "pistol" },
{WEAPCLASS_GRENADE, "grenade" },
{WEAPCLASS_ROCKETLAUNCHER, "rocketlauncher"},
{WEAPCLASS_TURRET, "turret" },
{WEAPCLASS_THROWINGKNIFE, "throwingknife" },
{WEAPCLASS_NON_PLAYER, "nonPlayer" },
{WEAPCLASS_ITEM, "item" },
});
class JsonWeaponAttachment
{
public:
std::string displayName;
AttachmentType type;
weapType_t weaponType;
weapClass_t weapClass;
std::vector<std::string> worldModels;
std::vector<std::string> viewModels;
std::vector<std::string> reticleViewModels;
std::optional<JsonAttAmmoGeneral> ammoGeneral;
std::optional<JsonAttSight> sight;
std::optional<JsonAttReload> reload;
std::optional<JsonAttAddOns> addOns;
std::optional<JsonAttGeneral> general;
std::optional<JsonAttAimAssist> aimAssist;
std::optional<JsonAttAmmunition> ammunition;
std::optional<JsonAttDamage> damage;
std::optional<JsonAttLocationDamage> locationDamage;
std::optional<JsonAttIdleSettings> idleSettings;
std::optional<JsonAttADSSettings> adsSettings;
std::optional<JsonAttADSSettings> adsSettingsMain;
std::optional<JsonAttHipSpread> hipSpread;
std::optional<JsonAttGunKick> gunKick;
std::optional<JsonAttViewKick> viewKick;
std::optional<JsonAttADSOverlay> adsOverlay;
std::optional<JsonAttUI> ui;
std::optional<JsonAttRumbles> rumbles;
std::optional<JsonAttProjectile> projectile;
float ammunitionScale;
float damageScale;
float damageScaleMin;
float stateTimersScale;
float fireTimersScale;
float idleSettingsScale;
float adsSettingsScale;
float adsSettingsScaleMain;
float hipSpreadScale;
float gunKickScale;
float viewKickScale;
float viewCenterScale;
int loadIndex;
bool hideIronSightsWithThisAttachment;
bool shareAmmoWithAlt;
};
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWeaponAttachment,
displayName,
type,
weaponType,
weapClass,
worldModels,
viewModels,
reticleViewModels,
ammoGeneral,
sight,
reload,
addOns,
general,
aimAssist,
ammunition,
damage,
locationDamage,
idleSettings,
adsSettings,
adsSettingsMain,
hipSpread,
gunKick,
viewKick,
adsOverlay,
ui,
rumbles,
projectile,
ammunitionScale,
damageScale,
damageScaleMin,
stateTimersScale,
fireTimersScale,
idleSettingsScale,
adsSettingsScale,
adsSettingsScaleMain,
hipSpreadScale,
gunKickScale,
viewKickScale,
viewCenterScale,
loadIndex,
hideIronSightsWithThisAttachment,
shareAmmoWithAlt);
} // namespace IW5

View File

@ -2,7 +2,7 @@
#include "Game/T6/T6.h" #include "Game/T6/T6.h"
#include "Json/JsonOptional.h" #include "Json/JsonExtension.h"
#include <memory> #include <memory>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <optional> #include <optional>
@ -44,7 +44,7 @@ namespace T6
GfxStencilFunc func; GfxStencilFunc func;
}; };
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonStencil, pass, fail, zfail, func); NLOHMANN_DEFINE_TYPE_EXTENSION(JsonStencil, pass, fail, zfail, func);
enum class JsonAlphaTest enum class JsonAlphaTest
{ {
@ -154,24 +154,24 @@ namespace T6
std::optional<JsonStencil> stencilBack; std::optional<JsonStencil> stencilBack;
}; };
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonStateBitsTableEntry, NLOHMANN_DEFINE_TYPE_EXTENSION(JsonStateBitsTableEntry,
srcBlendRgb, srcBlendRgb,
dstBlendRgb, dstBlendRgb,
blendOpRgb, blendOpRgb,
alphaTest, alphaTest,
cullFace, cullFace,
srcBlendAlpha, srcBlendAlpha,
dstBlendAlpha, dstBlendAlpha,
blendOpAlpha, blendOpAlpha,
colorWriteRgb, colorWriteRgb,
colorWriteAlpha, colorWriteAlpha,
polymodeLine, polymodeLine,
depthWrite, depthWrite,
depthWrite, depthWrite,
depthTest, depthTest,
polygonOffset, polygonOffset,
stencilFront, stencilFront,
stencilBack); stencilBack);
class JsonConstant class JsonConstant
{ {
@ -186,12 +186,12 @@ namespace T6
{ {
if (in.name.has_value()) if (in.name.has_value())
{ {
out["name"] = in.name; optional_to_json(out, "name", in.name);
} }
else else
{ {
out["nameFragment"] = in.nameFragment; optional_to_json(out, "nameFragment", in.nameFragment);
out["nameHash"] = in.nameHash; optional_to_json(out, "nameHash", in.nameHash);
} }
out["literal"] = in.literal; out["literal"] = in.literal;
@ -199,9 +199,9 @@ namespace T6
inline void from_json(const nlohmann::json& in, JsonConstant& out) inline void from_json(const nlohmann::json& in, JsonConstant& out)
{ {
in.value("name", nlohmann::json()).get_to(out.name); optional_from_json(in, "name", out.name);
in.value("nameFragment", nlohmann::json()).get_to(out.nameFragment); optional_from_json(in, "nameFragment", out.nameFragment);
in.value("nameHash", nlohmann::json()).get_to(out.nameHash); optional_from_json(in, "nameHash", out.nameHash);
in.at("literal").get_to(out.literal); in.at("literal").get_to(out.literal);
}; };
@ -232,7 +232,7 @@ namespace T6
bool clampW; bool clampW;
}; };
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonSamplerState, filter, mipMap, clampU, clampV, clampW); NLOHMANN_DEFINE_TYPE_EXTENSION(JsonSamplerState, filter, mipMap, clampU, clampV, clampW);
NLOHMANN_JSON_SERIALIZE_ENUM(TextureSemantic, NLOHMANN_JSON_SERIALIZE_ENUM(TextureSemantic,
{ {
@ -284,13 +284,13 @@ namespace T6
{ {
if (in.name.has_value()) if (in.name.has_value())
{ {
out["name"] = in.name; optional_to_json(out, "name", in.name);
} }
else else
{ {
out["nameHash"] = in.nameHash; optional_to_json(out, "nameHash", in.nameHash);
out["nameStart"] = in.nameStart; optional_to_json(out, "nameStart", in.nameStart);
out["nameEnd"] = in.nameEnd; optional_to_json(out, "nameEnd", in.nameEnd);
} }
out["semantic"] = in.semantic; out["semantic"] = in.semantic;
@ -301,10 +301,10 @@ namespace T6
inline void from_json(const nlohmann::json& in, JsonTexture& out) inline void from_json(const nlohmann::json& in, JsonTexture& out)
{ {
in.value("name", nlohmann::json()).get_to(out.name); optional_from_json(in, "name", out.name);
in.value("nameHash", nlohmann::json()).get_to(out.nameHash); optional_from_json(in, "nameHash", out.nameHash);
in.value("nameStart", nlohmann::json()).get_to(out.nameStart); optional_from_json(in, "nameStart", out.nameStart);
in.value("nameEnd", nlohmann::json()).get_to(out.nameEnd); optional_from_json(in, "nameEnd", out.nameEnd);
in.at("semantic").get_to(out.semantic); in.at("semantic").get_to(out.semantic);
in.at("isMatureContent").get_to(out.isMatureContent); in.at("isMatureContent").get_to(out.isMatureContent);
in.at("samplerState").get_to(out.samplerState); in.at("samplerState").get_to(out.samplerState);
@ -318,7 +318,7 @@ namespace T6
uint8_t columns; uint8_t columns;
}; };
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonTextureAtlas, rows, columns); NLOHMANN_DEFINE_TYPE_EXTENSION(JsonTextureAtlas, rows, columns);
NLOHMANN_JSON_SERIALIZE_ENUM(MaterialGameFlags, NLOHMANN_JSON_SERIALIZE_ENUM(MaterialGameFlags,
{ {
@ -376,22 +376,22 @@ namespace T6
std::optional<std::string> thermalMaterial; std::optional<std::string> thermalMaterial;
}; };
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonMaterial, NLOHMANN_DEFINE_TYPE_EXTENSION(JsonMaterial,
gameFlags, gameFlags,
sortKey, sortKey,
textureAtlas, textureAtlas,
surfaceTypeBits, surfaceTypeBits,
layeredSurfaceTypes, layeredSurfaceTypes,
hashIndex, hashIndex,
surfaceFlags, surfaceFlags,
contents, contents,
stateBitsEntry, stateBitsEntry,
stateFlags, stateFlags,
cameraRegion, cameraRegion,
probeMipBits, probeMipBits,
techniqueSet, techniqueSet,
textures, textures,
constants, constants,
stateBits, stateBits,
thermalMaterial); thermalMaterial);
} // namespace T6 } // namespace T6

View File

@ -3,7 +3,7 @@
#include "Game/T6/T6.h" #include "Game/T6/T6.h"
#include "Json/JsonCommon.h" #include "Json/JsonCommon.h"
#include "Json/JsonOptional.h" #include "Json/JsonExtension.h"
#include <memory> #include <memory>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <optional> #include <optional>
@ -21,7 +21,7 @@ namespace T6
float patternScale; float patternScale;
}; };
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonWeaponCamoSet, solidCamoImage, patternCamoImage, patternOffset, patternScale); NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWeaponCamoSet, solidCamoImage, patternCamoImage, patternOffset, patternScale);
class JsonWeaponCamoMaterialOverride class JsonWeaponCamoMaterialOverride
{ {
@ -30,7 +30,7 @@ namespace T6
std::string camoMaterial; std::string camoMaterial;
}; };
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonWeaponCamoMaterialOverride, baseMaterial, camoMaterial); NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWeaponCamoMaterialOverride, baseMaterial, camoMaterial);
constexpr auto SHADER_CONST_COUNT = 8; constexpr auto SHADER_CONST_COUNT = 8;
@ -46,7 +46,7 @@ namespace T6
static_assert(SHADER_CONST_COUNT == std::extent_v<decltype(WeaponCamoMaterial::shaderConsts)>); static_assert(SHADER_CONST_COUNT == std::extent_v<decltype(WeaponCamoMaterial::shaderConsts)>);
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonWeaponCamoMaterial, useColorMap, useNormalMap, useSpecularMap, materialOverrides, shaderConsts); NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWeaponCamoMaterial, useColorMap, useNormalMap, useSpecularMap, materialOverrides, shaderConsts);
class JsonWeaponCamoMaterialSet class JsonWeaponCamoMaterialSet
{ {
@ -54,7 +54,7 @@ namespace T6
std::vector<JsonWeaponCamoMaterial> materials; std::vector<JsonWeaponCamoMaterial> materials;
}; };
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonWeaponCamoMaterialSet, materials); NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWeaponCamoMaterialSet, materials);
class JsonWeaponCamo class JsonWeaponCamo
{ {
@ -65,5 +65,5 @@ namespace T6
std::vector<JsonWeaponCamoMaterialSet> camoMaterials; std::vector<JsonWeaponCamoMaterialSet> camoMaterials;
}; };
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonWeaponCamo, solidBaseImage, patternBaseImage, camoSets, camoMaterials); NLOHMANN_DEFINE_TYPE_EXTENSION(JsonWeaponCamo, solidBaseImage, patternBaseImage, camoSets, camoMaterials);
} // namespace T6 } // namespace T6

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "Json/JsonExtension.h"
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
class JsonVec2 class JsonVec2
@ -9,7 +10,7 @@ public:
float y; float y;
}; };
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonVec2, x, y); NLOHMANN_DEFINE_TYPE_EXTENSION(JsonVec2, x, y);
class JsonVec3 class JsonVec3
{ {
@ -19,7 +20,7 @@ public:
float z; float z;
}; };
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonVec3, x, y, z); NLOHMANN_DEFINE_TYPE_EXTENSION(JsonVec3, x, y, z);
class JsonVec4 class JsonVec4
{ {
@ -30,4 +31,4 @@ public:
float w; float w;
}; };
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(JsonVec4, x, y, z, w); NLOHMANN_DEFINE_TYPE_EXTENSION(JsonVec4, x, y, z, w);

View File

@ -0,0 +1,58 @@
#pragma once
// Credits to
// https://www.kdab.com/jsonify-with-nlohmann-json/
#include <nlohmann/json.hpp>
#include <optional>
// partial specialization (full specialization works too)
namespace nlohmann
{
template<class T> void optional_to_json(nlohmann::json& j, const char* name, const std::optional<T>& value)
{
if (value)
j[name] = *value;
}
template<class T> void optional_from_json(const nlohmann::json& j, const char* name, std::optional<T>& value)
{
const auto it = j.find(name);
if (it != j.end())
value = it->get<T>();
else
value = std::nullopt;
}
template<typename> constexpr bool is_optional = false;
template<typename T> constexpr bool is_optional<std::optional<T>> = true;
template<typename T> void extended_to_json(const char* key, nlohmann::json& j, const T& value)
{
if constexpr (is_optional<T>)
nlohmann::optional_to_json(j, key, value);
else
j[key] = value;
}
template<typename T> void extended_from_json(const char* key, const nlohmann::json& j, T& value)
{
if constexpr (is_optional<T>)
nlohmann::optional_from_json(j, key, value);
else
j.at(key).get_to(value);
}
} // namespace nlohmann
#define EXTEND_JSON_TO(v1) extended_to_json(#v1, nlohmann_json_j, nlohmann_json_t.v1);
#define EXTEND_JSON_FROM(v1) extended_from_json(#v1, nlohmann_json_j, nlohmann_json_t.v1);
#define NLOHMANN_DEFINE_TYPE_EXTENSION(Type, ...) \
inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) \
{ \
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(EXTEND_JSON_TO, __VA_ARGS__)) \
} \
inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) \
{ \
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(EXTEND_JSON_FROM, __VA_ARGS__)) \
}

View File

@ -1,37 +0,0 @@
#pragma once
#include <nlohmann/json.hpp>
#include <optional>
// partial specialization (full specialization works too)
namespace nlohmann
{
template<typename T> struct adl_serializer<std::optional<T>>
{
static void to_json(json& j, const std::optional<T>& opt)
{
if (!opt.has_value())
{
j = nullptr;
}
else
{
j = *opt; // this will call adl_serializer<T>::to_json which will
// find the free function to_json in T's namespace!
}
}
static void from_json(const json& j, std::optional<T>& opt)
{
if (j.is_null())
{
opt = std::nullopt;
}
else
{
opt = j.template get<T>(); // same as above, but with
// adl_serializer<T>::from_json
}
}
};
} // namespace nlohmann

View File

@ -0,0 +1,711 @@
#include "AssetDumperWeapon.h"
#include "Game/IW5/CommonIW5.h"
#include "Game/IW5/InfoString/InfoStringFromStructConverter.h"
#include "Game/IW5/InfoString/WeaponFields.h"
#include "Game/IW5/ObjConstantsIW5.h"
#include <bit>
#include <cassert>
#include <cstring>
#include <sstream>
#include <type_traits>
using namespace IW5;
namespace IW5
{
class InfoStringFromWeaponConverter final : public InfoStringFromStructConverter
{
public:
InfoStringFromWeaponConverter(const WeaponFullDef* structure,
const cspField_t* fields,
const size_t fieldCount,
std::function<std::string(scr_string_t)> scriptStringValueCallback)
: InfoStringFromStructConverter(structure, fields, fieldCount, std::move(scriptStringValueCallback)),
m_weapon(structure)
{
}
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_PER_SURFACE_TYPE_SOUND:
{
const auto* perSurfaceTypeSound = *reinterpret_cast<SndAliasCustom**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
if (perSurfaceTypeSound && perSurfaceTypeSound->name)
{
const std::string firstBounceSound(perSurfaceTypeSound->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_PICKUP:
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(WeaponFullDef::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(WeaponFullDef::notetrackSoundMapKeys)>];
std::stringstream ss;
bool first = true;
for (auto i = 0u; i < std::extent_v<decltype(WeaponFullDef::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_NOTETRACKRUMBLEMAP:
{
const auto* keys = reinterpret_cast<scr_string_t*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
const auto* values = &keys[std::extent_v<decltype(WeaponFullDef::notetrackRumbleMapKeys)>];
std::stringstream ss;
bool first = true;
for (auto i = 0u; i < std::extent_v<decltype(WeaponFullDef::notetrackRumbleMapKeys)>; 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_ATTACHMENT:
FillFromAttachments(std::string(field.szName));
break;
case WFT_ANIM_OVERRIDES:
FillFromAnimOverrides(std::string(field.szName));
break;
case WFT_SOUND_OVERRIDES:
FillFromSoundOverrides(std::string(field.szName));
break;
case WFT_FX_OVERRIDES:
FillFromFxOverrides(std::string(field.szName));
break;
case WFT_RELOAD_OVERRIDES:
FillFromReloadOverrides(std::string(field.szName));
break;
case WFT_NOTETRACK_OVERRIDES:
FillFromNoteTrackOverrides(std::string(field.szName));
break;
case WFT_NUM_FIELD_TYPES:
default:
assert(false);
break;
}
}
private:
void FillFromAttachments(const std::string& key)
{
std::stringstream ss;
bool first = true;
for (const auto& scope : m_weapon->scopes)
{
if (scope && scope->szInternalName)
{
if (!first)
ss << "\n";
else
first = false;
ss << scope->szInternalName;
}
}
for (const auto& underBarrel : m_weapon->underBarrels)
{
if (underBarrel && underBarrel->szInternalName)
{
if (!first)
ss << "\n";
else
first = false;
ss << underBarrel->szInternalName;
}
}
for (const auto& other : m_weapon->others)
{
if (other && other->szInternalName)
{
if (!first)
ss << "\n";
else
first = false;
ss << other->szInternalName;
}
}
m_info_string.SetValueForKey(key, ss.str());
}
[[nodiscard]] std::string GetNameForSingleWeaponAttachment(const WeaponAttachmentCombination& combination) const
{
// Only one attachment type can be set
assert(combination.scope == 0 || (combination.underBarrel == 0 && combination.other == 0));
assert(combination.underBarrel == 0 || (combination.scope == 0 && combination.other == 0));
assert(combination.other == 0 || (combination.scope == 0 && std::popcount(combination.other) == 1));
if (combination.scope > 0 && m_weapon->weapCompleteDef.scopes)
{
const auto attachment = m_weapon->weapCompleteDef.scopes[combination.scope - 1];
if (attachment && attachment->szInternalName)
return attachment->szInternalName;
}
else if (combination.underBarrel > 0 && m_weapon->weapCompleteDef.underBarrels)
{
const auto attachment = m_weapon->weapCompleteDef.underBarrels[combination.underBarrel - 1];
if (attachment && attachment->szInternalName)
return attachment->szInternalName;
}
else if (combination.other > 0 && m_weapon->weapCompleteDef.others)
{
const auto attachment = m_weapon->weapCompleteDef.others[std::countr_zero(combination.other)];
if (attachment && attachment->szInternalName)
return attachment->szInternalName;
}
return {};
}
void FillFromAnimOverrides(const std::string& key)
{
std::stringstream ss;
bool first = true;
for (auto i = 0u; i < m_weapon->weapCompleteDef.numAnimOverrides; i++)
{
const auto& animOverride = m_weapon->weapCompleteDef.animOverrides[i];
if (!first)
ss << "\n";
else
first = false;
assert(animOverride.attachment1.fields);
assert(animOverride.animTreeType < WEAP_ANIM_COUNT);
if (animOverride.attachment1.fields)
ss << GetNameForSingleWeaponAttachment(animOverride.attachment1);
else
ss << "none";
ss << ' ';
if (animOverride.attachment2.fields)
ss << GetNameForSingleWeaponAttachment(animOverride.attachment2);
else
ss << "none";
ss << ' ';
if (animOverride.animTreeType < WEAP_ANIM_COUNT)
ss << weapAnimFilesNames[animOverride.animTreeType] << ' ';
if (animOverride.overrideAnim && animOverride.overrideAnim[0])
ss << animOverride.overrideAnim;
else
ss << "none";
ss << ' ';
if (animOverride.altmodeAnim && animOverride.altmodeAnim[0])
ss << animOverride.altmodeAnim;
else
ss << "none";
ss << ' ' << animOverride.animTime << ' ' << animOverride.altTime;
}
m_info_string.SetValueForKey(key, ss.str());
}
void FillFromSoundOverrides(const std::string& key)
{
std::stringstream ss;
bool first = true;
for (auto i = 0u; i < m_weapon->weapCompleteDef.numSoundOverrides; i++)
{
const auto& soundOverride = m_weapon->weapCompleteDef.soundOverrides[i];
if (!first)
ss << "\n";
else
first = false;
assert(soundOverride.soundType < SNDTYPE_PLAYER_COUNT);
if (soundOverride.attachment1.fields)
ss << GetNameForSingleWeaponAttachment(soundOverride.attachment1);
else
ss << "none";
ss << ' ';
if (soundOverride.attachment2.fields)
ss << GetNameForSingleWeaponAttachment(soundOverride.attachment2);
else
ss << "none";
ss << ' ';
if (soundOverride.soundType < SNDTYPE_PLAYER_COUNT)
ss << soundOverrideTypeNames[soundOverride.soundType] << ' ';
if (soundOverride.overrideSound.name && soundOverride.overrideSound.name->soundName && soundOverride.overrideSound.name->soundName[0])
ss << soundOverride.overrideSound.name->soundName;
else
ss << "none";
ss << ' ';
if (soundOverride.altmodeSound.name && soundOverride.altmodeSound.name->soundName && soundOverride.altmodeSound.name->soundName[0])
ss << soundOverride.altmodeSound.name->soundName;
else
ss << "none";
}
m_info_string.SetValueForKey(key, ss.str());
}
void FillFromFxOverrides(const std::string& key)
{
std::stringstream ss;
bool first = true;
for (auto i = 0u; i < m_weapon->weapCompleteDef.numFXOverrides; i++)
{
const auto& fxOverride = m_weapon->weapCompleteDef.fxOverrides[i];
if (!first)
ss << "\n";
else
first = false;
assert(fxOverride.fxType < FXTYPE_COUNT);
if (fxOverride.attachment1.fields)
ss << GetNameForSingleWeaponAttachment(fxOverride.attachment1);
else
ss << "none";
ss << ' ';
if (fxOverride.attachment2.fields)
ss << GetNameForSingleWeaponAttachment(fxOverride.attachment2);
else
ss << "none";
ss << ' ';
if (fxOverride.fxType < FXTYPE_COUNT)
ss << fxOverrideTypeNames[fxOverride.fxType] << ' ';
if (fxOverride.overrideFX && fxOverride.overrideFX->name && fxOverride.overrideFX->name[0])
ss << fxOverride.overrideFX->name;
else
ss << "none";
ss << ' ';
if (fxOverride.altmodeFX && fxOverride.altmodeFX->name && fxOverride.altmodeFX->name[0])
ss << fxOverride.altmodeFX->name;
else
ss << "none";
}
m_info_string.SetValueForKey(key, ss.str());
}
void FillFromReloadOverrides(const std::string& key)
{
std::stringstream ss;
bool first = true;
for (auto i = 0u; i < m_weapon->weapCompleteDef.numReloadStateTimerOverrides; i++)
{
const auto& reloadOverride = m_weapon->weapCompleteDef.reloadOverrides[i];
if (!first)
ss << "\n";
else
first = false;
if (reloadOverride.attachment.fields)
ss << GetNameForSingleWeaponAttachment(reloadOverride.attachment);
else
ss << "none";
ss << ' ' << reloadOverride.reloadAddTime << ' ' << reloadOverride.reloadStartAddTime;
}
m_info_string.SetValueForKey(key, ss.str());
}
void FillFromNoteTrackOverrides(const std::string& key)
{
std::stringstream ss;
bool first = true;
for (auto i = 0u; i < m_weapon->weapCompleteDef.numNotetrackOverrides; i++)
{
const auto& noteTrackOverrides = m_weapon->weapCompleteDef.notetrackOverrides[i];
assert(noteTrackOverrides.notetrackSoundMapKeys || noteTrackOverrides.notetrackSoundMapValues);
if (!noteTrackOverrides.notetrackSoundMapKeys || !noteTrackOverrides.notetrackSoundMapValues)
continue;
const auto attachmentName = noteTrackOverrides.attachment.fields ? GetNameForSingleWeaponAttachment(noteTrackOverrides.attachment) : "none";
for (auto j = 0u; j < 24u; j++)
{
const auto& noteTrackKey = m_get_scr_string(noteTrackOverrides.notetrackSoundMapKeys[j]);
const auto& noteTrackValue = m_get_scr_string(noteTrackOverrides.notetrackSoundMapValues[j]);
if (noteTrackKey.empty() || noteTrackValue.empty())
continue;
if (!first)
ss << "\n";
else
first = false;
ss << attachmentName << ' ' << noteTrackKey << ' ' << noteTrackValue;
}
}
m_info_string.SetValueForKey(key, ss.str());
}
const WeaponFullDef* m_weapon;
};
} // namespace IW5
void AssetDumperWeapon::CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFullDef* fullDef)
{
fullDef->weapCompleteDef = *weapon;
if (weapon->weapDef)
{
fullDef->weapDef = *weapon->weapDef;
fullDef->weapCompleteDef.weapDef = &fullDef->weapDef;
}
if (weapon->hideTags)
{
memcpy(fullDef->hideTags, weapon->hideTags, sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::hideTags)>);
fullDef->weapCompleteDef.hideTags = fullDef->hideTags;
}
if (weapon->szXAnims)
{
static_assert(std::extent_v<decltype(WeaponFullDef::szXAnims)> == WEAP_ANIM_COUNT);
memcpy(fullDef->szXAnims, weapon->szXAnims, sizeof(void*) * WEAP_ANIM_COUNT);
fullDef->weapCompleteDef.szXAnims = fullDef->szXAnims;
}
if (fullDef->weapDef.gunXModel)
{
memcpy(fullDef->gunXModel, fullDef->weapDef.gunXModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::gunXModel)>);
fullDef->weapDef.gunXModel = fullDef->gunXModel;
}
if (fullDef->weapDef.szXAnimsRightHanded)
{
static_assert(std::extent_v<decltype(WeaponFullDef::szXAnimsRightHanded)> == WEAP_ANIM_COUNT);
memcpy(fullDef->szXAnimsRightHanded, fullDef->weapDef.szXAnimsRightHanded, sizeof(void*) * WEAP_ANIM_COUNT);
fullDef->weapDef.szXAnimsRightHanded = fullDef->szXAnimsRightHanded;
}
if (fullDef->weapDef.szXAnimsLeftHanded)
{
static_assert(std::extent_v<decltype(WeaponFullDef::szXAnimsLeftHanded)> == WEAP_ANIM_COUNT);
memcpy(fullDef->szXAnimsLeftHanded, fullDef->weapDef.szXAnimsLeftHanded, sizeof(void*) * WEAP_ANIM_COUNT);
fullDef->weapDef.szXAnimsLeftHanded = fullDef->szXAnimsLeftHanded;
}
if (fullDef->weapDef.notetrackSoundMapKeys)
{
memcpy(fullDef->notetrackSoundMapKeys,
fullDef->weapDef.notetrackSoundMapKeys,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapKeys)>);
fullDef->weapDef.notetrackSoundMapKeys = fullDef->notetrackSoundMapKeys;
}
if (fullDef->weapDef.notetrackSoundMapValues)
{
memcpy(fullDef->notetrackSoundMapValues,
fullDef->weapDef.notetrackSoundMapValues,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackSoundMapValues)>);
fullDef->weapDef.notetrackSoundMapValues = fullDef->notetrackSoundMapValues;
}
if (fullDef->weapDef.notetrackRumbleMapKeys)
{
memcpy(fullDef->notetrackRumbleMapKeys,
fullDef->weapDef.notetrackRumbleMapKeys,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackRumbleMapKeys)>);
fullDef->weapDef.notetrackRumbleMapKeys = fullDef->notetrackRumbleMapKeys;
}
if (fullDef->weapDef.notetrackRumbleMapValues)
{
memcpy(fullDef->notetrackRumbleMapValues,
fullDef->weapDef.notetrackRumbleMapValues,
sizeof(scr_string_t) * std::extent_v<decltype(WeaponFullDef::notetrackRumbleMapValues)>);
fullDef->weapDef.notetrackRumbleMapValues = fullDef->notetrackRumbleMapValues;
}
if (fullDef->weapDef.worldModel)
{
memcpy(fullDef->worldModel, fullDef->weapDef.worldModel, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::worldModel)>);
fullDef->weapDef.worldModel = fullDef->worldModel;
}
if (fullDef->weapDef.parallelBounce)
{
static_assert(std::extent_v<decltype(WeaponFullDef::parallelBounce)> == SURF_TYPE_COUNT);
assert(sizeof(WeaponFullDef::parallelBounce) >= sizeof(float) * std::extent_v<decltype(WeaponFullDef::parallelBounce)>);
memcpy(fullDef->parallelBounce, fullDef->weapDef.parallelBounce, sizeof(float) * std::extent_v<decltype(WeaponFullDef::parallelBounce)>);
fullDef->weapDef.parallelBounce = fullDef->parallelBounce;
}
if (fullDef->weapDef.perpendicularBounce)
{
static_assert(std::extent_v<decltype(WeaponFullDef::perpendicularBounce)> == SURF_TYPE_COUNT);
assert(sizeof(WeaponFullDef::perpendicularBounce) >= sizeof(float) * std::extent_v<decltype(WeaponFullDef::perpendicularBounce)>);
memcpy(fullDef->perpendicularBounce, fullDef->weapDef.perpendicularBounce, sizeof(float) * std::extent_v<decltype(WeaponFullDef::perpendicularBounce)>);
fullDef->weapDef.perpendicularBounce = fullDef->perpendicularBounce;
}
if (fullDef->weapDef.locationDamageMultipliers)
{
static_assert(std::extent_v<decltype(WeaponFullDef::locationDamageMultipliers)> == HITLOC_NUM);
assert(sizeof(WeaponFullDef::locationDamageMultipliers) >= sizeof(float) * std::extent_v<decltype(WeaponFullDef::locationDamageMultipliers)>);
memcpy(fullDef->locationDamageMultipliers,
fullDef->weapDef.locationDamageMultipliers,
sizeof(float) * std::extent_v<decltype(WeaponFullDef::locationDamageMultipliers)>);
fullDef->weapDef.locationDamageMultipliers = fullDef->locationDamageMultipliers;
}
if (fullDef->weapCompleteDef.scopes)
{
memcpy(fullDef->scopes, fullDef->weapCompleteDef.scopes, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::scopes)>);
fullDef->weapCompleteDef.scopes = fullDef->scopes;
}
if (fullDef->weapCompleteDef.underBarrels)
{
memcpy(fullDef->underBarrels, fullDef->weapCompleteDef.underBarrels, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::underBarrels)>);
fullDef->weapCompleteDef.underBarrels = fullDef->underBarrels;
}
if (fullDef->weapCompleteDef.others)
{
memcpy(fullDef->others, fullDef->weapCompleteDef.others, sizeof(void*) * std::extent_v<decltype(WeaponFullDef::others)>);
fullDef->weapCompleteDef.others = fullDef->others;
}
}
InfoString AssetDumperWeapon::CreateInfoString(XAssetInfo<WeaponCompleteDef>* asset)
{
const auto fullDef = std::make_unique<WeaponFullDef>();
memset(fullDef.get(), 0, sizeof(WeaponFullDef));
CopyToFullDef(asset->Asset(), fullDef.get());
InfoStringFromWeaponConverter converter(fullDef.get(),
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();
}
bool AssetDumperWeapon::ShouldDump(XAssetInfo<WeaponCompleteDef>* asset)
{
return true;
}
void AssetDumperWeapon::DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponCompleteDef>* asset)
{
// Only dump raw when no gdt available
if (context.m_gdt)
{
const auto infoString = CreateInfoString(asset);
GdtEntry gdtEntry(asset->m_name, ObjConstants::GDF_FILENAME_WEAPON);
infoString.ToGdtProperties(ObjConstants::INFO_STRING_PREFIX_WEAPON, gdtEntry);
context.m_gdt->WriteEntry(gdtEntry);
}
else
{
const auto assetFile = context.OpenAssetFile("weapons/" + asset->m_name);
if (!assetFile)
return;
auto& stream = *assetFile;
const auto infoString = CreateInfoString(asset);
const auto stringValue = infoString.ToString(ObjConstants::INFO_STRING_PREFIX_WEAPON);
stream.write(stringValue.c_str(), stringValue.size());
}
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
#include "InfoString/InfoString.h"
namespace IW5
{
class AssetDumperWeapon final : public AbstractAssetDumper<WeaponCompleteDef>
{
static void CopyToFullDef(const WeaponCompleteDef* weapon, WeaponFullDef* fullDef);
static InfoString CreateInfoString(XAssetInfo<WeaponCompleteDef>* asset);
protected:
bool ShouldDump(XAssetInfo<WeaponCompleteDef>* asset) override;
void DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponCompleteDef>* asset) override;
};
} // namespace IW5

View File

@ -0,0 +1,22 @@
#include "AssetDumperWeaponAttachment.h"
#include "Game/IW5/Weapon/JsonWeaponAttachmentWriter.h"
#include <format>
using namespace IW5;
bool AssetDumperWeaponAttachment::ShouldDump(XAssetInfo<WeaponAttachment>* asset)
{
return true;
}
void AssetDumperWeaponAttachment::DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponAttachment>* asset)
{
const auto assetFile = context.OpenAssetFile(std::format("attachment/{}.json", asset->m_name));
if (!assetFile)
return;
DumpWeaponAttachmentAsJson(*assetFile, asset->Asset(), context);
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/IW5/IW5.h"
namespace IW5
{
class AssetDumperWeaponAttachment final : public AbstractAssetDumper<WeaponAttachment>
{
protected:
bool ShouldDump(XAssetInfo<WeaponAttachment>* asset) override;
void DumpAsset(AssetDumpingContext& context, XAssetInfo<WeaponAttachment>* asset) override;
};
} // namespace IW5

View File

@ -84,6 +84,17 @@ void InfoStringFromStructConverter::FillFromBaseField(const cspField_t& field)
break; break;
} }
case CSPFT_PHYS_COLLMAP:
{
const auto* physCollMap = *reinterpret_cast<PhysCollmap**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
if (physCollMap)
m_info_string.SetValueForKey(std::string(field.szName), std::string(AssetName(physCollMap->name)));
else
m_info_string.SetValueForKey(std::string(field.szName), "");
break;
}
case CSPFT_SOUND: case CSPFT_SOUND:
{ {
const auto* sndAlias = reinterpret_cast<SndAliasCustom*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset); const auto* sndAlias = reinterpret_cast<SndAliasCustom*>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
@ -106,6 +117,10 @@ void InfoStringFromStructConverter::FillFromBaseField(const cspField_t& field)
break; break;
} }
case CSPFT_SCRIPT_STRING:
FillFromScriptString(std::string(field.szName), field.iOffset);
break;
case CSPFT_NUM_BASE_FIELD_TYPES: case CSPFT_NUM_BASE_FIELD_TYPES:
default: default:
assert(false); assert(false);

View File

@ -0,0 +1,401 @@
#include "JsonWeaponAttachmentWriter.h"
#include "Game/IW5/CommonIW5.h"
#include "Game/IW5/Weapon/JsonWeaponAttachment.h"
#include <iomanip>
#include <nlohmann/json.hpp>
using namespace nlohmann;
using namespace IW5;
namespace
{
class JsonDumper
{
public:
JsonDumper(AssetDumpingContext& context, std::ostream& stream)
: m_stream(stream)
{
}
void Dump(const WeaponAttachment* attachment) const
{
JsonWeaponAttachment jsonWeaponAttachment;
CreateJsonAttachment(jsonWeaponAttachment, *attachment);
json jRoot = jsonWeaponAttachment;
jRoot["_type"] = "attachment";
jRoot["_version"] = 1;
m_stream << std::setw(4) << jRoot << "\n";
}
private:
static const char* AssetName(const char* input)
{
if (input && input[0] == ',')
return &input[1];
return input;
}
static void CreateJsonAttachment(JsonWeaponAttachment& jAttachment, const WeaponAttachment& attachment)
{
#define CONVERT_XMODEL_ARRAY(propertyName, count) \
if (attachment.propertyName) \
{ \
for (auto i = 0u; i < (count); i++) \
{ \
const auto* model = attachment.propertyName[i]; \
if (model && model->name) \
jAttachment.propertyName.emplace_back(AssetName(model->name)); \
} \
}
#define CONVERT_ATTRIBUTE(attributeJsonClass, attributeName) \
if (attachment.attributeName) \
{ \
attributeJsonClass attribute; \
Convert##attributeJsonClass(attribute, *attachment.attributeName); \
jAttachment.attributeName = std::move(attribute); \
}
if (attachment.szDisplayName)
jAttachment.displayName = attachment.szDisplayName;
jAttachment.type = attachment.type;
jAttachment.weaponType = attachment.weaponType;
jAttachment.weapClass = attachment.weapClass;
CONVERT_XMODEL_ARRAY(worldModels, 16u)
CONVERT_XMODEL_ARRAY(viewModels, 16u)
CONVERT_XMODEL_ARRAY(reticleViewModels, 8u)
CONVERT_ATTRIBUTE(JsonAttAmmoGeneral, ammoGeneral)
CONVERT_ATTRIBUTE(JsonAttSight, sight)
CONVERT_ATTRIBUTE(JsonAttReload, reload)
CONVERT_ATTRIBUTE(JsonAttAddOns, addOns)
CONVERT_ATTRIBUTE(JsonAttGeneral, general)
CONVERT_ATTRIBUTE(JsonAttAimAssist, aimAssist)
CONVERT_ATTRIBUTE(JsonAttAmmunition, ammunition)
CONVERT_ATTRIBUTE(JsonAttDamage, damage)
CONVERT_ATTRIBUTE(JsonAttLocationDamage, locationDamage)
CONVERT_ATTRIBUTE(JsonAttIdleSettings, idleSettings)
CONVERT_ATTRIBUTE(JsonAttADSSettings, adsSettings)
CONVERT_ATTRIBUTE(JsonAttADSSettings, adsSettingsMain)
CONVERT_ATTRIBUTE(JsonAttHipSpread, hipSpread)
CONVERT_ATTRIBUTE(JsonAttGunKick, gunKick)
CONVERT_ATTRIBUTE(JsonAttViewKick, viewKick)
CONVERT_ATTRIBUTE(JsonAttADSOverlay, adsOverlay)
CONVERT_ATTRIBUTE(JsonAttUI, ui)
CONVERT_ATTRIBUTE(JsonAttRumbles, rumbles)
CONVERT_ATTRIBUTE(JsonAttProjectile, projectile)
jAttachment.ammunitionScale = attachment.ammunitionScale;
jAttachment.damageScale = attachment.damageScale;
jAttachment.damageScaleMin = attachment.damageScaleMin;
jAttachment.stateTimersScale = attachment.stateTimersScale;
jAttachment.fireTimersScale = attachment.fireTimersScale;
jAttachment.idleSettingsScale = attachment.idleSettingsScale;
jAttachment.adsSettingsScale = attachment.adsSettingsScale;
jAttachment.adsSettingsScaleMain = attachment.adsSettingsScaleMain;
jAttachment.hipSpreadScale = attachment.hipSpreadScale;
jAttachment.gunKickScale = attachment.gunKickScale;
jAttachment.viewKickScale = attachment.viewKickScale;
jAttachment.viewCenterScale = attachment.viewCenterScale;
jAttachment.loadIndex = attachment.loadIndex;
jAttachment.hideIronSightsWithThisAttachment = attachment.hideIronSightsWithThisAttachment;
jAttachment.shareAmmoWithAlt = attachment.shareAmmoWithAlt;
}
static void ConvertJsonAttAmmoGeneral(JsonAttAmmoGeneral& jAmmoGeneral, const AttAmmoGeneral& ammoGeneral)
{
jAmmoGeneral.penetrateType = ammoGeneral.penetrateType;
jAmmoGeneral.penetrateMultiplier = ammoGeneral.penetrateMultiplier;
jAmmoGeneral.impactType = ammoGeneral.impactType;
jAmmoGeneral.fireType = ammoGeneral.fireType;
if (ammoGeneral.tracerType && ammoGeneral.tracerType->name)
jAmmoGeneral.tracerType = AssetName(ammoGeneral.tracerType->name);
jAmmoGeneral.rifleBullet = ammoGeneral.rifleBullet;
jAmmoGeneral.armorPiercing = ammoGeneral.armorPiercing;
}
static void ConvertJsonAttSight(JsonAttSight& jSight, const AttSight& sight)
{
jSight.aimDownSight = sight.aimDownSight;
jSight.adsFire = sight.adsFire;
jSight.rechamberWhileAds = sight.rechamberWhileAds;
jSight.noAdsWhenMagEmpty = sight.noAdsWhenMagEmpty;
jSight.canHoldBreath = sight.canHoldBreath;
jSight.canVariableZoom = sight.canVariableZoom;
jSight.hideRailWithThisScope = sight.hideRailWithThisScope;
}
static void ConvertJsonAttReload(JsonAttReload& jAttReload, const AttReload& reload)
{
jAttReload.noPartialReload = reload.noPartialReload;
jAttReload.segmentedReload = reload.segmentedReload;
}
static void ConvertJsonAttAddOns(JsonAttAddOns& jAddOns, const AttAddOns& addOns)
{
jAddOns.motionTracker = addOns.motionTracker;
jAddOns.silenced = addOns.silenced;
}
static void ConvertJsonAttGeneral(JsonAttGeneral& jGeneral, const AttGeneral& general)
{
jGeneral.boltAction = general.boltAction;
jGeneral.inheritsPerks = general.inheritsPerks;
jGeneral.enemyCrosshairRange = general.enemyCrosshairRange;
if (general.reticleCenter && general.reticleCenter->info.name)
jGeneral.reticleCenter = AssetName(general.reticleCenter->info.name);
if (general.reticleSide && general.reticleSide->info.name)
jGeneral.reticleSide = AssetName(general.reticleSide->info.name);
jGeneral.reticleCenterSize = general.reticleCenterSize;
jGeneral.reticleSideSize = general.reticleSideSize;
jGeneral.moveSpeedScale = general.moveSpeedScale;
jGeneral.adsMoveSpeedScale = general.adsMoveSpeedScale;
}
static void ConvertJsonAttAimAssist(JsonAttAimAssist& jAimAssist, const AttAimAssist& aimAssist)
{
jAimAssist.autoAimRange = aimAssist.autoAimRange;
jAimAssist.aimAssistRange = aimAssist.aimAssistRange;
jAimAssist.aimAssistRangeAds = aimAssist.aimAssistRangeAds;
}
static void ConvertJsonAttAmmunition(JsonAttAmmunition& jAmmunition, const AttAmmunition& ammunition)
{
jAmmunition.maxAmmo = ammunition.maxAmmo;
jAmmunition.startAmmo = ammunition.startAmmo;
jAmmunition.clipSize = ammunition.clipSize;
jAmmunition.shotCount = ammunition.shotCount;
jAmmunition.reloadAmmoAdd = ammunition.reloadAmmoAdd;
jAmmunition.reloadStartAdd = ammunition.reloadStartAdd;
}
static void ConvertJsonAttDamage(JsonAttDamage& jDamage, const AttDamage& damage)
{
jDamage.damage = damage.damage;
jDamage.minDamage = damage.minDamage;
jDamage.meleeDamage = damage.meleeDamage;
jDamage.maxDamageRange = damage.maxDamageRange;
jDamage.minDamageRange = damage.minDamageRange;
jDamage.playerDamage = damage.playerDamage;
jDamage.minPlayerDamage = damage.minPlayerDamage;
}
static void ConvertJsonAttLocationDamage(JsonAttLocationDamage& jLocationDamage, const AttLocationDamage& locationDamage)
{
jLocationDamage.locNone = locationDamage.locNone;
jLocationDamage.locHelmet = locationDamage.locHelmet;
jLocationDamage.locHead = locationDamage.locHead;
jLocationDamage.locNeck = locationDamage.locNeck;
jLocationDamage.locTorsoUpper = locationDamage.locTorsoUpper;
jLocationDamage.locTorsoLower = locationDamage.locTorsoLower;
jLocationDamage.locRightArmUpper = locationDamage.locRightArmUpper;
jLocationDamage.locRightArmLower = locationDamage.locRightArmLower;
jLocationDamage.locRightHand = locationDamage.locRightHand;
jLocationDamage.locLeftArmUpper = locationDamage.locLeftArmUpper;
jLocationDamage.locLeftArmLower = locationDamage.locLeftArmLower;
jLocationDamage.locLeftHand = locationDamage.locLeftHand;
jLocationDamage.locRightLegUpper = locationDamage.locRightLegUpper;
jLocationDamage.locRightLegLower = locationDamage.locRightLegLower;
jLocationDamage.locRightFoot = locationDamage.locRightFoot;
jLocationDamage.locLeftLegUpper = locationDamage.locLeftLegUpper;
jLocationDamage.locLeftLegLower = locationDamage.locLeftLegLower;
jLocationDamage.locLeftFoot = locationDamage.locLeftFoot;
jLocationDamage.locGun = locationDamage.locGun;
}
static void ConvertJsonAttIdleSettings(JsonAttIdleSettings& jIdleSettings, const AttIdleSettings& idleSettings)
{
jIdleSettings.hipIdleAmount = idleSettings.hipIdleAmount;
jIdleSettings.hipIdleSpeed = idleSettings.hipIdleSpeed;
jIdleSettings.idleCrouchFactor = idleSettings.idleCrouchFactor;
jIdleSettings.idleProneFactor = idleSettings.idleProneFactor;
jIdleSettings.adsIdleLerpStartTime = idleSettings.adsIdleLerpStartTime;
jIdleSettings.adsIdleLerpTime = idleSettings.adsIdleLerpTime;
}
static void ConvertJsonAttADSSettings(JsonAttADSSettings& jAdsSettings, const AttADSSettings& adsSettings)
{
jAdsSettings.adsSpread = adsSettings.adsSpread;
jAdsSettings.adsAimPitch = adsSettings.adsAimPitch;
jAdsSettings.adsTransInTime = adsSettings.adsTransInTime;
jAdsSettings.adsTransOutTime = adsSettings.adsTransOutTime;
jAdsSettings.adsReloadTransTime = adsSettings.adsReloadTransTime;
jAdsSettings.adsCrosshairInFrac = adsSettings.adsCrosshairInFrac;
jAdsSettings.adsCrosshairOutFrac = adsSettings.adsCrosshairOutFrac;
jAdsSettings.adsZoomFov = adsSettings.adsZoomFov;
jAdsSettings.adsZoomInFrac = adsSettings.adsZoomInFrac;
jAdsSettings.adsZoomOutFrac = adsSettings.adsZoomOutFrac;
jAdsSettings.adsBobFactor = adsSettings.adsBobFactor;
jAdsSettings.adsViewBobMult = adsSettings.adsViewBobMult;
jAdsSettings.adsViewErrorMin = adsSettings.adsViewErrorMin;
jAdsSettings.adsViewErrorMax = adsSettings.adsViewErrorMax;
}
static void ConvertJsonAttHipSpread(JsonAttHipSpread& jHipSpread, const AttHipSpread& hipSpread)
{
jHipSpread.hipSpreadStandMin = hipSpread.hipSpreadStandMin;
jHipSpread.hipSpreadDuckedMin = hipSpread.hipSpreadDuckedMin;
jHipSpread.hipSpreadProneMin = hipSpread.hipSpreadProneMin;
jHipSpread.hipSpreadMax = hipSpread.hipSpreadMax;
jHipSpread.hipSpreadDuckedMax = hipSpread.hipSpreadDuckedMax;
jHipSpread.hipSpreadProneMax = hipSpread.hipSpreadProneMax;
jHipSpread.hipSpreadFireAdd = hipSpread.hipSpreadFireAdd;
jHipSpread.hipSpreadTurnAdd = hipSpread.hipSpreadTurnAdd;
jHipSpread.hipSpreadMoveAdd = hipSpread.hipSpreadMoveAdd;
jHipSpread.hipSpreadDecayRate = hipSpread.hipSpreadDecayRate;
jHipSpread.hipSpreadDuckedDecay = hipSpread.hipSpreadDuckedDecay;
jHipSpread.hipSpreadProneDecay = hipSpread.hipSpreadProneDecay;
}
static void ConvertJsonAttGunKick(JsonAttGunKick& jGunKick, const AttGunKick& gunKick)
{
jGunKick.hipGunKickReducedKickBullets = gunKick.hipGunKickReducedKickBullets;
jGunKick.hipGunKickReducedKickPercent = gunKick.hipGunKickReducedKickPercent;
jGunKick.hipGunKickPitchMin = gunKick.hipGunKickPitchMin;
jGunKick.hipGunKickPitchMax = gunKick.hipGunKickPitchMax;
jGunKick.hipGunKickYawMin = gunKick.hipGunKickYawMin;
jGunKick.hipGunKickYawMax = gunKick.hipGunKickYawMax;
jGunKick.hipGunKickAccel = gunKick.hipGunKickAccel;
jGunKick.hipGunKickSpeedMax = gunKick.hipGunKickSpeedMax;
jGunKick.hipGunKickSpeedDecay = gunKick.hipGunKickSpeedDecay;
jGunKick.hipGunKickStaticDecay = gunKick.hipGunKickStaticDecay;
jGunKick.adsGunKickReducedKickBullets = gunKick.adsGunKickReducedKickBullets;
jGunKick.adsGunKickReducedKickPercent = gunKick.adsGunKickReducedKickPercent;
jGunKick.adsGunKickPitchMin = gunKick.adsGunKickPitchMin;
jGunKick.adsGunKickPitchMax = gunKick.adsGunKickPitchMax;
jGunKick.adsGunKickYawMin = gunKick.adsGunKickYawMin;
jGunKick.adsGunKickYawMax = gunKick.adsGunKickYawMax;
jGunKick.adsGunKickAccel = gunKick.adsGunKickAccel;
jGunKick.adsGunKickSpeedMax = gunKick.adsGunKickSpeedMax;
jGunKick.adsGunKickSpeedDecay = gunKick.adsGunKickSpeedDecay;
jGunKick.adsGunKickStaticDecay = gunKick.adsGunKickStaticDecay;
}
static void ConvertJsonAttViewKick(JsonAttViewKick& jViewKick, const AttViewKick& viewKick)
{
jViewKick.hipViewKickPitchMin = viewKick.hipViewKickPitchMin;
jViewKick.hipViewKickPitchMax = viewKick.hipViewKickPitchMax;
jViewKick.hipViewKickYawMin = viewKick.hipViewKickYawMin;
jViewKick.hipViewKickYawMax = viewKick.hipViewKickYawMax;
jViewKick.hipViewKickCenterSpeed = viewKick.hipViewKickCenterSpeed;
jViewKick.adsViewKickPitchMin = viewKick.adsViewKickPitchMin;
jViewKick.adsViewKickPitchMax = viewKick.adsViewKickPitchMax;
jViewKick.adsViewKickYawMin = viewKick.adsViewKickYawMin;
jViewKick.adsViewKickYawMax = viewKick.adsViewKickYawMax;
jViewKick.adsViewKickCenterSpeed = viewKick.adsViewKickCenterSpeed;
}
static void ConvertJsonAttADSOverlay(JsonAttADSOverlay& jAdsOverlay, const AttADSOverlay& adsOverlay)
{
if (adsOverlay.overlay.shader && adsOverlay.overlay.shader->info.name)
jAdsOverlay.shader = AssetName(adsOverlay.overlay.shader->info.name);
if (adsOverlay.overlay.shaderLowRes && adsOverlay.overlay.shaderLowRes->info.name)
jAdsOverlay.shaderLowRes = AssetName(adsOverlay.overlay.shaderLowRes->info.name);
if (adsOverlay.overlay.shaderEMP && adsOverlay.overlay.shaderEMP->info.name)
jAdsOverlay.shaderEMP = AssetName(adsOverlay.overlay.shaderEMP->info.name);
if (adsOverlay.overlay.shaderEMPLowRes && adsOverlay.overlay.shaderEMPLowRes->info.name)
jAdsOverlay.shaderEMPLowRes = AssetName(adsOverlay.overlay.shaderEMPLowRes->info.name);
jAdsOverlay.reticle = adsOverlay.overlay.reticle;
jAdsOverlay.width = adsOverlay.overlay.width;
jAdsOverlay.height = adsOverlay.overlay.height;
jAdsOverlay.widthSplitscreen = adsOverlay.overlay.widthSplitscreen;
jAdsOverlay.heightSplitscreen = adsOverlay.overlay.heightSplitscreen;
jAdsOverlay.thermalScope = adsOverlay.thermalScope;
}
static void ConvertJsonAttUI(JsonAttUI& jUi, const AttUI& ui)
{
if (ui.dpadIcon && ui.dpadIcon->info.name)
jUi.dpadIcon = AssetName(ui.dpadIcon->info.name);
if (ui.ammoCounterIcon && ui.ammoCounterIcon->info.name)
jUi.ammoCounterIcon = AssetName(ui.ammoCounterIcon->info.name);
jUi.dpadIconRatio = ui.dpadIconRatio;
jUi.ammoCounterIconRatio = ui.ammoCounterIconRatio;
jUi.ammoCounterClip = ui.ammoCounterClip;
}
static void ConvertJsonAttRumbles(JsonAttRumbles& jRumbles, const AttRumbles& rumbles)
{
if (rumbles.fireRumble)
jRumbles.fireRumble = rumbles.fireRumble;
if (rumbles.meleeImpactRumble)
jRumbles.meleeImpactRumble = rumbles.meleeImpactRumble;
}
static void ConvertJsonAttProjectile(JsonAttProjectile& jProjectile, const AttProjectile& projectile)
{
jProjectile.explosionRadius = projectile.explosionRadius;
jProjectile.explosionInnerDamage = projectile.explosionInnerDamage;
jProjectile.explosionOuterDamage = projectile.explosionOuterDamage;
jProjectile.damageConeAngle = projectile.damageConeAngle;
jProjectile.projectileSpeed = projectile.projectileSpeed;
jProjectile.projectileSpeedUp = projectile.projectileSpeedUp;
jProjectile.projectileActivateDist = projectile.projectileActivateDist;
jProjectile.projectileLifetime = projectile.projectileLifetime;
if (projectile.projectileModel && projectile.projectileModel->name)
jProjectile.projectileModel = AssetName(projectile.projectileModel->name);
jProjectile.projExplosionType = projectile.projExplosionType;
if (projectile.projExplosionEffect && projectile.projExplosionEffect->name)
jProjectile.projExplosionEffect = AssetName(projectile.projExplosionEffect->name);
jProjectile.projExplosionEffectForceNormalUp = projectile.projExplosionEffectForceNormalUp;
if (projectile.projExplosionSound.name && projectile.projExplosionSound.name->soundName)
jProjectile.projExplosionSound = projectile.projExplosionSound.name->soundName;
if (projectile.projDudEffect && projectile.projDudEffect->name)
jProjectile.projDudEffect = AssetName(projectile.projDudEffect->name);
if (projectile.projDudSound.name && projectile.projDudSound.name->soundName)
jProjectile.projDudSound = projectile.projDudSound.name->soundName;
jProjectile.projImpactExplode = projectile.projImpactExplode;
jProjectile.destabilizationRateTime = projectile.destabilizationRateTime;
jProjectile.destabilizationCurvatureMax = projectile.destabilizationCurvatureMax;
jProjectile.destabilizeDistance = projectile.destabilizeDistance;
if (projectile.projTrailEffect && projectile.projTrailEffect->name)
jProjectile.projTrailEffect = AssetName(projectile.projTrailEffect->name);
jProjectile.projIgnitionDelay = projectile.projIgnitionDelay;
if (projectile.projIgnitionEffect && projectile.projIgnitionEffect->name)
jProjectile.projIgnitionEffect = AssetName(projectile.projIgnitionEffect->name);
if (projectile.projIgnitionSound.name && projectile.projIgnitionSound.name->soundName)
jProjectile.projIgnitionSound = projectile.projIgnitionSound.name->soundName;
}
std::ostream& m_stream;
};
} // namespace
namespace IW5
{
void DumpWeaponAttachmentAsJson(std::ostream& stream, const WeaponAttachment* attachment, AssetDumpingContext& context)
{
const JsonDumper dumper(context, stream);
dumper.Dump(attachment);
}
} // namespace IW5

View File

@ -0,0 +1,11 @@
#pragma once
#include "Dumping/AssetDumpingContext.h"
#include "Game/IW5/IW5.h"
#include <ostream>
namespace IW5
{
void DumpWeaponAttachmentAsJson(std::ostream& stream, const WeaponAttachment* attachment, AssetDumpingContext& context);
} // namespace IW5

View File

@ -9,6 +9,8 @@
#include "AssetDumpers/AssetDumperRawFile.h" #include "AssetDumpers/AssetDumperRawFile.h"
#include "AssetDumpers/AssetDumperScriptFile.h" #include "AssetDumpers/AssetDumperScriptFile.h"
#include "AssetDumpers/AssetDumperStringTable.h" #include "AssetDumpers/AssetDumperStringTable.h"
#include "AssetDumpers/AssetDumperWeapon.h"
#include "AssetDumpers/AssetDumperWeaponAttachment.h"
#include "AssetDumpers/AssetDumperXModel.h" #include "AssetDumpers/AssetDumperXModel.h"
#include "Game/IW5/GameAssetPoolIW5.h" #include "Game/IW5/GameAssetPoolIW5.h"
#include "Game/IW5/GameIW5.h" #include "Game/IW5/GameIW5.h"
@ -58,8 +60,8 @@ bool ZoneDumper::DumpZone(AssetDumpingContext& context) const
DUMP_ASSET_POOL(AssetDumperMenuList, m_menu_list, ASSET_TYPE_MENULIST) DUMP_ASSET_POOL(AssetDumperMenuList, m_menu_list, ASSET_TYPE_MENULIST)
DUMP_ASSET_POOL(AssetDumperMenuDef, m_menu_def, ASSET_TYPE_MENU) DUMP_ASSET_POOL(AssetDumperMenuDef, m_menu_def, ASSET_TYPE_MENU)
DUMP_ASSET_POOL(AssetDumperLocalizeEntry, m_localize, ASSET_TYPE_LOCALIZE_ENTRY) DUMP_ASSET_POOL(AssetDumperLocalizeEntry, m_localize, ASSET_TYPE_LOCALIZE_ENTRY)
// DUMP_ASSET_POOL(AssetDumperWeaponAttachment, m_attachment, ASSET_TYPE_ATTACHMENT) DUMP_ASSET_POOL(AssetDumperWeaponAttachment, m_attachment, ASSET_TYPE_ATTACHMENT)
// DUMP_ASSET_POOL(AssetDumperWeaponCompleteDef, m_weapon, ASSET_TYPE_WEAPON) DUMP_ASSET_POOL(AssetDumperWeapon, m_weapon, ASSET_TYPE_WEAPON)
// DUMP_ASSET_POOL(AssetDumperFxEffectDef, m_fx, ASSET_TYPE_FX) // DUMP_ASSET_POOL(AssetDumperFxEffectDef, m_fx, ASSET_TYPE_FX)
// DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table, ASSET_TYPE_IMPACT_FX) // DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table, ASSET_TYPE_IMPACT_FX)
// DUMP_ASSET_POOL(AssetDumperSurfaceFxTable, m_surface_fx_table, ASSET_TYPE_SURFACE_FX) // DUMP_ASSET_POOL(AssetDumperSurfaceFxTable, m_surface_fx_table, ASSET_TYPE_SURFACE_FX)

View File

@ -46,16 +46,16 @@ set reusable notetrackRumbleMapValues;
set scriptstring notetrackRumbleMapValues; set scriptstring notetrackRumbleMapValues;
set count notetrackRumbleMapValues 16; set count notetrackRumbleMapValues 16;
set reusable bounceSound; set reusable bounceSound;
set count bounceSound 31; set count bounceSound SURF_TYPE_NUM;
set reusable worldModel; set reusable worldModel;
set count worldModel 16; set count worldModel 16;
set string szAmmoName; set string szAmmoName;
set string szClipName; set string szClipName;
set string szSharedAmmoCapName; set string szSharedAmmoCapName;
set reusable parallelBounce; set reusable parallelBounce;
set count parallelBounce 31; set count parallelBounce SURF_TYPE_NUM;
set reusable perpendicularBounce; set reusable perpendicularBounce;
set count perpendicularBounce 31; set count perpendicularBounce SURF_TYPE_NUM;
set string accuracyGraphName0; set string accuracyGraphName0;
set string accuracyGraphName1; set string accuracyGraphName1;
set reusable originalAccuracyGraphKnots0; set reusable originalAccuracyGraphKnots0;

View File

@ -19,7 +19,7 @@ set count others 4;
set string szXAnims; set string szXAnims;
set assetref szXAnims ASSET_TYPE_XANIMPARTS; set assetref szXAnims ASSET_TYPE_XANIMPARTS;
set reusable szXAnims; set reusable szXAnims;
set count szXAnims NUM_WEAP_ANIMS; set count szXAnims WEAP_ANIM_COUNT;
set reusable animOverrides; set reusable animOverrides;
set count animOverrides numAnimOverrides; set count animOverrides numAnimOverrides;
set reusable soundOverrides; set reusable soundOverrides;
@ -39,6 +39,8 @@ set count accuracyGraphKnots[1] accuracyGraphKnotCount[1];
use AnimOverrideEntry; use AnimOverrideEntry;
set string overrideAnim; set string overrideAnim;
set string altmodeAnim; set string altmodeAnim;
set assetref overrideAnim ASSET_TYPE_XANIMPARTS;
set assetref altmodeAnim ASSET_TYPE_XANIMPARTS;
// NoteTrackToSoundEntry // NoteTrackToSoundEntry
use NoteTrackToSoundEntry; use NoteTrackToSoundEntry;
@ -57,11 +59,11 @@ set count gunXModel 16;
set reusable szXAnimsRightHanded; set reusable szXAnimsRightHanded;
set string szXAnimsRightHanded; set string szXAnimsRightHanded;
set assetref szXAnimsRightHanded ASSET_TYPE_XANIMPARTS; set assetref szXAnimsRightHanded ASSET_TYPE_XANIMPARTS;
set count szXAnimsRightHanded NUM_WEAP_ANIMS; set count szXAnimsRightHanded WEAP_ANIM_COUNT;
set reusable szXAnimsLeftHanded; set reusable szXAnimsLeftHanded;
set string szXAnimsLeftHanded; set string szXAnimsLeftHanded;
set assetref szXAnimsLeftHanded ASSET_TYPE_XANIMPARTS; set assetref szXAnimsLeftHanded ASSET_TYPE_XANIMPARTS;
set count szXAnimsLeftHanded NUM_WEAP_ANIMS; set count szXAnimsLeftHanded WEAP_ANIM_COUNT;
set string szModeName; set string szModeName;
set reusable notetrackSoundMapKeys; set reusable notetrackSoundMapKeys;
set scriptstring notetrackSoundMapKeys; set scriptstring notetrackSoundMapKeys;
@ -76,18 +78,18 @@ set reusable notetrackRumbleMapValues;
set scriptstring notetrackRumbleMapValues; set scriptstring notetrackRumbleMapValues;
set count notetrackRumbleMapValues 16; set count notetrackRumbleMapValues 16;
set reusable bounceSound; set reusable bounceSound;
set count bounceSound 31; set count bounceSound SURF_TYPE_COUNT;
set reusable rollingSound; set reusable rollingSound;
set count rollingSound 31; set count rollingSound SURF_TYPE_COUNT;
set reusable worldModel; set reusable worldModel;
set count worldModel 16; set count worldModel 16;
set string szAmmoName; set string szAmmoName;
set string szClipName; set string szClipName;
set string szSharedAmmoCapName; set string szSharedAmmoCapName;
set reusable parallelBounce; set reusable parallelBounce;
set count parallelBounce 31; set count parallelBounce SURF_TYPE_COUNT;
set reusable perpendicularBounce; set reusable perpendicularBounce;
set count perpendicularBounce 31; set count perpendicularBounce SURF_TYPE_COUNT;
set string accuracyGraphName0; set string accuracyGraphName0;
set string accuracyGraphName1; set string accuracyGraphName1;
set reusable originalAccuracyGraphKnots0; set reusable originalAccuracyGraphKnots0;
@ -117,4 +119,6 @@ set reusable name;
set condition sound never; set condition sound never;
// snd_alias_list_name // snd_alias_list_name
set string snd_alias_list_name::soundName; use snd_alias_list_name;
set string soundName;
set assetref soundName ASSET_TYPE_SOUND;