/// <summary> /// Disconnect from either the lobby or in-game. /// </summary> public void Disconnect(bool isServer, NetworkType nwType, bool isHostTimeout = false) { if (NwMgr.IsRunning) { NwMgr.NetworkHost.Disconnected -= new ConnectionDisconnectedHandler(ClientDisconnectEvent); } this.isServer = isServer; SetNetworkType(nwType); // If in the lobby or in-game, and still connected to host if ((toggle_InLobbyClientLogic || toggle_InLobbyHostLogic) && !isHostTimeout) { // Before sending disconnect signal, ensure another player is present to receive it. if (TrueLobbyState.NumActivePlayers > 1) { LobbyPlayerDisconnectPacket sendPkt = new LobbyPlayerDisconnectPacket(isServer); NwMgr.SendPacket <LobbyPlayerDisconnectPacket>("info", sendPkt); } HostLobby_ToggleLobbyHostLogic(false); JoinLobby_ToggleLobbyClientLogic(false); myIdStatus = PlayerIdStatus.None; } // Empty lobby state. TrueLobbyState = new LobbyStatePacket(true); // Trigger nwMgr.Stop() and this.serverLookup.Cancel() to be called in 2 seconds. nwMgrShutdownCurStatus = nwMgrShutdownStatus.Triggered; }
/// <summary> /// Event when the "Join Role" is pressed for a particular GUI lobby slot. /// </summary> public void OnClick_JoinRole(string teamRole) { TeamRole dTeamRole = (TeamRole)Enum.Parse(typeof(TeamRole), teamRole); LobbySlot myCurSlot = GetMyLobbySlot(); if (myCurSlot != null) { UnoccupyLobbySlot(myCurSlot.teamRole); } // As host, let everyone know about my change. if (mIsHost) { OccupyLobbySlot(dTeamRole, mUsername, mIsHost, true); LobbyStatePacket lobbyState = CopyLobbyStateToPacket(); mLobby.SendNewTrueLobbyState(lobbyState); } // As client, inform server. else { LobbyUpdateFromClientPacket sendPkt = new LobbyUpdateFromClientPacket(); // sendPkt.IsReady = false; sendPkt.IsOccupied = true; sendPkt.TeamRole = dTeamRole; sendPkt.Username = mUsername; mLobby.SendLobbyUpdateFromClient(sendPkt); } }
/// <summary> /// Event when the "Start Game" button is pressed by the server. This will be greyed out on client side, however, /// it will be invoked by Lobby.cs on the client side when it receives the "LobbyStartGamePacket" from the /// server. /// </summary> public void OnClick_StartGame() { LobbySlot mySlot = GetMyLobbySlot(); if (!mIsHost && mySlot == null) { OnClick_Disconnect("Server has already started the game before you could pick your team and role."); return; } // BUG FIX. This must be done before switching menu in order for GUI lobby slots to be queried. if (mIsHost) { // Alert clients that game starts. LobbyStatePacket sendPkt = CopyLobbyStateToPacket(); sendPkt.IsStartGame = true; mLobby.SendNewTrueLobbyState(sendPkt); } // Switch to in-game mode. mEngine.Run(mySlot.teamRole, mLobby.TrueLobbyState); SwitchMenu(mInGameMenu); }
/* Functions invoked by the external lobby logic class (Lobby.cs) */ /// <summary> /// Refresh the GUI lobby slots using the given true lobby state. /// </summary> public void RefreshLobby(LobbyStatePacket lobbyState, PlayerId myId) { RefreshNumActivePlayers(lobbyState.NumActivePlayers); for (int i = 0; i < 4; i++) { if (lobbyState.IsOccupieds[i] == false) { UnoccupyLobbySlot((TeamRole)i); } else { string username = lobbyState.Usernames[i]; bool isHost = lobbyState.IsHosts[i]; bool isYou = (lobbyState.PlayerIds[i] == myId); // bool isReady = lobbyState.IsReadys[i]; OccupyLobbySlot((TeamRole)i, username, isHost, isYou); //, isReady); } } Debug.Log("Lobby refreshed."); mIsLobbyRefreshed = true; // If loading screen because waiting for lobby to refresh, we can hide it now. if (IsLoadingSplash()) { HideLoadingSplash(); } }
/// <summary> /// As a server, /// - Send LobbyReturnPacket to trigger clients to return to the lobby. /// - Send the latest lobby state to the clients for them to refresh their lobby menu. /// - Refresh my own lobby menu. /// /// As a server, you'll need to switch to the lobby menu GUI manually. /// </summary> public void ServerReturnToLobby() { NwMgr.SendPacket <LobbyReturnPacket>("info", new LobbyReturnPacket()); //TrueLobbyState.IsStartGame = false; TrueLobbyState = new LobbyStatePacket(true); // Reset lobby slots. TrueLobbyState.NumActivePlayers = 1 + NwMgr.NetworkHost.ConnectionCount; SendNewTrueLobbyState(TrueLobbyState); Menus.RefreshLobby(TrueLobbyState, myId); }
/// <summary> /// Start the scoreboard to listen for game events (e.g. flag captured). Scores will be reset. If the host, /// this obj will handle synchronizing the server's truth score with the clients. /// </summary> /// /// <param name="playersInfo">Information about the current players</param> /// <param name="nwMgr">Network manager from the game engine</param> /// <param name="isHost">Am I the server?</param> public void Run(LobbyStatePacket playersInfo, NetworkManager nwMgr, bool isHost, TeamRole myTeamRole) { mNwMgr = nwMgr; mIsHost = isHost; mMyTeam = Common.GetTeam(myTeamRole); mMyRole = Common.GetRole(myTeamRole); mPacket = new ScoreboardStatePacket(true); mPacket.PurpleRunner.Username = playersInfo.Usernames[(int)TeamRole.PurpleRunner]; mPacket.PurpleBuilder.Username = playersInfo.Usernames[(int)TeamRole.PurpleBuilder]; mPacket.YellowRunner.Username = playersInfo.Usernames[(int)TeamRole.YellowRunner]; mPacket.YellowBuilder.Username = playersInfo.Usernames[(int)TeamRole.YellowBuilder]; mIsRunning = true; }
/// <summary> /// Copy the current state of my GUI lobby slots into a sendable packet. /// </summary> public LobbyStatePacket CopyLobbyStateToPacket() { LobbyStatePacket pkt = new LobbyStatePacket(true); pkt.NumActivePlayers = mLobby.TrueLobbyState.NumActivePlayers; for (int i = 0; i < 4; i++) { LobbySlot slot = mLobbySlots[i]; pkt.IsOccupieds[i] = slot.isOccupied; pkt.IsHosts[i] = slot.isHost; // pkt.IsReadys[i] = slot.isReadyToggle.isOn; pkt.PlayerIds[i] = mLobby.TrueLobbyState.PlayerIds[i]; pkt.Usernames[i] = slot.username; } return(pkt); }
/// <summary> /// Step 3/3 of hosting a lobby. /// /// This will cause this script to handle the logic involving hosting a lobby like /// broadcasting the true lobby state to clients and receiving updates from clients. /// </summary> public void HostLobby_ToggleLobbyHostLogic(bool isOn) { if (isOn) { Debug.Log(NwMgr.NetworkHost); NwMgr.NetworkHost.Disconnected -= new ConnectionDisconnectedHandler(ClientDisconnectEvent); NwMgr.NetworkHost.Disconnected += new ConnectionDisconnectedHandler(ClientDisconnectEvent); } else { if (NwMgr.NetworkHost != null) { NwMgr.NetworkHost.Disconnected -= new ConnectionDisconnectedHandler(ClientDisconnectEvent); } } this.TrueLobbyState = new LobbyStatePacket(true); this.toggle_InLobbyHostLogic = isOn; }
/// <summary> /// Step 4/4 of joining a lobby. /// /// This will cause this script to handle the logic of being in a lobby such as fetching /// the true lobby state from the server, and sending your lobby changes. /// </summary> public void JoinLobby_ToggleLobbyClientLogic(bool isOn) { this.TrueLobbyState = new LobbyStatePacket(true); this.toggle_InLobbyClientLogic = isOn; if (!isOn) { if (NwMgr.NetworkHost != null) { NwMgr.NetworkHost.Disconnected -= new ConnectionDisconnectedHandler(ClientDisconnectEvent); } this.inLobbyClientLogicCurStatus = inLobbyClientLogicStatus.NotStarted; } else { NwMgr.NetworkHost.Disconnected -= new ConnectionDisconnectedHandler(ClientDisconnectEvent); NwMgr.NetworkHost.Disconnected += new ConnectionDisconnectedHandler(ClientDisconnectEvent); this.inLobbyClientLogicCurStatus = inLobbyClientLogicStatus.DelayingStart; } }
/// <summary> /// Event when the "Leave Role" button is pressed for a particular GUI lobby slot. /// </summary> public void OnClick_LeaveRole(string teamRole) { TeamRole dTeamRole = (TeamRole)Enum.Parse(typeof(TeamRole), teamRole); // Update GUI. UnoccupyLobbySlot(dTeamRole); if (mIsHost) // Inform clients. { LobbyStatePacket lobbyState = CopyLobbyStateToPacket(); mLobby.SendNewTrueLobbyState(lobbyState); } else // Inform server. { LobbyUpdateFromClientPacket sendPkt = new LobbyUpdateFromClientPacket(); // sendPkt.IsReady = false; sendPkt.IsOccupied = false; sendPkt.TeamRole = dTeamRole; sendPkt.Username = mUsername; mLobby.SendLobbyUpdateFromClient(sendPkt); } }
/// <summary> /// As host, update the true lobby state locally and broadcast this new state to every client. /// </summary> /// <param name="newTrueLobbyState">New true lobby state.</param> public void SendNewTrueLobbyState(LobbyStatePacket newTrueLobbyState) { TrueLobbyState = newTrueLobbyState; NwMgr.SendPacket <LobbyStatePacket>("info", TrueLobbyState); }
/// <summary> /// As a client of the lobby, handle any received-packet events from the host of the lobby. /// </summary> protected void InLobbyClientLogic() { // Need to delay a bit before transferring packets. NwMgr needs to establish connection event after calling Run() // before sending packets. if (inLobbyClientLogicCurStatus == inLobbyClientLogicStatus.NotStarted) { inLobbyClientLogicStartDelayFinish = Time.time + inLobbyClientLogicStartDelayTime; inLobbyClientLogicCurStatus = inLobbyClientLogicStatus.DelayingStart; return; } else if (inLobbyClientLogicCurStatus == inLobbyClientLogicStatus.DelayingStart) { if (Time.time > inLobbyClientLogicStartDelayFinish) { inLobbyClientLogicCurStatus = inLobbyClientLogicStatus.Started; } else { return; } } // If just joined the lobby, request a player id. if (myIdStatus == PlayerIdStatus.None) { if (IsDebug) { Debug.Log("InLobbyClientLogic: Requesting a player id."); } NwMgr.SendPacket <LobbyRequestPlayerIdPacket>("info", new LobbyRequestPlayerIdPacket()); myIdStatus = PlayerIdStatus.Requested; } // If received my requested player id. if (NwMgr.PacketQueue.HasPacket <LobbyGivenPlayerIdPacket>()) { LobbyGivenPlayerIdPacket recvPkt = NwMgr.PacketQueue.GetNextPacket <LobbyGivenPlayerIdPacket>(); myId = recvPkt.PlayerId; myIdStatus = PlayerIdStatus.Received; if (IsDebug) { Debug.Log("InLobbyClientLogic: Received my player id: " + myId); } } // Retrieved true lobby state from server. if (NwMgr.PacketQueue.HasPacket <LobbyStatePacket>()) { if (IsDebug) { Debug.Log("InLobbyClientLogic: Received lobby state from server."); } TrueLobbyState = NwMgr.PacketQueue.GetNextPacket <LobbyStatePacket>(); Menus.RefreshLobby(TrueLobbyState, myId); // Go in-game mode if signalled by server. if (TrueLobbyState.IsStartGame) { Debug.Log("Lobby.cs: Got packet to start game. Time: " + Time.time); Menus.OnClick_StartGame(); } } // Received alert that server is disconnecting. Exit the lobby. if (NwMgr.PacketQueue.HasPacket <LobbyPlayerDisconnectPacket>()) { if (IsDebug) { Debug.Log("InLobbyClientLogic: Received alert that server is disconnecting."); } NwMgr.PacketQueue.GetNextPacket <LobbyPlayerDisconnectPacket>(); Menus.OnClick_Disconnect("Server has ended the game."); return; } // Received signal to return to the lobby. if (NwMgr.PacketQueue.HasPacket <LobbyReturnPacket>()) { if (IsDebug) { Debug.Log("InLobbyClientLogic: Received signal to return to lobby."); } NwMgr.PacketQueue.GetNextPacket <LobbyReturnPacket>(); Menus.OnClick_ReturnToLobby(); } }
/// <summary> /// Start the gameplay phase. This will be invoked when: /// As server: "Start Game" button is pressed in the lobby. /// As client: Received packet from server to start game. /// </summary> /// /// <param name="myTeamRole"> /// Your unique ID. Use this to determine your team and role. /// </param> /// /// <param name="playerInfo"> /// Every thing you need to know about the connected players, including yourself. Use these fields: /// playersInfo.NumActivePlayers // Number of players in-game, including yourself. /// playersInfo.usernames[i] // Username of player i /// playersInfo.isHosts[i] // Is player i the server/host? /// playersInfo.isOccupieds[i] // Is player i exist? /// /// These elements are indexed by TeamRole. For example: /// playersInfo.usernames[(int)myTeamRole] == "Billy" // My username is "Billy" /// playersInfo.isHosts[(int)TeamRole.PurpleRunner] == true // The purple runner is the host. /// </param> public void Run(TeamRole myTeamRole, LobbyStatePacket playersInfo) { this.myTeamRole = myTeamRole; this.playersInfo = playersInfo; this.scoreboard = gameObjectives.GetComponent <Scoreboard>(); this.scoreboard.Run(playersInfo, nwMgr, playersInfo.IsHosts[(int)myTeamRole], myTeamRole); EventManagerNetworked.Instance.Run(nwMgr, getIsHost(), playersInfo.PlayerIds[(int)myTeamRole]); if (IsDebug) { Debug.Log("GameEngine :: My team role is: " + myTeamRole); } if (IsDebug) { Debug.Log("GameEngine :: My username is : " + playersInfo.Usernames[(int)myTeamRole]); } if (IsDebug) { Debug.Log("GameEngine :: Am I the host? " + playersInfo.IsHosts[(int)myTeamRole]); } // TODO. Put your initialization code here. Do not put anything in this.Start(). this.rolelessUI.ToggleVisibility(true); stage.SetActive(true); parallaxCamArt.SetActive(true); parallaxCameraScript.GetComponent <CameraBehaviour>().ReassignBackgrounds(); runnerPurple = Instantiate(runner, new Vector3(-3, 4, 6), Quaternion.identity); runnerYellow = Instantiate(runner, new Vector3(32, 4, 6), Quaternion.identity); runnerPurple.transform.GetChild(0).transform.GetChild(0).GetComponent <SpriteRenderer>().color = new Color32(0xa3, 0x00, 0xDD, 0xFF); //RGBA runnerPurple.transform.GetChild(4).GetComponent <SpriteRenderer>().color = new Color32(0xa3, 0x00, 0xDD, 0xFF); //RGBA /*runnerPurple.transform.GetChild(3).GetComponent<SpriteRenderer>().color = new Color32(0xff, 0xcc, 0xff, 0xFF); //RGBA * runnerPurple.transform.GetChild(4).GetComponent<SpriteRenderer>().color = new Color32(0xff, 0xcc, 0xff, 0xFF); //RGBA * runnerPurple.transform.GetChild(5).GetComponent<SpriteRenderer>().color = new Color32(0xff, 0xcc, 0xff, 0xFF); //RGBA * runnerPurple.transform.GetChild(6).GetComponent<SpriteRenderer>().color = new Color32(0xff, 0xcc, 0xff, 0xFF); //RGBA */ runnerYellow.transform.GetChild(0).transform.GetChild(0).GetComponent <SpriteRenderer>().color = new Color32(0xFB, 0xFF, 0x00, 0xFF); //RGBA runnerYellow.transform.GetChild(4).GetComponent <SpriteRenderer>().color = new Color32(0xFB, 0xFF, 0x00, 0xFF); //RGBA /*runnerYellow.transform.GetChild(3).GetComponent<SpriteRenderer>().color = new Color32(0xff, 0xff, 0xcc, 0xFF); //RGBA * runnerYellow.transform.GetChild(4).GetComponent<SpriteRenderer>().color = new Color32(0xff, 0xff, 0xcc, 0xFF); //RGBA * runnerYellow.transform.GetChild(5).GetComponent<SpriteRenderer>().color = new Color32(0xff, 0xff, 0xcc, 0xFF); //RGBA * runnerYellow.transform.GetChild(6).GetComponent<SpriteRenderer>().color = new Color32(0xff, 0xff, 0xcc, 0xFF); //RGBA */ runnerPurpleRB = runnerPurple.GetComponent <Rigidbody2D>(); runnerYellowRB = runnerYellow.GetComponent <Rigidbody2D>(); runnerPurpleController = runnerPurple.GetComponent <PlatformerController>(); runnerYellowController = runnerYellow.GetComponent <PlatformerController>(); runnerYellowController.myTeam = Team.Yellow; runnerPurpleController.myTeam = Team.Purple; purpleAnim = runnerPurple.GetComponent <Animator>(); yellowAnim = runnerYellow.GetComponent <Animator>(); Economy economy = (Economy)Instantiate(economyPrefab); economy.transform.SetParent(canvas.transform, false); GameObject gameclockGO = Instantiate(gameclockPrefab); this.gameclock = gameclockGO.GetComponent <GameClock>(); this.gameclock.setIsHost(playersInfo.IsHosts[(int)myTeamRole]); GameObject builderUI = Instantiate(builderUIPrefab); RefreshRolelessUI(); switch (myTeamRole) { case TeamRole.PurpleBuilder: builderPurple = Instantiate(builder, new Vector3(-3, 0, 5.5f), Quaternion.identity); runnerPurpleController.enabled = false; runnerYellowController.enabled = false; runnerPurpleRB.gravityScale = 0; runnerYellowRB.gravityScale = 0; parallaxCameraScript.GetComponent <CameraBehaviour>().target = builderPurple.transform; parallaxCameraScript.GetComponent <CameraBehaviour>().SetupRoles(TeamRole.PurpleBuilder); builderPurple.GetComponent <BuilderPlatformer>().myTeam = Team.Purple; builderUI.transform.SetParent(canvas.transform, false); //normalbtn = Instantiate(normalBlockButton, new Vector3(1, 4, 6), Quaternion.identity); //firebtn = Instantiate(fireBlockButton, new Vector3(-1, 4, 6), Quaternion.identity); //icebtn = Instantiate(iceBlockButton, new Vector3(-3, 4, 6), Quaternion.identity); // cannonbtn = Instantiate(cannonButton, new Vector3(-5, 4, 6), Quaternion.identity); // smokebtn = Instantiate(smokeButton, new Vector3(-7, 4, 6), Quaternion.identity); break; case TeamRole.PurpleRunner: var gamepadPurple = runnerPurple.AddComponent <GamepadInputHandler>(); runnerPurple.GetComponent <PlatformerController>().gamepad = gamepadPurple; for (int i = 0; i < runnerPurple.transform.childCount; i++) { if (runnerPurple.transform.GetChild(i).name == "Explosion") { var explosion = runnerPurple.transform.GetChild(i).gameObject.AddComponent <PlatformerController_BlockExplosion>(); explosion.GetComponent <PlatformerController_BlockExplosion>().player = runnerPurple.GetComponent <PlatformerController>(); //) ) as PlatformerController_BlockExplosion; } } runnerYellowRB.gravityScale = 0; runnerYellow.GetComponent <PlatformerController>().enabled = false; parallaxCameraScript.GetComponent <CameraBehaviour>().target = runnerPurple.transform; parallaxCameraScript.GetComponent <CameraBehaviour>().SetupRoles(TeamRole.PurpleRunner); break; case TeamRole.YellowBuilder: builderYellow = Instantiate(builder, new Vector3(32, 0, 5.5f), Quaternion.identity); runnerPurpleController.enabled = false; runnerYellowController.enabled = false; runnerPurpleRB.gravityScale = 0; runnerYellowRB.gravityScale = 0; parallaxCameraScript.GetComponent <CameraBehaviour>().target = builderYellow.transform; parallaxCameraScript.GetComponent <CameraBehaviour>().SetupRoles(TeamRole.YellowBuilder); builderYellow.GetComponent <BuilderPlatformer>().myTeam = Team.Yellow; builderUI.transform.SetParent(canvas.transform, false); //normalbtn = Instantiate(normalBlockButton, new Vector3(30, 4, 6), Quaternion.identity); //firebtn = Instantiate(fireBlockButton, new Vector3(32, 4, 6), Quaternion.identity); //icebtn = Instantiate(iceBlockButton, new Vector3(34, 4, 6), Quaternion.identity); // cannonbtn = Instantiate(cannonButton, new Vector3(36, 4, 6), Quaternion.identity); // smokebtn = Instantiate(smokeButton, new Vector3(38, 4, 6), Quaternion.identity); break; case TeamRole.YellowRunner: var gamepadYellow = runnerYellow.AddComponent <GamepadInputHandler>(); runnerYellow.GetComponent <PlatformerController>().gamepad = gamepadYellow; for (int i = 0; i < runnerYellow.transform.childCount; i++) { if (runnerYellow.transform.GetChild(i).name == "Explosion") { var explosion = runnerYellow.transform.GetChild(i).gameObject.AddComponent <PlatformerController_BlockExplosion>(); explosion.GetComponent <PlatformerController_BlockExplosion>().player = runnerYellow.GetComponent <PlatformerController>(); //) ) as PlatformerController_BlockExplosion; } } runnerPurpleRB.gravityScale = 0; runnerPurple.GetComponent <PlatformerController>().enabled = false; parallaxCameraScript.GetComponent <CameraBehaviour>().target = runnerYellow.transform; parallaxCameraScript.GetComponent <CameraBehaviour>().SetupRoles(TeamRole.YellowRunner); break; default: break; } nwMgr.NetworkHost.Disconnected -= new ConnectionDisconnectedHandler(NwMgrDisconnectEvent); nwMgr.NetworkHost.Disconnected += new ConnectionDisconnectedHandler(NwMgrDisconnectEvent); /* Play battle music */ EventManager.Instance.PostNotification(EventType.GameStarted, this, null); this.isRunning = true; }