예제 #1
0
        //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;
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
 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
            };
        }
예제 #7
0
        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();
        }
예제 #8
0
        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();
        }
예제 #9
0
        //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;
            }
        }
예제 #10
0
        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);
            };
        }
예제 #11
0
        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
            };
        }
예제 #12
0
        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;
            }
        }
예제 #13
0
        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);
        }
예제 #14
0
        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);
        }
예제 #15
0
        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);
            }
        }
예제 #16
0
        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);
        }
예제 #18
0
        //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;
            }
        }
예제 #19
0
        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();
                }
            }
        }
예제 #21
0
        /// <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();
                        }
예제 #22
0
        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);
        }
예제 #23
0
        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();
        }
예제 #24
0
        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);
        }
예제 #25
0
        public void CreateDefaultSaveName()
        {
            string savePath = SaveUtil.CreateSavePath(isMultiplayer ? SaveUtil.SaveType.Multiplayer : SaveUtil.SaveType.Singleplayer);

            saveNameBox.Text = Path.GetFileNameWithoutExtension(savePath);
        }
예제 #26
0
        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);
        }
예제 #27
0
        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();
        }
예제 #30
0
        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);
        }