384 lines
15 KiB
C++
384 lines
15 KiB
C++
#pragma once
|
||
#include<vector>
|
||
|
||
/************************************************************************/
|
||
/*
|
||
/* 用户物品容器类
|
||
/*
|
||
/* 提供添加、删除、管理用户物品的功能并实现相关消息发送以及日志记录的接口函数。是实现
|
||
/* 用户包裹、仓库系统的基础类。
|
||
/*
|
||
/************************************************************************/
|
||
|
||
|
||
class CUserItemContainer //:protected std::vector<CUserItem*>
|
||
{
|
||
public:
|
||
// typedef std::vector<CUserItem*> Inherited;
|
||
|
||
//定义物品操作参数,用于添加、删除以及更新一个物品
|
||
struct ItemOPParam
|
||
{
|
||
public:
|
||
BYTE btQuality;
|
||
BYTE btStrong;
|
||
WORD wItemId;
|
||
|
||
BYTE btBindFlag;
|
||
BYTE btReserver;
|
||
WORD wCount; //数量溢出
|
||
WORD wStar; //强化星级
|
||
BYTE bLostStar; //强化损失星级
|
||
BYTE btLuck; //幸运
|
||
WORD wIdentifyslotnum;
|
||
WORD wIdentifynum;
|
||
int nSmith[CUserItem::MaxSmithAttrCount];
|
||
//byte nFiveIdx; //五行类型
|
||
//byte nFivePropIdx; //五行属性值
|
||
|
||
int nLeftTime; // 物品剩余时间。用于物品再添加的时候动态指定
|
||
char cBestAttr[200]; //极品属性
|
||
//int nStrongStar;
|
||
|
||
//---来源
|
||
BYTE bInSourceType; //来源
|
||
WORD nDropMonsterId; //怪物id
|
||
int nAreaId; //场景id
|
||
char cSourceName[200]; //归属昵称
|
||
CMiniDateTime nCreatetime; //物品的创建时间,类型为CMiniDateTime
|
||
|
||
public:
|
||
inline ItemOPParam()
|
||
{
|
||
memset(this, 0, sizeof(*this));
|
||
btBindFlag =-1;
|
||
}
|
||
void setSource(int nSourceType,int nTime, int nSceneId = 0, int nMonsterId = 0, const char* pKillerName = NULL)
|
||
{
|
||
memset(&this->cSourceName, 0, sizeof(this->cSourceName));
|
||
if(pKillerName)
|
||
memcpy(&this->cSourceName, pKillerName, sizeof(this->cSourceName));
|
||
this->nAreaId = nSceneId;
|
||
this->nCreatetime = nTime;//GetGlobalLogicEngine()->getMiniDateTime();
|
||
this->bInSourceType =nSourceType;// tagItemSource::iqKillMonster;
|
||
this->nDropMonsterId = nMonsterId;
|
||
}
|
||
inline ItemOPParam(const INT_PTR nItemId, const INT_PTR nCount = 1, const INT_PTR nQuality = 0,
|
||
const INT_PTR nStrong = 0, const INT_PTR nBindFlag = -1, const INT_PTR nItemStrongStar = 0)
|
||
{
|
||
wItemId = (WORD)nItemId;
|
||
btQuality = (BYTE)nQuality;
|
||
wStar = (WORD)nStrong;
|
||
wCount = (WORD)nCount;
|
||
btBindFlag = (BYTE)nBindFlag;
|
||
nLeftTime = 0;
|
||
memset(&cBestAttr, 0, sizeof(cBestAttr)/sizeof(char));
|
||
}
|
||
};
|
||
public:
|
||
CUserItemContainer()
|
||
: m_hasDataModify(false)
|
||
, m_nCapacity(0)
|
||
{
|
||
|
||
}
|
||
/*
|
||
* Comments:添加物品到容器中
|
||
* Param const ItemOPParam & param:添加物品的参数,包含物品ID、数量、品质、强化、绑定标志;
|
||
* Param LPCSTR lpSender:表示物品添加者的实体名称,主要用于记录日志中包含此实体的名称;
|
||
* Param const INT_PTR nLogIdent:表示日志号,0表示不记录日志
|
||
* Param BYTE bNoBatchUse:表示显示批量使用与否 0 显示 1不显示
|
||
* @Return INT_PTR: 实际添加成功的物品的数量
|
||
*/
|
||
INT_PTR AddItem(const ItemOPParam& param, LPCSTR lpSender, const INT_PTR nLogIdent, BYTE bNoBatchUse = 0);
|
||
|
||
/* 添加物品到容器中
|
||
* pUserItem用户物品对象;
|
||
* Sender 表示物品添加者的实体名称,主要用于记录日志中包含此实体的名称;
|
||
* nLogIdent表示本次物品添加操作的日志记录号,0表示不用记录日志;
|
||
* Param bool bNeedSendClient: 是否需要通知客户端
|
||
bDupCount = false 能叠加的也强制不叠加
|
||
* @return 返回添加了多少个物品
|
||
*/
|
||
INT_PTR AddItem(CUserItem *pUserItem, LPCSTR lpSender, const INT_PTR nLogIdent,bool bNeedSendClient=true,bool bDupCount=true, BYTE bNotice = 1);
|
||
INT_PTR AddItem2depot(CUserItem *pUserItem, LPCSTR lpSender, const INT_PTR nLogIdent,bool bNeedSendClient=true,bool bDupCount=true, BYTE bNotice = 1);
|
||
|
||
/* 从物品容器中删除并销毁物品
|
||
* param 删除物品的参数,包含物品ID、数量、品质、强化;
|
||
* nQuality 物品品质,-1表示匹配所有品质;
|
||
* nQuality 物品强化等级,-1表示匹配所有强化等级;
|
||
* nDuraOdds 耐力差 = 最大耐力-当前耐力 -1表示不检测 检测少于此耐力差的物品符合条件
|
||
* @param pActor 如果传入这指针,则必须足够数量才扣
|
||
* @return 返回删除了多少个物品
|
||
*/
|
||
INT_PTR DeleteItem(const ItemOPParam& param, LPCSTR lpSender, const INT_PTR nLogIdent, const int nDuraOdds = -1/*, CActor* pActor = nullptr*/);
|
||
|
||
/* 清空背包*/
|
||
void DeleteAllItem();
|
||
|
||
|
||
/*
|
||
* Comments:删除玩家背包里指定指针同状态不同series的其他物品
|
||
* Param CUserItem * pUserItem: 物品的指针
|
||
* Param INT_PTR nCount: 要删除的数量
|
||
* Param bool bReqSB:是否要判断强化与绑定条件
|
||
* @Return INT_PTR: 实际删除的物品的数量
|
||
*/
|
||
INT_PTR DeleteOtherItem(CUserItem * pUserItem,INT_PTR nCount, LPCSTR lpSender, const INT_PTR nLogIdent,bool bNeedFreeMemory =true,bool bReqSB = false);
|
||
|
||
/*
|
||
* Comments:从物品容器中移除一个物品
|
||
* Param const CUserItem::ItemSeries series:物品系列号
|
||
* Param bool bNeedFreeMemory:是否需要释放内存,如果否的话内存数据将保留
|
||
* @Return bool:
|
||
*/
|
||
bool RemoveItem(const CUserItem::ItemSeries series, LPCSTR lpSender, const INT_PTR nLogIdent,bool bNeedFreeMemory =true, int nMsgId = 0);
|
||
|
||
/*
|
||
* Comments:删除玩家身上的物品
|
||
* Param CUserItem * pUserItem: 物品的指针
|
||
* Param INT_PTR nCount: 要删除的数量
|
||
* @Return INT_PTR: 实际删除的物品的数量
|
||
*/
|
||
INT_PTR DeleteItem(CUserItem * pUserItem,INT_PTR nCount, LPCSTR lpSender, const INT_PTR nLogIdent,bool bNeedFreeMemory =true);
|
||
|
||
/*
|
||
* Comments:从物品容器中移除一个物品
|
||
* Param const INT_PTR nIndex:物品在容器中的索引
|
||
* Param bool bNeedFreeMemory: 是否需要释放内存,如果否的话内存数据将保留
|
||
* @Return VOID:
|
||
*/
|
||
bool RemoveItem(const INT_PTR nIndex, LPCSTR lpSender,INT_PTR nLogIdent,bool bNeedFreeMemory =true, int nMsgId = 0);
|
||
|
||
/* 查找一个用户物品
|
||
* wItemId 物品ID
|
||
* nQuality 物品品质,-1表示匹配所有品质;
|
||
* nQuality 物品强化等级,-1表示匹配所有强化等级;
|
||
* nMinCount 物品最低个数,1表示默认最少1个
|
||
* boRemove 参数用于规定在找到物品后是否将物品从容器中移除(只是移除,并不会销毁);
|
||
* @return 返回第一个匹配的用户物品指针
|
||
*/
|
||
CUserItem* FindItem(const INT_PTR wItemId, const INT_PTR nQuality = -1, const INT_PTR nStrong = -1, WORD nMinCount = 1);
|
||
|
||
|
||
/*
|
||
* Comments:通过序列号查找无哦
|
||
* Param const CUserItem::ItemSeries series: 物品的序列号
|
||
* Param bool boRemove 是否需要删除
|
||
* @Return CUserItem*:如果需要删除的话,那么找到就删除,返回NULL,否则返回查找的指针
|
||
*/
|
||
CUserItem* FindItemByGuid(const CUserItem::ItemSeries series);
|
||
|
||
|
||
/* 通过物品系列号查找用户物品对象
|
||
* boRemove 参数用于规定在找到物品后是否将物品从容器中移除(只是移除,并不会销毁);
|
||
* @return 返回第一个匹配的用户物品指针
|
||
*/
|
||
INT_PTR FindIndex(const CUserItem::ItemSeries series);
|
||
|
||
/* 统计指定物品的数量
|
||
* wItemId 物品ID
|
||
* nQuality 物品品质,-1表示匹配所有品质;
|
||
* nQuality 物品强化等级,-1表示匹配所有强化等级;
|
||
* nDuraOdds 耐力差 = 最大耐力-当前耐力 -1表示不检测 检测少于此耐力差的物品
|
||
* void * pUserItem:如果存在物品指针,不计算该指针的数量
|
||
* @return 返回匹配的物品总数量
|
||
*/
|
||
INT_PTR GetItemCount(const INT_PTR wItemId, const INT_PTR nQuality = -1, const INT_PTR nStrong = -1,const INT_PTR nBind =-1,const INT_PTR nDuraOdds = -1, void * pNoItem = NULL);
|
||
|
||
|
||
/*
|
||
* Comments:拆分一个物品
|
||
* Param const CUserItem::ItemSeries series: 物品的序列号
|
||
* Param INT_PTR nCount: 拆分出的数量
|
||
* @Return bool:成功返回true,否则返回false
|
||
*/
|
||
bool SplitItem(const CUserItem::ItemSeries series,INT_PTR nCount);
|
||
|
||
|
||
/*
|
||
* Comments: 合并物品,从源的物品合并到目的物品,如何合并完了就把删除
|
||
* Param const CUserItem::ItemSeries srcSeries: 源的物品
|
||
* Param const CUserItem::ItemSeries tgtSeries: 目的物品
|
||
@ Param bool bBindInfect:是否绑定感染,即合并的两种物品只要有一种是绑定的,目标就全部变成绑定的
|
||
* @Return bool:成功返回true,否则返回false
|
||
*/
|
||
bool MergeItem(const CUserItem::ItemSeries srcSeries,const CUserItem::ItemSeries tgtSeries, bool bBindInfect=false);
|
||
|
||
/*
|
||
* Comments: 获取能够叠加上去的数量
|
||
* Param const ItemOPParam & param: 物品的信息
|
||
* Param const CUserItem * pUserItem:目标的指针
|
||
* @Return INT_PTR: 能够叠加上去的数量
|
||
*/
|
||
INT_PTR GetCanOverlagCount(const ItemOPParam& param,const CUserItem * pUserItem);
|
||
|
||
/*
|
||
* Comments: 获取源物品能叠加到目标物品上去的数量
|
||
* Param const CUserItem * pSrcItem: 源物品对象指针
|
||
* Param const CUserItem * pDestItem: 目标物品对象指针
|
||
* Param bool bBindInfect:是否绑定感染
|
||
* @Return INT_PTR: 返回源物品能够叠加到目标物品的数量
|
||
* @Remark:
|
||
*/
|
||
INT_PTR GetCanOverlapCountEx(const CUserItem *pSrcItem, const CUserItem *pDestItem, bool bBindInfect=false);
|
||
|
||
//自动合并背包物品
|
||
void ArrangeItemList(int nLogId);
|
||
|
||
public:
|
||
// inline operator CUserItem** () const
|
||
// {
|
||
// return (CBaseList<CUserItem*>::operator CUserItem**());
|
||
// }
|
||
|
||
//清空容器中的物品,如果nLogIdent不为0则记录日志并向客户端发送
|
||
INT_PTR Clear(LPCSTR lpSender = NULL, const INT_PTR nLogIdent = 0);
|
||
|
||
//设置物品容器的容积
|
||
inline VOID setCapacity(const INT_PTR nCapacity)
|
||
{
|
||
m_nCapacity = nCapacity;
|
||
}
|
||
|
||
//获取容器中当前物品数量
|
||
// inline INT_PTR count()const{ return Inherited::count(); }
|
||
|
||
//获取容器的容量上限
|
||
inline INT_PTR capacity(){ return m_nCapacity; }
|
||
|
||
//获取容器的空闲数量
|
||
inline INT_PTR availableCount(){ return m_nCapacity - count(); } //delete
|
||
|
||
//剩余格数是否满足
|
||
bool bagIsEnough(int nType, int nNum = 0);
|
||
/*
|
||
* Comments: 能否添加一批物品,还没实现
|
||
* Param CVector<ItemOPParam> & itemList: 物品列表
|
||
* @Return bool:能够添加返回true,否则返回false
|
||
*/
|
||
bool CanAddItems( CVector<ItemOPParam> &itemList);
|
||
|
||
/*
|
||
* Comments: 能否添加物品,还没实现
|
||
* Param const ItemOPParam & param: 物品的信息
|
||
* @Return bool:能够添加返回true,否则返回false
|
||
*/
|
||
bool CanAddItem(const ItemOPParam& param, bool bNeedCkeckCell = false);
|
||
|
||
/*
|
||
* Comments: 能否添加物品
|
||
* Param const CUserItem * pUserItem: 物品的指针
|
||
* @Return bool:能返回true,否则返回false
|
||
*/
|
||
bool CanAddItem( CUserItem * pUserItem, bool bNeedCkeckCell = false);
|
||
|
||
/*--策划要求
|
||
* Comments: 添加物品需要的格子的数量,//这里将废弃 考虑叠加的情况如果能够叠加到一个现有的格子上面,那么将返回0
|
||
* Param const ItemOPParam & param: 物品的信息
|
||
* @Return INT_PTR: 返回需要的格子数量
|
||
*/
|
||
INT_PTR GetAddItemNeedGridCount(const ItemOPParam& param);
|
||
|
||
//----一支穿云箭 千军万马来相见
|
||
/*
|
||
* Comments: 获取容器的空闲数量
|
||
* Param int& type:背包类型
|
||
* @Return INT_PTR 剩余格数
|
||
*/
|
||
inline INT_PTR availableCount(WORD type);
|
||
|
||
/*
|
||
* Comments: 使用格数
|
||
* Paramint& type: 背包类型
|
||
*/
|
||
void addCostCount( WORD type, int nNum = 1);
|
||
|
||
/*
|
||
* Comments: 获取背包最大格数
|
||
* Paramint& type: 背包类型
|
||
*/
|
||
int GetBagCount(WORD type);
|
||
/*
|
||
* Comments: 获取背包最小剩余格数
|
||
*/
|
||
INT_PTR availableMinCount();
|
||
|
||
//最小剩余格数是否满足给定数值
|
||
bool bagLeftEnoughGiveNum(int num);
|
||
|
||
inline VOID SetBagNums(const INT_PTR maxNum)
|
||
{
|
||
m_nBagNums = maxNum;
|
||
}
|
||
|
||
inline VOID PushBagMaxCount(const INT_PTR maxNum)
|
||
{
|
||
m_BagMaxCounts.push_back(maxNum);
|
||
}
|
||
|
||
inline bool UpdateBagMaxCounts(const WORD& type,const INT_PTR maxNum)
|
||
{
|
||
if((type < 0) || (type > m_nBagNums -1))
|
||
return false;
|
||
m_BagMaxCounts[type] = maxNum;
|
||
}
|
||
//----
|
||
inline int count() {return m_pUserItemList.size();};
|
||
|
||
inline CUserItem* operator[](size_t __n)
|
||
{return m_pUserItemList[__n];}
|
||
protected:
|
||
/** 相关消息操作的接口虚函数 **/
|
||
/* 记录获得新物品的日志
|
||
* item 新物品对象
|
||
* pStdItem 物品对应的标准物品配置对象
|
||
* lpSender 物品给予者名称
|
||
* nLogIdent 日志消息号
|
||
*/
|
||
virtual VOID LogNewItem(const CUserItem *pUserItem, const CStdItem *pStdItem, LPCSTR lpSender, const INT_PTR nLogIdent) const = 0;
|
||
/* 记录物品数量变更的日志
|
||
* item 物品对象
|
||
* pStdItem 物品对应的标准物品配置对象
|
||
* nCountChg 物品变更的数量,负数表示扣除了物品,正数表示获得了物品
|
||
* lpSender 物品给予或收取者名称
|
||
* nLogIdent 日志消息号
|
||
*/
|
||
virtual VOID LogItemCountChange(const CUserItem *pUserItem, const CStdItem *pStdItem, const INT_PTR nCountChg, LPCSTR lpSender, const INT_PTR nLogIdent) const = 0;
|
||
/* 向角色发送获得物品的消息 */
|
||
virtual VOID SendAddItem(const CUserItem *pUserItem,INT_PTR nLogIdent, BYTE bNoBatchUse = 0, BYTE bNotice = 1) const = 0;
|
||
/* 向角色发送物品数量变更的消息,必须在修改了物品数量后调用此函数 */
|
||
virtual VOID SendItemCountChange(const CUserItem *pUserItem, bool isGetNewCount = false, BYTE bNoBatchUse = 0) const = 0;
|
||
/* 向角色发送删除物品的消息 */
|
||
virtual VOID SendDeleteItem(const CUserItem *pUserItem,INT_PTR nLogIdent) const = 0;
|
||
|
||
//当物品添加成功到里边调用,主要用来发系统提示的
|
||
virtual VOID OnAddItem(const CStdItem * pItem, INT_PTR nItemCount,INT_PTR nLogIdent,const CUserItem *pUserItem=NULL){}
|
||
|
||
//物品变动日志
|
||
virtual void SendItemChangeLog(int nType, int nCount, int nItemId, int nLogId = 0,LPCSTR sDes = NULL){ }
|
||
|
||
//当删除了几个物品,用于发系统提示
|
||
virtual VOID OnDeleteItem(const CStdItem * pItem, INT_PTR nItemCount,INT_PTR nLogIdent, int nMsgId = 0,const CUserItem *pUserItem=NULL){}
|
||
|
||
// 添加指定数量的物品,主要用于发系统提示
|
||
virtual VOID OnAddItemById(int itemId, INT_PTR nItemCount, INT_PTR nLogIdent,const CUserItem *pUserItem=NULL){}
|
||
//容器里的数据已经被修改
|
||
virtual VOID OnDataModified() {};
|
||
|
||
//通知客户端一个装备的数据改变了(比SendItemCountChange()更加全面)
|
||
virtual VOID NotifyItemChange(CUserItem *pUserItem) {};
|
||
|
||
protected:
|
||
//将物品叠加到物品容器的现有物品中
|
||
inline INT_PTR OverlapToExists(const ItemOPParam& param, INT_PTR nCount, LPCSTR lpSender, const INT_PTR nLogIdent, BYTE bNoBatchUse = 0);
|
||
protected:
|
||
INT_PTR m_nCapacity; //定义物品容器的容量上限
|
||
bool m_hasDataModify; //数据是否发生了改变
|
||
public:
|
||
std::vector<CUserItem*> m_pUserItemList; //物品信息
|
||
int m_nBagNums; //定义多少物品容器
|
||
std::vector<int> m_BagCostCounts; //所有背包消耗的格数 //1: 背包类型 2:表示用多少
|
||
std::vector<int> m_BagMaxCounts; //所有背包消耗的格数 1:表示最大
|
||
};
|