From c367e806413c6dc501370ca2777283ab95513afb Mon Sep 17 00:00:00 2001 From: PHIDIAS Date: Sun, 6 Apr 2025 23:33:56 +0900 Subject: [PATCH] Improve Bonus Gui (#379) * Update bonus.lua * Update bonus.lua * Update bonus.lua * Update bonus.lua * Update bonus.lua * Update bonus.lua * Update exp_legacy/module/modules/gui/bonus.lua Co-authored-by: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> * Recalculate limit on role change --------- Co-authored-by: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> --- exp_legacy/module/config/bonus.lua | 2 + exp_legacy/module/modules/gui/bonus.lua | 172 ++++++++---------------- 2 files changed, 59 insertions(+), 115 deletions(-) diff --git a/exp_legacy/module/config/bonus.lua b/exp_legacy/module/config/bonus.lua index 7c9289a4..88516939 100644 --- a/exp_legacy/module/config/bonus.lua +++ b/exp_legacy/module/config/bonus.lua @@ -18,6 +18,8 @@ return { ]] pts = { base = 260, + increase_percentage_per_role_level = 0.03, + role_name = "Member", }, gui_display_width = { half = 150, diff --git a/exp_legacy/module/modules/gui/bonus.lua b/exp_legacy/module/modules/gui/bonus.lua index d75a2396..c57b4a6b 100644 --- a/exp_legacy/module/modules/gui/bonus.lua +++ b/exp_legacy/module/modules/gui/bonus.lua @@ -9,6 +9,7 @@ local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles local config = require("modules.exp_legacy.config.bonus") --- @dep config.bonus local vlayer = require("modules.exp_legacy.modules.control.vlayer") local format_number = require("util").format_number --- @dep util + local bonus_container --- @param player LuaPlayer @@ -33,8 +34,9 @@ local function bonus_gui_pts_needed(player, container) end --- @param player LuaPlayer -local function apply_bonus(player) - if not Roles.player_allowed(player, "gui/bonus") then +--- @param reset boolean? +local function apply_bonus(player, reset) + if reset or not Roles.player_allowed(player, "gui/bonus") then for k, v in pairs(config.player_bonus) do player[k] = 0 @@ -101,9 +103,17 @@ local function apply_periodic_bonus(player) end end +local bonus_data_score_limit = {} +local function get_bonus_score_limit(player) + if not bonus_data_score_limit[player] then + bonus_data_score_limit[player] = math.floor(config.pts.base * (1 + config.pts.increase_percentage_per_role_level * (Roles.get_role_by_name(config.pts.role_name).index - Roles.get_player_highest_role(player).index))) + end + return bonus_data_score_limit[player] +end + --- Control label for the bonus points available --- @element bonus_gui_control_pts_a -local bonus_gui_control_pts_a = Gui.element("bonus_gui_control_pts_a") +-- @element bonus_gui_control_pts +local bonus_gui_control_pts = Gui.element("bonus_gui_control_pts") :draw{ type = "label", name = Gui.property_from_name, @@ -113,58 +123,17 @@ local bonus_gui_control_pts_a = Gui.element("bonus_gui_control_pts_a") width = config.gui_display_width["half"], } -local bonus_gui_control_pts_a_count = Gui.element("bonus_gui_control_pts_a_count") +local bonus_gui_control_pts_count = Gui.element("bonus_gui_control_pts_count") :draw{ - type = "label", + type = "progressbar", name = Gui.property_from_name, - caption = config.pts.base, - style = "heading_2_label", - }:style{ - width = config.gui_display_width["half"], - } - ---- Control label for the bonus points needed --- @element bonus_gui_control_pts_n -local bonus_gui_control_pts_n = Gui.element("bonus_gui_control_pts_n") - :draw{ - type = "label", - name = Gui.property_from_name, - caption = { "bonus.control-pts-n" }, - style = "heading_2_label", - }:style{ - width = config.gui_display_width["half"], - } - -local bonus_gui_control_pts_n_count = Gui.element("bonus_gui_control_pts_n_count") - :draw{ - type = "label", - name = Gui.property_from_name, - caption = "0", - style = "heading_2_label", - }:style{ - width = config.gui_display_width["half"], - } - ---- Control label for the bonus points remaining --- @element bonus_gui_control_pts_r -local bonus_gui_control_pts_r = Gui.element("bonus_gui_control_pts_r") - :draw{ - type = "label", - name = Gui.property_from_name, - caption = { "bonus.control-pts-r" }, - style = "heading_2_label", - }:style{ - width = config.gui_display_width["half"], - } - -local bonus_gui_control_pts_r_count = Gui.element("bonus_gui_control_pts_r_count") - :draw{ - type = "label", - name = Gui.property_from_name, - caption = "0", - style = "heading_2_label", + caption = "0 / 0", + value = 0, + style = "electric_satisfaction_statistics_progressbar", }:style{ width = config.gui_display_width["half"], + font = "heading-2", + color = { 1, 0, 0 }, } --- A button used for pts calculations @@ -183,21 +152,17 @@ local bonus_gui_control_reset = Gui.element("bonus_gui_control_reset") for k, v in pairs(config.conversion) do local s = "bonus_display_" .. k .. "_slider" disp[s].slider_value = config.player_bonus[v].value - - if config.player_bonus[v].is_percentage then - disp[disp[s].tags.counter].caption = format_number(disp[s].slider_value * 100, false) .. " %" - else - disp[disp[s].tags.counter].caption = format_number(disp[s].slider_value, false) - end + disp[disp[s].tags.counter].caption = (config.player_bonus[v].is_percentage and (format_number(disp[s].slider_value * 100, false) .. " %")) or format_number(disp[s].slider_value, false) end local slider = disp["bonus_display_personal_battery_recharge_slider"] slider.slider_value = config.player_special_bonus["personal_battery_recharge"].value disp[slider.tags.counter].caption = format_number(slider.slider_value, false) - local r = bonus_gui_pts_needed(player) - element.parent[bonus_gui_control_pts_n_count.name].caption = r - element.parent[bonus_gui_control_pts_r_count.name].caption = tonumber(element.parent[bonus_gui_control_pts_a_count.name].caption) - r + local n = bonus_gui_pts_needed(player) + local limit = get_bonus_score_limit(player) + element.parent[bonus_gui_control_pts_count.name].caption = n .. " / " .. limit + element.parent[bonus_gui_control_pts_count.name].value = n / limit end) --- A button used for pts apply @@ -211,11 +176,11 @@ local bonus_gui_control_apply = Gui.element("bonus_gui_control_apply") width = config.gui_display_width["half"], }:on_click(function(def, player, element) local n = bonus_gui_pts_needed(player) - element.parent[bonus_gui_control_pts_n_count.name].caption = n - local r = tonumber(element.parent[bonus_gui_control_pts_a_count.name].caption) - n - element.parent[bonus_gui_control_pts_r_count.name].caption = r + local limit = get_bonus_score_limit(player) + element.parent[bonus_gui_control_pts_count.name].caption = n .. " / " .. limit + element.parent[bonus_gui_control_pts_count.name].value = n / limit - if r >= 0 then + if n <= limit then apply_bonus(player) end end) @@ -227,15 +192,8 @@ local bonus_control_set = Gui.element("bonus_control_set") local bonus_set = parent.add{ type = "flow", direction = "vertical", name = name } local disp = Gui.elements.scroll_table(bonus_set, config.gui_display_width["half"] * 2, 2, "disp") - bonus_gui_control_pts_a(disp) - bonus_gui_control_pts_a_count(disp) - - bonus_gui_control_pts_n(disp) - bonus_gui_control_pts_n_count(disp) - - bonus_gui_control_pts_r(disp) - bonus_gui_control_pts_r_count(disp) - + bonus_gui_control_pts(disp) + bonus_gui_control_pts_count(disp) bonus_gui_control_reset(disp) bonus_gui_control_apply(disp) @@ -254,14 +212,6 @@ local bonus_gui_slider = Gui.element("bonus_gui_slider") } label.style.width = config.gui_display_width["label"] - local value = bonus.value - - if bonus.is_percentage then - value = format_number(value * 100, false) .. " %" - else - value = format_number(value, false) - end - local slider = parent.add{ type = "slider", name = name .. "_slider", @@ -281,7 +231,7 @@ local bonus_gui_slider = Gui.element("bonus_gui_slider") local count = parent.add{ type = "label", name = name .. "_count", - caption = value, + caption = (bonus.is_percentage and format_number(bonus.value * 100, false) .. " %") or format_number(bonus.value, false), style = "heading_2_label", } count.style.width = config.gui_display_width["count"] @@ -289,17 +239,13 @@ local bonus_gui_slider = Gui.element("bonus_gui_slider") return slider end) :on_value_changed(function(def, player, element) - if element.tags.is_percentage then - element.parent[element.tags.counter].caption = format_number(element.slider_value * 100, false) .. " %" - else - element.parent[element.tags.counter].caption = format_number(element.slider_value, false) - end - - local r = bonus_gui_pts_needed(player) + element.parent[element.tags.counter].caption = (element.tags.is_percentage and format_number(element.slider_value * 100, false) .. " %") or format_number(element.slider_value, false) local container = Gui.get_left_element(bonus_container, player) local disp = container.frame["bonus_st_1"].disp.table - disp[bonus_gui_control_pts_n_count.name].caption = r - disp[bonus_gui_control_pts_r_count.name].caption = tonumber(disp[bonus_gui_control_pts_a_count.name].caption) - r + local n = bonus_gui_pts_needed(player) + local limit = get_bonus_score_limit(player) + disp[bonus_gui_control_pts_count.name].caption = n .. " / " .. limit + disp[bonus_gui_control_pts_count.name].value = n / limit end) --- A vertical flow containing all the bonus data @@ -313,8 +259,7 @@ local bonus_data_set = Gui.element("bonus_data_set") bonus_gui_slider(disp, "bonus_display_" .. k, { "bonus.display-" .. k }, { "bonus.display-" .. k .. "-tooltip" }, config.player_bonus[v]) end - bonus_gui_slider(disp, "bonus_display_personal_battery_recharge", { "bonus.display-personal-battery-recharge" }, { "bonus.display-personal-battery-recharge-tooltip" }, - config.player_special_bonus["personal_battery_recharge"]) + bonus_gui_slider(disp, "bonus_display_personal_battery_recharge", { "bonus.display-personal-battery-recharge" }, { "bonus.display-personal-battery-recharge-tooltip" }, config.player_special_bonus["personal_battery_recharge"]) return bonus_set end) @@ -331,9 +276,9 @@ bonus_container = Gui.element("bonus_container") local disp = container["bonus_st_1"].disp.table local n = bonus_gui_pts_needed(player, container.parent) - disp[bonus_gui_control_pts_n_count.name].caption = n - local r = tonumber(disp[bonus_gui_control_pts_a_count.name].caption) - n - disp[bonus_gui_control_pts_r_count.name].caption = r + local limit = get_bonus_score_limit(player) + disp[bonus_gui_control_pts_count.name].caption = n .. " / " .. limit + disp[bonus_gui_control_pts_count.name].value = n / limit return container.parent end) @@ -364,33 +309,30 @@ Event.add(defines.events.on_player_created, function(event) end end) -Event.add(Roles.events.on_role_assigned, function(event) - apply_bonus(game.players[event.player_index]) -end) - -Event.add(Roles.events.on_role_unassigned, function(event) - apply_bonus(game.players[event.player_index]) -end) - ---- When a player respawns re-apply bonus -Event.add(defines.events.on_player_respawned, function(event) +local function recalculate_bonus(event) local player = game.players[event.player_index] + if event.name == Roles.events.on_role_assigned or event.name == Roles.events.on_role_unassigned then + -- If the player's roles changed then we need to recalculate their limit + bonus_data_score_limit[player] = nil + end + local container = Gui.get_left_element(bonus_container, player) local disp = container.frame["bonus_st_1"].disp.table local n = bonus_gui_pts_needed(player) - disp[bonus_gui_control_pts_n_count.name].caption = n - local r = tonumber(disp[bonus_gui_control_pts_a_count.name].caption) - n - disp[bonus_gui_control_pts_r_count.name].caption = r + local limit = get_bonus_score_limit(player) + disp[bonus_gui_control_pts_count.name].caption = n .. " / " .. limit + disp[bonus_gui_control_pts_count.name].value = n / limit - if r >= 0 then - apply_bonus(player) - end -end) + apply_bonus(player, n > limit) +end + +Event.add(Roles.events.on_role_assigned, recalculate_bonus) +Event.add(Roles.events.on_role_unassigned, recalculate_bonus) +Event.add(defines.events.on_player_respawned, recalculate_bonus) --- When a player dies allow them to have instant respawn Event.add(defines.events.on_player_died, function(event) local player = game.players[event.player_index] - if Roles.player_has_flag(player, "instant-respawn") then player.ticks_to_respawn = 120 end