How can I display a different image in characterlist when I have a different vocation? For example, if I create a character then i have vocation NONE, but when i join to clan i have vocation HUNTER, I want to display a different image in characterlist based on my vocation.
It is not very clear to me. Maybe someone could show or explain what I need to do?
Distribution TFS 1.2 Pokedash by Pota
OTCV8
Characterlist.lua
util.lua
newcharacterlist.otui
vocations.xml
It is not very clear to me. Maybe someone could show or explain what I need to do?
Distribution TFS 1.2 Pokedash by Pota
OTCV8
Characterlist.lua
LUA:
CharacterList = { }
-- private variables
local charactersWindow
local loadBox
local characterList
local characterListPanel
local errorBox
local waitingWindow
--local autoReconnectButton
local updateWaitEvent
local resendWaitEvent
local loginEvent
--local autoReconnectEvent
--local lastLogout = 0
-- private functions
local function tryLogin(charInfo, tries)
tries = tries or 1
if tries > 50 then
return
end
if g_game.isOnline() then
if tries == 1 then
g_game.safeLogout()
end
loginEvent = scheduleEvent(function() tryLogin(charInfo, tries+1) end, 100)
return
end
CharacterList.hide()
g_game.loginWorld(G.account, G.password, charInfo.worldName, charInfo.worldHost, charInfo.worldPort, charInfo.characterName, G.authenticatorToken, G.sessionKey)
-- g_logger.info("Login to " .. charInfo.worldHost .. ":" .. charInfo.worldPort)
loadBox = displayCancelBox(tr('Please wait'), tr('Connecting to game server...'))
connect(loadBox, { onCancel = function()
loadBox = nil
g_game.cancelLogin()
CharacterList.show()
end })
-- save last used character
g_settings.set('last-used-character', charInfo.characterName)
g_settings.set('last-used-world', charInfo.worldName)
end
local function updateWait(timeStart, timeEnd)
if waitingWindow then
local time = g_clock.seconds()
if time <= timeEnd then
local percent = ((time - timeStart) / (timeEnd - timeStart)) * 100
local timeStr = string.format("%.0f", timeEnd - time)
local progressBar = waitingWindow:getChildById('progressBar')
progressBar:setPercent(percent)
local label = waitingWindow:getChildById('timeLabel')
label:setText(tr('Trying to reconnect in %s seconds.', timeStr))
updateWaitEvent = scheduleEvent(function() updateWait(timeStart, timeEnd) end, 1000 * progressBar:getPercentPixels() / 100 * (timeEnd - timeStart))
return true
end
end
if updateWaitEvent then
updateWaitEvent:cancel()
updateWaitEvent = nil
end
end
local function resendWait()
if waitingWindow then
waitingWindow:destroy()
waitingWindow = nil
if updateWaitEvent then
updateWaitEvent:cancel()
updateWaitEvent = nil
end
if charactersWindow then
local selected = characterList:getFocusedChild()
if selected then
local charInfo = { worldHost = selected.worldHost,
worldPort = selected.worldPort,
worldName = selected.worldName,
characterName = selected.characterName }
tryLogin(charInfo)
end
end
end
end
local function onLoginWait(message, time)
CharacterList.destroyLoadBox()
waitingWindow = g_ui.displayUI('waitinglist')
local label = waitingWindow:getChildById('infoLabel')
label:setText(message)
updateWaitEvent = scheduleEvent(function() updateWait(g_clock.seconds(), g_clock.seconds() + time) end, 0)
resendWaitEvent = scheduleEvent(resendWait, time * 1000)
end
function onGameLoginError(message)
CharacterList.destroyLoadBox()
errorBox = displayErrorBox(tr("Login Error"), message)
errorBox.onOk = function()
errorBox = nil
CharacterList.showAgain()
end
scheduleAutoReconnect()
end
function onGameLoginToken(unknown)
CharacterList.destroyLoadBox()
-- TODO: make it possible to enter a new token here / prompt token
errorBox = displayErrorBox(tr("Two-Factor Authentification"), 'A new authentification token is required.\nPlease login again.')
errorBox.onOk = function()
errorBox = nil
EnterGame.show()
end
end
function onGameConnectionError(message, code)
CharacterList.destroyLoadBox()
if (not g_game.isOnline() or code ~= 2) and not errorBox then -- code 2 is normal disconnect, end of file
local text = translateNetworkError(code, g_game.getProtocolGame() and g_game.getProtocolGame():isConnecting(), message)
errorBox = displayErrorBox(tr("Connection Error"), text)
errorBox.onOk = function()
errorBox = nil
CharacterList.showAgain()
end
end
-- scheduleAutoReconnect()
end
function onGameUpdateNeeded(signature)
CharacterList.destroyLoadBox()
errorBox = displayErrorBox(tr("Update needed"), tr('Enter with your account again to update your client.'))
errorBox.onOk = function()
errorBox = nil
CharacterList.showAgain()
-- end
--end
--
--function onGameEnd()
-- scheduleAutoReconnect()
-- CharacterList.showAgain()
--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() or g_game.isOnline() then
-- return
-- end
-- if errorBox then
-- errorBox:destroy()
-- errorBox = nil
-- end
-- CharacterList.doLogin()
end
-- public functions
function CharacterList.init()
--if USE_NEW_ENERGAME then return end
connect(g_game, { onLoginError = onGameLoginError })
connect(g_game, { onLoginToken = onGameLoginToken })
connect(g_game, { onUpdateNeeded = onGameUpdateNeeded })
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)
end
end
function CharacterList.terminate()
--if USE_NEW_ENERGAME then return end
disconnect(g_game, { onLoginError = onGameLoginError })
disconnect(g_game, { onLoginToken = onGameLoginToken })
disconnect(g_game, { onUpdateNeeded = onGameUpdateNeeded })
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
charactersWindow:destroy()
charactersWindow = nil
end
if loadBox then
g_game.cancelLogin()
loadBox:destroy()
loadBox = nil
end
if waitingWindow then
waitingWindow:destroy()
waitingWindow = nil
end
if updateWaitEvent then
updateWaitEvent:cancel()
--removeEvent(updateWaitEvent)
updateWaitEvent = nil
end
if resendWaitEvent then
--removeEvent(resendWaitEvent)
resendWaitEvent:cancel()
resendWaitEvent = nil
end
if loginEvent then
removeEvent(loginEvent)
loginEvent = nil
end
CharacterList = nil
end
function CharacterList.create(characters, account, otui)
if not otui then otui = 'newcharacterlist' end
if charactersWindow then
charactersWindow:destroy()
end
charactersWindow = g_ui.displayUI(otui)
characterList = charactersWindow:getChildById('characters')
-- autoReconnectButton = charactersWindow:getChildById('autoReconnect')
-- characters
G.characters = characters
G.characterAccount = account
characterList:destroyChildren()
local accountStatusLabel = charactersWindow:getChildById('accountStatusLabel')
local focusLabel
for i,characterInfo in ipairs(characters) do
local widget = g_ui.createWidget('CharacterWidget', characterList)
widget:setImageSource('/images/trainerCards/' .. getVocationNameById(characterInfo.vocation))
widget:getChildById("ClaICON"):setImageSource('/images/trainerCards/clans/' .. getVocationNameById(characterInfo.vocation))
--g_ui.createWidget('Character', widget):getOutfit(characterInfo.outfit)
for key,value in pairs(characterInfo) do
local subWidget = widget:getChildById(key)
if subWidget then
if key == 'outfit' then -- it's an exception
subWidget:setOutfit(value)
else
local text = value
if subWidget.baseText and subWidget.baseTranslate then
text = tr(subWidget.baseText, text)
elseif subWidget.baseText then
text = string.format(subWidget.baseText, text)
end
subWidget:setText(text)
end
end
end
-- these are used by login
widget.characterName = characterInfo.name
widget.worldName = characterInfo.worldName
widget.worldHost = characterInfo.worldIp
widget.worldPort = characterInfo.worldPort
connect(widget, { onDoubleClick = function () CharacterList.doLogin() return true end } )
if i == 1 or (g_settings.get('last-used-character') == widget.characterName and g_settings.get('last-used-world') == widget.worldName) then
focusLabel = widget
end
end
if focusLabel then
characterList:focusChild(focusLabel, KeyboardFocusReason)
addEvent(function() characterList:ensureChildVisible(focusLabel) end)
end
-- characterList.onChildFocusChange = function()
-- removeEvent(autoReconnectEvent)
-- autoReconnectEvent = nil
-- end
-- account
local status = ''
if account.status == AccountStatus.Frozen then
status = tr(' (Frozen)')
elseif account.status == AccountStatus.Suspended then
status = tr(' (Suspended)')
end
--if account.subStatus == SubscriptionStatus.Free and account.premDays < 1 then
if account.subStatus == SubscriptionStatus.Free then
accountStatusLabel:setText(('%s%s'):format(tr('Free Account'), status))
elseif account.subStatus == SubscriptionStatus.Premium then
if account.premDays == 0 or account.premDays == 65535 then
accountStatusLabel:setText(('%s%s'):format(tr('Gratis Premium Account'), status))
else
accountStatusLabel:setText(('%s%s'):format(tr('Premium Account (%s) days left', account.premDays), status))
end
end
if account.premDays > 0 and account.premDays <= 7 then
accountStatusLabel:setOn(true)
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()
CharacterList.hide(true)
if charactersWindow then
characterList = nil
charactersWindow:destroy()
charactersWindow = nil
end
end
function CharacterList.show()
if loadBox or errorBox or not charactersWindow then return end
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()
if showLogin and EnterGame and not g_game.isOnline() then
EnterGame.show()
end
end
function CharacterList.showAgain()
if characterList and characterList:hasChildren() then
CharacterList.show()
end
end
function CharacterList.isVisible()
if charactersWindow and charactersWindow:isVisible() then
return true
end
return false
end
function CharacterList.doLogin()
--removeEvent(autoReconnectEvent)
--autoReconnectEvent = nil
local selected = characterList:getFocusedChild()
if selected then
local charInfo = { worldHost = selected.worldHost,
worldPort = selected.worldPort,
worldName = selected.worldName,
characterName = selected.characterName }
charactersWindow:hide()
if loginEvent then
removeEvent(loginEvent)
loginEvent = nil
end
tryLogin(charInfo)
else
displayErrorBox(tr('Error'), tr('You must select a character to login!'))
end
end
function CharacterList.destroyLoadBox()
if loadBox then
loadBox:destroy()
loadBox = nil
end
end
function CharacterList.cancelWait()
if waitingWindow then
waitingWindow:destroy()
waitingWindow = nil
end
if updateWaitEvent then
removeEvent(updateWaitEvent)
updateWaitEvent = nil
end
if resendWaitEvent then
removeEvent(resendWaitEvent)
resendWaitEvent = nil
end
CharacterList.destroyLoadBox()
CharacterList.showAgain()
end
util.lua
LUA:
function postostring(pos)
return pos.x .. " " .. pos.y .. " " .. pos.z
end
function dirtostring(dir)
for k,v in pairs(Directions) do
if v == dir then
return k
end
end
end
function getVocationNameById(vocation)
if (vocation == 0) then
return "hunter"
elseif (vocation == 2) then
return "catcher"
elseif (vocation == 3) then
return "healer"
elseif (vocation == 4) then
return "blocker"
elseif (vocation == 5) then
return "explorer"
end
return "none"
end
newcharacterlist.otui
Code:
Character < Creature
fixed-creature-size: true
anchors.top: parent.top
anchors.left: parent.left
margin-top: 45
margin-left: 140
image-source: ~
CharacterWidget < UIWidget
image-source: /images/trainerCards/none
margin: 4
size: 290 80
&updateOnStates: |
function(self)
local children = self:getChildren()
for i=1,#children do
children[i]:setOn(self:isFocused())
end
end
@onFocusChange: self:updateOnStates()
@onSetup: self:updateOnStates()
opacity: 0.7
$focus:
opacity: 1.0
Label
id: name
color: #aaaaaa
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
font: verdana-11px-monochrome
text-auto-resize: true
margin-top: 12
margin-left: 15
$on:
color: #ffffff
Label
visible: true
id: worldName
color: #ffffff
anchors.top: ClaICON.top
anchors.left: ClaICON.left
margin-left: 310
margin-top: 15
font: verdana-11px-monochrome
text-auto-resize: true
text-align: center
&baseText: '%s'
$on:
color: #ffffff
Label
id: level
color: #ffffff
anchors.top: ClaICON.top
anchors.left: ClaICON.left
margin-left: 43
margin-top: 13
font: verdana-11px-monochrome
text-auto-resize: true
text-align: center
$on:
color: #ffffff
UIWidget
//ICONE DO CLA
id: ClaICON
image-source: /images/trainerCards/clans/none
size: 40 40
anchors.top: parent.top
anchors.left: parent.left
margin-top: 110
margin-left: 10
UIWidget
id: pokemon1
color: #5C5C5C
anchors.bottom: parent.bottom
anchors.left: parent.left
margin-bottom: 20
margin-left: 19
image-source: ~
size: 50 54
UIWidget
id: pokemon2
color: #5C5C5C
anchors.bottom: parent.bottom
anchors.left: parent.left
margin-bottom: 20
margin-left: 80
image-source: ~
size: 50 54
UIWidget
id: pokemon3
color: #5C5C5C
anchors.bottom: parent.bottom
anchors.left: parent.left
margin-bottom: 20
margin-left: 145
image-source: ~
size: 50 54
UIWidget
id: pokemon4
color: #5C5C5C
anchors.bottom: parent.bottom
anchors.left: parent.left
margin-bottom: 20
margin-left: 208
image-source: ~
size: 50 54
UIWidget
id: pokemon5
color: #5C5C5C
anchors.bottom: parent.bottom
anchors.left: parent.left
margin-bottom: 20
margin-left: 271
image-source: ~
size: 50 54
UIWidget
id: pokemon6
color: #5C5C5C
anchors.bottom: parent.bottom
anchors.left: parent.left
margin-bottom: 20
margin-left: 335
image-source: ~
size: 50 54
MainWindow
id: charactersWindow
image-source: images/background_characterlist
size: 881 459
padding: 0
focusable: false
draggable: false
visible: false
@onEnter: CharacterList.doLogin()
@onEscape: CharacterList.hide(true)
@onSetup: |
g_keyboard.bindKeyPress('Up', function() self:getChildById('characters'):focusPreviousChild(KeyboardFocusReason) end, self)
g_keyboard.bindKeyPress('Down', function() self:getChildById('characters'):focusNextChild(KeyboardFocusReason) end, self)
UIWidget
//ICONE DO CLA
id: ClaICON
image-source: images/time
size: 30 30
anchors.bottom: parent.bottom
anchors.left: parent.left
margin-bottom: 75
margin-left: 20
ScrollableFlatPanel
id: characters
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
margin-top: 90
margin-bottom: 132
margin-left: 18
margin-right: 18
image-source: ~
padding: 0
layout:
type: horizontalBox
cell-size: 404 224
flow: true
cell-spacing: 1
horizontal-scrollbar: characterListScrollBar
auto-focus: first
focusable: false
HorizontalScrollBar
id: characterListScrollBar
anchors.top: parent.top
anchors.bottom: characters.bottom
anchors.top: characters.top
anchors.right: parent.right
anchors.left: parent.left
margin-bottom: -17
margin-top: 240
margin-left: 25
margin-right: 25
step: 15
pixels-scroll: true
Label
id: accountStatusCaption
!text: tr('Account Status') .. ':'
anchors.left: parent.left
anchors.bottom: separator.top
margin-bottom: 20
margin-left: 50
Label
id: accountStatusLabel
!text: tr('Free Account')
anchors.left: accountStatusCaption.right
anchors.right: parent.right
anchors.bottom: separator.top
margin-left: 5
margin-bottom: 19
text-auto-resize: true
$on:
color: #FF0000
HorizontalSeparator
id: separator
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
margin-bottom: 60
opacity: 0
//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
//UIWidget
// size: 27 30
// image-source: images/new_character
// !tooltip: tr('Novo Personagem')
// anchors.top: parent.top
// anchors.right: parent.right
// margin-top: 30
// margin-right: 15
// @onClick: modules.poke_create.showChar()
// opacity: 0.8
// $hover:
// opacity: 1
// $pressed:
// opacity: 0.9
UIButton
id: buttonOk
image-source: images/selecionar
size: 130 37
anchors.right: parent.right
anchors.bottom: parent.bottom
margin-right: 305
margin-bottom: 11
opacity: 1
@onClick: CharacterList.doLogin()
$hover:
size: 135 42
opacity: 1
$pressed:
size: 135 42
opacity: 0.9
UIButton
id: buttonCancel
image-source: images/voltar
size: 130 37
anchors.right: buttonOk.right
anchors.bottom: parent.bottom
margin-right: 140
margin-bottom: 11
@onClick: CharacterList.hide(true)
opacity: 1
$hover:
size: 135 42
opacity: 1
$pressed:
size: 135 42
opacity: 0.9
vocations.xml
XML:
<?xml version="1.0" encoding="UTF-8"?>
<vocations>
<vocation id="0" clientid="0" name="None" description="none" gaincap="0" gainhp="5" gainmana="5" gainhpticks="6" gainhpamount="1" gainmanaticks="6" gainmanaamount="1" manamultiplier="4.0" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="0">
<formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" />
<skill id="0" multiplier="1.5" />
<skill id="1" multiplier="2.0" />
<skill id="2" multiplier="2.0" />
<skill id="3" multiplier="2.0" />
<skill id="4" multiplier="2.0" />
<skill id="5" multiplier="1.5" />
<skill id="6" multiplier="1.1" />
</vocation>
<vocation id="1" clientid="3" name="Hunter" description="a hunter" gaincap="0" gainhp="5" gainmana="5" gainhpticks="6" gainhpamount="1" gainmanaticks="6" gainmanaamount="1" manamultiplier="4.0" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="1">
<formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" />
<skill id="0" multiplier="1.5" />
<skill id="1" multiplier="2.0" />
<skill id="2" multiplier="2.0" />
<skill id="3" multiplier="2.0" />
<skill id="4" multiplier="2.0" />
<skill id="5" multiplier="1.5" />
<skill id="6" multiplier="1.1" />
</vocation>
<vocation id="2" clientid="4" name="Catcher" description="a catcher" gaincap="0" gainhp="5" gainmana="5" gainhpticks="6" gainhpamount="1" gainmanaticks="6" gainmanaamount="1" manamultiplier="4.0" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="2">
<formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" />
<skill id="0" multiplier="1.5" />
<skill id="1" multiplier="2.0" />
<skill id="2" multiplier="2.0" />
<skill id="3" multiplier="2.0" />
<skill id="4" multiplier="2.0" />
<skill id="5" multiplier="1.5" />
<skill id="6" multiplier="1.1" />
</vocation>
<vocation id="3" clientid="2" name="Healer" description="a healer" gaincap="0" gainhp="5" gainmana="5" gainhpticks="6" gainhpamount="1" gainmanaticks="6" gainmanaamount="1" manamultiplier="4.0" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="3">
<formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" />
<skill id="0" multiplier="1.5" />
<skill id="1" multiplier="2.0" />
<skill id="2" multiplier="2.0" />
<skill id="3" multiplier="2.0" />
<skill id="4" multiplier="2.0" />
<skill id="5" multiplier="1.5" />
<skill id="6" multiplier="1.1" />
</vocation>
<vocation id="4" clientid="1" name="Blocker" description="a blocker" gaincap="0" gainhp="5" gainmana="5" gainhpticks="6" gainhpamount="1" gainmanaticks="6" gainmanaamount="1" manamultiplier="4.0" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="4">
<formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" />
<skill id="0" multiplier="1.5" />
<skill id="1" multiplier="2.0" />
<skill id="2" multiplier="2.0" />
<skill id="3" multiplier="2.0" />
<skill id="4" multiplier="2.0" />
<skill id="5" multiplier="1.5" />
<skill id="6" multiplier="1.1" />
</vocation>
<vocation id="5" clientid="3" name="Explorer" description="an explorer" gaincap="0" gainhp="5" gainmana="5" gainhpticks="6" gainhpamount="1" gainmanaticks="6" gainmanaamount="1" manamultiplier="4.0" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="5">
<formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" />
<skill id="0" multiplier="1.5" />
<skill id="1" multiplier="2.0" />
<skill id="2" multiplier="2.0" />
<skill id="3" multiplier="2.0" />
<skill id="4" multiplier="2.0" />
<skill id="5" multiplier="1.5" />
<skill id="6" multiplier="1.1" />
</vocation>
</vocations>