#include "stdafx.h" #include "./ActionTriggers.h" //================================================================================================== #include #include #include <3DEngine/Common/MathAssistant.h> #include #include #include #include #include #include #include #include "..\\..\\SolarTrigger\\ActionInfo.h" #include "TriggerManagerEx.h" #include "./Trigger.h" #include "./Player.h" #include #include #include "./Map.h" #include "GameZone.h" #include "MovingPlanner.h" #include "ItemManager.h" #include "./MissionManager.h" #include "./MissionRewardManager.h" // ¹üÀ§ µ¥¹ÌÁö À§ÇØ #include "MapObject.h" #include "DropManager.h" // ¹æÇâ ÁöÁ¤ ¸ó½ºÅÍ ¸®Á¨ À§ÇØ #include "PacketHandler//Handler_CG_SYNC.h" #include "GameParty/NewGameParty.h" #include "GameParty/NewGamePartyManager.h" #include "StatusManager.h" #include "GameField.h" #include "SkillAttrCalculator.h" #include "GameDominationField.h" #include "AITypes.h" #include "TargetManager.h" #ifdef _NA_003649_20111115_BATTLE_ZONE_HARDMODE #include "NPCReplaceInfoParser.h" #endif #include "CollectionStateInfo.h" #include "CollectionManager.h" #include "Collection.h" #include "SummonManager.h" #include "SummonedNPCs.h" #include "Summoned.h" #ifdef _NA_006826_20130722_DOMINATION_RENEWAL #include "GameGuild.h" #include "GameGuildManager.h" #endif _NA_006826_20130722_DOMINATION_RENEWAL #include "GameMissionRoom.h" #ifdef _NA_007907_20141222_MODIFY_MONSTER_MOVE_TRIGGER #include "NPCStateManager.h" #endif // _NA_007907_20141222_MODIFY_MONSTER_MOVE_TRIGGER //================================================================================================== __IMPL_POOL(ACTION_CHANGE_OBJECTANI) void ACTION_CHANGE_OBJECTANI::OnAction() { WzID triggerID = getParent()->TriggerID(); getMGR()->MAP_STATE.Change(triggerID); #ifdef __TRIGGER_TEST_LOG SUNLOG(eDEV_LOG, _T("[TriggerID:%u]:ACTION_CHANGE_OBJECTANI"), triggerID); #endif } //================================================================================================== __IMPL_POOL(ACTION_CHANGE_PATHTILE) void ACTION_CHANGE_PATHTILE::OnInit() { } void ACTION_CHANGE_PATHTILE::OnAction() { const ACTION_CHANGE_PATHTILE_INFO* pInfo = Get(); const BYTE attribute = pInfo->GetAttribute(); TriggerManagerEx* pTriggerManager = getMGR(); if(attribute == ns_trigger::CANMOVE) pTriggerManager->UnsetAttribute(pInfo->GetTileID(), PTA_NO_WALK); if(attribute == ns_trigger::CANNOTMOVE) pTriggerManager->SetAttribute(pInfo->GetTileID(), PTA_NO_WALK); pTriggerManager->MAP_STATE.Change(getParent()->TriggerID()); #ifdef __TRIGGER_TEST_LOG SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_CHANGE_PATHTILE", getParent()->TriggerID()); #endif } //================================================================================================== __IMPL_POOL(ACTION_CHANGE_OBJECTSTATE) void ACTION_CHANGE_OBJECTSTATE::OnAction() { const ACTION_CHANGE_OBJECTSTATE_INFO* pInfo = Get(); int object_id = pInfo->GetObjectID(); MapObject* pMapObject = getMGR()->FindMapObject(object_id); DEBUG_CODE(if(!pMapObject) return ;); switch(pInfo->GetState()) { case ACTION_CHANGE_OBJECTSTATE_INFO::APPEAR: { } break; case ACTION_CHANGE_OBJECTSTATE_INFO::DISAPPEAR: { } break; case ACTION_CHANGE_OBJECTSTATE_INFO::REMOVE: { SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] [ID:%u]:ACTION_CHANGE_OBJECTSTATE is Failed!!", getParent()->TriggerID()); } break; } getMGR()->MAP_STATE.Change(getParent()->TriggerID()); #ifdef __TRIGGER_TEST_LOG SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_CHANGE_OBJECTSTATE", getParent()->TriggerID()); #endif } //================================================================================================== __IMPL_POOL(ACTION_PLAY_EVENT) void ACTION_PLAY_EVENT::OnAction() { // À̺¥Æ®¸¦ Ç÷¹ÀÌÇ϶ó°í ¾Ë·Á¶ó! DWORD clicked_player_key = getParent()->GetClickedPlayerKey(); Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(pPlayer == 0) { SUNLOG(eFULL_LOG, "[ACTION_PLAY_EVENT::OnAction] [U:%d]Player NULL!!", clicked_player_key); return; } #if SUN_CODE_BACKUP // (f100721.2L) remove code //MSG_CG_TRIGGER_PLAY_EVENT_CMD msg; //msg.m_nEventIndex = Get()->GetEventID(); //pPlayer->SendPacket(&msg, sizeof(msg)); // (f100721.2L) add routine to present a cinematic effect getMGR()->MAP_STATE.Change(getParent()->TriggerID()); #endif #ifdef __TRIGGER_TEST_LOG SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_PLAY_EVENT", getParent()->TriggerID()); #endif } //================================================================================================== class ActionSetAttack { public: BYTE m_byTargetType; BOOL m_bAttack; ActionSetAttack(BYTE byTargetType, BOOL bAttack) : m_byTargetType(byTargetType), m_bAttack(bAttack) {} void operator()(Player* pPlayer) { // (WAVERIX) (090614) pStatusManager->RemoveÀÇ »ç¿ëÀº Á» °í¹ÎÇØºÁ¾ß ÇÒ µí ... StatusManager* pStatusManager = pPlayer->GetStatusManager(); if(m_byTargetType == ACTION_SET_ISATTACK_INFO::TARGET_TYPE_USER || m_byTargetType == ACTION_SET_ISATTACK_INFO::TARGET_TYPE_ALL) { if(m_bAttack == ACTION_SET_ISATTACK_INFO::CAN_NOT_ATTACK) pStatusManager->AllocStatus(eCHAR_STATE_ETC_DISABLE_VISION_TRIGGER); else pStatusManager->Remove(eCHAR_STATE_ETC_DISABLE_VISION_TRIGGER); } if(m_byTargetType == ACTION_SET_ISATTACK_INFO::TARGET_TYPE_MONSTER || m_byTargetType == ACTION_SET_ISATTACK_INFO::TARGET_TYPE_ALL) { if(m_bAttack == ACTION_SET_ISATTACK_INFO::CAN_NOT_ATTACK) pStatusManager->AllocStatus(eCHAR_STATE_BLUR_TRIGGER); else pStatusManager->Remove(eCHAR_STATE_BLUR_TRIGGER); } } void SetAttack(SATISFIED_PLAYER_PAIR rPair) { operator()(rPair.second); } }; //================================================================================================== // ƯÁ¤ À¯Àú(A)¸¦ ´ë»óÀ¸·Î A°¡ ´Ù¸¥ °´Ã¼ B¸¦ °ø°Ý ÇÒ¼ö ¾øµµ·Ï ¸¸µé°Å³ª, // B °´Ã¼·Î ºÎÅÍ °ø°Ý ´çÇÏÁö ¾Ê°Ô ¸¸µç´Ù. __IMPL_POOL(ACTION_SET_ISATTACK) void ACTION_SET_ISATTACK::OnAction() { const ACTION_SET_ISATTACK_INFO* pInfo = Get(); ActionSetAttack op(pInfo->GetTargetType(), pInfo->GetIsAttack()); Trigger* pTrigger = getParent(); if(DWORD clicked_player_key = pTrigger->GetClickedPlayerKey()) { // pPlayer == 0ÀÎ Á¶°ÇÀÌ »ý±æ ¼ö ÀÖ´Ù. Á¶°Ç Ãß°¡ÇÑ´Ù. if(Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key)) op(pPlayer); } else { pTrigger->ForeachSatisfiedPlayer(&ActionSetAttack::SetAttack, &op); pTrigger->RemoveAllSatisfiedPlayer(); } #ifdef __TRIGGER_TEST_LOG SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_SET_ISATTACK", pTrigger->TriggerID()); #endif } //================================================================================================== class WARP_PLAYER { public: static void Warp(Player* pPlayer, MAPCODE enterFieldCode, WzID areaID) { GameZone* pZone = pPlayer->GetGameZonePtr(); if(pZone == 0) return; // (WAVERIX)(080610)(BUG-FIX) - ¼­¹ö °­Á¦ À̵¿½Ã (Á×Àº »óÅÂÀÏ °æ¿ì) ¹ß»ýµÇ´Â ¹®Á¦ ÇØ°á ¸ñÀû // - related info (080604) if(pPlayer->GetHP() == 0) pPlayer->SetHP(1); pZone->Warp(pPlayer, enterFieldCode, areaID); MSG_CG_TRIGGER_PORTAL_ACK msg; msg.m_LeaveType = msg.eLeaveType_Default; msg.m_MapCode = pZone->GetMapCode(); msg.m_FieldCode = enterFieldCode; msg.Encode(); pPlayer->SendPacket(&msg, sizeof(msg)); return; } }; class WarpControl { typedef GameField::_PLAYER_HASH GF_PLAYER_LIST; public: // Iterator ¹«°á¼º ¹®Á¦·Î ÀçÀÛ¼º static void WarpAllPlayer(GameField* const pField, const MAPCODE fieldCode, const WzID areaID) { const GF_PLAYER_LIST& rPlayers = pField->GetRefPlayerList(); GF_PLAYER_LIST::const_iterator it = rPlayers.begin(); while(it != rPlayers.end()) { Player* const pPlayer = it->second; ++it; // ¾Æ·¡ ÁÖ¼® ÂüÁ¶. if (obj_util::IsValid(pPlayer, __FUNCTION__, __LINE__) == false) { continue; } WARP_PLAYER::Warp(pPlayer, fieldCode, areaID); } /* // Àú À§¿¡¼­ ¸»ÇÑ iterator ¹«°á¼º ¹®Á¦¶õ.. // WARP_PLAYER::Warp(...); // => pZone->Warp(...); // ==> pEnterZone->LeaveForWarp(...); // ===> GameZone::Leave(...); // { // ... // m_PlayerHash.erase(it); <= À̰ж§¹®¿¡ for ¹®À» »ç¿ëÇÏ¸é ¾ÈµÊ. // } */ } }; class BackToTheVillage { public: void operator()(Player* pPlayer) { MSG_AG_ZONE_MISSION_LEAVE_CMD msg; msg.m_LeaveType = msg.eLeaveType_Default; msg.m_ReturnMapCode = 0; pPlayer->SendPacket(&msg, sizeof(msg)); } void operator()(std::pair pair_type) { operator()(pair_type.second); } }; //__NA001310_BATTLEZONE_PORTAL_RETURN_TARGET_MOVE_SUPPORT__ class ReturnToTargetStaticField { public: ReturnToTargetStaticField(MAPCODE returnMapCode, FIELDCODE enterFieldCode, WzID areaID) : m_ReturnMapCode(returnMapCode) , m_EnterFieldCode(enterFieldCode) , m_AreaID(areaID) {} ~ReturnToTargetStaticField() {} void operator()(Player* pPlayer) { pPlayer->SetStartMapCode(m_ReturnMapCode); { MSG_CG_TRIGGER_PORTAL_ACK msg; msg.m_LeaveType = msg.eLeaveType_Target; msg.m_MapCode = m_ReturnMapCode; msg.m_FieldCode = m_EnterFieldCode; msg.Encode(); pPlayer->SendPacket(&msg, sizeof(msg)); } { MSG_AG_ZONE_MISSION_LEAVE_CMD msg; msg.m_LeaveType = msg.eLeaveType_Target; msg.m_ReturnMapCode = m_ReturnMapCode; pPlayer->SendPacket(&msg, sizeof(msg)); } } void operator()(std::pair pair_type) { operator()(pair_type.second); } private: const MAPCODE m_ReturnMapCode; const FIELDCODE m_EnterFieldCode; const WzID m_AreaID; }; // class WarpPlayerForField { MAPCODE m_FieldCode; WzID m_AreaID; public: WarpPlayerForField(MAPCODE fieldCode, WzID areaID) : m_FieldCode(fieldCode),m_AreaID(areaID) {} ~WarpPlayerForField() {} void operator()(Player* pPlayer) { WARP_PLAYER::Warp(pPlayer, m_FieldCode, m_AreaID); } void operator()(std::pair pair_type) { operator()(pair_type.second); } }; __IMPL_POOL(ACTION_PORTAL_PLAYER) void ACTION_PORTAL_PLAYER::OnAction() { Trigger* pTrigger = getParent(); ACTION_PORTAL_PLAYER_INFO* pInfo = Get(); MAPCODE enterFieldCode = static_cast(pInfo->GetMapCode()); int moveType = pInfo->GetType(); switch(moveType) { case pInfo->FIELDCODE: { if(pInfo->GetIsParty() == ns_trigger::PARTY) { // ÇöÀç Çʵ忡 ÀÖ´Â »ç¶÷À» ¸ðµÎ ¿öÇÁ // Á¶°Ç¿¡ ÇØ´çÇÏ´Â »ç¶÷À» ¾Ë ÇÊ¿ä ¾øÀ½ const WzID areaID = pInfo->GetAreaID(); WarpControl::WarpAllPlayer(getMGR()->GetField(), enterFieldCode, areaID); } else { ASSERT(pInfo->GetIsParty() == ns_trigger::PERSONAL); if(DWORD clicked_player_key = pTrigger->GetClickedPlayerKey()) { Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(pPlayer == 0) { SUNLOG(eFULL_LOG, "["__FUNCTION__"] [U:%d]ACTION_REWARD_PLAYER Player NULL!!", clicked_player_key); return; } WARP_PLAYER::Warp(pPlayer, enterFieldCode, pInfo->GetAreaID()); } else { /* WarpPlayerForCondition op(enterFieldCode,Get()->GetAreaID()); getParent()->FindPlayer(op); */ WarpPlayerForField op(enterFieldCode, pInfo->GetAreaID()); pTrigger->ForeachSatisfiedPlayer(op); pTrigger->RemoveAllSatisfiedPlayer(); } } } break; // ±âÁ¸ Äڵ尡 ¼±Çà°Ë»ç(FIELDCODE == moveType)ÀÌ³Ä ¾Æ´Ï³Ä·Î Æò°¡ ÇÏ´Â ¹Ù¶÷¿¡ 3°¡Áö ŸÀÔ //ÀÌ ½ÇÀç·Î 2°¡Áö ŸÀÔÀ¸·Î »ç¿ëµÇ°í ÀÖ¾ú´Ù. º° ¼ö ¾øÀÌ µ¿ÀÏÇÏ°Ô Ã³¸®ÇÑ´Ù. case pInfo->RELATEDVILLAGE: case pInfo->VILLAGECODE: { if(pInfo->GetIsParty() == ns_trigger::PARTY) { // ÇöÀç Çʵ忡 ÀÖ´Â »ç¶÷À» ¸ðµÎ ¿öÇÁ // Á¶°Ç¿¡ ÇØ´çÇÏ´Â »ç¶÷À» ¾Ë ÇÊ¿ä ¾øÀ½ BackToTheVillage op; getMGR()->ForeachPlayer(op); //WarpPlayerForField op(enterFieldCode,Get()->GetAreaID()); } else { ASSERT(pInfo->GetIsParty() == ns_trigger::PERSONAL); if(DWORD clicked_player_key = pTrigger->GetClickedPlayerKey()) { Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(pPlayer == 0) { SUNLOG(eFULL_LOG, "["__FUNCTION__"] [U:%d]ACTION_REWARD_PLAYER Player NULL!!", pTrigger->GetClickedPlayerKey()); return; } BackToTheVillage op; op(pPlayer); } else { BackToTheVillage op; pTrigger->ForeachSatisfiedPlayer(op); pTrigger->RemoveAllSatisfiedPlayer(); } } } break; //__NA001310_BATTLEZONE_PORTAL_RETURN_TARGET_MOVE_SUPPORT__ case pInfo->TARGET_RETURN: { BOOLEAN bParty = pInfo->GetIsParty() == ns_trigger::PARTY; DWORD clicked_player_key = bParty ? 0 : pTrigger->GetClickedPlayerKey(); MAPCODE returnMapCode = enterFieldCode; //ÀÌ ½ÃÁ¡Àº FieldCode°¡ ¾Æ´Ï´Ù. MapCode // ¾Æ·¡ pMapInfo¿¡¼­ »¸´Â´Ù¸é Å×½ºÆ® ½ÃÁ¡ ¹Ýµå½Ã ¹ß°ßµÈ´Ù. const sMAPINFO* pMapInfo = MapInfoParser::Instance()->FindMapInfo(returnMapCode); BOOLEAN acceptableField = pMapInfo->byMKind == eZONETYPE_VILLAGE || pMapInfo->byMKind == eZONETYPE_FIELD || pMapInfo->byMKind == eZONETYPE_DOMINATION_FIELD || pMapInfo->byMKind == eZONETYPE_TUTORIAL_FIELD; if(acceptableField == 0) break; enterFieldCode = pMapInfo->FCode[0]; ReturnToTargetStaticField op(returnMapCode, enterFieldCode, 0); //3rd Arg: pInfo->GetAreaID() < Áö¿ø ¿©ºÎ °í¹ÎÇÏÀÚ. if(bParty) { getMGR()->ForeachPlayer(op); } else if(clicked_player_key) { Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(pPlayer == NULL) { SUNLOG(eFULL_LOG, "["__FUNCTION__"] [U:%d] Player NULL!!", clicked_player_key); return; } op(pPlayer); } else { pTrigger->ForeachSatisfiedPlayer(op); pTrigger->RemoveAllSatisfiedPlayer(); } } break; } #ifdef __TRIGGER_TEST_LOG SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_PORTAL_PLAYER", pTrigger->TriggerID()); #endif } //================================================================================================== __IMPL_POOL(ACTION_SET_OBJECTTHRUST) void ACTION_SET_OBJECTTHRUST::OnAction() { } //================================================================================================== // Á¶±Ý ÀÌ»óÇÑ Æ®¸®°ÅÁö¸¸ ±âȹ¿¡¼­... // Àüü À¯Àú¿¡°Ô µ¥¹ÌÁö¸¦ ÁØ´Ù. (¿µ¿ªµ¥¹ÌÁö¿¡¼­ ¿µ¿ªÀÌ ºüÁø ¹öÀü) __IMPL_POOL(ACTION_APPLY_DAMAGE) class ApplyDamageHandler { public: ApplyDamageHandler(DAMAGETYPE damage) : damage_(damage) {} ~ApplyDamageHandler(){} void operator()(Player* pPlayer) { ASSERT(pPlayer); DAMAGETYPE apply_damage = static_cast(pPlayer->DecreaseHP(damage_)); SUNLOG(eDEV_LOG, "µ¥¹ÌÁö ºÎ¿© : Æ®¸®°Å µ¥¹ÌÁö[%d] ½ÇÁ¦ ÇÇÇØ µ¥¹ÌÁö[%d] Ç÷¹À̾î hp[%d]", damage_, apply_damage, pPlayer->GetHP()); MSG_CG_TRIGGER_AREADAMAGE_BRD msg; msg.m_dwObjectKey = pPlayer->GetObjectKey(); msg.m_wDamage = damage_; msg.m_dwHP = pPlayer->GetHP(); #ifdef _NA_008804_20160502_COMBAT_LOG time_t t; util::TimeSync::time(&t); msg.m_SvrTime = t; #endif //(_NA_008804_20160502_COMBAT_LOG) pPlayer->SendPacketAround((MSG_BASE_FORWARD*)&msg, sizeof(msg)); } void operator()(std::pair pair_type) { operator()(pair_type.second); } private: DAMAGETYPE damage_; }; void ACTION_APPLY_DAMAGE::OnAction() { ACTION_APPLY_DAMAGE_INFO* pInfo = Get(); ApplyDamageHandler op((DAMAGETYPE)pInfo->GetDamage()); const BYTE byTarget = pInfo->GetTargetType(); // (CHANGES) (f100608.1L) (WAVERIX) add type switch(byTarget) { case ACTION_APPLY_DAMAGE_INFO::TARGET_FIELD: getMGR()->ForeachPlayer(op); break; case ACTION_APPLY_DAMAGE_INFO::TARGET_PERSONAL: { Player* pPlayer = NULL; Trigger* pTrigger = getParent(); DWORD clickPlayer = pTrigger->GetClickedPlayerKey(); if (clickPlayer) pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clickPlayer); else pPlayer = pTrigger->GetFirstSatisfiedPlayer(); if (pPlayer) op(pPlayer); else SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_APPLY_DAMAGE : Cant not Find Player", pTrigger->TriggerID()); } break; } } //================================================================================================== __IMPL_POOL(ACTION_REFLECT_DAMAGE) void ACTION_REFLECT_DAMAGE::OnAction() { } //================================================================================================== namespace ns_trigger { struct CreateMonsterArgs { enum { MAX_NUMBER_OF_MONSTERS = 100, }; int area_id_; int group_id_; int number_of_monsters_; struct MonsterInfo { MONSTERCODE monster_code_; short angle_; } monters_list_[MAX_NUMBER_OF_MONSTERS]; inline void Clear() { ZeroMemory(this, sizeof(*this)); } inline void Init(int area_id, int group_id) { area_id_ = area_id; group_id_ = group_id; } inline void AddInfo(MONSTERCODE monster_code, short angle) { if(number_of_monsters_ >= _countof(monters_list_)) return; MonsterInfo& node = monters_list_[number_of_monsters_++]; node.monster_code_ = monster_code; node.angle_ = angle; } }; static int /*number of regened*/ CreateMonsterByTrigger(TriggerManagerEx* pTriggerManager, CreateMonsterArgs* args) { WzSpecialArea* pAreaInfo = pTriggerManager->GetAreaInfo(args->area_id_); nsAI::MovingPlanner* pMovingPlanner = pTriggerManager->GetField()->GetMovingPlanner(); //assert(pAreaInfo && pGameField); //assert(args->number_of_monters > 0); int number_of_regened = 0; const ENUM_BVTYPE bounding_volume_type = pAreaInfo->m_wbvRegion.m_eBvType; if(0) { } else if(bounding_volume_type == BVT_PATH_TILE_INDEX) { BvPathTileIndex& rTileIndex = pAreaInfo->m_wbvRegion.m_BvPathTileIndex; const WORD number_of_max_tiles = min(WORD(rTileIndex.m_nCount), args->MAX_NUMBER_OF_MONSTERS); //assert(number_of_max_tiles != 0); WORD number_of_tiles = 0; WORD tile_list[args->MAX_NUMBER_OF_MONSTERS] = { 0, }; // tileÀº word°ªÀ» ³ÑÁö ¾Ê´Â´Ù. ¹®Á¦°¡ »ý±â¸é MovingPlanner¿¡¼­ ÆÇ´Ü °¡´É. DWORD* tile_it = rTileIndex.m_pdwData; for(DWORD loop = number_of_max_tiles; loop; --loop, ++tile_it) { const DWORD tile_id = *tile_it; WORD tile_attr = pMovingPlanner->GetAttribute(tile_id); if(tile_attr & PTA_NO_WALK) continue; tile_list[number_of_tiles++] = WORD(tile_id); } if (number_of_tiles == 0) { SUNLOG(eCRITICAL_LOG, "[%s:%d] number_of_tiles == 0", __FUNCTION__, __LINE__); return 0; } CreateMonsterArgs::MonsterInfo* pMonsterInfo = args->monters_list_; //assert args->number_of_monsters_ <= args->MAX_NUMBER_OF_MONSTERS WORD indexes_of_tiles = number_of_tiles - 1; //if assert failed then '-1' protection fault WzVector spawn_pos; for(DWORD loop = args->number_of_monsters_; loop; --loop) { DWORD random_index = random(0, indexes_of_tiles); pMovingPlanner->GetRandomPosInTile(tile_list[random_index], &spawn_pos); number_of_regened += \ pTriggerManager->CreateNPC(pMonsterInfo->monster_code_, 1, &spawn_pos, args->area_id_, args->group_id_, pMonsterInfo->angle_); ++pMonsterInfo; } } else if(bounding_volume_type == BVT_SPHERE) { BvSphere& bvSphere = pAreaInfo->m_wbvRegion.m_BvSphere; WORD tile_attr; const int tile_no_1st = pMovingPlanner->GetTileToStand(bvSphere.m_wvCenter, 0, -1.0f, -1.0f, &tile_attr); static const float ratio_x = g_SinTable.FCOS(45); static const float ratio_y = g_SinTable.FSIN(45); int tile_no = -1; WzVector selected_pos; if((tile_attr & PTA_NO_WALK) == 0) { selected_pos = bvSphere.m_wvCenter; tile_no = tile_no_1st; } else { SetVector(&selected_pos, ratio_x * bvSphere.m_fRadius, ratio_y * bvSphere.m_fRadius, 0.0f); ViewBoxCubic cubic; cubic.SetInit3D(&bvSphere.m_wvCenter, &selected_pos); WzVector& max_point = cubic.Cubic.m_wvMax; WzVector& min_point = cubic.Cubic.m_wvMin; WzVector points[4] = { { max_point.x, max_point.y, bvSphere.m_wvCenter.z }, { max_point.x, min_point.y, bvSphere.m_wvCenter.z }, { min_point.x, max_point.y, bvSphere.m_wvCenter.z }, { min_point.x, min_point.y, bvSphere.m_wvCenter.z }, }; for(int i = 0; i < 4; ++i) { CopyMemory(&selected_pos, &points[i], sizeof(selected_pos)); tile_no = pMovingPlanner->GetTileToStand(selected_pos, 0, -1.0f, -1.0f, &tile_attr); if(tile_no_1st != tile_no && (tile_attr & PTA_NO_WALK) == 0) if(tile_no >= 0) break; } } for (int count = (args->number_of_monsters_ - 1); count >= 0; --count) { CreateMonsterArgs::MonsterInfo& monster_info = args->monters_list_[count]; number_of_regened = \ pTriggerManager->CreateNPC(monster_info.monster_code_, 1, &selected_pos, args->area_id_, args->group_id_, monster_info.angle_); } } else { //... } //pTriggerManager->CreateNPC(pInfo->GetMonsterCode(), 1, &vPos, areaID, pInfo->GetType()); return number_of_regened; } }; //end of namespace 'ns_trigger' //================================================================================================== __IMPL_POOL(ACTION_CREATE_MONSTER) void ACTION_CREATE_MONSTER::OnAction() { m_iRegenCount = 0; m_RegenTimer.SetTimer(0); //< óÀ½¿¡´Â ¹Ýµå½Ã Çѹø ½ÇÇàÇÑ´Ù. ACTION_CREATE_MONSTER_INFO* pInfo = Get(); if(pInfo->GetIsParty() == ns_trigger::PERSONAL) { // ¾ÆÁ÷ À¯Àú°¡ ¸Ê¿¡ µé¾î ¿ÀÁö ¾ÊÀº»óȲ¿¡¼­ 0ÀÌ µÉ ¼ö ÀÖ´Ù.!!!!!@@@@ DWORD number_of_players = getMGR()->GetPlayerNum(); m_iMaxCreateCount = pInfo->GetCreateCount() * (number_of_players == 0 ? 1 : number_of_players); } else m_iMaxCreateCount = pInfo->GetCreateCount(); #ifdef __TRIGGER_TEST_LOG SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_CREATE_MONSTER, °³¼ö(%d)", getParent()->TriggerID(), m_iMaxCreateCount); #endif } BOOL ACTION_CREATE_MONSTER::OnActionUpdate() { const ACTION_CREATE_MONSTER_INFO* pInfo = Get(); if(m_iRegenCount == pInfo->GetLoopCount()) { return FALSE; } if(m_RegenTimer.IsExpired() == 0) return TRUE; TriggerManagerEx* pTriggerManager = getMGR(); const int areaID = pInfo->GetAreaID(); m_RegenTimer.SetTimer(pInfo->GetDelayTime()); ns_trigger::CreateMonsterArgs args; args.Clear(); args.Init(areaID, pInfo->GetType()); MONSTERCODE monsterCode = (MONSTERCODE)pInfo->GetMonsterCode(); #ifdef _NA_003649_20111115_BATTLE_ZONE_HARDMODE GameZone* const game_zone = getMGR()->GetField()->GetGameZone(); if(game_zone->GetZoneType() == eZONETYPE_MISSION) { const MONSTERCODE replaace_monster_code = \ AppliedNpcDependencyChain::Instance()->GetRepleaceMonsterCode(game_zone, monsterCode, true); if (replaace_monster_code) { monsterCode = replaace_monster_code; } } #endif //_NA_003649_20111115_BATTLE_ZONE_HARDMODE for(int loop = m_iMaxCreateCount; loop; --loop) args.AddInfo(monsterCode, -1); ns_trigger::CreateMonsterByTrigger(pTriggerManager, &args); ++m_iRegenCount; return TRUE; } //================================================================================================== class DisPlayMsgBoxOpr { public: DisPlayMsgBoxOpr(MSG_CG_TRIGGER_DISPLAY_MSGBOX_CMD& rMsgCmd, BYTE byTarget) : m_rMsgCmd(rMsgCmd) , m_byTarget(byTarget) {} ~DisPlayMsgBoxOpr(){} void operator()(Player* pPlayer) { if (ACTION_DISPLAY_MSGBOX_INFO::TARGET_FIELD == m_byTarget) { pPlayer->SendPacket(&m_rMsgCmd, sizeof(m_rMsgCmd)); return; } GUILDGUID guildGuid = pPlayer->GetGuildGuid(); GameZone* pZone = pPlayer->GetGameZonePtr(); if (!pZone || INVALID_GUILDGUID == guildGuid || eZONETYPE_DOMINATION_FIELD != pZone->GetZoneType()) return; GameDominationField* pDomiZone = (GameDominationField*)pZone; #ifdef _NA_006826_20130722_DOMINATION_RENEWAL GUILDGUID defence_guild_guid = pDomiZone->GetDefenseGuild(); GameGuild* const defense_game_guild = g_GameGuildManager.FindGuild(defence_guild_guid); bool is_defence_guild = false; // ¹æ¾îÃø ±æµåÀÎÁö if (defense_game_guild == NULL) { // ¹æ¾î±æµå°¡ Á¸ÀçÇÏÁö ¾ÊÀ¸¸é ¿©±âÀÖ´Â »ç¶÷µéÀº ¸ðµÎ °ø°ÝÃø. is_defence_guild = false; } else { if (pPlayer->GetGuildGuid() == defence_guild_guid) { is_defence_guild = true; } else { GuildRelationSystem::GuildRelationEntry* defense_guild_entry = \ defense_game_guild->GetRelationEntry(); eGUILD_RELATION player_relation = defense_guild_entry->GetRelationType(pPlayer->GetGuildGuid()); if (player_relation == eGUILD_RELATION_ALLIENCE) { is_defence_guild = true; } else { is_defence_guild = false; } } } // °ø¼º,¼ö¼º ¿©ºÎ ÆÄ¾ÇÇØ¼­ ¸Þ¼¼Áö Àü´Þ switch(m_byTarget) { case ACTION_DISPLAY_MSGBOX_INFO::TARGET_OFFENCE: if (is_defence_guild == false) pPlayer->SendPacket(&m_rMsgCmd, sizeof(m_rMsgCmd)); break; case ACTION_DISPLAY_MSGBOX_INFO::TARGET_DEFENCE: if (is_defence_guild == true) pPlayer->SendPacket(&m_rMsgCmd, sizeof(m_rMsgCmd)); break; } #else switch(m_byTarget) { case ACTION_DISPLAY_MSGBOX_INFO::TARGET_OFFENCE: if (guildGuid == pDomiZone->GetOffenseGuild()) pPlayer->SendPacket(&m_rMsgCmd, sizeof(m_rMsgCmd)); break; case ACTION_DISPLAY_MSGBOX_INFO::TARGET_DEFENCE: if (guildGuid == pDomiZone->GetDefenseGuild()) pPlayer->SendPacket(&m_rMsgCmd, sizeof(m_rMsgCmd)); break; } #endif // _NA_006826_20130722_DOMINATION_RENEWAL } void operator()(std::pair pair_type) { operator()(pair_type.second); } private: BYTE m_byTarget; MSG_CG_TRIGGER_DISPLAY_MSGBOX_CMD& m_rMsgCmd; }; __IMPL_POOL(ACTION_DISPLAY_MSGBOX) void ACTION_DISPLAY_MSGBOX::OnAction() { const ACTION_DISPLAY_MSGBOX_INFO* pInfo = Get(); const BYTE byTarget = pInfo->GetTarget(); const BYTE byPersonal = ACTION_DISPLAY_MSGBOX_INFO::TARGET_PERSONAL; MSG_CG_TRIGGER_DISPLAY_MSGBOX_CMD msg; msg.m_nTextID = pInfo->GetTextID(); if (byPersonal == byTarget) { Player* pPlayer = NULL; Trigger* pTrigger = getParent(); DWORD clickPlayer = pTrigger->GetClickedPlayerKey(); if (clickPlayer) pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clickPlayer); else pPlayer = pTrigger->GetFirstSatisfiedPlayer(); if (pPlayer) pPlayer->SendPacket(&msg, sizeof(msg)); else SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_DISPLAY_MSGBOX : Cant not Find Player", pTrigger->TriggerID()); return; } DisPlayMsgBoxOpr op(msg,byTarget); getMGR()->ForeachPlayer(op); } //================================================================================================== class RemoveItemFromInventoryForCondition { SLOTCODE m_ItemCode; int m_iCount; public: RemoveItemFromInventoryForCondition(SLOTCODE itemCode, int count) : m_ItemCode(itemCode), m_iCount(count) {} ~RemoveItemFromInventoryForCondition() {} BOOL operator()(Player* pPlayer) { ASSERT(SAFE_NUMERIC_TYPECAST(int, m_ItemCode, SLOTCODE)); ItemManager* pItemMan = pPlayer->GetItemManager(); SLOTCODE slotCode = (SLOTCODE)m_ItemCode; POSTYPE pos = m_iCount; MSG_CG_ITEM_LOSE_ACK msg; if(RC::RC_ITEM_SUCCESS == pItemMan->DeleteAllKindOfItem(1, &slotCode, &pos, &(msg.m_ItemInfo))) { if(msg.m_ItemInfo.m_Count != 0) pPlayer->SendPacket(&msg, msg.GetSize()); return TRUE; } return FALSE; } //BOOL operator()(Trigger::PLAYER_TRIGGER_INFO* pPlayerInfo) //{ // //if(pPlayerInfo->m_State) // { // Player* pPlayer = pPlayerInfo->m_pPlayer; // pPlayer->GetItemManager()->Lose(m_ItemCode, m_byAllOfItem); // } // return FALSE; //} }; //================================================================================================== __IMPL_POOL(ACTION_REMOVE_ITEM) void ACTION_REMOVE_ITEM::OnAction() { const DWORD clicked_player_key = getParent()->GetClickedPlayerKey(); if(clicked_player_key != 0) { Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(pPlayer != 0) { int iItemCode = Get()->GetItemCode(); ASSERT(SAFE_NUMERIC_TYPECAST(int, iItemCode, SLOTCODE)); ItemManager* pItemMan = pPlayer->GetItemManager(); SLOTCODE slotCode = (SLOTCODE)iItemCode; POSTYPE pos = Get()->GetItemNum(); MSG_CG_ITEM_LOSE_ACK msg; if(RC::RC_ITEM_SUCCESS == pItemMan->DeleteAllKindOfItem(1, &slotCode, &pos, &(msg.m_ItemInfo))) { if(msg.m_ItemInfo.m_Count != 0) pPlayer->SendPacket(&msg, msg.GetSize()); } } else { SUNLOG(eFULL_LOG, "[U:%d]ACTION_REMOVE_ITEM Player NULL!!", clicked_player_key); return; } } else { RemoveItemFromInventoryForCondition op(Get()->GetItemCode(), Get()->GetItemNum()); getParent()->ForeachSatisfiedPlayer(op); getParent()->RemoveAllSatisfiedPlayer(); } #ifdef __TRIGGER_TEST_LOG SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_REMOVE_ITEM", getParent()->TriggerID()); #endif } // Çʵå»ó¿¡ ÀÖ´Â Ç÷¹À̾°Ô Àκ¥Å丮¿¡ º¸»ó¾ÆÀÌÅÛÀ» ÁØ´Ù. class DistributeItemToInventoryOnField : public std::unary_function { ACTION_REWARD_PLAYER* m_pReward; public : DistributeItemToInventoryOnField(ACTION_REWARD_PLAYER* pReward):m_pReward(pReward) {} ~DistributeItemToInventoryOnField(){} void operator()(Player* pPlayer) const { GameField* pField = pPlayer->GetField(); if(pField == 0) return; WzVector vec = pPlayer->GetRandomPosInAround(2); SCItemSlot slot; slot.SetCode(m_pReward->Get()->GetItemCode()); g_DropManager.DropItemToField(pField, &vec, pPlayer->GetObjectKey(), 0, slot); } void operator()(std::pair pair_type) { operator()(pair_type.second); } }; #ifdef __WAVERIX_UNUSED_SECTION__ // Á¶°Ç¿¡ ÇÕ´çÇÑ Ç÷¹À̾°Ô Àκ¥Å丮¿¡ º¸»óÀ» ÁØ´Ù. class DistributeItemToInventoryForCondition { CODETYPE m_ItemCode; int m_Count; public: DistributeItemToInventoryForCondition(CODETYPE ItemCode, int count) : m_ItemCode(ItemCode), m_Count(count) {} ~DistributeItemToInventoryForCondition() {} BOOL operator()(Trigger::PLAYER_TRIGGER_INFO* pPlayerInfo) { Player* pPlayer = pPlayerInfo->m_pPlayer; ///g_DropManager.DropItemToField(pPlayer->GetUserKey(), m_ItemCode); ///!!!!! temp TEMPTEMPTEMTPE ///!!!!! temp TEMPTEMPTEMTPE ///!!!!! temp TEMPTEMPTEMTPE ///!!!!! temp TEMPTEMPTEMTPE ///!!!!! temp TEMPTEMPTEMTPE ///!!!!! temp TEMPTEMPTEMTPE ///!!!!! temp TEMPTEMPTEMTPE return FALSE; } }; #endif //================================================================================================== __IMPL_POOL(ACTION_REWARD_PLAYER) void ACTION_REWARD_PLAYER::OnAction() { const BASE_ITEMINFO* pItemInfo = ItemInfoParser::Instance()->GetItemInfo(Get()->GetItemCode()); if(pItemInfo == 0) { // ¿¡·¯ ó¸® return; } ASSERT(Get()->GetCount() > 0); DWORD clicked_player_key = getParent()->GetClickedPlayerKey(); // º¸»ó ´ë»óÀÌ °³ÀÎÀ¸·Î µÇ¾îÀÖ°í, Ŭ¸¯ÇÑ Ç÷¹À̾ Á¸ÀçÇÒ°æ¿ì¿¡,, ÇØ´ç Ç÷¹À̾î ÁÖº¯¿¡ ¾ÆÀÌÅÛÁØ´Ù if( Get()->GetIsParty() == false && clicked_player_key != 0 ) { Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(pPlayer) { DistributeItemToInventoryOnField op((ACTION_REWARD_PLAYER*)this); op(pPlayer); } } // Ŭ¸¯ÇÑ Ç÷¹À̾ Á¸ÀçÇÏ´Â °æ¿ì, ÇØ´ç Ç÷¹À̾ ¼ÓÇÑ ÆÄƼ¸É¹öµé ÁÖº¯¿¡ ¾ÆÀÌÅÛÁØ´Ù else if( clicked_player_key != 0 ) { Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(pPlayer) { WORD partyKey = pPlayer->GetPartyState().GetPartyKey(); DistributeItemToInventoryOnField Opr(this); if(!NewGamePartyManager::Instance()->For_eachPlayers(partyKey, Opr)) SUNLOG(eCRITICAL_LOG, "[ACTION_REWARD_PLAYER] GameParty is NULL! (%s)'s PartyKey (%u)", pPlayer->GetCharName(), partyKey); return; } SUNLOG(eCRITICAL_LOG, "[ACTION_REWARD_PLAYER] Player is NULL! ClickedUserKey %u", clicked_player_key); } // ¸ðµç »ç¶÷¿¡°Ô ¾ÆÀÌÅÛÀ» ÁØ´Ù else { DistributeItemToInventoryOnField op((ACTION_REWARD_PLAYER*)this); getMGR()->ForeachPlayer(op); } } //================================================================================================== __IMPL_POOL(ACTION_CLEAR_MISSION) void ACTION_CLEAR_MISSION::OnAction() { getMGR()->ClearMission(); #ifdef __TRIGGER_TEST_LOG SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_CLEAR_MISSION", getParent()->TriggerID()); #endif } //================================================================================================== __IMPL_POOL(ACTION_PORTAL_RANDOM) void ACTION_PORTAL_RANDOM::OnAction() { ACTION_PORTAL_RANDOM_INFO* pInfo = Get(); // ÇØ´ç ¿µ¿ªÀ» ¾ò¾î¿Í¼­ MAPCODE enterFieldCode = static_cast(pInfo->GetMapID()); if(pInfo->GetRandom() == 0) { int nRandArea = rand() % 8; // ·£´ýÇÏ°Ô ¿öÇÁ if(pInfo->GetTarget() == ns_trigger::PARTY) { // ÇöÀç Çʵ忡 ÀÖ´Â »ç¶÷À» ¸ðµÎ ¿öÇÁ // Á¶°Ç¿¡ ÇØ´çÇÏ´Â »ç¶÷À» ¾Ë ÇÊ¿ä ¾øÀ½ const WzID areaID = pInfo->GetAreaID(nRandArea); WarpControl::WarpAllPlayer(getMGR()->GetField(), enterFieldCode, areaID); } else { ASSERT(pInfo->GetTarget() == ns_trigger::PERSONAL); if(DWORD clicked_player_key = getParent()->GetClickedPlayerKey()) { Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(NULL == pPlayer) { SUNLOG(eFULL_LOG, "["__FUNCTION__"] [U:%d] Player NULL!!", clicked_player_key); return; } WARP_PLAYER::Warp(pPlayer, enterFieldCode, pInfo->GetAreaID(nRandArea)); } else { WarpPlayerForField op(enterFieldCode,pInfo->GetAreaID(nRandArea)); getParent()->ForeachSatisfiedPlayer(op); getParent()->RemoveAllSatisfiedPlayer(); } } } else //if(pInfo->GetRandom() == ACTION_PORTAL_RANDOM::_ORDER) { // ÆÄƼ¿øµéÀ» ¼ø¼­´ë·Î À̵¿½ÃŲ´Ù if(pInfo->GetTarget() == ns_trigger::PARTY) { // ÇöÀç Çʵ忡 ÀÖ´Â »ç¶÷À» ¸ðµÎ ¿öÇÁ // Á¶°Ç¿¡ ÇØ´çÇÏ´Â »ç¶÷À» ¾Ë ÇÊ¿ä ¾øÀ½ BackToTheVillage op; getMGR()->ForeachPlayer(op); //WarpPlayerForField op(EnterFieldCode,pInfo->GetAreaID()); } else { ASSERT(pInfo->GetTarget() == ns_trigger::PERSONAL); if(DWORD clicked_player_key = getParent()->GetClickedPlayerKey()) { Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(NULL == pPlayer) { SUNLOG(eFULL_LOG, "["__FUNCTION__"] [U:%d]ACTION_REWARD_PLAYER Player NULL!!", clicked_player_key); return; } BackToTheVillage op; op(pPlayer); } else { BackToTheVillage op; getParent()->ForeachSatisfiedPlayer(op); getParent()->RemoveAllSatisfiedPlayer(); } } } } __IMPL_POOL(ACTION_NPC_RANDOM_AREA_MOVE) void ACTION_NPC_RANDOM_AREA_MOVE::OnAction() { ACTION_NPC_RANDOM_AREA_MOVE_INFO* pInfo = Get(); int nRandArea = rand() % 8; const WzID areaID = pInfo->GetAreaID(nRandArea); DWORD object_key = getParent()->GetObjectKey(); NPC* const npc = getMGR()->FindNPC(object_key); if (npc == NULL) return; GameField* pField = npc->GetField(); CWorldBase* pWorldBase = pField->GetFieldInfo()->GetWorldBase(); const int number_of_special_areas = pWorldBase->GetNumberOfSpecialArea(); WzSpecialArea* pSpecialArea = NULL; if (!FlowControl::FCAssert(areaID < number_of_special_areas && (pSpecialArea = pWorldBase->GetSpecialAreaByIndex(areaID)) != NULL)) { SUNLOG(eCRITICAL_LOG, _T("|["__FUNCTION__"]|ÐÅÏ¢=can't find special area (index = %u)"), areaID); return; } WzBoundingVolume& rVolume = pSpecialArea->m_wbvRegion; if(BVT_PATH_TILE_INDEX == rVolume.m_eBvType) { WzVector wvTarget = {0,0,0}; BvPathTileIndex& rPATHTILE = rVolume.m_BvPathTileIndex; DWORD dwSelectedTile = random(0, rPATHTILE.m_nCount - 1); nsAI::MovingPlanner* const pMovingPlanner = pField->GetMovingPlanner(); wvTarget = pMovingPlanner->GetRandomPosInTile(rPATHTILE.m_pdwData[dwSelectedTile]); if (pInfo->GetMoveOrWarp() == 0) { // 0: move #ifdef _NA_007907_20141222_MODIFY_MONSTER_MOVE_TRIGGER npc->SetRegenPos(wvTarget); npc->GetStateManager()->SetMoveAreaID(pSpecialArea->m_wiIdentity); npc->ChangeState(STATE_ID_TRACK_AREA); #else npc->MoveAndBroadcast(&wvTarget, CMS_RUN); #endif // _NA_007907_20141222_MODIFY_MONSTER_MOVE_TRIGGER } else if (pInfo->GetMoveOrWarp() == 1 ) {// 1: teleport pField->TeleportObject(npc, &wvTarget); } } } //================================================================================================== __IMPL_POOL(ACTION_ACTIVATE_TRIGGER) void ACTION_ACTIVATE_TRIGGER::OnAction() { const DWORD wz_trigger_id = Get()->GetWzTriggerID(); if(Get()->GetFlag() == 0) getMGR()->InsertActiveTrigger(wz_trigger_id); else getMGR()->RequestRemoveActiveTrigger(wz_trigger_id); // (f100721.2L) add routine to support a various planner trigger logic getMGR()->MAP_STATE.Change(getParent()->TriggerID()); #ifdef __TRIGGER_TEST_LOG SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_ACTIVATE_TRIGGER", getParent()->TriggerID()); #endif } //================================================================================================== __IMPL_POOL(ACTION_AREA_DAMAGE) class AreaDamageHandler { DWORD m_dwObjectKey; float m_dist; WzVector m_vPos; DAMAGETYPE m_wDamage; public: AreaDamageHandler(DWORD dwObjectKey, WzVector* pvPos, float dist, DAMAGETYPE wDamage) { m_dwObjectKey = dwObjectKey; m_vPos = *pvPos; m_dist = dist * dist; m_wDamage = wDamage; } ~AreaDamageHandler(){} void operator()(Player* const pPlayer) { const WzVector& curPos = *pPlayer->GetPosPtr(); WzVector wvDist = m_vPos - curPos; float fDist2 = VectorLength2(&wvDist); if(fDist2 <= m_dist) { pPlayer->DecreaseHP(m_wDamage); // (WAVERIX) (061018) ÆÐŶ ó¸® ÃÖÀûÈ­ÇÒ ¿©Áö°¡ º¸Àδ٠MSG_CG_TRIGGER_AREADAMAGE_BRD msg; msg.m_dwObjectKey = pPlayer->GetObjectKey(); msg.m_wDamage = m_wDamage; msg.m_dwHP = pPlayer->GetHP(); #ifdef _NA_008804_20160502_COMBAT_LOG time_t t; util::TimeSync::time(&t); msg.m_SvrTime = t; #endif //(_NA_008804_20160502_COMBAT_LOG) pPlayer->SendPacketAround((MSG_BASE_FORWARD*)&msg, sizeof(msg)); } } void operator()(std::pair pair_type) { operator()(pair_type.second); } }; void ACTION_AREA_DAMAGE::OnAction() { ACTION_AREA_DAMAGE_INFO* pInfo = Get(); // ¿ÀºêÁ§Æ® ¹Þ¾Æ¼­ MapObject* pMapObject = getMGR()->FindMapObject(pInfo->GetObjectIndex()); ASSERT(NULL != pMapObject); DEBUG_CODE(if(!pMapObject) return ;); // ¹üÀ§ ¾È¿¡ Ÿ°Ù(°³ÀÎ/ÆÄƼ) ÀÖ´ÂÁö üũÇÏ¿© µ¥¹ÌÁö ÁÖÀÚ WzVector vPos = *pMapObject->GetPosPtr(); float fRange = pInfo->GetRange(); AreaDamageHandler handler(pInfo->GetObjectIndex(), &vPos, fRange, static_cast(pInfo->GetDamage())); getMGR()->ForeachPlayer(handler); // ¹üÀ§ ¾È¿¡ °³ÀÎÀÌµç ÆÄÆ¼µç ÀÖÀ¸¸é ´Ù ÁÖ´Â °Å ¾Æ´Ñ°¡? #ifdef __TRIGGER_TEST_LOG SUNLOG(eDEV_LOG, "[ID:%u]:ACTION_AREA_DAMAGE", getParent()->TriggerID()); #endif } //================================================================================================== __IMPL_POOL(ACTION_OPERATE_SWITCH) void ACTION_OPERATE_SWITCH::OnAction() { const ACTION_OPERATE_SWITCH_INFO& rInfo = *Get(); int cond_value = (int)getMGR()->GetSwitchValue(rInfo.GetSwitchID()); int argument = rInfo.GetArgument(); int apply_value = 0; switch(rInfo.GetOperationType()) { case eOPERATION_EQUAL: apply_value = argument; break; case eOPERATION_PLUS: apply_value = (int)cond_value + argument; break; case eOPERATION_MINUS: apply_value = (int)cond_value - argument; break; case eOPERATION_MULTIPLE: apply_value = (int)cond_value * argument; break; case eOPERATION_DIVIDE: argument ? apply_value = (int)(cond_value / argument) : 0; break; } if(DWORD(apply_value) >= 256 || (argument == 0 && rInfo.GetOperationType() == eOPERATION_DIVIDE)) { SUNLOG(eCRITICAL_LOG, "[ACTION_OPERATE_SWITCH] OperationType[%u] Result[%d]", rInfo.GetOperationType(), apply_value); return; } if(SAFE_NUMERIC_TYPECAST(int, apply_value, BYTE)) getMGR()->SetSwitchValue(rInfo.GetSwitchID(), (BYTE)apply_value); else { #ifdef __TRIGGER_TEST_LOG SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_OPERATE_SWITCH", getParent()->TriggerID()); #endif } } __IMPL_POOL(ACTION_OPERATE_SWITCH_EX) void ACTION_OPERATE_SWITCH_EX::OnAction() { const ACTION_OPERATE_SWITCH_EX_INFO& rInfo = *Get(); 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); int cond_value = (int)mission_room->GetSwitchValue(rInfo.GetSwitchID()); int argument = rInfo.GetArgument(); int apply_value = 0; switch(rInfo.GetOperationType()) { case eOPERATION_EQUAL: apply_value = argument; break; case eOPERATION_PLUS: apply_value = (int)cond_value + argument; break; case eOPERATION_MINUS: apply_value = (int)cond_value - argument; break; case eOPERATION_MULTIPLE: apply_value = (int)cond_value * argument; break; case eOPERATION_DIVIDE: argument ? apply_value = (int)(cond_value / argument) : 0; break; } if(DWORD(apply_value) >= 256 || (argument == 0 && rInfo.GetOperationType() == eOPERATION_DIVIDE)) { SUNLOG(eCRITICAL_LOG, "[ACTION_OPERATE_SWITCH] OperationType[%u] Result[%d]", rInfo.GetOperationType(), apply_value); return; } if(SAFE_NUMERIC_TYPECAST(int, apply_value, BYTE)) mission_room->SetSwitchValue(rInfo.GetSwitchID(), (BYTE)apply_value); else { #ifdef __TRIGGER_TEST_LOG SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_OPERATE_SWITCH", getParent()->TriggerID()); #endif } } #endif //_NA_007369_20140625_ACTION_OPERATE_SWITCH_EX } } //================================================================================================== __IMPL_POOL(ACTION_ROAD_CONNECT) void ACTION_ROAD_CONNECT::OnAction() // ÀÏÁ¤ ¿µ¿ªÀÇ ±æ ¿¬°áÀ» ¼³Á¤ ¶Ç´Â ÇØÁ¦ ÇÑ´Ù { const ACTION_ROAD_CONNECT_INFO* road_connect_action = Get(); const INT area_index = road_connect_action->GetAreaIndex(); TriggerManagerEx* const trigger_manager = getMGR(); // Áö¿ªÀÌ À¯È¿ÇÑÁö °Ë»çÇÑ´Ù. const WzSpecialArea* const area = trigger_manager->GetAreaInfo(area_index); if (!area) { SUNLOG(eCRITICAL_LOG, _T("|%s|Áö¿ªÀÌ À¯È¿ÇÏÁö ¾Ê½À´Ï´Ù.|AreaIndex = %d|"), __FUNCTION__, area_index); return; } // ¿µ¿ª Çü½ÄÀÌ À¯È¿ÇÑÁö °Ë»çÇÑ´Ù. const WzBoundingVolume& region = area->m_wbvRegion; if (region.m_eBvType != BVT_PATH_TILE_INDEX) { SUNLOG(eCRITICAL_LOG, _T("|%s|¿µ¿ª Çü½ÄÀÌ À¯È¿ÇÏÁö ¾Ê½À´Ï´Ù.|RegionType = %d|"), __FUNCTION__, region.m_eBvType); return; } // ¼³Á¤°ªÀÌ À¯È¿ÇÑÁö °Ë»çÇÑ´Ù. const BYTE can_go = road_connect_action->GetCanGo(); if (can_go != ns_trigger::CANMOVE && can_go != ns_trigger::CANNOTMOVE) { SUNLOG(eCRITICAL_LOG, _T("|%s|¼³Á¤°ªÀÌ À¯È¿ÇÏÁö ¾Ê½À´Ï´Ù.|CanGo = %u|"), __FUNCTION__, can_go); return; } // °¢°¢ÀÇ Å¸ÀÏ¿¡ ´ëÇØ ¼³Á¤°ªÀ» Àû¿ëÇÑ´Ù. const BvPathTileIndex& tile_list = region.m_BvPathTileIndex; for (DWORD i = 0; i < tile_list.m_nCount; ++i) { const INT tile_id = static_cast(tile_list.m_pdwData[i]); if (can_go == ns_trigger::CANMOVE) { trigger_manager->UnsetAttribute(tile_id, PTA_NO_WALK); } else if (can_go == ns_trigger::CANNOTMOVE) { trigger_manager->SetAttribute(tile_id, PTA_NO_WALK); } } (trigger_manager->MAP_STATE).Change(getParent()->TriggerID()); } //================================================================================================== __IMPL_POOL(ACTION_CREATE_DIR_MONSTER) void ACTION_CREATE_DIR_MONSTER::OnAction() { const ACTION_CREATE_DIR_MONSTER_INFO& rInfo = *Get(); m_iRegenCount = 0; m_RegenTimer.SetTimer(0); //< óÀ½¿¡´Â ¹Ýµå½Ã Çѹø ½ÇÇàÇÑ´Ù. if(rInfo.GetIsParty() == ns_trigger::PERSONAL) { // ¾ÆÁ÷ À¯Àú°¡ ¸Ê¿¡ µé¾î ¿ÀÁö ¾ÊÀº»óȲ¿¡¼­ 0ÀÌ µÉ ¼ö ÀÖ´Ù.!!!!!@@@@ DWORD userCount = getMGR()->GetPlayerNum(); m_iMaxCreateCount = rInfo.GetCreateCount() * (userCount == 0 ? 1 : userCount); } else m_iMaxCreateCount = rInfo.GetCreateCount(); #ifdef __TRIGGER_TEST_LOG SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_CREATE_MONSTER,°³¼ö(%d)", getParent()->TriggerID(), m_iMaxCreateCount); #endif } BOOL ACTION_CREATE_DIR_MONSTER::OnActionUpdate() { const ACTION_CREATE_DIR_MONSTER_INFO& rInfo = *Get(); if(m_iRegenCount == rInfo.GetLoopCount()) { return FALSE; } if(m_RegenTimer.IsExpired() == 0) return TRUE; m_RegenTimer.SetTimer(rInfo.GetDelayTime()); ns_trigger::CreateMonsterArgs args; args.Clear(); args.Init(rInfo.GetAreaID(), rInfo.GetType()); MONSTERCODE monsterCode = (MONSTERCODE)rInfo.GetMonsterCode(); #ifdef _NA_003649_20111115_BATTLE_ZONE_HARDMODE GameZone* game_zone = getMGR()->GetField()->GetGameZone(); if(game_zone->GetZoneType() == eZONETYPE_MISSION) { MONSTERCODE replaace_monster_code = \ AppliedNpcDependencyChain::Instance()->GetRepleaceMonsterCode(game_zone, monsterCode, true); if (replaace_monster_code) { monsterCode = replaace_monster_code; } } #endif //_NA_003649_20111115_BATTLE_ZONE_HARDMODE WzVector vDirection = { rInfo.GetDirX(), rInfo.GetDirY(), rInfo.GetDirZ() }; short angle = 0; { float fangle = Math_GetAngleFromVector(&vDirection); // (NOTE) ¾È¿¡¼­ Normalize¼öÇà. angle = static_cast(fangle * 180.0f / WZ_PI); } for(int loop = m_iMaxCreateCount; loop; --loop) args.AddInfo(monsterCode, angle); ns_trigger::CreateMonsterByTrigger(getMGR(), &args); ++m_iRegenCount; return TRUE; } //================================================================================================== __IMPL_POOL(ACTION_CHANGE_LIGHT) void ACTION_CHANGE_LIGHT::OnAction() { getMGR()->MAP_STATE.Change(getParent()->TriggerID()); } //================================================================================================== __IMPL_POOL(ACTION_CHANGE_OBJECT_TYPE) void ACTION_CHANGE_OBJECT_TYPE::OnAction() { getMGR()->MAP_STATE.Change(getParent()->TriggerID()); } struct ActionOperator { class QUEST { public: // ActionTrigger <Äù½ºÆ® ¸¸Á·¿©ºÎ> class Satisfaction { QCODE m_QuestCode; public: Satisfaction(QCODE wQuestCode) : m_QuestCode(wQuestCode) {} void operator()(Player* pPlayer) { // <060606, waverix> // not implementation SUNLOG(eFULL_LOG, "ActionOperator::QUEST::Satisfaction is not implemented."); //Quest* pQuest = pPlayer->GetQuestManager()->FindQuest(m_QuestCode); //if(!pQuest) //{ // //} } void Process(SATISFIED_PLAYER_PAIR rPair) { // <060606, waverix> // not implementation SUNLOG(eCRITICAL_LOG, "ActionOperator::QUEST::Satisfaction is not implemented."); } }; //ActionOperator::QUEST::Satisfaction // ActionTrigger <Äù½ºÆ® ºÎ¿©> class Grant { QCODE m_QuestCode; public: Grant(QCODE wQuestCode) : m_QuestCode(wQuestCode) {} // ¾Æ·¡ÀÇ ÄÚµå´Â void operator()(Player* pPlayer) { QuestManager* pQuestManager = pPlayer->GetQuestManager(); //__NA_001337_20090511_EXPANSION_QUEST_COMPL_NUM if(pQuestManager->IsQuestMax()) { MSG_CG_QUEST_ACCEPT_NAK msg; msg.m_byErrorCode = RC::RC_QUEST_CANNOTQUEST_MAXCOUNT; pPlayer->SendPacket(&msg, sizeof(msg)); return ; } // Quest* pQuest = pQuestManager->CreateQuest(m_QuestCode); if(pQuest && (!pQuest->GetQuestInfo()->IsChildQuest())) { if(pQuestManager->CanDoAccept(m_QuestCode, pPlayer) == RC::RC_QUEST_SUCCESS) { // (WAVERIX) (060607) ¾Æ·¡ÀÇ ÆÐŶÀº Æ®¸®°Å¿ëÀ¸·Î Çϳª »õ·Î ¸¸µé¾î¼­ »ç¿ëÇÒ °Í. MSG_CG_QUEST_ACCEPT_ACK msg; pPlayer->SendPacket(&msg, sizeof(msg)); return; } } pQuestManager->DestroyQuest(m_QuestCode); } void Process(SATISFIED_PLAYER_PAIR rPair) { Player* pPlayer = rPair.second; QuestManager* pQuestMan = pPlayer->GetQuestManager(); //__NA_001337_20090511_EXPANSION_QUEST_COMPL_NUM if(pQuestMan->IsQuestMax()) { MSG_CG_QUEST_ACCEPT_NAK msg; msg.m_byErrorCode = RC::RC_QUEST_CANNOTQUEST_MAXCOUNT; pPlayer->SendPacket(&msg, sizeof(msg)); return ; } // Quest* pQuest = pQuestMan->CreateQuest(m_QuestCode); if(pQuest && (!pQuest->GetQuestInfo()->IsChildQuest())) { if(pQuestMan->CanDoAccept(m_QuestCode, pPlayer) == RC::RC_QUEST_SUCCESS) { // (WAVERIX) (060607) ¾Æ·¡ÀÇ ÆÐŶÀº Æ®¸®°Å¿ëÀ¸·Î Çϳª »õ·Î ¸¸µé¾î¼­ »ç¿ëÇÒ °Í. MSG_CG_QUEST_ACCEPT_ACK msg; pPlayer->SendPacket(&msg, sizeof(msg)); return; } } pQuestMan->DestroyQuest(m_QuestCode); } }; // ActionOperator::QUEST::Grant class Setup { QCODE m_QuestCode; public: Setup(QCODE wQuestCode) : m_QuestCode(wQuestCode) {} // ¾Æ·¡ÀÇ ÄÚµå´Â void operator()(Player* pPlayer) { QuestManager* pQuestManager = pPlayer->GetQuestManager(); Quest* pQuest = pQuestManager->FindQuest(m_QuestCode); if(pQuest == 0) return; if(pQuestManager->CanComplete(m_QuestCode, pPlayer) == RC::RC_QUEST_SUCCESS) { // º¸»ó ü°è¸¦ °®Ãç¾ß Çϴ°¡? pQuestManager->DoReward(m_QuestCode, pPlayer); //__NA_001337_20090511_EXPANSION_QUEST_COMPL_NUM QUESTPART_COMPL* pCompNum = pQuestManager->FindComplQuest(m_QuestCode); if(pCompNum && (0xFF == pCompNum->m_Num)) { //(lst1024)(090611) ¹«ÇÑ ¹Ýº¹Äù¸¦ 255ȸ ÀÌ»óÇÏ´Â À¯Àú°¡ ¸¹¾ÆÁ³´Ù. // Ȥ½Ã ´Ù¸¥ ÀÌÀ¯Àϼö ÀÖÀ¸´Ï ·Î±× ³²±ä´Ù. SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] char(%s), guid(%d), Quest(%d), num(%d)", pPlayer->GetCharName(), pPlayer->GetCharGuid(), m_QuestCode, pCompNum->m_Num); } //SUNLOG(eCRITICAL_LOG, _T("Setup %u"), m_QuestCode); } return; } void Process(SATISFIED_PLAYER_PAIR rPair) { Player* pPlayer = rPair.second; QuestManager* pQuestManager = pPlayer->GetQuestManager(); Quest* pQuest = pQuestManager->FindQuest(m_QuestCode); if(pQuest == 0) return; if(pQuestManager->CanComplete(m_QuestCode, pPlayer) == RC::RC_QUEST_SUCCESS) { // º¸»ó ü°è¸¦ °®Ãç¾ß Çϴ°¡? pQuestManager->DoReward(m_QuestCode, pPlayer); //__NA_001337_20090511_EXPANSION_QUEST_COMPL_NUM QUESTPART_COMPL* pCompNum = pQuestManager->FindComplQuest(m_QuestCode); if(pCompNum && (0xFF == pCompNum->m_Num)) { //(lst1024)(090611) ¹«ÇÑ ¹Ýº¹Äù¸¦ 255ȸ ÀÌ»óÇÏ´Â À¯Àú°¡ ¸¹¾ÆÁ³´Ù. // Ȥ½Ã ´Ù¸¥ ÀÌÀ¯Àϼö ÀÖÀ¸´Ï ·Î±× ³²±ä´Ù. SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] char(%s), guid(%d), Quest(%d), num(%d)", pPlayer->GetCharName(), pPlayer->GetCharGuid(), m_QuestCode, pCompNum->m_Num); } //SUNLOG(eCRITICAL_LOG, _T("Setup %u"), m_QuestCode); } return; } }; }; // ActionOperator::QUEST }; // ActionOperator //================================================================================================== // // Quest °ü·Ã ¹Ì±¸Çö ¶Ç´Â ºÐ¼® ¹Ìºñ·Î ÀÎÇÑ Æ®¸®°Å Ç׸ñ ¿Ï·á ¹Ì¼³Á¤ __IMPL_POOL(ACTION_QUEST_SATISFACTION) void ACTION_QUEST_SATISFACTION::OnAction() { const ACTION_QUEST_SATISFACTION_INFO* pInfo = (const ACTION_QUEST_SATISFACTION_INFO*)Get(); ASSERT(SAFE_NUMERIC_TYPECAST(ULONG, pInfo->GetQuestID(), QCODE)); ActionOperator::QUEST::Satisfaction op((QCODE)pInfo->GetQuestID()); if(DWORD clicked_player_key = getParent()->GetClickedPlayerKey()) { Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(pPlayer) { op(pPlayer); return; } SUNLOG(eFULL_LOG, "[ACTION_QUEST_SATISFACTION::OnAction] [U:%d] Player NULL!!", clicked_player_key); return; } else { // Satisfied Player getParent()->ForeachSatisfiedPlayer(&ActionOperator::QUEST::Satisfaction::Process, &op); getParent()->RemoveAllSatisfiedPlayer(); } } //================================================================================================== __IMPL_POOL(ACTION_QUEST_GRANT) void ACTION_QUEST_GRANT::OnAction() { const ACTION_QUEST_GRANT_INFO* pInfo = (const ACTION_QUEST_GRANT_INFO*)Get(); ASSERT(SAFE_NUMERIC_TYPECAST(ULONG, pInfo->GetQuestID(), QCODE)); ActionOperator::QUEST::Grant op((QCODE)pInfo->GetQuestID()); if(DWORD clicked_player_key = getParent()->GetClickedPlayerKey()) { Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(pPlayer) { op(pPlayer); return; } SUNLOG(eFULL_LOG, "[ACTION_QUEST_SATISFACTION::OnAction] [U:%d] Player NULL!!", clicked_player_key); } else { // Satisfied Player getParent()->ForeachSatisfiedPlayer(&ActionOperator::QUEST::Grant::Process, &op); getParent()->RemoveAllSatisfiedPlayer(); } } __IMPL_POOL(ACTION_QUEST_SETUP) void ACTION_QUEST_SETUP::OnAction() { const ACTION_QUEST_SETUP_INFO* pInfo = (const ACTION_QUEST_SETUP_INFO*)Get(); ASSERT(SAFE_NUMERIC_TYPECAST(ULONG, pInfo->GetQuestID(), QCODE)); QCODE questCode = (QCODE)pInfo->GetQuestID(); ActionOperator::QUEST::Setup op((QCODE)pInfo->GetQuestID()); const DWORD clicked_player_key = getParent()->GetClickedPlayerKey(); if(clicked_player_key != 0) { Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(pPlayer) { op(pPlayer); return; } SUNLOG(eFULL_LOG, "[ACTION_QUEST_SATISFACTION::OnAction] [U:%d] Player NULL!!", clicked_player_key); } else { // Satisfied Player getParent()->ForeachSatisfiedPlayer(&ActionOperator::QUEST::Setup::Process, &op); getParent()->RemoveAllSatisfiedPlayer(); } } //================================================================================================== __IMPL_POOL(ACTION_USE_CATEGORY) void ACTION_USE_CATEGORY::OnAction() { } //================================================================================================== // ±âÁ¸¿¡ Á¸ÀçÇÏ´Â ¾×¼Ç Æ®¸®°Å //__IMPL_POOL(ACTION_CREATE_MONSTER) __IMPL_POOL(ACTION_CREATE_MONSTER_GROUP) void ACTION_CREATE_MONSTER_GROUP::OnAction() { // ´ÙÀ½ÀÇ ·çƾÀº ACTION_CREATE_MONSTER ÀÇ ·ÎÁ÷À» µû¶óÇÑ °ÍÀÌ´Ù. m_iRegenCount = 0; m_dwTimeout = 0; const ACTION_CREATE_MONSTER_GROUP_INFO* pInfo = Get(); if(ns_trigger::PARTY == pInfo->GetPartyState()) { m_iMaxCreateCount = pInfo->GetGroupCount(); } else //ns_trigger::PERSONAL { // ¾ÆÁ÷ À¯Àú°¡ ¸Ê¿¡ µé¾î ¿ÀÁö ¾ÊÀº»óȲ¿¡¼­ 0ÀÌ µÉ ¼ö ÀÖ´Ù.!!!!!@@@@ DWORD count = getMGR()->GetPlayerNum(); m_iMaxCreateCount = pInfo->GetGroupCount() * (count == 0 ? 1 : count); } } BOOL ACTION_CREATE_MONSTER_GROUP::OnActionUpdate() { const ACTION_CREATE_MONSTER_GROUP_INFO* pInfo = Get(); if(pInfo->GetGroupCount() == m_iRegenCount) { return FALSE; } else { // ¸ó½ºÅÍ ±×·ì »ý¼ºÀº ÁֱⰡ ¾ø´Ù. ÇÏÁö¸¸ Çѹø¿¡ »ý¼ºÇÔÀ¸·Î ÀÎÇÑ ºÎÇÏ(²À ¼­¹ö¸¸ÀÇ ºÎÇÏ´Â ¾Æ´ÒÅÍ) // ¸¦ °¨¾ÈÇØ Àû´çÇÑ Áֱ⸦ ÁÖ°í »ý¼ºÇϱâ·Î ÇÏÀÚ. ´Ü À̸¦ À§ÇÑ Å×½ºÆ®´Â ÇØºÁ¾ß ÇÒ °ÍÀÌ´Ù. const DWORD dwInterval = 100000; //10ÃÊ? DWORD dwCurTick = GetTickCount(); if(m_dwTimeout < dwCurTick) { m_dwTimeout = dwCurTick + dwInterval; ASSERT(SAFE_NUMERIC_TYPECAST(int, pInfo->GetAreaID(), DWORD)); ASSERT(SAFE_NUMERIC_TYPECAST(int, pInfo->GetAreaID(), WORD)); // !!!!!!!¸ó½ºÅÍ ±×·ì »ý¼º Äڵ尡 ºüÁ®ÀÖ´Ù!!!!!! } } return TRUE; } //================================================================================================== __IMPL_POOL(ACTION_SHOW_OR_HIDE_UNIT) void ACTION_SHOW_OR_HIDE_UNIT::OnAction() { // ¸ÊÅøÀÇ °üÁ¡¿¡¼­´Â ¸ó½ºÅÍ ³ªÅ¸³²/»ç¶óÁüÀÌÁö¸¸, ½ÇÁ¦ ¼­¹ö¿¡¼­´Â // ¸ó½ºÅÍ À¯´Ö »ý¼º / ÆÄ±« //__NA_276_20070213_UNIT_TRIGGER const ACTION_SHOW_OR_HIDE_UNIT_INFO* pInfo = (const ACTION_SHOW_OR_HIDE_UNIT_INFO*)Get(); const INT is_hide = pInfo->GetIsHide(); const WzID unit_ID = pInfo->GetMonsterUnitID(); switch (is_hide) { case ACTION_SHOW_OR_HIDE_UNIT_INFO::SHOW: getMGR()->CreateNPCForUnitID(unit_ID); break; case ACTION_SHOW_OR_HIDE_UNIT_INFO::HIDE: getMGR()->DestroyNPCForUnitID(unit_ID); break; default: SUNLOG(eCRITICAL_LOG, "ACTION_SHOW_OR_HIDE_UNIT:Invalid Value(%u)", pInfo->GetIsHide()); return; } } //================================================================================================== __IMPL_POOL(ACTION_SHOW_GUIDE_MSGBOX) void ACTION_SHOW_GUIDE_MSGBOX::OnAction() { #ifndef __WAVERIX_NEW_TRIGGER_WORKS_TEST__ SUNLOG(eCRITICAL_LOG, "ACTION_SHOW_GUIDE_MSGBOX::OnAction"); #endif } //================================================================================================== __IMPL_POOL(ACTION_SHOW_OR_HIDE_MSGBOX) void ACTION_SHOW_OR_HIDE_MSGBOX::OnAction() { } //================================================================================================== // ¸ó½ºÅÍ ·£´ý ½ºÆù __IMPL_POOL(ACTION_RANDOM_MONSTER_SPAWN) BOOST_STATIC_ASSERT(ACTION_RANDOM_MONSTER_SPAWN::MAX_RANDOM_STEP_NUM == DropRatioInfoList::MAX_RANDOM_STEP_NUM); void ACTION_RANDOM_MONSTER_SPAWN::OnAction() { m_nCurRegenCount = 0; m_RegenTimer.SetTimer(0); //< óÀ½¿¡´Â ¹Ýµå½Ã Çѹø ½ÇÇàÇÑ´Ù. m_MonsterRandomizer.Clear(); const ACTION_RANDOM_MONSTER_SPAWN_INFO* pInfo = Get(); BOOL rt = FALSE; // ¸ó½ºÅÍ 1ºÎÅÍ 5±îÁö ´ëÀÔÇÑ´Ù. rt = m_MonsterRandomizer.AddRatio(pInfo->GetMonsterID_1(), pInfo->GetMonsterRate_1(), MAX_MONSTER_RATIO); ASSERT(rt); rt = m_MonsterRandomizer.AddRatio(pInfo->GetMonsterID_2(), pInfo->GetMonsterRate_2(), MAX_MONSTER_RATIO); ASSERT(rt); rt = m_MonsterRandomizer.AddRatio(pInfo->GetMonsterID_3(), pInfo->GetMonsterRate_3(), MAX_MONSTER_RATIO); ASSERT(rt); rt = m_MonsterRandomizer.AddRatio(pInfo->GetMonsterID_4(), pInfo->GetMonsterRate_4(), MAX_MONSTER_RATIO); ASSERT(rt); rt = m_MonsterRandomizer.AddRatio(pInfo->GetMonsterID_5(), pInfo->GetMonsterRate_5(), MAX_MONSTER_RATIO); ASSERT(rt); } BOOL ACTION_RANDOM_MONSTER_SPAWN::OnActionUpdate() { const ACTION_RANDOM_MONSTER_SPAWN_INFO* pInfo = Get(); // ÇöÀç ¸®Á¨µÈ Ƚ¼ö¿Í Max¸®Á¨ Ƚ¼ö°¡ °°´Ù¸é... ±×¸¸ ÇÑ´Ù. if(m_nCurRegenCount == pInfo->GetMaxRegenCount()) { return FALSE; } if(m_RegenTimer.IsExpired() == 0) return TRUE; //1. ¸®Á¨½Ã°£ÀÌ Áö³µ´Ù¸é.. ¸®Á¨½Ã°£À» ´Ù½Ã Àû¿ëÇϰí.. m_RegenTimer.SetTimer(pInfo->GetRegenTime()); ns_trigger::CreateMonsterArgs args; args.Clear(); args.Init(pInfo->GetAreaID(), 0); WzVector vDirection = { pInfo->GetDirX(), pInfo->GetDirY(), pInfo->GetDirZ() }; short angle = 0; { float fangle = Math_GetAngleFromVector(&vDirection); // (NOTE) ¾È¿¡¼­ Normalize¼öÇà. angle = static_cast(fangle * 180.0f / WZ_PI); } for(int loop = GetMonsterCount(); loop; --loop) { MONSTERCODE monsterCode = GetRandomMonster(); #ifdef _NA_003649_20111115_BATTLE_ZONE_HARDMODE GameZone* game_zone = getMGR()->GetField()->GetGameZone(); if(game_zone->GetZoneType() == eZONETYPE_MISSION) { MONSTERCODE replaace_monster_code = \ AppliedNpcDependencyChain::Instance()->GetRepleaceMonsterCode(game_zone, monsterCode, true); if (replaace_monster_code) { monsterCode = replaace_monster_code; } } #endif //_NA_003649_20111115_BATTLE_ZONE_HARDMODE args.AddInfo(monsterCode, angle); } ns_trigger::CreateMonsterByTrigger(getMGR(), &args); ++m_nCurRegenCount; return TRUE; } //¸®Á¨½Ãų ¸ó½ºÅÍÀÇ °³¼ö¸¦ ±¸ÇÑ´Ù. int ACTION_RANDOM_MONSTER_SPAWN::GetMonsterCount() { int nMonsterCount = 0; int nRandomCnt = random(Get()->GetMinCreateMonsterCnt(), Get()->GetMaxCreateMonsterCnt()); if(Get()->GetIsParty() == ns_trigger::PERSONAL) { // ¾ÆÁ÷ À¯Àú°¡ ¸Ê¿¡ µé¾î ¿ÀÁö ¾ÊÀº»óȲ¿¡¼­ 0ÀÌ µÉ ¼ö ÀÖ´Ù.!!!!!@@@@ DWORD dwPlayerNum = getMGR()->GetPlayerNum(); nMonsterCount = nRandomCnt * (dwPlayerNum == 0 ? 1 : dwPlayerNum); } else nMonsterCount = nRandomCnt; #ifdef __TRIGGER_TEST_LOG SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_RANDOM_MONSTER_SPAWN, °³¼ö(%d)", getParent()->TriggerID(), nMonsterCount); #endif return nMonsterCount; } int ACTION_RANDOM_MONSTER_SPAWN::GetRandomMonster() { return m_MonsterRandomizer.RandomizedKey(); } //================================================================================================== class ShowTheFloor { private: MSG_CG_TRIGGER_SHOW_THE_FLOOR_CMD& m_rMsgCMD; WORD m_PartyKey; public: ShowTheFloor(MSG_CG_TRIGGER_SHOW_THE_FLOOR_CMD& rMsgCMD) : m_rMsgCMD(rMsgCMD), m_PartyKey(0) {} void operator()(Player* pPlayer) { WORD partyKey = pPlayer->GetPartyState().GetPartyKey(); m_rMsgCMD.m_dwPlayerKey = pPlayer->GetObjectKey(); m_PartyKey = partyKey; if(!NewGamePartyManager::Instance()->SendPacketAllMember(partyKey, &m_rMsgCMD, sizeof(m_rMsgCMD))) { pPlayer->SendPacket(&m_rMsgCMD, sizeof(m_rMsgCMD)); } } }; __IMPL_POOL(ACTION_TOWER_OF_TRIAL_SHOW_THE_FLOOR) void ACTION_TOWER_OF_TRIAL_SHOW_THE_FLOOR::OnAction() { const ACTION_TOWER_OF_TRIAL_SHOW_THE_FLOOR_INFO* pInfo = Get(); MSG_CG_TRIGGER_SHOW_THE_FLOOR_CMD msgCMD; msgCMD.m_byFloor = pInfo->GetFloor(); DWORD clicked_player_key = getParent()->GetClickedPlayerKey(); ShowTheFloor fnShowTheFloor(msgCMD); if(0 != clicked_player_key) { Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(pPlayer) fnShowTheFloor(pPlayer); } else { getParent()->ForeachSatisfiedPlayer(fnShowTheFloor); } } //#endif // //================================================================================================== class IActionTriggerEx; class WarpPlayerForRandomFieldArea { public: enum eRANDOM_FIELDnAREA { RANDOM_FIELDnAREA_MAP = 0, RANDOM_FIELDnAREA_AREA = 1 }; private: eRANDOM_FIELDnAREA m_Type; IActionTrigger* m_pIActionObj; DWORD m_FixedValue; public: WarpPlayerForRandomFieldArea(eRANDOM_FIELDnAREA eType, DWORD dwFixedVal, IActionTrigger* pIActionObj) : m_Type(eType), m_pIActionObj(pIActionObj), m_FixedValue(dwFixedVal) {} ~WarpPlayerForRandomFieldArea() {} void operator()(Player* pPlayer) { GetRandomFieldArea_N_Warp(pPlayer); } void operator()(std::pair pair_type) { operator()(pair_type.second); } BOOL GetRandomFieldArea_N_Warp(Player* pPlayer) { GameZone* pZone = pPlayer->GetGameZonePtr(); GameField* pField = pPlayer->GetField(); if(pZone == 0 || pField == 0) return FALSE; switch(m_Type) { case RANDOM_FIELDnAREA_MAP: { ACTION_RANDOM_MAP_MOVE* pAction = (ACTION_RANDOM_MAP_MOVE*)m_pIActionObj; ACTION_RANDOM_MAP_MOVE_INFO* pInfo = pAction->Get(); WORD wSelectIdx = (WORD)pAction->PrepareNextCode(); FIELDCODE fcCODE = (FIELDCODE)pInfo->GetFieldID(wSelectIdx); WARP_PLAYER::Warp(pPlayer, (MAPCODE)fcCODE, (WzID)m_FixedValue); } break; case RANDOM_FIELDnAREA_AREA: { ACTION_RANDOM_AREA_MOVE* pAction = (ACTION_RANDOM_AREA_MOVE*)m_pIActionObj; int iAreaIDX; if(m_FixedValue) iAreaIDX = (int)m_FixedValue; else { ACTION_RANDOM_AREA_MOVE_INFO* pInfo = pAction->Get(); WORD wSelectIdx = (WORD)pAction->PrepareNextCode(); iAreaIDX = (int)pInfo->GetAreaIDX(wSelectIdx); } //FIELDCODE fcCODE = pField->GetFieldCode(); //WARP_PLAYER::Warp(pPlayer, (MAPCODE)fcCODE, wzAreaID); //pPlayer->Portal(ePORTAL_TYPE_GM, fcCODE); //const CHAR* RNDAREA = "STR0"; //wzAreaID = StrToWzID(RNDAREA); CWorldBase* pWorldBase = pField->GetFieldInfo()->GetWorldBase(); const int number_of_special_areas = pWorldBase->GetNumberOfSpecialArea(); WzSpecialArea* pSpecialArea = NULL; if (!FlowControl::FCAssert(iAreaIDX < number_of_special_areas && (pSpecialArea = pWorldBase->GetSpecialAreaByIndex(iAreaIDX)) != NULL)) { SUNLOG(eCRITICAL_LOG, _T("|["__FUNCTION__"]|ÐÅÏ¢=can't find special area (index = %u)"), iAreaIDX); return false; } WzBoundingVolume& rVolume = pSpecialArea->m_wbvRegion; if(BVT_PATH_TILE_INDEX == rVolume.m_eBvType) { WzVector wvTarget = {0,0,0}; BvPathTileIndex& rPATHTILE = rVolume.m_BvPathTileIndex; DWORD dwSelectedTile = random(0, rPATHTILE.m_nCount - 1); nsAI::MovingPlanner* const pMovingPlanner = pField->GetMovingPlanner(); wvTarget = pMovingPlanner->GetRandomPosInTile(rPATHTILE.m_pdwData[dwSelectedTile]); pField->TeleportObject(pPlayer, &wvTarget); } } break; } return TRUE; } }; //================================================================================================== __IMPL_POOL(ACTION_RANDOM_MAP_MOVE) void ACTION_RANDOM_MAP_MOVE::OnInit() { //if(!m_INIT.IsInited()) //{ ACTION_RANDOM_MAP_MOVE_INFO* pInfo = Get(); m_List.clear(); int* pFIELDs = pInfo->GetFieldIDPtr(); for(DWORD i=0 ; iGetRandom(); // óÀ½ »óÅÂÀÏ ¶§, ¼øÂ÷¿Í µ¿ÀÏÇØÁֹǷΠÇѹø ÁÖ»çÀ§ ±¼·ÁÁØ´Ù. if(ACTION_RANDOM_MAP_MOVE_INFO::RNDMODE_RANDOM == bIsRandom) PrepareNextCode(); // m_INIT.Inited(); //} } DWORD ACTION_RANDOM_MAP_MOVE::PrepareNextCode() { ACTION_RANDOM_MAP_MOVE_INFO* pInfo = Get(); ENUM_T bIsRandom = (ENUM_T)pInfo->GetRandom(); DWORD dwRET = *(m_List.begin()); if(ACTION_RANDOM_MAP_MOVE_INFO::RNDMODE_RANDOM == bIsRandom) random_shuffle(m_List.begin(), m_List.end()); else rotate(m_List.begin(), m_List.begin()+1, m_List.end()); return dwRET; } void ACTION_RANDOM_MAP_MOVE::OnAction() { ACTION_RANDOM_MAP_MOVE_INFO* pInfo = Get(); // ÇØ´ç ¿µ¿ªÀ» ¾ò¾î¿Í¼­ WzID areaID_for_Moving = pInfo->GetAreaID(); //RZ~~ ENUM_T bIsRandom = (ENUM_T)pInfo->GetRandom(); ENUM_T bIsParty = (ENUM_T)pInfo->GetTarget(); ENUM_T retMapType = (ENUM_T)pInfo->GetType(); //BOOL bIsLoop = getParent()->IsLoop() ? TRUE : FALSE; if(ACTION_RANDOM_MAP_MOVE_INFO::TARGET_PARTY == bIsParty) { // ¼±ÅÃµÈ ¸ÊÄÚµå WORD wSelectedIdx = (WORD)*m_List.begin(); FIELDCODE fcCODE = (FIELDCODE)pInfo->GetFieldID(wSelectedIdx); switch(retMapType) { case ACTION_RANDOM_MAP_MOVE_INFO::RETMAP_VILLAGE: case ACTION_RANDOM_MAP_MOVE_INFO::RETMAP_STARTINGVILLAGE: { // ¹¹³Ä À̰Ç... ±âÁ¸ Çü½Ä ȣȯ? ASSERT(!"Not Supported RANDOM_MAP_MOVE"); } break; case ACTION_RANDOM_MAP_MOVE_INFO::RETMAP_BATTLEMAP: { const WzID areaID = Get()->GetAreaID(); WarpControl::WarpAllPlayer(getMGR()->GetField(), fcCODE, areaID_for_Moving); } break; }; } else { switch(retMapType) { case ACTION_RANDOM_MAP_MOVE_INFO::RETMAP_VILLAGE: case ACTION_RANDOM_MAP_MOVE_INFO::RETMAP_STARTINGVILLAGE: { // ¹¹³Ä À̰Ç... ±âÁ¸ Çü½Ä ȣȯ? ASSERT(!"Not Supported RANDOM_MAP_MOVE"); } break; case ACTION_RANDOM_MAP_MOVE_INFO::RETMAP_BATTLEMAP: { WarpPlayerForRandomFieldArea oper(WarpPlayerForRandomFieldArea::RANDOM_FIELDnAREA_MAP, areaID_for_Moving, this); DWORD clicked_player_key = getParent()->GetClickedPlayerKey(); if(clicked_player_key != 0) { Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if(pPlayer) oper(pPlayer); else { SUNLOG(eFULL_LOG, "[ACTION_RANDOM_MAP_MOVE::OnAction] [U:%d] Player NULL!!", getParent()->GetClickedPlayerKey()); return; } } else { getParent()->ForeachSatisfiedPlayer(oper); getParent()->RemoveAllSatisfiedPlayer(); } } break; } } } //================================================================================================== __IMPL_POOL(ACTION_RANDOM_AREA_MOVE) void ACTION_RANDOM_AREA_MOVE::OnInit() { //if(!m_INIT.IsInited()) //{ ACTION_RANDOM_AREA_MOVE_INFO* pInfo = Get(); m_List.clear(); int* pAREAs = pInfo->GetAreaIDXPtr(); for(DWORD i=0 ; iGetProcType(); random_shuffle(m_List.begin(), m_List.end()); return *(m_List.begin());; } void ACTION_RANDOM_AREA_MOVE::OnAction() { ACTION_RANDOM_AREA_MOVE_INFO* pInfo = Get(); ENUM_T bIsParty = (ENUM_T)pInfo->GetTarget(); ENUM_T procType = (ENUM_T)pInfo->GetProcType(); //BOOL bIsLoop = getParent()->IsLoop() ? TRUE : FALSE; // ¼±ÅÃµÈ ¸ÊÄÚµå WORD wSelectedIdx = (WORD)*m_List.begin(); int iAreaID = (int)pInfo->GetAreaIDX(wSelectedIdx); if(ACTION_RANDOM_AREA_MOVE_INFO::PROC_EACH == procType) PrepareNextCode(); if(ACTION_RANDOM_AREA_MOVE_INFO::TARGET_PARTY == bIsParty) { ASSERT(!"Not Supported RANDOM_AREA_MOVE"); } else { DWORD clicked_player_key = getParent()->GetClickedPlayerKey(); if(clicked_player_key != 0) { Player* pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); WarpPlayerForRandomFieldArea oper(WarpPlayerForRandomFieldArea::RANDOM_FIELDnAREA_AREA, (DWORD)iAreaID, this); if(pPlayer) oper(pPlayer); else { SUNLOG(eFULL_LOG, "[ACTION_RANDOM_MAP_MOVE::OnAction] [U:%d] Player NULL!!", getParent()->GetClickedPlayerKey()); return; } } else { if(ACTION_RANDOM_AREA_MOVE_INFO::PROC_EACH == procType) iAreaID = 0; WarpPlayerForRandomFieldArea oper(WarpPlayerForRandomFieldArea::RANDOM_FIELDnAREA_AREA, (DWORD)iAreaID, this); getParent()->ForeachSatisfiedPlayer(oper); getParent()->RemoveAllSatisfiedPlayer(); } } } //================================================================================================== __IMPL_POOL(ACTION_REMOVE_MONSTER) void ACTION_REMOVE_MONSTER::OnAction() { const ACTION_REMOVE_MONSTER_INFO* pActionInfo = (const ACTION_REMOVE_MONSTER_INFO*)Get(); if(!pActionInfo) return; Player* pPlayer = NULL; //1. ¸ÕÀú ÇöÀç Ŭ¸¯ÇÑ À¯Àú°¡ ÀÖ´ÂÁö üũ DWORD clicked_player_key = getParent()->GetClickedPlayerKey(); if(clicked_player_key) { pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); } else { //2. Ŭ¸¯ÇÑ À¯Àú°¡ ¾øÀ¸¸é ÇöÀç Area¿¡ µé¾î¿Â À¯Àú°¡ ÀÖ´ÂÁö üũ. pPlayer = getParent()->GetFirstSatisfiedPlayer(); } getMGR()->KillMonster(pActionInfo->GetMonsterCode(), pPlayer, pActionInfo->GetIsExpItemDrop()); } __IMPL_POOL(ACTION_ADD_EXP) class ApplyAddExpHandler { public: ApplyAddExpHandler(EXPTYPE exp) : add_exp_(exp) {} ~ApplyAddExpHandler() {} void operator()(Player* player) { //Ç÷¹ÀÌ¾î »óŰËÁõ if (player == NULL) { return; } if (player->IsDead()) { return; } player->AddExp(add_exp_, 0, 0, TRUE); } private: EXPTYPE add_exp_; }; void ACTION_ADD_EXP::OnAction() { const ACTION_ADD_EXP_INFO* pActionInfo = Get(); if(!pActionInfo) return; //ÀÌ Æ®¸®°Å´Â ¿ø·¡ Ŭ¸¯ÇÑ À¯Àú¸¸ Çϱâ·Î ÇßÁö¸¸, º¸³Ê½º·Î Áö¿ª¿¡ µé¾î¿Â À¯Àúµµ ÇØÁÖÀÚ. ´Ü Áö¿ª¿¡ µé¾î¿Â À¯Àú´Â °³Àθ¸ µÈ´Ù. Player* pPlayer = NULL; if(pActionInfo->GetIsParty()) { // ÆÄƼ¸é... ÇöÀç ¸ÊÀÇ ¸ðµç À¯Àú¿¡°Ô °æÇèÄ¡¸¦ Áö±ÞÇÑ´Ù. getMGR()->AddExpAllMember(pActionInfo->GetExp()); } else { //°³ÀÎÀ̸é.. ApplyAddExpHandler op(pActionInfo->GetExp()); getParent()->ForeachSatisfiedPlayer(op); } } //================================================================================================== class CalcAttrOpr { public: CalcAttrOpr(const ACTION_MONSTER_STAT_UP_OR_DOWN_INFO* pInfo, GameField* pGameField) : m_pGameField(pGameField) { m_MonsterCode = pInfo->GetMonsterCode(); m_AbilityInfo.m_wAbilityID = pInfo->GetAbilityID(); m_AbilityInfo.m_iOption1 = eATTACK_TYPE_PHYSICAL_OPTION; // NOTE: f110719.4L, ... m_AbilityInfo.m_iParam[0] = pInfo->GetAbilityParameter1(); m_AbilityInfo.m_iParam[1] = pInfo->GetAbilityParameter2(); m_OperationType = pInfo->GetOperationType(); // NOTE: f110719.4L if (m_OperationType != ACTION_MONSTER_STAT_UP_OR_DOWN_INFO::eOPERATION_PLUS && m_OperationType != ACTION_MONSTER_STAT_UP_OR_DOWN_INFO::eOPERATION_MINUS) { SUNLOG(eCRITICAL_LOG, _T("|[%s]|ÐÅÏ¢=unexpected monster stat control operation type = %d ") _T("of Npc(%d) of GameField(%d)|"), __FUNCTION__, m_OperationType, m_MonsterCode, pGameField->GetFieldCode()); }; _CalcAttr(); } ~CalcAttrOpr() {} void _CalcAttr() { typedef GameField::_NPC_HASH _NPC_HASH; const _NPC_HASH& rMobs = m_pGameField->GetRefNPCList(); FOREACH_CONTAINER(const _NPC_HASH::value_type& rMob, rMobs, _NPC_HASH) { NPC* const npc = rMob.second; //#ifdef _NA_004126_20120111_CHANGE_GAME_SERVER_OBJECT_FACTORY if (npc != NULL && npc->IsDeleted()) { const Object::Key key = npc->GetObjectKey(); SUNLOG( eCRITICAL_LOG, _T("|%s|%d|Object is already deleted.|ObjectKey = %d|"), __FUNCTION__, __LINE__, key ); continue; } //#endif _SetNPC(rMob.second); } } void _SetNPC(NPC* const npc) { if (npc->GetBaseInfo()->m_MonsterCode != m_MonsterCode) { return; }; eATTR_TYPE attr_type = m_AbilityInfo.GetAttrType(); if (attr_type <= eATTR_TYPE_INVALID || attr_type >= eATTR_MAX) { return; }; SkillAttrCalculator skill_calculator(npc->GetAttr()); if (m_OperationType == ACTION_MONSTER_STAT_UP_OR_DOWN_INFO::eOPERATION_PLUS) { skill_calculator.AddAttr(attr_type, \ m_AbilityInfo.m_iParam[0], m_AbilityInfo.m_iParam[1]); } else if(m_OperationType == ACTION_MONSTER_STAT_UP_OR_DOWN_INFO::eOPERATION_MINUS) { skill_calculator.DelAttr(attr_type, \ m_AbilityInfo.m_iParam[0], m_AbilityInfo.m_iParam[1]); } } private: GameField* m_pGameField; int m_MonsterCode; BASE_ABILITYINFO m_AbilityInfo; BYTE m_OperationType; }; //================================================================================================== // __IMPL_POOL(ACTION_MONSTER_STAT_UP_OR_DOWN) void ACTION_MONSTER_STAT_UP_OR_DOWN::OnAction() { const ACTION_MONSTER_STAT_UP_OR_DOWN_INFO* pInfo = (const ACTION_MONSTER_STAT_UP_OR_DOWN_INFO*)Get(); CalcAttrOpr(pInfo, getMGR()->GetField()); #ifdef __TRIGGER_TEST_LOG SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_MONSTER_STAT_UP_OR_DOWN", getParent()->TriggerID()); #endif } //================================================================================================== __IMPL_POOL(ACTION_RANDUM_TRIGER_ON_OR_OFF) void ACTION_RANDUM_TRIGER_ON_OR_OFF::OnAction() { ACTION_RANDUM_TRIGER_ON_OR_OFF_INFO* pInfo = (ACTION_RANDUM_TRIGER_ON_OR_OFF_INFO*)Get(); // Æ®¸®°ÅID´Â ÃÖ´ëÇÑ 8°³¸¦ ³ÖÀ»¼ö ÀÖµµ·Ï ÇÑ´Ù. // ·£´ýÀ¸·Î µ¹¸®·Á´Â Æ®¸®°Å°¡ 3°³¶ó¸é 3°³¸¸ ÀÔ·ÂÇϰí, ³ª¸ÓÁö 5°³¸¦ °ø¶õÀ¸·Î ³Ö¾îµµ ÀÛ¿ëÇÑ´Ù. int i = 0; for(; ACTION_RANDUM_TRIGER_ON_OR_OFF_INFO::_MAX_TRIGGER_ID > i; ++i) { if(pInfo->GetWzTriggerID(i) == 0) break; } // 1°³ Â¥¸®´Â µû·Î ÀÖÀ¸¹Ç·Î 2ÀÌ»óÀÌ µé¾î¿Â´Ù. if(i > 1) { BYTE idx = random(1,i) - 1; // 1~8 => 0~7 ·Î. DWORD WzTriggerID = pInfo->GetWzTriggerID(idx); if(ACTION_RANDUM_TRIGER_ON_OR_OFF_INFO::_TRIGGER_STATE_ON == pInfo->GetTriggerState()) getMGR()->InsertActiveTrigger(WzTriggerID); else getMGR()->RequestRemoveActiveTrigger(WzTriggerID); } } //================================================================================================== template class NotifyMessageOpr { public: NotifyMessageOpr(T& msg) : msg_(msg){} ~NotifyMessageOpr(){} void operator()(Player* pPlayer) { pPlayer->SendPacket(&msg_, sizeof(msg_)); } void operator()(std::pair pair_type) { operator()(pair_type.second); } private: T& msg_; // void operator=(const NotifyMessageOpr&); }; template NotifyMessageOpr NotifyMessage(T& msg) { return NotifyMessageOpr(msg); } // //{__NA001140_20080128_SOUND_TRIGGER_ADD __IMPL_POOL(ACTION_PLAY_MUSIC) void ACTION_PLAY_MUSIC::OnAction() { const ACTION_PLAY_MUSIC_INFO* pInfo = Get(); // _NA001385_20090924_DOMINATION_TRIGGER [°³ÀÎ,ÆÄƼ -> °³ÀÎ,¸ÊÀüü·Î º¯°æ] const BYTE byTarget = pInfo->GetTarget(); const BYTE byField = ACTION_PLAY_MUSIC_INFO::TARGET_FIELD; const BYTE byPersonal = ACTION_PLAY_MUSIC_INFO::TARGET_PERSONAL; MSG_CG_TRIGGER_PLAY_MUSIC_CMD msg; msg.m_byTarget = byTarget; msg.m_nMusCode = pInfo->GetMusCode(); switch(byTarget) { case byPersonal: { Player* pPlayer = NULL; Trigger* pTrigger = getParent(); DWORD clickPlayer = pTrigger->GetClickedPlayerKey(); if (clickPlayer) pPlayer = PlayerManager::Instance()->FindPlayerByObjKey(clickPlayer); else pPlayer = pTrigger->GetFirstSatisfiedPlayer(); if (pPlayer) pPlayer->SendPacket(&msg, sizeof(msg)); else SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_PLAY_MUSIC : Cant not Find Player", pTrigger->TriggerID()); } break; case byField: { getMGR()->ForeachPlayer(NotifyMessage(msg)); } break; } } //}__NA001140_20080128_SOUND_TRIGGER_ADD __IMPL_POOL(ACTION_DOWN_OBJETC_HP) void ACTION_DOWN_OBJETC_HP::OnAction() { const ACTION_DOWN_OBJETC_HP_INFO* pInfo = Get(); const DWORD dwObjKey = pInfo->GetdwObjKey(); MapNpc* pMapNpc = getMGR()->FindMapNpc(dwObjKey); if (NULL == pMapNpc) return; const BYTE btHPPercentage = pInfo->GetbtHPPercentage(); const DWORD dwMaxHP = pMapNpc->GetMaxHP(); const DWORD dwDecrement = (DWORD)(dwMaxHP * (btHPPercentage/100.0f)); pMapNpc->DecreaseHP(dwDecrement); pMapNpc->SendHPChange(); } __IMPL_POOL(ACTION_CHANGE_ATTACK_KIND) void ACTION_CHANGE_ATTACK_KIND::OnAction() { const ACTION_CHANGE_ATTACK_KIND_INFO* pInfo = Get(); const DWORD dwObjKey = pInfo->GetdwObjKey(); MapNpc* pMapNpc = getMGR()->FindMapNpc(dwObjKey); if (NULL == pMapNpc) return; const BYTE attackImpossibility = ACTION_CHANGE_ATTACK_KIND_INFO::ATTACK_IMPOSSIBILITY; const BYTE attackPossibility = ACTION_CHANGE_ATTACK_KIND_INFO::ATTACK_POSSIBILITY; const BYTE btPossibility = pInfo->GetbtPossibility(); StatusManager* pStatusManager = pMapNpc->GetStatusManager(); if (attackImpossibility == btPossibility) { //pStatusManager->AllocStatus(eCHAR_STATE_STEEL/*eCHAR_STATE_ETC_DISABLE_VISION_TRIGGER*/); <- X pStatusManager->AllocStatus(eCHAR_STATE_STEEL, 15 * 1000/*eCHAR_STATE_ETC_DISABLE_VISION_TRIGGER*/); //<- better... #ifdef _CN_000000_20130731_STATE_STEEL_MOD_BUG_LOG SUNLOG(eCRITICAL_LOG,"["__FUNCTION__"]:AllocStatus(eCHAR_STATE_STEEL, BASE_EXPIRE_TIME_INFINITY)"); #endif // #ifdef _CN_000000_20130731_STATE_STEEL_MOD_BUG_LOG } else if(attackPossibility == btPossibility) { pStatusManager->Remove(eCHAR_STATE_STEEL); } } class NotifyStampOpr { public: NotifyStampOpr(){} ~NotifyStampOpr(){} void operator()(Player* pPlayer) { GUILDGUID guildGuid = pPlayer->GetGuildGuid(); GameZone* pZone = pPlayer->GetGameZonePtr(); if (!pZone || INVALID_GUILDGUID == guildGuid || eZONETYPE_DOMINATION_FIELD != pZone->GetZoneType()) return; GameDominationField* pDomiZone = (GameDominationField*)pZone; if (guildGuid == pDomiZone->GetOffenseGuild()) pPlayer->SendAllFieldCollectionInfo(); } void operator()(std::pair pair_type) { operator()(pair_type.second); } }; __IMPL_POOL(ACTION_ACTIVE_STAMP) void ACTION_ACTIVE_STAMP::OnAction() { NotifyStampOpr op; getMGR()->ForeachPlayer(op); } //================================================================================================== __IMPL_POOL(ACTION_ATTACK_OBJECTKIND) class AattackActionNPCCodeTypeOpr { public: AattackActionNPCCodeTypeOpr(const MONSTERCODE monster_code, const eACTION_ATTACK_TYPE attack_type) : monster_code_(monster_code) , attack_type_(attack_type) {} ~AattackActionNPCCodeTypeOpr(){} void operator()(NPC* npc) { const BASE_NPCINFO* const base_info = npc->GetBaseInfo(); const MONSTERCODE monster_code = base_info->m_MonsterCode; if (monster_code == monster_code_) { StatusManager* status_manager = npc->GetStatusManager(); ACTION_ATTACK_OBJECTKIND::StatusProc(*status_manager, attack_type_); } } void operator()(std::pair pair_type) { operator()(pair_type.second); } private: const MONSTERCODE monster_code_; const eACTION_ATTACK_TYPE attack_type_; }; void ACTION_ATTACK_OBJECTKIND::OnAction() { const ACTION_ATTACK_OBJECTKIND_INFO* info = Get(); const DWORD object_key = info->GetdwObjectKey(); const eACTION_ATTACK_TYPE attack_type = static_cast(info->GetbyAttack()); const eOBJECTCODE_TYPE object_type = static_cast(info->GetbyObjectType()); ProcessFunction action; action = GetProcessFunction(object_type); (this->*action)(object_key, attack_type); } ACTION_ATTACK_OBJECTKIND::ProcessFunction ACTION_ATTACK_OBJECTKIND::GetProcessFunction(const eOBJECTCODE_TYPE object_type) { switch(object_type) { case NPCCODE_TYPE: return &ACTION_ATTACK_OBJECTKIND::ActionNPCCodeType; case UNITID_TYPE: return &ACTION_ATTACK_OBJECTKIND::ActionUnitIDType; case MAPNPC_TYPE: return &ACTION_ATTACK_OBJECTKIND::ActionMapNpcType; } return &ACTION_ATTACK_OBJECTKIND::ActionDefaultType; } VOID ACTION_ATTACK_OBJECTKIND::ActionDefaultType(const DWORD object_key, const eACTION_ATTACK_TYPE attack_type) { __UNUSED((object_key, attack_type)); SUNLOG(eDEV_LOG, "[ACTION_ATTACK_OBJECTKIND]:TYPE_ERROR"); } VOID ACTION_ATTACK_OBJECTKIND::ActionNPCCodeType(const DWORD object_key, const eACTION_ATTACK_TYPE attack_type) { const MONSTERCODE npc_code = static_cast(object_key); AattackActionNPCCodeTypeOpr op(npc_code,attack_type); getMGR()->ForeachNPC(op); } VOID ACTION_ATTACK_OBJECTKIND::ActionUnitIDType(const DWORD object_key, const eACTION_ATTACK_TYPE attack_type) { NPC* const npc = getMGR()->FindNPCForUnitID(object_key); if (npc == NULL) return; StatusManager* const status_manager = npc->GetStatusManager(); StatusProc(*status_manager, attack_type); } VOID ACTION_ATTACK_OBJECTKIND::ActionMapNpcType(const DWORD object_key, const eACTION_ATTACK_TYPE attack_type) { MapNpc* const map_npc = getMGR()->FindMapNpc(object_key); if (map_npc == NULL) return; StatusManager* const status_manager = map_npc->GetStatusManager(); StatusProc(*status_manager, attack_type); } //[¸ó½ºÅÍ/À¯´Ö/¿ÀºêÁ§Æ®]¸¦ °ø°Ý ÇÒ ¼ö [ÀÖ°Ô/¾ø°Ô] ¸¸µç´Ù // ƯÁ¤ ¸ó½ºÅÍ °´Ã¼°¡ Ç÷¹À̾°Ô °ø°Ý ´çÇÏÁö ¾Ê°Ô ¸¸µç´Ù. VOID ACTION_ATTACK_OBJECTKIND::StatusProc(StatusManager& status_manager, const eACTION_ATTACK_TYPE attack_type) { switch(attack_type) { case ATTACK_IMPOSSIBILITY: status_manager.AllocStatus(eCHAR_STATE_ETC_DISABLE_VISION_TRIGGER); break; case ATTACK_POSSIBILITY: status_manager.Remove(eCHAR_STATE_ETC_DISABLE_VISION_TRIGGER); break; default: break; } } //================================================================================================== __IMPL_POOL(ACTION_ACTIVE_SKILL_OBJECTKIND) class ActiveSkillActionNPCCodeTypeOpr { public: ActiveSkillActionNPCCodeTypeOpr(const MONSTERCODE monster_code, const SLOTCODE skill_code) : monster_code_(monster_code), skill_code_(skill_code) {} ~ActiveSkillActionNPCCodeTypeOpr(){} void operator()(NPC* npc) { const BASE_NPCINFO* const base_info = npc->GetBaseInfo(); const MONSTERCODE monster_code = base_info->m_MonsterCode; if (monster_code == monster_code_) { npc->UseSkill(skill_code_); } } void operator()(std::pair pair_type) { operator()(pair_type.second); } private: const MONSTERCODE monster_code_; const SLOTCODE skill_code_; }; void ACTION_ACTIVE_SKILL_OBJECTKIND::OnAction() { const ACTION_ACTIVE_SKILL_OBJECTKIND_INFO* info = Get(); const DWORD object_key = info->GetdwObjectKey(); const eOBJECTCODE_TYPE object_type = static_cast(info->GetbyObjectType()); const SLOTCODE skill_code = static_cast(info->GetdwSkillCode()); NPC* npc = NULL; switch(object_type) { case UNITID_TYPE: npc = getMGR()->FindNPCForUnitID(object_key); if (npc != NULL) npc->UseSkill(skill_code); break; case MAPNPC_TYPE: npc = getMGR()->FindMapNpc(object_key); if (npc != NULL) npc->UseSkill(skill_code); break; case NPCCODE_TYPE: { const MONSTERCODE npc_code = static_cast(object_key); ActiveSkillActionNPCCodeTypeOpr op(npc_code, skill_code); getMGR()->ForeachNPC(op); } break; default: SUNLOG(eDEV_LOG, "[ACTION_ACTIVE_SKILL_OBJECTKIND]:TYPE_ERROR"); return; } } //================================================================================================== __IMPL_POOL(ACTION_SHOW_MESSAGEBOX_OBJECTKIND) class ShowMessageBoxActionNPCCodeTypeOpr { public: ShowMessageBoxActionNPCCodeTypeOpr(const MONSTERCODE monster_code, const DWORD message_code) : monster_code_(monster_code) { msg_cmd_.m_dwMessageCode = message_code; } ~ShowMessageBoxActionNPCCodeTypeOpr(){} void operator()(NPC* npc) { const BASE_NPCINFO* const base_info = npc->GetBaseInfo(); const MONSTERCODE monster_code = base_info->m_MonsterCode; if (monster_code == monster_code_) { msg_cmd_.m_dwObjectKey = npc->GetObjectKey(); npc->SendPacketAround(&msg_cmd_, sizeof(msg_cmd_)); } } void operator()(std::pair pair_type) { operator()(pair_type.second); } private: const MONSTERCODE monster_code_; MSG_CG_TRIGGER_DISPLAY_BALLOON_MSGBOX_CMD msg_cmd_; }; void ACTION_SHOW_MESSAGEBOX_OBJECTKIND::OnAction() { const ACTION_SHOW_MESSAGEBOX_OBJECTKIND_INFO* info = Get(); const DWORD object_key = info->GetdwObjectKey(); const eOBJECTCODE_TYPE object_type = static_cast(info->GetbyObjectType()); const DWORD message_code = info->GetdwMessageCode(); MSG_CG_TRIGGER_DISPLAY_BALLOON_MSGBOX_CMD msg_cmd; msg_cmd.m_dwMessageCode = message_code; NPC* npc = NULL; switch(object_type) { case UNITID_TYPE: npc = getMGR()->FindNPCForUnitID(object_key); if (npc != NULL) { msg_cmd.m_dwObjectKey = npc->GetObjectKey(); npc->SendPacketAround(&msg_cmd, sizeof(msg_cmd)); } break; case MAPNPC_TYPE: npc = getMGR()->FindMapNpc(object_key); if (npc != NULL) { msg_cmd.m_dwObjectKey = npc->GetObjectKey(); npc->SendPacketAround(&msg_cmd, sizeof(msg_cmd)); } break; case NPCCODE_TYPE: { const MONSTERCODE npc_code = static_cast(object_key); ShowMessageBoxActionNPCCodeTypeOpr op(npc_code, message_code); getMGR()->ForeachNPC(op); } break; default: SUNLOG(eDEV_LOG, "[ACTION_SHOW_MESSAGEBOX_OBJECTKIND]:TYPE_ERROR"); return; } } //================================================================================================== __IMPL_POOL(ACTION_SET_ATTACK_STATE_OBJECTKIND) class SetAttackStateActionNPCCodeTypeOpr { public: SetAttackStateActionNPCCodeTypeOpr(const MONSTERCODE monster_code, const eACTION_ATTACK_TYPE attack_type, const eTARGET_SEARCH_TYPE search_type, const DWORD dest_object_key) : monster_code_(monster_code), attack_type_(attack_type), search_type_(search_type), dest_object_key_(dest_object_key){} ~SetAttackStateActionNPCCodeTypeOpr(){} void operator()(NPC* npc) { const BASE_NPCINFO* const base_info = npc->GetBaseInfo(); const MONSTERCODE monster_code = base_info->m_MonsterCode; if (monster_code == monster_code_) { ACTION_SET_ATTACK_STATE_OBJECTKIND::StatusProc(npc, attack_type_, search_type_, dest_object_key_); } } void operator()(std::pair pair_type) { operator()(pair_type.second); } private: const MONSTERCODE monster_code_; const eACTION_ATTACK_TYPE attack_type_; const eTARGET_SEARCH_TYPE search_type_; const DWORD dest_object_key_; }; VOID ACTION_SET_ATTACK_STATE_OBJECTKIND::StatusProc(NPC* src_npc, const eACTION_ATTACK_TYPE attack_type, const eTARGET_SEARCH_TYPE search_type, const DWORD dest_object_key) { StatusManager* const status_manager = src_npc->GetStatusManager(); switch(attack_type) { case ATTACK_IMPOSSIBILITY: { const BASE_NPCINFO* const info = src_npc->GetBaseInfo(); const BYTE attitude = info->m_byAttitude; const eTARGET_SEARCH_TYPE search_type = src_npc->FindSearchTypeByAttitude(attitude); src_npc->SetSearchType(search_type, 0); status_manager->Remove(eCHAR_STATE_ETC_SKIP_UPDATE_TARGET_LIST); src_npc->ChangeState(STATE_ID_WANDER); } break; case ATTACK_POSSIBILITY: { src_npc->SetSearchType(search_type, dest_object_key); status_manager->AllocStatus(eCHAR_STATE_ETC_SKIP_UPDATE_TARGET_LIST); TargetManager* const target_manager = src_npc->GetTargetManager(); target_manager->ClearBattleRecord(); } break; default: break; } } void ACTION_SET_ATTACK_STATE_OBJECTKIND::OnAction() { const ACTION_SET_ATTACK_STATE_OBJECTKIND_INFO* info = Get(); const DWORD object_key = info->GetdwObjectKey(); const DWORD dest_object_key = info->GetdwDestObjectKey(); eACTION_ATTACK_TYPE action_attack_type = static_cast(info->GetbyAttack()); const eOBJECTCODE_TYPE object_type = static_cast(info->GetbyObjectType()); const eOBJECTCODE_TYPE dest_object_type = static_cast(info->GetbyDestObjectType()); //.// eTARGET_SEARCH_TYPE search_type = eRARGET_NOT_SEARCH; switch(dest_object_type) { case UNITID_TYPE: search_type = eRARGET_SEARCH_UNITID; break; case MAPNPC_TYPE: search_type = eRARGET_SEARCH_MAPOBJECTID; break; case NPCCODE_TYPE: search_type = eRARGET_SEARCH_MONSTERCODE; break; case NON_TYPE: // _NA_0_20100817_HELLON_LAST_TRIGGER (°ø°ÝÀÌ ¸ØÃçÁø »óÅÂ) search_type = eRARGET_SEARCH_NOT_SEARCH_AND_TARGET_CHNAGE; action_attack_type = static_cast(!info->GetbyAttack()); break; } //.// NPC* src_npc = NULL; switch(object_type) { case UNITID_TYPE: src_npc = getMGR()->FindNPCForUnitID(object_key); break; case MAPNPC_TYPE: src_npc = getMGR()->FindMapNpc(object_key); break; } //.// if (src_npc != NULL) { StatusProc(src_npc, action_attack_type, search_type, dest_object_key); } else { const MONSTERCODE npc_code = static_cast(object_key); SetAttackStateActionNPCCodeTypeOpr op(npc_code, action_attack_type, search_type, dest_object_key); getMGR()->ForeachNPC(op); } } //================================================================================================== __IMPL_POOL(ACTION_DESTROY_OBJECTKIND) void ACTION_DESTROY_OBJECTKIND::OnAction() { const ACTION_DESTROY_OBJECTKIND_INFO* info = Get(); const DWORD object_key = info->GetdwObjectKey(); const BOOL is_reward = info->GetbyReward() == ACTION_DESTROY_OBJECTKIND_INFO::REWARD ? TRUE : FALSE; Player* player = NULL; const DWORD clicked_player_key = getParent()->GetClickedPlayerKey(); if(clicked_player_key) player = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); else player = getParent()->GetFirstSatisfiedPlayer(); NPC* npc = NULL; const eOBJECTCODE_TYPE object_type = static_cast(info->GetbyObjectType()); switch(object_type) { case NPCCODE_TYPE: getMGR()->KillMonster(static_cast(object_key), player, is_reward); return; case UNITID_TYPE: npc = getMGR()->FindNPCForUnitID(object_key); if (npc) getMGR()->KillOneMonster(npc, player, is_reward); break; case MAPNPC_TYPE: npc = getMGR()->FindMapNpc(object_key); if (npc) getMGR()->KillOneMonster(npc, player, is_reward); break; default: SUNLOG(eDEV_LOG, "[ACTION_DESTROY_OBJECTKIND]:TYPE_ERROR"); return; } } __IMPL_POOL(ACTION_CREATE_MONSTER_LINKED_MAPOBJECT) void ACTION_CREATE_MONSTER_LINKED_MAPOBJECT::OnAction() { const ACTION_CREATE_MONSTER_LINKED_MAPOBJECT_INFO* pInfo = (const ACTION_CREATE_MONSTER_LINKED_MAPOBJECT_INFO*)Get(); const DWORD mapobjectID = pInfo->GetdwObjectKey(); MAPOBJECT_INFO* mapobject_info = getMGR()->FindMapObjectInfo(mapobjectID); DWORD dwCode = mapobject_info->dwExtraInfos[eMAPOBJECT_MONSTER]; ASSERT(SAFE_NUMERIC_TYPECAST( DWORD, dwCode, WORD )); WORD NPCCode = (WORD)dwCode; getMGR()->CreateMapNPC( NPCCode, &mapobject_info->wvPos, mapobject_info ); } //================================================================================================== __IMPL_POOL(ACTION_CONTROL_TIMER) void ACTION_CONTROL_TIMER::OnAction() { const ACTION_CONTROL_TIMER_INFO* pInfo = (const ACTION_CONTROL_TIMER_INFO*)Get(); MSG_CG_TRIGGER_CONTROL_TIMER_CMD msg; msg.m_dwTime = pInfo->GetdwTime(); msg.m_byControlType = pInfo->GetbyControlType(); getMGR()->ForeachPlayer(NotifyMessage(msg)); } // implemented by _NA_0_20100705_DOMINATION_EVENT __IMPL_POOL(ACTION_DO_COMMAND) void ACTION_DO_COMMAND::OnAction() { const ACTION_DO_COMMAND_INFO* pInfo = (const ACTION_DO_COMMAND_INFO*)Get(); switch(pInfo->GetbyCommandType()) { case ACTION_DO_COMMAND_INFO::END_REGEN_EVENT: // Á¡·ÉÀü º¸»ó À̺¥Æ® Æ®¸®°ÅÀÇ Á¾·á ¸Þ½ÃÁö(º¸»ó Á¾·á ó¸®) { GameField* field = getMGR()->GetField(); GameZone* zone = field->GetGameZone(); if (zone->GetZoneType() != eZONETYPE_DOMINATION_FIELD) { return; } GameDominationField* domination = static_cast(zone); domination->EndEventTrigger(); //_NA_20100604_BETTER_DOMINATION_MANAGER //Á¡·ÉÀü º¸»ó ¸ó½ºÅÍ »ç³É Ä«¿îÆ® Ƚ¼ö¸¦ ´Ã¸°´Ù. domination->UpdateGuildInfoByDomination(field->GetFieldCode()); } break; } } // ACTION_MOVE_CONTROL was implemented by _NA_0_20100817_HELLON_LAST_TRIGGER __IMPL_POOL(ACTION_MOVE_CONTROL) class MoveControlNPCCodeTypeOpr { public: MoveControlNPCCodeTypeOpr(const MONSTERCODE monster_code, const eACTION_MOVE_TYPE move_type) : monster_code_(monster_code) , move_type_(move_type) {} ~MoveControlNPCCodeTypeOpr(){} void operator()(NPC* npc) { const BASE_NPCINFO* const base_info = npc->GetBaseInfo(); const MONSTERCODE monster_code = base_info->m_MonsterCode; if (monster_code == monster_code_) ACTION_MOVE_CONTROL::StatusProc(npc, move_type_); } void operator()(std::pair pair_type) { operator()(pair_type.second); } private: const MONSTERCODE monster_code_; const eACTION_MOVE_TYPE move_type_; }; VOID ACTION_MOVE_CONTROL::StatusProc(NPC* npc, const eACTION_MOVE_TYPE move_type) { StatusManager* const status_manager = npc->GetStatusManager(); switch(move_type) { case MOVE_IMPOSSIBILITY: status_manager->AllocStatus(eCHAR_STATE_ETC_TRIGGER_HOLDING); npc->ChangeState(STATE_ID_STOP_IDLE); break; case MOVE_POSSIBILITY: status_manager->Remove(eCHAR_STATE_ETC_TRIGGER_HOLDING); npc->ChangeState(STATE_ID_WANDER); break; default: break; } } void ACTION_MOVE_CONTROL::OnAction() { const ACTION_MOVE_CONTROL_INFO* pInfo = (const ACTION_MOVE_CONTROL_INFO*)Get(); const DWORD object_key = pInfo->GetdwObjectKey(); const eOBJECTCODE_TYPE object_type = static_cast(pInfo->GetbyObjectType()); const eACTION_MOVE_TYPE move_type = static_cast(pInfo->GetbyMove()); switch(object_type) { case UNITID_TYPE: { NPC* npc = getMGR()->FindNPCForUnitID(object_key); if (npc) StatusProc(npc, move_type); } break; case NPCCODE_TYPE: { const MONSTERCODE npc_code = static_cast(object_key); MoveControlNPCCodeTypeOpr op(npc_code, move_type); getMGR()->ForeachNPC(op); } break; default: SUNLOG(eDEV_LOG, "[ACTION_MOVE_CONTROL]:TYPE_ERROR"); return; } } __IMPL_POOL(ACTION_ANIMATION_CONTROL) class AnimationControlNPCCodeTypeOpr { public: AnimationControlNPCCodeTypeOpr(const MONSTERCODE monster_code, const DWORD animation_code) : monster_code_(monster_code) , animation_code_(animation_code) {} ~AnimationControlNPCCodeTypeOpr(){} void operator()(NPC* npc) { const BASE_NPCINFO* const base_info = npc->GetBaseInfo(); const MONSTERCODE monster_code = base_info->m_MonsterCode; if (monster_code == monster_code_) npc->SetTriggerAnimationCode(animation_code_); } void operator()(std::pair pair_type) { operator()(pair_type.second); } private: const MONSTERCODE monster_code_; const DWORD animation_code_; }; void ACTION_ANIMATION_CONTROL::OnAction() { const ACTION_ANIMATION_CONTROL_INFO* pInfo = (const ACTION_ANIMATION_CONTROL_INFO*)Get(); DWORD animation_code = 0; if (pInfo->GetbyLoop2() == ACTION_ANIMATION_CONTROL_INFO::LOOP) { animation_code = pInfo->GetdwAnimationCode2(); } else if (pInfo->GetbyLoop1() == ACTION_ANIMATION_CONTROL_INFO::LOOP) { animation_code = pInfo->GetdwAnimationCode1(); } const DWORD object_key = pInfo->GetdwObjectKey(); const eOBJECTCODE_TYPE object_type = static_cast(pInfo->GetbyObjectType()); switch(object_type) { case UNITID_TYPE: { NPC* npc = getMGR()->FindNPCForUnitID(object_key); if (npc) npc->SetTriggerAnimationCode(animation_code); } break; case MAPNPC_TYPE: { NPC* npc = getMGR()->FindMapNpc(object_key); if (npc) npc->SetTriggerAnimationCode(animation_code); } break; case NPCCODE_TYPE: { const MONSTERCODE npc_code = static_cast(object_key); AnimationControlNPCCodeTypeOpr op(npc_code, animation_code); getMGR()->ForeachNPC(op); } break; default: SUNLOG(eDEV_LOG, "[ACTION_ANIMATION_CONTROL]:TYPE_ERROR"); return; } } // _NA_002098_20110307_ADD_NPC_CONTROL_TRIGGER __IMPL_POOL(ACTION_NPC_APPLY_DAMAGE) class NPCApplyDamageOper { public: NPCApplyDamageOper(const MONSTERCODE monster_code, const INT damage) : monster_code_(monster_code), damage_(damage) { } ~NPCApplyDamageOper() {} void operator()(NPC* npc) { const BASE_NPCINFO* const base_info = npc->GetBaseInfo(); const MONSTERCODE monster_code = base_info->m_MonsterCode; if (monster_code == monster_code_) { npc->DecreaseHP(damage_); npc->SendAreaDamage(damage_); } } void operator()(std::pair pair_type) { operator()(pair_type.second); } private: const MONSTERCODE monster_code_; const INT damage_; }; void ACTION_NPC_APPLY_DAMAGE::OnAction() { const ACTION_NPC_APPLY_DAMAGE_INFO* const apply_damage_info = Get(); const eOBJECTCODE_TYPE object_type = static_cast(apply_damage_info->GetObjectType()); const DWORD object_key = apply_damage_info->GetObjectKey(); const INT damage = apply_damage_info->GetDamage(); switch(object_type) { case UNITID_TYPE: { NPC* const npc_unit = getMGR()->FindNPCForUnitID(object_key); if (npc_unit != NULL) { npc_unit->DecreaseHP(damage); npc_unit->SendAreaDamage(damage); } } break; case MAPNPC_TYPE: { NPC* const npc_map_obj = getMGR()->FindMapNpc(object_key); if (npc_map_obj != NULL) { npc_map_obj->DecreaseHP(damage); npc_map_obj->SendAreaDamage(damage); } } break; case NPCCODE_TYPE: { const MONSTERCODE monster_code = static_cast(object_key); NPCApplyDamageOper oper(monster_code, damage); getMGR()->ForeachNPC(oper); } break; default: SUNLOG(eDEV_LOG, "[ACTION_NPC_APPLY_DAMAGE]:TYPE_ERROR"); return; } } //------------------------------------------------------------------------------ //_NA_004777_20120428_ADD_COMPLETE_COLLECTION_TRIGGER //------------------------------------------------------------------------------ class CollectAllCollectiveCmd { public: CollectAllCollectiveCmd(GameField* game_field, bool val, CODETYPE* object_key_ptr) : game_field_(game_field), is_active_(val), object_key_ptr_(object_key_ptr) { } void operator()(Player* player) { if (is_active_) { player->SendAllFieldCollectionInfo(); } else { CollectionManager* const collection_manager = game_field_->GetCollectManeger(); if (collection_manager == NULL) { return; } MSG_CG_COLLECT_DEACTIVE_BRD brd_msg; brd_msg.m_byCount = 0; for (int i = 0; i < MSG_CG_COLLECT_DEACTIVE_BRD::_MAX_FIELDCOLLECT_INFO_SIZE; ++i) { CODETYPE object_key = MAP_OBJECT_KEY + object_key_ptr_[i]; Collection* collection = static_cast(game_field_->FindObject(COLLECTION_OBJECT, object_key)); if (obj_util::IsValid(collection) == false) { continue; } if (collection->is_active() == true) { continue; } MAPOBJECT_INFO* pMapInfo = collection->GetMapObjectInfo(); RC::eCOLLECT_RESULT rc = collection_manager->ChkCondision(player, pMapInfo->CollectionID); if(RC::RC_COLLECT_SUCCESS != rc) continue; brd_msg.m_ObjKeyCollection[brd_msg.m_byCount++] = collection->GetObjectKey(); } if(brd_msg.m_byCount) { player->SendPacket(&brd_msg, (WORD)brd_msg.GetSize()); } } } void operator()(std::pair pair_type) { operator()(pair_type.second); } private: GameField* game_field_; bool is_active_; CODETYPE* object_key_ptr_; }; //------------------------------------------------------------------------------ __IMPL_POOL(ACTION_COMPLETE_COLLECTION) //------------------------------------------------------------------------------ VOID ACTION_COMPLETE_COLLECTION::OnAction() { GameField* const field = getMGR()->GetField(); if (field == NULL) { return; } CollectionManager* const collection_manager = field->GetCollectManeger(); if (collection_manager == NULL) { return; } ACTION_COMPLETE_COLLECTION_INFO* const info = Get(); if (info == NULL) { return; } for (int i = 0; i < ACTION_COMPLETE_COLLECTION_INFO::kMaxCollectObject; ++i) { CODETYPE object_key = MAP_OBJECT_KEY + info->GetObjectKey(i); Collection* collection = static_cast(field->FindObject(COLLECTION_OBJECT, object_key)); if (collection != NULL) { collection->set_active(info->GetEnableType() != 0); } } CollectAllCollectiveCmd op(field, info->GetEnableType() != 0, info->GetObjectKeyPtr()); getMGR()->ForeachPlayer(op); } //------------------------------------------------------------------------------------------------- // _NA_000000_20130104_ADD_ACTION_TRIGGER_APPLY_HPMPSD //------------------------------------------------------------------------------------------------- __IMPL_POOL(ACTION_APPLY_HPMPSD) class ApplyHPMPSDHandler { public: ApplyHPMPSDHandler(const BYTE point_type, const DWORD figure, const BYTE apply_type, const int team_key) : point_type_(point_type), figure_(figure), apply_type_(apply_type), team_key_(team_key), is_team_(false) { if (team_key_ > -1) is_team_ = true; } ~ApplyHPMPSDHandler(){} void operator()(Player* player) { ASSERT(player); // Ç÷¹À̾ Á×¾ú´Ù¸é Æ®¸®°Å Àû¿ë´ë»ó¿¡¼­ Á¦¿Ü.. if (player->IsDead()) return; // Ç÷¹¾îÀÇ ÆÀÀ» °í·ÁÇØ¾ß ÇÑ´Ù¸é.. if (is_team_) { if (team_key_ != player->GetTeamKey()) return; } DWORD apply_figure = 0; switch(point_type_) { case ACTION_APPLY_HPMPSD_INFO::kHP: { if (apply_type_ == ACTION_APPLY_HPMPSD_INFO::kIncrease) { apply_figure = player->IncreaseHP(figure_); #if !defined(_NA_000000_20140224_SUMMONER_REFACTORING) // ¼Òȯ¼ö °í·Á.. SummonedNPCs* const summon_npc = \ SummonManager::Instance()->FindSummonNPCs(player->GetSummonerKey()); if (summon_npc == NULL) break; Summoned* const summoned = summon_npc->FindSummoned(0); if (summoned == NULL) break; summoned->IncreaseHP(figure_); #endif //_NA_000000_20140224_SUMMONER_REFACTORING } else { apply_figure = player->DecreaseHP(figure_); MSG_CG_TRIGGER_AREADAMAGE_BRD msg; msg.m_dwObjectKey = player->GetObjectKey(); msg.m_wDamage = figure_; msg.m_dwHP = player->GetHP(); #ifdef _NA_008804_20160502_COMBAT_LOG time_t t; util::TimeSync::time(&t); msg.m_SvrTime = t; #endif //(_NA_008804_20160502_COMBAT_LOG) player->SendPacketAround((MSG_BASE_FORWARD*)&msg, sizeof(msg)); #if !defined(_NA_000000_20140224_SUMMONER_REFACTORING) // ¼Òȯ¼ö °í·Á.. SummonedNPCs* const summon_npc = \ SummonManager::Instance()->FindSummonNPCs(player->GetSummonerKey()); if (summon_npc == NULL) break; // ¾ÆÁ÷ ¼ÒȯÇÒ¼öÀÖ´Â °³Ã¼¼ö°¡ 1°³À̱⠶§¹®¿¡ objectkey°ªÀ» ±¸ÇöÇÏÁö ¾Ê¾Ò´Ù.. // object ۰ªÀ» ±¸ÇöÇÏÁö ¾Ê¾Æ ¸»µµ ¾ÈµÇ´Â 0°ªÀ¸·Î ¼Òȯ¼ö¸¦ ã´Â´Ù.. // FindSummoned ÇÔ¼ö ³»ºÎ¸¦ º¸¸é ¿ÀºêÁ§Æ® ۰ªÀÌ ÀÖÀ¸¸é ¾ÈµÇ´Â ±¸Á¶´Ù.. Summoned* const summoned = summon_npc->FindSummoned(0); if (summoned) { summoned->DecreaseHP(figure_); MSG_CG_TRIGGER_AREADAMAGE_BRD msg; msg.m_dwObjectKey = summoned->GetObjectKey(); msg.m_wDamage = figure_; msg.m_dwHP = summoned->GetHP(); #ifdef _NA_008804_20160502_COMBAT_LOG time_t t; util::TimeSync::time(&t); msg.m_SvrTime = t; #endif //(_NA_008804_20160502_COMBAT_LOG) player->SendPacketAround((MSG_BASE_FORWARD*)&msg, sizeof(msg)); } #endif //_NA_000000_20140224_SUMMONER_REFACTORING } } break; case ACTION_APPLY_HPMPSD_INFO::KMP: { if (apply_type_ == ACTION_APPLY_HPMPSD_INFO::kIncrease) apply_figure = player->IncreaseMP(figure_); else apply_figure = player->DecreaseMP(figure_); } break; case ACTION_APPLY_HPMPSD_INFO::KSD: { if (apply_type_ == ACTION_APPLY_HPMPSD_INFO::kIncrease) apply_figure = player->IncreaseSD(figure_); else apply_figure = player->DecreaseSD(figure_); } break; } } void operator()(std::pair pair_type) { operator()(pair_type.second); } private: BYTE point_type_; // HP/MP/SD DWORD figure_; // ¼öÄ¡ BYTE apply_type_; // Áõ°¡/°¨¼Ò int team_key_; bool is_team_; }; void ACTION_APPLY_HPMPSD::OnAction() { const ACTION_APPLY_HPMPSD_INFO* const apply_hpmpsd_info = Get(); ApplyHPMPSDHandler op(apply_hpmpsd_info->GetPointType(), apply_hpmpsd_info->GetFigure(), apply_hpmpsd_info->GetApplyType(), apply_hpmpsd_info->GetTeamKey()); const BYTE target_type = apply_hpmpsd_info->GetTargetType(); switch(target_type) { case ACTION_APPLY_HPMPSD_INFO::kPerson: // °³ÀÎ { Player* player = NULL; Trigger* trigger = getParent(); DWORD click_player = trigger->GetClickedPlayerKey(); if (click_player) player = PlayerManager::Instance()->FindPlayerByObjKey(click_player); else player = trigger->GetFirstSatisfiedPlayer(); if (player) op(player); else SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_APPLY_DAMAGE : Cant not Find Player", trigger->TriggerID()); } break; case ACTION_APPLY_HPMPSD_INFO::kField: // Àüü getMGR()->ForeachPlayer(op); break; case ACTION_APPLY_HPMPSD_INFO::kTeam: // ÆÀ getParent()->ForeachSatisfiedPlayer(op); break; } } //================================================================================================== //------------------------------------------------------------------------------------------------- // _NA_006658_20130422_ADD_ACTION_TRIGGER_CHANGE_OBJECT_HP //------------------------------------------------------------------------------------------------- __IMPL_POOL(ACTION_CHANGE_OBJECT_HP) void ACTION_CHANGE_OBJECT_HP::OnAction() { const ACTION_CHANGE_OBJECT_HP_INFO* const info = Get(); const DWORD object_key = info->GetObjectkey(); // ÇØ´ç ¿ÀºêÁ§Æ® Ű MapNpc* const map_npc = getMGR()->FindMapNpc(object_key); if (NULL == map_npc) { return; } const BYTE calc_type = info->GetCalcType(); // °è»ê ŸÀÔ (ºñÀ²/¼öÄ¡) const BYTE apply_type = info->GetApplyType(); // Àû¿ë ŸÀÔ (Áõ°¡/°¨¼Ò) DWORD figure = info->GetFigure(); // °ª const DWORD max_hp = map_npc->GetMaxHP(); DWORD change_hp = 0; if (calc_type == ACTION_CHANGE_OBJECT_HP_INFO::kPersentage) { if (figure > 100) { figure = 100; } change_hp = static_cast(max_hp * (figure / 100.0f)); } else if(calc_type == ACTION_CHANGE_OBJECT_HP_INFO::kValue) { change_hp = figure; } if (apply_type == ACTION_CHANGE_OBJECT_HP_INFO::kIncrease) { map_npc->IncreaseHP(change_hp); } else if(apply_type == ACTION_CHANGE_OBJECT_HP_INFO::kDecrease) { map_npc->DecreaseHP(change_hp); } map_npc->SendHPChange(); } //================================================================================================= //------------------------------------------------------------------------------------------------- // _NA_006619_20130422_ADD_ACTION_TRIGGER_CHANGE_RADAR_MAP //------------------------------------------------------------------------------------------------- class ChangeRadarMapHandler { public: explicit ChangeRadarMapHandler(const WzID sub_map_id_) : sub_map_id_(sub_map_id_) { } ~ChangeRadarMapHandler() { } void operator()(Player* player) { MSG_CG_TRIGGER_CHANGE_RADAR_MAP_CMD cmd_msg; cmd_msg.sub_map_id = sub_map_id_; player->SendPacket(&cmd_msg, sizeof(cmd_msg)); } void operator()(std::pair pair_type) { operator()(pair_type.second); } private: WzID sub_map_id_; }; __IMPL_POOL(ACTION_CHANGE_RADAR_MAP) void ACTION_CHANGE_RADAR_MAP::OnAction() { ACTION_CHANGE_RADAR_MAP_INFO* info = Get(); const WzID sub_map_id = info->GetSubMapID(); DWORD clicked_player_key = getParent()->GetClickedPlayerKey(); if(clicked_player_key != 0) { Player* const player = PlayerManager::Instance()->FindPlayerByObjKey(clicked_player_key); if (obj_util::IsValid(player)) { ChangeRadarMapHandler op(sub_map_id); op(player); } } else { ChangeRadarMapHandler op(sub_map_id); getParent()->ForeachSatisfiedPlayer(op); getParent()->RemoveAllSatisfiedPlayer(); } } //================================================================================================= //------------------------------------------------------------------------------------------------- // _NA_006654_20120422_MISSION_TRIGGER_ADD_AND_MODIFY //------------------------------------------------------------------------------------------------- __IMPL_POOL(ACTION_ATTACH_STATE_RANGE) class AttachStateRangeHandler { public: AttachStateRangeHandler(DWORD object_key, WzVector* pos, float range, eCHAR_STATE_TYPE state_type, DWORD time_duration, BYTE apply_type) { object_key_ = object_key; object_pos_ = *pos; range_ = range * range; state_type_ = state_type; time_duration_ = time_duration; apply_type_ = apply_type; } ~AttachStateRangeHandler(){} void operator()(Player* const player) { const WzVector& cur_pos = *player->GetPosPtr(); WzVector distance = object_pos_ - cur_pos; float distance2 = VectorLength2(&distance); if(distance2 <= range_) { if (apply_type_ == 0) { // »óÅºο© StatusManager* const status_manager = player->GetStatusManager(); ALLOC_STATUS_PAIR steel = status_manager->AllocStatus(state_type_, time_duration_); if (steel.second) steel.second->SendStatusAddBRD(); } else if (apply_type_ == 1) { // »óÅÂÇØÁ¦ if (!player->GetStatusManager()->Remove(state_type_)) { MSG_CG_STATUS_REMOVE_BRD brd_msg; brd_msg.m_dwTargetKey = player->GetObjectKey(); brd_msg.m_dwStatusCode = static_cast(state_type_); player->SendPacketAround(&brd_msg, brd_msg.GetSize()); } } } } void operator()(std::pair pair_type) { operator()(pair_type.second); } private: DWORD object_key_; float range_; WzVector object_pos_; eCHAR_STATE_TYPE state_type_; DWORD time_duration_; BYTE apply_type_; }; void ACTION_ATTACH_STATE_RANGE::OnAction() { ACTION_ATTACH_STATE_RANGE_INFO* info = Get(); #ifdef _NA_007266_20140530_BUG_ATTACH_STATE_TRIGGER eOBJECTCODE_TYPE object_type = static_cast(info->GetbyObjectType()); WzVector object_pos; const float range = info->GetfRange(); switch(object_type) { case NPCCODE_TYPE: // MKS 2014.05.30 // Ãʱ⠱¸ÇöÀǵµ¸¦ ¾Ë ¼ö ¾øÀ½. // ÇØ´ç ¸ó½ºÅÍÄڵ带 °¡Áø ¸ðµç ¸ó½ºÅͰ¡ ÀÌ Æ®¸®°Å µ¿ÀÛ½ÃÄѾßÇϳª? // ±¸Çö º¸·ù break; case UNITID_TYPE: { NPC* unit = getMGR()->FindNPCForUnitID(info->GetdwObjectKey()); ASSERT(NULL != unit); DEBUG_CODE(if(!unit) return ;); object_pos = *unit->GetPosPtr(); } break; case MAPNPC_TYPE: { MapObject* map_object = getMGR()->FindMapObject(info->GetdwObjectKey()); ASSERT(NULL != map_object); DEBUG_CODE(if(!map_object) return ;); object_pos = *map_object->GetPosPtr(); } break; case NON_TYPE: default: break; } #else MapObject* map_object = getMGR()->FindMapObject(info->GetdwObjectKey()); ASSERT(NULL != map_object); DEBUG_CODE(if(!map_object) return ;); WzVector object_pos = *map_object->GetPosPtr(); const float range = info->GetfRange(); #endif //_NA_007266_20140530_BUG_ATTACH_STATE_TRIGGER AttachStateRangeHandler handler(info->GetdwObjectKey(), &object_pos, range, static_cast(info->GetdwStateCode()), info->GetdwTimeDuration(), info->GetbyApplyType()); getMGR()->ForeachPlayer(handler); } //================================================================================================= //------------------------------------------------------------------------------------------------- // _NA_000000_20130925_ADD_ACTION_TRIGGER_CHANGE_PLAYER_HP //------------------------------------------------------------------------------------------------- __IMPL_POOL(ACTION_CHANGE_PLAYER_HP) class ChangePlayerHPHandler { public: ChangePlayerHPHandler(const DWORD figure, const BYTE calc_type, const BYTE apply_type) : figure_(figure), // HP º¯µ¿½Ãų ¼öÄ¡ calc_type_(calc_type), // °è»ê ŸÀÔ (ºñÀ²/¼öÄ¡) apply_type_(apply_type) // Áõ°¡/°¨¼Ò {} ~ChangePlayerHPHandler(){} void operator()(Player* player) { ASSERT(player); // Ç÷¹À̾ Á×¾ú´Ù¸é Æ®¸®°Å Àû¿ë´ë»ó¿¡¼­ Á¦¿Ü.. if (player->IsDead()) return; //ºñÀ²/¼öÄ¡ ¿©ºÎ ÆÇ´ÜÇÏ°í ½ÇÁ¦ HPº¯È­½Ãų °ª ±¸ÇÑ´Ù const DWORD player_max_hp = player->GetMaxHP(); DWORD change_hp = 0; if (calc_type_ == ACTION_CHANGE_PLAYER_HP_INFO::kPersentage) { if (figure_ > 100) { figure_ = 100; } change_hp = static_cast(player_max_hp * (figure_ / 100.0f)); } else if(calc_type_ == ACTION_CHANGE_PLAYER_HP_INFO::kValue) { change_hp = figure_; } DWORD apply_figure = 0; if (apply_type_ == ACTION_CHANGE_PLAYER_HP_INFO::kIncrease) { apply_figure = player->IncreaseHP(change_hp); } else if (apply_type_ == ACTION_CHANGE_PLAYER_HP_INFO::kDecrease) { apply_figure = player->DecreaseHP(change_hp); MSG_CG_TRIGGER_AREADAMAGE_BRD msg; msg.m_dwObjectKey = player->GetObjectKey(); msg.m_wDamage = apply_figure; msg.m_dwHP = player->GetHP(); #ifdef _NA_008804_20160502_COMBAT_LOG time_t t; util::TimeSync::time(&t); msg.m_SvrTime = t; #endif //(_NA_008804_20160502_COMBAT_LOG) player->SendPacketAround((MSG_BASE_FORWARD*)&msg, sizeof(msg)); } } void operator()(std::pair pair_type) { operator()(pair_type.second); } private: DWORD figure_; // ¼öÄ¡ BYTE calc_type_; // °è»ê ŸÀÔ (ºñÀ²/¼öÄ¡) BYTE apply_type_; // Áõ°¡/°¨¼Ò }; void ACTION_CHANGE_PLAYER_HP::OnAction() { const ACTION_CHANGE_PLAYER_HP_INFO* const info = Get(); Player* player = NULL; Trigger* trigger = getParent(); //value °¡Á®¿Â´Ù const BYTE target_type = info->GetTargetType(); const BYTE calc_type = info->GetCalcType(); // °è»ê ŸÀÔ (ºñÀ²/¼öÄ¡) const BYTE apply_type = info->GetApplyType(); // Àû¿ë ŸÀÔ (Áõ°¡/°¨¼Ò) DWORD figure = info->GetFigure(); // ºñÀ²/°ª ChangePlayerHPHandler op(figure, calc_type, apply_type); switch(target_type) { case ACTION_CHANGE_PLAYER_HP_INFO::kTargetPerson: // °³ÀÎ { DWORD click_player = trigger->GetClickedPlayerKey(); if (click_player) player = PlayerManager::Instance()->FindPlayerByObjKey(click_player); else trigger->ForeachSatisfiedPlayer(op); if (player) op(player); else SUNLOG(eDEV_LOG, "[TriggerID:%u]:ACTION_APPLY_DAMAGE : Cant not Find Player", trigger->TriggerID()); } break; case ACTION_CHANGE_PLAYER_HP_INFO::kTargetParty: // ÆÄƼ DWORD click_player = trigger->GetClickedPlayerKey(); if(click_player != 0) { player = PlayerManager::Instance()->FindPlayerByObjKey(click_player); WORD partyKey = player->GetPartyState().GetPartyKey(); if(!NewGamePartyManager::Instance()->For_eachPlayers(partyKey, op)) SUNLOG(eCRITICAL_LOG, "[ACTION_REWARD_PLAYER] GameParty is NULL! (%s)'s PartyKey (%u)", player->GetCharName(), partyKey); return; } else { getMGR()->ForeachPlayer(op); } break; } }