Merge pull request #38 from BeniS/otclient

This commit is contained in:
Eduardo Bart 2012-07-12 14:34:39 -03:00
commit 1f6cd33109
54 changed files with 495 additions and 288 deletions

View File

@ -1,7 +1,7 @@
Module Module
name: client_options name: client_options
description: Create the options window description: Create the options window
author: edubart author: edubart, BeniS
website: www.otclient.info website: www.otclient.info
dependencies: dependencies:

View File

@ -4,7 +4,8 @@ TopMenu = {}
local topMenu local topMenu
local leftButtonsPanel local leftButtonsPanel
local rightButtonsPanel local rightButtonsPanel
local gameButtonsPanel local leftGameButtonsPanel
local rightGameButtonsPanel
-- private functions -- private functions
local function addButton(id, description, icon, callback, panel, toggle) local function addButton(id, description, icon, callback, panel, toggle)
@ -32,10 +33,12 @@ function TopMenu.init()
leftButtonsPanel = topMenu:getChildById('leftButtonsPanel') leftButtonsPanel = topMenu:getChildById('leftButtonsPanel')
rightButtonsPanel = topMenu:getChildById('rightButtonsPanel') rightButtonsPanel = topMenu:getChildById('rightButtonsPanel')
gameButtonsPanel = topMenu:getChildById('gameButtonsPanel') leftGameButtonsPanel = topMenu:getChildById('leftGameButtonsPanel')
rightGameButtonsPanel = topMenu:getChildById('rightGameButtonsPanel')
if g_game.isOnline() then if g_game.isOnline() then
gameButtonsPanel:show() leftGameButtonsPanel:show()
rightGameButtonsPanel:show()
end end
end end
@ -45,7 +48,8 @@ function TopMenu.terminate()
leftButtonsPanel = nil leftButtonsPanel = nil
rightButtonsPanel = nil rightButtonsPanel = nil
gameButtonsPanel = nil leftGameButtonsPanel = nil
rightGameButtonsPanel = nil
topMenu:destroy() topMenu:destroy()
topMenu = nil topMenu = nil
@ -69,20 +73,30 @@ function TopMenu.addRightToggleButton(id, description, icon, callback, right)
return addButton(id, description, icon, callback, rightButtonsPanel, true) return addButton(id, description, icon, callback, rightButtonsPanel, true)
end end
function TopMenu.addGameButton(id, description, icon, callback) function TopMenu.addLeftGameButton(id, description, icon, callback)
return addButton(id, description, icon, callback, gameButtonsPanel, false) return addButton(id, description, icon, callback, leftGameButtonsPanel, false)
end end
function TopMenu.addGameToggleButton(id, description, icon, callback, right) function TopMenu.addLeftGameToggleButton(id, description, icon, callback, right)
return addButton(id, description, icon, callback, gameButtonsPanel, true) return addButton(id, description, icon, callback, leftGameButtonsPanel, true)
end
function TopMenu.addRightGameButton(id, description, icon, callback)
return addButton(id, description, icon, callback, rightGameButtonsPanel, false)
end
function TopMenu.addRightGameToggleButton(id, description, icon, callback, right)
return addButton(id, description, icon, callback, rightGameButtonsPanel, true)
end end
function TopMenu.hideGameButtons() function TopMenu.hideGameButtons()
gameButtonsPanel:hide() leftGameButtonsPanel:hide()
rightGameButtonsPanel:hide()
end end
function TopMenu.showGameButtons() function TopMenu.showGameButtons()
gameButtonsPanel:show() leftGameButtonsPanel:show()
rightGameButtonsPanel:show()
end end
function TopMenu.getButton(id) function TopMenu.getButton(id)

View File

@ -57,18 +57,12 @@ TopPanel
anchors.left: parent.left anchors.left: parent.left
TopMenuButtonsPanel TopMenuButtonsPanel
id: gameButtonsPanel id: leftGameButtonsPanel
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: prev.right anchors.left: prev.right
visible: false visible: false
TopMenuButtonsPanel
id: rightButtonsPanel
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
UILabel UILabel
id: frameCounter id: frameCounter
text-align: right text-align: right
@ -76,7 +70,7 @@ TopPanel
color: white color: white
id: frameCounter id: frameCounter
anchors.top: parent.top anchors.top: parent.top
anchors.right: prev.left anchors.left: prev.right
margin-top: 8 margin-top: 8
margin-right: 5 margin-right: 5
@onSetup: | @onSetup: |
@ -88,3 +82,16 @@ TopPanel
--print(text) --print(text)
end end
end, 250) end, 250)
TopMenuButtonsPanel
id: rightButtonsPanel
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
TopMenuButtonsPanel
id: rightGameButtonsPanel
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: prev.left
visible: false

View File

@ -57,3 +57,10 @@ function table.compare(t, other)
end end
return true return true
end end
function table.empty(t)
if(t) then
return next(t) == nil
end
return true
end

View File

@ -16,7 +16,7 @@ Module
- game_textmessage - game_textmessage
- game_console - game_console
- game_outfit - game_outfit
- game_healthbar - game_healthinfo
- game_skills - game_skills
- game_inventory - game_inventory
- game_combatcontrols - game_combatcontrols

View File

@ -37,7 +37,7 @@ table.insert(lifeBarColors, {percentAbove = -1, color = '#4F0000' } )
-- public functions -- public functions
function Battle.init() function Battle.init()
battleWindow = g_ui.loadUI('battle.otui', GameInterface.getRightPanel()) battleWindow = g_ui.loadUI('battle.otui', GameInterface.getRightPanel())
battleButton = TopMenu.addGameToggleButton('battleButton', tr('Battle') .. ' (Ctrl+B)', 'battle.png', Battle.toggle) battleButton = TopMenu.addRightGameToggleButton('battleButton', tr('Battle') .. ' (Ctrl+B)', 'battle.png', Battle.toggle)
battleButton:setOn(true) battleButton:setOn(true)
g_keyboard.bindKeyDown('Ctrl+B', Battle.toggle) g_keyboard.bindKeyDown('Ctrl+B', Battle.toggle)

