Exemple #1
0
        private bool CreateRenamingComponent(GUIButton button, object userData)
        {
            if (!HasPermission || !(userData is CharacterInfo characterInfo))
            {
                return(false);
            }
            var outerGlowFrame = new GUIFrame(new RectTransform(new Vector2(1.25f, 1.25f), parentComponent.RectTransform, Anchor.Center),
                                              style: "OuterGlow", color: Color.Black * 0.7f);
            var frame = new GUIFrame(new RectTransform(new Vector2(0.33f, 0.4f), outerGlowFrame.RectTransform, anchor: Anchor.Center)
            {
                MaxSize = new Point(400, 300).Multiply(GUI.Scale)
            });
            var layoutGroup = new GUILayoutGroup(new RectTransform((frame.Rect.Size - GUIStyle.ItemFrameMargin).Multiply(new Vector2(0.75f, 1.0f)), frame.RectTransform, anchor: Anchor.Center), childAnchor: Anchor.TopCenter)
            {
                RelativeSpacing = 0.02f,
                Stretch         = true
            };

            new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), layoutGroup.RectTransform), TextManager.Get("campaigncrew.givenickname"), font: GUI.SubHeadingFont, textAlignment: Alignment.Center, wrap: true);
            var groupElementSize = new Vector2(1.0f, 0.25f);
            var nameBox          = new GUITextBox(new RectTransform(groupElementSize, layoutGroup.RectTransform))
            {
                MaxTextLength = Client.MaxNameLength
            };

            new GUIButton(new RectTransform(groupElementSize, layoutGroup.RectTransform), text: TextManager.Get("confirm"))
            {
                OnClicked = (button, userData) =>
                {
                    if (RenameCharacter(characterInfo, nameBox.Text?.Trim()))
                    {
                        parentComponent.RemoveChild(outerGlowFrame);
                        return(true);
                    }
                    else
                    {
                        nameBox.Flash(color: Color.Red);
                        return(false);
                    }
                }
            };
            new GUIButton(new RectTransform(groupElementSize, layoutGroup.RectTransform), text: TextManager.Get("cancel"))
            {
                OnClicked = (button, userData) =>
                {
                    parentComponent.RemoveChild(outerGlowFrame);
                    return(true);
                }
            };
            layoutGroup.Recalculate();
            return(true);
        }
Exemple #2
0
        partial void InitProjSpecific()
        {
            var buttonContainer = new GUILayoutGroup(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ButtonAreaTop, GUICanvas.Instance),
                                                     isHorizontal: true, childAnchor: Anchor.CenterRight)
            {
                CanBeFocused = false
            };

            int buttonHeight = (int)(GUI.Scale * 40);
            int buttonWidth  = GUI.IntScale(450);

            endRoundButton = new GUIButton(HUDLayoutSettings.ToRectTransform(new Rectangle((GameMain.GraphicsWidth / 2) - (buttonWidth / 2), HUDLayoutSettings.ButtonAreaTop.Center.Y - (buttonHeight / 2), buttonWidth, buttonHeight), GUICanvas.Instance),
                                           TextManager.Get("EndRound"), textAlignment: Alignment.Center, style: "EndRoundButton")
            {
                Pulse     = true,
                TextBlock =
                {
                    Shadow              = true,
                    AutoScaleHorizontal = true
                },
                OnClicked = (btn, userdata) =>
                {
                    var availableTransition = GetAvailableTransition(out _, out _);
                    if (Character.Controlled != null &&
                        availableTransition == TransitionType.ReturnToPreviousLocation &&
                        Character.Controlled?.Submarine == Level.Loaded?.StartOutpost)
                    {
                        GameMain.Client.RequestStartRound();
                    }
                    else if (Character.Controlled != null &&
                             availableTransition == TransitionType.ProgressToNextLocation &&
                             Character.Controlled?.Submarine == Level.Loaded?.EndOutpost)
                    {
                        GameMain.Client.RequestStartRound();
                    }
                    else
                    {
                        ShowCampaignUI = true;
                        if (CampaignUI == null)
                        {
                            InitCampaignUI();
                        }
                        CampaignUI.SelectTab(InteractionType.Map);
                    }
                    return(true);
                }
            };
            buttonContainer.Recalculate();
        }
            static void RecalculateLastMessage(GUIListBox conversationList, bool append)
            {
                if (conversationList.Content.Children.LastOrDefault() is GUILayoutGroup lastElement)
                {
                    GUILayoutGroup textLayout = lastElement.GetChild <GUILayoutGroup>();

                    if (textLayout != null)
                    {
                        if (lastElement.Rect.Size.Y < textLayout.Rect.Size.Y && !append)
                        {
                            lastElement.RectTransform.MinSize = textLayout.Rect.Size;
                        }

                        int textHeight = textLayout.Children.Sum(c => c.Rect.Height);
                        textLayout.RectTransform.MaxSize = new Point(lastElement.RectTransform.MaxSize.X, textHeight);
                        textLayout.Recalculate();
                    }
                    int sumHeight = lastElement.Children.Sum(c => c.Rect.Height);
                    lastElement.RectTransform.MaxSize = new Point(lastElement.RectTransform.MaxSize.X, sumHeight);
                    lastElement.Recalculate();
                    conversationList.RecalculateChildren();

                    if (!append || textLayout == null)
                    {
                        return;
                    }

                    foreach (GUIComponent child in textLayout.Children)
                    {
                        conversationList.UpdateScrollBarSize();
                        float wait = conversationList.BarSize < 1.0f ? 0.5f : 0.0f;

                        if (child is GUITextBlock)
                        {
                            child.FadeIn(wait, 0.5f);
                        }

                        if (child is GUIButton btn)
                        {
                            btn.FadeIn(wait, 1.0f);
                            btn.TextBlock.FadeIn(wait, 0.5f);
                        }
                    }
                }
            }
        public GUIFrame CreateSummaryFrame(GameSession gameSession, string endMessage, List <TraitorMissionResult> traitorResults, CampaignMode.TransitionType transitionType = CampaignMode.TransitionType.None)
        {
            bool singleplayer = GameMain.NetworkMember == null;
            bool gameOver     =
                gameSession.GameMode.IsSinglePlayer ?
                gameSession.CrewManager.GetCharacters().All(c => c.IsDead || c.IsIncapacitated) :
                gameSession.CrewManager.GetCharacters().All(c => c.IsDead || c.IsIncapacitated || c.IsBot);

            if (!singleplayer)
            {
                SoundPlayer.OverrideMusicType     = gameOver ? "crewdead" : "endround";
                SoundPlayer.OverrideMusicDuration = 18.0f;
            }

            GUIFrame background = new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas, Anchor.Center), style: "GUIBackgroundBlocker")
            {
                UserData = this
            };

            List <GUIComponent> rightPanels = new List <GUIComponent>();

            int minWidth = 400, minHeight = 350;
            int padding = GUI.IntScale(25.0f);

            //crew panel -------------------------------------------------------------------------------

            GUIFrame crewFrame      = new GUIFrame(new RectTransform(new Vector2(0.35f, 0.55f), background.RectTransform, Anchor.TopCenter, minSize: new Point(minWidth, minHeight)));
            GUIFrame crewFrameInner = new GUIFrame(new RectTransform(new Point(crewFrame.Rect.Width - padding * 2, crewFrame.Rect.Height - padding * 2), crewFrame.RectTransform, Anchor.Center), style: "InnerFrame");

            var crewContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), crewFrameInner.RectTransform, Anchor.Center))
            {
                Stretch = true
            };

            var crewHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), crewContent.RectTransform),
                                              TextManager.Get("crew"), textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont);

            crewHeader.RectTransform.MinSize = new Point(0, GUI.IntScale(crewHeader.Rect.Height * 2.0f));

            CreateCrewList(crewContent, gameSession.CrewManager.GetCharacterInfos().Where(c => c.TeamID != Character.TeamType.Team2));

            //another crew frame for the 2nd team in combat missions
            if (gameSession.Mission is CombatMission)
            {
                crewHeader.Text = CombatMission.GetTeamName(Character.TeamType.Team1);
                GUIFrame crewFrame2 = new GUIFrame(new RectTransform(new Vector2(0.35f, 0.55f), background.RectTransform, Anchor.TopCenter, minSize: new Point(minWidth, minHeight)));
                rightPanels.Add(crewFrame2);
                GUIFrame crewFrameInner2 = new GUIFrame(new RectTransform(new Point(crewFrame2.Rect.Width - padding * 2, crewFrame2.Rect.Height - padding * 2), crewFrame2.RectTransform, Anchor.Center), style: "InnerFrame");
                var      crewContent2    = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), crewFrameInner2.RectTransform, Anchor.Center))
                {
                    Stretch = true
                };
                var crewHeader2 = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), crewContent2.RectTransform),
                                                   CombatMission.GetTeamName(Character.TeamType.Team2), textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont);
                crewHeader2.RectTransform.MinSize = new Point(0, GUI.IntScale(crewHeader2.Rect.Height * 2.0f));
                CreateCrewList(crewContent2, gameSession.CrewManager.GetCharacterInfos().Where(c => c.TeamID == Character.TeamType.Team2));
            }

            //header -------------------------------------------------------------------------------

            string       headerText      = GetHeaderText(gameOver, transitionType);
            GUITextBlock headerTextBlock = null;

            if (!string.IsNullOrEmpty(headerText))
            {
                headerTextBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), crewFrame.RectTransform, Anchor.TopLeft, Pivot.BottomLeft),
                                                   headerText, textAlignment: Alignment.BottomLeft, font: GUI.LargeFont, wrap: true);
            }

            //traitor panel -------------------------------------------------------------------------------

            if (traitorResults != null && traitorResults.Any())
            {
                GUIFrame traitorframe = new GUIFrame(new RectTransform(crewFrame.RectTransform.RelativeSize, background.RectTransform, Anchor.TopCenter, minSize: crewFrame.RectTransform.MinSize));
                rightPanels.Add(traitorframe);
                GUIFrame traitorframeInner = new GUIFrame(new RectTransform(new Point(traitorframe.Rect.Width - padding * 2, traitorframe.Rect.Height - padding * 2), traitorframe.RectTransform, Anchor.Center), style: "InnerFrame");

                var traitorContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), traitorframeInner.RectTransform, Anchor.Center))
                {
                    Stretch = true
                };

                var traitorHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), traitorContent.RectTransform),
                                                     TextManager.Get("traitors"), font: GUI.SubHeadingFont);
                traitorHeader.RectTransform.MinSize = new Point(0, GUI.IntScale(traitorHeader.Rect.Height * 2.0f));

                GUIListBox listBox = CreateCrewList(traitorContent, traitorResults.SelectMany(tr => tr.Characters.Select(c => c.Info)));

                foreach (var traitorResult in traitorResults)
                {
                    var traitorMission = TraitorMissionPrefab.List.Find(t => t.Identifier == traitorResult.MissionIdentifier);
                    if (traitorMission == null)
                    {
                        continue;
                    }

                    //spacing
                    new GUIFrame(new RectTransform(new Point(listBox.Content.Rect.Width, GUI.IntScale(25)), listBox.Content.RectTransform), style: null);

                    var traitorResultHorizontal = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.3f), listBox.Content.RectTransform), childAnchor: Anchor.CenterLeft, isHorizontal: true)
                    {
                        RelativeSpacing = 0.05f,
                        Stretch         = true
                    };

                    new GUIImage(new RectTransform(new Point(traitorResultHorizontal.Rect.Height), traitorResultHorizontal.RectTransform), traitorMission.Icon, scaleToFit: true)
                    {
                        Color = traitorMission.IconColor
                    };

                    string traitorMessage = TextManager.GetServerMessage(traitorResult.EndMessage);
                    if (!string.IsNullOrEmpty(traitorMessage))
                    {
                        var textContent = new GUILayoutGroup(new RectTransform(Vector2.One, traitorResultHorizontal.RectTransform))
                        {
                            RelativeSpacing = 0.025f
                        };

                        var traitorStatusText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), textContent.RectTransform),
                                                                 TextManager.Get(traitorResult.Success ? "missioncompleted" : "missionfailed"),
                                                                 textColor: traitorResult.Success ? GUI.Style.Green : GUI.Style.Red, font: GUI.SubHeadingFont);

                        var traitorMissionInfo = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), textContent.RectTransform),
                                                                  traitorMessage, font: GUI.SmallFont, wrap: true);

                        traitorResultHorizontal.Recalculate();

                        traitorStatusText.CalculateHeightFromText();
                        traitorMissionInfo.CalculateHeightFromText();
                        traitorStatusText.RectTransform.MinSize       = new Point(0, traitorStatusText.Rect.Height);
                        traitorMissionInfo.RectTransform.MinSize      = new Point(0, traitorMissionInfo.Rect.Height);
                        textContent.RectTransform.MaxSize             = new Point(int.MaxValue, (int)((traitorStatusText.Rect.Height + traitorMissionInfo.Rect.Height) * 1.2f));
                        traitorResultHorizontal.RectTransform.MinSize = new Point(0, traitorStatusText.RectTransform.MinSize.Y + traitorMissionInfo.RectTransform.MinSize.Y);
                    }
                }
            }

            //reputation panel -------------------------------------------------------------------------------

            if (gameMode is CampaignMode campaignMode)
            {
                GUIFrame reputationframe = new GUIFrame(new RectTransform(crewFrame.RectTransform.RelativeSize, background.RectTransform, Anchor.TopCenter, minSize: crewFrame.RectTransform.MinSize));
                rightPanels.Add(reputationframe);
                GUIFrame reputationframeInner = new GUIFrame(new RectTransform(new Point(reputationframe.Rect.Width - padding * 2, reputationframe.Rect.Height - padding * 2), reputationframe.RectTransform, Anchor.Center), style: "InnerFrame");

                var reputationContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), reputationframeInner.RectTransform, Anchor.Center))
                {
                    Stretch = true
                };

                var reputationHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), reputationContent.RectTransform),
                                                        TextManager.Get("reputation"), textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont);
                reputationHeader.RectTransform.MinSize = new Point(0, GUI.IntScale(reputationHeader.Rect.Height * 2.0f));

                GUIListBox reputationList = new GUIListBox(new RectTransform(Vector2.One, reputationContent.RectTransform))
                {
                    Padding = new Vector4(2, 5, 0, 0)
                };
                reputationList.ContentBackground.Color = Color.Transparent;

                if (startLocation.Type.HasOutpost && startLocation.Reputation != null)
                {
                    var iconStyle = GUI.Style.GetComponentStyle("LocationReputationIcon");
                    CreateReputationElement(
                        reputationList.Content,
                        startLocation.Name,
                        startLocation.Reputation.Value, startLocation.Reputation.NormalizedValue, initialLocationReputation,
                        startLocation.Type.Name, "",
                        iconStyle?.GetDefaultSprite(), startLocation.Type.GetPortrait(0), iconStyle?.Color ?? Color.White);
                }

                foreach (Faction faction in campaignMode.Factions)
                {
                    float initialReputation = faction.Reputation.Value;
                    if (initialFactionReputations.ContainsKey(faction))
                    {
                        initialReputation = initialFactionReputations[faction];
                    }
                    else
                    {
                        DebugConsole.AddWarning($"Could not determine reputation change for faction \"{faction.Prefab.Name}\" (faction was not present at the start of the round).");
                    }
                    CreateReputationElement(
                        reputationList.Content,
                        faction.Prefab.Name,
                        faction.Reputation.Value, faction.Reputation.NormalizedValue, initialReputation,
                        faction.Prefab.ShortDescription, faction.Prefab.Description,
                        faction.Prefab.Icon, faction.Prefab.BackgroundPortrait, faction.Prefab.IconColor);
                }

                float otherElementHeight   = 0.0f;
                float maxDescriptionHeight = 0.0f;
                foreach (GUIComponent child in reputationList.Content.Children)
                {
                    var descriptionElement = child.FindChild("description", recursive: true) as GUITextBlock;
                    maxDescriptionHeight = Math.Max(maxDescriptionHeight, descriptionElement.TextSize.Y * 1.1f);
                    otherElementHeight   = Math.Max(otherElementHeight, descriptionElement.Parent.Rect.Height - descriptionElement.TextSize.Y);
                }
                foreach (GUIComponent child in reputationList.Content.Children)
                {
                    var descriptionElement = child.FindChild("description", recursive: true) as GUITextBlock;
                    descriptionElement.RectTransform.MaxSize = new Point(int.MaxValue, (int)(maxDescriptionHeight));
                    child.RectTransform.MaxSize = new Point(int.MaxValue, (int)((maxDescriptionHeight + otherElementHeight) * 1.2f));
                    (descriptionElement?.Parent as GUILayoutGroup).Recalculate();
                }
            }

            //mission panel -------------------------------------------------------------------------------

            GUIFrame missionframe      = new GUIFrame(new RectTransform(new Vector2(0.39f, 0.22f), background.RectTransform, Anchor.TopCenter, minSize: new Point(minWidth, minHeight / 4)));
            GUIFrame missionframeInner = new GUIFrame(new RectTransform(new Point(missionframe.Rect.Width - padding * 2, missionframe.Rect.Height - padding * 2), missionframe.RectTransform, Anchor.Center), style: "InnerFrame");

            var missionContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), missionframeInner.RectTransform, Anchor.Center))
            {
                RelativeSpacing = 0.05f,
                Stretch         = true
            };

            if (!string.IsNullOrWhiteSpace(endMessage))
            {
                var endText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionContent.RectTransform),
                                               TextManager.GetServerMessage(endMessage), wrap: true);
                endText.RectTransform.MinSize = new Point(0, endText.Rect.Height);
                var line = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.1f), missionContent.RectTransform), style: "HorizontalLine");
                line.RectTransform.NonScaledSize = new Point(line.Rect.Width, GUI.IntScale(5.0f));
            }

            var missionContentHorizontal = new GUILayoutGroup(new RectTransform(Vector2.One, missionContent.RectTransform), childAnchor: Anchor.TopLeft, isHorizontal: true)
            {
                RelativeSpacing = 0.025f,
                Stretch         = true
            };

            Mission  displayedMission = selectedMission ?? startLocation.SelectedMission;
            string   missionMessage   = "";
            GUIImage missionIcon;

            if (displayedMission != null)
            {
                missionMessage =
                    displayedMission == selectedMission ?
                    displayedMission.Completed ? displayedMission.SuccessMessage : displayedMission.FailureMessage :
                    displayedMission.Description;
                missionIcon = new GUIImage(new RectTransform(new Point(missionContentHorizontal.Rect.Height), missionContentHorizontal.RectTransform), displayedMission.Prefab.Icon, scaleToFit: true)
                {
                    Color = displayedMission.Prefab.IconColor
                };
                if (displayedMission == selectedMission)
                {
                    new GUIImage(new RectTransform(Vector2.One, missionIcon.RectTransform), displayedMission.Completed ? "MissionCompletedIcon" : "MissionFailedIcon", scaleToFit: true);
                }
            }
            else
            {
                missionIcon = new GUIImage(new RectTransform(new Point(missionContentHorizontal.Rect.Height), missionContentHorizontal.RectTransform), style: "NoMissionIcon", scaleToFit: true);
            }
            var missionTextContent = new GUILayoutGroup(new RectTransform(Vector2.One, missionContentHorizontal.RectTransform))
            {
                RelativeSpacing = 0.05f
            };

            missionContentHorizontal.Recalculate();
            missionContent.Recalculate();
            missionIcon.RectTransform.MinSize        = new Point(0, missionContentHorizontal.Rect.Height);
            missionTextContent.RectTransform.MaxSize = new Point(int.MaxValue, missionIcon.Rect.Width);

            GUITextBlock missionDescription = null;

            if (displayedMission == null)
            {
                new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
                                 TextManager.Get("nomission"), font: GUI.LargeFont);
            }
            else
            {
                new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
                                 TextManager.AddPunctuation(':', TextManager.Get("Mission"), displayedMission.Name), font: GUI.SubHeadingFont);
                missionDescription = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
                                                      missionMessage, wrap: true);
                if (displayedMission == selectedMission && displayedMission.Completed)
                {
                    string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", displayedMission.Reward));
                    new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
                                     TextManager.GetWithVariable("MissionReward", "[reward]", rewardText));
                }
            }

            ButtonArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), missionContent.RectTransform, Anchor.BottomCenter), isHorizontal: true, childAnchor: Anchor.BottomRight)
            {
                IgnoreLayoutGroups = true,
                RelativeSpacing    = 0.025f
            };

            ContinueButton = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), ButtonArea.RectTransform), TextManager.Get("Close"));
            ButtonArea.RectTransform.NonScaledSize = new Point(ButtonArea.Rect.Width, ContinueButton.Rect.Height);
            ButtonArea.RectTransform.IsFixedSize   = true;

            missionContent.Recalculate();
            //description overlapping with the buttons -> switch to small font
            if (missionDescription != null && missionDescription.Rect.Y + missionDescription.TextSize.Y > ButtonArea.Rect.Y)
            {
                missionDescription.Font = GUI.Style.SmallFont;
                //still overlapping -> shorten the text
                if (missionDescription.Rect.Y + missionDescription.TextSize.Y > ButtonArea.Rect.Y && missionDescription.WrappedText.Contains('\n'))
                {
                    missionDescription.ToolTip = missionDescription.Text;
                    missionDescription.Text    = missionDescription.WrappedText.Split('\n').First() + "...";
                }
            }

            // set layout -------------------------------------------------------------------

            int panelSpacing = GUI.IntScale(20);
            int totalHeight  = crewFrame.Rect.Height + panelSpacing + missionframe.Rect.Height;
            int totalWidth   = crewFrame.Rect.Width;

            crewFrame.RectTransform.AbsoluteOffset    = new Point(0, (GameMain.GraphicsHeight - totalHeight) / 2);
            missionframe.RectTransform.AbsoluteOffset = new Point(0, crewFrame.Rect.Bottom + panelSpacing);

            if (rightPanels.Any())
            {
                totalWidth = crewFrame.Rect.Width * 2 + panelSpacing;
                if (headerTextBlock != null)
                {
                    headerTextBlock.RectTransform.MinSize = new Point(totalWidth, 0);
                }
                crewFrame.RectTransform.AbsoluteOffset = new Point(-(crewFrame.Rect.Width + panelSpacing) / 2, crewFrame.RectTransform.AbsoluteOffset.Y);
                foreach (var rightPanel in rightPanels)
                {
                    rightPanel.RectTransform.AbsoluteOffset = new Point((rightPanel.Rect.Width + panelSpacing) / 2, crewFrame.RectTransform.AbsoluteOffset.Y);
                }
            }

            Frame = background;
            return(background);
        }
