ShowMessage("刷马贼脚本版本 $Rev: 214 $")

System:LoadScript("graph")


--[[
[author]
script_name="刷马贼"
cmd0str=根据收集的信息刷
cmd0=0
cmd1str=只刷当前地图
cmd1=1
cmd2str=先刷当前地图，然后根据收集的信息刷
cmd2=3
cmd_default=0
chk0str=使用定位符
]]--

local g_TransferItem = false
local g_MaZeiPos = {}
--嵩山
g_MaZeiPos[3] = { {x=56,y=57},{x=84,y=140},{x=119,y=138},{x=46,y=171},{x=52,y=223},{x=94,y=268},{x=175,y=248},{x=187,y=170},{x=215,y=271},{x=251,y=269},{x=278,y=270},{x=251,y=204},{x=250,y=91} }
--太湖
g_MaZeiPos[4] = { {x=165,y=254},{x=89,y=253},{x=53,y=220},{x=124,y=147},{x=127,y=64},{x=158,y=44},{x=234,y=61},{x=241,y=145},{x=179,y=170},{x=180,y=200},{x=218,y=218},{x=269,y=196},{x=261,y=246} }
--镜湖
g_MaZeiPos[5] = { {x=191,y=46}, {x=70,y=44} , {x=119,y=83}, {x=125,y=88}, {x=128,y=143}, {x=119,y=169}, {x=108,y=146}, {x=45,y=204}, {x=69,y=263}, {x=48,y=256}, {x=38,y=276}, {x=108,y=272}, {x=169,y=224}, {x=225,y=257}, {x=238,y=252} }
--敦煌
g_MaZeiPos[8] = { {x=239,y=164}, {x=178,y=154}, {x=164,y=118}, {x=246,y=71}, {x=261,y=52}, {x=124,y=108}, {x=66,y=78}, {x=97,y=128}, {x=77,y=152}, {x=116,y=183}, {x=51,y=213}, {x=112,y=217}, {x=203,y=234}}
--雁南
g_MaZeiPos[18] = { {x=54,y=50},{x=56,y=103},{x=56,y=143},{x=137,y=116},{x=119,y=165},{x=83,y=180},{x=97,y=206},{x=81,y=245},{x=51,y=261},{x=192,y=270},{x=228,y=271},{x=238,y=233},{x=194,y=216},{x=266,y=179},{x=218,y=115},{x=249,y=47},{x=163,y=73},{x=102,y=44} }
--雁北
g_MaZeiPos[19] = { {x=254,y=175},{x=251,y=165},{x=266,y=51},{x=192,y=48},{x=113,y=39},{x=47,y=87},{x=40,y=130},{x=105,y=101},{x=151,y=119},{x=74,y=190},{x=114,y=261} }
--草原
g_MaZeiPos[20] = { {x=254,y=222}, {x=258,y=285}, {x=177,y=244}, {x=106,y=252}, {x=50,y=265}, {x=82,y=230}, {x=109,y=181}, {x=49,y=163}, {x=49,y=52}, {x=109,y=40}, {x=129,y=118}, {x=191,y=128}, {x=186,y=84}, {x=270,y=89}}
--辽西
g_MaZeiPos[21] = { {x=101,y=262}, {x=170,y=270} , {x=84,y=225}, {x=93,y=201}, {x=55,y=189}, {x=55,y=156}, {x=61,y=91}, {x=103,y=58}, {x=113,y=92}, {x=233,y=50}, {x=275,y=86}, {x=248,y=125}, {x=224,y=143}, {x=151,y=137}, {x=155,y=170},{x=225,y=201}, {x=268,y=223}, {x=219,y=259} , {x=271,y=252}}
--长白山
g_MaZeiPos[22] = { {x=86,y=269}, {x=167,y=264} , {x=199,y=200}, {x=250,y=154}, {x=104,y=200}, {x=60,y=192}, {x=56,y=168}, {x=45,y=126}, {x=93,y=147},{x=42,y=80}, {x=92,y=57}, {x=148,y=57}, {x=158,y=99}, {x=271,y=85} }
--黄龙府
g_MaZeiPos[23] = { {x=64,y=194},{x=54,y=117},{x=119,y=82},{x=252,y=53},{x=252,y=108},{x=263,y=270},{x=218,y=254},{x=196,y=177},{x=171,y=278},{x=119,y=275},{x=108,y=216} }
--洱海
g_MaZeiPos[24] = { {x=206,y=130}, {x=187,y=139}, {x=149,y=99}, {x=135,y=143}, {x=77,y=100}, {x=62,y=148}, {x=44,y=185}, {x=96,y=196}, {x=81,y=236}, {x=87,y=266}, {x=155,y=234}, {x=170,y=266}, {x=181,y=232}, {x=230,y=269},{x=240,y=215}, {x=252,y=167}}
--苍山
g_MaZeiPos[25] = { {x=162,y=54}, {x=153,y=100} , {x=139,y=107}, {x=95,y=130}, {x=105,y=123}, {x=62,y=72}, {x=95,y=130}, {x=71,y=187}, {x=63,y=214}, {x=49,y=257}, {x=87,y=136}, {x=112,y=222}, {x=157,y=143}, {x=195,y=157},{x=156,y=195}, {x=169,y=261}, {x=227,y=263}, {x=264,y=267}, {x=214,y=225}, {x=265,y=136}}
--石林
g_MaZeiPos[26] = { {x=174,y=108},{x=206,y=66},{x=98,y=56},{x=48,y=100},{x=87,y=77},{x=118,y=111},{x=105,y=132},{x=85,y=155},{x=112,y=188},{x=139,y=217},{x=44,y=241},{x=105,y=245},{x=231,y=232},{x=256,y=275},{x=242,y=198},{x=258,y=175},{x=235,y=159} }
--玉溪
g_MaZeiPos[27] = { {x=124,y=61},{x=48,y=97},{x=51,y=119},{x=103,y=155},{x=44,y=243},{x=86,y=273},{x=172,y=251},{x=183,y=216},{x=210,y=257},{x=270,y=251},{x=240,y=190},{x=219,y=119},{x=270,y=149},{x=264,y=66},{x=150,y=101} }
--南诏
g_MaZeiPos[28] = { {x=278,y=72},{x=230,y=62},{x=198,y=99},{x=157,y=123},{x=111,y=110},{x=63,y=70},{x=60,y=124},{x=54,y=178},{x=57,y=223},{x=73,y=273},{x=144,y=251},{x=168,y=240},{x=201,y=261},{x=240,y=236},{x=204,y=206},{x=162,y=212},{x=159,y=182},{x=199,y=143},{x=249,y=124},{x=275,y=146},{x=281,y=198} }
--苗疆
g_MaZeiPos[29] = { {x=65,y=47},{x=43,y=110},{x=42,y=217},{x=119,y=207},{x=158,y=194},{x=218,y=215},{x=275,y=270},{x=192,y=148},{x=239,y=102},{x=171,y=74},{x=126,y=100} }
--西湖
g_MaZeiPos[30] = { {x=83,y=77},{x=112,y=95},{x=105,y=175},{x=62,y=187},{x=112,y=229},{x=76,y=245},{x=101,y=257},{x=183,y=195},{x=210,y=210},{x=235,y=201},{x=231,y=253},{x=262,y=268},{x=232,y=122} }
--龙泉
g_MaZeiPos[31] = { {x=64,y=245}, {x=106,y=240} , {x=69,y=183}, {x=50,y=123}, {x=105,y=136}, {x=108,y=126}, {x=93,y=75}, {x=193,y=89}, {x=266,y=85}, {x=222,y=119}, {x=172,y=162}, {x=250,y=148}, {x=241,y=169}, {x=40,y=142}, {x=244,y=209}, {x=181,y=224}, {x=158,y=270}, {x=265,y=270}, {x=280,y=248} }
--武夷
g_MaZeiPos[32] = { {x=69,y=97},{x=52,y=215},{x=86,y=257},{x=150,y=262},{x=188,y=277},{x=199,y=243},{x=129,y=175},{x=211,y=184},{x=239,y=167},{x=267,y=100},{x=274,y=58},{x=199,y=124},{x=195,y=90},{x=216,y=80},{x=227,y=66},{x=145,y=45} }
--梅岭
g_MaZeiPos[33] = { {x=68,y=254},{x=64,y=225},{x=49,y=100},{x=101,y=54},{x=137,y=71},{x=113,y=125},{x=142,y=135},{x=126,y=189},{x=150,y=218},{x=132,y=261},{x=197,y=262},{x=250,y=269},{x=226,y=165},{x=268,y=191},{x=269,y=112},{x=238,y=75},{x=246,y=41} }
--南海
g_MaZeiPos[34] = { {x=66,y=42},{x=123,y=45},{x=198,y=61},{x=175,y=88},{x=115,y=107},{x=149,y=160},{x=168,y=206},{x=112,y=224},{x=105,y=200},{x=62,y=178},{x=106,y=141},{x=159,y=255},{x=234,y=280},{x=234,y=219},{x=283,y=149},{x=278,y=90},{x=277,y=59} }
--琼州
g_MaZeiPos[35] = { {x=269,y=263},{x=209,y=271},{x=206,y=209},{x=202,y=173},{x=258,y=190},{x=247,y=110},{x=269,y=50},{x=218,y=56},{x=172,y=49},{x=76,y=40},{x=108,y=68},{x=184,y=91},{x=108,y=108},{x=120,y=161},{x=66,y=208},{x=132,y=249},{x=200,y=173} }


