#pragma once #include #include //#include #include "float.h" #include "KPrimitiveMesh.h" #include struct sObjectHashKey { typedef AR_HANDLE Key; static inline unsigned getindex( const Key& key, int nCapacity ) { return unsigned( key ) % nCapacity; } static inline bool isequal( const Key& key1, const Key& key2 ) { return key1 == key2; } static inline bool isless( const Key& key1, const Key& key2 ) { return key1 < key2; } }; struct _Object { _Object() { bIsLeaved = false; leaveTime = 0; bIsActivate = true; layer=0; } virtual ~_Object() {} enum { PLAYER = 0, NPC = 1, STATIC_OBJECT = 2, SUMMON = 3 }; unsigned char type; AR_HANDLE handle; ArMoveVector mv; AR_TIME leaveTime; unsigned char layer; bool bIsLeaved; bool bIsActivate; }; struct ArcadiaIntf { virtual void ReqMove( AR_HANDLE handle, const ArPosition & from, const ArPosition & to, AR_TIME gap, const ArPosition * targetposdata, int count, bool bSpeedSync = true ) = 0; virtual void ReqRegionUpdate( AR_TIME gap ) = 0; virtual bool onLeave( _Object *pPtr ) = 0; // {} //내가 아는 경우, BERSERK 물어봐~ }; struct sNextKMoveInfo { sNextKMoveInfo() : collisionCount(0) {} void setCurPos(float x, float y, float z) { curPos.x = x; curPos.y = y; curPos.z = z; } float kmoveDir; unsigned char speed; ArPosition curPos; ArPosition nextKMovePos; AR_TIME elapsedArTime; float collisionTheta; bool checkNextCollisionPos; int collisionCount; }; struct ArcadiaClient { ArcadiaClient() { bIsPendingMove = false; m_terrainMapEngine = NULL; #ifdef KMOVE_DEBUG m_kmovePrimitive = new KWireUtilPrimitive; #endif } ~ArcadiaClient() { #ifdef KMOVE_DEBUG if (m_kmovePrimitive) delete m_kmovePrimitive; #endif } void ClerAll(); void ReSet(); void StopMove(); void SetInterface( ArcadiaIntf * intf ) { m_intf = intf; } void Proc( bool bPendingLeave = false ); bool FinishedReqRegionUpdate(); ArMoveVector & GetMyPos() { return m_myPos; } const ArPosition & GetTargetPos() { return m_targetPos; } void SetLayer( unsigned char layer ) { m_mylayer = layer; } unsigned char GetLayer() { return m_mylayer; } void ReqMove( const ArPosition & target, const ArPosition * targetposdata, int count, bool bSpeedSync ); void ReqMove( AR_HANDLE handle, const ArPosition & target, const ArPosition * targetposdata, int count, bool bSpeedSync ); void onLogin( const ArPosition & pos, AR_HANDLE my_id ); void onMoveAck( AR_TIME start_time, unsigned char speed ); void onEnter( _Object * pPtr ); void onWarp( AR_UNIT x, AR_UNIT y, AR_UNIT z ); void onRegionAck( unsigned rx, unsigned ry ); void SetActivate( AR_HANDLE handle ); /// 서버로 부터 받은~ _Object * onLeave( AR_HANDLE handle ); void onMove( AR_HANDLE id, const ArPosition & pos, unsigned char speed, AR_TIME start_time = 0 ); void onMultiMove( AR_HANDLE id, const ArPosition & pos, const std::vector< ArPosition > & _to, unsigned char speed, AR_TIME start_time = 0 ); void onKnockBack( AR_HANDLE id, const ArPosition & pos, unsigned char speed ); void setTerrainMapEngine(class CTerrainMapEngine* terrainMapEngine); bool getNextKMovePos(sNextKMoveInfo& info, float oneStepMoveLen, std::vector const& blockList, float rateLen = 1.0f); void onClientMultiMove(AR_HANDLE id, const ArPosition & pos, const std::vector< ArPosition > & _to, unsigned char speed, AR_TIME start_time = 0); AR_TIME calcElapsedMoveTime(float len, int speed) const; #ifdef KMOVE_DEBUG void addKMovePrimitive(std::vector const& _to, ArPosition const& curPos, int type); class KWireUtilPrimitive* getKMovePrimitive() const; #endif void procClient(_Object* client); void setSpeed(AR_HANDLE id, unsigned char speed); ArPosition GetPosition( AR_HANDLE handle ) { if( handle == m_myHandle ) return GetMyPos(); _Object* client; if (m_clientList.lookup(handle, client)) { return client->mv.GetPos(); } return ArPosition(); } template< typename FUNCTION_OBJECT > void DoEachClient( FUNCTION_OBJECT & fo ) { _Object* client = NULL; res = m_clientList.get_first_value(client); while ( res ) { fo.func( client ); res = m_clientList.get_next_value(client); } } unsigned GetPRX() { return m_px; } unsigned GetPRY() { return m_py; } private: void proc( ArMoveVector & pos ); void calcNextKMovePos(sNextKMoveInfo& info, float oneStepMoveLen, float rateLen); private: unsigned char m_mylayer; AR_HANDLE m_myHandle; AR_TIME m_lastProcTime; std::map< AR_HANDLE, AR_TIME > m_lastPendingTime; unsigned m_pnx, m_pny; unsigned m_px, m_py; ArcadiaIntf * m_intf; ArMoveVector m_myPos; ArPosition m_targetPos; //std::vector<_Object*> m_vClientList; KHash<_Object*, sObjectHashKey> m_clientList; bool bIsPendingMove; class CTerrainMapEngine* m_terrainMapEngine; #ifdef KMOVE_DEBUG class KWireUtilPrimitive* m_kmovePrimitive; #endif };