void _OnHostPressed() { //Create peer this.peer = new NetworkedMultiplayerENet(); this.peer.CompressionMode = NetworkedMultiplayerENet.CompressionModeEnum.RangeCoder; Error error = this.peer.CreateServer(PORT, 8); if (error != Error.Ok) { this.ShowError("Error: Unable to host server\nPerhaps there is alreay a server open?"); return; } this.p1Id = 1; this.p2Id = 0; GetTree().NetworkPeer = this.peer; Lobby.state = GameState.CHAR_SELECTION; //Hosts should start out as a spectator Lobby.role = MultiplayerRole.P1; Lobby.highLatency = false; this.Visible = false; //Goto CS as spectator CharSelection cs = (ResourceLoader.Load("res://scenes/ui/char_selection/char_selection.tscn") as PackedScene) .Instance() as CharSelection; GetTree().Root.AddChild(cs); //Set the character selection up for multiplayer, with this as a spectator cs.SetMp(); cs.SetCallback(this._MpCSCallback); cs.PlayersUpdated(true, false); //Get the player connected sprites set correctly }
//Multiplayer character selection callback, stores the selected characters and moves on to map selection LevelSelection _MpCSCallback(CharSelection cs, PackedScene p1, PackedScene p2) { //Disable all new connections this.peer.RefuseNewConnections = true; LevelSelection ls = this._LocalCSCallback(cs, p1, p2); ls.SetMp(Lobby.role); return(ls); }
//Host a regular, local game void _OnLocalPressed() { Lobby.role = MultiplayerRole.OFFLINE; Lobby.state = GameState.CHAR_SELECTION; this.p1Id = 0; this.p2Id = 0; //Move to char selection this.Visible = false; CharSelection cs = (ResourceLoader.Load("res://scenes/ui/char_selection/char_selection.tscn") as PackedScene) .Instance() as CharSelection; cs.SetCallback(this._LocalCSCallback); GetTree().Root.AddChild(cs); }
//Called when a player connects (duh) void _PlayerConnected(int id) { GD.Print(id.ToString() + " connected!"); //Don't let the server get in here (I don't think it can anyway tbf) if (id == 1) { return; } if (Lobby.IsHost) { //If p1 or p2 change, push changes to all clients if (this.p1Id == 0) { this.p1Id = id; Rpc(nameof(this.ResetToLobby), new object[] { this.p1Id, this.p2Id, highLatency }); } else if (this.p2Id == 0) { this.p2Id = id; Rpc(nameof(this.ResetToLobby), new object[] { this.p1Id, this.p2Id, highLatency }); } else { //Otherwise just current ids to new player RpcId(id, nameof(this.SetupClient), new object[] { this.p1Id, this.p2Id, highLatency }); //Also send through any character selection choices that have been made CharSelection cs = GetTree().Root.GetNode <CharSelection>("char_selection"); if (cs.p1.mpConfirmed) { cs.RpcId(id, nameof(cs.Confirm), new object[] { Lobby.MultiplayerRole.P1, cs.p1.selection }); } if (cs.p2.mpConfirmed) { cs.RpcId(id, nameof(cs.Confirm), new object[] { Lobby.MultiplayerRole.P2, cs.p2.selection }); } } } this.ResetSpectators(); }
//Local character selection callback, stores the selected characters and moves on to level selection //Returns the new level selection LevelSelection _LocalCSCallback(CharSelection cs, PackedScene p1, PackedScene p2) { //Removes the charselection GetTree().Root.RemoveChild(cs); //Stores player choices this.p1Scene = p1; this.p2Scene = p2; //Moves to level selection LevelSelection ls = (ResourceLoader.Load("res://scenes/ui/level_selection.tscn") as PackedScene).Instance() as LevelSelection; ls.SetCallback(this._LSCallback); GetTree().Root.AddChild(ls); Lobby.state = GameState.LEVEL_SELECTION; return(ls); }
/* * Which of these is called when? * If a player has changed -> Call SetPlayerId(...) on all clients * If a player hasn't changed -> Call SetupClient on just the new spectator */ //Called whenever the game has to be setup //This is called internally when the players have changed //Or by the server if you join late as a spectator private void SetupClient(int p1Id, int p2Id, bool highLatency) { //Set the role correctly if (p1Id == GetTree().GetNetworkUniqueId()) { Lobby.role = MultiplayerRole.P1; } else if (p2Id == GetTree().GetNetworkUniqueId()) { Lobby.role = MultiplayerRole.P2; } else { Lobby.role = MultiplayerRole.SPECTATOR; } Lobby.highLatency = highLatency; //Set the player ids this.p1Id = p1Id; this.p2Id = p2Id; //It doesn't matter what state you were in, once this is called you're in char selections Lobby.state = GameState.CHAR_SELECTION; //Case reseting lobby CharSelection cs = (ResourceLoader.Load("res://scenes/ui/char_selection/char_selection.tscn") as PackedScene) .Instance() as CharSelection; GetTree().Root.AddChild(cs); //Set the character selection up for multiplayer, with this as a spectator cs.SetMp(); cs.SetCallback(this._MpCSCallback); cs.PlayersUpdated(p1Id != 0, p2Id != 0); this.ResetSpectators(); }