From b2b0a6aee07c9c8b9fbf741220c33953ca325fa6 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Sat, 17 Nov 2018 21:10:06 -0800 Subject: [PATCH] CMetaree imps --- Runtime/Character/CBodyStateCmdMgr.hpp | 1 + Runtime/MP1/World/CMetaree.cpp | 190 +++++++++++++++++++++++-- Runtime/MP1/World/CMetaree.hpp | 38 +++-- Runtime/Weapon/CGameProjectile.hpp | 1 + Runtime/World/ScriptLoader.cpp | 3 +- 5 files changed, 210 insertions(+), 23 deletions(-) diff --git a/Runtime/Character/CBodyStateCmdMgr.hpp b/Runtime/Character/CBodyStateCmdMgr.hpp index 039855b6e..56672163a 100644 --- a/Runtime/Character/CBodyStateCmdMgr.hpp +++ b/Runtime/Character/CBodyStateCmdMgr.hpp @@ -465,6 +465,7 @@ public: const zeus::CVector3f& GetMoveVector() const { return x0_move; } const zeus::CVector3f& GetFaceVector() const { return xc_face; } const zeus::CVector3f& GetTargetVector() const { return x18_target; } + void SetTargetVector(const zeus::CVector3f& target) { x18_target = target; } const zeus::CVector3f& GetAdditiveTargetVector() const { return x24_additiveTarget; } }; diff --git a/Runtime/MP1/World/CMetaree.cpp b/Runtime/MP1/World/CMetaree.cpp index b0d82615c..2cf7d8570 100644 --- a/Runtime/MP1/World/CMetaree.cpp +++ b/Runtime/MP1/World/CMetaree.cpp @@ -1,4 +1,11 @@ -#include "CMetaree.hpp" +#include "MP1/World/CMetaree.hpp" +#include "Weapon/CGameProjectile.hpp" +#include "World/CPlayer.hpp" +#include "CStateManager.hpp" +#include "CPlayerState.hpp" + +#include "TCastTo.hpp" + namespace urde::MP1 { @@ -8,14 +15,14 @@ CMetaree::CMetaree(TUniqueId uid, std::string_view name, EFlavorType flavor, con const CActorParameters& aParms) : CPatterned(ECharacter::Metaree, uid, name, flavor, info, xf, std::move(mData), pInfo, EMovementType::Flyer, EColliderType::Zero, bodyType, aParms, EKnockBackVariant::Small) -, x568_(f3) +, x568_delay(f3) , x56c_(f4) -, x570_(f1) -, x574_(v1) -, x580_(f2) +, x570_dropHeight(f1) +, x574_offset(v1) +, x580_attackSpeed(f2) , x5ca_24_(true) -, x5ca_25_(false) -, x5ca_26_(false) +, x5ca_25_started(false) +, x5ca_26_deactivated(false) { } @@ -29,8 +36,175 @@ void CMetaree::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa CPatterned::AcceptScriptMsg(msg, uid, mgr); if (msg == EScriptObjectMessage::Start) - x5ca_25_ = true; + x5ca_25_started = true; else if (msg == EScriptObjectMessage::Registered) x450_bodyController->Activate(mgr); } + +void CMetaree::Think(float dt, CStateManager& mgr) +{ + bool target = true; + if (mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::EPlayerVisor::Thermal && + mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::EPlayerVisor::Scan) + { + target = x5ca_26_deactivated; + } + xe7_31_targetable = target; + CPatterned::Think(dt, mgr); +} + +void CMetaree::Explode(CStateManager& mgr, EStateMsg msg, float) +{ + if (msg != EStateMsg::Activate) + return; + + mgr.ApplyDamage(GetUniqueId(), mgr.GetPlayer().GetUniqueId(), GetUniqueId(), x5ac_damgeInfo, + CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), {}); + MassiveDeath(mgr); +} + +void CMetaree::Touch(CActor& act, CStateManager& mgr) +{ + if (!x400_25_alive) + return; + + if (TCastToPtr projectile = act) + { + if (projectile->GetOwnerId() != mgr.GetPlayer().GetUniqueId()) + return; + + x400_24_hitByPlayerProjectile = true; + x590_projectileDelta = projectile->GetTranslation() - projectile->GetPreviousPos(); + } +} + +void CMetaree::CollidedWith(TUniqueId& id, const CCollisionInfoList& colList, CStateManager& mgr) +{ + if (!x400_25_alive || colList.GetCount() <= 0) + return; + + mgr.ApplyDamageToWorld(GetUniqueId(), *this, GetTranslation(), x5ac_damgeInfo, + CMaterialFilter::MakeInclude({EMaterialTypes::Player})); + SendScriptMsgs(EScriptObjectState::Arrived, mgr, EScriptObjectMessage::None); + MassiveDeath(mgr); +} + +void CMetaree::Flee(CStateManager& mgr, EStateMsg msg, float) +{ + if (msg == EStateMsg::Activate) + { + ApplyImpulseWR(5.f * (GetMass() * (x590_projectileDelta * zeus::CVector3f{1.f, 1.f, 0.f})), + zeus::CAxisAngle::sIdentity); + + SetMomentumWR({0.f, 0.f, -GetGravityConstant() * GetMass()}); + SetTranslation(GetTranslation()); + x5a8_ = 0; + } + else if (msg == EStateMsg::Update) + { + if (x5a8_ != 0) + return; + + if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::LieOnGround) + { + x5a8_ = 1; + return; + } + + x450_bodyController->GetCommandMgr().DeliverCmd(CBCKnockDownCmd({0.f, 1.f, 0.f}, pas::ESeverity::Zero)); + } +} + +void CMetaree::Dead(CStateManager& mgr, EStateMsg msg, float) +{ + if (msg != EStateMsg::Activate) + return; + + mgr.ApplyDamageToWorld(GetUniqueId(), *this, GetTranslation(), x5ac_damgeInfo, + CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Player}, {})); + DeathDelete(mgr); +} + +void CMetaree::Attack(CStateManager&, EStateMsg msg, float) +{ + if (msg == EStateMsg::Activate) + { + x5a8_ = 0; + zeus::CVector3f dir = (x584_lookPos - GetTranslation()).normalized(); + SetVelocityWR(x580_attackSpeed * dir); + CSfxManager::AddEmitter(x5c8_attackSfx, GetTranslation(), {}, true, false, 127, kInvalidAreaId); + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Combat); + x59c_velocity = x580_attackSpeed * dir; + } + else if (msg == EStateMsg::Update) + { + if (x450_bodyController->GetPercentageFrozen() == 0.f) + SetVelocityWR(x59c_velocity); + else + { + Stop(); + SetVelocityWR({}); + } + } +} + +void CMetaree::Halt(CStateManager& mgr, EStateMsg msg, float) +{ + if (msg != EStateMsg::Activate) + return; + + Stop(); + SetVelocityWR({}); + SetMomentumWR({}); + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk); + x584_lookPos = x574_offset + mgr.GetPlayer().GetTranslation(); + SetTransform(zeus::lookAt(GetTranslation(), x584_lookPos)); + +} + +void CMetaree::Active(CStateManager& mgr, EStateMsg msg, float) +{ + if (msg == EStateMsg::Activate) + { + x400_24_hitByPlayerProjectile = false; + x584_lookPos = GetTranslation() - zeus::CVector3f{0.f, 0.f, x570_dropHeight}; + x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::Zero, x584_lookPos)); + SetMomentumWR({0.f, 0.f, -GetGravityConstant() * GetMass()}); + } + else if (msg == EStateMsg::Update) + { + x450_bodyController->GetCommandMgr().SetTargetVector( + (mgr.GetPlayer().GetTranslation() - GetTranslation()).normalized()); + } + else if (msg == EStateMsg::Deactivate) + { + SetMomentumWR({}); + } +} + +void CMetaree::InActive(CStateManager&, EStateMsg msg, float) +{ + if (msg == EStateMsg::Activate) + { + if (!x5ca_26_deactivated) + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); + } + else if (msg == EStateMsg::Deactivate) + { + x5ca_26_deactivated = true; + } +} + +bool CMetaree::InRange(CStateManager& mgr, float arg) +{ + if (x5ca_25_started) + return true; + + return CPatterned::InRange(mgr, arg); +} + +bool CMetaree::ShouldAttack(CStateManager&, float) +{ + return GetTranslation().z < x584_lookPos.z; +} } diff --git a/Runtime/MP1/World/CMetaree.hpp b/Runtime/MP1/World/CMetaree.hpp index 09dbc209f..5ed39bbe4 100644 --- a/Runtime/MP1/World/CMetaree.hpp +++ b/Runtime/MP1/World/CMetaree.hpp @@ -2,32 +2,31 @@ #include "World/CPatterned.hpp" #include "World/CDamageInfo.hpp" +#include "DataSpec/DNAMP1/SFX/Metaree.h" namespace urde::MP1 { class CMetaree : public CPatterned { - float x568_; + float x568_delay; float x56c_; - float x570_; - zeus::CVector3f x574_; - float x580_; - zeus::CVector3f x584_; - float x590_ = 0.f; - float x594_ = 0.f; - float x598_ = 0.f; - zeus::CVector3f x59c_; + float x570_dropHeight; + zeus::CVector3f x574_offset; + float x580_attackSpeed; + zeus::CVector3f x584_lookPos; + zeus::CVector3f x590_projectileDelta; + zeus::CVector3f x59c_velocity; u32 x5a8_ = 0; CDamageInfo x5ac_damgeInfo; - u16 x5c8_ = 549; + u16 x5c8_attackSfx = SFXsfx0225; struct { struct { bool x5ca_24_ : 1; - bool x5ca_25_ : 1; - bool x5ca_26_ : 1; + bool x5ca_25_started : 1; + bool x5ca_26_deactivated : 1; }; u16 _dummy; }; @@ -41,11 +40,24 @@ public: void Accept(IVisitor& visitor); void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&); + void Think(float, CStateManager&); + void Touch(CActor&, CStateManager&); + void CollidedWith(TUniqueId&, const CCollisionInfoList&, CStateManager&); + void ThinkAboutMove(float) {}; bool Delay(CStateManager&, float) { - return x330_stateMachineState.GetTime() == x568_; + return x330_stateMachineState.GetTime() > x568_delay; } + void Explode(CStateManager&, EStateMsg, float); + void Flee(CStateManager&, EStateMsg, float); + void Dead(CStateManager&, EStateMsg, float); + void Attack(CStateManager&, EStateMsg, float); + void Halt(CStateManager&, EStateMsg, float); + void Active(CStateManager&, EStateMsg, float); + void InActive(CStateManager&, EStateMsg, float); + bool InRange(CStateManager&, float); + bool ShouldAttack(CStateManager&, float); }; } diff --git a/Runtime/Weapon/CGameProjectile.hpp b/Runtime/Weapon/CGameProjectile.hpp index 56848908d..0d4793501 100644 --- a/Runtime/Weapon/CGameProjectile.hpp +++ b/Runtime/Weapon/CGameProjectile.hpp @@ -87,6 +87,7 @@ public: zeus::CAABox GetProjectileBounds() const; std::experimental::optional GetTouchBounds() const; TUniqueId GetHomingTargetId() const { return x2c0_homingTargetId; } + zeus::CVector3f GetPreviousPos() const { return x298_lastOrigin; } }; } diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index 50e4171ba..0d8667d05 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -1817,8 +1817,7 @@ CEntity* ScriptLoader::LoadMetaree(CStateManager& mgr, CInputStream& in, int pro CAnimRes(pInfo.GetAnimationParameters().GetACSFile(), pInfo.GetAnimationParameters().GetCharacter(), scale, pInfo.GetAnimationParameters().GetInitialAnimation(), true)); return new MP1::CMetaree(mgr.AllocateUniqueId(), name, CPatterned::EFlavorType::Zero, info, xf, std::move(mData), - pInfo, - dInfo, f1, vec, f2, EBodyType::Invalid, f3, f4, aParms); + pInfo, dInfo, f1, vec, f2, EBodyType::Invalid, f3, f4, aParms); } CEntity* ScriptLoader::LoadDockAreaChange(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)