local g_szNpcName = "夺宝马贼"
local g_szSceneArray = ""
local g_Records = {}
local g_nSceneID = -1	-- 当前刷马贼地图

-- 设置搜索坐标点
function SetArray(nSceneID)

	if g_MaZeiPos[nSceneID] == nil then return end

	local n = 0
	g_Array = nil
	g_Array = {}
	
	for i, pos in pairs(g_MaZeiPos[nSceneID]) do
		g_Array[n] = pos
		n = n+1
	end
end

-- 查找马贼地图记录
function FindRecord(time, mapname)
	
	for i, k in pairs(g_Records) do
		if k.t == time and k.m == mapname then
			return true
		end
	end
	return false
end

-- 保存马贼地图记录
function PushRecord(time, mapname)

	if FindRecord(time, mapname) == false then
		local i = table.getn(g_Records)
		g_Records[i] = {}
		g_Records[i].t = time
		g_Records[i].m = mapname
	end

end

-- 取得可存在马贼的地图
function GetMaZeiSceneID()
		
	local nMZMapCount = AI:GetMaZeiMapCount()
	
	if nMZMapCount <= 0 then return -1 end
	
	local szCurSceneName = GetActiveSceneName()
	
	DbgPrintf("当前地图 %s", szCurSceneName)

	local dist_min = 999999
	local _time = 0
	local _mapname = ""
	
	for i=1, nMZMapCount do
	
		local time, mapname = AI:GetMaZeiMap(i-1)
		
		if time ~= 0 and mapname ~= "" then
		
			if g_szScene == "" or string.find(g_szScene, mapname) ~= nil then

				local inte = os.time() - time

				DbgPrintf("间隔时间 %s", tostring(inte))
			
				if inte <= 900 then
