From 5db7eaeec3104ee1b2babcdec95430252ee33b4c Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 7 Mar 2021 15:25:58 +0100 Subject: [PATCH] Add T6 Attachment dumper --- src/Common/Game/T6/CommonT6.h | 73 ++++++++ src/Common/Game/T6/T6.h | 28 ++- src/Common/Game/T6/T6_Assets.h | 7 + .../AssetDumperPhysConstraints.cpp | 19 +- .../T6/AssetDumpers/AssetDumperWeapon.cpp | 31 +--- .../AssetDumperWeaponAttachment.cpp | 175 ++++++++++++++++++ .../AssetDumperWeaponAttachment.h | 26 +++ .../AssetDumperWeaponAttachmentUnique.cpp | 0 .../AssetDumperWeaponAttachmentUnique.h | 27 +++ src/ObjWriting/Game/T6/ZoneDumperT6.cpp | 3 +- 10 files changed, 344 insertions(+), 45 deletions(-) create mode 100644 src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeaponAttachment.cpp create mode 100644 src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeaponAttachment.h create mode 100644 src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeaponAttachmentUnique.cpp create mode 100644 src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeaponAttachmentUnique.h diff --git a/src/Common/Game/T6/CommonT6.h b/src/Common/Game/T6/CommonT6.h index 73e8e97a..81a8976b 100644 --- a/src/Common/Game/T6/CommonT6.h +++ b/src/Common/Game/T6/CommonT6.h @@ -1,5 +1,78 @@ #pragma once +namespace T6 +{ + inline const char* szAttachmentTypeNames[] + { + "none", + "acog", + "dualclip", + "dualoptic", + "dw", + "extbarrel", + "extclip", + "extramags", + "fastads", + "fastreload", + "fmj", + "gl", + "grip", + "holo", + "ir", + "is", + "longbreath", + "mk", + "mms", + "rangefinder", + "reflex", + "rf", + "sf", + "silencer", + "stackfire", + "stalker", + "steadyaim", + "swayreduc", + "tacknife", + "vzoom" + }; + + inline const char* szWeapFireTypeNames[] + { + "Full Auto", + "Single Shot", + "2-Round Burst", + "3-Round Burst", + "4-Round Burst", + "5-Round Burst", + "Stacked Fire", + "Minigun", + "Charge Shot", + "Jetgun" + }; + + inline const char* penetrateTypeNames[] + { + "none", + "small", + "medium", + "large" + }; + + inline const char* s_constraintTypeNames[] + { + "none", + "point", + "distance", + "hinge", + "joint", + "actuator", + "fake_shake", + "launch", + "rope", + "light", + }; +} + class CommonT6 { public: diff --git a/src/Common/Game/T6/T6.h b/src/Common/Game/T6/T6.h index a2af125d..7e9f8306 100644 --- a/src/Common/Game/T6/T6.h +++ b/src/Common/Game/T6/T6.h @@ -119,8 +119,32 @@ namespace T6 enum constraintsFieldType_t { - CFT_TYPE = 0x12, + CFT_TYPE = CSPFT_NUM_BASE_FIELD_TYPES, - CFT_NUM + CFT_NUM_FIELD_TYPES }; + + enum attachmentFieldType_t + { + AFT_ATTACHMENTTYPE = CSPFT_NUM_BASE_FIELD_TYPES, + AFT_UNKNOWN1, + AFT_UNKNOWN2, + AFT_UNKNOWN3, + AFT_UNKNOWN4, + AFT_PENETRATE_TYPE, + AFT_FIRETYPE, + + AFT_NUM + }; + + enum attachmentUniqueFieldType_t + { + AUFT_ATTACHMENTTYPE = CSPFT_NUM_BASE_FIELD_TYPES, + AUFT_HIDETAGS, + AUFT_OVERLAYRETICLE, + AUFT_CAMO, + + AUFT_NUM_FIELD_TYPES, + }; + } diff --git a/src/Common/Game/T6/T6_Assets.h b/src/Common/Game/T6/T6_Assets.h index 8f476c03..2ea8fffa 100644 --- a/src/Common/Game/T6/T6_Assets.h +++ b/src/Common/Game/T6/T6_Assets.h @@ -1719,6 +1719,13 @@ namespace T6 int customBool2; }; + struct WeaponAttachmentUniqueFull + { + WeaponAttachmentUnique attachment; + const char* szXAnims[88]; + uint16_t hideTags[32]; + float locationDamageMultipliers[21]; + }; struct WeaponCamo { diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperPhysConstraints.cpp b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperPhysConstraints.cpp index 2a797c69..bea22981 100644 --- a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperPhysConstraints.cpp +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperPhysConstraints.cpp @@ -3,6 +3,8 @@ #include #include + +#include "Game/T6/CommonT6.h" #include "Game/T6/InfoStringT6.h" using namespace T6; @@ -89,20 +91,6 @@ cspField_t AssetDumperPhysConstraints::phys_constraints_fields[] namespace T6 { - const char* s_constraintTypeNames[] - { - "none", - "point", - "distance", - "hinge", - "joint", - "actuator", - "fake_shake", - "launch", - "rope", - "light", - }; - class InfoStringFromPhysConstraintsConverter final : public InfoStringFromStructConverter { protected: @@ -113,8 +101,7 @@ namespace T6 case CFT_TYPE: FillFromEnumInt(std::string(field.szName), field.iOffset, s_constraintTypeNames, std::extent::value); break; - - case CFT_NUM: + default: assert(false); break; diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeapon.cpp b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeapon.cpp index 6508231e..ffdf26fe 100644 --- a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeapon.cpp +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeapon.cpp @@ -5,6 +5,7 @@ #include #include +#include "Game/T6/CommonT6.h" #include "Game/T6/InfoStringT6.h" using namespace T6; @@ -1088,20 +1089,6 @@ namespace T6 "dwlefthand" }; - const char* szWeapFireTypeNames[] - { - "Full Auto", - "Single Shot", - "2-Round Burst", - "3-Round Burst", - "4-Round Burst", - "5-Round Burst", - "Stacked Fire", - "Minigun", - "Charge Shot", - "Jetgun" - }; - const char* szWeapClipTypeNames[] { "bottom", @@ -1122,14 +1109,6 @@ namespace T6 "Quad Barrel Double Alternate" }; - const char* penetrateTypeNames[] - { - "none", - "small", - "medium", - "large" - }; - const char* impactTypeNames[] { "none", @@ -1625,11 +1604,11 @@ void AssetDumperWeapon::CopyToFullDef(const WeaponVariantDef* weapon, WeaponFull InfoString AssetDumperWeapon::CreateInfoString(XAssetInfo* asset) { - auto* fullDef = new WeaponFullDef; - memset(fullDef, 0, sizeof(WeaponFullDef)); - CopyToFullDef(asset->Asset(), fullDef); + const auto fullDef = std::make_unique(); + memset(fullDef.get(), 0, sizeof(WeaponFullDef)); + CopyToFullDef(asset->Asset(), fullDef.get()); - InfoStringFromWeaponConverter converter(fullDef, weapon_fields, std::extent::value, [asset](const scr_string_t scrStr) -> std::string + InfoStringFromWeaponConverter converter(fullDef.get(), weapon_fields, std::extent::value, [asset](const scr_string_t scrStr) -> std::string { assert(scrStr < asset->m_zone->m_script_strings.size()); if (scrStr >= asset->m_zone->m_script_strings.size()) diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeaponAttachment.cpp b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeaponAttachment.cpp new file mode 100644 index 00000000..82a45086 --- /dev/null +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeaponAttachment.cpp @@ -0,0 +1,175 @@ +#include "AssetDumperWeaponAttachment.h" + +#include +#include +#include +#include + +#include "Game/T6/CommonT6.h" +#include "Game/T6/InfoStringT6.h" + +using namespace T6; + +cspField_t AssetDumperWeaponAttachment::attachment_fields[] +{ + {"displayName", offsetof(WeaponAttachment, szDisplayName), CSPFT_STRING}, + {"attachmentType", offsetof(WeaponAttachment, attachmentType), AFT_ATTACHMENTTYPE}, + {"penetrateType", offsetof(WeaponAttachment, penetrateType), AFT_PENETRATE_TYPE}, + {"firstRaisePriority", offsetof(WeaponAttachment, firstRaisePriority), CSPFT_INT}, + {"hipIdleAmount", offsetof(WeaponAttachment, fHipIdleAmount), CSPFT_FLOAT}, + {"fireType", offsetof(WeaponAttachment, fireType), AFT_FIRETYPE}, + {"damageRangeScale", offsetof(WeaponAttachment, fDamageRangeScale), CSPFT_FLOAT}, + {"adsZoomFov1", offsetof(WeaponAttachment, fAdsZoomFov1), CSPFT_FLOAT}, + {"adsZoomFov2", offsetof(WeaponAttachment, fAdsZoomFov2), CSPFT_FLOAT}, + {"adsZoomFov3", offsetof(WeaponAttachment, fAdsZoomFov3), CSPFT_FLOAT}, + {"adsZoomInFrac", offsetof(WeaponAttachment, fAdsZoomInFrac), CSPFT_FLOAT}, + {"adsZoomOutFrac", offsetof(WeaponAttachment, fAdsZoomOutFrac), CSPFT_FLOAT}, + {"adsTransInTimeScale", offsetof(WeaponAttachment, fAdsTransInTimeScale), CSPFT_FLOAT}, + {"adsTransOutTimeScale", offsetof(WeaponAttachment, fAdsTransOutTimeScale), CSPFT_FLOAT}, + {"adsRecoilReductionRate", offsetof(WeaponAttachment, fAdsRecoilReductionRate), CSPFT_FLOAT}, + {"adsRecoilReductionLimit", offsetof(WeaponAttachment, fAdsRecoilReductionLimit), CSPFT_FLOAT}, + {"adsViewKickCenterSpeedScale", offsetof(WeaponAttachment, fAdsViewKickCenterSpeedScale), CSPFT_FLOAT}, + {"adsIdleAmountScale", offsetof(WeaponAttachment, fAdsIdleAmountScale), CSPFT_FLOAT}, + {"swayOverride", offsetof(WeaponAttachment, swayOverride), CSPFT_BOOL}, + {"swayMaxAngle", offsetof(WeaponAttachment, swayMaxAngle), CSPFT_FLOAT}, + {"swayLerpSpeed", offsetof(WeaponAttachment, swayLerpSpeed), CSPFT_FLOAT}, + {"swayPitchScale", offsetof(WeaponAttachment, swayPitchScale), CSPFT_FLOAT}, + {"swayYawScale", offsetof(WeaponAttachment, swayYawScale), CSPFT_FLOAT}, + {"swayHorizScale", offsetof(WeaponAttachment, swayHorizScale), CSPFT_FLOAT}, + {"swayVertScale", offsetof(WeaponAttachment, swayVertScale), CSPFT_FLOAT}, + {"adsSwayOverride", offsetof(WeaponAttachment, adsSwayOverride), CSPFT_BOOL}, + {"adsSwayMaxAngle", offsetof(WeaponAttachment, adsSwayMaxAngle), CSPFT_FLOAT}, + {"adsSwayLerpSpeed", offsetof(WeaponAttachment, adsSwayLerpSpeed), CSPFT_FLOAT}, + {"adsSwayPitchScale", offsetof(WeaponAttachment, adsSwayPitchScale), CSPFT_FLOAT}, + {"adsSwayYawScale", offsetof(WeaponAttachment, adsSwayYawScale), CSPFT_FLOAT}, + {"adsSwayHorizScale", offsetof(WeaponAttachment, fAdsSwayHorizScale), CSPFT_FLOAT}, + {"adsSwayVertScale", offsetof(WeaponAttachment, fAdsSwayVertScale), CSPFT_FLOAT}, + {"adsMoveSpeedScale", offsetof(WeaponAttachment, adsMoveSpeedScale), CSPFT_FLOAT}, + {"hipSpreadMinScale", offsetof(WeaponAttachment, fHipSpreadMinScale), CSPFT_FLOAT}, + {"hipSpreadMaxScale", offsetof(WeaponAttachment, fHipSpreadMaxScale), CSPFT_FLOAT}, + {"strafeRotR", offsetof(WeaponAttachment, strafeRotR), CSPFT_FLOAT}, + {"standMoveF", offsetof(WeaponAttachment, standMoveF), CSPFT_FLOAT}, + {"standRotP", offsetof(WeaponAttachment, vStandRot.x), CSPFT_FLOAT}, + {"standRotY", offsetof(WeaponAttachment, vStandRot.y), CSPFT_FLOAT}, + {"standRotR", offsetof(WeaponAttachment, vStandRot.z), CSPFT_FLOAT}, + {"fireTimeScale", offsetof(WeaponAttachment, fFireTimeScale), CSPFT_FLOAT}, + {"reloadTimeScale", offsetof(WeaponAttachment, fReloadTimeScale), CSPFT_FLOAT}, + {"reloadEmptyTimeScale", offsetof(WeaponAttachment, fReloadEmptyTimeScale), CSPFT_FLOAT}, + {"reloadAddTimeScale", offsetof(WeaponAttachment, fReloadAddTimeScale), CSPFT_FLOAT}, + {"reloadQuickTimeScale", offsetof(WeaponAttachment, fReloadQuickTimeScale), CSPFT_FLOAT}, + {"reloadQuickEmptyTimeScale", offsetof(WeaponAttachment, fReloadQuickEmptyTimeScale), CSPFT_FLOAT}, + {"reloadQuickAddTimeScale", offsetof(WeaponAttachment, fReloadQuickAddTimeScale), CSPFT_FLOAT}, + {"perks1", offsetof(WeaponAttachment, perks[0]), CSPFT_UINT}, + {"perks0", offsetof(WeaponAttachment, perks[1]), CSPFT_UINT}, + {"altWeaponAdsOnly", offsetof(WeaponAttachment, bAltWeaponAdsOnly), CSPFT_BOOL}, + {"altWeaponDisableSwitching", offsetof(WeaponAttachment, bAltWeaponDisableSwitching), CSPFT_BOOL}, + {"altScopeADSTransInTime", offsetof(WeaponAttachment, altScopeADSTransInTime), CSPFT_FLOAT}, + {"altScopeADSTransOutTime", offsetof(WeaponAttachment, altScopeADSTransOutTime), CSPFT_FLOAT}, + {"silenced", offsetof(WeaponAttachment, bSilenced), CSPFT_BOOL}, + {"dualMag", offsetof(WeaponAttachment, bDualMag), CSPFT_BOOL}, + {"laserSight", offsetof(WeaponAttachment, laserSight), CSPFT_BOOL}, + {"infrared", offsetof(WeaponAttachment, bInfraRed), CSPFT_BOOL}, + {"useAsMelee", offsetof(WeaponAttachment, bUseAsMelee), CSPFT_BOOL}, + {"dualWield", offsetof(WeaponAttachment, bDualWield), CSPFT_BOOL}, + {"sharedAmmo", offsetof(WeaponAttachment, sharedAmmo), CSPFT_BOOL}, + {"mmsWeapon", offsetof(WeaponAttachment, mmsWeapon), CSPFT_BOOL}, + {"mmsInScope", offsetof(WeaponAttachment, mmsInScope), CSPFT_BOOL}, + {"mmsFOV", offsetof(WeaponAttachment, mmsFOV), CSPFT_FLOAT}, + {"mmsAspect", offsetof(WeaponAttachment, mmsAspect), CSPFT_FLOAT}, + {"mmsMaxDist", offsetof(WeaponAttachment, mmsMaxDist), CSPFT_FLOAT}, + {"clipSizeScale", offsetof(WeaponAttachment, clipSizeScale), CSPFT_FLOAT}, + {"clipSize", offsetof(WeaponAttachment, iClipSize), CSPFT_INT}, + {"stackFire", offsetof(WeaponAttachment, stackFire), CSPFT_FLOAT}, + {"stackFireSpread", offsetof(WeaponAttachment, stackFireSpread), CSPFT_FLOAT}, + {"stackFireAccuracyDecay", offsetof(WeaponAttachment, stackFireAccuracyDecay), CSPFT_FLOAT}, + {"customFloat0", offsetof(WeaponAttachment, customFloat0), CSPFT_FLOAT}, + {"customFloat1", offsetof(WeaponAttachment, customFloat1), CSPFT_FLOAT}, + {"customFloat2", offsetof(WeaponAttachment, customFloat2), CSPFT_FLOAT}, + {"customBool0", offsetof(WeaponAttachment, customBool0), CSPFT_BOOL}, + {"customBool1", offsetof(WeaponAttachment, customBool1), CSPFT_BOOL}, + {"customBool2", offsetof(WeaponAttachment, customBool2), CSPFT_BOOL}, +}; + +namespace T6 +{ + class InfoStringFromAttachmentConverter final : public InfoStringFromStructConverter + { + protected: + void FillFromExtensionField(const cspField_t& field) override + { + switch (static_cast(field.iFieldType)) + { + case AFT_ATTACHMENTTYPE: + FillFromEnumInt(std::string(field.szName), field.iOffset, szAttachmentTypeNames, std::extent::value); + break; + + case AFT_PENETRATE_TYPE: + FillFromEnumInt(std::string(field.szName), field.iOffset, penetrateTypeNames, std::extent::value); + break; + + case AFT_FIRETYPE: + FillFromEnumInt(std::string(field.szName), field.iOffset, szWeapFireTypeNames, std::extent::value); + break; + + default: + break; + } + } + + public: + InfoStringFromAttachmentConverter(const WeaponAttachment* structure, const cspField_t* fields, const size_t fieldCount, std::function scriptStringValueCallback) + : InfoStringFromStructConverter(structure, fields, fieldCount, std::move(scriptStringValueCallback)) + { + } + }; +} + +InfoString AssetDumperWeaponAttachment::CreateInfoString(XAssetInfo* asset) +{ + InfoStringFromAttachmentConverter converter(asset->Asset(), attachment_fields, std::extent::value, [asset](const scr_string_t scrStr) -> std::string + { + assert(scrStr < asset->m_zone->m_script_strings.size()); + if (scrStr >= asset->m_zone->m_script_strings.size()) + return ""; + + return asset->m_zone->m_script_strings[scrStr]; + }); + + return converter.Convert(); +} + +bool AssetDumperWeaponAttachment::ShouldDump(XAssetInfo* asset) +{ + return true; +} + +bool AssetDumperWeaponAttachment::CanDumpAsRaw() +{ + return true; +} + +bool AssetDumperWeaponAttachment::CanDumpAsGdtEntry() +{ + return true; +} + +std::string AssetDumperWeaponAttachment::GetFileNameForAsset(Zone* zone, XAssetInfo* asset) +{ + return "attachment/" + asset->m_name; +} + +GdtEntry AssetDumperWeaponAttachment::DumpGdtEntry(AssetDumpingContext& context, XAssetInfo* asset) +{ + const auto infoString = CreateInfoString(asset); + GdtEntry gdtEntry(asset->m_name, GDF_NAME); + infoString.ToGdtProperties(FILE_TYPE_STR, gdtEntry); + + return gdtEntry; +} + +void AssetDumperWeaponAttachment::DumpRaw(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream) +{ + const auto infoString = CreateInfoString(asset); + const auto stringValue = infoString.ToString(FILE_TYPE_STR); + stream.write(stringValue.c_str(), stringValue.size()); +} diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeaponAttachment.h b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeaponAttachment.h new file mode 100644 index 00000000..98f59fba --- /dev/null +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeaponAttachment.h @@ -0,0 +1,26 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/T6/T6.h" +#include "Utils/InfoString.h" + +namespace T6 +{ + class AssetDumperWeaponAttachment final : public AbstractAssetDumper + { + static constexpr const char* FILE_TYPE_STR = "ATTACHMENTFILE"; + static constexpr const char* GDF_NAME = "attachment.gdf"; + static cspField_t attachment_fields[]; + + static InfoString CreateInfoString(XAssetInfo* asset); + + protected: + bool ShouldDump(XAssetInfo* asset) override; + bool CanDumpAsRaw() override; + bool CanDumpAsGdtEntry() override; + + std::string GetFileNameForAsset(Zone* zone, XAssetInfo* asset) override; + GdtEntry DumpGdtEntry(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpRaw(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream) override; + }; +} diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeaponAttachmentUnique.cpp b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeaponAttachmentUnique.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeaponAttachmentUnique.h b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeaponAttachmentUnique.h new file mode 100644 index 00000000..0bae843b --- /dev/null +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperWeaponAttachmentUnique.h @@ -0,0 +1,27 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/T6/T6.h" +#include "Utils/InfoString.h" + +namespace T6 +{ + class AssetDumperWeaponAttachmentUnique final : public AbstractAssetDumper + { + static constexpr const char* FILE_TYPE_STR = "ATTACHMENTUNIQUEFILE"; + static constexpr const char* GDF_NAME = "attachmentunique.gdf"; + static cspField_t attachment_unique_fields[]; + + static void CopyToFullDef(const WeaponAttachmentUnique* weapon, WeaponAttachmentUniqueFull* fullDef); + static InfoString CreateInfoString(XAssetInfo* asset); + + protected: + bool ShouldDump(XAssetInfo* asset) override; + bool CanDumpAsRaw() override; + bool CanDumpAsGdtEntry() override; + + std::string GetFileNameForAsset(Zone* zone, XAssetInfo* asset) override; + GdtEntry DumpGdtEntry(AssetDumpingContext& context, XAssetInfo* asset) override; + void DumpRaw(AssetDumpingContext& context, XAssetInfo* asset, std::ostream& stream) override; + }; +} diff --git a/src/ObjWriting/Game/T6/ZoneDumperT6.cpp b/src/ObjWriting/Game/T6/ZoneDumperT6.cpp index d89e8b78..31a3cfda 100644 --- a/src/ObjWriting/Game/T6/ZoneDumperT6.cpp +++ b/src/ObjWriting/Game/T6/ZoneDumperT6.cpp @@ -16,6 +16,7 @@ #include "AssetDumpers/AssetDumperTracer.h" #include "AssetDumpers/AssetDumperVehicle.h" #include "AssetDumpers/AssetDumperWeapon.h" +#include "AssetDumpers/AssetDumperWeaponAttachment.h" #include "AssetDumpers/AssetDumperZBarrier.h" using namespace T6; @@ -59,7 +60,7 @@ bool ZoneDumper::DumpZone(AssetDumpingContext& context) const // DUMP_ASSET_POOL(AssetDumperMenuDef, m_menu_def); DUMP_ASSET_POOL(AssetDumperLocalizeEntry, m_localize); DUMP_ASSET_POOL(AssetDumperWeapon, m_weapon); - // DUMP_ASSET_POOL(AssetDumperWeaponAttachment, m_attachment); + DUMP_ASSET_POOL(AssetDumperWeaponAttachment, m_attachment); // DUMP_ASSET_POOL(AssetDumperWeaponAttachmentUnique, m_attachment_unique); // DUMP_ASSET_POOL(AssetDumperWeaponCamo, m_camo); // DUMP_ASSET_POOL(AssetDumperSndDriverGlobals, m_snd_driver_globals);