mirror of
https://github.com/OTCv8/otclientv8.git
synced 2025-10-20 14:43:27 +02:00
Version 1.9
This commit is contained in:
330
modules/game_actionbar/actionbar.lua
Normal file
330
modules/game_actionbar/actionbar.lua
Normal file
@@ -0,0 +1,330 @@
|
||||
actionPanel1 = nil
|
||||
actionPanel2 = nil
|
||||
|
||||
local actionConfig
|
||||
local hotkeyAssignWindow
|
||||
local actionButtonsInPanel = 50
|
||||
|
||||
ActionTypes = {
|
||||
USE = 0,
|
||||
USE_SELF = 1,
|
||||
USE_TARGET = 2,
|
||||
USE_WITH = 3
|
||||
}
|
||||
|
||||
ActionColors = {
|
||||
empty = '#00000022',
|
||||
text = '#88888844',
|
||||
itemUse = '#8888FF44',
|
||||
itemUseSelf = '#00FF0044',
|
||||
itemUseTarget = '#FF000044',
|
||||
itemUseWith = '#F5B32544'
|
||||
}
|
||||
|
||||
function init()
|
||||
local bottomPanel = modules.game_interface.getBottomPanel()
|
||||
actionPanel1 = g_ui.loadUI('actionbar', bottomPanel)
|
||||
bottomPanel:moveChildToIndex(actionPanel1, 1)
|
||||
actionPanel2 = g_ui.loadUI('actionbar', bottomPanel)
|
||||
bottomPanel:moveChildToIndex(actionPanel2, 1)
|
||||
|
||||
actionConfig = g_configs.create("/actionbar.otml")
|
||||
|
||||
setupActionPanel(1, actionPanel1)
|
||||
setupActionPanel(2, actionPanel2)
|
||||
|
||||
connect(g_game, {
|
||||
onGameStart = online,
|
||||
onGameEnd = offline
|
||||
})
|
||||
|
||||
if g_game.isOnline() then
|
||||
show()
|
||||
end
|
||||
end
|
||||
|
||||
function terminate()
|
||||
disconnect(g_game, {
|
||||
onGameStart = online,
|
||||
onGameEnd = offline
|
||||
})
|
||||
|
||||
saveConfig()
|
||||
|
||||
-- remove hotkeys
|
||||
for index, panel in ipairs({actionPanel1, actionPanel2}) do
|
||||
for i, child in ipairs(panel.tabBar:getChildren()) do
|
||||
local gameRootPanel = modules.game_interface.getRootPanel()
|
||||
if child.hotkey then
|
||||
g_keyboard.unbindKeyPress(child.hotkey, child.callback, gameRootPanel)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
actionPanel1:destroy()
|
||||
actionPanel2:destroy()
|
||||
end
|
||||
|
||||
function show()
|
||||
actionPanel1:setOn(g_settings.getBoolean("actionBar1", false))
|
||||
actionPanel2:setOn(g_settings.getBoolean("actionBar2", false))
|
||||
end
|
||||
|
||||
function hide()
|
||||
actionPanel1:setOn(false)
|
||||
actionPanel2:setOn(false)
|
||||
end
|
||||
|
||||
function switchMode(newMode)
|
||||
if newMode then
|
||||
actionPanel1:setImageColor('#ffffff88')
|
||||
actionPanel2:setImageColor('#ffffff88')
|
||||
else
|
||||
actionPanel1:setImageColor('white')
|
||||
actionPanel2:setImageColor('white')
|
||||
end
|
||||
end
|
||||
|
||||
function online()
|
||||
show()
|
||||
end
|
||||
|
||||
function offline()
|
||||
hide()
|
||||
if hotkeyAssignWindow then
|
||||
hotkeyAssignWindow:destroy()
|
||||
hotkeyAssignWindow = nil
|
||||
end
|
||||
saveConfig()
|
||||
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
|
||||
for i=1,actionButtonsInPanel do
|
||||
local action = g_ui.createWidget('ActionButton', panel.tabBar)
|
||||
setupAction(index, action, config[i])
|
||||
end
|
||||
|
||||
panel.nextButton.onClick = function()
|
||||
panel.tabBar:moveChildToIndex(panel.tabBar:getLastChild(), 1)
|
||||
end
|
||||
panel.prevButton.onClick = function()
|
||||
panel.tabBar:moveChildToIndex(panel.tabBar:getFirstChild(), panel.tabBar:getChildCount())
|
||||
end
|
||||
end
|
||||
|
||||
function saveConfig()
|
||||
for index, panel in ipairs({actionPanel1, actionPanel2}) do
|
||||
local config = {}
|
||||
for i, child in ipairs(panel.tabBar:getChildren()) do
|
||||
table.insert(config, {
|
||||
text = child.text:getText(),
|
||||
item = child.item:getItemId(),
|
||||
count = child.item:getItemCount(),
|
||||
action = child.actionType,
|
||||
hotkey = child.hotkey
|
||||
})
|
||||
end
|
||||
actionConfig:setNode('actions_' .. index, config)
|
||||
end
|
||||
actionConfig:save()
|
||||
end
|
||||
|
||||
function setupAction(index, action, config)
|
||||
action.item:setShowCount(false)
|
||||
action.onMouseRelease = actionOnMouseRelease
|
||||
action.callback = function(k, c, ticks) executeAction(action, ticks) end
|
||||
|
||||
if config then
|
||||
action.hotkey = config.hotkey
|
||||
if action.hotkey then
|
||||
local gameRootPanel = modules.game_interface.getRootPanel()
|
||||
g_keyboard.bindKeyPress(action.hotkey, action.callback, gameRootPanel)
|
||||
end
|
||||
action.hotkeyLabel:setText(action.hotkey or "")
|
||||
action.text:setText(config.text)
|
||||
if action.text:getText():len() > 0 then
|
||||
action:setBorderColor(ActionColors.text)
|
||||
end
|
||||
if config.item > 0 then
|
||||
setupActionType(action, config.action)
|
||||
end
|
||||
action.item:setItemId(config.item)
|
||||
action.item:setItemCount(config.count)
|
||||
end
|
||||
|
||||
action.item.onItemChange = actionOnItemChange
|
||||
end
|
||||
|
||||
function setupActionType(action, actionType)
|
||||
action.actionType = actionType
|
||||
if action.actionType == ActionTypes.USE then
|
||||
action:setBorderColor(ActionColors.itemUse)
|
||||
elseif action.actionType == ActionTypes.USE_SELF then
|
||||
action:setBorderColor(ActionColors.itemUseSelf)
|
||||
elseif action.actionType == ActionTypes.USE_TARGET then
|
||||
action:setBorderColor(ActionColors.itemUseTarget)
|
||||
elseif action.actionType == ActionTypes.USE_WITH then
|
||||
action:setBorderColor(ActionColors.itemUseWith)
|
||||
end
|
||||
end
|
||||
|
||||
function executeAction(action, ticks)
|
||||
if type(ticks) ~= 'number' then ticks = 0 end
|
||||
|
||||
local actionDelay = 100
|
||||
if ticks == 0 then
|
||||
actionDelay = 200 -- for first use
|
||||
elseif action.actionDelayTo ~= nil and g_clock.millis() < action.actionDelayTo then
|
||||
return
|
||||
end
|
||||
|
||||
if action.text:getText():len() > 0 then
|
||||
modules.game_console.sendMessage(action.text:getText())
|
||||
action.actionDelayTo = g_clock.millis() + actionDelay
|
||||
elseif action.item:getItemId() > 0 then
|
||||
if action.actionType == ActionTypes.USE then
|
||||
if g_game.getClientVersion() < 740 then
|
||||
local item = g_game.findPlayerItem(action.item:getItemId(), hotKey.subType or -1)
|
||||
if item then
|
||||
g_game.use(item)
|
||||
end
|
||||
else
|
||||
g_game.useInventoryItem(action.item:getItemId())
|
||||
end
|
||||
action.actionDelayTo = g_clock.millis() + actionDelay
|
||||
elseif action.actionType == ActionTypes.USE_SELF then
|
||||
if g_game.getClientVersion() < 740 then
|
||||
local item = g_game.findPlayerItem(action.item:getItemId(), hotKey.subType or -1)
|
||||
if item then
|
||||
g_game.useWith(item, g_game.getLocalPlayer())
|
||||
end
|
||||
else
|
||||
g_game.useInventoryItemWith(action.item:getItemId(), g_game.getLocalPlayer(), action.item:getItemSubType() or -1)
|
||||
end
|
||||
action.actionDelayTo = g_clock.millis() + actionDelay
|
||||
elseif action.actionType == ActionTypes.USE_TARGET then
|
||||
local attackingCreature = g_game.getAttackingCreature()
|
||||
if not attackingCreature then
|
||||
local item = Item.create(action.item:getItemId())
|
||||
if g_game.getClientVersion() < 740 then
|
||||
local tmpItem = g_game.findPlayerItem(action.item:getItemId(), action.item:getItemSubType() or -1)
|
||||
if not tmpItem then return end
|
||||
item = tmpItem
|
||||
end
|
||||
|
||||
modules.game_interface.startUseWith(item, action.item:getItemSubType() or - 1)
|
||||
return
|
||||
end
|
||||
|
||||
if not attackingCreature:getTile() then return end
|
||||
if g_game.getClientVersion() < 740 then
|
||||
local item = g_game.findPlayerItem(action.item:getItemId(), action.item:getItemSubType() or -1)
|
||||
if item then
|
||||
g_game.useWith(item, attackingCreature, action.item:getItemSubType() or -1)
|
||||
end
|
||||
else
|
||||
g_game.useInventoryItemWith(action.item:getItemId(), attackingCreature, action.item:getItemSubType() or -1)
|
||||
end
|
||||
action.actionDelayTo = g_clock.millis() + actionDelay
|
||||
elseif action.actionType == ActionTypes.USE_WITH then
|
||||
local item = Item.create(action.item:getItemId())
|
||||
if g_game.getClientVersion() < 740 then
|
||||
local tmpItem = g_game.findPlayerItem(action.item:getItemId(), action.item:getItemSubType() or -1)
|
||||
if not tmpItem then return true end
|
||||
item = tmpItem
|
||||
end
|
||||
modules.game_interface.startUseWith(item, action.item:getItemSubType() or - 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function actionOnMouseRelease(action, mousePosition, mouseButton)
|
||||
if mouseButton == MouseRightButton then
|
||||
local menu = g_ui.createWidget('PopupMenu')
|
||||
menu:setGameMenu(true)
|
||||
if action.item:getItemId() > 0 and action.item:getItem():isMultiUse() then
|
||||
menu:addOption(tr('Use on yourself'), function() return setupActionType(action, ActionTypes.USE_SELF) end)
|
||||
menu:addOption(tr('Use on target'), function() return setupActionType(action, ActionTypes.USE_TARGET) end)
|
||||
menu:addOption(tr('With crosshair'), function() return setupActionType(action, ActionTypes.USE_WITH) end)
|
||||
end
|
||||
menu:addSeparator()
|
||||
menu:addOption(tr('Set text'), function()
|
||||
modules.game_textedit.singlelineEditor(action.text:getText(), function(newText)
|
||||
action.item:setItemId(0)
|
||||
action.text:setText(newText)
|
||||
if action.text:getText():len() > 0 then
|
||||
action:setBorderColor(ActionColors.text)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
menu:addOption(tr('Set hotkey'), function()
|
||||
if hotkeyAssignWindow then
|
||||
hotkeyAssignWindow:destroy()
|
||||
end
|
||||
local assignWindow = g_ui.createWidget('ActionAssignWindow', rootWidget)
|
||||
assignWindow:grabKeyboard()
|
||||
assignWindow.comboPreview.keyCombo = ''
|
||||
assignWindow.onKeyDown = function(assignWindow, keyCode, keyboardModifiers)
|
||||
local keyCombo = determineKeyComboDesc(keyCode, keyboardModifiers)
|
||||
assignWindow.comboPreview:setText(tr('Current action hotkey: %s', keyCombo))
|
||||
assignWindow.comboPreview.keyCombo = keyCombo
|
||||
assignWindow.comboPreview:resizeToText()
|
||||
return true
|
||||
end
|
||||
assignWindow.onDestroy = function()
|
||||
hotkeyAssignWindow = nil
|
||||
end
|
||||
assignWindow.addButton.onClick = function()
|
||||
local gameRootPanel = modules.game_interface.getRootPanel()
|
||||
if action.hotkey then
|
||||
g_keyboard.unbindKeyPress(action.hotkey, action.callback, gameRootPanel)
|
||||
end
|
||||
action.hotkey = assignWindow.comboPreview.keyCombo
|
||||
if action.hotkey then
|
||||
g_keyboard.bindKeyPress(action.hotkey, action.callback, gameRootPanel)
|
||||
end
|
||||
action.hotkeyLabel:setText(action.hotkey or "")
|
||||
assignWindow:destroy()
|
||||
end
|
||||
hotkeyAssignWindow = assignWindow
|
||||
end)
|
||||
menu:addSeparator()
|
||||
menu:addOption(tr('Clear'), function()
|
||||
action.item:setItem(nil)
|
||||
action.text:setText("")
|
||||
action.hotkeyLabel:setText("")
|
||||
local gameRootPanel = modules.game_interface.getRootPanel()
|
||||
if action.hotkey then
|
||||
g_keyboard.unbindKeyPress(action.hotkey, action.callback, gameRootPanel)
|
||||
end
|
||||
action.hotkey = nil
|
||||
action.actionType = nil
|
||||
action:setBorderColor(ActionColors.empty)
|
||||
end)
|
||||
menu:display(mousePosition)
|
||||
return true
|
||||
elseif mouseButton == MouseLeftButton then
|
||||
action.callback()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function actionOnItemChange(widget)
|
||||
local action = widget:getParent()
|
||||
if action.item:getItemId() > 0 then
|
||||
action.text:setText("")
|
||||
if action.item:getItem():isMultiUse() then
|
||||
if not action.actionType or action.actionType <= 1 then
|
||||
setupActionType(action, ActionTypes.USE_WITH)
|
||||
end
|
||||
else
|
||||
setupActionType(action, ActionTypes.USE)
|
||||
end
|
||||
end
|
||||
end
|
9
modules/game_actionbar/actionbar.otmod
Normal file
9
modules/game_actionbar/actionbar.otmod
Normal file
@@ -0,0 +1,9 @@
|
||||
Module
|
||||
name: game_actionbar
|
||||
description: Action bar
|
||||
author: otclient@otclient.ovh
|
||||
website: otclient.ovh
|
||||
sandboxed: true
|
||||
scripts: [ actionbar ]
|
||||
@onLoad: init()
|
||||
@onUnload: terminate()
|
134
modules/game_actionbar/actionbar.otui
Normal file
134
modules/game_actionbar/actionbar.otui
Normal file
@@ -0,0 +1,134 @@
|
||||
ActionButton < Panel
|
||||
size: 36 36
|
||||
font: cipsoftFont
|
||||
anchors.top: parent.top
|
||||
margin-left: 3
|
||||
border-width: 1
|
||||
border-color: #00000022
|
||||
|
||||
$first:
|
||||
anchors.left: parent.left
|
||||
|
||||
$!first:
|
||||
anchors.left: prev.right
|
||||
|
||||
Item
|
||||
id: item
|
||||
anchors.fill: parent
|
||||
margin: 1 1 1 1
|
||||
item-id: 3307
|
||||
&selectable: true
|
||||
&editable: false
|
||||
virtual: true
|
||||
|
||||
Label
|
||||
id: text
|
||||
anchors.fill: parent
|
||||
margin: 3 3 3 3
|
||||
text-auto-resize: true
|
||||
text-wrap: true
|
||||
text-align: center
|
||||
font: verdana-9px
|
||||
|
||||
Label
|
||||
id: hotkeyLabel
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
margin: 2 3 3 3
|
||||
text-auto-resize: true
|
||||
text-wrap: false
|
||||
font: small-9px
|
||||
color: #D3D3D3
|
||||
|
||||
Panel
|
||||
id: actionBar
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
image-source: /images/ui/panel_bottom
|
||||
image-border: 6
|
||||
focusable: false
|
||||
|
||||
$first:
|
||||
anchors.top: parent.top
|
||||
|
||||
$!first:
|
||||
anchors.top: prev.bottom
|
||||
|
||||
$on:
|
||||
height: 40
|
||||
visible: true
|
||||
|
||||
$!on:
|
||||
height: 0
|
||||
visible: false
|
||||
|
||||
TabButton
|
||||
id: prevButton
|
||||
icon: /images/game/console/leftarrow
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
margin-left: 1
|
||||
|
||||
Panel
|
||||
id: tabBar
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: prev.right
|
||||
anchors.right: next.left
|
||||
margin-right: 3
|
||||
margin-top: 2
|
||||
clipping: true
|
||||
|
||||
|
||||
TabButton
|
||||
id: nextButton
|
||||
icon: /images/game/console/rightarrow
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
margin-right: 1
|
||||
|
||||
|
||||
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()
|
Reference in New Issue
Block a user