--[[				
					if FindRecord(time, mapname) == false then
						_time = time
						_mapname = mapname
						break
]]--
					local dist = CMGraph:GetDist(szCurSceneName, mapname)
					DbgPrintf("%s %d %d %d", mapname, dist, inte, dist + inte)
					if dist + inte < dist_min then
							_time = time
							_mapname = mapname
							dist_min = dist + inte
					end
				end
			end
		end
		
	end
	
	return DataBase:GetSceneID(_mapname), _time, _mapname
end

function FindObject(fX, fY, nScene)
	
	local sid = INVALID_ID
	
	sid = LockNearestTarget(g_szNpcName, CHA_TYPE_NPC|CHA_RELATION_FRIEND|CHA_RELATION_ENEMY|CHA_OCCUPANT_FREE|CHA_OCCUPANT_MYSELF|CHA_OCCUPANT_TEAM|CHA_STATE_ALIVE )
		
	if sid == INVALID_ID then
		return INVALID_ID
	end

	if Character:IsPresent(sid) == false then 
		return INVALID_ID
	end
		
	local level = Character:GetData(sid, "LEVEL")
		
	if level <= 0 or level > Player:GetData("LEVEL") then 
		return INVALID_ID
	end

	return sid
end

local PreRide = false 

function _callback(fX, fY, nScene)

	if GetMount() ~= INVALID_ID then
		if PreRide == false then
			 Player:EnableTeamFollow(true)
			UpdateMsg("CheckTeamFollow")
		else
			if IsMsgCold("CheckTeamFollow" , 10000) == true then
				Player:EnableTeamFollow(true)
				UpdateMsg("CheckTeamFollow")
			end
		end

		PreRide = true 
	else
		if PreRide == true then 
			Player:EnableTeamFollow(false)
			UpdateMsg("CheckTeamFollow_False")
		else
			if IsMsgCold("CheckTeamFollow_False" , 10000) == true then
				Player:EnableTeamFollow(false)
				UpdateMsg("CheckTeamFollow_False")
			end
		end
		PreRide = false
	end


	if FindObject(fX, fY, nScene) == INVALID_ID then
		return true 
	end
 
	return false
