extends Control class_name Main @onready var start_btn : Button = $Mainmenu/Menu/MarginContainer/VBoxContainer/HBoxContainer4/VBoxContainer3/Start @onready var disconnect_btn : Button = $Pausemenu/Menu/MarginContainer/VBoxCurrentLobby/Disconnect @onready var name_edit : = $Mainmenu/Menu/MarginContainer/VBoxContainer/HBoxContainer4/VBoxContainer2/NameEdit @onready var disconnectDialog = $Dialogs/DisconnectDialog @onready var pausemenu: Control = $Pausemenu @onready var settingsmenu: Control = $Settingsmenu @onready var mainmenu: Control = $Mainmenu @onready var hud: Control = $Hud @onready var mapScreen: MapScreen = $MapScreen @onready var missionEndScreen: MissionEndScreen = $MissionEndScreen @onready var loadingScreen: Control = $LoadingScreen @onready var mapsParent: Node3D = $Maps @onready var playersParent: Node3D = $Players var peer = WebSocketMultiplayerPeer.new() var lobby: String = "res://Maps/Lobby/Lobby.tscn" var player: PackedScene = preload("res://actors/Player/player_character.tscn") @onready var currentMenu: Control = $Mainmenu var settingsPressed: bool = false #Flag for when Settings button is pressed, handled in process by Menu handeling function var displayMissionEndScreen: bool = false #Display Mission end screen while true var displayLoadingScreen: bool = false func _init(): peer.supported_protocols = ["ludus"] Steamworks.initialize() func _ready(): await Multiplayer.noray_connected multiplayer.peer_connected.connect(peer_connected) multiplayer.peer_disconnected.connect(peer_disconnected) multiplayer.server_disconnected.connect(close_network) multiplayer.connection_failed.connect(close_network) multiplayer.connected_to_server.connect(connected) # Set the player name according to the system username. Fallback to the path. if Steamworks.is_initiallized: get_tree().auto_accept_quit = false Steamworks.create_lobby() name_edit.text = Steam.getPersonaName() elif false: #TODO: Set text to saved value name_edit.text = "" disableMultiplayer() else: name_edit.text = "Spacebots Player" disableMultiplayer() func _process(_delta: float): #Does all switching between Menus handleMenus() func changeMenu(changeTo: Control) -> void: if currentMenu == changeTo: return var thisPlayer := Multiplayer.thisPlayer if thisPlayer: if changeTo == hud or changeTo == missionEndScreen: thisPlayer.currentControlState = thisPlayer.controls.DEFAULT else: thisPlayer.currentControlState = thisPlayer.controls.STANDARD_MINIGAME currentMenu.hide() changeTo.show() changeTo.grab_focus.call_deferred() currentMenu = changeTo func handleMenus() -> void: #This function returns after an Input is handled, ensuring one menu action per frame and avoiding conflicts if !playersParent.get_child_count() > 0: return #Flags for which Inputs are pressed var pausePressed: bool = Input.is_action_just_pressed("pause") var leaveMinigamePressed: bool = Input.is_action_just_pressed("leaveMinigame") var mapPressed: bool = Input.is_action_just_pressed("map") if displayLoadingScreen: if currentMenu != loadingScreen: changeMenu(loadingScreen) return if displayMissionEndScreen: if currentMenu != missionEndScreen: changeMenu(missionEndScreen) return if mapPressed: if Minigames.minigameActive: Minigames.endMinigame(false) if currentMenu != mapScreen: changeMenu(mapScreen) else: changeMenu(hud) return if (leaveMinigamePressed or pausePressed) and Minigames.minigameActive: Minigames.endMinigame(false) return if settingsPressed: if currentMenu != settingsmenu: changeMenu(settingsmenu) else: changeMenu(pausemenu) settingsPressed = false return if pausePressed: if currentMenu == hud: changeMenu(pausemenu) else: changeMenu(hud) return func disableMultiplayer() -> void: $/root/Main/Mainmenu/Menu/MarginContainer/VBoxContainer/HBoxContainer/VBoxMultiplayerDisabled.show() $/root/Main/Mainmenu/Menu/MarginContainer/VBoxContainer/HBoxContainer/VBoxLobbylist.hide() func start_game(): Input.mouse_mode = Input.MOUSE_MODE_CAPTURED mainmenu.hide() start_btn.disabled = true disconnect_btn.disabled = false hud.show() @rpc("authority","call_local","reliable") func changeMap(newMap: String, mapSeed: int = 0) -> void: if !(load(newMap).instantiate() is MapLogic): push_error("newMap: String is not a map scene") return var map : MapLogic = load(newMap).instantiate() if newMap == "res://test/spaceship_test.tscn": map.setSeed(hash(mapSeed)) if mapsParent.get_child_count() > 0: if Multiplayer.getCurrentMapLogic().is_connected(StringName("missionLost"),missionLost): Multiplayer.getCurrentMapLogic().disconnect(StringName("missionLost"),missionLost) mapsParent.get_child(0).queue_free() mapsParent.add_child(map) initiatePlayerPosition(map.playerStartPos) Multiplayer.setCurrentMapLogic(map) map.missionLost.connect(missionLost) func initiatePlayerPosition(pos: Vector3) -> void: for p in Multiplayer.playerDict.values(): if p.is_multiplayer_authority(): p.global_position = pos func missionLost() -> void: changeMap(lobby) func stop_game(): disconnect_btn.disabled = true mainmenu.show() pausemenu.hide() hud.hide() Input.mouse_mode = Input.MOUSE_MODE_CONFINED #Steamworks.stop() var currentMaps = mapsParent.get_children() for child in currentMaps: child.queue_free() var players = playersParent.get_children() for child in players: child.set_process(false) child.queue_free() await get_tree().process_frame start_btn.disabled = false func close_network(): peer.close() stop_game() disconnectDialog.popup_centered() disconnectDialog.get_ok_button().grab_focus() multiplayer.multiplayer_peer = null Multiplayer.currentMapLogic = null Multiplayer.playerDict = {} Multiplayer.alivePlayerDict = {} Multiplayer.is_host = false Steamworks.lobby_id = 0 Steamworks.lobby_members = [] Steamworks.lobby_members_max = 5 Steamworks.steam_id = 0 Steamworks.steam_username = "" func connected(): if Multiplayer.is_host == false: add_player.rpc_id(1, multiplayer.get_unique_id()) func peer_connected(_id): pass #Steamworks.on_peer_add(id) func peer_disconnected(id): if Multiplayer.is_host: remove_player(id) func on_server_disconnected(): on_Disconnect_pressed() func on_Start_pressed(): Multiplayer.host() start_game() changeMap(lobby) changeMenu(hud) add_player(multiplayer.get_unique_id()) func on_Disconnect_pressed(): if Steamworks.lobby_members.size() > 1: Steam.leaveLobby(Steamworks.lobby_id) close_network() func on_settings_pressed(): settingsPressed = true func on_Connect(norayid: String): start_btn.disabled = true disconnect_btn.disabled = false start_game() changeMap(lobby) Multiplayer.join(norayid) @rpc("any_peer") func add_player(id): var player_instance: PlayerCharacter = player.instantiate() player_instance.name = str(id) playersParent.add_child(player_instance) @rpc("any_peer") func remove_player(id): if playersParent.get_node(str(id)): playersParent.get_node(str(id)).queue_free()