2021-05-26 23:26:45 +00:00

268 lines
7.8 KiB
Lua

local context = G.botContext
context.getMapView = function() return modules.game_interface.getMapPanel() end
context.getMapPanel = context.getMapView
context.zoomIn = function() modules.game_interface.getMapPanel():zoomIn() end
context.zoomOut = function() modules.game_interface.getMapPanel():zoomOut() end
context.getSpectators = function(param1, param2)
--[[
if param1 is table (position) then it's used for central position, then param2 is used as param1
if param1 is creature, then creature position and direction of creature is used, then param2 is used as param1
if param1 is true/false then it's used for multifloor, example: getSpectators(true)
if param1 is string then it's used for getSpectatorsByPattern
]]--
local pos = context.player:getPosition()
local direction = context.player:getDirection()
if type(param1) == 'table' then
pos = param1
direction = 8 -- invalid direction
param1 = param2
end
if type(param1) == 'userdata' then
pos = param1:getPosition()
direction = param1:getDirection()
param1 = param2
end
if type(param1) == 'string' then
return g_map.getSpectatorsByPattern(pos, param1, direction)
end
local multifloor = false
if type(param1) == 'boolean' and param1 == true then
multifloor = true
end
return g_map.getSpectators(pos, multifloor)
end
context.getCreatureById = function(id, multifloor)
if type(id) ~= 'number' then return nil end
if multifloor ~= true then
multifloor = false
end
for i, spec in ipairs(g_map.getSpectators(context.player:getPosition(), multifloor)) do
if spec:getId() == id then
return spec
end
end
return nil
end
context.getCreatureByName = function(name, multifloor)
if not name then return nil end
name = name:lower()
if multifloor ~= true then
multifloor = false
end
for i, spec in ipairs(g_map.getSpectators(context.player:getPosition(), multifloor)) do
if spec:getName():lower() == name then
return spec
end
end
return nil
end
context.getPlayerByName = function(name, multifloor)
if not name then return nil end
name = name:lower()
if multifloor ~= true then
multifloor = false
end
for i, spec in ipairs(g_map.getSpectators(context.player:getPosition(), multifloor)) do
if spec:isPlayer() and spec:getName():lower() == name then
return spec
end
end
return nil
end
context.findAllPaths = function(start, maxDist, params)
--[[
Available params:
ignoreLastCreature
ignoreCreatures
ignoreNonPathable
ignoreNonWalkable
ignoreStairs
ignoreCost
allowUnseen
allowOnlyVisibleTiles
maxDistanceFrom
]]--
if type(params) ~= 'table' then
params = {}
end
for key, value in pairs(params) do
if value == nil or value == false then
params[key] = 0
elseif value == true then
params[key] = 1
end
end
if type(params['maxDistanceFrom']) == 'table' then
if #params['maxDistanceFrom'] == 2 then
params['maxDistanceFrom'] = params['maxDistanceFrom'][1].x .. "," .. params['maxDistanceFrom'][1].y ..
"," .. params['maxDistanceFrom'][1].z .. "," .. params['maxDistanceFrom'][2]
elseif #params['maxDistanceFrom'] == 4 then
params['maxDistanceFrom'] = params['maxDistanceFrom'][1] .. "," .. params['maxDistanceFrom'][2] ..
"," .. params['maxDistanceFrom'][3] .. "," .. params['maxDistanceFrom'][4]
end
end
return g_map.findEveryPath(start, maxDist, params)
end
context.findEveryPath = context.findAllPaths
context.translateAllPathsToPath = function(paths, destPos)
local predirections = {}
local directions = {}
local destPosStr = destPos
if type(destPos) ~= 'string' then
destPosStr = destPos.x .. "," .. destPos.y .. "," .. destPos.z
end
while destPosStr:len() > 0 do
local node = paths[destPosStr]
if not node then
break
end
if node[3] < 0 then
break
end
table.insert(predirections, node[3])
destPosStr = node[4]
end
-- reverse
for i=#predirections,1,-1 do
table.insert(directions, predirections[i])
end
return directions
end
context.translateEveryPathToPath = context.translateAllPathsToPath
context.findPath = function(startPos, destPos, maxDist, params)
--[[
Available params:
ignoreLastCreature
ignoreCreatures
ignoreNonPathable
ignoreNonWalkable
ignoreStairs
ignoreCost
allowUnseen
allowOnlyVisibleTiles
precision
marginMin
marginMax
maxDistanceFrom
]]--
if not destPos or startPos.z ~= destPos.z then
return
end
if type(maxDist) ~= 'number' then
maxDist = 100
end
if type(params) ~= 'table' then
params = {}
end
local destPosStr = destPos.x .. "," .. destPos.y .. "," .. destPos.z
params["destination"] = destPosStr
local paths = context.findAllPaths(startPos, maxDist, params)
local marginMin = params.marginMin or params.minMargin
local marginMax = params.marginMax or params.maxMargin
if type(marginMin) == 'number' and type(marginMax) == 'number' then
local bestCandidate = nil
local bestCandidatePos = nil
for x = -marginMax, marginMax do
for y = -marginMax, marginMax do
if math.abs(x) >= marginMin or math.abs(y) >= marginMin then
local dest = (destPos.x + x) .. "," .. (destPos.y + y) .. "," .. destPos.z
local node = paths[dest]
if node and (not bestCandidate or bestCandidate[1] > node[1]) then
bestCandidate = node
bestCandidatePos = dest
end
end
end
end
if bestCandidate then
return context.translateAllPathsToPath(paths, bestCandidatePos)
end
return
end
if not paths[destPosStr] then
local precision = params.precision
if type(precision) == 'number' then
for p = 1, precision do
local bestCandidate = nil
local bestCandidatePos = nil
for x = -p, p do
for y = -p, p do
local dest = (destPos.x + x) .. "," .. (destPos.y + y) .. "," .. destPos.z
local node = paths[dest]
if node and (not bestCandidate or bestCandidate[1] > node[1]) then
bestCandidate = node
bestCandidatePos = dest
end
end
end
if bestCandidate then
return context.translateAllPathsToPath(paths, bestCandidatePos)
end
end
end
return nil
end
return context.translateAllPathsToPath(paths, destPos)
end
context.getPath = context.findPath
-- also works as autoWalk(dirs) where dirs is a list eg.: {1,2,3,0,1,1,2,}
context.autoWalk = function(destination, maxDist, params)
if type(destination) == "table" and table.isList(destination) and not maxDist and not params then
g_game.autoWalk(destination, {x=0,y=0,z=0})
return true
end
-- Available params same as for findPath
local path = context.findPath(context.player:getPosition(), destination, maxDist, params)
if not path then
return false
end
-- autowalk without prewalk animation
g_game.autoWalk(path, {x=0,y=0,z=0})
return true
end
context.getTileUnderCursor = function()
if not modules.game_interface.gameMapPanel.mousePos then return end
return modules.game_interface.gameMapPanel:getTile(modules.game_interface.gameMapPanel.mousePos)
end
context.canShoot = function(pos, distance)
if not distance then distance = 5 end
local tile = g_map.getTile(pos, distance)
if tile then
return tile:canShoot(distance)
end
return false
end
context.isTrapped = function(creature)
if not creature then
creature = context.player
end
local pos = creature:getPosition()
local dirs = {{-1,1}, {0,1}, {1,1}, {-1, 0}, {1, 0}, {-1, -1}, {0, -1}, {1, -1}}
for i=1,#dirs do
local tile = g_map.getTile({x=pos.x-dirs[i][1],y=pos.y-dirs[i][2],z=pos.z})
if tile and tile:isWalkable(false) then
return false
end
end
return true
end