Togu
Advanced OT User
I've made some changes on game_skills module and I'd like to set minimum possible width to a label based on the text of the label. Is there a way to do that?
On the gif you can see that when game starts it loads a default width and when I reload the module he sets the minimum possible width based on the text. The only label starting with the right width is Walk Speed but it uses the same class as the other values so I dont know what is happening.
Also it should not start game showing the arrow and the green values cause the lua code says to setVisible(false) if the green value is equal or lesser than the other value. It is only being set to false when I reload.
skills.lua:
skill.otui: differences from original to mine Diff Checker (https://www.diffchecker.com/j1TN9Aow)
skills.otmod:
Edit:
Yeah I think I found the starting bug using the diff checker. I was missing a anchors line.
Anyway, I still want to know if there is a way to set minimum width to a label or to change anchors in skill.lua (so I can anchor.right to arrowLabel when its visible).
Edit: maybe the answer is here lol
Edit: solution
On the gif you can see that when game starts it loads a default width and when I reload the module he sets the minimum possible width based on the text. The only label starting with the right width is Walk Speed but it uses the same class as the other values so I dont know what is happening.
Also it should not start game showing the arrow and the green values cause the lua code says to setVisible(false) if the green value is equal or lesser than the other value. It is only being set to false when I reload.
skills.lua:
Lua:
skillsWindow = nil
skillsButton = nil
function init()
connect(LocalPlayer, {
onExperienceChange = onExperienceChange,
onLevelChange = onLevelChange,
onHealthChange = onHealthChange,
onManaChange = onManaChange,
onSoulChange = onSoulChange,
onSkillPointsChange = onSkillPointsChange,
onFreeCapacityChange = onFreeCapacityChange,
onTotalCapacityChange = onTotalCapacityChange,
onStaminaChange = onStaminaChange,
onRegenerationChange = onRegenerationChange,
onSpeedChange = onSpeedChange,
onBaseSpeedChange = onBaseSpeedChange,
onAttackSpeedChange = onAttackSpeedChange,
onMagicLevelChange = onMagicLevelChange,
onBaseMagicLevelChange = onBaseMagicLevelChange,
onNewBaseMagicLevelChange = onNewBaseMagicLevelChange,
onSkillChange = onSkillChange,
onBaseSkillChange = onBaseSkillChange,
onNewBaseSkillChange = onNewBaseSkillChange,
})
connect(g_game, {
onGameStart = refresh,
onGameEnd = offline
})
skillsButton = modules.client_topmenu.addRightGameToggleButton('skillsButton', tr('Skills') .. ' (Ctrl+S)', '/images/topbuttons/skills', toggle)
skillsButton:setOn(true)
skillsWindow = g_ui.loadUI('skills', modules.game_interface.getRightPanel())
g_keyboard.bindKeyDown('Ctrl+S', toggle)
refresh()
skillsWindow:setup()
end
function terminate()
disconnect(LocalPlayer, {
onExperienceChange = onExperienceChange,
onLevelChange = onLevelChange,
onHealthChange = onHealthChange,
onManaChange = onManaChange,
onSoulChange = onSoulChange,
onSkillPointsChange = onSkillPointsChange,
onFreeCapacityChange = onFreeCapacityChange,
onTotalCapacityChange = onTotalCapacityChange,
onStaminaChange = onStaminaChange,
onRegenerationChange = onRegenerationChange,
onSpeedChange = onSpeedChange,
onBaseSpeedChange = onBaseSpeedChange,
onAttackSpeedChange = onAttackSpeedChange,
onMagicLevelChange = onMagicLevelChange,
onBaseMagicLevelChange = onBaseMagicLevelChange,
onNewBaseMagicLevelChange = onNewBaseMagicLevelChange,
onSkillChange = onSkillChange,
onBaseSkillChange = onBaseSkillChange,
onNewBaseSkillChange = onNewBaseSkillChange,
})
disconnect(g_game, {
onGameStart = refresh,
onGameEnd = offline
})
g_keyboard.unbindKeyDown('Ctrl+S')
skillsWindow:destroy()
skillsButton:destroy()
end
function expForLevel(level)
return math.floor((50*level*level*level)/3 - 100*level*level + (850*level)/3 - 200)
end
function expToAdvance(currentLevel, currentExp)
return expForLevel(currentLevel+1) - currentExp
end
function resetSkillColor(id)
local skill = skillsWindow:recursiveGetChildById(id)
local widget = skill:getChildById('value')
widget:setColor('#bbbbbb')
end
function toggleSkill(id, state)
local skill = skillsWindow:recursiveGetChildById(id)
skill:setVisible(state)
end
function setSkillBase(id, value, baseValue)
if baseValue <= 0 or value < 0 then
return
end
local skill = skillsWindow:recursiveGetChildById(id)
local widget = skill:getChildById('value')
if value > baseValue then
widget:setColor('#008b00') -- green
skill:setTooltip(baseValue .. ' +' .. (value - baseValue))
elseif value < baseValue then
widget:setColor('#b22222') -- red
skill:setTooltip(baseValue .. ' ' .. (value - baseValue))
else
widget:setColor('#bbbbbb') -- default
skill:removeTooltip()
end
end
function setSkillValue(id, value)
local skill = skillsWindow:recursiveGetChildById(id)
local widget = skill:getChildById('value')
widget:setText(value)
end
function setSkillNewValue(id, newValue, currentValue)
local skill = skillsWindow:recursiveGetChildById(id)
local widgetArrow = skill:getChildById('arrow')
local widgetNewValue = skill:getChildById('newValue')
widgetNewValue:setText(newValue)
if newValue > currentValue then
widgetArrow:setVisible(true)
widgetNewValue:setVisible(true)
else
widgetArrow:setVisible(false)
widgetNewValue:setVisible(false)
end
end
function setSkillColor(id, value)
local skill = skillsWindow:recursiveGetChildById(id)
local widget = skill:getChildById('value')
widget:setColor(value)
end
function setSkillTooltip(id, value)
local skill = skillsWindow:recursiveGetChildById(id)
local widget = skill:getChildById('value')
widget:setTooltip(value)
end
function setSkillPercent(id, percent, tooltip, color)
local skill = skillsWindow:recursiveGetChildById(id)
local widget = skill:getChildById('percent')
if widget then
widget:setPercent(math.floor(percent))
if tooltip then
widget:setTooltip(tooltip)
end
if color then
widget:setBackgroundColor(color)
end
end
end
function checkAlert(id, value, maxValue, threshold, greaterThan)
if greaterThan == nil then greaterThan = false end
local alert = false
-- maxValue can be set to false to check value and threshold
-- used for regeneration checking
if type(maxValue) == 'boolean' then
if maxValue then
return
end
if greaterThan then
if value > threshold then
alert = true
end
else
if value < threshold then
alert = true
end
end
elseif type(maxValue) == 'number' then
if maxValue < 0 then
return
end
local percent = math.floor((value / maxValue) * 100)
if greaterThan then
if percent > threshold then
alert = true
end
else
if percent < threshold then
alert = true
end
end
end
if alert then
setSkillColor(id, '#b22222') -- red
else
resetSkillColor(id)
end
end
function refresh()
local player = g_game.getLocalPlayer()
if not player then return end
if expSpeedEvent then expSpeedEvent:cancel() end
expSpeedEvent = cycleEvent(checkExpSpeed, 30*1000)
onExperienceChange(player, player:getExperience())
onLevelChange(player, player:getLevel(), player:getLevelPercent())
onHealthChange(player, player:getHealth(), player:getMaxHealth())
onManaChange(player, player:getMana(), player:getMaxMana())
onSoulChange(player, player:getSoul())
onSkillPointsChange(player, player:getSkillPoints())
onFreeCapacityChange(player, player:getFreeCapacity())
onStaminaChange(player, player:getStamina())
onMagicLevelChange(player, player:getMagicLevel())
onNewBaseMagicLevelChange(player, player:getNewBaseMagicLevel())
onRegenerationChange(player, player:getRegenerationTime())
onSpeedChange(player, player:getSpeed())
onAttackSpeedChange(player, player:getAttackSpeed())
local hasAdditionalSkills = g_game.getFeature(GameAdditionalSkills)
for i = Skill.Fist, Skill.CriticalDamage do
onSkillChange(player, i, player:getSkillLevel(i))
if i > Skill.Fishing then
toggleSkill('skillId'.. i, hasAdditionalSkills)
end
end
for i = Skill.Fist, Skill.Fishing do
onNewBaseSkillChange(player, i, player:getNewBaseSkillLevel(i))
end
local regenerationTime = skillsWindow:recursiveGetChildById('regenerationTime')
local contentsPanel = skillsWindow:getChildById('contentsPanel')
skillsWindow:setContentMinimumHeight(46)
skillsWindow:setContentMaximumHeight(374)
end
function offline()
if expSpeedEvent then expSpeedEvent:cancel() expSpeedEvent = nil end
end
function toggle()
if skillsButton:isOn() then
skillsWindow:close()
skillsButton:setOn(false)
else
skillsWindow:open()
skillsButton:setOn(true)
end
end
function checkExpSpeed()
local player = g_game.getLocalPlayer()
if not player then return end
local currentExp = player:getExperience()
local currentTime = g_clock.seconds()
if player.lastExps ~= nil then
player.expSpeed = (currentExp - player.lastExps[1][1])/(currentTime - player.lastExps[1][2])
onLevelChange(player, player:getLevel(), player:getLevelPercent())
else
player.lastExps = {}
end
table.insert(player.lastExps, {currentExp, currentTime})
if #player.lastExps > 30 then
table.remove(player.lastExps, 1)
end
end
function onMiniWindowClose()
skillsButton:setOn(false)
end
function onExperienceChange(localPlayer, value)
setSkillValue('experience', value)
end
function onLevelChange(localPlayer, value, percent)
setSkillValue('level', value)
local text = tr('You have %s percent to go', 100 - percent) .. '\n' ..
tr('%s of experience left', expToAdvance(localPlayer:getLevel(), localPlayer:getExperience()))
if localPlayer.expSpeed ~= nil then
local expPerHour = math.floor(localPlayer.expSpeed * 3600)
if expPerHour > 0 then
local nextLevelExp = expForLevel(localPlayer:getLevel()+1)
local hoursLeft = (nextLevelExp - localPlayer:getExperience()) / expPerHour
local minutesLeft = math.floor((hoursLeft - math.floor(hoursLeft))*60)
hoursLeft = math.floor(hoursLeft)
text = text .. '\n' .. tr('%d of experience per hour', expPerHour)
text = text .. '\n' .. tr('Next level in %d hours and %d minutes', hoursLeft, minutesLeft)
end
end
setSkillPercent('level', percent, text)
end
function onHealthChange(localPlayer, health, maxHealth)
setSkillValue('health', health)
checkAlert('health', health, maxHealth, 30)
end
function onManaChange(localPlayer, mana, maxMana)
setSkillValue('mana', mana)
checkAlert('mana', mana, maxMana, 30)
end
function onSoulChange(localPlayer, soul)
setSkillValue('soul', soul)
end
function onSkillPointsChange(localPlayer, skillPoints)
setSkillValue('skillpoints', skillPoints)
end
function onFreeCapacityChange(localPlayer, freeCapacity)
setSkillValue('capacity', freeCapacity)
checkAlert('capacity', freeCapacity, localPlayer:getTotalCapacity(), 20)
end
function onTotalCapacityChange(localPlayer, totalCapacity)
checkAlert('capacity', localPlayer:getFreeCapacity(), totalCapacity, 20)
end
function onStaminaChange(localPlayer, stamina)
local hours = math.floor(stamina / 60)
local minutes = stamina % 60
if minutes < 10 then
minutes = '0' .. minutes
end
local percent = math.floor(100 * stamina / (42 * 60)) -- max is 42 hours --TODO not in all client versions
setSkillValue('stamina', hours .. ":" .. minutes)
--TODO not all client versions have premium time
if stamina > 2400 and g_game.getClientVersion() >= 1038 and localPlayer:isPremium() then
local text = tr("You have %s hours and %s minutes left", hours, minutes) .. '\n' ..
tr("Now you will gain 50%% more experience")
setSkillPercent('stamina', percent, text, 'green')
elseif stamina > 2400 and g_game.getClientVersion() >= 1038 and not localPlayer:isPremium() then
local text = tr("You have %s hours and %s minutes left", hours, minutes) .. '\n' ..
tr("You will not gain 50%% more experience because you aren't premium player, now you receive only 1x experience points")
setSkillPercent('stamina', percent, text, '#89F013')
elseif stamina > 2400 and g_game.getClientVersion() < 1038 then
local text = tr("You have %s hours and %s minutes left", hours, minutes) .. '\n' ..
tr("If you are premium player, you will gain 50%% more experience")
setSkillPercent('stamina', percent, text, 'green')
elseif stamina <= 2400 and stamina > 840 then
setSkillPercent('stamina', percent, tr("You have %s hours and %s minutes left", hours, minutes), 'orange')
elseif stamina <= 840 and stamina > 0 then
local text = tr("You have %s hours and %s minutes left", hours, minutes) .. "\n" ..
tr("You gain only 50%% experience and you don't may gain loot from monsters")
setSkillPercent('stamina', percent, text, 'red')
elseif stamina == 0 then
local text = tr("You have %s hours and %s minutes left", hours, minutes) .. "\n" ..
tr("You don't may receive experience and loot from monsters")
setSkillPercent('stamina', percent, text, 'black')
end
end
function onRegenerationChange(localPlayer, regenerationTime)
if not g_game.getFeature(GamePlayerRegenerationTime) or regenerationTime < 0 then
return
end
local minutes = math.floor(regenerationTime / 60)
local seconds = regenerationTime % 60
if seconds < 10 then
seconds = '0' .. seconds
end
setSkillValue('regenerationTime', minutes .. ":" .. seconds)
checkAlert('regenerationTime', regenerationTime, false, 300)
end
function onSpeedChange(localPlayer, speed)
setSkillValue('walkspeed', speed)
onBaseSpeedChange(localPlayer, localPlayer:getBaseSpeed())
end
function onBaseSpeedChange(localPlayer, baseSpeed)
setSkillBase('walkspeed', localPlayer:getSpeed(), baseSpeed)
end
function onAttackSpeedChange(localPlayer, attackSpeed)
setSkillValue('attackspeed', attackSpeed)
end
function onMagicLevelChange(localPlayer, magicLevel)
setSkillValue('magiclevel', magicLevel)
setSkillBase('magiclevel', localPlayer:getMagicLevel(), magicLevel)
end
function onBaseMagicLevelChange(localPlayer, baseMagicLevel)
setSkillBase('magiclevel', localPlayer:getMagicLevel(), baseMagicLevel)
end
function onNewBaseMagicLevelChange(localPlayer, newMagicLevel)
setSkillNewValue('magiclevel', newMagicLevel, localPlayer:getMagicLevel())
end
function onSkillChange(localPlayer, id, level)
setSkillValue('skillId' .. id, level)
setSkillBase('skillId'.. id, localPlayer:getSkillLevel(id), level)
end
function onBaseSkillChange(localPlayer, id, baseLevel)
setSkillBase('skillId'..id, localPlayer:getSkillLevel(id), baseLevel)
end
function onNewBaseSkillChange(localPlayer, id, level)
setSkillNewValue('skillId' .. id, level, localPlayer:getSkillLevel(id))
end
skill.otui: differences from original to mine Diff Checker (https://www.diffchecker.com/j1TN9Aow)
Code:
SkillFirstWidget < UIWidget
SkillButton < UIButton
height: 21
margin-bottom: 2
SmallSkillButton < SkillButton
height: 14
SkillNameLabel < GameLabel
font: verdana-11px-monochrome
anchors.top: parent.top
anchors.bottom: parent.bottom
SkillValueLabel < GameLabel
id: value
font: verdana-11px-monochrome
text-align: topright
anchors.top: parent.top
anchors.bottom: parent.bottom
SkillArrowLabel < GameLabel
id: arrow
font: verdana-11px-monochrome
text-align: topleft
width: 15
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: prev.right
margin-left: 5
!text: tr('->')
SkillNewValueLabel < GameLabel
id: newValue
font: verdana-11px-monochrome
text-align: topleft
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: prev.right
margin-left: 5
color: #008b00
SkillMinusButton < Button
id: minusbutton
font: verdana-11px-monochrome
width: 15
height: 15
margin-right: 1
anchors.right: prev.left
anchors.top: parent.top
anchors.bottom: parent.bottom
!text: tr('-')
SkillPlusButton < Button
id: plusbutton
font: verdana-11px-monochrome
width: 15
height: 15
margin-left: 2
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
!text: tr('+')
SkillPercentPanel < ProgressBar
id: percent
background-color: green
height: 5
margin-top: 15
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
phantom: false
MiniWindow
id: skillWindow
!text: tr('Skills')
height: 150
icon: /images/topbuttons/skills
@onClose: modules.game_skills.onMiniWindowClose()
&save: true
MiniWindowContents
padding-left: 5
padding-right: 5
layout: verticalBox
SkillButton
margin-top: 5
id: experience
height: 15
SkillNameLabel
anchors.left: parent.left
text-align:topleft
!text: tr('Experience')
SkillValueLabel
anchors.right: parent.right
SkillButton
id: level
SkillNameLabel
anchors.left: parent.left
text-align:topleft
!text: tr('Level')
SkillValueLabel
anchors.right: parent.right
SkillPercentPanel
background-color: red
SkillButton
id: health
height: 15
SkillNameLabel
text-align: topright
anchors.right: parent.right
margin-right: 96
!text: tr('Health')
SkillValueLabel
text-align: topleft
anchors.left: prev.right
margin-left: 5
SkillArrowLabel
SkillNewValueLabel
SkillButton
id: mana
height: 15
SkillNameLabel
text-align: topright
anchors.right: parent.right
margin-right: 96
!text: tr('Mana')
SkillValueLabel
text-align: topleft
anchors.left: prev.right
margin-left: 5
SkillArrowLabel
SkillNewValueLabel
SkillButton
id: soul
height: 15
SkillNameLabel
text-align: topright
anchors.right: parent.right
margin-right: 96
!text: tr('Soul')
SkillValueLabel
text-align: topleft
anchors.left: prev.right
margin-left: 5
SkillArrowLabel
SkillNewValueLabel
SkillButton
id: skillpoints
height: 15
SkillNameLabel
text-align: topright
anchors.right: parent.right
margin-right: 96
!text: tr('Points')
SkillValueLabel
text-align: topleft
anchors.left: prev.right
margin-left: 5
SkillArrowLabel
SkillNewValueLabel
SkillButton
id: capacity
height: 15
SkillNameLabel
text-align: topright
anchors.right: parent.right
margin-right: 96
!text: tr('Capacity')
SkillValueLabel
text-align: topleft
anchors.left: prev.right
margin-left: 5
SkillArrowLabel
SkillNewValueLabel
SkillButton
id: walkspeed
height: 15
SkillNameLabel
text-align: topright
anchors.right: parent.right
margin-right: 96
!text: tr('Walk Speed')
SkillValueLabel
text-align: topleft
anchors.left: prev.right
margin-left: 5
SkillArrowLabel
SkillNewValueLabel
SkillButton
id: attackspeed
height: 15
SkillNameLabel
text-align: topright
anchors.right: parent.right
margin-right: 96
!text: tr('Attack Speed')
SkillValueLabel
text-align: topleft
anchors.left: prev.right
margin-left: 5
SkillArrowLabel
SkillNewValueLabel
SkillButton
id: regenerationTime
SkillNameLabel
anchors.left: parent.left
text-align:topleft
!text: tr('Regeneration Time')
SkillValueLabel
anchors.right: parent.right
SkillPercentPanel
SkillButton
id: stamina
SkillNameLabel
anchors.left: parent.left
text-align: topleft
!text: tr('Stamina')
SkillValueLabel
anchors.right: parent.right
SkillPercentPanel
SmallSkillButton
id: magiclevel
SkillNameLabel
text-align: topright
anchors.right: parent.right
margin-right: 96
!text: tr('Magic Level')
SkillValueLabel
text-align: topleft
anchors.left: prev.right
margin-left: 5
SkillArrowLabel
SkillNewValueLabel
SkillPlusButton
SkillMinusButton
SmallSkillButton
id: skillId0
SkillNameLabel
text-align: topright
anchors.right: parent.right
margin-right: 96
!text: tr('Vitality')
SkillValueLabel
text-align: topleft
anchors.left: prev.right
margin-left: 5
SkillArrowLabel
SkillNewValueLabel
SkillPlusButton
SkillMinusButton
SmallSkillButton
id: skillId1
SkillNameLabel
text-align: topright
anchors.right: parent.right
margin-right: 96
!text: tr('Strenght')
SkillValueLabel
text-align: topleft
anchors.left: prev.right
margin-left: 5
SkillArrowLabel
SkillNewValueLabel
SkillPlusButton
SkillMinusButton
SmallSkillButton
id: skillId2
SkillNameLabel
text-align: topright
anchors.right: parent.right
margin-right: 96
!text: tr('Faith')
SkillValueLabel
text-align: topleft
anchors.left: prev.right
margin-left: 5
SkillArrowLabel
SkillNewValueLabel
SkillPlusButton
SkillMinusButton
SmallSkillButton
id: skillId3
SkillNameLabel
text-align: topright
anchors.right: parent.right
margin-right: 96
!text: tr('Intelligence')
SkillValueLabel
text-align: topleft
anchors.left: prev.right
margin-left: 5
SkillArrowLabel
SkillNewValueLabel
SkillPlusButton
SkillMinusButton
SmallSkillButton
id: skillId4
SkillNameLabel
text-align: topright
anchors.right: parent.right
margin-right: 96
!text: tr('Dexterity')
SkillValueLabel
text-align: topleft
anchors.left: prev.right
margin-left: 5
SkillArrowLabel
SkillNewValueLabel
SkillPlusButton
SkillMinusButton
SmallSkillButton
id: skillId5
SkillNameLabel
text-align: topright
anchors.right: parent.right
margin-right: 96
!text: tr('Defence')
SkillValueLabel
text-align: topleft
anchors.left: prev.right
margin-left: 5
SkillArrowLabel
SkillNewValueLabel
SkillPlusButton
SkillMinusButton
SmallSkillButton
id: skillId6
SkillNameLabel
text-align: topright
anchors.right: parent.right
margin-right: 96
!text: tr('Endurance')
SkillValueLabel
text-align: topleft
anchors.left: prev.right
margin-left: 5
SkillArrowLabel
SkillNewValueLabel
SkillPlusButton
SkillMinusButton
SmallSkillButton
id: skillId7
SkillNameLabel
anchors.left: parent.left
text-align:topleft
!text: tr('Critical Hit Chance')
SkillValueLabel
anchors.right: parent.right
SmallSkillButton
id: skillId8
SkillNameLabel
anchors.left: parent.left
text-align:topleft
!text: tr('Critical Hit Damage')
SkillValueLabel
anchors.right: parent.right
skills.otmod:
Code:
Module
name: game_skills
description: Manage skills window
author: baxnie, edubart
website: https://github.com/edubart/otclient
sandboxed: true
scripts: [ skills ]
@onLoad: init()
@onUnload: terminate()
dependencies:
- game_interface
Edit:
Yeah I think I found the starting bug using the diff checker. I was missing a anchors line.
Anyway, I still want to know if there is a way to set minimum width to a label or to change anchors in skill.lua (so I can anchor.right to arrowLabel when its visible).
Edit: maybe the answer is here lol
Code:
function createWindow()
localesWindow = g_ui.displayUI('locales')
local localesPanel = localesWindow:getChildById('localesPanel')
local layout = localesPanel:getLayout()
local spacing = layout:getCellSpacing()
local size = layout:getCellSize()
local count = 0
for name,locale in pairs(installedLocales) do
local widget = g_ui.createWidget('LocalesButton', localesPanel)
widget:setImageSource('/images/flags/' .. name .. '')
widget:setText(locale.languageName)
widget.onClick = function() selectFirstLocale(name) end
count = count + 1
end
count = math.max(1, math.min(count, 3))
localesPanel:setWidth(size.width*count + spacing*(count-1))
addEvent(function() addEvent(function() localesWindow:raise() localesWindow:focus() end) end)
end
Edit: solution
Code:
widget:setWidth(widget:getTextSize().width)
Last edited: