diff --git a/commands/misc.lua b/commands/misc.lua index bc075d7c..dc83f7c0 100644 --- a/commands/misc.lua +++ b/commands/misc.lua @@ -8,7 +8,9 @@ local Gui = require 'utils.gui' local this = { players = {}, - activate_custom_buttons = false + activate_custom_buttons = false, + bottom_right = false, + bottom_quickbar_button = {} } Global.register( @@ -505,11 +507,15 @@ end ----! Gui Functions ! ---- -local function create_frame(player) +local function create_frame(player, rebuild) local gui = player.gui local frame = gui.screen[clear_corpse_main_button_name] if frame and frame.valid then - return frame + if rebuild then + frame.destroy() + else + return frame + end end frame = @@ -544,7 +550,12 @@ local function create_frame(player) style = 'quick_bar_page_button' } - this.bottom_quickbar_button = {name = bottom_quickbar_button_name, frame = bottom_quickbar_button} + this.bottom_quickbar_button[player.index] = {name = bottom_quickbar_button_name, frame = bottom_quickbar_button} + + if this.bottom_quickbar_button.sprite and this.bottom_quickbar_button.tooltip then + bottom_quickbar_button.sprite = this.bottom_quickbar_button.sprite + bottom_quickbar_button.tooltip = this.bottom_quickbar_button.tooltip + end return frame end @@ -554,12 +565,29 @@ local function set_location(player) local resolution = player.display_resolution local scale = player.display_scale - frame.location = { - x = (resolution.width / 2) - ((54 + -528) * scale), - y = (resolution.height - (96 * scale)) - } + if this.bottom_right then + frame.location = { + x = (resolution.width / 2) - ((54 + -528) * scale), + y = (resolution.height - (96 * scale)) + } + else + local experimental = get_game_version() + if experimental then + frame.location = { + x = (resolution.width / 2) - ((54 + 445) * scale), + y = (resolution.height - (96 * scale)) + } + else + frame.location = { + x = (resolution.width / 2) - ((54 + 258) * scale), + y = (resolution.height - (96 * scale)) + } + end + end end +--- Activates the custom buttons +---@param boolean function Public.activate_custom_buttons(value) if value then this.activate_custom_buttons = value @@ -568,6 +596,16 @@ function Public.activate_custom_buttons(value) end end +--- Sets the buttons to be aligned bottom right +---@param boolean +function Public.bottom_right(value) + if value then + this.bottom_right = value + else + this.bottom_right = false + end +end + Gui.on_click( clear_corpse_button_name, function(event) @@ -597,6 +635,29 @@ Event.add( end ) +Event.add( + defines.events.on_player_respawned, + function(event) + local player = game.get_player(event.player_index) + if this.activate_custom_buttons then + set_location(player) + end + end +) + +Event.add( + defines.events.on_player_died, + function(event) + local player = game.get_player(event.player_index) + if this.activate_custom_buttons then + local frame = player.gui.screen[clear_corpse_main_button_name] + if frame and frame.valid then + frame.destroy() + end + end + end +) + Event.add( defines.events.on_player_display_scale_changed, function(event) diff --git a/maps/mountain_fortress_v3/entities.lua b/maps/mountain_fortress_v3/entities.lua index 0830075c..3e999247 100644 --- a/maps/mountain_fortress_v3/entities.lua +++ b/maps/mountain_fortress_v3/entities.lua @@ -19,6 +19,7 @@ local Alert = require 'utils.alert' local Task = require 'utils.task' local Score = require 'comfy_panel.score' local Token = require 'utils.token' +local HS = require 'maps.mountain_fortress_v3.highscore' -- tables local WPT = require 'maps.mountain_fortress_v3.table' @@ -86,26 +87,41 @@ local reset_game = local this = data.this local Reset_map = data.reset_map if this.soft_reset then + HS.set_scores() this.game_reset_tick = nil Reset_map() return end if this.restart then + HS.set_scores() local message = ({'entity.reset_game'}) - Server.to_discord_bold(message) + Server.to_discord_bold(message, true) Server.start_scenario('Mountain_Fortress_v3') this.announced_message = true return end if this.shutdown then + HS.set_scores() local message = ({'entity.shutdown_game'}) - Server.to_discord_bold(message) + Server.to_discord_bold(message, true) Server.stop_scenario() return end end ) +local function exists() + local carriages = WPT.get('carriages') + local t = {} + for i = 1, #carriages do + local e = carriages[i] + if (e and e.valid) then + t[e.unit_number] = true + end + end + return t +end + local function get_random_weighted(weighted_table, item_index, weight_index) local total_weight = 0 item_index = item_index or 1 @@ -261,19 +277,6 @@ local function protect_entities(event) return false end - local function exists() - local carriages = WPT.get('carriages') - local t = {} - for i = 1, #carriages do - local e = carriages[i] - if not (e and e.valid) then - return - end - t[e.unit_number] = true - end - return t - end - local units = exists() if is_protected(entity) then if (event.cause and event.cause.valid) then @@ -853,8 +856,9 @@ local function on_player_repaired_entity(event) return end local entity = event.entity - local locomotive = WPT.get('locomotive') - if entity == locomotive then + local units = exists() + + if units[entity.unit_number] then local player = game.players[event.player_index] local repair_speed = Functions.get_magicka(player) if repair_speed <= 0 then diff --git a/maps/mountain_fortress_v3/functions.lua b/maps/mountain_fortress_v3/functions.lua index 43b98d8e..363dd5f1 100644 --- a/maps/mountain_fortress_v3/functions.lua +++ b/maps/mountain_fortress_v3/functions.lua @@ -791,6 +791,7 @@ function Public.set_difficulty() local wave_defense_table = WD.get_table() local collapse_amount = WPT.get('collapse_amount') local collapse_speed = WPT.get('collapse_speed') + local difficulty = WPT.get('difficulty') local player_count = calc_players() if not Diff.difficulty_vote_value then @@ -807,10 +808,10 @@ function Public.set_difficulty() wave_defense_table.threat_gain_multiplier = 1.2 + player_count * Diff.difficulty_vote_value * 0.1 -- local amount = player_count * 0.40 + 2 -- too high? - local amount = player_count * 0.25 + 2 + local amount = player_count * difficulty.multiply + 2 amount = floor(amount) - if amount > 8 then - amount = 8 -- lowered from 20 to 8 + if amount > difficulty.highest then + amount = difficulty.highest -- lowered from 20 to 15 end wave_defense_table.wave_interval = 3600 - player_count * 60 diff --git a/maps/mountain_fortress_v3/highscore.lua b/maps/mountain_fortress_v3/highscore.lua index 9afa9625..6a039eae 100644 --- a/maps/mountain_fortress_v3/highscore.lua +++ b/maps/mountain_fortress_v3/highscore.lua @@ -39,27 +39,83 @@ local biters = { 'behemoth-spitter' } -local function get_sorted_list(column_name, score_list, limit) - local i = 0 - for _ = 1, #score_list, 1 do - for y = 1, #score_list, 1 do - if not score_list[y + 1] then - break - end - if score_list[y][column_name] < score_list[y + 1][column_name] then - local key = score_list[y] - score_list[y] = score_list[y + 1] - score_list[y + 1] = key - i = i + 1 - if limit and i == limit then - return score_list - end +local function get_lowest(tbl, column_name) + local t = {} + for _, value in pairs(tbl) do + insert(t, value[column_name]) + end + table.sort( + t, + function(a, b) + return a < b + end + ) + if t[1] then + return t[1] + else + return 100 + end +end + +local function get_highest(tbl, column_name) + local t = {} + for _, value in pairs(tbl) do + insert(t, value[column_name]) + end + table.sort( + t, + function(a, b) + return a > b + end + ) + if t[1] then + return t[1] + else + return 10 + end +end + +local function contains(tbl, key, string, rtn) + for index, value in pairs(tbl) do + if value[key] and value[key] == string then + if rtn then + return index + else + return true end end end + return false +end + +local function sort_list(method, column_name, score_list) + local comparators = { + ['ascending'] = function(a, b) + return a[column_name] < b[column_name] + end, + ['descending'] = function(a, b) + return a[column_name] > b[column_name] + end + } + table.sort(score_list, comparators[method]) return score_list end +local function get_sorted_list(column_name, score_list) + local sl = {} + local i = 0 + score_list = sort_list('descending', column_name, score_list) + + for key, player in ipairs(score_list) do + sl[key] = player + i = i + 1 + if i == 20 then + return sl + end + end + return sl +end + local function get_mvps() local new_score_table = Score.get_table().score_table if not new_score_table['player'] then @@ -93,68 +149,120 @@ local function get_mvps() end end - local score_list_k = get_sorted_list('killscore', score_list, 20) - local score_list_m = get_sorted_list('mined_entities', score_list, 20) - local score_list_b = get_sorted_list('built_entities', score_list, 20) - local score_list_d = get_sorted_list('deaths', score_list, 20) + local score_list_k = get_sorted_list('killscore', score_list) + local score_list_m = get_sorted_list('mined_entities', score_list) + local score_list_b = get_sorted_list('built_entities', score_list) + local score_list_d = get_sorted_list('deaths', score_list) + local lowest_k = get_lowest(mvp, 'killscore') + local lowest_m = get_lowest(mvp, 'mined_entities') + local lowest_b = get_lowest(mvp, 'built_entities') + local highest_d = get_highest(mvp, 'deaths') - for i = 1, 20 do - if score_list_k[i] then - local killscore = score_list_k[i].killscore - local mined_ents = score_list_m[i].mined_entities - local build_ents = score_list_b[i].built_entities - local deaths = score_list_d[i].deaths + for i = 1, 30 do + local kill_list = score_list_k[i] + local mined_list = score_list_m[i] + local build_list = score_list_b[i] + local death_list = score_list_d[i] - if old_score.players[score_list[i].name] and score.players[score_list[i].name] then - if not mvp[score_list[i].name] then - mvp[score_list[i].name] = {} + if kill_list then + if not contains(mvp, 'name', kill_list.name) then + if kill_list.killscore >= lowest_k then + if death_list and death_list.deaths < highest_d then + insert( + mvp, + { + name = kill_list.name, + killscore = kill_list.killscore, + deaths = death_list.deaths + } + ) + else + insert( + mvp, + { + name = kill_list.name, + killscore = kill_list.killscore + } + ) + end end - - local old_score_p = old_score.players[score_list[i].name] - if killscore > old_score_p.killscore then - mvp[score_list[i].name].killscore = killscore - else - mvp[score_list[i].name].killscore = old_score_p.killscore - end - if mined_ents > old_score_p.mined_entities then - mvp[score_list[i].name].mined_entities = mined_ents - else - mvp[score_list[i].name].mined_entities = old_score_p.mined_entities - end - if build_ents > old_score_p.built_entities then - mvp[score_list[i].name].built_entities = build_ents - else - mvp[score_list[i].name].built_entities = old_score_p.built_entities - end - if deaths > old_score_p.deaths then - mvp[score_list[i].name].deaths = deaths - else - mvp[score_list[i].name].deaths = old_score_p.deaths + else + local index = contains(mvp, 'name', kill_list.name, true) + if index then + if mvp[index].killscore and kill_list.killscore > mvp[index].killscore then + mvp[index].killscore = kill_list.killscore + end + if death_list and mvp[index].deaths and death_list.deaths < mvp[index].deaths then + mvp[index].deaths = death_list.deaths + end end end end - end - - if #mvp <= 0 then - for i = 1, 20 do - if score_list_k[i] and not mvp[score_list[i].name] then - local killscore = score_list_k[i].killscore - local mined_ents = score_list_m[i].mined_entities - local build_ents = score_list_b[i].built_entities - local deaths = score_list_d[i].deaths - - if not mvp[score_list[i].name] then - mvp[score_list[i].name] = {} + if mined_list then + if not contains(mvp, 'name', mined_list.name) then + if mined_list.mined_entities >= lowest_m then + if death_list and death_list.deaths < highest_d then + insert( + mvp, + { + name = mined_list.name, + mined_entities = mined_list.mined_entities, + deaths = death_list.deaths + } + ) + else + insert( + mvp, + { + name = mined_list.name, + mined_entities = mined_list.mined_entities + } + ) + end end - if killscore >= 50 and mined_ents > 10 and build_ents > 1 then - mvp[score_list[i].name].killscore = killscore - mvp[score_list[i].name].mined_entities = mined_ents - mvp[score_list[i].name].built_entities = build_ents + else + local index = contains(mvp, 'name', mined_list.name, true) + if index then + if mvp[index].mined_entities and mined_list.mined_entities > mvp[index].mined_entities then + mvp[index].mined_entities = mined_list.mined_entities + end + if death_list and mvp[index].deaths and death_list.deaths < mvp[index].deaths then + mvp[index].deaths = death_list.deaths + end end - - mvp[score_list[i].name].deaths = deaths - if #mvp[score_list[i].name] <= 1 then - mvp[score_list[i].name] = nil + end + end + if build_list then + if not contains(mvp, 'name', build_list.name) then + if build_list.built_entities >= lowest_b then + if death_list and death_list.deaths < highest_d then + insert( + mvp, + { + name = build_list.name, + built_entities = build_list.built_entities, + deaths = death_list.deaths + } + ) + else + insert( + mvp, + { + name = build_list.name, + built_entities = build_list.built_entities + } + ) + end + end + else + local index = contains(mvp, 'name', build_list.name, true) + if index then + if mvp[index].built_entities and build_list.built_entities > mvp[index].built_entities then + mvp[index].built_entities = build_list.built_entities + end + if death_list and mvp[index].deaths and death_list.deaths < mvp[index].deaths then + mvp[index].deaths = death_list.deaths + end end end end @@ -229,6 +337,8 @@ local function write_additional_stats(key) end end + this.score_table['player'] = t + if key then set_data(score_dataset, key, t) end @@ -292,9 +402,9 @@ local function get_score_list() insert( score_list, { - name = p, + name = score and score.name, killscore = score and score.killscore or 0, - deaths = score and score.deaths or 0, + deaths = score and score.deaths or 20, built_entities = score and score.built_entities or 0, mined_entities = score and score.mined_entities or 0 } @@ -424,9 +534,7 @@ local show_score = (function(player, frame) -- Score list local score_list = get_score_list() - if #game.connected_players > 1 then - score_list = get_sorted_list(sorting_pref.method, sorting_pref.column, score_list) - end + score_list = sort_list(sorting_pref.method, sorting_pref.column, score_list) -- New pane for scores (while keeping headers at same position) local scroll_pane = @@ -459,12 +567,18 @@ local show_score = (function(player, frame) b = p.color.b * 0.6 + 0.4, a = 1 } + + local k = entry.killscore > 0 and entry.killscore or 'Not MVP' + local d = entry.deaths < 10 and entry.deaths or 'Not MVP' + local b = entry.built_entities > 0 and entry.built_entities or 'Not MVP' + local m = entry.mined_entities > 0 and entry.mined_entities or 'Not MVP' + local line = { {caption = entry.name, color = special_color}, - {caption = tostring(entry.killscore)}, - {caption = tostring(entry.deaths)}, - {caption = tostring(entry.built_entities)}, - {caption = tostring(entry.mined_entities)} + {caption = tostring(k)}, + {caption = tostring(d)}, + {caption = tostring(b)}, + {caption = tostring(m)} } local default_color = {r = 0.9, g = 0.9, b = 0.9} @@ -499,18 +613,12 @@ local function on_gui_click(event) if not frame then return end - if frame.name ~= 'HighScore' then + if frame.name ~= 'Highscore' then return end local name = event.element.name - -- Handles click on the checkbox, for floating score - if name == 'show_floating_killscore_texts' then - global.show_floating_killscore[player.name] = event.element.state - return - end - -- Handles click on a score header local element_to_column = { ['score_killscore'] = 'killscore', diff --git a/maps/mountain_fortress_v3/main.lua b/maps/mountain_fortress_v3/main.lua index e00bb8c0..a7c04617 100644 --- a/maps/mountain_fortress_v3/main.lua +++ b/maps/mountain_fortress_v3/main.lua @@ -107,6 +107,7 @@ function Public.reset_map() BuriedEnemies.reset() Commands.reset() Commands.activate_custom_buttons(true) + Commands.bottom_right(false) Poll.reset() ICW.reset() @@ -278,6 +279,7 @@ local has_the_game_ended = function() end if this.restart and this.game_reset_tick == 0 then if not this.announced_message then + HS.set_scores() game.print(({'entity.notify_restart'}), {r = 0.22, g = 0.88, b = 0.22}) local message = 'Soft-reset is disabled! Server will restart from scenario to load new changes.' Server.to_discord_bold(table.concat {'*** ', message, ' ***'}) @@ -288,6 +290,7 @@ local has_the_game_ended = function() end if this.shutdown and this.game_reset_tick == 0 then if not this.announced_message then + HS.set_scores() game.print(({'entity.notify_shutdown'}), {r = 0.22, g = 0.88, b = 0.22}) local message = 'Soft-reset is disabled! Server will shutdown. Most likely because of updates.' Server.to_discord_bold(table.concat {'*** ', message, ' ***'}) diff --git a/maps/mountain_fortress_v3/table.lua b/maps/mountain_fortress_v3/table.lua index 688cf021..2de5a4cf 100644 --- a/maps/mountain_fortress_v3/table.lua +++ b/maps/mountain_fortress_v3/table.lua @@ -196,6 +196,10 @@ function Public.reset_table() this.check_afk_players = true this.winter_mode = false this.sent_to_discord = false + this.difficulty = { + multiply = 0.25, + highest = 15 + } --!reset player tables for _, player in pairs(this.players) do diff --git a/modules/autostash.lua b/modules/autostash.lua index 874edd32..6666cb06 100644 --- a/modules/autostash.lua +++ b/modules/autostash.lua @@ -443,8 +443,17 @@ local function create_gui_button(player) end if this.bottom_button then local data = Misc.get('bottom_quickbar_button') - data.frame.sprite = 'item/wooden-chest' - data.frame.tooltip = tooltip + -- save it for later use + data.tooltip = tooltip + data.sprite = 'item/wooden-chest' + + if data[player.index] then + data = data[player.index] + if data.frame and data.frame.valid then + data.frame.sprite = 'item/wooden-chest' + data.frame.tooltip = tooltip + end + end else local b = player.gui.top.add( @@ -493,14 +502,18 @@ local function on_gui_click(event) if not event.element.valid then return end + local player = game.players[event.player_index] local name = 'auto_stash' if this.bottom_button then local data = Misc.get('bottom_quickbar_button') - name = data.name + if data[player.index] then + data = data[player.index] + name = data.name + end end if event.element.name == name then - auto_stash(game.players[event.player_index], event) + auto_stash(player, event) end end diff --git a/modules/rpg/main.lua b/modules/rpg/main.lua index fe8ccc7d..18e95750 100644 --- a/modules/rpg/main.lua +++ b/modules/rpg/main.lua @@ -962,7 +962,6 @@ local function on_player_used_capsule(event) return end - local object_name = object.name local obj_name = object.obj_to_create local position = event.position @@ -1009,7 +1008,7 @@ local function on_player_used_capsule(event) end if object.obj_to_create == 'suicidal_comfylatron' then Functions.suicidal_comfylatron(position, surface) - p(({'rpg_main.suicidal_comfylatron', object_name}), Color.success) + p(({'rpg_main.suicidal_comfylatron', 'Suicidal Comfylatron'}), Color.success) rpg_t[player.index].mana = rpg_t[player.index].mana - object.mana_cost elseif object.obj_to_create == 'warp-gate' then player.teleport(surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 3, 0, 5), surface) @@ -1057,7 +1056,7 @@ local function on_player_used_capsule(event) end end - local msg = player.name .. ' casted ' .. object.name .. '. ' + local msg = player.name .. ' casted ' .. object.obj_to_create .. '. ' rpg_t[player.index].last_spawned = game.tick + object.tick Functions.update_mana(player) diff --git a/modules/wave_defense/threat_events.lua b/modules/wave_defense/threat_events.lua index c003ec1a..ab314c81 100644 --- a/modules/wave_defense/threat_events.lua +++ b/modules/wave_defense/threat_events.lua @@ -158,7 +158,7 @@ end local function shred_simple_entities(entity) local threat = WD.get('threat') - if threat < 25000 then + if threat < 5000 then return end local simple_entities =