From fe4d9f8b1ad41fa4e0033131b8ce44554c283d96 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Wed, 4 Mar 2020 05:32:41 -0800 Subject: [PATCH 1/2] Initial CChozoGhost stubs --- Runtime/MP1/World/CChozoGhost.cpp | 164 ++++++++++++++++++++++++------ Runtime/MP1/World/CChozoGhost.hpp | 105 ++++++++++++------- 2 files changed, 205 insertions(+), 64 deletions(-) diff --git a/Runtime/MP1/World/CChozoGhost.cpp b/Runtime/MP1/World/CChozoGhost.cpp index 6bc381343..213fa6a16 100644 --- a/Runtime/MP1/World/CChozoGhost.cpp +++ b/Runtime/MP1/World/CChozoGhost.cpp @@ -1,30 +1,33 @@ #include "Runtime/MP1/World/CChozoGhost.hpp" +#include "Runtime/GameGlobalObjects.hpp" #include "Runtime/CStateManager.hpp" +#include "Runtime/CSimplePool.hpp" #include "Runtime/CRandom16.hpp" +#include "Runtime/Character/CPASAnimParmData.hpp" #include "TCastTo.hpp" // Generated file, do not modify include path namespace urde::MP1 { CChozoGhost::CBehaveChance::CBehaveChance(CInputStream& in) : x0_propertyCount(in.readUint32Big()) -, x4_(in.readFloatBig()) +, x4_lurk(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; +, xc_attack(in.readFloatBig()) +, x10_move(in.readFloatBig()) +, x14_lurkTime(in.readFloatBig()) +, x18_chargeAttack(x0_propertyCount <= 5 ? 0.5f : in.readFloatBig() * .01f) +, x1c_numBolts(x0_propertyCount <= 6 ? 2 : in.readUint32Big()) { + float f2 = 1.f / (x10_move + xc_attack + x4_lurk + x8_); + x4_lurk *= f2; x8_ *= f2; - xc_ *= f2; - x10_ *= f2; + xc_attack *= f2; + x10_move *= f2; } u32 CChozoGhost::CBehaveChance::GetBehave(EBehaveType type, CStateManager& mgr) const { - float dVar5 = x4_; + float dVar5 = x4_lurk; float dVar4 = x8_; - float dVar3 = xc_; + float dVar3 = xc_attack; if (type == EBehaveType::Zero) { float dVar2 = dVar5 / 3.f; dVar5 = 0.f; @@ -41,7 +44,7 @@ u32 CChozoGhost::CBehaveChance::GetBehave(EBehaveType type, CStateManager& mgr) dVar5 += dVar2; dVar4 += dVar2; } else if (type == EBehaveType::Three) { - float dVar2 = x10_ / 3.f; + float dVar2 = x10_move / 3.f; dVar5 += dVar2; dVar4 += dVar2; dVar3 += dVar2; @@ -58,35 +61,37 @@ u32 CChozoGhost::CBehaveChance::GetBehave(EBehaveType type, CStateManager& mgr) } 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) + CModelData&& mData, const CActorParameters& actParms, const CPatternedInfo& pInfo, + float hearingRadius, float fadeOutDelay, float attackDelay, float freezeTime, CAssetId wpsc1, + const CDamageInfo& dInfo1, CAssetId wpsc2, const CDamageInfo& dInfo2, + const CBehaveChance& chance1, const CBehaveChance& chance2, const CBehaveChance& chance3, + u16 soundImpact, float f5, u16 sId2, u16 sId3, u32 w1, float f6, u32 w2, float hurlRecoverTime, + CAssetId projectileVisorEffect, s16 soundProjectileVisor, float f8, float f9, u32 nearChance, + u32 midChance) : CPatterned(ECharacter::ChozoGhost, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo, EMovementType::Flyer, EColliderType::Zero, EBodyType::BiPedal, actParms, EKnockBackVariant::Medium) -, x568_(f1) -, x56c_(f2) -, x570_(f3) -, x574_(f4) +, x568_hearingRadius(hearingRadius) +, x56c_fadeOutDelay(fadeOutDelay) +, x570_attackDelay(attackDelay) +, x574_freezeTime(freezeTime) , x578_(wpsc1, dInfo1) , x5a0_(wpsc2, dInfo2) , x5c8_(chance1) , x5e8_(chance2) , x608_(chance3) -, x628_(sId1) +, x628_soundImpact(soundImpact) , x62c_(f5) , x630_(sId2) , x632_(sId3) , x634_(f6) -, x638_(f7) +, x638_hurlRecoverTime(hurlRecoverTime) , x63c_(w2) -, x650_(sId4) +, x650_sound_ProjectileVisor(soundProjectileVisor) , x654_(f8) , x658_(f9) -, x65c_(w3) -, x660_(w4) -, x664_24_(w1) +, x65c_nearChance(nearChance) +, x660_midChance(midChance) +, x664_24_onGround(w1) , x664_25_(w1) , x664_26_(false) , x664_27_(false) @@ -100,6 +105,107 @@ CChozoGhost::CChozoGhost(TUniqueId uid, std::string_view name, const CEntityInfo , x665_27_(false) , x665_28_(false) , x665_29_(false) +, x680_(x664_24_onGround ? 2 : 4) , x68c_boneTracking(*GetModelData()->GetAnimationData(), "Head_1"sv, zeus::degToRad(80.f), zeus::degToRad(180.f), - EBoneTrackingFlags::None) {} + EBoneTrackingFlags::None) { + x578_.Token().Lock(); + x5a0_.Token().Lock(); + x668_ = GetModelData()->GetScale().z() * + GetAnimationDistance(CPASAnimParmData(13, CPASAnimParm::FromEnum(3), CPASAnimParm::FromEnum(0))); + x66c_ = GetModelData()->GetScale().z() * + GetAnimationDistance(CPASAnimParmData(15, CPASAnimParm::FromEnum(1), CPASAnimParm::FromReal32(90.f))); + x670_ = GetModelData()->GetScale().z() * + GetAnimationDistance(CPASAnimParmData(7, CPASAnimParm::FromEnum(1), CPASAnimParm::FromEnum(2))); + + if (projectileVisorEffect.IsValid()) + x640_ = g_SimplePool->GetObj({SBIG('PART'), projectileVisorEffect}); + x460_knockBackController.SetEnableBurn(false); + x460_knockBackController.SetEnableLaggedBurnDeath(false); + x460_knockBackController.SetEnableShock(false); + x460_knockBackController.SetEnableFreeze(false); + CreateShadow(false); + MakeThermalColdAndHot(); +} +void CChozoGhost::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { + CPatterned::AcceptScriptMsg(msg, uid, mgr); +} + +void CChozoGhost::Think(float dt, CStateManager& mgr) { CPatterned::Think(dt, mgr); } + +void CChozoGhost::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { CPatterned::PreRender(mgr, frustum); } + +void CChozoGhost::Render(const CStateManager& mgr) const { CPatterned::Render(mgr); } + +void CChozoGhost::Touch(CActor& act, CStateManager& mgr) { CPatterned::Touch(act, mgr); } + +EWeaponCollisionResponseTypes CChozoGhost::GetCollisionResponseType(const zeus::CVector3f& pos, + const zeus::CVector3f& dir, const CWeaponMode& mode, + EProjectileAttrib attrib) const { + return CAi::GetCollisionResponseType(pos, dir, mode, attrib); +} + +void CChozoGhost::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) { + CPatterned::DoUserAnimEvent(mgr, node, type, dt); +} + +void CChozoGhost::KnockBack(const zeus::CVector3f& dir, CStateManager& mgr, const CDamageInfo& info, + EKnockBackType type, bool inDeferred, float magnitude) { + CPatterned::KnockBack(dir, mgr, info, type, inDeferred, magnitude); +} + +bool CChozoGhost::CanBeShot(const CStateManager& mgr, int w1) { return CAi::CanBeShot(mgr, w1); } + +void CChozoGhost::Dead(CStateManager& mgr, EStateMsg msg, float arg) { CPatterned::Dead(mgr, msg, arg); } + +void CChozoGhost::SelectTarget(CStateManager& mgr, EStateMsg msg, float arg) { CAi::SelectTarget(mgr, msg, arg); } + +void CChozoGhost::Run(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Run(mgr, msg, arg); } + +void CChozoGhost::Generate(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Generate(mgr, msg, arg); } + +void CChozoGhost::Deactivate(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Deactivate(mgr, msg, arg); } + +void CChozoGhost::Attack(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Attack(mgr, msg, arg); } + +void CChozoGhost::Shuffle(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Shuffle(mgr, msg, arg); } + +void CChozoGhost::InActive(CStateManager& mgr, EStateMsg msg, float arg) { CAi::InActive(mgr, msg, arg); } + +void CChozoGhost::Taunt(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Taunt(mgr, msg, arg); } + +void CChozoGhost::Hurled(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Hurled(mgr, msg, arg); } + +void CChozoGhost::WallDetach(CStateManager& mgr, EStateMsg msg, float arg) { CAi::WallDetach(mgr, msg, arg); } + +void CChozoGhost::Growth(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Growth(mgr, msg, arg); } + +void CChozoGhost::Land(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Land(mgr, msg, arg); } + +bool CChozoGhost::Leash(CStateManager& mgr, float arg) { return CPatterned::Leash(mgr, arg); } + +bool CChozoGhost::InRange(CStateManager& mgr, float arg) { return CPatterned::InRange(mgr, arg); } + +bool CChozoGhost::InPosition(CStateManager& mgr, float arg) { return CPatterned::InPosition(mgr, arg); } + +bool CChozoGhost::AggressionCheck(CStateManager& mgr, float arg) { return CAi::AggressionCheck(mgr, arg); } + +bool CChozoGhost::ShouldTaunt(CStateManager& mgr, float arg) { return CAi::ShouldTaunt(mgr, arg); } + +bool CChozoGhost::ShouldFlinch(CStateManager& mgr, float arg) { return CAi::ShouldFlinch(mgr, arg); } + +bool CChozoGhost::ShouldMove(CStateManager& mgr, float arg) { return CAi::ShouldMove(mgr, arg); } + +bool CChozoGhost::AIStage(CStateManager& mgr, float arg) { return CAi::AIStage(mgr, arg); } + +u8 CChozoGhost::GetModelAlphau8(const CStateManager& mgr) const { + if (mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::EPlayerVisor::XRay || !IsAlive()) + return u8(x42c_color.a() * 255); + + return 255; +} + +bool CChozoGhost::IsOnGround() const { return x664_24_onGround; } + +CProjectileInfo* CChozoGhost::GetProjectileInfo() { return CPatterned::GetProjectileInfo(); } + } // namespace urde::MP1 \ No newline at end of file diff --git a/Runtime/MP1/World/CChozoGhost.hpp b/Runtime/MP1/World/CChozoGhost.hpp index c5b782647..5785d7569 100644 --- a/Runtime/MP1/World/CChozoGhost.hpp +++ b/Runtime/MP1/World/CChozoGhost.hpp @@ -21,13 +21,13 @@ class CChozoGhost : public CPatterned { public: class CBehaveChance { u32 x0_propertyCount; - float x4_; + float x4_lurk; float x8_; - float xc_; - float x10_; - float x14_; - float x18_; - u32 x1c_; + float xc_attack; + float x10_move; + float x14_lurkTime; + float x18_chargeAttack; + u32 x1c_numBolts; public: CBehaveChance(CInputStream&); @@ -36,47 +36,42 @@ public: }; private: - float x568_; - float x56c_; - float x570_; - float x574_; + float x568_hearingRadius; + float x56c_fadeOutDelay; + float x570_attackDelay; + float x574_freezeTime; CProjectileInfo x578_; CProjectileInfo x5a0_; CBehaveChance x5c8_; CBehaveChance x5e8_; CBehaveChance x608_; - s16 x628_; + s16 x628_soundImpact; float x62c_; s16 x630_; s16 x632_; float x634_; - float x638_; + float x638_hurlRecoverTime; u32 x63c_; TLockedToken x640_; - s16 x650_; + s16 x650_sound_ProjectileVisor; float x654_; float x658_; - u32 x65c_; - u32 x660_; - union { - struct { - bool x664_24_ : 1; - bool x664_25_ : 1; - bool x664_26_ : 1; - bool x664_27_ : 1; - bool x664_28_ : 1; - bool x664_29_ : 1; - bool x664_30_ : 1; - bool x664_31_ : 1; - bool x665_24_ : 1; - bool x665_25_ : 1; - bool x665_26_ : 1; - bool x665_27_ : 1; - bool x665_28_ : 1; - bool x665_29_ : 1; - }; - u32 _dummy = 0; - }; + u32 x65c_nearChance; + u32 x660_midChance; + bool x664_24_onGround : 1; + bool x664_25_ : 1; + bool x664_26_ : 1; + bool x664_27_ : 1; + bool x664_28_ : 1; + bool x664_29_ : 1; + bool x664_30_ : 1; + bool x664_31_ : 1; + bool x665_24_ : 1; + bool x665_25_ : 1; + bool x665_26_ : 1; + bool x665_27_ : 1; + bool x665_28_ : 1; + bool x665_29_ : 1; float x668_ = 0.f; float x66c_ = 0.f; float x670_ = 0.f; @@ -92,6 +87,7 @@ private: zeus::CVector3f x6cc_; u32 x6d8_ = 1; u32 x6dc_; + CTeamAiMgr public: DEFINE_PATTERNED(ChozoGhost) @@ -101,6 +97,45 @@ public: const CBehaveChance&, u16, float, u16, u16, u32, float, u32, float, CAssetId, s16, float, float, u32, u32); - float GetGravityConstant() const { return 60.f; } + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; + void Think(float dt, CStateManager&) override; + void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; + void Render(const CStateManager& mgr) const override; + void Touch(CActor& act, CStateManager& mgr) override; + EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f& pos, const zeus::CVector3f& dir, + const CWeaponMode& mode, EProjectileAttrib attrib) const override; + void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) override; + void KnockBack(const zeus::CVector3f& dir, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, + bool inDeferred, float magnitude) override; + bool CanBeShot(const CStateManager& mgr, int w1) override; + zeus::CVector3f GetOrigin(const CStateManager& mgr, const CTeamAiRole& role, + const zeus::CVector3f& aimPos) const override { + return x34_transform.origin; + } + void Dead(CStateManager& mgr, EStateMsg msg, float arg) override; + void SelectTarget(CStateManager& mgr, EStateMsg msg, float arg) override; + void Run(CStateManager& mgr, EStateMsg msg, float arg) override; + void Generate(CStateManager& mgr, EStateMsg msg, float arg) override; + void Deactivate(CStateManager& mgr, EStateMsg msg, float arg) override; + void Attack(CStateManager& mgr, EStateMsg msg, float arg) override; + void Shuffle(CStateManager& mgr, EStateMsg msg, float arg) override; + void InActive(CStateManager& mgr, EStateMsg msg, float arg) override; + void Taunt(CStateManager& mgr, EStateMsg msg, float arg) override; + void Hurled(CStateManager& mgr, EStateMsg msg, float arg) override; + void WallDetach(CStateManager& mgr, EStateMsg msg, float arg) override; + void Growth(CStateManager& mgr, EStateMsg msg, float arg) override; + void Land(CStateManager& mgr, EStateMsg msg, float arg) override; + bool Leash(CStateManager& mgr, float arg) override; + bool InRange(CStateManager& mgr, float arg) override; + bool InPosition(CStateManager& mgr, float arg) override; + bool AggressionCheck(CStateManager& mgr, float arg) override; + bool ShouldTaunt(CStateManager& mgr, float arg) override; + bool ShouldFlinch(CStateManager& mgr, float arg) override; + bool ShouldMove(CStateManager& mgr, float arg) override; + bool AIStage(CStateManager& mgr, float arg) override; + u8 GetModelAlphau8(const CStateManager&) const override; + bool IsOnGround() const override; + float GetGravityConstant() const override { return 60.f; } + CProjectileInfo* GetProjectileInfo() override; }; } // namespace urde::MP1 \ No newline at end of file From 174e6d53400d7996901dfe7af051f2f9a86e6942 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Wed, 4 Mar 2020 17:32:49 -0800 Subject: [PATCH 2/2] More ChozoGhost imps --- Runtime/CStateManager.cpp | 19 ++- Runtime/CStateManager.hpp | 2 + Runtime/MP1/World/CChozoGhost.cpp | 263 +++++++++++++++++++++++++++--- Runtime/MP1/World/CChozoGhost.hpp | 27 +-- Runtime/World/ScriptLoader.cpp | 2 +- 5 files changed, 276 insertions(+), 37 deletions(-) diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index 7b4d6ac25..d64d0929e 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -970,6 +970,14 @@ void CStateManager::DrawWorldCubeFaces() const { } } +void CStateManager::SetupFogForArea3XRange(TAreaId area) const { + if (area == kInvalidAreaId) + area = x8cc_nextAreaId; + const CGameArea* areaObj = x850_world->GetAreaAlways(area); + if (areaObj->IsPostConstructed()) + SetupFogForArea3XRange(*areaObj); +} + void CStateManager::SetupFogForArea(TAreaId area) const { if (area == kInvalidAreaId) area = x8cc_nextAreaId; @@ -986,6 +994,15 @@ void CStateManager::SetupFogForAreaNonCurrent(TAreaId area) const { SetupFogForAreaNonCurrent(*areaObj); } +void CStateManager::SetupFogForArea3XRange(const CGameArea& area) const { + if (x8b8_playerState->GetActiveVisor(*this) == CPlayerState::EPlayerVisor::XRay) { + float fogDist = area.GetXRayFogDistance(); + float farz = (g_tweakGui->GetXRayFogNearZ() * (1.f - fogDist) + g_tweakGui->GetXRayFogFarZ() * fogDist) * 3.f; + g_Renderer->SetWorldFog(ERglFogMode(g_tweakGui->GetXRayFogMode()), g_tweakGui->GetXRayFogNearZ(), farz, + g_tweakGui->GetXRayFogColor()); + } +} + void CStateManager::SetupFogForArea(const CGameArea& area) const { if (SetupFogForDraw()) return; @@ -1180,7 +1197,7 @@ void CStateManager::SendScriptMsgAlways(TUniqueId dest, TUniqueId src, EScriptOb } void CStateManager::SendScriptMsg(TUniqueId src, TEditorId dest, EScriptObjectMessage msg, EScriptObjectState state) { - //CEntity* ent = GetObjectById(src); + // CEntity* ent = GetObjectById(src); auto search = GetIdListForScript(dest); if (search.first != x890_scriptIdMap.cend()) { for (auto it = search.first; it != search.second; ++it) { diff --git a/Runtime/CStateManager.hpp b/Runtime/CStateManager.hpp index dba68ec77..c229bc52f 100644 --- a/Runtime/CStateManager.hpp +++ b/Runtime/CStateManager.hpp @@ -261,8 +261,10 @@ public: void DrawWorld() const; void DrawActorCubeFaces(CActor& actor, int& cubeInst) const; void DrawWorldCubeFaces() const; + void SetupFogForArea3XRange(TAreaId area) const; void SetupFogForArea(TAreaId area) const; void SetupFogForAreaNonCurrent(TAreaId area) const; + void SetupFogForArea3XRange(const CGameArea& area) const; void SetupFogForArea(const CGameArea& area) const; void SetupFogForAreaNonCurrent(const CGameArea& area) const; bool SetupFogForDraw() const; diff --git a/Runtime/MP1/World/CChozoGhost.cpp b/Runtime/MP1/World/CChozoGhost.cpp index 213fa6a16..ad976b81a 100644 --- a/Runtime/MP1/World/CChozoGhost.cpp +++ b/Runtime/MP1/World/CChozoGhost.cpp @@ -5,6 +5,8 @@ #include "Runtime/CSimplePool.hpp" #include "Runtime/CRandom16.hpp" #include "Runtime/Character/CPASAnimParmData.hpp" +#include "Runtime/World/CPlayer.hpp" +#include "Runtime/World/CTeamAiMgr.hpp" #include "TCastTo.hpp" // Generated file, do not modify include path namespace urde::MP1 { @@ -92,7 +94,7 @@ CChozoGhost::CChozoGhost(TUniqueId uid, std::string_view name, const CEntityInfo , x65c_nearChance(nearChance) , x660_midChance(midChance) , x664_24_onGround(w1) -, x664_25_(w1) +, x664_25_flinch(w1) , x664_26_(false) , x664_27_(false) , x664_28_(false) @@ -102,10 +104,10 @@ CChozoGhost::CChozoGhost(TUniqueId uid, std::string_view name, const CEntityInfo , x665_24_(true) , x665_25_(false) , x665_26_(false) -, x665_27_(false) -, x665_28_(false) -, x665_29_(false) -, x680_(x664_24_onGround ? 2 : 4) +, x665_27_playerInLeashRange(false) +, x665_28_inRange(false) +, x665_29_aggressive(false) +, x680_stateProg(x664_24_onGround ? 2 : 4) , x68c_boneTracking(*GetModelData()->GetAnimationData(), "Head_1"sv, zeus::degToRad(80.f), zeus::degToRad(180.f), EBoneTrackingFlags::None) { x578_.Token().Lock(); @@ -128,13 +130,70 @@ CChozoGhost::CChozoGhost(TUniqueId uid, std::string_view name, const CEntityInfo } void CChozoGhost::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { CPatterned::AcceptScriptMsg(msg, uid, mgr); + + switch (msg) { + case EScriptObjectMessage::Activate: + AddToTeam(mgr); + break; + case EScriptObjectMessage::Deactivate: + case EScriptObjectMessage::Deleted: + RemoveFromTeam(mgr); + break; + case EScriptObjectMessage::Action: + if (x664_26_) + break; + x664_26_ = true; + x400_24_hitByPlayerProjectile = true; + break; + case EScriptObjectMessage::Falling: + case EScriptObjectMessage::Jumped: { + if (!x328_25_verticalMovement) + x150_momentum = {0.f, 0.f, -(GetGravityConstant() * GetMass())}; + break; + } + case EScriptObjectMessage::InitializedInArea: + if (GetActive()) + AddToTeam(mgr); + break; + default: + break; + } } -void CChozoGhost::Think(float dt, CStateManager& mgr) { CPatterned::Think(dt, mgr); } +void CChozoGhost::Think(float dt, CStateManager& mgr) { + if (!GetActive()) + return; + + CPatterned::Think(dt, mgr); + UpdateThermalFrozenState(false); + x68c_boneTracking.Update(dt); + x6c8_ = std::max(0.f, x6c8_ - dt); + xe7_31_targetable = IsVisibleEnough(mgr); +} void CChozoGhost::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { CPatterned::PreRender(mgr, frustum); } -void CChozoGhost::Render(const CStateManager& mgr) const { CPatterned::Render(mgr); } +void CChozoGhost::Render(const CStateManager& mgr) const { + if (x6c8_ > 0.f) + mgr.DrawSpaceWarp(x6cc_, std::sin((M_PIF * x6c8_) / x56c_fadeOutDelay)); + + if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) { + CElementGen::SetSubtractBlend(true); + CElementGen::g_ParticleSystemInitialized = true; + CGraphics::SetFog(ERglFogMode::PerspLin, 0.f, 75.f, zeus::skBlack); + mgr.SetupFogForArea3XRange(GetAreaIdAlways()); + } + + CPatterned::Render(mgr); + + if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) { + CGraphics::SetFog(ERglFogMode::PerspLin, 0.f, 75.f, zeus::skBlack); + GetModelData()->GetAnimationData()->GetParticleDB().RenderSystemsToBeDrawnLast(); + mgr.SetupFogForArea(GetAreaIdAlways()); + CElementGen::SetSubtractBlend(false); + CElementGen::g_ParticleSystemInitialized = false; + } +} void CChozoGhost::Touch(CActor& act, CStateManager& mgr) { CPatterned::Touch(act, mgr); } @@ -153,7 +212,7 @@ void CChozoGhost::KnockBack(const zeus::CVector3f& dir, CStateManager& mgr, cons CPatterned::KnockBack(dir, mgr, info, type, inDeferred, magnitude); } -bool CChozoGhost::CanBeShot(const CStateManager& mgr, int w1) { return CAi::CanBeShot(mgr, w1); } +bool CChozoGhost::CanBeShot(const CStateManager& mgr, int w1) { return IsVisibleEnough(mgr); } void CChozoGhost::Dead(CStateManager& mgr, EStateMsg msg, float arg) { CPatterned::Dead(mgr, msg, arg); } @@ -161,51 +220,205 @@ void CChozoGhost::SelectTarget(CStateManager& mgr, EStateMsg msg, float arg) { C void CChozoGhost::Run(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Run(mgr, msg, arg); } -void CChozoGhost::Generate(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Generate(mgr, msg, arg); } +void CChozoGhost::Generate(CStateManager& mgr, EStateMsg msg, float arg) { + if (msg == EStateMsg::Activate) { + x330_stateMachineState.SetDelay(x56c_fadeOutDelay); + x32c_animState = EAnimState::Ready; + x664_27_ = false; + CRayCastResult res = mgr.RayStaticIntersection(GetTranslation(), zeus::skDown, 100.f, + CMaterialFilter::MakeInclude({EMaterialTypes::Floor})); + if (res.IsInvalid()) { + x678_ = mgr.GetPlayer().GetTranslation().z(); + } else + x678_ = res.GetPoint().z(); + x3e8_alphaDelta = 1.f; + x664_29_ = true; + if (x56c_fadeOutDelay > 0.f) { + x6c8_ = x56c_fadeOutDelay; + FindNearestSolid(mgr, zeus::skDown); + } + } else if (msg == EStateMsg::Update) { + TryCommand(mgr, pas::EAnimationState::Jump, &CPatterned::TryJump, 0); + if (x32c_animState == EAnimState::Over) { + x68c_boneTracking.SetActive(true); + x68c_boneTracking.SetTarget(mgr.GetPlayer().GetUniqueId()); + FloatToLevel(x678_, arg); + } else if (x32c_animState == EAnimState::Repeat) { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Crouch); + if (!x664_27_) { + zeus::CVector3f pos = GetTranslation(); + SetTranslation({pos.x(), pos.y(), x678_ + x668_}); + x664_27_ = true; + } + } + } else if (msg == EStateMsg::Deactivate) { + x32c_animState = EAnimState::NotReady; + x665_24_ = false; + x664_27_ = false; + } +} -void CChozoGhost::Deactivate(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Deactivate(mgr, msg, arg); } +void CChozoGhost::Deactivate(CStateManager& mgr, EStateMsg msg, float arg) { + if (msg == EStateMsg::Activate) { + x68c_boneTracking.SetActive(false); + ReleaseCoverPoint(mgr, x674_coverPoint); + x32c_animState = EAnimState::Ready; + x665_24_ = true; + } else if (msg == EStateMsg::Update) { + TryCommand(mgr, pas::EAnimationState::Generate, &CPatterned::TryGenerate, 1); + if (x32c_animState == EAnimState::Repeat) + GetBodyController()->SetLocomotionType(pas::ELocomotionType::Relaxed); + } else if (msg == EStateMsg::Deactivate) { + x32c_animState = EAnimState::NotReady; + } +} void CChozoGhost::Attack(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Attack(mgr, msg, arg); } void CChozoGhost::Shuffle(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Shuffle(mgr, msg, arg); } -void CChozoGhost::InActive(CStateManager& mgr, EStateMsg msg, float arg) { CAi::InActive(mgr, msg, arg); } +void CChozoGhost::InActive(CStateManager& mgr, EStateMsg msg, float arg) { + if (msg == EStateMsg::Activate) { + if (!x450_bodyController->GetActive()) + x450_bodyController->Activate(mgr); -void CChozoGhost::Taunt(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Taunt(mgr, msg, arg); } + if (x63c_ == 3) { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Crouch); + x42c_color.a() = 1.f; + } else { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed); + x42c_color.a() = 0.f; + } + + RemoveMaterial(EMaterialTypes::Solid, mgr); + x150_momentum.zeroOut(); + x665_24_ = true; + } +} + +void CChozoGhost::Taunt(CStateManager& mgr, EStateMsg msg, float arg) { + if (msg == EStateMsg::Activate) { + x32c_animState = EAnimState::Ready; + } else if (msg == EStateMsg::Update) { + TryCommand(mgr, pas::EAnimationState::Taunt, &CPatterned::TryTaunt, 0); + FloatToLevel(x678_, arg); + } else { + x32c_animState = EAnimState::NotReady; + x665_26_ = false; + } +} void CChozoGhost::Hurled(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Hurled(mgr, msg, arg); } void CChozoGhost::WallDetach(CStateManager& mgr, EStateMsg msg, float arg) { CAi::WallDetach(mgr, msg, arg); } -void CChozoGhost::Growth(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Growth(mgr, msg, arg); } +void CChozoGhost::Growth(CStateManager& mgr, EStateMsg msg, float arg) { + if (msg == EStateMsg::Activate) { + x330_stateMachineState.SetDelay(x56c_fadeOutDelay); + GetBodyController()->SetLocomotionType(pas::ELocomotionType::Crouch); + x3e8_alphaDelta = 1.f; + x664_29_ = true; + if (x56c_fadeOutDelay > 0.f) { + x6c8_ = x56c_fadeOutDelay; + FindNearestSolid(mgr, zeus::skUp); + } + } else if (msg == EStateMsg::Deactivate) { + x665_24_ = false; + x68c_boneTracking.SetActive(false); + x68c_boneTracking.SetTarget(mgr.GetPlayer().GetUniqueId()); + } +} -void CChozoGhost::Land(CStateManager& mgr, EStateMsg msg, float arg) { CAi::Land(mgr, msg, arg); } +void CChozoGhost::Land(CStateManager& mgr, EStateMsg msg, float arg) { + if (msg == EStateMsg::Update) { + FloatToLevel(x678_, arg); + if (std::fabs(x678_ - GetTranslation().z()) < 0.05f) { + x330_stateMachineState.SetCodeTrigger(); + } + } +} -bool CChozoGhost::Leash(CStateManager& mgr, float arg) { return CPatterned::Leash(mgr, arg); } +void CChozoGhost::Lurk(CStateManager& mgr, EStateMsg msg, float arg) { + if (msg == EStateMsg::Activate) { + x330_stateMachineState.SetDelay(x684_lurkDelay); + } else if (msg == EStateMsg::Update) { + FloatToLevel(x678_, arg); + } +} -bool CChozoGhost::InRange(CStateManager& mgr, float arg) { return CPatterned::InRange(mgr, arg); } +bool CChozoGhost::Leash(CStateManager& mgr, float arg) { return x665_27_playerInLeashRange || CPatterned::Leash(mgr, arg); } -bool CChozoGhost::InPosition(CStateManager& mgr, float arg) { return CPatterned::InPosition(mgr, arg); } +bool CChozoGhost::InRange(CStateManager& mgr, float arg) { return x665_28_inRange; } -bool CChozoGhost::AggressionCheck(CStateManager& mgr, float arg) { return CAi::AggressionCheck(mgr, arg); } +bool CChozoGhost::InPosition(CStateManager& mgr, float arg) { return x680_stateProg == 2; } -bool CChozoGhost::ShouldTaunt(CStateManager& mgr, float arg) { return CAi::ShouldTaunt(mgr, arg); } +bool CChozoGhost::AggressionCheck(CStateManager& mgr, float arg) { return x665_29_aggressive; } -bool CChozoGhost::ShouldFlinch(CStateManager& mgr, float arg) { return CAi::ShouldFlinch(mgr, arg); } +bool CChozoGhost::ShouldTaunt(CStateManager& mgr, float arg) { return x680_stateProg == 1; } -bool CChozoGhost::ShouldMove(CStateManager& mgr, float arg) { return CAi::ShouldMove(mgr, arg); } +bool CChozoGhost::ShouldFlinch(CStateManager& mgr, float arg) { return x664_25_flinch; } -bool CChozoGhost::AIStage(CStateManager& mgr, float arg) { return CAi::AIStage(mgr, arg); } +bool CChozoGhost::ShouldMove(CStateManager& mgr, float arg) { return x680_stateProg == 3; } + +bool CChozoGhost::AIStage(CStateManager& mgr, float arg) { return arg == x63c_; } u8 CChozoGhost::GetModelAlphau8(const CStateManager& mgr) const { - if (mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::EPlayerVisor::XRay || !IsAlive()) - return u8(x42c_color.a() * 255); + //if (mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::EPlayerVisor::XRay || !IsAlive()) + // return u8(x42c_color.a() * 255); return 255; } bool CChozoGhost::IsOnGround() const { return x664_24_onGround; } -CProjectileInfo* CChozoGhost::GetProjectileInfo() { return CPatterned::GetProjectileInfo(); } +CProjectileInfo* CChozoGhost::GetProjectileInfo() { return x67c_ == 2 ? &x578_ : &x5a0_; } + +void CChozoGhost::AddToTeam(CStateManager& mgr) { + if (x6c4_teamMgr == kInvalidUniqueId) + x6c4_teamMgr = CTeamAiMgr::GetTeamAiMgr(*this, mgr); + + if (x6c4_teamMgr == kInvalidUniqueId) + return; + + if (TCastToPtr teamMgr = mgr.ObjectById(x6c4_teamMgr)) + teamMgr->AssignTeamAiRole(*this, CTeamAiRole::ETeamAiRole::Ranged, CTeamAiRole::ETeamAiRole::Unknown, + CTeamAiRole::ETeamAiRole::Invalid); +} + +void CChozoGhost::RemoveFromTeam(CStateManager& mgr) { + if (x6c4_teamMgr == kInvalidUniqueId) + return; + + if (TCastToPtr teamMgr = mgr.ObjectById(x6c4_teamMgr)) { + if (teamMgr->IsPartOfTeam(GetUniqueId())) { + teamMgr->RemoveTeamAiRole(GetUniqueId()); + x6c4_teamMgr = kInvalidUniqueId; + } + } +} + +void CChozoGhost::FloatToLevel(float f1, float f2) { + zeus::CVector3f pos = GetTranslation(); + pos.z() = 4.f * (f1 - pos.z()) * f2 + pos.z(); + SetTranslation(pos); +} + +const CChozoGhost::CBehaveChance& CChozoGhost::ChooseBehaveChanceRange(CStateManager& mgr) { + const float dist = (GetTranslation() - mgr.GetPlayer().GetTranslation()).magnitude(); + if (x654_ <= dist && x658_ > dist) + return x5e8_; + else if (x658_ <= dist) + return x608_; + else + return x5c8_; +} +void CChozoGhost::FindNearestSolid(CStateManager& mgr, const zeus::CVector3f& dir) { + CRayCastResult res = mgr.RayStaticIntersection(GetBoundingBox().center() + (dir * 8.f), -dir, 8.f, + CMaterialFilter::MakeInclude({EMaterialTypes::Solid})); + if (res.IsInvalid()) { + x6cc_ = GetBoundingBox().center() + dir; + } else + x6cc_ = res.GetPoint(); +} } // namespace urde::MP1 \ No newline at end of file diff --git a/Runtime/MP1/World/CChozoGhost.hpp b/Runtime/MP1/World/CChozoGhost.hpp index 5785d7569..4b1654851 100644 --- a/Runtime/MP1/World/CChozoGhost.hpp +++ b/Runtime/MP1/World/CChozoGhost.hpp @@ -59,7 +59,7 @@ private: u32 x65c_nearChance; u32 x660_midChance; bool x664_24_onGround : 1; - bool x664_25_ : 1; + bool x664_25_flinch : 1; bool x664_26_ : 1; bool x664_27_ : 1; bool x664_28_ : 1; @@ -69,25 +69,31 @@ private: bool x665_24_ : 1; bool x665_25_ : 1; bool x665_26_ : 1; - bool x665_27_ : 1; - bool x665_28_ : 1; - bool x665_29_ : 1; + bool x665_27_playerInLeashRange : 1; + bool x665_28_inRange : 1; + bool x665_29_aggressive : 1; float x668_ = 0.f; float x66c_ = 0.f; float x670_ = 0.f; - TUniqueId x674_ = kInvalidUniqueId; + TUniqueId x674_coverPoint = kInvalidUniqueId; + float x6c8_ = 0.f; float x678_ = 0.f; u32 x67c_ = -1; - u32 x680_ = 0; - float x684_ = 1.f; + u32 x680_stateProg = 0; + float x684_lurkDelay = 1.f; CSteeringBehaviors x688_; CBoneTracking x68c_boneTracking; - TUniqueId x6c4_ = kInvalidUniqueId; - float x6c8_ = 0.f; + TUniqueId x6c4_teamMgr = kInvalidUniqueId; zeus::CVector3f x6cc_; u32 x6d8_ = 1; u32 x6dc_; - CTeamAiMgr + + void AddToTeam(CStateManager& mgr); + void RemoveFromTeam(CStateManager& mgr); + void FloatToLevel(float f1, float f2); + const CBehaveChance& ChooseBehaveChanceRange(CStateManager& mgr); + bool IsVisibleEnough(const CStateManager& mgr) const { return GetModelAlphau8(mgr) > 31; } + void FindNearestSolid(CStateManager& mgr, const zeus::CVector3f& dir); public: DEFINE_PATTERNED(ChozoGhost) @@ -125,6 +131,7 @@ public: void WallDetach(CStateManager& mgr, EStateMsg msg, float arg) override; void Growth(CStateManager& mgr, EStateMsg msg, float arg) override; void Land(CStateManager& mgr, EStateMsg msg, float arg) override; + void Lurk(CStateManager& mgr, EStateMsg msg, float arg) override; bool Leash(CStateManager& mgr, float arg) override; bool InRange(CStateManager& mgr, float arg) override; bool InPosition(CStateManager& mgr, float arg) override; diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index 6f1495681..b350ba5d5 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -1434,7 +1434,7 @@ CEntity* ScriptLoader::LoadMetroidBeta(CStateManager& mgr, CInputStream& in, int } CEntity* ScriptLoader::LoadChozoGhost(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { - if (!EnsurePropertyCount(propCount, 32, "ChozoGhost")) + if (!EnsurePropertyCount(propCount, 31, "ChozoGhost")) return nullptr; SScaledActorHead actorHead = LoadScaledActorHead(in, mgr);