View File

@ -1,7 +1,7 @@
Module Module
name: game_battle name: game_battle
description: Manage battle window description: Manage battle window
author: andrefaramir author: andrefaramir, BeniS
website: www.otclient.info website: www.otclient.info
icon: battle.png icon: battle.png

View File

@ -98,4 +98,3 @@ MiniWindow
type: verticalBox type: verticalBox
fit-children: true fit-children: true

View File

@ -41,7 +41,7 @@ end
-- public functions -- public functions
function CombatControls.init() function CombatControls.init()
combatControlsButton = TopMenu.addGameToggleButton('combatControlsButton', tr('Combat Controls'), 'combatcontrols.png', CombatControls.toggle) combatControlsButton = TopMenu.addRightGameToggleButton('combatControlsButton', tr('Combat Controls'), 'combatcontrols.png', CombatControls.toggle)
combatControlsButton:setOn(true) combatControlsButton:setOn(true)
combatControlsWindow = g_ui.loadUI('combatcontrols.otui', GameInterface.getRightPanel()) combatControlsWindow = g_ui.loadUI('combatcontrols.otui', GameInterface.getRightPanel())
@ -131,11 +131,43 @@ function CombatControls.check()
end end
function CombatControls.online() function CombatControls.online()
local player = g_game.getLocalPlayer()
if(player) then
local char = player:getName()
local lastCombatControls = g_settings.getNode('LastCombatControls')
if(not table.empty(lastCombatControls)) then
if(lastCombatControls[char]) then
g_game.setFightMode(lastCombatControls[char].fightMode)
g_game.setChaseMode(lastCombatControls[char].chaseMode)
g_game.setSafeFight(lastCombatControls[char].safeFight)
end
end
end
combatControlsWindow:setVisible(combatControlsButton:isOn()) combatControlsWindow:setVisible(combatControlsButton:isOn())
CombatControls.update() CombatControls.update()
end end
function CombatControls.offline() function CombatControls.offline()
local lastCombatControls = g_settings.getNode('LastCombatControls')
if(not lastCombatControls) then
lastCombatControls = {}
end
local player = g_game.getLocalPlayer()
if(player) then
local char = player:getName()
lastCombatControls[char] = {
fightMode = g_game.getFightMode(),
chaseMode = g_game.getChaseMode(),
safeFight = g_game.isSafeFight()
}
-- save last combat control settings
g_settings.setNode('LastCombatControls', lastCombatControls)
end
end end
function CombatControls.toggle() function CombatControls.toggle()

View File

@ -1,7 +1,7 @@
Module Module
name: game_combatcontrols name: game_combatcontrols
description: Combat controls window description: Combat controls window
author: edubart author: edubart, BeniS
website: www.otclient.info website: www.otclient.info
dependencies: dependencies:

View File

@ -185,12 +185,76 @@ local function onChannelList(channelList)
end end
local function onGameStart() local function onGameStart()
-- open last channels
local player = g_game.getLocalPlayer()
if(player) then
local char = player:getName()
local lastChannelsOpen = g_settings.getNode('LastChannelsOpen')
if(not table.empty(lastChannelsOpen) and lastChannelsOpen[char]) then
for channelName, channelId in ipairs(lastChannelsOpen[char]) do
if(not table.find(channels, channelId)) then g_game.joinChannel(channelId) end
end
end
end
local tab = Console.getTab(tr('Default')) local tab = Console.getTab(tr('Default'))
if tab then if tab then
addEvent(function() consoleTabBar:selectTab(tab) end, false) --[[
Known Issue: The server is calling to open channels after
onGameStart is executed causing it to focus the last tab opened.
Fix: Don't save channels to the settings that are opened by the server.
]]
addEvent(function() consoleTabBar:selectTab(tab) end, true)
end end
for _, channelId in ipairs(g_settings.getList('last-channels')) do end
g_game.joinChannel(channelId)
function Console.onTabChange(tabBar, tab)
if tab:getText() == tr('Default') or tab:getText() == tr('Server Log') then
consolePanel:getChildById('closeChannelButton'):disable()
else
consolePanel:getChildById('closeChannelButton'):enable()
end
end
function Console.clear()
local lastChannelsOpen = {}
local player = g_game.getLocalPlayer()
if(player) then
local char = player:getName()
lastChannelsOpen[char] = {}
for channelId, channelName in pairs(channels) do
table.insert(lastChannelsOpen[char], channelId)
end
end
-- save last open channels
g_settings.setNode('LastChannelsOpen', lastChannelsOpen)
for _, channelName in pairs(channels) do
local tab = consoleTabBar:getTab(channelName)
consoleTabBar:removeTab(tab)
end
channels = {}
consoleTabBar:getTab(tr('Default')).tabPanel:getChildById('consoleBuffer'):destroyChildren()
consoleTabBar:getTab(tr('Server Log')).tabPanel:getChildById('consoleBuffer'):destroyChildren()
local npcTab = consoleTabBar:getTab('NPCs')
if npcTab then
consoleTabBar:removeTab(npcTab)
end
consoleTextEdit:clearText()
if channelsWindow then
channelsWindow:destroy()
channelsWindow = nil
end end
end end
@ -270,33 +334,6 @@ function Console.terminate()
Console = nil Console = nil
end end
function Console.clear()
local lastChannels = {}
for channelid, channelname in pairs(channels) do
table.insert(lastChannels, channelid)
local tab = consoleTabBar:getTab(channelname)
consoleTabBar:removeTab(tab)
end
g_settings.setList('last-channels', lastChannels)
channels = {}
consoleTabBar:getTab(tr('Default')).tabPanel:getChildById('consoleBuffer'):destroyChildren()
consoleTabBar:getTab(tr('Server Log')).tabPanel:getChildById('consoleBuffer'):destroyChildren()
local npcTab = consoleTabBar:getTab('NPCs')
if npcTab then
consoleTabBar:removeTab(npcTab)
end
consoleTextEdit:clearText()
if channelsWindow then
channelsWindow:destroy()
channelsWindow = nil
end
end
function Console.setTextEditText(text) function Console.setTextEditText(text)
consoleTextEdit:setText(text) consoleTextEdit:setText(text)
end end
@ -320,14 +357,6 @@ function Console.addTab(name, focus)
return tab return tab
end end
function Console.onTabChange(tabBar, tab)
if tab:getText() == tr('Default') or tab:getText() == tr('Server Log') then
consolePanel:getChildById('closeChannelButton'):disable()
else
consolePanel:getChildById('closeChannelButton'):enable()
end
end
function Console.removeCurrentTab() function Console.removeCurrentTab()
local tab = consoleTabBar:getCurrentTab() local tab = consoleTabBar:getCurrentTab()
if tab:getText() == tr('Default') or tab:getText() == tr('Server Log') then return end if tab:getText() == tr('Default') or tab:getText() == tr('Server Log') then return end

View File

@ -1,7 +1,7 @@
Module Module
name: game_console name: game_console
description: Manage chat window description: Manage chat window
author: edubart, andrefaramir, baxnie, sn4ake author: edubart, andrefaramir, baxnie, sn4ake, BeniS
website: www.otclient.info website: www.otclient.info
dependencies: dependencies:

View File

@ -108,7 +108,7 @@ function Containers.clean()
if container.window then if container.window then
container.window:destroy() container.window:destroy()
container.window = nil container.window = nil
container.itemsPnale = nil container.itemsPanel = nil
end end
end end
end end

View File

@ -1,150 +0,0 @@
HealthBar = {}
-- constants
local Icons = {}
Icons[1] = { tooltip = tr('You are poisoned'), path = '/game_healthbar/icons/poisoned.png', id = 'condition_poisoned' }
Icons[2] = { tooltip = tr('You are burning'), path = '/game_healthbar/icons/burning.png', id = 'condition_burning' }
Icons[4] = { tooltip = tr('You are electrified'), path = '/game_healthbar/icons/electrified.png', id = 'condition_electrified' }
Icons[8] = { tooltip = tr('You are freezing'), path = '/game_healthbar/icons/drunk.png', id = 'condition_drunk' }
Icons[16] = { tooltip = tr('You are protected by a magic shield'), path = '/game_healthbar/icons/magic_shield.png', id = 'condition_magic_shield' }
Icons[32] = { tooltip = tr('You are paralysed'), path = '/game_healthbar/icons/slowed.png', id = 'condition_slowed' }
Icons[64] = { tooltip = tr('You are hasted'), path = '/game_healthbar/icons/haste.png', id = 'condition_haste' }
Icons[128] = { tooltip = tr('You may not logout during a fight'), path = '/game_healthbar/icons/logout_block.png', id = 'condition_logout_block' }
Icons[256] = { tooltip = tr('You are drowing'), path = '/game_healthbar/icons/drowning.png', id = 'condition_drowning' }
Icons[512] = { tooltip = tr('You are freezing'), path = '/game_healthbar/icons/freezing.png', id = 'condition_freezing' }
Icons[1024] = { tooltip = tr('You are dazzled'), path = '/game_healthbar/icons/dazzled.png', id = 'condition_dazzled' }
Icons[2048] = { tooltip = tr('You are cursed'), path = '/game_healthbar/icons/cursed.png', id = 'condition_cursed' }
Icons[4096] = { tooltip = tr('You are strengthened'), path = '/game_healthbar/icons/strengthened.png', id = 'condition_strengthened' }
Icons[8192] = { tooltip = tr('You may not logout or enter a protection zone'), path = '/game_healthbar/icons/protection_zone_block.png', id = 'condition_protection_zone_block' }
Icons[16384] = { tooltip = tr('You are within a protection zone'), path = '/game_healthbar/icons/protection_zone.png', id = 'condition_protection_zone' }
Icons[32768] = { tooltip = tr('You are bleeding'), path = '/game_healthbar/icons/bleeding.png', id = 'condition_bleeding' }
Icons[65536] = { tooltip = tr('You are hungry'), path = '/game_healthbar/icons/hungry.png', id = 'condition_hungry' }
-- private variables
local healthBarWindow
local healthBar
local manaBar
local healthLabel
local manaLabel
local soulLabel
local soulPoints
-- public functions
function HealthBar.init()
connect(LocalPlayer, { onHealthChange = HealthBar.onHealthChange,
onManaChange = HealthBar.onManaChange,
onStatesChange = HealthBar.onStatesChange,
onSoulChange = HealthBar.onSoulChange })
connect(g_game, { onGameEnd = HealthBar.offline })
healthBarWindow = g_ui.loadUI('healthbar.otui', GameInterface.getRightPanel())
healthBarButton = TopMenu.addGameToggleButton('healthBarButton', tr('Health Bar'), 'healthbar.png', HealthBar.toggle)
healthBarButton:setOn(true)
healthBar = healthBarWindow:recursiveGetChildById('healthBar')
manaBar = healthBarWindow:recursiveGetChildById('manaBar')
healthLabel = healthBarWindow:recursiveGetChildById('healthLabel')
manaLabel = healthBarWindow:recursiveGetChildById('manaLabel')
soulLabel = healthBarWindow:recursiveGetChildById('soulLabel')
if g_game.isOnline() then
local localPlayer = g_game.getLocalPlayer()
HealthBar.onHealthChange(localPlayer, localPlayer:getHealth(), localPlayer:getMaxHealth())
HealthBar.onManaChange(localPlayer, localPlayer:getMana(), localPlayer:getMaxMana())
HealthBar.onStatesChange(localPlayer, localPlayer:getStates(), 0)
HealthBar.onSoulChange(localPlayer, localPlayer:getSoul())
end
end
function HealthBar.terminate()
disconnect(LocalPlayer, { onHealthChange = HealthBar.onHealthChange,
onManaChange = HealthBar.onManaChange,
onStatesChange = HealthBar.onStatesChange,
onSoulChange = HealthBar.onSoulChange })
disconnect(g_game, { onGameEnd = HealthBar.offline })
healthBarWindow:destroy()
healthBarButton:destroy()
healthBarWindow = nil
healthBarButton = nil
healthBar = nil
manaBar = nil
healthLabel = nil
manaLabel = nil
soulLabel = nil
HealthBar = nil
end
function HealthBar.toggle()
if healthBarButton:isOn() then
healthBarWindow:close()
healthBarButton:setOn(false)
else
healthBarWindow:open()
healthBarButton:setOn(true)
end
end
function HealthBar.onMiniWindowClose()
healthBarButton:setOn(false)
end
function HealthBar.offline()
healthBarWindow:recursiveGetChildById('conditionPanel'):destroyChildren()
end
-- hooked events
function HealthBar.onHealthChange(localPlayer, health, maxHealth)
healthLabel:setText(health .. ' / ' .. maxHealth)
healthBar:setPercent(health / maxHealth * 100)
end
function HealthBar.onManaChange(localPlayer, mana, maxMana)
manaLabel:setText(mana .. ' / ' .. maxMana)
local percent
if maxMana == 0 then
percent = 100
else
percent = (mana * 100)/maxMana
end
manaBar:setPercent(percent)
end
function HealthBar.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
HealthBar.toggleIcon(bitChanged)
end
end
end
function HealthBar.onSoulChange(localPlayer, soul)
soulLabel:setText('Soul: '.. soul)
end
function HealthBar.toggleIcon(bitChanged)
local content = healthBarWindow:recursiveGetChildById('conditionPanel')
local icon = content:getChildById(Icons[bitChanged].id)
if icon then
icon:destroy()
else
icon = g_ui.createWidget('ConditionWidget', content)
icon:setId(Icons[bitChanged].id)
icon:setImageSource(Icons[bitChanged].path)
icon:setTooltip(Icons[bitChanged].tooltip)
end
end

