2022-06-06 18:53:56 +00:00

505 lines
15 KiB
Lua

Icons = {}
Icons[PlayerStates.Poison] = {
tooltip = tr('You are poisoned'),
path = '/images/game/states/poisoned',
id = 'condition_poisoned'
}
Icons[PlayerStates.Burn] = {
tooltip = tr('You are burning'),
path = '/images/game/states/burning',
id = 'condition_burning'
}
Icons[PlayerStates.Energy] = {
tooltip = tr('You are electrified'),
path = '/images/game/states/electrified',
id = 'condition_electrified'
}
Icons[PlayerStates.Drunk] = {
tooltip = tr('You are drunk'),
path = '/images/game/states/drunk',
id = 'condition_drunk'
}
Icons[PlayerStates.ManaShield] = {
tooltip = tr('You are protected by a magic shield'),
path = '/images/game/states/magic_shield',
id = 'condition_magic_shield'
}
Icons[PlayerStates.Paralyze] = {
tooltip = tr('You are paralysed'),
path = '/images/game/states/slowed',
id = 'condition_slowed'
}
Icons[PlayerStates.Haste] = {
tooltip = tr('You are hasted'),
path = '/images/game/states/haste',
id = 'condition_haste'
}
Icons[PlayerStates.Swords] = {
tooltip = tr('You may not logout during a fight'),
path = '/images/game/states/logout_block',
id = 'condition_logout_block'
}
Icons[PlayerStates.Drowning] = {
tooltip = tr('You are drowning'),
path = '/images/game/states/drowning',
id = 'condition_drowning'
}
Icons[PlayerStates.Freezing] = {
tooltip = tr('You are freezing'),
path = '/images/game/states/freezing',
id = 'condition_freezing'
}
Icons[PlayerStates.Dazzled] = {
tooltip = tr('You are dazzled'),
path = '/images/game/states/dazzled',
id = 'condition_dazzled'
}
Icons[PlayerStates.Cursed] = {
tooltip = tr('You are cursed'),
path = '/images/game/states/cursed',
id = 'condition_cursed'
}
Icons[PlayerStates.PartyBuff] = {
tooltip = tr('You are strengthened'),
path = '/images/game/states/strengthened',
id = 'condition_strengthened'
}
Icons[PlayerStates.PzBlock] = {
tooltip = tr('You may not logout or enter a protection zone'),
path = '/images/game/states/protection_zone_block',
id = 'condition_protection_zone_block'
}
Icons[PlayerStates.Pz] = {
tooltip = tr('You are within a protection zone'),
path = '/images/game/states/protection_zone',
id = 'condition_protection_zone'
}
Icons[PlayerStates.Bleeding] = {
tooltip = tr('You are bleeding'),
path = '/images/game/states/bleeding',
id = 'condition_bleeding'
}
Icons[PlayerStates.Hungry] = {
tooltip = tr('You are hungry'),
path = '/images/game/states/hungry',
id = 'condition_hungry'
}
local iconsTable = {
["Experience"] = 8,
["Magic"] = 0,
["Axe"] = 2,
["Club"] = 1,
["Distance"] = 3,
["Fist"] = 4,
["Shielding"] = 5,
["Sword"] = 6,
["Fishing"] = 7
}
local healthBar = nil
local manaBar = nil
local topBar = nil
local states = nil
local experienceTooltip = 'You have %d%% to advance to level %d.'
local settings = {}
function init()
connect(LocalPlayer, {
onHealthChange = onHealthChange,
onManaChange = onManaChange,
onLevelChange = onLevelChange,
onStatesChange = onStatesChange,
onMagicLevelChange = onMagicLevelChange,
onBaseMagicLevelChange = onBaseMagicLevelChange,
onSkillChange = onSkillChange,
onBaseSkillChange = onBaseSkillChange
})
connect(g_game, {onGameStart = refresh, onGameEnd = offline})
-- load condition icons
for k, v in pairs(Icons) do g_textures.preload(v.path) end
if g_game.isOnline() then refresh() end
end
function terminate()
disconnect(LocalPlayer, {
onHealthChange = onHealthChange,
onManaChange = onManaChange,
onLevelChange = onLevelChange,
onStatesChange = onStatesChange,
onMagicLevelChange = onMagicLevelChange,
onBaseMagicLevelChange = onBaseMagicLevelChange,
onSkillChange = onSkillChange,
onBaseSkillChange = onBaseSkillChange
})
disconnect(g_game, {onGameStart = refresh, onGameEnd = offline})
end
function setupTopBar()
local topPanel = modules.game_interface.getTopBar()
topBar = topBar or g_ui.loadUI('topbar', topPanel)
topBar = topBar or g_ui.createWidget('TopBar', topPanel)
manaBar = topBar.stats.mana
healthBar = topBar.stats.health
states = topBar.stats.states.box
topBar.onMouseRelease = function(widget, mousePos, mouseButton)
menu(mouseButton)
end
end
function refresh(profileChange)
local player = g_game.getLocalPlayer()
if not player then return end
setupTopBar()
load()
setupSkills()
show()
refreshVisibleBars()
onLevelChange(player, player:getLevel(), player:getLevelPercent())
onHealthChange(player, player:getHealth(), player:getMaxHealth())
onManaChange(player, player:getMana(), player:getMaxMana())
onMagicLevelChange(player, player:getMagicLevel(), player:getMagicLevelPercent())
if not profileChange then
onStatesChange(player, player:getStates(), 0)
end
onHealthChange(player, player:getHealth(), player:getMaxHealth())
onManaChange(player, player:getMana(), player:getMaxMana())
onLevelChange(player, player:getLevel(), player:getLevelPercent())
for i = Skill.Fist, Skill.ManaLeechAmount do
onSkillChange(player, i, player:getSkillLevel(i), player:getSkillLevelPercent(i))
onBaseSkillChange(player, i, player:getSkillBaseLevel(i))
end
topBar.skills.onGeometryChange = setSkillsLayout
end
function refreshVisibleBars()
local ids = {"Experience", "Magic", "Axe", "Club", "Distance", "Fist", "Shielding",
"Sword", "Fishing"}
for i, id in ipairs(ids) do
local panel = topBar[id] or topBar.skills[id]
if panel then
-- experience is exeption
if id == "Experience" then
if not settings[id] then
panel:setVisible(true)
end
else
panel:setVisible(settings[id] or false)
end
end
end
end
function setSkillsLayout()
local visible = 0
local skills = topBar.skills
local width = skills:getWidth()
for i, child in ipairs(skills:getChildren()) do
visible = child:isVisible() and visible + 1 or visible
end
local many = visible > 1
width = many and (width / 2) or width
skills:getLayout():setCellSize({width = width, height = 19})
end
function offline()
local player = g_game.getLocalPlayer()
if player then onStatesChange(player, 0, player:getStates()) end
save()
end
function toggleIcon(bitChanged)
local content = states
if not content then return end
local icon = content:getChildById(Icons[bitChanged].id)
if icon then
icon:destroy()
else
icon = loadIcon(bitChanged)
icon:setParent(content)
end
end
function loadIcon(bitChanged)
local icon = g_ui.createWidget('ConditionWidget', content)
icon:setId(Icons[bitChanged].id)
icon:setImageSource(Icons[bitChanged].path)
icon:setTooltip(Icons[bitChanged].tooltip)
return icon
end
function onHealthChange(localPlayer, health, maxHealth)
if not healthBar then return end
if health > maxHealth then maxHealth = health end
local healthPercent = (health / maxHealth) * 100
healthBar:setText(comma_value(health) .. ' / ' .. comma_value(maxHealth))
healthBar:setValue(health, 0, maxHealth)
healthBar:setPercent(healthPercent)
if healthPercent > 92 then
healthBar:setBackgroundColor("#00BC00FF")
elseif healthPercent > 60 then
healthBar:setBackgroundColor("#50A150FF")
elseif healthPercent > 30 then
healthBar:setBackgroundColor("#A1A100FF")
elseif healthPercent > 8 then
healthBar:setBackgroundColor("#BF0A0AFF")
elseif healthPercent > 3 then
healthBar:setBackgroundColor("#910F0FFF")
else
healthBar:setBackgroundColor("#850C0CFF")
end
end
function onManaChange(localPlayer, mana, maxMana)
if not manaBar then return end
if mana > maxMana then maxMana = mana end
local manaPercent = (mana / maxMana) * 100
if manaPercent < 0 then return end
manaBar:setText(comma_value(mana) .. ' / ' .. comma_value(maxMana))
manaBar:setValue(mana, 0, maxMana)
manaBar:setPercent(manaPercent)
end
function onLevelChange(localPlayer, value, percent)
if not topBar then return end
local experienceBar = topBar.Experience.progress
local levelLabel = topBar.Experience.level
experienceBar:setTooltip(tr(experienceTooltip, 100-percent, value + 1))
experienceBar:setPercent(percent)
levelLabel:setText(value)
end
function 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 toggleIcon(bitChanged) end
end
end
function show()
if not g_game.isOnline() then return end
topBar:setVisible(g_settings.getBoolean("topBar", false))
end
function setupSkillPanel(id, parent, experience, defaultOff)
local widget = g_ui.createWidget('SkillPanel', parent)
widget:setId(id)
widget.level:setTooltip(id)
widget.icon:setTooltip(id)
widget.icon:setImageClip({x = iconsTable[id]*9, y = 0, width = 9,height = 9})
if not experience then
widget.progress:setBackgroundColor('#00c000')
widget.shop:setVisible(false)
widget.shop:disable()
widget.shop:setWidth(0)
widget.progress:setMarginRight(1)
end
settings[id] = settings[id] ~= nil and settings[id] or defaultOff
if settings[id] == false then widget:setVisible(false) end
-- breakers
widget.onGeometryChange = function()
local margin = widget.progress:getWidth() / 4
local left = widget.left
local right = widget.right
left:setMarginRight(margin)
right:setMarginRight(margin)
end
end
function menu(mouseButton)
if mouseButton ~= 2 then return end
local menu = g_ui.createWidget('PopupMenu')
menu:setId("topBarMenu")
menu:setGameMenu(true)
local expPanel = topBar.Experience
local start = expPanel:isVisible() and "Hide" or "Show"
menu:addOption(start .. " Experience Level",
function() toggleSkillPanel(id) end)
for i, child in ipairs(topBar.skills:getChildren()) do
local id = child:getId()
if id ~= "stats" then
local start = child:isVisible() and "Hide" or "Show"
menu:addOption(start .. " " .. id .. " Level",
function() toggleSkillPanel(id) end)
end
end
menu:display(mousePos)
return true
end
function setupSkills()
local t = {
"Experience", "Magic", "Axe", "Club", "Distance", "Fist", "Shielding",
"Sword", "Fishing"
}
for i, id in ipairs(t) do
if not topBar[id] and not topBar.skills[id] then
setupSkillPanel(id, i == 1 and topBar or topBar.skills, i == 1,
i == 1)
end
end
local child = topBar.Experience
topBar:moveChildToIndex(child, 2)
end
function toggleSkillPanel(id)
if not topBar then return end
local panel = topBar.skills[id]
panel = panel or topBar.Experience
if not panel then return end
panel:setVisible(not panel:isVisible())
settings[id] = panel:isVisible()
setSkillsLayout()
end
function setSkillValue(id, value)
if not topBar then return end
local panel = topBar.skills[id]
if not panel then return end
panel.level:setText(value)
end
function setSkillPercent(id, percent, tooltip)
if not topBar then return end
local panel = topBar.skills[id]
if not panel then return end
panel.progress:setPercent(math.floor(percent))
end
function setSkillBase(id, value, baseValue)
if not topBar then return end
local panel = topBar.skills[id]
if not panel then return end
local progress = topBar.skills[id].progress
local progressDesc = "You have " .. 100 - math.floor(progress:getPercent()) .. " percent to go"
local level = topBar.skills[id].level
if baseValue <= 0 or value < 0 then return end
if value > baseValue then
level:setColor('#008b00') -- green
progress:setTooltip(value .. " = " .. baseValue .. ' + ' ..
(value - baseValue) .. "\n" .. progressDesc)
elseif value < baseValue then
level:setColor('#b22222') -- red
progress:setTooltip(baseValue .. ' ' .. (value - baseValue))
else
level:setColor('#bbbbbb') -- default
progress:removeTooltip()
end
end
function onMagicLevelChange(localPlayer, magiclevel, percent)
setSkillValue('Magic', magiclevel)
setSkillPercent('Magic', percent)
onBaseMagicLevelChange(localPlayer, localPlayer:getBaseMagicLevel())
end
function onBaseMagicLevelChange(localPlayer, baseMagicLevel)
setSkillBase('Magic', localPlayer:getMagicLevel(), baseMagicLevel)
end
function onSkillChange(localPlayer, id, level, percent)
id = id + 1
local t = {
"Fist", "Club", "Sword", "Axe", "Distance", "Shielding", "Fishing"
}
-- imbues, ignore
if id > #t then return end
setSkillValue(t[id], level)
setSkillPercent(t[id], percent)
setSkillBase(t[id], level, localPlayer:getSkillBaseLevel(id - 1))
end
function onBaseSkillChange(localPlayer, id, baseLevel)
id = id + 1
local t = {
"Fist", "Club", "Sword", "Axe", "Distance", "Shielding", "Fishing"
}
-- imbues, ignore
if id > #t then return end
setSkillBase(id, localPlayer:getSkillLevel(id), baseLevel)
end
function save()
local settingsFile = modules.client_profiles.getSettingsFilePath("topbar.json")
local status, result = pcall(function() return json.encode(settings, 2) end)
if not status then
return onError(
"Error while saving top bar settings. Data won't be saved. Details: " ..
result)
end
if result:len() > 100 * 1024 * 1024 then
return onError(
"Something went wrong, file is above 100MB, won't be saved")
end
g_resources.writeFileContents(settingsFile, result)
end
function load()
local settingsFile = modules.client_profiles.getSettingsFilePath("topbar.json")
if g_resources.fileExists(settingsFile) then
local status, result = pcall(function()
return json.decode(g_resources.readFileContents(settingsFile))
end)
if not status then
return onError(
"Error while reading top bar settings file. To fix this problem you can delete storage.json. Details: " ..
result)
end
settings = result
else
settings = {}
end
end