#pragma once #include class PVSObject { public: PVSObject(); ~PVSObject(); bool IsMapCheck( int nMapStartX, int nMapStartY ); bool IsPVSActCheck( int nRootSegmentX, int nRootSegmentY ); void Load( const char* pFileName ); bool IsVisibleSegment( int nRootSegmentX, int nRootSegmentY, int nSegmentX, int nSegmentY ); bool IsVisibleProp( int nRootSegmentX, int nRootSegmentY, size_t nSegmentIdx, size_t nPropIdx ); //Tool 용 int GetCountChildSegment( int nRootSegmentX, int nRootSegmentY ); int GetCountChildProp( int nRootSegmentX, int nRootSegmentY ); enum { EXPORT_EXCHANGE = 0, EXPORT_ADD, EXPORT_SUBTRACT, }; void ExportTxt( int nMode, const char* pFileName, int nRootSegmentX, int nRootSegmentY, std::vector& vSegXList, std::vector& vSegYList, std::vector& vPropIdxList, std::vector& vPropNumList ); struct hashPr_SEGMENT { struct Key { Key() {} Key( const Key& _segment ) { m_segmentX = _segment.m_segmentX; m_segmentY = _segment.m_segmentY; } Key( int nSegmentX, int nSegmentY ) { m_segmentX = nSegmentX; m_segmentY = nSegmentY; } ~Key() {} int m_segmentX; int m_segmentY; }; static inline unsigned int getindex( Key key, int nCapacity ) { return ((unsigned int)key.m_segmentX + key.m_segmentY) % nCapacity; } static inline bool isequal( Key key1, Key key2 ) { return (key1.m_segmentX == key2.m_segmentX && key1.m_segmentY == key2.m_segmentY); } static inline bool isless( Key key1, Key key2 ) { if( key1.m_segmentX != key2.m_segmentX ) return key1.m_segmentX < key2.m_segmentX; return key1.m_segmentY < key2.m_segmentY; } }; struct hashPr_PROP { struct Key { Key() {} Key( const Key& _prop ) { m_nSegmentIdx = _prop.m_nSegmentIdx; m_nPropIdx = _prop.m_nPropIdx; } Key( size_t nSegmentIdx, size_t nPropIdx ) { m_nSegmentIdx = nSegmentIdx; m_nPropIdx = nPropIdx; } ~Key() {} size_t m_nSegmentIdx; size_t m_nPropIdx; }; static inline unsigned int getindex( Key key, int nCapacity ) { return ((unsigned int)key.m_nSegmentIdx + key.m_nPropIdx) % nCapacity; } static inline bool isequal( Key key1, Key key2 ) { return ( key1.m_nSegmentIdx == key2.m_nSegmentIdx && key1.m_nPropIdx == key2.m_nPropIdx ); } static inline bool isless( Key key1, Key key2 ) { if( key1.m_nSegmentIdx != key2.m_nSegmentIdx ) return key1.m_nSegmentIdx < key2.m_nSegmentIdx; return key1.m_nPropIdx < key2.m_nPropIdx; } }; struct SEGMENT_DATA { SEGMENT_DATA() { nSegmentX = 0; nSegmentY = 0; } unsigned short nSegmentX; ///< 0~63 unsigned short nSegmentY; ///< 0~63 }; struct PROP_DATA { PROP_DATA() { nSegmentIdx = 0; nPropIdx = 0; } size_t nSegmentIdx; size_t nPropIdx; }; struct SEGMENT_ROOT { SEGMENT_ROOT() { nSegmentX = 0; nSegmentY = 0; } ~SEGMENT_ROOT() { SEGMENT_DATA* pDATA=NULL; bool res; res = m_hashBySEGMENT.get_first_value( pDATA ); while ( res ) { if ( pDATA != NULL ) { delete pDATA; } res = m_hashBySEGMENT.get_next_value( pDATA ); } m_hashBySEGMENT.clear(); } unsigned short nSegmentX; ///< 0~63 unsigned short nSegmentY; ///< 0~63 KHash< SEGMENT_DATA*, hashPr_SEGMENT > m_hashBySEGMENT; }; struct PROP_ROOT { PROP_ROOT() { nSegmentX = 0; nSegmentY = 0; } ~PROP_ROOT() { PROP_DATA* pDATA=NULL; bool res; res = m_hashByPROP.get_first_value( pDATA ); while ( res ) { if ( pDATA != NULL ) { delete pDATA; } res = m_hashByPROP.get_next_value( pDATA ); } m_hashByPROP.clear(); } unsigned short nSegmentX; ///< 0~63 unsigned short nSegmentY; ///<0~63 KHash< PROP_DATA*, hashPr_PROP > m_hashByPROP; }; protected: struct NFM_PVS_HEADER_V1* m_pHeader; KRect m_rcSegment; KHash< SEGMENT_ROOT*, hashPr_SEGMENT > m_hashBySEGMENT; KHash< PROP_ROOT*, hashPr_SEGMENT > m_hashByPROP; private: }; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// /// PVSObeject Manager class PVSObjectManager { public: PVSObjectManager(); ~PVSObjectManager(); /// 현재 위치 설정 void SetRootSegment( int nSegmentX, int nSegmentY ); bool IsPVSActive(); bool CheckSegment( int nSegmentX, int nSegmentY ); bool CheckProp( size_t nSegmentIdx, size_t nPropIdx ); //Load /// Warp Loading ex) 던전 void WarpLoad( int nWorldPosX, int nWorldPosY ); /// Thread Loading ex) 마을 void ThreadLoad( int nWorldPosX, int nWorldPosY ); static void SetTogglePVS() { m_sToggleAct = !m_sToggleAct; } /// 2011.11.09 월드 좌표를 맵 좌표로 변환 - prodongi void convertWorldToMapPos(int worldPosX, int worldPosY, int& mapX, int& mapY); protected: void Clear(); bool m_bIsPVSActive; PVSObject* m_pCurPVSObject; std::vector< PVSObject* > m_vPVSObjectList; int m_nRootSegmentX, m_nRootSegmentY; static bool m_sToggleAct; private: }; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// /// PVS Merge class PVSMerge { public: PVSMerge(); ~PVSMerge(); void Init(); void MergeFile( const char * pFileName ); void SaveMerge( const char * pFileName ); /// Modify void Modify( const char * pFileName ); struct MERGE_SEGMENT { struct NFM_PVS_SEGMENT_V1* pSegment; std::vector vSegmentList; }; struct MERGE_PROP { struct NFM_PVS_PROP_V1* pProp; std::vector vPropList; }; protected: void Clear(); unsigned int MergeSegment( std::vector< MERGE_SEGMENT* >& main_list, struct NFM_PVS_SEGMENT_V1* pMergeSegment, std::vector& segment_list ); unsigned int MergeProp( std::vector< MERGE_PROP* >& main_list, struct NFM_PVS_PROP_V1* pMergeProp, std::vector& prop_list ); NFM_PVS_HEADER_V1 m_Mainheader; std::vector< MERGE_SEGMENT* > m_vMergeSegment; std::vector< MERGE_PROP* > m_vMergeProp; };