protected override void CreateInstance(Rectangle rect) { System.Diagnostics.Debug.Assert(Submarine.MainSub != null); LinkedSubmarine.CreateDummy(Submarine.MainSub, subInfo.FilePath, rect.Location.ToVector2()); }
protected override IEnumerable <object> DoLevelTransition(TransitionType transitionType, LevelData newLevel, Submarine leavingSub, bool mirror, List <TraitorMissionResult> traitorResults) { lastUpdateID++; switch (transitionType) { case TransitionType.None: throw new InvalidOperationException("Level transition failed (no transitions available)."); case TransitionType.ReturnToPreviousLocation: //deselect destination on map map.SelectLocation(-1); break; case TransitionType.ProgressToNextLocation: Map.MoveToNextLocation(); break; case TransitionType.End: EndCampaign(); IsFirstRound = true; break; } Map.ProgressWorld(transitionType, (float)(Timing.TotalTime - GameMain.GameSession.RoundStartTime)); bool success = GameMain.Server.ConnectedClients.Any(c => c.InGame && c.Character != null && !c.Character.IsDead); GameMain.GameSession.EndRound("", traitorResults, transitionType); //-------------------------------------- if (success) { SaveInventories(); yield return(CoroutineStatus.Running); if (leavingSub != Submarine.MainSub && !leavingSub.DockedTo.Contains(Submarine.MainSub)) { Submarine.MainSub = leavingSub; GameMain.GameSession.Submarine = leavingSub; GameMain.GameSession.SubmarineInfo = leavingSub.Info; leavingSub.Info.FilePath = System.IO.Path.Combine(SaveUtil.TempPath, leavingSub.Info.Name + ".sub"); var subsToLeaveBehind = GetSubsToLeaveBehind(leavingSub); GameMain.GameSession.OwnedSubmarines.Add(leavingSub.Info); foreach (Submarine sub in subsToLeaveBehind) { GameMain.GameSession.OwnedSubmarines.RemoveAll(s => s != leavingSub.Info && s.Name == sub.Info.Name); MapEntity.mapEntityList.RemoveAll(e => e.Submarine == sub && e is LinkedSubmarine); LinkedSubmarine.CreateDummy(leavingSub, sub); } } NextLevel = newLevel; GameMain.GameSession.SubmarineInfo = new SubmarineInfo(GameMain.GameSession.Submarine); if (PendingSubmarineSwitch != null) { SubmarineInfo previousSub = GameMain.GameSession.SubmarineInfo; GameMain.GameSession.SubmarineInfo = PendingSubmarineSwitch; PendingSubmarineSwitch = null; for (int i = 0; i < GameMain.GameSession.OwnedSubmarines.Count; i++) { if (GameMain.GameSession.OwnedSubmarines[i].Name == previousSub.Name) { GameMain.GameSession.OwnedSubmarines[i] = previousSub; break; } } } SaveUtil.SaveGame(GameMain.GameSession.SavePath); } else { PendingSubmarineSwitch = null; GameMain.Server.EndGame(TransitionType.None); LoadCampaign(GameMain.GameSession.SavePath); LastSaveID++; LastUpdateID++; yield return(CoroutineStatus.Success); } CrewManager?.ClearCurrentOrders(); //-------------------------------------- GameMain.Server.EndGame(transitionType); ForceMapUI = false; NextLevel = newLevel; MirrorLevel = mirror; //give clients time to play the end cinematic before starting the next round if (transitionType == TransitionType.End) { yield return(new WaitForSeconds(EndCinematicDuration)); } else { yield return(new WaitForSeconds(EndTransitionDuration * 0.5f)); } GameMain.Server.StartGame(); yield return(CoroutineStatus.Success); }
public override void End(string endMessage = "") { isRunning = false; bool success = CrewManager.GetCharacters().Any(c => !c.IsDead); crewDead = false; if (success) { if (subsToLeaveBehind == null || leavingSub == null) { DebugConsole.ThrowError("Leaving submarine not selected -> selecting the closest one"); leavingSub = GetLeavingSub(); subsToLeaveBehind = GetSubsToLeaveBehind(leavingSub); } } GameMain.GameSession.EndRound(""); if (success) { if (leavingSub != Submarine.MainSub && !leavingSub.DockedTo.Contains(Submarine.MainSub)) { Submarine.MainSub = leavingSub; GameMain.GameSession.Submarine = leavingSub; foreach (Submarine sub in subsToLeaveBehind) { MapEntity.mapEntityList.RemoveAll(e => e.Submarine == sub && e is LinkedSubmarine); LinkedSubmarine.CreateDummy(leavingSub, sub); } } if (atEndPosition) { Map.MoveToNextLocation(); } else { Map.SelectLocation(-1); } Map.ProgressWorld(); //save and remove all items that are in someone's inventory foreach (Character c in Character.CharacterList) { if (c.Info == null || c.Inventory == null) { continue; } var inventoryElement = new XElement("inventory"); c.SaveInventory(c.Inventory, inventoryElement); c.Info.InventoryData = inventoryElement; c.Inventory?.DeleteAllItems(); } SaveUtil.SaveGame(GameMain.GameSession.SavePath); } if (!success) { var summaryScreen = GUIMessageBox.VisibleBox; if (summaryScreen != null) { summaryScreen = summaryScreen.Children.First(); var buttonArea = summaryScreen.Children.First().FindChild("buttonarea"); buttonArea.ClearChildren(); summaryScreen.RemoveChild(summaryScreen.Children.FirstOrDefault(c => c is GUIButton)); var okButton = new GUIButton(new RectTransform(new Vector2(0.2f, 1.0f), buttonArea.RectTransform), TextManager.Get("LoadGameButton")) { OnClicked = (GUIButton button, object obj) => { GameMain.GameSession.LoadPrevious(); GameMain.LobbyScreen.Select(); GUIMessageBox.MessageBoxes.Remove(GUIMessageBox.VisibleBox); return(true); } }; var quitButton = new GUIButton(new RectTransform(new Vector2(0.2f, 1.0f), buttonArea.RectTransform), TextManager.Get("QuitButton")); quitButton.OnClicked += GameMain.LobbyScreen.QuitToMainMenu; quitButton.OnClicked += (GUIButton button, object obj) => { GUIMessageBox.MessageBoxes.Remove(GUIMessageBox.VisibleBox); return(true); }; quitButton.OnClicked += (GUIButton button, object obj) => { if (ContextualTutorial.Initialized) { ContextualTutorial.Stop(); } return(true); }; } } CrewManager.EndRound(); for (int i = Character.CharacterList.Count - 1; i >= 0; i--) { Character.CharacterList[i].Remove(); } Submarine.Unload(); GameMain.LobbyScreen.Select(); }
public override void End(string endMessage = "") { isRunning = false; bool success = CrewManager.GetCharacters().Any(c => !c.IsDead); if (success) { if (subsToLeaveBehind == null || leavingSub == null) { DebugConsole.ThrowError("Leaving submarine not selected -> selecting the closest one"); leavingSub = GetLeavingSub(); subsToLeaveBehind = GetSubsToLeaveBehind(leavingSub); } } GameMain.GameSession.EndRound(""); if (success) { if (leavingSub != Submarine.MainSub && !leavingSub.DockedTo.Contains(Submarine.MainSub)) { Submarine.MainSub = leavingSub; GameMain.GameSession.Submarine = leavingSub; foreach (Submarine sub in subsToLeaveBehind) { MapEntity.mapEntityList.RemoveAll(e => e.Submarine == sub && e is LinkedSubmarine); LinkedSubmarine.CreateDummy(leavingSub, sub); } } if (atEndPosition) { Map.MoveToNextLocation(); } SaveUtil.SaveGame(GameMain.GameSession.SavePath); } if (!success) { var summaryScreen = GUIMessageBox.VisibleBox; if (summaryScreen != null) { summaryScreen = summaryScreen.children[0]; summaryScreen.RemoveChild(summaryScreen.children.Find(c => c is GUIButton)); var okButton = new GUIButton(new Rectangle(-120, 0, 100, 30), TextManager.Get("LoadGameButton"), Alignment.BottomRight, "", summaryScreen); okButton.OnClicked += (GUIButton button, object obj) => { GameMain.GameSession.LoadPrevious(); GameMain.LobbyScreen.Select(); GUIMessageBox.MessageBoxes.Remove(GUIMessageBox.VisibleBox); return(true); }; var quitButton = new GUIButton(new Rectangle(0, 0, 100, 30), TextManager.Get("QuitButton"), Alignment.BottomRight, "", summaryScreen); quitButton.OnClicked += GameMain.LobbyScreen.QuitToMainMenu; quitButton.OnClicked += (GUIButton button, object obj) => { GUIMessageBox.MessageBoxes.Remove(GUIMessageBox.VisibleBox); return(true); }; } } CrewManager.EndRound(); for (int i = Character.CharacterList.Count - 1; i >= 0; i--) { Character.CharacterList[i].Remove(); } Submarine.Unload(); GameMain.LobbyScreen.Select(); }
protected override IEnumerable <object> DoLevelTransition(TransitionType transitionType, LevelData newLevel, Submarine leavingSub, bool mirror, List <TraitorMissionResult> traitorResults = null) { NextLevel = newLevel; bool success = CrewManager.GetCharacters().Any(c => !c.IsDead); SoundPlayer.OverrideMusicType = success ? "endround" : "crewdead"; SoundPlayer.OverrideMusicDuration = 18.0f; crewDead = false; GameMain.GameSession.EndRound("", traitorResults, transitionType); var continueButton = GameMain.GameSession.RoundSummary?.ContinueButton; RoundSummary roundSummary = null; if (GUIMessageBox.VisibleBox?.UserData is RoundSummary) { roundSummary = GUIMessageBox.VisibleBox?.UserData as RoundSummary; } if (continueButton != null) { continueButton.Visible = false; } lastControlledCharacter = Character.Controlled; Character.Controlled = null; switch (transitionType) { case TransitionType.None: throw new InvalidOperationException("Level transition failed (no transitions available)."); case TransitionType.ReturnToPreviousLocation: //deselect destination on map map.SelectLocation(-1); break; case TransitionType.ProgressToNextLocation: Map.MoveToNextLocation(); break; } Map.ProgressWorld(transitionType, (float)(Timing.TotalTime - GameMain.GameSession.RoundStartTime)); var endTransition = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null, transitionType == TransitionType.LeaveLocation ? Alignment.BottomCenter : Alignment.Center, fadeOut: false, duration: EndTransitionDuration); GUI.ClearMessages(); Location portraitLocation = Map.SelectedLocation ?? Map.CurrentLocation; overlaySprite = portraitLocation.Type.GetPortrait(portraitLocation.PortraitId); float fadeOutDuration = endTransition.Duration; float t = 0.0f; while (t < fadeOutDuration || endTransition.Running) { t += CoroutineManager.UnscaledDeltaTime; overlayColor = Color.Lerp(Color.Transparent, Color.White, t / fadeOutDuration); yield return(CoroutineStatus.Running); } overlayColor = Color.White; yield return(CoroutineStatus.Running); //-------------------------------------- bool save = false; if (success) { if (leavingSub != Submarine.MainSub && !leavingSub.DockedTo.Contains(Submarine.MainSub)) { Submarine.MainSub = leavingSub; GameMain.GameSession.Submarine = leavingSub; var subsToLeaveBehind = GetSubsToLeaveBehind(leavingSub); foreach (Submarine sub in subsToLeaveBehind) { MapEntity.mapEntityList.RemoveAll(e => e.Submarine == sub && e is LinkedSubmarine); LinkedSubmarine.CreateDummy(leavingSub, sub); } } GameMain.GameSession.SubmarineInfo = new SubmarineInfo(GameMain.GameSession.Submarine); if (PendingSubmarineSwitch != null) { SubmarineInfo previousSub = GameMain.GameSession.SubmarineInfo; GameMain.GameSession.SubmarineInfo = PendingSubmarineSwitch; PendingSubmarineSwitch = null; for (int i = 0; i < GameMain.GameSession.OwnedSubmarines.Count; i++) { if (GameMain.GameSession.OwnedSubmarines[i].Name == previousSub.Name) { GameMain.GameSession.OwnedSubmarines[i] = previousSub; break; } } } SaveUtil.SaveGame(GameMain.GameSession.SavePath); } else { PendingSubmarineSwitch = null; EnableRoundSummaryGameOverState(); } //-------------------------------------- SelectSummaryScreen(roundSummary, newLevel, mirror, () => { GameMain.GameScreen.Select(); if (continueButton != null) { continueButton.Visible = true; } GUI.DisableHUD = false; GUI.ClearCursorWait(); overlayColor = Color.Transparent; }); yield return(CoroutineStatus.Success); }
protected override IEnumerable <object> DoLevelTransition(TransitionType transitionType, LevelData newLevel, Submarine leavingSub, bool mirror, List <TraitorMissionResult> traitorResults) { lastUpdateID++; switch (transitionType) { case TransitionType.None: throw new InvalidOperationException("Level transition failed (no transitions available)."); case TransitionType.ReturnToPreviousLocation: //deselect destination on map map.SelectLocation(-1); break; case TransitionType.ProgressToNextLocation: Map.MoveToNextLocation(); break; case TransitionType.End: EndCampaign(); IsFirstRound = true; break; } Map.ProgressWorld(transitionType, (float)(Timing.TotalTime - GameMain.GameSession.RoundStartTime)); bool success = GameMain.Server.ConnectedClients.Any(c => c.InGame && c.Character != null && !c.Character.IsDead); GameMain.GameSession.EndRound("", traitorResults, transitionType); //-------------------------------------- if (success) { List <CharacterCampaignData> prevCharacterData = new List <CharacterCampaignData>(characterData); //client character has spawned this round -> remove old data (and replace with an up-to-date one if the client still has a character) characterData.RemoveAll(cd => cd.HasSpawned); //refresh the character data of clients who are still in the server foreach (Client c in GameMain.Server.ConnectedClients) { if (c.Character?.Info == null) { continue; } if (c.Character.IsDead && c.Character.CauseOfDeath?.Type != CauseOfDeathType.Disconnected) { continue; } c.CharacterInfo = c.Character.Info; characterData.RemoveAll(cd => cd.MatchesClient(c)); characterData.Add(new CharacterCampaignData(c)); } //refresh the character data of clients who aren't in the server anymore foreach (CharacterCampaignData data in prevCharacterData) { if (data.HasSpawned && !characterData.Any(cd => cd.IsDuplicate(data))) { var character = Character.CharacterList.Find(c => c.Info == data.CharacterInfo && !c.IsHusk); if (character != null && (!character.IsDead || character.CauseOfDeath?.Type == CauseOfDeathType.Disconnected)) { data.Refresh(character); characterData.Add(data); } } } characterData.ForEach(cd => cd.HasSpawned = false); //remove all items that are in someone's inventory foreach (Character c in Character.CharacterList) { if (c.Inventory == null) { continue; } if (Level.Loaded.Type == LevelData.LevelType.Outpost && c.Submarine != Level.Loaded.StartOutpost) { Map.CurrentLocation.RegisterTakenItems(c.Inventory.Items.Where(it => it != null && it.SpawnedInOutpost && it.OriginalModuleIndex > 0).Distinct()); } if (c.Info != null && c.IsBot) { if (c.IsDead && c.CauseOfDeath?.Type != CauseOfDeathType.Disconnected) { CrewManager.RemoveCharacterInfo(c.Info); } c.Info.HealthData = new XElement("health"); c.CharacterHealth.Save(c.Info.HealthData); c.Info.InventoryData = new XElement("inventory"); c.SaveInventory(c.Inventory, c.Info.InventoryData); } c.Inventory.DeleteAllItems(); } yield return(CoroutineStatus.Running); if (leavingSub != Submarine.MainSub && !leavingSub.DockedTo.Contains(Submarine.MainSub)) { Submarine.MainSub = leavingSub; GameMain.GameSession.Submarine = leavingSub; var subsToLeaveBehind = GetSubsToLeaveBehind(leavingSub); foreach (Submarine sub in subsToLeaveBehind) { MapEntity.mapEntityList.RemoveAll(e => e.Submarine == sub && e is LinkedSubmarine); LinkedSubmarine.CreateDummy(leavingSub, sub); } } NextLevel = newLevel; GameMain.GameSession.SubmarineInfo = new SubmarineInfo(GameMain.GameSession.Submarine); if (PendingSubmarineSwitch != null) { SubmarineInfo previousSub = GameMain.GameSession.SubmarineInfo; GameMain.GameSession.SubmarineInfo = PendingSubmarineSwitch; PendingSubmarineSwitch = null; for (int i = 0; i < GameMain.GameSession.OwnedSubmarines.Count; i++) { if (GameMain.GameSession.OwnedSubmarines[i].Name == previousSub.Name) { GameMain.GameSession.OwnedSubmarines[i] = previousSub; break; } } } SaveUtil.SaveGame(GameMain.GameSession.SavePath); } else { PendingSubmarineSwitch = null; GameMain.Server.EndGame(TransitionType.None); LoadCampaign(GameMain.GameSession.SavePath); LastSaveID++; LastUpdateID++; yield return(CoroutineStatus.Success); } //-------------------------------------- GameMain.Server.EndGame(transitionType); ForceMapUI = false; NextLevel = newLevel; MirrorLevel = mirror; //give clients time to play the end cinematic before starting the next round if (transitionType == TransitionType.End) { yield return(new WaitForSeconds(EndCinematicDuration)); } else { yield return(new WaitForSeconds(EndTransitionDuration * 0.5f)); } GameMain.Server.StartGame(); yield return(CoroutineStatus.Success); }