void CParty::Link(LPCHARACTER pkChr) { TMemberMap::iterator it; if (pkChr->IsPC()) it = m_memberMap.find(pkChr->GetPlayerID()); else it = m_memberMap.find(pkChr->GetVID()); if (it == m_memberMap.end()) { sys_err("%s is not member of this party", pkChr->GetName()); return; } // 플레이어 파티일 경우 업데이트 이벤트 생성 if (m_bPCParty && !m_eventUpdate) { party_update_event_info* info = AllocEventInfo<party_update_event_info>(); info->pid = m_dwLeaderPID; m_eventUpdate = event_create(party_update_event, info, PASSES_PER_SEC(3)); } if (it->second.bRole == PARTY_ROLE_LEADER) m_pkChrLeader = pkChr; sys_log(2, "PARTY[%d] %s linked to party", GetLeaderPID(), pkChr->GetName()); it->second.pCharacter = pkChr; pkChr->SetParty(this); if (pkChr->IsPC()) { if (it->second.strName.empty()) { it->second.strName = pkChr->GetName(); } SendPartyJoinOneToAll(pkChr->GetPlayerID()); SendPartyJoinAllToOne(pkChr); SendPartyLinkOneToAll(pkChr); SendPartyLinkAllToOne(pkChr); SendPartyInfoAllToOne(pkChr); SendPartyInfoOneToAll(pkChr); SendParameter(pkChr); //sys_log(0, "PARTY-DUNGEON connect %p %p", this, GetDungeon()); if (GetDungeon() && GetDungeon()->GetMapIndex() == pkChr->GetMapIndex()) { pkChr->SetDungeon(GetDungeon()); } RequestSetMemberLevel(pkChr->GetPlayerID(), pkChr->GetLevel()); } }
void NormalAttackAffect(LPCHARACTER pkAttacker, LPCHARACTER pkVictim) { // 독 공격은 특이하므로 특수 처리 if (pkAttacker->GetPoint(POINT_POISON_PCT) && !pkVictim->IsAffectFlag(AFF_POISON)) { if (number(1, 100) <= pkAttacker->GetPoint(POINT_POISON_PCT)) pkVictim->AttackedByPoison(pkAttacker); } int iStunDuration = 2; if (pkAttacker->IsPC() && !pkVictim->IsPC()) iStunDuration = 4; AttackAffect(pkAttacker, pkVictim, POINT_STUN_PCT, IMMUNE_STUN, AFFECT_STUN, POINT_NONE, 0, AFF_STUN, iStunDuration, "STUN"); AttackAffect(pkAttacker, pkVictim, POINT_SLOW_PCT, IMMUNE_SLOW, AFFECT_SLOW, POINT_MOV_SPEED, -30, AFF_SLOW, 20, "SLOW"); }
void operator() (LPCHARACTER ch) { if (ch->IsPC()) { ch->ExitToSavedLocation(); } }
LPPARTY CPartyManager::CreateParty(LPCHARACTER pLeader) { if (pLeader->GetParty()) return pLeader->GetParty(); LPPARTY pParty = M2_NEW CParty; if (pLeader->IsPC()) { //TPacketGGParty p; //p.header = HEADER_GG_PARTY; //p.subheader = PARTY_SUBHEADER_GG_CREATE; //p.pid = pLeader->GetPlayerID(); //P2P_MANAGER::instance().Send(&p, sizeof(p)); TPacketPartyCreate p; p.dwLeaderPID = pLeader->GetPlayerID(); db_clientdesc->DBPacket(HEADER_GD_PARTY_CREATE, 0, &p, sizeof(TPacketPartyCreate)); sys_log(0, "PARTY: Create %s pid %u", pLeader->GetName(), pLeader->GetPlayerID()); pParty->SetPCParty(true); pParty->Join(pLeader->GetPlayerID()); m_set_pkPCParty.insert(pParty); } else { pParty->SetPCParty(false); pParty->Join(pLeader->GetVID()); } pParty->Link(pLeader); return (pParty); }
void FSetWarpLocation::operator() (LPCHARACTER ch) { if (ch->IsPC()) { ch->SetWarpLocation (map_index, x, y); } }
void CWarMap::IncMember(LPCHARACTER ch) { if (!ch->IsPC()) return; sys_log(0, "WarMap::IncMember"); DWORD gid = 0; if (ch->GetGuild()) gid = ch->GetGuild()->GetID(); bool isWarMember = ch->GetQuestFlag("war.is_war_member") > 0 ? true : false; if (isWarMember && gid != m_TeamData[0].dwID && gid != m_TeamData[1].dwID) { ch->SetQuestFlag("war.is_war_member", 0); isWarMember = false; } if (isWarMember) { if (gid == m_TeamData[0].dwID) { m_TeamData[0].AppendMember(ch); } else if (gid == m_TeamData[1].dwID) { m_TeamData[1].AppendMember(ch); } event_cancel(&m_pkTimeoutEvent); sys_log(0, "WarMap +m %u(cur:%d, acc:%d) vs %u(cur:%d, acc:%d)", m_TeamData[0].dwID, m_TeamData[0].GetCurJointerCount(), m_TeamData[0].GetAccumulatedJoinerCount(), m_TeamData[1].dwID, m_TeamData[1].GetCurJointerCount(), m_TeamData[1].GetAccumulatedJoinerCount()); } else { ++m_iObserverCount; sys_log(0, "WarMap +o %d", m_iObserverCount); ch->SetObserverMode(true); ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("관전 모드로 길드전에 참가하셨습니다.")); ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("자신을 선택하시면 밖으로 나갈 수 있는 <관람 종료> 버튼이 나옵니다.")); } UpdateUserCount(); m_set_pkChr.insert(ch); LPDESC d = ch->GetDesc(); SendWarPacket(d); SendScorePacket(0, d); SendScorePacket(1, d); }
bool battle_is_attackable(LPCHARACTER ch, LPCHARACTER victim) { // 상대방이 죽었으면 중단한다. if (victim->IsDead()) return false; // 안전지대면 중단 { SECTREE *sectree = NULL; sectree = ch->GetSectree(); if (sectree && sectree->IsAttr(ch->GetX(), ch->GetY(), ATTR_BANPK)) return false; sectree = victim->GetSectree(); if (sectree && sectree->IsAttr(victim->GetX(), victim->GetY(), ATTR_BANPK)) return false; } // 내가 죽었으면 중단한다. if (ch->IsStun() || ch->IsDead()) return false; if (ch->IsPC() && victim->IsPC()) { CGuild* g1 = ch->GetGuild(); CGuild* g2 = victim->GetGuild(); if (g1 && g2) { if (g1->UnderWar(g2->GetID())) return true; } } if (IS_CASTLE_MAP(ch->GetMapIndex()) && false==castle_can_attack(ch, victim)) return false; if (CArenaManager::instance().CanAttack(ch, victim) == true) return true; return CPVPManager::instance().CanAttack(ch, victim); }
void FSetQuestFlag::operator() (LPCHARACTER ch) { if (!ch->IsPC()) return; PC * pPC = CQuestManager::instance().GetPCForce(ch->GetPlayerID()); if (pPC) pPC->SetFlag(flagname, value); }
void SET_ATTACKED_TIME(LPCHARACTER ch, LPCHARACTER victim, DWORD current_time) { if (NULL == ch || NULL == victim) return; if (!ch->IsPC()) return; victim->m_AttackedLog.dwPID = ch->GetPlayerID(); victim->m_AttackedLog.dwAttackedTime= current_time; }
void SET_ATTACK_TIME(LPCHARACTER ch, LPCHARACTER victim, DWORD current_time) { if (NULL == ch || NULL == victim) return; if (!ch->IsPC()) return; ch->m_kAttackLog.dwVID = victim->GetVID(); ch->m_kAttackLog.dwTime = current_time; }
void operator () (LPENTITY ent) { // 오브젝트가 아닌 것은 거리를 계산하여 거리가 멀면 추가하지 않는다. if (!ent->IsType(ENTITY_OBJECT)) if (DISTANCE_APPROX(ent->GetX() - m_me->GetX(), ent->GetY() - m_me->GetY()) > dwViewRange) return; // 나를 대상에 추가 m_me->ViewInsert(ent); // 둘다 캐릭터면 if (ent->IsType(ENTITY_CHARACTER) && m_me->IsType(ENTITY_CHARACTER)) { LPCHARACTER chMe = (LPCHARACTER) m_me; LPCHARACTER chEnt = (LPCHARACTER) ent; // 대상이 NPC면 StateMachine을 킨다. if (chMe->IsPC() && !chEnt->IsPC() && !chEnt->IsWarp() && !chEnt->IsGoto()) chEnt->StartStateMachine(); } }
void operator() (LPENTITY ent) { if (true == ent->IsType(ENTITY_CHARACTER)) { LPCHARACTER ch = static_cast<LPCHARACTER>(ent); if (false == ch->IsPC()) { ch->Dead(); } } }
void FWarpEmpire::operator() (LPENTITY ent) { if (ent->IsType(ENTITY_CHARACTER)) { LPCHARACTER ch = (LPCHARACTER) ent; if (ch->IsPC() && ch->GetEmpire() == m_bEmpire) { ch->WarpSet(m_x, m_y, m_lMapIndexTo); } } }
void CWarMap::DecMember(LPCHARACTER ch) { if (!ch->IsPC()) return; sys_log(0, "WarMap::DecMember"); DWORD gid = 0; if (ch->GetGuild()) gid = ch->GetGuild()->GetID(); if (!ch->IsObserverMode()) { if (gid == m_TeamData[0].dwID) m_TeamData[0].RemoveMember(ch); else if (gid == m_TeamData[1].dwID) m_TeamData[1].RemoveMember(ch); if (m_kMapInfo.bType == WAR_MAP_TYPE_FLAG) { CAffect * pkAff = ch->FindAffect(AFFECT_WAR_FLAG); if (pkAff) { BYTE idx; if (GetTeamIndex(pkAff->lApplyValue, idx)) AddFlag(idx, ch->GetX(), ch->GetY()); ch->RemoveAffect(AFFECT_WAR_FLAG); } } sys_log(0, "WarMap -m %u(cur:%d, acc:%d) vs %u(cur:%d, acc:%d)", m_TeamData[0].dwID, m_TeamData[0].GetCurJointerCount(), m_TeamData[0].GetAccumulatedJoinerCount(), m_TeamData[1].dwID, m_TeamData[1].GetCurJointerCount(), m_TeamData[1].GetAccumulatedJoinerCount()); CheckWarEnd(); ch->SetQuestFlag("war.is_war_member", 0); } else { --m_iObserverCount; sys_log(0, "WarMap -o %d", m_iObserverCount); ch->SetObserverMode(false); } UpdateUserCount(); m_set_pkChr.erase(ch); }
void CParty::Unlink(LPCHARACTER pkChr) { TMemberMap::iterator it; if (pkChr->IsPC()) it = m_memberMap.find(pkChr->GetPlayerID()); else it = m_memberMap.find(pkChr->GetVID()); if (it == m_memberMap.end()) { sys_err("%s is not member of this party", pkChr->GetName()); return; } if (pkChr->IsPC()) { SendPartyUnlinkOneToAll(pkChr); //SendPartyUnlinkAllToOne(pkChr); // 끊기는 것이므로 구지 Unlink 패킷을 보낼 필요 없다. if (it->second.bRole == PARTY_ROLE_LEADER) { RemoveBonus(); if (it->second.pCharacter->GetDungeon()) { // TODO: 던젼에 있으면 나머지도 나간다 FExitDungeon f; ForEachNearMember(f); } } } if (it->second.bRole == PARTY_ROLE_LEADER) m_pkChrLeader = NULL; it->second.pCharacter = NULL; pkChr->SetParty(NULL); }
void CParty::Unlink(LPCHARACTER pkChr) { TMemberMap::iterator it; if (pkChr->IsPC()) it = m_memberMap.find(pkChr->GetPlayerID()); else it = m_memberMap.find(pkChr->GetVID()); if (it == m_memberMap.end()) { sys_err("%s is not member of this party", pkChr->GetName()); return; } if (pkChr->IsPC()) { SendPartyUnlinkOneToAll(pkChr); //SendPartyUnlinkAllToOne(pkChr); // Іч±вґВ °НАМ№З·О ±ёБц Unlink ЖРЕ¶А» єёіѕ ЗКїд ѕшґЩ. if (it->second.bRole == PARTY_ROLE_LEADER) { RemoveBonus(); if (it->second.pCharacter->GetDungeon()) { // TODO: ґшБЇїЎ АЦАёёй іЄёУБцµµ іЄ°ЈґЩ FExitDungeon f; ForEachNearMember(f); } } } if (it->second.bRole == PARTY_ROLE_LEADER) m_pkChrLeader = NULL; it->second.pCharacter = NULL; pkChr->SetParty(NULL); }
void operator() (LPENTITY ent) { if (NULL != ent) { LPCHARACTER pChar = static_cast<LPCHARACTER>(ent); if (NULL != pChar) { if (true == pChar->IsPC()) { pChar->GoHome(); } } } }
// 상점 거래를 시작 bool CShopManager::StartShopping(LPCHARACTER pkChr, LPCHARACTER pkChrShopKeeper, int iShopVnum) { if (pkChr->GetShopOwner() == pkChrShopKeeper) return false; // this method is only for NPC if (pkChrShopKeeper->IsPC()) return false; //PREVENT_TRADE_WINDOW if (pkChr->IsOpenSafebox() || pkChr->GetExchange() || pkChr->GetMyShop() || pkChr->IsCubeOpen()) { pkChr->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("다른 거래창이 열린상태에서는 상점거래를 할수 가 없습니다.")); return false; } //END_PREVENT_TRADE_WINDOW long distance = DISTANCE_APPROX(pkChr->GetX() - pkChrShopKeeper->GetX(), pkChr->GetY() - pkChrShopKeeper->GetY()); if (distance >= SHOP_MAX_DISTANCE) { sys_log(1, "SHOP: TOO_FAR: %s distance %d", pkChr->GetName(), distance); return false; } LPSHOP pkShop; if (iShopVnum) pkShop = Get(iShopVnum); else pkShop = GetByNPCVnum(pkChrShopKeeper->GetRaceNum()); if (!pkShop) { sys_log(1, "SHOP: NO SHOP"); return false; } bool bOtherEmpire = false; if (pkChr->GetEmpire() != pkChrShopKeeper->GetEmpire()) bOtherEmpire = true; pkShop->AddGuest(pkChr, pkChrShopKeeper->GetVID(), bOtherEmpire); pkChr->SetShopOwner(pkChrShopKeeper); sys_log(0, "SHOP: START: %s", pkChr->GetName()); return true; }
int GetPoisonDamageRate(LPCHARACTER ch) { int iRate; if (ch->IsPC()) { if (LC_IsYMIR()) iRate = 40; else iRate = 50; } else iRate = poison_damage_rate[ch->GetMobRank()]; iRate = MAX(0, iRate - ch->GetPoint(POINT_POISON_REDUCE)); return iRate; }
bool FPartyCheckFlagLt::operator() (LPCHARACTER ch) { if (!ch->IsPC()) return false; PC * pPC = CQuestManager::instance().GetPCForce(ch->GetPlayerID()); bool returnBool = false; if (pPC) { int flagValue = pPC->GetFlag(flagname); if (value > flagValue) returnBool = true; else returnBool = false; } return returnBool; }
void operator()(LPENTITY ent) { if (NULL != ent && true == ent->IsType(ENTITY_CHARACTER)) { LPCHARACTER pChar = static_cast<LPCHARACTER>(ent); if (true == pChar->IsPC()) { if (NULL != pChar->GetGuild()) { if (dwGuildID == pChar->GetGuild()->GetID()) { pChar->WarpSet(x, y, mapIndex); } } } } }
void SECTREE::Destroy() { if (!m_set_entity.empty()) { sys_err("Sectree: entity set not empty!!"); ENTITY_SET::iterator it = m_set_entity.begin(); for ( ; it != m_set_entity.end(); ++it) { LPENTITY ent = *it; if (ent->IsType(ENTITY_CHARACTER)) { LPCHARACTER ch = (LPCHARACTER) ent; sys_err("Sectree: destroying character: %s is_pc %d", ch->GetName(), ch->IsPC() ? 1 : 0); if (ch->GetDesc()) DESC_MANAGER::instance().DestroyDesc(ch->GetDesc()); else M2_DESTROY_CHARACTER(ch); } else if (ent->IsType(ENTITY_ITEM)) { LPITEM item = (LPITEM) ent; sys_err("Sectree: destroying Item: %s", item->GetName()); M2_DESTROY_ITEM(item); } else sys_err("Sectree: unknown type: %d", ent->GetType()); } } m_set_entity.clear(); if (!isClone && m_pkAttribute) { M2_DELETE(m_pkAttribute); m_pkAttribute = NULL; } }
bool SECTREE::InsertEntity(LPENTITY pkEnt) { LPSECTREE pkCurTree; if ((pkCurTree = pkEnt->GetSectree()) == this) return false; if (m_set_entity.find(pkEnt) != m_set_entity.end()) { sys_err("entity %p already exist in this sectree!", get_pointer(pkEnt)); return false; } if (pkCurTree) pkCurTree->m_set_entity.erase(pkEnt); pkEnt->SetSectree(this); //pkEnt->UpdateSectree(); m_set_entity.insert(pkEnt); if (pkEnt->IsType(ENTITY_CHARACTER)) { LPCHARACTER pkChr = (LPCHARACTER) pkEnt; if (pkChr->IsPC()) { IncreasePC(); if (pkCurTree) pkCurTree->DecreasePC(); } else if (m_iPCCount > 0 && !pkChr->IsWarp() && !pkChr->IsGoto()) // PC가 아니고 이 곳에 PC가 있다면 Idle event를 시작 시킨다. { pkChr->StartStateMachine(); } } return true; }
BYTE CParty::CountMemberByVnum(DWORD dwVnum) { if (m_bPCParty) return 0; LPCHARACTER tch; BYTE bCount = 0; TMemberMap::iterator it; for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { if (!(tch = it->second.pCharacter)) continue; if (tch->IsPC()) continue; if (tch->GetMobTable().dwVnum == dwVnum) ++bCount; } return bCount; }
void PC::EndRunning() { // unlocked locked npc { LPCHARACTER npc = CQuestManager::instance().GetCurrentNPCCharacterPtr(); LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); // npc АЦѕъґш °жїм if (npc && !npc->IsPC()) { // ±Ч їЈЗЗѕѕ°Ў іЄїЎ°Ф ¶фАО °жїм if (ch->GetPlayerID() == npc->GetQuestNPCID()) { npc->SetQuestNPCID(0); sys_log(0, "QUEST NPC lock isn't unlocked : pid %u", ch->GetPlayerID()); CQuestManager::instance().WriteRunningStateToSyserr(); } } } // commit data if (HasReward()) { Save(); LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); if (ch != NULL) { Reward(ch); ch->Save(); } } m_bIsGivenReward = false; if (m_iSendToClient) { sys_log(1, "QUEST end running %d", m_iSendToClient); SendQuestInfoPakcet(); } if (m_RunningQuestState == NULL) { sys_log(0, "Entered PC::EndRunning() with invalid running quest state"); return; } QuestState * pOldState = m_RunningQuestState; int iNowState = m_RunningQuestState->st; m_RunningQuestState = 0; if (m_iLastState != iNowState) { LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); DWORD dwQuestIndex = CQuestManager::instance().GetQuestIndexByName(m_stCurQuest); if (ch) { SetFlag(m_stCurQuest + ".__status", m_iLastState); CQuestManager::instance().LeaveState(ch->GetPlayerID(), dwQuestIndex, m_iLastState); pOldState->st = iNowState; SetFlag(m_stCurQuest + ".__status", iNowState); CQuestManager::instance().EnterState(ch->GetPlayerID(), dwQuestIndex, iNowState); if (GetFlag(m_stCurQuest + ".__status") == iNowState) CQuestManager::instance().Letter(ch->GetPlayerID(), dwQuestIndex, iNowState); } } DoQuestStateChange(); }
void CThreeWayWar::onDead(LPCHARACTER pChar, LPCHARACTER pkKiller) { if (false == pChar->IsPC()) return; if (GM_PLAYER != pChar->GetGMLevel() && false == test_server) return; if (-1 == GetRegenFlag()) return; DecreaseReviveTokenForPlayer( pChar->GetPlayerID() ); if (false == IsSungZiMapIndex(pChar->GetMapIndex())) return; if (NULL == pkKiller || true != pkKiller->IsPC()) return; // °°Ає Б¦±№Ає °и»кЗПБц ѕКАЅ if (pChar->GetEmpire() == pkKiller->GetEmpire()) return; int nKillScore = GetKillScore(pkKiller->GetEmpire()); // Б¦±№ Еі ЅєДЪѕо°Ў -1АП°жїмґВ Е»¶ф±№°ЎА̱⶧№®їЎ БЎјц ГјЕ©ё¦ ЗПёй ѕИµИґЩ. if (nKillScore >= 0) { nKillScore += GetKillValue(pChar->GetLevel()); SetKillScore(pkKiller->GetEmpire(), nKillScore); } if (nKillScore != 0 && (test_server || (nKillScore % 5) == 0)) { char szBuf[64 + 1]; snprintf(szBuf, sizeof(szBuf), LC_TEXT("ЗцАз ЅєДЪѕо ЅЕјц±№:%d ГµБ¶±№:%d Бшіл±№:%d"), GetKillScore(1), GetKillScore(2), GetKillScore(3)); SendNoticeMap(szBuf, GetSungziMapIndex(), false); } const int nVictoryScore = quest::CQuestManager::instance().GetEventFlag("threeway_war_kill_count"); if (0 == GetRegenFlag()) { int nEliminatedEmpireCount = 0; BYTE bLoseEmpire = 0; for (int n = 1; n < 4; ++n) { if (nVictoryScore > GetKillScore(n)) { ++nEliminatedEmpireCount; bLoseEmpire = n; } } if (1 != nEliminatedEmpireCount) return; //---------------------- //Д«їоЖ® ГК±вИ //---------------------- SetKillScore(1, 0); SetKillScore(2, 0); SetKillScore(3, 0); SetKillScore(bLoseEmpire, -1); quest::warp_all_to_map_my_empire_event_info * info; //---------------------- //Е»¶ф±№°Ў ЕрАе ЅГЕ°±в : јєБцїЎј //---------------------- info = AllocEventInfo<quest::warp_all_to_map_my_empire_event_info>(); info->m_lMapIndexFrom = GetSungziMapIndex(); info->m_lMapIndexTo = EMPIRE_START_MAP(bLoseEmpire); info->m_x = EMPIRE_START_X(bLoseEmpire); info->m_y = EMPIRE_START_Y(bLoseEmpire); info->m_bEmpire = bLoseEmpire; event_create(quest::warp_all_to_map_my_empire_event, info, PASSES_PER_SEC(10)); //---------------------- //Е»¶ф±№°Ў ЕрАе ЅГЕ°±в : Ел·ОїЎј //---------------------- info = AllocEventInfo<quest::warp_all_to_map_my_empire_event_info>(); info->m_lMapIndexFrom = GetPassMapIndex(bLoseEmpire); info->m_lMapIndexTo = EMPIRE_START_MAP(bLoseEmpire); info->m_x = EMPIRE_START_X(bLoseEmpire); info->m_y = EMPIRE_START_Y(bLoseEmpire); info->m_bEmpire = bLoseEmpire; event_create(quest::warp_all_to_map_my_empire_event, info, PASSES_PER_SEC(10)); //---------------------- //јєБцїЎ ЖГ±вґВ ±№°ЎїЎ ґлЗС АМѕЯ±вё¦ ё¶їХАМ ЗФ! //---------------------- const std::string Nation(EMPIRE_NAME(bLoseEmpire)); const std::string Script( LC_TEXT("јєБцАЗ ё¶їХ: іКИс ") + Nation + LC_TEXT("іај®µйАє АМ°ч јєБцїЎ АЦА» АЪ°ЭА» АТѕъґЩ. ёрµО јєБцїЎј №°·ЇіЄ°Е¶у~~[ENTER][ENTER] 10ГК ИДїЎ ёрµО ё¶А»·О АМµїЗП°Ф µЛґПґЩ. ") + "[ENTER][DONE]" ); CHARACTER_MANAGER::instance().SendScriptToMap(pChar->GetMapIndex(), Script); //---------------------- // °шБц ЗС№ж іЇ·ББЬ. //---------------------- char szNotice[512+1]; snprintf(szNotice, sizeof(szNotice), LC_TEXT("»п°Её® АьЕхїЎј %s ±№°Ў°Ў °ЎАеёХАъ Е»¶фА» ЗПїґЅАґПґЩ"), Nation.c_str()); BroadcastNotice(szNotice); snprintf(szNotice, sizeof(szNotice), "First Step: %s exclusion", Nation.c_str()); LogManager::instance().CharLog(0, 0, 0, 0, "THREEWAY", szNotice, NULL); //---------------------- // ёчА» ё®БЁЗСґЩ. //---------------------- regen_mob_event_info* regen_info = AllocEventInfo<regen_mob_event_info>(); regen_info->dwMapIndex = pChar->GetMapIndex(); event_create(regen_mob_event, regen_info, PASSES_PER_SEC(10)); SetRegenFlag(1); } else if (1 == GetRegenFlag()) { int nVictoryEmpireIndex = 0; for (int n = 1; n < 4; ++n) { nKillScore = GetKillScore(n); if (nKillScore == -1) continue; if (nVictoryScore <= nKillScore) { nVictoryEmpireIndex = n; break; } } if (0 == nVictoryEmpireIndex) return; for (int n = 1; n < 4; ++n) { if (n != nVictoryEmpireIndex) { BYTE bLoseEmpire = n; quest::warp_all_to_map_my_empire_event_info * info; //---------------------- //Е»¶ф±№°Ў ЕрАе ЅГЕ°±в : јєБцїЎј //---------------------- info = AllocEventInfo<quest::warp_all_to_map_my_empire_event_info>(); info->m_lMapIndexFrom = GetSungziMapIndex(); info->m_lMapIndexTo = EMPIRE_START_MAP(bLoseEmpire); info->m_x = EMPIRE_START_X(bLoseEmpire); info->m_y = EMPIRE_START_Y(bLoseEmpire); info->m_bEmpire = bLoseEmpire; event_create(quest::warp_all_to_map_my_empire_event, info, PASSES_PER_SEC(5)); //---------------------- //Е»¶ф±№°Ў ЕрАе ЅГЕ°±в : Ел·ОїЎј //---------------------- info = AllocEventInfo<quest::warp_all_to_map_my_empire_event_info>(); info->m_lMapIndexFrom = GetPassMapIndex(bLoseEmpire); info->m_lMapIndexTo = EMPIRE_START_MAP(bLoseEmpire); info->m_x = EMPIRE_START_X(bLoseEmpire); info->m_y = EMPIRE_START_Y(bLoseEmpire); info->m_bEmpire = bLoseEmpire; event_create(quest::warp_all_to_map_my_empire_event, info, PASSES_PER_SEC(5)); } } //------------------------------ // ГЦБѕ ЅєДЪѕо ЗҐЅГ //------------------------------ { char szBuf[64 + 1]; snprintf(szBuf, sizeof(szBuf), LC_TEXT("ЗцАз ЅєДЪѕо ЅЕјц±№:%d ГµБ¶±№:%d Бшіл±№:%d"), GetKillScore(1), GetKillScore(2), GetKillScore(3)); SendNoticeMap(szBuf, GetSungziMapIndex(), false); } // ёЮјјБцё¦ ¶зїцБШґЩ. LPSECTREE_MAP pSecMap = SECTREE_MANAGER::instance().GetMap(pChar->GetMapIndex()); if (NULL != pSecMap) { const std::string EmpireName(EMPIRE_NAME(nVictoryEmpireIndex)); const std::string Script( EmpireName + LC_TEXT(". іКИс°Ў јєБцАЗ јцИЈАЪё¦ Ав°Ф µИґЩёй іКИсґВ јєБцАЗ БЦАОАМ µИґЩ.[ENTER][ENTER] ") + "[ENTER][DONE]"); struct packet_script pack_script; pack_script.header = HEADER_GC_SCRIPT; pack_script.skin = 1; pack_script.src_size = Script.size(); quest::FSendPacketToEmpire fSend; fSend.bEmpire = nVictoryEmpireIndex; pack_script.size = pack_script.src_size + sizeof(struct packet_script); fSend.buf.write(&pack_script, sizeof(struct packet_script)); fSend.buf.write(&Script[0], Script.size()); pSecMap->for_each(fSend); char szBuf[512]; snprintf(szBuf, sizeof(szBuf), "Second Step: %s remain", EMPIRE_NAME( nVictoryEmpireIndex )); LogManager::instance().CharLog(0, 0, 0, 0, "THREEWAY", szBuf, NULL); } //------------------------------ // ё¶Бцё· єё»у : Бш±ё№МИЈ јТИЇ //----------------------------- for (int n = 0; n < quest::CQuestManager::instance().GetEventFlag("threeway_war_boss_count");) { int x = pChar->GetX(); int y = pChar->GetY(); x = (thecore_random() & 1) ? x - number(200, 1000) : x + number(200, 1000); y = (thecore_random() & 1) ? y - number(200, 1000) : y + number(200, 1000); if (x < 0) x = pChar->GetX(); if (y < 0) y = pChar->GetY(); LPCHARACTER ch = CHARACTER_MANAGER::instance().SpawnMob( GetEventSungZiMapInfo().m_iBossMobVnum, pChar->GetMapIndex(), x, y, 0, false); if (NULL != ch) { ch->SetAggressive(); ++n; } } SetRegenFlag(-1); } }
int CalcAttBonus(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, int iAtk) { // PvP에는 적용하지않음 if (!pkVictim->IsPC()) iAtk += pkAttacker->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_ATTACK_BONUS); // PvP에는 적용하지않음 if (!pkAttacker->IsPC()) { int iReduceDamagePct = pkVictim->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_TRANSFER_DAMAGE); iAtk = iAtk * (100 + iReduceDamagePct) / 100; } if (pkAttacker->IsNPC() && pkVictim->IsPC()) { iAtk = (iAtk * CHARACTER_MANAGER::instance().GetMobDamageRate(pkAttacker)) / 100; } if (pkVictim->IsNPC()) { if (pkVictim->IsRaceFlag(RACE_FLAG_ANIMAL)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_ANIMAL)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_UNDEAD)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_UNDEAD)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_DEVIL)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_DEVIL)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_HUMAN)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_HUMAN)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_ORC)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_ORC)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_MILGYO)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_MILGYO)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_INSECT)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_INSECT)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_FIRE)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_FIRE)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_ICE)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_ICE)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_DESERT)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_DESERT)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_TREE)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_TREE)) / 100; iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_MONSTER)) / 100; } else if (pkVictim->IsPC()) { iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_HUMAN)) / 100; switch (pkVictim->GetJob()) { case JOB_WARRIOR: iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_WARRIOR)) / 100; break; case JOB_ASSASSIN: iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_ASSASSIN)) / 100; break; case JOB_SURA: iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_SURA)) / 100; break; case JOB_SHAMAN: iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_SHAMAN)) / 100; break; } } if (pkAttacker->IsPC() == true) { switch (pkAttacker->GetJob()) { case JOB_WARRIOR: iAtk -= (iAtk * pkVictim->GetPoint(POINT_RESIST_WARRIOR)) / 100; break; case JOB_ASSASSIN: iAtk -= (iAtk * pkVictim->GetPoint(POINT_RESIST_ASSASSIN)) / 100; break; case JOB_SURA: iAtk -= (iAtk * pkVictim->GetPoint(POINT_RESIST_SURA)) / 100; break; case JOB_SHAMAN: iAtk -= (iAtk * pkVictim->GetPoint(POINT_RESIST_SHAMAN)) / 100; break; } } //[ mob -> PC ] 원소 속성 방어 적용 //2013/01/17 //몬스터 속성공격 데미지의 30%에 해당하는 수치에만 저항이 적용됨. if (pkAttacker->IsNPC() && pkVictim->IsPC()) { if (pkAttacker->IsRaceFlag(RACE_FLAG_ATT_ELEC)) iAtk -= (iAtk * 30 * pkVictim->GetPoint(POINT_RESIST_ELEC)) / 10000; else if (pkAttacker->IsRaceFlag(RACE_FLAG_ATT_FIRE)) iAtk -= (iAtk * 30 * pkVictim->GetPoint(POINT_RESIST_FIRE)) / 10000; else if (pkAttacker->IsRaceFlag(RACE_FLAG_ATT_ICE)) iAtk -= (iAtk * 30 * pkVictim->GetPoint(POINT_RESIST_ICE)) / 10000; else if (pkAttacker->IsRaceFlag(RACE_FLAG_ATT_WIND)) iAtk -= (iAtk * 30 * pkVictim->GetPoint(POINT_RESIST_WIND)) / 10000; else if (pkAttacker->IsRaceFlag(RACE_FLAG_ATT_EARTH)) iAtk -= (iAtk * 30 * pkVictim->GetPoint(POINT_RESIST_EARTH)) / 10000; else if (pkAttacker->IsRaceFlag(RACE_FLAG_ATT_DARK)) iAtk -= (iAtk * 30 * pkVictim->GetPoint(POINT_RESIST_DARK)) / 10000; } return iAtk; }
int CalcMeleeDamage(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, bool bIgnoreDefense, bool bIgnoreTargetRating) { LPITEM pWeapon = pkAttacker->GetWear(WEAR_WEAPON); bool bPolymorphed = pkAttacker->IsPolymorphed(); if (pWeapon && !(bPolymorphed && !pkAttacker->IsPolyMaintainStat())) { if (pWeapon->GetType() != ITEM_WEAPON) return 0; switch (pWeapon->GetSubType()) { case WEAPON_SWORD: case WEAPON_DAGGER: case WEAPON_TWO_HANDED: case WEAPON_BELL: case WEAPON_FAN: case WEAPON_MOUNT_SPEAR: break; case WEAPON_BOW: sys_err("CalcMeleeDamage should not handle bows (name: %s)", pkAttacker->GetName()); return 0; default: return 0; } } int iDam = 0; float fAR = CalcAttackRating(pkAttacker, pkVictim, bIgnoreTargetRating); int iDamMin = 0, iDamMax = 0; // TESTSERVER_SHOW_ATTACKINFO int DEBUG_iDamCur = 0; int DEBUG_iDamBonus = 0; // END_OF_TESTSERVER_SHOW_ATTACKINFO if (bPolymorphed && !pkAttacker->IsPolyMaintainStat()) { // MONKEY_ROD_ATTACK_BUG_FIX Item_GetDamage(pWeapon, &iDamMin, &iDamMax); // END_OF_MONKEY_ROD_ATTACK_BUG_FIX DWORD dwMobVnum = pkAttacker->GetPolymorphVnum(); const CMob * pMob = CMobManager::instance().Get(dwMobVnum); if (pMob) { int iPower = pkAttacker->GetPolymorphPower(); iDamMin += pMob->m_table.dwDamageRange[0] * iPower / 100; iDamMax += pMob->m_table.dwDamageRange[1] * iPower / 100; } } else if (pWeapon) { // MONKEY_ROD_ATTACK_BUG_FIX Item_GetDamage(pWeapon, &iDamMin, &iDamMax); // END_OF_MONKEY_ROD_ATTACK_BUG_FIX } else if (pkAttacker->IsNPC()) { iDamMin = pkAttacker->GetMobDamageMin(); iDamMax = pkAttacker->GetMobDamageMax(); } iDam = number(iDamMin, iDamMax) * 2; // TESTSERVER_SHOW_ATTACKINFO DEBUG_iDamCur = iDam; // END_OF_TESTSERVER_SHOW_ATTACKINFO // int iAtk = 0; // level must be ignored when multiply by fAR, so subtract it before calculation. iAtk = pkAttacker->GetPoint(POINT_ATT_GRADE) + iDam - (pkAttacker->GetLevel() * 2); iAtk = (int) (iAtk * fAR); iAtk += pkAttacker->GetLevel() * 2; // and add again if (pWeapon) { iAtk += pWeapon->GetValue(5) * 2; // 2004.11.12.myevan.TESTSERVER_SHOW_ATTACKINFO DEBUG_iDamBonus = pWeapon->GetValue(5) * 2; /////////////////////////////////////////////// } iAtk += pkAttacker->GetPoint(POINT_PARTY_ATTACKER_BONUS); // party attacker role bonus iAtk = (int) (iAtk * (100 + (pkAttacker->GetPoint(POINT_ATT_BONUS) + pkAttacker->GetPoint(POINT_MELEE_MAGIC_ATT_BONUS_PER))) / 100); iAtk = CalcAttBonus(pkAttacker, pkVictim, iAtk); int iDef = 0; if (!bIgnoreDefense) { iDef = (pkVictim->GetPoint(POINT_DEF_GRADE) * (100 + pkVictim->GetPoint(POINT_DEF_BONUS)) / 100); if (!pkAttacker->IsPC()) iDef += pkVictim->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_DEFENSE_BONUS); } if (pkAttacker->IsNPC()) iAtk = (int) (iAtk * pkAttacker->GetMobDamageMultiply()); iDam = MAX(0, iAtk - iDef); if (test_server) { int DEBUG_iLV = pkAttacker->GetLevel()*2; int DEBUG_iST = int((pkAttacker->GetPoint(POINT_ATT_GRADE) - DEBUG_iLV) * fAR); int DEBUG_iPT = pkAttacker->GetPoint(POINT_PARTY_ATTACKER_BONUS); int DEBUG_iWP = 0; int DEBUG_iPureAtk = 0; int DEBUG_iPureDam = 0; char szRB[32] = ""; char szGradeAtkBonus[32] = ""; DEBUG_iWP = int(DEBUG_iDamCur * fAR); DEBUG_iPureAtk = DEBUG_iLV + DEBUG_iST + DEBUG_iWP+DEBUG_iDamBonus; DEBUG_iPureDam = iAtk - iDef; if (pkAttacker->IsNPC()) { snprintf(szGradeAtkBonus, sizeof(szGradeAtkBonus), "=%d*%.1f", DEBUG_iPureAtk, pkAttacker->GetMobDamageMultiply()); DEBUG_iPureAtk = int(DEBUG_iPureAtk * pkAttacker->GetMobDamageMultiply()); } if (DEBUG_iDamBonus != 0) snprintf(szRB, sizeof(szRB), "+RB(%d)", DEBUG_iDamBonus); char szPT[32] = ""; if (DEBUG_iPT != 0) snprintf(szPT, sizeof(szPT), ", PT=%d", DEBUG_iPT); char szUnknownAtk[32] = ""; if (iAtk != DEBUG_iPureAtk) snprintf(szUnknownAtk, sizeof(szUnknownAtk), "+?(%d)", iAtk-DEBUG_iPureAtk); char szUnknownDam[32] = ""; if (iDam != DEBUG_iPureDam) snprintf(szUnknownDam, sizeof(szUnknownDam), "+?(%d)", iDam-DEBUG_iPureDam); char szMeleeAttack[128]; snprintf(szMeleeAttack, sizeof(szMeleeAttack), "%s(%d)-%s(%d)=%d%s, ATK=LV(%d)+ST(%d)+WP(%d)%s%s%s, AR=%.3g%s", pkAttacker->GetName(), iAtk, pkVictim->GetName(), iDef, iDam, szUnknownDam, DEBUG_iLV, DEBUG_iST, DEBUG_iWP, szRB, szUnknownAtk, szGradeAtkBonus, fAR, szPT); pkAttacker->ChatPacket(CHAT_TYPE_TALKING, "%s", szMeleeAttack); pkVictim->ChatPacket(CHAT_TYPE_TALKING, "%s", szMeleeAttack); } return CalcBattleDamage(iDam, pkAttacker->GetLevel(), pkVictim->GetLevel()); }
int battle_melee_attack(LPCHARACTER ch, LPCHARACTER victim) { if (test_server&&ch->IsPC()) sys_log(0, "battle_melee_attack : [%s] attack to [%s]", ch->GetName(), victim->GetName()); if (!victim || ch == victim) return BATTLE_NONE; if (test_server&&ch->IsPC()) sys_log(0, "battle_melee_attack : [%s] attack to [%s]", ch->GetName(), victim->GetName()); if (!battle_is_attackable(ch, victim)) return BATTLE_NONE; if (test_server&&ch->IsPC()) sys_log(0, "battle_melee_attack : [%s] attack to [%s]", ch->GetName(), victim->GetName()); // 거리 체크 int distance = DISTANCE_APPROX(ch->GetX() - victim->GetX(), ch->GetY() - victim->GetY()); if (!victim->IsBuilding()) { int max = 300; if (false == ch->IsPC()) { // 몬스터의 경우 몬스터 공격 거리를 사용 max = (int) (ch->GetMobAttackRange() * 1.15f); } else { // PC일 경우 상대가 melee 몹일 경우 몹의 공격 거리가 최대 공격 거리 if (false == victim->IsPC() && BATTLE_TYPE_MELEE == victim->GetMobBattleType()) max = MAX(300, (int) (victim->GetMobAttackRange() * 1.15f)); } if (distance > max) { if (test_server) sys_log(0, "VICTIM_FAR: %s distance: %d max: %d", ch->GetName(), distance, max); return BATTLE_NONE; } } if (timed_event_cancel(ch)) ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("전투가 시작 되어 취소 되었습니다.")); if (timed_event_cancel(victim)) victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("전투가 시작 되어 취소 되었습니다.")); ch->SetPosition(POS_FIGHTING); ch->SetVictim(victim); const PIXEL_POSITION & vpos = victim->GetXYZ(); ch->SetRotationToXY(vpos.x, vpos.y); int dam; int ret = battle_hit(ch, victim, dam); return (ret); }
int CalcAttBonus(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, int iAtk) { // PvPїЎґВ АыїлЗПБцѕКАЅ if (!pkVictim->IsPC()) iAtk += pkAttacker->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_ATTACK_BONUS); // PvPїЎґВ АыїлЗПБцѕКАЅ if (!pkAttacker->IsPC()) { int iReduceDamagePct = pkVictim->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_TRANSFER_DAMAGE); iAtk = iAtk * (100 + iReduceDamagePct) / 100; } if (pkAttacker->IsNPC() && pkVictim->IsPC()) { iAtk = (iAtk * CHARACTER_MANAGER::instance().GetMobDamageRate(pkAttacker)) / 100; } if (pkVictim->IsNPC()) { if (pkVictim->IsRaceFlag(RACE_FLAG_ANIMAL)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_ANIMAL)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_UNDEAD)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_UNDEAD)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_DEVIL)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_DEVIL)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_HUMAN)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_HUMAN)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_ORC)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_ORC)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_MILGYO)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_MILGYO)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_INSECT)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_INSECT)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_FIRE)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_FIRE)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_ICE)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_ICE)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_DESERT)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_DESERT)) / 100; else if (pkVictim->IsRaceFlag(RACE_FLAG_TREE)) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_TREE)) / 100; iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_MONSTER)) / 100; } else if (pkVictim->IsPC()) { iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_HUMAN)) / 100; switch (pkVictim->GetJob()) { case JOB_WARRIOR: iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_WARRIOR)) / 100; break; case JOB_ASSASSIN: iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_ASSASSIN)) / 100; break; case JOB_SURA: iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_SURA)) / 100; break; case JOB_SHAMAN: iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_SHAMAN)) / 100; break; } } if (pkAttacker->IsPC() == true) { switch (pkAttacker->GetJob()) { case JOB_WARRIOR: iAtk -= (iAtk * pkVictim->GetPoint(POINT_RESIST_WARRIOR)) / 100; break; case JOB_ASSASSIN: iAtk -= (iAtk * pkVictim->GetPoint(POINT_RESIST_ASSASSIN)) / 100; break; case JOB_SURA: iAtk -= (iAtk * pkVictim->GetPoint(POINT_RESIST_SURA)) / 100; break; case JOB_SHAMAN: iAtk -= (iAtk * pkVictim->GetPoint(POINT_RESIST_SHAMAN)) / 100; break; } } //[ mob -> PC ] їшјТ јУјє №жѕо Аыїл //2013/01/17 //ёуЅєЕН јУјє°ш°Э µҐ№МБцАЗ 30%їЎ ЗШґзЗПґВ јцДЎїЎёё АъЗЧАМ АыїлµК. if (pkAttacker->IsNPC() && pkVictim->IsPC()) { if (pkAttacker->IsRaceFlag(RACE_FLAG_ATT_ELEC)) iAtk -= (iAtk * 30 * pkVictim->GetPoint(POINT_RESIST_ELEC)) / 10000; else if (pkAttacker->IsRaceFlag(RACE_FLAG_ATT_FIRE)) iAtk -= (iAtk * 30 * pkVictim->GetPoint(POINT_RESIST_FIRE)) / 10000; else if (pkAttacker->IsRaceFlag(RACE_FLAG_ATT_ICE)) iAtk -= (iAtk * 30 * pkVictim->GetPoint(POINT_RESIST_ICE)) / 10000; else if (pkAttacker->IsRaceFlag(RACE_FLAG_ATT_WIND)) iAtk -= (iAtk * 30 * pkVictim->GetPoint(POINT_RESIST_WIND)) / 10000; else if (pkAttacker->IsRaceFlag(RACE_FLAG_ATT_EARTH)) iAtk -= (iAtk * 30 * pkVictim->GetPoint(POINT_RESIST_EARTH)) / 10000; else if (pkAttacker->IsRaceFlag(RACE_FLAG_ATT_DARK)) iAtk -= (iAtk * 30 * pkVictim->GetPoint(POINT_RESIST_DARK)) / 10000; } return iAtk; }