Updated to OTCv8 3.0 rev 83

This commit is contained in:
OTCv8
2021-05-26 23:26:45 +00:00
parent f769ffeda1
commit 86036d71f1
86 changed files with 1105 additions and 622 deletions

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -0,0 +1,203 @@
setDefaultTab("Main")
local panelName = "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(panelName)
if not storage[panelName] then
storage[panelName] = {
manaInfo = true,
mwallInfo = true,
vocation = true,
outfit = false,
broadcasts = true
}
end
local config = storage[panelName]
if not storage.BotServerChannel then
storage.BotServerChannel = tostring(math.random(1000000000000,9999999999999))
end
local channel = tostring(storage.BotServerChannel)
BotServer.init(name(), channel)
BotServerMembers = {}
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(config.manaInfo)
botServerWindow.Features.Feature1.onClick = function(widget)
config.manaInfo = not config.manaInfo
widget:setOn(config.manaInfo)
end
botServerWindow.Features.Feature2:setOn(config.mwallInfo)
botServerWindow.Features.Feature2.onClick = function(widget)
config.mwallInfo = not config.mwallInfo
widget:setOn(config.mwallInfo)
end
botServerWindow.Features.Feature3:setOn(config.vocation)
botServerWindow.Features.Feature3.onClick = function(widget)
config.vocation = not config.vocation
if config.vocation then
BotServer.send("voc", player:getVocation())
end
widget:setOn(config.vocation)
end
botServerWindow.Features.Feature4:setOn(config.outfit)
botServerWindow.Features.Feature4.onClick = function(widget)
config.outfit = not config.outfit
widget:setOn(config.outfit)
end
botServerWindow.Features.Feature5:setOn(config.broadcasts)
botServerWindow.Features.Feature5.onClick = function(widget)
config.broadcasts = not config.broadcasts
widget:setOn(config.broadcasts)
end
botServerWindow.Features.Broadcast.onClick = function(widget)
if BotServer._websocket then
BotServer.send("broadcast", botServerWindow.Features.broadcastText:getText())
end
botServerWindow.Features.broadcastText:setText('')
end
end
function updateStatusText()
if BotServer._websocket then
botServerWindow.Data.ServerStatus:setText("CONNECTED")
if serverCount then
botServerWindow.Data.Members:setText("Members: "..#serverCount)
if ServerMembers then
local text = ""
local regex = [["([a-z 'A-z-]*)"*]]
local re = regexMatch(ServerMembers, regex)
--re[name][2]
for i=1,#re do
if i == 1 then
text = re[i][2]
else
text = text .. "\n" .. re[i][2]
end
end
botServerWindow.Data.Members:setTooltip(text)
end
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)
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
-- mwalls
config.mwalls = {}
BotServer.listen("mwall", function(name, message)
if config.mwallInfo then
if not config.mwalls[message["pos"]] or config.mwalls[message["pos"]] < now then
config.mwalls[message["pos"]] = now + message["duration"] - 150 -- 150 is latency correction
end
end
end)
onAddThing(function(tile, thing)
if config.mwallInfo then
if thing:isItem() and thing:getId() == 2129 then
local pos = tile:getPosition().x .. "," .. tile:getPosition().y .. "," .. tile:getPosition().z
if not config.mwalls[pos] or config.mwalls[pos] < now then
config.mwalls[pos] = now + 20000
BotServer.send("mwall", {pos=pos, duration=20000})
end
end
end
end)
-- mana
local lastMana = 0
macro(100, function()
if config.manaInfo then
if manapercent() ~= lastMana then
lastMana = manapercent()
BotServer.send("mana", {mana=lastMana})
end
end
end)
BotServer.listen("mana", function(name, message)
if config.manaInfo then
local creature = getPlayerByName(name)
if creature then
creature:setManaPercent(message["mana"])
end
end
end)
-- vocation
if config.vocation then
BotServer.send("voc", player:getVocation())
BotServer.send("voc", "yes")
end
BotServer.listen("voc", function(name, message)
if message == "yes" and config.vocation then
BotServer.send("voc", player:getVocation())
else
BotServerMembers[name] = message
end
end)
-- broadcast
BotServer.listen("broadcast", function(name, message)
if config.broadcasts then
broadcastMessage(name..": "..message)
end
end)
addSeparator()

View File

@@ -0,0 +1,188 @@
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
UIWidget
id: Members
anchors.right: Participants.left
anchors.bottom: parent.bottom
size: 80 21
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
BotSwitch
id: Feature3
anchors.top: sep.bottom
anchors.left: prev.right
margin-top: 5
margin-left: 5
text: Send Vocation
BotSwitch
id: Feature4
anchors.top: prev.bottom
anchors.left: parent.left
margin-top: 3
margin-left: 3
text: Outfit Vocation
BotSwitch
id: Feature5
anchors.bottom: prev.bottom
anchors.left: prev.right
margin-top: 3
margin-left: 5
text: Broadcasts
TextEdit
id: broadcastText
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-left: 3
margin-bottom: 3
margin-right: 80
Button
id: Broadcast
anchors.top: prev.top
anchors.left: prev.right
anchors.right: parent.right
margin-right: 3
margin-left: 3
height: 22
text: Broadcast
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

View File

@@ -0,0 +1,247 @@
setDefaultTab("HP")
local conditionPanelName = "ConditionPanel"
local ui = setupUI([[
Panel
height: 19
BotSwitch
id: title
anchors.top: parent.top
anchors.left: parent.left
text-align: center
width: 130
!text: tr('Conditions')
Button
id: conditionList
anchors.top: prev.top
anchors.left: prev.right
anchors.right: parent.right
margin-left: 3
height: 17
text: Setup
]])
ui:setId(conditionPanelName)
if not HealBotConfig[conditionPanelName] then
HealBotConfig[conditionPanelName] = {
enabled = false,
curePosion = false,
poisonCost = 20,
cureCurse = false,
curseCost = 80,
cureBleed = false,
bleedCost = 45,
cureBurn = false,
burnCost = 30,
cureElectrify = false,
electrifyCost = 22,
cureParalyse = false,
paralyseCost = 40,
paralyseSpell = "utani hur",
holdHaste = false,
hasteCost = 40,
hasteSpell = "utani hur",
holdUtamo = false,
utamoCost = 40,
holdUtana = false,
utanaCost = 440,
holdUtura = false,
uturaType = "",
uturaCost = 100,
ignoreInPz = true,
stopHaste = false
}
end
ui.title:setOn(HealBotConfig[conditionPanelName].enabled)
ui.title.onClick = function(widget)
HealBotConfig[conditionPanelName].enabled = not HealBotConfig[conditionPanelName].enabled
widget:setOn(HealBotConfig[conditionPanelName].enabled)
vBotConfigSave("heal")
end
ui.conditionList.onClick = function(widget)
conditionsWindow:show()
conditionsWindow:raise()
conditionsWindow:focus()
end
local rootWidget = g_ui.getRootWidget()
if rootWidget then
conditionsWindow = UI.createWindow('ConditionsWindow', rootWidget)
conditionsWindow:hide()
-- text edits
conditionsWindow.Cure.PoisonCost:setText(HealBotConfig[conditionPanelName].poisonCost)
conditionsWindow.Cure.PoisonCost.onTextChange = function(widget, text)
HealBotConfig[conditionPanelName].poisonCost = tonumber(text)
end
conditionsWindow.Cure.CurseCost:setText(HealBotConfig[conditionPanelName].curseCost)
conditionsWindow.Cure.CurseCost.onTextChange = function(widget, text)
HealBotConfig[conditionPanelName].curseCost = tonumber(text)
end
conditionsWindow.Cure.BleedCost:setText(HealBotConfig[conditionPanelName].bleedCost)
conditionsWindow.Cure.BleedCost.onTextChange = function(widget, text)
HealBotConfig[conditionPanelName].bleedCost = tonumber(text)
end
conditionsWindow.Cure.BurnCost:setText(HealBotConfig[conditionPanelName].burnCost)
conditionsWindow.Cure.BurnCost.onTextChange = function(widget, text)
HealBotConfig[conditionPanelName].burnCost = tonumber(text)
end
conditionsWindow.Cure.ElectrifyCost:setText(HealBotConfig[conditionPanelName].electrifyCost)
conditionsWindow.Cure.ElectrifyCost.onTextChange = function(widget, text)
HealBotConfig[conditionPanelName].electrifyCost = tonumber(text)
end
conditionsWindow.Cure.ParalyseCost:setText(HealBotConfig[conditionPanelName].paralyseCost)
conditionsWindow.Cure.ParalyseCost.onTextChange = function(widget, text)
HealBotConfig[conditionPanelName].paralyseCost = tonumber(text)
end
conditionsWindow.Cure.ParalyseSpell:setText(HealBotConfig[conditionPanelName].paralyseSpell)
conditionsWindow.Cure.ParalyseSpell.onTextChange = function(widget, text)
HealBotConfig[conditionPanelName].paralyseSpell = text
end
conditionsWindow.Hold.HasteSpell:setText(HealBotConfig[conditionPanelName].hasteSpell)
conditionsWindow.Hold.HasteSpell.onTextChange = function(widget, text)
HealBotConfig[conditionPanelName].hasteSpell = text
end
conditionsWindow.Hold.HasteCost:setText(HealBotConfig[conditionPanelName].hasteCost)
conditionsWindow.Hold.HasteCost.onTextChange = function(widget, text)
HealBotConfig[conditionPanelName].hasteCost = tonumber(text)
end
conditionsWindow.Hold.UtamoCost:setText(HealBotConfig[conditionPanelName].utamoCost)
conditionsWindow.Hold.UtamoCost.onTextChange = function(widget, text)
HealBotConfig[conditionPanelName].utamoCost = tonumber(text)
end
conditionsWindow.Hold.UtanaCost:setText(HealBotConfig[conditionPanelName].utanaCost)
conditionsWindow.Hold.UtanaCost.onTextChange = function(widget, text)
HealBotConfig[conditionPanelName].utanaCost = tonumber(text)
end
conditionsWindow.Hold.UturaCost:setText(HealBotConfig[conditionPanelName].uturaCost)
conditionsWindow.Hold.UturaCost.onTextChange = function(widget, text)
HealBotConfig[conditionPanelName].uturaCost = tonumber(text)
end
-- combo box
conditionsWindow.Hold.UturaType:setOption(HealBotConfig[conditionPanelName].uturaType)
conditionsWindow.Hold.UturaType.onOptionChange = function(widget)
HealBotConfig[conditionPanelName].uturaType = widget:getCurrentOption().text
end
-- checkboxes
conditionsWindow.Cure.CurePoison:setChecked(HealBotConfig[conditionPanelName].curePoison)
conditionsWindow.Cure.CurePoison.onClick = function(widget)
HealBotConfig[conditionPanelName].curePoison = not HealBotConfig[conditionPanelName].curePoison
widget:setChecked(HealBotConfig[conditionPanelName].curePoison)
end
conditionsWindow.Cure.CureCurse:setChecked(HealBotConfig[conditionPanelName].cureCurse)
conditionsWindow.Cure.CureCurse.onClick = function(widget)
HealBotConfig[conditionPanelName].cureCurse = not HealBotConfig[conditionPanelName].cureCurse
widget:setChecked(HealBotConfig[conditionPanelName].cureCurse)
end
conditionsWindow.Cure.CureBleed:setChecked(HealBotConfig[conditionPanelName].cureBleed)
conditionsWindow.Cure.CureBleed.onClick = function(widget)
HealBotConfig[conditionPanelName].cureBleed = not HealBotConfig[conditionPanelName].cureBleed
widget:setChecked(HealBotConfig[conditionPanelName].cureBleed)
end
conditionsWindow.Cure.CureBurn:setChecked(HealBotConfig[conditionPanelName].cureBurn)
conditionsWindow.Cure.CureBurn.onClick = function(widget)
HealBotConfig[conditionPanelName].cureBurn = not HealBotConfig[conditionPanelName].cureBurn
widget:setChecked(HealBotConfig[conditionPanelName].cureBurn)
end
conditionsWindow.Cure.CureElectrify:setChecked(HealBotConfig[conditionPanelName].cureElectrify)
conditionsWindow.Cure.CureElectrify.onClick = function(widget)
HealBotConfig[conditionPanelName].cureElectrify = not HealBotConfig[conditionPanelName].cureElectrify
widget:setChecked(HealBotConfig[conditionPanelName].cureElectrify)
end
conditionsWindow.Cure.CureParalyse:setChecked(HealBotConfig[conditionPanelName].cureParalyse)
conditionsWindow.Cure.CureParalyse.onClick = function(widget)
HealBotConfig[conditionPanelName].cureParalyse = not HealBotConfig[conditionPanelName].cureParalyse
widget:setChecked(HealBotConfig[conditionPanelName].cureParalyse)
end
conditionsWindow.Hold.HoldHaste:setChecked(HealBotConfig[conditionPanelName].holdHaste)
conditionsWindow.Hold.HoldHaste.onClick = function(widget)
HealBotConfig[conditionPanelName].holdHaste = not HealBotConfig[conditionPanelName].holdHaste
widget:setChecked(HealBotConfig[conditionPanelName].holdHaste)
end
conditionsWindow.Hold.HoldUtamo:setChecked(HealBotConfig[conditionPanelName].holdUtamo)
conditionsWindow.Hold.HoldUtamo.onClick = function(widget)
HealBotConfig[conditionPanelName].holdUtamo = not HealBotConfig[conditionPanelName].holdUtamo
widget:setChecked(HealBotConfig[conditionPanelName].holdUtamo)
end
conditionsWindow.Hold.HoldUtana:setChecked(HealBotConfig[conditionPanelName].holdUtana)
conditionsWindow.Hold.HoldUtana.onClick = function(widget)
HealBotConfig[conditionPanelName].holdUtana = not HealBotConfig[conditionPanelName].holdUtana
widget:setChecked(HealBotConfig[conditionPanelName].holdUtana)
end
conditionsWindow.Hold.HoldUtura:setChecked(HealBotConfig[conditionPanelName].holdUtura)
conditionsWindow.Hold.HoldUtura.onClick = function(widget)
HealBotConfig[conditionPanelName].holdUtura = not HealBotConfig[conditionPanelName].holdUtura
widget:setChecked(HealBotConfig[conditionPanelName].holdUtura)
end
conditionsWindow.Hold.IgnoreInPz:setChecked(HealBotConfig[conditionPanelName].ignoreInPz)
conditionsWindow.Hold.IgnoreInPz.onClick = function(widget)
HealBotConfig[conditionPanelName].ignoreInPz = not HealBotConfig[conditionPanelName].ignoreInPz
widget:setChecked(HealBotConfig[conditionPanelName].ignoreInPz)
end
conditionsWindow.Hold.StopHaste:setChecked(HealBotConfig[conditionPanelName].stopHaste)
conditionsWindow.Hold.StopHaste.onClick = function(widget)
HealBotConfig[conditionPanelName].stopHaste = not HealBotConfig[conditionPanelName].stopHaste
widget:setChecked(HealBotConfig[conditionPanelName].stopHaste)
end
-- buttons
conditionsWindow.closeButton.onClick = function(widget)
conditionsWindow:hide()
vBotConfigSave("heal")
end
end
local utanaCast = nil
macro(500, function()
if not HealBotConfig[conditionPanelName].enabled or modules.game_cooldown.isGroupCooldownIconActive(2) then return end
if hppercent() > 95 then
if HealBotConfig[conditionPanelName].curePoison and mana() >= HealBotConfig[conditionPanelName].poisonCost and isPoisioned() then say("exana pox")
elseif HealBotConfig[conditionPanelName].cureCurse and mana() >= HealBotConfig[conditionPanelName].curseCost and isCursed() then say("exana mort")
elseif HealBotConfig[conditionPanelName].cureBleed and mana() >= HealBotConfig[conditionPanelName].bleedCost and isBleeding() then say("exana kor")
elseif HealBotConfig[conditionPanelName].cureBurn and mana() >= HealBotConfig[conditionPanelName].burnCost and isBurning() then say("exana flam")
elseif HealBotConfig[conditionPanelName].cureElectrify and mana() >= HealBotConfig[conditionPanelName].electrifyCost and isEnergized() then say("exana vis")
end
end
if (not HealBotConfig[conditionPanelName].ignoreInPz or not isInPz()) and HealBotConfig[conditionPanelName].holdUtura and mana() >= HealBotConfig[conditionPanelName].uturaCost and not hasPartyBuff() then say(HealBotConfig[conditionPanelName].uturaType)
elseif (not HealBotConfig[conditionPanelName].ignoreInPz or not isInPz()) and HealBotConfig[conditionPanelName].holdUtana and mana() >= HealBotConfig[conditionPanelName].utanaCost and (not utanaCast or (now - utanaCast > 120000)) then say("utana vid") utanaCast = now
end
end)
macro(50, function()
if not HealBotConfig[conditionPanelName].enabled then return end
if (not HealBotConfig[conditionPanelName].ignoreInPz or not isInPz()) and HealBotConfig[conditionPanelName].holdUtamo and mana() >= HealBotConfig[conditionPanelName].utamoCost and not hasManaShield() then say("utamo vita")
elseif (not HealBotConfig[conditionPanelName].ignoreInPz or not isInPz()) and HealBotConfig[conditionPanelName].holdHaste and mana() >= HealBotConfig[conditionPanelName].hasteCost and not hasHaste() and not getSpellCoolDown(HealBotConfig[conditionPanelName].hasteSpell) and (not target() or not HealBotConfig[conditionPanelName].stopHaste or TargetBot.isCaveBotActionAllowed()) then say(HealBotConfig[conditionPanelName].hasteSpell)
elseif HealBotConfig[conditionPanelName].cureParalyse and mana() >= HealBotConfig[conditionPanelName].paralyseCost and isParalyzed() and not getSpellCoolDown(HealBotConfig[conditionPanelName].paralyseSpell) then say(HealBotConfig[conditionPanelName].paralyseSpell)
end
end)

View File

