//static because we may need to instantiate the campaign if it hasn't been done yet public static void ClientRead(NetBuffer msg) { byte campaignID = msg.ReadByte(); UInt16 updateID = msg.ReadUInt16(); UInt16 saveID = msg.ReadUInt16(); string mapSeed = msg.ReadString(); UInt16 currentLocIndex = msg.ReadUInt16(); UInt16 selectedLocIndex = msg.ReadUInt16(); byte selectedMissionIndex = msg.ReadByte(); int money = msg.ReadInt32(); UInt16 purchasedItemCount = msg.ReadUInt16(); List <PurchasedItem> purchasedItems = new List <PurchasedItem>(); for (int i = 0; i < purchasedItemCount; i++) { UInt16 itemPrefabIndex = msg.ReadUInt16(); UInt16 itemQuantity = msg.ReadUInt16(); purchasedItems.Add(new PurchasedItem(MapEntityPrefab.List[itemPrefabIndex] as ItemPrefab, itemQuantity)); } bool hasCharacterData = msg.ReadBoolean(); CharacterInfo myCharacterInfo = null; if (hasCharacterData) { myCharacterInfo = CharacterInfo.ClientRead(Character.HumanConfigFile, msg); } MultiPlayerCampaign campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign; if (campaign == null || campaignID != campaign.CampaignID) { string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer); GameMain.GameSession = new GameSession(null, savePath, GameModePreset.List.Find(g => g.Identifier == "multiplayercampaign")); campaign = ((MultiPlayerCampaign)GameMain.GameSession.GameMode); campaign.CampaignID = campaignID; campaign.GenerateMap(mapSeed); } GameMain.NetLobbyScreen.ToggleCampaignMode(true); if (NetIdUtils.IdMoreRecent(campaign.lastUpdateID, updateID)) { return; } //server has a newer save file if (NetIdUtils.IdMoreRecent(saveID, campaign.PendingSaveID)) { /*//stop any active campaign save transfers, they're outdated now * List<FileReceiver.FileTransferIn> saveTransfers = * GameMain.Client.FileReceiver.ActiveTransfers.FindAll(t => t.FileType == FileTransferType.CampaignSave); * * foreach (var transfer in saveTransfers) * { * GameMain.Client.FileReceiver.StopTransfer(transfer); * } * * GameMain.Client.RequestFile(FileTransferType.CampaignSave, null, null);*/ campaign.PendingSaveID = saveID; } //we've got the latest save file else if (!NetIdUtils.IdMoreRecent(saveID, campaign.lastSaveID)) { campaign.Map.SetLocation(currentLocIndex == UInt16.MaxValue ? -1 : currentLocIndex); campaign.Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex); campaign.Map.SelectMission(selectedMissionIndex); campaign.Money = money; campaign.CargoManager.SetPurchasedItems(purchasedItems); if (myCharacterInfo != null) { GameMain.NetworkMember.CharacterInfo = myCharacterInfo; GameMain.NetLobbyScreen.SetCampaignCharacterInfo(myCharacterInfo); } else { GameMain.NetLobbyScreen.SetCampaignCharacterInfo(null); } campaign.lastUpdateID = updateID; } }
public CampaignSetupUI(bool isMultiplayer, GUIComponent newGameContainer, GUIComponent loadGameContainer, IEnumerable <SubmarineInfo> submarines, IEnumerable <string> saveFiles = null) { this.isMultiplayer = isMultiplayer; this.newGameContainer = newGameContainer; this.loadGameContainer = loadGameContainer; var columnContainer = new GUILayoutGroup(new RectTransform(Vector2.One, newGameContainer.RectTransform), isHorizontal: true) { Stretch = true, RelativeSpacing = isMultiplayer ? 0.0f : 0.02f }; var leftColumn = new GUILayoutGroup(new RectTransform(Vector2.One, columnContainer.RectTransform)) { Stretch = true, RelativeSpacing = 0.015f }; var rightColumn = new GUILayoutGroup(new RectTransform(isMultiplayer ? Vector2.Zero : new Vector2(1.5f, 1.0f), columnContainer.RectTransform)) { Stretch = true, RelativeSpacing = 0.015f }; columnContainer.Recalculate(); // New game left side new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, TextManager.Get("SaveName"), font: GUI.SubHeadingFont); saveNameBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, string.Empty) { textFilterFunction = (string str) => { return(ToolBox.RemoveInvalidFileNameChars(str)); } }; new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, TextManager.Get("MapSeed"), font: GUI.SubHeadingFont); seedBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, ToolBox.RandomSeed(8)); if (!isMultiplayer) { new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, TextManager.Get("SelectedSub"), font: GUI.SubHeadingFont); var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), isHorizontal: true) { Stretch = true }; subList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.65f), leftColumn.RectTransform)) { ScrollBarVisible = true }; var searchTitle = new GUITextBlock(new RectTransform(new Vector2(0.001f, 1.0f), filterContainer.RectTransform), TextManager.Get("serverlog.filter"), textAlignment: Alignment.CenterLeft, font: GUI.Font); var searchBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 1.0f), filterContainer.RectTransform, Anchor.CenterRight), font: GUI.Font, createClearButton: true); filterContainer.RectTransform.MinSize = searchBox.RectTransform.MinSize; searchBox.OnSelected += (sender, userdata) => { searchTitle.Visible = false; }; searchBox.OnDeselected += (sender, userdata) => { searchTitle.Visible = true; }; searchBox.OnTextChanged += (textBox, text) => { FilterSubs(subList, text); return(true); }; subList.OnSelected = OnSubSelected; } else // Spacing to fix the multiplayer campaign setup layout { //spacing new GUIFrame(new RectTransform(new Vector2(1.0f, 0.25f), leftColumn.RectTransform), style: null); } // New game right side subPreviewContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), rightColumn.RectTransform)) { Stretch = true }; var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.13f), (isMultiplayer ? leftColumn : rightColumn).RectTransform) { MaxSize = new Point(int.MaxValue, 60) }, childAnchor: Anchor.TopRight); if (!isMultiplayer) { buttonContainer.IgnoreLayoutGroups = true; } StartButton = new GUIButton(new RectTransform(isMultiplayer ? new Vector2(0.5f, 1.0f) : Vector2.One, buttonContainer.RectTransform, Anchor.BottomRight) { MaxSize = new Point(350, 60) }, TextManager.Get("StartCampaignButton"), style: "GUIButtonLarge") { OnClicked = (GUIButton btn, object userData) => { if (string.IsNullOrWhiteSpace(saveNameBox.Text)) { saveNameBox.Flash(GUI.Style.Red); return(false); } SubmarineInfo selectedSub = null; if (!isMultiplayer) { if (!(subList.SelectedData is SubmarineInfo)) { return(false); } selectedSub = subList.SelectedData as SubmarineInfo; } else { if (GameMain.NetLobbyScreen.SelectedSub == null) { return(false); } selectedSub = GameMain.NetLobbyScreen.SelectedSub; } if (string.IsNullOrEmpty(selectedSub.MD5Hash.Hash)) { ((GUITextBlock)subList.SelectedComponent).TextColor = Color.DarkRed * 0.8f; subList.SelectedComponent.CanBeFocused = false; subList.Deselect(); return(false); } string savePath = SaveUtil.CreateSavePath(isMultiplayer ? SaveUtil.SaveType.Multiplayer : SaveUtil.SaveType.Singleplayer, saveNameBox.Text); bool hasRequiredContentPackages = selectedSub.RequiredContentPackagesInstalled; if (selectedSub.HasTag(SubmarineTag.Shuttle) || !hasRequiredContentPackages) { if (!hasRequiredContentPackages) { var msgBox = new GUIMessageBox(TextManager.Get("ContentPackageMismatch"), TextManager.GetWithVariable("ContentPackageMismatchWarning", "[requiredcontentpackages]", string.Join(", ", selectedSub.RequiredContentPackages)), new string[] { TextManager.Get("Yes"), TextManager.Get("No") }); msgBox.Buttons[0].OnClicked = msgBox.Close; msgBox.Buttons[0].OnClicked += (button, obj) => { if (GUIMessageBox.MessageBoxes.Count == 0) { StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text); if (isMultiplayer) { CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup"); } } return(true); }; msgBox.Buttons[1].OnClicked = msgBox.Close; } if (selectedSub.HasTag(SubmarineTag.Shuttle)) { var msgBox = new GUIMessageBox(TextManager.Get("ShuttleSelected"), TextManager.Get("ShuttleWarning"), new string[] { TextManager.Get("Yes"), TextManager.Get("No") }); msgBox.Buttons[0].OnClicked = (button, obj) => { StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text); if (isMultiplayer) { CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup"); } return(true); }; msgBox.Buttons[0].OnClicked += msgBox.Close; msgBox.Buttons[1].OnClicked = msgBox.Close; return(false); } } else { StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text); if (isMultiplayer) { CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup"); } } return(true); } }; if (!isMultiplayer) { var disclaimerBtn = new GUIButton(new RectTransform(new Vector2(1.0f, 0.8f), rightColumn.RectTransform, Anchor.TopRight) { AbsoluteOffset = new Point(5) }, style: "GUINotificationButton") { IgnoreLayoutGroups = true, OnClicked = (btn, userdata) => { GameMain.Instance.ShowCampaignDisclaimer(); return(true); } }; disclaimerBtn.RectTransform.MaxSize = new Point((int)(30 * GUI.Scale)); } columnContainer.Recalculate(); leftColumn.Recalculate(); rightColumn.Recalculate(); if (submarines != null) { UpdateSubList(submarines); } UpdateLoadMenu(saveFiles); }
private bool SelectSaveFile(GUIComponent component, object obj) { string fileName = (string)obj; if (isMultiplayer) { loadGameButton.Enabled = true; deleteMpSaveButton.Visible = deleteMpSaveButton.Enabled = GameMain.Client.IsServerOwner; deleteMpSaveButton.Enabled = GameMain.GameSession?.SavePath != fileName; if (deleteMpSaveButton.Visible) { deleteMpSaveButton.UserData = obj as string; } return(true); } XDocument doc = SaveUtil.LoadGameSessionDoc(fileName); if (doc == null) { DebugConsole.ThrowError("Error loading save file \"" + fileName + "\". The file may be corrupted."); return(false); } loadGameButton.Enabled = true; RemoveSaveFrame(); string subName = doc.Root.GetAttributeString("submarine", ""); string saveTime = doc.Root.GetAttributeString("savetime", "unknown"); if (long.TryParse(saveTime, out long unixTime)) { DateTime time = ToolBox.Epoch.ToDateTime(unixTime); saveTime = time.ToString(); } string mapseed = doc.Root.GetAttributeString("mapseed", "unknown"); var saveFileFrame = new GUIFrame(new RectTransform(new Vector2(0.45f, 0.6f), loadGameContainer.RectTransform, Anchor.TopRight) { RelativeOffset = new Vector2(0.0f, 0.1f) }, style: "InnerFrame") { UserData = "savefileframe" }; new GUITextBlock(new RectTransform(new Vector2(1, 0.2f), saveFileFrame.RectTransform, Anchor.TopCenter) { RelativeOffset = new Vector2(0, 0.05f) }, Path.GetFileNameWithoutExtension(fileName), font: GUI.LargeFont, textAlignment: Alignment.Center); var layoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.5f), saveFileFrame.RectTransform, Anchor.Center) { RelativeOffset = new Vector2(0, 0.1f) }); new GUITextBlock(new RectTransform(new Vector2(1, 0), layoutGroup.RectTransform), $"{TextManager.Get("Submarine")} : {subName}", font: GUI.SmallFont); new GUITextBlock(new RectTransform(new Vector2(1, 0), layoutGroup.RectTransform), $"{TextManager.Get("LastSaved")} : {saveTime}", font: GUI.SmallFont); new GUITextBlock(new RectTransform(new Vector2(1, 0), layoutGroup.RectTransform), $"{TextManager.Get("MapSeed")} : {mapseed}", font: GUI.SmallFont); new GUIButton(new RectTransform(new Vector2(0.4f, 0.15f), saveFileFrame.RectTransform, Anchor.BottomCenter) { RelativeOffset = new Vector2(0, 0.1f) }, TextManager.Get("Delete"), style: "GUIButtonSmall") { UserData = fileName, OnClicked = DeleteSave }; return(true); }
public static XDocument OpenFile(string file, out Exception exception) { XDocument doc = null; string extension = ""; exception = null; try { extension = System.IO.Path.GetExtension(file); } catch { //no file extension specified: try using the default one file += ".sub"; } if (string.IsNullOrWhiteSpace(extension)) { extension = ".sub"; file += ".sub"; } if (extension == ".sub") { System.IO.Stream stream; try { stream = SaveUtil.DecompressFiletoStream(file); } catch (System.IO.FileNotFoundException e) { exception = e; DebugConsole.ThrowError("Loading submarine \"" + file + "\" failed! (File not found) " + Environment.StackTrace.CleanupStackTrace(), e); return(null); } catch (Exception e) { exception = e; DebugConsole.ThrowError("Loading submarine \"" + file + "\" failed!", e); return(null); } try { stream.Position = 0; doc = XDocument.Load(stream); //ToolBox.TryLoadXml(file); stream.Close(); stream.Dispose(); } catch (Exception e) { exception = e; DebugConsole.ThrowError("Loading submarine \"" + file + "\" failed! (" + e.Message + ")"); return(null); } } else if (extension == ".xml") { try { ToolBox.IsProperFilenameCase(file); doc = XDocument.Load(file, LoadOptions.SetBaseUri); } catch (Exception e) { exception = e; DebugConsole.ThrowError("Loading submarine \"" + file + "\" failed! (" + e.Message + ")"); return(null); } } else { DebugConsole.ThrowError("Couldn't load submarine \"" + file + "! (Unrecognized file extension)"); return(null); } return(doc); }
public void LoadPrevious() { Submarine.Unload(); SaveUtil.LoadGame(SavePath); }
public void UpdateLoadMenu(IEnumerable <string> saveFiles = null) { prevSaveFiles?.Clear(); prevSaveFiles = null; loadGameContainer.ClearChildren(); if (saveFiles == null) { saveFiles = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Multiplayer); } var leftColumn = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.85f), loadGameContainer.RectTransform), childAnchor: Anchor.TopCenter) { Stretch = true, RelativeSpacing = 0.03f }; saveList = new GUIListBox(new RectTransform(Vector2.One, leftColumn.RectTransform)) { OnSelected = SelectSaveFile }; foreach (string saveFile in saveFiles) { string fileName = saveFile; string subName = ""; string saveTime = ""; string contentPackageStr = ""; var saveFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.1f), saveList.Content.RectTransform) { MinSize = new Point(0, 45) }, style: "ListBoxElement") { UserData = saveFile }; var nameText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform), "") { CanBeFocused = false }; bool isCompatible = true; prevSaveFiles ??= new List <string>(); prevSaveFiles?.Add(saveFile); string[] splitSaveFile = saveFile.Split(';'); saveFrame.UserData = splitSaveFile[0]; fileName = nameText.Text = Path.GetFileNameWithoutExtension(splitSaveFile[0]); if (splitSaveFile.Length > 1) { subName = splitSaveFile[1]; } if (splitSaveFile.Length > 2) { saveTime = splitSaveFile[2]; } if (splitSaveFile.Length > 3) { contentPackageStr = splitSaveFile[3]; } if (!string.IsNullOrEmpty(saveTime) && long.TryParse(saveTime, out long unixTime)) { DateTime time = ToolBox.Epoch.ToDateTime(unixTime); saveTime = time.ToString(); } if (!string.IsNullOrEmpty(contentPackageStr)) { List <string> contentPackagePaths = contentPackageStr.Split('|').ToList(); if (!GameSession.IsCompatibleWithEnabledContentPackages(contentPackagePaths, out string errorMsg)) { nameText.TextColor = GUI.Style.Red; saveFrame.ToolTip = string.Join("\n", errorMsg, TextManager.Get("campaignmode.contentpackagemismatchwarning")); } } if (!isCompatible) { nameText.TextColor = GUI.Style.Red; saveFrame.ToolTip = TextManager.Get("campaignmode.incompatiblesave"); } new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform, Anchor.BottomLeft), text: subName, font: GUI.SmallFont) { CanBeFocused = false, UserData = fileName }; new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), saveFrame.RectTransform), text: saveTime, textAlignment: Alignment.Right, font: GUI.SmallFont) { CanBeFocused = false, UserData = fileName }; } saveList.Content.RectTransform.SortChildren((c1, c2) => { string file1 = c1.GUIComponent.UserData as string; string file2 = c2.GUIComponent.UserData as string; DateTime file1WriteTime = DateTime.MinValue; DateTime file2WriteTime = DateTime.MinValue; try { file1WriteTime = File.GetLastWriteTime(file1); } catch { //do nothing - DateTime.MinValue will be used and the element will get sorted at the bottom of the list }; try { file2WriteTime = File.GetLastWriteTime(file2); } catch { //do nothing - DateTime.MinValue will be used and the element will get sorted at the bottom of the list }; return(file2WriteTime.CompareTo(file1WriteTime)); }); loadGameButton = new GUIButton(new RectTransform(new Vector2(0.45f, 0.12f), loadGameContainer.RectTransform, Anchor.BottomRight), TextManager.Get("LoadButton")) { OnClicked = (btn, obj) => { if (string.IsNullOrWhiteSpace(saveList.SelectedData as string)) { return(false); } LoadGame?.Invoke(saveList.SelectedData as string); CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup"); return(true); }, Enabled = false }; deleteMpSaveButton = new GUIButton(new RectTransform(new Vector2(0.45f, 0.12f), loadGameContainer.RectTransform, Anchor.BottomLeft), TextManager.Get("Delete"), style: "GUIButtonSmall") { OnClicked = DeleteSave, Visible = false }; }
public override void End(string endMessage = "") { isRunning = false; bool success = CrewManager.characters.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.EndShift(""); 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.SaveFile); } 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), "Load game", Alignment.BottomRight, "", summaryScreen); okButton.OnClicked += GameMain.GameSession.LoadPrevious; okButton.OnClicked += (GUIButton button, object obj) => { GUIMessageBox.MessageBoxes.Remove(GUIMessageBox.VisibleBox); return(true); }; var quitButton = new GUIButton(new Rectangle(0, 0, 100, 30), "Quit", Alignment.BottomRight, "", summaryScreen); quitButton.OnClicked += GameMain.LobbyScreen.QuitToMainMenu; quitButton.OnClicked += (GUIButton button, object obj) => { GUIMessageBox.MessageBoxes.Remove(GUIMessageBox.VisibleBox); return(true); }; } } CrewManager.EndShift(); for (int i = Character.CharacterList.Count - 1; i >= 0; i--) { Character.CharacterList[i].Remove(); } Submarine.Unload(); }
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(); } else { Map.SelectLocation(-1); } Map.ProgressWorld(); 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); }; } } CrewManager.EndRound(); for (int i = Character.CharacterList.Count - 1; i >= 0; i--) { Character.CharacterList[i].Remove(); } Submarine.Unload(); GameMain.LobbyScreen.Select(); }
//static because we may need to instantiate the campaign if it hasn't been done yet public static void ClientRead(IReadMessage msg) { bool isFirstRound = msg.ReadBoolean(); byte campaignID = msg.ReadByte(); UInt16 updateID = msg.ReadUInt16(); UInt16 saveID = msg.ReadUInt16(); string mapSeed = msg.ReadString(); UInt16 currentLocIndex = msg.ReadUInt16(); UInt16 selectedLocIndex = msg.ReadUInt16(); byte selectedMissionIndex = msg.ReadByte(); bool allowDebugTeleport = msg.ReadBoolean(); float? reputation = null; if (msg.ReadBoolean()) { reputation = msg.ReadSingle(); } Dictionary <string, float> factionReps = new Dictionary <string, float>(); byte factionsCount = msg.ReadByte(); for (int i = 0; i < factionsCount; i++) { factionReps.Add(msg.ReadString(), msg.ReadSingle()); } bool forceMapUI = msg.ReadBoolean(); int money = msg.ReadInt32(); bool purchasedHullRepairs = msg.ReadBoolean(); bool purchasedItemRepairs = msg.ReadBoolean(); bool purchasedLostShuttles = msg.ReadBoolean(); byte missionCount = msg.ReadByte(); List <Pair <string, byte> > availableMissions = new List <Pair <string, byte> >(); for (int i = 0; i < missionCount; i++) { string missionIdentifier = msg.ReadString(); byte connectionIndex = msg.ReadByte(); availableMissions.Add(new Pair <string, byte>(missionIdentifier, connectionIndex)); } UInt16?storeBalance = null; if (msg.ReadBoolean()) { storeBalance = msg.ReadUInt16(); } UInt16 buyCrateItemCount = msg.ReadUInt16(); List <PurchasedItem> buyCrateItems = new List <PurchasedItem>(); for (int i = 0; i < buyCrateItemCount; i++) { string itemPrefabIdentifier = msg.ReadString(); int itemQuantity = msg.ReadRangedInteger(0, CargoManager.MaxQuantity); buyCrateItems.Add(new PurchasedItem(ItemPrefab.Prefabs[itemPrefabIdentifier], itemQuantity)); } UInt16 purchasedItemCount = msg.ReadUInt16(); List <PurchasedItem> purchasedItems = new List <PurchasedItem>(); for (int i = 0; i < purchasedItemCount; i++) { string itemPrefabIdentifier = msg.ReadString(); int itemQuantity = msg.ReadRangedInteger(0, CargoManager.MaxQuantity); purchasedItems.Add(new PurchasedItem(ItemPrefab.Prefabs[itemPrefabIdentifier], itemQuantity)); } UInt16 soldItemCount = msg.ReadUInt16(); List <SoldItem> soldItems = new List <SoldItem>(); for (int i = 0; i < soldItemCount; i++) { string itemPrefabIdentifier = msg.ReadString(); UInt16 id = msg.ReadUInt16(); bool removed = msg.ReadBoolean(); byte sellerId = msg.ReadByte(); soldItems.Add(new SoldItem(ItemPrefab.Prefabs[itemPrefabIdentifier], id, removed, sellerId)); } ushort pendingUpgradeCount = msg.ReadUInt16(); List <PurchasedUpgrade> pendingUpgrades = new List <PurchasedUpgrade>(); for (int i = 0; i < pendingUpgradeCount; i++) { string upgradeIdentifier = msg.ReadString(); UpgradePrefab prefab = UpgradePrefab.Find(upgradeIdentifier); string categoryIdentifier = msg.ReadString(); UpgradeCategory category = UpgradeCategory.Find(categoryIdentifier); int upgradeLevel = msg.ReadByte(); if (prefab == null || category == null) { continue; } pendingUpgrades.Add(new PurchasedUpgrade(prefab, category, upgradeLevel)); } bool hasCharacterData = msg.ReadBoolean(); CharacterInfo myCharacterInfo = null; if (hasCharacterData) { myCharacterInfo = CharacterInfo.ClientRead(CharacterPrefab.HumanSpeciesName, msg); } if (!(GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign) || campaignID != campaign.CampaignID) { string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer); GameMain.GameSession = new GameSession(null, savePath, GameModePreset.MultiPlayerCampaign, mapSeed); campaign = (MultiPlayerCampaign)GameMain.GameSession.GameMode; campaign.CampaignID = campaignID; GameMain.NetLobbyScreen.ToggleCampaignMode(true); } //server has a newer save file if (NetIdUtils.IdMoreRecent(saveID, campaign.PendingSaveID)) { campaign.PendingSaveID = saveID; } if (NetIdUtils.IdMoreRecent(updateID, campaign.lastUpdateID)) { campaign.SuppressStateSending = true; campaign.IsFirstRound = isFirstRound; //we need to have the latest save file to display location/mission/store if (campaign.LastSaveID == saveID) { campaign.ForceMapUI = forceMapUI; UpgradeStore.WaitForServerUpdate = false; campaign.Map.SetLocation(currentLocIndex == UInt16.MaxValue ? -1 : currentLocIndex); campaign.Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex); campaign.Map.SelectMission(selectedMissionIndex); campaign.Map.AllowDebugTeleport = allowDebugTeleport; campaign.CargoManager.SetItemsInBuyCrate(buyCrateItems); campaign.CargoManager.SetPurchasedItems(purchasedItems); campaign.CargoManager.SetSoldItems(soldItems); if (storeBalance.HasValue) { campaign.Map.CurrentLocation.StoreCurrentBalance = storeBalance.Value; } campaign.UpgradeManager.SetPendingUpgrades(pendingUpgrades); campaign.UpgradeManager.PurchasedUpgrades.Clear(); foreach (var(identifier, rep) in factionReps) { Faction faction = campaign.Factions.FirstOrDefault(f => f.Prefab.Identifier.Equals(identifier, StringComparison.OrdinalIgnoreCase)); if (faction?.Reputation != null) { faction.Reputation.Value = rep; } else { DebugConsole.ThrowError($"Received an update for a faction that doesn't exist \"{identifier}\"."); } } if (reputation.HasValue) { campaign.Map.CurrentLocation.Reputation.Value = reputation.Value; campaign?.CampaignUI?.UpgradeStore?.RefreshAll(); } foreach (var availableMission in availableMissions) { MissionPrefab missionPrefab = MissionPrefab.List.Find(mp => mp.Identifier == availableMission.First); if (missionPrefab == null) { DebugConsole.ThrowError($"Error when receiving campaign data from the server: mission prefab \"{availableMission.First}\" not found."); continue; } if (availableMission.Second < 0 || availableMission.Second >= campaign.Map.CurrentLocation.Connections.Count) { DebugConsole.ThrowError($"Error when receiving campaign data from the server: connection index for mission \"{availableMission.First}\" out of range (index: {availableMission.Second}, current location: {campaign.Map.CurrentLocation.Name}, connections: {campaign.Map.CurrentLocation.Connections.Count})."); continue; } LocationConnection connection = campaign.Map.CurrentLocation.Connections[availableMission.Second]; campaign.Map.CurrentLocation.UnlockMission(missionPrefab, connection); } GameMain.NetLobbyScreen.ToggleCampaignMode(true); } bool shouldRefresh = campaign.Money != money || campaign.PurchasedHullRepairs != purchasedHullRepairs || campaign.PurchasedItemRepairs != purchasedItemRepairs || campaign.PurchasedLostShuttles != purchasedLostShuttles; campaign.Money = money; campaign.PurchasedHullRepairs = purchasedHullRepairs; campaign.PurchasedItemRepairs = purchasedItemRepairs; campaign.PurchasedLostShuttles = purchasedLostShuttles; if (shouldRefresh) { campaign?.CampaignUI?.UpgradeStore?.RefreshAll(); } if (myCharacterInfo != null) { GameMain.Client.CharacterInfo = myCharacterInfo; GameMain.NetLobbyScreen.SetCampaignCharacterInfo(myCharacterInfo); } else { GameMain.NetLobbyScreen.SetCampaignCharacterInfo(null); } campaign.lastUpdateID = updateID; campaign.SuppressStateSending = false; } }
public static void StartCampaignSetup() { var setupBox = new GUIMessageBox("Campaign Setup", "", new string [0], 500, 500); setupBox.InnerFrame.Padding = new Vector4(20.0f, 80.0f, 20.0f, 20.0f); var newCampaignContainer = new GUIFrame(new Rectangle(0, 40, 0, 0), null, setupBox.InnerFrame); var loadCampaignContainer = new GUIFrame(new Rectangle(0, 40, 0, 0), null, setupBox.InnerFrame); var campaignSetupUI = new CampaignSetupUI(true, newCampaignContainer, loadCampaignContainer); var newCampaignButton = new GUIButton(new Rectangle(0, 0, 120, 20), "New campaign", "", setupBox.InnerFrame); newCampaignButton.OnClicked += (btn, obj) => { newCampaignContainer.Visible = true; loadCampaignContainer.Visible = false; return(true); }; var loadCampaignButton = new GUIButton(new Rectangle(130, 0, 120, 20), "Load campaign", "", setupBox.InnerFrame); loadCampaignButton.OnClicked += (btn, obj) => { newCampaignContainer.Visible = false; loadCampaignContainer.Visible = true; return(true); }; loadCampaignContainer.Visible = false; campaignSetupUI.StartNewGame = (Submarine sub, string saveName, string mapSeed) => { GameMain.GameSession = new GameSession(new Submarine(sub.FilePath, ""), saveName, GameModePreset.list.Find(g => g.Name == "Campaign")); var campaign = ((MultiplayerCampaign)GameMain.GameSession.GameMode); campaign.GenerateMap(mapSeed); campaign.SetDelegates(); setupBox.Close(); GameMain.NetLobbyScreen.ToggleCampaignMode(true); campaign.Map.SelectRandomLocation(true); SaveUtil.SaveGame(GameMain.GameSession.SavePath); campaign.LastSaveID++; }; campaignSetupUI.LoadGame = (string fileName) => { SaveUtil.LoadGame(fileName); var campaign = ((MultiplayerCampaign)GameMain.GameSession.GameMode); campaign.LastSaveID++; setupBox.Close(); GameMain.NetLobbyScreen.ToggleCampaignMode(true); campaign.Map.SelectRandomLocation(true); }; var cancelButton = new GUIButton(new Rectangle(0, 0, 120, 30), "Cancel", Alignment.BottomLeft, "", setupBox.InnerFrame); cancelButton.OnClicked += (btn, obj) => { setupBox.Close(); int otherModeIndex = 0; for (otherModeIndex = 0; otherModeIndex < GameMain.NetLobbyScreen.ModeList.children.Count; otherModeIndex++) { if (GameMain.NetLobbyScreen.ModeList.children[otherModeIndex].UserData is MultiplayerCampaign) { continue; } break; } GameMain.NetLobbyScreen.SelectMode(otherModeIndex); return(true); }; }
public void UpdateLoadMenu(IEnumerable <string> saveFiles = null) { loadGameContainer.ClearChildren(); if (saveFiles == null) { saveFiles = SaveUtil.GetSaveFiles(isMultiplayer ? SaveUtil.SaveType.Multiplayer : SaveUtil.SaveType.Singleplayer); } saveList = new GUIListBox(new RectTransform( isMultiplayer ? new Vector2(1.0f, 0.85f) : new Vector2(0.5f, 1.0f), loadGameContainer.RectTransform)) { OnSelected = SelectSaveFile }; foreach (string saveFile in saveFiles) { string fileName = saveFile; string subName = ""; string saveTime = ""; var saveFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.1f), saveList.Content.RectTransform) { MinSize = new Point(0, 45) }, style: "ListBoxElement") { UserData = saveFile }; var nameText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform), text: Path.GetFileNameWithoutExtension(saveFile)); if (!isMultiplayer) { XDocument doc = SaveUtil.LoadGameSessionDoc(saveFile); if (doc?.Root == null) { DebugConsole.ThrowError("Error loading save file \"" + saveFile + "\". The file may be corrupted."); nameText.Color = Color.Red; continue; } subName = doc.Root.GetAttributeString("submarine", ""); saveTime = doc.Root.GetAttributeString("savetime", ""); } else { string[] splitSaveFile = saveFile.Split(';'); saveFrame.UserData = splitSaveFile[0]; fileName = nameText.Text = Path.GetFileNameWithoutExtension(splitSaveFile[0]); if (splitSaveFile.Length > 1) { subName = splitSaveFile[1]; } if (splitSaveFile.Length > 2) { saveTime = splitSaveFile[2]; } } if (!string.IsNullOrEmpty(saveTime) && long.TryParse(saveTime, out long unixTime)) { DateTime time = ToolBox.Epoch.ToDateTime(unixTime); saveTime = time.ToString(); } new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform, Anchor.BottomLeft), text: subName, font: GUI.SmallFont) { UserData = fileName }; new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), saveFrame.RectTransform), text: saveTime, textAlignment: Alignment.Right, font: GUI.SmallFont) { UserData = fileName }; } saveList.Content.RectTransform.SortChildren((c1, c2) => { string file1 = c1.GUIComponent.UserData as string; string file2 = c2.GUIComponent.UserData as string; DateTime file1WriteTime = DateTime.MinValue; DateTime file2WriteTime = DateTime.MinValue; try { file1WriteTime = File.GetLastWriteTime(file1); } catch { //do nothing - DateTime.MinValue will be used and the element will get sorted at the bottom of the list }; try { file2WriteTime = File.GetLastWriteTime(file2); } catch { //do nothing - DateTime.MinValue will be used and the element will get sorted at the bottom of the list }; return(file2WriteTime.CompareTo(file1WriteTime)); }); loadGameButton = new GUIButton(new RectTransform(new Vector2(0.45f, 0.12f), loadGameContainer.RectTransform, Anchor.BottomRight), TextManager.Get("LoadButton"), style: "GUIButtonLarge") { OnClicked = (btn, obj) => { if (string.IsNullOrWhiteSpace(saveList.SelectedData as string)) { return(false); } LoadGame?.Invoke(saveList.SelectedData as string); if (isMultiplayer) { CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup"); } return(true); }, Enabled = false }; }
public static void ClientRead(NetBuffer msg) { //static because we may need to instantiate the campaign if it hasn't been done yet UInt16 updateID = msg.ReadUInt16(); UInt16 saveID = msg.ReadUInt16(); string mapSeed = msg.ReadString(); UInt16 currentLocIndex = msg.ReadUInt16(); UInt16 selectedLocIndex = msg.ReadUInt16(); int money = msg.ReadInt32(); UInt16 purchasedItemCount = msg.ReadUInt16(); List <ItemPrefab> purchasedItems = new List <ItemPrefab>(); for (int i = 0; i < purchasedItemCount; i++) { UInt16 itemPrefabIndex = msg.ReadUInt16(); purchasedItems.Add(MapEntityPrefab.list[itemPrefabIndex] as ItemPrefab); } MultiplayerCampaign campaign = GameMain.GameSession?.GameMode as MultiplayerCampaign; if (campaign == null || mapSeed != campaign.Map.Seed) { string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer); GameMain.GameSession = new GameSession(null, savePath, GameModePreset.list.Find(g => g.Name == "Campaign")); campaign = ((MultiplayerCampaign)GameMain.GameSession.GameMode); campaign.GenerateMap(mapSeed); } GameMain.NetLobbyScreen.ToggleCampaignMode(true); if (NetIdUtils.IdMoreRecent(campaign.lastUpdateID, updateID)) { return; } //server has a newer save file if (NetIdUtils.IdMoreRecent(saveID, campaign.PendingSaveID)) { //stop any active campaign save transfers, they're outdated now List <FileReceiver.FileTransferIn> saveTransfers = GameMain.Client.FileReceiver.ActiveTransfers.FindAll(t => t.FileType == FileTransferType.CampaignSave); foreach (var transfer in saveTransfers) { GameMain.Client.FileReceiver.StopTransfer(transfer); } GameMain.Client.RequestFile(FileTransferType.CampaignSave, null, null); campaign.PendingSaveID = saveID; } //we've got the latest save file else if (!NetIdUtils.IdMoreRecent(saveID, campaign.lastSaveID)) { campaign.Map.SetLocation(currentLocIndex == UInt16.MaxValue ? -1 : currentLocIndex); campaign.Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex); campaign.Money = money; campaign.CargoManager.SetPurchasedItems(purchasedItems); campaign.lastUpdateID = updateID; } }
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(); Map.ProgressWorld(); break; } 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); //-------------------------------------- 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); SaveUtil.SaveGame(GameMain.GameSession.SavePath); } else { EnableRoundSummaryGameOverState(); } //-------------------------------------- if (PendingSubmarineSwitch != null) { GameMain.GameSession.SubmarineInfo = PendingSubmarineSwitch; PendingSubmarineSwitch = null; } 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); }
private IEnumerable <object> Load(bool isSeparateThread) { if (GameSettings.VerboseLogging) { DebugConsole.NewMessage("LOADING COROUTINE", Color.Lime); } while (TitleScreen.WaitForLanguageSelection) { yield return(CoroutineStatus.Running); } SoundManager = new Sounds.SoundManager(); SoundManager.SetCategoryGainMultiplier("default", Config.SoundVolume, 0); SoundManager.SetCategoryGainMultiplier("ui", Config.SoundVolume, 0); SoundManager.SetCategoryGainMultiplier("waterambience", Config.SoundVolume, 0); SoundManager.SetCategoryGainMultiplier("music", Config.MusicVolume, 0); SoundManager.SetCategoryGainMultiplier("voip", Math.Min(Config.VoiceChatVolume, 1.0f), 0); if (Config.EnableSplashScreen && !ConsoleArguments.Contains("-skipintro")) { var pendingSplashScreens = TitleScreen.PendingSplashScreens; float baseVolume = MathHelper.Clamp(Config.SoundVolume * 2.0f, 0.0f, 1.0f); pendingSplashScreens?.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_UTG.webm", baseVolume * 0.5f)); pendingSplashScreens?.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_FF.webm", baseVolume)); pendingSplashScreens?.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_Daedalic.webm", baseVolume * 0.1f)); } //if not loading in a separate thread, wait for the splash screens to finish before continuing the loading //otherwise the videos will look extremely choppy if (!isSeparateThread) { while (TitleScreen.PlayingSplashScreen || TitleScreen.PendingSplashScreens.Count > 0) { yield return(CoroutineStatus.Running); } } GUI.Init(Window, Config.AllEnabledPackages, GraphicsDevice); DebugConsole.Init(); if (Config.AutoUpdateWorkshopItems) { Config.WaitingForAutoUpdate = true; TaskPool.Add("AutoUpdateWorkshopItemsAsync", SteamManager.AutoUpdateWorkshopItemsAsync(), (task) => { bool result = ((Task <bool>)task).Result; Config.WaitingForAutoUpdate = false; }); while (Config.WaitingForAutoUpdate) { yield return(CoroutineStatus.Running); } } #if DEBUG if (Config.ModBreakerMode) { Config.SelectCorePackage(ContentPackage.CorePackages.GetRandom()); foreach (var regularPackage in ContentPackage.RegularPackages) { if (Rand.Range(0.0, 1.0) <= 0.5) { Config.EnableRegularPackage(regularPackage); } else { Config.DisableRegularPackage(regularPackage); } } ContentPackage.SortContentPackages(p => { return(Rand.Int(int.MaxValue)); }); } #endif if (Config.AllEnabledPackages.None()) { DebugConsole.Log("No content packages selected"); } else { DebugConsole.Log("Selected content packages: " + string.Join(", ", Config.AllEnabledPackages.Select(cp => cp.Name))); } #if DEBUG GameSettings.ShowUserStatisticsPrompt = false; GameSettings.SendUserStatistics = false; #endif InitUserStats(); yield return(CoroutineStatus.Running); Debug.WriteLine("sounds"); int i = 0; foreach (object crObj in SoundPlayer.Init()) { CoroutineStatus status = (CoroutineStatus)crObj; if (status == CoroutineStatus.Success) { break; } i++; TitleScreen.LoadState = SoundPlayer.SoundCount == 0 ? 1.0f : Math.Min(40.0f * i / Math.Max(SoundPlayer.SoundCount, 1), 40.0f); yield return(CoroutineStatus.Running); } TitleScreen.LoadState = 40.0f; yield return(CoroutineStatus.Running); LightManager = new Lights.LightManager(base.GraphicsDevice, Content); TitleScreen.LoadState = 41.0f; yield return(CoroutineStatus.Running); GUI.LoadContent(); TitleScreen.LoadState = 42.0f; yield return(CoroutineStatus.Running); TaskPool.Add("InitRelayNetworkAccess", SteamManager.InitRelayNetworkAccess(), (t) => { }); FactionPrefab.LoadFactions(); NPCSet.LoadSets(); CharacterPrefab.LoadAll(); MissionPrefab.Init(); TraitorMissionPrefab.Init(); MapEntityPrefab.Init(); Tutorials.Tutorial.Init(); MapGenerationParams.Init(); LevelGenerationParams.LoadPresets(); CaveGenerationParams.LoadPresets(); OutpostGenerationParams.LoadPresets(); WreckAIConfig.LoadAll(); EventSet.LoadPrefabs(); ItemPrefab.LoadAll(GetFilesOfType(ContentType.Item)); AfflictionPrefab.LoadAll(GetFilesOfType(ContentType.Afflictions)); SkillSettings.Load(GetFilesOfType(ContentType.SkillSettings)); Order.Init(); EventManagerSettings.Init(); BallastFloraPrefab.LoadAll(GetFilesOfType(ContentType.MapCreature)); HintManager.Init(); TitleScreen.LoadState = 50.0f; yield return(CoroutineStatus.Running); StructurePrefab.LoadAll(GetFilesOfType(ContentType.Structure)); TitleScreen.LoadState = 55.0f; yield return(CoroutineStatus.Running); UpgradePrefab.LoadAll(GetFilesOfType(ContentType.UpgradeModules)); TitleScreen.LoadState = 56.0f; yield return(CoroutineStatus.Running); JobPrefab.LoadAll(GetFilesOfType(ContentType.Jobs)); CorpsePrefab.LoadAll(GetFilesOfType(ContentType.Corpses)); NPCConversation.LoadAll(GetFilesOfType(ContentType.NPCConversations)); ItemAssemblyPrefab.LoadAll(); TitleScreen.LoadState = 60.0f; yield return(CoroutineStatus.Running); GameModePreset.Init(); SaveUtil.DeleteDownloadedSubs(); SubmarineInfo.RefreshSavedSubs(); TitleScreen.LoadState = 65.0f; yield return(CoroutineStatus.Running); GameScreen = new GameScreen(GraphicsDeviceManager.GraphicsDevice, Content); TitleScreen.LoadState = 68.0f; yield return(CoroutineStatus.Running); MainMenuScreen = new MainMenuScreen(this); ServerListScreen = new ServerListScreen(); TitleScreen.LoadState = 70.0f; yield return(CoroutineStatus.Running); #if USE_STEAM SteamWorkshopScreen = new SteamWorkshopScreen(); if (SteamManager.IsInitialized) { Steamworks.SteamFriends.OnGameRichPresenceJoinRequested += OnInvitedToGame; Steamworks.SteamFriends.OnGameLobbyJoinRequested += OnLobbyJoinRequested; } #endif SubEditorScreen = new SubEditorScreen(); TitleScreen.LoadState = 75.0f; yield return(CoroutineStatus.Running); ParticleEditorScreen = new ParticleEditorScreen(); TitleScreen.LoadState = 80.0f; yield return(CoroutineStatus.Running); LevelEditorScreen = new LevelEditorScreen(); SpriteEditorScreen = new SpriteEditorScreen(); EventEditorScreen = new EventEditorScreen(); CharacterEditorScreen = new CharacterEditor.CharacterEditorScreen(); CampaignEndScreen = new CampaignEndScreen(); yield return(CoroutineStatus.Running); TitleScreen.LoadState = 85.0f; ParticleManager = new ParticleManager(GameScreen.Cam); ParticleManager.LoadPrefabs(); TitleScreen.LoadState = 88.0f; LevelObjectPrefab.LoadAll(); TitleScreen.LoadState = 90.0f; yield return(CoroutineStatus.Running); DecalManager = new DecalManager(); LocationType.Init(); MainMenuScreen.Select(); foreach (string steamError in SteamManager.InitializationErrors) { new GUIMessageBox(TextManager.Get("Error"), TextManager.Get(steamError)); } TitleScreen.LoadState = 100.0f; hasLoaded = true; if (GameSettings.VerboseLogging) { DebugConsole.NewMessage("LOADING COROUTINE FINISHED", Color.Lime); } yield return(CoroutineStatus.Success); }
public override void End(string endMessage = "") { isRunning = false; if (GameMain.Client != null) { GameMain.GameSession.EndRound(""); #if CLIENT GameMain.GameSession.CrewManager.EndRound(); #endif return; } lastUpdateID++; bool success = GameMain.Server.ConnectedClients.Any(c => c.InGame && c.Character != null && !c.Character.IsDead) || (GameMain.Server.Character != null && !GameMain.Server.Character.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(""); //TODO: save player inventories between mp campaign rounds //remove all items that are in someone's inventory foreach (Character c in Character.CharacterList) { if (c.Inventory == null) { continue; } foreach (Item item in c.Inventory.Items) { if (item != null) { item.Remove(); } } } #if CLIENT GameMain.GameSession.CrewManager.EndRound(); #endif if (success) { bool atEndPosition = Submarine.MainSub.AtEndPosition; /*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(); //select a random location to make sure we've got some destination //to head towards even if the host/clients don't select anything map.SelectRandomLocation(true); } SaveUtil.SaveGame(GameMain.GameSession.SavePath); } }
public CampaignSetupUI(bool isMultiplayer, GUIComponent newGameContainer, GUIComponent loadGameContainer) { this.isMultiplayer = isMultiplayer; this.newGameContainer = newGameContainer; this.loadGameContainer = loadGameContainer; var columnContainer = new GUILayoutGroup(new RectTransform(Vector2.One, newGameContainer.RectTransform), isHorizontal: true) { Stretch = true, RelativeSpacing = 0.05f }; var leftColumn = new GUILayoutGroup(new RectTransform(Vector2.One, columnContainer.RectTransform)) { Stretch = true, RelativeSpacing = 0.02f }; var rightColumn = new GUILayoutGroup(new RectTransform(Vector2.One, columnContainer.RectTransform)) { RelativeSpacing = 0.02f }; // New game left side new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), leftColumn.RectTransform), TextManager.Get("SelectedSub") + ":", textAlignment: Alignment.BottomLeft); subList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.65f), leftColumn.RectTransform)); UpdateSubList(); // New game right side new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), rightColumn.RectTransform), TextManager.Get("SaveName") + ":", textAlignment: Alignment.BottomLeft); saveNameBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.1f), rightColumn.RectTransform), string.Empty); new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), rightColumn.RectTransform), TextManager.Get("MapSeed") + ":", textAlignment: Alignment.BottomLeft); seedBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.1f), rightColumn.RectTransform), ToolBox.RandomSeed(8)); var startButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.13f), rightColumn.RectTransform, Anchor.BottomRight), TextManager.Get("StartCampaignButton"), style: "GUIButtonLarge") { IgnoreLayoutGroups = true, OnClicked = (GUIButton btn, object userData) => { if (string.IsNullOrWhiteSpace(saveNameBox.Text)) { saveNameBox.Flash(Color.Red); return(false); } Submarine selectedSub = subList.SelectedData as Submarine; if (selectedSub == null) { return(false); } if (string.IsNullOrEmpty(selectedSub.MD5Hash.Hash)) { ((GUITextBlock)subList.SelectedComponent).TextColor = Color.DarkRed * 0.8f; subList.SelectedComponent.CanBeFocused = false; subList.Deselect(); return(false); } string savePath = SaveUtil.CreateSavePath(isMultiplayer ? SaveUtil.SaveType.Multiplayer : SaveUtil.SaveType.Singleplayer, saveNameBox.Text); bool hasRequiredContentPackages = selectedSub.RequiredContentPackages.All(cp => GameMain.SelectedPackages.Any(cp2 => cp2.Name == cp)); if (selectedSub.HasTag(SubmarineTag.Shuttle) || !hasRequiredContentPackages) { if (!hasRequiredContentPackages) { var msgBox = new GUIMessageBox(TextManager.Get("ContentPackageMismatch"), TextManager.Get("ContentPackageMismatchWarning") .Replace("[requiredcontentpackages]", string.Join(", ", selectedSub.RequiredContentPackages)), new string[] { TextManager.Get("Yes"), TextManager.Get("No") }); msgBox.Buttons[0].OnClicked = msgBox.Close; msgBox.Buttons[0].OnClicked += (button, obj) => { if (GUIMessageBox.MessageBoxes.Count == 0) { StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text); } return(true); }; msgBox.Buttons[1].OnClicked = msgBox.Close; } if (selectedSub.HasTag(SubmarineTag.Shuttle)) { var msgBox = new GUIMessageBox(TextManager.Get("ShuttleSelected"), TextManager.Get("ShuttleWarning"), new string[] { TextManager.Get("Yes"), TextManager.Get("No") }); msgBox.Buttons[0].OnClicked = (button, obj) => { StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text); return(true); }; msgBox.Buttons[0].OnClicked += msgBox.Close; msgBox.Buttons[1].OnClicked = msgBox.Close; return(false); } } else { StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text); } return(true); } }; UpdateLoadMenu(); }
public MultiPlayerCampaignSetupUI(GUIComponent newGameContainer, GUIComponent loadGameContainer, IEnumerable <SubmarineInfo> submarines, IEnumerable <string> saveFiles = null) : base(newGameContainer, loadGameContainer) { var columnContainer = new GUILayoutGroup(new RectTransform(Vector2.One, newGameContainer.RectTransform), isHorizontal: true) { Stretch = true, RelativeSpacing = 0.0f }; var leftColumn = new GUILayoutGroup(new RectTransform(Vector2.One, columnContainer.RectTransform)) { Stretch = true, RelativeSpacing = 0.015f }; var rightColumn = new GUILayoutGroup(new RectTransform(Vector2.Zero, columnContainer.RectTransform)) { Stretch = true, RelativeSpacing = 0.015f }; columnContainer.Recalculate(); // New game left side new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, TextManager.Get("SaveName"), font: GUI.SubHeadingFont); saveNameBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, string.Empty) { textFilterFunction = (string str) => { return(ToolBox.RemoveInvalidFileNameChars(str)); } }; new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, TextManager.Get("MapSeed"), font: GUI.SubHeadingFont); seedBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, ToolBox.RandomSeed(8)); // Spacing to fix the multiplayer campaign setup layout CreateMultiplayerCampaignSubList(leftColumn.RectTransform); //spacing //new GUIFrame(new RectTransform(new Vector2(1.0f, 0.25f), leftColumn.RectTransform), style: null); // New game right side subPreviewContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), rightColumn.RectTransform)) { Stretch = true }; var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.12f), leftColumn.RectTransform) { MaxSize = new Point(int.MaxValue, 60) }, childAnchor: Anchor.BottomRight, isHorizontal: true); StartButton = new GUIButton(new RectTransform(new Vector2(0.4f, 1f), buttonContainer.RectTransform, Anchor.BottomRight) { MaxSize = new Point(350, 60) }, TextManager.Get("StartCampaignButton")) { OnClicked = (GUIButton btn, object userData) => { if (string.IsNullOrWhiteSpace(saveNameBox.Text)) { saveNameBox.Flash(GUI.Style.Red); return(false); } SubmarineInfo selectedSub = null; if (GameMain.NetLobbyScreen.SelectedSub == null) { return(false); } selectedSub = GameMain.NetLobbyScreen.SelectedSub; if (selectedSub.SubmarineClass == SubmarineClass.Undefined) { new GUIMessageBox(TextManager.Get("error"), TextManager.Get("undefinedsubmarineselected")); return(false); } if (string.IsNullOrEmpty(selectedSub.MD5Hash.Hash)) { ((GUITextBlock)subList.SelectedComponent).TextColor = Color.DarkRed * 0.8f; subList.SelectedComponent.CanBeFocused = false; subList.Deselect(); return(false); } string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer, saveNameBox.Text); bool hasRequiredContentPackages = selectedSub.RequiredContentPackagesInstalled; CampaignSettings settings = new CampaignSettings(); settings.RadiationEnabled = GameMain.NetLobbyScreen.IsRadiationEnabled(); settings.MaxMissionCount = GameMain.NetLobbyScreen.GetMaxMissionCount(); if (selectedSub.HasTag(SubmarineTag.Shuttle) || !hasRequiredContentPackages) { if (!hasRequiredContentPackages) { var msgBox = new GUIMessageBox(TextManager.Get("ContentPackageMismatch"), TextManager.GetWithVariable("ContentPackageMismatchWarning", "[requiredcontentpackages]", string.Join(", ", selectedSub.RequiredContentPackages)), new string[] { TextManager.Get("Yes"), TextManager.Get("No") }); msgBox.Buttons[0].OnClicked = msgBox.Close; msgBox.Buttons[0].OnClicked += (button, obj) => { if (GUIMessageBox.MessageBoxes.Count == 0) { StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings); CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup"); } return(true); }; msgBox.Buttons[1].OnClicked = msgBox.Close; } if (selectedSub.HasTag(SubmarineTag.Shuttle)) { var msgBox = new GUIMessageBox(TextManager.Get("ShuttleSelected"), TextManager.Get("ShuttleWarning"), new string[] { TextManager.Get("Yes"), TextManager.Get("No") }); msgBox.Buttons[0].OnClicked = (button, obj) => { StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings); CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup"); return(true); }; msgBox.Buttons[0].OnClicked += msgBox.Close; msgBox.Buttons[1].OnClicked = msgBox.Close; return(false); } } else { StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings); CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup"); } return(true); } }; InitialMoneyText = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1f), buttonContainer.RectTransform), "", font: GUI.Style.SmallFont, textColor: GUI.Style.Green) { TextGetter = () => { int initialMoney = CampaignMode.InitialMoney; if (GameMain.NetLobbyScreen.SelectedSub != null) { initialMoney -= GameMain.NetLobbyScreen.SelectedSub.Price; } initialMoney = Math.Max(initialMoney, MultiPlayerCampaign.MinimumInitialMoney); return(TextManager.GetWithVariable("campaignstartingmoney", "[money]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", initialMoney))); } }; columnContainer.Recalculate(); leftColumn.Recalculate(); rightColumn.Recalculate(); if (submarines != null) { UpdateSubList(submarines); } UpdateLoadMenu(saveFiles); }
//static because we may need to instantiate the campaign if it hasn't been done yet public static void ClientRead(IReadMessage msg) { byte campaignID = msg.ReadByte(); UInt16 updateID = msg.ReadUInt16(); UInt16 saveID = msg.ReadUInt16(); string mapSeed = msg.ReadString(); UInt16 currentLocIndex = msg.ReadUInt16(); UInt16 selectedLocIndex = msg.ReadUInt16(); byte selectedMissionIndex = msg.ReadByte(); UInt16 startWatchmanID = msg.ReadUInt16(); UInt16 endWatchmanID = msg.ReadUInt16(); int money = msg.ReadInt32(); bool purchasedHullRepairs = msg.ReadBoolean(); bool purchasedItemRepairs = msg.ReadBoolean(); bool purchasedLostShuttles = msg.ReadBoolean(); UInt16 purchasedItemCount = msg.ReadUInt16(); List <PurchasedItem> purchasedItems = new List <PurchasedItem>(); for (int i = 0; i < purchasedItemCount; i++) { string itemPrefabIdentifier = msg.ReadString(); int itemQuantity = msg.ReadRangedInteger(0, CargoManager.MaxQuantity); purchasedItems.Add(new PurchasedItem(ItemPrefab.Prefabs[itemPrefabIdentifier], itemQuantity)); } bool hasCharacterData = msg.ReadBoolean(); CharacterInfo myCharacterInfo = null; if (hasCharacterData) { myCharacterInfo = CharacterInfo.ClientRead(CharacterPrefab.HumanSpeciesName, msg); } MultiPlayerCampaign campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign; if (campaign == null || campaignID != campaign.CampaignID) { string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer); GameMain.GameSession = new GameSession(null, savePath, GameModePreset.List.Find(g => g.Identifier == "multiplayercampaign")); campaign = ((MultiPlayerCampaign)GameMain.GameSession.GameMode); campaign.CampaignID = campaignID; campaign.GenerateMap(mapSeed); GameMain.NetLobbyScreen.ToggleCampaignMode(true); } //server has a newer save file if (NetIdUtils.IdMoreRecent(saveID, campaign.PendingSaveID)) { /*//stop any active campaign save transfers, they're outdated now * List<FileReceiver.FileTransferIn> saveTransfers = * GameMain.Client.FileReceiver.ActiveTransfers.FindAll(t => t.FileType == FileTransferType.CampaignSave); * * foreach (var transfer in saveTransfers) * { * GameMain.Client.FileReceiver.StopTransfer(transfer); * } * * GameMain.Client.RequestFile(FileTransferType.CampaignSave, null, null);*/ campaign.PendingSaveID = saveID; } if (NetIdUtils.IdMoreRecent(updateID, campaign.lastUpdateID)) { campaign.SuppressStateSending = true; //we need to have the latest save file to display location/mission/store if (campaign.LastSaveID == saveID) { campaign.Map.SetLocation(currentLocIndex == UInt16.MaxValue ? -1 : currentLocIndex); campaign.Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex); campaign.Map.SelectMission(selectedMissionIndex); campaign.CargoManager.SetPurchasedItems(purchasedItems); } campaign.startWatchmanID = startWatchmanID; campaign.endWatchmanID = endWatchmanID; campaign.Money = money; campaign.PurchasedHullRepairs = purchasedHullRepairs; campaign.PurchasedItemRepairs = purchasedItemRepairs; campaign.PurchasedLostShuttles = purchasedLostShuttles; if (myCharacterInfo != null) { GameMain.Client.CharacterInfo = myCharacterInfo; GameMain.NetLobbyScreen.SetCampaignCharacterInfo(myCharacterInfo); } else { GameMain.NetLobbyScreen.SetCampaignCharacterInfo(null); } campaign.lastUpdateID = updateID; campaign.SuppressStateSending = false; } }
public void Run() { Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Character)); Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Item)); Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Items.Components.ItemComponent)); Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Hull)); TryStartChildServerRelay(); Init(); StartServer(); ResetFrameTime(); double frequency = (double)Stopwatch.Frequency; if (frequency <= 1500) { DebugConsole.NewMessage("WARNING: Stopwatch frequency under 1500 ticks per second. Expect significant syncing accuracy issues.", Color.Yellow); } stopwatch = Stopwatch.StartNew(); long prevTicks = stopwatch.ElapsedTicks; while (ShouldRun) { long currTicks = stopwatch.ElapsedTicks; double elapsedTime = Math.Max(currTicks - prevTicks, 0) / frequency; Timing.Accumulator += elapsedTime; if (Timing.Accumulator > 1.0) { //prevent spiral of death Timing.Accumulator = Timing.Step; } prevTicks = currTicks; while (Timing.Accumulator >= Timing.Step) { Timing.TotalTime += Timing.Step; DebugConsole.Update(); if (GameSession?.GameMode == null || !GameSession.GameMode.Paused) { Screen.Selected?.Update((float)Timing.Step); } Server.Update((float)Timing.Step); if (Server == null) { break; } SteamManager.Update((float)Timing.Step); TaskPool.Update(); CoroutineManager.Update((float)Timing.Step, (float)Timing.Step); Timing.Accumulator -= Timing.Step; } #if !DEBUG if (Server?.OwnerConnection == null) { DebugConsole.UpdateCommandLine((int)(Timing.Accumulator * 800)); } else { DebugConsole.Clear(); } #else DebugConsole.UpdateCommandLine((int)(Timing.Accumulator * 800)); #endif int frameTime = (int)(((double)(stopwatch.ElapsedTicks - prevTicks) / frequency) * 1000.0); frameTime = Math.Max(0, frameTime); Thread.Sleep(Math.Max(((int)(Timing.Step * 1000.0) - frameTime) / 2, 0)); } stopwatch.Stop(); CloseServer(); SteamManager.ShutDown(); SaveUtil.CleanUnnecessarySaveFiles(); if (GameSettings.SaveDebugConsoleLogs) { DebugConsole.SaveLogs(); } if (GameSettings.SendUserStatistics) { GameAnalytics.OnQuit(); } MainThread = null; }
public override void End(string endMessage = "") { isRunning = false; if (GameMain.Client != null) { GameMain.GameSession.EndRound(""); #if CLIENT GameMain.GameSession.CrewManager.EndRound(); #endif return; } lastUpdateID++; bool success = (GameMain.Server.ConnectedClients.Any(c => c.InGame && c.Character != null && !c.Character.IsDead) || (GameMain.Server.Character != null && !GameMain.Server.Character.IsDead)) && (!GameMain.NilMod.RoundEnded || Submarine.MainSub.AtEndPosition); /*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(""); //TODO: save player inventories between mp campaign rounds //remove all items that are in someone's inventory foreach (Character c in Character.CharacterList) { if (c.Inventory == null) { continue; } //Character is inside of a submarine and still alive in some form if (c.Submarine != null) { CheckSubInventory(c.Inventory.Items); } //Not on the submarine or dead, just remove everything. else { foreach (Item item in c.Inventory.Items) { if (item != null) { item.Remove(); } } } } //Code for removing items from the level which started in a players inventory, makes a bit of a mess though. for (int i = Item.ItemList.ToArray().Length - 1; i >= 0; i--) { if (Item.ItemList[i] == null) { continue; } if (Item.ItemList[i].Submarine == null) { continue; } if (Item.ItemList[i] != null) { if (Item.ItemList[i].HasTag("Starter_Item") && Item.ItemList[i].ContainedItems != null) { CheckSubInventory(Item.ItemList[i].ContainedItems); Item.ItemList[i].Remove(); } else if (Item.ItemList[i].HasTag("Starter_Item")) { Item.ItemList[i].Remove(); } } } #if CLIENT GameMain.GameSession.CrewManager.EndRound(); if (GameSession.inGameInfo != null) { GameSession.inGameInfo.ResetGUIListData(); } #endif if (success) { GameMain.NilMod.CampaignStart = false; //Make the save last longer if its being successful. if (GameMain.NilMod.CampaignFails > 0) { GameMain.NilMod.CampaignFails -= GameMain.NilMod.CampaignSuccessFailReduction; if (GameMain.NilMod.CampaignFails < 0) { GameMain.NilMod.CampaignFails = 0; } } bool atEndPosition = Submarine.MainSub.AtEndPosition; /*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(); //select a random location to make sure we've got some destination //to head towards even if the host/clients don't select anything map.SelectRandomLocation(true); } //Repair submarine walls foreach (Structure w in Structure.WallList) { for (int i = 0; i < w.SectionCount; i++) { w.AddDamage(i, -100000.0f); } } //Remove water, replenish oxygen, Extinguish fires foreach (Hull hull in Hull.hullList) { hull.OxygenPercentage = 100.0f; hull.WaterVolume = 0f; for (int i = hull.FireSources.Count - 1; i >= 0; i--) { hull.FireSources[i].Remove(); } } //Repair devices, electricals and shutdown reactors. foreach (Item it in Item.ItemList) { if (it.GetComponent <Barotrauma.Items.Components.Powered>() != null || it.GetComponent <Barotrauma.Items.Components.Reactor>() != null || it.GetComponent <Barotrauma.Items.Components.Engine>() != null || it.GetComponent <Barotrauma.Items.Components.Steering>() != null || it.GetComponent <Barotrauma.Items.Components.Radar>() != null || it.GetComponent <Barotrauma.Items.Components.MiniMap>() != null || it.GetComponent <Barotrauma.Items.Components.Door>() != null || it.GetComponent <Barotrauma.Items.Components.RelayComponent>() != null) { it.Condition = it.Prefab.Health; } if (it.GetComponent <Barotrauma.Items.Components.Reactor>() != null) { //Compatability for BTE. if (it.Prefab.Name == "Diesel-Electric Generator") { continue; } Barotrauma.Items.Components.Reactor reactor = it.GetComponent <Barotrauma.Items.Components.Reactor>(); reactor.AutoTemp = false; reactor.FissionRate = 0; reactor.CoolingRate = 100; reactor.Temperature = 0; } if (it.GetComponent <Barotrauma.Items.Components.PowerContainer>() != null) { var powerContainer = it.GetComponent <Barotrauma.Items.Components.PowerContainer>(); powerContainer.Charge = Math.Min(powerContainer.Capacity * 0.9f, powerContainer.Charge); } } Money += GameMain.NilMod.CampaignSurvivalReward; SaveUtil.SaveGame(GameMain.GameSession.SavePath); lastSaveID += 1; } else { GameMain.NilMod.CampaignFails += 1; if (GameMain.NilMod.CampaignDefaultSaveName != "" && GameMain.Client == null) { if (GameMain.NilMod.CampaignFails > GameMain.NilMod.CampaignMaxFails) { GameMain.NilMod.CampaignFails = 0; CoroutineManager.StartCoroutine(ResetCampaignMode(), "ResetCampaign"); foreach (Client c in GameMain.Server.ConnectedClients) { NilMod.NilModEventChatter.SendServerMessage("Campaign Info: No more chances remain, the campaign is lost!", c); NilMod.NilModEventChatter.SendServerMessage("Starting a new campaign...", c); } GameMain.NetworkMember.AddChatMessage("Campaign Info: No more chances remain, the campaign is lost!", ChatMessageType.Server, "", null); GameMain.NetworkMember.AddChatMessage("Starting a new campaign...", ChatMessageType.Server, "", null); } else { if ((GameMain.NilMod.CampaignMaxFails - GameMain.NilMod.CampaignFails) < 3) { foreach (Client c in GameMain.Server.ConnectedClients) { NilMod.NilModEventChatter.SendServerMessage("Campaign Info: There are " + (GameMain.NilMod.CampaignMaxFails - GameMain.NilMod.CampaignFails) + " Attempts remaining on this save unless you start pulling off some success!", c); } GameMain.NetworkMember.AddChatMessage("Campaign: There are " + (GameMain.NilMod.CampaignMaxFails - GameMain.NilMod.CampaignFails) + " Attempts remaining on this save unless you start pulling off some success!", ChatMessageType.Server, "", null); } //Reload the game and such SaveUtil.LoadGame(GameMain.GameSession.SavePath); #if CLIENT GameMain.NetLobbyScreen.modeList.Select(2, true); #endif GameMain.GameSession.Map.SelectRandomLocation(true); LastSaveID += 1; } } } //If its campaign start, add the starter items to the buy menu if (GameMain.NilMod.CampaignAutoPurchase) { var campaign = ((MultiPlayerCampaign)GameMain.GameSession.GameMode); if (GameMain.NilMod.CampaignStart) { AutoPurchaseNew(); } //If its a round that wasn't the first, buy the mid-round items! else { AutoPurchaseExisting(); } } }
/// <summary> /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime) { Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds; int updateIterations = (int)Math.Floor(Timing.Accumulator / Timing.Step); if (Timing.Accumulator > Timing.Step * 6.0) { //if the game's running too slowly then we have no choice //but to skip a bunch of steps //otherwise it snowballs and becomes unplayable Timing.Accumulator = Timing.Step; } CrossThread.ProcessTasks(); PlayerInput.UpdateVariable(); if (SoundManager != null) { if (WindowActive || !Config.MuteOnFocusLost) { SoundManager.ListenerGain = SoundManager.CompressionDynamicRangeGain; } else { SoundManager.ListenerGain = 0.0f; } } while (Timing.Accumulator >= Timing.Step) { Timing.TotalTime += Timing.Step; Stopwatch sw = new Stopwatch(); sw.Start(); fixedTime.IsRunningSlowly = gameTime.IsRunningSlowly; TimeSpan addTime = new TimeSpan(0, 0, 0, 0, 16); fixedTime.ElapsedGameTime = addTime; fixedTime.TotalGameTime.Add(addTime); base.Update(fixedTime); PlayerInput.Update(Timing.Step); if (loadingScreenOpen) { //reset accumulator if loading // -> less choppy loading screens because the screen is rendered after each update // -> no pause caused by leftover time in the accumulator when starting a new shift ResetFrameTime(); if (!TitleScreen.PlayingSplashScreen) { SoundPlayer.Update((float)Timing.Step); } if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen && (!waitForKeyHit || ((PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.PrimaryMouseButtonClicked()) && WindowActive))) { loadingScreenOpen = false; } #if DEBUG if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen && (Config.AutomaticQuickStartEnabled || Config.AutomaticCampaignLoadEnabled) && FirstLoad && !PlayerInput.KeyDown(Keys.LeftShift)) { loadingScreenOpen = false; FirstLoad = false; if (Config.AutomaticQuickStartEnabled) { MainMenuScreen.QuickStart(); } else if (Config.AutomaticCampaignLoadEnabled) { IEnumerable <string> saveFiles = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Singleplayer); if (saveFiles.Count() > 0) { saveFiles = saveFiles.OrderBy(file => File.GetLastWriteTime(file)); try { SaveUtil.LoadGame(saveFiles.Last()); } catch (Exception e) { DebugConsole.ThrowError("Loading save \"" + saveFiles.Last() + "\" failed", e); return; } } } } #endif if (!hasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine)) { throw new LoadingException(loadingCoroutine.Exception); } } else if (hasLoaded) { if (ConnectLobby != 0) { if (Client != null) { Client.Disconnect(); Client = null; GameMain.MainMenuScreen.Select(); } Steam.SteamManager.JoinLobby(ConnectLobby, true); ConnectLobby = 0; ConnectEndpoint = null; ConnectName = null; } else if (!string.IsNullOrWhiteSpace(ConnectEndpoint)) { if (Client != null) { Client.Disconnect(); Client = null; GameMain.MainMenuScreen.Select(); } UInt64 serverSteamId = SteamManager.SteamIDStringToUInt64(ConnectEndpoint); Client = new GameClient(Config.PlayerName, serverSteamId != 0 ? null : ConnectEndpoint, serverSteamId, string.IsNullOrWhiteSpace(ConnectName) ? ConnectEndpoint : ConnectName); ConnectLobby = 0; ConnectEndpoint = null; ConnectName = null; } SoundPlayer.Update((float)Timing.Step); if (PlayerInput.KeyHit(Keys.Escape) && WindowActive) { // Check if a text input is selected. if (GUI.KeyboardDispatcher.Subscriber != null) { if (GUI.KeyboardDispatcher.Subscriber is GUITextBox textBox) { textBox.Deselect(); } GUI.KeyboardDispatcher.Subscriber = null; } //if a verification prompt (are you sure you want to x) is open, close it else if (GUIMessageBox.VisibleBox as GUIMessageBox != null && GUIMessageBox.VisibleBox.UserData as string == "verificationprompt") { ((GUIMessageBox)GUIMessageBox.VisibleBox).Close(); } else if (GUIMessageBox.VisibleBox?.UserData is RoundSummary roundSummary && roundSummary.ContinueButton != null && roundSummary.ContinueButton.Visible) { GUIMessageBox.MessageBoxes.Remove(GUIMessageBox.VisibleBox); } else if (Tutorial.Initialized && Tutorial.ContentRunning) { (GameSession.GameMode as TutorialMode).Tutorial.CloseActiveContentGUI(); } else if (GameSession.IsTabMenuOpen) { gameSession.ToggleTabMenu(); } else if (GUI.PauseMenuOpen) { GUI.TogglePauseMenu(); } //open the pause menu if not controlling a character OR if the character has no UIs active that can be closed with ESC else if ((Character.Controlled == null || !itemHudActive()) //TODO: do we need to check Inventory.SelectedSlot? && Inventory.SelectedSlot == null && CharacterHealth.OpenHealthWindow == null && !CrewManager.IsCommandInterfaceOpen && !(Screen.Selected is SubEditorScreen editor && !editor.WiringMode && Character.Controlled?.SelectedConstruction != null)) { // Otherwise toggle pausing, unless another window/interface is open. GUI.TogglePauseMenu(); }
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); }
public CampaignSetupUI(bool isMultiplayer, GUIComponent newGameContainer, GUIComponent loadGameContainer) { this.isMultiplayer = isMultiplayer; this.newGameContainer = newGameContainer; this.loadGameContainer = loadGameContainer; new GUITextBlock(new Rectangle(0, 0, 0, 30), TextManager.Get("SelectedSub") + ":", null, null, Alignment.Left, "", newGameContainer); subList = new GUIListBox(new Rectangle(0, 30, 230, newGameContainer.Rect.Height - 100), "", newGameContainer); UpdateSubList(); new GUITextBlock(new Rectangle((int)(subList.Rect.Width + 20), 0, 100, 20), TextManager.Get("SaveName") + ": ", "", Alignment.Left, Alignment.Left, newGameContainer); saveNameBox = new GUITextBox(new Rectangle((int)(subList.Rect.Width + 30), 30, 180, 20), Alignment.TopLeft, "", newGameContainer); new GUITextBlock(new Rectangle((int)(subList.Rect.Width + 20), 60, 100, 20), TextManager.Get("MapSeed") + ": ", "", Alignment.Left, Alignment.Left, newGameContainer); seedBox = new GUITextBox(new Rectangle((int)(subList.Rect.Width + 30), 90, 180, 20), Alignment.TopLeft, "", newGameContainer); seedBox.Text = ToolBox.RandomSeed(8); var startButton = new GUIButton(new Rectangle(0, 0, 100, 30), TextManager.Get("StartCampaignButton"), Alignment.BottomRight, "", newGameContainer); startButton.OnClicked = (GUIButton btn, object userData) => { if (string.IsNullOrWhiteSpace(saveNameBox.Text)) { saveNameBox.Flash(Color.Red); return(false); } Submarine selectedSub = subList.SelectedData as Submarine; if (selectedSub == null) { return(false); } string savePath = SaveUtil.CreateSavePath(isMultiplayer ? SaveUtil.SaveType.Multiplayer : SaveUtil.SaveType.Singleplayer, saveNameBox.Text); if (selectedSub.HasTag(SubmarineTag.Shuttle) || !selectedSub.CompatibleContentPackages.Contains(GameMain.SelectedPackage.Name)) { if (!selectedSub.CompatibleContentPackages.Contains(GameMain.SelectedPackage.Name)) { var msgBox = new GUIMessageBox(TextManager.Get("ContentPackageMismatch"), TextManager.Get("ContentPackageMismatchWarning") .Replace("[selectedcontentpackage]", GameMain.SelectedPackage.Name), new string[] { TextManager.Get("Yes"), TextManager.Get("No") }); msgBox.Buttons[0].OnClicked = msgBox.Close; msgBox.Buttons[0].OnClicked += (button, obj) => { if (GUIMessageBox.MessageBoxes.Count == 0) { StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text); } return(true); }; msgBox.Buttons[1].OnClicked = msgBox.Close; } if (selectedSub.HasTag(SubmarineTag.Shuttle)) { var msgBox = new GUIMessageBox(TextManager.Get("ShuttleSelected"), TextManager.Get("ShuttleWarning"), new string[] { TextManager.Get("Yes"), TextManager.Get("No") }); msgBox.Buttons[0].OnClicked = (button, obj) => { StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text); return(true); }; msgBox.Buttons[0].OnClicked += msgBox.Close; msgBox.Buttons[1].OnClicked = msgBox.Close; return(false); } } else { StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text); } return(true); }; UpdateLoadMenu(); }
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); if (success) { foreach (Client c in GameMain.Server.ConnectedClients) { if (c.Character?.HasAbilityFlag(AbilityFlags.RetainExperienceForNewCharacter) ?? false) { (GameMain.GameSession?.GameMode as MultiPlayerCampaign)?.SaveExperiencePoints(c); } } } GameMain.GameSession.EndRound("", traitorResults, transitionType); //-------------------------------------- if (success) { SavePlayers(); 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; 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); PendingSubmarineSwitch = null; } 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 void CreateDefaultSaveName() { string savePath = SaveUtil.CreateSavePath(isMultiplayer ? SaveUtil.SaveType.Multiplayer : SaveUtil.SaveType.Singleplayer); saveNameBox.Text = Path.GetFileNameWithoutExtension(savePath); }
private bool FinishSetup(GUIButton btn, object userdata) { if (string.IsNullOrWhiteSpace(saveNameBox.Text)) { saveNameBox.Flash(GUI.Style.Red); return(false); } SubmarineInfo selectedSub = null; if (!(subList.SelectedData is SubmarineInfo)) { return(false); } selectedSub = subList.SelectedData as SubmarineInfo; if (selectedSub.SubmarineClass == SubmarineClass.Undefined) { new GUIMessageBox(TextManager.Get("error"), TextManager.Get("undefinedsubmarineselected")); return(false); } if (string.IsNullOrEmpty(selectedSub.MD5Hash.Hash)) { ((GUITextBlock)subList.SelectedComponent).TextColor = Color.DarkRed * 0.8f; subList.SelectedComponent.CanBeFocused = false; subList.Deselect(); return(false); } string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Singleplayer, saveNameBox.Text); bool hasRequiredContentPackages = selectedSub.RequiredContentPackagesInstalled; CampaignSettings settings = new CampaignSettings(); settings.RadiationEnabled = EnableRadiationToggle?.Selected ?? false; if (MaxMissionCountText != null && Int32.TryParse(MaxMissionCountText.Text, out int missionCount)) { settings.MaxMissionCount = missionCount; } else { settings.MaxMissionCount = CampaignSettings.DefaultMaxMissionCount; } if (selectedSub.HasTag(SubmarineTag.Shuttle) || !hasRequiredContentPackages) { if (!hasRequiredContentPackages) { var msgBox = new GUIMessageBox(TextManager.Get("ContentPackageMismatch"), TextManager.GetWithVariable("ContentPackageMismatchWarning", "[requiredcontentpackages]", string.Join(", ", selectedSub.RequiredContentPackages)), new string[] { TextManager.Get("Yes"), TextManager.Get("No") }); msgBox.Buttons[0].OnClicked = msgBox.Close; msgBox.Buttons[0].OnClicked += (button, obj) => { if (GUIMessageBox.MessageBoxes.Count == 0) { StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings); } return(true); }; msgBox.Buttons[1].OnClicked = msgBox.Close; } if (selectedSub.HasTag(SubmarineTag.Shuttle)) { var msgBox = new GUIMessageBox(TextManager.Get("ShuttleSelected"), TextManager.Get("ShuttleWarning"), new string[] { TextManager.Get("Yes"), TextManager.Get("No") }); msgBox.Buttons[0].OnClicked = (button, obj) => { StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings); return(true); }; msgBox.Buttons[0].OnClicked += msgBox.Close; msgBox.Buttons[1].OnClicked = msgBox.Close; return(false); } } else { StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings); } return(true); }
public void UpdateLoadMenu(IEnumerable <string> saveFiles = null) { prevSaveFiles?.Clear(); loadGameContainer.ClearChildren(); if (saveFiles == null) { saveFiles = SaveUtil.GetSaveFiles(isMultiplayer ? SaveUtil.SaveType.Multiplayer : SaveUtil.SaveType.Singleplayer); } var leftColumn = new GUILayoutGroup(new RectTransform(isMultiplayer ? new Vector2(1.0f, 0.85f) : new Vector2(0.5f, 1.0f), loadGameContainer.RectTransform), childAnchor: Anchor.TopCenter) { Stretch = true, RelativeSpacing = 0.03f }; saveList = new GUIListBox(new RectTransform(Vector2.One, leftColumn.RectTransform)) { OnSelected = SelectSaveFile }; if (!isMultiplayer) { new GUIButton(new RectTransform(new Vector2(0.6f, 0.08f), leftColumn.RectTransform), TextManager.Get("showinfolder")) { OnClicked = (btn, userdata) => { try { ToolBox.OpenFileWithShell(SaveUtil.SaveFolder); } catch (Exception e) { new GUIMessageBox( TextManager.Get("error"), TextManager.GetWithVariables("showinfoldererror", new string[] { "[folder]", "[errormessage]" }, new string[] { SaveUtil.SaveFolder, e.Message })); } return(true); } }; } foreach (string saveFile in saveFiles) { string fileName = saveFile; string subName = ""; string saveTime = ""; string contentPackageStr = ""; var saveFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.1f), saveList.Content.RectTransform) { MinSize = new Point(0, 45) }, style: "ListBoxElement") { UserData = saveFile }; var nameText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform), "") { CanBeFocused = false }; if (!isMultiplayer) { nameText.Text = Path.GetFileNameWithoutExtension(saveFile); XDocument doc = SaveUtil.LoadGameSessionDoc(saveFile); if (doc?.Root == null) { DebugConsole.ThrowError("Error loading save file \"" + saveFile + "\". The file may be corrupted."); nameText.TextColor = GUI.Style.Red; continue; } if (doc.Root.GetChildElement("multiplayercampaign") != null) { //multiplayer campaign save in the wrong folder -> don't show the save saveList.Content.RemoveChild(saveFrame); continue; } subName = doc.Root.GetAttributeString("submarine", ""); saveTime = doc.Root.GetAttributeString("savetime", ""); contentPackageStr = doc.Root.GetAttributeString("selectedcontentpackages", ""); prevSaveFiles?.Add(saveFile); } else { string[] splitSaveFile = saveFile.Split(';'); saveFrame.UserData = splitSaveFile[0]; fileName = nameText.Text = Path.GetFileNameWithoutExtension(splitSaveFile[0]); prevSaveFiles?.Add(fileName); if (splitSaveFile.Length > 1) { subName = splitSaveFile[1]; } if (splitSaveFile.Length > 2) { saveTime = splitSaveFile[2]; } if (splitSaveFile.Length > 3) { contentPackageStr = splitSaveFile[3]; } } if (!string.IsNullOrEmpty(saveTime) && long.TryParse(saveTime, out long unixTime)) { DateTime time = ToolBox.Epoch.ToDateTime(unixTime); saveTime = time.ToString(); } if (!string.IsNullOrEmpty(contentPackageStr)) { List <string> contentPackagePaths = contentPackageStr.Split('|').ToList(); if (!GameSession.IsCompatibleWithSelectedContentPackages(contentPackagePaths, out string errorMsg)) { nameText.TextColor = GUI.Style.Red; saveFrame.ToolTip = string.Join("\n", errorMsg, TextManager.Get("campaignmode.contentpackagemismatchwarning")); } } new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform, Anchor.BottomLeft), text: subName, font: GUI.SmallFont) { CanBeFocused = false, UserData = fileName }; new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), saveFrame.RectTransform), text: saveTime, textAlignment: Alignment.Right, font: GUI.SmallFont) { CanBeFocused = false, UserData = fileName }; } saveList.Content.RectTransform.SortChildren((c1, c2) => { string file1 = c1.GUIComponent.UserData as string; string file2 = c2.GUIComponent.UserData as string; DateTime file1WriteTime = DateTime.MinValue; DateTime file2WriteTime = DateTime.MinValue; try { file1WriteTime = File.GetLastWriteTime(file1); } catch { //do nothing - DateTime.MinValue will be used and the element will get sorted at the bottom of the list }; try { file2WriteTime = File.GetLastWriteTime(file2); } catch { //do nothing - DateTime.MinValue will be used and the element will get sorted at the bottom of the list }; return(file2WriteTime.CompareTo(file1WriteTime)); }); loadGameButton = new GUIButton(new RectTransform(new Vector2(0.45f, 0.12f), loadGameContainer.RectTransform, Anchor.BottomRight), TextManager.Get("LoadButton")) { OnClicked = (btn, obj) => { if (string.IsNullOrWhiteSpace(saveList.SelectedData as string)) { return(false); } LoadGame?.Invoke(saveList.SelectedData as string); if (isMultiplayer) { CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup"); } return(true); }, Enabled = false }; deleteMpSaveButton = new GUIButton(new RectTransform(new Vector2(0.45f, 0.12f), loadGameContainer.RectTransform, Anchor.BottomLeft), TextManager.Get("Delete"), style: "GUIButtonSmall") { OnClicked = DeleteSave, Visible = false }; }
public override void End(string endMessage = "") { isRunning = false; #if CLIENT if (GameMain.Client != null) { GameMain.GameSession.EndRound(""); GameMain.GameSession.CrewManager.EndRound(); return; } #endif #if SERVER lastUpdateID++; bool success = GameMain.Server.ConnectedClients.Any(c => c.InGame && c.Character != null && !c.Character.IsDead); #if CLIENT success = success || (GameMain.Server.Character != null && !GameMain.Server.Character.IsDead); #endif /*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(""); foreach (Client c in GameMain.Server.ConnectedClients) { if (c.HasSpawned) { //client has spawned this round -> remove old data (and replace with new one if the client still has an alive character) characterData.RemoveAll(cd => cd.MatchesClient(c)); } if (c.Character?.Info != null && !c.Character.IsDead) { characterData.Add(new CharacterCampaignData(c)); } } //remove all items that are in someone's inventory foreach (Character c in Character.CharacterList) { c.Inventory?.DeleteAllItems(); } #if CLIENT GameMain.GameSession.CrewManager.EndRound(); #endif if (success) { bool atEndPosition = Submarine.MainSub.AtEndPosition; /*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(); //select a random location to make sure we've got some destination //to head towards even if the host/clients don't select anything map.SelectRandomLocation(true); } map.ProgressWorld(); SaveUtil.SaveGame(GameMain.GameSession.SavePath); } #endif }
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"); // Recharge headset batteries var headset = c.Inventory.FindItemByIdentifier("headset"); if (headset != null) { var battery = headset.OwnInventory.FindItemByTag("loadable"); if (battery != null) { battery.Condition = battery.MaxCondition; } } 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.RemoveAll(c => c?.UserData as string == "roundsummary"); 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.RemoveAll(c => c?.UserData as string == "roundsummary"); return(true); }; } } CrewManager.EndRound(); for (int i = Character.CharacterList.Count - 1; i >= 0; i--) { Character.CharacterList[i].Remove(); } Submarine.Unload(); GameMain.LobbyScreen.Select(); }
public static GUIComponent StartCampaignSetup() { GUIFrame background = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: "GUIBackgroundBlocker"); GUIFrame setupBox = new GUIFrame(new RectTransform(new Vector2(0.25f, 0.45f), background.RectTransform, Anchor.Center) { MinSize = new Point(500, 500) }); var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), setupBox.RectTransform, Anchor.Center)) { Stretch = true }; new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), paddedFrame.RectTransform, Anchor.TopCenter), TextManager.Get("CampaignSetup"), font: GUI.LargeFont); var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.07f), paddedFrame.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.1f) }, isHorizontal: true) { RelativeSpacing = 0.02f }; var campaignContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.8f), paddedFrame.RectTransform, Anchor.BottomLeft), style: null); var newCampaignContainer = new GUIFrame(new RectTransform(Vector2.One, campaignContainer.RectTransform, Anchor.BottomLeft), style: null); var loadCampaignContainer = new GUIFrame(new RectTransform(Vector2.One, campaignContainer.RectTransform, Anchor.BottomLeft), style: null); var campaignSetupUI = new CampaignSetupUI(true, newCampaignContainer, loadCampaignContainer); var newCampaignButton = new GUIButton(new RectTransform(new Vector2(0.3f, 1.0f), buttonContainer.RectTransform), TextManager.Get("NewCampaign")) { OnClicked = (btn, obj) => { newCampaignContainer.Visible = true; loadCampaignContainer.Visible = false; return(true); } }; var loadCampaignButton = new GUIButton(new RectTransform(new Vector2(0.3f, 1.00f), buttonContainer.RectTransform), TextManager.Get("LoadCampaign")) { OnClicked = (btn, obj) => { newCampaignContainer.Visible = false; loadCampaignContainer.Visible = true; return(true); } }; loadCampaignContainer.Visible = false; campaignSetupUI.StartNewGame = (Submarine sub, string saveName, string mapSeed) => { GameMain.GameSession = new GameSession(new Submarine(sub.FilePath, ""), saveName, GameModePreset.List.Find(g => g.Identifier == "multiplayercampaign")); var campaign = ((MultiPlayerCampaign)GameMain.GameSession.GameMode); campaign.GenerateMap(mapSeed); campaign.SetDelegates(); background.Visible = false; GameMain.NetLobbyScreen.ToggleCampaignMode(true); campaign.Map.SelectRandomLocation(true); SaveUtil.SaveGame(GameMain.GameSession.SavePath); campaign.LastSaveID++; }; campaignSetupUI.LoadGame = (string fileName) => { SaveUtil.LoadGame(fileName); if (!(GameMain.GameSession.GameMode is MultiPlayerCampaign)) { DebugConsole.ThrowError("Failed to load the campaign. The save file appears to be for a single player campaign."); return; } var campaign = ((MultiPlayerCampaign)GameMain.GameSession.GameMode); campaign.LastSaveID++; background.Visible = false; GameMain.NetLobbyScreen.ToggleCampaignMode(true); campaign.Map.SelectRandomLocation(true); }; var cancelButton = new GUIButton(new RectTransform(new Vector2(0.2f, 0.05f), paddedFrame.RectTransform, Anchor.BottomLeft), TextManager.Get("Cancel")) { OnClicked = (btn, obj) => { //find the first mode that's not multiplayer campaign and switch to that background.Visible = false; int otherModeIndex = 0; for (otherModeIndex = 0; otherModeIndex < GameMain.NetLobbyScreen.ModeList.Content.CountChildren; otherModeIndex++) { if (GameMain.NetLobbyScreen.ModeList.Content.GetChild(otherModeIndex).UserData is MultiPlayerCampaign) { continue; } break; } GameMain.NetLobbyScreen.SelectMode(otherModeIndex); return(true); } }; return(background); }