Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
235 changes: 149 additions & 86 deletions modules/game_skills/skills.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ skillsWindow = nil
skillsButton = nil
skillsSettings = nil
local ExpRating = {}
local smallSkillsCache = {}

-- Cache for stats data when UI elements are hidden
local statsCache = {
Expand Down Expand Up @@ -38,8 +39,6 @@ local statsCache = {
amplification = 0
}



local function setupUIButtons()
local toggleFilterButton = skillsWindow:recursiveGetChildById('toggleFilterButton')
if toggleFilterButton then
Expand Down Expand Up @@ -120,9 +119,9 @@ function init()
end

setupUIButtons()
refresh()
skillsWindow:setup()
if g_game.isOnline() then
online()
skillsWindow:setupOnStart()
end
end
Expand Down Expand Up @@ -169,23 +168,30 @@ end

local SKILL_GROUPS = {
offence = {
'skillId7', 'skillId8', 'skillId9', 'skillId10', 'skillId11', 'skillId12',
'skillId13', 'skillId14', 'skillId15', 'skillId16', 'separadorOnOffenceInfoChange',
'damageHealing', 'attackValue', 'convertedDamage', 'convertedElement',
'criticalHit', 'lifeLeech', 'manaLeech', 'criticalChance', 'criticalExtraDamage', 'onslaught'
'lifeLeech', 'manaLeech', 'criticalChance', 'criticalExtraDamage', 'onslaught'
},
defence = {
'physicalResist', 'fireResist', 'earthResist', 'energyResist', 'IceResist',
'HolyResist', 'deathResist', 'HealingResist', 'drowResist', 'lifedrainResist',
'manadRainResist', 'defenceValue', 'armorValue', 'mitigation', 'dodge',
'damageReflection', 'separadorOnDefenseInfoChange'
'damageReflection'
},
misc = {
'momentum', 'transcendence', 'amplification', 'separadorOnForgeBonusesChange'
'momentum', 'transcendence', 'amplification'
},
individual = {
'level', 'stamina', 'offlineTraining', 'magiclevel', 'skillId0', 'skillId1',
'skillId2', 'skillId3', 'skillId4', 'skillId5', 'skillId6'
},
GameAdditionalSkills = {
'skillId7', 'skillId8', 'skillId9', 'skillId10', 'skillId11', 'skillId12'
},
GameForgeSkillStats = {
'skillId13', 'skillId14', 'skillId15'
},
GameForgeSkillStats1332 = {
'skillId16'
}
}

Expand All @@ -196,7 +202,18 @@ local function setSkillGroupVisibility(groupName, visible)
for _, skillId in pairs(skills) do
local skill = skillsWindow:recursiveGetChildById(skillId)
if skill then
skill:setVisible(visible)
if visible then
local valueWidget = skill:getChildById('value')
local text = valueWidget and valueWidget:getText() or ""
if g_game.getClientVersion() >= 1410 then
skill:setVisible(text ~= "" and text ~= "0" and text ~= "0%" and
text ~= "+ 0%" and text ~= "0.0%" and text ~= "+ 0.0%")
else
skill:setVisible(true)
end
else
skill:setVisible(false)
end
end
end
end
Expand Down Expand Up @@ -267,33 +284,23 @@ local function toggleGroupVisibility(groupName)
end

local function hideOldClientStats()
if g_game.getClientVersion() >= 1412 then
return
end

setSkillGroupVisibility('offence', false)
setSkillGroupVisibility('defence', false)
setSkillGroupVisibility('misc', false)

local function hideUnnamedSeparators(widget)
if not widget then return end

local children = widget:getChildren()
for _, child in pairs(children) do
if child:getClassName() == 'HorizontalSeparator' and (not child:getId() or child:getId() == '') then
child:setVisible(false)
elseif child:getClassName() == 'UIWidget' and (not child:getId() or child:getId() == '') then
local childHeight = child:getHeight()
local childChildrenCount = #child:getChildren()
if childHeight <= 15 and childChildrenCount == 0 then
child:setVisible(false)
end
end
hideUnnamedSeparators(child)
end
local features = {
newAppearance = g_game.getFeature(GameEnterGameShowAppearance),
charSkills = g_game.getFeature(GameCharacterSkillStats),
additionalSkills = g_game.getFeature(GameAdditionalSkills),
forgeSkills = g_game.getFeature(GameForgeSkillStats)
}
if features.newAppearance then
skillsWindow:recursiveGetChildById('regenerationTime'):getChildByIndex(1):setText('Food')
skillsWindow:recursiveGetChildById('experience'):getChildByIndex(1):setText('XP')
end

hideUnnamedSeparators(skillsWindow)
local version = g_game.getClientVersion()
setSkillGroupVisibility('offence', features.charSkills)
setSkillGroupVisibility('defence', features.charSkills)
setSkillGroupVisibility('misc', features.charSkills)
setSkillGroupVisibility('GameAdditionalSkills', features.additionalSkills)
setSkillGroupVisibility('GameForgeSkillStats1332', features.forgeSkills and version >= 1332)
setSkillGroupVisibility('GameForgeSkillStats', features.forgeSkills)
end

local function hideMenuOptionsForOldClients(menu)
Expand Down Expand Up @@ -618,19 +625,53 @@ end

function setSkillValue(id, value)
local skill = skillsWindow:recursiveGetChildById(id)
if skill then
local widget = skill:getChildById('value')
if id == "skillId7" or id == "skillId8" or id == "skillId9" or id == "skillId11" or id == "skillId13" or id == "skillId14" or id == "skillId15" or id == "skillId16" then
if g_game.getFeature(GameEnterGameShowAppearance) then
value = value / 100
end
widget:setText(value .. "%")
if not skill then
return
end
local widget = skill:getChildById('value')
local GameAdditionalSkills = isSkillInGroups(id, {'GameAdditionalSkills'})
if GameAdditionalSkills then
local usePercentage = g_game.getFeature(GameEnterGameShowAppearance)
if usePercentage then
local needsDecimals = (id == 'skillId10' or id == 'skillId12')
local displayValue = needsDecimals and (value / 100) or value
local text = needsDecimals
and string.format("%.2f%%", displayValue)
or (displayValue .. "%")

widget:setText(text)
local color = (displayValue > 0 and 'green')
or (displayValue == 0 and '#C0C0C0')
or 'red'
widget:setColor(color)
else
widget:setText(value)
widget:setText(((id == 'skillId8') and "+" or "") .. value .. "%")
end
else
widget:setText(value)
widget:setColor('#C0C0C0')
end
end

function isSkillInGroups(skillId, groupNames)
if smallSkillsCache[skillId] ~= nil then
return smallSkillsCache[skillId]
end
for _, groupName in ipairs(groupNames) do
local skills = SKILL_GROUPS[groupName]
if skills then
for _, id in ipairs(skills) do
if id == skillId then
smallSkillsCache[skillId] = true
return true
end
end
end
end
smallSkillsCache[skillId] = false
return false
end

function setSkillColor(id, value)
local skill = skillsWindow:recursiveGetChildById(id)
if skill then
Expand Down Expand Up @@ -741,13 +782,7 @@ end

function online()
skillsWindow:setupOnStart()
setupUIButtons()
refresh()

if g_game.getFeature(GameEnterGameShowAppearance) then
skillsWindow:recursiveGetChildById('regenerationTime'):getChildByIndex(1):setText('Food')
skillsWindow:recursiveGetChildById('experience'):getChildByIndex(1):setText('XP')
end

local newWindowButton = skillsWindow:recursiveGetChildById('newWindowButton')
if g_game.getClientVersion() < 1310 and newWindowButton then
Expand All @@ -760,10 +795,6 @@ function online()
if sepDefense and sepDefense:isVisible() then
sepDefense:setVisible(false)
end
local sepOffence = skillsWindow:recursiveGetChildById('separadorOnOffenceInfoChange')
if sepOffence and sepOffence:isVisible() then
sepOffence:setVisible(false)
end

local lockButton = skillsWindow:recursiveGetChildById('lockButton')
local contextMenuButton = skillsWindow:recursiveGetChildById('contextMenuButton')
Expand All @@ -780,6 +811,8 @@ function online()
scheduleEvent(function()
loadSkillsVisibilitySettings()
end, 100)
hideOldClientStats()
updateHeight()
end

function refresh()
Expand All @@ -790,6 +823,7 @@ function refresh()

if expSpeedEvent then
expSpeedEvent:cancel()
expSpeedEvent = nil
end
expSpeedEvent = cycleEvent(checkExpSpeed, 30 * 1000)

Expand All @@ -805,41 +839,20 @@ function refresh()
onRegenerationChange(player, player:getRegenerationTime())
onSpeedChange(player, player:getSpeed())

local hasAdditionalSkills = g_game.getFeature(GameAdditionalSkills)
for i = Skill.Fist, Skill.Transcendence do
onSkillChange(player, i, player:getSkillLevel(i), player:getSkillLevelPercent(i))

if i > Skill.Fishing then
local ativedAdditionalSkills = hasAdditionalSkills
if ativedAdditionalSkills then
if g_game.getClientVersion() >= 1281 then
if i == Skill.LifeLeechAmount or i == Skill.ManaLeechAmount then
ativedAdditionalSkills = false
elseif g_game.getClientVersion() < 1332 and Skill.Transcendence then
ativedAdditionalSkills = false
elseif i >= Skill.Fatal and player:getSkillLevel(i) <= 0 then
ativedAdditionalSkills = false
end
elseif g_game.getClientVersion() < 1281 and i >= Skill.Fatal then
ativedAdditionalSkills = false
end
end
toggleSkill('skillId' .. i, ativedAdditionalSkills)
end
end

update()
updateHeight()
hideOldClientStats()
loadSkillsVisibilitySettings()
-- Always show default Offence, Defence, and Misc stats when loading window
onFlatDamageHealingChange(player, statsCache.flatDamageHealing)
onAttackInfoChange(player, statsCache.attackValue, statsCache.attackElement)
onConvertedDamageChange(player, statsCache.convertedDamage, statsCache.convertedElement)
onImbuementsChange(player, statsCache.lifeLeech, statsCache.manaLeech, statsCache.critChance, statsCache.critDamage, statsCache.onslaught)
onDefenseInfoChange(player, statsCache.defense, statsCache.armor, statsCache.mitigation, statsCache.dodge, statsCache.damageReflection)
onCombatAbsorbValuesChange(player, statsCache.combatAbsorbValues)
onForgeBonusesChange(player, statsCache.momentum, statsCache.transcendence, statsCache.amplification)
if g_game.getClientVersion() >= 1410 then
onFlatDamageHealingChange(player, statsCache.flatDamageHealing)
onAttackInfoChange(player, statsCache.attackValue, statsCache.attackElement)
onConvertedDamageChange(player, statsCache.convertedDamage, statsCache.convertedElement)
onImbuementsChange(player, statsCache.lifeLeech, statsCache.manaLeech, statsCache.critChance, statsCache.critDamage, statsCache.onslaught)
onDefenseInfoChange(player, statsCache.defense, statsCache.armor, statsCache.mitigation, statsCache.dodge, statsCache.damageReflection)
onCombatAbsorbValuesChange(player, statsCache.combatAbsorbValues)
onForgeBonusesChange(player, statsCache.momentum, statsCache.transcendence, statsCache.amplification)
end
end

function loadSkillsVisibilitySettings()
Expand Down Expand Up @@ -923,12 +936,42 @@ function updateHeight()
skillsWindow:setContentMaximumHeight(maximumHeight)
end

local function resetTable(t)
for k, v in pairs(t) do
if type(v) == "table" then
resetTable(v)
else
t[k] = 0
end
end
end

function offline()
skillsWindow:setParent(nil, true)
if expSpeedEvent then
expSpeedEvent:cancel()
expSpeedEvent = nil
end

local allGroups = {'offence', 'defence', 'misc', 'GameAdditionalSkills', 'GameForgeSkillStats', 'GameForgeSkillStats1332'}
for _, groupName in pairs(allGroups) do
local skills = SKILL_GROUPS[groupName]
if skills then
for _, skillId in pairs(skills) do
local skill = skillsWindow:recursiveGetChildById(skillId)
if skill then
if not string.find(skillId, "separador") then
local valueWidget = skill:getChildById('value')
if valueWidget then
valueWidget:setText("0")
end
skill:setVisible(false)
end
end
end
end
end
resetTable(statsCache)
g_settings.setNode('skills-hide', skillSettings)
end

Expand All @@ -944,8 +987,6 @@ function toggle()
end
panel:addChild(skillsWindow)
end

setupUIButtons()
skillsWindow:open()
skillsButton:setOn(true)
updateHeight()
Expand Down Expand Up @@ -1322,6 +1363,18 @@ local function setSkillValueWithTooltips(id, value, tooltip, showPercentage, col
end

if value ~= nil then
local shouldHide = false
if value == 0 or (type(value) == "number" and math.abs(value) < 0.0001) then
shouldHide = true
elseif showPercentage then
local percentValue = math.floor(value * 10000) / 100
shouldHide = (percentValue == 0 or math.abs(percentValue) < 0.01)
end
if shouldHide then
skill:setVisible(false)
return
end

skill:show()
local widget = skill:getChildById('value')
if not widget then
Expand Down Expand Up @@ -1414,12 +1467,21 @@ function onImbuementsChange(localPlayer, lifeLeech, manaLeech, critChance, critD
onslaught = "You get +1% of the damage dealt as hit points"
}

skillsWindow:recursiveGetChildById("criticalHit"):setVisible(true)
setSkillValueWithTooltips('lifeLeech', lifeLeech, tooltips.lifeLeech, true)
setSkillValueWithTooltips('manaLeech', manaLeech, tooltips.manaLeech, true)
setSkillValueWithTooltips('criticalChance', critChance, tooltips.critChance, true)
setSkillValueWithTooltips('criticalExtraDamage', critDamage, tooltips.critDamage, true)
setSkillValueWithTooltips('onslaught', onslaught, tooltips.onslaught, true)
local criticalHitWidget = skillsWindow:recursiveGetChildById("criticalHit")
if criticalHitWidget then
local critChanceWidget = skillsWindow:recursiveGetChildById("criticalChance")
local critDamageWidget = skillsWindow:recursiveGetChildById("criticalExtraDamage")
local shouldShowCriticalHit = false
if (critChanceWidget and critChanceWidget:isVisible()) or (critDamageWidget and critDamageWidget:isVisible()) then
shouldShowCriticalHit = true
end
criticalHitWidget:setVisible(shouldShowCriticalHit)
end
end

local combatIdToWidgetId = {
Expand Down Expand Up @@ -1452,6 +1514,7 @@ function onCombatAbsorbValuesChange(localPlayer, absorbValues)
end
end
end

function onDefenseInfoChange(localPlayer, defense, armor, mitigation, dodge, damageReflection)
-- Cache the data regardless of visibility
statsCache.defense = defense or 0
Expand Down
1 change: 1 addition & 0 deletions modules/game_skills/skills.otui
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,7 @@ MiniWindow
id: HorizontalSeparator
margin-top: 5
margin-bottom: 15
visible: false

UIWidget
id: miniborder
Expand Down