Updated to OTCv8 3.1 rev 131

This commit is contained in:
OTCv8 2022-02-15 21:11:37 +00:00
parent 5a3e429d32
commit 80177bd151
136 changed files with 2685 additions and 5381 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 964 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 526 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

View File

@ -12,9 +12,6 @@ ProgressBar < UIProgressBar
margin-bottom: 0 margin-bottom: 0
height: 0 height: 0
ThickProgressBar < ProgressBar
image-source: /images/ui/progressbar_thick
LifeProgressBar < UIProgressBar LifeProgressBar < UIProgressBar
height: 16 height: 16
background-color: green background-color: green

View File

@ -20,4 +20,4 @@ Module
- client_terminal - client_terminal
- client_stats - client_stats
- client_feedback - client_feedback
- client_mobile - client_mobile

View File

@ -1,127 +0,0 @@
OptionPanel
Label
text: Client user features profile
ComboBox
id: profile
margin-top: 3
@onOptionChange: modules.client_options.setOption(self:getId(), self.currentIndex)
@onSetup: |
self:addOption("1")
self:addOption("2")
self:addOption("3")
self:addOption("4")
self:addOption("5")
self:addOption("6")
self:addOption("7")
self:addOption("8")
self:addOption("9")
self:addOption("10")
Label
OptionCheckBox
id: topBar
!text: tr('Show customizable top status bar')
OptionCheckBox
id: topHealtManaBar
!text: tr('Show player top health and mana bar')
OptionCheckBox
id: showHealthManaCircle
!text: tr('Show health and mana circle')
$mobile:
visible: false
Label
margin-top: 5
text: Show Bottom Action Bars:
Panel
margin-top: 2
height: 16
layout:
type: horizontalBox
OptionCheckBox
id: actionbarBottom1
!text: tr('Bar 1')
width: 60
OptionCheckBox
id: actionbarBottom2
!text: tr('Bar 2')
width: 60
OptionCheckBox
id: actionbarBottom3
!text: tr('Bar 3')
width: 60
Label
text: Show Left Action Bars:
$mobile:
visible: false
Panel
margin-top: 2
height: 16
$mobile:
visible: false
layout:
type: horizontalBox
OptionCheckBox
id: actionbarLeft1
!text: tr('Bar 1')
width: 60
OptionCheckBox
id: actionbarLeft2
!text: tr('Bar 2')
width: 60
OptionCheckBox
id: actionbarLeft3
!text: tr('Bar 3')
width: 60
Label
text: Show Right Action Bars:
$mobile:
visible: false
Panel
margin-top: 2
height: 16
layout:
type: horizontalBox
$mobile:
visible: false
OptionCheckBox
id: actionbarRight1
!text: tr('Bar 1')
width: 60
OptionCheckBox
id: actionbarRight2
!text: tr('Bar 2')
width: 60
OptionCheckBox
id: actionbarRight3
!text: tr('Bar 3')
width: 60
Label
OptionCheckBox
id: actionbarLock
!text: tr('Disable action bar hotkeys when chat mode is on')
$mobile:
visible: false

View File

@ -36,6 +36,14 @@ OptionPanel
$mobile: $mobile:
visible: false visible: false
OptionCheckBox
id: actionBar1
!text: tr("Show first action bar")
OptionCheckBox
id: actionBar2
!text: tr("Show second action bar")
OptionCheckBox OptionCheckBox
id: showPing id: showPing
@ -66,6 +74,16 @@ OptionPanel
$mobile: $mobile:
visible: false visible: false
OptionCheckBox
id: topHealtManaBar
!text: tr('Show player top health and mana bar')
OptionCheckBox
id: showHealthManaCircle
!text: tr('Show health and mana circle')
$mobile:
visible: false
OptionCheckBox OptionCheckBox
id: highlightThingsUnderCursor id: highlightThingsUnderCursor
!text: tr('Highlight things under cursor') !text: tr('Highlight things under cursor')

View File

@ -49,24 +49,9 @@ local defaultOptions = {
walkStairsDelay = 50, walkStairsDelay = 50,
walkTeleportDelay = 200, walkTeleportDelay = 200,
walkCtrlTurnDelay = 150, walkCtrlTurnDelay = 150,
topBar = true, actionBar1 = true,
actionBar2 = false
actionbarBottom1 = true,
actionbarBottom2 = false,
actionbarBottom3 = false,
actionbarLeft1 = false,
actionbarLeft2 = false,
actionbarLeft3 = false,
actionbarRight1 = false,
actionbarRight2 = false,
actionbarRight3 = false,
actionbarLock = true,
profile = 1
} }
local optionsWindow local optionsWindow
@ -78,8 +63,7 @@ local generalPanel
local interfacePanel local interfacePanel
local consolePanel local consolePanel
local graphicsPanel local graphicsPanel
local audioPanel local soundPanel
local customPanel
local extrasPanel local extrasPanel
local audioButton local audioButton
@ -117,7 +101,6 @@ function init()
audioPanel = g_ui.loadUI('audio') audioPanel = g_ui.loadUI('audio')
optionsTabBar:addTab(tr('Audio'), audioPanel, '/images/optionstab/audio') optionsTabBar:addTab(tr('Audio'), audioPanel, '/images/optionstab/audio')
extrasPanel = g_ui.createWidget('OptionPanel') extrasPanel = g_ui.createWidget('OptionPanel')
for _, v in ipairs(g_extras.getAll()) do for _, v in ipairs(g_extras.getAll()) do
local extrasButton = g_ui.createWidget('OptionCheckBox') local extrasButton = g_ui.createWidget('OptionCheckBox')
@ -129,9 +112,6 @@ function init()
optionsTabBar:addTab(tr('Extras'), extrasPanel, '/images/optionstab/extras') optionsTabBar:addTab(tr('Extras'), extrasPanel, '/images/optionstab/extras')
end end
customPanel = g_ui.loadUI('custom')
optionsTabBar:addTab(tr('Custom'), customPanel, '/images/optionstab/features')
optionsButton = modules.client_topmenu.addLeftButton('optionsButton', tr('Options'), '/images/topbuttons/options', toggle) optionsButton = modules.client_topmenu.addLeftButton('optionsButton', tr('Options'), '/images/topbuttons/options', toggle)
audioButton = modules.client_topmenu.addLeftButton('audioButton', tr('Audio'), '/images/topbuttons/audio', function() toggleOption('enableAudio') end) audioButton = modules.client_topmenu.addLeftButton('audioButton', tr('Audio'), '/images/topbuttons/audio', function() toggleOption('enableAudio') end)
if g_app.isMobile() then if g_app.isMobile() then
@ -376,20 +356,12 @@ function setOption(key, value, force)
g_settings.set(key, value) g_settings.set(key, value)
options[key] = value options[key] = value
if key == "profile" then
modules.client_profiles.onProfileChange()
end
if key == 'classicView' or key == 'rightPanels' or key == 'leftPanels' or key == 'cacheMap' then if key == 'classicView' or key == 'rightPanels' or key == 'leftPanels' or key == 'cacheMap' then
modules.game_interface.refreshViewMode() modules.game_interface.refreshViewMode()
elseif key:find("actionbar") then elseif key == 'actionBar1' or key == 'actionBar2' then
modules.game_actionbar.show() modules.game_actionbar.show()
end end
if key == 'topBar' then
modules.game_topbar.show()
end
end end
function getOption(key) function getOption(key)

View File

@ -1,160 +0,0 @@
local settings = {}
ChangedProfile = false
function init()
connect(g_game, {
onGameStart = online,
onGameEnd = offline
})
end
function terminate()
disconnect(g_game, {
onGameStart = online,
onGameEnd = offline
})
end
-- loads settings on character login
function online()
ChangedProfile = false
-- startup arguments has higher priority than settings
local index = getProfileFromStartupArgument()
if index then
setProfileOption(index)
end
load()
if not index then
setProfileOption(getProfileFromSettings() or 1)
end
-- create main settings dir
if not g_resources.directoryExists("/settings/") then
g_resources.makeDir("/settings/")
end
-- create profiles dirs
for i=1,10 do
local path = "/settings/profile_"..i
if not g_resources.directoryExists(path) then
g_resources.makeDir(path)
end
end
end
function setProfileOption(index)
local currentProfile = g_settings.getNumber('profile')
currentProfile = tostring(currentProfile)
index = tostring(index)
if currentProfile ~= index then
ChangedProfile = true
return modules.client_options.setOption('profile', index)
end
end
-- load profile number from settings
function getProfileFromSettings()
-- settings should save per character, return if not online
if not g_game.isOnline() then return end
local index = g_game.getCharacterName()
local savedData = settings[index]
return savedData
end
-- option to launch client with hardcoded profile
function getProfileFromStartupArgument()
local startupOptions = string.split(g_app.getStartupOptions(), " ")
if #startupOptions < 2 then
return false
end
for index, option in ipairs(startupOptions) do
if option == "--profile" then
local profileIndex = startupOptions[index + 1]
if profileIndex == nil then
return g_logger.info("Startup arguments incomplete: missing profile index.")
end
g_logger.info("Startup options: Forced profile: "..profileIndex)
-- set value in options
return profileIndex
end
end
return false
end
-- returns string path ie. "/settings/1/actionbar.json"
function getSettingsFilePath(fileNameWithFormat)
local currentProfile = g_settings.getNumber('profile')
return "/settings/profile_"..currentProfile.."/"..fileNameWithFormat
end
function offline()
onProfileChange(true)
end
-- profile change callback (called in options), saves settings & reloads given module configs
function onProfileChange(offline)
if not offline then
if not g_game.isOnline() then return end
-- had to apply some delay
scheduleEvent(collectiveReload, 100)
end
local currentProfile = g_settings.getNumber('profile')
local index = g_game.getCharacterName()
if index then
settings[index] = currentProfile
save()
end
end
-- collection of refresh functions from different modules
function collectiveReload()
modules.game_topbar.refresh(true)
modules.game_actionbar.refresh(true)
modules.game_bot.refresh()
end
-- json handlers
function load()
local file = "/settings/profiles.json"
if g_resources.fileExists(file) then
local status, result = pcall(function()
return json.decode(g_resources.readFileContents(file))
end)
if not status then
return onError(
"Error while reading profiles file. To fix this problem you can delete storage.json. Details: " ..
result)
end
settings = result
end
end
function save()
local file = "/settings/profiles.json"
local status, result = pcall(function() return json.encode(settings, 2) end)
if not status then
return onError(
"Error while saving profile settings. Data won't be saved. Details: " ..
result)
end
if result:len() > 100 * 1024 * 1024 then
return onError(
"Something went wrong, file is above 100MB, won't be saved")
end
g_resources.writeFileContents(file, result)
end

View File

@ -1,11 +0,0 @@
Module
name: client_profiles
description: Provides option to save client customizations into separate profiles
author: Vithrax
discord: Vithrax#5814
autoload: true
reloadable: false
scripts: [ profiles ]
sandboxed: true
@onLoad: init()
@onUnload: terminate()

View File

@ -181,4 +181,4 @@ end
function UIComboBox:canMouseScroll() function UIComboBox:canMouseScroll()
return self.mouseScroll return self.mouseScroll
end end

View File

@ -1,12 +1,7 @@
---@diagnostic disable: undefined-global actionPanel1 = nil
bottomActionPanel1 = nil actionPanel2 = nil
bottomActionPanel2 = nil
bottomActionPanel3 = nil
leftActionPanel1 = nil
leftActionPanel2 = nil
leftActionPanel3 = nil
local settings = {} local actionConfig
local hotkeyAssignWindow local hotkeyAssignWindow
local actionButtonsInPanel = 50 local actionButtonsInPanel = 50
@ -29,33 +24,13 @@ ActionColors = {
} }
function init() function init()
local bottomPanel = modules.game_interface.getBottomActionPanel() local bottomPanel = modules.game_interface.getActionPanel()
local leftPanel = modules.game_interface.getLeftActionPanel() actionPanel1 = g_ui.loadUI('actionbar', bottomPanel)
local rightPanel = modules.game_interface.getRightActionPanel() bottomPanel:moveChildToIndex(actionPanel1, 1)
actionPanel2 = g_ui.loadUI('actionbar', bottomPanel)
bottomPanel:moveChildToIndex(actionPanel2, 1)
-- bottom actionConfig = g_configs.create("/actionbar.otml")
bottomActionPanel1 = g_ui.loadUI('actionbar', bottomPanel)
bottomPanel:moveChildToIndex(bottomActionPanel1, 1)
bottomActionPanel2 = g_ui.loadUI('actionbar', bottomPanel)
bottomPanel:moveChildToIndex(bottomActionPanel2, 1)
bottomActionPanel3 = g_ui.loadUI('actionbar', bottomPanel)
bottomPanel:moveChildToIndex(bottomActionPanel3, 1)
-- left
leftActionPanel1 = g_ui.loadUI('sideactionbar', leftPanel)
leftPanel:moveChildToIndex(leftActionPanel1, 1)
leftActionPanel2 = g_ui.loadUI('sideactionbar', leftPanel)
leftPanel:moveChildToIndex(leftActionPanel2, 1)
leftActionPanel3 = g_ui.loadUI('sideactionbar', leftPanel)
leftPanel:moveChildToIndex(leftActionPanel3, 1)
-- right
rightActionPanel1 = g_ui.loadUI('sideactionbar', rightPanel)
rightPanel:moveChildToIndex(rightActionPanel1, 1)
rightActionPanel2 = g_ui.loadUI('sideactionbar', rightPanel)
rightPanel:moveChildToIndex(rightActionPanel2, 1)
rightActionPanel3 = g_ui.loadUI('sideactionbar', rightPanel)
rightPanel:moveChildToIndex(rightActionPanel3, 1)
connect(g_game, { connect(g_game, {
onGameStart = online, onGameStart = online,
@ -78,105 +53,42 @@ function terminate()
}) })
-- remove hotkeys, also saves config -- remove hotkeys, also saves config
local panels = { if actionPanel1.tabBar:getChildCount() > 0 and actionPanel2.tabBar:getChildCount() > 0 then
bottomActionPanel1, offline()
bottomActionPanel2,
bottomActionPanel3,
leftActionPanel1,
leftActionPanel2,
leftActionPanel3,
rightActionPanel1,
rightActionPanel2,
rightActionPanel3,
}
for i, panel in ipairs(panels) do
if panel.tabBar:getChildCount() > 0 then
offline()
break
end
end end
bottomActionPanel1:destroy() actionPanel1:destroy()
bottomActionPanel2:destroy() actionPanel2:destroy()
bottomActionPanel3:destroy()
leftActionPanel1:destroy()
leftActionPanel2:destroy()
leftActionPanel3:destroy()
rightActionPanel1:destroy()
rightActionPanel2:destroy()
rightActionPanel3:destroy()
end end
function show() function show()
if not g_game.isOnline() then return end if not g_game.isOnline() then return end
bottomActionPanel1:setOn(g_settings.getBoolean("actionbarBottom1", false)) actionPanel1:setOn(g_settings.getBoolean("actionBar1", false))
bottomActionPanel2:setOn(g_settings.getBoolean("actionbarBottom2", false)) actionPanel2:setOn(g_settings.getBoolean("actionBar2", false))
bottomActionPanel3:setOn(g_settings.getBoolean("actionbarBottom3", false))
leftActionPanel1:setOn(g_settings.getBoolean("actionbarLeft1", false))
leftActionPanel2:setOn(g_settings.getBoolean("actionbarLeft2", false))
leftActionPanel3:setOn(g_settings.getBoolean("actionbarLeft3", false))
rightActionPanel1:setOn(g_settings.getBoolean("actionbarRight1", false))
rightActionPanel2:setOn(g_settings.getBoolean("actionbarRight2", false))
rightActionPanel3:setOn(g_settings.getBoolean("actionbarRight3", false))
end end
function hide() function hide()
bottomActionPanel1:setOn(false) actionPanel1:setOn(false)
bottomActionPanel2:setOn(false) actionPanel2:setOn(false)
bottomActionPanel3:setOn(false)
leftActionPanel1:setOn(false)
leftActionPanel2:setOn(false)
leftActionPanel3:setOn(false)
rightActionPanel1:setOn(false)
rightActionPanel2:setOn(false)
rightActionPanel3:setOn(false)
end end
function switchMode(newMode) function switchMode(newMode)
if newMode then if newMode then
bottomActionPanel1:setImageColor('#ffffff88') actionPanel1:setImageColor('#ffffff88')
bottomActionPanel2:setImageColor('#ffffff88') actionPanel2:setImageColor('#ffffff88')
bottomActionPanel3:setImageColor('#ffffff88')
leftActionPanel1:setImageColor('#ffffff88')
leftActionPanel2:setImageColor('#ffffff88')
leftActionPanel3:setImageColor('#ffffff88')
rightActionPanel1:setImageColor('#ffffff88')
rightActionPanel2:setImageColor('#ffffff88')
rightActionPanel3:setImageColor('#ffffff88')
else else
bottomActionPanel1:setImageColor('white') actionPanel1:setImageColor('white')
bottomActionPanel2:setImageColor('white') actionPanel2:setImageColor('white')
bottomActionPanel3:setImageColor('white')
leftActionPanel1:setImageColor('white')
leftActionPanel2:setImageColor('white')
leftActionPanel3:setImageColor('white')
rightActionPanel1:setImageColor('white')
rightActionPanel2:setImageColor('white')
rightActionPanel3:setImageColor('white')
end end
end end
function online() function online()
load() setupActionPanel(1, actionPanel1)
setupActionPanel(1, bottomActionPanel1, true) setupActionPanel(2, actionPanel2)
setupActionPanel(2, bottomActionPanel2, true)
setupActionPanel(3, bottomActionPanel3, true)
setupActionPanel(4, leftActionPanel1, false)
setupActionPanel(5, leftActionPanel2, false)
setupActionPanel(6, leftActionPanel3, false)
setupActionPanel(7, rightActionPanel1, false)
setupActionPanel(8, rightActionPanel2, false)
setupActionPanel(9, rightActionPanel3, false)
show() show()
end end
function refresh(reloaded) function offline()
offline(reloaded)
online()
end
function offline(reloaded)
hide() hide()
if hotkeyAssignWindow then if hotkeyAssignWindow then
hotkeyAssignWindow:destroy() hotkeyAssignWindow:destroy()
@ -184,35 +96,37 @@ function offline(reloaded)
end end
local gameRootPanel = modules.game_interface.getRootPanel() local gameRootPanel = modules.game_interface.getRootPanel()
for index, panel in ipairs({bottomActionPanel1, bottomActionPanel2, bottomActionPanel3, for index, panel in ipairs({actionPanel1, actionPanel2}) do
leftActionPanel1, leftActionPanel2, leftActionPanel3, local config = {}
rightActionPanel1, rightActionPanel2, rightActionPanel3}) do
settings[tostring(index)] = {}
for i, child in ipairs(panel.tabBar:getChildren()) do for i, child in ipairs(panel.tabBar:getChildren()) do
if child.config and child.config.item then if child.config then
settings[tostring(index)][tostring(i)] = child.config table.insert(config, child.config)
if type(child.config.hotkey) == 'string' and child.config.hotkey:len() > 0 then if type(child.config.hotkey) == 'string' and child.config.hotkey:len() > 0 then
g_keyboard.unbindKeyPress(child.config.hotkey, child.callback, gameRootPanel) g_keyboard.unbindKeyPress(child.config.hotkey, child.callback, gameRootPanel)
end end
else
table.insert(config, {})
end end
if child.cooldownEvent then if child.cooldownEvent then
removeEvent(child.cooldownEvent) removeEvent(child.cooldownEvent)
end end
end end
actionConfig:setNode('actions_' .. index, config)
panel.tabBar:destroyChildren() panel.tabBar:destroyChildren()
end end
if not reloaded then actionConfig:save()
save()
end
end end
function setupActionPanel(index, panel, bottom) function setupActionPanel(index, panel)
local config = settings[tostring(index)] or {} local rawConfig = actionConfig:getNode('actions_' .. index) or {}
local config = {}
for i, buttonConfig in pairs(rawConfig) do -- sorting, because key in rawConfig is string
config[tonumber(i)] = buttonConfig
end
for i=1,actionButtonsInPanel do for i=1,actionButtonsInPanel do
local type = bottom and 'ActionButton' or 'SideActionButton' local action = g_ui.createWidget('ActionButton', panel.tabBar)
local action = g_ui.createWidget(type, panel.tabBar) action.config = config[i] or {}
action.config = config[tostring(i)] or {}
setupAction(action) setupAction(action)
end end
@ -229,18 +143,7 @@ function setupAction(action)
action.item:setShowCount(false) action.item:setShowCount(false)
action.onMouseRelease = actionOnMouseRelease action.onMouseRelease = actionOnMouseRelease
action.onTouchRelease = actionOnMouseRelease action.onTouchRelease = actionOnMouseRelease
action.callback = function(k, c, ticks) executeAction(action, ticks) end
action.callback = function(k, c, ticks)
local lockKeyboard = g_settings.getBoolean('actionbarLock', false)
local chatMode = not modules.game_walking.wsadWalking
if not lockKeyboard or not chatMode then
print('lock', lockKeyboard)
print('chatMode', chatMode)
executeAction(action, ticks)
end
end
action.item.onItemChange = nil -- disable callbacks for setup action.item.onItemChange = nil -- disable callbacks for setup
if config then if config then
@ -424,9 +327,7 @@ function actionOnItemChange(widget)
end end
function onSpellCooldown(iconId, duration) function onSpellCooldown(iconId, duration)
for index, panel in ipairs({bottomActionPanel1, bottomActionPanel2, bottomActionPanel3, for index, panel in ipairs({actionPanel1, actionPanel2}) do
leftActionPanel1, leftActionPanel2, leftActionPanel3,
rightActionPanel1, rightActionPanel2, rightActionPanel3}) do
for i, child in ipairs(panel.tabBar:getChildren()) do for i, child in ipairs(panel.tabBar:getChildren()) do
if child.spell and child.spell.id == iconId then if child.spell and child.spell.id == iconId then
startCooldown(child, duration) startCooldown(child, duration)
@ -436,9 +337,7 @@ function onSpellCooldown(iconId, duration)
end end
function onSpellGroupCooldown(groupId, duration) function onSpellGroupCooldown(groupId, duration)
for index, panel in ipairs({bottomActionPanel1, bottomActionPanel2, bottomActionPanel3, for index, panel in ipairs({actionPanel1, actionPanel2}) do
leftActionPanel1, leftActionPanel2, leftActionPanel3,
rightActionPanel1, rightActionPanel2, rightActionPanel3}) do
for i, child in ipairs(panel.tabBar:getChildren()) do for i, child in ipairs(panel.tabBar:getChildren()) do
if child.spell and child.spell.group then if child.spell and child.spell.group then
for group, dur in pairs(child.spell.group) do for group, dur in pairs(child.spell.group) do
@ -584,40 +483,4 @@ function executeAction(action, ticks)
end end
end end
end end
end end
function save()
local settingsFile = modules.client_profiles.getSettingsFilePath("actionbar.json")
local status, result = pcall(function() return json.encode(settings, 2) end)
if not status then
return onError(
"Error while saving top bar settings. Data won't be saved. Details: " ..
result)
end
if result:len() > 100 * 1024 * 1024 then
return onError(
"Something went wrong, file is above 100MB, won't be saved")
end
g_resources.writeFileContents(settingsFile, result)
end
function load()
local settingsFile = modules.client_profiles.getSettingsFilePath("actionbar.json")
if g_resources.fileExists(settingsFile) then
local status, result = pcall(function()
return json.decode(g_resources.readFileContents(settingsFile))
end)
if not status then
return onError(
"Error while reading top bar settings file. To fix this problem you can delete storage.json. Details: " ..
result)
end
settings = result
else
settings = {}
end
end