Exemple #5
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);
        }
Exemple #6
0
        public ServerListScreen()
        {
            GameMain.Instance.OnResolutionChanged += OnResolutionChanged;

            menu = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.85f), GUI.Canvas, Anchor.Center)
            {
                MinSize = new Point(GameMain.GraphicsHeight, 0)
            });

            var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.97f, 0.95f), menu.RectTransform, Anchor.Center))
            {
                RelativeSpacing = 0.02f,
                Stretch         = true
            };

            //-------------------------------------------------------------------------------------
            //Top row
            //-------------------------------------------------------------------------------------

            var topRow = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), paddedFrame.RectTransform))
            {
                Stretch = true
            };

            var title = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.33f), topRow.RectTransform), TextManager.Get("JoinServer"), font: GUI.LargeFont)
            {
                Padding        = Vector4.Zero,
                ForceUpperCase = true,
                AutoScale      = true
            };

            var infoHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.33f), topRow.RectTransform), isHorizontal: true)
            {
                RelativeSpacing = 0.05f, Stretch = true
            };

            var clientNameHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), infoHolder.RectTransform))
            {
                RelativeSpacing = 0.05f
            };

            new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), clientNameHolder.RectTransform), TextManager.Get("YourName"));
            clientNameBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.5f), clientNameHolder.RectTransform), "")
            {
                Text          = GameMain.Config.PlayerName,
                MaxTextLength = Client.MaxNameLength,
                OverflowClip  = true
            };

            if (string.IsNullOrEmpty(clientNameBox.Text))
            {
                clientNameBox.Text = SteamManager.GetUsername();
            }

            var ipBoxHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), infoHolder.RectTransform))
            {
                RelativeSpacing = 0.05f
            };

            new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), ipBoxHolder.RectTransform), TextManager.Get("ServerIP"));
            ipBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.5f), ipBoxHolder.RectTransform), "");
            ipBox.OnTextChanged += (textBox, text) => { joinButton.Enabled = !string.IsNullOrEmpty(text); return(true); };
            ipBox.OnSelected    += (sender, key) =>
            {
                if (sender.UserData is ServerInfo)
                {
                    sender.Text     = "";
                    sender.UserData = null;
                }
            };

            //-------------------------------------------------------------------------------------
            // Bottom row
            //-------------------------------------------------------------------------------------

            var bottomRow = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f - topRow.RectTransform.RelativeSize.Y),
                                                                 paddedFrame.RectTransform, Anchor.CenterRight))
            {
                Stretch = true
            };

            var serverListHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), bottomRow.RectTransform), isHorizontal: true)
            {
                Stretch = true
            };

            // filters -------------------------------------------

            var filters = new GUIFrame(new RectTransform(new Vector2(0.25f, 1.0f), serverListHolder.RectTransform, Anchor.Center), style: null)
            {
                Color        = new Color(12, 14, 15, 255) * 0.5f,
                OutlineColor = Color.Black
            };
            var filterToggle = new GUIButton(new RectTransform(new Vector2(0.02f, 1.0f), serverListHolder.RectTransform, Anchor.CenterRight)
            {
                MinSize = new Point(20, 0)
            }, style: "UIToggleButton")
            {
                OnClicked = (btn, userdata) =>
                {
                    filters.RectTransform.RelativeSize = new Vector2(0.25f, 1.0f);
                    filters.Visible            = !filters.Visible;
                    filters.IgnoreLayoutGroups = !filters.Visible;
                    serverListHolder.Recalculate();
                    btn.Children.ForEach(c => c.SpriteEffects = !filters.Visible ? SpriteEffects.None : SpriteEffects.FlipHorizontally);
                    return(true);
                }
            };

            filterToggle.Children.ForEach(c => c.SpriteEffects = SpriteEffects.FlipHorizontally);

            var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.99f), filters.RectTransform, Anchor.Center))
            {
                Stretch         = true,
                RelativeSpacing = 0.015f
            };

            var filterTitle = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), filterContainer.RectTransform), TextManager.Get("FilterServers"), font: GUI.LargeFont)
            {
                Padding   = Vector4.Zero,
                AutoScale = true
            };

            float elementHeight = 0.05f;

            var searchHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, elementHeight), filterContainer.RectTransform), isHorizontal: true)
            {
                Stretch = true
            };

            var searchTitle = new GUITextBlock(new RectTransform(new Vector2(0.001f, 1.0f), searchHolder.RectTransform), TextManager.Get("Search") + "...");

            searchBox                = new GUITextBox(new RectTransform(new Vector2(1.0f, 1.0f), searchHolder.RectTransform), "");
            searchBox.OnSelected    += (sender, userdata) => { searchTitle.Visible = false; };
            searchBox.OnDeselected  += (sender, userdata) => { searchTitle.Visible = true; };
            searchBox.OnTextChanged += (txtBox, txt) => { FilterServers(); return(true); };

            var filterHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), filterContainer.RectTransform))
            {
                RelativeSpacing = 0.005f
            };

            List <GUITextBlock> filterTextList = new List <GUITextBlock>();

            filterPassword = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filterHolder.RectTransform), TextManager.Get("FilterPassword"))
            {
                ToolTip    = TextManager.Get("FilterPassword"),
                OnSelected = (tickBox) => { FilterServers(); return(true); }
            };
            filterTextList.Add(filterPassword.TextBlock);
            filterIncompatible = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filterHolder.RectTransform), TextManager.Get("FilterIncompatibleServers"))
            {
                ToolTip    = TextManager.Get("FilterIncompatibleServers"),
                OnSelected = (tickBox) => { FilterServers(); return(true); }
            };
            filterTextList.Add(filterIncompatible.TextBlock);
            filterFull = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filterHolder.RectTransform), TextManager.Get("FilterFullServers"))
            {
                ToolTip    = TextManager.Get("FilterFullServers"),
                OnSelected = (tickBox) => { FilterServers(); return(true); }
            };
            filterTextList.Add(filterFull.TextBlock);
            filterEmpty = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filterHolder.RectTransform), TextManager.Get("FilterEmptyServers"))
            {
                ToolTip    = TextManager.Get("FilterEmptyServers"),
                OnSelected = (tickBox) => { FilterServers(); return(true); }
            };
            filterTextList.Add(filterEmpty.TextBlock);

            filterContainer.RectTransform.SizeChanged += () =>
            {
                filterContainer.RectTransform.RecalculateChildren(true, true);
                filterTextList.ForEach(t => t.Text = t.ToolTip);
                GUITextBlock.AutoScaleAndNormalize(filterTextList);
                if (filterTextList[0].TextScale < 0.8f)
                {
                    filterTextList.ForEach(t => t.TextScale = 1.0f);
                    filterTextList.ForEach(t => t.Text      = ToolBox.LimitString(t.Text, t.Font, (int)(filterContainer.Rect.Width * 0.8f)));
                }
            };

            // server list ---------------------------------------------------------------------

            var serverListContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), serverListHolder.RectTransform))
            {
                Stretch = true
            };

            labelHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.99f, 0.05f), serverListContainer.RectTransform)
            {
                MinSize = new Point(0, 15)
            },
                                             isHorizontal: true)
            {
                Stretch = true
            };

            for (int i = 0; i < columnRelativeWidth.Length; i++)
            {
                var btn = new GUIButton(new RectTransform(new Vector2(columnRelativeWidth[i], 1.0f), labelHolder.RectTransform),
                                        text: TextManager.Get(columnLabel[i]), textAlignment: Alignment.Center, style: null)
                {
                    Color          = new Color(12, 14, 15, 255) * 0.5f,
                    HoverColor     = new Color(12, 14, 15, 255) * 2.5f,
                    SelectedColor  = Color.Gray * 0.7f,
                    PressedColor   = Color.Gray * 0.7f,
                    OutlineColor   = Color.Black,
                    ToolTip        = TextManager.Get(columnLabel[i]),
                    ForceUpperCase = true,
                    UserData       = columnLabel[i],
                    OnClicked      = SortList
                };
                labelTexts.Add(btn.TextBlock);

                new GUIImage(new RectTransform(new Vector2(0.5f, 0.3f), btn.RectTransform, Anchor.BottomCenter, scaleBasis: ScaleBasis.BothHeight), style: "GUIButtonVerticalArrow", scaleToFit: true)
                {
                    CanBeFocused = false,
                    UserData     = "arrowup",
                    Visible      = false
                };
                new GUIImage(new RectTransform(new Vector2(0.5f, 0.3f), btn.RectTransform, Anchor.BottomCenter, scaleBasis: ScaleBasis.BothHeight), style: "GUIButtonVerticalArrow", scaleToFit: true)
                {
                    CanBeFocused  = false,
                    UserData      = "arrowdown",
                    SpriteEffects = SpriteEffects.FlipVertically,
                    Visible       = false
                };
            }

            serverList = new GUIListBox(new RectTransform(new Vector2(1.0f, 1.0f), serverListContainer.RectTransform, Anchor.Center))
            {
                ScrollBarVisible = true,
                OnSelected       = (btn, obj) =>
                {
                    if (obj is ServerInfo serverInfo)
                    {
                        joinButton.Enabled = true;
                        ipBox.UserData     = serverInfo;
                        ipBox.Text         = serverInfo.ServerName;
                        if (!serverPreview.Visible)
                        {
                            serverPreview.RectTransform.RelativeSize     = new Vector2(0.3f, 1.0f);
                            serverPreviewToggleButton.Visible            = true;
                            serverPreviewToggleButton.IgnoreLayoutGroups = false;
                            serverPreview.Visible            = true;
                            serverPreview.IgnoreLayoutGroups = false;
                            serverListHolder.Recalculate();
                        }
                        serverInfo.CreatePreviewWindow(serverPreview);
                        btn.Children.ForEach(c => c.SpriteEffects = serverPreview.Visible ? SpriteEffects.None : SpriteEffects.FlipHorizontally);
                    }
                    return(true);
                }
            };

            //server preview panel --------------------------------------------------

            serverPreviewToggleButton = new GUIButton(new RectTransform(new Vector2(0.02f, 1.0f), serverListHolder.RectTransform, Anchor.CenterRight)
            {
                MinSize = new Point(20, 0)
            }, style: "UIToggleButton")
            {
                Visible   = false,
                OnClicked = (btn, userdata) =>
                {
                    serverPreview.RectTransform.RelativeSize = new Vector2(0.25f, 1.0f);
                    serverPreview.Visible            = !serverPreview.Visible;
                    serverPreview.IgnoreLayoutGroups = !serverPreview.Visible;
                    serverListHolder.Recalculate();
                    btn.Children.ForEach(c => c.SpriteEffects = serverPreview.Visible ? SpriteEffects.None : SpriteEffects.FlipHorizontally);
                    return(true);
                }
            };

            serverPreview = new GUIFrame(new RectTransform(new Vector2(0.3f, 1.0f), serverListHolder.RectTransform, Anchor.Center), style: null)
            {
                Color              = new Color(12, 14, 15, 255) * 0.5f,
                OutlineColor       = Color.Black,
                IgnoreLayoutGroups = true,
                Visible            = false
            };

            // Spacing
            new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), bottomRow.RectTransform), style: null);

            var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.075f), bottomRow.RectTransform, Anchor.Center), isHorizontal: true)
            {
                RelativeSpacing = 0.02f,
                Stretch         = true
            };

            GUIButton button = new GUIButton(new RectTransform(new Vector2(0.25f, 0.9f), buttonContainer.RectTransform),
                                             TextManager.Get("Back"), style: "GUIButtonLarge")
            {
                OnClicked = GameMain.MainMenuScreen.ReturnToMainMenu
            };

            new GUIButton(new RectTransform(new Vector2(0.25f, 0.9f), buttonContainer.RectTransform),
                          TextManager.Get("ServerListRefresh"), style: "GUIButtonLarge")
            {
                OnClicked = (btn, userdata) => { RefreshServers(); return(true); }
            };

            /*var directJoinButton = new GUIButton(new RectTransform(new Vector2(0.25f, 0.9f), buttonContainer.RectTransform),
             *  TextManager.Get("serverlistdirectjoin"), style: "GUIButtonLarge")
             * {
             *  OnClicked = (btn, userdata) => { ShowDirectJoinPrompt(); return true; }
             * };*/

            joinButton = new GUIButton(new RectTransform(new Vector2(0.25f, 0.9f), buttonContainer.RectTransform),
                                       TextManager.Get("ServerListJoin"), style: "GUIButtonLarge")
            {
                OnClicked = (btn, userdata) =>
                {
                    if (ipBox.UserData is ServerInfo selectedServer)
                    {
                        if (selectedServer.LobbyID == 0)
                        {
                            JoinServer(selectedServer.IP + ":" + selectedServer.Port, selectedServer.ServerName);
                        }
                        else
                        {
                            Steam.SteamManager.JoinLobby(selectedServer.LobbyID, true);
                        }
                    }
                    else if (!string.IsNullOrEmpty(ipBox.Text))
                    {
                        JoinServer(ipBox.Text, "");
                    }
                    return(true);
                },
                Enabled = false
            };

            //--------------------------------------------------------

            bottomRow.Recalculate();
            serverListHolder.Recalculate();
            serverListContainer.Recalculate();
            labelHolder.RectTransform.MaxSize = new Point(serverList.Content.Rect.Width, int.MaxValue);
            labelHolder.Recalculate();

            serverList.Content.RectTransform.SizeChanged += () =>
            {
                labelHolder.RectTransform.MaxSize = new Point(serverList.Content.Rect.Width, int.MaxValue);
                labelHolder.Recalculate();
                foreach (GUITextBlock labelText in labelTexts)
                {
                    labelText.Text = ToolBox.LimitString(labelText.ToolTip, labelText.Font, labelText.Rect.Width);
                }
            };

            button.SelectedColor = button.Color;
            refreshDisableTimer  = DateTime.Now;
        }
