diff --git a/Runtime/Character/CBodyController.cpp b/Runtime/Character/CBodyController.cpp index 63460bc11..23960d058 100644 --- a/Runtime/Character/CBodyController.cpp +++ b/Runtime/Character/CBodyController.cpp @@ -90,7 +90,7 @@ void CBodyController::Update(float dt, CStateManager& mgr) if (x300_25_active) { x300_24_animationOver = - !x0_actor.GetModelData()->GetAnimationData()->IsAnimTimeRemaining(dt, "Whole Body"); + !x0_actor.GetModelData()->GetAnimationData()->IsAnimTimeRemaining(dt, "Whole Body"sv); x4_cmdMgr.BlendSteeringCmds(); x2dc_rot = zeus::CQuaternion::skNoRotation; UpdateBody(dt, mgr); @@ -306,7 +306,7 @@ void CBodyController::UpdateFrozenInfo(float dt, CStateManager& mgr) { UnFreeze(); x0_actor.SendScriptMsgs(EScriptObjectState::UnFrozen, mgr, EScriptObjectMessage::None); - mgr.GetActorModelParticles()->StartIce(x0_actor, mgr); + mgr.GetActorModelParticles()->StartIce(x0_actor); return; } if (x310_timeFrozen <= totalTime) diff --git a/Runtime/Character/CSequenceHelper.cpp b/Runtime/Character/CSequenceHelper.cpp index 6abb5f7d9..e8734a315 100644 --- a/Runtime/Character/CSequenceHelper.cpp +++ b/Runtime/Character/CSequenceHelper.cpp @@ -110,7 +110,7 @@ CSequenceFundamentals CSequenceHelper::ComputeSequenceFundamentals() if (i < x10_treeNodes.size()-1) { node = CTreeUtils::GetTransitionTree(node, - CAnimTreeNode::Cast(x10_treeNodes[i+1]->Clone()), x0_animCtx); + CAnimTreeNode::Cast(std::move(x10_treeNodes[i+1]->Clone())), x0_animCtx); } } } diff --git a/Runtime/MP1/World/CBeetle.hpp b/Runtime/MP1/World/CBeetle.hpp index 398662b9f..a6a0454d9 100644 --- a/Runtime/MP1/World/CBeetle.hpp +++ b/Runtime/MP1/World/CBeetle.hpp @@ -19,6 +19,7 @@ public: }; private: public: + DEFINE_PATTERNED(Beetle) CBeetle(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&, const CPatternedInfo&, CPatterned::EFlavorType,EEntranceType, const CDamageInfo &, const CDamageVulnerability&, const zeus::CVector3f&, float, float, float, const CDamageVulnerability&, const CActorParameters&, diff --git a/Runtime/MP1/World/CMetaree.hpp b/Runtime/MP1/World/CMetaree.hpp index 70e71db76..024bc3c23 100644 --- a/Runtime/MP1/World/CMetaree.hpp +++ b/Runtime/MP1/World/CMetaree.hpp @@ -35,7 +35,7 @@ class CMetaree : public CPatterned u32 x5cc_; public: - static constexpr ECharacter CharacterType = ECharacter::Metaree; + DEFINE_PATTERNED(Metaree) CMetaree(TUniqueId, std::string_view, EFlavorType, const CEntityInfo&, const zeus::CTransform&, CModelData&&, const CPatternedInfo&, const CDamageInfo&, float, const zeus::CVector3f&, float, EBodyType, float, float, const CActorParameters&); diff --git a/Runtime/MP1/World/CMetroid.hpp b/Runtime/MP1/World/CMetroid.hpp index 4b8ffeaf0..96bf28bf6 100644 --- a/Runtime/MP1/World/CMetroid.hpp +++ b/Runtime/MP1/World/CMetroid.hpp @@ -29,7 +29,7 @@ public: class CMetroid : public CPatterned { public: - static constexpr ECharacter CharacterType = ECharacter::Metroid; + DEFINE_PATTERNED(Metroid) CMetroid(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& aParms, const CMetroidData& metroidData); diff --git a/Runtime/MP1/World/CMetroidBeta.hpp b/Runtime/MP1/World/CMetroidBeta.hpp index 5336f9ed0..b58ee1b74 100644 --- a/Runtime/MP1/World/CMetroidBeta.hpp +++ b/Runtime/MP1/World/CMetroidBeta.hpp @@ -10,7 +10,7 @@ namespace urde::MP1 class CMetroidBeta : public CPatterned { public: - static constexpr ECharacter CharacterType = ECharacter::MetroidBeta; + 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); diff --git a/Runtime/MP1/World/CMetroidPrimeExo.hpp b/Runtime/MP1/World/CMetroidPrimeExo.hpp index a19942579..d3761affb 100644 --- a/Runtime/MP1/World/CMetroidPrimeExo.hpp +++ b/Runtime/MP1/World/CMetroidPrimeExo.hpp @@ -103,7 +103,7 @@ struct SPrimeExoRoomParameters class CMetroidPrimeExo : public CPatterned { public: - static constexpr ECharacter CharacterType = ECharacter::MetroidPrimeExo; + DEFINE_PATTERNED(MetroidPrimeExo) CMetroidPrimeExo(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& aParms, u32 pw1, const CCameraShakeData& shakeData1, const CCameraShakeData& shakeData2, diff --git a/Runtime/MP1/World/CNewIntroBoss.hpp b/Runtime/MP1/World/CNewIntroBoss.hpp index c8f57f49a..2bea24899 100644 --- a/Runtime/MP1/World/CNewIntroBoss.hpp +++ b/Runtime/MP1/World/CNewIntroBoss.hpp @@ -13,6 +13,7 @@ namespace MP1 class CNewIntroBoss : public CPatterned { public: + DEFINE_PATTERNED(NewIntroBoss) CNewIntroBoss(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, float, u32, const CDamageInfo& dInfo, diff --git a/Runtime/MP1/World/CParasite.hpp b/Runtime/MP1/World/CParasite.hpp index 6d7bedcdf..21ecc993f 100644 --- a/Runtime/MP1/World/CParasite.hpp +++ b/Runtime/MP1/World/CParasite.hpp @@ -38,6 +38,7 @@ struct CParasiteInfo class CParasite : public CWallWalker { public: + DEFINE_PATTERNED(Parasite) CParasite(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo&, u32, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, bool, u32, const CDamageVulnerability&, const CParasiteInfo&, u16, u16, diff --git a/Runtime/MP1/World/CPuddleToadGamma.hpp b/Runtime/MP1/World/CPuddleToadGamma.hpp index f3bac05a3..9404d28f3 100644 --- a/Runtime/MP1/World/CPuddleToadGamma.hpp +++ b/Runtime/MP1/World/CPuddleToadGamma.hpp @@ -9,7 +9,7 @@ namespace urde::MP1 class CPuddleToadGamma : public CPatterned { public: - static constexpr ECharacter CharacterType = ECharacter::PuddleToad; + DEFINE_PATTERNED(PuddleToad) CPuddleToadGamma(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& aParms, float f1, float f2, float f3, const zeus::CVector3f& v1, diff --git a/Runtime/MP1/World/CRidley.hpp b/Runtime/MP1/World/CRidley.hpp index d41a9ccab..d6a02b3a3 100644 --- a/Runtime/MP1/World/CRidley.hpp +++ b/Runtime/MP1/World/CRidley.hpp @@ -62,6 +62,7 @@ class CRidley : public CPatterned { CRidleyData x568_; public: + DEFINE_PATTERNED(Ridley) CRidley(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&, const CPatternedInfo&, const CActorParameters&, CInputStream&, u32); diff --git a/Runtime/MP1/World/CSeedling.hpp b/Runtime/MP1/World/CSeedling.hpp index 44fd41c82..70b584393 100644 --- a/Runtime/MP1/World/CSeedling.hpp +++ b/Runtime/MP1/World/CSeedling.hpp @@ -10,6 +10,7 @@ namespace MP1 class CSeedling : public CWallWalker { public: + DEFINE_PATTERNED(Seedling) CSeedling(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&, const CPatternedInfo&, const CActorParameters&, CAssetId, CAssetId, const CDamageInfo&, const CDamageInfo&, diff --git a/Runtime/MP1/World/CSpacePirate.hpp b/Runtime/MP1/World/CSpacePirate.hpp index 95a0d153a..6df62bbe7 100644 --- a/Runtime/MP1/World/CSpacePirate.hpp +++ b/Runtime/MP1/World/CSpacePirate.hpp @@ -9,6 +9,10 @@ namespace urde::MP1 class CSpacePirate : public CPatterned { +public: + DEFINE_PATTERNED(SpacePirate) + +private: class CSpacePirateData { float x0_; diff --git a/Runtime/MP1/World/CThardusRockProjectile.hpp b/Runtime/MP1/World/CThardusRockProjectile.hpp index 0c3cb136d..957f508f7 100644 --- a/Runtime/MP1/World/CThardusRockProjectile.hpp +++ b/Runtime/MP1/World/CThardusRockProjectile.hpp @@ -9,7 +9,7 @@ namespace urde class CThardusRockProjectile : public CPatterned { public: - static constexpr ECharacter CharacterType = ECharacter::ThardusRockProjectile; + DEFINE_PATTERNED(ThardusRockProjectile) CThardusRockProjectile(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& modelData, const CActorParameters& aParms, const CPatternedInfo& patternedInfo, const std::vector& mDataVec, u32); diff --git a/Runtime/MP1/World/CWarWasp.hpp b/Runtime/MP1/World/CWarWasp.hpp index 55e2eb8b2..797eb4aa4 100644 --- a/Runtime/MP1/World/CWarWasp.hpp +++ b/Runtime/MP1/World/CWarWasp.hpp @@ -11,6 +11,7 @@ namespace MP1 class CWarWasp : public CPatterned { public: + DEFINE_PATTERNED(WarWasp) CWarWasp(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, CPatterned::EFlavorType flavor, CPatterned::EColliderType, const CDamageInfo& dInfo1, diff --git a/Runtime/World/CActorModelParticles.cpp b/Runtime/World/CActorModelParticles.cpp index d124e47a0..80c79f0c1 100644 --- a/Runtime/World/CActorModelParticles.cpp +++ b/Runtime/World/CActorModelParticles.cpp @@ -288,9 +288,18 @@ std::list::iterator CActorModelParticles::FindOrCre return x0_items.emplace(x0_items.end(), act, *this); } -void CActorModelParticles::StartIce(CActor& actor, CStateManager& mgr) +void CActorModelParticles::StartIce(CActor& actor) { +} +void CActorModelParticles::StopElectric(CActor& act) +{ + if (!act.GetPointGeneratorParticles()) + { + auto iter = FindSystem(act.GetUniqueId()); + if (iter != x0_items.cend() && iter->xc0_particleElectric) + iter->xc0_particleElectric->SetParticleEmission(false); + } } void CActorModelParticles::AddRainSplashGenerator(CActor& act, CStateManager& mgr, u32 maxSplashes, diff --git a/Runtime/World/CActorModelParticles.hpp b/Runtime/World/CActorModelParticles.hpp index 5381c6461..d9603affa 100644 --- a/Runtime/World/CActorModelParticles.hpp +++ b/Runtime/World/CActorModelParticles.hpp @@ -95,11 +95,30 @@ public: void SetupHook(TUniqueId uid); std::list::const_iterator FindSystem(TUniqueId uid) const; std::list::iterator FindOrCreateSystem(CActor& act); - void StartIce(CActor& actor, CStateManager& mgr); + void StartIce(CActor& actor); void AddRainSplashGenerator(CActor& act, CStateManager& mgr, u32 maxSplashes, u32 genRate, float minZ); void RemoveRainSplashGenerator(CActor& act); void Render(const CActor& actor) const; + void StartElectric(CActor& act) + { + auto iter = FindOrCreateSystem(act); + + if (iter->xc0_particleElectric && !iter->xc0_particleElectric->GetParticleEmission()) + iter->xc0_particleElectric->SetParticleEmission(true); + + } + + void StopElectric(CActor& act); + + void LightDudeOnFire(CActor& act) + { + auto iter = FindOrCreateSystem(act); + + /* iter->sub801e5a04(false); */ + if (iter->x6c_ > 0.f) + iter->x70_ = true; + } }; } diff --git a/Runtime/World/CAiFuncMap.hpp b/Runtime/World/CAiFuncMap.hpp index 3eccf66c2..5ab64ca60 100644 --- a/Runtime/World/CAiFuncMap.hpp +++ b/Runtime/World/CAiFuncMap.hpp @@ -9,6 +9,7 @@ namespace urde enum class EStateMsg { One = 1, + Two = 2, Twenty = 20 }; diff --git a/Runtime/World/CPatterned.cpp b/Runtime/World/CPatterned.cpp index 50f44c71b..894640161 100644 --- a/Runtime/World/CPatterned.cpp +++ b/Runtime/World/CPatterned.cpp @@ -1,5 +1,6 @@ -#include +#include #include "CPatterned.hpp" +#include "Runtime/CStateManager.hpp" #include "CPatternedInfo.hpp" #include "TCastTo.hpp" #include "CActorParameters.hpp" @@ -9,6 +10,9 @@ #include "CPlayer.hpp" #include "Weapon/CGameProjectile.hpp" #include "Character/CAnimData.hpp" +#include "TCastTo.hpp" +#include "MP1/World/CSpacePirate.hpp" +#include "World/CStateMachine.hpp" namespace urde { @@ -54,7 +58,7 @@ x3fc_flavor(flavor) x402_30_ = x402_31_ = actorParms.HasThermalHeat(); x403_25_ = true; x403_26_ = true; - x404_ = pInfo.x34_damageInfo; + x404_contactDamage = pInfo.x34_contactDamageInfo; x424_damageWaitTime = pInfo.x50_damageWaitTime; x454_deathSfx = pInfo.xe8_deathSfx; x458_iceShatterSfx = pInfo.x134_iceShatterSfx; @@ -76,15 +80,117 @@ x3fc_flavor(flavor) if (pInfo.x130_particle2.IsValid()) x54c_ = { g_SimplePool->GetObj({FOURCC('PART'), pInfo.x130_particle2})}; - if (x404_.GetRadius() > 0.f) - x404_.SetRadius(0.f); + if (x404_contactDamage.GetRadius() > 0.f) + x404_contactDamage.SetRadius(0.f); xe6_29_renderParticleDBInside = false; x402_27_ = x64_modelData->HasModel(CModelData::EWhichModel::XRay); BuildBodyController(bodyType); } -void CPatterned::Think(float dt, urde::CStateManager& mgr) +void CPatterned::Accept(urde::IVisitor& visitor) +{ + visitor.Visit(this); +} + +void CPatterned::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) +{ + CAi::AcceptScriptMsg(msg, uid, mgr); + + switch(msg) + { + case EScriptObjectMessage::Registered: + { + if (x508_colliderType == EColliderType::Zero) + { + CMaterialList include = GetMaterialFilter().GetIncludeList(); + CMaterialList exclude = GetMaterialFilter().GetExcludeList(); + include.Remove(EMaterialTypes::Character); + exclude.Add(EMaterialTypes::Character); + SetMaterialFilter(CMaterialFilter::MakeIncludeExclude(include, exclude)); + } + + if (HasModelData() && GetModelData()->HasAnimData() && GetModelData()->GetAnimationData()->GetIceModel()) + { + /* TODO Initialize CVertexMorphEffect located at 0x8007CC7C */ + } + + xf8_25_angularEnabled = true; + x450_bodyController->Activate(mgr); + break; + } + case EScriptObjectMessage::OnFloor: + { + if (!x328_25_) + { + x150_momentum = {}; + AddMaterial(EMaterialTypes::GroundCollider, mgr); + } + x328_27_onGround = true; + break; + } + case EScriptObjectMessage::Falling: + { + if (!x328_25_) + { + if (x450_bodyController->GetPercentageFrozen() == 0.f) + { + x150_momentum = {0.f, 0.f, -GetWeight()}; + RemoveMaterial(EMaterialTypes::GroundCollider, mgr); + } + } + x328_27_onGround = false; + break; + } + case EScriptObjectMessage::Activate: + x3a0_ = GetTranslation(); + break; + case EScriptObjectMessage::Deleted: + if (x330_stateMachineState.GetActorState() != nullptr) + x330_stateMachineState.GetActorState()->CallFunc(mgr, *this, EStateMsg::Two, 0.f); + break; + case EScriptObjectMessage::Damage: + { + if (TCastToConstPtr proj = mgr.GetObjectById(uid)) + { + const CDamageInfo& info = proj->GetDamageInfo(); + if (info.GetWeaponMode().GetType() == EWeaponType::Wave) + { + if (x460_.x81_26_ && info.GetWeaponMode().IsComboed() && HealthInfo(mgr)) + { + x401_31_ = true; + KnockBack(GetTransform().frontVector(), mgr, info, EKnockBackType::One, false, + info.GetKnockBackPower()); +// x460_.sub80233D30(2); + } + } + else if (info.GetWeaponMode().GetType() == EWeaponType::Plasma) + { + if (x460_.x81_27_ && info.GetWeaponMode().IsCharged() && HealthInfo(mgr)) + { + KnockBack(GetTransform().frontVector(), mgr, info, EKnockBackType::One, false, info.GetKnockBackPower()); + // x460_.sub80233D30(2); + } + } + if (mgr.GetPlayer().GetUniqueId() == proj->GetOwnerId()) + x400_24_ = true; + } + break; + } + case EScriptObjectMessage::InvulnDamage: + { + if (TCastToConstPtr proj = mgr.GetObjectById(uid)) + { + if (proj->GetOwnerId() == mgr.GetPlayer().GetUniqueId()) + x400_24_ = true; + } + break; + } + default: break; + } +} + +void CPatterned::Think(float dt, CStateManager& mgr) { if (!GetActive()) return; @@ -103,6 +209,146 @@ void CPatterned::Think(float dt, urde::CStateManager& mgr) if (froz > 0.8f) x400_29_ = true; } + + if (x400_25_ && !x400_28_ && x400_29_) + { + if (x3e0_ > 0.f && x400_29_) + { + SendScriptMsgs(EScriptObjectState::UNKS4, mgr, EScriptObjectMessage::None); + sub8007ab34(mgr); + } + else + { + SendScriptMsgs(EScriptObjectState::UNKS4, mgr, EScriptObjectMessage::None); + sub8007ace8(mgr); + } + } + else if (!x400_29_) + { + x3e0_ -= dt; + if (x403_26_) + { + if (x330_stateMachineState.sub8007FB9C()) + { + u32 unk = x330_stateMachineState.sub8007FB9C(); + bool isDead = false; //sub8007A454(unk, "Dead"sv); + + if (!isDead && x330_stateMachineState.x8_time > 15.f) + sub8007ace8(mgr); + } + } + } + + sub8007a68c(dt, mgr); + + x3e4_ = HealthInfo(mgr)->GetHP(); + if (!x330_stateMachineState.x4_state) + x330_stateMachineState.SetState(mgr, *this, GetStateMachine(), "Start"sv); + + zeus::CVector3f diffVec = x4e4_ - GetTranslation(); + if (!x328_25_) + diffVec.z = 0.f; + + if (diffVec.magSquared() > (0.1f * dt)) + x4f0_ += dt; + else + x4f0_ = 0.f; + + if (x460_.x81_26_ && x401_31_ && x402_24_) + Shock(0.5f + mgr.GetActiveRandom()->Range(0.f, 0.5f), 0.2f); + + x402_24_ = x401_24_; + x401_31_ = false; + if (x450_bodyController->IsElectrocuting()) + { + mgr.GetActorModelParticles()->StartElectric(*this); + if (x3f0_ > 0.f && x400_25_) + { + CDamageInfo dInfo({EWeaponType::Wave}, x3f0_, 0.f, 0.f); + mgr.ApplyDamage(kInvalidUniqueId, GetUniqueId(), kInvalidUniqueId, dInfo, + CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), {}); + } + } + else + { + if (x3f0_!= 0.f) + { + //x450_bodyController->sub80139f0c(x3f0_); + mgr.GetActorModelParticles()->StopElectric(*this); + } + } + + if (x450_bodyController->IsOnFire()) + { + if (x400_25_) + { + mgr.GetActorModelParticles()->LightDudeOnFire(*this); + CDamageInfo dInfo({EWeaponType::Wave}, x3f0_, 0.f, 0.f); + mgr.ApplyDamage(kInvalidUniqueId, GetUniqueId(), kInvalidUniqueId, dInfo, + CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), {}); + } + } + else if (x3ec_ > 0.f) + x3ec_ = 0.f; + + + //if (x450_bodyController->IsFrozen()) + //mgr.GetActorModelParticles()->sub801e5044(*this); + + if (!x401_27_ || x401_28_) + x3e8_ = -0.33333334f; + + if (x401_30_) + { + x401_30_ = false; + Death(mgr, GetTransform().frontVector(), EStateMsg::Twenty); + } + + float thinkDt = (x400_25_ ? dt : dt * sub80078a88()); + + x450_bodyController->Update(thinkDt, mgr); + x450_bodyController->MultiplyPlaybackRate(x3b4_speed); + SAdvancementDeltas deltas = UpdateAnimation(thinkDt, mgr, !x450_bodyController->IsFrozen()); + x434_posDelta = deltas.x0_posDelta; + x440_rotDelta = deltas.xc_rotDelta; + + if (x403_25_ && x450_bodyController->GetPercentageFrozen() < 1.f) + x330_stateMachineState.Update(mgr, *this, thinkDt); + + + ThinkAboutMove(thinkDt); + + //x460_.sub80233b58(thinkDt, mgr, *this); + x4e4_ = GetTranslation() + PredictMotion(thinkDt).x0_translation; + x328_26_ = false; + if (x420_ > 0.f) + x420_ -= dt; + + if (x401_28_ && x3f4_ > dt) + x3f4_ -= dt; + + xd0_thermalMag = x50c_thermalMag; + sub8007a5b8(dt); + + if (!x450_bodyController->IsFrozen()) + { + if (x3a0_ == zeus::CVector3f()) + x3a0_ = GetTranslation(); + + if (x3cc_playerLeashRadius != 0.f) + { + zeus::CVector3f diffVec = (GetTranslation() - mgr.GetPlayer().GetTranslation()); + if (diffVec.magSquared() > x3cc_playerLeashRadius) + x3d4_curPlayerLeashTime += dt; + else + x3d4_curPlayerLeashTime = 0.f; + } + } + else + RemoveEmitter(); + + if (x2f8_ > 0.f) + x2f8_ -= dt; } void CPatterned::Touch(CActor& act, CStateManager& mgr) @@ -117,6 +363,17 @@ void CPatterned::Touch(CActor& act, CStateManager& mgr) } } +std::experimental::optional CPatterned::GetTouchBounds() const +{ + return GetBoundingBox(); +} + +bool CPatterned::CanRenderUnsorted(const urde::CStateManager& mgr) const +{ + return x64_modelData->GetAnimationData()->GetParticleDB().AreAnySystemsDrawnWithModel() ? false : + CActor::CanRenderUnsorted(mgr); +} + zeus::CVector3f CPatterned::GetAimPosition(const urde::CStateManager& mgr, float dt) const { zeus::CVector3f offset; @@ -172,4 +429,109 @@ void CPatterned::SetupPlayerCollision(bool v) } +float CPatterned::sub80078a88() +{ + float f0 = (x401_28_ ? x3f4_ / 1.f : 1.f); + return zeus::max(0.1f, f0); +} + +void CPatterned::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) +{ +#if 1 + if (mgr.GetPlayerState()->GetActiveVisor(mgr ) == CPlayerState::EPlayerVisor::Thermal) + { + SetCalculateLighting(false); + x90_actorLights->BuildConstantAmbientLighting(zeus::CColor::skWhite); + } + else + SetCalculateLighting(true); + + zeus::CColor col = x42c_; + u8 alpha = GetModelAlphau8(mgr); + if (x402_27_ && mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) + alpha = 0x4C; + + if (alpha < 0xFF) + { + if (col.r == 0.f && col.g == 0.f && col.b == 0.f) + col = zeus::CColor::skWhite; + } + + if (x401_29_ && alpha > 0x7F) + { + + } +#endif + + CActor::PreRender(mgr, frustum); + +} + +void CPatterned::ThinkAboutMove(float dt) +{ + bool doMove = true; + if (!x328_25_ && ! x328_27_onGround) + { + x310_.zeroOut(); + doMove = false; + } + + if (doMove && x39c_ < x390_) + { + zeus::CVector3f frontVec = GetTransform().frontVector(); + zeus::CVector3f x31cCpy = x31c_; + if (x31c_.magSquared() > 0.1f) + x31cCpy.normalize(); + float mag = frontVec.dot(x31cCpy); + + switch (x3f8_) + { + case 0: + if (!x328_26_) + break; + case 1: + { + doMove = false; + if (mag > 0.85) + { + doMove = true; + x3f8_ = 2; + break; + } + x3f8_ = 1; + } + case 2: + x3f8_ = 3; + case 3: + { + doMove = true; + if (!x328_26_) + { + x3f8_ = 0; + break; + } + if (mag > 0.89) + x3f8_ = 4; + break; + } + case 4: + { + x328_24_ = true; + doMove = false; + x3f8_ = 0; + } + default: + break; + } + } + + if (!x401_26_ && doMove) + { + const CBodyState* state = x450_bodyController->GetBodyStateInfo().GetCurrentState(); + if (state->ApplyAnimationDeltas() && !zeus::close_enough(x2e0_ - GetTranslation(), {})) + MoveToOR((x64_modelData->GetScale() * x434_posDelta) * x55c_, dt); + } + + RotateToOR(x440_rotDelta, dt); +} } diff --git a/Runtime/World/CPatterned.hpp b/Runtime/World/CPatterned.hpp index b9a66b441..961ec2d56 100644 --- a/Runtime/World/CPatterned.hpp +++ b/Runtime/World/CPatterned.hpp @@ -10,10 +10,14 @@ #include "TCastTo.hpp" #include "CDamageInfo.hpp" +#ifndef DEFINE_PATTERNED +#define DEFINE_PATTERNED(type) static constexpr ECharacter CharacterType = ECharacter::type; +#endif + namespace urde { class CPatternedInfo; - +class CProjectileInfo; class CPatternedUnknown2 { friend class CPatterned; @@ -112,6 +116,7 @@ protected: float x308_attackTimeVariation; u32 x30c_ = 0; zeus::CVector3f x310_; + zeus::CVector3f x31c_; union { struct @@ -152,7 +157,7 @@ protected: float x3c8_leashRadius; float x3cc_playerLeashRadius; float x3d0_playerLeashTime; - float x3d4_ = 0.f; + float x3d4_curPlayerLeashTime = 0.f; float x3d8_; float x3dc_; float x3e0_; @@ -199,12 +204,14 @@ protected: u32 _dummy2 = 0; }; - CDamageInfo x404_; + CDamageInfo x404_contactDamage; float x420_ = 0.f; float x424_damageWaitTime; float x428_ = -1.f; zeus::CColor x42c_ = zeus::CColor::skBlack; zeus::CColor x430_ = skDamageColor; + zeus::CVector3f x434_posDelta; + zeus::CQuaternion x440_rotDelta; CSteeringBehaviors x45c_; std::unique_ptr x450_bodyController; u32 x454_deathSfx; @@ -226,20 +233,21 @@ protected: std::experimental::optional> x530_; zeus::CVector3f x540_; std::experimental::optional> x54c_; - /* x55c_ */ - /* x560_ */ - /* x564_ */ + zeus::CVector3f x55c_; public: CPatterned(ECharacter character, TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info, const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pinfo, CPatterned::EMovementType movement, EColliderType collider, EBodyType body, const CActorParameters& params, int variant); - void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) {} + void Accept(IVisitor&); + void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&); void Think(float, CStateManager&); + void PreRender(CStateManager&, const zeus::CFrustum&); + void Touch(CActor&, CStateManager&); - virtual void Death(CStateManager&, const zeus::CVector3f&, EStateMsg) {} - virtual void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType, bool, float) {} + std::experimental::optional GetTouchBounds() const; + bool CanRenderUnsorted(const CStateManager& mgr) const; zeus::CVector3f GetOrbitPosition(const CStateManager& mgr) const { return GetAimPosition(mgr, 0.f); @@ -247,6 +255,46 @@ public: zeus::CVector3f GetAimPosition(const CStateManager& mgr, float) const; + void Death(CStateManager&, const zeus::CVector3f&, EStateMsg) {} + void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType, bool, float) {} + void TakeDamage(const zeus::CVector3f&, float) { x428_ = 0.33f;} + bool FixedRandom(CStateManager&, float) { return x330_stateMachineState.GetRandom() < x330_stateMachineState.x14_; } + bool Random(CStateManager&, float dt) { return x330_stateMachineState.GetRandom() < dt; } + //bool FixedDelay(CStateManager&, float dt) { return x330_stateMachineState.GetDelay() == dt; } + + bool Default() { return true; } + virtual bool KnockbackWhenFrozen() const { return true;} + virtual void sub8007ace8(CStateManager&) {} + virtual void sub8007ab34(CStateManager&) {} + virtual void Burn(float, float) {} + virtual void Shock(float, float) {} + virtual void ThinkAboutMove(float); + virtual void GetSearchPath() {} + virtual CDamageInfo GetContactDamage() { return x404_contactDamage; } + virtual u8 GetModelAlphau8(const CStateManager&) const { return u8(x42c_.a * 255);} + virtual bool IsOnGround() const { return x328_27_onGround; } + virtual float GetGravityConstant() const { return 24.525002f; } + virtual CProjectileInfo* GetProjectileInfo() { return nullptr; } + virtual void PhazeOut(CStateManager&) {} + virtual TLockedToken& GetX520() { return x520_.value(); } + float GetDamageDuration() const { return x504_damageDur; } + zeus::CVector3f GetGunEyePos() const; + + void BuildBodyController(EBodyType); + const CBodyController* GetBodyController() const { return x450_bodyController.get(); } + CBodyController* BodyController() { return x450_bodyController.get(); } + void SetupPlayerCollision(bool); + + + void sub8007a68c(float, CStateManager&) {} + float sub80078a88(); + void sub8007a5b8(float) {} + + bool GetX328_26() const { return x328_26_; } + bool GetX402_28() const { return x402_28_; } + + //region Casting Functions + template static T* CastTo(CEntity* ent) { @@ -279,18 +327,7 @@ public: return nullptr; } - bool GetX328_26() const { return x328_26_; } - bool GetX402_28() const { return x402_28_; } - - virtual bool IsOnGround() const { return x328_27_onGround; } - virtual float GetGravityConstant() const { return 24.525002f; } - float GetDamageDuration() const { return x504_damageDur; } - zeus::CVector3f GetGunEyePos() const; - - void BuildBodyController(EBodyType); - const CBodyController* GetBodyController() const { return x450_bodyController.get(); } - CBodyController* BodyController() { return x450_bodyController.get(); } - void SetupPlayerCollision(bool); + //endregion }; } diff --git a/Runtime/World/CPatternedInfo.cpp b/Runtime/World/CPatternedInfo.cpp index 955ba3e6e..f642660b3 100644 --- a/Runtime/World/CPatternedInfo.cpp +++ b/Runtime/World/CPatternedInfo.cpp @@ -18,7 +18,7 @@ CPatternedInfo::CPatternedInfo(CInputStream& in, u32 pcount) , x28_leashRadius(in.readFloatBig()) , x2c_playerLeashRadius(in.readFloatBig()) , x30_playerLeashTime(in.readFloatBig()) -, x34_damageInfo(in) +, x34_contactDamageInfo(in) , x50_damageWaitTime(in.readFloatBig()) , x54_healthInfo(in) , x5c_damageVulnerability(in) diff --git a/Runtime/World/CPatternedInfo.hpp b/Runtime/World/CPatternedInfo.hpp index c580e64d8..e20f3c2f5 100644 --- a/Runtime/World/CPatternedInfo.hpp +++ b/Runtime/World/CPatternedInfo.hpp @@ -27,7 +27,7 @@ class CPatternedInfo float x28_leashRadius; float x2c_playerLeashRadius; float x30_playerLeashTime; - CDamageInfo x34_damageInfo; + CDamageInfo x34_contactDamageInfo; float x50_damageWaitTime; CHealthInfo x54_healthInfo; CDamageVulnerability x5c_damageVulnerability; diff --git a/Runtime/World/CStateMachine.cpp b/Runtime/World/CStateMachine.cpp index 2bdaf78a0..b08320f8a 100644 --- a/Runtime/World/CStateMachine.cpp +++ b/Runtime/World/CStateMachine.cpp @@ -86,7 +86,7 @@ void CStateMachineState::Setup(const CStateMachine* machine) x0_machine = machine; x4_state = nullptr; x8_time = 0.f; - xc_ = 0.f; + xc_random = 0.f; x10_ = 0.f; } diff --git a/Runtime/World/CStateMachine.hpp b/Runtime/World/CStateMachine.hpp index a6aa25e04..97c815279 100644 --- a/Runtime/World/CStateMachine.hpp +++ b/Runtime/World/CStateMachine.hpp @@ -35,6 +35,7 @@ public: class CAiState { + friend class CStateMachineState; CAiStateFunc x0_func; const char* x4_name; u32 x8_; @@ -77,11 +78,13 @@ public: class CStateMachineState { + friend class CPatterned; const CStateMachine* x0_machine = nullptr; CAiState* x4_state = nullptr; float x8_time = 0.f; - float xc_ = 0.f; + float xc_random = 0.f; float x10_ = 0.f; + float x14_; union { struct @@ -93,7 +96,7 @@ class CStateMachineState public: CStateMachineState()=default; - void GetActorState() const; + CAiState* GetActorState() const { return x4_state; } float GetTime() const; void Update(CStateManager& mgr, CAi& ai, float delta) @@ -108,8 +111,15 @@ public: void Setup(const CStateMachine* machine); std::string GetName() const; void SetDelay(float); - void GetRandom() const; + float GetRandom() const { return xc_random; } float GetDelay() const; + + u32 sub8007FB9C() const + { + if (x4_state) + return x4_state->xc_; + return 0; + } }; CFactoryFnReturn FAiFiniteStateMachineFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms,