implementing battle window, need some improvements but its working

This commit is contained in:
AndreFaramir 2012-02-09 03:27:29 -02:00
parent a8c9980a5c
commit 8545d15304
13 changed files with 580 additions and 33 deletions

View File

@ -23,53 +23,74 @@ EmblemGreen = 1
EmblemRed = 2
EmblemBlue = 3
function Creature:onSkullChange(skullId)
function getSkullImagePath(skullId)
if skullId == SkullYellow then
self:setSkullTexture(resolvepath('images/skull_yellow.png'))
return 'images/skull_yellow.png'
elseif skullId == SkullGreen then
self:setSkullTexture(resolvepath('images/skull_green.png'))
return 'images/skull_green.png'
elseif skullId == SkullWhite then
self:setSkullTexture(resolvepath('images/skull_white.png'))
return 'images/skull_white.png'
elseif skullId == SkullRed then
self:setSkullTexture(resolvepath('images/skull_red.png'))
return 'images/skull_red.png'
elseif skullId == SkullBlack then
self:setSkullTexture(resolvepath('images/skull_black.png'))
return 'images/skull_black.png'
elseif skullId == SkullOrange then
self:setSkullTexture(resolvepath('images/skull_orange.png'))
return 'images/skull_orange.png'
end
end
function getShieldImagePathAndBlink(shieldId)
if shieldId == ShieldWhiteYellow then
return 'images/shield_yellow_white.png', false
elseif shieldId == ShieldWhiteBlue then
return 'images/shield_blue_white.png', false
elseif shieldId == ShieldBlue then
return 'images/shield_blue.png', false
elseif shieldId == ShieldYellow then
return 'images/shield_yellow.png', false
elseif shieldId == ShieldBlueSharedExp then
return 'images/shield_blue_shared.png', false
elseif shieldId == ShieldYellowSharedExp then
return 'images/shield_yellow_shared.png', false
elseif shieldId == ShieldBlueNoSharedExpBlink then
return 'images/shield_blue_not_shared.png', true
elseif shieldId == ShieldYellowNoSharedExpBlink then
return 'images/shield_yellow_not_shared.png', true
elseif shieldId == ShieldBlueNoSharedExp then
return 'images/shield_blue_not_shared.png', false
elseif shieldId == ShieldYellowNoSharedExp then
return 'images/shield_yellow_not_shared.png', false
end
end
function getEmblemImagePath(emblemId)
if emblemId == EmblemGreen then
return 'images/emblem_green.png'
elseif emblemId == EmblemRed then
return 'images/emblem_red.png'
elseif emblemId == EmblemBlue then
return 'images/emblem_blue.png'
end
end
function Creature:onSkullChange(skullId)
local imagePath = getSkullImagePath(skullId)
if imagePath then
self:setSkullTexture(resolvepath(imagePath))
end
end
function Creature:onShieldChange(shieldId)
if shieldId == ShieldWhiteYellow then
self:setShieldTexture(resolvepath('images/shield_yellow_white.png'), false)
elseif shieldId == ShieldWhiteBlue then
self:setShieldTexture(resolvepath('images/shield_blue_white.png'), false)
elseif shieldId == ShieldBlue then
self:setShieldTexture(resolvepath('images/shield_blue.png'), false)
elseif shieldId == ShieldYellow then
self:setShieldTexture(resolvepath('images/shield_yellow.png'), false)
elseif shieldId == ShieldBlueSharedExp then
self:setShieldTexture(resolvepath('images/shield_blue_shared.png'), false)
elseif shieldId == ShieldYellowSharedExp then
self:setShieldTexture(resolvepath('images/shield_yellow_shared.png'), false)
elseif shieldId == ShieldBlueNoSharedExpBlink then
self:setShieldTexture(resolvepath('images/shield_blue_not_shared.png'), true)
elseif shieldId == ShieldYellowNoSharedExpBlink then
self:setShieldTexture(resolvepath('images/shield_yellow_not_shared.png'), true)
elseif shieldId == ShieldBlueNoSharedExp then
self:setShieldTexture(resolvepath('images/shield_blue_not_shared.png'), false)
elseif shieldId == ShieldYellowNoSharedExp then
self:setShieldTexture(resolvepath('images/shield_yellow_not_shared.png'), false)
local imagePath, blink = getShieldImagePathAndBlink(shieldId)
if imagePath then
self:setShieldTexture(resolvepath(imagePath), blink)
end
end
function Creature:onEmblemChange(emblemId)
if emblemId == EmblemGreen then
self:setEmblemTexture(resolvepath('images/emblem_green.png'))
elseif emblemId == EmblemRed then
self:setEmblemTexture(resolvepath('images/emblem_red.png'))
elseif emblemId == EmblemBlue then
self:setEmblemTexture(resolvepath('images/emblem_blue.png'))
local imagePath = getEmblemImagePath(emblemId)
if imagePath then
self:setEmblemTexture(resolvepath(imagePath))
end
end

View File

@ -27,6 +27,12 @@ local function onUseWithMouseRelease(self, mousePosition, mouseButton)
end
elseif clickedWidget:getClassName() == 'UIItem' and not clickedWidget:isVirtual() then
g_game.useWith(g_game.selectedThing, clickedWidget:getItem())
elseif clickedWidget.isBattleButton or clickedWidget.battleButtonChild then
local battleButton = clickedWidget
if clickedWidget.battleButtonChild then
battleButton = clickedWidget:getParent()
end
g_game.useWith(g_game.selectedThing, battleButton.creature)
end
end
end

View File

@ -15,6 +15,7 @@ Module
- game_containers
- game_combatcontrols
- game_hotkeys
- game_battle
onLoad: |
dofile 'game'

View File

@ -0,0 +1,365 @@
Battle = {}
--TODO
--onCreatureAppears onCreatureHealthChange onCreatureDisappears
--reloadable/disconnects
-- private variables
local battleWindow
local battleButton
local battlePanel
local lastBattleButtonSwitched
local checkCreaturesEvent
local battleButtonsByCreaturesList = {}
local mouseWidget
local hidePlayersButton
local hideNPCsButton
local hideMonstersButton
local hideSkullsButton
local hidePartyButton
local battleButtonColors = {
onIdle = {notHovered = '#888888', hovered = '#FFFFFF' },
onTargeted = {notHovered = '#FF0000', hovered = '#FF8888' },
onFollowed = {notHovered = '#00FF00', hovered = '#88FF88' }
}
local lifeBarColors = {} --Must be sorted by percentAbose
table.insert(lifeBarColors, {percentAbove = 92, color = '#00BC00' } )
table.insert(lifeBarColors, {percentAbove = 60, color = '#50A150' } )
table.insert(lifeBarColors, {percentAbove = 30, color = '#A1A100' } )
table.insert(lifeBarColors, {percentAbove = 8, color = '#3C2727' } )
table.insert(lifeBarColors, {percentAbove = 3, color = '#3C0000' } )
table.insert(lifeBarColors, {percentAbove = -1, color = '#4F0000' } )
-- public functions
function Battle.create()
battleWindow = displayUI('battle.otui', { parent = g_game.gameRightPanel })
battleWindow:hide()
battleButton = TopMenu.addGameButton('battleButton', 'Battle (Ctrl+B)', '/game_battle/battle.png', Battle.toggle)
Keyboard.bindKeyDown('Ctrl+B', Battle.toggle)
battlePannel = battleWindow:getChildById('battlePanel')
hidePlayersButton = battleWindow:getChildById('hidePlayers')
hideNPCsButton = battleWindow:getChildById('hideNPCs')
hideMonstersButton = battleWindow:getChildById('hideMonsters')
hideSkullsButton = battleWindow:getChildById('hideSkulls')
hidePartyButton = battleWindow:getChildById('hideParty')
mouseWidget = createWidget('UIButton')
mouseWidget:setVisible(false)
mouseWidget:setFocusable(false)
connect(UIWidget, { onHoverChange = Battle.onbattlePannelHoverChange,
onMouseRelease = Battle.onMouseRelease } )
connect(Creature, { onSkullChange = Battle.checkCreatureSkull,
onEmblemChange = Battle.checkCreatureEmblem } )
connect(g_game, { onAttackingCreatureChange = Battle.onAttack,
onFollowingCreatureChange = Battle.onFollow } )
addEvent(Battle.addAllCreatures)
checkCreaturesEvent = scheduleEvent(Battle.checkCreatures, 200)
end
function Battle.destroy()
Keyboard.unbindKeyDown('Ctrl+B')
battlePannel = nil
lastBattleButtonTargeted = nil
lastBattleButtonFollowed = nil
battleButtonsByCreaturesList = {}
removeEvent(checkCreaturesEvent)
hidePlayersButton = nil
hideNPCsButton = nil
hideMonstersButton = nil
hideSkullsButton = nil
hidePartyButton = nil
checkCreaturesEvent = nil
battleButton:destroy()
battleButton = nil
battleWindow:destroy()
battleWindow = nil
disconnect(UIWidget, { onHoverChange = Battle.onbattlePannelHoverChange,
onMouseRelease = Battle.onMouseRelease } )
disconnect(Creature, { onSkullChange = Battle.checkCreatureSkull,
onEmblemChange = Battle.checkCreatureEmblem } )
disconnect(g_game, { onAttackingCreatureChange = Battle.onAttack } )
end
function Battle.toggle()
local visible = not battleWindow:isExplicitlyVisible()
battleWindow:setVisible(visible)
battleButton:setOn(visible)
end
function Battle.addAllCreatures()
local spectators = {}
local player = g_game.getLocalPlayer()
if player then
creatures = g_map.getSpectators(player:getPosition(), false)
for i, creature in ipairs(creatures) do
if creature ~= player and Battle.doCreatureFitFilters(creature) then
table.insert(spectators, creature)
end
end
end
for i, v in pairs(spectators) do
Battle.addCreature(v)
end
end
function Battle.doCreatureFitFilters(creature)
local hidePlayers = hidePlayersButton:isChecked()
local hideNPCs = hideNPCsButton:isChecked()
local hideMonsters = hideMonstersButton:isChecked()
local hideSkulls = hideSkullsButton:isChecked()
local hideParty = hidePartyButton:isChecked()
if hidePlayers and not creature:asMonster() and not creature:asNpc() then
return false
elseif hideNPCs and creature:asNpc() then
return false
elseif hideMonsters and creature:asMonster() then
return false
elseif hideSkulls and creature:getSkull() == SkullNone then
return false
elseif hideParty and creature:getShield() > ShieldWhiteBlue then
return false
end
return true
end
function Battle.checkCreatures()
local player = g_game.getLocalPlayer()
if player then
local spectators = {}
-- reloading list of spectators
local creaturesAppeared = {}
creatures = g_map.getSpectators(player:getPosition(), false)
for i, creature in ipairs(creatures) do
if creature ~= player and Battle.doCreatureFitFilters(creature) then
-- searching for creatures that appeared on battle list
local battleButton = battleButtonsByCreaturesList[creature:getId()]
if battleButton == nil then
table.insert(creaturesAppeared, creature)
else
Battle.setLifeBarPercent(battleButton, creature:getHealthPercent())
end
spectators[creature:getId()] = creature
end
end
for i, v in pairs(creaturesAppeared) do
Battle.addCreature(v)
end
-- searching for creatures that disappeared from battle list
local creaturesDisappeared = {}
for i, creature in pairs(battleButtonsByCreaturesList) do
if spectators[creature.creatureId] == nil then
table.insert(creaturesDisappeared, creature.creature)
end
end
for i, v in pairs(creaturesDisappeared) do
Battle.removeCreature(v)
end
end
checkCreaturesEvent = scheduleEvent(Battle.checkCreatures, 500)
end
function Battle.addCreature(creature)
local creatureId = creature:getId()
if battleButtonsByCreaturesList[creatureId] == nil then
local battleButton = displayUI('battleButton.otui', { parent = battlePannel })
local creatureWidget = battleButton:getChildById('creature')
local labelWidget = battleButton:getChildById('label')
local lifeBarWidget = battleButton:getChildById('lifeBar')
battleButton:setId('BattleButton_' .. creature:getName():gsub('%s','_'))
battleButton.creatureId = creatureId
battleButton.creature = creature
battleButton.isHovered = false
battleButton.isTarget = false
battleButton.isFollowed = false
labelWidget:setText(creature:getName())
creatureWidget:setCreature(creature)
Battle.setLifeBarPercent(battleButton, creature:getHealthPercent())
battleButtonsByCreaturesList[creatureId] = battleButton
Battle.checkCreatureSkull(battleButton.creature)
Battle.checkCreatureEmblem(battleButton.creature)
end
end
function Battle.checkCreatureSkull(creature, skullId)
local battleButton = battleButtonsByCreaturesList[creature:getId()]
if battleButton then
local skullWidget = battleButton:getChildById('skull')
local labelWidget = battleButton:getChildById('label')
local creature = battleButton.creature
if creature:getSkull() ~= SkullNone then
skullWidget:setWidth(skullWidget:getHeight())
local imagePath = getSkullImagePath(creature:getSkull())
skullWidget:setImageSource('/game/' .. imagePath)
labelWidget:setMarginLeft(5)
else
skullWidget:setWidth(0)
if creature:getEmblem() == EmblemNone then
labelWidget:setMarginLeft(2)
end
end
end
end
function Battle.checkCreatureEmblem(creature, emblemId)
local battleButton = battleButtonsByCreaturesList[creature:getId()]
if battleButton then
local emblemId = emblemId or creature:getEmblem()
local emblemWidget = battleButton:getChildById('emblem')
local labelWidget = battleButton:getChildById('label')
local creature = battleButton.creature
if emblemId ~= EmblemNone then
emblemWidget:setWidth(emblemWidget:getHeight())
local imagePath = getEmblemImagePath(emblemId)
emblemWidget:setImageSource('/game/' .. imagePath)
emblemWidget:setMarginLeft(5)
labelWidget:setMarginLeft(5)
else
emblemWidget:setWidth(0)
emblemWidget:setMarginLeft(0)
if creature:getSkull() == SkullNone then
labelWidget:setMarginLeft(2)
end
end
end
end
function Battle.onMouseRelease(self, mousePosition, mouseButton)
if mouseButton == MouseRightButton then
local clickedWidget = g_game.gameUi:recursiveGetChildByPos(mousePosition)
if clickedWidget then
if clickedWidget:getStyleName() == 'BattleButton' then
g_game.createThingMenu(mousePosition, nil, nil, clickedWidget.creature)
return true
end
end
end
end
function Battle.removeCreature(creature)
local creatureId = creature:getId()
if battleButtonsByCreaturesList[creatureId] ~= nil then
if lastBattleButtonSwitched == battleButtonsByCreaturesList[creatureId] then
lastBattleButtonSwitched = nil
end
battleButtonsByCreaturesList[creatureId]:destroy()
battleButtonsByCreaturesList[creatureId] = nil
end
end
function Battle.setLifeBarPercent(battleButton, percent)
local lifeBarWidget = battleButton:getChildById('lifeBar')
lifeBarWidget:setPercent(percent)
local color
for i, v in pairs(lifeBarColors) do
if percent > v.percentAbove then
color = v.color
break
end
end
lifeBarWidget:setBackgroundColor(color)
end
function Battle.onButtonClick(battleButton)
if battleButton then
if battleButton.isTarget then
g_game.cancelAttack()
else
g_game.attack(battleButton.creature)
end
end
end
function Battle.onbattlePannelHoverChange(widget, hovered)
if widget.isBattleButton or widget.battleButtonChild then
local battleButton = widget
if widget.battleButtonChild then
battleButton = widget:getParent()
end
if battleButton then
battleButton.isHovered = hovered
Battle.checkBattleButton(battleButton)
end
end
end
function Battle.onAttack(creature)
local battleButton = creature and battleButtonsByCreaturesList[creature:getId()] or lastBattleButtonSwitched
if battleButton then
battleButton.isTarget = creature and true or false
Battle.checkBattleButton(battleButton)
end
end
function Battle.onFollow(creature)
local battleButton = creature and battleButtonsByCreaturesList[creature:getId()] or lastBattleButtonSwitched
if battleButton then
battleButton.isFollowed = creature and true or false
Battle.checkBattleButton(battleButton)
end
end
function Battle.checkBattleButton(battleButton)
local color = battleButtonColors.onIdle
if battleButton.isTarget then
color = battleButtonColors.onTargeted
elseif battleButton.isFollowed then
color = battleButtonColors.onFollowed
end
color = battleButton.isHovered and color.hovered or color.notHovered
if battleButton.isHovered or battleButton.isTarget or battleButton.isFollowed then
battleButton.creature:showStaticSquare(color)
battleButton:getChildById('creature'):setBorderWidth(1)
battleButton:getChildById('creature'):setBorderColor(color)
battleButton:getChildById('label'):setColor(color)
else
battleButton.creature:hideStaticSquare()
battleButton:getChildById('creature'):setBorderWidth(0)
battleButton:getChildById('label'):setColor(color)
end
if battleButton.isTarget or battleButton.isFollowed then
if lastBattleButtonSwitched and lastBattleButtonSwitched ~= battleButton then
lastBattleButtonSwitched.isTarget = false
lastBattleButtonSwitched.isFollowed = false
Battle.checkBattleButton(lastBattleButtonSwitched)
end
lastBattleButtonSwitched = battleButton
end
end
connect(g_game, { onGameStart = Battle.create,
onGameEnd = Battle.destroy } )