Exemple #7
0
        public GUIFrame CreateSummaryFrame(GameSession gameSession, string endMessage, List <TraitorMissionResult> traitorResults, CampaignMode.TransitionType transitionType = CampaignMode.TransitionType.None)
        {
            bool singleplayer = GameMain.NetworkMember == null;
            bool gameOver     =
                gameSession.GameMode.IsSinglePlayer ?
                gameSession.CrewManager.GetCharacters().All(c => c.IsDead || c.IsIncapacitated) :
                gameSession.CrewManager.GetCharacters().All(c => c.IsDead || c.IsIncapacitated || c.IsBot);

            if (!singleplayer)
            {
                SoundPlayer.OverrideMusicType     = gameOver ? "crewdead" : "endround";
                SoundPlayer.OverrideMusicDuration = 18.0f;
            }

            GUIFrame background = new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas, Anchor.Center), style: "GUIBackgroundBlocker")
            {
                UserData = this
            };

            List <GUIComponent> rightPanels = new List <GUIComponent>();

            int minWidth = 400, minHeight = 350;
            int padding = GUI.IntScale(25.0f);

            //crew panel -------------------------------------------------------------------------------

            GUIFrame crewFrame      = new GUIFrame(new RectTransform(new Vector2(0.35f, 0.45f), background.RectTransform, Anchor.TopCenter, minSize: new Point(minWidth, minHeight)));
            GUIFrame crewFrameInner = new GUIFrame(new RectTransform(new Point(crewFrame.Rect.Width - padding * 2, crewFrame.Rect.Height - padding * 2), crewFrame.RectTransform, Anchor.Center), style: "InnerFrame");

            var crewContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), crewFrameInner.RectTransform, Anchor.Center))
            {
                Stretch = true
            };

            var crewHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), crewContent.RectTransform),
                                              TextManager.Get("crew"), textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont);

            crewHeader.RectTransform.MinSize = new Point(0, GUI.IntScale(crewHeader.Rect.Height * 2.0f));

            CreateCrewList(crewContent, gameSession.CrewManager.GetCharacterInfos().Where(c => c.TeamID != CharacterTeamType.Team2));

            //another crew frame for the 2nd team in combat missions
            if (gameSession.Missions.Any(m => m is CombatMission))
            {
                crewHeader.Text = CombatMission.GetTeamName(CharacterTeamType.Team1);
                GUIFrame crewFrame2 = new GUIFrame(new RectTransform(new Vector2(0.35f, 0.45f), background.RectTransform, Anchor.TopCenter, minSize: new Point(minWidth, minHeight)));
                rightPanels.Add(crewFrame2);
                GUIFrame crewFrameInner2 = new GUIFrame(new RectTransform(new Point(crewFrame2.Rect.Width - padding * 2, crewFrame2.Rect.Height - padding * 2), crewFrame2.RectTransform, Anchor.Center), style: "InnerFrame");
                var      crewContent2    = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), crewFrameInner2.RectTransform, Anchor.Center))
                {
                    Stretch = true
                };
                var crewHeader2 = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), crewContent2.RectTransform),
                                                   CombatMission.GetTeamName(CharacterTeamType.Team2), textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont);
                crewHeader2.RectTransform.MinSize = new Point(0, GUI.IntScale(crewHeader2.Rect.Height * 2.0f));
                CreateCrewList(crewContent2, gameSession.CrewManager.GetCharacterInfos().Where(c => c.TeamID == CharacterTeamType.Team2));
            }

            //header -------------------------------------------------------------------------------

            string       headerText      = GetHeaderText(gameOver, transitionType);
            GUITextBlock headerTextBlock = null;

            if (!string.IsNullOrEmpty(headerText))
            {
                headerTextBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), crewFrame.RectTransform, Anchor.TopLeft, Pivot.BottomLeft),
                                                   headerText, textAlignment: Alignment.BottomLeft, font: GUI.LargeFont, wrap: true);
            }

            //traitor panel -------------------------------------------------------------------------------

            if (traitorResults != null && traitorResults.Any())
            {
                GUIFrame traitorframe = new GUIFrame(new RectTransform(crewFrame.RectTransform.RelativeSize, background.RectTransform, Anchor.TopCenter, minSize: crewFrame.RectTransform.MinSize));
                rightPanels.Add(traitorframe);
                GUIFrame traitorframeInner = new GUIFrame(new RectTransform(new Point(traitorframe.Rect.Width - padding * 2, traitorframe.Rect.Height - padding * 2), traitorframe.RectTransform, Anchor.Center), style: "InnerFrame");

                var traitorContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), traitorframeInner.RectTransform, Anchor.Center))
                {
                    Stretch = true
                };

                var traitorHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), traitorContent.RectTransform),
                                                     TextManager.Get("traitors"), font: GUI.SubHeadingFont);
                traitorHeader.RectTransform.MinSize = new Point(0, GUI.IntScale(traitorHeader.Rect.Height * 2.0f));

                GUIListBox listBox = CreateCrewList(traitorContent, traitorResults.SelectMany(tr => tr.Characters.Select(c => c.Info)));

                foreach (var traitorResult in traitorResults)
                {
                    var traitorMission = TraitorMissionPrefab.List.Find(t => t.Identifier == traitorResult.MissionIdentifier);
                    if (traitorMission == null)
                    {
                        continue;
                    }

                    //spacing
                    new GUIFrame(new RectTransform(new Point(listBox.Content.Rect.Width, GUI.IntScale(25)), listBox.Content.RectTransform), style: null);

                    var traitorResultHorizontal = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.3f), listBox.Content.RectTransform), childAnchor: Anchor.CenterLeft, isHorizontal: true)
                    {
                        RelativeSpacing = 0.05f,
                        Stretch         = true
                    };

                    new GUIImage(new RectTransform(new Point(traitorResultHorizontal.Rect.Height), traitorResultHorizontal.RectTransform), traitorMission.Icon, scaleToFit: true)
                    {
                        Color = traitorMission.IconColor
                    };

                    string traitorMessage = TextManager.GetServerMessage(traitorResult.EndMessage);
                    if (!string.IsNullOrEmpty(traitorMessage))
                    {
                        var textContent = new GUILayoutGroup(new RectTransform(Vector2.One, traitorResultHorizontal.RectTransform))
                        {
                            RelativeSpacing = 0.025f
                        };

                        var traitorStatusText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), textContent.RectTransform),
                                                                 TextManager.Get(traitorResult.Success ? "missioncompleted" : "missionfailed"),
                                                                 textColor: traitorResult.Success ? GUI.Style.Green : GUI.Style.Red, font: GUI.SubHeadingFont);

                        var traitorMissionInfo = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), textContent.RectTransform),
                                                                  traitorMessage, font: GUI.SmallFont, wrap: true);

                        traitorResultHorizontal.Recalculate();

                        traitorStatusText.CalculateHeightFromText();
                        traitorMissionInfo.CalculateHeightFromText();
                        traitorStatusText.RectTransform.MinSize       = new Point(0, traitorStatusText.Rect.Height);
                        traitorMissionInfo.RectTransform.MinSize      = new Point(0, traitorMissionInfo.Rect.Height);
                        textContent.RectTransform.MaxSize             = new Point(int.MaxValue, (int)((traitorStatusText.Rect.Height + traitorMissionInfo.Rect.Height) * 1.2f));
                        traitorResultHorizontal.RectTransform.MinSize = new Point(0, traitorStatusText.RectTransform.MinSize.Y + traitorMissionInfo.RectTransform.MinSize.Y);
                    }
                }
            }

            //reputation panel -------------------------------------------------------------------------------

            var campaignMode = gameMode as CampaignMode;

            if (campaignMode != null)
            {
                GUIFrame reputationframe = new GUIFrame(new RectTransform(crewFrame.RectTransform.RelativeSize, background.RectTransform, Anchor.TopCenter, minSize: crewFrame.RectTransform.MinSize));
                rightPanels.Add(reputationframe);
                GUIFrame reputationframeInner = new GUIFrame(new RectTransform(new Point(reputationframe.Rect.Width - padding * 2, reputationframe.Rect.Height - padding * 2), reputationframe.RectTransform, Anchor.Center), style: "InnerFrame");

                var reputationContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), reputationframeInner.RectTransform, Anchor.Center))
                {
                    Stretch = true
                };

                var reputationHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), reputationContent.RectTransform),
                                                        TextManager.Get("reputation"), textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont);
                reputationHeader.RectTransform.MinSize = new Point(0, GUI.IntScale(reputationHeader.Rect.Height * 2.0f));

                CreateReputationInfoPanel(reputationContent, campaignMode);
            }

            //mission panel -------------------------------------------------------------------------------

            GUIFrame       missionframe        = new GUIFrame(new RectTransform(new Vector2(0.39f, 0.3f), background.RectTransform, Anchor.TopCenter, minSize: new Point(minWidth, minHeight / 4)));
            GUILayoutGroup missionFrameContent = new GUILayoutGroup(new RectTransform(new Point(missionframe.Rect.Width - padding * 2, missionframe.Rect.Height - padding * 2), missionframe.RectTransform, Anchor.Center))
            {
                Stretch         = true,
                RelativeSpacing = 0.05f
            };
            GUIFrame missionframeInner = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.9f), missionFrameContent.RectTransform, Anchor.Center), style: "InnerFrame");

            var missionContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.93f), missionframeInner.RectTransform, Anchor.Center))
            {
                Stretch = true
            };

            List <Mission> missionsToDisplay = new List <Mission>(selectedMissions);

            if (!selectedMissions.Any() && startLocation?.SelectedMission != null)
            {
                if (startLocation.SelectedMission.Locations[0] == startLocation.SelectedMission.Locations[1] ||
                    startLocation.SelectedMission.Locations.Contains(campaignMode?.Map.SelectedLocation))
                {
                    missionsToDisplay.Add(startLocation.SelectedMission);
                }
            }

            if (missionsToDisplay.Any())
            {
                var missionHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionContent.RectTransform),
                                                     TextManager.Get(missionsToDisplay.Count > 1 ? "Missions" : "Mission"), textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont);
                missionHeader.RectTransform.MinSize = new Point(0, (int)(missionHeader.Rect.Height * 1.2f));
            }

            GUIListBox missionList = new GUIListBox(new RectTransform(Vector2.One, missionContent.RectTransform, Anchor.Center))
            {
                Padding = new Vector4(4, 10, 0, 0) * GUI.Scale
            };

            missionList.ContentBackground.Color = Color.Transparent;

            ButtonArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), missionFrameContent.RectTransform, Anchor.BottomCenter), isHorizontal: true, childAnchor: Anchor.BottomRight)
            {
                RelativeSpacing = 0.025f
            };

            missionFrameContent.Recalculate();
            missionContent.Recalculate();

            if (!string.IsNullOrWhiteSpace(endMessage))
            {
                var endText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionList.Content.RectTransform),
                                               TextManager.GetServerMessage(endMessage), wrap: true)
                {
                    CanBeFocused = false
                };
                endText.RectTransform.MinSize = new Point(0, endText.Rect.Height);
                var line = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.1f), missionList.Content.RectTransform), style: "HorizontalLine");
                line.RectTransform.NonScaledSize = new Point(line.Rect.Width, GUI.IntScale(5.0f));
            }

            foreach (Mission displayedMission in missionsToDisplay)
            {
                var missionContentHorizontal = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.8f), missionList.Content.RectTransform), childAnchor: Anchor.CenterLeft, isHorizontal: true)
                {
                    RelativeSpacing = 0.025f,
                    Stretch         = true
                };

                string missionMessage =
                    selectedMissions.Contains(displayedMission) ?
                    displayedMission.Completed ? displayedMission.SuccessMessage : displayedMission.FailureMessage :
                    displayedMission.Description;
                GUIImage missionIcon = new GUIImage(new RectTransform(new Point((int)(missionContentHorizontal.Rect.Height)), missionContentHorizontal.RectTransform), displayedMission.Prefab.Icon, scaleToFit: true)
                {
                    Color         = displayedMission.Prefab.IconColor,
                    HoverColor    = displayedMission.Prefab.IconColor,
                    SelectedColor = displayedMission.Prefab.IconColor
                };
                missionIcon.RectTransform.MinSize = new Point((int)(missionContentHorizontal.Rect.Height * 0.9f));
                if (selectedMissions.Contains(displayedMission))
                {
                    new GUIImage(new RectTransform(Vector2.One, missionIcon.RectTransform), displayedMission.Completed ? "MissionCompletedIcon" : "MissionFailedIcon", scaleToFit: true);
                }

                var missionTextContent = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.8f), missionContentHorizontal.RectTransform))
                {
                    RelativeSpacing = 0.05f
                };
                var missionNameTextBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
                                                            displayedMission.Name, font: GUI.SubHeadingFont);
                if (displayedMission.Difficulty.HasValue)
                {
                    var groupSize = missionNameTextBlock.Rect.Size;
                    groupSize.X -= (int)(missionNameTextBlock.Padding.X + missionNameTextBlock.Padding.Z);
                    var indicatorGroup = new GUILayoutGroup(new RectTransform(groupSize, missionTextContent.RectTransform)
                    {
                        AbsoluteOffset = new Point((int)missionNameTextBlock.Padding.X, 0)
                    },
                                                            isHorizontal: true, childAnchor: Anchor.CenterLeft)
                    {
                        AbsoluteSpacing = 1
                    };
                    var difficultyColor = displayedMission.GetDifficultyColor();
                    for (int i = 0; i < displayedMission.Difficulty; i++)
                    {
                        new GUIImage(new RectTransform(Vector2.One, indicatorGroup.RectTransform, scaleBasis: ScaleBasis.Smallest)
                        {
                            IsFixedSize = true
                        }, "DifficultyIndicator", scaleToFit: true)
                        {
                            CanBeFocused = false,
                            Color        = difficultyColor
                        };
                    }
                }
                new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
                                 missionMessage, wrap: true, parseRichText: true);
                if (selectedMissions.Contains(displayedMission) && displayedMission.Completed && displayedMission.Reward > 0)
                {
                    string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", displayedMission.Reward));
                    new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), displayedMission.GetMissionRewardText(), parseRichText: true);
                }

                if (displayedMission != missionsToDisplay.Last())
                {
                    var spacing = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), missionList.Content.RectTransform)
                    {
                        MaxSize = new Point(int.MaxValue, GUI.IntScale(15))
                    }, style: null);
                    new GUIFrame(new RectTransform(new Vector2(0.8f, 1.0f), spacing.RectTransform, Anchor.Center)
                    {
                        RelativeOffset = new Vector2(0.1f, 0.0f)
                    }, "HorizontalLine");
                }
            }

            if (!missionsToDisplay.Any())
            {
                var missionContentHorizontal = new GUILayoutGroup(new RectTransform(Vector2.One, missionList.Content.RectTransform), childAnchor: Anchor.TopLeft, isHorizontal: true)
                {
                    RelativeSpacing = 0.025f,
                    Stretch         = true
                };
                GUIImage missionIcon = new GUIImage(new RectTransform(new Point((int)(missionContentHorizontal.Rect.Height * 0.7f)), missionContentHorizontal.RectTransform), style: "NoMissionIcon", scaleToFit: true);
                missionIcon.RectTransform.MinSize = new Point((int)(missionContentHorizontal.Rect.Height * 0.7f));
                new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionContentHorizontal.RectTransform),
                                 TextManager.Get("nomission"), font: GUI.LargeFont);
            }

            /*missionContentHorizontal.Recalculate();
             * missionContent.Recalculate();
             * missionIcon.RectTransform.MinSize = new Point(0, missionContentHorizontal.Rect.Height);
             * missionTextContent.RectTransform.MaxSize = new Point(int.MaxValue, missionIcon.Rect.Width);*/

            ContinueButton = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), ButtonArea.RectTransform), TextManager.Get("Close"));
            ButtonArea.RectTransform.NonScaledSize = new Point(ButtonArea.Rect.Width, ContinueButton.Rect.Height);
            ButtonArea.RectTransform.IsFixedSize   = true;

            missionFrameContent.Recalculate();

            // set layout -------------------------------------------------------------------

            int panelSpacing = GUI.IntScale(20);
            int totalHeight  = crewFrame.Rect.Height + panelSpacing + missionframe.Rect.Height;
            int totalWidth   = crewFrame.Rect.Width;

            crewFrame.RectTransform.AbsoluteOffset    = new Point(0, (GameMain.GraphicsHeight - totalHeight) / 2);
            missionframe.RectTransform.AbsoluteOffset = new Point(0, crewFrame.Rect.Bottom + panelSpacing);

            if (rightPanels.Any())
            {
                totalWidth = crewFrame.Rect.Width * 2 + panelSpacing;
                if (headerTextBlock != null)
                {
                    headerTextBlock.RectTransform.MinSize = new Point(totalWidth, 0);
                }
                crewFrame.RectTransform.AbsoluteOffset = new Point(-(crewFrame.Rect.Width + panelSpacing) / 2, crewFrame.RectTransform.AbsoluteOffset.Y);
                foreach (var rightPanel in rightPanels)
                {
                    rightPanel.RectTransform.AbsoluteOffset = new Point((rightPanel.Rect.Width + panelSpacing) / 2, crewFrame.RectTransform.AbsoluteOffset.Y);
                }
            }

            Frame = background;
            return(background);
        }
