diff --git a/features/gui/poll.lua b/features/gui/poll.lua index 021c618d..d562bc16 100644 --- a/features/gui/poll.lua +++ b/features/gui/poll.lua @@ -231,7 +231,8 @@ local function redraw_poll_viewer_content(data) local question_flow = poll_viewer_content.add {type = 'table', column_count = 2} - if Rank.equal_or_greater_than(player.name, Ranks.regular) then + local edit_rank = poll.edit_rank or Ranks.regular + if Rank.equal_or_greater_than(player.name, edit_rank) then local edit_button = question_flow.add { type = 'sprite-button', @@ -247,8 +248,8 @@ local function redraw_poll_viewer_content(data) local question_label = question_flow.add {type = 'label', caption = poll.question} local question_label_style = question_label.style - question_label_style.height = 32 question_label_style.font_color = focus_color + question_label_style.single_line = false question_label_style.font = 'default-listbox' local grid = poll_viewer_content.add {type = 'table', column_count = 2} @@ -291,7 +292,7 @@ local function redraw_poll_viewer_content(data) vote_buttons[i] = vote_button local label = grid.add {type = 'label', caption = a.text} - label.style.height = 24 + label.style.single_line = false end data.vote_buttons = vote_buttons @@ -737,7 +738,8 @@ local function create_poll(event) end_tick = end_tick, duration = duration, created_by = event.player, - edited_by = {} + edited_by = {}, + edit_rank = nil } insert(polls, poll_data) @@ -1331,7 +1333,8 @@ function Class.poll(data) end_tick = end_tick, duration = duration, created_by = game.player or {name = '', valid = true}, - edited_by = {} + edited_by = {}, + edit_rank = data.edit_rank or nil } insert(polls, poll_data) @@ -1370,6 +1373,16 @@ function Class.poll_result(id) return table.concat {'poll #', id, ' not found'} end +function Class.get_poll_data(id) + for _, poll_data in pairs(polls) do + if poll_data.id == id then + return poll_data + end + end + + return nil +end + local function poll_command(args) local param = args.poll param = 'return ' .. param diff --git a/features/restart_command.lua b/features/restart_command.lua index 0b1cd827..ee9d2966 100644 --- a/features/restart_command.lua +++ b/features/restart_command.lua @@ -13,10 +13,21 @@ local Public = {} local game_types = {scenario = 'scenario', save = 'save'} Public.game_types = game_types -local memory = {mod_pack_text = '', restarting = nil} -local start_game_data = {type = game_types.scenario, name = '', mod_pack = nil} +local memory = { + mod_pack_text = '', + restarting = nil, + use_map_poll_result = nil +} +local start_game_data = { + type = game_types.scenario, + name = '', + mod_pack = nil +} -Global.register({start_game_data = start_game_data, memory = memory}, function(tbl) +Global.register({ + start_game_data = start_game_data, + memory = memory +}, function(tbl) start_game_data = tbl.start_game_data memory = tbl.memory end) @@ -27,6 +38,7 @@ end local registered = false local server_can_restart_func = default_can_restart_func +local server_restart_requested_callback = nil local server_restart_callback = nil local server_player = {name = '', print = print, admin = true} @@ -134,6 +146,10 @@ local function restart(args, player) return end + if server_restart_requested_callback then + server_restart_requested_callback() + end + local str = args.str:trim() if str ~= '' and player.admin then if not set_start_data(player, str) then @@ -168,7 +184,7 @@ local function abort(_, player) end end -function Public.register(can_restart_func, restart_callback) +function Public.register(can_restart_func, restart_callback, restart_requested_callback) if registered then error('Register can only be called once', 2) end @@ -179,9 +195,18 @@ function Public.register(can_restart_func, restart_callback) registered = true server_can_restart_func = can_restart_func or default_can_restart_func + server_restart_requested_callback = restart_requested_callback server_restart_callback = restart_callback end +function Public.get_use_map_poll_result_option() + return memory.use_map_poll_result +end + +function Public.set_use_map_poll_result_option(state) + memory.use_map_poll_result = state +end + local main_frame_name = Gui.uid_name() local close_button_name = Gui.uid_name() local scenario_radio_button_name = Gui.uid_name() @@ -189,6 +214,7 @@ local save_radio_button_name = Gui.uid_name() local name_textfield_name = Gui.uid_name() local set_mod_pack_checkbox_name = Gui.uid_name() local mod_pack_name_textfield_name = Gui.uid_name() +local use_map_poll_result_checkbox_name = Gui.uid_name() Public._main_frame_name = main_frame_name Public._close_button_name = close_button_name @@ -197,6 +223,7 @@ Public._save_radio_button_name = save_radio_button_name Public._name_textfield_name = name_textfield_name Public._set_mod_pack_checkbox_name = set_mod_pack_checkbox_name Public._mod_pack_name_textfield_name = mod_pack_name_textfield_name +Public._use_map_poll_result_checkbox_name = use_map_poll_result_checkbox_name local function value_of_type_or_deafult(value, value_type, default) if type(value) == value_type then @@ -309,7 +336,19 @@ local function draw_main_frame(player) Gui.set_data(set_mod_pack_checkbox, mod_pack_name_textfield) - local bottom_flow = main_frame.add {type = 'flow', direction = 'horizontal'} + if memory.use_map_poll_result ~= nil then + main_frame.add { + type = 'checkbox', + name = use_map_poll_result_checkbox_name, + caption = 'Use map poll result', + state = memory.use_map_poll_result + } + end + + local bottom_flow = main_frame.add { + type = 'flow', + direction = 'horizontal' + } bottom_flow.add { type = 'button', @@ -360,6 +399,11 @@ Gui.on_checked_state_changed(set_mod_pack_checkbox_name, function(event) end end) +Gui.on_checked_state_changed(use_map_poll_result_checkbox_name, function(event) + local use_map_poll_result_checkbox = event.element + memory.use_map_poll_result = use_map_poll_result_checkbox.state +end) + Gui.on_text_changed(mod_pack_name_textfield_name, function(event) local text = event.element.text start_game_data.mod_pack = text diff --git a/map_gen/maps/danger_ores/modules/map_poll.lua b/map_gen/maps/danger_ores/modules/map_poll.lua index 2e6d422b..d4abba38 100644 --- a/map_gen/maps/danger_ores/modules/map_poll.lua +++ b/map_gen/maps/danger_ores/modules/map_poll.lua @@ -2,13 +2,78 @@ local Poll = require 'features.gui.poll' local Global = require 'utils.global' local Event = require 'utils.event' local Server = require 'features.server' +local Ranks = require 'resources.ranks' -local data = {created = false} +local data = { + created = false, + id = nil +} Global.register(data, function(tbl) data = tbl end) +local normal_mod_pack = 'danger_ore23' +local bobs_mod_pack = 'danger_ore_bobs2' + +local maps = {{ + name = 'danger-ore-deadlock-beltboxes-ore-only', + mod_pack = normal_mod_pack, + display_name = 'terraforming (default)' +}, { + name = 'danger-ore-one-direction-beltboxes-ore-only', + mod_pack = normal_mod_pack, + display_name = 'one direction (line)' +}, { + name = 'danger-ore-3way-beltboxes-ore-only', + mod_pack = normal_mod_pack, + display_name = '3-way (T shape)' +}, { + name = 'danger-ore-chessboard-beltboxes-ore-only', + mod_pack = normal_mod_pack, + display_name = 'chessboard (random squares)' +}, { + name = 'danger-ore-chessboard-uniform-beltboxes-ore-only', + mod_pack = normal_mod_pack, + display_name = 'chessboard uniform (fixed squares)' +}, { + name = 'danger-ore-circles-beltboxes-ore-only', + mod_pack = normal_mod_pack, + display_name = 'circles (ore rings)' +}, { + name = 'danger-ore-gradient-beltboxes-ore-only', + mod_pack = normal_mod_pack, + display_name = 'gradient (smooth ore ratios)' +}, { + name = 'danger-ore-split-beltboxes-ore-only', + mod_pack = normal_mod_pack, + display_name = 'split (4x sectors)' +}, { + name = 'danger-ore-hub-spiral-beltboxes-ore-only', + mod_pack = normal_mod_pack, + display_name = 'hub-spiral (with void)' +}, { + name = 'danger-ore-spiral-beltboxes-ore-only', + mod_pack = normal_mod_pack, + display_name = 'spiral (without void)' +}, { + name = 'danger-ore-landfill-beltboxes-ore-only', + mod_pack = normal_mod_pack, + display_name = 'landfill (all tiles)' +}, { + name = 'danger-ore-patches-beltboxes-ore-only', + mod_pack = normal_mod_pack, + display_name = 'patches (ore islands in coal)' +}, { + name = 'danger-ore-xmas-tree-beltboxes-ore-only', + mod_pack = normal_mod_pack, + display_name = 'xmas tree (triangle)' +}, { + name = 'danger-bobs-ores', + mod_pack = bobs_mod_pack, + display_name = 'bob\'s mod (default map)' +}} + Event.add(Server.events.on_server_started, function() if data.created then return @@ -16,24 +81,59 @@ Event.add(Server.events.on_server_started, function() data.created = true - Poll.poll({ + local answers = {} + for i, map_data in pairs(maps) do + answers[i] = map_data.display_name + end + + local success, id = Poll.poll({ question = 'Next map? (Advisory only)', duration = 0, - answers = { - 'terraforming (default)', - 'one direction (line)', - '3-way (T shape)', - 'chessboard (random squares)', - 'chessboard uniform (fixed squares)', - 'circles (ore rings)', - 'gradient (smooth ore ratios)', - 'split (4x sectors)', - 'hub-spiral (with void)', - 'spiral (without void)', - 'landfill (all tiles)', - 'patches (ore islands in coal)', - 'xmas tree (triangle)', - 'bob\'s mod (default map)' - } + edit_rank = Ranks.admin, + answers = answers }) + + if success then + data.id = id + end end) + +local Public = {} + +function Public.get_next_map() + local poll_data = Poll.get_poll_data(data.id) + if poll_data == nil then + return nil + end + + local answers = poll_data.answers + local vote_counts = {} + for i, answer_data in pairs(answers) do + vote_counts[i] = answer_data.voted_count + end + + local max_count = 0 + for i = 1, #vote_counts do + local count = vote_counts[i] or 0 + if count > max_count then + max_count = count + end + end + + if max_count == 0 then + return nil + end + + local max_indexes = {} + for i = 1, #vote_counts do + local count = vote_counts[i] or 0 + if count == max_count then + max_indexes[#max_indexes + 1] = i + end + end + + local chosen_index = max_indexes[math.random(#max_indexes)] + return maps[chosen_index] +end + +return Public diff --git a/map_gen/maps/danger_ores/modules/restart_command.lua b/map_gen/maps/danger_ores/modules/restart_command.lua index a1b6f511..03872f3d 100644 --- a/map_gen/maps/danger_ores/modules/restart_command.lua +++ b/map_gen/maps/danger_ores/modules/restart_command.lua @@ -2,6 +2,7 @@ local Discord = require 'resources.discord' local Server = require 'features.server' local Core = require 'utils.core' local Restart = require 'features.restart_command' +local MapPoll = require 'map_gen.maps.danger_ores.modules.map_poll' local ShareGlobals = require 'map_gen.maps.danger_ores.modules.shared_globals' local ScoreTracker = require 'utils.score_tracker' local PlayerStats = require 'features.player_stats' @@ -17,6 +18,7 @@ return function(config) --local danger_ore_role_mention = Discord.role_mentions.test Restart.set_start_game_data({type = Restart.game_types.scenario, name = config.scenario_name or 'danger-ore-next'}) + Restart.set_use_map_poll_result_option(true) local function can_restart(player) if player.admin then @@ -190,5 +192,18 @@ return function(config) Server.to_discord_named_raw(map_promotion_channel, message) end - Restart.register(can_restart, restart_callback) + local function restart_requested() + if not Restart.get_use_map_poll_result_option() then + return + end + + local map_data = MapPoll.get_next_map() + if map_data == nil then + return + end + + Restart.set_start_game_data({type = Restart.game_types.scenario, name = map_data.name, mod_pack = map_data.mod_pack}) + end + + Restart.register(can_restart, restart_callback, restart_requested) end