#include "stdafx.h" #include #include "./ConditionTriggers.h" #include "./TriggerManagerEx.h" #include "../../SolarTrigger/TriggerMsg.h" //================================================================================================== #include "Trigger.h" #include "Player.h" #include "ItemManager.h" #include "MissionManager.h" #include "GameZone.h" #include "GameMissionRoom.h" #include "Map.h" #include "MapObject.h" //================================================================================================== // CONDITION_ALWAYS __IMPL_POOL(CONDITION_ALWAYS) VOID CONDITION_ALWAYS::OnInit() { setSatisfied(TRUE); } //================================================================================================== __IMPL_POOL(CONDITION_COMPARE_SWITCH) BOOL CONDITION_COMPARE_SWITCH::IsSatisfied() { if(satisfied_) return TRUE; CONDITION_COMPARE_SWITCH_INFO& rINFO = *Get(); const BYTE idx = rINFO.GetSwitchID(); const BYTE curr_value = getMGR()->GetSwitchValue(idx); const BYTE cond_value = rINFO.GetValue(); BOOL bSatisfied = FALSE; switch(rINFO.GetOperationType()) { case eCOMPARE_EQUAL: bSatisfied = curr_value == cond_value; break; case eCOMPARE_MORE: bSatisfied = curr_value > cond_value; break; case eCOMPARE_LESS: bSatisfied = curr_value < cond_value; break; case eCOMPARE_LESSTHAN: bSatisfied = !(curr_value > cond_value); break; case eCOMPARE_MORETHAN: bSatisfied = !(curr_value < cond_value); break; case eCOMPARE_NOTEQUAL: bSatisfied = curr_value != cond_value; break; // break; default: __debugbreak(); break; } if(bSatisfied) setSatisfied(bSatisfied); return satisfied_; } //================================================================================================== __IMPL_POOL(CONDITION_COMPARE_SWITCH_EX) BOOL CONDITION_COMPARE_SWITCH_EX::IsSatisfied() { if(satisfied_) return TRUE; CONDITION_COMPARE_SWITCH_EX_INFO& rINFO = *Get(); const BYTE idx = rINFO.GetSwitchID(); BYTE curr_value = 0; if (rINFO.GetTarget() == ns_trigger::ZONE) { #ifdef _NA_007369_20140625_ACTION_OPERATE_SWITCH_EX GameZone* const game_zone = getMGR()->GetField()->GetGameZone(); if(game_zone->GetZoneType() == eZONETYPE_MISSION) { GameMissionRoom* mission_room = static_cast(game_zone); curr_value = static_cast(mission_room->GetSwitchValue(rINFO.GetSwitchID())); } #endif //_NA_007369_20140625_ACTION_OPERATE_SWITCH_EX } else return FALSE; const BYTE cond_value = rINFO.GetValue(); BOOL bSatisfied = FALSE; switch(rINFO.GetOperationType()) { case eCOMPARE_EQUAL: bSatisfied = curr_value == cond_value; break; case eCOMPARE_MORE: bSatisfied = curr_value > cond_value; break; case eCOMPARE_LESS: bSatisfied = curr_value < cond_value; break; case eCOMPARE_LESSTHAN: bSatisfied = !(curr_value > cond_value); break; case eCOMPARE_MORETHAN: bSatisfied = !(curr_value < cond_value); break; case eCOMPARE_NOTEQUAL: bSatisfied = curr_value != cond_value; break; // break; default: __debugbreak(); break; } if(bSatisfied) setSatisfied(bSatisfied); return satisfied_; } //================================================================================================== __IMPL_POOL(CONDITION_CLICK_OBJECT) VOID CONDITION_CLICK_OBJECT::onMsg(TRIGGER_MSG* pmsg) { switch(pmsg->m_dwMsgID) { case eTRIGGER_CLICK_OBJECT: { TRIGGER_CLICK_OBJECT* pMsg = (TRIGGER_CLICK_OBJECT *)pmsg; const CONDITION_CLICK_OBJECT_INFO* pInfo = Get(); int object_id = pInfo->GetObjectID(); ASSERT(object_id >= 0); if(pMsg->m_dwObjectKey != object_id) break; MAPOBJECT_INFO* map_object_info = getMGR()->FindMapObjectInfo(object_id); if (map_object_info == NULL) break; Player* player = PlayerManager::Instance()->FindPlayerByObjKey(pMsg->m_PlayerKey); if (player == NULL) break; float near_radius = DISTANCE_NPC_MEET + 1.5f; if(Math_VectorLength(*player->GetPosPtr(), map_object_info->wvPos) > near_radius) break; getParent()->SetClickedPlayerKey(pMsg->m_PlayerKey); #ifdef __TRIGGER_TEST_LOG SUNLOG(eFULL_LOG, "[CONDITION_CLICK_OBJECT::onMsg] [TriggerID:%u]:CONDITION_CLICK_OBJECT", getParent()->TriggerID()); #endif setSatisfied(TRUE); player->Player_TransOff(); MSG_CG_TRIGGER_CLICK_OBJECT_BRD msgBRD; msgBRD.m_dwClickedUserObjectKey = player->GetObjectKey(); msgBRD.m_dwClickedObjectKey = pMsg->m_dwObjectKey; player->SendPacketAround(&msgBRD, sizeof(msgBRD)); } break; } } VOID CONDITION_CLICK_OBJECT::OnReset() { getParent()->SetClickedPlayerKey(0); setSatisfied(FALSE); } //================================================================================================== __IMPL_POOL(CONDITION_DAMAGE_OBJECT) VOID CONDITION_DAMAGE_OBJECT::onMsg(TRIGGER_MSG* pmsg) { if(eTRIGGER_DAMAGE_OBJECT == pmsg->m_dwMsgID) { TRIGGER_DAMAGE_OBJECT* pMsg = (TRIGGER_DAMAGE_OBJECT *)pmsg; if(pMsg->m_dwObjectKey == Get()->GetObjectID()) { //ÀÌ ¿µ¿ª¿¡ Ç÷¹À̾ ÀÖ´ÂÁö üũ ÇÊ¿ä...ÇѰ¡? MapObject* pMapObject = getMGR()->FindMapObject(pMsg->m_dwObjectKey); // Á×¾úÀ¸¸é??? if(FlowControl::FCAssert(pMapObject)) { setSatisfied(TRUE); return; } setSatisfied(FALSE); } } } //================================================================================================== __IMPL_POOL(CONDITION_COUNT_NPCKILL) VOID CONDITION_COUNT_NPCKILL::OnInstanciate() { } VOID CONDITION_COUNT_NPCKILL::OnInit() { ZeroMemory(m_PartyMember, sizeof(m_PartyMember)); } VOID CONDITION_COUNT_NPCKILL::onMsg(TRIGGER_MSG* pmsg) { switch(pmsg->m_dwMsgID) { case eTRIGGER_KILL_MONSTER: { TRIGGER_KILL_MONSTER* pMsg = (TRIGGER_KILL_MONSTER *)pmsg; CONDITION_COUNT_NPCKILL_INFO* pInfo = Get(); if(ns_trigger::PARTY == pInfo->GetIsParty()) { //ASSERT(SAFE_NUMERIC_TYPECAST(int, pInfo->GetMonsterCode(), MONSTERCODE)); PARTY_MEMBER* pMember = &(m_PartyMember[0]); MONSTERCODE monsterCode = pInfo->GetMonsterCode(); #ifdef _NA_003649_20111115_BATTLE_ZONE_HARDMODE GameZone* const game_zone = getMGR()->GetField()->GetGameZone(); if(game_zone->GetZoneType() == eZONETYPE_MISSION) { MONSTERCODE replaace_monster_code = \ AppliedNpcDependencyChain::Instance()->GetRepleaceMonsterCode(game_zone, monsterCode); if (replaace_monster_code) { monsterCode = replaace_monster_code; } } #endif //_NA_003649_20111115_BATTLE_ZONE_HARDMODE if(pMsg->m_dwMonsterCode != monsterCode) { // ´ëºÎºÐÀº ÀÌ Á¶°Ç¿¡ °É¸± °ÍÀÌ´Ù. return; } else { // elseÀÇ Á¶°ÇÀÌ´Ù. Áï, ¸¸Á·ÇÒ °æ¿ì... ++(pMember->m_iKillCount); } const int number_of_kills = pInfo->GetKillCount(); if(number_of_kills > pMember->m_iKillCount) return; //------------------------ // Á¶°Ç ¸¸Á· // == or < setSatisfied(TRUE); #ifdef __TRIGGER_TEST_LOG SUNLOG(eFULL_LOG, "["__FUNCTION__"] [ID:%u]:MONSTER:[%u], KILL CONDITION %u : KILL %u ", getParent()->TriggerID(), pInfo->GetMonsterCode(), \ number_of_kills, pMember->m_iKillCount); #endif //------------------------ if(number_of_kills < pMember->m_iKillCount) { // < ÀÇ Á¶°Ç¿¡ °É¸®´Â °æ¿ì°¡ ÀÖÀ»±î? Ȥ½Ã ¸ð¸¥´Ù. // ÀÖ´Ù¸é ãµµ·Ï 060601, WAVERIX SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] Over Count Killed! TriggerID [%u]: MonsterID [%u], " "MAX [%u]TriggerID(), pInfo->GetMonsterCode(), number_of_kills, pMember->m_iKillCount); } } else { ASSERT(!"ÇöÀç °³ÀδÜÀ§ NPC KILLÀº Çã¿ëÇÏÁö ¾Ê´Â´Ù."); } } break; } } //================================================================================================== __IMPL_POOL(CONDITION_PASS_TIME) VOID CONDITION_PASS_TIME::OnInit() { m_dwStartTick = GetTickCount(); } BOOL CONDITION_PASS_TIME::IsSatisfied() { if(satisfied_) return TRUE; DWORD delay = (DWORD)Get()->GetPassTime(); if((m_dwStartTick + delay) <= GetTickCount()) { setSatisfied(TRUE); } return satisfied_; } VOID CONDITION_PASS_TIME::OnReset() { setSatisfied(FALSE); } //================================================================================================== // CHANGES: f110311.3L, AddSatisfiedPlayer processing replacement #if SUN_CODE_BACKUP class AddSatisfiedPlayer { private: Trigger* m_pTrigger; bool m_bEnterPlayersMismatched; WORD m_NumberOfPlayers; PlayerManager* m_pPlayerMgr; public: AddSatisfiedPlayer(Trigger* pTrigger) : m_pTrigger(pTrigger) , m_bEnterPlayersMismatched(false) , m_NumberOfPlayers(0) { m_pPlayerMgr = PlayerManager::Instance(); } inline bool IsEnterPlayersMismatched() const { return m_bEnterPlayersMismatched; } inline WORD GetNumberOfPlayers() const { return m_NumberOfPlayers; } bool ProcessCheckAndAdd(TriggerPlayerLink* link) { if(link->IsValidState() == 0) { m_bEnterPlayersMismatched = true; return false; } ns_trigger::TriggerPlayerLinkInGame* item = static_cast(link); if(FlowControl::FCAssert(item->player_ != 0)) m_pTrigger->AddSatisfiedPlayer(item->player_); ++m_NumberOfPlayers; return true; } }; #endif //-------------------------------------------------------------------------------------------------- __IMPL_POOL(CONDITION_ENTER_AREA); VOID CONDITION_ENTER_AREA::OnInit() { getParent()->RemoveAllSatisfiedPlayer(); } VOID CONDITION_ENTER_AREA::OnReset() { getParent()->RemoveAllSatisfiedPlayer(); setSatisfied(FALSE); } BOOL CONDITION_ENTER_AREA::IsSatisfied() { if(satisfied_) return TRUE; const CONDITION_ENTER_AREA_INFO& rInfo = *Get(); int areaID = rInfo.GetAreaID(); BOOL need_process = FALSE; TriggerManagerEx* pTriggerManager = getMGR(); TriggerArea* pArea = pTriggerManager->GetAreaManager()->FindArea(areaID); if(pArea == 0) return FALSE; const DWORD number_of_entered = pArea->GetPlayerNumber(); //pTriggerManager->GetPlayerNumForAreaID(areaID); if(rInfo.GetIsParty() == 0) { const DWORD number_of_players = (DWORD)rInfo.GetPlayerCount(); bool is_accepted = number_of_players ? number_of_entered >= number_of_players : number_of_entered == number_of_players; if(is_accepted) { // Á¶°Ç¿¡ ¸¸Á·ÇÑ´Ù. Ç÷¹À̾îÀÇ À¯È¿¼º üũ. À¯È¿ÇÏÁö ¾Ê´Â´Ù¸é, Ç÷¹À̾î Á¦°Å need_process = TRUE; } } else { // Party if(number_of_entered) // 1¸í ÀÌ»óÀ¸·Î Æò°¡ need_process = TRUE; } if (need_process == false) { return satisfied_; }; // // CHANGES: f110311.3L, AddSatisfiedPlayer processing replacement class AdderIfExistSatisfiedConditionPlayer : public TriggerAreaLinkForeachFunctor { public: AdderIfExistSatisfiedConditionPlayer( const TriggerAreaManager* trigger_area_manager, Trigger* trigger, int area_id) : trigger_area_manager_(trigger_area_manager) , trigger_(trigger) , area_id_(area_id) , mismatched_enter_player_(false) , number_of_players_(0) { } bool Process() { TriggerArea* trigger_area = trigger_area_manager_->FindArea(area_id_); if (trigger_area == NULL) { return false; } trigger_area->Foreach(this); return true; } virtual TriggerAreaLinkForeachFunctor::eControl ProcessNode(const TriggerPlayerLink* trigger_player_link) const { if (trigger_player_link->IsValidState() == false) { mismatched_enter_player_ = true; return this->eStop; } const ns_trigger::TriggerPlayerLinkInGame* link_item = static_cast(trigger_player_link); if (FlowControl::FCAssert(link_item->player_ != NULL)) { trigger_->AddSatisfiedPlayer(link_item->player_); }; ++number_of_players_; // return this->eContinue; }; //private: const TriggerAreaManager* const trigger_area_manager_; Trigger* const trigger_; const int area_id_; mutable bool mismatched_enter_player_; mutable int number_of_players_; } functor(getMGR()->GetAreaManager(), getParent(), areaID); if (functor.Process() == false) { return satisfied_; } if (functor.mismatched_enter_player_ == false) { // success // NOTE: refactoring history. f090831.x, f110311.3L uint16_t new_updated = static_cast(functor.number_of_players_); if (local_storage_.last_updated_number_of_chars_ < new_updated) { local_storage_.last_updated_number_of_chars_ = new_updated; functor.trigger_->NeedActionByRuntimeConfig(); }; setSatisfied(true); }; // return satisfied_; } VOID CONDITION_ENTER_AREA::onMsg(TRIGGER_MSG* pmsg) { switch(pmsg->m_dwMsgID) { case eTRIGGER_ENTER_AREA: { TRIGGER_ENTER_AREA* pMsg = (TRIGGER_ENTER_AREA *)pmsg; if(Get()->GetAreaID() == pMsg->m_AreaID) { IsSatisfied(); } } break; case eTRIGGER_LEAVE_AREA: { TRIGGER_LEAVE_AREA* pMsg = (TRIGGER_LEAVE_AREA *)pmsg; if(Get()->GetAreaID() == pMsg->m_AreaID) { IsSatisfied(); } } break; } } //////////////////////////////////////////////////////////////////////////////////////////////////// // _NA_002098_20110307_ADD_NPC_CONTROL_TRIGGER __IMPL_POOL(CONDITION_NPC_ENTER_AREA); void CONDITION_NPC_ENTER_AREA::OnInit() { setSatisfied(false); } void CONDITION_NPC_ENTER_AREA::OnReset() { setSatisfied(false); } BOOL CONDITION_NPC_ENTER_AREA::IsSatisfied() { if (satisfied_) { return true; } #ifdef _NA_002098_20110307_ADD_NPC_CONTROL_TRIGGER_BASE const CONDITION_NPC_ENTER_AREA_INFO& trigger_info = *Get(); const int area_id = trigger_info.GetAreaID(); TriggerManagerEx* const trigger_manager = getMGR(); TriggerAreaForNpc* const trigger_area = trigger_manager->GetAreaManagerForNpc()->FindArea(area_id); if (trigger_area == NULL) { return false; } const DWORD number_of_entered = trigger_area->GetNpcNumber(); bool need_process = (number_of_entered != 0); if (need_process == false) { return satisfied_; }; // // success // NOTE: reference from 'CONDITION_ENTER_AREA: f110311.3L' uint16_t new_updated = static_cast(number_of_entered); if (local_storage_.last_updated_number_of_chars_ < new_updated) { local_storage_.last_updated_number_of_chars_ = new_updated; if (Trigger* trigger = getParent()) { trigger->NeedActionByRuntimeConfig(); }; setSatisfied(true); }; // #endif //_NA_002098_20110307_ADD_NPC_CONTROL_TRIGGER_BASE return satisfied_; } void CONDITION_NPC_ENTER_AREA::onMsg(TRIGGER_MSG* trigger_msg) { // NOTE: f110318.2L, an area event message for npc is prefetched // by trigger initialization evnets. so that this method don't test the unit identification. const eTRIGGER_MSG msg_type = static_cast(trigger_msg->m_dwMsgID); switch (msg_type) { case eTRIGGER_NPC_ENTER_AREA: { const TRIGGER_NPC_ENTER_AREA* const enter_msg = static_cast(trigger_msg); const CONDITION_NPC_ENTER_AREA_INFO& trigger_info = *Get(); if (trigger_info.GetAreaID() == enter_msg->area_id) { this->IsSatisfied(); } }; break; case eTRIGGER_NPC_LEAVE_AREA: { const TRIGGER_NPC_LEAVE_AREA* const leave_msg = static_cast(trigger_msg); const CONDITION_NPC_ENTER_AREA_INFO& trigger_info = *Get(); if (trigger_info.GetAreaID() == leave_msg->area_id) { this->IsSatisfied(); } }; break; }; } //================================================================================================== class HaveItemPlayer { private: SLOTCODE m_ItemCode; int m_Count; BOOL is_satisfied_; Trigger* parent_trigger_; public: HaveItemPlayer(SLOTCODE itemCode, int count, Trigger* parent): is_satisfied_(FALSE), m_ItemCode(itemCode), m_Count(count), parent_trigger_(parent) {} ~HaveItemPlayer() {} BOOL Process(SATISFIED_PLAYER_PAIR rPair) { Player* pPlayer = rPair.second; ItemManager* pItemManager = pPlayer->GetItemManager(); is_satisfied_ = (pItemManager->ExistItem(SI_INVENTORY, m_ItemCode, m_Count) == m_Count); if (is_satisfied_ == FALSE) { parent_trigger_->CheckUnsatisfiedPlayer(pPlayer->GetObjectKey()); } return is_satisfied_; } }; __IMPL_POOL(CONDITION_HAVE_ITEM) VOID CONDITION_HAVE_ITEM::OnInit() { m_dwCheckTimer = GetTickCount(); } BOOL CONDITION_HAVE_ITEM::IsSatisfied() { if(satisfied_) return TRUE; DWORD cur_tick = GetTickCount(); if(m_dwCheckTimer + CONDITION_HAVE_ITEM::c_dwDelayCheckTime <= cur_tick) { m_dwCheckTimer = cur_tick; const CONDITION_HAVE_ITEM_INFO& rInfo = *Get(); // ¿©·¯»ç¶÷ÀÏ °æ¿ì°¡ ¾øÁö¸¸ ¿µ¿ª¿¡ µé¾î¿Â »ç¶÷°ú Ŭ¸¯ÇÑ »ç¶÷À» ÀúÀå DWORD clicked_player_key = getParent()->GetClickedPlayerKey(); int number_of_items = rInfo.GetItemNum(); int item_code = rInfo.GetItemCode(); // µÑ Áß Çϳª if(clicked_player_key) { Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(pPlayer) { BOOLEAN satisfied = number_of_items == pPlayer->GetItemManager()->ExistItem(SI_INVENTORY, item_code, number_of_items); if(satisfied) { setSatisfied(TRUE); return TRUE; } } } else { //_NA_008069_20150210_ADD_SPA_SYSTEM HaveItemPlayer op(item_code, number_of_items, getParent()); getParent()->ForeachSatisfiedPlayer(&HaveItemPlayer::Process, &op); setSatisfied(TRUE); } } return satisfied_; } //_NA_008069_20150210_ADD_SPA_SYSTEM VOID CONDITION_HAVE_ITEM::OnReset() { setSatisfied(false); } //================================================================================================== __IMPL_POOL(CONDITION_MULTI_SWITCH) BOOL CONDITION_MULTI_SWITCH::IsSatisfied() { if(satisfied_) return TRUE; CONDITION_MULTI_SWITCH_INFO& rInfo = *Get(); TriggerManagerEx* pTriggerManager = getMGR(); // (WAVERIX) (090621) (CHANGES) less_than, more_than È¿À²º¸´Ù´Â °¡µ¶¼º ¼±Åà int satisfiedCount = 0; for(DWORD idx = 0; idx < rInfo._MAX_SWITCH_ID_NUM; ++idx) { BYTE switchID = rInfo.GetSwitchID((WORD)idx); if(INVALID_SWITCH_ID_VALUE == switchID) continue; const int curr_value = (int)pTriggerManager->GetSwitchValue(switchID); const int cond_value = rInfo.GetValue1(); switch(rInfo.GetOperationType1()) { case eCOMPARE_EQUAL: if(curr_value == cond_value) ++satisfiedCount; break; case eCOMPARE_MORE: if(curr_value > cond_value) ++satisfiedCount; break; case eCOMPARE_LESS: if(curr_value < cond_value) ++satisfiedCount; break; case eCOMPARE_LESSTHAN: if(curr_value <= cond_value) ++satisfiedCount; break; case eCOMPARE_MORETHAN: if(curr_value >= cond_value) ++satisfiedCount; break; case eCOMPARE_NOTEQUAL: if(curr_value != cond_value) ++satisfiedCount; break; default: __debugbreak(); break; } } BOOL bSatisfied = FALSE; const int cond_count = rInfo.GetValue2(); switch(rInfo.GetOperationType2()) { case eCOMPARE_EQUAL: bSatisfied = (satisfiedCount == cond_count); break; case eCOMPARE_MORE: bSatisfied = (satisfiedCount > cond_count); break; case eCOMPARE_LESS: bSatisfied = (satisfiedCount < cond_count); break; case eCOMPARE_LESSTHAN: bSatisfied = (satisfiedCount <= cond_count); break; case eCOMPARE_MORETHAN: bSatisfied = (satisfiedCount >= cond_count); break; case eCOMPARE_NOTEQUAL: bSatisfied = (satisfiedCount != cond_count); break; default: __debugbreak(); break; } if(bSatisfied) setSatisfied(bSatisfied); DEBUG_CODE( if(satisfied_) SUNLOG(eFULL_LOG, "["__FUNCTION__"] [ID:%u]:TriggerMultiSwitchCondition", getParent()->TriggerID()); ); return satisfied_; } //================================================================================================== __IMPL_POOL(CONDITION_MISSION_POINT) VOID CONDITION_MISSION_POINT::OnInit() { //m_iNumberOfPlayersInArea = 0; } VOID CONDITION_MISSION_POINT::onMsg(TRIGGER_MSG* pmsg) { if(eTRIGGER_ENTER_AREA == pmsg->m_dwMsgID) { TRIGGER_ENTER_AREA* pMsg = (TRIGGER_ENTER_AREA*)pmsg; // ½ÇÁ¦ Ç÷¹À̾ ÀÌ ¿µ¿ª¿¡ Àִ°¡? Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(pMsg->m_PlayerKey); if(pPlayer == 0 || pPlayer->GetField() == 0) return; GameZone* pGameZone = pPlayer->GetGameZonePtr(); int iMapCode = pGameZone ? (int)pGameZone->GetMapCode() : -1; if(SAFE_NUMERIC_TYPECAST(int, iMapCode, BYTE)) { const CONDITION_MISSION_POINT_INFO& rInfo = *Get(); const int iMissionPoint = pPlayer->GetMissionManager()->GetMissionPoint((BYTE)iMapCode); const int cond_mission_point = rInfo.GetMissionPoint(); switch(rInfo.GetFlag()) { case eCOMPARE_EQUAL: setSatisfied(iMissionPoint == cond_mission_point); break; case eCOMPARE_MORE: setSatisfied(iMissionPoint > cond_mission_point); break; case eCOMPARE_LESS: setSatisfied(iMissionPoint < cond_mission_point); break; default: __debugbreak(); break; } } } } //================================================================================================== __IMPL_POOL(CONDITION_COMPARE_VARIABLE) BOOL CONDITION_COMPARE_VARIABLE::IsSatisfied() { return FALSE; } //================================================================================================== // #include #include class QuestProgress { BOOL& m_bOrRet; QCODE m_wQuestCode; CONDITION_QUEST_PROGRESS_INFO::ePROGRESS m_eCond; public: QuestProgress(BOOL& bOrRet, QCODE wQuestCode, CONDITION_QUEST_PROGRESS_INFO::ePROGRESS iCond) : m_bOrRet(bOrRet), m_wQuestCode(wQuestCode), m_eCond(iCond) {} VOID operator()(Player* pPlayer) { QuestManager* pQuestMan = (QuestManager*)pPlayer->GetQuestManager(); Quest* pQuest = NULL; switch(m_eCond) { case CONDITION_QUEST_PROGRESS_INFO::IN_PROGRESS: if(pQuestMan->FindQuest(m_wQuestCode)) m_bOrRet = TRUE; break; case CONDITION_QUEST_PROGRESS_INFO::COMPLETED: if(pQuestMan->FindComplQuest(m_wQuestCode)) m_bOrRet = TRUE; break; }; } VOID Check(SATISFIED_PLAYER_PAIR rPair) { Player* pPlayer = rPair.second; QuestManager* pQuestMan = (QuestManager*)pPlayer->GetQuestManager(); Quest* pQuest = NULL; switch(m_eCond) { case CONDITION_QUEST_PROGRESS_INFO::IN_PROGRESS: if(pQuestMan->FindQuest(m_wQuestCode)) m_bOrRet = TRUE; break; case CONDITION_QUEST_PROGRESS_INFO::COMPLETED: if(pQuestMan->FindComplQuest(m_wQuestCode)) m_bOrRet = TRUE; break; }; } }; //-------------------------------------------------------------------------------------------------- __IMPL_POOL(CONDITION_QUEST_PROGRESS) BOOL CONDITION_QUEST_PROGRESS::IsSatisfied() { if(satisfied_) return TRUE; const CONDITION_QUEST_PROGRESS_INFO* pInfo = (const CONDITION_QUEST_PROGRESS_INFO*)Get(); ASSERT(SAFE_NUMERIC_TYPECAST(ULONG, pInfo->GetQuestID(), QCODE)); BOOL bOrRet = FALSE; QuestProgress op(bOrRet, (QCODE)pInfo->GetQuestID(), (CONDITION_QUEST_PROGRESS_INFO::ePROGRESS)pInfo->GetProgress()); DWORD clicked_player_key = getParent()->GetClickedPlayerKey(); if(clicked_player_key != 0) { Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(pPlayer != 0) { op(pPlayer); if(bOrRet) setSatisfied(TRUE); } } else { getParent()->ForeachSatisfiedPlayer(&QuestProgress::Check, &op); if(bOrRet) setSatisfied(TRUE); } return satisfied_; } //================================================================================================== class CheckClassID { BOOL& m_bOrRet; eCHAR_TYPE m_CharType; public: CheckClassID(BOOL& bOrRet, eCHAR_TYPE eCharType) : m_bOrRet(bOrRet), m_CharType(eCharType) {} VOID operator() (Player* pPlayer) { if(pPlayer->GetCharType() == m_CharType) m_bOrRet = TRUE; } VOID Check(SATISFIED_PLAYER_PAIR rPair) { Player* pPlayer = rPair.second; if(pPlayer->GetCharType() == m_CharType) m_bOrRet = TRUE; } }; //-------------------------------------------------------------------------------------------------- __IMPL_POOL(CONDITION_CHECK_CLASS_ID) BOOL CONDITION_CHECK_CLASS_ID::IsSatisfied() { if(satisfied_) return TRUE; const CONDITION_CHECK_CLASS_ID_INFO* pInfo = (const CONDITION_CHECK_CLASS_ID_INFO*)Get(); const DWORD clicked_player_key = getParent()->GetClickedPlayerKey(); if(clicked_player_key) { Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(NULL != pPlayer) { // (WAVERIX) (060606) // ÀÏ´ÜÀº Á¶°ÇÀ¸·Î ÁÖ¾îÁø Class ID°¡ eCHAR_TYPE°ú ÀÏÄ¡ÇÑ´Ù. // ÀÌÈĸ¦ À§ÇØ ±âȹÂÊ¿¡ À̰ÍÀÇ º¯°æÀÌ ¾øµµ·Ï ¿äûÇÒ °Í. eCHAR_TYPE eClass = (eCHAR_TYPE)pInfo->GetClassID(); if(pPlayer->GetCharType() == eClass) setSatisfied(TRUE); } } else { // ÆÄƼ´Â Æ÷ÇÔµÇÁö ¾Ê´Â´Ù. BOOL bOrRet = FALSE; CheckClassID op(bOrRet, (eCHAR_TYPE)pInfo->GetClassID()); getParent()->ForeachSatisfiedPlayer(&CheckClassID::Check, &op); if(bOrRet) setSatisfied(TRUE); } return satisfied_; } //================================================================================================== __IMPL_POOL(CONDITION_NPCKILL_FOR_UNITID) VOID CONDITION_NPCKILL_FOR_UNITID::onMsg(TRIGGER_MSG* pmsg) { switch(pmsg->m_dwMsgID) { case eTRIGGER_KILL_MONSTER: { TRIGGER_KILL_MONSTER* pMsg = (TRIGGER_KILL_MONSTER*)pmsg; CONDITION_NPCKILL_FOR_UNITID_INFO* pInfo = Get(); if(pMsg->m_MonsterUnitID != pInfo->GetMonsterUnitID()) return; //------------------------ // Á¶°Ç ¸¸Á· setSatisfied(TRUE); DEBUG_CODE( SUNLOG(eFULL_LOG, "[CONDITION_NPCKILL_FOR_UNITID::onMsg] [ID:%u]:MONSTER:[%u]", getParent()->TriggerID(), pInfo->GetMonsterUnitID()); ); //------------------------ } break; } } //================================================================================================== class CheckPartyMember { BOOL& m_bAndRet; BYTE m_byLiveFlag; public: CheckPartyMember(BOOL& bAndRet, BYTE byLiveFlag) : m_bAndRet(bAndRet), m_byLiveFlag(byLiveFlag) {} VOID operator()(Player* pPlayer) { if(m_bAndRet && pPlayer) m_bAndRet = CheckMember(pPlayer); } VOID operator()(std::pair pair_type) { operator()(pair_type.second); } BOOL CheckMember(Player* pPlayer) { switch(m_byLiveFlag) { // »ýÁ¸ : 1ÀÎÀÌ¶óµµ »ýÁ¸ ½Ã TRUE case CONDITION_LIVE_PARTY_MEMBER_INFO::MEMBER_LIVE: return pPlayer->IsAlive(); //»ç¸Á : Àü¿ø »ç¸ÁÀÏ ½Ã TRUE case CONDITION_LIVE_PARTY_MEMBER_INFO::MEMBER_DIE: return !(pPlayer->IsAlive()); } return FALSE; } }; //-------------------------------------------------------------------------------------------------- __IMPL_POOL(CONDITION_LIVE_PARTY_MEMBER) BOOL CONDITION_LIVE_PARTY_MEMBER::IsSatisfied() { if(satisfied_) return TRUE; const CONDITION_LIVE_PARTY_MEMBER_INFO* pInfo = (const CONDITION_LIVE_PARTY_MEMBER_INFO*)Get(); BOOL and_result = TRUE; CheckPartyMember opr(and_result, pInfo->GetLiveFlag()); getMGR()->ForeachPlayer(opr); if(and_result) setSatisfied(TRUE); return satisfied_; } //================================================================================================== __IMPL_POOL(CONDITION_CHECK_OBJECT_HP) VOID CONDITION_CHECK_OBJECT_HP::OnInit() { m_dwStartTick = GetTickCount(); } BOOL CONDITION_CHECK_OBJECT_HP::IsSatisfied() { if(satisfied_) return TRUE; if((m_dwStartTick + CONDITION_DELEY) <= GetTickCount()) { const CONDITION_CHECK_OBJECT_HP_INFO* pInfo = (const CONDITION_CHECK_OBJECT_HP_INFO*)Get(); const DWORD dwObjKey = pInfo->GetdwObjKey(); const MapNpc* pMapNpc = getMGR()->FindMapNpc(dwObjKey); if (NULL != pMapNpc) { const FLOAT infoHP = (FLOAT)pInfo->GetbtHPPercentage(); const FLOAT mapNpcHP = pMapNpc->GetHPRatio()*100.0f; if (infoHP > mapNpcHP) setSatisfied(TRUE); } m_dwStartTick = GetTickCount(); } return satisfied_; } __IMPL_POOL(CONDITION_DESTROY_OBJECT) VOID CONDITION_DESTROY_OBJECT::OnInit() { m_dwStartTick = GetTickCount(); } BOOL CONDITION_DESTROY_OBJECT::IsSatisfied() { if(satisfied_) return TRUE; if((m_dwStartTick + CONDITION_DELEY) <= GetTickCount()) { const CONDITION_DESTROY_OBJECT_INFO* pInfo = (const CONDITION_DESTROY_OBJECT_INFO*)Get(); const DWORD dwObjKey = pInfo->GetdwObjKey(); if (0 != dwObjKey) { const MapNpc* pMapNpc = getMGR()->FindMapNpc(dwObjKey); if (NULL != pMapNpc && pMapNpc->IsDead()) setSatisfied(TRUE); } m_dwStartTick = GetTickCount(); } return satisfied_; } __IMPL_POOL(CONDITION_CHECK_OBJECTKIND_HP) VOID CONDITION_CHECK_OBJECTKIND_HP::OnInit() { start_tick_ = GetTickCount(); } BOOL CONDITION_CHECK_OBJECTKIND_HP::IsSatisfied() { if(satisfied_) return TRUE; if((start_tick_ + CONDITION_DELEY) <= GetTickCount()) { const CONDITION_CHECK_OBJECTKIND_HP_INFO* info = Get(); const BYTE object_type = info->GetbyObjectType(); const DWORD object_key = info->GetdwObjectKey(); NPC* npc = NULL; switch (object_type) { case UNITID_TYPE: npc = getMGR()->FindNPCForUnitID(object_key); break; case MAPNPC_TYPE: npc = getMGR()->FindMapNpc(object_key); break; default: break; } if (npc != NULL) { const FLOAT info_HP = static_cast(info->GetbtHPPercentage()); const FLOAT npc_HP = npc->GetHPRatio()*100.0f; if (info_HP >= npc_HP) { setSatisfied(TRUE); getParent()->SetObjectKey(npc->GetObjectKey()); } } start_tick_ = GetTickCount(); } return satisfied_; } //////////////////////////////////////////////////////////////////////////////////////////////////// // _NA_004777_20120428_ADD_COMPLETE_COLLECTION_TRIGGER __IMPL_POOL(CONDITION_COMPLETE_COLLECTION); void CONDITION_COMPLETE_COLLECTION::OnInit() { setSatisfied(false); } void CONDITION_COMPLETE_COLLECTION::OnReset() { setSatisfied(false); } BOOL CONDITION_COMPLETE_COLLECTION::IsSatisfied() { if (satisfied_) { return true; } return satisfied_; } void CONDITION_COMPLETE_COLLECTION::onMsg(TRIGGER_MSG* trigger_msg) { if (trigger_msg == NULL) { return; } const eTRIGGER_MSG msg_type = static_cast(trigger_msg->m_dwMsgID); if (msg_type == eTRIGGER_COMPLETE_COLLECTION) { const TRIGGER_COMPLETE_COLLECTION* const msg = static_cast(trigger_msg); const CONDITION_COMPLETE_COLLECTION_INFO& info = *Get(); if (MAP_OBJECT_KEY + info.GetObjectKey() == msg->object_key) { setSatisfied(true); } } } //////////////////////////////////////////////////////////////////////////////////////////////////// // _NA_000000_20130103_ADD_SERVER_EVENT_TRIGGER __IMPL_POOL(CONDITION_SERVER_EVENT); void CONDITION_SERVER_EVENT::OnInit() { setSatisfied(false); } void CONDITION_SERVER_EVENT::OnReset() { setSatisfied(false); } BOOL CONDITION_SERVER_EVENT::IsSatisfied() { if (satisfied_) { return true; } return satisfied_; } void CONDITION_SERVER_EVENT::onMsg(TRIGGER_MSG* trigger_msg) { if (trigger_msg == NULL) { return; } const eTRIGGER_MSG msg_type = static_cast(trigger_msg->m_dwMsgID); if (msg_type == eTRIGGER_SERVER_EVENT) { const TRIGGER_SERVER_EVENT* const msg = static_cast(trigger_msg); const CONDITION_SERVER_EVENT_INFO& server_event_info = *Get(); if (server_event_info.GetEventID() == msg->event_id) { setSatisfied(true); } } } //////////////////////////////////////////////////////////////////////////////////////////////////// // _NA_000000_20130104_ADD_CONDITION_TRIGGER_CHECK_TEAM class CheckTeam { BOOL& is_satisfied_; int team_key_; public: CheckTeam(BOOL& is_satisfied, int team_key) : is_satisfied_(is_satisfied), team_key_(team_key) { } VOID operator() (Player* const player) { if(player->GetTeamKey() == team_key_) is_satisfied_ = TRUE; } VOID Check(SATISFIED_PLAYER_PAIR rPair) { Player* const player = rPair.second; if(player->GetTeamKey() == team_key_) is_satisfied_ = TRUE; } }; __IMPL_POOL(CONDITION_CHECK_TEAM); BOOL CONDITION_CHECK_TEAM::IsSatisfied() { if (satisfied_) return true; const CONDITION_CHECK_TEAM_INFO* const check_team_info = (const CONDITION_CHECK_TEAM_INFO*)Get(); const DWORD clicked_player_key = getParent()->GetClickedPlayerKey(); if(clicked_player_key) { const Player* const player = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(NULL != player) { // (WAVERIX) (060606) // ÀÏ´ÜÀº Á¶°ÇÀ¸·Î ÁÖ¾îÁø Class ID°¡ eCHAR_TYPE°ú ÀÏÄ¡ÇÑ´Ù. // ÀÌÈĸ¦ À§ÇØ ±âȹÂÊ¿¡ À̰ÍÀÇ º¯°æÀÌ ¾øµµ·Ï ¿äûÇÒ °Í. const int team_key = check_team_info->GetTeamKey(); if(player->GetTeamKey() == team_key) setSatisfied(TRUE); } } else { BOOL is_result = FALSE; CheckTeam op(is_result, (int)check_team_info->GetTeamKey()); getParent()->ForeachSatisfiedPlayer(&CheckTeam::Check, &op); if(is_result) setSatisfied(TRUE); } return satisfied_; } __IMPL_POOL(CONDITION_MONSTER_ENTER_AREA); void CONDITION_MONSTER_ENTER_AREA::onMsg( TRIGGER_MSG* trigger_msg ) { const eTRIGGER_MSG msg_type = static_cast(trigger_msg->m_dwMsgID); switch (msg_type) { case eTRIGGER_NPC_ENTER_AREA: { const TRIGGER_NPC_ENTER_AREA* const enter_msg = static_cast(trigger_msg); const CONDITION_MONSTER_ENTER_AREA_INFO& trigger_info = *Get(); NPC* const npc = getMGR()->FindNPC(enter_msg->object_key); if (npc == NULL) return; if (trigger_info.GetAreaID() == enter_msg->area_id && trigger_info.GetMonsterCode() == npc->GetBaseInfo()->m_MonsterCode) { bool satisfied = satisfied_; if (this->IsSatisfied() != satisfied) { getParent()->SetObjectKey(enter_msg->object_key); } } }; break; case eTRIGGER_NPC_LEAVE_AREA: { const TRIGGER_NPC_LEAVE_AREA* const leave_msg = static_cast(trigger_msg); const CONDITION_MONSTER_ENTER_AREA_INFO& trigger_info = *Get(); // to do }; break; }; } BOOL CONDITION_MONSTER_ENTER_AREA::IsSatisfied() { if (satisfied_) { return true; } const CONDITION_MONSTER_ENTER_AREA_INFO& trigger_info = *Get(); const int area_id = trigger_info.GetAreaID(); TriggerManagerEx* const trigger_manager = getMGR(); TriggerAreaForNpc* const trigger_area = trigger_manager->GetAreaManagerForNpc()->FindArea(area_id); if (trigger_area == NULL) { return false; } const DWORD number_of_entered = trigger_area->GetNpcNumber(); bool need_process = (number_of_entered != 0); if (need_process == false) { return satisfied_; }; // uint16_t new_updated = static_cast(number_of_entered); if (local_storage_.last_updated_number_of_chars_ < new_updated) { local_storage_.last_updated_number_of_chars_ = new_updated; if (Trigger* trigger = getParent()) { trigger->NeedActionByRuntimeConfig(); }; setSatisfied(true); }; // return satisfied_; } void CONDITION_MONSTER_ENTER_AREA::OnInit() { setSatisfied(false); } void CONDITION_MONSTER_ENTER_AREA::OnReset() { setSatisfied(false); }