#pragma once // 将本地玩家的操作封装在这个对象中, 减少Player 的复杂度. #include "State/SYStateBase.h" #include "SKIll/SkillInfo.h" #include "ui/UISystem.h" #define INVALID_OBJECTID SYObjID(0) class CCharacter; class CPlayer; class CGameObject; class CCreature; class CSceneGameObj; class CHookMgr; enum EPlayerInputEventType { PIE_WALK = 0, PIE_RUN, PIE_JUMP, PIE_ATTACK, PIE_RETARGET, PIE_TRIGETARGET, }; struct Key { enum { UP = 0, DOWN, }; unsigned int mkeycode; int mstate; int bistate; void Init(unsigned int keycode, int state) { mkeycode = keycode; mstate = state; } bool Compare(unsigned int keycode) { return bool(mkeycode == keycode); } unsigned int GetCode() { return mkeycode; } void SetState(int state) { mstate = state; } int GetState() { return mstate; } }; const static float SKILL_SELECT_RANGE_MAX = 26.0f; class CPlayerInputMgr { enum KeyboardMoveState { KMD_W = 0x01, KMD_S = 0x02, KMD_A = 0x04, KMD_D = 0x08, KMD_Q = 0x10, KMD_E = 0x20, KMD_SPACE = 0x40, KMD_G = 0x80, KMD_TAB = 0x100, }; enum { DBL_CLICK_DELTA = 1000, // 100 MS 内点击算做双击. ACTION_MAX = 8, }; public: CPlayerInputMgr(void); virtual ~CPlayerInputMgr(void); BOOL Initialize(); void Shutdown(); void Update(DWORD dt); bool UpdateMoveKeys(); bool IsInMoveKeys(DWORD DIK); void ResetMoveKeys(){ for(uint32 i = 0; i < 9; i++) { m_movekeys[i].SetState( UNIInputKey::UP ); } } void OnInputMessage(DWORD dt); BOOL BeginSkillAttack(SpellID spellid); BOOL CanUseSkill(SpellID spellid); BOOL UseSkillShanXian(float radius, BOOL isShanXian01 = TRUE); BOOL CheckSkillShanXian(float& radius, BOOL isShanXian01 = TRUE); void SelectTarget(INT SelFlag, INT SelAreaFlag, SpellID spellid, float fRadius, const char* Brush, float fBrushHeight = 0.05f); void SelectItem( SpellID spellid ); // 锁定移动 void LockInput(); void UnlockInput(); void ClearInput(); inline void LockMove() { NIASSERT(m_iLockMC >= 0); m_iLockMC++; } inline void UnlockMove() { m_iLockMC--; NIASSERT(m_iLockMC >= 0); } inline BOOL IsMoveLocked() const { if( m_iLockMC > 0 ) return true; /*else if( m_force_root ) return true;*/ else return false; } inline void LockAttack() { NIASSERT(m_iLockAC >= 0); m_iLockAC++; } inline void UnlockAttack() { m_iLockAC--; NIASSERT(m_iLockAC >= 0); } inline BOOL IsAttackLocked() const { return (m_iLockAC > 0?TRUE:FALSE); } BOOL CanDoAttackAction(const SpellID& spellid) const; SYObjID GetTargetObjectID() { return m_TargetObjectID; } inline void ForceRoot() { m_force_root = true; } inline void ForceUnRoot() { m_force_root = false; } inline bool IsForceRoot() const { return m_force_root; } // 输入事件队列处理 void ClearQueueAction(); BOOL LBClick(); BOOL LBDblClick(); BOOL RBDblClick(); BOOL RBClick(); void MouseMove(); void OnRightMouseDown(const POINT& position, UINT nRepCnt, UINT flags); void OnMouseDown(const POINT& point, UINT nRepCnt, UINT uFlags); void OnMouseUp(const POINT& position, UINT flags); void OnMouseOBJ(float ftime); void OnMouseMove(const POINT& position, UINT flags); POINT GetCurMousePoint(); BOOL GetRayFormMousePoint(const POINT& pt, const NiCamera* pkCamera, NiPoint3& ptOrig, NiPoint3& vDir); CGameObject* PickObject(const POINT& kScreenP, NiPoint3& ptPickPos, bool bFirst = false, bool bLoot = false, int weight = 1); CGameObject* PickObject(const NiPoint3& ptOrig, const NiPoint3& vDir, NiPoint3& ptPickPos); BOOL PickGround(const NiPoint3& ptOrig, const NiPoint3& vDir, NiPoint3& ptTarget); CGameObject* GetLastTargetObject(); void CommitMoveEvt(); BOOL KeyDown(UINT nKeyCode); BOOL KeyUp(UINT nKeyCode); BOOL OnEscape(); BOOL Action_ClickTarget(CGameObject* pTargetObj); bool IsSelectingTarget() const; bool IsSelectingItem() const; BOOL HilightSelectTarget(NiPoint3 dest, float radius); BOOL EndHilight(); void EndSelectTarget(); void EndSelectItem(); SYObjID HookAutoSelectCreature(ui64 guid,BOOL selDeadOBJ = TRUE); BOOL OnSkillToItemAction( const SpellCastTargets& target ); protected: // Input Rule BOOL LBContinueDown(); BOOL OnLocationSkillAction(SpellID spellid, const SpellCastTargets& target); BOOL OnSkillAction(SYObjID id, SpellID spellid, const SpellCastTargets &target, bool bMoveTo = true); BOOL OnSkillAction(CCharacter* pkChar, SpellID spellid, const SpellCastTargets& target, bool bMoveTo = true); bool isInFront(CCharacter* attcker, CCharacter* target); BOOL OnAttackAction(CCharacter* pkChar); void ProcessSpellLocationSelect(const NiPoint3& kRayStart, const NiPoint3& kRayDir); // Input Event BOOL OnSelectPlayer(CPlayer* Char); BOOL OnSelectSceneObj(CSceneGameObj* pkGameObj); BOOL OnSelectPos(const NiPoint3& WorldPos); BOOL OnSelectCreature(CCreature* pkCreature); BOOL OnRequirePlayer(CPlayer* pkPlayer); BOOL OnRequireCreature(CCreature* pkCreature); //右击怪物的操作. 这里暂时用来调用显示怪物尸体上爆出来的装备. BOOL OnRequireSceneObject(CSceneGameObj* pkSceneObj); //作场景采集用! void AutoCancelProcess(); SYObjID AutoSelectCreature(); int GetFaction(SYObjID uiTargetID); BOOL SetSelectScenceOBJ(SYObjID uiScenceOBjID); public: void SetTargetID(SYObjID uiTargetID, bool bAttack=false); SYObjID GetTargetID(); inline void SetUseMouseToMove( BOOL bUseMouseToMove){ m_bUseMouseToMove = bUseMouseToMove;} inline BOOL IsUseMouseMove(){ return m_bUseMouseToMove;} void SetDecal(SYObjID uiTargetID); class DecalEffect* GetDecalEffect() { return m_pkDecal; } bool GetAutoAction(){ return m_bAutoAction;} void SetAutoAction( bool isAuto ){ m_bAutoAction = isAuto; } void SetSwingTargetID(SYObjID uiId); void SetSelectItemInfo(float SpellRadius, ui8 bag, ui8 slot); private: void UpdateTarget(DWORD Time); void PostUpdateTarget(DWORD dwTime); void UpdatePick(); void UpdateDecal(); //刷新DECAL 红色和绿色之间过渡问题 void ProcessTarget(); BOOL MoveToActionPos(const NiPoint3& ActionPos, UINT flag); BOOL MoveToActionTarget(const SYObjID& ActionTarget, float fRange, UINT flag); BOOL ProcessNextAction(); BOOL ProcessNextSkillAttack(DWORD ActionTime); BOOL ProcessPickItem(DWORD ActionTime); private: struct PlayerInputEvent { EPlayerInputEventType EventType; // 事件ID DWORD Time; // 时间 }; void FlushInputEventList(); protected: DWORD m_LastUpdateTime; // 上次更新时间. float m_MoveOBJUpdate ; BOOL m_LastLBClick; // 上次是否存在点击. int m_LBClickCnt; // 鼠标连击次数. 时间间隔 : DBL_CLICK_DELTA BOOL m_CurLeftBtnDown; // 当前鼠标左键是否按下 BOOL m_LastLeftBtnDown; // 上一帧鼠标左键是否按下 DWORD m_LastMouseDownTime; // 上一次鼠标按下时间(MS) BOOL m_CurRightBtnDown; // 当前鼠标右键是否按下 BOOL m_LastRightBtnDown; BOOL m_bClearnQueueAction; bool m_bAutoCancelProcess; bool m_force_root; private: SYStateAction m_NextAction; UINT m_KeyboardMoveState; SYObjID m_TargetObjectID; SYObjID m_SwingId; SYObjID m_LastTargetID; bool m_bLastFriendCheck; std::vector m_pkSelectLocationObj; class DecalEffect* m_pkDecal; class DecalEffect* m_pkSelScenceObj; class DecalEffect* m_pkSelectLocation; class CSceneEffect* m_pkFlag; SpellID m_LocationSelSpellID; bool m_bSpellLocationSelect; SpellID m_ItemSelSpellID; bool m_bSpellItemSelect; float m_fSpellMaxRadius; struct ItemSelectInfo { bool bSelectByItem; ui8 bag; ui8 slot; }m_ItemSelectInfo; int m_iLockMC; int m_iLockAC; bool m_bAutoAction; BOOL m_bUseMouseToMove; UNIInputKey m_movekeys[9]; CSceneEffect* m_pMouseEffect; };