From 08b1dbcf4f374cb0939cbdcdb4892bb4c517508c Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Sat, 4 Apr 2020 06:55:08 -0700 Subject: [PATCH] Drone: Implement AcceptScriptMsg --- Runtime/MP1/World/CDrone.cpp | 211 ++++++++++++++++++++++++++++++++++- Runtime/MP1/World/CDrone.hpp | 62 +++++++++- 2 files changed, 267 insertions(+), 6 deletions(-) diff --git a/Runtime/MP1/World/CDrone.cpp b/Runtime/MP1/World/CDrone.cpp index 1dbbca48b..824dde63d 100644 --- a/Runtime/MP1/World/CDrone.cpp +++ b/Runtime/MP1/World/CDrone.cpp @@ -1,9 +1,14 @@ #include "Runtime/MP1/World/CDrone.hpp" #include "Runtime/Audio/CSfxManager.hpp" -#include "Runtime/World/CPatternedInfo.hpp" #include "Runtime/CSimplePool.hpp" +#include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/Weapon/CWeapon.hpp" +#include "Runtime/World/CGameLight.hpp" +#include "Runtime/World/CPatternedInfo.hpp" +#include "Runtime/World/CTeamAiMgr.hpp" +#include "Runtime/World/CWorld.hpp" #include "TCastTo.hpp" // Generated file, do not modify include path @@ -73,20 +78,199 @@ CDrone::CDrone(TUniqueId uid, std::string_view name, EFlavorType flavor, const C } void CDrone::Accept(IVisitor& visitor) { visitor.Visit(this); } +void CDrone::Think(float dt, CStateManager& mgr) { CPatterned::Think(dt, mgr); } + void CDrone::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) { CPatterned::AcceptScriptMsg(msg, sender, mgr); switch (msg) { + case EScriptObjectMessage::Activate: { + SetLightEnabled(mgr, true); + AddToTeam(mgr); + break; + } + case EScriptObjectMessage::Deactivate: + case EScriptObjectMessage::Deleted: { + for (TUniqueId& unkId : x7d4_) { + if (unkId != kInvalidUniqueId) { + mgr.FreeScriptObject(unkId); + unkId = kInvalidUniqueId; + } + } + RemoveFromTeam(mgr); + mgr.GetPlayerState()->GetStaticInterference().RemoveSource(GetUniqueId()); + if (x578_lightId != kInvalidUniqueId) { + mgr.FreeScriptObject(x578_lightId); + } + if (x57a_ != kInvalidUniqueId) { + mgr.FreeScriptObject(x57a_); + } + + if (x7d0_) { + CSfxManager::RemoveEmitter(x7d0_); + x7d0_.reset(); + } + break; + } + case EScriptObjectMessage::Alert: + x834_29_ = true; + break; + case EScriptObjectMessage::OnFloor: + if (!x835_26_ && x834_24_) { + x835_26_ = true; + MassiveFrozenDeath(mgr); + } + break; case EScriptObjectMessage::Registered: x450_bodyController->Activate(mgr); x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk); x450_bodyController->BodyStateInfo().SetMaximumPitch(0.f); + x5cc_ = 0.f; + x460_knockBackController.SetEnableFreeze(false); + AddMaterial(EMaterialTypes::AIJoint, mgr); + x578_lightId = mgr.AllocateUniqueId(); + mgr.AddObject(new CGameLight(x578_lightId, GetAreaIdAlways(), GetActive(), "LaserLight"sv, {}, GetUniqueId(), + CLight::BuildPoint(zeus::skZero3f, zeus::skRed), 0, 0, 0.f)); break; + case EScriptObjectMessage::InitializedInArea: { + x6b0_pathFind.SetArea(mgr.GetWorld()->GetAreaAlways(GetAreaIdAlways())->GetPostConstructed()->x10bc_pathArea); + if (x688_teamMgr == kInvalidUniqueId) { + x688_teamMgr = CTeamAiMgr::GetTeamAiMgr(*this, mgr); + if (GetActive()) { + AddToTeam(mgr); + } + } + + x604_ = HealthInfo(mgr)->GetHP(); + x55c_moveScale = 1.f / GetModelData()->GetScale(); + if (x835_25_) + SetSoundEventPitchBend(0); + break; + } default: break; } } +void CDrone::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { + CPatterned::PreRender(mgr, frustum); + if (x3fc_flavor == EFlavorType::One) { + if (HasModelData() && GetModelData()->HasAnimData()) { + if (GetModelAlphau8(mgr) == 0) + GetModelData()->GetAnimationData()->BuildPose(); + } + } +} + +void CDrone::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { + CPatterned::AddToRenderer(frustum, mgr); +} + +void CDrone::Render(const CStateManager& mgr) const { + bool isOne = x3fc_flavor == EFlavorType::One; + if (!isOne || GetModelAlphau8(mgr) != 0) { + if (isOne && mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) { + CGraphics::SetFog(ERglFogMode::PerspLin, 0.f, 75.f, zeus::skBlack); + GetModelData()->GetAnimationData()->GetParticleDB().RenderSystemsToBeDrawnFirst(); + mgr.SetupFogForArea3XRange(GetAreaIdAlways()); + } + CPatterned::Render(mgr); + if (isOne && mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) { + CGraphics::SetFog(ERglFogMode::PerspLin, 0.f, 75.f, zeus::skBlack); + GetModelData()->GetAnimationData()->GetParticleDB().RenderSystemsToBeDrawnLast(); + mgr.SetupFogForArea3XRange(GetAreaIdAlways()); + } + + if (isOne && zeus::close_enough(x5dc_, 0)) { + x82c_->Render(mgr, GetLctrTransform("Shield_LCTR"sv), GetActorLights(), + CModelFlags{8, 0, 3, zeus::CColor::lerp({1.f, 0.f, 0.f, 1.f}, zeus::skWhite, x5e8_)}); + } + } +} +bool CDrone::CanRenderUnsorted(const CStateManager& mgr) const { + if (zeus::close_enough(x5dc_, 0.f)) + return false; + return CPatterned::CanRenderUnsorted(mgr); +} + +const CDamageVulnerability* CDrone::GetDamageVulnerability(const zeus::CVector3f&, const zeus::CVector3f& dir, + const CDamageInfo&) const { + if (x3fc_flavor == EFlavorType::One && HitShield(-dir)) { + return &CDamageVulnerability::ImmuneVulnerabilty(); + } + return CAi::GetDamageVulnerability(); +} +void CDrone::Touch(CActor& act, CStateManager& mgr) { + CPatterned::Touch(act, mgr); + if (TCastToPtr weapon = act) { + if (IsAlive()) { + x834_24_ = weapon->GetType() == EWeaponType::Wave; + if (HitShield(weapon->GetTranslation() - GetTranslation())) { + x5e8_ = 1.f; + } + } + } +} + +EWeaponCollisionResponseTypes CDrone::GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f& dir, + const CWeaponMode&, EProjectileAttrib) const { + if (x3fc_flavor == EFlavorType::One && HitShield(-dir)) { + return EWeaponCollisionResponseTypes::Unknown86; + } + return EWeaponCollisionResponseTypes::Unknown36; +} + +void CDrone::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) { + CPatterned::DoUserAnimEvent(mgr, node, type, dt); +} +const CCollisionPrimitive* CDrone::GetCollisionPrimitive() const { return CPhysicsActor::GetCollisionPrimitive(); } +void CDrone::Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state) { + CPatterned::Death(mgr, direction, state); +} +void CDrone::KnockBack(const zeus::CVector3f& backVec, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, + bool inDeferred, float magnitude) { + CPatterned::KnockBack(backVec, mgr, info, type, inDeferred, magnitude); +} +void CDrone::Patrol(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::Patrol(mgr, msg, dt); } +void CDrone::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::PathFind(mgr, msg, dt); } +void CDrone::TargetPlayer(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::TargetPlayer(mgr, msg, dt); } +void CDrone::TargetCover(CStateManager& mgr, EStateMsg msg, float dt) { CAi::TargetCover(mgr, msg, dt); } +void CDrone::Deactivate(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Deactivate(mgr, msg, dt); } +void CDrone::Attack(CStateManager& mgr, EStateMsg msg, float dt) {} +void CDrone::Active(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Active(mgr, msg, dt); } +void CDrone::Flee(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Flee(mgr, msg, dt); } +void CDrone::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::ProjectileAttack(mgr, msg, dt); } +void CDrone::TelegraphAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::TelegraphAttack(mgr, msg, dt); } +void CDrone::Dodge(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Dodge(mgr, msg, dt); } +void CDrone::Retreat(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Retreat(mgr, msg, dt); } +void CDrone::Cover(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Cover(mgr, msg, dt); } +void CDrone::SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::SpecialAttack(mgr, msg, dt); } +void CDrone::PathFindEx(CStateManager& mgr, EStateMsg msg, float dt) { CAi::PathFindEx(mgr, msg, dt); } +bool CDrone::Leash(CStateManager& mgr, float arg) { return CPatterned::Leash(mgr, arg); } +bool CDrone::InRange(CStateManager& mgr, float arg) { return CPatterned::InRange(mgr, arg); } +bool CDrone::SpotPlayer(CStateManager& mgr, float arg) { return CPatterned::SpotPlayer(mgr, arg); } +bool CDrone::AnimOver(CStateManager& mgr, float arg) { return CPatterned::AnimOver(mgr, arg); } +bool CDrone::ShouldAttack(CStateManager& mgr, float arg) { return CAi::ShouldAttack(mgr, arg); } +bool CDrone::HearShot(CStateManager& mgr, float arg) { return CAi::HearShot(mgr, arg); } +bool CDrone::CoverCheck(CStateManager& mgr, float arg) { return CAi::CoverCheck(mgr, arg); } +bool CDrone::LineOfSight(CStateManager& mgr, float arg) { return CAi::LineOfSight(mgr, arg); } +bool CDrone::ShouldMove(CStateManager& mgr, float arg) { return CAi::ShouldMove(mgr, arg); } +bool CDrone::CodeTrigger(CStateManager& mgr, float arg) { return CPatterned::CodeTrigger(mgr, arg); } +void CDrone::Burn(float duration, float damage) { CPatterned::Burn(duration, damage); } +CPathFindSearch* CDrone::GetSearchPath() { return CPatterned::GetSearchPath(); } + +void CDrone::BuildNearList(EMaterialTypes includeMat, EMaterialTypes excludeMat, + rstl::reserved_vector& listOut, float radius, CStateManager& mgr) { + const zeus::CVector3f pos = GetTranslation(); + mgr.BuildNearList(listOut, zeus::CAABox(pos - radius, pos + radius), + CMaterialFilter::MakeIncludeExclude({includeMat}, {excludeMat}), nullptr); +} +void CDrone::SetLightEnabled(CStateManager& mgr, bool activate) { + mgr.SendScriptMsgAlways(x578_lightId, GetUniqueId(), + activate ? EScriptObjectMessage::Activate : EScriptObjectMessage::Deactivate); +} +void CDrone::UpdateVisorFlare(CStateManager& mgr) {} + void CDrone::UpdateTouchBounds(float radius) { const zeus::CTransform xf = GetLctrTransform("Skeleton_Root"sv); const zeus::CVector3f diff = xf.origin - GetTranslation(); @@ -94,4 +278,29 @@ void CDrone::UpdateTouchBounds(float radius) { x6b0_pathFind.SetRadius(0.25f + radius); } +bool CDrone::HitShield(const zeus::CVector3f& dir) const { + if (x3fc_flavor == EFlavorType::One && zeus::close_enough(x5dc_, 0.f)) { + return GetLctrTransform("Shield_LCTR"sv).basis[1].dot(dir.normalized()) > 0.85f; + } + + return false; +} +void CDrone::AddToTeam(CStateManager& mgr) const { + if (x688_teamMgr == kInvalidUniqueId) { + return; + } + + if (TCastToPtr teamMgr = mgr.ObjectById(x688_teamMgr)) { + teamMgr->AssignTeamAiRole(*this, CTeamAiRole::ETeamAiRole::Ranged, CTeamAiRole::ETeamAiRole::Melee, + CTeamAiRole::ETeamAiRole::Invalid); + } +} +void CDrone::RemoveFromTeam(CStateManager& mgr) const { + if (TCastToPtr teamMgr = mgr.ObjectById(x688_teamMgr)) { + if (teamMgr->IsPartOfTeam(GetUniqueId())) { + teamMgr->RemoveTeamAiRole(GetUniqueId()); + } + } +} + } // namespace urde::MP1 diff --git a/Runtime/MP1/World/CDrone.hpp b/Runtime/MP1/World/CDrone.hpp index d27d5866b..a8e20d6cc 100644 --- a/Runtime/MP1/World/CDrone.hpp +++ b/Runtime/MP1/World/CDrone.hpp @@ -10,7 +10,7 @@ class CDrone : public CPatterned { CAssetId x568_; TLockedToken x56c_; CCollisionResponseData* x574_; - TUniqueId x578_ = kInvalidUniqueId; + TUniqueId x578_lightId = kInvalidUniqueId; TUniqueId x57a_ = kInvalidUniqueId; std::vector x57c_flares; u32 x58c_ = 2; @@ -60,7 +60,7 @@ class CDrone : public CPatterned { float x66c_ = 0.f; zeus::CVector3f x670_; zeus::CVector3f x67c_; - TUniqueId x688_ = kInvalidUniqueId; + TUniqueId x688_teamMgr = kInvalidUniqueId; CCollidableSphere x690_; CPathFindSearch x6b0_pathFind; zeus::CAxisAngle x794_; @@ -72,7 +72,7 @@ class CDrone : public CPatterned { float x7bc_ = 0.f; s32 x7c8_ = 0; s16 x7cc_; - s32 x7d0_ = 0; + CSfxHandle x7d0_; rstl::reserved_vector x7d4_; rstl::reserved_vector x7e0_; rstl::reserved_vector x7fc_; @@ -93,6 +93,10 @@ class CDrone : public CPatterned { bool x835_25_ : 1; bool x835_26_ : 1; void UpdateTouchBounds(float radius); + bool HitShield(const zeus::CVector3f& dir) const; + void AddToTeam(CStateManager& mgr) const; + void RemoveFromTeam(CStateManager& mgr) const; + public: DEFINE_PATTERNED(Drone); CDrone(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info, const zeus::CTransform& xf, @@ -103,7 +107,55 @@ public: float f13, float f14, float f15, float f16, float f17, float f18, float f19, float f20, CAssetId crscId, float f21, float f22, float f23, float f24, s32 w3, bool b1); - void Accept(IVisitor& visitor); - void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr); + void Accept(IVisitor& visitor) override; + void Think(float dt, CStateManager& mgr) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) override; + void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; + void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; + void Render(const CStateManager &mgr) const override; + bool CanRenderUnsorted(const CStateManager& mgr) const override; + const CDamageVulnerability* GetDamageVulnerability() const override { return CAi::GetDamageVulnerability(); } + const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f&, const zeus::CVector3f&, + const CDamageInfo&) const override; + void Touch(CActor& act, CStateManager& mgr) override; + EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, + const CWeaponMode&, EProjectileAttrib) const override; + void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) override; + const CCollisionPrimitive* GetCollisionPrimitive() const override; + void Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state) override; + void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType type, bool inDeferred, + float magnitude) override; + void Patrol(CStateManager&, EStateMsg msg, float dt) override; + void PathFind(CStateManager&, EStateMsg msg, float dt) override; + void TargetPlayer(CStateManager&, EStateMsg msg, float dt) override; + void TargetCover(CStateManager&, EStateMsg msg, float dt) override; + void Deactivate(CStateManager&, EStateMsg msg, float dt) override; + void Attack(CStateManager&, EStateMsg msg, float dt) override; + void Active(CStateManager&, EStateMsg msg, float dt) override; + void Flee(CStateManager&, EStateMsg msg, float dt) override; + void ProjectileAttack(CStateManager&, EStateMsg msg, float dt) override; + void TelegraphAttack(CStateManager&, EStateMsg msg, float dt) override; + void Dodge(CStateManager&, EStateMsg msg, float dt) override; + void Retreat(CStateManager&, EStateMsg msg, float dt) override; + void Cover(CStateManager&, EStateMsg msg, float dt) override; + void SpecialAttack(CStateManager&, EStateMsg msg, float dt) override; + void PathFindEx(CStateManager&, EStateMsg msg, float dt) override; + bool Leash(CStateManager&, float arg) override; + bool InRange(CStateManager&, float arg) override; + bool SpotPlayer(CStateManager&, float arg) override; + bool AnimOver(CStateManager&, float arg) override; + bool ShouldAttack(CStateManager&, float arg) override; + bool HearShot(CStateManager&, float arg) override; + bool CoverCheck(CStateManager&, float arg) override; + bool LineOfSight(CStateManager&, float arg) override; + bool ShouldMove(CStateManager&, float arg) override; + bool CodeTrigger(CStateManager&, float arg) override; + void Burn(float duration, float damage) override; + CPathFindSearch* GetSearchPath() override; + virtual void BuildNearList(EMaterialTypes includeMat, EMaterialTypes excludeMat, + rstl::reserved_vector& listOut, float radius, CStateManager& mgr); + virtual void SetLightEnabled(CStateManager& mgr, bool activate); + virtual void UpdateVisorFlare(CStateManager& mgr); + virtual int sub_8015f150() { return 3; } }; } // namespace urde::MP1