#include "stdafx.h"
#include "CAction.h"

namespace GameAssist
{
#define SETGAMEFOREGROUND AutoThreadSection ats(&m_ts);\
if (!::IsWindow(m_hGameWnd)) return;\
::ShowWindow(m_hGameWnd, SW_SHOWNORMAL);\
::SetForegroundWindow(m_hGameWnd);\
SRAND(80,120);

	std::map<std::string, POINT> g_mapZYNPC;
	std::map<std::string, PNPC> g_mapZYNPC2;

	// 使用快捷键来处理：读取配置文件
	auto FindJNShortCut = [](LPCTSTR lpSkillName, int& nKeyValue, int& nSkilltime)->BOOL {
		// 读取文件：jnmap.bin
		// 格式：技能=快捷键的键值;
		std::string line;
		std::ifstream ifJN("img\\jnmap.bin");
		if (ifJN)
		{
			TCHAR szKeyValue[MAX_PATH] = { 0 };
			TCHAR szSkillName[MAX_PATH] = { 0 };
			TCHAR szSkillTime[MAX_PATH] = { 0 };
			while (std::getline(ifJN, line))
			{
				int nRet = _stscanf_s(line.c_str(), _T("%[^;];%[^;];%s"), szSkillName, MAX_PATH, szKeyValue, MAX_PATH, szSkillTime, MAX_PATH);
				if (nRet == 3 && _tcsicmp(lpSkillName, szSkillName) == 0) {
					// 将快捷键值
					nKeyValue = atol(szKeyValue);
					nSkilltime = atol(szSkillTime);
					return TRUE;
				}
			}
		}

		// 没有找到jnmap.bin文件;
		return FALSE;
	};


	ThreadSection CAction::m_ts;
	CAction::CAction(HWND hWnd) :m_hGameWnd(hWnd), m_ptCur({ 0,0 })
	{
		m_hBattleJY = NULL;
		m_hBattleJYEvent = NULL;
		m_hBattleZYTZ = NULL;
		m_nSkillShortcutKey = VK_F1;
		InitNPCInfo();
	}

	CAction::~CAction()
	{
	}

	void CAction::MouseMove(POINT pt, bool bSetCurPos)
	{
		SETGAMEFOREGROUND;
		GameAssist::GamePos2Screen(m_hGameWnd, pt);
		GameAssist::MouseMove(pt, bSetCurPos);
		SRAND(80, 150);
	}

	void CAction::MouseMove(POINT ptStart, POINT ptEnd, bool bSetCurPos)
	{
		SETGAMEFOREGROUND;
		GameAssist::GamePos2Screen(m_hGameWnd, ptStart);
		GameAssist::MouseMove(ptStart, bSetCurPos);
		Sleep(50);
		GameAssist::GamePos2Screen(m_hGameWnd, ptEnd);
		GameAssist::MouseMove(ptEnd, bSetCurPos);
		SRAND(80, 150);
	}

	void CAction::MouseMoveEx(POINT pt, bool bSetCurPos)
	{
		SETGAMEFOREGROUND;
		GameAssist::GamePos2Screen(m_hGameWnd, pt);
		GameAssist::MouseClick(pt);
		SRAND(80, 150);
	}

	void CAction::MouseMoveEx(POINT ptStart, POINT ptEnd, bool bSetCurPos)
	{
		SETGAMEFOREGROUND;
		GameAssist::GamePos2Screen(m_hGameWnd, ptStart);
		GameAssist::MouseMove(ptStart, bSetCurPos);

		GameAssist::GamePos2Screen(m_hGameWnd, ptEnd);
		GameAssist::MouseClick(ptEnd);
		SRAND(80, 150);
	}

	void CAction::MouseClick()
	{
		SETGAMEFOREGROUND;
		GameAssist::MouseClick();
		SRAND(80, 150);
	}

	void CAction::MouseClick(POINT pt)
	{
		SETGAMEFOREGROUND;
		GameAssist::GamePos2Screen(m_hGameWnd, pt);
		GameAssist::MouseClick(pt);
		SRAND(80, 150);
	}

	void CAction::MouseDbClick()
	{
		SETGAMEFOREGROUND;
		GameAssist::MouseDbClick();
		SRAND(80, 150);
	}

	void CAction::MouseDbClick(POINT pt)
	{
		SETGAMEFOREGROUND;
		GameAssist::GamePos2Screen(m_hGameWnd, pt);
		GameAssist::MouseDbClick(pt);
		SRAND(80, 150);
	}

	void CAction::MouseRClick()
	{
		SETGAMEFOREGROUND;
		GameAssist::MouseRClick();
		SRAND(80, 150);
	}

	void CAction::MouseRClick(POINT pt)
	{
		SETGAMEFOREGROUND;
		GameAssist::GamePos2Screen(m_hGameWnd, pt);
		GameAssist::MouseRClick(pt);
		SRAND(80, 150);
	}

	void CAction::MouseDrag(POINT pt)
	{
		SETGAMEFOREGROUND;
		GameAssist::GamePos2Screen(m_hGameWnd, pt);
		GameAssist::MouseDrag(pt);
		SRAND(80, 150);
	}

	void CAction::SendKey(DWORD key, BOOL bCtrl, BOOL bAtl, BOOL bShift)
	{
		SETGAMEFOREGROUND;
		GameAssist::SendKey(key, bCtrl, bAtl, bShift);
		SRAND(80, 150);
	}

	void CAction::InitNPCInfo()
	{
		static bool bInit = false;
		if (!bInit) {
			// "医师独侠","术士独侠","道士独侠","武师独侠","浪子独侠","剑客独侠", "弓手独侠", "禁卫独侠", "墨者独侠", "巫煞独侠", "魂武独侠"
			g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("医师独侠"), { 305, 325 }));
			g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("术士独侠"), { 305, 325 }));
			g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("道士独侠"), { 305, 325 }));
			g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("武师独侠"), { 305, 325 }));
			g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("浪子独侠"), { 160, 435 }));
			g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("剑客独侠"), { 420, 215 }));
			g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("弓手独侠"), { 265, 240 }));
			g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("禁卫独侠"), { 155, 205 }));
			g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("墨者独侠"), { 155, 205 }));
			g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("巫煞独侠"), { 155, 205 }));
			g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("魂武独侠"), { 165, 335 }));
			g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("寒星独侠"), { 440, 324 }));
			// 应天府NPC
			g_mapZYNPC.insert(std::pair<std::string, POINT>(_T("职业训导大师"), { 315, 415 }));

			g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("医师独侠"), { { 305, 325 }, { 590, 380 } }));
			g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("术士独侠"), { { 305, 325 }, { 610, 160 } }));
			g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("道士独侠"), { { 305, 325 }, { 140, 160 } }));
			g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("武师独侠"), { { 305, 325 }, { 140, 380 } }));
			g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("浪子独侠"), { { 160, 435 }, { 190, 370 } }));
			g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("剑客独侠"), { { 420, 215 }, { 540, 170 } }));
			g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("弓手独侠"), { { 265, 240 }, { 465, 120 } }));
			g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("禁卫独侠"), { { 155, 205 }, { 605, 235 } }));
			g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("墨者独侠"), { { 155, 205 }, { 315, 380 } }));
			g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("巫煞独侠"), { { 155, 205 }, { 270, 175 } }));
			g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("魂武独侠"), { { 165, 335 }, { 270, 305 } }));
			g_mapZYNPC2.insert(std::pair<std::string, PNPC>(_T("寒星独侠"), { { 440, 324 }, { 571, 219 } }));

			bInit = true;
		}
	}

	void CAction::SetGameForeground()
	{
		AutoThreadSection ats(&m_ts);
		if (!::IsWindow(m_hGameWnd)) return;
		::ShowWindow(m_hGameWnd, SW_SHOWNORMAL);
		::SetForegroundWindow(m_hGameWnd); // 窗口前置才能单击成功;
	}

	bool CAction::IsWalkStop()
	{
		if (!::IsWindow(m_hGameWnd))
			return false;

		// 将鼠标移走,不要在抠图区域;
		// 截图,抠指定区域;
		// 再截图,抠指定区域与上次抠图结果比较;
		// 比较结果相同，表示停止走路;
		//POINT pt1 = { 635, 20 }; 
		//POINT pt2 = { 780, 38 };
		CRect rc = { 630, 40, 800, 65 };
		CRect rc2 = { 640, 45, 770, 63 };
		for (int i = 0; i < 100; i++)
		{
			std::string strImg = GameGlobal::BuildImgPath(m_hGameWnd, "walk1");
			std::string strImg2 = GameGlobal::BuildImgPath(m_hGameWnd, "walk2");
			ImgAssist::CropPicture(m_hGameWnd, rc, strImg.c_str());
			Sleep(600);
			ImgAssist::CropPicture(m_hGameWnd, rc2, strImg2.c_str());
			// 判断2张图片是否一样;
			if (ImgAssist::IsSimilarPicture(strImg.c_str(), strImg2.c_str()))
			{
				GameGlobal::DebugLog(_T("停止走路"));
				return true;
			}
		}

		return false;
	}

	bool CAction::IsFighting()
	{
		CRect rc;
		SRAND(100, 200);
		if (ImgAssist::IsMatchIcon(m_hGameWnd, GameGlobal::g_strAppdir + _T("img\\活动\\镜妖\\非战斗中.bmp"), { 630, 25, 805, 45 }, rc)) {
			GameGlobal::DebugLog(_T("Battle：非战斗中"));
			return false;
		}

		GameGlobal::DebugLog(_T("Battle：战斗中"));
		return true;
	}

	CRect CAction::FindMatchIcon(LPCTSTR lpszTemplateImage)
	{
		CRect rc;
		TCHAR szTemplateImage[MAX_PATH] = { 0 };
		// 先截图;
		GameGlobal::DebugLog(_T("FindMatchIcon=%s"), lpszTemplateImage);
		ImgAssist::CaptureGameWnd(m_hGameWnd); SRAND(200, 500);
		_stprintf_s(szTemplateImage, _T("%s%s"), GameGlobal::g_strAppdir.c_str(), lpszTemplateImage);
		if (ImgAssist::GetImgMatchtemplate(GameGlobal::BuildImgPath(m_hGameWnd), szTemplateImage, rc)) {
			// 找到匹配的模块;
			GameGlobal::DebugLog(_T("====> 找到匹配目标:%s"), lpszTemplateImage);
			return rc;
		}

		rc.SetRectEmpty();
		GameGlobal::DebugLog(_T("<==== 没找到匹配目标:%s"), lpszTemplateImage);
		return rc;
	}

	bool CAction::IsOnMap(LPCTSTR lpszTemplateImage)
	{
		CRect rc = FindMatchIcon(lpszTemplateImage);
		if (rc.IsRectEmpty() || rc.IsRectNull())
			return false;

		return true;
	}

	void CAction::WorldMapPositioning(POINT ptMap)
	{
		CRect rc;
		//// 打开世界地图;
		SendKey(VK_TAB); SRAND(550, 800);
		// 判断是否打开了地图;
		if (!ImgAssist::GetImgMatchtemplate(m_hGameWnd, GameGlobal::g_strAppdir + _T("img\\世界地图.bmp"), rc))
			return;

		//// 单击寻路窗口;
		MouseClick(ptMap); SRAND(300, 600);

		while (ImgAssist::GetImgMatchtemplate(m_hGameWnd, GameGlobal::g_strAppdir + _T("img\\世界地图.bmp"), rc)) {
			// 退出世界地址;
			SendKey(VK_TAB); SRAND(200, 300);
		}

		IsWalkStop();
	}

	bool CAction::IsWattingAttack(int nAttackNPCType)
	{
		CRect rc;
		BOOL bIsAttack = FALSE;
		if (ImgAssist::IsMatchIcon(m_hGameWnd, GameGlobal::g_strAppdir + _T("img\\我方攻击2.bmp"), { 720, 85, 806, 120 }, rc)) {
			GameGlobal::DebugLog(_T("IsWattingAttack：我方攻击中……"));
			bIsAttack = TRUE;
		}

		return bIsAttack;
	}

	bool CAction::ClickDlgSetup(LPCSTR lpszTemplateImage)
	{
		CRect rc = FindMatchIcon(_T("img\\对话框关闭按钮.bmp"));
		if (rc.IsRectEmpty() || rc.IsRectNull())
			return false;

		// 移动到关闭按钮;
		MouseMove({ rc.left - 30 , rc.top + 10 });
		SRAND(50, 80);
		// 再找目标;
		rc = FindMatchIcon(lpszTemplateImage);
		SRAND(50, 80);
		// 单击目标;
		MouseClick(CPoint((rc.right + rc.left) / 2, (rc.top + rc.bottom) / 2 + rand() % 3));
		// 单击后，系统切图可能要的时间会比较长;
		SRAND(100, 200);
		// 单击目标后，要往移走鼠标，防止下面匹配的时候被鼠标挡住;
		MouseMove(CPoint(rc.top - RAND(5, 12), rc.left - RAND(5, 10))); // 移动到左上角;
		SRAND(100, 200);

		return true;
	}

	bool CAction::ClickDlgSetup(std::vector<std::string> vtOptions)
	{
		std::vector<std::string>::iterator it = vtOptions.begin();
		for (; it != vtOptions.end(); it++)
		{

		}

		return false;
	}

	bool CAction::FindNPCByWorldMap(LPCTSTR lpszNPCName)
	{
		CRect rc;
		//// 打开世界地图;
		SendKey(VK_TAB); SRAND(500, 600);
		if (!ImgAssist::GetImgMatchtemplate(m_hGameWnd, GameGlobal::g_strAppdir + _T("img\\寻路窗口.bmp"), rc))
			return false;

		//// 单击寻路窗口;
		MouseClick(CPoint((rc.right + rc.left) / 2 + rand() % 2, (rc.top + rc.bottom) / 2 + rand() % 2)); SRAND(500, 800);
		//// 设置剪切板：职业大挑战;
		SetClipboardString(lpszNPCName); SRAND(200, 500);
		//// Ctrl+V
		SendKey(0x56, TRUE); SRAND(300, 500);
		// 先移动到目标后，才能实现单击;
		MouseMove(CPoint((rc.right + rc.left) / 2 + 5 + rand() % 2, (rc.top + rc.bottom) / 2 + 60 + rand() % 2)); SRAND(200, 300);
		//// 寻路窗口往下50就是目标;
		MouseDbClick(CPoint((rc.right + rc.left) / 2 + 5 + rand() % 2, (rc.top + rc.bottom) / 2 + 60 + rand() % 2)); SRAND(200, 300);
		while (ImgAssist::GetImgMatchtemplate(m_hGameWnd, GameGlobal::g_strAppdir + _T("img\\世界地图.bmp"), rc)) {
			// 退出世界地址;
			SendKey(VK_TAB); SRAND(200, 300);
		}

		// 直到停止走动为止;
		IsWalkStop();

		// 遍历3次;
		bool bFind = false;
		for (int i = 0; i < 3; i++)
		{
			Sleep(800 - i * 150);
			rc = FindMatchIcon(_T("img\\对话框关闭按钮.bmp"));
			if (!rc.IsRectEmpty() && !rc.IsRectNull())
			{
				bFind = true;
				break;
			}
		}

		return bFind;
	}

	bool CAction::FindNPCByIcon(POINT ptMap, LPCTSTR lpszNPCName)
	{
		TCHAR szNPC[MAX_PATH] = { 0 };
		_stprintf_s(szNPC, _T("img\\npc\\%s.bmp"), lpszNPCName);
		CRect rc = FindMatchIcon(szNPC);
		if (rc.IsRectEmpty() || rc.IsRectNull())
		{
			WorldMapPositioning(ptMap);
			Sleep(600); // 有时走到目标点，NPC还未刷新出来;
			rc = FindMatchIcon(szNPC);
			if (rc.IsRectEmpty() || rc.IsRectNull())
			{
				// 可能还是未刷新出来,再次等待;
				Sleep(300);
				rc = FindMatchIcon(szNPC);
				if (rc.IsRectEmpty() || rc.IsRectNull())
				{
					return false;
				}
			}
		}

		// 找到目标,单击;
		MouseMove(CPoint(rc.left, rc.top));
		// 单击：我要挑战他们;
		MouseClick({ (rc.right + rc.left) / 2, (rc.top + rc.bottom) / 2 });
		SRAND(500, 1300);// 等对话框出现;
		// 移动鼠标：不要停留在人物身上;
		MouseMove({ rc.left - rand() % 10, rc.top - rand() % 10 });

		return true;
	}

	bool CAction::FindNPCByIconAndPos(LPCTSTR lpszNPCName, POINT ptMap, POINT ptNpc)
	{
		TCHAR szNPC[MAX_PATH] = { 0 };
		_stprintf_s(szNPC, _T("img\\npc\\%s.bmp"), lpszNPCName);
		CRect rc = FindMatchIcon(szNPC);
		if (rc.IsRectEmpty() || rc.IsRectNull())
		{
			WorldMapPositioning(ptMap);
			Sleep(600); // 有时走到目标点，NPC还未刷新出来;
			rc = FindMatchIcon(szNPC);
			if (rc.IsRectEmpty() || rc.IsRectNull())
			{
				// 可能还是未刷新出来,再次等待;
				Sleep(600);
				rc = FindMatchIcon(szNPC);
				if (rc.IsRectEmpty() || rc.IsRectNull())
				{
					return false;
				}
			}
		}

		// 找到目标,单击;
		MouseMove(CPoint(rc.left - rand() % 30, rc.top + rand() % 50));
		// 单击：我要挑战他们;
		MouseClick(ptNpc);

		// 遍历3次;
		bool bFind = false;
		for (int i = 0; i < 3; i++)
		{
			Sleep(800 - i * 150);
			CRect rc = FindMatchIcon("img\\对话框关闭按钮.bmp");
			if (!rc.IsRectEmpty() && !rc.IsRectNull())
			{
				bFind = true;
				break;
			}
		}

		// 移动鼠标：不要停留在人物身上;
		MouseMove({ ptNpc.x - rand() % 30, ptNpc.y - rand() % 30 });

		return bFind;
	}

	bool CAction::FindNPCByMap(LPCTSTR lpszNPCName)
	{
		auto it = g_mapZYNPC2.find(lpszNPCName);
		if (it != g_mapZYNPC2.end())
		{
			if (FindNPCByIconAndPos(it->first.c_str(), it->second.ptMap, it->second.ptNpc))
			{
				return true;
			}
		}

		return false;
	}

	bool CAction::IsSPBelowSafeValue(BOOL IsRole, BOOL IsIdle, int nSafeValue /*= 30*/)
	{
		RECT rect = { 0,0,0,0 };
		if (IsIdle)
		{
			rect = IsRole ? GameAssist::g_rcRoleIdleSP : GameAssist::g_rcSummonerIdleSP;
		}
		else
		{
			rect = IsRole ? GameAssist::g_rcRoleFightingSP : GameAssist::g_rcSummonerFightingSP;
		}

		// 截图;
		TCHAR szSPImg[MAX_PATH] = { 0 };
		_stprintf_s(szSPImg, _T("%s%p_SPValue.bmp"), GameGlobal::g_szTempDir, m_hGameWnd);
		ImgAssist::CropPicture(m_hGameWnd, rect, szSPImg);

		return ImgAssist::GetColorOccupiedLength(szSPImg, 8, 96, 248) < nSafeValue;
	}

	bool CAction::IsHPBelowSafeValue(BOOL IsRole, BOOL IsIdle, int nSafeValue /*= 30*/)
	{
		RECT rect = { 0,0,0,0 };
		if (IsIdle)
		{
			rect = IsRole ? GameAssist::g_rcRoleIdleHP : GameAssist::g_rcSummonerIdleHP;
		}
		else
		{
			rect = IsRole ? GameAssist::g_rcRoleFightingHP : GameAssist::g_rcSummonerFightingHP;
		}

		// 截图;
		TCHAR szSPImg[MAX_PATH] = { 0 };
		_stprintf_s(szSPImg, _T("%s%p_HPValue.bmp"), GameGlobal::g_szTempDir, m_hGameWnd);
		ImgAssist::CropPicture(m_hGameWnd, rect, szSPImg);

		return ImgAssist::GetColorOccupiedLength(szSPImg, 248, 56, 64) < nSafeValue;
	}

	void CAction::FightingJY(BOOL bHasSummoner, int nZJType, BOOL bAggressiveSkill)
	{
		BOOL bFirstAttack = TRUE;
		BOOL bAltA = FALSE;
		// 1.是否在战斗中;
		while (IsFighting()) {
			// 2.是否我方攻击;
			while (IsWattingAttack(0)) { // Bug:如果被镜妖打死了,无法中断;
				GameGlobal::DebugLog(_T("BattleJY：我方攻击……"));
				if (bFirstAttack)
				{
					SRAND(350, 500);	// 有时切换需要时间,如果不延时会失败;
					GameGlobal::DebugLog(_T("BattleJY：第一次攻击……"));
					// 根据角色选择技能;
					SendKey(VK_F2);
					SRAND(300, 350);
					if (bAggressiveSkill) // 打镜妖喽罗;
					{
						MouseClick(CPoint(290 - 3, 140 - 20));
						//MouseMove(hWnd, CPoint(220 - 5, 180 - 10));// 打主镜妖;
						SRAND(350, 500);
					}

					if (bHasSummoner) {
						CRect rc;
						// 召唤兽技能;
						GameGlobal::DebugLog(_T("BattleJY：召唤兽技能选择"));

						// 选择重击;
						if (nZJType) {
							SRAND(150, 350);
							SendKey(VK_S, FALSE, TRUE);
							GameGlobal::DebugLog(_T("BattleJY：召唤兽技能选择:%d"), nZJType);
							if (ImgAssist::GetImgMatchtemplate(m_hGameWnd, nZJType == 1 ? GameGlobal::g_strAppdir + _T("img\\活动\\镜妖\\重击.bmp") : GameGlobal::g_strAppdir + _T("img\\活动\\镜妖\\重击2.bmp"), rc))
							{
								SRAND(150, 300);
								MouseClick(CPoint((rc.right + rc.left) / 2 + rand() % 3, (rc.top + rc.bottom) / 2 + rand() % 3));
							}
						}

						SRAND(300, 500);
						MouseMove(CPoint(290 - 3, 140 - 15));
						MouseClick(CPoint(290 - 3, 140 - 20));
					}

					bFirstAttack = FALSE;
				}
				else
				{
					if (!bAltA)
					{
						bAltA = TRUE;
						// 根据角色选择技能;
						SendKey(VK_F1);
						SRAND(300, 350);
						MouseClick(CPoint(230, 180 - 10));// 打主镜妖;
						SRAND(350, 500);
					}
					else {
						GameGlobal::DebugLog(_T("BattleJY：不是第一次攻击……"));
						SendKey(VK_A, FALSE, TRUE);
						SRAND(80, 100);
						if (bFirstAttack) {
							SendKey(VK_A, FALSE, TRUE);
							SRAND(80, 120);
						}
					}
				}
			}

			SRAND(500, 850);
		}

		if (IsSPBelowSafeValue(TRUE, TRUE, 15))
		{
			GameGlobal::DebugLog(_T("低SP安全值"));
			// 右键;
			MouseMove({ (GameAssist::g_rcRoleIdleSP.right + GameAssist::g_rcRoleIdleSP.left) / 2 - 3, (GameAssist::g_rcRoleIdleSP.bottom + GameAssist::g_rcRoleIdleSP.top) / 2 - 20 });
			MouseRClick({ (GameAssist::g_rcRoleIdleSP.right + GameAssist::g_rcRoleIdleSP.left) / 2 - 3, (GameAssist::g_rcRoleIdleSP.bottom + GameAssist::g_rcRoleIdleSP.top) / 2 - 20 });
		}

		if (bHasSummoner && IsSPBelowSafeValue(FALSE, TRUE, 10))
		{
			GameGlobal::DebugLog(_T("低SP安全值"));
			// 右键;
			MouseMove({ (GameAssist::g_rcSummonerIdleSP.right + GameAssist::g_rcSummonerIdleSP.left) / 2 - 3, (GameAssist::g_rcSummonerIdleSP.bottom + GameAssist::g_rcSummonerIdleSP.top) / 2 - 20 });
			MouseRClick({ (GameAssist::g_rcSummonerIdleSP.right + GameAssist::g_rcSummonerIdleSP.left) / 2 - 3, (GameAssist::g_rcSummonerIdleSP.bottom + GameAssist::g_rcSummonerIdleSP.top) / 2 - 20 });
		}

		// 非战斗中,是否在贫民房中;
		if (!IsOnMap(_T("img\\地图\\贫民房.bmp"))) {
			// 找小米;
			CRect rc;
			if (!FindNPCByWorldMap("臭美的小米"))
				return;

			// 选择进入;
			BOOL bMatch = FALSE;
			int trySize = 15;
			// 我要挑战他们;
			while (!(bMatch = ClickDlgSetup(_T("img\\活动\\镜妖\\1-我帮您抓.bmp")))) {
				SRAND(800, 1200);
				if (!trySize--) break;
			}

			if (bMatch) {
				MouseMove(CPoint(rc.left, rc.top));
				// 单击：我要挑战他们;
				MouseClick(CPoint((rc.right + rc.left) / 2, (rc.top + rc.bottom) / 2));
				SRAND(1000, 1500);// 等出图;

				// 移动一下;
				MouseMove(CPoint(rc.left, rc.top));
				::SetCursorPos(rc.left + rand() % 6, rc.top + rand() % 8);

				// 是否第一次进入地图;
				if (ClickDlgSetup(_T("img\\活动\\镜妖\\2-我这就去.bmp")))
				{
					SRAND(600, 1200);
					if (ClickDlgSetup(_T("img\\活动\\镜妖\\3-战意镜妖.bmp")))
					{
						SRAND(600, 1800);
						if ((bMatch = ClickDlgSetup(_T("img\\活动\\镜妖\\4-我就选择它.bmp"))))
						{
							SRAND(800, 1800);
						}
					}
				}
			}
		}
		else
		{
			// 找到镜妖;
			CRect rc;
			POINT spt[4] = { { 250, 335 }, { 310,360}, { 385, 315}, { 280,295 } };
			for (int i = 0; !ImgAssist::GetImgMatchtemplate(m_hGameWnd, GameGlobal::g_strAppdir + _T("img\\活动\\镜妖\\镜妖1.bmp"), rc); i++)
			{
				// 打开世界地图;
				SendKey(VK_TAB); SRAND(200, 300);
				// 选择坐标点;
				MouseClick(spt[i % 4]);
				while (ImgAssist::GetImgMatchtemplate(m_hGameWnd, GameGlobal::g_strAppdir + _T("img\\世界地图.bmp"), rc)) {
					// 退出世界地址;
					SendKey(VK_TAB); SRAND(500, 900);
				}
				// 等待跑完成;
				IsWalkStop();
				// 移动下鼠标;
				MouseMove(spt[(i + 1) % 4]);
				if (i > 10) {
					GameGlobal::DebugLog(_T("未找到镜妖+10"));
					break;
				}
			}

			// 找到镜妖;
			MouseMove(CPoint(rc.left + rand() % 10, rc.top + rand() % 10));
			GameGlobal::DebugLog(_T("移动鼠标"));
			MouseClick(CPoint((rc.right + rc.left) / 2 + rand() % 3, (rc.top + rc.bottom) / 2 + rand() % 3));
			SRAND(390, 600);
			// 单击目标后，要往移走鼠标，防止下面匹配的时候被鼠标挡住;
			MouseMove(CPoint(rc.right + RAND(10, 20), rc.bottom + RAND(10, 20)));
			SRAND(300, 500);
			GameGlobal::DebugLog(_T("找到目标并单击成功:%s"));

			// 我来抓你;
			if (ImgAssist::GetImgMatchtemplate(m_hGameWnd, GameGlobal::g_strAppdir + _T("img\\活动\\镜妖\\我来抓您的.bmp"), rc)) {
				// 找到匹配的模块;
				SRAND(200, 300);
				//MouseMove(hWnd, CPoint(rc.left + rand() % 10, rc.top + rand() % 10));
				GameGlobal::DebugLog(_T("我来抓你：移动鼠标"));
				MouseClick(CPoint((rc.right + rc.left) / 2 + rand() % 3, (rc.top + rc.bottom) / 2 + rand() % 3));
				SRAND(1000, 1500);
				GameGlobal::DebugLog(_T("我来抓你：找到目标并单击成功:%s"));
			}
		}
	}

	void CAction::FightingYS(LPCTSTR lpszSkillName)
	{
		CRect rc;
		BOOL bBattle = FALSE;
		if (!FindNPCByMap("医师独侠"))
			return;

		// 废话少说：表示这个没打过;
		rc = FindMatchIcon(_T("img\\gdd\\废话少说.bmp"));
		if (!rc.IsRectEmpty() && !rc.IsRectNull())
		{
			// 确定
			bBattle = TRUE;
			MouseMove({ rc.left - RAND(30, 50), rc.top - RAND(30, 50) });
			SRAND(20, 50);
			MouseClick(CPoint((rc.right + rc.left) / 2, (rc.top + rc.bottom) / 2));
			SRAND(500, 800); // 切图时间长;
			ClickDlgSetup(_T("img\\确定.bmp"));
		}
		else
		{
			rc = FindMatchIcon(_T("img\\gdd\\离开这里.bmp"));
			if (!rc.IsRectEmpty() && !rc.IsRectNull())
			{
				// 只有离开这里：已经打过，右键并退出 ;
				GameGlobal::DebugLog("只有离开这里：已经打过，右键并退出");
				MouseRClick({ rc.left, rc.top });
				SRAND(200, 500);
				return;
			}
			else
			{
				// 找下一页的技能：没有下一页返回-1，找到返回0，没找到返回1;
				auto FindNextPageJZ = [&](TCHAR* pJN)->int {
					// 没有在当前页找到目标,看看是否在下一页;
					rc = FindMatchIcon(_T("img\\jn-jk\\gdd\\xyy.bmp"));
					if (rc.IsRectEmpty() || rc.IsRectNull())
					{
						// 没有下一页,右键退出;
						MouseRClick();
						SRAND(200, 300);
						return -1;
					}

					MouseClick(CPoint((rc.right + rc.left) / 2, (rc.top + rc.bottom) / 2));
					SRAND(500, 750);
					// 下一页中查看;
					rc = FindMatchIcon(pJN);
					if (!rc.IsRectEmpty() && !rc.IsRectNull())
					{
						// 找到目标,单击;
						MouseClick(CPoint((rc.right + rc.left) / 2, (rc.top + rc.bottom) / 2));
						SRAND(500, 800);
						ClickDlgSetup(_T("img\\确定.bmp"));
						SRAND(350, 500);

						rc = FindMatchIcon(_T("img\\gdd\\接受挑战.bmp"));
						if (!rc.IsRectEmpty() && !rc.IsRectNull())
						{// 第二次开始都会多这个;
							// 找到目标,单击;
							MouseClick(CPoint((rc.right + rc.left) / 2, (rc.top + rc.bottom) / 2));
							SRAND(500, 800);
							// 移动下，防止高亮识别失败;
							MouseMove({ rc.left, rc.top }, { rc.left - rand() % 20, rc.top - rand() % 20 });
							SRAND(150, 250);
						}

						ClickDlgSetup(_T("img\\确定.bmp"));
						SRAND(250, 300);

						// 战斗;
						return 0;
					}

					return 1;
				};

				TCHAR szJN[MAX_PATH] = { 0 };
				_stprintf_s(szJN, _T("img\\jn-jk\\gdd\\%s.bmp"), lpszSkillName);
				rc = FindMatchIcon(szJN);
				if (rc.IsRectEmpty() || rc.IsRectNull())
				{
					// 最多只有三页;
					for (int i = 0; i < 3; i++)
					{
						// 没有在当前页找到目标,看看是否在下一页;
						int nRet = FindNextPageJZ(szJN);
						if (nRet == 1)
						{
							// 没有找到技能;
							SRAND(500, 800);
							continue;
						}

						if (nRet == 0)
						{
							// 找到了;
							bBattle = TRUE;
						}

						break; // 没有下一页也直接break;
					}
				}
				else
				{
					bBattle = TRUE;
					// 找到目标,单击;
					MouseClick(CPoint((rc.right + rc.left) / 2, (rc.top + rc.bottom) / 2));
					// 切图时间比较长;
					SRAND(500, 800);
					// 战斗;
					ClickDlgSetup(_T("img\\确定.bmp"));
					SRAND(200, 300);
				}
			}
		}

		int KeyValue, SkillTime;
		// 进入战斗;
		if (bBattle)
		{
			// 人物：Alt+S显示技能，双击选择技能，单击怪物发动技能;
			// 注：有的人物技能太多，导致会有滚动条：这是有难点;
			BOOL bRet = FindJNShortCut(lpszSkillName, KeyValue, SkillTime);
			GameGlobal::DebugLog("快捷键值=%ld", KeyValue);

			// 快捷键;
			SendKey(KeyValue);
			SRAND(350, 650);
			// 单击指定位置;
			MouseClick({ 230, 170 });
			SRAND(260, 380);
			// 将鼠标移动到指定位置;
			POINT ptDest = { 625, 28 }; // 左上角;
			MouseMove(ptDest);
			while (IsFighting())
			{
				// 判断是否我方攻击;
				if (IsWattingAttack(1))
				{
					SendKey(VK_A, FALSE, TRUE);
				}
				SRAND(500, 900);
			}
		}

		// 右键退出;
		SRAND(300, 500); //必要的等待时间;
		do
		{
			rc = FindMatchIcon("img\\对话框关闭按钮.bmp");
			Sleep(900);
		} while (rc.IsRectEmpty() || rc.IsRectNull());

		MouseRClick();
	}

	void CAction::FightingOthers(LPCTSTR lpszName, LPCTSTR lpszSkillName)
	{
		CRect rc;
		BOOL bBattle = FALSE;
		if (!FindNPCByMap(lpszName))
			return;

		// 废话少说：表示这个没打过;
		rc = FindMatchIcon(_T("img\\gdd\\废话少说.bmp"));
		if (!rc.IsRectEmpty() && !rc.IsRectNull())
		{
			MouseMove({ rc.left - RAND(30, 50), rc.top - RAND(30, 50) });
			SRAND(120, 150);
			MouseClick(CPoint((rc.right + rc.left) / 2, (rc.top + rc.bottom) / 2));
			SRAND(330, 550);
			// 确定
			bBattle = TRUE;
			ClickDlgSetup(_T("img\\确定.bmp"));
			SRAND(250, 350);
		}
		else
		{
			rc = FindMatchIcon(_T("img\\gdd\\离开这里.bmp"));
		}

		int KeyValue, SkillTime;
		if (bBattle) {
			BOOL bRet = FindJNShortCut(lpszSkillName, KeyValue, SkillTime);
			// 将鼠标移动到指定位置;
			POINT ptDest = { 625, 28 }; // 左上角;
			MouseMove(ptDest);
			while (IsFighting())
			{
				// 判断是否我方攻击;
				if (IsWattingAttack(1))
				{
					SendKey(VK_A, FALSE, TRUE);
				}

				SRAND(500, 750);
			}
		}

		// 右键退出;
		if (_tcsicmp(lpszName, _T("寒星独侠")))
		{
			SRAND(300, 500);
			do
			{
				rc = FindMatchIcon("img\\对话框关闭按钮.bmp");
				Sleep(900);
			} while (rc.IsRectEmpty() || rc.IsRectNull());

			MouseRClick();
		}
		else
		{
			// 回到应天府;
			MouseMoveEx({ rc.left, rc.top }, { rc.right + rand() % 10, rc.bottom + rand() % 10 });
			ClickDlgSetup(_T("\\img\\gdd\\送我回应天府.bmp"));
		}
	}

	void CAction::OpenChest(int nTimes)
	{
		CRect rc;
		for (int i = 0; i < nTimes; i++)
		{
			if (!ImgAssist::GetImgMatchtemplate(m_hGameWnd, GameGlobal::g_strAppdir + _T("img\\开宝箱\\应天府铁匠.bmp"), rc))
			{
				// 没找到，要将鼠标从目标中移走;并且要右击一次将目标的高亮状态取消;
				MouseMove({ rc.top - rand() % 5, rc.left - rand() % 5 });
				MouseRClick();
			}
			else
			{
				MouseClick(CPoint((rc.right + rc.left) / 2 + rand() % 3, (rc.top + rc.bottom) / 2 + rand() % 5));
				Sleep(600 + rand() % 30);
				// 再移动下，会更高精度;
				MouseMove({ rc.top - rand() % 15, rc.left - rand() % 15 });
				// 判断是否还有对话,如果没有的话表明不是第一次进入;
				if (ImgAssist::GetImgMatchtemplate(m_hGameWnd, GameGlobal::g_strAppdir + _T("img\\开宝箱\\开宝箱.bmp"), rc)) {

					MouseClick(CPoint((rc.right + rc.left) / 2 + rand() % 2, (rc.top + rc.bottom) / 2 + rand() % 2));
					Sleep(rand() % 200 + 190);
					// 然后移动出去;
					//GameGlobal::MouseMove(hProcessMainWnd, CPoint(rc.top - 50 - rand()%20, rc.left - 50 - rand() % 20));
					MouseMoveEx({ rc.top + RAND(0, rc.Height()), rc.left + RAND(0, rc.Width()) });
				}
			}

			Sleep(600 + rand() % 300);
		}
	}

	void CAction::GetSaturdayPresents()
	{
		FindNPCByWorldMap(_T("送礼协会会长丙"));
		IsWalkStop();

		if (ClickDlgSetup(_T("img\\活动\\周六礼物\\我来领取礼物.bmp")))
		{
			if (ClickDlgSetup(_T("img\\活动\\周六礼物\\好的.bmp")))
			{
				FindNPCByWorldMap(_T("【星】铜钱怪"));
				IsWalkStop();

				CRect rc;
				//铜钱怪：好的，要问些什么问题呢？
				struct MyStruct
				{
					BOOL bDone = FALSE;
					TCHAR szQuestion[MAX_PATH] = { 0 };
				};

				if (ClickDlgSetup(_T("img\\活动\\周六礼物\\铜钱怪：好的，要问些什么问题呢？.bmp")))
				{
					// 第一次回答;
					std::vector<MyStruct> vtMyst1 = { {FALSE, _T("img\\活动\\周六礼物\\铜钱怪：帮派就象个大家庭.bmp")},
					{FALSE, _T("img\\活动\\周六礼物\\铜钱怪：交流的场所.bmp")},
					{FALSE, _T("img\\活动\\周六礼物\\铜钱怪：能够认识很多.bmp")},
					{FALSE, _T("img\\活动\\周六礼物\\铜钱怪：我希望能够.bmp")},
					{FALSE, _T("img\\活动\\周六礼物\\铜钱怪：由系统定时发布.bmp")},
					{FALSE, _T("img\\活动\\周六礼物\\铜钱怪：好的，快点问吧.bmp")}
					};

					for (; vtMyst1.size();)
					{
						for (std::vector<MyStruct>::iterator it = vtMyst1.begin(); it != vtMyst1.end(); it++)
						{
							rc = FindMatchIcon(it->szQuestion);
							if (!rc.IsRectEmpty() && !rc.IsRectNull())
							{
								// 单击目标回答;
								MouseClick(CPoint((rc.right + rc.left) / 2 + rand() % 3, (rc.top + rc.bottom) / 2 + rand() % 5));
								// 再移动下鼠标，防止高亮影响下次的判断;
								MouseMove(CPoint(rc.right + RAND(6, 20), rc.bottom + RAND(6, 20)));
								// 等待下一个问题出现;
								SRAND(200, 300);
								it = vtMyst1.erase(it);
								break;
							}
						}
					}

					// 第二次回答;
					std::vector<MyStruct> vtMyst2 = { {FALSE, _T("img\\活动\\周六礼物\\铜钱怪：帮派就象个大家庭.bmp")},
					{FALSE, _T("img\\活动\\周六礼物\\铜钱怪：交流的场所.bmp")},
					{FALSE, _T("img\\活动\\周六礼物\\铜钱怪：能够认识很多.bmp")},
					{FALSE, _T("img\\活动\\周六礼物\\铜钱怪：我希望能够.bmp")},
					{FALSE, _T("img\\活动\\周六礼物\\铜钱怪：由系统定时发布.bmp")}
					};
					for (; vtMyst2.size();)
					{
						for (std::vector<MyStruct>::iterator it = vtMyst2.begin(); it != vtMyst2.end(); it++)
						{
							rc = FindMatchIcon(it->szQuestion);
							if (!rc.IsRectEmpty() && !rc.IsRectNull())
							{
								// 单击目标回答;
								MouseClick(CPoint((rc.right + rc.left) / 2 + rand() % 3, (rc.top + rc.bottom) / 2 + rand() % 5));
								// 再移动下鼠标，防止高亮影响下次的判断;
								MouseMove(CPoint(rc.right + RAND(6, 20), rc.bottom + RAND(6, 20)));
								// 等待下一个问题出现;
								SRAND(200, 300);
								it = vtMyst2.erase(it);
								break;
							}
						}
					}

					// 回答完所有问题,右键退出;
					SRAND(200, 300);
					MouseRClick();
				}

				// 再次回到送礼协会会长;
				FindNPCByWorldMap(_T("送礼协会会长丙"));
				IsWalkStop();
				// 再右键一次;
				SRAND(200, 300);
				MouseRClick();
				FindNPCByWorldMap(_T("送礼协会会长丙"));
				if (ClickDlgSetup(_T("img\\活动\\周六礼物\\好，现在就去.bmp")))
				{
					// 等待切换地图;
					SRAND(800, 900);
				}
			}
		}

		if (IsOnMap(_T("img\\地图\\汴京城.bmp")))
		{
			// 找送礼协会会长丁
			FindNPCByWorldMap(_T("送礼协会会长丁"));
			IsWalkStop();
			SRAND(300, 500); // 等对话框出现;
			if (ClickDlgSetup(_T("img\\活动\\周六礼物\\我来领取礼物.bmp")))
			{
				if (ClickDlgSetup(_T("img\\活动\\周六礼物\\好的.bmp")))
				{
					// 找铜钱怪;
					FindNPCByWorldMap(_T("【汴】铜钱怪"));
					IsWalkStop();
					SRAND(300, 500);
					if (ClickDlgSetup(_T("img\\活动\\周六礼物\\铜钱怪：进入战斗.bmp")))
					{
						// 将鼠标移动到指定位置;
						POINT ptDest = { 625, 28 }; // 左上角;
						MouseMove(ptDest);
						while (IsFighting())
						{
							// 判断是否我方攻击;
							if (IsWattingAttack(1))
							{
								SendKey(VK_A, FALSE, TRUE);
							}

							SRAND(500, 750);
						}

						// 送礼协会会长乙;
						FindNPCByWorldMap(_T("送礼协会会长乙"));
						IsWalkStop();
						// 再右键一次;
						SRAND(200, 300);
						MouseRClick();
						FindNPCByWorldMap(_T("送礼协会会长丙")); SRAND(200, 300);
						if (ClickDlgSetup(_T("img\\活动\\周六礼物\\好，现在就去.bmp")))
						{
							// 等待切换地图;
							SRAND(800, 900);
						}
					}
				}
			}
		}

		if (IsOnMap(_T("img\\地图\\应天府.bmp")))
		{
			// 找送礼协会会长丁
			FindNPCByWorldMap(_T("送礼协会会长甲"));
			IsWalkStop();
			SRAND(300, 500); // 等对话框出现;
			if (ClickDlgSetup(_T("img\\活动\\周六礼物\\我来领取礼物.bmp")))
			{
				if (ClickDlgSetup(_T("img\\活动\\周六礼物\\好的.bmp")))
				{
					// 找铜钱怪;
					FindNPCByWorldMap(_T("【应】铜钱怪"));
					IsWalkStop();
					SRAND(300, 500);
					if (ClickDlgSetup(_T("img\\活动\\周六礼物\\铜钱怪：进入战斗.bmp")))
					{
						// 将鼠标移动到指定位置;
						POINT ptDest = { 625, 28 }; // 左上角;
						MouseMove(ptDest);
						while (IsFighting())
						{
							// 判断是否我方攻击;
							if (IsWattingAttack(1))
							{
								SendKey(VK_A, FALSE, TRUE);
							}

							SRAND(500, 750);
						}

						// 送礼协会会长乙;
						FindNPCByWorldMap(_T("送礼协会会长甲"));
						IsWalkStop();
						SRAND(1000, 2000);
						MouseRClick();
					}
				}
			}
		}
	}

	void CAction::ExerciseSkill(INT nVK_Skill, BOOL bCheckAttack)
	{
		BOOL bFirst = TRUE;
		while (IsFighting())
		{
			if (IsWattingAttack(-1))
			{
				if (bFirst)
				{
					SRAND(250, 350);
					SendKey(nVK_Skill);
					if (bCheckAttack)
					{
						Sleep(30);
						MouseClick({ 226, 158 });
					}
					bFirst = FALSE;
				}
				else
				{
					if (bCheckAttack)
						SendKey(VK_A, FALSE, TRUE);
					else
						SendKey(nVK_Skill);
				}
			}
			Sleep(650);
		}
		
		if (IsSPBelowSafeValue(TRUE, TRUE, 20))
		{
			//DebugLog(_T("低SP安全值"));
			// 右键;
			MouseMove({ (GameAssist::g_rcRoleIdleSP.right + GameAssist::g_rcRoleIdleSP.left) / 2 - 3, (GameAssist::g_rcRoleIdleSP.bottom + GameAssist::g_rcRoleIdleSP.top) / 2 - 20 });
			MouseRClick({ (GameAssist::g_rcRoleIdleSP.right + GameAssist::g_rcRoleIdleSP.left) / 2 - 3, (GameAssist::g_rcRoleIdleSP.bottom + GameAssist::g_rcRoleIdleSP.top) / 2 - 20 });
		}
	}

	void CAction::StartBattleJY()
	{
		m_hBattleJYEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
		if (m_hBattleJYEvent == NULL) {
			_tprintf_s(_T("创建事件失败\n"));
			return;
		}

		m_hBattleJY = CreateThread(NULL, 0, BattleJYThread, this, 0, NULL);
		if (m_hBattleJY == NULL) {
			_tprintf_s(_T("创建线程失败\n"));

			if (m_hBattleJYEvent) {
				SetEvent(m_hBattleJYEvent);
				CloseHandle(m_hBattleJYEvent);
				m_hBattleJYEvent = NULL;
			}
		}
	}

	void CAction::StopBattleJY()
	{
		// 设置事件有信号;
		if (m_hBattleJYEvent)
			SetEvent(m_hBattleJYEvent);

		// 等待线程结束;
		if (m_hBattleJY) {
			WaitForSingleObject(m_hBattleJY, INFINITE);
			CloseHandle(m_hBattleJY);
			m_hBattleJY = NULL;
		}

		// 关闭事件句柄;
		if (m_hBattleJYEvent) {
			CloseHandle(m_hBattleJYEvent);
			m_hBattleJYEvent = NULL;
		}

	}

	DWORD __stdcall CAction::BattleJYThread(LPVOID lpParam)
	{
		int i = 0;
		Sleep(20000);
		CAction* pThis = (CAction*)lpParam;
		do
		{
			GameGlobal::DebugLog(_T("start.打镜妖 %d----------------------------"), i);
			pThis->FightingJY(pThis->m_bHasSummoner, pThis->m_nSummonerSkillType, pThis->m_bTargetOfRoleSkill);
			GameGlobal::DebugLog(_T("end.打镜妖 %d----------------------------\n"), i++);
		} while (WaitForSingleObject(pThis->m_hBattleJYEvent, 200) == WAIT_TIMEOUT);

		return 0;
	}

	void CAction::StartSkill()
	{
		m_hBattleJYEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
		if (m_hBattleJYEvent == NULL) {
			_tprintf_s(_T("创建事件失败\n"));
			return;
			
		}
		
		m_hBattleJY = CreateThread(NULL, 0, SkillThread, this, 0, NULL);
		if (m_hBattleJY == NULL) {
			_tprintf_s(_T("创建线程失败\n"));
			
			if (m_hBattleJYEvent) {
				SetEvent(m_hBattleJYEvent);
				CloseHandle(m_hBattleJYEvent);
				m_hBattleJYEvent = NULL;
				
			}			
		}
	}
	
	void CAction::StopSkill()
	{
		// 设置事件有信号;
		if (m_hBattleJYEvent)
			SetEvent(m_hBattleJYEvent);
		
		// 等待线程结束;
		if (m_hBattleJY) {
			WaitForSingleObject(m_hBattleJY, INFINITE);
			CloseHandle(m_hBattleJY);
			m_hBattleJY = NULL;			
		}
		
		// 关闭事件句柄;
		if (m_hBattleJYEvent) {
			CloseHandle(m_hBattleJYEvent);
			m_hBattleJYEvent = NULL;			
		}
	}
	
	DWORD __stdcall CAction::SkillThread(LPVOID lpParam)
	{
		int i = 0;
		CAction * pThis = (CAction*)lpParam;
		do
		{
			GameGlobal::DebugLog(_T("start.打镜妖 %d----------------------------"), i);
			pThis->ExerciseSkill(pThis->m_nSkillShortcutKey, pThis->m_bTargetOfRoleSkill);
			GameGlobal::DebugLog(_T("end.打镜妖 %d----------------------------\n"), i++);
		} while (WaitForSingleObject(pThis->m_hBattleJYEvent, 200) == WAIT_TIMEOUT);

		return 0;
	}
};