On char_skill.cpp search for:
bool CHARACTER::LearnSkillByBook(DWORD dwSkillVnum, BYTE bProb)
Replace the whole function with:
bool CHARACTER::LearnSkillByBook(DWORD dwSkillVnum, BYTE bProb)
{
const CSkillProto *pkSk = CSkillManager::instance().Get(dwSkillVnum);
if (!pkSk)
return false;
if (!IsLearnableSkill(dwSkillVnum))
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("수련할 수 없는 스킬입니다."));
return false;
}
DWORD need_exp = 0;
if (FN_should_check_exp(this))
{
need_exp = 20000;
if (GetExp() < need_exp)
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("경험치가 부족하여 책을 읽을 수 없습니다."));
return false;
}
}
if (pkSk->dwType != 0)
{
if (GetSkillMasterType(dwSkillVnum) != SKILL_MASTER)
{
if (GetSkillMasterType(dwSkillVnum) > SKILL_MASTER)
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 스킬은 책으로 더이상 수련할 수 없습니다."));
else
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 스킬은 아직 책으로 수련할 경지에 이르지 않았습니다."));
return false;
}
}
if (get_global_time() < GetSkillNextReadTime(dwSkillVnum))
{
if (!(test_server && quest::CQuestManager::instance().GetEventFlag("no_read_delay")))
{
if (FindAffect(AFFECT_SKILL_NO_BOOK_DELAY))
{
RemoveAffect(AFFECT_SKILL_NO_BOOK_DELAY);
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("주안술서를 통해 주화입마에서 빠져나왔습니다."));
}
else
{
SkillLearnWaitMoreTimeMessage(static_cast<DWORD>(GetSkillNextReadTime(dwSkillVnum) - get_global_time()));
return false;
}
}
}
BYTE bLastLevel = GetSkillLevel(dwSkillVnum);
if (bProb != 0)
{
if (FindAffect(AFFECT_SKILL_BOOK_BONUS))
{
bProb += bProb / 2;
RemoveAffect(AFFECT_SKILL_BOOK_BONUS);
}
sys_log(0, "LearnSkillByBook Pct %u prob %d", dwSkillVnum, bProb);
if (number(1, 100) <= bProb)
{
if (test_server)
sys_log(0, "LearnSkillByBook %u SUCC", dwSkillVnum);
SkillLevelUp(dwSkillVnum, SKILL_UP_BY_BOOK);
}
else
{
if (test_server)
sys_log(0, "LearnSkillByBook %u FAIL", dwSkillVnum);
}
}
else
{
int idx = MIN(9, GetSkillLevel(dwSkillVnum) - 20);
sys_log(0, "LearnSkillByBook %s table idx %d value %d", GetName(), idx, aiSkillBookCountForLevelUp[idx]);
{
int need_bookcount = GetSkillLevel(dwSkillVnum) - 20;
PointChange(POINT_EXP, -static_cast<int>(need_exp));
quest::CQuestManager &q = quest::CQuestManager::instance();
quest::PC *pPC = q.GetPC(GetPlayerID());
if (pPC)
{
char flag[128 + 1];
memset(flag, 0, sizeof(flag));
snprintf(flag, sizeof(flag), "traning_master_skill.%u.read_count", dwSkillVnum);
int read_count = pPC->GetFlag(flag);
int percent = 65;
if (FindAffect(AFFECT_SKILL_BOOK_BONUS))
{
percent = 0;
RemoveAffect(AFFECT_SKILL_BOOK_BONUS);
}
if (number(1, 100) > percent)
{
if (read_count >= need_bookcount)
{
SkillLevelUp(dwSkillVnum, SKILL_UP_BY_BOOK);
pPC->SetFlag(flag, 0);
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("책으로 더 높은 경지의 수련을 성공적으로 끝내셨습니다."));
LogManager::instance().CharLog(this, dwSkillVnum, "READ_SUCCESS", "");
return true;
}
else
{
pPC->SetFlag(flag, read_count + 1);
switch (number(1, 3))
{
case 1:
ChatPacket(CHAT_TYPE_TALKING, LC_TEXT("어느정도 이 기술에 대해 이해가 되었지만 조금 부족한듯 한데.."));
break;
case 2:
ChatPacket(CHAT_TYPE_TALKING, LC_TEXT("드디어 끝이 보이는 건가... 이 기술은 이해하기가 너무 힘들어.."));
break;
case 3:
default:
ChatPacket(CHAT_TYPE_TALKING, LC_TEXT("열심히 하는 배움을 가지는 것만이 기술을 배울수 있는 유일한 길이다.."));
break;
}
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d 권을 더 읽어야 수련을 완료 할 수 있습니다."), need_bookcount - read_count);
return true;
}
}
}
else
{
}
}
}
if (bLastLevel != GetSkillLevel(dwSkillVnum))
{
ChatPacket(CHAT_TYPE_TALKING, LC_TEXT("몸에서 뭔가 힘이 터져 나오는 기분이야!"));
ChatPacket(CHAT_TYPE_TALKING, LC_TEXT("뜨거운 무엇이 계속 용솟음치고 있어! 이건, 이것은!"));
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("책으로 더 높은 경지의 수련을 성공적으로 끝내셨습니다."));
LogManager::instance().CharLog(this, dwSkillVnum, "READ_SUCCESS", "");
}
else
{
ChatPacket(CHAT_TYPE_TALKING, LC_TEXT("크윽, 기가 역류하고 있어! 이거 설마 주화입마인가!? 젠장!"));
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("수련이 실패로 끝났습니다. 다시 도전해주시기 바랍니다."));
LogManager::instance().CharLog(this, dwSkillVnum, "READ_FAIL", "");
}
return true;
}