mirror of
				https://github.com/AxioDL/metaforce.git
				synced 2025-10-27 15:30:23 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			139 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "Runtime/World/CAmbientAI.hpp"
 | |
| 
 | |
| #include "Runtime/CStateManager.hpp"
 | |
| #include "Runtime/World/CPlayer.hpp"
 | |
| 
 | |
| #include "TCastTo.hpp" // Generated file, do not modify include path
 | |
| 
 | |
| namespace metaforce {
 | |
| 
 | |
| CAmbientAI::CAmbientAI(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
 | |
|                        CModelData&& mData, const zeus::CAABox& aabox, const CMaterialList& matList, float mass,
 | |
|                        const CHealthInfo& hInfo, const CDamageVulnerability& dVuln, const CActorParameters& aParms,
 | |
|                        float alertRange, float impactRange, s32 alertAnim, s32 impactAnim, bool active)
 | |
| : CPhysicsActor(uid, active, name, info, xf, std::move(mData), matList, aabox, SMoverData(mass), aParms, 0.3f, 0.1f)
 | |
| , x258_initialHealthInfo(hInfo)
 | |
| , x260_healthInfo(hInfo)
 | |
| , x268_dVuln(dVuln)
 | |
| , x2d4_alertRange(alertRange)
 | |
| , x2d8_impactRange(impactRange)
 | |
| , x2dc_defaultAnim(GetModelData()->GetAnimationData()->GetDefaultAnimation())
 | |
| , x2e0_alertAnim(alertAnim)
 | |
| , x2e4_impactAnim(impactAnim) {
 | |
|   GetModelData()->GetAnimationData()->EnableLooping(true);
 | |
| }
 | |
| 
 | |
| void CAmbientAI::Accept(IVisitor& visitor) { visitor.Visit(this); }
 | |
| 
 | |
| void CAmbientAI::Think(float dt, CStateManager& mgr) {
 | |
|   if (!GetActive())
 | |
|     return;
 | |
| 
 | |
|   if (GetModelData() && GetModelData()->GetAnimationData()) {
 | |
|     bool hasAnimTime = GetModelData()->GetAnimationData()->IsAnimTimeRemaining(dt - FLT_EPSILON, "Whole Body"sv);
 | |
|     bool isLooping = GetModelData()->GetIsLoop();
 | |
| 
 | |
|     if (hasAnimTime || isLooping) {
 | |
|       x2e8_25_animating = true;
 | |
|       SAdvancementDeltas deltas = UpdateAnimation(dt, mgr, x2e8_25_animating);
 | |
|       MoveToOR(deltas.x0_posDelta, dt);
 | |
|       RotateToOR(deltas.xc_rotDelta, dt);
 | |
|     }
 | |
| 
 | |
|     if (!hasAnimTime || (x2e8_25_animating && !isLooping)) {
 | |
|       SendScriptMsgs(EScriptObjectState::MaxReached, mgr, EScriptObjectMessage::None);
 | |
|       x2e8_25_animating = false;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   bool inAlertRange = (mgr.GetPlayer().GetTranslation() - GetTranslation()).magnitude() < x2d4_alertRange;
 | |
|   bool inImpactRange = (mgr.GetPlayer().GetTranslation() - GetTranslation()).magnitude() < x2d8_impactRange;
 | |
| 
 | |
|   switch (x2d0_animState) {
 | |
|   case EAnimationState::Ready: {
 | |
|     if (inAlertRange) {
 | |
|       x2d0_animState = EAnimationState::Alert;
 | |
|       GetModelData()->GetAnimationData()->SetAnimation(CAnimPlaybackParms(x2e0_alertAnim, -1, 1.f, true), false);
 | |
|       GetModelData()->EnableLooping(true);
 | |
|       RandomizePlaybackRate(mgr);
 | |
|     }
 | |
|     break;
 | |
|   }
 | |
|   case EAnimationState::Alert: {
 | |
|     if (!inAlertRange) {
 | |
|       x2d0_animState = EAnimationState::Ready;
 | |
|       GetModelData()->GetAnimationData()->SetAnimation(CAnimPlaybackParms(x2dc_defaultAnim, -1, 1.f, true), false);
 | |
|       GetModelData()->EnableLooping(true);
 | |
|       RandomizePlaybackRate(mgr);
 | |
|     } else if (inImpactRange) {
 | |
|       SendScriptMsgs(EScriptObjectState::Dead, mgr, EScriptObjectMessage::None);
 | |
|       SetActive(false);
 | |
|     }
 | |
|     break;
 | |
|   }
 | |
|   case EAnimationState::Impact: {
 | |
|     if (!x2e8_25_animating) {
 | |
|       x2d0_animState = EAnimationState::Ready;
 | |
|       GetModelData()->GetAnimationData()->SetAnimation(CAnimPlaybackParms(x2dc_defaultAnim, -1, 1.f, true), false);
 | |
|       GetModelData()->EnableLooping(true);
 | |
|       RandomizePlaybackRate(mgr);
 | |
|     }
 | |
|     break;
 | |
|   }
 | |
|   }
 | |
| 
 | |
|   if (!x2e8_24_dead) {
 | |
|     CHealthInfo* hInfo = HealthInfo(mgr);
 | |
|     if (hInfo->GetHP() <= 0.f) {
 | |
|       x2e8_24_dead = true;
 | |
|       SendScriptMsgs(EScriptObjectState::Dead, mgr, EScriptObjectMessage::None);
 | |
|       RemoveEmitter();
 | |
|       SetActive(false);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| void CAmbientAI::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
 | |
|   switch (msg) {
 | |
|   case EScriptObjectMessage::Reset: {
 | |
|     if (!GetActive())
 | |
|       SetActive(true);
 | |
|     x2d0_animState = EAnimationState::Ready;
 | |
|     GetModelData()->GetAnimationData()->SetAnimation(CAnimPlaybackParms(x2dc_defaultAnim, -1, 1.f, true), false);
 | |
|     GetModelData()->GetAnimationData()->EnableLooping(true);
 | |
|     RandomizePlaybackRate(mgr);
 | |
|     x2e8_24_dead = false;
 | |
|     x260_healthInfo = x258_initialHealthInfo;
 | |
|     break;
 | |
|   }
 | |
|   case EScriptObjectMessage::Damage: {
 | |
|     if (GetActive()) {
 | |
|       x2d0_animState = EAnimationState::Impact;
 | |
|       GetModelData()->GetAnimationData()->SetAnimation(CAnimPlaybackParms(x2e4_impactAnim, -1, 1.f, true), false);
 | |
|       GetModelData()->GetAnimationData()->EnableLooping(false);
 | |
|       RandomizePlaybackRate(mgr);
 | |
|     }
 | |
|     break;
 | |
|   }
 | |
|   case EScriptObjectMessage::InitializedInArea:
 | |
|     RandomizePlaybackRate(mgr);
 | |
|     break;
 | |
|   default:
 | |
|     break;
 | |
|   }
 | |
|   CPhysicsActor::AcceptScriptMsg(msg, uid, mgr);
 | |
| }
 | |
| 
 | |
| std::optional<zeus::CAABox> CAmbientAI::GetTouchBounds() const {
 | |
|   if (GetActive()) {
 | |
|     return {GetBoundingBox()};
 | |
|   }
 | |
|   return std::nullopt;
 | |
| }
 | |
| 
 | |
| void CAmbientAI::RandomizePlaybackRate(CStateManager& mgr) {
 | |
|   GetModelData()->GetAnimationData()->MultiplyPlaybackRate(0.4f * mgr.GetActiveRandom()->Float() + 0.8f);
 | |
| }
 | |
| 
 | |
| } // namespace metaforce
 |