From dd30f517610ee2a34f7c5ed67f25c8c4e2ec9802 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Sat, 27 Oct 2018 17:20:30 -0700 Subject: [PATCH] Initial CScriptGun implementation, more loaders --- Editor/ViewManager.cpp | 8 +- Runtime/Collision/CCollisionActorManager.cpp | 5 + Runtime/Collision/CCollisionActorManager.hpp | 1 + Runtime/MP1/MP1.cpp | 28 +- Runtime/MP1/World/CChozoGhost.cpp | 29 + Runtime/MP1/World/CChozoGhost.hpp | 34 + Runtime/MP1/World/CFlyingPirate.cpp | 14 + Runtime/MP1/World/CFlyingPirate.hpp | 15 + Runtime/MP1/World/CMakeLists.txt | 2 + Runtime/MP1/World/CMetroidBeta.cpp | 24 +- Runtime/MP1/World/CMetroidBeta.hpp | 24 +- Runtime/Particle/CParticleElectric.cpp | 2 +- Runtime/Weapon/CBurstFire.cpp | 10 + Runtime/Weapon/CBurstFire.hpp | 4 +- Runtime/World/CActor.cpp | 6 + Runtime/World/CActor.hpp | 1 + Runtime/World/CScriptEffect.cpp | 2 +- Runtime/World/CScriptGunTurret.cpp | 770 ++++++++++++++++++- Runtime/World/CScriptGunTurret.hpp | 50 +- Runtime/World/ScriptLoader.cpp | 143 +++- 20 files changed, 1127 insertions(+), 45 deletions(-) create mode 100644 Runtime/MP1/World/CChozoGhost.cpp create mode 100644 Runtime/MP1/World/CChozoGhost.hpp create mode 100644 Runtime/MP1/World/CFlyingPirate.cpp create mode 100644 Runtime/MP1/World/CFlyingPirate.hpp diff --git a/Editor/ViewManager.cpp b/Editor/ViewManager.cpp index 1214f53a8..3e99fc311 100644 --- a/Editor/ViewManager.cpp +++ b/Editor/ViewManager.cpp @@ -92,12 +92,16 @@ void ViewManager::TestGameView::think() zeus::CQuaternion camQ = zeus::CQuaternion(camXf.getRotation().buildMatrix3f()); overlayText += hecl::Format("Player Position: x %f, y %f, z %f\n" " Quaternion: w %f, x %f, y %f, z %f\n" + " Roll: %f, Pitch: %f, Yaw: %f\n" "Camera Position: x %f, y %f, z %f\n" - " Quaternion: w %f, x %f, y %f, z %f\n", + " Quaternion: w %f, x %f, y %f, z %f\n" + " Roll: %f, Pitch: %f, Yaw: %f\n", pl.GetTranslation().x, pl.GetTranslation().y, pl.GetTranslation().z, plQ.w, plQ.x, plQ.y, plQ.z, + plQ.roll(), plQ.pitch(), plQ.yaw(), camXf.origin.x, camXf.origin.y, camXf.origin.z, - camQ.w, camQ.x, camQ.y, camQ.z); + camQ.w, camQ.x, camQ.y, camQ.z, + camQ.roll(), camQ.pitch(), camQ.yaw()); } if (worldInfo && worldInfo->toBoolean()) { diff --git a/Runtime/Collision/CCollisionActorManager.cpp b/Runtime/Collision/CCollisionActorManager.cpp index 8528fda8b..09b0c2301 100644 --- a/Runtime/Collision/CCollisionActorManager.cpp +++ b/Runtime/Collision/CCollisionActorManager.cpp @@ -47,4 +47,9 @@ CJointCollisionDescription CCollisionActorManager::GetCollisionDescFromIndex(u32 return x0_jointDescriptions[idx]; } +void CCollisionActorManager::Update(float, CStateManager&, CCollisionActorManager::EUpdateOptions) const +{ + +} + } diff --git a/Runtime/Collision/CCollisionActorManager.hpp b/Runtime/Collision/CCollisionActorManager.hpp index 6b4ec8b30..cfe11b439 100644 --- a/Runtime/Collision/CCollisionActorManager.hpp +++ b/Runtime/Collision/CCollisionActorManager.hpp @@ -15,6 +15,7 @@ class CCollisionActorManager public: enum class EUpdateOptions { + Zero }; private: diff --git a/Runtime/MP1/MP1.cpp b/Runtime/MP1/MP1.cpp index 0b964ece3..a3354035b 100644 --- a/Runtime/MP1/MP1.cpp +++ b/Runtime/MP1/MP1.cpp @@ -736,6 +736,13 @@ void CMain::Init(const hecl::Runtime::FileStoreManager& storeMgr, m_console->registerCommand("ListWorlds"sv, "Lists loaded worlds"sv, ""sv, std::bind(&CMain::ListWorlds, this, std::placeholders::_1, std::placeholders::_2), hecl::SConsoleCommand::ECommandFlags::Normal); m_console->registerCommand("WarpTo"sv, "Warps to a given area and world"sv, "[worldname] areaId"sv, std::bind(&CMain::WarpTo, this, std::placeholders::_1, std::placeholders::_2), hecl::SConsoleCommand::ECommandFlags::Normal); + + InitializeSubsystems(); + x128_globalObjects.PostInitialize(); + x70_tweaks.RegisterTweaks(m_cvarMgr); + x70_tweaks.RegisterResourceTweaks(m_cvarMgr); + AddWorldPaks(); + const auto& args = boo::APP->getArgs(); for (auto it = args.begin(); it != args.end(); ++it) { @@ -752,6 +759,22 @@ void CMain::Init(const hecl::Runtime::FileStoreManager& storeMgr, if (endptr == areaIdxStr) m_warpAreaId = 0; + bool found = false; + for (const auto& pak : g_ResFactory->GetResLoader()->GetPaks()) + { + if (*(pak->GetPath().end() - 6) == '0' + m_warpWorldIdx) + { + found = true; + break; + } + } + + if (!found) + { + m_warpWorldIdx = -1; + break; + } + if (args.end() - it >= 4) { const hecl::SystemChar* layerStr = (*(it + 3)).c_str(); @@ -765,11 +788,6 @@ void CMain::Init(const hecl::Runtime::FileStoreManager& storeMgr, } } - InitializeSubsystems(); - x128_globalObjects.PostInitialize(); - x70_tweaks.RegisterTweaks(m_cvarMgr); - x70_tweaks.RegisterResourceTweaks(m_cvarMgr); - AddWorldPaks(); FillInAssetIDs(); x164_archSupport.reset(new CGameArchitectureSupport(*this, voiceEngine, backend)); g_archSupport = x164_archSupport.get(); diff --git a/Runtime/MP1/World/CChozoGhost.cpp b/Runtime/MP1/World/CChozoGhost.cpp new file mode 100644 index 000000000..f3bb2ca25 --- /dev/null +++ b/Runtime/MP1/World/CChozoGhost.cpp @@ -0,0 +1,29 @@ +#include "CChozoGhost.hpp" + +namespace urde::MP1 +{ +CChozoGhost::CBehaveChance::CBehaveChance(CInputStream& in) + : x0_propertyCount(in.readUint32Big()), x4_(in.readFloatBig()), x8_(in.readFloatBig()), xc_(in.readFloatBig()), + x10_(in.readFloatBig()), x14_(in.readFloatBig()), x18_(x0_propertyCount <= 5 ? 0.5f : in.readFloatBig() * .01f), + x1c_(x0_propertyCount <= 6 ? 2 : in.readUint32Big()) +{ + float f2 = 1.f / (x10_ + xc_ + x4_ + x8_); + x4_ *= f2; + x8_ *= f2; + xc_ *= f2; + x10_ *= f2; +} + + +CChozoGhost::CChozoGhost(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + CModelData&& mData, const CActorParameters& actParms, const CPatternedInfo& pInfo, float f1, + float f2, float f3, float f4, CAssetId wpsc1, const CDamageInfo& dInfo1, CAssetId wpsc2, + const CDamageInfo& dInfo2, const CBehaveChance& chance1, const CBehaveChance& chance2, + const CBehaveChance& chance3, u16 sId1, float f5, u16 sId2, u16 sId3, u32 w1, float f6, u32 w2, + float f7, CAssetId partId, s16 sId4, float f8, float f9, u32 w3, u32 w4) + : CPatterned(ECharacter::ChozoGhost, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo, + EMovementType::Flyer, EColliderType::Zero, EBodyType::BiPedal, actParms, 1) +{ + +} +} \ No newline at end of file diff --git a/Runtime/MP1/World/CChozoGhost.hpp b/Runtime/MP1/World/CChozoGhost.hpp new file mode 100644 index 000000000..f625b5f49 --- /dev/null +++ b/Runtime/MP1/World/CChozoGhost.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include "World/CPatterned.hpp" + +namespace urde::MP1 +{ +class CChozoGhost : public CPatterned +{ +public: + class CBehaveChance + { + u32 x0_propertyCount; + float x4_; + float x8_; + float xc_; + float x10_; + float x14_; + float x18_; + u32 x1c_; + public: + CBehaveChance(CInputStream&); + }; + +private: +public: + DEFINE_PATTERNED(ChozoGhost) + + CChozoGhost(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&, + const CActorParameters&, const CPatternedInfo&, float, float, float, float, CAssetId, + const CDamageInfo&, CAssetId, const CDamageInfo&, const CChozoGhost::CBehaveChance&, + const CChozoGhost::CBehaveChance&, const CBehaveChance&, u16, float, u16, u16, u32, float, u32, float, + CAssetId, s16, float, float, u32, u32); +}; +} \ No newline at end of file diff --git a/Runtime/MP1/World/CFlyingPirate.cpp b/Runtime/MP1/World/CFlyingPirate.cpp new file mode 100644 index 000000000..e1d10fef5 --- /dev/null +++ b/Runtime/MP1/World/CFlyingPirate.cpp @@ -0,0 +1,14 @@ +#include "CFlyingPirate.hpp" + +namespace urde::MP1 +{ + +CFlyingPirate::CFlyingPirate(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, + CModelData&& mData, const CActorParameters& actParms, const CPatternedInfo& pInfo, + CInputStream& in, u32 propCount) + : CPatterned(ECharacter::FlyingPirate, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo, + EMovementType::Flyer, EColliderType::One, EBodyType::NewFlyer, actParms, 1) +{ + +} +} diff --git a/Runtime/MP1/World/CFlyingPirate.hpp b/Runtime/MP1/World/CFlyingPirate.hpp new file mode 100644 index 000000000..098353641 --- /dev/null +++ b/Runtime/MP1/World/CFlyingPirate.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "World/CPatterned.hpp" + +namespace urde::MP1 +{ +class CFlyingPirate : public CPatterned +{ +public: + DEFINE_PATTERNED(FlyingPirate) + + CFlyingPirate(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&, + const CActorParameters&, const CPatternedInfo&, CInputStream&, u32); +}; +} \ No newline at end of file diff --git a/Runtime/MP1/World/CMakeLists.txt b/Runtime/MP1/World/CMakeLists.txt index 6c076c142..489a8bb6e 100644 --- a/Runtime/MP1/World/CMakeLists.txt +++ b/Runtime/MP1/World/CMakeLists.txt @@ -4,6 +4,7 @@ set(MP1_WORLD_SOURCES CWarWasp.hpp CWarWasp.cpp CElitePirate.hpp CElitePirate.cpp CBloodFlower.hpp CBloodFlower.cpp + CChozoGhost.hpp CChozoGhost.cpp CSpacePirate.hpp CSpacePirate.cpp CParasite.hpp CParasite.cpp CBabygoth.hpp CBabygoth.cpp @@ -12,6 +13,7 @@ set(MP1_WORLD_SOURCES CEyeball.hpp CEyeball.cpp CAtomicAlpha.hpp CAtomicAlpha.cpp CFlickerBat.hpp CFlickerBat.cpp + CFlyingPirate.hpp CFlyingPirate.cpp CMetroidPrimeRelay.hpp CMetroidPrimeRelay.cpp CMetroidPrimeExo.hpp CMetroidPrimeExo.cpp CMetroidPrimeProjectile.hpp CMetroidPrimeProjectile.cpp diff --git a/Runtime/MP1/World/CMetroidBeta.cpp b/Runtime/MP1/World/CMetroidBeta.cpp index df70dabd9..e219c54c9 100644 --- a/Runtime/MP1/World/CMetroidBeta.cpp +++ b/Runtime/MP1/World/CMetroidBeta.cpp @@ -4,9 +4,30 @@ namespace urde::MP1 { +CMetroidBetaData::CMetroidBetaData(CInputStream& in) +: x0_(in) +, x68_(in) +, xd0_(in.readFloatBig()) +, xd4_(in.readFloatBig()) +, xd8_(in.readFloatBig()) +, xdc_(in.readFloatBig()) +, xe0_(in.readFloatBig()) +, xe4_(in.readFloatBig()) +, xe8_(in.readFloatBig()) +, xec_(in.readFloatBig()) +, xf0_(in.readFloatBig()) +, xf4_(in) +, xf8_(in) +, xfc_(in) +, x100_(in) +, x104_(in) +, x108_24_(in.readBool()) +{ +} + CMetroidBeta::CMetroidBeta(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, - const CActorParameters& aParms, const CMetroidData& metroidData) + const CActorParameters& aParms, const CMetroidBetaData& metroidData) : CPatterned(ECharacter::MetroidBeta, uid, name, EFlavorType::One, info, xf, std::move(mData), pInfo, EMovementType::Flyer, EColliderType::One, EBodyType::Flyer, aParms, 2) { @@ -21,5 +42,4 @@ void CMetroidBeta::RenderHitBallEffect() const { } - } diff --git a/Runtime/MP1/World/CMetroidBeta.hpp b/Runtime/MP1/World/CMetroidBeta.hpp index cbc7c2339..51a1fd023 100644 --- a/Runtime/MP1/World/CMetroidBeta.hpp +++ b/Runtime/MP1/World/CMetroidBeta.hpp @@ -6,13 +6,35 @@ namespace urde::MP1 { +class CMetroidBetaData +{ + CDamageVulnerability x0_; + CDamageVulnerability x68_; + float xd0_; + float xd4_; + float xd8_; + float xdc_; + float xe0_; + float xe4_; + float xe8_; + float xec_; + float xf0_; + CAssetId xf4_; + CAssetId xf8_; + CAssetId xfc_; + CAssetId x100_; + CAssetId x104_; + bool x108_24_ : 1; +public: + CMetroidBetaData(CInputStream&); +}; class CMetroidBeta : public CPatterned { public: DEFINE_PATTERNED(MetroidBeta) CMetroidBeta(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, - const CActorParameters& aParms, const CMetroidData& metroidData); + const CActorParameters& aParms, const CMetroidBetaData& metroidData); void RenderHitGunEffect() const; void RenderHitBallEffect() const; }; diff --git a/Runtime/Particle/CParticleElectric.cpp b/Runtime/Particle/CParticleElectric.cpp index 494cb8f33..40f1374cd 100644 --- a/Runtime/Particle/CParticleElectric.cpp +++ b/Runtime/Particle/CParticleElectric.cpp @@ -101,7 +101,7 @@ void CParticleElectric::DrawLineStrip(const std::vector& verts, m_lineRenderers.resize(m_nextLineRenderer); if (!m_lineRenderers[useIdx]) m_lineRenderers[useIdx] = std::make_unique(CLineRenderer::EPrimitiveMode::LineStrip, - x150_SSEG, nullptr, true); + x150_SSEG, nullptr, true, true); CLineRenderer& renderer = *m_lineRenderers[useIdx]; zeus::CColor useColor = x1b8_moduColor * color; diff --git a/Runtime/Weapon/CBurstFire.cpp b/Runtime/Weapon/CBurstFire.cpp index 8fe789a6c..0b8e64fa6 100644 --- a/Runtime/Weapon/CBurstFire.cpp +++ b/Runtime/Weapon/CBurstFire.cpp @@ -15,4 +15,14 @@ CBurstFire::CBurstFire(SBurst** bursts, s32 firstIndex) ++burst; } } + +void CBurstFire::Update(CStateManager&, float) +{ + +} + +zeus::CVector3f CBurstFire::GetDistanceCompensatedError(float, float) const +{ + return {}; +} } diff --git a/Runtime/Weapon/CBurstFire.hpp b/Runtime/Weapon/CBurstFire.hpp index 31fd6abea..f06cae8dd 100644 --- a/Runtime/Weapon/CBurstFire.hpp +++ b/Runtime/Weapon/CBurstFire.hpp @@ -46,10 +46,12 @@ public: void Update(CStateManager&, float); void Update(); void GetError(float, float) const; - void GetDistanceCompensatedError(float, float) const; + zeus::CVector3f GetDistanceCompensatedError(float, float) const; float GetMaxXError() const; float GetMaxZError() const; void GetError() const; void SetFirstBurstIndex(s32); + + bool GetX14_24() const { return x14_24_; } }; } diff --git a/Runtime/World/CActor.cpp b/Runtime/World/CActor.cpp index 065360bbe..8a9c127ca 100644 --- a/Runtime/World/CActor.cpp +++ b/Runtime/World/CActor.cpp @@ -785,4 +785,10 @@ void CActor::SetModelData(std::unique_ptr&& mData) else x64_modelData = std::move(mData); } + +void CActor::SetMuted(bool muted) +{ + xe5_26_muted = muted; + RemoveEmitter(); +} } diff --git a/Runtime/World/CActor.hpp b/Runtime/World/CActor.hpp index a09b24081..89bd566a5 100644 --- a/Runtime/World/CActor.hpp +++ b/Runtime/World/CActor.hpp @@ -136,6 +136,7 @@ public: void RemoveEmitter(); void SetVolume(float vol); + void SetMuted(bool); const zeus::CTransform& GetTransform() const { return x34_transform; } const zeus::CVector3f& GetTranslation() const { return x34_transform.origin; } const zeus::CTransform GetScaledLocatorTransform(std::string_view segName) const; diff --git a/Runtime/World/CScriptEffect.cpp b/Runtime/World/CScriptEffect.cpp index 292deb1fd..fe2ff36b7 100644 --- a/Runtime/World/CScriptEffect.cpp +++ b/Runtime/World/CScriptEffect.cpp @@ -147,7 +147,7 @@ void CScriptEffect::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSt case EScriptObjectMessage::InitializedInArea: for (const SConnection& conn : x20_conns) { - if (!(conn.x0_state == EScriptObjectState::Active && conn.x4_msg == EScriptObjectMessage::Deactivate) || + if (!(conn.x0_state == EScriptObjectState::Active && conn.x4_msg == EScriptObjectMessage::Deactivate) && !(conn.x0_state == EScriptObjectState::Modify && conn.x4_msg == EScriptObjectMessage::Activate)) continue; diff --git a/Runtime/World/CScriptGunTurret.cpp b/Runtime/World/CScriptGunTurret.cpp index 35828cf92..454e5cd9a 100644 --- a/Runtime/World/CScriptGunTurret.cpp +++ b/Runtime/World/CScriptGunTurret.cpp @@ -3,8 +3,14 @@ #include "CSimplePool.hpp" #include "Particle/CGenDescription.hpp" #include "Particle/CElementGen.hpp" +#include "Weapon/CGameProjectile.hpp" +#include "World/CGameLight.hpp" +#include "Collision/CCollisionActorManager.hpp" +#include "Collision/CCollisionActor.hpp" +#include "CPlayer.hpp" +#include "Character/CPASAnimParmData.hpp" +#include "Graphics/CBooRenderer.hpp" #include "TCastTo.hpp" - namespace urde { @@ -39,7 +45,7 @@ CScriptGunTurretData::CScriptGunTurretData(CInputStream& in, s32 propCount) x78_(propCount >= 44 ? in.readUint32Big() : -1), x7c_(CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF)), x7e_(CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF)), - x80_(CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF)), + x80_unfreezeSound(CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF)), x82_(CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF)), x84_(CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF)), x86_(propCount >= 45 ? CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF) : -1), @@ -126,7 +132,7 @@ CScriptGunTurret::CScriptGunTurret(TUniqueId uid, std::string_view name, ETurret const CHealthInfo& hInfo, const CDamageVulnerability& dVuln, const CActorParameters& aParms, const CScriptGunTurretData& turretData) : CPhysicsActor(uid, true, name, info, xf, std::move(mData), - comp == ETurretComponent::Turret ? skTurretMaterialList : skGunMaterialList, + comp == ETurretComponent::Base ? skTurretMaterialList : skGunMaterialList, aabb, SMoverData(1000.f), aParms, 0.3f, 0.1f) , x258_type(comp) , x264_healthInfo(hInfo) @@ -162,7 +168,7 @@ CScriptGunTurret::CScriptGunTurret(TUniqueId uid, std::string_view name, ETurret x560_30_ = true; x560_31_ = false; - if (comp == ETurretComponent::Turret && HasModelData() && GetModelData()->HasAnimData()) + if (comp == ETurretComponent::Base && HasModelData() && GetModelData()->HasAnimData()) ModelData()->EnableLooping(true); } @@ -171,15 +177,181 @@ void CScriptGunTurret::Accept(IVisitor& visitor) visitor.Visit(this); } -void CScriptGunTurret::AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager &) +void CScriptGunTurret::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { + CActor::AcceptScriptMsg(msg, uid, mgr); + switch(msg) + { + case EScriptObjectMessage::Activate: + if (x49c_collisionManager) + x49c_collisionManager->SetActive(mgr, true); + break; + case EScriptObjectMessage::Deactivate: + if (x49c_collisionManager) + x49c_collisionManager->SetActive(mgr, false); + break; + case EScriptObjectMessage::Registered: + if (x258_type == ETurretComponent::Gun) + { + if (x478_->SystemHasLight()) + { + x498_lightId = mgr.AllocateUniqueId(); + mgr.AddObject(new CGameLight(x498_lightId, GetAreaIdAlways(), GetActive(), + std::string("ParticleLight_") + GetName().data(), GetTransform(), + GetUniqueId(), x478_->GetLight(), 0, 1, 0.f)); + } + SetupCollisionManager(mgr); + } + else if (x258_type == ETurretComponent::Base) + { + zeus::CVector3f scale = GetModelData()->GetScale(); + if (x2d4_data.x88_.IsValid()) + { + CModelData mData(CStaticRes(x2d4_data.x88_, scale)); + x4a4_.emplace(std::move(mData)); + x4f4_ = x4a4_->GetBounds().max.z - x4a4_->GetBounds().min.z; + } + sub80219b18(5, mgr); + } + break; + case EScriptObjectMessage::Deleted: + { + if (x258_type == ETurretComponent::Gun) + { + if (x498_lightId != kInvalidUniqueId) + mgr.FreeScriptObject(x498_lightId); + } + if (x50c_) + CSfxManager::RemoveEmitter(x50c_); + + if (x49c_collisionManager) + x49c_collisionManager->Destroy(mgr); + break; + } + case EScriptObjectMessage::Start: + if (x258_type == ETurretComponent::Base && x520_ == 5) + x560_29_ = true; + break; + case EScriptObjectMessage::Stop: + if (x258_type == ETurretComponent::Base && x520_ != 1 && x520_ != 2 && x520_ != 3) + sub80219b18((!x560_28_ ? 3 : 4), mgr); + break; + case EScriptObjectMessage::Action: + { + if (x258_type == ETurretComponent::Gun) + sub80217408(mgr); + else if (x258_type == ETurretComponent::Base) + sub802172b8(mgr); + break; + } + case EScriptObjectMessage::SetToMax: + { + x560_25_ = false; + SetMuted(false); + break; + } + case EScriptObjectMessage::SetToZero: + { + x560_25_ = true; + SetMuted(true); + break; + } + case EScriptObjectMessage::InitializedInArea: + { + if (x258_type == ETurretComponent::Base) + { + for (const SConnection& conn : x20_conns) + { + if (conn.x0_state != EScriptObjectState::Play || conn.x4_msg != EScriptObjectMessage::Activate) + continue; + + if (TCastToConstPtr gun = mgr.GetObjectById(mgr.GetIdForScript(conn.x8_objId))) + { + x25c_ = mgr.GetIdForScript(conn.x8_objId); + x260_ = gun->GetHealthInfo(mgr)->GetHP(); + return; + } + } + } + break; + } + case EScriptObjectMessage::Damage: + { + if (x258_type == ETurretComponent::Gun && GetHealthInfo(mgr)->GetHP() > 0.f) + { + if (TCastToConstPtr proj = mgr.GetObjectById(uid)) + { + if ((proj->GetAttribField() & EProjectileAttrib::Wave) == EProjectileAttrib::Wave) + { + x520_ = 12; + RemoveMaterial(EMaterialTypes::Target, EMaterialTypes::Orbit, mgr); + mgr.GetPlayer().SetOrbitRequestForTarget(GetUniqueId(), + CPlayer::EPlayerOrbitRequest::ActivateOrbitSource, mgr); + x53c_ = 0.f; + } + } + } + break; + } + default: + break; + } } -void CScriptGunTurret::Think(float, CStateManager &) +void CScriptGunTurret::Think(float dt, CStateManager& mgr) { if (!GetActive()) return; + + if (x258_type == ETurretComponent::Base) + { + if (!x560_25_) + { + sub80219a00(dt, mgr); + sub802189c8(); + sub80217f5c(dt, mgr); + zeus::CVector3f vec = sub80217e34(dt); + SAdvancementDeltas advancementDeltas = UpdateAnimation(dt, mgr, true); + SetTranslation(vec + advancementDeltas.x0_posDelta + GetTranslation()); + RotateToOR(advancementDeltas.xc_rotDelta, dt); + } else + Stop(); + + sub80216288(dt); + } + else if (x258_type == ETurretComponent::Gun) + { + UpdatGunParticles(dt, mgr); + SAdvancementDeltas deltas = UpdateAnimation(dt, mgr, true); + MoveToOR(deltas.x0_posDelta, dt); + RotateToOR(deltas.xc_rotDelta, dt); + UpdateGunCollisionManager(dt, mgr); + GetUnFreezeSoundId(dt, mgr); + } +} + +void CScriptGunTurret::Touch(CActor& act, CStateManager& mgr) +{ + if (x258_type != ETurretComponent::Gun) + return; + if (TCastToPtr proj = act) + { + const CPlayer& player = mgr.GetPlayer(); + if (proj->GetOwnerId() == player.GetUniqueId()) + { + const CDamageVulnerability* dVuln = GetDamageVulnerability(); + if (!x560_24_ && x520_ != 12 && (proj->GetAttribField() & EProjectileAttrib::Ice) == EProjectileAttrib::Ice + && dVuln->WeaponHits(CWeaponMode::Ice(), false)) + { + x560_24_ = true; + SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None); + x53c_ = mgr.GetActiveRandom()->Float() * x2d4_data.x38_ + x2d4_data.x34_; + SetMuted(true); + } + SendScriptMsgs(EScriptObjectState::Damage, mgr, EScriptObjectMessage::None); + } + } } std::experimental::optional CScriptGunTurret::GetTouchBounds() const @@ -196,10 +368,594 @@ zeus::CVector3f CScriptGunTurret::GetOrbitPosition(const CStateManager& mgr) con zeus::CVector3f CScriptGunTurret::GetAimPosition(const CStateManager &, float) const { - if (x258_type == ETurretComponent::Turret) + if (x258_type == ETurretComponent::Base) return GetTranslation() + x34_transform.rotate(GetLocatorTransform("Gun_SDK"sv).origin); return GetTranslation(); } +void CScriptGunTurret::SetupCollisionManager(CStateManager&) +{ + +} + +void CScriptGunTurret::sub80219b18(s32 w1, CStateManager& mgr) +{ + + if (w1 < 0 || w1 > 12) + return; + + if (x520_ != -1) + sub8021998c(2, mgr, 0.f); + + + x520_ = w1; + x524_ = 0.f; + sub8021998c(0, mgr, 0.f); +} + +void CScriptGunTurret::sub80217408(CStateManager&) +{ + +} + +void CScriptGunTurret::sub802172b8(CStateManager&) +{ + +} + +void CScriptGunTurret::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) +{ + CActor::AddToRenderer(frustum, mgr); + + if (x258_type != ETurretComponent::Gun) + return; + + if (!x560_25_) + { + if (x520_ == 6 || (x520_ >= 9 && x520_ <= 12)) + { + g_Renderer->AddParticleGen(*x478_); + if (x520_ == 10 || x520_ == 12) + g_Renderer->AddParticleGen(*x488_); + } + else if (x520_ == 5) + { + g_Renderer->AddParticleGen(*x468_); + } + else if (x520_ >= 1) + { + g_Renderer->AddParticleGen(*x470_); + } + } + else + { + g_Renderer->AddParticleGen(*x480_); + } +} + +void CScriptGunTurret::Render(const CStateManager& mgr) const +{ + CPhysicsActor::Render(mgr); + + if (x258_type == ETurretComponent::Gun) + { + if (!x560_25_) + { + if (x520_ == 6 || (x520_ >= 9 && x520_ <= 12)) + { + x478_->Render(x90_actorLights.get()); + if (x520_ == 10) + x488_->Render(x90_actorLights.get()); + } + else if (x520_ == 5) + x468_->Render(x90_actorLights.get()); + else if (x520_ >= 1) + x470_->Render(x90_actorLights.get()); + } + } + else if (x258_type == ETurretComponent::Base) + { + if (x4a4_ && x4f8_ > 0.f) + { + zeus::CTransform xf = GetTransform(); + xf.origin = x4fc_ + (x4f4_ * 0.5f * zeus::CVector3f::skDown); + CModelFlags flags; + flags.x2_flags = 3; + flags.x1_matSetIdx = 0; + flags.x4_color = zeus::CColor::skWhite; + x4a4_->Render(mgr, xf, x90_actorLights.get(), flags); + } + + } +} + +void CScriptGunTurret::UpdateGunCollisionManager(float dt, CStateManager& mgr) +{ + if (TCastToPtr colAct = mgr.ObjectById(x4a0_)) + colAct->SetActive(mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed); + + x49c_collisionManager->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::Zero); +} + +void CScriptGunTurret::GetUnFreezeSoundId(float dt, CStateManager& mgr) +{ + if (x560_25_) + { + if (x53c_ <= 0.f) + { + SendScriptMsgs(EScriptObjectState::UnFrozen, mgr, EScriptObjectMessage::None); + CSfxManager::AddEmitter(x2d4_data.x80_unfreezeSound, GetTranslation(), zeus::CVector3f::skUp, false, false, + 0x7f, GetAreaIdAlways()); + SetMuted(false); + } + else if (x2d4_data.x3c_) + x53c_ -= dt; + } + else + x53c_ = 0.f; +} + +void CScriptGunTurret::UpdatGunParticles(float dt, CStateManager& mgr) +{ + CGameLight* light = nullptr; + if (x498_lightId != kInvalidUniqueId) + light = TCastToPtr(mgr.ObjectById(x498_lightId)); + + if (!x560_25_) + { + zeus::CTransform lightXf = GetLocatorTransform("light_LCTR"sv); + zeus::CVector3f pos = x34_transform.rotate(lightXf.origin); + pos += GetTranslation(); + if (light) + light->SetActive(true); + + if (x520_ == 6 || (x520_ >= 9 && x520_ <= 12)) + { + bool doEmission = false; + if (x520_ != 10 && x520_ != 12) + doEmission = true; + + x468_->SetParticleEmission(false); + x470_->SetParticleEmission(false); + x478_->SetParticleEmission(true); + x480_->SetParticleEmission(false); + x488_->SetParticleEmission(doEmission); + x478_->SetOrientation(GetTransform().getRotation()); + x478_->SetGlobalTranslation(pos); + x478_->SetGlobalScale(GetModelData()->GetScale()); + x478_->Update(dt); + if (x478_->SystemHasLight()) + light->SetLight(x478_->GetLight()); + else + light->SetActive(false); + + if (doEmission) + { + zeus::CTransform blastXf = GetLocatorTransform("Blast_LCTR"sv); + zeus::CVector3f blastPos = GetTransform().rotate(blastXf.origin); + blastPos += GetTranslation(); + x488_->SetOrientation(GetTransform().getRotation()); + x488_->SetGlobalTranslation(blastPos); + x488_->SetGlobalScale(GetModelData()->GetScale()); + x488_->Update(dt); + } + } + else if (x520_ == 5) + { + x468_->SetParticleEmission(true); + x470_->SetParticleEmission(false); + x478_->SetParticleEmission(false); + x480_->SetParticleEmission(false); + x488_->SetParticleEmission(false); + x490_->SetParticleEmission(false); + x468_->SetOrientation(GetTransform().getRotation()); + x468_->SetGlobalTranslation(pos); + x468_->SetGlobalScale(GetModelData()->GetScale()); + } + else if (x520_ > 0 && x520_ < 5) + { + x468_->SetParticleEmission(false); + x470_->SetParticleEmission(true); + x478_->SetParticleEmission(false); + x480_->SetParticleEmission(false); + x488_->SetParticleEmission(false); + x490_->SetParticleEmission(false); + x470_->SetOrientation(GetTransform().getRotation()); + x470_->SetGlobalTranslation(pos); + x470_->SetGlobalScale(GetModelData()->GetScale()); + x470_->Update(dt); + if (light && x470_->SystemHasLight()) + light->SetLight(x470_->GetLight()); + } + else + { + x468_->SetParticleEmission(false); + x470_->SetParticleEmission(false); + x478_->SetParticleEmission(false); + x480_->SetParticleEmission(false); + x488_->SetParticleEmission(false); + x490_->SetParticleEmission(false); + x480_->SetOrientation(GetTransform().getRotation()); + x480_->SetGlobalTranslation(GetTranslation()); + x480_->SetGlobalScale(GetModelData()->GetScale()); + x480_->Update(dt); + if (light) + light->SetActive(false); + } + } + else + { + x468_->SetParticleEmission(false); + x470_->SetParticleEmission(false); + x478_->SetParticleEmission(false); + x480_->SetParticleEmission(false); + x488_->SetParticleEmission(false); + x490_->SetParticleEmission(false); + x480_->SetOrientation(GetTransform().getRotation()); + x480_->SetGlobalTranslation(GetTranslation()); + x480_->SetGlobalScale(GetModelData()->GetScale()); + x480_->Update(dt); + if (light) + light->SetActive(false); + } +} + +void CScriptGunTurret::sub80219a00(float dt, CStateManager& mgr) +{ + sub80219b18(1, mgr); + x524_ += dt; + sub80217124(mgr); + if (x25c_ != kInvalidUniqueId) + { + if (TCastToPtr gunTurret = mgr.ObjectById(x25c_)) + { + if (gunTurret->x520_ != 12) + gunTurret->x520_ = x520_; + else if (x520_ != 12) + { + sub80219b18(12, mgr); + gunTurret->RemoveMaterial(EMaterialTypes::Target, EMaterialTypes::Orbit, mgr); + mgr.GetPlayer().SetOrbitRequestForTarget(GetUniqueId(), + CPlayer::EPlayerOrbitRequest::ActivateOrbitSource, mgr); + } + } + } +} + +void CScriptGunTurret::sub802189c8() +{ + if (!HasModelData() || !GetModelData()->HasAnimData()) + return; + + if (x520_ > 12) + return; + + static const u32 animIds[13] = {5, 7, 9, 0, 1, 0, 1, 2, 3, 1, 1, 1, 1}; + CPASAnimParmData parmData = CPASAnimParmData(5, CPASAnimParm::FromEnum(0), CPASAnimParm::FromEnum(animIds[x520_])); + auto pair = GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase().FindBestAnimation(parmData, -1); + + if (pair.first > 0.f && pair.second != x540_) + { + ModelData()->AnimationData()->SetAnimation(CAnimPlaybackParms(pair.second, -1, 1.f, true), false); + ModelData()->AnimationData()->EnableLooping(true); + x540_ = pair.second; + } + +} + +void CScriptGunTurret::sub8021998c(s32 w1, CStateManager& mgr, float dt) +{ + switch(x520_) + { + case 3: + case 4: + sub80219938(w1, mgr); + break; + case 5: + sub802196c4(w1, mgr, dt); + break; + case 6: + sub802195bc(w1, mgr, dt); + break; + case 7: + case 8: + sub8021942c(w1, mgr, dt); + break; + case 9: + case 10: + sub80218f50(w1, mgr, dt); + break; + case 11: + sub80218e34(w1, mgr, dt); + break; + case 12: + sub80218bb4(w1, mgr, dt); + break; + default: + break; + } +} + +void CScriptGunTurret::sub80219938(s32 w1, CStateManager& mgr) +{ + if (w1 == 1) + { + float f1 = x524_; + float f0 = x2d4_data.x0_; + if (f1 >= f0 && x560_28_) + w1 = 2; + + sub80219b18(w1, mgr); + } +} + +void CScriptGunTurret::sub802196c4(s32 w1, CStateManager& mgr, float dt) +{ + if (w1 == 0) + { + x528_ = 0.f; + x560_27_ = false; + if (TCastToPtr gunTurret = mgr.ObjectById(x25c_)) + x260_ = gunTurret->HealthInfo(mgr)->GetHP(); + } + else if (w1 == 1) + { + } + else if (w1 == 2) + { + x560_28_ = true; + x468_->SetParticleEmission(false); + + if (TCastToPtr gunTurret = mgr.ObjectById(x25c_)) + x260_ = gunTurret->GetHealthInfo(mgr)->GetHP(); + } +} + +void CScriptGunTurret::sub802195bc(s32 w1, CStateManager& mgr, float dt) +{ + if (w1 == 0) + { + x52c_ = 0.f; + } + else if (w1 == 1) + { + x52c_ += dt; + if (x52c_ < x2d4_data.x10_) + return; + + if (sub80217ad8(mgr) && sub802179a4(mgr)) + { + sub80219b18(9, mgr); + CSfxManager::AddEmitter(x2d4_data.x7e_, GetTranslation(), zeus::CVector3f::skUp, false, false, 0x7f, + GetAreaIdAlways()); + } + else + { + sub80219b18(7, mgr); + x530_ = 0.f; + } + } +} + +void CScriptGunTurret::sub8021942c(s32 state, CStateManager& mgr, float dt) +{ + if (state == 0) + { + x52c_ = 0.f; + } + else if (state == 1) + { + if (sub80217ad8(mgr) && sub802179a4(mgr)) + { + sub80219b18(9, mgr); + CSfxManager::AddEmitter(x2d4_data.x7e_, GetTranslation(), zeus::CVector3f::skUp, false, false, 0x7f, + GetAreaIdAlways()); + } + else + { + x52c_ += dt; + x530_ += dt; + if (x530_ >= x2d4_data.x18_ && !x4a4_ && !x2d4_data.xa0_) + sub80219b18(5, mgr); + else if (x52c_ >= x2d4_data.x14_) + sub80219b18(x520_ != 7 ? 7 : 8, mgr); + } + } +} + +void CScriptGunTurret::sub80218f50(s32 state, CStateManager& mgr, float dt) +{ + if (state == 0) + { + x52c_ = 0.f; + } + else if (state == 1) + { + if (!x560_26_) + { + if (sub802179a4(mgr)) + { + sub80218830(dt, mgr); + if (x25c_ != kInvalidUniqueId) + { + if (TCastToPtr gun = mgr.ObjectById(x25c_)) + { + zeus::CVector3f vec = x404_; + if (sub80217ad8(mgr)) + { + zeus::CTransform blastXf = gun->GetLocatorTransform("Blast_LCTR"sv); + zeus::CVector3f rotatedBlastVec = GetTransform().rotate(blastXf.origin) + GetTranslation(); + x404_ = mgr.GetPlayer().GetAimPosition(mgr, 0.f); + vec = x37c_projectileInfo.PredictInterceptPos(rotatedBlastVec, + mgr.GetPlayer().GetAimPosition(mgr, dt), + mgr.GetPlayer(), false); + } + + zeus::CVector3f compensated = x3a4_burstFire.GetDistanceCompensatedError( + (x404_ - gun->GetTranslation()).magnitude(), 20.f); + + compensated = gun->GetTransform().rotate(compensated); + + gun->x404_ = x404_ + (vec - x404_) + compensated; + } + } + + zeus::CVector3f diffVec = x404_ - GetTranslation(); + if (diffVec.canBeNormalized()) + { + zeus::CVector3f normDiff = diffVec.normalized(); + float angDif = zeus::CVector3f::getAngleDiff(normDiff, GetTransform().frontVector()); + zeus::CQuaternion quat = zeus::CQuaternion::lookAt(GetTransform().frontVector(), normDiff, + std::min(angDif, (dt * x2d4_data.x28_))); + + quat.setImaginary(GetTransform().transposeRotate(quat.getImaginary())); + RotateInOneFrameOR(quat, dt); + } + } + + if (sub80217950(mgr)) + { + SendScriptMsgs(EScriptObjectState::Attack, mgr, EScriptObjectMessage::None); + x560_26_ = true; + } + + x52c_ = 0.f; + } + else + { + x52c_ += dt; + if (x52c_ >= 10.f) + sub80219b18(11, mgr); + } + } + else if (state == 2) + { + x560_30_ = true; + } +} + +void CScriptGunTurret::sub80218e34(s32, CStateManager&, float) +{ + +} + +void CScriptGunTurret::sub80218bb4(s32, CStateManager&, float) +{ + +} + +bool CScriptGunTurret::sub80217ad8(CStateManager&) +{ + return false; +} + +bool CScriptGunTurret::sub802179a4(CStateManager&) +{ + return false; +} + +zeus::CVector3f CScriptGunTurret::sub80217e34(float dt) +{ + if (!x4a4_) + return {}; + + if (x520_ >= 7 && x520_ < 12) + x4f8_ = std::min(0.9f, x4f8_ + 1.5f * dt); + else if ((x520_ >= 0 && x520_ < 3) || x520_ == 5 || x520_ == 13) + x4f8_ = std::max(0.f, x4f8_ - 1.f * dt); + + return (x4fc_ + (x2d4_data.x8c_ * x4f8_ * zeus::CVector3f::skDown)) - GetTranslation(); +} + +void CScriptGunTurret::sub80217f5c(float dt, CStateManager& mgr) +{ + /* TODO: Finish */ + if (x25c_ == kInvalidUniqueId) + return; + + if (TCastToPtr gun = mgr.ObjectById(x25c_)) + { + zeus::CTransform xf = GetLocatorTransform("Gun_SDK"sv); + xf = GetTransform() * xf; + + switch(x520_) + { + case 11: + { + zeus::CVector3f frontVec = GetTransform().frontVector(); + zeus::CVector3f gunFrontVec = gun->GetTransform().frontVector(); + zeus::CQuaternion quat = zeus::CQuaternion::lookAt(gunFrontVec, frontVec, 0.3f * dt * x2d4_data.x28_); + zeus::CVector3f xposVec = gun->GetTransform().transposeRotate(quat.getImaginary()); + quat.setImaginary(xposVec); + gun->RotateInOneFrameOR(quat, dt); + RotateInOneFrameOR(quat, dt); + break; + } + case 12: + break; + default: + gun->SetTransform(xf); + break; + } + } +} + +void CScriptGunTurret::sub80216288(float) +{ + +} + +void CScriptGunTurret::sub80217124(CStateManager&) +{ + +} + +void CScriptGunTurret::sub80218830(float dt, CStateManager& mgr) +{ + if (mgr.GetCameraManager()->IsInCinematicCamera()) + { + x534_ = mgr.GetActiveRandom()->Float() * x2d4_data.xc_ + x2d4_data.x8_; + x538_ = 0.5f * x534_; + } + + if (x534_ > 0.f) + { + x534_ -= dt; + if (x534_ < x538_ && x520_ != 10) + { + CSfxManager::AddEmitter(x2d4_data.x84_, GetTranslation(), zeus::CVector3f::skUp, false, false, 0x7f, GetAreaIdAlways()); + sub80219b18(10, mgr); + return; + } + + if (x520_ != 9) + sub80219b18(9, mgr); + + if (x2d4_data.x18_ == 0) + { + sub80216594(mgr); + x534_ = mgr.GetActiveRandom()->Float() * x2d4_data.xc_ + x2d4_data.x8_; + x538_ = 0.5f * x534_; + return; + } + + x3a4_burstFire.Update(mgr, dt); + } +} + +void CScriptGunTurret::sub80216594(CStateManager&) +{ + +} + +bool CScriptGunTurret::sub80217950(CStateManager& mgr) +{ + if (x520_ == 9 && x534_ <= 0.f && x3a4_burstFire.GetX14_24()) + return sub80217ad8(mgr); + + return false; +} + + } diff --git a/Runtime/World/CScriptGunTurret.hpp b/Runtime/World/CScriptGunTurret.hpp index 5fa07b280..dc9b32c4c 100644 --- a/Runtime/World/CScriptGunTurret.hpp +++ b/Runtime/World/CScriptGunTurret.hpp @@ -8,7 +8,7 @@ namespace urde { - +class CCollisionActorManager; class CScriptGunTurretData { friend class CScriptGunTurret; @@ -39,7 +39,7 @@ class CScriptGunTurretData CAssetId x78_; u16 x7c_; u16 x7e_; - u16 x80_; + u16 x80_unfreezeSound; u16 x82_; u16 x84_; u16 x86_; @@ -78,9 +78,15 @@ class CScriptGunTurret : public CPhysicsActor public: enum class ETurretComponent { - Turret, + Base, Gun }; + enum class ETurretState + { + + }; +private: + ETurretComponent x258_type; TUniqueId x25c_ = kInvalidUniqueId; float x260_ = 0.f; @@ -104,15 +110,15 @@ public: std::unique_ptr x480_; std::unique_ptr x488_; std::unique_ptr x490_; - TUniqueId x498_ = kInvalidUniqueId; - u32 x49c_ = 0; + TUniqueId x498_lightId = kInvalidUniqueId; + std::unique_ptr x49c_collisionManager; TUniqueId x4a0_ = kInvalidUniqueId; std::experimental::optional x4a4_; float x4f4_ = 0.f; float x4f8_ = 0.f; zeus::CVector3f x4fc_; u8 x508_ = 0xFF; - u32 x50c_ = 0; + CSfxHandle x50c_ = 0; float x510_ = 0.f; zeus::CVector3f x514_; s32 x520_ = -1; @@ -138,6 +144,9 @@ public: u32 _dummy = 0; }; private: + + void SetupCollisionManager(CStateManager&); + public: CScriptGunTurret(TUniqueId uid, std::string_view name, ETurretComponent comp, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const zeus::CAABox& aabb, @@ -147,13 +156,40 @@ public: void Accept(IVisitor&); void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&); void Think(float, CStateManager&); + void Touch(CActor&, CStateManager&); + void AddToRenderer(const zeus::CFrustum&, const CStateManager&); + void Render(const CStateManager&) const; std::experimental::optional GetTouchBounds() const; zeus::CVector3f GetOrbitPosition(const CStateManager&) const; zeus::CVector3f GetAimPosition(const CStateManager&, float) const; CHealthInfo* HealthInfo(CStateManager&) { return &x264_healthInfo; } const CDamageVulnerability* GetDamageVulnerability() const { return &x26c_damageVuln; } - + void sub80219b18(s32, CStateManager&); + void sub8021998c(s32, CStateManager&, float); + void sub80217408(CStateManager&); + void sub802172b8(CStateManager&); + void sub80219a00(float, CStateManager&); + void sub802189c8(); + void UpdateGunCollisionManager(float, CStateManager&); + void GetUnFreezeSoundId(float, CStateManager&); + void UpdatGunParticles(float, CStateManager&); + void sub80219938(s32, CStateManager&); + void sub802196c4(s32, CStateManager&, float); + void sub802195bc(s32, CStateManager&, float); + void sub8021942c(s32, CStateManager&, float); + void sub80218f50(s32, CStateManager&, float); + void sub80218e34(s32, CStateManager&, float); + void sub80218bb4(s32, CStateManager&, float); + bool sub80217ad8(CStateManager&); + bool sub802179a4(CStateManager&); + void sub80217f5c(float, CStateManager&); + zeus::CVector3f sub80217e34(float); + void sub80216288(float); + void sub80217124(CStateManager&); + void sub80218830(float, CStateManager&); + void sub80216594(CStateManager&); + bool sub80217950(CStateManager&); }; } diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index 29851893f..3e458ab27 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -32,6 +32,9 @@ #include "CScriptControllerAction.hpp" #include "CScriptCounter.hpp" #include "MP1/World/CElitePirate.hpp" +#include "MP1/World/CMetroid.hpp" +#include "MP1/World/CMetroidBeta.hpp" +#include "MP1/World/CChozoGhost.hpp" #include "CScriptCoverPoint.hpp" #include "CScriptSpiderBallWaypoint.hpp" #include "CScriptDamageableTrigger.hpp" @@ -97,12 +100,14 @@ #include "MP1/World/CMetroidPrimeRelay.hpp" #include "MP1/World/CNewIntroBoss.hpp" #include "MP1/World/CSpacePirate.hpp" +#include "MP1/World/CFlyingPirate.hpp" #include "MP1/World/CWarWasp.hpp" #include "MP1/World/CParasite.hpp" #include "Particle/CWeaponDescription.hpp" #include "MP1/World/CBloodFlower.hpp" #include "MP1/World/CFlickerBat.hpp" #include "Camera/CPathCamera.hpp" + namespace urde { static logvisor::Module Log("urde::ScriptLoader"); @@ -261,11 +266,11 @@ CActorParameters ScriptLoader::LoadActorParameters(CInputStream& in) if (propCount > 13) thermalMag = in.readFloatBig(); - std::pair xray = {}; + std::pair xray = {}; if (g_ResFactory->GetResourceTypeById(xrayModel)) xray = {xrayModel, xraySkin}; - std::pair infra = {}; + std::pair infra = {}; if (g_ResFactory->GetResourceTypeById(infraModel)) infra = {infraModel, infraSkin}; @@ -544,7 +549,7 @@ CEntity* ScriptLoader::LoadTrigger(CStateManager& mgr, CInputStream& in, int pro zeus::CVector3f forceVec = zeus::CVector3f::ReadBig(in); ETriggerFlags - flags = ETriggerFlags(in.readUint32Big()); + flags = ETriggerFlags(in.readUint32Big()); bool active = in.readBool(); bool b2 = in.readBool(); bool b3 = in.readBool(); @@ -672,7 +677,7 @@ CEntity* ScriptLoader::LoadPlatform(CStateManager& mgr, CInputStream& in, int pr zeus::CAABox aabb = GetCollisionBox(mgr, info.GetAreaId(), extent, centroid); FourCC dclnType = g_ResFactory->GetResourceTypeById(dclnId); - std::experimental::optional > dclnToken; + std::experimental::optional> dclnToken; if (dclnType) { dclnToken.emplace(g_SimplePool->GetObj({SBIG('DCLN'), dclnId})); @@ -1036,7 +1041,7 @@ CEntity* ScriptLoader::LoadBeetle(CStateManager& mgr, CInputStream& in, int prop if (animType != SBIG('ANCS')) return nullptr; - std::experimental::optional abdomenRes; + std::experimental::optional abdomenRes; if (flavor == CPatterned::EFlavorType::One) abdomenRes.emplace(CStaticRes(abdomen, scale)); @@ -1238,11 +1243,11 @@ CEntity* ScriptLoader::LoadWater(CStateManager& mgr, CInputStream& in, int propC zeus::CVector3f orientedForce; orientedForce.readBig(in); ETriggerFlags - triggerFlags = ETriggerFlags(in.readUint32Big()) | ETriggerFlags::DetectProjectiles1 | - ETriggerFlags::DetectProjectiles2 | ETriggerFlags::DetectProjectiles3 | - ETriggerFlags::DetectProjectiles4 | ETriggerFlags::DetectBombs | - ETriggerFlags::DetectPowerBombs | ETriggerFlags::DetectProjectiles5 | - ETriggerFlags::DetectProjectiles6 | ETriggerFlags::DetectProjectiles7; + triggerFlags = ETriggerFlags(in.readUint32Big()) | ETriggerFlags::DetectProjectiles1 | + ETriggerFlags::DetectProjectiles2 | ETriggerFlags::DetectProjectiles3 | + ETriggerFlags::DetectProjectiles4 | ETriggerFlags::DetectBombs | + ETriggerFlags::DetectPowerBombs | ETriggerFlags::DetectProjectiles5 | + ETriggerFlags::DetectProjectiles6 | ETriggerFlags::DetectProjectiles7; bool thermalCold = in.readBool(); bool displaySurface = in.readBool(); CAssetId patternMap1 = in.readUint32Big(); @@ -1309,7 +1314,7 @@ CEntity* ScriptLoader::LoadWater(CStateManager& mgr, CInputStream& in, int propC u32 w22 = in.readUint32Big(); bool b5 = in.readBool(); - std::unique_ptr < u32[] > bitset; + std::unique_ptr bitset; u32 bitVal0 = 0; u32 bitVal1 = 0; @@ -1413,7 +1418,27 @@ CEntity* ScriptLoader::LoadSpacePirate(CStateManager& mgr, CInputStream& in, int CEntity* ScriptLoader::LoadFlyingPirate(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { - return nullptr; + if (!EnsurePropertyCount(propCount, 35, "FlyingPirate")) + return nullptr; + + SScaledActorHead actHead = LoadScaledActorHead(in, mgr); + auto pair = CPatternedInfo::HasCorrectParameterCount(in); + if (pair.first) + return nullptr; + + CPatternedInfo pInfo(in, pair.second); + CActorParameters actParms = LoadActorParameters(in); + + if (g_ResFactory->GetResourceTypeById(pInfo.GetAnimationParameters().GetACSFile()) != SBIG('ANCS')) + return nullptr; + + const CAnimationParameters& animParms = pInfo.GetAnimationParameters(); + CModelData mData( + CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), actHead.x40_scale, animParms.GetInitialAnimation(), + true)); + + return new MP1::CFlyingPirate(mgr.AllocateUniqueId(), actHead.x0_name, info, actHead.x10_transform, + std::move(mData), actParms, pInfo, in, propCount); } CEntity* ScriptLoader::LoadElitePirate(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) @@ -1444,12 +1469,79 @@ CEntity* ScriptLoader::LoadElitePirate(CStateManager& mgr, CInputStream& in, int CEntity* ScriptLoader::LoadMetroidBeta(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { - return nullptr; + if (!EnsurePropertyCount(propCount, 23, "MetroidBeta")) + return nullptr; + + std::string name = mgr.HashInstanceName(in); + zeus::CTransform xf = LoadEditorTransform(in); + zeus::CVector3f scale = zeus::CVector3f::ReadBig(in); + auto pair = CPatternedInfo::HasCorrectParameterCount(in); + if (!pair.first) + return nullptr; + + CPatternedInfo pInfo(in, pair.second); + CActorParameters actParms = LoadActorParameters(in); + MP1::CMetroidBetaData metData(in); + if (!pInfo.GetAnimationParameters().GetACSFile().IsValid()) + return nullptr; + + const CAnimationParameters& animParms = pInfo.GetAnimationParameters(); + CModelData mData( + CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), scale, animParms.GetInitialAnimation(), true)); + + return new MP1::CMetroidBeta(mgr.AllocateUniqueId(), name, info, xf, std::move(mData), pInfo, actParms, metData); } CEntity* ScriptLoader::LoadChozoGhost(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { - return nullptr; + if (!EnsurePropertyCount(propCount, 32, "ChozoGhost")) + return nullptr; + + SScaledActorHead actorHead = LoadScaledActorHead(in, mgr); + + auto pair = CPatternedInfo::HasCorrectParameterCount(in); + + if (!pair.first) + return nullptr; + + CPatternedInfo pInfo(in, pair.second); + CActorParameters actParms = LoadActorParameters(in); + float f1 = in.readFloatBig(); + float f2 = in.readFloatBig(); + float f3 = in.readFloatBig(); + float f4 = in.readFloatBig(); + CAssetId wpsc1(in); + CDamageInfo dInfo1(in); + CAssetId wpsc2(in); + CDamageInfo dInfo2(in); + MP1::CChozoGhost::CBehaveChance behaveChance1(in); + MP1::CChozoGhost::CBehaveChance behaveChance2(in); + MP1::CChozoGhost::CBehaveChance behaveChance3(in); + s16 sId1 = CSfxManager::TranslateSFXID(in.readUint32Big()); + float f5 = in.readFloatBig(); + s16 sId2 = CSfxManager::TranslateSFXID(in.readUint32Big()); + s16 sId3 = CSfxManager::TranslateSFXID(in.readUint32Big()); + u32 w1 = in.readUint32Big(); + float f6 = in.readFloatBig(); + u32 w2 = in.readUint32Big(); + float f7 = in.readFloatBig(); + CAssetId partId(in); + s16 sId4 = CSfxManager::TranslateSFXID(in.readUint32Big()); + float f8 = in.readFloatBig(); + float f9 = in.readFloatBig(); + u32 w3 = in.readUint32Big(); + u32 w4 = in.readUint32Big(); + + const CAnimationParameters& animParms = pInfo.GetAnimationParameters(); + if (g_ResFactory->GetResourceTypeById(animParms.GetACSFile()) != SBIG('ANCS')) + return nullptr; + + CModelData mData(CAnimRes(animParms.GetACSFile(), 0, actorHead.x40_scale, animParms.GetInitialAnimation(), true)); + + return new MP1::CChozoGhost(mgr.AllocateUniqueId(), actorHead.x0_name, info, actorHead.x10_transform, + std::move(mData), actParms, pInfo, f1, f2, f3, f4, wpsc1, dInfo1, wpsc2, dInfo2, + behaveChance1, behaveChance2, behaveChance3, sId1, f5, sId2, sId3, w1, f6, w2, f7, + partId, sId4, f8, f9, w3, w4); } CEntity* ScriptLoader::LoadCoverPoint(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) @@ -1586,7 +1678,22 @@ CEntity* ScriptLoader::LoadGrapplePoint(CStateManager& mgr, CInputStream& in, in CEntity* ScriptLoader::LoadPuddleSpore(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { + if (!EnsurePropertyCount(propCount, 16, "PuddleSpore")) + return nullptr; + + std::string name = mgr.HashInstanceName(in); + CPatterned::EFlavorType flavor = CPatterned::EFlavorType(in.readUint32Big()); + zeus::CTransform xf = LoadEditorTransform(in); + zeus::CVector3f scale = zeus::CVector3f::ReadBig(in); + + auto pair = CPatternedInfo::HasCorrectParameterCount(in); + if (!pair.first) + return nullptr; + + CPatternedInfo pInfo(in, pair.second); + return nullptr; + } CEntity* ScriptLoader::LoadDebugCameraWaypoint(CStateManager& mgr, CInputStream& in, int propCount, @@ -1955,7 +2062,7 @@ CEntity* ScriptLoader::LoadSteam(CStateManager& mgr, CInputStream& in, int propC zeus::CVector3f v3 = zeus::CVector3f::ReadBig(in); ETriggerFlags - w1 = ETriggerFlags(in.readUint32Big()); + w1 = ETriggerFlags(in.readUint32Big()); bool b1 = in.readBool(); u32 w2 = in.readUint32Big(); float f1 = in.readFloatBig(); @@ -2185,7 +2292,7 @@ CEntity* ScriptLoader::LoadVisorFlare(CStateManager& mgr, CInputStream& in, int float f2 = in.readFloatBig(); float f3 = in.readFloatBig(); u32 w2 = in.readUint32Big(); - std::vector flares; + std::vector flares; flares.reserve(5); for (int i = 0; i < 5; ++i) if (auto flare = CVisorFlare::LoadFlareDef(in)) @@ -3200,7 +3307,7 @@ CEntity* ScriptLoader::LoadBeam(CStateManager& mgr, CInputStream& in, int propCo CBeamInfo beamInfo(in); CDamageInfo dInfo(in); - TToken weaponDesc = g_SimplePool->GetObj({SBIG('WPSC'), weaponDescId}); + TToken weaponDesc = g_SimplePool->GetObj({SBIG('WPSC'), weaponDescId}); return new CScriptBeam(mgr.AllocateUniqueId(), aHead.x0_name, info, aHead.x10_transform, active, weaponDesc, beamInfo, dInfo); @@ -3336,4 +3443,4 @@ CEntity* ScriptLoader::LoadEnergyBall(CStateManager& mgr, CInputStream& in, int { return nullptr; } -} // namespace urde +}// namespace urde