1108 lines
37 KiB
C++
1108 lines
37 KiB
C++
#include "stdafx.h"
|
|
#include "./ItemManager.h"
|
|
|
|
#include <PublicMath.h>
|
|
|
|
#include "InventorySlotContainer.h"
|
|
#include "EquipmentSlotContainer.h"
|
|
#include "SlotManager.h"
|
|
|
|
#include "DropManager.h"
|
|
#include "FunctionalRestrictManager.h"
|
|
#include "AchievementManager.h"
|
|
#include "ItemExpDistributor.h"
|
|
#include "Item.h"
|
|
#include "GameParty/NewGamePartyManager.h"
|
|
|
|
#ifdef _NA_008283_20150511_NOTIFICATIONS_SYSTEM
|
|
#include "NotificationInfoParser.h"
|
|
#endif // _NA_008283_20150511_NOTIFICATIONS_SYSTEM
|
|
|
|
//
|
|
//==================================================================================================
|
|
//==================================================================================================
|
|
//==================================================================================================
|
|
// ItemManager
|
|
//
|
|
ItemManager::ItemManager()
|
|
: player_(NULL)
|
|
, slot_manager_(NULL)
|
|
, slot_containers_(NULL)
|
|
, current_special_transaction_(ItemManager::TransactionClosure::eTransType_None)
|
|
, item_switch_handle_(NULL)
|
|
{
|
|
item_update_timer_.SetTimer(3 * 1000);
|
|
}
|
|
|
|
ItemManager::~ItemManager()
|
|
{
|
|
Release();
|
|
}
|
|
|
|
|
|
VOID
|
|
ItemManager::Release()
|
|
{
|
|
// m_SerialCodeCheck.RemoveAll();
|
|
SALE_ITEM_DEQ::iterator iter;
|
|
for(iter = saled_item_list_.begin(); iter != saled_item_list_.end(); ++iter)
|
|
{
|
|
RepurchaseSlot& slot = *iter;
|
|
SAFE_DELETE(slot.m_itemSlot);
|
|
}
|
|
saled_item_list_.clear();
|
|
SAFE_DELETE(item_switch_handle_);
|
|
}
|
|
|
|
|
|
void ItemManager::Init(SlotManager* slot_manager)
|
|
{
|
|
player_ = slot_manager->player_;
|
|
slot_containers_ = slot_manager->slot_container_list_;
|
|
slot_manager_ = slot_manager;
|
|
|
|
// CHANGES: f091202.x, WOPS:5334, 可在锁定状态下清除物品的特殊处理(PK掉落)
|
|
current_special_transaction_ = TransactionClosure::eTransType_None; // ref) eLOG_ITEM
|
|
// CHANGES: f110404.2L, this object has not release routine.
|
|
new (&durability_impl_) nsSlot::DurabilityImpl(this);
|
|
new (&item_move_impl_) nsSlot::ItemMoveImpl(this);
|
|
new (&trading_impl_) nsSlot::ItemTradingImpl(this);
|
|
new (&updater_impl_) nsSlot::ItemManagerUpdateImpl(this);
|
|
serial_check_table_.clear();
|
|
|
|
expiration_item_table_.clear();
|
|
|
|
saled_item_list_.clear();
|
|
saled_item_list_.resize(MAX_REPURCHASE_ITEM_NUM, RepurchaseSlot());
|
|
}
|
|
|
|
//==================================================================================================
|
|
//== basic check routines
|
|
//==================================================================================================
|
|
|
|
bool ItemManager::IsEmpty(SLOTIDX slot_index, POSTYPE pos_in_slots)
|
|
{
|
|
ASSERT(slot_index < SI_MAX && slot_index != SI_SKILL);
|
|
return slot_manager_->IsEmpty(slot_index, pos_in_slots);
|
|
}
|
|
|
|
SCItemSlotContainer* ItemManager::GetItemSlotContainer(const SLOTIDX slot_index) const
|
|
{
|
|
const ulong kAcceptablContainers = (1 << SI_INVENTORY)
|
|
| (1 << SI_EQUIPMENT)
|
|
| (1 << SI_WAREHOUSE)
|
|
| (1 << SI_GUILDWAREHOUSE);
|
|
if (bool in_range = (((1 << slot_index) & kAcceptablContainers) != 0)) {
|
|
SCItemSlotContainer* selected_container =
|
|
static_cast<SCItemSlotContainer*>(slot_manager_->GetSlotContainer(slot_index));
|
|
// 帮会仓库容器可能没有在列表中
|
|
return selected_container;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
bool ItemManager::ValidPos(
|
|
const SLOTIDX slot_index, const POSTYPE pos_in_slots, const bool check_empty) const
|
|
{
|
|
const ulong kPreventContainers = (1 << SI_SKILL)
|
|
| (1 << SI_STYLE) // removed by _NA002217_100728_EP2_PERK_SYSTEM_
|
|
| (1 << SI_QUICK);
|
|
if (bool is_prevent = (((1 << slot_index) & kPreventContainers) != 0)) {
|
|
return false;
|
|
}
|
|
|
|
return slot_manager_->ValidPos(slot_index, pos_in_slots, check_empty);
|
|
}
|
|
|
|
bool ItemManager::ValidContainer(SLOTIDX slot_index)
|
|
{
|
|
return slot_manager_->ValidContainer(slot_index);
|
|
}
|
|
|
|
bool ItemManager::ValidState() const
|
|
{
|
|
return slot_manager_->ValidState();
|
|
}
|
|
|
|
bool ItemManager::IsRestrictFunction(eFUNCTIONALRESTRICT_TYPE type) const
|
|
{
|
|
switch (type)
|
|
{
|
|
case eFUNCTIONALRESTRICT_ENCHANT:
|
|
case eFUNCTIONALRESTRICT_RANKUP:
|
|
case eFUNCTIONALRESTRICT_ADDSOCKET:
|
|
case eFUNCTIONALRESTRICT_FILLSOCKET:
|
|
case eFUNCTIONALRESTRICT_EXTRACTSOCKET:
|
|
case eFUNCTIONALRESTRICT_COMPOSE:
|
|
case eFUNCTIONALRESTRICT_CRYSTALIZE:
|
|
case eFUNCTIONALRESTRICT_USE_EXTRASTONE:
|
|
case eFUNCTIONALRESTRICT_USE_WAREHOUSE:
|
|
//case eFUNCTIONALRESTRICT_USE_TRADE:
|
|
//case eFUNCTIONALRESTRICT_USE_VENDOR:
|
|
case eFUNCTIONALRESTRICT_REPAIR_ITEM:
|
|
case eFUNCTIONALRESTRICT_SELL_ITEM:
|
|
case eFUNCTIONALRESTRICT_BUY_ITEM:
|
|
case eFUNCTIONALRESTRICT_EXCHANGE_ITEM:
|
|
if (g_pGameServer->GetServerType() == BATTLE_SERVER)
|
|
{ // 是黑客玩家!!!!需要制剂措施!
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
return g_FunctionalRestrictMgr.IsRestrictFunction(type);
|
|
}
|
|
|
|
void ItemManager::BindGuildWarehouseContainer(
|
|
CGuildWarehouseSlotContainer* guild_warehouse_container)
|
|
{
|
|
// TODO: waverix, added acceptable slotcontainer filter
|
|
slot_manager_->BindGuildWarehouseContainer(guild_warehouse_container);
|
|
}
|
|
|
|
void ItemManager::UnbindGuildWarehouseContainer()
|
|
{
|
|
// TODO: waverix, added acceptable slotcontainer filter
|
|
slot_manager_->UnbindGuildWarehouseContainer();
|
|
}
|
|
|
|
//==================================================================================================
|
|
//== 项更新例程的根。ItemManagerUpdateImpl中的实际处理工作
|
|
//==================================================================================================
|
|
|
|
void ItemManager::Update()
|
|
{
|
|
updater_impl_._UpdateExpirationItem();
|
|
updater_impl_._UpdateEtcItem();
|
|
#ifdef _NA_008440_20150818_ADD_CHARGE_SUB_IMMEDIATELY_USE
|
|
updater_impl_.UpdateImmediatelyUseItem();
|
|
#endif // _NA_008440_20150818_ADD_CHARGE_SUB_IMMEDIATELY_USE
|
|
}
|
|
|
|
//==================================================================================================
|
|
//==================================================================================================
|
|
//==================================================================================================
|
|
#ifdef _NA_002289_20110322_EQUIPMENTS_CALCULATOR_CHANGES_FOR_IMPROVEMENT
|
|
|
|
void ItemManager::UpdateItemAttributes(bool recalced_equip_items,
|
|
bool recalced_inven_option_items)
|
|
{
|
|
if (recalced_equip_items == false && recalced_inven_option_items == false) {
|
|
assert(!"check! unexpected command");
|
|
return;
|
|
};
|
|
|
|
ns_object::ChangedValuesNotifier notifier(player_);
|
|
|
|
if (recalced_equip_items)
|
|
{
|
|
CEquipmentSlotContainer* const equip_container =
|
|
static_cast<CEquipmentSlotContainer*>(GetItemSlotContainer(SI_EQUIPMENT));
|
|
equip_container->CheckupActiveEquipItemAll();
|
|
};
|
|
|
|
if (recalced_inven_option_items) {
|
|
CInventorySlotContainer* const inventory =
|
|
static_cast<CInventorySlotContainer*>(GetItemSlotContainer(SI_INVENTORY));
|
|
inventory->UpdateAttr();
|
|
};
|
|
}
|
|
|
|
// CHANGES: f110422.2L, 刷新CEquipmentSlotContainer::设备存在_
|
|
void ItemManager::RefreshEquipItemsCache()
|
|
{
|
|
CEquipmentSlotContainer* const equip_container =
|
|
static_cast<CEquipmentSlotContainer*>(GetItemSlotContainer(SI_EQUIPMENT));
|
|
equip_container->RefreshEquipItemsCache();
|
|
}
|
|
|
|
//==================================================================================================
|
|
#else //if !defined(_NA_002289_20110322_EQUIPMENTS_CALCULATOR_CHANGES_FOR_IMPROVEMENT)
|
|
//==================================================================================================
|
|
|
|
void ItemManager::UpdateAttrInventory() // 只对Inventory进行UpdateAtter
|
|
{
|
|
CInventorySlotContainer* const inventory =
|
|
static_cast<CInventorySlotContainer*>(GetItemSlotContainer(SI_INVENTORY));
|
|
inventory->UpdateAttr();
|
|
}
|
|
|
|
void ItemManager::UpdateAttrForEquipItem()
|
|
{
|
|
DWORD maxHP = player_->GetMaxHP();
|
|
DWORD maxMP = player_->GetMaxMP();
|
|
DWORD maxSD = player_->GetMaxSD();
|
|
|
|
CEquipmentSlotContainer* const equip_container =
|
|
static_cast<CEquipmentSlotContainer*>(GetItemSlotContainer(SI_EQUIPMENT));
|
|
equip_container->CheckupActiveEquipItemAll();
|
|
|
|
if (maxHP != player_->GetMaxHP()) {
|
|
player_->NotifyChangedStatus(PlayerStatEvent::eFlag_ChangedHP);
|
|
};
|
|
if (maxMP != player_->GetMaxMP()) {
|
|
player_->NotifyChangedStatus(PlayerStatEvent::eFlag_ChangedMP);
|
|
};
|
|
if (maxSD != player_->GetMaxSD()) {
|
|
player_->NotifyChangedStatus(PlayerStatEvent::eFlag_ChangedSD);
|
|
}
|
|
}
|
|
#endif //_NA_002289_20110322_EQUIPMENTS_CALCULATOR_CHANGES_FOR_IMPROVEMENT
|
|
//==================================================================================================
|
|
|
|
RC::eITEM_RESULT
|
|
ItemManager::DropMoney( MONEY Money )
|
|
{
|
|
if( !ValidState() )
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
|
|
|
|
if( Money > player_->GetMoney() )
|
|
{
|
|
return RC::RC_ITEM_HAVENOTMONEY;
|
|
}
|
|
|
|
WzVector wvCurPos = player_->GetRandomPosInAround(2);
|
|
if( !g_DropManager.DropMoneyToField( player_->GetField(), &wvCurPos, 0, 0, Money ) )
|
|
{
|
|
return RC::RC_ITEM_ERRORDROPMONEY;
|
|
}
|
|
|
|
// player_->SetMoney( player_->GetMoney() - Money );
|
|
player_->MinusMoney( Money ); // 用SetMoney花钱的部分全部换成MinusMoney()中
|
|
|
|
return RC::RC_ITEM_SUCCESS;
|
|
}
|
|
|
|
|
|
RC::eITEM_RESULT
|
|
ItemManager::Drop( SLOTIDX atIndex, POSTYPE atPos, DWORD dwOwnerKey )
|
|
{
|
|
if( !ValidState() )
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
|
|
if( !ValidPos( atIndex, atPos ) )
|
|
return RC::RC_ITEM_INVALIDPOS;
|
|
|
|
SCSlotContainer * pAtContainer = GetItemSlotContainer( atIndex );
|
|
SCItemSlot & rSlot = (SCItemSlot &)pAtContainer->GetSlot(atPos);
|
|
|
|
// (CHANGES) protect invalid item operation
|
|
// (NOTE) 首先只检查from.
|
|
const nsSlot::ItemRuleInfo& from_item_rule_info = rSlot.GetItemRuleInfo();
|
|
if(from_item_rule_info.is_valid_item == 0)
|
|
return RC::RC_ITEM_INVALIDPOS;
|
|
// 不可掉落?
|
|
|
|
if (rSlot.IsPossessionItem() && rSlot.GetIdentifyPossession() && (!rSlot.IsDestroyItem())) {
|
|
return RC::RC_ITEM_CANNOT_DROP_ITEM;
|
|
}
|
|
if (rSlot.CanTradeSell(eITEM_TRADESELL_DROP) == false) {
|
|
return RC::RC_ITEM_CANNOT_DROP_ITEM;
|
|
}
|
|
|
|
SCItemSlot DropItemSlotOut;
|
|
if( !pAtContainer->DeleteSlot( atPos, &DropItemSlotOut ) )
|
|
return RC::RC_ITEM_CANNNOT_DROPSTATE;
|
|
|
|
#ifdef _NA_008069_20150210_ADD_SPA_SYSTEM
|
|
PlayerSpaInfo* spa_info = player_->GetPlayerSpaInfo();
|
|
spa_info->CheckAndResetSpaTicket(atPos);
|
|
#endif //_NA_008069_20150210_ADD_SPA_SYSTEM
|
|
|
|
WzVector wvCurPos = player_->GetRandomPosInAround(2);
|
|
if( !g_DropManager.DropItemToField( player_->GetField(), &wvCurPos, dwOwnerKey, 0, DropItemSlotOut, 0 ) )
|
|
{
|
|
pAtContainer->InsertSlot( atPos, DropItemSlotOut );
|
|
return RC::RC_ITEM_INVALIDPOSFORDROPITEM;
|
|
}
|
|
|
|
// 游戏日志
|
|
GAMELOG->LogItem( ITEM_DROP, player_, &DropItemSlotOut, 0, DropItemSlotOut.GetNum() );
|
|
|
|
return RC::RC_ITEM_SUCCESS;
|
|
}
|
|
|
|
|
|
RC::eITEM_RESULT
|
|
ItemManager::Pick( POSTYPE NumberOfItems, SCItemSlot & rItemSlot, INVENTORY_TOTAL_INFO * OUT pTotalInfo )
|
|
{
|
|
DURATYPE Num = rItemSlot.GetNum();
|
|
rItemSlot.SetNum(1);
|
|
RC::eITEM_RESULT rt = Obtain( rItemSlot, NumberOfItems*Num, pTotalInfo );
|
|
|
|
if( rt == RC::RC_ITEM_SUCCESS )
|
|
{
|
|
// 物品捡取日志
|
|
GAMELOG->LogItem( ITEM_PICK, player_, &rItemSlot, 0, NumberOfItems*Num );
|
|
|
|
#ifdef _NA_001990_ACSYSTEM_ADD
|
|
const BASE_ITEMINFO* const pInfo = rItemSlot.GetItemInfo();
|
|
if(pInfo->m_wACCode)
|
|
{
|
|
player_->GetACManager()->ProcessItemObtain(pInfo->m_Code, pInfo->m_wACCode,
|
|
pInfo->m_byACReferenceID, NumberOfItems*Num);
|
|
}
|
|
#endif
|
|
|
|
#ifdef _NA_008283_20150511_NOTIFICATIONS_SYSTEM
|
|
if (rItemSlot.GetSerial() == 0 &&
|
|
NotificationInfoParser::Instance()->IsNotificationItem(
|
|
rItemSlot, eNotificationDrop) == true)
|
|
{
|
|
MSG_DG_NOTIFICATION_ITEM_SYN msg;
|
|
msg.info.SetInfo(player_->GetCharName(),
|
|
(player_->GetGameZonePtr() != NULL) ? player_->GetGameZonePtr()->GetMapCode() : 0,
|
|
GetTickCount(), eNotificationDrop, rItemSlot.GetItemCode());
|
|
g_pGameServer->SendToSessionType(GAME_DBPROXY, &msg, sizeof(MSG_DG_NOTIFICATION_ITEM_SYN));
|
|
}
|
|
#endif // _NA_008283_20150511_NOTIFICATIONS_SYSTEM
|
|
}
|
|
|
|
return rt;
|
|
}
|
|
|
|
|
|
//选择了GameField中的单品。
|
|
//将物品放入库存的空余空间或临时库存中。
|
|
//重叠的项目重叠处理,发送ACK。
|
|
//不重叠的项目不同步地从DBP那里获得麦片,发送ACK.
|
|
RC::eITEM_RESULT
|
|
ItemManager::Pick( DWORD dwItemObjectKey, INVENTORY_TOTAL_INFO * OUT pTotalInfo )
|
|
{
|
|
if( !ValidState() )
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
if( !ValidContainer(SI_INVENTORY) )
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
|
|
GameField *pField = player_->GetField();
|
|
if( !pField || !pField->IsReady() )
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
|
|
// CHANGES: f100503.3L, 更改接口用法
|
|
// f110415.6L, 使用方法查找简单的更改。邻里关系的内在过程
|
|
// 对每个项目都有一个对象搜索算法.
|
|
Item* pItem = NULL;
|
|
;{
|
|
Object* object = pField->FindObject(ITEM_OBJECT, dwItemObjectKey);
|
|
if (object && object->IsEqualObjectKind(ITEM_OBJECT) &&
|
|
object->IsDeleteReserved() == false)
|
|
{
|
|
pItem = static_cast<Item*>(object);
|
|
}
|
|
};
|
|
#if SUN_CODE_BACKUP
|
|
Item* pItem = pField->SearchNeighborItem(player_->GetSectorIndex(), dwItemObjectKey);
|
|
#endif
|
|
if( !pItem)
|
|
{
|
|
return RC::RC_ITEM_NOTEXISTITEMATFIELD;
|
|
}
|
|
|
|
// 确认是否可以提供该物品
|
|
RC::eITEM_RESULT rt = CanPick( pItem );
|
|
if( rt != RC::RC_ITEM_SUCCESS )
|
|
{
|
|
return rt;
|
|
}
|
|
|
|
SCItemSlot ItemSlot = pItem->GetItemSlot();
|
|
DURATYPE num = 1;
|
|
|
|
//#ifdef _DEBUG
|
|
// 测试用
|
|
// switch( rItemSlot.GetItemInfo()->m_ChargeSubType )
|
|
// {
|
|
// case eCHARGE_SUB_FIXED_AMOUNT:
|
|
// case eCHARGE_SUB_FIXED_AMOUNT_EX:
|
|
// case eCHARGE_SUB_FIXED_QUANTITY:
|
|
// {
|
|
// // 30盒利侩
|
|
// rItemSlot.SetDateTime( 30*60 );
|
|
// }break;
|
|
// }
|
|
//#endif
|
|
|
|
rt = Pick( num, ItemSlot, pTotalInfo );
|
|
if( rt == RC::RC_ITEM_SUCCESS )
|
|
{
|
|
// 初次获得怪物的道具时,也会分配给周边队员.
|
|
if( pItem->GetFromMonsterKey() != 0 )
|
|
{
|
|
g_ItemExpDistributor.DistributeItem( pItem, player_ );
|
|
}
|
|
|
|
pField->DestroyObject( pItem );
|
|
}
|
|
return rt;
|
|
}
|
|
|
|
|
|
#ifdef _NA_002399_20110323_ITEM_ROUTING_METHOD_CHANGE
|
|
//可以代替队员的道具
|
|
RC::eITEM_RESULT
|
|
ItemManager::PickParty( DWORD dwItemObjectKey, const SERVER_COMMON_OPTION& ServerOption )
|
|
{
|
|
if( !ValidState() )
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
if( !ValidContainer(SI_INVENTORY) )
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
|
|
GameField *pField = player_->GetField();
|
|
if( !pField || !pField->IsReady() )
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
|
|
// CHANGES: f100503.3L, 更改接口用法
|
|
// f110415.6L, 使用方法查找简单的更改。邻里关系的内在过程
|
|
// 对每个项目都有一个对象搜索算法.
|
|
Item* pItem = NULL;
|
|
;{
|
|
Object* object = pField->FindObject(ITEM_OBJECT, dwItemObjectKey);
|
|
if (object && object->IsEqualObjectKind(ITEM_OBJECT) &&
|
|
object->IsDeleteReserved() == false)
|
|
{
|
|
pItem = static_cast<Item*>(object);
|
|
}
|
|
};
|
|
|
|
if( !pItem)
|
|
{
|
|
return RC::RC_ITEM_NOTEXISTITEMATFIELD;
|
|
}
|
|
|
|
// 确认是否可以提供该物品
|
|
RC::eITEM_RESULT rt = CanPick( pItem );
|
|
if( rt != RC::RC_ITEM_SUCCESS )
|
|
{
|
|
return rt;
|
|
}
|
|
|
|
//
|
|
Player* item_owner = player_;
|
|
|
|
#ifdef _NA_003033_20110831_DICECAST_ITEM_ROUTING
|
|
;{
|
|
NewGamePartyManager* party_manager = NewGamePartyManager::Instance();
|
|
DWORD item_owner_key = pItem->GetOwnerPlayerKey();
|
|
|
|
if (pItem->IsEqualObjectKind(ITEM_OBJECT))
|
|
{
|
|
// 物品的所有权在队员处时
|
|
WORD party_key = player_->GetPartyState().GetPartyKey();
|
|
if(Player* party_member = party_manager->FindMemberPlayer(party_key, item_owner_key))
|
|
{
|
|
eITEM_DISTRIBUTION_TYPE party_type = \
|
|
static_cast<eITEM_DISTRIBUTION_TYPE>(party_manager->GetDistributionType(party_key));
|
|
|
|
if( party_type != eITEM_DISTRIBUTION_DEFAULT &&
|
|
party_type != eITEM_DISTRIBUTION_DICE_AND_DEFAULT )
|
|
{
|
|
item_owner = party_member; // 可以代替队员的道具进行路由.
|
|
}
|
|
|
|
//
|
|
if( pItem->GetItemSlot().GetDiceCastType() )
|
|
{
|
|
MSG_CG_PARTY_DICECAST_RESULT_CMD msg;
|
|
{
|
|
msg.item_object_key = 0;
|
|
msg.winner_key = 0;
|
|
memset(msg.result, 0, sizeof(msg.result));
|
|
};
|
|
|
|
DWORD winner_key = party_manager->GetDiceCastDistributionMember(player_, party_key, msg.result);
|
|
Player* winner_player = party_manager->FindMemberPlayer(party_key, winner_key);
|
|
if(winner_player)
|
|
{
|
|
// 告知骰子结果
|
|
msg.item_object_key = pItem->GetObjectKey();
|
|
msg.item_code = pItem->GetItemSlot().GetItemInfo()->m_Code;
|
|
msg.winner_key = winner_key;
|
|
party_manager->SendPacketAllMember(party_key, &msg, sizeof(msg));
|
|
|
|
// 掷骰子一次的道具转换为普通道具.
|
|
pItem->GetItemSlot().SetDiceCastType(FALSE);
|
|
// 物品的所有权由骰子结果第一的玩家持有.
|
|
pItem->SetOwnerPlayerKey(winner_key);
|
|
|
|
item_owner = winner_player;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
#else
|
|
if (pItem->IsEqualObjectKind(ITEM_OBJECT) && (player_->GetObjectKey() != pItem->GetOwnerPlayerKey()))
|
|
{
|
|
WORD PartyKey = player_->GetPartyState().GetPartyKey();
|
|
if( PartyKey )
|
|
{
|
|
if(NewGamePartyManager::Instance()->GetDistributionType(PartyKey) != eITEM_DISTRIBUTION_DEFAULT)
|
|
{
|
|
Player *pMember = NewGamePartyManager::Instance()->FindMemberPlayer( PartyKey, pItem->GetOwnerPlayerKey() );
|
|
if( pMember )
|
|
{
|
|
item_owner = pMember; // 可以代替队员的道具进行调整。arycoat 2011.6.28#2946道具获得方式变更
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif //_NA_003033_20110831_DICECAST_ITEM_ROUTING
|
|
|
|
MSG_CG_ITEM_PICK_ACK msgACK;
|
|
// NOTE: f110715.1L, 复制是因为“Pick”操作有SCItemSlot修改的副作用
|
|
SCItemSlot ItemSlot = pItem->GetItemSlot();
|
|
DURATYPE num = 1;
|
|
|
|
if(item_owner == player_) {
|
|
rt = Pick(num, ItemSlot, &msgACK.m_ItemInfo);
|
|
}
|
|
else {
|
|
if( item_owner->IsDead() )
|
|
return RC::RC_ITEM_DEAD_OWNER;
|
|
|
|
GameField* pOwnerField = item_owner->GetField();
|
|
GameField* pMemberField = player_->GetField();
|
|
if ((pOwnerField == NULL) || (pMemberField == NULL) || (pOwnerField != pMemberField)) {
|
|
return RC::RC_ITEM_DEAD_OWNER;
|
|
};
|
|
//
|
|
rt = item_owner->GetItemManager()->Pick(num, ItemSlot, &msgACK.m_ItemInfo);
|
|
}
|
|
|
|
if( rt == RC::RC_ITEM_SUCCESS )
|
|
{
|
|
// 初次获得怪物的道具时,也会分配给周边队员.
|
|
if( pItem->GetFromMonsterKey() != 0 )
|
|
{
|
|
g_ItemExpDistributor.DistributeItem( pItem, item_owner );
|
|
}
|
|
|
|
pField->DestroyObject( pItem );
|
|
|
|
//
|
|
item_owner->SendPacket(&msgACK, msgACK.GetSize());
|
|
|
|
const sPOLICY_CHARACTER& rPolicyment = item_owner->Policyment;
|
|
const BOOLEAN isBrdApply = !(rPolicyment.FIELD & rPolicyment.PCC_IN_SSQ_FIELD_PLAYER);
|
|
if(isBrdApply) {
|
|
// 物品习得告知周围.
|
|
MSG_CG_ITEM_PICK_BRD msgBRD;
|
|
msgBRD.m_dwObjKey = item_owner->GetObjectKey();
|
|
msgBRD.m_ItemCode = msgACK.m_ItemInfo.m_Slot[0].m_Stream.Part.wCode;
|
|
if(ServerOption.m_bItemPickUpMsgBrd != 0) {
|
|
item_owner->SendPacketAround(&msgBRD, sizeof(msgBRD), FALSE);
|
|
}
|
|
|
|
if(ServerOption.m_bItemPickUpPartyMsgBrd != 0) {
|
|
WORD party_key = item_owner->GetPartyState().GetPartyKey();
|
|
if(party_key != 0) {
|
|
NewGamePartyManager* pPartyManager = NewGamePartyManager::Instance();
|
|
pPartyManager->SendPacketAllMember(party_key, &msgBRD, sizeof(msgBRD));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return rt;
|
|
}
|
|
#endif //_NA_002399_20110323_ITEM_ROUTING_METHOD_CHANGE
|
|
|
|
|
|
RC::eITEM_RESULT
|
|
ItemManager::CanPick( Item *pItem )
|
|
{
|
|
if(pItem->IsDeleteReserved())
|
|
return RC::RC_ITEM_NOTEXISTITEMATFIELD;
|
|
if( player_->GetGMStateInfo().m_TransOn )
|
|
return RC::RC_ITEM_CANNOT_PICKUP_OBSERVER;
|
|
|
|
// 当前客户端为7m
|
|
// 玩家和Item的距离远就捡不到.
|
|
WzVector posOfItem;
|
|
WzVector posOfPlayer;
|
|
pItem->GetPos( &posOfItem );
|
|
player_->GetPos( &posOfPlayer );
|
|
|
|
float fItemLen = Math_Vector3DLength( posOfPlayer, posOfItem );
|
|
if( DISTANCE_SPACE_GET_ITEM < fItemLen )
|
|
{
|
|
return RC::RC_ITEM_CANT_PICKABLE_BY_LENGTH;
|
|
}
|
|
|
|
// 确认所有权.
|
|
if( pItem->GetOwnerPlayerKey() )
|
|
{
|
|
WORD PartyKey = player_->GetPartyState().GetPartyKey();
|
|
if( PartyKey )
|
|
{
|
|
Player *pMember = NewGamePartyManager::Instance()->FindMemberPlayer( PartyKey, pItem->GetOwnerPlayerKey() );
|
|
|
|
// 检查物品的所有权者是否是同一队伍的原因
|
|
if( !pMember )
|
|
{
|
|
return RC::RC_ITEM_DONOT_HAVE_OWNERSHIP;
|
|
}
|
|
|
|
#ifdef _NA_002399_20110323_ITEM_ROUTING_METHOD_CHANGE
|
|
BOOL bPartyMemberCanPickItem = FALSE;
|
|
if(pItem->IsEqualObjectKind(ITEM_OBJECT))
|
|
{
|
|
// 可以代替队员的道具进行调整。arycoat 2011.6.28#2946道具获得方式变更
|
|
bPartyMemberCanPickItem = TRUE;
|
|
#if SUN_CODE_BACKUP
|
|
const BASE_ITEMINFO* ItemInfo = pItem->GetItemSlot().GetItemInfo();
|
|
if(ItemInfo)
|
|
{
|
|
const eITEMTYPE type = static_cast<eITEMTYPE>(ItemInfo->m_wType);
|
|
if (type == eITEMTYPE_QUEST ||
|
|
type == eITEMTYPE_AC ||
|
|
type == eITEMTYPE_EVENT_FIELD_PARTY_ALL_MEMBER_PICK_UP)
|
|
{
|
|
bPartyMemberCanPickItem = TRUE;
|
|
}
|
|
}
|
|
#endif //SUN_CODE_BACKUP
|
|
}
|
|
#endif //_NA_002399_20110323_ITEM_ROUTING_METHOD_CHANGE
|
|
// changed rule by _NA_0_20101206_PARTY_ITEM_DISTRIBUTE_CHANGE
|
|
//--------------------------------------------------------------------------------------
|
|
// CHANGES: f110413.2L, 解决版本控制问题
|
|
// 因为包含下面代码块的嵌套宏是模糊的.
|
|
// 海姆可由所有队员获得. - arycoat 2011.03.24
|
|
const bool result_of_money_distribute_method = !pItem->IsEqualObjectKind(MONEY_OBJECT);
|
|
#ifdef _NA_002399_20110323_ITEM_ROUTING_METHOD_CHANGE
|
|
const bool result_of_item_routing_method = (bPartyMemberCanPickItem == false);
|
|
#else
|
|
const bool result_of_item_routing_method = true;
|
|
#endif
|
|
if ((result_of_money_distribute_method) &&
|
|
(result_of_item_routing_method) &&
|
|
(NewGamePartyManager::Instance()->GetDistributionType(PartyKey) !=
|
|
eITEM_DISTRIBUTION_DEFAULT))
|
|
{
|
|
if (player_->GetObjectKey() != pItem->GetOwnerPlayerKey()) {
|
|
return RC::RC_ITEM_DONOT_HAVE_OWNERSHIP;
|
|
}
|
|
}
|
|
//--------------------------------------------------------------------------------------
|
|
}
|
|
else // if PartyKey is zero...
|
|
{
|
|
if( player_->GetObjectKey() != pItem->GetOwnerPlayerKey() )
|
|
{
|
|
return RC::RC_ITEM_DONOT_HAVE_OWNERSHIP;
|
|
}
|
|
}
|
|
}
|
|
|
|
//道具不存在捡的几率。
|
|
//如果有分开的单品,只能捡不捡.
|
|
if( pItem->GetFromMonsterKey() != 0 )
|
|
{
|
|
BOOL bItemPicUp = player_->GetFatigueManager()->GetItemPickUp();
|
|
if( bItemPicUp == 0 )
|
|
return RC::RC_ITEM_OVER_PLAYING_TIME;
|
|
}
|
|
|
|
return RC::RC_ITEM_SUCCESS;
|
|
}
|
|
|
|
|
|
RC::eITEM_RESULT ItemManager::Combine(const SLOTIDX from_slot_type,
|
|
const POSTYPE from_slot_position,
|
|
const SLOTIDX to_slot_type,
|
|
const POSTYPE to_slot_position,
|
|
DURATYPE& INOUT combine_quantity)
|
|
{
|
|
if (IsRestrictFunction(eFUNCTIONALRESTRICT_COMBINE_ITEM))
|
|
{
|
|
return RC::RC_ITEM_UNUSABLE_FUNCTION;
|
|
}
|
|
|
|
if (!ValidState())
|
|
{
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
}
|
|
|
|
if (!ValidPos(from_slot_type, from_slot_position))
|
|
{
|
|
return RC::RC_ITEM_INVALIDPOS;
|
|
}
|
|
|
|
if (!ValidPos(to_slot_type, to_slot_position))
|
|
{
|
|
return RC::RC_ITEM_INVALIDPOS;
|
|
}
|
|
|
|
// 非库存不可combine.
|
|
// 仓库尽可能的。...
|
|
if ((from_slot_type != SI_INVENTORY && from_slot_type != SI_WAREHOUSE) ||
|
|
(to_slot_type != SI_INVENTORY && to_slot_type != SI_WAREHOUSE))
|
|
{
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
}
|
|
|
|
// 各种例外处理
|
|
if (from_slot_type == to_slot_type && from_slot_position == to_slot_position)
|
|
{
|
|
return RC::RC_ITEM_INVALIDPOS;
|
|
}
|
|
|
|
SCSlotContainer* const from_item_slot_container = GetItemSlotContainer(from_slot_type);
|
|
SCSlotContainer* const to_item_slot_container = GetItemSlotContainer(to_slot_type);
|
|
|
|
SCItemSlot& from_item_slot =
|
|
static_cast<SCItemSlot&>(from_item_slot_container->GetSlot(from_slot_position));
|
|
SCItemSlot& to_item_slot =
|
|
static_cast<SCItemSlot&>(to_item_slot_container->GetSlot(to_slot_position));
|
|
|
|
if (from_item_slot.GetItemCode() != to_item_slot.GetItemCode())
|
|
{
|
|
return RC::RC_ITEM_ITEMCODENOTEQUAL;
|
|
}
|
|
|
|
if (from_item_slot.GetMaxNum() <= 1) // || (from_item_slot.GetItemInfo() && from_item_slot.GetItemInfo()->m_wType != eITEMTYPE_WASTE ) )
|
|
{
|
|
return RC::RC_ITEM_ITEMCODENOTEQUAL;
|
|
}
|
|
// NOTE: f100909.1L, 另一个项目\
|
|
//即使已标记项的项代码等于未标记项的项代码.
|
|
if (from_item_slot.GetOptionTag().value != to_item_slot.GetOptionTag().value) {
|
|
return RC::RC_ITEM_ITEMCODENOTEQUAL;
|
|
};
|
|
const WORD number_of_max_combine = from_item_slot.GetMaxNum();
|
|
if (number_of_max_combine > 0x270F)//物品叠加最大值 9999 by:十里坡剑神 2021-06-04
|
|
{
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
}
|
|
|
|
// 检查请求的数量是否实际存在.
|
|
if (combine_quantity > from_item_slot.GetNum())
|
|
{
|
|
SUNLOG(eCRITICAL_LOG,
|
|
_T("|%s |要移动的数量比实际存在的数量多。|出发槽=%d,出发槽数量=%d,移动个数=%d,角色名称=%s |"),
|
|
__FUNCTION__,
|
|
from_slot_position,
|
|
from_item_slot.GetNum(),
|
|
combine_quantity,
|
|
player_->GetCharName());
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
}
|
|
|
|
const bool is_divide_combine = (combine_quantity > 0 && combine_quantity != from_item_slot.GetNum());
|
|
const WORD number_of_combine =
|
|
(is_divide_combine ? combine_quantity : from_item_slot.GetNum()) + to_item_slot.GetNum();
|
|
|
|
// 如果把物品分割后合并的话
|
|
if (is_divide_combine)
|
|
{
|
|
DURATYPE new_combine_quantity = combine_quantity;
|
|
|
|
// 合七个数超过最大重叠个数的话。
|
|
if (number_of_combine > number_of_max_combine)
|
|
{
|
|
// 最多叠加个数.
|
|
new_combine_quantity = number_of_max_combine - to_item_slot.GetNum();
|
|
}
|
|
|
|
// 记录日志.
|
|
GAMELOG->LogItemEx(ITEM_COMBINE,
|
|
player_,
|
|
to_item_slot,
|
|
from_item_slot,
|
|
0,
|
|
new_combine_quantity);
|
|
|
|
// 更新个数.
|
|
from_item_slot_container->UpdateSlot(from_slot_position, -new_combine_quantity);
|
|
to_item_slot_container->UpdateSlot(to_slot_position, new_combine_quantity);
|
|
|
|
// 设置变更的个数.
|
|
combine_quantity = to_item_slot.GetNum();
|
|
}
|
|
// 如果不是分割的话,就用和以前一样的方式合并.
|
|
else
|
|
{
|
|
if (number_of_combine > number_of_max_combine)
|
|
{
|
|
GAMELOG->LogItemEx(ITEM_COMBINE,
|
|
player_,
|
|
to_item_slot,
|
|
from_item_slot,
|
|
0,
|
|
static_cast<BYTE>(number_of_max_combine));
|
|
|
|
// to from 俺荐 函版茄促.
|
|
from_item_slot_container->UpdateSlot(from_slot_position, number_of_combine - number_of_max_combine - from_item_slot.GetNum());
|
|
|
|
// to slot 俺荐 函版茄促.
|
|
to_item_slot_container->UpdateSlot(to_slot_position, number_of_max_combine - to_item_slot.GetNum());
|
|
}
|
|
else
|
|
{
|
|
GAMELOG->LogItemEx(ITEM_COMBINE,
|
|
player_,
|
|
to_item_slot,
|
|
from_item_slot,
|
|
0,
|
|
static_cast<BYTE>(number_of_combine));
|
|
|
|
// from slot 瘤款促.
|
|
from_item_slot_container->DeleteSlot(from_slot_position, NULL);
|
|
|
|
// to slot 俺荐 函版茄促.
|
|
to_item_slot_container->UpdateSlot(to_slot_position, number_of_combine - to_item_slot.GetNum());
|
|
}
|
|
}
|
|
|
|
return RC::RC_ITEM_SUCCESS;
|
|
}
|
|
|
|
|
|
RC::eITEM_RESULT
|
|
ItemManager::Divide( POSTYPE fromPos, POSTYPE toPos, DURATYPE fromNum, DURATYPE toNum )
|
|
{
|
|
if( IsRestrictFunction( eFUNCTIONALRESTRICT_DIVIDE_ITEM ) )
|
|
return RC::RC_ITEM_UNUSABLE_FUNCTION;
|
|
|
|
if( !ValidState() )
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
|
|
if( !ValidPos( SI_INVENTORY, fromPos ) )
|
|
return RC::RC_ITEM_INVALIDPOS;
|
|
if( !ValidPos( SI_INVENTORY, toPos, FALSE ) )
|
|
return RC::RC_ITEM_INVALIDPOS;
|
|
if( fromPos == toPos )
|
|
return RC::RC_ITEM_INVALIDPOS;
|
|
|
|
SCSlotContainer * pAtContainer = GetItemSlotContainer( SI_INVENTORY );
|
|
if( !pAtContainer->IsEmpty(toPos) )
|
|
return RC::RC_ITEM_INVALIDPOS;
|
|
|
|
SCItemSlot & rFromSlot = static_cast<SCItemSlot &>(pAtContainer->GetSlot( fromPos ));
|
|
if( fromNum == 0 || toNum == 0 ||
|
|
rFromSlot.GetNum() != (fromNum+toNum) )
|
|
return RC::RC_ITEM_INVALID_VALUE;
|
|
|
|
pAtContainer->UpdateSlot( rFromSlot.GetPos(), -toNum );
|
|
|
|
// toPos俊绰 矫府倔 惯鞭 贸府 -----------------------
|
|
SCItemSlot slot;
|
|
slot.Copy(rFromSlot);
|
|
slot.SetNum(toNum);
|
|
slot.SetSerial(TEMP_DBSERIAL_VALUE);
|
|
pAtContainer->InsertSlot( toPos, slot );
|
|
//pAtContainer->SetLock( toPos, TRUE );
|
|
//MSG_DG_ITEM_SERIAL_SYN msg;
|
|
//msg.m_dwKey = player_->GetUserKey();
|
|
//msg.m_SlotIdx = SI_INVENTORY;
|
|
//msg.m_ItemPos = toPos;
|
|
//player_->SendToGameDBPServer( &msg, sizeof(msg) );
|
|
//// --------------------------------------------------
|
|
|
|
GAMELOG->LogItemEx( ITEM_DIVIDE, player_, rFromSlot, slot, 0, fromNum );
|
|
|
|
return RC::RC_ITEM_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
RC::eITEM_RESULT
|
|
ItemManager::Delete( POSTYPE atPos )
|
|
{
|
|
if( !ValidState() )
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
|
|
if( !ValidPos( SI_INVENTORY, atPos ) )
|
|
return RC::RC_ITEM_INVALIDPOS;
|
|
|
|
SCSlotContainer * pAtContainer = GetItemSlotContainer( SI_INVENTORY );
|
|
SCItemSlot & rItemSlot = (SCItemSlot &)pAtContainer->GetSlot( atPos );
|
|
// BASE_ITEMINFO * pInfo = rItemSlot.GetItemInfo();
|
|
|
|
// (CHANGES) change to more generic code 'IsPetLocked' & 'IsRiderLocked' ...
|
|
if(rItemSlot.IsUserBlocked())
|
|
return RC::RC_ITEM_CANNOT_DESTROY_ITEM;
|
|
if( rItemSlot.GetLaxLock()->IsLock() )
|
|
return RC::RC_ITEM_CANNOT_DESTROY_ITEM;
|
|
|
|
// 昏力啊瓷牢 酒捞袍父 昏力且 荐 乐促.
|
|
if (rItemSlot.CanTradeSell(eITEM_TRADESELL_DELETE) == false) {
|
|
return RC::RC_ITEM_CANNOT_DESTROY_ITEM;
|
|
}
|
|
// 酒捞袍 昏力 肺弊
|
|
GAMELOG->LogItem( ITEM_DELETE, player_, &rItemSlot, 0, rItemSlot.GetNum() );
|
|
|
|
pAtContainer->DeleteSlot( atPos, NULL );
|
|
|
|
#ifdef _NA_008069_20150210_ADD_SPA_SYSTEM
|
|
PlayerSpaInfo* spa_info = player_->GetPlayerSpaInfo();
|
|
spa_info->CheckAndResetSpaTicket(atPos);
|
|
#endif //_NA_008069_20150210_ADD_SPA_SYSTEM
|
|
|
|
return RC::RC_ITEM_SUCCESS;
|
|
}
|
|
|
|
|
|
RC::eITEM_RESULT // ref) eLOG_ITEM
|
|
ItemManager::Delete( SLOTIDX fromIndex, POSTYPE atPos, POSTYPE num, int iLogType )
|
|
{
|
|
// 捞霖籍 : 东户内靛 荐沥 官恩!!!
|
|
if( !player_ )
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
|
|
// (BUGFIX) (091202) (WOPS:5334) 牢亥泪陛 惑怕俊辑 酒捞袍 力芭 啊瓷茄 漂荐 贸府(PK靛而)
|
|
TransactionClosure transaction(this, TransactionClosure::eTransType_PKDrop);
|
|
|
|
// (CHANGES) (091209) (WAVERIX) 昏力 啊瓷 浇吩捞 公搬己捞 焊厘登瘤 臼绰促, all version supported
|
|
#if WAVERIX_CODE_RENEWAL
|
|
|
|
if(ValidPos(fromIndex, atPos, true) == false)
|
|
return RC::RC_ITEM_INVALIDPOS;
|
|
|
|
SCSlotContainer* pAtContainer = GetItemSlotContainer(fromIndex);
|
|
const SCItemSlot& rItemSlot = static_cast<SCItemSlot&>(pAtContainer->GetSlot(atPos));
|
|
|
|
if(rItemSlot.IsContainValidItem() == false)
|
|
return RC::RC_ITEM_INVALIDPOS;
|
|
|
|
const BASE_ITEMINFO* pItemInfo = rItemSlot.GetItemInfo(); // available instance in this function
|
|
|
|
// 昏力啊瓷牢 酒捞袍父 昏力且 荐 乐促.
|
|
if (rItemSlot.CanTradeSell(eITEM_TRADESELL_DELETE) == false) {
|
|
return RC::RC_ITEM_CANNOT_DESTROY_ITEM;
|
|
}
|
|
// 俺荐父怒 乐绰瘤 眉农
|
|
DURATYPE duplicated_num = rItemSlot.GetNum();
|
|
if(duplicated_num < num) {
|
|
return RC::RC_ITEM_CANNOT_DELETE_FOR_SHORT_COUNT;
|
|
}
|
|
else if(duplicated_num == num) {
|
|
// (BUGFIX) (WAVERIX) 酒捞袍 昏力 贸府矫 秦寸 浇吩篮 檬扁拳 等促.
|
|
// 肋给等 沥焊甫 扁废窍绰 巩力 荐沥窍扁 困秦 鉴辑 焊沥
|
|
GAMELOG->LogItem(iLogType, player_, &rItemSlot, 0, num);
|
|
pAtContainer->DeleteSlot(atPos, NULL);
|
|
}
|
|
else {//duplicated_num > num
|
|
pAtContainer->UpdateSlot(atPos, -num);
|
|
GAMELOG->LogItem(iLogType, player_, &rItemSlot, 0, num);
|
|
}
|
|
|
|
return RC::RC_ITEM_SUCCESS;
|
|
|
|
#else //---------------------------------------------------------------------------
|
|
if( !ValidPos( fromIndex, atPos ) )
|
|
return RC::RC_ITEM_INVALIDPOS;
|
|
|
|
SCSlotContainer * pAtContainer = GetItemSlotContainer( fromIndex );
|
|
SCItemSlot & rItemSlot = (SCItemSlot &)pAtContainer->GetSlot( atPos );
|
|
|
|
// 昏力啊瓷牢 酒捞袍父 昏力且 荐 乐促.
|
|
if( rItemSlot.GetItemInfo()->m_wTradeSellType & eITEM_TRADESELL_DELETE )
|
|
return RC::RC_ITEM_CANNOT_DESTROY_ITEM;
|
|
|
|
// 俺荐父怒 乐绰瘤 眉农
|
|
if( rItemSlot.GetNum() < num )
|
|
return RC::RC_ITEM_CANNOT_DELETE_FOR_SHORT_COUNT;
|
|
else if( rItemSlot.GetNum() == num )
|
|
pAtContainer->DeleteSlot(atPos, NULL);
|
|
else
|
|
{
|
|
pAtContainer->UpdateSlot( rItemSlot.GetPos(), -num );
|
|
}
|
|
|
|
// 酒捞袍 昏力 肺弊
|
|
GAMELOG->LogItem( iLogType, player_, &rItemSlot, 0, num );
|
|
|
|
return RC::RC_ITEM_SUCCESS;
|
|
#endif //!WAVERIX_CODE_RENEWAL
|
|
}
|
|
|
|
// 捞巴篮 泅犁 荤侩窍瘤 臼绰 窃荐 (菊栏肺绰?)
|
|
RC::eITEM_RESULT
|
|
ItemManager::Lose( SLOTCODE ItemCode, BOOL bAllOfItem )
|
|
{
|
|
if( !ValidState() )
|
|
return RC::RC_ITEM_INVALIDSTATE;
|
|
|
|
SCSlotContainer * pInventory = GetItemSlotContainer( SI_INVENTORY );
|
|
for(POSTYPE i = 0 ; i < pInventory->GetMaxSlotNum() ; ++i )
|
|
{
|
|
if( pInventory->IsEmpty(i) ) continue;
|
|
const SCItemSlot & rSlot = static_cast<SCItemSlot&>(pInventory->GetSlot(i));
|
|
if( rSlot.GetItemCode() != ItemCode ) continue;
|
|
pInventory->DeleteSlot(i, NULL);
|
|
|
|
// 菩哦 焊晨 < 函版登菌栏骨肺 老窜 林籍贸府
|
|
//MSG_CG_ITEM_LOSE_ACK msg;
|
|
//msg.m_ItemPos = i;
|
|
//player_->SendPacket( &msg, sizeof(msg) );
|
|
|
|
if( bAllOfItem ) return RC::RC_ITEM_SUCCESS;
|
|
}
|
|
|
|
return RC::RC_ITEM_SUCCESS;
|
|
}
|
|
|
|
|
|
// 荤侩惑 林狼痢!!!
|
|
// 馆靛矫 己傍窍绰 牢磊蔼父阑 持绢具 茄促.
|
|
// 溜, 蜡瓤己 眉农甫 茄 牢磊父 持绢具 茄促.
|
|
VOID
|
|
ItemManager::Lose( SCSlotContainer * pContainer, POSTYPE pos, int num )
|
|
{
|
|
SCItemSlot & rSlotItem = (SCItemSlot &)pContainer->GetSlot(pos);
|
|
if( rSlotItem.GetNum() > num )
|
|
{
|
|
pContainer->UpdateSlot( rSlotItem.GetPos(), -num );
|
|
}
|
|
else
|
|
{
|
|
BOOL rt = pContainer->DeleteSlot( rSlotItem.GetPos(), NULL );
|
|
ASSERT( rt && "泅犁 浇吩 牧抛捞呈俊辑 昏力且 荐 绝绰 酒捞袍涝聪促.\n" );
|
|
}
|
|
}
|
|
|
|
//==================================================================================================
|
|
//==================================================================================================
|
|
//==================================================================================================
|
|
|
|
VOID
|
|
ItemManager::SendSetItemBrd( BOOL bFullOption )
|
|
{
|
|
if( !player_ ) return;
|
|
|
|
MSG_CG_ITEM_SETITEM_CHANGE_BRD Brd;
|
|
Brd.m_PlayerKey = (PLAYERKEY)player_->GetObjectKey();
|
|
Brd.m_bFull = bFullOption;
|
|
player_->SendPacketAround( &Brd, sizeof(Brd), FALSE );
|
|
}
|
|
|
|
RC::eBATTLE_GROUND_RESULT ItemManager::GetPlayerItemScore(DWORD* OUT item_score)
|
|
{
|
|
CEquipmentSlotContainer* const equip_container =
|
|
static_cast<CEquipmentSlotContainer* const>(GetItemSlotContainer(SI_EQUIPMENT));
|
|
if (equip_container == NULL) {
|
|
return RC::RC_BATTLE_GROUND_RESERVATION_FAIL;
|
|
}
|
|
|
|
const ns_formula::EquipSlotsManageInfo* const equip_manage_info = \
|
|
equip_container->GetEquipmentManageInfo();
|
|
if (equip_manage_info == NULL)
|
|
{
|
|
return RC::RC_BATTLE_GROUND_RESERVATION_FAIL;
|
|
}
|
|
|
|
const ns_formula::EquipSlotsManageInfo::ItemScoreInfo& item_score_info = \
|
|
equip_manage_info->item_score_info;
|
|
|
|
*item_score = item_score_info.GetTotalScore();
|
|
|
|
return RC::RC_BATTLE_GROUND_RESERVATION_SUCCESS;
|
|
}
|
|
|
|
//==================================================================================================
|
|
//==================================================================================================
|
|
//==================================================================================================
|
|
|