#pragma once class SSQMonster; class INpcLinkAction; class IEventRegisterForNpcKillByQuest; class IEventRegisterForNpcKillByTrigger; //¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬ // struct sNPC_POLICY { enum ePOLICY { NPC_POLICY_NOT_DEFINED = 0, NPC_POLICY_NO_CONTROL = NPC_POLICY_NOT_DEFINED, // ÄÁÆ®·ÑÇÒ Á¤º¸ ¾øÀ½ NPC_POLICY_NPC_ONDEAD_TRIGGER = 1<<0, // ¸ó½ºÅͰ¡ Á×¾úÀ» ¶§ Æ®¸®°Å ¾×¼Ç ¿©ºÎ NPC_POLICY_NPC_ONDEAD_QUEST = 1<<1, // ¸ó½ºÅͰ¡ Á×¾úÀ» ¶§ Äù½ºÆ® ¾×¼Ç ¿©ºÎ NPC_POLICY_NPC_ONDEAD_ITEM_DELETE_QUEST = 1<<2, // ¸ó½ºÅͰ¡ Á×¾úÀ» ¶§ Äù½ºÆ® ¸ó½ºÅÍ Á×À»¶§ ¹Ù·Î »èÁ¦µÇ´Â ¾ÆÀÌÅÛ Ã³¸® NPC_POLICY_NPC_ONDEAD_ITEM_DELETE_NO_COND = 1<<3, // ¸ó½ºÅͰ¡ Á×¾úÀ» ¶§ ¾ÆÀÌÅÛ »èÁ¦ ¾×¼Ç ¿©ºÎ (¹Ì±¸Çö) }; //static const DWORD _MAX_ITEM_DELETE_COUNT = 5; ePOLICY POLICY; union uSHARED_BLK { struct sTRIGGER_ACTION { MONSTERCODE NpcCode; } TRIGGER_ACTION; // Trigger´Â ƯÁ¤ »óŸ¸ ÁöĪÇÒ ¼öµµ ÀÖÁö¸¸, ±×·¸°Ô µÇ¸é Á¤º¸·®ÀÌ ¸¹¾ÆÁö¹Ç·Î ±âÁ¸´ë·Î °£´Ù. struct sQUEST_ACTION { MONSTERCODE NpcCode; } QUEST_ACTION; // Quest´Â ƯÁ¤ »óŸ¸ ÁöĪÇÒ ¼öµµ ÀÖÁö¸¸, ±×·¸°Ô µÇ¸é Á¤º¸·®ÀÌ ¸¹¾ÆÁö¹Ç·Î ±âÁ¸´ë·Î °£´Ù. struct sITEM_DELETE { MONSTERCODE NpcCode; CODETYPE ItemCode; } ITEM_DELETE_ACTION; } SHARED_BLK; typedef uSHARED_BLK::sTRIGGER_ACTION sTRIGGER_ACTION; typedef uSHARED_BLK::sQUEST_ACTION sQUEST_ACTION; typedef uSHARED_BLK::sITEM_DELETE sITEM_DELETE; inline VOID Clear() { POLICY = NPC_POLICY_NOT_DEFINED; ZeroMemory( &SHARED_BLK, sizeof(SHARED_BLK) ); } inline sTRIGGER_ACTION& GetTriggerInfo() { return SHARED_BLK.TRIGGER_ACTION; } inline sQUEST_ACTION& GetQuestInfo() { return SHARED_BLK.QUEST_ACTION; } inline sITEM_DELETE& GetItemDeleteInfo() { return SHARED_BLK.ITEM_DELETE_ACTION; } }; //{__NA001277_090205_NAVI_SYSTEM_SUPPORT__ typedef MSG_CG_QUEST_OBJECT_NAVI_POS_CMD::Node NPC_NAVI_NODE; struct NPC_NAVI_INFO { NPC_NAVI_INFO() : numberOfNaviInfos(0) { ZeroMemory(naviInfos, sizeof(naviInfos)); } BYTE numberOfNaviInfos; MONSTERCODE naviInfos[5]; // assert check in code-file }; union uQUEST_NPC_POS_KEY { struct { MONSTERCODE npcCode; FIELDCODE fieldCode; MAPCODE mapCode; WORD __reserved__; }; DWORD64 key; }; //} //¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬ // class AppliedNpcDependencyChain : public IWorkNode { private: static const DWORD INTERVALforUPDATE = 10*1000; private: typedef sNPC_POLICY::ePOLICY ePOLICY; typedef sNPC_POLICY::sTRIGGER_ACTION sTRIGGER_ACTION; typedef sNPC_POLICY::sQUEST_ACTION sQUEST_ACTION; typedef sNPC_POLICY::sITEM_DELETE sITEM_DELETE; private: typedef std::pair POLICY_NODE; typedef STLX_LIST POLICY_LIST; typedef POLICY_LIST::iterator POLICY_LIST_IT; typedef sNPC_POLICY::ePOLICY ePOLICY_BITSET; // ÇØ´ç Äڵ忡 °ü·ÃµÈ ¸ðµç POLICY bitset typedef sNPC_POLICY* sTRIGGER_PTR; // °ü·Ã Æ®¸®°Å Á¸Àç½Ã typedef sNPC_POLICY* sQUEST_PTR; // °ü·Ã Äù½ºÆ® Á¸Àç½Ã typedef sNPC_POLICY* sITEM_DELETE_PTR; // ¾ÆÀÌÅÛ Á¦°Å ó¸® Á¸Àç½Ã struct NPCPOLICY_NODE { sTRIGGER_PTR m_pTRIGGER; sQUEST_PTR m_pQUEST; sITEM_DELETE_PTR m_pITEM_DEL; NPCPOLICY_NODE( const sTRIGGER_PTR pTRIGGER=NULL, const sQUEST_PTR pQUEST=NULL, const sITEM_DELETE_PTR pITEM_DEL=NULL ) : m_pTRIGGER(pTRIGGER), m_pQUEST(pQUEST), m_pITEM_DEL(pITEM_DEL) {} }; //typedef pair NPCPOLICY_NODE; typedef std::pair NPCCODE_LINK; // typedef STLX_MAP NPCCODE_LIST; typedef NPCCODE_LIST::iterator NPCCODE_LIST_IT; typedef std::pair NPCCODE_NODE; public: typedef STLX_HASH_MAP QUEST_NPC_NAVI_TABLE; // [MAPCODE|FIELDCODE|MONSTERCODE] - uQUEST_NPC_POS_KEY typedef STLX_HASH_MAP QUEST_NPC_NAVI_SEARCH_TABLE; private: AppliedNpcDependencyChain(); public: virtual ~AppliedNpcDependencyChain(); static VOID CreateInstance() { ms_pInstance ? 0 : new AppliedNpcDependencyChain(); } static VOID DestoryInstance() { SAFE_DELETE(ms_pInstance); } inline static AppliedNpcDependencyChain* Instance() { return ms_pInstance; } inline static WORK_KEY GetWorkKey() { return ms_WorkKey; } inline static VOID SetWorkKey( WORK_KEY wKey ) { ms_WorkKey = wKey; } public: virtual BOOL DoInit(); virtual BOOL DoProcess(); virtual BOOL IsComplete(); virtual BOOL DoRelease(); // Control Interface virtual VOID OnMsg( sSIG_MSG* pSIG_MSG ); inline ePOLICY GetNpcDependencyInfo( const MONSTERCODE npcCode ) { NPCCODE_LIST_IT itFIND = m_NpcCodeChain.find(npcCode); return itFIND != m_NpcCodeChain.end() ? itFIND->second.first : sNPC_POLICY::NPC_POLICY_NO_CONTROL; } inline ePOLICY GetNpcDependencyInfo( const MONSTERCODE npcCode, NPCCODE_LIST_IT& OUT itFIND ) { itFIND = m_NpcCodeChain.find(npcCode); return itFIND != m_NpcCodeChain.end() ? itFIND->second.first : sNPC_POLICY::NPC_POLICY_NO_CONTROL; } //{__NA001277_090205_NAVI_SYSTEM_SUPPORT__ void RegisterQuestNpcRegenPosForNavigation(MAPCODE mapCode, FIELDCODE fieldCode, MONSTERCODE npcCode, const WzVector* pos); void RegisterQuestNpcForNavigation(WORD /*QCODE*/ questCode, MONSTERCODE npcCode); inline const QUEST_NPC_NAVI_TABLE& GetQuestNpcNaviTable() const { return m_QuestNpcNaviTable; } inline const QUEST_NPC_NAVI_SEARCH_TABLE& GetQuestNpcNaviSearchTable() const { return m_QuestNpcNaviSearchTable; } //} //inline BOOL IsExpirationItem( const CODETYPE itemCode ) //{ return !!( sNPC_POLICY::NPC_POLICY_TRIGGER_ACTION&GetItemDependencyInfo(itemCode) ); } //inline BOOL IsExclusiveItem( const CODETYPE itemCode ) //{ return !!( sNPC_POLICY::NPC_POLICY_QUEST_ACTION&GetItemDependencyInfo(itemCode) ); } //inline BOOL IsRenderEffectItem( const CODETYPE itemCode ) //{ return !!( sNPC_POLICY::NPC_POLICY_ITEM_DELETE_ACTION&GetItemDependencyInfo(itemCode) ); } public: CODETYPE GetDeleteItem( const MONSTERCODE npcCode ); CODETYPE GetDeleteItem( const MONSTERCODE npcCode, NPCCODE_LIST_IT& IN rIT ); VOID AddPolicyNpcLinkTrigger( const MONSTERCODE npcCode ); VOID AddPolicyNpcLinkQuest( const MONSTERCODE npcCode ); VOID AddPolicyNpcLinkItemDelete( const MONSTERCODE npcCode, const CODETYPE itemCode ); // ÇÊ¿äÇÒ ¶§ ±¸ÇöÇϱâ·Î ÇÏÀÚ. //VOID RemovePolicyNpcLinkTrigger( const MONSTERCODE npcCode ); //VOID RemovePolicyNpcLinkQuest( const MONSTERCODE npcCode ); //VOID RemovePolicyNpcLinkItemDelete( const MONSTERCODE npcCode ); INpcLinkAction* GetNpcLinkAction( const MONSTERCODE npcCode, const eOBJECT_TYPE objType ); BOOL OnMonsterDeadProcess( GameField* IN pField, NPC* IN pNPC, Player* IN pOwner, const DWORD killerObjKey ); BOOL OnMapNpcDeadProcess( GameField* IN pField, NPC* IN pNPC, Player* IN pOwner, const DWORD killerObjKey ); BOOL OnSSQMonsterDeadProcess( GameField* IN pField, NPC* IN pNPC, Player* IN pOwner, const DWORD killerObjKey ); BOOL OnMonsterDeadProcessGradeQuest( GameField* IN pField, NPC* IN pNPC, Player* IN pOwner, const DWORD killerObjKey ); IEventRegisterForNpcKillByQuest* GetIEventRegisterForNpcKillByQuest(); IEventRegisterForNpcKillByTrigger* GetIEventRegisterForNpcKillByTrigger(); #ifdef _NA_003649_20111115_BATTLE_ZONE_HARDMODE MONSTERCODE GetRepleaceMonsterCode(GameZone* game_zone, MONSTERCODE monster_code, bool regist_trigger = false); #endif //_NA_003649_20111115_BATTLE_ZONE_HARDMODE private: POLICY_LIST m_PolicyChain; NPCCODE_LIST m_NpcCodeChain; ITimerBase m_UpdateTimer; QUEST_NPC_NAVI_TABLE m_QuestNpcNaviTable; QUEST_NPC_NAVI_SEARCH_TABLE m_QuestNpcNaviSearchTable; static WORK_KEY ms_WorkKey; static AppliedNpcDependencyChain* ms_pInstance; //¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡ //enum eHARDCODE_VALUE //{ // LINK_ITEM_DELETE00_NPCCODE = 38399, // ±¸½½0-Á¦°ÅÇÒ À̺¥Æ® NPC // LINK_ITEM_DELETE00_ITEMCODE = 40194, // ±¸½½0 // LINK_ITEM_DELETE01_NPCCODE = 38403, // ±¸½½1-Á¦°ÅÇÒ À̺¥Æ® NPC // LINK_ITEM_DELETE01_ITEMCODE = 40195, // ±¸½½1 // LINK_ITEM_DELETE02_NPCCODE = 38408, // ±¸½½2-Á¦°ÅÇÒ À̺¥Æ® NPC // LINK_ITEM_DELETE02_ITEMCODE = 40196, // ±¸½½2 // LINK_ITEM_DELETE03_NPCCODE = 38413, // ±¸½½3-Á¦°ÅÇÒ À̺¥Æ® NPC // LINK_ITEM_DELETE03_ITEMCODE = 40197, // ±¸½½3 //}; }; //¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬ // NpcAction class INpcLinkAction { public: virtual ~INpcLinkAction() {} // pOwner´Â ±âÁ¸ Á¶°Ç¿¡ µû¸¥ ¼³Á¤ÀÌ ÇÊ¿äÇÑ °æ¿ì¿¡ »ç¿ë, Áï ÇöÀç±âÁØ(071209) // (Owner && !bTransformation) == TRUE ÀÎ Á¶°Ç¿¡ ´ëÇØ¼­ Quest 󸮰¡ ÀÌ·ïÁö°í ÀÖ°í, // Trigger¿¡ ÀÇÇÑ °ÍÀº À§ Á¶°ÇÀ» ¹«½ÃÇϰí All roundingµÈ´Ù. // µû¶ó¼­ Çѹø¸¸ È£ÃâÇÏ·Á¸é, // NpcLinkAction.OnDead( pField, pNPC, (pOwner&&!bTransaction) ? pOwner : NULL ); // ¿Í °°ÀÌ ÇÏ¸é µÈ´Ù. ACÁ¤º¸´Â... À½... virtual BOOL OnDead( GameField* IN pField, NPC* IN pNPC, Player* IN pOwner, const DWORD killerObjKey ) = 0; }; class INpcLinkNoAction : public INpcLinkAction { public: virtual ~INpcLinkNoAction() {} virtual BOOL OnDead( GameField* IN pField, NPC* IN pNPC, Player* IN pOwner, const DWORD killerObjKey ) { __UNUSED((pField, pNPC, pOwner, killerObjKey)); return TRUE; } }; class INpcLinkActionD { public: INpcLinkActionD() : m_pInterface(NULL) {} INpcLinkActionD( const INpcLinkAction* pIAction ) : m_pInterface(const_cast(pIAction)) {} INpcLinkActionD( const INpcLinkActionD& rSrc ) : m_pInterface(rSrc.m_pInterface) {} ~INpcLinkActionD() { m_pInterface = NULL; } inline BOOL OnDead( GameField* IN pField, NPC* IN pNPC, Player* IN pOwner, const DWORD killerObjKey ) { return m_pInterface ? m_pInterface->OnDead(pField, pNPC, pOwner, killerObjKey) : TRUE; } INpcLinkAction* m_pInterface; };