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

📄 gameautofight.cpp

📁 是一个基于热血战国协议的网络游戏。现在脱机客户端先放出来给大家研究
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			item=m_Game.FindDropedItem(m_Target.ServerId);
			if ( m_Game.isOverEnd(item) ) // 目标物品不存在了
			{
				//m_Game.m_FrameWnd.AddLog(crRed,"目标物品不存在了\n"); 梁健雄 2007-08-19
				m_Target.type=0; // 取消目标
			}
		}
		if ( m_Target.type==0 ) // 有目标嘛?
		{ // 没有
			//m_Game.m_FrameWnd.AddLog(crRed,"找目标\n");
			if ( FindTarget() ) // 找目标
				Path.clear(); // 目标变动 势必清除路径
		}
		bool action=false;
		if ( m_Target.type==1 )
		{ // 怪物
			//m_Game.m_FrameWnd.AddLog(crRed,"怪物\n");
			PreAttack();
			actr=m_Game.FindActor(m_Target.ServerId);
			if ( !m_Game.isOverEnd(actr) )
			{
				//m_Game.m_FrameWnd.AddLog(crGreen,"怪物%s\n",actr->Name.c_str());
				m_Target.pos.x = actr->xx;
				m_Target.pos.y = actr->yy;
				if ( InAttackRange(self,m_Target.pos) )
				{
					//m_Game.m_FrameWnd.AddLog(crGreen,"攻击%s\n",actr->Name.c_str());
					if(DoAttack(m_Target.ServerId,m_Target.pos))
						action=true; // 标记action
				}
			}
			if ( !action )
			{
				// 如果 攻击范围内有目标
				// 切换目标 并 攻击 并 标记action
				if(SwitchTarget())
					if(DoAttack(m_Target.ServerId,m_Target.pos))
						action=true;
			}
		}
		else if ( m_Target.type==2 )
		{ // 地面物品
			//CString str;
			item=m_Game.FindDropedItem(m_Target.ServerId);
			//str.Format("/56451414949456 地面物品%s(%d,%d)",item->Name.c_str(),item->x,item->y);
			m_Game.m_FrameWnd.AddLog(crRed,"地面物品%s(%d,%d)\n",item->Name.c_str(),item->x,item->y);
			//m_Game.m_Action.SendSay(str);
			m_Target.pos.x = item->x;
			m_Target.pos.y = item->y;
			if ( m_Target.pos==self ) // 站在物品上
			{ // 执行捡取 标记action
				m_Game.SendMsg(CM_PICKUP,0,self.x,self.y);
				action=true;
				Sleep(200);
			}
		}
		// 如果没有action 则执行走路
		if ( !action )
		{
			if ( m_Target.type==1 ) // 目标是怪物 因为是活动目标 适用A*寻路
			{
				if ( Path.empty() || !(Path.back()==m_Target.pos) ) //当没有路径 或者目标位置移动
				{
					//m_Game.m_FrameWnd.AddLog(crWhite,"A*寻路\n");梁健雄 2007-08-19
					if( !FindPathAStar(m_Game,self,m_Target.pos,Path) ) // A*计算路径
					{
						//m_Game.m_FrameWnd.AddLog(crRed,"A*寻路失败\n");梁健雄 2007-08-19
						return;
					}
					m_Game.m_FrameWnd.m_wndMap.SetPath(Path);
					DStar.Free(); // 释放D*数据
				}
			}
			else if ( m_Target.type==2 ) // 目标是地面物品 静止目标 适用D*寻路
			{
				POINT tmp;
				DStar.GetTarget(tmp);
				if ( !(tmp==m_Target.pos) )
				{
					//m_Game.m_FrameWnd.AddLog(crWhite,"D*寻路\n");梁健雄 2007-08-19
					//m_Game.m_FrameWnd.AddLog(crRed,"D* Init\n");梁健雄 2007-08-19
					DStar.Init(m_Target.pos.x,m_Target.pos.y);
					Path.clear();
				}
				if ( Path.empty() )
				{
					if ( !DStar.GetPath(self,Path) )
					{
						m_Game.m_FrameWnd.AddLog(crRed,"D*寻路失败\n");
						return;
					}
					m_Game.m_FrameWnd.m_wndMap.SetPath(Path);
				}
			}
			else
			{ // 巡航中
				while(true)
				{
					if ( self==Cruise ) // 到达巡航点
						Cruise=GetCruisePoint();
					POINT tmp;
					DStar.GetTarget(tmp);
					if ( !(tmp==Cruise) ) // D*对应目标不是巡航点
					{
						//m_Game.m_FrameWnd.AddLog(crRed,"D* Init\n");梁健雄 2007-08-19
						DStar.Init(Cruise.x,Cruise.y);
						Path.clear();
					}
					if ( Path.empty() ) // 如果路径没有被建立
					{
						if ( DStar.GetPath(self,Path) ) // 路径被成功搜索
						{
							//m_Game.m_FrameWnd.AddLog(crRed,"D* GetPath%d\n",__LINE__);梁健雄 2007-08-19
							m_Game.m_FrameWnd.m_wndMap.SetPath(Path);
							break;
						}
						Cruise=GetCruisePoint(); // 重新设置巡航点
					}
					else
					{
						break;
					}
				}
			}
			//在路径中查找英雄当前所在点
			std::vector<POINT>::iterator pos=std::find(Path.begin(),Path.end(),self);
			action=false;
			POINT next;
			if(pos!=Path.end()) // 是否找到
			{
				pos++;
				if(pos!=Path.end()) // 是否最后一个节点
				{
					next=*pos;
					BYTE dir=GetDirect(self,next);
					if( (dir&0xf0)==0 )
					{
						bool run=((dir>>3)!=0);
						dir&=7;
						if(run)
						{
							if( m_Game.CanRun(self,dir) )
							{
								action=true;
								m_Game.m_Action.SendRun(dir);
							}
							else
							{
								pos++;
								if ( m_Target.type==1 && m_Game.CanWalk(self,dir) && pos!=Path.end() ) //如果是怪物
								{
									// A*的终点就是目标怪物的坐标
									// 所以当终点不可及时 一般认为目标怪物就在那
									// 所以 走过去
									action=true;
									m_Game.m_Action.SendWalk(dir);
								}
							}
						}
						else
						{
							if( m_Game.CanWalk(self,dir) )
							{
								action=true;
								m_Game.m_Action.SendWalk(dir);
							}
						}
					}
				}
			}
		}
		if(action)
		{
			while(!m_Game.m_Action.CanAction() 
				&& m_EnableAutoFight )	// add by zdl. 2007-10-15
				Sleep(50);
		}
		else
		{
			Sleep(100);
			//说明我们的英雄已经偏离了路线 或者路原来的路径上被人站了 重新查找路径
			Path.clear();
		}
	}

	TRACE0("_AutoFightThread execute complete\n");
	//DWORD w,h;
	//m_Game.m_Map.GetSize(w,h);
	//POINT target;
	//m_EnableAutoFight=true;
	//m_HasNewActor=true;
	//if ( !m_Game.m_Action.CanWideHit() )
	//{
	//	itClientMagic magic=m_Game.FindMagic("半月弯刀");
	//	if ( magic!=m_Game.m_Magics.end() )
	//	{
	//		m_Game.m_Action.SendSpell(CM_SPELL,0,0,magic->Def.MagicId,0);
	//		while ( !m_Game.m_Action.CanAction() )
	//		{
	//			Sleep(10);
	//		}
	//	}
	//}
	//if ( !m_Game.m_Action.CanLongHit() )
	//{
	//	itClientMagic magic=m_Game.FindMagic("刺杀剑术");
	//	if ( magic!=m_Game.m_Magics.end() )
	//	{
	//		m_Game.m_Action.SendSpell(CM_SPELL,0,0,magic->Def.MagicId,0);
	//		while ( !m_Game.m_Action.CanAction() )
	//		{
	//			Sleep(10);
	//		}
	//	}
	//}
	//while ( m_EnableAutoFight )
	//{
	//	do 
	//	{
	//		target.x=(rand()*w)/RAND_MAX;
	//		target.y=(rand()*h)/RAND_MAX;
	//	} while( !m_Game.m_Map.TestMap(target.x,target.y) );
	//	MoveAndFight(target); // 边走边打
	//}
}

