Skip to content

Instantly share code, notes, and snippets.

@rmobis
Last active July 4, 2018 22:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rmobis/7963079 to your computer and use it in GitHub Desktop.
Save rmobis/7963079 to your computer and use it in GitHub Desktop.
WindBot Script Requests
init start
local alerts = {
{
name = 'Player on Screen',
sound = 'playeronscreen.wav',
playSound = false,
pauseBot = false,
logout = false,
safelist = {'Bubble', 'Cachero'}
},
{
name = 'Player Attacking',
sound = 'playerattacking.wav',
playSound = false,
pauseBot = false,
logout = false,
safelist = {'Bubble', 'Cachero'}
},
{
name = 'Monster Attacking',
sound = 'monsterattacking.wav',
playSound = false,
pauseBot = false,
logout = false,
safelist = {'Rat', 'Bat'}
},
{
name = 'Private Message',
sound = 'privatemessage.wav',
playSound = false,
pauseBot = false,
logout = false,
safelist = {'Bubble', 'Cachero'}
},
{
name = 'Default Message',
sound = 'defaultmessage.wav',
playSound = false,
pauseBot = false,
logout = false,
safelist = {'Bubble', 'Cachero'}
},
{
name = 'GM Detected',
sound = 'gmdetected.wav',
playSound = false,
pauseBot = false,
logout = false
},
{
name = 'Disconnected',
sound = 'disconnected.wav',
playSound = false,
pauseBot = false,
logout = false
},
{
name = 'Character Stuck',
sound = 'characterstuck.wav',
playSound = false,
pauseBot = false,
logout = false,
stuckTime = 30000 -- ms
},
{
name = 'Health Below',
sound = 'lowhealth.wav',
playSound = false,
pauseBot = false,
logout = false,
pcBelow = 50
},
{
name = 'Mana Below',
sound = 'lowmana.wav',
playSound = false,
pauseBot = false,
logout = false,
pcBelow = 50
}
}
-- Do not edit below this line
do
local tests = {
function(safelist) return paroundignore(10, table.unpack(safelist)) > 0 end,
function(safelist) return $pattacker.id ~= 0 and not table.find(safelist, $pattacker.name:lower()) end,
function(safelist) return $mattacker.id ~= 0 and not table.find(safelist, $mattacker.name:lower()) end,
function(safelist) foreach newmessage m do if m.type == MSG_PVT then return true end end return false end,
function(safelist) foreach newmessage m do if m.type == MSG_WHISPER or m.type == MSG_DEFAULT or m.type == MSG_YELL then return true end end return false end,
function() foreach creature c do if c.name:starts('GM') or c.name:starts('CM') then return true end end return false end,
function() return not $connected end,
function(stuckTime) return $standtime > stuckTime end,
function(pcBelow) return $hppc < pcBelow end,
function(pcBelow) return $mppc < pcBelow end
}
for i = 1, #alerts do
local alert = alerts[i]
alert.test = tests[i]
if alert.safelist then
table.lower(alert.safelist)
end
end
end
init end
auto(100)
listas('Alerts')
for k, v in ipairs(alerts) do
if v.test(v.safelist or v.stuckTime or v.pcBelow) then
if v.playSound then
playsound(v.sound)
end
if v.pauseBot then
pausebot(true)
end
if v.logout then
xlog()
end
end
end
init start
local item = 'life ring' -- Can be a ring or an amulet
-- DO NOT EDIT BELOW THIS LINE
item = itemid(item)
local slot, slotName = $neck, 'neck'
if itemname(item):lower():find('ring') then
slot, slotName = $finger, 'finger'
end
init end
auto(100, 200)
if slot.id ~= item and itemcount(item) > 0 then
equipitem(item, slotName)
waitping()
end
init start
local lastStand = $standtime
local randTime = math.random(300000, 600000)
init end
auto(100)
if $standtime < lastStand then
lastStand = $standtime
end
if $standtime - lastStand > randTime then
local dirs = {'n', 'e', 's', 'w'}
-- Makes sure it's random and not the same we're facing right now
table.remove(dirs, table.find(dirs, $self.dir))
turn(dirs[math.random(1, 3)])
waitping()
lastStand = $standtime
randTime = math.random(300000, 600000)
end
init start
-- local SCRIPT_VERSION = '1.0.1'
local invisCreatures = {'Stalker'}
local stuckTime = 0 -- Set to 0 to always attack
local spellToUse = 'exori'
-- DO NOT EDIT BELOW THIS LINE --
table.lower(invisCreatures)
local spellToUseInfo, spellType = spellinfo(spellToUse), 'spell'
if spellToUseInfo.castarea == 'None' then
spellToUseInfo, spellType = runeinfo(spellToUse), 'rune'
end
init end
auto(100)
if $standtime >= stuckTime then
foreach newmessage m do
if m.type == MSG_STATUSLOG then
local _, _, name = m.content:match(REGEX_DMG_TAKEN)
if name and table.find(invisCreatures, name:lower()) and maround(7, name:lower()) == 0 then
if spellType == 'spell' and cancastspell(spellToUseInfo) then
cast(spellToUseInfo.words)
waitping()
elseif spellType == 'rune' then
useoncreature(spellToUseInfo.itemid, $self)
waitping()
end
end
end
end
end
init start
local hasteSpell = 'utani hur'
-- Do not edit below this line
hasteSpell = spellinfo(hasteSpell)
init end
auto(100)
if $hastetime < $pingaverage * 2 + 500 and cancastspell(hasteSpell) then
cast(hasteSpell.words)
waitping()
end
local account = 'accountName'
local password = 'accountPassword'
local charList = {'Char1', 'Char2', 'Char3', 'Char4'}
local minStamina = 16 * 60 -- In minutes
-- DO NOT EDIT BELOW THIS LINE --
table.lower(charList)
if $stamina < minStamina then
local curChar = table.find(charList, $name:lower())
local nextChar = charList[(curChar % #charList) + 1]
waitandlogout()
waitping()
keyevent(VK_ESCAPE)
waitping()
connect(account, password, nextChar)
end
init start
-- local SCRIPT_VERSION = '2.0.2'
local showProfile = true
local showRelation = true
local showWaypoints = true
local mainWaypoints = {'Node', 'Stand', 'Action', 'Lure'}
local secondaryWaypoints = {'Walk', 'Shovel', 'Rope', 'Machete', 'Ladder', 'Use'}
-- DO NOT EDIT BELOW THIS LINE --
local defFontColor = color(223, 223, 223)
local defBackColor = color(70, 70, 70)
local defHighColor = color(128, 128, 128)
local boxColor = color(70, 70, 70)
local boxLightShadowColor = color(117, 117, 117)
local boxDarkShadowColor = color(41, 41, 41)
local borderSize = 4
local paddingSize = 3
local PROFILE_URL = "http://www.tibia.com/community/?subtopic=characters&Submit.x=1&name="
ALIGN_LEFT = 0
ALIGN_CENTER = 1
ALIGN_RIGHT = 2
MENU_SEPARATOR = '-- SEPARATOR --'
local items, highlight, contextMenu, maxWidth, maxHeight, clicked
do -- Register default handlers
if showProfile then
local function showProfileName(m)
return 'Show page for ' .. m.creature.name
end
local function showProfileCall(m)
openbrowser(PROFILE_URL .. m.creature.name:gsub(' ', '+'))
end
registermessagehandler('contextMenu_player', showProfileName, showProfileCall)
registermessagehandler('contextMenu_player', MENU_SEPARATOR, nil)
end
if showRelation then
local function currentRelationName(m)
if m.creature.id ~= $self.id then
return m.creature.name .. ': ' .. m.creature.teamname, m.creature.teamcolor, nil, color(70, 70, 70)
end
end
registermessagehandler('contextMenu_player', currentRelationName, nil)
registermessagehandler('contextMenu_player', MENU_SEPARATOR, nil)
-- enemy
local function setEnemyName(m)
if m.creature.id ~= $self.id and not m.creature.isenemy then
return 'Set ' .. m.creature.name .. ' as enemy'
end
end
local function setEnemyCall(m)
setrelation(m.creature, 'enemy')
end
registermessagehandler('contextMenu_player', setEnemyName, setEnemyCall)
-- ally
local function setAllyName(m)
if m.creature.id ~= $self.id and (not m.creature.isally or m.creature.isleader) then
return 'Set ' .. m.creature.name .. ' as ally'
end
end
local function setAllyCall(m)
setrelation(m.creature, 'ally')
end
registermessagehandler('contextMenu_player', setAllyName, setAllyCall)
-- leader
local function setLeaderName(m)
if m.creature.id ~= $self.id and not m.creature.isleader then
return 'Set ' .. m.creature.name .. ' as leader'
end
end
local function setLeaderCall(m)
setrelation(m.creature, 'leader')
end
registermessagehandler('contextMenu_player', setLeaderName, setLeaderCall)
registermessagehandler('contextMenu_player', MENU_SEPARATOR, nil)
end
if showWaypoints then
for _, v in ipairs({mainWaypoints, secondaryWaypoints}) do
for _, vv in ipairs(v) do
-- I learned this trick with JavaScript; basically, we call a anonymous
-- function that returns the function we'll actually use. The trick is
-- that we pass to this first anonymous function the type of the node
-- we want the returned function to add. This works because the inner
-- function is created in a scope where `type` has the desired value,
-- so it's value is retained for future calls.
registermessagehandler('contextMenu_world', 'Add ' .. vv, (function(type)
return function(m)
addwaypoint(type, m.posx, m.posy, m.posz)
end
end)(vv))
end
registermessagehandler('contextMenu_world', MENU_SEPARATOR, nil)
end
end
end
local function loadCategories(...)
local categories = {...}
for _, v in ipairs(categories) do
local cat = 'contextMenu_' .. v
foreach messagehandler m cat do
local text, fontColor, backColor, highColor, align
if type(m.name) == 'function' then
text, fontColor, highColor, backColor, align = m.name(contextMenu)
else
text = m.name
end
if text and text ~= '' then
local width
if text == MENU_SEPARATOR then
maxHeight = maxHeight + 8
else
width = (measurestring(text))
maxHeight = maxHeight + 19
maxWidth = math.max(maxWidth, width)
end
table.insert(items, {
text = text,
width = width,
callback = m.callback,
fontColor = fontColor or defFontColor,
highColor = highColor or defHighColor,
backColor = backColor or defBackColor
});
end
end
end
end
filterinput(false, true, true, false)
function inputevents(e)
local eventItem, itemIndex
for i, v in ipairs(items) do
if v.id == e.elementid then
eventItem = v
itemIndex = i
break
end
end
highlight = itemIndex
if e.type == IEVENT_LMOUSEUP then
if eventItem and eventItem.callback then
eventItem.callback(contextMenu)
end
clicked = true
highlight = nil
waitforevents(false)
press('[ESC]')
waitforevents(true)
end
end
setfontstyle('Tahoma', 7, 75, defFontColor, 1, 0x000000)
setantialiasing(true)
init end
auto(10)
contextMenu = contextmenuinfo()
-- This prevents the HUD from redrawing after clicking
if clicked then
clicked = contextMenu ~= nil
contextMenu = nil
end
if contextMenu == nil then
highlight = nil
return
end
items = {}
maxWidth, maxHeight = 0, -4
local fullWidth, fullHeight
do -- Bootstrap
-- Load categories
if contextMenu.type == 'battle' or contextMenu.itemid == 99 then
contextMenu.creature = getcreaturebyid(contextMenu.creatureid)
if contextMenu.creature.isplayer then
loadCategories(contextMenu.type .. 'Player', 'player')
elseif contextMenu.creature.isnpc then
loadCategories(contextMenu.type .. 'NPC', 'NPC')
elseif contextMenu.creature.ismonster then
loadCategories(contextMenu.type .. 'Monster', 'monster')
end
loadCategories(contextMenu.type .. 'Creature', 'creature')
elseif contextMenu.type == 'world' then
loadCategories('worldItem', 'item')
elseif contextMenu.type == 'container' then
loadCategories('containerItem', 'item')
elseif contextMenu.type == 'equip' then
loadCategories('equipItem', 'item')
end
loadCategories(contextMenu.type)
-- We set it as true from the beginning so that it also removes the first
-- item if it's a separator; we obviously don't want the first item to be a
-- separator. NOTE: relies on the fact that ipairs() will traverse the
-- table in ascending order, which isn't guaranteed by the reference manual
-- but is the common implementation
local lastSep = true
-- Instead of removing the items at the for loop, we simply set it to nil
-- and normalize it after; this is because if we did remove it, it would
-- shift the indexes and end up fucking up posterior checks
for i, v in ipairs(items) do
local curSep = v.text == MENU_SEPARATOR
if curSep and (lastSep or i == #items) then
items[i] = nil
maxHeight = maxHeight - 8
end
lastSep = curSep
end
table.normalize(items)
-- No item to display, abort mission!
if #items == 0 then
return
end
-- The Tibia context menu has an extra width of 44 pixels for the longest
-- item; here we account for that
maxWidth = maxWidth + 44
fullWidth, fullHeight = maxWidth + 2*borderSize, maxHeight + 2*borderSize
setposition($clientwin.x + contextMenu.x - fullWidth - 2,$clientwin.y + contextMenu.y)
end
do -- Draw Container
-- Draw main box
setfillstyle('color', boxColor)
setbordercolor(-1)
drawrect(0, 0, fullWidth, fullHeight)
-- Draw shadows
setbordercolor(boxLightShadowColor)
drawline(0, 0, fullWidth, 0)
drawline(0, 0, 0, fullHeight)
drawline(2, fullHeight - 2, fullWidth - borderSize, 0)
drawline(fullWidth - 2, 2, 0, fullHeight - borderSize)
setbordercolor(boxDarkShadowColor)
drawline(2, 2, fullWidth - borderSize, 0)
drawline(2, 2, 0, fullHeight - borderSize)
drawline(0, fullHeight, fullWidth, 0)
drawline(fullWidth, 0, 0, fullHeight)
end
do -- Draw items
local curHeight = borderSize
for i, v in ipairs(items) do
-- Separators get special treatment here
if v.text == MENU_SEPARATOR then
setbordercolor(boxDarkShadowColor)
drawline(borderSize, curHeight, maxWidth, 0)
setbordercolor(boxLightShadowColor)
drawline(borderSize, curHeight + 1, maxWidth, 0)
curHeight = curHeight + 8
else
-- This is a dirty, dirrty attempt of making the code shorter; and
-- that's what I love the most about programming
local alignOffset = ((maxWidth - paddingSize - v.width) / 2) * (v.align or ALIGN_LEFT)
-- Set style
setbordercolor(-1)
setfontcolor(v.fontColor)
setfillstyle('color', tern(i == highlight, v.highColor, v.backColor))
-- Draw stuff
v.id = drawrect(borderSize, curHeight, maxWidth, 15)
drawtext(v.text, borderSize + paddingSize + alignOffset, curHeight + paddingSize)
curHeight = curHeight + 19
end
end
end
init start
local header, closeButton, closed, moving
local cursorPosition = {}
local engines = {'Cavebot', 'Looting', 'Targeting', 'Spell Healer', 'Potion Healer', 'Condition Healer', 'Mana Trainer'}
filterinput(false, true, false, false)
function inputevents(e)
if e.type == IEVENT_LMOUSEUP then
if e.elementid == closeButton then
closed = true
return
end
for _, v in ipairs(engines) do
if e.elementid == v.shape then
toggle(v.name:gsub(' ', '') .. '/Enabled')
return
end
end
elseif e.elementid == header then
if e.type == IEVENT_MMOUSEDOWN then
moving = true
cursorPosition.x = $cursor.x
cursorPosition.y = $cursor.y
return
elseif e.type == IEVENT_MMOUSEUP then
moving = false
return
end
end
end
-- Taken from Sirmate's MMH
local blueGradient = {0.0, color(36, 68, 105, 20), 0.23, color(39, 73, 114, 20), 0.76, color(21, 39, 60, 20)}
local blackGradient = {0.0, color(75, 75, 75, 20), 0.23, color(45, 45, 45, 20), 0.76, color(19, 19, 19, 20)}
local redGradient = {0.0, color(136, 35, 12, 20), 0.23, color(139, 37, 13, 20), 0.76, color(92, 6, 6, 20)}
local greenGradient = {0.0, color(65, 96, 12, 20), 0.23, color(67, 99, 13, 20), 0.76, color(36, 52, 6, 20)}
for k, v in ipairs(engines) do
engines[k] = {
name = v,
shape = nil
}
end
setposition($clientwin.right - 424, $worldwin.top + 300)
setfontstyle('Tahoma', 8, 75, 0xFFFFFF, 1, 0x000000)
setfillstyle('gradient', 'linear', 2, 0, 0, 0, 21)
setbordercolor(color(0, 0, 0, 50))
setantialiasing(true)
init end
auto(100)
if moving then
auto(10)
local curPosition = getposition()
setposition(
curPosition.x + ($cursor.x - cursorPosition.x),
curPosition.y + ($cursor.y - cursorPosition.y)
)
cursorPosition.x = $cursor.x
cursorPosition.y = $cursor.y
end
if closed then
return
end
addgradcolors(table.unpack(blueGradient))
header = addshape('roundrect', 0, 0, 150, 20, 3, 3)
addtext('ENGINE STATES', 24, 3)
addgradcolors(table.unpack(blackGradient))
closeButton = addshape('roundrect', 130, 0, 20, 20, 3, 3)
addtext('X', 137, 3)
local isEnabled
for k, v in ipairs(engines) do
addgradcolors(table.unpack(blackGradient))
addshape('roundrect', 0, k * 23, 150, 20, 3, 3)
addtext(v.name, 6, k * 23 + 3)
isEnabled = get(v.name:gsub(' ', '') .. '/Enabled') == 'yes'
addgradcolors(table.unpack(tern(isEnabled, greenGradient, redGradient)))
engines[k].shape = addshape('roundrect', 120, k * 23, 30, 20, 3, 3)
addtext(tern(isEnabled, 'ON', 'OFF'), 126 + tern(isEnabled, 2, 0), k * 23 + 3)
end
init start
-- local SCRIPT_VERSION = '1.1.1'
-- If set to true, will pause walking and wait for fresh bodies to become
-- 'fisable'.
local waitFresh = false
-- DO NOT EDIT BELOW THIS LINE --
local fishLoot = {281, 282, 3026, 3029, 3032, 9303}
-- I wish I could have made this a more generic function, but it would most
-- likely make it less efficient for the current use case; I know... I will
-- pay for that in the future. Meh... whatever, bring it on!
local function findwaterfishspots(exceptClose)
local hasFresh = false
for x = -7, 7 do
for y = -5, 5 do
-- This lets us ignore bodies that are too close and might fuck
-- up because of character's first movements, but still account
-- for them after it's already standing.
if not exceptClose or (math.abs(x) > 1 or math.abs(y) > 1) then
local curX, curY = $posx + x, $posy + y
local item = topuseonitem(curX, curY, $posz).id
if item == 9582 then
return {x = curX, y = curY}
elseif item == 4037 then
hasFresh = true
end
end
end
end
return nil, hasFresh
end
init end
auto(100)
if $lootsaround == 0 and $targetingtarget.hppc == 0 then
local old, fresh = findwaterfishspots(true)
while old ~= nil or (waitFresh and fresh) do
pausewalking(6^9) -- Yeah babe!
if old ~= nil then
local itemCount = {}
for _, v in ipairs(fishLoot) do
itemCount[v] = itemcount(v)
end
useitemon(3483, 0, ground(old.x, old.y, $posz))
waitping()
for _, v in ipairs(fishLoot) do
local curCount = itemcount(v)
if curCount > itemCount[v] then
increaseamountlooted(v, curCount - itemCount[v])
end
end
end
-- If starting conditions are no longer met, abort mission!
if $lootsaround ~= 0 or $targetingtarget.hppc ~= 0 then
break
end
old, fresh = findwaterfishspots(false)
end
pausewalking(0) -- Orgasm.
end
init start
local minAmount = 30
local randMinAmount = minAmount
init end
auto(1000, 3000)
dontlist()
if flasks() >= randMinAmount then
if maround() ~= 0 then
wait(500, 1000)
else
pausewalking(10000)
for i = 283, 285 do
if itemcount(i) > 0 then
moveitems(i, 'ground')
waitping()
end
end
pausewalking(0)
end
randMinAmount = math.random(minAmount - 5, minAmount + 5)
end
auto(180000, 240000)
eatfoodfull()
init start
-- Friends to heal
local friends = {
'Cachero',
'Bubble'
}
local healHPPC = 100 -- Minimum HPPC to heal
local minHPPC = 30 -- Minimum HPPC you should have to heal
local minMPPC = 30 -- Minimum MPPC you should have to heal
table.lower(friends)
init end
auto(100)
if $hppc >= minHPPC and $mppc >= minMPPC then
foreach creature m 'pt' do
if m.hppc < healHPPC and table.find(friends, m.name:lower()) then
cast('exura sio "' .. m.name:lower())
waitping()
return
end
end
end
init start
local goldIds = {itemid('gold coin'), itemid('platinum coin')}
init end
auto(200, 300)
local cont, item
for i = 0, 15 do
cont = getcontainer(i)
if cont.isopen then
for j = 0, cont.itemcount do
item = cont.item[j]
if item.count == 100 and table.find(goldIds, item.id) then
useitem(item.id, i, j)
waitping()
end
end
end
end
init start
local capMin = 5
local lootCat = 'ds'
local lootRange = 4
-- DO NOT EDIT BELOW THIS LINE --
init end
auto(100, 200)
if $cap > capMin and maround() == 0 and $lootbodies == 0 then
local maxRatio, minDist, bestItem, items = 0, math.huge, nil, {}
foreach lootingitem l lootCat do
-- Add it to list only if we have enough capacity to loot it and still
-- remain above minimum capacity
if $cap > capMin + l.weight then
table.insertsorted(items, {id = l.id, dest = l.destination, ratio = l.sellprice / l.weight}, 'ratio', 'desc')
end
end
-- Find best item/location to collect
for y = -lootRange, lootRange do
for x = -lootRange, lootRange do
if tilereachable($posx + x, $posy + y, $posz) then
local tile = gettile($posx + x, $posy + y, $posz)
-- We do it the other way around so that we can know the actual
-- index of the item in the browsefield, if we need it
local j = 0
for i = tile.itemcount, 1, -1 do
-- Creatures and not moveable items do not appear on the browsefield, so we ignore them
if tile.item[i].id ~= 99 and not itemproperty(tile.item[i].id, ITEM_NOTMOVEABLE) then
j = j + 1
for _, v in ipairs(items) do
if tile.item[i].id == v.id then
local curDist = math.max(0, math.abs(x) - 1) + math.max(0, math.abs(y) - 1)
if v.ratio > maxRatio or (v.ratio == maxRatio and curDist < minDist) then
maxRatio = v.ratio
minDist = curDist
bestItem = {
id = v.id,
dest = v.dest,
index = j,
x = $posx + x,
y = $posy + y
}
end
end
end
end
end
end
end
end
local browseField = getcontainer('Browse Field')
if browseField then
for i = 1, browseField.itemcount do
for _, v in ipairs(items) do
if v.id == browseField.item[i].id and v.ratio >= maxRatio then
maxRatio = v.ratio
minDist = 0
bestItem = {
id = v.id,
dest = v.dest,
-- This means the browse field is already open
index = -1
}
end
end
end
end
if bestItem ~= nil then
set('Cavebot/Enabled', 'no')
-- Only reach if we have to
if minDist ~= 0 then
reachlocation(bestItem.x, bestItem.y, $posz)
waitping()
end
-- No need to use browse field if we're getting the top item
if bestItem.index == 1 then
moveitems(bestItem.id, bestItem.dest, ground(bestItem.x, bestItem.y, $posz))
waitping()
elseif bestItem.index > 1 then
contextmenu('Browse Field', 0, ground(bestItem.x, bestItem.y, $posz))
waitping()
local browseField = getcontainer(windowcount() - 1)
-- Go to last page, because that's where top items are
if browseField.curpage ~= browseField.lastpage then
changepage(browseField.lastpage, browseField.index)
waitping()
-- If the number of items on the last page is lower than the
-- index of our best item, it's actually on the previous page.
if browseField.itemcount < bestItem.index then
previouspage(browseField.index)
waitping()
end
end
moveitems(bestItem.id, bestItem.dest, 'Browse Field')
waitping()
end
set('Cavebot/Enabled', 'yes')
end
end
auto(100)
if $target.id ~= 0 and $target.id ~= $attacked.id then
attack($target.id)
waitping()
end
init start
local capMin = 5
local lootCat = 'ds'
local lootRange = 4
-- DO NOT EDIT BELOW THIS LINE --
init end
auto(100, 200)
if $cap > capMin and maround() == 0 and $lootbodies == 0 then
local maxRatio, minDist, bestItem, items = 0, math.huge, nil, {}
foreach lootingitem l lootCat do
-- Add it to list only if we have enough capacity to loot it and still
-- remain above minimum capacity
if $cap > capMin + l.weight then
table.insertsorted(items, {id = l.id, dest = l.destination, ratio = l.sellprice / l.weight}, 'ratio', 'desc')
end
end
-- Find best item/location to collect
for y = -lootRange, lootRange do
for x = -lootRange, lootRange do
if tilereachable($posx + x, $posy + y, $posz) then
local tile = gettile($posx + x, $posy + y, $posz)
-- We do it the other way around so that we can know the actual
-- index of the item in the browsefield, if we need it
local j = 0
for i = tile.itemcount, 1, -1 do
-- Creatures and not moveable items do not appear on the browsefield, so we ignore them
if tile.item[i].id ~= 99 and not itemproperty(tile.item[i].id, ITEM_NOTMOVEABLE) then
j = j + 1
for _, v in ipairs(items) do
if tile.item[i].id == v.id then
local curDist = math.max(0, math.abs(x) - 1) + math.max(0, math.abs(y) - 1)
if v.ratio > maxRatio or (v.ratio == maxRatio and curDist < minDist) then
maxRatio = v.ratio
minDist = curDist
bestItem = {
id = v.id,
dest = v.dest,
index = j,
x = $posx + x,
y = $posy + y
}
end
end
end
end
end
end
end
end
local browseField = getcontainer('Browse Field')
if browseField then
for i = 1, browseField.itemcount do
for _, v in ipairs(items) do
if v.id == browseField.item[i].id and v.ratio >= maxRatio then
maxRatio = v.ratio
minDist = 0
bestItem = {
id = v.id,
dest = v.dest,
-- This means the browse field is already open
index = -1
}
end
end
end
end
if bestItem ~= nil then
set('Cavebot/Enabled', 'no')
-- Only reach if we have to
if minDist ~= 0 then
reachlocation(bestItem.x, bestItem.y, $posz)
waitping()
end
-- No need to use browse field if we're getting the top item
if bestItem.index == 1 then
moveitems(bestItem.id, bestItem.dest, ground(bestItem.x, bestItem.y, $posz))
waitping()
elseif bestItem.index > 1 then
contextmenu('Browse Field', 0, ground(bestItem.x, bestItem.y, $posz))
waitping()
local browseField = getcontainer(windowcount() - 1)
-- Go to last page, because that's where top items are
if browseField.curpage ~= browseField.lastpage then
changepage(browseField.lastpage, browseField.index)
waitping()
-- If the number of items on the last page is lower than the
-- index of our best item, it's actually on the previous page.
if browseField.itemcount < bestItem.index then
previouspage(browseField.index)
waitping()
end
end
moveitems(bestItem.id, bestItem.dest, 'Browse Field')
waitping()
end
set('Cavebot/Enabled', 'yes')
end
end
init start
-- If set to true, will save kill count to $chardb so that it is persisted
-- throughout different sessions.
local saveToDB = true
-- DO NOT EDIT BELOW THIS LINE --
-- We don't want to override the object because that'd delete all data in
-- killCount.creatures
if killCount == nil then
killCount = {
saveToDB = saveToDB,
creatures = {}
}
killCount.set = function(count, ...)
local names = table.each({...}, string.lower)
for _, v in ipairs(names) do
killCount.creatures[v] = count
if killCount.saveToDB then
$chardb:setvalue('killCount', v, count)
end
end
end
killCount.add = function(addAmount, ...)
local names = table.each({...}, string.lower)
for _, v in ipairs(names) do
killCount.set(killCount.get(v) + addAmount, v)
end
end
killCount.reset = function(...)
killCount.set(0, ...)
end
killCount.get = function(...)
local names = table.each({...}, string.lower)
local count = 0
for _, v in ipairs(names) do
local cCount = killCount.creatures[v]
if cCount == nil then
-- Preferably, I should be loading all this data at boot,
-- but since there's no direct SQL querying, there's no way
-- to loop all the saved data on $chardb, so I have to make
-- it work with this dirty, hacky code.
if killCount.saveToDB then
cCount = $chardb:getvalue('killCount', v)
end
cCount = cCount or 0
killCount.set(cCount, v)
end
count = count + cCount
end
return count
end
end
init end
auto(100)
foreach newmessage m do
if m.type == MSG_INFO then
local creature = m.content:match(REGEX_LOOT)
if creature then
killCount.add(1, creature)
end
end
end
init start
local filename = 'Loot - ' .. $name .. '.txt'
local hideEmpty = false
init end
auto(1000)
local handler = nil
foreach newmessage m do
if m.type == MSG_INFO and not (hideEmpty and m.content:find('nothing')) then
if handler == nil then
handler = io.open(filename, 'a+')
end
handler:write(os.date('%H:%M') .. ' ' .. m.content .. '\n')
end
end
if handler ~= nil then
handler:close()
end
init start
-- local SCRIPT_VERSION = '0.2.3'
-- Where to get the items from; to loot from ground, open the tile's browse
-- field on last page and write 'Browse Field'
local getFrom = 'Beach Backpack'
-- If set to true, will look on all pages, starting from the last one.
local allPages = true
-- If set to true, will open the next backpack on the destinations if it
-- gets full
local openNext = true
-- Specify where each item goes
local config = {
{
items = {'strong health potion', 'strong mana potion', 'soul orb', 'essence of a bad dream', 'poisonous slime'}, -- Items by name
dest = '1' -- Container by index
},
{
items = {'stealth ring', 'dark shield', 'wailing widow\'s necklace'}, -- Items by ID
dest = '2' -- Container by name
},
{
items = {'*'}, -- Use '*' to refer to any item; ignores containers
dest = '3' -- Ground by position
}
}
-- DO NOT EDIT BELOW THIS LINE --
local allItems = {}
for _, v in ipairs(config) do
if table.find(v.items, '*') then
v.items = '*'
else
table.map(v.items, itemid)
allItems = table.merge(allItems, v.items)
end
end
init end
auto(100)
local cont = getcontainer(getFrom)
-- I'm not really into using while loops to iterate over collections, but this
-- seemed to be the only way to do so and still be able to force it to try the
-- same index again; thanks to @Colandus for the heads up
local i = 0
while i < #config do
i = i + 1
local entry = config[i]
-- For the special case of all items, we'll handle it separately, more like
-- 'all items but the ones listed before and containers'. To do so, we
-- actually loop through the items in the container and check that
-- condition.
if entry.items == '*' then
local j = 0
-- Same as above for while loops to iterate over collections
while j < cont.itemcount do
j = j + 1
local item = cont.item[j]
local itemData = iteminfo(item.id)
if not itemData.iscontainer and not table.find(allItems, item.id) then
moveitems(item.id, entry.dest, getFrom)
waitping()
-- Since we messed with the containers items, we don't actually
-- know what's inside it, starting from the last index we
-- checked, so we force it to check again
j = j - 1
end
end
else
for _, item in ipairs(entry.items) do
if itemcount(item, getFrom) > 0 then
moveitems(item, entry.dest, getFrom)
waitping()
end
end
end
-- If it's a container and not a ground location
if openNext and not entry.dest:match('$ground') then
local entryCont = getcontainer(entry.dest)
if entryCont.emptycount == 0 then
-- Going backwards should save us a few comparisions, since the new
-- container should be most likely at the end of the current one
for k = entryCont.itemcount, 1, -1 do
local item = entryCont.item[i]
local itemData = iteminfo(item.id)
if not table.find(entry.items, item.id) and itemData.iscontainer then
openitem(item.id, entryCont.index, false, k)
waitping()
-- Because our destination container got full, some
-- moveitems events might not have been correctly ran, so
-- we try again with the same entry
i = i - 1
end
end
end
end
end
if allPages then
if cont.ispage and cont.curpage ~= 1 then
previouspage(cont.index)
elseif cont.hashigher then
higherwindows(cont.index, true)
end
waitping()
end
init start
--
-- 88
-- "" ,d
-- 88
-- ,adPPYba, 88 8b,dPPYba, 88,dPYba,,adPYba, ,adPPYYba, MM88MMM ,adPPYba,
-- I8[ "" 88 88P' "Y8 88P' "88" "8a "" `Y8 88 a8P_____88
-- `"Y8ba, 88 88 88 88 88 ,adPPPPP88 88 8PP"""""""
-- aa ]8I 88 88 88 88 88 88, ,88 88, "8b, ,aa
-- `"YbbdP"' 88 88 88 88 88 `"8bbdP"Y8 "Y888 `"Ybbd8"'
--
-- Name: Monitor My Stats
-- Last Updated: 19/12/2013
-- Version: 1.0
filterinput(false, true, false, false)
local HUD_Sections = {
{Name = 'OTHERS', State = true, Items = {
{'Ping', function() return $ping .. ' (avg: ' .. $pingaverage .. ')' end},
{'Bank Balance', function() return num($balance) end},
}
},
{Name = 'CHARACTER STATS', State = true, Items = {
{'Level', function() return $level .. ' (' .. 100 - math.floor(($exp - expatlvl($level)) * 100 / (expatlvl($level + 1) - expatlvl($level))) .. '%)' end},
{'Experience', function() return num($exp) end},
{'Magic Level', function() return $mlevel .. ' (' .. 100 - $mlevelpc .. '%)' end},
{'Weapon Skill', function() local _ = WeaponSkill() return _.skill .. ' (' .. 100 - _.skillpc .. '%)' end},
{'Shielding', function() return $shielding .. ' (' .. 100 - $shieldingpc .. '%)' end},
{'Fishing', function() return $fishing .. ' (' .. 100 - $fishingpc .. '%)' end}
}
},
{Name = 'ENGINE STATES', State = true, Items = {
{'Spell Healer', function() return getsetting('SpellHealer/Enabled') end, function() return toggle('SpellHealer/Enabled') end},
{'Potion Healer', function() return getsetting('PotionHealer/Enabled') end, function() return toggle('PotionHealer/Enabled') end},
{'Condition Healer', function() return getsetting('ConditionHealer/Enabled') end, function() return toggle('ConditionHealer/Enabled') end},
{'Mana Training', function() return getsetting('ManaTrainer/Enabled') end, function() return toggle('ManaTrainer/Enabled') end},
{'Cavebot', function() return getsetting('Cavebot/Enabled') end, function() return toggle('Cavebot/Enabled') end},
{'Looting', function() return getsetting('Looting/Enabled') end, function() return toggle('Looting/Enabled') end},
{'Targeting', function() return getsetting('Targeting/Enabled') end, function() return toggle('Targeting/Enabled') end}
}
},
{Name = 'BOTTING STATS', State = true, Items = {
{'Experience per Hour', function() return num($exphour) end},
{'Experience Left', function() return num(exptolevel()) end},
{'Experience Today', function() return num($expgained) end},
{'Time to Next Level', function() return time(timetolevel()) end},
{'Played Time', function() return time(math.floor($charactertime / 1000)) end},
{'Stamina', function() return time($stamina) end}
}
}
}
local HUD_Colors = {
Font = color(255, 255, 255, 0),
SectionHeaderBackground = {0.0, color(36, 68, 105, 20), 0.23, color(39, 73, 114, 20), 0.76, color(21, 39, 60, 20)},
EntryNameBackground = {0.0, color(75, 75, 75, 20), 0.23, color(45, 45, 45, 20), 0.76, color(19, 19, 19, 20)},
EntryValueBackground = {0.0, color(145, 95, 0, 20), 0.23, color(158, 104, 0, 20), 0.76, color(84, 55, 0, 20)},
EntryValueEnabledBackground = {0.0, color(65, 96, 12, 20), 0.23, color(67, 99, 13, 20), 0.76, color(36, 52, 6, 20)},
EntryValueDisabledBackground = {0.0, color(90, 12, 15, 20), 0.23, color(98, 13, 17, 20), 0.76, color(52, 6, 9, 20)},
}
function WeaponSkill()
local SkillTypes = {
['axe'] = {type = 'axe', skill = $axe, skillpc = $axepc},
['club'] = {type = 'club', skill = $club, skillpc = $clubpc},
['sword'] = {type = 'sword', skill = $sword, skillpc = $swordpc},
['bow'] = {type = 'distance', skill = $distance, skillpc = $distancepc},
['distance weapon'] = {type = 'distance', skill = $distance, skillpc = $distancepc},
['no weapon'] = {type = 'fist', skill = $fist, skillpc = $fistpc},
['rod'] = {type = 'magic', skill = $mlevel, skillpc = $mlevelpc},
['wand'] = {type = 'magic', skill = $mlevel, skillpc = $mlevelpc},
}
return SkillTypes[findweapontype()]
end
local Moving, Temp, Moved = false, {0, 0}, {0, 0}
function inputevents(e)
if (e.type == IEVENT_LMOUSEDOWN) then
for _, Section in ipairs(HUD_Sections) do
if (e.elementid == Section.StateSwitch) then
Section.State = not Section.State
return
end
end
for _, Section in ipairs(HUD_Sections) do
if (Section.Name == 'ENGINE STATES') then
for _, SectionItem in ipairs(Section.Items) do
if (e.elementid == SectionItem[4]) then
SectionItem[3]()
return
end
end
end
end
end
if (e.type == IEVENT_MMOUSEDOWN) then
Moving, Temp = true, {$cursor.x - Moved[1], $cursor.y - Moved[2]}
end
if (e.type == IEVENT_MMOUSEUP) then
Moving = false
end
end
init end
if (Moving) then
auto(10)
Moved = {$cursor.x - Temp[1], $cursor.y - Temp[2]}
end
setposition($clientwin.left + 5 + Moved[1], $worldwin.top + Moved[2])
setfontstyle('Tahoma', 8, 75, 0xFFFFFF, 1, color(0, 0, 0, 20))
local StringWidth, StringHeight = measurestring('TEMP')
setfillstyle('gradient', 'linear', 2, 0, 0, 0, 22)
addgradcolors(unpack(HUD_Colors.SectionHeaderBackground))
drawroundrect(0, 0, 240, 21, 2, 2)
drawtext('SCRIPT INFO', 6, 21 / 2 - StringHeight * 0.5)
setfillstyle('gradient', 'linear', 2, 0, 0, 0, 22)
addgradcolors(unpack(HUD_Colors.EntryValueBackground))
drawroundrect(130, 0, 110, 21, 2, 2)
drawtext('CREATOR NAME', 136, 21 / 2 - StringHeight * 0.5)
setfontsize(7)
local StringWidth, StringHeight = measurestring('TEMP')
setfillstyle('gradient', 'linear', 2, 0, 0, 0, 16)
addgradcolors(unpack(HUD_Colors.EntryNameBackground))
drawroundrect(0, 24 + 0 * 18, 240, 15, 2, 2)
drawtext('Voc - Script Name', 6, 24 + 0 * 18 + 15 / 2 - StringHeight * 0.5 + 1)
setfillstyle('gradient', 'linear', 2, 0, 0, 0, 16)
addgradcolors(unpack(HUD_Colors.EntryNameBackground))
drawroundrect(0, 24 + 1 * 18, 240, 15, 2, 2)
drawtext('Script version:', 6, 24 + 1 * 18 + 15 / 2 - StringHeight * 0.5 + 1)
setfillstyle('gradient', 'linear', 2, 0, 0, 0, 16)
addgradcolors(unpack(HUD_Colors.EntryValueBackground))
drawroundrect(130, 24 + 1 * 18, 110, 15, 2, 2)
drawtext('1.0', 136, 24 + 1 * 18 + 15 / 2 - StringHeight * 0.5 + 1)
local YPosition, SectionRow, SectionItemsRow = 22 + 2 * 19, 0, 0
for SectionIndex, Section in ipairs(HUD_Sections) do
setfontsize(8)
local StringWidth, StringHeight = measurestring('TEMP')
setfillstyle('gradient', 'linear', 2, 0, 0, 0, 21)
addgradcolors(unpack(HUD_Colors.SectionHeaderBackground))
drawroundrect(0, YPosition + (SectionRow * 23) + (SectionItemsRow * 19), 240, 20, 2, 2)
drawtext(Section.Name, 6, YPosition + (SectionRow * 23) + (SectionItemsRow * 19) + 20 / 2 - StringHeight * 0.5 + 1)
setfillstyle('gradient', 'linear', 2, 0, 0, 0, 21)
if (Section.State) then
addgradcolors(unpack(HUD_Colors.EntryValueEnabledBackground))
else
addgradcolors(unpack(HUD_Colors.EntryValueDisabledBackground))
end
Section.StateSwitch = drawroundrect(220, YPosition + (SectionRow * 23) + (SectionItemsRow * 19), 20, 20, 2, 2)
drawtext('X', 228, YPosition + (SectionRow * 23) + (SectionItemsRow * 19) + 20 / 2 - StringHeight * 0.5 + 1)
SectionRow = SectionRow + 1
if (Section.State) then
setfontsize(7)
local StringWidth, StringHeight = measurestring('TEMP')
for SectionItemIndex, SectionItem in ipairs(Section.Items) do
setfillstyle('gradient', 'linear', 2, 0, 0, 0, 17)
addgradcolors(unpack(HUD_Colors.EntryNameBackground))
drawroundrect(0, YPosition + (SectionRow * 23) + (SectionItemsRow * 19), 240, 16, 2, 2)
drawtext(SectionItem[1], 6, YPosition + (SectionRow * 23) + (SectionItemsRow * 19) + 16 / 2 - StringHeight * 0.5 + 1)
if (Section.Name == 'ENGINE STATES') then
local EngineCurrentState = SectionItem[2]()
setfillstyle('gradient', 'linear', 2, 0, 0, 0, 17)
if (EngineCurrentState == 'yes') then
addgradcolors(unpack(HUD_Colors.EntryValueEnabledBackground))
else
addgradcolors(unpack(HUD_Colors.EntryValueDisabledBackground))
end
HUD_Sections[SectionIndex].Items[SectionItemIndex][4] = drawroundrect(130, YPosition + (SectionRow * 23) + (SectionItemsRow * 19), 110, 16, 2, 2)
drawtext((EngineCurrentState == 'yes' and ('On')) or ('Off'), 136, YPosition + (SectionRow * 23) + (SectionItemsRow * 19) + 16 / 2 - StringHeight * 0.5 + 1)
else
setfillstyle('gradient', 'linear', 2, 0, 0, 0, 17)
addgradcolors(unpack(HUD_Colors.EntryValueBackground))
drawroundrect(130, YPosition + (SectionRow * 23) + (SectionItemsRow * 19), 110, 16, 2, 2)
drawtext(SectionItem[2](), 136, YPosition + (SectionRow * 23) + (SectionItemsRow * 19) + 16 / 2 - StringHeight * 0.5 + 1)
end
SectionItemsRow = SectionItemsRow + 1
end
end
end
init start
local commands = {
sd = {
leaderOnly = true,
action = function(id)
useoncreature(3155, getcreaturebyid(id))
waitping()
end
}
}
function navmessages(m)
local comm, args = m.message:match('(.-):(.+)')
comm = commands[comm]
args = args:explode(';')
table.map(args, string.trim)
if comm then
if not comm.leaderOnly or m.isleader then
comm.action(table.unpack(args))
end
end
end
init end
navsay('sd:' .. $attacked.id)
init start
local charList = {
{'account1', 'password1', 'char1', 'skill1'},
{'account2', 'password2', 'char2', 'skill2'},
{'account3', 'password3', 'char3', 'skill3'},
{'account4', 'password4', 'char4', 'skill4'},
{'account5', 'password5', 'char5', 'skill5'},
{'account6', 'password6', 'char6', 'skill6'},
{'account7', 'password7', 'char7', 'skill7'}
}
-- Do not edit below
local skills = {'sword', 'axe', 'club', 'distance', 'magic'}
local randTime = math.random(-110, 10)
for i, v in ipairs(charList) do
table.insert(charList[i], $botdb:getvalue('offtrainlast', v[3]) or 0)
table.insert(charList[i], $botdb:getvalue('offtraintime', v[3]) or 0)
end
init end
auto(10000, 30000)
for _, v in ipairs(charList) do
if (os.time() - v[5]) / 60 > v[6] + (12 * 60) + randTime then
randTime = math.random(-110, 10)
connect(v[1], v[2], v[3])
waitping()
v[5] = os.time()
v[6] = $offlinetraining
$botdb:setvalue('offtrainlast', v[3], v[5])
$botdb:setvalue('offtraintime', v[3], v[6])
if $offlinetraining > 10 then
local id = 16197 + table.find(skills, v[4])
reachgrounditem(id)
wait(200, 500)
useitem(id, 'ground')
else
logout()
end
wait(1000, 1500)
press('[ESC]')
wait(1000, 1500)
end
end
init start
local warnItems = {'cheese', 'energy ring', 'life ring'} -- you can add more items here
local maxLines = 10 -- max lines to display at once
local lootMsgs = {}
init end
setfontstyle('Tahoma', 7, 75, 0xFFFFFF, 1, 0x000000)
foreach newmessage m do
local creature, loot = m.content:match(REGEX_LOOT)
if loot then
local message, color = m.content, 0xFFFFFF
for k, v in ipairs(warnItems) do
if loot:find(v, 1, false) then
color = 0xFF0000
break
end
end
table.insert(lootMsgs, 1, {message = message, color = color})
end
end
while #lootMsgs > maxLines do
table.remove(lootMsgs)
end
for k, msg in ipairs(lootMsgs) do
setfontcolor(msg.color)
drawtext(msg.message, 0, k * 10)
end
setposition($worldwin.left + 3, $worldwin.bottom - #lootMsgs * 10 - 13)
init start
-- The bot will open these backpacks, in this order. The first item is the
-- name of the backpack, the second the location and the third is whether
-- it should be open as new, which defaults to true.
local backpacks = {
{'Backpack of Holding', 'back'},
{'Dragon Backpack' , '0' },
{'Expedition Backpack', '1' , false},
{'Brocade Backpack' , '1' },
{'Brown Bag' , '0' },
}
local serverSaveWait = {15, 20} -- Wait time on server save, in minutes
local nextTry = $timems
REGEX_SERVER_SAVE = '^Server is saving game in (%d+) minutes. Please .+%.$'
init end
auto(100)
if not $connected and $timems >= nextTry then
set('Cavebot/Enabled', 'no')
set('Targeting/Enabled', 'no')
set('Looting/Enabled', 'no')
reconnect()
while not $connected do
wait(90, 110)
end
waitping()
local bp, loc, new, count, parentCont
for _, v in ipairs(backpacks) do
bp, loc, new = table.unpack(v)
new = tern(new ~= nil, new, true)
count = #getopencontainers()
openitem(bp, loc, new)
if new then
while #getopencontainers() ~= count + 1 do
wait(90, 110)
end
else
waitping()
end
resizewindows(0)
end
set('Cavebot/Enabled', 'yes')
set('Targeting/Enabled', 'yes')
set('Looting/Enabled', 'yes')
end
foreach newmessage m do
if m.type == MSG_RED then
local min = m.content:match(REGEX_SERVER_SAVE)
if min then
nextTry = $timems + (tonumber(min) + math.random(table.unpack(serverSaveWait))) * 60000
break
end
end
end
init start
-- local SCRIPT_VERSION = '1.0.0'
-- Creatures counted; empty array means any creature
local creatures = {'Serpent Spawn', 'Hydra'}
-- Minimum amount of creatures to change heal rule
local minCreatures = 1
-- The full path to the heal rule to be changed
local rulePath = 'SpellHealer/Rules/NewHealRule'
-- The value for when there are less creatures on screen then what was set
-- up on `minCreatures` variable. NOTE: This is a range; eg: {50, 55} means
-- '50 to 55'.
local defaultValue = {50, 55}
-- The value for when there are at least the same amount of creatures on
--screen then what was set up on `minCreatures` variable. NOTE: This is a
-- range; eg: {90, 95} means '90 to 95'.
local safeValue = {90, 95}
-- DO NOT EDIT BELOW THIS LINE --
table.lower(creatures)
rulePath = string.finish(rulePath, '/ConditionValue')
init end
auto(100)
local value = tern(maround(creatures) < minCreatures, defaultValue, safeValue)
set(rulePath, ('%d x %d'):format(value[1], value[2]))
init start
local xOffset, yOffset, worldWidth, worldHeight, x, y, z, topLeftTilePos,
botRightTilePos, width, height, avoidance, name, policy
local specialAreaRect = {}
function gettilepos(x, y, z)
local tile = getobjectarea(x, y, z)
if tile == nil then
local xDiff, yDiff = x - $posx, y - $posy
if math.abs($posx - x) <= 7 then
tile = getobjectarea(x, $posy, $posz)
xDiff = 0
elseif math.abs($posy - y) <= 5 then
tile = getobjectarea($posx, y, $posz)
yDiff = 0
else
tile = getobjectarea($posx, $posy, $posz)
end
-- Some strange stuff happens when you go from 0 to -1, so I'm
-- adding this as a precaution.
if tile ~= nil then
local width, height = $worldwin.width, $worldwin.height
tile.left = tile.left + (width * xDiff)
tile.right = tile.right + (width * xDiff)
tile.centerx = tile.centerx + (width * xDiff)
tile.top = tile.top + (height * yDiff)
tile.bottom = tile.bottom + (height * yDiff)
tile.centery = tile.centery + (height * yDiff)
end
end
return tile
end
useworldhud()
init end
setfontstyle('Arial', 8, 75, 0xFFFFFF, 1, 0x000000)
xOffset, yOffset = $worldwin.left - $clientwin.left, $worldwin.top - $clientwin.top
worldWidth, worldHeight = $worldwin.right - $worldwin.left - 2, $worldwin.bottom - $worldwin.top - 2
foreach settingsentry e 'Cavebot/SpecialAreas' do
x, y, z = getsetting(e, 'Coordinates'):match('.-(%d+).-(%d+).-(%d+)')
x, y, z = tonumber(x), tonumber(y), tonumber(z)
if z == $posz then
width, height = getsetting(e, 'Size'):match('(%d+).-(%d+)')
width, height = tonumber(width), tonumber(height)
topLeftTilePos = gettilepos(x, y, z)
botRightTilePos = gettilepos(x + width - 1, y + height - 1, z)
if topLeftTilePos and botRightTilePos then
specialAreaRect.left = math.max(topLeftTilePos.left , 0)
specialAreaRect.top = math.max(topLeftTilePos.top , 0)
specialAreaRect.right = math.min(botRightTilePos.right , worldWidth)
specialAreaRect.bottom = math.min(botRightTilePos.bottom, worldHeight)
specialAreaRect.width = specialAreaRect.right - specialAreaRect.left
specialAreaRect.height = specialAreaRect.bottom - specialAreaRect.top
if specialAreaRect.width > 0 and specialAreaRect.height > 0 then
avoidance = tonumber(getsetting(e, 'Avoidance'))
name = getsetting(e, 'Name')
policy = getsetting(e, 'Policy'):gsub('[^A-Z]', '')
setfillstyle('color', color(255, 0, 0, math.round(100 - (avoidance / 4))))
drawroundrect(
specialAreaRect.left,
specialAreaRect.top,
specialAreaRect.width,
specialAreaRect.height,
10, 10
)
if specialAreaRect.width > 10 then
drawtext(
string.fit(name, specialAreaRect.width - 10, '...', true),
specialAreaRect.left + 5,
specialAreaRect.top + 3
)
drawtext(
string.fit(policy, specialAreaRect.width - 10, '...', true),
specialAreaRect.left + 5,
specialAreaRect.top + 15
)
end
end
end
end
end
@mooises9
Copy link

mooises9 commented Jul 4, 2018

man u can do a scrip to heal lvl 200 summons with 85% or less hp?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment