Skip to content

Commit

Permalink
Add multiplayer menu
Browse files Browse the repository at this point in the history
  • Loading branch information
Nemrav committed Jan 15, 2025
1 parent da6c155 commit 7e496f9
Show file tree
Hide file tree
Showing 21 changed files with 906 additions and 7 deletions.
42 changes: 42 additions & 0 deletions game/assets/localisation/locales/en_GB/menus.csv
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,48 @@ OPTIONS_SOUND_EXPLODE_EARS;Explode Eardrums on Startup?
OPTIONS_CONTROLS;Controls
OPTIONS_OTHER;Other

;; Multiplayer Menu
MP_BACK;X
MP_SERVERBROWSER;Online
MP_LANBROWSER;LAN
MP_DIRECT_CONNECTION;Direct Connection
MP_HOST;Host

;; Server Browser Tab

;; LAN Tab

;; Direct Connection Tab
MP_USERNAME_ENTRY;Username

MP_DIRECT_NAME_ENTRY;Connection Name
MP_DIRECT_IP_ENTRY;Connection IP
MP_DIRECT_ADD_IP;Add IP
MP_DIRECT_SAVE_IPS;Save IPs
MP_DIRECT_REVERT_IPS; Revert IPs

MP_DIRECT_SAVED_IPS;Saved IPs
MP_DIRECT_CONNECT;Connect
MP_DIRECT_EDIT;Edit
MP_DIRECT_DELETE;X

;; Connection
MP_CONNECT_PASSWORD_ENTRY;Password
MP_CONNECT_PASSWORD_CANCEL; Cancel
MP_CONNECT_PASSWORD_OK;Connect

MP_CONNECT_FAIL;Connection Failed
MP_CONNECT_FAIL_OK; Ok
MP_CONNECT_FAIL_REASON;Reason:
MP_CONNECT_FAIL_PASSWORD;Incorrect Password
MP_CONNECT_FAIL_NO_SERVER;Could not Find the specified Server
MP_CONNECT_FAIL_BAD_IP; Invalid IP

;; Host Tab
MP_HOST_GAME_NAME_ENTRY;Game Name
MP_HOST_HOST;Host
MP_HOST_IS_LAN_ONLY;LAN Connections only

;; Credits Menu
CREDITS_BACK;Back to Main Menu

Expand Down
1 change: 1 addition & 0 deletions game/project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ limits/message_queue/max_size_kb=16384
settings/settings_file_path="user://settings.cfg"
data/saves_directory="user://saves"
project_file_req_comment.editor="FS-2, FS-20, FS-21, FS-22"
settings/ips_file_path="user://ips.cfg"

[rendering]

Expand Down
2 changes: 2 additions & 0 deletions game/src/Game/Autoload/Events.gd
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
extends Node

var Options : OptionsEventsObject
var Multiplayer : MultiplayerEventsObject
var NationManagementScreens : NationManagementScreensEventsObject

func _init() -> void:
Options = OptionsEventsObject.new()
NationManagementScreens = NationManagementScreensEventsObject.new()
Multiplayer = MultiplayerEventsObject.new()
64 changes: 64 additions & 0 deletions game/src/Game/Autoload/Events/Multiplayer.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
class_name MultiplayerEventsObject
extends RefCounted

signal save_ips(save_file: ConfigFile)
signal load_ips(load_file: ConfigFile)

const ips_file_path_setting : String = "openvic/settings/ips_file_path"
const ips_file_path_default : String = "user://ips.cfg"

var _saved_ips_file_path : String = ProjectSettings.get_setting(ips_file_path_setting, ips_file_path_default)
var _saved_ips_file := ConfigFile.new()

var config_file_loaded : bool = false

const USER : StringName = &"USER"
const SERVER_NAMES : StringName = &"SERVER_NAMES"
const SERVER_IPS : StringName = &"SERVER_IPS"
const PLAYER_NAME : StringName = &"player_name"
const HOST_GAME_NAME : StringName = &"host_game_name"
const HOST_GAME_PASSWORD : StringName = &"host_game_password"

const DEFAULT_PLAYER_NAME : StringName = &"Player1"
const DEFAULT_GAME_NAME : StringName = &"Player1's Game"
const DEFAULT_GAME_PASSWORD : StringName = &""

func get_override_path() -> String:
var override_path : String = ProjectSettings.get_setting("application/config/project_settings_override", "")
if override_path.is_empty():
override_path = _saved_ips_file_path
return override_path

func get_ips_config_file() -> ConfigFile:
if config_file_loaded:
return _saved_ips_file
else:
return load_ips_config_file()

func load_ips_config_file() -> ConfigFile:
var override_path := get_override_path()
if FileAccess.file_exists(override_path):
if _saved_ips_file.load(override_path) != OK:
push_error("Failed to load overrides from %s" % override_path)
else:
if !_saved_ips_file.has_section_key(USER,PLAYER_NAME):
_saved_ips_file.set_value(USER,PLAYER_NAME,DEFAULT_PLAYER_NAME)
if !_saved_ips_file.has_section_key(USER,HOST_GAME_NAME):
_saved_ips_file.set_value(USER,HOST_GAME_NAME,DEFAULT_GAME_NAME)
if !_saved_ips_file.has_section_key(USER,HOST_GAME_PASSWORD):
_saved_ips_file.set_value(USER,HOST_GAME_PASSWORD,DEFAULT_GAME_PASSWORD)
save_ips_config_file()
load_ips.emit(_saved_ips_file)
config_file_loaded = true
return _saved_ips_file

