mirror of
https://github.com/Refactorio/RedMew.git
synced 2025-02-03 13:11:21 +02:00
Updates/frontier v8 (#1434)
* Fix player pockets * Add scenario manager gui * tweak terrain gen * Add discord notifications * Add restart UI
This commit is contained in:
parent
4b040d1048
commit
5152d642ce
@ -102,7 +102,7 @@ function Public.get_main_frame(player)
|
||||
vertically_stretchable = true,
|
||||
horizontal_align = 'center',
|
||||
padding = 10,
|
||||
vertical_spacing = 10,
|
||||
vertical_spacing = 5,
|
||||
})
|
||||
|
||||
for _, page in pairs(pages) do
|
||||
@ -157,7 +157,9 @@ function Public.close_all_pages(player)
|
||||
end
|
||||
|
||||
for _, button in pairs(Gui.get_data(frame).left.children) do
|
||||
button.toggled = false
|
||||
if button.type == 'button' or button.type == 'sprite-button' then
|
||||
button.toggled = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -57,7 +57,7 @@ local function draw_gui(player)
|
||||
button_flow.add { type = 'button', name = clear_button_name, style = 'red_back_button', caption = 'Clear' }
|
||||
local dry_run = button_flow.add { type = 'button', name = dry_run_button_name, style = 'forward_button', caption = 'Dry run' }
|
||||
local confirm = button_flow.add { type = 'button', name = confirm_button_name, style = 'confirm_double_arrow_button', caption = 'Confirm', tooltip = 'Run input code' }
|
||||
Gui.set_style(confirm, { left_margin = - 4 })
|
||||
Gui.set_style(confirm, { left_margin = -9 })
|
||||
|
||||
Gui.set_data(dry_run, { input = input, output = output })
|
||||
Gui.set_data(confirm, { input = input, output = output })
|
||||
|
@ -189,6 +189,7 @@ earn_coin=[achievement=steamrolled] you steal another treasure [item=coin] from
|
||||
empty_rocket=[color=purple][Kraken][/color] The God of the Sea accepts your rocket offer and rewards you with magic fishes
|
||||
kraken_eat=[color=purple][Kraken][/color] ate __1__ and was delicious!
|
||||
loot_chest=[achievement=golem] You find an hidden [color=orange]treasure[/color] beneath the enemy forces
|
||||
abort=[color=blue][Mapkeeper][/color] Aborting map restart
|
||||
restart=[color=blue][Mapkeeper][/color] Map is restarting in __1__ __plural_for_parameter_1_{1=second|rest=seconds}__
|
||||
rocket_launched=[color=blue][Mapkeeper][/color] __1__ __plural_for_parameter_1_{1=rocket|rest=rockets}__ launched, __2__ __plural_for_parameter_2_{1=rocket|rest=rockets}__ to go!
|
||||
rockets_to_launch=Remaining rockets to launch
|
||||
|
@ -150,7 +150,7 @@ return function(config)
|
||||
ore_totals_message = ore_totals_message..ore_name:gsub( "-ore", "")..": "..format_number(count, true)..", "
|
||||
end
|
||||
ore_totals_message = ore_totals_message:sub(1, -3)..')' -- remove the last ", " and add a bracket
|
||||
ore_totals_message = "Total ore mined: "..format_number(total_ore, true).. "\\n"..ore_totals_message
|
||||
ore_totals_message = format_number(total_ore, true).. "\\n"..ore_totals_message
|
||||
|
||||
local statistics_message = statistics.scenario..' completed!\\n\\n'..
|
||||
'Statistics:\\n'..
|
||||
|
@ -371,6 +371,9 @@ end
|
||||
|
||||
function Enemy.spawn_turret_outpost(position)
|
||||
local this = Public.get()
|
||||
if not this.spawn_enemy_outpost then
|
||||
return
|
||||
end
|
||||
if position.x < this.right_boundary * 32 + this.wall_width then
|
||||
return
|
||||
end
|
||||
|
@ -21,12 +21,7 @@ function Lobby.get_surface()
|
||||
end
|
||||
|
||||
function Lobby.teleport_to(player)
|
||||
for k = 1, player.get_max_inventory_index() do
|
||||
local inv = player.get_inventory(k)
|
||||
if inv and inv.valid then
|
||||
inv.clear()
|
||||
end
|
||||
end
|
||||
player.clear_items_inside()
|
||||
|
||||
local surface = Lobby.get_surface()
|
||||
local position = surface.find_non_colliding_position('character', {0, 0}, 0, 0.2)
|
||||
|
584
map_gen/maps/frontier/modules/restart.lua
Normal file
584
map_gen/maps/frontier/modules/restart.lua
Normal file
@ -0,0 +1,584 @@
|
||||
local AdminPanel = require 'features.gui.admin_panel.core'
|
||||
local Color = require 'resources.color_presets'
|
||||
local Core = require 'utils.core'
|
||||
local Discord = require 'resources.discord'
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
local Gui = require 'utils.gui'
|
||||
local PlayerStats = require 'features.player_stats'
|
||||
local ScoreTracker = require 'utils.score_tracker'
|
||||
local Server = require 'features.server'
|
||||
local Task = require 'utils.task'
|
||||
local Token = require 'utils.token'
|
||||
local Public = require 'map_gen.maps.frontier.shared.core'
|
||||
local format_number = require 'util'.format_number
|
||||
|
||||
local Restart = {}
|
||||
local main_button_name = Gui.uid_name()
|
||||
local textbox_tag_name = Gui.uid_name()
|
||||
local reset_button_name = Gui.uid_name()
|
||||
local save_button_name = Gui.uid_name()
|
||||
local apply_button_name = Gui.uid_name()
|
||||
local mode_dropdown_name = Gui.uid_name()
|
||||
local abort_button_name = Gui.uid_name()
|
||||
local restart_button_name = Gui.uid_name()
|
||||
local switch_save_button_name = Gui.uid_name()
|
||||
local switch_mod_pack_button_name = Gui.uid_name()
|
||||
local load_clear_button_name = Gui.uid_name()
|
||||
local load_confirm_button_name = Gui.uid_name()
|
||||
|
||||
---@type table<string>
|
||||
local DEFAULT_MODIFIERS = {
|
||||
'rounds',
|
||||
|
||||
-- Map gen
|
||||
'height', -- in chunks, height of the ribbon world
|
||||
'left_boundary', -- in chunks, distance to water body
|
||||
'right_boundary', -- in chunks, distance to wall/biter presence
|
||||
'wall_width', -- in tiles
|
||||
'rock_richness', -- how many rocks/chunk
|
||||
'ore_base_quantity', -- base ore quantity, everything is scaled up from this
|
||||
'ore_chunk_scale', -- sets how fast the ore will increase from spawn, lower = faster
|
||||
'kraken_distance', -- where the kraken lives past the left boundary
|
||||
|
||||
-- Rocket silo position
|
||||
'silo_starting_x',
|
||||
'move_buffer',
|
||||
'rocket_step', -- rocket/tiles ratio
|
||||
'min_step', -- minimum tiles to move
|
||||
'max_distance', -- maximum x distance of rocket silo
|
||||
'rockets_to_win',
|
||||
'rockets_launched',
|
||||
'rockets_per_death', -- how many extra launch needed for each death
|
||||
|
||||
-- Enemy data
|
||||
'spawn_enemy_outpost',
|
||||
'spawn_enemy_wave',
|
||||
|
||||
-- Markets
|
||||
'loot_budget',
|
||||
'loot_richness',
|
||||
|
||||
-- Spawn shop
|
||||
'spawn_shop_funds',
|
||||
}
|
||||
---@type table<string, any>
|
||||
local restart_modifiers = {}
|
||||
Global.register(restart_modifiers, function(tbl) restart_modifiers = tbl end)
|
||||
|
||||
local pages = AdminPanel.get_pages()
|
||||
pages[#pages +1] = {
|
||||
type = 'sprite-button',
|
||||
sprite = 'utility/map',
|
||||
tooltip = '[font=default-bold]Scenario manager[/font]',
|
||||
name = main_button_name,
|
||||
auto_toggle = true,
|
||||
}
|
||||
|
||||
local restart_mode_text = { 'None', 'Reset map', 'Restart server', 'Load save/mods' }
|
||||
|
||||
local function is_number(value)
|
||||
if type(value) == 'number' then return true end
|
||||
return tonumber(value) ~= nil
|
||||
end
|
||||
|
||||
local function is_boolean(value)
|
||||
if type(value) == 'boolean' then return true end
|
||||
return value == 'true' or value == 'false'
|
||||
end
|
||||
|
||||
local function parse_value(value)
|
||||
if is_boolean(value) then
|
||||
return value == 'true' and true or false
|
||||
end
|
||||
|
||||
if is_number(value) then
|
||||
return tonumber(value)
|
||||
end
|
||||
|
||||
return value
|
||||
end
|
||||
|
||||
local function safe_add(value1, value2)
|
||||
if type(value1) ~= type(value2) then
|
||||
return
|
||||
end
|
||||
|
||||
if is_boolean(value1) and is_boolean(value2) then
|
||||
return value2 == 'true' and true or false
|
||||
end
|
||||
|
||||
if is_number(value1) and is_number(value2) then
|
||||
return tonumber(value1) + tonumber(value2)
|
||||
end
|
||||
|
||||
return value2
|
||||
end
|
||||
|
||||
local function show_values(parent, parent_data, params)
|
||||
local flow = parent.add { type = 'flow', direction = 'horizontal' }
|
||||
Gui.set_style(flow, { vertical_align = 'center', width = 444 })
|
||||
|
||||
local this = Public.get()
|
||||
local key = params.feature
|
||||
local current_value = this[key]
|
||||
local modifier_value = restart_modifiers[key]
|
||||
local predicted_value = safe_add(current_value, modifier_value)
|
||||
|
||||
flow.add { type = 'label', caption = params.caption }
|
||||
Gui.add_pusher(flow)
|
||||
local current = flow.add {
|
||||
type = 'text-box',
|
||||
style = 'short_number_textfield',
|
||||
tags = { name = textbox_tag_name },
|
||||
text = current_value,
|
||||
}
|
||||
local modifier = flow.add {
|
||||
type = 'text-box',
|
||||
style = 'short_number_textfield',
|
||||
tags = { name = textbox_tag_name },
|
||||
text = modifier_value,
|
||||
}
|
||||
local predicted = flow.add {
|
||||
type = 'text-box',
|
||||
style = 'short_number_textfield',
|
||||
text = predicted_value,
|
||||
}
|
||||
predicted.enabled = false
|
||||
|
||||
local data = { current = current, modifier = modifier, predicted = predicted }
|
||||
table.insert(parent_data, { feature = key, data = data })
|
||||
Gui.set_data(current, data)
|
||||
Gui.set_data(modifier, data)
|
||||
return flow
|
||||
end
|
||||
|
||||
local function draw_gui(player)
|
||||
local canvas = AdminPanel.get_canvas(player)
|
||||
Gui.clear(canvas)
|
||||
|
||||
do -- Scenario settings
|
||||
local data = {}
|
||||
|
||||
local headers = canvas.add { type = 'flow', direction = 'horizontal' }
|
||||
Gui.set_style(headers, { right_padding = 14 })
|
||||
Gui.add_pusher(headers)
|
||||
Gui.set_style(headers.add { type = 'label', caption = 'Current' }, { width = 80, font = 'heading-2', font_color = { 255, 230, 192 } })
|
||||
Gui.set_style(headers.add { type = 'label', caption = 'Modifier' }, { width = 80, font = 'heading-2', font_color = { 255, 230, 192 } })
|
||||
Gui.set_style(headers.add { type = 'label', caption = 'Predicted' }, { width = 80, font = 'heading-2', font_color = { 255, 230, 192 } })
|
||||
|
||||
local sp = canvas.add { type = 'scroll-pane', horizontal_scroll_policy = 'auto', vertical_scroll_policy = 'always', style = 'naked_scroll_pane' }
|
||||
Gui.set_style(sp, { maximal_height = 400, right_padding = 4 })
|
||||
|
||||
local row_1 = sp.add { type = 'frame', caption = 'Map generation', style = 'bordered_frame', direction = 'vertical' }
|
||||
show_values(row_1, data, { feature = 'height', caption = 'Map height' })
|
||||
show_values(row_1, data, { feature = 'left_boundary', caption = 'Left boundary' })
|
||||
show_values(row_1, data, { feature = 'right_boundary', caption = 'Right boundary' })
|
||||
show_values(row_1, data, { feature = 'wall_width', caption = 'Wall width' })
|
||||
show_values(row_1, data, { feature = 'rock_richness', caption = 'Rocks frequency' })
|
||||
show_values(row_1, data, { feature = 'ore_base_quantity', caption = 'Base resources richness' })
|
||||
show_values(row_1, data, { feature = 'ore_chunk_scale', caption = 'Ore chunk scale' })
|
||||
show_values(row_1, data, { feature = 'kraken_distance', caption = 'Kraken distance' })
|
||||
|
||||
local row_2 = sp.add { type = 'frame', caption = 'Rocket silo', style = 'bordered_frame', direction = 'vertical' }
|
||||
show_values(row_2, data, { feature = 'silo_starting_x', caption = 'Silo starting X' })
|
||||
show_values(row_2, data, { feature = 'move_buffer', caption = 'Moving buffer' })
|
||||
show_values(row_2, data, { feature = 'rocket_step', caption = 'Moving step' })
|
||||
show_values(row_2, data, { feature = 'min_step', caption = 'Min. moving step' })
|
||||
show_values(row_2, data, { feature = 'max_distance', caption = 'Max. silo distance' })
|
||||
show_values(row_2, data, { feature = 'rockets_to_win', caption = 'Rockets to win' })
|
||||
show_values(row_2, data, { feature = 'rockets_launched', caption = 'Rockets launched' })
|
||||
show_values(row_2, data, { feature = 'rockets_per_death', caption = 'Rockets per death' })
|
||||
|
||||
local row_3 = sp.add { type = 'frame', caption = 'Enemies', style = 'bordered_frame', direction = 'vertical' }
|
||||
show_values(row_3, data, { feature = 'spawn_enemy_outpost', caption = 'Turrets under rocks' })
|
||||
show_values(row_3, data, { feature = 'spawn_enemy_wave', caption = 'Waves after launches' })
|
||||
|
||||
local row_4 = sp.add { type = 'frame', caption = 'Markets', style = 'bordered_frame', direction = 'vertical' }
|
||||
show_values(row_4, data, { feature = 'loot_budget', caption = 'Loot budget' })
|
||||
show_values(row_4, data, { feature = 'loot_richness', caption = 'Loot richness' })
|
||||
|
||||
local row_5 = sp.add { type = 'frame', caption = 'Spawn Shop', style = 'bordered_frame', direction = 'vertical' }
|
||||
show_values(row_5, data, { feature = 'spawn_shop_funds', caption = 'Team funds' })
|
||||
|
||||
local button_flow = canvas.add { type = 'flow', direction = 'horizontal' }
|
||||
Gui.set_style(button_flow, { right_padding = 8 })
|
||||
Gui.add_pusher(button_flow)
|
||||
button_flow.add {
|
||||
type = 'button',
|
||||
name = reset_button_name,
|
||||
style = 'red_back_button',
|
||||
caption = 'Reset',
|
||||
tooltip = 'Resets all values to previous configuration',
|
||||
}
|
||||
local save = button_flow.add {
|
||||
type = 'button',
|
||||
name = save_button_name,
|
||||
style = 'forward_button',
|
||||
caption = 'Save',
|
||||
tooltip = 'Save modifiers configuration for later',
|
||||
}
|
||||
local apply = button_flow.add {
|
||||
type = 'button',
|
||||
name = apply_button_name,
|
||||
style = 'confirm_double_arrow_button',
|
||||
caption = 'Apply',
|
||||
tooltip = 'Apply modifiers to current configuration now',
|
||||
}
|
||||
Gui.set_style(apply, { left_margin = -9 })
|
||||
Gui.set_data(save, data)
|
||||
Gui.set_data(apply, data)
|
||||
end
|
||||
|
||||
canvas.add { type = 'line', direction = 'horizontal' }
|
||||
|
||||
do -- Restart settings
|
||||
local mode = Public.get('server_commands').mode
|
||||
local restart_settings = canvas.add { type = 'frame', caption = 'Restart settings', style = 'bordered_frame', direction = 'vertical' }
|
||||
|
||||
local row_1 = restart_settings.add { type = 'flow', direction = 'horizontal' }
|
||||
row_1.add { type = 'label', caption = 'Map restart mode' }
|
||||
Gui.add_pusher(row_1)
|
||||
row_1.add {
|
||||
type = 'drop-down',
|
||||
name = mode_dropdown_name,
|
||||
items = restart_mode_text,
|
||||
selected_index = mode
|
||||
}
|
||||
|
||||
local row_2 = restart_settings.add { type = 'flow', direction = 'horizontal' }
|
||||
row_2.add {
|
||||
type = 'label',
|
||||
caption = 'Restart scenario'
|
||||
}
|
||||
Gui.add_pusher(row_2)
|
||||
row_2.add {
|
||||
type = 'button',
|
||||
name = abort_button_name,
|
||||
style = 'red_back_button',
|
||||
caption = 'Abort',
|
||||
tooltip = 'Abort any restart action'
|
||||
}
|
||||
row_2.add {
|
||||
type = 'button',
|
||||
name = restart_button_name,
|
||||
style = 'red_confirm_button',
|
||||
caption = 'Restart',
|
||||
tooltip = 'A save of current map will be automatically\ncreated before restarting'
|
||||
}
|
||||
end
|
||||
|
||||
do -- Load settings
|
||||
local server_commands = Public.get('server_commands')
|
||||
local switch_map = server_commands.switch_map
|
||||
local mode = server_commands.mode
|
||||
|
||||
if switch_map.name == '' then
|
||||
switch_map.name = nil
|
||||
end
|
||||
if switch_map.mod_pack == '' then
|
||||
switch_map.mod_pack = nil
|
||||
end
|
||||
|
||||
local load_settings = canvas.add { type = 'frame', caption = 'Load settings', style = 'bordered_frame', direction = 'vertical' }
|
||||
|
||||
local row_1 = load_settings.add { type = 'flow', direction = 'vertical' }
|
||||
local table_1 = row_1.add { type = 'table', column_count = 2 }
|
||||
table_1.add {
|
||||
type = 'label',
|
||||
caption = 'Save name',
|
||||
}
|
||||
local t12 = table_1.add {
|
||||
type = 'textfield',
|
||||
name = switch_save_button_name,
|
||||
text = switch_map.name or 'i.e. frontier-special.zip',
|
||||
}
|
||||
table_1.add {
|
||||
type = 'label',
|
||||
caption = 'Mod pack name',
|
||||
}
|
||||
local t22 = table_1.add {
|
||||
type = 'textfield',
|
||||
name = switch_mod_pack_button_name,
|
||||
text = switch_map.mod_pack or 'i.e. frontier_modpack',
|
||||
}
|
||||
|
||||
local row_2 = load_settings.add { type = 'flow', direction = 'horizontal' }
|
||||
Gui.add_pusher(row_2)
|
||||
row_2.add {
|
||||
type = 'button',
|
||||
name = load_clear_button_name,
|
||||
style = 'red_back_button',
|
||||
caption = 'Clear',
|
||||
tooltip = 'Clear load settings',
|
||||
}
|
||||
local confirm = row_2.add {
|
||||
type = 'button',
|
||||
name = load_confirm_button_name,
|
||||
style = 'confirm_button',
|
||||
caption = 'Confirm',
|
||||
tooltip = 'Confirm load settings',
|
||||
}
|
||||
|
||||
Gui.set_data(confirm, { name = t12, mod_pack = t22 })
|
||||
|
||||
load_settings.visible = (mode == Public.restart_mode.switch)
|
||||
end
|
||||
end
|
||||
|
||||
local raise_event_token = Token.register(function(params)
|
||||
script.raise_event(params.name, params.data or {})
|
||||
end)
|
||||
|
||||
Gui.on_click(main_button_name, function(event)
|
||||
local player = event.player
|
||||
local element = event.element
|
||||
if element.toggled then
|
||||
AdminPanel.close_all_pages(player)
|
||||
event.element.toggled = true
|
||||
draw_gui(player)
|
||||
else
|
||||
Gui.clear(AdminPanel.get_canvas(player))
|
||||
end
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_gui_text_changed, function(event)
|
||||
local element = event.element
|
||||
if not (element and element.valid) then
|
||||
return
|
||||
end
|
||||
|
||||
local tag = element.tags and element.tags.name
|
||||
if not tag then
|
||||
return
|
||||
end
|
||||
|
||||
if tag == textbox_tag_name then
|
||||
local data = Gui.get_data(element)
|
||||
local current, modifier = data.current, data.modifier
|
||||
data.predicted.text = tostring(safe_add(current.text, modifier.text))
|
||||
end
|
||||
end)
|
||||
|
||||
Gui.on_click(reset_button_name, function(event)
|
||||
draw_gui(event.player)
|
||||
end)
|
||||
|
||||
Gui.on_click(save_button_name, function(event)
|
||||
local data = Gui.get_data(event.element)
|
||||
for _, v in pairs(data) do
|
||||
restart_modifiers[v.feature] = parse_value(v.data.modifier.text)
|
||||
end
|
||||
draw_gui(event.player)
|
||||
end)
|
||||
|
||||
Gui.on_click(apply_button_name, function(event)
|
||||
local this = Public.get()
|
||||
local data = Gui.get_data(event.element)
|
||||
for _, v in pairs(data) do
|
||||
this[v.feature] = safe_add(v.data.current.text, v.data.modifier.text)
|
||||
end
|
||||
Restart.reset_modifiers()
|
||||
draw_gui(event.player)
|
||||
end)
|
||||
|
||||
Gui.on_selection_state_changed(mode_dropdown_name, function(event)
|
||||
local mode = event.element.selected_index
|
||||
Public.get().server_commands.mode = mode
|
||||
event.player.print('Restart mode changed to: '..restart_mode_text[mode], Color.info)
|
||||
draw_gui(event.player)
|
||||
end)
|
||||
|
||||
Gui.on_click(abort_button_name, function(event)
|
||||
local cmd = Public.get('server_commands')
|
||||
if not cmd.restarting then
|
||||
event.player.print('No restart action in progress', Color.info)
|
||||
return
|
||||
else
|
||||
cmd.restarting = false
|
||||
game.print({'frontier.abort'}, Color.warning)
|
||||
end
|
||||
end)
|
||||
|
||||
Gui.on_click(restart_button_name, function()
|
||||
local this = Public.get()
|
||||
this.server_commands.restarting = true
|
||||
game.auto_save('pre-reset')
|
||||
Task.set_timeout( 1, Restart.restart_message_token, 10)
|
||||
Task.set_timeout(11, raise_event_token, { name = Public.events.on_game_finished })
|
||||
end)
|
||||
|
||||
Gui.on_click(load_clear_button_name, function(event)
|
||||
local switch_map = Public.get('server_commands').switch_map
|
||||
switch_map.name = nil
|
||||
switch_map.mod_pack = nil
|
||||
draw_gui(event.player)
|
||||
end)
|
||||
|
||||
Gui.on_click(load_confirm_button_name, function(event)
|
||||
local data = Gui.get_data(event.element)
|
||||
local switch_map = Public.get('server_commands').switch_map
|
||||
switch_map.name = data.name.text
|
||||
switch_map.mod_pack = data.mod_pack.text
|
||||
draw_gui(event.player)
|
||||
end)
|
||||
|
||||
Restart.restart_message_token = Token.register(function(seconds)
|
||||
game.print({'frontier.restart', seconds}, Color.success)
|
||||
end)
|
||||
|
||||
function Restart.set_game_state(player_won)
|
||||
local this = Public.get()
|
||||
this.scenario_finished = true
|
||||
this.server_commands.restarting = true
|
||||
game.set_game_state {
|
||||
game_finished = true,
|
||||
player_won = player_won or false,
|
||||
can_continue = true,
|
||||
victorious_force = player_won and 'player' or 'enemy'
|
||||
}
|
||||
|
||||
Task.set_timeout( 1, Restart.restart_message_token, 90)
|
||||
Task.set_timeout(31, Restart.restart_message_token, 60)
|
||||
Task.set_timeout(61, Restart.restart_message_token, 30)
|
||||
Task.set_timeout(81, Restart.restart_message_token, 10)
|
||||
Task.set_timeout(86, Restart.restart_message_token, 5)
|
||||
Task.set_timeout(90, raise_event_token, { name = Public.events.on_game_finished })
|
||||
end
|
||||
|
||||
function Restart.reset_modifiers()
|
||||
local this = Public.get()
|
||||
for _, k in pairs(DEFAULT_MODIFIERS) do
|
||||
local init_value = this[k]
|
||||
if type(init_value) == 'number' then
|
||||
restart_modifiers[k] = 0
|
||||
else
|
||||
restart_modifiers[k] = init_value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Restart.apply_modifiers()
|
||||
local this = Public.get()
|
||||
for k, v in pairs(restart_modifiers) do
|
||||
this[k] = safe_add(this[k], v)
|
||||
end
|
||||
Restart.reset_modifiers()
|
||||
end
|
||||
|
||||
function Restart.get(key)
|
||||
if key then
|
||||
return restart_modifiers[key]
|
||||
end
|
||||
return restart_modifiers
|
||||
end
|
||||
|
||||
function Restart.set(key, value)
|
||||
restart_modifiers[key] = value
|
||||
end
|
||||
|
||||
function Restart.queue_restart_event()
|
||||
Task.set_timeout(10, raise_event_token, { name = Public.events.on_game_started })
|
||||
end
|
||||
|
||||
function Restart.execute_server_command()
|
||||
local cmd = Public.get('server_commands')
|
||||
if not cmd.restarting then
|
||||
return
|
||||
end
|
||||
local is_hosted = Server.get_current_time() ~= nil
|
||||
|
||||
if is_hosted and cmd.mode == Public.restart_mode.switch then
|
||||
Server.start_game({
|
||||
type = (cmd.switch_map.name and 'save') or 'scenario',
|
||||
name = cmd.switch_map.name or 'frontier',
|
||||
mod_pack = cmd.switch_map.mod_pack,
|
||||
})
|
||||
elseif is_hosted and cmd.mode == Public.restart_mode.restart then
|
||||
Server.start_game({
|
||||
type = 'scenario',
|
||||
name = 'frontier',
|
||||
mod_pack = nil,
|
||||
})
|
||||
elseif cmd.mode ~= Public.restart_mode.none then
|
||||
Restart.queue_restart_event()
|
||||
end
|
||||
cmd.restarting = false
|
||||
end
|
||||
|
||||
function Restart.announce_new_map()
|
||||
local map_promotion_channel = Discord.channel_names.map_promotion
|
||||
local frontier_role_mention = Discord.role_mentions.frontier
|
||||
|
||||
if _DEBUG then
|
||||
map_promotion_channel = Discord.channel_names.bot_playground
|
||||
frontier_role_mention = Discord.role_mentions.test
|
||||
end
|
||||
|
||||
local notification_message = frontier_role_mention .. ' **Frontier map has just restarted!**'
|
||||
Server.to_discord_named_raw(map_promotion_channel, notification_message)
|
||||
end
|
||||
|
||||
function Restart.print_endgame_statistics()
|
||||
local map_promotion_channel = Discord.channel_names.map_promotion
|
||||
local frontier_channel = Discord.channel_names.frontier
|
||||
|
||||
if _DEBUG then
|
||||
map_promotion_channel = Discord.channel_names.bot_playground
|
||||
frontier_channel = Discord.channel_names.bot_playground
|
||||
end
|
||||
|
||||
local statistics = {
|
||||
time_string = Core.format_time(game.ticks_played),
|
||||
biters_killed = ScoreTracker.get_for_global(PlayerStats.aliens_killed_name),
|
||||
entities_built = ScoreTracker.get_for_global(PlayerStats.built_by_players_name),
|
||||
resources_exhausted = ScoreTracker.get_for_global(PlayerStats.resources_exhausted_name),
|
||||
total_players = #game.players,
|
||||
rounds = Public.get('rounds'),
|
||||
rockets_launched = Public.get('rockets_launched'),
|
||||
tiles_traveled = math.ceil(Public.get('x')),
|
||||
}
|
||||
do
|
||||
local resource_prototypes = game.get_filtered_entity_prototypes({{ filter = 'type', type = 'resource' }})
|
||||
local ore_products = {}
|
||||
for _, ore_prototype in pairs(resource_prototypes) do
|
||||
local mineable_properties = ore_prototype.mineable_properties
|
||||
if mineable_properties.minable and ore_prototype.resource_category == 'basic-solid' then
|
||||
for _, product in pairs(mineable_properties.products) do
|
||||
ore_products[product.name] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local total_ore = 0
|
||||
local ore_totals_message = '('
|
||||
for ore_name in pairs(ore_products) do
|
||||
local count = game.forces.player.item_production_statistics.get_input_count(ore_name)
|
||||
total_ore = total_ore + count
|
||||
ore_totals_message = ore_totals_message..ore_name:gsub( '-ore', '')..': '..format_number(count, true)..', '
|
||||
end
|
||||
ore_totals_message = ore_totals_message:sub(1, -3)..')' -- remove the last ', ' and add a bracket
|
||||
statistics.ore_totals_value = format_number(total_ore, true)
|
||||
statistics.ore_totals_breakdown = ore_totals_message
|
||||
end
|
||||
|
||||
local statistics_message = {
|
||||
'Frontier round '..statistics.rounds..' completed!',
|
||||
'',
|
||||
'S T A T I S T I C S:',
|
||||
'Map time: '..statistics.time_string,
|
||||
'Total entities built: '..statistics.entities_built,
|
||||
'Total ore mined: '..statistics.ore_totals_value,
|
||||
statistics.ore_totals_breakdown,
|
||||
'Total ore resources exhausted: '..statistics.resources_exhausted,
|
||||
'Players: '..statistics.total_players,
|
||||
'Rockets launched: '..statistics.rockets_launched,
|
||||
'Tiles traveled: '..statistics.tiles_traveled,
|
||||
'Enemies killed: '..statistics.biters_killed,
|
||||
}
|
||||
Server.to_discord_named_embed(map_promotion_channel, table.concat(statistics_message, '\\n'))
|
||||
Server.to_discord_named_embed(frontier_channel, table.concat(statistics_message, '\\n'))
|
||||
game.print(table.concat(statistics_message, '\n'), { sound_path = 'utility/new_objective' })
|
||||
end
|
||||
|
||||
return Restart
|
@ -6,6 +6,7 @@ local Token = require 'utils.token'
|
||||
local Task = require 'utils.task'
|
||||
local Public = require 'map_gen.maps.frontier.shared.core'
|
||||
local Enemy = require 'map_gen.maps.frontier.modules.enemy'
|
||||
local Restart = require 'map_gen.maps.frontier.modules.restart'
|
||||
local Terrain = require 'map_gen.maps.frontier.modules.terrain'
|
||||
local math_abs = math.abs
|
||||
local math_ceil = math.ceil
|
||||
@ -95,10 +96,6 @@ local bard_messages_2 = {
|
||||
|
||||
RocketSilo.play_sound_token = Token.register(Sounds.notify_all)
|
||||
|
||||
RocketSilo.restart_message_token = Token.register(function(seconds)
|
||||
game.print({'frontier.restart', seconds}, Color.success)
|
||||
end)
|
||||
|
||||
function RocketSilo.bard_message(list)
|
||||
game.print('[color=orange][Bard][/color] ' .. list[math_random(#list)], { sound_path = 'utility/axe_fighting', color = Color.brown })
|
||||
end
|
||||
@ -225,7 +222,7 @@ function RocketSilo.compute_silo_coordinates(step)
|
||||
this.rockets_to_win = this.rockets_to_win - remove_rockets
|
||||
if this.rockets_to_win < 1 then this.rockets_to_win = 1 end
|
||||
if this.rockets_launched >= this.rockets_to_win then
|
||||
RocketSilo.set_game_state(true)
|
||||
Restart.set_game_state(true)
|
||||
return
|
||||
else
|
||||
game.print({'frontier.warning_min_distance', this.rocket_step})
|
||||
@ -247,44 +244,6 @@ function RocketSilo.init_silo()
|
||||
RocketSilo.move_silo()
|
||||
end
|
||||
|
||||
function RocketSilo.set_game_state(player_won)
|
||||
Public.get().scenario_finished = true
|
||||
game.set_game_state {
|
||||
game_finished = true,
|
||||
player_won = player_won or false,
|
||||
can_continue = true,
|
||||
victorious_force = player_won and 'player' or 'enemy'
|
||||
}
|
||||
|
||||
Task.set_timeout( 1, RocketSilo.restart_message_token, 90)
|
||||
Task.set_timeout(31, RocketSilo.restart_message_token, 60)
|
||||
Task.set_timeout(61, RocketSilo.restart_message_token, 30)
|
||||
Task.set_timeout(81, RocketSilo.restart_message_token, 10)
|
||||
Task.set_timeout(86, RocketSilo.restart_message_token, 5)
|
||||
Task.set_timeout(90, RocketSilo.end_game_token)
|
||||
Task.set_timeout(100, RocketSilo.restart_game_token)
|
||||
end
|
||||
RocketSilo.set_game_state_token = Token.register(RocketSilo.set_game_state)
|
||||
|
||||
RocketSilo.restart_game_token = Token.register(function()
|
||||
script.raise_event(Public.events.on_game_started, {})
|
||||
end)
|
||||
|
||||
function RocketSilo.on_game_finished()
|
||||
Public.get().lobby_enabled = true
|
||||
game.print({'frontier.map_setup'})
|
||||
|
||||
local surface = Public.surface()
|
||||
surface.clear(true)
|
||||
local mgs = table.deepcopy(surface.map_gen_settings)
|
||||
mgs.seed = mgs.seed + 1e4
|
||||
surface.map_gen_settings = mgs
|
||||
end
|
||||
|
||||
RocketSilo.end_game_token = Token.register(function()
|
||||
script.raise_event(Public.events.on_game_finished, {})
|
||||
end)
|
||||
|
||||
function RocketSilo.on_rocket_launched(event)
|
||||
local rocket = event.rocket
|
||||
if not (rocket and rocket.valid) then
|
||||
@ -299,7 +258,7 @@ function RocketSilo.on_rocket_launched(event)
|
||||
this.rockets_launched = this.rockets_launched + 1
|
||||
ScoreTracker.set_for_global(Public.scores.rocket_launches.name, this.rockets_to_win - this.rockets_launched)
|
||||
if this.rockets_launched >= this.rockets_to_win then
|
||||
RocketSilo.set_game_state(true)
|
||||
Restart.set_game_state(true)
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -319,7 +319,7 @@ end
|
||||
function SpawnShop.earn_coin()
|
||||
local this = Public.get()
|
||||
this.spawn_shop_funds = this.spawn_shop_funds + 1
|
||||
ScoreTracker.change_for_global(Public.scores.shop_funds.name, 1)
|
||||
ScoreTracker.set_for_global(Public.scores.shop_funds.name, this.spawn_shop_funds)
|
||||
Toast.toast_all_players(20, {'frontier.earn_coin'})
|
||||
end
|
||||
|
||||
@ -395,7 +395,7 @@ function SpawnShop.on_player_refresh(player)
|
||||
local this = Public.get()
|
||||
this.spawn_shop_funds = this.spawn_shop_funds - 1
|
||||
this.spawn_shop_cooldown[player.index] = game.tick + 40 * SECOND
|
||||
ScoreTracker.change_for_global(Public.scores.shop_funds.name, -1)
|
||||
ScoreTracker.set_for_global(Public.scores.shop_funds.name, this.spawn_shop_funds)
|
||||
player.print('[color=orange][Bard][/color] ' .. bard_refresh_messages[math_random(#bard_refresh_messages)], { sound_path = 'utility/scenario_message', color = Color.dark_grey })
|
||||
if this.spawn_shop_funds <= 5 then
|
||||
game.print({'frontier.shop_funds_alert', player.name, this.spawn_shop_funds})
|
||||
|
@ -201,15 +201,15 @@ function Terrain.scale_resource_richness(surface, area)
|
||||
local chunks = math.clamp(math_abs((resource.position.x - this.right_boundary * 32) / this.ore_chunk_scale), 1, 100)
|
||||
chunks = math_random(chunks, chunks + 4)
|
||||
if resource.prototype.resource_category == 'basic-fluid' then
|
||||
resource.amount = 3000 * 3 * chunks
|
||||
resource.amount = this.ore_base_quantity * 800 * chunks
|
||||
elseif resource.prototype.resource_category == 'basic-solid' then
|
||||
resource.amount = math_min(0.7 * resource.amount, 100 + math_random(100))
|
||||
resource.amount = math_min(0.7 * resource.amount, this.ore_base_quantity * 10 + math_random(100))
|
||||
end
|
||||
else
|
||||
if resource.prototype.resource_category == 'basic-fluid' then
|
||||
resource.amount = 800000 + math_random(400000)
|
||||
resource.amount = this.ore_base_quantity * 80000 + math_random(400000)
|
||||
elseif resource.prototype.resource_category == 'basic-solid' then
|
||||
resource.amount = 3700 + math_random(1300)
|
||||
resource.amount = this.ore_base_quantity * 300 + math_random(400, 1700)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -493,4 +493,15 @@ function Terrain.clear_area(args)
|
||||
end
|
||||
end
|
||||
|
||||
function Terrain.prepare_next_surface()
|
||||
Public.get().lobby_enabled = true
|
||||
game.print({'frontier.map_setup'})
|
||||
|
||||
local surface = Public.surface()
|
||||
surface.clear(true)
|
||||
local mgs = table.deepcopy(surface.map_gen_settings)
|
||||
mgs.seed = mgs.seed + 1e4
|
||||
surface.map_gen_settings = mgs
|
||||
end
|
||||
|
||||
return Terrain
|
||||
|
@ -11,6 +11,7 @@ local Public = require 'map_gen.maps.frontier.shared.core'
|
||||
local Enemy = require 'map_gen.maps.frontier.modules.enemy'
|
||||
local Lobby = require 'map_gen.maps.frontier.modules.lobby'
|
||||
local Market = require 'map_gen.maps.frontier.modules.market'
|
||||
local Restart = require 'map_gen.maps.frontier.modules.restart'
|
||||
local RocketSilo = require 'map_gen.maps.frontier.modules.rocket_silo'
|
||||
local SpawnShop = require 'map_gen.maps.frontier.modules.spawn_shop'
|
||||
local Terrain = require 'map_gen.maps.frontier.modules.terrain'
|
||||
@ -119,6 +120,8 @@ Event.add(defines.events.on_tick, on_tick)
|
||||
|
||||
local function on_game_started()
|
||||
Public.reset()
|
||||
Restart.announce_new_map()
|
||||
Restart.apply_modifiers()
|
||||
Terrain.reveal_spawn_area()
|
||||
Terrain.queue_reveal_map()
|
||||
RocketSilo.init_silo()
|
||||
@ -130,11 +133,23 @@ end
|
||||
Event.add(Public.events.on_game_started, on_game_started)
|
||||
|
||||
local function on_game_finished()
|
||||
for _, player in pairs(game.players) do
|
||||
SpawnShop.destroy_gui(player)
|
||||
Lobby.teleport_to(player)
|
||||
local this = Public.get()
|
||||
local cmd = this.server_commands
|
||||
|
||||
if cmd.restarting then
|
||||
Restart.print_endgame_statistics()
|
||||
if this.rounds >= 5 then
|
||||
cmd.mode = Public.restart_mode.restart
|
||||
end
|
||||
if cmd.mode ~= Public.restart_mode.none then
|
||||
Terrain.prepare_next_surface()
|
||||
for _, player in pairs(game.players) do
|
||||
SpawnShop.destroy_gui(player)
|
||||
Lobby.teleport_to(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
RocketSilo.on_game_finished()
|
||||
Restart.execute_server_command()
|
||||
end
|
||||
Event.add(Public.events.on_game_finished, on_game_finished)
|
||||
|
||||
|
@ -20,13 +20,27 @@ Public.scores = {
|
||||
shop_funds = { name = 'shop-funds-frontier', tooltip = {'frontier.shop_funds'}, sprite = '[img=item.coin]' },
|
||||
}
|
||||
|
||||
Public.restart_mode = {
|
||||
none = 1,
|
||||
reset = 2,
|
||||
restart = 3,
|
||||
switch = 4,
|
||||
}
|
||||
|
||||
Public.ESCAPE_PLAYER = false
|
||||
Public.VALUE_7_PACKS = 451
|
||||
Public.PROD_PENALTY = 1.2 * 1.4^5
|
||||
|
||||
local this = {
|
||||
rounds = 0,
|
||||
|
||||
server_commands = {
|
||||
restarting = false,
|
||||
mode = Public.restart_mode.reset,
|
||||
switch_map = {
|
||||
name = nil,
|
||||
mod_pack = nil,
|
||||
}
|
||||
},
|
||||
-- Map gen
|
||||
chart_queue = Queue.new(),
|
||||
height = 36, -- in chunks, height of the ribbon world
|
||||
@ -57,6 +71,7 @@ local this = {
|
||||
scenario_finished = false,
|
||||
|
||||
-- Enemy data
|
||||
spawn_enemy_outpost = false,
|
||||
spawn_enemy_wave = false,
|
||||
invincible = {},
|
||||
target_entities = {},
|
||||
|
@ -10,6 +10,7 @@ return {
|
||||
danger_ores = 'danger-ores',
|
||||
crash_site = 'crash-site',
|
||||
events = 'events',
|
||||
frontier = 'frontier',
|
||||
},
|
||||
--- The strings that mention the discord role.
|
||||
-- Has to be used with features.server.to_discord_raw variants else the mention is sanitized server side.
|
||||
@ -20,5 +21,6 @@ return {
|
||||
moderator = '<@&454192594633883658>',
|
||||
diggy = '<@&921476458076061718>',
|
||||
map_update = '<@486532533220147203>',
|
||||
frontier = '<@1274494225953591370>',
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user