242 lines
9.7 KiB
C++
242 lines
9.7 KiB
C++
#include "stdafx.h"
|
|
#include "./ItemManager_ItemFunction.h"
|
|
#include "ItemManager.h"
|
|
#include "InventorySlotContainer.h"
|
|
#include "AwakeningInfoParser.h"
|
|
#include "SlotManager.h"
|
|
|
|
#ifdef _NA_008283_20150511_NOTIFICATIONS_SYSTEM
|
|
#include "NotificationInfoParser.h"
|
|
#include "GameZone.h"
|
|
#endif // _NA_008283_20150511_NOTIFICATIONS_SYSTEM
|
|
|
|
#ifdef _NA_008124_20150313_AWAKENING_SYSTEM
|
|
|
|
RC::eITEM_RESULT
|
|
nsSlot::ItemFunctionAwakening::ChkBlockAwakening() const
|
|
{
|
|
if (root_->player_->GetBehave() == PLAYER_BEHAVE_UNEXPECTED_WAITING) {
|
|
return RC::RC_ITEM_INVALIDSTATEOFPLAYER;
|
|
}
|
|
if (root_->ValidState() == false) {
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
}
|
|
return RC::RC_ITEM_SUCCESS;
|
|
}
|
|
|
|
RC::eITEM_RESULT
|
|
nsSlot::ItemFunctionAwakening::ChkInvaild(const POSTYPE equip_item_pos,
|
|
const POSTYPE material_item_pos,
|
|
const POSTYPE additive_item_pos) const
|
|
{
|
|
if (root_->ValidPos(SI_INVENTORY, equip_item_pos) == false)
|
|
{
|
|
return RC::RC_ITEM_INVALIDPOS;
|
|
}
|
|
|
|
if (root_->ValidPos(SI_INVENTORY, material_item_pos) == false)
|
|
{
|
|
return RC::RC_ITEM_INVALIDPOS;
|
|
}
|
|
|
|
if (root_->ValidPos(SI_INVENTORY, additive_item_pos) == false)
|
|
{
|
|
return RC::RC_ITEM_INVALIDPOS;
|
|
}
|
|
|
|
return RC::RC_ITEM_SUCCESS;
|
|
}
|
|
|
|
RC::eITEM_RESULT
|
|
nsSlot::ItemFunctionAwakening::ChkSlotAwakening(const SCItemSlot& equip_item,
|
|
const SCItemSlot& material_item,
|
|
const SCItemSlot& additive_item) const
|
|
{
|
|
return AwakeningInfoParser::Instance()->ResultAwakeningCheck(equip_item, material_item, additive_item);
|
|
}
|
|
|
|
RC::eITEM_RESULT
|
|
nsSlot::ItemFunctionAwakening::DeleteMaterialAndAdditive(SCItemSlot& equip_item,
|
|
SCItemSlot& material_item,
|
|
SCItemSlot& additive_item)
|
|
{
|
|
BYTE result_awakening =
|
|
AwakeningInfoParser::Instance()->GetResultAwakening(equip_item, material_item.GetCode(), material_item.GetAwakening());
|
|
const AwakeningInfo* awakening_info =
|
|
AwakeningInfoParser::Instance()->FindData(equip_item.GetCode());
|
|
if ( awakening_info == NULL )
|
|
{
|
|
return RC::RC_EQUIPMENT_AWAKENING_INVALID_EQUIP_INFO;
|
|
}
|
|
|
|
int need_additive_number = awakening_info->additive_count;
|
|
#ifdef _NA_008536_20151030_AWAKENING_MATERIAL_AMOUNT_ADD
|
|
int need_material_number = AwakeningInfoParser::Instance()->GetAllRoundMaterialNum(equip_item.GetCode(), material_item.GetCode());
|
|
if (need_material_number == 0)
|
|
{
|
|
return RC::RC_EQUIPMENT_AWAKENING_DOES_NOT_MATCH_MATERIAL;
|
|
}
|
|
std::list<AllRoundMaterialInfo> allround_material_list = awakening_info->allround_material_info_list;
|
|
|
|
RC::eITEM_RESULT result_code = RC::RC_ITEM_SUCCESS;
|
|
result_code = AwakeningInfoParser::Instance()->IsAllroundMaterial(equip_item.GetCode(), material_item.GetCode(), need_material_number);
|
|
if (result_code != RC::RC_ITEM_SUCCESS)
|
|
{
|
|
return result_code;
|
|
}
|
|
|
|
#endif // _NA_008536_20151030_AWAKENING_MATERIAL_AMOUNT_ADD
|
|
|
|
// ÷°¡Á¦ »èÁ¦
|
|
for (int count = 0; count < need_additive_number; ++count)
|
|
{
|
|
const RC::eITEM_RESULT check_delete_additive =
|
|
root_->DeleteWastedItem(SI_INVENTORY, additive_item.GetPos());
|
|
if (RC::RC_ITEM_SUCCESS != check_delete_additive)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG, "|[%s]| Additives deletes failed(%d, %d, %d)",
|
|
__FUNCTION__, root_->player_->GetCharGuid(), additive_item.GetCode(), need_additive_number);
|
|
return check_delete_additive;
|
|
}
|
|
}
|
|
|
|
// Àç·á »èÁ¦
|
|
const POSTYPE material_pos = material_item.GetPos();
|
|
#ifdef _NA_008536_20151030_AWAKENING_MATERIAL_AMOUNT_ADD
|
|
for (int count = 0; count < need_material_number; ++count)
|
|
{
|
|
const RC::eITEM_RESULT check_delete_material = root_->Delete(SI_INVENTORY,
|
|
material_item.GetPos(), 1, ITEM_AWAKENING_DELETE_MATERIAL);
|
|
if (RC::RC_ITEM_SUCCESS != check_delete_material)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG, "|[%s]| Materials deletes failed(%d, %d)",
|
|
__FUNCTION__, root_->player_->GetCharGuid(), material_item.GetCode());
|
|
return check_delete_material;
|
|
}
|
|
|
|
MSG_CG_ITEM_DELETE_CMD CmdMsg;
|
|
CmdMsg.m_byReason = RC::RC_ITEM_DELETE_SUCCESS;
|
|
CmdMsg.m_atIndex = SI_INVENTORY;
|
|
CmdMsg.m_atPos = material_pos;
|
|
root_->player_->SendPacket(&CmdMsg, sizeof(CmdMsg));
|
|
}
|
|
#else
|
|
const RC::eITEM_RESULT check_delete_material = root_->Delete(SI_INVENTORY,
|
|
material_item.GetPos(), 1, ITEM_AWAKENING_DELETE_MATERIAL);
|
|
if (RC::RC_ITEM_SUCCESS != check_delete_material)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG, "|[%s]| Materials deletes failed(%d, %d)",
|
|
__FUNCTION__, root_->player_->GetCharGuid(), material_item.GetCode());
|
|
return check_delete_material;
|
|
}
|
|
|
|
MSG_CG_ITEM_DELETE_CMD CmdMsg;
|
|
CmdMsg.m_byReason = RC::RC_ITEM_DELETE_SUCCESS;
|
|
CmdMsg.m_atIndex = SI_INVENTORY;
|
|
CmdMsg.m_atPos = material_pos;
|
|
root_->player_->SendPacket(&CmdMsg, sizeof(CmdMsg));
|
|
#endif // _NA_008536_20151030_AWAKENING_MATERIAL_AMOUNT_ADD
|
|
|
|
return RC::RC_ITEM_SUCCESS;
|
|
}
|
|
|
|
RC::eITEM_RESULT
|
|
nsSlot::ItemFunctionAwakening::Awakening(const POSTYPE equip_item_pos,
|
|
const POSTYPE material_item_pos,
|
|
const POSTYPE additive_item_pos)
|
|
{
|
|
const RC::eITEM_RESULT check_block_awakening = ChkBlockAwakening();
|
|
if (RC::RC_ITEM_SUCCESS != check_block_awakening)
|
|
{
|
|
return check_block_awakening;
|
|
}
|
|
|
|
const RC::eITEM_RESULT check_invalid = ChkInvaild(equip_item_pos, material_item_pos, additive_item_pos);
|
|
if (RC::RC_ITEM_SUCCESS != check_invalid)
|
|
{
|
|
return check_invalid;
|
|
}
|
|
|
|
SCSlotContainer* const inventory = root_->GetItemSlotContainer(SI_INVENTORY);
|
|
if (inventory == NULL)
|
|
{
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
}
|
|
SCItemSlot& equip_item_slot = static_cast<SCItemSlot&>(inventory->GetSlot(equip_item_pos));
|
|
SCItemSlot& material_item_slot = static_cast<SCItemSlot&>(inventory->GetSlot(material_item_pos));
|
|
SCItemSlot& additive_item_slot = static_cast<SCItemSlot&>(inventory->GetSlot(additive_item_pos));
|
|
const RC::eITEM_RESULT check_slot_awakening = ChkSlotAwakening(equip_item_slot, material_item_slot, additive_item_slot);
|
|
if (check_slot_awakening != RC::RC_ITEM_SUCCESS)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG, "|[%s]| CheckFunction failed(%d)",
|
|
__FUNCTION__, root_->player_->GetCharGuid());
|
|
return check_slot_awakening;
|
|
}
|
|
|
|
const CODETYPE additive_item_code = additive_item_slot.GetCode();
|
|
const CODETYPE material_item_code = material_item_slot.GetCode();
|
|
const BYTE material_awakening = material_item_slot.GetAwakening();
|
|
const RC::eITEM_RESULT check_delete = DeleteMaterialAndAdditive(
|
|
equip_item_slot, material_item_slot, additive_item_slot);
|
|
if (check_delete != RC::RC_ITEM_SUCCESS)
|
|
{
|
|
SUNLOG(eCRITICAL_LOG, "|[%s]| DeleteMaterialAndAdditive failed(%d)",
|
|
__FUNCTION__, root_->player_->GetCharGuid());
|
|
return check_delete;
|
|
}
|
|
|
|
bool success = GetResult(equip_item_slot, material_item_code, material_awakening);
|
|
return ApplyAwakening(success, equip_item_slot, material_item_code, material_awakening, additive_item_code);
|
|
}
|
|
|
|
RC::eITEM_RESULT
|
|
nsSlot::ItemFunctionAwakening::ApplyAwakening(bool success,
|
|
SCItemSlot& equip_item_slot,
|
|
const CODETYPE material_item_code,
|
|
const BYTE material_awakening,
|
|
const CODETYPE additive_item_code)
|
|
{
|
|
BYTE prev_awakening = equip_item_slot.GetAwakening();
|
|
|
|
if (success == true)
|
|
{
|
|
BYTE result_awakening =
|
|
AwakeningInfoParser::Instance()->GetResultAwakening(equip_item_slot, material_item_code, material_awakening);
|
|
equip_item_slot.SetAwakening(result_awakening);
|
|
root_->SendItemChange(equip_item_slot);
|
|
|
|
#ifdef _NA_008283_20150511_NOTIFICATIONS_SYSTEM
|
|
if (NotificationInfoParser::Instance()->IsNotificationItem(
|
|
equip_item_slot, eNotificationAwakening) == true)
|
|
{
|
|
MSG_DG_NOTIFICATION_ITEM_SYN msg;
|
|
msg.info.SetInfo(root_->player_->GetCharName(),
|
|
(root_->player_->GetGameZonePtr() != NULL) ? root_->player_->GetGameZonePtr()->GetMapCode() : 0,
|
|
GetTickCount(), eNotificationAwakening, equip_item_slot.GetItemCode(), equip_item_slot.GetAwakening());
|
|
g_pGameServer->SendToSessionType(GAME_DBPROXY, &msg, sizeof(MSG_DG_NOTIFICATION_ITEM_SYN));
|
|
}
|
|
#endif // _NA_008283_20150511_NOTIFICATIONS_SYSTEM
|
|
}
|
|
|
|
GAMELOG->LogAwakening(success ? ITEM_AWAKENING_SUCCESS : ITEM_AWAKENING_FAILED,
|
|
root_->player_, equip_item_slot, material_item_code, material_awakening,
|
|
equip_item_slot.GetAwakening(), prev_awakening, additive_item_code);
|
|
|
|
return success ? RC::RC_EQUIPMENT_AWAKENING_SUCCESS : RC::RC_EQUIPMENT_AWAKENING_FAIL;
|
|
}
|
|
|
|
const bool
|
|
nsSlot::ItemFunctionAwakening::GetResult(const SCItemSlot& equip_item_slot,
|
|
const CODETYPE material_item_code,
|
|
const BYTE material_awakening) const
|
|
{
|
|
int succeed_ratio =
|
|
AwakeningInfoParser::Instance()->GetSuccessProbability(
|
|
equip_item_slot, material_item_code, material_awakening);
|
|
RandomManager* const random_manager = root_->player_->GetRandomManager();
|
|
int random_result = random_manager->randomizer_awakening_.Rand();
|
|
succeed_ratio += root_->player_->GetAttr().GetAwakeningProbability();
|
|
return (random_result <= succeed_ratio) ? true : false;
|
|
}
|
|
|
|
#endif // _NA_008124_20150313_AWAKENING_SYSTEM
|