yarka0000 1
yarka0000
kralhakan2009 1
kralhakan2009
Vahsi Uzman 1
Vahsi Uzman
Hikaye Ekle

YENİ EFSUN EKLEME SORUNU

  • Konuyu başlatan Konuyu başlatan BayEmsY
  • Başlangıç tarihi Başlangıç tarihi
  • Cevaplar Cevaplar 17
  • Görüntüleme Görüntüleme 3K

Ayyıldız2 | 2008 TR Yapısı • 1-99 Orta Emek Destan • Oto Avsız • 10 Temmuz 21:00 HEMEN TIKLA!

Arkadaşlar selamlar herkese öncelikle iyi forumlar diliyorum. Server geliştirmeye çalışıyorum daha doğrusu öğrenmeye serverime patron ve metinlere karşı güç efsunu ekledim client source, game source, dump_proto build vb her şeyi hallettim fakat bu eklediğim efsunları metinlere ve bosslara nasıl entegre edebilirim? RaceFlag oluyor sanırım acil yardımlarınızı bekliyorum TW den yardım edebilecek olursa çok iyi olur şimdiden teşekkür ediyorum.
 
battle.cpp paylaşmassanız düzenleyemez kimse böyle
battle.cpp içinde dediğiniz kısım burası işte ben böyle yapmıştım dediğiniz gibi bu şekilde düzenledim doğrumudur?

if (pkVictim->IsNPC())
{
if (pkVictim->IsRaceFlag(RACE_FLAG_ANIMAL))
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_ANIMAL)) / 100;
else if (pkVictim->IsRaceFlag(RACE_FLAG_BOSS))
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_PATRON)) / 100;
else if (pkVictim->IsStone())
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_METINN) / 100;
else if (pkVictim->IsRaceFlag(RACE_FLAG_UNDEAD))
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_UNDEAD)) / 100;
 
[CODE title="battle.cpp"]#include "stdafx.h"
#include "utils.h"
#include "config.h"
#include "desc.h"
#include "char.h"
#include "char_manager.h"
#include "battle.h"
#include "item.h"
#include "item_manager.h"
#include "mob_manager.h"
#include "vector.h"
#include "packet.h"
#include "pvp.h"
#include "profiler.h"
#include "guild.h"
#include "affect.h"
#include "unique_item.h"
#include "lua_incl.h"
#include "arena.h"
#include "castle.h"
#include "sectree.h"
#include "ani.h"
#include "locale_service.h"
#include "../../common/service.h"

int battle_hit(LPCHARACTER ch, LPCHARACTER victim, int & iRetDam);

bool battle_distance_valid_by_xy(long x, long y, long tx, long ty)
{
long distance = DISTANCE_APPROX(x - tx, y - ty);

if (distance > 170)
return false;

return true;
}

bool battle_distance_valid(LPCHARACTER ch, LPCHARACTER victim)
{
return battle_distance_valid_by_xy(ch->GetX(), ch->GetY(), victim->GetX(), victim->GetY());
}

bool timed_event_cancel(LPCHARACTER ch)
{
if (ch->m_pkTimedEvent)
{
event_cancel(&ch->m_pkTimedEvent);
return true;
}

/* RECALL_DELAY
차후 전투로 인해 귀환부 딜레이가 취소 되어야 할 경우 주석 해제
if (ch->m_pk_RecallEvent)
{
event_cancel(&ch->m_pkRecallEvent);
return true;
}
END_OF_RECALL_DELAY */

return false;
}

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);
}

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);
}

void battle_end_ex(LPCHARACTER ch)
{
if (ch->IsPosition(POS_FIGHTING))
ch->SetPosition(POS_STANDING);
}

void battle_end(LPCHARACTER ch)
{
battle_end_ex(ch);
}

int CalcBattleDamage(int iDam, int iAttackerLev, int iVictimLev)
{
if (iDam < 3)
iDam = number(1, 5);

return iDam;
}

int CalcMagicDamageWithValue(int iDam, LPCHARACTER pkAttacker, LPCHARACTER pkVictim)
{
return CalcBattleDamage(iDam, pkAttacker->GetLevel(), pkVictim->GetLevel());
}

int CalcMagicDamage(LPCHARACTER pkAttacker, LPCHARACTER pkVictim)
{
int iDam = 0;

if (pkAttacker->IsNPC())
{
iDam = CalcMeleeDamage(pkAttacker, pkVictim, false, false);
}

iDam += pkAttacker->GetPoint(POINT_PARTY_ATTACKER_BONUS);

return CalcMagicDamageWithValue(iDam, pkAttacker, pkVictim);
}

float CalcAttackRating(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, bool bIgnoreTargetRating)
{
int iARSrc;
int iERSrc;

if (LC_IsYMIR()) // 천마
{
iARSrc = MIN(90, pkAttacker->GetPolymorphPoint(POINT_DX));
iERSrc = MIN(90, pkVictim->GetPolymorphPoint(POINT_DX));
}
else
{
int attacker_dx = pkAttacker->GetPolymorphPoint(POINT_DX);
int attacker_lv = pkAttacker->GetLevel();

int victim_dx = pkVictim->GetPolymorphPoint(POINT_DX);
int victim_lv = pkAttacker->GetLevel();

iARSrc = MIN(90, (attacker_dx * 4 + attacker_lv * 2) / 6);
iERSrc = MIN(90, (victim_dx * 4 + victim_lv * 2) / 6);
}

float fAR = ((float) iARSrc + 210.0f) / 300.0f; // fAR = 0.7 ~ 1.0

if (bIgnoreTargetRating)
return fAR;

float fER = ((float) (iERSrc * 2 + 5) / (iERSrc + 95)) * 3.0f / 10.0f;

return fAR - fER;
}

int CalcAttBonus(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, int iAtk)
{
if (!pkVictim->IsPC())
iAtk += pkAttacker->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_ATTACK_BONUS);

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_BOSS))
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_PATRON)) / 100;
else if (pkVictim->IsStone())
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_METINN) / 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;
#ifdef ELEMENT_NEW_BONUSES
else if (pkVictim->IsRaceFlag(RACE_FLAG_ELEC))
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_ELEC)) / 100;
else if (pkVictim->IsRaceFlag(RACE_FLAG_WIND))
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_WIND)) / 100;
else if (pkVictim->IsRaceFlag(RACE_FLAG_EARTH))
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_EARTH)) / 100;
else if (pkVictim->IsRaceFlag(RACE_FLAG_DARK))
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_DARK)) / 100;
#endif
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;
#ifdef ENABLE_WOLFMAN_CHARACTER
case JOB_WOLFMAN:
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_WOLFMAN)) / 100;
break;
#endif
}
}

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;
#ifdef ENABLE_WOLFMAN_CHARACTER
case JOB_WOLFMAN:
iAtk -= (iAtk * pkVictim->GetPoint(POINT_RESIST_WOLFMAN)) / 100;
break;
#endif
}
}

#ifdef ELEMENT_TARGET
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;
}

#endif
return iAtk;
}

void Item_GetDamage(LPITEM pkItem, int* pdamMin, int* pdamMax)
{
*pdamMin = 0;
*pdamMax = 1;

if (!pkItem)
return;

switch (pkItem->GetType())
{
case ITEM_ROD:
case ITEM_PICK:
return;
}

if (pkItem->GetType() != ITEM_WEAPON)
sys_err("Item_GetDamage - !ITEM_WEAPON vnum=%d, type=%d", pkItem->GetOriginalVnum(), pkItem->GetType());

*pdamMin = pkItem->GetValue(3);
*pdamMax = pkItem->GetValue(4);
}

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:
#ifdef ENABLE_WOLFMAN_CHARACTER
case WEAPON_CLAW:
#endif
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())
{
Item_GetDamage(pWeapon, &iDamMin, &iDamMax);
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)
{
Item_GetDamage(pWeapon, &iDamMin, &iDamMax);
}
else if (pkAttacker->IsNPC())
{
iDamMin = pkAttacker->GetMobDamageMin();
iDamMax = pkAttacker->GetMobDamageMax();
}

iDam = number(iDamMin, iDamMax) * 2;
DEBUG_iDamCur = iDam;

int iAtk = 0;
iAtk = pkAttacker->GetPoint(POINT_ATT_GRADE) + iDam - (pkAttacker->GetLevel() * 2);
iAtk = (int) (iAtk * fAR);
iAtk += pkAttacker->GetLevel() * 2;

if (pWeapon)
{
iAtk += pWeapon->GetValue(5) * 2;
DEBUG_iDamBonus = pWeapon->GetValue(5) * 2;
}

iAtk += pkAttacker->GetPoint(POINT_PARTY_ATTACKER_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 CalcArrowDamage(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, LPITEM pkBow, LPITEM pkArrow, bool bIgnoreDefense)
{
if (!pkBow || pkBow->GetType() != ITEM_WEAPON || pkBow->GetSubType() != WEAPON_BOW)
return 0;
if (!pkArrow)
return 0;

int iDist = (int) (DISTANCE_SQRT(pkAttacker->GetX() - pkVictim->GetX(), pkAttacker->GetY() - pkVictim->GetY()));
int iGap = (iDist / 100) - 5 - pkAttacker->GetPoint(POINT_BOW_DISTANCE);
int iPercent = 100 - (iGap * 5);
#ifdef WJ_QUIVER_SYSTEM
if (pkArrow->GetSubType() == WEAPON_UNLIMITED_ARROW)
{
iPercent = 100;
}
#endif

if(pkArrow->GetValue(5)==1)
{
iPercent = 100;
}

if (iPercent <= 0)
return 0;
else if (iPercent > 100)
iPercent = 100;

int iDam = 0;
float fAR = CalcAttackRating(pkAttacker, pkVictim, false);
iDam = number(pkBow->GetValue(3), pkBow->GetValue(4)) * 2 + pkArrow->GetValue(3);
int iAtk;
iAtk = pkAttacker->GetPoint(POINT_ATT_GRADE) + iDam - (pkAttacker->GetLevel() * 2);
iAtk = (int) (iAtk * fAR);
iAtk += pkAttacker->GetLevel() * 2;
iAtk += pkBow->GetValue(5) * 2;
iAtk += pkAttacker->GetPoint(POINT_PARTY_ATTACKER_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 + pkAttacker->GetPoint(POINT_DEF_BONUS)) / 100);

if (pkAttacker->IsNPC())
iAtk = (int) (iAtk * pkAttacker->GetMobDamageMultiply());

iDam = MAX(0, iAtk - iDef);

int iPureDam = iDam;

iPureDam = (iPureDam * iPercent) / 100;

if (test_server)
{
pkAttacker->ChatPacket(CHAT_TYPE_INFO, "ARROW %s -> %s, DAM %d DIST %d GAP %d %% %d",
pkAttacker->GetName(),
pkVictim->GetName(),
iPureDam,
iDist, iGap, iPercent);
}

return iPureDam;
//return iDam;
}

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);
}
#ifdef ENABLE_WOLFMAN_CHARACTER
if (pkAttacker->GetPoint(POINT_BLEEDING_PCT) && !pkVictim->IsAffectFlag(AFF_BLEEDING))
{
if (number(1, 100) <= pkAttacker->GetPoint(POINT_BLEEDING_PCT))
pkVictim->AttackedByBleeding(pkAttacker);
}
#endif
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");
}

int battle_hit(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, int & iRetDam)
{
if (test_server)
sys_log(0, "battle_hit : [%s] attack to [%s] : dam :%d type :%d", pkAttacker->GetName(), pkVictim->GetName(), iRetDam);

int iDam = CalcMeleeDamage(pkAttacker, pkVictim);
if (iDam <= 0)
return (BATTLE_DAMAGE);

NormalAttackAffect(pkAttacker, pkVictim);

LPITEM pkWeapon = pkAttacker->GetWear(WEAR_WEAPON);
if (pkWeapon)
switch (pkWeapon->GetSubType())
{
case WEAPON_SWORD:
iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_SWORD)) / 100;
break;

case WEAPON_TWO_HANDED:
iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_TWOHAND)) / 100;
break;

case WEAPON_DAGGER:
iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_DAGGER)) / 100;
break;

case WEAPON_BELL:
iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_BELL)) / 100;
break;

case WEAPON_FAN:
iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_FAN)) / 100;
break;

case WEAPON_BOW:
iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_BOW)) / 100;
break;
#ifdef ENABLE_WOLFMAN_CHARACTER
case WEAPON_CLAW:
iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_CLAW)) / 100;
#if defined(ENABLE_WOLFMAN_CHARACTER) && defined(USE_ITEM_CLAW_AS_DAGGER)
iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_DAGGER)) / 100;
#endif
break;
#endif
}

float attMul = pkAttacker->GetAttMul();
float tempIDam = iDam;
iDam = attMul * tempIDam + 0.5f;
iRetDam = iDam;

if (pkVictim->Damage(pkAttacker, iDam, DAMAGE_TYPE_NORMAL))
return (BATTLE_DEAD);

return (BATTLE_DAMAGE);
}

DWORD GET_ATTACK_SPEED(LPCHARACTER ch)
{
if (NULL == ch)
return 1000;

LPITEM item = ch->GetWear(WEAR_WEAPON);
DWORD default_bonus = SPEEDHACK_LIMIT_BONUS;
DWORD riding_bonus = 0;
if (ch->IsRiding())
{
riding_bonus = 50;
}

DWORD ani_speed = ani_attack_speed(ch);
DWORD real_speed = (ani_speed * 100) / (default_bonus + ch->GetPoint(POINT_ATT_SPEED) + riding_bonus);
if (item && item->GetSubType() == WEAPON_DAGGER)
real_speed /= 2;
#ifdef ENABLE_WOLFMAN_CHARACTER
else if (item && item->GetSubType() == WEAPON_CLAW)
real_speed /= 2;
#endif

return real_speed;
}

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 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;
}

bool IS_SPEED_HACK(LPCHARACTER ch, LPCHARACTER victim, DWORD current_time)
{
if (ch->m_kAttackLog.dwVID == victim->GetVID())
{
if (current_time - ch->m_kAttackLog.dwTime < GET_ATTACK_SPEED(ch))
{
INCREASE_SPEED_HACK_COUNT(ch);

if (test_server)
{
sys_log(0, "%s attack hack! time (delta, limit)=(%u, %u) hack_count %d",
ch->GetName(),
current_time - ch->m_kAttackLog.dwTime,
GET_ATTACK_SPEED(ch),
ch->m_speed_hack_count);

ch->ChatPacket(CHAT_TYPE_INFO, "%s attack hack! time (delta, limit)=(%u, %u) hack_count %d",
ch->GetName(),
current_time - ch->m_kAttackLog.dwTime,
GET_ATTACK_SPEED(ch),
ch->m_speed_hack_count);
}

SET_ATTACK_TIME(ch, victim, current_time);
SET_ATTACKED_TIME(ch, victim, current_time);
return true;
}
}

SET_ATTACK_TIME(ch, victim, current_time);

if (victim->m_AttackedLog.dwPID == ch->GetPlayerID())
{
if (current_time - victim->m_AttackedLog.dwAttackedTime < GET_ATTACK_SPEED(ch))
{
INCREASE_SPEED_HACK_COUNT(ch);

if (test_server)
{
sys_log(0, "%s Attack Speed HACK! time (delta, limit)=(%u, %u), hack_count = %d",
ch->GetName(),
current_time - victim->m_AttackedLog.dwAttackedTime,
GET_ATTACK_SPEED(ch),
ch->m_speed_hack_count);

ch->ChatPacket(CHAT_TYPE_INFO, "Attack Speed Hack(%s), (delta, limit)=(%u, %u)",
ch->GetName(),
current_time - victim->m_AttackedLog.dwAttackedTime,
GET_ATTACK_SPEED(ch));
}

SET_ATTACKED_TIME(ch, victim, current_time);
return true;
}
}

SET_ATTACKED_TIME(ch, victim, current_time);
return false;
}


[/CODE]


[CODE title="constants.cpp"]#include "stdafx.h"
#include "char.h"
#include "../../common/service.h"
TJobInitialPoints JobInitialPoints[JOB_MAX_NUM] =
/*
{
int st, ht, dx, iq;
int max_hp, max_sp;
int hp_per_ht, sp_per_iq;
int hp_per_lv_begin, hp_per_lv_end;
int sp_per_lv_begin, sp_per_lv_end;
int max_stamina;
int stamina_per_con;
int stamina_per_lv_begin, stamina_per_lv_end;
}
*/
{
// str con dex int 초기HP 초기SP CON/HP INT/SP HP랜덤/lv MP랜덤/lv 초기stam stam/con stam/lv
{ 6, 4, 3, 3, 600, 200, 40, 20, 36, 44, 18, 22, 800, 5, 1, 3 }, // JOB_WARRIOR 16
{ 4, 3, 6, 3, 650, 200, 40, 20, 36, 44, 18, 22, 800, 5, 1, 3 }, // JOB_ASSASSIN 16
{ 5, 3, 3, 5, 650, 200, 40, 20, 36, 44, 18, 22, 800, 5, 1, 3 }, // JOB_SURA 16
{ 3, 4, 3, 6, 700, 200, 40, 20, 36, 44, 18, 22, 800, 5, 1, 3 }, // JOB_SHAMANa 16
#ifdef ENABLE_WOLFMAN_CHARACTER
{ 2, 6, 6, 2, 600, 200, 40, 20, 36, 44, 18, 22, 800, 5, 1, 3 }, // JOB_WOLFMAN 16 // TODO: 4개능력치 초기값 외에 다른 스탯 필요 (기획자한테 요청)
#endif
};