Exemple #8
0
        public GUIFrame CreateSummaryFrame(string endMessage)
        {
            bool singleplayer = GameMain.NetworkMember == null;
            bool gameOver     = gameSession.CrewManager.GetCharacters().All(c => c.IsDead || c.IsUnconscious);
            bool progress     = Submarine.MainSub.AtEndPosition;

            if (!singleplayer)
            {
                SoundPlayer.OverrideMusicType     = gameOver ? "crewdead" : "endround";
                SoundPlayer.OverrideMusicDuration = 18.0f;
            }

            GUIFrame frame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: "GUIBackgroundBlocker");

            int      width = 760, height = 500;
            GUIFrame innerFrame  = new GUIFrame(new RectTransform(new Vector2(0.4f, 0.5f), frame.RectTransform, Anchor.Center, minSize: new Point(width, height)));
            var      paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), innerFrame.RectTransform, Anchor.Center))
            {
                Stretch         = true,
                RelativeSpacing = 0.03f
            };

            GUIListBox infoTextBox = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.7f), paddedFrame.RectTransform))
            {
                Spacing = (int)(5 * GUI.Scale)
            };

            //spacing
            new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), infoTextBox.Content.RectTransform), style: null);

            string summaryText = TextManager.GetWithVariables(gameOver ? "RoundSummaryGameOver" :
                                                              (progress ? "RoundSummaryProgress" : "RoundSummaryReturn"), new string[2] {
                "[sub]", "[location]"
            },
                                                              new string[2] {
                Submarine.MainSub.Name, progress ? GameMain.GameSession.EndLocation.Name : GameMain.GameSession.StartLocation.Name
            });

            var infoText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoTextBox.Content.RectTransform),
                                            summaryText, wrap: true);

            GUIComponent endText = null;

            if (!string.IsNullOrWhiteSpace(endMessage))
            {
                endText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoTextBox.Content.RectTransform),
                                           TextManager.GetServerMessage(endMessage), wrap: true);
            }

            //don't show the mission info if the mission was not completed and there's no localized "mission failed" text available
            if (GameMain.GameSession.Mission != null)
            {
                string message = GameMain.GameSession.Mission.Completed ? GameMain.GameSession.Mission.SuccessMessage : GameMain.GameSession.Mission.FailureMessage;
                if (!string.IsNullOrEmpty(message))
                {
                    //spacing
                    var spacingTransform = new RectTransform(new Vector2(1.0f, 0.1f), infoTextBox.Content.RectTransform);

                    new GUIFrame(spacingTransform, style: null);

                    new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoTextBox.Content.RectTransform),
                                     TextManager.AddPunctuation(':', TextManager.Get("Mission"), GameMain.GameSession.Mission.Name),
                                     font: GUI.LargeFont);

                    var missionInfo = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoTextBox.Content.RectTransform),
                                                       message, wrap: true);

                    if (GameMain.GameSession.Mission.Completed && singleplayer)
                    {
                        var missionReward = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoTextBox.Content.RectTransform),
                                                             TextManager.GetWithVariable("MissionReward", "[reward]", GameMain.GameSession.Mission.Reward.ToString()));
                    }
                }
            }

            new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedFrame.RectTransform),
                             TextManager.Get("RoundSummaryCrewStatus"), font: GUI.LargeFont);

            GUIListBox characterListBox = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.4f), paddedFrame.RectTransform, minSize: new Point(0, 75)), isHorizontal: true);

            foreach (CharacterInfo characterInfo in gameSession.CrewManager.GetCharacterInfos())
            {
                if (GameMain.GameSession.Mission is CombatMission &&
                    characterInfo.TeamID != GameMain.GameSession.WinningTeam)
                {
                    continue;
                }

                var characterFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.2f, 1.0f), characterListBox.Content.RectTransform, minSize: new Point(170, 0)))
                {
                    CanBeFocused = false,
                    Stretch      = true
                };

                characterInfo.CreateCharacterFrame(characterFrame,
                                                   characterInfo.Job != null ? (characterInfo.Name + '\n' + "(" + characterInfo.Job.Name + ")") : characterInfo.Name, null);

                string statusText  = TextManager.Get("StatusOK");
                Color  statusColor = Color.DarkGreen;

                Character character = characterInfo.Character;
                if (character == null || character.IsDead)
                {
                    if (characterInfo.CauseOfDeath == null)
                    {
                        statusText = TextManager.Get("CauseOfDeathDescription.Unknown");
                    }
                    else if (characterInfo.CauseOfDeath.Type == CauseOfDeathType.Affliction && characterInfo.CauseOfDeath.Affliction == null)
                    {
                        string errorMsg = "Character \"" + character.Name + "\" had an invalid cause of death (the type of the cause of death was Affliction, but affliction was not specified).";
                        DebugConsole.ThrowError(errorMsg);
                        GameAnalyticsManager.AddErrorEventOnce("RoundSummary:InvalidCauseOfDeath", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
                        statusText = TextManager.Get("CauseOfDeathDescription.Unknown");
                    }
                    else
                    {
                        statusText = characterInfo.CauseOfDeath.Type == CauseOfDeathType.Affliction ?
                                     characterInfo.CauseOfDeath.Affliction.CauseOfDeathDescription :
                                     TextManager.Get("CauseOfDeathDescription." + characterInfo.CauseOfDeath.Type.ToString());
                    }
                    statusColor = Color.DarkRed;
                }
                else
                {
                    if (character.IsUnconscious)
                    {
                        statusText  = TextManager.Get("Unconscious");
                        statusColor = Color.DarkOrange;
                    }
                    else if (character.Vitality / character.MaxVitality < 0.8f)
                    {
                        statusText  = TextManager.Get("Injured");
                        statusColor = Color.DarkOrange;
                    }
                }

                var textHolder = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.2f), characterFrame.RectTransform, Anchor.BottomCenter), style: "InnerGlow", color: statusColor);
                new GUITextBlock(new RectTransform(Vector2.One, textHolder.RectTransform, Anchor.Center),
                                 statusText, Color.White,
                                 textAlignment: Alignment.Center,
                                 wrap: true, font: GUI.SmallFont, style: null);
            }

            new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), paddedFrame.RectTransform), isHorizontal: true, childAnchor: Anchor.BottomRight)
            {
                RelativeSpacing = 0.05f,
                UserData        = "buttonarea"
            };

            paddedFrame.Recalculate();
            foreach (GUIComponent child in infoTextBox.Content.Children)
            {
                child.CanBeFocused = false;
                if (child is GUITextBlock textBlock)
                {
                    textBlock.CalculateHeightFromText();
                }
            }

            return(frame);
        }
