From b251bc541f8698ad60e64afb52e3d8bb5555ef0a Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Sun, 9 Jun 2019 17:09:07 -0700 Subject: [PATCH] CFlaahgraTentacle implementations (needs testing) --- Runtime/MP1/World/CFlaahgra.cpp | 0 Runtime/MP1/World/CFlaahgra.hpp | 15 ++ Runtime/MP1/World/CFlaahgraTentacle.cpp | 234 ++++++++++++++++++++++++ Runtime/MP1/World/CFlaahgraTentacle.hpp | 44 +++++ Runtime/MP1/World/CMakeLists.txt | 2 + Runtime/World/CScriptEffect.cpp | 4 +- Runtime/World/CScriptTrigger.hpp | 5 + Runtime/World/ScriptLoader.cpp | 23 ++- 8 files changed, 324 insertions(+), 3 deletions(-) create mode 100644 Runtime/MP1/World/CFlaahgra.cpp create mode 100644 Runtime/MP1/World/CFlaahgra.hpp create mode 100644 Runtime/MP1/World/CFlaahgraTentacle.cpp create mode 100644 Runtime/MP1/World/CFlaahgraTentacle.hpp diff --git a/Runtime/MP1/World/CFlaahgra.cpp b/Runtime/MP1/World/CFlaahgra.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Runtime/MP1/World/CFlaahgra.hpp b/Runtime/MP1/World/CFlaahgra.hpp new file mode 100644 index 000000000..2dfc059a3 --- /dev/null +++ b/Runtime/MP1/World/CFlaahgra.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "World/CPatterned.hpp" + +namespace urde::MP1 { +class CFlaahgraData { + friend class CFlaahgra; +}; + +class CFlaahgra : public CPatterned { +public: + DEFINE_PATTERNED(Flaahgra); + +}; +} \ No newline at end of file diff --git a/Runtime/MP1/World/CFlaahgraTentacle.cpp b/Runtime/MP1/World/CFlaahgraTentacle.cpp new file mode 100644 index 000000000..77b7bed44 --- /dev/null +++ b/Runtime/MP1/World/CFlaahgraTentacle.cpp @@ -0,0 +1,234 @@ +#include "CFlaahgraTentacle.hpp" +#include "Collision/CCollisionActor.hpp" +#include "World/CPlayer.hpp" +#include "World/CScriptTrigger.hpp" +#include "CStateManager.hpp" +#include "TCastTo.hpp" + +namespace urde::MP1 { +CFlaahgraTentacle::CFlaahgraTentacle(TUniqueId uid, std::string_view name, const CEntityInfo& info, + const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, + const CActorParameters& actParms) +: CPatterned(ECharacter::FlaahgraTentacle, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo, + EMovementType::Flyer, EColliderType::One, EBodyType::Restricted, actParms, EKnockBackVariant::Large) { + x58e_24_ = false; + ActorLights()->SetCastShadows(false); + x460_knockBackController.SetAutoResetImpulse(false); + CreateShadow(true); +} +void CFlaahgraTentacle::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { + + switch (msg) { + case EScriptObjectMessage::Registered: { + x450_bodyController->Activate(mgr); + SetupCollisionManager(mgr); + break; + } + case EScriptObjectMessage::Deleted: { + x56c_collisionManager->Destroy(mgr); + if (TCastToPtr trigger = mgr.ObjectById(x58c_triggerId)) { + trigger->SetForceVector(x580_forceVector); + } + break; + } + case EScriptObjectMessage::Touched: { + if (TCastToConstPtr colAct = mgr.GetObjectById(uid)) { + if (colAct->GetLastTouchedObject() == mgr.GetPlayer().GetUniqueId() && x420_curDamageRemTime <= 0.f) { + mgr.ApplyDamage(mgr.GetPlayer().GetUniqueId(), GetUniqueId(), GetUniqueId(), GetContactDamage(), + CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), {}); + x420_curDamageRemTime = x424_damageWaitTime; + } + } + break; + } + case EScriptObjectMessage::Play: { + x578_ = 0.039999999f; + break; + } + case EScriptObjectMessage::Deactivate: { + DeathDelete(mgr); + break; + } + case EScriptObjectMessage::Open: { + ExtractTentacle(mgr); + break; + } + case EScriptObjectMessage::Close: { + RetractTentacle(mgr); + break; + } + case EScriptObjectMessage::InitializedInArea: { + SaveBombSlotInfo(mgr); + break; + } + default: + break; + } + + CPatterned::AcceptScriptMsg(msg, uid, mgr); +} + +void CFlaahgraTentacle::Think(float dt, CStateManager& mgr) { + if (!GetActive()) + return; + + CPatterned::Think(dt, mgr); + x56c_collisionManager->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); + + if (x574_ > 0.f) + x574_ -= dt; + + if (x578_ > 0.f) + x578_ -= dt; +} + +void CFlaahgraTentacle::AddSphereCollisionList(const SSphereJointInfo* sphereJoints, s32 jointCount, + std::vector& outJoints) { + + const CAnimData* animData = GetModelData()->GetAnimationData(); + + for (u32 i = 0; i < jointCount; ++i) { + CSegId segId = animData->GetLocatorSegId(sphereJoints[i].name); + if (segId == 0xFF) + continue; + outJoints.push_back( + CJointCollisionDescription::SphereCollision(segId, sphereJoints->radius, sphereJoints->name, 10.f)); + } +} + +const SSphereJointInfo CFlaahgraTentacle::skJointList[3] = {{"Arm_8", 2.f}, {"Arm_10", 1.2f}, {"Arm_12", 1.2f}}; + +void CFlaahgraTentacle::SetupCollisionManager(CStateManager& mgr) { + std::vector jointList; + AddSphereCollisionList(skJointList, 3, jointList); + x56c_collisionManager.reset(new CCollisionActorManager(mgr, GetUniqueId(), GetAreaIdAlways(), jointList, true)); + + for (u32 i = 0; i < x56c_collisionManager->GetNumCollisionActors(); ++i) { + const CJointCollisionDescription& desc = x56c_collisionManager->GetCollisionDescFromIndex(i); + if (TCastToPtr colAct = mgr.ObjectById(desc.GetCollisionActorId())) { + colAct->SetMaterialFilter(CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Player}, + {EMaterialTypes::Character, + EMaterialTypes::CollisionActor, + EMaterialTypes::NoStaticCollision, + EMaterialTypes::NoPlatformCollision})); + colAct->AddMaterial(EMaterialTypes::ScanPassthrough); + colAct->SetDamageVulnerability(*GetDamageVulnerability()); + + if (x57c_tentacleTipAct == kInvalidUniqueId && desc.GetName() == skpTentacleTip) + x57c_tentacleTipAct = desc.GetCollisionActorId(); + } + } + + RemoveMaterial(EMaterialTypes::Solid, EMaterialTypes::Target, EMaterialTypes::Orbit, mgr); + AddMaterial(EMaterialTypes::Scannable, mgr); + +} +zeus::CVector3f CFlaahgraTentacle::GetAimPosition(const CStateManager& mgr, float dt) const { + if (TCastToConstPtr colAct = mgr.GetObjectById(x57c_tentacleTipAct)) + return colAct->GetTranslation(); + + return CPatterned::GetAimPosition(mgr, dt); +} +void CFlaahgraTentacle::ExtractTentacle(CStateManager& mgr) { + if (!Inside(mgr, 0.f)) + return; + + x58e_24_ = true; + + if (TCastToPtr trigger = mgr.ObjectById(x58c_triggerId)) { + trigger->SetForceVector(x580_forceVector); + } +} + +void CFlaahgraTentacle::RetractTentacle(CStateManager& mgr) { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Crouch); + if (TCastToPtr trigger = mgr.ObjectById(x58c_triggerId)) { + trigger->SetForceVector({}); + } +} +void CFlaahgraTentacle::SaveBombSlotInfo(CStateManager& mgr) { + for (const SConnection& conn : GetConnectionList()) { + if (conn.x0_state != EScriptObjectState::Modify || conn.x4_msg != EScriptObjectMessage::ToggleActive) + continue; + + TUniqueId uid = mgr.GetIdForScript(conn.x8_objId); + if (TCastToConstPtr trigger = mgr.GetObjectById(uid)) { + x58c_triggerId = uid; + x580_forceVector = trigger->GetForceVector(); + return; + } + } +} + +bool CFlaahgraTentacle::ShouldAttack(CStateManager& mgr, float) { + if (x578_ > 0.f) + return true; + + /* FIXME: Double check this */ + if (x574_ > 0.f || mgr.GetPlayer().IsInWaterMovement()) + return false; + + if (TCastToConstPtr colAct = mgr.GetObjectById(x57c_tentacleTipAct)) { + float mag = (colAct->GetTranslation().toVec2f() - mgr.GetPlayer().GetTranslation().toVec2f()).magSquared(); + return mag >= (x2fc_minAttackRange * x2fc_minAttackRange) && mag <= (x300_maxAttackRange * x300_maxAttackRange); + } + + return false; +} + +void CFlaahgraTentacle::Attack(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Activate) { + x568_ = 0; + } else if (msg == EStateMsg::Update) { + if (x568_ == 0) { + if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::MeleeAttack) + x568_ = 2; + else + x450_bodyController->GetCommandMgr().DeliverCmd( + CBCMeleeAttackCmd((x578_ > 0.f ? pas::ESeverity::Zero : pas::ESeverity::One), {})); + + } else if (x568_ == 2 && x450_bodyController->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::MeleeAttack) { + x568_ = 3; + } + + } else if (msg == EStateMsg::Deactivate) { + x574_ = (x308_attackTimeVariation * mgr.GetActiveRandom()->Float()) + x304_averageAttackTime; + x578_ = 0.f; + } +} +void CFlaahgraTentacle::Retreat(CStateManager& mgr, EStateMsg msg, float) { + if (msg == EStateMsg::Update) { + if (!x58e_24_) + return; + + if (x330_stateMachineState.GetTime() <= 1.f) + return; + + if (TCastToPtr trigger = mgr.ObjectById(x58c_triggerId)) { + if (trigger->IsPlayerTriggerProc()) + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); + } + } else if (msg == EStateMsg::Deactivate) { + x58e_24_ = false; + } +} +void CFlaahgraTentacle::InActive(CStateManager& mgr, EStateMsg msg, float arg) { + if (msg == EStateMsg::Activate) { + x570_ = 0.f; + } else if (msg == EStateMsg::Update) { + if (Inside(mgr, 0.f)) + return; + + if (TCastToPtr trigger = mgr.ObjectById(x58c_triggerId)) { + if (trigger->IsPlayerTriggerProc()) { + if (x570_ > 1.f) { + RetractTentacle(mgr); + ExtractTentacle(mgr); + } else + x570_ += arg; + } + } + } +} + +} \ No newline at end of file diff --git a/Runtime/MP1/World/CFlaahgraTentacle.hpp b/Runtime/MP1/World/CFlaahgraTentacle.hpp new file mode 100644 index 000000000..86a26675f --- /dev/null +++ b/Runtime/MP1/World/CFlaahgraTentacle.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include "World/CPatterned.hpp" +#include "Collision/CCollisionActorManager.hpp" + +namespace urde::MP1 { +class CFlaahgraTentacle : public CPatterned { + static const SSphereJointInfo skJointList[3]; + static constexpr std::string_view skpTentacleTip = "Arm_12"sv; + s32 x568_ = -1; + std::unique_ptr x56c_collisionManager; + float x570_ = 0.f; + float x574_ = 0.f; + float x578_ = 0.f; + TUniqueId x57c_tentacleTipAct = kInvalidUniqueId; + zeus::CVector3f x580_forceVector; + TUniqueId x58c_triggerId = kInvalidUniqueId; + bool x58e_24_ : 1; + + void AddSphereCollisionList(const SSphereJointInfo*, s32, std::vector&); + void SetupCollisionManager(CStateManager&); + void ExtractTentacle(CStateManager&); + void RetractTentacle(CStateManager&); + void SaveBombSlotInfo(CStateManager&); +public: + DEFINE_PATTERNED(FlaahgraTentacle); + CFlaahgraTentacle(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&, + const CPatternedInfo&, const CActorParameters&); + + void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&); + void Think(float, CStateManager&); + + zeus::CVector3f GetAimPosition(const CStateManager&, float) const; + + bool Inside(CStateManager&, float) { return x450_bodyController->GetLocomotionType() == pas::ELocomotionType::Crouch; } + bool AnimOver(CStateManager&, float) { return x568_ == 3; } + bool ShouldAttack(CStateManager&, float); + + void Dead(CStateManager&, EStateMsg, float) { x450_bodyController->SetLocomotionType(pas::ELocomotionType::Crouch); } + void Attack(CStateManager&, EStateMsg, float); + void Retreat(CStateManager&, EStateMsg, float); + void InActive(CStateManager&, EStateMsg, float); +}; +} \ No newline at end of file diff --git a/Runtime/MP1/World/CMakeLists.txt b/Runtime/MP1/World/CMakeLists.txt index d4f15b72c..6d945649d 100644 --- a/Runtime/MP1/World/CMakeLists.txt +++ b/Runtime/MP1/World/CMakeLists.txt @@ -30,6 +30,8 @@ set(MP1_WORLD_SOURCES CSeedling.hpp CSeedling.cpp CRidley.hpp CRidley.cpp CPuddleToadGamma.hpp CPuddleToadGamma.cpp + CFlaahgra.hpp CFlaahgra.cpp + CFlaahgraTentacle.hpp CFlaahgraTentacle.cpp CFlaahgraProjectile.hpp CFlaahgraProjectile.cpp CSpankWeed.hpp CSpankWeed.cpp CPuddleSpore.hpp CPuddleSpore.cpp) diff --git a/Runtime/World/CScriptEffect.cpp b/Runtime/World/CScriptEffect.cpp index e2ccbca79..9acdac5c5 100644 --- a/Runtime/World/CScriptEffect.cpp +++ b/Runtime/World/CScriptEffect.cpp @@ -242,12 +242,12 @@ void CScriptEffect::Render(const CStateManager& mgr) const { */ if (x104_particleSystem && x104_particleSystem->GetParticleCountAll() > 0) { g_NumParticlesRendered += x104_particleSystem->GetParticleCountAll(); - x104_particleSystem->Render(GetActorLights()); + x104_particleSystem->Render(x138_actorLights.get()); } if (xf4_electric && xf4_electric->GetParticleCount() > 0) { g_NumParticlesRendered += xf4_electric->GetParticleCount(); - xf4_electric->Render(GetActorLights()); + xf4_electric->Render(x138_actorLights.get()); } } diff --git a/Runtime/World/CScriptTrigger.hpp b/Runtime/World/CScriptTrigger.hpp index e2a8b327a..75e622cc9 100644 --- a/Runtime/World/CScriptTrigger.hpp +++ b/Runtime/World/CScriptTrigger.hpp @@ -84,5 +84,10 @@ public: ETriggerFlags GetTriggerFlags() const { return x12c_flags; } float GetForceMagnitude() const { return x128_forceMagnitude; } const zeus::CVector3f& GetForceVector() const { return x11c_forceField; } + void SetForceVector(const zeus::CVector3f& force) { + x11c_forceField = force; + x128_forceMagnitude = x11c_forceField.magnitude(); + } + bool IsPlayerTriggerProc() const { return x148_28_playerTriggerProc; } }; } // namespace urde diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index dec6f1214..2353e87ff 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -10,6 +10,8 @@ #include "CScriptActorKeyframe.hpp" #include "CScriptActorRotate.hpp" #include "CScriptAiJumpPoint.hpp" +#include "MP1/World/CFlaahgra.hpp" +#include "MP1/World/CFlaahgraTentacle.hpp" #include "CScriptAreaAttributes.hpp" #include "MP1/World/CSeedling.hpp" #include "MP1/World/CBurrower.hpp" @@ -2522,7 +2524,26 @@ CEntity* ScriptLoader::LoadAiJumpPoint(CStateManager& mgr, CInputStream& in, int CEntity* ScriptLoader::LoadFlaahgraTentacle(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { - return nullptr; + + if (!EnsurePropertyCount(propCount, 6, "FlaahgraTentacle")) + 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 (!pInfo.GetAnimationParameters().GetACSFile().IsValid()) + return nullptr; + + const CAnimationParameters& animParms = pInfo.GetAnimationParameters(); + CModelData mData(CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), actHead.x40_scale, + animParms.GetInitialAnimation(), true)); + + return new MP1::CFlaahgraTentacle(mgr.AllocateUniqueId(), actHead.x0_name, info, actHead.x10_transform, + std::move(mData), pInfo, actParms); } CEntity* ScriptLoader::LoadRoomAcoustics(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) {