#ifndef _SEQUENCER_ACTION_HPP #define _SEQUENCER_ACTION_HPP //----------------------------------------------------------------------------- // Copyright (C) 2001 Radical Entertainment Ltd. All rights reserved. // // action.hpp // // Description: An atomic unit of execution in the Sequencer, the Action class // is the base class for all logical actions that operate on // a character for movement and animation. // // Modification History: // + Created Aug 14, 2001 -- Gary Keong // - Snapshot from Hair Club (rev 1) Owner: Laurent Ancessi //----------------------------------------------------------------------------- //--------------------------------------------------------------------- // Includes //--------------------------------------------------------------------- //======================================== // Nested Includes //======================================== #include #include #include #include #include #include #include #include #include #include class tName; class Action: public Task { public: virtual ~Action(); virtual bool IsSlave() const; virtual void WakeUp(float time); virtual void DoSimulation(float time); virtual void Update(float time); virtual void Clear(); virtual void Abort() {}; // Pool allocators. // static void* operator new( size_t size ) { void *memPtr = sMemoryPool.Allocate( size ); #ifdef RADLOAD_HEAP_DEBUGGING radLoadHeapDebugAddAddress( memPtr ); #endif return memPtr; } static void operator delete( void* deadObject, size_t size ) { sMemoryPool.Free( deadObject, size ); //This is done in the radObject... //#ifdef RADLOAD_HEAP_DEBUGGING // radLoadHeapDebugRemoveAddress( deadObject ); //#endif } // Declared but not defined to prevent access. static void* operator new[]( size_t size ); static void operator delete[]( void* pMemory ); private: static FBMemoryPool sMemoryPool; }; class SlaveAction: public Action { public: virtual bool IsSlave() const; }; namespace choreo { class AnimationDriver; class RootTransformController; class RootDriver; class Locomotion; class LocomotionDriver; } class TriggerEventAction : public Action { public: TriggerEventAction( EventEnum eventId, void* pUserData ) : mEventId( eventId ), mpUserData( pUserData ) { } virtual void WakeUp( float timeins ) { GetEventManager()->TriggerEvent( mEventId, mpUserData ); Done( ); } private: EventEnum mEventId; void* mpUserData; }; class DelayAction : public Action { public: DelayAction( float timeins ) : mTime( timeins) { } virtual void Update( float timeins ) { mTime -= timeins; if(mTime <= 0.0f) { Done( ); } } private: float mTime; }; ////////////////////////////////////////////////////////////////////////// // // class WalkerLocomotionAction // // ////////////////////////////////////////////////////////////////////////// class WalkerLocomotionAction : public SlaveAction { public: WalkerLocomotionAction( Character* pCharacter ); ~WalkerLocomotionAction( ); virtual void WakeUp( float timeins ); virtual void DoSimulation( float timeins); virtual void Update( float timeins); void PlayDriver(void); void StopDriver(void); void SetDesiredSpeed( float fSpeed ) { mfDesiredSpeed = fSpeed; } void SwitchLocomotion(void); choreo::LocomotionDriver* GetDriver(void) { return mpLocomotionDriver;} void AllowIdle(bool b) { mAllowIdle = b; } protected: static rmt::Randomizer sRandom; static bool sRandomSeeded; float SolveActualDir( float fDesiredDir, float timeins ); float SolveActualSpeed( float fDesiredSpeed, float timeins ); float mfDesiredSpeed; float mIdleTime; float mNextIdle; bool mAllowIdle : 1; Character* mpCharacter; choreo::Locomotion* mpLocomotion; choreo::LocomotionDriver* mpLocomotionDriver; }; ////////////////////////////////////////////////////////////////////////// class InCarAction : public Action { public: InCarAction( Character* pCharacter ); ~InCarAction( ); virtual void WakeUp( float timeins ); virtual void DoSimulation( float timeins); virtual void Update( float timeins); virtual void Clear( void ); protected: void IWannaRock(bool); Character* mpCharacter; choreo::AnimationDriver* mpAnimationDriver; bool mIsDriver : 1; bool rockinIsMyBusiness : 1; float timeBetweenBeats; float timeSinceLastBeat; float lastBeatValue; float mIdleTime; }; ////////////////////////////////////////////////////////////////////////// class HoldAnimationAction : public Action { public: HoldAnimationAction( Character* pCharacter, const char* animName, float holdFrame); ~HoldAnimationAction( ); virtual void WakeUp( float timeins ); virtual void DoSimulation( float timeins); virtual void Update( float timeins); virtual void Clear( void ); protected: virtual bool ShouldRelease(void) = 0; Character* mpCharacter; tUID mAnimUID; choreo::AnimationDriver* mpAnimationDriver; float mHoldFrame; float mOrigFrames; }; class SteerAction : public HoldAnimationAction { public: SteerAction( Character* pCharacter, const char* anim, float frame); protected: virtual bool ShouldRelease(void); }; class ReverseAction : public HoldAnimationAction { public: ReverseAction( Character* pCharacter, const char* anim, float frame); protected: virtual bool ShouldRelease(void); float mRelease; }; class AccelAction : public HoldAnimationAction { public: AccelAction( Character* pCharacter, const char* anim, float frame); protected: virtual bool ShouldRelease(void); }; class DecelAction : public HoldAnimationAction { public: DecelAction( Character* pCharacter, const char* anim, float frame); protected: virtual bool ShouldRelease(void); }; ////////////////////////////////////////////////////////////////////////// // // class JumpAction // // ////////////////////////////////////////////////////////////////////////// class JumpAction : public Action { public: JumpAction( Character* pCharacter, const char* name, float fUpVelocity ); virtual ~JumpAction( void ); enum eJumpState { NoTranslate = 1 << 16, InitJump, PostTurboJumpRecover, IdleJump, AllowTranslate = 1 << 17, PreJump, Jump, PostJump, JumpDone }; virtual void WakeUp( float timeins ); float Reset( float fJumpHeight, bool bFalling = false ); void Reset( const rmt::Vector& jumpTarget, bool bFalling = false ); virtual void DoSimulation( float timeins ); virtual void Update( float timeins ); void TestForJumpAgain( const rmt::Vector& currentPos, float fUpVelocity, rmt::Vector& groundPos ); virtual void Clear( ); void SetRootTransform( void ); void SetRootPosition( const rmt::Vector& position ); bool IsInJump( void ) { return mJumpState == Jump // if we are in the PreJump state with no animation, // then we are as good as jumping. // had to do it for the launching platforms. // Bounce. // || ( mJumpState == PreJump && mpAnimationDriver == 0 ) || ( mJumpState == PreJump && mbJumpAgain ); } bool IsJumpState( eJumpState state ) { return ( state == mJumpState ); } const rmt::Vector& GetJumpVelocity( void ) const { return mVelocity; } float GetGravity( void ) const { return mfGravity; } protected: void SetJumpVelocity( float fVelocity ) { mVelocity.y = fVelocity; } float SolveActualDir( float fDesiredDir, float timeins ); float SolveActualSpeed( float fDesiredSpeed, float timeins ); private: Character* mpCharacter; eJumpState mJumpState; rmt::Vector mVelocity; tUID mAnimUid; float mfTime; float mfGravity; float mfStartHeight; float mfJumpHeight; float mfMaxSpeed; choreo::AnimationDriver* mpAnimationDriver; choreo::RootTransformController* mpRootController; choreo::RootDriver* mpRootDriver; bool mbBoost : 1; bool mbFalling : 1; bool mbJumpAgain : 1; bool mbTurboJump : 1; bool mbInJumpKick : 1; bool mbDoJumpKick : 1; bool mbSlam : 1; bool mbPreSlam : 1; }; ////////////////////////////////////////////////////////////////////////// // // class DodgeAction // // ////////////////////////////////////////////////////////////////////////// class DodgeAction : public Action { public: DodgeAction( Character* pCharacter ); virtual void WakeUp( float timeins ); virtual void DoSimulation( float timeins); virtual void Update( float timeins); virtual void Clear(); protected: float SolveActualDir( float fDesiredDir, float timeins ); float SolveActualSpeed( float fDesiredSpeed, float timeins ); choreo::AnimationDriver* mpAnimationDriver; // stores handle for dodge animation Character* mpCharacter; }; ////////////////////////////////////////////////////////////////////////// // // class CringeAction // // ////////////////////////////////////////////////////////////////////////// class CringeAction : public Action { public: CringeAction( Character* pCharacter ); virtual void WakeUp( float timeins ); virtual void DoSimulation( float timeins); virtual void Update( float timeins); virtual void Clear(); protected: float SolveActualDir( float fDesiredDir, float timeins ); float SolveActualSpeed( float fDesiredSpeed, float timeins ); choreo::AnimationDriver* mpAnimationDriver; // stores handle for dodge animation Character* mpCharacter; }; ////////////////////////////////////////////////////////////////////////// // // class FlailAction // // ////////////////////////////////////////////////////////////////////////// class FlailAction : public Action { public: FlailAction( Character* pCharacter ); virtual void WakeUp( float timeins ); virtual void DoSimulation( float timeins); virtual void Update( float timeins); virtual void Clear(); protected: float SolveActualDir( float fDesiredDir, float timeins ); float SolveActualSpeed( float fDesiredSpeed, float timeins ); choreo::AnimationDriver* mpAnimationDriver; // stores handle for dodge animation Character* mpCharacter; }; ////////////////////////////////////////////////////////////////////////// // // class GetUpAction // // ////////////////////////////////////////////////////////////////////////// class GetUpAction : public Action { public: GetUpAction( Character* pCharacter ); virtual void WakeUp( float timeins ); virtual void DoSimulation( float timeins); virtual void Update( float timeins); virtual void Clear(); protected: float SolveActualDir( float fDesiredDir, float timeins ); float SolveActualSpeed( float fDesiredSpeed, float timeins ); choreo::AnimationDriver* mpAnimationDriver; // stores handle for dodge animation Character* mpCharacter; }; ////////////////////////////////////////////////////////////////////////// // // class PlayAnimationAction // // ////////////////////////////////////////////////////////////////////////// class PlayAnimationAction: public Action { public: PlayAnimationAction( Character* pCharacter, const char* anim, float fFrameRate = 30.0f ); PlayAnimationAction( Character* pCharacter, const tName& anim, float fFrameRate = 30.0f ); virtual void WakeUp( float timeins ); virtual void DoSimulation( float timeins ); virtual void Update( float timeins ); virtual void Clear( void ); void AbortWhenMovementOccurs( bool abort ); void SetLoop(bool b) { loop = b;} private: PlayAnimationAction( void ); protected: virtual bool ShouldAbort(void); Character* mpCharacter; tUID mAnimUID; float mfFrameRate; choreo::AnimationDriver* mpAnimationDriver; bool mbAbortWhenMovementOccurs : 1; bool loop : 1; }; ////////////////////////////////////////////////////////////////////////// // // class PlayIdleAnimationAction // // ////////////////////////////////////////////////////////////////////////// class PlayIdleAnimationAction: public PlayAnimationAction { public: PlayIdleAnimationAction( Character* pCharacter, const char* anim, float fFrameRate = 30.0f ); PlayIdleAnimationAction( Character* pCharacter, const tName& anim, float fFrameRate = 30.0f ); virtual void WakeUp( float timeins ); virtual void Clear( void ); virtual void Abort( void ); private: PlayIdleAnimationAction( void ); protected: }; ////////////////////////////////////////////////////////////////////////// // // class CarDoorAction // // Action for opening and closing car doors // ////////////////////////////////////////////////////////////////////////// class Sequencer; class CarDoorAction: public Action { public: CarDoorAction( Vehicle* vehicle, Vehicle::DoorAction, Vehicle::Door, float delay, float timeins, Character* character = NULL, Sequencer* seq = NULL); virtual void WakeUp( float timeins ); virtual void DoSimulation( float timeins ); virtual void Update( float timeins ); virtual void Clear( void ); private: CarDoorAction( void ); Vehicle* mpVehicle; Vehicle::DoorAction mAction; Vehicle::Door mDoor; float mTime; float mDelay; float mCurrentTime; Character* character; Sequencer* sequencer; }; class ReleaseDoorsAction: public Action { public: ReleaseDoorsAction( Vehicle* v ) : mVehicle(v) {}; virtual void Update( float timeins ); protected: Vehicle* mVehicle; }; ////////////////////////////////////////////////////////////////////////// // // class Arrive // // ////////////////////////////////////////////////////////////////////////// class Arrive : public Action { public: Arrive( Character* pCharacter, rmt::Vector& destination, bool strict = false ); virtual ~Arrive( void ); virtual void WakeUp( float timeins ); virtual void DoSimulation( float timeins ); virtual void Update( float timeins ); virtual void Clear( ); protected: private: Character* mpCharacter; rmt::Vector mDestination; float mfDecelTime; float mfMaxSpeed; float mEstTime; float mElapsedTime; bool mbSolveState : 1; bool mbPrevLocoMode : 1; bool mStrict : 1; }; class FragileArrive : public Arrive { public: FragileArrive( Character* pCharacter, rmt::Vector& destination, bool strict = false ) : Arrive( pCharacter, destination, strict ) {} bool IsSlave() const { return true; } }; ////////////////////////////////////////////////////////////////////////// // // class Orient // // ////////////////////////////////////////////////////////////////////////// class Orient : public Action { public: Orient( Character* pCharacter, rmt::Vector& facing ); virtual ~Orient( void ); virtual void WakeUp( float timeins ); virtual void DoSimulation( float timeins ); virtual void Update( float timeins ); protected: private: Character* mpCharacter; float mfTarget; }; ////////////////////////////////////////////////////////////////////////// // // class Position // // ////////////////////////////////////////////////////////////////////////// class Position : public Action { public: Position( Character* pCharacter, rmt::Vector& position, float fDuration, bool local = false ); virtual ~Position( void ); virtual void WakeUp( float timeins ); virtual void DoSimulation( float timeins ); virtual void Update( float timeins ); protected: private: Character* mpCharacter; rmt::Vector mDestination; float mfDuration; float mfTimeLeft; bool mLocal : 1; }; class GroundSnap : public Action { public: GroundSnap( Character* pCharacter) : mpCharacter( pCharacter ) {} virtual ~GroundSnap( void ) {} virtual void WakeUp( float timeins ); virtual void DoSimulation( float timeins ) {} virtual void Update( float timeins ) {} protected: private: Character* mpCharacter; }; ////////////////////////////////////////////////////////////////////////// // // class AssignValueToFloat // // ////////////////////////////////////////////////////////////////////////// class AssignValueToFloat : public Action { public: AssignValueToFloat( float& refFloat, float fValue ) : mRefFloat( refFloat ), mfValue( fValue ) { } virtual void WakeUp( float timeins ) { mRefFloat = mfValue; Done( ); } private: float& mRefFloat; float mfValue; }; class ChangeLocomotion : public Action { public: enum LocoType { INCAR, WALKING }; ChangeLocomotion( Character* c, LocoType type) : mpCharacter(c), mType(type) { } virtual void Update( float timeins ); private: Character* mpCharacter; LocoType mType; }; class ChangeNPCControllerState : public Action { public: ChangeNPCControllerState( Character* c, NPCController::State state) : mpCharacter(c), mState(state) { } virtual void Update( float timeins ); virtual void Abort( void ); private: Character* mpCharacter; NPCController::State mState; }; class KickAction : public SlaveAction { public: KickAction( Character* c, float contact) : mpCharacter(c), mTime(0.0f), mContact(contact) { } virtual void Update( float timeins ); private: Character* mpCharacter; float mTime; float mContact; }; class SurfAction : public PlayAnimationAction { public: SurfAction(Character*); protected: unsigned mLowCount; bool ShouldAbort(void); void Update(float); }; template class ChangeState : public Action { public: ChangeState( Character* c) : mpCharacter(c) { } virtual void Update( float timeins ) { CharacterAi::SetState( mpCharacter->GetStateManager() ); Done(); } private: Character* mpCharacter; }; #endif // HC_SEQUENCER_ACTION_HPP