#ifndef _CPATTERNED #define _CPATTERNED #include "types.h" #include "MetroidPrime/CSteeringBehaviors.hpp" #include "MetroidPrime/Enemies/CAi.hpp" #include "MetroidPrime/Enemies/CPatternedInfo.hpp" #include "MetroidPrime/Enemies/CStateMachine.hpp" class CBodyController; class CVertexMorphEffect; class CGenDescription; class CElectricDescription; class CPathFindSearch; class CProjectileInfo; template < typename T > struct TPatternedCast { CEntity* ent; TPatternedCast(CEntity* ent); }; class CPatterned : public CAi { public: enum ECharacter { kC_AtomicAlpha = 0, kC_AtomicBeta = 1, kC_Babygoth = 2, kC_Beetle = 3, kC_BloodFlower = 4, kC_Burrower = 5, kC_ChozoGhost = 6, kC_Drone = 7, kC_ElitePirate = 8, kC_EyeBall = 9, kC_FireFlea = 10, kC_Flaahgra = 11, kC_FlaahgraTentacle = 12, kC_FlickerBat = 13, kC_FlyingPirate = 14, kC_IceSheegoth = 15, kC_JellyZap = 16, kC_Magdolite = 17, kC_Metaree = 18, kC_Metroid = 19, kC_MetroidBeta = 20, kC_MetroidPrimeExo = 21, kC_MetroidPrimeEssence = 22, kC_NewIntroBoss = 23, kC_Parasite = 24, kC_PuddleSpore = 27, kC_PuddleToad = 28, kC_Puffer = 29, kC_Ridley = 30, kC_Ripper = 31, kC_Seedling = 32, kC_SpacePirate = 34, kC_SpankWeed = 35, kC_PhazonHealingNodule = 35, kC_Thardus = 36, kC_ThardusRockProjectile = 37, kC_Tryclops = 38, kC_WarWasp = 39, kC_EnergyBall = 40 }; enum EFlavorType { kFT_Zero = 0, kFT_One = 1, kFT_Two = 2, }; enum EMovementType { kMT_Ground = 0, kMT_Flyer = 1, }; enum EColliderType { kCT_Zero = 0, kCT_One = 1, }; enum EPatrolState { kPS_Invalid = -1, kPS_Patrol, kPS_Pause, kPS_Done, }; enum EBehaviour { kB_Zero, }; enum EBehaviourOrient { kBO_MoveDir, kBO_Constant, kBO_Destination, }; enum EBehaviourModifiers { kBM_Zero, }; enum EAnimState { kAS_Invalid = -1, kAS_NotReady, kAS_Ready, kAS_Repeat, kAS_Over, }; enum EPatternTranslate { kPT_RelativeStart, kPT_RelativePlayerStart, kPT_RelativePlayer, kPT_Absolute, }; enum EPatternOrient { kPO_StartToPlayer, kPO_StartToPlayerStart, kPO_ReversePlayerForward, kPO_Forward, }; enum EPatternFit { kPF_Zero, kPF_One, }; enum EMoveState { kMS_Zero, kMS_One, kMS_Two, kMS_Three, kMS_Four, }; class CPatternNode { CVector3f x0_pos; CVector3f xc_forward; float x18_speed; uchar x1c_behaviour; uchar x1d_behaviourOrient; ushort x1e_behaviourModifiers; uint x20_animation; public: CPatternNode(const CVector3f& pos, const CVector3f& forward, float speed, uint behaviour, uint behaviourOrient, uint behaviourModifiers, uint animation); const CVector3f& GetPos() const { return x0_pos; } const CVector3f& GetForward() const { return xc_forward; } float GetSpeed() const { return x18_speed; } uchar GetBehaviour() const { return x1c_behaviour; } uchar GetBehaviourOrient() const { return x1d_behaviourOrient; } ushort GetBehaviourModifiers() const { return x1e_behaviourModifiers; } }; CPatterned(ECharacter character, TUniqueId uid, const rstl::string& name, EFlavorType flavor, const CEntityInfo& info, const CTransform4f& xf, const CModelData& mData, const CPatternedInfo& pinfo, EMovementType movement, EColliderType collider, EBodyType body, const CActorParameters& params, EKnockBackVariant kbVariant); // CEntity ~CPatterned() override; void Accept(IVisitor& visitor) override; void PreThink(float dt, CStateManager& mgr) override; void Think(float dt, CStateManager& mgr) override; void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; // CActor void PreRender(CStateManager&, const CFrustumPlanes&) override; void AddToRenderer(const CFrustumPlanes&, const CStateManager&) const override; void Render(const CStateManager&) const override; bool CanRenderUnsorted(const CStateManager&) const override; rstl::optional_object< CAABox > GetTouchBounds() const override; void Touch(CActor&, CStateManager&) override; CVector3f GetOrbitPosition(const CStateManager&) const override; CVector3f GetAimPosition(const CStateManager&, float) const override; EWeaponCollisionResponseTypes GetCollisionResponseType(const CVector3f&, const CVector3f&, const CWeaponMode&, int /*EProjectileAttrib?*/) const override; void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) override; // CPhysicsActor void CollidedWith(const TUniqueId& id, const CCollisionInfoList& list, CStateManager& mgr) override; // CAi void Death(CStateManager& mgr, const CVector3f& direction, EScriptObjectState state) override; void KnockBack(const CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType type, bool inDeferred, float magnitude) override; void TakeDamage(const CVector3f& direction, float magnitude) override; void Patrol(CStateManager&, EStateMsg, float) override; void FollowPattern(CStateManager&, EStateMsg, float) override; void Dead(CStateManager&, EStateMsg, float) override; void PathFind(CStateManager&, EStateMsg, float) override; void Start(CStateManager&, EStateMsg, float) override; void TargetPatrol(CStateManager&, EStateMsg, float) override; void TargetPlayer(CStateManager&, EStateMsg, float) override; bool Leash(CStateManager&, float) override; bool OffLine(CStateManager&, float) override; bool Attacked(CStateManager&, float) override; bool PathShagged(CStateManager&, float) override; bool PathOver(CStateManager&, float) override; bool PathFound(CStateManager&, float) override; bool TooClose(CStateManager&, float) override; bool InRange(CStateManager&, float) override; bool InMaxRange(CStateManager&, float) override; bool InDetectionRange(CStateManager&, float) override; bool SpotPlayer(CStateManager&, float) override; bool PlayerSpot(CStateManager&, float) override; bool PatternOver(CStateManager&, float) override; bool PatternShagged(CStateManager&, float) override; bool HasAttackPattern(CStateManager&, float) override; bool HasPatrolPath(CStateManager&, float) override; bool HasRetreatPattern(CStateManager&, float) override; bool Delay(CStateManager&, float) override; bool RandomDelay(CStateManager&, float) override; bool FixedDelay(CStateManager&, float) override; bool Default(CStateManager&, float) override; bool AnimOver(CStateManager&, float) override; bool InPosition(CStateManager&, float) override; bool Stuck(CStateManager&, float) override; bool NoPathNodes(CStateManager&, float) override; bool Landed(CStateManager&, float) override; bool PatrolPathOver(CStateManager&, float) override; bool CodeTrigger(CStateManager&, float) override; bool Random(CStateManager&, float) override; bool FixedRandom(CStateManager&, float) override; // CPatterned virtual void Freeze(CStateManager& mgr, const CVector3f& pos, const CUnitVector3f& dir, float frozenDur); virtual bool KnockbackWhenFrozen() const { return true; } virtual void MassiveDeath(CStateManager& mgr); virtual void MassiveFrozenDeath(CStateManager& mgr); virtual void Burn(float duration, float damage); virtual void Shock(CStateManager& mgr, float duration, float damage); virtual void ThinkAboutMove(float); virtual CPathFindSearch* GetSearchPath() { return nullptr; } virtual CDamageInfo GetContactDamage() const { return x404_contactDamage; } virtual u8 GetModelAlphau8(const CStateManager&) const { return x42c_color.GetAlphau8(); } virtual bool IsOnGround() const { return x328_27_onGround; } virtual float GetGravityConstant() const { return CPhysicsActor::GravityConstant(); } virtual CProjectileInfo* ProjectileInfo() { return nullptr; } virtual void PhazeOut(CStateManager&); virtual const rstl::optional_object< TLockedToken< CGenDescription > >& GetDeathExplosionParticle() const { return x520_deathExplosionParticle; } void DeathDelete(CStateManager& mgr); CTransform4f GetLctrTransform(const rstl::string&) const; TUniqueId GetDestObj() const { return x2dc_destObj; } // TODO: name? CStateMachineState& StateMachineState() { return x330_stateMachineState; } const CStateMachineState& GetStateMachineState() const { return x330_stateMachineState; } ECharacter GetCharacterType() const { return x34c_characterType; } bool IsAlive() const { return x400_25_alive; } void SetWasHit(bool v) { x400_24_hitByPlayerProjectile = v; } void SetPendingDeath(bool v) { x401_30_pendingDeath = v; } CBodyController* BodyCtrl() { return x450_bodyController.get(); } const CBodyController* GetBodyCtrl() const { return x450_bodyController.get(); } CKnockBackController& GetKnockBackCtrl() { return x460_knockBackController; } const CKnockBackController& GetKnockBackCtrl() const { return x460_knockBackController; } template < class T > static T* CastTo(const TPatternedCast< T >& ent); private: EPatrolState x2d8_patrolState; TUniqueId x2dc_destObj; CVector3f x2e0_destPos; CVector3f x2ec_reflectedDestPos; float x2f8_waypointPauseRemTime; float x2fc_minAttackRange; float x300_maxAttackRange; float x304_averageAttackTime; float x308_attackTimeVariation; EBehaviourOrient x30c_behaviourOrient; CVector3f x310_moveVec; CVector3f x31c_faceVec; bool x328_24_inPosition : 1; bool x328_25_verticalMovement : 1; bool x328_26_solidCollision : 1; bool x328_27_onGround : 1; bool x328_28_prevOnGround : 1; bool x328_29_noPatternShagging : 1; bool x328_30_lookAtDeathDir : 1; bool x328_31_energyAttractor : 1; bool x329_24_ : 1; EAnimState x32c_animState; CStateMachineState x330_stateMachineState; ECharacter x34c_characterType; CVector3f x350_patternStartPos; CVector3f x35c_patternStartPlayerPos; CVector3f x368_destWPDelta; EPatternTranslate x374_patternTranslate; EPatternOrient x378_patternOrient; EPatternFit x37c_patternFit; EBehaviour x380_behaviour; EBehaviourModifiers x384_behaviourModifiers; int x388_anim; rstl::vector< CPatternNode > x38c_patterns; uint x39c_curPattern; CVector3f x3a0_latestLeashPosition; TUniqueId x3ac_lastPatrolDest; float x3b0_moveSpeed; float x3b4_speed; float x3b8_turnSpeed; float x3bc_detectionRange; float x3c0_detectionHeightRange; float x3c4_detectionAngle; float x3c8_leashRadius; float x3cc_playerLeashRadius; float x3d0_playerLeashTime; float x3d4_curPlayerLeashTime; float x3d8_xDamageThreshold; float x3dc_frozenXDamageThreshold; float x3e0_xDamageDelay; float x3e4_lastHP; float x3e8_alphaDelta; float x3ec_pendingFireDamage; float x3f0_pendingShockDamage; float x3f4_burnThinkRateTimer; EMoveState x3f8_moveState; EFlavorType x3fc_flavor; uint x400_24_hitByPlayerProjectile : 1; uint x400_25_alive : 1; uint x400_26_ : 1; uint x400_27_fadeToDeath : 1; uint x400_28_pendingMassiveDeath : 1; uint x400_29_pendingMassiveFrozenDeath : 1; uint x400_30_patternShagged : 1; uint x400_31_isFlyer : 1; uint x401_24_pathOverCount : 2; uint x401_26_disableMove : 1; uint x401_27_phazingOut : 1; uint x401_28_burning : 1; uint x401_29_laggedBurnDeath : 1; uint x401_30_pendingDeath : 1; uint x401_31_nextPendingShock : 1; uint x402_24_pendingShock : 1; uint x402_25_lostMassiveFrozenHP : 1; uint x402_26_dieIf80PercFrozen : 1; uint x402_27_noXrayModel : 1; uint x402_28_isMakingBigStrike : 1; uint x402_29_drawParticles : 1; uint x402_30_updateThermalFrozenState : 1; uint x402_31_thawed : 1; uint x403_24_keepThermalVisorState : 1; uint x403_25_enableStateMachine : 1; uint x403_26_stateControlledMassiveDeath : 1; CDamageInfo x404_contactDamage; float x420_curDamageRemTime; float x424_damageWaitTime; float x428_damageCooldownTimer; CColor x42c_color; CColor x430_damageColor; CVector3f x434_posDelta; CQuaternion x440_rotDelta; rstl::single_ptr< CBodyController > x450_bodyController; u32 x454_deathSfx; u32 x458_iceShatterSfx; CSteeringBehaviors x45c_steeringBehaviors; CKnockBackController x460_knockBackController; CVector3f x4e4_latestPredictedTranslation; float x4f0_predictedLeashTime; float x4f4_intoFreezeDur; float x4f8_outofFreezeDur; float x4fc_freezeDur; float x500_preThinkDt; float x504_damageDur; EColliderType x508_colliderType; float x50c_baseDamageMag; rstl::single_ptr< CVertexMorphEffect > x510_vertexMorph; CVector3f x514_deathExplosionOffset; rstl::optional_object< TLockedToken< CGenDescription > > x520_deathExplosionParticle; rstl::optional_object< TLockedToken< CElectricDescription > > x530_deathExplosionElectric; CVector3f x540_iceDeathExplosionOffset; rstl::optional_object< TLockedToken< CGenDescription > > x54c_iceDeathExplosionParticle; CVector3f x55c_moveScale; }; CHECK_SIZEOF(CPatterned, 0x568) #endif // _CPATTERNED