Exemple #9
0
        private GUIComponent CreateItemFrame(PurchasedItem pi, PriceInfo priceInfo, GUIListBox listBox, int width)
        {
            GUIFrame frame = new GUIFrame(new RectTransform(new Point(listBox.Content.Rect.Width, (int)(GUI.Scale * 50)), listBox.Content.RectTransform), style: "ListBoxElement")
            {
                UserData = pi,
                ToolTip  = pi.ItemPrefab.Description
            };

            var content = new GUILayoutGroup(new RectTransform(Vector2.One, frame.RectTransform), isHorizontal: true)
            {
                RelativeSpacing = 0.02f,
                Stretch         = true
            };

            ScalableFont font = listBox.Rect.Width < 280 ? GUI.SmallFont : GUI.Font;

            Sprite itemIcon = pi.ItemPrefab.InventoryIcon ?? pi.ItemPrefab.sprite;

            if (itemIcon != null)
            {
                GUIImage img = new GUIImage(new RectTransform(new Point((int)(content.Rect.Height * 0.8f)), content.RectTransform, Anchor.CenterLeft), itemIcon, scaleToFit: true)
                {
                    Color = itemIcon == pi.ItemPrefab.InventoryIcon ? pi.ItemPrefab.InventoryIconColor : pi.ItemPrefab.SpriteColor
                };
                img.RectTransform.MaxSize = img.Rect.Size;
                //img.Scale = Math.Min(Math.Min(40.0f / img.SourceRect.Width, 40.0f / img.SourceRect.Height), 1.0f);
            }

            GUITextBlock textBlock = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), content.RectTransform),
                                                      pi.ItemPrefab.Name, font: font)
            {
                ToolTip = pi.ItemPrefab.Description
            };

            new GUITextBlock(new RectTransform(new Vector2(0.2f, 1.0f), content.RectTransform),
                             priceInfo.BuyPrice.ToString(), font: font, textAlignment: Alignment.CenterRight)
            {
                ToolTip = pi.ItemPrefab.Description
            };

            //If its the store menu, quantity will always be 0
            GUINumberInput amountInput = null;

            if (pi.Quantity > 0)
            {
                amountInput = new GUINumberInput(new RectTransform(new Vector2(0.3f, 1.0f), content.RectTransform),
                                                 GUINumberInput.NumberType.Int)
                {
                    MinValueInt = 0,
                    MaxValueInt = 100,
                    UserData    = pi,
                    IntValue    = pi.Quantity
                };
                amountInput.OnValueChanged += (numberInput) =>
                {
                    PurchasedItem purchasedItem = numberInput.UserData as PurchasedItem;

                    //Attempting to buy
                    if (numberInput.IntValue > purchasedItem.Quantity)
                    {
                        int quantity = numberInput.IntValue - purchasedItem.Quantity;
                        //Cap the numberbox based on the amount we can afford.
                        quantity = Campaign.Money <= 0 ?
                                   0 : Math.Min((int)(Campaign.Money / (float)priceInfo.BuyPrice), quantity);
                        for (int i = 0; i < quantity; i++)
                        {
                            BuyItem(numberInput, purchasedItem);
                        }
                        numberInput.IntValue = purchasedItem.Quantity;
                    }
                    //Attempting to sell
                    else
                    {
                        int quantity = purchasedItem.Quantity - numberInput.IntValue;
                        for (int i = 0; i < quantity; i++)
                        {
                            SellItem(numberInput, purchasedItem);
                        }
                    }
                };
            }
            listBox.RecalculateChildren();
            content.Recalculate();
            content.RectTransform.RecalculateChildren(true, true);
            amountInput?.LayoutGroup.Recalculate();
            textBlock.Text = ToolBox.LimitString(textBlock.Text, textBlock.Font, textBlock.Rect.Width);
            content.RectTransform.IsFixedSize = true;
            content.RectTransform.Children.ForEach(c => c.IsFixedSize = true);

            return(frame);
        }
Exemple #10
0
        private void CreateCharacterPreviewFrame(GUIListBox listBox, GUIFrame characterFrame, CharacterInfo characterInfo)
        {
            Pivot pivot          = listBox == hireableList ? Pivot.TopLeft : Pivot.TopRight;
            Point absoluteOffset = new Point(
                pivot == Pivot.TopLeft ? listBox.Parent.Parent.Rect.Right + 5 : listBox.Parent.Parent.Rect.Left - 5,
                characterFrame.Rect.Top);
            int frameSize = (int)(GUI.Scale * 300);

            if (GameMain.GraphicsHeight - (absoluteOffset.Y + frameSize) < 0)
            {
                pivot            = listBox == hireableList ? Pivot.BottomLeft : Pivot.BottomRight;
                absoluteOffset.Y = characterFrame.Rect.Bottom;
            }
            characterPreviewFrame = new GUIFrame(new RectTransform(new Point(frameSize), parent: campaignUI.GetTabContainer(CampaignMode.InteractionType.Crew).Parent.RectTransform, pivot: pivot)
            {
                AbsoluteOffset = absoluteOffset
            }, style: "InnerFrame")
            {
                UserData = characterInfo
            };
            GUILayoutGroup mainGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.95f), characterPreviewFrame.RectTransform, anchor: Anchor.Center))
            {
                RelativeSpacing = 0.01f
            };

            // Character info
            GUILayoutGroup infoGroup      = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.475f), mainGroup.RectTransform), isHorizontal: true);
            GUILayoutGroup infoLabelGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 1.0f), infoGroup.RectTransform))
            {
                Stretch = true
            };
            GUILayoutGroup infoValueGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.6f, 1.0f), infoGroup.RectTransform))
            {
                Stretch = true
            };
            float blockHeight = 1.0f / 4;

            new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoLabelGroup.RectTransform), TextManager.Get("name"));
            new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoValueGroup.RectTransform), characterInfo.Name);
            if (characterInfo.HasGenders)
            {
                new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoLabelGroup.RectTransform), TextManager.Get("gender"));
                new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoValueGroup.RectTransform), TextManager.Get(characterInfo.Gender.ToString()));
            }
            if (characterInfo.Job is Job job)
            {
                new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoLabelGroup.RectTransform), TextManager.Get("tabmenu.job"));
                new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoValueGroup.RectTransform), job.Name);
            }
            if (characterInfo.PersonalityTrait is NPCPersonalityTrait trait)
            {
                new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoLabelGroup.RectTransform), TextManager.Get("PersonalityTrait"));
                new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoValueGroup.RectTransform), TextManager.Get("personalitytrait." + trait.Name.Replace(" ", "")));
            }
            infoLabelGroup.Recalculate();
            infoValueGroup.Recalculate();

            new GUIImage(new RectTransform(new Vector2(1.0f, 0.05f), mainGroup.RectTransform), "HorizontalLine");

            // Skills
            GUILayoutGroup skillGroup      = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.475f), mainGroup.RectTransform), isHorizontal: true);
            GUILayoutGroup skillNameGroup  = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 1.0f), skillGroup.RectTransform));
            GUILayoutGroup skillLevelGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.2f, 1.0f), skillGroup.RectTransform));
            List <Skill>   characterSkills = characterInfo.Job.Skills;

            blockHeight = 1.0f / characterSkills.Count;
            foreach (Skill skill in characterSkills)
            {
                new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), skillNameGroup.RectTransform), TextManager.Get("SkillName." + skill.Identifier));
                new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), skillLevelGroup.RectTransform), ((int)skill.Level).ToString(), textAlignment: Alignment.Right);
            }
        }
