Files

716 lines
18 KiB
C
Raw Permalink Normal View History

2025-01-09 17:45:40 +08:00

#pragma once
/***************************************************************/
/*
/* 实体
/*
/***************************************************************/
class CObserverSystem;
class CMovementSystem;
class CBuffSystem;
class CUserBag;
class CQuestSystem;
class CAnimal;
//class CEntitySystem;
#include <list>
// 实体脚本回调参数结构定义
#define MAX_SCRIPT_FUN_NAME_LEN 40
// 实体传送类型
enum EntityTransferStype
{
etsTeleport, // 通过传送门传送
etsOther, // 其他方式传送
};
class OwnedBabyInfo
{
public:
EntityHandle m_handle; // 宝宝句柄
bool m_bWatch; // 是否监控此宝宝。宝宝被监控后,属性变化会同步到客户端
};
class ScriptCallbackParam : public Counter<ScriptCallbackParam>
{
public:
ScriptCallbackParam()
{
init(0, 0, 0, 0, 0, "", 0);
}
void init (unsigned int handle, unsigned int nNpdId, unsigned int nDelay, unsigned int nInterval, int nCount, const char *pszName, const CScriptValueList *paramList)
{
if (!pszName || strlen(pszName) > MAX_SCRIPT_FUN_NAME_LEN)
return;
m_nHandle = handle;
m_nNpcId = nNpdId;
m_nDelayTime = nDelay;
m_nInterval = nInterval;
m_nCount = nCount;
_asncpyt(m_szScriptFn, pszName);
if (paramList)
{
m_paramList = *paramList;
}
}
unsigned int m_nNpcId; // 目标NPCID
unsigned int m_nHandle; // 事件句柄
unsigned int m_nDelayTime; // 第一次执行的延迟时间(ms为单位
unsigned int m_nInterval; // 两次执行间隔时间(ms为单位)
int m_nCount; // 执行次数
TICKCOUNT m_nNextHitTime; // 下一次执行的触发时间
CScriptValueList m_paramList; // 脚本参数列表
char m_szScriptFn[MAX_SCRIPT_FUN_NAME_LEN+1]; // 回调函数名称
};
//tolua_begin
class CEntity
{
public:
CEntity()
: m_hTest(Uint64(-1))
, m_hEntityHandler(0)
, m_targetHandler(0)
{
m_sEntityName[0] = 0;
m_entityPos.nSceneId = 0;
m_entityPos.pFb = NULL;
m_entityPos.pScene = NULL;
m_isInited = false;
m_sTitle[0] = 0;
m_nTraceFlag = 0;
m_nMaxFollowDistSqrt = 0;
m_bHasClearMarkedMsg = false;
#ifndef ENTITY_MANAGER_USE_STL_MAP
m_pNode =NULL;
#endif
m_boIsDestroy = false;
m_showName[0] = 0;
m_race = 0;
m_idx = 0;
}
~CEntity ()
{
m_sEntityName[0]=0;
m_isInited =false;
m_entityPos.nSceneId = 0;
m_entityPos.pFb = NULL;
m_entityPos.pScene = NULL;
m_sTitle[0] = 0;
m_boIsDestroy = false;
}
//实体初始化
virtual bool Init(void * data, size_t size);
//销毁实体
virtual void Destroy();
/*
线
*/
inline VOID RunOne(TICKCOUNT nCurrentTime)
{
BeforeLogicRun(nCurrentTime);
LogicRun(nCurrentTime);
AfterLogicRun(nCurrentTime);
}
//例行逻辑准备函数,当例行逻辑函数调用前被调用
virtual VOID BeforeLogicRun(TICKCOUNT nCurrentTime);
//例行逻辑处理函数
virtual VOID LogicRun(TICKCOUNT nCurrentTime);
//例行逻辑收尾函数,当例行逻辑函数调用后被调用
virtual VOID AfterLogicRun(TICKCOUNT nCurrentTime);
//获取属性集的指针
virtual CPropertySet* GetPropertyPtr() {return NULL;}
virtual const CPropertySet* GetPropertyPtr() const {return NULL;}
//获取属性集数据部分的长度
virtual INT_PTR GetPropertySize() const =0;
inline const char* GetPropertyDataPtr() const
{
const CPropertySet* set = GetPropertyPtr();
if(set ==NULL) return NULL;
return set->GetValuePtr(0);
}
/*
*nPropIDid
*value :
*/
virtual void OnEntityDeath(); //当实体死亡的时候
// nUpdateVal: 变化值
virtual void OnLevelUp(int nUpdateVal){}; //升级的时候
//向实体发送消息
void _PostEntityMsg(const CEntityMsg &msg,LPCSTR file, INT_PTR line);
#define PostEntityMsg(msg) _PostEntityMsg(msg,__FILE__, __LINE__)
//删除实体消息
INT_PTR DeleteEntityMsg(const INT_PTR nMsg);
// 删除延迟删除消息
void ClearDelayDelEntityMsg();
//向实体发送消息,如果存在同消息号的消息则更新原有消息
void UpdateEntityMsg(const CEntityMsg &msg);
//处理实体消息
virtual void ProcessEntityMsg(const CEntityMsg &msg);
/*
* Comments:
* @Return : truefalse
*/
inline bool IsDeath()
{
if(isAnimal())
{
return GetProperty<unsigned int>(PROP_CREATURE_HP) ==0;
}
else
{
return false;
}
}
//获取动态变量
inline CCLVariant& GetDynamicVar(){ return m_DynamicVar; }
/*
* Comments:
* Param unsigned int nLevel: 37
* @Return VOID:
*/
VOID SetLevel(unsigned int nLevel);
VOID SetIndex(int nIdx){ m_idx = nIdx; }
int GetIndex(){ return m_idx; }
//当属性发生调用的时候使用
//template < class T>
//void OnPropertyChange(int nPropID, const T& oldValue, const T& value);
void OnPropertyChange(int nPropID, UINT64 oldValue, UINT64 value);
/*
* Comments:
* Param int nValue:11-1
* @Return VOID:
*/
inline VOID ChangeLevel(int nValue)
{
if(nValue ==0) return;
nValue += GetProperty<unsigned int>(PROP_CREATURE_LEVEL );
nValue = __max(0,nValue); //不能少于0
SetLevel(nValue);
}
/*
*nPropIDid
*/
virtual int GetPropertySetTotalSize()const =0;
//virtual int GetPropertySetTotalSize()const {return 0;}
template < class T>
inline T GetProperty(int nPropID) const
{
T temp=0;
//int totalSize = GetPropertySetTotalSize();
//int offset = sizeof(CUpdateMask) + (nPropID << 2);
//DbgAssert(offset < totalSize);
const CPropertySet* set = GetPropertyPtr();
if(set ==NULL) return temp;
return *(T*)set->GetValuePtr(nPropID);
}
virtual char * GetForbitMask() {return CUpdateMask::s_forbitUpdateMask;}
template < class T>
inline void SetProperty(int nPropID, const T& value)
{
T oldValue = GetProperty<T>(nPropID);
if(oldValue == value )return;
CPropertySet* set = GetPropertyPtr();
if(set ==NULL) return ;
#ifdef _DEBUG
static const int ENTITYDATA_Size = sizeof(ENTITYDATA);
static const int CREATUREDATA_Size = sizeof(CREATUREDATA);
static const int MONSTERDATA_Size = sizeof(MONSTERDATA);
int totalSize = GetPropertySetTotalSize();
int maskSize = sizeof(CUpdateMask);
int offset = (nPropID << 2);
int realSize = totalSize - maskSize;
assert(offset < realSize);
#endif
set->SetValue(nPropID,value,this->GetForbitMask());
OnPropertyChange(nPropID,(UINT64)oldValue,(UINT64)value);
}
//基础属性的读取
inline LPCSTR GetEntityName() const {return m_sEntityName;}
void SetEntityName(const char * name);
//设置、获取称号
inline LPCSTR GetTitle() const {return m_sTitle;}
inline void SetTitle(char * name)
{
if(name ==NULL) return;
_asncpytA( m_sTitle,name );
}
inline VOID GetPosition(int &x, int &y) const
{
x = GetProperty<int>(PROP_ENTITY_POSX);
y = GetProperty<int>(PROP_ENTITY_POSY);
}
inline VOID GetPosition(INT_PTR &x, INT_PTR &y) const
{
x = GetProperty<int>(PROP_ENTITY_POSX);
y = GetProperty<int>(PROP_ENTITY_POSY);
}
bool getPosRangeByDir(INT_PTR &nX, INT_PTR &nY, INT_PTR &nDir, INT_PTR nRange) const;
inline const ENTITYPOS& GetPosInfo() const {return m_entityPos; }
inline WORD GetSceneID() const { return m_entityPos.nSceneId; }
inline CFuBen* GetFuBen() const {return m_entityPos.pFb;}
inline CScene* GetScene() const {return m_entityPos.pScene; };
inline void SetSceneID(WORD nSceneID) { m_entityPos.nSceneId = nSceneID; }
inline VOID SetFuBen(CFuBen* pFb) { m_entityPos.pFb = pFb;}
inline void SetPosInfo(ENTITYPOS & posInfo){m_entityPos = posInfo;}
//获取实体所处的场景对象指针
inline void SetScene(CScene* pScene) {m_entityPos.pScene = pScene;}
inline void SetPosition(int x, int y)
{
SetProperty<int>(PROP_ENTITY_POSX,x);
SetProperty<int>(PROP_ENTITY_POSY,y);
}
inline unsigned int GetId()const
{
return GetProperty<unsigned int>(PROP_ENTITY_ID);
}
inline INT_PTR GetType() const {return m_hEntityHandler.GetType();}
inline const EntityHandle& GetHandle() const {return m_hEntityHandler;}
//是指
inline void SetHandle (EntityHandle hHandle)
{
m_hEntityHandler =hHandle;
}
inline VOID SetInitFlag(bool flag){m_isInited = flag;}
inline bool IsInited() const {return m_isInited ;}
inline void SetDestroyFlag(bool boflag) {m_boIsDestroy = boflag;}
inline bool IsDestory() const {return m_boIsDestroy;}
inline virtual CUpdateMask * GetBroadCastMask() {return NULL;} //获取广播的mask
//判断是否是非生物
inline bool isNonLive()
{
switch(GetType())
{
case enTransfer:
case enFire:
case enDropItem:
return true;
}
return false;
}
//判断是否是Animal
inline bool isAnimal()
{
switch(GetType())
{
case enActor:
case enPet:
case enMonster:
case enGatherMonster:
case enHero:
return true;
}
return false;
}
/*
* Comments:
* @Return bool: truefalse
*/
inline bool IsMonster()
{
switch(GetType())
{
case enMonster:
case enGatherMonster:
return true;
}
return false;
}
//是否是英雄
inline bool IsHero()
{
switch(GetType())
{
case enHero:
return true;
}
return false;
}
//是否攻击免疫
inline bool IsAttackImmune()
{
switch(GetType())
{
case enGatherMonster:
return true;
default:
return false;
}
}
//判断是否是NPC
inline bool isNPC()
{
switch(GetType())
{
case enNpc:
return true;
}
return false;
}
//判断是否要push到人物观察列表中
inline bool PushActorAppear()
{
if (IsMonster())
{
return true;
}
switch(GetType())
{
case enNpc:
case enHero:
case enPet:
return true;
}
return false;
}
//获取目标实体的handle
inline const EntityHandle& GetTarget() const {return m_targetHandler; }
//设置目标实体的handle
void SetTarget(const EntityHandle& handle) ;
//还是设置实体目标
/*
* Comments:
* Param LPCSTR sSceneName:
* Param INT_PTR nPosX:x
* Param INT_PTR nPsY:y
* @Return bool:true,false
*/
bool TelportSceneByName(LPCSTR sSceneName,INT_PTR nPosX,INT_PTR nPsY, int nType = 0);
/*
* Comments:
* Param LPCSTR sSceneName:
* Param INT_PTR nPointID:ID0
* @Return bool: truefalse
*/
bool TelportSceneDefaultPoint(LPCSTR sSceneName,INT_PTR nPointID);
/*
* Comments:
* Param CEntity * pEntity:
* Param int nType :
* Param int nValue :
* Param int nDest:
* @Return bool: truefalse
*/
bool MoveToEntity(CEntity * pEntity, int nType = 0, int nValue = 0, int nDest = 0 );
/*
* Comments:
* Param CEntity * pEntity:
* @Return INT_PTR:
*/
inline INT_PTR GetEntityDistanceSquare(CEntity * pEntity)
{
if(pEntity ==this) return 0;
if(pEntity ==NULL) return 100000;
if(GetSceneID() != pEntity->GetSceneID())
{
return 100000;
}
int nPosX, nPosY;
pEntity->GetPosition(nPosX,nPosY); //获取实体的坐标
int nSelfPosX, nSelfPosY;
GetPosition(nSelfPosX,nSelfPosY); //自身的坐标
return (nSelfPosX - nPosX)* (nSelfPosX - nPosX) + (nSelfPosY - nPosY)* (nSelfPosY - nPosY);
}
/*
* Comments:
* Param CFuben* pFb:
* Param INT_PTR nSceneID:id
* Param INT_PTR nPosX:x
* Param nPosY:y
* @Return bool: true,false
*/
bool Teleport(CFuBen* pFB,INT_PTR nSceneID, INT_PTR nPosX,INT_PTR nPosY);
/*
* Comments:
* Param INT_PTR nDir: 0
* @Return void:
*/
void SetDir(INT_PTR nDir =-1);
/*
* Comments:,
* Param CEntity * pTarget:
* @Return INT_PTR:
*/
INT_PTR GetTargetDir(CEntity * pTarget);
/*
* Comments:
* Param CEntity * pOther:
* @Return bool:true
*/
bool IsInSameScreen(CEntity* pOther);
/*
* Comments: 2
* Param INT_PTR nSourceX: x
* Param INT_PTR nSourceY: y
* Param INT_PTR nTargetX: x
* Param INT_PTR nTargetY: y
* @Return INT_PTR:
*/
static INT_PTR GetDir(INT_PTR nSourceX, INT_PTR nSourceY, INT_PTR nTargetX, INT_PTR nTargetY);
/*
* Comments:
* Param void * pTargetNPC: NPC对象指针,
* Param unsigned int nDelayTime:
* Param unsigned int nInterval:
* Param int nCount:
* Param const char * pszFuncname:
* Param const CScriptValueList &args
* @Return unsigned int: SCB句柄0
*/
unsigned int RegScriptCallback(unsigned int nNpcId, unsigned int nDelayTime, unsigned int nInterval, int nCount, const char *pszFuncname, const CScriptValueList &args);
/*
* Comments:
* Param unsigned int handle:
* @Return void:
*/
void UnregScriptCallback(unsigned int handle);
/*
* Comments:
* Param const char * pFnName:
* @Return void:
*/
void UnregScriptCallback(const char *pFnName);
/*
* Comments:
* Param INT_PTR nIdx:
* @Return void:
*/
void OnScriptCallback(INT_PTR nIdx);
//设置怪物的属性标志位
inline void SetAttriFlag(const EntityFlags flag)
{
m_attriFlag = flag;
}
inline EntityFlags& GetAttriFlag() { return m_attriFlag; }
void Say(MonsterSayBCType nStyle, const char *pMsg);
// 实体Trace标记相关定义
enum EntityTraceType
{
ettActorSkillDamage = 0x00000001, // 输出玩家对别人的技能伤害
ettActorBeSkillDamage = 0x00000010, // 输出对玩家的技能伤害
};
inline void SeEntityTraceFlag(EntityTraceType nType, bool bSet)
{
if (bSet)
m_nTraceFlag |= nType;
else
m_nTraceFlag &= ~nType;
}
inline bool GetEntityTraceFlag(EntityTraceType nType)
{
return ((m_nTraceFlag & nType) != 0) ? true : false;
}
/*
* Comments:
* Param unsigned int nMaxDist:
* @Return void:
*/
inline void SetMaxFollDist(unsigned int nMaxDist) { m_nMaxFollowDistSqrt = nMaxDist * nMaxDist; }
#ifndef ENTITY_MANAGER_USE_STL_MAP
//设置在实体管理器里的Node
inline void SetNode (CList<CEntity*>::NodeType * pNode){m_pNode = pNode; }
inline CList<CEntity*>::NodeType * GetNode () {return m_pNode;}
#endif
/*
* Comments:
* Param CFuBen * pFB:
* Param INT_PTR nSceneID: ID
* Param INT_PTR nPosX: X坐标
* Param INT_PTR nPosY:Y坐标
* Param INT_PTR nOwnerSceneId: Owner所在场景Id
* Param INT_PTR nOwnerPosX: Owner地位置X坐标
* Param INT_PTR nOwnerPosY:Owner地位置Y坐标
* Param EntityTransferStype transStype:
* @Return void:
* @Remark:
*/
void TeleportOwnedEntity(CFuBen *pFB,
INT_PTR nSceneID,
INT_PTR nPosX,
INT_PTR nPosY,
INT_PTR nOwnderSceneId,
INT_PTR nOwnerPosX,
INT_PTR nOwnerPosY,
EntityTransferStype transStype);
//显示显示的名字
inline LPCTSTR GetShowName(){return m_showName;}
//设置显示的名字
inline void SetShowName( LPCTSTR name )
{
if(name ==NULL) return ;
_asncpytA(m_showName,name);
}
/*
* Comments:
* Param CEntity * pEntity:
* @Return bool: truefalse
* @Remark:
*/
virtual bool CanSee(CEntity* pEntity);
/**
pTarget实体
*/
void Face2Target(CEntity* pTarget);
protected:
/*
* Comments:
* @Return void:
*/
void ProcessScriptCallback();
/*
* Comments:
* @Return void:
*/
void ClearScriptCallback();
/*
* Comments:
* @Return void:
* @Remark:
*/
void ClearAllEntityMsg();
/*
* Comments:
* @Return void:
*/
void PostEntityDeadMsg();
protected:
char m_sEntityName[64]; //所有的长度用玩家名字的长度
char m_showName[160]; //显示的名字,玩家显示的名字 名字\\帮派\\帮派排名其他NPC可能改玩家的名字
ENTITYPOS m_entityPos;
// TODO 待修改
Uint64 m_hTest; //这里是为了解决 宠物的句柄m_hEntityHandler被修改的bug这里再提供一段8字节内存以替代被修改的句柄。
EntityHandle m_hEntityHandler; //实体句柄
bool m_isInited ; //是否初始化好了
bool m_boIsDestroy; //实体是否正在释放
//种族用于图腾怪等客户端需要特殊处理的怪物配置entityType为普通怪物race为特别的种类如果不配置或者为0的话使用entityType的值
//否则的话表示怪物里的种族方便客户端显示比如15表示图腾怪,以及其他后面其他方便扩展的其他怪物
BYTE m_race; //种族
int m_idx; //如果创建多个相同的实体可以区别不同的idx
EntityHandle m_targetHandler; //实体的目标的句柄
CList<CEntityMsg*> m_EntityMsgList; //实体消息队列
CCLVariant m_DynamicVar; //实体动态变量
ACTORNAME m_sTitle; //实体的称号,如“铁匠”“商人”等
CVector<ScriptCallbackParam*> m_scriptCBList; // 脚本回调列表
CTimer<1000> m_t1s;
EntityFlags m_attriFlag; //怪物的属性标志位,怪物刚创建,默认就是配置表的设置,可由程序动态修改
int m_nTraceFlag; // 实体Trace标记
unsigned int m_nMaxFollowDistSqrt; // 最大跟随距离的平方
#ifndef ENTITY_MANAGER_USE_STL_MAP
CList<CEntity*>::NodeType *m_pNode;
#endif
bool m_bHasClearMarkedMsg; // 标记是否有标记位Delete的消息需要清楚
static CActorProperty * m_defaultProperty; //一个默认的属性器
DECLARE_OBJECT_COUNTER(CEntity)
};
//tolua_end