Version 1.3 - auto reconnect, better bot (with sound), animated mounts, bug fixes

This commit is contained in:
OTCv8
2019-11-11 17:10:03 +01:00
parent d78af570ea
commit 1072671986
48 changed files with 458 additions and 154 deletions

View File

@@ -64,7 +64,7 @@ function init()
g_window.setFullscreen(true)
else
-- window size
local size = { width = 800, height = 600 }
local size = { width = 1024, height = 600 }
size = g_settings.getSize('window-size', size)
g_window.resize(size)

View File

@@ -6,9 +6,12 @@ local loadBox
local characterList
local errorBox
local waitingWindow
local autoReconnectButton
local updateWaitEvent
local resendWaitEvent
local loginEvent
local autoReconnectEvent
local lastLogout = 0
-- private functions
local function tryLogin(charInfo, tries)
@@ -118,6 +121,7 @@ function onGameLoginError(message)
errorBox = nil
CharacterList.showAgain()
end
scheduleAutoReconnect()
end
function onGameLoginToken(unknown)
@@ -138,6 +142,7 @@ function onGameConnectionError(message, code)
errorBox = nil
CharacterList.showAgain()
end
scheduleAutoReconnect()
end
function onGameUpdateNeeded(signature)
@@ -146,7 +151,37 @@ function onGameUpdateNeeded(signature)
errorBox.onOk = function()
errorBox = nil
CharacterList.showAgain()
end
end
function onGameEnd()
CharacterList.showAgain()
scheduleAutoReconnect()
end
function onLogout()
lastLogout = g_clock.millis()
end
function scheduleAutoReconnect()
if lastLogout + 2000 > g_clock.millis() then
return
end
if autoReconnectEvent then
removeEvent(autoReconnectEvent)
end
autoReconnectEvent = scheduleEvent(executeAutoReconnect, 2500)
end
function executeAutoReconnect()
if not autoReconnectButton or not autoReconnectButton:isOn() then
return
end
if errorBox then
errorBox:destroy()
errorBox = nil
end
CharacterList.doLogin()
end
-- public functions
@@ -157,7 +192,8 @@ function CharacterList.init()
connect(g_game, { onConnectionError = onGameConnectionError })
connect(g_game, { onGameStart = CharacterList.destroyLoadBox })
connect(g_game, { onLoginWait = onLoginWait })
connect(g_game, { onGameEnd = CharacterList.showAgain })
connect(g_game, { onGameEnd = onGameEnd })
connect(g_game, { onLogout = onLogout })
if G.characters then
CharacterList.create(G.characters, G.characterAccount)
@@ -171,7 +207,8 @@ function CharacterList.terminate()
disconnect(g_game, { onConnectionError = onGameConnectionError })
disconnect(g_game, { onGameStart = CharacterList.destroyLoadBox })
disconnect(g_game, { onLoginWait = onLoginWait })
disconnect(g_game, { onGameEnd = CharacterList.showAgain })
disconnect(g_game, { onGameEnd = onGameEnd })
disconnect(g_game, { onLogout = onLogout })
if charactersWindow then
characterList = nil
@@ -217,6 +254,7 @@ function CharacterList.create(characters, account, otui)
charactersWindow = g_ui.displayUI(otui)
characterList = charactersWindow:getChildById('characters')
autoReconnectButton = charactersWindow:getChildById('autoReconnect')
-- characters
G.characters = characters
@@ -224,7 +262,6 @@ function CharacterList.create(characters, account, otui)
characterList:destroyChildren()
local accountStatusLabel = charactersWindow:getChildById('accountStatusLabel')
local focusLabel
for i,characterInfo in ipairs(characters) do
local widget = g_ui.createWidget('CharacterWidget', characterList)
@@ -262,6 +299,11 @@ function CharacterList.create(characters, account, otui)
characterList:focusChild(focusLabel, KeyboardFocusReason)
addEvent(function() characterList:ensureChildVisible(focusLabel) end)
end
characterList.onChildFocusChange = function()
removeEvent(autoReconnectEvent)
autoReconnectEvent = nil
end
-- account
local status = ''
@@ -286,6 +328,12 @@ function CharacterList.create(characters, account, otui)
else
accountStatusLabel:setOn(false)
end
autoReconnectButton.onClick = function(widget)
local autoReconnect = not g_settings.getBoolean('autoReconnect', true)
autoReconnectButton:setOn(autoReconnect)
g_settings.set('autoReconnect', autoReconnect)
end
end
function CharacterList.destroy()
@@ -303,9 +351,15 @@ function CharacterList.show()
charactersWindow:show()
charactersWindow:raise()
charactersWindow:focus()
local autoReconnect = g_settings.getBoolean('autoReconnect', true)
autoReconnectButton:setOn(autoReconnect)
end
function CharacterList.hide(showLogin)
removeEvent(autoReconnectEvent)
autoReconnectEvent = nil
showLogin = showLogin or false
charactersWindow:hide()
@@ -328,6 +382,9 @@ function CharacterList.isVisible()
end
function CharacterList.doLogin()
removeEvent(autoReconnectEvent)
autoReconnectEvent = nil
local selected = characterList:getFocusedChild()
if selected then
local charInfo = { worldHost = selected.worldHost,

View File

@@ -82,14 +82,12 @@ StaticMainWindow
id: accountStatusCaption
!text: tr('Account Status') .. ':'
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: next.top
margin-bottom: 1
anchors.bottom: separator.top
margin-bottom: 5
Label
id: accountStatusLabel
!text: tr('Free Account')
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: separator.top
margin-bottom: 5
@@ -105,16 +103,16 @@ StaticMainWindow
anchors.bottom: next.top
margin-bottom: 10
//CheckBox
// id: charAutoLoginBox
// !text: tr('Auto login')
// !tooltip: tr('Auto login selected character on next charlist load')
// anchors.left: parent.left
// anchors.right: parent.right
// anchors.bottom: next.top
// margin-bottom: 6
// margin-left: 18
// margin-right: 18
Button
id: autoReconnect
!text: tr('Auto reconnect: On')
width: 140
anchors.left: parent.left
anchors.bottom: parent.bottom
image-color: green
$!on:
image-color: red
!text: tr('Auto reconnect: Off')
Button
id: buttonOk

View File

@@ -19,7 +19,7 @@ local serverSelector
local clientVersionSelector
local serverHostTextEdit
local rememberPasswordBox
local protos = {"740", "760", "772", "800", "810", "854", "860", "1077", "1090", "1096", "1098", "1099"}
local protos = {"740", "760", "772", "800", "810", "854", "860", "1077", "1090", "1096", "1098", "1099", "1100"}
-- private functions

View File

@@ -59,12 +59,43 @@ function send()
position = localPlayer:getPosition()
}
end
local details = {
report_delay = sendInterval,
os = g_app.getOs(),
graphics_vendor = g_graphics.getVendor(),
graphics_renderer = g_graphics.getRenderer(),
graphics_version = g_graphics.getVersion(),
fps = g_app.getFps(),
maxFps = g_app.getMaxFps(),
atlas = g_atlas.getStats(),
classic = tostring(g_settings.getBoolean("classicView")),
fullscreen = tostring(g_window.isFullscreen()),
vsync = tostring(g_settings.getBoolean("vsync")),
window_width = g_window.getWidth(),
window_height = g_window.getHeight(),
player_name = g_game.getCharacterName(),
world_name = g_game.getWorldName(),
otserv_host = G.host,
otserv_protocol = g_game.getProtocolVersion(),
otserv_client = g_game.getClientVersion(),
build_version = g_app.getVersion(),
build_revision = g_app.getBuildRevision(),
build_commit = g_app.getBuildCommit(),
build_date = g_app.getBuildDate(),
display_width = g_window.getDisplayWidth(),
display_height = g_window.getDisplayHeight(),
cpu = g_platform.getCPUName(),
mem = g_platform.getTotalSystemMemory(),
os_name = g_platform.getOSName()
}
local data = json.encode({
text = text,
version = g_app.getVersion(),
host = g_settings.get('host'),
player = playerData
player = playerData,
details = details
})
postId = HTTP.post(Services.feedback, data, function(ret, err)
if err then
tries = tries + 1

View File

@@ -1,6 +1,6 @@
MainWindow
id: feedbackWindow
size: 300 280
size: 400 280
!text: tr("Feedback/Bug report")
Label
@@ -11,7 +11,7 @@ MainWindow
text-auto-resize: true
text-align: left
text-wrap: true
!text: tr("Bellow enter your feedback or bug report. Please include as much details as possible.")
!text: tr("Bellow enter your feedback or bug report. Please include as much details as possible. Thank you!")
MultilineTextEdit
id: text

View File

@@ -26,3 +26,23 @@ Panel
margin-top: 3
minimum: 0
maximum: 100
Label
id: botSoundVolumeLabel
!text: tr('Bot sound volume: %d', 100)
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 6
@onSetup: |
local value = modules.client_options.getOption('botSoundVolume')
self:setText(tr('Bot sound volume: %d', value))
OptionScrollbar
id: botSoundVolume
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 3
minimum: 0
maximum: 100

View File

@@ -26,11 +26,6 @@ Panel
!text: tr('Enable smart walking')
!tooltip: tr('Will detect when to use diagonal step based on the\nkeys you are pressing')
OptionCheckBox
id: realDirection
!text: tr('Show real direction (ignore walk direction)')
!tooltip: tr('Shows real creature direction while it\'s walking')
Label
anchors.top: prev.bottom
anchors.left: parent.left

View File

@@ -3,7 +3,7 @@ local defaultOptions = {
showFps = true,
showPing = true,
fullscreen = false,
classicView = false,
classicView = true,
classicControl = true,
smartWalk = false,
extentedPreWalking = true,
@@ -16,12 +16,13 @@ local defaultOptions = {
showPrivateMessagesInConsole = true,
showPrivateMessagesOnScreen = true,
rightPanels = 1,
leftPanels = 0,
leftPanels = 2,
containerPanel = 8,
backgroundFrameRate = 100,
enableAudio = false,
enableAudio = true,
enableMusicSound = false,
musicSoundVolume = 100,
botSoundVolume = 100,
enableLights = false,
floorFading = 500,
crosshair = 2,
@@ -235,6 +236,11 @@ function setOption(key, value, force)
g_sounds.getChannel(SoundChannels.Music):setGain(value/100)
end
audioPanel:getChildById('musicSoundVolumeLabel'):setText(tr('Music volume: %d', value))
elseif key == 'botSoundVolume' then
if g_sounds ~= nil then
g_sounds.getChannel(SoundChannels.Bot):setGain(value/100)
end
audioPanel:getChildById('botSoundVolumeLabel'):setText(tr('Bot sound volume: %d', value))
elseif key == 'showHealthManaCircle' then
modules.game_healthinfo.healthCircle:setVisible(value)
modules.game_healthinfo.healthCircleFront:setVisible(value)

View File

@@ -113,6 +113,7 @@ end
function setPingVisible(enable)
topMenu.pingLabel:setVisible(enable)
topMenu.reportBug:setVisible(enable)
end
function setFpsVisible(enable)

View File

@@ -22,7 +22,6 @@ TopMenuPanel
text-auto-resize: true
anchors.top: parent.top
anchors.left: leftGameButtonsPanel.right
anchors.right: rightGameButtonsPanel.left
TopMenuPingLabel
color: white
@@ -30,7 +29,19 @@ TopMenuPanel
text-auto-resize: true
anchors.top: fpsLabel.bottom
anchors.left: fpsLabel.left
anchors.right: fpsLabel.right
Button
id: reportBug
text: Report bug
text-align: center
color: white
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: leftGameButtonsPanel.right
margin-left: 80
margin-top: 5
margin-bottom: 5
@onClick: modules.client_feedback.show()
TopMenuButtonsPanel
id: rightButtonsPanel

View File

@@ -318,4 +318,5 @@ SoundChannels = {
Music = 1,
Ambient = 2,
Effect = 3,
Bot = 4
}

View File

@@ -166,6 +166,10 @@ function UIMiniWindow:setup()
if selfSettings.locked then
self:lock(true)
end
else
if not self.forceOpen and self.autoOpen ~= nil and (self.autoOpen == 0 or self.autoOpen == false) then
self:close(true)
end
end
end

View File

@@ -190,6 +190,8 @@ function UIMiniWindowContainer:order()
for i=1,#children do
if children[i].miniIndex then
self:swapInsert(children[i], children[i].miniIndex)
elseif children[i].autoOpen then
self:swapInsert(children[i], children[i].autoOpen)
end
end
end

View File

@@ -94,7 +94,6 @@ local function updateTabs(tabBar)
end
updateNavigation(tabBar)
updateMargins(tabBar)
if not tabBar.currentTab and #tabBar.tabs > 0 then
tabBar:selectTab(tabBar.tabs[1])
end
@@ -338,19 +337,18 @@ function UIMoveableTabBar:removeTab(tab)
if tabTable == nil then
return
end
table.remove(tabTable, index)
if self.currentTab == tab then
self:selectPrevTab()
if #self.tabs == 1 then
self.currentTab = nil
end
end
table.remove(tabTable, index)
if tab.blinkEvent then
removeEvent(tab.blinkEvent)
end
tab:destroy()
updateTabs(self)
tab:destroy()
end
function UIMoveableTabBar:getTab(text)

View File

@@ -43,6 +43,7 @@ MiniWindow
icon: /images/topbuttons/battle
@onClose: modules.game_battle.onMiniWindowClose()
&save: true
&autoOpen: false
Panel
id: filterPanel

View File

@@ -82,7 +82,7 @@ function init()
botButton:setOn(false)
botButton:hide()
botWindow = g_ui.loadUI('bot', modules.game_interface.getRightPanel())
botWindow = g_ui.loadUI('bot', modules.game_interface.getLeftPanel())
botWindow:setup()
contentsPanel = botWindow.contentsPanel
@@ -353,6 +353,10 @@ function clearConfig()
if gameMapPanel then
gameMapPanel:unlockVisibleFloor()
end
if g_sounds then
local botSoundChannel = g_sounds.getChannel(SoundChannels.Bot)
botSoundChannel:stop()
end
end
function refreshConfig()

View File

@@ -5,6 +5,7 @@ MiniWindow
icon: /images/topbuttons/bot
@onClose: modules.game_bot.onMiniWindowClose()
&save: true
&autoOpen: 10
MiniWindowContents
margin-left: 5

View File

@@ -3,10 +3,11 @@ botDefaultConfig = {
{name = "Default", script = [=[
--Default
--IMPORTANT
--In this config editions are not saved
--In 1st config (default) editions are not saved, just select and edit other config
--#main
--#panels
local healTab = addTab("HP")
local attackTab = addTab("Atck")
@@ -14,6 +15,21 @@ local warTab = addTab("War")
local caveTab = addTab("Cave")
Panels.TradeMessage()
Panels.AutoStackItems()
addButton("discord", "Discord & Help", function()
g_platform.openUrl("https://discord.gg/yhqBE4A")
end)
addButton("forum", "Forum", function()
g_platform.openUrl("https://otland.net/forums/otclient.494/")
end)
addButton("github", "Documentation", function()
g_platform.openUrl("https://github.com/OTCv8/otclientv8_bot")
end)
addSeparator("sep")
Panels.Haste(healTab)
Panels.ManaShield(healTab)
@@ -45,13 +61,6 @@ end, caveTab)
--#macros
addSeparator("sep1")
local helloLabel = addLabel("helloLabel", "")
macro(1000, "example macro (time)", nil, function()
helloLabel:setText("Time from start: " .. now)
end)
macro(1000, "this macro does nothing", "f7", function()
end)
@@ -91,6 +100,14 @@ singlehotkey("ctrl+f6", "singlehotkey", function()
usewith(268, player)
end)
singlehotkey("ctrl+f8", "play alarm", function()
playAlarm()
end)
singlehotkey("ctrl+f9", "stop alarm", function()
stopSound()
end)
--#callbacks
local positionLabel = addLabel("positionLabel", "")
@@ -98,6 +115,18 @@ onPlayerPositionChange(function()
positionLabel:setText("Pos: " .. posx() .. "," .. posy() .. "," .. posz())
end)
local s = addSwitch("sdSound", "Play sound when using sd", function(widget)
storage.sdSound = not storage.sdSound
widget:setOn(storage.sdSound)
end)
s:setOn(storage.sdSound)
onUseWith(function(pos, itemId)
if storage.sdSound and itemId == 3155 then
playSound("/sounds/magnum.ogg")
end
end)
--#other
macro(100, "hide useless tiles", "", function()

View File

@@ -84,7 +84,7 @@ context.onContainerOpen = function(callback)
return context.callback("onContainerOpen", callback)
end
-- onContainerUpdateItem -- callback = function(container)
-- onContainerClose -- callback = function(container)
context.onContainerClose = function(callback)
return context.callback("onContainerClose", callback)
end

View File

@@ -0,0 +1,31 @@
local context = G.botContext
context.getSoundChannel = function()
if not g_sounds then
return
end
return g_sounds.getChannel(SoundChannels.Bot)
end
context.playSound = function(file)
local botSoundChannel = context.getSoundChannel()
if not botSoundChannel then
return
end
botSoundChannel:setEnabled(true)
botSoundChannel:stop(0)
botSoundChannel:play(file, 0, 0)
return botSoundChannel
end
context.stopSound = function()
local botSoundChannel = context.getSoundChannel()
if not botSoundChannel then
return
end
botSoundChannel:stop()
end
context.playAlarm = function()
return context.playSound("/sounds/alarm.ogg")
end

View File

@@ -2,3 +2,9 @@ local context = G.botContext
context.encode = function(data) return json.encode(data) end
context.decode = function(text) local status, result = pcall(function() return json.decode(text) end) if status then return result end return {} end
context.displayGeneralBox = function(title, message, buttons, onEnterCallback, onEscapeCallback)
local box = displayGeneralBox(title, message, buttons, onEnterCallback, onEscapeCallback)
box.botWidget = true
return box
end

View File

@@ -10,7 +10,7 @@ Panels.MonsterEditor = function(monster, config, callback, parent)
local window = context.setupUI([[
MainWindow
id: monsterEditor
size: 450 430
size: 450 450
!text: tr("Edit monster")
Label
@@ -163,12 +163,24 @@ MainWindow
maximum: 100
step: 1
Label
id: dangerText
anchors.left: parent.left
anchors.right: parent.horizontalCenter
anchors.top: prev.bottom
margin-right: 5
margin-top: 10
text: If total danger is high (>8) bot won't auto loot until it's low again and will be trying to minimize it
text-align: center
text-wrap: true
text-auto-resize: true
Label
id: attackSpellText
anchors.left: parent.left
anchors.right: parent.horizontalCenter
anchors.top: prev.bottom
margin-right: 10
margin-right: 5
margin-top: 10
text: Attack spell and attack rune are only used when you have more than 30% health
text-align: center
@@ -600,7 +612,6 @@ Panel
local status, result = pcall(function() return json.decode(command.text) end)
if not status then
context.error("Invalid monster config: " .. commands[i].command .. ", error: " .. result)
print(command.text)
else
monsters[commands[i].command] = result
table.insert(labels, commands[i].command)
@@ -634,7 +645,7 @@ Panel
ui.config:addOption(name)
end
if not context.storage.attacking.activeConfig and #context.storage.attacking.configs > 0 then
if (not context.storage.attacking.activeConfig or context.storage.attacking.activeConfig == 0) and #context.storage.attacking.configs > 0 then
context.storage.attacking.activeConfig = 1
end
@@ -687,12 +698,26 @@ Panel
if not context.storage.attacking.activeConfig or not context.storage.attacking.configs[context.storage.attacking.activeConfig] then
return
end
context.storage.attacking.enabled = false
table.remove(context.storage.attacking.configs, context.storage.attacking.activeConfig)
context.storage.attacking.activeConfig = 0
refreshConfig()
local questionWindow = nil
local closeWindow = function()
questionWindow:destroy()
end
local removeConfig = function()
closeWindow()
if not context.storage.attacking.activeConfig or not context.storage.attacking.configs[context.storage.attacking.activeConfig] then
return
end
context.storage.attacking.enabled = false
table.remove(context.storage.attacking.configs, context.storage.attacking.activeConfig)
context.storage.attacking.activeConfig = 0
refreshConfig()
end
questionWindow = context.displayGeneralBox(tr('Remove config'), tr('Do you want to remove current attacking config?'), {
{ text=tr('Yes'), callback=removeConfig },
{ text=tr('No'), callback=closeWindow },
anchor=AnchorHorizontalCenter}, removeConfig, closeWindow)
end
ui.mAdd.onClick = function()
if not context.storage.attacking.activeConfig or not context.storage.attacking.configs[context.storage.attacking.activeConfig] then
@@ -745,7 +770,7 @@ Panel
return false
end
if monster:isPlayer() and config.monstersOnly then
if monster:isPlayer() and (config.monstersOnly == true or config.monstersOnly == nil) then
return false
end
@@ -770,7 +795,7 @@ Panel
return false
end
local pathTo = context.findPath(context.player:getPosition(), {x=mpos.x, y=mpos.y, z=mpos.z}, maxDistance + 2, { ignoreNonPathable = true, precision=1, allowOnlyVisibleTiles = true })
local pathTo = context.findPath(context.player:getPosition(), {x=mpos.x, y=mpos.y, z=mpos.z}, maxDistance + 2, { ignoreNonPathable = true, precision=1, allowOnlyVisibleTiles = true, ignoreCost = true })
if not pathTo or #pathTo > maxDistance + 1 then
return false
end
@@ -900,7 +925,7 @@ Panel
end
local topItem = tile:getTopUseThing()
if not topItem:isContainer() then
if not topItem or not topItem:isContainer() then
table.remove(lootContainers, 1)
return true
end

View File

@@ -229,7 +229,7 @@ Panel
ui.config:addOption(name)
end
if not context.storage.looting.activeConfig and #context.storage.looting.configs > 0 then
if (not context.storage.looting.activeConfig or context.storage.looting.activeConfig == 0) and #context.storage.looting.configs > 0 then
context.storage.looting.activeConfig = 1
end
@@ -286,12 +286,25 @@ Panel
if not context.storage.looting.activeConfig or not context.storage.looting.configs[context.storage.looting.activeConfig] then
return
end
context.storage.looting.enabled = false
table.remove(context.storage.looting.configs, context.storage.looting.activeConfig)
context.storage.looting.activeConfig = 0
refreshConfig()
local questionWindow = nil
local closeWindow = function()
questionWindow:destroy()
end
local removeConfig = function()
closeWindow()
if not context.storage.looting.activeConfig or not context.storage.looting.configs[context.storage.looting.activeConfig] then
return
end
context.storage.looting.enabled = false
table.remove(context.storage.looting.configs, context.storage.looting.activeConfig)
context.storage.looting.activeConfig = 0
refreshConfig()
end
questionWindow = context.displayGeneralBox(tr('Remove config'), tr('Do you want to remove current looting config?'), {
{ text=tr('Yes'), callback=removeConfig },
{ text=tr('No'), callback=closeWindow },
anchor=AnchorHorizontalCenter}, removeConfig, closeWindow)
end
refreshConfig()
context.onContainerOpen(function(container, prevContainer)
@@ -360,7 +373,7 @@ Panel
if item:getId() == foundItem:getId() then
if foundItem:isStackable() then
if item:getCount() ~= 100 then
g_game.move(foundItem, container:getSlotPosition(j), foundItem:getCount())
g_game.move(foundItem, container:getSlotPosition(j - 1), foundItem:getCount())
return
end
else

View File

@@ -14,4 +14,23 @@ Panels.TradeMessage = function(parent)
context.addTextEdit("autoTradeMessage", context.storage.autoTradeMessage or "I'm using OTClientV8 - https://github.com/OTCv8/otclientv8", function(widget, text)
context.storage.autoTradeMessage = text
end, parent)
end
Panels.AutoStackItems = function(parent)
context.macro(500, "Auto stacking items", nil, function()
local containers = context.getContainers()
for i, container in pairs(containers) do
local toStack = {}
for j, item in ipairs(container:getItems()) do
if item:isStackable() and item:getCount() ~= 100 then
local otherItem = toStack[item:getId()]
if otherItem then
g_game.move(item, otherItem, item:getCount())
return
end
toStack[item:getId()] = container:getSlotPosition(j - 1)
end
end
end
end, parent)
end

View File

@@ -27,7 +27,7 @@ Panels.AttackLeaderTarget = function(parent)
end
end)
context.macro(50, "Attack leader's target", nil, function()
if toAttack and context.storage.attackLeader:len() > 0 then
if toAttack and context.storage.attackLeader:len() > 0 and toAttack ~= g_game.getAttackingCreature() then
g_game.attack(toAttack)
toAttack = nil
end

View File

@@ -269,7 +269,7 @@ Panel
ui.config:addOption(name)
end
if not context.storage.cavebot.activeConfig and #context.storage.cavebot.configs > 0 then
if (not context.storage.cavebot.activeConfig or context.storage.cavebot.activeConfig == 0) and #context.storage.cavebot.configs > 0 then
context.storage.cavebot.activeConfig = 1
end
@@ -331,10 +331,24 @@ Panel
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
return
end
context.storage.cavebot.enabled = false
table.remove(context.storage.cavebot.configs, context.storage.cavebot.activeConfig)
context.storage.cavebot.activeConfig = 0
refreshConfig()
local questionWindow = nil
local closeWindow = function()
questionWindow:destroy()
end
local removeConfig = function()
closeWindow()
if not context.storage.cavebot.activeConfig or not context.storage.cavebot.configs[context.storage.cavebot.activeConfig] then
return
end
context.storage.cavebot.enabled = false
table.remove(context.storage.cavebot.configs, context.storage.cavebot.activeConfig)
context.storage.cavebot.activeConfig = 0
refreshConfig()
end
questionWindow = context.displayGeneralBox(tr('Remove config'), tr('Do you want to remove current waypoints config?'), {
{ text=tr('Yes'), callback=removeConfig },
{ text=tr('No'), callback=closeWindow },
anchor=AnchorHorizontalCenter}, removeConfig, closeWindow)
end
-- waypoint editor
@@ -733,7 +747,7 @@ Panel
ui.list:focusChild(nextChild)
commandExecutionNo = 0
end
end)
end)
return functions
end

View File

@@ -28,6 +28,7 @@ MiniWindow
icon: /images/topbuttons/cooldowns
@onClose: modules.game_cooldown.onMiniWindowClose()
&save: true
&autoOpen: false
MiniWindowContents
SpellGroupIcon

View File

@@ -7,7 +7,6 @@ function terminate()
end
function updateFeatures(version)
print(version)
g_game.resetFeatures()
-- you can add custom features here, list of them in modules\gamelib\const.lua
@@ -16,166 +15,170 @@ function updateFeatures(version)
--g_game.enableFeature(GameSpritesAlphaChannel)
if(version >= 770) then
g_game.enableFeature(GameLooktypeU16);
g_game.enableFeature(GameMessageStatements);
g_game.enableFeature(GameLoginPacketEncryption);
g_game.enableFeature(GameLooktypeU16)
g_game.enableFeature(GameMessageStatements)
g_game.enableFeature(GameLoginPacketEncryption)
end
if(version >= 780) then
g_game.enableFeature(GamePlayerAddons);
g_game.enableFeature(GamePlayerStamina);
g_game.enableFeature(GameNewFluids);
g_game.enableFeature(GameMessageLevel);
g_game.enableFeature(GamePlayerStateU16);
g_game.enableFeature(GameNewOutfitProtocol);
g_game.enableFeature(GamePlayerAddons)
g_game.enableFeature(GamePlayerStamina)
g_game.enableFeature(GameNewFluids)
g_game.enableFeature(GameMessageLevel)
g_game.enableFeature(GamePlayerStateU16)
g_game.enableFeature(GameNewOutfitProtocol)
end
if(version >= 790) then
g_game.enableFeature(GameWritableDate);
g_game.enableFeature(GameWritableDate)
end
if(version >= 840) then
g_game.enableFeature(GameProtocolChecksum);
g_game.enableFeature(GameAccountNames);
g_game.enableFeature(GameDoubleFreeCapacity);
g_game.enableFeature(GameProtocolChecksum)
g_game.enableFeature(GameAccountNames)
g_game.enableFeature(GameDoubleFreeCapacity)
end
if(version >= 841) then
g_game.enableFeature(GameChallengeOnLogin);
g_game.enableFeature(GameMessageSizeCheck);
g_game.enableFeature(GameTileAddThingWithStackpos);
g_game.enableFeature(GameChallengeOnLogin)
g_game.enableFeature(GameMessageSizeCheck)
g_game.enableFeature(GameTileAddThingWithStackpos)
end
if(version >= 854) then
g_game.enableFeature(GameCreatureEmblems);
g_game.enableFeature(GameCreatureEmblems)
end
if(version >= 860) then
g_game.enableFeature(GameAttackSeq);
g_game.enableFeature(GameAttackSeq)
end
if(version >= 862) then
g_game.enableFeature(GamePenalityOnDeath);
g_game.enableFeature(GamePenalityOnDeath)
end
if(version >= 870) then
g_game.enableFeature(GameDoubleExperience);
g_game.enableFeature(GamePlayerMounts);
g_game.enableFeature(GameSpellList);
g_game.enableFeature(GameDoubleExperience)
g_game.enableFeature(GamePlayerMounts)
g_game.enableFeature(GameSpellList)
end
if(version >= 910) then
g_game.enableFeature(GameNameOnNpcTrade);
g_game.enableFeature(GameTotalCapacity);
g_game.enableFeature(GameSkillsBase);
g_game.enableFeature(GamePlayerRegenerationTime);
g_game.enableFeature(GameChannelPlayerList);
g_game.enableFeature(GameEnvironmentEffect);
g_game.enableFeature(GameItemAnimationPhase);
g_game.enableFeature(GameNameOnNpcTrade)
g_game.enableFeature(GameTotalCapacity)
g_game.enableFeature(GameSkillsBase)
g_game.enableFeature(GamePlayerRegenerationTime)
g_game.enableFeature(GameChannelPlayerList)
g_game.enableFeature(GameEnvironmentEffect)
g_game.enableFeature(GameItemAnimationPhase)
end
if(version >= 940) then
g_game.enableFeature(GamePlayerMarket);
g_game.enableFeature(GamePlayerMarket)
end
if(version >= 953) then
g_game.enableFeature(GamePurseSlot);
g_game.enableFeature(GameClientPing);
g_game.enableFeature(GamePurseSlot)
g_game.enableFeature(GameClientPing)
end
if(version >= 960) then
g_game.enableFeature(GameSpritesU32);
g_game.enableFeature(GameOfflineTrainingTime);
g_game.enableFeature(GameSpritesU32)
g_game.enableFeature(GameOfflineTrainingTime)
end
if(version >= 963) then
g_game.enableFeature(GameAdditionalVipInfo);
g_game.enableFeature(GameAdditionalVipInfo)
end
if(version >= 980) then
g_game.enableFeature(GamePreviewState);
g_game.enableFeature(GameClientVersion);
g_game.enableFeature(GamePreviewState)
g_game.enableFeature(GameClientVersion)
end
if(version >= 981) then
g_game.enableFeature(GameLoginPending);
g_game.enableFeature(GameNewSpeedLaw);
g_game.enableFeature(GameLoginPending)
g_game.enableFeature(GameNewSpeedLaw)
end
if(version >= 984) then
g_game.enableFeature(GameContainerPagination);
g_game.enableFeature(GameBrowseField);
g_game.enableFeature(GameContainerPagination)
g_game.enableFeature(GameBrowseField)
end
if(version >= 1000) then
g_game.enableFeature(GameThingMarks);
g_game.enableFeature(GamePVPMode);
g_game.enableFeature(GameThingMarks)
g_game.enableFeature(GamePVPMode)
end
if(version >= 1035) then
g_game.enableFeature(GameDoubleSkills);
g_game.enableFeature(GameBaseSkillU16);
g_game.enableFeature(GameDoubleSkills)
g_game.enableFeature(GameBaseSkillU16)
end
if(version >= 1036) then
g_game.enableFeature(GameCreatureIcons);
g_game.enableFeature(GameHideNpcNames);
g_game.enableFeature(GameCreatureIcons)
g_game.enableFeature(GameHideNpcNames)
end
if(version >= 1038) then
g_game.enableFeature(GamePremiumExpiration);
g_game.enableFeature(GamePremiumExpiration)
end
if(version >= 1050) then
g_game.enableFeature(GameEnhancedAnimations);
g_game.enableFeature(GameEnhancedAnimations)
end
if(version >= 1053) then
g_game.enableFeature(GameUnjustifiedPoints);
g_game.enableFeature(GameUnjustifiedPoints)
end
if(version >= 1054) then
g_game.enableFeature(GameExperienceBonus);
g_game.enableFeature(GameExperienceBonus)
end
if(version >= 1055) then
g_game.enableFeature(GameDeathType);
g_game.enableFeature(GameDeathType)
end
if(version >= 1057) then
g_game.enableFeature(GameIdleAnimations);
g_game.enableFeature(GameIdleAnimations)
end
if(version >= 1061) then
g_game.enableFeature(GameOGLInformation);
g_game.enableFeature(GameOGLInformation)
end
if(version >= 1071) then
g_game.enableFeature(GameContentRevision);
g_game.enableFeature(GameContentRevision)
end
if(version >= 1072) then
g_game.enableFeature(GameAuthenticator);
g_game.enableFeature(GameAuthenticator)
end
if(version >= 1074) then
g_game.enableFeature(GameSessionKey);
g_game.enableFeature(GameSessionKey)
end
if(version >= 1080) then
g_game.enableFeature(GameIngameStore);
g_game.enableFeature(GameIngameStore)
end
if(version >= 1092) then
g_game.enableFeature(GameIngameStoreServiceType);
g_game.enableFeature(GameIngameStoreServiceType)
end
if(version >= 1093) then
g_game.enableFeature(GameIngameStoreHighlights);
g_game.enableFeature(GameIngameStoreHighlights)
end
if(version >= 1094) then
g_game.enableFeature(GameAdditionalSkills);
g_game.enableFeature(GameAdditionalSkills)
end
if(version >= 1100) then
g_game.enableFeature(GamePrey)
end
modules.game_things.load()

View File

@@ -134,6 +134,7 @@ MiniWindow
height: 123
@onClose: modules.game_healthinfo.onMiniWindowClose()
&save: true
&autoOpen: 2
MiniWindowContents
HealthBar

View File

@@ -728,6 +728,13 @@ function getRightPanel()
return gameRightPanels:getChildByIndex(-1)
end
function getLeftPanel()
if gameLeftPanels:getChildCount() >= 1 then
return gameLeftPanels:getChildByIndex(-1)
end
return getRightPanel()
end
function getContainerPanel()
local containerPanel = g_settings.getNumber("containerPanel")
if containerPanel >= 5 then

View File

@@ -34,6 +34,7 @@ inventoryWindow = nil
inventoryPanel = nil
inventoryButton = nil
purseButton = nil
marketButton = nil
combatControlsWindow = nil
fightOffensiveBox = nil
@@ -66,8 +67,9 @@ function init()
inventoryButton = modules.client_topmenu.addRightGameToggleButton('inventoryButton', tr('Inventory') .. ' (Ctrl+I)', '/images/topbuttons/inventory', toggle)
inventoryButton:setOn(true)
end
--[[
purseButton = inventoryPanel:getChildById('purseButton')
purseButton = inventoryWindow:recursiveGetChildById('purseButton')
marketButton = inventoryWindow:recursiveGetChildById('marketButton')
local function purseFunction()
local purse = g_game.getLocalPlayer():getInventoryItem(InventorySlotPurse)
if purse then
@@ -75,8 +77,8 @@ function init()
end
end
purseButton.onClick = purseFunction
]]--
-- controls
-- controls
fightOffensiveBox = inventoryWindow:recursiveGetChildById('fightOffensiveBox')
fightBalancedBox = inventoryWindow:recursiveGetChildById('fightBalancedBox')
fightDefensiveBox = inventoryWindow:recursiveGetChildById('fightDefensiveBox')
@@ -203,7 +205,8 @@ function refresh()
onStatesChange(player, player:getStates(), 0)
end
--purseButton:setVisible(g_game.getFeature(GamePurseSlot))
purseButton:setVisible(g_game.getFeature(GamePurseSlot))
marketButton:setVisible(g_game.getFeature(GamePurseSlot))
end
function toggle()

View File

@@ -72,14 +72,20 @@ AmmoSlot < InventoryItem
$on:
image-source: /images/game/slots/ammo-blessed
PurseButton < Button
PurseButton < UIButton
id: purseButton
size: 26 26
size: 24 24
!tooltip: tr('Open purse')
icon-source: /images/game/slots/purse
icon-size: 24 24
icon-offset: 1 1
MarketButton < UIButton
id: marketButton
size: 24 24
!tooltip: tr('Open Market')
icon-source: /images/game/slots/coins
icon-size: 24 24
CombatBox < UICheckBox
size: 20 20
image-clip: 0 0 20 20
@@ -91,7 +97,8 @@ CombatBox < UICheckBox
InventoryButton < Button
font: verdana-11px-antialised
height: 20
height: 18
margin-top: 1
SoulCapLabel < GameLabel
text-align: center
@@ -124,6 +131,7 @@ MiniWindow
height: 200
@onClose: modules.game_inventory.onMiniWindowClose()
&save: true
&autoOpen: 3
--&forceOpen: true
MiniWindowContents
@@ -254,6 +262,7 @@ MiniWindow
anchors.top: parent.top
Panel
id: buttonsPanel
margin-top: 4
margin-right: 5
anchors.fill: parent
@@ -265,10 +274,6 @@ MiniWindow
!text: tr('Stop')
@onClick: g_game.stop(); g_game.cancelAttackAndFollow()
InventoryButton
!text: tr('Quests')
@onClick: g_game.requestQuestLog()
InventoryButton
!text: tr('Options')
@onClick: modules.client_options.toggle()
@@ -280,3 +285,15 @@ MiniWindow
InventoryButton
!text: tr('Logout')
@onClick: modules.game_interface.tryLogout()
MarketButton
anchors.left: buttonsPanel.left
anchors.bottom: buttonsPanel.bottom
margin-bottom: 3
margin-left: 3
PurseButton
anchors.right: buttonsPanel.right
anchors.bottom: buttonsPanel.bottom
margin-bottom: 3
margin-right: 2

View File

@@ -5,6 +5,7 @@ MiniWindow
icon: /images/topbuttons/minimap
@onClose: modules.game_minimap.onMiniWindowClose()
&save: true
&autoOpen: 1
--&forceOpen: true
Label

View File

@@ -28,7 +28,7 @@ function init()
skillsButton = modules.client_topmenu.addRightGameToggleButton('skillsButton', tr('Skills'), '/images/topbuttons/skills', toggle)
skillsButton:setOn(true)
skillsWindow = g_ui.loadUI('skills', modules.game_interface.getRightPanel())
refresh()
skillsWindow:setup()
end

View File

@@ -40,6 +40,7 @@ MiniWindow
icon: /images/topbuttons/skills
@onClose: modules.game_skills.onMiniWindowClose()
&save: true
&autoOpen: false
MiniWindowContents
padding-left: 5

View File

@@ -18,6 +18,7 @@ MiniWindow
icon: /images/topbuttons/unjustifiedpoints
@onClose: modules.game_unjustifiedpoints.onMiniWindowClose()
&save: true
&autoOpen: false
MiniWindowContents
Label

View File

@@ -17,6 +17,7 @@ MiniWindow
icon: /images/topbuttons/viplist
@onClose: modules.game_viplist.onMiniWindowClose()
&save: true
&autoOpen: false
MiniWindowContents
layout: verticalBox

View File

@@ -157,6 +157,7 @@ GameIngameStoreHighlights = 74
GameIngameStoreServiceType = 75
GameAdditionalSkills = 76
GameDistanceEffectU16 = 77
GamePrey = 78
GameExtendedOpcode = 80
GameMinimapLimitedToSingleFloor = 81