const TMobRankStat MobRankStats[MOB_RANK_MAX_NUM] =
/*
{
int iGoldPercent;
}
*/
{
{ 20, }, // MOB_RANK_PAWN,
{ 20, }, // MOB_RANK_S_PAWN,
{ 25, }, // MOB_RANK_KNIGHT,
{ 30, }, // MOB_RANK_S_KNIGHT,
{ 50, }, // MOB_RANK_BOSS,
{ 100, } // MOB_RANK_KING,
};

TBattleTypeStat BattleTypeStats[BATTLE_TYPE_MAX_NUM] =
/*
{
int AttGradeBias;
int DefGradeBias;
int MagicAttGradeBias;
int MagicDefGradeBias;
}
*/
{
{ 0, 0, 0, -10 }, // BATTLE_TYPE_MELEE,
{ 10, -20, -10, -15 }, // BATTLE_TYPE_RANGE,
{ -5, -5, 10, 10 }, // BATTLE_TYPE_MAGIC,
{ 0, 0, 0, 0 }, // BATTLE_TYPE_SPECIAL,
{ 10, -10, 0, -15 }, // BATTLE_TYPE_POWER,
{ -10, 10, -10, 0 }, // BATTLE_TYPE_TANKER,
{ 20, -20, 0, -10 }, // BATTLE_TYPE_SUPER_POWER,
{ -20, 20, -10, 0 }, // BATTLE_TYPE_SUPER_TANKER,
};

#ifdef ENABLE_GROWTH_PET_SYSTEM
DWORD * exppet_table = NULL;
//const DWORD pets = 4;
const DWORD Pet_Table[10][2] =
{
{ 55701, 34041 },
{ 55702, 34045 },
{ 55703, 34049 },
{ 55704, 34053 },
{ 55705, 34036 },
{ 55706, 34061 },
{ 55707, 34073 },
{ 55708, 34075 },
{ 55709, 34080 },
{ 55710, 34082 }
};

const DWORD Pet_Skill_Table[18][23] =
{
//Level Like Index ->> Bonus Value --> typeSkill --> CoolDown -->> Percentage
{ 78, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 12 },
{ 80, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 12 },
{ 79, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 12 },
{ 81, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 12 },
{ 95, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 12 }, //5
{ 64, 0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 10 },
{ 98, 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, 12 },//fixpet
{ 9, 0, 0, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 17 },
{ 16, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 9, 9 },
{ 4, 1, 480, 17, 68, 153, 272, 425, 612, 833, 1088, 1377, 1700, 2057, 2448, 2873, 3332, 3825, 4352, 4913, 5508, 6137, 6800 }, //10
{ 23, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5 },
{ 24, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 6, 6 },
{ 27, 0, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11 },
{ 28, 0, 0, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7 },
{ 44, 0, 0, 5, 10, 15, 20, 25, 31, 36, 41, 46, 51, 56, 61, 67, 72, 77, 82, 87, 92, 97, 103 }, //15
{ 52, 0, 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6 },
{ 11, 1, 600, 2, 4, 6, 7, 8, 9, 11, 12, 13, 15, 16, 17, 18, 20, 21, 22, 23, 25, 26, 27 },
{ 6, 1, 480, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }


};

const DWORD Pet_SKill_TablePerc[3][20] =
{
{ 2, 5, 8, 11, 13, 16, 19, 22, 24, 27, 30, 33, 35, 38, 41, 44, 46, 49, 52, 55 },
{ 2, 5, 7, 10, 12, 15, 17, 20, 23, 25, 27, 30, 32, 35, 37, 40, 42, 45, 47, 50 },
{ 2, 5, 8, 11, 13, 16, 19, 22, 25, 27, 30, 33, 36, 38, 41, 44, 47, 50, 52, 55 }
};

DWORD exppet_table_common[120];
#endif

const DWORD * exp_table = NULL;

const DWORD exp_table_euckr[PLAYER_EXP_TABLE_MAX + 1] =
{
0, // 0

100,
150,
260,
380,
600,

1300,
3300,
5700,
8700,
12800, // 10
18000,
25000,
36000,
52000,
73000,
100000,
125000,
160000,
220000,
280000, // 20
370000,
540000,
670000,
880000,
1000000,

1237000,
1418000,
1624000,
1857000,
2122000, // 30
2421000,
2761000,
3145000,
3580000,
4073000,
4632000,
5194000,
5717000,
6264000,
6837000, // 40
7600000,
8274000,
8990000,
9753000,
10560000,
11410000,
12320000,
13270000,
14280000,
15340000, // 50
16870000,
18960000,
19980000,
21420000,
22930000,
24530000,
26200000,
27960000,
29800000,
32780000, // 60
36060000,
39670000,
43640000,
48000000,
52800000,
58080000,
63890000,
70280000,
77310000,
85040000, // 70
93540000,
102900000,
113200000,
124500000,
137000000,
150700000,
165700000,
236990000,
260650000,
286780000, // 80
315380000,
346970000,
381680000,
419770000,
461760000,
508040000,
558740000,
614640000,
676130000,
743730000, // 90
1041222000,
1145344200,
1259878620,
1385866482,
1524453130,
1676898443,
1844588288,
2029047116,
2100000000, // 99 99레벨일 때 필요경험치 (100레벨이 되기 위한)
2100000000, // 100
2100000000,
2100000000,
2100000000,
2100000000,
2100000000, // 105
2100000000,
2100000000,
2100000000,
2100000000,
2100000000, // 110
2100000000,
2100000000,
2100000000,
2100000000,
2100000000, // 115
2100000000,
2100000000,
2100000000,
2100000000,
2100000000, // 120
};

const DWORD exp_table_common[PLAYER_EXP_TABLE_MAX + 1] =
{
0, // 0
300, //500
800, //700
1500, //1000
2500,
4300,
7200,
11000,
17000,
24000,
33000, // 10
43000,
58000,
76000,
100000,
130000,
169000,
219000,
283000,
365000,
472000, // 20
610000,
705000,
813000,
937000,
1077000,
1237000,
1418000,
1624000,
1857000,
2122000, // 30
2421000,
2761000,
3145000,
3580000,
4073000,
4632000,
5194000,
5717000,
6264000,
6837000, // 40
7600000,
8274000,
8990000,
9753000,
10560000,
11410000,
12320000,
13270000,
14280000,
15340000, // 50
16870000,
18960000,
19980000,
21420000,
22930000,
24530000,
26200000,
27960000,
29800000,
32780000, // 60
36060000,
39670000,
43640000,
48000000,
52800000,
58080000,
63890000,
70280000,
77310000,
85040000, // 70
93540000,
102900000,
113200000,
124500000,
137000000,
150700000,
165700000,
236990000,
260650000,
286780000, // 80
315380000,
346970000,
381680000,
419770000,
461760000,
508040000,
558740000,
614640000,
676130000,
743730000, // 90
1041222000,
1145344200,
1259878620,
1385866482,
1524453130,
1676898443,
1844588288,
1929047116,
2000000000, // 99레벨 일 때 필요경험치 (100레벨이 되기 위한)
2020000000, // 100
2040000000,
2060000000,
2080000000,
2090000000,
2100000000, // 105
2100000000,
2100000000,
2100000000,
2100000000,
2100000000, // 110
2100000000,
2100000000,
2100000000,
2100000000,
2100000000, // 115
2100000000,
2100000000,
2100000000,
2100000000,
2100000000, // 120
2251500000,
2253000000,
2254500000,
2256000000,
2257500000, // 125
2259000000,
2260500000,
2262000000,
2263500000,
2265000000, // 130
2266500000,
2268000000,
2269500000,
2271000000,
2272500000, // 135
2274000000,
2275500000,
2277000000,
2278500000,
2280000000, // 140
2281800000,
2283600000,
2285400000,
2287200000,
2289000000, // 145
2290800000,
2292600000,
2294400000,
2296200000,
2298000000, // 150
2299800000,
2301600000,
2303400000,
2305200000,
2307000000, // 155
2308800000,
2310600000,
2312400000,
2314200000,
2316000000, // 160
2317800000,
2319600000,
2321400000,
2323200000,
2325000000, // 165
2326800000,
2328600000,
2330400000,
2332200000,
2334000000, // 170
2335800000,
2337600000,
2339400000,
2341200000,
2343000000, // 175
2344800000,
2346600000,
2348400000,
2350200000,
2352000000, // 180
2353800000,
2355600000,
2357400000,
2359200000,
2361000000, // 185
2362800000,
2364600000,
2366400000,
2368200000,
2370000000, // 190
2371800000,
2373600000,
2375400000,
2377200000,
2379000000, // 195
2380800000,
2382600000,
2384400000,
2386200000,
2388000000, // 200
2389800000,
2391600000,
2393400000,
2395200000,
2397000000, // 205
2398800000,
2400600000,
2402400000,
2404200000,
2406000000, // 210
2407800000,
2409600000,
2411400000,
2413200000,
2415000000, // 215
2416800000,
2418600000,
2420400000,
2422200000,
2424000000, // 220
2425800000,
2427600000,
2429400000,
2431200000,
2433000000, // 225
2434800000,
2436600000,
2438400000,
2440200000,
2442000000, // 230
2443800000,
2445600000,
2447400000,
2449200000,
2451000000, // 235
2452800000,
2454600000,
2456400000,
2458200000,
2460000000, // 240
2461800000,
2463600000,
2465400000,
2467200000,
2469000000, // 245
2470800000,
2472600000,
2474400000,
2478000000,
2500000000, // 250
};

#ifdef ENABLE_SUPPORT_SYSTEM
const DWORD exp_support_table[121] =
{
0,
300,
800,
1500,
2500,
4300,
7200,
11000,
17000,
24000,
33001,
43000,
58000,
76000,
100000,
130000,
169000,
219000,
283000,
365000,
472000,
610000,
705000,
813000,
937000,
1077000,
1237000,
1418000,
1624000,
1857000,
2122000,
2421000,
2761000,
3145000,
3580000,
4073000,
4632000,
5194000,
5717000,
6264000,
6837000,
7600000,
8274000,
8990000,
9753000,
10560000,
11410000,
12320000,
13270000,
14280000,
15340000,
16870000,
18960000,
19980000,
21420000,
22930000,
24530000,
26200000,
27960000,
29800000,
32780000,
36060000,
39670000,
43640000,
48000000,
52800000,
58080000,
63890000,
70280000,
77310000,
85040000,
93540000,
102900000,
113200000,
124500000,
137000000,
150700000,
165700000,
236990000,
260650000,
286780000,
315380000,
346970000,
381680000,
419770000,
461760000,
508040000,
558740000,
614640000,
676130000,
743730000,
1041222000,
1145344200,
1259878620,
1385866482,
1524453130,
1676898443,
1844588288,
2029047116,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
};
#endif

const DWORD exp_table_newcibn[PLAYER_EXP_TABLE_MAX + 1 ] =
{
300, // 0
800, // 1
1500,
2500,
4300,
7200,
11400,
17000,
24000,
33000,
46000, // 10
62000,
83000,
111000,
149000,
200000,
268000,
360000,
482000,
647000,
868000, // 20
996000,
1143000,
1312000,
1506000,
1729000,
1984000,
2277000,
2614000,
3000000,
3443000, // 30
3952000,
4536000,
5206000,
5975000,
6858000,
7730000,
8504000,
9307000,
10140000,
11330000, // 40
12320000,
13370000,
14490000,
15670000,
16920000,
18240000,
19630000,
21090000,
22630000,
24670000, // 50
26890000,
29310000,
31950000,
34820000,
37960000,
41370000,
45100000,
49160000,
53580000,
58400000, // 60
63660000,
69390000,
75630000,
82440000,
89860000,
97950000,
106760000,
136370000,
151800000,
168300000, // 70
250000000,
340000000,
450000000,
570000000,
690000000,
810000000,
912600000,
1004000000,
1094000000,
1182000000, // 80
1269000000,
1354000000,
1438000000,
1521000000,
1603000000,
1684000000,
1764000000,
1844000000,
1922000000,
2000000000, // 90
2000000000,
2000000000,
2000000000,
2000000000,
2000000000,
2000000000,
2000000000,
2000000000,
2000000000, // 99 99레벨일 때 필요경험치 (100레벨이 되기 위한).. 현재 CIBN이 어떻게 운영하고 있는 지 모르니 신규 테이블을 쓰지 않고 기존값 계속 연장 유지
2000000000, // 100
2000000000,
2000000000,
2000000000,
2000000000,
2000000000, // 105
2000000000,
2000000000,
2000000000,
2000000000,
2000000000, // 110
2000000000,
2000000000,
2000000000,
2000000000,
2000000000, // 115
2000000000,
2000000000,
2000000000,
2000000000,
2000000000, // 120
};

const int * aiPercentByDeltaLev = NULL;
const int * aiPercentByDeltaLevForBoss = NULL;

// 적과 나와의 레벨차이에 의한 계산에 사용되는 테이블
// MIN(MAX_EXP_DELTA_OF_LEV - 1, (적렙 + 15) - 내렙))
const int aiPercentByDeltaLevForBoss_euckr[MAX_EXP_DELTA_OF_LEV] =
{
1, // -15 0
3, // -14 1
5, // -13 2
7, // -12 3
15, // -11 4
30, // -10 5
60, // -9 6
90, // -8 7
91, // -7 8
92, // -6 9
93, // -5 10
94, // -4 11
95, // -3 12
97, // -2 13
99, // -1 14
100, // 0 15
105, // 1 16
110, // 2 17
115, // 3 18
120, // 4 19
125, // 5 20
130, // 6 21
135, // 7 22
140, // 8 23
145, // 9 24
150, // 10 25
155, // 11 26
160, // 12 27
165, // 13 28
170, // 14 29
180 // 15 30
};



const int aiPercentByDeltaLev_euckr[MAX_EXP_DELTA_OF_LEV] =
{
1, // -15 0
5, // -14 1
10, // -13 2
20, // -12 3
30, // -11 4
50, // -10 5
70, // -9 6
80, // -8 7
85, // -7 8
90, // -6 9
92, // -5 10
94, // -4 11
96, // -3 12
98, // -2 13
100, // -1 14
100, // 0 15
105, // 1 16
110, // 2 17
115, // 3 18
120, // 4 19
125, // 5 20
130, // 6 21
135, // 7 22
140, // 8 23
145, // 9 24
150, // 10 25
155, // 11 26
160, // 12 27
165, // 13 28
170, // 14 29
180, // 15 30
};

const DWORD party_exp_distribute_table[PLAYER_MAX_LEVEL_CONST + 1] =
{
0,
10, 10, 10, 10, 15, 15, 20, 25, 30, 40, // 1 - 10
50, 60, 80, 100, 120, 140, 160, 184, 210, 240, // 11 - 20
270, 300, 330, 360, 390, 420, 450, 480, 510, 550, // 21 - 30
600, 640, 700, 760, 820, 880, 940, 1000, 1100, 1180, // 31 - 40
1260, 1320, 1380, 1440, 1500, 1560, 1620, 1680, 1740, 1800, // 41 - 50
1860, 1920, 2000, 2100, 2200, 2300, 2450, 2600, 2750, 2900, // 51 - 60
3050, 3200, 3350, 3500, 3650, 3800, 3950, 4100, 4250, 4400, // 61 - 70
4600, 4800, 5000, 5200, 5400, 5600, 5800, 6000, 6200, 6400, // 71 - 80
6600, 6800, 7000, 7200, 7400, 7600, 7800, 8000, 8200, 8400, // 81 - 90
8600, 8800, 9000, 9200, 9400, 9600, 9800, 10000, 10200, 10400, // 91 - 100
10600, 10800, 11000, 11200, 11400, 11600, 11800, 12000, 12200, 12400, // 101 - 110
12600, 12800, 13000, 13200, 13400, 13600, 13800, 14000, 14200, 14400, // 111 - 120
14600, 14800, 15000, 15200, 15400, 15600, 15800, 16000, 16200, 16400, // 121 - 130
16600, 16800, 17000, 17200, 17400, 17600, 17800, 18000, 18200, 18400, // 131 - 140
18600, 18800, 19000, 19200, 19400, 19600, 19800, 20000, 20200, 20400, // 141 - 150
20600, 20800, 21000, 21200, 21400, 21600, 21800, 22000, 22200, 22400, // 151 - 160
22600, 22800, 23000, 23200, 23400, 23600, 23800, 24000, 24200, 24400, // 161 - 170
24600, 24800, 25000, 25200, 25400, 25600, 25800, 26000, 26200, 26400, // 171 - 180
26600, 26800, 27000, 27200, 27400, 27600, 27800, 28000, 28200, 28400, // 181 - 190
28600, 28800, 29000, 29200, 29400, 29600, 29800, 30000, 30200, 30400, // 191 - 200
30600, 30800, 31000, 31200, 31400, 31600, 31800, 32000, 32200, 32400, // 201 - 210
32600, 32800, 33000, 33200, 33400, 33600, 33800, 34000, 34200, 34400, // 211 - 220
34600, 34800, 35000, 35200, 35400, 35600, 35800, 36000, 36200, 36400, // 221 - 230
36600, 36800, 37000, 37200, 37400, 37600, 37800, 38000, 38200, 38400, // 231 - 240
38600, 38800, 39000, 39200, 39400, 39600, 39800, 40000, 40200, 40400, // 241 - 250
};

