Resolve "Merge the best from 7.40 branch"

This commit is contained in:
Erikas Kontenis
2022-04-06 14:58:52 +00:00
parent 3bd1a6f07e
commit 155da3573c
928 changed files with 43723 additions and 1221 deletions

View File

@@ -0,0 +1,437 @@
skillsWindow = nil
skillsButton = nil
function init()
connect(LocalPlayer, {
onExperienceChange = onExperienceChange,
onLevelChange = onLevelChange,
onHealthChange = onHealthChange,
onManaChange = onManaChange,
onSoulChange = onSoulChange,
onFreeCapacityChange = onFreeCapacityChange,
onTotalCapacityChange = onTotalCapacityChange,
onStaminaChange = onStaminaChange,
onOfflineTrainingChange = onOfflineTrainingChange,
onRegenerationChange = onRegenerationChange,
onSpeedChange = onSpeedChange,
onBaseSpeedChange = onBaseSpeedChange,
onMagicLevelChange = onMagicLevelChange,
onBaseMagicLevelChange = onBaseMagicLevelChange,
onSkillChange = onSkillChange,
onBaseSkillChange = onBaseSkillChange
})
connect(g_game, {
onGameStart = refresh,
onGameEnd = offline
})
skillsButton = modules.client_topmenu.addRightGameToggleButton('skillsButton', tr('Skills'), '/images/topbuttons/skills', toggle, false, 1)
skillsButton:setOn(true)
skillsWindow = g_ui.loadUI('skills', modules.game_interface.getRightPanel())
refresh()
skillsWindow:setup()
end
function terminate()
disconnect(LocalPlayer, {
onExperienceChange = onExperienceChange,
onLevelChange = onLevelChange,
onHealthChange = onHealthChange,
onManaChange = onManaChange,
onSoulChange = onSoulChange,
onFreeCapacityChange = onFreeCapacityChange,
onTotalCapacityChange = onTotalCapacityChange,
onStaminaChange = onStaminaChange,
onOfflineTrainingChange = onOfflineTrainingChange,
onRegenerationChange = onRegenerationChange,
onSpeedChange = onSpeedChange,
onBaseSpeedChange = onBaseSpeedChange,
onMagicLevelChange = onMagicLevelChange,
onBaseMagicLevelChange = onBaseMagicLevelChange,
onSkillChange = onSkillChange,
onBaseSkillChange = onBaseSkillChange
})
disconnect(g_game, {
onGameStart = refresh,
onGameEnd = offline
})
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 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 update()
local offlineTraining = skillsWindow:recursiveGetChildById('offlineTraining')
if not g_game.getFeature(GameOfflineTrainingTime) then
offlineTraining:hide()
else
offlineTraining:show()
end
local regenerationTime = skillsWindow:recursiveGetChildById('regenerationTime')
if not g_game.getFeature(GamePlayerRegenerationTime) then
regenerationTime:hide()
else
regenerationTime:show()
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())
onFreeCapacityChange(player, player:getFreeCapacity())
onStaminaChange(player, player:getStamina())
onMagicLevelChange(player, player:getMagicLevel(), player:getMagicLevelPercent())
onOfflineTrainingChange(player, player:getOfflineTrainingTime())
onRegenerationChange(player, player:getRegenerationTime())
onSpeedChange(player, player:getSpeed())
local hasAdditionalSkills = g_game.getFeature(GameAdditionalSkills)
for i = Skill.Fist, Skill.ManaLeechAmount do
onSkillChange(player, i, player:getSkillLevel(i), player:getSkillLevelPercent(i))
onBaseSkillChange(player, i, player:getSkillBaseLevel(i))
if i > Skill.Fishing then
toggleSkill('skillId'..i, hasAdditionalSkills)
end
end
update()
local contentsPanel = skillsWindow:getChildById('contentsPanel')
skillsWindow:setContentMinimumHeight(44)
if hasAdditionalSkills then
skillsWindow:setContentMaximumHeight(480)
else
skillsWindow:setContentMaximumHeight(390)
end
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 onSkillButtonClick(button)
local percentBar = button:getChildById('percent')
if percentBar then
percentBar:setVisible(not percentBar:isVisible())
if percentBar:isVisible() then
button:setHeight(21)
else
button:setHeight(21 - 6)
end
end
end
function onExperienceChange(localPlayer, value)
local postFix = ""
if value > 1e15 then
postFix = "B"
value = math.floor(value / 1e9)
elseif value > 1e12 then
postFix = "M"
value = math.floor(value / 1e6)
elseif value > 1e9 then
postFix = "K"
value = math.floor(value / 1e3)
end
setSkillValue('experience', comma_value(value) .. postFix)
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 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 onOfflineTrainingChange(localPlayer, offlineTrainingTime)
if not g_game.getFeature(GameOfflineTrainingTime) then
return
end
local hours = math.floor(offlineTrainingTime / 60)
local minutes = offlineTrainingTime % 60
if minutes < 10 then
minutes = '0' .. minutes
end
local percent = 100 * offlineTrainingTime / (12 * 60) -- max is 12 hours
setSkillValue('offlineTraining', hours .. ":" .. minutes)
setSkillPercent('offlineTraining', percent, tr('You have %s percent', percent))
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('speed', speed)
onBaseSpeedChange(localPlayer, localPlayer:getBaseSpeed())
end
function onBaseSpeedChange(localPlayer, baseSpeed)
setSkillBase('speed', localPlayer:getSpeed(), baseSpeed)
end
function onMagicLevelChange(localPlayer, magiclevel, percent)
setSkillValue('magiclevel', magiclevel)
setSkillPercent('magiclevel', percent, tr('You have %s percent to go', 100 - percent))
onBaseMagicLevelChange(localPlayer, localPlayer:getBaseMagicLevel())
end
function onBaseMagicLevelChange(localPlayer, baseMagicLevel)
setSkillBase('magiclevel', localPlayer:getMagicLevel(), baseMagicLevel)
end
function onSkillChange(localPlayer, id, level, percent)
setSkillValue('skillId' .. id, level)
setSkillPercent('skillId' .. id, percent, tr('You have %s percent to go', 100 - percent))
onBaseSkillChange(localPlayer, id, localPlayer:getSkillBaseLevel(id))
end
function onBaseSkillChange(localPlayer, id, baseLevel)
setSkillBase('skillId'..id, localPlayer:getSkillLevel(id), baseLevel)
end

View File

@@ -0,0 +1,11 @@
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

View File

@@ -0,0 +1,212 @@
SkillFirstWidget < UIWidget
SkillButton < UIButton
height: 21
margin-bottom: 2
&onClick: onSkillButtonClick
SmallSkillButton < SkillButton
height: 14
SkillNameLabel < GameLabel
font: verdana-11px-monochrome
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
SkillValueLabel < GameLabel
id: value
font: verdana-11px-monochrome
text-align: topright
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: prev.left
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
&autoOpen: false
MiniWindowContents
padding-left: 5
padding-right: 5
layout: verticalBox
SkillButton
margin-top: 5
id: experience
height: 15
SkillNameLabel
!text: tr('Experience')
SkillValueLabel
SkillButton
id: level
SkillNameLabel
!text: tr('Level')
SkillValueLabel
SkillPercentPanel
background-color: red
SkillButton
id: health
height: 15
SkillNameLabel
!text: tr('Hit Points')
SkillValueLabel
SkillButton
id: mana
height: 15
SkillNameLabel
!text: tr('Mana')
SkillValueLabel
SkillButton
id: soul
height: 15
SkillNameLabel
!text: tr('Soul Points')
SkillValueLabel
SkillButton
id: capacity
height: 15
SkillNameLabel
!text: tr('Capacity')
SkillValueLabel
SkillButton
id: speed
height: 15
SkillNameLabel
!text: tr('Speed')
SkillValueLabel
SkillButton
id: regenerationTime
SkillNameLabel
!text: tr('Regeneration Time')
SkillValueLabel
SkillButton
id: stamina
SkillNameLabel
!text: tr('Stamina')
SkillValueLabel
SkillPercentPanel
SkillButton
id: offlineTraining
SkillNameLabel
!text: tr('Offline Training')
SkillValueLabel
SkillPercentPanel
SkillButton
id: magiclevel
SkillNameLabel
!text: tr('Magic Level')
SkillValueLabel
SkillPercentPanel
background-color: red
SkillButton
id: skillId0
SkillNameLabel
!text: tr('Fist Fighting')
SkillValueLabel
SkillPercentPanel
SkillButton
id: skillId1
SkillNameLabel
!text: tr('Club Fighting')
SkillValueLabel
SkillPercentPanel
SkillButton
id: skillId2
SkillNameLabel
!text: tr('Sword Fighting')
SkillValueLabel
SkillPercentPanel
SkillButton
id: skillId3
SkillNameLabel
!text: tr('Axe Fighting')
SkillValueLabel
SkillPercentPanel
SkillButton
id: skillId4
SkillNameLabel
!text: tr('Distance Fighting')
SkillValueLabel
SkillPercentPanel
SkillButton
id: skillId5
SkillNameLabel
!text: tr('Shielding')
SkillValueLabel
SkillPercentPanel
SkillButton
id: skillId6
SkillNameLabel
!text: tr('Fishing')
SkillValueLabel
SkillPercentPanel
SmallSkillButton
id: skillId7
SkillNameLabel
!text: tr('Critical Hit Chance')
SkillValueLabel
SmallSkillButton
id: skillId8
SkillNameLabel
!text: tr('Critical Hit Damage')
SkillValueLabel
SmallSkillButton
id: skillId9
SkillNameLabel
!text: tr('Life Leech Chance')
SkillValueLabel
SmallSkillButton
id: skillId10
SkillNameLabel
!text: tr('Life Leech Amount')
SkillValueLabel
SmallSkillButton
id: skillId11
SkillNameLabel
!text: tr('Mana Leech Chance')
SkillValueLabel
SmallSkillButton
id: skillId12
SkillNameLabel
!text: tr('Mana Leech Amount')
SkillValueLabel