Exemple #11
0
        private static void CreateDialog(string text, Character speaker, IEnumerable <string> options, int[] closingOptions, string spriteIdentifier = null,
                                         ConversationAction actionInstance = null, UInt16?actionId = null, bool fadeToBlack = false, DialogTypes dialogType = DialogTypes.Regular, bool continueConversation = false)
        {
            Debug.Assert(actionInstance == null || actionId == null);

            shouldFadeToBlack = fadeToBlack;

            if (lastMessageBox != null && !lastMessageBox.Closed && GUIMessageBox.MessageBoxes.Contains(lastMessageBox))
            {
                if (actionId != null && lastMessageBox.UserData is Pair <string, ushort> userData)
                {
                    if (userData.Second == actionId)
                    {
                        return;
                    }
                    lastMessageBox.UserData = new Pair <string, ushort>("ConversationAction", actionId.Value);
                }

                GUIListBox conversationList = lastMessageBox.FindChild("conversationlist", true) as GUIListBox;
                Debug.Assert(conversationList != null);

                // gray out the last text block
                if (conversationList.Content.Children.LastOrDefault() is GUILayoutGroup lastElement)
                {
                    if (lastElement.FindChild("text", true) is GUITextBlock textLayout)
                    {
                        textLayout.OverrideTextColor(Color.DarkGray * 0.8f);
                    }
                }

                List <GUIButton> extraButtons = CreateConversation(conversationList, text, speaker, options, string.IsNullOrWhiteSpace(spriteIdentifier));
                AssignActionsToButtons(extraButtons, lastMessageBox);
                RecalculateLastMessage(conversationList, true);

                conversationList.ScrollToEnd(0.5f);
                lastMessageBox.SetBackgroundIcon(EventSet.GetEventSprite(spriteIdentifier));
                return;
            }

            var(relative, min) = GetSizes(dialogType);

            GUIMessageBox messageBox = new GUIMessageBox(string.Empty, string.Empty, new string[0],
                                                         relativeSize: relative, minSize: min,
                                                         type: GUIMessageBox.Type.InGame, backgroundIcon: EventSet.GetEventSprite(spriteIdentifier))
            {
                UserData = "ConversationAction"
            };

            lastMessageBox = messageBox;

            messageBox.InnerFrame.ClearChildren();
            messageBox.AutoClose = false;
            GUI.Style.Apply(messageBox.InnerFrame, "DialogBox");

            if (actionInstance != null)
            {
                lastActiveAction         = actionInstance;
                actionInstance.dialogBox = messageBox;
            }
            else
            {
                messageBox.UserData = new Pair <string, UInt16>("ConversationAction", actionId.Value);
            }

            int padding = GUI.IntScale(16);

            GUIListBox listBox = new GUIListBox(new RectTransform(messageBox.InnerFrame.Rect.Size - new Point(padding * 2), messageBox.InnerFrame.RectTransform, Anchor.Center), style: null)
            {
                KeepSpaceForScrollBar = true,
                HoverCursor           = CursorState.Default,
                UserData = "conversationlist"
            };

            List <GUIButton> buttons = CreateConversation(listBox, text, speaker, options, string.IsNullOrWhiteSpace(spriteIdentifier));

            AssignActionsToButtons(buttons, messageBox);
            RecalculateLastMessage(listBox, false);

            messageBox.InnerFrame.RectTransform.MinSize = new Point(0, Math.Max(listBox.RectTransform.MinSize.Y + padding * 2, (int)(100 * GUI.yScale)));

            var shadow = new GUIFrame(new RectTransform(messageBox.InnerFrame.Rect.Size + new Point(padding * 4), messageBox.InnerFrame.RectTransform, Anchor.Center), style: "OuterGlow")
            {
                Color = Color.Black * 0.7f
            };

            shadow.SetAsFirstChild();

            void RecalculateLastMessage(GUIListBox conversationList, bool append)
            {
                if (conversationList.Content.Children.LastOrDefault() is GUILayoutGroup lastElement)
                {
                    GUILayoutGroup textLayout = lastElement.GetChild <GUILayoutGroup>();
                    if (lastElement.Rect.Size.Y < textLayout.Rect.Size.Y && !append)
                    {
                        lastElement.RectTransform.MinSize = textLayout.Rect.Size;
                    }
                    if (textLayout != null)
                    {
                        int textHeight = textLayout.Children.Sum(c => c.Rect.Height);
                        textLayout.RectTransform.MaxSize = new Point(lastElement.RectTransform.MaxSize.X, textHeight);
                        textLayout.Recalculate();
                    }
                    int sumHeight = lastElement.Children.Sum(c => c.Rect.Height);
                    lastElement.RectTransform.MaxSize = new Point(lastElement.RectTransform.MaxSize.X, sumHeight);
                    lastElement.Recalculate();
                    conversationList.RecalculateChildren();

                    if (!append || textLayout == null)
                    {
                        return;
                    }

                    foreach (GUIComponent child in textLayout.Children)
                    {
                        conversationList.UpdateScrollBarSize();
                        float wait = conversationList.BarSize < 1.0f ? 0.5f : 0.0f;

                        if (child is GUITextBlock)
                        {
                            child.FadeIn(wait, 0.5f);
                        }

                        if (child is GUIButton btn)
                        {
                            btn.FadeIn(wait, 1.0f);
                            btn.TextBlock.FadeIn(wait, 0.5f);
                        }
                    }
                }
            }

            void AssignActionsToButtons(List <GUIButton> optionButtons, GUIMessageBox target)
            {
                if (!options.Any())
                {
                    GUIButton closeButton = new GUIButton(new RectTransform(Vector2.One, target.InnerFrame.RectTransform, Anchor.BottomRight, scaleBasis: ScaleBasis.Smallest)
                    {
                        MaxSize        = new Point(GUI.IntScale(24)),
                        MinSize        = new Point(24),
                        AbsoluteOffset = new Point(GUI.IntScale(48), GUI.IntScale(16))
                    }, style: "GUIButtonVerticalArrow")
                    {
                        UserData           = "ContinueButton",
                        IgnoreLayoutGroups = true,
                        Bounce             = true,
                        OnClicked          = (btn, userdata) =>
                        {
                            if (actionInstance != null)
                            {
                                actionInstance.selectedOption = 0;
                            }
                            else if (actionId.HasValue)
                            {
                                SendResponse(actionId.Value, 0);
                            }

                            if (!continueConversation)
                            {
                                target.Close();
                            }
                            else
                            {
                                btn.Frame.FadeOut(0.33f, true);
                            }

                            return(true);
                        }
                    };

                    closeButton.Children.ForEach(child => child.SpriteEffects = SpriteEffects.FlipVertically);
                    closeButton.Frame.FadeIn(0.5f, 0.5f);
                    closeButton.SlideIn(0.5f, 0.33f, 16, SlideDirection.Down);
                }

                for (int i = 0; i < optionButtons.Count; i++)
                {
                    optionButtons[i].UserData   = i;
                    optionButtons[i].OnClicked += (btn, userdata) =>
                    {
                        int selectedOption = (userdata as int?) ?? 0;
                        if (actionInstance != null)
                        {
                            actionInstance.selectedOption = selectedOption;
                            foreach (GUIButton otherButton in optionButtons)
                            {
                                otherButton.CanBeFocused = false;
                                if (otherButton != btn)
                                {
                                    otherButton.TextBlock.OverrideTextColor(Color.DarkGray * 0.8f);
                                }
                            }
                            btn.ExternalHighlight = true;
                            return(true);
                        }

                        if (actionId.HasValue)
                        {
                            SendResponse(actionId.Value, selectedOption);
                            btn.CanBeFocused      = false;
                            btn.ExternalHighlight = true;
                            foreach (GUIButton otherButton in optionButtons)
                            {
                                otherButton.CanBeFocused = false;
                                if (otherButton != btn)
                                {
                                    otherButton.TextBlock.OverrideTextColor(Color.DarkGray * 0.8f);
                                }
                            }
                            return(true);
                        }
                        //should not happen
                        return(false);
                    };

                    if (closingOptions.Contains(i))
                    {
                        optionButtons[i].OnClicked += target.Close;
                    }
                }
            }
        }
        public CampaignSetupUI(bool isMultiplayer, GUIComponent newGameContainer, GUIComponent loadGameContainer, IEnumerable <Submarine> 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.05f
            };

            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") + ":");
            saveNameBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform)
            {
                MinSize = new Point(0, 20)
            }, string.Empty);

            new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform)
            {
                MinSize = new Point(0, 20)
            }, TextManager.Get("MapSeed") + ":");
            seedBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform)
            {
                MinSize = new Point(0, 20)
            }, ToolBox.RandomSeed(8));

            new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform)
            {
                MinSize = new Point(0, 20)
            }, TextManager.Get("SelectedSub") + ":");
            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("FilterMapEntities"), 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);

            searchBox.OnSelected   += (sender, userdata) => { searchTitle.Visible = false; };
            searchBox.OnDeselected += (sender, userdata) => { searchTitle.Visible = true; };

            searchBox.OnTextChanged += (textBox, text) => { FilterSubs(subList, text); return(true); };
            var clearButton = new GUIButton(new RectTransform(new Vector2(0.075f, 1.0f), filterContainer.RectTransform), "x")
            {
                OnClicked = (btn, userdata) => { searchBox.Text = ""; FilterSubs(subList, ""); searchBox.Flash(Color.White); return(true); }
            };

            if (!isMultiplayer)
            {
                subList.OnSelected = OnSubSelected;
            }

            // New game right side
            subPreviewContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.8f), 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);

            var 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(Color.Red);
                        return(false);
                    }

                    if (!(subList.SelectedData is Submarine selectedSub))
                    {
                        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);
                                    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);
                }
            };

            leftColumn.Recalculate();
            rightColumn.Recalculate();


            UpdateSubList(submarines);
            UpdateLoadMenu(saveFiles);
        }
Exemple #13
0
        public GUIContextMenu(Vector2?position, string header, string style, params ContextMenuOption[] options) : base(style, new RectTransform(Point.Zero, GUI.Canvas))
        {
            Vector2      pos = position ?? PlayerInput.MousePosition;
            ScalableFont headerFont = GUI.SubHeadingFont;
            ScalableFont font = GUI.SmallFont; // font the context menu options use
            Vector4      padding = new Vector4(4), headerPadding = new Vector4(8);
            int          horizontalPadding = (int)(padding.X + padding.Z), verticalPadding = (int)(padding.Y + padding.W);
            bool         hasHeader = !string.IsNullOrWhiteSpace(header);

            //----------------------------------------------------------------------------------
            // Estimate the size of the context menu
            //----------------------------------------------------------------------------------

            Dictionary <ContextMenuOption, Vector2> optionsAndSizes = new Dictionary <ContextMenuOption, Vector2>();

            // estimate how big the context menu needs to be
            Point estimatedSize = new Point(horizontalPadding, verticalPadding);

            if (hasHeader)
            {
                InflateSize(ref estimatedSize, header, headerFont);
            }

            foreach (ContextMenuOption option in options)
            {
                Vector2 optionSize = InflateSize(ref estimatedSize, option.Label, font);
                optionsAndSizes.Add(option, optionSize);
            }

            // it's better to overestimate the size since it's going to be cropped anyways
            estimatedSize = estimatedSize.Multiply(1.2f);

            RectTransform.NonScaledSize  = estimatedSize;
            RectTransform.AbsoluteOffset = pos.ToPoint();

            //----------------------------------------------------------------------------------
            // Construct the GUI elements
            //----------------------------------------------------------------------------------

            GUILayoutGroup background = new GUILayoutGroup(new RectTransform(Vector2.One, RectTransform, Anchor.Center));

            if (hasHeader)
            {
                HeaderLabel = new GUITextBlock(new RectTransform(new Vector2(1f, 0.2f), background.RectTransform), header, font: headerFont)
                {
                    Padding = headerPadding
                };
            }

            GUIListBox optionList = new GUIListBox(new RectTransform(new Vector2(1f, hasHeader ? 0.8f : 1f), background.RectTransform), style: null)
            {
                AutoHideScrollBar = false,
                ScrollBarVisible  = false,
                Padding           = hasHeader ? new Vector4(4, 0, 4, 4) : padding
            };

            foreach (var(option, size) in optionsAndSizes)
            {
                GUITextBlock optionElement = new GUITextBlock(new RectTransform(size.ToPoint(), optionList.Content.RectTransform), option.Label, font: font)
                {
                    UserData = option,
                    Enabled  = option.IsEnabled
                };
                Options.Add(option, optionElement);

                if (!string.IsNullOrWhiteSpace(option.Tooltip) && optionElement.Enabled)
                {
                    optionElement.ToolTip = option.Tooltip;
                }

                if (!option.IsEnabled)
                {
                    optionElement.TextColor *= 0.5f;
                }
            }

            //----------------------------------------------------------------------------------
            // Positioning and cropping the context menu
            //----------------------------------------------------------------------------------

            List <GUIComponent> children = optionList.Content.Children.ToList();

            // Resize all children to the size of their text
            foreach (GUITextBlock block in children.Where(c => c is GUITextBlock).Cast <GUITextBlock>())
            {
                block.RectTransform.NonScaledSize = new Point((int)(block.TextSize.X + (block.Padding.X + block.Padding.Z)), (int)(18 * GUI.Scale));
            }

            int largestWidth = children.Max(c => c.Rect.Width + horizontalPadding);

            // if the header is bigger than any of the options then overwrite
            if (HeaderLabel != null)
            {
                RectTransform headerTransform = HeaderLabel.RectTransform;
                headerTransform.MinSize = new Point((int)(HeaderLabel.TextSize.X + (headerPadding.X + headerPadding.Z)), headerTransform.NonScaledSize.Y);
                if (largestWidth < headerTransform.MinSize.X)
                {
                    largestWidth = headerTransform.MinSize.X;
                }
            }

            // resize all children to the size of the longest element
            foreach (GUIComponent c in children)
            {
                c.RectTransform.MinSize = new Point(largestWidth, c.Rect.Height);
            }

            // the cropped size of the option list
            Point newSize = new Point(largestWidth, children.Sum(c => c.Rect.Height) + verticalPadding);

            // resize the menu itself taking into account the option menus relative Y size
            RectTransform.NonScaledSize            = new Point(newSize.X, (int)(newSize.Y / optionList.RectTransform.RelativeSize.Y));
            optionList.RectTransform.NonScaledSize = newSize;

            // move the context menu if it would go outside of screen
            if (RectTransform.Rect.Bottom > GameMain.GraphicsHeight)
            {
                Rectangle rect = RectTransform.Rect;
                RectTransform.AbsoluteOffset = new Point(rect.X, rect.Y - rect.Height);
            }

            if (RectTransform.Rect.Right > GameMain.GraphicsWidth)
            {
                Rectangle rect = RectTransform.Rect;
                RectTransform.AbsoluteOffset = new Point(rect.X - rect.Width, rect.Y);
            }

            background.Recalculate();

            optionList.OnSelected = OnSelected;
        }
        private void CreateReputationElement(GUIComponent parent,
                                             string name, float reputation, float normalizedReputation, float initialReputation,
                                             string shortDescription, string fullDescription, Sprite icon, Sprite backgroundPortrait, Color iconColor)
        {
            var factionFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.3f), parent.RectTransform), style: null);

            if (backgroundPortrait != null)
            {
                new GUICustomComponent(new RectTransform(Vector2.One, factionFrame.RectTransform), onDraw: (sb, customComponent) =>
                {
                    backgroundPortrait.Draw(sb, customComponent.Rect.Center.ToVector2(), customComponent.Color, backgroundPortrait.size / 2, scale: customComponent.Rect.Width / backgroundPortrait.size.X);
                })
                {
                    HideElementsOutsideFrame = true,
                    IgnoreLayoutGroups       = true,
                    Color = iconColor * 0.2f
                };
            }

            var factionInfoHorizontal = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), factionFrame.RectTransform, Anchor.Center), childAnchor: Anchor.CenterLeft, isHorizontal: true)
            {
                RelativeSpacing = 0.02f,
                Stretch         = true
            };

            var factionTextContent = new GUILayoutGroup(new RectTransform(Vector2.One, factionInfoHorizontal.RectTransform))
            {
                RelativeSpacing = 0.05f,
                Stretch         = true
            };
            var factionIcon = new GUIImage(new RectTransform(new Point((int)(factionInfoHorizontal.Rect.Height * 0.7f)), factionInfoHorizontal.RectTransform, scaleBasis: ScaleBasis.Smallest), icon, scaleToFit: true)
            {
                Color = iconColor
            };

            factionInfoHorizontal.Recalculate();

            new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), factionTextContent.RectTransform),
                             name, font: GUI.SubHeadingFont)
            {
                Padding = Vector4.Zero
            };
            var factionDescription = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.6f), factionTextContent.RectTransform),
                                                      shortDescription, font: GUI.SmallFont, wrap: true)
            {
                UserData = "description",
                Padding  = Vector4.Zero
            };

            if (shortDescription != fullDescription && !string.IsNullOrEmpty(fullDescription))
            {
                factionDescription.ToolTip = fullDescription;
            }

            var sliderHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), factionTextContent.RectTransform),
                                                  childAnchor: Anchor.CenterLeft, isHorizontal: true)
            {
                RelativeSpacing = 0.05f,
                Stretch         = true
            };

            sliderHolder.RectTransform.MaxSize = new Point(int.MaxValue, GUI.IntScale(25.0f));
            factionTextContent.Recalculate();

            new GUICustomComponent(new RectTransform(new Vector2(0.8f, 1.0f), sliderHolder.RectTransform),
                                   onDraw: (sb, customComponent) => DrawReputationBar(sb, customComponent.Rect, normalizedReputation));

            string reputationText   = ((int)Math.Round(reputation)).ToString();
            int    reputationChange = (int)Math.Round(reputation - initialReputation);

            if (Math.Abs(reputationChange) > 0)
            {
                string changeText = $"{(reputationChange > 0 ? "+" : "") + reputationChange}";
                string colorStr   = XMLExtensions.ColorToString(reputationChange > 0 ? GUI.Style.Green : GUI.Style.Red);
                var    rtData     = RichTextData.GetRichTextData($"{reputationText} (‖color:{colorStr}‖{changeText}‖color:end‖)", out string sanitizedText);
                new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), sliderHolder.RectTransform),
                                 rtData, sanitizedText,
                                 textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont);
            }
            else
            {
                new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), sliderHolder.RectTransform),
                                 reputationText,
                                 textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont);
            }
        }