func save_ips_config_file() -> void:
var override_path := get_override_path()
_saved_ips_file.save(_saved_ips_file_path)
if _saved_ips_file.save(override_path) != OK:
push_error("Failed to save ip overrides to %s" % override_path)
else:
save_ips.emit(_saved_ips_file)

func _init() -> void:
load_ips_config_file()
11 changes: 11 additions & 0 deletions game/src/Game/GameMenu.gd
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ extends Control

@export var _main_menu : Control
@export var _options_menu : Control
@export var _multiplayer_menu : Control
@export var _lobby_menu : Control
@export var _credits_menu : Control

Expand Down Expand Up @@ -40,3 +41,13 @@ func _on_credits_back_button_pressed() -> void:
func _on_main_menu_credits_button_pressed() -> void:
_credits_menu.show()
_main_menu.hide()


func _on_multiplayer_menu_back_button_pressed() -> void:
_multiplayer_menu.hide()
_main_menu.show()


func _on_main_menu_multiplayer_button_pressed() -> void:
_multiplayer_menu.show()
_main_menu.hide()
12 changes: 10 additions & 2 deletions game/src/Game/GameMenu.tscn
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
[gd_scene load_steps=7 format=3 uid="uid://o4u142w4qkln"]
[gd_scene load_steps=8 format=3 uid="uid://o4u142w4qkln"]

[ext_resource type="Script" path="res://src/Game/GameMenu.gd" id="1_cafwe"]
[ext_resource type="PackedScene" uid="uid://bp5n3mlu45ygw" path="res://src/Game/Menu/MainMenu/MainMenu.tscn" id="2_2jbkh"]
[ext_resource type="PackedScene" uid="uid://cnbfxjy1m6wja" path="res://src/Game/Menu/OptionMenu/OptionsMenu.tscn" id="3_111lv"]
[ext_resource type="PackedScene" uid="uid://c8knthxkwj1uj" path="res://src/Game/Menu/CreditsMenu/CreditsMenu.tscn" id="4_n0hoo"]
[ext_resource type="PackedScene" uid="uid://do60kx0d3nrh4" path="res://src/Game/Menu/LobbyMenu/LobbyMenu.tscn" id="4_nofk1"]
[ext_resource type="PackedScene" uid="uid://btri1i0hkhdsh" path="res://src/Game/Menu/MultiplayerMenu/MultiplayerMenu.tscn" id="4_s7nkl"]
[ext_resource type="PackedScene" uid="uid://cvl76duuym1wq" path="res://src/Game/MusicConductor/MusicPlayer.tscn" id="6_lts1m"]

[node name="GameMenu" type="Control" node_paths=PackedStringArray("_main_menu", "_options_menu", "_lobby_menu", "_credits_menu")]
[node name="GameMenu" type="Control" node_paths=PackedStringArray("_main_menu", "_options_menu", "_multiplayer_menu", "_lobby_menu", "_credits_menu")]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
Expand All @@ -17,6 +18,7 @@ grow_vertical = 2
script = ExtResource("1_cafwe")
_main_menu = NodePath("MainMenu")
_options_menu = NodePath("OptionsMenu")
_multiplayer_menu = NodePath("MultiplayerMenu")
_lobby_menu = NodePath("LobbyMenu")
_credits_menu = NodePath("CreditsMenu")

