Unstable 1.1.14.0

This commit is contained in:
Markus Isberg
2023-10-02 16:43:54 +03:00
parent 94f5a93a0c
commit cf8f0de659
606 changed files with 21906 additions and 11456 deletions
@@ -38,6 +38,7 @@ namespace Barotrauma
private float prevUIScale;
private readonly GUIFrame channelSettingsFrame;
private readonly GUITextBlock radioJammedWarning;
private readonly GUITextBox channelText;
private readonly GUILayoutGroup channelPickerContent;
private readonly GUIButton memButton;
@@ -107,6 +108,13 @@ namespace Barotrauma
RelativeSpacing = 0.01f
};
radioJammedWarning = new GUITextBlock(new RectTransform(Vector2.One, channelSettingsFrame.RectTransform), TextManager.Get("radiojammedwarning"),
textColor: GUIStyle.Orange, color: Color.Black,
textAlignment: Alignment.Center, style: "OuterGlow")
{
ToolTip = TextManager.Get("hint.radiojammed")
};
var buttonLeft = new GUIButton(new RectTransform(new Vector2(0.1f, 0.8f), channelSettingsContent.RectTransform), style: "DeviceButton")
{
PlaySoundOnSelect = false,
@@ -643,7 +651,7 @@ namespace Barotrauma
ToggleButton.RectTransform.AbsoluteOffset = new Point(GUIFrame.Rect.Right, GUIFrame.Rect.Y + HUDLayoutSettings.ChatBoxArea.Height - ToggleButton.Rect.Height);
}
if (Character.Controlled != null && ChatMessage.CanUseRadio(Character.Controlled, out WifiComponent radio))
if (Character.Controlled != null && ChatMessage.CanUseRadio(Character.Controlled, out WifiComponent radio, ignoreJamming: true))
{
if (prevRadio != radio)
{
@@ -672,10 +680,11 @@ namespace Barotrauma
}
}
channelSettingsFrame.Visible = true;
radioJammedWarning.Visible = radio is { JamTimer: > 0 };
}
else
{
channelSettingsFrame.Visible = false;
radioJammedWarning.Visible = channelSettingsFrame.Visible = false;
channelPickerContent.Children.First().CanBeFocused = true;
channelMemPending = false;
memButton.Enabled = true;
@@ -756,7 +756,7 @@ namespace Barotrauma
private bool CreateRenamingComponent(GUIButton button, object userData)
{
if (!HasPermission || !(userData is CharacterInfo characterInfo)) { return false; }
if (!HasPermission || userData is not 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)
@@ -843,7 +843,7 @@ namespace Barotrauma
private bool FireCharacter(GUIButton button, object selection)
{
if (!(selection is CharacterInfo characterInfo)) { return false; }
if (selection is not CharacterInfo characterInfo) { return false; }
campaign.CrewManager.FireCharacter(characterInfo);
SelectCharacter(null, null, null);
@@ -161,7 +161,7 @@ namespace Barotrauma
return 1;
}
return string.Compare(file1, file2);
return string.Compare(file1, file2, StringComparison.OrdinalIgnoreCase);
}
private static void InitIfNecessary()
@@ -419,6 +419,8 @@ namespace Barotrauma
};
}
fileList.Content.RectTransform.SortChildren(SortFiles);
directoryBox!.Text = currentDirectory;
fileBox!.Text = "";
fileList.Deselect();
@@ -111,7 +111,7 @@ namespace Barotrauma
/// </summary>
public static float AspectRatioAdjustment => HorizontalAspectRatio < 1.4f ? (1.0f - (1.4f - HorizontalAspectRatio)) : 1.0f;
public static bool IsUltrawide => HorizontalAspectRatio > 2.0f;
public static bool IsUltrawide => HorizontalAspectRatio > 2.3f;
public static int UIWidth
{
@@ -1010,16 +1010,13 @@ namespace Barotrauma
// Sub editor drag and highlight
case SubEditorScreen editor:
{
foreach (var mapEntity in MapEntity.mapEntityList)
if (MapEntity.StartMovingPos != Vector2.Zero || MapEntity.Resizing)
{
if (MapEntity.StartMovingPos != Vector2.Zero)
{
return CursorState.Dragging;
}
if (mapEntity.IsHighlighted)
{
return CursorState.Hand;
}
return CursorState.Dragging;
}
if (MapEntity.HighlightedEntities.Any(h => !h.IsSelected))
{
return CursorState.Hand;
}
break;
}
@@ -2438,13 +2435,14 @@ namespace Barotrauma
var pauseMenuInner = new GUIFrame(new RectTransform(new Vector2(0.13f, 0.3f), PauseMenu.RectTransform, Anchor.Center) { MinSize = new Point(250, 300) });
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.7f, 0.6f), pauseMenuInner.RectTransform, Anchor.Center))
float padding = 0.06f;
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.7f, 0.8f), pauseMenuInner.RectTransform, Anchor.BottomCenter) { RelativeOffset = new Vector2(0.0f, padding) })
{
Stretch = true,
RelativeSpacing = 0.05f
AbsoluteSpacing = IntScale(15)
};
new GUIButton(new RectTransform(new Vector2(0.1f, 0.1f), pauseMenuInner.RectTransform, Anchor.TopRight) { AbsoluteOffset = new Point((int)(15 * GUI.Scale)) },
new GUIButton(new RectTransform(new Vector2(0.1f, 0.07f), pauseMenuInner.RectTransform, Anchor.TopRight) { RelativeOffset = new Vector2(padding) },
"", style: "GUIBugButton")
{
IgnoreLayoutGroups = true,
@@ -2520,6 +2518,13 @@ namespace Barotrauma
}
GUITextBlock.AutoScaleAndNormalize(buttonContainer.Children.Where(c => c is GUIButton).Select(c => ((GUIButton)c).TextBlock));
//scale to ensure there's enough room for all the buttons
pauseMenuInner.RectTransform.MinSize = new Point(
pauseMenuInner.RectTransform.MinSize.X,
Math.Max(
(int)(buttonContainer.Children.Sum(c => c.Rect.Height + buttonContainer.AbsoluteSpacing) / buttonContainer.RectTransform.RelativeSize.Y),
pauseMenuInner.RectTransform.MinSize.X));
}
void CreateButton(string textTag, GUIComponent parent, Action action, string verificationTextTag = null)
@@ -781,7 +781,7 @@ namespace Barotrauma
if (toolTipBlock.Rect.Right > GameMain.GraphicsWidth - 10)
{
toolTipBlock.RectTransform.AbsoluteOffset -= new Point(toolTipBlock.Rect.Width, 0);
toolTipBlock.RectTransform.AbsoluteOffset -= new Point(toolTipBlock.Rect.Width + targetElement.Width, 0);
}
if (toolTipBlock.Rect.Bottom > GameMain.GraphicsHeight - 10)
{
@@ -49,7 +49,7 @@ namespace Barotrauma
get { return lifeTime; }
}
public ScalableFont Font
public GUIFont Font
{
get;
private set;
@@ -69,7 +69,7 @@ namespace Barotrauma
}
}
public GUIMessage(string text, Color color, float lifeTime, ScalableFont font = null)
public GUIMessage(string text, Color color, float lifeTime, GUIFont font = null)
{
coloredText = new ColoredText(text, color, false, false);
this.lifeTime = lifeTime;
@@ -81,7 +81,7 @@ namespace Barotrauma
Font = font;
}
public GUIMessage(string text, Color color, Vector2 position, Vector2 velocity, float lifeTime, Alignment textAlignment = Alignment.Center, ScalableFont font = null, Submarine sub = null)
public GUIMessage(string text, Color color, Vector2 position, Vector2 velocity, float lifeTime, Alignment textAlignment = Alignment.Center, GUIFont font = null, Submarine sub = null)
{
coloredText = new ColoredText(text, color, false, false);
WorldSpace = true;
@@ -693,5 +693,52 @@ namespace Barotrauma
rectT.Parent = RectTransform;
Buttons.Add(new GUIButton(rectT, text) { OnClicked = onClick });
}
public static GUIMessageBox CreateLoadingBox(LocalizedString text, (LocalizedString Label, Action<GUIMessageBox> Action)[] buttons = null, Vector2? relativeSize = null)
{
buttons ??= Array.Empty<(LocalizedString Label, Action<GUIMessageBox> Action)>();
var relativeSizeFallback = relativeSize ?? (0.7f, 0.5f);
var newMessageBox = new GUIMessageBox(
headerText: "",
text: "",
relativeSize: relativeSizeFallback,
buttons: buttons.Select(b => b.Label).ToArray());
newMessageBox.InnerFrame.RectTransform.ScaleBasis = ScaleBasis.BothHeight;
for (int i = 0; i < buttons.Length; i++)
{
var capturedIndex = i;
newMessageBox.Buttons[i].OnClicked = (_, _) =>
{
buttons[capturedIndex].Action(newMessageBox);
return false;
};
}
const float throbberSize = 0.25f;
new GUITextBlock(
new RectTransform((0.9f, 0f), newMessageBox.InnerFrame.RectTransform, Anchor.Center, Pivot.BottomCenter) { RelativeOffset = (0f, -throbberSize * 0.5f) },
text: text, textAlignment: Alignment.Center, wrap: true);
// Throbber
new GUICustomComponent(
new RectTransform(Vector2.One * throbberSize, newMessageBox.InnerFrame.RectTransform, Anchor.Center, scaleBasis: ScaleBasis.BothHeight),
onDraw: static (sb, component) =>
{
GUIStyle.GenericThrobber.Draw(
sb,
spriteIndex: (int)(Timing.TotalTime * 20f) % GUIStyle.GenericThrobber.FrameCount,
pos: component.Rect.Center.ToVector2(),
color: Color.White,
origin: GUIStyle.GenericThrobber.FrameSize.ToVector2() * 0.5f,
rotate: 0f,
scale: component.Rect.Size.ToVector2() / GUIStyle.GenericThrobber.FrameSize.ToVector2());
});
MessageBoxes.Remove(newMessageBox);
MessageBoxes.Insert(0, newMessageBox);
return newMessageBox;
}
}
}
@@ -132,7 +132,7 @@ namespace Barotrauma
if (subElement.NameAsIdentifier() != "override") { continue; }
if (ScalableFont.ExtractShccFromXElement(subElement).HasFlag(flag))
{
return new ScalableFont(subElement, GameMain.Instance.GraphicsDevice);
return new ScalableFont(subElement, font.Size, GameMain.Instance.GraphicsDevice);
}
}
@@ -4,7 +4,7 @@ using Microsoft.Xna.Framework.Graphics;
namespace Barotrauma
{
public class GUIScissorComponent: GUIComponent
public sealed class GUIScissorComponent : GUIComponent
{
public GUIComponent Content;
@@ -14,19 +14,14 @@ namespace Barotrauma
{
CanBeFocused = false
};
rectT.ChildrenChanged += CheckForChildren;
}
protected override void Update(float deltaTime)
private void CheckForChildren(RectTransform rectT)
{
base.Update(deltaTime);
foreach (GUIComponent child in Children)
{
if (child == Content) { continue; }
throw new InvalidOperationException($"Children were found in {nameof(GUIScissorComponent)}, Add them to {nameof(GUIScissorComponent)}.{nameof(Content)} instead.");
}
ClampChildMouseRects(Content);
if (rectT == Content.RectTransform) { return; }
throw new InvalidOperationException($"Children were found in {nameof(GUIScissorComponent)}, Add them to {nameof(GUIScissorComponent)}.{nameof(Content)} instead.");
}
public override void DrawChildren(SpriteBatch spriteBatch, bool recursive)
@@ -57,7 +52,13 @@ namespace Barotrauma
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: prevRasterizerState);
}
private void ClampChildMouseRects(GUIComponent child)
protected override void Update(float deltaTime)
{
base.Update(deltaTime);
ClampChildMouseRects(Content);
}
private static void ClampChildMouseRects(GUIComponent child)
{
child.ClampMouseRectToParent = true;
@@ -142,11 +142,13 @@ namespace Barotrauma
public readonly static GUIColor HealthBarColorHigh = new GUIColor("HealthBarColorHigh");
public readonly static GUIColor HealthBarColorPoisoned = new GUIColor("HealthBarColorPoisoned");
private readonly static Point defaultItemFrameMargin = new Point(50, 56);
public static Point ItemFrameMargin
{
get
{
Point size = new Point(50, 56).Multiply(GUI.SlicedSpriteScale);
Point size = defaultItemFrameMargin.Multiply(GUI.SlicedSpriteScale);
var style = GetComponentStyle("ItemUI");
var sprite = style?.Sprites[GUIComponent.ComponentState.None].First();
@@ -159,6 +161,16 @@ namespace Barotrauma
}
}
public static int ItemFrameTopBarHeight
{
get
{
var style = GetComponentStyle("ItemUI");
var sprite = style?.Sprites[GUIComponent.ComponentState.None].First();
return (int)Math.Min(sprite?.Slices[0].Height ?? 0, defaultItemFrameMargin.Y / 2 * GUI.SlicedSpriteScale);
}
}
public static Point ItemFrameOffset => new Point(0, 3).Multiply(GUI.SlicedSpriteScale);
public static GUIComponentStyle GetComponentStyle(string styleName)
@@ -12,8 +12,6 @@ namespace Barotrauma
public delegate bool OnSelectedHandler(GUITickBox obj);
public OnSelectedHandler OnSelected;
public static int size = 20;
private GUIRadioButtonGroup radioButtonGroup;
public override bool Selected
@@ -21,21 +19,7 @@ namespace Barotrauma
get { return isSelected; }
set
{
if (value == isSelected) { return; }
if (radioButtonGroup != null && radioButtonGroup.SelectedRadioButton == this)
{
isSelected = true;
return;
}
isSelected = value;
State = isSelected ? ComponentState.Selected : ComponentState.None;
if (value && radioButtonGroup != null)
{
radioButtonGroup.SelectRadioButton(this);
}
OnSelected?.Invoke(this);
SetSelected(value, callOnSelected: true);
}
}
@@ -186,6 +170,27 @@ namespace Barotrauma
text.SetTextPos();
ContentWidth = box.Rect.Width + text.Padding.X + text.TextSize.X + text.Padding.Z;
}
public void SetSelected(bool selected, bool callOnSelected = true)
{
if (selected == isSelected) { return; }
if (radioButtonGroup != null && radioButtonGroup.SelectedRadioButton == this)
{
isSelected = true;
return;
}
isSelected = selected;
State = isSelected ? ComponentState.Selected : ComponentState.None;
if (selected && radioButtonGroup != null)
{
radioButtonGroup.SelectRadioButton(this);
}
if (callOnSelected)
{
OnSelected?.Invoke(this);
}
}
protected override void Update(float deltaTime)
{
@@ -160,8 +160,9 @@ namespace Barotrauma
int crewAreaY = ButtonAreaTop.Bottom + Padding;
int crewAreaHeight = ObjectiveAnchor.Top - Padding - crewAreaY;
float crewAreaWidthMultiplier = GUI.IsUltrawide ? GUI.HorizontalAspectRatio : 1.0f;
CrewArea = new Rectangle(Padding, crewAreaY, (int)(Math.Max(400 * GUI.Scale, 220) * crewAreaWidthMultiplier), crewAreaHeight);
CrewArea = new Rectangle(Padding, crewAreaY,
(int)MathHelper.Clamp(400 * GUI.Scale, 220, GameMain.GraphicsHeight * 0.4f),
crewAreaHeight);
InventoryAreaLower = new Rectangle(ChatBoxArea.Right + Padding * 7, inventoryTopY, GameMain.GraphicsWidth - Padding * 9 - ChatBoxArea.Width, GameMain.GraphicsHeight - inventoryTopY);
int healthWindowWidth = (int)(GameMain.GraphicsWidth * 0.5f);
@@ -4,12 +4,13 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma
{
class LoadingScreen
sealed class LoadingScreen
{
private readonly Sprite defaultBackgroundTexture, overlay;
private readonly SpriteSheet decorativeGraph, decorativeMap;
@@ -37,36 +38,16 @@ namespace Barotrauma
}
}
private Queue<PendingSplashScreen> pendingSplashScreens = new Queue<PendingSplashScreen>();
/// <summary>
/// Triplet.first = filepath, Triplet.second = resolution, Triplet.third = audio gain
/// </summary>
public Queue<PendingSplashScreen> PendingSplashScreens
{
get
{
lock (loadMutex)
{
return pendingSplashScreens;
}
}
set
{
lock (loadMutex)
{
pendingSplashScreens = value;
}
}
}
public readonly ConcurrentQueue<PendingSplashScreen> PendingSplashScreens = new ConcurrentQueue<PendingSplashScreen>();
public bool PlayingSplashScreen
{
get
{
lock (loadMutex)
{
return currSplashScreen != null || pendingSplashScreens.Count > 0;
}
return currSplashScreen != null || PendingSplashScreens.Count > 0;
}
}
@@ -76,33 +57,7 @@ namespace Barotrauma
selectedTip = RichString.Rich(tip);
}
private readonly object loadMutex = new object();
private float? loadState;
public float? LoadState
{
get
{
lock (loadMutex)
{
return loadState;
}
}
set
{
lock (loadMutex)
{
loadState = value;
DrawLoadingText = true;
}
}
}
public bool DrawLoadingText
{
get;
set;
}
public float LoadState;
public bool WaitForLanguageSelection
{
@@ -121,7 +76,7 @@ namespace Barotrauma
overlay = new Sprite("Content/UI/MainMenuVignette.png", Vector2.Zero);
noiseSprite = new Sprite("Content/UI/noise.png", Vector2.Zero);
DrawLoadingText = true;
SetSelectedTip(TextManager.Get("LoadingScreenTip"));
}
@@ -170,10 +125,11 @@ namespace Barotrauma
{
DrawLanguageSelectionPrompt(spriteBatch, graphics);
}
else if (DrawLoadingText)
else
{
LocalizedString loadText;
if (LoadState == 100.0f)
var loadState = LoadState; // avoid multiple reads here to prevent jank
if (loadState >= 100.0f)
{
#if DEBUG
if (GameSettings.CurrentConfig.AutomaticQuickStartEnabled || GameSettings.CurrentConfig.AutomaticCampaignLoadEnabled || (GameSettings.CurrentConfig.TestScreenEnabled && GameMain.FirstLoad))
@@ -191,17 +147,17 @@ namespace Barotrauma
else
{
loadText = TextManager.Get("Loading");
if (LoadState != null)
if (loadState >= 0f)
{
loadText += " " + (int)LoadState + " %";
loadText += $" {loadState:N0} %";
}
#if DEBUG
if (GameMain.FirstLoad && GameMain.CancelQuickStart)
{
loadText += " (Quickstart aborted)";
}
#endif
if (GameMain.FirstLoad && GameMain.CancelQuickStart)
{
loadText += " (Quickstart aborted)";
}
#endif
}
if (GUIStyle.LargeFont.HasValue)
@@ -343,11 +299,9 @@ namespace Barotrauma
private void DrawSplashScreen(SpriteBatch spriteBatch, GraphicsDevice graphics)
{
if (currSplashScreen == null && PendingSplashScreens.Count == 0) { return; }
if (currSplashScreen == null)
{
var newSplashScreen = PendingSplashScreens.Dequeue();
if (!PendingSplashScreens.TryDequeue(out var newSplashScreen)) { return; }
string fileName = newSplashScreen.Filename;
try
{
@@ -362,10 +316,10 @@ namespace Barotrauma
PendingSplashScreens.Clear();
currSplashScreen = null;
}
if (currSplashScreen == null) { return; }
}
if (currSplashScreen == null) { return; }
if (currSplashScreen.IsPlaying)
{
graphics.Clear(Color.Black);
@@ -425,7 +379,7 @@ namespace Barotrauma
public IEnumerable<CoroutineStatus> DoLoading(IEnumerable<CoroutineStatus> loader)
{
drawn = false;
LoadState = null;
LoadState = -1f;
SetSelectedTip(TextManager.Get("LoadingScreenTip"));
currentBackgroundTexture = LocationType.Prefabs.Where(p => p.UsePortraitInRandomLoadingScreens).GetRandomUnsynced()?.GetPortrait(Rand.Int(int.MaxValue));
if (GameMain.GameSession?.GameMode?.Missions is { } missions && missions.Any(m => m.Prefab.HasPortraits))
@@ -946,7 +946,7 @@ namespace Barotrauma
}
if (truncated)
{
descriptionBlock.Text += "...";
descriptionBlock.Text += TextManager.Get("ellipsis");
}
GUITextBlock priceBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.25f), bottomTextLayout.RectTransform), TextManager.FormatCurrency(affliction.Price), font: GUIStyle.SubHeadingFont);
@@ -306,6 +306,8 @@ namespace Barotrauma
{
_scaleBasis = value;
RecalculateAbsoluteSize();
RecalculateAnchorPoint();
RecalculatePivotOffset();
}
}
@@ -91,8 +91,8 @@ namespace Barotrauma
var angle = (float)Math.Atan2(point2.Y - point1.Y, point2.X - point1.X);
var scale = new Vector2(length, thickness);
Vector2 middle = new Vector2((point1.X + point2.X) / 2f, (point1.Y + point2.Y) / 2f);
Texture2D tex = GetTexture(spriteBatch);
spriteBatch.Draw(GetTexture(spriteBatch), middle, null, color, angle, new Vector2(tex.Width / 2f, tex.Height / 2f), scale, SpriteEffects.None, 0);
Texture2D tex = GUI.WhiteTexture;
spriteBatch.Draw(tex, middle, null, color, angle, new Vector2(tex.Width / 2f, tex.Height / 2f), scale, SpriteEffects.None, 0);
}
private static void DrawPolygonEdge(SpriteBatch spriteBatch, Vector2 point1, Vector2 point2, Color color, float thickness)
@@ -112,6 +112,18 @@ namespace Barotrauma
DrawLine(spriteBatch, new Vector2(x1, y1), new Vector2(x2, y2), color, thickness);
}
public static void DrawLineWithTexture(this SpriteBatch spriteBatch, Texture2D tex, Vector2 point1, Vector2 point2,
Color color, float thickness = 1f)
{
// calculate the distance between the two vectors
var distance = Vector2.Distance(point1, point2);
// calculate the angle between the two vectors
var angle = (float)Math.Atan2(point2.Y - point1.Y, point2.X - point1.X);
DrawLine(spriteBatch, tex, point1, distance, angle, color, thickness);
}
/// <summary>
/// Draws a line from point1 to point2 with an offset
/// </summary>
@@ -124,18 +136,18 @@ namespace Barotrauma
// calculate the angle between the two vectors
var angle = (float)Math.Atan2(point2.Y - point1.Y, point2.X - point1.X);
DrawLine(spriteBatch, point1, distance, angle, color, thickness);
DrawLine(spriteBatch, GetTexture(spriteBatch), point1, distance, angle, color, thickness);
}
/// <summary>
/// Draws a line from point1 to point2 with an offset
/// </summary>
public static void DrawLine(this SpriteBatch spriteBatch, Vector2 point, float length, float angle, Color color,
public static void DrawLine(this SpriteBatch spriteBatch, Texture2D tex, Vector2 point, float length, float angle, Color color,
float thickness = 1f)
{
var origin = new Vector2(0f, 0.5f);
var scale = new Vector2(length, thickness);
spriteBatch.Draw(GetTexture(spriteBatch), point, null, color, angle, origin, scale, SpriteEffects.None, 0);
var origin = new Vector2(0f, tex.Height / 2f);
var scale = new Vector2(length / tex.Width, thickness / tex.Height);
spriteBatch.Draw(tex, point, null, color, angle, origin, scale, SpriteEffects.None, 0);
}
/// <summary>
@@ -19,7 +19,7 @@ namespace Barotrauma
private static UISprite spectateIcon, disconnectedIcon;
private static Sprite ownerIcon, moderatorIcon;
public enum InfoFrameTab { Crew, Mission, Reputation, Traitor, Submarine, Talents };
public enum InfoFrameTab { Crew, Mission, Reputation, Submarine, Talents };
public static InfoFrameTab SelectedTab { get; private set; }
private GUIFrame infoFrame, contentFrame;
@@ -299,9 +299,15 @@ namespace Barotrauma
var crewButton = createTabButton(InfoFrameTab.Crew, "crew");
if (!(GameMain.GameSession?.GameMode is TestGameMode))
if (GameMain.GameSession?.GameMode is not TestGameMode)
{
createTabButton(InfoFrameTab.Mission, "mission");
var missionBtn = createTabButton(InfoFrameTab.Mission, "mission");
eventLogNotification = GameSession.CreateNotificationIcon(missionBtn);
eventLogNotification.Visible = GameMain.GameSession.EventManager?.EventLog?.UnreadEntries ?? false;
if (eventLogNotification.Visible)
{
eventLogNotification.Pulsate(Vector2.One, Vector2.One * 2, 1.0f);
}
}
if (GameMain.GameSession?.GameMode is CampaignMode campaignMode)
@@ -340,14 +346,6 @@ namespace Barotrauma
text.Text = TextManager.GetWithVariable("bankbalanceformat", "[money]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", balance));
}
}
else
{
bool isTraitor = GameMain.Client?.Character?.IsTraitor ?? false;
if (isTraitor && GameMain.Client.TraitorMission != null)
{
var traitorButton = createTabButton(InfoFrameTab.Traitor, "tabmenu.traitor");
}
}
var submarineButton = createTabButton(InfoFrameTab.Submarine, "submarine");
@@ -361,7 +359,7 @@ namespace Barotrauma
}
};
talentPointNotification = GameSession.CreateTalentIconNotification(talentsButton);
talentPointNotification = GameSession.CreateNotificationIcon(talentsButton);
}
public void SelectInfoFrameTab(InfoFrameTab selectedTab)
@@ -387,12 +385,6 @@ namespace Barotrauma
GameMain.GameSession.RoundSummary.CreateReputationInfoPanel(reputationFrame, campaignMode);
}
break;
case InfoFrameTab.Traitor:
TraitorMissionPrefab traitorMission = GameMain.Client?.TraitorMission;
Character traitor = GameMain.Client?.Character;
if (traitor == null || traitorMission == null) { return; }
CreateTraitorInfo(infoFrameHolder, traitorMission, traitor);
break;
case InfoFrameTab.Submarine:
CreateSubmarineInfo(infoFrameHolder, Submarine.MainSub);
break;
@@ -1539,96 +1531,44 @@ namespace Barotrauma
int locationInfoYOffset = locationInfoContainer.Rect.Height + padding * 2;
GUIListBox missionList = new GUIListBox(new RectTransform(new Point(contentWidth, missionFrameContent.Rect.Height - locationInfoYOffset), missionFrameContent.RectTransform, Anchor.TopCenter) { AbsoluteOffset = new Point(0, locationInfoYOffset) });
missionList.ContentBackground.Color = Color.Transparent;
missionList.Spacing = GUI.IntScale(15);
if (GameMain.GameSession?.Missions != null)
{
int spacing = GUI.IntScale(5);
int iconSize = (int)(GUIStyle.LargeFont.MeasureChar('T').Y + GUIStyle.Font.MeasureChar('T').Y * 4 + spacing * 4);
foreach (Mission mission in GameMain.GameSession.Missions)
{
if (!mission.Prefab.ShowInMenus) { continue; }
GUIFrame missionDescriptionHolder = new GUIFrame(new RectTransform(Vector2.One, missionList.Content.RectTransform), style: null);
GUILayoutGroup missionTextGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.744f, 0f), missionDescriptionHolder.RectTransform, Anchor.CenterLeft) { AbsoluteOffset = new Point(iconSize + spacing, 0) }, false, childAnchor: Anchor.TopLeft)
var textContent = new List<LocalizedString>()
{
AbsoluteSpacing = spacing
mission.GetMissionRewardText(Submarine.MainSub),
mission.GetReputationRewardText(),
mission.Description
};
LocalizedString descriptionText = mission.Description;
foreach (LocalizedString missionMessage in mission.ShownMessages)
textContent.AddRange(mission.ShownMessages);
RoundSummary.CreateMissionEntry(
missionList.Content,
mission.Name,
textContent,
mission.Difficulty ?? 0,
mission.Prefab.Icon, mission.Prefab.IconColor,
out GUIImage missionIcon);
if (missionIcon != null)
{
descriptionText += "\n\n" + missionMessage;
}
RichString rewardText = mission.GetMissionRewardText(Submarine.MainSub);
RichString reputationText = mission.GetReputationRewardText();
UpdateMissionStateIcon();
mission.OnMissionStateChanged += (mission) => UpdateMissionStateIcon();
Func<string, string> wrapMissionText(GUIFont font)
{
return (str) => ToolBox.WrapText(str, missionTextGroup.Rect.Width, font.Value);
}
RichString missionNameString = RichString.Rich(mission.Name, wrapMissionText(GUIStyle.LargeFont));
RichString missionRewardString = RichString.Rich(rewardText, wrapMissionText(GUIStyle.Font));
RichString missionReputationString = RichString.Rich(reputationText, wrapMissionText(GUIStyle.Font));
RichString missionDescriptionString = RichString.Rich(descriptionText, wrapMissionText(GUIStyle.Font));
Vector2 missionNameSize = GUIStyle.LargeFont.MeasureString(missionNameString.SanitizedValue);
Vector2 missionDescriptionSize = GUIStyle.Font.MeasureString(missionDescriptionString.SanitizedValue);
Vector2 missionRewardSize = GUIStyle.Font.MeasureString(missionRewardString.SanitizedValue);
Vector2 missionReputationSize = GUIStyle.Font.MeasureString(missionReputationString.SanitizedValue);
float ySize = missionNameSize.Y + missionDescriptionSize.Y + missionRewardSize.Y + missionReputationSize.Y + missionTextGroup.AbsoluteSpacing * 4;
bool displayDifficulty = mission.Difficulty.HasValue;
if (displayDifficulty) { ySize += missionRewardSize.Y; }
missionDescriptionHolder.RectTransform.NonScaledSize = new Point(missionDescriptionHolder.RectTransform.NonScaledSize.X, (int)ySize);
missionTextGroup.RectTransform.NonScaledSize = new Point(missionTextGroup.RectTransform.NonScaledSize.X, missionDescriptionHolder.RectTransform.NonScaledSize.Y);
if (mission.Prefab.Icon != null)
{
/*float iconAspectRatio = mission.Prefab.Icon.SourceRect.Width / mission.Prefab.Icon.SourceRect.Height;
int iconWidth = (int)(0.225f * missionDescriptionHolder.RectTransform.NonScaledSize.X);
int iconHeight = Math.Max(missionTextGroup.RectTransform.NonScaledSize.Y, (int)(iconWidth * iconAspectRatio));
Point iconSize = new Point(iconWidth, iconHeight);*/
var icon = new GUIImage(new RectTransform(new Point(iconSize), missionDescriptionHolder.RectTransform), mission.Prefab.Icon, null, true)
void UpdateMissionStateIcon()
{
Color = mission.Prefab.IconColor,
HoverColor = mission.Prefab.IconColor,
SelectedColor = mission.Prefab.IconColor,
CanBeFocused = false
};
UpdateMissionStateIcon(mission, icon);
mission.OnMissionStateChanged += (mission) => UpdateMissionStateIcon(mission, icon);
}
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionNameString, font: GUIStyle.LargeFont);
GUILayoutGroup difficultyIndicatorGroup = null;
if (displayDifficulty)
{
difficultyIndicatorGroup = new GUILayoutGroup(new RectTransform(new Point(missionTextGroup.Rect.Width, (int)missionRewardSize.Y), parent: missionTextGroup.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft)
{
AbsoluteSpacing = 1
};
var difficultyColor = mission.GetDifficultyColor();
for (int i = 0; i < mission.Difficulty.Value; i++)
{
new GUIImage(new RectTransform(Vector2.One, difficultyIndicatorGroup.RectTransform, scaleBasis: ScaleBasis.Smallest), "DifficultyIndicator", scaleToFit: true)
if (mission.DisplayAsCompleted || mission.DisplayAsFailed)
{
CanBeFocused = false,
Color = difficultyColor
};
RoundSummary.UpdateMissionStateIcon(mission.DisplayAsCompleted, missionIcon);
}
}
}
var rewardTextBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionRewardString);
if (difficultyIndicatorGroup != null)
{
difficultyIndicatorGroup.RectTransform.Resize(new Point((int)(difficultyIndicatorGroup.Rect.Width - rewardTextBlock.Padding.X - rewardTextBlock.Padding.Z), difficultyIndicatorGroup.Rect.Height));
difficultyIndicatorGroup.RectTransform.AbsoluteOffset = new Point((int)rewardTextBlock.Padding.X, 0);
}
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionReputationString);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionDescriptionString);
}
}
else
@@ -1636,66 +1576,14 @@ namespace Barotrauma
GUILayoutGroup missionTextGroup = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0f), missionList.RectTransform, Anchor.CenterLeft), false, childAnchor: Anchor.TopLeft);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), TextManager.Get("NoMission"), font: GUIStyle.LargeFont);
}
GameMain.GameSession?.EventManager?.EventLog?.CreateEventLogUI(missionList.Content);
GameMain.GameSession.EnableEventLogNotificationIcon(enabled: false);
RoundSummary.AddSeparators(missionList.Content);
}
private void UpdateMissionStateIcon(Mission mission, GUIImage missionIcon)
{
if (mission == null || missionIcon == null) { return; }
string style = string.Empty;
if (mission.DisplayAsFailed)
{
style = "MissionFailedIcon";
}
else if (mission.DisplayAsCompleted)
{
style = "MissionCompletedIcon";
}
GUIImage stateIcon = missionIcon.GetChild<GUIImage>();
if (string.IsNullOrEmpty(style))
{
if (stateIcon != null)
{
stateIcon.Visible = false;
}
}
else
{
stateIcon ??= new GUIImage(new RectTransform(Vector2.One, missionIcon.RectTransform), style, scaleToFit: true);
stateIcon.Visible = true;
}
}
private void CreateTraitorInfo(GUIFrame infoFrame, TraitorMissionPrefab traitorMission, Character traitor)
{
GUIFrame missionFrame = new GUIFrame(new RectTransform(Vector2.One, infoFrame.RectTransform, Anchor.TopCenter), style: "GUIFrameListBox");
int padding = (int)(0.0245f * missionFrame.Rect.Height);
GUIFrame missionDescriptionHolder = new GUIFrame(new RectTransform(new Point(missionFrame.Rect.Width - padding * 2, 0), missionFrame.RectTransform, Anchor.TopCenter) { AbsoluteOffset = new Point(0, padding) }, style: null);
GUILayoutGroup missionTextGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.65f, 0f), missionDescriptionHolder.RectTransform, Anchor.CenterLeft) { RelativeOffset = new Vector2(0.319f, 0f) }, false, childAnchor: Anchor.TopLeft);
LocalizedString missionNameString = ToolBox.WrapText(TextManager.Get("tabmenu.traitor"), missionTextGroup.Rect.Width, GUIStyle.LargeFont);
LocalizedString missionDescriptionString = ToolBox.WrapText(traitor.TraitorCurrentObjective, missionTextGroup.Rect.Width, GUIStyle.Font);
Vector2 missionNameSize = GUIStyle.LargeFont.MeasureString(missionNameString);
Vector2 missionDescriptionSize = GUIStyle.Font.MeasureString(missionDescriptionString);
missionDescriptionHolder.RectTransform.NonScaledSize = new Point(missionDescriptionHolder.RectTransform.NonScaledSize.X, (int)(missionNameSize.Y + missionDescriptionSize.Y));
missionTextGroup.RectTransform.NonScaledSize = new Point(missionTextGroup.RectTransform.NonScaledSize.X, missionDescriptionHolder.RectTransform.NonScaledSize.Y);
float aspectRatio = traitorMission.Icon.SourceRect.Width / traitorMission.Icon.SourceRect.Height;
int iconWidth = (int)(0.319f * missionDescriptionHolder.RectTransform.NonScaledSize.X);
int iconHeight = Math.Max(missionTextGroup.RectTransform.NonScaledSize.Y, (int)(iconWidth * aspectRatio));
Point iconSize = new Point(iconWidth, iconHeight);
new GUIImage(new RectTransform(iconSize, missionDescriptionHolder.RectTransform), traitorMission.Icon, null, true) { Color = traitorMission.IconColor };
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionNameString, font: GUIStyle.LargeFont);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionDescriptionString);
}
private void CreateSubmarineInfo(GUIFrame infoFrame, Submarine sub)
private static void CreateSubmarineInfo(GUIFrame infoFrame, Submarine sub)
{
GUIFrame subInfoFrame = new GUIFrame(new RectTransform(Vector2.One, infoFrame.RectTransform, Anchor.TopCenter), style: "GUIFrameListBox");
GUIFrame paddedFrame = new GUIFrame(new RectTransform(Vector2.One * 0.97f, subInfoFrame.RectTransform, Anchor.Center), style: null);
@@ -1793,7 +1681,7 @@ namespace Barotrauma
}
}
private GUIImage talentPointNotification;
private GUIImage talentPointNotification, eventLogNotification;
public static void CreateSkillList(Character character, CharacterInfo info, GUIListBox parent)
{
@@ -117,6 +117,9 @@ namespace Barotrauma
return MathHelper.Clamp(Math.Min(Math.Min(scale.X, scale.Y), GUI.SlicedSpriteScale), minBorderScale, maxBorderScale);
}
public void Draw(SpriteBatch spriteBatch, RectangleF rect, Color color, SpriteEffects spriteEffects = SpriteEffects.None, Vector2? uvOffset = null)
=> Draw(spriteBatch, new Rectangle(rect.Location.ToPoint(), rect.Size.ToPoint()), color, spriteEffects, uvOffset);
public void Draw(SpriteBatch spriteBatch, Rectangle rect, Color color, SpriteEffects spriteEffects = SpriteEffects.None, Vector2? uvOffset = null)
{
uvOffset ??= Vector2.Zero;