Coord aArroundCoords[ARROUND_COORD_MAX_NUM] =
{
{ 0, 0 },
{ 0, 50 },
{ 35, 35 },
{ 50, -0 },
{ 35, -35 },
{ 0, -50 },
{ -35, -35 },
{ -50, 0 },
{ -35, 35 },
{ 0, 100 },
{ 71, 71 },
{ 100, -0 },
{ 71, -71 },
{ 0, -100 },
{ -71, -71 },
{ -100, 0 },
{ -71, 71 },
{ 0, 150 },
{ 106, 106 },
{ 150, -0 },
{ 106, -106 },
{ 0, -150 },
{ -106, -106 },
{ -150, 0 },
{ -106, 106 },
{ 0, 200 },
{ 141, 141 },
{ 200, -0 },
{ 141, -141 },
{ 0, -200 },
{ -141, -141 },
{ -200, 0 },
{ -141, 141 },
{ 0, 250 },
{ 177, 177 },
{ 250, -0 },
{ 177, -177 },
{ 0, -250 },
{ -177, -177 },
{ -250, 0 },
{ -177, 177 },
{ 0, 300 },
{ 212, 212 },
{ 300, -0 },
{ 212, -212 },
{ 0, -300 },
{ -212, -212 },
{ -300, 0 },
{ -212, 212 },
{ 0, 350 },
{ 247, 247 },
{ 350, -0 },
{ 247, -247 },
{ 0, -350 },
{ -247, -247 },
{ -350, 0 },
{ -247, 247 },
{ 0, 400 },
{ 283, 283 },
{ 400, -0 },
{ 283, -283 },
{ 0, -400 },
{ -283, -283 },
{ -400, 0 },
{ -283, 283 },
{ 0, 450 },
{ 318, 318 },
{ 450, -0 },
{ 318, -318 },
{ 0, -450 },
{ -318, -318 },
{ -450, 0 },
{ -318, 318 },
{ 0, 500 },
{ 354, 354 },
{ 500, -0 },
{ 354, -354 },
{ 0, -500 },
{ -354, -354 },
{ -500, 0 },
{ -354, 354 },
{ 0, 550 },
{ 389, 389 },
{ 550, -0 },
{ 389, -389 },
{ 0, -550 },
{ -389, -389 },
{ -550, 0 },
{ -389, 389 },
{ 0, 600 },
{ 424, 424 },
{ 600, -0 },
{ 424, -424 },
{ 0, -600 },
{ -424, -424 },
{ -600, 0 },
{ -424, 424 },
{ 0, 650 },
{ 460, 460 },
{ 650, -0 },
{ 460, -460 },
{ 0, -650 },
{ -460, -460 },
{ -650, 0 },
{ -460, 460 },
{ 0, 700 },
{ 495, 495 },
{ 700, -0 },
{ 495, -495 },
{ 0, -700 },
{ -495, -495 },
{ -700, 0 },
{ -495, 495 },
{ 0, 750 },
{ 530, 530 },
{ 750, -0 },
{ 530, -530 },
{ 0, -750 },
{ -530, -530 },
{ -750, 0 },
{ -530, 530 },
{ 0, 800 },
{ 566, 566 },
{ 800, -0 },
{ 566, -566 },
{ 0, -800 },
{ -566, -566 },
{ -800, 0 },
{ -566, 566 },
{ 0, 850 },
{ 601, 601 },
{ 850, -0 },
{ 601, -601 },
{ 0, -850 },
{ -601, -601 },
{ -850, 0 },
{ -601, 601 },
{ 0, 900 },
{ 636, 636 },
{ 900, -0 },
{ 636, -636 },
{ 0, -900 },
{ -636, -636 },
{ -900, 0 },
{ -636, 636 },
{ 0, 950 },
{ 672, 672 },
{ 950, -0 },
{ 672, -672 },
{ 0, -950 },
{ -672, -672 },
{ -950, 0 },
{ -672, 672 },
{ 0, 1000 },
{ 707, 707 },
{ 1000, -0 },
{ 707, -707 },
{ 0, -1000 },
{ -707, -707 },
{ -1000, 0 },
{ -707, 707 },
};

const DWORD guild_exp_table[GUILD_MAX_LEVEL+1] =
{
0,
15000UL,
45000UL,
90000UL,
160000UL,
235000UL,
325000UL,
430000UL,
550000UL,
685000UL,
835000UL,
1000000UL,
1500000UL,
2100000UL,
2800000UL,
3600000UL,
4500000UL,
6500000UL,
8000000UL,
10000000UL,
42000000UL
};

// INTERNATIONAL_VERSION 길드경험치
const DWORD guild_exp_table2[GUILD_MAX_LEVEL+1] =
{
0,
6000UL,
18000UL,
36000UL,
64000UL,
94000UL,
130000UL,
172000UL,
220000UL,
274000UL,
334000UL,
400000UL,
600000UL,
840000UL,
1120000UL,
1440000UL,
1800000UL,
2600000UL,
3200000UL,
4000000UL,
16800000UL
};
// END_OF_INTERNATIONAL_VERSION 길드경험치

const int aiMobEnchantApplyIdx[MOB_ENCHANTS_MAX_NUM] =
{
APPLY_CURSE_PCT,
APPLY_SLOW_PCT,
APPLY_POISON_PCT,
APPLY_STUN_PCT,
APPLY_CRITICAL_PCT,
APPLY_PENETRATE_PCT,
#if defined(ENABLE_WOLFMAN_CHARACTER) && !defined(USE_MOB_BLEEDING_AS_POISON)
APPLY_BLEEDING_PCT,
#endif
};

const int aiMobResistsApplyIdx[MOB_RESISTS_MAX_NUM] =
{
APPLY_RESIST_SWORD,
APPLY_RESIST_TWOHAND,
APPLY_RESIST_DAGGER,
APPLY_RESIST_BELL,
APPLY_RESIST_FAN,
APPLY_RESIST_BOW,
APPLY_RESIST_FIRE,
APPLY_RESIST_ELEC,
APPLY_RESIST_MAGIC,
APPLY_RESIST_WIND,
APPLY_POISON_REDUCE,
#if defined(ENABLE_WOLFMAN_CHARACTER) && !defined(USE_MOB_CLAW_AS_DAGGER)
APPLY_RESIST_CLAW,
#endif
#if defined(ENABLE_WOLFMAN_CHARACTER) && !defined(USE_MOB_BLEEDING_AS_POISON)
APPLY_BLEEDING_REDUCE,
#endif
};

const int aiSocketPercentByQty[5][4] =
{
{ 0, 0, 0, 0 },
{ 3, 0, 0, 0 },
{ 10, 1, 0, 0 },
{ 15, 10, 1, 0 },
{ 20, 15, 10, 1 }
};

const int aiWeaponSocketQty[WEAPON_NUM_TYPES] =
{
4, // WEAPON_SWORD,
4, // WEAPON_DAGGER,
4, // WEAPON_BOW,
4, // WEAPON_TWO_HANDED,
4, // WEAPON_BELL,
4, // WEAPON_FAN,
0, // WEAPON_ARROW,
0, // WEAPON_MOUNT_SPEAR,
#ifdef ENABLE_WOLFMAN_CHARACTER
4, // WEAPON_CLAW
#endif
#ifdef WJ_QUIVER_SYSTEM
0, // WEAPON_UNLIMITED_ARROW
#endif
};

const int aiArmorSocketQty[ARMOR_NUM_TYPES] =
{
4, // ARMOR_BODY,
1, // ARMOR_HEAD,
1, // ARMOR_SHIELD,
0, // ARMOR_WRIST,
0, // ARMOR_FOOTS,
0 // ARMOR_ACCESSORY
};

TItemAttrMap g_map_itemAttr;
TItemAttrMap g_map_itemRare;

const TApplyInfo aApplyInfo[MAX_APPLY_NUM] =
/*
{
DWORD dwPointType;
}
*/
{
// Point Type
{ POINT_NONE, }, // APPLY_NONE, 0
{ POINT_MAX_HP, }, // APPLY_MAX_HP, 1
{ POINT_MAX_SP, }, // APPLY_MAX_SP, 2
{ POINT_HT, }, // APPLY_CON, 3
{ POINT_IQ, }, // APPLY_INT, 4
{ POINT_ST, }, // APPLY_STR, 5
{ POINT_DX, }, // APPLY_DEX, 6
{ POINT_ATT_SPEED, }, // APPLY_ATT_SPEED, 7
{ POINT_MOV_SPEED, }, // APPLY_MOV_SPEED, 8
{ POINT_CASTING_SPEED, }, // APPLY_CAST_SPEED, 9
{ POINT_HP_REGEN, }, // APPLY_HP_REGEN, 10
{ POINT_SP_REGEN, }, // APPLY_SP_REGEN, 11
{ POINT_POISON_PCT, }, // APPLY_POISON_PCT, 12
{ POINT_STUN_PCT, }, // APPLY_STUN_PCT, 13
{ POINT_SLOW_PCT, }, // APPLY_SLOW_PCT, 14
{ POINT_CRITICAL_PCT, }, // APPLY_CRITICAL_PCT, 15
{ POINT_PENETRATE_PCT, }, // APPLY_PENETRATE_PCT, 16
{ POINT_ATTBONUS_HUMAN, }, // APPLY_ATTBONUS_HUMAN, 17
{ POINT_ATTBONUS_ANIMAL, }, // APPLY_ATTBONUS_ANIMAL, 18
{ POINT_ATTBONUS_ORC, }, // APPLY_ATTBONUS_ORC, 19
{ POINT_ATTBONUS_MILGYO, }, // APPLY_ATTBONUS_MILGYO, 20
{ POINT_ATTBONUS_UNDEAD, }, // APPLY_ATTBONUS_UNDEAD, 21
{ POINT_ATTBONUS_DEVIL, }, // APPLY_ATTBONUS_DEVIL, 22
{ POINT_STEAL_HP, }, // APPLY_STEAL_HP, 23
{ POINT_STEAL_SP, }, // APPLY_STEAL_SP, 24
{ POINT_MANA_BURN_PCT, }, // APPLY_MANA_BURN_PCT, 25
{ POINT_DAMAGE_SP_RECOVER, }, // APPLY_DAMAGE_SP_RECOVER,26
{ POINT_BLOCK, }, // APPLY_BLOCK, 27
{ POINT_DODGE, }, // APPLY_DODGE, 28
{ POINT_RESIST_SWORD, }, // APPLY_RESIST_SWORD, 29
{ POINT_RESIST_TWOHAND, }, // APPLY_RESIST_TWOHAND, 30
{ POINT_RESIST_DAGGER, }, // APPLY_RESIST_DAGGER, 31
{ POINT_RESIST_BELL, }, // APPLY_RESIST_BELL, 32
{ POINT_RESIST_FAN, }, // APPLY_RESIST_FAN, 33
{ POINT_RESIST_BOW, }, // APPLY_RESIST_BOW, 34
{ POINT_RESIST_FIRE, }, // APPLY_RESIST_FIRE, 35
{ POINT_RESIST_ELEC, }, // APPLY_RESIST_ELEC, 36
{ POINT_RESIST_MAGIC, }, // APPLY_RESIST_MAGIC, 37
{ POINT_RESIST_WIND, }, // APPLY_RESIST_WIND, 38
{ POINT_REFLECT_MELEE, }, // APPLY_REFLECT_MELEE, 39
{ POINT_REFLECT_CURSE, }, // APPLY_REFLECT_CURSE, 40
{ POINT_POISON_REDUCE, }, // APPLY_POISON_REDUCE, 41
{ POINT_KILL_SP_RECOVER, }, // APPLY_KILL_SP_RECOVER, 42
{ POINT_EXP_DOUBLE_BONUS, }, // APPLY_EXP_DOUBLE_BONUS, 43
{ POINT_GOLD_DOUBLE_BONUS, }, // APPLY_GOLD_DOUBLE_BONUS,44
{ POINT_ITEM_DROP_BONUS, }, // APPLY_ITEM_DROP_BONUS, 45
{ POINT_POTION_BONUS, }, // APPLY_POTION_BONUS, 46
{ POINT_KILL_HP_RECOVERY, }, // APPLY_KILL_HP_RECOVER, 47
{ POINT_IMMUNE_STUN, }, // APPLY_IMMUNE_STUN, 48
{ POINT_IMMUNE_SLOW, }, // APPLY_IMMUNE_SLOW, 49
{ POINT_IMMUNE_FALL, }, // APPLY_IMMUNE_FALL, 50
{ POINT_NONE, }, // APPLY_SKILL, 51
{ POINT_BOW_DISTANCE, }, // APPLY_BOW_DISTANCE, 52
{ POINT_ATT_GRADE_BONUS, }, // APPLY_ATT_GRADE, 53
{ POINT_DEF_GRADE_BONUS, }, // APPLY_DEF_GRADE, 54
{ POINT_MAGIC_ATT_GRADE_BONUS, }, // APPLY_MAGIC_ATT_GRADE, 55
{ POINT_MAGIC_DEF_GRADE_BONUS, }, // APPLY_MAGIC_DEF_GRADE, 56
{ POINT_CURSE_PCT, }, // APPLY_CURSE_PCT, 57
{ POINT_MAX_STAMINA }, // APPLY_MAX_STAMINA 58
{ POINT_ATTBONUS_WARRIOR }, // APPLY_ATTBONUS_WARRIOR 59
{ POINT_ATTBONUS_ASSASSIN }, // APPLY_ATTBONUS_ASSASSIN 60
{ POINT_ATTBONUS_SURA }, // APPLY_ATTBONUS_SURA 61
{ POINT_ATTBONUS_SHAMAN }, // APPLY_ATTBONUS_SHAMAN 62
{ POINT_ATTBONUS_MONSTER }, // APPLY_ATTBONUS_MONSTER 63
{ POINT_ATT_BONUS }, // 64 // APPLY_MALL_ATTBONUS
{ POINT_MALL_DEFBONUS }, // 65
{ POINT_MALL_EXPBONUS }, // 66 APPLY_MALL_EXPBONUS
{ POINT_MALL_ITEMBONUS }, // 67
{ POINT_MALL_GOLDBONUS }, // 68
{ POINT_MAX_HP_PCT }, // 69
{ POINT_MAX_SP_PCT }, // 70
{ POINT_SKILL_DAMAGE_BONUS }, // 71
{ POINT_NORMAL_HIT_DAMAGE_BONUS }, // 72

// DEFEND_BONUS_ATTRIBUTES
{ POINT_SKILL_DEFEND_BONUS }, // 73
{ POINT_NORMAL_HIT_DEFEND_BONUS }, // 74
// END_OF_DEFEND_BONUS_ATTRIBUTES

// PC_BANG_ITEM_ADD
{ POINT_PC_BANG_EXP_BONUS }, // 75
{ POINT_PC_BANG_DROP_BONUS }, // 76
// END_PC_BANG_ITEM_ADD

{ POINT_NONE, }, // 77 사용시 HP 소모 APPLY_EXTRACT_HP_PCT

{ POINT_RESIST_WARRIOR, }, // 78 무사에게 저항 APPLY_RESIST_WARRIOR
{ POINT_RESIST_ASSASSIN, }, // 79 자객에게 저항 APPLY_RESIST_ASSASSIN
{ POINT_RESIST_SURA, }, // 80 수라에게 저항 APPLY_RESIST_SURA
{ POINT_RESIST_SHAMAN, }, // 81 무당에게 저항 APPLY_RESIST_SHAMAN
{ POINT_ENERGY }, // 82 기력
{ POINT_DEF_GRADE }, // 83 방어력. DEF_GRADE_BONUS는 클라에서 두배로 보여지는 의도된 버그(...)가 있다.
{ POINT_COSTUME_ATTR_BONUS }, // 84 코스튬에 붙은 속성에 대해서만 보너스를 주는 기력
{ POINT_MAGIC_ATT_BONUS_PER }, // 85 마법 공격력 +x%
{ POINT_MELEE_MAGIC_ATT_BONUS_PER }, // 86 APPLY_MELEE_MAGIC_ATTBONUS_PER
{ POINT_RESIST_ICE, }, // APPLY_RESIST_ICE, 87
{ POINT_RESIST_EARTH, }, // APPLY_RESIST_EARTH, 88
{ POINT_RESIST_DARK, }, // APPLY_RESIST_DARK, 89
{ POINT_RESIST_CRITICAL, }, // APPLY_ANTI_CRITICAL_PCT, 90
{ POINT_RESIST_PENETRATE, }, // APPLY_ANTI_PENETRATE_PCT, 91
#ifdef ENABLE_WOLFMAN_CHARACTER
{ POINT_BLEEDING_REDUCE, }, // APPLY_BLEEDING_REDUCE, 92
{ POINT_BLEEDING_PCT, }, // APPLY_BLEEDING_PCT, 93
{ POINT_ATTBONUS_WOLFMAN, }, // APPLY_ATTBONUS_WOLFMAN, 94 수인족에게 강함
{ POINT_RESIST_WOLFMAN, }, // APPLY_RESIST_WOLFMAN, 95 수인족에게 저항
{ POINT_RESIST_CLAW, }, // APPLY_RESIST_CLAW, 96 CLAW에게 저항
#else
{ POINT_NONE, }, // APPLY_BLEEDING_REDUCE, 92
{ POINT_NONE, }, // APPLY_BLEEDING_PCT, 93
{ POINT_NONE, }, // APPLY_ATTBONUS_WOLFMAN, 94 수인족에게 강함
{ POINT_NONE, }, // APPLY_RESIST_WOLFMAN, 95 수인족에게 저항
{ POINT_NONE, }, // APPLY_RESIST_CLAW, 96 CLAW에게 저항
#endif
#ifdef ENABLE_MAGIC_REDUCTION_SYSTEM
{ POINT_RESIST_MAGIC_REDUCTION, }, // APPLY_RESIST_MAGIC_REDUCTION,98
#else
{ POINT_NONE, }, // APPLY_RESIST_MAGIC_REDUCTION,98
#endif
#ifdef ELEMENT_NEW_BONUSES
{POINT_ATTBONUS_ELEC,},
{POINT_ATTBONUS_FIRE,},
{POINT_ATTBONUS_ICE,},
{POINT_ATTBONUS_WIND,},
{POINT_ATTBONUS_EARTH,},
{POINT_ATTBONUS_DARK,},
{POINT_ATTBONUS_PATRON,},
{POINT_ATTBONUS_METINN,},
#endif
};

