Updated to OTCv8 3.0 rev 99

This commit is contained in:
OTCv8 2021-09-05 16:09:55 +00:00
parent a22d7a7a63
commit 4231b74314
96 changed files with 3024 additions and 1713 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,401 +0,0 @@
AttackEntry < Label
background-color: alpha
text-offset: 18 0
focusable: true
height: 16
CheckBox
id: enabled
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
width: 15
height: 15
margin-top: 2
margin-left: 3
$focus:
background-color: #00000055
Button
id: remove
!text: tr('x')
anchors.right: parent.right
margin-right: 15
width: 15
height: 15
AttackWindow < MainWindow
!text: tr('AttackBot')
size: 800 350
TextList
id: attackList
anchors.left: parent.left
anchors.top: parent.top
padding: 1
size: 500 150
margin-left: 3
margin-top: 3
margin-left: 3
vertical-scrollbar: attackListScrollBar
VerticalScrollBar
id: attackListScrollBar
anchors.top: attackList.top
anchors.bottom: attackList.bottom
anchors.right: attackList.right
step: 14
pixels-scroll: true
Label
id: category
anchors.top: attackList.bottom
anchors.left: attackList.left
anchors.right: attackList.right
text-align: center
margin-top: 5
image-source: /images/ui/panel_flat
image-border: 5
height: 21
margin-left: 25
margin-right: 25
NextButton
id: categoryNext
anchors.left: category.right
anchors.verticalCenter: category.verticalCenter
margin-left: 10
PreviousButton
id: categoryPrev
anchors.right: category.left
anchors.verticalCenter: category.verticalCenter
margin-right: 10
Label
id: parameter1
anchors.top: category.bottom
anchors.left: category.left
anchors.right: category.horizontalCenter
margin-top: 5
margin-right: 25
height: 21
text-align: center
image-source: /images/ui/panel_flat
image-border: 5
NextButton
id: parameter1Next
anchors.left: parameter1.right
anchors.verticalCenter: parameter1.verticalCenter
margin-left: 10
PreviousButton
id: parameter1Prev
anchors.right: parameter1.left
anchors.verticalCenter: parameter1.verticalCenter
margin-right: 10
Label
id: parameter2
anchors.top: category.bottom
anchors.left: category.horizontalCenter
anchors.right: category.right
margin-top: 5
margin-left: 25
height: 21
text-align: center
image-source: /images/ui/panel_flat
image-border: 5
NextButton
id: parameter2Next
anchors.left: parameter2.right
anchors.verticalCenter: parameter2.verticalCenter
margin-left: 10
PreviousButton
id: parameter2Prev
anchors.right: parameter2.left
anchors.verticalCenter: parameter2.verticalCenter
margin-right: 10
TextEdit
id: spellFormula
anchors.left: parent.left
anchors.top: parameter2Prev.bottom
margin-top: 20
margin-left: 30
width: 200
Label
id: spellDescription
anchors.left: prev.left
anchors.right: prev.right
anchors.bottom: prev.top
margin-bottom: 2
text-align: center
text: Insert Spell Formula Below
BotItem
id: itemId
anchors.left: parent.left
anchors.top: parameter2Prev.bottom
margin-top: 10
margin-left: 20
Label
id: itemDescription
anchors.left: itemId.right
margin-left: 5
anchors.verticalCenter: itemId.verticalCenter
text: < insert id or drag item here
Label
anchors.left: parent.left
anchors.bottom: BottomSeparator.top
margin-bottom: 10
text-align: center
text: Min Monsters:
SpinBox
id: minMonsters
anchors.left: prev.right
anchors.verticalCenter: prev.verticalCenter
margin-left: 5
width: 45
minimum: 1
maximum: 100
focusable: true
Label
anchors.left: minMonsters.right
anchors.verticalCenter: minMonsters.verticalCenter
margin-left: 10
text-align: center
text: Min Mana%:
SpinBox
id: minMana
anchors.left: prev.right
anchors.verticalCenter: prev.verticalCenter
margin-left: 5
width: 45
minimum: 1
maximum: 100
focusable: true
Label
anchors.left: prev.right
anchors.verticalCenter: prev.verticalCenter
margin-left: 10
text: Cooldown(ms):
!tooltip: tr('Optional, can be left at 1, recommended for custom spells/old tibia')
SpinBox
id: newCooldown
anchors.left: prev.right
anchors.verticalCenter: prev.verticalCenter
margin-left: 5
width: 60
minimum: 0
maximum: 99999
focusable: true
CheckBox
id: pvpSpell
anchors.verticalCenter: spellFormula.verticalCenter
anchors.left: spellFormula.right
width: 100
margin-left: 50
text: Spell for PVP
Button
id: addButton
anchors.right: attackList.right
anchors.bottom: BottomSeparator.top
text-align: center
text: Add
margin-bottom: 10
size: 80 20
Button
id: MoveUp
anchors.right: prev.right
anchors.bottom: prev.top
size: 80 20
text: Move Up
margin-bottom: 2
Button
id: MoveDown
anchors.right: prev.right
anchors.bottom: prev.top
size: 80 20
text: Move Down
text-align: center
margin-bottom: 2
VerticalSeparator
anchors.top: parent.top
anchors.bottom: BottomSeparator.top
anchors.left: MoveDown.right
margin-top: 3
margin-bottom: 3
margin-left: 10
Label
id: thing
anchors.left: prev.right
anchors.right: parent.right
anchors.top: parent.top
margin-top: 3
text-align: center
text: Additional Options
HorizontalSeparator
anchors.left: prev.left
anchors.right: prev.right
anchors.top: prev.bottom
margin-top: 3
margin-left: 5
CheckBox
id: IgnoreMana
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 10
margin-left: 5
width: 200
text: Check RL Tibia conditions
CheckBox
id: Kills
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 8
width: 200
height: 22
text: Don't use area attacks if less than kills to red skull
text-wrap: true
text-align: left
SpinBox
id: KillsAmount
anchors.top: prev.top
anchors.bottom: prev.bottom
anchors.left: prev.right
text-align: center
width: 50
minimum: 1
maximum: 10
focusable: true
margin-left: 5
Label
anchors.left: Kills.left
anchors.bottom: BottomSeparator.top
margin-bottom: 8
text: Profile:
TextEdit
id: Name
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 5
Button
id: ResetSettings
anchors.verticalCenter: prev.verticalCenter
anchors.right: parent.right
text: Reset Settings
margin-top: 1
CheckBox
id: Rotate
anchors.top: Kills.bottom
anchors.left: Kills.left
margin-top: 8
width: 220
text: Turn to side with most monsters
CheckBox
id: Cooldown
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 8
width: 220
text: Check spell cooldowns
CheckBox
id: Visible
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 8
width: 245
text: Items must be visible (recommended)
CheckBox
id: PvpMode
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 8
width: 245
text: PVP mode
CheckBox
id: PvpSafe
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 8
width: 245
text: PVP safe
CheckBox
id: BlackListSafe
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 8
width: 200
height: 18
text: Stop if Anti-RS player in range
SpinBox
id: AntiRsRange
anchors.top: prev.top
anchors.bottom: prev.bottom
anchors.left: prev.right
text-align: center
width: 50
minimum: 1
maximum: 10
focusable: true
margin-left: 5
Label
anchors.left: thing.left
anchors.right: thing.right
anchors.bottom: ResetSettings.top
margin-bottom: 10
text: Note: Cooldown value is optional for new global Tibia, recommended for Old tibia and custom OT
text-wrap: true
text-align: center
height: 40
multiline: true
HorizontalSeparator
id: BottomSeparator
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: CloseButton.top
margin-bottom: 8
Button
id: CloseButton
!text: tr('Close')
font: cipsoftFont
anchors.right: parent.right
anchors.bottom: parent.bottom
size: 45 21
margin-top: 15
margin-right: 5

View File

