#ifndef __STATEBASE_H__ #define __STATEBASE_H__ enum StateLayer { SL_Poseture = 0, SL_Action, SL_Max, }; enum ESYStateID { STATE_UNKNOWN = 0, STATE_IDLE, // 待机 STATE_ACTIONIDLE, STATE_MOUNT_IDLE, // 骑宠待机 STATE_DEATH, STATE_MOVE, // 移动 STATE_CONSTRAINT, // STATE_FALLING, //掉落 STATE_SWIMMING, //游泳 STATE_MOUNT_MOVE, // 骑宠移动 STATE_NORMAL_ATTACK, // 普通攻击 STATE_SKILL_ATTACK, // 技能攻击 STATE_MAX, }; typedef ESYStateID State; //! 挂起状态和结束状态都会导致状态转换, 但挂起状态特殊的地方在于挂起后,目标状态如果无效,则当前 //! 状态并不产生实际转换,而是保留, 直到目标状态有效时才发生转换. //! 结束状态则无视目标状态是否有效, 如果无效则自动转换到一个默认状态, 一般而言是待机状态(idle). enum EStateProcessResult { SPR_SUSPEND = 0, // 挂起状态 SPR_HOLD, // 保持状态 SPR_END, // 正常结束 }; struct IStateActor; struct IStateProxy { // 返回关联的状态. virtual State GetState() const = 0; virtual BOOL CanTransite(IStateActor* Owner, DWORD CurTime, State ToState) = 0; virtual BOOL Start(IStateActor* Owner, DWORD CurTime) = 0; virtual EStateProcessResult Process(IStateActor* Owner, float fTime, float fDelta) = 0; virtual State End(IStateActor* Owner, DWORD CurTime) = 0; virtual StateLayer GetLayer() = 0; virtual char* GetStateDesc() = 0; //class IStateActor* m_pOwner; }; #define PROXY_INSTANCE(Cls) \ public: \ static IStateProxy* Instance() { static Cls proxy; return &proxy;} \ private: \ struct StateAction { UINT EventID; // 动作编码 DWORD Time; // 动作时刻 }; class StateUserData : public NiMemObject { public: inline StateUserData() { } virtual ~StateUserData(){} //IStateProxy* m_pState; }; // NOTE: struct IStateActor { //virtual State GetCurState() = 0; //virtual State GetNextState() = 0; //virtual IStateProxy* GetCurStateProxy() = 0; // 设置下一个状态, 没有SetCurState这样的接口, 因为状态之间是否可以过度,何时过渡目前尚不可知, // 只允许设置下一个理想的状态, 并交由状态代理来进行处理. virtual BOOL SetNextState(State NextState, DWORD Time) = 0; // 强制地立即转换状态. 上面已经提过, 是不允许设置当前状态的, SetNextState 后,当前状态可能 // 会继续维持一段时间, 结束后NextState才会激活, 并转为当前状态. 这里会有一定的合理的时间延迟. // 如果需要的是一个立即的转换, 可以考虑ForceStateChange, 但前提是你必须事先设置好需要转换到的 // 目标状态, 这个函数的执行会无视状态间是否可以转换, 也不会考虑状态的滞留时间. virtual IStateProxy* ForceStateChange(State NextState, DWORD Time) = 0; // 清空动作队列 virtual void ClearActionQueue() = 0; virtual BOOL ProcessAction(const StateAction* Action) = 0; virtual void PushAction(const StateAction* QueueAction) = 0; virtual BOOL ProcessNextAction() = 0; virtual INT GetNumQueueAction() = 0; virtual void UpdateState(float fTime, float fDelta) = 0; // 检查角色是否有效 virtual BOOL IsStateActorActive() = 0; inline StateUserData* GetStateUserData() { return m_pStateData; } inline void SetStateUserData(StateUserData* pStateData) { ClearStateUserData(); m_pStateData = pStateData; } inline void ClearStateUserData() { if (m_pStateData) { NiDelete m_pStateData; m_pStateData = NULL; } } protected: StateUserData* m_pStateData; }; #endif