Exemple #15
0
        private void CreateFirstPage(GUILayoutGroup firstPageLayout, IEnumerable <SubmarineInfo> submarines)
        {
            firstPageLayout.RelativeSpacing = 0.02f;

            var columnContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.9f), firstPageLayout.RectTransform), isHorizontal: true)
            {
                Stretch         = true,
                RelativeSpacing = 0.02f
            };

            var leftColumn = new GUILayoutGroup(new RectTransform(Vector2.One, columnContainer.RectTransform))
            {
                Stretch         = true,
                RelativeSpacing = 0.015f
            };

            var rightColumn = new GUILayoutGroup(new RectTransform(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));

            new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform)
            {
                MinSize = new Point(0, 20)
            }, TextManager.Get("SelectedSub"), font: GUI.SubHeadingFont);

            var moddedDropdown = new GUIDropDown(new RectTransform(new Vector2(1f, 0.02f), leftColumn.RectTransform), "", 3);

            moddedDropdown.AddItem(TextManager.Get("clientpermission.all"), CategoryFilter.All);
            moddedDropdown.AddItem(TextManager.Get("servertag.modded.false"), CategoryFilter.Vanilla);
            moddedDropdown.AddItem(TextManager.Get("customrank"), CategoryFilter.Custom);
            moddedDropdown.Select(0);

            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); };

            moddedDropdown.OnSelected = (component, data) =>
            {
                searchBox.Text = string.Empty;
                subFilter      = (CategoryFilter)data;
                UpdateSubList(SubmarineInfo.SavedSubmarines);
                return(true);
            };

            subList.OnSelected = OnSubSelected;

            // New game right side
            subPreviewContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), rightColumn.RectTransform))
            {
                Stretch = true
            };

            var firstPageButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.08f),
                                                                                firstPageLayout.RectTransform), childAnchor: Anchor.BottomLeft, isHorizontal: true)
            {
                RelativeSpacing = 0.025f
            };

            InitialMoneyText = new GUITextBlock(new RectTransform(new Vector2(0.3f, 1f), firstPageButtonContainer.RectTransform), "", font: GUI.Style.Font, textColor: GUI.Style.Green, textAlignment: Alignment.CenterLeft)
            {
                TextGetter = () =>
                {
                    int initialMoney = CampaignMode.InitialMoney;
                    if (subList.SelectedData is SubmarineInfo subInfo)
                    {
                        initialMoney -= subInfo.Price;
                    }
                    initialMoney = Math.Max(initialMoney, 0);
                    return(TextManager.GetWithVariable("campaignstartingmoney", "[money]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", initialMoney)));
                }
            };

            CampaignCustomizeButton = new GUIButton(new RectTransform(new Vector2(0.25f, 1f), firstPageButtonContainer.RectTransform, Anchor.CenterLeft), TextManager.Get("SettingsButton"))
            {
                OnClicked = (tb, userdata) =>
                {
                    CreateCustomizeWindow();
                    return(true);
                }
            };

            nextButton = new GUIButton(new RectTransform(new Vector2(0.4f, 1f), firstPageButtonContainer.RectTransform, Anchor.BottomRight), TextManager.Get("Next"))
            {
                OnClicked = (GUIButton btn, object userData) =>
                {
                    SetPage(1);
                    return(false);
                }
            };

            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);
            }
        }
Exemple #16
0
        public GUINumberInput(RectTransform rectT, NumberType inputType, string style = "", Alignment textAlignment = Alignment.Center) : base(style, rectT)
        {
            LayoutGroup = new GUILayoutGroup(new RectTransform(Vector2.One, rectT), isHorizontal: true)
            {
                Stretch = true
            };

            float relativeButtonAreaWidth = MathHelper.Clamp(Rect.Height / (float)Rect.Width, 0.1f, 0.5f);

            TextBox = new GUITextBox(new RectTransform(new Vector2(1.0f - relativeButtonAreaWidth, 1.0f), LayoutGroup.RectTransform), textAlignment: textAlignment, style: style)
            {
                ClampText = false,
                // For some reason the caret in the number inputs is dimmer than it should.
                // It should not be rendered behind anything, as I first suspected.
                // Therefore this hack.
                CaretColor = Color.White
            };
            TextBox.OnTextChanged += TextChanged;
            var buttonArea = new GUIFrame(new RectTransform(new Vector2(relativeButtonAreaWidth, 1.0f), LayoutGroup.RectTransform, Anchor.CenterRight)
            {
                MinSize = new Point(Rect.Height, 0)
            }, style: null);

            PlusButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.5f), buttonArea.RectTransform), "+");
            PlusButton.OnButtonDown += () =>
            {
                pressedTimer = pressedDelay;
                return(true);
            };
            PlusButton.OnClicked += (button, data) =>
            {
                IncreaseValue();
                return(true);
            };
            PlusButton.OnPressed += () =>
            {
                if (!IsPressedTimerRunning)
                {
                    IncreaseValue();
                }
                return(true);
            };
            PlusButton.Visible = inputType == NumberType.Int;

            MinusButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.5f), buttonArea.RectTransform, Anchor.BottomRight), "-");
            MinusButton.OnButtonDown += () =>
            {
                pressedTimer = pressedDelay;
                return(true);
            };
            MinusButton.OnClicked += (button, data) =>
            {
                ReduceValue();
                return(true);
            };
            MinusButton.OnPressed += () =>
            {
                if (!IsPressedTimerRunning)
                {
                    ReduceValue();
                }
                return(true);
            };
            MinusButton.Visible = inputType == NumberType.Int;

            if (inputType == NumberType.Int)
            {
                UpdateText();
                TextBox.OnEnterPressed += (txtBox, txt) =>
                {
                    UpdateText();
                    TextBox.Deselect();
                    return(true);
                };
                TextBox.OnDeselected += (txtBox, key) => UpdateText();
            }
            else if (inputType == NumberType.Float)
            {
                UpdateText();
                TextBox.OnDeselected   += (txtBox, key) => UpdateText();
                TextBox.OnEnterPressed += (txtBox, txt) =>
                {
                    UpdateText();
                    TextBox.Deselect();
                    return(true);
                };
            }
            InputType = inputType;
            switch (InputType)
            {
            case NumberType.Int:
                TextBox.textFilterFunction = text => new string(text.Where(c => char.IsNumber(c)).ToArray());
                break;

            case NumberType.Float:
                TextBox.textFilterFunction = text => new string(text.Where(c => char.IsDigit(c) || c == '.' || c == '-').ToArray());
                break;
            }

            LayoutGroup.Recalculate();
        }