View File

@ -0,0 +1,7 @@
Module
name: game_battle
description: Manage battle window
author: OTClient team
website: https://github.com/edubart/otclient
onLoad: |
dofile 'battle'

View File

@ -0,0 +1,91 @@
BattleIcon < UICheckBox
size: 20 20
image-color: white
image-rect: 0 0 20 20
$hover !disabled:
color: #cccccc
$!checked:
image-clip: 0 0 20 20
$hover !checked:
image-clip: 0 40 20 20
$checked:
image-clip: 0 20 20 20
$hover checked:
image-clip: 0 60 20 20
$disabled:
image-color: #ffffff88
BattlePlayers < BattleIcon
image-source: /game_battle/battle_players.png
BattleNPCs < BattleIcon
image-source: /game_battle/battle_npcs.png
BattleMonsters < BattleIcon
image-source: /game_battle/battle_monsters.png
BattleSkulls < BattleIcon
image-source: /game_battle/battle_skulls.png
BattleParty < BattleIcon
image-source: /game_battle/battle_party.png
MiniWindow
id: battleWindow
text: Battle
height: 250
BattlePlayers
id: hidePlayers
tooltip: Hide players
anchors.top: parent.top
anchors.right: next.left
margin-right: 5
BattleNPCs
id: hideNPCs
tooltip: Hide Npc's
anchors.top: parent.top
anchors.right: next.left
margin-right: 5
BattleMonsters
id: hideMonsters
tooltip: Hide monsters
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
BattleSkulls
id: hideSkulls
tooltip: Hide non-skull players
anchors.top: prev.top
anchors.left: prev.right
margin-left: 5
BattleParty
id: hideParty
tooltip: Hide party members
anchors.top: prev.top
anchors.left: prev.right
margin-left: 5
HorizontalSeparator
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
margin-top: 5
Panel
id: battlePanel
anchors.fill: parent
anchors.top: prev.bottom
margin-top: 5
layout: verticalBox

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,56 @@
BattleButton < UIButton
BattleButton
height: 20
margin-top: 5
fixed-size: true
@onClick: Battle.onButtonClick(self)
&isBattleButton: true
UICreature
id: creature
size: 20 20
anchors.left: parent.left
anchors.top: parent.top
@onClick: Battle.onButtonClick(parent)
&battleButtonChild: true
UIWidget
id: spacer
width: 5
anchors.left: creature.right
anchors.top: creature.top
&battleButtonChild: true
UIWidget
id: skull
height: 11
anchors.left: spacer.right
anchors.top: spacer.top
&battleButtonChild: true
UIWidget
id: emblem
height: 11
anchors.left: skull.right
anchors.top: creature.top
&battleButtonChild: true
LargerLabel
id: label
anchors.left: emblem.right
anchors.top: creature.top
color: #888888
margin-left: 2
@onClick: Battle.onButtonClick(parent)
&battleButtonChild: true
ProgressBar
id: lifeBar
height: 5
anchors.left: spacer.right
anchors.right: parent.right
anchors.top: label.bottom
margin-top: 2
@onClick: Battle.onButtonClick(parent)
&battleButtonChild: true

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB