From 2199a0f97f350fcdd22b7450d58003c43bf523d7 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Fri, 3 May 2019 13:40:12 +0300 Subject: [PATCH] (276dcf6d2) Docking indicator changes color when the docking port is within the sector --- .../Source/GUI/GUIComponent.cs | 7 +- .../Source/GUI/GUIMessageBox.cs | 6 + .../BarotraumaClient/Source/GUI/GUITickBox.cs | 5 +- .../BarotraumaClient/Source/GameMain.cs | 10 +- .../Source/GameSession/CrewManager.cs | 66 +++++++- .../Source/Items/Components/Machines/Sonar.cs | 35 ++-- .../BarotraumaClient/Source/Map/Hull.cs | 27 +++ .../Source/Screens/CampaignSetupUI.cs | 2 - .../Source/Characters/AI/EnemyAIController.cs | 2 + .../Animation/FishAnimController.cs | 16 -- .../Source/Characters/Character.cs | 4 + .../BarotraumaShared/Source/Map/Submarine.cs | 14 -- .../BarotraumaShared/Source/TextManager.cs | 156 ------------------ 13 files changed, 128 insertions(+), 222 deletions(-) diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIComponent.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIComponent.cs index f67787327..de3fa157c 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUIComponent.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIComponent.cs @@ -132,6 +132,8 @@ namespace Barotrauma public bool IgnoreLayoutGroups; + public bool IgnoreLayoutGroups; + public virtual ScalableFont Font { get; @@ -515,6 +517,7 @@ namespace Barotrauma yield return CoroutineStatus.Running; } + toolTipBlock.SetTextPos(); SetAlpha(to); @@ -540,11 +543,9 @@ namespace Barotrauma OutlineColor = style.OutlineColor; - public virtual void Flash(Color? color = null, float flashDuration = 1.5f, bool useRectangleFlash = false, Vector2? flashRectInflate = null) + public virtual void Flash(Color? color = null, float flashDuration = 1.5f) { flashTimer = flashDuration; - this.flashRectInflate = flashRectInflate ?? Vector2.Zero; - this.useRectangleFlash = useRectangleFlash; this.flashDuration = flashDuration; flashColor = (color == null) ? Color.Red : (Color)color; } diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIMessageBox.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIMessageBox.cs index ec9c026e6..435c43066 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUIMessageBox.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIMessageBox.cs @@ -47,6 +47,12 @@ namespace Barotrauma Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 }; Tag = tag; + InnerFrame = new GUIFrame(new RectTransform(new Point(width, height), RectTransform, Anchor.Center) { IsFixedSize = false }, style: null); + GUI.Style.Apply(InnerFrame, "", this); + + Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 }; + Tag = tag; + if (height == 0) { string wrappedText = ToolBox.WrapText(text, Content.Rect.Width, GUI.Font); diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUITickBox.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUITickBox.cs index 913914243..889628213 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUITickBox.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUITickBox.cs @@ -44,10 +44,11 @@ namespace Barotrauma public Color TextColor { - get { return box; } + get { return text.TextColor; } + set { text.TextColor = value; } } - public GUITextBlock TextBlock + public override Rectangle MouseRect { get { diff --git a/Barotrauma/BarotraumaClient/Source/GameMain.cs b/Barotrauma/BarotraumaClient/Source/GameMain.cs index d795cbaea..f318ee077 100644 --- a/Barotrauma/BarotraumaClient/Source/GameMain.cs +++ b/Barotrauma/BarotraumaClient/Source/GameMain.cs @@ -180,6 +180,10 @@ namespace Barotrauma GUI.KeyboardDispatcher = new EventInput.KeyboardDispatcher(Window); + GUI.KeyboardDispatcher = new EventInput.KeyboardDispatcher(Window); + + + PerformanceCounter = new PerformanceCounter(); PerformanceCounter = new PerformanceCounter(); @@ -767,12 +771,6 @@ namespace Barotrauma Config.SaveNewPlayerConfig(); } - // ToDo: Move texts/links to localization, when possible. - public void ShowBugReporter() - { - var msgBox = new GUIMessageBox("", ""); - var linkHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), msgBox.Content.RectTransform)) { Stretch = true, RelativeSpacing = 0.05f }; - msgBox.Text.RectTransform.MaxSize = new Point(int.MaxValue, msgBox.Text.Rect.Height); linkHolder.RectTransform.MaxSize = new Point(int.MaxValue, linkHolder.Rect.Height); msgBox.RectTransform.MinSize = new Point(0, msgBox.Rect.Height + linkHolder.Rect.Height + msgBox.Buttons.First().Rect.Height * 8); diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs index 73c350584..d36d40a67 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs @@ -83,6 +83,66 @@ namespace Barotrauma break; } } + + var reports = Order.PrefabList.FindAll(o => o.TargetAllCharacters && o.SymbolSprite != null); + reportButtonFrame = new GUILayoutGroup(new RectTransform( + new Point((HUDLayoutSettings.CrewArea.Height - (int)((reports.Count - 1) * 5 * GUI.Scale)) / reports.Count, HUDLayoutSettings.CrewArea.Height), guiFrame.RectTransform)) + { + AbsoluteSpacing = (int)(5 * GUI.Scale), + UserData = "reportbuttons", + CanBeFocused = false + }; + + //report buttons + foreach (Order order in reports) + { + if (!order.TargetAllCharacters || order.SymbolSprite == null) continue; + var btn = new GUIButton(new RectTransform(new Point(reportButtonFrame.Rect.Width), reportButtonFrame.RectTransform), style: null) + { + OnClicked = (GUIButton button, object userData) => + { + if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) return false; + SetCharacterOrder(null, order, null, Character.Controlled); + HumanAIController.PropagateHullSafety(Character.Controlled, Character.Controlled.CurrentHull); + return true; + }, + UserData = order, + ToolTip = order.Name + }; + + new GUIFrame(new RectTransform(new Vector2(1.5f), btn.RectTransform, Anchor.Center), "OuterGlow") + { + Color = Color.Red * 0.8f, + HoverColor = Color.Red * 1.0f, + PressedColor = Color.Red * 0.6f, + UserData = "highlighted", + CanBeFocused = false, + Visible = false + }; + + var img = new GUIImage(new RectTransform(Vector2.One, btn.RectTransform), order.Prefab.SymbolSprite, scaleToFit: true) + { + Color = order.Color, + HoverColor = Color.Lerp(order.Color, Color.White, 0.5f), + ToolTip = order.Name + }; + } + + screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight); + + prevUIScale = GUI.Scale; + + ToggleCrewAreaOpen = GameMain.Config.CrewMenuOpen; + } + + + #endregion + + #region Character list management + + public Rectangle GetCharacterListArea() + { + return characterListBox.Rect; } partial void InitProjectSpecific() @@ -829,12 +889,6 @@ namespace Barotrauma matchingItems.RemoveAll(it => it.Submarine != submarine && !submarine.DockedTo.Contains(it.Submarine)); matchingItems.RemoveAll(it => it.Submarine != null && it.Submarine.IsOutpost); } - var characterElement = characterListBox.Content.FindChild(character); - GUIButton orderBtn = characterElement.FindChild(order, recursive: true) as GUIButton; - if (orderBtn.Frame.FlashTimer <= 0) - { - orderBtn.Flash(color, 1.5f, false, flashRectInflate); - } //more than one target item -> create a minimap-like selection with a pic of the sub if (matchingItems.Count > 1) diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs index 557a747f3..dad5f0b1d 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs @@ -601,54 +601,55 @@ namespace Barotrauma.Items.Components Vector2 midPos = (sourcePortPos + targetPortPos) / 2.0f; System.Diagnostics.Debug.Assert(steering.DockingSource.IsHorizontal == steering.DockingTarget.IsHorizontal); - float dist = Vector2.Distance(steering.DockingSource.Item.WorldPosition, steering.DockingTarget.Item.WorldPosition); - dist *= Physics.DisplayToRealWorldRatio; - - Vector2 dockingDir = Vector2.Normalize(sourcePortPos - targetPortPos); + Vector2 diff = steering.DockingTarget.Item.WorldPosition - steering.DockingSource.Item.WorldPosition; + float dist = diff.Length(); + + Vector2 dockingDir = sourcePortPos - targetPortPos; + Vector2 normalizedDockingDir = Vector2.Normalize(dockingDir); if (steering.DockingSource.IsHorizontal) { - dockingDir = new Vector2(Math.Sign(dockingDir.X), 0.0f); + normalizedDockingDir = new Vector2(Math.Sign(normalizedDockingDir.X), 0.0f); } else { - dockingDir = new Vector2(0.0f, Math.Sign(dockingDir.Y)); + normalizedDockingDir = new Vector2(0.0f, Math.Sign(normalizedDockingDir.Y)); } Color staticLineColor = Color.White * 0.8f; - float sector = MathHelper.ToRadians(MathHelper.Lerp(10.0f, 45.0f, MathHelper.Clamp(dist / 20.0f, 0.0f, 1.0f))); + float sector = MathHelper.ToRadians(MathHelper.Lerp(10.0f, 45.0f, MathHelper.Clamp(dist / steering.DockingAssistThreshold, 0.0f, 1.0f))); float sectorLength = DisplayRadius; //use law of cosines to calculate the length of the center line float midLength = (float)(Math.Cos(sector) * sectorLength); - Vector2 midNormal = new Vector2(-dockingDir.Y, dockingDir.X); + Vector2 midNormal = new Vector2(-normalizedDockingDir.Y, normalizedDockingDir.X); - DrawLine(spriteBatch, targetPortPos, targetPortPos + dockingDir * midLength, staticLineColor, width: 2); + DrawLine(spriteBatch, targetPortPos, targetPortPos + normalizedDockingDir * midLength, staticLineColor, width: 2); DrawLine(spriteBatch, targetPortPos, - targetPortPos + MathUtils.RotatePoint(dockingDir, sector) * sectorLength, staticLineColor, width: 2); + targetPortPos + MathUtils.RotatePoint(normalizedDockingDir, sector) * sectorLength, staticLineColor, width: 2); DrawLine(spriteBatch, targetPortPos, - targetPortPos + MathUtils.RotatePoint(dockingDir, -sector) * sectorLength, staticLineColor, width: 2); + targetPortPos + MathUtils.RotatePoint(normalizedDockingDir, -sector) * sectorLength, staticLineColor, width: 2); for (float z = 0; z < 1.0f; z += 0.1f * zoom) { - Vector2 linePos = targetPortPos + dockingDir * midLength * z; + Vector2 linePos = targetPortPos + normalizedDockingDir * midLength * z; DrawLine(spriteBatch, linePos + midNormal * 3.0f, linePos - midNormal * 3.0f, staticLineColor, width: 2); } - float indicatorSector = sector * 0.75f; float indicatorSectorLength = (float)(midLength / Math.Cos(indicatorSector)); bool withinSector = - Vector2.Dot(dockingDir, MathUtils.RotatePoint(dockingDir, indicatorSector)) < - Vector2.Dot(dockingDir, Vector2.Normalize(steering.DockingSource.Item.WorldPosition - steering.DockingTarget.Item.WorldPosition)); + (Math.Abs(diff.X) < steering.DockingSource.DistanceTolerance.X && Math.Abs(diff.Y) < steering.DockingSource.DistanceTolerance.Y) || + Vector2.Dot(normalizedDockingDir, MathUtils.RotatePoint(normalizedDockingDir, indicatorSector)) < + Vector2.Dot(normalizedDockingDir, Vector2.Normalize(dockingDir)); Color indicatorColor = withinSector ? Color.LightGreen * 0.9f : Color.Red * 0.9f; DrawLine(spriteBatch, targetPortPos, - targetPortPos + MathUtils.RotatePoint(dockingDir,indicatorSector) * indicatorSectorLength, indicatorColor, width: 2); + targetPortPos + MathUtils.RotatePoint(normalizedDockingDir,indicatorSector) * indicatorSectorLength, indicatorColor, width: 2); DrawLine(spriteBatch, targetPortPos, - targetPortPos + MathUtils.RotatePoint(dockingDir, -indicatorSector) * indicatorSectorLength, indicatorColor, width: 2); + targetPortPos + MathUtils.RotatePoint(normalizedDockingDir, -indicatorSector) * indicatorSectorLength, indicatorColor, width: 2); /*if (steering.DockingSource.IsHorizontal) { diff --git a/Barotrauma/BarotraumaClient/Source/Map/Hull.cs b/Barotrauma/BarotraumaClient/Source/Map/Hull.cs index 6f5fad842..b755074bb 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Hull.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Hull.cs @@ -353,6 +353,33 @@ namespace Barotrauma Color.Green, width: 2); } } + + foreach (MapEntity e in linkedTo) + { + if (e is Hull) + { + Hull linkedHull = (Hull)e; + Rectangle connectedHullRect = e.Submarine == null ? + linkedHull.rect : + new Rectangle( + (int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X), + (int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y), + linkedHull.WorldRect.Width, linkedHull.WorldRect.Height); + + //center of the hull + Rectangle currentHullRect = Submarine == null ? + WorldRect : + new Rectangle( + (int)(Submarine.DrawPosition.X + WorldPosition.X), + (int)(Submarine.DrawPosition.Y + WorldPosition.Y), + WorldRect.Width, WorldRect.Height); + + GUI.DrawLine(spriteBatch, + new Vector2(currentHullRect.X, -currentHullRect.Y), + new Vector2(connectedHullRect.X, -connectedHullRect.Y), + Color.Green, width: 2); + } + } } public static void UpdateVertices(GraphicsDevice graphicsDevice, Camera cam, WaterRenderer renderer) diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs b/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs index 954fe58e9..d4d830e8b 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs @@ -20,8 +20,6 @@ namespace Barotrauma private GUILayoutGroup subPreviewContainer; - private GUILayoutGroup subPreviewContainer; - private GUIButton loadGameButton; public Action StartNewGame; diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs index 26be7ee85..2530dcbb2 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs @@ -1049,6 +1049,8 @@ namespace Barotrauma private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure; + private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure; + //goes through all the AItargets, evaluates how preferable it is to attack the target, //whether the Character can see/hear the target and chooses the most preferable target within //sight/hearing range diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Animation/FishAnimController.cs b/Barotrauma/BarotraumaShared/Source/Characters/Animation/FishAnimController.cs index 905e06237..6f049f1a6 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Animation/FishAnimController.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Animation/FishAnimController.cs @@ -730,22 +730,6 @@ namespace Barotrauma limb?.body.SmoothRotate(angle, torque, wrapAngle: false); } - private void SmoothRotateWithoutWrapping(Limb limb, float angle, Limb referenceLimb, float torque) - { - //make sure the angle "has the same number of revolutions" as the reference limb - //(e.g. we don't want to rotate the legs to 0 if the torso is at 360, because that'd blow up the hip joints) - while (referenceLimb.Rotation - angle > MathHelper.TwoPi) - { - angle += MathHelper.TwoPi; - } - while (referenceLimb.Rotation - angle < -MathHelper.TwoPi) - { - angle -= MathHelper.TwoPi; - } - - limb?.body.SmoothRotate(angle, torque, wrapAngle: false); - } - public override void Flip() { base.Flip(); diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs index 90321ed94..ad8a17f33 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs @@ -2555,6 +2555,10 @@ namespace Barotrauma GameMain.GameSession?.CrewManager?.RemoveCharacter(this); #endif +#if CLIENT + GameMain.GameSession?.CrewManager?.RemoveCharacter(this); +#endif + #if CLIENT GameMain.GameSession?.CrewManager?.RemoveCharacter(this); #endif diff --git a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs index 9167e2774..ab486666c 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs @@ -536,20 +536,6 @@ namespace Barotrauma { maxX = Math.Min(maxX, ruin.Area.X - 100.0f); } - else - { - maxX = Math.Min(maxX, ruin.Area.X - 100.0f); - } - } - - if (minX < 0.0f && maxX > Level.Loaded.Size.X) - { - //no walls found at either side, just use the initial spawnpos and hope for the best - } - else if (minX < 0) - { - //no wall found at the left side, spawn to the left from the right-side wall - spawnPos.X = maxX - minWidth - 100.0f + subDockingPortOffset; } if (minX < 0.0f && maxX > Level.Loaded.Size.X) diff --git a/Barotrauma/BarotraumaShared/Source/TextManager.cs b/Barotrauma/BarotraumaShared/Source/TextManager.cs index d1d47b5ad..52df9ac7b 100644 --- a/Barotrauma/BarotraumaShared/Source/TextManager.cs +++ b/Barotrauma/BarotraumaShared/Source/TextManager.cs @@ -274,162 +274,6 @@ namespace Barotrauma return allText; } - public static string GetFormatted(string textTag, bool returnNull = false, params object[] args) - { - string text = Get(textTag, returnNull); - - if (text == null || text.Length == 0) - { - if (returnNull) - { - return null; - } - else - { - DebugConsole.ThrowError("Text \"" + textTag + "\" not found."); - return textTag; - } - } - - return string.Format(text, args); - } - - // Format: ServerMessage.Identifier1/ServerMessage.Indentifier2~[variable1]=value~[variable2]=value - public static string GetServerMessage(string serverMessage) - { - if (!textPacks.ContainsKey(Language)) - { - DebugConsole.ThrowError("No text packs available for the selected language (" + Language + ")! Switching to English..."); - Language = "English"; - if (!textPacks.ContainsKey(Language)) - { - throw new Exception("No text packs available in English!"); - } - } - - string[] messages = serverMessage.Split('/'); - - try - { - for (int i = 0; i < messages.Length; i++) - { - if (!IsServerMessageWithVariables(messages[i])) // No variables, try to translate - { - if (messages[i].Contains(" ")) continue; // Spaces found, do not translate - string msg = Get(messages[i], true); - if (msg != null) // If a translation was found, otherwise use the original - { - messages[i] = msg; - } - } - else - { - string[] messageWithVariables = messages[i].Split('~'); - string msg = Get(messageWithVariables[0], true); - - if (msg != null) // If a translation was found, otherwise use the original - { - messages[i] = msg; - } - else - { - continue; // No translation found, probably caused by player input -> skip variable handling - } - - // First index is always the message identifier -> start at 1 - for (int j = 1; j < messageWithVariables.Length; j++) - { - string[] variableAndValue = messageWithVariables[j].Split('='); - messages[i] = messages[i].Replace(variableAndValue[0], variableAndValue[1]); - } - } - } - - string translatedServerMessage = string.Empty; - for (int i = 0; i < messages.Length; i++) - { - translatedServerMessage += messages[i]; - } - return translatedServerMessage; - } - - catch (IndexOutOfRangeException exception) - { - string errorMsg = "Failed to translate server message \"" + serverMessage + "\"."; -#if DEBUG - DebugConsole.ThrowError(errorMsg, exception); -#endif - GameAnalyticsManager.AddErrorEventOnce("TextManager.GetServerMessage:" + serverMessage, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); - return errorMsg; - } - } - - public static bool IsServerMessageWithVariables(string message) - { - for (int i = 0; i < serverMessageCharacters.Length; i++) - { - if (!message.Contains(serverMessageCharacters[i])) return false; - } - - return true; - } - - public static List GetAll(string textTag) - { - if (!textPacks.ContainsKey(Language)) - { - DebugConsole.ThrowError("No text packs available for the selected language (" + Language + ")! Switching to English..."); - Language = "English"; - if (!textPacks.ContainsKey(Language)) - { - throw new Exception("No text packs available in English!"); - } - } - - List allText; - - foreach (TextPack textPack in textPacks[Language]) - { - allText = textPack.GetAll(textTag); - if (allText != null) return allText; - } - - //if text was not found and we're using a language other than English, see if we can find an English version - //may happen, for example, if a user has selected another language and using mods that haven't been translated to that language - if (Language != "English" && textPacks.ContainsKey("English")) - { - foreach (TextPack textPack in textPacks["English"]) - { - allText = textPack.GetAll(textTag); - if (allText != null) return allText; - } - } - - return null; - } - - public static List> GetAllTagTextPairs() - { - if (!textPacks.ContainsKey(Language)) - { - DebugConsole.ThrowError("No text packs available for the selected language (" + Language + ")! Switching to English..."); - Language = "English"; - if (!textPacks.ContainsKey(Language)) - { - throw new Exception("No text packs available in English!"); - } - } - - List> allText = new List>(); - - foreach (TextPack textPack in textPacks[Language]) - { - allText.AddRange(textPack.GetAllTagTextPairs()); - } - - return allText; - } - public static string ReplaceGenderPronouns(string text, Gender gender) { if (gender == Gender.Male)