feat: load iw5 weapon attachments from raw

This commit is contained in:
Jan 2024-04-14 17:47:06 +02:00
parent 28949f4ee8
commit d3c0325fea
No known key found for this signature in database
GPG Key ID: 44B581F78FF5C57C
5 changed files with 722 additions and 1 deletions

View File

@ -0,0 +1,47 @@
#include "AssetLoaderWeaponAttachment.h"
#include "Game/IW5/IW5.h"
#include "Game/IW5/Weapon/JsonWeaponAttachmentLoader.h"
#include "Pool/GlobalAssetPool.h"
#include <cstring>
#include <format>
#include <iostream>
using namespace IW5;
void* AssetLoaderWeaponAttachment::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
{
auto* attachment = memory->Create<WeaponAttachment>();
memset(attachment, 0, sizeof(WeaponAttachment));
attachment->szInternalName = memory->Dup(assetName.c_str());
return attachment;
}
bool AssetLoaderWeaponAttachment::CanLoadFromRaw() const
{
return true;
}
bool AssetLoaderWeaponAttachment::LoadFromRaw(
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
{
const auto file = searchPath->Open(std::format("attachment/{}.json", assetName));
if (!file.IsOpen())
return false;
auto* attachment = static_cast<WeaponAttachment*>(memory->Alloc(sizeof(WeaponAttachment)));
memset(attachment, 0, sizeof(Material));
attachment->szInternalName = memory->Dup(assetName.c_str());
std::vector<XAssetInfoGeneric*> dependencies;
std::vector<IndirectAssetReference> indirectAssetReferences;
if (LoadWeaponAttachmentAsJson(*file.m_stream, *attachment, memory, manager, dependencies, indirectAssetReferences))
manager->AddAsset(
ASSET_TYPE_ATTACHMENT, assetName, attachment, std::move(dependencies), std::vector<scr_string_t>(), std::move(indirectAssetReferences));
else
std::cerr << "Failed to load attachment \"" << assetName << "\"\n";
return true;
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "AssetLoading/BasicAssetLoader.h"
#include "AssetLoading/IAssetLoadingManager.h"
#include "Game/IW5/IW5.h"
#include "SearchPath/ISearchPath.h"
namespace IW5
{
class AssetLoaderWeaponAttachment final : public BasicAssetLoader<ASSET_TYPE_ATTACHMENT, WeaponAttachment>
{
public:
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
_NODISCARD bool CanLoadFromRaw() const override;
bool
LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
};
} // namespace IW5

View File

@ -7,6 +7,7 @@
#include "AssetLoaders/AssetLoaderRawFile.h" #include "AssetLoaders/AssetLoaderRawFile.h"
#include "AssetLoaders/AssetLoaderScriptFile.h" #include "AssetLoaders/AssetLoaderScriptFile.h"
#include "AssetLoaders/AssetLoaderStringTable.h" #include "AssetLoaders/AssetLoaderStringTable.h"
#include "AssetLoaders/AssetLoaderWeaponAttachment.h"
#include "AssetLoading/AssetLoadingManager.h" #include "AssetLoading/AssetLoadingManager.h"
#include "Game/IW5/GameAssetPoolIW5.h" #include "Game/IW5/GameAssetPoolIW5.h"
#include "Game/IW5/GameIW5.h" #include "Game/IW5/GameIW5.h"
@ -55,7 +56,7 @@ ObjLoader::ObjLoader()
REGISTER_ASSET_LOADER(AssetLoaderMenuList) REGISTER_ASSET_LOADER(AssetLoaderMenuList)
REGISTER_ASSET_LOADER(AssetLoaderMenuDef) REGISTER_ASSET_LOADER(AssetLoaderMenuDef)
REGISTER_ASSET_LOADER(AssetLoaderLocalizeEntry) REGISTER_ASSET_LOADER(AssetLoaderLocalizeEntry)
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_ATTACHMENT, WeaponAttachment)) REGISTER_ASSET_LOADER(AssetLoaderWeaponAttachment)
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_WEAPON, WeaponCompleteDef)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_WEAPON, WeaponCompleteDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FX, FxEffectDef)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FX, FxEffectDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_IMPACT_FX, FxImpactTable)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_IMPACT_FX, FxImpactTable))

