Hello. I decided to share my little library, containing some useful functions for both scripters and common users. The functions are not documented well (if at all), but their usage should be pretty obvious.
Note: I'm overriding the current opendepot function, you should comment it out at the end of the code if you want to use the original from Lucas Terra's library
Note2: If you want to keep my version, however, you must save the library as e.g. xColandus.lua, to make sure it's loaded last!
Functions included in library:
- NPCAround(distance, name) [boolean] (optional distance, name)
- sellLootItems(category) [void]
- isItemsOnPos(x, y, z, itemid, ...) [boolean]
- depotAround() [x, y, z or false]
- getClosestItemPosition(...) [x, y, z, item]
- ropeUp(x, y, z) [boolean] (optional x, y, z)
- useLadder(x, y, z, itemid) [boolean] (optional x, y, z, itemid)
- openClosestDoor() [void]
- clearTile(x, y, z) [void]
- breakWoodenBars() [boolean]
- moveToDepot() [void]
- safeOpenDepot(forceBrowse) [void] (optional boolean forceBrowse)
- isBackpackOpen(bptype) [boolean]
- useSphereMachine(itemName) [void]
Special functions:
- doStick() [boolean]
- stick(radiusX, radiusY) [void] (optional radiusX, radiusY)
- unstick() [void]
Save this code in a file called Colandus.lua, in your lib folder:
--###################################--
--###################################--
-- COLANDUS' LIBRARY --
-- VERSION 1.0.0 --
--###################################--
--###################################--
print "Colandus' Library Version 1.0.0"
------------------------------
--------- Variables ----------
------------------------------
local stairIDs = {386, 421, 1948, 1968, 3968, 5542, 7762, 7771, 9116, 12202}
local doorIDs = {1628, 1629, 1631, 1632, 1638, 1640, 1642, 1644, 1646, 1648, 1650, 1651, 1653, 1654, 1656, 1658, 1660, 1662, 1664, 1666, 1668, 1669, 1671, 1672, 1674, 1676, 1678, 1680, 1682, 1683, 1685, 1687, 1689, 1691, 1692, 1694, 1696, 1698, 4912, 4913, 5006, 5007, 5082, 5084, 5097, 5098, 5100, 5102, 5104, 5106, 5107, 5109, 5111, 5113, 5115, 5116, 5118, 5120, 5122, 5124, 5125, 5127, 5129, 5131, 5133, 5134, 5136, 5137, 5139, 5140, 5142, 5143, 5277, 5278, 5280, 5281, 5282, 5285, 5287, 5289, 5291, 5293, 5302, 5303, 5514, 5516, 5735, 5732, 5745, 5749, 6191, 6192, 6194, 6195, 6197, 6199, 6201, 6203, 6205, 6207, 6248, 6249, 6251, 6252, 6254, 6258, 6260, 6262, 6264, 6435, 6436, 6439, 6440, 6443, 6444, 6449, 6450, 6453, 6454, 6457, 6458, 6461, 6462, 6465, 6466, 6469, 6470, 6788, 6789, 6891, 6892, 6894, 6896, 6898, 6900, 6901, 6903, 6905, 6907, 7027, 7028, 7033, 7034, 7036, 7038, 7040, 7042, 7043, 7045, 7047, 7049, 7051, 7052, 7711, 7712, 7714, 7715, 7717, 7719, 7721, 7723, 7725, 7727, 7868, 7941, 8249, 8250, 8252, 8253, 8255, 8257, 8258, 8261, 8263, 8265, 8351, 8352, 8354, 8355, 8357, 8359, 8361, 8363, 8365, 8367, 9347, 9348, 9351, 9352, 9354, 9355, 9357, 9359, 9361, 9363, 9365, 9367, 9551, 9552, 9554, 9556, 9558, 9560, 9561, 9563, 9565, 9567, 9571, 9572, 9858, 9859, 9863, 9865, 9867, 9868, 9872, 9874, 10147, 10149, 10151, 10153, 10155, 10157, 10520, 10521, 11232, 11233, 11237, 11239, 11241, 11242, 11246, 11248, 11705}
local ropeHoleIDs = {386, 421, 7762, 12202}
local depotIDs = {3497, 3498, 3499, 3500}
local depotTileID = 10145
local sphereItems = {"emerald", "amethyst", "ruby", "sapphire"}
------------------------------
-- Tibia specific functions --
------------------------------
-- Returns true if an NPC can be found near you (distance and name are optional).
function NPCAround(distance, name)
distance = distance or 3
foreach creature m 'ns' do
if(m.dist <= distance and (not name or m.name:lower() == name:lower())) then
return true
end
end
return false
end
-- Sell items by looting category.
function sellLootItems(category)
if(not NPCAround(3)) then
return
end
try($tradeopen, opentrade)
foreach lootingitem m category do
while(tradecount('sell', m.id) > 0) do
sellitems(m.id, tradecount('sell', m.id))
waitping(1.8, 2.3)
end
end
end
-- Check if at least one of specified items can be found on given position.
function isItemsOnPos(x, y, z, ...)
local args = {...}
local tile = gettile(x, y, z)
for i=1, tile.itemcount do
if(table.find(args, tile.item[i].id)) then
return tile.item[i].id
end
end
return false
end
-- Check if there is a depot around you.
function depotAround()
for x = -1, 1 do
for y = -1, 1 do
if(not(x == 0 and y == 0)) then
local posX = $posx + x
local posY = $posy + y
if(isItemsOnPos(posX, posY, $posz, unpack(depotIDs))) then
return posX, posY, $posz
end
end
end
end
return false
end
-- Get position of nearest item with specific id
function getClosestItemPosition(...)
local closestDistance, closestPos = -1
for X_OFFSET = SCREEN_LEFT, SCREEN_RIGHT do
for Y_OFFSET = SCREEN_TOP, SCREEN_BOTTOM do
if(not(x == 0 and y == 0)) then
local posX = $posx + X_OFFSET
local posY = $posy + Y_OFFSET
local item = isItemsOnPos(posX, posY, $posz, ...)
if(item) then
local distance = math.abs(X_OFFSET) + math.abs(Y_OFFSET)
if(closestDistance == -1 or distance < closestDistance or (distance == closestDistance and math.random(1, 2) == 2)) then
closestDistance = distance
closestPos = {posX, posY, $posz, item}
end
end
end
end
end
if(not closestPos) then
return
end
return unpack(closestPos)
end
-- Will rope up on closest rope hole, if no position specified.
function ropeUp(x, y, z)
if(not (x and y and z)) then
x, y, z = getClosestItemPosition(unpack(ropeHoleIDs))
if(not x) then
return false
end
end
local rope = getsetting('Cavebot/Rope')
useitemon(itemid(rope), 0, ground(x, y, z))
waitping(1.3, 1.7)
return true
end
-- Will use closest ladder, if no position specified.
function useLadder(x, y, z, itemid)
if(not (x and y and z)) then
x, y, z, itemid = getClosestItemPosition(unpack(stairIDs))
if(not x) then
return false
end
end
useitem(itemid or 0, ground(x, y, z))
waitping(1.3, 1.7)
return true
end
function openClosestDoor()
local x, y, z = getClosestItemPosition(unpack(doorIDs))
if(x) then
useitem(0, ground(x, y, z))
end
end
function clearTile(x, y, z)
local id = topitem(x, y, z).id
while(not itemproperty(id, ITEM_NOTMOVEABLE)) do
moveitems(id, ground($posx, $posy, $posz), ground(x, y, z), 100)
waitping(1.5, 2)
id = topitem(x, y, z).id
end
end
local breakableWoodenBars = {2295, 2296}
function breakWoodenBars()
local x, y, z = getClosestItemPosition(unpack(breakableWoodenBars))
if(not x) then
return false
end
local _, weapon = findweapontouse()
clearTile(x, y, z)
repeat
reachlocation(x, y, z)
waitping(1, 1.7)
useitemon(weapon, 0, ground(x, y, z))
waitping(1, 1.7)
until not isItemsOnPos(x, y, z, unpack(breakableWoodenBars))
return true
end
-- TODO: Enable walk through first, for those who don't use it...
-- Moves to closest depot despite if it's not top item
function moveToDepot()
while not depotAround() do
local closestX, closestY, closestZ = getClosestItemPosition(depotTileID)
if(closestX) then
moveto(closestX, closestY, closestZ)
end
waitping(1, 1.7)
end
end
-- Tries different methods of opening depot
function safeOpenDepot(forceBrowse)
local dpX, dpY, dpZ = depotAround()
if(not dpX) then
return
end
if(table.find(depotIDs, topitem(dpX, dpY, dpZ).id)) then
openitem("depot")
waitcontainer("Locker", false)
openitem(3502, "Locker", false)
waitcontainer("Depot Chest", false)
return
end
if(not forceBrowse) then
local tile = gettile(dpX, dpY, dpZ)
local count = tile.itemcount
if(count <= (5 + 3)) then
local expectedCount = count
repeat
if(tile.itemcount > expectedCount) then
break
end
moveitems(tile.item[tile.itemcount].id, ground($posx, $posy, $posz), ground(dpX, dpY, dpZ))
expectedCount = expectedCount - 1
tile = gettile(dpX, dpY, dpZ)
until tile.itemcount == 3
safeOpenDepot(true)
return
end
end
while(windowcount("Depot Chest") == 0) do
contextmenu("Browse Field", 0, ground(dpX, dpY, dpZ))
waitcontainer("Browse Field", false)
openitem(0, "Browse Field", false, 0)
waitcontainer("Locker", false)
openitem(0, "Locker", false, 0)
waitcontainer("Depot Chest", false)
end
end
function isBackpackOpen(bptype)
for i = 0, windowcount() - 1 do
local bpname = getcontainer(i).name:lower()
if(bptype:lower() == bpname) then
return true
end
end
return false
end
-- Use Sphere Machine in edron, with specified pearls.
-- usage: useSphereMachine("emerald")
function useSphereMachine(itemName)
for _, sphereItem in ipairs(sphereItems) do
if(itemName:match(sphereItem)) then
itemName = "small enchanted " .. sphereItem
break
end
end
local machineX, machineY, machineZ = 33269, 31830, 10
local machineActiveId = 847
local machineInactiveId = 843
local itemsNeeded = 20
local itemAmount = itemcount(itemName)
if(itemAmount < itemsNeeded) then
printerror('Insufficient amount of "' .. itemName .. 's"')
return
end
repeat
if(topitem(machineX, machineY, machineZ).id == machineActiveId) then
useitem(machineActiveId, ground(machineX, machineY, machineZ))
waitping()
end
useitemon(itemid(itemName), machineInactiveId, ground(machineX, machineY, machineZ))
waitping()
until (itemAmount - itemcount(itemName)) >= itemsNeeded or itemcount(itemName) == 0
while(topitem(machineX, machineY, machineZ).id == machineActiveId) do
useitem(machineActiveId, ground(machineX, machineY, machineZ))
waitping()
end
useitem(machineInactiveId, ground(machineX, machineY, machineZ))
end
------ SPECIAL
STICK_POSITION = {}
STICK_RADIUS = {}
STICK_ENABLED = false
function doStick()
if(not STICK_ENABLED) then
return false
end
local stickX, stickY, stickZ = unpack(STICK_POSITION)
if(tilereachable(stickX, stickY, stickZ)) then
local stickRadiusX, stickRadiusY = unpack(STICK_RADIUS)
if($posx < (stickX - stickRadiusX) or $posx > (stickX + stickRadiusX) or
$posy < (stickY - stickRadiusY) or $posy > (stickY + stickRadiusY) or
$posz ~= stickZ) then
moveto(stickX, stickY, stickZ)
wait(300, 450)
return true
end
end
return false
end
function stick(radiusX, radiusY)
STICK_POSITION = {$wptx, $wpty, $wptz}
STICK_RADIUS = {radiusX or 0, radiusY or 0}
STICK_ENABLED = true
end
function unstick()
STICK_POSITION = {0, 0, 0}
STICK_RADIUS = {0, 0}
STICK_ENABLED = false
end
------------------------------
-- Overridden functions --
------------------------------
-- NOTE: Requires library --
-- to be loaded LAST --
-- by naming it e.g. --
-- xColandus.lua --
------------------------------
-- Don't use this if you want Lucas Terra's version.
function opendepot()
moveToDepot()
safeOpenDepot()
end
-- Will make sure an NPC is near you before attempting to talk to it.
_npctalk = _npctalk or npctalk
function npctalk(...)
if(not NPCAround()) then
return
end
_npctalk(...)
end