/*
=======================================================================
函数名       : MoveAndFight
功能描述     : 
参数         : const POINT& target 
返回值       : void
=======================================================================
*/
//void CAutoFight::MoveAndFight( const POINT& target )
//{
//	// 初始化D*
//	CDStar DStar(m_Game.m_Map,m_Game);
//	std::string CurrentMap=m_Game.m_Map.get_MapName();
//	std::vector<POINT> Path;//路径
//	u64 retval=DStar.Init(target.x,target.y);
//	POINT start;
//	POINT next;
//	bool action;
//	if(retval==0) // DStar初始化失败
//		return;
//	while ( m_EnableAutoFight )
//	{
//		// 找怪 打怪循环
//		while(FindTarget())
//		{
//			Fight();
//		}
//		start.x=m_Game.m_Self.xx;
//		start.y=m_Game.m_Self.yy;
//		if ( start==target ) // 到达目的地
//			return;
//		if ( CurrentMap!=m_Game.m_Map.get_MapName() ) //地图变动
//			return;
//		if ( Path.empty() )
//		{
//			if ( !DStar.GetPath( start, Path ) )
//				return;
//			m_Game.m_FrameWnd.m_wndMap.SetPath(Path);
//		}
//		//在路径中查找英雄当前所在点
//		std::vector<POINT>::iterator pos=std::find(Path.begin(),Path.end(),start);
//		action=false;
//		if(pos!=Path.end()) // 是否找到
//		{
//			pos++;
//			if(pos!=Path.end()) // 是否最后一个节点
//			{
//				next=*pos;
//				for(BYTE i=0;i<8;i++)
//				{
//					POINT search;
//					search.x=start.x+xofs_walk[i];
//					search.y=start.y+yofs_walk[i];
//					if(m_Game.CanMove(search.x,search.y))
//					{
//						if( search==next )
//						{
//							action=true;
//							m_Game.m_Action.SendWalk(i);
//							break;
//						}
//						search.x+=xofs_walk[i];
//						search.y+=yofs_walk[i];
//						if(m_Game.CanMove(search.x,search.y))
//						{
//							if( search==next )
//							{
//								action=true;
//								m_Game.m_Action.SendRun(i);
//								break;
//							}
//						}
//					}				
//				}
//			}
//		}
//		if(action)
//		{
//			while(!m_Game.m_Action.CanAction())
//				Sleep(50);
//		}
//		else
//		{
//			Sleep(100);
//			//说明我们的英雄已经偏离了路线 或者路原来的路径上被人站了 重新查找路径
//			Path.clear();
//		}
//	}
//}
//
//
//////////////////////////////////////////////////////////////////////////
// 战士版本
//////////////////////////////////////////////////////////////////////////

/*
=======================================================================
函数名       : InAttackRange
功能描述     : 是否在攻击范围
参数         : const POINT& self
参数         : const POINT& target
返回值       : bool
=======================================================================
*/
bool CAutoFightWarrior::InAttackRange(const POINT& self, const POINT& target)
{
	return ((GetDirect(self,target)&0xf0)==0);
}

/*
=======================================================================
函数名       : DoAttack
功能描述     : 攻击
参数         : DWORD ServerId
参数         : const POINT& Position
返回值       : bool
=======================================================================
*/
bool CAutoFightWarrior::DoAttack(DWORD ServerId, const POINT& Position)
{
	POINT self;
	self.x = m_Game.m_Self.xx;
	self.y = m_Game.m_Self.yy;
	BYTE dir=GetDirect(self,Position);
	if( (dir&0xf0)==0 ) // 如果目标在攻击范围 算上刺杀位
	{
		CGameAction & ActionMgr=m_Game.m_Action;
		bool run=((dir>>3)!=0);
		dir&=7;
		if(run!=0) // 在刺杀位
		{
			if ( ActionMgr.CanLongHit() ) // 刺杀打开了吗?
			{
				ActionMgr.SendHit(dir,CM_LONGHIT);
				return true;
			}
		}
		else
		{
			if ( ActionMgr.CanFireHit() )
			{
				ActionMgr.SendHit(dir,CM_FIREHIT);
				m_Game.m_FrameWnd.AddLog(crYellow,"烈火\n");
				return true;
			}
			else if ( ActionMgr.CanPowerHit() ) // 可以攻杀
			{
				ActionMgr.SendHit(dir,CM_POWERHIT);
				return true;
			}
			else
			{
				int mcnt=1;
				if (!m_Game.isOverEnd(HasMonster[(dir-1)&7]))
					mcnt++;
				if (!m_Game.isOverEnd(HasMonster[(dir+1)&7]))
					mcnt++;
				if (!m_Game.isOverEnd(HasMonster[(dir+2)&7]))
					mcnt++;
				if ( m_Game.m_Self.Ability.Mp>10			// MP够
					//&& ActionMgr.CanWideHit()				// 半月打开
					&& m_Game.m_Sets.AutoWideHit			// 自动半月选中
					&& mcnt>=m_Game.m_Sets.WideHitLevel  )  // 怪物数目符合
				{
					ActionMgr.SendHit(dir,CM_WIDEHIT); // 半月
					return true;
				}
				else if ( m_Game.m_Sets.AlwaysLongHit && ActionMgr.CanLongHit() ) // 刀刀刺杀打开
				{
					ActionMgr.SendHit(dir,CM_LONGHIT); // 刺杀
					return true;
				}
				else
				{
					ActionMgr.SendHit(dir,CM_HEAVYHIT); // 平砍
					return true;
				}
			}
		}
	}
	return false;
}

