bayuMIR/Mirserver/Mir200/Envir/QuestDiary/util/自动巡航下图.lua
2026-06-26 04:18:02 +08:00

428 lines
12 KiB
Lua

AutoXunHangOBJ = Up_BaseClass:new()
AutoXunHangOBJ._name = "AutoXunHangOBJ"
AutoXunHangOBJ.maxMap = 3
function AutoXunHangOBJ:getMapCfg(mapid)
if not mapid or not MapCfg or not MapCfg.dalumap then
return nil
end
return MapCfg.dalumap[mapid] or MapCfg.dalumap[tostring(mapid)] or MapCfg.dalumap[tonumber(mapid)]
end
function AutoXunHangOBJ:isForbidMap(mapid)
local cfg = self:getMapCfg(mapid)
if not cfg then
return true, "地图配置不存在!"
end
if cfg.xunhang then
return true, "当前地图禁止巡航!"
end
return false
end
function AutoXunHangOBJ:getMaps(actor)
local str = Player.getstr(actor, VarCfg.Player.str["自动巡航地图"]) or ""
if str == "" then
return {}
end
local ok, data = pcall(json2tbl, str)
if ok and type(data) == "table" then
return data
end
return {}
end
function AutoXunHangOBJ:saveMaps(actor, maps)
Player.setstr(actor, VarCfg.Player.str["自动巡航地图"], tbl2json(maps or {}))
end
function AutoXunHangOBJ:getSetting(actor)
return {
autoKuangBao = Player.getint(actor, VarCfg.Player.int["自动巡航自动狂暴"]) or 0,
dieStop = Player.getint(actor, VarCfg.Player.int["自动巡航死亡停止"]) or 0,
noAttackSec = Player.getint(actor, VarCfg.Player.int["自动巡航未攻击切图"]) or 0,
orderMode = Player.getint(actor, VarCfg.Player.int["自动巡航顺序下图"]) or 0,
}
end
function AutoXunHangOBJ:isOpen(actor)
return (Player.gettempint(actor, VarCfg.Player.temp.int["自动巡航开关"]) or 0) == 1
end
function AutoXunHangOBJ:setOpen(actor, value)
Player.settempint(actor, VarCfg.Player.temp.int["自动巡航开关"], value and 1 or 0)
end
function AutoXunHangOBJ:setLastAttack(actor)
Player.settempint(actor, VarCfg.Player.temp.int["自动巡航最后攻击"], os.time())
end
function AutoXunHangOBJ:getLastAttack(actor)
return Player.gettempint(actor, VarCfg.Player.temp.int["自动巡航最后攻击"]) or 0
end
function AutoXunHangOBJ:startTimer(actor)
local timerId = VarCfg.Timer["自动巡航巡检"]
if not hastimer(actor, timerId) then
setontimer(actor, timerId, 3, 0)
end
end
function AutoXunHangOBJ:stopTimer(actor)
local timerId = VarCfg.Timer["自动巡航巡检"]
if hastimer(actor, timerId) then
setofftimer(actor, timerId)
end
end
function AutoXunHangOBJ:getClientData(actor)
local setting = self:getSetting(actor)
return {
maps = self:getMaps(actor),
isOpen = self:isOpen(actor) and 1 or 0,
autoKuangBao = setting.autoKuangBao,
dieStop = setting.dieStop,
dieCount = Player.gettempint(actor, VarCfg.Player.temp.int["自动巡航死亡次数"]) or 0,
noAttackSec = setting.noAttackSec,
orderMode = setting.orderMode,
}
end
function AutoXunHangOBJ:sendSync(actor)
Message:SubLink(actor, self._name .. "_syncData", self:getClientData(actor))
end
function AutoXunHangOBJ:sync(actor)
self:sendSync(actor)
end
function AutoXunHangOBJ:recordMap(actor, p1, p2, p3, data)
data = type(data) == "table" and (data[1] or data) or data
local idx = tonumber(data and data.index or data) or 0
if idx < 1 or idx > self.maxMap then
Func.sendmsg9(actor, "记录位置无效!")
self:sendSync(actor)
return
end
local mapid = getbaseinfo(actor, ConstCfg.gbase.mapid)
local forbid, msg = self:isForbidMap(mapid)
if forbid then
Func.sendmsg9(actor, msg)
self:sendSync(actor)
return
end
local maps = self:getMaps(actor)
for i, v in ipairs(maps) do
if i ~= idx and tostring(v) == tostring(mapid) then
Func.sendmsg9(actor, "该地图已记录!")
self:sendSync(actor)
return
end
end
maps[idx] = mapid
self:saveMaps(actor, maps)
Func.sendmsg9(actor, string.format("已记录巡航地图:%s", tostring(mapid)))
self:sendSync(actor)
end
function AutoXunHangOBJ:delMap(actor, p1, p2, p3, data)
data = type(data) == "table" and (data[1] or data) or data
local idx = tonumber(data and data.index or data) or 0
local maps = self:getMaps(actor)
if idx > 0 and maps[idx] then
table.remove(maps, idx)
self:saveMaps(actor, maps)
Func.sendmsg9(actor, "已删除巡航地图!")
end
self:sendSync(actor)
end
function AutoXunHangOBJ:saveSetting(actor, p1, p2, p3, data)
data = type(data) == "table" and (data[1] or data) or {}
local autoKuangBao = tonumber(data.autoKuangBao) or 0
local dieStop = math.max(0, tonumber(data.dieStop) or 0)
local noAttackSec = math.max(0, tonumber(data.noAttackSec) or 0)
local orderMode = tonumber(data.orderMode) or 0
Player.setint(actor, VarCfg.Player.int["自动巡航自动狂暴"], autoKuangBao == 1 and 1 or 0)
Player.setint(actor, VarCfg.Player.int["自动巡航死亡停止"], dieStop)
Player.setint(actor, VarCfg.Player.int["自动巡航未攻击切图"], noAttackSec)
Player.setint(actor, VarCfg.Player.int["自动巡航顺序下图"], orderMode == 1 and 1 or 0)
Func.sendmsg9(actor, "自动巡航设置已保存!")
self:sendSync(actor)
end
function AutoXunHangOBJ:getCanGotoMaps(actor, excludeMap)
local ret = {}
for _, mapid in ipairs(self:getMaps(actor)) do
if tostring(mapid) ~= tostring(excludeMap) then
local forbid = self:isForbidMap(mapid)
if not forbid then
table.insert(ret, mapid)
end
end
end
return ret
end
function AutoXunHangOBJ:isRecordMap(actor, mapid)
for _, v in ipairs(self:getMaps(actor)) do
if tostring(v) == tostring(mapid) then
return true
end
end
return false
end
function AutoXunHangOBJ:tryOpenKuangBao(actor)
local setting = self:getSetting(actor)
if setting.autoKuangBao ~= 1 then
return
end
if checktitle(actor, "狂暴之力") then
return
end
if KuangBaoOBJ and KuangBaoOBJ.up then
KuangBaoOBJ:up(actor)
end
end
function AutoXunHangOBJ:checkMapCost(actor, mapid)
self:tryOpenKuangBao(actor)
if MapCfg and MapCfg.checkgotomap and not MapCfg.checkgotomap(actor, mapid) then
return false
end
if NPCGotoMapOBJ and NPCGotoMapOBJ.checkgotomapByMapId then
if not NPCGotoMapOBJ:checkgotomapByMapId(actor, mapid, true) then
return false
end
end
return true
end
function AutoXunHangOBJ:gotoMap(actor, mapid)
local forbid, msg = self:isForbidMap(mapid)
if forbid then
Func.sendmsg9(actor, msg)
self:stop(actor, nil, nil, nil, { nomsg = 1 })
return false
end
if not self:checkMapCost(actor, mapid) then
self:stop(actor, nil, nil, nil, { nomsg = 1 })
return false
end
MapCfg.gotomap(actor, mapid)
startautoattack(actor)
self:setLastAttack(actor)
self:sendSync(actor)
return true
end
function AutoXunHangOBJ:selectNextMap(actor, excludeMap)
local setting = self:getSetting(actor)
local maps = self:getMaps(actor)
if setting.orderMode ~= 1 then
local canMaps = self:getCanGotoMaps(actor, excludeMap)
if #canMaps == 0 then
return nil
end
return canMaps[math.random(1, #canMaps)]
end
local startIndex = 0
if excludeMap then
for i, mapid in ipairs(maps) do
if tostring(mapid) == tostring(excludeMap) then
startIndex = i
break
end
end
end
for i = 1, #maps do
local index = ((startIndex + i - 1) % #maps) + 1
local mapid = maps[index]
if tostring(mapid) ~= tostring(excludeMap) then
local forbid = self:isForbidMap(mapid)
if not forbid then
return mapid
end
end
end
return nil
end
function AutoXunHangOBJ:gotoRandomMap(actor)
local curMap = getbaseinfo(actor, ConstCfg.gbase.mapid)
local mapid = self:selectNextMap(actor, curMap)
if not mapid then
return false
end
return self:gotoMap(actor, mapid)
end
function AutoXunHangOBJ:start(actor)
if getflagstatus(actor, VarCfg.Falg_tequan) == 0 then
Func.sendmsg9(actor, "开通王者特权后才可开启自动巡航!")
self:sendSync(actor)
return
end
local maps = self:getMaps(actor)
if #maps == 0 then
Func.sendmsg9(actor, "请先记录巡航地图!")
self:sendSync(actor)
return
end
local curMap = getbaseinfo(actor, ConstCfg.gbase.mapid)
local curMapRecorded = false
for _, mapid in ipairs(maps) do
if tostring(mapid) == tostring(curMap) then
curMapRecorded = true
break
end
end
local curMapForbid = self:isForbidMap(curMap)
if curMapRecorded and not curMapForbid then
if not self:checkMapCost(actor, curMap) then
self:sendSync(actor)
return
end
self:setOpen(actor, true)
Player.settempint(actor, VarCfg.Player.temp.int["自动巡航死亡次数"], 0)
self:setLastAttack(actor)
self:startTimer(actor)
startautoattack(actor)
Func.sendmsg9(actor, "自动巡航已开启!")
self:sendSync(actor)
return
end
local targetMap = self:selectNextMap(actor, curMapRecorded and curMap or nil)
if not targetMap then
Func.sendmsg9(actor, "没有可巡航的记录地图!")
self:sendSync(actor)
return
end
self:setOpen(actor, true)
Player.settempint(actor, VarCfg.Player.temp.int["自动巡航死亡次数"], 0)
self:setLastAttack(actor)
self:startTimer(actor)
if self:gotoMap(actor, targetMap) then
Func.sendmsg9(actor, "自动巡航已开启!")
end
end
function AutoXunHangOBJ:stop(actor, p1, p2, p3, data)
self:setOpen(actor, false)
self:stopTimer(actor)
stopautoattack(actor)
if not data or data.nomsg ~= 1 then
Func.sendmsg9(actor, "自动巡航已停止!")
end
self:sendSync(actor)
end
function AutoXunHangOBJ:onTimer(actor)
if not self:isOpen(actor) then
self:stopTimer(actor)
return
end
local curMap = getbaseinfo(actor, ConstCfg.gbase.mapid)
local forbid, msg = self:isForbidMap(curMap)
if forbid then
Func.sendmsg9(actor, msg)
self:stop(actor, nil, nil, nil, { nomsg = 1 })
return
end
if not self:isRecordMap(actor, curMap) then
if not self:gotoRandomMap(actor) then
self:stop(actor, nil, nil, nil, { nomsg = 1 })
end
return
end
startautoattack(actor)
local setting = self:getSetting(actor)
if setting.noAttackSec <= 0 then
return
end
local lastAttack = self:getLastAttack(actor)
if lastAttack <= 0 then
self:setLastAttack(actor)
return
end
if os.time() - lastAttack >= setting.noAttackSec then
self:gotoRandomMap(actor)
end
end
function AutoXunHangOBJ:onAttackMon(actor)
if self:isOpen(actor) then
self:setLastAttack(actor)
end
end
function AutoXunHangOBJ:onNextdie(actor)
if not self:isOpen(actor) then
return
end
local dieCount = (Player.gettempint(actor, VarCfg.Player.temp.int["自动巡航死亡次数"]) or 0) + 1
Player.settempint(actor, VarCfg.Player.temp.int["自动巡航死亡次数"], dieCount)
local setting = self:getSetting(actor)
if setting.dieStop > 0 and dieCount >= setting.dieStop then
Func.sendmsg9(actor, "死亡次数达到设置值,自动巡航已停止!")
self:stop(actor, nil, nil, nil, { nomsg = 1 })
return
end
self:sendSync(actor)
end
function AutoXunHangOBJ:onRevive(actor)
if not self:isOpen(actor) then
return
end
if not self:gotoRandomMap(actor) then
startautoattack(actor)
self:setLastAttack(actor)
end
end
GameEvent.add(EventCfg.onAttackMon, function(actor)
AutoXunHangOBJ:onAttackMon(actor)
end, AutoXunHangOBJ)
GameEvent.add(EventCfg.onNextdie, function(actor)
AutoXunHangOBJ:onNextdie(actor)
end, AutoXunHangOBJ)
GameEvent.add(EventCfg.onRevive, function(actor)
AutoXunHangOBJ:onRevive(actor)
end, AutoXunHangOBJ)
GameEvent.add(EventCfg.onExitGame, function(actor)
AutoXunHangOBJ:setOpen(actor, false)
AutoXunHangOBJ:stopTimer(actor)
end, AutoXunHangOBJ)
AutoXunHangOBJ.allowFunc = { "recordMap", "delMap", "start", "stop", "saveSetting", "sync" }
return AutoXunHangOBJ