#include "stdafx.h" #include "AppliedNpcDependencyChain.h" #include #include #include #include "ItemManager.h" #include "Monster.h" #include "MapNpc.h" #include "TriggerManagerEx.h" #include "QuestManager.h" #include "QuestManager_Concrete.h" #include "GameZone.h" #include #include "GameInstanceDungeon.h" #include #include "GameParty/NewGamePartyManager.h" #ifdef _NA_003649_20111115_BATTLE_ZONE_HARDMODE #include "NPCReplaceInfoParser.h" #endif //_NA_003649_20111115_BATTLE_ZONE_HARDMODE #include "MonsterBookParser.h" //_NA_007086_20140318_MONSTERBOOK //================================================================================================== // WORK_KEY AppliedNpcDependencyChain::ms_WorkKey = 0; AppliedNpcDependencyChain* AppliedNpcDependencyChain::ms_pInstance = NULL; AppliedNpcDependencyChain::AppliedNpcDependencyChain() { ms_pInstance = this; } AppliedNpcDependencyChain::~AppliedNpcDependencyChain() { ms_pInstance = NULL; } BOOL AppliedNpcDependencyChain::DoInit() { m_UpdateTimer.SetTimer(INTERVALforUPDATE); //AddPolicyNpcLinkItemDelete( LINK_ITEM_DELETE00_NPCCODE, LINK_ITEM_DELETE00_ITEMCODE ); //AddPolicyNpcLinkItemDelete( LINK_ITEM_DELETE01_NPCCODE, LINK_ITEM_DELETE01_ITEMCODE ); //AddPolicyNpcLinkItemDelete( LINK_ITEM_DELETE02_NPCCODE, LINK_ITEM_DELETE02_ITEMCODE ); //AddPolicyNpcLinkItemDelete( LINK_ITEM_DELETE03_NPCCODE, LINK_ITEM_DELETE03_ITEMCODE ); return TRUE; } BOOL AppliedNpcDependencyChain::DoProcess() { if( m_UpdateTimer.IsExpired() ) { } return TRUE; } BOOL AppliedNpcDependencyChain::IsComplete() { return FALSE; } BOOL AppliedNpcDependencyChain::DoRelease() { return TRUE; } VOID AppliedNpcDependencyChain::OnMsg( sSIG_MSG* pSIG_MSG ) { __UNUSED(pSIG_MSG); return; } //================================================================================================== // NpcAction class IMonsterLinkActions : public INpcLinkAction { public: virtual ~IMonsterLinkActions() {} virtual BOOL OnDead( GameField* IN pField, NPC* IN pNPC, Player* IN pOwner, const DWORD killerObjKey ) { return AppliedNpcDependencyChain::Instance()->OnMonsterDeadProcess( pField, pNPC, pOwner, killerObjKey ); } }; class IMapNpcLinkActions : public INpcLinkAction { public: virtual ~IMapNpcLinkActions() {} virtual BOOL OnDead( GameField* IN pField, NPC* IN pNPC, Player* IN pOwner, const DWORD killerObjKey ) { return AppliedNpcDependencyChain::Instance()->OnMapNpcDeadProcess( pField, pNPC, pOwner, killerObjKey ); } }; class ISSQMonsterLinkActions : public INpcLinkAction { public: virtual ~ISSQMonsterLinkActions() {} virtual BOOL OnDead( GameField* IN pField, NPC* IN pNPC, Player* IN pOwner, const DWORD killerObjKey ) { return AppliedNpcDependencyChain::Instance()->OnSSQMonsterDeadProcess( pField, pNPC, pOwner, killerObjKey ); } }; class IEventRegisterForNpcKillByQuestImpl : public IEventRegisterForNpcKillByQuest { public: IEventRegisterForNpcKillByQuestImpl() {} ~IEventRegisterForNpcKillByQuestImpl() {} virtual BOOL RegisterNpcKillInfo(WORD/*QCODE*/ questCode, MONSTERCODE npcCode) { AppliedNpcDependencyChain* pChain = AppliedNpcDependencyChain::Instance(); pChain->AddPolicyNpcLinkQuest(npcCode); pChain->RegisterQuestNpcForNavigation(questCode, npcCode); return TRUE; }; }; class IEventRegisterForNpcKillByTriggerImpl : public IEventRegisterForNpcKillByTrigger { typedef STLX_VECTOR UNIT_ID_SET; UNIT_ID_SET m_UnitID_Set; public: virtual ~IEventRegisterForNpcKillByTriggerImpl() {} virtual BOOL RegisterNpcKillInfo( const MONSTERCODE npcCode ) { AppliedNpcDependencyChain* pChain = AppliedNpcDependencyChain::Instance(); pChain->AddPolicyNpcLinkTrigger( npcCode ); return TRUE; } virtual BOOL RegisterUnitKillInfo( const REGENID unitID ) { m_UnitID_Set.push_back( unitID ); return TRUE; } // Unit ID µî·ÏÀº WUT, WMO ºÐ¸® »óÀÇ ¹®Á¦·Î Àӽðø°£ÀÌ ¿ä±¸µÇ¹Ç·Î ÀÌ¿¡ ´ëÇÑ ÃʱâÈ­ ÀÛ¾÷ÀÌ ¿ä±¸µÈ´Ù. virtual VOID PrepareRegistering() { m_UnitID_Set.clear(); m_UnitID_Set.reserve( 200 ); } virtual VOID BuildRegisterInfo(MAPCODE mapCode, FIELDCODE fieldCode, UnitRegenInfoManager* const pUnitRegenInfoManager) { AppliedNpcDependencyChain* pChain = AppliedNpcDependencyChain::Instance(); //const AppliedNpcDependencyChain::QUEST_NPC_NAVI_TABLE& rTable = pChain->GetQuestNpcNaviTable(); DWORD rCount = 0; MONSTERCODE pArray[NUM_REGENUNITTYPE] = {0,};//_NA_0_20100706_RANDOM_REGEN const UNITREGENINFO_HASH& rUnitRegenList = pUnitRegenInfoManager->GetUnitRegenInfoHash(); FOREACH_CONTAINER(const UNITREGENINFO_HASH::value_type& rUnitRegen, rUnitRegenList, UNITREGENINFO_HASH) { UnitRegenInfo* pUnitRegenInfo = rUnitRegen.second; // ÁÖÀÇ : npcÄÚµå ¸¶´Ù ½ÃÀÛ À§Ä¡°¡ ´Ù¸¦¼ö´Â ÀÖ´Ù. [3/22/2010 lst1024] // Åø¿¡ ÀÇÇØ¼­ ·£´ýÇÑ ½ÃÀÛ À§Ä¡¸¦ ÂïÀ»¼ö ÀÖ´Ù. const WzVector& rPos = pUnitRegenInfo->GetStartPos(0); rCount = pUnitRegenInfo->GetNpcCodeArray(pArray, NUM_REGENUNITTYPE); for(DWORD i = 0; i < rCount; ++i) { MONSTERCODE npcCode = (MONSTERCODE)pArray[i]; // »ó¼ö Å×À̺í·Î¸¸ ³²°ÜµÎÀÚ. ¸ðµç npcÀÇ naviÁ¤º¸ ¼³Á¤. pChain->RegisterQuestNpcRegenPosForNavigation(mapCode, fieldCode, npcCode, &rPos); } } FOREACH_CONTAINER(const REGENID unitID, m_UnitID_Set, UNIT_ID_SET) { UnitRegenInfo* const pUnitRegenInfo = pUnitRegenInfoManager->FindUnit( unitID ); if(pUnitRegenInfo == 0) continue; //const WzVector& rPos = pUnitRegenInfo->GetRandomStartPos(); // ÀǵµµÈ È£Ãâ? [3/22/2010 lst1024] rCount = pUnitRegenInfo->GetNpcCodeArray(pArray, NUM_REGENUNITTYPE); for(DWORD i = 0; i < rCount; ++i) { MONSTERCODE npcCode = (MONSTERCODE)pArray[i]; RegisterNpcKillInfo(npcCode); } } m_UnitID_Set.clear(); } }; //================================================================================================== // INpcLinkAction* AppliedNpcDependencyChain::GetNpcLinkAction( const MONSTERCODE npcCode, const eOBJECT_TYPE objType ) { static INpcLinkNoAction sINpcLinkNoAction; static IMonsterLinkActions sIMonsterLinkActions; static IMapNpcLinkActions sIMapNpcLinkActions; static ISSQMonsterLinkActions sISSQMonsterLinkActions; typedef AppliedNpcDependencyChain::NPCCODE_LIST_IT NPCCODE_LIST_IT; AppliedNpcDependencyChain* const pChain = AppliedNpcDependencyChain::Instance(); NPCCODE_LIST_IT itFIND; const ePOLICY policy = pChain->GetNpcDependencyInfo(npcCode, itFIND); if( sNPC_POLICY::NPC_POLICY_NO_CONTROL!=policy ) { switch( objType ) { case FRIEND_MONSTER_OBJECT: case MONSTER_OBJECT: case LUCKYMON_OBJECT: return &sIMonsterLinkActions; case MAPNPC_OBJECT: return &sIMapNpcLinkActions; case SSQMONSTER_OBJECT: return &sISSQMonsterLinkActions; }; } else { switch( objType ) { case FRIEND_MONSTER_OBJECT: case MONSTER_OBJECT: case LUCKYMON_OBJECT: return &sIMonsterLinkActions; case MAPNPC_OBJECT: return NULL; case SSQMONSTER_OBJECT: return &sISSQMonsterLinkActions; }; } return NULL; } IEventRegisterForNpcKillByQuest* AppliedNpcDependencyChain::GetIEventRegisterForNpcKillByQuest() { static IEventRegisterForNpcKillByQuestImpl sIEventRegisterForNpcKillByQuestImpl; return &sIEventRegisterForNpcKillByQuestImpl; }; IEventRegisterForNpcKillByTrigger* AppliedNpcDependencyChain::GetIEventRegisterForNpcKillByTrigger() { static IEventRegisterForNpcKillByTriggerImpl sIEventRegisterForNpcKillByTriggerImpl; return &sIEventRegisterForNpcKillByTriggerImpl; } //¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡ // struct KillMobAcceptableStatus : public std::unary_function { enum { MAX_CHECK_DISTANCE = 30, MAX_CHECK_DISTANCE2 = MAX_CHECK_DISTANCE*MAX_CHECK_DISTANCE }; KillMobAcceptableStatus( Player* IN pKiller, const BASE_NPCINFO* pInfo ) : m_pKiller(pKiller), m_ObjectKey(pKiller->GetObjectKey()), m_pNPCInfo(pInfo) { m_pZone = m_pKiller ? m_pKiller->GetGameZonePtr() : NULL; m_ZoneKey = m_pZone ? m_pZone->GetKey() : 0; m_pPos = m_pKiller ? m_pKiller->GetPosPtr() : NULL; } inline BOOL IsValidState() { return m_pZone && m_ObjectKey ; } BOOL Process( Player* IN pPlayer ) const { // (WAVERIX) (090324) (BUG-FIX) // ´©±º°¡°¡ ¸ó½ºÅ͸¦ ÀâÀ» ¶§, ´Ù¸¥ ÆÄƼ¿øÀÌ Çʵ忡¼­ ³ª°¡¹ö¸° »óȲ¿¡ // ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Â ºÎºÐ ¼öÁ¤ GameField* pField = pPlayer->GetField(); GameZone* pZone = pField ? pPlayer->GetGameZonePtr() : 0; if((pZone && pPlayer->IsAlive()) == FALSE) return FALSE; if( m_ObjectKey != pPlayer->GetObjectKey() ) { if( (m_ZoneKey != pZone->GetKey()) || pPlayer->IsDead() ) return FALSE; if( Math_VectorLength2( *m_pPos, *m_pKiller->GetPosPtr() ) > (MAX_CHECK_DISTANCE2) ) return FALSE; } return TRUE; } BOOL operator() ( Character* pChar ) const { Player* pPlayer = (Player*)pChar; Process( pPlayer ); } Player* m_pKiller; const DWORD m_ObjectKey; const BASE_NPCINFO* m_pNPCInfo; GameZone* m_pZone; ZONEKEY m_ZoneKey; const WzVector* m_pPos; // __DISABLE_COPY(KillMobAcceptableStatus); }; ////¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡ //// //class _ItemDeleter //{ //public: typedef pair _PLAYER_HASH_ITR; //public: _ItemDeleter( const CODETYPE itemCode ) : m_ItemCode(itemCode) {} // // inline BOOL IsDeleteAction() const { return m_ItemCode ? TRUE : FALSE; } // VOID operator()( _PLAYER_HASH_ITR rPair ) const // { // Player* pPlayer = rPair.second; // ItemManager* pItemMGR = pPlayer->GetItemManager(); // // SLOTCODE slotCode = (SLOTCODE)m_ItemCode; // POSTYPE pos = 1; // // static MSG_CG_ITEM_LOSE_ACK msgLOSE; // INVEN_DELETE_TOTAL_INFO& rItemInfos = msgLOSE.m_ItemInfo; // if( RC::RC_ITEM_SUCCESS == pItemMGR->DeleteAllKindOfItem( 1, &slotCode, &pos, &rItemInfos ) ) // { // if( rItemInfos.m_Count != 0 ) // pPlayer->SendPacket( &msgLOSE, msgLOSE.GetSize() ); // // //GAMELOG->LogItem( ITEM_DELETE, m_pPlayer, &rItemSlot, 0, rItemSlot.GetNum() ); // return; // } // } // // inline VOID Process( Player* IN pPlayer ) const // { operator()( make_pair( pPlayer->GetObjectKey(), pPlayer ) ); } // //private: const CODETYPE m_ItemCode; //}; //¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡ // class LoopKillMonsterEvent : public std::unary_function { public: LoopKillMonsterEvent( Player* pKiller, QUEST_MONSTER_KILL_MSG& questMsg, const BASE_NPCINFO* pInfo, const CODETYPE deleteItem=0 ) : AcceptCond( pKiller, pInfo ), m_QuestMsg(questMsg)//, m_ItemDeleter(deleteItem) { } ~LoopKillMonsterEvent() {} inline BOOL IsValidState() { return AcceptCond.IsValidState(); } inline VOID Process( Player* IN pPlayer ) const { // IsValidState´Â ÀÌ¹Ì È£ÃâµÇ¾î ÀÖ´Ù°í ÀüÁ¦ÇÑ´Ù. if( FALSE == AcceptCond.Process( pPlayer ) ) return; // Äù½ºÆ® ó¸® pPlayer->GetQuestManager()->Event( QUEST_EVENT_MONSTERKILL, &m_QuestMsg ); // AC ó¸® const BASE_NPCINFO* pNPCInfo = AcceptCond.m_pNPCInfo; //C_NA_0_20100520_ACSYSTEM_CHANGED if( 0 != pNPCInfo->m_wACCode ) pPlayer->GetACManager()->IncConditionValue( pNPCInfo->m_wACCode, pNPCInfo->m_byACReferenceID, pNPCInfo->m_MonsterCode); //if( m_ItemDeleter.IsDeleteAction() ) // m_ItemDeleter.Process( pPlayer ); } // ÆÄƼ¿ø+°³ÀÎ ¸ðµÎ Àû¿ëÇÏÀÚ. VOID operator() ( Character* pChar ) const { Player* pPlayer = (Player*)pChar; Process( pPlayer ); } private: KillMobAcceptableStatus AcceptCond; QUEST_MONSTER_KILL_MSG& m_QuestMsg; //_ItemDeleter m_ItemDeleter; // __DISABLE_COPY(LoopKillMonsterEvent); }; //¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡¦¡ // class LoopKillMonsterGradeQuest : public std::unary_function { public: LoopKillMonsterGradeQuest( Player* pKiller, QUEST_MONSTER_KILL_GRADE_MSG& questMsg, const BASE_NPCINFO* pInfo ) : AcceptCond( pKiller, pInfo ), m_QuestMsg(questMsg) { } ~LoopKillMonsterGradeQuest() {} inline BOOL IsValidState() { return AcceptCond.IsValidState(); } inline VOID Process( Player* IN pPlayer ) const { // IsValidState´Â ÀÌ¹Ì È£ÃâµÇ¾î ÀÖ´Ù°í ÀüÁ¦ÇÑ´Ù. if( FALSE == AcceptCond.Process( pPlayer ) ) return; // Äù½ºÆ® ó¸® pPlayer->GetQuestManager()->Event( QUEST_EVENT_MONSTERKILL_GRADE, &m_QuestMsg ); } // ÆÄƼ¿ø+°³ÀÎ ¸ðµÎ Àû¿ëÇÏÀÚ. VOID operator() ( Character* pChar ) const { Player* pPlayer = (Player*)pChar; Process( pPlayer ); } private: KillMobAcceptableStatus AcceptCond; QUEST_MONSTER_KILL_GRADE_MSG& m_QuestMsg; // __DISABLE_COPY(LoopKillMonsterGradeQuest); }; class MonsterDeadOperator { public: MonsterDeadOperator( MONSTERCODE MonsterCode, //C_NA_0_20100520_ACSYSTEM_CHANGED KillMobAcceptableStatus *pAcceptCond, BOOLEAN existQuestEvent, BOOLEAN existACEvent, uint8_t type_of_AC, BYTE id_of_AC_ref, QUEST_MONSTER_KILL_MSG * pmsgQuestKill ) { m_pAcceptCond = pAcceptCond; m_existQuestEvent = existQuestEvent; m_existACEvent = existACEvent; m_type_of_AC = type_of_AC; m_id_of_AC_ref = id_of_AC_ref; m_pmsgQuestKill = pmsgQuestKill; m_MonsterCode = MonsterCode; //C_NA_0_20100520_ACSYSTEM_CHANGED do_monster_book_ = FALSE; //_NA_007086_20140318_MONSTERBOOK } ~MonsterDeadOperator() {} VOID operator () ( Player *pPlayer ) { if( !m_pAcceptCond->Process( pPlayer ) ) return; // Äù½ºÆ® ó¸® if( m_existQuestEvent ) pPlayer->GetQuestManager()->Event( QUEST_EVENT_MONSTERKILL, m_pmsgQuestKill ); // AC ó¸® if( m_existACEvent ) pPlayer->GetACManager()->IncConditionValue( m_type_of_AC, m_id_of_AC_ref , m_MonsterCode //C_NA_0_20100520_ACSYSTEM_CHANGED ); if (do_monster_book_) { #ifdef _NA_007086_20140318_MONSTERBOOK MonsterBook player_monster_book = pPlayer->GetMonsterBook(); if (player_monster_book.find(m_MonsterCode) == 0) { MSG_DG_CHARACTER_MONSTERBOOK_ADD_CMD cmd; cmd.monster_code = m_MonsterCode; pPlayer->SendToGameDBPServer(&cmd, sizeof(cmd)); } #endif //_NA_007086_20140318_MONSTERBOOK } } private: KillMobAcceptableStatus * m_pAcceptCond; BOOLEAN m_existQuestEvent; BOOLEAN m_existACEvent; uint8_t m_type_of_AC; BYTE m_id_of_AC_ref; QUEST_MONSTER_KILL_MSG * m_pmsgQuestKill; //C_NA_0_20100520_ACSYSTEM_CHANGED MONSTERCODE m_MonsterCode; public: BOOL do_monster_book_; //_NA_007086_20140318_MONSTERBOOK }; //¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬¦¬ // BOOL AppliedNpcDependencyChain::OnMonsterDeadProcess( GameField* IN pField, NPC* IN pNPC, Player* IN pOwner, const DWORD killerObjKey ) { const BASE_NPCINFO* pInfo = pNPC->GetBaseInfo(); if(pNPC->IsEqualObjectKind(MONSTER_OBJECT) == 0) return FALSE; const MONSTERCODE npcCode = pInfo->m_MonsterCode; Monster* pMonster = (Monster*)pNPC; NPCCODE_LIST_IT itFIND; const ePOLICY policy = GetNpcDependencyInfo(npcCode, itFIND); FlowControl flow; FLOWCONTROL_START() { IfFailThenBreak(pOwner, 0); const BOOLEAN existQuestEvent = !!(sNPC_POLICY::NPC_POLICY_NPC_ONDEAD_QUEST&policy); const uint8_t type_of_AC = pInfo->m_wACCode; const BYTE id_of_AC_ref = pInfo->m_byACReferenceID; //C_NA_0_20100520_ACSYSTEM_CHANGED const BOOLEAN existACEvent = (type_of_AC != 0); QUEST_MONSTER_KILL_MSG msgQuestKill; msgQuestKill.m_MonsterCode = npcCode; KillMobAcceptableStatus acceptCond( pOwner, pInfo ); IfFailThenBreak(acceptCond.IsValidState(), 0); MonsterDeadOperator Opr( //C_NA_0_20100520_ACSYSTEM_CHANGED pInfo->m_MonsterCode, &acceptCond, existQuestEvent, existACEvent, type_of_AC, id_of_AC_ref, &msgQuestKill ); #ifdef _NA_007086_20140318_MONSTERBOOK if (MonsterBookParser::Instance()->FindMonsterBookInfo(npcCode) != NULL) { Opr.do_monster_book_ = TRUE; } #endif //_NA_007086_20140318_MONSTERBOOK if( !NewGamePartyManager::Instance()->For_eachPlayers( pOwner->GetPartyState().GetPartyKey(), Opr ) ) { Opr( pOwner ); } } FLOWCONTROL_END; if( sNPC_POLICY::NPC_POLICY_NPC_ONDEAD_TRIGGER&policy ) // no-check pOwner { TriggerManager* pMGR = pField->GetTriggerManager(); // Send EventMsg To TriggerManager TRIGGER_KILL_MONSTER msgKill; msgKill.m_dwMonsterCode = npcCode; msgKill.m_dwObjectKey = killerObjKey; UnitRegenInfo* pRegenInfo = pMonster->GetUnitRegenInfo(); msgKill.m_MonsterUnitID = ( pRegenInfo ) ? pRegenInfo->GetID() : 0; pMGR->OnMsg( &msgKill ); } return OnMonsterDeadProcessGradeQuest( pField, pNPC, pOwner, killerObjKey ); } BOOL AppliedNpcDependencyChain::OnMapNpcDeadProcess( GameField* IN pField, NPC* IN pNPC, Player* IN pOwner, const DWORD killerObjKey ) { const BASE_NPCINFO* pInfo = pNPC->GetBaseInfo(); if(pNPC->IsEqualObjectKind(MAPNPC_OBJECT) == 0) return FALSE; const MONSTERCODE npcCode = pInfo->m_MonsterCode; MapNpc* pMapNPC = (MapNpc*)pNPC; NPCCODE_LIST_IT itFIND; const ePOLICY policy = GetNpcDependencyInfo(npcCode, itFIND); if( sNPC_POLICY::NPC_POLICY_NPC_ONDEAD_TRIGGER&policy ) { TriggerManager* pMGR = pField->GetTriggerManager(); TRIGGER_DAMAGE_OBJECT msgDamage; // Æ®¸®°Å´Â (1~) ´ë¿ªÀ» »ç¿ë msgDamage.m_dwObjectKey = Conv_TriggerObjectKey(pMapNPC->GetMapObjectID()); pMGR->OnMsg( &msgDamage ); // Send EventMsg To TriggerManager TRIGGER_KILL_MONSTER msgKill; msgKill.m_dwMonsterCode = npcCode; msgKill.m_dwObjectKey = killerObjKey; msgKill.m_MonsterUnitID = 0; pMGR->OnMsg( &msgKill ); } return TRUE; } BOOL AppliedNpcDependencyChain::OnSSQMonsterDeadProcess( GameField* IN pField, NPC* IN pNPC, Player* IN pOwner, const DWORD killerObjKey ) { const BASE_NPCINFO* const pInfo = pNPC->GetBaseInfo(); if(pNPC->IsEqualObjectKind(SSQMONSTER_OBJECT) == 0) return FALSE; GameZone* const pGameZone = pField->GetGameZone(); if( pGameZone->GetZoneType() == eZONETYPE_INSTANCE ) { GameInstanceDungeon* const pDungeon = static_cast( pGameZone ); if( pDungeon->GetTypeOfIndun() == INDUN_KIND_SS_QUEST ) GameWarControlManager::OnMsg( GameSSQCtrlCmd::CharacterEvent::OnDead( pNPC, pOwner ), pDungeon ); } return OnMonsterDeadProcess( pField, pNPC, pOwner, killerObjKey ); } BOOL AppliedNpcDependencyChain::OnMonsterDeadProcessGradeQuest( GameField* IN pField, NPC* IN pNPC, Player* IN pOwner, const DWORD killerObjKey ) { const BASE_NPCINFO* pInfo = pNPC->GetBaseInfo(); if(pNPC->IsEqualObjectKind(MONSTER_OBJECT) == 0) return FALSE; const MONSTERCODE npcCode = pInfo->m_MonsterCode; Monster* pMonster = (Monster*)pNPC; if( pOwner ) { QUEST_MONSTER_KILL_GRADE_MSG questMsg; questMsg.m_MonsterGrade = pInfo->m_byGrade; questMsg.m_MonsterLevel = pInfo->m_DisplayLevel; LoopKillMonsterGradeQuest Opr( pOwner, questMsg, pInfo ); if( Opr.IsValidState() ) { if( !NewGamePartyManager::Instance()->For_eachPlayers( pOwner->GetPartyState().GetPartyKey(), Opr ) ) { Opr( pOwner ); } } } return TRUE; } VOID AppliedNpcDependencyChain::AddPolicyNpcLinkTrigger( const MONSTERCODE npcCode ) { NPCCODE_LIST_IT itFIND; const ePOLICY policy = GetNpcDependencyInfo(npcCode, itFIND); if( !(sNPC_POLICY::NPC_POLICY_NPC_ONDEAD_TRIGGER&policy) ) { sNPC_POLICY rPolicy; rPolicy.Clear(); rPolicy.POLICY = sNPC_POLICY::NPC_POLICY_NPC_ONDEAD_TRIGGER; sNPC_POLICY::sTRIGGER_ACTION& rTriggerAction = rPolicy.SHARED_BLK.TRIGGER_ACTION; rTriggerAction.NpcCode = npcCode; POLICY_LIST_IT it = m_PolicyChain.insert( m_PolicyChain.end(), std::make_pair( rPolicy.POLICY, rPolicy ) ); NPCCODE_LIST_IT itFIND = m_NpcCodeChain.find(npcCode); if( itFIND == m_NpcCodeChain.end() ) { NPCCODE_LINK rLink = NPCCODE_LINK( sNPC_POLICY::NPC_POLICY_NPC_ONDEAD_TRIGGER, NPCPOLICY_NODE( &(it->second), NULL, NULL ) ); m_NpcCodeChain.insert( NPCCODE_NODE( npcCode, rLink ) ); } else { // ´Ù¸¥ Á¤Ã¥Àº Á¸ÀçÇÏ´Â °æ¿ì. NPCCODE_LINK& rLink = itFIND->second; ePOLICY_BITSET& rBit = rLink.first; NPCPOLICY_NODE& rNODE = rLink.second; rNODE.m_pTRIGGER = &(it->second); rBit = (ePOLICY_BITSET) ( (DWORD)rBit | (DWORD)sNPC_POLICY::NPC_POLICY_NPC_ONDEAD_TRIGGER ); } } } VOID AppliedNpcDependencyChain::AddPolicyNpcLinkQuest( const MONSTERCODE npcCode ) { NPCCODE_LIST_IT itFIND; const ePOLICY policy = GetNpcDependencyInfo(npcCode, itFIND); if( !(sNPC_POLICY::NPC_POLICY_NPC_ONDEAD_QUEST&policy) ) { sNPC_POLICY rPolicy; rPolicy.Clear(); rPolicy.POLICY = sNPC_POLICY::NPC_POLICY_NPC_ONDEAD_QUEST; sNPC_POLICY::sQUEST_ACTION& rQuestAction = rPolicy.SHARED_BLK.QUEST_ACTION; rQuestAction.NpcCode = npcCode; POLICY_LIST_IT it = m_PolicyChain.insert( m_PolicyChain.end(), std::make_pair( rPolicy.POLICY, rPolicy ) ); NPCCODE_LIST_IT itFIND = m_NpcCodeChain.find(npcCode); if( itFIND == m_NpcCodeChain.end() ) { NPCCODE_LINK rLink = NPCCODE_LINK( sNPC_POLICY::NPC_POLICY_NPC_ONDEAD_QUEST, NPCPOLICY_NODE( NULL, &(it->second), NULL ) ); m_NpcCodeChain.insert( NPCCODE_NODE( npcCode, rLink ) ); } else { // ´Ù¸¥ Á¤Ã¥Àº Á¸ÀçÇÏ´Â °æ¿ì. NPCCODE_LINK& rLink = itFIND->second; ePOLICY_BITSET& rBit = rLink.first; NPCPOLICY_NODE& rNODE = rLink.second; rNODE.m_pQUEST = &(it->second); rBit = (ePOLICY_BITSET) ( (DWORD)rBit | (DWORD)sNPC_POLICY::NPC_POLICY_NPC_ONDEAD_QUEST ); } } } VOID AppliedNpcDependencyChain::AddPolicyNpcLinkItemDelete( const MONSTERCODE npcCode, const CODETYPE itemCode ) { NPCCODE_LIST_IT itFIND; const ePOLICY policy = GetNpcDependencyInfo(npcCode, itFIND); if( !(sNPC_POLICY::NPC_POLICY_NPC_ONDEAD_ITEM_DELETE_QUEST&policy) ) { sNPC_POLICY rPolicy; rPolicy.Clear(); rPolicy.POLICY = sNPC_POLICY::NPC_POLICY_NPC_ONDEAD_ITEM_DELETE_QUEST; sNPC_POLICY::sITEM_DELETE& rItemDelAction = rPolicy.SHARED_BLK.ITEM_DELETE_ACTION; rItemDelAction.NpcCode = npcCode; rItemDelAction.ItemCode = itemCode; POLICY_LIST_IT it = m_PolicyChain.insert( m_PolicyChain.end(), std::make_pair( rPolicy.POLICY, rPolicy ) ); NPCCODE_LIST_IT itFIND = m_NpcCodeChain.find(npcCode); if( itFIND == m_NpcCodeChain.end() ) { NPCCODE_LINK rLink = NPCCODE_LINK( sNPC_POLICY::NPC_POLICY_NPC_ONDEAD_ITEM_DELETE_QUEST, NPCPOLICY_NODE( NULL, NULL, &(it->second) ) ); m_NpcCodeChain.insert( NPCCODE_NODE( npcCode, rLink ) ); } else { // ´Ù¸¥ Á¤Ã¥Àº Á¸ÀçÇÏ´Â °æ¿ì. NPCCODE_LINK& rLink = itFIND->second; ePOLICY_BITSET& rBit = rLink.first; NPCPOLICY_NODE& rNODE = rLink.second; rNODE.m_pITEM_DEL = &(it->second); rBit = (ePOLICY_BITSET) ( (DWORD)rBit | (DWORD)sNPC_POLICY::NPC_POLICY_NPC_ONDEAD_ITEM_DELETE_QUEST ); } } } //{__NA001277_090205_NAVI_SYSTEM_SUPPORT__ void AppliedNpcDependencyChain::RegisterQuestNpcRegenPosForNavigation(MAPCODE mapCode, FIELDCODE fieldCode, MONSTERCODE npcCode, const WzVector* pos) { uQUEST_NPC_POS_KEY conv = { 0, }; conv.npcCode = npcCode; conv.fieldCode = fieldCode; conv.mapCode = mapCode; // Áߺ¹µÇ´Â °æ¿ì´Â ±âÁ¸ Á¤º¸ ³¯·Á¹ö¸°´Ù. NPC_NAVI_NODE& node = m_QuestNpcNaviSearchTable[conv.key]; node.questCode = 0; node.npcCode = npcCode; node.posX = (short)pos->x; node.posY = (short)pos->y; } void AppliedNpcDependencyChain::RegisterQuestNpcForNavigation(WORD /*QCODE*/ questCode, MONSTERCODE npcCode) { NPC_NAVI_INFO& node = m_QuestNpcNaviTable[questCode]; BOOST_STATIC_ASSERT(_countof(node.naviInfos) == QUEST_CONDITION_KILLMONSTER_INFO::_MAX_CHECK_NUM); if(_countof(node.naviInfos) <= node.numberOfNaviInfos) return; node.naviInfos[node.numberOfNaviInfos++] = npcCode; } #ifdef _NA_003649_20111115_BATTLE_ZONE_HARDMODE MONSTERCODE AppliedNpcDependencyChain::GetRepleaceMonsterCode( \ GameZone* game_zone, MONSTERCODE monster_code, bool regist_trigger ) { if (!game_zone) return 0; MONSTERCODE replaace_monster_code = \ NPCReplaceInfoParser::Instance()->GetReplaceNPCCode(game_zone->GetMapCode(), monster_code); if (replaace_monster_code) { if (regist_trigger) { const sNPC_POLICY::ePOLICY policy = GetNpcDependencyInfo(monster_code); // ¿ø·¡¸÷¿¡ OnDeadTrigger°¡ ÀÖÀ¸¸é ±³Ã¼¸÷¿¡µµ Æ®¸®°Å¸¦ °É¾îÁÜ if (sNPC_POLICY::NPC_POLICY_NPC_ONDEAD_TRIGGER&policy ) { AddPolicyNpcLinkTrigger(replaace_monster_code); } } return replaace_monster_code; } return 0; } #endif //_NA_003649_20111115_BATTLE_ZONE_HARDMODE //}