/*
=======================================================================
函数名       : PreAttack
功能描述     : 
参数         : void
返回值       : void
=======================================================================
*/
void CAutoFightWarrior::PreAttack(void)
{
	POINT self;
	self.x = m_Game.m_Self.xx;
	self.y = m_Game.m_Self.yy;
	BYTE dir;
	for ( int i=0; i<0x10; i++ ) HasMonster[i] = m_Game.m_ActorList.end();
	for ( itActor pos = m_Game.m_ActorList.begin(); pos != m_Game.m_ActorList.end(); pos++ )
	{
		if ( pos->Type!=AT_Monst ) continue;
		POINT tp;
		tp.x=pos->xx;
		tp.y=pos->yy;
		dir=GetDirect(self,tp);
		if( (dir>>4)==0 )
		{
			dir&=0xf;
			HasMonster[dir]=pos;
		}
	}
}

/*
=======================================================================
函数名       : SwitchTarget
功能描述     : 选择目标
参数         : void
返回值       : bool
=======================================================================
*/
bool CAutoFightWarrior::SwitchTarget(void)
{
	return false;
}

/*
=======================================================================
函数名       : FindTarget 
功能描述     : 寻找目标
参数         : void
返回值       : bool
=======================================================================
*/
bool CAutoFightWarrior::FindTarget()
{
	m_Target.type=0; //清除目标
	if ( !m_HasNewActor )
		return false;
	CGameDStar star(m_Game.m_Map,m_Game);
	if(star.Init(m_Game.m_Self.xx,m_Game.m_Self.yy,1)==0) // 步行距离
	{
		m_Game.m_FrameWnd.AddLog(crGreen,"DStar初始化失败\n");
		return false;
	}
	long targetDist = MAXLONG ;
	itActor actor;
	for ( itActor pos=m_Game.m_ActorList.begin(); pos!=m_Game.m_ActorList.end(); pos++ ) // 遍历actors
	{
		if ( pos->Type!=AT_Monst ) continue;
		//if ( pos->Death ) continue;
		long dist=star.GetDist(pos->xx,pos->yy);
		if ( dist<targetDist )
		{
			m_Target.type=1;
			m_Target.ServerId=pos->ServerId;
			m_Target.pos.x=pos->xx;
			m_Target.pos.y=pos->yy;
			actor=pos;

			targetDist=dist;
		}
	}

	// modify by zdl. 2007-10-17
	// purpose: 当设置为”捡物品”时,则执行“捡物品”动作

	if ( m_Game.m_Sets.PickItem )	
	{
		for ( itDropedItem pos = m_Game.m_DropedItems.begin(); pos != m_Game.m_DropedItems.end(); pos++ ) // 遍历DropedItems
		{
			long dist=star.GetDist(pos->x,pos->y);
			if ( dist<targetDist )
			{
				m_Target.type=2;
				m_Target.ServerId=pos->ServerId;
				m_Target.pos.x=pos->x;
				m_Target.pos.y=pos->y;

				targetDist=dist;
			}
		}
	}

	// end of add


	if ( m_Target.type == 0 )
	{
		m_HasNewActor=false;
		return false;
	}
	if ( m_Target.type == 1 )
	{
        m_Game.m_FrameWnd.SetTarget(actor);
		m_Game.m_FrameWnd.m_wndLeftView.SetTarget(actor);
		m_Game.m_FrameWnd.m_wndMap2.SetTarget(actor);
	}
	return true;
}

/*
=======================================================================
函数名       : GetCruisePoint
功能描述     : 
参数         : void
返回值       : POINT
=======================================================================
*/
POINT CGameAutoFight::GetCruisePoint(void)
{
	POINT Cruise;
	DWORD w,h;
	m_Game.m_Map.GetSize(w,h);
	do 
	{
		Cruise.x=(rand()*w)/RAND_MAX;
		Cruise.y=(rand()*h)/RAND_MAX;
	} while( !m_Game.m_Map.TestMap(Cruise.x,Cruise.y) );
	return Cruise;
}

⌨️ 快捷键说明

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