View File

@ -1,15 +0,0 @@
Module
name: game_healthbar
description: Displays health and mana points
author: edubart
website: www.otclient.info
dependencies:
- game_interface
@onLoad: |
dofile 'healthbar'
HealthBar.init()
@onUnload: |
HealthBar.terminate()

View File

@ -0,0 +1,151 @@
HealthInfo = {}
-- constants
local Icons = {}
Icons[1] = { tooltip = tr('You are poisoned'), path = '/game_healthinfo/icons/poisoned.png', id = 'condition_poisoned' }
Icons[2] = { tooltip = tr('You are burning'), path = '/game_healthinfo/icons/burning.png', id = 'condition_burning' }
Icons[4] = { tooltip = tr('You are electrified'), path = '/game_healthinfo/icons/electrified.png', id = 'condition_electrified' }
Icons[8] = { tooltip = tr('You are freezing'), path = '/game_healthinfo/icons/drunk.png', id = 'condition_drunk' }
Icons[16] = { tooltip = tr('You are protected by a magic shield'), path = '/game_healthinfo/icons/magic_shield.png', id = 'condition_magic_shield' }
Icons[32] = { tooltip = tr('You are paralysed'), path = '/game_healthinfo/icons/slowed.png', id = 'condition_slowed' }
Icons[64] = { tooltip = tr('You are hasted'), path = '/game_healthinfo/icons/haste.png', id = 'condition_haste' }
Icons[128] = { tooltip = tr('You may not logout during a fight'), path = '/game_healthinfo/icons/logout_block.png', id = 'condition_logout_block' }
Icons[256] = { tooltip = tr('You are drowing'), path = '/game_healthinfo/icons/drowning.png', id = 'condition_drowning' }
Icons[512] = { tooltip = tr('You are freezing'), path = '/game_healthinfo/icons/freezing.png', id = 'condition_freezing' }
Icons[1024] = { tooltip = tr('You are dazzled'), path = '/game_healthinfo/icons/dazzled.png', id = 'condition_dazzled' }
Icons[2048] = { tooltip = tr('You are cursed'), path = '/game_healthinfo/icons/cursed.png', id = 'condition_cursed' }
Icons[4096] = { tooltip = tr('You are strengthened'), path = '/game_healthinfo/icons/strengthened.png', id = 'condition_strengthened' }
Icons[8192] = { tooltip = tr('You may not logout or enter a protection zone'), path = '/game_healthinfo/icons/protection_zone_block.png', id = 'condition_protection_zone_block' }
Icons[16384] = { tooltip = tr('You are within a protection zone'), path = '/game_healthinfo/icons/protection_zone.png', id = 'condition_protection_zone' }
Icons[32768] = { tooltip = tr('You are bleeding'), path = '/game_healthinfo/icons/bleeding.png', id = 'condition_bleeding' }
Icons[65536] = { tooltip = tr('You are hungry'), path = '/game_healthinfo/icons/hungry.png', id = 'condition_hungry' }
-- private variables
local healthInfoWindow
local healthBar
local manaBar
local soulBar
local healthLabel
local manaLabel
local soulLabel
-- public functions
function HealthInfo.init()
connect(LocalPlayer, { onHealthChange = HealthInfo.onHealthChange,
onManaChange = HealthInfo.onManaChange,
onStatesChange = HealthInfo.onStatesChange,
onSoulChange = HealthInfo.onSoulChange })
connect(g_game, { onGameEnd = HealthInfo.offline })
healthInfoWindow = g_ui.loadUI('healthinfo.otui', GameInterface.getRightPanel())
healthInfoButton = TopMenu.addRightGameToggleButton('healthInfoButton', tr('Health Information'), 'healthinfo.png', HealthInfo.toggle)
healthInfoButton:setOn(true)
healthBar = healthInfoWindow:recursiveGetChildById('healthBar')
manaBar = healthInfoWindow:recursiveGetChildById('manaBar')
healthLabel = healthInfoWindow:recursiveGetChildById('healthLabel')
manaLabel = healthInfoWindow:recursiveGetChildById('manaLabel')
soulBar = healthInfoWindow:recursiveGetChildById('soulBar')
soulLabel = healthInfoWindow:recursiveGetChildById('soulLabel')
if g_game.isOnline() then
local localPlayer = g_game.getLocalPlayer()
HealthInfo.onHealthChange(localPlayer, localPlayer:getHealth(), localPlayer:getMaxHealth())
HealthInfo.onManaChange(localPlayer, localPlayer:getMana(), localPlayer:getMaxMana())
HealthInfo.onStatesChange(localPlayer, localPlayer:getStates(), 0)
HealthInfo.onSoulChange(localPlayer, localPlayer:getSoul())
end
end
function HealthInfo.terminate()
disconnect(LocalPlayer, { onHealthChange = HealthInfo.onHealthChange,
onManaChange = HealthInfo.onManaChange,
onStatesChange = HealthInfo.onStatesChange,
onSoulChange = HealthInfo.onSoulChange })
disconnect(g_game, { onGameEnd = HealthInfo.offline })
healthInfoWindow:destroy()
healthInfoButton:destroy()
healthInfoWindow = nil
healthInfoButton = nil
healthBar = nil
manaBar = nil
soulBar = nil
healthLabel = nil
manaLabel = nil
soulLabel = nil
HealthInfo = nil
end
function HealthInfo.toggle()
if healthInfoButton:isOn() then
healthInfoWindow:close()
healthInfoButton:setOn(false)
else
healthInfoWindow:open()
healthInfoButton:setOn(true)
end
end
function HealthInfo.onMiniWindowClose()
healthInfoButton:setOn(false)
end
function HealthInfo.offline()
healthInfoWindow:recursiveGetChildById('conditionPanel'):destroyChildren()
end
-- hooked events
function HealthInfo.onHealthChange(localPlayer, health, maxHealth)
healthLabel:setText(health .. ' / ' .. maxHealth)
healthBar:setPercent(health / maxHealth * 100)
end
function HealthInfo.onManaChange(localPlayer, mana, maxMana)
manaLabel:setText(mana .. ' / ' .. maxMana)
local percent
if maxMana == 0 then
percent = 100
else
percent = (mana * 100)/maxMana
end
manaBar:setPercent(percent)
end
function HealthInfo.onSoulChange(localPlayer, soul)
soulLabel:setText('Soul: ' .. soul)
end
function HealthInfo.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
HealthInfo.toggleIcon(bitChanged)
end
end
end
function HealthInfo.toggleIcon(bitChanged)
local content = healthInfoWindow:recursiveGetChildById('conditionPanel')
local icon = content:getChildById(Icons[bitChanged].id)
if icon then
icon:destroy()
else
icon = g_ui.createWidget('ConditionWidget', content)
icon:setId(Icons[bitChanged].id)
icon:setImageSource(Icons[bitChanged].path)
icon:setTooltip(Icons[bitChanged].tooltip)
end
end