@@ -0,0 +1,424 @@
UturaComboBoxPopupMenu < ComboBoxPopupMenu
UturaComboBoxPopupMenuButton < ComboBoxPopupMenuButton
UturaComboBox < ComboBox
@onSetup: |
self:addOption("Utura")
self:addOption("Utura Gran")
CureConditions < Panel
id: Cure
image-source: /images/ui/panel_flat
image-border: 6
padding: 3
size: 200 190
Label
id: label1
anchors.top: parent.top
anchors.left: parent.left
margin-top: 10
margin-left: 5
text: Poison
color: #ffaa00
Label
id: label11
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 40
text: Mana:
TextEdit
id: PoisonCost
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 3
width: 40
CheckBox
id: CurePoison
anchors.verticalCenter: prev.verticalCenter
anchors.right: parent.right
margin-right: 10
Label
id: label2
anchors.left: label1.left
anchors.top: label1.bottom
margin-top: 10
text: Curse
color: #ffaa00
Label
id: label22
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 44
text: Mana:
TextEdit
id: CurseCost
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 3
width: 40
CheckBox
id: CureCurse
anchors.verticalCenter: prev.verticalCenter
anchors.right: parent.right
margin-right: 10
Label
id: label3
anchors.left: label2.left
anchors.top: label2.bottom
margin-top: 10
text: Bleed
color: #ffaa00
Label
id: label33
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 46
text: Mana:
TextEdit
id: BleedCost
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 3
width: 40
CheckBox
id: CureBleed
anchors.verticalCenter: prev.verticalCenter
anchors.right: parent.right
margin-right: 10
Label
id: label4
anchors.left: label3.left
anchors.top: label3.bottom
margin-top: 10
text: Burn
color: #ffaa00
Label
id: label44
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 50
text: Mana:
TextEdit
id: BurnCost
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 3
width: 40
CheckBox
id: CureBurn
anchors.verticalCenter: prev.verticalCenter
anchors.right: parent.right
margin-right: 10
Label
id: label5
anchors.left: label4.left
anchors.top: label4.bottom
margin-top: 10
text: Electify
color: #ffaa00
Label
id: label55
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 33
text: Mana:
TextEdit
id: ElectrifyCost
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 3
width: 40
CheckBox
id: CureElectrify
anchors.verticalCenter: prev.verticalCenter
anchors.right: parent.right
margin-right: 10
Label
id: label6
anchors.left: label5.left
anchors.top: label5.bottom
margin-top: 10
text: Paralyse
color: #ffaa00
Label
id: label66
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 26
text: Mana:
TextEdit
id: ParalyseCost
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 3
width: 40
CheckBox
id: CureParalyse
anchors.verticalCenter: prev.verticalCenter
anchors.right: parent.right
margin-right: 10
Label
id: label7
anchors.left: label6.left
anchors.top: label6.bottom
margin-top: 10
margin-left: 12
text: Spell:
TextEdit
id: ParalyseSpell
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 10
width: 100
HoldConditions < Panel
id: Hold
image-source: /images/ui/panel_flat
image-border: 6
padding: 3
size: 200 190
Label
id: label1
anchors.top: parent.top
anchors.left: parent.left
margin-top: 10
margin-left: 5
text: Haste
color: #ffaa00
Label
id: label11
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 44
text: Mana:
TextEdit
id: HasteCost
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 3
width: 40
CheckBox
id: HoldHaste
anchors.verticalCenter: prev.verticalCenter
anchors.right: parent.right
margin-right: 10
Label
id: label2
anchors.left: label1.left
anchors.top: label1.bottom
margin-top: 10
margin-left: 12
text: Spell:
TextEdit
id: HasteSpell
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 10
width: 100
Label
id: label3
anchors.left: label1.left
anchors.top: label2.bottom
margin-top: 10
text: Utana Vid
color: #ffaa00
Label
id: label33
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 21
text: Mana:
TextEdit
id: UtanaCost
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 3
width: 40
CheckBox
id: HoldUtana
anchors.verticalCenter: prev.verticalCenter
anchors.right: parent.right
margin-right: 10
Label
id: label4
anchors.left: label3.left
anchors.top: label3.bottom
margin-top: 10
text: Utamo Vita
color: #ffaa00
Label
id: label44
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 12
text: Mana:
TextEdit
id: UtamoCost
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 3
width: 40
CheckBox
id: HoldUtamo
anchors.verticalCenter: prev.verticalCenter
anchors.right: parent.right
margin-right: 10
Label
id: label5
anchors.left: label4.left
anchors.top: label4.bottom
margin-top: 10
text: Recovery
color: #ffaa00
Label
id: label55
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 20
text: Mana:
TextEdit
id: UturaCost
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 3
width: 40
CheckBox
id: HoldUtura
anchors.verticalCenter: prev.verticalCenter
anchors.right: parent.right
margin-right: 10
Label
id: label6
anchors.left: label5.left
anchors.top: label5.bottom
margin-top: 10
margin-left: 12
text: Spell:
UturaComboBox
id: UturaType
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 10
width: 100
CheckBox
id: IgnoreInPz
anchors.left: label5.left
anchors.top: label6.bottom
margin-top: 12
Label
anchors.verticalCenter: IgnoreInPz.verticalCenter
anchors.left: prev.right
margin-top: 3
margin-left: 5
text: Don't Cast in Protection Zones
font: cipsoftFont
CheckBox
id: StopHaste
anchors.horizontalCenter: IgnoreInPz.horizontalCenter
anchors.top: IgnoreInPz.bottom
margin-top: 8
Label
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-top: 3
margin-left: 5
text: Stop Haste if TargetBot Is Active
font: cipsoftFont
ConditionsWindow < MainWindow
!text: tr('Condition Manager')
size: 445 280
CureConditions
id: Cure
anchors.top: parent.top
anchors.left: parent.left
margin-top: 7
Label
id: label
anchors.top: parent.top
anchors.left: parent.left
text: Cure Conditions
color: #88e3dd
margin-left: 10
HoldConditions
id: Hold
anchors.top: parent.top
anchors.right: parent.right
margin-top: 7
Label
id: label
anchors.top: parent.top
anchors.right: parent.right
text: Hold Conditions
color: #88e3dd
margin-right: 100
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