@ -17,6 +17,7 @@ end
-- libraries should be loaded first
local luaFiles = {
"main",
"items",
"vlib",
"new_cavebot_lib",
"configs", -- do not change this and above
@ -42,7 +43,7 @@ local luaFiles = {
"eat_food",
"equip",
"exeta",
"info",
"analyzer",
"jewellery_equipper",
"spy_level",
"supplies",

View File

@ -1,5 +1,7 @@
CaveBot.Actions = {}
local antiTrapTriggered = false
-- it adds an action widget to list
CaveBot.addAction = function(action, value, focus)
action = action:lower()
@ -148,7 +150,9 @@ CaveBot.registerAction("goto", "green", function(value, retries, prev)
return false -- different floor
end
if math.abs(pos.x-playerPos.x) + math.abs(pos.y-playerPos.y) > 40 then
local maxDist = storage.extras.gotoMaxDistance or 40
if math.abs(pos.x-playerPos.x) + math.abs(pos.y-playerPos.y) > maxDist then
return false -- too far way
end
@ -163,34 +167,36 @@ CaveBot.registerAction("goto", "green", function(value, retries, prev)
return true -- already at position
end
-- check if there's a path to that place, ignore creatures and fields
local path = findPath(playerPos, pos, 40, { ignoreNonPathable = true, precision = 1, ignoreCreatures = true })
local path = findPath(playerPos, pos, maxDist, { ignoreNonPathable = true, precision = 1, ignoreCreatures = true })
if not path then
return false -- there's no way
end
-- check if there's a path to destination but consider Creatures (attack only if trapped)
local path2 = findPath(playerPos, pos, 40, { ignoreNonPathable = true, precision = 1 })
local path2 = findPath(playerPos, pos, maxDist, { ignoreNonPathable = true, precision = 1 })
if not path2 then
local monsters = {}
local target = {} -- c = creature, d = distance
for i, spec in pairs(getSpectators()) do
if spec:isMonster() and spec:getType() ~= 3 then
if spec:canShoot() and findPath(playerPos, spec:getPosition(), 20, {ignoreNonPathable = true, precision = 1}) then
table.insert(monsters, {mob = spec, dist = getDistanceBetween(pos, spec:getPosition())})
if spec:isMonster() then
local path = findPath(playerPos, spec:getPosition(), 7, { ignoreNonPathable = true, precision = 1 })
if path then
local dist = getDistanceBetween(pos, spec:getPosition())
if not target.d or target.d > dist then
target = {c=spec, d=dist}
end
end
end
end
table.sort(monsters, function(a,b) return a.dist < b.dist end)
if monsters[1] then
g_game.attack(monsters[1].mob)
storage.blockMonster = monsters[1].mob
autoWalk(storage.blockMonster, 10, {precision = 1})
storage.clearing = true
CaveBot.setOff()
if target.c then
if target.c ~= getTarget() then
attack(target.c)
end
g_game.setChaseMode(1)
schedule(3000, function() CaveBot.setOn() end) -- just in case callback trigger fails
CaveBot.setOff()
antiTrapTriggered = true
return "retry"
else
return false -- there's no way
return false -- no other way
end
end
@ -200,7 +206,7 @@ CaveBot.registerAction("goto", "green", function(value, retries, prev)
end
-- try to find path, don't ignore creatures, ignore fields
if CaveBot.walkTo(pos, 40, { ignoreNonPathable = true }) then
if CaveBot.walkTo(pos, maxDist, { ignoreNonPathable = true }) then
return "retry"
end
@ -224,34 +230,14 @@ CaveBot.registerAction("goto", "green", function(value, retries, prev)
end
-- everything else failed, try to walk ignoring creatures, maybe will work
CaveBot.walkTo(pos, 40, { ignoreNonPathable = true, precision = 1, ignoreCreatures = true })
CaveBot.walkTo(pos, maxDist, { ignoreNonPathable = true, precision = 1, ignoreCreatures = true })
return "retry"
end)
onCreatureDisappear(function(creature)
if creature ~= storage.blockMonster then return end
if storage.clearing then
onAttackingCreatureChange(function(creature, oldCreature)
if antiTrapTriggered then
CaveBot.setOn()
storage.blockMonster = nil
storage.clearing = false
end
end)
onCreaturePositionChange(function(creature, newPos, oldPos)
if creature ~= storage.blockMonster and creature ~= player then return end
if storage.clearing then
if creature == storage.blockMonster and not findPath(player:getPosition(), newPos, 20, {ignoreNonPathable = true, precision = 1}) then
CaveBot.setOn()
storage.blockMonster = nil
storage.clearing = false
end
if creature == player then
if oldPos.z ~= newPos.z then
CaveBot.setOn()
storage.blockMonster = nil
storage.clearing = false
end
end
antiTrapTriggered = false
end
end)

View File

@ -10,6 +10,7 @@ CaveBot.Extensions.DWithdraw.setup = function()
end
local destContainer
local depotContainer
delay(70)
-- input validation
if not value or #data ~= 3 and #data ~= 4 then
@ -25,6 +26,11 @@ CaveBot.Extensions.DWithdraw.setup = function()
-- cap check
if freecap() < (capLimit or 200) then
for i, container in ipairs(getContainers()) do
if container:getName():lower():find("depot") or container:getName():lower():find("locker") then
g_game.close(container)
end
end
print("CaveBot[DepotWithdraw]: cap limit reached, proceeding")
return true
end
@ -56,6 +62,7 @@ CaveBot.Extensions.DWithdraw.setup = function()
-- stash validation
if depotContainer and #depotContainer:getItems() == 0 then
print("CaveBot[DepotWithdraw]: all items withdrawn")
g_game.close(depotContainer)
return true
end
@ -79,6 +86,7 @@ CaveBot.Extensions.DWithdraw.setup = function()
for i, container in pairs(g_game.getContainers()) do
if string.find(container:getName():lower(), "depot box") then
for j, item in ipairs(container:getItems()) do
statusMessage("[D_Withdraw] witdhrawing item: "..item:getId())
g_game.move(item, destContainer:getSlotPosition(destContainer:getItemsCount()), item:getCount())
return "retry"
end

View File

@ -11,6 +11,12 @@ local function resetCache()
reopenedContainers = false
destination = nil
lootTable = nil
for i, container in ipairs(getContainers()) do
if container:getName():lower():find("depot") or container:getName():lower():find("locker") then
g_game.close(container)
end
end
end
local description = g_game.getClientVersion() > 960 and "No - just deposit \n Yes - also reopen loot containers" or "currently not supported, will be added in near future"
@ -31,6 +37,8 @@ CaveBot.Extensions.Depositor.setup = function()
return true
end
delay(70)
-- backpacks etc
if value:lower() == "yes" then
-- reopening backpacks
@ -106,6 +114,7 @@ CaveBot.Extensions.Depositor.setup = function()
local id = item:getId()
if table.find(lootTable, id) then
local index = getStashingIndex(id) or item:isStackable() and 1 or 0
statusMessage("[Depositer] stashing item: " ..id.. " to depot: "..index+1)
CaveBot.StashItem(item, index, destination)
return "retry"
end

View File

@ -46,6 +46,7 @@ CaveBot.Extensions.InWithdraw.setup = function()
end
if inboxAmount == 0 then
warn("CaveBot[InboxWithdraw]: not enough items in inbox container, proceeding")
g_game.close(inboxContainer)
return true
end
@ -58,7 +59,8 @@ CaveBot.Extensions.InWithdraw.setup = function()
if not destination then
print("CaveBot[InboxWithdraw]: couldn't find proper destination container, skipping")
return falsed
g_game.close(inboxContainer)
return false
end
CaveBot.PingDelay(2)

View File

@ -0,0 +1,26 @@
local minimap = modules.game_minimap.minimapWidget
minimap.onMouseRelease = function(widget,pos,button)
if not minimap.allowNextRelease then return true end
minimap.allowNextRelease = false
local mapPos = minimap:getTilePosition(pos)
if not mapPos then return end
if button == 1 then
local player = g_game.getLocalPlayer()
if minimap.autowalk then
player:autoWalk(mapPos)
end
return true
elseif button == 2 then
local menu = g_ui.createWidget('PopupMenu')
menu:setId("minimapMenu")
menu:setGameMenu(true)
menu:addOption(tr('Create mark'), function() minimap:createFlagWindow(mapPos) end)
menu:addOption(tr('Add CaveBot GoTo'), function() CaveBot.addAction("goto", mapPos.x .. "," .. mapPos.y .. "," .. mapPos.z, true) CaveBot.save() end)
menu:display(pos)
return true
end
return false
end

View File

@ -172,7 +172,7 @@ onTextMessage(function(mode, text)
local m1 = storage.caveBotTasker.monster
local m2 = storage.caveBotTasker.monster2
if monster == m1 or monster == m2 and storage.caveBotTasker.countaa then
if monster == m1 or monster == m2 and storage.caveBotTasker.count then
storage.caveBotTasker.count = storage.caveBotTasker.count + 1
end
end)

View File

@ -23,15 +23,26 @@ CaveBot.Extensions.Withdraw.setup = function()
-- check for retries
if retries > 100 then
print("CaveBot[Withdraw]: actions limit reached, proceeding")
for i, container in ipairs(getContainers()) do
if container:getName():lower():find("depot") or container:getName():lower():find("locker") then
g_game.close(container)
end
end
return true
end
-- check for items
if itemAmount(id) >= amount then
print("CaveBot[Withdraw]: enough items, proceeding")
for i, container in ipairs(getContainers()) do
if container:getName():lower():find("depot") or container:getName():lower():find("locker") then
g_game.close(container)
end
end
return true
end
statusMessage("[Withdraw] withdrawing item: " ..id.. " x"..amount)
CaveBot.WithdrawItem(id, amount, source)
CaveBot.PingDelay()
return "retry"

View File

@ -3,6 +3,49 @@ local targetCount = 0
local delayValue = 0
local lureMax = 0
local anchorPosition = nil
local lastCall = now
local delayFrom = nil
function getWalkableTilesCount(position)
local count = 0
for i, tile in pairs(getNearTiles(position)) do
if tile:isWalkable() or tile:hasCreature() then
count = count + 1
end
end
return count
end
function rePosition(minTiles)
minTiles = minTiles or 8
if now - lastCall < 500 then return end
local pPos = player:getPosition()
local tiles = getNearTiles(pPos)
local playerTilesCount = getWalkableTilesCount(pPos)
local tilesTable = {}
if playerTilesCount > minTiles then return end
for i, tile in ipairs(tiles) do
tilesTable[tile] = not tile:hasCreature() and tile:isWalkable() and getWalkableTilesCount(tile:getPosition()) or nil
end
local best = 0
local target = nil
for k,v in pairs(tilesTable) do
if v > best and v > playerTilesCount then
best = v
target = k:getPosition()
end
end
if target then
lastCall = now
return CaveBot.GoTo(target, 0)
end
end
TargetBot.Creature.attack = function(params, targets, isLooting) -- params {config, creature, danger, priority}
if player:isWalking() then
lastWalk = now
@ -97,9 +140,10 @@ TargetBot.Creature.walk = function(creature, config, targets)
lureMax = config.lureMax
end
delayFrom = config.delayFrom
-- luring
if TargetBot.canLure() and (config.lure or config.lureCavebot or config.dynamicLure) and not (config.chase and creature:getHealthPercent() < 5) and not isTrapped then
if TargetBot.canLure() and (config.lure or config.lureCavebot or config.dynamicLure) and not (creature:getHealthPercent() < (storage.extras.killUnder or 30)) and not isTrapped then
local monsters = 0
if targetBotLure then
anchorPosition = nil
@ -119,8 +163,12 @@ TargetBot.Creature.walk = function(creature, config, targets)
end
end
local lastRePosition = now
if not config.chase and not config.keepDistance and config.rePosition and (creature:getHealthPercent() >= storage.extras.killUnder) then
return rePosition(config.rePositionAmount or 6)
end
local currentDistance = findPath(pos, cpos, 10, {ignoreCreatures=true, ignoreNonPathable=true, ignoreCost=true})
if config.chase and (creature:getHealthPercent() < (storage.extras.killUnder or 30) or not config.keepDistance) then
if ((storage.extras.killUnder > 1 and (creature:getHealthPercent() < storage.extras.killUnder)) or config.chase) and not config.keepDistance then
if #currentDistance > 1 then
return TargetBot.walkTo(cpos, 10, {ignoreNonPathable=true, precision=1})
end
@ -187,6 +235,6 @@ onPlayerPositionChange(function(newPos, oldPos)
if not lureMax then return end
if storage.TargetBotDelayWhenPlayer then return end
if targetCount < lureMax/2 or not target() then return end
if targetCount < (delayFrom or lureMax/2) or not target() then return end
CaveBot.delay(delayValue or 0)
end)

View File

@ -82,9 +82,11 @@ TargetBot.Creature.edit = function(config, callback) -- callback = function(newC
addScrollBar("keepDistanceRange", "Keep distance", 1, 5, 1)
addScrollBar("anchorRange", "Anchoring Range", 1, 10, 3)
addScrollBar("lureCount", "Classic Lure", 0, 5, 1)
addScrollBar("lureMin", "Dynamic lure min", 0, 9, 1)
addScrollBar("lureMax", "Dynamic lure max", 1, 9, 3)
addScrollBar("lureMin", "Dynamic lure min", 0, 29, 1)
addScrollBar("lureMax", "Dynamic lure max", 1, 30, 3)
addScrollBar("lureDelay", "Dynamic lure delay", 100, 1000, 250)
addScrollBar("delayFrom", "Start delay when monsters", 1, 29, 2)
addScrollBar("rePositionAmount", "Min tiles to rePosition", 0, 7, 5)
addCheckBox("chase", "Chase", true)
addCheckBox("keepDistance", "Keep Distance", false)
@ -97,4 +99,5 @@ TargetBot.Creature.edit = function(config, callback) -- callback = function(newC
addCheckBox("dynamicLure", "Dynamic lure", false)
addCheckBox("dynamicLureDelay", "Dynamic lure delay", false)
addCheckBox("diamondArrows", "D-Arrows priority", false)
addCheckBox("rePosition", "rePosition to better tile", false)
end

View File

@ -166,7 +166,7 @@ TargetBot.Looting.getLootContainers = function(containers)
for index, container in pairs(containers) do
openedContainersById[container:getContainerItem():getId()] = 1
if containersById[container:getContainerItem():getId()] and not container.lootContainer then
if container:getItemsCount() < container:getCapacity() then
if container:getItemsCount() < container:getCapacity() or container:hasPages() then
table.insert(lootContainers, container)
else -- it's full, open next container if possible
for slot, item in ipairs(container:getItems()) do

View File

@ -67,17 +67,3 @@ TargetBotLootingPanel < Panel
anchors.verticalCenter: prev.verticalCenter
text: Min. capacity:
margin-left: 5
Label
margin-top: 3
margin-left: 20
margin-right: 20
!text: tr("Drag item or click on any of empty slot")
text-align: center
text-wrap: true
text-auto-resize: true
BotButton
margin-top: 3
text: Help & Tutorials
@onClick: g_platform.openUrl("http://bot.otclient.ovh/")

View File

@ -47,7 +47,7 @@ targetbotMacro = macro(100, function()
local targets = 0
local highestPriorityParams = nil
for i, creature in ipairs(creatures) do
local path = findPath(player:getPosition(), creature:getPosition(), 7, {ignoreLastCreature=true, ignoreNonPathable=true, ignoreCost=true})
local path = findPath(player:getPosition(), creature:getPosition(), 7, {ignoreLastCreature=true, ignoreNonPathable=true, ignoreCost=true, ignoreCreatures=true})
if creature:isMonster() and (oldTibia or creature:getType() < 3) and path then
local params = TargetBot.Creature.calculateParams(creature, path) -- return {craeture, config, danger, priority}
dangerLevel = dangerLevel + params.danger

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,599 @@
AttackEntry < UIWidget
background-color: alpha
text-offset: 18 1
focusable: true
height: 16
font: verdana-11px-rounded
text-align: left
CheckBox
id: enabled
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
width: 15
height: 15
margin-top: 2
margin-left: 3
$focus:
background-color: #00000055
Button
id: remove
!text: tr('x')
anchors.right: parent.right
margin-right: 15
width: 15
height: 15
AttackBotBotPanel < Panel
height: 38
BotSwitch
id: title
anchors.top: parent.top
anchors.left: parent.left
text-align: center
width: 130
!text: tr('AttackBot')
Button
id: settings
anchors.top: prev.top
anchors.left: prev.right
anchors.right: parent.right
margin-left: 3
height: 17
text: Setup
Button
id: 1
anchors.top: prev.bottom
anchors.left: parent.left
text: 1
margin-right: 2
margin-top: 4
size: 17 17
Button
id: 2
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
text: 2
margin-left: 4
size: 17 17
Button
id: 3
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
text: 3
margin-left: 4
size: 17 17
Button
id: 4
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
text: 4
margin-left: 4
size: 17 17
Button
id: 5
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
text: 5
margin-left: 4
size: 17 17
Label
id: name
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
anchors.right: parent.right
text-align: center
margin-left: 4
height: 17
text: Profile #1
background: #292A2A
CategoryLabel < Panel
size: 315 15
image-source: /images/ui/panel_flat
image-border: 5
padding: 1
Label
id: description
anchors.fill: parent
text-align: center
text: Area Rune (avalanche, great fireball, etc)
font: verdana-11px-rounded
background: #363636
SourceLabel < Panel
size: 105 15
image-source: /images/ui/panel_flat
image-border: 5
padding: 1
Label
id: description
anchors.fill: parent
text-align: center
text: Monster Name
font: verdana-11px-rounded
background: #363636
RangeLabel < Panel
size: 323 15
image-source: /images/ui/panel_flat
image-border: 5
padding: 1
Label
id: description
anchors.fill: parent
text-align: center
text: 5 Sqm
font: verdana-11px-rounded
background: #363636
PreButton < PreviousButton
background: #363636
height: 15
NexButton < NextButton
background: #363636
height: 15
AttackBotPanel < Panel
size: 500 200
image-source: /images/ui/panel_flat
image-border: 5
padding: 5
TextList
id: entryList
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
margin-top: 3
size: 430 100
vertical-scrollbar: entryListScrollBar
VerticalScrollBar
id: entryListScrollBar
anchors.top: entryList.top
anchors.bottom: entryList.bottom
anchors.right: entryList.right
step: 14
pixels-scroll: true
PreButton
id: previousCategory
anchors.left: entryList.left
anchors.top: entryList.bottom
margin-top: 8
NexButton
id: nextCategory
anchors.left: category.right
anchors.top: entryList.bottom
margin-top: 8
margin-left: 2
CategoryLabel
id: category
anchors.top: entryList.bottom
anchors.left: previousCategory.right
anchors.verticalCenter: previousCategory.verticalCenter
margin-left: 3
PreButton
id: previousSource
anchors.left: entryList.left
anchors.top: category.bottom
margin-top: 8
NexButton
id: nextSource
anchors.left: source.right
anchors.top: category.bottom
margin-top: 8
margin-left: 2
SourceLabel
id: source
anchors.top: category.bottom
anchors.left: previousSource.right
anchors.verticalCenter: previousSource.verticalCenter
margin-left: 3
PreButton
id: previousRange
anchors.left: nextSource.right
anchors.verticalCenter: nextSource.verticalCenter
margin-left: 8
NexButton
id: nextRange
anchors.left: range.right
anchors.verticalCenter: range.verticalCenter
margin-left: 2
RangeLabel
id: range
anchors.left: previousRange.right
anchors.verticalCenter: previousRange.verticalCenter
margin-left: 3
TextEdit
id: monsters
anchors.left: entryList.left
anchors.top: range.bottom
margin-top: 5
size: 405 15
text: monster names
font: cipsoftFont
background: #363636
Label
anchors.left: prev.left
anchors.top: prev.bottom
margin-top: 6
margin-left: 3
text-align: center
text: Mana%:
font: verdana-11px-rounded
SpinBox
id: manaPercent
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 4
size: 30 20
minimum: 0
maximum: 99
step: 1
editable: true
focusable: true
Label
anchors.left: prev.right
margin-left: 7
anchors.verticalCenter: prev.verticalCenter
text: Creatures:
font: verdana-11px-rounded
SpinBox
id: creatures
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 4
size: 30 20
minimum: 1
maximum: 99
step: 1
editable: true
focusable: true
CheckBox
id: orMore
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 3
tooltip: or more creatures
Label
anchors.left: prev.right
margin-left: 7
anchors.verticalCenter: prev.verticalCenter
text: HP:
font: verdana-11px-rounded
SpinBox
id: minHp
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 4
size: 40 20
minimum: 0
maximum: 99
value: 0
editable: true
focusable: true
Label
anchors.left: prev.right
margin-left: 4
anchors.verticalCenter: prev.verticalCenter
text: -
font: verdana-11px-rounded
SpinBox
id: maxHp
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 4
size: 40 20
minimum: 1
maximum: 100
value: 100
editable: true
focusable: true
Label
anchors.left: prev.right
margin-left: 7
anchors.verticalCenter: prev.verticalCenter
text: CD:
font: verdana-11px-rounded
SpinBox
id: cooldown
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 4
size: 60 20
minimum: 0
maximum: 999999
step: 100
value: 0
editable: true
focusable: true
Button
id: up
anchors.right: parent.right
anchors.top: entryList.bottom
size: 60 17
text: Move Up
text-align: center
font: cipsoftFont
margin-top: 7
margin-right: 8
Button
id: down
anchors.right: prev.left
anchors.verticalCenter: prev.verticalCenter
size: 60 17
margin-right: 5
text: Move Down
text-align: center
font: cipsoftFont
Button
id: addEntry
anchors.right: parent.right
anchors.bottom: parent.bottom
size: 40 19
text-align: center
text: New
font: cipsoftFont
BotItem
id: itemId
anchors.right: addEntry.left
margin-right: 5
anchors.bottom: parent.bottom
margin-bottom: 2
tooltip: drag item here on press to open window
TextEdit
id: spellName
anchors.top: monsters.top
anchors.left: monsters.right
anchors.right: parent.right
margin-left: 5
height: 15
text: spell name
background: #363636
font: cipsoftFont
visible: false
SettingsPanel < Panel
size: 500 200
image-source: /images/ui/panel_flat
image-border: 5
padding: 10
VerticalSeparator
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: Visible.right
margin-left: 10
margin-top: 5
margin-bottom: 5
Label
anchors.top: parent.top
anchors.left: prev.right
anchors.right: parent.right
margin-left: 10
text-align: center
font: verdana-11px-rounded
text: Profile:
TextEdit
id: profileName
anchors.top: prev.bottom
margin-top: 3
anchors.left: prev.left
anchors.right: prev.right
margin-left: 20
margin-right: 20
Button
id: resetSettings
anchors.right: parent.right
anchors.bottom: parent.bottom
text-align: center
text: Reset Settings
CheckBox
id: IgnoreMana
anchors.top: parent.top
anchors.left: parent.left
margin-top: 5
width: 200
text: Check RL Tibia conditions
CheckBox
id: Kills
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 8
width: 200
height: 22
text: Don't use area attacks if less than kills to red skull
text-wrap: true
text-align: left
SpinBox
id: KillsAmount
anchors.top: prev.top
anchors.bottom: prev.bottom
anchors.left: prev.right
text-align: left
width: 30
minimum: 1
maximum: 10
focusable: true
margin-left: 5
CheckBox
id: Rotate
anchors.top: Kills.bottom
anchors.left: Kills.left
margin-top: 8
width: 220
text: Turn to side with most monsters
CheckBox
id: Cooldown
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 8
width: 220
text: Check spell cooldowns
CheckBox
id: Visible
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 8
width: 245
text: Items must be visible (recommended)
CheckBox
id: PvpMode
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 8
width: 245
text: PVP mode
CheckBox
id: PvpSafe
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 8
width: 245
text: PVP safe
CheckBox
id: BlackListSafe
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 8
width: 200
height: 18
text: Stop if Anti-RS player in range
SpinBox
id: AntiRsRange
anchors.top: prev.top
anchors.bottom: prev.bottom
anchors.left: prev.right
text-align: center
width: 50
minimum: 1
maximum: 10
focusable: true
margin-left: 5
AttackBotWindow < MainWindow
size: 535 300
padding: 15
text: AttackBot v2
Label
id: mainLabel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
margin-top: 10
margin-left: 2
!text: tr('More important methods come first (Example: Exori gran above Exori)')
text-align: left
font: verdana-11px-rounded
color: #aeaeae
SettingsPanel
id: settingsPanel
anchors.top: prev.bottom
margin-top: 10
anchors.left: parent.left
margin-left: 2
Label
id: settingsLabel
anchors.verticalCenter: prev.top
anchors.left: prev.left
margin-left: 3
text: Settings
color: #fe4400
font: verdana-11px-rounded
AttackBotPanel
id: mainPanel
anchors.top: mainLabel.bottom
margin-top: 10
anchors.left: parent.left
margin-left: 2
visible: false
Label
id: shooterLabel
anchors.verticalCenter: prev.top
anchors.left: prev.left
margin-left: 3
text: Spell Shooter
color: #fe4400
font: verdana-11px-rounded
visible: false
HorizontalSeparator
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: closeButton.top
margin-bottom: 10
Button
id: closeButton
anchors.right: parent.right
anchors.bottom: parent.bottom
size: 45 21
text: Close
font: cipsoftFont
Button
id: settings
anchors.left: parent.left
anchors.verticalCenter: prev.verticalCenter
size: 50 21
font: cipsoftFont
text: Settings

View File

@ -4,7 +4,6 @@ if type(storage[panelName]) ~= "table" then
storage[panelName] = {
enabled = false;
purse = true;
all = true;
list = {
{
value = "Main Backpack",
@ -199,24 +198,13 @@ ContListsWindow < MainWindow
anchors.bottom: closeButton.top
margin-bottom: 8
CheckBox
id: all
anchors.left: parent.left
anchors.bottom: parent.bottom
text: Open All
tooltip: Opens all containers in main backpack.
width: 90
height: 15
margin-top: 2
margin-left: 3
CheckBox
id: purse
anchors.left: prev.right
anchors.left: parent.left
anchors.bottom: parent.bottom
text: Open Purse
tooltip: Opens Store/Charm Purse
width: 90
width: 85
height: 15
margin-top: 2
margin-left: 3
@ -227,7 +215,18 @@ ContListsWindow < MainWindow
anchors.bottom: parent.bottom
text: Sort Items
tooltip: Sort items based on items widget
width: 90
width: 85
height: 15
margin-top: 2
margin-left: 15
CheckBox
id: forceOpen
anchors.left: prev.right
anchors.bottom: parent.bottom
text: Keep Open
tooltip: Will keep open containers all the time
width: 85
height: 15
margin-top: 2
margin-left: 15
@ -292,7 +291,7 @@ function reopenBackpacks()
g_game.open(bpItem)
end
schedule(250, function()
schedule(500, function()
local delay = 200
if config.purse then
@ -301,33 +300,11 @@ function reopenBackpacks()
use(item)
end
end
if config.all then
local nextContainers = {}
containers = getContainers()
for i, container in pairs(g_game.getContainers()) do
for i, item in ipairs(container:getItems()) do
if item:isContainer() then
if item:isContainer() and config.all then
table.insert(nextContainers, item)
end
end
end
end
if #nextContainers > 0 then
for i = 1, #nextContainers do
schedule(delay, function()
g_game.open(nextContainers[i], nil)
end)
delay = delay + 250
end
end
else
for i=1,#lstBPs do
schedule(delay, function()
openContainer(lstBPs[i])
end)
delay = delay + 250
end
for i=1,#lstBPs do
schedule(delay, function()
openContainer(lstBPs[i])
end)
delay = delay + 250
end
end)
@ -371,12 +348,11 @@ if rootWidget then
end
contListWindow.sort:setChecked(config.sort)
contListWindow.all.onClick = function(widget)
config.all = not config.all
contListWindow.all:setChecked(config.all)
label.enabled:setTooltip(config.all and 'Opens all containers in main backpack.' or 'Opens listed containers from main backpack.')
contListWindow.forceOpen.onClick = function(widget)
config.forceOpen = not config.forceOpen
contListWindow.forceOpen:setChecked(config.forceOpen)
end
contListWindow.all:setChecked(config.all)
contListWindow.forceOpen:setChecked(config.forceOpen)
local function refreshSortList(k, t)
t = t or {}
@ -490,38 +466,58 @@ end
local function properTable(t)
local r = {}
for _, entry in pairs(t) do
table.insert(r, entry.id)
if type(entry) == "number" then
table.insert(r, entry)
else
table.insert(r, entry.id)
end
end
return r
end
macro(100, function()
if not config.sort then return end
if not config.sort and not config.purse then return end
local storageVal = config.list
for _, entry in pairs(storageVal) do
local dId = entry.item
local items = properTable(entry.items)
for _, container in pairs(getContainers()) do
local cName = container:getName():lower()
if not cName:find("depot") and not cName:find("depot") and not cName:find("quiver") then
local cId = container:getContainerItem():getId()
for __, item in ipairs(container:getItems()) do
local id = item:getId()
if table.find(items, id) and cId ~= dId then
local destination = getContainerByItem(dId)
if destination and not containerIsFull(destination) then
return moveItem(item, destination)
-- sorting
if config.sort then
for _, container in pairs(getContainers()) do
local cName = container:getName():lower()
if not cName:find("depot") and not cName:find("depot") and not cName:find("quiver") then
local cId = container:getContainerItem():getId()
for __, item in ipairs(container:getItems()) do
local id = item:getId()
if table.find(items, id) and cId ~= dId then
local destination = getContainerByItem(dId, true)
if destination and not containerIsFull(destination) then
return moveItem(item, destination)
end
end
end
end
end
end
-- keep open / purse 23396
if config.forceOpen then
local container = getContainerByItem(dId)
if not container then
if getBack() and getBack():getId() == dId then
g_game.open(getBack())
else
local cItem = findItem(dId)
if cItem then
return g_game.open(cItem)
end
end
end
end
end
if config.purse and config.forceOpen and not getContainerByItem(23396) then
return use(getPurse())
end
delay(900)
end)

View File

@ -134,9 +134,9 @@ macro(200, function()
for __, item in ipairs(container:getItems()) do
for ___, userItem in ipairs(tables[i]) do
if item:getId() == userItem then
return i == 1 and freecap() < 150 and g_game.move(item, pos(), item:getCount()) or
return i == 1 and freecap() < 150 and dropItem(item) or
i == 2 and use(item) or
g_game.move(item, pos(), item:getCount())
i == 3 and dropItem(item)
end
end
end

View File

@ -622,7 +622,6 @@ macro(100, function()
end
end
standBySpells = true
lastMana = mana()
end)
-- items
@ -707,22 +706,15 @@ macro(100, function()
end
end
standByItems = true
lastMana = mana()
end)
UI.Separator()
onAddThing(function(tile, thing)
if thing == player then return end
if getDistanceBetween(tile:getPosition(), player:getPosition()) == 0 then
standByItems = false
standBySpells = false
end
onPlayerHealthChange(function(healthPercent)
standByItems = false
standBySpells = false
end)
macro(5000, function()
if (standByItems or standBySpells) and mana() >= lastMana then
lastMana = mana()
standByItems = false
standBySpells = false
end
onManaChange(function(player, mana, maxMana, oldMana, oldMaxMana)
standByItems = false
standBySpells = false
end)

View File

@ -63,7 +63,7 @@ Panel
sioListWindow:hide()
-- TextWindow
sioListWindow.spellName:setText(config.spellName)
sioListWindow.spellName:setText(config.customSpellName)
sioListWindow.spellName.onTextChange = function(widget, text)
config.customSpellName = text
end

View File

@ -126,6 +126,7 @@ if rootWidget then
if math.max(math.abs(posx()-specPos.x), math.abs(posy()-specPos.y)) <= 8 then
playSound("/sounds/Player_Detected.ogg")
delay(1500)
g_window.setTitle(name() .. " - Player Detected!")
if config.playerDetectedLogout then
modules.game_interface.tryLogout(false)
end
@ -142,6 +143,7 @@ if rootWidget then
if math.max(math.abs(posx()-specPos.x), math.abs(posy()-specPos.y)) <= 8 then
playSound("/sounds/Creature_Detected.ogg")
delay(1500)
g_window.setTitle(name() .. " - Creature Detected! ")
return
end
end
@ -151,6 +153,7 @@ if rootWidget then
if config.healthBelow then
if hppercent() <= config.healthValue then
playSound("/sounds/Low_Health.ogg")
g_window.setTitle(name() .. " - Low Health!")
delay(1500)
return
end
@ -159,6 +162,7 @@ if rootWidget then
if config.manaBelow then
if manapercent() <= config.manaValue then
playSound("/sounds/Low_Mana.ogg")
g_window.setTitle(name() .. " - Low Mana!")
delay(1500)
return
end
@ -168,6 +172,7 @@ if rootWidget then
onTalk(function(name, level, mode, text, channelId, pos)
if mode == 4 and config.enabled and config.privateMessage then
playSound("/sounds/Private_Message.ogg")
g_window.setTitle(name() .. " - Private Message")
return
end
end)

View File

@ -0,0 +1,437 @@
setDefaultTab("Main")
-- first, the variables
local launchTime = now
local startExp = exp()
local dmgTable = {}
local healTable = {}
local expTable = {}
local totalDmg = 0
local totalHeal = 0
local dmgDistribution = {}
local first = "-"
local second = "-"
local third = "-"
local bestHit = 0
local bestHeal = 0
local lootedItems = {}
local useData = {}
local usedItems ={}
local resetSessionData = function()
launchTime = now
startExp = exp()
dmgTable = {}
healTable = {}
expTable = {}
totalDmg = 0
totalHeal = 0
dmgDistribution = {}
first = "-"
second = "-"
third = "-"
bestHit = 0
bestHeal = 0
lootedItems = {}
useData = {}
usedItems ={}
refreshLoot()
refreshWaste()
end
function format_thousand(v)
if not v then return 0 end
local s = string.format("%d", math.floor(v))
local pos = string.len(s) % 3
if pos == 0 then pos = 3 end
return string.sub(s, 1, pos)
.. string.gsub(string.sub(s, pos+1), "(...)", ".%1")
end
local expGained = function()
return exp() - startExp
end
local expLeft = function()
local level = lvl()+1
return math.floor((50*level*level*level)/3 - 100*level*level + (850*level)/3 - 200) - exp()
end
local niceTimeFormat = function(v) -- v in seconds
local hours = string.format("%02.f", math.floor(v/3600))
local mins = string.format("%02.f", math.floor(v/60 - (hours*60)))
return hours .. ":" .. mins .. "h"
end
local uptime
local sessionTime = function()
uptime = math.floor((now - launchTime)/1000)
return niceTimeFormat(uptime)
end
sessionTime()
local expPerHour = function(calculation)
local r = 0
if #expTable > 0 then
r = exp() - expTable[1]
else
return "-"
end
if uptime < 15*60 then
r = math.ceil((r/uptime)*60*60)
else
r = math.ceil(r*8)
end
if calculation then
return r
else
return format_thousand(r)
end
end
local timeToLevel = function()
local t = 0
if expPerHour(true) == 0 or expPerHour() == "-" then
return "-"
else
t = expLeft()/expPerHour(true)
return niceTimeFormat(math.ceil(t*60*60))
end
end
local sumT = function(t)
local s = 0
for i,v in pairs(t) do
s = s + v.d
end
return s
end
local valueInSeconds = function(t)
local d = 0
local time = 0
if #t > 0 then
for i, v in ipairs(t) do
if now - v.t <= 3000 then
if time == 0 then
time = v.t
end
d = d + v.d
else
table.remove(t, 1)
end
end
end
return math.ceil(d/((now-time)/1000))
end
local regex = "You lose ([0-9]*) hitpoints due to an attack by ([a-z]*) ([a-z A-z-]*)"
onTextMessage(function(mode, text)
if mode == 21 then -- damage dealt
totalDmg = totalDmg + getFirstNumberInText(text)
table.insert(dmgTable, {d = getFirstNumberInText(text), t = now})
if getFirstNumberInText(text) > bestHit then
bestHit = getFirstNumberInText(text)
end
end
if mode == 23 then -- healing
totalHeal = totalHeal + getFirstNumberInText(text)
table.insert(healTable, {d = getFirstNumberInText(text), t = now})
if getFirstNumberInText(text) > bestHeal then
bestHeal = getFirstNumberInText(text)
end
end
-- damage distribution part
if text:find("You lose") then
local data = regexMatch(text, regex)[1]
if data then
local monster = data[4]
local val = data[2]
table.insert(dmgDistribution, {v=val,m=monster,t=now})
end
end
end)
-- tables maintance
macro(500, function()
local dmgFinal = {}
local labelTable = {}
local dmgSum = 0
table.insert(expTable, exp())
if #expTable > 15*60 then
for i,v in pairs(expTable) do
if i == 1 then
table.remove(expTable, i)
end
end
end
for i,v in pairs(dmgDistribution) do
if now - v.t > 60*1000*10 then
table.remove(dmgDistribution, i)
else
dmgSum = dmgSum + v.v
if not dmgFinal[v.m] then
dmgFinal[v.m] = v.v
else
dmgFinal[v.m] = dmgFinal[v.m] + v.v
end
end
end
if not dmgFinal[1] then
first = "-"
end
if not dmgFinal[2] then
second = "-"
end
if not dmgFinal[3] then
third = "-"
end
local iter = 0
for k,v in pairs(dmgFinal) do
table.insert(labelTable, {m=k, d=tonumber(v)})
end
table.sort(labelTable, function(a,b) return a.d > b.d end)
for i,v in pairs(labelTable) do
local label = v.m .. ": " .. math.floor((v.d/dmgSum)*100) .. "%"
if i == 1 then
first = label
elseif i == 2 then
second = label
elseif i == 3 then
third = label
end
end
end)
-- visuals
UI.Separator()
local main = UI.createWidget("MainAnalyzer")
local ui = UI.createWidget("HuntingAnalyzer")
local ui2 = UI.createWidget("LootAnalyzer")
ui:hide()
ui2:hide()
function refreshLoot()
for i, child in pairs(ui2.List:getChildren()) do
child:destroy()
end
for k,v in pairs(lootedItems) do
local label = g_ui.createWidget("LootItemLabel", ui2.List)
label:setText(v .. "x " .. k)
end
end
function refreshWaste()
for i, child in pairs(ui2.supplyList:getChildren()) do
child:destroy()
end
for k,v in pairs(usedItems) do
local label = g_ui.createWidget("LootItemLabel", ui2.supplyList)
label:setText(v .. "x " .. k)
end
end
-- loot analyzer
-- adding
local containers = CaveBot.GetLootContainers()
local lastCap = freecap()
onAddItem(function(container, slot, item, oldItem)
if not table.find(containers, container:getContainerItem():getId()) then return end
if isInPz() then return end
if slot > 0 then return end
if freecap() >= lastCap then return end
local name = item:getId() == 3031 and "gold coin" or item:getId() == 3035 and "platinum coin" or item:getId() == 3043 and "crystal coin" or item:getMarketData().name
if not lootedItems[name] then
lootedItems[name] = item:getCount()
else
lootedItems[name] = lootedItems[name] + item:getCount()
end
refreshLoot()
end)
onContainerUpdateItem(function(container, slot, item, oldItem)
if not table.find(containers, container:getContainerItem():getId()) then return end
if not oldItem then return end
if isInPz() then return end
if freecap() == lastCap then return end
local name = item:getId() == 3031 and "gold coin" or item:getId() == 3035 and "platinum coin" or item:getId() == 3043 and "crystal coin" or item:getMarketData().name
local amount = item:getCount() - oldItem:getCount()
if not lootedItems[name] then
lootedItems[name] = amount
else
lootedItems[name] = lootedItems[name] + amount
end
refreshLoot()
end)
-- waste
local regex3 = [[\d ([a-z A-Z]*)s...]]
useData = {}
usedItems = {}
onTextMessage(function(mode, text)
text = text:lower()
if not text:find("using one of") then return end
local amount = getFirstNumberInText(text)
local re = regexMatch(text, regex3)
local name = re[1][2]
if not useData[name] then
useData[name] = amount
else
if math.abs(useData[name]-amount) == 1 then
useData[name] = amount
if not usedItems[name] then
usedItems[name] = 1
else
usedItems[name] = usedItems[name] + 1
end
end
end
refreshWaste()
end)
function toggleBetween()
if ui:isVisible() then
ui:hide()
ui2:show()
main.change:setText("Hunt")
else
ui:show()
ui2:hide()
main.change:setText("Loot")
end
end
function hideAll()
if not ui:isVisible() and not ui2:isVisible() then
ui:show()
ui2:hide()
else
ui:hide()
ui2:hide()
end
end
main.reset.onClick = function(widget)
resetSessionData()
end
main.toggle.onClick = function(widget)
hideAll()
end
main.change.onClick = function(widget)
toggleBetween()
end
function hourVal(v)
return (v/uptime)*3600
end
local lootWorth
local wasteWorth
local balance
local balanceDesc
local hourDesc
local desc
local hour
function bottingStats()
lootWorth = 0
wasteWorth = 0
for k, v in pairs(lootedItems) do
if LootItems[k] then
lootWorth = lootWorth + (LootItems[k]*v)
end
end
for k, v in pairs(usedItems) do
if LootItems[k] then
wasteWorth = wasteWorth + (LootItems[k]*v)
end
end
balance = lootWorth - wasteWorth
return lootWorth, wasteWorth, balance
end
function bottingLabels(lootWorth, wasteWorth, balance)
balanceDesc = nil
hourDesc = nil
desc = nil
if balance >= 1000000 or balance <= -1000000 then
desc = balance / 1000000
balanceDesc = math.floor(desc) .. "." .. math.floor(desc * 10) % 10 .. "kk"
elseif balance >= 1000 or balance <= -1000 then
desc = balance / 1000
balanceDesc = math.floor(desc) .. "." .. math.floor(desc * 10) % 10 .."k"
else
balanceDesc = balance .. "gp"
end
hour = hourVal(balance)
if hour >= 1000000 or hour <= -1000000 then
desc = balance / 1000000
hourDesc = math.floor(hourVal(desc)) .. "." .. math.floor(hourVal(desc) * 10) % 10 .. "kk/h"
elseif hour >= 1000 or hour <= -1000 then
desc = balance / 1000
hourDesc = math.floor(hourVal(desc)) .. "." .. math.floor(hourVal(desc) * 10) % 10 .. "k/h"
else
hourDesc = math.floor(hourVal(balance)) .. "gp/h"
end
return balanceDesc, hourDesc
end
function reportStats()
local lootWorth, wasteWorth, balance = bottingStats()
local balanceDesc, hourDesc = bottingLabels(lootWorth, wasteWorth, balance)
local a, b, c
a = "Session Time: " .. sessionTime() .. ", Exp Gained: " .. format_thousand(expGained()) .. ", Exp/h: " .. expPerHour()
b = " | Balance: " .. balanceDesc .. " (" .. hourDesc .. ")"
c = a..b
return c
end
macro(500, function()
local lootWorth, wasteWorth, balance = bottingStats()
local balanceDesc, hourDesc = bottingLabels(lootWorth, wasteWorth, balance)
-- hunting
ui.one:setText(sessionTime())
ui.two:setText(format_thousand(expGained()))
ui.three:setText(expPerHour())
ui.four:setText(timeToLevel())
ui.five:setText(format_thousand(burstDamageValue()))
ui.six:setText(format_thousand(totalDmg))
ui.seven:setText(format_thousand(valueInSeconds(dmgTable)))
ui.eight:setText(format_thousand(bestHit))
ui.nine:setText(format_thousand(totalHeal))
ui.ten:setText(format_thousand(valueInSeconds(healTable)))
ui.eleven:setText(format_thousand(bestHeal))
ui.dOne:setText(first)
ui.dTwo:setText(second)
ui.dThree:setText(third)
-- loot
ui2.loot:setText(format_thousand(lootWorth))
ui2.lootHour:setText(format_thousand(hourVal(lootWorth)))
ui2.supplies:setText(format_thousand(wasteWorth))
ui2.suppliesHour:setText(format_thousand(hourVal(wasteWorth)))
ui.balance:setColor(balance >= 0 and "green" or "red")
ui.balance:setText(balanceDesc .. " (" .. hourDesc .. ")")
end)

View File

@ -0,0 +1,367 @@
LootItemLabel < Label
opacity: 0.87
text-offset: 2 0
focusable: false
height: 16
MainAnalyzer < Panel
height: 45
padding: 4
BotButton
id: toggle
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
text: Session Analyzer
BotButton
id: reset
anchors.top: prev.bottom
margin-top: 4
anchors.left: parent.left
anchors.right: parent.horizontalCenter
margin-right: 2
text: Reset
BotButton
id: change
anchors.top: toggle.bottom
margin-top: 4
anchors.left: parent.horizontalCenter
margin-left: 2
anchors.right: toggle.right
text-align: center
text: Loot
HuntingAnalyzer < Panel
height: 275
padding: 5
Label
id: SessionLabel
anchors.top: parent.top
anchors.left: parent.left
text: Session:
Label
id: XpGainLabel
anchors.top: prev.bottom
anchors.left: parent.left
margin-top: 5
text: XP Gain:
Label
id: XpHourLabel
anchors.top: prev.bottom
anchors.left: parent.left
margin-top: 5
text: XP/h:
Label
id: NextLevelLabel
anchors.top: prev.bottom
anchors.left: parent.left
margin-top: 5
text: Next Level:
Label
id: BalanceLabel
anchors.top: prev.bottom
margin-top: 5
anchors.left: parent.left
text: Balance
Label
id: BurstDamageLabel
anchors.top: prev.bottom
anchors.left: parent.left
margin-top: 5
text: Burst Damage:
Label
id: DamageDealtLabel
anchors.top: prev.bottom
anchors.left: parent.left
margin-top: 5
text: Damage Dealt:
Label
id: DPSLabel
anchors.top: prev.bottom
anchors.left: parent.left
margin-top: 5
text: DPS:
Label
id: BestHitLabel
anchors.top: prev.bottom
anchors.left: parent.left
margin-top: 5
text: Best Hit:
Label
id: HealingDoneLabel
anchors.top: prev.bottom
anchors.left: parent.left
margin-top: 5
text: Healing Done:
Label
id: HPSLabel
anchors.top: prev.bottom
anchors.left: parent.left
margin-top: 5
text: HPS:
Label
id: BestHealLabel
anchors.top: prev.bottom
anchors.left: parent.left
margin-top: 5
text: Best Heal:
Label
id: one
anchors.right: parent.right
anchors.verticalCenter: SessionLabel.verticalCenter
text-align: right
text: 00:00h
width: 150
Label
id: two
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 5
text-align: right
text: 0
width: 150
Label
id: three
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 5
text-align: right
text: -
width: 150
Label
id: four
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 5
text-align: right
text: -
width: 150
Label
id: balance
anchors.top: prev.bottom
anchors.right: parent.right
margin-top: 5
text: 0
text-align: right
width: 150
Label
id: five
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 5
text-align: right
text: 0
width: 150
Label
id: six
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 5
text-align: right
text: -
width: 150
Label
id: seven
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 5
text-align: right
text: 0
width: 150
Label
id: eight
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 5
text-align: right
text: 0
width: 150
Label
id: nine
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 5
text-align: right
text: 0
width: 150
Label
id: ten
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 5
text-align: right
text: 0
width: 150
Label
id: eleven
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 5
text-align: right
text: 0
width: 150
HorizontalSeparator
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 3
Label
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 3
text-align: center
text: Damage Distribution
Label
id: dOne
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 5
text-align: center
text: -
Label
id: dTwo
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 5
text-align: center
text: -
Label
id: dThree
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 5
text-align: center
text: -
LootAnalyzer < Panel
height: 275
padding: 4
Label
id: first
anchors.top: parent.top
anchors.left: parent.left
text: Supplies
Label
anchors.top: prev.bottom
margin-top: 5
anchors.left: parent.left
text: Supplies/h
TextList
id: supplyList
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 3
height: 50
vertical-scrollbar: supplyListScrollBar
Label
id: second
anchors.top: prev.bottom
margin-top: 5
anchors.left: parent.left
text: Loot
Label
anchors.top: prev.bottom
margin-top: 5
anchors.left: parent.left
text: Loot/h
Label
id: supplies
anchors.top: parent.top
anchors.right: parent.right
width: 150
text: 0
text-align: right
Label
id: suppliesHour
anchors.top: prev.bottom
anchors.right: parent.right
margin-top: 5
text: 0
text-align: right
width: 150
Label
id: loot
anchors.top: second.top
anchors.right: parent.right
width: 150
text: 0
text-align: right
Label
id: lootHour
anchors.top: prev.bottom
anchors.right: parent.right
margin-top: 5
text: 0
text-align: right
width: 150
TextList
id: List
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 3
height: 120
vertical-scrollbar: ListScrollBar
VerticalScrollBar
id: ListScrollBar
anchors.top: List.top
anchors.bottom: List.bottom
anchors.right: List.right
step: 14
pixels-scroll: true
VerticalScrollBar
id: supplyListScrollBar
anchors.top: supplyList.top
anchors.bottom: supplyList.bottom
anchors.right: supplyList.right
step: 14
pixels-scroll: true

View File

@ -2,7 +2,7 @@
-- visit http://bot.otclient.ovh/
local cavebotTab = "Cave"
local targetingTab = "Target"
local targetingTab = storage.extras.joinBot and "Cave" or "Target"
setDefaultTab(cavebotTab)
CaveBot.Extensions = {}
@ -15,6 +15,7 @@ dofile("/cavebot/editor.lua")
dofile("/cavebot/example_functions.lua")
dofile("/cavebot/recorder.lua")
dofile("/cavebot/walking.lua")
dofile("/cavebot/minimap.lua")
-- in this section you can add extensions, check extension_template.lua
--dofile("/cavebot/extension_template.lua")
dofile("/cavebot/sell_all.lua")
@ -35,6 +36,7 @@ dofile("/cavebot/tasker.lua")
dofile("/cavebot/cavebot.lua")
setDefaultTab(targetingTab)
if storage.extras.joinBot then UI.Label("-- [[ TargetBot ]] --") end
TargetBot = {} -- global namespace
importStyle("/targetbot/looting.otui")
importStyle("/targetbot/target.otui")

View File

@ -94,7 +94,10 @@ addScrollBar("talkDelay", "Global NPC Talk Delay", 0, 2000, 1000, leftPanel)
addScrollBar("looting", "Max Loot Distance", 0, 50, 40, leftPanel)
addScrollBar("huntRoutes", "Hunting Routes Limit", 0, 300, 50, leftPanel)
addScrollBar("killUnder", "Kill monsters below", 0, 100, 30, leftPanel)
addScrollBar("gotoMaxDistance", "Max GoTo Distance", 0, 127, 30, leftPanel)
addCheckBox("lootLast", "Start loot from last corpse", true, leftPanel)
addCheckBox("joinBot", "Join TargetBot and CaveBot", false, leftPanel)
addCheckBox("reachable", "Target only pathable mobs", false, leftPanel)
addCheckBox("title", "Custom Window Title", true, rightPanel)
if true then
@ -123,19 +126,33 @@ if true then
end)
end
addCheckBox("separatePm", "Open PM's in new Window", false, rightPanel)
if true then
onTalk(function(name, level, mode, text, channelId, pos)
if mode == 4 and settings.separatePm then
local g_console = modules.game_console
local privateTab = g_console.getTab(name)
if privateTab == nil then
privateTab = g_console.addTab(name, true)
g_console.addPrivateText(g_console.applyMessagePrefixies(name, level, text), g_console.SpeakTypesSettings['private'], name, false, name)
end
return
end
end)
end
addTextEdit("useAll", "Use All Hotkey", "space", rightPanel)
if true then
local useId = {34847, 1764, 21051, 30823, 6264, 5282, 20453, 20454, 20474, 11708, 11705,
6257, 6256, 2772, 27260, 2773, 1632, 1633, 1948, 435, 6252, 6253, 5007, 4911,
1629, 1630, 5108, 5107, 5281, 1968, 435, 1948, 5542, 31116, 31120, 30742, 31115,
31118, 20474, 5737, 5736, 5734, 5733, 31202, 31228, 31199, 31200, 33262, 30824,
5125, 5126, 5116, 5117, 8257, 8258, 8255, 8256, 5120, 30777, 30776, 23873, 23877,
5736, 6264, 31262, 31130, 31129, 6250, 6249, 5122, 30049}
local shovelId = {606, 593, 867}
local ropeId = {17238, 12202, 12935, 386, 421, 21966, 14238}
local macheteId = {2130, 3696}
local scytheId = {3653}
local useId = { 34847, 1764, 21051, 30823, 6264, 5282, 20453, 20454, 20474, 11708, 11705,
6257, 6256, 2772, 27260, 2773, 1632, 1633, 1948, 435, 6252, 6253, 5007, 4911,
1629, 1630, 5108, 5107, 5281, 1968, 435, 1948, 5542, 31116, 31120, 30742, 31115,
31118, 20474, 5737, 5736, 5734, 5733, 31202, 31228, 31199, 31200, 33262, 30824,
5125, 5126, 5116, 5117, 8257, 8258, 8255, 8256, 5120, 30777, 30776, 23873, 23877,
5736, 6264, 31262, 31130, 31129, 6250, 6249, 5122, 30049, 7131, 7132, 7727 }
local shovelId = { 606, 593, 867 }
local ropeId = { 17238, 12202, 12935, 386, 421, 21966, 14238 }
local macheteId = { 2130, 3696 }
local scytheId = { 3653 }
setDefaultTab("Tools")
-- script
@ -286,7 +303,7 @@ if true then
7719, 6256, 1669, 1672, 5125, 5115, 5124, 17701, 17710, 1642,
6260, 5107, 4912, 6251, 5291, 1683, 1696, 1692, 5006, 2179, 5116,
1632, 11705, 30772, 30774, 6248, 5735, 5732, 5120, 23873, 5736,
6264, 5122, 30049, 30042 }
6264, 5122, 30049, 30042, 7727 }
function checkForDoors(pos)
local tile = g_map.getTile(pos)
@ -373,14 +390,19 @@ if true then
end)
end
addCheckBox("holdMwall", "Hold MW/WG [ , ][ . ]", true, rightPanel)
addCheckBox("holdMwall", "Hold MW/WG", true, rightPanel)
addTextEdit("holdMwHot", "Magic Wall Hotkey: ", "F5", rightPanel)
addTextEdit("holdWgHot", "Wild Growth Hotkey: ", "F6", rightPanel)
if true then
local mwHot = ","
local wgHot = "."
local mwHot
local wgHot
local candidates = {}
local m = macro(20, function()
mwHot = settings.holdMwHot
wgHot = settings.holdWgHot
if not settings.holdMwall then return end
if #candidates == 0 then return end
@ -388,7 +410,7 @@ if true then
if tile:getText():len() == 0 then
table.remove(candidates, i)
end
local rune = tile:getText() == "HOLD MW" and 3180 or 3156
local rune = tile:getText() == "HOLD MW" and 3180 or tile:getText() == "HOLD WG" and 3156
if tile:canShoot() and not isInPz() and tile:isWalkable() and tile:getTopUseThing():getId() ~= 2130 then
return useWith(rune, tile:getTopUseThing())
end
@ -398,9 +420,10 @@ if true then
onRemoveThing(function(tile, thing)
if not settings.holdMwall then return end
if thing:getId() ~= 2129 then return end
if tile:getText():len() > 0 then
if tile:getText():find("HOLD") then
table.insert(candidates, tile)
useWith(3180, tile:getTopUseThing())
local rune = tile:getText() == "HOLD MW" and 3180 or tile:getText() == "HOLD WG" and 3156
useWith(rune, tile:getTopUseThing())
end
end)
@ -439,22 +462,18 @@ end
addCheckBox("checkPlayer", "Check Players", true, rightPanel)
if true then
local found
local function checkPlayers()
local found = false
for i, spec in ipairs(getSpectators()) do
if spec:isPlayer() and spec:getText() == "" and spec:getPosition().z == posz() and spec ~= player then
g_game.look(spec)
found = true
found = now
end
end
if found then
schedule(20, function() modules.game_textmessage.clearMessages() end)
schedule(40, function() modules.game_textmessage.clearMessages() end)
schedule(60, function() modules.game_textmessage.clearMessages() end)
end
end
checkPlayers()
if settings.checkPlayer then
checkPlayers()
end
onPlayerPositionChange(function(x,y)
if not settings.checkPlayer then return end
@ -465,22 +484,15 @@ if true then
onCreatureAppear(function(creature)
if not settings.checkPlayer then return end
local found = false
if creature:isPlayer() and creature:getText() == "" and creature:getPosition().z == posz() and creature ~= player then
g_game.look(creature)
found = true
end
if found then
schedule(20, function() modules.game_textmessage.clearMessages() end)
schedule(40, function() modules.game_textmessage.clearMessages() end)
schedule(60, function() modules.game_textmessage.clearMessages() end)
found = now
end
end)
local regex = [[You see ([a-z 'A-z-]*) \(Level ([0-9]*)\)]]
onTextMessage(function(mode, text)
if not settings.checkPlayer then return end
if mode ~= 20 then return end
local re = regexMatch(text, regex)
if #re ~= 0 then
@ -500,6 +512,9 @@ if true then
if creature then
creature:setText(level..voc)
end
if found and now - found < 500 then
modules.game_textmessage.clearMessages()
end
end
end)
end

View File

@ -39,6 +39,7 @@ ExtrasTextEdit < Panel
minimum: 0
maximum: 10
step: 1
text-align: center
ExtrasItem < Panel
height: 34

View File

@ -1230,5 +1230,38 @@ LootItems = {
["ultimate health potion"] = 379,
["supreme health potion"] = 625,
["great spirit potion"] = 228,
["ultimate spirit potion"] = 438
["ultimate spirit potion"] = 438,
-- runes
["cure poison rune"] = 65,
["poison field rune"] = 21,
["fire field rune"] = 28,
["intense healing rune"] = 95,
["destroy field rune"] = 15,
["energy field rune"] = 38,
["stalagmite rune"] = 12,
["heavy magic missile rune"] = 12,
["disintegrate rune"] = 26,
["ultimate healing rune"] = 175,
["poison bomb rune"] = 85,
["animate death rune"] = 375,
["chameleon rune"] = 210,
["fireball rune"] = 30,
["holy missile rune"] = 16,
["icicle rune"] = 30,
["stone shower rune"] = 37,
["thunderstorm rune"] = 47,
["avalanche rune"] = 57,
["great fireball rune"] = 57,
["convince creature rune"] = 80,
["fire bomb rune"] = 147,
["poison wall rune"] = 52,
["explosion rune"] = 31,
["fire wall rune"] = 61,
["soulfire rune"] = 46,
["wild growth rune"] = 160,
["magic wall rune"] = 116,
["energy wall rune"] = 85,
["energy bomb rune"] = 203,
["sudden death rune"] = 135,
["paralyse rune"] = 700
}

View File

@ -1,3 +1,3 @@
UI.Label("vBot 3.01 \n Vithrax#5814")
UI.Label("vBot v3.4 \n Vithrax#5814")
UI.Button("Official OTCv8 Discord!", function() g_platform.openUrl("https://discord.gg/yhqBE4A") end)
UI.Separator()

View File

@ -24,6 +24,9 @@ local LOCKER_ACCESSTILE_MODIFIERS = {
local function CaveBotConfigParse()
local name = storage["_configs"]["targetbot_configs"]["selected"]
if not name then
return warn("[vBot] Please create a new TargetBot config and reset bot")
end
local file = configDir .. "/targetbot_configs/" .. name .. ".json"
local data = g_resources.readFileContents(file)
return Config.parse(data)['looting']
@ -72,11 +75,13 @@ CaveBot.Status = "waiting"
--- Parses config and extracts loot list.
-- @return table
function CaveBot.GetLootItems()
local t = CaveBotConfigParse()["items"]
local t = CaveBotConfigParse() and CaveBotConfigParse()["items"] or nil
local returnTable = {}
for i, item in pairs(t) do
table.insert(returnTable, item["id"])
if type(t) == "table" then
for i, item in pairs(t) do
table.insert(returnTable, item["id"])
end
end
return returnTable
@ -102,11 +107,13 @@ end
--- Parses config and extracts loot containers.
-- @return table
function CaveBot.GetLootContainers()
local t = CaveBotConfigParse()["containers"]
local t = CaveBotConfigParse() and CaveBotConfigParse()["containers"] or nil
local returnTable = {}
for i, container in pairs(t) do
table.insert(returnTable, container["id"])
if type(t) == "table" then
for i, container in pairs(t) do
table.insert(returnTable, container["id"])
end
end
return returnTable
@ -429,7 +436,7 @@ function CaveBot.WithdrawItem(id, amount, fromDepot, destination)
destination = getContainerByName(destination)
end
local itemCount = itemAmount(id)
test()
local depot
for i, container in pairs(getContainers()) do
if container:getName():lower():find("depot box") or container:getName():lower():find("your inbox") then

View File

@ -93,33 +93,37 @@ Panel
if config.highlight then
creature:setMarked('#0000FF')
end
specOutfit.head = 88
specOutfit.body = 88
specOutfit.legs = 88
specOutfit.feet = 88
if storage.BOTserver.outfit then
local voc = vBot.BotServerMembers[creature:getName()]
specOutfit.addons = 3
if voc == 1 then
specOutfit.type = 131
elseif voc == 2 then
specOutfit.type = 129
elseif voc == 3 then
specOutfit.type = 130
elseif voc == 4 then
specOutfit.type = 144
if config.outfits then
specOutfit.head = 88
specOutfit.body = 88
specOutfit.legs = 88
specOutfit.feet = 88
if storage.BOTserver.outfit then
local voc = vBot.BotServerMembers[creature:getName()]
specOutfit.addons = 3
if voc == 1 then
specOutfit.type = 131
elseif voc == 2 then
specOutfit.type = 129
elseif voc == 3 then
specOutfit.type = 130
elseif voc == 4 then
specOutfit.type = 144
end
end
creature:setOutfit(specOutfit)
end
creature:setOutfit(specOutfit)
elseif isEnemy(specName) then
if config.highlight then
creature:setMarked('#FF0000')
end
specOutfit.head = 94
specOutfit.body = 94
specOutfit.legs = 94
specOutfit.feet = 94
creature:setOutfit(specOutfit)
if config.outfits then
specOutfit.head = 94
specOutfit.body = 94
specOutfit.legs = 94
specOutfit.feet = 94
creature:setOutfit(specOutfit)
end
end
end

View File

@ -1,15 +1,18 @@
-- tools tab
setDefaultTab("Tools")
local moneyIds = {3031, 3035} -- gold coin, platinium coin
if type(storage.moneyItems) ~= "table" then
storage.moneyItems = {3031, 3035}
end
macro(1000, "Exchange money", function()
if not storage.moneyItems[1] then return end
local containers = g_game.getContainers()
for index, container in pairs(containers) do
if not container.lootContainer then -- ignore monster containers
for i, item in ipairs(container:getItems()) do
if item:getCount() == 100 then
for m, moneyId in ipairs(moneyIds) do
if item:getId() == moneyId then
for m, moneyId in ipairs(storage.moneyItems) do
if item:getId() == moneyId.id then
return g_game.use(item)
end
end
@ -19,6 +22,12 @@ macro(1000, "Exchange money", function()
end
end)
local moneyContainer = UI.Container(function(widget, items)
storage.moneyItems = items
end, true)
moneyContainer:setHeight(35)
moneyContainer:setItems(storage.moneyItems)
UI.Separator()
macro(60000, "Send message on trade", function()

View File

@ -14,8 +14,6 @@ vBot.isUsingPotion = false
vBot.isUsing = false
-- scripts / functions
onPlayerPositionChange(function(x,y)
vBot.standTime = now
@ -64,6 +62,10 @@ function whiteInfoMessage(text)
return modules.game_textmessage.displayGameMessage(text)
end
function statusMessage(text, logInConsole)
return not logInConsole and modules.game_textmessage.displayFailureMessage(text) or modules.game_textmessage.displayStatusMessage(text)
end
-- same as above but red message
function broadcastMessage(text)
return modules.game_textmessage.displayBroadcastMessage(text)
@ -150,19 +152,34 @@ function containerIsFull(c)
end
function dropItem(idOrObject)
if type(idOrObject) == "number" then
idOrObject = findItem(idOrObject)
end
g_game.move(idOrObject, pos(), idOrObject:getCount())
end
-- not perfect function to return whether character has utito tempo buff
-- known to be bugged if received debuff (ie. roshamuul)
-- TODO: simply a better version
-- returns boolean
function isBuffed()
local var = false
if not hasPartyBuff() then return var end
local skillId = 0
for i = 1, 4 do
local premium = (player:getSkillLevel(i) - player:getSkillBaseLevel(i))
local base = player:getSkillBaseLevel(i)
if hasPartyBuff() and (premium / 100) * 305 > base then
var = true
if player:getSkillBaseLevel(i) > player:getSkillBaseLevel(skillId) then
skillId = i
end
end
local premium = (player:getSkillLevel(skillId) - player:getSkillBaseLevel(skillId))
local base = player:getSkillBaseLevel(skillId)
if (premium / 100) * 305 > base then
var = true
end
return var
end
@ -361,7 +378,7 @@ function isFriend(c)
if p:isLocalPlayer() then return true end
if p:isPlayer() then
if ((p:getShield() >= 3 and p:getShield() <= 10) or p:getEmblem() ==
2) then
1) then
CachedFriends[c] = true
CachedFriends[p] = true
return true
@ -391,7 +408,7 @@ function isEnemy(c)
if p:isLocalPlayer() then return end
if p:isPlayer() and table.find(storage.playerList.enemyList, name) or
(storage.playerList.marks and not isFriend(name)) then
(storage.playerList.marks and not isFriend(name)) or p:getEmblem() == 2 then
return true
else
return false
@ -673,35 +690,10 @@ function itemAmount(id)
end
end
end
if getHead() and getHead():getId() == id then
totalItemCount = totalItemCount + getHead():getCount()
end
if getNeck() and getNeck():getId() == id then
totalItemCount = totalItemCount + getNeck():getCount()
end
if getBack() and getBack():getId() == id then
totalItemCount = totalItemCount + getBack():getCount()
end
if getBody() and getBody():getId() == id then
totalItemCount = totalItemCount + getBody():getCount()
end
if getRight() and getRight():getId() == id then
totalItemCount = totalItemCount + getRight():getCount()
end
if getLeft() and getLeft():getId() == id then
totalItemCount = totalItemCount + getLeft():getCount()
end
if getLeg() and getLeg():getId() == id then
totalItemCount = totalItemCount + getLeg():getCount()
end
if getFeet() and getFeet():getId() == id then
totalItemCount = totalItemCount + getFeet():getCount()
end
if getFinger() and getFinger():getId() == id then
totalItemCount = totalItemCount + getFinger():getCount()
end
if getAmmo() and getAmmo():getId() == id then
totalItemCount = totalItemCount + getAmmo():getCount()
local slots = {getHead(), getNeck(), getBack(), getBody(), getRight(), getLeft(), getLeg(), getFeet(), getFinger(), getAmmo()}
for i, slot in pairs(slots) do
totalItemCount = slot and slot:getId() == id and totalItemCount + 1 or totalItemCount
end
return totalItemCount
end
@ -940,7 +932,7 @@ function getBestTileByPatern(pattern, specType, maxDist, safe)
if distanceFromPlayer(tile:getPosition()) <= maxDist then
local minimapColor = g_map.getMinimapColor(tile:getPosition())
local stairs = (minimapColor >= 210 and minimapColor <= 213)
if tile:canShoot() and tile:isWalkable() and not stairs then
if tile:canShoot() and tile:isWalkable() then
if getCreaturesInArea(tile:getPosition(), pattern, specType) > 0 then
if (not safe or
getCreaturesInArea(tile:getPosition(), pattern, 3) == 0) then
@ -969,12 +961,12 @@ function getBestTileByPatern(pattern, specType, maxDist, safe)
end
-- returns container object based on name
function getContainerByName(name)
function getContainerByName(name, notFull)
if type(name) ~= "string" then return nil end
local d = nil
for i, c in pairs(getContainers()) do
if c:getName():lower() == name:lower() then
if c:getName():lower() == name:lower() and (not notFull or not containerIsFull(c)) then
d = c
break
end
@ -983,12 +975,12 @@ function getContainerByName(name)
end
-- returns container object based on container ID
function getContainerByItem(id)
function getContainerByItem(id, notFull)
if type(id) ~= "number" then return nil end
local d = nil
for i, c in pairs(getContainers()) do
if c:getContainerItem():getId() == id then
if c:getContainerItem():getId() == id and (not notFull or not containerIsFull(c)) then
d = c
break
end

View File

@ -56,8 +56,8 @@ local function parseMarketEnter(protocol, msg)
end
local balance = 0
if g_game.getClientVersion() <= 1250 or not g_game.getFeature(GameTibia12Protocol) then
if g_game.getClientVersion() >= 981 or g_game.getClientVersion() < 944 then
if g_game.getProtocolVersion() <= 1250 or not g_game.getFeature(GameTibia12Protocol) then
if g_game.getProtocolVersion() >= 981 or g_game.getProtocolVersion() < 944 then
balance = msg:getU64()
else
balance = msg:getU32()
@ -65,7 +65,7 @@ local function parseMarketEnter(protocol, msg)
end
local vocation = -1
if g_game.getClientVersion() >= 944 and g_game.getClientVersion() < 950 then
if g_game.getProtocolVersion() >= 944 and g_game.getProtocolVersion() < 950 then
vocation = msg:getU8() -- get vocation id
end
local offers = msg:getU8()
@ -100,7 +100,7 @@ local function parseMarketDetail(protocol, msg)
end
end
if g_game.getClientVersion() >= 1100 then -- imbuements
if g_game.getProtocolVersion() >= 1100 then -- imbuements
if msg:peekU16() ~= 0x00 then
table.insert(descriptions, {MarketItemDescription.Last + 1, msg:getString()})
else

View File

@ -124,7 +124,7 @@ function registerProtocol()
registerOpcode(ServerPackets.Inspection, function(protocol, msg)
local bool = msg:getU8() -- IsPlayer
if g_game.getClientVersion() >= 1230 then
if g_game.getProtocolVersion() >= 1230 then
msg:getU8()
end
local size = msg:getU8() -- List
@ -209,7 +209,7 @@ function registerProtocol()
registerOpcode(ServerPackets.CyclopediaCharacterInfo, function(protocol, msg)
local type = msg:getU8()
if g_game.getClientVersion() >= 1215 then
if g_game.getProtocolVersion() >= 1215 then
local error = msg:getU8()
if error > 0 then
-- [1] 'No data available at the moment.'
@ -232,7 +232,7 @@ function registerProtocol()
msg:getU16() -- lookTypeEx
end
msg:getU8() -- Hide stamina
if g_game.getClientVersion() >= 1220 then
if g_game.getProtocolVersion() >= 1220 then
msg:getU8() -- Personal habs
msg:getString() -- Title
end
@ -268,7 +268,7 @@ function registerProtocol()
msg:getU16() -- Base skill
msg:getU16() -- Skill percent
end
if g_game.getClientVersion() < 1215 then
if g_game.getProtocolVersion() < 1215 then
msg:getU16()
msg:getString() -- Player name
msg:getString() -- Vocation
@ -369,7 +369,7 @@ function registerProtocol()
msg:getU8() -- Category 0 = Standard, 1 = Quest, 2 = Store
msg:getU32() -- Is current ? then 1000 or 0
end
if g_game.getClientVersion() >= 1260 then
if g_game.getProtocolVersion() >= 1260 then
msg:getU8() -- Mount lookHead
msg:getU8() -- Mount lookBody
msg:getU8() -- Mount lookLegs
@ -532,7 +532,7 @@ function registerProtocol()
msg:getU8() -- Is updating
msg:getU32() -- Normal coin
msg:getU32() -- Transferable coin
if g_game.getClientVersion() >= 1220 then
if g_game.getProtocolVersion() >= 1220 then
msg:getU32() -- Reserved auction coin
msg:getU32() -- Tournament coin
end
@ -652,17 +652,17 @@ end
function readAddItem(msg)
msg:getU16() -- Item client ID
if g_game.getClientVersion() < 1150 then
if g_game.getProtocolVersion() < 1150 then
msg:getU8() -- Unmarked
end
local var = msg:getU8()
if g_game.getClientVersion() > 1150 then
if g_game.getProtocolVersion() > 1150 then
if var == 1 then
msg:getU32() -- Loot flag
end
if g_game.getClientVersion() >= 1260 then
if g_game.getProtocolVersion() >= 1260 then
local isQuiver = msg:getU8()
if isQuiver == 1 then
msg:getU32() -- Quiver count

View File

@ -206,6 +206,8 @@ GameMapIgnoreCorpseCorrection = 117
GameDontCacheFiles = 118 -- doesn't work with encryption and compression
GameBigAurasCenter = 119 -- Automatic negative offset for aura bigger than 32x32
GameNewUpdateWalk = 120 -- Walk update rate dependant on FPS
GameNewCreatureStacking = 121 -- Ignore MAX_THINGS limit while adding to tile
GameCreaturesMana = 122 -- get mana from server for creatures other than Player
LastGameFeature = 130

View File

@ -110,7 +110,7 @@ function ProtocolLogin:sendLoginPacket()
msg:addU8(1) --unknown
msg:addU8(1) --unknown
if g_game.getClientVersion() >= 1072 then
if g_game.getProtocolVersion() >= 1072 then
msg:addString(string.format('%s %s', g_graphics.getVendor(), g_graphics.getRenderer()))
else
msg:addString(g_graphics.getRenderer())
@ -221,7 +221,7 @@ end
function ProtocolLogin:parseCharacterList(msg)
local characters = {}
if g_game.getClientVersion() > 1010 then
if g_game.getProtocolVersion() > 1010 then
local worlds = {}
local worldsCount = msg:getU8()

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.