View File

@ -0,0 +1,15 @@
Module
name: game_healthinfo
description: Displays health, mana points, soul points, and conditions
author: edubart, BeniS
website: www.otclient.info
dependencies:
- game_interface
@onLoad: |
dofile 'healthinfo'
HealthInfo.init()
@onUnload: |
HealthInfo.terminate()

View File

@ -52,11 +52,11 @@ ConditionWidget < UIWidget
margin-left: 5 margin-left: 5
MiniWindow MiniWindow
icon: healthbar.png icon: healthinfo.png
id: healthBarWindow id: healthInfoWindow
!text: tr('Health Bar') !text: tr('Health Info')
height: 102 height: 102
@onClose: HealthBar.onMiniWindowClose() @onClose: HealthInfo.onMiniWindowClose()
&save: true &save: true
MiniWindowContents MiniWindowContents

View File

Before

Width:  |  Height:  |  Size: 238 B

After

Width:  |  Height:  |  Size: 238 B

View File

Before

Width:  |  Height:  |  Size: 905 B

After

Width:  |  Height:  |  Size: 905 B

View File

Before

Width:  |  Height:  |  Size: 933 B

After

Width:  |  Height:  |  Size: 933 B

View File

Before

Width:  |  Height:  |  Size: 445 B

After

Width:  |  Height:  |  Size: 445 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 894 B

After

Width:  |  Height:  |  Size: 894 B

View File

Before

Width:  |  Height:  |  Size: 912 B

After

Width:  |  Height:  |  Size: 912 B

View File

Before

Width:  |  Height:  |  Size: 957 B

After

Width:  |  Height:  |  Size: 957 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 905 B

After

Width:  |  Height:  |  Size: 905 B

View File

Before

Width:  |  Height:  |  Size: 570 B

After

Width:  |  Height:  |  Size: 570 B

View File

Before

Width:  |  Height:  |  Size: 898 B

After

Width:  |  Height:  |  Size: 898 B

View File

Before

Width:  |  Height:  |  Size: 909 B

After

Width:  |  Height:  |  Size: 909 B

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 628 B

After

