void CHARACTER::SkillLevelUp(DWORD dwVnum, BYTE bMethod)
{
if (NULL == m_pSkillLevels)
return;
if (g_bSkillDisable)
return;
if (IsPolymorphed())
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("둔갑 중에는 능력을 올릴 수 없습니다."));
return;
}
if (SKILL_7_A_ANTI_TANHWAN <= dwVnum && dwVnum <= SKILL_8_D_ANTI_BYEURAK)
{
if (0 == GetSkillLevel(dwVnum))
return;
}
const CSkillProto* pkSk = CSkillManager::instance().Get(dwVnum);
if (!pkSk)
{
sys_err("There is no such skill by number (vnum %u)", dwVnum);
return;
}
if (pkSk->dwVnum >= SKILL_MAX_NUM)
{
sys_err("Skill Vnum overflow (vnum %u)", dwVnum);
return;
}
if (!IsLearnableSkill(dwVnum))
return;
// 그랜드 마스터는 퀘스트로만 수행가능
if (pkSk->dwType != 0)
{
switch (GetSkillMasterType(pkSk->dwVnum))
{
case SKILL_GRAND_MASTER:
if (bMethod != SKILL_UP_BY_QUEST)
return;
break;
case SKILL_PERFECT_MASTER:
return;
}
}
if (bMethod == SKILL_UP_BY_POINT)
{
// 마스터가 아닌 상태에서만 수련가능
if (GetSkillMasterType(pkSk->dwVnum) != SKILL_NORMAL)
return;
if (IS_SET(pkSk->dwFlag, SKILL_FLAG_DISABLE_BY_POINT_UP))
return;
}
else if (bMethod == SKILL_UP_BY_BOOK)
{
if (pkSk->dwType != 0) // 직업에 속하지 않았거나 포인트로 올릴수 없는 스킬은 처음부터 책으로 배울 수 있다.
if (GetSkillMasterType(pkSk->dwVnum) != SKILL_MASTER)
return;
}
if (GetLevel() < pkSk->bLevelLimit)
return;
if (pkSk->preSkillVnum)
if (GetSkillMasterType(pkSk->preSkillVnum) == SKILL_NORMAL &&
GetSkillLevel(pkSk->preSkillVnum) < pkSk->preSkillLevel)
return;
if (!GetSkillGroup())
return;
if (bMethod == SKILL_UP_BY_POINT)
{
int idx;
switch (pkSk->dwType)
{
case 0:
idx = POINT_SUB_SKILL;
break;
case 1:
case 2:
case 3:
case 4:
case 6:
idx = POINT_SKILL;
break;
case 5:
idx = POINT_HORSE_SKILL;
break;
default:
sys_err("Wrong skill type %d skill vnum %d", pkSk->dwType, pkSk->dwVnum);
return;
}
if (GetPoint(idx) < 1)
return;
PointChange(idx, -1);
}
int SkillPointBefore = GetSkillLevel(pkSk->dwVnum);
SetSkillLevel(pkSk->dwVnum, m_pSkillLevels[pkSk->dwVnum].bLevel + 1);
if (pkSk->dwType != 0)
{
// 갑자기 그레이드 업하는 코딩
switch (GetSkillMasterType(pkSk->dwVnum))
{
case SKILL_NORMAL:
// 번섭은 스킬 업그레이드 17~20 사이 랜덤 마스터 수련
if (GetSkillLevel(pkSk->dwVnum) >= 17)
{
if (GetQuestFlag("reset_scroll.force_to_master_skill") > 0)
{
SetSkillLevel(pkSk->dwVnum, 20);
SetQuestFlag("reset_scroll.force_to_master_skill", 0);
}
else
{
if (number(1, 21 - MIN(20, GetSkillLevel(pkSk->dwVnum))) == 1)
SetSkillLevel(pkSk->dwVnum, 20);
}
}
break;
case SKILL_MASTER:
if (GetSkillLevel(pkSk->dwVnum) >= 30)
{
if (number(1, 31 - MIN(30, GetSkillLevel(pkSk->dwVnum))) == 1)
SetSkillLevel(pkSk->dwVnum, 30);
}
break;
case SKILL_GRAND_MASTER:
if (GetSkillLevel(pkSk->dwVnum) >= 40)
{
SetSkillLevel(pkSk->dwVnum, 40);
}
break;
}
}
char szSkillUp[1024];
snprintf(szSkillUp, sizeof(szSkillUp), "SkillUp: %s %u %d %d[Before:%d] type %u",
GetName(), pkSk->dwVnum, m_pSkillLevels[pkSk->dwVnum].bMasterType, m_pSkillLevels[pkSk->dwVnum].bLevel, SkillPointBefore, pkSk->dwType);
sys_log(0, "%s", szSkillUp);
LogManager::instance().CharLog(this, pkSk->dwVnum, "SKILLUP", szSkillUp);
Save();
ComputePoints();
SkillLevelPacket();
}