View File

@ -0,0 +1,639 @@
#include "JsonWeaponAttachmentLoader.h"
#include "Game/IW5/CommonIW5.h"
#include "Game/IW5/Weapon/JsonWeaponAttachment.h"
#include <format>
#include <iostream>
#include <nlohmann/json.hpp>
using namespace nlohmann;
using namespace IW5;
namespace
{
class JsonLoader
{
public:
JsonLoader(std::istream& stream,
MemoryManager& memory,
IAssetLoadingManager& manager,
std::vector<XAssetInfoGeneric*>& dependencies,
std::vector<IndirectAssetReference>& indirectAssetReferences)
: m_stream(stream),
m_memory(memory),
m_manager(manager),
m_dependencies(dependencies),
m_indirect_asset_references(indirectAssetReferences)
{
}
bool Load(WeaponAttachment& attachment) const
{
const auto jRoot = json::parse(m_stream);
std::string type;
unsigned version;
jRoot.at("_type").get_to(type);
jRoot.at("_version").get_to(version);
if (type != "attachment" || version != 1u)
{
std::cerr << "Tried to load attachment \"" << attachment.szInternalName << "\" but did not find expected type attachment of version 1\n";
return false;
}
const auto jAttachment = jRoot.get<JsonWeaponAttachment>();
return CreateWeaponAttachmentFromJson(jAttachment, attachment);
}
private:
static void PrintError(const WeaponAttachment& attachment, const std::string& message)
{
std::cerr << "Cannot load attachment \"" << attachment.szInternalName << "\": " << message << "\n";
}
bool CreateWeaponAttachmentFromJson(const JsonWeaponAttachment& jAttachment, WeaponAttachment& attachment) const
{
#define CONVERT_XMODEL_ARRAY(propertyName, count) \
CreateXModelArrayFromJson(jAttachment.propertyName, attachment.propertyName, #propertyName, count, attachment);
#define CONVERT_ATTRIBUTE(attributeClass, attributeName) \
if (jAttachment.ammoGeneral) \
{ \
using AttributeType = std::remove_pointer_t<decltype(attachment.attributeName)>; \
attachment.attributeName = static_cast<AttributeType*>(m_memory.Alloc(sizeof(AttributeType))); \
if (!Create##attributeClass##FromJson(jAttachment.attributeName.value(), *attachment.attributeName, attachment)) \
return false; \
} \
else \
attachment.attributeName = nullptr;
attachment.szDisplayName = m_memory.Dup(jAttachment.displayName.c_str());
attachment.type = jAttachment.type;
attachment.weaponType = jAttachment.weaponType;
attachment.weapClass = jAttachment.weapClass;
CONVERT_XMODEL_ARRAY(worldModels, ATTACHMENT_WORLD_MODEL_COUNT)
CONVERT_XMODEL_ARRAY(viewModels, ATTACHMENT_VIEW_MODEL_COUNT)
CONVERT_XMODEL_ARRAY(reticleViewModels, ATTACHMENT_RETICLE_VIEW_MODEL_COUNT)
CONVERT_ATTRIBUTE(AttAmmoGeneral, ammoGeneral)
CONVERT_ATTRIBUTE(AttSight, sight)
CONVERT_ATTRIBUTE(AttReload, reload)
CONVERT_ATTRIBUTE(AttAddOns, addOns)
CONVERT_ATTRIBUTE(AttGeneral, general)
CONVERT_ATTRIBUTE(AttAimAssist, aimAssist)
CONVERT_ATTRIBUTE(AttAmmunition, ammunition)
CONVERT_ATTRIBUTE(AttDamage, damage)
CONVERT_ATTRIBUTE(AttLocationDamage, locationDamage)
CONVERT_ATTRIBUTE(AttIdleSettings, idleSettings)
CONVERT_ATTRIBUTE(AttADSSettings, adsSettings)
CONVERT_ATTRIBUTE(AttADSSettings, adsSettingsMain)
CONVERT_ATTRIBUTE(AttHipSpread, hipSpread)
CONVERT_ATTRIBUTE(AttGunKick, gunKick)
CONVERT_ATTRIBUTE(AttViewKick, viewKick)
CONVERT_ATTRIBUTE(AttADSOverlay, adsOverlay)
CONVERT_ATTRIBUTE(AttUI, ui)
CONVERT_ATTRIBUTE(AttRumbles, rumbles)
CONVERT_ATTRIBUTE(AttProjectile, projectile)
attachment.ammunitionScale = jAttachment.ammunitionScale;
attachment.damageScale = jAttachment.damageScale;
attachment.damageScaleMin = jAttachment.damageScaleMin;
attachment.stateTimersScale = jAttachment.stateTimersScale;
attachment.fireTimersScale = jAttachment.fireTimersScale;
attachment.idleSettingsScale = jAttachment.idleSettingsScale;
attachment.adsSettingsScale = jAttachment.adsSettingsScale;
attachment.adsSettingsScaleMain = jAttachment.adsSettingsScaleMain;
attachment.hipSpreadScale = jAttachment.hipSpreadScale;
attachment.gunKickScale = jAttachment.gunKickScale;
attachment.viewKickScale = jAttachment.viewKickScale;
attachment.viewCenterScale = jAttachment.viewCenterScale;
attachment.loadIndex = jAttachment.loadIndex;
attachment.hideIronSightsWithThisAttachment = jAttachment.hideIronSightsWithThisAttachment;
attachment.shareAmmoWithAlt = jAttachment.shareAmmoWithAlt;
return true;
}
bool CreateTracerFromJson(const std::string& assetName, TracerDef*& tracerPtr, const WeaponAttachment& attachment) const
{
auto* tracer = static_cast<XAssetInfo<TracerDef>*>(m_manager.LoadDependency(ASSET_TYPE_TRACER, assetName));
if (!tracer)
{
PrintError(attachment, std::format("Could not find tracer {}", assetName));
return false;
}
m_dependencies.push_back(tracer);
tracerPtr = tracer->Asset();
return true;
}
bool CreateMaterialFromJson(const std::string& assetName, Material*& materialPtr, const WeaponAttachment& attachment) const
{
auto* material = static_cast<XAssetInfo<Material>*>(m_manager.LoadDependency(ASSET_TYPE_MATERIAL, assetName));
if (!material)
{
PrintError(attachment, std::format("Could not find material {}", assetName));
return false;
}
m_dependencies.push_back(material);
materialPtr = material->Asset();
return true;
}
bool CreateFxFromJson(const std::string& assetName, FxEffectDef*& fxPtr, const WeaponAttachment& attachment) const
{
auto* fx = static_cast<XAssetInfo<FxEffectDef>*>(m_manager.LoadDependency(ASSET_TYPE_FX, assetName));
if (!fx)
{
PrintError(attachment, std::format("Could not find fx {}", assetName));
return false;
}
m_dependencies.push_back(fx);
fxPtr = fx->Asset();
return true;
}
bool CreateSoundFromJson(const std::string& assetName, SndAliasCustom& sndAliasCustom, const WeaponAttachment& attachment) const
{
auto sound = m_manager.LoadIndirectAssetReference(ASSET_TYPE_SOUND, assetName);
m_indirect_asset_references.push_back(std::move(sound));
sndAliasCustom.name = static_cast<snd_alias_list_name*>(m_memory.Alloc(sizeof(snd_alias_list_name)));
sndAliasCustom.name->soundName = m_memory.Dup(assetName.c_str());
return true;
}
bool CreateXModelFromJson(const std::string& assetName, XModel*& xmodelPtr, const WeaponAttachment& attachment) const
{
auto* xmodel = static_cast<XAssetInfo<XModel>*>(m_manager.LoadDependency(ASSET_TYPE_XMODEL, assetName));
if (!xmodel)
{
PrintError(attachment, std::format("Could not find xmodel {}", assetName));
return false;
}
m_dependencies.push_back(xmodel);
xmodelPtr = xmodel->Asset();
return true;
}
bool CreateXModelArrayFromJson(const std::vector<std::string>& jXmodelArray,
XModel**& xmodelArray,
const char* propertyName,
size_t propertyCount,
const WeaponAttachment& attachment) const
{
if (!jXmodelArray.empty())
{
const auto arraySize = jXmodelArray.size();
if (arraySize > propertyCount)
{
PrintError(attachment, std::format("{} size cannot exceed {}", propertyName, propertyCount));
return false;
}
xmodelArray = static_cast<XModel**>(m_memory.Alloc(sizeof(void*) * propertyCount));
memset(xmodelArray, 0, sizeof(void*) * propertyCount);
for (auto i = 0u; i < arraySize; i++)
{
if (!CreateXModelFromJson(jXmodelArray[i], xmodelArray[i], attachment))
return false;
}
}
else
{
xmodelArray = nullptr;
}
return true;
}
bool CreateAttAmmoGeneralFromJson(const JsonAttAmmoGeneral& jAmmoGeneral, AttAmmoGeneral& ammoGeneral, const WeaponAttachment& attachment) const
{
ammoGeneral.penetrateType = jAmmoGeneral.penetrateType;
ammoGeneral.penetrateMultiplier = jAmmoGeneral.penetrateMultiplier;
ammoGeneral.impactType = jAmmoGeneral.impactType;
ammoGeneral.fireType = jAmmoGeneral.fireType;
if (jAmmoGeneral.tracerType)
{
if (!CreateTracerFromJson(jAmmoGeneral.tracerType.value(), ammoGeneral.tracerType, attachment))
return false;
}
else
ammoGeneral.tracerType = nullptr;
ammoGeneral.rifleBullet = jAmmoGeneral.rifleBullet;
ammoGeneral.armorPiercing = jAmmoGeneral.armorPiercing;
return true;
}
static bool CreateAttSightFromJson(const JsonAttSight& jSight, AttSight& sight, const WeaponAttachment& attachment)
{
sight.aimDownSight = jSight.aimDownSight;
sight.adsFire = jSight.adsFire;
sight.rechamberWhileAds = jSight.rechamberWhileAds;
sight.noAdsWhenMagEmpty = jSight.noAdsWhenMagEmpty;
sight.canHoldBreath = jSight.canHoldBreath;
sight.canVariableZoom = jSight.canVariableZoom;
sight.hideRailWithThisScope = jSight.hideRailWithThisScope;
return true;
}
static bool CreateAttReloadFromJson(const JsonAttReload& jReload, AttReload& reload, const WeaponAttachment& attachment)
{
reload.noPartialReload = jReload.noPartialReload;
reload.segmentedReload = jReload.segmentedReload;
return true;
}
static bool CreateAttAddOnsFromJson(const JsonAttAddOns& jAddOns, AttAddOns& addOns, const WeaponAttachment& attachment)
{
addOns.motionTracker = jAddOns.motionTracker;
addOns.silenced = jAddOns.silenced;
return true;
}
bool CreateAttGeneralFromJson(const JsonAttGeneral& jGeneral, AttGeneral& general, const WeaponAttachment& attachment) const
{
general.boltAction = jGeneral.boltAction;
general.inheritsPerks = jGeneral.inheritsPerks;
general.enemyCrosshairRange = jGeneral.enemyCrosshairRange;
if (jGeneral.reticleCenter)
{
if (!CreateMaterialFromJson(jGeneral.reticleCenter.value(), general.reticleCenter, attachment))
return false;
}
else
general.reticleCenter = nullptr;
if (jGeneral.reticleSide)
{
if (!CreateMaterialFromJson(jGeneral.reticleSide.value(), general.reticleSide, attachment))
return false;
}
else
general.reticleSide = nullptr;
general.reticleCenterSize = jGeneral.reticleCenterSize;
general.reticleSideSize = jGeneral.reticleSideSize;
general.moveSpeedScale = jGeneral.moveSpeedScale;
general.adsMoveSpeedScale = jGeneral.adsMoveSpeedScale;
return true;
}
static bool CreateAttAimAssistFromJson(const JsonAttAimAssist& jAimAssist, AttAimAssist& aimAssist, const WeaponAttachment& attachment)
{
aimAssist.autoAimRange = jAimAssist.autoAimRange;
aimAssist.aimAssistRange = jAimAssist.aimAssistRange;
aimAssist.aimAssistRangeAds = jAimAssist.aimAssistRangeAds;
return true;
}
static bool CreateAttAmmunitionFromJson(const JsonAttAmmunition& jAmmunition, AttAmmunition& ammunition, const WeaponAttachment& attachment)
{
ammunition.maxAmmo = jAmmunition.maxAmmo;
ammunition.startAmmo = jAmmunition.startAmmo;
ammunition.clipSize = jAmmunition.clipSize;
ammunition.shotCount = jAmmunition.shotCount;
ammunition.reloadAmmoAdd = jAmmunition.reloadAmmoAdd;
ammunition.reloadStartAdd = jAmmunition.reloadStartAdd;
return true;
}
static bool CreateAttDamageFromJson(const JsonAttDamage& jDamage, AttDamage& damage, const WeaponAttachment& attachment)
{
damage.damage = jDamage.damage;
damage.minDamage = jDamage.minDamage;
damage.meleeDamage = jDamage.meleeDamage;
damage.maxDamageRange = jDamage.maxDamageRange;
damage.minDamageRange = jDamage.minDamageRange;
damage.playerDamage = jDamage.playerDamage;
damage.minPlayerDamage = jDamage.minPlayerDamage;
return true;
}
static bool
CreateAttLocationDamageFromJson(const JsonAttLocationDamage& jLocationDamage, AttLocationDamage& locationDamage, const WeaponAttachment& attachment)
{
locationDamage.locNone = jLocationDamage.locNone;
locationDamage.locHelmet = jLocationDamage.locHelmet;
locationDamage.locHead = jLocationDamage.locHead;
locationDamage.locNeck = jLocationDamage.locNeck;
locationDamage.locTorsoUpper = jLocationDamage.locTorsoUpper;
locationDamage.locTorsoLower = jLocationDamage.locTorsoLower;
locationDamage.locRightArmUpper = jLocationDamage.locRightArmUpper;
locationDamage.locRightArmLower = jLocationDamage.locRightArmLower;
locationDamage.locRightHand = jLocationDamage.locRightHand;
locationDamage.locLeftArmUpper = jLocationDamage.locLeftArmUpper;
locationDamage.locLeftArmLower = jLocationDamage.locLeftArmLower;
locationDamage.locLeftHand = jLocationDamage.locLeftHand;
locationDamage.locRightLegUpper = jLocationDamage.locRightLegUpper;
locationDamage.locRightLegLower = jLocationDamage.locRightLegLower;
locationDamage.locRightFoot = jLocationDamage.locRightFoot;
locationDamage.locLeftLegUpper = jLocationDamage.locLeftLegUpper;
locationDamage.locLeftLegLower = jLocationDamage.locLeftLegLower;
locationDamage.locLeftFoot = jLocationDamage.locLeftFoot;
locationDamage.locGun = jLocationDamage.locGun;
return true;
}
static bool CreateAttIdleSettingsFromJson(const JsonAttIdleSettings& jIdleSettings, AttIdleSettings& idleSettings, const WeaponAttachment& attachment)
{
idleSettings.hipIdleAmount = jIdleSettings.hipIdleAmount;
idleSettings.hipIdleSpeed = jIdleSettings.hipIdleSpeed;
idleSettings.idleCrouchFactor = jIdleSettings.idleCrouchFactor;
idleSettings.idleProneFactor = jIdleSettings.idleProneFactor;
idleSettings.adsIdleLerpStartTime = jIdleSettings.adsIdleLerpStartTime;
idleSettings.adsIdleLerpTime = jIdleSettings.adsIdleLerpTime;
return true;
}
static bool CreateAttADSSettingsFromJson(const JsonAttADSSettings& jAdsSettings, AttADSSettings& adsSettings, const WeaponAttachment& attachment)
{
adsSettings.adsSpread = jAdsSettings.adsSpread;
adsSettings.adsAimPitch = jAdsSettings.adsAimPitch;
adsSettings.adsTransInTime = jAdsSettings.adsTransInTime;
adsSettings.adsTransOutTime = jAdsSettings.adsTransOutTime;
adsSettings.adsReloadTransTime = jAdsSettings.adsReloadTransTime;
adsSettings.adsCrosshairInFrac = jAdsSettings.adsCrosshairInFrac;
adsSettings.adsCrosshairOutFrac = jAdsSettings.adsCrosshairOutFrac;
adsSettings.adsZoomFov = jAdsSettings.adsZoomFov;
adsSettings.adsZoomInFrac = jAdsSettings.adsZoomInFrac;
adsSettings.adsZoomOutFrac = jAdsSettings.adsZoomOutFrac;
adsSettings.adsBobFactor = jAdsSettings.adsBobFactor;
adsSettings.adsViewBobMult = jAdsSettings.adsViewBobMult;
adsSettings.adsViewErrorMin = jAdsSettings.adsViewErrorMin;
adsSettings.adsViewErrorMax = jAdsSettings.adsViewErrorMax;
return true;
}
static bool CreateAttHipSpreadFromJson(const JsonAttHipSpread& jHipSpread, AttHipSpread& hipSpread, const WeaponAttachment& attachment)
{
hipSpread.hipSpreadStandMin = jHipSpread.hipSpreadStandMin;
hipSpread.hipSpreadDuckedMin = jHipSpread.hipSpreadDuckedMin;
hipSpread.hipSpreadProneMin = jHipSpread.hipSpreadProneMin;
hipSpread.hipSpreadMax = jHipSpread.hipSpreadMax;
hipSpread.hipSpreadDuckedMax = jHipSpread.hipSpreadDuckedMax;
hipSpread.hipSpreadProneMax = jHipSpread.hipSpreadProneMax;
hipSpread.hipSpreadFireAdd = jHipSpread.hipSpreadFireAdd;
hipSpread.hipSpreadTurnAdd = jHipSpread.hipSpreadTurnAdd;
hipSpread.hipSpreadMoveAdd = jHipSpread.hipSpreadMoveAdd;
hipSpread.hipSpreadDecayRate = jHipSpread.hipSpreadDecayRate;
hipSpread.hipSpreadDuckedDecay = jHipSpread.hipSpreadDuckedDecay;
hipSpread.hipSpreadProneDecay = jHipSpread.hipSpreadProneDecay;
return true;
}
static bool CreateAttGunKickFromJson(const JsonAttGunKick& jGunKick, AttGunKick& gunKick, const WeaponAttachment& attachment)
{
gunKick.hipGunKickReducedKickBullets = jGunKick.hipGunKickReducedKickBullets;
gunKick.hipGunKickReducedKickPercent = jGunKick.hipGunKickReducedKickPercent;
gunKick.hipGunKickPitchMin = jGunKick.hipGunKickPitchMin;
gunKick.hipGunKickPitchMax = jGunKick.hipGunKickPitchMax;
gunKick.hipGunKickYawMin = jGunKick.hipGunKickYawMin;
gunKick.hipGunKickYawMax = jGunKick.hipGunKickYawMax;
gunKick.hipGunKickAccel = jGunKick.hipGunKickAccel;
gunKick.hipGunKickSpeedMax = jGunKick.hipGunKickSpeedMax;
gunKick.hipGunKickSpeedDecay = jGunKick.hipGunKickSpeedDecay;
gunKick.hipGunKickStaticDecay = jGunKick.hipGunKickStaticDecay;
gunKick.adsGunKickReducedKickBullets = jGunKick.adsGunKickReducedKickBullets;
gunKick.adsGunKickReducedKickPercent = jGunKick.adsGunKickReducedKickPercent;
gunKick.adsGunKickPitchMin = jGunKick.adsGunKickPitchMin;
gunKick.adsGunKickPitchMax = jGunKick.adsGunKickPitchMax;
gunKick.adsGunKickYawMin = jGunKick.adsGunKickYawMin;
gunKick.adsGunKickYawMax = jGunKick.adsGunKickYawMax;
gunKick.adsGunKickAccel = jGunKick.adsGunKickAccel;
gunKick.adsGunKickSpeedMax = jGunKick.adsGunKickSpeedMax;
gunKick.adsGunKickSpeedDecay = jGunKick.adsGunKickSpeedDecay;
gunKick.adsGunKickStaticDecay = jGunKick.adsGunKickStaticDecay;
return true;
}
static bool CreateAttViewKickFromJson(const JsonAttViewKick& jViewKick, AttViewKick& viewKick, const WeaponAttachment& attachment)
{
viewKick.hipViewKickPitchMin = jViewKick.hipViewKickPitchMin;
viewKick.hipViewKickPitchMax = jViewKick.hipViewKickPitchMax;
viewKick.hipViewKickYawMin = jViewKick.hipViewKickYawMin;
viewKick.hipViewKickYawMax = jViewKick.hipViewKickYawMax;
viewKick.hipViewKickCenterSpeed = jViewKick.hipViewKickCenterSpeed;
viewKick.adsViewKickPitchMin = jViewKick.adsViewKickPitchMin;
viewKick.adsViewKickPitchMax = jViewKick.adsViewKickPitchMax;
viewKick.adsViewKickYawMin = jViewKick.adsViewKickYawMin;
viewKick.adsViewKickYawMax = jViewKick.adsViewKickYawMax;
viewKick.adsViewKickCenterSpeed = jViewKick.adsViewKickCenterSpeed;
return true;
}
bool CreateAttADSOverlayFromJson(const JsonAttADSOverlay& jAdsOverlay, AttADSOverlay& adsOverlay, const WeaponAttachment& attachment) const
{
if (jAdsOverlay.shader)
{
if (!CreateMaterialFromJson(jAdsOverlay.shader.value(), adsOverlay.overlay.shader, attachment))
return false;
}
else
adsOverlay.overlay.shader = nullptr;
if (jAdsOverlay.shaderLowRes)
{
if (!CreateMaterialFromJson(jAdsOverlay.shaderLowRes.value(), adsOverlay.overlay.shaderLowRes, attachment))
return false;
}
else
adsOverlay.overlay.shaderLowRes = nullptr;
if (jAdsOverlay.shaderEMP)
{
if (!CreateMaterialFromJson(jAdsOverlay.shaderEMP.value(), adsOverlay.overlay.shaderEMP, attachment))
return false;
}
else
adsOverlay.overlay.shaderEMP = nullptr;
if (jAdsOverlay.shaderEMPLowRes)
{
if (!CreateMaterialFromJson(jAdsOverlay.shaderEMPLowRes.value(), adsOverlay.overlay.shaderEMPLowRes, attachment))
return false;
}
else
adsOverlay.overlay.shaderEMPLowRes = nullptr;
adsOverlay.overlay.reticle = jAdsOverlay.reticle;
adsOverlay.overlay.width = jAdsOverlay.width;
adsOverlay.overlay.height = jAdsOverlay.height;
adsOverlay.overlay.widthSplitscreen = jAdsOverlay.widthSplitscreen;
adsOverlay.overlay.heightSplitscreen = jAdsOverlay.heightSplitscreen;
adsOverlay.thermalScope = jAdsOverlay.thermalScope;
return true;
}
bool CreateAttUIFromJson(const JsonAttUI& jUi, AttUI& ui, const WeaponAttachment& attachment) const
{
if (jUi.dpadIcon)
{
if (!CreateMaterialFromJson(jUi.dpadIcon.value(), ui.dpadIcon, attachment))
return false;
}
else
ui.dpadIcon = nullptr;
if (jUi.ammoCounterIcon)
{
if (!CreateMaterialFromJson(jUi.ammoCounterIcon.value(), ui.ammoCounterIcon, attachment))
return false;
}
else
ui.ammoCounterIcon = nullptr;
ui.dpadIconRatio = jUi.dpadIconRatio;
ui.ammoCounterIconRatio = jUi.ammoCounterIconRatio;
ui.ammoCounterClip = jUi.ammoCounterClip;
return true;
}
bool CreateAttRumblesFromJson(const JsonAttRumbles& jRumbles, AttRumbles& rumbles, const WeaponAttachment& attachment) const
{
if (jRumbles.fireRumble)
rumbles.fireRumble = m_memory.Dup(jRumbles.fireRumble.value().c_str());
if (jRumbles.meleeImpactRumble)
rumbles.meleeImpactRumble = m_memory.Dup(jRumbles.meleeImpactRumble.value().c_str());
return true;
}
bool CreateAttProjectileFromJson(const JsonAttProjectile& jProjectile, AttProjectile& projectile, const WeaponAttachment& attachment) const
{
projectile.explosionRadius = jProjectile.explosionRadius;
projectile.explosionInnerDamage = jProjectile.explosionInnerDamage;
projectile.explosionOuterDamage = jProjectile.explosionOuterDamage;
projectile.damageConeAngle = jProjectile.damageConeAngle;
projectile.projectileSpeed = jProjectile.projectileSpeed;
projectile.projectileSpeedUp = jProjectile.projectileSpeedUp;
projectile.projectileActivateDist = jProjectile.projectileActivateDist;
projectile.projectileLifetime = jProjectile.projectileLifetime;
if (jProjectile.projectileModel)
{
if (!CreateXModelFromJson(jProjectile.projectileModel.value(), projectile.projectileModel, attachment))
return false;
}
else
projectile.projectileModel = nullptr;
projectile.projExplosionType = jProjectile.projExplosionType;
if (jProjectile.projExplosionEffect)
{
if (!CreateFxFromJson(jProjectile.projExplosionEffect.value(), projectile.projExplosionEffect, attachment))
return false;
}
else
projectile.projExplosionEffect = nullptr;
projectile.projExplosionEffectForceNormalUp = jProjectile.projExplosionEffectForceNormalUp;
if (jProjectile.projExplosionSound)
{
if (!CreateSoundFromJson(jProjectile.projExplosionSound.value(), projectile.projExplosionSound, attachment))
return false;
}
else
projectile.projExplosionSound.name = nullptr;
if (jProjectile.projDudEffect)
{
if (!CreateFxFromJson(jProjectile.projDudEffect.value(), projectile.projDudEffect, attachment))
return false;
}
else
projectile.projDudEffect = nullptr;
if (jProjectile.projDudSound)
{
if (!CreateSoundFromJson(jProjectile.projDudSound.value(), projectile.projDudSound, attachment))
return false;
}
else
projectile.projDudSound.name = nullptr;
projectile.projImpactExplode = jProjectile.projImpactExplode;
projectile.destabilizationRateTime = jProjectile.destabilizationRateTime;
projectile.destabilizationCurvatureMax = jProjectile.destabilizationCurvatureMax;
projectile.destabilizeDistance = jProjectile.destabilizeDistance;
if (jProjectile.projTrailEffect)
{
if (!CreateFxFromJson(jProjectile.projTrailEffect.value(), projectile.projTrailEffect, attachment))
return false;
}
else
projectile.projTrailEffect = nullptr;
projectile.projIgnitionDelay = jProjectile.projIgnitionDelay;
if (jProjectile.projIgnitionEffect)
{
if (!CreateFxFromJson(jProjectile.projIgnitionEffect.value(), projectile.projIgnitionEffect, attachment))
return false;
}
else
projectile.projIgnitionEffect = nullptr;
if (jProjectile.projIgnitionSound)
{
if (!CreateSoundFromJson(jProjectile.projIgnitionSound.value(), projectile.projIgnitionSound, attachment))
return false;
}
else
projectile.projIgnitionSound.name = nullptr;
return true;
}
std::istream& m_stream;
MemoryManager& m_memory;
IAssetLoadingManager& m_manager;
std::vector<XAssetInfoGeneric*>& m_dependencies;
std::vector<IndirectAssetReference>& m_indirect_asset_references;
};
} // namespace
namespace IW5
{
bool LoadWeaponAttachmentAsJson(std::istream& stream,
WeaponAttachment& attachment,
MemoryManager* memory,
IAssetLoadingManager* manager,
std::vector<XAssetInfoGeneric*>& dependencies,
std::vector<IndirectAssetReference>& indirectAssetReferences)
{
const JsonLoader loader(stream, *memory, *manager, dependencies, indirectAssetReferences);
return loader.Load(attachment);
}
} // namespace IW5

View File

@ -0,0 +1,17 @@
#pragma once
#include "AssetLoading/IAssetLoadingManager.h"
#include "Game/IW5/IW5.h"
#include "Utils/MemoryManager.h"
#include <istream>
namespace IW5
{
bool LoadWeaponAttachmentAsJson(std::istream& stream,
WeaponAttachment& attachment,
MemoryManager* memory,
IAssetLoadingManager* manager,
std::vector<XAssetInfoGeneric*>& dependencies,
std::vector<IndirectAssetReference>& indirectAssetReferences);
} // namespace IW5