Files
mir_server/server/LogicServer/item/cnt/UserItemContianer.cpp
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

1011 lines
30 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "StdAfx.h"
#include "UserItemContainer.h"
INT_PTR CUserItemContainer::AddItem(const ItemOPParam& param, LPCSTR lpSender, const INT_PTR nLogIdent, BYTE bNoBatchUse)
{
if(param.wCount <= 0) return 0;
const CStdItem *pStdItem;
INT_PTR Result = 0, nRemainCount, nDupedCount;
const CStdItemProvider& stdItemProvider = GetLogicServer()->GetDataProvider()->GetStdItemProvider();
//通过物品ID查找物品配置对象
pStdItem = stdItemProvider.GetStdItem(param.wItemId);
if ( !pStdItem)//|| pStdItem->m_Flags.boDelete)
return 0;
//
SendItemChangeLog(1, param.wCount, param.wItemId ,nLogIdent,lpSender);
nRemainCount = param.wCount;
//如果物品可以叠加,则尝试叠加到现有物品中
if ( pStdItem->m_wDupCount > 1 )
{
//不断的尝试叠加到现有物品中,直到物品获取完成或不可继续叠加了
while (nRemainCount > 0)
{
nDupedCount = OverlapToExists(param, nRemainCount, lpSender, nLogIdent, bNoBatchUse);
if ( nDupedCount <= 0 )
break;
nRemainCount -= nDupedCount;
Result += nDupedCount; // 解决提示错误的bug
}
}
//继续将未能叠加到已经存在的物品中的剩余物品作为新物品添加
nDupedCount = __max(1, pStdItem->m_wDupCount);
INT_PTR nAddCount ; //实际添加的数量
CUserItem *pUserItem = NULL;
while ( availableCount(pStdItem->m_nPackageType) > 0 && nRemainCount > 0 )
{
pUserItem = GetLogicServer()->GetLogicEngine()->AllocUserItem(true);
pUserItem->wItemId = param.wItemId;
nAddCount = __min(nRemainCount, nDupedCount); //实际添加的数量
pUserItem->wCount = (WORD)nAddCount; //实际添加的数量
pUserItem->btFlag = param.btBindFlag;
pUserItem->btQuality = param.btQuality;
pUserItem->wStar = param.wStar; //强化星级
pUserItem->bLostStar = param.bLostStar; //强化损失星级
pUserItem->bInSourceType = param.bInSourceType; //铭刻等级
pUserItem->nAreaId = param.nAreaId; //来源场景
pUserItem->btLuck = param.btLuck; //幸运
pUserItem->wIdentifySlotNum = param.wIdentifyslotnum; //鉴定槽数量
CStdItem::AssignInstance (pUserItem,pStdItem);
//售卖类箱子道具时间设置
// if(pStdItem->m_btType == Item::itSellBox)
// {
// if(pStdItem->m_UseTime.tv > 0)
// {
// pUserItem->time = pStdItem->m_UseTime.tv;
// pUserItem->time.startRecord(GetLogicServer()->GetLogicEngine()->getMiniDateTime());
// }
// }
// if (param.nLeftTime > 0)
// {
// pUserItem->nCreatetime = param.nLeftTime;
// pUserItem->nCreatetime.startRecord(GetLogicServer()->GetLogicEngine()->getMiniDateTime());
// }
memcpy(pUserItem->smithAttrs, param.nSmith, sizeof(param.nSmith));
memcpy(pUserItem->cBestAttr, param.cBestAttr, sizeof(param.cBestAttr));
if(!param.bInSourceType)
pUserItem->setSource(CStdItem::iqOther,GetLogicServer()->GetLogicEngine()->getMiniDateTime());
else
{
pUserItem->setSource(param.bInSourceType,param.nCreatetime,param.nAreaId,param.nDropMonsterId,param.cSourceName);
}
pUserItem->wPackageType = pStdItem->m_nPackageType;
//将物品添加到容器中
m_pUserItemList.push_back(pUserItem);
addCostCount(pUserItem->wPackageType);
//如果物品需要记录流通日志,则需要向日志服务器发送记录日志的数据
// if ( nLogIdent )
// {
// LogNewItem(pUserItem, pStdItem, lpSender, nLogIdent);
// }
//向角色发送获得物品的消息
SendAddItem(pUserItem,nLogIdent, bNoBatchUse);
//减少给予物品的数量并增加已获得的物品数量
nRemainCount -= (nAddCount); //减去实际添加的数量
Result += nAddCount; //结果添加实际的数量
}
OnAddItemById(param.wItemId, (int)Result , nLogIdent, pUserItem); // 修改添加物品如果叠放了提示不对的bug
OnDataModified();
//统计产出
GetLogicServer()->GetDataProvider()->GetStdItemProvider().AddItemOutPutCount(param.wItemId,param.wCount,nLogIdent);
return Result;
}
INT_PTR CUserItemContainer::GetAddItemNeedGridCount(const ItemOPParam& param)
{
// INT_PTR nRemainCount, nDupedCount;
int nRemainCount = param.wCount;//装备的数量
const CStdItemProvider& stdItemProvider = GetLogicServer()->GetDataProvider()->GetStdItemProvider();
//通过物品ID查找物品配置对象
const CStdItem * pStdItem= stdItemProvider.GetStdItem(param.wItemId);
if ( !pStdItem )
return nRemainCount;
int nDupedCount = pStdItem->m_wDupCount; //能够叠加的数量
if(nDupedCount > 1)
{
int value = nRemainCount % nDupedCount;
nRemainCount = nRemainCount / nDupedCount;
if(value > 0)
nRemainCount++;
}
{
return nRemainCount; //如果不能叠加直接返回物品的个数
}
}
//能否添加一个物品
bool CUserItemContainer::CanAddItem(const ItemOPParam& param, bool bNeedCkeckCell)
{
const CStdItemProvider& stdItemProvider = GetLogicServer()->GetDataProvider()->GetStdItemProvider();
const CStdItem * pStdItem= stdItemProvider.GetStdItem(param.wItemId);
if ( !pStdItem )
return false; //不合法的物品
int nNum = 0;
if (bNeedCkeckCell && pStdItem->m_nPackageType >= 1)
nNum = 10;
return (availableCount(pStdItem->m_nPackageType)-nNum) >= GetAddItemNeedGridCount(param) ;
}
bool CUserItemContainer::CanAddItem( CUserItem * pUserItem, bool bNeedCkeckCell)
{
if(pUserItem ==NULL) return false;
ItemOPParam param;
param.wItemId =pUserItem->wItemId;
param.wCount =pUserItem->wCount;
param.btQuality = pUserItem->btQuality;
param.btBindFlag =pUserItem->btFlag;
param.btStrong = pUserItem->btStrong;
return CanAddItem(param, bNeedCkeckCell);
}
//能否添加一批物品
bool CUserItemContainer::CanAddItems( CVector<ItemOPParam> &itemList)
{
const CStdItemProvider& stdItemProvider = GetLogicServer()->GetDataProvider()->GetStdItemProvider();
INT_PTR nGridCount = availableMinCount(); //当前的格子的数量
const CStdItem * pStdItem;
for(INT_PTR i=0; i< itemList.count(); i++)
{
pStdItem = stdItemProvider.GetStdItem(itemList[i].wItemId);
if ( !pStdItem )
return false; //不合法的物品
nGridCount -= GetAddItemNeedGridCount(itemList[i]);
if(nGridCount < 0) return false;
}
return true;
}
bool CUserItemContainer::SplitItem(const CUserItem::ItemSeries series,INT_PTR nCount)
{
CUserItem* pUserItem = FindItemByGuid(series);
if( pUserItem==NULL) return false; //找不到这个物品
int nsubcount = 0;
if(pUserItem->wPackageType >= 1 )
nsubcount = 10;
if((availableCount(pUserItem->wPackageType)-nsubcount) < 1) return false; //没有剩下格子
OnDataModified();
INT_PTR nLeftCount = pUserItem->wCount - nCount;
//无法拆分出这么多个
if(nLeftCount < 1) return false;
CUserItem* pNewUserItem = GetLogicServer()->GetLogicEngine()->AllocUserItem(true); //新的物品
if(pNewUserItem ==NULL) return false;
CUserItem::ItemSeries newGuid = pNewUserItem->series; //保存序列号
memcpy(pNewUserItem,pUserItem,sizeof(*pUserItem)); //先拷贝过去
pNewUserItem->series = newGuid; //序列号是新的
pNewUserItem->wCount = (WORD)nCount; //新的数量
pUserItem->wCount = (WORD) nLeftCount; // 剩下的数量
SendItemCountChange(pUserItem); //通知客户端发生改变
m_pUserItemList.push_back(pNewUserItem);
addCostCount(pUserItem->wPackageType);
SendAddItem(pNewUserItem,GameLog::clEquipSplit); //通知剩下的数量发生改变
return true;
}
/*
道具合并,
bBindInfect是否绑定感染
绑定感染,如果源目标是绑定的,则目标也会变成绑定的
*/
bool CUserItemContainer::MergeItem(const CUserItem::ItemSeries srcSeries,const CUserItem::ItemSeries tgtSeries, bool bBindInfect)
{
CUserItem* pSrcUserItem = FindItemByGuid(srcSeries);
CUserItem* pTgtUserItem = FindItemByGuid(tgtSeries);
if(pSrcUserItem ==NULL || pTgtUserItem ==NULL ) return false;
if(pSrcUserItem->wItemId != pTgtUserItem->wItemId) return false;
const CStdItem* pStdItem = GetLogicServer()->GetDataProvider()->GetStdItemProvider().GetStdItem(pTgtUserItem->wItemId);
ItemOPParam param;
param.wItemId = pSrcUserItem->wItemId;
param.btQuality = pSrcUserItem->btQuality;
param.btStrong = pSrcUserItem->btStrong;
param.wCount = pSrcUserItem->wCount;
param.btBindFlag = pSrcUserItem->btFlag;
// 修改bug 只判断目标能否叠加会有问题,有时间限制的物品往没有时间限制的物品上叠加会成功。 2011.12。8 by 王鹏
//能够叠加的数量
INT_PTR nOverLapCount= __min( pSrcUserItem->wCount, GetCanOverlapCountEx(pSrcUserItem, pTgtUserItem,bBindInfect) );
if( nOverLapCount == 0 ) //叠加的数量为0
{
return false;
}
else
{
INT_PTR nTotalCount = pSrcUserItem->wCount + pTgtUserItem->wCount; //开始叠加前的数量
INT_PTR nTargetCount = pTgtUserItem->wCount + nOverLapCount; //目标的数量
INT_PTR nSrcCount = pSrcUserItem->wCount - nOverLapCount;
if( nTargetCount > pStdItem->m_wDupCount || nSrcCount <0) //计算错误了
{
return false;
}
pTgtUserItem->wCount = (WORD)nTargetCount;
if( bBindInfect && pSrcUserItem->binded() ) //需要绑定感染
{
pTgtUserItem->btFlag = pSrcUserItem->btFlag; //如果源目标是绑定的,则目标也变成绑定的
}
if( bBindInfect )
{
NotifyItemChange(pTgtUserItem); //通知客户端目标道具数据发生改变
}
else
{
SendItemCountChange(pTgtUserItem); //通知客户端发生改变
}
if(nSrcCount == 0)
{
RemoveItem(pSrcUserItem->series,"item_merge",GameLog::Log_ItemMerge,true); //删除这个物品
}
else
{
pSrcUserItem->wCount = (WORD)nSrcCount ;
if( bBindInfect )
{
NotifyItemChange(pSrcUserItem); //通知客户端目标道具数据发生改变
}
else
{
SendItemCountChange(pSrcUserItem); //通知客户端发生改变
}
}
OnDataModified();
return true;
}
}
INT_PTR CUserItemContainer::AddItem(CUserItem *pUserItem, LPCSTR lpSender, const INT_PTR nLogIdent,bool bNeedSendClient,bool bDupCount,BYTE bNotice)
{
// 优先叠放
if (!pUserItem)
{
return 0;
}
const CStdItem* pStdItem = GetLogicServer()->GetDataProvider()->GetStdItemProvider().GetStdItem((int)pUserItem->wItemId);
if (!pStdItem)
return 0;
if (pUserItem->wCount <= 0)
{
OutputMsg(rmError,"[%s] remove item count=0,logid=%d,itemid=%d",__FUNCTION__,(int)nLogIdent,(int)pUserItem->wItemId);
GetGlobalLogicEngine()->DestroyUserItem(pUserItem);
return 0;
}
//如果已经找到了,那说明出现了复制则不添加进去
if (FindItemByGuid(pUserItem->series))
{
OutputMsg(rmWaning,_T("Copy Item is Coming...guid(%lld),LogId(%d)"),pUserItem->series.llId,(int)nLogIdent);
GetGlobalLogicEngine()->DestroyUserItem(pUserItem);
return 0;
}
//
SendItemChangeLog(1, pUserItem->wCount, pUserItem->wItemId ,nLogIdent,lpSender);
OnDataModified();
INT_PTR nAddCount =0; //实际上添加的个数
INT_PTR nCount = pUserItem->wCount;
INT_PTR nStackCount = pStdItem->m_wDupCount;
if (bDupCount && nStackCount > 0 && nCount != nStackCount)
{
INT_PTR nStackedCount = 0;
ItemOPParam param;
param.wItemId = pUserItem->wItemId;
param.wCount = pUserItem->wCount;
param.btBindFlag = pUserItem->btFlag;
param.btQuality = pUserItem->btQuality;
param.wStar = pUserItem->wStar;
nStackedCount = OverlapToExists(param, param.wCount, lpSender, nLogIdent);
nAddCount += nStackedCount;
if (nCount <= nStackedCount) // 全部堆叠完毕
{
pUserItem->wCount -= (WORD)nStackedCount;
OnAddItemById(pUserItem->wItemId, nCount, nLogIdent, pUserItem);
if(pUserItem->wCount <= 0)
{
GetGlobalLogicEngine()->DestroyUserItem(pUserItem); //数目已经叠加好了,删除指针
}
return nAddCount;
}
pUserItem->wCount -= (WORD)nStackedCount;
}
// 不能叠放的,用新格子
if(availableCount(pStdItem->m_nPackageType) <=0)
{
OutputMsg(rmWaning," CUserItemContainer::AddItem has no grid,itemid=%d,nLogIdent=%d",(int)pUserItem->wItemId,(int)nLogIdent);
return nAddCount; //空间不够
}
if(pUserItem->wCount <=0)
{
OutputMsg(rmWaning," CUserItemContainer::AddItem count=0,itemid=%d,nLogIdent=%d",(int)pUserItem->wItemId,(int)nLogIdent);
return nAddCount; //空间不够
}
pUserItem->wPackageType = pStdItem->m_nPackageType;
m_pUserItemList.push_back(pUserItem);
addCostCount(pUserItem->wPackageType);
//如果物品需要记录日志,则向日志服务器记录日志
if ( pStdItem && nLogIdent ) //没有nLogIdent 可能就是db返回的
{
LogNewItem(pUserItem, pStdItem, lpSender, nLogIdent);
}
if(bNeedSendClient )
{
OnAddItem(pStdItem,pUserItem->wCount,nLogIdent,pUserItem);
SendAddItem(pUserItem,nLogIdent,0 ,bNotice);
}
return (pUserItem->wCount + nAddCount); //添加的个数为已经添加的个数以及自己的个数之和
}
void CUserItemContainer::DeleteAllItem()
{
CUserItem **pUserItemList, *pUserItem;
// pUserItemList = *this;
for (INT_PTR i=count()-1; i>-1; --i)
{
pUserItem = m_pUserItemList[i];
if(pUserItem ==NULL ) continue;
DeleteItem(pUserItem,pUserItem->wCount,"self_del_item",GameLog::clUserDestroyItem,true);
}
}
INT_PTR CUserItemContainer::DeleteItem(const ItemOPParam& param, LPCSTR lpSender, const INT_PTR nLogIdent, const int nDuraOdds/*, CActor* pActor*/)
{
INT_PTR Result = 0, nCount = param.wCount;
CUserItem **pUserItemList, *pUserItem;
const CStdItem *pStdItem = GetLogicServer()->GetDataProvider()->GetStdItemProvider().GetStdItem(param.wItemId);
// pUserItemList = *this;
for (INT_PTR i=count()-1; i>-1; --i)
{
pUserItem = m_pUserItemList[i];
if(pUserItem ==NULL ) continue;
if ( pUserItem->wItemId == param.wItemId )
{
if ( pUserItem->btQuality != param.btQuality && param.btQuality != (BYTE)-1 && param.btQuality != 255)
continue;
if ( pUserItem->btStrong != param.btStrong && param.btStrong != (BYTE)-1 )
continue;
if(param.btBindFlag != -1 && param.btBindFlag != 255)
{
if( (param.btBindFlag && 0==pUserItem->btFlag) || (param.btBindFlag==0 && pUserItem->btFlag) )
{
continue;
}
}
// if ((pUserItem->wDuraMax - pUserItem->wDura) > nDuraOdds && nDuraOdds != -1)
// continue;
INT_PTR nDelCount = DeleteItem(pUserItem,nCount,lpSender,nLogIdent);
Result += nDelCount;
nCount -= nDelCount;
if(nCount <=0 ) //已经全部删除完毕了
{
break;
}
}
}
OnDataModified();
return Result;
}
INT_PTR CUserItemContainer::DeleteOtherItem(CUserItem * pUserItem,INT_PTR nCount, LPCSTR lpSender, const INT_PTR nLogIdent,bool bNeedFreeMemory,bool bReqSB )
{
if (pUserItem == NULL) return 0;
INT_PTR Result = 0;
CUserItem **pUserItemList, *pSelfItem;
const CStdItem *pStdItem = GetLogicServer()->GetDataProvider()->GetStdItemProvider().GetStdItem(pUserItem->wItemId);
// pUserItemList = *this;
for (INT_PTR i = count()-1; i > -1; --i)
{
pSelfItem = m_pUserItemList[i];
if (pSelfItem == NULL) continue;
if ( pSelfItem->wItemId == pUserItem->wItemId )
{
if ( pSelfItem->btQuality != pUserItem->btQuality && pUserItem->btQuality != (BYTE)-1)
continue;
if (bReqSB)
{
if ( pSelfItem->btStrong != pUserItem->btStrong && pUserItem->btStrong != (BYTE)-1 )
continue;
if (pUserItem->btFlag != -1 && pUserItem->btFlag != 255)
{
if( (pUserItem->btFlag && 0 == pSelfItem->btFlag) || (pUserItem->btFlag == 0 && pSelfItem->btFlag) )
{
continue;
}
}
}
//如果为指定的物品 则排除
if (pUserItem->series == pSelfItem->series)
{
continue;
}
INT_PTR nDelCount = DeleteItem(pSelfItem,nCount,lpSender,nLogIdent);
Result += nDelCount;
nCount -= nDelCount;
if(nCount <= 0 ) //已经全部删除完毕了
{
break;
}
}
}
OnDataModified();
return Result;
}
INT_PTR CUserItemContainer::DeleteItem(CUserItem * pUserItem,INT_PTR nCount, LPCSTR lpSender, const INT_PTR nLogIdent,bool bNeedFreeMemory )
{
INT_PTR Result = 0;
if(pUserItem == NULL) return 0;
//修改一个bug在背包里删除一个物品需要判断是否在背包里存在
//如果查找到这个物品不在这个容器里,需要删除
CUserItem * pSelfItem = FindItemByGuid(pUserItem->series);
if(pSelfItem == NULL || pSelfItem != pUserItem)
{
return 0;
}
const CStdItem *pStdItem = GetLogicServer()->GetDataProvider()->GetStdItemProvider().GetStdItem(pUserItem->wItemId);
if(pStdItem ==NULL) return 0;
//
if ( pUserItem->wCount > nCount )
{
pUserItem->wCount -= (WORD)nCount;
Result += nCount;
//如果物品需要记录流通日志,则需要向日志服务器发送记录日志的数据
// if ( pStdItem /*&& pStdItem->m_Flags.recordLog*/ )
// {
// LogItemCountChange(pUserItem, pStdItem, -nCount, lpSender, nLogIdent);
// }
//
//向角色发送删物品数量变更的消息
SendItemChangeLog(2, nCount, pUserItem->wItemId ,nLogIdent,lpSender);
SendItemCountChange(pUserItem);
}
else
{
INT_PTR nItemCount = pUserItem->wCount;
Result += nItemCount;
//如果物品需要记录流通日志,则需要向日志服务器发送记录日志的数据
// if ( pStdItem /*&& pStdItem->m_Flags.recordLog*/)
// {
// LogItemCountChange(pUserItem, pStdItem, -nItemCount, lpSender, nLogIdent);
// }
int nCount = pUserItem->wCount;
pUserItem->wCount = 0;//将物品数量归零以便正确的记录日志
RemoveItem(pUserItem->series,lpSender,nLogIdent,bNeedFreeMemory,nCount);
}
//OnDeleteItem(pStdItem,Result,nLogIdent, 0,pUserItem);
OnDataModified();
return Result;
}
bool CUserItemContainer::RemoveItem(const CUserItem::ItemSeries series, LPCSTR lpSender, const INT_PTR nLogIdent,bool bNeedFreeMemory, int nCount )
{ INT_PTR nIdx = FindIndex(series);
if ( nIdx > -1 )
{
return RemoveItem(nIdx,lpSender,nLogIdent,bNeedFreeMemory, nCount);
}
return false;
}
bool CUserItemContainer::RemoveItem(const INT_PTR nIndex, LPCSTR lpSender,INT_PTR nLogIdent,bool bNeedFreeMemory, int nCount)
{
if ( (nIndex > -1) && (nIndex < m_pUserItemList.size()))
{
CUserItem *pUserItem = m_pUserItemList[nIndex];
if(pUserItem ==NULL) return false;
SendDeleteItem(pUserItem,nLogIdent); //通知客户端删除
const CStdItem *pStdItem = GetLogicServer()->GetDataProvider()->GetStdItemProvider().GetStdItem(pUserItem->wItemId);
if(pStdItem ==NULL) return false;
//OnDeleteItem(pStdItem,pUserItem->wCount,nLogIdent, nMsgId, pUserItem);
//
if(pUserItem->wCount > nCount)
nCount = pUserItem->wCount;
SendItemChangeLog(2, nCount, pUserItem->wItemId ,nLogIdent,lpSender);
if(nLogIdent != GameLog::Log_Deport2Bag && nLogIdent != GameLog::Log_DepotMerge)
addCostCount(pUserItem->wPackageType, -1);
if(bNeedFreeMemory)
{
GetGlobalLogicEngine()->DestroyUserItem(pUserItem); //销毁这个物品的内存,可以重用
}
m_pUserItemList.erase(m_pUserItemList.begin()+nIndex); //背包格子可以重用
OnDataModified();
return true;
}
return false;
}
CUserItem* CUserItemContainer::FindItem(const INT_PTR wItemId, const INT_PTR nQuality /* = -1 */, const INT_PTR nStrong /* = -1 */, WORD nMinCount)
{
CUserItem **pUserItemList, *pUserItem;
// pItemList = *this;
for (INT_PTR i=count()-1; i>-1; --i)
{
pUserItem = m_pUserItemList[i];
if(pUserItem ==NULL ) continue;
if ( pUserItem->wItemId == wItemId )
{
if ( pUserItem->wCount < nMinCount )
continue;
if ( pUserItem->btQuality != nQuality && nQuality != -1)
continue;
if ( pUserItem->wStar != nStrong && nStrong != -1 )
continue;
return pUserItem;
}
}
return NULL;
}
CUserItem* CUserItemContainer::FindItemByGuid(const CUserItem::ItemSeries series )
{
CUserItem **pItemList, *Result = NULL;
//pUserItemList = *this;
int count1 = count();
for (INT_PTR i = count1 - 1; i > -1; --i)
{
if ( m_pUserItemList[i]
&& m_pUserItemList[i]->series.llId == series.llId )
{
Result = m_pUserItemList[i];
break;
}
}
return Result;
}
INT_PTR CUserItemContainer::FindIndex(const CUserItem::ItemSeries series)
{
//CUserItem **pItemList = *this;
for (INT_PTR i= count()-1; i>-1; --i)
{
if ( m_pUserItemList[i] && m_pUserItemList[i]->series.llId == series.llId )
return i;
}
return -1;
}
INT_PTR CUserItemContainer::GetItemCount(const INT_PTR wItemId, const INT_PTR nQuality , const INT_PTR nStrong ,const INT_PTR nBind, const INT_PTR nDuraOdds,void * pNoItem)
{
INT_PTR Result = 0;
CUserItem **pUserItemList, *pUserItem, *pNoGetItem = NULL;
// pUserItemList = *this;
int size = count();
if (pNoItem != NULL)
{
pNoGetItem = (CUserItem*)pNoItem;
}
for (INT_PTR i=size-1; i>-1; --i)
{
pUserItem = m_pUserItemList[i];
if (pUserItem && pUserItem->wItemId == wItemId )
{
if ( pUserItem->btQuality != nQuality && nQuality != -1 && nQuality != 255)
continue;
if ( pUserItem->btStrong != nStrong && nStrong != -1 && nStrong != 255)
continue;
//判断绑定属性是否一致
if(nBind != -1 && nBind != 255)
{
if( (nBind && 0==pUserItem->btFlag) || (nBind==0 && pUserItem->btFlag) )
{
continue;
}
if(nBind > 0 && pUserItem->btFlag != nBind)
{
continue;
}
}
// if ((pUserItem->wDuraMax - pUserItem->wDura) > nDuraOdds && nDuraOdds != -1)
// continue;
if (pNoGetItem != NULL && pNoGetItem == pUserItem)
{
continue;
}
Result += pUserItem->wCount;
}
}
return Result;
}
INT_PTR CUserItemContainer::Clear(LPCSTR lpSender /* = NULL */, const INT_PTR nLogIdent /* = 0 */)
{
INT_PTR i, nCount;
const CStdItem *pStdItem;
const CStdItemProvider &stdItemProvider = GetLogicServer()->GetDataProvider()->GetStdItemProvider();
//CUserItem **pItemList = *this;
for (i=count()-1; i>-1; --i)
{
if(m_pUserItemList[i]) {
//记录日志并向角色发送数据
if ( nLogIdent )
{
nCount = m_pUserItemList[i]->wCount;
m_pUserItemList[i]->wCount = 0;
pStdItem = stdItemProvider.GetStdItem(m_pUserItemList[i]->wItemId);
// if ( pStdItem /*&& pStdItem->m_Flags.recordLog*/)
// LogItemCountChange(m_pUserItemList[i], pStdItem, -nCount, lpSender, nLogIdent);
SendDeleteItem(m_pUserItemList[i],nLogIdent);
}
//释放物品的内存
GetLogicServer()->GetLogicEngine()->DestroyUserItem(m_pUserItemList[i]);
}
}
nCount = count();
//Inherited::clear();
m_pUserItemList.clear();
OnDataModified();
return nCount;
}
/*
计算道具叠加数量
bBindInfect:允许绑定道具与非绑定道具之间的合并
*/
INT_PTR CUserItemContainer::GetCanOverlapCountEx(const CUserItem *pSrcItem, const CUserItem *pDestItem, bool bBindInfect)
{
if (!pSrcItem || !pDestItem || pSrcItem->wItemId != pDestItem->wItemId)
return 0;
// if( pSrcItem->btQuality != pDestItem->btQuality ||
// pSrcItem->btStrong != pDestItem->btStrong ||
// pSrcItem->time.tv != pDestItem->time.tv
// )
// return 0;
// if( !bBindInfect ) //如果不需要绑定感染,就要判断两方道具是否同为绑定或者不绑定
// {
// if( pSrcItem->btFlag != pDestItem->btFlag )
// {
// return 0;
// }
// }
CStdItemProvider &itemProvider = GetLogicServer()->GetDataProvider()->GetStdItemProvider();
const CStdItem *pStdItem = itemProvider.GetStdItem(pDestItem->wItemId);
if (!pStdItem)
return 0;
INT_PTR nDupSpace = pStdItem->m_wDupCount - pDestItem->wCount;
if(nDupSpace <=0)
{
return 0;
}
else
{
return nDupSpace;
}
}
INT_PTR CUserItemContainer::GetCanOverlagCount(const ItemOPParam& param, const CUserItem * pUserItem)
{
//物品能够堆叠的条件为:
//1、物品ID相同
//2、物品品质相同
//3、物品强化等级相同
//4、物品绑定标志位相同
const CStdItem *pStdItem = GetLogicServer()->GetDataProvider()->GetStdItemProvider().GetStdItem(param.wItemId);
if ( !pStdItem || !pUserItem )
return 0;
if ( pUserItem->wItemId == param.wItemId && pUserItem->btQuality == param.btQuality
&& pUserItem->wStar == param.wStar
&& (pUserItem->btFlag == param.btBindFlag)
)
{
INT_PTR nDupSpace = pStdItem->m_wDupCount - pUserItem->wCount;
if(nDupSpace <=0)
{
return 0;
}
else
{
return nDupSpace;
}
}
else
{
return 0;
}
}
INT_PTR CUserItemContainer::OverlapToExists(const ItemOPParam& param, INT_PTR nCount, LPCSTR lpSender, const INT_PTR nLogIdent, BYTE bNoBatchUse)
{
INT_PTR Result = 0;
CUserItem **pUserItemList, *pUserItem;
const CStdItem *pStdItem = GetLogicServer()->GetDataProvider()->GetStdItemProvider().GetStdItem(param.wItemId);
if ( !pStdItem )
return 0;
// pUserItemList = *this;
for (INT_PTR i=count()-1; i>-1 && nCount > 0; --i)
{
pUserItem = m_pUserItemList[i];
if(NULL == pUserItem ) continue;
INT_PTR nDupSpace = GetCanOverlagCount(param,pUserItem);
if ( nDupSpace > 0 )
{
if ( nDupSpace > nCount )
nDupSpace = nCount;
pUserItem->wCount += (WORD)nDupSpace;
nCount -= nDupSpace;
Result += nDupSpace;
//如果物品需要记录流通日志,则需要向日志服务器发送记录日志的消息
if (nLogIdent )
{
LogItemCountChange(pUserItem, pStdItem, nDupSpace, lpSender, nLogIdent);
}
//向角色发送物品数量变更的消息
SendItemCountChange(pUserItem,true, bNoBatchUse);
}
}
return Result;
}
void CUserItemContainer::ArrangeItemList(int nLogId)
{
if (count() <= 1)
{
return;
}
int i = 0;
CUserItem **pUserItemList, *pItemDest, *pItemSour;
// pUserItemList = *this;
while ( (i < count()) && (i >= 0) )
{
pItemDest = m_pUserItemList[i];
if ( !pItemDest )
{
return;
}
const CStdItem *pStdItemEx = GetLogicServer()->GetDataProvider()->GetStdItemProvider().GetStdItem(pItemDest->wItemId);
if (!pStdItemEx || pItemDest->wCount >= pStdItemEx->m_wDupCount )
{
i++;
continue;
}
int maxCount = pStdItemEx->m_wDupCount;
int j = i + 1;
while ( (pItemDest->wCount < maxCount) && ( j < count() ))
{
pItemSour = m_pUserItemList[j];
if ( pItemSour && pItemSour->wItemId == pItemDest->wItemId)
{
int dupCount = __min(maxCount - pItemDest->wCount, pItemSour->wCount);
pItemDest->wCount += dupCount;
SendItemCountChange(pItemDest);
if (dupCount >= pItemSour->wCount)
{
RemoveItem(pItemSour->series,"item_arrange",nLogId,true);
}
else
{
pItemSour->wCount -= dupCount;
SendItemCountChange(pItemSour);
break;
}
}
else
{
j++;
}
}
i++;
}
}
/*
剩余格数
*/
INT_PTR CUserItemContainer::availableCount(WORD type)//type 从0开始
{
//int maxBagsNum = GetLogicServer()->GetDataProvider()->GetBagConfig().nMaxBagCount;
if(type > m_nBagNums -1)
{
return 0;
}
int result = m_BagMaxCounts[type] - m_BagCostCounts[type];
return result < 0?0:result;
}
/*
获取所有类型背包最小的格数-----刘老板要求先这样做 一个背包满了 所有的物品都不能添加到背包
*/
INT_PTR CUserItemContainer::availableMinCount()
{
std::vector<int> results;
for(int i = 0; i< m_nBagNums; i++)
{
int left = m_BagMaxCounts[i] - m_BagCostCounts[i];
results.push_back(left < 0?0:left);
}
sort(results.begin(), results.end());
return results[0];
}
//BagType
bool CUserItemContainer::bagIsEnough(int nType, int nNum)
{
std::vector<int>& count = GetLogicServer()->GetDataProvider()->getBagRemainConfig(nType);
for(int i = 0; i< m_nBagNums; i++)
{
if( m_BagMaxCounts[i] - m_BagCostCounts[i] < count[i] + nNum)
return false;
}
return true;
}
bool CUserItemContainer::bagLeftEnoughGiveNum(int num)
{
return availableMinCount() >= num?true:false;
}
/*
使用格数
*/
void CUserItemContainer::addCostCount(WORD type, int nNum)//type 从0开始
{
if(type > m_nBagNums -1)
{
return ;
}
m_BagCostCounts[type] += nNum;
if(m_BagCostCounts[type] < 0) //删除
m_BagCostCounts[type] = 0;
}
int CUserItemContainer::GetBagCount(WORD type)//type 从0开始
{
if(type > m_nBagNums -1)
{
return 0;
}
return m_BagMaxCounts[type];
}
INT_PTR CUserItemContainer::AddItem2depot(CUserItem *pUserItem, LPCSTR lpSender, const INT_PTR nLogIdent,bool bNeedSendClient,bool bDupCount,BYTE bNotice)
{
// 优先叠放
if (!pUserItem)
{
return 0;
}
const CStdItem* pStdItem = GetLogicServer()->GetDataProvider()->GetStdItemProvider().GetStdItem((int)pUserItem->wItemId);
if (!pStdItem)
return 0;
if (pUserItem->wCount <= 0)
{
OutputMsg(rmError,"[%s] remove item count=0,logid=%d,itemid=%d",__FUNCTION__,(int)nLogIdent,(int)pUserItem->wItemId);
GetGlobalLogicEngine()->DestroyUserItem(pUserItem);
return 0;
}
//如果已经找到了,那说明出现了复制则不添加进去
if (FindItemByGuid(pUserItem->series))
{
OutputMsg(rmWaning,_T("Copy Item is Coming...guid(%lld),LogId(%d)"),pUserItem->series.llId,(int)nLogIdent);
GetGlobalLogicEngine()->DestroyUserItem(pUserItem);
return 0;
}
//
// SendItemChangeLog(1, pUserItem->wCount, pUserItem->wItemId ,nLogIdent);
OnDataModified();
INT_PTR nAddCount =0; //实际上添加的个数
INT_PTR nCount = pUserItem->wCount;
INT_PTR nStackCount = pStdItem->m_wDupCount;
// if (bDupCount && nStackCount > 0 && nCount != nStackCount)
// {
// INT_PTR nStackedCount = 0;
// ItemOPParam param;
// param.wItemId = pUserItem->wItemId;
// param.wCount = pUserItem->wCount;
// param.btBindFlag = pUserItem->btFlag;
// param.btQuality = pUserItem->btQuality;
// param.wStar = pUserItem->wStar;
// nStackedCount = OverlapToExists(param, param.wCount, lpSender, nLogIdent);
// nAddCount += nStackedCount;
// if (nCount <= nStackedCount) // 全部堆叠完毕
// {
// pUserItem->wCount -= (WORD)nStackedCount;
// OnAddItemById(pUserItem->wItemId, nCount, nLogIdent, pUserItem);
// if(pUserItem->wCount <=0)
// {
// GetGlobalLogicEngine()->DestroyUserItem(pUserItem); //数目已经叠加好了,删除指针
// }
// return nAddCount;
// }
// pUserItem->wCount -= (WORD)nStackedCount;
// }
// 不能叠放的,用新格子
if(availableCount() <=0)
{
OutputMsg(rmWaning," CUserItemContainer::AddItem has no grid,itemid=%d,nLogIdent=%d",(int)pUserItem->wItemId,(int)nLogIdent);
return nAddCount; //空间不够
}
if(pUserItem->wCount <=0)
{
OutputMsg(rmWaning," CUserItemContainer::AddItem count=0,itemid=%d,nLogIdent=%d",(int)pUserItem->wItemId,(int)nLogIdent);
return nAddCount; //空间不够
}
pUserItem->wPackageType = pStdItem->m_nPackageType;
m_pUserItemList.push_back(pUserItem);
//如果物品需要记录日志,则向日志服务器记录日志
// if ( pStdItem && nLogIdent ) //没有nLogIdent 可能就是db返回的
// {
// LogNewItem(pUserItem, pStdItem, lpSender, nLogIdent);
// }
if(bNeedSendClient )
{
OnAddItem(pStdItem,pUserItem->wCount,nLogIdent,pUserItem);
SendAddItem(pUserItem,nLogIdent,0 ,bNotice);
}
return (pUserItem->wCount + nAddCount); //添加的个数为已经添加的个数以及自己的个数之和
}