const int aiItemMagicAttributePercentHigh[ITEM_ATTRIBUTE_MAX_LEVEL] =
{
//25, 25, 40, 8, 2,
30, 40, 20, 8, 2
};

const int aiItemMagicAttributePercentLow[ITEM_ATTRIBUTE_MAX_LEVEL] =
{
//45, 25, 20, 10, 0,
50, 40, 10, 0, 0
};

// ADD_ITEM_ATTRIBUTE
const int aiItemAttributeAddPercent[ITEM_ATTRIBUTE_MAX_NUM] =
{
100, 80, 60, 50, 30, 0, 0,
};
// END_OF_ADD_ITEM_ATTRIBUTE

const int aiExpLossPercents[PLAYER_EXP_TABLE_MAX + 1] =
{
0,
5, 5, 5, 5, 5, 5, 5, 5, 5, 4, // 1 - 10
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 11 - 20
4, 4, 4, 4, 4, 4, 4, 3, 3, 3, // 21 - 30
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 31 - 40
3, 3, 3, 3, 2, 2, 2, 2, 2, 2, // 41 - 50
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 51 - 60
2, 2, 1, 1, 1, 1, 1, 1, 1, 1, // 61 - 70
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 71 - 80
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 81 - 90
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 91 - 100
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 101 - 110
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 111 - 120
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 121 - 130
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 131 - 140
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 141 - 150
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 151 - 160
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 161 - 170
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 171 - 180
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 181 - 190
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 191 - 200
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 201 - 210
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 211 - 220
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 221 - 230
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 231 - 240
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 241 - 250
};

const int aiSkillBookCountForLevelUp[10] =
{
3, 3, 3, 3, 3, 4, 4, 5, 5, 6
};

// ADD_GRANDMASTER_SKILL
const int aiGrandMasterSkillBookCountForLevelUp[10] =
{
3, 3, 5, 5, 7, 7, 10, 10, 10, 20,
};

const int aiGrandMasterSkillBookMinCount[10] =
{
// 1, 1, 3, 5, 10, 15, 20, 30, 40, 50,
// 3, 3, 5, 5, 10, 10, 15, 15, 20, 30
1, 1, 1, 2, 2, 3, 3, 4, 5, 6
};

const int aiGrandMasterSkillBookMaxCount[10] =
{
// 6, 15, 30, 45, 60, 80, 100, 120, 160, 200,
// 6, 10, 15, 20, 30, 40, 50, 60, 70, 80
5, 7, 9, 11, 13, 15, 20, 25, 30, 35
};
// END_OF_ADD_GRANDMASTER_SKILL

const int CHN_aiPartyBonusExpPercentByMemberCount[9] =
{
0, 0, 12, 18, 26, 40, 53, 70, 100
};


// UPGRADE_PARTY_BONUS
const int KOR_aiPartyBonusExpPercentByMemberCount[9] =
{
0,
0,
30, // 66% * 2 - 100
60, // 53% * 3 - 100
75, // 44% * 4 - 100
90, // 38% * 5 - 100
105, // 34% * 6 - 100
110, // 30% * 7 - 100
140, // 30% * 8 - 100
};

const int KOR_aiUniqueItemPartyBonusExpPercentByMemberCount[9] =
{
0,
0,
15*2,
14*3,
13*4,
12*5,
11*6,
10*7,
10*8,
};
// END_OF_UPGRADE_PARTY_BONUS

const int * aiChainLightningCountBySkillLevel = NULL;

const int aiChainLightningCountBySkillLevel_euckr[SKILL_MAX_LEVEL+1] =
{
0, // 0
2, // 1
2, // 2
2, // 3
2, // 4
2, // 5
2, // 6
2, // 7
2, // 8
3, // 9
3, // 10
3, // 11
3, // 12
3, // 13
3, // 14
3, // 15
3, // 16
3, // 17
3, // 18
4, // 19
4, // 20
4, // 21
4, // 22
4, // 23
5, // 24
5, // 25
5, // 26
5, // 27
5, // 28
5, // 29
5, // 30
5, // 31
5, // 32
5, // 33
5, // 34
5, // 35
5, // 36
5, // 37
5, // 38
5, // 39
5, // 40
};

const SStoneDropInfo aStoneDrop[STONE_INFO_MAX_NUM] =
{
// mob pct {+0 +1 +2 +3 +4}
{8001, 60, {30, 30, 30, 9, 1} },
{8002, 60, {30, 30, 30, 9, 1} },
{8003, 60, {30, 30, 30, 9, 1} },
{8004, 60, {30, 30, 30, 9, 1} },
{8005, 60, {30, 30, 30, 9, 1} },
{8006, 60, {28, 29, 31, 11, 1} },
{8007, 60, {24, 29, 32, 13, 2} },
{8008, 60, {22, 28, 33, 15, 2} },
{8009, 60, {21, 27, 33, 17, 2} },
{8010, 60, {18, 26, 34, 20, 2} },
{8011, 60, {14, 26, 35, 22, 3} },
{8012, 60, {10, 26, 37, 24, 3} },
{8013, 60, {2, 26, 40, 29, 3} },
{8014, 60, {0, 26, 41, 30, 3} },
{8024, 60, {0, 26, 41, 30, 3} },
{8025, 60, {0, 26, 41, 30, 3} },
{8026, 60, {0, 26, 41, 30, 3} },
{8027, 60, {0, 26, 41, 30, 3} },
{8051, 60, {0, 26, 41, 30, 3} },
{8052, 60, {0, 26, 41, 30, 3} },
{8053, 60, {0, 26, 41, 30, 3} },
{8054, 60, {0, 26, 41, 30, 3} },
{8055, 60, {0, 26, 41, 30, 3} },
{8056, 60, {0, 26, 41, 30, 3} },
{8057, 60, {0, 26, 41, 30, 3} },
{8058, 60, {0, 26, 41, 30, 3} },
{8059, 60, {0, 26, 41, 30, 3} },
{8061, 60, {0, 26, 41, 30, 3} },
};

const char * c_apszEmpireNames[EMPIRE_MAX_NUM] =
{
"전제국",
"신수국",
"천조국",
"진노국"
};

const char * c_apszPrivNames[MAX_PRIV_NUM] =
{
"",
"아이템이 나올 확률",
"돈이 나올 확률",
"돈 대박이 나올 확률",
"경험치 배율",
};

const int aiPolymorphPowerByLevel[SKILL_MAX_LEVEL + 1] =
{
10, // 1
11, // 2
11, // 3
12, // 4
13, // 5
13, // 6
14, // 7
15, // 8
16, // 9
17, // 10
18, // 11
19, // 12
20, // 13
22, // 14
23, // 15
24, // 16
26, // 17
27, // 18
29, // 19
31, // 20
33, // 21
35, // 22
37, // 23
39, // 24
41, // 25
44, // 26
46, // 27
49, // 28
52, // 29
55, // 30
59, // 31
62, // 32
66, // 33
70, // 34
74, // 35
79, // 36
84, // 37
89, // 38
94, // 39
100, // 40
};

TGuildWarInfo KOR_aGuildWarInfo[GUILD_WAR_TYPE_MAX_NUM] =
/*
{
long lMapIndex;
int iWarPrice;
int iWinnerPotionRewardPctToWinner;
int iLoserPotionRewardPctToWinner;
int iInitialScore;
int iEndScore;
};
*/
{
{ 0, 0, 0, 0, 0, 0 },
{ 110, 0, 100, 50, 0, 100 },
{ 111, 0, 100, 50, 0, 10 },
};

//
// 악세서리 소켓용 수치들
//

// 다이아몬드로 소켓을 추가할 때 확률
const int aiAccessorySocketAddPct[ITEM_ACCESSORY_SOCKET_MAX_NUM] =
{
50, 50, 50
};

// 악세서리 수치 값의 몇%만큼의 성능을 추가하는지
const int aiAccessorySocketEffectivePct[ITEM_ACCESSORY_SOCKET_MAX_NUM + 1] =
{
0, 10, 20, 40
};

// 소켓 지속시간 24, 12, 6
const int aiAccessorySocketDegradeTime[ITEM_ACCESSORY_SOCKET_MAX_NUM + 1] =
{
0, 3600 * 24, 3600 * 12, 3600 * 6
};

// 소켓 장착 성공률
const int aiAccessorySocketPutPct[ITEM_ACCESSORY_SOCKET_MAX_NUM + 1] =
{
90, 80, 70, 0
};
// END_OF_ACCESSORY_REFINE

#include "../../common/length.h"
// from import_item_proto.c
typedef struct SValueName
{
const char * c_pszName;
long lValue;
} TValueName;

TValueName c_aApplyTypeNames[] =
{
{ "STR", APPLY_STR },
{ "DEX", APPLY_DEX },
{ "CON", APPLY_CON },
{ "INT", APPLY_INT },
{ "MAX_HP", APPLY_MAX_HP },
{ "MAX_SP", APPLY_MAX_SP },
{ "MAX_STAMINA", APPLY_MAX_STAMINA },
{ "POISON_REDUCE", APPLY_POISON_REDUCE },
{ "EXP_DOUBLE_BONUS", APPLY_EXP_DOUBLE_BONUS },
{ "GOLD_DOUBLE_BONUS", APPLY_GOLD_DOUBLE_BONUS },
{ "ITEM_DROP_BONUS", APPLY_ITEM_DROP_BONUS },
{ "HP_REGEN", APPLY_HP_REGEN },
{ "SP_REGEN", APPLY_SP_REGEN },
{ "ATTACK_SPEED", APPLY_ATT_SPEED },
{ "MOVE_SPEED", APPLY_MOV_SPEED },
{ "CAST_SPEED", APPLY_CAST_SPEED },
{ "ATT_BONUS", APPLY_ATT_GRADE_BONUS },
{ "DEF_BONUS", APPLY_DEF_GRADE_BONUS },
{ "MAGIC_ATT_GRADE",APPLY_MAGIC_ATT_GRADE },
{ "MAGIC_DEF_GRADE",APPLY_MAGIC_DEF_GRADE },
{ "SKILL", APPLY_SKILL },
{ "ATTBONUS_ANIMAL",APPLY_ATTBONUS_ANIMAL },
{ "ATTBONUS_UNDEAD",APPLY_ATTBONUS_UNDEAD },
{ "ATTBONUS_DEVIL", APPLY_ATTBONUS_DEVIL },
{ "ATTBONUS_HUMAN", APPLY_ATTBONUS_HUMAN },
{ "ADD_BOW_DISTANCE",APPLY_BOW_DISTANCE },
{ "DODGE", APPLY_DODGE },
{ "BLOCK", APPLY_BLOCK },
{ "RESIST_SWORD", APPLY_RESIST_SWORD },
{ "RESIST_TWOHAND", APPLY_RESIST_TWOHAND },
{ "RESIST_DAGGER", APPLY_RESIST_DAGGER },
{ "RESIST_BELL", APPLY_RESIST_BELL },
{ "RESIST_FAN", APPLY_RESIST_FAN },
{ "RESIST_BOW", APPLY_RESIST_BOW },
{ "RESIST_FIRE", APPLY_RESIST_FIRE },
{ "RESIST_ELEC", APPLY_RESIST_ELEC },
{ "RESIST_MAGIC", APPLY_RESIST_MAGIC },
{ "RESIST_WIND", APPLY_RESIST_WIND },
{ "REFLECT_MELEE", APPLY_REFLECT_MELEE },
{ "REFLECT_CURSE", APPLY_REFLECT_CURSE },
{ "RESIST_ICE", APPLY_RESIST_ICE },
{ "RESIST_EARTH", APPLY_RESIST_EARTH },
{ "RESIST_DARK", APPLY_RESIST_DARK },
{ "RESIST_CRITICAL", APPLY_ANTI_CRITICAL_PCT },
{ "RESIST_PENETRATE", APPLY_ANTI_PENETRATE_PCT },
{ "POISON", APPLY_POISON_PCT },
{ "SLOW", APPLY_SLOW_PCT },
{ "STUN", APPLY_STUN_PCT },
{ "STEAL_HP", APPLY_STEAL_HP },
{ "STEAL_SP", APPLY_STEAL_SP },
{ "MANA_BURN_PCT", APPLY_MANA_BURN_PCT },
{ "CRITICAL", APPLY_CRITICAL_PCT },
{ "PENETRATE", APPLY_PENETRATE_PCT },
{ "KILL_SP_RECOVER",APPLY_KILL_SP_RECOVER },
{ "KILL_HP_RECOVER",APPLY_KILL_HP_RECOVER },
{ "PENETRATE_PCT", APPLY_PENETRATE_PCT },
{ "CRITICAL_PCT", APPLY_CRITICAL_PCT },
{ "POISON_PCT", APPLY_POISON_PCT },
{ "STUN_PCT", APPLY_STUN_PCT },
{ "ATT_BONUS_TO_WARRIOR", APPLY_ATTBONUS_WARRIOR },
{ "ATT_BONUS_TO_ASSASSIN", APPLY_ATTBONUS_ASSASSIN },
{ "ATT_BONUS_TO_SURA", APPLY_ATTBONUS_SURA },
{ "ATT_BONUS_TO_SHAMAN", APPLY_ATTBONUS_SHAMAN },
{ "ATT_BONUS_TO_MONSTER", APPLY_ATTBONUS_MONSTER },
{ "ATT_BONUS_TO_MOB", APPLY_ATTBONUS_MONSTER },
{ "MALL_ATTBONUS", APPLY_MALL_ATTBONUS },
{ "MALL_EXPBONUS", APPLY_MALL_EXPBONUS },
{ "MALL_DEFBONUS", APPLY_MALL_DEFBONUS },
{ "MALL_ITEMBONUS", APPLY_MALL_ITEMBONUS },
{ "MALL_GOLDBONUS", APPLY_MALL_GOLDBONUS },
{ "MAX_HP_PCT", APPLY_MAX_HP_PCT },
{ "MAX_SP_PCT", APPLY_MAX_SP_PCT },
{ "SKILL_DAMAGE_BONUS", APPLY_SKILL_DAMAGE_BONUS },
{ "NORMAL_HIT_DAMAGE_BONUS",APPLY_NORMAL_HIT_DAMAGE_BONUS },
{ "SKILL_DEFEND_BONUS", APPLY_SKILL_DEFEND_BONUS },
{ "NORMAL_HIT_DEFEND_BONUS",APPLY_NORMAL_HIT_DEFEND_BONUS },
{ "PCBANG_EXP_BONUS", APPLY_PC_BANG_EXP_BONUS },
{ "PCBANG_DROP_BONUS", APPLY_PC_BANG_DROP_BONUS },

{ "RESIST_WARRIOR", APPLY_RESIST_WARRIOR},
{ "RESIST_ASSASSIN", APPLY_RESIST_ASSASSIN},
{ "RESIST_SURA", APPLY_RESIST_SURA},
{ "RESIST_SHAMAN", APPLY_RESIST_SHAMAN},
// by mhh game/affect.h 정의되어있음. INFINITE_AFFECT_DURATION = 0x1FFFFFFF
{ "INFINITE_AFFECT_DURATION", 0x1FFFFFFF },
{ "ENERGY", APPLY_ENERGY }, // 기력
{ "COSTUME_ATTR_BONUS", APPLY_COSTUME_ATTR_BONUS }, // 기력
{ "MAGIC_ATTBONUS_PER", APPLY_MAGIC_ATTBONUS_PER },
{ "MELEE_MAGIC_ATTBONUS_PER", APPLY_MELEE_MAGIC_ATTBONUS_PER },

#ifdef ENABLE_WOLFMAN_CHARACTER
{ "BLEEDING_REDUCE",APPLY_BLEEDING_REDUCE },
{ "BLEEDING_PCT",APPLY_BLEEDING_PCT },
{ "ATT_BONUS_TO_WOLFMAN",APPLY_ATTBONUS_WOLFMAN },
{ "RESIST_WOLFMAN",APPLY_RESIST_WOLFMAN },
{ "RESIST_CLAW",APPLY_RESIST_CLAW },
#endif

#ifdef ENABLE_MAGIC_REDUCTION_SYSTEM
{ "RESIST_MAGIC_REDUCTION",APPLY_RESIST_MAGIC_REDUCTION },
#endif
#ifdef ELEMENT_NEW_BONUSES
{"ATTBONUS_ELEC", APPLY_ATTBONUS_ELEC},
{"ATTBONUS_FIRE", APPLY_ATTBONUS_FIRE},
{"ATTBONUS_ICE", APPLY_ATTBONUS_ICE},
{"ATTBONUS_WIND", APPLY_ATTBONUS_WIND},
{"ATTBONUS_EARTH", APPLY_ATTBONUS_EARTH},
{"ATTBONUS_DARK", APPLY_ATTBONUS_DARK},
#endif

{ NULL, 0 }
};
// from import_item_proto.c

