diff --git a/config/GM8E01_00/symbols.txt b/config/GM8E01_00/symbols.txt index 529d396f..a75e1a2d 100644 --- a/config/GM8E01_00/symbols.txt +++ b/config/GM8E01_00/symbols.txt @@ -11838,12 +11838,12 @@ __dt__12CRealElementFv = .text:0x802B410C; // type:function size:0x60 scope:glob CreateGeneratorDescription__17CDecalDataFactoryFR12CInputStreamP11CSimplePool = .text:0x802B416C; // type:function size:0x8C scope:global GetGeneratorDesc__17CDecalDataFactoryFR12CInputStreamP11CSimplePool = .text:0x802B41F8; // type:function size:0x20 scope:global __dt__45TObjOwnerDerivedFromIObj<17CDecalDescription>Fv = .text:0x802B4218; // type:function size:0x90 scope:global -fn_802B42A8 = .text:0x802B42A8; // type:function size:0x338 +__dt__17CDecalDescriptionFv = .text:0x802B42A8; // type:function size:0x338 FDecalDataFactory__FRC10SObjectTagR12CInputStreamRC15CVParamTransfer = .text:0x802B45E0; // type:function size:0x68 scope:global -__ct__Q24rstl29auto_ptr<17CDecalDescription>FP17CDecalDescription = .text:0x802B4648; // type:function size:0xA4 scope:global +__ct<17CDecalDescription>__16CFactoryFnReturnFP17CDecalDescription = .text:0x802B4648; // type:function size:0xA4 scope:global GetIObjObjectFor__27TToken<17CDecalDescription>FRCQ24rstl29auto_ptr<17CDecalDescription> = .text:0x802B46EC; // type:function size:0x2C scope:global GetNewDerivedObject__45TObjOwnerDerivedFromIObj<17CDecalDescription>FRCQ24rstl29auto_ptr<17CDecalDescription> = .text:0x802B4718; // type:function size:0x9C scope:global -fn_802B47B4 = .text:0x802B47B4; // type:function size:0x64 +__dt__Q24rstl29auto_ptr<17CDecalDescription>Fv = .text:0x802B47B4; // type:function size:0x64 IsConstant__12CRealElementCFv = .text:0x802B4818; // type:function size:0x8 scope:global IsFastConstant__14CVectorElementCFv = .text:0x802B4820; // type:function size:0x8 scope:global Update__6CDecalFf = .text:0x802B4828; // type:function size:0x64 scope:global @@ -18615,7 +18615,7 @@ jumptable_803E7E20 = .data:0x803E7E20; // type:object size:0xAC scope:local lbl_803E7ED0 = .data:0x803E7ED0; // type:object size:0x88 lbl_803E7F58 = .data:0x803E7F58; // type:object size:0x84 jumptable_803E7FDC = .data:0x803E7FDC; // type:object size:0x70 scope:local -lbl_803E8050 = .data:0x803E8050; // type:object size:0x70 +__vt__10CShockWave = .data:0x803E8050; // type:object size:0x70 __vt__25CRipperControlledPlatform = .data:0x803E80C0; // type:object size:0x8C scope:global jumptable_803E8150 = .data:0x803E8150; // type:object size:0x28 scope:local jumptable_803E8178 = .data:0x803E8178; // type:object size:0x24 scope:local @@ -19557,7 +19557,7 @@ SecParams = .bss:0x8056A0A0; // type:object size:0x100 scope:local align:32 __GBA = .bss:0x8056A1A0; // type:object size:0x400 scope:global align:8 gCommandFilterFlag__13ControlMapper = .bss:0x8056A5A0; // type:object size:0x48 scope:global data:4byte sIdentity__10CAxisAngle = .bss:0x8056A5E8; // type:object size:0xC scope:global align:4 data:float -lbl_8056A5F4 = .bss:0x8056A5F4; // type:object size:0xC align:4 data:float +sIdentity__12CEulerAngles = .bss:0x8056A5F4; // type:object size:0xC align:4 data:float mBoolPOINodes__9CAnimData = .bss:0x8056A600; // type:object size:0x1E4 scope:global align:4 data:4byte mInt32POINodes__9CAnimData = .bss:0x8056BDF4; // type:object size:0x4C4 scope:global data:4byte mParticlePOINodes__9CAnimData = .bss:0x8056C2B8; // type:object size:0x734 scope:global data:4byte @@ -21895,8 +21895,7 @@ lbl_805A90A8 = .sbss:0x805A90A8; // type:object size:0x4 data:4byte lbl_805A90AC = .sbss:0x805A90AC; // type:object size:0x1 data:byte lbl_805A90B0 = .sbss:0x805A90B0; // type:object size:0x4 data:4byte lbl_805A90B4 = .sbss:0x805A90B4; // type:object size:0x1 data:byte -lbl_805A90B8 = .sbss:0x805A90B8; // type:object size:0x4 data:4byte -lbl_805A90BC = .sbss:0x805A90BC; // type:object size:0x4 data:4byte +kCheckMaterial__17CEnergyProjectile = .sbss:0x805A90B8; // type:object size:0x8 data:8byte lbl_805A90C0 = .sbss:0x805A90C0; // type:object size:0x4 data:4byte lbl_805A90C4 = .sbss:0x805A90C4; // type:object size:0x4 data:4byte lbl_805A90C8 = .sbss:0x805A90C8; // type:object size:0x4 data:4byte diff --git a/config/GM8E01_01/symbols.txt b/config/GM8E01_01/symbols.txt index 8c5eb34f..fd34fcaf 100644 --- a/config/GM8E01_01/symbols.txt +++ b/config/GM8E01_01/symbols.txt @@ -11838,12 +11838,12 @@ __dt__12CRealElementFv = .text:0x802B41B8; // type:function size:0x60 scope:glob CreateGeneratorDescription__17CDecalDataFactoryFR12CInputStreamP11CSimplePool = .text:0x802B4218; // type:function size:0x8C scope:global GetGeneratorDesc__17CDecalDataFactoryFR12CInputStreamP11CSimplePool = .text:0x802B42A4; // type:function size:0x20 scope:global __dt__45TObjOwnerDerivedFromIObj<17CDecalDescription>Fv = .text:0x802B42C4; // type:function size:0x90 scope:global -fn_802B42A8 = .text:0x802B4354; // type:function size:0x338 scope:global +__dt__17CDecalDescriptionFv = .text:0x802B4354; // type:function size:0x338 scope:global FDecalDataFactory__FRC10SObjectTagR12CInputStreamRC15CVParamTransfer = .text:0x802B468C; // type:function size:0x68 scope:global -__ct__Q24rstl29auto_ptr<17CDecalDescription>FP17CDecalDescription = .text:0x802B46F4; // type:function size:0xA4 scope:global +__ct<17CDecalDescription>__16CFactoryFnReturnFP17CDecalDescription = .text:0x802B46F4; // type:function size:0xA4 scope:global GetIObjObjectFor__27TToken<17CDecalDescription>FRCQ24rstl29auto_ptr<17CDecalDescription> = .text:0x802B4798; // type:function size:0x2C scope:global GetNewDerivedObject__45TObjOwnerDerivedFromIObj<17CDecalDescription>FRCQ24rstl29auto_ptr<17CDecalDescription> = .text:0x802B47C4; // type:function size:0x9C scope:global -fn_802B47B4 = .text:0x802B4860; // type:function size:0x64 scope:global +__dt__Q24rstl29auto_ptr<17CDecalDescription>Fv = .text:0x802B4860; // type:function size:0x64 scope:global IsConstant__12CRealElementCFv = .text:0x802B48C4; // type:function size:0x8 scope:global IsFastConstant__14CVectorElementCFv = .text:0x802B48CC; // type:function size:0x8 scope:global Update__6CDecalFf = .text:0x802B48D4; // type:function size:0x64 scope:global @@ -18522,7 +18522,7 @@ jumptable_803E8000 = .data:0x803E8000; // type:object size:0xAC scope:local lbl_803E80B0 = .data:0x803E80B0; // type:object size:0x88 lbl_803E8138 = .data:0x803E8138; // type:object size:0x84 jumptable_803E81BC = .data:0x803E81BC; // type:object size:0x70 scope:local -lbl_803E8230 = .data:0x803E8230; // type:object size:0x70 +__vt__10CShockWave = .data:0x803E8230; // type:object size:0x70 __vt__25CRipperControlledPlatform = .data:0x803E82A0; // type:object size:0x8C jumptable_803E8330 = .data:0x803E8330; // type:object size:0x28 scope:local jumptable_803E8358 = .data:0x803E8358; // type:object size:0x24 scope:local diff --git a/include/MetroidPrime/CActor.hpp b/include/MetroidPrime/CActor.hpp index 269355ef..ccccb157 100644 --- a/include/MetroidPrime/CActor.hpp +++ b/include/MetroidPrime/CActor.hpp @@ -203,6 +203,7 @@ public: void AddMaterial(EMaterialTypes, EMaterialTypes, CStateManager&); void AddMaterial(EMaterialTypes, CStateManager&); void AddMaterial(const CMaterialList& l) { x68_material.Add(l); } + void SetMaterial(const CMaterialList& l) { x68_material = l; } const CAABox& GetRenderBoundsCached() const { return x9c_renderBounds; } void SetRenderBounds(const CAABox& bounds) { x9c_renderBounds = bounds; } diff --git a/include/MetroidPrime/CStateManager.hpp b/include/MetroidPrime/CStateManager.hpp index 1c491897..b318dc45 100644 --- a/include/MetroidPrime/CStateManager.hpp +++ b/include/MetroidPrime/CStateManager.hpp @@ -369,6 +369,8 @@ public: void CacheReflection(); void DrawReflection(const CVector3f& point); void DrawSpaceWarp(const CVector3f& point, float strength) const; + + void UpdateActorInSortedLists(CActor& actor); private: enum EInitPhase { kIP_LoadWorld, kIP_LoadFirstArea, kIP_Done }; diff --git a/include/MetroidPrime/Cameras/CCameraShakeData.hpp b/include/MetroidPrime/Cameras/CCameraShakeData.hpp index c0b77cd8..9943d78f 100644 --- a/include/MetroidPrime/Cameras/CCameraShakeData.hpp +++ b/include/MetroidPrime/Cameras/CCameraShakeData.hpp @@ -91,7 +91,7 @@ public: float GetDuration() const { return x0_duration; } // In MP1R, returns either x0 or xec? float GetCurTime() const { return x4_curTime; } - CVector3f GetPoint() const; // { return xc4_sfxPos; } + CVector3f GetPoint() const; // { return xc4_sfxPos; } bool Done() const { return x4_curTime >= x0_duration; } // Finished in MP1R uint GetFlags() const { return xc0_flags; } const CVector3f& GetSfxPos() const { return xc4_sfxPos; } @@ -99,6 +99,8 @@ public: static CCameraShakeData skSoftRecoil; static CCameraShakeData skHardRecoil; + static CCameraShakeData BuildProjectileCameraShake(const float duration, const float magnitude); + private: float x0_duration; float x4_curTime; diff --git a/include/MetroidPrime/Weapons/CEnergyProjectile.hpp b/include/MetroidPrime/Weapons/CEnergyProjectile.hpp index 50a1ba8f..482aad84 100644 --- a/include/MetroidPrime/Weapons/CEnergyProjectile.hpp +++ b/include/MetroidPrime/Weapons/CEnergyProjectile.hpp @@ -41,6 +41,10 @@ public: void Set3d0_26(bool v) { x3d0_26_ = v; } CProjectileWeapon& ProjectileWeapon() { return x170_projectile; } + + void StopProjectile(CStateManager& mgr); + + void SetCameraShake(const CCameraShakeData& data); private: CSfxHandle x2e8_sfx; @@ -52,6 +56,8 @@ private: bool x3d0_26_ : 1; bool x3d0_27_camShakeDirty : 1; float x3d4_curTime; + + static const CMaterialList kCheckMaterial; }; CHECK_SIZEOF(CEnergyProjectile, 0x3d8); diff --git a/include/MetroidPrime/Weapons/CGameProjectile.hpp b/include/MetroidPrime/Weapons/CGameProjectile.hpp index 0a13fa9c..d0df67ef 100644 --- a/include/MetroidPrime/Weapons/CGameProjectile.hpp +++ b/include/MetroidPrime/Weapons/CGameProjectile.hpp @@ -47,6 +47,7 @@ public: CProjectileTouchResult CanCollideWithTrigger(CActor& act, CStateManager& mgr); const CProjectileWeapon& GetProjectile() const { return x170_projectile; } + CProjectileWeapon& Projectile() { return x170_projectile; } const CVector3f& GetPreviousPos() const { return x298_previousPos; } TUniqueId GetHomingTargetId() const { return x2c0_homingTargetId; } TUniqueId GetHitProjectileOwner() const { return x2c4_hitProjectileOwner; } @@ -62,8 +63,8 @@ public: static EProjectileAttrib GetBeamAttribType(EWeaponType wType); CAABox GetProjectileBounds() const; - - protected: + +protected: rstl::optional_object< TLockedToken< CGenDescription > > x158_visorParticle; ushort x168_visorSfx; CProjectileWeapon x170_projectile; diff --git a/include/MetroidPrime/Weapons/CProjectileWeapon.hpp b/include/MetroidPrime/Weapons/CProjectileWeapon.hpp index 6a9d97f6..f07af8de 100644 --- a/include/MetroidPrime/Weapons/CProjectileWeapon.hpp +++ b/include/MetroidPrime/Weapons/CProjectileWeapon.hpp @@ -24,7 +24,7 @@ public: const CTransform4f& orient, const CVector3f& scale, const int); virtual ~CProjectileWeapon(); virtual void Update(float dt); - virtual void AddToRenderer(); + virtual void AddToRenderer() const; virtual void Render() const; virtual CVector3f GetTranslation() const; virtual CTransform4f GetTransform() const; @@ -35,6 +35,8 @@ public: static float GetTickPeriod(); // { return 0.0166667f; } static void SetGlobalSeed(uint seed); + + rstl::optional_object GetBounds() const; private: TLockedToken< CWeaponDescription > x4_weaponDesc; diff --git a/include/Weapons/CDecalDataFactory.hpp b/include/Weapons/CDecalDataFactory.hpp new file mode 100644 index 00000000..1c005564 --- /dev/null +++ b/include/Weapons/CDecalDataFactory.hpp @@ -0,0 +1,21 @@ +#ifndef _CDECALDATAFACTORY +#define _CDECALDATAFACTORY +#include "Weapons/CDecalDescription.hpp" + +#include "Kyoto/CFactoryFnReturn.hpp" + +class CDecalDescription; +class CSimplePool; +class CInputStream; +class CDecalDataFactory { +public: + static CDecalDescription* GetGeneratorDesc(CInputStream& in, CSimplePool* pool); + static CDecalDescription* CreateGeneratorDescription(CInputStream& in, CSimplePool* pool); + static void GetQuadDecalInfo(CInputStream& in, CSimplePool* pool, uint classId, + CDecalDescription::SQuadDescr& quad); + static bool CreateDPSM(CDecalDescription* desc, CInputStream& in, CSimplePool* pool); +}; + +CFactoryFnReturn FDecalDataFactory(const SObjectTag& tag, CInputStream& in, + const CVParamTransfer& transfer); +#endif diff --git a/include/Weapons/CDecalDescription.hpp b/include/Weapons/CDecalDescription.hpp index 3cbe460c..74e5a38f 100644 --- a/include/Weapons/CDecalDescription.hpp +++ b/include/Weapons/CDecalDescription.hpp @@ -33,4 +33,6 @@ public: bool x5c_25_DMOO : 1; }; +CHECK_SIZEOF(CDecalDescription, 0x60); + #endif // _CDECALDESCRIPTION diff --git a/src/MetroidPrime/Weapons/CEnergyProjectile.cpp b/src/MetroidPrime/Weapons/CEnergyProjectile.cpp new file mode 100644 index 00000000..99413d98 --- /dev/null +++ b/src/MetroidPrime/Weapons/CEnergyProjectile.cpp @@ -0,0 +1,79 @@ +#include "MetroidPrime/Weapons/CEnergyProjectile.hpp" + +#include "Kyoto/Audio/CSfxManager.hpp" +#include "MetroidPrime/Player/CPlayerState.hpp" + +#define MATERIAL_FLAG(x) (1 << x) + +const CMaterialList CEnergyProjectile::kCheckMaterial( + MATERIAL_FLAG(kMT_Stone) | MATERIAL_FLAG(kMT_Metal) | MATERIAL_FLAG(kMT_Grass) | + MATERIAL_FLAG(kMT_Ice) | MATERIAL_FLAG(kMT_Pillar) | MATERIAL_FLAG(kMT_MetalGrating) | + MATERIAL_FLAG(kMT_Phazon) | MATERIAL_FLAG(kMT_Dirt) | MATERIAL_FLAG(kMT_Lava) | + MATERIAL_FLAG(kMT_LavaStone) | MATERIAL_FLAG(kMT_Snow) | MATERIAL_FLAG(kMT_MudSlow) | + MATERIAL_FLAG(kMT_HalfPipe) | MATERIAL_FLAG(kMT_Mud) | MATERIAL_FLAG(kMT_Glass) | + MATERIAL_FLAG(kMT_Shield) | MATERIAL_FLAG(kMT_Sand) | MATERIAL_FLAG(kMT_CameraPassthrough) | + MATERIAL_FLAG(kMT_Wood) | MATERIAL_FLAG(kMT_Organic)); +#undef MATERIAL_FLAG + +CEnergyProjectile::CEnergyProjectile( + const bool active, const TToken< CWeaponDescription >& desc, const EWeaponType type, + const CTransform4f& xf, const EMaterialTypes excludeMat, const CDamageInfo& damage, + const TUniqueId uid, TAreaId aid, const TUniqueId owner, const TUniqueId homingTarget, + const uint attribs, const bool underwater, const CVector3f& scale, + const rstl::optional_object< TLockedToken< CGenDescription > >& visorParticle, + const ushort visorSfx, const bool sendCollideMsg) +: CGameProjectile(active, desc, rstl::string_l("GameProjectile"), type, xf, excludeMat, damage, uid, + aid, owner, homingTarget, attribs, underwater, scale, visorParticle, visorSfx, + sendCollideMsg) +, x2ec_dir(xf.GetForward()) +, x2f8_mag(x2ec_dir.Magnitude()) +, x2fc_camShake(CCameraShakeData::BuildProjectileCameraShake(0.5f, 0.75f)) +, x3d0_24_dead(false) +, x3d0_25_(false) +, x3d0_26_(false) +, x3d0_27_camShakeDirty(false) +, x3d4_curTime(0.f) { + SetThermalFlags(kTF_Hot); +} + +void CEnergyProjectile::StopProjectile(CStateManager& mgr) { + DeleteProjectileLight(mgr); + mgr.RemoveWeaponId(GetOwnerId(), GetType()); + x2e4_24_active = false; + SetMaterial(CMaterialList()); + mgr.UpdateActorInSortedLists(*this); + if (x2e8_sfx) { + CSfxManager::RemoveEmitter(x2e8_sfx); + x2e8_sfx.Clear(); + } +} + +bool CEnergyProjectile::Explode(const CVector3f& pos, const CVector3f& normal, + const EWeaponCollisionResponseTypes type, CStateManager& mgr, + const CDamageVulnerability& dVuln, const TUniqueId hitActor) { + +} + +void CEnergyProjectile::Touch(CActor&, CStateManager&) {} + +void CEnergyProjectile::AddToRenderer(const CFrustumPlanes& frustum, + const CStateManager& mgr) const { + const rstl::optional_object< CAABox > bounds = GetProjectile().GetBounds(); + if (bounds.valid() && !frustum.BoxInFrustumPlanes(bounds)) { + return; + } + + const CPlayerState::EPlayerVisor visor = mgr.GetPlayerState()->GetActiveVisor(mgr); + + if (visor != CPlayerState::kPV_XRay && + ((GetAttribField() & kPA_Ice) != kPA_Ice || mgr.GetThermalDrawFlag() != kTD_Hot)) { + GetProjectile().AddToRenderer(); + } + + EnsureRendered(mgr); +} + +void CEnergyProjectile::SetCameraShake(const CCameraShakeData& data) { + x2fc_camShake = data; + x3d0_27_camShakeDirty = true; +} \ No newline at end of file diff --git a/src/MetroidPrime/Weapons/GunController/CGSFreeLook.cpp b/src/MetroidPrime/Weapons/GunController/CGSFreeLook.cpp index 70c03768..6f848005 100644 --- a/src/MetroidPrime/Weapons/GunController/CGSFreeLook.cpp +++ b/src/MetroidPrime/Weapons/GunController/CGSFreeLook.cpp @@ -34,20 +34,21 @@ bool CGSFreeLook::Update(CAnimData& data, float dt, CStateManager& mgr) { return false; } -int CGSFreeLook::SetAnim(CAnimData& data, int gunId, int setId, int loopState, CStateManager& mgr, - float delay) { +int CGSFreeLook::SetAnim(CAnimData& data, const int gunId, const int setId, const int loopState, + CStateManager& mgr, const float delay) { int useLoopState = 1; - if (!x14_idle) + if (!x14_idle) { useLoopState = loopState; + } x14_idle = false; const CPASDatabase& pas = data.GetCharacterInfo().GetPASDatabase(); - rstl::pair< float, int > anim = pas.FindBestAnimation( + const rstl::pair< float, int > anim = pas.FindBestAnimation( CPASAnimParmData(pas::kAS_Step, CPASAnimParm::FromInt32(gunId), CPASAnimParm::FromInt32(setId), CPASAnimParm::FromEnum(useLoopState)), *mgr.Random(), -1); - CPASAnimParm animParm = pas.GetAnimState(pas::kAS_Step)->GetAnimParmData(anim.second, 1); + const CPASAnimParm animParm = pas.GetAnimState(pas::kAS_Step)->GetAnimParmData(anim.second, 1); xc_gunId = gunId; x10_setId = animParm.GetInt32Value(); x8_loopState = useLoopState; @@ -56,8 +57,7 @@ int CGSFreeLook::SetAnim(CAnimData& data, int gunId, int setId, int loopState, C x4_cueAnimId = anim.second; } else { data.EnableLooping(loopState == 1); - CAnimPlaybackParms aparms(anim.second, -1, 1.f, true); - data.SetAnimation(aparms, false); + data.SetAnimation(CAnimPlaybackParms(anim.second, -1, 1.f, true), false); } return anim.second; } diff --git a/src/Weapons/CCollisionResponseData.cpp b/src/Weapons/CCollisionResponseData.cpp index 5e311cae..10daa8a3 100644 --- a/src/Weapons/CCollisionResponseData.cpp +++ b/src/Weapons/CCollisionResponseData.cpp @@ -25,9 +25,9 @@ CCollisionResponseData::CCollisionResponseData(CInputStream& in, CSimplePool* sp return; } - CRandom16 _(99); + CRandom16 _; CGlobalRandom __(_); - // bool done = false; + while (!done) { const FourCC clsId = CParticleDataFactory::GetClassID(in); if (CheckAndAddResourcesToResponse(clsId, in, sp)) { diff --git a/src/Weapons/CDecalDataFactory.cpp b/src/Weapons/CDecalDataFactory.cpp new file mode 100644 index 00000000..8abb6568 --- /dev/null +++ b/src/Weapons/CDecalDataFactory.cpp @@ -0,0 +1,94 @@ +#include "Weapons/CDecalDataFactory.hpp" + +#include "Kyoto/CRandom16.hpp" +#include "Kyoto/Particles/CParticleDataFactory.hpp" + +CFactoryFnReturn FDecalDataFactory(const SObjectTag& tag, CInputStream& in, + const CVParamTransfer& transfer) { + rstl::rc_ptr< IVParamObj > obj = transfer.x0_obj; + CSimplePool* pool = static_cast< TObjOwnerParam< CSimplePool* >* >(obj.GetPtr())->GetData(); + CDecalDescription* ret = CDecalDataFactory::GetGeneratorDesc(in, pool); + return ret; +} + +CDecalDescription* CDecalDataFactory::GetGeneratorDesc(CInputStream& in, CSimplePool* pool) { + return CreateGeneratorDescription(in, pool); +} +CDecalDescription* CDecalDataFactory::CreateGeneratorDescription(CInputStream& in, + CSimplePool* pool) { + if (CParticleDataFactory::GetClassID(in) != 'DPSM') { + return nullptr; + } + + CDecalDescription* desc = rs_new CDecalDescription(); + CreateDPSM(desc, in, pool); + return desc; +} +void CDecalDataFactory::GetQuadDecalInfo(CInputStream& in, CSimplePool* pool, uint classId, + CDecalDescription::SQuadDescr& quad) {} + +bool CDecalDataFactory::CreateDPSM(CDecalDescription* desc, CInputStream& in, CSimplePool* pool) { + bool done = false; + CRandom16 _; + + while (!done) { + CGlobalRandom __(_); + const FourCC clsId = CParticleDataFactory::GetClassID(in); + bool loadFirstDesc = false; + switch (clsId) { + case '1SZE': + case '1LFT': + case '1ROT': + case '1OFF': + case '1CLR': + case '1TEX': + case '1ADD': + loadFirstDesc = true; + case '2LFT': + case '2SZE': + case '2ROT': + case '2OFF': + case '2CLR': + case '2TEX': + case '2ADD': { + CDecalDescription::SQuadDescr& quad = loadFirstDesc ? desc->x0_quad1 : desc->x1c_quad2; + GetQuadDecalInfo(in, pool, clsId, quad); + } break; + case 'DMDL': { + rstl::optional_object< TToken< CModel > > model = CParticleDataFactory::GetModel(in, pool); + if (model.valid()) { + rstl::optional_object > m = TLockedToken(*model); + desc->x38_DMDL = m; + } + } break; + case 'DLFT': + desc->x48_DLFT = CParticleDataFactory::GetIntElement(in); + break; + case 'DMOP': + desc->x4c_DMOP = CParticleDataFactory::GetVectorElement(in); + break; + case 'DMRT': + desc->x50_DMRT = CParticleDataFactory::GetVectorElement(in); + break; + case 'DMSC': + desc->x54_DMSC = CParticleDataFactory::GetVectorElement(in); + break; + case 'DMCL': + desc->x58_DMCL = CParticleDataFactory::GetColorElement(in); + break; + case 'DMAB': + desc->x5c_24_DMAB = CParticleDataFactory::GetBool(in); + break; + case 'DMOO': + desc->x5c_25_DMOO = CParticleDataFactory::GetBool(in); + break; + case '_END': + done = true; + break; + default: + return false; + } + } + + return true; +} \ No newline at end of file