end


-- 搜索单个场景
function SearchSingleScene(nSceneID)

	if g_MaZeiPos[nSceneID] == nil then return end

	g_nSceneID = nSceneID

	local bBreakSearch = false
	local nThisMapKillMazei = 0 
	UpdateMsg("SearchSingleScene")
	
	for i, v in pairs(g_MaZeiPos[nSceneID]) do
	
		while true do

			-- 团队少于三人
			-- if DataPool:GetTeamMemCount() < 3 then
			--	g_nSceneID = -1
			--	return
			-- end
	
			local sid = LockNearestTarget(g_szNpcName, CHA_TYPE_NPC|CHA_RELATION_ENEMY|CHA_OCCUPANT_FREE|CHA_OCCUPANT_MYSELF|CHA_OCCUPANT_TEAM|CHA_STATE_ALIVE  )

			if sid ~= INVALID_ID  then
				--有马贼可杀
				nThisMapKillMazei = nThisMapKillMazei + 1
				Player:EnableTeamFollow(false)
				AI:SetAI("杀怪")
				AI:SetParameter("初始化")
				AI:SetParameter("目标", "添加", "夺宝马贼")
				AI:SetParameter("拾取", PM_PICKUP)
				AI:Start(true)

				while true do
					local mazei = LockNearestTarget(g_szNpcName, CHA_TYPE_NPC|CHA_RELATION_ENEMY|CHA_OCCUPANT_FREE|CHA_OCCUPANT_MYSELF|CHA_OCCUPANT_TEAM|CHA_STATE_ALIVE  )
					local bag = LockNearestTarget( "" , CHA_TYPE_BAG )
					--没有背包和马贼的时候
					if mazei == INVALID_ID and bag == INVALID_ID then 
						break 
					end
				end

				AI:Stop()

				UpdateMsg("Mazei_End_Hunt")
				System:Sleep(1000)

			else
				local xNow, yNow = Player:GetPos()

				-- 判断是否到达
				local MaZeiID = FindObject(xNow , yNow , nSceneId )

				if MaZeiID ~= INVALID_ID then
					--有马贼npc可以对话
					QuestFrameSpeak(MaZeiID, "")
					Dismount()
					Player:EnableTeamFollow(false)
					System:Sleep(1000)
				else
					--无马贼和npc时
					while IsMsgCold("Mazei_End_Hunt" , 3000) == false do
						DoMount(true)
					end
					--System:Sleep(1000)
					Player:EnableTeamFollow(true)
					
					MoveTo(v.x, v.y, nSceneID, "", 3, true, _callback , true , false , g_TransferItem )

					xNow, yNow = Player:GetPos()
					if FindObject(xNow , yNow , nSceneId ) == INVALID_ID then
						--准备寻下一个坐标
						--如果本地图未寻到任何马贼,且寻路超过2分钟,且有新的地图出现,则去下一个地图
						local new_mapid, new_time, new_mapname = GetMaZeiSceneID()
						
						if nThisMapKillMazei== 0 and IsMsgCold( "SearchSingleScene" , 1000*60*2 ) and new_mapid ~= -1 and new_mapid ~= nSceneId and g_MaZeiPos[new_mapid] ~= nil then
							bBreakSearch = true 
						end

						break 
					end
				end				
			end
		end

		if bBreakSearch == true then 
			break 
		end
	end
			
	g_nSceneID = -1
	
end