long FN_get_apply_type(const char *apply_type_string)
{
TValueName *value_name;
for (value_name = c_aApplyTypeNames; value_name->c_pszName; ++value_name)
{
if (0==strcasecmp(value_name->c_pszName, apply_type_string))
return value_name->lValue;
}
return 0;
}
[/CODE]
 
[CODE title="battle.cpp"]#include "stdafx.h"
#include "utils.h"
#include "config.h"
#include "desc.h"
#include "char.h"
#include "char_manager.h"
#include "battle.h"
#include "item.h"
#include "item_manager.h"
#include "mob_manager.h"
#include "vector.h"
#include "packet.h"
#include "pvp.h"
#include "profiler.h"
#include "guild.h"
#include "affect.h"
#include "unique_item.h"
#include "lua_incl.h"
#include "arena.h"
#include "castle.h"
#include "sectree.h"
#include "ani.h"
#include "locale_service.h"
#include "../../common/service.h"

int battle_hit(LPCHARACTER ch, LPCHARACTER victim, int & iRetDam);

bool battle_distance_valid_by_xy(long x, long y, long tx, long ty)
{
long distance = DISTANCE_APPROX(x - tx, y - ty);

if (distance > 170)
return false;

return true;
}

bool battle_distance_valid(LPCHARACTER ch, LPCHARACTER victim)
{
return battle_distance_valid_by_xy(ch->GetX(), ch->GetY(), victim->GetX(), victim->GetY());
}

bool timed_event_cancel(LPCHARACTER ch)
{
if (ch->m_pkTimedEvent)
{
event_cancel(&ch->m_pkTimedEvent);
return true;
}

/* RECALL_DELAY
차후 전투로 인해 귀환부 딜레이가 취소 되어야 할 경우 주석 해제
if (ch->m_pk_RecallEvent)
{
event_cancel(&ch->m_pkRecallEvent);
return true;
}
END_OF_RECALL_DELAY */

return false;
}

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);
}

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);
}

void battle_end_ex(LPCHARACTER ch)
{
if (ch->IsPosition(POS_FIGHTING))
ch->SetPosition(POS_STANDING);
}

void battle_end(LPCHARACTER ch)
{
battle_end_ex(ch);
}

int CalcBattleDamage(int iDam, int iAttackerLev, int iVictimLev)
{
if (iDam < 3)
iDam = number(1, 5);

return iDam;
}

int CalcMagicDamageWithValue(int iDam, LPCHARACTER pkAttacker, LPCHARACTER pkVictim)
{
return CalcBattleDamage(iDam, pkAttacker->GetLevel(), pkVictim->GetLevel());
}

int CalcMagicDamage(LPCHARACTER pkAttacker, LPCHARACTER pkVictim)
{
int iDam = 0;

if (pkAttacker->IsNPC())
{
iDam = CalcMeleeDamage(pkAttacker, pkVictim, false, false);
}

iDam += pkAttacker->GetPoint(POINT_PARTY_ATTACKER_BONUS);

return CalcMagicDamageWithValue(iDam, pkAttacker, pkVictim);
}

float CalcAttackRating(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, bool bIgnoreTargetRating)
{
int iARSrc;
int iERSrc;

if (LC_IsYMIR()) // 천마
{
iARSrc = MIN(90, pkAttacker->GetPolymorphPoint(POINT_DX));
iERSrc = MIN(90, pkVictim->GetPolymorphPoint(POINT_DX));
}
else
{
int attacker_dx = pkAttacker->GetPolymorphPoint(POINT_DX);
int attacker_lv = pkAttacker->GetLevel();

int victim_dx = pkVictim->GetPolymorphPoint(POINT_DX);
int victim_lv = pkAttacker->GetLevel();

iARSrc = MIN(90, (attacker_dx * 4 + attacker_lv * 2) / 6);
iERSrc = MIN(90, (victim_dx * 4 + victim_lv * 2) / 6);
}

float fAR = ((float) iARSrc + 210.0f) / 300.0f; // fAR = 0.7 ~ 1.0

if (bIgnoreTargetRating)
return fAR;

float fER = ((float) (iERSrc * 2 + 5) / (iERSrc + 95)) * 3.0f / 10.0f;

return fAR - fER;
}

int CalcAttBonus(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, int iAtk)
{
if (!pkVictim->IsPC())
iAtk += pkAttacker->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_ATTACK_BONUS);

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_BOSS))
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_PATRON)) / 100;
else if (pkVictim->IsStone())
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_METINN) / 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;
#ifdef ELEMENT_NEW_BONUSES
else if (pkVictim->IsRaceFlag(RACE_FLAG_ELEC))
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_ELEC)) / 100;
else if (pkVictim->IsRaceFlag(RACE_FLAG_WIND))
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_WIND)) / 100;
else if (pkVictim->IsRaceFlag(RACE_FLAG_EARTH))
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_EARTH)) / 100;
else if (pkVictim->IsRaceFlag(RACE_FLAG_DARK))
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_DARK)) / 100;
#endif
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;
#ifdef ENABLE_WOLFMAN_CHARACTER
case JOB_WOLFMAN:
iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_WOLFMAN)) / 100;
break;
#endif
}
}

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;
#ifdef ENABLE_WOLFMAN_CHARACTER
case JOB_WOLFMAN:
iAtk -= (iAtk * pkVictim->GetPoint(POINT_RESIST_WOLFMAN)) / 100;
break;
#endif
}
}

#ifdef ELEMENT_TARGET
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;
}

#endif
return iAtk;
}

void Item_GetDamage(LPITEM pkItem, int* pdamMin, int* pdamMax)
{
*pdamMin = 0;
*pdamMax = 1;

if (!pkItem)
return;

switch (pkItem->GetType())
{
case ITEM_ROD:
case ITEM_PICK:
return;
}

if (pkItem->GetType() != ITEM_WEAPON)
sys_err("Item_GetDamage - !ITEM_WEAPON vnum=%d, type=%d", pkItem->GetOriginalVnum(), pkItem->GetType());

*pdamMin = pkItem->GetValue(3);
*pdamMax = pkItem->GetValue(4);
}

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:
#ifdef ENABLE_WOLFMAN_CHARACTER
case WEAPON_CLAW:
#endif
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())
{
Item_GetDamage(pWeapon, &iDamMin, &iDamMax);
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)
{
Item_GetDamage(pWeapon, &iDamMin, &iDamMax);
}
else if (pkAttacker->IsNPC())
{
iDamMin = pkAttacker->GetMobDamageMin();
iDamMax = pkAttacker->GetMobDamageMax();
}

iDam = number(iDamMin, iDamMax) * 2;
DEBUG_iDamCur = iDam;

int iAtk = 0;
iAtk = pkAttacker->GetPoint(POINT_ATT_GRADE) + iDam - (pkAttacker->GetLevel() * 2);
iAtk = (int) (iAtk * fAR);
iAtk += pkAttacker->GetLevel() * 2;

if (pWeapon)
{
iAtk += pWeapon->GetValue(5) * 2;
DEBUG_iDamBonus = pWeapon->GetValue(5) * 2;
}

iAtk += pkAttacker->GetPoint(POINT_PARTY_ATTACKER_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 CalcArrowDamage(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, LPITEM pkBow, LPITEM pkArrow, bool bIgnoreDefense)
{
if (!pkBow || pkBow->GetType() != ITEM_WEAPON || pkBow->GetSubType() != WEAPON_BOW)
return 0;
if (!pkArrow)
return 0;

int iDist = (int) (DISTANCE_SQRT(pkAttacker->GetX() - pkVictim->GetX(), pkAttacker->GetY() - pkVictim->GetY()));
int iGap = (iDist / 100) - 5 - pkAttacker->GetPoint(POINT_BOW_DISTANCE);
int iPercent = 100 - (iGap * 5);
#ifdef WJ_QUIVER_SYSTEM
if (pkArrow->GetSubType() == WEAPON_UNLIMITED_ARROW)
{
iPercent = 100;
}
#endif

if(pkArrow->GetValue(5)==1)
{
iPercent = 100;
}

if (iPercent <= 0)
return 0;
else if (iPercent > 100)
iPercent = 100;

int iDam = 0;
float fAR = CalcAttackRating(pkAttacker, pkVictim, false);
iDam = number(pkBow->GetValue(3), pkBow->GetValue(4)) * 2 + pkArrow->GetValue(3);
int iAtk;
iAtk = pkAttacker->GetPoint(POINT_ATT_GRADE) + iDam - (pkAttacker->GetLevel() * 2);
iAtk = (int) (iAtk * fAR);
iAtk += pkAttacker->GetLevel() * 2;
iAtk += pkBow->GetValue(5) * 2;
iAtk += pkAttacker->GetPoint(POINT_PARTY_ATTACKER_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 + pkAttacker->GetPoint(POINT_DEF_BONUS)) / 100);

if (pkAttacker->IsNPC())
iAtk = (int) (iAtk * pkAttacker->GetMobDamageMultiply());

iDam = MAX(0, iAtk - iDef);

int iPureDam = iDam;

iPureDam = (iPureDam * iPercent) / 100;

if (test_server)
{
pkAttacker->ChatPacket(CHAT_TYPE_INFO, "ARROW %s -> %s, DAM %d DIST %d GAP %d %% %d",
pkAttacker->GetName(),
pkVictim->GetName(),
iPureDam,
iDist, iGap, iPercent);
}

return iPureDam;
//return iDam;
}

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);
}
#ifdef ENABLE_WOLFMAN_CHARACTER
if (pkAttacker->GetPoint(POINT_BLEEDING_PCT) && !pkVictim->IsAffectFlag(AFF_BLEEDING))
{
if (number(1, 100) <= pkAttacker->GetPoint(POINT_BLEEDING_PCT))
pkVictim->AttackedByBleeding(pkAttacker);
}
#endif
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");
}

int battle_hit(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, int & iRetDam)
{
if (test_server)
sys_log(0, "battle_hit : [%s] attack to [%s] : dam :%d type :%d", pkAttacker->GetName(), pkVictim->GetName(), iRetDam);

int iDam = CalcMeleeDamage(pkAttacker, pkVictim);
if (iDam <= 0)
return (BATTLE_DAMAGE);

NormalAttackAffect(pkAttacker, pkVictim);

LPITEM pkWeapon = pkAttacker->GetWear(WEAR_WEAPON);
if (pkWeapon)
switch (pkWeapon->GetSubType())
{
case WEAPON_SWORD:
iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_SWORD)) / 100;
break;

case WEAPON_TWO_HANDED:
iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_TWOHAND)) / 100;
break;

case WEAPON_DAGGER:
iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_DAGGER)) / 100;
break;

case WEAPON_BELL:
iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_BELL)) / 100;
break;

case WEAPON_FAN:
iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_FAN)) / 100;
break;

case WEAPON_BOW:
iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_BOW)) / 100;
break;
#ifdef ENABLE_WOLFMAN_CHARACTER
case WEAPON_CLAW:
iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_CLAW)) / 100;
#if defined(ENABLE_WOLFMAN_CHARACTER) && defined(USE_ITEM_CLAW_AS_DAGGER)
iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_DAGGER)) / 100;
#endif
break;
#endif
}

float attMul = pkAttacker->GetAttMul();
float tempIDam = iDam;
iDam = attMul * tempIDam + 0.5f;
iRetDam = iDam;

if (pkVictim->Damage(pkAttacker, iDam, DAMAGE_TYPE_NORMAL))
return (BATTLE_DEAD);

return (BATTLE_DAMAGE);
}

DWORD GET_ATTACK_SPEED(LPCHARACTER ch)
{
if (NULL == ch)
return 1000;

LPITEM item = ch->GetWear(WEAR_WEAPON);
DWORD default_bonus = SPEEDHACK_LIMIT_BONUS;
DWORD riding_bonus = 0;
if (ch->IsRiding())
{
riding_bonus = 50;
}

DWORD ani_speed = ani_attack_speed(ch);
DWORD real_speed = (ani_speed * 100) / (default_bonus + ch->GetPoint(POINT_ATT_SPEED) + riding_bonus);
if (item && item->GetSubType() == WEAPON_DAGGER)
real_speed /= 2;
#ifdef ENABLE_WOLFMAN_CHARACTER
else if (item && item->GetSubType() == WEAPON_CLAW)
real_speed /= 2;
#endif

return real_speed;
}

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 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;
}

bool IS_SPEED_HACK(LPCHARACTER ch, LPCHARACTER victim, DWORD current_time)
{
if (ch->m_kAttackLog.dwVID == victim->GetVID())
{
if (current_time - ch->m_kAttackLog.dwTime < GET_ATTACK_SPEED(ch))
{
INCREASE_SPEED_HACK_COUNT(ch);

if (test_server)
{
sys_log(0, "%s attack hack! time (delta, limit)=(%u, %u) hack_count %d",
ch->GetName(),
current_time - ch->m_kAttackLog.dwTime,
GET_ATTACK_SPEED(ch),
ch->m_speed_hack_count);

ch->ChatPacket(CHAT_TYPE_INFO, "%s attack hack! time (delta, limit)=(%u, %u) hack_count %d",
ch->GetName(),
current_time - ch->m_kAttackLog.dwTime,
GET_ATTACK_SPEED(ch),
ch->m_speed_hack_count);
}

SET_ATTACK_TIME(ch, victim, current_time);
SET_ATTACKED_TIME(ch, victim, current_time);
return true;
}
}

SET_ATTACK_TIME(ch, victim, current_time);

if (victim->m_AttackedLog.dwPID == ch->GetPlayerID())
{
if (current_time - victim->m_AttackedLog.dwAttackedTime < GET_ATTACK_SPEED(ch))
{
INCREASE_SPEED_HACK_COUNT(ch);

if (test_server)
{
sys_log(0, "%s Attack Speed HACK! time (delta, limit)=(%u, %u), hack_count = %d",
ch->GetName(),
current_time - victim->m_AttackedLog.dwAttackedTime,
GET_ATTACK_SPEED(ch),
ch->m_speed_hack_count);

ch->ChatPacket(CHAT_TYPE_INFO, "Attack Speed Hack(%s), (delta, limit)=(%u, %u)",
ch->GetName(),
current_time - victim->m_AttackedLog.dwAttackedTime,
GET_ATTACK_SPEED(ch));
}

SET_ATTACKED_TIME(ch, victim, current_time);
return true;
}
}

SET_ATTACKED_TIME(ch, victim, current_time);
return false;
}


[/CODE]


[CODE title="constants.cpp"]#include "stdafx.h"
#include "char.h"
#include "../../common/service.h"
TJobInitialPoints JobInitialPoints[JOB_MAX_NUM] =
/*
{
int st, ht, dx, iq;
int max_hp, max_sp;
int hp_per_ht, sp_per_iq;
int hp_per_lv_begin, hp_per_lv_end;
int sp_per_lv_begin, sp_per_lv_end;
int max_stamina;
int stamina_per_con;
int stamina_per_lv_begin, stamina_per_lv_end;
}
*/
{
// str con dex int 초기HP 초기SP CON/HP INT/SP HP랜덤/lv MP랜덤/lv 초기stam stam/con stam/lv
{ 6, 4, 3, 3, 600, 200, 40, 20, 36, 44, 18, 22, 800, 5, 1, 3 }, // JOB_WARRIOR 16
{ 4, 3, 6, 3, 650, 200, 40, 20, 36, 44, 18, 22, 800, 5, 1, 3 }, // JOB_ASSASSIN 16
{ 5, 3, 3, 5, 650, 200, 40, 20, 36, 44, 18, 22, 800, 5, 1, 3 }, // JOB_SURA 16
{ 3, 4, 3, 6, 700, 200, 40, 20, 36, 44, 18, 22, 800, 5, 1, 3 }, // JOB_SHAMANa 16
#ifdef ENABLE_WOLFMAN_CHARACTER
{ 2, 6, 6, 2, 600, 200, 40, 20, 36, 44, 18, 22, 800, 5, 1, 3 }, // JOB_WOLFMAN 16 // TODO: 4개능력치 초기값 외에 다른 스탯 필요 (기획자한테 요청)
#endif
};

const TMobRankStat MobRankStats[MOB_RANK_MAX_NUM] =
/*
{
int iGoldPercent;
}
*/
{
{ 20, }, // MOB_RANK_PAWN,
{ 20, }, // MOB_RANK_S_PAWN,
{ 25, }, // MOB_RANK_KNIGHT,
{ 30, }, // MOB_RANK_S_KNIGHT,
{ 50, }, // MOB_RANK_BOSS,
{ 100, } // MOB_RANK_KING,
};

