Updated to OTCv8 3.1 rev 112

This commit is contained in:
OTCv8
2021-11-25 23:32:26 +00:00
parent dbe70e787a
commit bbcb7c2168
228 changed files with 3376 additions and 12584 deletions

View File

@@ -103,6 +103,13 @@ function clear()
widget:destroy()
end
end
for _, widget in pairs({modules.game_interface.getRightPanel(), modules.game_interface.getLeftPanel()}) do
for i, child in pairs(widget:getChildren()) do
if child.botWidget then
child:destroy()
end
end
end
local gameMapPanel = modules.game_interface.getMapPanel()
if gameMapPanel then
@@ -478,6 +485,11 @@ function initCallbacks()
onImbuementWindow = botImbuementWindow,
onModalDialog = botModalDialog,
onAttackingCreatureChange = botAttackingCreatureChange,
onAddItem = botContainerAddItem,
onRemoveItem = botContainerRemoveItem,
onGameEditText = botGameEditText,
onSpellCooldown = botSpellCooldown,
onSpellGroupCooldown = botGroupSpellCooldown
})
connect(Tile, {
@@ -508,6 +520,7 @@ function initCallbacks()
onClose = botContainerClose,
onUpdateItem = botContainerUpdateItem,
onAddItem = botContainerAddItem,
onRemoveItem = botContainerRemoveItem,
})
connect(g_map, {
@@ -536,7 +549,10 @@ function terminateCallbacks()
onChannelEvent = botChannelEvent,
onImbuementWindow = botImbuementWindow,
onModalDialog = botModalDialog,
onAttackingCreatureChange = botAttackingCreatureChange
onAttackingCreatureChange = botAttackingCreatureChange,
onGameEditText = botGameEditText,
onSpellCooldown = botSpellCooldown,
onSpellGroupCooldown = botGroupSpellCooldown
})
disconnect(Tile, {
@@ -567,6 +583,7 @@ function terminateCallbacks()
onClose = botContainerClose,
onUpdateItem = botContainerUpdateItem,
onAddItem = botContainerAddItem,
onRemoveItem = botContainerRemoveItem
})
disconnect(g_map, {
@@ -726,6 +743,11 @@ function botModalDialog(id, title, message, buttons, enterButton, escapeButton,
safeBotCall(function() botExecutor.callbacks.onModalDialog(id, title, message, buttons, enterButton, escapeButton, choices, priority) end)
end
function botGameEditText(id, itemId, maxLength, text, writer, time)
if botExecutor == nil then return false end
safeBotCall(function() botExecutor.callbacks.onGameEditText(id, itemId, maxLength, text, writer, time) end)
end
function botAttackingCreatureChange(creature, oldCreature)
if botExecutor == nil then return false end
safeBotCall(function() botExecutor.callbacks.onAttackingCreatureChange(creature,oldCreature) end)
@@ -741,7 +763,22 @@ function botStatesChange(states, oldStates)
safeBotCall(function() botExecutor.callbacks.onStatesChange(states, oldStates) end)
end
function botContainerAddItem(container, slot, item)
function botContainerAddItem(container, slot, item, oldItem)
if botExecutor == nil then return false end
safeBotCall(function() botExecutor.callbacks.onAddItem(container, slot, item) end)
safeBotCall(function() botExecutor.callbacks.onAddItem(container, slot, item, oldItem) end)
end
function botContainerRemoveItem(container, slot, item)
if botExecutor == nil then return false end
safeBotCall(function() botExecutor.callbacks.onRemoveItem(container, slot, item) end)
end
function botSpellCooldown(iconId, duration)
if botExecutor == nil then return false end
safeBotCall(function() botExecutor.callbacks.onSpellCooldown(iconId, duration) end)
end
function botGroupSpellCooldown(iconId, duration)
if botExecutor == nil then return false end
safeBotCall(function() botExecutor.callbacks.onGroupSpellCooldown(iconId, duration) end)
end

View File

@@ -1,105 +0,0 @@
AlarmsWindow < MainWindow
!text: tr('Alarms')
size: 270 200
@onEscape: self:hide()
BotSwitch
id: playerAttack
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
text-align: center
text: Player Attack
BotSwitch
id: playerDetected
anchors.left: parent.left
anchors.right: parent.horizontalCenter
anchors.top: prev.bottom
margin-top: 4
text-align: center
text: Player Detected
CheckBox
id: playerDetectedLogout
anchors.top: playerDetected.top
anchors.left: parent.horizontalCenter
anchors.right: parent.right
margin-top: 3
margin-left: 4
text: Logout
BotSwitch
id: creatureDetected
anchors.left: parent.left
anchors.right: parent.right
anchors.top: playerDetected.bottom
margin-top: 4
text-align: center
text: Creature Detected
BotSwitch
id: healthBelow
anchors.left: parent.left
anchors.top: prev.bottom
anchors.right: parent.horizontalCenter
text-align: center
margin-top: 4
text: Health < 50%
HorizontalScrollBar
id: healthValue
anchors.left: parent.horizontalCenter
anchors.right: parent.right
anchors.top: healthBelow.top
margin-left: 3
margin-top: 2
minimum: 1
maximum: 100
step: 1
BotSwitch
id: manaBelow
anchors.left: parent.left
anchors.top: healthBelow.bottom
anchors.right: parent.horizontalCenter
text-align: center
margin-top: 4
text: Mana < 50%
HorizontalScrollBar
id: manaValue
anchors.left: parent.horizontalCenter
anchors.right: parent.right
anchors.top: manaBelow.top
margin-left: 3
margin-top: 2
minimum: 1
maximum: 100
step: 1
BotSwitch
id: privateMessage
anchors.left: parent.left
anchors.top: manaBelow.bottom
anchors.right: parent.right
text-align: center
margin-top: 4
text: Private Message
HorizontalSeparator
id: separator
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

@@ -1,437 +0,0 @@
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

@@ -1,367 +0,0 @@
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

@@ -167,7 +167,7 @@ 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, maxDist, { ignoreNonPathable = true, precision = 1, ignoreCreatures = true })
local path = findPath(playerPos, pos, maxDist, { ignoreNonPathable = true, precision = 1, ignoreCreatures = true, allowUnseen = true, allowOnlyVisibleTiles = false })
if not path then
return false -- there's no way
end
@@ -206,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, maxDist, { ignoreNonPathable = true }) then
if CaveBot.walkTo(pos, maxDist, { ignoreNonPathable = true, allowUnseen = true, allowOnlyVisibleTiles = false }) then
return "retry"
end
@@ -216,7 +216,7 @@ CaveBot.registerAction("goto", "green", function(value, retries, prev)
if stairs then
precison = 0
end
if CaveBot.walkTo(pos, 50, { ignoreNonPathable = true, precision = precison }) then
if CaveBot.walkTo(pos, 50, { ignoreNonPathable = true, precision = precison, allowUnseen = true, allowOnlyVisibleTiles = false }) then
return "retry"
end
end
@@ -230,7 +230,7 @@ CaveBot.registerAction("goto", "green", function(value, retries, prev)
end
-- everything else failed, try to walk ignoring creatures, maybe will work
CaveBot.walkTo(pos, maxDist, { ignoreNonPathable = true, precision = 1, ignoreCreatures = true })
CaveBot.walkTo(pos, maxDist, { ignoreNonPathable = true, precision = 1, ignoreCreatures = true, allowUnseen = true, allowOnlyVisibleTiles = false })
return "retry"
end)

View File

@@ -30,7 +30,7 @@ cavebotMacro = macro(20, function()
end
if CaveBot.doWalking() then
return -- executing walking
return -- executing walking3
end
local actions = ui.list:getChildCount()
@@ -185,6 +185,20 @@ CaveBot.setOff = function(val)
config.setOff()
end
CaveBot.getCurrentProfile = function()
return storage._configs.cavebot_configs.selected
end
local botConfigName = modules.game_bot.contentsPanel.config:getCurrentOption().text
CaveBot.setCurrentProfile = function(name)
if not g_resources.fileExists("/bot/"..botConfigName.."/cavebot_configs/"..name..".cfg") then
return warn("there is no cavebot profile with that name!")
end
CaveBot.setOff()
storage._configs.cavebot_configs.selected = name
CaveBot.setOn()
end
CaveBot.delay = function(value)
cavebotMacro.delay = math.max(cavebotMacro.delay or 0, now + value)
end

View File

@@ -1,13 +1,11 @@
CaveBot.Extensions.Depositor = {}
--local variables
local closedContainers = false
local reopenedContainers = false
local destination = nil
local lootTable = nil
local reopenedContainers = false
local function resetCache()
closedContainers = false
reopenedContainers = false
destination = nil
lootTable = nil
@@ -41,21 +39,11 @@ CaveBot.Extensions.Depositor.setup = function()
-- backpacks etc
if value:lower() == "yes" then
-- reopening backpacks
if not reopenedContainers then
if not closedContainers then
if not CaveBot.CloseLootContainer() then
return "retry"
else
closedContainers = true
end
else
if not CaveBot.OpenLootContainer() then
return "retry"
else
reopenedContainers = true
end
end
CaveBot.CloseAllLootContainers()
delay(3000)
reopenedContainers = true
return "retry"
end
-- open next backpacks if no more loot
if not CaveBot.HasLootItems() then
@@ -70,12 +58,14 @@ CaveBot.Extensions.Depositor.setup = function()
return "retry"
end
end
-- couldn't find next container, so we done
print("CaveBot[Depositor]: all items stashed, no backpack to open next, proceeding")
resetCache()
return true
end
end
-- couldn't find next container, so we done
print("CaveBot[Depositor]: all items stashed, no backpack to open next, proceeding")
CaveBot.CloseAllLootContainers()
delay(3000)
resetCache()
return true
end
end

View File

@@ -35,7 +35,7 @@ end
]])
addExampleFunction("Check for stamina and imbues", [[
if stamina() < 900 or player:getSkillLevel(11) ~= 100 then CaveBot.setOff() return false else return true end
if stamina() < 900 or player:getSkillLevel(11) == 0 then CaveBot.setOff() return false else return true end
]])
addExampleFunction("buy 200 mana potion from npc Eryn", [[
@@ -105,4 +105,10 @@ addExampleFunction("Logout", [[
g_game.safeLogout()
delay(1000)
return "retry"
]])
addExampleFunction("Close Loot Containers", [[
CaveBot.CloseAllLootContainers()
delay(3000)
return true
]])

View File

@@ -5,6 +5,7 @@ local lureMax = 0
local anchorPosition = nil
local lastCall = now
local delayFrom = nil
local dynamicLureDelay = false
function getWalkableTilesCount(position)
local count = 0
@@ -140,6 +141,7 @@ TargetBot.Creature.walk = function(creature, config, targets)
lureMax = config.lureMax
end
dynamicLureDelay = config.dynamicLureDelay
delayFrom = config.delayFrom
-- luring
@@ -185,6 +187,7 @@ TargetBot.Creature.walk = function(creature, config, targets)
end
end
--target only movement
if config.avoidAttacks then
local diffx = cpos.x - pos.x
local diffy = cpos.y - pos.y
@@ -235,6 +238,6 @@ onPlayerPositionChange(function(newPos, oldPos)
if not lureMax then return end
if storage.TargetBotDelayWhenPlayer then return end
if targetCount < (delayFrom or lureMax/2) or not target() then return end
if dynamicLureDelay and targetCount < (delayFrom or lureMax/2) or not target() then return end
CaveBot.delay(delayValue or 0)
end)

View File

@@ -203,6 +203,20 @@ TargetBot.setOff = function(val)
config.setOff()
end
TargetBot.getCurrentProfile = function()
return storage._configs.targetbot_configs.selected
end
local botConfigName = modules.game_bot.contentsPanel.config:getCurrentOption().text
TargetBot.setCurrentProfile = function(name)
if not g_resources.fileExists("/bot/"..botConfigName.."/targetbot_configs/"..name..".json") then
return warn("there is no targetbot profile with that name!")
end
TargetBot.setOff()
storage._configs.targetbot_configs.selected = name
TargetBot.setOn()
end
TargetBot.delay = function(value)
targetbotMacro.delay = now + value
end

View File

@@ -1075,7 +1075,7 @@ function getBestTileByPattern(pattern, minHp, maxHp, safePattern, monsterNamesTa
for i, tile in pairs(tiles) do
local tPos = tile:getPosition()
local distance = distanceFromPlayer(tPos)
if tile:canShoot() and tile:isWalkable() and (not safePattern or distance < 4) then
if tile:canShoot() and tile:isWalkable() and distance < 4 then
local amount = getMonstersInArea(2, tPos, pattern, minHp, maxHp, safePattern, monsterNamesTable)
if amount > targetTile.amount then
targetTile = {amount=amount,pos=tPos}
@@ -1161,7 +1161,7 @@ macro(100, function()
if entry.enabled and manapercent() >= entry.mana then
if (entry.spell and canCast(entry.spell, not currentSettings.ignoreMana, not currentSettings.Cooldown)) or (entry.itemId > 100 and (not currentSettings.Visible or findItem(entry.itemId))) then
-- first PVP scenario
if currentSettings.pvpMode and target():getHealthPercent() >= entry.minHp and target():getHealthPercent() <= entry.maxHp then
if currentSettings.pvpMode and target():getHealthPercent() >= entry.minHp and target():getHealthPercent() <= entry.maxHp and target():canShoot() then
if entry.category == 2 then
return warn("[AttackBot] Area Runes cannot be used in PVP situation!")
else
@@ -1186,7 +1186,7 @@ macro(100, function()
local anchorParam = (pattern == 2 or pattern == 6 or pattern == 7 or pattern > 9) and player or pos()
local safe = currentSettings.PvpSafe and spellPatterns[pCat][entry.pattern][2] or false
local monsterAmount = pCat ~= 8 and getMonstersInArea(entry.category, anchorParam, spellPatterns[pCat][entry.pattern][1], entry.minHp, entry.maxHp, safe, entry.monsters)
if (pattern ~= 8 and (entry.orMore and monsterAmount >= entry.count or not entry.orMore and monsterAmount == entry.count)) or pattern == 8 and bestSide >= entry.count then
if (pattern ~= 8 and (entry.orMore and monsterAmount >= entry.count or not entry.orMore and monsterAmount == entry.count)) or (pattern == 8 and bestSide >= entry.count and (not currentSettings.PvpSafe or getPlayers(2) == 0)) then
return executeAttackBotAction(entry.category, attackData, entry.cooldown)
end
elseif entry.category == 2 then

View File

@@ -235,7 +235,7 @@ Panel
elseif config.cureElectrify and mana() >= config.electrifyCost and isEnergized() then say("exana vis")
end
end
if (not config.ignoreInPz or not isInPz()) and config.holdUtura and mana() >= config.uturaCost and not hasPartyBuff() then say(config.uturaType)
if (not config.ignoreInPz or not isInPz()) and config.holdUtura and mana() >= config.uturaCost and canCast(config.uturaType) and hppercent() < 90 then say(config.uturaType)
elseif (not config.ignoreInPz or not isInPz()) and config.holdUtana and mana() >= config.utanaCost and (not utanaCast or (now - utanaCast > 120000)) then say("utana vid") utanaCast = now
end
end)

View File

@@ -441,19 +441,19 @@ end
onContainerOpen(function(container, previousContainer)
if renameContui.title:isOn() then
if not container.window then return end
local containerWindow = container.window
if not previousContainer then
if not container.window then return end
containerWindow = container.window
containerWindow:setContentHeight(34)
local storageVal = config.list
if storageVal and #storageVal > 0 then
for _, entry in pairs(storageVal) do
if entry.enabled and string.find(container:getContainerItem():getId(), entry.item) then
if entry.min then
containerWindow:minimize()
end
containerWindow:setText(entry.value)
end
local storageVal = config.list
if storageVal and #storageVal > 0 then
for _, entry in pairs(storageVal) do
if entry.enabled and string.find(container:getContainerItem():getId(), entry.item) then
if entry.min then
containerWindow:minimize()
end
containerWindow:setText(entry.value)
end
end
end
@@ -476,7 +476,7 @@ local function properTable(t)
return r
end
macro(100, function()
macro(500, function()
if not config.sort and not config.purse then return end
local storageVal = config.list
@@ -522,5 +522,5 @@ macro(100, function()
if config.purse and config.forceOpen and not getContainerByItem(23396) then
return use(getPurse())
end
delay(900)
delay(1500)
end)

View File

@@ -1,3 +1,6 @@
local standBySpells = false
local standByItems = false
setDefaultTab("HP")
healPanelName = "healbot"
local ui = setupUI([[
@@ -222,10 +225,14 @@ if rootWidget then
local label = UI.createWidget("SpellEntry", healWindow.spells.spellList)
label.enabled:setChecked(entry.enabled)
label.enabled.onClick = function(widget)
standBySpells = false
standByItems = false
entry.enabled = not entry.enabled
label.enabled:setChecked(entry.enabled)
end
label.remove.onClick = function(widget)
standBySpells = false
standByItems = false
table.removevalue(currentSettings.spellTable, entry)
reindexTable(currentSettings.spellTable)
label:destroy()
@@ -245,10 +252,14 @@ if rootWidget then
local label = UI.createWidget("SpellEntry", healWindow.items.itemList)
label.enabled:setChecked(entry.enabled)
label.enabled.onClick = function(widget)
standBySpells = false
standByItems = false
entry.enabled = not entry.enabled
label.enabled:setChecked(entry.enabled)
end
label.remove.onClick = function(widget)
standBySpells = false
standByItems = false
table.removevalue(currentSettings.itemTable, entry)
reindexTable(currentSettings.itemTable)
label:destroy()
@@ -414,6 +425,8 @@ if rootWidget then
healWindow.spells.spellValue:setText('')
healWindow.spells.manaCost:setText('')
end
standBySpells = false
standByItems = false
refreshSpells()
end
@@ -455,6 +468,8 @@ if rootWidget then
if id > 100 then
table.insert(currentSettings.itemTable, {index = #currentSettings.itemTable+1,item = id, sign = equasion, origin = source, value = trigger, enabled = true})
standBySpells = false
standByItems = false
refreshItems()
healWindow.items.itemId:setItemId(0)
healWindow.items.itemValue:setText('')
@@ -554,9 +569,6 @@ if rootWidget then
end
-- spells
local lastMana = mana()
local standBySpells = false
local iterationsSpells = 0
macro(100, function()
if standBySpells then return end
if not currentSettings.enabled or modules.game_cooldown.isGroupCooldownIconActive(2) or #currentSettings.spellTable == 0 then return end
@@ -625,7 +637,6 @@ macro(100, function()
end)
-- items
local standByItems = false
macro(100, function()
if standByItems then return end
if not currentSettings.enabled or #currentSettings.itemTable == 0 then return end

View File

@@ -34,10 +34,15 @@ if not storage[panelName] then
healthValue = 40,
manaBelow = false,
manaValue = 50,
privateMessage = false
privateMessage = false,
ignoreFriends = true,
warnBoss = false,
bossName = '[B]'
}
end
local config = storage[panelName]
ui.title:setOn(config.enabled)
@@ -46,6 +51,10 @@ config.enabled = not config.enabled
widget:setOn(config.enabled)
end
-- new var's validation
config.messageText = config.messageText or ""
config.bossName = config.bossName or ""
rootWidget = g_ui.getRootWidget()
if rootWidget then
alarmsWindow = UI.createWindow('AlarmsWindow', rootWidget)
@@ -109,11 +118,57 @@ if rootWidget then
widget:setOn(config.privateMessage)
end
alarmsWindow.ignoreFriends:setOn(config.ignoreFriends)
alarmsWindow.ignoreFriends.onClick = function(widget)
config.ignoreFriends = not config.ignoreFriends
widget:setOn(config.ignoreFriends)
end
alarmsWindow.warnBoss:setOn(config.warnBoss)
alarmsWindow.warnBoss.onClick = function(widget)
config.warnBoss = not config.warnBoss
widget:setOn(config.warnBoss)
end
alarmsWindow.bossName:setText(config.bossName)
alarmsWindow.bossName.onTextChange = function(widget, text)
config.bossName = text
end
alarmsWindow.warnMessage:setOn(config.warnMessage)
alarmsWindow.warnMessage.onClick = function(widget)
config.warnMessage = not config.warnMessage
widget:setOn(config.warnMessage)
end
alarmsWindow.messageText:setText(config.messageText)
alarmsWindow.messageText.onTextChange = function(widget, text)
config.messageText = text
end
local pName = player:getName()
onTextMessage(function(mode, text)
if config.enabled and config.playerAttack and mode == 16 and string.match(text, "hitpoints due to an attack") and not string.match(text, "hitpoints due to an attack by a ") then
if config.enabled and config.playerAttack and string.match(text, "hitpoints due to an attack") and not string.match(text, "hitpoints due to an attack by a ") then
playSound("/sounds/Player_Attack.ogg")
g_window.setTitle(pName .. " - Player Detected!")
g_window.setTitle(pName .. " - Player Attacks!")
return
end
if config.warnMessage and config.messageText:len() > 0 then
text = text:lower()
local parts = string.split(config.messageText, ",")
for i=1,#parts do
local part = parts[i]
part = part:trim()
part = part:lower()
if text:find(part) then
delay(1500)
playSound(g_resources.fileExists("/sounds/Special_Message.ogg") and "/sounds/Special_Message.ogg" or "/sounds/Private_Message.ogg")
g_window.setTitle(pName .. " - Special Message Detected: "..part)
return
end
end
end
end)
@@ -121,14 +176,15 @@ if rootWidget then
if not config.enabled then
return
end
local specs = getSpectators()
if config.playerDetected then
for _, spec in ipairs(getSpectators()) do
for _, spec in ipairs(specs) do
if spec:isPlayer() and spec:getName() ~= name() then
specPos = spec:getPosition()
if math.max(math.abs(posx()-specPos.x), math.abs(posy()-specPos.y)) <= 8 then
local specPos = spec:getPosition()
if (not config.ignoreFriends or not isFriend(spec)) and math.max(math.abs(posx()-specPos.x), math.abs(posy()-specPos.y)) <= 8 then
playSound("/sounds/Player_Detected.ogg")
delay(1500)
g_window.setTitle(pName .. " - Player Detected!")
g_window.setTitle(pName .. " - Player Detected! "..spec:getName())
if config.playerDetectedLogout then
modules.game_interface.tryLogout(false)
end
@@ -139,24 +195,53 @@ if rootWidget then
end
if config.creatureDetected then
for _, spec in ipairs(getSpectators()) do
if not spec:isPlayer()then
specPos = spec:getPosition()
for _, spec in ipairs(specs) do
if not spec:isPlayer() then
local specPos = spec:getPosition()
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(pName .. " - Creature Detected! ")
g_window.setTitle(pName .. " - Creature Detected! "..spec:getName())
return
end
end
end
end
if config.warnBoss then
-- experimental, but since we check only names i think the best way would be to combine all spec's names into one string and then check it to avoid multiple loops
if config.bossName:len() > 0 then
local names = string.split(config.bossName, ",")
local combinedString = ""
for _, spec in ipairs(specs) do
local specPos = spec:getPosition()
if math.max(math.abs(posx() - specPos.x), math.abs(posy() - specPos.y)) <= 8 then
local name = spec:getName():lower()
-- add special sign between names to avoid unwanted combining mistakes
combinedString = combinedString .."&"..name
end
end
for i=1,#names do
local name = names[i]
name = name:trim()
name = name:lower()
if combinedString:find(name) then
playSound(g_resources.fileExists("/sounds/Special_Creature.ogg") and "/sounds/Special_Creature.ogg" or "/sounds/Creature_Detected.ogg")
delay(1500)
g_window.setTitle(pName .. " - Special Creature Detected: "..name)
return
end
end
end
end
if config.healthBelow then
if hppercent() <= config.healthValue then
playSound("/sounds/Low_Health.ogg")
g_window.setTitle(pName .. " - Low Health!")
delay(1500)
g_window.setTitle(pName .. " - Low Health! only: "..hppercent().."%")
return
end
end
@@ -164,8 +249,8 @@ if rootWidget then
if config.manaBelow then
if manapercent() <= config.manaValue then
playSound("/sounds/Low_Mana.ogg")
g_window.setTitle(pName .. " - Low Mana!")
delay(1500)
g_window.setTitle(pName .. " - Low Mana! only: "..manapercent().."%")
return
end
end
@@ -174,7 +259,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(pName .. " - Private Message")
g_window.setTitle(pName .. " - Private Message from: " .. name)
return
end
end)

View File

@@ -0,0 +1,181 @@
AlarmsWindow < MainWindow
!text: tr('Alarms')
size: 300 280
@onEscape: self:hide()
BotSwitch
id: playerAttack
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
text-align: center
text: Player Attack
!tooltip: tr('Alerts when attacked by player.')
BotSwitch
id: playerDetected
anchors.left: parent.left
anchors.right: parent.horizontalCenter
anchors.top: prev.bottom
margin-top: 4
text-align: center
text: Player Detected
!tooltip: tr('Alerts when a player is detected on screen.')
CheckBox
id: playerDetectedLogout
anchors.top: playerDetected.top
anchors.left: parent.horizontalCenter
anchors.right: parent.right
margin-top: 3
margin-left: 4
text: Logout
!tooltip: tr('Attempts to logout when a player is detected on screen.')
BotSwitch
id: ignoreFriends
anchors.left: parent.left
anchors.top: playerDetected.bottom
anchors.right: parent.right
text-align: center
margin-top: 4
text: Ignore Friends
!tooltip: tr('Player detection alerts will ignore friends.')
HorizontalSeparator
id: sepPlayer
anchors.right: parent.right
anchors.left: parent.left
anchors.top: prev.bottom
margin-top: 4
BotSwitch
id: creatureDetected
anchors.left: parent.left
anchors.right: parent.right
anchors.top: sepPlayer.bottom
margin-top: 4
text-align: center
text: Creature Detected
!tooltip: tr('Alerts when a creature is detected on screen.')
BotSwitch
id: warnBoss
anchors.left: parent.left
anchors.top: prev.bottom
anchors.right: parent.horizontalCenter
text-align: center
margin-top: 5
text: Creature Name
!tooltip: tr('Alerts when a creature/npc with name is detected on screen. \n eg: Benjamin or [boss] would detect a creature with [boss] in name. \n You can add many examples, just separate them by comma.')
BotTextEdit
id: bossName
anchors.left: prev.right
margin-left: 4
anchors.top: prev.top
anchors.right: parent.right
margin-top: 1
height: 17
font: terminus-10px
HorizontalSeparator
id: sepCreature
anchors.right: parent.right
anchors.left: parent.left
anchors.top: prev.bottom
margin-top: 4
BotSwitch
id: healthBelow
anchors.left: parent.left
anchors.top: prev.bottom
anchors.right: parent.horizontalCenter
text-align: center
margin-top: 4
text: Health < 50%
HorizontalScrollBar
id: healthValue
anchors.left: parent.horizontalCenter
anchors.right: parent.right
anchors.top: healthBelow.top
margin-left: 3
margin-top: 2
minimum: 1
maximum: 100
step: 1
BotSwitch
id: manaBelow
anchors.left: parent.left
anchors.top: healthBelow.bottom
anchors.right: parent.horizontalCenter
text-align: center
margin-top: 4
text: Mana < 50%
HorizontalScrollBar
id: manaValue
anchors.left: parent.horizontalCenter
anchors.right: parent.right
anchors.top: manaBelow.top
margin-left: 3
margin-top: 2
minimum: 1
maximum: 100
step: 1
HorizontalSeparator
id: sepMessages
anchors.right: parent.right
anchors.left: parent.left
anchors.top: prev.bottom
margin-top: 4
BotSwitch
id: privateMessage
anchors.left: parent.left
anchors.top: prev.bottom
anchors.right: parent.right
text-align: center
margin-top: 4
text: Private Message
!tooltip: tr('Alerts when recieving a private message.')
BotSwitch
id: warnMessage
anchors.left: parent.left
anchors.top: prev.bottom
anchors.right: parent.horizontalCenter
text-align: center
margin-top: 5
text: Message Alert
!tooltip: tr('Alerts when players receive a message that contains given part. \n Eg. event - will trigger alert whenever a message with word event appears. \n You can give many examples, just separate them by comma.')
BotTextEdit
id: messageText
anchors.left: prev.right
margin-left: 4
anchors.top: prev.top
anchors.right: parent.right
margin-top: 1
height: 17
font: terminus-10px
HorizontalSeparator
id: separator
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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,267 @@
AnalyzerPriceLabel < Label
background-color: alpha
text-offset: 2 0
focusable: true
height: 16
$focus:
background-color: #00000055
Button
id: remove
!text: tr('x')
anchors.right: parent.right
margin-right: 15
width: 15
height: 15
AnalyzerItemsPanel < Panel
height: 0
Panel
id: List
anchors.fill: parent
margin-top: 3
padding: 2
layout:
type: grid
cell-size: 32 32
cell-spacing: 3
num-columns: 5
AnalyzerLootItem < UIItem
opacity: 0.87
height: 37
margin-left: 1
virtual: true
background-color: alpha
Label
id: count
font: verdana-11px-rounded
color: white
opacity: 0.87
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
margin-right: 2
text-align: right
text: 0
AnalyzerGraph < UIGraph
height: 140
capacity: 400
line-width: 1
color: red
margin-top: 5
margin-left: 5
margin-right: 5
background-color: #383636
padding: 5
font: verdana-11px-rounded
image-source: /images/ui/graph_background
AnalyzerProgressBar < ProgressBar
background-color: green
height: 5
margin-top: 3
phantom: false
margin-left: 3
margin-right: 3
border: 1 black
AnalyzerButton < Button
height: 22
margin-bottom: 2
font: verdana-11px-rounded
text-offset: 0 4
MainAnalyzerWindow < MiniWindow
id: MainAnalyzerWindow
text: Analytics Selector
height: 200
icon: /images/topbuttons/analyzers
MiniWindowContents
padding-left: 5
padding-right: 5
padding-top: 5
layout: verticalBox
AnalyzerButton
id: HuntingAnalyzer
text: Hunting Analyzer
AnalyzerButton
id: LootAnalyzer
text: Loot Analyzer
AnalyzerButton
id: SupplyAnalyzer
text: Supply Analyzer
AnalyzerButton
id: ImpactAnalyzer
text: Impact Analyzer
AnalyzerButton
id: XPAnalyzer
text: XP Analyzer
AnalyzerButton
id: Settings
text: Features & Settings
color: #FABD02
AnalyzerButton
id: ResetSession
text: Reset Session
color: #FF0000
HuntingAnalyzer < MiniWindow
id: HuntingAnalyzerWindow
text: Hunt Analyzer
icon: /images/topbuttons/analyzers
MiniWindowContents
padding-top: 3
layout: verticalBox
LootAnalyzer < MiniWindow
id: LootAnalyzerWindow
text: Loot Analyzer
icon: /images/topbuttons/analyzers
MiniWindowContents
padding-top: 3
layout: verticalBox
SupplyAnalyzer < MiniWindow
id: SupplyAnalyzerWindow
text: Supply Analyzer
icon: /images/topbuttons/analyzers
MiniWindowContents
padding-top: 3
layout: verticalBox
ImpactAnalyzer < MiniWindow
id: ImpactAnalyzerWindow
text: Impact Analyzer
icon: /images/topbuttons/analyzers
MiniWindowContents
padding-top: 3
layout: verticalBox
XPAnalyzer < MiniWindow
id: XPAnalyzerWindow
text: XP Analyzer
height: 150
icon: /images/topbuttons/analyzers
MiniWindowContents
padding-top: 3
layout: verticalBox
FeaturesWindow < MainWindow
id: FeaturesWindow
size: 250 370
padding: 15
text: Analyzers Features
@onEscape: self:hide()
TextList
id: CustomPrices
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
margin-top: 10
padding: 1
height: 220
vertical-scrollbar: CustomPricesScrollBar
VerticalScrollBar
id: CustomPricesScrollBar
anchors.top: CustomPrices.top
anchors.bottom: CustomPrices.bottom
anchors.right: CustomPrices.right
step: 14
pixels-scroll: true
BotItem
id: ID
anchors.left: CustomPrices.left
anchors.top: CustomPrices.bottom
margin-top: 5
SpinBox
id: NewPrice
anchors.left: prev.right
margin-left: 5
anchors.verticalCenter: prev.verticalCenter
width: 100
minimum: 0
maximum: 1000000000
step: 1
text-align: center
focusable: true
Button
id: addItem
anchors.left: prev.right
margin-left: 5
anchors.verticalCenter: prev.verticalCenter
anchors.right: CustomPrices.right
text: Add
font: verdana-11px-rounded
HorizontalSeparator
anchors.left: ID.right
margin-left: 5
anchors.right: CustomPrices.right
anchors.verticalCenter: ID.top
HorizontalSeparator
id: secondSeparator
anchors.left: ID.right
margin-left: 5
anchors.right: CustomPrices.right
anchors.bottom: ID.bottom
BotSwitch
id: LootChannel
anchors.left: CustomPrices.left
anchors.right: parent.horizontalCenter
margin-right: 2
anchors.top: prev.top
margin-top: 20
text: Loot Channel
font: verdana-11px-rounded
BotSwitch
id: RarityFrames
anchors.left: parent.horizontalCenter
margin-left: 2
anchors.right: CustomPrices.right
anchors.top: secondSeparator.top
margin-top: 20
text: Rarity Frames
font: verdana-11px-rounded
HorizontalSeparator
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

@@ -2,7 +2,7 @@
Configs for modules
Based on Kondrah storage method
--]]
configName = modules.game_bot.contentsPanel.config:getCurrentOption().text
local configName = modules.game_bot.contentsPanel.config:getCurrentOption().text
-- make vBot config dir
if not g_resources.directoryExists("/bot/".. configName .."/vBot_configs/") then

View File

@@ -1,7 +1,7 @@
setDefaultTab("Main")
-- securing storage namespace
panelName = "extras"
local panelName = "extras"
if not storage[panelName] then
storage[panelName] = {}
end
@@ -346,12 +346,22 @@ end
addCheckBox("bless", "Buy bless at login", true, rightPanel)
if true then
local blessed = false
onTextMessage(function(mode,text)
if not settings.bless then return end
text = text:lower()
if text == "you already have all blessings." then
blessed = true
end
end)
if settings.bless then
if player:getBlessings() == 0 then
say("!bless")
schedule(2000, function()
if g_game.getClientVersion() > 1000 then
if player:getBlessings() == 0 then
if not blessed and player:getBlessings() == 0 then
warn("!! Blessings not bought !!")
end
end
@@ -394,11 +404,12 @@ 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 hold = 0
local mwHot
local wgHot
local candidates = {}
local m = macro(20, function()
mwHot = settings.holdMwHot
wgHot = settings.holdWgHot
@@ -406,14 +417,19 @@ if true then
if not settings.holdMwall then return end
if #candidates == 0 then return end
for i, tile in pairs(candidates) do
for i, pos in pairs(candidates) do
local tile = g_map.getTile(pos)
if tile then
if tile:getText():len() == 0 then
table.remove(candidates, i)
table.remove(candidates, i)
end
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
if math.abs(player:getPosition().x-tile:getPosition().x) < 8 and math.abs(player:getPosition().y-tile:getPosition().y) < 6 then
return useWith(rune, tile:getTopUseThing())
end
end
end
end
end)
@@ -421,9 +437,11 @@ if true then
if not settings.holdMwall then return end
if thing:getId() ~= 2129 then return end
if tile:getText():find("HOLD") then
table.insert(candidates, tile)
table.insert(candidates, tile:getPosition())
local rune = tile:getText() == "HOLD MW" and 3180 or tile:getText() == "HOLD WG" and 3156
useWith(rune, tile:getTopUseThing())
if math.abs(player:getPosition().x-tile:getPosition().x) < 8 and math.abs(player:getPosition().y-tile:getPosition().y) < 6 then
return useWith(rune, tile:getTopUseThing())
end
end
end)
@@ -436,13 +454,13 @@ if true then
end
end)
onKeyPress(function(keys)
onKeyDown(function(keys)
local wsadWalking = modules.game_walking.wsadWalking
if not wsadWalking then return end
if not settings.holdMwall then return end
if m.isOff() then return end
if keys ~= mwHot and keys ~= wgHot then return end
hold = now
local tile = getTileUnderCursor()
if not tile then return end
@@ -455,7 +473,25 @@ if true then
else
tile:setText("HOLD WG")
end
table.insert(candidates, tile)
table.insert(candidates, tile:getPosition())
end
end)
onKeyPress(function(keys)
local wsadWalking = modules.game_walking.wsadWalking
if not wsadWalking then return end
if not settings.holdMwall then return end
if m.isOff() then return end
if keys ~= mwHot and keys ~= wgHot then return end
if (hold - now) < -1000 then
candidates = {}
for i, tile in ipairs(g_map.getTiles(posz())) do
local text = tile:getText()
if text:find("HOLD") then
tile:setText("")
end
end
end
end)
end
@@ -490,7 +526,7 @@ if true then
end
end)
local regex = [[You see ([a-z 'A-z-]*) \(Level ([0-9]*)\)]]
local regex = [[You see ([a-z 'A-z-]*) \(Level ([0-9]*)\)((?:.)* of the ([\w ]*),|)]]
onTextMessage(function(mode, text)
if not settings.checkPlayer then return end
@@ -498,6 +534,12 @@ if true then
if #re ~= 0 then
local name = re[1][2]
local level = re[1][3]
local guild = re[1][5] or ""
if guild:len() > 10 then
guild = guild:sub(1,10) -- change to proper (last) values
guild = guild.."..."
end
local voc
if text:lower():find("sorcerer") then
voc = "MS"
@@ -510,11 +552,43 @@ if true then
end
local creature = getCreatureByName(name)
if creature then
creature:setText(level..voc)
creature:setText("\n"..level..voc.."\n"..guild)
end
if found and now - found < 500 then
modules.game_textmessage.clearMessages()
end
end
end)
end
addCheckBox("title", "Open Next Loot Container", true, leftPanel)
local function openNextLootContainer()
local containers = getContainers()
local lootCotaniersIds = CaveBot.GetLootContainers()
for i, container in ipairs(containers) do
local cId = container:getContainerItem():getId()
if containerIsFull(container) then
if table.find(lootCotaniersIds, cId) then
for _, item in ipairs(container:getItems()) do
if item:getId() == cId then
return g_game.open(item, container)
end
end
end
end
end
end
if true then
onContainerOpen(function(container, previousContainer)
schedule(100, function()
openNextLootContainer()
end)
end)
onAddItem(function(container, slot, item, oldItem)
schedule(100, function()
openNextLootContainer()
end)
end)
end

View File

@@ -930,7 +930,7 @@ LootItems = {
["sickle"] = 3,
["sight of surrender's eye"] = 3000,
["signet ring"] = 480000,
["silencer claws"] = 390,
["silencer claws"] = 25000,
["silencer resonating chamber"] = 600,
["silken bookmark"] = 1300,
["silkweaver bow"] = 12000,
@@ -1263,5 +1263,99 @@ LootItems = {
["energy wall rune"] = 85,
["energy bomb rune"] = 203,
["sudden death rune"] = 135,
["paralyse rune"] = 700
["paralyse rune"] = 700,
["envenomed arrow"] = 12,
["flaming arrow"] = 5,
["flash arrow"] = 5,
["onyx arrow"] = 7,
["poison arrow"] = 1,
["shiver arrow"] = 5,
["simple arrow"] = 2,
["sniper arrow"] = 5,
["tarsal arrow"] = 6,
["arrow"] = 3,
["burst arrow"] = 0,
["crystalline arrow"] = 20,
["diamond arrow"] = 100,
["earth arrow"] = 5,
["infernal bolt"] = 12,
["piercing bolt"] = 5,
["power bolt"] = 7,
["prismatic bolt"] = 20,
["spectral bolt"] = 70,
["vortex bolt"] = 6,
["bolt"] = 4,
["drill bolt"] = 12,
}
WasteItems = {
-- supplies
["mana potion"] = 268,
["strong mana potion"] = 237,
["great mana potion"] = 238,
["ultimate mana potion"] = 23373,
["health potion"] = 266,
["strong health potion"] = 236,
["great health potion"] = 239,
["ultimate health potion"] = 7643,
["supreme health potion"] = 23375,
["great spirit potion"] = 7642,
["ultimate spirit potion"] = 23374,
-- ammo
["envenomed arrow"] = 16143,
["flaming arrow"] = 763,
["flash arrow"] = 761,
["onyx arrow"] = 7365,
["poison arrow"] = 3448,
["shiver arrow"] = 762,
["simple arrow"] = 21470,
["sniper arrow"] = 7364,
["tarsal arrow"] = 14251,
["arrow"] = 3447,
["burst arrow"] = 3449,
["crystalline arrow"] = 15793,
["diamond arrow"] = 35901,
["earth arrow"] = 774,
["infernal bolt"] = 6528,
["piercing bolt"] = 7363,
["power bolt"] = 3450,
["prismatic bolt"] = 16141,
["spectral bolt"] = 35902,
["vortex bolt"] = 14252,
["bolt"] = 3446,
["drill bolt"] = 16142,
-- runes
["cure poison rune"] = 3153,
["poison field rune"] = 3172,
["fire field rune"] = 3188,
["intense healing rune"] = 3152,
["destroy field rune"] = 3148,
["energy field rune"] = 3164,
["stalagmite rune"] = 3179,
["heavy magic missile rune"] = 3198,
["disintegrate rune"] = 3197,
["ultimate healing rune"] = 3160,
["poison bomb rune"] = 3173,
["animate death rune"] = 3203,
["chameleon rune"] = 3178,
["fireball rune"] = 3189,
["holy missile rune"] = 3182,
["icicle rune"] = 3158,
["stone shower rune"] = 3175,
["thunderstorm rune"] = 3202,
["avalanche rune"] = 3161,
["great fireball rune"] = 3191,
["convince creature rune"] = 3177,
["fire bomb rune"] = 3192,
["poison wall rune"] = 3176,
["explosion rune"] = 3200,
["fire wall rune"] = 3190,
["soulfire rune"] = 3195,
["wild growth rune"] = 3156,
["magic wall rune"] = 3180,
["energy wall rune"] = 3166,
["energy bomb rune"] = 3149,
["sudden death rune"] = 3155,
["paralyse rune"] = 3165
}

View File

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

View File

@@ -167,6 +167,19 @@ function CaveBot.CloseLootContainer()
return true
end
function CaveBot.CloseAllLootContainers()
local containers = CaveBot.GetLootContainers()
for i, container in pairs(getContainers()) do
local containerId = container:getContainerItem():getId()
if table.find(containers, containerId) then
g_game.close(container)
end
end
return true
end
--- Opens any loot container that isn't already opened.
-- @return void or boolean
function CaveBot.OpenLootContainer()
@@ -436,7 +449,6 @@ 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

@@ -1,3 +1,4 @@
---@diagnostic disable: undefined-global
setDefaultTab("Main")
local panelName = "pushmax"
@@ -93,22 +94,22 @@ local customMwall = config.mwallBlockId
local key = config.pushMaxKey
local enabled = config.enabled
local fieldTable = {2118, 105, 2122}
local cleanTile = nil
-- scripts
local targetTile
local pushTarget
local targetid
local resetData = function()
for i, tile in pairs(g_map.getTiles(posz())) do
if tile:getText() == "TARGET" or tile:getText() == "DEST" then
if tile:getText() == "TARGET" or tile:getText() == "DEST" or tile:getText() == "CLEAR" then
tile:setText('')
end
end
pushTarget = nil
targetTile = nil
targetId = nil
cleanTile = nil
end
local getCreatureById = function(id)
@@ -139,9 +140,11 @@ local isOk = function(a,b)
end
-- to mark
local hold = 0
onKeyDown(function(keys)
if not enabled then return end
if keys ~= key then return end
hold = now
local tile = getTileUnderCursor()
if not tile then return end
if pushTarget and targetTile then
@@ -151,7 +154,6 @@ onKeyDown(function(keys)
local creature = tile:getCreatures()[1]
if not pushTarget and creature then
pushTarget = creature
targetId = creature:getId()
if pushTarget then
tile:setText('TARGET')
pushTarget:setMarked('#00FF00')
@@ -167,6 +169,24 @@ onKeyDown(function(keys)
end
end)
-- mark tile to throw anything from it
onKeyPress(function(keys)
if not enabled then return end
if keys ~= key then return end
local tile = getTileUnderCursor()
if not tile then return end
if (hold - now) < -2500 then
if cleanTile and tile ~= cleanTile then
resetData()
elseif not cleanTile then
cleanTile = tile
tile:setText("CLEAR")
end
end
hold = 0
end)
onCreaturePositionChange(function(creature, newPos, oldPos)
if not enabled then return end
if creature == player then
@@ -178,42 +198,93 @@ onCreaturePositionChange(function(creature, newPos, oldPos)
end
end)
macro(20, function()
macro(50, function()
if not enabled then return end
if not pushTarget or not targetTile then return end
tilePos = targetTile:getPosition()
targetPos = pushTarget:getPosition()
if not isOk(tilePos,targetPos) then return end
local tileOfTarget = g_map.getTile(targetPos)
if not targetTile:isWalkable() then
local topThing = targetTile:getTopUseThing():getId()
if topThing == 2129 or topThing == 2130 or topThing == customMwall then
if targetTile:getTimer() < pushDelay+500 then
vBot.isUsing = true
schedule(pushDelay+700, function()
vBot.isUsing = false
end)
end
if targetTile:getTimer() > pushDelay then
return
end
else
return resetData()
end
end
if not tileOfTarget:getTopUseThing():isNotMoveable() then
return useWith(rune, pushTarget)
end
if isNotOk(fieldTable, targetTile) then
if targetTile:canShoot() then
return useWith(3148, targetTile:getTopUseThing())
else
if cleanTile then
local tilePos = cleanTile:getPosition()
local pPos = player:getPosition()
if not isOk(tilePos, pPos) then
resetData()
return
end
if not cleanTile:hasCreature() then return end
local tiles = getNearTiles(tilePos)
local destTile
local forbidden = {}
-- unfortunately double loop
for i, tile in pairs(tiles) do
local minimapColor = g_map.getMinimapColor(tile:getPosition())
local stairs = (minimapColor >= 210 and minimapColor <= 213)
if stairs then
table.insert(forbidden, tile:getPosition())
end
end
for i, tile in pairs(tiles) do
local minimapColor = g_map.getMinimapColor(tile:getPosition())
local stairs = (minimapColor >= 210 and minimapColor <= 213)
if tile:isWalkable() and not isNotOk(fieldTable, tile) and not tile:hasCreature() and not stairs then
local tooClose = false
if #forbidden ~= 0 then
for i=1,#forbidden do
local pos = forbidden[i]
if isOk(pos, tile:getPosition()) then
tooClose = true
break
end
end
end
if not tooClose then
destTile = tile
break
end
end
end
if not destTile then return end
local parcel = cleanTile:getCreatures()[1]
if parcel then
test()
g_game.move(parcel,destTile:getPosition())
delay(2000)
end
else
if not pushTarget or not targetTile then return end
local tilePos = targetTile:getPosition()
local targetPos = pushTarget:getPosition()
if not isOk(tilePos,targetPos) then return end
local tileOfTarget = g_map.getTile(targetPos)
if not targetTile:isWalkable() then
local topThing = targetTile:getTopUseThing():getId()
if topThing == 2129 or topThing == 2130 or topThing == customMwall then
if targetTile:getTimer() < pushDelay+500 then
vBot.isUsing = true
schedule(pushDelay+700, function()
vBot.isUsing = false
end)
end
if targetTile:getTimer() > pushDelay then
return
end
else
return resetData()
end
end
if not tileOfTarget:getTopUseThing():isNotMoveable() and targetTile:getTimer() < pushDelay+500 then
return useWith(rune, pushTarget)
end
if isNotOk(fieldTable, targetTile) then
if targetTile:canShoot() then
return useWith(3148, targetTile:getTopUseThing())
else
return
end
end
g_game.move(pushTarget,tilePos)
delay(2000)
end
g_game.move(pushTarget,tilePos)
delay(2000)
end)

View File

@@ -1,10 +1,5 @@
-- Author: Vithrax
-- contains mostly basic function shortcuts and code shorteners
-- burst damage calculation, for function burstDamageValue()
-- sums monster hits on a span of last 3seconds
-- if last message was more than 3s ago then clears the table
-- initial global variables declaration
vBot = {} -- global namespace for bot variables
@@ -12,7 +7,7 @@ vBot.BotServerMembers = {}
vBot.standTime = now
vBot.isUsingPotion = false
vBot.isUsing = false
vBot.customCooldowns = {}
-- scripts / functions
onPlayerPositionChange(function(x,y)
@@ -282,18 +277,56 @@ end
-- exctracts data about spell from gamelib SpellInfo table
-- returns table
-- ie:['Spell Name'] = {id, words, exhaustion, premium, type, icon, mana, level, soul, group, vocations}
-- cooldown detection module
local lastPhrase = ""
onTalk(function(name, level, mode, text, channelId, pos)
if name == player:getName() then
lastPhrase = text:lower()
end
end)
if onSpellCooldown and onGroupSpellCooldown then
onSpellCooldown(function(iconId, duration)
schedule(5, function()
if not vBot.customCooldowns[lastPhrase] then
vBot.customCooldowns[lastPhrase] = {id = iconId}
end
end)
end)
onGroupSpellCooldown(function(iconId, duration)
schedule(10, function()
if vBot.customCooldowns[lastPhrase] then
vBot.customCooldowns[lastPhrase] = {id = vBot.customCooldowns[lastPhrase].id, group = {[iconId] = duration}}
end
end)
end)
else
warn("Outdated OTClient! update to newest version to take benefits from all scripts!")
end
function getSpellData(spell)
if not spell then return false end
spell = spell:lower()
local t = nil
local c = nil
for k, v in pairs(Spells) do
if v.words == spell then
t = k
break
end
end
if not t then
for k, v in pairs(vBot.customCooldowns) do
if k == spell then
c = {id = v.id, mana = 1, level = 1, group = v.group}
break
end
end
end
if t then
return Spells[t]
elseif c then
return c
else
return false
end
@@ -819,7 +852,7 @@ end
-- self explanatory
-- use along with delay, it will only call action
function useOnGroundItem(a, b)
if not id then return false end
if not b then return false end
local item = findItem(a)
if not item then return false end
@@ -989,7 +1022,6 @@ function getContainerByItem(id, notFull)
end
-- [[ ready to use getSpectators patterns ]] --
LargeUeArea = [[
0000001000000
0000011100000

View File

@@ -1,7 +0,0 @@
-- main tab
UI.Label("Vithrax CFG v1.3 \n \n Scripting Service: \n Vithrax#5814")
UI.Separator()

View File

@@ -1,147 +0,0 @@
setDefaultTab("Main")
BotPanelName = "BOTserver"
local ui = setupUI([[
Panel
height: 18
Button
id: botServer
anchors.left: parent.left
anchors.right: parent.right
text-align: center
height: 18
!text: tr('BotServer')
]])
ui:setId(BotPanelName)
if not storage[BotPanelName] then
storage[BotPanelName] = {
manaInfo = true,
mwallInfo = true
}
end
if not storage.BotServerChannel then
storage.BotServerChannel = tostring(math.random(1000000000000,9999999999999))
end
local channel = tostring(storage.BotServerChannel)
BotServer.init(name(), channel)
rootWidget = g_ui.getRootWidget()
if rootWidget then
botServerWindow = g_ui.createWidget('BotServerWindow', rootWidget)
botServerWindow:hide()
botServerWindow.Data.Channel:setText(storage.BotServerChannel)
botServerWindow.Data.Channel.onTextChange = function(widget, text)
storage.BotServerChannel = text
end
botServerWindow.Data.Random.onClick = function(widget)
storage.BotServerChannel = tostring(math.random(1000000000000,9999999999999))
botServerWindow.Data.Channel:setText(storage.BotServerChannel)
end
botServerWindow.Features.Feature1:setOn(storage[BotPanelName].manaInfo)
botServerWindow.Features.Feature1.onClick = function(widget)
storage[BotPanelName].manaInfo = not storage[BotPanelName].manaInfo
widget:setOn(storage[BotPanelName].manaInfo)
end
botServerWindow.Features.Feature2:setOn(storage[BotPanelName].mwallInfo)
botServerWindow.Features.Feature2.onClick = function(widget)
storage[BotPanelName].mwallInfo = not storage[BotPanelName].mwallInfo
widget:setOn(storage[BotPanelName].mwallInfo)
end
end
function updateStatusText()
if BotServer._websocket then
botServerWindow.Data.ServerStatus:setText("CONNECTED")
if serverCount then
botServerWindow.Data.Participants:setText(#serverCount)
end
else
botServerWindow.Data.ServerStatus:setText("DISCONNECTED")
botServerWindow.Data.Participants:setText("-")
end
end
macro(2000, function()
if BotServer._websocket then
BotServer.send("list")
end
updateStatusText()
end)
local regex = [["(.*?)"]]
BotServer.listen("list", function(name, data)
serverCount = regexMatch(json.encode(data), regex)
storage.serverMembers = json.encode(data)
end)
ui.botServer.onClick = function(widget)
botServerWindow:show()
botServerWindow:raise()
botServerWindow:focus()
end
botServerWindow.closeButton.onClick = function(widget)
botServerWindow:hide()
end
-- scripts
storage[BotPanelName].mwalls = {}
BotServer.listen("mwall", function(name, message)
if storage[BotPanelName].mwallInfo then
if not storage[BotPanelName].mwalls[message["pos"]] or storage[BotPanelName].mwalls[message["pos"]] < now then
storage[BotPanelName].mwalls[message["pos"]] = now + message["duration"] - 150 -- 150 is latency correction
end
end
end)
BotServer.listen("mana", function(name, message)
if storage[BotPanelName].manaInfo then
local creature = getPlayerByName(name)
if creature then
creature:setManaPercent(message["mana"])
end
end
end)
onAddThing(function(tile, thing)
if storage[BotPanelName].mwallInfo then
if thing:isItem() and thing:getId() == 2129 then
local pos = tile:getPosition().x .. "," .. tile:getPosition().y .. "," .. tile:getPosition().z
if not storage[BotPanelName].mwalls[pos] or storage[BotPanelName].mwalls[pos] < now then
storage[BotPanelName].mwalls[pos] = now + 20000
BotServer.send("mwall", {pos=pos, duration=20000})
end
tile:setTimer(storage[BotPanelName].mwalls[pos] - now)
end
end
end)
local lastMana = 0
macro(100, function()
if storage[BotPanelName].manaInfo then
if manapercent() ~= lastMana then
lastMana = manapercent()
BotServer.send("mana", {mana=lastMana})
end
end
end)
addSeparator()

View File

@@ -1,178 +0,0 @@
alarmsPanelName = "alarms"
local ui = setupUI([[
Panel
height: 19
BotSwitch
id: title
anchors.top: parent.top
anchors.left: parent.left
text-align: center
width: 130
!text: tr('Alarms')
Button
id: alerts
anchors.top: prev.top
anchors.left: prev.right
anchors.right: parent.right
margin-left: 3
height: 17
text: Edit
]])
ui:setId(alarmsPanelName)
if not storage[alarmsPanelName] then
storage[alarmsPanelName] = {
enabled = false,
playerAttack = false,
playerDetected = false,
playerDetectedLogout = false,
creatureDetected = false,
healthBelow = false,
healthValue = 40,
manaBelow = false,
manaValue = 50,
privateMessage = false
}
end
ui.title:setOn(storage[alarmsPanelName].enabled)
ui.title.onClick = function(widget)
storage[alarmsPanelName].enabled = not storage[alarmsPanelName].enabled
widget:setOn(storage[alarmsPanelName].enabled)
end
rootWidget = g_ui.getRootWidget()
if rootWidget then
alarmsWindow = g_ui.createWidget('AlarmsWindow', rootWidget)
alarmsWindow:hide()
alarmsWindow.closeButton.onClick = function(widget)
alarmsWindow:hide()
end
alarmsWindow.playerAttack:setOn(storage[alarmsPanelName].playerAttack)
alarmsWindow.playerAttack.onClick = function(widget)
storage[alarmsPanelName].playerAttack = not storage[alarmsPanelName].playerAttack
widget:setOn(storage[alarmsPanelName].playerAttack)
end
alarmsWindow.playerDetected:setOn(storage[alarmsPanelName].playerDetected)
alarmsWindow.playerDetected.onClick = function(widget)
storage[alarmsPanelName].playerDetected = not storage[alarmsPanelName].playerDetected
widget:setOn(storage[alarmsPanelName].playerDetected)
end
alarmsWindow.playerDetectedLogout:setChecked(storage[alarmsPanelName].playerDetectedLogout)
alarmsWindow.playerDetectedLogout.onClick = function(widget)
storage[alarmsPanelName].playerDetectedLogout = not storage[alarmsPanelName].playerDetectedLogout
widget:setChecked(storage[alarmsPanelName].playerDetectedLogout)
end
alarmsWindow.creatureDetected:setOn(storage[alarmsPanelName].creatureDetected)
alarmsWindow.creatureDetected.onClick = function(widget)
storage[alarmsPanelName].creatureDetected = not storage[alarmsPanelName].creatureDetected
widget:setOn(storage[alarmsPanelName].creatureDetected)
end
alarmsWindow.healthBelow:setOn(storage[alarmsPanelName].healthBelow)
alarmsWindow.healthBelow.onClick = function(widget)
storage[alarmsPanelName].healthBelow = not storage[alarmsPanelName].healthBelow
widget:setOn(storage[alarmsPanelName].healthBelow)
end
alarmsWindow.healthValue.onValueChange = function(scroll, value)
storage[alarmsPanelName].healthValue = value
alarmsWindow.healthBelow:setText("Health < " .. storage[alarmsPanelName].healthValue .. "%")
end
alarmsWindow.healthValue:setValue(storage[alarmsPanelName].healthValue)
alarmsWindow.manaBelow:setOn(storage[alarmsPanelName].manaBelow)
alarmsWindow.manaBelow.onClick = function(widget)
storage[alarmsPanelName].manaBelow = not storage[alarmsPanelName].manaBelow
widget:setOn(storage[alarmsPanelName].manaBelow)
end
alarmsWindow.manaValue.onValueChange = function(scroll, value)
storage[alarmsPanelName].manaValue = value
alarmsWindow.manaBelow:setText("Mana < " .. storage[alarmsPanelName].manaValue .. "%")
end
alarmsWindow.manaValue:setValue(storage[alarmsPanelName].manaValue)
alarmsWindow.privateMessage:setOn(storage[alarmsPanelName].privateMessage)
alarmsWindow.privateMessage.onClick = function(widget)
storage[alarmsPanelName].privateMessage = not storage[alarmsPanelName].privateMessage
widget:setOn(storage[alarmsPanelName].privateMessage)
end
onTextMessage(function(mode, text)
if storage[alarmsPanelName].enabled and storage[alarmsPanelName].playerAttack and mode == 16 and string.match(text, "hitpoints due to an attack") and not string.match(text, "hitpoints due to an attack by a ") then
playSound("/sounds/Player_Attack.ogg")
end
end)
macro(100, function()
if not storage[alarmsPanelName].enabled then
return
end
if storage[alarmsPanelName].playerDetected then
for _, spec in ipairs(getSpectators()) do
if spec:isPlayer() and spec:getName() ~= name() then
specPos = spec:getPosition()
if math.max(math.abs(posx()-specPos.x), math.abs(posy()-specPos.y)) <= 8 then
playSound("/sounds/Player_Detected.ogg")
delay(1500)
if storage[alarmsPanelName].playerDetectedLogout then
modules.game_interface.tryLogout(false)
end
return
end
end
end
end
if storage[alarmsPanelName].creatureDetected then
for _, spec in ipairs(getSpectators()) do
if not spec:isPlayer()then
specPos = spec:getPosition()
if math.max(math.abs(posx()-specPos.x), math.abs(posy()-specPos.y)) <= 8 then
playSound("/sounds/Creature_Detected.ogg")
delay(1500)
return
end
end
end
end
if storage[alarmsPanelName].healthBelow then
if hppercent() <= storage[alarmsPanelName].healthValue then
playSound("/sounds/Low_Health.ogg")
delay(1500)
return
end
end
if storage[alarmsPanelName].manaBelow then
if manapercent() <= storage[alarmsPanelName].manaValue then
playSound("/sounds/Low_Mana.ogg")
delay(1500)
return
end
end
end)
onTalk(function(name, level, mode, text, channelId, pos)
if mode == 4 and storage[alarmsPanelName].enabled and storage[alarmsPanelName].privateMessage then
playSound("/sounds/Private_Message.ogg")
return
end
end)
end
ui.alerts.onClick = function(widget)
alarmsWindow:show()
alarmsWindow:raise()
alarmsWindow:focus()
end

View File

@@ -1,440 +0,0 @@
ComboPanelName = "combobot"
local ui = setupUI([[
Panel
height: 19
BotSwitch
id: title
anchors.top: parent.top
anchors.left: parent.left
text-align: center
width: 130
!text: tr('ComboBot')
Button
id: combos
anchors.top: prev.top
anchors.left: prev.right
anchors.right: parent.right
margin-left: 3
height: 17
text: Setup
]])
ui:setId(ComboPanelName)
if not storage[ComboPanelName] then
storage[ComboPanelName] = {
enabled = false,
onSayEnabled = false,
onShootEnabled = false,
onCastEnabled = false,
followLeaderEnabled = false,
attackLeaderTargetEnabled = false,
attackSpellEnabled = false,
attackItemToggle = false,
sayLeader = "",
shootLeader = "",
castLeader = "",
sayPhrase = "",
spell = "",
serverLeader = "",
item = 3155,
attack = "",
follow = "",
commandsEnabled = true,
serverEnabled = false,
serverLeaderTarget = false,
serverTriggers = true
}
end
ui.title:setOn(storage[ComboPanelName].enabled)
ui.title.onClick = function(widget)
storage[ComboPanelName].enabled = not storage[ComboPanelName].enabled
widget:setOn(storage[ComboPanelName].enabled)
end
ui.combos.onClick = function(widget)
comboWindow:show()
comboWindow:raise()
comboWindow:focus()
end
rootWidget = g_ui.getRootWidget()
if rootWidget then
comboWindow = g_ui.createWidget('ComboWindow', rootWidget)
comboWindow:hide()
-- bot item
comboWindow.actions.attackItem:setItemId(storage[ComboPanelName].item)
comboWindow.actions.attackItem.onItemChange = function(widget)
storage[ComboPanelName].item = widget:getItemId()
end
-- switches
comboWindow.actions.commandsToggle:setOn(storage[ComboPanelName].commandsEnabled)
comboWindow.actions.commandsToggle.onClick = function(widget)
storage[ComboPanelName].commandsEnabled = not storage[ComboPanelName].commandsEnabled
widget:setOn(storage[ComboPanelName].commandsEnabled)
end
comboWindow.server.botServerToggle:setOn(storage[ComboPanelName].serverEnabled)
comboWindow.server.botServerToggle.onClick = function(widget)
storage[ComboPanelName].serverEnabled = not storage[ComboPanelName].serverEnabled
widget:setOn(storage[ComboPanelName].serverEnabled)
end
comboWindow.server.Triggers:setOn(storage[ComboPanelName].serverTriggers)
comboWindow.server.Triggers.onClick = function(widget)
storage[ComboPanelName].serverTriggers = not storage[ComboPanelName].serverTriggers
widget:setOn(storage[ComboPanelName].serverTriggers)
end
comboWindow.server.targetServerLeaderToggle:setOn(storage[ComboPanelName].serverLeaderTarget)
comboWindow.server.targetServerLeaderToggle.onClick = function(widget)
storage[ComboPanelName].serverLeaderTarget = not storage[ComboPanelName].serverLeaderTarget
widget:setOn(storage[ComboPanelName].serverLeaderTarget)
end
-- buttons
comboWindow.closeButton.onClick = function(widget)
comboWindow:hide()
end
-- combo boxes
comboWindow.actions.followLeader:setOption(storage[ComboPanelName].follow)
comboWindow.actions.followLeader.onOptionChange = function(widget)
storage[ComboPanelName].follow = widget:getCurrentOption().text
end
comboWindow.actions.attackLeaderTarget:setOption(storage[ComboPanelName].attack)
comboWindow.actions.attackLeaderTarget.onOptionChange = function(widget)
storage[ComboPanelName].attack = widget:getCurrentOption().text
end
-- checkboxes
comboWindow.trigger.onSayToggle:setChecked(storage[ComboPanelName].onSayEnabled)
comboWindow.trigger.onSayToggle.onClick = function(widget)
storage[ComboPanelName].onSayEnabled = not storage[ComboPanelName].onSayEnabled
widget:setChecked(storage[ComboPanelName].onSayEnabled)
end
comboWindow.trigger.onShootToggle:setChecked(storage[ComboPanelName].onShootEnabled)
comboWindow.trigger.onShootToggle.onClick = function(widget)
storage[ComboPanelName].onShootEnabled = not storage[ComboPanelName].onShootEnabled
widget:setChecked(storage[ComboPanelName].onShootEnabled)
end
comboWindow.trigger.onCastToggle:setChecked(storage[ComboPanelName].onCastEnabled)
comboWindow.trigger.onCastToggle.onClick = function(widget)
storage[ComboPanelName].onCastEnabled = not storage[ComboPanelName].onCastEnabled
widget:setChecked(storage[ComboPanelName].onCastEnabled)
end
comboWindow.actions.followLeaderToggle:setChecked(storage[ComboPanelName].followLeaderEnabled)
comboWindow.actions.followLeaderToggle.onClick = function(widget)
storage[ComboPanelName].followLeaderEnabled = not storage[ComboPanelName].followLeaderEnabled
widget:setChecked(storage[ComboPanelName].followLeaderEnabled)
end
comboWindow.actions.attackLeaderTargetToggle:setChecked(storage[ComboPanelName].attackLeaderTargetEnabled)
comboWindow.actions.attackLeaderTargetToggle.onClick = function(widget)
storage[ComboPanelName].attackLeaderTargetEnabled = not storage[ComboPanelName].attackLeaderTargetEnabled
widget:setChecked(storage[ComboPanelName].attackLeaderTargetEnabled)
end
comboWindow.actions.attackSpellToggle:setChecked(storage[ComboPanelName].attackSpellEnabled)
comboWindow.actions.attackSpellToggle.onClick = function(widget)
storage[ComboPanelName].attackSpellEnabled = not storage[ComboPanelName].attackSpellEnabled
widget:setChecked(storage[ComboPanelName].attackSpellEnabled)
end
comboWindow.actions.attackItemToggle:setChecked(storage[ComboPanelName].attackItemEnabled)
comboWindow.actions.attackItemToggle.onClick = function(widget)
storage[ComboPanelName].attackItemEnabled = not storage[ComboPanelName].attackItemEnabled
widget:setChecked(storage[ComboPanelName].attackItemEnabled)
end
-- text edits
comboWindow.trigger.onSayLeader:setText(storage[ComboPanelName].sayLeader)
comboWindow.trigger.onSayLeader.onTextChange = function(widget, text)
storage[ComboPanelName].sayLeader = text
end
comboWindow.trigger.onShootLeader:setText(storage[ComboPanelName].shootLeader)
comboWindow.trigger.onShootLeader.onTextChange = function(widget, text)
storage[ComboPanelName].shootLeader = text
end
comboWindow.trigger.onCastLeader:setText(storage[ComboPanelName].castLeader)
comboWindow.trigger.onCastLeader.onTextChange = function(widget, text)
storage[ComboPanelName].castLeader = text
end
comboWindow.trigger.onSayPhrase:setText(storage[ComboPanelName].sayPhrase)
comboWindow.trigger.onSayPhrase.onTextChange = function(widget, text)
storage[ComboPanelName].sayPhrase = text
end
comboWindow.actions.attackSpell:setText(storage[ComboPanelName].spell)
comboWindow.actions.attackSpell.onTextChange = function(widget, text)
storage[ComboPanelName].spell = text
end
comboWindow.server.botServerLeader:setText(storage[ComboPanelName].serverLeader)
comboWindow.server.botServerLeader.onTextChange = function(widget, text)
storage[ComboPanelName].serverLeader = text
end
end
-- bot server
-- [[ join party made by Frosty ]] --
local shouldCloseWindow = false
local firstInvitee = true
local isInComboTeam = false
macro(10, function()
if shouldCloseWindow and storage[ComboPanelName].serverEnabled and storage[ComboPanelName].enabled then
local channelsWindow = modules.game_console.channelsWindow
if channelsWindow then
local child = channelsWindow:getChildById("buttonCancel")
if child then
child:onClick()
shouldCloseWindow = false
isInComboTeam = true
end
end
end
end)
comboWindow.server.partyButton.onClick = function(widget)
if storage[ComboPanelName].serverEnabled and storage[ComboPanelName].enabled then
if storage[ComboPanelName].serverLeader:len() > 0 and storage.BotServerChannel:len() > 0 then
talkPrivate(storage[ComboPanelName].serverLeader, "request invite " .. storage.BotServerChannel)
else
error("Request failed. Lack of data.")
end
end
end
onTextMessage(function(mode, text)
if storage[ComboPanelName].serverEnabled and storage[ComboPanelName].enabled then
if mode == 20 then
if string.find(text, "invited you to") then
local regex = "[a-zA-Z]*"
local regexData = regexMatch(text, regex)
if regexData[1][1]:lower() == storage[ComboPanelName].serverLeader:lower() then
local leader = getCreatureByName(regexData[1][1])
if leader then
g_game.partyJoin(leader:getId())
g_game.requestChannels()
g_game.joinChannel(1)
shouldCloseWindow = true
end
end
end
end
end
end)
onTalk(function(name, level, mode, text, channelId, pos)
if storage[ComboPanelName].serverEnabled and storage[ComboPanelName].enabled then
if mode == 4 then
if string.find(text, "request invite") then
local access = string.match(text, "%d.*")
if access and access == storage.BotServerChannel then
local minion = getCreatureByName(name)
if minion then
g_game.partyInvite(minion:getId())
if firstInvitee then
g_game.requestChannels()
g_game.joinChannel(1)
shouldCloseWindow = true
firstInvitee = false
end
end
else
talkPrivate(name, "Incorrect access key!")
end
end
end
end
-- [[ End of Frosty's Code ]] --
if storage[ComboPanelName].enabled and storage[ComboPanelName].enabled then
if name:lower() == storage[ComboPanelName].sayLeader:lower() and string.find(text, storage[ComboPanelName].sayPhrase) and storage[ComboPanelName].onSayEnabled then
startCombo = true
end
if (storage[ComboPanelName].castLeader and name:lower() == storage[ComboPanelName].castLeader:lower()) and isAttSpell(text) and storage[ComboPanelName].onCastEnabled then
startCombo = true
end
end
if storage[ComboPanelName].enabled and storage[ComboPanelName].commandsEnabled and (storage[ComboPanelName].shootLeader and name:lower() == storage[ComboPanelName].shootLeader:lower()) or (storage[ComboPanelName].sayLeader and name:lower() == storage[ComboPanelName].sayLeader:lower()) or (storage[ComboPanelName].castLeader and name:lower() == storage[ComboPanelName].castLeader:lower()) then
if string.find(text, "ue") then
say(storage[ComboPanelName].spell)
elseif string.find(text, "sd") then
local params = string.split(text, ",")
if #params == 2 then
local target = params[2]:trim()
if getCreatureByName(target) then
useWith(3155, getCreatureByName(target))
end
end
elseif string.find(text, "att") then
local attParams = string.split(text, ",")
if #attParams == 2 then
local atTarget = attParams[2]:trim()
if getCreatureByName(atTarget) and storage[ComboPanelName].attack == "COMMAND TARGET" then
g_game.attack(getCreatureByName(atTarget))
end
end
end
end
if isAttSpell(text) and storage[ComboPanelName].enabled and storage[ComboPanelName].serverEnabled then
BotServer.send("trigger", "start")
end
end)
onMissle(function(missle)
if storage[ComboPanelName].enabled and storage[ComboPanelName].onShootEnabled then
if not storage[ComboPanelName].shootLeader or storage[ComboPanelName].shootLeader:len() == 0 then
return
end
local src = missle:getSource()
if src.z ~= posz() then
return
end
local from = g_map.getTile(src)
local to = g_map.getTile(missle:getDestination())
if not from or not to then
return
end
local fromCreatures = from:getCreatures()
local toCreatures = to:getCreatures()
if #fromCreatures ~= 1 or #toCreatures ~= 1 then
return
end
local c1 = fromCreatures[1]
local t1 = toCreatures[1]
leaderTarget = t1
if c1:getName():lower() == storage[ComboPanelName].shootLeader:lower() then
if storage[ComboPanelName].attackItemEnabled and storage[ComboPanelName].item and storage[ComboPanelName].item > 100 and findItem(storage[ComboPanelName].item) then
useWith(storage[ComboPanelName].item, t1)
end
if storage[ComboPanelName].attackSpellEnabled and storage[ComboPanelName].spell:len() > 1 then
say(storage[ComboPanelName].spell)
end
end
end
end)
macro(10, function()
if not storage[ComboPanelName].enabled or not storage[ComboPanelName].attackLeaderTargetEnabled then return end
if leaderTarget and storage[ComboPanelName].attack == "LEADER TARGET" then
if not getTarget() or (getTarget() and getTarget():getName() ~= leaderTarget:getName()) then
g_game.attack(leaderTarget)
end
end
if storage[ComboPanelName].enabled and storage[ComboPanelName].serverEnabled and storage[ComboPanelName].attack == "SERVER LEADER TARGET" and serverTarget then
if serverTarget and not getTarget() or (getTarget() and getTarget():getname() ~= serverTarget)
then
g_game.attack(serverTarget)
end
end
end)
local toFollow
local toFollowPos = {}
macro(100, function()
toFollow = nil
if not storage[ComboPanelName].enabled or not storage[ComboPanelName].followLeaderEnabled then return end
if leaderTarget and storage[ComboPanelName].follow == "LEADER TARGET" and leaderTarget:isPlayer() then
toFollow = leaderTarget:getName()
elseif storage[ComboPanelName].follow == "SERVER LEADER TARGET" and storage[ComboPanelName].serverLeader:len() ~= 0 then
toFollow = serverTarget
elseif storage[ComboPanelName].follow == "SERVER LEADER" and storage[ComboPanelName].serverLeader:len() ~= 0 then
toFollow = storage[ComboPanelName].serverLeader
elseif storage[ComboPanelName].follow == "LEADER" then
if storage[ComboPanelName].onSayEnabled and storage[ComboPanelName].sayLeader:len() ~= 0 then
toFollow = storage[ComboPanelName].sayLeader
elseif storage[ComboPanelName].onCastEnabled and storage[ComboPanelName].castLeader:len() ~= 0 then
toFollow = storage[ComboPanelName].castLeader
elseif storage[ComboPanelName].onShootEnabled and storage[ComboPanelName].shootLeader:len() ~= 0 then
toFollow = storage[ComboPanelName].shootLeader
end
end
if not toFollow then return end
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 CaveBot.walkTo(p, 20, {ignoreNonPathable=true, precision=1, ignoreStairs=false}) then
delay(100)
end
end)
onCreaturePositionChange(function(creature, oldPos, newPos)
if creature:getName() == toFollow and newPos then
toFollowPos[newPos.z] = newPos
end
end)
local timeout = now
macro(10, function()
if storage[ComboPanelName].enabled and startCombo then
if storage[ComboPanelName].attackItemEnabled and storage[ComboPanelName].item and storage[ComboPanelName].item > 100 and findItem(storage[ComboPanelName].item) then
useWith(storage[ComboPanelName].item, getTarget())
end
if storage[ComboPanelName].attackSpellEnabled and storage[ComboPanelName].spell:len() > 1 then
say(storage[ComboPanelName].spell)
end
startCombo = false
end
-- attack part / server
if BotServer._websocket and storage[ComboPanelName].enabled and storage[ComboPanelName].serverEnabled then
if target() and now - timeout > 500 then
targetPos = target():getName()
BotServer.send("target", targetPos)
timeout = now
end
end
end)
onUseWith(function(pos, itemId, target, subType)
if BotServer._websocket and itemId == 3155 then
BotServer.send("useWith", target:getPosition())
end
end)
if BotServer._websocket and storage[ComboPanelName].enabled and storage[ComboPanelName].serverEnabled then
BotServer.listen("trigger", function(name, message)
if message == "start" and name:lower() ~= player:getName():lower() and name:lower() == storage[ComboPanelName].serverLeader:lower() and storage[ComboPanelName].serverTriggers then
startCombo = true
end
end)
BotServer.listen("target", function(name, message)
if name:lower() ~= player:getName():lower() and name:lower() == storage[ComboPanelName].serverLeader:lower() then
if not target() or target():getName() == getCreatureByName(message) then
if storage[ComboPanelName].serverLeaderTarget then
serverTarget = getCreatureByName(message)
g_game.attack(getCreatureByName(message))
end
end
end
end)
BotServer.listen("useWith", function(name, message)
local tile = g_map.getTile(message)
if storage[ComboPanelName].serverTriggers and name:lower() ~= player:getName():lower() and name:lower() == storage[ComboPanelName].serverLeader:lower() and storage[ComboPanelName].attackItemEnabled and storage[ComboPanelName].item and findItem(storage[ComboPanelName].item) then
useWith(storage[ComboPanelName].item, tile:getTopUseThing())
end
end)
end

View File

@@ -1,187 +0,0 @@
setDefaultTab("Main")
pushPanelName = "pushmax"
local ui = setupUI([[
Panel
height: 19
BotSwitch
id: title
anchors.top: parent.top
anchors.left: parent.left
text-align: center
width: 130
!text: tr('PUSHMAX')
Button
id: push
anchors.top: prev.top
anchors.left: prev.right
anchors.right: parent.right
margin-left: 3
height: 17
text: Setup
]])
ui:setId(pushPanelName)
if not storage[pushPanelName] then
storage[pushPanelName] = {
enabled = true,
pushDelay = 1060,
pushMaxRuneId = 3188,
mwallBlockId = 2128,
pushMaxKey = "PageUp"
}
end
ui.title:setOn(storage[pushPanelName].enabled)
ui.title.onClick = function(widget)
storage[pushPanelName].enabled = not storage[pushPanelName].enabled
widget:setOn(storage[pushPanelName].enabled)
end
ui.push.onClick = function(widget)
pushWindow:show()
pushWindow:raise()
pushWindow:focus()
end
rootWidget = g_ui.getRootWidget()
if rootWidget then
pushWindow = g_ui.createWidget('PushMaxWindow', rootWidget)
pushWindow:hide()
pushWindow.closeButton.onClick = function(widget)
pushWindow:hide()
end
local updateDelayText = function()
pushWindow.delayText:setText("Push Delay: ".. storage[pushPanelName].pushDelay)
end
updateDelayText()
pushWindow.delay.onValueChange = function(scroll, value)
storage[pushPanelName].pushDelay = value
updateDelayText()
end
pushWindow.delay:setValue(storage[pushPanelName].pushDelay)
pushWindow.runeId.onItemChange = function(widget)
storage[pushPanelName].pushMaxRuneId = widget:getItemId()
end
pushWindow.runeId:setItemId(storage[pushPanelName].pushMaxRuneId)
pushWindow.mwallId.onItemChange = function(widget)
storage[pushPanelName].mwallBlockId = widget:getItemId()
end
pushWindow.mwallId:setItemId(storage[pushPanelName].mwallBlockId)
pushWindow.hotkey.onTextChange = function(widget, text)
storage[pushPanelName].pushMaxKey = text
end
pushWindow.hotkey:setText(storage[pushPanelName].pushMaxKey)
end
function matchPosition(curX, curY, destX, destY)
return (curX == destX and curY == destY)
end
local target
local targetTile
local targetOldPos
macro(10, function()
if not storage[pushPanelName].enabled then return end
if target and targetTile then
if not matchPosition(target:getPosition().x, target:getPosition().y, targetTile:getPosition().x, targetTile:getPosition().y) then
local tile = g_map.getTile(target:getPosition())
targetOldPos = tile:getPosition()
if tile then
if tile:getTopUseThing():isPickupable() or not tile:getTopUseThing():isNotMoveable() then
useWith(tonumber(storage[pushPanelName].pushMaxRuneId), target)
delay(10)
end
if targetTile:getTopThing():getId() == 2129 or targetTile:getTopThing():getId() == 2130 or targetTile:getTopThing():getId() == tonumber(storage[pushPanelName].mwallBlockId) then
if targetTile:getTimer() <= tonumber(storage[pushPanelName].pushDelay) then
info("now")
g_game.move(target, targetTile:getPosition())
tile:setText("")
targetTile:setText("")
target = nil
targetTile = nil
end
else
g_game.move(target, targetTile:getPosition())
delay(1250)
end
end
else
if targetOldPos then
local tile = g_map.getTile(targetOldPos)
if tile then
tile:setText("")
targetTile:setText("")
end
end
target = nil
targetTile = nil
end
end
end)
local resetTimer = now
onKeyDown(function(keys)
if not storage[pushPanelName].enabled then return end
if keys == storage[pushPanelName].pushMaxKey and resetTimer == 0 then
if not target then
local tile = getTileUnderCursor()
if tile and getDistanceBetween(pos(), tile:getPosition()) <= 1 then
if tile:getCreatures()[1] then
target = tile:getCreatures()[1]
tile:setText("PUSH TARGET")
end
end
else
local tile = getTileUnderCursor()
if tile and not tile:getCreatures()[1] then
targetTile = tile
tile:setText("DESTINATION")
end
end
resetTimer = now
end
end)
onKeyPress(function(keys)
if not storage[pushPanelName].enabled then return end
if keys == storage.pushMaxKey and (resetTimer - now) < -10 then
for _, tile in ipairs(g_map.getTiles(posz())) do
if getDistanceBetween(pos(), tile:getPosition()) < 3 then
if tile:getText() ~= "" then
tile:setText("")
end
end
end
target = nil
targetTile = nil
resetTimer = 0
else
resetTimer = 0
end
end)
onCreaturePositionChange(function(creature, newPos, oldPos)
if target and storage[pushPanelName].enabled then
if creature:getName() == target:getName() then
target = nil
targetTile = nil
for _, tile in ipairs(g_map.getTiles(posz())) do
if getDistanceBetween(pos(), tile:getPosition()) < 3 then
if tile:getText() ~= "" then
tile:setText("")
end
end
end
end
end
end)

View File

@@ -1,415 +0,0 @@
setDefaultTab("HP")
storage.lootStatus = ""
healPanelName = "healbot"
local ui = setupUI([[
Panel
height: 19
BotSwitch
id: title
anchors.top: parent.top
anchors.left: parent.left
text-align: center
width: 130
!text: tr('HealBot')
Button
id: combos
anchors.top: prev.top
anchors.left: prev.right
anchors.right: parent.right
margin-left: 3
height: 17
text: Setup
]])
ui:setId(healPanelName)
if not storage[healPanelName] or not storage[healPanelName].spellTable or not storage[healPanelName].itemTable then
storage[healPanelName] = {
enabled = false,
spellTable = {},
itemTable = {}
}
end
ui.title:setOn(storage[healPanelName].enabled)
ui.title.onClick = function(widget)
storage[healPanelName].enabled = not storage[healPanelName].enabled
widget:setOn(storage[healPanelName].enabled)
end
ui.combos.onClick = function(widget)
healWindow:show()
healWindow:raise()
healWindow:focus()
end
rootWidget = g_ui.getRootWidget()
if rootWidget then
healWindow = g_ui.createWidget('HealWindow', rootWidget)
healWindow:hide()
local refreshSpells = function()
if storage[healPanelName].spellTable and #storage[healPanelName].spellTable > 0 then
for i, child in pairs(healWindow.spells.spellList:getChildren()) do
child:destroy()
end
for _, entry in pairs(storage[healPanelName].spellTable) do
local label = g_ui.createWidget("SpellEntry", healWindow.spells.spellList)
label.enabled:setChecked(entry.enabled)
label.enabled.onClick = function(widget)
entry.enabled = not entry.enabled
label.enabled:setChecked(entry.enabled)
end
label.remove.onClick = function(widget)
table.removevalue(storage[healPanelName].spellTable, entry)
reindexTable(storage[healPanelName].spellTable)
label:destroy()
end
label:setText("(MP>" .. entry.cost .. ") " .. entry.origin .. entry.sign .. entry.value .. ":" .. entry.spell)
end
end
end
refreshSpells()
local refreshItems = function()
if storage[healPanelName].itemTable and #storage[healPanelName].itemTable > 0 then
for i, child in pairs(healWindow.items.itemList:getChildren()) do
child:destroy()
end
for _, entry in pairs(storage[healPanelName].itemTable) do
local label = g_ui.createWidget("SpellEntry", healWindow.items.itemList)
label.enabled:setChecked(entry.enabled)
label.enabled.onClick = function(widget)
entry.enabled = not entry.enabled
label.enabled:setChecked(entry.enabled)
end
label.remove.onClick = function(widget)
table.removevalue(storage[healPanelName].itemTable, entry)
reindexTable(storage[healPanelName].itemTable)
label:destroy()
end
label:setText(entry.origin .. entry.sign .. entry.value .. ":" .. entry.item)
end
end
end
refreshItems()
healWindow.spells.MoveUp.onClick = function(widget)
local input = healWindow.spells.spellList:getFocusedChild()
if not input then return end
local index = healWindow.spells.spellList:getChildIndex(input)
if index < 2 then return end
local move
if storage[healPanelName].spellTable and #storage[healPanelName].spellTable > 0 then
for _, entry in pairs(storage[healPanelName].spellTable) do
if entry.index == index -1 then
move = entry
end
if entry.index == index then
move.index = index
entry.index = index -1
end
end
end
table.sort(storage[healPanelName].spellTable, function(a,b) return a.index < b.index end)
healWindow.spells.spellList:moveChildToIndex(input, index - 1)
healWindow.spells.spellList:ensureChildVisible(input)
end
healWindow.spells.MoveDown.onClick = function(widget)
local input = healWindow.spells.spellList:getFocusedChild()
if not input then return end
local index = healWindow.spells.spellList:getChildIndex(input)
if index >= healWindow.spells.spellList:getChildCount() then return end
local move
local move2
if storage[healPanelName].spellTable and #storage[healPanelName].spellTable > 0 then
for _, entry in pairs(storage[healPanelName].spellTable) do
if entry.index == index +1 then
move = entry
end
if entry.index == index then
move2 = entry
end
end
if move and move2 then
move.index = index
move2.index = index + 1
end
end
table.sort(storage[healPanelName].spellTable, function(a,b) return a.index < b.index end)
healWindow.spells.spellList:moveChildToIndex(input, index + 1)
healWindow.spells.spellList:ensureChildVisible(input)
end
healWindow.items.MoveUp.onClick = function(widget)
local input = healWindow.items.itemList:getFocusedChild()
if not input then return end
local index = healWindow.items.itemList:getChildIndex(input)
if index < 2 then return end
local move
if storage[healPanelName].itemTable and #storage[healPanelName].itemTable > 0 then
for _, entry in pairs(storage[healPanelName].itemTable) do
if entry.index == index -1 then
move = entry
end
if entry.index == index then
move.index = index
entry.index = index - 1
end
end
end
table.sort(storage[healPanelName].itemTable, function(a,b) return a.index < b.index end)
healWindow.items.itemList:moveChildToIndex(input, index - 1)
healWindow.items.itemList:ensureChildVisible(input)
end
healWindow.items.MoveDown.onClick = function(widget)
local input = healWindow.items.itemList:getFocusedChild()
if not input then return end
local index = healWindow.items.itemList:getChildIndex(input)
if index >= healWindow.items.itemList:getChildCount() then return end
local move
local move2
if storage[healPanelName].itemTable and #storage[healPanelName].itemTable > 0 then
for _, entry in pairs(storage[healPanelName].itemTable) do
if entry.index == index +1 then
move = entry
end
if entry.index == index then
move2 = entry
end
end
if move and move2 then
move.index = index
move2.index = index + 1
end
end
table.sort(storage[healPanelName].itemTable, function(a,b) return a.index < b.index end)
healWindow.items.itemList:moveChildToIndex(input, index + 1)
healWindow.items.itemList:ensureChildVisible(input)
end
healWindow.spells.addSpell.onClick = function(widget)
local spellFormula = healWindow.spells.spellFormula:getText():trim()
local manaCost = tonumber(healWindow.spells.manaCost:getText())
local spellTrigger = tonumber(healWindow.spells.spellValue:getText())
local spellSource = healWindow.spells.spellSource:getCurrentOption().text
local spellEquasion = healWindow.spells.spellCondition:getCurrentOption().text
local source
local equasion
if not manaCost then
warn("HealBot: incorrect mana cost value!")
healWindow.spells.spellFormula:setText('')
healWindow.spells.spellValue:setText('')
healWindow.spells.manaCost:setText('')
return
end
if not spellTrigger then
warn("HealBot: incorrect condition value!")
healWindow.spells.spellFormula:setText('')
healWindow.spells.spellValue:setText('')
healWindow.spells.manaCost:setText('')
return
end
if spellSource == "Current Mana" then
source = "MP"
elseif spellSource == "Current Health" then
source = "HP"
elseif spellSource == "Mana Percent" then
source = "MP%"
else
source = "HP%"
end
if spellEquasion == "Above" then
equasion = ">"
elseif spellEquasion == "Below" then
equasion = "<"
else
equasion = "="
end
if spellFormula:len() > 0 then
table.insert(storage[healPanelName].spellTable, {index = #storage[healPanelName].spellTable+1, spell = spellFormula, sign = equasion, origin = source, cost = manaCost, value = spellTrigger, enabled = true})
healWindow.spells.spellFormula:setText('')
healWindow.spells.spellValue:setText('')
healWindow.spells.manaCost:setText('')
end
refreshSpells()
end
healWindow.items.addItem.onClick = function(widget)
local id = healWindow.items.itemId:getItemId()
local trigger = tonumber(healWindow.items.itemValue:getText())
local src = healWindow.items.itemSource:getCurrentOption().text
local eq = healWindow.items.itemCondition:getCurrentOption().text
local source
local equasion
if not trigger then
warn("HealBot: incorrect trigger value!")
healWindow.items.itemId:setItemId(0)
healWindow.items.itemValue:setText('')
return
end
if src == "Current Mana" then
source = "MP"
elseif src == "Current Health" then
source = "HP"
elseif src == "Mana Percent" then
source = "MP%"
else
source = "HP%"
end
if eq == "Above" then
equasion = ">"
elseif eq == "Below" then
equasion = "<"
else
equasion = "="
end
if id > 100 then
table.insert(storage[healPanelName].itemTable, {index = #storage[healPanelName].itemTable+1,item = id, sign = equasion, origin = source, value = trigger, enabled = true})
refreshItems()
healWindow.items.itemId:setItemId(0)
healWindow.items.itemValue:setText('')
end
end
healWindow.closeButton.onClick = function(widget)
healWindow:hide()
end
end
-- spells
macro(100, function()
if not storage[healPanelName].enabled or modules.game_cooldown.isGroupCooldownIconActive(2) or #storage[healPanelName].spellTable == 0 then return end
for _, entry in pairs(storage[healPanelName].spellTable) do
if canCast(entry.spell) and entry.enabled then
if entry.origin == "HP%" then
if entry.sign == "=" and hppercent() == entry.value then
say(entry.spell)
return
elseif entry.sign == ">" and hppercent() >= entry.value then
say(entry.spell)
return
elseif entry.sign == "<" and hppercent() <= entry.value then
say(entry.spell)
return
end
elseif entry.origin == "HP" then
if entry.sign == "=" and hp() == entry.value then
say(entry.spell)
return
elseif entry.sign == ">" and hp() >= entry.value then
say(entry.spell)
return
elseif entry.sign == "<" and hp() <= entry.value then
say(entry.spell)
return
end
elseif entry.origin == "MP%" then
if entry.sign == "=" and manapercent() == entry.value then
say(entry.spell)
return
elseif entry.sign == ">" and manapercent() >= entry.value then
say(entry.spell)
return
elseif entry.sign == "<" and manapercent() <= entry.value then
say(entry.spell)
return
end
elseif entry.origin == "MP" then
if entry.sign == "=" and mana() == entry.value then
say(entry.spell)
return
elseif entry.sign == ">" and mana() >= entry.value then
say(entry.spell)
return
elseif entry.sign == "<" and mana() <= entry.value then
say(entry.spell)
return
end
end
end
end
end)
-- items
macro(500, function()
if TargetBot.isOff() then storage.lootStatus = "" end
if not storage[healPanelName].enabled or storage.isUsing or #storage[healPanelName].itemTable == 0 then return end
if storage.lootStatus:len() > 0 then
delay(500)
end
for _, entry in pairs(storage[healPanelName].itemTable) do
local item = findItem(entry.item)
if item and entry.enabled then
if entry.origin == "HP%" then
if entry.sign == "=" and hppercent() == entry.value then
useWith(entry.item, player)
return
elseif entry.sign == ">" and hppercent() >= entry.value then
useWith(entry.item, player)
return
elseif entry.sign == "<" and hppercent() <= entry.value then
useWith(entry.item, player)
return
end
elseif entry.origin == "HP" then
if entry.sign == "=" and hp() == tonumberentry.value then
useWith(entry.item, player)
return
elseif entry.sign == ">" and hp() >= entry.value then
useWith(entry.item, player)
return
elseif entry.sign == "<" and hp() <= entry.value then
useWith(entry.item, player)
return
end
elseif entry.origin == "MP%" then
if entry.sign == "=" and manapercent() == entry.value then
useWith(entry.item, player)
return
elseif entry.sign == ">" and manapercent() >= entry.value then
useWith(entry.item, player)
return
elseif entry.sign == "<" and manapercent() <= entry.value then
useWith(entry.item, player)
return
end
elseif entry.origin == "MP" then
if entry.sign == "=" and mana() == entry.value then
useWith(entry.item, player)
return
elseif entry.sign == ">" and mana() >= entry.value then
useWith(entry.item, player)
return
elseif entry.sign == "<" and mana() <= entry.value then
useWith(entry.item, player)
return
end
end
end
end
end)

View File

@@ -1,124 +0,0 @@
setDefaultTab("Main")
local panelName = "advancedFriendHealer"
local ui = setupUI([[
Panel
height: 19
BotSwitch
id: title
anchors.top: parent.top
anchors.left: parent.left
text-align: center
width: 130
!text: tr('Friend Healer')
Button
id: editList
anchors.top: prev.top
anchors.left: prev.right
anchors.right: parent.right
margin-left: 3
height: 17
text: Setup
]], parent)
ui:setId(panelName)
if not storage[panelName] then
storage[panelName] = {
minMana = 60,
minFriendHp = 40,
spellName = "exura sio",
spellHeal = true,
distance = 8,
itemHeal = true,
id = 3160
}
end
rootWidget = g_ui.getRootWidget()
sioListWindow = g_ui.createWidget('SioListWindow', rootWidget)
sioListWindow:hide()
ui.title:setOn(storage[panelName].enabled)
sioListWindow.spell:setOn(storage[panelName].spellHeal)
sioListWindow.item:setOn(storage[panelName].itemHeal)
ui.title.onClick = function(widget)
storage[panelName].enabled = not storage[panelName].enabled
widget:setOn(storage[panelName].enabled)
end
ui.editList.onClick = function(widget)
sioListWindow:show()
sioListWindow:raise()
sioListWindow:focus()
end
sioListWindow.spell.onClick = function(widget)
storage[panelName].spellHeal = not storage[panelName].spellHeal
widget:setOn(storage[panelName].spellHeal)
end
sioListWindow.item.onClick = function(widget)
storage[panelName].itemHeal = not storage[panelName].itemHeal
widget:setOn(storage[panelName].itemHeal)
end
sioListWindow.closeButton.onClick = function(widget)
sioListWindow:hide()
end
sioListWindow.spellName.onTextChange = function(widget, text)
storage[panelName].spellName = text
end
local updateMinManaText = function()
sioListWindow.manaInfo:setText("Minimum Mana >= " .. storage[panelName].minMana .. "%")
end
local updateFriendHpText = function()
sioListWindow.friendHp:setText("Heal Friend Below " .. storage[panelName].minFriendHp .. "% hp")
end
local updateDistanceText = function()
sioListWindow.distText:setText("Max Distance: " .. storage[panelName].distance)
end
sioListWindow.Distance.onValueChange = function(scroll, value)
storage[panelName].distance = value
updateDistanceText()
end
updateDistanceText()
sioListWindow.minMana.onValueChange = function(scroll, value)
storage[panelName].minMana = value
updateMinManaText()
end
sioListWindow.minFriendHp.onValueChange = function(scroll, value)
storage[panelName].minFriendHp = value
updateFriendHpText()
end
sioListWindow.itemId:setItemId(storage[panelName].id)
sioListWindow.itemId.onItemChange = function(widget)
storage[panelName].id = widget:getItemId()
end
sioListWindow.spellName:setText(storage[panelName].spellName)
sioListWindow.minMana:setValue(storage[panelName].minMana)
sioListWindow.minFriendHp:setValue(storage[panelName].minFriendHp)
sioListWindow.Distance:setValue(storage[panelName].distance)
local healItem
macro(200, function()
if storage[panelName].enabled and storage[panelName].spellName:len() > 0 and manapercent() > storage[panelName].minMana then
for _, spec in ipairs(getSpectators()) do
if not spec:isLocalPlayer() then
if spec:isPlayer() and storage[panelName].minFriendHp >= spec:getHealthPercent() and isFriend(spec:getName()) then
if storage[panelName].spellHeal then
saySpell(storage[panelName].spellName .. ' "' .. spec:getName(), 100)
return
end
healItem = findItem(storage[panelName].id)
if storage[panelName].itemHeal and distanceFromPlayer(spec:getPosition()) <= storage[panelName].distance and healItem then
useWith(storage[panelName].id, spec)
return
end
end
end
end
end
end)
addSeparator()

View File

@@ -1,150 +0,0 @@
local listPanelName = "playerList"
local ui = setupUI([[
Panel
height: 18
Button
id: editList
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
height: 18
text: Player Lists
]], parent)
ui:setId(listPanelName)
if not storage[listPanelName] then
storage[listPanelName] = {
enemyList = {},
friendList = {},
groupMembers = true,
outfits = false,
marks = false
}
end
rootWidget = g_ui.getRootWidget()
playerListWindow = g_ui.createWidget('PlayerListsWindow', rootWidget)
playerListWindow:hide()
playerListWindow.Members:setOn(storage[listPanelName].groupMembers)
playerListWindow.Members.onClick = function(widget)
storage[listPanelName].groupMembers = not storage[listPanelName].groupMembers
widget:setOn(storage[listPanelName].groupMembers)
end
playerListWindow.Outfit:setOn(storage[listPanelName].outfits)
playerListWindow.Outfit.onClick = function(widget)
storage[listPanelName].outfits = not storage[listPanelName].outfits
widget:setOn(storage[listPanelName].outfits)
end
playerListWindow.Marks:setOn(storage[listPanelName].marks)
playerListWindow.Marks.onClick = function(widget)
storage[listPanelName].marks = not storage[listPanelName].marks
widget:setOn(storage[listPanelName].marks)
end
if storage[listPanelName].enemyList and #storage[listPanelName].enemyList > 0 then
for _, name in ipairs(storage[listPanelName].enemyList) do
local label = g_ui.createWidget("PlayerName", playerListWindow.EnemyList)
label.remove.onClick = function(widget)
table.removevalue(storage[listPanelName].enemyList, label:getText())
label:destroy()
end
label:setText(name)
end
end
playerListWindow.AddFriend.onClick = function(widget)
local friendName = playerListWindow.FriendName:getText()
if friendName:len() > 0 and not table.contains(storage[listPanelName].enemyList, friendName, true) then
table.insert(storage[listPanelName].enemyList, friendName)
local label = g_ui.createWidget("PlayerName", playerListWindow.EnemyList)
label.remove.onClick = function(widget)
table.removevalue(storage[listPanelName].enemyList, label:getText())
label:destroy()
end
label:setText(friendName)
playerListWindow.FriendName:setText('')
end
end
if storage[listPanelName].friendList and #storage[listPanelName].friendList > 0 then
for _, name in ipairs(storage[listPanelName].friendList) do
local label = g_ui.createWidget("PlayerName", playerListWindow.FriendList)
label.remove.onClick = function(widget)
table.removevalue(storage[listPanelName].friendList, label:getText())
label:destroy()
end
label:setText(name)
end
end
playerListWindow.AddFriend.onClick = function(widget)
local friendName = playerListWindow.FriendName:getText()
if friendName:len() > 0 and not table.contains(storage[listPanelName].friendList, friendName, true) then
table.insert(storage[listPanelName].friendList, friendName)
local label = g_ui.createWidget("PlayerName", playerListWindow.FriendList)
label.remove.onClick = function(widget)
table.removevalue(storage[listPanelName].friendList, label:getText())
label:destroy()
end
label:setText(friendName)
playerListWindow.FriendName:setText('')
end
end
playerListWindow.AddEnemy.onClick = function(widget)
local enemyName = playerListWindow.EnemyName:getText()
if enemyName:len() > 0 and not table.contains(storage[listPanelName].enemyList, enemyName, true) then
table.insert(storage[listPanelName].enemyList, enemyName)
local label = g_ui.createWidget("PlayerName", playerListWindow.EnemyList)
label.remove.onClick = function(widget)
table.removevalue(storage[listPanelName].enemyList, label:getText())
label:destroy()
end
label:setText(enemyName)
playerListWindow.EnemyName:setText('')
end
end
ui.editList.onClick = function(widget)
playerListWindow:show()
playerListWindow:raise()
playerListWindow:focus()
end
playerListWindow.closeButton.onClick = function(widget)
playerListWindow:hide()
end
function refreshStatus()
for _, spec in ipairs(getSpectators()) do
if spec:isPlayer() and not spec:isLocalPlayer() then
if storage[listPanelName].outfits then
specOutfit = spec:getOutfit()
if isEnemy(spec:getName()) then
specOutfit.head = 112
specOutfit.body = 112
specOutfit.legs = 112
specOutfit.feet = 112
spec:setOutfit(specOutfit)
elseif isFriend(spec:getName()) then
specOutfit.head = 88
specOutfit.body = 88
specOutfit.legs = 88
specOutfit.feet = 88
spec:setOutfit(specOutfit)
end
end
end
end
end
refreshStatus()
onCreatureAppear(function(creature)
if creature:isPlayer() then
refreshStatus()
end
end)
addSeparator()

View File

@@ -1,764 +0,0 @@
-- if you want to change tab, in line below insert: setDefaultTab("tab name")
attackPanelName = "attackbot"
local ui = setupUI([[
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: mode
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.horizontalCenter
text: Mode: PVP
margin-right: 2
margin-top: 4
font: cipsoftFont
height: 17
Button
id: safe
anchors.top: settings.bottom
anchors.left: parent.horizontalCenter
anchors.right: parent.right
text: PVP Safe
margin-left: 2
margin-top: 4
height: 17
font:cipsoftFont
]])
ui:setId(attackPanelName)
local i = 1
local j = 1
local k = 1
local pvpDedicated = false
local item = false
if not storage[attackPanelName] or not storage[attackPanelName].attackTable then
storage[attackPanelName] = {
pvpMode = false,
pvpSafe = true,
enabled = false,
attackTable = {},
ignoreMana = true
}
end
local categories = {
"Select Category",
"Area Spell (exevo mas san, exevo gran mas flam etc.)",
"Adjacent (exori, exori gran)",
"Front Sweep (exori min)",
"Wave (exevo tera hur, exevo gran vis lux)",
"Targeted Spell (exori ico, exori flam etc.)",
"Targeted Rune (sudden death, heavy magic missle etc.)",
"Area Rune (great fireball, avalanche etc.)",
"Empowerment (utito tempo)"
}
local labels = {
"",
"Area Spell",
"Adjacent",
"Front Sweep",
"Wave",
"Targeted Spell",
"Targeted Rune",
"Area Rune",
"Buff"
}
local range = {
"Select Range",
"Range: 1",
"Range: 2",
"Range: 3",
"Range: 4",
"Range: 5",
"Range: 6",
"Range: 7",
"Range: 8",
"Range: 9"
}
local pattern = {
"Pattern",
"Single (exori frigo, SD)",
"Large AOE (mas tera)",
"Medium AOE (mas frigo)",
"Small AOE (mas san)",
"Large Wave (tera hur)",
"Medium Wave (frigo hur)",
"Small Wave (gran frigo hur)",
"Beam (exevo vis lux)",
"Adjacent (exori)",
"Area Rune (GFB, AVA)",
"Empowerment"
}
local updateModeText = function()
local text
if storage[attackPanelName].pvpMode then
text = "PVP"
ui.mode:setColor("yellow")
else
text = "HUNT"
ui.mode:setColor("green")
end
ui.mode:setText("MODE: " .. text)
end
updateModeText()
local updatePvpColor = function()
if storage[attackPanelName].pvpSafe then
ui.safe:setColor("green")
else
ui.safe:setColor("white")
end
end
updatePvpColor()
ui.title:setOn(storage[attackPanelName].enabled)
ui.title.onClick = function(widget)
storage[attackPanelName].enabled = not storage[attackPanelName].enabled
widget:setOn(storage[attackPanelName].enabled)
end
ui.mode.onClick = function(widget)
storage[attackPanelName].pvpMode = not storage[attackPanelName].pvpMode
updateModeText()
end
ui.safe.onClick = function(widget)
storage[attackPanelName].pvpSafe = not storage[attackPanelName].pvpSafe
updatePvpColor()
end
ui.settings.onClick = function(widget)
attackWindow:show()
attackWindow:raise()
attackWindow:focus()
end
rootWidget = g_ui.getRootWidget()
if rootWidget then
attackWindow = g_ui.createWidget('AttackWindow', rootWidget)
attackWindow:hide()
-- functions
local updateCategoryText = function()
attackWindow.category:setText(categories[i])
end
updateCategoryText()
local updateParameter1Text = function()
attackWindow.parameter1:setText(pattern[k])
end
updateParameter1Text()
local updateParameter2Text = function()
attackWindow.parameter2:setText(range[j])
end
updateParameter2Text()
-- checkbox
attackWindow.pvpSpell.onClick = function(widget)
pvpDedicated = not pvpDedicated
attackWindow.pvpSpell:setChecked(pvpDedicated)
end
attackWindow.IgnoreMana:setChecked(storage[attackPanelName].ignoreMana)
attackWindow.IgnoreMana.onClick = function(widget)
storage[attackPanelName].ignoreMana = not storage[attackPanelName].ignoreMana
attackWindow.IgnoreMana:setChecked(storage[attackPanelName].ignoreMana)
end
--buttons
attackWindow.CloseButton.onClick = function(widget)
attackWindow:hide()
end
local inputTypeToggle = function()
if attackWindow.category:getText():lower():find("rune") then
item = true
attackWindow.spellFormula:setText("")
attackWindow.spellFormula:hide()
attackWindow.spellDescription:hide()
attackWindow.itemId:show()
attackWindow.itemDescription:show()
else
item = false
attackWindow.itemId:setItemId(0)
attackWindow.itemId:hide()
attackWindow.itemDescription:hide()
attackWindow.spellFormula:show()
attackWindow.spellDescription:show()
end
end
inputTypeToggle()
attackWindow.categoryNext.onClick = function(widget)
if i == #categories then
i = 1
else
i = i + 1
end
updateCategoryText()
inputTypeToggle()
end
attackWindow.categoryPrev.onClick = function(widget)
if i == 1 then
i = #categories
else
i = i - 1
end
updateCategoryText()
inputTypeToggle()
end
attackWindow.parameter1Next.onClick = function(widget)
if k == #pattern then
k = 1
else
k = k + 1
end
updateParameter1Text()
end
attackWindow.parameter1Prev.onClick = function(widget)
if k == 1 then
k = #pattern
else
k = k - 1
end
updateParameter1Text()
end
attackWindow.parameter2Next.onClick = function(widget)
if j == #range then
j = 1
else
j = j + 1
end
updateParameter2Text()
end
attackWindow.parameter2Prev.onClick = function(widget)
if j == 1 then
j = #range
else
j = j - 1
end
updateParameter2Text()
end
local validVal = function(v)
if type(v) ~= "number" then
local val = tonumber(v)
if not val then return false end
end
if v >= 0 and v < 101 then
return true
else
return false
end
end
local clearValues = function()
attackWindow.spellFormula:setText("")
attackWindow.minMana:setText("")
attackWindow.minMonsters:setText("")
attackWindow.itemId:setItemId(0)
pvpDedicated = false
item = false
attackWindow.pvpSpell:setChecked(false)
i = 1
j = 1
k = 1
updateParameter1Text()
updateParameter2Text()
updateCategoryText()
inputTypeToggle()
end
local refreshAttacks = function()
if storage[attackPanelName].attackTable and #storage[attackPanelName].attackTable > 0 then
for i, child in pairs(attackWindow.attackList:getChildren()) do
child:destroy()
end
for _, entry in pairs(storage[attackPanelName].attackTable) do
local label = g_ui.createWidget("AttackEntry", attackWindow.attackList)
label.enabled:setChecked(entry.enabled)
label.enabled.onClick = function(widget)
entry.enabled = not entry.enabled
label.enabled:setChecked(entry.enabled)
end
label.remove.onClick = function(widget)
table.removevalue(storage[attackPanelName].attackTable, entry)
reindexTable(storage[attackPanelName].attackTable)
label:destroy()
end
if entry.pvp then
label:setText("(" .. entry.manaCost .. "% MP) " .. labels[entry.category] .. ": " .. entry.attack .. " (Range: ".. entry.dist .. ")")
label:setColor("yellow")
else
label:setText("(" .. entry.manaCost .. "% MP & mob >= " .. entry.minMonsters .. ") " .. labels[entry.category] .. ": " .. entry.attack .. " (Range: ".. entry.dist .. ")")
label:setColor("green")
end
end
end
end
refreshAttacks()
attackWindow.MoveUp.onClick = function(widget)
local input = attackWindow.attackList:getFocusedChild()
if not input then return end
local index = attackWindow.attackList:getChildIndex(input)
if index < 2 then return end
local move
if storage[attackPanelName].attackTable and #storage[attackPanelName].attackTable > 0 then
for _, entry in pairs(storage[attackPanelName].attackTable) do
if entry.index == index -1 then
move = entry
end
if entry.index == index then
move.index = index
entry.index = index -1
end
end
end
table.sort(storage[attackPanelName].attackTable, function(a,b) return a.index < b.index end)
attackWindow.attackList:moveChildToIndex(input, index - 1)
attackWindow.attackList:ensureChildVisible(input)
end
attackWindow.MoveDown.onClick = function(widget)
local input = attackWindow.attackList:getFocusedChild()
if not input then return end
local index = attackWindow.attackList:getChildIndex(input)
if index >= attackWindow.attackList:getChildCount() then return end
local move
local move2
if storage[attackPanelName].attackTable and #storage[attackPanelName].attackTable > 0 then
for _, entry in pairs(storage[attackPanelName].attackTable) do
if entry.index == index +1 then
move = entry
end
if entry.index == index then
move2 = entry
end
end
if move and move2 then
move.index = index
move2.index = index + 1
end
end
table.sort(storage[attackPanelName].attackTable, function(a,b) return a.index < b.index end)
attackWindow.attackList:moveChildToIndex(input, index + 1)
attackWindow.attackList:ensureChildVisible(input)
end
attackWindow.addButton.onClick = function(widget)
local val
if (item and attackWindow.itemId:getItemId() <= 100) or (not item and attackWindow.spellFormula:getText():len() == 0) then
warn("AttackBot: missing spell or item id!")
elseif not tonumber(attackWindow.minMana:getText()) or not validVal(tonumber(attackWindow.minMana:getText())) then
warn("AttackBot: Mana Values incorrect! it has to be number from between 1 and 100")
elseif not tonumber(attackWindow.minMonsters:getText()) or not validVal(tonumber(attackWindow.minMonsters:getText())) then
warn("AttackBot: Monsters Count incorrect! it has to be number higher than 0")
elseif i == 1 or j == 1 or k == 1 then
warn("AttackBot: Categories not changed! You need to be more precise")
else
if item then
val = attackWindow.itemId:getItemId()
else
val = attackWindow.spellFormula:getText()
end
table.insert(storage[attackPanelName].attackTable, {index = #storage[attackPanelName].attackTable+1, attack = val, manaCost = tonumber(attackWindow.minMana:getText()), minMonsters = tonumber(attackWindow.minMonsters:getText()), pvp = pvpDedicated, dist = j-1, model = k, category = i, enabled = true})
refreshAttacks()
clearValues()
end
end
end
-- executor
-- table example (attack = 3155, manaCost = 50(%), minMonsters = 5, pvp = true, dist = 3, model = 6, category = 3)
-- i = category
-- j = range
-- k = pattern - covered
local patterns = {
"",
"",
[[
0000001000000
0000011100000
0000111110000
0001111111000
0011111111100
0111111111110
1111111111111
0111111111110
0011111111100
0001111111000
0000111110000
0000011100000
0000001000000
]],
[[
00000100000
00011111000
00111111100
01111111110
01111111110
11111111111
01111111110
01111111110
00111111100
00001110000
00000100000
]],
[[
0011100
0111110
1111111
1111111
1111111
0111110
0011100
]],
[[
0000NNN0000
0000NNN0000
0000NNN0000
00000N00000
WWW00N00EEE
WWWWW0EEEEE
WWW00S00EEE
00000S00000
0000SSS0000
0000SSS0000
0000SSS0000
]],
[[
000NNNNN000
000NNNNN000
0000NNN0000
WW00NNN00EE
WWWW0N0EEEE
WWWWW0EEEEE
WWWW0S0EEEE
WW00SSS00EE
0000SSS0000
000SSSSS000
000SSSSS000
]],
[[
00NNN00
00NNN00
WW0N0EE
WWW0EEE
WW0S0EE
00SSS00
00SSS00
]],
[[
0000000N0000000
0000000N0000000
0000000N0000000
0000000N0000000
0000000N0000000
0000000N0000000
0000000N0000000
WWWWWWW0EEEEEEE
0000000S0000000
0000000S0000000
0000000S0000000
0000000S0000000
0000000S0000000
0000000S0000000
0000000S0000000
]],
"",
""
}
local safePatterns = {
"",
"",
[[
000000010000000
000000111000000
000001111100000
000011111110000
000111111111000
001111111111100
011111111111110
111111111111111
011111111111110
001111111111100
000111111111000
000011111110000
000001111100000
000000111000000
000000010000000
]],
[[
0000011100000
0000111110000
0001111111000
0011111111100
0111111111110
0111111111110
1111111111111
0111111111110
0111111111110
0011111111100
0001111111000
0000111110000
0000011100000
]],
[[
000111000
001111100
011111110
111111111
111111111
111111111
011111110
001111100
000111000
]],
[[
0000NNNNN0000
0000NNNNN0000
0000NNNNN0000
0000NNNNN0000
WWWW0NNN0EEEE
WWWWWNNNEEEEE
WWWWWW0EEEEEE
WWWWWSSSEEEEE
WWWW0SSS0EEEE
0000SSSSS0000
0000SSSSS0000
0000SSSSS0000
0000SSSSS0000
]],
[[
000NNNNNNN000
000NNNNNNN000
000NNNNNNN000
WWWWNNNNNEEEE
WWWWNNNNNEEEE
WWWWWNNNEEEEE
WWWWWW0EEEEEE
WWWWWSSSEEEEE
WWWWSSSSSEEEE
WWWWSSSSSEEEE
000SSSSSSS000
000SSSSSSS000
000SSSSSSS000
]],
[[
00NNNNN00
00NNNNN00
WWNNNNNEE
WWWWNEEEE
WWWW0EEEE
WWWWSEEEE
WWSSSSSEE
00SSSSS00
00SSSSS00
]],
[[
0000000NNN0000000
0000000NNN0000000
0000000NNN0000000
0000000NNN0000000
0000000NNN0000000
0000000NNN0000000
0000000NNN0000000
WWWWWWWNNNEEEEEEE
WWWWWWWW0EEEEEEEE
WWWWWWWSSSEEEEEEE
0000000SSS0000000
0000000SSS0000000
0000000SSS0000000
0000000SSS0000000
0000000SSS0000000
0000000SSS0000000
0000000SSS0000000
]],
"",
""
}
local posN = [[
111
000
000
]]
local posE = [[
001
001
001
]]
local posS = [[
000
000
111
]]
local posW = [[
100
100
100
]]
local bestTile
macro(100, function()
if not storage[attackPanelName].enabled then return end
if #storage[attackPanelName].attackTable == 0 or isInPz() or not target() or modules.game_cooldown.isGroupCooldownIconActive(1) then return end
local monstersN = 0
local monstersE = 0
local monstersS = 0
local monstersW = 0
monstersN = getCreaturesInArea(pos(), posN, 2)
monstersE = getCreaturesInArea(pos(), posE, 2)
monstersS = getCreaturesInArea(pos(), posS, 2)
monstersW = getCreaturesInArea(pos(), posW, 2)
local posTable = {monstersE, monstersN, monstersS, monstersW}
local bestSide = 0
local bestDir
-- pulling out the biggest number
for i, v in pairs(posTable) do
if v > bestSide then
bestSide = v
end
end
-- associate biggest number with turn direction
if monstersN == bestSide then bestDir = 0
elseif monstersE == bestSide then bestDir = 1
elseif monstersS == bestSide then bestDir = 2
elseif monstersW == bestSide then bestDir = 3
end
if player:getDirection() ~= bestDir and bestSide > 0 then
turn(bestDir)
end
for _, entry in pairs(storage[attackPanelName].attackTable) do
if entry.enabled then
if (type(entry.attack) == "string" and canCast(entry.attack, not storage[attackPanelName].ignoreMana)) or (type(entry.attack) == "number" and findItem(entry.attack)) then
if manapercent() >= entry.manaCost and distanceFromPlayer(target():getPosition()) <= entry.dist then
if storage[attackPanelName].pvpMode then
if entry.pvp then
if type(entry.attack) == "string" and target():canShoot() then
say(entry.attack)
return
else
if not storage.isUsing and target():canShoot() then
useWith(entry.attack, target())
return
end
end
end
else
if entry.category == 6 or entry.category == 7 then
if getMonsters(4) >= entry.minMonsters then
if type(entry.attack) == "number" then
if not storage.isUsing then
useWith(entry.attack, target())
return
end
else
say(entry.attack)
return
end
end
else
if killsToRs() > 2 then
if entry.category == 8 then
bestTile = getBestTileByPatern(patterns[5], 2, entry.dist, storage[attackPanelName].pvpSafe)
end
if entry.category == 4 and (not storage[attackPanelName].pvpSafe or isSafe(2, false)) and bestSide >= entry.minMonsters then
say(entry.attack)
return
elseif entry.category == 3 and (not storage[attackPanelName].pvpSafe or isSafe(2, false)) and getMonsters(1) >= entry.minMonsters then
say(entry.attack)
return
elseif entry.category == 5 and getCreaturesInArea(player, patterns[entry.model], 2) >= entry.minMonsters and (not storage[attackPanelName].pvpSafe or getCreaturesInArea(player, safePatterns[entry.model], 3) == 0) then
say(entry.attack)
return
elseif entry.category == 2 and getCreaturesInArea(pos(), patterns[entry.model], 2) >= entry.minMonsters and (not storage[attackPanelName].pvpSafe or getCreaturesInArea(pos(), safePatterns[entry.model], 3) == 0) then
say(entry.attack)
return
elseif entry.category == 8 and bestTile and bestTile.count >= entry.minMonsters then
if not storage.isUsing then
useWith(entry.attack, bestTile.pos:getTopUseThing())
end
return
elseif entry.category == 9 and not isBuffed() and getMonsters(entry.dist) >= entry.minMonsters then
say(entry.attack)
return
else
if entry.category == 6 or entry.category == 7 then
if getMonsters(4) >= entry.minMonsters then
if type(entry.attack) == "number" then
if not storage.isUsing then
useWith(entry.attack, target())
return
end
else
say(entry.attack)
return
end
end
end
end
else
if entry.category == 6 or entry.category == 7 then
if getMonsters(4) >= entry.minMonsters then
if type(entry.attack) == "number" then
if not storage.isUsing then
useWith(entry.attack, target())
return
end
else
say(entry.attack)
return
end
end
end
end
end
end
end
end
end
end
end)

View File

@@ -1,242 +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: 520 350
@onEscape: self:hide()
TextList
id: attackList
anchors.left: parent.left
anchors.right: parent.right
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: 27
margin-left: 5
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: 20
margin-left: 5
Label
id: itemDescription
anchors.left: itemId.right
margin-left: 5
anchors.verticalCenter: itemId.verticalCenter
text: < insert id or drag item here
Label
anchors.left: parameter2Prev.left
anchors.top: parameter2Prev.bottom
margin-top: 10
text-align: center
text: Min Monsters:
TextEdit
id: minMonsters
anchors.left: prev.right
anchors.verticalCenter: prev.verticalCenter
margin-left: 5
width: 30
Label
anchors.left: parameter2Prev.left
anchors.top: prev.bottom
margin-top: 10
text-align: center
text: Min Mana%:
TextEdit
id: minMana
anchors.left: minMonsters.left
anchors.verticalCenter: prev.verticalCenter
width: 30
CheckBox
id: pvpSpell
anchors.right: minMana.right
anchors.top: minMana.bottom
width: 100
margin-left: 30
margin-top: 6
text: Spell for PVP
Button
id: addButton
anchors.right: CloseButton.right
anchors.bottom: BottomSeparator.top
text-align: center
text: Add
margin-bottom: 10
size: 80 20
margin-right: 15
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
CheckBox
id: IgnoreMana
anchors.verticalCenter: CloseButton.verticalCenter
anchors.left: parent.left
margin-left: 5
width: 250
text: Check RL Tibia mana cost
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

@@ -1,145 +0,0 @@
BotServerData < Panel
size: 340 70
image-source: /images/ui/window
image-border: 6
padding: 3
Label
id: label
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
text-align: center
!text: tr("BotServer Data")
Label
id: label
anchors.top: parent.top
anchors.left: parent.left
margin-top: 23
text-align: center
text: Channel Name:
margin-left: 6
TextEdit
id: Channel
anchors.top: parent.top
anchors.left: prev.right
margin-top: 20
width: 150
margin-left: 5
text-align: center
Button
id: Random
anchors.left: prev.right
anchors.top: prev.top
anchors.right: parent.right
text-align: center
text: Randomize
margin-left: 6
margin-right: 6
Label
id: label
anchors.left: parent.left
anchors.bottom: parent.bottom
margin-left: 6
margin-bottom: 4
text-align: center
text: Status:
BotLabel
id: ServerStatus
anchors.left: prev.right
anchors.bottom: parent.bottom
margin-left: 10
margin-bottom: 4
text-align: center
text: CONNECTED
BotLabel
id: Participants
anchors.right: parent.right
anchors.bottom: parent.bottom
margin-right: 8
margin-bottom: 4
text-align: center
Label
id: label
anchors.right: Participants.left
anchors.bottom: parent.bottom
margin-right: 10
margin-bottom: 4
text-align: center
text: Members:
FeaturePanel < Panel
size: 340 150
image-source: /images/ui/panel_flat
image-border: 5
padding: 3
Label
id: title
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
text-align: center
text: Features
HorizontalSeparator
id: sep
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 2
BotSwitch
id: Feature1
anchors.top: prev.bottom
anchors.left: parent.left
margin-left: 3
margin-top: 5
text: Mana info
BotSwitch
id: Feature2
anchors.top: sep.bottom
anchors.left: prev.right
margin-top: 5
margin-left: 5
text: MWall info
BotServerWindow < MainWindow
!text: tr('BotServer')
size: 370 310
@onEscape: self:hide()
BotServerData
id: Data
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
FeaturePanel
id: Features
anchors.top: prev.bottom
anchors.horizontalCenter: parent.horizontalCenter
margin-top: 10
HorizontalSeparator
id: separator
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

Some files were not shown because too many files have changed in this diff Show More