Files
mir_server/server/LogicServer/property/PropertySet.h
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

541 lines
15 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.

/*
*属性集,玩家的属性的集合
*可以自己定义各种类型的数据类型,包括float,int,uint,long long等
*属性集的修改是4个字节为单位更新到客户端的
*属性可能是各种类型的数据
*
class DATA:
public CPropertySet
{
public:
int a;
int b;
float c;
unsigned d;
long long e;
int max_hp;
struct VVV
{
float x;
unsigned z;
}sVVV;
};
DATA a;
a.SetValue<int>(&a.a,int(23));
a.SetValue<float>(&a.c,float(23.0));
a.SetValue<long long >(&a.e,long long(2312121));
a.SetValue<float>(&a.sVVV.x,float(0.3));
*/
#pragma once
#pragma pack(4)
class CUpdateMask
{
public:
CUpdateMask()
{
ClearUpdateMask();
}
/// 清空修改纪录,将不留纪录
inline void ClearUpdateMask()
{
memset(m_updateMask,0,sizeof(m_updateMask) );
m_nUsedCount =0;
}
inline CUpdateMask & operator &= (CUpdateMask &mask)
{
INT_PTR count = __max(m_nUsedCount,mask.GetUsedCount());
if(count ==0) return *this;
//INT_PTR nIntCount = count >>3 ; //计算有多少个字节
INT_PTR nMaxCount =0;
for(INT_PTR i= 0; i< count; i++ )
{
m_updateMask[i] &= mask[i];
if(m_updateMask[i] && i>= nMaxCount )
{
nMaxCount = i +1;
}
}
m_nUsedCount = nMaxCount;
return *this;
}
/*
*设置第nPos个int是否修改过
* nPos 第几个4字节
* flag flag=true表示修改过,否则去掉这个修改标记
*/
inline void SetUpdateMaskFlag(INT_PTR nPos,bool flag=true)
{
if( IsBitForbidUpdate(nPos) ) return; //如果禁止更新的话
UINT_PTR nBytePos= nPos % 8;
UINT_PTR nByteId = nPos >> 3;
if ((nByteId >= MAX_MASK_BYTE_COUNT) || (nByteId <0)) return;
unsigned char value= 1<< nBytePos;
if(flag) //让其成立
{
m_updateMask[nByteId] |= value;
}
else
{
value = ~value; //取反
m_updateMask[nByteId] &= value; //按位与
}
nByteId ++;
if (m_nUsedCount<nByteId)
{
m_nUsedCount = nByteId;
}
}
inline void SetUpdateMaskFlag(INT_PTR nPos,bool flag,char*pForbitMask)
{
if( IsBitForbidUpdate(pForbitMask,nPos) ) return; //如果禁止更新的话
UINT_PTR nBytePos= nPos % 8;
UINT_PTR nByteId = nPos >> 3;
if ((nByteId >= MAX_MASK_BYTE_COUNT) || (nByteId <0)) return;
unsigned char value= 1<< nBytePos;
if(flag) //让其成立
{
m_updateMask[nByteId] |= value;
}
else
{
value = ~value; //取反
m_updateMask[nByteId] &= value; //按位与
}
nByteId ++;
if (m_nUsedCount<nByteId)
{
m_nUsedCount = nByteId;
}
}
//第nPos个int是否修改过
inline bool GetUpdateMaskFlag(INT_PTR nPos)
{
INT_PTR nBytePos= nPos%8;
INT_PTR nByteId = nPos >> 3;
if ((nByteId >= MAX_MASK_BYTE_COUNT) || (nByteId <0)) return false;
unsigned char value= 1<< nBytePos;
return m_updateMask[nByteId] & value ? true:false;
}
//修改过多少个int
inline UINT_PTR GetUsedCount(){ return m_nUsedCount; }
//获取修改buff的指针
inline unsigned char * GetMaskPtr( ){ return m_updateMask;}
//属性集是否修改过
inline bool HasModified( ){return m_nUsedCount>0;}
inline operator unsigned char * (){return m_updateMask;}
//获取数据的指针,this加上mask的长+使用长度
//设置禁止更新的属性的位
static void SetForbidUpdate(INT_PTR nPos,bool flag)
{
if( s_forbitUpdateMask ==NULL) return ;
INT_PTR nBytePos= nPos%8;
INT_PTR nByteId = nPos >> 3;
if ((nByteId >= MAX_MASK_BYTE_COUNT) || (nByteId <0)) return ;
unsigned char value= 1<< nBytePos;
if(flag) //让其成立
{
s_forbitUpdateMask[nByteId] |= value;
}
else
{
value = ~value; //取反
s_forbitUpdateMask[nByteId] &= value; //按位与
}
}
//某个位置是否禁止更新
inline bool IsBitForbidUpdate(INT_PTR nPos)
{
if( s_forbitUpdateMask ==NULL) return false;
INT_PTR nBytePos= nPos%8;
INT_PTR nByteId = nPos >> 3;
if ((nByteId >= MAX_MASK_BYTE_COUNT) || (nByteId <0)) return false;
unsigned char value= 1<< nBytePos;
return s_forbitUpdateMask[nByteId] & value ? true:false;
}
//设置禁止更新的属性的位
static void SetForbidUpdate(char*pForbitMask, INT_PTR nPos,bool flag)
{
if( pForbitMask ==NULL) return ;
INT_PTR nBytePos= nPos%8;
INT_PTR nByteId = nPos >> 3;
if ((nByteId >= MAX_MASK_BYTE_COUNT) || (nByteId <0)) return ;
unsigned char value= 1<< nBytePos;
if(flag) //让其成立
{
pForbitMask[nByteId] |= value;
}
else
{
value = ~value; //取反
pForbitMask[nByteId] &= value; //按位与
}
}
//某个位置是否禁止更新
inline bool IsBitForbidUpdate(char*pForbitMask, INT_PTR nPos)
{
if( pForbitMask ==NULL) return false;
INT_PTR nBytePos= nPos%8;
INT_PTR nByteId = nPos >> 3;
if ((nByteId >= MAX_MASK_BYTE_COUNT) || (nByteId <0)) return false;
unsigned char value= 1<< nBytePos;
return pForbitMask[nByteId] & value ? true:false;
}
public:
const static int MAX_MASK_BYTE_COUNT = 32; //暂时支持32*8个属性为了在各种机器对齐都有效这里要使用8的倍数
static char s_forbitUpdateMask[MAX_MASK_BYTE_COUNT]; //禁止更新的那些mask位
private:
unsigned char m_updateMask[MAX_MASK_BYTE_COUNT]; //这个是mask的存储地方
UINT_PTR m_nUsedCount ; //已经使用的字节数
//DECLARE_OBJECT_COUNTER(CUpdateMask)
};
//实体属性集合,可以是各种数据,带有一个mask纪录第几个int的值修改过
class CPropertySet:
public CUpdateMask
{
public:
CPropertySet(){} //
/*
设置属性的值,同时会在mask做修改标记
*pos,是这个属性的指针
*value是值
*修改完了会在mask里纪录第几个int的值修改过
*/
template<typename T>
void SetValue( T* pos,CONST T &value)
{
if( *(T *)(pos) == value) return; //没改变
INT_PTR nByteIntervel = (INT_PTR)( (char *)pos- (char*)this - sizeof(CUpdateMask)); //偏移了多少字节
if (nByteIntervel < 0) return ; //计算错误了
*(T *)(pos) = value; //设置值
if( nByteIntervel >0)
{
nByteIntervel = nByteIntervel >>2; //多少个字节
}
SIZE_T size = sizeof(T);
size = __max(size >>2,1); //多少个4字节
for (UINT_PTR i=0; i< size ; i++)
{
SetUpdateMaskFlag(nByteIntervel +i); //
}
}
template<typename T>
inline void SetValue( int nPropertyID,CONST T &value)
{
T * pos = (T*)GetValuePtr(nPropertyID);
SetValue(pos,value);
}
template<typename T>
void SetValue( T* pos,CONST T &value, char*pForbitMask)
{
if( *(T *)(pos) == value) return; //没改变
INT_PTR nByteIntervel = (INT_PTR)( (char *)pos- (char*)this - sizeof(CUpdateMask)); //偏移了多少字节
if (nByteIntervel < 0) return ; //计算错误了
*(T *)(pos) = value; //设置值
if( nByteIntervel >0)
{
nByteIntervel = nByteIntervel >>2; //多少个字节
}
SIZE_T size = sizeof(T);
size = __max(size >>2,1); //多少个4字节
for (UINT_PTR i=0; i< size ; i++)
{
SetUpdateMaskFlag(nByteIntervel +i,true,pForbitMask); //
}
}
template<typename T>
inline void SetValue( int nPropertyID,CONST T &value, char*pForbitMask)
{
T * pos = (T*)GetValuePtr(nPropertyID);
SetValue(pos,value,pForbitMask);
}
//获取属性集第nPos个int的指针
inline const char *GetValuePtr(INT_PTR nPos) const
{
char *ptr= (char*)this + sizeof(CUpdateMask) + ( nPos << 2);
return ptr;
}
inline INT_PTR GetDataIndex(char* pos)
{
INT_PTR nByteIntervel = (INT_PTR)( (char *)pos- (char*)this - sizeof(CUpdateMask)); //偏移了多少字节
return nByteIntervel >>2 ; //在第几个int位置上
}
};
//玩家的属性集,包括 玩家的db数据,1级属性数据
class CActorProperty:
public CPropertySet,
public ENTITYDATA,
public CREATUREDATA,
public ACTORHEADPARTDATA,
public ACTORDBPARTDATA,
public ACTORTAILDATA // 角色尾部数据
{
public:
CActorProperty()
{
memset(this, 0, sizeof(CActorProperty));
}
};
class CActorOfflineProperty:
public ENTITYDATA,
public CREATUREDATA,
public ACTORHEADPARTDATA,
public ACTORDBPARTDATA,
public ACTORTAILDATA
{
public:
CActorOfflineProperty()
{
memset(this,0,sizeof(CActorOfflineProperty));
}
};
static_assert( (sizeof(CActorProperty) - sizeof(CPropertySet))/sizeof(int) == PROP_MAX_ACTOR,
"Actor属性集定义属性长度 与 CActorProperty 枚举长度不一致!");
// 定义玩家自定义数据索引位置,方便离线查找修改
#define ACTORRULE_SPACE 4
#define CAL_ARS(num) (num*ACTORRULE_SPACE)
enum
{
ACTORRULE_PROP_ENTITY_ID = CAL_ARS(0), //实体的id
ACTORRULE_PROP_ENTITY_POSX = CAL_ARS(1), //位置 posx
ACTORRULE_PROP_ENTITY_POSY = CAL_ARS(2), //位置pos y
ACTORRULE_PROP_ENTITY_MODELID = CAL_ARS(3), //实体的模型ID
ACTORRULE_PROP_ENTITY_ICON = CAL_ARS(4), //头像ID
ACTORRULE_PROP_ENTITY_DIR = CAL_ARS(5), //实体的朝向
ACTORRULE_PROP_CREATURE_LEVEL = CAL_ARS(6), //等级
ACTORRULE_PROP_CREATURE_HP = CAL_ARS(7), //
ACTORRULE_PROP_CREATURE_MP = CAL_ARS(8), //
ACTORRULE_PROP_CREATURE_STATE = CAL_ARS(9), //
ACTORRULE_PROP_CREATURE_COLOR = CAL_ARS(10), //
ACTORRULE_PROP_CREATURE_MAXHP = CAL_ARS(11), //
ACTORRULE_PROP_CREATURE_MAXMP = CAL_ARS(12), //
ACTORRULE_PROP_CREATURE_PHYSICAL_ATTACK_MIN = CAL_ARS(13), //
ACTORRULE_PROP_CREATURE_PHYSICAL_ATTACK_MAX = CAL_ARS(14), //
ACTORRULE_PROP_CREATURE_MAGIC_ATTACK_MIN = CAL_ARS(15), //最小魔法攻击
ACTORRULE_PROP_CREATURE_MAGIC_ATTACK_MAX = CAL_ARS(16), //最大魔法攻击
ACTORRULE_PROP_CREATURE_WIZARD_ATTACK_MIN = CAL_ARS(17), //最小道术攻击
ACTORRULE_PROP_CREATURE_WIZARD_ATTACK_MAX = CAL_ARS(18), //最大道术攻击
ACTORRULE_PROP_CREATURE_PYSICAL_DEFENCE_MIN = CAL_ARS(19), //最小物理防御
ACTORRULE_PROP_CREATURE_PYSICAL_DEFENCE_MAX = CAL_ARS(20), //最大物理防御
ACTORRULE_PROP_CREATURE_MAGIC_DEFENCE_MIN = CAL_ARS(21), //最小魔法防御
ACTORRULE_PROP_CREATURE_MAGIC_DEFENCE_MAX = CAL_ARS(22), //最大魔法防御
ACTORRULE_PROP_CREATURE_HITVALUE = CAL_ARS(23), //物理命中
ACTORRULE_PROP_CREATURE_DODVALUE = CAL_ARS(24), //物理闪避
ACTORRULE_PROP_CREATURE_MAGIC_HITRATE = CAL_ARS(25), //魔法命中
ACTORRULE_PROP_CREATURE_MAGIC_DOGERATE = CAL_ARS(26), //魔法闪避
ACTORRULE_PROP_CREATURE_HP_RATE_RENEW = CAL_ARS(27), //HP万分比恢复
ACTORRULE_PROP_CREATURE_MP_RATE_RENEW = CAL_ARS(28), //MP万分比恢复
ACTORRULE_PROP_CREATURE_MOVEONESLOTTIME = CAL_ARS(29), //移动1格需要的时间单位ms
ACTORRULE_PROP_CREATURE_ATTACK_SPEED = CAL_ARS(30), //攻击速度
ACTORRULE_PROP_CREATURE_LUCK = CAL_ARS(31), //幸运
ACTORRULE_PROP_CREATURE_HP_RENEW = CAL_ARS(32), //HP值恢复
ACTORRULE_PROP_CREATURE_MP_RENEW = CAL_ARS(33), //MP值恢复
ACTORRULE_PROP_CREATURE_DIZZY_STATUS = CAL_ARS(34), //麻痹
//预留1000个给老的数据
ACTORRULE_KICK_USER = 1000, //是否踢出玩家byte
ACTORRULE_KICK_USER_FREETIME = 1001, //踢出的玩家可以进入时间
ACTORRULE_CUSTOMTITLE_ID = 1005, // (int)后台 添加/删除 离线玩家自定义称号(添加自定义称号:(+)自定义称号Id删除自定义称号(-)自定义称号Id
};
#define MASK_BACKSTAGE_FORVID 1 //查询标记后台封禁
#define MASK_BACKSTAGE_UNFORVID 2 //查询标记后台解开封禁
class CActorCustomProperty
{
public:
//数据设置
BYTE cbCustomProperty[2048]; //自定规则
CActorCustomProperty()
{
memset(this, 0, sizeof(CActorCustomProperty));
}
};
#define COPY_CUSTOM_PROPERTY(a, b)\
{unsigned int * pDataUint = (unsigned int *)&m_ProCustom.cbCustomProperty[a]; \
*pDataUint = GetProperty<unsigned int>(b); \
}
#define COPY_CUSTOM_PROPERTY_INT(a, b)\
{ int * pDataUint = ( int *)&m_ProCustom.cbCustomProperty[a]; \
*pDataUint = GetProperty<int>(b); \
}
#define ADD_CUSTOM_PROPERTY_BYTE(index, a)\
{ BYTE * pDataUint = ( BYTE *)&m_ProCustom.cbCustomProperty[index]; \
*pDataUint = a; \
}
#define ADD_CUSTOM_PROPERTY_INT(index, a)\
{ int * pDataUint = ( int *)&m_ProCustom.cbCustomProperty[index]; \
*pDataUint = a; \
}
#define ADD_CUSTOM_PROPERTY(index, a)\
{ unsigned int * pDataUint = ( unsigned int *)&m_ProCustom.cbCustomProperty[index]; \
*pDataUint = a; \
}
#define GET_CUSTOM_PROPERTY_INT(a, b)\
{ int * pDataUint = ( int *)&m_ProCustom.cbCustomProperty[a]; \
*pDataUint = GetProperty<int>(b); \
}
//NPC的属性集合
class CNPCProperty:
public CPropertySet,
public ENTITYDATA
{
public:
CNPCProperty()
{
memset(this,0,sizeof(CNPCProperty));
}
};
static_assert( (sizeof(CNPCProperty) - sizeof(CPropertySet))/sizeof(int) == PROP_MAX_ENTITY,
"NPC属性集定义属性长度 与 CNPCProperty 枚举长度不一致!");
//怪物的属性集合
class CMonsterProperty:
public CPropertySet,
public ENTITYDATA,
public CREATUREDATA,
public MONSTERDATA
{
public:
CMonsterProperty()
{
memset(this,0,sizeof(CMonsterProperty));
}
};
static_assert( (sizeof(CMonsterProperty) - sizeof(CPropertySet))/sizeof(int) == PROP_MAX_MONSTER,
"Monster属性集定义属性长度 与 CMonsterProperty 枚举长度不一致!");
//掉落物品的属性集合
class CDropItemProperty:
public CPropertySet,
public ENTITYDATA
{
public:
CDropItemProperty()
{
memset(this,0,sizeof(CDropItemProperty));
}
};
static_assert( (sizeof(CDropItemProperty) - sizeof(CPropertySet))/sizeof(int) == PROP_MAX_ENTITY,
"DropItem属性集定义属性长度 与 CDropItemProperty 枚举长度不一致!");
//传送门的属性集合
class CTransferProperty:
public CPropertySet,
public ENTITYDATA
{
public:
CTransferProperty()
{
memset(this,0,sizeof(CTransferProperty));
}
};
static_assert( (sizeof(CTransferProperty) - sizeof(CPropertySet))/sizeof(int) == PROP_MAX_ENTITY,
"Transfer属性集定义属性长度 与 CTransferProperty 枚举长度不一致!");
//宠物的属性计算器
class CPetProperty:
public CPropertySet,
public ENTITYDATA,
public CREATUREDATA
{
public:
CPetProperty()
{
memset(this,0,sizeof(CPetProperty));
}
};
static_assert( (sizeof(CPetProperty) - sizeof(CPropertySet))/sizeof(int) == PROP_MAX_CREATURE,
"Pet属性集定义属性长度 与 CPetProperty 枚举长度不一致!");
//火的属性集合
class CFireProperty:
public CPropertySet,
public ENTITYDATA
{
public:
CFireProperty()
{
memset(this,0,sizeof(CFireProperty));
}
};
static_assert( (sizeof(CFireProperty) - sizeof(CPropertySet))/sizeof(int) == PROP_MAX_ENTITY,
"Fire属性集定义属性长度 与 CFireProperty 枚举长度不一致!");
// 这个有问题,注意(待添加英雄需求时再处理)
class CHeroProperty:
public CPropertySet,
public ENTITYDATA,
public CREATUREDATA,
public ACTORHEADPARTDATA
{
public:
CHeroProperty()
{
memset(this,0,sizeof(CHeroProperty));
}
};
class CWalkRideProperty:
public CPropertySet,
public ENTITYDATA,
public CREATUREDATA
{
public:
CWalkRideProperty()
{
memset(this, 0, sizeof(CWalkRideProperty));
}
};
#pragma pack()