TBattleTypeStat BattleTypeStats[BATTLE_TYPE_MAX_NUM] =
/*
{
int AttGradeBias;
int DefGradeBias;
int MagicAttGradeBias;
int MagicDefGradeBias;
}
*/
{
{ 0, 0, 0, -10 }, // BATTLE_TYPE_MELEE,
{ 10, -20, -10, -15 }, // BATTLE_TYPE_RANGE,
{ -5, -5, 10, 10 }, // BATTLE_TYPE_MAGIC,
{ 0, 0, 0, 0 }, // BATTLE_TYPE_SPECIAL,
{ 10, -10, 0, -15 }, // BATTLE_TYPE_POWER,
{ -10, 10, -10, 0 }, // BATTLE_TYPE_TANKER,
{ 20, -20, 0, -10 }, // BATTLE_TYPE_SUPER_POWER,
{ -20, 20, -10, 0 }, // BATTLE_TYPE_SUPER_TANKER,
};

#ifdef ENABLE_GROWTH_PET_SYSTEM
DWORD * exppet_table = NULL;
//const DWORD pets = 4;
const DWORD Pet_Table[10][2] =
{
{ 55701, 34041 },
{ 55702, 34045 },
{ 55703, 34049 },
{ 55704, 34053 },
{ 55705, 34036 },
{ 55706, 34061 },
{ 55707, 34073 },
{ 55708, 34075 },
{ 55709, 34080 },
{ 55710, 34082 }
};

const DWORD Pet_Skill_Table[18][23] =
{
//Level Like Index ->> Bonus Value --> typeSkill --> CoolDown -->> Percentage
{ 78, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 12 },
{ 80, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 12 },
{ 79, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 12 },
{ 81, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 12 },
{ 95, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 12 }, //5
{ 64, 0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 10 },
{ 98, 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, 12 },//fixpet
{ 9, 0, 0, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 14, 15, 15, 16, 16, 17, 17, 17 },
{ 16, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 9, 9 },
{ 4, 1, 480, 17, 68, 153, 272, 425, 612, 833, 1088, 1377, 1700, 2057, 2448, 2873, 3332, 3825, 4352, 4913, 5508, 6137, 6800 }, //10
{ 23, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5 },
{ 24, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 6, 6 },
{ 27, 0, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11 },
{ 28, 0, 0, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7 },
{ 44, 0, 0, 5, 10, 15, 20, 25, 31, 36, 41, 46, 51, 56, 61, 67, 72, 77, 82, 87, 92, 97, 103 }, //15
{ 52, 0, 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6 },
{ 11, 1, 600, 2, 4, 6, 7, 8, 9, 11, 12, 13, 15, 16, 17, 18, 20, 21, 22, 23, 25, 26, 27 },
{ 6, 1, 480, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }


};

const DWORD Pet_SKill_TablePerc[3][20] =
{
{ 2, 5, 8, 11, 13, 16, 19, 22, 24, 27, 30, 33, 35, 38, 41, 44, 46, 49, 52, 55 },
{ 2, 5, 7, 10, 12, 15, 17, 20, 23, 25, 27, 30, 32, 35, 37, 40, 42, 45, 47, 50 },
{ 2, 5, 8, 11, 13, 16, 19, 22, 25, 27, 30, 33, 36, 38, 41, 44, 47, 50, 52, 55 }
};

DWORD exppet_table_common[120];
#endif

const DWORD * exp_table = NULL;

const DWORD exp_table_euckr[PLAYER_EXP_TABLE_MAX + 1] =
{
0, // 0

100,
150,
260,
380,
600,

1300,
3300,
5700,
8700,
12800, // 10
18000,
25000,
36000,
52000,
73000,
100000,
125000,
160000,
220000,
280000, // 20
370000,
540000,
670000,
880000,
1000000,

1237000,
1418000,
1624000,
1857000,
2122000, // 30
2421000,
2761000,
3145000,
3580000,
4073000,
4632000,
5194000,
5717000,
6264000,
6837000, // 40
7600000,
8274000,
8990000,
9753000,
10560000,
11410000,
12320000,
13270000,
14280000,
15340000, // 50
16870000,
18960000,
19980000,
21420000,
22930000,
24530000,
26200000,
27960000,
29800000,
32780000, // 60
36060000,
39670000,
43640000,
48000000,
52800000,
58080000,
63890000,
70280000,
77310000,
85040000, // 70
93540000,
102900000,
113200000,
124500000,
137000000,
150700000,
165700000,
236990000,
260650000,
286780000, // 80
315380000,
346970000,
381680000,
419770000,
461760000,
508040000,
558740000,
614640000,
676130000,
743730000, // 90
1041222000,
1145344200,
1259878620,
1385866482,
1524453130,
1676898443,
1844588288,
2029047116,
2100000000, // 99 99레벨일 때 필요경험치 (100레벨이 되기 위한)
2100000000, // 100
2100000000,
2100000000,
2100000000,
2100000000,
2100000000, // 105
2100000000,
2100000000,
2100000000,
2100000000,
2100000000, // 110
2100000000,
2100000000,
2100000000,
2100000000,
2100000000, // 115
2100000000,
2100000000,
2100000000,
2100000000,
2100000000, // 120
};

const DWORD exp_table_common[PLAYER_EXP_TABLE_MAX + 1] =
{
0, // 0
300, //500
800, //700
1500, //1000
2500,
4300,
7200,
11000,
17000,
24000,
33000, // 10
43000,
58000,
76000,
100000,
130000,
169000,
219000,
283000,
365000,
472000, // 20
610000,
705000,
813000,
937000,
1077000,
1237000,
1418000,
1624000,
1857000,
2122000, // 30
2421000,
2761000,
3145000,
3580000,
4073000,
4632000,
5194000,
5717000,
6264000,
6837000, // 40
7600000,
8274000,
8990000,
9753000,
10560000,
11410000,
12320000,
13270000,
14280000,
15340000, // 50
16870000,
18960000,
19980000,
21420000,
22930000,
24530000,
26200000,
27960000,
29800000,
32780000, // 60
36060000,
39670000,
43640000,
48000000,
52800000,
58080000,
63890000,
70280000,
77310000,
85040000, // 70
93540000,
102900000,
113200000,
124500000,
137000000,
150700000,
165700000,
236990000,
260650000,
286780000, // 80
315380000,
346970000,
381680000,
419770000,
461760000,
508040000,
558740000,
614640000,
676130000,
743730000, // 90
1041222000,
1145344200,
1259878620,
1385866482,
1524453130,
1676898443,
1844588288,
1929047116,
2000000000, // 99레벨 일 때 필요경험치 (100레벨이 되기 위한)
2020000000, // 100
2040000000,
2060000000,
2080000000,
2090000000,
2100000000, // 105
2100000000,
2100000000,
2100000000,
2100000000,
2100000000, // 110
2100000000,
2100000000,
2100000000,
2100000000,
2100000000, // 115
2100000000,
2100000000,
2100000000,
2100000000,
2100000000, // 120
2251500000,
2253000000,
2254500000,
2256000000,
2257500000, // 125
2259000000,
2260500000,
2262000000,
2263500000,
2265000000, // 130
2266500000,
2268000000,
2269500000,
2271000000,
2272500000, // 135
2274000000,
2275500000,
2277000000,
2278500000,
2280000000, // 140
2281800000,
2283600000,
2285400000,
2287200000,
2289000000, // 145
2290800000,
2292600000,
2294400000,
2296200000,
2298000000, // 150
2299800000,
2301600000,
2303400000,
2305200000,
2307000000, // 155
2308800000,
2310600000,
2312400000,
2314200000,
2316000000, // 160
2317800000,
2319600000,
2321400000,
2323200000,
2325000000, // 165
2326800000,
2328600000,
2330400000,
2332200000,
2334000000, // 170
2335800000,
2337600000,
2339400000,
2341200000,
2343000000, // 175
2344800000,
2346600000,
2348400000,
2350200000,
2352000000, // 180
2353800000,
2355600000,
2357400000,
2359200000,
2361000000, // 185
2362800000,
2364600000,
2366400000,
2368200000,
2370000000, // 190
2371800000,
2373600000,
2375400000,
2377200000,
2379000000, // 195
2380800000,
2382600000,
2384400000,
2386200000,
2388000000, // 200
2389800000,
2391600000,
2393400000,
2395200000,
2397000000, // 205
2398800000,
2400600000,
2402400000,
2404200000,
2406000000, // 210
2407800000,
2409600000,
2411400000,
2413200000,
2415000000, // 215
2416800000,
2418600000,
2420400000,
2422200000,
2424000000, // 220
2425800000,
2427600000,
2429400000,
2431200000,
2433000000, // 225
2434800000,
2436600000,
2438400000,
2440200000,
2442000000, // 230
2443800000,
2445600000,
2447400000,
2449200000,
2451000000, // 235
2452800000,
2454600000,
2456400000,
2458200000,
2460000000, // 240
2461800000,
2463600000,
2465400000,
2467200000,
2469000000, // 245
2470800000,
2472600000,
2474400000,
2478000000,
2500000000, // 250
};

#ifdef ENABLE_SUPPORT_SYSTEM
const DWORD exp_support_table[121] =
{
0,
300,
800,
1500,
2500,
4300,
7200,
11000,
17000,
24000,
33001,
43000,
58000,
76000,
100000,
130000,
169000,
219000,
283000,
365000,
472000,
610000,
705000,
813000,
937000,
1077000,
1237000,
1418000,
1624000,
1857000,
2122000,
2421000,
2761000,
3145000,
3580000,
4073000,
4632000,
5194000,
5717000,
6264000,
6837000,
7600000,
8274000,
8990000,
9753000,
10560000,
11410000,
12320000,
13270000,
14280000,
15340000,
16870000,
18960000,
19980000,
21420000,
22930000,
24530000,
26200000,
27960000,
29800000,
32780000,
36060000,
39670000,
43640000,
48000000,
52800000,
58080000,
63890000,
70280000,
77310000,
85040000,
93540000,
102900000,
113200000,
124500000,
137000000,
150700000,
165700000,
236990000,
260650000,
286780000,
315380000,
346970000,
381680000,
419770000,
461760000,
508040000,
558740000,
614640000,
676130000,
743730000,
1041222000,
1145344200,
1259878620,
1385866482,
1524453130,
1676898443,
1844588288,
2029047116,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
2147483646,
};
#endif

const DWORD exp_table_newcibn[PLAYER_EXP_TABLE_MAX + 1 ] =
{
300, // 0
800, // 1
1500,
2500,
4300,
7200,
11400,
17000,
24000,
33000,
46000, // 10
62000,
83000,
111000,
149000,
200000,
268000,
360000,
482000,
647000,
868000, // 20
996000,
1143000,
1312000,
1506000,
1729000,
1984000,
2277000,
2614000,
3000000,
3443000, // 30
3952000,
4536000,
5206000,
5975000,
6858000,
7730000,
8504000,
9307000,
10140000,
11330000, // 40
12320000,
13370000,
14490000,
15670000,
16920000,
18240000,
19630000,
21090000,
22630000,
24670000, // 50
26890000,
29310000,
31950000,
34820000,
37960000,
41370000,
45100000,
49160000,
53580000,
58400000, // 60
63660000,
69390000,
75630000,
82440000,
89860000,
97950000,
106760000,
136370000,
151800000,
168300000, // 70
250000000,
340000000,
450000000,
570000000,
690000000,
810000000,
912600000,
1004000000,
1094000000,
1182000000, // 80
1269000000,
1354000000,
1438000000,
1521000000,
1603000000,
1684000000,
1764000000,
1844000000,
1922000000,
2000000000, // 90
2000000000,
2000000000,
2000000000,
2000000000,
2000000000,
2000000000,
2000000000,
2000000000,
2000000000, // 99 99레벨일 때 필요경험치 (100레벨이 되기 위한).. 현재 CIBN이 어떻게 운영하고 있는 지 모르니 신규 테이블을 쓰지 않고 기존값 계속 연장 유지
2000000000, // 100
2000000000,
2000000000,
2000000000,
2000000000,
2000000000, // 105
2000000000,
2000000000,
2000000000,
2000000000,
2000000000, // 110
2000000000,
2000000000,
2000000000,
2000000000,
2000000000, // 115
2000000000,
2000000000,
2000000000,
2000000000,
2000000000, // 120
};

const int * aiPercentByDeltaLev = NULL;
const int * aiPercentByDeltaLevForBoss = NULL;

// 적과 나와의 레벨차이에 의한 계산에 사용되는 테이블
// MIN(MAX_EXP_DELTA_OF_LEV - 1, (적렙 + 15) - 내렙))
const int aiPercentByDeltaLevForBoss_euckr[MAX_EXP_DELTA_OF_LEV] =
{
1, // -15 0
3, // -14 1
5, // -13 2
7, // -12 3
15, // -11 4
30, // -10 5
60, // -9 6
90, // -8 7
91, // -7 8
92, // -6 9
93, // -5 10
94, // -4 11
95, // -3 12
97, // -2 13
99, // -1 14
100, // 0 15
105, // 1 16
110, // 2 17
115, // 3 18
120, // 4 19
125, // 5 20
130, // 6 21
135, // 7 22
140, // 8 23
145, // 9 24
150, // 10 25
155, // 11 26
160, // 12 27
165, // 13 28
170, // 14 29
180 // 15 30
};



const int aiPercentByDeltaLev_euckr[MAX_EXP_DELTA_OF_LEV] =
{
1, // -15 0
5, // -14 1
10, // -13 2
20, // -12 3
30, // -11 4
50, // -10 5
70, // -9 6
80, // -8 7
85, // -7 8
90, // -6 9
92, // -5 10
94, // -4 11
96, // -3 12
98, // -2 13
100, // -1 14
100, // 0 15
105, // 1 16
110, // 2 17
115, // 3 18
120, // 4 19
125, // 5 20
130, // 6 21
135, // 7 22
140, // 8 23
145, // 9 24
150, // 10 25
155, // 11 26
160, // 12 27
165, // 13 28
170, // 14 29
180, // 15 30
};

const DWORD party_exp_distribute_table[PLAYER_MAX_LEVEL_CONST + 1] =
{
0,
10, 10, 10, 10, 15, 15, 20, 25, 30, 40, // 1 - 10
50, 60, 80, 100, 120, 140, 160, 184, 210, 240, // 11 - 20
270, 300, 330, 360, 390, 420, 450, 480, 510, 550, // 21 - 30
600, 640, 700, 760, 820, 880, 940, 1000, 1100, 1180, // 31 - 40
1260, 1320, 1380, 1440, 1500, 1560, 1620, 1680, 1740, 1800, // 41 - 50
1860, 1920, 2000, 2100, 2200, 2300, 2450, 2600, 2750, 2900, // 51 - 60
3050, 3200, 3350, 3500, 3650, 3800, 3950, 4100, 4250, 4400, // 61 - 70
4600, 4800, 5000, 5200, 5400, 5600, 5800, 6000, 6200, 6400, // 71 - 80
6600, 6800, 7000, 7200, 7400, 7600, 7800, 8000, 8200, 8400, // 81 - 90
8600, 8800, 9000, 9200, 9400, 9600, 9800, 10000, 10200, 10400, // 91 - 100
10600, 10800, 11000, 11200, 11400, 11600, 11800, 12000, 12200, 12400, // 101 - 110
12600, 12800, 13000, 13200, 13400, 13600, 13800, 14000, 14200, 14400, // 111 - 120
14600, 14800, 15000, 15200, 15400, 15600, 15800, 16000, 16200, 16400, // 121 - 130
16600, 16800, 17000, 17200, 17400, 17600, 17800, 18000, 18200, 18400, // 131 - 140
18600, 18800, 19000, 19200, 19400, 19600, 19800, 20000, 20200, 20400, // 141 - 150
20600, 20800, 21000, 21200, 21400, 21600, 21800, 22000, 22200, 22400, // 151 - 160
22600, 22800, 23000, 23200, 23400, 23600, 23800, 24000, 24200, 24400, // 161 - 170
24600, 24800, 25000, 25200, 25400, 25600, 25800, 26000, 26200, 26400, // 171 - 180
26600, 26800, 27000, 27200, 27400, 27600, 27800, 28000, 28200, 28400, // 181 - 190
28600, 28800, 29000, 29200, 29400, 29600, 29800, 30000, 30200, 30400, // 191 - 200
30600, 30800, 31000, 31200, 31400, 31600, 31800, 32000, 32200, 32400, // 201 - 210
32600, 32800, 33000, 33200, 33400, 33600, 33800, 34000, 34200, 34400, // 211 - 220
34600, 34800, 35000, 35200, 35400, 35600, 35800, 36000, 36200, 36400, // 221 - 230
36600, 36800, 37000, 37200, 37400, 37600, 37800, 38000, 38200, 38400, // 231 - 240
38600, 38800, 39000, 39200, 39400, 39600, 39800, 40000, 40200, 40400, // 241 - 250
};