@@ -0,0 +1,702 @@
setDefaultTab("HP")
healPanelName = "healbot"
local ui = setupUI([[
Panel
height: 38
BotSwitch
id: title
anchors.top: parent.top
anchors.left: parent.left
text-align: center
width: 130
!text: tr('HealBot')
Button
id: settings
anchors.top: prev.top
anchors.left: prev.right
anchors.right: parent.right
margin-left: 3
height: 17
text: Setup
Button
id: 1
anchors.top: prev.bottom
anchors.left: parent.left
text: 1
margin-right: 2
margin-top: 4
size: 17 17
Button
id: 2
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
text: 2
margin-left: 4
size: 17 17
Button
id: 3
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
text: 3
margin-left: 4
size: 17 17
Button
id: 4
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
text: 4
margin-left: 4
size: 17 17
Button
id: 5
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
text: 5
margin-left: 4
size: 17 17
Label
id: name
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
anchors.right: parent.right
text-align: center
margin-left: 4
height: 17
text: Profile #1
background: #292A2A
]])
ui:setId(healPanelName)
if not HealBotConfig[healPanelName] or not HealBotConfig[healPanelName][1] or #HealBotConfig[healPanelName] ~= 5 then
HealBotConfig[healPanelName] = {
[1] = {
enabled = false,
spellTable = {},
itemTable = {},
name = "Profile #1",
Visible = true,
Cooldown = true,
Interval = true,
Conditions = true,
Delay = true,
MessageDelay = false
},
[2] = {
enabled = false,
spellTable = {},
itemTable = {},
name = "Profile #2",
Visible = true,
Cooldown = true,
Interval = true,
Conditions = true,
Delay = true,
MessageDelay = false
},
[3] = {
enabled = false,
spellTable = {},
itemTable = {},
name = "Profile #3",
Visible = true,
Cooldown = true,
Interval = true,
Conditions = true,
Delay = true,
MessageDelay = false
},
[4] = {
enabled = false,
spellTable = {},
itemTable = {},
name = "Profile #4",
Visible = true,
Cooldown = true,
Interval = true,
Conditions = true,
Delay = true,
MessageDelay = false
},
[5] = {
enabled = false,
spellTable = {},
itemTable = {},
name = "Profile #5",
Visible = true,
Cooldown = true,
Interval = true,
Conditions = true,
Delay = true,
MessageDelay = false
},
}
end
if not HealBotConfig.currentHealBotProfile or HealBotConfig.currentHealBotProfile == 0 or HealBotConfig.currentHealBotProfile > 5 then
HealBotConfig.currentHealBotProfile = 1
end
-- finding correct table, manual unfortunately
local currentSettings
local setActiveProfile = function()
local n = HealBotConfig.currentHealBotProfile
currentSettings = HealBotConfig[healPanelName][n]
end
setActiveProfile()
local activeProfileColor = function()
for i=1,5 do
if i == HealBotConfig.currentHealBotProfile then
ui[i]:setColor("green")
else
ui[i]:setColor("white")
end
end
end
activeProfileColor()
ui.title:setOn(currentSettings.enabled)
ui.title.onClick = function(widget)
currentSettings.enabled = not currentSettings.enabled
widget:setOn(currentSettings.enabled)
vBotConfigSave("heal")
end
ui.settings.onClick = function(widget)
healWindow:show()
healWindow:raise()
healWindow:focus()
end
rootWidget = g_ui.getRootWidget()
if rootWidget then
healWindow = UI.createWindow('HealWindow', rootWidget)
healWindow:hide()
local setProfileName = function()
ui.name:setText(currentSettings.name)
end
healWindow.Name.onTextChange = function(widget, text)
currentSettings.name = text
setProfileName()
end
healWindow.Visible.onClick = function(widget)
currentSettings.Visible = not currentSettings.Visible
healWindow.Visible:setChecked(currentSettings.Visible)
end
healWindow.Cooldown.onClick = function(widget)
currentSettings.Cooldown = not currentSettings.Cooldown
healWindow.Cooldown:setChecked(currentSettings.Cooldown)
end
healWindow.Interval.onClick = function(widget)
currentSettings.Interval = not currentSettings.Interval
healWindow.Interval:setChecked(currentSettings.Interval)
end
healWindow.Conditions.onClick = function(widget)
currentSettings.Conditions = not currentSettings.Conditions
healWindow.Conditions:setChecked(currentSettings.Conditions)
end
healWindow.Delay.onClick = function(widget)
currentSettings.Delay = not currentSettings.Delay
healWindow.Delay:setChecked(currentSettings.Delay)
end
healWindow.MessageDelay.onClick = function(widget)
currentSettings.MessageDelay = not currentSettings.MessageDelay
healWindow.MessageDelay:setChecked(currentSettings.MessageDelay)
end
local refreshSpells = function()
if currentSettings.spellTable then
for i, child in pairs(healWindow.spells.spellList:getChildren()) do
child:destroy()
end
for _, entry in pairs(currentSettings.spellTable) do
local label = 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(currentSettings.spellTable, entry)
reindexTable(currentSettings.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 currentSettings.itemTable then
for i, child in pairs(healWindow.items.itemList:getChildren()) do
child:destroy()
end
for _, entry in pairs(currentSettings.itemTable) do
local label = 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(currentSettings.itemTable, entry)
reindexTable(currentSettings.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 currentSettings.spellTable and #currentSettings.spellTable > 0 then
for _, entry in pairs(currentSettings.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(currentSettings.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 currentSettings.spellTable and #currentSettings.spellTable > 0 then
for _, entry in pairs(currentSettings.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(currentSettings.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 currentSettings.itemTable and #currentSettings.itemTable > 0 then
for _, entry in pairs(currentSettings.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(currentSettings.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 currentSettings.itemTable and #currentSettings.itemTable > 0 then
for _, entry in pairs(currentSettings.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(currentSettings.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%"
elseif spellSource == "Health Percent" then
source = "HP%"
else
source = "burst"
end
if spellEquasion == "Above" then
equasion = ">"
elseif spellEquasion == "Below" then
equasion = "<"
else
equasion = "="
end
if spellFormula:len() > 0 then
table.insert(currentSettings.spellTable, {index = #currentSettings.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%"
elseif src == "Health Percent" then
source = "HP%"
else
source = "burst"
end
if eq == "Above" then
equasion = ">"
elseif eq == "Below" then
equasion = "<"
else
equasion = "="
end
if id > 100 then
table.insert(currentSettings.itemTable, {index = #currentSettings.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()
vBotConfigSave("heal")
end
local loadSettings = function()
ui.title:setOn(currentSettings.enabled)
setProfileName()
healWindow.Name:setText(currentSettings.name)
refreshSpells()
refreshItems()
healWindow.Visible:setChecked(currentSettings.Visible)
healWindow.Cooldown:setChecked(currentSettings.Cooldown)
healWindow.Delay:setChecked(currentSettings.Delay)
healWindow.MessageDelay:setChecked(currentSettings.MessageDelay)
healWindow.Interval:setChecked(currentSettings.Interval)
healWindow.Conditions:setChecked(currentSettings.Conditions)
end
loadSettings()
local profileChange = function()
setActiveProfile()
activeProfileColor()
loadSettings()
vBotConfigSave("heal")
end
local resetSettings = function()
currentSettings.enabled = false
currentSettings.spellTable = {}
currentSettings.itemTable = {}
currentSettings.Visible = true
currentSettings.Cooldown = true
currentSettings.Delay = true
currentSettings.MessageDelay = false
currentSettings.Interval = true
currentSettings.Conditions = true
currentSettings.name = "Profile #" .. HealBotConfig.currentBotProfile
end
-- profile buttons
for i=1,5 do
local button = ui[i]
button.onClick = function()
HealBotConfig.currentHealBotProfile = i
profileChange()
end
end
healWindow.ResetSettings.onClick = function()
resetSettings()
loadSettings()
end
-- public functions
HealBot = {} -- global table
HealBot.isOn = function()
return currentSettings.enabled
end
HealBot.isOff = function()
return not currentSettings.enabled
end
HealBot.setOff = function()
currentSettings.enabled = false
ui.title:setOn(currentSettings.enabled)
vBotConfigSave("atk")
end
HealBot.setOn = function()
currentSettings.enabled = true
ui.title:setOn(currentSettings.enabled)
vBotConfigSave("atk")
end
HealBot.getActiveProfile = function()
return HealBotConfig.currentHealBotProfile -- returns number 1-5
end
HealBot.setActiveProfile = function(n)
if not n or not tonumber(n) or n < 1 or n > 5 then
return error("[HealBot] wrong profile parameter! should be 1 to 5 is " .. n)
else
HealBotConfig.currentHealBotProfile = n
profileChange()
end
end
end
-- spells
macro(100, function()
if not currentSettings.enabled or modules.game_cooldown.isGroupCooldownIconActive(2) or #currentSettings.spellTable == 0 then return end
for _, entry in pairs(currentSettings.spellTable) do
if canCast(entry.spell, not currentSettings.Conditions, not currentSettings.Cooldown) and entry.enabled and entry.cost < mana() 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
elseif entry.origin == "burst" then
if entry.sign == "=" and burstDamageValue() == entry.value then
say(entry.spell)
return
elseif entry.sign == ">" and burstDamageValue() >= entry.value then
say(entry.spell)
return
elseif entry.sign == "<" and burstDamageValue() <= entry.value then
say(entry.spell)
return
end
end
end
end
end)
-- items
macro(100, function()
if not currentSettings.enabled or #currentSettings.itemTable == 0 then return end
if currentSettings.Delay and storage.isUsing then return end
if currentSettings.MessageDelay and storage.isUsingPotion then return end
if not currentSettings.MessageDelay then
delay(400)
end
if TargetBot.isOn() and TargetBot.Looting.getStatus():len() > 0 and currentSettings.Interval then
if not currentSettings.MessageDelay then
delay(700)
else
delay(200)
end
end
for _, entry in pairs(currentSettings.itemTable) do
local item = findItem(entry.item)
if (not currentSettings.Visible or item) and entry.enabled then
if entry.origin == "HP%" then
if entry.sign == "=" and hppercent() == entry.value then
g_game.useInventoryItemWith(entry.item, player)
return
elseif entry.sign == ">" and hppercent() >= entry.value then
g_game.useInventoryItemWith(entry.item, player)
return
elseif entry.sign == "<" and hppercent() <= entry.value then
g_game.useInventoryItemWith(entry.item, player)
return
end
elseif entry.origin == "HP" then
if entry.sign == "=" and hp() == tonumberentry.value then
g_game.useInventoryItemWith(entry.item, player)
return
elseif entry.sign == ">" and hp() >= entry.value then
g_game.useInventoryItemWith(entry.item, player)
return
elseif entry.sign == "<" and hp() <= entry.value then
g_game.useInventoryItemWith(entry.item, player)
return
end
elseif entry.origin == "MP%" then
if entry.sign == "=" and manapercent() == entry.value then
g_game.useInventoryItemWith(entry.item, player)
return
elseif entry.sign == ">" and manapercent() >= entry.value then
g_game.useInventoryItemWith(entry.item, player)
return
elseif entry.sign == "<" and manapercent() <= entry.value then
g_game.useInventoryItemWith(entry.item, player)
return
end
elseif entry.origin == "MP" then
if entry.sign == "=" and mana() == entry.value then
g_game.useInventoryItemWith(entry.item, player)
return
elseif entry.sign == ">" and mana() >= entry.value then
g_game.useInventoryItemWith(entry.item, player)
return
elseif entry.sign == "<" and mana() <= entry.value then
g_game.useInventoryItemWith(entry.item, player)
return
end
elseif entry.origin == "burst" then
if entry.sign == "=" and burstDamageValue() == entry.value then
g_game.useInventoryItemWith(entry.item, player)
return
elseif entry.sign == ">" and burstDamageValue() >= entry.value then
g_game.useInventoryItemWith(entry.item, player)
return
elseif entry.sign == "<" and burstDamageValue() <= entry.value then
g_game.useInventoryItemWith(entry.item, player)
return
end
end
end
end
end)
UI.Separator()

View File

@@ -0,0 +1,405 @@
SpellSourceBoxPopupMenu < ComboBoxPopupMenu
SpellSourceBoxPopupMenuButton < ComboBoxPopupMenuButton
SpellSourceBox < ComboBox
@onSetup: |
self:addOption("Current Mana")
self:addOption("Current Health")
self:addOption("Mana Percent")
self:addOption("Health Percent")
self:addOption("Burst Damage")
SpellConditionBoxPopupMenu < ComboBoxPopupMenu
SpellConditionBoxPopupMenuButton < ComboBoxPopupMenuButton
SpellConditionBox < ComboBox
@onSetup: |
self:addOption("Below")
self:addOption("Above")
self:addOption("Equal To")
SpellEntry < 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
ItemEntry < 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
SpellHealing < Panel
image-source: /images/ui/panel_flat
image-border: 6
padding: 3
size: 490 130
Label
id: whenSpell
anchors.left: spellList.right
anchors.top: parent.top
text: When
margin-top: 10
margin-left: 7
SpellSourceBox
id: spellSource
anchors.top: parent.top
anchors.left: whenSpell.right
margin-top: 5
margin-left: 35
width: 128
Label
id: isSpell
anchors.left: spellList.right
anchors.top: whenSpell.bottom
text: Is
margin-top: 9
margin-left: 7
SpellConditionBox
id: spellCondition
anchors.left: spellSource.left
anchors.top: spellSource.bottom
marin-top: 15
width: 80
TextEdit
id: spellValue
anchors.left: spellCondition.right
anchors.top: spellCondition.top
anchors.bottom: spellCondition.bottom
width: 49
Label
id: castSpell
anchors.left: isSpell.left
anchors.top: isSpell.bottom
text: Cast
margin-top: 9
TextEdit
id: spellFormula
anchors.left: spellCondition.left
anchors.top: spellCondition.bottom
anchors.right: spellValue.right
Label
id: manaSpell
anchors.left: castSpell.left
anchors.top: castSpell.bottom
text: Mana Cost:
margin-top: 8
TextEdit
id: manaCost
anchors.left: spellFormula.left
anchors.top: spellFormula.bottom
width: 40
TextList
id: spellList
anchors.left: parent.left
anchors.bottom: parent.bottom
padding: 1
size: 270 116
margin-bottom: 3
margin-left: 3
vertical-scrollbar: spellListScrollBar
VerticalScrollBar
id: spellListScrollBar
anchors.top: spellList.top
anchors.bottom: spellList.bottom
anchors.right: spellList.right
step: 14
pixels-scroll: true
Button
id: addSpell
anchors.right: spellFormula.right
anchors.bottom: parent.bottom
margin-bottom: 2
margin-right: 10
text: Add
size: 40 17
font: cipsoftFont
Button
id: MoveUp
anchors.right: prev.left
anchors.bottom: parent.bottom
margin-bottom: 2
margin-right: 5
text: Move Up
size: 55 17
font: cipsoftFont
Button
id: MoveDown
anchors.right: prev.left
anchors.bottom: parent.bottom
margin-bottom: 2
margin-right: 5
text: Move Down
size: 55 17
font: cipsoftFont
ItemHealing < Panel
image-source: /images/ui/panel_flat
image-border: 6
padding: 3
size: 490 130
Label
id: whenItem
anchors.left: itemList.right
anchors.top: parent.top
text: When
margin-top: 10
margin-left: 7
SpellSourceBox
id: itemSource
anchors.top: parent.top
anchors.left: whenItem.right
margin-top: 5
margin-left: 35
width: 128
Label
id: isItem
anchors.left: itemList.right
anchors.top: whenItem.bottom
text: Is
margin-top: 9
margin-left: 7
SpellConditionBox
id: itemCondition
anchors.left: itemSource.left
anchors.top: itemSource.bottom
marin-top: 15
width: 80
TextEdit
id: itemValue
anchors.left: itemCondition.right
anchors.top: itemCondition.top
anchors.bottom: itemCondition.bottom
width: 49
Label
id: useItem
anchors.left: isItem.left
anchors.top: isItem.bottom
text: Use
margin-top: 15
BotItem
id: itemId
anchors.left: itemCondition.left
anchors.top: itemCondition.bottom
TextList
id: itemList
anchors.left: parent.left
anchors.bottom: parent.bottom
padding: 1
size: 270 116
margin-top: 3
margin-bottom: 3
margin-left: 3
vertical-scrollbar: itemListScrollBar
VerticalScrollBar
id: itemListScrollBar
anchors.top: itemList.top
anchors.bottom: itemList.bottom
anchors.right: itemList.right
step: 14
pixels-scroll: true
Button
id: addItem
anchors.right: itemValue.right
anchors.bottom: parent.bottom
margin-bottom: 2
margin-right: 10
text: Add
size: 40 17
font: cipsoftFont
Button
id: MoveUp
anchors.right: prev.left
anchors.bottom: parent.bottom
margin-bottom: 2
margin-right: 5
text: Move Up
size: 55 17
font: cipsoftFont
Button
id: MoveDown
anchors.right: prev.left
anchors.bottom: parent.bottom
margin-bottom: 2
margin-right: 5
text: Move Down
size: 55 17
font: cipsoftFont
HealWindow < MainWindow
!text: tr('Self Healer')
size: 800 350
SpellHealing
id: spells
anchors.top: parent.top
anchors.left: parent.left
ItemHealing
id: items
anchors.top: prev.bottom
anchors.left: parent.left
margin-top: 10
VerticalSeparator
id: sep
anchors.top: parent.top
anchors.left: prev.right
anchors.bottom: separator.top
margin-left: 10
margin-bottom: 5
Label
anchors.left: prev.right
anchors.right: parent.right
anchors.top: parent.top
text-align: center
text: Additional Options
HorizontalSeparator
anchors.left: prev.left
anchors.top: prev.bottom
anchors.right: prev.right
margin-top: 5
margin-left: 10
CheckBox
id: Cooldown
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 10
margin-left: 5
width: 200
text: Check spell cooldowns
CheckBox
id: Visible
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 8
width: 250
text: Items must be visible (recommended)
CheckBox
id: Delay
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 8
width: 250
text: Don't use items when interacting
CheckBox
id: Interval
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 8
width: 250
text: Additional delay when looting corpses
CheckBox
id: Conditions
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 8
width: 250
text: Also check conditions from RL Tibia
CheckBox
id: MessageDelay
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 8
width: 250
text: Cooldown based on "Aaaah..." message
Label
anchors.left: Visible.left
anchors.bottom: separator.top
margin-bottom: 8
text: Profile:
TextEdit
id: Name
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 5
Button
id: ResetSettings
anchors.verticalCenter: prev.verticalCenter
anchors.right: parent.right
text: Reset Settings
margin-top: 1
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

@@ -0,0 +1,252 @@
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,
customSpellName = "exura max sio",
customSpell = false,
distance = 8,
itemHeal = false,
id = 3160,
exuraSio = false,
exuraGranSio = false,
exuraMasRes = false,
healEk = false,
healRp = false,
healEd = false,
healMs = false
}
end
local config = storage[panelName]
-- basic elements
ui.title:setOn(config.enabled)
ui.title.onClick = function(widget)
config.enabled = not config.enabled
widget:setOn(config.enabled)
end
ui.editList.onClick = function(widget)
sioListWindow:show()
sioListWindow:raise()
sioListWindow:focus()
end
rootWidget = g_ui.getRootWidget()
if rootWidget then
sioListWindow = UI.createWindow('SioListWindow', rootWidget)
sioListWindow:hide()
-- TextWindow
sioListWindow.spellName:setText(config.spellName)
sioListWindow.spellName.onTextChange = function(widget, text)
config.customSpellName = text
end
-- botswitches
sioListWindow.spell:setOn(config.customSpell)
sioListWindow.spell.onClick = function(widget)
config.customSpell = not config.customSpell
widget:setOn(config.customSpell)
end
sioListWindow.item:setOn(config.itemHeal)
sioListWindow.item.onClick = function(widget)
config.itemHeal = not config.itemHeal
widget:setOn(config.itemHeal)
end
sioListWindow.exuraSio:setOn(config.exuraSio)
sioListWindow.exuraSio.onClick = function(widget)
config.exuraSio = not config.exuraSio
widget:setOn(config.exuraSio)
end
sioListWindow.exuraGranSio:setOn(config.exuraGranSio)
sioListWindow.exuraGranSio.onClick = function(widget)
config.exuraGranSio = not config.exuraGranSio
widget:setOn(config.exuraGranSio)
end
sioListWindow.exuraMasRes:setOn(config.exuraMasRes)
sioListWindow.exuraMasRes.onClick = function(widget)
config.exuraMasRes = not config.exuraMasRes
widget:setOn(config.exuraMasRes)
end
sioListWindow.vocation.ED:setOn(config.healEd)
sioListWindow.vocation.ED.onClick = function(widget)
config.healEd = not config.healEd
widget:setOn(config.healEd)
end
sioListWindow.vocation.MS:setOn(config.healMs)
sioListWindow.vocation.MS.onClick = function(widget)
config.healMs = not config.healMs
widget:setOn(config.healMs)
end
sioListWindow.vocation.EK:setOn(config.healEk)
sioListWindow.vocation.EK.onClick = function(widget)
config.healEk = not config.healEk
widget:setOn(config.healEk)
end
sioListWindow.vocation.RP:setOn(config.healRp)
sioListWindow.vocation.RP.onClick = function(widget)
config.healRp = not config.healRp
widget:setOn(config.healRp)
end
-- functions
local updateMinManaText = function()
sioListWindow.manaInfo:setText("Minimum Mana >= " .. config.minMana .. "%")
end
local updateFriendHpText = function()
sioListWindow.friendHp:setText("Heal Friend Below " .. config.minFriendHp .. "% hp")
end
local updateDistanceText = function()
sioListWindow.distText:setText("Max Distance: " .. config.distance)
end
-- scrollbars and text updates
sioListWindow.Distance:setValue(config.distance)
sioListWindow.Distance.onValueChange = function(scroll, value)
config.distance = value
updateDistanceText()
end
updateDistanceText()
sioListWindow.minMana:setValue(config.minMana)
sioListWindow.minMana.onValueChange = function(scroll, value)
config.minMana = value
updateMinManaText()
end
updateMinManaText()
sioListWindow.minFriendHp:setValue(config.minFriendHp)
sioListWindow.minFriendHp.onValueChange = function(scroll, value)
config.minFriendHp = value
updateFriendHpText()
end
updateFriendHpText()
sioListWindow.itemId:setItemId(config.id)
sioListWindow.itemId.onItemChange = function(widget)
config.id = widget:getItemId()
end
sioListWindow.closeButton.onClick = function(widget)
sioListWindow:hide()
end
end
-- local variables
local newTibia = g_game.getClientVersion() >= 960
local function isValid(name)
if not newTibia then return true end
local voc = BotServerMembers[name]
if not voc then return true end
if voc == 11 then voc = 1
elseif voc == 12 then voc = 2
elseif voc == 13 then voc = 3
elseif voc == 14 then voc = 4
end
local isOk = false
if voc == 1 and config.healEk then
isOk = true
elseif voc == 2 and config.healRp then
isOk = true
elseif voc == 3 and config.healMs then
isOk = true
elseif voc == 4 and config.healEd then
isOk = true
end
return isOk
end
macro(200, function()
if not config.enabled then return end
if modules.game_cooldown.isGroupCooldownIconActive(2) then return end
--[[
1. custom spell
2. exura gran sio - at 50% of minHpValue
3. exura gran mas res
4. exura sio
5. item healing
--]]
-- exura gran sio & custom spell
if config.customSpell or config.exuraGranSio then
for i, spec in ipairs(getSpectators()) do
if spec:isPlayer() and spec ~= player and isValid(spec:getName()) and spec:canShoot() then
if isFriend(spec) then
if config.customSpell and spec:getHealthPercent() <= config.minFriendHp then
return cast(config.customSpellName .. ' "' .. spec:getName() .. '"', 1000)
end
if config.exuraGranSio and spec:getHealthPercent() <= config.minFriendHp/3 then
if canCast('exura gran sio "' .. spec:getName() ..'"') then
return cast('exura gran sio "' .. spec:getName() ..'"', 60000)
end
end
end
end
end
end
-- exura gran mas res and standard sio
local friends = 0
if config.exuraMasRes then
for i, spec in ipairs(getSpectators(player, largeRuneArea)) do
if spec:isPlayer() and spec ~= player and isValid(spec:getName()) and spec:canShoot() then
if isFriend(spec) and spec:getHealthPercent() <= config.minFriendHp then
friends = friends + 1
end
end
end
if friends > 1 then
return cast('exura gran mas res', 2000)
end
end
if config.exuraSio or config.itemHeal then
for i, spec in ipairs(getSpectators()) do
if spec:isPlayer() and spec ~= player and isValid(spec:getName()) and spec:canShoot() then
if isFriend(spec) then
if spec:getHealthPercent() <= config.minFriendHp then
if config.exuraSio then
return cast('exura sio "' .. spec:getName() .. '"', 1000)
elseif findItem(config.id) and distanceFromPlayer(spec:getPosition()) <= config.distance then
return useWith(config.id, spec)
end
end
end
end
end
end
end)
addSeparator()

View File

@@ -0,0 +1,178 @@
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 = UI.createWindow('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

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

@@ -0,0 +1,14 @@
setDefaultTab("Tools")
local m = macro(1000, "AntiRS & Msg", function() end)
local frags = 0
onTextMessage(function(mode, text)
if not m.isOn() then return end
if not text:lower():find("warning! the murder of") then return end
info(text)
say("Don't bother, I have anti-rs and shit EQ. Don't waste our time.")
frags = frags + 1
if killsToRs() < 6 or frags > 1 then
modules.game_interface.forceExit()
end
end)

View File

@@ -0,0 +1,22 @@
setDefaultTab("HP")
if voc() ~= 1 and voc() ~= 11 then
if storage.foodItems then
local t = {}
for i, v in pairs(storage.foodItems) do
if not table.find(t, v.id) then
table.insert(t, v.id)
end
end
local foodItems = { 3607, 3585, 3592, 3600, 3601 }
for i, item in pairs(foodItems) do
if not table.find(t, item) then
table.insert(storage.foodItems, item)
end
end
end
macro(500, "Cast Food", function()
if player:getRegenerationTime() <= 400 then
cast("exevo pan", 5000)
end
end)
end

View File

@@ -0,0 +1,49 @@
-- Cavebot by otclient@otclient.ovh
-- visit http://bot.otclient.ovh/
local cavebotTab = "Cave"
local targetingTab = "Target"
setDefaultTab(cavebotTab)
CaveBot.Extensions = {}
importStyle("/cavebot/cavebot.otui")
importStyle("/cavebot/config.otui")
importStyle("/cavebot/editor.otui")
dofile("/cavebot/actions.lua")
dofile("/cavebot/config.lua")
dofile("/cavebot/editor.lua")
dofile("/cavebot/example_functions.lua")
dofile("/cavebot/recorder.lua")
dofile("/cavebot/walking.lua")
-- in this section you can add extensions, check extension_template.lua
--dofile("/cavebot/extension_template.lua")
dofile("/cavebot/sell_all.lua")
dofile("/cavebot/depositor.lua")
dofile("/cavebot/buy_supplies.lua")
dofile("/cavebot/d_withdraw.lua")
dofile("/cavebot/supply_check.lua")
dofile("/cavebot/travel.lua")
dofile("/cavebot/doors.lua")
dofile("/cavebot/pos_check.lua")
dofile("/cavebot/withdraw.lua")
dofile("/cavebot/inbox_withdraw.lua")
dofile("/cavebot/lure.lua")
dofile("/cavebot/bank.lua")
dofile("/cavebot/clear_tile.lua")
dofile("/cavebot/tasker.lua")
-- main cavebot file, must be last
dofile("/cavebot/cavebot.lua")
setDefaultTab(targetingTab)
TargetBot = {} -- global namespace
importStyle("/targetbot/looting.otui")
importStyle("/targetbot/target.otui")
importStyle("/targetbot/creature_editor.otui")
dofile("/targetbot/creature.lua")
dofile("/targetbot/creature_attack.lua")
dofile("/targetbot/creature_editor.lua")
dofile("/targetbot/creature_priority.lua")
dofile("/targetbot/looting.lua")
dofile("/targetbot/walking.lua")
-- main targetbot file, must be last
dofile("/targetbot/target.lua")

View File

@@ -0,0 +1,441 @@
setDefaultTab("Main")
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 = UI.createWindow('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

@@ -0,0 +1,391 @@
AttackComboBoxPopupMenu < ComboBoxPopupMenu
AttackComboBoxPopupMenuButton < ComboBoxPopupMenuButton
AttackComboBox < ComboBox
@onSetup: |
self:addOption("LEADER TARGET")
self:addOption("COMMAND TARGET")
FollowComboBoxPopupMenu < ComboBoxPopupMenu
FollowComboBoxPopupMenuButton < ComboBoxPopupMenuButton
FollowComboBox < ComboBox
@onSetup: |
self:addOption("LEADER TARGET")
self:addOption("SERVER LEADER TARGET")
self:addOption("LEADER")
self:addOption("SERVER LEADER")
ComboTrigger < Panel
id: trigger
image-source: /images/ui/panel_flat
image-border: 6
padding: 3
size: 450 72
Label
id: triggerLabel1
anchors.left: parent.left
anchors.top: parent.top
text: On Say
margin-top: 8
margin-left: 5
color: #ffaa00
Label
id: leaderLabel
anchors.left: triggerLabel1.right
anchors.top: triggerLabel1.top
text: Leader:
margin-left: 35
TextEdit
id: onSayLeader
anchors.left: leaderLabel.right
anchors.top: leaderLabel.top
anchors.bottom: leaderLabel.bottom
margin-left: 5
width: 120
font: cipsoftFont
Label
id: phrase
anchors.left: onSayLeader.right
anchors.top: onSayLeader.top
text: Phrase:
margin-left: 5
TextEdit
id: onSayPhrase
anchors.left: phrase.right
anchors.top: leaderLabel.top
anchors.bottom: leaderLabel.bottom
margin-left: 5
width: 120
font: cipsoftFont
CheckBox
id: onSayToggle
anchors.left: onSayPhrase.right
anchors.top: onSayPhrase.top
margin-top: 1
margin-left: 5
Label
id: triggerLabel2
anchors.left: triggerLabel1.left
anchors.top: triggerLabel1.bottom
text: On Shoot
margin-top: 5
color: #ffaa00
Label
id: leaderLabel1
anchors.left: triggerLabel2.right
anchors.top: triggerLabel2.top
text: Leader:
margin-left: 24
TextEdit
id: onShootLeader
anchors.left: leaderLabel1.right
anchors.top: leaderLabel1.top
anchors.bottom: leaderLabel1.bottom
anchors.right: onSayPhrase.right
margin-left: 5
width: 120
font: cipsoftFont
CheckBox
id: onShootToggle
anchors.left: onShootLeader.right
anchors.top: onShootLeader.top
margin-top: 1
margin-left: 5
Label
id: triggerLabel3
anchors.left: triggerLabel2.left
anchors.top: triggerLabel2.bottom
text: On Cast
margin-top: 5
color: #ffaa00
Label
id: leaderLabel2
anchors.left: triggerLabel3.right
anchors.top: triggerLabel3.top
text: Leader:
margin-left: 32
TextEdit
id: onCastLeader
anchors.left: leaderLabel2.right
anchors.top: leaderLabel2.top
anchors.bottom: leaderLabel2.bottom
anchors.right: onSayPhrase.right
margin-left: 5
width: 120
font: cipsoftFont
CheckBox
id: onCastToggle
anchors.left: onCastLeader.right
anchors.top: onCastLeader.top
margin-top: 1
margin-left: 5
ComboActions < Panel
id: actions
image-source: /images/ui/panel_flat
image-border: 6
padding: 3
size: 220 100
Label
id: label1
anchors.left: parent.left
anchors.top: parent.top
text: Follow:
margin-top: 5
margin-left: 3
height: 15
color: #ffaa00
FollowComboBox
id: followLeader
anchors.left: prev.right
anchors.top: prev.top
margin-left: 7
height: 15
width: 145
font: cipsoftFont
CheckBox
id: followLeaderToggle
anchors.left: followLeader.right
anchors.top: followLeader.top
margin-top: 2
margin-left: 5
Label
id: label2
anchors.left: label1.left
anchors.top: label1.bottom
margin-top: 5
text: Attack:
color: #ffaa00
AttackComboBox
id: attackLeaderTarget
anchors.left: prev.right
anchors.top: prev.top
margin-left: 5
height: 15
width: 145
font: cipsoftFont
CheckBox
id: attackLeaderTargetToggle
anchors.left: attackLeaderTarget.right
anchors.top: attackLeaderTarget.top
margin-top: 2
margin-left: 5
Label
id: label3
anchors.left: label2.left
anchors.top: label2.bottom
margin-top: 5
text: Spell:
color: #ffaa00
TextEdit
id: attackSpell
anchors.left: prev.right
anchors.top: prev.top
anchors.right: attackLeaderTarget.right
margin-left: 17
height: 15
width: 145
font: cipsoftFont
CheckBox
id: attackSpellToggle
anchors.left: attackSpell.right
anchors.top: attackSpell.top
margin-top: 2
margin-left: 5
Label
id: label4
anchors.left: label3.left
anchors.top: label3.bottom
margin-top: 15
text: Attack Item:
color: #ffaa00
BotItem
id: attackItem
anchors.left: prev.right
anchors.verticalCenter: prev.verticalCenter
margin-left: 10
CheckBox
id: attackItemToggle
anchors.left: prev.right
anchors.verticalCenter: prev.verticalCenter
margin-left: 5
BotSwitch
id: commandsToggle
anchors.left: prev.right
anchors.top: attackItem.top
anchors.right: attackSpellToggle.right
anchors.bottom: attackItem.bottom
margin-left: 5
text: Leader Commands
text-wrap: true
multiline: true
BotServer < Panel
id: server
image-source: /images/ui/panel_flat
image-border: 6
padding: 3
size: 220 100
Label
id: labelX
anchors.left: parent.left
anchors.top: parent.top
text: Leader:
height: 15
color: #ffaa00
margin-left: 3
margin-top: 5
TextEdit
id: botServerLeader
anchors.left: prev.right
anchors.top: prev.top
anchors.right: parent.right
margin-right: 3
margin-left: 9
height: 15
font: cipsoftFont
Button
id: partyButton
anchors.left: labelX.left
anchors.top: botServerLeader.bottom
margin-top: 5
height: 30
text: Join Party
text-wrap: true
multiline: true
BotSwitch
id: botServerToggle
anchors.left: prev.right
anchors.top: botServerLeader.bottom
anchors.right: parent.right
height: 30
margin-left: 3
margin-right: 3
margin-top: 5
text: Server Enabled
BotSwitch
id: targetServerLeaderToggle
anchors.left: partyButton.left
anchors.top: partyButton.bottom
anchors.right: partyButton.right
margin-top: 3
height: 30
text: Leader Targets
BotSwitch
id: Triggers
anchors.left: prev.right
anchors.top: partyButton.bottom
anchors.right: parent.right
margin-top: 3
height: 30
margin-left: 3
margin-right: 3
text: Triggers
ComboWindow < MainWindow
!text: tr('Combo Options')
size: 500 280
@onEscape: self:hide()
ComboTrigger
id: trigger
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
margin-top: 7
Label
id: title
anchors.top: parent.top
anchors.left: parent.left
margin-left: 10
text: Combo Trigger
color: #ff7700
ComboActions
id: actions
anchors.top: trigger.bottom
anchors.left: trigger.left
margin-top: 15
Label
id: title
anchors.top: parent.top
anchors.left: parent.left
margin-left: 10
margin-top: 85
text: Combo Actions
color: #ff7700
BotServer
id: server
anchors.top: actions.top
anchors.left: actions.right
margin-left: 10
Label
id: title
anchors.top: parent.top
anchors.left: server.left
margin-left: 3
margin-top: 85
text: BotServer
color: #ff7700
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
Button
id: toolsButton
!text: tr('Help')
font: cipsoftFont
anchors.right: closeButton.left
anchors.top: closeButton.top
margin-right: 10
size: 45 21
@onClick: g_platform.openUrl("http://bot.otclient.ovh/books/scripts/page/combobot")

View File

@@ -0,0 +1,87 @@
--[[
Configs for modules
Based on Kondrah storage method
--]]
configName = modules.game_bot.contentsPanel.config:getCurrentOption().text
-- make vBot config dir
if not g_resources.directoryExists("/bot/".. configName .."/vBot_configs/") then
g_resources.makeDir("/bot/".. configName .."/vBot_configs/")
end
HealBotConfig = {}
local healBotFile = "/bot/" .. configName .. "/vBot_configs/".. name() .. " HealBot.json"
AttackBotConfig = {}
local attackBotFile = "/bot/" .. configName .. "/vBot_configs/".. name() .. " AttackBot.json"
SuppliesConfig = {}
local suppliesFile = "/bot/" .. configName .. "/vBot_configs/".. name() .. " Supplies.json"
--healbot
if g_resources.fileExists(healBotFile) then
local status, result = pcall(function()
return json.decode(g_resources.readFileContents(healBotFile))
end)
if not status then
return onError("Error while reading config file (" .. healBotFile .. "). To fix this problem you can delete HealBot.json. Details: " .. result)
end
HealBotConfig = result
end
--attackbot
if g_resources.fileExists(attackBotFile) then
local status, result = pcall(function()
return json.decode(g_resources.readFileContents(attackBotFile))
end)
if not status then
return onError("Error while reading config file (" .. attackBotFile .. "). To fix this problem you can delete HealBot.json. Details: " .. result)
end
AttackBotConfig = result
end
--supplies
if g_resources.fileExists(suppliesFile) then
local status, result = pcall(function()
return json.decode(g_resources.readFileContents(suppliesFile))
end)
if not status then
return onError("Error while reading config file (" .. suppliesFile .. "). To fix this problem you can delete HealBot.json. Details: " .. result)
end
SuppliesConfig = result
end
function vBotConfigSave(file)
-- file can be either
--- heal
--- atk
--- supply
local configFile
local configTable
if not file then return end
file = file:lower()
if file == "heal" then
configFile = healBotFile
configTable = HealBotConfig
elseif file == "atk" then
configFile = attackBotFile
configTable = AttackBotConfig
elseif file == "supply" then
configFile = suppliesFile
configTable = SuppliesConfig
else
return
end
local status, result = pcall(function()
return json.encode(configTable, 2)
end)
if not status then
return onError("Error while saving config. it won't be saved. Details: " .. result)
end
if result:len() > 100 * 1024 * 1024 then
return onError("config file is too big, above 100MB, it won't be saved")
end
g_resources.writeFileContents(configFile, result)
end

View File

@@ -0,0 +1,76 @@
-- config
setDefaultTab("Tools")
local defaultBp = "shopping bag"
local id = 21411
-- script
local playerContainer = nil
local depotContainer = nil
local mailContainer = nil
function reopenLootContainer()
for _, container in pairs(getContainers()) do
if container:getName():lower() == defaultBp:lower() then
g_game.close(container)
end
end
local lootItem = findItem(id)
if lootItem then
schedule(500, function() g_game.open(lootItem) end)
end
end
macro(50, "Depot Withdraw", function()
-- set the containers
if not potionsContainer or not runesContainer or not ammoContainer then
for i, container in pairs(getContainers()) do
if container:getName() == defaultBp then
playerContainer = container
elseif string.find(container:getName(), "Depot") then
depotContainer = container
elseif string.find(container:getName(), "your inbox") then
mailContainer = container
end
end
end
if playerContainer and #playerContainer:getItems() == 20 then
for j, item in pairs(playerContainer:getItems()) do
if item:getId() == id then
g_game.open(item, playerContainer)
return
end
end
end
if playerContainer and freecap() >= 200 then
local time = 500
if depotContainer then
for i, container in pairs(getContainers()) do
if string.find(container:getName(), "Depot") then
for j, item in pairs(container:getItems()) do
g_game.move(item, playerContainer:getSlotPosition(playerContainer:getItemsCount()), item:getCount())
return
end
end
end
end
if mailContainer then
for i, container in pairs(getContainers()) do
if string.find(container:getName(), "your inbox") then
for j, item in pairs(container:getItems()) do
g_game.move(item, playerContainer:getSlotPosition(playerContainer:getItemsCount()), item:getCount())
return
end
end
end
end
end
end)

View File

@@ -0,0 +1,28 @@
setDefaultTab("HP")
UI.Label("Eatable items:")
if type(storage.foodItems) ~= "table" then
storage.foodItems = {3582, 3577}
end
local foodContainer = UI.Container(function(widget, items)
storage.foodItems = items
end, true)
foodContainer:setHeight(35)
foodContainer:setItems(storage.foodItems)
macro(500, "Eat Food", function()
if player:getRegenerationTime() > 400 or not storage.foodItems[1] then return end
-- search for food in containers
for _, container in pairs(g_game.getContainers()) do
for __, item in ipairs(container:getItems()) do
for i, foodItem in ipairs(storage.foodItems) do
if item:getId() == foodItem.id then
return g_game.use(item)
end
end
end
end
end)
UI.Separator()

View File

@@ -0,0 +1,36 @@
-- config
setDefaultTab("HP")
local scripts = 2 -- if you want more auto equip panels you can change 2 to higher value
-- script by kondrah, don't edit below unless you know what you are doing
UI.Label("Auto equip")
if type(storage.autoEquip) ~= "table" then
storage.autoEquip = {}
end
for i=1,scripts do
if not storage.autoEquip[i] then
storage.autoEquip[i] = {on=false, title="Auto Equip", item1=i == 1 and 3052 or 0, item2=i == 1 and 3089 or 0, slot=i == 1 and 9 or 0}
end
UI.TwoItemsAndSlotPanel(storage.autoEquip[i], function(widget, newParams)
storage.autoEquip[i] = newParams
end)
end
macro(250, function()
local containers = g_game.getContainers()
for index, autoEquip in ipairs(storage.autoEquip) do
if autoEquip.on then
local slotItem = getSlot(autoEquip.slot)
if not slotItem or (slotItem:getId() ~= autoEquip.item1 and slotItem:getId() ~= autoEquip.item2) then
for _, container in pairs(containers) do
for __, item in ipairs(container:getItems()) do
if item:getId() == autoEquip.item1 or item:getId() == autoEquip.item2 then
g_game.move(item, {x=65535, y=autoEquip.slot, z=0}, item:getCount())
delay(1000) -- don't call it too often
return
end
end
end
end
end
end
end)

View File

@@ -0,0 +1,26 @@
local voc = player:getVocation()
if voc == 1 or voc == 11 then
setDefaultTab("Cave")
UI.Separator()
local m = macro(100000, "Exeta when low hp", function() end)
local lastCast = now
onCreatureHealthPercentChange(function(creature, healthPercent)
if m.isOff() then return end
if healthPercent > 15 then return end
if CaveBot.isOff() or TargetBot.isOff() or not isBuffed() then return end
if modules.game_cooldown.isGroupCooldownIconActive(3) then return end
if creature:getPosition() and getDistanceBetween(pos(),creature:getPosition()) > 1 then return end
if canCast("exeta res") and now - lastCast > 6000 then
say("exeta res")
lastCast = now
end
end)
macro(500, "ExetaIfPlayer", function()
if getMonsters(6) >= 1 and getPlayers(6) > 0 then
say("exeta res")
delay(6000)
end
end)
UI.Separator()
end

View File

@@ -0,0 +1,434 @@
setDefaultTab("Main")
-- securing storage namespace
panelName = "extras"
if not storage[panelName] then
storage[panelName] = {}
end
local settings = storage[panelName]
-- basic elements
extrasWindow = UI.createWindow('ExtrasWindow', rootWidget)
extrasWindow:hide()
extrasWindow.closeButton.onClick = function(widget)
extrasWindow:hide()
end
-- available options for dest param
local rightPanel = extrasWindow.content.right
local leftPanel = extrasWindow.content.left
-- objects made by Kondrah - taken from creature editor, minor changes to adapt
local addCheckBox = function(id, title, defaultValue, dest)
local widget = UI.createWidget('ExtrasCheckBox', dest)
widget.onClick = function()
widget:setOn(not widget:isOn())
settings[id] = widget:isOn()
end
widget:setText(title)
if settings[id] == nil then
widget:setOn(defaultValue)
else
widget:setOn(settings[id])
end
settings[id] = widget:isOn()
end
local addItem = function(id, title, defaultItem, dest)
local widget = UI.createWidget('ExtrasItem', dest)
widget.text:setText(title)
widget.item:setItemId(settings[id] or defaultItem)
widget.item.onItemChange = function(widget)
settings[id] = widget:getItemId()
end
settings[id] = settings[id] or defaultItem
end
local addTextEdit = function(id, title, defaultValue, dest)
local widget = UI.createWidget('ExtrasTextEdit', dest)
widget.text:setText(title)
widget.textEdit:setText(settings[id] or defaultValue or "")
widget.textEdit.onTextChange = function(widget,text)
settings[id] = text
end
settings[id] = settings[id] or defaultValue or ""
end
local addScrollBar = function(id, title, min, max, defaultValue, dest)
local widget = UI.createWidget('ExtrasScrollBar', dest)
widget.scroll.onValueChange = function(scroll, value)
widget.text:setText(title .. ": " .. value)
if value == 0 then
value = 1
end
settings[id] = value
end
widget.scroll:setRange(min, max)
if max-min > 1000 then
widget.scroll:setStep(100)
elseif max-min > 100 then
widget.scroll:setStep(10)
end
widget.scroll:setValue(settings[id] or defaultValue)
widget.scroll.onValueChange(widget.scroll, widget.scroll:getValue())
end
UI.Button("vBot Settings and Scripts", function()
extrasWindow:show()
extrasWindow:raise()
extrasWindow:focus()
end)
UI.Separator()
---- to maintain order, add options right after another:
--- add object
--- add variables for function (optional)
--- add callback (optional)
--- optionals should be addionaly sandboxed (if true then end)
addItem("rope", "Rope Item", 9596, leftPanel)
addItem("shovel", "Shovel Item", 9596, leftPanel)
addItem("machete", "Machete Item", 9596, leftPanel)
addItem("scythe", "Scythe Item", 9596, leftPanel)
addScrollBar("talkDelay", "Global NPC Talk Delay", 0, 2000, 1000, leftPanel)
addScrollBar("looting", "Max Loot Distance", 0, 50, 40, leftPanel)
addCheckBox("title", "Custom Window Title", true, rightPanel)
if true then
local vocText = ""
if voc() == 1 or voc() == 11 then
vocText = "- EK"
elseif voc() == 2 or voc() == 12 then
vocText = "- RP"
elseif voc() == 3 or voc() == 13 then
vocText = "- MS"
elseif voc() == 4 or voc() == 14 then
vocText = "- ED"
end
macro(2000, function()
if settings.title then
if hppercent() > 0 then
g_window.setTitle("Tibia - " .. name() .. " - " .. lvl() .. "lvl " .. vocText)
else
g_window.setTitle("Tibia - " .. name() .. " - DEAD")
end
else
g_window.setTitle("Tibia - " .. name())
end
end)
end
addTextEdit("useAll", "Use All Hotkey", "space", rightPanel)
if true then
local useId = {34847, 1764, 21051, 30823, 6264, 5282, 20453, 20454, 20474, 11708, 11705,
6257, 6256, 2772, 27260, 2773, 1632, 1633, 1948, 435, 6252, 6253, 5007, 4911,
1629, 1630, 5108, 5107, 5281, 1968, 435, 1948, 5542, 31116, 31120, 30742, 31115,
31118, 20474, 5737, 5736, 5734, 5733, 31202, 31228, 31199, 31200, 33262, 30824,
5125, 5126, 5116, 5117, 8257, 8258, 8255, 8256, 5120, 30777, 30776}
local shovelId = {606, 593, 867}
local ropeId = {17238, 12202, 12935, 386, 421, 21966, 14238}
local macheteId = {2130, 3696}
local scytheId = {3653}
setDefaultTab("Tools")
-- script
if settings.useAll and settings.useAll:len() > 0 then
hotkey(settings.useAll, function()
if not modules.game_walking.wsadWalking then return end
for _, tile in pairs(g_map.getTiles(posz())) do
if distanceFromPlayer(tile:getPosition()) < 2 then
for _, item in pairs(tile:getItems()) do
-- use
if table.find(useId, item:getId()) then
use(item)
return
elseif table.find(shovelId, item:getId()) then
useWith(settings.shovel, item)
return
elseif table.find(ropeId, item:getId()) then
useWith(settings.rope, item)
return
elseif table.find(macheteId, item:getId()) then
useWith(settings.machete, item)
return
elseif table.find(scytheId, item:getId()) then
useWith(settings.scythe, item)
return
end
end
end
end
end)
end
end
addCheckBox("timers", "MW & WG Timers", true, rightPanel)
if true then
local activeTimers = {}
onAddThing(function(tile, thing)
if not settings.timers then return end
if not thing:isItem() then
return
end
local timer = 0
if thing:getId() == 2129 then -- mwall id
timer = 20000 -- mwall time
elseif thing:getId() == 2130 then -- wg id
timer = 45000 -- wg time
else
return
end
local pos = tile:getPosition().x .. "," .. tile:getPosition().y .. "," .. tile:getPosition().z
if not activeTimers[pos] or activeTimers[pos] < now then
activeTimers[pos] = now + timer
end
tile:setTimer(activeTimers[pos] - now)
end)
onRemoveThing(function(tile, thing)
if not settings.timers then return end
if not thing:isItem() then
return
end
if (thing:getId() == 2129 or thing:getId() == 2130) and tile:getGround() then
local pos = tile:getPosition().x .. "," .. tile:getPosition().y .. "," .. tile:getPosition().z
activeTimers[pos] = nil
tile:setTimer(0)
end
end)
end
addCheckBox("antiKick", "Anti - Kick", true, rightPanel)
if true then
macro(600*1000, function()
if not settings.antiKick then return end
local dir = player:getDirection()
turn((dir + 1) % 4)
schedule(50, function() turn(dir) end)
end)
end
addCheckBox("stake", "Skin Monsters", false, leftPanel)
if true then
local knifeBodies = {4272, 4173, 4011, 4025, 4047, 4052, 4057, 4062, 4112, 4212, 4321, 4324, 4327, 10352, 10356, 10360, 10364}
local stakeBodies = {4097, 4137, 8738, 18958}
local fishingBodies = {9582}
macro(500, function()
if not CaveBot.isOn() or not settings.stake then return end
for i, tile in ipairs(g_map.getTiles(posz())) do
for u,item in ipairs(tile:getItems()) do
if table.find(knifeBodies, item:getId()) and findItem(5908) then
CaveBot.delay(550)
useWith(5908, item)
return
end
if table.find(stakeBodies, item:getId()) and findItem(5942) then
CaveBot.delay(550)
useWith(5942, item)
return
end
if table.find(fishingBodies, item:getId()) and findItem(3483) then
CaveBot.delay(550)
useWith(3483, item)
return
end
end
end
end)
end
addCheckBox("oberon", "Auto Reply Oberon", true, rightPanel)
if true then
onTalk(function(name, level, mode, text, channelId, pos)
if not settings.oberon then return end
if mode == 34 then
if string.find(text, "world will suffer for") then
say("Are you ever going to fight or do you prefer talking!")
elseif string.find(text, "feet when they see me") then
say("Even before they smell your breath?")
elseif string.find(text, "from this plane") then
say("Too bad you barely exist at all!")
elseif string.find(text, "ESDO LO") then
say("SEHWO ASIMO, TOLIDO ESD")
elseif string.find(text, "will soon rule this world") then
say("Excuse me but I still do not get the message!")
elseif string.find(text, "honourable and formidable") then
say("Then why are we fighting alone right now?")
elseif string.find(text, "appear like a worm") then
say("How appropriate, you look like something worms already got the better of!")
elseif string.find(text, "will be the end of mortal") then
say("Then let me show you the concept of mortality before it!")
elseif string.find(text, "virtues of chivalry") then
say("Dare strike up a Minnesang and you will receive your last accolade!")
end
end
end)
end
addCheckBox("autoOpenDoors", "Auto Open Doors", true, rightPanel)
if true then
local wsadWalking = modules.game_walking.wsadWalking
local doorsIds = { 5007, 8265, 1629, 1632, 5129, 6252, 6249, 7715, 7712, 7714,
7719, 6256, 1669, 1672, 5125, 5115, 5124, 17701, 17710, 1642,
6260, 5107, 4912, 6251, 5291, 1683, 1696, 1692, 5006, 2179, 5116,
1632, 11705, 30772, 30774, 6248, 5735, 5732, 5120 }
function checkForDoors(pos)
local tile = g_map.getTile(pos)
if tile then
local useThing = tile:getTopUseThing()
if useThing and table.find(doorsIds, useThing:getId()) then
g_game.use(useThing)
end
end
end
onKeyPress(function(keys)
if not settings.autoOpenDoors then return end
local pos = player:getPosition()
if keys == 'Up' or (wsadWalking and keys == 'W') then
pos.y = pos.y - 1
elseif keys == 'Down' or (wsadWalking and keys == 'S') then
pos.y = pos.y + 1
elseif keys == 'Left' or (wsadWalking and keys == 'A') then
pos.x = pos.x - 1
elseif keys == 'Right' or (wsadWalking and keys == 'D') then
pos.x = pos.x + 1
elseif wsadWalking and keys == "Q" then
pos.y = pos.y - 1
pos.x = pos.x - 1
elseif wsadWalking and keys == "E" then
pos.y = pos.y - 1
pos.x = pos.x + 1
elseif wsadWalking and keys == "Z" then
pos.y = pos.y + 1
pos.x = pos.x - 1
elseif wsadWalking and keys == "C" then
pos.y = pos.y + 1
pos.x = pos.x + 1
end
checkForDoors(pos)
end)
end
addCheckBox("bless", "Buy bless at login", true, rightPanel)
if true then
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
warn("!! Blessings not bought !!")
end
end
end)
end
end
end
addCheckBox("reUse", "Keep Crosshair", false, rightPanel)
if true then
local excluded = {268, 237, 238, 23373, 266, 236, 239, 7643, 23375, 7642, 23374, 5908, 5942}
onUseWith(function(pos, itemId, target, subType)
if settings.reUse and not table.find(excluded, itemId) then
schedule(50, function()
item = findItem(itemId)
if item then
modules.game_interface.startUseWith(item)
end
end)
end
end)
end
addCheckBox("suppliesControl", "TargetBot off if low supply", false, leftPanel)
if true then
macro(500, function()
if not settings.suppliesControl then return end
if TargetBot.isOff() then return end
if CaveBot.isOff() then return end
if not hasSupplies() then
TargetBot.setOff()
end
end)
end
addCheckBox("holdMwall", "Hold MW/WG [ , ][ . ]", true, rightPanel)
if true then
local mwHot = ","
local wgHot = "."
local candidates = {}
local m = macro(20, function()
if not settings.holdMwall then return end
if #candidates == 0 then return end
for i, tile in pairs(candidates) do
if tile:getText():len() == 0 then
table.remove(candidates, i)
end
local rune = tile:getText() == "HOLD MW" and 3180 or 3156
if tile:canShoot() and not isInPz() and tile:isWalkable() and tile:getTopUseThing():getId() ~= 2130 then
return useWith(rune, tile:getTopUseThing())
end
end
end)
onRemoveThing(function(tile, thing)
if not settings.holdMwall then return end
if thing:getId() ~= 2129 then return end
if tile:getText():len() > 0 then
table.insert(candidates, tile)
useWith(3180, tile:getTopUseThing())
end
end)
onAddThing(function(tile, thing)
if not settings.holdMwall then return end
if m.isOff() then return end
if thing:getId() ~= 2129 then return end
if tile:getText():len() > 0 then
table.remove(candidates, table.find(candidates,tile))
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
local tile = getTileUnderCursor()
if not tile then return end
if tile:getText():len() > 0 then
tile:setText("")
else
if keys == mwHot then
tile:setText("HOLD MW")
else
tile:setText("HOLD WG")
end
table.insert(candidates, tile)
end
end)
end

View File

@@ -0,0 +1,147 @@
ExtrasScrollBar < Panel
height: 28
margin-top: 3
Label
id: text
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
text-align: center
HorizontalScrollBar
id: scroll
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 3
minimum: 0
maximum: 10
step: 1
ExtrasTextEdit < Panel
height: 40
margin-top: 7
Label
id: text
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
text-align: center
TextEdit
id: textEdit
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 5
minimum: 0
maximum: 10
step: 1
ExtrasItem < Panel
height: 34
margin-top: 7
margin-left: 25
margin-right: 25
Label
id: text
anchors.left: parent.left
anchors.verticalCenter: next.verticalCenter
BotItem
id: item
anchors.top: parent.top
anchors.right: parent.right
ExtrasCheckBox < BotSwitch
height: 20
margin-top: 7
ExtrasWindow < MainWindow
!text: tr('Extras')
size: 440 360
padding: 25
Label
anchors.left: parent.left
anchors.right: parent.horizontalCenter
anchors.top: parent.top
text-align: center
text: < CaveBot >
Label
anchors.left: parent.horizontalCenter
anchors.right: parent.right
anchors.top: parent.top
text-align: center
text: < Miscellaneous >
VerticalScrollBar
id: contentScroll
anchors.top: prev.bottom
margin-top: 3
anchors.right: parent.right
anchors.bottom: separator.top
step: 28
pixels-scroll: true
margin-right: -10
margin-top: 5
margin-bottom: 5
ScrollablePanel
id: content
anchors.top: prev.top
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: separator.top
vertical-scrollbar: contentScroll
margin-bottom: 10
Panel
id: left
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.horizontalCenter
margin-top: 5
margin-left: 10
margin-right: 10
layout:
type: verticalBox
fit-children: true
Panel
id: right
anchors.top: parent.top
anchors.left: parent.horizontalCenter
anchors.right: parent.right
margin-top: 5
margin-left: 10
margin-right: 10
layout:
type: verticalBox
fit-children: true
VerticalSeparator
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.horizontalCenter
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-right: 5

View File

@@ -0,0 +1,477 @@
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 = "-"
if not storage.bestHit or type(storage.bestHit) ~= "number" then
storage.bestHit = 0
end
if not storage.bestHeal or type(storage.bestHeal) ~= "number" then
storage.bestHeal = 0
end
local resetSessionData = function()
launchTime = now
startExp = exp()
dmgTable = {}
healTable = {}
expTable = {}
totalDmg = 0
totalHeal = 0
dmgDistribution = {}
first = "-"
second = "-"
third = "-"
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 sessionTime = function()
uptime = math.floor((now - launchTime)/1000)
return niceTimeFormat(uptime)
end
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) > storage.bestHit then
storage.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) > storage.bestHeal then
storage.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
local ui = setupUI([[
Panel
height: 320
padding: 5
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: 5
anchors.left: parent.left
anchors.right: parent.right
text: Reset Session
Label
id: SessionLabel
anchors.top: prev.bottom
margin-top: 3
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: 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: 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: -
]])
ui:setId("analyzers")
local function toggleHeight()
local h = ui:getHeight()
if h == 320 then
ui:setHeight(28)
else
ui:setHeight(320)
end
end
toggleHeight()
ui.reset.onClick = function(widget)
resetSessionData()
end
ui.toggle.onClick = function(widget)
toggleHeight()
end
macro(500, function()
-- refresh part
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(storage.bestHit))
ui.nine:setText(format_thousand(totalHeal))
ui.ten:setText(format_thousand(valueInSeconds(healTable)))
ui.eleven:setText(format_thousand(storage.bestHeal))
ui.dOne:setText(first)
ui.dTwo:setText(second)
ui.dThree:setText(third)
end)

View File

@@ -0,0 +1,23 @@
setDefaultTab("Tools")
-- allows to test/edit bot lua scripts ingame, you can have multiple scripts like this, just change storage.ingame_lua
UI.Button("Ingame script editor", function(newText)
UI.MultilineEditorWindow(storage.ingame_hotkeys or "", {title="Hotkeys editor", description="You can add your custom scrupts here"}, function(text)
storage.ingame_hotkeys = text
reload()
end)
end)
UI.Separator()
for _, scripts in pairs({storage.ingame_hotkeys}) do
if type(scripts) == "string" and scripts:len() > 3 then
local status, result = pcall(function()
assert(load(scripts, "ingame_editor"))()
end)
if not status then
error("Ingame edior error:\n" .. result)
end
end
end
UI.Separator()

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,78 @@
setDefaultTab("Tools")
UI.Label("Items Management")
UI.Separator()
UI.Label("Trash items:")
if type(storage.trashItems) ~= "table" or not storage.trashItems then
storage.trashItems = {283, 284, 285}
end
local dropContainer = UI.Container(function(widget, items)
storage.trashItems = items
end, true)
dropContainer:setHeight(35)
dropContainer:setItems(storage.trashItems)
macro(200, "Drop Items", function()
if not storage.trashItems[1] then return end
for _, container in pairs(g_game.getContainers()) do
for __, item in ipairs(container:getItems()) do
for i, trashItem in ipairs(storage.trashItems) do
if item:getId() == trashItem.id then
return g_game.move(item, pos(), item:getCount())
end
end
end
end
end)
UI.Label("Items to use:")
if type(storage.useItems) ~= "table" or not storage.useItems then
storage.useItems = {21203, 14758}
end
local useContainer = UI.Container(function(widget, items)
storage.useItems = items
end, true)
useContainer:setHeight(35)
useContainer:setItems(storage.useItems)
macro(200, "Use Items", function()
if not storage.useItems[1] then return end
for _, container in pairs(g_game.getContainers()) do
for __, item in ipairs(container:getItems()) do
for i, useItem in ipairs(storage.useItems) do
if item:getId() == useItem.id then
return use(item)
end
end
end
end
end)
UI.Label("Items to drop below 150 cap:")
if type(storage.lowCapDrop) ~= "table" or not storage.lowCapDrop then
storage.lowCapDrop = {21175}
end
local useContainer = UI.Container(function(widget, items)
storage.lowCapDrop = items
end, true)
useContainer:setHeight(35)
useContainer:setItems(storage.lowCapDrop)
macro(200, "Drop Items", function()
if not storage.lowCapDrop[1] then return end
if freecap() > 150 then return end
for _, container in pairs(g_game.getContainers()) do
for __, item in ipairs(container:getItems()) do
for i, dropItem in ipairs(storage.lowCapDrop) do
if item:getId() == dropItem.id then
return g_game.move(item, pos(), item:getCount())
end
end
end
end
end)
UI.Separator()

View File

@@ -0,0 +1,367 @@
setDefaultTab("HP")
function jewelleryEquip()
panelName = "jewelleryEquipper"
local ui = setupUI([[
Panel
height: 133
margin-top: 2
BotItem
id: ringId
anchors.left: parent.left
anchors.top: parent.top
SmallBotSwitch
id: ringSwitch
anchors.left: ringId.right
anchors.right: parent.right
anchors.top: parent.top
text-align: center
text: Equip Ring
margin-left: 3
margin-right: 45
SmallBotSwitch
id: valueRing
anchors.left: ringSwitch.right
anchors.right: parent.right
anchors.top: parent.top
text-align: center
text: Mana
margin-left: 3
margin-right: 0
BotLabel
id: ringTitle
anchors.left: ringId.right
anchors.right: parent.right
anchors.top: ringId.verticalCenter
text-align: center
HorizontalScrollBar
id: ringScroll1
anchors.left: parent.left
anchors.right: parent.horizontalCenter
anchors.top: ringId.bottom
margin-right: 2
margin-top: 2
minimum: 0
maximum: 100
step: 1
HorizontalScrollBar
id: ringScroll2
anchors.left: parent.horizontalCenter
anchors.right: parent.right
anchors.top: prev.top
margin-left: 2
minimum: 0
maximum: 100
step: 1
BotItem
id: ammyId
anchors.left: parent.left
anchors.top: ringScroll1.bottom
margin-top: 5
SmallBotSwitch
id: ammySwitch
anchors.left: ammyId.right
anchors.right: parent.right
anchors.top: ringScroll2.bottom
text-align: center
text: Equip Amulet
margin-top: 5
margin-left: 3
margin-right: 45
SmallBotSwitch
id: valueAmmy
anchors.left: ammySwitch.right
anchors.right: parent.right
anchors.top: ringScroll2.bottom
text-align: center
text: Mana
margin-top: 5
margin-left: 3
BotLabel
id: ammyTitle
anchors.left: ammyId.right
anchors.right: parent.right
anchors.top: ammyId.verticalCenter
text-align: center
HorizontalScrollBar
id: ammyScroll1
anchors.left: parent.left
anchors.right: parent.horizontalCenter
anchors.top: ammyId.bottom
margin-right: 2
margin-top: 2
minimum: 0
maximum: 100
step: 1
HorizontalScrollBar
id: ammyScroll2
anchors.left: parent.horizontalCenter
anchors.right: parent.right
anchors.top: prev.top
margin-left: 2
minimum: 0
maximum: 100
step: 1
SmallBotSwitch
id: safe
anchors.top: ammyScroll2.bottom
anchors.right: parent.right
anchors.bottom: parent.bottom
text: Safe min
margin-top: 5
width: 60
BotLabel
id: safeText
anchors.top: ammyScroll2.bottom
anchors.left: parent.left
anchors.right: prev.left
anchors.bottom: prev.verticalCenter
text-align: center
text: Stop if below 99%
HorizontalScrollBar
id: safeMin
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: safe.left
anchors.bottom: safe.bottom
margin-left: 2
margin-top: 2
margin-right: 5
minimum: 0
maximum: 99
step: 1
]], parent)
ui:setId(panelName)
if not storage[panelName] or not storage[panelName].ringId or not storage[panelName].ammyId then
storage[panelName] = {
ringSwitch = true,
ammySwitch = true,
ringId = 3048,
ammyId = 3081,
ringMin = 30,
ringMax = 80,
ammyMin = 30,
ammyMax = 80,
valueAmmy = false,
valueRing = false,
ringValue = "HP",
ammyValue = "HP",
safe = true,
safeMin = 30
}
end
if not storage[panelName].safeMin then
storage[panelName].safeMin = 30
end
ui.ringSwitch:setOn(storage[panelName].ringEnabled)
ui.ringSwitch.onClick = function(widget)
storage[panelName].ringEnabled = not storage[panelName].ringEnabled
widget:setOn(storage[panelName].ringEnabled)
end
ui.safe:setOn(storage[panelName].safe)
ui.safe.onClick = function(widget)
storage[panelName].safe = not storage[panelName].safe
widget:setOn(storage[panelName].safe)
end
ui.ammySwitch:setOn(storage[panelName].ammyEnabled)
ui.ammySwitch.onClick = function(widget)
storage[panelName].ammyEnabled = not storage[panelName].ammyEnabled
widget:setOn(storage[panelName].ammyEnabled)
end
local updateRingText = function()
ui.ringTitle:setText("" .. storage[panelName].ringMin .. "% <= " .. storage[panelName].ringValue .. " >= " .. storage[panelName].ringMax .. "%")
end
local updateAmmyText = function()
ui.ammyTitle:setText("" .. storage[panelName].ammyMin .. "% <= " .. storage[panelName].ammyValue .. " >= " .. storage[panelName].ammyMax .. "%")
end
local updateSafeText = function()
ui.safeText:setText("Stop if below " .. storage[panelName].safeMin .. "%")
end
updateSafeText()
ui.valueRing:setOn(storage[panelName].valueRing)
ui.valueRing.onClick = function(widget)
storage[panelName].valueRing = not storage[panelName].valueRing
widget:setOn(storage[panelName].valueRing)
if storage[panelName].valueRing then
storage[panelName].ringValue = "MP"
else
storage[panelName].ringValue = "HP"
end
updateRingText()
end
ui.valueAmmy:setOn(storage[panelName].valueAmmy)
ui.valueAmmy.onClick = function(widget)
storage[panelName].valueAmmy = not storage[panelName].valueAmmy
widget:setOn(storage[panelName].valueAmmy)
if storage[panelName].valueAmmy then
storage[panelName].ammyValue = "MP"
else
storage[panelName].ammyValue = "HP"
end
updateAmmyText()
end
ui.ringScroll1.onValueChange = function(scroll, value)
storage[panelName].ringMin = value
updateRingText()
end
ui.ringScroll2.onValueChange = function(scroll, value)
storage[panelName].ringMax = value
updateRingText()
end
ui.ammyScroll1.onValueChange = function(scroll, value)
storage[panelName].ammyMin = value
updateAmmyText()
end
ui.ammyScroll2.onValueChange = function(scroll, value)
storage[panelName].ammyMax = value
updateAmmyText()
end
ui.ringId.onItemChange = function(widget)
storage[panelName].ringId = widget:getItemId()
end
ui.ammyId.onItemChange = function(widget)
storage[panelName].ammyId = widget:getItemId()
end
ui.safeMin.onValueChange = function(scroll, value)
storage[panelName].safeMin = value
updateSafeText()
end
ui.ringScroll1:setValue(storage[panelName].ringMin)
ui.ringScroll2:setValue(storage[panelName].ringMax)
ui.ammyScroll1:setValue(storage[panelName].ammyMin)
ui.ammyScroll2:setValue(storage[panelName].ammyMax)
ui.ringId:setItemId(storage[panelName].ringId)
ui.ammyId:setItemId(storage[panelName].ammyId)
ui.safeMin:setValue(storage[panelName].safeMin)
local defaultRing
local defaultAmmy
-- basic ring check
function defaultRingFind()
if storage[panelName].ringEnabled then
if getFinger() and (getFinger():getId() ~= storage[panelName].ringId and getFinger():getId() ~= getActiveItemId(storage[panelName].ringId)) then
defaultRing = getInactiveItemId(getFinger():getId())
else
defaultRing = false
end
end
end
-- basic amulet check
function defaultAmmyFind()
if storage[panelName].ammyEnabled then
if getNeck() and (getNeck():getId() ~= storage[panelName].ammyId and getNeck():getId() ~= getActiveItemId(storage[panelName].ammyId)) then
defaultAmmy = getInactiveItemId(getNeck():getId())
else
defaultAmmy = false
end
end
end
local lastAction = now
macro(20, function()
if now - lastAction < math.max(math.max(g_game.getPing()*2,150),300) then return end
if not storage[panelName].ringEnabled and not storage[panelName].ammyEnabled then return end
-- [[ safe findout ]] --
local safeAmmyVal
local safeRingVal
if not storage[panelName].valueAmmy then
safeAmmyVal = hppercent()
else
safeAmmyVal = manapercent()
end
if not storage[panelName].valueRing then
safeRingVal = hppercent()
else
safeRingVal = manapercent()
end
-- [[ condition list ]] --
local ringEnabled = storage[panelName].ringEnabled
local ringEquipped = getFinger() and (getFinger():getId() == storage[panelName].ringId or getFinger():getId() == getActiveItemId(storage[panelName].ringId))
local shouldEquipRing = not storage[panelName].valueRing and hppercent() <= storage[panelName].ringMin or storage[panelName].valueRing and manapercent() <= storage[panelName].ringMin
local shouldUnequipRing = not storage[panelName].valueRing and hppercent() >= storage[panelName].ringMax or storage[panelName].valueRing and manapercent() >= storage[panelName].ringMax
local hasDefaultRing = defaultRing and findItem(defaultRing)
local ammyEnabled = storage[panelName].ammyEnabled
local ammyEquipped = getNeck() and (getNeck():getId() == storage[panelName].ammyId or getNeck():getId() == getActiveItemId(storage[panelName].ammyId))
local shouldEquipAmmy = not storage[panelName].valueAmmy and hppercent() <= storage[panelName].ammyMin or storage[panelName].valueAmmy and manapercent() <= storage[panelName].ammyMin
local shouldUnequipAmmy = not storage[panelName].valueAmmy and hppercent() >= storage[panelName].ammyMax or storage[panelName].valueAmmy and manapercent() >= storage[panelName].ammyMax
local hasDefaultAmmy = defaultAmmy and findItem(defaultAmmy)
local ringIsSafe = not storage[panelName].safe or safeRingVal >= storage[panelName].safeMin
local ammyIsSafe = not storage[panelName].safe or safeAmmyVal >= storage[panelName].safeMin
-- [[ ring ]] --
if ringEnabled then
if not ringEquipped and shouldEquipRing and ringIsSafe then
defaultRingFind()
g_game.equipItemId(storage[panelName].ringId)
lastAction = now
return
elseif ringEquipped and (shouldUnequipRing or not ringIsSafe) then
if hasDefaultRing then
g_game.equipItemId(defaultRing)
lastAction = now
return
else
g_game.equipItemId(storage[panelName].ringId)
lastAction = now
return
end
end
end
-- [[ amulet ]] --
if ammyEnabled then
if not ammyEquipped and shouldEquipAmmy and ammyIsSafe then
defaultAmmyFind()
g_game.equipItemId(storage[panelName].ammyId)
lastAction = now
return
elseif ammyEquipped and (shouldUnequipAmmy or not ammyIsSafe) then
if hasDefaultAmmy then
g_game.equipItemId(defaultAmmy)
lastAction = now
return
else
g_game.equipItemId(storage[panelName].ammyId)
lastAction = now
return
end
end
end
end)
-- end of function
end
if g_game.getClientVersion() >= 1000 then
addSeparator()
UI.Label("-- [[ Equipper ]] --")
addSeparator()
jewelleryEquip()
addSeparator()
end

View File

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

View File

@@ -0,0 +1,456 @@
CaveBot = {} -- global namespace
-------------------------------------------------------------------
-- CaveBot lib 1.0
-- Contains a universal set of functions to be used in CaveBot
----------------------[[ basic assumption ]]-----------------------
-- in general, functions cannot be slowed from within, only externally, by event calls, delays etc.
-- considering that and the fact that there is no while loop, every function return action
-- thus, functions will need to be verified outside themselfs or by another function
-- overall tips to creating extension:
-- - functions return action(nil) or true(done)
-- - extensions are controlled by retries var
-------------------------------------------------------------------
-- local variables, constants and functions, used by global functions
local LOCKERS_LIST = {3497, 3498, 3499, 3500}
local function CaveBotConfigParse()
local name = storage["_configs"]["targetbot_configs"]["selected"]
local file = configDir .. "/targetbot_configs/" .. name .. ".json"
local data = g_resources.readFileContents(file)
return Config.parse(data)['looting']
end
local function getNearTiles(pos)
if type(pos) ~= "table" then
pos = pos:getPosition()
end
local tiles = {}
local dirs = {
{-1, 1},
{0, 1},
{1, 1},
{-1, 0},
{1, 0},
{-1, -1},
{0, -1},
{1, -1}
}
for i = 1, #dirs do
local tile =
g_map.getTile(
{
x = pos.x - dirs[i][1],
y = pos.y - dirs[i][2],
z = pos.z
}
)
if tile then
table.insert(tiles, tile)
end
end
return tiles
end
-- ##################### --
-- [[ Information class ]] --
-- ##################### --
--- global variable to reflect current CaveBot status
CaveBot.Status = "waiting"
--- Parses config and extracts loot list.
-- @return table
function CaveBot.GetLootItems()
local t = CaveBotConfigParse()["items"]
local returnTable = {}
for i, item in pairs(t) do
table.insert(returnTable, item["id"])
end
return returnTable
end
--- Parses config and extracts loot containers.
-- @return table
function CaveBot.GetLootContainers()
local t = CaveBotConfigParse()["containers"]
local returnTable = {}
for i, container in pairs(t) do
table.insert(returnTable, container["id"])
end
return returnTable
end
--- Information about open containers.
-- @param amount is boolean
-- @return table or integer
function CaveBot.GetOpenedLootContainers(containerTable)
local containers = CaveBot.GetLootContainers()
local t = {}
for i, container in pairs(getContainers()) do
local containerId = container:getContainerItem():getId()
if table.find(containers, containerId) then
table.insert(t, container)
end
end
return containerTable and t or #t
end
--- Some actions needs to be additionally slowed down in case of high ping.
-- Maximum at 2000ms in case of lag spike.
-- @param multiplayer is integer
-- @return void
function CaveBot.PingDelay(multiplayer)
multiplayer = multiplayer or 1
if ping() and ping() > 150 then -- in most cases ping above 150 affects CaveBot
local value = math.min(ping() * multiplayer, 2000)
return delay(value)
end
end
-- ##################### --
-- [[ Container class ]] --
-- ##################### --
--- Closes any loot container that is open.
-- @return void or boolean
function CaveBot.CloseLootContainer()
local containers = CaveBot.GetLootContainers()
for i, container in pairs(getContainers()) do
local containerId = container:getContainerItem():getId()
if table.find(containers, containerId) then
return 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()
local containers = CaveBot.GetLootContainers()
local t = {}
for i, container in pairs(getContainers()) do
local containerId = container:getContainerItem():getId()
table.insert(t, containerId)
end
for _, container in pairs(getContainers()) do
for _, item in pairs(container:getItems()) do
local id = item:getId()
if table.find(containers, id) and not table.find(t, id) then
test()
return g_game.open(item)
end
end
end
return true
end
-- ##################### --
-- [[[ Position class ]] --
-- ##################### --
--- Compares distance between player position and given pos.
-- @param position is table
-- @param distance is integer
-- @return boolean
function CaveBot.MatchPosition(position, distance)
local pPos = player:getPosition()
distance = distance or 1
return getDistanceBetween(pPos, position) <= distance
end
--- Stripped down to take less space.
-- Use only to safe position, like pz movement or reaching npc.
-- Needs to be called between 200-500ms to achieve fluid movement.
-- @param position is table
-- @param distance is integer
-- @return void
function CaveBot.GoTo(position, precision)
if not precision then
precision = 3
end
return CaveBot.walkTo(position, 20, {ignoreNonPathable = true, precision = precision})
end
--- Finds position of npc by name and reaches its position.
-- @return void(acion) or boolean
function CaveBot.ReachNPC(name)
name = name:lower()
local npc = nil
for i, spec in pairs(getSpectators()) do
if spec:isNpc() and spec:getName():lower() == name then
npc = spec
end
end
if not CaveBot.MatchPosition(npc:getPosition(), 3) then
CaveBot.GoTo(npc:getPosition())
else
return true
end
end
-- ##################### --
-- [[[[ Depot class ]]]] --
-- ##################### --
--- Reaches closest locker.
-- @return void(acion) or boolean
function CaveBot.ReachDepot()
local pPos = player:getPosition()
local tiles = getNearTiles(player:getPosition())
for i, tile in pairs(tiles) do
for i, item in pairs(tile:getItems()) do
if table.find(LOCKERS_LIST, item:getId()) then
return true -- if near locker already then return function
end
end
end
local candidate = {}
for i, tile in pairs(g_map.getTiles(posz())) do
local tPos = tile:getPosition()
local distance = getDistanceBetween(pPos, tPos)
for i, item in pairs(tile:getItems()) do
if table.find(LOCKERS_LIST, item:getId()) then
if findPath(pos(), tPos, 10, {ignoreNonPathable = true, precision = 1}) then
if #candidate == 0 or candidate.dist < distance then
candidate = {pos = tPos, dist = distance}
end
end
end
end
end
if candidate.pos then
if not CaveBot.MatchPosition(candidate.pos) then
CaveBot.GoTo(candidate.pos, 1)
else
return true
end
end
end
--- Opens locker item.
-- @return void(acion) or boolean
function CaveBot.OpenLocker()
local pPos = player:getPosition()
local tiles = getNearTiles(player:getPosition())
local locker = getContainerByName("Locker")
if not locker then
for i, tile in pairs(tiles) do
for i, item in pairs(tile:getItems()) do
if table.find(LOCKERS_LIST, item:getId()) then
local topThing = tile:getTopUseThing()
if not topThing:isNotMoveable() then
g_game.move(topThing, pPos, topThing:getCount())
else
return g_game.open(item)
end
end
end
end
else
return true
end
end
--- Opens depot chest.
-- @return void(acion) or boolean
function CaveBot.OpenDepotChest()
local depot = getContainerByName("Depot chest")
if not depot then
local locker = getContainerByName("Locker")
if not locker then
return CaveBot.OpenLocker()
end
for i, item in pairs(locker:getItems()) do
if item:getId() == 3502 then
return g_game.open(item, locker)
end
end
else
return true
end
end
--- Opens inbox inside locker.
-- @return void(acion) or boolean
function CaveBot.OpenInbox()
local inbox = getContainerByName("Your inbox")
if not inbox then
local locker = getContainerByName("Locker")
if not locker then
return CaveBot.OpenLocker()
end
for i, item in pairs(locker:getItems()) do
if item:getId() == 12902 then
return g_game.open(item)
end
end
else
return true
end
end
--- Opens depot box of given number.
-- @param index is integer
-- @return void or boolean
function CaveBot.OpenDepotBox(index)
local depot = getContainerByName("Depot chest")
if not depot then
return CaveBot.OpenDepotChest()
end
local foundParent = false
for i, container in pairs(getContainers()) do
if container:getName():lower():find("depot box") then
foundParent = container
break
end
end
if foundParent then return true end
for i, container in pairs(depot:getItems()) do
if i == index then
return g_game.open(container)
end
end
end
--- Reaches and opens depot.
-- Combined for shorthand usage.
-- @return boolean whether succeed to reach and open depot
function CaveBot.ReachAndOpenDepot()
if CaveBot.ReachDepot() and CaveBot.OpenDepotChest() then
return true
end
return false
end
--- Reaches and opens imbox.
-- Combined for shorthand usage.
-- @return boolean whether succeed to reach and open depot
function CaveBot.ReachAndOpenInbox()
if CaveBot.ReachDepot() and CaveBot.OpenInbox() then
return true
end
return false
end
--- Stripped down function to stash item.
-- @param item is object
-- @param index is integer
-- @param destination is object
-- @return void
function CaveBot.StashItem(item, index, destination)
local depotContainer
if not destination then
depotContainer = getContainerByName("Depot chest")
end
if not depotContainer then return false end
return g_game.move(item, depotContainer:getSlotPosition(index), item:getCount())
end
--- Withdraws item from depot chest or mail inbox.
-- main function for depositer/withdrawer
-- @param id is integer
-- @param amount is integer
-- @param fromDepot is boolean or integer
-- @param destination is object
-- @return void
function CaveBot.WithdrawItem(id, amount, fromDepot, destination)
if destination and type(destination) == "string" then
destination = getContainerByName(destination)
end
local itemCount = itemAmount(id)
local depot
for i, container in pairs(getContainers()) do
if container:getName():lower():find("depot box") or container:getName():lower():find("your inbox") then
depot = container
break
end
end
if not depot then
if fromDepot then
if not CaveBot.OpenDepotBox(fromDepot) then return end
else
return CaveBot.ReachAndOpenInbox()
end
return
end
if not destination then
for i, container in pairs(getContainers()) do
if container:getCapacity() > #container:getItems() and not string.find(container:getName():lower(), "quiver") and not string.find(container:getName():lower(), "depot") and not string.find(container:getName():lower(), "loot") and not string.find(container:getName():lower(), "inbox") then
destination = container
end
end
end
if itemCount >= amount then
return true
end
local toMove = amount - itemCount
info(toMove)
for i, item in pairs(depot:getItems()) do
if item:getId() == id then
return g_game.move(item, destination:getSlotPosition(destination:getItemsCount()), math.min(toMove, item:getCount()))
end
end
end
-- ##################### --
-- [[[[[ Talk class ]]]] --
-- ##################### --
--- Controlled by event caller.
-- Simple way to build npc conversations instead of multiline overcopied code.
-- @return void
function CaveBot.Conversation(...)
local expressions = {...}
local delay = storage.extras.talkDelay or 1000
local talkDelay = 0
for i, expr in ipairs(expressions) do
schedule(talkDelay, function() NPC.say(expr) end)
talkDelay = talkDelay + delay
end
end
--- Says hi trade to NPC.
-- Used as shorthand to open NPC trade window.
-- @return void
function CaveBot.OpenNpcTrade()
return CaveBot.Conversation("hi", "trade")
end
--- Says hi destination yes to NPC.
-- Used as shorthand to travel.
-- @param destination is string
-- @return void
function CaveBot.Travel(destination)
return CaveBot.Conversation("hi", destination, "yes")
end

View File

@@ -0,0 +1,209 @@
PlayerName < 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
PlayerListsWindow < MainWindow
!text: tr('Player Lists')
size: 580 350
@onEscape: self:hide()
Label
anchors.left: FriendList.left
anchors.top: parent.top
anchors.right: FriendList.right
text-align: center
text: Friends List
margin-right: 3
TextList
id: FriendList
anchors.top: parent.top
anchors.left: parent.left
margin-top: 15
margin-bottom: 5
margin-right: 3
padding: 1
width: 180
height: 160
vertical-scrollbar: FriendListScrollBar
VerticalScrollBar
id: FriendListScrollBar
anchors.top: FriendList.top
anchors.bottom: FriendList.bottom
anchors.right: FriendList.right
step: 14
pixels-scroll: true
TextEdit
id: FriendName
anchors.right: FriendList.right
anchors.left: FriendList.left
anchors.top: FriendList.bottom
margin-right: 3
margin-top: 5
Button
id: AddFriend
!text: tr('Add Friend')
anchors.right: FriendList.right
anchors.left: FriendList.left
anchors.top: prev.bottom
margin-right: 3
margin-top: 3
Label
anchors.right: EnemyList.right
anchors.top: parent.top
anchors.left: EnemyList.left
text-align: center
text: Enemy List
margin-left: 3
TextList
id: EnemyList
anchors.top: parent.top
anchors.left: FriendList.right
margin-top: 15
margin-bottom: 5
margin-left: 3
padding: 1
width: 180
height: 160
vertical-scrollbar: EnemyListScrollBar
VerticalScrollBar
id: EnemyListScrollBar
anchors.top: EnemyList.top
anchors.bottom: EnemyList.bottom
anchors.right: EnemyList.right
step: 14
pixels-scroll: true
TextEdit
id: EnemyName
anchors.left: EnemyList.left
anchors.right: EnemyList.right
anchors.top: EnemyList.bottom
margin-left: 3
margin-top: 5
Button
id: AddEnemy
!text: tr('Add Enemy')
anchors.left: EnemyList.left
anchors.right: EnemyList.right
anchors.top: prev.bottom
margin-left: 3
margin-top: 3
Label
anchors.right: BlackList.right
anchors.top: parent.top
anchors.left: BlackList.left
text-align: center
text: Anty RS List
margin-left: 3
TextList
id: BlackList
anchors.top: parent.top
anchors.left: EnemyList.right
margin-top: 15
margin-bottom: 5
margin-left: 3
padding: 1
width: 180
height: 160
vertical-scrollbar: BlackListScrollBar
VerticalScrollBar
id: BlackListScrollBar
anchors.top: BlackList.top
anchors.bottom: BlackList.bottom
anchors.right: BlackList.right
step: 14
pixels-scroll: true
TextEdit
id: BlackName
anchors.left: BlackList.left
anchors.right: BlackList.right
anchors.top: BlackList.bottom
margin-left: 3
margin-top: 5
Button
id: AddBlack
!text: tr('Add Anty-RS')
anchors.left: BlackList.left
anchors.right: BlackList.right
anchors.top: prev.bottom
margin-left: 3
margin-top: 3
BotSwitch
id: Members
anchors.left: parent.left
anchors.top: AddEnemy.bottom
margin-top: 15
width: 135
text-align: center
text: Group Members
BotSwitch
id: Outfit
anchors.bottom: prev.bottom
anchors.left: prev.right
margin-left: 3
width: 135
text-align: center
text: Color Outfits
BotSwitch
id: Marks
anchors.bottom: prev.bottom
anchors.left: prev.right
width: 135
margin-left: 3
text-align: center
text: Not Ally = Enemy
BotSwitch
id: Highlight
anchors.bottom: prev.bottom
anchors.left: prev.right
width: 135
margin-left: 3
text-align: center
text: Highlight
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

@@ -0,0 +1,261 @@
setDefaultTab("Main")
local panelName = "playerList"
local ui = setupUI([[
Panel
height: 18
Button
id: editList
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
background: #292A2A
height: 18
text: Player Lists
]], parent)
ui:setId(panelName)
if not storage[panelName] then
storage[panelName] = {
enemyList = {},
friendList = {},
blackList = {},
groupMembers = true,
outfits = false,
marks = false,
highlight = false
}
end
local config = storage[panelName]
-- for backward compability
if not config.blackList then
config.blackList = {}
end
-- functions
local function clearCachedPlayers()
CachedFriends = {}
CachedEnemies = {}
end
local refreshStatus = function()
for _, spec in ipairs(getSpectators()) do
if spec:isPlayer() and not spec:isLocalPlayer() then
if config.outfits then
local specOutfit = spec:getOutfit()
if isFriend(spec:getName()) then
if config.highlight then
spec:setMarked('#0000FF')
end
specOutfit.head = 88
specOutfit.body = 88
specOutfit.legs = 88
specOutfit.feet = 88
if storage.BOTserver.outfit then
local voc = BotServerMembers[spec:getName()]
specOutfit.addons = 3
if voc == 1 then
specOutfit.type = 131
elseif voc == 2 then
specOutfit.type = 129
elseif voc == 3 then
specOutfit.type = 130
elseif voc == 4 then
specOutfit.type = 144
end
end
spec:setOutfit(specOutfit)
elseif isEnemy(spec:getName()) then
if config.highlight then
spec:setMarked('#FF0000')
end
specOutfit.head = 94
specOutfit.body = 94
specOutfit.legs = 94
specOutfit.feet = 94
spec:setOutfit(specOutfit)
end
end
end
end
end
refreshStatus()
local checkStatus = function(creature)
if not creature:isPlayer() or creature:isLocalPlayer() then return end
local specName = creature:getName()
local specOutfit = creature:getOutfit()
if isFriend(specName) then
if config.highlight then
creature:setMarked('#0000FF')
end
specOutfit.head = 88
specOutfit.body = 88
specOutfit.legs = 88
specOutfit.feet = 88
if storage.BOTserver.outfit then
local voc = BotServerMembers[creature:getName()]
specOutfit.addons = 3
if voc == 1 then
specOutfit.type = 131
elseif voc == 2 then
specOutfit.type = 129
elseif voc == 3 then
specOutfit.type = 130
elseif voc == 4 then
specOutfit.type = 144
end
end
creature:setOutfit(specOutfit)
elseif isEnemy(specName) then
if config.highlight then
creature:setMarked('#FF0000')
end
specOutfit.head = 94
specOutfit.body = 94
specOutfit.legs = 94
specOutfit.feet = 94
creature:setOutfit(specOutfit)
end
end
-- eof
-- UI
rootWidget = g_ui.getRootWidget()
playerListWindow = UI.createWindow('PlayerListsWindow', rootWidget)
playerListWindow:hide()
playerListWindow.Members:setOn(config.groupMembers)
playerListWindow.Members.onClick = function(widget)
config.groupMembers = not config.groupMembers
if not config then
clearCachedPlayers()
end
refreshStatus()
widget:setOn(config.groupMembers)
end
playerListWindow.Outfit:setOn(config.outfits)
playerListWindow.Outfit.onClick = function(widget)
config.outfits = not config.outfits
widget:setOn(config.outfits)
end
playerListWindow.Marks:setOn(config.marks)
playerListWindow.Marks.onClick = function(widget)
config.marks = not config.marks
widget:setOn(config.marks)
end
playerListWindow.Highlight:setOn(config.highlight)
playerListWindow.Highlight.onClick = function(widget)
config.highlight = not config.highlight
widget:setOn(config.highlight)
end
if config.enemyList and #config.enemyList > 0 then
for _, name in ipairs(config.enemyList) do
local label = g_ui.createWidget("PlayerName", playerListWindow.EnemyList)
label.remove.onClick = function(widget)
table.removevalue(config.enemyList, label:getText())
label:destroy()
end
label:setText(name)
end
end
if config.blackList and #config.blackList > 0 then
for _, name in ipairs(config.blackList) do
local label = g_ui.createWidget("PlayerName", playerListWindow.BlackList)
label.remove.onClick = function(widget)
table.removevalue(config.blackList, label:getText())
label:destroy()
end
label:setText(name)
end
end
if config.friendList and #config.friendList > 0 then
for _, name in ipairs(config.friendList) do
local label = g_ui.createWidget("PlayerName", playerListWindow.FriendList)
label.remove.onClick = function(widget)
table.removevalue(config.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(config.friendList, friendName, true) then
table.insert(config.friendList, friendName)
local label = g_ui.createWidget("PlayerName", playerListWindow.FriendList)
label.remove.onClick = function(widget)
table.removevalue(config.friendList, label:getText())
label:destroy()
end
label:setText(friendName)
playerListWindow.FriendName:setText('')
clearCachedPlayers()
refreshStatus()
end
end
playerListWindow.AddEnemy.onClick = function(widget)
local enemyName = playerListWindow.EnemyName:getText()
if enemyName:len() > 0 and not table.contains(config.enemyList, enemyName, true) then
table.insert(config.enemyList, enemyName)
local label = g_ui.createWidget("PlayerName", playerListWindow.EnemyList)
label.remove.onClick = function(widget)
table.removevalue(config.enemyList, label:getText())
label:destroy()
end
label:setText(enemyName)
playerListWindow.EnemyName:setText('')
clearCachedPlayers()
refreshStatus()
end
end
playerListWindow.AddBlack.onClick = function(widget)
local blackName = playerListWindow.BlackName:getText()
if blackName:len() > 0 and not table.contains(config.blackList, blackName, true) then
table.insert(config.blackList, blackName)
local label = g_ui.createWidget("PlayerName", playerListWindow.BlackList)
label.remove.onClick = function(widget)
table.removevalue(config.blackList, label:getText())
label:destroy()
end
label:setText(blackName)
playerListWindow.BlackName:setText('')
clearCachedPlayers()
refreshStatus()
end
end
ui.editList.onClick = function(widget)
playerListWindow:show()
playerListWindow:raise()
playerListWindow:focus()
end
playerListWindow.closeButton.onClick = function(widget)
playerListWindow:hide()
end
-- execution
onCreatureAppear(function(creature)
checkStatus(creature)
end)
onPlayerPositionChange(function(x,y)
if x.z ~= y.z then
schedule(20, function()
refreshStatus()
end)
end
end)

View File

@@ -0,0 +1,217 @@
setDefaultTab("Main")
local panelName = "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(panelName)
if not storage[panelName] then
storage[panelName] = {
enabled = true,
pushDelay = 1060,
pushMaxRuneId = 3188,
mwallBlockId = 2128,
pushMaxKey = "PageUp"
}
end
ui.title:setOn(storage[panelName].enabled)
ui.title.onClick = function(widget)
storage[panelName].enabled = not storage[panelName].enabled
widget:setOn(storage[panelName].enabled)
end
ui.push.onClick = function(widget)
pushWindow:show()
pushWindow:raise()
pushWindow:focus()
end
rootWidget = g_ui.getRootWidget()
if rootWidget then
pushWindow = UI.createWindow('PushMaxWindow', rootWidget)
pushWindow:hide()
pushWindow.closeButton.onClick = function(widget)
pushWindow:hide()
end
local updateDelayText = function()
pushWindow.delayText:setText("Push Delay: ".. storage[panelName].pushDelay)
end
updateDelayText()
pushWindow.delay.onValueChange = function(scroll, value)
storage[panelName].pushDelay = value
updateDelayText()
end
pushWindow.delay:setValue(storage[panelName].pushDelay)
pushWindow.runeId.onItemChange = function(widget)
storage[panelName].pushMaxRuneId = widget:getItemId()
end
pushWindow.runeId:setItemId(storage[panelName].pushMaxRuneId)
pushWindow.mwallId.onItemChange = function(widget)
storage[panelName].mwallBlockId = widget:getItemId()
end
pushWindow.mwallId:setItemId(storage[panelName].mwallBlockId)
pushWindow.hotkey.onTextChange = function(widget, text)
storage[panelName].pushMaxKey = text
end
pushWindow.hotkey:setText(storage[panelName].pushMaxKey)
end
-- variables for config
local config = storage[panelName]
local pushDelay = tonumber(config.pushDelay)
local rune = tonumber(config.pushMaxRuneId)
local customMwall = config.mwallBlockId
local key = config.pushMaxKey
local enabled = config.enabled
local fieldTable = {2118, 105, 2122}
-- 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
tile:setText('')
end
end
pushTarget = nil
targetTile = nil
targetId = nil
end
local getCreatureById = function(id)
for i, spec in ipairs(getSpectators()) do
if spec:getId() == id then
return spec
end
end
return false
end
local isNotOk = function(t,tile)
local tileItems = {}
for i, item in pairs(tile:getItems()) do
table.insert(tileItems, item:getId())
end
for i, field in ipairs(t) do
if table.find(tileItems, field) then
return true
end
end
return false
end
local isOk = function(a,b)
return getDistanceBetween(a,b) == 1
end
-- to mark
onKeyDown(function(keys)
if not enabled then return end
if keys ~= key then return end
local tile = getTileUnderCursor()
if not tile then return end
if pushTarget and targetTile then
resetData()
return
end
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')
end
elseif not targetTile and pushTarget then
if pushTarget and getDistanceBetween(tile:getPosition(),pushTarget:getPosition()) ~= 1 then
resetData()
return
else
tile:setText('DEST')
targetTile = tile
end
end
end)
onCreaturePositionChange(function(creature, newPos, oldPos)
if not enabled then return end
if creature == player then
resetData()
end
if not pushTarget or not targetTile then return end
if creature == pushTarget and newPos == targetTile then
resetData()
end
end)
macro(20, 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
storage.isUsing = true
schedule(pushDelay+700, function()
storage.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
return
end
end
g_game.move(pushTarget,tilePos)
delay(2000)
end)

View File

@@ -0,0 +1,85 @@
PushMaxWindow < MainWindow
!text: tr('Pushmax Settings')
size: 200 240
@onEscape: self:hide()
BotLabel
id: delayText
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
text-align: center
HorizontalScrollBar
id: delay
anchors.left: delayText.left
anchors.right: delayText.right
anchors.top: delayText.bottom
margin-top: 5
minimum: 800
maximum: 2000
step: 10
Label
id: label2
anchors.top: delay.bottom
anchors.left: parent.horizontalCenter
anchors.right: parent.right
text-align: center
text: Custom WallID
margin-top: 5
Label
id: label3
anchors.top: delay.bottom
anchors.right: parent.horizontalCenter
anchors.left: parent.left
text-align: center
text: VS AntiPush
margin-top: 5
BotItem
id: runeId
anchors.horizontalCenter: label3.horizontalCenter
anchors.top: label3.bottom
margin-top: 5
BotItem
id: mwallId
anchors.horizontalCenter: label2.horizontalCenter
anchors.top: label2.bottom
margin-top: 5
Label
id: label1
anchors.top: mwallId.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 10
text-align: center
text: Hotkey for PUSHMAX
TextEdit
id: hotkey
anchors.left: parent.left
anchors.right: parent.right
anchors.top: label1.bottom
margin-top: 5
text-align: center
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

@@ -0,0 +1,115 @@
setDefaultTab("Tools")
function quiverManager()
quiverPanelName = "quiverManager"
local ui = setupUI([[
Panel
height: 33
margin-top: 2
BotItem
id: BoltsID
anchors.left: parent.left
anchors.top: parent.top
BotItem
id: ArrowsID
anchors.left: prev.right
anchors.verticalCenter: prev.verticalCenter
BotSwitch
id: BoltsSwitch
anchors.top: parent.top
anchors.bottom: prev.verticalCenter
anchors.right: parent.right
text: Sort Bolts
BotSwitch
id: ArrowsSwitch
anchors.top: prev.bottom
anchors.bottom: ArrowsID.bottom
anchors.right: parent.right
text: Sort Arrows
]])
ui:setId(quiverPanelName)
if not storage[quiverPanelName] then
storage[quiverPanelName] = {
arrowsId = 35848,
boltsId = 35849,
bolts = false,
arrows = false
}
end
ui.BoltsSwitch:setOn(storage[quiverPanelName].bolts)
ui.BoltsSwitch.onClick = function(widget)
storage[quiverPanelName].bolts = not storage[quiverPanelName].bolts
widget:setOn(storage[quiverPanelName].bolts)
end
ui.ArrowsSwitch:setOn(storage[quiverPanelName].arrows)
ui.ArrowsSwitch.onClick = function(widget)
storage[quiverPanelName].arrows = not storage[quiverPanelName].arrows
widget:setOn(storage[quiverPanelName].arrows)
end
ui.BoltsID:setItemId(storage[quiverPanelName].boltsId)
ui.BoltsID.onItemChange = function(widget)
storage[quiverPanelName].boltsId = widget:getItemId()
end
ui.ArrowsID:setItemId(storage[quiverPanelName].arrowsId)
ui.ArrowsID.onItemChange = function(widget)
storage[quiverPanelName].arrowsId = widget:getItemId()
end
local arrows = {16143, 763, 761, 7365, 3448, 762, 21470, 7364, 14251, 3447, 3449, 15793, 25757, 774}
local bolts = {6528, 7363, 3450, 16141, 25758, 14252, 3446, 16142}
macro(200, function()
local dArrow
local dBolt
for _, c in pairs(getContainers()) do
if not containerIsFull(c) then
if c:getContainerItem():getId() == storage[quiverPanelName].arrowsId and storage[quiverPanelName].arrows then
dArrow = c
elseif c:getContainerItem():getId() == storage[quiverPanelName].boltsId and storage[quiverPanelName].bolts then
dBolt = c
end
end
end
if dArrow and storage[quiverPanelName].arrows then
for _, c in pairs(getContainers()) do
if c:getName():lower():find("backpack") or c:getName():lower():find("bag") or c:getName():lower():find("chess") then
for _, i in pairs(c:getItems()) do
if table.find(arrows, i:getId()) then
return g_game.move(i, dArrow:getSlotPosition(dArrow:getItemsCount()), i:getCount())
end
end
end
end
end
if dBolt and storage[quiverPanelName].bolts then
for _, c in pairs(getContainers()) do
if c:getName():lower():find("backpack") or c:getName():lower():find("bag") or c:getName():lower():find("chess") then
for _, i in pairs(c:getItems()) do
if table.find(bolts, i:getId()) then
return g_game.move(i, dBolt:getSlotPosition(dBolt:getItemsCount()), i:getCount())
end
end
end
end
end
end)
end
if voc() == 2 or voc() == 12 then
addSeparator()
UI.Label("[[ Quiver Manager ]]")
addSeparator()
quiverManager()
end

View File

@@ -0,0 +1,192 @@
VocationPanel < Panel
padding: 3
image-source: /images/ui/panel_flat
image-border: 6
size: 190 55
Label
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
text-align: center
text: for BotServer, Heal only:
BotSwitch
id: ED
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.horizontalCenter
text: Druids
BotSwitch
id: MS
anchors.bottom: parent.bottom
anchors.left: parent.horizontalCenter
anchors.right: parent.right
text: Sorcerers
BotSwitch
id: EK
anchors.bottom: ED.top
anchors.left: parent.left
anchors.right: parent.horizontalCenter
text: Knights
BotSwitch
id: RP
anchors.bottom: ED.top
anchors.left: parent.horizontalCenter
anchors.right: parent.right
text: Paladins
SioListWindow < MainWindow
!text: tr('Healer Options')
size: 220 360
@onEscape: self:hide()
BotSwitch
id: exuraSio
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.horizontalCenter
text: Exura Sio
margin-right: 2
BotSwitch
id: exuraGranSio
anchors.top: parent.top
anchors.left: prev.right
anchors.right: parent.right
text: Exura Gran Sio
margin-left: 2
BotSwitch
id: exuraMasRes
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
text: Exura Gran Mas Res
margin-top: 3
BotSwitch
id: spell
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
text: Custom Spell
margin-top: 3
text-align: center
BotTextEdit
id: spellName
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 3
HorizontalSeparator
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 10
BotItem
id: itemId
anchors.top: prev.bottom
anchors.left: parent.left
margin-top: 10
BotSwitch
id: item
anchors.top: prev.top
anchors.left: prev.right
anchors.right: parent.right
anchors.bottom: prev.verticalCenter
text-align: center
text: Item Healing
margin-left: 2
BotLabel
id: distText
anchors.top: itemId.verticalCenter
anchors.left: itemId.right
anchors.right: parent.right
anchors.bottom: itemId.bottom
text-align: center
text: Max Distance
HorizontalScrollBar
id: Distance
anchors.left: parent.left
anchors.top: itemId.bottom
anchors.right: parent.right
margin-top: 3
minimum: 1
maximum: 10
step: 1
HorizontalSeparator
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 8
BotLabel
id: manaInfo
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
text-align: center
margin-top: 5
HorizontalScrollBar
id: minMana
anchors.left: spellName.left
anchors.right: spellName.right
anchors.top: manaInfo.bottom
margin-top: 2
minimum: 1
maximum: 100
step: 1
BotLabel
id: friendHp
anchors.left: spellName.left
anchors.right: spellName.right
anchors.top: prev.bottom
text-align: center
margin-top: 5
HorizontalScrollBar
id: minFriendHp
anchors.left: spellName.left
anchors.right: spellName.right
anchors.top: friendHp.bottom
margin-top: 2
minimum: 1
maximum: 100
step: 1
VocationPanel
id: vocation
anchors.top: prev.bottom
margin-top: 6
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

@@ -0,0 +1,24 @@
-- config
local keyUp = "="
local keyDown = "-"
setDefaultTab("Tools")
-- script
local lockedLevel = pos().z
onPlayerPositionChange(function(newPos, oldPos)
lockedLevel = pos().z
modules.game_interface.getMapPanel():unlockVisibleFloor()
end)
onKeyPress(function(keys)
if keys == keyDown then
lockedLevel = lockedLevel + 1
modules.game_interface.getMapPanel():lockVisibleFloor(lockedLevel)
elseif keys == keyUp then
lockedLevel = lockedLevel - 1
modules.game_interface.getMapPanel():lockVisibleFloor(lockedLevel)
end
end)

View File

@@ -0,0 +1,402 @@
function SuppliesPanel(parent)
suppliesPanelName = "supplies"
if not parent then
parent = panel
end
if not SuppliesConfig[suppliesPanelName] then
SuppliesConfig[suppliesPanelName] = {
item1 = 0,
item2 = 0,
item3 = 0,
item4 = 0,
item5 = 0,
item6 = 0,
item7 = 0,
capValue = 0,
capSwitch = false,
SoftBoots = false,
staminaSwitch = false,
staminaValue = 900,
imbues = false,
item1Min = 0,
item1Max = 0,
item2Min = 0,
item2Max = 0,
item3Min = 0,
item3Max = 0,
item4Min = 0,
item4Max = 0,
item5Min = 0,
item5Max = 0,
item6Min = 0,
item6Max = 0,
item7Max = 0,
sortSupplies = false,
potionBp = 0,
runeBp = 0,
ammoBp = 0
}
end
-- data validation
local setup = SuppliesConfig[suppliesPanelName]
setup.item1 = setup.item1 or 0
setup.item2 = setup.item2 or 0
setup.item3 = setup.item3 or 0
setup.item4 = setup.item4 or 0
setup.item5 = setup.item5 or 0
setup.item6 = setup.item6 or 0
setup.item1Min = setup.item1Min or 0
setup.item1Max = setup.item1Max or 0
setup.item2Min = setup.item2Min or 0
setup.item2Max = setup.item2Max or 0
setup.item3Min = setup.item3Min or 0
setup.item3Max = setup.item3Max or 0
setup.item4Min = setup.item4Min or 0
setup.item4Max = setup.item4Max or 0
setup.item5Min = setup.item5Min or 0
setup.item5Max = setup.item5Max or 0
setup.item6Min = setup.item6Min or 0
setup.item6Max = setup.item6Max or 0
setup.capValue = setup.capValue or 0
setup.staminaValue = setup.staminaValue or 0
setup.potionBp = setup.potionBp or 0
setup.runeBp = setup.runeBp or 0
setup.ammoBp = setup.ammoBp or 0
rootWidget = g_ui.getRootWidget()
if rootWidget then
SuppliesWindow = g_ui.createWidget('SuppliesWindow', rootWidget)
SuppliesWindow:hide()
SuppliesWindow.capSwitch:setOn(SuppliesConfig[suppliesPanelName].capSwitch)
SuppliesWindow.capSwitch.onClick = function(widget)
SuppliesConfig[suppliesPanelName].capSwitch = not SuppliesConfig[suppliesPanelName].capSwitch
widget:setOn(SuppliesConfig[suppliesPanelName].capSwitch)
end
SuppliesWindow.SoftBoots:setOn(SuppliesConfig[suppliesPanelName].SoftBoots)
SuppliesWindow.SoftBoots.onClick = function(widget)
SuppliesConfig[suppliesPanelName].SoftBoots = not SuppliesConfig[suppliesPanelName].SoftBoots
widget:setOn(SuppliesConfig[suppliesPanelName].SoftBoots)
end
SuppliesWindow.imbues:setOn(SuppliesConfig[suppliesPanelName].imbues)
SuppliesWindow.imbues.onClick = function(widget)
SuppliesConfig[suppliesPanelName].imbues = not SuppliesConfig[suppliesPanelName].imbues
widget:setOn(SuppliesConfig[suppliesPanelName].imbues)
end
SuppliesWindow.staminaSwitch:setOn(SuppliesConfig[suppliesPanelName].staminaSwitch)
SuppliesWindow.staminaSwitch.onClick = function(widget)
SuppliesConfig[suppliesPanelName].staminaSwitch = not SuppliesConfig[suppliesPanelName].staminaSwitch
widget:setOn(SuppliesConfig[suppliesPanelName].staminaSwitch)
end
SuppliesWindow.SortSupplies:setOn(SuppliesConfig[suppliesPanelName].sortSupplies)
SuppliesWindow.SortSupplies.onClick = function(widget)
SuppliesConfig[suppliesPanelName].sortSupplies = not SuppliesConfig[suppliesPanelName].sortSupplies
widget:setOn(SuppliesConfig[suppliesPanelName].sortSupplies)
end
-- bot items
SuppliesWindow.item1:setItemId(SuppliesConfig[suppliesPanelName].item1)
SuppliesWindow.item1.onItemChange = function(widget)
SuppliesConfig[suppliesPanelName].item1 = widget:getItemId()
end
SuppliesWindow.item2:setItemId(SuppliesConfig[suppliesPanelName].item2)
SuppliesWindow.item2.onItemChange = function(widget)
SuppliesConfig[suppliesPanelName].item2 = widget:getItemId()
end
SuppliesWindow.item3:setItemId(SuppliesConfig[suppliesPanelName].item3)
SuppliesWindow.item3.onItemChange = function(widget)
SuppliesConfig[suppliesPanelName].item3 = widget:getItemId()
end
SuppliesWindow.item4:setItemId(SuppliesConfig[suppliesPanelName].item4)
SuppliesWindow.item4.onItemChange = function(widget)
SuppliesConfig[suppliesPanelName].item4 = widget:getItemId()
end
SuppliesWindow.item5:setItemId(SuppliesConfig[suppliesPanelName].item5)
SuppliesWindow.item5.onItemChange = function(widget)
SuppliesConfig[suppliesPanelName].item5 = widget:getItemId()
end
SuppliesWindow.item6:setItemId(SuppliesConfig[suppliesPanelName].item6)
SuppliesWindow.item6.onItemChange = function(widget)
SuppliesConfig[suppliesPanelName].item6 = widget:getItemId()
end
SuppliesWindow.PotionBp:setItemId(SuppliesConfig[suppliesPanelName].potionBp)
SuppliesWindow.PotionBp.onItemChange = function(widget)
SuppliesConfig[suppliesPanelName].potionBp = widget:getItemId()
end
SuppliesWindow.RuneBp:setItemId(SuppliesConfig[suppliesPanelName].runeBp)
SuppliesWindow.RuneBp.onItemChange = function(widget)
SuppliesConfig[suppliesPanelName].runeBp = widget:getItemId()
end
SuppliesWindow.AmmoBp:setItemId(SuppliesConfig[suppliesPanelName].ammoBp)
SuppliesWindow.AmmoBp.onItemChange = function(widget)
SuppliesConfig[suppliesPanelName].ammoBp = widget:getItemId()
end
-- text windows
SuppliesWindow.capValue:setText(SuppliesConfig[suppliesPanelName].capValue)
SuppliesWindow.capValue.onTextChange = function(widget, text)
local value = tonumber(SuppliesWindow.capValue:getText())
if not value then
SuppliesWindow.capValue:setText(0)
SuppliesConfig[suppliesPanelName].capValue = 0
else
text = text:match("0*(%d+)")
SuppliesConfig[suppliesPanelName].capValue = text
end
end
SuppliesWindow.item1Min:setText(SuppliesConfig[suppliesPanelName].item1Min)
SuppliesWindow.item1Min.onTextChange = function(widget, text)
local value = tonumber(SuppliesWindow.item1Min:getText())
if not value then
SuppliesWindow.item1Min:setText(0)
SuppliesConfig[suppliesPanelName].item1Min = 0
else
text = text:match("0*(%d+)")
SuppliesConfig[suppliesPanelName].item1Min = text
end
end
SuppliesWindow.item1Max:setText(SuppliesConfig[suppliesPanelName].item1Max)
SuppliesWindow.item1Max.onTextChange = function(widget, text)
local value = tonumber(SuppliesWindow.item1Max:getText())
if not value then
SuppliesWindow.item1Max:setText(0)
SuppliesConfig[suppliesPanelName].item1Max = 0
else
text = text:match("0*(%d+)")
SuppliesConfig[suppliesPanelName].item1Max = text
end
end
SuppliesWindow.item2Min:setText(SuppliesConfig[suppliesPanelName].item2Min)
SuppliesWindow.item2Min.onTextChange = function(widget, text)
local value = tonumber(SuppliesWindow.item2Min:getText())
if not value then
SuppliesWindow.item2Min:setText(0)
SuppliesConfig[suppliesPanelName].item2Min = 0
else
text = text:match("0*(%d+)")
SuppliesConfig[suppliesPanelName].item2Min = text
end
end
SuppliesWindow.item2Max:setText(SuppliesConfig[suppliesPanelName].item2Max)
SuppliesWindow.item2Max.onTextChange = function(widget, text)
local value = tonumber(SuppliesWindow.item2Max:getText())
if not value then
SuppliesWindow.item2Max:setText(0)
SuppliesConfig[suppliesPanelName].item2Max = 0
else
text = text:match("0*(%d+)")
SuppliesConfig[suppliesPanelName].item2Max = text
end
end
SuppliesWindow.item3Min:setText(SuppliesConfig[suppliesPanelName].item3Min)
SuppliesWindow.item3Min.onTextChange = function(widget, text)
local value = tonumber(SuppliesWindow.item3Min:getText())
if not value then
SuppliesWindow.item3Min:setText(0)
SuppliesConfig[suppliesPanelName].item3Min = 0
else
text = text:match("0*(%d+)")
SuppliesConfig[suppliesPanelName].item3Min = text
end
end
SuppliesWindow.item3Max:setText(SuppliesConfig[suppliesPanelName].item3Max)
SuppliesWindow.item3Max.onTextChange = function(widget, text)
local value = tonumber(SuppliesWindow.item3Max:getText())
if not value then
SuppliesWindow.item3Max:setText(0)
SuppliesConfig[suppliesPanelName].item3Max = 0
else
SuppliesConfig[suppliesPanelName].item3Max = text
end
end
SuppliesWindow.item4Min:setText(SuppliesConfig[suppliesPanelName].item4Min)
SuppliesWindow.item4Min.onTextChange = function(widget, text)
local value = tonumber(SuppliesWindow.item4Min:getText())
if not value then
SuppliesWindow.item4Min:setText(0)
SuppliesConfig[suppliesPanelName].item4Min = 0
else
text = text:match("0*(%d+)")
SuppliesConfig[suppliesPanelName].item4Min = text
end
end
SuppliesWindow.staminaValue:setText(SuppliesConfig[suppliesPanelName].staminaValue)
SuppliesWindow.staminaValue.onTextChange = function(widget, text)
local value = tonumber(SuppliesWindow.staminaValue:getText())
if not value then
SuppliesWindow.staminaValue:setText(0)
SuppliesConfig[suppliesPanelName].staminaValue = 0
else
text = text:match("0*(%d+)")
SuppliesConfig[suppliesPanelName].staminaValue = text
end
end
SuppliesWindow.item4Max:setText(SuppliesConfig[suppliesPanelName].item4Max)
SuppliesWindow.item4Max.onTextChange = function(widget, text)
local value = tonumber(SuppliesWindow.item4Max:getText())
if not value then
SuppliesWindow.item4Max:setText(0)
SuppliesConfig[suppliesPanelName].item4Max = 0
else
text = text:match("0*(%d+)")
SuppliesConfig[suppliesPanelName].item4Max = text
end
end
SuppliesWindow.item5Min:setText(SuppliesConfig[suppliesPanelName].item5Min)
SuppliesWindow.item5Min.onTextChange = function(widget, text)
local value = tonumber(SuppliesWindow.item5Min:getText())
if not value then
SuppliesWindow.item5Min:setText(0)
SuppliesConfig[suppliesPanelName].item5Min = 0
else
text = text:match("0*(%d+)")
SuppliesConfig[suppliesPanelName].item5Min = text
end
end
SuppliesWindow.item5Max:setText(SuppliesConfig[suppliesPanelName].item5Max)
SuppliesWindow.item5Max.onTextChange = function(widget, text)
local value = tonumber(SuppliesWindow.item5Max:getText())
if not value then
SuppliesWindow.item5Max:setText(0)
SuppliesConfig[suppliesPanelName].item5Max = 0
else
text = text:match("0*(%d+)")
SuppliesConfig[suppliesPanelName].item5Max = text
end
end
SuppliesWindow.item6Min:setText(SuppliesConfig[suppliesPanelName].item6Min)
SuppliesWindow.item6Min.onTextChange = function(widget, text)
local value = tonumber(SuppliesWindow.item6Min:getText())
if not value then
SuppliesWindow.item6Min:setText(0)
SuppliesConfig[suppliesPanelName].item6Min = 0
else
text = text:match("0*(%d+)")
SuppliesConfig[suppliesPanelName].item6Min = text
end
end
SuppliesWindow.item6Max:setText(SuppliesConfig[suppliesPanelName].item6Max)
SuppliesWindow.item6Max.onTextChange = function(widget, text)
local value = tonumber(SuppliesWindow.item6Max:getText())
if not value then
SuppliesWindow.item6Max:setText(0)
SuppliesConfig[suppliesPanelName].item6Max = 0
else
text = text:match("0*(%d+)")
SuppliesConfig[suppliesPanelName].item6Max = text
end
end
end
UI.Button("Supplies", function()
SuppliesWindow:show()
SuppliesWindow:raise()
SuppliesWindow:focus()
end)
SuppliesWindow.close.onClick = function(widget)
SuppliesWindow:hide()
vBotConfigSave("supply")
end
end
local potions = {23375, 268, 237, 238, 23373, 266, 236, 239, 7643, 7642, 23374}
local runes = {3725, 3203, 3161, 3147, 3178, 3177, 3153, 3148, 3197, 3149, 3164, 3166, 3200, 3192, 3188, 3190, 3189, 3191, 3198, 3182, 3158, 3152, 3174, 3180, 3165, 3173, 3172, 3176, 3195, 3179, 3175, 3155, 3202, 3160, 3156}
local ammo = {3446, 16142, 6528, 7363, 3450, 16141, 25785, 14252, 3447, 3449, 15793, 25757, 774, 16143, 763, 761, 7365, 3448, 762, 21470, 7364, 14251, 7368, 25759, 3287, 7366, 3298, 25758}
macro(250, function()
if not SuppliesConfig[suppliesPanelName].sortSupplies then return end
local sortPotions = SuppliesConfig[suppliesPanelName].potionBp > 100
local sortRunes = SuppliesConfig[suppliesPanelName].runeBp > 100
local sortAmmo = SuppliesConfig[suppliesPanelName].ammoBp > 100
local potionsContainer = nil
local runesContainer = nil
local ammoContainer = nil
-- set the containers
if not potionsContainer or not runesContainer or not ammoContainer then
for i, container in pairs(getContainers()) do
if not containerIsFull(container) then
if sortPotions and container:getContainerItem():getId() == SuppliesConfig[suppliesPanelName].potionBp then
potionsContainer = container
elseif sortRunes and container:getContainerItem():getId() == SuppliesConfig[suppliesPanelName].runeBp then
runesContainer = container
elseif sortAmmo and container:getContainerItem():getId() == SuppliesConfig[suppliesPanelName].ammoBp then
ammoContainer = container
end
end
end
end
-- potions
if potionsContainer then
for i, container in pairs(getContainers()) do
if (container:getContainerItem():getId() ~= SuppliesConfig[suppliesPanelName].potionBp and (string.find(container:getName(), "backpack") or string.find(container:getName(), "bag") or string.find(container:getName(), "chess"))) then
for j, item in pairs(container:getItems()) do
if table.find(potions, item:getId()) then
return g_game.move(item, potionsContainer:getSlotPosition(potionsContainer:getItemsCount()), item:getCount())
end
end
end
end
end
-- runes
if runesContainer then
for i, container in pairs(getContainers()) do
if (container:getContainerItem():getId() ~= SuppliesConfig[suppliesPanelName].runeBp and (string.find(container:getName(), "backpack") or string.find(container:getName(), "bag") or string.find(container:getName(), "chess"))) then
for j, item in pairs(container:getItems()) do
if table.find(runes, item:getId()) then
return g_game.move(item, runesContainer:getSlotPosition(runesContainer:getItemsCount()), item:getCount())
end
end
end
end
end
-- ammo
if ammoContainer then
for i, container in pairs(getContainers()) do
if (container:getContainerItem():getId() ~= SuppliesConfig[suppliesPanelName].ammoBp and (string.find(container:getName(), "backpack") or string.find(container:getName(), "bag") or string.find(container:getName(), "chess"))) and not string.find(container:getName():lower(), "loot") then
for j, item in pairs(container:getItems()) do
if table.find(ammo, item:getId()) then
return g_game.move(item, ammoContainer:getSlotPosition(ammoContainer:getItemsCount()), item:getCount())
end
end
end
end
end
end)
UI.Separator()
SuppliesPanel(setDefaultTab("Cave"))

View File

@@ -0,0 +1,365 @@
SuppliesWindow < MainWindow
!text: tr('Supplies')
size: 430 310
VerticalSeparator
id: sep
anchors.top: parent.top
anchors.left: item1Max.right
anchors.bottom: parent.bottom
margin-top: 3
margin-bottom: 3
margin-left: 10
Label
anchors.left: sep.right
anchors.right: parent.right
anchors.top: parent.top
margin-left: 10
margin-top: 3
text-align: center
text: Additional Conditions:
HorizontalSeparator
anchors.top: prev.bottom
anchors.left: prev.left
anchors.right: prev.right
margin-top: 3
BotSwitch
id: SoftBoots
anchors.top: prev.bottom
anchors.left: sep.right
anchors.right: parent.right
margin-top: 10
margin-left: 10
text: No Soft
BotSwitch
id: capSwitch
height: 20
anchors.left: SoftBoots.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 5
margin-right: 50
text-align: center
text: Cap Below:
BotTextEdit
id: capValue
size: 40 20
anchors.left: prev.right
anchors.right: parent.right
anchors.top: prev.top
margin-left: 5
BotSwitch
id: staminaSwitch
height: 20
anchors.left: SoftBoots.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 5
margin-right: 50
text-align: center
text: Stamina:
BotTextEdit
id: staminaValue
size: 40 20
anchors.left: prev.right
anchors.right: parent.right
anchors.top: prev.top
margin-left: 5
BotSwitch
id: imbues
anchors.top: prev.bottom
anchors.left: sep.right
anchors.right: parent.right
margin-top: 5
margin-left: 10
text: No Imbues
HorizontalSeparator
anchors.top: prev.bottom
anchors.left: prev.left
anchors.right: prev.right
margin-top: 5
BotSwitch
id: SortSupplies
anchors.top: prev.bottom
anchors.left: prev.left
anchors.right: prev.right
margin-top: 5
text: Sort Supplies
BotItem
id: PotionBp
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 3
Label
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 5
text: Potions
BotItem
id: RuneBp
anchors.top: PotionBp.bottom
anchors.left: PotionBp.left
margin-top: 3
Label
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 5
text: Runes
BotItem
id: AmmoBp
anchors.top: RuneBp.bottom
anchors.left: RuneBp.left
margin-top: 3
Label
anchors.verticalCenter: prev.verticalCenter
anchors.left: prev.right
margin-left: 5
text: Ammo
BotItem
id: item1
anchors.left: parent.left
anchors.top: parent.top
margin-top: 3
Label
id: MinLabel
!text: tr('Min Amount')
anchors.left: prev.right
anchors.top: prev.top
margin-left: 18
Label
id: MaxLabel
!text: tr('Max Amount')
anchors.left: prev.right
anchors.top: prev.top
margin-left: 35
BotTextEdit
id: item1Min
size: 100 20
anchors.left: parent.left
anchors.top: prev.top
margin-top: 15
margin-left: 40
text-align: center
BotTextEdit
id: item1Max
size: 100 20
anchors.left: prev.right
anchors.top: prev.top
margin-left: 5
text-align: center
BotItem
id: item2
anchors.left: parent.left
anchors.top: prev.top
margin-top: 30
Label
id: MinLabel
!text: tr('Min Amount')
anchors.left: prev.right
anchors.top: prev.top
margin-left: 18
Label
id: MaxLabel
!text: tr('Max Amount')
anchors.left: prev.right
anchors.top: prev.top
margin-left: 35
BotTextEdit
id: item2Min
size: 100 20
anchors.left: parent.left
anchors.top: prev.top
margin-top: 15
margin-left: 40
text-align: center
BotTextEdit
id: item2Max
size: 100 20
anchors.left: prev.right
anchors.top: prev.top
margin-left: 5
text-align: center
BotItem
id: item3
anchors.left: parent.left
anchors.top: prev.top
margin-top: 30
Label
id: MinLabel
!text: tr('Min Amount')
anchors.left: prev.right
anchors.top: prev.top
margin-left: 18
Label
id: MaxLabel
!text: tr('Max Amount')
anchors.left: prev.right
anchors.top: prev.top
margin-left: 35
BotTextEdit
id: item3Min
size: 100 20
anchors.left: parent.left
anchors.top: prev.top
margin-top: 15
margin-left: 40
text-align: center
BotTextEdit
id: item3Max
size: 100 20
anchors.left: prev.right
anchors.top: prev.top
margin-left: 5
text-align: center
BotItem
id: item4
anchors.left: parent.left
anchors.top: prev.top
margin-top: 30
Label
id: MinLabel
!text: tr('Min Amount')
anchors.left: prev.right
anchors.top: prev.top
margin-left: 18
Label
id: MaxLabel
!text: tr('Max Amount')
anchors.left: prev.right
anchors.top: prev.top
margin-left: 35
BotTextEdit
id: item4Min
size: 100 20
anchors.left: parent.left
anchors.top: prev.top
margin-top: 15
margin-left: 40
text-align: center
BotTextEdit
id: item4Max
size: 100 20
anchors.left: prev.right
anchors.top: prev.top
margin-left: 5
text-align: center
BotItem
id: item5
anchors.left: parent.left
anchors.top: prev.top
margin-top: 30
Label
id: MinLabel
!text: tr('Min Amount')
anchors.left: prev.right
anchors.top: prev.top
margin-left: 18
Label
id: MaxLabel
!text: tr('Max Amount')
anchors.left: prev.right
anchors.top: prev.top
margin-left: 35
BotTextEdit
id: item5Min
size: 100 20
anchors.left: parent.left
anchors.top: prev.top
margin-top: 15
margin-left: 40
text-align: center
BotTextEdit
id: item5Max
size: 100 20
anchors.left: prev.right
anchors.top: prev.top
margin-left: 5
text-align: center
BotItem
id: item6
anchors.left: parent.left
anchors.top: prev.top
margin-top: 30
Label
id: MinLabel
!text: tr('Min Amount')
anchors.left: prev.right
anchors.top: prev.top
margin-left: 18
Label
id: MaxLabel
!text: tr('Max Amount')
anchors.left: prev.right
anchors.top: prev.top
margin-left: 35
BotTextEdit
id: item6Min
size: 100 20
anchors.left: parent.left
anchors.top: prev.top
margin-top: 15
margin-left: 40
text-align: center
BotTextEdit
id: item6Max
size: 100 20
anchors.left: prev.right
anchors.top: prev.top
margin-left: 5
text-align: center
Button
id: close
!text: tr('Close')
font: cipsoftFont
anchors.right: parent.right
anchors.bottom: parent.bottom
size: 45 21
margin-top: 15
margin-right: 5

View File

@@ -0,0 +1,37 @@
-- tools tab
setDefaultTab("Tools")
local moneyIds = {3031, 3035} -- gold coin, platinium coin
macro(1000, "Exchange money", function()
local containers = g_game.getContainers()
for index, container in pairs(containers) do
if not container.lootContainer then -- ignore monster containers
for i, item in ipairs(container:getItems()) do
if item:getCount() == 100 then
for m, moneyId in ipairs(moneyIds) do
if item:getId() == moneyId then
return g_game.use(item)
end
end
end
end
end
end
end)
UI.Separator()
macro(60000, "Send message on trade", function()
local trade = getChannelId("advertising")
if not trade then
trade = getChannelId("trade")
end
if trade and storage.autoTradeMessage:len() > 0 then
sayChannel(trade, storage.autoTradeMessage)
end
end)
UI.TextEdit(storage.autoTradeMessage or "I'm using OTClientV8!", function(widget, text)
storage.autoTradeMessage = text
end)
UI.Separator()

File diff suppressed because it is too large Load Diff