#pragma once #include "Player.h" #include "ui/UMailSystem.h" #include "Map/ModelInstance.h" #include "Utils/MapToMapPathInfo.h" class DecalTerrain; class CSceneEffect; struct SPELL_INFO { UINT SpellId; DWORD CDRemainTimeMS; // 剩余冷却时间 DWORD CDTimeMS; // 冷却时间 BOOL bPubCD; }; //客户端的UI一些状态。 enum CUstate { cus_Normal = 0, //普通 , 除掉以下几种状态, UI都是这个状态。包括战斗,死亡,等等。 cus_Bank , //仓库 cus_Mail, //邮件 cus_Trade, //交易 cus_NPCTrade, //NPC交易 cus_NPC, //NPC交互 cus_Quest, //任务选项 cus_QuestD, // 任务D cus_Pick, cus_Auction, //拍卖行 cus_error }; struct ActiveLocalPlayerDesc { inline void ResetSpellInfo() {m_SpellInfos.clear();} inline void AddSpellInfoEntry(const SPELL_INFO& NewEntry) { m_SpellInfos.push_back(NewEntry);} inline SPELL_INFO* GetSpellInfo(UINT uSpellId) { for (int i =0; i < (int)m_SpellInfos.size(); i++) { if (m_SpellInfos[i].SpellId == uSpellId) { return &m_SpellInfos[i]; } } return NULL; } std::vector m_SpellInfos; }; // 本地玩家 class CPlayerLocal : public CPlayer { public: CPlayerLocal(void); virtual ~CPlayerLocal(void); enum EFFECT_TYPE { MOVETARGETPOINT = 0, EFFECT_MAX, }; BOOL InitMoveCollision(); void ShutdownMoveCollision(); bool IsLocalPlayer() const { return true; } static ActiveLocalPlayerDesc& GetActivePlayerDesc() { return sm_ActiveLPDesc;} void FollowPlayer(ui64 playerID); ui64 GetFollowPlayerID() const; float GetFollowResponeRange() const; DWORD GetMovementTimeStamp(); void SendMovementPacket(MoveOP eOP = MOVE_HEARTBEAT); void StartForward(bool bAutoRun = false); void StartBackward(); void StopVertical(); void StartLeft(); void StartRight(); void StopHorizontal(); void StartTurnLeft(); void StartTurnRight(); void StopTurn(); void OnJumpInputEvent(); virtual void SetFacing(float rot); virtual void OnDeath(bool bDeadNow = true); virtual void OnAlive(); virtual void OnEquipmentChanged(); void PathMoveStart(const NiPoint3& pos, UINT uiFlag); virtual void PathMoveUpdate(float fTimeDelta); void PathMoveEnd(); void UpdateNpcState(unsigned int uiQuestId, unsigned int uiQuestState); void UpdateScenOBJState(); BOOL IsNeedAddScenOBJ(ui32 ScenceOBJ_Entry, ui32 QuestID, ui32 QuestItemID); BOOL CanLookTarget( CGameObject* pTargetObj ); //判断相关 bool HasItem(ui32 ItemEntry); bool HasLearnSkill(ui32 Spellid); bool HasQuest(uint32 uiQuestId); void ResetMovementInfo(); void SetLastMovementFlags( uint32 uiFlag ) { m_uiLastMovementFlags = uiFlag; } uint32 GetLastMovementFlags() const { return m_uiLastMovementFlags; } float GetLastDesirdAngle() const { return m_fLastDesiredAngle; } void SetLastDesiredAngle(float fMoveAngle) { m_fLastDesiredAngle = fMoveAngle; } void SetLastSendMovementTime( float fTime ) { m_fLastSendMovementTime = fTime; } void SetLastFacingTime( float fTime ) { m_fLastFacingTime = fTime; } float GetLastSendMovementTime() const { return m_fLastSendMovementTime; } float GetLastFacingTime() const { return m_fLastFacingTime; } void SetSendMovementDuration( float fTime ) { m_fSendMovementDuration = fTime; } float GetSendMovementDuration() { return m_fSendMovementDuration; } // 在人物身上冒出影响数值 virtual void BubbleUpEffectNumber(int Number, int affectType = 0,ui32 subType = 0, const WCHAR* extraOutput = NULL , ui32 SubType2 = 1); void StopAttack(); virtual BOOL MoveTo(const NiPoint3& Target, UINT Flag, bool findpath = true); BOOL SetMoveToTarget(float fRange,UINT Flag); BOOL IsMoveToTarget(){return m_MoveToTarget;} void MoveToTargetUpdate(float fTimeDelta); void CheckMoveTarget(float fTimeDelta); void EndMoveToTarget(); //寻路接口 BOOL MoveToMapAStar(int MapId ,const NiPoint3& Target, UINT Flag); //寻路接口 //当前地图寻路 BOOL MoveToAStar(const NiPoint3& Target, UINT Flag); //当前地图寻路 //跨地图跳转后操作 BOOL ContinuePathMove(); //是当前地图的传送门,那么继续寻路 BOOL ContinueTraceGatePathMove(); //当前地图寻路结束后 //如果切换到下张地图传送方式是NPC. 超找之, 然后处理对话传送 //如果切换到下张地图传送方式是传送门, 到这里还没有收到传送门的传送信息, 那么出错. 停止寻路 void PathTranceBegin(); //切换到下张地图传送方式是NPC. 发送对话选项,进行传送 void SendTranceBegin(ui64 guid);//获得NPC对话后,发送传送选项 //碰到传送门后, 切换到下张地图传送方式是否是传送门, 如果不是, //尝试本地图传送 void PathTraceGateBegin(ui32 Gateid);//碰到了传送门 virtual void StopMove(); virtual void MoveTo(); virtual NiControllerSequence* SetCurAnimation(AnimationID Anim, float Frequence = 1.0f, BOOL bLoop = FALSE, BOOL bForceStart = FALSE, int iPriority = 0); virtual NiControllerSequence* SetCurAnimation(const char* AnimName, float Frequence = 1.0f, BOOL bLoop = FALSE, BOOL bForceStart = FALSE, int iPriority = 0); virtual void SetPosition(const NiPoint3& kPos); void OnContact(CModelInstance* pkInstance); void OnContactTransport(CModelInstance* pkInstance); void OnMoveToNewWorld(); NiPoint3 GetLocalPlayerPos(); NiAVObject* GetEyeNod(){ return m_pEyeNod;} ui32 GetYuanBao() { return GetUInt32Value(PLAYER_FIELD_YUANBAO); } void SetYuanBao(ui32 uiYuanBao); void SetAutoActionPos( bool bautoaction ){ m_bAutoActionPos = bautoaction; } bool GetAutoActionPos(){ return m_bAutoActionPos;} void SetShowPositon() { m_bShowPositon = !m_bShowPositon; } void SetForceFly() { m_bForceFly = !m_bForceFly; } public: BOOL IsHook(); bool isShowPosition(){ return m_bShowPositon;} protected: IStateProxy* GetStateInstance(State eState); IStateProxy* GetStateProxy(State StateID); //IStateProxy* GetCurStateProxy(); private: virtual void OnCreate(class ByteBuffer* data, ui8 update_flags); void PostOnCreate(); virtual void OnValueChanged(class UpdateMask* mask); virtual void OnActorLoaded(NiActorManager* pkActorManager); virtual void Update(float dt); void UpdatePhysics(float fDelta); virtual void OnLevelupStatus(ui32 newLevel); void ActivateMoveTargetPointEffect(const NiPoint3& pos); void DeactivateMoveTargetPointEffect(); public: bool GetPathPoint(std::deque& PathPoint); std::vector m_pkMapToMapInfo ; //跨地图寻路的所有传送NPC信息 ui64 m_pkMapToMapNPC ; //当前需要点击的NPC BOOL m_pkBChangeMap ; //是否在跳转地图当中 BOOL m_pkTraceGate; //是否碰到传送门 BOOL m_MoveToTarget; float m_fRange; protected: //PVP 区域信息移植到本地玩家身上, 不应该绑定到小地图界面。 void InitPVPInfo(); NiFixedString m_kMapName; unsigned int m_uiAreaId; //当前区的ID NiPoint3 m_kLastAreaPos; unsigned int m_uiAreaFlags; BOOL m_IsChangMap; //是否正在加载地图。 加载地图中, 保证玩家的安全 BOOL m_ChangMapOK ; //地图加载后,还需要再次更新一下才保证是正确的 void UpdataArea(); //更新区域信息 void OnAreaChanged(unsigned int uiAreaId, BOOL bChangMap = FALSE); //更新区域标识 void OnAreaFlagsChanged(BOOL bChangMap = FALSE); //PVP信息更新 void OnMapChanged(); //地图更新 public: void SetChangMap(BOOL chang){m_IsChangMap = chang;} BOOL GetIsChangMap(){return m_IsChangMap;} virtual void OnFormModelChanged(); public: static CUstate GetCUState(); static void SetCUState(CUstate pState, BOOL bChange = FALSE); //客户端判断是否可以交易 BOOL CanSendTradeRequest(ui64 guid); bool GetCanFinishQuestData(uint32 MapID, vector& PosVec); bool m_bAutoRun; ui32 m_TempMapId; BOOL AddLearnNewSkillEffect(); protected: CUstate m_CUState; private: // HACK 服务端返回信息时,玩家尚未创建,因此将其独立出来. static ActiveLocalPlayerDesc sm_ActiveLPDesc; NiCollisionGroup m_CGForMove; // 行走的碰撞空间. 基于NDL的实现,如果一个Col space中,动态物体 // 过多,则会指数级降低求解的性能, 而我们的设定中, 动态物体之间是没有碰撞的. 因此我们可以确保 // NiCollisionGroup 保持一个线性的复杂度. static IStateProxy* sm_StateProxys[STATE_MAX]; private: CEffectBase* m_pkEffectList[EFFECT_MAX]; CSceneEffect* m_pkAStarDir; NiAVObject* m_pEyeNod; ui64 m_uiFollowPlayerID; float m_fFollowRadius; vector m_vQust; ui32 m_uiLastMovementFlags; float m_fLastSendMovementTime; float m_fLastFacingTime; float m_fSendMovementDuration; float m_fLastDesiredAngle; float m_fLastTransportTime; int m_uiLastHonor; bool m_bAutoActionPos; bool m_bShowPositon; vector m_SkillList; public: bool GetSkillList(vector& vlist); void PushSkillList(vector& vlist); void PushSkill(uint32 spellID); void PopSkill(uint32 spellID); bool FindSkill(uint32 spellID); protected: //SM int32 * SM_CriticalChance;//flat int32 * SM_FDur;//flat int32 * SM_PDur;//pct int32 * SM_PRadius;//pct int32 * SM_FRadius;//flat int32 * SM_PRange;//pct int32 * SM_FRange;//flat int32 * SM_PCastTime;//pct int32 * SM_FCastTime;//flat int32 * SM_PCriticalDamage; int32 * SM_PDOT;//pct int32 * SM_FDOT;//flat int32 * SM_FEffectBonus;//flat int32 * SM_PEffectBonus;//pct int32 * SM_FDamageBonus;//flat int32 * SM_PDamageBonus;//pct int32 * SM_PSPELL_VALUE;//pct int32 * SM_FSPELL_VALUE;//flat int32 * SM_FHitchance;//flat int32 * SM_PAPBonus;//pct int32 * SM_PCost; int32 * SM_FCost; int32 * SM_PNonInterrupt; int32 * SM_PJumpReduce; int32 * SM_FSpeedMod; int32 * SM_FAdditionalTargets; int32 * SM_FPenalty;//flat int32 * SM_PPenalty;//Pct int32 * SM_PCooldownTime; int32 * SM_FCooldownTime; int32 * SM_FChanceOfSuccess; int32 * SM_FRezist_dispell; int32 * SM_PRezist_dispell; int32 * SM_FThreatReduce; int32 * SM_PThreatReduce; int32 * SM_FSPELL_VALUE0; int32 * SM_FSPELL_VALUE1; int32 * SM_FSPELL_VALUE2; int32 * SM_PSPELL_VALUE0; int32 * SM_PSPELL_VALUE1; int32 * SM_PSPELL_VALUE2; void SetSpellModifier(int32** m, int32 v, uint8 x, uint8 type); void SpellAddFlatModifier(int32 v, uint8 x, uint8 type); void SpellAddPctModifier(int32 v, uint8 x, uint8 type); public: void UpdataSpellModifier(int32 v, uint8 x, uint8 type, bool pct); void SM_FF_Value(uint8 type, float* v, uint64 group); void SM_FI_Value(uint8 type, int32* v, uint64 group); void SM_PF_Value(uint8 type, float* v, uint64 group); void SM_PI_Value(uint8 type, int32* v, uint64 group); public: ui64 m_LocalBuyBack[12]; ui32 m_LocalBuyBackPrice[12]; };