Files

637 lines
20 KiB
C
Raw Permalink Normal View History

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

#pragma once
/***************************************************************/
/*
/* 动物,继承于生物动物有Buff系统背包系统观察者子系统,移动子系统
/*
/***************************************************************/
//附加的战斗属性,放在这里,便于管理
struct CreatureBattleProp
{
int m_selfAttackAppend; ///< 技能攻击的时候 攻击伤害追加n点以固定值的方式影响角色造成的内功与外功攻击伤害
float m_deductDamagePower; //伤害低扣倍率
int m_nAddPhysicalDamageRate; ///< 物理攻击时候附加物理攻击输出的概率,整数1点表示万分之一
int m_nAddPhysicalDamageValue; ///< 物理攻击时附加攻击输出的数值增加
int m_hp2MpRate; ///< 护身效果
unsigned int m_nDizzyValue; ///< 麻痹的概率单位1%
unsigned int m_nDeductDizzyValue; ///< 抗麻痹概率,万分比
unsigned int m_nDizzyTimeAdd; ///< 麻痹时长增加 万分比
unsigned int m_nDizzyTimeAbsorbAdd; ///< 麻痹时长减免 万分比
unsigned int m_nGuardRate; ///< 守护概率,万分比
unsigned int m_nGuardValue; ///< 守护值
unsigned int m_nCuttingRate; ///< 切割概率,万分比
unsigned int m_nDoubleAtkRate; ///< 倍攻率,万分比
int m_DieRefreshHpPro; ///< 死亡以后立刻回复的HP的比例,1点表示百分之1(复活戒指使用)
TICKCOUNT m_nextHpReliveCd; ///< 下一个死亡复活的cd时间
WORD m_nFireDefenseRate; ///< 抗火率 使用1点表示1万分之1
float m_fDamgeAbsorbRate; ///< 伤害减免比例
int m_nWarriorTargetDamageValue; //固定值增加对战士的伤害
int m_nWarriorTargetDamageRate; //百分比增加对战士的伤害
int m_nMagicianTargetDamageValue; //固定值增加对法师的伤害
int m_nMagicianTargetDamageRate; //固定比增加对法师的伤害
int m_nWizardTargetDamageValue; //固定值增加对道士的伤害
int m_nWizardTargetDamageRate; //固定比增加对法师的伤害
int m_nMonsterTargetDamageValue; //固定值增加对怪物的伤害
int m_nMonsterTargetDamageRate; //固定比增加对怪物的伤害
unsigned int m_nAddAllDamageRate; //全职业攻击伤害追加概率
unsigned int m_nAddAllDamageRateEx; //会心一击追加概率
unsigned int m_nCritDamageRate; //新版暴击几率万分比区别于m_nAddAllDamageRate
unsigned int m_nCritDamageValue; //新版暴击力,int
unsigned int m_nCritDamagePower; ///新版暴击倍率 万分比 int
unsigned int m_nDeductCritDamageRate; //抗暴
float m_fAddAllDamagePower; //全职业攻击时附加攻击输出的倍率增加
unsigned int m_nDamageReboundRate; //伤害反弹 概率
float m_fDamageReboundPower; //伤害反弹 倍率
int m_nIgnorDefenceRatio; //无视防御的比例
int m_nDamageAbsorbRatio; //伤害减免 比例 ---暂时没用
int m_nPkDamageAbsorbRatio; //pk伤害减免 比例
int m_nSuckBloodRatio; //吸血比例
int m_nSaviorTime; //救主灵刃-CD时间
int m_nSaviorRate; //救主灵刃-回复率
int m_nSaviorValue; //救主灵刃-回复值
int m_nToxicRate; //剧毒裁决-淬毒几率
int m_nToxicDamage; //剧毒裁决-淬毒伤害
int m_nToxicEffect; //剧毒裁决-效果
int m_nFrozenStrength; //冰冻强度
int m_nHpRenewAdd; //生命恢复值增加
CreatureBattleProp()
{
memset(this,0,sizeof(*this));
}
};
#ifdef _DEBUG
extern std::string s_HurtValueMsg;
extern char s_HurtValueBuff[100];
#endif
static LPCTSTR szJZLRCDTime = "JZLRCDTime"; //救主灵刃CD时间
static const int nJZBuffId = 244;
class CAnimal:
public CCreature,
public CreatureBattleProp
{
public:
typedef CCreature Inherited;
static const int BATTLE_LEFT_TIME = 10000; ///< 战斗脱离时间
CAnimal():Inherited()
{
m_pAI =NULL;
m_stateMask =0;
m_attackInterval =0; ///< 攻击的间隔,这个是不会改的,不作为属性
m_maxDropHp =0; ///< 每次掉的最大的血
m_nCamp =0;
m_nAttackType =0;
m_battleLeftTime =0;
m_killHandler =0;
m_AttackerHandler = 0;
m_GuildId = 0;
m_nAttackLevel =1; ///< 攻击优先级
m_MonsterDieHpPro = 0;
m_nDizzyBuffInterval = 0;
m_nDizzyTime = 0;
m_nJZLRCDTime = 0;
m_nToxicAttckValue = 0;
m_nSZASAttckValue = 0;
}
bool Init(void * data, size_t size); ///< 初始化
inline CObserverSystem* GetObserverSystem() {return &m_observerSystem;} ///< 获取观察者子系统
inline CMovementSystem* GetMoveSystem() {return &m_moveSystem;} ///< 获取移动子系统
inline CBuffSystem * GetBuffSystem() {return &m_buffSystem ;} ///< Buff子系统
inline CSkillSubSystem & GetSkillSystem() {return m_skillSystem;} ///< 获取技能子系统
inline CPropertySystem &GetPropertySystem() {return m_propertySystem;} ///< 属性子系统
inline CEffectSystem & GetEffectSystem() {return m_effectSystem;} ///< 特效子系统 TO DELETE
inline void Destroy()
{
ClearAllEntityMsg();
m_observerSystem.Destroy();
m_moveSystem.Destroy();
m_propertySystem.Destroy();
m_buffSystem.Destroy();
m_skillSystem.Destroy();
DestroyAi();
m_effectSystem.Destroy();
Inherited::Destroy();
}
//设置汇总处理标记
inline void CollectOperate(const CEntityOPCollector::CollecteOPType eType)
{
m_OPCollector.Collect(eType);
}
//进行一项汇总收集的操作
virtual VOID DoCollectedOperation(CEntityOPCollector::CollecteOPType eOPType);
/******* 覆盖父类的函数集 *******/
//例行逻辑准备函数,当例行逻辑函数调用前被调用
virtual VOID BeforeLogicRun(TICKCOUNT nCurrentTime);
//例行逻辑处理函数
virtual VOID LogicRun(TICKCOUNT nCurrentTime);
//例行逻辑收尾函数,当例行逻辑函数调用后被调用
virtual VOID AfterLogicRun(TICKCOUNT nCurrentTime);
//处理实体消息
void ProcessEntityMsg(const CEntityMsg &msg);
//TODELETE 能否攻击 pPet:如果存在则target为主人
bool _CanAttack(CAnimal *pTargetEntity, CAnimal *pPet=NULL, bool boAttackNotice = true);
//能否攻击
bool CanAttack(CAnimal *pTargetEntity, CAnimal * = NULL, bool = true);
bool IsFriend(CAnimal *pTargetEntity);
/*
* Comments: HP
* Param int nValue:
* @Return VOID:
*/
virtual void ChangeHP(int nValue,CEntity * pKiller=NULL,bool bIgnoreDamageRedure=false, bool bIgnoreMaxDropHp=false, bool boSkillResult = false, int btHitType = 0);
/*
* Comments:MP
* Param int nValue:
* @Return VOID:
*/
virtual VOID ChangeMP(int nValue);
//当等级提升的时候
virtual void OnLevelUp(int nUpdateVal);
virtual void OnEntityDeath();
//复活
virtual void OnEntityRelive();
/*
* Comments:
* Param CEntity * pKillerEntity:
* @Return void:
*/
virtual void OnKilledByEntity(CEntity * pKillerEntity)
{
if(pKillerEntity && pKillerEntity->IsInited())
{
m_killHandler = pKillerEntity->GetHandle();
}
}
//获取一个bool 标记位,免得写很多垃圾代码
inline static bool GetFlag(unsigned int nValue,int nBitId)
{
return (nValue & (0x1 << nBitId) ) ? true:false;
}
//设置一个bit位
template<class T>
inline static void SetFlag(T &nValue,int nBitId,bool flag)
{
T newValue;
if(flag)
{
newValue = (T)(0x1 << nBitId);
nValue |= newValue;
}
else
{
newValue = (T)(~(0x1 << nBitId));
nValue &= newValue;
}
}
//重刷一下状态的禁止位
inline void RefreshStateMask()
{
if( CAnimal::s_stateForbidMask ==NULL) return;
m_stateMask =0;
for(INT_PTR i =0 ; i < esMaxStateCount; i++)
{
if(HasState(i))
{
m_stateMask |= CAnimal::s_stateForbidMask[i];
}
}
}
/*
* Comments:
* Param INT_PTR nStateID:ID
* @Return bool:truefalse
*/
inline bool HasState(INT_PTR nStateID)
{
if(nStateID <0 || nStateID >=esMaxStateCount) return false;
return !!(GetProperty<unsigned int>(PROP_CREATURE_STATE) & (0x1 << nStateID) );
}
/*
* Comments:
* Param INT_PTR nStateID:id
* @Return bool:true,false
*/
inline bool AddState(INT_PTR nStateID)
{
if(nStateID <0 || nStateID >=esMaxStateCount) return false;
if(HasState(nStateID) ) return false; //已经有这个状态了
unsigned int nMask = 0x1 << nStateID;
nMask |= GetProperty<unsigned int>(PROP_CREATURE_STATE);
SetProperty<unsigned int>(PROP_CREATURE_STATE,nMask);
RefreshStateMask();
if(nStateID == esStateBattle)
{
OnEnterBattle();
}
return true;
}
//进入战斗状态
void OnEnterBattle();
/*
* Comments:
* Param INT_PTR nStateID: truefalse
* @Return bool:truefalse
*/
inline bool RemoveState(INT_PTR nStateID)
{
if(nStateID <0 || nStateID >=esMaxStateCount) return false;
if(!HasState(nStateID ) ) return false; //没有这个状态
unsigned int nMask = 0x1 << nStateID;
nMask =~ nMask; //取反
nMask &= GetProperty<unsigned int>(PROP_CREATURE_STATE);
SetProperty<unsigned int>(PROP_CREATURE_STATE,nMask);
RefreshStateMask();
return true;
}
/*
* Comments:
* @Return bool:truefalse
*/
inline bool RemoveDizzyState()
{
SetProperty<unsigned int>(PROP_CREATURE_DIZZY_STATUS,0);
RefreshStateMask();
return true;
}
/*
* Comments:
* @Return bool:truefalse
*/
inline bool SetDizzyState()
{
int nValue = GetProperty<unsigned int>(PROP_CREATURE_DIZZY_STATUS);
if(nValue <= 0)
nValue = 10000;
nValue--;
SetProperty<unsigned int>(PROP_CREATURE_DIZZY_STATUS,nValue);
RefreshStateMask();
return true;
}
//麻痹状态
inline bool GetDizzyState()
{
return GetProperty<unsigned int>(PROP_CREATURE_DIZZY_STATUS);
}
//获取阵营的id
inline int GetCampId()
{
if(GetType() == enActor)
{
return GetProperty<UINT>(PROP_ACTOR_ZY);
}
else
{
return m_nCamp;
}
}
void SetCamp(int nCampId);
inline void SetNpcGuildId(unsigned int nGuildId) {m_GuildId = nGuildId;}
inline unsigned int GetNpcGuildId() {return m_GuildId;}
//获取AI的指针
inline CAnimalAI * GetAI()
{
return m_pAI;
}
//被别人攻击 bSetVest:是否设置归属
virtual void OnAttacked(CAnimal * pEntity, bool bSetVest=true);
//攻击别人 bChgDura:是否改变装备耐久
virtual void OnAttackOther(CAnimal * pEntity, bool bChgDura=true);
//取附近的玩家列表
void GetNearActorList(CVector<EntityHandle> &vecEntityList);
//取场景的玩家的列表
void GetSceneActorList(CScene *pScene, CVector<EntityHandle> &vecEntityList);
//取副本的玩家列表
void GetFubenActorList(CVector<EntityHandle> &vecEntityList);
//世界的玩家列表
void GetWorldActorList(CVector<EntityHandle> &vecEntityList);
//获取阵营的玩家的列表
void GetCampActorList(CVector<EntityHandle> &vecEntityList);
/*
* Comments:
* Param MonsterSayBCType nStyle:
* Param const char * pMsg:
* Param tagTipmsgType tipType:
* Param nLimitLev:
* @Return void:
*/
void Say(MonsterSayBCType nStyle, const char *pMsg, int tipType = ttChatWindow, unsigned int nLimitLev = 0);
/*
* Comments:
* Param INT_PTR nTime:
* @Return void:
*/
inline void PostponeRefViewTime(INT_PTR nTime){ m_tRefViewTimer.SetNextHitTimeFromNow(nTime); }
//初始化状态静止表
static void InitStateForbidMask();
//消耗状态表
static void DestroyStateForbidMask();
//能否进入一个状态,状态定义在enum tagEntityState定义
inline bool CanEnterState(INT_PTR nStateID)
{
return !GetFlag(m_stateMask,(int)nStateID);
}
/*
* Comments: ,
* Param TICKCOUNT nTick:
* Param bool bFailSendmsg:
* Param bool bMoveOp:
* @Return bool: true,false
*/
bool CheckCommonOpTick(TICKCOUNT nTick, bool bFailSendmsg =true, bool bMoveOp = false);
// 玩家的m_tOpsTimer因未知原因导致数值极大从而造成发射技能在公共CD检查时失败
bool CheckCommonOpTickBefore(TICKCOUNT nTick);
/*
* Comments:
* Param INT_PTR nNextTime:
* Param bool bSendResult2Client:
* Param bool bResult:
* Param unsigned int nStep: 0
* Param unsigned int nSendPkgTick:
* Param bool bUseGateTime: true表明是使用网关收到数据包时间来对时使
* Param bool bUseCheckCd: cd
* Param bool bNearAttackSuc:
* @Return void:
*/
void SetCommonOpNextTime(INT_PTR nNextTime,bool bSendResult2Client =false,bool bResult =true,
unsigned int nStep = 0,
unsigned int nSendPkgTick = 0,
bool bUseGateTime = true,
bool bUseCheckCd=true,
bool bNearAttackSuc = true);
void DestroyAi();
//怪物重用时,重置所有相关属性
virtual void Reuse();
/*
* Comments:
* @Return int:
*/
inline int GetAttackLevel()
{
return m_nAttackLevel;
}
//设置攻击等级 攻击等级,用于决定怪物被攻击的优先等级,玩家是100等级越高的越容易被攻击数值没有上限
inline void SetAttackLevel(int nLevel)
{
m_nAttackLevel = nLevel;
}
/*
* Comments:
* Param unsigned int nMsgIdx:
* Param int nParam1:
* Param int nParam2:
* Param int nParam3:
* Param int nParam4:
* Param int nParam5:
* @Return void:
* @Note:
*/
virtual void OnEntityScriptDelayMsgCallback(unsigned int nMsgIdx, int nParam1, int nParam2, int nParam3, int nParam4, int nParam5){}
inline void SetObserverSysNextHitTime(TICKCOUNT nTickCount)
{
//m_tRefViewTimer.SetNextHitTime(nTickCount);
}
inline int GetDistance(int nPosX,int nPosy)
{
int nCurPosx,nCurPoyY;
GetPosition(nCurPosx,nCurPoyY);
nCurPosx -= nPosX;
nCurPoyY -= nPosy;
double nDis = nCurPosx*nCurPosx + nCurPoyY * nCurPoyY;
return (int)(sqrt (nDis));
}
//////////////////////////////////下面这些函数是战斗用的
//设置获取攻击间隔
inline void SetAttackInterval(int nInterval){m_attackInterval = nInterval;}
inline int GetAttackInterval(){return m_attackInterval;}
//设置和读取每次掉落的maxHP
inline int GetMaxDropHp() {return m_maxDropHp; }
inline void SetMaxDropHp(int nValue){ m_maxDropHp = nValue; }
/*
* Comments:
* @Return float:
*/
inline float GetDeductDamagePower()
{
return m_deductDamagePower;
}
/*
* Comments:
* Param float rate:
* @Return void:
*/
inline void SetDeductDamagePower(float rate)
{
m_deductDamagePower = rate;
}
//设置/获取 物理攻击时候附加物理攻击输出的概率,整数1点表示万分之一
// inline void SetAddPhysicalDamageRate(int nValue) {m_nAddPhysicalDamageRate =nValue;}
// inline int GetAddPhysicalDamageRate() {return m_nAddPhysicalDamageRate ;}
//设置/获取 物理攻击时附加攻击输出的数值增加
// inline void SetAddPhysicalDamageValue(int nValue) {m_nAddPhysicalDamageValue =nValue;}
// inline int GetAddPhysicalDamageValue() {return m_nAddPhysicalDamageValue ;}
//血转换为蓝的比例
inline void SetHp2MpRate( int nValue) {m_hp2MpRate =nValue; }
inline int GetHp2MpRate () { return m_hp2MpRate;}
inline float GetFastMedicamentRenew()
{
return (((float)GetProperty<int>(PROP_ACTOR_MEDIC_RENEW))/10000.0);
}
//更改名字
void ChangeName(const char* sName);
void ChangeShowName(int nRadius, LPCTSTR sName);
/*
* Comments:
* Param int nRadius:
* Param int nModelId:id
* @Return void:
*/
void ChangeModel(int nRadius, int nModelId);
//获取攻击类型
inline int GetAttackType() { return m_nAttackType; }
//设置攻击类型
void SetAttackType(int nType,bool bNeedBroadCast =false);
//获取离开战斗的时间
inline TICKCOUNT GetLeftBattleTickCount(){return m_battleLeftTime;}
//设置击杀自己的人的handle
inline void SetKillerHandler(EntityHandle hd)
{
m_killHandler = hd;
}
//获取杀死者的指针
inline EntityHandle& GetKillHandle( ) {return m_killHandler;}
void SetDizzyTime(int time);
inline void SetAttackerHandler(EntityHandle hd) { m_AttackerHandler = hd; }
inline EntityHandle& GetAttackerHandle( ) {return m_AttackerHandler;}
//更新救主灵刃特效以及当前CD时间
void UpdateJZLR();
/*
* Comments:
* Param INT_PTR nAttackType:
* @Return int:
*/
int GetAttackValue(INT_PTR nAttackType);
//死亡以后立刻回复的HP的比例
void SetDieRefreshHpPro(int nValue) {m_MonsterDieHpPro = nValue;}
//获取公共操作下一次tick
TICKCOUNT GetCommonOpTick(){return m_tOpsTimer.GetNextTime();}
//发送复活戒指的db时间
void SendReliveRingCd();
private:
virtual int getLeaveCombatTime() { return BATTLE_LEFT_TIME; }
void postponeLeaveCombatTimer();
public:
//状态禁
static unsigned int *s_stateForbidMask; //
int m_nAttackType; //攻击类型
unsigned int m_nDizzyBuffInterval; //麻痹间隔时间
TICKCOUNT m_nDizzyTime; //麻痹时间
int m_nJZLRCDTime;
int m_nToxicAttckValue;//剧毒裁决造成的绝对值伤害
int m_nSZASAttckValue;//霜之哀伤造成的绝对值伤害
protected:
CObserverSystem m_observerSystem; // 观察者子系统
CMovementSystem m_moveSystem; //移动的子系统
CPropertySystem m_propertySystem; //属性子系统
CBuffSystem m_buffSystem; //Buff子系统
CEntityOPCollector m_OPCollector; //汇总操作记录对象
CSkillSubSystem m_skillSystem; //技能子系统
CEffectSystem m_effectSystem; //特效子系统
CTimer<2000> m_t2s ; //回蓝回血定时器
CTimer<500> m_t500ms ; //500ms定时器
CTimer<1000> m_t1S; //1秒定时器
CTimer<700> m_tRefViewTimer;//观察者系统刷新定时器
CTimer<3000> m_tKfRefViewTimer;//跨服观察者系统刷新定时器
CTimer<3000> m_t3sInner; //内劲恢复
CAnimalAI * m_pAI; //怪物的AI指针
unsigned int m_stateMask; //状态禁止的模板
CTimer<1000> m_tOpsTimer; //公共操作的定时器
TICKCOUNT m_battleLeftTime; //战斗状态的进入状态
//下面这些是战斗中用到的,不想每个都是以属性做,集中到一起
int m_nAttackLevel; // 战斗等级
int m_attackInterval; //攻击间隔
int m_maxDropHp; //最大的掉落的hp,默认是0
int m_nCamp; // 阵营Id
unsigned int m_GuildId; //设置行会id
int m_MonsterDieHpPro; //死亡以后立刻回复的HP的比例,1点表示百分之1(针对怪物用的)
EntityHandle m_killHandler; //击杀者的指针
EntityHandle m_AttackerHandler; //攻击自己的动物指针
};