View File

@ -5,7 +5,6 @@ ActionButton < Panel
width: 40 width: 40
padding: 1 1 1 1 padding: 1 1 1 1
margin-left: 1 margin-left: 1
draggable: true
$first: $first:
anchors.left: parent.left anchors.left: parent.left
@ -102,6 +101,7 @@ Panel
margin-top: 1 margin-top: 1
margin-bottom: 2 margin-bottom: 2
ActionAssignWindow < MainWindow ActionAssignWindow < MainWindow
id: assignWindow id: assignWindow
!text: tr('Button Assign') !text: tr('Button Assign')

View File

@ -1,149 +0,0 @@
SideActionButton < Panel
font: cipsoftFont
anchors.left: parent.left
anchors.right: parent.right
height: 40
padding: 1 1 1 1
margin-top: 1
draggable: true
$first:
anchors.top: parent.top
margin-top: -3
$!first:
anchors.top: prev.bottom
Item
id: item
anchors.fill: parent
&selectable: true
&editable: false
virtual: true
border-width: 1
border-color: #00000000
$!on:
image-source: /images/game/actionbarslot
Label
id: text
anchors.fill: parent
text-auto-resize: true
text-wrap: true
phantom: true
text-align: center
font: verdana-9px
Label
id: hotkeyLabel
anchors.top: parent.top
anchors.right: parent.right
margin: 2 3 3 3
text-auto-resize: true
text-wrap: false
phantom: true
font: cipsoftFont
color: white
background: #292A2A
UIProgressRect
id: cooldown
background: #585858AA
percent: 100
focusable: false
phantom: true
anchors.fill: parent
margin: 1 1 1 1
font: verdana-11px-rounded
color: white
Panel
id: actionBar
focusable: false
image-source: /images/ui/panel_side
image-border: 4
margin-top: -2
$on:
width: 40
visible: true
$!on:
width: 0
visible: false
TabButton
id: prevButton
icon: /images/game/console/uparrow
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
margin-top: -1
margin-left: 1
margin-right: 1
Panel
id: tabBar
anchors.top: prev.bottom
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: next.top
margin-top: 3
clipping: true
TabButton
id: nextButton
icon: /images/game/console/downarrow
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: parent.bottom
margin-right: 1
margin-left: 1
margin-bottom: 2
ActionAssignWindow < MainWindow
id: assignWindow
!text: tr('Button Assign')
size: 360 150
@onEscape: self:destroy()
Label
!text: tr('Please, press the key you wish to use for action')
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
text-auto-resize: true
text-align: left
Label
id: comboPreview
!text: tr('Current action hotkey: %s', 'none')
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: prev.bottom
margin-top: 10
text-auto-resize: true
HorizontalSeparator
id: separator
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: next.top
margin-bottom: 10
Button
id: addButton
!text: tr('Add')
width: 64
anchors.right: next.left
anchors.bottom: parent.bottom
margin-right: 10
Button
id: cancelButton
!text: tr('Cancel')
width: 64
anchors.right: parent.right
anchors.bottom: parent.bottom
@onClick: self:getParent():destroy()

View File

@ -190,13 +190,7 @@ function refresh()
-- storage -- storage
botStorage = {} botStorage = {}
botStorageFile = "/bot/" .. configName .. "/storage.json"
local path = "/bot/" .. configName .. "/storage/"
if not g_resources.directoryExists(path) then
g_resources.makeDir(path)
end
botStorageFile = path.."profile_" .. g_settings.getNumber('profile') .. ".json"
if g_resources.fileExists(botStorageFile) then if g_resources.fileExists(botStorageFile) then
local status, result = pcall(function() local status, result = pcall(function()
return json.decode(g_resources.readFileContents(botStorageFile)) return json.decode(g_resources.readFileContents(botStorageFile))
@ -261,9 +255,7 @@ end
function online() function online()
botButton:show() botButton:show()
if not modules.client_profiles.ChangedProfile then scheduleEvent(refresh, 20)
scheduleEvent(refresh, 20)
end
end end
function offline() function offline()

View File

@ -31,7 +31,7 @@ local luaFiles = {
"pushmax", "pushmax",
"combo", "combo",
"HealBot", "HealBot",
"new healer", "Sio",
"AttackBot", -- last of major modules "AttackBot", -- last of major modules
"ingame_editor", "ingame_editor",
"Dropper", "Dropper",
@ -48,9 +48,7 @@ local luaFiles = {
"spy_level", "spy_level",
"supplies", "supplies",
"depositer_config", "depositer_config",
"npc_talk", "npc_talk"
"xeno_menu",
"hold_target"
} }
for i, file in ipairs(luaFiles) do for i, file in ipairs(luaFiles) do

View File

@ -3,7 +3,6 @@ CaveBot.Extensions.BuySupplies = {}
CaveBot.Extensions.BuySupplies.setup = function() CaveBot.Extensions.BuySupplies.setup = function()
CaveBot.registerAction("BuySupplies", "#C300FF", function(value, retries) CaveBot.registerAction("BuySupplies", "#C300FF", function(value, retries)
local supplies = SuppliesConfig.supplies local supplies = SuppliesConfig.supplies
supplies = supplies[supplies.currentProfile]
local item1Count = itemAmount(supplies.item1) local item1Count = itemAmount(supplies.item1)
local item2Count = itemAmount(supplies.item2) local item2Count = itemAmount(supplies.item2)
local item3Count = itemAmount(supplies.item3) local item3Count = itemAmount(supplies.item3)

View File

@ -236,60 +236,6 @@ CaveBot.gotoNextWaypointInRange = function()
return false return false
end end
local function reverseTable(t, max)
local reversedTable = {}
local itemCount = max or #t
for i, v in ipairs(t) do
reversedTable[itemCount + 1 - i] = v
end
return reversedTable
end
function rpairs(t)
test()
return function(t, i)
i = i - 1
if i ~= 0 then
return i, t[i]
end
end, t, #t + 1
end
CaveBot.gotoFirstPreviousReachableWaypoint = function()
local currentAction = ui.list:getFocusedChild()
local currentIndex = ui.list:getChildIndex(currentAction)
local index = ui.list:getChildIndex(currentAction)
-- check up to 100 childs
for i=0,100 do
index = index - i
if index <= 0 or index > currentIndex or math.abs(index-currentIndex) > 100 then
break
end
local child = ui.list:getChildByIndex(index)
if child then
local text = child:getText()
if string.starts(text, "goto:") then
local re = regexMatch(text, [[(?:goto:)([^,]+),([^,]+),([^,]+)]])
local pos = {x = tonumber(re[1][2]), y = tonumber(re[1][3]), z = tonumber(re[1][4])}
if posz() == pos.z then
if distanceFromPlayer(pos) <= storage.extras.gotoMaxDistance/2 then
print("found pos, going back "..currentIndex-index.. " waypoints.")
return ui.list:focusChild(child)
end
end
end
end
end
-- not found
print("previous pos not found, proceeding")
return false
end
CaveBot.getFirstWaypointBeforeLabel = function(label) CaveBot.getFirstWaypointBeforeLabel = function(label)
label = "label:"..label label = "label:"..label
label = label:lower() label = label:lower()

View File

@ -42,7 +42,7 @@ CaveBot.Extensions.ClearTile.setup = function()
end end
if retries > 0 then if retries > 0 then
delay(1500) delay(1100)
end end
-- but if not then first check for creatures -- but if not then first check for creatures
@ -55,7 +55,7 @@ CaveBot.Extensions.ClearTile.setup = function()
elseif c:isPlayer() then elseif c:isPlayer() then
local candidates = {} local candidates = {}
for _, tile in ipairs(g_map.getTiles(posz())) do for _, tile in ipairs(g_map.getTiles(posz())) do
if getDistanceBetween(c:getPosition(), tile:getPosition()) == 1 and tile:getPosition() ~= pPos and tile:isWalkable(false) then if getDistanceBetween(c:getPosition(), tile:getPosition()) == 1 and tile:getPosition() ~= pPos then
table.insert(candidates, tile:getPosition()) table.insert(candidates, tile:getPosition())
end end
end end
@ -65,11 +65,7 @@ CaveBot.Extensions.ClearTile.setup = function()
return false return false
else else
print("CaveBot[ClearTile]: pushing player... " .. c:getName() .. " out of the way") print("CaveBot[ClearTile]: pushing player... " .. c:getName() .. " out of the way")
local pos = candidates[math.random(1,#candidates)] g_game.move(c, candidates[math.random(1,#candidates)])
local tile = g_map.getTile(pos)
tile:setText("here")
schedule(500, function() tile:setText("") end)
g_game.move(c, pos)
return "retry" return "retry"
end end
end end

View File

@ -24,7 +24,6 @@ CaveBot.Extensions.DWithdraw.setup = function()
capLimit = tonumber(data[4]:trim()) capLimit = tonumber(data[4]:trim())
end end
-- cap check -- cap check
if freecap() < (capLimit or 200) then if freecap() < (capLimit or 200) then
for i, container in ipairs(getContainers()) do for i, container in ipairs(getContainers()) do

View File

@ -15,17 +15,6 @@ local function resetCache()
g_game.close(container) g_game.close(container)
end end
end end
if storage.caveBot.backStop then
storage.caveBot.backStop = false
CaveBot.setOff()
elseif storage.caveBot.backTrainers then
storage.caveBot.backTrainers = false
CaveBot.gotoLabel('toTrainers')
elseif storage.caveBot.backOffline then
storage.caveBot.backOffline = false
CaveBot.gotoLabel('toOfflineTraining')
end
end end
local description = g_game.getClientVersion() > 960 and "No - just deposit \n Yes - also reopen loot containers" or "currently not supported, will be added in near future" local description = g_game.getClientVersion() > 960 and "No - just deposit \n Yes - also reopen loot containers" or "currently not supported, will be added in near future"
@ -34,7 +23,6 @@ CaveBot.Extensions.Depositor.setup = function()
CaveBot.registerAction("depositor", "#002FFF", function(value, retries) CaveBot.registerAction("depositor", "#002FFF", function(value, retries)
-- version check, TODO old tibia -- version check, TODO old tibia
if g_game.getClientVersion() < 960 then if g_game.getClientVersion() < 960 then
resetCache()
warn("CaveBot[Depositor]: unsupported Tibia version, will be added in near future") warn("CaveBot[Depositor]: unsupported Tibia version, will be added in near future")
return false return false
end end
@ -132,6 +120,5 @@ CaveBot.Extensions.Depositor.setup = function()
value="no", value="no",
title="Depositor", title="Depositor",
description=description, description=description,
validation="(yes|Yes|YES|no|No|NO)"
}) })
end end

View File

@ -53,6 +53,5 @@ CaveBot.Extensions.OpenDoors.setup = function()
title="Door position", title="Door position",
description="doors position (x,y,z) and key id (optional)", description="doors position (x,y,z) and key id (optional)",
multiline=false, multiline=false,
validation=[[\d{1,5},\d{1,5},\d{1,2}(?:,\d{1,5}$|$)]]
}) })
end end

View File

@ -76,10 +76,9 @@ CaveBot.Extensions.Imbuing.setup = function()
if not item then if not item then
-- did try before, still not found so item is unavailable -- did try before, still not found so item is unavailable
if triedToTakeOff then if triedToTakeOff then
warn("CaveBot[Imbuing] item not found! skipping: "..currentId) warn("CaveBot[Imbuing] item not found! proceeding")
triedToTakeOff = false reset()
currentIndex = currentIndex + 1 return false
return "retry"
end end
triedToTakeOff = true triedToTakeOff = true
g_game.equipItemId(currentId) g_game.equipItemId(currentId)
@ -100,7 +99,7 @@ CaveBot.Extensions.Imbuing.setup = function()
useWith(shrine, item) useWith(shrine, item)
currentIndex = currentIndex + 1 currentIndex = currentIndex + 1
warn("CaveBot[Imbuing] Using shrine on item: "..currentId) warn("CaveBot[Imbuing] Using shrine on item: "..currentId)
delay(4000) delay(2000)
return "retry" return "retry"
end) end)

View File

@ -24,6 +24,5 @@ CaveBot.Extensions.Lure.setup = function()
title="Lure", title="Lure",
description="TargetBot: start, stop, toggle", description="TargetBot: start, stop, toggle",
multiline=false, multiline=false,
validation=[[(start|stop|toggle)$]]
}) })
end end

View File

@ -26,20 +26,16 @@ CaveBot.Extensions.PosCheck.setup = function()
return true return true
else else
posCheckRetries = posCheckRetries + 1 posCheckRetries = posCheckRetries + 1
if data[1] == "last" then CaveBot.gotoLabel(data[1])
CaveBot.gotoFirstPreviousReachableWaypoint() print("CaveBot[CheckPos]: position not-reached, going back to label: " .. data[1])
print("CaveBot[CheckPos]: position not-reached, going back to first reachable waypoint.") return false
return false
else
CaveBot.gotoLabel(data[1])
print("CaveBot[CheckPos]: position not-reached, going back to label: " .. data[1])
return false
end
end end
end) end)
CaveBot.Editor.registerAction("poscheck", "pos check", { CaveBot.Editor.registerAction("poscheck", "pos check", {
value=function() return "last" .. "," .. "10" .. "," .. posx() .. "," .. posy() .. "," .. posz() end, value=function() return "label" .. "," .. "10" .. "," .. posx() .. "," .. posy() .. "," .. posz() end,
title="Location Check", title="Location Check",
description="label name, accepted dist from coordinates, x, y, z", description="label name, accepted dist from coordinates, x, y, z",
multiline=false, multiline=false,

View File

@ -60,6 +60,5 @@ CaveBot.Extensions.SellAll.setup = function()
value="NPC", value="NPC",
title="Sell All", title="Sell All",
description="Insert NPC name, and 'yes' if sell with delay ", description="Insert NPC name, and 'yes' if sell with delay ",
validation=[[^[^,]+(?:, yes$|, Yes$|, YES$|$)]]
}) })
end end

View File

@ -35,7 +35,6 @@ CaveBot.Extensions.SupplyCheck.setup = function()
time = now time = now
local supplies = SuppliesConfig.supplies local supplies = SuppliesConfig.supplies
supplies = supplies[supplies.currentProfile]
local softCount = itemAmount(6529) + itemAmount(3549) local softCount = itemAmount(6529) + itemAmount(3549)
local totalItem1 = itemAmount(supplies.item1) local totalItem1 = itemAmount(supplies.item1)
local totalItem2 = itemAmount(supplies.item2) local totalItem2 = itemAmount(supplies.item2)
@ -43,29 +42,8 @@ CaveBot.Extensions.SupplyCheck.setup = function()
local totalItem4 = itemAmount(supplies.item4) local totalItem4 = itemAmount(supplies.item4)
local totalItem5 = itemAmount(supplies.item5) local totalItem5 = itemAmount(supplies.item5)
local totalItem6 = itemAmount(supplies.item6) local totalItem6 = itemAmount(supplies.item6)
if storage.caveBot.forceRefill then if supplyRetries > (storage.extras.huntRoutes or 50) then
print("CaveBot[SupplyCheck]: User forced, going back on refill. Last round took: " .. round)
storage.caveBot.forceRefill = false
supplyRetries = 0
missedChecks = 0
return false
elseif storage.caveBot.backStop then
print("CaveBot[SupplyCheck]: User forced, going back to city and turning off CaveBot. Last round took: " .. round)
supplyRetries = 0
missedChecks = 0
return false
elseif storage.caveBot.backTrainers then
print("CaveBot[SupplyCheck]: User forced, going back to city, then on trainers. Last round took: " .. round)
supplyRetries = 0
missedChecks = 0
return false
elseif storage.caveBot.backOffline then
print("CaveBot[SupplyCheck]: User forced, going back to city, then on offline training. Last round took: " .. round)
supplyRetries = 0
missedChecks = 0
return false
elseif supplyRetries > (storage.extras.huntRoutes or 50) then
print("CaveBot[SupplyCheck]: Round limit reached, going back on refill. Last round took: " .. round) print("CaveBot[SupplyCheck]: Round limit reached, going back on refill. Last round took: " .. round)
supplyRetries = 0 supplyRetries = 0
missedChecks = 0 missedChecks = 0
@ -137,6 +115,5 @@ CaveBot.Extensions.SupplyCheck.setup = function()
value=function() return "startHunt," .. posx() .. "," .. posy() .. "," .. posz() end, value=function() return "startHunt," .. posx() .. "," .. posy() .. "," .. posz() end,
title="Supply check label", title="Supply check label",
description="Insert here hunting start label", description="Insert here hunting start label",
validation=[[[^,]+,\d{1,5},\d{1,5},\d{1,2}$]]
}) })
end end

View File

@ -25,7 +25,7 @@ TargetBot.Creature.addConfig = function(config, focus)
if config.regex:len() > 0 then if config.regex:len() > 0 then
config.regex = config.regex .. "|" config.regex = config.regex .. "|"
end end
config.regex = config.regex .. "^" .. part:trim():lower():gsub("%*", ".*"):gsub("%?", ".?") .. "$" config.regex = config.regex .. "^" .. part:trim():lower():gsub("%*", ".*"):gsub("%?", ".?") .. "$"
end end
end end

View File

@ -145,10 +145,8 @@ TargetBot.Creature.walk = function(creature, config, targets)
delayFrom = config.delayFrom delayFrom = config.delayFrom
-- luring -- luring
if config.closeLure and config.closeLureAmount <= getMonsters(1) then
return TargetBot.allowCaveBot(150)
end
if TargetBot.canLure() and (config.lure or config.lureCavebot or config.dynamicLure) and not (creature:getHealthPercent() < (storage.extras.killUnder or 30)) and not isTrapped then if TargetBot.canLure() and (config.lure or config.lureCavebot or config.dynamicLure) and not (creature:getHealthPercent() < (storage.extras.killUnder or 30)) and not isTrapped then
local monsters = 0
if targetBotLure then if targetBotLure then
anchorPosition = nil anchorPosition = nil
return TargetBot.allowCaveBot(150) return TargetBot.allowCaveBot(150)
@ -167,10 +165,11 @@ TargetBot.Creature.walk = function(creature, config, targets)
end end
end end
local currentDistance = findPath(pos, cpos, 10, {ignoreCreatures=true, ignoreNonPathable=true, ignoreCost=true}) local lastRePosition = now
if (not config.chase or #currentDistance == 1) and not config.avoidAttacks and not config.keepDistance and config.rePosition and (creature:getHealthPercent() >= storage.extras.killUnder) then if not config.chase and not config.keepDistance and config.rePosition and (creature:getHealthPercent() >= storage.extras.killUnder) then
return rePosition(config.rePositionAmount or 6) return rePosition(config.rePositionAmount or 6)
end end
local currentDistance = findPath(pos, cpos, 10, {ignoreCreatures=true, ignoreNonPathable=true, ignoreCost=true})
if ((storage.extras.killUnder > 1 and (creature:getHealthPercent() < storage.extras.killUnder)) or config.chase) and not config.keepDistance then if ((storage.extras.killUnder > 1 and (creature:getHealthPercent() < storage.extras.killUnder)) or config.chase) and not config.keepDistance then
if #currentDistance > 1 then if #currentDistance > 1 then
return TargetBot.walkTo(cpos, 10, {ignoreNonPathable=true, precision=1}) return TargetBot.walkTo(cpos, 10, {ignoreNonPathable=true, precision=1})
@ -238,8 +237,7 @@ onPlayerPositionChange(function(newPos, oldPos)
if TargetBot.isOff() then return end if TargetBot.isOff() then return end
if not lureMax then return end if not lureMax then return end
if storage.TargetBotDelayWhenPlayer then return end if storage.TargetBotDelayWhenPlayer then return end
if not dynamicLureDelay then return end
if targetCount < (delayFrom or lureMax/2) or not target() then return end if dynamicLureDelay and targetCount < (delayFrom or lureMax/2) or not target() then return end
CaveBot.delay(delayValue or 0) CaveBot.delay(delayValue or 0)
end) end)

View File

@ -87,7 +87,6 @@ TargetBot.Creature.edit = function(config, callback) -- callback = function(newC
addScrollBar("lureDelay", "Dynamic lure delay", 100, 1000, 250) addScrollBar("lureDelay", "Dynamic lure delay", 100, 1000, 250)
addScrollBar("delayFrom", "Start delay when monsters", 1, 29, 2) addScrollBar("delayFrom", "Start delay when monsters", 1, 29, 2)
addScrollBar("rePositionAmount", "Min tiles to rePosition", 0, 7, 5) addScrollBar("rePositionAmount", "Min tiles to rePosition", 0, 7, 5)
addScrollBar("closeLureAmount", "Close Pull Until", 0, 8, 3)
addCheckBox("chase", "Chase", true) addCheckBox("chase", "Chase", true)
addCheckBox("keepDistance", "Keep Distance", false) addCheckBox("keepDistance", "Keep Distance", false)
@ -101,5 +100,4 @@ TargetBot.Creature.edit = function(config, callback) -- callback = function(newC
addCheckBox("dynamicLureDelay", "Dynamic lure delay", false) addCheckBox("dynamicLureDelay", "Dynamic lure delay", false)
addCheckBox("diamondArrows", "D-Arrows priority", false) addCheckBox("diamondArrows", "D-Arrows priority", false)
addCheckBox("rePosition", "rePosition to better tile", false) addCheckBox("rePosition", "rePosition to better tile", false)
addCheckBox("closeLure", "Close Pulling Monsters", false)
end end

View File

@ -313,13 +313,6 @@ onCreatureDisappear(function(creature)
if not container or not container:isContainer() then return end if not container or not container:isContainer() then return end
if not findPath(player:getPosition(), mpos, 6, {ignoreNonPathable=true, ignoreCreatures=true, ignoreCost=true}) then return end if not findPath(player:getPosition(), mpos, 6, {ignoreNonPathable=true, ignoreCreatures=true, ignoreCost=true}) then return end
table.insert(TargetBot.Looting.list, {pos=mpos, creature=name, container=container:getId(), added=now, tries=0}) table.insert(TargetBot.Looting.list, {pos=mpos, creature=name, container=container:getId(), added=now, tries=0})
table.sort(TargetBot.Looting.list, function(a,b)
a.dist = distanceFromPlayer(a.pos)
b.dist = distanceFromPlayer(b.pos)
return a.dist > b.dist
end)
container:setMarked('#000088') container:setMarked('#000088')
end) end)
end) end)

View File

@ -181,10 +181,6 @@ TargetBot.setStatus = function(text)
return ui.status.right:setText(text) return ui.status.right:setText(text)
end end
TargetBot.getStatus = function()
return ui.status.right:getText()
end
TargetBot.isOn = function() TargetBot.isOn = function()
return config.isOn() return config.isOn()
end end

View File

