Files
mir_server/server/LogicServer/item/cnt/UserItemContainer.h

384 lines
15 KiB
C
Raw Normal View History

2025-01-09 17:45:40 +08:00
#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 nLogIdent0
* 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 11
* 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:truefalse
*/
bool CanAddItems( CVector<ItemOPParam> &itemList);
/*
* Comments:
* Param const ItemOPParam & param:
* @Return bool:truefalse
*/
bool CanAddItem(const ItemOPParam& param, bool bNeedCkeckCell = false);
/*
* Comments:
* Param const CUserItem * pUserItem:
* @Return bool:truefalse
*/
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表示最大
};