#include "StdAfx.h" #include "SummonAbility.h" #include "SummonedNPCs.h" #include "SummonManager.h" #include "GroupParser.h" #include "Summoned.h" #include "MovingPlanner.h" #ifdef _NA_007667_20141001_WITCHBLADE_SKILL #include "Skill.h" #endif //_NA_007667_20141001_WITCHBLADE_SKILL bool SummonAbility::ExecuteEffect(BYTE* /*msg*/, WORD& /*msg_size*/) { Character* const attacker = GetAttacker(); if (attacker == NULL) { return false; } GameField *pField = attacker->GetField(); if (!pField) return false; // Ç÷¹À̾ »ç¿ëÇÑ ¼Òȯ½ºÅ³ÀÎÁö ¸ó½ºÅͰ¡ »ç¿ëÇÑ ½ºÅ³ÀÎÁö¿¡ µû¶ó¼­ ¼Òȯ¸ó½ºÅÍ Á¾·ù°¡ ´Þ¶óÁø´Ù. BOOL bPlayerSkill = attacker->IsEqualObjectKind(PLAYER_OBJECT); // ÆÄ¶ó¹ÌÅÍ ¼ÂÆÃ const BASE_ABILITYINFO* const ability_info = GetBaseAbilityInfo(); BYTE bySummonGroupType = ability_info->m_iOption1; // ¸ó½ºÅÍ(0), ±×·ì(0) DWORD dwSummonID = ability_info->m_iOption2; // ¸ó½ºÅÍID, ±×·ìID BYTE bySummonedNum = ability_info->m_iParam[0]; if (!bySummonedNum || bySummonedNum > MAX_SUMMONED_NUM) return false; // ¼Òȯ NPC ¸®½ºÆ®¸¦ ã°Å³ª ¾øÀ¸¸é »ý¼ºÇÑ´Ù. #ifdef _NA_007667_20141001_WITCHBLADE_SKILL SummonedNPCs *pOwnerSummonNPCs = NULL; Player* player = NULL; if (bPlayerSkill == true) { player = reinterpret_cast(attacker); } if (player != NULL && player->GetCharType() == eCHAR_WITCHBLADE) { pOwnerSummonNPCs = SummonManager::Instance()->AllocSummonNPCs(attacker, bPlayerSkill, ability_info->m_wAbilityID); } else { pOwnerSummonNPCs = SummonManager::Instance()->AllocSummonNPCs(attacker, bPlayerSkill); } #else SummonedNPCs *pOwnerSummonNPCs = SummonManager::Instance()->AllocSummonNPCs(attacker, bPlayerSkill); #endif //_NA_007667_20141001_WITCHBLADE_SKILL if (!pOwnerSummonNPCs) return false; // ¼Òȯ´ë»óÀÌ ±×·ìÀÎ °æ¿ì if (bySummonGroupType == 1) { BASE_GROUPINFO *pGroupInfo = GroupParser::Instance()->GetGroupInfo((WORD)dwSummonID); // ÀÏ´Ü º¸·ù... } // NPC¸¦ »ý¼ºÇÑ´Ù. if (bPlayerSkill) { CreateSummoned(attacker, pOwnerSummonNPCs, dwSummonID, bySummonedNum); } else { CreateSummonNPC(attacker, pOwnerSummonNPCs, dwSummonID, bySummonedNum); } #if !defined(_NA_000000_20140224_SUMMONER_REFACTORING) attacker->SetSummonerKey(pOwnerSummonNPCs->GetSummonerKey()); #endif //_NA_000000_20140224_SUMMONER_REFACTORING return false; // ÀǵµµÈ false : msg ¸¦ »ç¿ë ÇÏÁö ¾Ê´Â´Ù. Effect ¸¦ Ŭ¶ó¿¡ ÁÖÁö ¾Ê´Â´Ù. } void SummonAbility::CreateSummoned(Character *pSummoner, SummonedNPCs *pOwnerSummonNPCs, DWORD dwCode, DWORD dwNumberOfNPCs) { GameField *pField = pSummoner->GetField(); if (!pField) return; int iCurTile = pSummoner->GetPathExplorer()->GetTile(); if (iCurTile < 0) { WzVector wvSummonerPos; pSummoner->GetPos(&wvSummonerPos); SUNLOG(eCRITICAL_LOG, "[CreateSummoned] Summoner " "Key[%d] Type[%d] CurTile[%d]" "FCode[%d] pos[%d,%d,%d]", pSummoner->GetObjectKey(), pSummoner->GetObjectType(), iCurTile, pField->GetFieldCode(), wvSummonerPos.x, wvSummonerPos.y, wvSummonerPos.z); return; } DWORD dwExpireTime = GetBaseAbilityInfo()->m_iParam[2]; WzVector wvSummonerPos; pSummoner->GetPos(&wvSummonerPos); WzVector wvSummonPos; float fMoveLength2 = 0; // (WAVERIX)(080926)(NOTE) // - thinking... »ç¿ë »ç·Ê·Î ºÁ¼­´Â regenµÉ À§Ä¡ °áÁ¤½Ã ŸÀÏ °í·Á°¡ ÇÊ¿äÇÏ°Ô µÉ µí. ¾Ö±¸ ÇÒ ÀÏ ¸¹¾ÆÁö³ß. nsAI::MovingPlanner* const pMovingPlanner = pField->GetMovingPlanner(); // ¸ó½ºÅÍ »ý¼º bool is_pos_input=false; for (DWORD i = 0; i < dwNumberOfNPCs; ++i) { #ifdef _NA_007667_20141001_WITCHBLADE_SKILL //°íÁ¤Çü ¼Òȯ¼öÀÏ °æ¿ì main_target_pos À§Ä¡·Î ¼Òȯ½ÃŲ´Ù. //±× ¿Ü¿£ ±âÁ¸Ã³·³ ÀÚ±âÁÖÀ§¿¡ ¼Òȯ is_pos_input=false; if (GetAbilityID() == eABILITY_SUMMON_IMMOVABLE) { Skill* skill = GetSKill(); if (skill != NULL) { SkillInfo* skill_info = skill->GetSkillInfo(); if(skill_info != NULL) { wvSummonPos = skill_info->main_target_pos_; is_pos_input = true; } } } if (is_pos_input == false) { // ¼ÒȯüÀÇ À§Ä¡°áÁ¤(¼ÒȯÀÚ¿Í ³Ê¹« ¸Ö¸® ¶³¾îÁöÁö ¾Êµµ·Ï ÇÑ´Ù.) for (int iPosTrial = 0; iPosTrial < 51; ++iPosTrial) { wvSummonPos = pMovingPlanner->GetRandomPosInTile(iCurTile); fMoveLength2 = VectorLength2(&(wvSummonerPos - wvSummonPos)); if (fMoveLength2 >= 4.0 && fMoveLength2 <= 16.0) break; // 50¹øÀ» µµ´Â µ¿¾È¿¡µµ ¼Òȯü À§Ä¡¸¦ °áÁ¤ÇÏÁö ¸øÇߴ°¡? if (iPosTrial >= 50) { SUNLOG(eFULL_LOG, "[Ability::CreateSummoned] Can't Find wvSummonPos whithin 50 Times"); break; } } } #else // ¼ÒȯüÀÇ À§Ä¡°áÁ¤(¼ÒȯÀÚ¿Í ³Ê¹« ¸Ö¸® ¶³¾îÁöÁö ¾Êµµ·Ï ÇÑ´Ù.) for (int iPosTrial = 0; iPosTrial < 51; ++iPosTrial) { wvSummonPos = pMovingPlanner->GetRandomPosInTile(iCurTile); fMoveLength2 = VectorLength2(&(wvSummonerPos - wvSummonPos)); if (fMoveLength2 >= 4.0 && fMoveLength2 <= 16.0) break; // 50¹øÀ» µµ´Â µ¿¾È¿¡µµ ¼Òȯü À§Ä¡¸¦ °áÁ¤ÇÏÁö ¸øÇߴ°¡? if (iPosTrial >= 50) { SUNLOG(eFULL_LOG, "[Ability::CreateSummoned] Can't Find wvSummonPos whithin 50 Times"); break; } } #endif //_NA_007667_20141001_WITCHBLADE_SKILL // ¼Òȯü »ý¼º Summoned* pSummoned = pField->CreateSummonByPlayer(dwCode, &wvSummonPos, pSummoner, pOwnerSummonNPCs, dwExpireTime, GetSkillCode(), NULL); if (pSummoned) { MSG_CG_SUMMON_CURRENT_HP_CMD summonMsg; summonMsg.m_dwSummonedObjKey = pSummoned->GetObjectKey(); summonMsg.m_dwMaxHP = pSummoned->GetMaxHP(); summonMsg.m_dwHP = pSummoned->GetHP(); summonMsg.m_dwSpeedRatio = pSummoned->GetMoveSpeedRatio(); pSummoner->SendPacket(&summonMsg, sizeof(MSG_CG_SUMMON_CURRENT_HP_CMD)); } } } void SummonAbility::CreateSummonNPC(Character *pSummoner, SummonedNPCs *pOwnerSummonNPCs, DWORD dwCode, DWORD dwNumberOfNPCs) { GameField *pField = pSummoner->GetField(); if (!pField) return; int iCurTile = pSummoner->GetPathExplorer()->GetTile(); if (iCurTile < 0) { SUNLOG(eCRITICAL_LOG, "[CreateSummonNPC] pSummoner Key[%d] Type[%d] CurTile[%d]", pSummoner->GetObjectKey(), pSummoner->GetObjectType(), iCurTile); return; } WzVector wvSummonPos; // (WAVERIX)(080926)(NOTE) // - thinking... »ç¿ë »ç·Ê·Î ºÁ¼­´Â regenµÉ À§Ä¡ °áÁ¤½Ã ŸÀÏ °í·Á°¡ ÇÊ¿äÇÏ°Ô µÉ µí. ¾Ö±¸ ÇÒ ÀÏ ¸¹¾ÆÁö³ß. nsAI::MovingPlanner* const pMovingPlanner = pField->GetMovingPlanner(); // ¸ó½ºÅÍ »ý¼º for (DWORD i = 0; i < dwNumberOfNPCs; ++i) { // À§Ä¡ °áÁ¤ wvSummonPos = pMovingPlanner->GetRandomPosInTile(iCurTile); // ¼Òȯü »ý¼º pField->CreateSummonByNPC(dwCode, &wvSummonPos, pSummoner, pOwnerSummonNPCs); } }