diff --git a/data/images/game/console/downarrow.png b/data/images/game/console/downarrow.png new file mode 100644 index 0000000..d3a3aa4 Binary files /dev/null and b/data/images/game/console/downarrow.png differ diff --git a/data/images/game/console/uparrow.png b/data/images/game/console/uparrow.png new file mode 100644 index 0000000..83153ac Binary files /dev/null and b/data/images/game/console/uparrow.png differ diff --git a/data/images/game/topbar/boost.png b/data/images/game/topbar/boost.png new file mode 100644 index 0000000..f7bbc64 Binary files /dev/null and b/data/images/game/topbar/boost.png differ diff --git a/data/images/game/topbar/icons.png b/data/images/game/topbar/icons.png new file mode 100644 index 0000000..cfa2352 Binary files /dev/null and b/data/images/game/topbar/icons.png differ diff --git a/data/images/optionstab/features.png b/data/images/optionstab/features.png new file mode 100644 index 0000000..4cf47fc Binary files /dev/null and b/data/images/optionstab/features.png differ diff --git a/data/images/ui/dark_background.png b/data/images/ui/dark_background.png new file mode 100644 index 0000000..9b8e992 Binary files /dev/null and b/data/images/ui/dark_background.png differ diff --git a/data/images/ui/panel_bottom2.png b/data/images/ui/panel_bottom2.png new file mode 100644 index 0000000..b01e73c Binary files /dev/null and b/data/images/ui/panel_bottom2.png differ diff --git a/data/images/ui/rarity_frames.png b/data/images/ui/rarity_frames.png new file mode 100644 index 0000000..cebc6d9 Binary files /dev/null and b/data/images/ui/rarity_frames.png differ diff --git a/data/minimap.otmm b/data/minimap.otmm new file mode 100644 index 0000000..1dd2be4 Binary files /dev/null and b/data/minimap.otmm differ diff --git a/data/styles/10-progressbars.otui b/data/styles/10-progressbars.otui index 6eac011..94b9b01 100644 --- a/data/styles/10-progressbars.otui +++ b/data/styles/10-progressbars.otui @@ -12,6 +12,9 @@ ProgressBar < UIProgressBar margin-bottom: 0 height: 0 +ThickProgressBar < ProgressBar + image-source: /images/ui/progressbar_thick + LifeProgressBar < UIProgressBar height: 16 background-color: green diff --git a/modules/client/client.otmod b/modules/client/client.otmod index 2824a66..f633b64 100644 --- a/modules/client/client.otmod +++ b/modules/client/client.otmod @@ -20,4 +20,4 @@ Module - client_terminal - client_stats - client_feedback - - client_mobile + - client_mobile \ No newline at end of file diff --git a/modules/client_options/custom.otui b/modules/client_options/custom.otui new file mode 100644 index 0000000..011b83d --- /dev/null +++ b/modules/client_options/custom.otui @@ -0,0 +1,127 @@ +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 \ No newline at end of file diff --git a/modules/client_options/interface.otui b/modules/client_options/interface.otui index f43b51d..be5630e 100644 --- a/modules/client_options/interface.otui +++ b/modules/client_options/interface.otui @@ -36,14 +36,6 @@ OptionPanel $mobile: visible: false - - OptionCheckBox - id: actionBar1 - !text: tr("Show first action bar") - - OptionCheckBox - id: actionBar2 - !text: tr("Show second action bar") OptionCheckBox id: showPing @@ -74,16 +66,6 @@ OptionPanel $mobile: 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 id: highlightThingsUnderCursor !text: tr('Highlight things under cursor') diff --git a/modules/client_options/options.lua b/modules/client_options/options.lua index 3936f21..49be73e 100644 --- a/modules/client_options/options.lua +++ b/modules/client_options/options.lua @@ -49,9 +49,24 @@ local defaultOptions = { walkStairsDelay = 50, walkTeleportDelay = 200, walkCtrlTurnDelay = 150, - - actionBar1 = true, - actionBar2 = false + + topBar = true, + + actionbarBottom1 = true, + actionbarBottom2 = false, + actionbarBottom3 = false, + + actionbarLeft1 = false, + actionbarLeft2 = false, + actionbarLeft3 = false, + + actionbarRight1 = false, + actionbarRight2 = false, + actionbarRight3 = false, + + actionbarLock = true, + + profile = 1 } local optionsWindow @@ -63,7 +78,8 @@ local generalPanel local interfacePanel local consolePanel local graphicsPanel -local soundPanel +local audioPanel +local customPanel local extrasPanel local audioButton @@ -101,6 +117,7 @@ function init() audioPanel = g_ui.loadUI('audio') optionsTabBar:addTab(tr('Audio'), audioPanel, '/images/optionstab/audio') + extrasPanel = g_ui.createWidget('OptionPanel') for _, v in ipairs(g_extras.getAll()) do local extrasButton = g_ui.createWidget('OptionCheckBox') @@ -112,6 +129,9 @@ function init() optionsTabBar:addTab(tr('Extras'), extrasPanel, '/images/optionstab/extras') 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) audioButton = modules.client_topmenu.addLeftButton('audioButton', tr('Audio'), '/images/topbuttons/audio', function() toggleOption('enableAudio') end) if g_app.isMobile() then @@ -356,12 +376,20 @@ function setOption(key, value, force) g_settings.set(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 modules.game_interface.refreshViewMode() - elseif key == 'actionBar1' or key == 'actionBar2' then + elseif key:find("actionbar") then modules.game_actionbar.show() end + + if key == 'topBar' then + modules.game_topbar.show() + end end function getOption(key) diff --git a/modules/client_profiles/profiles.lua b/modules/client_profiles/profiles.lua new file mode 100644 index 0000000..eb38948 --- /dev/null +++ b/modules/client_profiles/profiles.lua @@ -0,0 +1,160 @@ +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 \ No newline at end of file diff --git a/modules/client_profiles/profiles.otmod b/modules/client_profiles/profiles.otmod new file mode 100644 index 0000000..1cc012c --- /dev/null +++ b/modules/client_profiles/profiles.otmod @@ -0,0 +1,11 @@ +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() \ No newline at end of file diff --git a/modules/corelib/ui/uicombobox.lua b/modules/corelib/ui/uicombobox.lua index 08fd9a2..51bbf2a 100644 --- a/modules/corelib/ui/uicombobox.lua +++ b/modules/corelib/ui/uicombobox.lua @@ -181,4 +181,4 @@ end function UIComboBox:canMouseScroll() return self.mouseScroll -end +end \ No newline at end of file diff --git a/modules/game_actionbar/actionbar.lua b/modules/game_actionbar/actionbar.lua index 477df57..783dd6d 100644 --- a/modules/game_actionbar/actionbar.lua +++ b/modules/game_actionbar/actionbar.lua @@ -1,7 +1,12 @@ -actionPanel1 = nil -actionPanel2 = nil +---@diagnostic disable: undefined-global +bottomActionPanel1 = nil +bottomActionPanel2 = nil +bottomActionPanel3 = nil +leftActionPanel1 = nil +leftActionPanel2 = nil +leftActionPanel3 = nil -local actionConfig +local settings = {} local hotkeyAssignWindow local actionButtonsInPanel = 50 @@ -24,13 +29,33 @@ ActionColors = { } function init() - local bottomPanel = modules.game_interface.getActionPanel() - actionPanel1 = g_ui.loadUI('actionbar', bottomPanel) - bottomPanel:moveChildToIndex(actionPanel1, 1) - actionPanel2 = g_ui.loadUI('actionbar', bottomPanel) - bottomPanel:moveChildToIndex(actionPanel2, 1) + local bottomPanel = modules.game_interface.getBottomActionPanel() + local leftPanel = modules.game_interface.getLeftActionPanel() + local rightPanel = modules.game_interface.getRightActionPanel() - actionConfig = g_configs.create("/actionbar.otml") + -- bottom + 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, { onGameStart = online, @@ -53,42 +78,105 @@ function terminate() }) -- remove hotkeys, also saves config - if actionPanel1.tabBar:getChildCount() > 0 and actionPanel2.tabBar:getChildCount() > 0 then - offline() + local panels = { + bottomActionPanel1, + 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 - actionPanel1:destroy() - actionPanel2:destroy() + bottomActionPanel1:destroy() + bottomActionPanel2:destroy() + bottomActionPanel3:destroy() + leftActionPanel1:destroy() + leftActionPanel2:destroy() + leftActionPanel3:destroy() + rightActionPanel1:destroy() + rightActionPanel2:destroy() + rightActionPanel3:destroy() end function show() if not g_game.isOnline() then return end - actionPanel1:setOn(g_settings.getBoolean("actionBar1", false)) - actionPanel2:setOn(g_settings.getBoolean("actionBar2", false)) + bottomActionPanel1:setOn(g_settings.getBoolean("actionbarBottom1", false)) + bottomActionPanel2:setOn(g_settings.getBoolean("actionbarBottom2", 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 function hide() - actionPanel1:setOn(false) - actionPanel2:setOn(false) + bottomActionPanel1:setOn(false) + bottomActionPanel2:setOn(false) + bottomActionPanel3:setOn(false) + leftActionPanel1:setOn(false) + leftActionPanel2:setOn(false) + leftActionPanel3:setOn(false) + rightActionPanel1:setOn(false) + rightActionPanel2:setOn(false) + rightActionPanel3:setOn(false) end function switchMode(newMode) if newMode then - actionPanel1:setImageColor('#ffffff88') - actionPanel2:setImageColor('#ffffff88') + bottomActionPanel1:setImageColor('#ffffff88') + bottomActionPanel2:setImageColor('#ffffff88') + bottomActionPanel3:setImageColor('#ffffff88') + leftActionPanel1:setImageColor('#ffffff88') + leftActionPanel2:setImageColor('#ffffff88') + leftActionPanel3:setImageColor('#ffffff88') + rightActionPanel1:setImageColor('#ffffff88') + rightActionPanel2:setImageColor('#ffffff88') + rightActionPanel3:setImageColor('#ffffff88') else - actionPanel1:setImageColor('white') - actionPanel2:setImageColor('white') + bottomActionPanel1:setImageColor('white') + bottomActionPanel2: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 function online() - setupActionPanel(1, actionPanel1) - setupActionPanel(2, actionPanel2) + load() + setupActionPanel(1, bottomActionPanel1, true) + 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() end -function offline() +function refresh(reloaded) + offline(reloaded) + online() +end + +function offline(reloaded) hide() if hotkeyAssignWindow then hotkeyAssignWindow:destroy() @@ -96,37 +184,35 @@ function offline() end local gameRootPanel = modules.game_interface.getRootPanel() - for index, panel in ipairs({actionPanel1, actionPanel2}) do - local config = {} + for index, panel in ipairs({bottomActionPanel1, bottomActionPanel2, bottomActionPanel3, + leftActionPanel1, leftActionPanel2, leftActionPanel3, + rightActionPanel1, rightActionPanel2, rightActionPanel3}) do + settings[tostring(index)] = {} for i, child in ipairs(panel.tabBar:getChildren()) do - if child.config then - table.insert(config, child.config) + if child.config and child.config.item then + settings[tostring(index)][tostring(i)] = child.config if type(child.config.hotkey) == 'string' and child.config.hotkey:len() > 0 then g_keyboard.unbindKeyPress(child.config.hotkey, child.callback, gameRootPanel) end - else - table.insert(config, {}) end if child.cooldownEvent then removeEvent(child.cooldownEvent) end end - actionConfig:setNode('actions_' .. index, config) panel.tabBar:destroyChildren() end - actionConfig:save() + if not reloaded then + save() + end end -function setupActionPanel(index, panel) - 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 +function setupActionPanel(index, panel, bottom) + local config = settings[tostring(index)] or {} for i=1,actionButtonsInPanel do - local action = g_ui.createWidget('ActionButton', panel.tabBar) - action.config = config[i] or {} + local type = bottom and 'ActionButton' or 'SideActionButton' + local action = g_ui.createWidget(type, panel.tabBar) + action.config = config[tostring(i)] or {} setupAction(action) end @@ -143,7 +229,18 @@ function setupAction(action) action.item:setShowCount(false) action.onMouseRelease = 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 if config then @@ -327,7 +424,9 @@ function actionOnItemChange(widget) end function onSpellCooldown(iconId, duration) - for index, panel in ipairs({actionPanel1, actionPanel2}) do + for index, panel in ipairs({bottomActionPanel1, bottomActionPanel2, bottomActionPanel3, + leftActionPanel1, leftActionPanel2, leftActionPanel3, + rightActionPanel1, rightActionPanel2, rightActionPanel3}) do for i, child in ipairs(panel.tabBar:getChildren()) do if child.spell and child.spell.id == iconId then startCooldown(child, duration) @@ -337,7 +436,9 @@ function onSpellCooldown(iconId, duration) end function onSpellGroupCooldown(groupId, duration) - for index, panel in ipairs({actionPanel1, actionPanel2}) do + for index, panel in ipairs({bottomActionPanel1, bottomActionPanel2, bottomActionPanel3, + leftActionPanel1, leftActionPanel2, leftActionPanel3, + rightActionPanel1, rightActionPanel2, rightActionPanel3}) do for i, child in ipairs(panel.tabBar:getChildren()) do if child.spell and child.spell.group then for group, dur in pairs(child.spell.group) do @@ -483,4 +584,40 @@ function executeAction(action, ticks) end end end -end \ No newline at end of file +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 diff --git a/modules/game_actionbar/actionbar.otui b/modules/game_actionbar/actionbar.otui index b7613d2..43c1ce0 100644 --- a/modules/game_actionbar/actionbar.otui +++ b/modules/game_actionbar/actionbar.otui @@ -5,6 +5,7 @@ ActionButton < Panel width: 40 padding: 1 1 1 1 margin-left: 1 + draggable: true $first: anchors.left: parent.left @@ -101,7 +102,6 @@ Panel margin-top: 1 margin-bottom: 2 - ActionAssignWindow < MainWindow id: assignWindow !text: tr('Button Assign') diff --git a/modules/game_actionbar/sideactionbar.otui b/modules/game_actionbar/sideactionbar.otui new file mode 100644 index 0000000..23cb19e --- /dev/null +++ b/modules/game_actionbar/sideactionbar.otui @@ -0,0 +1,149 @@ +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() \ No newline at end of file diff --git a/modules/game_bot/bot.lua b/modules/game_bot/bot.lua index e7e6791..7b0fea5 100644 --- a/modules/game_bot/bot.lua +++ b/modules/game_bot/bot.lua @@ -190,7 +190,13 @@ function refresh() -- storage 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 local status, result = pcall(function() return json.decode(g_resources.readFileContents(botStorageFile)) @@ -255,7 +261,9 @@ end function online() botButton:show() - scheduleEvent(refresh, 20) + if not modules.client_profiles.ChangedProfile then + scheduleEvent(refresh, 20) + end end function offline() diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/depositer_config.lua b/modules/game_bot/default_configs/vBot_4.0/vBot/depositer_config.lua deleted file mode 100644 index 227e94a..0000000 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/depositer_config.lua +++ /dev/null @@ -1,65 +0,0 @@ -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 \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/depositer_config.otui b/modules/game_bot/default_configs/vBot_4.0/vBot/depositer_config.otui deleted file mode 100644 index f699fb0..0000000 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/depositer_config.otui +++ /dev/null @@ -1,86 +0,0 @@ -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 \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/info.lua b/modules/game_bot/default_configs/vBot_4.0/vBot/info.lua deleted file mode 100644 index 7c3f67d..0000000 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/info.lua +++ /dev/null @@ -1,477 +0,0 @@ -setDefaultTab("Main") --- first, the variables -local launchTime = now -local startExp = exp() -local dmgTable = {} -local healTable = {} -local expTable = {} -local totalDmg = 0 -local totalHeal = 0 -local dmgDistribution = {} -local first = "-" -local second = "-" -local third = "-" - -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) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/items_management.lua b/modules/game_bot/default_configs/vBot_4.0/vBot/items_management.lua deleted file mode 100644 index bddb262..0000000 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/items_management.lua +++ /dev/null @@ -1,78 +0,0 @@ -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() \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/jewellery_equipper.lua b/modules/game_bot/default_configs/vBot_4.0/vBot/jewellery_equipper.lua deleted file mode 100644 index b5857f2..0000000 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/jewellery_equipper.lua +++ /dev/null @@ -1,367 +0,0 @@ -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 \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/main.lua b/modules/game_bot/default_configs/vBot_4.0/vBot/main.lua deleted file mode 100644 index 37925ce..0000000 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/main.lua +++ /dev/null @@ -1,3 +0,0 @@ -UI.Label("vBot v4.1 \n Vithrax#5814") -UI.Button("Official OTCv8 Discord!", function() g_platform.openUrl("https://discord.gg/yhqBE4A") end) -UI.Separator() \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/player_list.otui b/modules/game_bot/default_configs/vBot_4.0/vBot/player_list.otui deleted file mode 100644 index a8a66b3..0000000 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/player_list.otui +++ /dev/null @@ -1,209 +0,0 @@ -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 \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/playerlist.lua b/modules/game_bot/default_configs/vBot_4.0/vBot/playerlist.lua deleted file mode 100644 index b13edb9..0000000 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/playerlist.lua +++ /dev/null @@ -1,265 +0,0 @@ -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) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/supplies.lua b/modules/game_bot/default_configs/vBot_4.0/vBot/supplies.lua deleted file mode 100644 index 712ffbe..0000000 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/supplies.lua +++ /dev/null @@ -1,311 +0,0 @@ -function SuppliesPanel(parent) - local panelName = "supplies" - if not parent then - parent = panel - end - -if not SuppliesConfig[panelName] then - SuppliesConfig[panelName] = { - item1 = 0, - item2 = 0, - item3 = 0, - item4 = 0, - item5 = 0, - item6 = 0, - item7 = 0, - capValue = 0, - capSwitch = false, - SoftBoots = false, - staminaSwitch = false, - staminaValue = 900, - imbues = false, - item1Min = 0, - item1Max = 0, - item2Min = 0, - item2Max = 0, - item3Min = 0, - item3Max = 0, - item4Min = 0, - item4Max = 0, - item5Min = 0, - item5Max = 0, - item6Min = 0, - item6Max = 0, - item7Max = 0, - sortSupplies = false, - potionBp = 0, - runeBp = 0, - ammoBp = 0 - } -end - -local config = SuppliesConfig[panelName] - --- data validation -local setup = config -setup.item1 = setup.item1 or 0 -setup.item2 = setup.item2 or 0 -setup.item3 = setup.item3 or 0 -setup.item4 = setup.item4 or 0 -setup.item5 = setup.item5 or 0 -setup.item6 = setup.item6 or 0 -setup.item1Min = setup.item1Min or 0 -setup.item1Max = setup.item1Max or 0 -setup.item2Min = setup.item2Min or 0 -setup.item2Max = setup.item2Max or 0 -setup.item3Min = setup.item3Min or 0 -setup.item3Max = setup.item3Max or 0 -setup.item4Min = setup.item4Min or 0 -setup.item4Max = setup.item4Max or 0 -setup.item5Min = setup.item5Min or 0 -setup.item5Max = setup.item5Max or 0 -setup.item6Min = setup.item6Min or 0 -setup.item6Max = setup.item6Max or 0 -setup.capValue = setup.capValue or 0 -setup.staminaValue = setup.staminaValue or 0 - -rootWidget = g_ui.getRootWidget() -if rootWidget then - SuppliesWindow = g_ui.createWidget('SuppliesWindow', rootWidget) - SuppliesWindow:hide() - - SuppliesWindow.capSwitch:setOn(config.capSwitch) - SuppliesWindow.capSwitch.onClick = function(widget) - config.capSwitch = not config.capSwitch - widget:setOn(config.capSwitch) - end - - SuppliesWindow.SoftBoots:setOn(config.SoftBoots) - SuppliesWindow.SoftBoots.onClick = function(widget) - config.SoftBoots = not config.SoftBoots - widget:setOn(config.SoftBoots) - end - - SuppliesWindow.imbues:setOn(config.imbues) - SuppliesWindow.imbues.onClick = function(widget) - config.imbues = not config.imbues - widget:setOn(config.imbues) - end - - SuppliesWindow.staminaSwitch:setOn(config.staminaSwitch) - SuppliesWindow.staminaSwitch.onClick = function(widget) - config.staminaSwitch = not config.staminaSwitch - widget:setOn(config.staminaSwitch) - end - - -- bot items - - SuppliesWindow.item1:setItemId(config.item1) - SuppliesWindow.item1.onItemChange = function(widget) - config.item1 = widget:getItemId() - end - - SuppliesWindow.item2:setItemId(config.item2) - SuppliesWindow.item2.onItemChange = function(widget) - config.item2 = widget:getItemId() - end - - SuppliesWindow.item3:setItemId(config.item3) - SuppliesWindow.item3.onItemChange = function(widget) - config.item3 = widget:getItemId() - end - - SuppliesWindow.item4:setItemId(config.item4) - SuppliesWindow.item4.onItemChange = function(widget) - config.item4 = widget:getItemId() - end - - SuppliesWindow.item5:setItemId(config.item5) - SuppliesWindow.item5.onItemChange = function(widget) - config.item5 = widget:getItemId() - end - - SuppliesWindow.item6:setItemId(config.item6) - SuppliesWindow.item6.onItemChange = function(widget) - config.item6 = widget:getItemId() - end - - -- text windows - SuppliesWindow.capValue:setText(config.capValue) - SuppliesWindow.capValue.onTextChange = function(widget, text) - local value = tonumber(SuppliesWindow.capValue:getText()) - if not value then - SuppliesWindow.capValue:setText(0) - config.capValue = 0 - else - text = text:match("0*(%d+)") - config.capValue = text - end -end - - SuppliesWindow.item1Min:setText(config.item1Min) - SuppliesWindow.item1Min.onTextChange = function(widget, text) - local value = tonumber(SuppliesWindow.item1Min:getText()) - if not value then - SuppliesWindow.item1Min:setText(0) - config.item1Min = 0 - else - text = text:match("0*(%d+)") - config.item1Min = text - end -end - - SuppliesWindow.item1Max:setText(config.item1Max) - SuppliesWindow.item1Max.onTextChange = function(widget, text) - local value = tonumber(SuppliesWindow.item1Max:getText()) - if not value then - SuppliesWindow.item1Max:setText(0) - config.item1Max = 0 - else - text = text:match("0*(%d+)") - config.item1Max = text - end -end - - SuppliesWindow.item2Min:setText(config.item2Min) - SuppliesWindow.item2Min.onTextChange = function(widget, text) - local value = tonumber(SuppliesWindow.item2Min:getText()) - if not value then - SuppliesWindow.item2Min:setText(0) - config.item2Min = 0 - else - text = text:match("0*(%d+)") - config.item2Min = text - end -end - - SuppliesWindow.item2Max:setText(config.item2Max) - SuppliesWindow.item2Max.onTextChange = function(widget, text) - local value = tonumber(SuppliesWindow.item2Max:getText()) - if not value then - SuppliesWindow.item2Max:setText(0) - config.item2Max = 0 - else - text = text:match("0*(%d+)") - config.item2Max = text - end -end - - SuppliesWindow.item3Min:setText(config.item3Min) - SuppliesWindow.item3Min.onTextChange = function(widget, text) - local value = tonumber(SuppliesWindow.item3Min:getText()) - if not value then - SuppliesWindow.item3Min:setText(0) - config.item3Min = 0 - else - text = text:match("0*(%d+)") - config.item3Min = text - end -end - - SuppliesWindow.item3Max:setText(config.item3Max) - SuppliesWindow.item3Max.onTextChange = function(widget, text) - local value = tonumber(SuppliesWindow.item3Max:getText()) - if not value then - SuppliesWindow.item3Max:setText(0) - config.item3Max = 0 - else - config.item3Max = text - end -end - - SuppliesWindow.item4Min:setText(config.item4Min) - SuppliesWindow.item4Min.onTextChange = function(widget, text) - local value = tonumber(SuppliesWindow.item4Min:getText()) - if not value then - SuppliesWindow.item4Min:setText(0) - config.item4Min = 0 - else - text = text:match("0*(%d+)") - config.item4Min = text - end -end - -SuppliesWindow.staminaValue:setText(config.staminaValue) -SuppliesWindow.staminaValue.onTextChange = function(widget, text) - local value = tonumber(SuppliesWindow.staminaValue:getText()) - if not value then - SuppliesWindow.staminaValue:setText(0) - config.staminaValue = 0 - else - text = text:match("0*(%d+)") - config.staminaValue = text - end -end - - SuppliesWindow.item4Max:setText(config.item4Max) - SuppliesWindow.item4Max.onTextChange = function(widget, text) - local value = tonumber(SuppliesWindow.item4Max:getText()) - if not value then - SuppliesWindow.item4Max:setText(0) - config.item4Max = 0 - else - text = text:match("0*(%d+)") - config.item4Max = text - end - end - - SuppliesWindow.item5Min:setText(config.item5Min) - SuppliesWindow.item5Min.onTextChange = function(widget, text) - local value = tonumber(SuppliesWindow.item5Min:getText()) - if not value then - SuppliesWindow.item5Min:setText(0) - config.item5Min = 0 - else - text = text:match("0*(%d+)") - config.item5Min = text - end - end - - SuppliesWindow.item5Max:setText(config.item5Max) - SuppliesWindow.item5Max.onTextChange = function(widget, text) - local value = tonumber(SuppliesWindow.item5Max:getText()) - if not value then - SuppliesWindow.item5Max:setText(0) - config.item5Max = 0 - else - text = text:match("0*(%d+)") - config.item5Max = text - end - end - -SuppliesWindow.item6Min:setText(config.item6Min) -SuppliesWindow.item6Min.onTextChange = function(widget, text) - local value = tonumber(SuppliesWindow.item6Min:getText()) - if not value then - SuppliesWindow.item6Min:setText(0) - config.item6Min = 0 - else - text = text:match("0*(%d+)") - config.item6Min = text - end -end - -SuppliesWindow.item6Max:setText(config.item6Max) -SuppliesWindow.item6Max.onTextChange = function(widget, text) - local value = tonumber(SuppliesWindow.item6Max:getText()) - if not value then - SuppliesWindow.item6Max:setText(0) - config.item6Max = 0 - else - text = text:match("0*(%d+)") - config.item6Max = text - end -end - -end - -UI.Button("Supplies", function() - SuppliesWindow:show() - SuppliesWindow:raise() - SuppliesWindow:focus() -end) - -SuppliesWindow.close.onClick = function(widget) - SuppliesWindow:hide() - vBotConfigSave("supply") -end -end - -UI.Separator() -SuppliesPanel(setDefaultTab("Cave")) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/_Loader.lua b/modules/game_bot/default_configs/vBot_4.4/_Loader.lua similarity index 95% rename from modules/game_bot/default_configs/vBot_4.0/_Loader.lua rename to modules/game_bot/default_configs/vBot_4.4/_Loader.lua index 1400580..b13e3c8 100644 --- a/modules/game_bot/default_configs/vBot_4.0/_Loader.lua +++ b/modules/game_bot/default_configs/vBot_4.4/_Loader.lua @@ -31,7 +31,7 @@ local luaFiles = { "pushmax", "combo", "HealBot", - "Sio", + "new healer", "AttackBot", -- last of major modules "ingame_editor", "Dropper", @@ -48,7 +48,9 @@ local luaFiles = { "spy_level", "supplies", "depositer_config", - "npc_talk" + "npc_talk", + "xeno_menu", + "hold_target" } for i, file in ipairs(luaFiles) do diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/actions.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/actions.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/actions.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/actions.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/bank.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/bank.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/bank.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/bank.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/buy_supplies.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/buy_supplies.lua similarity index 98% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/buy_supplies.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/buy_supplies.lua index 15f2c5e..ccac24f 100644 --- a/modules/game_bot/default_configs/vBot_4.0/cavebot/buy_supplies.lua +++ b/modules/game_bot/default_configs/vBot_4.4/cavebot/buy_supplies.lua @@ -3,6 +3,7 @@ CaveBot.Extensions.BuySupplies = {} CaveBot.Extensions.BuySupplies.setup = function() CaveBot.registerAction("BuySupplies", "#C300FF", function(value, retries) local supplies = SuppliesConfig.supplies + supplies = supplies[supplies.currentProfile] local item1Count = itemAmount(supplies.item1) local item2Count = itemAmount(supplies.item2) local item3Count = itemAmount(supplies.item3) diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/cavebot.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/cavebot.lua similarity index 88% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/cavebot.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/cavebot.lua index b7c819c..fde0239 100644 --- a/modules/game_bot/default_configs/vBot_4.0/cavebot/cavebot.lua +++ b/modules/game_bot/default_configs/vBot_4.4/cavebot/cavebot.lua @@ -236,6 +236,60 @@ CaveBot.gotoNextWaypointInRange = function() return false 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) label = "label:"..label label = label:lower() diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/cavebot.otui b/modules/game_bot/default_configs/vBot_4.4/cavebot/cavebot.otui similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/cavebot.otui rename to modules/game_bot/default_configs/vBot_4.4/cavebot/cavebot.otui diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/clear_tile.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/clear_tile.lua similarity index 90% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/clear_tile.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/clear_tile.lua index 983b9d1..d9b95ae 100644 --- a/modules/game_bot/default_configs/vBot_4.0/cavebot/clear_tile.lua +++ b/modules/game_bot/default_configs/vBot_4.4/cavebot/clear_tile.lua @@ -42,7 +42,7 @@ CaveBot.Extensions.ClearTile.setup = function() end if retries > 0 then - delay(1100) + delay(1500) end -- but if not then first check for creatures @@ -55,7 +55,7 @@ CaveBot.Extensions.ClearTile.setup = function() elseif c:isPlayer() then local candidates = {} for _, tile in ipairs(g_map.getTiles(posz())) do - if getDistanceBetween(c:getPosition(), tile:getPosition()) == 1 and tile:getPosition() ~= pPos then + if getDistanceBetween(c:getPosition(), tile:getPosition()) == 1 and tile:getPosition() ~= pPos and tile:isWalkable(false) then table.insert(candidates, tile:getPosition()) end end @@ -65,7 +65,11 @@ CaveBot.Extensions.ClearTile.setup = function() return false else print("CaveBot[ClearTile]: pushing player... " .. c:getName() .. " out of the way") - g_game.move(c, candidates[math.random(1,#candidates)]) + local pos = 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" end end diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/config.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/config.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/config.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/config.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/config.otui b/modules/game_bot/default_configs/vBot_4.4/cavebot/config.otui similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/config.otui rename to modules/game_bot/default_configs/vBot_4.4/cavebot/config.otui diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/d_withdraw.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/d_withdraw.lua similarity index 99% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/d_withdraw.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/d_withdraw.lua index d7ffccd..888ed1b 100644 --- a/modules/game_bot/default_configs/vBot_4.0/cavebot/d_withdraw.lua +++ b/modules/game_bot/default_configs/vBot_4.4/cavebot/d_withdraw.lua @@ -24,6 +24,7 @@ CaveBot.Extensions.DWithdraw.setup = function() capLimit = tonumber(data[4]:trim()) end + -- cap check if freecap() < (capLimit or 200) then for i, container in ipairs(getContainers()) do diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/depositor.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/depositor.lua similarity index 89% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/depositor.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/depositor.lua index 87fc6bd..8f2bb85 100644 --- a/modules/game_bot/default_configs/vBot_4.0/cavebot/depositor.lua +++ b/modules/game_bot/default_configs/vBot_4.4/cavebot/depositor.lua @@ -15,6 +15,17 @@ local function resetCache() g_game.close(container) 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 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" @@ -23,6 +34,7 @@ CaveBot.Extensions.Depositor.setup = function() CaveBot.registerAction("depositor", "#002FFF", function(value, retries) -- version check, TODO old tibia if g_game.getClientVersion() < 960 then + resetCache() warn("CaveBot[Depositor]: unsupported Tibia version, will be added in near future") return false end @@ -120,5 +132,6 @@ CaveBot.Extensions.Depositor.setup = function() value="no", title="Depositor", description=description, + validation="(yes|Yes|YES|no|No|NO)" }) end \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/doors.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/doors.lua similarity index 96% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/doors.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/doors.lua index d9a6502..f53992b 100644 --- a/modules/game_bot/default_configs/vBot_4.0/cavebot/doors.lua +++ b/modules/game_bot/default_configs/vBot_4.4/cavebot/doors.lua @@ -53,5 +53,6 @@ CaveBot.Extensions.OpenDoors.setup = function() title="Door position", description="doors position (x,y,z) and key id (optional)", multiline=false, + validation=[[\d{1,5},\d{1,5},\d{1,2}(?:,\d{1,5}$|$)]] }) end \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/editor.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/editor.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/editor.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/editor.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/editor.otui b/modules/game_bot/default_configs/vBot_4.4/cavebot/editor.otui similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/editor.otui rename to modules/game_bot/default_configs/vBot_4.4/cavebot/editor.otui diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/example_functions.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/example_functions.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/example_functions.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/example_functions.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/extension_template.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/extension_template.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/extension_template.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/extension_template.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/imbuing.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/imbuing.lua similarity index 93% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/imbuing.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/imbuing.lua index 8276c4c..5cd6f7c 100644 --- a/modules/game_bot/default_configs/vBot_4.0/cavebot/imbuing.lua +++ b/modules/game_bot/default_configs/vBot_4.4/cavebot/imbuing.lua @@ -76,9 +76,10 @@ CaveBot.Extensions.Imbuing.setup = function() if not item then -- did try before, still not found so item is unavailable if triedToTakeOff then - warn("CaveBot[Imbuing] item not found! proceeding") - reset() - return false + warn("CaveBot[Imbuing] item not found! skipping: "..currentId) + triedToTakeOff = false + currentIndex = currentIndex + 1 + return "retry" end triedToTakeOff = true g_game.equipItemId(currentId) @@ -99,7 +100,7 @@ CaveBot.Extensions.Imbuing.setup = function() useWith(shrine, item) currentIndex = currentIndex + 1 warn("CaveBot[Imbuing] Using shrine on item: "..currentId) - delay(2000) + delay(4000) return "retry" end) diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/inbox_withdraw.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/inbox_withdraw.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/inbox_withdraw.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/inbox_withdraw.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/lure.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/lure.lua similarity index 93% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/lure.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/lure.lua index f7aa9c5..0cb5c54 100644 --- a/modules/game_bot/default_configs/vBot_4.0/cavebot/lure.lua +++ b/modules/game_bot/default_configs/vBot_4.4/cavebot/lure.lua @@ -24,5 +24,6 @@ CaveBot.Extensions.Lure.setup = function() title="Lure", description="TargetBot: start, stop, toggle", multiline=false, + validation=[[(start|stop|toggle)$]] }) end \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/minimap.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/minimap.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/minimap.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/minimap.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/pos_check.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/pos_check.lua similarity index 70% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/pos_check.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/pos_check.lua index bf18844..361ddb6 100644 --- a/modules/game_bot/default_configs/vBot_4.0/cavebot/pos_check.lua +++ b/modules/game_bot/default_configs/vBot_4.4/cavebot/pos_check.lua @@ -26,16 +26,20 @@ CaveBot.Extensions.PosCheck.setup = function() return true else posCheckRetries = posCheckRetries + 1 - CaveBot.gotoLabel(data[1]) - print("CaveBot[CheckPos]: position not-reached, going back to label: " .. data[1]) - return false + if data[1] == "last" then + CaveBot.gotoFirstPreviousReachableWaypoint() + print("CaveBot[CheckPos]: position not-reached, going back to first reachable waypoint.") + return false + else + CaveBot.gotoLabel(data[1]) + print("CaveBot[CheckPos]: position not-reached, going back to label: " .. data[1]) + return false + end end - - end) CaveBot.Editor.registerAction("poscheck", "pos check", { - value=function() return "label" .. "," .. "10" .. "," .. posx() .. "," .. posy() .. "," .. posz() end, + value=function() return "last" .. "," .. "10" .. "," .. posx() .. "," .. posy() .. "," .. posz() end, title="Location Check", description="label name, accepted dist from coordinates, x, y, z", multiline=false, diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/recorder.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/recorder.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/recorder.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/recorder.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/sell_all.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/sell_all.lua similarity index 96% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/sell_all.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/sell_all.lua index 08ce208..3b79bec 100644 --- a/modules/game_bot/default_configs/vBot_4.0/cavebot/sell_all.lua +++ b/modules/game_bot/default_configs/vBot_4.4/cavebot/sell_all.lua @@ -60,5 +60,6 @@ CaveBot.Extensions.SellAll.setup = function() value="NPC", title="Sell All", description="Insert NPC name, and 'yes' if sell with delay ", + validation=[[^[^,]+(?:, yes$|, Yes$|, YES$|$)]] }) end \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/supply_check.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/supply_check.lua similarity index 82% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/supply_check.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/supply_check.lua index 836ea5a..172db5b 100644 --- a/modules/game_bot/default_configs/vBot_4.0/cavebot/supply_check.lua +++ b/modules/game_bot/default_configs/vBot_4.4/cavebot/supply_check.lua @@ -35,6 +35,7 @@ CaveBot.Extensions.SupplyCheck.setup = function() time = now local supplies = SuppliesConfig.supplies + supplies = supplies[supplies.currentProfile] local softCount = itemAmount(6529) + itemAmount(3549) local totalItem1 = itemAmount(supplies.item1) local totalItem2 = itemAmount(supplies.item2) @@ -42,8 +43,29 @@ CaveBot.Extensions.SupplyCheck.setup = function() local totalItem4 = itemAmount(supplies.item4) local totalItem5 = itemAmount(supplies.item5) local totalItem6 = itemAmount(supplies.item6) - - if supplyRetries > (storage.extras.huntRoutes or 50) then + + if storage.caveBot.forceRefill 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) supplyRetries = 0 missedChecks = 0 @@ -115,5 +137,6 @@ CaveBot.Extensions.SupplyCheck.setup = function() value=function() return "startHunt," .. posx() .. "," .. posy() .. "," .. posz() end, title="Supply check label", description="Insert here hunting start label", + validation=[[[^,]+,\d{1,5},\d{1,5},\d{1,2}$]] }) end \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/tasker.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/tasker.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/tasker.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/tasker.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/travel.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/travel.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/travel.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/travel.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/walking.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/walking.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/walking.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/walking.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/cavebot/withdraw.lua b/modules/game_bot/default_configs/vBot_4.4/cavebot/withdraw.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/cavebot/withdraw.lua rename to modules/game_bot/default_configs/vBot_4.4/cavebot/withdraw.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/targetbot/creature.lua b/modules/game_bot/default_configs/vBot_4.4/targetbot/creature.lua similarity index 98% rename from modules/game_bot/default_configs/vBot_4.0/targetbot/creature.lua rename to modules/game_bot/default_configs/vBot_4.4/targetbot/creature.lua index d4dd545..225bcec 100644 --- a/modules/game_bot/default_configs/vBot_4.0/targetbot/creature.lua +++ b/modules/game_bot/default_configs/vBot_4.4/targetbot/creature.lua @@ -25,7 +25,7 @@ TargetBot.Creature.addConfig = function(config, focus) if config.regex:len() > 0 then config.regex = config.regex .. "|" end - config.regex = config.regex .. "^" .. part:trim():lower():gsub("%*", ".*"):gsub("%?", ".?") .. "$" + config.regex = config.regex .. "^" .. part:trim():lower():gsub("%*", ".*"):gsub("%?", ".?") .. "$" end end diff --git a/modules/game_bot/default_configs/vBot_4.0/targetbot/creature_attack.lua b/modules/game_bot/default_configs/vBot_4.4/targetbot/creature_attack.lua similarity index 95% rename from modules/game_bot/default_configs/vBot_4.0/targetbot/creature_attack.lua rename to modules/game_bot/default_configs/vBot_4.4/targetbot/creature_attack.lua index 8c8186c..4c31644 100644 --- a/modules/game_bot/default_configs/vBot_4.0/targetbot/creature_attack.lua +++ b/modules/game_bot/default_configs/vBot_4.4/targetbot/creature_attack.lua @@ -145,8 +145,10 @@ TargetBot.Creature.walk = function(creature, config, targets) delayFrom = config.delayFrom -- 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 - local monsters = 0 if targetBotLure then anchorPosition = nil return TargetBot.allowCaveBot(150) @@ -165,11 +167,10 @@ TargetBot.Creature.walk = function(creature, config, targets) end end - local lastRePosition = now - if not config.chase and not config.keepDistance and config.rePosition and (creature:getHealthPercent() >= storage.extras.killUnder) then + local currentDistance = findPath(pos, cpos, 10, {ignoreCreatures=true, ignoreNonPathable=true, ignoreCost=true}) + 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 return rePosition(config.rePositionAmount or 6) 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 #currentDistance > 1 then return TargetBot.walkTo(cpos, 10, {ignoreNonPathable=true, precision=1}) @@ -237,7 +238,8 @@ onPlayerPositionChange(function(newPos, oldPos) if TargetBot.isOff() then return end if not lureMax then return end if storage.TargetBotDelayWhenPlayer then return end + if not dynamicLureDelay then return end - if dynamicLureDelay and targetCount < (delayFrom or lureMax/2) or not target() then return end + if targetCount < (delayFrom or lureMax/2) or not target() then return end CaveBot.delay(delayValue or 0) end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/targetbot/creature_editor.lua b/modules/game_bot/default_configs/vBot_4.4/targetbot/creature_editor.lua similarity index 97% rename from modules/game_bot/default_configs/vBot_4.0/targetbot/creature_editor.lua rename to modules/game_bot/default_configs/vBot_4.4/targetbot/creature_editor.lua index 068b46c..cc4c289 100644 --- a/modules/game_bot/default_configs/vBot_4.0/targetbot/creature_editor.lua +++ b/modules/game_bot/default_configs/vBot_4.4/targetbot/creature_editor.lua @@ -87,6 +87,7 @@ TargetBot.Creature.edit = function(config, callback) -- callback = function(newC addScrollBar("lureDelay", "Dynamic lure delay", 100, 1000, 250) addScrollBar("delayFrom", "Start delay when monsters", 1, 29, 2) addScrollBar("rePositionAmount", "Min tiles to rePosition", 0, 7, 5) + addScrollBar("closeLureAmount", "Close Pull Until", 0, 8, 3) addCheckBox("chase", "Chase", true) addCheckBox("keepDistance", "Keep Distance", false) @@ -100,4 +101,5 @@ TargetBot.Creature.edit = function(config, callback) -- callback = function(newC addCheckBox("dynamicLureDelay", "Dynamic lure delay", false) addCheckBox("diamondArrows", "D-Arrows priority", false) addCheckBox("rePosition", "rePosition to better tile", false) + addCheckBox("closeLure", "Close Pulling Monsters", false) end diff --git a/modules/game_bot/default_configs/vBot_4.0/targetbot/creature_editor.otui b/modules/game_bot/default_configs/vBot_4.4/targetbot/creature_editor.otui similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/targetbot/creature_editor.otui rename to modules/game_bot/default_configs/vBot_4.4/targetbot/creature_editor.otui diff --git a/modules/game_bot/default_configs/vBot_4.0/targetbot/creature_priority.lua b/modules/game_bot/default_configs/vBot_4.4/targetbot/creature_priority.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/targetbot/creature_priority.lua rename to modules/game_bot/default_configs/vBot_4.4/targetbot/creature_priority.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/targetbot/looting.lua b/modules/game_bot/default_configs/vBot_4.4/targetbot/looting.lua similarity index 98% rename from modules/game_bot/default_configs/vBot_4.0/targetbot/looting.lua rename to modules/game_bot/default_configs/vBot_4.4/targetbot/looting.lua index 168590d..f93a266 100644 --- a/modules/game_bot/default_configs/vBot_4.0/targetbot/looting.lua +++ b/modules/game_bot/default_configs/vBot_4.4/targetbot/looting.lua @@ -313,6 +313,13 @@ onCreatureDisappear(function(creature) 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 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') end) end) diff --git a/modules/game_bot/default_configs/vBot_4.0/targetbot/looting.otui b/modules/game_bot/default_configs/vBot_4.4/targetbot/looting.otui similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/targetbot/looting.otui rename to modules/game_bot/default_configs/vBot_4.4/targetbot/looting.otui diff --git a/modules/game_bot/default_configs/vBot_4.0/targetbot/target.lua b/modules/game_bot/default_configs/vBot_4.4/targetbot/target.lua similarity index 99% rename from modules/game_bot/default_configs/vBot_4.0/targetbot/target.lua rename to modules/game_bot/default_configs/vBot_4.4/targetbot/target.lua index 195b5a3..8bfb499 100644 --- a/modules/game_bot/default_configs/vBot_4.0/targetbot/target.lua +++ b/modules/game_bot/default_configs/vBot_4.4/targetbot/target.lua @@ -181,6 +181,10 @@ TargetBot.setStatus = function(text) return ui.status.right:setText(text) end +TargetBot.getStatus = function() + return ui.status.right:getText() +end + TargetBot.isOn = function() return config.isOn() end diff --git a/modules/game_bot/default_configs/vBot_4.0/targetbot/target.otui b/modules/game_bot/default_configs/vBot_4.4/targetbot/target.otui similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/targetbot/target.otui rename to modules/game_bot/default_configs/vBot_4.4/targetbot/target.otui diff --git a/modules/game_bot/default_configs/vBot_4.0/targetbot/walking.lua b/modules/game_bot/default_configs/vBot_4.4/targetbot/walking.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/targetbot/walking.lua rename to modules/game_bot/default_configs/vBot_4.4/targetbot/walking.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/AttackBot.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/AttackBot.lua similarity index 86% rename from modules/game_bot/default_configs/vBot_4.0/vBot/AttackBot.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/AttackBot.lua index 1ff0cb9..755ed1c 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/AttackBot.lua +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/AttackBot.lua @@ -7,6 +7,7 @@ local showItem = false local category = 1 local patternCategory = 1 local pattern = 1 +local mainWindow -- label library @@ -614,32 +615,40 @@ ui.title.onClick = function(widget) end ui.settings.onClick = function(widget) - windowUI:show() - windowUI:raise() - windowUI:focus() + mainWindow:show() + mainWindow:raise() + mainWindow:focus() end -rootWidget = g_ui.getRootWidget() -if rootWidget then - windowUI = UI.createWindow("AttackBotWindow", rootWidget) - windowUI:hide() + mainWindow = UI.createWindow("AttackBotWindow") + mainWindow:hide() - local panel = windowUI.mainPanel - local settingsUI = windowUI.settingsPanel + local panel = mainWindow.mainPanel + local settingsUI = mainWindow.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 -- functions function toggleSettings() panel:setVisible(not showSettings) - windowUI.shooterLabel:setVisible(not showSettings) + mainWindow.shooterLabel:setVisible(not showSettings) settingsUI:setVisible(showSettings) - windowUI.settingsLabel:setVisible(showSettings) - windowUI.settings:setText(showSettings and "Back" or "Settings") + mainWindow.settingsLabel:setVisible(showSettings) + mainWindow.settings:setText(showSettings and "Back" or "Settings") end toggleSettings() - windowUI.settings.onClick = function() + mainWindow.settings.onClick = function() showSettings = not showSettings toggleSettings() end @@ -717,62 +726,72 @@ if rootWidget then -- eo in/de/crementation ------- [[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 function refreshAttacks() if not currentSettings.attackTable then return end - for i, child in pairs(panel.entryList:getChildren()) do child:destroy() end + panel.entryList:destroyChildren() for i, entry in pairs(currentSettings.attackTable) do local label = UI.createWidget("AttackEntry", panel.entryList) - label:setText(entry.description) - 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 + label.params = entry + setupWidget(label) end end refreshAttacks() @@ -810,7 +829,7 @@ if rootWidget then local countDescription = orMore and count.."+" or count - local entry = { + local params = { creatures = creatures, monsters = monsters, mana = mana, @@ -829,32 +848,36 @@ if rootWidget then description = '['..type..'] '..countDescription.. ' '..specificMonsters..': '..attackType..', '..categoryName..' ('..minHp..'%-'..maxHp..'%)' } - -- inserting to table - table.insert(currentSettings.attackTable, entry) - refreshAttacks() + local label = UI.createWidget("AttackEntry", panel.entryList) + label.params = params + setupWidget(label) resetFields() end -- moving values -- up panel.up.onClick = function(widget) - local n = panel.entryList:getChildIndex(panel.entryList:getFocusedChild()) - local t = currentSettings.attackTable + local focused = panel.entryList:getFocusedChild() + local n = panel.entryList:getChildIndex(focused) - t[n], t[n-1] = t[n-1], t[n] - panel.up:setEnabled(false) - panel.down:setEnabled(false) - refreshAttacks() + if n-1 == 1 then + widget:setEnabled(false) + end + panel.down:setEnabled(true) + panel.entryList:moveChildToIndex(focused, n-1) + panel.entryList:ensureChildVisible(focused) end -- down panel.down.onClick = function(widget) - local n = panel.entryList:getChildIndex(panel.entryList:getFocusedChild()) - local t = currentSettings.attackTable + local focused = panel.entryList:getFocusedChild() + local n = panel.entryList:getChildIndex(focused) - t[n], t[n+1] = t[n+1], t[n] - panel.up:setEnabled(false) - panel.down:setEnabled(false) - refreshAttacks() + if n + 1 == panel.entryList:getChildCount() then + widget:setEnabled(false) + end + panel.up:setEnabled(true) + panel.entryList:moveChildToIndex(focused, n+1) + panel.entryList:ensureChildVisible(focused) end -- [[settings panel]] -- @@ -907,12 +930,11 @@ if rootWidget then -- window elements - windowUI.closeButton.onClick = function() + mainWindow.closeButton.onClick = function() showSettings = false toggleSettings() resetFields() - windowUI:hide() - vBotConfigSave("atk") + mainWindow:hide() end -- core functions @@ -1020,7 +1042,13 @@ if rootWidget then profileChange() end end -end + + AttackBot.show = function() + mainWindow:show() + mainWindow:raise() + mainWindow:focus() + end + -- otui covered, now support functions function getPattern(category, pattern, safe) @@ -1162,10 +1190,11 @@ macro(100, function() } ]] - for i, entry in pairs(currentSettings.attackTable) do + for i, child in ipairs(panel.entryList:getChildren()) do + local entry = child.params local attackData = entry.itemId > 100 and entry.itemId or entry.spell if entry.enabled and manapercent() >= entry.mana then - if (entry.spell and canCast(entry.spell, not currentSettings.ignoreMana, not currentSettings.Cooldown)) or (entry.itemId > 100 and (not currentSettings.Visible or findItem(entry.itemId))) then + 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 -- first PVP scenario if currentSettings.pvpMode and target():getHealthPercent() >= entry.minHp and target():getHealthPercent() <= entry.maxHp and target():canShoot() then if entry.category == 2 then @@ -1193,7 +1222,9 @@ macro(100, function() local safe = currentSettings.PvpSafe and spellPatterns[pCat][entry.pattern][2] or false local monsterAmount = pCat ~= 8 and getMonstersInArea(entry.category, anchorParam, spellPatterns[pCat][entry.pattern][1], entry.minHp, entry.maxHp, safe, entry.monsters) if (pattern ~= 8 and (entry.orMore and monsterAmount >= entry.count or not entry.orMore and monsterAmount == entry.count)) or (pattern == 8 and bestSide >= entry.count and (not currentSettings.PvpSafe or getPlayers(2) == 0)) then - return executeAttackBotAction(entry.category, attackData, entry.cooldown) + 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) + end end elseif entry.category == 2 then local pCat = entry.patternCategory @@ -1206,7 +1237,9 @@ macro(100, function() pos = data.pos end if monsterAmount and (entry.orMore and monsterAmount >= entry.count or not entry.orMore and monsterAmount == entry.count) then - return useWith(attackData, g_map.getTile(pos):getTopUseThing()) + 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()) + end end end end diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/AttackBot.otui b/modules/game_bot/default_configs/vBot_4.4/vBot/AttackBot.otui similarity index 96% rename from modules/game_bot/default_configs/vBot_4.0/vBot/AttackBot.otui rename to modules/game_bot/default_configs/vBot_4.4/vBot/AttackBot.otui index 4d3cce2..f6329f4 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/AttackBot.otui +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/AttackBot.otui @@ -1,6 +1,6 @@ AttackEntry < UIWidget background-color: alpha - text-offset: 18 1 + text-offset: 35 1 focusable: true height: 16 font: verdana-11px-rounded @@ -15,6 +15,22 @@ AttackEntry < UIWidget margin-top: 2 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: background-color: #00000055 @@ -537,6 +553,7 @@ AttackBotWindow < MainWindow size: 535 300 padding: 15 text: AttackBot v2 + @onEscape: self:hide() Label id: mainLabel diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/BotServer.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/BotServer.lua similarity index 99% rename from modules/game_bot/default_configs/vBot_4.0/vBot/BotServer.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/BotServer.lua index 59edc3e..1be5171 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/BotServer.lua +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/BotServer.lua @@ -4,7 +4,6 @@ local panelName = "BOTserver" local ui = setupUI([[ Panel height: 18 - Button id: botServer anchors.left: parent.left @@ -28,6 +27,7 @@ end local config = storage[panelName] if not storage.BotServerChannel then + math.randomseed(os.time()) storage.BotServerChannel = tostring(math.random(1000000000000,9999999999999)) end diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/BotServer.otui b/modules/game_bot/default_configs/vBot_4.4/vBot/BotServer.otui similarity index 99% rename from modules/game_bot/default_configs/vBot_4.0/vBot/BotServer.otui rename to modules/game_bot/default_configs/vBot_4.4/vBot/BotServer.otui index 18c47a3..ff6874b 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/BotServer.otui +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/BotServer.otui @@ -185,4 +185,4 @@ BotServerWindow < MainWindow anchors.bottom: parent.bottom size: 45 21 margin-top: 15 - margin-right: 5 \ No newline at end of file + margin-right: 5 \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/Conditions.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/Conditions.lua similarity index 96% rename from modules/game_bot/default_configs/vBot_4.0/vBot/Conditions.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/Conditions.lua index 3e6ba62..fa3c76d 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/Conditions.lua +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/Conditions.lua @@ -76,6 +76,13 @@ Panel if rootWidget then conditionsWindow = UI.createWindow('ConditionsWindow', rootWidget) conditionsWindow:hide() + + + conditionsWindow.onVisibilityChange = function(widget, visible) + if not visible then + vBotConfigSave("heal") + end + end -- text edits conditionsWindow.Cure.PoisonCost:setText(config.poisonCost) @@ -220,7 +227,13 @@ Panel -- buttons conditionsWindow.closeButton.onClick = function(widget) conditionsWindow:hide() - vBotConfigSave("heal") + end + + Conditions = {} + Conditions.show = function() + conditionsWindow:show() + conditionsWindow:raise() + conditionsWindow:focus() end end diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/Conditions.otui b/modules/game_bot/default_configs/vBot_4.4/vBot/Conditions.otui similarity index 86% rename from modules/game_bot/default_configs/vBot_4.0/vBot/Conditions.otui rename to modules/game_bot/default_configs/vBot_4.4/vBot/Conditions.otui index 38762e2..ee8d43b 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/Conditions.otui +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/Conditions.otui @@ -20,6 +20,7 @@ CureConditions < Panel margin-left: 5 text: Poison color: #ffaa00 + font: verdana-11px-rounded Label id: label11 @@ -27,6 +28,7 @@ CureConditions < Panel anchors.left: prev.right margin-left: 40 text: Mana: + font: verdana-11px-rounded TextEdit id: PoisonCost @@ -34,6 +36,7 @@ CureConditions < Panel anchors.left: prev.right margin-left: 3 width: 40 + font: verdana-11px-rounded CheckBox id: CurePoison @@ -48,6 +51,7 @@ CureConditions < Panel margin-top: 10 text: Curse color: #ffaa00 + font: verdana-11px-rounded Label id: label22 @@ -55,6 +59,7 @@ CureConditions < Panel anchors.left: prev.right margin-left: 44 text: Mana: + font: verdana-11px-rounded TextEdit id: CurseCost @@ -62,6 +67,7 @@ CureConditions < Panel anchors.left: prev.right margin-left: 3 width: 40 + font: verdana-11px-rounded CheckBox id: CureCurse @@ -76,6 +82,7 @@ CureConditions < Panel margin-top: 10 text: Bleed color: #ffaa00 + font: verdana-11px-rounded Label id: label33 @@ -83,6 +90,7 @@ CureConditions < Panel anchors.left: prev.right margin-left: 46 text: Mana: + font: verdana-11px-rounded TextEdit id: BleedCost @@ -90,6 +98,7 @@ CureConditions < Panel anchors.left: prev.right margin-left: 3 width: 40 + font: verdana-11px-rounded CheckBox id: CureBleed @@ -104,6 +113,7 @@ CureConditions < Panel margin-top: 10 text: Burn color: #ffaa00 + font: verdana-11px-rounded Label id: label44 @@ -111,6 +121,7 @@ CureConditions < Panel anchors.left: prev.right margin-left: 50 text: Mana: + font: verdana-11px-rounded TextEdit id: BurnCost @@ -118,6 +129,7 @@ CureConditions < Panel anchors.left: prev.right margin-left: 3 width: 40 + font: verdana-11px-rounded CheckBox id: CureBurn @@ -132,6 +144,7 @@ CureConditions < Panel margin-top: 10 text: Electify color: #ffaa00 + font: verdana-11px-rounded Label id: label55 @@ -139,6 +152,7 @@ CureConditions < Panel anchors.left: prev.right margin-left: 33 text: Mana: + font: verdana-11px-rounded TextEdit id: ElectrifyCost @@ -146,6 +160,7 @@ CureConditions < Panel anchors.left: prev.right margin-left: 3 width: 40 + font: verdana-11px-rounded CheckBox id: CureElectrify @@ -159,7 +174,8 @@ CureConditions < Panel anchors.top: label5.bottom margin-top: 10 text: Paralyse - color: #ffaa00 + color: #ffaa00 + font: verdana-11px-rounded Label id: label66 @@ -167,6 +183,7 @@ CureConditions < Panel anchors.left: prev.right margin-left: 26 text: Mana: + font: verdana-11px-rounded TextEdit id: ParalyseCost @@ -174,6 +191,7 @@ CureConditions < Panel anchors.left: prev.right margin-left: 3 width: 40 + font: verdana-11px-rounded CheckBox id: CureParalyse @@ -188,6 +206,7 @@ CureConditions < Panel margin-top: 10 margin-left: 12 text: Spell: + font: verdana-11px-rounded TextEdit id: ParalyseSpell @@ -195,6 +214,7 @@ CureConditions < Panel anchors.left: prev.right margin-left: 10 width: 100 + font: verdana-11px-rounded HoldConditions < Panel id: Hold @@ -210,7 +230,8 @@ HoldConditions < Panel margin-top: 10 margin-left: 5 text: Haste - color: #ffaa00 + color: #ffaa00 + font: verdana-11px-rounded Label id: label11 @@ -218,6 +239,7 @@ HoldConditions < Panel anchors.left: prev.right margin-left: 44 text: Mana: + font: verdana-11px-rounded TextEdit id: HasteCost @@ -225,6 +247,7 @@ HoldConditions < Panel anchors.left: prev.right margin-left: 3 width: 40 + font: verdana-11px-rounded CheckBox id: HoldHaste @@ -239,6 +262,7 @@ HoldConditions < Panel margin-top: 10 margin-left: 12 text: Spell: + font: verdana-11px-rounded TextEdit id: HasteSpell @@ -246,6 +270,7 @@ HoldConditions < Panel anchors.left: prev.right margin-left: 10 width: 100 + font: verdana-11px-rounded Label id: label3 @@ -254,6 +279,7 @@ HoldConditions < Panel margin-top: 10 text: Utana Vid color: #ffaa00 + font: verdana-11px-rounded Label id: label33 @@ -261,6 +287,7 @@ HoldConditions < Panel anchors.left: prev.right margin-left: 21 text: Mana: + font: verdana-11px-rounded TextEdit id: UtanaCost @@ -268,6 +295,7 @@ HoldConditions < Panel anchors.left: prev.right margin-left: 3 width: 40 + font: verdana-11px-rounded CheckBox id: HoldUtana @@ -282,6 +310,7 @@ HoldConditions < Panel margin-top: 10 text: Utamo Vita color: #ffaa00 + font: verdana-11px-rounded Label id: label44 @@ -289,6 +318,7 @@ HoldConditions < Panel anchors.left: prev.right margin-left: 12 text: Mana: + font: verdana-11px-rounded TextEdit id: UtamoCost @@ -296,6 +326,7 @@ HoldConditions < Panel anchors.left: prev.right margin-left: 3 width: 40 + font: verdana-11px-rounded CheckBox id: HoldUtamo @@ -309,7 +340,8 @@ HoldConditions < Panel anchors.top: label4.bottom margin-top: 10 text: Recovery - color: #ffaa00 + color: #ffaa00 + font: verdana-11px-rounded Label id: label55 @@ -317,6 +349,7 @@ HoldConditions < Panel anchors.left: prev.right margin-left: 20 text: Mana: + font: verdana-11px-rounded TextEdit id: UturaCost @@ -324,6 +357,7 @@ HoldConditions < Panel anchors.left: prev.right margin-left: 3 width: 40 + font: verdana-11px-rounded CheckBox id: HoldUtura @@ -338,6 +372,7 @@ HoldConditions < Panel margin-top: 10 margin-left: 12 text: Spell: + font: verdana-11px-rounded UturaComboBox id: UturaType @@ -345,6 +380,7 @@ HoldConditions < Panel anchors.left: prev.right margin-left: 10 width: 100 + font: verdana-11px-rounded CheckBox id: IgnoreInPz @@ -377,6 +413,7 @@ HoldConditions < Panel ConditionsWindow < MainWindow !text: tr('Condition Manager') size: 445 280 + @onEscape: self:hide() CureConditions id: Cure @@ -391,6 +428,7 @@ ConditionsWindow < MainWindow text: Cure Conditions color: #88e3dd margin-left: 10 + font: verdana-11px-rounded HoldConditions id: Hold @@ -404,7 +442,8 @@ ConditionsWindow < MainWindow anchors.right: parent.right text: Hold Conditions color: #88e3dd - margin-right: 100 + margin-right: 100 + font: verdana-11px-rounded HorizontalSeparator id: separator diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/Containers.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/Containers.lua similarity index 77% rename from modules/game_bot/default_configs/vBot_4.0/vBot/Containers.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/Containers.lua index c087b76..ca0f9ce 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/Containers.lua +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/Containers.lua @@ -3,6 +3,7 @@ local panelName = "renameContainers" if type(storage[panelName]) ~= "table" then storage[panelName] = { enabled = false; + height = 170, purse = true; list = { { @@ -75,9 +76,10 @@ renameContui:setId(panelName) g_ui.loadUIFromString([[ BackpackName < Label background-color: alpha - text-offset: 18 0 + text-offset: 18 2 focusable: true - height: 16 + height: 17 + font: verdana-11px-rounded CheckBox id: enabled @@ -85,7 +87,7 @@ BackpackName < Label anchors.verticalCenter: parent.verticalCenter width: 15 height: 15 - margin-top: 2 + margin-top: 1 margin-left: 3 $focus: @@ -95,31 +97,44 @@ BackpackName < Label id: state !text: tr('M') anchors.right: remove.left - margin-right: 5 + anchors.verticalCenter: parent.verticalCenter + margin-right: 1 width: 15 height: 15 Button id: remove - !text: tr('x') + !text: tr('X') !tooltip: tr('Remove') anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter margin-right: 15 width: 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 !text: tr('Container Names') - size: 445 170 + size: 465 170 @onEscape: self:hide() TextList id: itemList anchors.left: parent.left anchors.top: parent.top - size: 180 83 + anchors.bottom: separator.top + width: 200 + margin-bottom: 6 margin-top: 3 - margin-bottom: 3 margin-left: 3 vertical-scrollbar: itemListScrollBar @@ -148,12 +163,14 @@ ContListsWindow < MainWindow text: Name: margin-left: 10 margin-top: 3 + font: verdana-11px-rounded TextEdit id: contName anchors.left: lblName.right anchors.top: sep.top anchors.right: parent.right + font: verdana-11px-rounded Label id: lblCont @@ -161,6 +178,7 @@ ContListsWindow < MainWindow anchors.verticalCenter: contId.verticalCenter width: 70 text: Container: + font: verdana-11px-rounded BotItem id: contId @@ -173,14 +191,16 @@ ContListsWindow < MainWindow anchors.left: prev.left anchors.right: parent.right anchors.top: prev.bottom + anchors.bottom: separator.top + margin-bottom: 6 margin-top: 3 - height: 32 Label anchors.left: lblCont.left - anchors.verticalCenter: prev.verticalCenter + anchors.verticalCenter: sortList.verticalCenter width: 70 text: Items: + font: verdana-11px-rounded Button id: addItem @@ -208,6 +228,7 @@ ContListsWindow < MainWindow height: 15 margin-top: 2 margin-left: 3 + font: verdana-11px-rounded CheckBox id: sort @@ -219,6 +240,7 @@ ContListsWindow < MainWindow height: 15 margin-top: 2 margin-left: 15 + font: verdana-11px-rounded CheckBox id: forceOpen @@ -230,6 +252,19 @@ ContListsWindow < MainWindow height: 15 margin-top: 2 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 id: closeButton @@ -239,6 +274,16 @@ ContListsWindow < MainWindow anchors.bottom: parent.bottom size: 45 21 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) @@ -308,7 +353,6 @@ function reopenBackpacks() end end) - end rootWidget = g_ui.getRootWidget() @@ -316,6 +360,14 @@ if rootWidget then contListWindow = UI.createWindow('ContListsWindow', rootWidget) 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) contListWindow:show() contListWindow:raise() @@ -352,7 +404,13 @@ if rootWidget then config.forceOpen = not config.forceOpen contListWindow.forceOpen:setChecked(config.forceOpen) 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) t = t or {} @@ -398,13 +456,18 @@ if rootWidget then label.state:setColor(entry.min and '#00FF00' or '#FF0000') label.state:setTooltip(entry.min and 'Open Minimised' or 'Do not minimise') 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.enabled:setChecked(entry.enabled) label.enabled:setTooltip(entry.enabled and 'Disable' or 'Enable') label.enabled:setImageColor(entry.enabled 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.openNext:setColor(entry.openNext and '#00FF00' or '#FF0000') if tFocus and entry.item == tFocus then tFocus = label @@ -440,26 +503,56 @@ if rootWidget then end onContainerOpen(function(container, previousContainer) - if renameContui.title:isOn() then - if not container.window then return end - local containerWindow = container.window - if not previousContainer then - containerWindow:setContentHeight(34) - end - local storageVal = config.list - if storageVal and #storageVal > 0 then - for _, entry in pairs(storageVal) do - if entry.enabled and string.find(container:getContainerItem():getId(), entry.item) then - if entry.min then - containerWindow:minimize() - end + if not container.window then return end + local containerWindow = container.window + if not previousContainer then + containerWindow:setContentHeight(34) + end + + local storageVal = config.list + if storageVal and #storageVal > 0 then + for _, entry in pairs(storageVal) do + if entry.enabled and string.find(container:getContainerItem():getId(), entry.item) then + if entry.min then + containerWindow:minimize() + end + 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 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) return g_game.move(item, destination:getSlotPosition(destination:getItemsCount()), item:getCount()) end @@ -522,5 +615,12 @@ macro(500, function() if config.purse and config.forceOpen and not getContainerByItem(23396) then return use(getPurse()) 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) end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/Dropper.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/Dropper.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/Dropper.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/Dropper.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/Equipper.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/Equipper.lua similarity index 90% rename from modules/game_bot/default_configs/vBot_4.0/vBot/Equipper.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/Equipper.lua index 65c7a13..c5eb1ee 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/Equipper.lua +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/Equipper.lua @@ -50,7 +50,8 @@ local conditions = { -- always add new conditions at the bottom "Player is paralyzed", -- nothing 10 "Player is in protection zone", -- nothing 11 "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 @@ -225,25 +226,33 @@ inputPanel.optionalCondition.pre.onClick = function() setCondition(false, optionalConditionNumber) end -listPanel.up.onClick = function() - local n = listPanel.list:getChildIndex(listPanel.list:getFocusedChild()) +listPanel.up.onClick = function(widget) + local focused = listPanel.list:getFocusedChild() + local n = listPanel.list:getChildIndex(focused) local t = config.rules t[n], t[n-1] = t[n-1], t[n] - listPanel.up:setEnabled(false) - listPanel.down:setEnabled(false) - refreshRules() + if n-1 == 1 then + widget:setEnabled(false) + end + listPanel.down:setEnabled(true) + listPanel.list:moveChildToIndex(focused, n-1) + listPanel.list:ensureChildVisible(focused) end -listPanel.down.onClick = function() - local n = listPanel.list:getChildIndex(listPanel.list:getFocusedChild()) +listPanel.down.onClick = function(widget) + local focused = listPanel.list:getFocusedChild() + local n = listPanel.list:getChildIndex(focused) local t = config.rules t[n], t[n+1] = t[n+1], t[n] - listPanel.up:setEnabled(false) - listPanel.down:setEnabled(false) - refreshRules() -end + if n + 1 == listPanel.list:getChildCount() then + widget:setEnabled(false) + end + listPanel.up:setEnabled(true) + listPanel.list:moveChildToIndex(focused, n+1) + listPanel.list:ensureChildVisible(focused) + end function getItemsFromBox() local t = {} @@ -262,6 +271,19 @@ function refreshItemBox(reset) local box = inputPanel.itemBox 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 box:destroyChildren() local widget = UI.createWidget("BotItem", box) @@ -285,9 +307,8 @@ function refreshItemBox(reset) widget:destroy() end refreshItemBox() - refreshItemBox() 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) widget.onItemChange = function(widget) local id = widget:getItemId() @@ -296,7 +317,6 @@ function refreshItemBox(reset) widget:destroy() end refreshItemBox() - refreshItemBox() end end end @@ -324,6 +344,7 @@ function refreshRules() list:destroyChildren() for i,v in pairs(config.rules) do local widget = UI.createWidget('Rule', list) + widget:setId(v.name) widget:setText(v.name) widget.remove.onClick = function() widget:destroy() @@ -513,30 +534,33 @@ end --"Player is paralyzed", -- nothing 10 local pressedKey = "" +local lastPress = now onKeyPress(function(keys) pressedKey = keys + lastPress = now + schedule(100, function() + if now - lastPress > 20 then + pressedKey = "" + end + end) end) local function interpreteCondition(n, v) - local hp = hppercent() - local mp = manapercent() - local mobs = getMonsters() - local players = getPlayers() if n == 1 then return true elseif n == 2 then - return mobs > v + return getMonsters() > v elseif n == 3 then - return mobs < v + return getMonsters() < v elseif n == 4 then - return hp < v + return hppercent() < v elseif n == 5 then - return hp > v + return hppercent() > v elseif n == 6 then - return mp < v + return manapercent() < v elseif n == 7 then - return mp > v + return manapercent() > v elseif n == 8 then return target() and target():getName():lower() == v:lower() or false elseif n == 9 then @@ -546,10 +570,13 @@ local function interpreteCondition(n, v) elseif n == 11 then return isInPz() elseif n == 12 then - return players > v + return getPlayers() > v elseif n == 13 then - return players < v + return getPlayers() < v + elseif n == 14 then + return TargetBot.Danger() > v and TargetBot.isOn() end + end local function finalCheck(first,relation,second) @@ -605,7 +632,16 @@ EquipManager = macro(50, function() if #config.rules == 0 then return end 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 + widget:setColor('green') local firstCondition = interpreteCondition(rule.mainCondition, rule.mainValue) local optionalCondition = nil if rule.relation ~= "-" then diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/HealBot.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/HealBot.lua similarity index 61% rename from modules/game_bot/default_configs/vBot_4.0/vBot/HealBot.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/HealBot.lua index f43c517..530f429 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/HealBot.lua +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/HealBot.lua @@ -1,8 +1,11 @@ local standBySpells = false local standByItems = false +local red = "#ff0800" -- "#ff0800" / #ea3c53 best +local blue = "#7ef9ff" + setDefaultTab("HP") -healPanelName = "healbot" +local healPanelName = "healbot" local ui = setupUI([[ Panel height: 38 @@ -168,9 +171,9 @@ activeProfileColor() ui.title:setOn(currentSettings.enabled) ui.title.onClick = function(widget) -currentSettings.enabled = not currentSettings.enabled -widget:setOn(currentSettings.enabled) -vBotConfigSave("heal") + currentSettings.enabled = not currentSettings.enabled + widget:setOn(currentSettings.enabled) + vBotConfigSave("heal") end ui.settings.onClick = function(widget) @@ -184,45 +187,64 @@ if rootWidget then healWindow = UI.createWindow('HealWindow', rootWidget) 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() ui.name:setText(currentSettings.name) end - healWindow.Name.onTextChange = function(widget, text) + healWindow.settings.profiles.Name.onTextChange = function(widget, text) currentSettings.name = text setProfileName() end - healWindow.Visible.onClick = function(widget) + healWindow.settings.list.Visible.onClick = function(widget) currentSettings.Visible = not currentSettings.Visible - healWindow.Visible:setChecked(currentSettings.Visible) + healWindow.settings.list.Visible:setChecked(currentSettings.Visible) end - healWindow.Cooldown.onClick = function(widget) + healWindow.settings.list.Cooldown.onClick = function(widget) currentSettings.Cooldown = not currentSettings.Cooldown - healWindow.Cooldown:setChecked(currentSettings.Cooldown) + healWindow.settings.list.Cooldown:setChecked(currentSettings.Cooldown) end - healWindow.Interval.onClick = function(widget) + healWindow.settings.list.Interval.onClick = function(widget) currentSettings.Interval = not currentSettings.Interval - healWindow.Interval:setChecked(currentSettings.Interval) + healWindow.settings.list.Interval:setChecked(currentSettings.Interval) end - healWindow.Conditions.onClick = function(widget) + healWindow.settings.list.Conditions.onClick = function(widget) currentSettings.Conditions = not currentSettings.Conditions - healWindow.Conditions:setChecked(currentSettings.Conditions) + healWindow.settings.list.Conditions:setChecked(currentSettings.Conditions) end - healWindow.Delay.onClick = function(widget) + healWindow.settings.list.Delay.onClick = function(widget) currentSettings.Delay = not currentSettings.Delay - healWindow.Delay:setChecked(currentSettings.Delay) + healWindow.settings.list.Delay:setChecked(currentSettings.Delay) end - healWindow.MessageDelay.onClick = function(widget) + healWindow.settings.list.MessageDelay.onClick = function(widget) currentSettings.MessageDelay = not currentSettings.MessageDelay - healWindow.MessageDelay:setChecked(currentSettings.MessageDelay) + healWindow.settings.list.MessageDelay:setChecked(currentSettings.MessageDelay) end local refreshSpells = function() if currentSettings.spellTable then - for i, child in pairs(healWindow.spells.spellList:getChildren()) do - child:destroy() - end + healWindow.healer.spells.spellList:destroyChildren() for _, entry in pairs(currentSettings.spellTable) do - local label = UI.createWidget("SpellEntry", healWindow.spells.spellList) + local label = UI.createWidget("SpellEntry", healWindow.healer.spells.spellList) label.enabled:setChecked(entry.enabled) label.enabled.onClick = function(widget) standBySpells = false @@ -237,7 +259,7 @@ if rootWidget then reindexTable(currentSettings.spellTable) label:destroy() 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 @@ -245,11 +267,9 @@ if rootWidget then local refreshItems = function() if currentSettings.itemTable then - for i, child in pairs(healWindow.items.itemList:getChildren()) do - child:destroy() - end + healWindow.healer.items.itemList:destroyChildren() for _, entry in pairs(currentSettings.itemTable) do - local label = UI.createWidget("SpellEntry", healWindow.items.itemList) + local label = UI.createWidget("ItemEntry", healWindow.healer.items.itemList) label.enabled:setChecked(entry.enabled) label.enabled.onClick = function(widget) standBySpells = false @@ -264,138 +284,87 @@ if rootWidget then reindexTable(currentSettings.itemTable) label:destroy() end - label:setText(entry.origin .. entry.sign .. entry.value .. ":" .. entry.item) + label.id:setItemId(entry.item) + label:setText(entry.origin .. entry.sign .. entry.value .. ": " .. entry.item) end end end refreshItems() - healWindow.spells.MoveUp.onClick = function(widget) - local input = healWindow.spells.spellList:getFocusedChild() + healWindow.healer.spells.MoveUp.onClick = function(widget) + local input = healWindow.healer.spells.spellList:getFocusedChild() if not input then return end - local index = healWindow.spells.spellList:getChildIndex(input) + local index = healWindow.healer.spells.spellList:getChildIndex(input) if index < 2 then return end - local move - if currentSettings.spellTable and #currentSettings.spellTable > 0 then - for _, entry in pairs(currentSettings.spellTable) do - if entry.index == index -1 then - move = entry - end - if entry.index == index then - move.index = index - entry.index = index -1 - end - end - end - table.sort(currentSettings.spellTable, function(a,b) return a.index < b.index end) + local t = currentSettings.spellTable - healWindow.spells.spellList:moveChildToIndex(input, index - 1) - healWindow.spells.spellList:ensureChildVisible(input) + t[index],t[index-1] = t[index-1], t[index] + healWindow.healer.spells.spellList:moveChildToIndex(input, index - 1) + healWindow.healer.spells.spellList:ensureChildVisible(input) end - healWindow.spells.MoveDown.onClick = function(widget) - local input = healWindow.spells.spellList:getFocusedChild() + healWindow.healer.spells.MoveDown.onClick = function(widget) + local input = healWindow.healer.spells.spellList:getFocusedChild() if not input then return end - local index = healWindow.spells.spellList:getChildIndex(input) - if index >= healWindow.spells.spellList:getChildCount() then return end + local index = healWindow.healer.spells.spellList:getChildIndex(input) + if index >= healWindow.healer.spells.spellList:getChildCount() then return end - local move - local move2 - if currentSettings.spellTable and #currentSettings.spellTable > 0 then - for _, entry in pairs(currentSettings.spellTable) do - if entry.index == index +1 then - move = entry - end - if entry.index == index then - move2 = entry - end - end - if move and move2 then - move.index = index - move2.index = index + 1 - end - end - table.sort(currentSettings.spellTable, function(a,b) return a.index < b.index end) + local t = currentSettings.spellTable - healWindow.spells.spellList:moveChildToIndex(input, index + 1) - healWindow.spells.spellList:ensureChildVisible(input) + t[index],t[index+1] = t[index+1],t[index] + healWindow.healer.spells.spellList:moveChildToIndex(input, index + 1) + healWindow.healer.spells.spellList:ensureChildVisible(input) end - healWindow.items.MoveUp.onClick = function(widget) - local input = healWindow.items.itemList:getFocusedChild() + healWindow.healer.items.MoveUp.onClick = function(widget) + local input = healWindow.healer.items.itemList:getFocusedChild() if not input then return end - local index = healWindow.items.itemList:getChildIndex(input) + local index = healWindow.healer.items.itemList:getChildIndex(input) if index < 2 then return end - local move - if currentSettings.itemTable and #currentSettings.itemTable > 0 then - for _, entry in pairs(currentSettings.itemTable) do - if entry.index == index -1 then - move = entry - end - if entry.index == index then - move.index = index - entry.index = index - 1 - end - end - end - table.sort(currentSettings.itemTable, function(a,b) return a.index < b.index end) + local t = currentSettings.itemTable - healWindow.items.itemList:moveChildToIndex(input, index - 1) - healWindow.items.itemList:ensureChildVisible(input) + t[index],t[index-1] = t[index-1], t[index] + healWindow.healer.items.itemList:moveChildToIndex(input, index - 1) + healWindow.healer.items.itemList:ensureChildVisible(input) end - healWindow.items.MoveDown.onClick = function(widget) - local input = healWindow.items.itemList:getFocusedChild() + healWindow.healer.items.MoveDown.onClick = function(widget) + local input = healWindow.healer.items.itemList:getFocusedChild() if not input then return end - local index = healWindow.items.itemList:getChildIndex(input) - if index >= healWindow.items.itemList:getChildCount() then return end + local index = healWindow.healer.items.itemList:getChildIndex(input) + if index >= healWindow.healer.items.itemList:getChildCount() then return end - local move - local move2 - if currentSettings.itemTable and #currentSettings.itemTable > 0 then - for _, entry in pairs(currentSettings.itemTable) do - if entry.index == index +1 then - move = entry - end - if entry.index == index then - move2 = entry - end - end - if move and move2 then - move.index = index - move2.index = index + 1 - end - end - table.sort(currentSettings.itemTable, function(a,b) return a.index < b.index end) + local t = currentSettings.itemTable - healWindow.items.itemList:moveChildToIndex(input, index + 1) - healWindow.items.itemList:ensureChildVisible(input) + t[index],t[index+1] = t[index+1],t[index] + healWindow.healer.items.itemList:moveChildToIndex(input, index + 1) + healWindow.healer.items.itemList:ensureChildVisible(input) end - healWindow.spells.addSpell.onClick = function(widget) + healWindow.healer.spells.addSpell.onClick = function(widget) - local spellFormula = healWindow.spells.spellFormula:getText():trim() - local manaCost = tonumber(healWindow.spells.manaCost:getText()) - local spellTrigger = tonumber(healWindow.spells.spellValue:getText()) - local spellSource = healWindow.spells.spellSource:getCurrentOption().text - local spellEquasion = healWindow.spells.spellCondition:getCurrentOption().text + local spellFormula = healWindow.healer.spells.spellFormula:getText():trim() + local manaCost = tonumber(healWindow.healer.spells.manaCost:getText()) + local spellTrigger = tonumber(healWindow.healer.spells.spellValue:getText()) + local spellSource = healWindow.healer.spells.spellSource:getCurrentOption().text + local spellEquasion = healWindow.healer.spells.spellCondition:getCurrentOption().text local source local equasion if not manaCost then warn("HealBot: incorrect mana cost value!") - healWindow.spells.spellFormula:setText('') - healWindow.spells.spellValue:setText('') - healWindow.spells.manaCost:setText('') + healWindow.healer.spells.spellFormula:setText('') + healWindow.healer.spells.spellValue:setText('') + healWindow.healer.spells.manaCost:setText('') return end if not spellTrigger then warn("HealBot: incorrect condition value!") - healWindow.spells.spellFormula:setText('') - healWindow.spells.spellValue:setText('') - healWindow.spells.manaCost:setText('') + healWindow.healer.spells.spellFormula:setText('') + healWindow.healer.spells.spellValue:setText('') + healWindow.healer.spells.manaCost:setText('') return end @@ -421,28 +390,28 @@ if rootWidget 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}) - healWindow.spells.spellFormula:setText('') - healWindow.spells.spellValue:setText('') - healWindow.spells.manaCost:setText('') + healWindow.healer.spells.spellFormula:setText('') + healWindow.healer.spells.spellValue:setText('') + healWindow.healer.spells.manaCost:setText('') end standBySpells = false standByItems = false refreshSpells() end - healWindow.items.addItem.onClick = function(widget) + healWindow.healer.items.addItem.onClick = function(widget) - local id = healWindow.items.itemId:getItemId() - local trigger = tonumber(healWindow.items.itemValue:getText()) - local src = healWindow.items.itemSource:getCurrentOption().text - local eq = healWindow.items.itemCondition:getCurrentOption().text + local id = healWindow.healer.items.itemId:getItemId() + local trigger = tonumber(healWindow.healer.items.itemValue:getText()) + local src = healWindow.healer.items.itemSource:getCurrentOption().text + local eq = healWindow.healer.items.itemCondition:getCurrentOption().text local source local equasion if not trigger then warn("HealBot: incorrect trigger value!") - healWindow.items.itemId:setItemId(0) - healWindow.items.itemValue:setText('') + healWindow.healer.items.itemId:setItemId(0) + healWindow.healer.items.itemValue:setText('') return end @@ -471,28 +440,27 @@ if rootWidget then standBySpells = false standByItems = false refreshItems() - healWindow.items.itemId:setItemId(0) - healWindow.items.itemValue:setText('') + healWindow.healer.items.itemId:setItemId(0) + healWindow.healer.items.itemValue:setText('') end end healWindow.closeButton.onClick = function(widget) healWindow:hide() - vBotConfigSave("heal") end local loadSettings = function() ui.title:setOn(currentSettings.enabled) setProfileName() - healWindow.Name:setText(currentSettings.name) + healWindow.settings.profiles.Name:setText(currentSettings.name) refreshSpells() refreshItems() - healWindow.Visible:setChecked(currentSettings.Visible) - healWindow.Cooldown:setChecked(currentSettings.Cooldown) - healWindow.Delay:setChecked(currentSettings.Delay) - healWindow.MessageDelay:setChecked(currentSettings.MessageDelay) - healWindow.Interval:setChecked(currentSettings.Interval) - healWindow.Conditions:setChecked(currentSettings.Conditions) + healWindow.settings.list.Visible:setChecked(currentSettings.Visible) + healWindow.settings.list.Cooldown:setChecked(currentSettings.Cooldown) + healWindow.settings.list.Delay:setChecked(currentSettings.Delay) + healWindow.settings.list.MessageDelay:setChecked(currentSettings.MessageDelay) + healWindow.settings.list.Interval:setChecked(currentSettings.Interval) + healWindow.settings.list.Conditions:setChecked(currentSettings.Conditions) end loadSettings() @@ -525,7 +493,7 @@ if rootWidget then end end - healWindow.ResetSettings.onClick = function() + healWindow.settings.profiles.ResetSettings.onClick = function() resetSettings() loadSettings() end @@ -566,74 +534,87 @@ if rootWidget then profileChange() end end + + HealBot.show = function() + healWindow:show() + healWindow:raise() + healWindow:focus() + end end -- spells macro(100, function() if standBySpells then return end - if not currentSettings.enabled or modules.game_cooldown.isGroupCooldownIconActive(2) or #currentSettings.spellTable == 0 then return end + if not currentSettings.enabled then return end + local somethingIsOnCooldown = false for _, entry in pairs(currentSettings.spellTable) do - if canCast(entry.spell, not currentSettings.Conditions, not currentSettings.Cooldown) and entry.enabled and entry.cost < mana() then - if entry.origin == "HP%" then - if entry.sign == "=" and hppercent() == entry.value then - say(entry.spell) - return - elseif entry.sign == ">" and hppercent() >= entry.value then - say(entry.spell) - return - elseif entry.sign == "<" and hppercent() <= entry.value then - say(entry.spell) - return + if 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.sign == "=" and hppercent() == entry.value then + say(entry.spell) + return + elseif entry.sign == ">" and hppercent() >= entry.value then + say(entry.spell) + return + elseif entry.sign == "<" and hppercent() <= entry.value then + say(entry.spell) + return + end + elseif entry.origin == "HP" then + if entry.sign == "=" and hp() == entry.value then + say(entry.spell) + return + elseif entry.sign == ">" and hp() >= entry.value then + say(entry.spell) + return + elseif entry.sign == "<" and hp() <= entry.value then + say(entry.spell) + return + end + elseif entry.origin == "MP%" then + if entry.sign == "=" and manapercent() == entry.value then + say(entry.spell) + return + elseif entry.sign == ">" and manapercent() >= entry.value then + say(entry.spell) + return + elseif entry.sign == "<" and manapercent() <= entry.value then + say(entry.spell) + return + end + elseif entry.origin == "MP" then + if entry.sign == "=" and mana() == entry.value then + say(entry.spell) + return + elseif entry.sign == ">" and mana() >= entry.value then + say(entry.spell) + return + elseif entry.sign == "<" and mana() <= entry.value then + say(entry.spell) + return + end + elseif entry.origin == "burst" then + if entry.sign == "=" and burstDamageValue() == entry.value then + say(entry.spell) + return + elseif entry.sign == ">" and burstDamageValue() >= entry.value then + say(entry.spell) + return + elseif entry.sign == "<" and burstDamageValue() <= entry.value then + say(entry.spell) + return + end end - 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 + else + somethingIsOnCooldown = true end end end - standBySpells = true + if not somethingIsOnCooldown then + standBySpells = true + end end) -- items diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/HealBot.otui b/modules/game_bot/default_configs/vBot_4.4/vBot/HealBot.otui similarity index 55% rename from modules/game_bot/default_configs/vBot_4.0/vBot/HealBot.otui rename to modules/game_bot/default_configs/vBot_4.4/vBot/HealBot.otui index 06a197a..fb8cb03 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/HealBot.otui +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/HealBot.otui @@ -1,3 +1,9 @@ +SettingCheckBox < CheckBox + text-wrap: true + text-auto-resize: true + margin-top: 3 + font: verdana-11px-rounded + SpellSourceBoxPopupMenu < ComboBoxPopupMenu SpellSourceBoxPopupMenuButton < ComboBoxPopupMenuButton SpellSourceBox < ComboBox @@ -18,9 +24,10 @@ SpellConditionBox < ComboBox SpellEntry < Label background-color: alpha - text-offset: 18 0 + text-offset: 18 1 focusable: true height: 16 + font: verdana-11px-rounded CheckBox id: enabled @@ -39,14 +46,33 @@ SpellEntry < Label !text: tr('x') anchors.right: parent.right margin-right: 15 + text-offset: 1 0 width: 15 - height: 15 + height: 15 ItemEntry < Label background-color: alpha - text-offset: 2 0 + text-offset: 40 1 focusable: true 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: background-color: #00000055 @@ -56,30 +82,37 @@ ItemEntry < Label !text: tr('x') anchors.right: parent.right margin-right: 15 + text-offset: 1 0 width: 15 - height: 15 + height: 15 -SpellHealing < Panel - image-source: /images/ui/panel_flat - image-border: 6 - padding: 3 +SpellHealing < FlatPanel 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 id: whenSpell anchors.left: spellList.right - anchors.top: parent.top + anchors.verticalCenter: prev.verticalCenter text: When - margin-top: 10 margin-left: 7 - - SpellSourceBox - id: spellSource - anchors.top: parent.top - anchors.left: whenSpell.right - margin-top: 5 - margin-left: 35 - width: 128 + font: verdana-11px-rounded Label id: isSpell @@ -88,6 +121,7 @@ SpellHealing < Panel text: Is margin-top: 9 margin-left: 7 + font: verdana-11px-rounded SpellConditionBox id: spellCondition @@ -95,13 +129,15 @@ SpellHealing < Panel anchors.top: spellSource.bottom marin-top: 15 width: 80 + font: verdana-11px-rounded TextEdit id: spellValue anchors.left: spellCondition.right anchors.top: spellCondition.top anchors.bottom: spellCondition.bottom - width: 49 + anchors.right: spellSource.right + font: verdana-11px-rounded Label id: castSpell @@ -109,12 +145,14 @@ SpellHealing < Panel anchors.top: isSpell.bottom text: Cast margin-top: 9 + font: verdana-11px-rounded TextEdit id: spellFormula anchors.left: spellCondition.left anchors.top: spellCondition.bottom anchors.right: spellValue.right + font: verdana-11px-rounded Label id: manaSpell @@ -122,21 +160,26 @@ SpellHealing < Panel anchors.top: castSpell.bottom text: Mana Cost: margin-top: 8 + font: verdana-11px-rounded TextEdit id: manaCost anchors.left: spellFormula.left anchors.top: spellFormula.bottom width: 40 + font: verdana-11px-rounded TextList id: spellList anchors.left: parent.left anchors.bottom: parent.bottom + anchors.top: parent.top padding: 1 - size: 270 116 - margin-bottom: 3 - margin-left: 3 + padding-top: 2 + width: 270 + margin-bottom: 7 + margin-left: 7 + margin-top: 10 vertical-scrollbar: spellListScrollBar VerticalScrollBar @@ -150,9 +193,7 @@ SpellHealing < Panel Button id: addSpell anchors.right: spellFormula.right - anchors.bottom: parent.bottom - margin-bottom: 2 - margin-right: 10 + anchors.bottom: spellList.bottom text: Add size: 40 17 font: cipsoftFont @@ -160,8 +201,7 @@ SpellHealing < Panel Button id: MoveUp anchors.right: prev.left - anchors.bottom: parent.bottom - margin-bottom: 2 + anchors.bottom: prev.bottom margin-right: 5 text: Move Up size: 55 17 @@ -170,34 +210,39 @@ SpellHealing < Panel Button id: MoveDown anchors.right: prev.left - anchors.bottom: parent.bottom - margin-bottom: 2 + anchors.bottom: prev.bottom margin-right: 5 text: Move Down size: 55 17 font: cipsoftFont -ItemHealing < Panel - image-source: /images/ui/panel_flat - image-border: 6 - padding: 3 - size: 490 130 +ItemHealing < FlatPanel + size: 490 120 + + Label + id: title + 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 id: whenItem anchors.left: itemList.right - anchors.top: parent.top + anchors.verticalCenter: prev.verticalCenter text: When - margin-top: 10 margin-left: 7 - - SpellSourceBox - id: itemSource - anchors.top: parent.top - anchors.left: whenItem.right - margin-top: 5 - margin-left: 35 - width: 128 + font: verdana-11px-rounded Label id: isItem @@ -206,6 +251,7 @@ ItemHealing < Panel text: Is margin-top: 9 margin-left: 7 + font: verdana-11px-rounded SpellConditionBox id: itemCondition @@ -213,6 +259,7 @@ ItemHealing < Panel anchors.top: itemSource.bottom marin-top: 15 width: 80 + font: verdana-11px-rounded TextEdit id: itemValue @@ -220,6 +267,7 @@ ItemHealing < Panel anchors.top: itemCondition.top anchors.bottom: itemCondition.bottom width: 49 + font: verdana-11px-rounded Label id: useItem @@ -227,6 +275,7 @@ ItemHealing < Panel anchors.top: isItem.bottom text: Use margin-top: 15 + font: verdana-11px-rounded BotItem id: itemId @@ -237,11 +286,13 @@ ItemHealing < Panel id: itemList anchors.left: parent.left anchors.bottom: parent.bottom + anchors.top: parent.top padding: 1 - size: 270 116 - margin-top: 3 - margin-bottom: 3 - margin-left: 3 + padding-top: 2 + width: 270 + margin-top: 10 + margin-bottom: 7 + margin-left: 8 vertical-scrollbar: itemListScrollBar VerticalScrollBar @@ -255,9 +306,7 @@ ItemHealing < Panel Button id: addItem anchors.right: itemValue.right - anchors.bottom: parent.bottom - margin-bottom: 2 - margin-right: 10 + anchors.bottom: itemList.bottom text: Add size: 40 17 font: cipsoftFont @@ -265,8 +314,7 @@ ItemHealing < Panel Button id: MoveUp anchors.right: prev.left - anchors.bottom: parent.bottom - margin-bottom: 2 + anchors.bottom: prev.bottom margin-right: 5 text: Move Up size: 55 17 @@ -275,20 +323,19 @@ ItemHealing < Panel Button id: MoveDown anchors.right: prev.left - anchors.bottom: parent.bottom - margin-bottom: 2 + anchors.bottom: prev.bottom margin-right: 5 text: Move Down size: 55 17 - font: cipsoftFont + font: cipsoftFont -HealWindow < MainWindow - !text: tr('Self Healer') - size: 800 350 +HealerPanel < Panel + size: 510 275 SpellHealing id: spells anchors.top: parent.top + margin-top: 8 anchors.left: parent.left ItemHealing @@ -297,95 +344,128 @@ HealWindow < MainWindow anchors.left: parent.left 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 - id: sep - anchors.top: parent.top + anchors.top: prev.top + anchors.bottom: prev.bottom anchors.left: prev.right - anchors.bottom: separator.top - margin-left: 10 - margin-bottom: 5 + margin-left: 8 + + FlatPanel + 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 - anchors.left: prev.right - anchors.right: parent.right + id: title + anchors.left: parent.left anchors.top: parent.top - text-align: center - text: Additional Options + margin-left: 2 + !text: tr('More important methods come first (Example: Exura gran above Exura)') + text-align: left + font: verdana-11px-rounded + color: #aeaeae - HorizontalSeparator - anchors.left: prev.left - anchors.top: prev.bottom - anchors.right: prev.right - margin-top: 5 - margin-left: 10 - - CheckBox - id: Cooldown + HealerPanel + id: healer anchors.top: prev.bottom - anchors.left: prev.left - margin-top: 10 - margin-left: 5 - width: 200 - text: Check spell cooldowns + anchors.left: parent.left - CheckBox - id: Visible - anchors.top: prev.bottom - anchors.left: prev.left - margin-top: 8 - width: 250 - text: Items must be visible (recommended) - - CheckBox - id: Delay - anchors.top: prev.bottom - anchors.left: prev.left - margin-top: 8 - width: 250 - text: Don't use items when interacting - - CheckBox - id: Interval - anchors.top: prev.bottom - anchors.left: prev.left - margin-top: 8 - width: 250 - text: Additional delay when looting corpses - - CheckBox - id: Conditions - anchors.top: prev.bottom - anchors.left: prev.left - margin-top: 8 - width: 250 - text: Also check conditions from RL Tibia - - CheckBox - id: MessageDelay - anchors.top: prev.bottom - anchors.left: prev.left - margin-top: 8 - width: 250 - text: Cooldown based on "Aaaah..." message - - Label - anchors.left: Visible.left - anchors.bottom: separator.top - margin-bottom: 8 - text: Profile: - - TextEdit - id: Name - anchors.verticalCenter: prev.verticalCenter - anchors.left: prev.right - margin-left: 5 - - Button - id: ResetSettings - anchors.verticalCenter: prev.verticalCenter - anchors.right: parent.right - text: Reset Settings - margin-top: 1 + HealBotSettingsPanel + id: settings + anchors.top: title.bottom + anchors.left: parent.left + visible: false HorizontalSeparator id: separator @@ -401,5 +481,12 @@ HealWindow < MainWindow anchors.right: parent.right anchors.bottom: parent.bottom size: 45 21 - margin-top: 15 - margin-right: 5 \ No newline at end of file + margin-right: 5 + + Button + id: settingsButton + !text: tr('Settings') + font: cipsoftFont + anchors.left: parent.left + anchors.bottom: parent.bottom + size: 45 21 \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/Sio.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/Sio.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/Sio.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/Sio.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/alarms.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/alarms.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/alarms.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/alarms.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/alarms.otui b/modules/game_bot/default_configs/vBot_4.4/vBot/alarms.otui similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/alarms.otui rename to modules/game_bot/default_configs/vBot_4.4/vBot/alarms.otui diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/analyzer.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/analyzer.lua similarity index 61% rename from modules/game_bot/default_configs/vBot_4.0/vBot/analyzer.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/analyzer.lua index 3ba6233..615f3f0 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/analyzer.lua +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/analyzer.lua @@ -11,10 +11,54 @@ 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 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 -local windowsTable = {"MainAnalyzerWindow", "HuntingAnalyzerWindow", "LootAnalyzerWindow", "SupplyAnalyzerWindow", "ImpactAnalyzerWindow", "XPAnalyzerWindow"} +local windowsTable = {"MainAnalyzerWindow", "HuntingAnalyzerWindow", "LootAnalyzerWindow", "SupplyAnalyzerWindow", "ImpactAnalyzerWindow", "XPAnalyzerWindow", "PartyAnalyzerWindow", "DropTracker"} for i, window in ipairs(windowsTable) do local element = g_ui.getRootWidget():recursiveGetChildById(window) @@ -24,31 +68,26 @@ for i, window in ipairs(windowsTable) do end local mainWindow = UI.createMiniWindow("MainAnalyzerWindow") -mainWindow:disableResize() mainWindow:hide() - +mainWindow:setContentMaximumHeight(220) local huntingWindow = UI.createMiniWindow("HuntingAnalyzer") huntingWindow:hide() - local lootWindow = UI.createMiniWindow("LootAnalyzer") lootWindow:hide() -lootWindow:setContentMaximumHeight(215) - local supplyWindow = UI.createMiniWindow("SupplyAnalyzer") supplyWindow:hide() -supplyWindow:setContentMaximumHeight(215) - local impactWindow = UI.createMiniWindow("ImpactAnalyzer") impactWindow:hide() impactWindow:setContentMaximumHeight(615) - local xpWindow = UI.createMiniWindow("XPAnalyzer") xpWindow:hide() xpWindow:setContentMaximumHeight(230) - local settingsWindow = UI.createWindow("FeaturesWindow") settingsWindow:hide() - +local partyHuntWindow = UI.createMiniWindow("PartyAnalyzerWindow") +partyHuntWindow:hide() +local dropTrackerWindow = UI.createMiniWindow("DropTracker") +dropTrackerWindow:hide() --f local toggle = function() @@ -73,6 +112,51 @@ local toggleAnalyzer = function(window) 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 analyzerButton = modules.game_buttons.buttonsWindow.contentsPanel and modules.game_buttons.buttonsWindow.contentsPanel.buttons.botAnalyzersButton analyzerButton = analyzerButton or modules.client_topmenu.getButton("botAnalyzersButton") @@ -88,6 +172,9 @@ analyzerButton:setOn(false) mainWindow.contentsPanel.HuntingAnalyzer.onClick = function() toggleAnalyzer(huntingWindow) end +mainWindow.onClose = function() + analyzerButton:setOn(false) +end mainWindow.contentsPanel.LootAnalyzer.onClick = function() toggleAnalyzer(lootWindow) end @@ -100,9 +187,14 @@ end mainWindow.contentsPanel.XPAnalyzer.onClick = function() toggleAnalyzer(xpWindow) end +mainWindow.contentsPanel.PartyHunt.onClick = function() + toggleAnalyzer(partyHuntWindow) +end +mainWindow.contentsPanel.DropTracker.onClick = function() + toggleAnalyzer(dropTrackerWindow) +end --hunting -huntingWindow:setContentMaximumHeight(204) local sessionTimeLabel = UI.DualLabel("Session:", "00:00h", {}, huntingWindow.contentsPanel).right local xpGainLabel = UI.DualLabel("XP Gain:", "0", {}, huntingWindow.contentsPanel).right local xpHourLabel = UI.DualLabel("XP/h:", "0", {}, huntingWindow.contentsPanel).right @@ -113,9 +205,171 @@ local damageLabel = UI.DualLabel("Damage:", "0", {}, huntingWindow.contentsPanel local damageHourLabel = UI.DualLabel("Damage/h:", "0", {}, huntingWindow.contentsPanel).right local healingLabel = UI.DualLabel("Healing:", "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 @@ -240,14 +494,18 @@ local function getColor(v) return "#5F8DF7" elseif v >= 1000 then -- 1k, green return "#00FF00" + elseif v >= 50 then + return "#FFFFFF" -- 50gp, white else - return "#FFFFFF" -- less than 1k, white + return "#aaaaaa" -- less than 100gp, grey end end local function formatStr(str) if string.starts(str, "a ") then str = str:sub(2, #str) + elseif string.starts(str, "an ") then + str = str:sub(3, #str) end local n = getFirstNumberInText(str) @@ -261,6 +519,7 @@ end local function getPrice(name) name = formatStr(name) + name = name:lower() -- first check custom prices if storage.analyzers.customPrices[name] then return storage.analyzers.customPrices[name] @@ -289,6 +548,57 @@ local function getPrice(name) return 0 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) table.insert(t, text) table.insert(t, color) @@ -298,9 +608,147 @@ local function add(t, text, color, last) 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) 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 + 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 local split = string.split(text, ":") local re = regexMatch(split[2], regex) @@ -308,21 +756,50 @@ onTextMessage(function(mode, text) local formatted local div local t = {} + local messageT = {} -- add timestamp, creature part and color it as white add(t, os.date('%H:%M') .. ' ' .. split[1]..": ", "#FFFFFF", true) + add(messageT, split[1]..": ", "#FFFFFF", true) -- main part if re ~= 0 then for i=1,#re do local data = re[i][2] -- each looted item - local amount = getFirstNumberInText(data) -- amount found in data - local price = amount and getPrice(data) * amount or getPrice(data) -- if amount then multity price, else just take price + local formattedLoot = regexMatch(data, [[(^[^(]+)]])[1][1] + formattedLoot = formattedLoot:trim() + 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 messageColor = getColor(getPrice(formattedLoot)) combinedWorth = combinedWorth + price -- add all prices to calculate total worth 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 @@ -337,6 +814,13 @@ onTextMessage(function(mode, text) formatted = combinedWorth .. "gp" 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(t, " - (", "#FFFFFF", true) add(t, formatted, getColor(combinedWorth), true) @@ -375,27 +859,7 @@ local function niceFormat(v) return formatted end - -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() +resetAnalyzerSessionData = function() launchTime = now startExp = exp() dmgTable = {} @@ -424,10 +888,13 @@ local resetSessionData = function() drawGraph(dmgGraph, 0) healGraph:clear() drawGraph(healGraph, 0) + killList = {} + refreshKills() + HuntingSessionStart = os.date('%Y-%m-%d, %H:%M:%S') end mainWindow.contentsPanel.ResetSession.onClick = function() - resetSessionData() + resetAnalyzerSessionData() end mainWindow.contentsPanel.Settings.onClick = function() @@ -442,22 +909,14 @@ settingsWindow.closeButton.onClick = function() settingsWindow:hide() end -if not storage.analyzers then - storage.analyzers = { - customPrices = {}, - lootChannel = true, - rarityFrames = true - } -end - local function getFrame(v) - if v > 1000000 then + if v >= 1000000 then return '/images/ui/rarity_gold' - elseif v > 100000 then + elseif v >= 100000 then return '/images/ui/rarity_purple' - elseif v > 10000 then + elseif v >= 10000 then return '/images/ui/rarity_blue' - elseif v > 1000 then + elseif v >= 1000 then return '/images/ui/rarity_green' else return '/images/ui/item' @@ -568,63 +1027,6 @@ settingsWindow.RarityFrames.onClick = function(widget) setFrames() end - - - - - - - - -function format_thousand(v) - if not v then return 0 end - local s = string.format("%d", math.floor(v)) - local pos = string.len(s) % 3 - if pos == 0 then pos = 3 end - return string.sub(s, 1, pos) - .. string.gsub(string.sub(s, pos+1), "(...)", ".%1") - end - -local expGained = function() - return exp() - startExp -end -local expLeft = function() - local level = lvl()+1 - return math.floor((50*level*level*level)/3 - 100*level*level + (850*level)/3 - 200) - exp() -end - -local niceTimeFormat = function(v) -- v in seconds - local hours = string.format("%02.f", math.floor(v/3600)) - local mins = string.format("%02.f", math.floor(v/60 - (hours*60))) - return hours .. ":" .. mins .. "h" -end -local uptime -local sessionTime = function() - uptime = math.floor((now - launchTime)/1000) - return niceTimeFormat(uptime) -end -sessionTime() - -local expPerHour = function(calculation) - local r = 0 - if #expTable > 0 then - r = exp() - expTable[1] - else - return "-" - end - - if uptime < 15*60 then - r = math.ceil((r/uptime)*60*60) - else - r = math.ceil(r*8) - end - if calculation then - return r - else - return format_thousand(r) - end -end - local timeToLevel = function() local t = 0 if expPerHour(true) == 0 or expPerHour() == "-" then @@ -772,9 +1174,11 @@ end function refreshLoot() - lootItems.List:destroyChildren() + lootItems:destroyChildren() + lootList:destroyChildren() + for k,v in pairs(lootedItems) do - local label1 = UI.createWidget("AnalyzerLootItem", lootItems.List) + local label1 = UI.createWidget("AnalyzerLootItem", lootItems) local price = v.count and getPrice(v.name) * v.count or getPrice(v.name) label1:setItemId(k) @@ -784,17 +1188,38 @@ function refreshLoot() label1.count:setColor(getColor(price)) 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)") + --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 - local height = getPanelHeight(lootItems) - lootItems:setHeight(height) - lootWindow:setContentMaximumHeight(height+220) 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() - supplyItems.List:destroyChildren() + supplyItems:destroyChildren() for k,v in pairs(usedItems) do - local label1 = UI.createWidget("AnalyzerLootItem", supplyItems.List) + local label1 = UI.createWidget("AnalyzerLootItem", supplyItems) local price = v.count and getPrice(v.name) * v.count or getPrice(v.name) label1:setItemId(k) @@ -805,13 +1230,8 @@ function refreshWaste() 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)") end - local height = getPanelHeight(supplyItems) - supplyItems:setHeight(height) - supplyWindow:setContentMaximumHeight(height+215) end - - -- loot analyzer -- adding local containers = CaveBot.GetLootContainers() @@ -821,7 +1241,6 @@ onAddItem(function(container, slot, item, oldItem) if isInPz() then return end if slot > 0 then return end if freecap() >= lastCap then return end - --local name = item:getId() == 3031 and "gold coin" or item:getId() == 3035 and "platinum coin" or item:getId() == 3043 and "crystal coin" or item:getMarketData().name 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 if not lootedItems[name] then @@ -831,6 +1250,8 @@ onAddItem(function(container, slot, item, oldItem) end lastCap = freecap() refreshLoot() + + -- drop tracker end) onContainerUpdateItem(function(container, slot, item, oldItem) @@ -894,6 +1315,8 @@ onTextMessage(function(mode, text) else usedItems[id].count = usedItems[id].count + 1 end + else + useData[name] = amount end refreshWaste() end @@ -904,15 +1327,6 @@ function hourVal(v) return (v/uptime)*3600 end -local lootWorth -local wasteWorth -local balance -local balanceDesc -local hourDesc -local desc -local hour - - function bottingStats() lootWorth = 0 wasteWorth = 0 @@ -1008,6 +1422,11 @@ function lootHour() end end +function getHuntingData() + local lootWorth, wasteWorth, balance = bottingStats() + return totalDmg, totalHeal, lootWorth, wasteWorth, balance +end + --bestdps/hps local bestDPS = 0 local bestHPS = 0 @@ -1029,7 +1448,7 @@ macro(500, function() xpHourLabel:setText(expPerHour()) lootLabel:setText(format_thousand(lootWorth)) suppliesLabel:setText(format_thousand(wasteWorth)) - balanceLabel:setColor(balance >= 0 and "green" or "red") + balanceLabel:setColor(balance >= 0 and "#45ad25" or "#ff9854") balanceLabel:setText(balanceDesc .. " (" .. hourDesc .. ")") damageLabel:setText(format_thousand(totalDmg)) damageHourLabel:setText(format_thousand(damageHour())) @@ -1080,4 +1499,81 @@ macro(60*1000, function() drawGraph(supplyGraph, wasteHour() or 0) drawGraph(dmgGraph, valueInSeconds(dmgTable) or 0) drawGraph(healGraph, valueInSeconds(healTable) or 0) -end) \ No newline at end of file +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 \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/analyzer.otui b/modules/game_bot/default_configs/vBot_4.4/vBot/analyzer.otui similarity index 61% rename from modules/game_bot/default_configs/vBot_4.0/vBot/analyzer.otui rename to modules/game_bot/default_configs/vBot_4.4/vBot/analyzer.otui index 76c8276..fd12bd4 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/analyzer.otui +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/analyzer.otui @@ -1,3 +1,121 @@ +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 background-color: alpha text-offset: 2 0 @@ -15,19 +133,28 @@ AnalyzerPriceLabel < Label width: 15 height: 15 -AnalyzerItemsPanel < Panel - height: 0 +AnalyzerListPanel < Panel + padding-left: 4 + padding-right: 4 + layout: + type: verticalBox + fit-children: true - Panel - id: List - anchors.fill: parent - margin-top: 3 - padding: 2 - layout: - type: grid - cell-size: 32 32 - cell-spacing: 3 - num-columns: 5 + +ListLabel < Label + height: 15 + font: verdana-11px-rounded + text-offset: 15 0 + +AnalyzerItemsPanel < Panel + id: List + padding: 2 + layout: + type: grid + cell-size: 33 33 + cell-spacing: 1 + num-columns: 5 + fit-children: true AnalyzerLootItem < UIItem opacity: 0.87 @@ -79,7 +206,7 @@ AnalyzerButton < Button MainAnalyzerWindow < MiniWindow id: MainAnalyzerWindow text: Analytics Selector - height: 200 + height: 245 icon: /images/topbuttons/analyzers MiniWindowContents @@ -108,6 +235,15 @@ MainAnalyzerWindow < MiniWindow id: XPAnalyzer text: XP Analyzer + AnalyzerButton + id: DropTracker + text: Drop Tracker + + AnalyzerButton + id: PartyHunt + text: Party Hunt + color: #3895D3 + AnalyzerButton id: Settings text: Features & Settings @@ -164,6 +300,29 @@ XPAnalyzer < MiniWindow padding-top: 3 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 id: FeaturesWindow diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/antiRs.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/antiRs.lua similarity index 79% rename from modules/game_bot/default_configs/vBot_4.0/vBot/antiRs.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/antiRs.lua index 0330500..41f5a3f 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/antiRs.lua +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/antiRs.lua @@ -4,10 +4,11 @@ local m = macro(1000, "AntiRS & Msg", function() end) local frags = 0 onTextMessage(function(mode, text) if not m.isOn() then return end - if not text:lower():find("warning! the murder of") then return end + if not text:find("Warning! The murder of") then return end say("Don't bother, I have anti-rs and shit EQ. Don't waste our time.") frags = frags + 1 if killsToRs() < 6 or frags > 1 then + g_game.stop() modules.game_interface.forceExit() end end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/cast_food.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/cast_food.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/cast_food.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/cast_food.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/cavebot.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/cavebot.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/cavebot.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/cavebot.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/combo.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/combo.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/combo.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/combo.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/combo.otui b/modules/game_bot/default_configs/vBot_4.4/vBot/combo.otui similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/combo.otui rename to modules/game_bot/default_configs/vBot_4.4/vBot/combo.otui diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/configs.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/configs.lua similarity index 81% rename from modules/game_bot/default_configs/vBot_4.0/vBot/configs.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/configs.lua index 47e0d9b..45cd29a 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/configs.lua +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/configs.lua @@ -9,12 +9,22 @@ if not g_resources.directoryExists("/bot/".. configName .."/vBot_configs/") then g_resources.makeDir("/bot/".. configName .."/vBot_configs/") 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 = {} -local healBotFile = "/bot/" .. configName .. "/vBot_configs/".. name() .. " HealBot.json" +local healBotFile = "/bot/" .. configName .. "/vBot_configs/profile_".. profile .. "/HealBot.json" AttackBotConfig = {} -local attackBotFile = "/bot/" .. configName .. "/vBot_configs/".. name() .. " AttackBot.json" +local attackBotFile = "/bot/" .. configName .. "/vBot_configs/profile_".. profile .. "/AttackBot.json" SuppliesConfig = {} -local suppliesFile = "/bot/" .. configName .. "/vBot_configs/".. name() .. " Supplies.json" +local suppliesFile = "/bot/" .. configName .. "/vBot_configs/profile_".. profile .. "/Supplies.json" --healbot diff --git a/modules/game_bot/default_configs/vBot_4.4/vBot/depositer_config.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/depositer_config.lua new file mode 100644 index 0000000..568c825 --- /dev/null +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/depositer_config.lua @@ -0,0 +1,123 @@ +setDefaultTab("Cave") +local panelName = "specialDeposit" +local depositerPanel + +UI.Button("Stashing Settings", function() + depositerPanel:show() + depositerPanel:raise() + depositerPanel:focus() +end) + +if not storage[panelName] then + storage[panelName] = { + items = {}, + height = 380 + } +end + +local config = storage[panelName] + +depositerPanel = UI.createWindow('DepositerPanel', rootWidget) +depositerPanel:hide() +-- basic one +depositerPanel.CloseButton.onClick = function() + depositerPanel:hide() +end + +depositerPanel:setHeight(config.height or 380) +depositerPanel.onGeometryChange = function(widget, old, new) + if old.height == 0 then return end + config.height = new.height +end + +function arabicToRoman(n) + local t = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XI", "XII", "XIV", "XV", "XVI", "XVII"} + return t[n] +end + +local function refreshEntries() + depositerPanel.DepositerList:destroyChildren() + for _, entry in ipairs(config.items) do + local panel = g_ui.createWidget("StashItem", depositerPanel.DepositerList) + panel.name:setText(Item.create(entry.id):getMarketData().name) + for i, child in ipairs(panel:getChildren()) do + if child:getId() ~= "slot" then + child:setTooltip("Clear item or double click to remove entry.") + child.onDoubleClick = function(widget) + table.remove(config.items, table.find(entry)) + panel:destroy() + end + end + end + panel.item:setItemId(entry.id) + if entry.id > 0 then + panel.item:setImageSource('') + end + panel.item.onItemChange = function(widget) + local id = widget:getItemId() + if id < 100 then + table.remove(config.items, table.find(entry)) + panel:destroy() + else + for i, data in ipairs(config.items) do + if data.id == id then + warn("[Depositer Panel] Item already added!") + return + end + end + entry.id = id + panel.item:setImageSource('') + panel.name:setText(Item.create(entry.id):getMarketData().name) + if entry.index == 0 then + local window = modules.client_textedit.show(panel.slot, { + title = "Set depot for "..panel.name:getText(), + description = "Select depot to which item should be stashed, choose between 3 and 17", + validation = [[^([3-9]|1[0-7])$]] + }) + window.text:setText(entry.index) + schedule(50, function() + window:raise() + window:focus() + end) + end + end + end + if entry.id > 0 then + panel.slot:setText("Stash to depot: ".. entry.index) + end + panel.slot:setTooltip("Click to set stashing destination.") + panel.slot.onClick = function(widget) + local window = modules.client_textedit.show(widget, { + title = "Set depot for "..panel.name:getText(), + description = "Select depot to which item should be stashed, choose between 3 and 17", + validation = [[^([3-9]|1[0-7])$]] + }) + window.text:setText(entry.index) + schedule(50, function() + window:raise() + window:focus() + end) + end + panel.slot.onTextChange = function(widget, text) + local n = tonumber(text) + if n then + entry.index = n + widget:setText("Stash to depot: "..entry.index) + end + end + end +end +refreshEntries() + +depositerPanel.title.onDoubleClick = function(widget) + table.insert(config.items, {id=0, index=0}) + refreshEntries() +end + +function getStashingIndex(id) + for _, v in pairs(config.items) do + if v.id == id then + return v.index - 1 + end + end +end \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.4/vBot/depositer_config.otui b/modules/game_bot/default_configs/vBot_4.4/vBot/depositer_config.otui new file mode 100644 index 0000000..33dea64 --- /dev/null +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/depositer_config.otui @@ -0,0 +1,99 @@ +StashItem < Panel + height: 40 + + BotItem + id: item + anchors.top: parent.top + margin-top: 2 + anchors.left: parent.left + + 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-align:left + text: item name + font: verdana-11px-rounded + color: #FFFFFF + + UIWidget + id: slot + 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: Add item to select locker. + color: #CCCCCC + +DepositerPanel < MainWindow + size: 230 380 + !text: tr('Depositer Panel') + @onEscape: self:hide() + + UIWidget + id: title + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + text: Double click here to add item. + text-align: left + font: verdana-11px-rounded + color: #aeaeae + + ScrollablePanel + id: DepositerList + image-source: /images/ui/panel_flat + image-border: 1 + anchors.top: prev.bottom + margin-top: 5 + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: sep.top + margin-bottom: 10 + padding: 2 + padding-left: 4 + vertical-scrollbar: DepositerScrollBar + layout: + type: verticalBox + + VerticalScrollBar + id: DepositerScrollBar + anchors.top: DepositerList.top + anchors.bottom: DepositerList.bottom + anchors.right: DepositerList.right + step: 14 + pixels-scroll: true + visible: false + + ResizeBorder + id: bottomResizeBorder + anchors.fill: next + height: 3 + minimum: 180 + maximum: 800 + margin-left: 3 + margin-right: 3 + background: #ffffff88 + + HorizontalSeparator + id: sep + anchors.right: parent.right + anchors.left: parent.left + anchors.bottom: CloseButton.top + margin-bottom: 8 + + Button + id: CloseButton + !text: tr('Close') + font: cipsoftFont + anchors.right: parent.right + anchors.bottom: parent.bottom + size: 45 21 + margin-right: 5 \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/depot_withdraw.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/depot_withdraw.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/depot_withdraw.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/depot_withdraw.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/eat_food.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/eat_food.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/eat_food.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/eat_food.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/equip.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/equip.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/equip.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/equip.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/equipper.otui b/modules/game_bot/default_configs/vBot_4.4/vBot/equipper.otui similarity index 97% rename from modules/game_bot/default_configs/vBot_4.0/vBot/equipper.otui rename to modules/game_bot/default_configs/vBot_4.4/vBot/equipper.otui index 9f34696..d034146 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/equipper.otui +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/equipper.otui @@ -70,7 +70,7 @@ Rule < UIWidget ConditionPanel < Panel - height: 55 + height: 53 NexButton id: nex @@ -115,12 +115,8 @@ ConditionPanel < Panel - - - - ListPanel < FlatPanel - size: 270 265 + size: 270 300 padding-left: 10 padding-right: 10 padding-bottom: 10 @@ -218,10 +214,8 @@ Unequip < Panel - - InputPanel < FlatPanel - size: 270 265 + size: 270 300 padding-left: 10 padding-right: 10 padding-bottom: 10 @@ -240,12 +234,12 @@ InputPanel < FlatPanel anchors.right: parent.right anchors.top: parent.top margin-top: 10 - height: 40 + height: 80 layout: type: grid cell-size: 34 34 cell-spacing: 2 - num-columns: 9 + num-columns: 7 Button id: unequip @@ -303,7 +297,7 @@ InputPanel < FlatPanel anchors.left: parent.left anchors.right: parent.right anchors.top: prev.bottom - margin-top: 8 + margin-top: 3 HorizontalSeparator anchors.left: parent.left @@ -336,7 +330,7 @@ InputPanel < FlatPanel tooltip: On add above rule will be listed as Profile name - use friendly one! EquipWindow < MainWindow - size: 600 345 + size: 600 370 text: Equipment Manager @onEscape: self:hide() diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/exeta.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/exeta.lua similarity index 91% rename from modules/game_bot/default_configs/vBot_4.0/vBot/exeta.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/exeta.lua index 29d7a6c..324bad9 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/exeta.lua +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/exeta.lua @@ -7,7 +7,7 @@ if voc == 1 or voc == 11 then onCreatureHealthPercentChange(function(creature, healthPercent) if m.isOff() then return end if healthPercent > 15 then return end - if CaveBot.isOff() or TargetBot.isOff() or not isBuffed() then return end + if CaveBot.isOff() or TargetBot.isOff() then return end if modules.game_cooldown.isGroupCooldownIconActive(3) then return end if creature:getPosition() and getDistanceBetween(pos(),creature:getPosition()) > 1 then return end if canCast("exeta res") and now - lastCast > 6000 then diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/extras.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/extras.lua similarity index 77% rename from modules/game_bot/default_configs/vBot_4.0/vBot/extras.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/extras.lua index d8c31c7..756fdaf 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/extras.lua +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/extras.lua @@ -19,13 +19,24 @@ local rightPanel = extrasWindow.content.right local leftPanel = extrasWindow.content.left -- objects made by Kondrah - taken from creature editor, minor changes to adapt -local addCheckBox = function(id, title, defaultValue, dest) +local addCheckBox = function(id, title, defaultValue, dest, tooltip) local widget = UI.createWidget('ExtrasCheckBox', dest) widget.onClick = function() widget:setOn(not 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 widget:setText(title) + widget:setTooltip(tooltip) if settings[id] == nil then widget:setOn(defaultValue) else @@ -34,9 +45,11 @@ local addCheckBox = function(id, title, defaultValue, dest) settings[id] = widget:isOn() end -local addItem = function(id, title, defaultItem, dest) +local addItem = function(id, title, defaultItem, dest, tooltip) local widget = UI.createWidget('ExtrasItem', dest) widget.text:setText(title) + widget.text:setTooltip(tooltip) + widget.item:setTooltip(tooltip) widget.item:setItemId(settings[id] or defaultItem) widget.item.onItemChange = function(widget) settings[id] = widget:getItemId() @@ -44,18 +57,20 @@ local addItem = function(id, title, defaultItem, dest) settings[id] = settings[id] or defaultItem end -local addTextEdit = function(id, title, defaultValue, dest) +local addTextEdit = function(id, title, defaultValue, dest, tooltip) local widget = UI.createWidget('ExtrasTextEdit', dest) widget.text:setText(title) widget.textEdit:setText(settings[id] or defaultValue or "") + widget.text:setTooltip(tooltip) widget.textEdit.onTextChange = function(widget,text) settings[id] = text end settings[id] = settings[id] or defaultValue or "" end -local addScrollBar = function(id, title, min, max, defaultValue, dest) +local addScrollBar = function(id, title, min, max, defaultValue, dest, tooltip) local widget = UI.createWidget('ExtrasScrollBar', dest) + widget.text:setTooltip(tooltip) widget.scroll.onValueChange = function(scroll, value) widget.text:setText(title .. ": " .. value) if value == 0 then @@ -64,6 +79,7 @@ local addScrollBar = function(id, title, min, max, defaultValue, dest) settings[id] = value end widget.scroll:setRange(min, max) + widget.scroll:setTooltip(tooltip) if max-min > 1000 then widget.scroll:setStep(100) elseif max-min > 100 then @@ -86,20 +102,20 @@ UI.Separator() --- add callback (optional) --- optionals should be addionaly sandboxed (if true then end) -addItem("rope", "Rope Item", 9596, leftPanel) -addItem("shovel", "Shovel Item", 9596, leftPanel) -addItem("machete", "Machete Item", 9596, leftPanel) -addItem("scythe", "Scythe Item", 9596, leftPanel) -addScrollBar("talkDelay", "Global NPC Talk Delay", 0, 2000, 1000, leftPanel) -addScrollBar("looting", "Max Loot Distance", 0, 50, 40, leftPanel) -addScrollBar("huntRoutes", "Hunting Routes Limit", 0, 300, 50, leftPanel) -addScrollBar("killUnder", "Kill monsters below", 0, 100, 1, leftPanel) -addScrollBar("gotoMaxDistance", "Max GoTo Distance", 0, 127, 30, leftPanel) -addCheckBox("lootLast", "Start loot from last corpse", true, leftPanel) -addCheckBox("joinBot", "Join TargetBot and CaveBot", false, leftPanel) -addCheckBox("reachable", "Target only pathable mobs", false, leftPanel) +addItem("rope", "Rope Item", 9596, leftPanel, "This item will be used in various bot related scripts as default rope item.") +addItem("shovel", "Shovel Item", 9596, leftPanel, "This item will be used in various bot related scripts as default shovel item.") +addItem("machete", "Machete Item", 9596, leftPanel, "This item will be used in various bot related scripts as default machete item.") +addItem("scythe", "Scythe Item", 9596, leftPanel, "This item will be used in various bot related scripts as default scythe item.") +addScrollBar("talkDelay", "Global NPC Talk Delay", 0, 2000, 1000, leftPanel, "Breaks between each talk action in cavebot (time in miliseconds).") +addScrollBar("looting", "Max Loot Distance", 0, 50, 40, leftPanel, "Every loot corpse futher than set distance (in sqm) will be ignored and forgotten.") +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("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("gotoMaxDistance", "Max GoTo Distance", 0, 127, 30, leftPanel, "Maximum distance to next goto waypoint for the bot to try to reach.") +addCheckBox("lootLast", "Start loot from last corpse", true, leftPanel, "Looting sequence will be reverted and bot will start looting newest bodies.") +addCheckBox("joinBot", "Join TargetBot and CaveBot", false, leftPanel, "Cave and Target tabs will be joined into one.") +addCheckBox("reachable", "Target only pathable mobs", false, leftPanel, "Ignore monsters that can't be reached.") -addCheckBox("title", "Custom Window Title", true, rightPanel) +addCheckBox("title", "Custom Window Title", true, rightPanel, "Personalize OTCv8 window name according to character specific.") if true then local vocText = "" @@ -126,7 +142,7 @@ if true then end) end -addCheckBox("separatePm", "Open PM's in new Window", false, rightPanel) +addCheckBox("separatePm", "Open PM's in new Window", false, rightPanel, "PM's will be automatically opened in new tab after receiving one.") if true then onTalk(function(name, level, mode, text, channelId, pos) if mode == 4 and settings.separatePm then @@ -141,7 +157,7 @@ if true then end) end -addTextEdit("useAll", "Use All Hotkey", "space", rightPanel) +addTextEdit("useAll", "Use All Hotkey", "space", rightPanel, "Set hotkey for universal actions - rope, shovel, scythe, use, open doors") if true then local useId = { 34847, 1764, 21051, 30823, 6264, 5282, 20453, 20454, 20474, 11708, 11705, 6257, 6256, 2772, 27260, 2773, 1632, 1633, 1948, 435, 6252, 6253, 5007, 4911, @@ -149,7 +165,7 @@ if true then 31118, 20474, 5737, 5736, 5734, 5733, 31202, 31228, 31199, 31200, 33262, 30824, 5125, 5126, 5116, 5117, 8257, 8258, 8255, 8256, 5120, 30777, 30776, 23873, 23877, 5736, 6264, 31262, 31130, 31129, 6250, 6249, 5122, 30049, 7131, 7132, 7727 } - local shovelId = { 606, 593, 867 } + local shovelId = { 606, 593, 867, 608 } local ropeId = { 17238, 12202, 12935, 386, 421, 21966, 14238 } local macheteId = { 2130, 3696 } local scytheId = { 3653 } @@ -187,7 +203,7 @@ if true then end -addCheckBox("timers", "MW & WG Timers", true, rightPanel) +addCheckBox("timers", "MW & WG Timers", true, rightPanel, "Show times for Magic Walls and Wild Growths.") if true then local activeTimers = {} @@ -226,7 +242,7 @@ if true then end -addCheckBox("antiKick", "Anti - Kick", true, rightPanel) +addCheckBox("antiKick", "Anti - Kick", true, rightPanel, "Turn every 10 minutes to prevent kick.") if true then macro(600*1000, function() if not settings.antiKick then return end @@ -237,7 +253,7 @@ if true then end -addCheckBox("stake", "Skin Monsters", false, leftPanel) +addCheckBox("stake", "Skin Monsters", false, leftPanel, "Automatically skin & stake corpses when cavebot is enabled") if true then 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} @@ -245,35 +261,36 @@ if true then macro(500, function() if not CaveBot.isOn() or not settings.stake then return end for i, tile in ipairs(g_map.getTiles(posz())) do - for u,item in ipairs(tile:getItems()) do - if table.find(knifeBodies, item:getId()) and findItem(5908) then - CaveBot.delay(550) - useWith(5908, item) - return - end - if table.find(stakeBodies, item:getId()) and findItem(5942) then - CaveBot.delay(550) - useWith(5942, item) - return - end - if table.find(fishingBodies, item:getId()) and findItem(3483) then - CaveBot.delay(550) - useWith(3483, item) - return - end + local item = tile:getTopThing() + if item and item:isContainer() then + if table.find(knifeBodies, item:getId()) and findItem(5908) then + CaveBot.delay(550) + useWith(5908, item) + return end + if table.find(stakeBodies, item:getId()) and findItem(5942) then + CaveBot.delay(550) + useWith(5942, item) + return + end + if table.find(fishingBodies, item:getId()) and findItem(3483) then + CaveBot.delay(550) + useWith(3483, item) + return + end + end end end) end -addCheckBox("oberon", "Auto Reply Oberon", true, rightPanel) +addCheckBox("oberon", "Auto Reply Oberon", true, rightPanel, "Auto reply to Grand Master Oberon talk minigame.") if true then onTalk(function(name, level, mode, text, channelId, pos) if not settings.oberon then return end if mode == 34 then if string.find(text, "world will suffer for") then - say("Are you ever going to fight or do you prefer talking!") + say("Are you ever going to fight or do you prefer talking?") elseif string.find(text, "feet when they see me") then say("Even before they smell your breath?") elseif string.find(text, "from this plane") then @@ -296,9 +313,8 @@ if true then end -addCheckBox("autoOpenDoors", "Auto Open Doors", true, rightPanel) +addCheckBox("autoOpenDoors", "Auto Open Doors", true, rightPanel, "Open doors when trying to step on them.") if true then - local wsadWalking = modules.game_walking.wsadWalking local doorsIds = { 5007, 8265, 1629, 1632, 5129, 6252, 6249, 7715, 7712, 7714, 7719, 6256, 1669, 1672, 5125, 5115, 5124, 17701, 17710, 1642, 6260, 5107, 4912, 6251, 5291, 1683, 1696, 1692, 5006, 2179, 5116, @@ -316,6 +332,7 @@ if true then end onKeyPress(function(keys) + local wsadWalking = modules.game_walking.wsadWalking if not settings.autoOpenDoors then return end local pos = player:getPosition() if keys == 'Up' or (wsadWalking and keys == 'W') then @@ -344,7 +361,7 @@ if true then end -addCheckBox("bless", "Buy bless at login", true, rightPanel) +addCheckBox("bless", "Buy bless at login", true, rightPanel, "Say !bless at login.") if true then local blessed = false onTextMessage(function(mode,text) @@ -371,7 +388,7 @@ if true then end -addCheckBox("reUse", "Keep Crosshair", false, rightPanel) +addCheckBox("reUse", "Keep Crosshair", false, rightPanel, "Keep crosshair after using with item") if true then local excluded = {268, 237, 238, 23373, 266, 236, 239, 7643, 23375, 7642, 23374, 5908, 5942} @@ -388,7 +405,7 @@ if true then end -addCheckBox("suppliesControl", "TargetBot off if low supply", false, leftPanel) +addCheckBox("suppliesControl", "TargetBot off if low supply", false, leftPanel, "Turn off TargetBot if either one of supply amount is below 50% of minimum.") if true then macro(500, function() if not settings.suppliesControl then return end @@ -400,7 +417,7 @@ if true then end) end -addCheckBox("holdMwall", "Hold MW/WG", true, rightPanel) +addCheckBox("holdMwall", "Hold MW/WG", true, rightPanel, "Mark tiles with below hotkeys to automatically use Magic Wall or Wild Growth") addTextEdit("holdMwHot", "Magic Wall Hotkey: ", "F5", rightPanel) addTextEdit("holdWgHot", "Wild Growth Hotkey: ", "F6", rightPanel) if true then @@ -496,7 +513,7 @@ if true then end) end -addCheckBox("checkPlayer", "Check Players", true, rightPanel) +addCheckBox("checkPlayer", "Check Players", true, rightPanel, "Auto look on players and mark level and vocation on character model") if true then local found local function checkPlayers() @@ -561,8 +578,9 @@ if true then end) end -addCheckBox("title", "Open Next Loot Container", true, leftPanel) +addCheckBox("nextBackpack", "Open Next Loot Container", true, leftPanel, "Auto open next loot container if full - has to have the same ID.") local function openNextLootContainer() + if not settings.nextBackpack then return end local containers = getContainers() local lootCotaniersIds = CaveBot.GetLootContainers() @@ -591,4 +609,24 @@ if true then openNextLootContainer() 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 \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/extras.otui b/modules/game_bot/default_configs/vBot_4.4/vBot/extras.otui similarity index 98% rename from modules/game_bot/default_configs/vBot_4.0/vBot/extras.otui rename to modules/game_bot/default_configs/vBot_4.4/vBot/extras.otui index 49c88e4..d72f916 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/extras.otui +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/extras.otui @@ -2,7 +2,7 @@ ExtrasScrollBar < Panel height: 28 margin-top: 3 - Label + UIWidget id: text anchors.left: parent.left anchors.right: parent.right @@ -23,7 +23,7 @@ ExtrasTextEdit < Panel height: 40 margin-top: 7 - Label + UIWidget id: text anchors.left: parent.left anchors.right: parent.right @@ -47,7 +47,7 @@ ExtrasItem < Panel margin-left: 25 margin-right: 25 - Label + UIWidget id: text anchors.left: parent.left anchors.verticalCenter: next.verticalCenter diff --git a/modules/game_bot/default_configs/vBot_4.4/vBot/hold_target.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/hold_target.lua new file mode 100644 index 0000000..484bf85 --- /dev/null +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/hold_target.lua @@ -0,0 +1,30 @@ +setDefaultTab("Tools") + +local targetID = nil + +-- escape when attacking will reset hold target +onKeyPress(function(keys) + if keys == "Escape" and targetID then + targetID = nil + end +end) + +macro(100, "Hold Target", function() + -- if attacking then save it as target, but check pos z in case of marking by mistake on other floor + if target() and target():getPosition().z == posz() and not target():isNpc() then + targetID = target():getId() + elseif not target() then + -- there is no saved data, do nothing + if not targetID then return end + + -- look for target + for i, spec in ipairs(getSpectators()) do + local sameFloor = spec:getPosition().z == posz() + local oldTarget = spec:getId() == targetID + + if sameFloor and oldTarget then + attack(spec) + end + end + end +end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/ingame_editor.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/ingame_editor.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/ingame_editor.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/ingame_editor.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/items.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/items.lua similarity index 96% rename from modules/game_bot/default_configs/vBot_4.0/vBot/items.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/items.lua index 8c3e35a..312aa37 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/items.lua +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/items.lua @@ -1219,6 +1219,49 @@ LootItems = { ["zaoan sword"] = 30000, ["zaogun flag"] = 600, ["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 ["mana potion"] = 56, ["strong mana potion"] = 93, diff --git a/modules/game_bot/default_configs/vBot_4.4/vBot/main.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/main.lua new file mode 100644 index 0000000..59ecc78 --- /dev/null +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/main.lua @@ -0,0 +1,46 @@ +local version = "4.4" +local currentVersion +local hashcode +local available = false + +storage.checkVersion = storage.checkVersion or 0 + +-- check max once per 12hours +if os.time() > storage.checkVersion + (12 * 60 * 60) then + + storage.checkVersion = os.time() + + HTTP.get("https://raw.githubusercontent.com/Vithrax/vBot/main/vBot/version.txt", function(data, err) + if err then + warn("[vBot updater]: Unable to check version:\n" .. err) + return + end + + local t = string.split(data, ",") + currentVersion = t[1]:trim() + hashcode = t[2]:trim() + available = true + end) + +end + +UI.Label("vBot v".. version .." \n Vithrax#5814") +UI.Button("Official OTCv8 Discord!", function() g_platform.openUrl("https://discord.gg/yhqBE4A") end) +UI.Separator() + +schedule(5000, function() + if not available then return end + if currentVersion ~= version then + + UI.Separator() + local label = UI.Label("New vBot is available for download! v"..currentVersion) + label:setColor() + UI.Button("Get Hash Code", function() + g_window.setClipboardText(hashcode) + info("Hashcode copied to clipboard!") + end) + UI.Button("Go to vBot GitHub Page", function() g_platform.openUrl("https://github.com/Vithrax/vBot") end) + UI.Separator() + end + +end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.4/vBot/new healer.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/new healer.lua new file mode 100644 index 0000000..9e85304 --- /dev/null +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/new healer.lua @@ -0,0 +1,455 @@ +setDefaultTab("Main") +local panelName = "newHealer" +local ui = setupUI([[ +Panel + height: 19 + + BotSwitch + id: title + anchors.top: parent.top + anchors.left: parent.left + text-align: center + width: 130 + !text: tr('Friend Healer') + + Button + id: edit + anchors.top: prev.top + anchors.left: prev.right + anchors.right: parent.right + margin-left: 3 + height: 17 + text: Setup + +]]) +ui:setId(panelName) + +-- validate current settings +if not storage[panelName] or not storage[panelName].priorities then + storage[panelName] = nil +end + +if not storage[panelName] then + storage[panelName] = { + enabled = false, + customPlayers = {}, + vocations = {}, + groups = {}, + priorities = { + + {name="Custom Spell", enabled=false, custom=true}, + {name="Exura Gran Sio", enabled=true, strong = true}, + {name="Exura Sio", enabled=true, normal = true}, + {name="Exura Gran Mas Res", enabled=true, area = true}, + {name="Health Item", enabled=true, health=true}, + {name="Mana Item", enabled=true, mana=true} + + }, + settings = { + + {type="HealItem", text="Mana Item ", value=268}, + {type="HealScroll", text="Item Range: ", value=6}, + {type="HealItem", text="Health Item ", value=3160}, + {type="HealScroll", text="Mas Res Players: ", value=2}, + {type="HealScroll", text="Heal Friend at: ", value=80}, + {type="HealScroll", text="Use Gran Sio at: ", value=80}, + {type="HealScroll", text="Min Player HP%: ", value=80}, + {type="HealScroll", text="Min Player MP%: ", value=50}, + + }, + conditions = { + knights = true, + paladins = true, + druids = false, + sorcerers = false, + party = true, + guild = false, + botserver = false, + friends = false + } + } +end + +local config = storage[panelName] +local healerWindow = UI.createWindow('FriendHealer') +healerWindow:hide() +healerWindow:setId(panelName) + +ui.title:setOn(config.enabled) +ui.title.onClick = function(widget) + config.enabled = not config.enabled + widget:setOn(config.enabled) +end + +ui.edit.onClick = function() + healerWindow:show() + healerWindow:raise() + healerWindow:focus() +end + +local conditions = healerWindow.conditions +local targetSettings = healerWindow.targetSettings +local customList = healerWindow.customList +local priority = healerWindow.priority + +-- customList +-- create entries on the list +for name, health in pairs(config.customPlayers) do + local widget = UI.createWidget("HealerPlayerEntry", customList.playerList.list) + widget.remove.onClick = function() + config.customPlayers[name] = nil + widget:destroy() + end + widget:setText("["..health.."%] "..name) +end + +customList.playerList.onDoubleClick = function() + customList.playerList:hide() +end + +local function clearFields() + customList.addPanel.name:setText("friend name") + customList.addPanel.health:setText("1") + customList.playerList:show() +end + +local function capitalFistLetter(str) + return (string.gsub(str, "^%l", string.upper)) + end + +customList.addPanel.add.onClick = function() + local name = "" + local words = string.split(customList.addPanel.name:getText(), " ") + local health = tonumber(customList.addPanel.health:getText()) + for i, word in ipairs(words) do + name = name .. " " .. capitalFistLetter(word) + end + + if not health then + clearFields() + return warn("[Friend Healer] Please enter health percent value!") + end + + if name:len() == 0 or name:lower() == "friend name" then + clearFields() + return warn("[Friend Healer] Please enter friend name to be added!") + end + + if config.customPlayers[name] or config.customPlayers[name:lower()] then + clearFields() + return warn("[Friend Healer] Player already added to custom list.") + else + config.customPlayers[name] = health + local widget = UI.createWidget("HealerPlayerEntry", customList.playerList.list) + widget.remove.onClick = function() + config.customPlayers[name] = nil + widget:destroy() + end + widget:setText("["..health.."%] "..name) + end + + clearFields() +end + +local function validate(widget, category) + local list = widget:getParent() + local label = list:getParent().title + -- 1 - priorities | 2 - vocation + category = category or 0 + + if category == 2 and not storage.extras.checkPlayer then + label:setColor("#d9321f") + label:setTooltip("! WARNING ! \nTurn on check players in extras to use this feature!") + return + else + label:setColor("#dfdfdf") + label:setTooltip("") + end + + local checked = false + for i, child in ipairs(list:getChildren()) do + if category == 1 and child.enabled:isChecked() or child:isChecked() then + checked = true + end + end + + if not checked then + label:setColor("#d9321f") + label:setTooltip("! WARNING ! \nNo category selected!") + else + label:setColor("#dfdfdf") + label:setTooltip("") + end +end +-- targetSettings +targetSettings.vocations.box.knights:setChecked(config.conditions.knights) +targetSettings.vocations.box.knights.onClick = function(widget) + config.conditions.knights = not config.conditions.knights + widget:setChecked(config.conditions.knights) + validate(widget, 2) +end + +targetSettings.vocations.box.paladins:setChecked(config.conditions.paladins) +targetSettings.vocations.box.paladins.onClick = function(widget) + config.conditions.paladins = not config.conditions.paladins + widget:setChecked(config.conditions.paladins) + validate(widget, 2) +end + +targetSettings.vocations.box.druids:setChecked(config.conditions.druids) +targetSettings.vocations.box.druids.onClick = function(widget) + config.conditions.druids = not config.conditions.druids + widget:setChecked(config.conditions.druids) + validate(widget, 2) +end + +targetSettings.vocations.box.sorcerers:setChecked(config.conditions.sorcerers) +targetSettings.vocations.box.sorcerers.onClick = function(widget) + config.conditions.sorcerers = not config.conditions.sorcerers + widget:setChecked(config.conditions.sorcerers) + validate(widget, 2) +end + +targetSettings.groups.box.friends:setChecked(config.conditions.friends) +targetSettings.groups.box.friends.onClick = function(widget) + config.conditions.friends = not config.conditions.friends + widget:setChecked(config.conditions.friends) + validate(widget) +end + +targetSettings.groups.box.party:setChecked(config.conditions.party) +targetSettings.groups.box.party.onClick = function(widget) + config.conditions.party = not config.conditions.party + widget:setChecked(config.conditions.party) + validate(widget) +end + +targetSettings.groups.box.guild:setChecked(config.conditions.guild) +targetSettings.groups.box.guild.onClick = function(widget) + config.conditions.guild = not config.conditions.guild + widget:setChecked(config.conditions.guild) + validate(widget) +end + +targetSettings.groups.box.botserver:setChecked(config.conditions.botserver) +targetSettings.groups.box.botserver.onClick = function(widget) + config.conditions.botserver = not config.conditions.botserver + widget:setChecked(config.conditions.botserver) + validate(widget) +end + +validate(targetSettings.vocations.box.knights) +validate(targetSettings.groups.box.friends) +validate(targetSettings.vocations.box.sorcerers, 2) + +-- conditions +for i, setting in ipairs(config.settings) do + local widget = UI.createWidget(setting.type, conditions.box) + local text = setting.text + local val = setting.value + widget.text:setText(text) + + if setting.type == "HealScroll" then + widget.text:setText(widget.text:getText()..val) + if not (text:find("Range") or text:find("Mas Res")) then + widget.text:setText(widget.text:getText().."%") + end + widget.scroll:setValue(val) + widget.scroll.onValueChange = function(scroll, value) + setting.value = value + widget.text:setText(text..value) + if not (text:find("Range") or text:find("Mas Res")) then + widget.text:setText(widget.text:getText().."%") + end + end + if text:find("Range") or text:find("Mas Res") then + widget.scroll:setMaximum(10) + end + else + widget.item:setItemId(val) + widget.item:setShowCount(false) + widget.item.onItemChange = function(widget) + setting.value = widget:getItemId() + end + end +end + + + +-- priority and toggles +local function setCrementalButtons() + for i, child in ipairs(priority.list:getChildren()) do + if i == 1 then + child.increment:disable() + elseif i == 6 then + child.decrement:disable() + else + child.increment:enable() + child.decrement:enable() + end + end +end + +for i, action in ipairs(config.priorities) do + local widget = UI.createWidget("PriorityEntry", priority.list) + + widget:setText(action.name) + widget.increment.onClick = function() + local index = priority.list:getChildIndex(widget) + local table = config.priorities + + priority.list:moveChildToIndex(widget, index-1) + table[index], table[index-1] = table[index-1], table[index] + setCrementalButtons() + end + widget.decrement.onClick = function() + local index = priority.list:getChildIndex(widget) + local table = config.priorities + + priority.list:moveChildToIndex(widget, index+1) + table[index], table[index+1] = table[index+1], table[index] + setCrementalButtons() + end + widget.enabled:setChecked(action.enabled) + widget:setColor(action.enabled and "#98BF64" or "#dfdfdf") + widget.enabled.onClick = function() + action.enabled = not action.enabled + widget:setColor(action.enabled and "#98BF64" or "#dfdfdf") + widget.enabled:setChecked(action.enabled) + validate(widget, 1) + end + if action.custom then + widget.onDoubleClick = function() + local window = modules.client_textedit.show(widget, {title = "Custom Spell", description = "Enter below formula for a custom healing spell"}) + schedule(50, function() + window:raise() + window:focus() + end) + end + widget.onTextChange = function(widget,text) + action.name = text + end + widget:setTooltip("Double click to set spell formula.") + end + + if i == #config.priorities then + validate(widget, 1) + setCrementalButtons() + end +end + +local lastItemUse = now +local function friendHealerAction(spec, targetsInRange) + local name = spec:getName() + local health = spec:getHealthPercent() + local mana = spec:getManaPercent() + local dist = distanceFromPlayer(spec:getPosition()) + targetsInRange = targetsInRange or 0 + + local masResAmount = config.settings[4].value + local itemRange = config.settings[2].value + local healItem = config.settings[3].value + local manaItem = config.settings[1].value + local normalHeal = config.customPlayers[name] or config.settings[5].value + local strongHeal = config.customPlayers[name] and normalHeal/2 or config.settings[6].value + + for i, action in ipairs(config.priorities) do + if action.enabled then + if action.area and masResAmount <= targetsInRange and canCast("exura gran mas res") then + return say("exura gran mas res") + end + if action.mana and findItem(manaItem) and mana <= normalHeal and dist <= itemRange and now - lastItemUse > 1000 then + lastItemUse = now + return useWith(manaItem, spec) + end + if action.health and findItem(healItem) and health <= normalHeal and dist <= itemRange and now - lastItemUse > 1000 then + lastItemUse = now + return useWith(healItem, spec) + end + if action.strong and health <= strongHeal and not modules.game_cooldown.isCooldownIconActive(101) then + return say('exura gran sio "'..name) + end + if (action.normal or action.custom) and health <= normalHeal and canCast('exura sio "'..name) then + return say('exura sio "'..name) + end + end + end +end + +macro(100, function() + if not config.enabled then return end + if modules.game_cooldown.isGroupCooldownIconActive(2) then return end + + local minHp = config.settings[7].value + local minMp = config.settings[8].value + + -- first index will be heal target + local finalTable = {} + local inMasResRange = 0 + + -- check basic + if hppercent() <= minHp or manapercent() <= minMp then return end + + -- get all spectators + local spectators = getSpectators() + + -- clear table from irrelevant spectators + for i, spec in ipairs(getSpectators()) do + if spec:isLocalPlayer() or not spec:isPlayer() or not spec:canShoot() then + if not config.customPlayers[name] then + table.remove(spectators, table.find(spectators, spec)) + end + else + local specText = spec:getText() + -- check players is enabled and spectator already verified + if storage.extras.checkPlayer and specText:len() > 0 then + if specText:find("EK") and not config.conditions.knights or + specText:find("RP") and not config.conditions.paladins or + specText:find("ED") and not config.conditions.druids or + specText:find("MS") and not config.conditions.sorcerers then + if not config.customPlayers[name] then + table.remove(spectators, table.find(spectators, spec)) + end + end + end + local okParty = config.conditions.party and spec:isPartyMember() + local okFriend = config.conditions.friends and isFriend(spec) + local okGuild = config.conditions.guild and spec:getEmblem() == 1 + local okBotServer = config.conditions.botserver and vBot.BotServerMembers[spec:getName()] + if not (okParty or okFriend or okGuild or okBotServer) then + if not config.customPlayers[name] then + table.remove(spectators, table.find(spectators, spec)) + end + end + end + end + + -- no targets, return + if #spectators == 0 then return end + + for name, health in pairs(config.customPlayers) do + for i, spec in ipairs(spectators) do + local specHp = spec:getHealthPercent() + if spec:getName() == name and specHp <= health then + if distanceFromPlayer(spec:getPosition()) <= 2 then + inMasResRange = inMasResRange + 1 + end + table.insert(finalTable, spec) + table.remove(spectators, i) + end + end + end + + for i=1,#spectators do + local spec = spectators[i] + if distanceFromPlayer(spec:getPosition()) <= 3 then + inMasResRange = inMasResRange + 1 + end + table.insert(finalTable, spec) + end + + -- no targets, return + if #finalTable == 0 then return end + + friendHealerAction(finalTable[1], inMasResRange) +end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.4/vBot/new healer.otui b/modules/game_bot/default_configs/vBot_4.4/vBot/new healer.otui new file mode 100644 index 0000000..2eb55cc --- /dev/null +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/new healer.otui @@ -0,0 +1,413 @@ +CategoryCheckBox < CheckBox + font: verdana-11px-rounded + margin-top: 3 + + $checked: + color: #98BF64 + +HealScroll < Panel + + ToolTipLabel + id: text + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + text-align: center + text: test + + HorizontalScrollBar + id: scroll + anchors.left: parent.left + anchors.right: parent.right + anchors.top: prev.bottom + margin-top: 3 + minimum: 0 + maximum: 100 + step: 1 + +HealItem < Panel + + BotItem + id: item + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + size: 34 34 + + ToolTipLabel + id: text + anchors.fill: parent + anchors.left: prev.right + margin-left: 8 + text-wrap: true + text-align: left + +ToolTipLabel < UIWidget + font: verdana-11px-rounded + color: #dfdfdf + height: 14 + text-align: center + +HealerPlayerEntry < Label + background-color: alpha + text-offset: 5 1 + focusable: true + height: 16 + font: verdana-11px-rounded + text-align: left + + $focus: + background-color: #00000055 + + Button + id: remove + anchors.right: parent.right + margin-right: 2 + anchors.verticalCenter: parent.verticalCenter + size: 15 15 + margin-right: 15 + text: X + tooltip: Remove player from the list + +PriorityEntry < ToolTipLabel + background-color: alpha + text-offset: 18 1 + focusable: true + height: 16 + font: verdana-11px-rounded + text-align: left + + $focus: + background-color: #00000055 + + CheckBox + id: enabled + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + size: 15 15 + margin-top: 2 + margin-left: 3 + + Button + id: increment + anchors.right: parent.right + margin-right: 2 + anchors.verticalCenter: parent.verticalCenter + size: 14 14 + text: + + tooltip: Increase Priority + + Button + id: decrement + anchors.right: prev.left + margin-right: 2 + anchors.verticalCenter: parent.verticalCenter + size: 14 14 + text: - + tooltip: Decrease Priority + +TargetSettings < Panel + size: 280 125 + padding: 3 + image-source: /images/ui/window + image-border: 6 + + Label + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + font: verdana-11px-rounded + text: Heal Target Settings + + Groups + id: groups + anchors.top: prev.bottom + margin-top: 8 + anchors.left: parent.left + margin-left: 9 + + Vocations + id: vocations + anchors.left: prev.right + margin-left: 5 + anchors.verticalCenter: prev.verticalCenter + +Groups < FlatPanel + size: 150 90 + padding: 3 + padding-top: 5 + + ToolTipLabel + id: title + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + text: Groups + tooltip: Players added in custom list will always be in scope + + HorizontalSeparator + anchors.top: prev.bottom + margin-top: 2 + anchors.left: parent.left + anchors.right: parent.right + + Panel + id: box + anchors.top: prev.bottom + margin-top: 2 + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + padding: 2 + layout: + type: verticalBox + + CategoryCheckBox + id: friends + text: Friends + + CategoryCheckBox + id: party + text: Party Members + + CategoryCheckBox + id: guild + text: Guild Members + + CategoryCheckBox + id: botserver + text: BotServer Members + +Vocations < FlatPanel + size: 100 90 + padding: 3 + padding-top: 5 + + ToolTipLabel + id: title + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + font: verdana-11px-rounded + text: Vocations + + HorizontalSeparator + anchors.top: prev.bottom + margin-top: 2 + anchors.left: parent.left + anchors.right: parent.right + + Panel + id: box + anchors.top: prev.bottom + margin-top: 2 + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + padding: 2 + + layout: + type: verticalBox + + CategoryCheckBox + id: knights + text: Knights + + CategoryCheckBox + id: paladins + text: Paladins + + CategoryCheckBox + id: druids + text: Druids + + CategoryCheckBox + id: sorcerers + text: Sorcerers + +Priority < Panel + size: 190 123 + padding: 6 + padding-top: 3 + image-source: /images/ui/window + image-border: 6 + + ToolTipLabel + id: title + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + font: verdana-11px-rounded + text: Priority & Toggles + + TextList + id: list + anchors.top: prev.bottom + margin-top: 3 + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + fit-children: true + padding-top: 1 + +AddPlayer < FlatPanel + padding: 5 + + Label + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + font: verdana-11px-rounded + text: Add Player to Custom List + text-align: center + text-wrap: true + + HorizontalSeparator + anchors.top: prev.bottom + anchors.left: parent.left + anchors.right: parent.right + margin-top: 2 + + SpinBox + id: health + anchors.left: parent.left + anchors.top: prev.bottom + margin-top: 20 + width: 50 + minimum: 1 + maximum: 99 + step: 1 + focusable: true + text-align: center + + Label + anchors.verticalCenter: prev.verticalCenter + anchors.left: prev.right + margin-left: 3 + font: verdana-11px-rounded + text: %HP - heal if below + + TextEdit + id: name + anchors.top: health.bottom + margin-top: 5 + anchors.left: health.left + anchors.right: parent.right + font: verdana-11px-rounded + text-align: center + text: friend name + + Button + id: add + anchors.left: health.left + anchors.right: parent.right + anchors.top: prev.bottom + margin-top: 5 + font: verdana-11px-rounded + text: Add Player + +PlayerList < Panel + + TextList + id: list + anchors.fill: parent + fit-children: true + padding-top: 2 + vertical-scrollbar: listScrollBar + + VerticalScrollBar + id: listScrollBar + anchors.top: list.top + anchors.bottom: list.bottom + anchors.right: list.right + step: 14 + pixels-scroll: true + +CustomList < Panel + size: 190 172 + padding: 6 + padding-top: 3 + image-source: /images/ui/window + image-border: 6 + + ToolTipLabel + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + font: verdana-11px-rounded + text: Custom Player List + tooltip: Double click on the list below to add new player. + + AddPlayer + id: addPanel + anchors.top: prev.bottom + margin-top: 3 + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + + PlayerList + id: playerList + anchors.fill: prev + +Conditions < Panel + size: 280 170 + padding: 3 + image-source: /images/ui/window + image-border: 6 + + Label + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + font: verdana-11px-rounded + text: Player Conditions + + Panel + id: box + anchors.fill: parent + margin-top: 16 + padding: 5 + padding-top: 3 + layout: + type: grid + cell-size: 128 31 + cell-spacing: 5 + num-columns: 2 + +FriendHealer < MainWindow + !text: tr('Friend Healer') + size: 512 390 + padding-top: 30 + @onEscape: self:hide() + + Conditions + id: conditions + anchors.top: parent.top + anchors.right: parent.right + + TargetSettings + id: targetSettings + anchors.top: prev.bottom + margin-top: 10 + anchors.left: prev.left + + Priority + id: priority + anchors.top: parent.top + anchors.left: parent.left + + CustomList + id: customList + anchors.top: priority.bottom + margin-top: 10 + anchors.left: priority.left + + 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 + @onClick: self:getParent():hide() \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/new_cavebot_lib.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/new_cavebot_lib.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/new_cavebot_lib.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/new_cavebot_lib.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/npc_talk.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/npc_talk.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/npc_talk.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/npc_talk.lua diff --git a/modules/game_bot/default_configs/vBot_4.4/vBot/playerlist.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/playerlist.lua new file mode 100644 index 0000000..aad85fe --- /dev/null +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/playerlist.lua @@ -0,0 +1,272 @@ +setDefaultTab("Main") +local tabs = {"Friends", "Enemies", "BlackList"} +local panelName = "playerList" +local colors = {"#03C04A", "#fc4c4e", "orange"} + +if not storage[panelName] then + storage[panelName] = { + enemyList = {}, + friendList = {}, + blackList = {}, + groupMembers = true, + outfits = false, + marks = false, + highlight = false + } +end + +local config = storage[panelName] +local playerTables = {config.friendList, config.enemyList, config.blackList} + +-- 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 + + +rootWidget = g_ui.getRootWidget() +if rootWidget then + local ListWindow = UI.createWindow('PlayerListWindow', rootWidget) + ListWindow:hide() + + UI.Button("Player Lists", function() + ListWindow:show() + ListWindow:raise() + ListWindow:focus() + end) + + -- settings + ListWindow.settings.Members:setChecked(config.groupMembers) + ListWindow.settings.Members.onClick = function(widget) + config.groupMembers = not config.groupMembers + if not config.groupMembers then + clearCachedPlayers() + end + refreshStatus() + widget:setChecked(config.groupMembers) + end + ListWindow.settings.Outfit:setChecked(config.outfits) + ListWindow.settings.Outfit.onClick = function(widget) + config.outfits = not config.outfits + widget:setChecked(config.outfits) + refreshStatus() + end + ListWindow.settings.NeutralsAreEnemy:setChecked(config.marks) + ListWindow.settings.NeutralsAreEnemy.onClick = function(widget) + config.marks = not config.marks + widget:setChecked(config.marks) + end + ListWindow.settings.Highlight:setChecked(config.highlight) + ListWindow.settings.Highlight.onClick = function(widget) + config.highlight = not config.highlight + widget:setChecked(config.highlight) + end + + ListWindow.settings.AutoAdd:setChecked(config.autoAdd) + ListWindow.settings.AutoAdd.onClick = function(widget) + config.autoAdd = not config.autoAdd + widget:setChecked(config.autoAdd) + end + + local TabBar = ListWindow.tmpTabBar + TabBar:setContentWidget(ListWindow.tmpTabContent) + local blacklistList + + for v = 1, 3 do + local listPanel = g_ui.createWidget("tPanel") -- Creates Panel + local playerList = playerTables[v] + listPanel:setId(tabs[v].."Tab") + TabBar:addTab(tabs[v], listPanel) + + -- elements + local addButton = listPanel.add + local nameTab = listPanel.name + local list = listPanel.list + if v == 3 then + blacklistList = list + end + + for i, name in ipairs(playerList) do + local label = UI.createWidget("PlayerLabel", list) + label:setText(name) + label.remove.onClick = function() + table.remove(playerList, table.find(playerList, name)) + label:destroy() + clearCachedPlayers() + refreshStatus() + end + end + + local tabButton = TabBar.buttonsPanel:getChildren()[v] + + tabButton.onStyleApply = function(widget) + if TabBar:getCurrentTab() == widget then + widget:setColor(colors[v]) + end + end + + -- callbacks + addButton.onClick = function() + local names = string.split(nameTab:getText(), ",") + + if #names == 0 then + warn("vBot[PlayerList]: Name is missing!") + return + end + + for i=1,#names do + local name = names[i]:trim() + if name:len() == 0 then + warn("vBot[PlayerList]: Name is missing!") + else + if not table.find(playerList, name) then + table.insert(playerList, name) + local label = UI.createWidget("PlayerLabel", list) + label:setText(name) + label.remove.onClick = function() + table.remove(playerList, table.find(playerList, name)) + label:destroy() + end + nameTab:setText("") + else + warn("vBot[PlayerList]: Player ".. name .." is already added!") + nameTab:setText("") + end + clearCachedPlayers() + refreshStatus() + end + end + end + + nameTab.onKeyPress = function(widget, keyCode, keyboardModifiers) + if keyCode ~= 5 then + return false + end + addButton.onClick() + return true + end + end + + function addBlackListPlayer(name) + if table.find(config.blackList, name) then return end + + table.insert(config.blackList, name) + local label = UI.createWidget("PlayerLabel", blacklistList) + label:setText(name) + label.remove.onClick = function() + table.remove(playerList, table.find(playerList, name)) + label:destroy() + end + end +end + +onTextMessage(function(mode,text) + if not config.autoAdd then return end + if CaveBot.isOff() or TargetBot.isOff() then return end + if not text:find("Warning! The murder of") then return end + + text = string.split(text, "Warning! The murder of ")[1] + text = string.split(text, " was not justified.")[1] + + addBlackListPlayer(text) +end) + +onCreatureAppear(function(creature) + checkStatus(creature) + end) + + onPlayerPositionChange(function(x,y) + if x.z ~= y.z then + schedule(20, function() + refreshStatus() + end) + end + end) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.4/vBot/playerlist.otui b/modules/game_bot/default_configs/vBot_4.4/vBot/playerlist.otui new file mode 100644 index 0000000..a4f0d92 --- /dev/null +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/playerlist.otui @@ -0,0 +1,151 @@ +PlayerLabel < UIWidget + background-color: alpha + text-offset: 3 1 + focusable: true + height: 16 + font: verdana-11px-rounded + text-align: left + + $focus: + background-color: #00000055 + + Button + id: remove + !text: tr('X') + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + width: 14 + height: 14 + margin-right: 15 + text-align: center + text-offset: 0 1 + tooltip: Remove profile from the list. + +SettingCheckBox < CheckBox + text-wrap: true + text-auto-resize: true + margin-top: 3 + font: verdana-11px-rounded + +Settings < FlatPanel + padding: 6 + layout: + type: verticalBox + + Label + text: Additional Settings + text-align: center + font: verdana-11px-rounded + + HorizontalSeparator + + SettingCheckBox + id: Members + margin-top: 6 + text: Consider group members as friends. + + SettingCheckBox + id: Outfit + text: Color listed player outfits to red or blue. + + SettingCheckBox + id: NeutralsAreEnemy + text: Consider every non friend player as enemy. + + SettingCheckBox + id: Highlight + text: Hightlight listed players in red or blue color. + + SettingCheckBox + id: AutoAdd + text: Automatically add killed players while cave botting to blacklist. + +tPanel < Panel + margin: 3 + padding: 3 + + TextList + id: list + height: 200 + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + vertical-scrollbar: listScrollBar + + VerticalScrollBar + id: listScrollBar + anchors.top: list.top + anchors.bottom: list.bottom + anchors.right: list.right + step: 14 + pixels-scroll: true + + TextEdit + id: name + anchors.top: list.bottom + margin-top: 3 + anchors.left: parent.left + anchors.right: parent.right + + Button + id: add + text: Add Player + anchors.top: prev.bottom + margin-top: 3 + anchors.left: parent.left + anchors.right: parent.right + font: verdana-11px-rounded + +PlayerListWindow < MainWindow + !text: tr('Player List') + size: 405 356 + @onEscape: self:hide() + + TabBar + id: tmpTabBar + anchors.top: parent.top + anchors.left: parent.left + width: 180 + + FlatPanel + id: tmpTabContent + anchors.top: tmpTabBar.bottom + anchors.left: parent.left + width: 180 + anchors.bottom: separator.top + margin-bottom: 5 + + VerticalSeparator + id: verticalSep + anchors.top: parent.top + anchors.bottom: separator.top + margin-bottom: 5 + anchors.horizontalCenter: parent.horizontalCenter + + Settings + id: settings + anchors.left: prev.right + anchors.top: parent.top + anchors.right: parent.right + anchors.bottom: next.top + margin: 3 + margin-left: 6 + margin-bottom: 4 + + 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 + @onClick: self:getParent():hide() \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/pushmax.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/pushmax.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/pushmax.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/pushmax.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/pushmax.otui b/modules/game_bot/default_configs/vBot_4.4/vBot/pushmax.otui similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/pushmax.otui rename to modules/game_bot/default_configs/vBot_4.4/vBot/pushmax.otui diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/quiver_manager.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/quiver_manager.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/quiver_manager.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/quiver_manager.lua diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/siolist.otui b/modules/game_bot/default_configs/vBot_4.4/vBot/siolist.otui similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/siolist.otui rename to modules/game_bot/default_configs/vBot_4.4/vBot/siolist.otui diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/spy_level.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/spy_level.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/spy_level.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/spy_level.lua diff --git a/modules/game_bot/default_configs/vBot_4.4/vBot/supplies.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/supplies.lua new file mode 100644 index 0000000..4e99673 --- /dev/null +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/supplies.lua @@ -0,0 +1,383 @@ +function SuppliesPanel(parent) + local panelName = "supplies" + if not parent then + parent = panel + end + + local temp = nil + if SuppliesConfig[panelName] and SuppliesConfig[panelName].item1 then + temp = SuppliesConfig[panelName] + end + + +if not SuppliesConfig[panelName] or SuppliesConfig[panelName].item1 then + SuppliesConfig[panelName] = { + currentProfile = "Default", + ["Default"] = {} + } + if temp then + SuppliesConfig[panelName].Default = temp + end +end + +local currentProfile = SuppliesConfig[panelName].currentProfile +local config = SuppliesConfig[panelName][currentProfile] + +if not config then + for k,v in pairs(SuppliesConfig[panelName]) do + if type(v) == "table" then + SuppliesConfig[panelName].currentProfile = k + config = SuppliesConfig[panelName][k] + break + end + end +end + +rootWidget = g_ui.getRootWidget() +if rootWidget then + SuppliesWindow = UI.createWindow('SuppliesWindow', rootWidget) + SuppliesWindow:hide() + + SuppliesWindow.onVisibilityChange = function(widget, visible) + if not visible then + vBotConfigSave("supply") + end + end + + local function loadVariables() + config.item1 = config.item1 or 0 + config.item2 = config.item2 or 0 + config.item3 = config.item3 or 0 + config.item4 = config.item4 or 0 + config.item5 = config.item5 or 0 + config.item6 = config.item6 or 0 + config.item1Min = config.item1Min or 0 + config.item1Max = config.item1Max or 0 + config.item2Min = config.item2Min or 0 + config.item2Max = config.item2Max or 0 + config.item3Min = config.item3Min or 0 + config.item3Max = config.item3Max or 0 + config.item4Min = config.item4Min or 0 + config.item4Max = config.item4Max or 0 + config.item5Min = config.item5Min or 0 + config.item5Max = config.item5Max or 0 + config.item6Min = config.item6Min or 0 + config.item6Max = config.item6Max or 0 + config.capValue = config.capValue or 0 + config.staminaValue = config.staminaValue or 0 + end + loadVariables() + + local function setValues() + SuppliesWindow.capSwitch:setOn(config.capSwitch) + SuppliesWindow.SoftBoots:setOn(config.SoftBoots) + SuppliesWindow.imbues:setOn(config.imbues) + SuppliesWindow.staminaSwitch:setOn(config.staminaSwitch) + SuppliesWindow.item1:setItemId(config.item1) + SuppliesWindow.item2:setItemId(config.item2) + SuppliesWindow.item3:setItemId(config.item3) + SuppliesWindow.item4:setItemId(config.item4) + SuppliesWindow.item5:setItemId(config.item5) + SuppliesWindow.capValue:setText(config.capValue) + SuppliesWindow.item1Min:setText(config.item1Min) + SuppliesWindow.item1Max:setText(config.item1Max) + SuppliesWindow.item2Min:setText(config.item2Min) + SuppliesWindow.item2Max:setText(config.item2Max) + SuppliesWindow.item3Min:setText(config.item3Min) + SuppliesWindow.item3Max:setText(config.item3Max) + SuppliesWindow.item4Min:setText(config.item4Min) + SuppliesWindow.staminaValue:setText(config.staminaValue) + SuppliesWindow.item4Max:setText(config.item4Max) + SuppliesWindow.item5Min:setText(config.item5Min) + SuppliesWindow.item5Max:setText(config.item5Max) + SuppliesWindow.item6Min:setText(config.item6Min) + SuppliesWindow.item6Max:setText(config.item6Max) + end + setValues() + + local function refreshProfileList() + local profiles = SuppliesConfig[panelName] + + SuppliesWindow.profiles:destroyChildren() + for k,v in pairs(profiles) do + if type(v) == "table" then + local label = UI.createWidget("ProfileLabel", SuppliesWindow.profiles) + label:setText(k) + label:setTooltip("Click to load this profile. \nDouble click to change the name.") + label.remove.onClick = function() + local childs = SuppliesWindow.profiles:getChildCount() + if childs == 1 then + return info("vBot[Supplies] You need at least one profile!") + end + profiles[k] = nil + label:destroy() + vBotConfigSave("supply") + end + label.onDoubleClick = function(widget) + local window = modules.client_textedit.show(widget, {title = "Set Profile Name", description = "Enter a new name for selected profile"}) + schedule(50, function() + window:raise() + window:focus() + end) + end + label.onClick = function() + SuppliesConfig[panelName].currentProfile = label:getText() + config = SuppliesConfig[panelName][label:getText()] + loadVariables() + setValues() + vBotConfigSave("supply") + end + label.onTextChange = function(widget,text) + profiles[text] = profiles[k] + profiles[k] = nil + vBotConfigSave("supply") + end + end + end + end + refreshProfileList() + + local function setProfileFocus() + for i,v in ipairs(SuppliesWindow.profiles:getChildren()) do + local name = v:getText() + if name == SuppliesConfig[panelName].currentProfile then + return v:focus() + end + end + end + setProfileFocus() + + SuppliesWindow.newProfile.onClick = function() + local n = SuppliesWindow.profiles:getChildCount() + if n > 6 then + return info("vBot[Supplies] - max profile count reached!") + end + local name = "Profile #"..n+1 + SuppliesConfig[panelName][name] = {} + refreshProfileList() + setProfileFocus() + vBotConfigSave("supply") + end + + SuppliesWindow.capSwitch.onClick = function(widget) + config.capSwitch = not config.capSwitch + widget:setOn(config.capSwitch) + end + + SuppliesWindow.SoftBoots.onClick = function(widget) + config.SoftBoots = not config.SoftBoots + widget:setOn(config.SoftBoots) + end + + SuppliesWindow.imbues.onClick = function(widget) + config.imbues = not config.imbues + widget:setOn(config.imbues) + end + + SuppliesWindow.staminaSwitch.onClick = function(widget) + config.staminaSwitch = not config.staminaSwitch + widget:setOn(config.staminaSwitch) + end + + -- bot items + + SuppliesWindow.item1.onItemChange = function(widget) + config.item1 = widget:getItemId() + end + + SuppliesWindow.item2.onItemChange = function(widget) + config.item2 = widget:getItemId() + end + + SuppliesWindow.item3.onItemChange = function(widget) + config.item3 = widget:getItemId() + end + + SuppliesWindow.item4.onItemChange = function(widget) + config.item4 = widget:getItemId() + end + + SuppliesWindow.item5.onItemChange = function(widget) + config.item5 = widget:getItemId() + end + + SuppliesWindow.item6:setItemId(config.item6) + SuppliesWindow.item6.onItemChange = function(widget) + config.item6 = widget:getItemId() + end + + -- text windows + SuppliesWindow.capValue.onTextChange = function(widget, text) + local value = tonumber(SuppliesWindow.capValue:getText()) + if not value then + SuppliesWindow.capValue:setText(0) + config.capValue = 0 + else + text = text:match("0*(%d+)") + config.capValue = text + end + end + + SuppliesWindow.item1Min.onTextChange = function(widget, text) + local value = tonumber(SuppliesWindow.item1Min:getText()) + if not value then + SuppliesWindow.item1Min:setText(0) + config.item1Min = 0 + else + text = text:match("0*(%d+)") + config.item1Min = text + end + end + + SuppliesWindow.item1Max.onTextChange = function(widget, text) + local value = tonumber(SuppliesWindow.item1Max:getText()) + if not value then + SuppliesWindow.item1Max:setText(0) + config.item1Max = 0 + else + text = text:match("0*(%d+)") + config.item1Max = text + end + end + + SuppliesWindow.item2Min.onTextChange = function(widget, text) + local value = tonumber(SuppliesWindow.item2Min:getText()) + if not value then + SuppliesWindow.item2Min:setText(0) + config.item2Min = 0 + else + text = text:match("0*(%d+)") + config.item2Min = text + end + end + + SuppliesWindow.item2Max.onTextChange = function(widget, text) + local value = tonumber(SuppliesWindow.item2Max:getText()) + if not value then + SuppliesWindow.item2Max:setText(0) + config.item2Max = 0 + else + text = text:match("0*(%d+)") + config.item2Max = text + end + end + + SuppliesWindow.item3Min.onTextChange = function(widget, text) + local value = tonumber(SuppliesWindow.item3Min:getText()) + if not value then + SuppliesWindow.item3Min:setText(0) + config.item3Min = 0 + else + text = text:match("0*(%d+)") + config.item3Min = text + end + end + + SuppliesWindow.item3Max.onTextChange = function(widget, text) + local value = tonumber(SuppliesWindow.item3Max:getText()) + if not value then + SuppliesWindow.item3Max:setText(0) + config.item3Max = 0 + else + config.item3Max = text + end + end + + SuppliesWindow.item4Min.onTextChange = function(widget, text) + local value = tonumber(SuppliesWindow.item4Min:getText()) + if not value then + SuppliesWindow.item4Min:setText(0) + config.item4Min = 0 + else + text = text:match("0*(%d+)") + config.item4Min = text + end + end + + SuppliesWindow.staminaValue.onTextChange = function(widget, text) + local value = tonumber(SuppliesWindow.staminaValue:getText()) + if not value then + SuppliesWindow.staminaValue:setText(0) + config.staminaValue = 0 + else + text = text:match("0*(%d+)") + config.staminaValue = text + end + end + + SuppliesWindow.item4Max.onTextChange = function(widget, text) + local value = tonumber(SuppliesWindow.item4Max:getText()) + if not value then + SuppliesWindow.item4Max:setText(0) + config.item4Max = 0 + else + text = text:match("0*(%d+)") + config.item4Max = text + end + end + + SuppliesWindow.item5Min.onTextChange = function(widget, text) + local value = tonumber(SuppliesWindow.item5Min:getText()) + if not value then + SuppliesWindow.item5Min:setText(0) + config.item5Min = 0 + else + text = text:match("0*(%d+)") + config.item5Min = text + end + end + + SuppliesWindow.item5Max.onTextChange = function(widget, text) + local value = tonumber(SuppliesWindow.item5Max:getText()) + if not value then + SuppliesWindow.item5Max:setText(0) + config.item5Max = 0 + else + text = text:match("0*(%d+)") + config.item5Max = text + end + end + + SuppliesWindow.item6Min.onTextChange = function(widget, text) + local value = tonumber(SuppliesWindow.item6Min:getText()) + if not value then + SuppliesWindow.item6Min:setText(0) + config.item6Min = 0 + else + text = text:match("0*(%d+)") + config.item6Min = text + end + end + + SuppliesWindow.item6Max.onTextChange = function(widget, text) + local value = tonumber(SuppliesWindow.item6Max:getText()) + if not value then + SuppliesWindow.item6Max:setText(0) + config.item6Max = 0 + else + text = text:match("0*(%d+)") + config.item6Max = text + end + end + + Supplies = {} + Supplies.show = function() + SuppliesWindow:show() + SuppliesWindow:raise() + SuppliesWindow:focus() + end +end + +UI.Button("Supplies", function() + SuppliesWindow:show() + SuppliesWindow:raise() + SuppliesWindow:focus() +end) + +SuppliesWindow.close.onClick = function(widget) + SuppliesWindow:hide() +end +end + +UI.Separator() +SuppliesPanel(setDefaultTab("Cave")) \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/supplies.otui b/modules/game_bot/default_configs/vBot_4.4/vBot/supplies.otui similarity index 82% rename from modules/game_bot/default_configs/vBot_4.0/vBot/supplies.otui rename to modules/game_bot/default_configs/vBot_4.4/vBot/supplies.otui index 86e268b..7f86eab 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/supplies.otui +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/supplies.otui @@ -1,6 +1,30 @@ +ProfileLabel < UIWidget + background-color: alpha + text-offset: 3 1 + focusable: true + height: 16 + font: verdana-11px-rounded + text-align: left + + $focus: + background-color: #00000055 + + Button + id: remove + !text: tr('X') + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + width: 14 + height: 14 + margin-right: 3 + text-align: center + text-offset: 0 1 + tooltip: Remove profile from the list. + SuppliesWindow < MainWindow !text: tr('Supplies') size: 430 310 + @onEscape: self:hide() VerticalSeparator id: sep @@ -31,9 +55,10 @@ SuppliesWindow < MainWindow anchors.top: prev.bottom anchors.left: sep.right anchors.right: parent.right - margin-top: 10 + margin-top: 5 margin-left: 10 - text: No Soft + text: No Soft + tooltip: Go refill if there's no more active soft boots. BotSwitch id: capSwitch @@ -45,6 +70,7 @@ SuppliesWindow < MainWindow margin-right: 50 text-align: center text: Cap Below: + tooltip: Go refill if capacity is below set value. BotTextEdit id: capValue @@ -64,6 +90,7 @@ SuppliesWindow < MainWindow margin-right: 50 text-align: center text: Stamina: + tooltip: Go refill if stamina is below set value. (in minutes) BotTextEdit id: staminaValue @@ -81,6 +108,25 @@ SuppliesWindow < MainWindow margin-top: 5 margin-left: 10 text: No Imbues + tooltip: Go refill when mana leech imbue has worn off. + + TextList + id: profiles + anchors.top: prev.bottom + margin-top: 5 + anchors.left: prev.left + anchors.right: prev.right + anchors.bottom: close.top + margin-bottom: 20 + + BotButton + id: newProfile + anchors.left: prev.left + anchors.top: prev.bottom + size: 35 15 + text: New + font: cipsoftFont + tooltip: Create new supplies profile. BotItem id: item1 @@ -311,5 +357,5 @@ SuppliesWindow < MainWindow anchors.right: parent.right anchors.bottom: parent.bottom size: 45 21 - margin-top: 15 - margin-right: 5 \ No newline at end of file + margin-top: 15 + tooltip: Close supplies window and save settings. \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/tools.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/tools.lua similarity index 100% rename from modules/game_bot/default_configs/vBot_4.0/vBot/tools.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/tools.lua diff --git a/modules/game_bot/default_configs/vBot_4.4/vBot/version.txt b/modules/game_bot/default_configs/vBot_4.4/vBot/version.txt new file mode 100644 index 0000000..d54b7c3 --- /dev/null +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/version.txt @@ -0,0 +1 @@ +4.4,2e01326d0a \ No newline at end of file diff --git a/modules/game_bot/default_configs/vBot_4.0/vBot/vlib.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/vlib.lua similarity index 96% rename from modules/game_bot/default_configs/vBot_4.0/vBot/vlib.lua rename to modules/game_bot/default_configs/vBot_4.4/vBot/vlib.lua index a30e09d..bf1fc55 100644 --- a/modules/game_bot/default_configs/vBot_4.0/vBot/vlib.lua +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/vlib.lua @@ -18,6 +18,24 @@ function standTime() return now - vBot.standTime end +function relogOnCharacter(charName) + local characters = g_ui.getRootWidget().charactersWindow.characters + for index, child in ipairs(characters:getChildren()) do + local name = child:getChildren()[1]:getText() + + if name:lower():find(charName:lower()) then + child:focus() + schedule(100, modules.client_entergame.CharacterList.doLogin) + end + end +end + +function castSpell(text) + if canCast(text) then + say(text) + end +end + local dmgTable = {} local lastDmgMessage = now onTextMessage(function(mode, text) @@ -242,7 +260,6 @@ function cast(text, delay) local lastCast = SpellCastTable[text].t local spellDelay = SpellCastTable[text].d if now - lastCast > spellDelay then return say(text) end - return end -- canCast is a base for AttackBot and HealBot @@ -274,10 +291,6 @@ function canCast(spell, ignoreRL, ignoreCd) return true end --- exctracts data about spell from gamelib SpellInfo table --- returns table --- ie:['Spell Name'] = {id, words, exhaustion, premium, type, icon, mana, level, soul, group, vocations} --- cooldown detection module local lastPhrase = "" onTalk(function(name, level, mode, text, channelId, pos) if name == player:getName() then @@ -304,6 +317,11 @@ if onSpellCooldown and onGroupSpellCooldown then else warn("Outdated OTClient! update to newest version to take benefits from all scripts!") end + +-- exctracts data about spell from gamelib SpellInfo table +-- returns table +-- ie:['Spell Name'] = {id, words, exhaustion, premium, type, icon, mana, level, soul, group, vocations} +-- cooldown detection module function getSpellData(spell) if not spell then return false end spell = spell:lower() @@ -528,6 +546,16 @@ function getActiveItemId(id) return 23534 elseif id == 23529 then return 23530 + elseif id == 30343 then -- Sleep Shawl + return 30342 + elseif id == 30344 then -- Enchanted Pendulet + return 30345 + elseif id == 30403 then -- Enchanted Theurgic Amulet + return 30402 + elseif id == 31621 then -- Blister Ring + return 31616 + elseif id == 32621 then -- Ring of Souls + return 32635 else return id end @@ -566,6 +594,16 @@ function getInactiveItemId(id) return 23533 elseif id == 23530 then return 23529 + elseif id == 30342 then -- Sleep Shawl + return 30343 + elseif id == 30345 then -- Enchanted Pendulet + return 30344 + elseif id == 30402 then -- Enchanted Theurgic Amulet + return 30403 + elseif id == 31616 then -- Blister Ring + return 31621 + elseif id == 32635 then -- Ring of Souls + return 32621 else return id end @@ -745,6 +783,7 @@ end -- returns boolean function hasSupplies() local supplies = SuppliesConfig.supplies + supplies = supplies[supplies.currentProfile] local items = { {ID = supplies.item1, minAmount = supplies.item1Min}, {ID = supplies.item2, minAmount = supplies.item2Min}, diff --git a/modules/game_bot/default_configs/vBot_4.4/vBot/xeno_menu.lua b/modules/game_bot/default_configs/vBot_4.4/vBot/xeno_menu.lua new file mode 100644 index 0000000..2583500 --- /dev/null +++ b/modules/game_bot/default_configs/vBot_4.4/vBot/xeno_menu.lua @@ -0,0 +1,30 @@ +modules.game_interface.gameRootPanel.onMouseRelease = function(widget, mousePos, mouseButton) + if mouseButton == 2 then + local child = rootWidget:recursiveGetChildByPos(mousePos) + if child == widget then + local menu = g_ui.createWidget('PopupMenu') + menu:setId("blzMenu") + menu:setGameMenu(true) + menu:addOption('AttackBot', AttackBot.show, "OTCv8") + menu:addOption('HealBot', HealBot.show, "OTCv8") + menu:addOption('Conditions', Conditions.show, "OTCv8") + menu:addSeparator() + menu:addOption('CaveBot', function() + if CaveBot.isOn() then + CaveBot.setOff() + else + CaveBot.setOn() + end + end, CaveBot.isOn() and "ON " or "OFF ") + menu:addOption('TargetBot', function() + if TargetBot.isOn() then + TargetBot.setOff() + else + TargetBot.setOn() + end + end, TargetBot.isOn() and "ON " or "OFF ") + menu:display(mousePos) + return true + end + end +end \ No newline at end of file diff --git a/modules/game_bot/executor.lua b/modules/game_bot/executor.lua index 0798417..0566712 100644 --- a/modules/game_bot/executor.lua +++ b/modules/game_bot/executor.lua @@ -89,7 +89,6 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, relo context.pcall = pcall context.os = { time = os.time, - date = os.date, difftime = os.difftime, date = os.date, clock = os.clock @@ -118,6 +117,7 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, relo context.g_window = g_window context.g_mouse = g_mouse context.g_things = g_things + context.g_settings = g_settings context.g_platform = { openUrl = g_platform.openUrl, openDir = g_platform.openDir, diff --git a/modules/game_bot/functions/callbacks.lua b/modules/game_bot/functions/callbacks.lua index a8b088e..55b7a69 100644 --- a/modules/game_bot/functions/callbacks.lua +++ b/modules/game_bot/functions/callbacks.lua @@ -195,7 +195,7 @@ context.onManaChange = function(callback) return context.callback("onManaChange", callback) end --- onAddItem - callback = function(container, slot, item) +-- onAddItem - callback = function(container, slot, item, oldItem) context.onAddItem = function(callback) return context.callback("onAddItem", callback) end diff --git a/modules/game_interface/gameinterface.lua b/modules/game_interface/gameinterface.lua index 267523b..3b88522 100644 --- a/modules/game_interface/gameinterface.lua +++ b/modules/game_interface/gameinterface.lua @@ -3,8 +3,11 @@ gameMapPanel = nil gameRightPanels = nil gameLeftPanels = nil gameBottomPanel = nil -gameActionPanel = nil +gameBottomActionPanel = nil +gameLeftActionPanel = nil +gameRightActionPanel = nil gameLeftActions = nil +gameTopBar = nil logoutButton = nil mouseGrabberWidget = nil countWindow = nil @@ -47,7 +50,10 @@ function init() gameRightPanels = gameRootPanel:getChildById('gameRightPanels') gameLeftPanels = gameRootPanel:getChildById('gameLeftPanels') gameBottomPanel = gameRootPanel:getChildById('gameBottomPanel') - gameActionPanel = gameRootPanel:getChildById('gameActionPanel') + gameBottomActionPanel = gameRootPanel:getChildById('gameBottomActionPanel') + gameRightActionPanel = gameRootPanel:getChildById('gameRightActionPanel') + gameLeftActionPanel = gameRootPanel:getChildById('gameLeftActionPanel') + gameTopBar = gameRootPanel:getChildById('gameTopBar') gameLeftActions = gameRootPanel:getChildById('gameLeftActions') connect(gameLeftPanel, { onVisibilityChange = onLeftPanelVisibilityChange }) @@ -877,8 +883,20 @@ function getBottomPanel() return gameBottomPanel end -function getActionPanel() - return gameActionPanel +function getBottomActionPanel() + return gameBottomActionPanel +end + +function getLeftActionPanel() + return gameLeftActionPanel +end + +function getRightActionPanel() + return gameRightActionPanel +end + +function getTopBar() + return gameTopBar end function refreshViewMode() @@ -945,9 +963,10 @@ function refreshViewMode() if classic then g_game.changeMapAwareRange(19, 15) - gameMapPanel:addAnchor(AnchorLeft, 'gameLeftPanels', AnchorRight) - gameMapPanel:addAnchor(AnchorRight, 'gameRightPanels', AnchorLeft) - gameMapPanel:addAnchor(AnchorBottom, 'gameActionPanel', AnchorTop) + gameMapPanel:addAnchor(AnchorLeft, 'gameLeftActionPanel', AnchorRight) + gameMapPanel:addAnchor(AnchorRight, 'gameRightActionPanel', AnchorLeft) + gameMapPanel:addAnchor(AnchorBottom, 'gameBottomActionPanel', AnchorTop) + gameMapPanel:addAnchor(AnchorTop, 'gameTopBar', AnchorBottom) gameMapPanel:setKeepAspectRatio(true) gameMapPanel:setLimitVisibleRange(false) gameMapPanel:setZoom(11) diff --git a/modules/game_interface/gameinterface.otui b/modules/game_interface/gameinterface.otui index 533ceb5..664f168 100644 --- a/modules/game_interface/gameinterface.otui +++ b/modules/game_interface/gameinterface.otui @@ -96,6 +96,22 @@ UIWidget type: horizontalBox fit-children: true spacing: -1 + + Panel + id: gameLeftActionPanel + phantom: true + focusable: false + anchors.top: gameTopBar.bottom + anchors.left: gameLeftPanels.right + anchors.bottom: bottomSplitter.top + margin-top: 3 + + $mobile: + visible: false + + layout: + type: horizontalBox + fit-children: true Panel id: gameRightPanels @@ -107,6 +123,22 @@ UIWidget type: horizontalBox fit-children: true spacing: -1 + + Panel + id: gameRightActionPanel + phantom: true + focusable: false + anchors.top: gameTopBar.bottom + anchors.right: gameRightPanels.left + anchors.bottom: bottomSplitter.top + margin-top: 3 + + $mobile: + visible: false + + layout: + type: horizontalBox + fit-children: true Splitter id: bottomSplitter @@ -123,7 +155,7 @@ UIWidget visible: false Panel - id: gameActionPanel + id: gameBottomActionPanel phantom: true focusable: false @@ -145,9 +177,9 @@ UIWidget Panel id: gameBottomPanel $!mobile: - anchors.left: gameActionPanel.left - anchors.right: gameActionPanel.right - anchors.top: gameActionPanel.bottom + anchors.left: gameBottomActionPanel.left + anchors.right: gameBottomActionPanel.right + anchors.top: gameBottomActionPanel.bottom anchors.bottom: parent.bottom $mobile: @@ -159,3 +191,18 @@ UIWidget id: mouseGrabber focusable: false visible: false + + Panel + id: gameTopBar + image-source: /images/ui/panel_bottom2 + anchors.top: parent.top + anchors.left: gameBottomActionPanel.left + anchors.right: gameBottomActionPanel.right + focusable: false + + $mobile: + height: 0 + + layout: + type: verticalBox + fit-children: true \ No newline at end of file diff --git a/modules/game_interface/interface.otmod b/modules/game_interface/interface.otmod index b395028..4572b90 100644 --- a/modules/game_interface/interface.otmod +++ b/modules/game_interface/interface.otmod @@ -35,6 +35,7 @@ Module - game_shop - game_itemselector - client_textedit + - client_profiles - game_actionbar - game_prey - game_imbuing diff --git a/modules/game_market/market.lua b/modules/game_market/market.lua index 7bb7c78..5c6abb7 100644 --- a/modules/game_market/market.lua +++ b/modules/game_market/market.lua @@ -1402,7 +1402,7 @@ function Market.onMarketEnter(depotItems, offers, balance, vocation, items) end if g_game.isOnline() then - marketWindow:lock() + -- marketWindow:lock() marketWindow:show() end end diff --git a/modules/game_prey/prey.lua b/modules/game_prey/prey.lua index 3f61c0e..ef54d82 100644 --- a/modules/game_prey/prey.lua +++ b/modules/game_prey/prey.lua @@ -1,9 +1,8 @@ -- sponsored by kivera-global.com -- remade by Vithrax#5814 -local preyWindow -local preyButton -local preyTracker +preyWindow = nil +preyButton = nil local preyTrackerButton local msgWindow local bankGold = 0 diff --git a/modules/game_topbar/topbar.lua b/modules/game_topbar/topbar.lua new file mode 100644 index 0000000..0c5b9d2 --- /dev/null +++ b/modules/game_topbar/topbar.lua @@ -0,0 +1,500 @@ +Icons = {} +Icons[PlayerStates.Poison] = { + tooltip = tr('You are poisoned'), + path = '/images/game/states/poisoned', + id = 'condition_poisoned' +} +Icons[PlayerStates.Burn] = { + tooltip = tr('You are burning'), + path = '/images/game/states/burning', + id = 'condition_burning' +} +Icons[PlayerStates.Energy] = { + tooltip = tr('You are electrified'), + path = '/images/game/states/electrified', + id = 'condition_electrified' +} +Icons[PlayerStates.Drunk] = { + tooltip = tr('You are drunk'), + path = '/images/game/states/drunk', + id = 'condition_drunk' +} +Icons[PlayerStates.ManaShield] = { + tooltip = tr('You are protected by a magic shield'), + path = '/images/game/states/magic_shield', + id = 'condition_magic_shield' +} +Icons[PlayerStates.Paralyze] = { + tooltip = tr('You are paralysed'), + path = '/images/game/states/slowed', + id = 'condition_slowed' +} +Icons[PlayerStates.Haste] = { + tooltip = tr('You are hasted'), + path = '/images/game/states/haste', + id = 'condition_haste' +} +Icons[PlayerStates.Swords] = { + tooltip = tr('You may not logout during a fight'), + path = '/images/game/states/logout_block', + id = 'condition_logout_block' +} +Icons[PlayerStates.Drowning] = { + tooltip = tr('You are drowning'), + path = '/images/game/states/drowning', + id = 'condition_drowning' +} +Icons[PlayerStates.Freezing] = { + tooltip = tr('You are freezing'), + path = '/images/game/states/freezing', + id = 'condition_freezing' +} +Icons[PlayerStates.Dazzled] = { + tooltip = tr('You are dazzled'), + path = '/images/game/states/dazzled', + id = 'condition_dazzled' +} +Icons[PlayerStates.Cursed] = { + tooltip = tr('You are cursed'), + path = '/images/game/states/cursed', + id = 'condition_cursed' +} +Icons[PlayerStates.PartyBuff] = { + tooltip = tr('You are strengthened'), + path = '/images/game/states/strengthened', + id = 'condition_strengthened' +} +Icons[PlayerStates.PzBlock] = { + tooltip = tr('You may not logout or enter a protection zone'), + path = '/images/game/states/protection_zone_block', + id = 'condition_protection_zone_block' +} +Icons[PlayerStates.Pz] = { + tooltip = tr('You are within a protection zone'), + path = '/images/game/states/protection_zone', + id = 'condition_protection_zone' +} +Icons[PlayerStates.Bleeding] = { + tooltip = tr('You are bleeding'), + path = '/images/game/states/bleeding', + id = 'condition_bleeding' +} +Icons[PlayerStates.Hungry] = { + tooltip = tr('You are hungry'), + path = '/images/game/states/hungry', + id = 'condition_hungry' +} + +local iconsTable = { + ["Experience"] = 8, + ["Magic"] = 0, + ["Axe"] = 2, + ["Club"] = 1, + ["Distance"] = 3, + ["Fist"] = 4, + ["Shielding"] = 5, + ["Sword"] = 6, + ["Fishing"] = 7 +} + +local healthBar = nil +local manaBar = nil +local topBar = nil +local states = nil +local experienceTooltip = 'You have %d%% to advance to level %d.' +local settings = {} + +function init() + -- unfortunately won't work for mobile + if g_app.isMobile() then return end + + connect(LocalPlayer, { + onHealthChange = onHealthChange, + onManaChange = onManaChange, + onLevelChange = onLevelChange, + onStatesChange = onStatesChange, + onMagicLevelChange = onMagicLevelChange, + onBaseMagicLevelChange = onBaseMagicLevelChange, + onSkillChange = onSkillChange, + onBaseSkillChange = onBaseSkillChange + }) + connect(g_game, {onGameStart = refresh, onGameEnd = offline}) + + -- load condition icons + for k, v in pairs(Icons) do g_textures.preload(v.path) end + + if g_game.isOnline() then refresh() end +end + +function terminate() + -- unfortunately won't work for mobile + if g_app.isMobile() then return end + + disconnect(LocalPlayer, { + onHealthChange = onHealthChange, + onManaChange = onManaChange, + onLevelChange = onLevelChange, + onStatesChange = onStatesChange, + onMagicLevelChange = onMagicLevelChange, + onBaseMagicLevelChange = onBaseMagicLevelChange, + onSkillChange = onSkillChange, + onBaseSkillChange = onBaseSkillChange + }) + disconnect(g_game, {onGameStart = refresh, onGameEnd = offline}) +end + +function setupTopBar() + local topPanel = modules.game_interface.getTopBar() + topBar = topBar or g_ui.loadUI('TopBar', topPanel) + topBar = topBar or g_ui.createWidget('TopBar', topPanel) + + manaBar = topBar.stats.mana + healthBar = topBar.stats.health + states = topBar.stats.states.box + + topBar.onMouseRelease = function(widget, mousePos, mouseButton) + menu(mouseButton) + end +end + +function refresh(profileChange) + local player = g_game.getLocalPlayer() + if not player then return end + + setupTopBar() + load() + setupSkills() + show() + refreshVisibleBars() + + onLevelChange(player, player:getLevel(), player:getLevelPercent()) + onHealthChange(player, player:getHealth(), player:getMaxHealth()) + onManaChange(player, player:getMana(), player:getMaxMana()) + onMagicLevelChange(player, player:getMagicLevel(), player:getMagicLevelPercent()) + if not profileChange then + onStatesChange(player, player:getStates(), 0) + end + onHealthChange(player, player:getHealth(), player:getMaxHealth()) + onManaChange(player, player:getMana(), player:getMaxMana()) + onLevelChange(player, player:getLevel(), player:getLevelPercent()) + + for i = Skill.Fist, Skill.ManaLeechAmount do + onSkillChange(player, i, player:getSkillLevel(i), player:getSkillLevelPercent(i)) + onBaseSkillChange(player, i, player:getSkillBaseLevel(i)) + end + + topBar.skills.onGeometryChange = setSkillsLayout +end + +function refreshVisibleBars() + local ids = {"Experience", "Magic", "Axe", "Club", "Distance", "Fist", "Shielding", + "Sword", "Fishing"} + + for i, id in ipairs(ids) do + local panel = topBar[id] or topBar.skills[id] + + if panel then + -- experience is exeption + if id == "Experience" then + if not settings[id] then + panel:setVisible(true) + end + else + panel:setVisible(settings[id] or false) + end + end + end +end + +function setSkillsLayout() + local visible = 0 + local skills = topBar.skills + local width = skills:getWidth() + + for i, child in ipairs(skills:getChildren()) do + visible = child:isVisible() and visible + 1 or visible + end + + local many = visible > 1 + width = many and (width / 2) or width + + skills:getLayout():setCellSize({width = width, height = 19}) +end + +function offline() + local player = g_game.getLocalPlayer() + + if player then onStatesChange(player, 0, player:getStates()) end + save() +end + +function toggleIcon(bitChanged) + local content = states + + local icon = content:getChildById(Icons[bitChanged].id) + if icon then + icon:destroy() + else + icon = loadIcon(bitChanged) + icon:setParent(content) + end +end + +function loadIcon(bitChanged) + local icon = g_ui.createWidget('ConditionWidget', content) + icon:setId(Icons[bitChanged].id) + icon:setImageSource(Icons[bitChanged].path) + icon:setTooltip(Icons[bitChanged].tooltip) + return icon +end + +function onHealthChange(localPlayer, health, maxHealth) + if health > maxHealth then maxHealth = health end + + local healthPercent = (health / maxHealth) * 100 + healthBar:setText(comma_value(health) .. ' / ' .. comma_value(maxHealth)) + healthBar:setValue(health, 0, maxHealth) + healthBar:setPercent(healthPercent) + + if healthPercent > 92 then + healthBar:setBackgroundColor("#00BC00FF") + elseif healthPercent > 60 then + healthBar:setBackgroundColor("#50A150FF") + elseif healthPercent > 30 then + healthBar:setBackgroundColor("#A1A100FF") + elseif healthPercent > 8 then + healthBar:setBackgroundColor("#BF0A0AFF") + elseif healthPercent > 3 then + healthBar:setBackgroundColor("#910F0FFF") + else + healthBar:setBackgroundColor("#850C0CFF") + end +end + +function onManaChange(localPlayer, mana, maxMana) + if mana > maxMana then maxMana = mana end + + local manaPercent = (mana / maxMana) * 100 + if manaPercent < 0 then return end + manaBar:setText(comma_value(mana) .. ' / ' .. comma_value(maxMana)) + manaBar:setValue(mana, 0, maxMana) + manaBar:setPercent(manaPercent) +end + +function onLevelChange(localPlayer, value, percent) + local experienceBar = topBar.Experience.progress + local levelLabel = topBar.Experience.level + experienceBar:setTooltip(tr(experienceTooltip, 100-percent, value + 1)) + experienceBar:setPercent(percent) + levelLabel:setText(value) +end + +function onStatesChange(localPlayer, now, old) + if now == old then return end + + local bitsChanged = bit32.bxor(now, old) + for i = 1, 32 do + local pow = math.pow(2, i - 1) + if pow > bitsChanged then break end + local bitChanged = bit32.band(bitsChanged, pow) + if bitChanged ~= 0 then toggleIcon(bitChanged) end + end +end + +function show() + if not g_game.isOnline() then return end + topBar:setVisible(g_settings.getBoolean("topBar", false)) +end + +function setupSkillPanel(id, parent, experience, defaultOff) + local widget = g_ui.createWidget('SkillPanel', parent) + widget:setId(id) + widget.level:setTooltip(id) + widget.icon:setTooltip(id) + widget.icon:setImageClip({x = iconsTable[id]*9, y = 0, width = 9,height = 9}) + + if not experience then + widget.progress:setBackgroundColor('#00c000') + widget.shop:setVisible(false) + widget.shop:disable() + widget.shop:setWidth(0) + widget.progress:setMarginRight(1) + end + + settings[id] = settings[id] ~= nil and settings[id] or defaultOff + if settings[id] == false then widget:setVisible(false) end + + -- breakers + widget.onGeometryChange = function() + local margin = widget.progress:getWidth() / 4 + local left = widget.left + local right = widget.right + + left:setMarginRight(margin) + right:setMarginRight(margin) + end + +end + +function menu(mouseButton) + if mouseButton ~= 2 then return end + + local menu = g_ui.createWidget('PopupMenu') + menu:setId("topBarMenu") + menu:setGameMenu(true) + + local expPanel = topBar.Experience + local start = expPanel:isVisible() and "Hide" or "Show" + menu:addOption(start .. " Experience Level", + function() toggleSkillPanel(id) end) + for i, child in ipairs(topBar.skills:getChildren()) do + local id = child:getId() + if id ~= "stats" then + local start = child:isVisible() and "Hide" or "Show" + menu:addOption(start .. " " .. id .. " Level", + function() toggleSkillPanel(id) end) + end + end + + menu:display(mousePos) + return true +end + +function setupSkills() + local t = { + "Experience", "Magic", "Axe", "Club", "Distance", "Fist", "Shielding", + "Sword", "Fishing" + } + + for i, id in ipairs(t) do + if not topBar[id] and not topBar.skills[id] then + setupSkillPanel(id, i == 1 and topBar or topBar.skills, i == 1, + i == 1) + end + end + + local child = topBar.Experience + topBar:moveChildToIndex(child, 2) +end + +function toggleSkillPanel(id) + local panel = topBar.skills[id] + panel = panel or topBar.Experience + if not panel then return end + + panel:setVisible(not panel:isVisible()) + settings[id] = panel:isVisible() + setSkillsLayout() +end + +function setSkillValue(id, value) + local panel = topBar.skills[id] + if not panel then return end + + panel.level:setText(value) +end + +function setSkillPercent(id, percent, tooltip) + local panel = topBar.skills[id] + if not panel then return end + + panel.progress:setPercent(math.floor(percent)) +end + +function setSkillBase(id, value, baseValue) + local panel = topBar.skills[id] + if not panel then return end + + local progress = topBar.skills[id].progress + local progressDesc = "You have " .. 100 - math.floor(progress:getPercent()) .. " percent to go" + local level = topBar.skills[id].level + + if baseValue <= 0 or value < 0 then return end + + if value > baseValue then + level:setColor('#008b00') -- green + progress:setTooltip(value .. " = " .. baseValue .. ' + ' .. + (value - baseValue) .. "\n" .. progressDesc) + elseif value < baseValue then + level:setColor('#b22222') -- red + progress:setTooltip(baseValue .. ' ' .. (value - baseValue)) + else + level:setColor('#bbbbbb') -- default + progress:removeTooltip() + end + +end + +function onMagicLevelChange(localPlayer, magiclevel, percent) + setSkillValue('Magic', magiclevel) + setSkillPercent('Magic', percent) + + onBaseMagicLevelChange(localPlayer, localPlayer:getBaseMagicLevel()) +end + +function onBaseMagicLevelChange(localPlayer, baseMagicLevel) + setSkillBase('Magic', localPlayer:getMagicLevel(), baseMagicLevel) +end + +function onSkillChange(localPlayer, id, level, percent) + id = id + 1 + local t = { + "Fist", "Club", "Sword", "Axe", "Distance", "Shielding", "Fishing" + } + + -- imbues, ignore + if id > #t then return end + + setSkillValue(t[id], level) + setSkillPercent(t[id], percent) + + setSkillBase(t[id], level, localPlayer:getSkillBaseLevel(id - 1)) +end + +function onBaseSkillChange(localPlayer, id, baseLevel) + id = id + 1 + local t = { + "Fist", "Club", "Sword", "Axe", "Distance", "Shielding", "Fishing" + } + + -- imbues, ignore + if id > #t then return end + + setSkillBase(id, localPlayer:getSkillLevel(id), baseLevel) +end + +function save() + local settingsFile = modules.client_profiles.getSettingsFilePath("topbar.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("topbar.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 diff --git a/modules/game_topbar/topbar.otmod b/modules/game_topbar/topbar.otmod new file mode 100644 index 0000000..16d3f82 --- /dev/null +++ b/modules/game_topbar/topbar.otmod @@ -0,0 +1,10 @@ +Module + name: game_topbar + description: Customizable Top Bar from Cipsoft's Tibia 12 Client + author: Vithrax + discord: Vithrax#5814 + sandboxed: true + autoload: true + scripts: [ topbar ] + @onLoad: init() + @onUnload: terminate() \ No newline at end of file diff --git a/modules/game_topbar/topbar.otui b/modules/game_topbar/topbar.otui new file mode 100644 index 0000000..be8ce7e --- /dev/null +++ b/modules/game_topbar/topbar.otui @@ -0,0 +1,121 @@ +StatsPanel < Panel + height: 19 + + ProgressBar + id: health + anchors.left: parent.left + anchors.right: states.left + anchors.top: states.top + anchors.bottom: states.bottom + margin-right: 7 + + ProgressBar + id: mana + anchors.left: states.right + anchors.right: parent.right + anchors.top: states.top + anchors.bottom: states.bottom + margin-left: 7 + background-color: #0060d5 + + FlatPanel + id: states + padding: 1 + size: 150 18 + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + + Panel + id: box + image-source: /images/ui/dark_background + anchors.fill: parent + layout: + type: horizontalBox + +SkillPanel < Panel + height: 19 + + UIWidget + id: level + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + text: 999 + font: verdana-11px-rounded + text-align: center + margin-left: 7 + + UIWidget + id: icon + anchors.left: prev.right + anchors.verticalCenter: parent.verticalCenter + image-source: /images/game/topbar/icons + size: 9 9 + image-clip: 0 0 9 9 + margin-left: 7 + + ProgressBar + id: progress + anchors.left: prev.right + margin-left: 7 + anchors.right: next.left + margin-right: 7 + anchors.verticalCenter: parent.verticalCenter + background-color: #c00000 + height: 6 + border: 1 black + + UIWidget + id: shop + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + image-source: /images/game/topbar/boost + size: 76 14 + @onClick: modules.game_shop.show() + image-clip: 0 0 76 14 + + $pressed: + image-clip: 0 14 76 14 + + VerticalSeparator + id: left + anchors.top: progress.top + margin-top: -2 + anchors.bottom: progress.bottom + margin-bottom: -2 + anchors.right: progress.horizontalCenter + + VerticalSeparator + id: middle + anchors.top: progress.top + margin-top: -2 + anchors.bottom: progress.bottom + margin-bottom: -2 + anchors.right: progress.horizontalCenter + + VerticalSeparator + id: right + anchors.top: progress.top + margin-top: -2 + anchors.bottom: progress.bottom + margin-bottom: -2 + anchors.right: progress.right + +TopBar < Panel + id: topbar + focusable: false + padding-top: 4 + padding-left: 7 + padding-right: 7 + layout: + type: verticalBox + fit-children: true + + StatsPanel + id: stats + + Panel + id: skills + layout: + type: grid + num-columns: 2 + fit-children: true \ No newline at end of file diff --git a/otclient_dx.exe b/otclient_dx.exe index 138fa39..2f2094d 100644 Binary files a/otclient_dx.exe and b/otclient_dx.exe differ diff --git a/otclient_gl.exe b/otclient_gl.exe index 560cce2..c3a4bbc 100644 Binary files a/otclient_gl.exe and b/otclient_gl.exe differ diff --git a/otclient_linux b/otclient_linux index 55a3727..bd88107 100644 Binary files a/otclient_linux and b/otclient_linux differ diff --git a/otclient_mac b/otclient_mac index 01dbfed..abcec86 100644 Binary files a/otclient_mac and b/otclient_mac differ diff --git a/otclientv8.apk b/otclientv8.apk index 36e126a..436be83 100644 Binary files a/otclientv8.apk and b/otclientv8.apk differ