Width:  |  Height:  |  Size: 628 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -38,7 +38,7 @@ function HotkeysManager.init()
local hotkeyListPanel = hotkeysWindow:getChildById('currentHotkeys') local hotkeyListPanel = hotkeysWindow:getChildById('currentHotkeys')
hotkeysWindow:setVisible(false) hotkeysWindow:setVisible(false)
hotkeysButton = TopMenu.addGameButton('hotkeysButton', tr('Hotkeys') .. ' (Ctrl+K)', '/game_hotkeys/icon.png', HotkeysManager.toggle) hotkeysButton = TopMenu.addLeftGameButton('hotkeysButton', tr('Hotkeys') .. ' (Ctrl+K)', '/game_hotkeys/icon.png', HotkeysManager.toggle)
g_keyboard.bindKeyDown('Ctrl+K', HotkeysManager.toggle) g_keyboard.bindKeyDown('Ctrl+K', HotkeysManager.toggle)
g_keyboard.bindKeyPress('Down', function() hotkeyListPanel:focusNextChild(KeyboardFocusReason) end, hotkeysWindow) g_keyboard.bindKeyPress('Down', function() hotkeyListPanel:focusNextChild(KeyboardFocusReason) end, hotkeysWindow)
g_keyboard.bindKeyPress('Up', function() hotkeyListPanel:focusPreviousChild(KeyboardFocusReason) end, hotkeysWindow) g_keyboard.bindKeyPress('Up', function() hotkeyListPanel:focusPreviousChild(KeyboardFocusReason) end, hotkeysWindow)

View File

@ -1,7 +1,7 @@
Module Module
name: game_hotkeys name: game_hotkeys
description: Manage client hotkeys description: Manage client hotkeys
author: andrefaramir author: andrefaramir, BeniS
website: www.otclient.info website: www.otclient.info
dependencies: dependencies:

View File