@ -7,7 +7,6 @@ local showItem = false
local category = 1 local category = 1
local patternCategory = 1 local patternCategory = 1
local pattern = 1 local pattern = 1
local mainWindow
-- label library -- label library
@ -615,40 +614,32 @@ ui.title.onClick = function(widget)
end end
ui.settings.onClick = function(widget) ui.settings.onClick = function(widget)
mainWindow:show() windowUI:show()
mainWindow:raise() windowUI:raise()
mainWindow:focus() windowUI:focus()
end end
mainWindow = UI.createWindow("AttackBotWindow") rootWidget = g_ui.getRootWidget()
mainWindow:hide() if rootWidget then
windowUI = UI.createWindow("AttackBotWindow", rootWidget)
windowUI:hide()
local panel = mainWindow.mainPanel local panel = windowUI.mainPanel
local settingsUI = mainWindow.settingsPanel local settingsUI = windowUI.settingsPanel
mainWindow.onVisibilityChange = function(widget, visible)
if not visible then
currentSettings.attackTable = {}
for i, child in ipairs(panel.entryList:getChildren()) do
table.insert(currentSettings.attackTable, child.params)
end
vBotConfigSave("atk")
end
end
-- main panel -- main panel
-- functions -- functions
function toggleSettings() function toggleSettings()
panel:setVisible(not showSettings) panel:setVisible(not showSettings)
mainWindow.shooterLabel:setVisible(not showSettings) windowUI.shooterLabel:setVisible(not showSettings)
settingsUI:setVisible(showSettings) settingsUI:setVisible(showSettings)
mainWindow.settingsLabel:setVisible(showSettings) windowUI.settingsLabel:setVisible(showSettings)
mainWindow.settings:setText(showSettings and "Back" or "Settings") windowUI.settings:setText(showSettings and "Back" or "Settings")
end end
toggleSettings() toggleSettings()
mainWindow.settings.onClick = function() windowUI.settings.onClick = function()
showSettings = not showSettings showSettings = not showSettings
toggleSettings() toggleSettings()
end end
@ -726,72 +717,62 @@ end
-- eo in/de/crementation -- eo in/de/crementation
------- [[core table function]] ------- ------- [[core table function]] -------
function setupWidget(widget)
local params = widget.params
widget:setText(params.description)
if params.itemId > 0 then
widget.spell:setVisible(false)
widget.id:setVisible(true)
widget.id:setItemId(params.itemId)
end
widget:setTooltip(params.tooltip)
widget.remove.onClick = function()
panel.up:setEnabled(false)
panel.down:setEnabled(false)
widget:destroy()
end
widget.enabled:setChecked(params.enabled)
widget.enabled.onClick = function()
params.enabled = not params.enabled
widget.enabled:setChecked(params.enabled)
end
-- will serve as edit
widget.onDoubleClick = function(widget)
panel.manaPercent:setValue(params.mana)
panel.creatures:setValue(params.count)
panel.minHp:setValue(params.minHp)
panel.maxHp:setValue(params.maxHp)
panel.cooldown:setValue(params.cooldown)
showItem = params.itemId > 100 and true or false
panel.itemId:setItemId(params.itemId)
panel.spellName:setText(params.spell or "")
panel.orMore:setChecked(params.orMore)
toggleItem()
category = params.category
patternCategory = params.patternCategory
pattern = params.pattern
setPatternText()
setCategoryText()
widget:destroy()
end
widget.onClick = function(widget)
if #panel.entryList:getChildren() == 1 then
panel.up:setEnabled(false)
panel.down:setEnabled(false)
elseif panel.entryList:getChildIndex(widget) == 1 then
panel.up:setEnabled(false)
panel.down:setEnabled(true)
elseif panel.entryList:getChildIndex(widget) == panel.entryList:getChildCount() then
panel.up:setEnabled(true)
panel.down:setEnabled(false)
else
panel.up:setEnabled(true)
panel.down:setEnabled(true)
end
end
end
-- refreshing values -- refreshing values
function refreshAttacks() function refreshAttacks()
if not currentSettings.attackTable then return end if not currentSettings.attackTable then return end
panel.entryList:destroyChildren() for i, child in pairs(panel.entryList:getChildren()) do child:destroy() end
for i, entry in pairs(currentSettings.attackTable) do for i, entry in pairs(currentSettings.attackTable) do
local label = UI.createWidget("AttackEntry", panel.entryList) local label = UI.createWidget("AttackEntry", panel.entryList)
label.params = entry label:setText(entry.description)
setupWidget(label) label:setTooltip(entry.tooltip)
label.remove.onClick = function(widget)
table.remove(currentSettings.attackTable, i)
label:destroy()
panel.up:setEnabled(false)
panel.down:setEnabled(false)
refreshAttacks()
end
label.enabled:setChecked(entry.enabled)
label.enabled.onClick = function(widget)
entry.enabled = not entry.enabled
label.enabled:setChecked(entry.enabled)
end
-- will serve as edit
label.onDoubleClick = function(widget)
table.remove(currentSettings.attackTable, i)
label:destroy()
panel.manaPercent:setValue(entry.mana)
panel.creatures:setValue(entry.count)
panel.minHp:setValue(entry.minHp)
panel.maxHp:setValue(entry.maxHp)
panel.cooldown:setValue(entry.cooldown)
showItem = entry.itemId > 100 and true or false
panel.itemId:setItemId(entry.itemId)
panel.spellName:setText(entry.spell or "")
panel.orMore:setChecked(entry.orMore)
toggleItem()
category = entry.category
patternCategory = entry.patternCategory
pattern = entry.pattern
setPatternText()
setCategoryText()
end
label.onClick = function(widget)
if #panel.entryList:getChildren() == 1 then
panel.up:setEnabled(false)
panel.down:setEnabled(false)
elseif panel.entryList:getChildIndex(panel.entryList:getFocusedChild()) == 1 then
panel.up:setEnabled(false)
panel.down:setEnabled(true)
elseif panel.entryList:getChildIndex(panel.entryList:getFocusedChild()) == #panel.entryList:getChildren() then
panel.up:setEnabled(true)
panel.down:setEnabled(false)
else
panel.up:setEnabled(true)
panel.down:setEnabled(true)
end
end
end end
end end
refreshAttacks() refreshAttacks()
@ -829,7 +810,7 @@ end
local countDescription = orMore and count.."+" or count local countDescription = orMore and count.."+" or count
local params = { local entry = {
creatures = creatures, creatures = creatures,
monsters = monsters, monsters = monsters,
mana = mana, mana = mana,
@ -848,36 +829,32 @@ end
description = '['..type..'] '..countDescription.. ' '..specificMonsters..': '..attackType..', '..categoryName..' ('..minHp..'%-'..maxHp..'%)' description = '['..type..'] '..countDescription.. ' '..specificMonsters..': '..attackType..', '..categoryName..' ('..minHp..'%-'..maxHp..'%)'
} }
local label = UI.createWidget("AttackEntry", panel.entryList) -- inserting to table
label.params = params table.insert(currentSettings.attackTable, entry)
setupWidget(label) refreshAttacks()
resetFields() resetFields()
end end
-- moving values -- moving values
-- up -- up
panel.up.onClick = function(widget) panel.up.onClick = function(widget)
local focused = panel.entryList:getFocusedChild() local n = panel.entryList:getChildIndex(panel.entryList:getFocusedChild())
local n = panel.entryList:getChildIndex(focused) local t = currentSettings.attackTable
if n-1 == 1 then t[n], t[n-1] = t[n-1], t[n]
widget:setEnabled(false) panel.up:setEnabled(false)
end panel.down:setEnabled(false)
panel.down:setEnabled(true) refreshAttacks()
panel.entryList:moveChildToIndex(focused, n-1)
panel.entryList:ensureChildVisible(focused)
end end
-- down -- down
panel.down.onClick = function(widget) panel.down.onClick = function(widget)
local focused = panel.entryList:getFocusedChild() local n = panel.entryList:getChildIndex(panel.entryList:getFocusedChild())
local n = panel.entryList:getChildIndex(focused) local t = currentSettings.attackTable
if n + 1 == panel.entryList:getChildCount() then t[n], t[n+1] = t[n+1], t[n]
widget:setEnabled(false) panel.up:setEnabled(false)
end panel.down:setEnabled(false)
panel.up:setEnabled(true) refreshAttacks()
panel.entryList:moveChildToIndex(focused, n+1)
panel.entryList:ensureChildVisible(focused)
end end
-- [[settings panel]] -- -- [[settings panel]] --
@ -930,11 +907,12 @@ end
-- window elements -- window elements
mainWindow.closeButton.onClick = function() windowUI.closeButton.onClick = function()
showSettings = false showSettings = false
toggleSettings() toggleSettings()
resetFields() resetFields()
mainWindow:hide() windowUI:hide()
vBotConfigSave("atk")
end end
-- core functions -- core functions
@ -1042,13 +1020,7 @@ end
profileChange() profileChange()
end end
end end
end
AttackBot.show = function()
mainWindow:show()
mainWindow:raise()
mainWindow:focus()
end
-- otui covered, now support functions -- otui covered, now support functions
function getPattern(category, pattern, safe) function getPattern(category, pattern, safe)
@ -1190,11 +1162,10 @@ macro(100, function()
} }
]] ]]
for i, child in ipairs(panel.entryList:getChildren()) do for i, entry in pairs(currentSettings.attackTable) do
local entry = child.params
local attackData = entry.itemId > 100 and entry.itemId or entry.spell local attackData = entry.itemId > 100 and entry.itemId or entry.spell
if entry.enabled and manapercent() >= entry.mana then if entry.enabled and manapercent() >= entry.mana then
if (type(attackData) == "string" and canCast(entry.spell, not currentSettings.ignoreMana, not currentSettings.Cooldown)) or (entry.itemId > 100 and (not currentSettings.Visible or findItem(entry.itemId))) then if (entry.spell and canCast(entry.spell, not currentSettings.ignoreMana, not currentSettings.Cooldown)) or (entry.itemId > 100 and (not currentSettings.Visible or findItem(entry.itemId))) then
-- first PVP scenario -- first PVP scenario
if currentSettings.pvpMode and target():getHealthPercent() >= entry.minHp and target():getHealthPercent() <= entry.maxHp and target():canShoot() then if currentSettings.pvpMode and target():getHealthPercent() >= entry.minHp and target():getHealthPercent() <= entry.maxHp and target():canShoot() then
if entry.category == 2 then if entry.category == 2 then
@ -1222,9 +1193,7 @@ macro(100, function()
local safe = currentSettings.PvpSafe and spellPatterns[pCat][entry.pattern][2] or false local safe = currentSettings.PvpSafe and spellPatterns[pCat][entry.pattern][2] or false
local monsterAmount = pCat ~= 8 and getMonstersInArea(entry.category, anchorParam, spellPatterns[pCat][entry.pattern][1], entry.minHp, entry.maxHp, safe, entry.monsters) local monsterAmount = pCat ~= 8 and getMonstersInArea(entry.category, anchorParam, spellPatterns[pCat][entry.pattern][1], entry.minHp, entry.maxHp, safe, entry.monsters)
if (pattern ~= 8 and (entry.orMore and monsterAmount >= entry.count or not entry.orMore and monsterAmount == entry.count)) or (pattern == 8 and bestSide >= entry.count and (not currentSettings.PvpSafe or getPlayers(2) == 0)) then if (pattern ~= 8 and (entry.orMore and monsterAmount >= entry.count or not entry.orMore and monsterAmount == entry.count)) or (pattern == 8 and bestSide >= entry.count and (not currentSettings.PvpSafe or getPlayers(2) == 0)) then
if (not currentSettings.BlackListSafe or not isBlackListedPlayerInRange(currentSettings.AntiRsRange)) and (not currentSettings.Kills or killsToRs() > currentSettings.KillsAmount) then return executeAttackBotAction(entry.category, attackData, entry.cooldown)
return executeAttackBotAction(entry.category, attackData, entry.cooldown)
end
end end
elseif entry.category == 2 then elseif entry.category == 2 then
local pCat = entry.patternCategory local pCat = entry.patternCategory
@ -1237,9 +1206,7 @@ macro(100, function()
pos = data.pos pos = data.pos
end end
if monsterAmount and (entry.orMore and monsterAmount >= entry.count or not entry.orMore and monsterAmount == entry.count) then if monsterAmount and (entry.orMore and monsterAmount >= entry.count or not entry.orMore and monsterAmount == entry.count) then
if (not currentSettings.BlackListSafe or not isBlackListedPlayerInRange(currentSettings.AntiRsRange)) and (not currentSettings.Kills or killsToRs() > currentSettings.KillsAmount) then return useWith(attackData, g_map.getTile(pos):getTopUseThing())
return useWith(attackData, g_map.getTile(pos):getTopUseThing())
end
end end
end end
end end

View File

@ -1,6 +1,6 @@
AttackEntry < UIWidget AttackEntry < UIWidget
background-color: alpha background-color: alpha
text-offset: 35 1 text-offset: 18 1
focusable: true focusable: true
height: 16 height: 16
font: verdana-11px-rounded font: verdana-11px-rounded
@ -15,22 +15,6 @@ AttackEntry < UIWidget
margin-top: 2 margin-top: 2
margin-left: 3 margin-left: 3
UIItem
id: id
anchors.left: prev.right
anchors.verticalCenter: parent.verticalCenter
size: 16 16
focusable: false
visible: false
UIWidget
id: spell
anchors.left: enabled.right
anchors.verticalCenter: parent.verticalCenter
size: 12 12
margin-left: 1
image-source: /images/game/dangerous
$focus: $focus:
background-color: #00000055 background-color: #00000055
@ -553,7 +537,6 @@ AttackBotWindow < MainWindow
size: 535 300 size: 535 300
padding: 15 padding: 15
text: AttackBot v2 text: AttackBot v2
@onEscape: self:hide()
Label Label
id: mainLabel id: mainLabel

View File

@ -4,6 +4,7 @@ local panelName = "BOTserver"
local ui = setupUI([[ local ui = setupUI([[
Panel Panel
height: 18 height: 18
Button Button
id: botServer id: botServer
anchors.left: parent.left anchors.left: parent.left
@ -27,7 +28,6 @@ end
local config = storage[panelName] local config = storage[panelName]
if not storage.BotServerChannel then if not storage.BotServerChannel then
math.randomseed(os.time())
storage.BotServerChannel = tostring(math.random(1000000000000,9999999999999)) storage.BotServerChannel = tostring(math.random(1000000000000,9999999999999))
end end

View File

@ -185,4 +185,4 @@ BotServerWindow < MainWindow
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
size: 45 21 size: 45 21
margin-top: 15 margin-top: 15
margin-right: 5 margin-right: 5

View File

@ -76,13 +76,6 @@ Panel
if rootWidget then if rootWidget then
conditionsWindow = UI.createWindow('ConditionsWindow', rootWidget) conditionsWindow = UI.createWindow('ConditionsWindow', rootWidget)
conditionsWindow:hide() conditionsWindow:hide()
conditionsWindow.onVisibilityChange = function(widget, visible)
if not visible then
vBotConfigSave("heal")
end
end
-- text edits -- text edits
conditionsWindow.Cure.PoisonCost:setText(config.poisonCost) conditionsWindow.Cure.PoisonCost:setText(config.poisonCost)
@ -227,13 +220,7 @@ Panel
-- buttons -- buttons
conditionsWindow.closeButton.onClick = function(widget) conditionsWindow.closeButton.onClick = function(widget)
conditionsWindow:hide() conditionsWindow:hide()
end vBotConfigSave("heal")
Conditions = {}
Conditions.show = function()
conditionsWindow:show()
conditionsWindow:raise()
conditionsWindow:focus()
end end
end end

View File

@ -20,7 +20,6 @@ CureConditions < Panel
margin-left: 5 margin-left: 5
text: Poison text: Poison
color: #ffaa00 color: #ffaa00
font: verdana-11px-rounded
Label Label
id: label11 id: label11
@ -28,7 +27,6 @@ CureConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 40 margin-left: 40
text: Mana: text: Mana:
font: verdana-11px-rounded
TextEdit TextEdit
id: PoisonCost id: PoisonCost
@ -36,7 +34,6 @@ CureConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 3 margin-left: 3
width: 40 width: 40
font: verdana-11px-rounded
CheckBox CheckBox
id: CurePoison id: CurePoison
@ -51,7 +48,6 @@ CureConditions < Panel
margin-top: 10 margin-top: 10
text: Curse text: Curse
color: #ffaa00 color: #ffaa00
font: verdana-11px-rounded
Label Label
id: label22 id: label22
@ -59,7 +55,6 @@ CureConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 44 margin-left: 44
text: Mana: text: Mana:
font: verdana-11px-rounded
TextEdit TextEdit
id: CurseCost id: CurseCost
@ -67,7 +62,6 @@ CureConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 3 margin-left: 3
width: 40 width: 40
font: verdana-11px-rounded
CheckBox CheckBox
id: CureCurse id: CureCurse
@ -82,7 +76,6 @@ CureConditions < Panel
margin-top: 10 margin-top: 10
text: Bleed text: Bleed
color: #ffaa00 color: #ffaa00
font: verdana-11px-rounded
Label Label
id: label33 id: label33
@ -90,7 +83,6 @@ CureConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 46 margin-left: 46
text: Mana: text: Mana:
font: verdana-11px-rounded
TextEdit TextEdit
id: BleedCost id: BleedCost
@ -98,7 +90,6 @@ CureConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 3 margin-left: 3
width: 40 width: 40
font: verdana-11px-rounded
CheckBox CheckBox
id: CureBleed id: CureBleed
@ -113,7 +104,6 @@ CureConditions < Panel
margin-top: 10 margin-top: 10
text: Burn text: Burn
color: #ffaa00 color: #ffaa00
font: verdana-11px-rounded
Label Label
id: label44 id: label44
@ -121,7 +111,6 @@ CureConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 50 margin-left: 50
text: Mana: text: Mana:
font: verdana-11px-rounded
TextEdit TextEdit
id: BurnCost id: BurnCost
@ -129,7 +118,6 @@ CureConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 3 margin-left: 3
width: 40 width: 40
font: verdana-11px-rounded
CheckBox CheckBox
id: CureBurn id: CureBurn
@ -144,7 +132,6 @@ CureConditions < Panel
margin-top: 10 margin-top: 10
text: Electify text: Electify
color: #ffaa00 color: #ffaa00
font: verdana-11px-rounded
Label Label
id: label55 id: label55
@ -152,7 +139,6 @@ CureConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 33 margin-left: 33
text: Mana: text: Mana:
font: verdana-11px-rounded
TextEdit TextEdit
id: ElectrifyCost id: ElectrifyCost
@ -160,7 +146,6 @@ CureConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 3 margin-left: 3
width: 40 width: 40
font: verdana-11px-rounded
CheckBox CheckBox
id: CureElectrify id: CureElectrify
@ -174,8 +159,7 @@ CureConditions < Panel
anchors.top: label5.bottom anchors.top: label5.bottom
margin-top: 10 margin-top: 10
text: Paralyse text: Paralyse
color: #ffaa00 color: #ffaa00
font: verdana-11px-rounded
Label Label
id: label66 id: label66
@ -183,7 +167,6 @@ CureConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 26 margin-left: 26
text: Mana: text: Mana:
font: verdana-11px-rounded
TextEdit TextEdit
id: ParalyseCost id: ParalyseCost
@ -191,7 +174,6 @@ CureConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 3 margin-left: 3
width: 40 width: 40
font: verdana-11px-rounded
CheckBox CheckBox
id: CureParalyse id: CureParalyse
@ -206,7 +188,6 @@ CureConditions < Panel
margin-top: 10 margin-top: 10
margin-left: 12 margin-left: 12
text: Spell: text: Spell:
font: verdana-11px-rounded
TextEdit TextEdit
id: ParalyseSpell id: ParalyseSpell
@ -214,7 +195,6 @@ CureConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 10 margin-left: 10
width: 100 width: 100
font: verdana-11px-rounded
HoldConditions < Panel HoldConditions < Panel
id: Hold id: Hold
@ -230,8 +210,7 @@ HoldConditions < Panel
margin-top: 10 margin-top: 10
margin-left: 5 margin-left: 5
text: Haste text: Haste
color: #ffaa00 color: #ffaa00
font: verdana-11px-rounded
Label Label
id: label11 id: label11
@ -239,7 +218,6 @@ HoldConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 44 margin-left: 44
text: Mana: text: Mana:
font: verdana-11px-rounded
TextEdit TextEdit
id: HasteCost id: HasteCost
@ -247,7 +225,6 @@ HoldConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 3 margin-left: 3
width: 40 width: 40
font: verdana-11px-rounded
CheckBox CheckBox
id: HoldHaste id: HoldHaste
@ -262,7 +239,6 @@ HoldConditions < Panel
margin-top: 10 margin-top: 10
margin-left: 12 margin-left: 12
text: Spell: text: Spell:
font: verdana-11px-rounded
TextEdit TextEdit
id: HasteSpell id: HasteSpell
@ -270,7 +246,6 @@ HoldConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 10 margin-left: 10
width: 100 width: 100
font: verdana-11px-rounded
Label Label
id: label3 id: label3
@ -279,7 +254,6 @@ HoldConditions < Panel
margin-top: 10 margin-top: 10
text: Utana Vid text: Utana Vid
color: #ffaa00 color: #ffaa00
font: verdana-11px-rounded
Label Label
id: label33 id: label33
@ -287,7 +261,6 @@ HoldConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 21 margin-left: 21
text: Mana: text: Mana:
font: verdana-11px-rounded
TextEdit TextEdit
id: UtanaCost id: UtanaCost
@ -295,7 +268,6 @@ HoldConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 3 margin-left: 3
width: 40 width: 40
font: verdana-11px-rounded
CheckBox CheckBox
id: HoldUtana id: HoldUtana
@ -310,7 +282,6 @@ HoldConditions < Panel
margin-top: 10 margin-top: 10
text: Utamo Vita text: Utamo Vita
color: #ffaa00 color: #ffaa00
font: verdana-11px-rounded
Label Label
id: label44 id: label44
@ -318,7 +289,6 @@ HoldConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 12 margin-left: 12
text: Mana: text: Mana:
font: verdana-11px-rounded
TextEdit TextEdit
id: UtamoCost id: UtamoCost
@ -326,7 +296,6 @@ HoldConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 3 margin-left: 3
width: 40 width: 40
font: verdana-11px-rounded
CheckBox CheckBox
id: HoldUtamo id: HoldUtamo
@ -340,8 +309,7 @@ HoldConditions < Panel
anchors.top: label4.bottom anchors.top: label4.bottom
margin-top: 10 margin-top: 10
text: Recovery text: Recovery
color: #ffaa00 color: #ffaa00
font: verdana-11px-rounded
Label Label
id: label55 id: label55
@ -349,7 +317,6 @@ HoldConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 20 margin-left: 20
text: Mana: text: Mana:
font: verdana-11px-rounded
TextEdit TextEdit
id: UturaCost id: UturaCost
@ -357,7 +324,6 @@ HoldConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 3 margin-left: 3
width: 40 width: 40
font: verdana-11px-rounded
CheckBox CheckBox
id: HoldUtura id: HoldUtura
@ -372,7 +338,6 @@ HoldConditions < Panel
margin-top: 10 margin-top: 10
margin-left: 12 margin-left: 12
text: Spell: text: Spell:
font: verdana-11px-rounded
UturaComboBox UturaComboBox
id: UturaType id: UturaType
@ -380,7 +345,6 @@ HoldConditions < Panel
anchors.left: prev.right anchors.left: prev.right
margin-left: 10 margin-left: 10
width: 100 width: 100
font: verdana-11px-rounded
CheckBox CheckBox
id: IgnoreInPz id: IgnoreInPz
@ -413,7 +377,6 @@ HoldConditions < Panel
ConditionsWindow < MainWindow ConditionsWindow < MainWindow
!text: tr('Condition Manager') !text: tr('Condition Manager')
size: 445 280 size: 445 280
@onEscape: self:hide()
CureConditions CureConditions
id: Cure id: Cure
@ -428,7 +391,6 @@ ConditionsWindow < MainWindow
text: Cure Conditions text: Cure Conditions
color: #88e3dd color: #88e3dd
margin-left: 10 margin-left: 10
font: verdana-11px-rounded
HoldConditions HoldConditions
id: Hold id: Hold
@ -442,8 +404,7 @@ ConditionsWindow < MainWindow
anchors.right: parent.right anchors.right: parent.right
text: Hold Conditions text: Hold Conditions
color: #88e3dd color: #88e3dd
margin-right: 100 margin-right: 100
font: verdana-11px-rounded
HorizontalSeparator HorizontalSeparator
id: separator id: separator

View File

@ -3,7 +3,6 @@ local panelName = "renameContainers"
if type(storage[panelName]) ~= "table" then if type(storage[panelName]) ~= "table" then
storage[panelName] = { storage[panelName] = {
enabled = false; enabled = false;
height = 170,
purse = true; purse = true;
list = { list = {
{ {
@ -76,10 +75,9 @@ renameContui:setId(panelName)
g_ui.loadUIFromString([[ g_ui.loadUIFromString([[
BackpackName < Label BackpackName < Label
background-color: alpha background-color: alpha
text-offset: 18 2 text-offset: 18 0
focusable: true focusable: true
height: 17 height: 16
font: verdana-11px-rounded
CheckBox CheckBox
id: enabled id: enabled
@ -87,7 +85,7 @@ BackpackName < Label
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: 15 width: 15
height: 15 height: 15
margin-top: 1 margin-top: 2
margin-left: 3 margin-left: 3
$focus: $focus:
@ -97,44 +95,31 @@ BackpackName < Label
id: state id: state
!text: tr('M') !text: tr('M')
anchors.right: remove.left anchors.right: remove.left
anchors.verticalCenter: parent.verticalCenter margin-right: 5
margin-right: 1
width: 15 width: 15
height: 15 height: 15
Button Button
id: remove id: remove
!text: tr('X') !text: tr('x')
!tooltip: tr('Remove') !tooltip: tr('Remove')
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
margin-right: 15 margin-right: 15
width: 15 width: 15
height: 15 height: 15
Button
id: openNext
!text: tr('N')
anchors.right: state.left
anchors.verticalCenter: parent.verticalCenter
margin-right: 1
width: 15
height: 15
tooltip: Open container inside with the same ID.
ContListsWindow < MainWindow ContListsWindow < MainWindow
!text: tr('Container Names') !text: tr('Container Names')
size: 465 170 size: 445 170
@onEscape: self:hide() @onEscape: self:hide()
TextList TextList
id: itemList id: itemList
anchors.left: parent.left anchors.left: parent.left
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: separator.top size: 180 83
width: 200
margin-bottom: 6
margin-top: 3 margin-top: 3
margin-bottom: 3
margin-left: 3 margin-left: 3
vertical-scrollbar: itemListScrollBar vertical-scrollbar: itemListScrollBar
@ -163,14 +148,12 @@ ContListsWindow < MainWindow
text: Name: text: Name:
margin-left: 10 margin-left: 10
margin-top: 3 margin-top: 3
font: verdana-11px-rounded
TextEdit TextEdit
id: contName id: contName
anchors.left: lblName.right anchors.left: lblName.right
anchors.top: sep.top anchors.top: sep.top
anchors.right: parent.right anchors.right: parent.right
font: verdana-11px-rounded
Label Label
id: lblCont id: lblCont
@ -178,7 +161,6 @@ ContListsWindow < MainWindow
anchors.verticalCenter: contId.verticalCenter anchors.verticalCenter: contId.verticalCenter
width: 70 width: 70
text: Container: text: Container:
font: verdana-11px-rounded
BotItem BotItem
id: contId id: contId
@ -191,16 +173,14 @@ ContListsWindow < MainWindow
anchors.left: prev.left anchors.left: prev.left
anchors.right: parent.right anchors.right: parent.right
anchors.top: prev.bottom anchors.top: prev.bottom
anchors.bottom: separator.top
margin-bottom: 6
margin-top: 3 margin-top: 3
height: 32
Label Label
anchors.left: lblCont.left anchors.left: lblCont.left
anchors.verticalCenter: sortList.verticalCenter anchors.verticalCenter: prev.verticalCenter
width: 70 width: 70
text: Items: text: Items:
font: verdana-11px-rounded
Button Button
id: addItem id: addItem
@ -228,7 +208,6 @@ ContListsWindow < MainWindow
height: 15 height: 15
margin-top: 2 margin-top: 2
margin-left: 3 margin-left: 3
font: verdana-11px-rounded
CheckBox CheckBox
id: sort id: sort
@ -240,7 +219,6 @@ ContListsWindow < MainWindow
height: 15 height: 15
margin-top: 2 margin-top: 2
margin-left: 15 margin-left: 15
font: verdana-11px-rounded
CheckBox CheckBox
id: forceOpen id: forceOpen
@ -252,19 +230,6 @@ ContListsWindow < MainWindow
height: 15 height: 15
margin-top: 2 margin-top: 2
margin-left: 15 margin-left: 15
font: verdana-11px-rounded
CheckBox
id: lootBag
anchors.left: prev.right
anchors.bottom: parent.bottom
text: Loot Bag
tooltip: Open Loot Bag (gunzodus franchaise)
width: 85
height: 15
margin-top: 2
margin-left: 15
font: verdana-11px-rounded
Button Button
id: closeButton id: closeButton
@ -274,16 +239,6 @@ ContListsWindow < MainWindow
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
size: 45 21 size: 45 21
margin-top: 15 margin-top: 15
ResizeBorder
id: bottomResizeBorder
anchors.fill: separator
height: 3
minimum: 170
maximum: 245
margin-left: 3
margin-right: 3
background: #ffffff88
]]) ]])
function findItemsInArray(t, tfind) function findItemsInArray(t, tfind)
@ -353,6 +308,7 @@ function reopenBackpacks()
end end
end) end)
end end
rootWidget = g_ui.getRootWidget() rootWidget = g_ui.getRootWidget()
@ -360,14 +316,6 @@ if rootWidget then
contListWindow = UI.createWindow('ContListsWindow', rootWidget) contListWindow = UI.createWindow('ContListsWindow', rootWidget)
contListWindow:hide() contListWindow:hide()
contListWindow.onGeometryChange = function(widget, old, new)
if old.height == 0 then return end
config.height = new.height
end
contListWindow:setHeight(config.height or 170)
renameContui.editContList.onClick = function(widget) renameContui.editContList.onClick = function(widget)
contListWindow:show() contListWindow:show()
contListWindow:raise() contListWindow:raise()
@ -404,13 +352,7 @@ if rootWidget then
config.forceOpen = not config.forceOpen config.forceOpen = not config.forceOpen
contListWindow.forceOpen:setChecked(config.forceOpen) contListWindow.forceOpen:setChecked(config.forceOpen)
end end
contListWindow.forceOpen:setChecked(config.forceOpen) contListWindow.forceOpen:setChecked(config.forceOpen)
contListWindow.lootBag.onClick = function(widget)
config.lootBag = not config.lootBag
contListWindow.lootBag:setChecked(config.lootBag)
end
contListWindow.lootBag:setChecked(config.lootBag)
local function refreshSortList(k, t) local function refreshSortList(k, t)
t = t or {} t = t or {}
@ -456,18 +398,13 @@ if rootWidget then
label.state:setColor(entry.min and '#00FF00' or '#FF0000') label.state:setColor(entry.min and '#00FF00' or '#FF0000')
label.state:setTooltip(entry.min and 'Open Minimised' or 'Do not minimise') label.state:setTooltip(entry.min and 'Open Minimised' or 'Do not minimise')
end end
label.openNext.onClick = function(widget)
entry.openNext = not entry.openNext
label.openNext:setChecked(entry.openNext)
label.openNext:setColor(entry.openNext and '#00FF00' or '#FF0000')
end
label:setText(entry.value) label:setText(entry.value)
label.enabled:setChecked(entry.enabled) label.enabled:setChecked(entry.enabled)
label.enabled:setTooltip(entry.enabled and 'Disable' or 'Enable') label.enabled:setTooltip(entry.enabled and 'Disable' or 'Enable')
label.enabled:setImageColor(entry.enabled and '#00FF00' or '#FF0000') label.enabled:setImageColor(entry.enabled and '#00FF00' or '#FF0000')
label.state:setColor(entry.min and '#00FF00' or '#FF0000') label.state:setColor(entry.min and '#00FF00' or '#FF0000')
label.state:setTooltip(entry.min and 'Open Minimised' or 'Do not minimise') label.state:setTooltip(entry.min and 'Open Minimised' or 'Do not minimise')
label.openNext:setColor(entry.openNext and '#00FF00' or '#FF0000')
if tFocus and entry.item == tFocus then if tFocus and entry.item == tFocus then
tFocus = label tFocus = label
@ -503,56 +440,26 @@ if rootWidget then
end end
onContainerOpen(function(container, previousContainer) onContainerOpen(function(container, previousContainer)
if not container.window then return end if renameContui.title:isOn() then
local containerWindow = container.window if not container.window then return end
if not previousContainer then local containerWindow = container.window
containerWindow:setContentHeight(34) if not previousContainer then
end containerWindow:setContentHeight(34)
end
local storageVal = config.list local storageVal = config.list
if storageVal and #storageVal > 0 then if storageVal and #storageVal > 0 then
for _, entry in pairs(storageVal) do for _, entry in pairs(storageVal) do
if entry.enabled and string.find(container:getContainerItem():getId(), entry.item) then if entry.enabled and string.find(container:getContainerItem():getId(), entry.item) then
if entry.min then if entry.min then
containerWindow:minimize() containerWindow:minimize()
end
if renameContui.title:isOn() then
containerWindow:setText(entry.value)
end
if entry.openNext then
for i, item in ipairs(container:getItems()) do
if item:getId() == entry.item then
local time = #storageVal * 250
schedule(time, function()
time = time + 250
g_game.open(item)
end)
end
end end
containerWindow:setText(entry.value)
end end
end end
end end
end end
end) end)
local function nameContainersOnLogin()
for i, container in ipairs(getContainers()) do
if renameContui.title:isOn() then
if not container.window then return end
local containerWindow = container.window
local storageVal = config.list
if storageVal and #storageVal > 0 then
for _, entry in pairs(storageVal) do
if entry.enabled and string.find(container:getContainerItem():getId(), entry.item) then
containerWindow:setText(entry.value)
end
end
end
end
end
end
nameContainersOnLogin()
local function moveItem(item, destination) local function moveItem(item, destination)
return g_game.move(item, destination:getSlotPosition(destination:getItemsCount()), item:getCount()) return g_game.move(item, destination:getSlotPosition(destination:getItemsCount()), item:getCount())
end end
@ -615,12 +522,5 @@ macro(500, function()
if config.purse and config.forceOpen and not getContainerByItem(23396) then if config.purse and config.forceOpen and not getContainerByItem(23396) then
return use(getPurse()) return use(getPurse())
end end
if config.lootBag and config.forceOpen and not getContainerByItem(23721) then
if findItem(23721) then
g_game.open(findItem(23721), getContainerByItem(23396))
else
return use(getPurse())
end
end
delay(1500) delay(1500)
end) end)

View File

@ -50,8 +50,7 @@ local conditions = { -- always add new conditions at the bottom
"Player is paralyzed", -- nothing 10 "Player is paralyzed", -- nothing 10
"Player is in protection zone", -- nothing 11 "Player is in protection zone", -- nothing 11
"Players around is more than:", -- spinbox 12 "Players around is more than:", -- spinbox 12
"Players around is less than:", -- spinbox 13 "Players around is less than:" -- spinbox 13
"TargetBot Danger is Above:" -- spinbox 14
} }
local conditionNumber = 1 local conditionNumber = 1
@ -226,33 +225,25 @@ inputPanel.optionalCondition.pre.onClick = function()
setCondition(false, optionalConditionNumber) setCondition(false, optionalConditionNumber)
end end
listPanel.up.onClick = function(widget) listPanel.up.onClick = function()
local focused = listPanel.list:getFocusedChild() local n = listPanel.list:getChildIndex(listPanel.list:getFocusedChild())
local n = listPanel.list:getChildIndex(focused)
local t = config.rules local t = config.rules
t[n], t[n-1] = t[n-1], t[n] t[n], t[n-1] = t[n-1], t[n]
if n-1 == 1 then listPanel.up:setEnabled(false)
widget:setEnabled(false) listPanel.down:setEnabled(false)
end refreshRules()
listPanel.down:setEnabled(true)
listPanel.list:moveChildToIndex(focused, n-1)
listPanel.list:ensureChildVisible(focused)
end end
listPanel.down.onClick = function(widget) listPanel.down.onClick = function()
local focused = listPanel.list:getFocusedChild() local n = listPanel.list:getChildIndex(listPanel.list:getFocusedChild())
local n = listPanel.list:getChildIndex(focused)
local t = config.rules local t = config.rules
t[n], t[n+1] = t[n+1], t[n] t[n], t[n+1] = t[n+1], t[n]
if n + 1 == listPanel.list:getChildCount() then listPanel.up:setEnabled(false)
widget:setEnabled(false) listPanel.down:setEnabled(false)
end refreshRules()
listPanel.up:setEnabled(true) end
listPanel.list:moveChildToIndex(focused, n+1)
listPanel.list:ensureChildVisible(focused)
end
function getItemsFromBox() function getItemsFromBox()
local t = {} local t = {}
@ -271,19 +262,6 @@ function refreshItemBox(reset)
local box = inputPanel.itemBox local box = inputPanel.itemBox
local childAmount = box:getChildCount() local childAmount = box:getChildCount()
--height
if #getItemsFromBox() < 7 then
mainWindow:setHeight(345)
inputPanel:setHeight(265)
listPanel:setHeight(265)
box:setHeight(40)
else
mainWindow:setHeight(370)
inputPanel:setHeight(300)
listPanel:setHeight(300)
box:setHeight(80)
end
if reset then if reset then
box:destroyChildren() box:destroyChildren()
local widget = UI.createWidget("BotItem", box) local widget = UI.createWidget("BotItem", box)
@ -307,8 +285,9 @@ function refreshItemBox(reset)
widget:destroy() widget:destroy()
end end
refreshItemBox() refreshItemBox()
refreshItemBox()
end end
elseif box:getLastChild():getItemId() > 100 and childAmount <= max then elseif box:getLastChild():getItemId() > 100 and childAmount < max then
local widget = UI.createWidget("BotItem", box) local widget = UI.createWidget("BotItem", box)
widget.onItemChange = function(widget) widget.onItemChange = function(widget)
local id = widget:getItemId() local id = widget:getItemId()
@ -317,6 +296,7 @@ function refreshItemBox(reset)
widget:destroy() widget:destroy()
end end
refreshItemBox() refreshItemBox()
refreshItemBox()
end end
end end
end end
@ -344,7 +324,6 @@ function refreshRules()
list:destroyChildren() list:destroyChildren()
for i,v in pairs(config.rules) do for i,v in pairs(config.rules) do
local widget = UI.createWidget('Rule', list) local widget = UI.createWidget('Rule', list)
widget:setId(v.name)
widget:setText(v.name) widget:setText(v.name)
widget.remove.onClick = function() widget.remove.onClick = function()
widget:destroy() widget:destroy()
@ -534,33 +513,30 @@ end
--"Player is paralyzed", -- nothing 10 --"Player is paralyzed", -- nothing 10
local pressedKey = "" local pressedKey = ""
local lastPress = now
onKeyPress(function(keys) onKeyPress(function(keys)
pressedKey = keys pressedKey = keys
lastPress = now
schedule(100, function()
if now - lastPress > 20 then
pressedKey = ""
end
end)
end) end)
local function interpreteCondition(n, v) local function interpreteCondition(n, v)
local hp = hppercent()
local mp = manapercent()
local mobs = getMonsters()
local players = getPlayers()
if n == 1 then if n == 1 then
return true return true
elseif n == 2 then elseif n == 2 then
return getMonsters() > v return mobs > v
elseif n == 3 then elseif n == 3 then
return getMonsters() < v return mobs < v
elseif n == 4 then elseif n == 4 then
return hppercent() < v return hp < v
elseif n == 5 then elseif n == 5 then
return hppercent() > v return hp > v
elseif n == 6 then elseif n == 6 then
return manapercent() < v return mp < v
elseif n == 7 then elseif n == 7 then
return manapercent() > v return mp > v
elseif n == 8 then elseif n == 8 then
return target() and target():getName():lower() == v:lower() or false return target() and target():getName():lower() == v:lower() or false
elseif n == 9 then elseif n == 9 then
@ -570,13 +546,10 @@ local function interpreteCondition(n, v)
elseif n == 11 then elseif n == 11 then
return isInPz() return isInPz()
elseif n == 12 then elseif n == 12 then
return getPlayers() > v return players > v
elseif n == 13 then elseif n == 13 then
return getPlayers() < v return players < v
elseif n == 14 then
return TargetBot.Danger() > v and TargetBot.isOn()
end end
end end
local function finalCheck(first,relation,second) local function finalCheck(first,relation,second)
@ -632,16 +605,7 @@ EquipManager = macro(50, function()
if #config.rules == 0 then return end if #config.rules == 0 then return end
for i, rule in ipairs(config.rules) do for i, rule in ipairs(config.rules) do
local widget = listPanel.list:getChildById(rule.name)
if mainWindow:isVisible() then
for i, child in ipairs(listPanel.list:getChildren()) do
if child ~= widget then
child:setColor('white')
end
end
end
if rule.enabled then if rule.enabled then
widget:setColor('green')
local firstCondition = interpreteCondition(rule.mainCondition, rule.mainValue) local firstCondition = interpreteCondition(rule.mainCondition, rule.mainValue)
local optionalCondition = nil local optionalCondition = nil
if rule.relation ~= "-" then if rule.relation ~= "-" then

View File

@ -1,11 +1,8 @@
local standBySpells = false local standBySpells = false
local standByItems = false local standByItems = false
local red = "#ff0800" -- "#ff0800" / #ea3c53 best
local blue = "#7ef9ff"
setDefaultTab("HP") setDefaultTab("HP")
local healPanelName = "healbot" healPanelName = "healbot"
local ui = setupUI([[ local ui = setupUI([[
Panel Panel
height: 38 height: 38
@ -171,9 +168,9 @@ activeProfileColor()
ui.title:setOn(currentSettings.enabled) ui.title:setOn(currentSettings.enabled)
ui.title.onClick = function(widget) ui.title.onClick = function(widget)
currentSettings.enabled = not currentSettings.enabled currentSettings.enabled = not currentSettings.enabled
widget:setOn(currentSettings.enabled) widget:setOn(currentSettings.enabled)
vBotConfigSave("heal") vBotConfigSave("heal")
end end
ui.settings.onClick = function(widget) ui.settings.onClick = function(widget)
@ -187,64 +184,45 @@ if rootWidget then
healWindow = UI.createWindow('HealWindow', rootWidget) healWindow = UI.createWindow('HealWindow', rootWidget)
healWindow:hide() healWindow:hide()
healWindow.onVisibilityChange = function(widget, visible)
if not visible then
vBotConfigSave("heal")
healWindow.healer:show()
healWindow.settings:hide()
healWindow.settingsButton:setText("Settings")
end
end
healWindow.settingsButton.onClick = function(widget)
if healWindow.healer:isVisible() then
healWindow.healer:hide()
healWindow.settings:show()
widget:setText("Back")
else
healWindow.healer:show()
healWindow.settings:hide()
widget:setText("Settings")
end
end
local setProfileName = function() local setProfileName = function()
ui.name:setText(currentSettings.name) ui.name:setText(currentSettings.name)
end end
healWindow.settings.profiles.Name.onTextChange = function(widget, text) healWindow.Name.onTextChange = function(widget, text)
currentSettings.name = text currentSettings.name = text
setProfileName() setProfileName()
end end
healWindow.settings.list.Visible.onClick = function(widget) healWindow.Visible.onClick = function(widget)
currentSettings.Visible = not currentSettings.Visible currentSettings.Visible = not currentSettings.Visible
healWindow.settings.list.Visible:setChecked(currentSettings.Visible) healWindow.Visible:setChecked(currentSettings.Visible)
end end
healWindow.settings.list.Cooldown.onClick = function(widget) healWindow.Cooldown.onClick = function(widget)
currentSettings.Cooldown = not currentSettings.Cooldown currentSettings.Cooldown = not currentSettings.Cooldown
healWindow.settings.list.Cooldown:setChecked(currentSettings.Cooldown) healWindow.Cooldown:setChecked(currentSettings.Cooldown)
end end
healWindow.settings.list.Interval.onClick = function(widget) healWindow.Interval.onClick = function(widget)
currentSettings.Interval = not currentSettings.Interval currentSettings.Interval = not currentSettings.Interval
healWindow.settings.list.Interval:setChecked(currentSettings.Interval) healWindow.Interval:setChecked(currentSettings.Interval)
end end
healWindow.settings.list.Conditions.onClick = function(widget) healWindow.Conditions.onClick = function(widget)
currentSettings.Conditions = not currentSettings.Conditions currentSettings.Conditions = not currentSettings.Conditions
healWindow.settings.list.Conditions:setChecked(currentSettings.Conditions) healWindow.Conditions:setChecked(currentSettings.Conditions)
end end
healWindow.settings.list.Delay.onClick = function(widget) healWindow.Delay.onClick = function(widget)
currentSettings.Delay = not currentSettings.Delay currentSettings.Delay = not currentSettings.Delay
healWindow.settings.list.Delay:setChecked(currentSettings.Delay) healWindow.Delay:setChecked(currentSettings.Delay)
end end
healWindow.settings.list.MessageDelay.onClick = function(widget) healWindow.MessageDelay.onClick = function(widget)
currentSettings.MessageDelay = not currentSettings.MessageDelay currentSettings.MessageDelay = not currentSettings.MessageDelay
healWindow.settings.list.MessageDelay:setChecked(currentSettings.MessageDelay) healWindow.MessageDelay:setChecked(currentSettings.MessageDelay)
end end
local refreshSpells = function() local refreshSpells = function()
if currentSettings.spellTable then if currentSettings.spellTable then
healWindow.healer.spells.spellList:destroyChildren() for i, child in pairs(healWindow.spells.spellList:getChildren()) do
child:destroy()
end
for _, entry in pairs(currentSettings.spellTable) do for _, entry in pairs(currentSettings.spellTable) do
local label = UI.createWidget("SpellEntry", healWindow.healer.spells.spellList) local label = UI.createWidget("SpellEntry", healWindow.spells.spellList)
label.enabled:setChecked(entry.enabled) label.enabled:setChecked(entry.enabled)
label.enabled.onClick = function(widget) label.enabled.onClick = function(widget)
standBySpells = false standBySpells = false
@ -259,7 +237,7 @@ if rootWidget then
reindexTable(currentSettings.spellTable) reindexTable(currentSettings.spellTable)
label:destroy() label:destroy()
end end
label:setText("(MP>" .. entry.cost .. ") " .. entry.origin .. entry.sign .. entry.value .. ": " .. entry.spell) label:setText("(MP>" .. entry.cost .. ") " .. entry.origin .. entry.sign .. entry.value .. ":" .. entry.spell)
end end
end end
end end
@ -267,9 +245,11 @@ if rootWidget then
local refreshItems = function() local refreshItems = function()
if currentSettings.itemTable then if currentSettings.itemTable then
healWindow.healer.items.itemList:destroyChildren() for i, child in pairs(healWindow.items.itemList:getChildren()) do
child:destroy()
end
for _, entry in pairs(currentSettings.itemTable) do for _, entry in pairs(currentSettings.itemTable) do
local label = UI.createWidget("ItemEntry", healWindow.healer.items.itemList) local label = UI.createWidget("SpellEntry", healWindow.items.itemList)
label.enabled:setChecked(entry.enabled) label.enabled:setChecked(entry.enabled)
label.enabled.onClick = function(widget) label.enabled.onClick = function(widget)
standBySpells = false standBySpells = false
@ -284,87 +264,138 @@ if rootWidget then
reindexTable(currentSettings.itemTable) reindexTable(currentSettings.itemTable)
label:destroy() label:destroy()
end end
label.id:setItemId(entry.item) label:setText(entry.origin .. entry.sign .. entry.value .. ":" .. entry.item)
label:setText(entry.origin .. entry.sign .. entry.value .. ": " .. entry.item)
end end
end end
end end
refreshItems() refreshItems()
healWindow.healer.spells.MoveUp.onClick = function(widget) healWindow.spells.MoveUp.onClick = function(widget)
local input = healWindow.healer.spells.spellList:getFocusedChild() local input = healWindow.spells.spellList:getFocusedChild()
if not input then return end if not input then return end
local index = healWindow.healer.spells.spellList:getChildIndex(input) local index = healWindow.spells.spellList:getChildIndex(input)
if index < 2 then return end if index < 2 then return end
local t = currentSettings.spellTable 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)
t[index],t[index-1] = t[index-1], t[index] healWindow.spells.spellList:moveChildToIndex(input, index - 1)
healWindow.healer.spells.spellList:moveChildToIndex(input, index - 1) healWindow.spells.spellList:ensureChildVisible(input)
healWindow.healer.spells.spellList:ensureChildVisible(input)
end end
healWindow.healer.spells.MoveDown.onClick = function(widget) healWindow.spells.MoveDown.onClick = function(widget)
local input = healWindow.healer.spells.spellList:getFocusedChild() local input = healWindow.spells.spellList:getFocusedChild()
if not input then return end if not input then return end
local index = healWindow.healer.spells.spellList:getChildIndex(input) local index = healWindow.spells.spellList:getChildIndex(input)
if index >= healWindow.healer.spells.spellList:getChildCount() then return end if index >= healWindow.spells.spellList:getChildCount() then return end
local t = currentSettings.spellTable 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)
t[index],t[index+1] = t[index+1],t[index] healWindow.spells.spellList:moveChildToIndex(input, index + 1)
healWindow.healer.spells.spellList:moveChildToIndex(input, index + 1) healWindow.spells.spellList:ensureChildVisible(input)
healWindow.healer.spells.spellList:ensureChildVisible(input)
end end
healWindow.healer.items.MoveUp.onClick = function(widget) healWindow.items.MoveUp.onClick = function(widget)
local input = healWindow.healer.items.itemList:getFocusedChild() local input = healWindow.items.itemList:getFocusedChild()
if not input then return end if not input then return end
local index = healWindow.healer.items.itemList:getChildIndex(input) local index = healWindow.items.itemList:getChildIndex(input)
if index < 2 then return end if index < 2 then return end
local t = currentSettings.itemTable 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)
t[index],t[index-1] = t[index-1], t[index] healWindow.items.itemList:moveChildToIndex(input, index - 1)
healWindow.healer.items.itemList:moveChildToIndex(input, index - 1) healWindow.items.itemList:ensureChildVisible(input)
healWindow.healer.items.itemList:ensureChildVisible(input)
end end
healWindow.healer.items.MoveDown.onClick = function(widget) healWindow.items.MoveDown.onClick = function(widget)
local input = healWindow.healer.items.itemList:getFocusedChild() local input = healWindow.items.itemList:getFocusedChild()
if not input then return end if not input then return end
local index = healWindow.healer.items.itemList:getChildIndex(input) local index = healWindow.items.itemList:getChildIndex(input)
if index >= healWindow.healer.items.itemList:getChildCount() then return end if index >= healWindow.items.itemList:getChildCount() then return end
local t = currentSettings.itemTable 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)
t[index],t[index+1] = t[index+1],t[index] healWindow.items.itemList:moveChildToIndex(input, index + 1)
healWindow.healer.items.itemList:moveChildToIndex(input, index + 1) healWindow.items.itemList:ensureChildVisible(input)
healWindow.healer.items.itemList:ensureChildVisible(input)
end end
healWindow.healer.spells.addSpell.onClick = function(widget) healWindow.spells.addSpell.onClick = function(widget)
local spellFormula = healWindow.healer.spells.spellFormula:getText():trim() local spellFormula = healWindow.spells.spellFormula:getText():trim()
local manaCost = tonumber(healWindow.healer.spells.manaCost:getText()) local manaCost = tonumber(healWindow.spells.manaCost:getText())
local spellTrigger = tonumber(healWindow.healer.spells.spellValue:getText()) local spellTrigger = tonumber(healWindow.spells.spellValue:getText())
local spellSource = healWindow.healer.spells.spellSource:getCurrentOption().text local spellSource = healWindow.spells.spellSource:getCurrentOption().text
local spellEquasion = healWindow.healer.spells.spellCondition:getCurrentOption().text local spellEquasion = healWindow.spells.spellCondition:getCurrentOption().text
local source local source
local equasion local equasion
if not manaCost then if not manaCost then
warn("HealBot: incorrect mana cost value!") warn("HealBot: incorrect mana cost value!")
healWindow.healer.spells.spellFormula:setText('') healWindow.spells.spellFormula:setText('')
healWindow.healer.spells.spellValue:setText('') healWindow.spells.spellValue:setText('')
healWindow.healer.spells.manaCost:setText('') healWindow.spells.manaCost:setText('')
return return
end end
if not spellTrigger then if not spellTrigger then
warn("HealBot: incorrect condition value!") warn("HealBot: incorrect condition value!")
healWindow.healer.spells.spellFormula:setText('') healWindow.spells.spellFormula:setText('')
healWindow.healer.spells.spellValue:setText('') healWindow.spells.spellValue:setText('')
healWindow.healer.spells.manaCost:setText('') healWindow.spells.manaCost:setText('')
return return
end end
@ -390,28 +421,28 @@ if rootWidget then
if spellFormula:len() > 0 then 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}) table.insert(currentSettings.spellTable, {index = #currentSettings.spellTable+1, spell = spellFormula, sign = equasion, origin = source, cost = manaCost, value = spellTrigger, enabled = true})
healWindow.healer.spells.spellFormula:setText('') healWindow.spells.spellFormula:setText('')
healWindow.healer.spells.spellValue:setText('') healWindow.spells.spellValue:setText('')
healWindow.healer.spells.manaCost:setText('') healWindow.spells.manaCost:setText('')
end end
standBySpells = false standBySpells = false
standByItems = false standByItems = false
refreshSpells() refreshSpells()
end end
healWindow.healer.items.addItem.onClick = function(widget) healWindow.items.addItem.onClick = function(widget)
local id = healWindow.healer.items.itemId:getItemId() local id = healWindow.items.itemId:getItemId()
local trigger = tonumber(healWindow.healer.items.itemValue:getText()) local trigger = tonumber(healWindow.items.itemValue:getText())
local src = healWindow.healer.items.itemSource:getCurrentOption().text local src = healWindow.items.itemSource:getCurrentOption().text
local eq = healWindow.healer.items.itemCondition:getCurrentOption().text local eq = healWindow.items.itemCondition:getCurrentOption().text
local source local source
local equasion local equasion
if not trigger then if not trigger then
warn("HealBot: incorrect trigger value!") warn("HealBot: incorrect trigger value!")
healWindow.healer.items.itemId:setItemId(0) healWindow.items.itemId:setItemId(0)
healWindow.healer.items.itemValue:setText('') healWindow.items.itemValue:setText('')
return return
end end
@ -440,27 +471,28 @@ if rootWidget then
standBySpells = false standBySpells = false
standByItems = false standByItems = false
refreshItems() refreshItems()
healWindow.healer.items.itemId:setItemId(0) healWindow.items.itemId:setItemId(0)
healWindow.healer.items.itemValue:setText('') healWindow.items.itemValue:setText('')
end end
end end
healWindow.closeButton.onClick = function(widget) healWindow.closeButton.onClick = function(widget)
healWindow:hide() healWindow:hide()
vBotConfigSave("heal")
end end
local loadSettings = function() local loadSettings = function()
ui.title:setOn(currentSettings.enabled) ui.title:setOn(currentSettings.enabled)
setProfileName() setProfileName()
healWindow.settings.profiles.Name:setText(currentSettings.name) healWindow.Name:setText(currentSettings.name)
refreshSpells() refreshSpells()
refreshItems() refreshItems()
healWindow.settings.list.Visible:setChecked(currentSettings.Visible) healWindow.Visible:setChecked(currentSettings.Visible)
healWindow.settings.list.Cooldown:setChecked(currentSettings.Cooldown) healWindow.Cooldown:setChecked(currentSettings.Cooldown)
healWindow.settings.list.Delay:setChecked(currentSettings.Delay) healWindow.Delay:setChecked(currentSettings.Delay)
healWindow.settings.list.MessageDelay:setChecked(currentSettings.MessageDelay) healWindow.MessageDelay:setChecked(currentSettings.MessageDelay)
healWindow.settings.list.Interval:setChecked(currentSettings.Interval) healWindow.Interval:setChecked(currentSettings.Interval)
healWindow.settings.list.Conditions:setChecked(currentSettings.Conditions) healWindow.Conditions:setChecked(currentSettings.Conditions)
end end
loadSettings() loadSettings()
@ -493,7 +525,7 @@ if rootWidget then
end end
end end
healWindow.settings.profiles.ResetSettings.onClick = function() healWindow.ResetSettings.onClick = function()
resetSettings() resetSettings()
loadSettings() loadSettings()
end end
@ -534,87 +566,74 @@ if rootWidget then
profileChange() profileChange()
end end
end end
HealBot.show = function()
healWindow:show()
healWindow:raise()
healWindow:focus()
end
end end
-- spells -- spells
macro(100, function() macro(100, function()
if standBySpells then return end if standBySpells then return end
if not currentSettings.enabled then return end if not currentSettings.enabled or modules.game_cooldown.isGroupCooldownIconActive(2) or #currentSettings.spellTable == 0 then return end
local somethingIsOnCooldown = false
for _, entry in pairs(currentSettings.spellTable) do for _, entry in pairs(currentSettings.spellTable) do
if entry.enabled and entry.cost < mana() then if canCast(entry.spell, not currentSettings.Conditions, not currentSettings.Cooldown) and entry.enabled and entry.cost < mana() then
if canCast(entry.spell, not currentSettings.Conditions, not currentSettings.Cooldown) then if entry.origin == "HP%" then
if entry.origin == "HP%" then if entry.sign == "=" and hppercent() == entry.value then
if entry.sign == "=" and hppercent() == entry.value then say(entry.spell)
say(entry.spell) return
return elseif entry.sign == ">" and hppercent() >= entry.value then
elseif entry.sign == ">" and hppercent() >= entry.value then say(entry.spell)
say(entry.spell) return
return elseif entry.sign == "<" and hppercent() <= entry.value then
elseif entry.sign == "<" and hppercent() <= entry.value then say(entry.spell)
say(entry.spell) return
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
else elseif entry.origin == "HP" then
somethingIsOnCooldown = true 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
end end
if not somethingIsOnCooldown then standBySpells = true
standBySpells = true
end
end) end)
-- items -- items

View File

@ -1,9 +1,3 @@
SettingCheckBox < CheckBox
text-wrap: true
text-auto-resize: true
margin-top: 3
font: verdana-11px-rounded
SpellSourceBoxPopupMenu < ComboBoxPopupMenu SpellSourceBoxPopupMenu < ComboBoxPopupMenu
SpellSourceBoxPopupMenuButton < ComboBoxPopupMenuButton SpellSourceBoxPopupMenuButton < ComboBoxPopupMenuButton
SpellSourceBox < ComboBox SpellSourceBox < ComboBox
@ -24,10 +18,9 @@ SpellConditionBox < ComboBox
SpellEntry < Label SpellEntry < Label
background-color: alpha background-color: alpha
text-offset: 18 1 text-offset: 18 0
focusable: true focusable: true
height: 16 height: 16
font: verdana-11px-rounded
CheckBox CheckBox
id: enabled id: enabled
@ -46,33 +39,14 @@ SpellEntry < Label
!text: tr('x') !text: tr('x')
anchors.right: parent.right anchors.right: parent.right
margin-right: 15 margin-right: 15
text-offset: 1 0
width: 15 width: 15
height: 15 height: 15
ItemEntry < Label ItemEntry < Label
background-color: alpha background-color: alpha
text-offset: 40 1 text-offset: 2 0
focusable: true focusable: true
height: 16 height: 16
font: verdana-11px-rounded
CheckBox
id: enabled
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
width: 15
height: 15
margin-top: 2
margin-left: 3
UIItem
id: id
anchors.left: prev.right
margin-left: 3
anchors.verticalCenter: parent.verticalCenter
size: 15 15
focusable: false
$focus: $focus:
background-color: #00000055 background-color: #00000055
@ -82,37 +56,30 @@ ItemEntry < Label
!text: tr('x') !text: tr('x')
anchors.right: parent.right anchors.right: parent.right
margin-right: 15 margin-right: 15
text-offset: 1 0
width: 15 width: 15
height: 15 height: 15
SpellHealing < FlatPanel SpellHealing < Panel
image-source: /images/ui/panel_flat
image-border: 6
padding: 3
size: 490 130 size: 490 130
Label
id: title
anchors.verticalCenter: parent.top
anchors.left: parent.left
margin-left: 5
text: Spell Healing
color: #269e26
font: verdana-11px-rounded
SpellSourceBox
id: spellSource
anchors.top: spellList.top
anchors.left: spellList.right
margin-left: 80
width: 125
font: verdana-11px-rounded
Label Label
id: whenSpell id: whenSpell
anchors.left: spellList.right anchors.left: spellList.right
anchors.verticalCenter: prev.verticalCenter anchors.top: parent.top
text: When text: When
margin-top: 10
margin-left: 7 margin-left: 7
font: verdana-11px-rounded
SpellSourceBox
id: spellSource
anchors.top: parent.top
anchors.left: whenSpell.right
margin-top: 5
margin-left: 35
width: 128
Label Label
id: isSpell id: isSpell
@ -121,7 +88,6 @@ SpellHealing < FlatPanel
text: Is text: Is
margin-top: 9 margin-top: 9
margin-left: 7 margin-left: 7
font: verdana-11px-rounded
SpellConditionBox SpellConditionBox
id: spellCondition id: spellCondition
@ -129,15 +95,13 @@ SpellHealing < FlatPanel
anchors.top: spellSource.bottom anchors.top: spellSource.bottom
marin-top: 15 marin-top: 15
width: 80 width: 80
font: verdana-11px-rounded
TextEdit TextEdit
id: spellValue id: spellValue
anchors.left: spellCondition.right anchors.left: spellCondition.right
anchors.top: spellCondition.top anchors.top: spellCondition.top
anchors.bottom: spellCondition.bottom anchors.bottom: spellCondition.bottom
anchors.right: spellSource.right width: 49
font: verdana-11px-rounded
Label Label
id: castSpell id: castSpell
@ -145,14 +109,12 @@ SpellHealing < FlatPanel
anchors.top: isSpell.bottom anchors.top: isSpell.bottom
text: Cast text: Cast
margin-top: 9 margin-top: 9
font: verdana-11px-rounded
TextEdit TextEdit
id: spellFormula id: spellFormula
anchors.left: spellCondition.left anchors.left: spellCondition.left
anchors.top: spellCondition.bottom anchors.top: spellCondition.bottom
anchors.right: spellValue.right anchors.right: spellValue.right
font: verdana-11px-rounded
Label Label
id: manaSpell id: manaSpell
@ -160,26 +122,21 @@ SpellHealing < FlatPanel
anchors.top: castSpell.bottom anchors.top: castSpell.bottom
text: Mana Cost: text: Mana Cost:
margin-top: 8 margin-top: 8
font: verdana-11px-rounded
TextEdit TextEdit
id: manaCost id: manaCost
anchors.left: spellFormula.left anchors.left: spellFormula.left
anchors.top: spellFormula.bottom anchors.top: spellFormula.bottom
width: 40 width: 40
font: verdana-11px-rounded
TextList TextList
id: spellList id: spellList
anchors.left: parent.left anchors.left: parent.left
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.top: parent.top
padding: 1 padding: 1
padding-top: 2 size: 270 116
width: 270 margin-bottom: 3
margin-bottom: 7 margin-left: 3
margin-left: 7
margin-top: 10
vertical-scrollbar: spellListScrollBar vertical-scrollbar: spellListScrollBar
VerticalScrollBar VerticalScrollBar
@ -193,7 +150,9 @@ SpellHealing < FlatPanel
Button Button
id: addSpell id: addSpell
anchors.right: spellFormula.right anchors.right: spellFormula.right
anchors.bottom: spellList.bottom anchors.bottom: parent.bottom
margin-bottom: 2
margin-right: 10
text: Add text: Add
size: 40 17 size: 40 17
font: cipsoftFont font: cipsoftFont
@ -201,7 +160,8 @@ SpellHealing < FlatPanel
Button Button
id: MoveUp id: MoveUp
anchors.right: prev.left anchors.right: prev.left
anchors.bottom: prev.bottom anchors.bottom: parent.bottom
margin-bottom: 2
margin-right: 5 margin-right: 5
text: Move Up text: Move Up
size: 55 17 size: 55 17
@ -210,39 +170,34 @@ SpellHealing < FlatPanel
Button Button
id: MoveDown id: MoveDown
anchors.right: prev.left anchors.right: prev.left
anchors.bottom: prev.bottom anchors.bottom: parent.bottom
margin-bottom: 2
margin-right: 5 margin-right: 5
text: Move Down text: Move Down
size: 55 17 size: 55 17
font: cipsoftFont font: cipsoftFont
ItemHealing < FlatPanel ItemHealing < Panel
size: 490 120 image-source: /images/ui/panel_flat
image-border: 6
Label padding: 3
id: title size: 490 130
anchors.verticalCenter: parent.top
anchors.left: parent.left
margin-left: 5
text: Item Healing
color: #ff4513
font: verdana-11px-rounded
SpellSourceBox
id: itemSource
anchors.top: itemList.top
anchors.right: parent.right
margin-right: 10
width: 128
font: verdana-11px-rounded
Label Label
id: whenItem id: whenItem
anchors.left: itemList.right anchors.left: itemList.right
anchors.verticalCenter: prev.verticalCenter anchors.top: parent.top
text: When text: When
margin-top: 10
margin-left: 7 margin-left: 7
font: verdana-11px-rounded
SpellSourceBox
id: itemSource
anchors.top: parent.top
anchors.left: whenItem.right
margin-top: 5
margin-left: 35
width: 128
Label Label
id: isItem id: isItem
@ -251,7 +206,6 @@ ItemHealing < FlatPanel
text: Is text: Is
margin-top: 9 margin-top: 9
margin-left: 7 margin-left: 7
font: verdana-11px-rounded
SpellConditionBox SpellConditionBox
id: itemCondition id: itemCondition
@ -259,7 +213,6 @@ ItemHealing < FlatPanel
anchors.top: itemSource.bottom anchors.top: itemSource.bottom
marin-top: 15 marin-top: 15
width: 80 width: 80
font: verdana-11px-rounded
TextEdit TextEdit
id: itemValue id: itemValue
@ -267,7 +220,6 @@ ItemHealing < FlatPanel
anchors.top: itemCondition.top anchors.top: itemCondition.top
anchors.bottom: itemCondition.bottom anchors.bottom: itemCondition.bottom
width: 49 width: 49
font: verdana-11px-rounded
Label Label
id: useItem id: useItem
@ -275,7 +227,6 @@ ItemHealing < FlatPanel
anchors.top: isItem.bottom anchors.top: isItem.bottom
text: Use text: Use
margin-top: 15 margin-top: 15
font: verdana-11px-rounded
BotItem BotItem
id: itemId id: itemId
@ -286,13 +237,11 @@ ItemHealing < FlatPanel
id: itemList id: itemList
anchors.left: parent.left anchors.left: parent.left
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.top: parent.top
padding: 1 padding: 1
padding-top: 2 size: 270 116
width: 270 margin-top: 3
margin-top: 10 margin-bottom: 3
margin-bottom: 7 margin-left: 3
margin-left: 8
vertical-scrollbar: itemListScrollBar vertical-scrollbar: itemListScrollBar
VerticalScrollBar VerticalScrollBar
@ -306,7 +255,9 @@ ItemHealing < FlatPanel
Button Button
id: addItem id: addItem
anchors.right: itemValue.right anchors.right: itemValue.right
anchors.bottom: itemList.bottom anchors.bottom: parent.bottom
margin-bottom: 2
margin-right: 10
text: Add text: Add
size: 40 17 size: 40 17
font: cipsoftFont font: cipsoftFont
@ -314,7 +265,8 @@ ItemHealing < FlatPanel
Button Button
id: MoveUp id: MoveUp
anchors.right: prev.left anchors.right: prev.left
anchors.bottom: prev.bottom anchors.bottom: parent.bottom
margin-bottom: 2
margin-right: 5 margin-right: 5
text: Move Up text: Move Up
size: 55 17 size: 55 17
@ -323,19 +275,20 @@ ItemHealing < FlatPanel
Button Button
id: MoveDown id: MoveDown
anchors.right: prev.left anchors.right: prev.left
anchors.bottom: prev.bottom anchors.bottom: parent.bottom
margin-bottom: 2
margin-right: 5 margin-right: 5
text: Move Down text: Move Down
size: 55 17 size: 55 17
font: cipsoftFont font: cipsoftFont
HealerPanel < Panel HealWindow < MainWindow
size: 510 275 !text: tr('Self Healer')
size: 800 350
SpellHealing SpellHealing
id: spells id: spells
anchors.top: parent.top anchors.top: parent.top
margin-top: 8
anchors.left: parent.left anchors.left: parent.left
ItemHealing ItemHealing
@ -344,128 +297,95 @@ HealerPanel < Panel
anchors.left: parent.left anchors.left: parent.left
margin-top: 10 margin-top: 10
HealBotSettingsPanel < Panel
size: 500 267
padding-top: 8
FlatPanel
id: list
anchors.fill: parent
margin-right: 240
padding-left: 6
padding-right: 6
padding-top: 6
layout:
type: verticalBox
Label
text: Additional Settings
text-align: center
font: verdana-11px-rounded
HorizontalSeparator
SettingCheckBox
id: Cooldown
text: Check spell cooldowns
margin-top: 10
SettingCheckBox
id: Visible
text: Items must be visible (recommended)
SettingCheckBox
id: Delay
text: Don't use items when interacting
SettingCheckBox
id: Interval
text: Additional delay when looting corpses
SettingCheckBox
id: Conditions
text: Also check conditions from RL Tibia
SettingCheckBox
id: MessageDelay
text: Cooldown based on "Aaaah..." message
VerticalSeparator VerticalSeparator
anchors.top: prev.top id: sep
anchors.bottom: prev.bottom anchors.top: parent.top
anchors.left: prev.right anchors.left: prev.right
margin-left: 8 anchors.bottom: separator.top
margin-left: 10
FlatPanel margin-bottom: 5
id: profiles
anchors.fill: parent
anchors.left: prev.left
margin-left: 8
margin-right: 8
padding: 8
Label
text: Profile Settings
text-align: center
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
font: verdana-11px-rounded
HorizontalSeparator
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
Label
anchors.top: prev.bottom
margin-top: 30
anchors.left: parent.left
anchors.right: parent.right
text-align: center
font: verdana-11px-rounded
text: Profile Name:
TextEdit
id: Name
anchors.top: prev.bottom
margin-top: 3
anchors.left: parent.left
anchors.right: parent.right
Button
id: ResetSettings
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
text: Reset Current Profile
text-auto-resize: true
color: #ff4513
HealWindow < MainWindow
!text: tr('Self Healer')
size: 520 360
@onEscape: self:hide()
Label Label
id: title anchors.left: prev.right
anchors.left: parent.left anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
margin-left: 2 text-align: center
!text: tr('More important methods come first (Example: Exura gran above Exura)') text: Additional Options
text-align: left
font: verdana-11px-rounded
color: #aeaeae
HealerPanel HorizontalSeparator
id: healer 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.top: prev.bottom
anchors.left: parent.left anchors.left: prev.left
margin-top: 10
margin-left: 5
width: 200
text: Check spell cooldowns
HealBotSettingsPanel CheckBox
id: settings id: Visible
anchors.top: title.bottom anchors.top: prev.bottom
anchors.left: parent.left anchors.left: prev.left
visible: false 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 HorizontalSeparator
id: separator id: separator
@ -481,12 +401,5 @@ HealWindow < MainWindow
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
size: 45 21 size: 45 21
margin-right: 5 margin-top: 15
margin-right: 5
Button
id: settingsButton
!text: tr('Settings')
font: cipsoftFont
anchors.left: parent.left
anchors.bottom: parent.bottom
size: 45 21

View File

@ -11,54 +11,10 @@
br, Vithrax br, Vithrax
]] ]]
local lootWorth = 0
local wasteWorth = 0
local balance = 0
local balanceDesc = ""
local hourDesc = ""
local desc = ""
local hour = ""
local launchTime = now
local startExp = exp()
local dmgTable = {}
local healTable = {}
local expTable = {}
local totalDmg = 0
local totalHeal = 0
local dmgDistribution = {}
local first = {l="-", r="0"}
local second = {l="-", r="0"}
local third = {l="-", r="0"}
local fourth = {l="-", r="0"}
local five = {l="-", r="0"}
storage.bestHit = storage.bestHit or 0
storage.bestHeal = storage.bestHeal or 0
local lootedItems = {}
local useData = {}
local usedItems ={}
local lastDataSend = {0, 0}
local analyzerButton local analyzerButton
local killList = {}
local membersData = {}
HuntingSessionStart = os.date('%Y-%m-%d, %H:%M:%S')
if not storage.analyzers then
storage.analyzers = {
trackedLoot = {},
customPrices = {},
lootChannel = true,
rarityFrames = true
}
end
storage.analyzers = storage.analyzers or {}
storage.analyzers.trackedLoot = storage.analyzers.trackedLoot or {}
local trackedLoot = storage.analyzers.trackedLoot
--destroy old windows --destroy old windows
local windowsTable = {"MainAnalyzerWindow", "HuntingAnalyzerWindow", "LootAnalyzerWindow", "SupplyAnalyzerWindow", "ImpactAnalyzerWindow", "XPAnalyzerWindow", "PartyAnalyzerWindow", "DropTracker"} local windowsTable = {"MainAnalyzerWindow", "HuntingAnalyzerWindow", "LootAnalyzerWindow", "SupplyAnalyzerWindow", "ImpactAnalyzerWindow", "XPAnalyzerWindow"}
for i, window in ipairs(windowsTable) do for i, window in ipairs(windowsTable) do
local element = g_ui.getRootWidget():recursiveGetChildById(window) local element = g_ui.getRootWidget():recursiveGetChildById(window)
@ -68,26 +24,31 @@ for i, window in ipairs(windowsTable) do
end end
local mainWindow = UI.createMiniWindow("MainAnalyzerWindow") local mainWindow = UI.createMiniWindow("MainAnalyzerWindow")
mainWindow:disableResize()
mainWindow:hide() mainWindow:hide()
mainWindow:setContentMaximumHeight(220)
local huntingWindow = UI.createMiniWindow("HuntingAnalyzer") local huntingWindow = UI.createMiniWindow("HuntingAnalyzer")
huntingWindow:hide() huntingWindow:hide()
local lootWindow = UI.createMiniWindow("LootAnalyzer") local lootWindow = UI.createMiniWindow("LootAnalyzer")
lootWindow:hide() lootWindow:hide()
lootWindow:setContentMaximumHeight(215)
local supplyWindow = UI.createMiniWindow("SupplyAnalyzer") local supplyWindow = UI.createMiniWindow("SupplyAnalyzer")
supplyWindow:hide() supplyWindow:hide()
supplyWindow:setContentMaximumHeight(215)
local impactWindow = UI.createMiniWindow("ImpactAnalyzer") local impactWindow = UI.createMiniWindow("ImpactAnalyzer")
impactWindow:hide() impactWindow:hide()
impactWindow:setContentMaximumHeight(615) impactWindow:setContentMaximumHeight(615)
local xpWindow = UI.createMiniWindow("XPAnalyzer") local xpWindow = UI.createMiniWindow("XPAnalyzer")
xpWindow:hide() xpWindow:hide()
xpWindow:setContentMaximumHeight(230) xpWindow:setContentMaximumHeight(230)
local settingsWindow = UI.createWindow("FeaturesWindow") local settingsWindow = UI.createWindow("FeaturesWindow")
settingsWindow:hide() settingsWindow:hide()
local partyHuntWindow = UI.createMiniWindow("PartyAnalyzerWindow")
partyHuntWindow:hide()
local dropTrackerWindow = UI.createMiniWindow("DropTracker")
dropTrackerWindow:hide()
--f --f
local toggle = function() local toggle = function()
@ -112,51 +73,6 @@ local toggleAnalyzer = function(window)
end end
end end
local function getSumStats()
local totalWaste = 0
local totalLoot = 0
for k,v in pairs(membersData) do
totalWaste = totalWaste + v.waste
totalLoot = totalLoot + v.loot
end
local totalBalance = totalLoot - totalWaste
return totalWaste, totalLoot, totalBalance
end
local function clipboardData()
local totalWaste, totalLoot, totalBalance = getSumStats()
local final = ""
local first = "Session data: From " .. HuntingSessionStart .." to ".. os.date('%Y-%m-%d, %H:%M:%S')
local second = "Session: " .. sessionTime()
local third = "Loot Type: Market"
local fourth = "Loot " .. format_thousand(totalLoot, true)
local fifth = "Supplies " .. format_thousand(totalWaste, true)
local six = "Balance " .. format_thousand(totalBalance, true)
local t = {first, second, third, fourth, fifth, six}
for i, string in ipairs(t) do
final = final.. "\n"..string
end
--user data now
for k,v in pairs(membersData) do
final = final.. "\n".. k
final = final.. "\n\tLoot "..v.loot
final = final.. "\n\tSupplies "..v.waste
final = final.. "\n\tBalance "..v.balance
final = final.. "\n\tDamage "..v.damage
final = final.. "\n\tHealing "..v.heal
end
g_window.setClipboardText(final)
end
-- create analyzers button -- create analyzers button
analyzerButton = modules.game_buttons.buttonsWindow.contentsPanel and modules.game_buttons.buttonsWindow.contentsPanel.buttons.botAnalyzersButton analyzerButton = modules.game_buttons.buttonsWindow.contentsPanel and modules.game_buttons.buttonsWindow.contentsPanel.buttons.botAnalyzersButton
analyzerButton = analyzerButton or modules.client_topmenu.getButton("botAnalyzersButton") analyzerButton = analyzerButton or modules.client_topmenu.getButton("botAnalyzersButton")
@ -172,9 +88,6 @@ analyzerButton:setOn(false)
mainWindow.contentsPanel.HuntingAnalyzer.onClick = function() mainWindow.contentsPanel.HuntingAnalyzer.onClick = function()
toggleAnalyzer(huntingWindow) toggleAnalyzer(huntingWindow)
end end
mainWindow.onClose = function()
analyzerButton:setOn(false)
end
mainWindow.contentsPanel.LootAnalyzer.onClick = function() mainWindow.contentsPanel.LootAnalyzer.onClick = function()
toggleAnalyzer(lootWindow) toggleAnalyzer(lootWindow)
end end
@ -187,14 +100,9 @@ end
mainWindow.contentsPanel.XPAnalyzer.onClick = function() mainWindow.contentsPanel.XPAnalyzer.onClick = function()
toggleAnalyzer(xpWindow) toggleAnalyzer(xpWindow)
end end
mainWindow.contentsPanel.PartyHunt.onClick = function()
toggleAnalyzer(partyHuntWindow)
end
mainWindow.contentsPanel.DropTracker.onClick = function()
toggleAnalyzer(dropTrackerWindow)
end
--hunting --hunting
huntingWindow:setContentMaximumHeight(204)
local sessionTimeLabel = UI.DualLabel("Session:", "00:00h", {}, huntingWindow.contentsPanel).right local sessionTimeLabel = UI.DualLabel("Session:", "00:00h", {}, huntingWindow.contentsPanel).right
local xpGainLabel = UI.DualLabel("XP Gain:", "0", {}, huntingWindow.contentsPanel).right local xpGainLabel = UI.DualLabel("XP Gain:", "0", {}, huntingWindow.contentsPanel).right
local xpHourLabel = UI.DualLabel("XP/h:", "0", {}, huntingWindow.contentsPanel).right local xpHourLabel = UI.DualLabel("XP/h:", "0", {}, huntingWindow.contentsPanel).right
@ -205,171 +113,9 @@ local damageLabel = UI.DualLabel("Damage:", "0", {}, huntingWindow.contentsPanel
local damageHourLabel = UI.DualLabel("Damage/h:", "0", {}, huntingWindow.contentsPanel).right local damageHourLabel = UI.DualLabel("Damage/h:", "0", {}, huntingWindow.contentsPanel).right
local healingLabel = UI.DualLabel("Healing:", "0", {}, huntingWindow.contentsPanel).right local healingLabel = UI.DualLabel("Healing:", "0", {}, huntingWindow.contentsPanel).right
local healingHourLabel = UI.DualLabel("Healing/h:", "0", {}, huntingWindow.contentsPanel).right local healingHourLabel = UI.DualLabel("Healing/h:", "0", {}, huntingWindow.contentsPanel).right
UI.DualLabel("Killed Monsters:", "", {maxWidth = 200}, huntingWindow.contentsPanel)
local killedList = UI.createWidget("AnalyzerListPanel", huntingWindow.contentsPanel)
UI.DualLabel("Looted items:", "", {maxWidth = 200}, huntingWindow.contentsPanel)
local lootList = UI.createWidget("AnalyzerListPanel", huntingWindow.contentsPanel)
--party
UI.Button("Copy to Clipboard", function() clipboardData() end, partyHuntWindow.contentsPanel)
UI.Button("Reset Sessions", function()
if BotServer._websocket then
BotServer.send("partyHunt", false)
end
end, partyHuntWindow.contentsPanel)
local switch = addSwitch("sendData", "Send Analyzer Data", function(widget)
widget:setOn(not widget:isOn())
storage.sendPartyAnalyzerData = widget:isOn()
end, partyHuntWindow.contentsPanel)
switch:setOn(storage.sendPartyAnalyzerData)
UI.Separator(partyHuntWindow.contentsPanel)
local partySessionTimeLabel = UI.DualLabel("Session:", "00:00h", {}, partyHuntWindow.contentsPanel).right
local partyLootLabel = UI.DualLabel("Loot:", "0", {}, partyHuntWindow.contentsPanel).right
local partySuppliesLabel = UI.DualLabel("Supplies:", "0", {}, partyHuntWindow.contentsPanel).right
local partyBalanceLabel = UI.DualLabel("Balance:", "0", {}, partyHuntWindow.contentsPanel).right
UI.Separator(partyHuntWindow.contentsPanel)
local function maintainDropTable()
local panel = dropTrackerWindow.contentsPanel
for k,v in pairs(trackedLoot) do
local widget = panel[k]
if not widget then
trackedLoot[k] = nil
end
end
end
local function createTrackedItems()
local panel = dropTrackerWindow.contentsPanel
for i, child in ipairs(panel:getChildren()) do
if i > 2 then
child:destroy()
end
end
for k,v in pairs(trackedLoot) do
local dropLoot = UI.createWidget("TrackerItem", dropTrackerWindow.contentsPanel)
local item = dropLoot.item
local name = dropLoot.name
local drops = dropLoot.drops
local id = tonumber(k)
local itemName = id == 3031 and "gold coin" or id == 3035 and "platinum coin" or id == 3043 and "crystal coin" or Item.create(id):getMarketData().name
dropLoot:setId(id)
item:setItemId(id)
if item:getItemCount() > 1 then
item:setItemCount(1)
end
name:setText(itemName)
drops:setText("Loot Drops: "..v)
dropLoot.onDoubleClick = function()
local id = dropLoot.item:getItemId()
trackedLoot[tostring(id)] = 0
drops:setText("Loot Drops: 0")
end
for i, child in pairs(dropLoot:getChildren()) do
child:setTooltip("Double click to reset or clear item to remove.")
end
item.onItemChange = function(widget)
local id = widget:getItemId()
if id == 0 then
trackedLoot[widget:getParent():getId()] = nil
if tonumber(widget:getParent():getId()) then
widget:getParent():destroy()
return
end
widget:setImageSource('/images/ui/item')
widget:getParent():setId("blank")
name:setText("Set Item to start track.")
drops:setText("Loot Drops: 0")
return
end
-- only amount have changed, ignore
if tonumber(widget:getParent():getId()) == id then return end
local itemName = id == 3031 and "gold coin" or id == 3035 and "platinum coin" or id == 3043 and "crystal coin" or Item.create(id):getMarketData().name
if trackedLoot[tostring(id)] then
warn("vBot[Drop Tracker]: Item already added!")
name:setText("Set Item to start track.")
widget:setItemId(0)
return
end
widget:setImageSource('')
drops:setText("Loot Drops: 0")
name:setText(itemName)
trackedLoot[tostring(id)] = trackedLoot[tostring(id)] or 0
widget:getParent():setId(id)
maintainDropTable()
end
end
end
--drop tracker
UI.Button("Add item to track drops", function()
local dropLoot = UI.createWidget("TrackerItem", dropTrackerWindow.contentsPanel)
local item = dropLoot.item
local name = dropLoot.name
local drops = dropLoot.drops
item:setImageSource('/images/ui/item')
dropLoot.onDoubleClick = function()
local id = dropLoot.item:getItemId()
trackedLoot[tostring(id)] = 0
drops:setText("Loot Drops: 0")
end
for i, child in pairs(dropLoot:getChildren()) do
child:setTooltip("Double click to reset or clear item to remove.")
end
item.onItemChange = function(widget)
local id = widget:getItemId()
if id == 0 then
trackedLoot[widget:getParent():getId()] = nil
if tonumber(widget:getParent():getId()) then
widget:getParent():destroy()
return
end
widget:setImageSource('/images/ui/item')
widget:getParent():setId("blank")
name:setText("Set Item to start track.")
drops:setText("Loot Drops: 0")
return
end
-- only amount have changed, ignore
if tonumber(widget:getParent():getId()) == id then return end
local itemName = id == 3031 and "gold coin" or id == 3035 and "platinum coin" or id == 3043 and "crystal coin" or Item.create(id):getMarketData().name
if trackedLoot[tostring(id)] then
warn("vBot[Drop Tracker]: Item already added!")
name:setText("Set Item to start track.")
widget:setItemId(0)
return
end
widget:setImageSource('')
drops:setText("Loot Drops: 0")
name:setText(itemName)
trackedLoot[tostring(id)] = trackedLoot[tostring(id)] or 0
widget:getParent():setId(id)
maintainDropTable()
end
end, dropTrackerWindow.contentsPanel)
UI.Separator(dropTrackerWindow.contentsPanel)
createTrackedItems()
--loot --loot
@ -494,18 +240,14 @@ local function getColor(v)
return "#5F8DF7" return "#5F8DF7"
elseif v >= 1000 then -- 1k, green elseif v >= 1000 then -- 1k, green
return "#00FF00" return "#00FF00"
elseif v >= 50 then
return "#FFFFFF" -- 50gp, white
else else
return "#aaaaaa" -- less than 100gp, grey return "#FFFFFF" -- less than 1k, white
end end
end end
local function formatStr(str) local function formatStr(str)
if string.starts(str, "a ") then if string.starts(str, "a ") then
str = str:sub(2, #str) str = str:sub(2, #str)
elseif string.starts(str, "an ") then
str = str:sub(3, #str)
end end
local n = getFirstNumberInText(str) local n = getFirstNumberInText(str)
@ -519,7 +261,6 @@ end
local function getPrice(name) local function getPrice(name)
name = formatStr(name) name = formatStr(name)
name = name:lower()
-- first check custom prices -- first check custom prices
if storage.analyzers.customPrices[name] then if storage.analyzers.customPrices[name] then
return storage.analyzers.customPrices[name] return storage.analyzers.customPrices[name]
@ -548,57 +289,6 @@ local function getPrice(name)
return 0 return 0
end end
local expGained = function()
return exp() - startExp
end
function format_thousand(v, comma)
comma = comma and "," or "."
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), "(...)", comma.."%1")
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
niceTimeFormat = function(v) -- v in seconds
local hours = string.format("%02.f", math.floor(v/3600))
local mins = string.format("%02.f", math.floor(v/60 - (hours*60)))
return hours .. ":" .. mins .. "h"
end
local uptime
sessionTime = function()
uptime = math.floor((now - launchTime)/1000)
return niceTimeFormat(uptime)
end
sessionTime()
local expPerHour = function(calculation)
local r = 0
if #expTable > 0 then
r = exp() - expTable[1]
else
return "-"
end
if uptime < 15*60 then
r = math.ceil((r/uptime)*60*60)
else
r = math.ceil(r*8)
end
if calculation then
return r
else
return format_thousand(r)
end
end
local function add(t, text, color, last) local function add(t, text, color, last)
table.insert(t, text) table.insert(t, text)
table.insert(t, color) table.insert(t, color)
@ -608,147 +298,9 @@ local function add(t, text, color, last)
end end
end end
-- Bot Server
local function sendData()
if BotServer._websocket then
local totalDmg, totalHeal, lootWorth, wasteWorth, balance = getHuntingData()
local outfit = player:getOutfit()
outfit.mount = 0
local t = {
totalDmg,
totalHeal,
balance,
hppercent(),
manapercent(),
outfit,
player:isPartyLeader(),
lootWorth,
wasteWorth,
modules.game_skills.skillsWindow.contentsPanel.stamina.value:getText(),
format_thousand(expGained()),
expPerHour(),
balanceDesc .. " (" .. hourDesc .. ")",
sessionTime()
}
-- validation
if lastDataSend.totalDmg ~= t[1] and lastDataSend.totalHeal ~= t[2] then
BotServer.send("partyHunt", t)
lastDataSend[1] = t[1]
lastDataSend[2] = t[2]
end
end
end
-- process data
BotServer.listen("partyHunt", function(name, message)
if message == true then
sendData()
elseif message == false then
resetAnalyzerSessionData()
else
membersData[name] = {
damage = message[1],
heal = message[2],
balance = message[3],
hp = message[4],
mana = message[5],
outfit = message[6],
leader = message[7],
loot = message[8],
waste = message[9],
stamina = message[10],
expGained = message[11],
expH = message[12],
balanceH = message[13],
session = message[14]
}
local widgetName = "Widget"..name
local widget = partyHuntWindow.contentsPanel[widgetName] or UI.createWidget("MemberWidget", partyHuntWindow.contentsPanel)
widget:setId(widgetName)
widget.lastUpdate = now
local t = membersData[name]
widget.name:setText(name)
widget.name:setColor("white")
if t.leader then
widget.name:setColor('#f8db38')
end
schedule(10*1000, function()
if widget and widget.lastUpdate and now - widget.lastUpdate > 10000 then
widget.name:setText(widget.name:getText().. " [inactive]")
widget.name:setColor("#aeaeae")
widget.health:setBackgroundColor("#aeaeae")
widget.mana:setBackgroundColor("#aeaeae")
widget.balance.value:setText("-")
widget.damage.value:setText("-")
widget.healing.value:setText("-")
widget.creature:disable()
end
end)
widget.creature:setOutfit(t.outfit)
widget.health:setPercent(t.hp)
widget.health:setBackgroundColor("#00c000")
widget.mana:setPercent(t.mana)
widget.mana:setBackgroundColor("#0000FF")
widget.balance.value:setText(format_thousand(t.balance))
if t.balance < 0 then
widget.balance.value:setColor('#ff9854')
elseif t.balance > 0 then
widget.balance.value:setColor('#45ad25')
else
widget.balance.value:setColor('white')
end
widget.damage.value:setText(format_thousand(t.damage))
widget.healing.value:setText(format_thousand(t.heal))
widget.onDoubleClick = function()
membersData[name] = nil
widget:destroy()
end
--tooltip
local tooltip = "Session: "..t.session.."\n"..
"Stamina: "..t.stamina.."\n"..
"Exp Gained: "..t.expGained.."\n"..
"Exp per Hour: "..t.expH.."\n"..
"Balance: "..t.balanceH
widget.creature:setTooltip(tooltip)
end
end)
function hightlightText(widget, color, duration)
for i=0,duration do
schedule(i * 250, function()
if i == duration or (i > 0 and i % 2 == 0) then
widget:setColor("#FFFFFF")
else
widget:setColor(color)
end
end)
end
end
local nameRegex = [[Loot of (?:an |a |the |)([^:]+)]]
onTextMessage(function(mode, text) onTextMessage(function(mode, text)
if not storage.analyzers.lootChannel then return end if not storage.analyzers.lootChannel then return end
if not text:find("Loot of") and not text:find("The following items are available in your reward chest") then return end if not text:find("Loot of") and not text:find("The following items are available in your reward chest") then return end
local name
-- adding monster to killed list
if text:find("Loot of") then
name = regexMatch(text, nameRegex)[1][2]
if not killList[name] then
killList[name] = 1
else
killList[name] = killList[name] + 1
end
refreshKills()
end
-- variables -- variables
local split = string.split(text, ":") local split = string.split(text, ":")
local re = regexMatch(split[2], regex) local re = regexMatch(split[2], regex)
@ -756,50 +308,21 @@ onTextMessage(function(mode, text)
local formatted local formatted
local div local div
local t = {} local t = {}
local messageT = {}
-- add timestamp, creature part and color it as white -- add timestamp, creature part and color it as white
add(t, os.date('%H:%M') .. ' ' .. split[1]..": ", "#FFFFFF", true) add(t, os.date('%H:%M') .. ' ' .. split[1]..": ", "#FFFFFF", true)
add(messageT, split[1]..": ", "#FFFFFF", true)
-- main part -- main part
if re ~= 0 then if re ~= 0 then
for i=1,#re do for i=1,#re do
local data = re[i][2] -- each looted item local data = re[i][2] -- each looted item
local formattedLoot = regexMatch(data, [[(^[^(]+)]])[1][1] local amount = getFirstNumberInText(data) -- amount found in data
formattedLoot = formattedLoot:trim() local price = amount and getPrice(data) * amount or getPrice(data) -- if amount then multity price, else just take price
local amount = getFirstNumberInText(formattedLoot) -- amount found in data
local price = amount and getPrice(formattedLoot) * amount or getPrice(formattedLoot) -- if amount then multity price, else just take price
local color = getColor(price) -- generate hex string based off price local color = getColor(price) -- generate hex string based off price
local messageColor = getColor(getPrice(formattedLoot))
combinedWorth = combinedWorth + price -- add all prices to calculate total worth combinedWorth = combinedWorth + price -- add all prices to calculate total worth
add(t, data, color, i==#re) add(t, data, color, i==#re)
add(messageT, data, color, i==#re)
--drop tracker
for i, child in ipairs(dropTrackerWindow.contentsPanel:getChildren()) do
local childName = child.name
childName = childName and childName:getText()
if childName and formattedLoot:find(childName) then
trackedLoot[tostring(child.item:getItemId())] = trackedLoot[tostring(child.item:getItemId())] + (amount or 1)
child.drops:setText("Loot Drops: "..trackedLoot[tostring(child.item:getItemId())])
hightlightText(child.name,"#f0b400", 8)
modules.game_textmessage.messagesPanel.statusLabel:setVisible(true)
modules.game_textmessage.messagesPanel.statusLabel:setColoredText({
"Valuable loot: ", "#f0b400",
childName.."", messageColor,
" dropped by "..name.."!", "#f0b400"
})
schedule(3000, function()
modules.game_textmessage.messagesPanel.statusLabel:setVisible(false)
end)
end
end
end end
end end
@ -814,13 +337,6 @@ onTextMessage(function(mode, text)
formatted = combinedWorth .. "gp" formatted = combinedWorth .. "gp"
end end
if modules.game_textmessage.messagesPanel.centerTextMessagePanel.highCenterLabel:getText() == text then
modules.game_textmessage.messagesPanel.centerTextMessagePanel.highCenterLabel:setColoredText(messageT)
schedule(math.max(#text * 50, 2000), function()
modules.game_textmessage.messagesPanel.centerTextMessagePanel.highCenterLabel:setVisible(false)
end)
end
-- add total worth to string -- add total worth to string
add(t, " - (", "#FFFFFF", true) add(t, " - (", "#FFFFFF", true)
add(t, formatted, getColor(combinedWorth), true) add(t, formatted, getColor(combinedWorth), true)
@ -859,7 +375,27 @@ local function niceFormat(v)
return formatted return formatted
end end
resetAnalyzerSessionData = function()
local launchTime = now
local startExp = exp()
local dmgTable = {}
local healTable = {}
local expTable = {}
local totalDmg = 0
local totalHeal = 0
local dmgDistribution = {}
local first = {l="-", r="0"}
local second = {l="-", r="0"}
local third = {l="-", r="0"}
local fourth = {l="-", r="0"}
local five = {l="-", r="0"}
storage.bestHit = storage.bestHit or 0
storage.bestHeal = storage.bestHeal or 0
local lootedItems = {}
local useData = {}
local usedItems ={}
local resetSessionData = function()
launchTime = now launchTime = now
startExp = exp() startExp = exp()
dmgTable = {} dmgTable = {}
@ -888,13 +424,10 @@ resetAnalyzerSessionData = function()
drawGraph(dmgGraph, 0) drawGraph(dmgGraph, 0)
healGraph:clear() healGraph:clear()
drawGraph(healGraph, 0) drawGraph(healGraph, 0)
killList = {}
refreshKills()
HuntingSessionStart = os.date('%Y-%m-%d, %H:%M:%S')
end end
mainWindow.contentsPanel.ResetSession.onClick = function() mainWindow.contentsPanel.ResetSession.onClick = function()
resetAnalyzerSessionData() resetSessionData()
end end
mainWindow.contentsPanel.Settings.onClick = function() mainWindow.contentsPanel.Settings.onClick = function()
@ -909,14 +442,22 @@ settingsWindow.closeButton.onClick = function()
settingsWindow:hide() settingsWindow:hide()
end end
if not storage.analyzers then
storage.analyzers = {
customPrices = {},
lootChannel = true,
rarityFrames = true
}
end
local function getFrame(v) local function getFrame(v)
if v >= 1000000 then if v > 1000000 then
return '/images/ui/rarity_gold' return '/images/ui/rarity_gold'
elseif v >= 100000 then elseif v > 100000 then
return '/images/ui/rarity_purple' return '/images/ui/rarity_purple'
elseif v >= 10000 then elseif v > 10000 then
return '/images/ui/rarity_blue' return '/images/ui/rarity_blue'
elseif v >= 1000 then elseif v > 1000 then
return '/images/ui/rarity_green' return '/images/ui/rarity_green'
else else
return '/images/ui/item' return '/images/ui/item'
@ -1027,6 +568,63 @@ settingsWindow.RarityFrames.onClick = function(widget)
setFrames() setFrames()
end end
function format_thousand(v)
if not v then return 0 end
local s = string.format("%d", math.floor(v))
local pos = string.len(s) % 3
if pos == 0 then pos = 3 end
return string.sub(s, 1, pos)
.. string.gsub(string.sub(s, pos+1), "(...)", ".%1")
end
local expGained = function()
return exp() - startExp
end
local expLeft = function()
local level = lvl()+1
return math.floor((50*level*level*level)/3 - 100*level*level + (850*level)/3 - 200) - exp()
end
local niceTimeFormat = function(v) -- v in seconds
local hours = string.format("%02.f", math.floor(v/3600))
local mins = string.format("%02.f", math.floor(v/60 - (hours*60)))
return hours .. ":" .. mins .. "h"
end
local uptime
local sessionTime = function()
uptime = math.floor((now - launchTime)/1000)
return niceTimeFormat(uptime)
end
sessionTime()
local expPerHour = function(calculation)
local r = 0
if #expTable > 0 then
r = exp() - expTable[1]
else
return "-"
end
if uptime < 15*60 then
r = math.ceil((r/uptime)*60*60)
else
r = math.ceil(r*8)
end
if calculation then
return r
else
return format_thousand(r)
end
end
local timeToLevel = function() local timeToLevel = function()
local t = 0 local t = 0
if expPerHour(true) == 0 or expPerHour() == "-" then if expPerHour(true) == 0 or expPerHour() == "-" then
@ -1174,11 +772,9 @@ end
function refreshLoot() function refreshLoot()
lootItems:destroyChildren() lootItems.List:destroyChildren()
lootList:destroyChildren()
for k,v in pairs(lootedItems) do for k,v in pairs(lootedItems) do
local label1 = UI.createWidget("AnalyzerLootItem", lootItems) local label1 = UI.createWidget("AnalyzerLootItem", lootItems.List)
local price = v.count and getPrice(v.name) * v.count or getPrice(v.name) local price = v.count and getPrice(v.name) * v.count or getPrice(v.name)
label1:setItemId(k) label1:setItemId(k)
@ -1188,38 +784,17 @@ function refreshLoot()
label1.count:setColor(getColor(price)) label1.count:setColor(getColor(price))
local tooltipName = v.count > 1 and v.name.."s" or v.name local tooltipName = v.count > 1 and v.name.."s" or v.name
label1:setTooltip(v.count .. "x " .. tooltipName .. " (Value: "..format_thousand(getPrice(v.name)).."gp, Sum: "..format_thousand(price).."gp)") label1:setTooltip(v.count .. "x " .. tooltipName .. " (Value: "..format_thousand(getPrice(v.name)).."gp, Sum: "..format_thousand(price).."gp)")
--hunting window loot list
local label2 = UI.createWidget("ListLabel", lootList)
label2:setText(v.count .. "x " .. v.name)
end
if lootItems:getChildCount() == 0 then
local label = UI.createWidget("ListLabel", lootList)
label:setText("None")
end end
local height = getPanelHeight(lootItems)
lootItems:setHeight(height)
lootWindow:setContentMaximumHeight(height+220)
end end
refreshLoot()
function refreshKills()
killedList:destroyChildren()
local kills = 0
for k,v in pairs(killList) do
kills = kills + 1
local label = UI.createWidget("ListLabel", killedList)
label:setText(v .. "x " .. k)
end
if kills == 0 then
local label = UI.createWidget("ListLabel", killedList)
label:setText("None")
end
end
refreshKills()
function refreshWaste() function refreshWaste()
supplyItems:destroyChildren() supplyItems.List:destroyChildren()
for k,v in pairs(usedItems) do for k,v in pairs(usedItems) do
local label1 = UI.createWidget("AnalyzerLootItem", supplyItems) local label1 = UI.createWidget("AnalyzerLootItem", supplyItems.List)
local price = v.count and getPrice(v.name) * v.count or getPrice(v.name) local price = v.count and getPrice(v.name) * v.count or getPrice(v.name)
label1:setItemId(k) label1:setItemId(k)
@ -1230,8 +805,13 @@ function refreshWaste()
local tooltipName = v.count > 1 and v.name.."s" or v.name local tooltipName = v.count > 1 and v.name.."s" or v.name
label1:setTooltip(v.count .. "x " .. tooltipName .. " (Value: "..format_thousand(getPrice(v.name)).."gp, Sum: "..format_thousand(price).."gp)") label1:setTooltip(v.count .. "x " .. tooltipName .. " (Value: "..format_thousand(getPrice(v.name)).."gp, Sum: "..format_thousand(price).."gp)")
end end
local height = getPanelHeight(supplyItems)
supplyItems:setHeight(height)
supplyWindow:setContentMaximumHeight(height+215)
end end
-- loot analyzer -- loot analyzer
-- adding -- adding
local containers = CaveBot.GetLootContainers() local containers = CaveBot.GetLootContainers()
@ -1241,6 +821,7 @@ onAddItem(function(container, slot, item, oldItem)
if isInPz() then return end if isInPz() then return end
if slot > 0 then return end if slot > 0 then return end
if freecap() >= lastCap then return end if freecap() >= lastCap then return end
--local name = item:getId() == 3031 and "gold coin" or item:getId() == 3035 and "platinum coin" or item:getId() == 3043 and "crystal coin" or item:getMarketData().name
local name = item:getId() local name = item:getId()
local tmpname = item:getId() == 3031 and "gold coin" or item:getId() == 3035 and "platinum coin" or item:getId() == 3043 and "crystal coin" or item:getMarketData().name local tmpname = item:getId() == 3031 and "gold coin" or item:getId() == 3035 and "platinum coin" or item:getId() == 3043 and "crystal coin" or item:getMarketData().name
if not lootedItems[name] then if not lootedItems[name] then
@ -1250,8 +831,6 @@ onAddItem(function(container, slot, item, oldItem)
end end
lastCap = freecap() lastCap = freecap()
refreshLoot() refreshLoot()
-- drop tracker
end) end)
onContainerUpdateItem(function(container, slot, item, oldItem) onContainerUpdateItem(function(container, slot, item, oldItem)
@ -1315,8 +894,6 @@ onTextMessage(function(mode, text)
else else
usedItems[id].count = usedItems[id].count + 1 usedItems[id].count = usedItems[id].count + 1
end end
else
useData[name] = amount
end end
refreshWaste() refreshWaste()
end end
@ -1327,6 +904,15 @@ function hourVal(v)
return (v/uptime)*3600 return (v/uptime)*3600
end end
local lootWorth
local wasteWorth
local balance
local balanceDesc
local hourDesc
local desc
local hour
function bottingStats() function bottingStats()
lootWorth = 0 lootWorth = 0
wasteWorth = 0 wasteWorth = 0
@ -1422,11 +1008,6 @@ function lootHour()
end end
end end
function getHuntingData()
local lootWorth, wasteWorth, balance = bottingStats()
return totalDmg, totalHeal, lootWorth, wasteWorth, balance
end
--bestdps/hps --bestdps/hps
local bestDPS = 0 local bestDPS = 0
local bestHPS = 0 local bestHPS = 0
@ -1448,7 +1029,7 @@ macro(500, function()
xpHourLabel:setText(expPerHour()) xpHourLabel:setText(expPerHour())
lootLabel:setText(format_thousand(lootWorth)) lootLabel:setText(format_thousand(lootWorth))
suppliesLabel:setText(format_thousand(wasteWorth)) suppliesLabel:setText(format_thousand(wasteWorth))
balanceLabel:setColor(balance >= 0 and "#45ad25" or "#ff9854") balanceLabel:setColor(balance >= 0 and "green" or "red")
balanceLabel:setText(balanceDesc .. " (" .. hourDesc .. ")") balanceLabel:setText(balanceDesc .. " (" .. hourDesc .. ")")
damageLabel:setText(format_thousand(totalDmg)) damageLabel:setText(format_thousand(totalDmg))
damageHourLabel:setText(format_thousand(damageHour())) damageHourLabel:setText(format_thousand(damageHour()))
@ -1499,81 +1080,4 @@ macro(60*1000, function()
drawGraph(supplyGraph, wasteHour() or 0) drawGraph(supplyGraph, wasteHour() or 0)
drawGraph(dmgGraph, valueInSeconds(dmgTable) or 0) drawGraph(dmgGraph, valueInSeconds(dmgTable) or 0)
drawGraph(healGraph, valueInSeconds(healTable) or 0) drawGraph(healGraph, valueInSeconds(healTable) or 0)
end) end)
--party hunt analyzer
macro(2000, function()
if not BotServer._websocket then return end
-- send data
if storage.sendPartyAnalyzerData then
sendData()
end
local totalWaste, totalLoot, totalBalance = getSumStats()
partySessionTimeLabel:setText(sessionTime())
partyLootLabel:setText(format_thousand(totalLoot))
partySuppliesLabel:setText(format_thousand(totalWaste))
partyBalanceLabel:setText(format_thousand(totalBalance))
if totalBalance < 0 then
partyBalanceLabel:setColor('#ff9854')
elseif totalBalance > 0 then
partyBalanceLabel:setColor('#45ad25')
else
partyBalanceLabel:setColor('white')
end
end)
-- public functions
-- global namespace
Analyzer = {}
Analyzer.getKillsAmount = function(name)
return killList[name] or 0
end
Analyzer.getLootedAmount = function(nameOrId)
if type(nameOrId) == "number" then
return lootedItems[nameOrId].count or 0
else
local nameOrId = nameOrId:lower()
for k,v in pairs(lootedItems) do
if v.name == nameOrId then
return v.count
end
end
end
return 0
end
Analyzer.getTotalProfit = function()
local lootWorth, wasteWorth, balance = bottingStats()
return lootWorth
end
Analyzer.getTotalWaste = function()
local lootWorth, wasteWorth, balance = bottingStats()
return wasteWorth
end
Analyzer.getBalance = function()
local lootWorth, wasteWorth, balance = bottingStats()
return balance
end
Analyzer.getXpGained = function()
return expGained()
end
Analyzer.getXpHour = function()
return expPerHour()
end
Analyzer.getTimeToNextLevel = function()
return timeToLevel()
end

View File

@ -1,121 +1,3 @@
TrackerItem < Panel
height: 40
BotItem
id: item
anchors.top: parent.top
margin-top: 2
anchors.left: parent.left
image-source:
UIWidget
id: name
anchors.top: prev.top
margin-top: 1
anchors.bottom: prev.verticalCenter
anchors.left: prev.right
anchors.right: parent.right
margin-left: 5
text: Set Item to start track.
text-align:left
font: verdana-11px-rounded
color: #FFFFFF
UIWidget
id: drops
anchors.top: prev.bottom
margin-top: 3
anchors.bottom: Item.bottom
anchors.left: prev.left
anchors.right: parent.right
font: verdana-11px-rounded
text-align:left
text: Loot Drops: 0
color: #CCCCCC
DualLabel < Label
height: 15
text-offset: 4 0
font: verdana-11px-rounded
text-align: left
width: 50
Label
id: value
anchors.right: parent.right
margin-right: 4
anchors.verticalCenter: parent.verticalCenter
width: 200
font: verdana-11px-rounded
text-align: right
text: 0
MemberWidget < Panel
height: 85
margin-top: 3
UICreature
id: creature
anchors.top: parent.top
anchors.left: parent.left
anchors.bottom: parent.bottom
size: 28 28
UIWidget
id: name
anchors.left: prev.right
margin-left: 5
anchors.top: parent.top
height: 12
anchors.right: parent.right
text: Player Name
font: verdana-11px-rounded
text-align: left
ProgressBar
id: health
anchors.left: prev.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 2
height: 7
background-color: #00c000
phantom: false
ProgressBar
id: mana
anchors.left: prev.left
anchors.right: parent.right
anchors.top: prev.bottom
height: 7
background-color: #0000FF
phantom: false
DualLabel
id: balance
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 5
text: Balance:
DualLabel
id: damage
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 2
text: Damage:
DualLabel
id: healing
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 2
text: Healing:
AnalyzerPriceLabel < Label AnalyzerPriceLabel < Label
background-color: alpha background-color: alpha
text-offset: 2 0 text-offset: 2 0
@ -133,28 +15,19 @@ AnalyzerPriceLabel < Label
width: 15 width: 15
height: 15 height: 15
AnalyzerListPanel < Panel
padding-left: 4
padding-right: 4
layout:
type: verticalBox
fit-children: true
ListLabel < Label
height: 15
font: verdana-11px-rounded
text-offset: 15 0
AnalyzerItemsPanel < Panel AnalyzerItemsPanel < Panel
id: List height: 0
padding: 2
layout: Panel
type: grid id: List
cell-size: 33 33 anchors.fill: parent
cell-spacing: 1 margin-top: 3
num-columns: 5 padding: 2
fit-children: true layout:
type: grid
cell-size: 32 32
cell-spacing: 3
num-columns: 5
AnalyzerLootItem < UIItem AnalyzerLootItem < UIItem
opacity: 0.87 opacity: 0.87
@ -206,7 +79,7 @@ AnalyzerButton < Button
MainAnalyzerWindow < MiniWindow MainAnalyzerWindow < MiniWindow
id: MainAnalyzerWindow id: MainAnalyzerWindow
text: Analytics Selector text: Analytics Selector
height: 245 height: 200
icon: /images/topbuttons/analyzers icon: /images/topbuttons/analyzers
MiniWindowContents MiniWindowContents
@ -235,15 +108,6 @@ MainAnalyzerWindow < MiniWindow
id: XPAnalyzer id: XPAnalyzer
text: XP Analyzer text: XP Analyzer
AnalyzerButton
id: DropTracker
text: Drop Tracker
AnalyzerButton
id: PartyHunt
text: Party Hunt
color: #3895D3
AnalyzerButton AnalyzerButton
id: Settings id: Settings
text: Features & Settings text: Features & Settings
@ -300,29 +164,6 @@ XPAnalyzer < MiniWindow
padding-top: 3 padding-top: 3
layout: verticalBox layout: verticalBox
PartyAnalyzerWindow < MiniWindow
id: PartyAnalyzerWindow
text: Party Hunt
height: 200
icon: /images/topbuttons/analyzers
MiniWindowContents
padding-left: 3
padding-right: 3
padding-top: 1
layout: verticalBox
DropTracker < MiniWindow
id: DropTracker
text: Drop Tracker
height: 200
icon: /images/topbuttons/analyzers
MiniWindowContents
padding-left: 3
padding-right: 3
padding-top: 1
layout: verticalBox
FeaturesWindow < MainWindow FeaturesWindow < MainWindow
id: FeaturesWindow id: FeaturesWindow

View File

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

View File

@ -9,22 +9,12 @@ if not g_resources.directoryExists("/bot/".. configName .."/vBot_configs/") then
g_resources.makeDir("/bot/".. configName .."/vBot_configs/") g_resources.makeDir("/bot/".. configName .."/vBot_configs/")
end end
-- make profile dirs
for i=1,10 do
local path = "/bot/".. configName .."/vBot_configs/profile_"..i
if not g_resources.directoryExists(path) then
g_resources.makeDir(path)
end
end
local profile = g_settings.getNumber('profile')
HealBotConfig = {} HealBotConfig = {}
local healBotFile = "/bot/" .. configName .. "/vBot_configs/profile_".. profile .. "/HealBot.json" local healBotFile = "/bot/" .. configName .. "/vBot_configs/".. name() .. " HealBot.json"
AttackBotConfig = {} AttackBotConfig = {}
local attackBotFile = "/bot/" .. configName .. "/vBot_configs/profile_".. profile .. "/AttackBot.json" local attackBotFile = "/bot/" .. configName .. "/vBot_configs/".. name() .. " AttackBot.json"
SuppliesConfig = {} SuppliesConfig = {}
local suppliesFile = "/bot/" .. configName .. "/vBot_configs/profile_".. profile .. "/Supplies.json" local suppliesFile = "/bot/" .. configName .. "/vBot_configs/".. name() .. " Supplies.json"
--healbot --healbot

View File

@ -0,0 +1,65 @@
setDefaultTab("Cave")
local panelName = "specialDeposit"
local depositerPanel
UI.Button("Depositer Settings", function()
depositerPanel:show()
depositerPanel:raise()
depositerPanel:focus()
end)
if not storage[panelName] then
storage[panelName] = {
items = {}
}
end
local config = storage[panelName]
local rootWidget = g_ui.getRootWidget()
if rootWidget then
depositerPanel = UI.createWindow('DepositerPanel', rootWidget)
depositerPanel:hide()
-- basic one
depositerPanel.CloseButton.onClick = function()
depositerPanel:hide()
end
if config.items and #config.items > 0 then
for _, value in ipairs(config.items) do
local label = g_ui.createWidget("ItemLabel", depositerPanel.DepositerList)
label.remove.onClick = function(widget)
table.remove(config.items, table.find(value))
label:destroy()
end
label:setText("Stash (".. value.id .. ") to depot: (" .. value.index .. ")")
end
end
depositerPanel.Add.onClick = function(widget)
local itemId = depositerPanel.ID:getItemId()
local index = tonumber(depositerPanel.Index:getText())
if index and itemId > 100 and not config.items[itemId] then
local value = {id=itemId,index=index}
table.insert(config.items, value)
local label = g_ui.createWidget("ItemLabel", depositerPanel.DepositerList)
label.remove.onClick = function(widget)
table.remove(config.items, table.find(value))
label:destroy()
end
label:setText("Stash (".. itemId .. ") to depot: (" .. index..")")
depositerPanel.ID:setItemId(0)
depositerPanel.Index:setText(0)
end
end
end
function getStashingIndex(id)
for _, v in pairs(config.items) do
if v.id == id then
return v.index - 1
end
end
end

View File

@ -0,0 +1,86 @@
ItemLabel < 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
DepositerPanel < MainWindow
size: 250 450
!text: tr('Depositer Panel')
@onEscape: self:hide()
TextList
id: DepositerList
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
margin-top: 15
margin-bottom: 5
margin-right: 3
padding: 1
height: 300
vertical-scrollbar: DepositerScrollBar
VerticalScrollBar
id: DepositerScrollBar
anchors.top: DepositerList.top
anchors.bottom: DepositerList.bottom
anchors.right: DepositerList.right
step: 14
pixels-scroll: true
BotItem
id: ID
anchors.top: DepositerList.bottom
margin-top: 3
anchors.left: DepositerList.left
SpinBox
id: Index
anchors.top: DepositerList.bottom
margin-top: 3
anchors.left: prev.right
margin-left: 3
anchors.bottom: prev.bottom
width: 50
minimum: 3
maximum: 17
step: 1
text-align: center
Button
id: Add
anchors.top: DepositerList.bottom
margin-top: 3
anchors.left: prev.right
margin-left: 3
anchors.right: DepositerList.right
anchors.bottom: prev.bottom
!text: tr('Add Item')
HorizontalSeparator
anchors.bottom: CloseButton.top
margin-bottom: 5
anchors.left: parent.left
anchors.right: parent.right
Button
id: CloseButton
anchors.right: parent.right
anchors.bottom: parent.bottom
margin-right: 5
margin-bottom: 5
!text: tr('Close')
font: cipsoftFont
size: 41 25

View File

@ -70,7 +70,7 @@ Rule < UIWidget
ConditionPanel < Panel ConditionPanel < Panel
height: 53 height: 55
NexButton NexButton
id: nex id: nex
@ -115,8 +115,12 @@ ConditionPanel < Panel
ListPanel < FlatPanel ListPanel < FlatPanel
size: 270 300 size: 270 265
padding-left: 10 padding-left: 10
padding-right: 10 padding-right: 10
padding-bottom: 10 padding-bottom: 10
@ -214,8 +218,10 @@ Unequip < Panel
InputPanel < FlatPanel InputPanel < FlatPanel
size: 270 300 size: 270 265
padding-left: 10 padding-left: 10
padding-right: 10 padding-right: 10
padding-bottom: 10 padding-bottom: 10
@ -234,12 +240,12 @@ InputPanel < FlatPanel
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
margin-top: 10 margin-top: 10
height: 80 height: 40
layout: layout:
type: grid type: grid
cell-size: 34 34 cell-size: 34 34
cell-spacing: 2 cell-spacing: 2
num-columns: 7 num-columns: 9
Button Button
id: unequip id: unequip
@ -297,7 +303,7 @@ InputPanel < FlatPanel
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.top: prev.bottom anchors.top: prev.bottom
margin-top: 3 margin-top: 8
HorizontalSeparator HorizontalSeparator
anchors.left: parent.left anchors.left: parent.left
@ -330,7 +336,7 @@ InputPanel < FlatPanel
tooltip: On add above rule will be listed as Profile name - use friendly one! tooltip: On add above rule will be listed as Profile name - use friendly one!
EquipWindow < MainWindow EquipWindow < MainWindow
size: 600 370 size: 600 345
text: Equipment Manager text: Equipment Manager
@onEscape: self:hide() @onEscape: self:hide()

View File

@ -7,7 +7,7 @@ if voc == 1 or voc == 11 then
onCreatureHealthPercentChange(function(creature, healthPercent) onCreatureHealthPercentChange(function(creature, healthPercent)
if m.isOff() then return end if m.isOff() then return end
if healthPercent > 15 then return end if healthPercent > 15 then return end
if CaveBot.isOff() or TargetBot.isOff() 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 modules.game_cooldown.isGroupCooldownIconActive(3) then return end
if creature:getPosition() and getDistanceBetween(pos(),creature:getPosition()) > 1 then return end if creature:getPosition() and getDistanceBetween(pos(),creature:getPosition()) > 1 then return end
if canCast("exeta res") and now - lastCast > 6000 then if canCast("exeta res") and now - lastCast > 6000 then

View File

@ -19,24 +19,13 @@ local rightPanel = extrasWindow.content.right
local leftPanel = extrasWindow.content.left local leftPanel = extrasWindow.content.left
-- objects made by Kondrah - taken from creature editor, minor changes to adapt -- objects made by Kondrah - taken from creature editor, minor changes to adapt
local addCheckBox = function(id, title, defaultValue, dest, tooltip) local addCheckBox = function(id, title, defaultValue, dest)
local widget = UI.createWidget('ExtrasCheckBox', dest) local widget = UI.createWidget('ExtrasCheckBox', dest)
widget.onClick = function() widget.onClick = function()
widget:setOn(not widget:isOn()) widget:setOn(not widget:isOn())
settings[id] = widget:isOn() settings[id] = widget:isOn()
if id == "checkPlayer" then
local label = rootWidget.newHealer.targetSettings.vocations.title
if not widget:isOn() then
label:setColor("#d9321f")
label:setTooltip("! WARNING ! \nTurn on check players in extras to use this feature!")
else
label:setColor("#dfdfdf")
label:setTooltip("")
end
end
end end
widget:setText(title) widget:setText(title)
widget:setTooltip(tooltip)
if settings[id] == nil then if settings[id] == nil then
widget:setOn(defaultValue) widget:setOn(defaultValue)
else else
@ -45,11 +34,9 @@ local addCheckBox = function(id, title, defaultValue, dest, tooltip)
settings[id] = widget:isOn() settings[id] = widget:isOn()
end end
local addItem = function(id, title, defaultItem, dest, tooltip) local addItem = function(id, title, defaultItem, dest)
local widget = UI.createWidget('ExtrasItem', dest) local widget = UI.createWidget('ExtrasItem', dest)
widget.text:setText(title) widget.text:setText(title)
widget.text:setTooltip(tooltip)
widget.item:setTooltip(tooltip)
widget.item:setItemId(settings[id] or defaultItem) widget.item:setItemId(settings[id] or defaultItem)
widget.item.onItemChange = function(widget) widget.item.onItemChange = function(widget)
settings[id] = widget:getItemId() settings[id] = widget:getItemId()
@ -57,20 +44,18 @@ local addItem = function(id, title, defaultItem, dest, tooltip)
settings[id] = settings[id] or defaultItem settings[id] = settings[id] or defaultItem
end end
local addTextEdit = function(id, title, defaultValue, dest, tooltip) local addTextEdit = function(id, title, defaultValue, dest)
local widget = UI.createWidget('ExtrasTextEdit', dest) local widget = UI.createWidget('ExtrasTextEdit', dest)
widget.text:setText(title) widget.text:setText(title)
widget.textEdit:setText(settings[id] or defaultValue or "") widget.textEdit:setText(settings[id] or defaultValue or "")
widget.text:setTooltip(tooltip)
widget.textEdit.onTextChange = function(widget,text) widget.textEdit.onTextChange = function(widget,text)
settings[id] = text settings[id] = text
end end
settings[id] = settings[id] or defaultValue or "" settings[id] = settings[id] or defaultValue or ""
end end
local addScrollBar = function(id, title, min, max, defaultValue, dest, tooltip) local addScrollBar = function(id, title, min, max, defaultValue, dest)
local widget = UI.createWidget('ExtrasScrollBar', dest) local widget = UI.createWidget('ExtrasScrollBar', dest)
widget.text:setTooltip(tooltip)
widget.scroll.onValueChange = function(scroll, value) widget.scroll.onValueChange = function(scroll, value)
widget.text:setText(title .. ": " .. value) widget.text:setText(title .. ": " .. value)
if value == 0 then if value == 0 then
@ -79,7 +64,6 @@ local addScrollBar = function(id, title, min, max, defaultValue, dest, tooltip)
settings[id] = value settings[id] = value
end end
widget.scroll:setRange(min, max) widget.scroll:setRange(min, max)
widget.scroll:setTooltip(tooltip)
if max-min > 1000 then if max-min > 1000 then
widget.scroll:setStep(100) widget.scroll:setStep(100)
elseif max-min > 100 then elseif max-min > 100 then
@ -102,20 +86,20 @@ UI.Separator()
--- add callback (optional) --- add callback (optional)
--- optionals should be addionaly sandboxed (if true then end) --- optionals should be addionaly sandboxed (if true then end)
addItem("rope", "Rope Item", 9596, leftPanel, "This item will be used in various bot related scripts as default rope item.") addItem("rope", "Rope Item", 9596, leftPanel)
addItem("shovel", "Shovel Item", 9596, leftPanel, "This item will be used in various bot related scripts as default shovel item.") addItem("shovel", "Shovel Item", 9596, leftPanel)
addItem("machete", "Machete Item", 9596, leftPanel, "This item will be used in various bot related scripts as default machete item.") addItem("machete", "Machete Item", 9596, leftPanel)
addItem("scythe", "Scythe Item", 9596, leftPanel, "This item will be used in various bot related scripts as default scythe item.") addItem("scythe", "Scythe Item", 9596, leftPanel)
addScrollBar("talkDelay", "Global NPC Talk Delay", 0, 2000, 1000, leftPanel, "Breaks between each talk action in cavebot (time in miliseconds).") addScrollBar("talkDelay", "Global NPC Talk Delay", 0, 2000, 1000, leftPanel)
addScrollBar("looting", "Max Loot Distance", 0, 50, 40, leftPanel, "Every loot corpse futher than set distance (in sqm) will be ignored and forgotten.") addScrollBar("looting", "Max Loot Distance", 0, 50, 40, leftPanel)
addScrollBar("huntRoutes", "Hunting Rounds Limit", 0, 300, 50, leftPanel, "Round limit for supply check, if character already made more rounds than set, on next supply check will return to city.") addScrollBar("huntRoutes", "Hunting Routes Limit", 0, 300, 50, leftPanel)
addScrollBar("killUnder", "Kill monsters below", 0, 100, 1, leftPanel, "Force TargetBot to kill added creatures when they are below set percentage of health - will ignore all other TargetBot settings.") addScrollBar("killUnder", "Kill monsters below", 0, 100, 1, leftPanel)
addScrollBar("gotoMaxDistance", "Max GoTo Distance", 0, 127, 30, leftPanel, "Maximum distance to next goto waypoint for the bot to try to reach.") addScrollBar("gotoMaxDistance", "Max GoTo Distance", 0, 127, 30, leftPanel)
addCheckBox("lootLast", "Start loot from last corpse", true, leftPanel, "Looting sequence will be reverted and bot will start looting newest bodies.") addCheckBox("lootLast", "Start loot from last corpse", true, leftPanel)
addCheckBox("joinBot", "Join TargetBot and CaveBot", false, leftPanel, "Cave and Target tabs will be joined into one.") addCheckBox("joinBot", "Join TargetBot and CaveBot", false, leftPanel)
addCheckBox("reachable", "Target only pathable mobs", false, leftPanel, "Ignore monsters that can't be reached.") addCheckBox("reachable", "Target only pathable mobs", false, leftPanel)
addCheckBox("title", "Custom Window Title", true, rightPanel, "Personalize OTCv8 window name according to character specific.") addCheckBox("title", "Custom Window Title", true, rightPanel)
if true then if true then
local vocText = "" local vocText = ""
@ -142,7 +126,7 @@ if true then
end) end)
end end
addCheckBox("separatePm", "Open PM's in new Window", false, rightPanel, "PM's will be automatically opened in new tab after receiving one.") addCheckBox("separatePm", "Open PM's in new Window", false, rightPanel)
if true then if true then
onTalk(function(name, level, mode, text, channelId, pos) onTalk(function(name, level, mode, text, channelId, pos)
if mode == 4 and settings.separatePm then if mode == 4 and settings.separatePm then
@ -157,7 +141,7 @@ if true then
end) end)
end end
addTextEdit("useAll", "Use All Hotkey", "space", rightPanel, "Set hotkey for universal actions - rope, shovel, scythe, use, open doors") addTextEdit("useAll", "Use All Hotkey", "space", rightPanel)
if true then if true then
local useId = { 34847, 1764, 21051, 30823, 6264, 5282, 20453, 20454, 20474, 11708, 11705, 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, 6257, 6256, 2772, 27260, 2773, 1632, 1633, 1948, 435, 6252, 6253, 5007, 4911,
@ -165,7 +149,7 @@ if true then
31118, 20474, 5737, 5736, 5734, 5733, 31202, 31228, 31199, 31200, 33262, 30824, 31118, 20474, 5737, 5736, 5734, 5733, 31202, 31228, 31199, 31200, 33262, 30824,
5125, 5126, 5116, 5117, 8257, 8258, 8255, 8256, 5120, 30777, 30776, 23873, 23877, 5125, 5126, 5116, 5117, 8257, 8258, 8255, 8256, 5120, 30777, 30776, 23873, 23877,
5736, 6264, 31262, 31130, 31129, 6250, 6249, 5122, 30049, 7131, 7132, 7727 } 5736, 6264, 31262, 31130, 31129, 6250, 6249, 5122, 30049, 7131, 7132, 7727 }
local shovelId = { 606, 593, 867, 608 } local shovelId = { 606, 593, 867 }
local ropeId = { 17238, 12202, 12935, 386, 421, 21966, 14238 } local ropeId = { 17238, 12202, 12935, 386, 421, 21966, 14238 }
local macheteId = { 2130, 3696 } local macheteId = { 2130, 3696 }
local scytheId = { 3653 } local scytheId = { 3653 }
@ -203,7 +187,7 @@ if true then
end end
addCheckBox("timers", "MW & WG Timers", true, rightPanel, "Show times for Magic Walls and Wild Growths.") addCheckBox("timers", "MW & WG Timers", true, rightPanel)
if true then if true then
local activeTimers = {} local activeTimers = {}
@ -242,7 +226,7 @@ if true then
end end
addCheckBox("antiKick", "Anti - Kick", true, rightPanel, "Turn every 10 minutes to prevent kick.") addCheckBox("antiKick", "Anti - Kick", true, rightPanel)
if true then if true then
macro(600*1000, function() macro(600*1000, function()
if not settings.antiKick then return end if not settings.antiKick then return end
@ -253,7 +237,7 @@ if true then
end end
addCheckBox("stake", "Skin Monsters", false, leftPanel, "Automatically skin & stake corpses when cavebot is enabled") addCheckBox("stake", "Skin Monsters", false, leftPanel)
if true then if true then
local knifeBodies = {4286, 4272, 4173, 4011, 4025, 4047, 4052, 4057, 4062, 4112, 4212, 4321, 4324, 4327, 10352, 10356, 10360, 10364} local knifeBodies = {4286, 4272, 4173, 4011, 4025, 4047, 4052, 4057, 4062, 4112, 4212, 4321, 4324, 4327, 10352, 10356, 10360, 10364}
local stakeBodies = {4097, 4137, 8738, 18958} local stakeBodies = {4097, 4137, 8738, 18958}
@ -261,36 +245,35 @@ if true then
macro(500, function() macro(500, function()
if not CaveBot.isOn() or not settings.stake then return end if not CaveBot.isOn() or not settings.stake then return end
for i, tile in ipairs(g_map.getTiles(posz())) do for i, tile in ipairs(g_map.getTiles(posz())) do
local item = tile:getTopThing() for u,item in ipairs(tile:getItems()) do
if item and item:isContainer() then if table.find(knifeBodies, item:getId()) and findItem(5908) then
if table.find(knifeBodies, item:getId()) and findItem(5908) then CaveBot.delay(550)
CaveBot.delay(550) useWith(5908, item)
useWith(5908, item) return
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
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) end)
end end
addCheckBox("oberon", "Auto Reply Oberon", true, rightPanel, "Auto reply to Grand Master Oberon talk minigame.") addCheckBox("oberon", "Auto Reply Oberon", true, rightPanel)
if true then if true then
onTalk(function(name, level, mode, text, channelId, pos) onTalk(function(name, level, mode, text, channelId, pos)
if not settings.oberon then return end if not settings.oberon then return end
if mode == 34 then if mode == 34 then
if string.find(text, "world will suffer for") then if string.find(text, "world will suffer for") then
say("Are you ever going to fight or do you prefer talking?") say("Are you ever going to fight or do you prefer talking!")
elseif string.find(text, "feet when they see me") then elseif string.find(text, "feet when they see me") then
say("Even before they smell your breath?") say("Even before they smell your breath?")
elseif string.find(text, "from this plane") then elseif string.find(text, "from this plane") then
@ -313,8 +296,9 @@ if true then
end end
addCheckBox("autoOpenDoors", "Auto Open Doors", true, rightPanel, "Open doors when trying to step on them.") addCheckBox("autoOpenDoors", "Auto Open Doors", true, rightPanel)
if true then if true then
local wsadWalking = modules.game_walking.wsadWalking
local doorsIds = { 5007, 8265, 1629, 1632, 5129, 6252, 6249, 7715, 7712, 7714, local doorsIds = { 5007, 8265, 1629, 1632, 5129, 6252, 6249, 7715, 7712, 7714,
7719, 6256, 1669, 1672, 5125, 5115, 5124, 17701, 17710, 1642, 7719, 6256, 1669, 1672, 5125, 5115, 5124, 17701, 17710, 1642,
6260, 5107, 4912, 6251, 5291, 1683, 1696, 1692, 5006, 2179, 5116, 6260, 5107, 4912, 6251, 5291, 1683, 1696, 1692, 5006, 2179, 5116,
@ -332,7 +316,6 @@ if true then
end end
onKeyPress(function(keys) onKeyPress(function(keys)
local wsadWalking = modules.game_walking.wsadWalking
if not settings.autoOpenDoors then return end if not settings.autoOpenDoors then return end
local pos = player:getPosition() local pos = player:getPosition()
if keys == 'Up' or (wsadWalking and keys == 'W') then if keys == 'Up' or (wsadWalking and keys == 'W') then
@ -361,7 +344,7 @@ if true then
end end
addCheckBox("bless", "Buy bless at login", true, rightPanel, "Say !bless at login.") addCheckBox("bless", "Buy bless at login", true, rightPanel)
if true then if true then
local blessed = false local blessed = false
onTextMessage(function(mode,text) onTextMessage(function(mode,text)
@ -388,7 +371,7 @@ if true then
end end
addCheckBox("reUse", "Keep Crosshair", false, rightPanel, "Keep crosshair after using with item") addCheckBox("reUse", "Keep Crosshair", false, rightPanel)
if true then if true then
local excluded = {268, 237, 238, 23373, 266, 236, 239, 7643, 23375, 7642, 23374, 5908, 5942} local excluded = {268, 237, 238, 23373, 266, 236, 239, 7643, 23375, 7642, 23374, 5908, 5942}
@ -405,7 +388,7 @@ if true then
end end
addCheckBox("suppliesControl", "TargetBot off if low supply", false, leftPanel, "Turn off TargetBot if either one of supply amount is below 50% of minimum.") addCheckBox("suppliesControl", "TargetBot off if low supply", false, leftPanel)
if true then if true then
macro(500, function() macro(500, function()
if not settings.suppliesControl then return end if not settings.suppliesControl then return end
@ -417,7 +400,7 @@ if true then
end) end)
end end
addCheckBox("holdMwall", "Hold MW/WG", true, rightPanel, "Mark tiles with below hotkeys to automatically use Magic Wall or Wild Growth") addCheckBox("holdMwall", "Hold MW/WG", true, rightPanel)
addTextEdit("holdMwHot", "Magic Wall Hotkey: ", "F5", rightPanel) addTextEdit("holdMwHot", "Magic Wall Hotkey: ", "F5", rightPanel)
addTextEdit("holdWgHot", "Wild Growth Hotkey: ", "F6", rightPanel) addTextEdit("holdWgHot", "Wild Growth Hotkey: ", "F6", rightPanel)
if true then if true then
@ -513,7 +496,7 @@ if true then
end) end)
end end
addCheckBox("checkPlayer", "Check Players", true, rightPanel, "Auto look on players and mark level and vocation on character model") addCheckBox("checkPlayer", "Check Players", true, rightPanel)
if true then if true then
local found local found
local function checkPlayers() local function checkPlayers()
@ -578,9 +561,8 @@ if true then
end) end)
end end
addCheckBox("nextBackpack", "Open Next Loot Container", true, leftPanel, "Auto open next loot container if full - has to have the same ID.") addCheckBox("title", "Open Next Loot Container", true, leftPanel)
local function openNextLootContainer() local function openNextLootContainer()
if not settings.nextBackpack then return end
local containers = getContainers() local containers = getContainers()
local lootCotaniersIds = CaveBot.GetLootContainers() local lootCotaniersIds = CaveBot.GetLootContainers()
@ -609,24 +591,4 @@ if true then
openNextLootContainer() openNextLootContainer()
end) end)
end) end)
end
addCheckBox("highlightTarget", "Highlight Current Target", true, rightPanel, "Additionaly hightlight current target with red glow")
if true then
local function forceMarked(creature)
if target() == creature then
creature:setMarked("red")
return schedule(333, function() forceMarked(creature) end)
end
end
onAttackingCreatureChange(function(newCreature, oldCreature)
if not settings.highlightTarget then return end
if oldCreature then
oldCreature:setMarked('')
end
if newCreature then
forceMarked(newCreature)
end
end)
end end

View File

@ -2,7 +2,7 @@ ExtrasScrollBar < Panel
height: 28 height: 28
margin-top: 3 margin-top: 3
UIWidget Label
id: text id: text
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@ -23,7 +23,7 @@ ExtrasTextEdit < Panel
height: 40 height: 40
margin-top: 7 margin-top: 7
UIWidget Label
id: text id: text
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@ -47,7 +47,7 @@ ExtrasItem < Panel
margin-left: 25 margin-left: 25
margin-right: 25 margin-right: 25
UIWidget Label
id: text id: text
anchors.left: parent.left anchors.left: parent.left
anchors.verticalCenter: next.verticalCenter anchors.verticalCenter: next.verticalCenter

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

@ -1219,49 +1219,6 @@ LootItems = {
["zaoan sword"] = 30000, ["zaoan sword"] = 30000,
["zaogun flag"] = 600, ["zaogun flag"] = 600,
["zaogun shoulderplates"] = 150, ["zaogun shoulderplates"] = 150,
-- 12.70
["carnisylvan bark"] = 230,
["carnisylvan finger"] = 250,
["human teeth"] = 2000,
["abomination's eye"] = 650000,
["abomination's tail"] = 700000,
["abomination's tongue"] = 950000,
["afflicted strider head"] = 900,
["afflicted strider worms"] = 500,
["bashmu fang"] = 600,
["bashmu feather"] = 350,
["bashmu tongue"] = 400,
["blemished spawn abdomen"] = 550,
["blemished spawn head"] = 800,
["blemished spawn tail"] = 1000,
["brainstealer's brain"] = 300000,
["brainstealer's brainwave"] = 440000,
["brainstealer's tissue"] = 240000,
["cave chimera head"] = 1200,
["cave chimera leg"] = 650,
["curl of hair"] = 320000,
["eyeless devourer legs"] = 650,
["eyeless devourer maw"] = 420,
["eyeless devourer tongue"] = 900,
["girtablilu warrior carapace"] = 520,
["lavafungus head"] = 900,
["lavafungus ring"] = 390,
["lavaworm jaws"] = 1100,
["lavaworm spike roots"] = 600,
["lavaworm spikes"] = 750,
["old girtablilu carapace"] = 570,
["old royal diary"] = 220000,
["scorpion charm"] = 620,
["tremendous tyrant head"] = 930,
["tremendous tyrant shell"] = 740,
["varnished diremaw brainpan"] = 750,
["varnished diremaw legs"] = 670,
["streaked devourer eyes"] = 500,
["streaked devourer legs"] = 600,
["streaked devourer maw"] = 400,
["eldritch crystal"] = 48000,
-- supplies -- supplies
["mana potion"] = 56, ["mana potion"] = 56,
["strong mana potion"] = 93, ["strong mana potion"] = 93,

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 v4.1 \n Vithrax#5814")
UI.Button("Official OTCv8 Discord!", function() g_platform.openUrl("https://discord.gg/yhqBE4A") end)
UI.Separator()

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,265 @@
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 = vBot.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
if config.outfits then
specOutfit.head = 88
specOutfit.body = 88
specOutfit.legs = 88
specOutfit.feet = 88
if storage.BOTserver.outfit then
local voc = vBot.BotServerMembers[creature:getName()]
specOutfit.addons = 3
if voc == 1 then
specOutfit.type = 131
elseif voc == 2 then
specOutfit.type = 129
elseif voc == 3 then
specOutfit.type = 130
elseif voc == 4 then
specOutfit.type = 144
end
end
creature:setOutfit(specOutfit)
end
elseif isEnemy(specName) then
if config.highlight then
creature:setMarked('#FF0000')
end
if config.outfits then
specOutfit.head = 94
specOutfit.body = 94
specOutfit.legs = 94
specOutfit.feet = 94
creature:setOutfit(specOutfit)
end
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)

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