⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 npc.h

📁 网络游戏魔域的服务端与客户端完整源代码 包括详细的说明文档与开发日志
💻 H
字号:
// Npc.h: interface for the CNpc class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_NPC_H__6093FC28_BAC7_4C65_AF21_721F11F1C975__INCLUDED_)
#define AFX_NPC_H__6093FC28_BAC7_4C65_AF21_721F11F1C975__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "GameObj.h"
#include "Timeout.h"
#include "NpcType.h"
#include "I_MapData.h"
#include "I_Role.h"
#include "MsgWalk.h"
#include "NpcGenerator.h"
#include "AutoPtr.h"
#include "item.h"

//////////////////////////////////////////////////////////////////////
//const int	ITEMSORT_WEAPON2				=	5;	// 双手武器
//const int	DWEAPON_BOW					=	00000;// 弓

//////////////////////////////////////////////////////////////////////
const int	THINK_SECS					= 1;		// 休息状态时每3秒侦察一下周围
const int	DORMANCY_SECS				= 60;		// 周围无PLAYER时,60秒休眠
const int	SHORTWEAPON_RANGE_LIMIT		= 2;		// 近身武器的最大攻击范围(以此范围是否弓箭手)
const int	NPC_CLIMBCAP				= 26;		// NPC爬山的能力(高度差)
const int	GUARD_LEAVEDISTANCE			= 48;		// 卫兵放弃追杀的距离
const int	PKKILLER_JUMPDISTANCE		= 6;		// 触发卫兵跳的距离
const int	RANDOMMOVE_RATE				= 5;		// NPC休闲时随机走动的频度为1/20
const int	GUARD_RANDOMMOVE_RATE		= 5;		// 卫兵休闲时随机走动的频度为1/10
const int	SIMPLEMAGIC_RECRUIT			= 1020;		// 加血魔法

//////////////////////////////////////////////////////////////////////
enum {	ATKUSER_LEAVEONLY				= 0,				// 只会逃跑
		ATKUSER_PASSIVE					= 0x0001,				// 被动攻击
		ATKUSER_ACTIVE					= 0x0002,				// 主动攻击
		ATKUSER_RIGHTEOUS				= 0x0004,				// 正义的(卫兵或玩家召唤和控制的怪物)
		ATKUSER_GUARD					= 0x0008,				// 卫兵
		ATKUSER_PPKER					= 0x0010,				// 追杀黑名
		ATKUSER_JUMP					= 0x0020,				// 会跳
		ATKUSER_FIXED					= 0x0040,				// 不会动的
		ATKUSER_FASTBACK				= 0x0080,				// 速归
		ATKUSER_LOCKUSER				= 0x0100,				// 锁定攻击指定玩家,玩家离开自动消失
		ATKUSER_LOCKONE					= 0x0200,				// 锁定攻击首先攻击自己的玩家
		ATKUSER_ADDLIFE					= 0x0400,				// 自动加血
		ATKUSER_EVIL_KILLER				= 0x0800,				// 白名杀手
		ATKUSER_WING					= 0x1000,				// 飞行状态
		ATKUSER_NEUTRAL					= 0x2000,				// 中立的
		ATKUSER_ROAR					= 0x4000,				// 出生时全地图怒吼
		ATKUSER_NOESCAPE				= 0x8000,				// 不会逃跑
		ATKUSER_EQUALITY				= 0x00010000,				// 不藐视
};
const int	ATKUSER_NO_DORMANCY				= ATKUSER_LOCKUSER;

//////////////////////////////////////////////////////////////////////
enum { OWNER_NONE, OWNER_USER, OWNER_SYN, OWNER_NPC };

