1
0
mirror of https://github.com/Refactorio/RedMew.git synced 2024-12-14 10:13:13 +02:00
RedMew/map_gen/maps/space_race/lobby.lua
2019-10-11 21:07:16 +02:00

465 lines
14 KiB
Lua

local Event = require 'utils.event'
local Token = require 'utils.token'
local Task = require 'utils.task'
local Gui = require 'utils.gui'
local b = require 'map_gen.shared.builders'
local snake_game = require 'features.snake.game'
local floor = math.floor
local Public = {}
--Lobby Map
local Generate = require 'map_gen.shared.generate'
local shape = b.rectangle(45, 4)
shape = b.change_tile(shape, true, 'concrete')
Generate.get_surfaces()['snake'] = shape
local delay_snake_checker
local players_needed = 4
local size = 45
local snake_generate =
Token.register(
function()
local surface = game.get_surface('snake')
if surface.get_tile({100, -50}).name == 'out-of-map' and surface.get_tile({100, 50}).name == 'out-of-map' then
local position = {x = -floor(size), y = 5}
local max_food = 8
local speed = 30
snake_game.start_game(surface, position, size, speed, max_food)
else
Task.set_timeout_in_ticks(5, delay_snake_checker)
end
end
)
local check_map_gen_is_done
check_map_gen_is_done =
Token.register(
function()
if not snake_game.is_running() then
local surface = game.get_surface('snake')
if surface.get_tile({100, -50}).name == 'out-of-map' and surface.get_tile({100, 50}).name == 'out-of-map' then
Event.remove_removable_nth_tick(60, check_map_gen_is_done)
Token.get(snake_generate)()
Public.update_gui()
return
end
else
Event.remove_removable_nth_tick(60, check_map_gen_is_done)
Public.update_gui()
end
end
)
delay_snake_checker =
Token.register(
function()
Event.add_removable_nth_tick(60, check_map_gen_is_done)
end
)
Event.on_init(
function()
local snake_surface = game.create_surface('snake')
game.forces.player.set_spawn_position({x = 0, y = 0}, snake_surface)
local y = 128
local x = 128
game.forces.player.chart(snake_surface, {lefttop = {x = -x, y = -y}, rightbottom = {x = x, y = y}})
Task.set_timeout_in_ticks(60 * 3, delay_snake_checker)
end
)
-- <Waiting GUI start>
local waiting_close_name = Gui.uid_name()
local function show_waiting_gui(event)
local frame
local player = game.get_player(event.player_index)
local center = player.gui.center
local gui = center['Space-Race-Lobby']
if (gui) then
Gui.destroy(gui)
end
local snake_button_text
if snake_game.is_running() then
snake_button_text = 'Play Snake'
else
snake_button_text = '... Loading Snake ...'
end
frame = player.gui.center.add {name = 'Space-Race-Lobby', type = 'frame', direction = 'vertical', style = 'captionless_frame'}
frame.style.minimal_width = 300
--Header
local top_flow = frame.add {type = 'flow', direction = 'horizontal'}
top_flow.style.horizontal_align = 'center'
top_flow.style.horizontally_stretchable = true
local title_flow = top_flow.add {type = 'flow'}
title_flow.style.horizontal_align = 'center'
title_flow.style.top_padding = 8
title_flow.style.horizontally_stretchable = false
local title = title_flow.add {type = 'label', caption = 'Welcome to Space Race'}
title.style.font = 'default-large-bold'
--Body
local content_flow = frame.add {type = 'flow', direction = 'horizontal'}
content_flow.style.top_padding = 8
content_flow.style.bottom_padding = 16
content_flow.style.left_padding = 24
content_flow.style.right_padding = 24
content_flow.style.horizontal_align = 'center'
content_flow.style.horizontally_stretchable = true
local label_flow = content_flow.add {type = 'flow'}
label_flow.style.horizontal_align = 'center'
label_flow.style.horizontally_stretchable = true
local label = label_flow.add {type = 'label', caption = #game.connected_players .. ' out of ' .. players_needed .. ' players needed to begin!'}
label.style.horizontal_align = 'center'
label.style.single_line = false
label.style.font = 'default'
--Footer
local ok_button_flow = frame.add {type = 'flow'}
ok_button_flow.style.horizontally_stretchable = true
ok_button_flow.style.horizontal_align = 'center'
local ok_button = ok_button_flow.add {type = 'button', name = waiting_close_name, caption = snake_button_text}
Gui.set_data(ok_button, frame)
end
Gui.on_click(
waiting_close_name,
function(event)
if snake_game.is_running() then
local frame = Gui.get_data(event.element)
local player = event.player
game.permissions.get_group('lobby').remove_player(player)
snake_game.new_snake(player)
Gui.remove_data_recursively(frame)
frame.destroy()
end
end
)
-- <Waiting GUI end>
-- <Join GUI start>
local join_USA = Gui.uid_name()
local join_USSR = Gui.uid_name()
local function show_join_gui(event)
local frame
local player = game.get_player(event.player_index)
local center = player.gui.center
local gui = center['Space-Race-Lobby']
if (gui) then
Gui.destroy(gui)
end
frame = player.gui.center.add {name = 'Space-Race-Lobby', type = 'frame', direction = 'vertical', style = 'captionless_frame'}
frame.style.minimal_width = 300
--Header
local top_flow = frame.add {type = 'flow', direction = 'horizontal'}
top_flow.style.horizontal_align = 'center'
top_flow.style.horizontally_stretchable = true
local title_flow = top_flow.add {type = 'flow'}
title_flow.style.horizontal_align = 'center'
title_flow.style.top_padding = 8
title_flow.style.horizontally_stretchable = false
local title = title_flow.add {type = 'label', caption = 'Welcome to Space Race'}
title.style.font = 'default-large-bold'
--Body
local content_flow = frame.add {type = 'flow', direction = 'horizontal'}
content_flow.style.top_padding = 8
content_flow.style.bottom_padding = 16
content_flow.style.left_padding = 24
content_flow.style.right_padding = 24
content_flow.style.horizontal_align = 'center'
content_flow.style.horizontally_stretchable = true
local label_flow = content_flow.add {type = 'flow'}
label_flow.style.horizontal_align = 'center'
label_flow.style.horizontally_stretchable = true
local label = label_flow.add {type = 'label', caption = 'Feel free to pick a side!'}
label.style.horizontal_align = 'center'
label.style.single_line = false
label.style.font = 'default'
--Footer
local button_flow = frame.add {type = 'flow'}
button_flow.style.horizontal_align = 'center'
button_flow.style.horizontally_stretchable = true
local usa_button_flow = button_flow.add {type = 'flow', direction = 'vertical'}
usa_button_flow.style.horizontally_stretchable = true
usa_button_flow.style.horizontal_align = 'center'
local ussr_button_flow = button_flow.add {type = 'flow', direction = 'vertical'}
ussr_button_flow.style.horizontally_stretchable = true
ussr_button_flow.style.horizontal_align = 'center'
local teams = remote.call('space-race', 'get_teams')
local force_USSR = teams[2]
local force_USA = teams[1]
local usa_players = #force_USA.players
local ussr_players = #force_USSR.players
local usa_connected = #force_USA.connected_players
local ussr_connected = #force_USSR.connected_players
label = usa_button_flow.add {type = 'label', caption = usa_connected .. ' online / ' .. usa_players .. ' total'}
label.style.horizontal_align = 'center'
label.style.single_line = false
label.style.font = 'default'
local join_usa_button = usa_button_flow.add {type = 'button', name = join_USA, caption = 'Join United Factory Workers'}
label = ussr_button_flow.add {type = 'label', caption = ussr_connected .. ' online / ' .. ussr_players .. ' total'}
label.style.horizontal_align = 'center'
label.style.single_line = false
label.style.font = 'default'
local join_ussr_button = ussr_button_flow.add {type = 'button', name = join_USSR, caption = 'Join Union of Factory Employees'}
Gui.set_data(join_usa_button, frame)
Gui.set_data(join_ussr_button, frame)
end
Gui.on_click(
join_USA,
function(event)
local frame = Gui.get_data(event.element)
local player = event.player
if remote.call('space-race', 'join_usa', nil, player) then
Gui.remove_data_recursively(frame)
frame.destroy()
Public.update_gui()
end
end
)
Gui.on_click(
join_USSR,
function(event)
local frame = Gui.get_data(event.element)
local player = event.player
if remote.call('space-race', 'join_ussr', nil, player) then
Gui.remove_data_recursively(frame)
frame.destroy()
Public.update_gui()
end
end
)
-- <Join GUI end>
-- <Won GUI start>
local won_close_name = Gui.uid_name()
local function show_won_gui(event, force)
local frame
local player = game.get_player(event.player_index)
local center = player.gui.center
local gui = center['Space-Race-Lobby']
if (gui) then
Gui.destroy(gui)
end
local snake_button_text
if snake_game.is_running() then
snake_button_text = 'Play Snake'
else
snake_button_text = '... Loading Snake ...'
end
frame = player.gui.center.add {name = 'Space-Race-Lobby', type = 'frame', direction = 'vertical', style = 'captionless_frame'}
frame.style.minimal_width = 300
--Header
local top_flow = frame.add {type = 'flow', direction = 'horizontal'}
top_flow.style.horizontal_align = 'center'
top_flow.style.horizontally_stretchable = true
local title_flow = top_flow.add {type = 'flow'}
title_flow.style.horizontal_align = 'center'
title_flow.style.top_padding = 8
title_flow.style.horizontally_stretchable = false
local title = title_flow.add {type = 'label', caption = 'Welcome to Space Race'}
title.style.font = 'default-large-bold'
--Body
local content_flow = frame.add {type = 'flow', direction = 'horizontal'}
content_flow.style.top_padding = 8
content_flow.style.bottom_padding = 16
content_flow.style.left_padding = 24
content_flow.style.right_padding = 24
content_flow.style.horizontal_align = 'center'
content_flow.style.horizontally_stretchable = true
local label_flow = content_flow.add {type = 'flow'}
label_flow.style.horizontal_align = 'center'
label_flow.style.horizontally_stretchable = true
local label = label_flow.add {type = 'label', caption = force.name .. ' have won the game!\nWaiting for map restart\n\nPlay some snake while we wait!'}
label.style.horizontal_align = 'center'
label.style.single_line = false
label.style.font = 'default'
--Footer
local ok_button_flow = frame.add {type = 'flow'}
ok_button_flow.style.horizontally_stretchable = true
ok_button_flow.style.horizontal_align = 'center'
local ok_button = ok_button_flow.add {type = 'button', name = won_close_name, caption = snake_button_text}
Gui.set_data(ok_button, frame)
end
Gui.on_click(
won_close_name,
function(event)
if snake_game.is_running() then
local frame = Gui.get_data(event.element)
local player = event.player
game.permissions.get_group('lobby').remove_player(player)
snake_game.new_snake(player)
Gui.remove_data_recursively(frame)
frame.destroy()
end
end
)
-- <Won GUI end>
function Public.show_gui(event)
if #game.connected_players < players_needed and (not remote.call('space-race', 'get_game_status')) then
if not snake_game.is_running() and game.tick > 60 * 55 then
Token.get(snake_generate)()
end
game.forces.enemy.evolution_factor = 0
show_waiting_gui(event)
return
end
local won = remote.call('space-race', 'get_won')
if won then
show_won_gui(event, won)
else
if snake_game.is_running() then
snake_game.end_game()
end
show_join_gui(event)
end
end
function Public.update_gui()
local players = game.connected_players
for i = 1, #players do
local player = players[i]
local center = player.gui.center
local gui = center['Space-Race-Lobby']
if (gui) then
Public.show_gui({player_index = player.index})
end
end
end
local function on_snake_player_died(event)
local player = event.player
game.permissions.get_group('lobby').add_player(player)
Public.show_gui({player_index = player.index})
player.teleport({0, 0}, game.get_surface('snake'))
end
local function to_lobby(player_index)
local player = game.get_player(player_index)
player.teleport({0, 0}, game.get_surface('snake'))
game.permissions.get_group('lobby').add_player(player)
local character = player.character
if character and character.valid then
player.character.destroy()
end
player.set_controller {type = defines.controllers.ghost}
Public.show_gui({player_index = player.index})
end
local function on_player_created(event)
to_lobby(event.player_index)
end
local function on_player_joined(event)
local won = remote.call('space-race', 'get_won')
if won then
to_lobby(event.player_index)
end
Public.update_gui()
end
local delay_to_lobby =
Token.register(
function()
local teams = remote.call('space-race', 'get_teams')
game.remove_offline_players()
for i = 1, #teams do
for _, player in pairs(teams[i].connected_players) do
player.force = game.forces.player
to_lobby(player.index)
end
end
end
)
local function on_player_left()
if #game.connected_players < players_needed and (not remote.call('space-race', 'get_game_status')) then
Task.set_timeout_in_ticks(1, delay_to_lobby) -- Other on_player_left_game events would error if we removed offline players instantly
end
Public.update_gui()
end
Event.add(snake_game.events.on_snake_player_died, on_snake_player_died)
Event.add(defines.events.on_player_created, on_player_created)
Event.add(defines.events.on_player_joined_game, on_player_joined)
Event.add(defines.events.on_player_left_game, on_player_left)
function Public.all_to_lobby()
local players = game.connected_players
for i = 1, #players do
to_lobby(players[i].index)
end
Task.set_timeout_in_ticks(5, snake_generate)
end
function Public.to_lobby(player_index)
to_lobby(player_index)
end
return Public