• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

scripts/macros for kondras otclientv8 bot

Evolunia

evolunia.net
Joined
Nov 6, 2017
Messages
210
Solutions
3
Reaction score
187
hello, since there's quite many people making use of otclientv8, i thought it would be nice to have a place where people can share macros and what not, since right now they're only posted in discord which isn't a good place to find scripts

collection of scripts i found, some are made by me, some are made by thaenz (i don't know if he has a otland acct), some are made by others:


Automatically equip energy shield when you're below a certiain amount of health percent:
Lua:
--[[
  1. Start the script with your normal ring on 
  2. make sure the backpack with e-rings
     are always open
]]
local energy_ring = 3051; -- Your energy ring
local energy_ring_equiped = 3088; -- Ring changes id when equiped
local original_ring = getFinger(); -- Your original ring
local healthp_for_energy = 50;
local healthp_for_original = 80;
local manap_for_original = 25;

macro(1000, "e-ring", function()
  if (manapercent() <= manap_for_original and getFinger():getId() ~= original_ring:getId()) then
    g_game.equipItem(original_ring);
  elseif (hppercent() <= healthp_for_energy and manapercent() >= manap_for_original and getFinger():getId() ~= energy_ring) then
      local ring = findItem(energy_ring);
      if (ring) then
          g_game.equipItem(ring);
      end
  elseif (hppercent() >= healthp_for_original and getFinger():getId() ~= original_ring:getId()) then
      g_game.equipItem(original_ring);
  end
end)

Automatically walk to an item on your screen (used on my ots to walk into flames which spawns monsters, but can be useful for other ots too)
Lua:
macro(1000, "open monster flames",  function()
  for i, tile in ipairs(g_map.getTiles(posz())) do
      for u,item in ipairs(tile:getItems()) do
          if (item:getId() == 25058) then
            autoWalk(tile:getPosition(), 100, {ignoreNonPathable = true})
          end
        end
    end
end)

Automatically follow a player with X name:
Lua:
local playerToFollow = 'Lunia'
macro(1000, "auto follow",  function()
    if g_game.isFollowing() then
        return
    end
    for _, followcreature in ipairs(g_map.getSpectators(pos(), false)) do
        if (followcreature:getName() == playerToFollow and getDistanceBetween(pos(), followcreature:getPosition()) <= 8) then
            g_game.follow(followcreature)
        end
    end
end)

Hold target:
Lua:
local oldTarget
macro(200, "hold target",  function()
    if g_game.isAttacking() then
        oldTarget = g_game.getAttackingCreature()
    end
    if (oldTarget and not g_game.isAttacking() and getDistanceBetween(pos(), oldTarget:getPosition()) <= 8) then
        g_game.attack(oldTarget)
    end
end)

Mana restore (can be good if you wanna edit it more, or just spam it faster):
Lua:
local manaId = 268
local manaPercent = 80
macro(200, "faster mana potting",  function()
  if (manapercent() <= manaPercent) then
    usewith(manaId, player) 
  end
end)


Health restore:
Lua:
local healthId = 268
local healthPercent = 80
macro(200, "faster health potting",  function()
  if (hppercent() <= healthPercent) then
    usewith(healthId, player) 
  end
end)

Healing with spells:
Lua:
local healingSpell = 'Exura gran san'
local hpPercent = 99
macro(50, "faster healing",  function()
  if (hppercent() <= hpPercent) then
    say(healingSpell) 
  end
end)

Automatically use an item on your screen (used on my ots for opening boxes that spawn randomly)
Lua:
macro(2500, "open monster boxes",  function()
  for i, tile in ipairs(g_map.getTiles(posz())) do
    for u,item in ipairs(tile:getItems()) do
      if (item and item:getId() == 9586) then
        g_game.use(item)
        return
      end
    end  
  end
end)

Cast aoe spell when more than X monsters on the screen, else use single target spell: (there's also a version where it doesn't cast aoe spells if there are players on screen if somebody needs)
Lua:
local singleTargetSpell = 'exori gran star'
local multiTargetSpell = 'exevo mas row'
local distance = 3
local amountOfMonsters = 4

macro(250, "multi target spell",  function()
    local specAmount = 0
    if not g_game.isAttacking() then
        return
    end
    for i,mob in ipairs(getSpectators()) do
        if (getDistanceBetween(player:getPosition(), mob:getPosition())  <= distance and mob:isMonster())  then
            specAmount = specAmount + 1
        end
    end
    if (specAmount >= amountOfMonsters) then    
        say(multiTargetSpell)
    else
        say(singleTargetSpell)
    end
end)

Rainbow outfit (should probably be improved by taking your current outfit type, but this also works if you know the outfit looktype)
Lua:
local outfit = {
  head = 0,
  body = 1,
  legs = 2,
  feet = 3,
  type = 143, -- outfit id
  auxType = 0,
  addons = 3, -- 1, 2, or 3 for all
  mount = 0, -- mount id
}

macro(100, "RainbowOutfit",  function()
  outfit.head = (outfit.head + 1) % 133;
  outfit.body = (outfit.body + 1) % 133;
  outfit.legs = (outfit.legs + 1) % 133;
  outfit.feet = (outfit.feet + 1) % 133;
  setOutfit(outfit);
end)

Automatically cast utamo vita when below X health, and deactivate again when you're below X mana (useful for paladin on ots with custom mana shield)
Lua:
local castBelowHp = 40
local deactiveBelowMana = 40
macro(100, "advanced manashield",  function()
  if (hppercent() <= castBelowHp and manapercent() >= deactiveBelowMana and not hasManaShield()) then
    say('utamo vita')
  end
  if (manapercent() <= deactiveBelowMana and  hppercent() >= castBelowHp and hasManaShield()) then
      say('utamo vita')
  end
end)

Automatically convert gold coins:
Lua:
macro(500, "replace coins", function()
  for i, container in pairs(getContainers()) do
    for j, item in ipairs(container:getItems()) do
      if item:getCount() == 100 and item:getId() == 3031 then
        g_game.use(item)
        return
      end
    end
  end
end)

Automatically cast exura sio on a friend:
Lua:
local friendName = "asd"
macro(100, "heal friend", function()
    local friend = getPlayerByName(friendName)
    if friend and friend:getHealthPercent() < 90 then
        say("exura sio \"" .. friendName)
        delay(1000)
    end
end)


And post requests of things you want here, and somebody can probably create it, u should also join otcv8 discord where people are talking about the bot and macros: Join the OTClientV8 Discord Server! (https://discord.gg/feySup6)
 
Last edited:
Nice to see someone start doing script for this bot.
I remade some of your scripts for a friend and some others we found that he needed. I will post them here so the community can use them.
Otcv8bot.png

Monster Flames
Lua:
macro(500, "monster flames",  function()for i, tile in ipairs(g_map.getTiles(g_game.getLocalPlayer():getPosition().z)) do
  if (tile) then
    for u,item in ipairs(tile:getItems()) do
      if (item) then
        if (item:getId() == 25058) then
          walkButton:setChecked(false)
          autoWalk(tile:getPosition(), 100, {ignoreNonPathable = true})
          schedule(5000, turnOnWalking);
          return
        end 
      end
    end
  end
end
end)
)

Blackskull Flames
Lua:
local walkButton = modules.game_luniabot.walkButton
function turnOnWalking()
  walkButton:setChecked(true)
end
macro(500, "Blackskull flames",  function()for i, tile in ipairs(g_map.getTiles(g_game.getLocalPlayer():getPosition().z)) do
  if (tile) then
    for u,item in ipairs(tile:getItems()) do
      if (item) then
        if (item:getId() == 21463) then
          walkButton:setChecked(false)
          autoWalk(tile:getPosition(), 100, {ignoreNonPathable = true})
          schedule(5000, turnOnWalking);
          return
        end 
      end
    end
  end
end
end)

Faster mana potting with textwindow to choose pot
Lua:
local manaPercent = 99
macro(200, "faster mana potting",  function()
  if (manapercent() <= manaPercent) then
    usewith((storage.mpItem), player)
  end
end)
addTextEdit("mpItem", storage.mpItem or "268", function(widget, text) 
storage.mpItem = text
end)

Faster health potting with textwindow to choose pot
Lua:
local healthPercent = 99
macro(200, "faster health potting",  function()
  if (hppercent() <= healthPercent) then
    usewith((storage.hpItem), player)
  end
end)
addTextEdit("hpItem", storage.hpItem or "23375", function(widget, text) 
storage.hpItem = text
end)

Faster Healer with textwindow to choose spell
Lua:
local hpPercent = 99
macro(50, "faster healing",  function()
  if (hppercent() <= hpPercent) then
  say(storage.HealText)
end
end)
addTextEdit("HealText", storage.HealText or "exura vita", function(widget, text) 
storage.HealText = text
end)

Multi target spell with textwindow to choose spells
Lua:
local distance = 4
local amountOfMonsters = 2
macro(1000, "multi target spell",  function()
    local specAmount = 0
    if not g_game.isAttacking() then
        return
    end
    for i,mob in ipairs(getSpectators()) do
        if (getDistanceBetween(player:getPosition(), mob:getPosition())  <= distance and mob:isMonster())  then
            specAmount = specAmount + 1
        end
    end
    if (specAmount >= amountOfMonsters) then 
        say(storage.Spell2, 250)
    else
        say(storage.Spell1, 250)
    end
end)
addTextEdit("Spell1", storage.Spell1 or "Single target", function(widget, text) 
storage.Spell1 = text
end)
addTextEdit("Spell2", storage.Spell2 or "Multi target", function(widget, text) 
storage.Spell2 = text
end)

Auto exeta res with textwindow to choose spell for custom servers
Lua:
macro(500, "Auto RES",  function()
  say(storage.ExetaText)
end)
addTextEdit("ExetaText", storage.ExetaText or "Exeta mas res", function(widget, text) 
storage.ExetaText = text
end)

Anti paralyze
Lua:
macro(100, "Anti Paralyze", nil, function()
  if isParalyzed() and storage.autoAntiParalyzeText:len() > 0 then
    saySpell(storage.autoAntiParalyzeText)
end
end)
addTextEdit("autoAntiParalyzeText", storage.autoAntiParalyzeText or "utani hur", function(widget, text) 
  storage.autoAntiParalyzeText = text
end)

Auto Haste
Lua:
macro(500, "Auto Haste", nil, function()
    if not hasHaste() and storage.autoHasteText:len() > 0 then
      if saySpell(storage.autoHasteText) then
        delay(5000)
      end
    end
  end)
  addTextEdit("autoHasteText", storage.autoHasteText or "utani gran hur", function(widget, text) 
    storage.autoHasteText = text
end)

Sio with room for more friends with textwindow
Lua:
macro(100, "Sio", function()
    local friend = getPlayerByName(storage.friendName)
    local friend1 = getPlayerByName(storage.friend1Name)
    if friend and friend:getHealthPercent() < 80 then
        say("exura sio \""..storage.friendName)
        delay(500)
   elseif friend1 and friend1:getHealthPercent() <= 80 then -- If u need more you can copy this lines
        say("exura sio \""..storage.friend1Name) --
        delay(500) --
    end -- And paste them between this end and the delay
end)
  addTextEdit("friendName", storage.friendName or "Friend Name", function(widget, text) 
    storage.friendName = text
end)
addLabel("Priority 1 ^ Priority 2 v", "Priority 1 ^ Priority 2 v")
  addTextEdit("friend1Name", storage.friend1Name or "Friend Name", function(widget, text)   -- Also copy this lines
    storage.friend1Name = text -- If u add more just rename the Friend1Name to Friend2Name in the lines u paste
end) --

Mana Trainer
Lua:
macro(200, "Manatrain",  function()
  if (hppercent() > 50) then
  say(storage.ManatrainText)
end
end)
addTextEdit("ManatrainText", storage.ManatrainText or "Utevo Mana", function(widget, text) 
storage.ManatrainText = text
end)
 
Last edited:
can this work for xenobot??
how to do it for xeno or even for custom lunia version??
thx
 
can this work for xenobot??
how to do it for xeno or even for custom lunia version??
thx

It's pretty straight forward, just open macro/kondrah's bot window and press edit -> macros -> paste in what you would like to use.
There's also possibility for sound alarms now, you can use function playAlarm() to play sounds, with this and callbacks you can easily create notifications for player on screen, when you recieve messages, when there's a certain event ingame and more. Callbacks also allows more things, for example you could create UI with private messages, recent loot, and such like other bots have.

You can also play custom sounds by using this: playSound("/sounds/alarm.ogg")
 
how I do this?

automatic collector arround you(on the floor)

in elfbot is : auto 1 listas "AUTO RECOLLECTOR" | collectitems 'backpack of holding' '3031' '3035' '3725' '3043' '9019' '6390' '8063' '8060' '3253 ' '3606' '3775' '6529' '3492' '3588'
 
It's pretty straight forward, just open macro/kondrah's bot window and press edit -> macros -> paste in what you would like to use.
There's also possibility for sound alarms now, you can use function playAlarm() to play sounds, with this and callbacks you can easily create notifications for player on screen, when you recieve messages, when there's a certain event ingame and more. Callbacks also allows more things, for example you could create UI with private messages, recent loot, and such like other bots have.

You can also play custom sounds by using this: playSound("/sounds/alarm.ogg")
Too Much Thanks
 
It's pretty straight forward, just open macro/kondrah's bot window and press edit -> macros -> paste in what you would like to use.
There's also possibility for sound alarms now, you can use function playAlarm() to play sounds, with this and callbacks you can easily create notifications for player on screen, when you recieve messages, when there's a certain event ingame and more. Callbacks also allows more things, for example you could create UI with private messages, recent loot, and such like other bots have.

You can also play custom sounds by using this: playSound("/sounds/alarm.ogg")
can you give an example of a callback script? I don't know how to use them.
 
can you give an example of a callback script? I don't know how to use them.

Here's a list of available callbacks: OTCv8/otclientv8_bot (https://github.com/OTCv8/otclientv8_bot/blob/master/game_bot/functions/callbacks.lua)
For example onTalk, executes everytime the client gets a message, for example when a monster says something, when you get a private message, any message in all channels you have open.
onTalk can be used like this (just paste it into callbacks):
Lua:
onTalk(function(name, level, mode, text, channelId, pos)
    print("Creature: ".. name  .." said ".. text)
end)
This will script will just output all messages in the console window (CTRL+T), but you can easily adjust it to make it useful.

So you can easily for example, just edit that a little bit and play a sound if you get a private message, or if X message happens in a channel.
 
Last edited:
This code makes all private messages display on your screen, similarly to scripts in windbot/xenobot. Just paste it into the callbacks window and it will work.
Lua:
local height = 50
local widget = setupUI([[
Panel
  id: msgPanel
  height: 400
  width: 200
]], g_ui.getRootWidget())

onTalk(function(name, level, mode, text, channelId, pos)
    if (mode ~= 4) then return end
    local msgLabel = g_ui.loadUIFromString([[
Label
  color: #5ff7f7
  background-color: black
  opacity: 0.87
]], widget)
    msgLabel:setText(name .." ["..level.. "]: " .. text)
    msgLabel:setPosition({y = height, x = 10})
    if height > 210 then
        for msgIndex, message in ipairs(widget:getChildren()) do
            message:setPosition({y = message:getPosition().y - 13, x = 10})
            if (msgIndex == 1) then message:destroy() end
        end
    else
        height = height + 13
    end
end)

How it looks: (all spells just displayed for testing, and you will see less messages, just made it more for testing)
unknown.png


Btw any otclient guys know if you can add text shadows in OTML?
 
Last edited:
I like this! getting out of tibia clients! we should create skins for the otclient! like with diferent colors and buttons styles.
 
Here's a list of available callbacks: OTCv8/otclientv8_bot (https://github.com/OTCv8/otclientv8_bot/blob/master/game_bot/functions/callbacks.lua)
For example onTalk, executes everytime the client gets a message, for example when a monster says something, when you get a private message, any message in all channels you have open.
onTalk can be used like this (just paste it into callbacks):
Lua:
onTalk(function(name, level, mode, text, channelId, pos)
    print("Creature: ".. name  .." said ".. text)
end)
This will script will just output all messages in the console window (CTRL+T), but you can easily adjust it to make it useful.

So you can easily for example, just edit that a little bit and play a sound if you get a private message, or if X message happens in a channel.
ok but OnTalk doens't get messages from Server log channel. How can i check for those?
 
@mateogon From 1.5 there's
Code:
onTextMessage(callback) -- callback = function(mode, text)

In 1.5 you can also use new method of synchronization - BotServer. Here's an example of magic wall and mana synchronization.

Code:
-- magic wall timer and mana synchronization, otclientv8 1.5
storage.mwalls = {}

local channel = "uniquenameofchannel"
BotServer.init(name(), channel)

BotServer.listen("mwall", function(name, message)
  if not storage.mwalls[message["pos"]] or storage.mwalls[message["pos"]] < now then
    storage.mwalls[message["pos"]] = now + message["duration"] - 150 -- 150 is latency correction
  end
end)

BotServer.listen("mana", function(name, message)
  local creature = getPlayerByName(name)
  if creature then
    creature:setManaPercent(message["mana"])
  end
end)

onAddThing(function(tile, thing)
  if thing:isItem() and thing:getId() == 2129 then
    local pos = tile:getPosition().x .. "," .. tile:getPosition().y .. "," .. tile:getPosition().z
    if not storage.mwalls[pos] or storage.mwalls[pos] < now then
      storage.mwalls[pos] = now + 20000
      BotServer.send("mwall", {pos=pos, duration=20000})
    end
    tile:setTimer(storage.mwalls[pos] - now)
  end
end)

local lastMana = 0
macro(100, function()
  if manapercent() ~= lastMana then
    lastMana = manapercent()
    BotServer.send("mana", {mana=lastMana})
  end
end)
 
Will there be some function to sell items to npc's?
And is there also a way to go to a certain label?
(I`m kinda thinking in the way Xenobot used to work)
 
hey, i would like to share a script for (kinda advanced?)safe caster.

how it behaves:
1.bot will use multi target spell if 2 or more monsters around, even when there are players on screen - untill u reach 15 pvp kills (someone tries to RS you)
2. bot will use single target spell if only 1 monsters around OR there are players on screen (if you passed 15 pvp kills treshhold).

Important! bot will count the number of kills u gained since you started the script/reset the macro window (off then on again).
To change the starting point of counting, just change the frags from 0 to X

Script itself:
Lua:
local frags = 0

onTextMessage(function(mode, text)
 if string.find(text, "Warning! The murder") then
    frags = frags + 1
end
end)

local multiTargetSpell = 'holy power'
local singleTargetSpell = 'exori san'
local distance = 3
local amountOfMonsters = 2
local fragLimit = 15

macro(250, "Exp Cast",  function()
    local isSafe = true;
    local specAmount = 0
    if not g_game.isAttacking() then
        return
    end
    for i,mob in ipairs(getSpectators()) do
        if (getDistanceBetween(player:getPosition(), mob:getPosition())  <= distance and mob:isMonster())  then
            specAmount = specAmount + 1
        end
        if (mob:isPlayer() and player:getName() ~= mob:getName()) then
            isSafe = false;
        end
    end
    if (specAmount >= amountOfMonsters and ((frags <= fragLimit) or isSafe)) then
        say(multiTargetSpell)
    else
        say(singleTargetSpell)
    end
end)
 
where can I learn to make this? is F"#%ing awesome!

BTW some has a script for utito's? thanks!
 
The following macro attacks closest monster and if there are more than 1 closest it attacks one with least health percent.
Lua:
macro(100, "Smarter targeting", function() 
  local battlelist = getSpectators();
  local closest = 10
  local lowesthpc = 101
  for key, val in pairs(battlelist) do
    if val:isMonster() then
      if getDistanceBetween(player:getPosition(), val:getPosition()) <= closest then
        closest = getDistanceBetween(player:getPosition(), val:getPosition())
        if val:getHealthPercent() < lowesthpc then
          lowesthpc = val:getHealthPercent()
        end
      end
    end
  end
  for key, val in pairs(battlelist) do
    if val:isMonster() then
      if getDistanceBetween(player:getPosition(), val:getPosition()) <= closest then
        if g_game.getAttackingCreature() ~= val and val:getHealthPercent() <= lowesthpc then 
          g_game.attack(val)
          break
        end
      end
    end
  end
end)
 
Last edited:
AoE Rune caster with text box for preferred rune. tested on Evolunia with 'explosive impact rune' as default (would appreciate some feedback to how it can be improved, just a amateur rookie here 😅)

Code:
local currentEnemy
macro(200, "Aoe Rune", function()
    if g_game.isAttacking() then
     currentEnemy = g_game.getAttackingCreature()
     end
     if g_game.isAttacking(currentEnemy) then usewith((storage.atkItem), currentEnemy)
     end
end)
addTextEdit("atkItem", storage.atkItem or "3201", function(widget, text)
storage.atkItem = text
end)
 
Anyone has an idea on how to make a proper lure script? I tried looking for the actual lure system the bot has but couldnt find it, what im trying to do is to keep atacking and running, similar to "paladin run" on mage bot till it has 7-8 mobs, then keep walking+atacking
 
example of better follow, including stairs, holes, teleports etc
Code:
local toFollow = "Player2"
local toFollowPos = {}

local followMacro = macro(20, "follow target", function()
  local target = getCreatureByName(toFollow)
  if target then
    local tpos = target:getPosition()
    toFollowPos[tpos.z] = tpos
  end
  if player:isWalking() then return end
  local p = toFollowPos[posz()]
  if not p then return end
  if autoWalk(p, 20, {ignoreNonPathable=true, precision=1}) then
    delay(100)
  end
end)

onCreaturePositionChange(function(creature, oldPos, newPos)
  if creature:getName() == toFollow then
    toFollowPos[newPos.z] = newPos
  end
end)
 
Back
Top