1
0
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:
RedRafe 2024-09-13 18:05:47 +02:00 committed by GitHub
parent 4b040d1048
commit 5152d642ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 652 additions and 65 deletions

View File

@ -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

View File

@ -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 })

View File

@ -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

View File

@ -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'..

View File

@ -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

View File

@ -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)

View 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

View File

@ -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

View File

@ -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})

View File

@ -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

View File

@ -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)

View File

@ -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 = {},

View File

@ -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>',
}
}