Expand All @@ -28,6 +30,10 @@ metadata/_edit_vertical_guides_ = [251.0, 269.0, 504.0, 523.0, 15.0, 759.0, 777.
visible = false
layout_mode = 1

[node name="MultiplayerMenu" parent="." instance=ExtResource("4_s7nkl")]
visible = false
layout_mode = 1

[node name="LobbyMenu" parent="." instance=ExtResource("4_nofk1")]
visible = false
layout_mode = 1
Expand All @@ -46,8 +52,10 @@ offset_right = -34.0
grow_horizontal = 0

[connection signal="credits_button_pressed" from="MainMenu" to="." method="_on_main_menu_credits_button_pressed"]
[connection signal="multiplayer_button_pressed" from="MainMenu" to="." method="_on_main_menu_multiplayer_button_pressed"]
[connection signal="new_game_button_pressed" from="MainMenu" to="." method="_on_main_menu_new_game_button_pressed"]
[connection signal="options_button_pressed" from="MainMenu" to="." method="_on_main_menu_options_button_pressed"]
[connection signal="back_button_pressed" from="OptionsMenu" to="." method="_on_options_menu_back_button_pressed"]
[connection signal="back_button_pressed" from="MultiplayerMenu" to="." method="_on_multiplayer_menu_back_button_pressed"]
[connection signal="back_button_pressed" from="LobbyMenu" to="." method="_on_lobby_menu_back_button_pressed"]
[connection signal="back_button_pressed" from="CreditsMenu" to="." method="_on_credits_back_button_pressed"]
2 changes: 1 addition & 1 deletion game/src/Game/Menu/LobbyMenu/LobbyMenu.gd
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ signal start_date_selected(index : int)

func filter_for_tag(tag : StringName) -> void:
for child : Control in game_select_save_list.get_children():
if tag == &"":
if tag.is_empty():
child.show()
else:
if tag == child.resource.session_tag:
Expand Down
7 changes: 4 additions & 3 deletions game/src/Game/Menu/MainMenu/MainMenu.gd
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ extends Control
signal options_button_pressed
signal new_game_button_pressed
signal credits_button_pressed
signal multiplayer_button_pressed
signal continue_button_pressed

@export
var _new_game_button : BaseButton
Expand All @@ -19,14 +21,13 @@ func _on_new_game_button_pressed() -> void:
print("Start a new game!")
new_game_button_pressed.emit()


func _on_continue_button_pressed() -> void:
print("Continue last game!")

continue_button_pressed.emit()

func _on_multi_player_button_pressed() -> void:
print("Have fun with friends!")

multiplayer_button_pressed.emit()

func _on_options_button_pressed() -> void:
print("Check out some options!")
Expand Down
21 changes: 21 additions & 0 deletions game/src/Game/Menu/MultiplayerMenu/ConnectionFailDialog.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
extends AcceptDialog
class_name ConnectionFailDialog

enum FAIL_REASONS {NO_SERVER, PASSWORD, BAD_IP}

@export var reason_text : String
@export var no_server_fail_text : String
@export var bad_password_fail_text : String
@export var bad_ip_text : String

@onready var reason_text_map : Dictionary = {
FAIL_REASONS.NO_SERVER : no_server_fail_text,
FAIL_REASONS.PASSWORD : bad_password_fail_text,
FAIL_REASONS.BAD_IP : bad_ip_text
}

@export var label : Label

func display(reason : FAIL_REASONS) -> void:
label.text = "%s %s" % [tr(reason_text), tr(reason_text_map[reason])]
popup_centered()
23 changes: 23 additions & 0 deletions game/src/Game/Menu/MultiplayerMenu/DirectConnectionEntry.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
extends HBoxContainer
class_name DirectConnectionEntry

@export var ip_edit : SecretEdit
@export var name_edit : LineEdit
@export var connect_button : Button
@export var delete_button : Button

# Collects connect and delete presses from its children, and emits
# the corresponding signals for the connection controller to handle

signal connect_to_ip(ip : String)
signal delete()

func setup(name_in : StringName, ip : StringName) -> void:
name_edit.text = name_in
ip_edit.set_text(ip)

func _on_connect_pressed() -> void:
connect_to_ip.emit(ip_edit.get_text())

func _on_delete_pressed() -> void:
delete.emit()
50 changes: 50 additions & 0 deletions game/src/Game/Menu/MultiplayerMenu/DirectConnectionEntry.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[gd_scene load_steps=3 format=3 uid="uid://br26w6mwqilyr"]

[ext_resource type="Script" path="res://src/Game/Menu/MultiplayerMenu/DirectConnectionEntry.gd" id="1_8v0qa"]
[ext_resource type="PackedScene" uid="uid://dcsy6w6ow2xxg" path="res://src/Game/Menu/MultiplayerMenu/SecretEdit.tscn" id="2_3yivm"]

[node name="DirectConnectionEntry" type="HBoxContainer" node_paths=PackedStringArray("ip_edit", "name_edit", "connect_button", "delete_button")]
anchors_preset = 10
anchor_right = 1.0
offset_bottom = 31.0
grow_horizontal = 2
script = ExtResource("1_8v0qa")
ip_edit = NodePath("SecretEdit")
name_edit = NodePath("EditName")
connect_button = NodePath("Connect")
delete_button = NodePath("Delete")

[node name="EditName" type="LineEdit" parent="."]
layout_mode = 2
size_flags_horizontal = 3
placeholder_text = "Game1"
max_length = 32
editable = false

[node name="VSeparator" type="VSeparator" parent="."]
layout_mode = 2

[node name="SecretEdit" parent="." instance=ExtResource("2_3yivm")]
layout_mode = 2
size_flags_horizontal = 3
editable = false

[node name="VSeparator2" type="VSeparator" parent="."]
layout_mode = 2

[node name="Connect" type="Button" parent="."]
layout_mode = 2
text = "MP_DIRECT_CONNECT"

[node name="Edit" type="CheckButton" parent="."]
layout_mode = 2
text = "MP_DIRECT_EDIT"

[node name="Delete" type="Button" parent="."]
layout_mode = 2
text = "MP_DIRECT_DELETE"

[connection signal="pressed" from="Connect" to="." method="_on_connect_pressed"]
[connection signal="toggled" from="Edit" to="EditName" method="set_editable"]
[connection signal="toggled" from="Edit" to="SecretEdit" method="set_editable"]
[connection signal="pressed" from="Delete" to="." method="_on_delete_pressed"]
Loading

0 comments on commit 7e496f9

Please sign in to comment.