Exemple #17
0
        public GUIMessageBox(string headerText, string text, string[] buttons, Vector2?relativeSize = null, Point?minSize = null, Alignment textAlignment = Alignment.TopLeft, Type type = Type.Default, string tag = "", Sprite icon = null)
            : base(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: GUI.Style.GetComponentStyle("GUIMessageBox." + type) != null ? "GUIMessageBox." + type : "GUIMessageBox")
        {
            int width = (int)(DefaultWidth * (type == Type.Default ? 1.0f : 1.5f)), height = 0;

            if (relativeSize.HasValue)
            {
                width  = (int)(GameMain.GraphicsWidth * relativeSize.Value.X);
                height = (int)(GameMain.GraphicsHeight * relativeSize.Value.Y);
            }
            if (minSize.HasValue)
            {
                width = Math.Max(width, minSize.Value.X);
                if (height > 0)
                {
                    height = Math.Max(height, minSize.Value.Y);
                }
            }

            InnerFrame = new GUIFrame(new RectTransform(new Point(width, height), RectTransform, type == Type.InGame ? Anchor.TopCenter : Anchor.Center)
            {
                IsFixedSize = false
            }, style: null);
            GUI.Style.Apply(InnerFrame, "", this);
            this.type = type;
            Tag       = tag;

            if (type == Type.Default)
            {
                Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center))
                {
                    AbsoluteSpacing = 5
                };

                Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform),
                                          headerText, font: GUI.SubHeadingFont, textAlignment: Alignment.Center, wrap: true);
                GUI.Style.Apply(Header, "", this);
                Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);

                if (!string.IsNullOrWhiteSpace(text))
                {
                    Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true);
                    GUI.Style.Apply(Text, "", this);
                    Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
                        new Point(Text.Rect.Width, Text.Rect.Height);
                    Text.RectTransform.IsFixedSize = true;
                }

                var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), Content.RectTransform, Anchor.BottomCenter), childAnchor: Anchor.TopCenter)
                {
                    AbsoluteSpacing    = 5,
                    IgnoreLayoutGroups = true
                };

                int buttonSize  = 35;
                var buttonStyle = GUI.Style.GetComponentStyle("GUIButton");
                if (buttonStyle != null && buttonStyle.Height.HasValue)
                {
                    buttonSize = buttonStyle.Height.Value;
                }

                buttonContainer.RectTransform.NonScaledSize = buttonContainer.RectTransform.MinSize = buttonContainer.RectTransform.MaxSize =
                    new Point(buttonContainer.Rect.Width, (int)((buttonSize + 5) * buttons.Length));
                buttonContainer.RectTransform.IsFixedSize = true;

                if (height == 0)
                {
                    height += Header.Rect.Height + Content.AbsoluteSpacing;
                    height += (Text == null ? 0 : Text.Rect.Height) + Content.AbsoluteSpacing;
                    height += buttonContainer.Rect.Height + 20;
                    if (minSize.HasValue)
                    {
                        height = Math.Max(height, minSize.Value.Y);
                    }

                    InnerFrame.RectTransform.NonScaledSize =
                        new Point(InnerFrame.Rect.Width, (int)Math.Max(height / Content.RectTransform.RelativeSize.Y, height + (int)(50 * GUI.yScale)));
                    Content.RectTransform.NonScaledSize =
                        new Point(Content.Rect.Width, height);
                }

                Buttons = new List <GUIButton>(buttons.Length);
                for (int i = 0; i < buttons.Length; i++)
                {
                    var button = new GUIButton(new RectTransform(new Vector2(0.6f, 1.0f / buttons.Length), buttonContainer.RectTransform), buttons[i]);
                    Buttons.Add(button);
                }
            }
            else if (type == Type.InGame)
            {
                InnerFrame.RectTransform.AbsoluteOffset = new Point(0, GameMain.GraphicsHeight);
                alwaysVisible = true;
                CanBeFocused  = false;
                GUI.Style.Apply(InnerFrame, "", this);

                var horizontalLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.98f, 0.95f), InnerFrame.RectTransform, Anchor.Center),
                                                               isHorizontal: true, childAnchor: Anchor.CenterLeft)
                {
                    Stretch         = true,
                    RelativeSpacing = 0.02f
                };
                if (icon != null)
                {
                    Icon = new GUIImage(new RectTransform(new Vector2(0.2f, 0.95f), horizontalLayoutGroup.RectTransform), icon, scaleToFit: true);
                }

                Content = new GUILayoutGroup(new RectTransform(new Vector2(icon != null ? 0.65f : 0.85f, 1.0f), horizontalLayoutGroup.RectTransform));

                var buttonContainer = new GUIFrame(new RectTransform(new Vector2(0.15f, 1.0f), horizontalLayoutGroup.RectTransform), style: null);
                Buttons = new List <GUIButton>(1)
                {
                    new GUIButton(new RectTransform(new Vector2(0.5f, 0.5f), buttonContainer.RectTransform, Anchor.Center),
                                  style: "GUIButtonHorizontalArrow")
                    {
                        OnClicked = Close
                    }
                };

                Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), headerText, wrap: true);
                GUI.Style.Apply(Header, "", this);
                Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);

                if (!string.IsNullOrWhiteSpace(text))
                {
                    Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true);
                    GUI.Style.Apply(Text, "", this);
                    Content.Recalculate();
                    Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
                        new Point(Text.Rect.Width, Text.Rect.Height);
                    Text.RectTransform.IsFixedSize = true;
                }

                if (height == 0)
                {
                    height += Header.Rect.Height + Content.AbsoluteSpacing;
                    height += (Text == null ? 0 : Text.Rect.Height) + Content.AbsoluteSpacing;
                    if (minSize.HasValue)
                    {
                        height = Math.Max(height, minSize.Value.Y);
                    }

                    InnerFrame.RectTransform.NonScaledSize =
                        new Point(InnerFrame.Rect.Width, (int)Math.Max(height / Content.RectTransform.RelativeSize.Y, height + (int)(50 * GUI.yScale)));
                    Content.RectTransform.NonScaledSize =
                        new Point(Content.Rect.Width, height);
                }
                Buttons[0].RectTransform.MaxSize = new Point(Math.Min(Buttons[0].Rect.Width, Buttons[0].Rect.Height));
            }

            MessageBoxes.Add(this);
        }
        public GUIMessageBox(string headerText, string text, string[] buttons, Vector2?relativeSize = null, Point?minSize = null, Alignment textAlignment = Alignment.TopLeft, Type type = Type.Default, string tag = "", Sprite icon = null, string iconStyle = "", Sprite backgroundIcon = null)
            : base(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas, Anchor.Center), style: GUI.Style.GetComponentStyle("GUIMessageBox." + type) != null ? "GUIMessageBox." + type : "GUIMessageBox")
        {
            int width = (int)(DefaultWidth * (type == Type.Default ? 1.0f : 1.5f)), height = 0;

            if (relativeSize.HasValue)
            {
                width  = (int)(GameMain.GraphicsWidth * relativeSize.Value.X);
                height = (int)(GameMain.GraphicsHeight * relativeSize.Value.Y);
            }
            if (minSize.HasValue)
            {
                width = Math.Max(width, minSize.Value.X);
                if (height > 0)
                {
                    height = Math.Max(height, minSize.Value.Y);
                }
            }

            if (backgroundIcon != null)
            {
                BackgroundIcon = new GUIImage(new RectTransform(backgroundIcon.size.ToPoint(), RectTransform), backgroundIcon)
                {
                    IgnoreLayoutGroups = true,
                    Color = Color.Transparent
                };
            }

            Anchor anchor = type switch
            {
                Type.InGame => Anchor.TopCenter,
                Type.Vote => Anchor.TopRight,
                _ => Anchor.Center
            };

            InnerFrame = new GUIFrame(new RectTransform(new Point(width, height), RectTransform, anchor)
            {
                IsFixedSize = false
            }, style: null);
            if (type == Type.Vote)
            {
                int offset = GUI.IntScale(64);
                InnerFrame.RectTransform.ScreenSpaceOffset = new Point(-offset, offset);
                CanBeFocused = false;
            }
            GUI.Style.Apply(InnerFrame, "", this);
            this.type = type;
            Tag       = tag;

            if (type == Type.Default || type == Type.Vote)
            {
                Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center))
                {
                    AbsoluteSpacing = 5
                };

                Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform),
                                          headerText, font: GUI.SubHeadingFont, textAlignment: Alignment.Center, wrap: true);
                GUI.Style.Apply(Header, "", this);
                Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);

                if (!string.IsNullOrWhiteSpace(text))
                {
                    Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true);
                    GUI.Style.Apply(Text, "", this);
                    Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
                        new Point(Text.Rect.Width, Text.Rect.Height);
                    Text.RectTransform.IsFixedSize = true;
                }

                var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), Content.RectTransform, Anchor.BottomCenter), childAnchor: Anchor.TopCenter)
                {
                    AbsoluteSpacing    = 5,
                    IgnoreLayoutGroups = true
                };

                int buttonSize  = 35;
                var buttonStyle = GUI.Style.GetComponentStyle("GUIButton");
                if (buttonStyle != null && buttonStyle.Height.HasValue)
                {
                    buttonSize = buttonStyle.Height.Value;
                }

                buttonContainer.RectTransform.NonScaledSize = buttonContainer.RectTransform.MinSize = buttonContainer.RectTransform.MaxSize =
                    new Point(buttonContainer.Rect.Width, (int)((buttonSize + 5) * buttons.Length));
                buttonContainer.RectTransform.IsFixedSize = true;

                if (height == 0)
                {
                    height += Header.Rect.Height + Content.AbsoluteSpacing;
                    height += (Text == null ? 0 : Text.Rect.Height) + Content.AbsoluteSpacing;
                    height += buttonContainer.Rect.Height + 20;
                    if (minSize.HasValue)
                    {
                        height = Math.Max(height, minSize.Value.Y);
                    }

                    InnerFrame.RectTransform.NonScaledSize =
                        new Point(InnerFrame.Rect.Width, (int)Math.Max(height / Content.RectTransform.RelativeSize.Y, height + (int)(50 * GUI.yScale)));
                    Content.RectTransform.NonScaledSize =
                        new Point(Content.Rect.Width, height);
                }

                Buttons = new List <GUIButton>(buttons.Length);
                for (int i = 0; i < buttons.Length; i++)
                {
                    var button = new GUIButton(new RectTransform(new Vector2(0.6f, 1.0f / buttons.Length), buttonContainer.RectTransform), buttons[i]);
                    Buttons.Add(button);
                }
            }
            else if (type == Type.InGame)
            {
                InnerFrame.RectTransform.AbsoluteOffset = new Point(0, GameMain.GraphicsHeight);
                alwaysVisible = true;
                CanBeFocused  = false;
                AutoClose     = true;
                GUI.Style.Apply(InnerFrame, "", this);

                var horizontalLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.98f, 0.95f), InnerFrame.RectTransform, Anchor.Center),
                                                               isHorizontal: true, childAnchor: Anchor.CenterLeft)
                {
                    Stretch         = true,
                    RelativeSpacing = 0.02f
                };
                if (icon != null)
                {
                    Icon = new GUIImage(new RectTransform(new Vector2(0.2f, 0.95f), horizontalLayoutGroup.RectTransform), icon, scaleToFit: true);
                }
                else if (iconStyle != string.Empty)
                {
                    Icon = new GUIImage(new RectTransform(new Vector2(0.2f, 0.95f), horizontalLayoutGroup.RectTransform), iconStyle, scaleToFit: true);
                }

                Content = new GUILayoutGroup(new RectTransform(new Vector2(Icon != null ? 0.65f : 0.85f, 1.0f), horizontalLayoutGroup.RectTransform));

                var buttonContainer = new GUIFrame(new RectTransform(new Vector2(0.15f, 1.0f), horizontalLayoutGroup.RectTransform), style: null);
                Buttons = new List <GUIButton>(1)
                {
                    new GUIButton(new RectTransform(new Vector2(0.3f, 0.5f), buttonContainer.RectTransform, Anchor.Center),
                                  style: "UIToggleButton")
                    {
                        OnClicked = Close
                    }
                };

                InputType?closeInput = null;
                if (GameMain.Config.KeyBind(InputType.Use).MouseButton == MouseButton.None)
                {
                    closeInput = InputType.Use;
                }
                else if (GameMain.Config.KeyBind(InputType.Select).MouseButton == MouseButton.None)
                {
                    closeInput = InputType.Select;
                }
                if (closeInput.HasValue)
                {
                    Buttons[0].ToolTip = TextManager.ParseInputTypes($"{TextManager.Get("Close")} ([InputType.{closeInput.Value}])");
                    Buttons[0].OnAddedToGUIUpdateList += (GUIComponent component) =>
                    {
                        if (!closing && openState >= 1.0f && PlayerInput.KeyHit(closeInput.Value))
                        {
                            GUIButton btn = component as GUIButton;
                            btn?.OnClicked(btn, btn.UserData);
                            btn?.Flash(GUI.Style.Green);
                        }
                    };
                }

                Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), headerText, wrap: true);
                GUI.Style.Apply(Header, "", this);
                Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);

                if (!string.IsNullOrWhiteSpace(text))
                {
                    Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true);
                    GUI.Style.Apply(Text, "", this);
                    Content.Recalculate();
                    Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
                        new Point(Text.Rect.Width, Text.Rect.Height);
                    Text.RectTransform.IsFixedSize = true;
                    if (string.IsNullOrWhiteSpace(headerText))
                    {
                        Content.ChildAnchor = Anchor.Center;
                    }
                }

                if (height == 0)
                {
                    height += Header.Rect.Height + Content.AbsoluteSpacing;
                    height += (Text == null ? 0 : Text.Rect.Height) + Content.AbsoluteSpacing;
                    if (minSize.HasValue)
                    {
                        height = Math.Max(height, minSize.Value.Y);
                    }

                    InnerFrame.RectTransform.NonScaledSize =
                        new Point(InnerFrame.Rect.Width, (int)Math.Max(height / Content.RectTransform.RelativeSize.Y, height + (int)(50 * GUI.yScale)));
                    Content.RectTransform.NonScaledSize =
                        new Point(Content.Rect.Width, height);
                }
                Buttons[0].RectTransform.MaxSize = new Point((int)(0.4f * Buttons[0].Rect.Y), Buttons[0].Rect.Y);
            }

            MessageBoxes.Add(this);
        }
        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);
        }
        public GUIComponent CreateEditor(GUIComponent parent, List <SpriteDeformation> deformations, string parentDebugName)
        {
            var container = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.0f), parent.RectTransform))
            {
                AbsoluteSpacing = 5,
                CanBeFocused    = true
            };

            new GUITextBlock(new RectTransform(new Point(container.Rect.Width, (int)(60 * GUI.Scale)), container.RectTransform)
            {
                IsFixedSize = true
            },
                             "Sprite Deformations", textAlignment: Alignment.BottomCenter, font: GUI.LargeFont);

            var resolutionField = GUI.CreatePointField(new Point(subDivX + 1, subDivY + 1), (int)(30 * GUI.Scale), "Resolution", container.RectTransform,
                                                       "How many vertices the deformable sprite has on the x and y axes. Larger values make the deformations look smoother, but are more performance intensive.");

            resolutionField.RectTransform.IsFixedSize = true;
            GUINumberInput xField = null, yField = null;

            foreach (GUIComponent child in resolutionField.GetAllChildren())
            {
                if (yField == null)
                {
                    yField = child as GUINumberInput;
                }
                else
                {
                    xField = child as GUINumberInput;
                    if (xField != null)
                    {
                        break;
                    }
                }
            }
            xField.MinValueInt    = 2;
            xField.MaxValueInt    = SpriteDeformationParams.ShaderMaxResolution.X - 1;
            xField.OnValueChanged = (numberInput) => { ChangeResolution(); };
            yField.MinValueInt    = 2;
            yField.MaxValueInt    = SpriteDeformationParams.ShaderMaxResolution.Y - 1;
            yField.OnValueChanged = (numberInput) => { ChangeResolution(); };

            void ChangeResolution()
            {
                subDivX = xField.IntValue - 1;
                subDivY = yField.IntValue - 1;

                foreach (SpriteDeformation deformation in deformations)
                {
                    deformation.SetResolution(new Point(xField.IntValue, yField.IntValue));
                }
                SetupVertexBuffers();
                SetupIndexBuffer();
            }

            foreach (SpriteDeformation deformation in deformations)
            {
                var deformEditor = new SerializableEntityEditor(container.RectTransform, deformation.Params,
                                                                inGame: false, showName: true, titleFont: GUI.SubHeadingFont);
                deformEditor.RectTransform.MinSize = new Point(deformEditor.Rect.Width, deformEditor.Rect.Height);
            }

            var deformationDD = new GUIDropDown(new RectTransform(new Point(container.Rect.Width, 30), container.RectTransform), "Add new sprite deformation");

            deformationDD.OnSelected = (selected, userdata) =>
            {
                deformations.Add(SpriteDeformation.Load((string)userdata, parentDebugName));
                deformationDD.Text = "Add new sprite deformation";
                return(false);
            };

            foreach (string deformationType in SpriteDeformation.DeformationTypes)
            {
                deformationDD.AddItem(deformationType, deformationType);
            }

            container.RectTransform.Resize(new Point(
                                               container.Rect.Width, container.Children.Sum(c => c.Rect.Height + container.AbsoluteSpacing)), false);

            container.RectTransform.MinSize     = new Point(0, container.Rect.Height);
            container.RectTransform.MaxSize     = new Point(int.MaxValue, container.Rect.Height);
            container.RectTransform.IsFixedSize = true;
            container.Recalculate();

            return(container);
        }
Exemple #21
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 moddedDropdown = new GUIDropDown(new RectTransform(new Vector2(1f, 0.02f), leftColumn.RectTransform), "", 3);
                moddedDropdown.AddItem(TextManager.Get("clientpermission.all"), CategoryFilter.All);
                moddedDropdown.AddItem(TextManager.Get("servertag.modded.false"), CategoryFilter.Vanilla);
                moddedDropdown.AddItem(TextManager.Get("customrank"), CategoryFilter.Custom);
                moddedDropdown.Select(0);

                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); };

                moddedDropdown.OnSelected = (component, data) =>
                {
                    searchBox.Text = string.Empty;
                    subFilter      = (CategoryFilter)data;
                    UpdateSubList(SubmarineInfo.SavedSubmarines);
                    return(true);
                };

                subList.OnSelected = OnSubSelected;
            }
            else // 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),
                                                                       (isMultiplayer ? leftColumn : rightColumn).RectTransform)
            {
                MaxSize = new Point(int.MaxValue, 60)
            }, childAnchor: Anchor.BottomRight, isHorizontal: true);

            if (!isMultiplayer)
            {
                buttonContainer.IgnoreLayoutGroups = 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 (!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 (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(isMultiplayer ? SaveUtil.SaveType.Multiplayer : SaveUtil.SaveType.Singleplayer, saveNameBox.Text);
                    bool   hasRequiredContentPackages = selectedSub.RequiredContentPackagesInstalled;

                    CampaignSettings settings = new CampaignSettings();
                    if (isMultiplayer)
                    {
                        settings.RadiationEnabled = GameMain.NetLobbyScreen.IsRadiationEnabled();
                        settings.MaxMissionCount  = GameMain.NetLobbyScreen.GetMaxMissionCount();
                    }
                    else
                    {
                        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);
                                    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, settings);
                                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, settings);
                        if (isMultiplayer)
                        {
                            CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
                        }
                    }

                    return(true);
                }
            };

            InitialMoneyText = new GUITextBlock(new RectTransform(new Vector2(isMultiplayer ? 0.6f : 0.3f, 1f), buttonContainer.RectTransform), "", font: isMultiplayer ? GUI.Style.SmallFont : GUI.Style.Font, textColor: GUI.Style.Green)
            {
                TextGetter = () =>
                {
                    int initialMoney = CampaignMode.InitialMoney;
                    if (isMultiplayer)
                    {
                        if (GameMain.NetLobbyScreen.SelectedSub != null)
                        {
                            initialMoney -= GameMain.NetLobbyScreen.SelectedSub.Price;
                        }
                    }
                    else if (subList.SelectedData is SubmarineInfo subInfo)
                    {
                        initialMoney -= subInfo.Price;
                    }
                    initialMoney = Math.Max(initialMoney, isMultiplayer ? MultiPlayerCampaign.MinimumInitialMoney : 0);
                    return(TextManager.GetWithVariable("campaignstartingmoney", "[money]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", initialMoney)));
                }
            };

            if (!isMultiplayer)
            {
                CampaignCustomizeButton = new GUIButton(new RectTransform(new Vector2(0.25f, 1f), buttonContainer.RectTransform, Anchor.CenterLeft), TextManager.Get("SettingsButton"))
                {
                    OnClicked = (tb, userdata) =>
                    {
                        CreateCustomizeWindow();
                        return(true);
                    }
                };

                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);
        }