//////////////////////////////////////////////////////////////////////
class CNetMsg;
class CNpc : public CGameObj, INpc
{ 
public:
	CNpc();
	virtual ~CNpc();
	static CNpc*	CreateNew()			{ return new CNpc; }
	void			OnTimer();
	virtual bool	Create(OBJID idNpc, int nType, OBJID idMap, int nPosX, int nPosY, OBJID idGenerator, OBJID idOwner, int nOwnerType, int nData);
	void		ReleaseByOwner()		{ delete this; }
	IRole*		QueryRole()				{ return (IRole*)this; }
	IRoleAttr*	QueryRoleAttr()			{ return static_cast<IRoleAttr*>(this); }
	virtual CAutoLink<IRole>&	QueryLink(const CAutoLink<IRole>&)				{ return m_lnkThis; }
	template<TYPENAME T>
		T*		QueryInterface(T** ppT=NULL)	{ if(ppT) *ppT = this; return this; }
	virtual void*	QueryInterface(int id, void** ppT)	{ void* p=NULL; if(id==GUID_OF(CNpc)) p=this; if(ppT) *ppT=p; return p; }

public: // get info
	OBJID		GetID()				{ return m_id; }
	OBJID		GetType()			{ return m_pType->GetID(); }
	LPCTSTR		GetStr(NPCTYPEDATA idx)	{ return m_pType->GetStr(idx); }
	int			GetInt(NPCTYPEDATA idx)	{ return m_pType->GetInt(idx); }
public: // get
	int			GetLife()			{ return m_nCurrLife; }
	int			GetPower()			{ return m_nCurrPower; }
	OBJID		GetMapID();
	CGameMap*	GetMap()			{ return m_pMap; }
	int			GetPosX()			{ return m_nPosX; }
	int			GetPosY()			{ return m_nPosY; }
	int			GetDir()			{ return m_nDir; }
	IGenerator* 	GetGenerator()			{ return m_pGenerator; }
	int			GetAttackRange(int nSizeAdd)			{ return GetInt(NPCTYPEDATA_ATKRANGE)+(GetSizeAdd()+nSizeAdd+1)/2; }
	int			GetSizeAdd()		{ return GetInt(NPCTYPEDATA_SIZEADD); }
	I64			GetEffect()			{ return m_i64Effect; }
	int			GetOwnerID()		{ return m_idOwner; }
public:
	bool		IsMonster()			{ return !IsSynPet() && !IsGuard() && !IsPkKiller() && !IsEvilKiller(); }
	bool		IsSynPet()			{ return m_nOwnerType == OWNER_SYN; }
	bool		IsOpposedSyn(OBJID idSyn);
	bool		IsLurker()			{ return 0; }
	bool		IsDormancy()		{ return (m_nActMode == MODE_DORMANCY); }
	bool		IsAlive()			{ return !m_bDie && m_nCurrLife > 0 && (GetEffect()&KEEPEFFECT_DIE) == 0; }
	bool		IsFarWeapen()		{ return GetInt(NPCTYPEDATA_ATKRANGE) > SHORTWEAPON_RANGE_LIMIT; }
	bool		IsRighteous()		{ return (GetInt(NPCTYPEDATA_ATKUSER) & ATKUSER_RIGHTEOUS) != 0; }
	bool		IsEvil()			{ return (GetInt(NPCTYPEDATA_ATKUSER) & (ATKUSER_RIGHTEOUS|ATKUSER_NEUTRAL)) == 0; }
	bool		IsGuard()			{ return (GetInt(NPCTYPEDATA_ATKUSER) & ATKUSER_GUARD) != 0; }
	bool		IsPkKiller()		{ return (GetInt(NPCTYPEDATA_ATKUSER) & ATKUSER_PPKER) != 0; }
	bool		IsActiveEnable()	{ return (GetEffect() & (KEEPEFFECT_NOT_ACTIVE)) == 0; }	// 可以动作(非冻结)
	bool		IsMoveEnable()		{ return IsActiveEnable() && (IsWalkEnable() || IsJumpEnable()); }
	bool		IsWalkEnable()		{ return (GetInt(NPCTYPEDATA_ATKUSER) & ATKUSER_FIXED) == 0; }
	bool		IsJumpEnable()		{ return (GetInt(NPCTYPEDATA_ATKUSER) & ATKUSER_JUMP) != 0; }
	bool		IsFastBack()		{ return (GetInt(NPCTYPEDATA_ATKUSER) & ATKUSER_FASTBACK) != 0; }
	bool		IsLockUser()		{ return (GetInt(NPCTYPEDATA_ATKUSER) & ATKUSER_LOCKUSER) != 0; }
	bool		IsLockOne()			{ return (GetInt(NPCTYPEDATA_ATKUSER) & ATKUSER_LOCKONE		) != 0; }
//	bool		IsFighterFirst()	{ return (GetInt(NPCTYPEDATA_ATKUSER) & ATKUSER_FIGHTER_FIRST) != 0; }
//	bool		IsWizardFirst()		{ return (GetInt(NPCTYPEDATA_ATKUSER) & ATKUSER_WIZARD_FIRST) != 0; }
//	bool		IsBowmanFirst()		{ return (GetInt(NPCTYPEDATA_ATKUSER) & ATKUSER_BOWMAN_FIRST) != 0; }
	bool		IsAddLife()			{ return (GetInt(NPCTYPEDATA_ATKUSER) & ATKUSER_ADDLIFE		) != 0; }
	bool		IsEvilKiller()		{ return (GetInt(NPCTYPEDATA_ATKUSER) & ATKUSER_EVIL_KILLER	) != 0; }
	bool		IsDormancyEnable()	{ return (GetInt(NPCTYPEDATA_ATKUSER) & ATKUSER_NO_DORMANCY	) == 0; }
	bool		IsWing()			{ return (GetInt(NPCTYPEDATA_ATKUSER) & ATKUSER_WING		) != 0; }
	bool		IsBowman()			{ int nType=GetInt(NPCTYPEDATA_WEAPONR_TYPE); return ((nType%10000000)/100000) == ITEMSORT_WEAPON2 && ((nType%100000)/1000)*1000 == DWEAPON_BOW; }
	bool		IsSimpleMagicAtk()	{ return GetInt(NPCTYPEDATA_MAGIC_TYPE) != ID_NONE && GetInt(NPCTYPEDATA_MAGIC_TYPE) != SIMPLEMAGIC_RECRUIT; }
	bool		IsCloseAttack()		{ return !IsBowman() && !IsSimpleMagicAtk(); }
	virtual bool		IsBlockNpc()								{ return (GetEffect() & KEEPEFFECT_NOT_BLOCKNPC) == 0; }
//	bool		IsAttackEnable(IRole* pRole);
	bool		IsEscapeEnable()	{ return (GetInt(NPCTYPEDATA_ATKUSER) & (ATKUSER_NOESCAPE)) == 0; }
public: // modify
	void		JumpPos(int nPosX, int nPosY, int nDir);
//	void		SetStatus(int nStatus)			{ m_nStatus = nStatus; }
	void		SetDir(int nDir)				{ m_nDir = nDir; }
	bool		IsAttackEnable(IRole* pTarget);

public: // set (call by msguserattrib)
	void		SetLife(int nLife)				{ m_nCurrLife = nLife; }
	void		SetPower(int nPower)			{ m_nCurrPower = nPower; }
	void		SetEffect(I64 i64Effect)		{ m_i64Effect = i64Effect; }
	void		SetSizeAdd(int nSizeAdd)		{}		// can't change npc size_add
	void		SetDie()						{ if(m_bDie) return; m_bDie = true; m_pGenerator->DeleteNpc(this->GetID()); }

public: // application
	bool		PathMove(int nMode);
	bool		MoveForward(int nDir, int nMode);
	bool		SynchroPos(int nSourX, int nSourY, int nTargX, int nTargY);
	bool		KickBack(int nTargX, int nTargY);
	void		SetPos(int nPosX, int nPosY);
	void		Attack();
	void		AttackOnce()					{ m_bAttackFlag = true; }
	bool		CheckTarget();				// 检查当前TARGET是否有效。同时修改m_idActTarget
	bool		FindNewTarget();
	bool		JumpBlock(int x, int y, int dir);
	bool		FarJump(int x, int y, int dir);
	void		LockMove(int nMilliSecs);

public: // change mode
	bool		ChangeMode(int nMode);			// return false : 失败
	void		WakeUp()						{ m_tDormancy.Update(); if(IsDormancy()) ChangeMode(MODE_IDLE); }
	void		BeAttack(IRole* pRole);
	void		BeKill(IRole* pRole)			{ ChangeMode(CNpc::MODE_IDLE); }
	bool		ProcessEscape();
	bool		ProcessAttack();
	bool		ProcessForward();
	bool		ProcessIdle();
	bool		CheckDormancy();

public: // socket
	bool		SendMsg(CNetMsg* pMsg);
	bool		SendMsg(LPCTSTR szMsg);

public: // static
	int			Distance(int x, int y)			{ return __max(abs(x-GetPosX()), abs(y-GetPosY())); }

public:	// others
	virtual bool		IsActive();
	virtual bool		Lock(bool bLock)							{ m_bLocked	= bLock; return true; }
	virtual bool		IsLocked()									{ return m_bLocked; }
protected:
	bool		m_bLocked;

//////////////////////////////////////////////////////////////////////////////////////////
protected: // info
	OBJID		m_id;
	CNpcType*	m_pType;

protected: // attrib
	int			m_nCurrLife;
	int			m_nCurrPower;
	CAutoLink<IRole>	m_lnkThis;

public:
	enum NPC_MODE { MODE_DORMANCY=0, MODE_IDLE, MODE_WALK, MODE_GOTO, MODE_TALK, MODE_FOLLOW, MODE_ESCAPE, MODE_FORWARD, MODE_ATTACK,  };
protected: // action
	int			m_nActMode;		// enum { attack,escape,talk,follow,goto,idle,dormancy };
								// 设置dormancy时,同时设置地图CELL的dormancy标志。由玩家消息驱动清除标志。