@ -20,6 +20,8 @@ end
function GameInterface.init() function GameInterface.init()
g_ui.importStyle('styles/countwindow.otui') g_ui.importStyle('styles/countwindow.otui')
g_ui.importStyle('styles/logoutwindow.otui')
g_ui.importStyle('styles/exitwindow.otui')
connect(g_game, { onGameStart = GameInterface.show }, true) connect(g_game, { onGameStart = GameInterface.show }, true)
connect(g_game, { onGameEnd = GameInterface.hide }, true) connect(g_game, { onGameEnd = GameInterface.hide }, true)
@ -63,8 +65,8 @@ function GameInterface.init()
g_keyboard.bindKeyPress('Escape', function() g_game.cancelAttackAndFollow() end, gameRootPanel, WALK_AUTO_REPEAT_DELAY) g_keyboard.bindKeyPress('Escape', function() g_game.cancelAttackAndFollow() end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
g_keyboard.bindKeyPress('Ctrl+=', function() gameMapPanel:zoomIn() end, gameRootPanel, 250) g_keyboard.bindKeyPress('Ctrl+=', function() gameMapPanel:zoomIn() end, gameRootPanel, 250)
g_keyboard.bindKeyPress('Ctrl+-', function() gameMapPanel:zoomOut() end, gameRootPanel, 250) g_keyboard.bindKeyPress('Ctrl+-', function() gameMapPanel:zoomOut() end, gameRootPanel, 250)
g_keyboard.bindKeyDown('Ctrl+Q', GameInterface.tryLogout, gameRootPanel) g_keyboard.bindKeyDown('Ctrl+Q', GameInterface.logout, gameRootPanel)
g_keyboard.bindKeyDown('Ctrl+L', GameInterface.tryLogout, gameRootPanel) g_keyboard.bindKeyDown('Ctrl+L', GameInterface.logout, gameRootPanel)
g_keyboard.bindKeyDown('Ctrl+W', function() g_map.cleanTexts() TextMessage.clearMessages() end, gameRootPanel) g_keyboard.bindKeyDown('Ctrl+W', function() g_map.cleanTexts() TextMessage.clearMessages() end, gameRootPanel)
g_keyboard.bindKeyDown('Ctrl+.', function() g_keyboard.bindKeyDown('Ctrl+.', function()
@ -114,7 +116,7 @@ function GameInterface.hide()
g_app.onClose = nil g_app.onClose = nil
end end
function GameInterface.tryExit() function GameInterface.exit()
if g_game.isOnline() then if g_game.isOnline() then
g_game.forceLogout() g_game.forceLogout()
scheduleEvent(exit, 10) scheduleEvent(exit, 10)
@ -122,13 +124,47 @@ function GameInterface.tryExit()
end end
end end
function GameInterface.tryLogout() function GameInterface.tryExit()
local exitWindow = g_ui.createWidget('ExitWindow', rootWidget)
local exitButton = exitWindow:getChildById('buttonExit')
local logoutButton = exitWindow:getChildById('buttonLogout')
local exitFunc = function()
GameInterface.exit()
exitButton:getParent():destroy()
end
local logoutFunc = function()
GameInterface.logout()
logoutButton:getParent():destroy()
end
exitWindow.onEnter = logoutFunc
exitButton.onClick = exitFunc
logoutButton.onClick = logoutFunc
return true -- signal closing
end
function GameInterface.logout()
if g_game.isOnline() then if g_game.isOnline() then
g_game.safeLogout() g_game.safeLogout()
return true return true
end end
end end
function GameInterface.tryLogout()
local logoutWindow = g_ui.createWidget('LogoutWindow', rootWidget)
local yesButton = logoutWindow:getChildById('buttonYes')
local logoutFunc = function()
GameInterface.logout()
yesButton:getParent():destroy()
end
logoutWindow.onEnter = logoutFunc
yesButton.onClick = logoutFunc
end
function GameInterface.onMouseGrabberRelease(self, mousePosition, mouseButton) function GameInterface.onMouseGrabberRelease(self, mousePosition, mouseButton)
if GameInterface.selectedThing == nil then return false end if GameInterface.selectedThing == nil then return false end
if mouseButton == MouseLeftButton then if mouseButton == MouseLeftButton then

View File

@ -0,0 +1,54 @@
ExitWindow < MainWindow
id: exitWindow
!text: tr('Exit')
size: 550 135
@onEscape: self:destroy()
Label
!text: tr('If you shut down the program, you character might stay in the game.')
width: 550
anchors.left: parent.left
anchors.top: parent.top
margin-left: 10
margin-top: 2
Label
!text: tr('Click on "Logout" to ensure that you character leaves the game property.')
width: 550
anchors.left: parent.left
anchors.top: prev.bottom
margin-left: 10
margin-top: 2
Label
!text: tr('Click on "Exit" if you want to exit the program without logging out your character.')
width: 550
anchors.left: parent.left
anchors.top: prev.bottom
margin-left: 10
margin-top: 2
Button
id: buttonExit
!text: tr('Exit')
width: 64
anchors.left: parent.left
anchors.bottom: parent.bottom
margin-left: 155
Button
id: buttonLogout
!text: tr('Logout')
width: 64
anchors.left: prev.right
anchors.bottom: parent.bottom
margin-left: 5
Button
id: buttonCancel
!text: tr('Cancel')
width: 64
anchors.left: prev.right
anchors.bottom: parent.bottom
margin-left: 5
@onClick: self:getParent():destroy()

View File

@ -0,0 +1,30 @@
LogoutWindow < MainWindow
id: logoutWindow
!text: tr('Logout')
size: 300 100
@onEscape: self:destroy()
Label
!text: tr('Are you sure you want to logout?')
width: 300
anchors.left: parent.left
anchors.top: parent.top
margin-left: 30
margin-top: 2
Button
id: buttonYes
!text: tr('Yes')
width: 64
anchors.left: parent.left
anchors.bottom: parent.bottom
margin-left: 65
Button
id: buttonNo
!text: tr('No')
width: 64
anchors.left: prev.right
anchors.bottom: parent.bottom
margin-left: 5
@onClick: self:getParent():destroy()

View File

@ -35,8 +35,8 @@ function UIGameMap:onDrop(widget, mousePos)
local thing = widget.currentDragThing local thing = widget.currentDragThing
local toPos = tile:getPosition() local toPos = tile:getPosition()
local itemPos = thing:getPosition() local thingPos = thing:getPosition()
if itemPos.x == toPos.x and itemPos.y == toPos.y and itemPos.z == toPos.z then return false end if thingPos.x == toPos.x and thingPos.y == toPos.y and thingPos.z == toPos.z then return false end
if thing:asItem() and thing:getCount() > 1 then if thing:asItem() and thing:getCount() > 1 then
GameInterface.moveStackableItem(thing, toPos) GameInterface.moveStackableItem(thing, toPos)

View File

@ -27,7 +27,7 @@ function UIItem:onDrop(widget, mousePos)
local toPos = self.position local toPos = self.position
local itemPos = item:getPosition() local itemPos = item:getPosition()
if itemPos.x == self.position.x and itemPos.y == self.position.y and itemPos.z == self.position.z then return false end if itemPos.x == toPos.x and itemPos.y == toPos.y and itemPos.z == toPos.z then return false end
if item:getCount() > 1 then if item:getCount() > 1 then
GameInterface.moveStackableItem(item, toPos) GameInterface.moveStackableItem(item, toPos)

View File

@ -29,7 +29,7 @@ function Inventory.init()
inventoryWindow = g_ui.loadUI('inventory.otui', GameInterface.getRightPanel()) inventoryWindow = g_ui.loadUI('inventory.otui', GameInterface.getRightPanel())
inventoryPanel = inventoryWindow:getChildById('contentsPanel') inventoryPanel = inventoryWindow:getChildById('contentsPanel')
inventoryButton = TopMenu.addGameToggleButton('inventoryButton', tr('Inventory') .. ' (Ctrl+I)', 'inventory.png', Inventory.toggle) inventoryButton = TopMenu.addRightGameToggleButton('inventoryButton', tr('Inventory') .. ' (Ctrl+I)', 'inventory.png', Inventory.toggle)
inventoryButton:setOn(true) inventoryButton:setOn(true)
Inventory.refresh() Inventory.refresh()

View File

@ -1,7 +1,7 @@
Module Module
name: game_inventory name: game_inventory
description: View local player equipments window description: View local player equipments window
author: baxnie, edubart author: baxnie, edubart, BeniS
website: www.otclient.info website: www.otclient.info
dependencies: dependencies:

View File

@ -127,13 +127,3 @@ MiniWindow
margin-top: 5 margin-top: 5
text-align: center text-align: center
text-auto-resize: true text-auto-resize: true
GameLabel
id: soul
height: 30
anchors.top: slot9.bottom
anchors.left: slot9.left
margin-top: 5
text-align: center
text-auto-resize: true

View File

@ -42,7 +42,7 @@ function Minimap.init()
g_keyboard.bindKeyDown('Ctrl+M', Minimap.toggle) g_keyboard.bindKeyDown('Ctrl+M', Minimap.toggle)
minimapButton = TopMenu.addGameToggleButton('minimapButton', tr('Minimap') .. ' (Ctrl+M)', 'minimap.png', Minimap.toggle) minimapButton = TopMenu.addRightGameToggleButton('minimapButton', tr('Minimap') .. ' (Ctrl+M)', 'minimap.png', Minimap.toggle)
minimapButton:setOn(true) minimapButton:setOn(true)
minimapWindow = g_ui.loadUI('minimap.otui', GameInterface.getRightPanel()) minimapWindow = g_ui.loadUI('minimap.otui', GameInterface.getRightPanel())
@ -137,11 +137,11 @@ function Minimap.onButtonClick(id)
minimapWidget:setZoom(math.max(minimapWidget:getMaxZoomIn(), minimapWidget:getZoom()-15)) minimapWidget:setZoom(math.max(minimapWidget:getMaxZoomIn(), minimapWidget:getZoom()-15))
elseif id == "zoomOut" then elseif id == "zoomOut" then
minimapWidget:setZoom(math.min(minimapWidget:getMaxZoomOut(), minimapWidget:getZoom()+15)) minimapWidget:setZoom(math.min(minimapWidget:getMaxZoomOut(), minimapWidget:getZoom()+15))
elseif id == "levelUp" then elseif id == "floorUp" then
local pos = minimapWidget:getCameraPosition() local pos = minimapWidget:getCameraPosition()
pos.z = pos.z - 1 pos.z = pos.z - 1
minimapWidget:setCameraPosition(pos) minimapWidget:setCameraPosition(pos)
elseif id == "levelDown" then elseif id == "floorDown" then
local pos = minimapWidget:getCameraPosition() local pos = minimapWidget:getCameraPosition()
pos.z = pos.z + 1 pos.z = pos.z + 1
minimapWidget:setCameraPosition(pos) minimapWidget:setCameraPosition(pos)

View File

@ -1,7 +1,7 @@
Module Module
name: game_minimap name: game_minimap
description: Manage minimap description: Manage minimap
author: edubart author: edubart, BeniS
website: www.otclient.info website: www.otclient.info
dependencies: dependencies:

View File

@ -77,15 +77,20 @@ MiniWindow
$disabled: $disabled:
image-color: #ffffff88 image-color: #ffffff88
Button FloorUpControl
id: zoomOut id: floorUp
text: -
font: terminus-14px-bold
size: 16 16
anchors.left: minimap.right anchors.left: minimap.right
anchors.top: compass.bottom anchors.top: compass.bottom
margin-top: 10 margin-top: 10
margin-left: 10 margin-left: 15
enabled: true
@onClick: Minimap.onButtonClick(self:getId())
FloorDownControl
id: floorDown
anchors.left: floorUp.left
anchors.top: floorUp.bottom
margin-top: 4
enabled: true enabled: true
@onClick: Minimap.onButtonClick(self:getId()) @onClick: Minimap.onButtonClick(self:getId())
@ -93,25 +98,20 @@ MiniWindow
id: zoomIn id: zoomIn
text: + text: +
size: 16 16 size: 16 16
anchors.left: zoomOut.left anchors.left: floorUp.right
anchors.top: zoomOut.bottom anchors.top: floorUp.top
margin-top: 4 margin-left: 10
enabled: true enabled: true
@onClick: Minimap.onButtonClick(self:getId()) @onClick: Minimap.onButtonClick(self:getId())
FloorUpControl Button
id: levelUp id: zoomOut
anchors.left: zoomOut.right text: -
anchors.top: zoomOut.top font: terminus-14px-bold
margin-left: 15 size: 16 16
enabled: true anchors.left: floorDown.right
@onClick: Minimap.onButtonClick(self:getId()) anchors.top: floorDown.top
margin-left: 10
FloorDownControl
id: levelDown
anchors.left: zoomIn.right
anchors.top: zoomIn.top
margin-left: 15
enabled: true enabled: true
@onClick: Minimap.onButtonClick(self:getId()) @onClick: Minimap.onButtonClick(self:getId())

View File

@ -58,7 +58,7 @@ function QuestLog.init()
g_ui.importStyle('questlogwindow.otui') g_ui.importStyle('questlogwindow.otui')
g_ui.importStyle('questlinewindow.otui') g_ui.importStyle('questlinewindow.otui')
questLogButton = TopMenu.addGameButton('questLogButton', tr('Quest Log'), 'questlog.png', function() g_game.requestQuestLog() end) questLogButton = TopMenu.addLeftGameButton('questLogButton', tr('Quest Log'), 'questlog.png', function() g_game.requestQuestLog() end)
connect(g_game, { onQuestLog = onGameQuestLog }) connect(g_game, { onQuestLog = onGameQuestLog })
connect(g_game, { onQuestLine= onGameQuestLine }) connect(g_game, { onQuestLine= onGameQuestLine })

View File

@ -36,7 +36,7 @@ function Skills.init()
}) })
skillsWindow = g_ui.loadUI('skills.otui', GameInterface.getRightPanel()) skillsWindow = g_ui.loadUI('skills.otui', GameInterface.getRightPanel())
skillsButton = TopMenu.addGameToggleButton('skillsButton', tr('Skills') .. ' (Ctrl+S)', 'skills.png', Skills.toggle) skillsButton = TopMenu.addRightGameToggleButton('skillsButton', tr('Skills') .. ' (Ctrl+S)', 'skills.png', Skills.toggle)
skillsButton:setOn(true) skillsButton:setOn(true)
g_keyboard.bindKeyDown('Ctrl+S', Skills.toggle) g_keyboard.bindKeyDown('Ctrl+S', Skills.toggle)