function OnMemberKill()

	AI:SetAI("杀怪")
	AI:SetParameter("初始化")
	AI:SetParameter("目标", "添加", "夺宝马贼")
	AI:SetParameter("拾取", PM_PICKUP)
	AI:SetParameter("收费通道" , true )
	AI:SetParameter("使用传送道具" , true )
	AI:SetParameter("跟随时允许自动选怪" , true )
	AI:Start(true)

	AI:SetParameter("运行参数" ,"组队跟随", 1)
	AI:SetParameter("运行参数" ,"辅助攻击", 0)
	AI:SetParameter("运行参数" , "只拾取BOSS掉落" , 1)
	AI:SetParameter("运行参数" , "引怪" , 1)
	AI:SetParameter("运行参数" , "选怪模式" , "红怪专杀")
	while true do 
		if DataPool:IsTeamLeader() == true then 
			break
		end
		if AI:IsStop() == true then
			break 
		end
		System:Sleep(1000)
	end

	AI:Stop()
end

function OnShuaMaZei(nSceneID)

	local last_mapid = -1
	local mapid = -1
	local time = 0
	local mapname = ""
	local save_time = 0
		
	while true do

		-- if DataPool:GetTeamMemCount() < 3 then 
		--	ShowMessage("队伍人数少于3人，刷马结束并前往周天师处！")
		--	MoveToNPC(256, 273, 0, "周天师")
		--	break
		-- end
	
		-- if DataPool:GetTeamMemCount() < 3 then break end

		if DataPool:IsTeamLeader() == false then 
			--队员
			OnMemberKill()
		else
			--队长
			if nSceneID == -1 then	-- 根据聊天信息中的马贼信息自动找图刷马贼

				mapid, time, mapname = GetMaZeiSceneID()
						
				if mapid ~= -1 and g_MaZeiPos[mapid] ~= nil then
				
					if mapid ~= last_mapid then
						ShowMessage("前往%s寻找马贼...", mapname)
						SearchSingleScene(mapid)
					end
					
					PushRecord(time, mapname)
					last_mapid = mapid
					save_time = 0
				
				else
					-- 记录一下没有马贼信息的时间
					if save_time == 0 then
						save_time = os.time()
					else
						if os.time() - save_time > 180 then
							MoveToNPC(256, 273, 0, "周天师")
						else
							PushDebugMessage("正在等待马贼信息..." ,1)
						end
					end
				end

			elseif nSceneID == -2 then	-- 从当前地图开始

				local curSceneID = GetActiveDataSceneID()

				if g_MaZeiPos[curSceneID] == nil then
					ShowMessage("当前地图不是刷马地图！")
					break
				else
					SearchSingleScene(curSceneID)
				end

				nSceneID = -1

			else -- 只刷指定地图

				if g_MaZeiPos[nSceneID] == nil then
					ShowMessage("当前地图不是刷马地图！")
					break
				end
		
				SearchSingleScene(nSceneID)
			
			end			
		end
		System:Sleep(1000)
	end
end

local mode=0

function _SMain(...)

	
	if _CommandLine ~= nil then 
		mode =tonumber(_CommandLine)
	end

	if _CommandChk0 ~= nil and tonumber(_CommandChk0) > 0 then
		g_TransferItem = true 
	end
	
	g_szScene = arg[2]
	
	if mode == 0 then
		OnShuaMaZei(-1)
	elseif mode == 1 then
		OnShuaMaZei(GetActiveDataSceneID())
	elseif mode == 2 then
		OnShuaMaZei(DataBase:GetSceneID(tostring(arg[2])))
	elseif mode == 3 then
		OnShuaMaZei(-2)
	end
	
end

--[[
参数	0:刷马贼模式，必须的
	0：根据收集的信息刷
	1：只刷当前地图
	2：只刷指定地图
	3：先刷当前地图，然后根据收集的信息刷

参数1：刷马贼地图，必须的
当模式为0，参数表示为刷马贼的地图集合，""表示刷所有地图，也可以指定多个地图名称用逗号分开，如:"嵩山,太湖,镜湖"。
当模式为1，参数表示刷马贼的单一地图名称。

_SMain(0, "") 根据收集的信息刷所有地图
			参数为0时可以指定多个地图名称
			当模式为0，参数表示为刷马贼的地图集合，""表示刷所有地图，也可以指定多个地图名称用逗号分开，如:"嵩山,太湖,镜湖"。
			_SMain(0, "嵩山,太湖,镜湖") 表示根据收集的信息只刷这三个地图

_SMain(1, "") 只刷当前地图

_SMain(2, "") 只刷指定地图
			_SMain(2, "石林")	参数为2时 只能指定一个地图名称
			
_SMain(3, "") 先刷当前地图，然后根据收集的信息刷
]]--

CMGraph:Init()
_SMain(0, "")