	OBJID		m_idMoveTarget;	// 移动但不攻击的目标ID,为了“吸引”状态而增加的,
								// 如果m_idActTarget!=ID_NONE,则一定与m_idMoveTarget相同
	OBJID		m_idActTarget;	// 攻击目标ID
	CTimeOut	m_tAction;		// 用于IDLE和ATTACK时延时

protected: // state
	int			m_nPosX, m_nPosY;
	I64			m_i64Effect;			// enum { STATUS_NORMAL=0, STATUS_FREEZE, STATUS_DIE };
	int			m_nDir;
	int			m_nPose;
	CMapPtr		m_pMap;
	CTimeOut	m_tDormancy;

protected: // fight
	CTimeOutMS	m_tMove;			// 用于控制走路的频率
	OBJID		m_idAtkMe;			// 由对方填写,自己清除
	bool		m_bAtkFirst;		// 主动攻击
	bool		m_bAttackFlag;		// 游戏服务器返回了攻击动作

protected: // pet
	int			m_nOwnerType;
	OBJID		m_idOwner;

protected: // append attribute
	CAutoPtr<IGenerator> 	m_pGenerator;		// 指向NPC发生器,与发生器的计数器同步
	bool		m_bDie;

protected: // path ////////////////////////////////////////////////////////////////////////////
	bool		FindPath(int nEscapeSteps = 0);
	bool		FindPath(int x, int y, int nEscapeSteps = 0);
	bool		DetectPath(int nNoDir);		// -1: 全允许
	bool		TestPath(int nDir);
	void		ClearPath()				{ m_nPathLen = 0; }
protected:
	POINT		m_posTarget;
	bool		m_bAheadPath;
	int			m_nPathLen;
	char		m_bufPath[_MAX_PATHSTEP];
};


#endif // !defined(AFX_NPC_H__6093FC28_BAC7_4C65_AF21_721F11F1C975__INCLUDED_)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -