Skip to content

Instantly share code, notes, and snippets.

@TheUltDev
Last active November 30, 2015 13:16
Show Gist options
  • Save TheUltDev/86aaedf2c294db8a1682 to your computer and use it in GitHub Desktop.
Save TheUltDev/86aaedf2c294db8a1682 to your computer and use it in GitHub Desktop.
Executes an AoE when monsters go invisible
-- Module: Invisible Monster Shooter
-- Description: Executes an AoE when monsters go invisible
-- Version: 2.1.0 (updated 11.30.2015)
-- Created by: Cavitt Glover (Syntax)
-- Table containing every attack configured below
local attack = {}
-- Order attacks by number, 1 being highest priority.
-- eg: exori gran should be a lower number than exori or exori mas.
-- comment out (add two dashes[--]) an attack to disable it.
-- option "mana" should be the minimum mana needed to cast
-- option "direction=true" will face the last known direction (useful for waves).
-- option "radius" should be used with the safety option below
-- option "safety" supports the following values:
-- 2 = triggers when no players in the radius on any visible floor.
-- 1 = triggers when no players in the radius on the current floor.
-- 0 = triggers without any regards to players in the area.
attack[1] = {rune=3200}
--attack[2] = {spell="exori gran", mana=50, radius=1, safety=0}
--attack[3] = {spell="exori mas", mana=80, radius=4, safety=0}
--attack[4] = {spell="exevo vis hur", mana=170, radius=5, safety=0, direction=true}
-- The last known target & his position
local lastTarget, lastPosition = nil, nil
-- The current and max shots to fire after the creature goes invisible
-- the script will stop shooting when the bot retargets
local maxShots = 10
local remainingShots = maxShots
-- Checks if an area of a certain position is safe
local function isAreaPvPSafe(pos, radius, multiFloor)
local spectators = Self.GetSpectators(multiFloor)
for i = 1, #spectators do
local creature = spectators[i]
local distance = getDistanceBetween(pos, creature:Position())
if (distance <= radius and creature:isPlayer()) then
if not creature:isPartyMember() then
return false
end
end
end
return true
end
-- Triggered when a target goes invisible
-- it finds a valid attack configured above and fires it once.
local function shoot()
for i = 1, #attack do
local opt = attack[i]
local attackMode = opt.safety or 0
local shootPos = lastPosition or Self.Position()
local isSafe = attackMode == 0 or isAreaPvPSafe(shootPos, opt.radius or 7, attackMode >= 2, true)
if isSafe then
-- Turn if needed
if opt.direction and lastPosition then
Self.Turn(Map.GetDirectionTo(Self.Position(), lastPosition))
wait(200)
end
-- Attack is a spell
if opt.spell then
Self.Cast(opt.spell, opt.mana)
-- Attack is a rune
elseif opt.rune then
Self.UseItemWithGround(opt.rune, shootPos.x, shootPos.y, shootPos.z)
end
return true
end
end
return false
end
-- Listen to error messages
ErrorMessageProxy.OnReceive('Invisible-Monster-Shooter', function(proxy, message)
-- We only react to losing a target
if message ~= 'Target lost.' then return end
-- Target disappeared, start shooting
local targetId = Self.TargetID()
if lastTarget and targetId == 0 and remainingShots == maxShots then
remainingShots = remainingShots - 1
shoot()
end
end)
-- Updates target every tick (200ms)
Module.New('Invisible-Monster-Shooter', function()
local targetId = Self.TargetID()
local target = targetId > 0 and Creature.New(targetId) or nil
if target and target:isAlive() and target:isValid() then
lastTarget = target
lastPosition = target:Position()
remainingShots = maxShots
return
end
-- Continue our volley
if remainingShots > 0 and remainingShots < maxShots then
-- Decrement shots left
remainingShots = remainingShots - 1
-- Shot, delay next check
if shoot() then
wait(200)
end
end
end)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment