mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-06-26 10:58:04 +00:00
feat: t6 flametables (#845)
* feat: add flametable loading and dumping for T6 * chore: add additional validation logic of game for t6 weapon loading
This commit is contained in:
@@ -77,6 +77,7 @@ namespace
|
|||||||
"vertexdecl",
|
"vertexdecl",
|
||||||
"vertexshader",
|
"vertexshader",
|
||||||
"pixelshader",
|
"pixelshader",
|
||||||
|
"flametable",
|
||||||
};
|
};
|
||||||
static_assert(std::extent_v<decltype(SUB_ASSET_TYPE_NAMES)> == SUB_ASSET_TYPE_COUNT);
|
static_assert(std::extent_v<decltype(SUB_ASSET_TYPE_NAMES)> == SUB_ASSET_TYPE_COUNT);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ namespace T6
|
|||||||
SUB_ASSET_TYPE_VERTEX_DECL,
|
SUB_ASSET_TYPE_VERTEX_DECL,
|
||||||
SUB_ASSET_TYPE_VERTEX_SHADER,
|
SUB_ASSET_TYPE_VERTEX_SHADER,
|
||||||
SUB_ASSET_TYPE_PIXEL_SHADER,
|
SUB_ASSET_TYPE_PIXEL_SHADER,
|
||||||
|
SUB_ASSET_TYPE_FLAME_TABLE,
|
||||||
|
|
||||||
SUB_ASSET_TYPE_COUNT
|
SUB_ASSET_TYPE_COUNT
|
||||||
};
|
};
|
||||||
@@ -292,6 +293,7 @@ namespace T6
|
|||||||
using SubAssetVertexDecl = SubAsset<SUB_ASSET_TYPE_VERTEX_DECL, MaterialVertexDeclaration>;
|
using SubAssetVertexDecl = SubAsset<SUB_ASSET_TYPE_VERTEX_DECL, MaterialVertexDeclaration>;
|
||||||
using SubAssetVertexShader = SubAsset<SUB_ASSET_TYPE_VERTEX_SHADER, MaterialVertexShader>;
|
using SubAssetVertexShader = SubAsset<SUB_ASSET_TYPE_VERTEX_SHADER, MaterialVertexShader>;
|
||||||
using SubAssetPixelShader = SubAsset<SUB_ASSET_TYPE_PIXEL_SHADER, MaterialPixelShader>;
|
using SubAssetPixelShader = SubAsset<SUB_ASSET_TYPE_PIXEL_SHADER, MaterialPixelShader>;
|
||||||
|
using SubAssetFlameTable = SubAsset<SUB_ASSET_TYPE_FLAME_TABLE, FlameTable>;
|
||||||
} // namespace T6
|
} // namespace T6
|
||||||
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetPhysPreset, name);
|
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetPhysPreset, name);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace T6
|
namespace T6
|
||||||
{
|
{
|
||||||
|
static constexpr auto INFO_STRING_PREFIX_FLAME_TABLE = "FLAMETABLEFILE";
|
||||||
static constexpr auto INFO_STRING_PREFIX_PHYS_CONSTRAINTS = "PHYSCONSTRAINTS";
|
static constexpr auto INFO_STRING_PREFIX_PHYS_CONSTRAINTS = "PHYSCONSTRAINTS";
|
||||||
static constexpr auto INFO_STRING_PREFIX_PHYS_PRESET = "PHYSIC";
|
static constexpr auto INFO_STRING_PREFIX_PHYS_PRESET = "PHYSIC";
|
||||||
static constexpr auto INFO_STRING_PREFIX_TRACER = "TRACER";
|
static constexpr auto INFO_STRING_PREFIX_TRACER = "TRACER";
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Game/T6/T6.h"
|
||||||
|
|
||||||
|
namespace T6
|
||||||
|
{
|
||||||
|
inline cspField_t flameTableFields[]{
|
||||||
|
{"flameVar_streamChunkGravityStart", offsetof(FlameTable, flameVar_streamChunkGravityStart), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkGravityEnd", offsetof(FlameTable, flameVar_streamChunkGravityEnd), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkMaxSize", offsetof(FlameTable, flameVar_streamChunkMaxSize), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkStartSize", offsetof(FlameTable, flameVar_streamChunkStartSize), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkEndSize", offsetof(FlameTable, flameVar_streamChunkEndSize), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkStartSizeRand", offsetof(FlameTable, flameVar_streamChunkStartSizeRand), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkEndSizeRand", offsetof(FlameTable, flameVar_streamChunkEndSizeRand), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkDistScalar", offsetof(FlameTable, flameVar_streamChunkDistScalar), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkDistSwayScale", offsetof(FlameTable, flameVar_streamChunkDistSwayScale), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkDistSwayVelMax", offsetof(FlameTable, flameVar_streamChunkDistSwayVelMax), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkSpeed", offsetof(FlameTable, flameVar_streamChunkSpeed), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkDecel", offsetof(FlameTable, flameVar_streamChunkDecel), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkVelocityAddScale", offsetof(FlameTable, flameVar_streamChunkVelocityAddScale), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkDuration", offsetof(FlameTable, flameVar_streamChunkDuration), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkDurationScaleMaxVel", offsetof(FlameTable, flameVar_streamChunkDurationScaleMaxVel), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkDurationVelScalar", offsetof(FlameTable, flameVar_streamChunkDurationVelScalar), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkSizeSpeedScale", offsetof(FlameTable, flameVar_streamChunkSizeSpeedScale), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkSizeAgeScale", offsetof(FlameTable, flameVar_streamChunkSizeAgeScale), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkSpawnFireIntervalStart", offsetof(FlameTable, flameVar_streamChunkSpawnFireIntervalStart), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkSpawnFireIntervalEnd", offsetof(FlameTable, flameVar_streamChunkSpawnFireIntervalEnd), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkSpawnFireMinLifeFrac", offsetof(FlameTable, flameVar_streamChunkSpawnFireMinLifeFrac), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkSpawnFireMaxLifeFrac", offsetof(FlameTable, flameVar_streamChunkSpawnFireMaxLifeFrac), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkFireMinLifeFrac", offsetof(FlameTable, flameVar_streamChunkFireMinLifeFrac), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkFireMinLifeFracStart", offsetof(FlameTable, flameVar_streamChunkFireMinLifeFracStart), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkFireMinLifeFracEnd", offsetof(FlameTable, flameVar_streamChunkFireMinLifeFracEnd), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkDripsMinLifeFrac", offsetof(FlameTable, flameVar_streamChunkDripsMinLifeFrac), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkDripsMinLifeFracStart", offsetof(FlameTable, flameVar_streamChunkDripsMinLifeFracStart), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkDripsMinLifeFracEnd", offsetof(FlameTable, flameVar_streamChunkDripsMinLifeFracEnd), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkRotationRange", offsetof(FlameTable, flameVar_streamChunkRotationRange), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamSizeRandSinWave", offsetof(FlameTable, flameVar_streamSizeRandSinWave), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamSizeRandCosWave", offsetof(FlameTable, flameVar_streamSizeRandCosWave), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamDripsChunkInterval", offsetof(FlameTable, flameVar_streamDripsChunkInterval), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamDripsChunkMinFrac", offsetof(FlameTable, flameVar_streamDripsChunkMinFrac), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamDripsChunkRandFrac", offsetof(FlameTable, flameVar_streamDripsChunkRandFrac), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamSmokeChunkInterval", offsetof(FlameTable, flameVar_streamSmokeChunkInterval), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamSmokeChunkMinFrac", offsetof(FlameTable, flameVar_streamSmokeChunkMinFrac), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamSmokeChunkRandFrac", offsetof(FlameTable, flameVar_streamSmokeChunkRandFrac), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkCullDistSizeFrac", offsetof(FlameTable, flameVar_streamChunkCullDistSizeFrac), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkCullMinLife", offsetof(FlameTable, flameVar_streamChunkCullMinLife), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamChunkCullMaxLife", offsetof(FlameTable, flameVar_streamChunkCullMaxLife), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamFuelSizeStart", offsetof(FlameTable, flameVar_streamFuelSizeStart), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamFuelSizeEnd", offsetof(FlameTable, flameVar_streamFuelSizeEnd), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamFuelLength", offsetof(FlameTable, flameVar_streamFuelLength), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamFuelNumSegments", offsetof(FlameTable, flameVar_streamFuelNumSegments), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamFuelAnimLoopTime", offsetof(FlameTable, flameVar_streamFuelAnimLoopTime), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamFlameSizeStart", offsetof(FlameTable, flameVar_streamFlameSizeStart), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamFlameSizeEnd", offsetof(FlameTable, flameVar_streamFlameSizeEnd), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamFlameLength", offsetof(FlameTable, flameVar_streamFlameLength), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamFlameNumSegments", offsetof(FlameTable, flameVar_streamFlameNumSegments), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamFlameAnimLoopTime", offsetof(FlameTable, flameVar_streamFlameAnimLoopTime), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamPrimaryLightRadius", offsetof(FlameTable, flameVar_streamPrimaryLightRadius), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamPrimaryLightRadiusFlutter", offsetof(FlameTable, flameVar_streamPrimaryLightRadiusFlutter), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamPrimaryLightR", offsetof(FlameTable, flameVar_streamPrimaryLightR), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamPrimaryLightG", offsetof(FlameTable, flameVar_streamPrimaryLightG), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamPrimaryLightB", offsetof(FlameTable, flameVar_streamPrimaryLightB), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamPrimaryLightFlutterR", offsetof(FlameTable, flameVar_streamPrimaryLightFlutterR), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamPrimaryLightFlutterG", offsetof(FlameTable, flameVar_streamPrimaryLightFlutterG), CSPFT_FLOAT },
|
||||||
|
{"flameVar_streamPrimaryLightFlutterB", offsetof(FlameTable, flameVar_streamPrimaryLightFlutterB), CSPFT_FLOAT },
|
||||||
|
{"flameVar_fireLife", offsetof(FlameTable, flameVar_fireLife), CSPFT_FLOAT },
|
||||||
|
{"flameVar_fireLifeRand", offsetof(FlameTable, flameVar_fireLifeRand), CSPFT_FLOAT },
|
||||||
|
{"flameVar_fireSpeedScale", offsetof(FlameTable, flameVar_fireSpeedScale), CSPFT_FLOAT },
|
||||||
|
{"flameVar_fireSpeedScaleRand", offsetof(FlameTable, flameVar_fireSpeedScaleRand), CSPFT_FLOAT },
|
||||||
|
{"flameVar_fireVelocityAddZ", offsetof(FlameTable, flameVar_fireVelocityAddZ), CSPFT_FLOAT },
|
||||||
|
{"flameVar_fireVelocityAddZRand", offsetof(FlameTable, flameVar_fireVelocityAddZRand), CSPFT_FLOAT },
|
||||||
|
{"flameVar_fireVelocityAddSideways", offsetof(FlameTable, flameVar_fireVelocityAddSideways), CSPFT_FLOAT },
|
||||||
|
{"flameVar_fireGravity", offsetof(FlameTable, flameVar_fireGravity), CSPFT_FLOAT },
|
||||||
|
{"flameVar_fireGravityEnd", offsetof(FlameTable, flameVar_fireGravityEnd), CSPFT_FLOAT },
|
||||||
|
{"flameVar_fireMaxRotVel", offsetof(FlameTable, flameVar_fireMaxRotVel), CSPFT_FLOAT },
|
||||||
|
{"flameVar_fireFriction", offsetof(FlameTable, flameVar_fireFriction), CSPFT_FLOAT },
|
||||||
|
{"flameVar_fireEndSizeAdd", offsetof(FlameTable, flameVar_fireEndSizeAdd), CSPFT_FLOAT },
|
||||||
|
{"flameVar_fireStartSizeScale", offsetof(FlameTable, flameVar_fireStartSizeScale), CSPFT_FLOAT },
|
||||||
|
{"flameVar_fireEndSizeScale", offsetof(FlameTable, flameVar_fireEndSizeScale), CSPFT_FLOAT },
|
||||||
|
{"flameVar_fireBrightness", offsetof(FlameTable, flameVar_fireBrightness), CSPFT_FLOAT },
|
||||||
|
{"flameVar_dripsLife", offsetof(FlameTable, flameVar_dripsLife), CSPFT_FLOAT },
|
||||||
|
{"flameVar_dripsLifeRand", offsetof(FlameTable, flameVar_dripsLifeRand), CSPFT_FLOAT },
|
||||||
|
{"flameVar_dripsSpeedScale", offsetof(FlameTable, flameVar_dripsSpeedScale), CSPFT_FLOAT },
|
||||||
|
{"flameVar_dripsSpeedScaleRand", offsetof(FlameTable, flameVar_dripsSpeedScaleRand), CSPFT_FLOAT },
|
||||||
|
{"flameVar_dripsVelocityAddZ", offsetof(FlameTable, flameVar_dripsVelocityAddZ), CSPFT_FLOAT },
|
||||||
|
{"flameVar_dripsVelocityAddZRand", offsetof(FlameTable, flameVar_dripsVelocityAddZRand), CSPFT_FLOAT },
|
||||||
|
{"flameVar_dripsVelocityAddSideways", offsetof(FlameTable, flameVar_dripsVelocityAddSideways), CSPFT_FLOAT },
|
||||||
|
{"flameVar_dripsGravity", offsetof(FlameTable, flameVar_dripsGravity), CSPFT_FLOAT },
|
||||||
|
{"flameVar_dripsGravityEnd", offsetof(FlameTable, flameVar_dripsGravityEnd), CSPFT_FLOAT },
|
||||||
|
{"flameVar_dripsMaxRotVel", offsetof(FlameTable, flameVar_dripsMaxRotVel), CSPFT_FLOAT },
|
||||||
|
{"flameVar_dripsFriction", offsetof(FlameTable, flameVar_dripsFriction), CSPFT_FLOAT },
|
||||||
|
{"flameVar_dripsEndSizeAdd", offsetof(FlameTable, flameVar_dripsEndSizeAdd), CSPFT_FLOAT },
|
||||||
|
{"flameVar_dripsStartSizeScale", offsetof(FlameTable, flameVar_dripsStartSizeScale), CSPFT_FLOAT },
|
||||||
|
{"flameVar_dripsEndSizeScale", offsetof(FlameTable, flameVar_dripsEndSizeScale), CSPFT_FLOAT },
|
||||||
|
{"flameVar_dripsBrightness", offsetof(FlameTable, flameVar_dripsBrightness), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeLife", offsetof(FlameTable, flameVar_smokeLife), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeLifeRand", offsetof(FlameTable, flameVar_smokeLifeRand), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeSpeedScale", offsetof(FlameTable, flameVar_smokeSpeedScale), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeVelocityAddZ", offsetof(FlameTable, flameVar_smokeVelocityAddZ), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeGravity", offsetof(FlameTable, flameVar_smokeGravity), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeGravityEnd", offsetof(FlameTable, flameVar_smokeGravityEnd), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeMaxRotation", offsetof(FlameTable, flameVar_smokeMaxRotation), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeMaxRotVel", offsetof(FlameTable, flameVar_smokeMaxRotVel), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeFriction", offsetof(FlameTable, flameVar_smokeFriction), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeEndSizeAdd", offsetof(FlameTable, flameVar_smokeEndSizeAdd), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeStartSizeAdd", offsetof(FlameTable, flameVar_smokeStartSizeAdd), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeOriginSizeOfsZScale", offsetof(FlameTable, flameVar_smokeOriginSizeOfsZScale), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeOriginOfsZ", offsetof(FlameTable, flameVar_smokeOriginOfsZ), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeFadein", offsetof(FlameTable, flameVar_smokeFadein), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeFadeout", offsetof(FlameTable, flameVar_smokeFadeout), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeMaxAlpha", offsetof(FlameTable, flameVar_smokeMaxAlpha), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeBrightness", offsetof(FlameTable, flameVar_smokeBrightness), CSPFT_FLOAT },
|
||||||
|
{"flameVar_smokeOriginOffset", offsetof(FlameTable, flameVar_smokeOriginOffset), CSPFT_FLOAT },
|
||||||
|
{"flameVar_collisionSpeedScale", offsetof(FlameTable, flameVar_collisionSpeedScale), CSPFT_FLOAT },
|
||||||
|
{"flameVar_collisionVolumeScale", offsetof(FlameTable, flameVar_collisionVolumeScale), CSPFT_FLOAT },
|
||||||
|
{"name", offsetof(FlameTable, name), CSPFT_STRING },
|
||||||
|
{"fire", offsetof(FlameTable, fire), CSPFT_MATERIAL},
|
||||||
|
{"smoke", offsetof(FlameTable, smoke), CSPFT_MATERIAL},
|
||||||
|
{"heat", offsetof(FlameTable, heat), CSPFT_MATERIAL},
|
||||||
|
{"drips", offsetof(FlameTable, drips), CSPFT_MATERIAL},
|
||||||
|
{"streamFuel", offsetof(FlameTable, streamFuel), CSPFT_MATERIAL},
|
||||||
|
{"streamFuel2", offsetof(FlameTable, streamFuel2), CSPFT_MATERIAL},
|
||||||
|
{"streamFlame", offsetof(FlameTable, streamFlame), CSPFT_MATERIAL},
|
||||||
|
{"streamFlame2", offsetof(FlameTable, streamFlame2), CSPFT_MATERIAL},
|
||||||
|
{"flameOffLoopSound", offsetof(FlameTable, flameOffLoopSound), CSPFT_STRING },
|
||||||
|
{"flameIgniteSound", offsetof(FlameTable, flameIgniteSound), CSPFT_STRING },
|
||||||
|
{"flameOnLoopSound", offsetof(FlameTable, flameOnLoopSound), CSPFT_STRING },
|
||||||
|
{"flameCooldownSound", offsetof(FlameTable, flameCooldownSound), CSPFT_STRING },
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -43,6 +43,7 @@
|
|||||||
#include "Weapon/AttachmentUniqueGdtLoaderT6.h"
|
#include "Weapon/AttachmentUniqueGdtLoaderT6.h"
|
||||||
#include "Weapon/AttachmentUniqueRawLoaderT6.h"
|
#include "Weapon/AttachmentUniqueRawLoaderT6.h"
|
||||||
#include "Weapon/CamoJsonLoaderT6.h"
|
#include "Weapon/CamoJsonLoaderT6.h"
|
||||||
|
#include "Weapon/FlameTableLoaderT6.h"
|
||||||
#include "Weapon/WeaponGdtLoaderT6.h"
|
#include "Weapon/WeaponGdtLoaderT6.h"
|
||||||
#include "Weapon/WeaponRawLoaderT6.h"
|
#include "Weapon/WeaponRawLoaderT6.h"
|
||||||
#include "ZBarrier/GdtLoaderZBarrierT6.h"
|
#include "ZBarrier/GdtLoaderZBarrierT6.h"
|
||||||
@@ -441,6 +442,7 @@ namespace T6
|
|||||||
|
|
||||||
collection.AddSubAssetCreator(techset::CreateVertexShaderLoaderT6(memory, searchPath));
|
collection.AddSubAssetCreator(techset::CreateVertexShaderLoaderT6(memory, searchPath));
|
||||||
collection.AddSubAssetCreator(techset::CreatePixelShaderLoaderT6(memory, searchPath));
|
collection.AddSubAssetCreator(techset::CreatePixelShaderLoaderT6(memory, searchPath));
|
||||||
|
collection.AddSubAssetCreator(weapon::CreateFlameTableLoaderT6(memory, searchPath, zone));
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
#include "FlameTableLoaderT6.h"
|
||||||
|
|
||||||
|
#include "Game/T6/InfoString/InfoStringToStructConverter.h"
|
||||||
|
#include "Game/T6/ObjConstantsT6.h"
|
||||||
|
#include "Game/T6/T6.h"
|
||||||
|
#include "Game/T6/Weapon/FlameTableFields.h"
|
||||||
|
#include "Weapon/WeaponCommon.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <format>
|
||||||
|
|
||||||
|
using namespace T6;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class InfoStringToFlameTableConverter final : public InfoStringToStructConverter
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
bool ConvertExtensionField(const cspField_t& field, const std::string& value) override
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
InfoStringToFlameTableConverter(const InfoString& infoString,
|
||||||
|
FlameTable& flameTable,
|
||||||
|
ZoneScriptStrings& zoneScriptStrings,
|
||||||
|
MemoryManager& memory,
|
||||||
|
AssetCreationContext& context,
|
||||||
|
AssetRegistration<SubAssetFlameTable>& registration,
|
||||||
|
const cspField_t* fields,
|
||||||
|
const size_t fieldCount)
|
||||||
|
: InfoStringToStructConverter(infoString, &flameTable, zoneScriptStrings, memory, context, registration, fields, fieldCount)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class FlameTableLoaderT6 final : public SubAssetCreator<SubAssetFlameTable>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FlameTableLoaderT6(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||||
|
: m_memory(memory),
|
||||||
|
m_search_path(searchPath),
|
||||||
|
m_zone(zone)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetCreationResult CreateSubAsset(const std::string& assetName, AssetCreationContext& context) override
|
||||||
|
{
|
||||||
|
const auto fileName = weapon::GetFileNameForFlameTable(assetName);
|
||||||
|
const auto file = m_search_path.Open(fileName);
|
||||||
|
if (!file.IsOpen())
|
||||||
|
return AssetCreationResult::NoAction();
|
||||||
|
|
||||||
|
InfoString infoString;
|
||||||
|
if (!infoString.FromStream(INFO_STRING_PREFIX_FLAME_TABLE, *file.m_stream))
|
||||||
|
{
|
||||||
|
con::error("Could not parse as info string file: \"{}\"", fileName);
|
||||||
|
return AssetCreationResult::Failure();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* flameTable = m_memory.Alloc<FlameTable>();
|
||||||
|
AssetRegistration<SubAssetFlameTable> registration(assetName, flameTable);
|
||||||
|
InfoStringToFlameTableConverter converter(
|
||||||
|
infoString, *flameTable, m_zone.m_script_strings, m_memory, context, registration, flameTableFields, std::extent_v<decltype(flameTableFields)>);
|
||||||
|
if (!converter.Convert())
|
||||||
|
{
|
||||||
|
con::error("Failed to parse flame table: \"{}\"", assetName);
|
||||||
|
return AssetCreationResult::Failure();
|
||||||
|
}
|
||||||
|
|
||||||
|
// The flametable infostring contains the name but we don't to use it from there
|
||||||
|
// It's kept to keep compatiblity with the official modtools and game
|
||||||
|
flameTable->name = m_memory.Dup(assetName.c_str());
|
||||||
|
|
||||||
|
return AssetCreationResult::Success(context.AddSubAsset(std::move(registration)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MemoryManager& m_memory;
|
||||||
|
ISearchPath& m_search_path;
|
||||||
|
Zone& m_zone;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace weapon
|
||||||
|
{
|
||||||
|
std::unique_ptr<ISubAssetCreator> CreateFlameTableLoaderT6(MemoryManager& memory, ISearchPath& searchPath, Zone& zone)
|
||||||
|
{
|
||||||
|
return std::make_unique<FlameTableLoaderT6>(memory, searchPath, zone);
|
||||||
|
}
|
||||||
|
} // namespace weapon
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Asset/IAssetCreator.h"
|
||||||
|
#include "SearchPath/ISearchPath.h"
|
||||||
|
#include "Utils/MemoryManager.h"
|
||||||
|
#include "Zone/Zone.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace weapon
|
||||||
|
{
|
||||||
|
std::unique_ptr<ISubAssetCreator> CreateFlameTableLoaderT6(MemoryManager& memory, ISearchPath& searchPath, Zone& zone);
|
||||||
|
} // namespace weapon
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "Game/T6/Weapon/WeaponFields.h"
|
#include "Game/T6/Weapon/WeaponFields.h"
|
||||||
#include "Game/T6/Weapon/WeaponStrings.h"
|
#include "Game/T6/Weapon/WeaponStrings.h"
|
||||||
#include "Utils/Logging/Log.h"
|
#include "Utils/Logging/Log.h"
|
||||||
|
#include "Utils/StringUtils.h"
|
||||||
#include "Weapon/AccuracyGraphLoader.h"
|
#include "Weapon/AccuracyGraphLoader.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@@ -442,6 +443,32 @@ namespace
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LoadFlameTable(const char* flameTableName, FlameTable*& flameTablePtr, AssetRegistration<AssetWeapon>& registration, AssetCreationContext& context)
|
||||||
|
{
|
||||||
|
if (flameTableName && flameTableName[0] != '\0')
|
||||||
|
{
|
||||||
|
auto* flameTableAsset = context.LoadSubAsset<SubAssetFlameTable>(flameTableName);
|
||||||
|
if (!flameTableAsset)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (auto* dependency : flameTableAsset->m_dependencies)
|
||||||
|
registration.AddDependency(dependency);
|
||||||
|
|
||||||
|
assert(flameTableAsset->m_used_script_strings.empty());
|
||||||
|
assert(flameTableAsset->m_indirect_asset_references.empty());
|
||||||
|
|
||||||
|
flameTablePtr = flameTableAsset->Asset();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadFlameTables(WeaponFullDef& weaponFullDef, AssetRegistration<AssetWeapon>& registration, AssetCreationContext& context)
|
||||||
|
{
|
||||||
|
return LoadFlameTable(weaponFullDef.weapDef.flameTableFirstPerson, weaponFullDef.weapDef.flameTableFirstPersonPtr, registration, context)
|
||||||
|
&& LoadFlameTable(weaponFullDef.weapDef.flameTableThirdPerson, weaponFullDef.weapDef.flameTableThirdPersonPtr, registration, context);
|
||||||
|
}
|
||||||
|
|
||||||
void LinkWeaponFullDefSubStructs(WeaponFullDef& weapon)
|
void LinkWeaponFullDefSubStructs(WeaponFullDef& weapon)
|
||||||
{
|
{
|
||||||
weapon.weapVariantDef.weapDef = &weapon.weapDef;
|
weapon.weapVariantDef.weapDef = &weapon.weapDef;
|
||||||
@@ -462,25 +489,109 @@ namespace
|
|||||||
weapon.weapDef.locationDamageMultipliers = weapon.locationDamageMultipliers;
|
weapon.weapDef.locationDamageMultipliers = weapon.locationDamageMultipliers;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalculateWeaponFields(WeaponFullDef& weapon)
|
bool IsDefaultWeapon(const WeaponFullDef& weapon)
|
||||||
|
{
|
||||||
|
return strcmp(weapon.weapVariantDef.szInternalName, "defaultweapon") == 0 || strcmp(weapon.weapVariantDef.szInternalName, "defaultweapon_mp") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetWeaponDefaults(WeaponFullDef& weapon)
|
||||||
|
{
|
||||||
|
if (IsDefaultWeapon(weapon))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!weapon.weapDef.viewLastShotEjectEffect)
|
||||||
|
weapon.weapDef.viewLastShotEjectEffect = weapon.weapDef.viewShellEjectEffect;
|
||||||
|
if (!weapon.weapDef.worldLastShotEjectEffect)
|
||||||
|
weapon.weapDef.worldLastShotEjectEffect = weapon.weapDef.worldShellEjectEffect;
|
||||||
|
if (!weapon.weapDef.raiseSound)
|
||||||
|
weapon.weapDef.raiseSound = "wpn_default_raise";
|
||||||
|
if (!weapon.weapDef.putawaySound)
|
||||||
|
weapon.weapDef.putawaySound = "wpn_default_putaway";
|
||||||
|
if (!weapon.weapDef.pickupSound)
|
||||||
|
weapon.weapDef.pickupSound = "wpn_default_pickup";
|
||||||
|
if (!weapon.weapDef.ammoPickupSound)
|
||||||
|
weapon.weapDef.ammoPickupSound = "wpn_default_ammo_pickup";
|
||||||
|
if (!weapon.weapDef.emptyFireSound)
|
||||||
|
weapon.weapDef.emptyFireSound = "wpn_default_no_ammo";
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupTransitionTimes(WeaponFullDef& weapon)
|
||||||
|
{
|
||||||
|
if (weapon.weapVariantDef.iAdsTransInTime <= 0)
|
||||||
|
weapon.weapVariantDef.fOOPosAnimLength[0] = 1.0f / 300.0f; // 0.0033333334f;
|
||||||
|
else
|
||||||
|
weapon.weapVariantDef.fOOPosAnimLength[0] = 1.0f / static_cast<float>(weapon.weapVariantDef.iAdsTransInTime);
|
||||||
|
|
||||||
|
if (weapon.weapVariantDef.iAdsTransOutTime <= 0)
|
||||||
|
weapon.weapVariantDef.fOOPosAnimLength[1] = 1.0f / 500.0f; // 0.0020000001f
|
||||||
|
else
|
||||||
|
weapon.weapVariantDef.fOOPosAnimLength[1] = 1.0f / static_cast<float>(weapon.weapVariantDef.iAdsTransOutTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckWeaponDamageRanges(WeaponFullDef& weapon)
|
||||||
|
{
|
||||||
|
if (strcmp(weapon.weapVariantDef.szInternalName, "none") == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (weapon.weapDef.damageRange[0] <= 0.0)
|
||||||
|
weapon.weapDef.damageRange[0] = 999999.0f;
|
||||||
|
if (weapon.weapDef.damageRange[5] <= 0.0)
|
||||||
|
weapon.weapDef.damageRange[5] = 999999.12f; // oddly specific number, no clue
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckCrosshairValues(WeaponFullDef& weapon)
|
||||||
|
{
|
||||||
|
if (weapon.weapDef.enemyCrosshairRange > 15000.0f)
|
||||||
|
con::warn("Weapon {}: Enemy crosshair ranges should be less than 15000", weapon.weapVariantDef.szInternalName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckProjectileValues(WeaponFullDef& weapon)
|
||||||
|
{
|
||||||
|
if (weapon.weapDef.weapType != WEAPTYPE_PROJECTILE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (weapon.weapDef.iProjectileSpeed <= 0)
|
||||||
|
con::warn("Weapon {}: Projectile speed must be greater than 0.0", weapon.weapVariantDef.szDisplayName);
|
||||||
|
|
||||||
|
if (weapon.weapDef.destabilizationCurvatureMax >= 1000000000.0f || weapon.weapDef.destabilizationCurvatureMax < 0.0f)
|
||||||
|
con::warn("Weapon {}: Destabilization angle must be between 0 and 45 degrees", weapon.weapVariantDef.szDisplayName);
|
||||||
|
|
||||||
|
if (weapon.weapDef.destabilizationRateTime < 0.0f)
|
||||||
|
con::warn("Weapon {}: Destabilization rate time must be non-negative", weapon.weapVariantDef.szDisplayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckSharedAmmoValues(const WeaponFullDef& weapon)
|
||||||
|
{
|
||||||
|
if (weapon.weapVariantDef.szAmmoName)
|
||||||
|
utils::MakeStringLowerCase(const_cast<char*>(weapon.weapVariantDef.szAmmoName));
|
||||||
|
|
||||||
|
if (weapon.weapVariantDef.szClipName)
|
||||||
|
utils::MakeStringLowerCase(const_cast<char*>(weapon.weapVariantDef.szClipName));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckAttachModelTags(const WeaponFullDef& weapon)
|
||||||
|
{
|
||||||
|
for (auto* tag : weapon.attachViewModelTag)
|
||||||
|
{
|
||||||
|
if (tag)
|
||||||
|
utils::MakeStringLowerCase(const_cast<char*>(tag));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto* tag : weapon.attachWorldModelTag)
|
||||||
|
{
|
||||||
|
if (tag)
|
||||||
|
utils::MakeStringLowerCase(const_cast<char*>(tag));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupAttachmentField(WeaponFullDef& weapon)
|
||||||
{
|
{
|
||||||
// iAttachments
|
|
||||||
weapon.weapVariantDef.iAttachments = 0;
|
weapon.weapVariantDef.iAttachments = 0;
|
||||||
for (auto i = 1u; i < sizeof(WeaponVariantDef::iAttachments) * 8; i++) // Bit for default attachment always 0
|
for (auto i = 1u; i < sizeof(WeaponVariantDef::iAttachments) * 8; i++) // Bit for default attachment always 0
|
||||||
{
|
{
|
||||||
if (weapon.attachments[i])
|
if (weapon.attachments[i])
|
||||||
weapon.weapVariantDef.iAttachments |= 1 << i;
|
weapon.weapVariantDef.iAttachments |= 1 << i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (weapon.weapVariantDef.iAdsTransInTime <= 0)
|
|
||||||
weapon.weapVariantDef.fOOPosAnimLength[0] = 0.0033333334f;
|
|
||||||
else
|
|
||||||
weapon.weapVariantDef.fOOPosAnimLength[0] = 1.0f / static_cast<float>(weapon.weapVariantDef.iAdsTransInTime);
|
|
||||||
|
|
||||||
if (weapon.weapVariantDef.iAdsTransOutTime <= 0)
|
|
||||||
weapon.weapVariantDef.fOOPosAnimLength[1] = 0.0020000001f;
|
|
||||||
else
|
|
||||||
weapon.weapVariantDef.fOOPosAnimLength[1] = 1.0f / static_cast<float>(weapon.weapVariantDef.iAdsTransOutTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsStringOverride(const char* baseString, const char* overrideString)
|
bool IsStringOverride(const char* baseString, const char* overrideString)
|
||||||
@@ -625,10 +736,27 @@ namespace weapon
|
|||||||
return AssetCreationResult::Failure();
|
return AssetCreationResult::Failure();
|
||||||
}
|
}
|
||||||
|
|
||||||
CalculateWeaponFields(*weaponFullDef);
|
if (!LoadAccuracyGraphs(*weaponFullDef, m_memory, m_search_path, context))
|
||||||
CalculateAttachmentFields(*weaponFullDef);
|
{
|
||||||
|
con::error("Failed to load accuracy tables of weapon: \"{}\"", assetName);
|
||||||
|
return AssetCreationResult::Failure();
|
||||||
|
}
|
||||||
|
|
||||||
LoadAccuracyGraphs(*weaponFullDef, m_memory, m_search_path, context);
|
if (!LoadFlameTables(*weaponFullDef, registration, context))
|
||||||
|
{
|
||||||
|
con::error("Failed to load flame tables of weapon: \"{}\"", assetName);
|
||||||
|
return AssetCreationResult::Failure();
|
||||||
|
}
|
||||||
|
|
||||||
|
SetWeaponDefaults(*weaponFullDef);
|
||||||
|
SetupTransitionTimes(*weaponFullDef);
|
||||||
|
CheckWeaponDamageRanges(*weaponFullDef);
|
||||||
|
SetupAttachmentField(*weaponFullDef);
|
||||||
|
CalculateAttachmentFields(*weaponFullDef);
|
||||||
|
CheckCrosshairValues(*weaponFullDef);
|
||||||
|
CheckProjectileValues(*weaponFullDef);
|
||||||
|
CheckSharedAmmoValues(*weaponFullDef);
|
||||||
|
CheckAttachModelTags(*weaponFullDef);
|
||||||
|
|
||||||
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#include "WeaponDumperT6.h"
|
#include "WeaponDumperT6.h"
|
||||||
|
|
||||||
|
#include "Dumping/SubAssetDeduplicationDumperState.h"
|
||||||
#include "Game/T6/InfoString/InfoStringFromStructConverter.h"
|
#include "Game/T6/InfoString/InfoStringFromStructConverter.h"
|
||||||
#include "Game/T6/ObjConstantsT6.h"
|
#include "Game/T6/ObjConstantsT6.h"
|
||||||
|
#include "Game/T6/Weapon/FlameTableFields.h"
|
||||||
#include "Game/T6/Weapon/WeaponFields.h"
|
#include "Game/T6/Weapon/WeaponFields.h"
|
||||||
#include "Game/T6/Weapon/WeaponStrings.h"
|
#include "Game/T6/Weapon/WeaponStrings.h"
|
||||||
#include "InfoString/InfoString.h"
|
#include "InfoString/InfoString.h"
|
||||||
@@ -267,6 +269,24 @@ namespace
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class InfoStringFromFlameTableConverter final : public InfoStringFromStructConverter
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void FillFromExtensionField(const cspField_t& field) override
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
InfoStringFromFlameTableConverter(const FlameTable* structure,
|
||||||
|
const cspField_t* fields,
|
||||||
|
const size_t fieldCount,
|
||||||
|
std::function<std::string(scr_string_t)> scriptStringValueCallback)
|
||||||
|
: InfoStringFromStructConverter(structure, fields, fieldCount, std::move(scriptStringValueCallback))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
GenericGraph2D ConvertAccuracyGraph(const char* graphName, const vec2_t* originalKnots, const unsigned originalKnotCount)
|
GenericGraph2D ConvertAccuracyGraph(const char* graphName, const vec2_t* originalKnots, const unsigned originalKnotCount)
|
||||||
{
|
{
|
||||||
GenericGraph2D graph;
|
GenericGraph2D graph;
|
||||||
@@ -457,6 +477,47 @@ namespace
|
|||||||
weapDef->originalAiVsPlayerAccuracyGraphKnotCount));
|
weapDef->originalAiVsPlayerAccuracyGraphKnotCount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DumpFlameTable(const AssetDumpingContext& context,
|
||||||
|
SubAssetDeduplicationDumperState<FlameTable>& deduplicator,
|
||||||
|
const char* flameTableName,
|
||||||
|
const FlameTable* flameTable)
|
||||||
|
{
|
||||||
|
if (!flameTable || !flameTableName || flameTableName[0] == '\0')
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!deduplicator.ShouldDumpSubAsset(flameTable))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto assetFile = context.OpenAssetFile(weapon::GetFileNameForFlameTable(flameTableName));
|
||||||
|
|
||||||
|
if (!assetFile)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto& stream = *assetFile;
|
||||||
|
InfoStringFromFlameTableConverter converter(flameTable,
|
||||||
|
flameTableFields,
|
||||||
|
std::extent_v<decltype(flameTableFields)>,
|
||||||
|
[](const scr_string_t scrStr) -> std::string
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
return "";
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto infoString = converter.Convert();
|
||||||
|
|
||||||
|
const auto stringValue = infoString.ToString(INFO_STRING_PREFIX_FLAME_TABLE);
|
||||||
|
stream.write(stringValue.c_str(), stringValue.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DumpFlameTables(AssetDumpingContext& context, const XAssetInfo<WeaponVariantDef>& asset)
|
||||||
|
{
|
||||||
|
auto* deduplicator = context.GetZoneAssetDumperState<SubAssetDeduplicationDumperState<FlameTable>>();
|
||||||
|
const auto weapon = asset.Asset();
|
||||||
|
|
||||||
|
DumpFlameTable(context, *deduplicator, weapon->weapDef->flameTableFirstPerson, weapon->weapDef->flameTableFirstPersonPtr);
|
||||||
|
DumpFlameTable(context, *deduplicator, weapon->weapDef->flameTableThirdPerson, weapon->weapDef->flameTableThirdPersonPtr);
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace weapon
|
namespace weapon
|
||||||
@@ -485,5 +546,6 @@ namespace weapon
|
|||||||
}
|
}
|
||||||
|
|
||||||
DumpAccuracyGraphs(context, asset);
|
DumpAccuracyGraphs(context, asset);
|
||||||
|
DumpFlameTables(context, asset);
|
||||||
}
|
}
|
||||||
} // namespace weapon
|
} // namespace weapon
|
||||||
|
|||||||
Reference in New Issue
Block a user