bool CHARACTER::DoRefineWithScroll(LPITEM item)
{
if (!CanHandleItem(true))
{
ClearRefineMode();
return false;
}
ClearRefineMode();
//개량 시간제한 : upgrade_refine_scroll.quest 에서 개량후 5분이내에 일반 개량을
//진행할수 없음
if (quest::CQuestManager::instance().GetEventFlag("update_refine_time") != 0)
{
if (get_global_time() < quest::CQuestManager::instance().GetEventFlag("update_refine_time") + (60 * 5))
{
sys_log(0, "can't refine %d %s", GetPlayerID(), GetName());
return false;
}
}
const TRefineTable * prt = CRefineManager::instance().GetRefineRecipe(item->GetRefineSet());
if (!prt)
return false;
LPITEM pkItemScroll;
// 개량서 체크
if (m_iRefineAdditionalCell < 0)
return false;
pkItemScroll = GetInventoryItem(m_iRefineAdditionalCell);
if (!pkItemScroll)
return false;
if (!(pkItemScroll->GetType() == ITEM_USE && pkItemScroll->GetSubType() == USE_TUNING))
return false;
if (pkItemScroll->GetVnum() == item->GetVnum())
return false;
DWORD result_vnum = item->GetRefinedVnum();
DWORD result_fail_vnum = item->GetRefineFromVnum();
if (result_vnum == 0)
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("더 이상 개량할 수 없습니다."));
return false;
}
// MUSIN_SCROLL
if (pkItemScroll->GetValue(0) == MUSIN_SCROLL)
{
if (item->GetRefineLevel() >= 4)
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 개량서로 더 이상 개량할 수 없습니다."));
return false;
}
}
// END_OF_MUSIC_SCROLL
else if (pkItemScroll->GetValue(0) == MEMO_SCROLL)
{
if (item->GetRefineLevel() != pkItemScroll->GetValue(1))
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 개량서로 개량할 수 없습니다."));
return false;
}
}
else if (pkItemScroll->GetValue(0) == BDRAGON_SCROLL)
{
if (item->GetType() != ITEM_METIN || item->GetRefineLevel() != 4)
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 아이템으로 개량할 수 없습니다."));
return false;
}
}
TItemTable * pProto = ITEM_MANAGER::instance().GetTable(item->GetRefinedVnum());
if (!pProto)
{
sys_err("DoRefineWithScroll NOT GET ITEM PROTO %d", item->GetRefinedVnum());
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("이 아이템은 개량할 수 없습니다."));
return false;
}
// Check level limit in korea only
if (!g_iUseLocale)
{
for (int i = 0; i < ITEM_LIMIT_MAX_NUM; ++i)
{
long limit = pProto->aLimits[i].lValue;
switch (pProto->aLimits[i].bType)
{
case LIMIT_LEVEL:
if (GetLevel() < limit)
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("개량된 후 아이템의 레벨 제한보다 레벨이 낮습니다."));
return false;
}
break;
}
}
}
if (GetGold() < prt->cost)
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("개량을 하기 위한 돈이 부족합니다."));
return false;
}
for (int i = 0; i < prt->material_count; ++i)
{
if (CountSpecifyItem(prt->materials[i].vnum) < prt->materials[i].count)
{
if (test_server)
{
ChatPacket(CHAT_TYPE_INFO, "Find %d, count %d, require %d", prt->materials[i].vnum, CountSpecifyItem(prt->materials[i].vnum), prt->materials[i].count);
}
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("개량을 하기 위한 재료가 부족합니다."));
return false;
}
}
for (int i = 0; i < prt->material_count; ++i)
RemoveSpecifyItem(prt->materials[i].vnum, prt->materials[i].count);
int prob = number(1, 100);
int success_prob = prt->prob;
bool bDestroyWhenFail = false;
const char* szRefineType = "SCROLL";
if (pkItemScroll->GetValue(0) == HYUNIRON_CHN ||
pkItemScroll->GetValue(0) == YONGSIN_SCROLL ||
pkItemScroll->GetValue(0) == YAGONG_SCROLL) // 현철, 용신의 축복서, 야공의 비전서 처리
{
const char hyuniron_prob[9] = { 100, 75, 65, 55, 45, 40, 35, 25, 20 };
const char hyuniron_prob_euckr[9] = { 100, 75, 65, 55, 45, 40, 35, 30, 25 };
const char yagong_prob[9] = { 100, 100, 90, 80, 70, 60, 50, 30, 20 };
const char yagong_prob_euckr[9] = { 100, 100, 90, 80, 70, 60, 50, 40, 30 };
if (pkItemScroll->GetValue(0) == YONGSIN_SCROLL)
{
if (LC_IsYMIR() == true || LC_IsKorea() == true)
success_prob = hyuniron_prob_euckr[MINMAX(0, item->GetRefineLevel(), 8)];
else
success_prob = hyuniron_prob[MINMAX(0, item->GetRefineLevel(), 8)];
}
else if (pkItemScroll->GetValue(0) == YAGONG_SCROLL)
{
if (LC_IsYMIR() == true || LC_IsKorea() == true)
success_prob = yagong_prob_euckr[MINMAX(0, item->GetRefineLevel(), 8)];
else
success_prob = yagong_prob[MINMAX(0, item->GetRefineLevel(), 8)];
}
else
{
sys_err("REFINE : Unknown refine scroll item. Value0: %d", pkItemScroll->GetValue(0));
}
if (test_server)
{
ChatPacket(CHAT_TYPE_INFO, "[Only Test] Success_Prob %d, RefineLevel %d ", success_prob, item->GetRefineLevel());
}
if (pkItemScroll->GetValue(0) == HYUNIRON_CHN) // 현철은 아이템이 부서져야 한다.
bDestroyWhenFail = true;
// DETAIL_REFINE_LOG
if (pkItemScroll->GetValue(0) == HYUNIRON_CHN)
{
szRefineType = "HYUNIRON";
}
else if (pkItemScroll->GetValue(0) == YONGSIN_SCROLL)
{
szRefineType = "GOD_SCROLL";
}
else if (pkItemScroll->GetValue(0) == YAGONG_SCROLL)
{
szRefineType = "YAGONG_SCROLL";
}
// END_OF_DETAIL_REFINE_LOG
}
// DETAIL_REFINE_LOG
if (pkItemScroll->GetValue(0) == MUSIN_SCROLL) // 무신의 축복서는 100% 성공 (+4까지만)
{
success_prob = 100;
szRefineType = "MUSIN_SCROLL";
}
// END_OF_DETAIL_REFINE_LOG
else if (pkItemScroll->GetValue(0) == MEMO_SCROLL)
{
success_prob = 100;
szRefineType = "MEMO_SCROLL";
}
else if (pkItemScroll->GetValue(0) == BDRAGON_SCROLL)
{
success_prob = 80;
szRefineType = "BDRAGON_SCROLL";
}
pkItemScroll->SetCount(pkItemScroll->GetCount() - 1);
if (prob <= success_prob)
{
// 성공! 모든 아이템이 사라지고, 같은 속성의 다른 아이템 획득
LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(result_vnum, 1, 0, false);
if (pkNewItem)
{
ITEM_MANAGER::CopyAllAttrTo(item, pkNewItem);
LogManager::instance().ItemLog(this, pkNewItem, "REFINE SUCCESS", pkNewItem->GetName());
BYTE bCell = item->GetCell();
NotifyRefineSuccess(this, item, szRefineType);
DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -prt->cost);
ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (REFINE SUCCESS)");
pkNewItem->AddToCharacter(this, TItemPos(INVENTORY, bCell));
ITEM_MANAGER::instance().FlushDelayedSave(pkNewItem);
pkNewItem->AttrLog();
//PointChange(POINT_GOLD, -prt->cost);
PayRefineFee(prt->cost);
}
else
{
// 아이템 생성에 실패 -> 개량 실패로 간주
sys_err("cannot create item %u", result_vnum);
NotifyRefineFail(this, item, szRefineType);
}
}
else if (!bDestroyWhenFail && result_fail_vnum)
{
// 실패! 모든 아이템이 사라지고, 같은 속성의 낮은 등급의 아이템 획득
LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(result_fail_vnum, 1, 0, false);
if (pkNewItem)
{
ITEM_MANAGER::CopyAllAttrTo(item, pkNewItem);
LogManager::instance().ItemLog(this, pkNewItem, "REFINE FAIL", pkNewItem->GetName());
BYTE bCell = item->GetCell();
DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -prt->cost);
NotifyRefineFail(this, item, szRefineType, -1);
ITEM_MANAGER::instance().RemoveItem(item, "REMOVE (REFINE FAIL)");
pkNewItem->AddToCharacter(this, TItemPos(INVENTORY, bCell));
ITEM_MANAGER::instance().FlushDelayedSave(pkNewItem);
pkNewItem->AttrLog();
//PointChange(POINT_GOLD, -prt->cost);
PayRefineFee(prt->cost);
}
else
{
// 아이템 생성에 실패 -> 개량 실패로 간주
sys_err("cannot create item %u", result_fail_vnum);
NotifyRefineFail(this, item, szRefineType);
}
}
else
{
NotifyRefineFail(this, item, szRefineType); // 개량시 아이템 사라지지 않음
PayRefineFee(prt->cost);
}
return true;
}