View File

@ -15,7 +15,7 @@ function VipList.init()
g_keyboard.bindKeyDown('Ctrl+P', VipList.toggle) g_keyboard.bindKeyDown('Ctrl+P', VipList.toggle)
vipWindow = g_ui.loadUI('viplist.otui', GameInterface.getRightPanel()) vipWindow = g_ui.loadUI('viplist.otui', GameInterface.getRightPanel())
vipButton = TopMenu.addGameToggleButton('vipListButton', tr('VIP list') .. ' (Ctrl+P)', 'viplist.png', VipList.toggle) vipButton = TopMenu.addRightGameToggleButton('vipListButton', tr('VIP list') .. ' (Ctrl+P)', 'viplist.png', VipList.toggle)
vipButton:setOn(true) vipButton:setOn(true)
VipList.refresh() VipList.refresh()

View File

@ -189,6 +189,9 @@ void Creature::drawOutfit(const Rect& destRect, bool resize)
void Creature::drawInformation(const Point& point, bool useGray, const Rect& parentRect) void Creature::drawInformation(const Point& point, bool useGray, const Rect& parentRect)
{ {
if(m_healthPercent < 1) // creature is dead
return;
Color fillColor = Color(96, 96, 96); Color fillColor = Color(96, 96, 96);
if(!useGray) if(!useGray)

View File

@ -118,6 +118,11 @@ void UIMap::setKeepAspectRatio(bool enable)
TilePtr UIMap::getTile(const Point& mousePos) TilePtr UIMap::getTile(const Point& mousePos)
{ {
/*
* Known Issue: If you move a container widget into the map rect
* if you move an item onto itself it will allow this to execute
* still dropping the item on the ground.
*/
if(!m_mapRect.contains(mousePos)) if(!m_mapRect.contains(mousePos))
return nullptr; return nullptr;