Coord aArroundCoords[ARROUND_COORD_MAX_NUM] =
{
{ 0, 0 },
{ 0, 50 },
{ 35, 35 },
{ 50, -0 },
{ 35, -35 },
{ 0, -50 },
{ -35, -35 },
{ -50, 0 },
{ -35, 35 },
{ 0, 100 },
{ 71, 71 },
{ 100, -0 },
{ 71, -71 },
{ 0, -100 },
{ -71, -71 },
{ -100, 0 },
{ -71, 71 },
{ 0, 150 },
{ 106, 106 },
{ 150, -0 },
{ 106, -106 },
{ 0, -150 },
{ -106, -106 },
{ -150, 0 },
{ -106, 106 },
{ 0, 200 },
{ 141, 141 },
{ 200, -0 },
{ 141, -141 },
{ 0, -200 },
{ -141, -141 },
{ -200, 0 },
{ -141, 141 },
{ 0, 250 },
{ 177, 177 },
{ 250, -0 },
{ 177, -177 },
{ 0, -250 },
{ -177, -177 },
{ -250, 0 },
{ -177, 177 },
{ 0, 300 },
{ 212, 212 },
{ 300, -0 },
{ 212, -212 },
{ 0, -300 },
{ -212, -212 },
{ -300, 0 },
{ -212, 212 },
{ 0, 350 },
{ 247, 247 },
{ 350, -0 },
{ 247, -247 },
{ 0, -350 },
{ -247, -247 },
{ -350, 0 },
{ -247, 247 },
{ 0, 400 },
{ 283, 283 },
{ 400, -0 },
{ 283, -283 },
{ 0, -400 },
{ -283, -283 },
{ -400, 0 },
{ -283, 283 },
{ 0, 450 },
{ 318, 318 },
{ 450, -0 },
{ 318, -318 },
{ 0, -450 },
{ -318, -318 },
{ -450, 0 },
{ -318, 318 },
{ 0, 500 },
{ 354, 354 },
{ 500, -0 },
{ 354, -354 },
{ 0, -500 },
{ -354, -354 },
{ -500, 0 },
{ -354, 354 },
{ 0, 550 },
{ 389, 389 },
{ 550, -0 },
{ 389, -389 },
{ 0, -550 },
{ -389, -389 },
{ -550, 0 },
{ -389, 389 },
{ 0, 600 },
{ 424, 424 },
{ 600, -0 },
{ 424, -424 },
{ 0, -600 },
{ -424, -424 },
{ -600, 0 },
{ -424, 424 },
{ 0, 650 },
{ 460, 460 },
{ 650, -0 },
{ 460, -460 },
{ 0, -650 },
{ -460, -460 },
{ -650, 0 },
{ -460, 460 },
{ 0, 700 },
{ 495, 495 },
{ 700, -0 },
{ 495, -495 },
{ 0, -700 },
{ -495, -495 },
{ -700, 0 },
{ -495, 495 },
{ 0, 750 },
{ 530, 530 },
{ 750, -0 },
{ 530, -530 },
{ 0, -750 },
{ -530, -530 },
{ -750, 0 },
{ -530, 530 },
{ 0, 800 },
{ 566, 566 },
{ 800, -0 },
{ 566, -566 },
{ 0, -800 },
{ -566, -566 },
{ -800, 0 },
{ -566, 566 },
{ 0, 850 },
{ 601, 601 },
{ 850, -0 },
{ 601, -601 },
{ 0, -850 },
{ -601, -601 },
{ -850, 0 },
{ -601, 601 },
{ 0, 900 },
{ 636, 636 },
{ 900, -0 },
{ 636, -636 },
{ 0, -900 },
{ -636, -636 },
{ -900, 0 },
{ -636, 636 },
{ 0, 950 },
{ 672, 672 },
{ 950, -0 },
{ 672, -672 },
{ 0, -950 },
{ -672, -672 },
{ -950, 0 },
{ -672, 672 },
{ 0, 1000 },
{ 707, 707 },
{ 1000, -0 },
{ 707, -707 },
{ 0, -1000 },
{ -707, -707 },
{ -1000, 0 },
{ -707, 707 },
};

const DWORD guild_exp_table[GUILD_MAX_LEVEL+1] =
{
0,
15000UL,
45000UL,
90000UL,
160000UL,
235000UL,
325000UL,
430000UL,
550000UL,
685000UL,
835000UL,
1000000UL,
1500000UL,
2100000UL,
2800000UL,
3600000UL,
4500000UL,
6500000UL,
8000000UL,
10000000UL,
42000000UL
};

// INTERNATIONAL_VERSION 길드경험치
const DWORD guild_exp_table2[GUILD_MAX_LEVEL+1] =
{
0,
6000UL,
18000UL,
36000UL,
64000UL,
94000UL,
130000UL,
172000UL,
220000UL,
274000UL,
334000UL,
400000UL,
600000UL,
840000UL,
1120000UL,
1440000UL,
1800000UL,
2600000UL,
3200000UL,
4000000UL,
16800000UL
};
// END_OF_INTERNATIONAL_VERSION 길드경험치

const int aiMobEnchantApplyIdx[MOB_ENCHANTS_MAX_NUM] =
{
APPLY_CURSE_PCT,
APPLY_SLOW_PCT,
APPLY_POISON_PCT,
APPLY_STUN_PCT,
APPLY_CRITICAL_PCT,
APPLY_PENETRATE_PCT,
#if defined(ENABLE_WOLFMAN_CHARACTER) && !defined(USE_MOB_BLEEDING_AS_POISON)
APPLY_BLEEDING_PCT,
#endif
};

const int aiMobResistsApplyIdx[MOB_RESISTS_MAX_NUM] =
{
APPLY_RESIST_SWORD,
APPLY_RESIST_TWOHAND,
APPLY_RESIST_DAGGER,
APPLY_RESIST_BELL,
APPLY_RESIST_FAN,
APPLY_RESIST_BOW,
APPLY_RESIST_FIRE,
APPLY_RESIST_ELEC,
APPLY_RESIST_MAGIC,
APPLY_RESIST_WIND,
APPLY_POISON_REDUCE,
#if defined(ENABLE_WOLFMAN_CHARACTER) && !defined(USE_MOB_CLAW_AS_DAGGER)
APPLY_RESIST_CLAW,
#endif
#if defined(ENABLE_WOLFMAN_CHARACTER) && !defined(USE_MOB_BLEEDING_AS_POISON)
APPLY_BLEEDING_REDUCE,
#endif
};

const int aiSocketPercentByQty[5][4] =
{
{ 0, 0, 0, 0 },
{ 3, 0, 0, 0 },
{ 10, 1, 0, 0 },
{ 15, 10, 1, 0 },
{ 20, 15, 10, 1 }
};

const int aiWeaponSocketQty[WEAPON_NUM_TYPES] =
{
4, // WEAPON_SWORD,
4, // WEAPON_DAGGER,
4, // WEAPON_BOW,
4, // WEAPON_TWO_HANDED,
4, // WEAPON_BELL,
4, // WEAPON_FAN,
0, // WEAPON_ARROW,
0, // WEAPON_MOUNT_SPEAR,
#ifdef ENABLE_WOLFMAN_CHARACTER
4, // WEAPON_CLAW
#endif
#ifdef WJ_QUIVER_SYSTEM
0, // WEAPON_UNLIMITED_ARROW
#endif
};

const int aiArmorSocketQty[ARMOR_NUM_TYPES] =
{
4, // ARMOR_BODY,
1, // ARMOR_HEAD,
1, // ARMOR_SHIELD,
0, // ARMOR_WRIST,
0, // ARMOR_FOOTS,
0 // ARMOR_ACCESSORY
};

TItemAttrMap g_map_itemAttr;
TItemAttrMap g_map_itemRare;

const TApplyInfo aApplyInfo[MAX_APPLY_NUM] =
/*
{
DWORD dwPointType;
}
*/
{
// Point Type
{ POINT_NONE, }, // APPLY_NONE, 0
{ POINT_MAX_HP, }, // APPLY_MAX_HP, 1
{ POINT_MAX_SP, }, // APPLY_MAX_SP, 2
{ POINT_HT, }, // APPLY_CON, 3
{ POINT_IQ, }, // APPLY_INT, 4
{ POINT_ST, }, // APPLY_STR, 5
{ POINT_DX, }, // APPLY_DEX, 6
{ POINT_ATT_SPEED, }, // APPLY_ATT_SPEED, 7
{ POINT_MOV_SPEED, }, // APPLY_MOV_SPEED, 8
{ POINT_CASTING_SPEED, }, // APPLY_CAST_SPEED, 9
{ POINT_HP_REGEN, }, // APPLY_HP_REGEN, 10
{ POINT_SP_REGEN, }, // APPLY_SP_REGEN, 11
{ POINT_POISON_PCT, }, // APPLY_POISON_PCT, 12
{ POINT_STUN_PCT, }, // APPLY_STUN_PCT, 13
{ POINT_SLOW_PCT, }, // APPLY_SLOW_PCT, 14
{ POINT_CRITICAL_PCT, }, // APPLY_CRITICAL_PCT, 15
{ POINT_PENETRATE_PCT, }, // APPLY_PENETRATE_PCT, 16
{ POINT_ATTBONUS_HUMAN, }, // APPLY_ATTBONUS_HUMAN, 17
{ POINT_ATTBONUS_ANIMAL, }, // APPLY_ATTBONUS_ANIMAL, 18
{ POINT_ATTBONUS_ORC, }, // APPLY_ATTBONUS_ORC, 19
{ POINT_ATTBONUS_MILGYO, }, // APPLY_ATTBONUS_MILGYO, 20
{ POINT_ATTBONUS_UNDEAD, }, // APPLY_ATTBONUS_UNDEAD, 21
{ POINT_ATTBONUS_DEVIL, }, // APPLY_ATTBONUS_DEVIL, 22
{ POINT_STEAL_HP, }, // APPLY_STEAL_HP, 23
{ POINT_STEAL_SP, }, // APPLY_STEAL_SP, 24
{ POINT_MANA_BURN_PCT, }, // APPLY_MANA_BURN_PCT, 25
{ POINT_DAMAGE_SP_RECOVER, }, // APPLY_DAMAGE_SP_RECOVER,26
{ POINT_BLOCK, }, // APPLY_BLOCK, 27
{ POINT_DODGE, }, // APPLY_DODGE, 28
{ POINT_RESIST_SWORD, }, // APPLY_RESIST_SWORD, 29
{ POINT_RESIST_TWOHAND, }, // APPLY_RESIST_TWOHAND, 30
{ POINT_RESIST_DAGGER, }, // APPLY_RESIST_DAGGER, 31
{ POINT_RESIST_BELL, }, // APPLY_RESIST_BELL, 32
{ POINT_RESIST_FAN, }, // APPLY_RESIST_FAN, 33
{ POINT_RESIST_BOW, }, // APPLY_RESIST_BOW, 34
{ POINT_RESIST_FIRE, }, // APPLY_RESIST_FIRE, 35
{ POINT_RESIST_ELEC, }, // APPLY_RESIST_ELEC, 36
{ POINT_RESIST_MAGIC, }, // APPLY_RESIST_MAGIC, 37
{ POINT_RESIST_WIND, }, // APPLY_RESIST_WIND, 38
{ POINT_REFLECT_MELEE, }, // APPLY_REFLECT_MELEE, 39
{ POINT_REFLECT_CURSE, }, // APPLY_REFLECT_CURSE, 40
{ POINT_POISON_REDUCE, }, // APPLY_POISON_REDUCE, 41
{ POINT_KILL_SP_RECOVER, }, // APPLY_KILL_SP_RECOVER, 42
{ POINT_EXP_DOUBLE_BONUS, }, // APPLY_EXP_DOUBLE_BONUS, 43
{ POINT_GOLD_DOUBLE_BONUS, }, // APPLY_GOLD_DOUBLE_BONUS,44
{ POINT_ITEM_DROP_BONUS, }, // APPLY_ITEM_DROP_BONUS, 45
{ POINT_POTION_BONUS, }, // APPLY_POTION_BONUS, 46
{ POINT_KILL_HP_RECOVERY, }, // APPLY_KILL_HP_RECOVER, 47
{ POINT_IMMUNE_STUN, }, // APPLY_IMMUNE_STUN, 48
{ POINT_IMMUNE_SLOW, }, // APPLY_IMMUNE_SLOW, 49
{ POINT_IMMUNE_FALL, }, // APPLY_IMMUNE_FALL, 50
{ POINT_NONE, }, // APPLY_SKILL, 51
{ POINT_BOW_DISTANCE, }, // APPLY_BOW_DISTANCE, 52
{ POINT_ATT_GRADE_BONUS, }, // APPLY_ATT_GRADE, 53
{ POINT_DEF_GRADE_BONUS, }, // APPLY_DEF_GRADE, 54
{ POINT_MAGIC_ATT_GRADE_BONUS, }, // APPLY_MAGIC_ATT_GRADE, 55
{ POINT_MAGIC_DEF_GRADE_BONUS, }, // APPLY_MAGIC_DEF_GRADE, 56
{ POINT_CURSE_PCT, }, // APPLY_CURSE_PCT, 57
{ POINT_MAX_STAMINA }, // APPLY_MAX_STAMINA 58
{ POINT_ATTBONUS_WARRIOR }, // APPLY_ATTBONUS_WARRIOR 59
{ POINT_ATTBONUS_ASSASSIN }, // APPLY_ATTBONUS_ASSASSIN 60
{ POINT_ATTBONUS_SURA }, // APPLY_ATTBONUS_SURA 61
{ POINT_ATTBONUS_SHAMAN }, // APPLY_ATTBONUS_SHAMAN 62
{ POINT_ATTBONUS_MONSTER }, // APPLY_ATTBONUS_MONSTER 63
{ POINT_ATT_BONUS }, // 64 // APPLY_MALL_ATTBONUS
{ POINT_MALL_DEFBONUS }, // 65
{ POINT_MALL_EXPBONUS }, // 66 APPLY_MALL_EXPBONUS
{ POINT_MALL_ITEMBONUS }, // 67
{ POINT_MALL_GOLDBONUS }, // 68
{ POINT_MAX_HP_PCT }, // 69
{ POINT_MAX_SP_PCT }, // 70
{ POINT_SKILL_DAMAGE_BONUS }, // 71
{ POINT_NORMAL_HIT_DAMAGE_BONUS }, // 72

// DEFEND_BONUS_ATTRIBUTES
{ POINT_SKILL_DEFEND_BONUS }, // 73
{ POINT_NORMAL_HIT_DEFEND_BONUS }, // 74
// END_OF_DEFEND_BONUS_ATTRIBUTES

// PC_BANG_ITEM_ADD
{ POINT_PC_BANG_EXP_BONUS }, // 75
{ POINT_PC_BANG_DROP_BONUS }, // 76
// END_PC_BANG_ITEM_ADD

{ POINT_NONE, }, // 77 사용시 HP 소모 APPLY_EXTRACT_HP_PCT

{ POINT_RESIST_WARRIOR, }, // 78 무사에게 저항 APPLY_RESIST_WARRIOR
{ POINT_RESIST_ASSASSIN, }, // 79 자객에게 저항 APPLY_RESIST_ASSASSIN
{ POINT_RESIST_SURA, }, // 80 수라에게 저항 APPLY_RESIST_SURA
{ POINT_RESIST_SHAMAN, }, // 81 무당에게 저항 APPLY_RESIST_SHAMAN
{ POINT_ENERGY }, // 82 기력
{ POINT_DEF_GRADE }, // 83 방어력. DEF_GRADE_BONUS는 클라에서 두배로 보여지는 의도된 버그(...)가 있다.
{ POINT_COSTUME_ATTR_BONUS }, // 84 코스튬에 붙은 속성에 대해서만 보너스를 주는 기력
{ POINT_MAGIC_ATT_BONUS_PER }, // 85 마법 공격력 +x%
{ POINT_MELEE_MAGIC_ATT_BONUS_PER }, // 86 APPLY_MELEE_MAGIC_ATTBONUS_PER
{ POINT_RESIST_ICE, }, // APPLY_RESIST_ICE, 87
{ POINT_RESIST_EARTH, }, // APPLY_RESIST_EARTH, 88
{ POINT_RESIST_DARK, }, // APPLY_RESIST_DARK, 89
{ POINT_RESIST_CRITICAL, }, // APPLY_ANTI_CRITICAL_PCT, 90
{ POINT_RESIST_PENETRATE, }, // APPLY_ANTI_PENETRATE_PCT, 91
#ifdef ENABLE_WOLFMAN_CHARACTER
{ POINT_BLEEDING_REDUCE, }, // APPLY_BLEEDING_REDUCE, 92
{ POINT_BLEEDING_PCT, }, // APPLY_BLEEDING_PCT, 93
{ POINT_ATTBONUS_WOLFMAN, }, // APPLY_ATTBONUS_WOLFMAN, 94 수인족에게 강함
{ POINT_RESIST_WOLFMAN, }, // APPLY_RESIST_WOLFMAN, 95 수인족에게 저항
{ POINT_RESIST_CLAW, }, // APPLY_RESIST_CLAW, 96 CLAW에게 저항
#else
{ POINT_NONE, }, // APPLY_BLEEDING_REDUCE, 92
{ POINT_NONE, }, // APPLY_BLEEDING_PCT, 93
{ POINT_NONE, }, // APPLY_ATTBONUS_WOLFMAN, 94 수인족에게 강함
{ POINT_NONE, }, // APPLY_RESIST_WOLFMAN, 95 수인족에게 저항
{ POINT_NONE, }, // APPLY_RESIST_CLAW, 96 CLAW에게 저항
#endif
#ifdef ENABLE_MAGIC_REDUCTION_SYSTEM
{ POINT_RESIST_MAGIC_REDUCTION, }, // APPLY_RESIST_MAGIC_REDUCTION,98
#else
{ POINT_NONE, }, // APPLY_RESIST_MAGIC_REDUCTION,98
#endif
#ifdef ELEMENT_NEW_BONUSES
{POINT_ATTBONUS_ELEC,},
{POINT_ATTBONUS_FIRE,},
{POINT_ATTBONUS_ICE,},
{POINT_ATTBONUS_WIND,},
{POINT_ATTBONUS_EARTH,},
{POINT_ATTBONUS_DARK,},
{POINT_ATTBONUS_PATRON,},
{POINT_ATTBONUS_METINN,},
#endif
};

