Description
A persistent that keeps monsters on your screen when you want to lure them, without the need to add a thousand actions to your waypoints.
init start
WaitForMonsters = true -- Toggle this variable when you dont want to lure.
local Config = {
-- A table of monsters that will be lured.
-- If a string is used, it will be treated as a targeting category.
-- If nil is used all monsters will be considered.
monsters = {"Glooth Bandit", "glooth brigand"},
-- The script will wait for monsters that are further away than this.
longdist = 4,
-- The script will stop waiting if too many monsters get too close.
-- Configure what counts as "too many" and "too close".
maxclose = 4,
closedist = 2,
-- The maximum number of seconds that the script will wait for a monster before blacklisting it.
timeout = 4,
-- The number of seconds that a monster stays blacklisted if it times out.
blacklistTime = 5,
-- The minimum number of milliseconds to walk between lure waits
minwalk = 500,
}
-- Fix the monsters in the config
if type(Config.monsters) == 'table' then
local monsters = {}
for _, name in ipairs(Config.monsters) do
monsters[name:lower()] = true
end
Config.monsters = monsters
elseif type(Config.monsters) == 'string' then
local monsters = {}
foreach settingsentry e 'Targeting/Creatures' do
local name = getsetting(e, 'Name')
local cat = getsetting(e, 'Category')
if not name:find('category') and cat == Config.monsters then
monsters[name:lower()] = true
end
end
Config.monsters = monsters
end
local function distance(x, y, x1, y1)
return math.max(math.abs(x-x1), math.abs(y-y1))
end
local function distanceFromMe(c)
return distance($posx, $posy, c.posx, c.posy)
end
local lx, ly = $posx, $posy
local function updatepos()
if distance($posx, $posy, lx, ly) > 1 then
lx, ly = $posx, $posy
end
end
local function isBehindMe(c)
local dir = $self.dir
local dx, dy = c.posx - $posx, c.posy - $posy
local adx, ady = math.abs(dx), math.abs(dy)
if dir == 'n' then
return dy > 0 or adx > ady
elseif dir == 's' then
return dy < 0 or adx > ady
elseif dir == 'e' then
return dx < 0 or adx < ady
elseif dir == 'w' then
return dx > 0 or adx < ady
end
end
local blacklist = {}
local function needWaitMonster(c, ignoreblacklist)
return isBehindMe(c) and
distanceFromMe(c) >= Config.longdist and
(ignoreblacklist or not blacklist[c.id]) and
c.isreachable
end
local function needwait()
foreach creature c 'ms' do
if (not Config.monsters or Config.monsters[c.name:lower()]) and needWaitMonster(c) then
return true
end
end
return false
end
local function doblacklist()
local now = os.clock()
foreach creature c 'ms' do
if needWaitMonster(c, true) then
blacklist[c.id] = now
end
end
end
local function freeblacklist()
local now = os.clock()
for c, time in pairs(blacklist) do
if now - time >= Config.blacklistTime then
blacklist[c] = nil
end
end
end
local function canwait()
return maround(Config.closedist, unpack(Config.monsters)) <= Config.maxclose
end
local minwalk = Config.minwalk / 1000
local lastwait = os.clock()
local function lurewait()
local t = os.clock()
if needwait() and canwait() and t - lastwait > minwalk then
pausewalking(10000)
while needwait() and canwait() and os.clock() - t <= Config.timeout do
-- In case another persistant calls pausewalking while we're waiting
pausewalking(10000)
waitping()
lastwait = os.clock()
end
if os.clock() - t >= Config.timeout then
doblacklist()
end
pausewalking(0)
end
end
listas("Lurer")
init end
updatepos()
if WaitForMonsters then
lurewait()
end
freeblacklist()
auto(100)
Notes
The script ignores monsters based on the direction your character is facing. I've chosen to only ignore monsters inside the red triangle (rather than on the wrong half of the screen) since the direction you're facing frequently changes when walking diagonally and the other alternative can then lead to you dropping monsters.
Also, this script only keeps the monsters on your screen. You have to enable/disable targeting in some other way. Most people lure between locations, i.e. they add a waypoint somewhere and says "turn on targeting here and kill all monsters. Then start luring again". This is acceptable for Knights, and also Mages in spawns with lots of stairs and holes and similar stuff that prevent luring for long distances. However, in reasonably open single-floor spawns with fairly uniform monster density --like Oramond West and Glooth Bandits-- this is bad. In these spawns you want to always be luring. You stop to pickup loot or if there's more monsters on the screen than you can lure (~8 in Glooth Bandits and ~15 in Oramond West imo), but then you start luring again as soon as the number of monsters is manageable again.
Finally, it's not always worth it to wait for monsters while luring. In particular, it's a very bad idea to wait for monsters when you want to leave the spawn. To this end, I've included a variable that you can toggle to toggle the lurer. However, you have to figure out when to do this on your own.