const int aiItemMagicAttributePercentHigh[ITEM_ATTRIBUTE_MAX_LEVEL] =
{
//25, 25, 40, 8, 2,
30, 40, 20, 8, 2
};

const int aiItemMagicAttributePercentLow[ITEM_ATTRIBUTE_MAX_LEVEL] =
{
//45, 25, 20, 10, 0,
50, 40, 10, 0, 0
};

// ADD_ITEM_ATTRIBUTE
const int aiItemAttributeAddPercent[ITEM_ATTRIBUTE_MAX_NUM] =
{
100, 80, 60, 50, 30, 0, 0,
};
// END_OF_ADD_ITEM_ATTRIBUTE

const int aiExpLossPercents[PLAYER_EXP_TABLE_MAX + 1] =
{
0,
5, 5, 5, 5, 5, 5, 5, 5, 5, 4, // 1 - 10
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 11 - 20
4, 4, 4, 4, 4, 4, 4, 3, 3, 3, // 21 - 30
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 31 - 40
3, 3, 3, 3, 2, 2, 2, 2, 2, 2, // 41 - 50
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 51 - 60
2, 2, 1, 1, 1, 1, 1, 1, 1, 1, // 61 - 70
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 71 - 80
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 81 - 90
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 91 - 100
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 101 - 110
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 111 - 120
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 121 - 130
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 131 - 140
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 141 - 150
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 151 - 160
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 161 - 170
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 171 - 180
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 181 - 190
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 191 - 200
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 201 - 210
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 211 - 220
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 221 - 230
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 231 - 240
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 241 - 250
};

const int aiSkillBookCountForLevelUp[10] =
{
3, 3, 3, 3, 3, 4, 4, 5, 5, 6
};

// ADD_GRANDMASTER_SKILL
const int aiGrandMasterSkillBookCountForLevelUp[10] =
{
3, 3, 5, 5, 7, 7, 10, 10, 10, 20,
};

const int aiGrandMasterSkillBookMinCount[10] =
{
// 1, 1, 3, 5, 10, 15, 20, 30, 40, 50,
// 3, 3, 5, 5, 10, 10, 15, 15, 20, 30
1, 1, 1, 2, 2, 3, 3, 4, 5, 6
};

const int aiGrandMasterSkillBookMaxCount[10] =
{
// 6, 15, 30, 45, 60, 80, 100, 120, 160, 200,
// 6, 10, 15, 20, 30, 40, 50, 60, 70, 80
5, 7, 9, 11, 13, 15, 20, 25, 30, 35
};
// END_OF_ADD_GRANDMASTER_SKILL

const int CHN_aiPartyBonusExpPercentByMemberCount[9] =
{
0, 0, 12, 18, 26, 40, 53, 70, 100
};


// UPGRADE_PARTY_BONUS
const int KOR_aiPartyBonusExpPercentByMemberCount[9] =
{
0,
0,
30, // 66% * 2 - 100
60, // 53% * 3 - 100
75, // 44% * 4 - 100
90, // 38% * 5 - 100
105, // 34% * 6 - 100
110, // 30% * 7 - 100
140, // 30% * 8 - 100
};

const int KOR_aiUniqueItemPartyBonusExpPercentByMemberCount[9] =
{
0,
0,
15*2,
14*3,
13*4,
12*5,
11*6,
10*7,
10*8,
};
// END_OF_UPGRADE_PARTY_BONUS

const int * aiChainLightningCountBySkillLevel = NULL;

const int aiChainLightningCountBySkillLevel_euckr[SKILL_MAX_LEVEL+1] =
{
0, // 0
2, // 1
2, // 2
2, // 3
2, // 4
2, // 5
2, // 6
2, // 7
2, // 8
3, // 9
3, // 10
3, // 11
3, // 12
3, // 13
3, // 14
3, // 15
3, // 16
3, // 17
3, // 18
4, // 19
4, // 20
4, // 21
4, // 22
4, // 23
5, // 24
5, // 25
5, // 26
5, // 27
5, // 28
5, // 29
5, // 30
5, // 31
5, // 32
5, // 33
5, // 34
5, // 35
5, // 36
5, // 37
5, // 38
5, // 39
5, // 40
};

const SStoneDropInfo aStoneDrop[STONE_INFO_MAX_NUM] =
{
// mob pct {+0 +1 +2 +3 +4}
{8001, 60, {30, 30, 30, 9, 1} },
{8002, 60, {30, 30, 30, 9, 1} },
{8003, 60, {30, 30, 30, 9, 1} },
{8004, 60, {30, 30, 30, 9, 1} },
{8005, 60, {30, 30, 30, 9, 1} },
{8006, 60, {28, 29, 31, 11, 1} },
{8007, 60, {24, 29, 32, 13, 2} },
{8008, 60, {22, 28, 33, 15, 2} },
{8009, 60, {21, 27, 33, 17, 2} },
{8010, 60, {18, 26, 34, 20, 2} },
{8011, 60, {14, 26, 35, 22, 3} },
{8012, 60, {10, 26, 37, 24, 3} },
{8013, 60, {2, 26, 40, 29, 3} },
{8014, 60, {0, 26, 41, 30, 3} },
{8024, 60, {0, 26, 41, 30, 3} },
{8025, 60, {0, 26, 41, 30, 3} },
{8026, 60, {0, 26, 41, 30, 3} },
{8027, 60, {0, 26, 41, 30, 3} },
{8051, 60, {0, 26, 41, 30, 3} },
{8052, 60, {0, 26, 41, 30, 3} },
{8053, 60, {0, 26, 41, 30, 3} },
{8054, 60, {0, 26, 41, 30, 3} },
{8055, 60, {0, 26, 41, 30, 3} },
{8056, 60, {0, 26, 41, 30, 3} },
{8057, 60, {0, 26, 41, 30, 3} },
{8058, 60, {0, 26, 41, 30, 3} },
{8059, 60, {0, 26, 41, 30, 3} },
{8061, 60, {0, 26, 41, 30, 3} },
};

const char * c_apszEmpireNames[EMPIRE_MAX_NUM] =
{
"전제국",
"신수국",
"천조국",
"진노국"
};

const char * c_apszPrivNames[MAX_PRIV_NUM] =
{
"",
"아이템이 나올 확률",
"돈이 나올 확률",
"돈 대박이 나올 확률",
"경험치 배율",
};

const int aiPolymorphPowerByLevel[SKILL_MAX_LEVEL + 1] =
{
10, // 1
11, // 2
11, // 3
12, // 4
13, // 5
13, // 6
14, // 7
15, // 8
16, // 9
17, // 10
18, // 11
19, // 12
20, // 13
22, // 14
23, // 15
24, // 16
26, // 17
27, // 18
29, // 19
31, // 20
33, // 21
35, // 22
37, // 23
39, // 24
41, // 25
44, // 26
46, // 27
49, // 28
52, // 29
55, // 30
59, // 31
62, // 32
66, // 33
70, // 34
74, // 35
79, // 36
84, // 37
89, // 38
94, // 39
100, // 40
};

TGuildWarInfo KOR_aGuildWarInfo[GUILD_WAR_TYPE_MAX_NUM] =
/*
{
long lMapIndex;
int iWarPrice;
int iWinnerPotionRewardPctToWinner;
int iLoserPotionRewardPctToWinner;
int iInitialScore;
int iEndScore;
};
*/
{
{ 0, 0, 0, 0, 0, 0 },
{ 110, 0, 100, 50, 0, 100 },
{ 111, 0, 100, 50, 0, 10 },
};

//
// 악세서리 소켓용 수치들
//

// 다이아몬드로 소켓을 추가할 때 확률
const int aiAccessorySocketAddPct[ITEM_ACCESSORY_SOCKET_MAX_NUM] =
{
50, 50, 50
};

// 악세서리 수치 값의 몇%만큼의 성능을 추가하는지
const int aiAccessorySocketEffectivePct[ITEM_ACCESSORY_SOCKET_MAX_NUM + 1] =
{
0, 10, 20, 40
};

// 소켓 지속시간 24, 12, 6
const int aiAccessorySocketDegradeTime[ITEM_ACCESSORY_SOCKET_MAX_NUM + 1] =
{
0, 3600 * 24, 3600 * 12, 3600 * 6
};

// 소켓 장착 성공률
const int aiAccessorySocketPutPct[ITEM_ACCESSORY_SOCKET_MAX_NUM + 1] =
{
90, 80, 70, 0
};
// END_OF_ACCESSORY_REFINE

#include "../../common/length.h"
// from import_item_proto.c
typedef struct SValueName
{
const char * c_pszName;
long lValue;
} TValueName;

TValueName c_aApplyTypeNames[] =
{
{ "STR", APPLY_STR },
{ "DEX", APPLY_DEX },
{ "CON", APPLY_CON },
{ "INT", APPLY_INT },
{ "MAX_HP", APPLY_MAX_HP },
{ "MAX_SP", APPLY_MAX_SP },
{ "MAX_STAMINA", APPLY_MAX_STAMINA },
{ "POISON_REDUCE", APPLY_POISON_REDUCE },
{ "EXP_DOUBLE_BONUS", APPLY_EXP_DOUBLE_BONUS },
{ "GOLD_DOUBLE_BONUS", APPLY_GOLD_DOUBLE_BONUS },
{ "ITEM_DROP_BONUS", APPLY_ITEM_DROP_BONUS },
{ "HP_REGEN", APPLY_HP_REGEN },
{ "SP_REGEN", APPLY_SP_REGEN },
{ "ATTACK_SPEED", APPLY_ATT_SPEED },
{ "MOVE_SPEED", APPLY_MOV_SPEED },
{ "CAST_SPEED", APPLY_CAST_SPEED },
{ "ATT_BONUS", APPLY_ATT_GRADE_BONUS },
{ "DEF_BONUS", APPLY_DEF_GRADE_BONUS },
{ "MAGIC_ATT_GRADE",APPLY_MAGIC_ATT_GRADE },
{ "MAGIC_DEF_GRADE",APPLY_MAGIC_DEF_GRADE },
{ "SKILL", APPLY_SKILL },
{ "ATTBONUS_ANIMAL",APPLY_ATTBONUS_ANIMAL },
{ "ATTBONUS_UNDEAD",APPLY_ATTBONUS_UNDEAD },
{ "ATTBONUS_DEVIL", APPLY_ATTBONUS_DEVIL },
{ "ATTBONUS_HUMAN", APPLY_ATTBONUS_HUMAN },
{ "ADD_BOW_DISTANCE",APPLY_BOW_DISTANCE },
{ "DODGE", APPLY_DODGE },
{ "BLOCK", APPLY_BLOCK },
{ "RESIST_SWORD", APPLY_RESIST_SWORD },
{ "RESIST_TWOHAND", APPLY_RESIST_TWOHAND },
{ "RESIST_DAGGER", APPLY_RESIST_DAGGER },
{ "RESIST_BELL", APPLY_RESIST_BELL },
{ "RESIST_FAN", APPLY_RESIST_FAN },
{ "RESIST_BOW", APPLY_RESIST_BOW },
{ "RESIST_FIRE", APPLY_RESIST_FIRE },
{ "RESIST_ELEC", APPLY_RESIST_ELEC },
{ "RESIST_MAGIC", APPLY_RESIST_MAGIC },
{ "RESIST_WIND", APPLY_RESIST_WIND },
{ "REFLECT_MELEE", APPLY_REFLECT_MELEE },
{ "REFLECT_CURSE", APPLY_REFLECT_CURSE },
{ "RESIST_ICE", APPLY_RESIST_ICE },
{ "RESIST_EARTH", APPLY_RESIST_EARTH },
{ "RESIST_DARK", APPLY_RESIST_DARK },
{ "RESIST_CRITICAL", APPLY_ANTI_CRITICAL_PCT },
{ "RESIST_PENETRATE", APPLY_ANTI_PENETRATE_PCT },
{ "POISON", APPLY_POISON_PCT },
{ "SLOW", APPLY_SLOW_PCT },
{ "STUN", APPLY_STUN_PCT },
{ "STEAL_HP", APPLY_STEAL_HP },
{ "STEAL_SP", APPLY_STEAL_SP },
{ "MANA_BURN_PCT", APPLY_MANA_BURN_PCT },
{ "CRITICAL", APPLY_CRITICAL_PCT },
{ "PENETRATE", APPLY_PENETRATE_PCT },
{ "KILL_SP_RECOVER",APPLY_KILL_SP_RECOVER },
{ "KILL_HP_RECOVER",APPLY_KILL_HP_RECOVER },
{ "PENETRATE_PCT", APPLY_PENETRATE_PCT },
{ "CRITICAL_PCT", APPLY_CRITICAL_PCT },
{ "POISON_PCT", APPLY_POISON_PCT },
{ "STUN_PCT", APPLY_STUN_PCT },
{ "ATT_BONUS_TO_WARRIOR", APPLY_ATTBONUS_WARRIOR },
{ "ATT_BONUS_TO_ASSASSIN", APPLY_ATTBONUS_ASSASSIN },
{ "ATT_BONUS_TO_SURA", APPLY_ATTBONUS_SURA },
{ "ATT_BONUS_TO_SHAMAN", APPLY_ATTBONUS_SHAMAN },
{ "ATT_BONUS_TO_MONSTER", APPLY_ATTBONUS_MONSTER },
{ "ATT_BONUS_TO_MOB", APPLY_ATTBONUS_MONSTER },
{ "MALL_ATTBONUS", APPLY_MALL_ATTBONUS },
{ "MALL_EXPBONUS", APPLY_MALL_EXPBONUS },
{ "MALL_DEFBONUS", APPLY_MALL_DEFBONUS },
{ "MALL_ITEMBONUS", APPLY_MALL_ITEMBONUS },
{ "MALL_GOLDBONUS", APPLY_MALL_GOLDBONUS },
{ "MAX_HP_PCT", APPLY_MAX_HP_PCT },
{ "MAX_SP_PCT", APPLY_MAX_SP_PCT },
{ "SKILL_DAMAGE_BONUS", APPLY_SKILL_DAMAGE_BONUS },
{ "NORMAL_HIT_DAMAGE_BONUS",APPLY_NORMAL_HIT_DAMAGE_BONUS },
{ "SKILL_DEFEND_BONUS", APPLY_SKILL_DEFEND_BONUS },
{ "NORMAL_HIT_DEFEND_BONUS",APPLY_NORMAL_HIT_DEFEND_BONUS },
{ "PCBANG_EXP_BONUS", APPLY_PC_BANG_EXP_BONUS },
{ "PCBANG_DROP_BONUS", APPLY_PC_BANG_DROP_BONUS },

{ "RESIST_WARRIOR", APPLY_RESIST_WARRIOR},
{ "RESIST_ASSASSIN", APPLY_RESIST_ASSASSIN},
{ "RESIST_SURA", APPLY_RESIST_SURA},
{ "RESIST_SHAMAN", APPLY_RESIST_SHAMAN},
// by mhh game/affect.h 정의되어있음. INFINITE_AFFECT_DURATION = 0x1FFFFFFF
{ "INFINITE_AFFECT_DURATION", 0x1FFFFFFF },
{ "ENERGY", APPLY_ENERGY }, // 기력
{ "COSTUME_ATTR_BONUS", APPLY_COSTUME_ATTR_BONUS }, // 기력
{ "MAGIC_ATTBONUS_PER", APPLY_MAGIC_ATTBONUS_PER },
{ "MELEE_MAGIC_ATTBONUS_PER", APPLY_MELEE_MAGIC_ATTBONUS_PER },

#ifdef ENABLE_WOLFMAN_CHARACTER
{ "BLEEDING_REDUCE",APPLY_BLEEDING_REDUCE },
{ "BLEEDING_PCT",APPLY_BLEEDING_PCT },
{ "ATT_BONUS_TO_WOLFMAN",APPLY_ATTBONUS_WOLFMAN },
{ "RESIST_WOLFMAN",APPLY_RESIST_WOLFMAN },
{ "RESIST_CLAW",APPLY_RESIST_CLAW },
#endif

#ifdef ENABLE_MAGIC_REDUCTION_SYSTEM
{ "RESIST_MAGIC_REDUCTION",APPLY_RESIST_MAGIC_REDUCTION },
#endif
#ifdef ELEMENT_NEW_BONUSES
{"ATTBONUS_ELEC", APPLY_ATTBONUS_ELEC},
{"ATTBONUS_FIRE", APPLY_ATTBONUS_FIRE},
{"ATTBONUS_ICE", APPLY_ATTBONUS_ICE},
{"ATTBONUS_WIND", APPLY_ATTBONUS_WIND},
{"ATTBONUS_EARTH", APPLY_ATTBONUS_EARTH},
{"ATTBONUS_DARK", APPLY_ATTBONUS_DARK},
#endif

{ NULL, 0 }
};
// from import_item_proto.c

long FN_get_apply_type(const char *apply_type_string)
{
TValueName *value_name;
for (value_name = c_aApplyTypeNames; value_name->c_pszName; ++value_name)
{
if (0==strcasecmp(value_name->c_pszName, apply_type_string))
return value_name->lValue;
}
return 0;
}
[/CODE]


battle.cpp : 261 numaralı satırda parantez eksik POINT_ATTBONUS_METINN'den sonra bir parantez daha ekle
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst