Unstable 0.17.0.0

This commit is contained in:
Markus Isberg
2022-02-26 02:43:01 +09:00
parent a83f375681
commit 3974067915
913 changed files with 32472 additions and 32364 deletions
@@ -25,7 +25,7 @@ namespace Barotrauma
get { return _toggleOpen; }
set
{
_toggleOpen = GameMain.Config.ChatOpen = value;
_toggleOpen = value;
if (value) hideableElements.Visible = true;
}
}
@@ -121,7 +121,7 @@ namespace Barotrauma
};
arrowIcon.HoverColor = arrowIcon.PressedColor = arrowIcon.PressedColor = arrowIcon.Color;
channelText = new GUITextBox(new RectTransform(new Vector2(0.25f, 0.8f), channelSettingsContent.RectTransform), style: "DigitalFrameLight", textAlignment: Alignment.Center, font: GUI.DigitalFont)
channelText = new GUITextBox(new RectTransform(new Vector2(0.25f, 0.8f), channelSettingsContent.RectTransform), style: "DigitalFrameLight", textAlignment: Alignment.Center, font: GUIStyle.DigitalFont)
{
textFilterFunction = text =>
{
@@ -173,7 +173,7 @@ namespace Barotrauma
new GUIButton(new RectTransform(new Vector2(0.1f, 1.0f), channelPickerContent.RectTransform), i.ToString(), style: "GUITextBlock")
{
TextColor = new Color(51, 59, 46),
SelectedTextColor = GUI.Style.Green,
SelectedTextColor = GUIStyle.Green,
UserData = i,
OnClicked = (btn, userdata) =>
{
@@ -185,13 +185,13 @@ namespace Barotrauma
int.TryParse(channelText.Text, out int newChannel);
radio.SetChannelMemory(index, newChannel);
btn.ToolTip = TextManager.GetWithVariables("radiochannelpreset",
new string[] { "[index]", "[channel]" },
new string[] { index.ToString(), radio.GetChannelMemory(index).ToString() });
("[index]", index.ToString()),
("[channel]", radio.GetChannelMemory(index).ToString()));
channelMemPending = false;
channelPickerContent.Children.First().CanBeFocused = true;
memButton.Enabled = true;
channelPickerContent.Flash(GUI.Style.Green);
channelText.Flash(GUI.Style.Green);
channelPickerContent.Flash(GUIStyle.Green);
channelText.Flash(GUIStyle.Green);
}
SetChannel(radio.GetChannelMemory(index), setText: true);
SoundPlayer.PlayUISound(GUISoundType.PopupMenu);
@@ -224,7 +224,7 @@ namespace Barotrauma
style: "ChatTextBox")
{
OverflowClip = true,
Font = GUI.SmallFont,
Font = GUIStyle.SmallFont,
MaxTextLength = ChatMessage.MaxLength
};
@@ -265,7 +265,7 @@ namespace Barotrauma
};
showNewMessagesButton.Visible = false;
ToggleOpen = GameMain.Config.ChatOpen;
ToggleOpen = GameSettings.CurrentConfig.ChatOpen;
}
public bool TypingChatMessage(GUITextBox textBox, string text)
@@ -337,7 +337,7 @@ namespace Barotrauma
color: ((chatBox.Content.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f);
GUITextBlock senderNameTimestamp = new GUITextBlock(new RectTransform(new Vector2(0.98f, 0.0f), msgHolder.RectTransform) { AbsoluteOffset = new Point((int)(5 * GUI.Scale), 0) },
ChatMessage.GetTimeStamp(), textColor: Color.LightGray, font: GUI.SmallFont, textAlignment: Alignment.TopLeft, style: null)
ChatMessage.GetTimeStamp(), textColor: Color.LightGray, font: GUIStyle.SmallFont, textAlignment: Alignment.TopLeft, style: null)
{
CanBeFocused = true
};
@@ -350,9 +350,9 @@ namespace Barotrauma
{
Padding = Vector4.Zero
},
Font = GUI.SmallFont,
Font = GUIStyle.SmallFont,
CanBeFocused = true,
ForceUpperCase = false,
ForceUpperCase = ForceUpperCase.No,
UserData = message.SenderClient,
OnClicked = (_, o) =>
{
@@ -379,8 +379,8 @@ namespace Barotrauma
var msgText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), msgHolder.RectTransform)
{ AbsoluteOffset = new Point((int)(10 * GUI.Scale), senderNameTimestamp == null ? 0 : senderNameTimestamp.Rect.Height) },
displayedText, textColor: message.Color, font: GUI.SmallFont, textAlignment: Alignment.TopLeft, style: null, wrap: true,
color: ((chatBox.Content.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f, parseRichText: true)
RichString.Rich(displayedText), textColor: message.Color, font: GUIStyle.SmallFont, textAlignment: Alignment.TopLeft, style: null, wrap: true,
color: ((chatBox.Content.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f)
{
UserData = message.SenderName,
CanBeFocused = false
@@ -454,7 +454,7 @@ namespace Barotrauma
if (!string.IsNullOrEmpty(senderName))
{
var senderText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform),
senderName, textColor: senderColor, style: null, font: GUI.SmallFont)
senderName, textColor: senderColor, style: null, font: GUIStyle.SmallFont)
{
CanBeFocused = false
};
@@ -462,7 +462,7 @@ namespace Barotrauma
senderText.RectTransform.MinSize = new Point(0, senderText.Rect.Height);
}
var msgPopupText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform),
displayedText, textColor: message.Color, font: GUI.SmallFont, textAlignment: Alignment.BottomLeft, style: null, wrap: true, parseRichText: true)
RichString.Rich(displayedText), textColor: message.Color, font: GUIStyle.SmallFont, textAlignment: Alignment.BottomLeft, style: null, wrap: true)
{
CanBeFocused = false
};
@@ -553,8 +553,8 @@ namespace Barotrauma
{
int index = (int)presetButton.UserData;
presetButton.ToolTip = TextManager.GetWithVariables("radiochannelpreset",
new string[] { "[index]", "[channel]" },
new string[] { index.ToString(), radio.GetChannelMemory(index).ToString() });
("[index]", index.ToString()),
("[channel]", radio.GetChannelMemory(index).ToString()));
}
SetChannel(radio.Channel, setText: true);
prevRadio = radio;
@@ -563,7 +563,7 @@ namespace Barotrauma
{
if (channelPickerContent.FlashTimer <= 0)
{
channelPickerContent.Flash(GUI.Style.Green, flashRectInflate: new Vector2(GUI.Scale * 5.0f));
channelPickerContent.Flash(GUIStyle.Green, flashRectInflate: new Vector2(GUI.Scale * 5.0f));
}
if (PlayerInput.PrimaryMouseButtonClicked() && !GUI.IsMouseOn(channelPickerContent))
{
@@ -671,7 +671,7 @@ namespace Barotrauma
if (Character.Controlled != null && ChatMessage.CanUseRadio(Character.Controlled, out WifiComponent radio))
{
radio.Channel = channel;
GameMain.Client?.CreateEntityEvent(radio.Item, new object[] { NetEntityEvent.Type.ChangeProperty, radio.SerializableProperties["channel"] });
GameMain.Client?.CreateEntityEvent(radio.Item, new object[] { NetEntityEvent.Type.ChangeProperty, radio.SerializableProperties["channel".ToIdentifier()] });
if (setText)
{
@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Barotrauma.Extensions;
namespace Barotrauma
{
@@ -16,7 +17,7 @@ namespace Barotrauma
Toggle
}
public class GUIComponentStyle
public class GUIComponentStyle : GUIPrefab
{
public readonly Vector4 Padding;
@@ -35,31 +36,53 @@ namespace Barotrauma
public readonly float ColorCrossFadeTime;
public readonly TransitionMode TransitionMode;
public readonly string Font;
public readonly Identifier Font;
public readonly bool ForceUpperCase;
public readonly Color OutlineColor;
public readonly XElement Element;
public readonly ContentXElement Element;
public readonly Dictionary<GUIComponent.ComponentState, List<UISprite>> Sprites;
public SpriteFallBackState FallBackState;
public Dictionary<string, GUIComponentStyle> ChildStyles;
public readonly GUIStyle Style;
public readonly GUIComponentStyle ParentStyle;
public readonly Dictionary<Identifier, GUIComponentStyle> ChildStyles;
public static GUIComponentStyle FromHierarchy(IReadOnlyList<Identifier> hierarchy)
{
if (hierarchy is null || hierarchy.None()) { return null; }
GUIStyle.ComponentStyles.TryGet(hierarchy[0], out GUIComponentStyle style);
for (int i = 1; i < hierarchy.Count; i++)
{
if (style is null) { return null; }
style.ChildStyles.TryGetValue(hierarchy[i], out style);
}
return style;
}
public static Identifier[] ToHierarchy(GUIComponentStyle style)
{
List<Identifier> ids = new List<Identifier>();
while (style != null)
{
ids.Insert(0, style.Identifier);
style = style.ParentStyle;
}
return ids.ToArray();
}
public readonly string Name;
public int? Width { get; private set; }
public int? Height { get; private set; }
public GUIComponentStyle(XElement element, GUIStyle style)
public GUIComponentStyle(ContentXElement element, UIStyleFile file, GUIComponentStyle parent = null) : base(element, file)
{
Name = element.Name.LocalName;
Style = style;
Element = element;
Sprites = new Dictionary<GUIComponent.ComponentState, List<UISprite>>();
@@ -68,7 +91,8 @@ namespace Barotrauma
Sprites[state] = new List<UISprite>();
}
ChildStyles = new Dictionary<string, GUIComponentStyle>();
ParentStyle = parent;
ChildStyles = new Dictionary<Identifier, GUIComponentStyle>();
Padding = element.GetAttributeVector4("padding", Vector4.Zero);
@@ -95,10 +119,10 @@ namespace Barotrauma
FallBackState = s;
}
Font = element.GetAttributeString("font", "");
Font = element.GetAttributeIdentifier("font", "");
ForceUpperCase = element.GetAttributeBool("forceuppercase", false);
foreach (XElement subElement in element.Elements())
foreach (var subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
@@ -128,15 +152,15 @@ namespace Barotrauma
case "size":
break;
default:
string styleName = subElement.Name.ToString().ToLowerInvariant();
Identifier styleName = subElement.NameAsIdentifier();
if (ChildStyles.ContainsKey(styleName))
{
DebugConsole.ThrowError("UI style \"" + element.Name.ToString() + "\" contains multiple child styles with the same name (\"" + styleName + "\")!");
ChildStyles[styleName] = new GUIComponentStyle(subElement, style);
ChildStyles[styleName] = new GUIComponentStyle(subElement, file, this);
}
else
{
ChildStyles.Add(styleName, new GUIComponentStyle(subElement, style));
ChildStyles.Add(styleName, new GUIComponentStyle(subElement, file, this));
}
break;
}
@@ -157,7 +181,7 @@ namespace Barotrauma
public void GetSize(XElement element)
{
Point size = new Point(0, 0);
foreach (XElement subElement in element.Elements())
foreach (var subElement in element.Elements())
{
if (!subElement.Name.ToString().Equals("size", StringComparison.OrdinalIgnoreCase)) { continue; }
Point maxResolution = subElement.GetAttributePoint("maxresolution", new Point(int.MaxValue, int.MaxValue));
@@ -172,5 +196,7 @@ namespace Barotrauma
if (size.X > 0) { Width = size.X; }
if (size.Y > 0) { Height = size.Y; }
}
public override void Dispose() { }
}
}
@@ -108,10 +108,10 @@ namespace Barotrauma
};
var imageWidth = (float)headerGroup.Rect.Height / headerGroup.Rect.Width;
new GUIImage(new RectTransform(new Vector2(imageWidth, 1.0f), headerGroup.RectTransform), "CrewManagementHeaderIcon");
new GUITextBlock(new RectTransform(new Vector2(1.0f - imageWidth, 1.0f), headerGroup.RectTransform), TextManager.Get("campaigncrew.header"), font: GUI.LargeFont)
new GUITextBlock(new RectTransform(new Vector2(1.0f - imageWidth, 1.0f), headerGroup.RectTransform), TextManager.Get("campaigncrew.header"), font: GUIStyle.LargeFont)
{
CanBeFocused = false,
ForceUpperCase = true
ForceUpperCase = ForceUpperCase.Yes
};
var hireablesGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.95f), anchor: Anchor.Center,
@@ -162,13 +162,13 @@ namespace Barotrauma
RelativeSpacing = 0.005f
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), playerBalanceContainer.RectTransform),
TextManager.Get("campaignstore.balance"), font: GUI.Font, textAlignment: Alignment.BottomRight)
TextManager.Get("campaignstore.balance"), font: GUIStyle.Font, textAlignment: Alignment.BottomRight)
{
AutoScaleVertical = true,
ForceUpperCase = true
ForceUpperCase = ForceUpperCase.Yes
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), playerBalanceContainer.RectTransform),
"", font: GUI.SubHeadingFont, textAlignment: Alignment.TopRight)
"", font: GUIStyle.SubHeadingFont, textAlignment: Alignment.TopRight)
{
AutoScaleVertical = true,
TextScale = 1.1f,
@@ -182,13 +182,13 @@ namespace Barotrauma
}).RectTransform));
float height = 0.05f;
new GUITextBlock(new RectTransform(new Vector2(1.0f, height), pendingAndCrewGroup.RectTransform), TextManager.Get("campaigncrew.pending"), font: GUI.SubHeadingFont);
new GUITextBlock(new RectTransform(new Vector2(1.0f, height), pendingAndCrewGroup.RectTransform), TextManager.Get("campaigncrew.pending"), font: GUIStyle.SubHeadingFont);
pendingList = new GUIListBox(new RectTransform(new Vector2(1.0f, 8 * height), pendingAndCrewGroup.RectTransform))
{
Spacing = 1
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, height), pendingAndCrewGroup.RectTransform), TextManager.Get("campaignmenucrew"), font: GUI.SubHeadingFont);
new GUITextBlock(new RectTransform(new Vector2(1.0f, height), pendingAndCrewGroup.RectTransform), TextManager.Get("campaignmenucrew"), font: GUIStyle.SubHeadingFont);
crewList = new GUIListBox(new RectTransform(new Vector2(1.0f, 8 * height), pendingAndCrewGroup.RectTransform))
{
Spacing = 1
@@ -196,7 +196,7 @@ namespace Barotrauma
var group = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, height), pendingAndCrewGroup.RectTransform), isHorizontal: true);
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), group.RectTransform), TextManager.Get("campaignstore.total"));
totalBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), group.RectTransform), "", font: GUI.SubHeadingFont, textAlignment: Alignment.Right)
totalBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), group.RectTransform), "", font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right)
{
TextScale = 1.1f
};
@@ -207,12 +207,12 @@ namespace Barotrauma
validateHiresButton = new GUIButton(new RectTransform(new Vector2(1.0f / 3.0f, 1.0f), group.RectTransform), text: TextManager.Get("campaigncrew.validate"))
{
ClickSound = GUISoundType.HireRepairClick,
ForceUpperCase = true,
ForceUpperCase = ForceUpperCase.Yes,
OnClicked = (b, o) => ValidateHires(PendingHires, true)
};
clearAllButton = new GUIButton(new RectTransform(new Vector2(1.0f / 3.0f, 1.0f), group.RectTransform), text: TextManager.Get("campaignstore.clearall"))
{
ForceUpperCase = true,
ForceUpperCase = ForceUpperCase.Yes,
Enabled = HasPermission,
OnClicked = (b, o) => RemoveAllPendingHires()
};
@@ -302,30 +302,42 @@ namespace Barotrauma
if (sortingMethod == SortingMethod.AlphabeticalAsc)
{
list.Content.RectTransform.SortChildren((x, y) =>
(x.GUIComponent.UserData as Tuple<CharacterInfo, float>).Item1.Name.CompareTo((y.GUIComponent.UserData as Tuple<CharacterInfo, float>).Item1.Name));
((InfoSkill)x.GUIComponent.UserData).CharacterInfo.Name.CompareTo(((InfoSkill)y.GUIComponent.UserData).CharacterInfo.Name));
}
else if (sortingMethod == SortingMethod.JobAsc)
{
SortCharacters(list, SortingMethod.AlphabeticalAsc);
list.Content.RectTransform.SortChildren((x, y) =>
String.Compare((x.GUIComponent.UserData as Tuple<CharacterInfo, float>)?.Item1.Job.Name, (y.GUIComponent.UserData as Tuple<CharacterInfo, float>).Item1.Job.Name, StringComparison.Ordinal));
String.Compare(((InfoSkill)x.GUIComponent.UserData).CharacterInfo.Job.Name.Value, ((InfoSkill)y.GUIComponent.UserData).CharacterInfo.Job.Name.Value, StringComparison.Ordinal));
}
else if (sortingMethod == SortingMethod.PriceAsc || sortingMethod == SortingMethod.PriceDesc)
{
SortCharacters(list, SortingMethod.AlphabeticalAsc);
list.Content.RectTransform.SortChildren((x, y) =>
(x.GUIComponent.UserData as Tuple<CharacterInfo, float>).Item1.Salary.CompareTo((y.GUIComponent.UserData as Tuple<CharacterInfo, float>).Item1.Salary));
((InfoSkill)x.GUIComponent.UserData).CharacterInfo.Salary.CompareTo(((InfoSkill)y.GUIComponent.UserData).CharacterInfo.Salary));
if (sortingMethod == SortingMethod.PriceDesc) { list.Content.RectTransform.ReverseChildren(); }
}
else if (sortingMethod == SortingMethod.SkillAsc || sortingMethod == SortingMethod.SkillDesc)
{
SortCharacters(list, SortingMethod.AlphabeticalAsc);
list.Content.RectTransform.SortChildren((x, y) =>
(x.GUIComponent.UserData as Tuple<CharacterInfo, float>).Item2.CompareTo((y.GUIComponent.UserData as Tuple<CharacterInfo, float>).Item2));
((InfoSkill)x.GUIComponent.UserData).SkillLevel.CompareTo(((InfoSkill)y.GUIComponent.UserData).SkillLevel));
if (sortingMethod == SortingMethod.SkillDesc) { list.Content.RectTransform.ReverseChildren(); }
}
}
private readonly struct InfoSkill
{
public readonly CharacterInfo CharacterInfo;
public readonly float SkillLevel;
public InfoSkill(CharacterInfo characterInfo, float skillLevel)
{
CharacterInfo = characterInfo;
SkillLevel = skillLevel;
}
}
private void CreateCharacterFrame(CharacterInfo characterInfo, GUIListBox listBox)
{
Skill skill = null;
@@ -338,7 +350,7 @@ namespace Barotrauma
GUIFrame frame = new GUIFrame(new RectTransform(new Point(listBox.Content.Rect.Width, (int)(GUI.yScale * 55)), parent: listBox.Content.RectTransform), "ListBoxElement")
{
UserData = new Tuple<CharacterInfo, float>(characterInfo, skill?.Level ?? 0.0f)
UserData = new InfoSkill(characterInfo, skill?.Level ?? 0.0f)
};
GUILayoutGroup mainGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), frame.RectTransform, anchor: Anchor.Center), isHorizontal: true, childAnchor: Anchor.CenterLeft)
{
@@ -363,7 +375,7 @@ namespace Barotrauma
nameBlock.Text = ToolBox.LimitString(nameBlock.Text, nameBlock.Font, nameBlock.Rect.Width);
GUITextBlock jobBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), nameAndJobGroup.RectTransform),
characterInfo.Job.Name, textColor: Color.White, font: GUI.SmallFont, textAlignment: Alignment.TopLeft)
characterInfo.Job.Name, textColor: Color.White, font: GUIStyle.SmallFont, textAlignment: Alignment.TopLeft)
{
CanBeFocused = false
};
@@ -374,7 +386,7 @@ namespace Barotrauma
{
GUILayoutGroup skillGroup = new GUILayoutGroup(new RectTransform(new Vector2(width, 0.6f), mainGroup.RectTransform), isHorizontal: true);
float iconWidth = (float)skillGroup.Rect.Height / skillGroup.Rect.Width;
GUIImage skillIcon = new GUIImage(new RectTransform(new Vector2(iconWidth, 1.0f), skillGroup.RectTransform), skill.Icon)
GUIImage skillIcon = new GUIImage(new RectTransform(Vector2.One, skillGroup.RectTransform, scaleBasis: ScaleBasis.Smallest), skill.Icon, scaleToFit: true)
{
CanBeFocused = false
};
@@ -448,7 +460,7 @@ namespace Barotrauma
var confirmDialog = new GUIMessageBox(
TextManager.Get("FireWarningHeader"),
TextManager.GetWithVariable("FireWarningText", "[charactername]", ((CharacterInfo)obj).Name),
new string[] { TextManager.Get("Yes"), TextManager.Get("No") });
new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") });
confirmDialog.Buttons[0].UserData = (CharacterInfo)obj;
confirmDialog.Buttons[0].OnClicked = FireCharacter;
confirmDialog.Buttons[0].OnClicked += confirmDialog.Close;
@@ -510,10 +522,11 @@ namespace Barotrauma
string name = listBox == hireableList ? characterInfo.OriginalName : characterInfo.Name;
nameBlock.Text = ToolBox.LimitString(name, nameBlock.Font, nameBlock.Rect.Width);
if (characterInfo.HasGenders)
if (characterInfo.HasSpecifierTags)
{
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()));
var menuCategoryVar = characterInfo.Prefab.MenuCategoryVar;
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoLabelGroup.RectTransform), TextManager.Get(menuCategoryVar));
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoValueGroup.RectTransform), TextManager.Get(characterInfo.ReplaceVars($"[{menuCategoryVar}]")));
}
if (characterInfo.Job is Job job)
{
@@ -523,7 +536,7 @@ namespace Barotrauma
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(" ", "")));
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoValueGroup.RectTransform), TextManager.Get("personalitytrait." + trait.Name.Replace(" ".ToIdentifier(), Identifier.Empty)));
}
infoLabelGroup.Recalculate();
infoValueGroup.Recalculate();
@@ -568,7 +581,7 @@ namespace Barotrauma
return false;
}
hireableList.Content.RemoveChild(hireableList.Content.FindChild(c => (c.UserData as Tuple<CharacterInfo, float>).Item1 == characterInfo));
hireableList.Content.RemoveChild(hireableList.Content.FindChild(c => ((InfoSkill)c.UserData).CharacterInfo == characterInfo));
hireableList.UpdateScrollBarSize();
if (!PendingHires.Contains(characterInfo)) { PendingHires.Add(characterInfo); }
CreateCharacterFrame(characterInfo, pendingList);
@@ -582,14 +595,14 @@ namespace Barotrauma
private bool RemovePendingHire(CharacterInfo characterInfo, bool setTotalHireCost = true, bool createNetworkMessage = true)
{
if (PendingHires.Contains(characterInfo)) { PendingHires.Remove(characterInfo); }
pendingList.Content.RemoveChild(pendingList.Content.FindChild(c => (c.UserData as Tuple<CharacterInfo, float>).Item1 == characterInfo));
pendingList.Content.RemoveChild(pendingList.Content.FindChild(c => ((InfoSkill)c.UserData).CharacterInfo == characterInfo));
pendingList.UpdateScrollBarSize();
// Server will reset the names to originals in multiplayer
if (!GameMain.IsMultiplayer) { characterInfo?.ResetName(); }
if (campaign.Map.CurrentLocation.HireManager.AvailableCharacters.Any(info => info.GetIdentifierUsingOriginalName() == characterInfo.GetIdentifierUsingOriginalName()) &&
hireableList.Content.Children.None(c => c.UserData is Tuple<CharacterInfo, float> userData && userData.Item1.GetIdentifierUsingOriginalName() == characterInfo.GetIdentifierUsingOriginalName()))
hireableList.Content.Children.None(c => c.UserData is InfoSkill userData && userData.CharacterInfo.GetIdentifierUsingOriginalName() == characterInfo.GetIdentifierUsingOriginalName()))
{
CreateCharacterFrame(characterInfo, hireableList);
SortCharacters(hireableList, (SortingMethod)sortingDropDown.SelectedItemData);
@@ -603,7 +616,7 @@ namespace Barotrauma
private bool RemoveAllPendingHires(bool createNetworkMessage = true)
{
pendingList.Content.Children.ToList().ForEach(c => RemovePendingHire((c.UserData as Tuple<CharacterInfo, float>).Item1, setTotalHireCost: false, createNetworkMessage));
pendingList.Content.Children.ToList().ForEach(c => RemovePendingHire(((InfoSkill)c.UserData).CharacterInfo, setTotalHireCost: false, createNetworkMessage));
SetTotalHireCost();
return true;
}
@@ -614,7 +627,7 @@ namespace Barotrauma
int total = 0;
pendingList.Content.Children.ForEach(c =>
{
total += (c.UserData as Tuple<CharacterInfo, float>).Item1.Salary;
total += ((InfoSkill)c.UserData).CharacterInfo.Salary;
});
totalBlock.Text = FormatCurrency(total);
bool enoughMoney = campaign != null ? total <= campaign.Money : true;
@@ -661,7 +674,7 @@ namespace Barotrauma
var dialog = new GUIMessageBox(
TextManager.Get("newcrewmembers"),
TextManager.GetWithVariable("crewhiredmessage", "[location]", campaignUI?.Campaign?.Map?.CurrentLocation?.Name),
new string[] { TextManager.Get("Ok") });
new LocalizedString[] { TextManager.Get("Ok") });
dialog.Buttons[0].OnClicked += dialog.Close;
}
@@ -687,7 +700,7 @@ namespace Barotrauma
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);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), layoutGroup.RectTransform), TextManager.Get("campaigncrew.givenickname"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Center, wrap: true);
var groupElementSize = new Vector2(1.0f, 0.25f);
var nameBox = new GUITextBox(new RectTransform(groupElementSize, layoutGroup.RectTransform))
{
@@ -732,7 +745,7 @@ namespace Barotrauma
}
else
{
var crewComponent = crewList.Content.FindChild(c => (c.UserData as Tuple<CharacterInfo, float>).Item1 == characterInfo);
var crewComponent = crewList.Content.FindChild(c => ((InfoSkill)c.UserData).CharacterInfo == characterInfo);
if (crewComponent != null)
{
crewList.Content.RemoveChild(crewComponent);
@@ -742,7 +755,7 @@ namespace Barotrauma
}
else
{
var pendingComponent = pendingList.Content.FindChild(c => (c.UserData as Tuple<CharacterInfo, float>).Item1 == characterInfo);
var pendingComponent = pendingList.Content.FindChild(c => ((InfoSkill)c.UserData).CharacterInfo == characterInfo);
if (pendingComponent != null)
{
pendingList.Content.RemoveChild(pendingComponent);
@@ -821,15 +834,15 @@ namespace Barotrauma
characterPreviewFrame = null;
}
static (GUIComponent, CharacterInfo) FindHighlightedCharacter(GUIComponent c)
static (GUIComponent GuiComponent, CharacterInfo CharacterInfo) FindHighlightedCharacter(GUIComponent c)
{
if (c == null)
{
return default;
}
if (c.UserData is Tuple<CharacterInfo, float> highlightedData)
if (c.UserData is InfoSkill highlightedData)
{
return (c, highlightedData.Item1);
return (c, highlightedData.CharacterInfo);
}
if (c.Parent != null)
{
@@ -913,6 +926,6 @@ namespace Barotrauma
}
}
private string FormatCurrency(int currency) => TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", currency));
private LocalizedString FormatCurrency(int currency) => TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", currency));
}
}
@@ -1,9 +1,11 @@
using Microsoft.Xna.Framework;
#nullable enable
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using Barotrauma.IO;
using System.Linq;
using System.Text;
using Barotrauma.Extensions;
namespace Barotrauma
{
@@ -18,7 +20,7 @@ namespace Barotrauma
}
set
{
if (value && backgroundFrame == null) { Init(); }
if (value) { InitIfNecessary(); }
if (!value)
{
fileSystemWatcher?.Dispose();
@@ -28,26 +30,31 @@ namespace Barotrauma
}
}
private static GUIFrame backgroundFrame;
private static GUIFrame window;
private static GUIListBox sidebar;
private static GUIListBox fileList;
private static GUITextBox directoryBox;
private static GUITextBox filterBox;
private static GUITextBox fileBox;
private static GUIDropDown fileTypeDropdown;
private static GUIButton openButton;
private static GUIFrame? backgroundFrame;
private static GUIFrame? window;
private static GUIListBox? sidebar;
private static GUIListBox? fileList;
private static GUITextBox? directoryBox;
private static GUITextBox? filterBox;
private static GUITextBox? fileBox;
private static GUIDropDown? fileTypeDropdown;
private static GUIButton? openButton;
private static System.IO.FileSystemWatcher fileSystemWatcher;
private static System.IO.FileSystemWatcher? fileSystemWatcher;
private static string currentFileTypePattern;
private enum ItemIsDirectory
{
Yes, No
}
private static readonly string[] ignoredDrivePrefixes = new string[]
private static string? currentFileTypePattern;
private static readonly string[] ignoredDrivePrefixes =
{
"/sys/", "/snap/"
};
private static string currentDirectory;
private static string currentDirectory = "";
public static string CurrentDirectory
{
get
@@ -91,7 +98,7 @@ namespace Barotrauma
}
}
public static Action<string> OnFileSelected
public static Action<string>? OnFileSelected
{
get;
set;
@@ -99,15 +106,16 @@ namespace Barotrauma
private static void OnFileSystemChanges(object sender, System.IO.FileSystemEventArgs e)
{
if (fileList is null) { return; }
switch (e.ChangeType)
{
case System.IO.WatcherChangeTypes.Created:
{
var itemFrame = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), fileList.Content.RectTransform), e.Name)
var itemFrame = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), fileList.Content.RectTransform), e.Name ?? string.Empty)
{
UserData = (bool?)Directory.Exists(e.FullPath)
UserData = Directory.Exists(e.FullPath) ? ItemIsDirectory.Yes : ItemIsDirectory.No
};
if ((itemFrame.UserData as bool?) ?? false)
if (itemFrame.UserData is ItemIsDirectory.Yes)
{
itemFrame.Text += "/";
}
@@ -122,11 +130,13 @@ namespace Barotrauma
break;
case System.IO.WatcherChangeTypes.Renamed:
{
System.IO.RenamedEventArgs renameArgs = e as System.IO.RenamedEventArgs;
var itemFrame = fileList.Content.FindChild(c => (c is GUITextBlock tb) && (tb.Text == renameArgs.OldName || tb.Text == renameArgs.OldName + "/")) as GUITextBlock;
itemFrame.UserData = (bool?)Directory.Exists(e.FullPath);
itemFrame.Text = renameArgs.Name;
if ((itemFrame.UserData as bool?) ?? false)
System.IO.RenamedEventArgs renameArgs = e as System.IO.RenamedEventArgs ?? throw new InvalidCastException($"Unable to cast {nameof(System.IO.FileSystemEventArgs)} to {nameof(System.IO.RenamedEventArgs)}.");
var itemFrame =
fileList.Content.FindChild(c => (c is GUITextBlock tb) && (tb.Text == renameArgs.OldName || tb.Text == renameArgs.OldName + "/")) as GUITextBlock
?? throw new Exception($"Could not find file list item with name \"{renameArgs.OldName}\"");
itemFrame.UserData = Directory.Exists(e.FullPath) ? ItemIsDirectory.Yes : ItemIsDirectory.No;
itemFrame.Text = renameArgs.Name ?? string.Empty;
if (itemFrame.UserData is ItemIsDirectory.Yes)
{
itemFrame.Text += "/";
}
@@ -138,10 +148,10 @@ namespace Barotrauma
private static int SortFiles(RectTransform r1, RectTransform r2)
{
string file1 = (r1.GUIComponent as GUITextBlock)?.Text ?? "";
string file2 = (r2.GUIComponent as GUITextBlock)?.Text ?? "";
bool dir1 = (r1.GUIComponent.UserData as bool?) ?? false;
bool dir2 = (r2.GUIComponent.UserData as bool?) ?? false;
string file1 = (r1.GUIComponent as GUITextBlock)?.Text?.SanitizedValue ?? "";
string file2 = (r2.GUIComponent as GUITextBlock)?.Text?.SanitizedValue ?? "";
bool dir1 = r1.GUIComponent.UserData is ItemIsDirectory.Yes;
bool dir2 = r2.GUIComponent.UserData is ItemIsDirectory.Yes;
if (dir1 && !dir2)
{
return -1;
@@ -154,6 +164,11 @@ namespace Barotrauma
return string.Compare(file1, file2);
}
private static void InitIfNecessary()
{
if (backgroundFrame == null) { Init(); }
}
public static void Init()
{
backgroundFrame = new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas), style: null)
@@ -179,7 +194,7 @@ namespace Barotrauma
sidebar.OnSelected = (child, userdata) =>
{
CurrentDirectory = (child as GUITextBlock).Text;
CurrentDirectory = (child as GUITextBlock)?.Text.SanitizedValue ?? throw new Exception("Sidebar selection is invalid");
return false;
};
@@ -228,13 +243,14 @@ namespace Barotrauma
{
OnSelected = (child, userdata) =>
{
if (userdata == null) { return false; }
if (userdata is null) { return false; }
if (fileBox is null) { return false; }
var fileName = (child as GUITextBlock).Text;
var fileName = (child as GUITextBlock)!.Text.SanitizedValue;
fileBox.Text = fileName;
if (PlayerInput.DoubleClicked())
{
bool isDir = (userdata as bool?).Value;
bool isDir = userdata is ItemIsDirectory.Yes;
if (isDir)
{
CurrentDirectory += fileName;
@@ -263,7 +279,7 @@ namespace Barotrauma
{
OnSelected = (child, userdata) =>
{
currentFileTypePattern = (child as GUITextBlock).UserData as string;
currentFileTypePattern = (child as GUITextBlock)!.UserData as string;
RefreshFileList();
return true;
@@ -307,30 +323,31 @@ namespace Barotrauma
public static void ClearFileTypeFilters()
{
if (backgroundFrame == null) { Init(); }
fileTypeDropdown.ClearChildren();
InitIfNecessary();
fileTypeDropdown!.ClearChildren();
}
public static void AddFileTypeFilter(string name, string pattern)
{
if (backgroundFrame == null) { Init(); }
fileTypeDropdown.AddItem(name + " (" + pattern + ")", pattern);
InitIfNecessary();
fileTypeDropdown!.AddItem(name + " (" + pattern + ")", pattern);
}
public static void SelectFileTypeFilter(string pattern)
{
if (backgroundFrame == null) { Init(); }
fileTypeDropdown.SelectItem(pattern);
InitIfNecessary();
fileTypeDropdown!.SelectItem(pattern);
}
public static void RefreshFileList()
{
fileList.Content.ClearChildren();
InitIfNecessary();
fileList!.Content.ClearChildren();
fileList.BarScroll = 0.0f;
try
{
var directories = Directory.EnumerateDirectories(currentDirectory, "*" + filterBox.Text + "*");
var directories = Directory.EnumerateDirectories(currentDirectory, "*" + filterBox!.Text + "*");
foreach (var directory in directories)
{
string txt = directory;
@@ -338,7 +355,7 @@ namespace Barotrauma
if (!txt.EndsWith("/")) { txt += "/"; }
var itemFrame = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), fileList.Content.RectTransform), txt)
{
UserData = (bool?)true
UserData = ItemIsDirectory.Yes
};
var folderIcon = new GUIImage(new RectTransform(new Point((int)(itemFrame.Rect.Height * 0.8f)), itemFrame.RectTransform, Anchor.CenterLeft)
{
@@ -347,18 +364,18 @@ namespace Barotrauma
itemFrame.Padding = new Vector4(folderIcon.Rect.Width * 1.5f, itemFrame.Padding.Y, itemFrame.Padding.Z, itemFrame.Padding.W);
}
IEnumerable<string> files = null;
if (currentFileTypePattern == null)
IEnumerable<string> files = Enumerable.Empty<string>();
if (currentFileTypePattern.IsNullOrEmpty())
{
files = Directory.GetFiles(currentDirectory);
}
else
{
foreach (string pattern in currentFileTypePattern.Split(','))
foreach (string pattern in currentFileTypePattern!.Split(','))
{
string patternTrimmed = pattern.Trim();
patternTrimmed = "*" + filterBox.Text + "*" + patternTrimmed;
if (files == null)
if (files.None())
{
files = Directory.EnumerateFiles(currentDirectory, patternTrimmed);
}
@@ -375,7 +392,7 @@ namespace Barotrauma
if (txt.StartsWith(currentDirectory)) { txt = txt.Substring(currentDirectory.Length); }
var itemFrame = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), fileList.Content.RectTransform), txt)
{
UserData = (bool?)false
UserData = ItemIsDirectory.No
};
}
}
@@ -387,8 +404,8 @@ namespace Barotrauma
};
}
directoryBox.Text = currentDirectory;
fileBox.Text = "";
directoryBox!.Text = currentDirectory;
fileBox!.Text = "";
fileList.Deselect();
}
@@ -14,6 +14,7 @@ using FarseerPhysics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.Collections.Immutable;
namespace Barotrauma
{
@@ -36,13 +37,13 @@ namespace Barotrauma
public enum CursorState
{
Default, // Cursor
Hand, // Hand with a finger
Move, // arrows pointing to all directions
IBeam, // Text
Dragging,// Closed hand
Waiting, // Hourglass
WaitingBackground // Cursor + Hourglass
Default = 0, // Cursor
Hand = 1, // Hand with a finger
Move = 2, // arrows pointing to all directions
IBeam = 3, // Text
Dragging = 4,// Closed hand
Waiting = 5, // Hourglass
WaitingBackground = 6, // Cursor + Hourglass
}
public static class GUI
@@ -78,20 +79,19 @@ namespace Barotrauma
FilterMode = TextureFilterMode.Default,
};
public static readonly string[] vectorComponentLabels = { "X", "Y", "Z", "W" };
public static readonly string[] rectComponentLabels = { "X", "Y", "W", "H" };
public static readonly string[] colorComponentLabels = { "R", "G", "B", "A" };
public static readonly string[] VectorComponentLabels = { "X", "Y", "Z", "W" };
public static readonly string[] RectComponentLabels = { "X", "Y", "W", "H" };
public static readonly string[] ColorComponentLabels = { "R", "G", "B", "A" };
private static readonly object mutex = new object();
public static Vector2 ReferenceResolution => new Vector2(1920f, 1080f);
public static float Scale => (UIWidth / ReferenceResolution.X + GameMain.GraphicsHeight / ReferenceResolution.Y) / 2.0f * GameSettings.HUDScale;
public static float xScale => UIWidth / ReferenceResolution.X * GameSettings.HUDScale;
public static float yScale => GameMain.GraphicsHeight / ReferenceResolution.Y * GameSettings.HUDScale;
public static readonly Vector2 ReferenceResolution = new Vector2(1920f, 1080f);
public static float Scale => (UIWidth / ReferenceResolution.X + GameMain.GraphicsHeight / ReferenceResolution.Y) / 2.0f * GameSettings.CurrentConfig.Graphics.HUDScale;
public static float xScale => UIWidth / ReferenceResolution.X * GameSettings.CurrentConfig.Graphics.HUDScale;
public static float yScale => GameMain.GraphicsHeight / ReferenceResolution.Y * GameSettings.CurrentConfig.Graphics.HUDScale;
public static int IntScale(float f) => (int)(f * Scale);
public static int IntScaleFloor(float f) => (int)Math.Floor(f * Scale);
public static int IntScaleCeiling(float f) => (int) Math.Ceiling(f * Scale);
public static int IntScaleCeiling(float f) => (int)Math.Ceiling(f * Scale);
public static float HorizontalAspectRatio => GameMain.GraphicsWidth / (float)GameMain.GraphicsHeight;
public static float VerticalAspectRatio => GameMain.GraphicsHeight / (float)GameMain.GraphicsWidth;
public static float RelativeHorizontalAspectRatio => HorizontalAspectRatio / (ReferenceResolution.X / ReferenceResolution.Y);
@@ -102,7 +102,6 @@ namespace Barotrauma
{
get
{
// Ultrawide
if (IsUltrawide)
{
return (int)(GameMain.GraphicsHeight * ReferenceResolution.X / ReferenceResolution.Y);
@@ -127,23 +126,21 @@ namespace Barotrauma
}
}
public static GUIStyle Style;
private static Texture2D t;
public static Texture2D WhiteTexture => t;
private static Sprite[] MouseCursorSprites => Style.CursorSprite;
private static Texture2D solidWhiteTexture;
public static Texture2D WhiteTexture => solidWhiteTexture;
private static GUICursor MouseCursorSprites => GUIStyle.CursorSprite;
private static bool debugDrawSounds, debugDrawEvents, debugDrawMetadata;
private static int debugDrawMetadataOffset;
private static readonly string[] ignoredMetadataInfo = { string.Empty, string.Empty, string.Empty, string.Empty };
public static GraphicsDevice GraphicsDevice { get; private set; }
public static GraphicsDevice GraphicsDevice => GameMain.Instance.GraphicsDevice;
private static List<GUIMessage> messages = new List<GUIMessage>();
private static readonly Dictionary<GUISoundType, string> soundIdentifiers = new Dictionary<GUISoundType, string>();
private static bool pauseMenuOpen, settingsMenuOpen;
public static GUIFrame PauseMenu { get; private set; }
private static Sprite arrow;
public static GUIFrame SettingsMenuContainer { get; private set; }
public static Sprite Arrow => GUIStyle.Arrow.Value.Sprite;
public static bool HideCursor;
@@ -154,61 +151,31 @@ namespace Barotrauma
/// </summary>
public static bool ScreenChanged;
public static ScalableFont Font => Style?.Font;
// Usable in CJK as a regular font
public static ScalableFont GlobalFont => Style?.GlobalFont;
public static ScalableFont UnscaledSmallFont => Style?.UnscaledSmallFont;
public static ScalableFont SmallFont => Style?.SmallFont;
public static ScalableFont LargeFont => Style?.LargeFont;
public static ScalableFont SubHeadingFont => Style?.SubHeadingFont;
public static ScalableFont DigitalFont => Style?.DigitalFont;
public static ScalableFont HotkeyFont => Style?.HotkeyFont;
public static ScalableFont MonospacedFont => Style?.MonospacedFont;
public static ScalableFont CJKFont { get; private set; }
public static UISprite UIGlow => Style.UIGlow;
public static UISprite UIGlowCircular => Style.UIGlowCircular;
public static Sprite SubmarineIcon
{
get;
private set;
}
public static Sprite BrokenIcon
{
get;
private set;
}
public static Sprite SpeechBubbleIcon
{
get;
private set;
}
public static Sprite Arrow
{
get { return arrow; }
}
private static bool settingsMenuOpen;
public static bool SettingsMenuOpen
{
get { return settingsMenuOpen; }
set
{
if (value == settingsMenuOpen) { return; }
GameMain.Config.ResetSettingsFrame();
if (value == SettingsMenuOpen) { return; }
if (value)
{
SettingsMenuContainer = new GUIFrame(new RectTransform(Vector2.One, Canvas, Anchor.Center), style: null);
new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, SettingsMenuContainer.RectTransform, Anchor.Center), style: "GUIBackgroundBlocker");
var settingsMenuInner = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.8f), SettingsMenuContainer.RectTransform, Anchor.Center, scaleBasis: ScaleBasis.Smallest) { MinSize = new Point(640, 480) });
SettingsMenu.Create(settingsMenuInner.RectTransform);
}
else
{
SettingsMenu.Instance?.Close();
}
settingsMenuOpen = value;
}
}
public static bool PauseMenuOpen
{
get { return pauseMenuOpen; }
}
public static bool PauseMenuOpen { get; private set; }
public static bool InputBlockingMenuOpen
{
@@ -251,66 +218,14 @@ namespace Barotrauma
FadingOut
}
public static void Init(GameWindow window, IEnumerable<ContentPackage> selectedContentPackages, GraphicsDevice graphicsDevice)
public static void Init()
{
GraphicsDevice = graphicsDevice;
var files = ContentPackage.GetFilesOfType(selectedContentPackages, ContentType.UIStyle);
XElement selectedStyle = null;
foreach (var file in files)
{
XDocument doc = XMLExtensions.TryLoadXml(file.Path);
if (doc == null) { continue; }
var mainElement = doc.Root;
if (doc.Root.IsOverride())
{
mainElement = doc.Root.FirstElement();
if (selectedStyle != null)
{
DebugConsole.NewMessage($"Overriding the ui styles with '{file.Path}'", Color.Yellow);
}
}
else if (selectedStyle != null)
{
DebugConsole.ThrowError("Another ui style already loaded! Use <override></override> tags to override it.");
break;
}
selectedStyle = mainElement;
}
if (selectedStyle == null)
{
DebugConsole.ThrowError("No UI styles defined in the selected content package!");
}
else
{
Style = new GUIStyle(selectedStyle, graphicsDevice);
}
if (CJKFont == null)
{
CJKFont = new ScalableFont("Content/Fonts/NotoSans/NotoSansCJKsc-Bold.otf",
Font.Size, graphicsDevice, dynamicLoading: true, isCJK: true);
}
}
public static void LoadContent()
{
foreach (GUISoundType soundType in Enum.GetValues(typeof(GUISoundType)))
{
soundIdentifiers.Add(soundType, soundType.ToString().ToLowerInvariant());
}
// create 1x1 texture for line drawing
CrossThread.RequestExecutionOnMainThread(() =>
{
t = new Texture2D(GraphicsDevice, 1, 1);
t.SetData(new Color[] { Color.White });// fill the texture with white
solidWhiteTexture = new Texture2D(GraphicsDevice, 1, 1);
solidWhiteTexture.SetData(new Color[] { Color.White });// fill the texture with white
});
SubmarineIcon = new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(452, 385, 182, 81), new Vector2(0.5f, 0.5f));
arrow = new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(393, 393, 49, 45), new Vector2(0.5f, 0.5f));
SpeechBubbleIcon = new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(385, 449, 66, 60), new Vector2(0.5f, 0.5f));
BrokenIcon = new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(898, 386, 123, 123), new Vector2(0.5f, 0.5f));
}
/// <summary>
@@ -341,41 +256,41 @@ namespace Barotrauma
}
#if UNSTABLE
string line1 = "Barotrauma Unstable v" + GameMain.Version;
string line2 = "(" + AssemblyInfo.BuildString + ", branch " + AssemblyInfo.GitBranch + ", revision " + AssemblyInfo.GitRevision + ")";
string line1 = "Barotrauma Unstable v" + GameMain.Version;
string line2 = "(" + AssemblyInfo.BuildString + ", branch " + AssemblyInfo.GitBranch + ", revision " + AssemblyInfo.GitRevision + ")";
Rectangle watermarkRect = new Rectangle(-50, GameMain.GraphicsHeight - 80, 50 + (int)(Math.Max(LargeFont.MeasureString(line1).X, Font.MeasureString(line2).X) * 1.2f), 100);
float alpha = 1.0f;
Rectangle watermarkRect = new Rectangle(-50, GameMain.GraphicsHeight - 80, 50 + (int)(Math.Max(GUIStyle.LargeFont.MeasureString(line1).X, GUIStyle.Font.MeasureString(line2).X) * 1.2f), 100);
float alpha = 1.0f;
int yOffset = 0;
int yOffset = 0;
if (Screen.Selected == GameMain.GameScreen)
{
yOffset = (int)(-HUDLayoutSettings.ChatBoxArea.Height * 1.2f);
watermarkRect.Y += yOffset;
}
if (Screen.Selected == GameMain.GameScreen)
{
yOffset = (int)(-HUDLayoutSettings.ChatBoxArea.Height * 1.2f);
watermarkRect.Y += yOffset;
}
if (Screen.Selected == GameMain.GameScreen || Screen.Selected == GameMain.SubEditorScreen)
{
alpha = 0.2f;
}
if (Screen.Selected == GameMain.GameScreen || Screen.Selected == GameMain.SubEditorScreen)
{
alpha = 0.2f;
}
Style.GetComponentStyle("OuterGlow").Sprites[GUIComponent.ComponentState.None][0].Draw(
spriteBatch, watermarkRect, Color.Black * 0.8f * alpha);
LargeFont.DrawString(spriteBatch, line1,
new Vector2(10, GameMain.GraphicsHeight - 30 - LargeFont.MeasureString(line1).Y + yOffset), Color.White * 0.6f * alpha);
Font.DrawString(spriteBatch, line2,
GUIStyle.GetComponentStyle("OuterGlow").Sprites[GUIComponent.ComponentState.None][0].Draw(
spriteBatch, watermarkRect, Color.Black * 0.8f * alpha);
GUIStyle.LargeFont.DrawString(spriteBatch, line1,
new Vector2(10, GameMain.GraphicsHeight - 30 - GUIStyle.LargeFont.MeasureString(line1).Y + yOffset), Color.White * 0.6f * alpha);
GUIStyle.Font.DrawString(spriteBatch, line2,
new Vector2(10, GameMain.GraphicsHeight - 30 + yOffset), Color.White * 0.6f * alpha);
if (Screen.Selected != GameMain.GameScreen)
{
var buttonRect =
new Rectangle(20 + (int)Math.Max(LargeFont.MeasureString(line1).X, Font.MeasureString(line2).X), GameMain.GraphicsHeight - (int)(45 * Scale) + yOffset, (int)(150 * Scale), (int)(40 * Scale));
if (DrawButton(spriteBatch, buttonRect, "Report Bug", Style.GetComponentStyle("GUIBugButton").Color * 0.8f))
if (Screen.Selected != GameMain.GameScreen)
{
GameMain.Instance.ShowBugReporter();
var buttonRect =
new Rectangle(20 + (int)Math.Max(GUIStyle.LargeFont.MeasureString(line1).X, GUIStyle.Font.MeasureString(line2).X), GameMain.GraphicsHeight - (int)(45 * Scale) + yOffset, (int)(150 * Scale), (int)(40 * Scale));
if (DrawButton(spriteBatch, buttonRect, "Report Bug", GUIStyle.GetComponentStyle("GUIBugButton").Color * 0.8f))
{
GameMain.Instance.ShowBugReporter();
}
}
}
#endif
if (DisableHUD)
@@ -388,12 +303,12 @@ namespace Barotrauma
{
DrawString(spriteBatch, new Vector2(10, 10),
"FPS: " + Math.Round(GameMain.PerformanceCounter.AverageFramesPerSecond),
Color.White, Color.Black * 0.5f, 0, SmallFont);
Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
if (GameMain.GameSession != null && Timing.TotalTime > GameMain.GameSession.RoundStartTime + 1.0)
{
DrawString(spriteBatch, new Vector2(10, 25),
$"Physics: {GameMain.CurrentUpdateRate}",
(GameMain.CurrentUpdateRate < Timing.FixedUpdateRate) ? Color.Red : Color.White, Color.Black * 0.5f, 0, SmallFont);
(GameMain.CurrentUpdateRate < Timing.FixedUpdateRate) ? Color.Red : Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
}
}
@@ -403,15 +318,15 @@ namespace Barotrauma
DrawString(spriteBatch, new Vector2(300, y),
"Draw - Avg: " + GameMain.PerformanceCounter.DrawTimeGraph.Average().ToString("0.00") + " ms" +
" Max: " + GameMain.PerformanceCounter.DrawTimeGraph.LargestValue().ToString("0.00") + " ms",
Style.Green, Color.Black * 0.8f, font: SmallFont);
y += 15;
GameMain.PerformanceCounter.DrawTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), color: Style.Green);
GUIStyle.Green, Color.Black * 0.8f, font: GUIStyle.SmallFont);
y += 15;
GameMain.PerformanceCounter.DrawTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), color: GUIStyle.Green);
y += 50;
DrawString(spriteBatch, new Vector2(300, y),
"Update - Avg: " + GameMain.PerformanceCounter.UpdateTimeGraph.Average().ToString("0.00") + " ms" +
" Max: " + GameMain.PerformanceCounter.UpdateTimeGraph.LargestValue().ToString("0.00") + " ms",
Color.LightBlue, Color.Black * 0.8f, font: SmallFont);
Color.LightBlue, Color.Black * 0.8f, font: GUIStyle.SmallFont);
y += 15;
GameMain.PerformanceCounter.UpdateTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), color: Color.LightBlue);
y += 50;
@@ -420,19 +335,25 @@ namespace Barotrauma
float elapsedMillisecs = GameMain.PerformanceCounter.GetAverageElapsedMillisecs(key);
DrawString(spriteBatch, new Vector2(300, y),
key + ": " + elapsedMillisecs.ToString("0.00"),
Color.Lerp(Color.LightGreen, GUI.Style.Red, elapsedMillisecs / 10.0f), Color.Black * 0.5f, 0, SmallFont);
Color.Lerp(Color.LightGreen, GUIStyle.Red, elapsedMillisecs / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
y += 15;
}
if (Powered.Grids != null)
{
DrawString(spriteBatch, new Vector2(300, y), "Grids: " + Powered.Grids.Count, Color.LightGreen, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
y += 15;
}
if (Settings.EnableDiagnostics)
{
DrawString(spriteBatch, new Vector2(320, y), "ContinuousPhysicsTime: " + GameMain.World.ContinuousPhysicsTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUI.Style.Red, (float)GameMain.World.ContinuousPhysicsTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, SmallFont);
DrawString(spriteBatch, new Vector2(320, y + 15), "ControllersUpdateTime: " + GameMain.World.ControllersUpdateTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUI.Style.Red, (float)GameMain.World.ControllersUpdateTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, SmallFont);
DrawString(spriteBatch, new Vector2(320, y + 30), "AddRemoveTime: " + GameMain.World.AddRemoveTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUI.Style.Red, (float)GameMain.World.AddRemoveTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, SmallFont);
DrawString(spriteBatch, new Vector2(320, y + 45), "NewContactsTime: " + GameMain.World.NewContactsTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUI.Style.Red, (float)GameMain.World.NewContactsTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, SmallFont);
DrawString(spriteBatch, new Vector2(320, y + 60), "ContactsUpdateTime: " + GameMain.World.ContactsUpdateTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUI.Style.Red, (float)GameMain.World.ContactsUpdateTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, SmallFont);
DrawString(spriteBatch, new Vector2(320, y + 75), "SolveUpdateTime: " + GameMain.World.SolveUpdateTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUI.Style.Red, (float)GameMain.World.SolveUpdateTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, SmallFont);
DrawString(spriteBatch, new Vector2(320, y), "ContinuousPhysicsTime: " + GameMain.World.ContinuousPhysicsTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.ContinuousPhysicsTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
DrawString(spriteBatch, new Vector2(320, y + 15), "ControllersUpdateTime: " + GameMain.World.ControllersUpdateTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.ControllersUpdateTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
DrawString(spriteBatch, new Vector2(320, y + 30), "AddRemoveTime: " + GameMain.World.AddRemoveTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.AddRemoveTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
DrawString(spriteBatch, new Vector2(320, y + 45), "NewContactsTime: " + GameMain.World.NewContactsTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.NewContactsTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
DrawString(spriteBatch, new Vector2(320, y + 60), "ContactsUpdateTime: " + GameMain.World.ContactsUpdateTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.ContactsUpdateTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
DrawString(spriteBatch, new Vector2(320, y + 75), "SolveUpdateTime: " + GameMain.World.SolveUpdateTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, GUIStyle.Red, (float)GameMain.World.SolveUpdateTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
}
}
@@ -440,56 +361,56 @@ namespace Barotrauma
{
DrawString(spriteBatch, new Vector2(10, 25),
"Physics: " + GameMain.World.UpdateTime,
Color.White, Color.Black * 0.5f, 0, SmallFont);
Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
DrawString(spriteBatch, new Vector2(10, 40),
$"Bodies: {GameMain.World.BodyList.Count} ({GameMain.World.BodyList.Count(b => b != null && b.Awake && b.Enabled)} awake, {GameMain.World.BodyList.Count(b => b != null && b.Awake && b.BodyType == BodyType.Dynamic && b.Enabled)} dynamic)",
Color.White, Color.Black * 0.5f, 0, SmallFont);
Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
if (Screen.Selected.Cam != null)
{
DrawString(spriteBatch, new Vector2(10, 55),
"Camera pos: " + Screen.Selected.Cam.Position.ToPoint() + ", zoom: " + Screen.Selected.Cam.Zoom,
Color.White, Color.Black * 0.5f, 0, SmallFont);
Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
}
if (Submarine.MainSub != null)
{
DrawString(spriteBatch, new Vector2(10, 70),
"Sub pos: " + Submarine.MainSub.Position.ToPoint(),
Color.White, Color.Black * 0.5f, 0, SmallFont);
Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
}
DrawString(spriteBatch, new Vector2(10, 90),
"Particle count: " + GameMain.ParticleManager.ParticleCount + "/" + GameMain.ParticleManager.MaxParticles,
Color.Lerp(GUI.Style.Green, GUI.Style.Red, (GameMain.ParticleManager.ParticleCount / (float)GameMain.ParticleManager.MaxParticles)), Color.Black * 0.5f, 0, SmallFont);
Color.Lerp(GUIStyle.Green, GUIStyle.Red, (GameMain.ParticleManager.ParticleCount / (float)GameMain.ParticleManager.MaxParticles)), Color.Black * 0.5f, 0, GUIStyle.SmallFont);
if (loadedSpritesText == null || DateTime.Now > loadedSpritesUpdateTime)
{
loadedSpritesText = "Loaded sprites: " + Sprite.LoadedSprites.Count() + "\n(" + Sprite.LoadedSprites.Select(s => s.FilePath).Distinct().Count() + " unique textures)";
loadedSpritesUpdateTime = DateTime.Now + new TimeSpan(0, 0, seconds: 5);
}
DrawString(spriteBatch, new Vector2(10, 115), loadedSpritesText, Color.White, Color.Black * 0.5f, 0, SmallFont);
DrawString(spriteBatch, new Vector2(10, 115), loadedSpritesText, Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
if (debugDrawSounds)
{
int y = 0;
DrawString(spriteBatch, new Vector2(500, y),
"Sounds (Ctrl+S to hide): ", Color.White, Color.Black * 0.5f, 0, SmallFont);
"Sounds (Ctrl+S to hide): ", Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
y += 15;
DrawString(spriteBatch, new Vector2(500, y),
"Current playback amplitude: " + GameMain.SoundManager.PlaybackAmplitude.ToString(), Color.White, Color.Black * 0.5f, 0, SmallFont);
"Current playback amplitude: " + GameMain.SoundManager.PlaybackAmplitude.ToString(), Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
y += 15;
DrawString(spriteBatch, new Vector2(500, y),
"Compressed dynamic range gain: " + GameMain.SoundManager.CompressionDynamicRangeGain.ToString(), Color.White, Color.Black * 0.5f, 0, SmallFont);
"Compressed dynamic range gain: " + GameMain.SoundManager.CompressionDynamicRangeGain.ToString(), Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
y += 15;
DrawString(spriteBatch, new Vector2(500, y),
"Loaded sounds: " + GameMain.SoundManager.LoadedSoundCount + " (" + GameMain.SoundManager.UniqueLoadedSoundCount + " unique)", Color.White, Color.Black * 0.5f, 0, SmallFont);
"Loaded sounds: " + GameMain.SoundManager.LoadedSoundCount + " (" + GameMain.SoundManager.UniqueLoadedSoundCount + " unique)", Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
y += 15;
for (int i = 0; i < SoundManager.SOURCE_COUNT; i++)
@@ -538,27 +459,27 @@ namespace Barotrauma
}
}
DrawString(spriteBatch, new Vector2(500, y), soundStr, clr, Color.Black * 0.5f, 0, SmallFont);
DrawString(spriteBatch, new Vector2(500, y), soundStr, clr, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
y += 15;
}
}
else
{
DrawString(spriteBatch, new Vector2(500, 0),
"Ctrl+S to show sound debug info", Color.White, Color.Black * 0.5f, 0, SmallFont);
"Ctrl+S to show sound debug info", Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
}
if (debugDrawEvents)
{
DrawString(spriteBatch, new Vector2(10, 300),
"Ctrl+E to hide EventManager debug info", Color.White, Color.Black * 0.5f, 0, SmallFont);
"Ctrl+E to hide EventManager debug info", Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
GameMain.GameSession?.EventManager?.DebugDrawHUD(spriteBatch, 315);
}
else
{
DrawString(spriteBatch, new Vector2(10, 300),
"Ctrl+E to show EventManager debug info", Color.White, Color.Black * 0.5f, 0, SmallFont);
"Ctrl+E to show EventManager debug info", Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
}
if (GameMain.GameSession?.GameMode is CampaignMode campaignMode)
@@ -570,17 +491,17 @@ namespace Barotrauma
$"Ctrl+2 to {(string.IsNullOrWhiteSpace(ignoredMetadataInfo[1]) ? "hide" : "show")} faction reputations, \n" +
$"Ctrl+3 to {(string.IsNullOrWhiteSpace(ignoredMetadataInfo[2]) ? "hide" : "show")} upgrade levels, \n" +
$"Ctrl+4 to {(string.IsNullOrWhiteSpace(ignoredMetadataInfo[3]) ? "hide" : "show")} upgrade prices";
var (x, y) = SmallFont.MeasureString(text);
var (x, y) = GUIStyle.SmallFont.MeasureString(text);
Vector2 pos = new Vector2(GameMain.GraphicsWidth - (x + 10), 300);
DrawString(spriteBatch, pos, text, Color.White, Color.Black * 0.5f, 0, SmallFont);
DrawString(spriteBatch, pos, text, Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
pos.Y += y + 8;
campaignMode.CampaignMetadata?.DebugDraw(spriteBatch, pos, debugDrawMetadataOffset, ignoredMetadataInfo);
}
else
{
const string text = "Ctrl+M to show campaign metadata debug info";
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (SmallFont.MeasureString(text).X + 10), 300),
text, Color.White, Color.Black * 0.5f, 0, SmallFont);
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (GUIStyle.SmallFont.MeasureString(text).X + 10), 300),
text, Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
}
}
@@ -616,9 +537,9 @@ namespace Barotrauma
foreach (string str in strings)
{
Vector2 stringSize = SmallFont.MeasureString(str);
Vector2 stringSize = GUIStyle.SmallFont.MeasureString(str);
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)stringSize.X - padding, yPos), str, Color.LightGreen, Color.Black, 0, SmallFont);
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)stringSize.X - padding, yPos), str, Color.LightGreen, Color.Black, 0, GUIStyle.SmallFont);
yPos += (int)stringSize.Y + padding / 2;
}
}
@@ -639,7 +560,7 @@ namespace Barotrauma
DrawMessages(spriteBatch, cam);
if (MouseOn != null && !string.IsNullOrWhiteSpace(MouseOn.ToolTip))
if (MouseOn != null && !MouseOn.ToolTip.IsNullOrWhiteSpace())
{
MouseOn.DrawToolTip(spriteBatch);
}
@@ -651,7 +572,7 @@ namespace Barotrauma
{
case ItemPrefab itemPrefab:
{
var sprite = itemPrefab.InventoryIcon ?? itemPrefab.sprite;
var sprite = itemPrefab.InventoryIcon ?? itemPrefab.Sprite;
sprite?.Draw(spriteBatch, PlayerInput.MousePosition, scale: Math.Min(64 / sprite.size.X, 64 / sprite.size.Y) * Scale);
break;
}
@@ -660,12 +581,13 @@ namespace Barotrauma
var (x, y) = PlayerInput.MousePosition;
foreach (var pair in iPrefab.DisplayEntities)
{
Rectangle dRect = pair.Second;
Rectangle dRect = pair.Item2;
dRect = new Rectangle(x: (int)(dRect.X * iPrefab.Scale + x),
y: (int)(dRect.Y * iPrefab.Scale - y),
width: (int)(dRect.Width * iPrefab.Scale),
height: (int)(dRect.Height * iPrefab.Scale));
pair.First.DrawPlacing(spriteBatch, dRect, pair.First.Scale * iPrefab.Scale);
MapEntityPrefab prefab = MapEntityPrefab.Find("", pair.Item1);
prefab.DrawPlacing(spriteBatch, dRect, prefab.Scale * iPrefab.Scale);
}
break;
}
@@ -678,14 +600,14 @@ namespace Barotrauma
{
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: SamplerStateClamp, rasterizerState: GameMain.ScissorTestEnable);
if (GameMain.GameSession?.CrewManager is { DraggedOrder: { SymbolSprite: { } orderSprite, Color: var color }, DragOrder: true })
if (GameMain.GameSession?.CrewManager is { DraggedOrderPrefab: { SymbolSprite: { } orderSprite, Color: var color }, DragOrder: true })
{
float spriteSize = Math.Max(orderSprite.size.X, orderSprite.size.Y);
orderSprite.Draw(spriteBatch, PlayerInput.LatestMousePosition, color, orderSprite.size / 2f, scale: 32f / spriteSize * Scale);
}
var sprite = MouseCursorSprites[(int)MouseCursor] ?? MouseCursorSprites[(int)CursorState.Default];
var sprite = MouseCursorSprites[MouseCursor] ?? MouseCursorSprites[CursorState.Default];
sprite.Draw(spriteBatch, PlayerInput.LatestMousePosition, Color.White, sprite.Origin, 0f, Scale / 1.5f);
spriteBatch.End();
@@ -891,13 +813,13 @@ namespace Barotrauma
GUIMessageBox.AddActiveToGUIUpdateList();
GUIContextMenu.AddActiveToGUIUpdateList();
if (pauseMenuOpen)
if (PauseMenuOpen)
{
PauseMenu.AddToGUIUpdateList();
}
if (settingsMenuOpen)
if (SettingsMenuOpen)
{
GameMain.Config.SettingsFrame.AddToGUIUpdateList();
SettingsMenuContainer.AddToGUIUpdateList();
}
//the "are you sure you want to quit" prompts are drawn on top of everything else
@@ -1303,7 +1225,7 @@ namespace Barotrauma
private static void UpdateSavingIndicator(float deltaTime)
{
if (Style.SavingIndicator == null) { return; }
if (GUIStyle.SavingIndicator == null) { return; }
lock (mutex)
{
if (timeUntilSavingIndicatorDisabled.HasValue)
@@ -1349,7 +1271,7 @@ namespace Barotrauma
}
if (IsSavingIndicatorVisible)
{
savingIndicatorSpriteIndex = (savingIndicatorSpriteIndex + 15.0f * deltaTime) % (Style.SavingIndicator.FrameCount + 1);
savingIndicatorSpriteIndex = (savingIndicatorSpriteIndex + 15.0f * deltaTime) % (GUIStyle.SavingIndicator.FrameCount + 1);
}
}
}
@@ -1439,7 +1361,7 @@ namespace Barotrauma
public static void DrawLine(SpriteBatch sb, Vector2 start, Vector2 end, Color clr, float depth = 0.0f, float width = 1)
{
DrawLine(sb, t, start, end, clr, depth, (int)width);
DrawLine(sb, solidWhiteTexture, start, end, clr, depth, (int)width);
}
public static void DrawLine(SpriteBatch sb, Sprite sprite, Vector2 start, Vector2 end, Color clr, float depth = 0.0f, int width = 1)
@@ -1482,21 +1404,26 @@ namespace Barotrauma
depth);
}
public static void DrawString(SpriteBatch sb, Vector2 pos, string text, Color color, Color? backgroundColor = null, int backgroundPadding = 0, ScalableFont font = null)
public static void DrawString(SpriteBatch sb, Vector2 pos, LocalizedString text, Color color, Color? backgroundColor = null, int backgroundPadding = 0, GUIFont font = null)
{
if (font == null) font = Font;
DrawString(sb, pos, text.Value, color, backgroundColor, backgroundPadding, font);
}
public static void DrawString(SpriteBatch sb, Vector2 pos, string text, Color color, Color? backgroundColor = null, int backgroundPadding = 0, GUIFont font = null, ForceUpperCase forceUpperCase = ForceUpperCase.Inherit)
{
if (font == null) font = GUIStyle.Font;
if (backgroundColor != null)
{
Vector2 textSize = font.MeasureString(text);
DrawRectangle(sb, pos - Vector2.One * backgroundPadding, textSize + Vector2.One * 2.0f * backgroundPadding, (Color)backgroundColor, true);
}
font.DrawString(sb, text, pos, color);
font.DrawString(sb, text, pos, color, forceUpperCase: forceUpperCase);
}
public static void DrawStringWithColors(SpriteBatch sb, Vector2 pos, string text, Color color, List<RichTextData> richTextData, Color? backgroundColor = null, int backgroundPadding = 0, ScalableFont font = null, float depth = 0.0f)
public static void DrawStringWithColors(SpriteBatch sb, Vector2 pos, string text, Color color, in ImmutableArray<RichTextData>? richTextData, Color? backgroundColor = null, int backgroundPadding = 0, GUIFont font = null, float depth = 0.0f)
{
if (font == null) font = Font;
if (font == null) font = GUIStyle.Font;
if (backgroundColor != null)
{
Vector2 textSize = font.MeasureString(text);
@@ -1506,6 +1433,63 @@ namespace Barotrauma
font.DrawStringWithColors(sb, text, pos, color, 0.0f, Vector2.Zero, 1f, SpriteEffects.None, depth, richTextData);
}
private const int DonutSegments = 30;
private static readonly ImmutableArray<Vector2> canonicalCircle
= Enumerable.Range(0, DonutSegments)
.Select(i => i * (2.0f * MathF.PI / DonutSegments))
.Select(angle => new Vector2(MathF.Cos(angle), MathF.Sin(angle)))
.ToImmutableArray();
private static readonly VertexPositionColorTexture[] donutVerts = new VertexPositionColorTexture[DonutSegments * 4];
public static void DrawDonutSection(
SpriteBatch sb, Vector2 center, Range<float> radii, float sectionRad, Color clr, float depth = 0.0f)
{
float getRadius(int vertexIndex)
=> (vertexIndex % 4) switch
{
0 => radii.End,
1 => radii.End,
2 => radii.Start,
3 => radii.Start,
_ => throw new InvalidOperationException()
};
int getDirectionIndex(int vertexIndex)
=> (vertexIndex % 4) switch
{
0 => (vertexIndex / 4) + 0,
1 => (vertexIndex / 4) + 1,
2 => (vertexIndex / 4) + 0,
3 => (vertexIndex / 4) + 1,
_ => throw new InvalidOperationException()
};
float sectionProportion = sectionRad / (MathF.PI * 2.0f);
int maxDirectionIndex = Math.Min(DonutSegments, (int)MathF.Ceiling(sectionProportion * DonutSegments));
Vector2 getDirection(int vertexIndex)
{
int directionIndex = getDirectionIndex(vertexIndex);
Vector2 dir = canonicalCircle[directionIndex % DonutSegments];
if (maxDirectionIndex > 0 && directionIndex >= maxDirectionIndex)
{
float maxSectionProportion = (float)maxDirectionIndex / DonutSegments;
dir = Vector2.Lerp(
canonicalCircle[maxDirectionIndex - 1],
canonicalCircle[maxDirectionIndex % DonutSegments],
1.0f - (maxSectionProportion - sectionProportion) * DonutSegments);
}
return new Vector2(dir.Y, -dir.X);
}
for (int vertexIndex = 0; vertexIndex < maxDirectionIndex * 4; vertexIndex++)
{
donutVerts[vertexIndex].Color = clr;
donutVerts[vertexIndex].Position = new Vector3(center + getDirection(vertexIndex) * getRadius(vertexIndex), 0.0f);
}
sb.Draw(solidWhiteTexture, donutVerts, depth, count: maxDirectionIndex);
}
public static void DrawRectangle(SpriteBatch sb, Vector2 start, Vector2 size, Color clr, bool isFilled = false, float depth = 0.0f, float thickness = 1)
{
if (size.X < 0)
@@ -1525,15 +1509,15 @@ namespace Barotrauma
{
if (isFilled)
{
sb.Draw(t, rect, null, clr, 0.0f, Vector2.Zero, SpriteEffects.None, depth);
sb.Draw(solidWhiteTexture, rect, null, clr, 0.0f, Vector2.Zero, SpriteEffects.None, depth);
}
else
{
Rectangle srcRect = new Rectangle(0, 0, 1, 1);
sb.Draw(t, new Vector2(rect.X, rect.Y), srcRect, clr, 0.0f, Vector2.Zero, new Vector2(thickness, rect.Height), SpriteEffects.None, depth);
sb.Draw(t, new Vector2(rect.X + thickness, rect.Y), srcRect, clr, 0.0f, Vector2.Zero, new Vector2(rect.Width - thickness, thickness), SpriteEffects.None, depth);
sb.Draw(t, new Vector2(rect.X + thickness, rect.Bottom - thickness), srcRect, clr, 0.0f, Vector2.Zero, new Vector2(rect.Width - thickness, thickness), SpriteEffects.None, depth);
sb.Draw(t, new Vector2(rect.Right - thickness, rect.Y + thickness), srcRect, clr, 0.0f, Vector2.Zero, new Vector2(thickness, rect.Height - thickness * 2f), SpriteEffects.None, depth);
sb.Draw(solidWhiteTexture, new Vector2(rect.X, rect.Y), srcRect, clr, 0.0f, Vector2.Zero, new Vector2(thickness, rect.Height), SpriteEffects.None, depth);
sb.Draw(solidWhiteTexture, new Vector2(rect.X + thickness, rect.Y), srcRect, clr, 0.0f, Vector2.Zero, new Vector2(rect.Width - thickness, thickness), SpriteEffects.None, depth);
sb.Draw(solidWhiteTexture, new Vector2(rect.X + thickness, rect.Bottom - thickness), srcRect, clr, 0.0f, Vector2.Zero, new Vector2(rect.Width - thickness, thickness), SpriteEffects.None, depth);
sb.Draw(solidWhiteTexture, new Vector2(rect.Right - thickness, rect.Y + thickness), srcRect, clr, 0.0f, Vector2.Zero, new Vector2(thickness, rect.Height - thickness * 2f), SpriteEffects.None, depth);
}
}
@@ -1555,7 +1539,7 @@ namespace Barotrauma
size.Y = -size.Y;
}
sb.Draw(t, start, null, clr, 0f, Vector2.Zero, size, SpriteEffects.None, depth);
sb.Draw(solidWhiteTexture, start, null, clr, 0f, Vector2.Zero, size, SpriteEffects.None, depth);
}
public static void DrawRectangle(SpriteBatch sb, Vector2 center, float width, float height, float rotation, Color clr, float depth = 0.0f, float thickness = 1)
@@ -1621,14 +1605,14 @@ namespace Barotrauma
Vector2 origin;
try
{
origin = Font.MeasureString(text) / 2;
origin = GUIStyle.Font.MeasureString(text) / 2;
}
catch
{
origin = Vector2.Zero;
}
Font.DrawString(sb, text, new Vector2(rect.Center.X, rect.Center.Y), Color.White, 0.0f, origin, 1.0f, SpriteEffects.None, 0.0f);
GUIStyle.Font.DrawString(sb, text, new Vector2(rect.Center.X, rect.Center.Y), Color.White, 0.0f, origin, 1.0f, SpriteEffects.None, 0.0f);
return clicked;
}
@@ -1698,7 +1682,7 @@ namespace Barotrauma
public static void DrawSineWithDots(SpriteBatch spriteBatch, Vector2 from, Vector2 dir, float amplitude, float length, float scale, int pointCount, Color color, int dotSize = 2)
{
Vector2 up = dir.Right();
//DrawLine(spriteBatch, from, from + dir, GUI.Style.Red);
//DrawLine(spriteBatch, from, from + dir, GUIStyle.Red);
//DrawLine(spriteBatch, from, from + up * dir.Length(), Color.Blue);
for (int i = 0; i < pointCount; i++)
{
@@ -1715,8 +1699,8 @@ namespace Barotrauma
private static void DrawSavingIndicator(SpriteBatch spriteBatch)
{
if (!IsSavingIndicatorVisible || Style.SavingIndicator == null) { return; }
var sheet = Style.SavingIndicator;
if (!IsSavingIndicatorVisible || GUIStyle.SavingIndicator == null) { return; }
var sheet = GUIStyle.SavingIndicator;
Vector2 pos = new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight) - new Vector2(HUDLayoutSettings.Padding) - 2 * Scale * sheet.FrameSize.ToVector2();
sheet.Draw(spriteBatch, (int)Math.Floor(savingIndicatorSpriteIndex), pos, savingIndicatorColor, origin: Vector2.Zero, rotate: 0.0f, scale: new Vector2(Scale));
}
@@ -1907,9 +1891,9 @@ namespace Barotrauma
return CreateElements(count, parent, constructor, null, absoluteSize, anchor, pivot, null, null, absoluteSpacing, relativeSpacing, extraSpacing, startOffsetAbsolute, startOffsetRelative, isHorizontal);
}
public static GUIComponent CreateEnumField(Enum value, int elementHeight, string name, RectTransform parent, string toolTip = null, ScalableFont font = null)
public static GUIComponent CreateEnumField(Enum value, int elementHeight, LocalizedString name, RectTransform parent, string toolTip = null, GUIFont font = null)
{
font = font ?? SmallFont;
font = font ?? GUIStyle.SmallFont;
var frame = new GUIFrame(new RectTransform(new Point(parent.Rect.Width, elementHeight), parent), color: Color.Transparent);
new GUITextBlock(new RectTransform(new Vector2(0.6f, 1), frame.RectTransform), name, font: font)
{
@@ -1928,10 +1912,10 @@ namespace Barotrauma
return frame;
}
public static GUIComponent CreateRectangleField(Rectangle value, int elementHeight, string name, RectTransform parent, string toolTip = null, ScalableFont font = null)
public static GUIComponent CreateRectangleField(Rectangle value, int elementHeight, LocalizedString name, RectTransform parent, LocalizedString toolTip = null, GUIFont font = null)
{
var frame = new GUIFrame(new RectTransform(new Point(parent.Rect.Width, Math.Max(elementHeight, 26)), parent), color: Color.Transparent);
font = font ?? SmallFont;
font = font ?? GUIStyle.SmallFont;
new GUITextBlock(new RectTransform(new Vector2(0.2f, 1), frame.RectTransform), name, font: font)
{
ToolTip = toolTip
@@ -1944,7 +1928,7 @@ namespace Barotrauma
for (int i = 3; i >= 0; i--)
{
var element = new GUIFrame(new RectTransform(new Vector2(0.22f, 1), inputArea.RectTransform) { MinSize = new Point(50, 0), MaxSize = new Point(150, 50) }, style: null);
new GUITextBlock(new RectTransform(new Vector2(0.3f, 1), element.RectTransform, Anchor.CenterLeft), rectComponentLabels[i], font: font, textAlignment: Alignment.CenterLeft);
new GUITextBlock(new RectTransform(new Vector2(0.3f, 1), element.RectTransform, Anchor.CenterLeft), RectComponentLabels[i], font: font, textAlignment: Alignment.CenterLeft);
GUINumberInput numberInput = new GUINumberInput(new RectTransform(new Vector2(0.7f, 1), element.RectTransform, Anchor.CenterRight),
GUINumberInput.NumberType.Int)
{
@@ -1973,10 +1957,10 @@ namespace Barotrauma
return frame;
}
public static GUIComponent CreatePointField(Point value, int elementHeight, string displayName, RectTransform parent, string toolTip = null)
public static GUIComponent CreatePointField(Point value, int elementHeight, LocalizedString displayName, RectTransform parent, LocalizedString toolTip = null)
{
var frame = new GUIFrame(new RectTransform(new Point(parent.Rect.Width, Math.Max(elementHeight, 26)), parent), color: Color.Transparent);
new GUITextBlock(new RectTransform(new Vector2(0.4f, 1), frame.RectTransform), displayName, font: SmallFont)
new GUITextBlock(new RectTransform(new Vector2(0.4f, 1), frame.RectTransform), displayName, font: GUIStyle.SmallFont)
{
ToolTip = toolTip
};
@@ -1988,11 +1972,11 @@ namespace Barotrauma
for (int i = 1; i >= 0; i--)
{
var element = new GUIFrame(new RectTransform(new Vector2(0.45f, 1), inputArea.RectTransform), style: null);
new GUITextBlock(new RectTransform(new Vector2(0.3f, 1), element.RectTransform, Anchor.CenterLeft), vectorComponentLabels[i], font: SmallFont, textAlignment: Alignment.CenterLeft);
new GUITextBlock(new RectTransform(new Vector2(0.3f, 1), element.RectTransform, Anchor.CenterLeft), VectorComponentLabels[i], font: GUIStyle.SmallFont, textAlignment: Alignment.CenterLeft);
GUINumberInput numberInput = new GUINumberInput(new RectTransform(new Vector2(0.7f, 1), element.RectTransform, Anchor.CenterRight),
GUINumberInput.NumberType.Int)
{
Font = SmallFont
Font = GUIStyle.SmallFont
};
if (i == 0)
@@ -2003,9 +1987,9 @@ namespace Barotrauma
return frame;
}
public static GUIComponent CreateVector2Field(Vector2 value, int elementHeight, string name, RectTransform parent, string toolTip = null, ScalableFont font = null, int decimalsToDisplay = 1)
public static GUIComponent CreateVector2Field(Vector2 value, int elementHeight, LocalizedString name, RectTransform parent, LocalizedString toolTip = null, GUIFont font = null, int decimalsToDisplay = 1)
{
font = font ?? SmallFont;
font = font ?? GUIStyle.SmallFont;
var frame = new GUIFrame(new RectTransform(new Point(parent.Rect.Width, Math.Max(elementHeight, 26)), parent), color: Color.Transparent);
new GUITextBlock(new RectTransform(new Vector2(0.4f, 1), frame.RectTransform), name, font: font)
{
@@ -2019,7 +2003,7 @@ namespace Barotrauma
for (int i = 1; i >= 0; i--)
{
var element = new GUIFrame(new RectTransform(new Vector2(0.45f, 1), inputArea.RectTransform), style: null);
new GUITextBlock(new RectTransform(new Vector2(0.3f, 1), element.RectTransform, Anchor.CenterLeft), vectorComponentLabels[i], font: font, textAlignment: Alignment.CenterLeft);
new GUITextBlock(new RectTransform(new Vector2(0.3f, 1), element.RectTransform, Anchor.CenterLeft), VectorComponentLabels[i], font: font, textAlignment: Alignment.CenterLeft);
GUINumberInput numberInput = new GUINumberInput(new RectTransform(new Vector2(0.7f, 1), element.RectTransform, Anchor.CenterRight), GUINumberInput.NumberType.Float) { Font = font };
switch (i)
{
@@ -2035,7 +2019,7 @@ namespace Barotrauma
return frame;
}
public static void NotifyPrompt(string header, string body)
public static void NotifyPrompt(LocalizedString header, LocalizedString body)
{
GUIMessageBox msgBox = new GUIMessageBox(header, body, new[] { TextManager.Get("Ok") }, new Vector2(0.2f, 0.175f), minSize: new Point(300, 175));
msgBox.Buttons[0].OnClicked = delegate
@@ -2045,9 +2029,9 @@ namespace Barotrauma
};
}
public static GUIMessageBox AskForConfirmation(string header, string body, Action onConfirm, Action onDeny = null)
public static GUIMessageBox AskForConfirmation(LocalizedString header, LocalizedString body, Action onConfirm, Action onDeny = null)
{
string[] buttons = { TextManager.Get("Ok"), TextManager.Get("Cancel") };
LocalizedString[] buttons = { TextManager.Get("Ok"), TextManager.Get("Cancel") };
GUIMessageBox msgBox = new GUIMessageBox(header, body, buttons, new Vector2(0.2f, 0.175f), minSize: new Point(300, 175));
// Cancel button
@@ -2068,9 +2052,9 @@ namespace Barotrauma
return msgBox;
}
public static GUIMessageBox PromptTextInput(string header, string body, Action<string> onConfirm)
public static GUIMessageBox PromptTextInput(LocalizedString header, string body, Action<string> onConfirm)
{
string[] buttons = { TextManager.Get("Ok"), TextManager.Get("Cancel") };
LocalizedString[] buttons = { TextManager.Get("Ok"), TextManager.Get("Cancel") };
GUIMessageBox msgBox = new GUIMessageBox(header, string.Empty, buttons, new Vector2(0.2f, 0.175f), minSize: new Point(300, 175));
GUITextBox textBox = new GUITextBox(new RectTransform(Vector2.One, msgBox.Content.RectTransform), text: body)
{
@@ -2198,16 +2182,18 @@ namespace Barotrauma
/// <param name="clampArea">The elements will not be moved outside this area. If the parameter is not given, the elements are kept inside the window.</param>
public static void PreventElementOverlap(IList<GUIComponent> elements, IList<Rectangle> disallowedAreas = null, Rectangle? clampArea = null)
{
List<GUIComponent> sortedElements = elements.OrderByDescending(e => e.Rect.Width + e.Rect.Height).ToList();
Rectangle area = clampArea ?? new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
for (int i = 0; i < elements.Count; i++)
for (int i = 0; i < sortedElements.Count; i++)
{
Point moveAmount = Point.Zero;
Rectangle rect1 = elements[i].Rect;
Rectangle rect1 = sortedElements[i].Rect;
moveAmount.X += Math.Max(area.X - rect1.X, 0);
moveAmount.X -= Math.Max(rect1.Right - area.Right, 0);
moveAmount.Y += Math.Max(area.Y - rect1.Y, 0);
moveAmount.Y -= Math.Max(rect1.Bottom - area.Bottom, 0);
elements[i].RectTransform.ScreenSpaceOffset += moveAmount;
sortedElements[i].RectTransform.ScreenSpaceOffset += moveAmount;
}
bool intersections = true;
@@ -2215,18 +2201,18 @@ namespace Barotrauma
while (intersections && iterations < 100)
{
intersections = false;
for (int i = 0; i < elements.Count; i++)
for (int i = 0; i < sortedElements.Count; i++)
{
Rectangle rect1 = elements[i].Rect;
for (int j = i + 1; j < elements.Count; j++)
Rectangle rect1 = sortedElements[i].Rect;
for (int j = i + 1; j < sortedElements.Count; j++)
{
Rectangle rect2 = elements[j].Rect;
Rectangle rect2 = sortedElements[j].Rect;
if (!rect1.Intersects(rect2)) { continue; }
intersections = true;
Point centerDiff = rect1.Center - rect2.Center;
//move the interfaces away from each other, in a random direction if they're at the same position
Vector2 moveAmount = centerDiff == Point.Zero ? Rand.Vector(1.0f) : Vector2.Normalize(centerDiff.ToVector2());
Vector2 moveAmount = centerDiff == Point.Zero ? Vector2.UnitX + Rand.Vector(0.1f) : Vector2.Normalize(centerDiff.ToVector2());
//if the horizontal move amount is much larger than vertical, only move horizontally
//(= attempt to place the elements side-by-side if they're more apart horizontally than vertically)
@@ -2246,8 +2232,8 @@ namespace Barotrauma
//move by 10 units in the desired direction and repeat until nothing overlaps
//(or after 100 iterations, in which case we'll just give up and let them overlap)
elements[i].RectTransform.ScreenSpaceOffset += moveAmount1.ToPoint();
elements[j].RectTransform.ScreenSpaceOffset += moveAmount2.ToPoint();
sortedElements[i].RectTransform.ScreenSpaceOffset += moveAmount1.ToPoint();
sortedElements[j].RectTransform.ScreenSpaceOffset += moveAmount2.ToPoint();
}
if (disallowedAreas == null) { continue; }
@@ -2265,7 +2251,7 @@ namespace Barotrauma
//move by 10 units in the desired direction and repeat until nothing overlaps
//(or after 100 iterations, in which case we'll just give up and let them overlap)
elements[i].RectTransform.ScreenSpaceOffset += (moveAmount1).ToPoint();
sortedElements[i].RectTransform.ScreenSpaceOffset += (moveAmount1).ToPoint();
}
}
iterations++;
@@ -2301,11 +2287,11 @@ namespace Barotrauma
if (Screen.Selected == GameMain.MainMenuScreen) { return; }
if (PreventPauseMenuToggle) { return; }
settingsMenuOpen = false;
SettingsMenuOpen = false;
TogglePauseMenu(null, null);
if (pauseMenuOpen)
if (PauseMenuOpen)
{
Inventory.DraggingItems.Clear();
Inventory.DraggingInventory = null;
@@ -2330,7 +2316,7 @@ namespace Barotrauma
};
CreateButton("PauseMenuResume", buttonContainer, null);
CreateButton("PauseMenuSettings", buttonContainer, () => { settingsMenuOpen = !settingsMenuOpen; });
CreateButton("PauseMenuSettings", buttonContainer, () => SettingsMenuOpen = true);
bool IsOutpostLevel() => GameMain.GameSession != null && Level.IsLoadedOutpost;
if (Screen.Selected == GameMain.GameScreen && GameMain.GameSession != null)
@@ -2407,7 +2393,7 @@ namespace Barotrauma
{
if (string.IsNullOrEmpty(verificationTextTag))
{
pauseMenuOpen = false;
PauseMenuOpen = false;
action?.Invoke();
}
else
@@ -2422,13 +2408,13 @@ namespace Barotrauma
void CreateVerificationPrompt(string textTag, Action confirmAction)
{
var msgBox = new GUIMessageBox("", TextManager.Get(textTag),
new string[] { TextManager.Get("Yes"), TextManager.Get("No") })
new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") })
{
UserData = "verificationprompt"
};
msgBox.Buttons[0].OnClicked = (_, __) =>
{
pauseMenuOpen = false;
PauseMenuOpen = false;
confirmAction?.Invoke();
return true;
};
@@ -2439,8 +2425,8 @@ namespace Barotrauma
private static bool TogglePauseMenu(GUIButton button, object obj)
{
pauseMenuOpen = !pauseMenuOpen;
if (!pauseMenuOpen && PauseMenu != null)
PauseMenuOpen = !PauseMenuOpen;
if (!PauseMenuOpen && PauseMenu != null)
{
PauseMenu.RectTransform.Parent = null;
PauseMenu = null;
@@ -2451,10 +2437,21 @@ namespace Barotrauma
/// <summary>
/// Displays a message at the center of the screen, automatically preventing overlapping with other centered messages. TODO: Allow to show messages at the middle of the screen (instead of the top center).
/// </summary>
public static void AddMessage(string message, Color color, float? lifeTime = null, bool playSound = true, ScalableFont font = null)
///
public static void AddMessage(LocalizedString message, Color color, float? lifeTime = null, bool playSound = true, GUIFont font = null)
{
AddMessage(message.Value, color, lifeTime, playSound, font);
}
public static void AddMessage(LocalizedString message, Color color, Vector2 pos, Vector2 velocity, float lifeTime = 3.0f, bool playSound = true, GUISoundType soundType = GUISoundType.UIMessage, int subId = -1)
{
AddMessage(message.Value, color, pos, velocity, lifeTime, playSound, soundType, subId);
}
public static void AddMessage(string message, Color color, float? lifeTime = null, bool playSound = true, GUIFont font = null)
{
if (messages.Any(msg => msg.Text == message)) { return; }
messages.Add(new GUIMessage(message, color, lifeTime ?? MathHelper.Clamp(message.Length / 5.0f, 3.0f, 10.0f), font ?? LargeFont));
messages.Add(new GUIMessage(message, color, lifeTime ?? MathHelper.Clamp(message.Length / 5.0f, 3.0f, 10.0f), font ?? GUIStyle.LargeFont));
if (playSound) { SoundPlayer.PlayUISound(GUISoundType.UIMessage); }
}
@@ -2462,7 +2459,7 @@ namespace Barotrauma
{
Submarine sub = Submarine.Loaded.FirstOrDefault(s => s.ID == subId);
var newMessage = new GUIMessage(message, color, pos, velocity, lifeTime, Alignment.Center, Font, sub: sub);
var newMessage = new GUIMessage(message, color, pos, velocity, lifeTime, Alignment.Center, GUIStyle.Font, sub: sub);
if (playSound) { SoundPlayer.PlayUISound(soundType); }
bool overlapFound = true;
int tries = 0;
@@ -116,32 +116,32 @@ namespace Barotrauma
get { return Frame.FlashTimer; }
}
public override ScalableFont Font
public override GUIFont Font
{
get
{
return (textBlock == null) ? GUI.Font : textBlock.Font;
return (textBlock == null) ? GUIStyle.Font : textBlock.Font;
}
set
{
base.Font = value;
if (textBlock != null) textBlock.Font = value;
if (textBlock != null) { textBlock.Font = value; }
}
}
public string Text
public LocalizedString Text
{
get { return textBlock.Text; }
set { textBlock.Text = value; }
}
public bool ForceUpperCase
public ForceUpperCase ForceUpperCase
{
get { return textBlock.ForceUpperCase; }
set { textBlock.ForceUpperCase = value; }
}
public override string ToolTip
public override RichString ToolTip
{
get
{
@@ -160,39 +160,36 @@ namespace Barotrauma
private bool flashed;
public GUISoundType ClickSound { get; set; } = GUISoundType.Click;
public GUIButton(RectTransform rectT, string text = "", Alignment textAlignment = Alignment.Center, string style = "", Color? color = null) : base(style, rectT)
public GUIButton(RectTransform rectT, Alignment textAlignment = Alignment.Center, string style = "", Color? color = null) : this(rectT, new RawLString(""), textAlignment, style, color) { }
public GUIButton(RectTransform rectT, LocalizedString text, Alignment textAlignment = Alignment.Center, string style = "", Color? color = null) : base(style, rectT)
{
CanBeFocused = true;
HoverCursor = CursorState.Hand;
frame = new GUIFrame(new RectTransform(Vector2.One, rectT), style) { CanBeFocused = false };
if (style != null) { GUI.Style.Apply(frame, style == "" ? "GUIButton" : style); }
if (style != null) { GUIStyle.Apply(frame, style == "" ? "GUIButton" : style); }
if (color.HasValue)
{
this.color = frame.Color = color.Value;
}
var selfStyle = Style;
textBlock = new GUITextBlock(new RectTransform(Vector2.One, rectT, Anchor.Center), text, textAlignment: textAlignment, style: null)
{
TextColor = this.style == null ? Color.Black : this.style.TextColor,
HoverTextColor = this.style == null ? Color.Black : this.style.HoverTextColor,
SelectedTextColor = this.style == null ? Color.Black : this.style.SelectedTextColor,
TextColor = selfStyle?.TextColor ?? Color.Black,
HoverTextColor = selfStyle?.HoverTextColor ?? Color.Black,
SelectedTextColor = selfStyle?.SelectedTextColor ?? Color.Black,
CanBeFocused = false
};
if (rectT.Rect.Height == 0 && !string.IsNullOrEmpty(text))
if (rectT.Rect.Height == 0 && !text.IsNullOrEmpty())
{
RectTransform.Resize(new Point(RectTransform.Rect.Width, (int)Font.MeasureString(textBlock.Text).Y));
RectTransform.MinSize = textBlock.RectTransform.MinSize = new Point(0, System.Math.Max(rectT.MinSize.Y, Rect.Height));
TextBlock.SetTextPos();
}
GUI.Style.Apply(textBlock, "", this);
//if the text is in chinese/korean/japanese and we're not using a CJK-compatible font,
//use the default CJK font as a fallback
if (TextManager.IsCJK(textBlock.Text) && !textBlock.Font.IsCJK)
{
textBlock.Font = GUI.CJKFont;
}
GUIStyle.Apply(textBlock, "", this);
Enabled = true;
}
@@ -217,7 +214,7 @@ namespace Barotrauma
float expand = (pulseExpand * 20.0f) * GUI.Scale;
expandRect.Inflate(expand, expand);
GUI.Style.ButtonPulse.Draw(spriteBatch, expandRect, ToolBox.GradientLerp(pulseExpand, Color.White, Color.White, Color.Transparent));
GUIStyle.EndRoundButtonPulse.Draw(spriteBatch, expandRect, ToolBox.GradientLerp(pulseExpand, Color.White, Color.White, Color.Transparent));
}
}
@@ -8,6 +8,7 @@ using System.Xml.Linq;
using Barotrauma.IO;
using RestSharp;
using System.Net;
using System.Collections.Immutable;
namespace Barotrauma
{
@@ -66,7 +67,7 @@ namespace Barotrauma
{
foreach (GUIComponent child in Children)
{
if (child.UserData == obj || (child.userData != null && child.userData.Equals(obj))) { return child; }
if (child.UserData == obj || (child.UserData != null && child.UserData.Equals(obj))) { return child; }
}
return null;
}
@@ -107,7 +108,7 @@ namespace Barotrauma
}
public GUIComponent FindChild(object userData, bool recursive = false)
{
var matchingChild = Children.FirstOrDefault(c => c.userData == userData);
var matchingChild = Children.FirstOrDefault(c => c.UserData == userData);
if (recursive && matchingChild == null)
{
foreach (GUIComponent child in Children)
@@ -122,7 +123,7 @@ namespace Barotrauma
public IEnumerable<GUIComponent> FindChildren(object userData)
{
return Children.Where(c => c.userData == userData);
return Children.Where(c => c.UserData == userData);
}
public IEnumerable<GUIComponent> FindChildren(Func<GUIComponent, bool> predicate)
@@ -161,9 +162,7 @@ namespace Barotrauma
protected Alignment alignment;
protected GUIComponentStyle style;
protected object userData;
protected Identifier[] styleHierarchy;
public bool CanBeFocused;
@@ -206,16 +205,14 @@ namespace Barotrauma
}
}
public virtual ScalableFont Font
public virtual GUIFont Font
{
get;
set;
}
// Use the rawtooltip when copying displayed tooltips so that any possible color-data related values are translated over as well
public string RawToolTip;
private string toolTip;
public virtual string ToolTip
private RichString toolTip;
public virtual RichString ToolTip
{
get
{
@@ -223,18 +220,12 @@ namespace Barotrauma
}
set
{
RawToolTip = value;
TooltipRichTextData = RichTextData.GetRichTextData(value, out value);
toolTip = value;
}
}
public List<RichTextData> TooltipRichTextData = null;
public GUIComponentStyle Style
{
get { return style; }
}
=> GUIComponentStyle.FromHierarchy(styleHierarchy);
public bool Visible
{
@@ -258,8 +249,8 @@ namespace Barotrauma
protected Rectangle ClampRect(Rectangle r)
{
if (Parent == null || !ClampMouseRectToParent) { return r; }
Rectangle parentRect = Parent.ClampRect(Parent.Rect);
if (Parent is null) { return r; }
Rectangle parentRect = !Parent.ClampMouseRectToParent ? Parent.Rect : Parent.ClampRect(Parent.Rect);
if (parentRect.Width <= 0 || parentRect.Height <= 0) { return Rectangle.Empty; }
if (parentRect.X > r.X)
{
@@ -293,11 +284,13 @@ namespace Barotrauma
}
public bool ClampMouseRectToParent { get; set; } = false;
public virtual Rectangle MouseRect
{
get
{
if (!CanBeFocused) { return Rectangle.Empty; }
return ClampMouseRectToParent ? ClampRect(Rect) : Rect;
}
}
@@ -310,13 +303,13 @@ namespace Barotrauma
protected ComponentState _state;
protected ComponentState _previousState;
protected bool selected;
protected bool isSelected;
public virtual bool Selected
{
get { return selected; }
get { return isSelected; }
set
{
selected = value;
isSelected = value;
foreach (var child in Children)
{
child.Selected = value;
@@ -338,11 +331,8 @@ namespace Barotrauma
}
}
public object UserData
{
get { return userData; }
set { userData = value; }
}
#warning TODO: this is cursed, stop using this
public object UserData;
public int CountChildren
{
@@ -417,20 +407,20 @@ namespace Barotrauma
Visible = true;
OutlineColor = Color.Transparent;
Font = GUI.Font;
Font = GUIStyle.Font;
CanBeFocused = true;
if (style != null) { GUI.Style.Apply(this, style); }
if (style != null) { GUIStyle.Apply(this, style); }
}
protected GUIComponent(string style)
{
Visible = true;
OutlineColor = Color.Transparent;
Font = GUI.Font;
Font = GUIStyle.Font;
CanBeFocused = true;
if (style != null) { GUI.Style.Apply(this, style); }
if (style != null) { GUIStyle.Apply(this, style); }
}
#region Updating
@@ -486,7 +476,7 @@ namespace Barotrauma
{
if (GUI.IsMouseOn(this) && PlayerInput.SecondaryMouseButtonClicked())
{
OnSecondaryClicked?.Invoke(this, userData);
OnSecondaryClicked?.Invoke(this, UserData);
}
}
@@ -704,7 +694,7 @@ namespace Barotrauma
if (GlowOnSelect && State == ComponentState.Selected)
{
GUI.UIGlow.Draw(spriteBatch, Rect, SelectedColor);
GUIStyle.UIGlow.Draw(spriteBatch, Rect, SelectedColor);
}
if (flashTimer > 0.0f)
@@ -724,7 +714,7 @@ namespace Barotrauma
}
else
{
var glow = useCircularFlash ? GUI.UIGlowCircular : GUI.UIGlow;
var glow = useCircularFlash ? GUIStyle.UIGlowCircular : GUIStyle.UIGlow;
glow.Draw(spriteBatch,
flashRect,
flashColor * (float)Math.Sin(flashTimer % flashCycleDuration / flashCycleDuration * MathHelper.Pi * 0.8f));
@@ -738,24 +728,24 @@ namespace Barotrauma
public void DrawToolTip(SpriteBatch spriteBatch)
{
if (!Visible) { return; }
DrawToolTip(spriteBatch, ToolTip, GUI.MouseOn.Rect, TooltipRichTextData);
DrawToolTip(spriteBatch, ToolTip, GUI.MouseOn.Rect);
}
public static void DrawToolTip(SpriteBatch spriteBatch, string toolTip, Vector2 pos, List<RichTextData> richTextData = null)
public static void DrawToolTip(SpriteBatch spriteBatch, RichString toolTip, Vector2 pos)
{
if (Tutorials.Tutorial.ContentRunning) { return; }
if (GameMain.GameSession?.GameMode is TutorialMode tutorialMode && tutorialMode.Tutorial.ContentRunning) { return; }
int width = (int)(400 * GUI.Scale);
int height = (int)(18 * GUI.Scale);
Point padding = new Point((int)(10 * GUI.Scale));
if (toolTipBlock == null || (string)toolTipBlock.userData != toolTip)
if (toolTipBlock == null || (RichString)toolTipBlock.UserData != toolTip)
{
toolTipBlock = new GUITextBlock(new RectTransform(new Point(width, height), null), richTextData, toolTip, font: GUI.SmallFont, wrap: true, style: "GUIToolTip");
toolTipBlock = new GUITextBlock(new RectTransform(new Point(width, height), null), toolTip, font: GUIStyle.SmallFont, wrap: true, style: "GUIToolTip");
toolTipBlock.RectTransform.NonScaledSize = new Point(
(int)(GUI.SmallFont.MeasureString(toolTipBlock.WrappedText).X + padding.X + toolTipBlock.Padding.X + toolTipBlock.Padding.Z),
(int)(GUI.SmallFont.MeasureString(toolTipBlock.WrappedText).Y + padding.Y + toolTipBlock.Padding.Y + toolTipBlock.Padding.W));
toolTipBlock.userData = toolTip;
(int)(GUIStyle.SmallFont.MeasureString(toolTipBlock.WrappedText).X + padding.X + toolTipBlock.Padding.X + toolTipBlock.Padding.Z),
(int)(GUIStyle.SmallFont.MeasureString(toolTipBlock.WrappedText).Y + padding.Y + toolTipBlock.Padding.Y + toolTipBlock.Padding.W));
toolTipBlock.UserData = toolTip;
}
toolTipBlock.RectTransform.AbsoluteOffset = pos.ToPoint();
@@ -764,21 +754,21 @@ namespace Barotrauma
toolTipBlock.DrawManually(spriteBatch);
}
public static void DrawToolTip(SpriteBatch spriteBatch, string toolTip, Rectangle targetElement, List<RichTextData> richTextData = null)
public static void DrawToolTip(SpriteBatch spriteBatch, RichString toolTip, Rectangle targetElement)
{
if (Tutorials.Tutorial.ContentRunning) { return; }
if (GameMain.GameSession?.GameMode is TutorialMode tutorialMode && tutorialMode.Tutorial.ContentRunning) { return; }
int width = (int)(400 * GUI.Scale);
int height = (int)(18 * GUI.Scale);
Point padding = new Point((int)(10 * GUI.Scale));
if (toolTipBlock == null || (string)toolTipBlock.userData != toolTip)
if (toolTipBlock == null || (RichString)toolTipBlock.UserData != toolTip)
{
toolTipBlock = new GUITextBlock(new RectTransform(new Point(width, height), null), richTextData, toolTip, font: GUI.SmallFont, wrap: true, style: "GUIToolTip");
toolTipBlock = new GUITextBlock(new RectTransform(new Point(width, height), null), toolTip, font: GUIStyle.SmallFont, wrap: true, style: "GUIToolTip");
toolTipBlock.RectTransform.NonScaledSize = new Point(
(int)(toolTipBlock.Font.MeasureString(toolTipBlock.WrappedText).X + padding.X + toolTipBlock.Padding.X + toolTipBlock.Padding.Z),
(int)(toolTipBlock.Font.MeasureString(toolTipBlock.WrappedText).Y + padding.Y + toolTipBlock.Padding.Y + toolTipBlock.Padding.W));
toolTipBlock.userData = toolTip;
toolTipBlock.UserData = toolTip;
}
toolTipBlock.RectTransform.AbsoluteOffset = new Point(targetElement.Center.X, targetElement.Bottom);
@@ -811,7 +801,7 @@ namespace Barotrauma
this.useRectangleFlash = useRectangleFlash;
this.useCircularFlash = useCircularFlash;
this.flashDuration = flashDuration;
flashColor = (color == null) ? GUI.Style.Red : (Color)color;
flashColor = (color == null) ? GUIStyle.Red : (Color)color;
}
public void FadeOut(float duration, bool removeAfter, float wait = 0.0f)
@@ -952,8 +942,7 @@ namespace Barotrauma
ApplySizeRestrictions(style);
}
this.style = style;
styleHierarchy = GUIComponentStyle.ToHierarchy(style);
}
public void ApplySizeRestrictions(GUIComponentStyle style)
@@ -972,11 +961,11 @@ namespace Barotrauma
}
}
public static GUIComponent FromXML(XElement element, RectTransform parent)
public static GUIComponent FromXML(ContentXElement element, RectTransform parent)
{
GUIComponent component = null;
foreach (XElement subElement in element.Elements())
foreach (var subElement in element.Elements())
{
if (subElement.Name.ToString().Equals("conditional", StringComparison.OrdinalIgnoreCase) && !CheckConditional(subElement))
{
@@ -1027,7 +1016,7 @@ namespace Barotrauma
if (component != null)
{
foreach (XElement subElement in element.Elements())
foreach (var subElement in element.Elements())
{
if (subElement.Name.ToString().Equals("conditional", StringComparison.OrdinalIgnoreCase)) { continue; }
FromXML(subElement, component is GUIListBox listBox ? listBox.Content.RectTransform : component.RectTransform);
@@ -1078,8 +1067,9 @@ namespace Barotrauma
switch (attribute.Name.ToString().ToLowerInvariant())
{
case "language":
string[] languages = element.GetAttributeStringArray(attribute.Name.ToString(), new string[0]);
if (!languages.Any(l => GameMain.Config.Language.Equals(l, StringComparison.OrdinalIgnoreCase))) { return false; }
var languages = element.GetAttributeIdentifierArray(attribute.Name.ToString(), Array.Empty<Identifier>())
.Select(s => new LanguageIdentifier(s));
if (!languages.Any(l => GameSettings.CurrentConfig.Language == l)) { return false; }
break;
case "gameversion":
var version = new Version(attribute.Value);
@@ -1136,23 +1126,12 @@ namespace Barotrauma
if (element.Attribute("color") != null) { color = element.GetAttributeColor("color", Color.White); }
float scale = element.GetAttributeFloat("scale", 1.0f);
bool wrap = element.GetAttributeBool("wrap", true);
Alignment alignment = Alignment.Center;
Enum.TryParse(element.GetAttributeString("alignment", "Center"), out alignment);
ScalableFont font = GUI.Font;
switch (element.GetAttributeString("font", "Font").ToLowerInvariant())
Alignment alignment =
element.GetAttributeEnum("alignment", text.Contains('\n') ? Alignment.Left : Alignment.Center);
GUIFont font;
if (!GUIStyle.Fonts.TryGetValue(element.GetAttributeIdentifier("font", "Font"), out font))
{
case "font":
font = GUI.Font;
break;
case "smallfont":
font = GUI.SmallFont;
break;
case "largefont":
font = GUI.LargeFont;
break;
case "subheading":
font = GUI.SubHeadingFont;
break;
font = GUIStyle.Font;
}
var textBlock = new GUITextBlock(RectTransform.Load(element, parent),
@@ -1265,7 +1244,7 @@ namespace Barotrauma
};
}
private static GUIImage LoadGUIImage(XElement element, RectTransform parent)
private static GUIImage LoadGUIImage(ContentXElement element, RectTransform parent)
{
Sprite sprite;
string url = element.GetAttributeString("url", "");
@@ -1298,11 +1277,11 @@ namespace Barotrauma
return new GUIImage(RectTransform.Load(element, parent), sprite, scaleToFit: true);
}
private static GUIButton LoadAccordion(XElement element, RectTransform parent)
private static GUIButton LoadAccordion(ContentXElement element, RectTransform parent)
{
var button = LoadGUIButton(element, parent);
List<GUIComponent> content = new List<GUIComponent>();
foreach (XElement subElement in element.Elements())
foreach (var subElement in element.Elements())
{
var contentElement = FromXML(subElement, parent);
if (contentElement != null)
@@ -9,16 +9,23 @@ namespace Barotrauma
{
struct ContextMenuOption
{
public string Label;
public LocalizedString Label;
public Action OnSelected;
public ContextMenuOption[]? SubOptions;
public bool IsEnabled;
public string Tooltip;
public LocalizedString Tooltip;
public ContextMenuOption(string labelTag, bool isEnabled, Action onSelected)
: this(TextManager.Get(labelTag), isEnabled, onSelected) { }
public ContextMenuOption(Identifier labelTag, bool isEnabled, Action onSelected)
: this(TextManager.Get(labelTag), isEnabled, onSelected) { }
// Creates a regular context menu
public ContextMenuOption(string label, bool isEnabled, Action onSelected)
public ContextMenuOption(LocalizedString label, bool isEnabled, Action onSelected)
{
Label = TextManager.Get(label, returnNull: true) ?? label;
Label = label;
OnSelected = onSelected;
IsEnabled = isEnabled;
SubOptions = null;
@@ -49,14 +56,14 @@ namespace Barotrauma
/// <param name="header">Header text</param>
/// <param name="style">Background style</param>
/// <param name="options">list of context menu options</param>
public GUIContextMenu(Vector2? position, string header, string style, params ContextMenuOption[] options) : base(style, new RectTransform(Point.Zero, GUI.Canvas))
public GUIContextMenu(Vector2? position, LocalizedString 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
GUIFont headerFont = GUIStyle.SubHeadingFont;
GUIFont font = GUIStyle.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);
bool hasHeader = !header.IsNullOrWhiteSpace();
//----------------------------------------------------------------------------------
// Estimate the size of the context menu
@@ -111,7 +118,7 @@ namespace Barotrauma
};
Options.Add(option, optionElement);
if (!string.IsNullOrWhiteSpace(option.Tooltip) && optionElement.Enabled)
if (!option.Tooltip.IsNullOrWhiteSpace() && optionElement.Enabled)
{
optionElement.ToolTip = option.Tooltip;
}
@@ -179,7 +186,7 @@ namespace Barotrauma
public static GUIContextMenu CreateContextMenu(params ContextMenuOption[] options) => CreateContextMenu(PlayerInput.MousePosition, string.Empty, null, options);
public static GUIContextMenu CreateContextMenu(Vector2? pos, string header, Color? headerColor, params ContextMenuOption[] options)
public static GUIContextMenu CreateContextMenu(Vector2? pos, LocalizedString header, Color? headerColor, params ContextMenuOption[] options)
{
GUIContextMenu menu = new GUIContextMenu(pos,header, "GUIToolTip", options);
if (headerColor != null)
@@ -209,7 +216,7 @@ namespace Barotrauma
/// <param name="label">String whose size to inflate by</param>
/// <param name="font">What font to use</param>
/// <returns>The size of the text</returns>
private Vector2 InflateSize(ref Point size, string label, ScalableFont font)
private Vector2 InflateSize(ref Point size, LocalizedString label, ScalableFont font)
{
Vector2 textSize = font.MeasureString(label);
size.X = Math.Max((int) Math.Ceiling(textSize.X), size.X);
@@ -55,9 +55,8 @@ namespace Barotrauma
{
get { return listBox.SelectedComponent; }
}
// TODO: fix implicit hiding
public bool Selected
public override bool Selected
{
get
{
@@ -97,7 +96,7 @@ namespace Barotrauma
set { button.TextColor = value; }
}
public override ScalableFont Font
public override GUIFont Font
{
get { return button?.Font ?? base.Font; }
set
@@ -142,13 +141,13 @@ namespace Barotrauma
get { return selectedIndexMultiple; }
}
public string Text
public LocalizedString Text
{
get { return button.Text; }
set { button.Text = value; }
}
public override string ToolTip
public override RichString ToolTip
{
get
{
@@ -162,8 +161,10 @@ namespace Barotrauma
}
}
public GUIDropDown(RectTransform rectT, string text = "", int elementCount = 4, string style = "", bool selectMultiple = false, bool dropAbove = false) : base(style, rectT)
public GUIDropDown(RectTransform rectT, LocalizedString text = null, int elementCount = 4, string style = "", bool selectMultiple = false, bool dropAbove = false) : base(style, rectT)
{
text ??= new RawLString("");
HoverCursor = CursorState.Hand;
CanBeFocused = true;
@@ -173,7 +174,7 @@ namespace Barotrauma
{
OnClicked = OnClicked
};
GUI.Style.Apply(button, "", this);
GUIStyle.Apply(button, "", this);
button.TextBlock.SetTextPos();
Anchor listAnchor = dropAbove ? Anchor.TopCenter : Anchor.BottomCenter;
@@ -184,13 +185,13 @@ namespace Barotrauma
Enabled = !selectMultiple
};
if (!selectMultiple) { listBox.OnSelected = SelectItem; }
GUI.Style.Apply(listBox, "GUIListBox", this);
GUI.Style.Apply(listBox.ContentBackground, "GUIListBox", this);
GUIStyle.Apply(listBox, "GUIListBox", this);
GUIStyle.Apply(listBox.ContentBackground, "GUIListBox", this);
if (button.Style.ChildStyles.ContainsKey("dropdownicon"))
if (button.Style.ChildStyles.ContainsKey("dropdownicon".ToIdentifier()))
{
icon = new GUIImage(new RectTransform(new Vector2(0.6f, 0.6f), button.RectTransform, Anchor.CenterRight, scaleBasis: ScaleBasis.BothHeight) { AbsoluteOffset = new Point(5, 0) }, null, scaleToFit: true);
icon.ApplyStyle(button.Style.ChildStyles["dropdownicon"]);
icon.ApplyStyle(button.Style.ChildStyles["dropdownicon".ToIdentifier()]);
}
currentHighestParent = FindHighestParent();
@@ -244,8 +245,9 @@ namespace Barotrauma
return parentHierarchy.Last();
}
public void AddItem(string text, object userData = null, string toolTip = "")
public void AddItem(LocalizedString text, object userData = null, LocalizedString toolTip = null)
{
toolTip ??= "";
if (selectMultiple)
{
var frame = new GUIFrame(new RectTransform(new Point(button.Rect.Width, button.Rect.Height), listBox.Content.RectTransform)
@@ -261,7 +263,7 @@ namespace Barotrauma
ToolTip = toolTip,
OnSelected = (GUITickBox tb) =>
{
List<string> texts = new List<string>();
List<LocalizedString> texts = new List<LocalizedString>();
selectedDataMultiple.Clear();
selectedIndexMultiple.Clear();
int i = 0;
@@ -276,7 +278,7 @@ namespace Barotrauma
}
i++;
}
button.Text = string.Join(", ", texts);
button.Text = LocalizedString.Join(", ", texts);
// TODO: The callback is called at least twice, remove this?
OnSelected?.Invoke(tb.Parent, tb.Parent.UserData);
return true;
@@ -368,8 +370,9 @@ namespace Barotrauma
Dropped = !Dropped;
if (Dropped && Enabled)
{
OnDropped?.Invoke(this, userData);
OnDropped?.Invoke(this, UserData);
listBox.UpdateScrollBarSize();
listBox.UpdateDimensions();
GUI.KeyboardDispatcher.Subscriber = this;
}
@@ -177,6 +177,7 @@ namespace Barotrauma
spriteBatch.Begin(blendState: BlendState, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
}
var style = Style;
if (style != null)
{
foreach (UISprite uiSprite in style.Sprites[State])
@@ -193,7 +194,7 @@ namespace Barotrauma
}
}
}
else if (sprite?.Texture != null)
else if (sprite?.Texture is { IsDisposed: false })
{
spriteBatch.Draw(sprite.Texture, Rect.Center.ToVector2(), sourceRect, currentColor * (currentColor.A / 255.0f), Rotation, origin,
Scale, SpriteEffects, 0.0f);
@@ -92,29 +92,19 @@ namespace Barotrauma
foreach (RectTransform child in RectTransform.Children)
{
if (child.GUIComponent.IgnoreLayoutGroups) { continue; }
if (child.ScaleBasis == ScaleBasis.BothHeight) { child.MinSize = new Point(child.Rect.Height, child.MinSize.Y); }
if (child.ScaleBasis == ScaleBasis.BothWidth) { child.MinSize = new Point(child.MinSize.X, child.Rect.Width); }
if (child.ScaleBasis == ScaleBasis.Smallest)
switch (child.ScaleBasis)
{
if (Rect.Width < Rect.Height)
{
child.MinSize = new Point(child.MinSize.X, child.Rect.Width);
}
else
{
child.MinSize = new Point(child.Rect.Height, child.MinSize.Y);
}
}
if (child.ScaleBasis == ScaleBasis.Largest)
{
if (Rect.Width > Rect.Height)
{
child.MinSize = new Point(child.MinSize.X, child.Rect.Width);
}
else
{
child.MinSize = new Point(child.Rect.Height, child.MinSize.Y);
}
case ScaleBasis.BothHeight:
case ScaleBasis.Smallest when Rect.Height <= Rect.Width:
case ScaleBasis.Largest when Rect.Height > Rect.Width:
child.MinSize = new Point((int)((child.Rect.Height * child.RelativeSize.X) / child.RelativeSize.Y), child.MinSize.Y);
break;
case ScaleBasis.BothWidth:
case ScaleBasis.Smallest when Rect.Width <= Rect.Height:
case ScaleBasis.Largest when Rect.Width > Rect.Height:
child.MinSize = new Point(child.MinSize.X, (int)((child.Rect.Width * child.RelativeSize.Y) / child.RelativeSize.X));
break;
}
}
@@ -144,42 +134,65 @@ namespace Barotrauma
foreach (var child in RectTransform.Children)
{
if (child.GUIComponent.IgnoreLayoutGroups) { continue; }
float currentStretchFactor = child.ScaleBasis == ScaleBasis.Normal ? stretchFactor : 1.0f;
child.SetPosition(childAnchor);
void advancePositionsAndCalculateChildSizes(
ref int childNonScaledSize,
ref float childRelativeSize,
int childMinSize,
int childMaxSize,
int childRectSize,
int selfRectSize)
{
if (child.IsFixedSize)
{
absPos += childNonScaledSize + absoluteSpacing;
}
else
{
absPos += (int)Math.Round(MathHelper.Clamp(childRectSize * currentStretchFactor, childMinSize, childMaxSize) + (absoluteSpacing * currentStretchFactor));
if (stretch)
{
float relativeSize =
MathF.Round(childRelativeSize * currentStretchFactor * selfRectSize) / selfRectSize;
childRelativeSize = relativeSize;
}
}
}
Point childNonScaledSize = child.NonScaledSize;
Vector2 childRelativeSize = child.RelativeSize;
if (isHorizontal)
{
child.RelativeOffset = new Vector2(relPos, child.RelativeOffset.Y);
child.AbsoluteOffset = new Point(absPos, child.AbsoluteOffset.Y);
if (child.IsFixedSize)
{
absPos += child.NonScaledSize.X + absoluteSpacing;
}
else
{
absPos += (int)(MathHelper.Clamp(child.Rect.Width * stretchFactor, child.MinSize.X, child.MaxSize.X) + (absoluteSpacing * stretchFactor));
if (stretch)
{
child.RelativeSize = new Vector2(child.RelativeSize.X * stretchFactor, child.RelativeSize.Y);
}
}
advancePositionsAndCalculateChildSizes(
ref childNonScaledSize.X,
ref childRelativeSize.X,
child.MinSize.X,
child.MaxSize.X,
child.Rect.Width,
Rect.Width);
}
else
{
child.RelativeOffset = new Vector2(child.RelativeOffset.X, relPos);
child.AbsoluteOffset = new Point(child.AbsoluteOffset.X, absPos);
if (child.IsFixedSize)
{
absPos += child.NonScaledSize.Y + absoluteSpacing;
}
else
{
absPos += (int)(MathHelper.Clamp(child.Rect.Height * stretchFactor, child.MinSize.Y, child.MaxSize.Y) + (absoluteSpacing * stretchFactor));
if (stretch)
{
child.RelativeSize = new Vector2(child.RelativeSize.X, child.RelativeSize.Y * stretchFactor);
}
}
advancePositionsAndCalculateChildSizes(
ref childNonScaledSize.Y,
ref childRelativeSize.Y,
child.MinSize.Y,
child.MaxSize.Y,
child.Rect.Height,
Rect.Height);
}
child.NonScaledSize = childNonScaledSize;
child.RelativeSize = childRelativeSize;
relPos += relativeSpacing * stretchFactor;
if (isHorizontal) { relPos = MathF.Round(relPos * Rect.Width) / Rect.Width; }
else { relPos = MathF.Round(relPos * Rect.Height) / Rect.Height; }
}
needsToRecalculate = false;
}
@@ -148,7 +148,11 @@ namespace Barotrauma
}
// TODO: fix implicit hiding
public bool Selected { get; set; }
public override bool Selected
{
get { return isSelected; }
set { isSelected = value; }
}
public IReadOnlyList<GUIComponent> AllSelected => selected;
@@ -328,7 +332,7 @@ namespace Barotrauma
};
if (style != null)
{
GUI.Style.Apply(ContentBackground, "", this);
GUIStyle.Apply(ContentBackground, "", this);
}
if (color.HasValue)
{
@@ -435,7 +439,7 @@ namespace Barotrauma
Vector2 topOffset = CalculateTopOffset();
int x = (int)topOffset.X;
int y = (int)topOffset.Y;
for (int i = 0; i < Content.CountChildren; i++)
{
GUIComponent child = Content.GetChild(i);
@@ -10,7 +10,8 @@ namespace Barotrauma
{
public class GUIMessageBox : GUIFrame
{
public static List<GUIComponent> MessageBoxes = new List<GUIComponent>();
#warning TODO: change this to List<GUIMessageBox> and fix incorrect uses of this list
public readonly static List<GUIComponent> MessageBoxes = new List<GUIComponent>();
private static int DefaultWidth
{
get { return Math.Max(400, (int)(400 * (GameMain.GraphicsWidth / GUI.ReferenceResolution.X))); }
@@ -70,14 +71,14 @@ namespace Barotrauma
public static GUIComponent VisibleBox => MessageBoxes.LastOrDefault();
public GUIMessageBox(string headerText, string text, Vector2? relativeSize = null, Point? minSize = null)
: this(headerText, text, new string[] { "OK" }, relativeSize, minSize)
public GUIMessageBox(LocalizedString headerText, LocalizedString text, Vector2? relativeSize = null, Point? minSize = null)
: this(headerText, text, new LocalizedString[] { "OK" }, relativeSize, minSize)
{
this.Buttons[0].OnClicked = Close;
}
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, bool parseRichText = false)
: base(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas, Anchor.Center), style: GUI.Style.GetComponentStyle("GUIMessageBox." + type) != null ? "GUIMessageBox." + type : "GUIMessageBox")
public GUIMessageBox(RichString headerText, RichString text, LocalizedString[] 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: GUIStyle.GetComponentStyle("GUIMessageBox." + type) != null ? "GUIMessageBox." + type : "GUIMessageBox")
{
int width = (int)(DefaultWidth * type switch
{
@@ -125,23 +126,24 @@ namespace Barotrauma
InnerFrame.RectTransform.ScreenSpaceOffset = new Point(-offset, offset);
CanBeFocused = false;
}
GUI.Style.Apply(InnerFrame, "", this);
GUIStyle.Apply(InnerFrame, "", this);
this.type = type;
Tag = tag;
#warning TODO: These should be broken into separate methods at least
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, parseRichText: parseRichText);
GUI.Style.Apply(Header, "", this);
headerText, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Center, wrap: true);
GUIStyle.Apply(Header, "", this);
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
if (!string.IsNullOrWhiteSpace(text))
if (!text.IsNullOrWhiteSpace())
{
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true, parseRichText: parseRichText);
GUI.Style.Apply(Text, "", this);
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true);
GUIStyle.Apply(Text, "", this);
Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
new Point(Text.Rect.Width, Text.Rect.Height);
Text.RectTransform.IsFixedSize = true;
@@ -154,7 +156,7 @@ namespace Barotrauma
};
int buttonSize = 35;
var buttonStyle = GUI.Style.GetComponentStyle("GUIButton");
var buttonStyle = GUIStyle.GetComponentStyle("GUIButton");
if (buttonStyle != null && buttonStyle.Height.HasValue)
{
buttonSize = buttonStyle.Height.Value;
@@ -189,7 +191,7 @@ namespace Barotrauma
InnerFrame.RectTransform.AbsoluteOffset = new Point(0, GameMain.GraphicsHeight);
CanBeFocused = false;
AutoClose = true;
GUI.Style.Apply(InnerFrame, "", this);
GUIStyle.Apply(InnerFrame, "", this);
var horizontalLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.98f, 0.95f), InnerFrame.RectTransform, Anchor.Center),
isHorizontal: true, childAnchor: Anchor.CenterLeft)
@@ -219,11 +221,11 @@ namespace Barotrauma
};
InputType? closeInput = null;
if (GameMain.Config.KeyBind(InputType.Use).MouseButton == MouseButton.None)
if (GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Use].MouseButton == MouseButton.None)
{
closeInput = InputType.Use;
}
else if (GameMain.Config.KeyBind(InputType.Select).MouseButton == MouseButton.None)
else if (GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Select].MouseButton == MouseButton.None)
{
closeInput = InputType.Select;
}
@@ -236,24 +238,24 @@ namespace Barotrauma
{
GUIButton btn = component as GUIButton;
btn?.OnClicked(btn, btn.UserData);
btn?.Flash(GUI.Style.Green);
btn?.Flash(GUIStyle.Green);
}
};
}
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), headerText, wrap: true, parseRichText: parseRichText);
GUI.Style.Apply(Header, "", this);
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), headerText, wrap: true);
GUIStyle.Apply(Header, "", this);
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
if (!string.IsNullOrWhiteSpace(text))
if (!text.IsNullOrWhiteSpace())
{
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true, parseRichText: parseRichText);
GUI.Style.Apply(Text, "", this);
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true);
GUIStyle.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))
if (headerText.IsNullOrWhiteSpace())
{
Content.ChildAnchor = Anchor.Center;
}
@@ -275,7 +277,7 @@ namespace Barotrauma
else if (type == Type.Hint)
{
CanBeFocused = false;
GUI.Style.Apply(InnerFrame, "", this);
GUIStyle.Apply(InnerFrame, "", this);
Point absoluteSpacing = GUIStyle.ItemFrameMargin.Multiply(1.0f / 5.0f);
var verticalLayoutGroup = new GUILayoutGroup(new RectTransform(GetVerticalLayoutGroupSize(), parent: InnerFrame.RectTransform, anchor: Anchor.Center), childAnchor: Anchor.TopCenter)
@@ -353,18 +355,18 @@ namespace Barotrauma
};
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), headerText, wrap: true);
GUI.Style.Apply(Header, "", this);
GUIStyle.Apply(Header, "", this);
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
if (!string.IsNullOrWhiteSpace(text))
if (!text.IsNullOrWhiteSpace())
{
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true);
GUI.Style.Apply(Text, "", this);
GUIStyle.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))
if (headerText.IsNullOrWhiteSpace())
{
Header.RectTransform.Parent = null;
Content.ChildAnchor = Anchor.Center;
@@ -410,7 +412,7 @@ namespace Barotrauma
/// <summary>
/// Use to create a message box of Hint type
/// </summary>
public GUIMessageBox(string hintIdentifier, string text, Sprite icon) : this("", text, new string[0], textAlignment: Alignment.CenterLeft, type: Type.Hint, icon: icon)
public GUIMessageBox(Identifier hintIdentifier, LocalizedString text, Sprite icon) : this("", text, Array.Empty<LocalizedString>(), textAlignment: Alignment.CenterLeft, type: Type.Hint, icon: icon)
{
if (InnerFrame.FindChild("dontshowagain", recursive: true) is GUITickBox dontShowAgainTickBox)
{
@@ -162,7 +162,7 @@ namespace Barotrauma
}
}
public override ScalableFont Font
public override GUIFont Font
{
get
{
@@ -225,7 +225,7 @@ namespace Barotrauma
var buttonArea = new GUIFrame(new RectTransform(new Vector2(_relativeButtonAreaWidth, 1.0f), LayoutGroup.RectTransform, Anchor.CenterRight), style: null);
PlusButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.5f), buttonArea.RectTransform), style: null);
GUI.Style.Apply(PlusButton, "PlusButton", this);
GUIStyle.Apply(PlusButton, "PlusButton", this);
PlusButton.OnButtonDown += () =>
{
pressedTimer = pressedDelay;
@@ -246,7 +246,7 @@ namespace Barotrauma
};
MinusButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.5f), buttonArea.RectTransform, Anchor.BottomRight), style: null);
GUI.Style.Apply(MinusButton, "MinusButton", this);
GUIStyle.Apply(MinusButton, "MinusButton", this);
MinusButton.OnButtonDown += () =>
{
pressedTimer = pressedDelay;
@@ -0,0 +1,395 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Barotrauma
{
public abstract class GUIPrefab : Prefab
{
public GUIPrefab(ContentXElement element, UIStyleFile file) : base(file, element) { }
protected override Identifier DetermineIdentifier(XElement element)
{
return element.NameAsIdentifier();
}
}
public abstract class GUISelector<T> where T : GUIPrefab
{
public readonly PrefabSelector<T> Prefabs = new PrefabSelector<T>();
public readonly Identifier Identifier;
public GUISelector(string identifier)
{
Identifier = identifier.ToIdentifier();
}
}
public class GUIFontPrefab : GUIPrefab
{
private readonly ContentXElement element;
private ScalableFont font;
public ScalableFont Font
{
get
{
if (Language != GameSettings.CurrentConfig.Language) { LoadFont(); }
return font;
}
}
private ScalableFont cjkFont;
public ScalableFont CjkFont
{
get
{
if (Language != GameSettings.CurrentConfig.Language) { LoadFont(); }
if (font.IsCJK) { return font; }
return cjkFont;
}
}
public LanguageIdentifier Language { get; private set; }
public GUIFontPrefab(ContentXElement element, UIStyleFile file) : base(element, file)
{
this.element = element;
LoadFont();
}
private void LoadFont()
{
string fontPath = GetFontFilePath(element);
uint size = GetFontSize(element);
bool dynamicLoading = GetFontDynamicLoading(element);
bool isCJK = GetIsCJK(element);
font?.Dispose();
cjkFont?.Dispose();
font = new ScalableFont(fontPath, size, GameMain.Instance.GraphicsDevice, dynamicLoading, isCJK)
{
ForceUpperCase = element.GetAttributeBool("forceuppercase", false)
};
if (!isCJK)
{
cjkFont = ExtractCjkFont(element)
?? new ScalableFont("Content/Fonts/NotoSans/NotoSansCJKsc-Bold.otf",
font.Size, GameMain.Instance.GraphicsDevice, dynamicLoading: true, isCJK: true);
cjkFont.ForceUpperCase = font.ForceUpperCase;
}
Language = GameSettings.CurrentConfig.Language;
}
public override void Dispose()
{
font?.Dispose(); font = null;
cjkFont?.Dispose(); cjkFont = null;
}
private ScalableFont ExtractCjkFont(ContentXElement element)
{
foreach (var subElement in element.Elements().Reverse())
{
if (subElement.NameAsIdentifier() != "override") { continue; }
if (subElement.GetAttributeBool("iscjk", false))
{
return new ScalableFont(subElement, GameMain.Instance.GraphicsDevice);
}
}
return null;
}
private string GetFontFilePath(ContentXElement element)
{
foreach (var subElement in element.Elements())
{
if (!subElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase)) { continue; }
if (GameSettings.CurrentConfig.Language == subElement.GetAttributeIdentifier("language", "").ToLanguageIdentifier())
{
return subElement.GetAttributeContentPath("file")?.Value;
}
}
return element.GetAttributeContentPath("file")?.Value;
}
private uint GetFontSize(XElement element, uint defaultSize = 14)
{
//check if any of the language override fonts want to override the font size as well
foreach (var subElement in element.Elements())
{
if (!subElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase)) { continue; }
if (GameSettings.CurrentConfig.Language == subElement.GetAttributeIdentifier("language", "").ToLanguageIdentifier())
{
uint overrideFontSize = GetFontSize(subElement, 0);
if (overrideFontSize > 0) { return (uint)Math.Round(overrideFontSize * GameSettings.CurrentConfig.Graphics.TextScale); }
}
}
foreach (var subElement in element.Elements())
{
if (!subElement.Name.ToString().Equals("size", StringComparison.OrdinalIgnoreCase)) { continue; }
Point maxResolution = subElement.GetAttributePoint("maxresolution", new Point(int.MaxValue, int.MaxValue));
if (GameMain.GraphicsWidth <= maxResolution.X && GameMain.GraphicsHeight <= maxResolution.Y)
{
return (uint)Math.Round(subElement.GetAttributeInt("size", 14) * GameSettings.CurrentConfig.Graphics.TextScale);
}
}
return (uint)Math.Round(defaultSize * GameSettings.CurrentConfig.Graphics.TextScale);
}
private bool GetFontDynamicLoading(XElement element)
{
foreach (var subElement in element.Elements())
{
if (!subElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase)) { continue; }
if (GameSettings.CurrentConfig.Language == subElement.GetAttributeIdentifier("language", "").ToLanguageIdentifier())
{
return subElement.GetAttributeBool("dynamicloading", false);
}
}
return element.GetAttributeBool("dynamicloading", false);
}
private bool GetIsCJK(XElement element)
{
foreach (var subElement in element.Elements())
{
if (!subElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase)) { continue; }
if (GameSettings.CurrentConfig.Language == subElement.GetAttributeIdentifier("language", "").ToLanguageIdentifier())
{
return subElement.GetAttributeBool("iscjk", false);
}
}
return element.GetAttributeBool("iscjk", false);
}
}
public class GUIFont : GUISelector<GUIFontPrefab>
{
public GUIFont(string identifier) : base(identifier) { }
public bool HasValue => Prefabs.Any();
public ScalableFont Value => Prefabs.ActivePrefab.Font;
public static implicit operator ScalableFont(GUIFont reference) => reference.Value;
public bool ForceUpperCase => HasValue && Value.ForceUpperCase;
public uint Size => HasValue ? Value.Size : 0;
private ScalableFont GetFontForStr(LocalizedString str) => GetFontForStr(str.Value);
private ScalableFont GetFontForStr(string str) =>
TextManager.IsCJK(str) ? Prefabs.ActivePrefab.CjkFont : Prefabs.ActivePrefab.Font;
public void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects se, float layerDepth)
{
DrawString(sb, text.Value, position, color, rotation, origin, scale, se, layerDepth);
}
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects se, float layerDepth)
{
GetFontForStr(text).DrawString(sb, text, position, color, rotation, origin, scale, se, layerDepth);
}
public void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects se, float layerDepth, Alignment alignment = Alignment.TopLeft)
{
DrawString(sb, text.Value, position, color, rotation, origin, scale, se, layerDepth, alignment);
}
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects se, float layerDepth, Alignment alignment = Alignment.TopLeft, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit)
{
GetFontForStr(text).DrawString(sb, text, position, color, rotation, origin, scale, se, layerDepth, alignment, forceUpperCase);
}
public void DrawString(SpriteBatch sb, LocalizedString text, Vector2 position, Color color, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit, bool italics = false)
{
DrawString(sb, text.Value, position, color, forceUpperCase, italics);
}
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit, bool italics = false)
{
GetFontForStr(text).DrawString(sb, text, position, color, forceUpperCase, italics);
}
public void DrawStringWithColors(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects se, float layerDepth, in ImmutableArray<RichTextData>? richTextData, int rtdOffset = 0, Alignment alignment = Alignment.TopLeft, ForceUpperCase forceUpperCase = Barotrauma.ForceUpperCase.Inherit)
{
GetFontForStr(text).DrawStringWithColors(sb, text, position, color, rotation, origin, scale, se, layerDepth, richTextData, rtdOffset, alignment, forceUpperCase);
}
public Vector2 MeasureString(LocalizedString str, bool removeExtraSpacing = false)
{
return GetFontForStr(str).MeasureString(str, removeExtraSpacing);
}
public Vector2 MeasureChar(char c)
{
return GetFontForStr($"{c}").MeasureChar(c);
}
public string WrapText(string text, float width)
=> GetFontForStr(text).WrapText(text, width);
public string WrapText(string text, float width, int requestCharPos, out Vector2 requestedCharPos)
=> GetFontForStr(text).WrapText(text, width, requestCharPos, out requestedCharPos);
public string WrapText(string text, float width, out Vector2[] allCharPositions)
=> GetFontForStr(text).WrapText(text, width, out allCharPositions);
public float LineHeight => Value.LineHeight;
}
public class GUIColorPrefab : GUIPrefab
{
public readonly Color Color;
public GUIColorPrefab(ContentXElement element, UIStyleFile file) : base(element, file)
{
Color = element.GetAttributeColor("color", Color.White);
}
public override void Dispose() { }
}
public class GUIColor : GUISelector<GUIColorPrefab>
{
public GUIColor(string identifier) : base(identifier) { }
public Color Value
{
get
{
return Prefabs.ActivePrefab.Color;
}
}
public static implicit operator Color(GUIColor reference) => reference.Value;
public static Color operator*(GUIColor value, float scale)
{
return value.Value * scale;
}
}
public class GUISpritePrefab : GUIPrefab
{
public readonly UISprite Sprite;
public GUISpritePrefab(ContentXElement element, UIStyleFile file) : base(element, file)
{
Sprite = new UISprite(element);
}
public override void Dispose()
{
Sprite.Sprite.Remove();
}
}
public class GUISprite : GUISelector<GUISpritePrefab>
{
public GUISprite(string identifier) : base(identifier) { }
public UISprite Value
{
get
{
return Prefabs.ActivePrefab.Sprite;
}
}
public static implicit operator UISprite(GUISprite reference) => reference.Value;
public void Draw(SpriteBatch spriteBatch, Rectangle rect, Color color, SpriteEffects spriteEffects = SpriteEffects.None)
{
Value.Draw(spriteBatch, rect, color, spriteEffects);
}
}
public class GUISpriteSheetPrefab : GUIPrefab
{
public readonly SpriteSheet SpriteSheet;
public GUISpriteSheetPrefab(ContentXElement element, UIStyleFile file) : base(element, file)
{
SpriteSheet = new SpriteSheet(element);
}
public override void Dispose()
{
SpriteSheet.Remove();
}
}
public class GUISpriteSheet : GUISelector<GUISpriteSheetPrefab>
{
public GUISpriteSheet(string identifier) : base(identifier) { }
public SpriteSheet Value
{
get
{
return Prefabs.ActivePrefab.SpriteSheet;
}
}
public int FrameCount => Value.FrameCount;
public Point FrameSize => Value.FrameSize;
public void Draw(ISpriteBatch spriteBatch, Vector2 pos, float rotate = 0, float scale = 1, SpriteEffects spriteEffects = SpriteEffects.None)
{
Value.Draw(spriteBatch, pos, rotate, scale, spriteEffects);
}
public void Draw(ISpriteBatch spriteBatch, Vector2 pos, Color color, Vector2 origin, float rotate = 0, float scale = 1, SpriteEffects spriteEffects = SpriteEffects.None, float? depth = null)
{
Value.Draw(spriteBatch, pos, color, origin, rotate, scale, spriteEffects, depth);
}
public void Draw(ISpriteBatch spriteBatch, int spriteIndex, Vector2 pos, Color color, Vector2 origin, float rotate, Vector2 scale, SpriteEffects spriteEffects = SpriteEffects.None, float? depth = null)
{
Value.Draw(spriteBatch, spriteIndex, pos, color, origin, rotate, scale, spriteEffects, depth);
}
public static implicit operator SpriteSheet(GUISpriteSheet reference) => reference.Value;
}
public class GUICursorPrefab : GUIPrefab
{
public readonly Sprite[] Sprites;
public GUICursorPrefab(ContentXElement element, UIStyleFile file) : base(element, file)
{
Sprites = new Sprite[Enum.GetValues(typeof(CursorState)).Length];
foreach (var subElement in element.Elements())
{
CursorState state = subElement.GetAttributeEnum("state", CursorState.Default);
Sprites[(int)state] = new Sprite(subElement);
}
}
public override void Dispose()
{
foreach (var sprite in Sprites)
{
sprite?.Remove();
}
}
}
public class GUICursor : GUISelector<GUICursorPrefab>
{
public GUICursor(string identifier) : base(identifier) { }
public Sprite this[CursorState k] => Prefabs.ActivePrefab.Sprites[(int)k];
}
}
@@ -47,9 +47,9 @@ namespace Barotrauma
}
isHorizontal = (Rect.Width > Rect.Height);
frame = new GUIFrame(new RectTransform(Vector2.One, rectT));
GUI.Style.Apply(frame, "", this);
GUIStyle.Apply(frame, "", this);
slider = new GUIFrame(new RectTransform(Vector2.One, rectT));
GUI.Style.Apply(slider, "Slider", this);
GUIStyle.Apply(slider, "Slider", this);
this.showFrame = showFrame;
this.barSize = barSize;
Enabled = true;
@@ -62,10 +62,10 @@ namespace Barotrauma
public Rectangle GetSliderRect(float fillAmount)
{
Rectangle sliderArea = new Rectangle(
frame.Rect.X + (int)style.Padding.X,
frame.Rect.Y + (int)style.Padding.Y,
(int)(frame.Rect.Width - style.Padding.X - style.Padding.Z),
(int)(frame.Rect.Height - style.Padding.Y - style.Padding.W));
frame.Rect.X + (int)Style.Padding.X,
frame.Rect.Y + (int)Style.Padding.Y,
(int)(frame.Rect.Width - Style.Padding.X - Style.Padding.Z),
(int)(frame.Rect.Height - Style.Padding.Y - Style.Padding.W));
Vector4 sliceBorderSizes = Vector4.Zero;
if (slider.sprites.ContainsKey(slider.State) && (slider.sprites[slider.State].First()?.Slice ?? false))
@@ -116,10 +116,10 @@ namespace Barotrauma
var sliderRect = GetSliderRect(barSize);
slider.RectTransform.AbsoluteOffset = new Point((int)style.Padding.X, (int)style.Padding.Y);
slider.RectTransform.AbsoluteOffset = new Point((int)Style.Padding.X, (int)Style.Padding.Y);
slider.RectTransform.MaxSize = new Point(
(int)(Rect.Width - style.Padding.X + style.Padding.Z),
(int)(Rect.Height - style.Padding.Y + style.Padding.W));
(int)(Rect.Width - Style.Padding.X + Style.Padding.Z),
(int)(Rect.Height - Style.Padding.Y + Style.Padding.W));
frame.Visible = showFrame;
slider.Visible = BarSize > 0.0f;
@@ -1,6 +1,5 @@
using Barotrauma.Extensions;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
namespace Barotrauma
@@ -29,7 +28,7 @@ namespace Barotrauma
public bool IsBooleanSwitch;
public override string ToolTip
public override RichString ToolTip
{
get { return base.ToolTip; }
set
@@ -203,7 +202,7 @@ namespace Barotrauma
CanBeFocused = true;
this.isHorizontal = isHorizontal ?? (Rect.Width > Rect.Height);
Frame = new GUIFrame(new RectTransform(Vector2.One, rectT));
GUI.Style.Apply(Frame, IsHorizontal ? "GUIFrameHorizontal" : "GUIFrameVertical", this);
GUIStyle.Apply(Frame, IsHorizontal ? "GUIFrameHorizontal" : "GUIFrameVertical", this);
this.barSize = barSize;
Bar = new GUIButton(new RectTransform(Vector2.One, rectT, IsHorizontal ? Anchor.CenterLeft : Anchor.TopCenter), color: color, style: null);
@@ -224,7 +223,7 @@ namespace Barotrauma
break;
}
GUI.Style.Apply(Bar, IsHorizontal ? "GUIButtonHorizontal" : "GUIButtonVertical", this);
GUIStyle.Apply(Bar, IsHorizontal ? "GUIButtonHorizontal" : "GUIButtonVertical", this);
Bar.OnPressed = SelectBar;
enabled = true;
UpdateRect();
@@ -1,523 +1,195 @@
using Barotrauma.Extensions;
using System;
using Barotrauma.Extensions;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
namespace Barotrauma
{
public class GUIStyle
public static class GUIStyle
{
private Dictionary<string, GUIComponentStyle> componentStyles;
private readonly XElement configElement;
private GraphicsDevice graphicsDevice;
private ScalableFont defaultFont;
public ScalableFont Font { get; private set; }
public ScalableFont GlobalFont { get; private set; }
public ScalableFont UnscaledSmallFont { get; private set; }
public ScalableFont SmallFont { get; private set; }
public ScalableFont LargeFont { get; private set; }
public ScalableFont SubHeadingFont { get; private set; }
public ScalableFont DigitalFont { get; private set; }
public ScalableFont HotkeyFont { get; private set; }
public ScalableFont MonospacedFont { get; private set; }
public Dictionary<ScalableFont, bool> ForceFontUpperCase
public readonly static ImmutableDictionary<Identifier, GUIFont> Fonts;
public readonly static ImmutableDictionary<Identifier, GUISprite> Sprites;
public readonly static ImmutableDictionary<Identifier, GUISpriteSheet> SpriteSheets;
public readonly static ImmutableDictionary<Identifier, GUIColor> Colors;
static GUIStyle()
{
get;
private set;
} = new Dictionary<ScalableFont, bool>();
var guiClassProperties = typeof(GUIStyle).GetFields(BindingFlags.Public | BindingFlags.Static);
public readonly Sprite[] CursorSprite = new Sprite[7];
ImmutableDictionary<Identifier, T> getPropertiesOfType<T>() where T : class
{
return guiClassProperties
.Where(p => p.FieldType == typeof(T))
.Select(p => (p.Name.ToIdentifier(), p.GetValue(null) as T))
.ToImmutableDictionary();
}
public UISprite RadiationSprite { get; private set; }
public SpriteSheet RadiationAnimSpriteSheet { get; private set; }
Fonts = getPropertiesOfType<GUIFont>();
Sprites = getPropertiesOfType<GUISprite>();
SpriteSheets = getPropertiesOfType<GUISpriteSheet>();
Colors = getPropertiesOfType<GUIColor>();
}
public SpriteSheet SavingIndicator { get; private set; }
public readonly static PrefabCollection<GUIComponentStyle> ComponentStyles = new PrefabCollection<GUIComponentStyle>();
public UISprite UIGlow { get; private set; }
public readonly static GUIFont Font = new GUIFont("Font");
public readonly static GUIFont GlobalFont = new GUIFont("GlobalFont");
public readonly static GUIFont UnscaledSmallFont = new GUIFont("UnscaledSmallFont");
public readonly static GUIFont SmallFont = new GUIFont("SmallFont");
public readonly static GUIFont LargeFont = new GUIFont("LargeFont");
public readonly static GUIFont SubHeadingFont = new GUIFont("SubHeadingFont");
public readonly static GUIFont DigitalFont = new GUIFont("DigitalFont");
public readonly static GUIFont HotkeyFont = new GUIFont("HotkeyFont");
public readonly static GUIFont MonospacedFont = new GUIFont("MonospacedFont");
public UISprite PingCircle { get; private set; }
public readonly static GUICursor CursorSprite = new GUICursor("Cursor");
public UISprite YouAreHereCircle { get; private set; }
public readonly static GUISprite SubmarineLocationIcon = new GUISprite("SubmarineLocationIcon");
public readonly static GUISprite Arrow = new GUISprite("Arrow");
public readonly static GUISprite SpeechBubbleIcon = new GUISprite("SpeechBubbleIcon");
public readonly static GUISprite BrokenIcon = new GUISprite("BrokenIcon");
public readonly static GUISprite YouAreHereCircle = new GUISprite("YouAreHereCircle");
public UISprite UIGlowCircular { get; private set; }
public readonly static GUISprite Radiation = new GUISprite("Radiation");
public readonly static GUISpriteSheet RadiationAnimSpriteSheet = new GUISpriteSheet("RadiationAnimSpriteSheet");
public UISprite UIGlowSolidCircular { get; private set; }
public UISprite UIThermalGlow { get; private set; }
public readonly static GUISpriteSheet SavingIndicator = new GUISpriteSheet("SavingIndicator");
public readonly static GUISpriteSheet GenericThrobber = new GUISpriteSheet("GenericThrobber");
public UISprite ButtonPulse { get; private set; }
public readonly static GUISprite UIGlow = new GUISprite("UIGlow");
public readonly static GUISprite TalentGlow = new GUISprite("TalentGlow");
public readonly static GUISprite PingCircle = new GUISprite("PingCircle");
public readonly static GUISprite UIGlowCircular = new GUISprite("UIGlowCircular");
public readonly static GUISprite UIGlowSolidCircular = new GUISprite("UIGlowSolidCircular");
public readonly static GUISprite UIThermalGlow = new GUISprite("UIGlowSolidCircular");
public readonly static GUISprite ButtonPulse = new GUISprite("ButtonPulse");
public SpriteSheet FocusIndicator { get; private set; }
public readonly static GUISprite EndRoundButtonPulse = new GUISprite("EndRoundButtonPulse");
public UISprite IconOverflowIndicator { get; private set; }
public readonly static GUISpriteSheet FocusIndicator = new GUISpriteSheet("FocusIndicator");
public readonly static GUISprite IconOverflowIndicator = new GUISprite("IconOverflowIndicator");
/// <summary>
/// General green color used for elements whose colors are set from code
/// </summary>
public Color Green { get; private set; } = Color.LightGreen;
public readonly static GUIColor Green = new GUIColor("Green");
/// <summary>
/// General red color used for elements whose colors are set from code
/// </summary>
public Color Orange { get; private set; } = Color.Orange;
public readonly static GUIColor Orange = new GUIColor("Orange");
/// <summary>
/// General red color used for elements whose colors are set from code
/// </summary>
public Color Red { get; private set; } = Color.Red;
public readonly static GUIColor Red = new GUIColor("Red");
/// <summary>
/// General blue color used for elements whose colors are set from code
/// </summary>
public Color Blue { get; private set; } = Color.Blue;
public readonly static GUIColor Blue = new GUIColor("Blue");
/// <summary>
/// General yellow color used for elements whose colors are set from code
/// </summary>
public Color Yellow { get; private set; } = Color.Yellow;
public readonly static GUIColor Yellow = new GUIColor("Yellow");
public Color ColorInventoryEmpty { get; private set; } = Color.Red;
public Color ColorInventoryHalf { get; private set; } = Color.Orange;
public Color ColorInventoryFull { get; private set; } = Color.LightGreen;
public Color ColorInventoryBackground { get; private set; } = Color.Gray;
public Color ColorInventoryEmptyOverlay { get; private set; } = Color.Red;
public readonly static GUIColor ColorInventoryEmpty = new GUIColor("ColorInventoryEmpty");
public readonly static GUIColor ColorInventoryHalf = new GUIColor("ColorInventoryHalf");
public readonly static GUIColor ColorInventoryFull = new GUIColor("ColorInventoryFull");
public readonly static GUIColor ColorInventoryBackground = new GUIColor("ColorInventoryBackground");
public readonly static GUIColor ColorInventoryEmptyOverlay = new GUIColor("ColorInventoryEmptyOverlay");
public Color TextColor { get; private set; } = Color.White * 0.8f;
public Color TextColorBright { get; private set; } = Color.White * 0.9f;
public Color TextColorDark { get; private set; } = Color.Black * 0.9f;
public Color TextColorDim { get; private set; } = Color.White * 0.6f;
public readonly static GUIColor TextColorNormal = new GUIColor("TextColorNormal");
public readonly static GUIColor TextColorBright = new GUIColor("TextColorBright");
public readonly static GUIColor TextColorDark = new GUIColor("TextColorDark");
public readonly static GUIColor TextColorDim = new GUIColor("TextColorDim");
public Color ItemQualityColorPoor { get; private set; } = Color.DarkRed;
public Color ItemQualityColorNormal { get; private set; } = Color.Gray;
public Color ItemQualityColorGood { get; private set; } = Color.LightGreen;
public Color ItemQualityColorExcellent { get; private set; } = Color.LightBlue;
public Color ItemQualityColorMasterwork { get; private set; } = Color.MediumPurple;
public Color ColorReputationVeryLow { get; private set; } = Color.Red;
public Color ColorReputationLow { get; private set; } = Color.Orange;
public Color ColorReputationNeutral { get; private set; } = Color.White * 0.8f;
public Color ColorReputationHigh { get; private set; } = Color.LightBlue;
public Color ColorReputationVeryHigh { get; private set; } = Color.Blue;
public readonly static GUIColor ItemQualityColorPoor = new GUIColor("ItemQualityColorPoor");
public readonly static GUIColor ItemQualityColorNormal = new GUIColor("ItemQualityColorNormal");
public readonly static GUIColor ItemQualityColorGood = new GUIColor("ItemQualityColorGood");
public readonly static GUIColor ItemQualityColorExcellent = new GUIColor("ItemQualityColorExcellent");
public readonly static GUIColor ItemQualityColorMasterwork = new GUIColor("ItemQualityColorMasterwork");
public readonly static GUIColor ColorReputationVeryLow = new GUIColor("ColorReputationVeryLow");
public readonly static GUIColor ColorReputationLow = new GUIColor("ColorReputationLow");
public readonly static GUIColor ColorReputationNeutral = new GUIColor("ColorReputationNeutral");
public readonly static GUIColor ColorReputationHigh = new GUIColor("ColorReputationHigh");
public readonly static GUIColor ColorReputationVeryHigh = new GUIColor("ColorReputationVeryHigh");
// Inventory
public Color EquipmentSlotIconColor { get; private set; } = new Color(99, 70, 64);
public readonly static GUIColor EquipmentSlotIconColor = new GUIColor("EquipmentSlotIconColor");
// Health HUD
public Color BuffColorLow { get; private set; } = Color.LightGreen;
public Color BuffColorMedium { get; private set; } = Color.Green;
public Color BuffColorHigh { get; private set; } = Color.DarkGreen;
public readonly static GUIColor BuffColorLow = new GUIColor("BuffColorLow");
public readonly static GUIColor BuffColorMedium = new GUIColor("BuffColorMedium");
public readonly static GUIColor BuffColorHigh = new GUIColor("BuffColorHigh");
public Color DebuffColorLow { get; private set; } = Color.DarkSalmon;
public Color DebuffColorMedium { get; private set; } = Color.Red;
public Color DebuffColorHigh { get; private set; } = Color.DarkRed;
public readonly static GUIColor DebuffColorLow = new GUIColor("DebuffColorLow");
public readonly static GUIColor DebuffColorMedium = new GUIColor("DebuffColorMedium");
public readonly static GUIColor DebuffColorHigh = new GUIColor("DebuffColorHigh");
public Color HealthBarColorLow { get; private set; } = Color.Red;
public Color HealthBarColorMedium { get; private set; } = Color.Orange;
public Color HealthBarColorHigh { get; private set; } = new Color(78, 114, 88);
public readonly static GUIColor HealthBarColorLow = new GUIColor("HealthBarColorLow");
public readonly static GUIColor HealthBarColorMedium = new GUIColor("HealthBarColorMedium");
public readonly static GUIColor HealthBarColorHigh = new GUIColor("HealthBarColorHigh");
public Color EquipmentIndicatorNotEquipped { get; private set; } = Color.Gray;
public Color EquipmentIndicatorEquipped { get; private set; } = new Color(105, 202, 125);
public Color EquipmentIndicatorRunningOut { get; private set; } = new Color(202, 105, 105);
public readonly static GUIColor EquipmentIndicatorNotEquipped = new GUIColor("EquipmentIndicatorNotEquipped");
public readonly static GUIColor EquipmentIndicatorEquipped = new GUIColor("EquipmentIndicatorEquipped");
public readonly static GUIColor EquipmentIndicatorRunningOut = new GUIColor("EquipmentIndicatorRunningOut");
public static Point ItemFrameMargin => new Point(50, 56).Multiply(GUI.SlicedSpriteScale);
public static Point ItemFrameOffset => new Point(0, 3).Multiply(GUI.SlicedSpriteScale);
public GUIStyle(XElement element, GraphicsDevice graphicsDevice)
public static GUIComponentStyle GetComponentStyle(string name)
=> ComponentStyles.ContainsKey(name) ? ComponentStyles[name] : null;
public static void Apply(GUIComponent targetComponent, string styleName = "", GUIComponent parent = null)
{
this.graphicsDevice = graphicsDevice;
componentStyles = new Dictionary<string, GUIComponentStyle>();
configElement = element;
foreach (XElement subElement in configElement.Elements())
{
var name = subElement.Name.ToString().ToLowerInvariant();
switch (name)
{
case "cursor":
if (subElement.HasElements)
{
foreach (var children in subElement.Descendants())
{
var index = children.GetAttributeInt("state", (int)CursorState.Default);
CursorSprite[index] = new Sprite(children);
}
}
else
{
CursorSprite[(int)CursorState.Default] = new Sprite(subElement);
}
break;
case "green":
Green = subElement.GetAttributeColor("color", Green);
break;
case "orange":
Orange = subElement.GetAttributeColor("color", Orange);
break;
case "red":
Red = subElement.GetAttributeColor("color", Red);
break;
case "blue":
Blue = subElement.GetAttributeColor("color", Blue);
break;
case "yellow":
Yellow = subElement.GetAttributeColor("color", Yellow);
break;
case "colorinventoryempty":
ColorInventoryEmpty = subElement.GetAttributeColor("color", ColorInventoryEmpty);
break;
case "colorinventoryhalf":
ColorInventoryHalf = subElement.GetAttributeColor("color", ColorInventoryHalf);
break;
case "colorinventoryfull":
ColorInventoryFull = subElement.GetAttributeColor("color", ColorInventoryFull);
break;
case "colorinventorybackground":
ColorInventoryBackground = subElement.GetAttributeColor("color", ColorInventoryBackground);
break;
case "colorinventoryemptyoverlay":
ColorInventoryEmptyOverlay = subElement.GetAttributeColor("color", ColorInventoryEmptyOverlay);
break;
case "textcolordark":
TextColorDark = subElement.GetAttributeColor("color", TextColorDark);
break;
case "textcolorbright":
TextColorBright = subElement.GetAttributeColor("color", TextColorBright);
break;
case "textcolordim":
TextColorDim = subElement.GetAttributeColor("color", TextColorDim);
break;
case "textcolornormal":
case "textcolor":
TextColor = subElement.GetAttributeColor("color", TextColor);
break;
case "colorreputationverylow":
ColorReputationVeryLow = subElement.GetAttributeColor("color", TextColor);
break;
case "colorreputationlow":
ColorReputationLow = subElement.GetAttributeColor("color", TextColor);
break;
case "colorreputationneutral":
ColorReputationNeutral = subElement.GetAttributeColor("color", TextColor);
break;
case "colorreputationhigh":
ColorReputationHigh = subElement.GetAttributeColor("color", TextColor);
break;
case "colorreputationveryhigh":
ColorReputationVeryHigh = subElement.GetAttributeColor("color", TextColor);
break;
case "equipmentsloticoncolor":
EquipmentSlotIconColor = subElement.GetAttributeColor("color", EquipmentSlotIconColor);
break;
case "buffcolorlow":
BuffColorLow = subElement.GetAttributeColor("color", BuffColorLow);
break;
case "buffcolormedium":
BuffColorMedium = subElement.GetAttributeColor("color", BuffColorMedium);
break;
case "buffcolorhigh":
BuffColorHigh = subElement.GetAttributeColor("color", BuffColorHigh);
break;
case "debuffcolorlow":
DebuffColorLow = subElement.GetAttributeColor("color", DebuffColorLow);
break;
case "debuffcolormedium":
DebuffColorMedium = subElement.GetAttributeColor("color", DebuffColorMedium);
break;
case "debuffcolorhigh":
DebuffColorHigh = subElement.GetAttributeColor("color", DebuffColorHigh);
break;
case "healthbarcolorlow":
HealthBarColorLow = subElement.GetAttributeColor("color", HealthBarColorLow);
break;
case "healthbarcolormedium":
HealthBarColorMedium = subElement.GetAttributeColor("color", HealthBarColorMedium);
break;
case "healthbarcolorhigh":
HealthBarColorHigh = subElement.GetAttributeColor("color", HealthBarColorHigh);
break;
case "equipmentindicatornotequipped":
EquipmentIndicatorNotEquipped = subElement.GetAttributeColor("color", EquipmentIndicatorNotEquipped);
break;
case "equipmentindicatorequipped":
EquipmentIndicatorEquipped = subElement.GetAttributeColor("color", EquipmentIndicatorEquipped);
break;
case "equipmentindicatorrunningout":
EquipmentIndicatorRunningOut = subElement.GetAttributeColor("color", EquipmentIndicatorRunningOut);
break;
case "uiglow":
UIGlow = new UISprite(subElement);
break;
case "pingcircle":
PingCircle = new UISprite(subElement);
break;
case "youareherecircle":
YouAreHereCircle = new UISprite(subElement);
break;
case "radiation":
RadiationSprite = new UISprite(subElement);
break;
case "radiationanimspritesheet":
RadiationAnimSpriteSheet = new SpriteSheet(subElement);
break;
case "uiglowcircular":
UIGlowCircular = new UISprite(subElement);
break;
case "uiglowsolidcircular":
UIGlowSolidCircular = new UISprite(subElement);
break;
case "uithermalglow":
UIThermalGlow = new UISprite(subElement);
break;
case "endroundbuttonpulse":
ButtonPulse = new UISprite(subElement);
break;
case "iconoverflowindicator":
IconOverflowIndicator = new UISprite(subElement);
break;
case "focusindicator":
FocusIndicator = new SpriteSheet(subElement);
break;
case "savingindicator":
SavingIndicator = new SpriteSheet(subElement);
break;
case "font":
Font = LoadFont(subElement, graphicsDevice);
ForceFontUpperCase[Font] = subElement.GetAttributeBool("forceuppercase", false);
break;
case "globalfont":
GlobalFont = LoadFont(subElement, graphicsDevice);
ForceFontUpperCase[GlobalFont] = subElement.GetAttributeBool("forceuppercase", false);
break;
case "unscaledsmallfont":
UnscaledSmallFont = LoadFont(subElement, graphicsDevice);
ForceFontUpperCase[UnscaledSmallFont] = subElement.GetAttributeBool("forceuppercase", false);
break;
case "smallfont":
SmallFont = LoadFont(subElement, graphicsDevice);
ForceFontUpperCase[SmallFont] = subElement.GetAttributeBool("forceuppercase", false);
break;
case "largefont":
LargeFont = LoadFont(subElement, graphicsDevice);
ForceFontUpperCase[LargeFont] = subElement.GetAttributeBool("forceuppercase", false);
break;
case "digitalfont":
DigitalFont = LoadFont(subElement, graphicsDevice);
ForceFontUpperCase[DigitalFont] = subElement.GetAttributeBool("forceuppercase", false);
break;
case "monospacedfont":
MonospacedFont = LoadFont(subElement, graphicsDevice);
ForceFontUpperCase[MonospacedFont] = subElement.GetAttributeBool("forceuppercase", false);
break;
case "hotkeyfont":
HotkeyFont = LoadFont(subElement, graphicsDevice);
ForceFontUpperCase[HotkeyFont] = subElement.GetAttributeBool("forceuppercase", false);
break;
case "objectivetitle":
case "subheading":
SubHeadingFont = LoadFont(subElement, graphicsDevice);
ForceFontUpperCase[SubHeadingFont] = subElement.GetAttributeBool("forceuppercase", false);
break;
default:
GUIComponentStyle componentStyle = new GUIComponentStyle(subElement, this);
componentStyles.Add(subElement.Name.ToString().ToLowerInvariant(), componentStyle);
break;
}
}
if (GlobalFont == null)
{
GlobalFont = Font;
DebugConsole.NewMessage("Global font not defined in the current UI style file. The global font is used to render western symbols when using Chinese/Japanese/Korean localization. Using default font instead...", Color.Orange);
}
// TODO: Needs to unregister if we ever remove GUIStyles.
GameMain.Instance.ResolutionChanged += RescaleElements;
Apply(targetComponent, styleName.ToIdentifier(), parent);
}
/// <summary>
/// Returns the default font of the currently selected language
/// </summary>
public ScalableFont LoadCurrentDefaultFont()
{
defaultFont?.Dispose();
defaultFont = null;
foreach (XElement subElement in configElement.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "font":
defaultFont = LoadFont(subElement, graphicsDevice);
break;
}
}
return defaultFont;
}
private void RescaleElements()
{
if (configElement == null) { return; }
if (configElement.Elements() == null) { return; }
foreach (XElement subElement in configElement.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "font":
if (Font == null) { continue; }
Font.Size = GetFontSize(subElement);
break;
case "smallfont":
if (SmallFont == null) { continue; }
SmallFont.Size = GetFontSize(subElement);
break;
case "largefont":
if (LargeFont == null) { continue; }
LargeFont.Size = GetFontSize(subElement);
break;
case "hotkeyfont":
if (HotkeyFont == null) { continue; }
HotkeyFont.Size = GetFontSize(subElement);
break;
case "objectivetitle":
case "subheading":
if (SubHeadingFont == null) { continue; }
SubHeadingFont.Size = GetFontSize(subElement);
break;
}
}
foreach (var componentStyle in componentStyles.Values)
{
componentStyle.GetSize(componentStyle.Element);
foreach (var childStyle in componentStyle.ChildStyles.Values)
{
childStyle.GetSize(childStyle.Element);
}
}
}
private ScalableFont LoadFont(XElement element, GraphicsDevice graphicsDevice)
{
string file = GetFontFilePath(element);
uint size = GetFontSize(element);
bool dynamicLoading = GetFontDynamicLoading(element);
bool isCJK = GetIsCJK(element);
return new ScalableFont(file, size, graphicsDevice, dynamicLoading, isCJK);
}
private uint GetFontSize(XElement element, uint defaultSize = 14)
{
//check if any of the language override fonts want to override the font size as well
foreach (XElement subElement in element.Elements())
{
if (!subElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase)) { continue; }
if (GameMain.Config.Language.Equals(subElement.GetAttributeString("language", ""), StringComparison.OrdinalIgnoreCase))
{
uint overrideFontSize = GetFontSize(subElement, 0);
if (overrideFontSize > 0) { return (uint)Math.Round(overrideFontSize * GameSettings.TextScale); }
}
}
foreach (XElement subElement in element.Elements())
{
if (!subElement.Name.ToString().Equals("size", StringComparison.OrdinalIgnoreCase)) { continue; }
Point maxResolution = subElement.GetAttributePoint("maxresolution", new Point(int.MaxValue, int.MaxValue));
if (GameMain.GraphicsWidth <= maxResolution.X && GameMain.GraphicsHeight <= maxResolution.Y)
{
return (uint)Math.Round(subElement.GetAttributeInt("size", 14) * GameSettings.TextScale);
}
}
return (uint)Math.Round(defaultSize * GameSettings.TextScale);
}
private string GetFontFilePath(XElement element)
{
foreach (XElement subElement in element.Elements())
{
if (!subElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase)) { continue; }
if (GameMain.Config.Language.Equals(subElement.GetAttributeString("language", ""), StringComparison.OrdinalIgnoreCase))
{
return subElement.GetAttributeString("file", "");
}
}
return element.GetAttributeString("file", "");
}
private bool GetFontDynamicLoading(XElement element)
{
foreach (XElement subElement in element.Elements())
{
if (!subElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase)) { continue; }
if (GameMain.Config.Language.Equals(subElement.GetAttributeString("language", ""), StringComparison.OrdinalIgnoreCase))
{
return subElement.GetAttributeBool("dynamicloading", false);
}
}
return element.GetAttributeBool("dynamicloading", false);
}
private bool GetIsCJK(XElement element)
{
foreach (XElement subElement in element.Elements())
{
if (!subElement.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase)) { continue; }
if (GameMain.Config.Language.Equals(subElement.GetAttributeString("language", ""), StringComparison.OrdinalIgnoreCase))
{
return subElement.GetAttributeBool("iscjk", false);
}
}
return element.GetAttributeBool("iscjk", false);
}
public GUIComponentStyle GetComponentStyle(string name)
{
componentStyles.TryGetValue(name.ToLowerInvariant(), out GUIComponentStyle style);
return style;
}
public void Apply(GUIComponent targetComponent, string styleName = "", GUIComponent parent = null)
public static void Apply(GUIComponent targetComponent, Identifier styleName, GUIComponent parent = null)
{
GUIComponentStyle componentStyle = null;
if (parent != null)
{
GUIComponentStyle parentStyle = parent.Style;
if (parent.Style == null)
if (parentStyle == null)
{
string parentStyleName = parent.GetType().Name.ToLowerInvariant();
Identifier parentStyleName = parent.GetType().Name.ToIdentifier();
if (!componentStyles.TryGetValue(parentStyleName, out parentStyle))
if (!ComponentStyles.ContainsKey(parentStyleName))
{
DebugConsole.ThrowError("Couldn't find a GUI style \""+ parentStyleName + "\"");
DebugConsole.ThrowError($"Couldn't find a GUI style \"{parentStyleName}\"");
return;
}
parentStyle = ComponentStyles[parentStyleName];
}
string childStyleName = string.IsNullOrEmpty(styleName) ? targetComponent.GetType().Name : styleName;
parentStyle.ChildStyles.TryGetValue(childStyleName.ToLowerInvariant(), out componentStyle);
Identifier childStyleName = styleName.IsEmpty ? targetComponent.GetType().Name.ToIdentifier() : styleName;
parentStyle.ChildStyles.TryGetValue(childStyleName, out componentStyle);
}
else
{
if (string.IsNullOrEmpty(styleName))
Identifier styleIdentifier = styleName.ToIdentifier();
if (styleIdentifier == Identifier.Empty)
{
styleName = targetComponent.GetType().Name;
styleIdentifier = targetComponent.GetType().Name.ToIdentifier();
}
if (!componentStyles.TryGetValue(styleName.ToLowerInvariant(), out componentStyle))
if (!ComponentStyles.ContainsKey(styleIdentifier))
{
DebugConsole.ThrowError("Couldn't find a GUI style \""+ styleName+"\"");
DebugConsole.ThrowError($"Couldn't find a GUI style \"{styleIdentifier}\"");
return;
}
componentStyle = ComponentStyles[styleIdentifier];
}
targetComponent.ApplyStyle(componentStyle);
}
public Color GetQualityColor(int quality)
public static GUIColor GetQualityColor(int quality)
{
switch (quality)
{
@@ -1,4 +1,5 @@
using Microsoft.Xna.Framework;
using Barotrauma.Extensions;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
@@ -7,9 +8,16 @@ using System.Linq;
namespace Barotrauma
{
public enum ForceUpperCase
{
Inherit,
No,
Yes
}
public class GUITextBlock : GUIComponent
{
protected string text;
protected RichString text;
protected Alignment textAlignment;
@@ -20,10 +28,10 @@ namespace Barotrauma
protected Color textColor, disabledTextColor, selectedTextColor;
private string wrappedText;
private LocalizedString wrappedText;
private string censoredText;
public delegate string TextGetterHandler();
public delegate LocalizedString TextGetterHandler();
public TextGetterHandler TextGetter;
public bool Wrap;
@@ -41,8 +49,6 @@ namespace Barotrauma
private float textDepth;
private ScalableFont originalFont;
public Vector2 TextOffset { get; set; }
private Vector4 padding;
@@ -56,7 +62,7 @@ namespace Barotrauma
}
}
public override ScalableFont Font
public override GUIFont Font
{
get
{
@@ -65,23 +71,25 @@ namespace Barotrauma
set
{
if (base.Font == value) { return; }
base.Font = originalFont = value;
if (text != null && GUI.Style.ForceFontUpperCase.ContainsKey(Font) && GUI.Style.ForceFontUpperCase[Font])
{
Text = text.ToUpper();
}
base.Font = value;
if (text != null) { Text = text; }
SetTextPos();
}
}
public string Text
public RichString Text
{
get { return text; }
set
{
string newText = forceUpperCase || (GUI.Style.ForceFontUpperCase.ContainsKey(Font) && GUI.Style.ForceFontUpperCase[Font]) || (style != null && style.ForceUpperCase) ?
value?.ToUpper() :
value;
#warning TODO: Remove this eventually. Nobody should want to pass null.
value ??= "";
RichString newText = forceUpperCase switch
{
ForceUpperCase.Inherit => value.CaseTiedToFontAndStyle(Font, Style),
ForceUpperCase.No => value.CaseTiedToFontAndStyle(null, null),
ForceUpperCase.Yes => value.ToUpper()
};
if (Text == newText) { return; }
@@ -89,21 +97,12 @@ namespace Barotrauma
if (autoScaleHorizontal || autoScaleVertical) { textScale = 1.0f; }
text = newText;
wrappedText = newText;
if (TextManager.IsCJK(text))
{
//switch to fallback CJK font
if (!Font.IsCJK) { base.Font = GUI.CJKFont; }
}
else
{
if (Font == GUI.CJKFont) { base.Font = originalFont; }
}
wrappedText = newText.SanitizedString;
SetTextPos();
}
}
public string WrappedText
public LocalizedString WrappedText
{
get { return wrappedText; }
}
@@ -117,7 +116,11 @@ namespace Barotrauma
public Vector2 TextPos
{
get { return textPos; }
set { textPos = value; }
set
{
textPos = value;
ClearCaretPositions();
}
}
public float TextScale
@@ -169,8 +172,8 @@ namespace Barotrauma
}
}
private bool forceUpperCase;
public bool ForceUpperCase
private ForceUpperCase forceUpperCase = ForceUpperCase.Inherit;
public ForceUpperCase ForceUpperCase
{
get { return forceUpperCase; }
set
@@ -178,12 +181,7 @@ namespace Barotrauma
if (forceUpperCase == value) { return; }
forceUpperCase = value;
if (forceUpperCase ||
(style != null && style.ForceUpperCase) ||
(GUI.Style.ForceFontUpperCase.ContainsKey(Font) && GUI.Style.ForceFontUpperCase[Font]))
{
Text = text?.ToUpper();
}
if (text != null) { Text = text; }
}
}
@@ -247,7 +245,7 @@ namespace Barotrauma
public class StrikethroughSettings
{
public Color Color { get; set; } = GUI.Style.Red;
public Color Color { get; set; } = GUIStyle.Red;
private int thickness;
private int expand;
@@ -266,13 +264,9 @@ namespace Barotrauma
public StrikethroughSettings Strikethrough = null;
public List<RichTextData> RichTextData
{
get;
private set;
}
public ImmutableArray<RichTextData>? RichTextData => text.RichTextData;
public bool HasColorHighlight => RichTextData != null;
public bool HasColorHighlight => RichTextData.HasValue;
public bool OverrideRichTextDataAlpha = true;
@@ -292,9 +286,9 @@ namespace Barotrauma
/// This is the new constructor.
/// If the rectT height is set 0, the height is calculated from the text.
/// </summary>
public GUITextBlock(RectTransform rectT, string text, Color? textColor = null, ScalableFont font = null,
public GUITextBlock(RectTransform rectT, RichString text, Color? textColor = null, GUIFont font = null,
Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null,
bool playerInput = false, bool parseRichText = false)
bool playerInput = false)
: base(style, rectT)
{
if (color.HasValue)
@@ -306,28 +300,15 @@ namespace Barotrauma
OverrideTextColor(textColor.Value);
}
if (parseRichText)
{
RichTextData = Barotrauma.RichTextData.GetRichTextData(text, out text);
if (RichTextData != null && RichTextData.Count == 0)
{
RichTextData = null;
}
}
//if the text is in chinese/korean/japanese and we're not using a CJK-compatible font,
//use the default CJK font as a fallback
var selectedFont = originalFont = font ?? GUI.Font;
if (TextManager.IsCJK(text) && !selectedFont.IsCJK)
{
selectedFont = GUI.CJKFont;
}
var selectedFont = font ?? GUIStyle.Font;
this.Font = selectedFont;
this.textAlignment = textAlignment;
this.Wrap = wrap;
this.Text = text ?? "";
this.playerInput = playerInput;
if (rectT.Rect.Height == 0 && !string.IsNullOrEmpty(text))
if (rectT.Rect.Height == 0 && !text.IsNullOrEmpty())
{
CalculateHeightFromText();
}
@@ -339,11 +320,6 @@ namespace Barotrauma
Enabled = true;
Censor = false;
}
public GUITextBlock(RectTransform rectT, List<RichTextData> richTextData, string text, Color? textColor = null, ScalableFont font = null, Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null, bool playerInput = false)
: this(rectT, text, textColor, font, textAlignment, wrap, style, color, playerInput)
{
this.RichTextData = richTextData;
}
public void CalculateHeightFromText(int padding = 0, bool removeExtraSpacing = false)
{
@@ -351,10 +327,9 @@ namespace Barotrauma
RectTransform.Resize(new Point(RectTransform.Rect.Width, (int)Font.MeasureString(wrappedText, removeExtraSpacing).Y + padding));
}
public void SetRichText(string richText)
public void SetRichText(LocalizedString richText)
{
RichTextData = Barotrauma.RichTextData.GetRichTextData(richText, out string sanitizedText);
Text = sanitizedText;
Text = RichString.Rich(richText);
}
public override void ApplyStyle(GUIComponentStyle componentStyle)
@@ -368,41 +343,34 @@ namespace Barotrauma
disabledTextColor = componentStyle.DisabledTextColor;
selectedTextColor = componentStyle.SelectedTextColor;
switch (componentStyle.Font)
if (Font == null || !componentStyle.Font.IsEmpty)
{
case "font":
Font = componentStyle.Style.Font;
break;
case "smallfont":
Font = componentStyle.Style.SmallFont;
break;
case "largefont":
Font = componentStyle.Style.LargeFont;
break;
case "objectivetitle":
case "subheading":
Font = componentStyle.Style.SubHeadingFont;
break;
Font = GUIStyle.Fonts[componentStyle.Font.AppendIfMissing("Font")];
}
}
public void ClearCaretPositions()
{
cachedCaretPositions = ImmutableArray<Vector2>.Empty;
}
public void SetTextPos()
{
cachedCaretPositions = ImmutableArray<Vector2>.Empty;
ClearCaretPositions();
if (text == null) { return; }
censoredText = string.IsNullOrEmpty(text) ? "" : new string('\u2022', text.Length);
censoredText = text.IsNullOrEmpty() ? "" : new string('\u2022', text.Length);
var rect = Rect;
overflowClipActive = false;
wrappedText = text;
wrappedText = text.SanitizedString;
TextSize = MeasureText(text);
TextSize = MeasureText(text.SanitizedString);
if (Wrap && rect.Width > 0)
{
wrappedText = ToolBox.WrapText(text, rect.Width - padding.X - padding.Z, Font, textScale);
wrappedText = ToolBox.WrapText(text.SanitizedString, rect.Width - padding.X - padding.Z, Font, textScale);
TextSize = MeasureText(wrappedText);
}
else if (OverflowClip)
@@ -426,15 +394,15 @@ namespace Barotrauma
textPos = new Vector2(padding.X + (rect.Width - padding.Z - padding.X) / 2.0f, padding.Y + (rect.Height - padding.Y - padding.W) / 2.0f);
origin = TextSize * 0.5f;
origin.X = 0;
if (textAlignment.HasFlag(Alignment.Left) && !overflowClipActive)
{
textPos.X = padding.X;
origin.X = 0;
}
if (textAlignment.HasFlag(Alignment.Right) || overflowClipActive)
{
textPos.X = rect.Width - padding.Z;
origin.X = TextSize.X;
//origin.X = TextSize.X;
}
if (textAlignment.HasFlag(Alignment.Top))
{
@@ -454,7 +422,12 @@ namespace Barotrauma
textPos.Y = (int)textPos.Y;
}
private Vector2 MeasureText(string text)
private Vector2 MeasureText(LocalizedString text)
{
return MeasureText(text.Value);
}
private Vector2 MeasureText(string text)
{
if (Font == null) return Vector2.Zero;
@@ -498,12 +471,20 @@ namespace Barotrauma
{
return cachedCaretPositions;
}
string textDrawn = Censor ? CensoredText : Text;
string textDrawn = Censor ? CensoredText : Text.SanitizedValue;
float w = Wrap
? (Rect.Width - Padding.X - Padding.Z) / TextScale
: float.PositiveInfinity;
Font.WrapText(textDrawn, w, out Vector2[] positions);
cachedCaretPositions = positions.Select(p => p * TextScale + TextPos - Origin * TextScale).ToImmutableArray();
string wrapped = Font.WrapText(textDrawn, w, out Vector2[] positions);
int textWidth = (int)Font.MeasureString(wrapped).X;
int alignmentXDiff
= textAlignment.HasFlag(Alignment.Right) ? textWidth
: textAlignment.HasFlag(Alignment.Center) ? textWidth / 2
: 0;
cachedCaretPositions = positions
.Select(p => p - new Vector2(alignmentXDiff, 0))
.Select(p => p * TextScale + TextPos - Origin * TextScale)
.ToImmutableArray();
return cachedCaretPositions;
}
@@ -584,7 +565,7 @@ namespace Barotrauma
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
}
if (!string.IsNullOrEmpty(text))
if (!text.IsNullOrEmpty())
{
Vector2 pos = rect.Location.ToVector2() + textPos + TextOffset;
if (RoundToNearestPixel)
@@ -605,28 +586,29 @@ namespace Barotrauma
if (!HasColorHighlight)
{
string textToShow = Censor ? censoredText : (Wrap ? wrappedText : text);
string textToShow = Censor ? censoredText : (Wrap ? wrappedText.Value : text.SanitizedValue);
Color colorToShow = currentTextColor * (currentTextColor.A / 255.0f);
if (Shadow)
{
Vector2 shadowOffset = new Vector2(GUI.IntScale(2));
Font.DrawString(spriteBatch, textToShow, pos + shadowOffset, Color.Black, 0.0f, origin, TextScale, SpriteEffects.None, textDepth);
Font.DrawString(spriteBatch, textToShow, pos + shadowOffset, Color.Black, 0.0f, origin, TextScale, SpriteEffects.None, textDepth, alignment: textAlignment, forceUpperCase: ForceUpperCase);
}
Font.DrawString(spriteBatch, textToShow, pos, colorToShow, 0.0f, origin, TextScale, SpriteEffects.None, textDepth);
Font.DrawString(spriteBatch, textToShow, pos, colorToShow, 0.0f, origin, TextScale, SpriteEffects.None, textDepth, alignment: textAlignment, forceUpperCase: ForceUpperCase);
}
else
{
if (OverrideRichTextDataAlpha)
{
RichTextData.ForEach(rt => rt.Alpha = currentTextColor.A / 255.0f);
RichTextData.Value.ForEach(rt => rt.Alpha = currentTextColor.A / 255.0f);
}
Font.DrawStringWithColors(spriteBatch, Censor ? censoredText : (Wrap ? wrappedText : text), pos,
currentTextColor * (currentTextColor.A / 255.0f), 0.0f, origin, TextScale, SpriteEffects.None, textDepth, RichTextData);
Font.DrawStringWithColors(spriteBatch, Censor ? censoredText : (Wrap ? wrappedText : text.SanitizedString).Value, pos,
currentTextColor * (currentTextColor.A / 255.0f), 0.0f, origin, TextScale, SpriteEffects.None, textDepth, RichTextData.Value, alignment: textAlignment, forceUpperCase: ForceUpperCase);
}
Strikethrough?.Draw(spriteBatch, (int)Math.Ceiling(TextSize.X / 2f), pos.X, ForceUpperCase ? pos.Y : pos.Y + GUI.Scale * 2f);
Strikethrough?.Draw(spriteBatch, (int)Math.Ceiling(TextSize.X / 2f), pos.X,
/* TODO: ???? */ForceUpperCase == ForceUpperCase.Yes ? pos.Y : pos.Y + GUI.Scale * 2f);
}
if (overflowClipActive)
@@ -66,9 +66,6 @@ namespace Barotrauma
private int selectionStartIndex;
private int selectionEndIndex;
private bool IsLeftToRight => selectionStartIndex <= selectionEndIndex;
private Vector2 selectionStartPos;
private Vector2 selectionEndPos;
private Vector2 selectionRectSize;
private GUICustomComponent caretAndSelectionRenderer;
@@ -141,7 +138,7 @@ namespace Barotrauma
maxTextLength = value;
if (Text.Length > MaxTextLength)
{
SetText(textBlock.Text.Substring(0, (int)maxTextLength));
SetText(Text.Substring(0, (int)maxTextLength));
}
}
}
@@ -172,7 +169,7 @@ namespace Barotrauma
set { textBlock.Censor = value; }
}
public override string ToolTip
public override RichString ToolTip
{
get
{
@@ -184,7 +181,7 @@ namespace Barotrauma
}
}
public override ScalableFont Font
public override GUIFont Font
{
get { return textBlock?.Font ?? base.Font; }
set
@@ -237,7 +234,7 @@ namespace Barotrauma
{
get
{
return textBlock.Text;
return textBlock.Text.SanitizedValue;
}
set
{
@@ -249,12 +246,12 @@ namespace Barotrauma
public string WrappedText
{
get { return textBlock.WrappedText; }
get { return textBlock.WrappedText.Value; }
}
public bool Readonly { get; set; }
public GUITextBox(RectTransform rectT, string text = "", Color? textColor = null, ScalableFont font = null,
public GUITextBox(RectTransform rectT, string text = "", Color? textColor = null, GUIFont font = null,
Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null, bool createClearButton = false, bool createPenIcon = true)
: base(style, rectT)
{
@@ -263,9 +260,10 @@ namespace Barotrauma
this.color = color ?? Color.White;
frame = new GUIFrame(new RectTransform(Vector2.One, rectT, Anchor.Center), style, color);
GUI.Style.Apply(frame, style == "" ? "GUITextBox" : style);
textBlock = new GUITextBlock(new RectTransform(Vector2.One, frame.RectTransform, Anchor.CenterLeft), text, textColor, font, textAlignment, wrap, playerInput: true);
GUI.Style.Apply(textBlock, "", this);
GUIStyle.Apply(frame, style == "" ? "GUITextBox" : style);
textBlock = new GUITextBlock(new RectTransform(Vector2.One, frame.RectTransform, Anchor.CenterLeft), text ?? "", textColor, font, textAlignment, wrap, playerInput: true);
GUIStyle.Apply(textBlock, "", this);
if (font != null) { textBlock.Font = font; }
CaretEnabled = true;
caretPosDirty = true;
@@ -287,10 +285,11 @@ namespace Barotrauma
clearButtonWidth = (int)(clearButton.Rect.Width * 1.2f);
}
if (this.style != null && this.style.ChildStyles.ContainsKey("textboxicon") && createPenIcon)
var selfStyle = Style;
if (selfStyle != null && selfStyle.ChildStyles.ContainsKey("textboxicon".ToIdentifier()) && createPenIcon)
{
icon = new GUIImage(new RectTransform(new Vector2(0.6f, 0.6f), frame.RectTransform, Anchor.CenterRight, scaleBasis: ScaleBasis.BothHeight) { AbsoluteOffset = new Point(5 + clearButtonWidth, 0) }, null, scaleToFit: true);
icon.ApplyStyle(this.style.ChildStyles["textboxicon"]);
icon.ApplyStyle(this.Style.ChildStyles["textboxicon".ToIdentifier()]);
textBlock.RectTransform.MaxSize = new Point(frame.Rect.Width - icon.Rect.Height - clearButtonWidth - icon.RectTransform.AbsoluteOffset.X * 2, int.MaxValue);
}
Font = textBlock.Font;
@@ -315,53 +314,38 @@ namespace Barotrauma
{
text = textFilterFunction(text);
}
if (textBlock.Text == text) { return false; }
if (Text == text) { return false; }
textBlock.Text = text;
if (textBlock.Text == null) textBlock.Text = "";
if (textBlock.Text != "" && !Wrap)
if (Text == null) textBlock.Text = "";
if (Text != "" && !Wrap)
{
if (maxTextLength != null)
{
if (textBlock.Text.Length > maxTextLength)
{
textBlock.Text = textBlock.Text.Substring(0, (int)maxTextLength);
textBlock.Text = Text.Substring(0, (int)maxTextLength);
}
}
else
{
while (ClampText && textBlock.Text.Length > 0 && Font.MeasureString(textBlock.Text).X * TextBlock.TextScale > (int)(textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z))
{
textBlock.Text = textBlock.Text.Substring(0, textBlock.Text.Length - 1);
textBlock.Text = Text.Substring(0, textBlock.Text.Length - 1);
}
}
}
if (store)
{
memento.Store(textBlock.Text);
memento.Store(Text);
}
return true;
}
private void CalculateCaretPos()
{
if (Censor || !Wrap)
{
string textDrawn = textBlock.CensoredText;
CaretIndex = Math.Min(CaretIndex, textDrawn.Length);
textDrawn = Censor ? textBlock.CensoredText : textBlock.Text;
Vector2 textSize = Font.MeasureString(textDrawn[..CaretIndex]) * TextBlock.TextScale;
caretPos = new Vector2(textSize.X, 0) + textBlock.TextPos - textBlock.Origin * TextBlock.TextScale;
}
else
{
CaretIndex = Math.Min(CaretIndex, textBlock.Text.Length);
textBlock.Font.WrapText(
textBlock.Text,
(textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z) / TextBlock.TextScale,
CaretIndex,
out Vector2 requestedCharPos);
caretPos = requestedCharPos * TextBlock.TextScale + textBlock.TextPos - textBlock.Origin * TextBlock.TextScale;
}
CaretIndex = Math.Clamp(CaretIndex, 0, textBlock.Text.Length);
var caretPositions = textBlock.GetAllCaretPositions();
caretPos = caretPositions[CaretIndex];
caretPosDirty = false;
}
@@ -460,14 +444,19 @@ namespace Barotrauma
{
if (textBlock.OverflowClipActive)
{
if (CaretScreenPos.X < textBlock.Rect.X + textBlock.Padding.X)
float left = textBlock.Rect.X + textBlock.Padding.X;
if (CaretScreenPos.X < left)
{
textBlock.TextPos = new Vector2(textBlock.TextPos.X + ((textBlock.Rect.X + textBlock.Padding.X) - CaretScreenPos.X), textBlock.TextPos.Y);
float diff = left - CaretScreenPos.X;
textBlock.TextPos = new Vector2(textBlock.TextPos.X + diff, textBlock.TextPos.Y);
CalculateCaretPos();
}
else if (CaretScreenPos.X > textBlock.Rect.Right - textBlock.Padding.Z)
float right = textBlock.Rect.Right - textBlock.Padding.Z;
if (CaretScreenPos.X > right)
{
textBlock.TextPos = new Vector2(textBlock.TextPos.X - (CaretScreenPos.X - (textBlock.Rect.Right - textBlock.Padding.Z)), textBlock.TextPos.Y);
float diff = CaretScreenPos.X - right;
textBlock.TextPos = new Vector2(textBlock.TextPos.X - diff, textBlock.TextPos.Y);
CalculateCaretPos();
}
}
@@ -499,74 +488,54 @@ namespace Barotrauma
private void DrawCaretAndSelection(SpriteBatch spriteBatch, GUICustomComponent customComponent)
{
if (!Visible) { return; }
if (Selected)
if (!Selected) { return; }
if (caretVisible)
{
if (caretVisible )
{
GUI.DrawLine(spriteBatch,
new Vector2(Rect.X + (int)caretPos.X + 2, Rect.Y + caretPos.Y + 3),
new Vector2(Rect.X + (int)caretPos.X + 2, Rect.Y + caretPos.Y + Font.MeasureString("I").Y * textBlock.TextScale - 3),
CaretColor ?? textBlock.TextColor * (textBlock.TextColor.A / 255.0f));
}
if (selectedCharacters > 0)
{
DrawSelectionRect(spriteBatch);
}
//GUI.DrawString(spriteBatch, new Vector2(100, 0), selectedCharacters.ToString(), Color.LightBlue, Color.Black);
//GUI.DrawString(spriteBatch, new Vector2(100, 20), selectionStartIndex.ToString(), Color.White, Color.Black);
//GUI.DrawString(spriteBatch, new Vector2(140, 20), selectionEndIndex.ToString(), Color.White, Color.Black);
//GUI.DrawString(spriteBatch, new Vector2(100, 40), selectedText.ToString(), Color.Yellow, Color.Black);
//GUI.DrawString(spriteBatch, new Vector2(100, 60), $"caret index: {CaretIndex.ToString()}", GUI.Style.Red, Color.Black);
//GUI.DrawString(spriteBatch, new Vector2(100, 80), $"caret pos: {caretPos.ToString()}", GUI.Style.Red, Color.Black);
//GUI.DrawString(spriteBatch, new Vector2(100, 100), $"caret screen pos: {CaretScreenPos.ToString()}", GUI.Style.Red, Color.Black);
//GUI.DrawString(spriteBatch, new Vector2(100, 120), $"text start pos: {(textBlock.TextPos - textBlock.Origin).ToString()}", Color.White, Color.Black);
//GUI.DrawString(spriteBatch, new Vector2(100, 140), $"cursor pos: {PlayerInput.MousePosition.ToString()}", Color.White, Color.Black);
GUI.DrawLine(spriteBatch,
new Vector2(Rect.X + (int)caretPos.X + 2, Rect.Y + caretPos.Y + 3),
new Vector2(Rect.X + (int)caretPos.X + 2, Rect.Y + caretPos.Y + Font.LineHeight * textBlock.TextScale - 3),
CaretColor ?? textBlock.TextColor * (textBlock.TextColor.A / 255.0f));
}
if (selectedCharacters > 0)
{
DrawSelectionRect(spriteBatch);
}
}
private void DrawSelectionRect(SpriteBatch spriteBatch)
{
if (textBlock.WrappedText.Contains("\n"))
{
// Multiline selection
var characterPositions = textBlock.GetAllCaretPositions();
(int startIndex, int endIndex) = selectionStartIndex < selectionEndIndex
? (selectionStartIndex, selectionEndIndex)
: (selectionEndIndex, selectionStartIndex);
endIndex--;
var characterPositions = textBlock.GetAllCaretPositions();
(int startIndex, int endIndex) = IsLeftToRight
? (selectionStartIndex, selectionEndIndex)
: (selectionEndIndex, selectionStartIndex);
endIndex--;
void drawRect(Vector2 topLeft, Vector2 bottomRight)
{
int minWidth = GUI.IntScale(5);
if (bottomRight.X - topLeft.X < minWidth) { bottomRight.X = topLeft.X + minWidth; }
GUI.DrawRectangle(spriteBatch,
Rect.Location.ToVector2() + topLeft,
bottomRight - topLeft,
SelectionColor, isFilled: true);
}
Vector2 topLeft = characterPositions[startIndex];
for (int i = startIndex+1; i <= endIndex; i++)
{
Vector2 currPos = characterPositions[i];
if (!MathUtils.NearlyEqual(topLeft.Y, currPos.Y))
{
Vector2 bottomRight = characterPositions[i - 1];
bottomRight += Font.MeasureChar(Text[i - 1]);
drawRect(topLeft, bottomRight);
topLeft = currPos;
}
}
Vector2 finalBottomRight = characterPositions[endIndex];
finalBottomRight += Font.MeasureChar(Text[endIndex]);
drawRect(topLeft, finalBottomRight);
}
else
void drawRect(Vector2 topLeft, Vector2 bottomRight)
{
// Single line selection
Vector2 topLeft = IsLeftToRight ? selectionStartPos : selectionEndPos;
GUI.DrawRectangle(spriteBatch, Rect.Location.ToVector2() + topLeft, selectionRectSize, SelectionColor, isFilled: true);
int minWidth = GUI.IntScale(5);
if (bottomRight.X - topLeft.X < minWidth) { bottomRight.X = topLeft.X + minWidth; }
GUI.DrawRectangle(spriteBatch,
Rect.Location.ToVector2() + topLeft,
bottomRight - topLeft,
SelectionColor, isFilled: true);
}
Vector2 topLeft = characterPositions[startIndex];
for (int i = startIndex+1; i <= endIndex; i++)
{
Vector2 currPos = characterPositions[i];
if (!MathUtils.NearlyEqual(topLeft.Y, currPos.Y))
{
Vector2 bottomRight = characterPositions[i - 1];
bottomRight += Font.MeasureChar(Text[i - 1]) * TextBlock.TextScale;
drawRect(topLeft, bottomRight);
topLeft = currPos;
}
}
Vector2 finalBottomRight = characterPositions[endIndex];
finalBottomRight += Font.MeasureChar(Text[endIndex]) * TextBlock.TextScale;
drawRect(topLeft, finalBottomRight);
}
public void ReceiveTextInput(char inputChar)
@@ -700,8 +669,8 @@ namespace Barotrauma
float lineHeight = Font.LineHeight * TextBlock.TextScale;
int newIndex = textBlock.GetCaretIndexFromLocalPos(new Vector2(caretPos.X, caretPos.Y - lineHeight * 0.5f));
textBlock.Font.WrapText(
textBlock.Text,
(textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z) / TextBlock.TextScale,
textBlock.Text.SanitizedValue,
GetWrapWidth(),
newIndex,
out Vector2 requestedCharPos);
requestedCharPos *= TextBlock.TextScale;
@@ -718,8 +687,8 @@ namespace Barotrauma
lineHeight = Font.LineHeight * TextBlock.TextScale;
newIndex = textBlock.GetCaretIndexFromLocalPos(new Vector2(caretPos.X, caretPos.Y + lineHeight * 1.5f));
textBlock.Font.WrapText(
textBlock.Text,
(textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z) / TextBlock.TextScale,
textBlock.Text.SanitizedValue,
GetWrapWidth(),
newIndex,
out Vector2 requestedCharPos2);
requestedCharPos2 *= TextBlock.TextScale;
@@ -806,7 +775,6 @@ namespace Barotrauma
{
CaretIndex = 0;
CalculateCaretPos();
selectionStartPos = caretPos;
selectionStartIndex = 0;
CaretIndex = Text.Length;
CalculateSelection();
@@ -846,6 +814,9 @@ namespace Barotrauma
OnTextChanged?.Invoke(this, Text);
}
private float GetWrapWidth()
=> Wrap ? (textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z) / TextBlock.TextScale : float.PositiveInfinity;
private void InitSelectionStart()
{
if (caretPosDirty)
@@ -855,29 +826,20 @@ namespace Barotrauma
if (selectionStartIndex == -1)
{
selectionStartIndex = CaretIndex;
selectionStartPos = caretPos;
}
}
private void CalculateSelection()
{
string textDrawn = Censor ? textBlock.CensoredText : textBlock.WrappedText;
string textDrawn = Censor ? textBlock.CensoredText : WrappedText;
InitSelectionStart();
selectionEndIndex = Math.Min(CaretIndex, textDrawn.Length);
selectionEndPos = caretPos;
selectedCharacters = Math.Abs(selectionStartIndex - selectionEndIndex);
try
{
if (IsLeftToRight)
{
selectedText = Text.Substring(selectionStartIndex, Math.Min(selectedCharacters, Text.Length));
selectionRectSize = Font.MeasureString(textDrawn.Substring(selectionStartIndex, Math.Min(selectedCharacters, textDrawn.Length))) * TextBlock.TextScale;
}
else
{
selectedText = Text.Substring(selectionEndIndex, Math.Min(selectedCharacters, Text.Length));
selectionRectSize = Font.MeasureString(textDrawn.Substring(selectionEndIndex, Math.Min(selectedCharacters, textDrawn.Length))) * TextBlock.TextScale;
}
selectedText = Text.Substring(
IsLeftToRight ? selectionStartIndex : selectionEndIndex,
Math.Min(selectedCharacters, Text.Length));
}
catch (ArgumentOutOfRangeException exception)
{
@@ -20,18 +20,18 @@ namespace Barotrauma
public override bool Selected
{
get { return selected; }
get { return isSelected; }
set
{
if (value == selected) { return; }
if (value == isSelected) { return; }
if (radioButtonGroup != null && radioButtonGroup.SelectedRadioButton == this)
{
selected = true;
isSelected = true;
return;
}
selected = value;
State = selected ? ComponentState.Selected : ComponentState.None;
isSelected = value;
State = isSelected ? ComponentState.Selected : ComponentState.None;
if (value && radioButtonGroup != null)
{
radioButtonGroup.SelectRadioButton(this);
@@ -88,7 +88,7 @@ namespace Barotrauma
}
}*/
public override ScalableFont Font
public override GUIFont Font
{
get
{
@@ -112,7 +112,7 @@ namespace Barotrauma
get { return text; }
}
public override string ToolTip
public override RichString ToolTip
{
get { return base.ToolTip; }
set
@@ -123,13 +123,13 @@ namespace Barotrauma
}
}
public string Text
public LocalizedString Text
{
get { return text.Text; }
set { text.Text = value; }
}
public GUITickBox(RectTransform rectT, string label, ScalableFont font = null, string style = "") : base(null, rectT)
public GUITickBox(RectTransform rectT, LocalizedString label, GUIFont font = null, string style = "") : base(null, rectT)
{
CanBeFocused = true;
HoverCursor = CursorState.Hand;
@@ -145,7 +145,7 @@ namespace Barotrauma
SelectedColor = Color.DarkGray,
CanBeFocused = false
};
GUI.Style.Apply(box, style == "" ? "GUITickBox" : style);
GUIStyle.Apply(box, style == "" ? "GUITickBox" : style);
if (box.RectTransform.MinSize.Y > 0)
{
RectTransform.MinSize = box.RectTransform.MinSize;
@@ -159,7 +159,7 @@ namespace Barotrauma
{
CanBeFocused = false
};
GUI.Style.Apply(text, "GUITextBlock", this);
GUIStyle.Apply(text, "GUITextBlock", this);
Enabled = true;
ResizeBox();
@@ -205,13 +205,13 @@ namespace Barotrauma
{
Selected = !Selected;
}
else if (!selected)
else if (!isSelected)
{
Selected = true;
}
}
}
else if (selected)
else if (isSelected)
{
State = ComponentState.Selected;
}
@@ -90,7 +90,8 @@ namespace Barotrauma
if (GameMain.Instance != null)
{
GameMain.Instance.ResolutionChanged += CreateAreas;
GameMain.Config.OnHUDScaleChanged += CreateAreas;
#warning TODO: reimplement
//GameSettings.CurrentConfig.OnHUDScaleChanged += CreateAreas;
CreateAreas();
CharacterInfo.Init();
}
@@ -163,7 +164,7 @@ namespace Barotrauma
public static void Draw(SpriteBatch spriteBatch)
{
GUI.DrawRectangle(spriteBatch, ButtonAreaTop, Color.White * 0.5f);
GUI.DrawRectangle(spriteBatch, MessageAreaTop, GUI.Style.Orange * 0.5f);
GUI.DrawRectangle(spriteBatch, MessageAreaTop, GUIStyle.Orange * 0.5f);
GUI.DrawRectangle(spriteBatch, CrewArea, Color.Blue * 0.5f);
GUI.DrawRectangle(spriteBatch, ChatBoxArea, Color.Cyan * 0.5f);
GUI.DrawRectangle(spriteBatch, HealthBarArea, Color.Red * 0.5f);
@@ -7,6 +7,7 @@ using System.Xml.Linq;
using Barotrauma.Media;
using System.Linq;
using Barotrauma.Extensions;
using System.Collections.Immutable;
namespace Barotrauma
{
@@ -69,14 +70,10 @@ namespace Barotrauma
}
}
private string selectedTip;
private List<RichTextData> selectedTipRichTextData;
private bool selectedTipRichTextUnparsed;
private void SetSelectedTip(string tip)
private RichString selectedTip;
private void SetSelectedTip(LocalizedString tip)
{
selectedTip = tip;
selectedTipRichTextData = null;
selectedTipRichTextUnparsed = true;
selectedTip = RichString.Rich(tip);
}
private readonly object loadMutex = new object();
@@ -113,6 +110,8 @@ namespace Barotrauma
set;
}
public LanguageIdentifier[] AvailableLanguages = null;
public LoadingScreen(GraphicsDevice graphics)
{
defaultBackgroundTexture = TextureLoader.FromFile("Content/Map/LocationPortraits/AlienRuins.png");
@@ -123,12 +122,12 @@ namespace Barotrauma
overlay = TextureLoader.FromFile("Content/UI/LoadingScreenOverlay.png");
noiseSprite = new Sprite("Content/UI/noise.png", Vector2.Zero);
DrawLoadingText = true;
SetSelectedTip(TextManager.Get("LoadingScreenTip", true));
SetSelectedTip(TextManager.Get("LoadingScreenTip"));
}
public void Draw(SpriteBatch spriteBatch, GraphicsDevice graphics, float deltaTime)
{
if (GameMain.Config.EnableSplashScreen)
if (GameSettings.CurrentConfig.EnableSplashScreen)
{
try
{
@@ -138,11 +137,11 @@ namespace Barotrauma
catch (Exception e)
{
DebugConsole.ThrowError("Playing splash screen video failed", e);
GameMain.Config.EnableSplashScreen = false;
DisableSplashScreen();
}
}
var titleStyle = GUI.Style?.GetComponentStyle("TitleText");
var titleStyle = GUIStyle.GetComponentStyle("TitleText");
Sprite titleSprite = null;
if (!WaitForLanguageSelection && titleStyle != null && titleStyle.Sprites.ContainsKey(GUIComponent.ComponentState.None))
{
@@ -187,67 +186,58 @@ namespace Barotrauma
}
else if (DrawLoadingText)
{
if (TextManager.Initialized)
LocalizedString loadText;
if (LoadState == 100.0f)
{
string loadText;
if (LoadState == 100.0f)
#if DEBUG
if (GameSettings.CurrentConfig.AutomaticQuickStartEnabled || GameSettings.CurrentConfig.AutomaticCampaignLoadEnabled || (GameSettings.CurrentConfig.TestScreenEnabled && GameMain.FirstLoad))
{
#if DEBUG
if (GameMain.Config.AutomaticQuickStartEnabled || GameMain.Config.AutomaticCampaignLoadEnabled || GameMain.Config.TestScreenEnabled && GameMain.FirstLoad)
{
loadText = "QUICKSTARTING ...";
}
else
{
#endif
loadText = TextManager.Get("PressAnyKey");
#if DEBUG
}
#endif
loadText = "QUICKSTARTING ...";
}
else
{
loadText = TextManager.Get("Loading");
if (LoadState != null)
{
loadText += " " + (int)LoadState + " %";
#endif
loadText = TextManager.Get("PressAnyKey");
#if DEBUG
}
#endif
}
else
{
loadText = TextManager.Get("Loading");
if (LoadState != null)
{
loadText += " " + (int)LoadState + " %";
#if DEBUG
if (GameMain.FirstLoad && GameMain.CancelQuickStart)
{
loadText += " (Quickstart aborted)";
}
#endif
if (GameMain.FirstLoad && GameMain.CancelQuickStart)
{
loadText += " (Quickstart aborted)";
}
}
if (GUI.LargeFont != null)
{
GUI.LargeFont.DrawString(spriteBatch, loadText.ToUpper(),
new Vector2(GameMain.GraphicsWidth / 2.0f - GUI.LargeFont.MeasureString(loadText.ToUpper()).X / 2.0f, GameMain.GraphicsHeight * 0.75f),
Color.White);
#endif
}
}
if (GUI.Font != null && selectedTip != null)
if (GUIStyle.LargeFont.HasValue)
{
if (selectedTipRichTextUnparsed)
{
selectedTipRichTextData = RichTextData.GetRichTextData(selectedTip, out selectedTip);
selectedTipRichTextUnparsed = false;
}
GUIStyle.LargeFont.DrawString(spriteBatch, loadText.ToUpper(),
new Vector2(GameMain.GraphicsWidth / 2.0f - GUIStyle.LargeFont.MeasureString(loadText.ToUpper()).X / 2.0f, GameMain.GraphicsHeight * 0.75f),
Color.White);
}
string wrappedTip = ToolBox.WrapText(selectedTip, GameMain.GraphicsWidth * 0.5f, GUI.Font);
if (GUIStyle.Font.HasValue && selectedTip != null)
{
string wrappedTip = ToolBox.WrapText(selectedTip.SanitizedValue, GameMain.GraphicsWidth * 0.5f, GUIStyle.Font.Value);
string[] lines = wrappedTip.Split('\n');
float lineHeight = GUI.Font.MeasureString(selectedTip).Y;
float lineHeight = GUIStyle.Font.MeasureString(selectedTip).Y;
if (selectedTipRichTextData != null)
if (selectedTip.RichTextData != null)
{
int rtdOffset = 0;
for (int i = 0; i < lines.Length; i++)
{
GUI.Font.DrawStringWithColors(spriteBatch, lines[i],
new Vector2((int)(GameMain.GraphicsWidth / 2.0f - GUI.Font.MeasureString(lines[i]).X / 2.0f), (int)(GameMain.GraphicsHeight * 0.8f + i * lineHeight)), Color.White,
0f, Vector2.Zero, 1f, SpriteEffects.None, 0f, selectedTipRichTextData, rtdOffset);
GUIStyle.Font.DrawStringWithColors(spriteBatch, lines[i],
new Vector2((int)(GameMain.GraphicsWidth / 2.0f - GUIStyle.Font.MeasureString(lines[i]).X / 2.0f), (int)(GameMain.GraphicsHeight * 0.8f + i * lineHeight)), Color.White,
0f, Vector2.Zero, 1f, SpriteEffects.None, 0f, selectedTip.RichTextData.Value, rtdOffset);
rtdOffset += lines[i].Length;
}
}
@@ -255,8 +245,8 @@ namespace Barotrauma
{
for (int i = 0; i < lines.Length; i++)
{
GUI.Font.DrawString(spriteBatch, lines[i],
new Vector2((int)(GameMain.GraphicsWidth / 2.0f - GUI.Font.MeasureString(lines[i]).X / 2.0f), (int)(GameMain.GraphicsHeight * 0.8f + i * lineHeight)), Color.White);
GUIStyle.Font.DrawString(spriteBatch, lines[i],
new Vector2((int)(GameMain.GraphicsWidth / 2.0f - GUIStyle.Font.MeasureString(lines[i]).X / 2.0f), (int)(GameMain.GraphicsHeight * 0.8f + i * lineHeight)), Color.White);
}
}
}
@@ -280,7 +270,7 @@ namespace Barotrauma
if (noiseVal < 0.2f)
{
//SCP-CB reference
randText = (new string[] { "NIL", "black white gray", "Sometimes we would have had time to scream", "e8m106]af", "NO" }).GetRandom();
randText = (new string[] { "NIL", "black white gray", "Sometimes we would have had time to scream", "e8m106]af", "NO" }).GetRandomUnsynced();
}
else if (noiseVal < 0.3f)
{
@@ -295,15 +285,20 @@ namespace Barotrauma
Rand.Int(100).ToString().PadLeft(2, '0');
}
GUI.LargeFont?.DrawString(spriteBatch, randText,
new Vector2(GameMain.GraphicsWidth - decorativeMap.FrameSize.X * decorativeScale.X * 0.8f, GameMain.GraphicsHeight * 0.57f),
Color.White * (1.0f - noiseVal));
if (GUIStyle.LargeFont.HasValue)
{
GUIStyle.LargeFont.DrawString(spriteBatch, randText,
new Vector2(GameMain.GraphicsWidth - decorativeMap.FrameSize.X * decorativeScale.X * 0.8f, GameMain.GraphicsHeight * 0.57f),
Color.White * (1.0f - noiseVal));
}
spriteBatch.End();
}
private void DrawLanguageSelectionPrompt(SpriteBatch spriteBatch, GraphicsDevice graphicsDevice)
{
if (AvailableLanguages is null) { return; }
if (languageSelectionFont == null)
{
languageSelectionFont = new ScalableFont("Content/Fonts/NotoSans/NotoSans-Bold.ttf",
@@ -320,8 +315,8 @@ namespace Barotrauma
}
Vector2 textPos = new Vector2(GameMain.GraphicsWidth / 2, GameMain.GraphicsHeight * 0.3f);
Vector2 textSpacing = new Vector2(0.0f, (GameMain.GraphicsHeight * 0.5f) / TextManager.AvailableLanguages.Count());
foreach (string language in TextManager.AvailableLanguages)
Vector2 textSpacing = new Vector2(0.0f, (GameMain.GraphicsHeight * 0.5f) / AvailableLanguages.Length);
foreach (LanguageIdentifier language in AvailableLanguages)
{
string localizedLanguageName = TextManager.GetTranslatedLanguageName(language);
var font = TextManager.IsCJK(localizedLanguageName) ? languageSelectionFontCJK : languageSelectionFont;
@@ -335,11 +330,11 @@ namespace Barotrauma
hover ? Color.White : Color.White * 0.6f);
if (hover && PlayerInput.PrimaryMouseButtonClicked())
{
GameMain.Config.Language = language;
var config = GameSettings.CurrentConfig;
config.Language = language;
GameSettings.SetCurrentConfig(config);
//reload tip in the selected language
SetSelectedTip(TextManager.Get("LoadingScreenTip", true));
GameMain.Config.SetDefaultBindings(legacy: false);
GameMain.Config.CheckBindings(useDefaults: true);
SetSelectedTip(TextManager.Get("LoadingScreenTip"));
WaitForLanguageSelection = false;
languageSelectionFont?.Dispose(); languageSelectionFont = null;
languageSelectionFontCJK?.Dispose(); languageSelectionFontCJK = null;
@@ -368,7 +363,7 @@ namespace Barotrauma
}
catch (Exception e)
{
GameMain.Config.EnableSplashScreen = false;
DisableSplashScreen();
DebugConsole.ThrowError("Playing the splash screen \"" + fileName + "\" failed.", e);
PendingSplashScreens.Clear();
currSplashScreen = null;
@@ -425,13 +420,20 @@ namespace Barotrauma
}
}
private void DisableSplashScreen()
{
var config = GameSettings.CurrentConfig;
config.EnableSplashScreen = false;
GameSettings.SetCurrentConfig(config);
}
bool drawn;
public IEnumerable<CoroutineStatus> DoLoading(IEnumerable<CoroutineStatus> loader)
{
drawn = false;
LoadState = null;
SetSelectedTip(TextManager.Get("LoadingScreenTip", true));
currentBackgroundTexture = LocationType.List.GetRandom()?.GetPortrait(Rand.Int(int.MaxValue))?.Texture;
SetSelectedTip(TextManager.Get("LoadingScreenTip"));
currentBackgroundTexture = LocationType.Prefabs.GetRandomUnsynced()?.GetPortrait(Rand.Int(int.MaxValue))?.Texture;
while (!drawn)
{
@@ -50,7 +50,7 @@ namespace Barotrauma
Afflictions = new List<PendingAfflictionElement>();
}
public PendingAfflictionElement? FindAfflictionElement(MedicalClinic.NetAffliction target) => Afflictions.FirstOrNull(element => element.Target.Identifier.Equals(target.Identifier, StringComparison.OrdinalIgnoreCase));
public PendingAfflictionElement? FindAfflictionElement(MedicalClinic.NetAffliction target) => Afflictions.FirstOrNull(element => element.Target.Identifier == target.Identifier);
}
// Represents an affliction on the left side crew entry
@@ -269,11 +269,11 @@ namespace Barotrauma
int totalCost = medicalClinic.GetTotalCost();
healList.PriceBlock.Text = UpgradeStore.FormatCurrency(totalCost);
healList.PriceBlock.TextColor = GUI.Style.Red;
healList.PriceBlock.TextColor = GUIStyle.Red;
healList.HealButton.Enabled = false;
if (medicalClinic.GetMoney() > totalCost)
{
healList.PriceBlock.TextColor = GUI.Style.TextColor;
healList.PriceBlock.TextColor = GUIStyle.TextColorNormal;
if (medicalClinic.PendingHeals.Any())
{
healList.HealButton.Enabled = true;
@@ -443,7 +443,7 @@ namespace Barotrauma
GUILayoutGroup clinicLabelLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.1f), clinicContent.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
GUIImage clinicIcon = new GUIImage(new RectTransform(Vector2.One, clinicLabelLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "CrewManagementHeaderIcon", scaleToFit: true);
GUITextBlock clinicLabel = new GUITextBlock(new RectTransform(Vector2.One, clinicLabelLayout.RectTransform), TextManager.Get("medicalclinic.medicalclinic"), font: GUI.LargeFont);
GUITextBlock clinicLabel = new GUITextBlock(new RectTransform(Vector2.One, clinicLabelLayout.RectTransform), TextManager.Get("medicalclinic.medicalclinic"), font: GUIStyle.LargeFont);
GUIFrame clinicBackground = new GUIFrame(new RectTransform(Vector2.One, clinicContent.RectTransform));
@@ -459,13 +459,13 @@ namespace Barotrauma
};
GUILayoutGroup balanceLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.1f), crewContent.RectTransform));
GUITextBlock balanceLabel = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), balanceLayout.RectTransform), TextManager.Get("campaignstore.balance"), textAlignment: Alignment.BottomRight, font: GUI.Font)
GUITextBlock balanceLabel = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), balanceLayout.RectTransform), TextManager.Get("campaignstore.balance"), textAlignment: Alignment.BottomRight, font: GUIStyle.Font)
{
AutoScaleVertical = true,
ForceUpperCase = true
ForceUpperCase = ForceUpperCase.Yes
};
GUITextBlock moneyLabel = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), balanceLayout.RectTransform), string.Empty, textAlignment: Alignment.TopRight, font: GUI.Style.SubHeadingFont)
GUITextBlock moneyLabel = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), balanceLayout.RectTransform), string.Empty, textAlignment: Alignment.TopRight, font: GUIStyle.SubHeadingFont)
{
TextGetter = () => UpgradeStore.FormatCurrency(medicalClinic.GetMoney()),
AutoScaleVertical = true,
@@ -519,18 +519,18 @@ namespace Barotrauma
GUILayoutGroup healthLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.1f, 1f), crewLayout.RectTransform), isHorizontal: true, Anchor.Center);
new GUITextBlock(new RectTransform(Vector2.One, healthLayout.RectTransform), string.Empty, textAlignment: Alignment.Center, font: GUI.SubHeadingFont)
new GUITextBlock(new RectTransform(Vector2.One, healthLayout.RectTransform), string.Empty, textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont)
{
TextGetter = () => $"{(int)(info.Character?.HealthPercentage ?? 100f)}%",
TextColor = GUI.Style.Green
TextColor = GUIStyle.Green
};
GUITextBlock overflowIndicator =
new GUITextBlock(new RectTransform(new Vector2(0.25f, 1f), afflictionList.Content.RectTransform, scaleBasis: ScaleBasis.BothHeight), text: "+", textAlignment: Alignment.Center, font: GUI.LargeFont)
new GUITextBlock(new RectTransform(new Vector2(0.25f, 1f), afflictionList.Content.RectTransform, scaleBasis: ScaleBasis.BothHeight), text: "+", textAlignment: Alignment.Center, font: GUIStyle.LargeFont)
{
Visible = false,
CanBeFocused = false,
TextColor = GUI.Style.Red
TextColor = GUIStyle.Red
};
MedicalClinic.NetCrewMember member = new MedicalClinic.NetCrewMember { CharacterInfo = info, Afflictions = Array.Empty<MedicalClinic.NetAffliction>() };
@@ -552,13 +552,13 @@ namespace Barotrauma
Stretch = true
};
new GUITextBlock(new RectTransform(new Vector2(1f, 0.05f), pendingHealContainer.RectTransform), TextManager.Get("medicalclinic.pendingheals"), font: GUI.SubHeadingFont);
new GUITextBlock(new RectTransform(new Vector2(1f, 0.05f), pendingHealContainer.RectTransform), TextManager.Get("medicalclinic.pendingheals"), font: GUIStyle.SubHeadingFont);
GUIFrame healListContainer = new GUIFrame(new RectTransform(new Vector2(1f, 0.9f), pendingHealContainer.RectTransform), style: null);
GUITextBlock? errorBlock = null;
if (!GameMain.IsSingleplayer)
{
errorBlock = new GUITextBlock(new RectTransform(Vector2.One, healListContainer.RectTransform), text: TextManager.Get("pleasewaitupnp"), font: GUI.LargeFont, textAlignment: Alignment.Center);
errorBlock = new GUITextBlock(new RectTransform(Vector2.One, healListContainer.RectTransform), text: TextManager.Get("pleasewaitupnp"), font: GUIStyle.LargeFont, textAlignment: Alignment.Center);
}
GUIListBox healList = new GUIListBox(new RectTransform(Vector2.One, healListContainer.RectTransform))
@@ -571,7 +571,7 @@ namespace Barotrauma
GUILayoutGroup priceLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), footerLayout.RectTransform), isHorizontal: true);
GUITextBlock priceLabelBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), priceLayout.RectTransform), TextManager.Get("campaignstore.total"));
GUITextBlock priceBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), priceLayout.RectTransform), UpgradeStore.FormatCurrency(medicalClinic.GetTotalCost()), font: GUI.SubHeadingFont,
GUITextBlock priceBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), priceLayout.RectTransform), UpgradeStore.FormatCurrency(medicalClinic.GetTotalCost()), font: GUIStyle.SubHeadingFont,
textAlignment: Alignment.Right);
GUILayoutGroup buttonLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), footerLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterRight);
@@ -679,12 +679,12 @@ namespace Barotrauma
GUILayoutGroup textLayout = new GUILayoutGroup(new RectTransform(Vector2.One, parentLayout.RectTransform), isHorizontal: true);
string name = prefab.Name;
LocalizedString name = prefab.Name;
GUIFrame textContainer = new GUIFrame(new RectTransform(new Vector2(0.6f, 1f), textLayout.RectTransform), style: null);
GUITextBlock afflictionName = new GUITextBlock(new RectTransform(Vector2.One, textContainer.RectTransform), name, font: GUI.SubHeadingFont);
GUITextBlock afflictionName = new GUITextBlock(new RectTransform(Vector2.One, textContainer.RectTransform), name, font: GUIStyle.SubHeadingFont);
GUITextBlock healCost = new GUITextBlock(new RectTransform(new Vector2(0.2f, 1f), textLayout.RectTransform), UpgradeStore.FormatCurrency(affliction.Price), textAlignment: Alignment.Center, font: GUI.LargeFont)
GUITextBlock healCost = new GUITextBlock(new RectTransform(new Vector2(0.2f, 1f), textLayout.RectTransform), UpgradeStore.FormatCurrency(affliction.Price), textAlignment: Alignment.Center, font: GUIStyle.LargeFont)
{
Padding = Vector4.Zero
};
@@ -702,7 +702,7 @@ namespace Barotrauma
}
};
EnsureTextDoesntOverflow(name, afflictionName, textContainer.Rect, ImmutableArray.Create(textLayout, parentLayout));
EnsureTextDoesntOverflow(name.Value, afflictionName, textContainer.Rect, ImmutableArray.Create(textLayout, parentLayout));
healElement.Afflictions.Add(new PendingAfflictionElement(affliction, backgroundFrame, healCost));
@@ -720,8 +720,8 @@ namespace Barotrauma
GUILayoutGroup textGroup = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.8f), parent.RectTransform));
string? characterName = info.Name,
jobName = null;
string? characterName = info.Name;
LocalizedString? jobName = null;
GUITextBlock? nameBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), textGroup.RectTransform), characterName),
jobBlock = null;
@@ -741,7 +741,7 @@ namespace Barotrauma
if (jobBlock is null) { return; }
EnsureTextDoesntOverflow(jobName, jobBlock, parent.Rect, layoutGroups);
EnsureTextDoesntOverflow(jobName?.Value, jobBlock, parent.Rect, layoutGroups);
}
}
@@ -766,14 +766,14 @@ namespace Barotrauma
mainFrame.RectTransform.ScreenSpaceOffset = new Point((int)location.X, GameMain.GraphicsHeight - mainFrame.Rect.Height);
}
GUITextBlock feedbackBlock = new GUITextBlock(new RectTransform(Vector2.One, mainFrame.RectTransform), TextManager.Get("pleasewaitupnp"), textAlignment: Alignment.Center, font: GUI.LargeFont, wrap: true)
GUITextBlock feedbackBlock = new GUITextBlock(new RectTransform(Vector2.One, mainFrame.RectTransform), TextManager.Get("pleasewaitupnp"), textAlignment: Alignment.Center, font: GUIStyle.LargeFont, wrap: true)
{
Visible = true
};
GUIButton treatAllButton = new GUIButton(new RectTransform(new Vector2(1f, 0.2f), mainLayout.RectTransform), TextManager.Get("medicalclinic.treatall"))
{
Font = GUI.SubHeadingFont,
Font = GUIStyle.SubHeadingFont,
Visible = false
};
@@ -793,7 +793,7 @@ namespace Barotrauma
if (request.Result != MedicalClinic.RequestResult.Success)
{
feedbackBlock.Text = GetErrorText(request.Result);
feedbackBlock.TextColor = GUI.Style.Red;
feedbackBlock.TextColor = GUIStyle.Red;
return;
}
@@ -844,11 +844,11 @@ namespace Barotrauma
GUILayoutGroup topTextLayout = new GUILayoutGroup(new RectTransform(Vector2.One, topLayout.RectTransform), isHorizontal: true);
GUITextBlock prefabBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), topTextLayout.RectTransform), prefab.Name, font: GUI.SubHeadingFont);
GUITextBlock prefabBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), topTextLayout.RectTransform), prefab.Name, font: GUIStyle.SubHeadingFont);
Color textColor = Color.Lerp(GUI.Style.Orange, GUI.Style.Red, (int)affliction.AfflictionSeverity / 2f);
Color textColor = Color.Lerp(GUIStyle.Orange, GUIStyle.Red, (int)affliction.AfflictionSeverity / 2f);
string vitalityText = TextManager.GetWithVariable("medicalclinic.vitalitydifference", "[amount]", (-affliction.Strength).ToString());
LocalizedString vitalityText = TextManager.GetWithVariable("medicalclinic.vitalitydifference", "[amount]", (-affliction.Strength).ToString());
GUITextBlock vitalityBlock = new GUITextBlock(new RectTransform(new Vector2(0.25f, 1f), topTextLayout.RectTransform), vitalityText, textAlignment: Alignment.Center)
{
TextColor = textColor,
@@ -857,8 +857,8 @@ namespace Barotrauma
AutoScaleHorizontal = true
};
string severityText = TextManager.Get($"AfflictionStrength{affliction.AfflictionSeverity}");
GUITextBlock severityBlock = new GUITextBlock(new RectTransform(new Vector2(0.25f, 1f), topTextLayout.RectTransform), severityText, textAlignment: Alignment.Center, font: GUI.SubHeadingFont)
LocalizedString severityText = TextManager.Get($"AfflictionStrength{affliction.AfflictionSeverity}");
GUITextBlock severityBlock = new GUITextBlock(new RectTransform(new Vector2(0.25f, 1f), topTextLayout.RectTransform), severityText, textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont)
{
TextColor = textColor,
DisabledTextColor = textColor * 0.5f,
@@ -866,17 +866,17 @@ namespace Barotrauma
AutoScaleHorizontal = true
};
EnsureTextDoesntOverflow(prefab.Name, prefabBlock, prefabBlock.Rect, ImmutableArray.Create(mainLayout, topLayout, topTextLayout));
EnsureTextDoesntOverflow(prefab.Name.Value, prefabBlock, prefabBlock.Rect, ImmutableArray.Create(mainLayout, topLayout, topTextLayout));
GUILayoutGroup bottomLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.66f), mainLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
GUILayoutGroup bottomTextLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 1f), bottomLayout.RectTransform));
GUITextBlock descriptionBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), bottomTextLayout.RectTransform), ToolBox.LimitString(prefab.Description, GUI.IntScale(64)), wrap: true)
GUITextBlock descriptionBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), bottomTextLayout.RectTransform), ToolBox.LimitString(prefab.Description, GUIStyle.Font, GUI.IntScale(64)), wrap: true)
{
ToolTip = prefab.Description
};
GUITextBlock priceBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), bottomTextLayout.RectTransform), UpgradeStore.FormatCurrency(affliction.Price), font: GUI.LargeFont);
GUITextBlock priceBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), bottomTextLayout.RectTransform), UpgradeStore.FormatCurrency(affliction.Price), font: GUIStyle.LargeFont);
GUIButton buyButton = new GUIButton(new RectTransform(new Vector2(0.2f, 0.75f), bottomLayout.RectTransform), style: "CrewManagementAddButton");
@@ -968,7 +968,7 @@ namespace Barotrauma
if (GameMain.IsSingleplayer || !(pendingHealList is { ErrorBlock: { } errorBlock, HealList: { } healList })) { return; }
errorBlock.Visible = true;
errorBlock.TextColor = GUI.Style.TextColor;
errorBlock.TextColor = GUIStyle.TextColorNormal;
errorBlock.Text = TextManager.Get("pleasewaitupnp");
healList.Visible = false;
@@ -983,7 +983,7 @@ namespace Barotrauma
if (request.Result != MedicalClinic.RequestResult.Success)
{
errorBlock.Text = GetErrorText(request.Result);
errorBlock.TextColor = GUI.Style.Red;
errorBlock.TextColor = GUIStyle.Red;
return;
}
@@ -1011,7 +1011,7 @@ namespace Barotrauma
selectedCrewAfflictionList = null;
}
private static string GetErrorText(MedicalClinic.RequestResult result)
private static LocalizedString GetErrorText(MedicalClinic.RequestResult result)
{
return result switch
{
@@ -10,6 +10,25 @@ namespace Barotrauma
{
class Store
{
class ItemQuantity
{
public int Total { get; private set; }
public int NonEmpty { get; private set; }
public bool AllNonEmpty => NonEmpty == Total;
public ItemQuantity(int total, bool areNonEmpty = true)
{
Total = total;
NonEmpty = areNonEmpty ? total : 0;
}
public void Add(int amount, bool areNonEmpty)
{
Total += amount;
if (areNonEmpty) { NonEmpty += amount; }
}
}
private readonly CampaignUI campaignUI;
private readonly GUIComponent parentComponent;
private readonly List<GUIButton> storeTabButtons = new List<GUIButton>();
@@ -44,7 +63,7 @@ namespace Barotrauma
private Point resolutionWhenCreated;
private Dictionary<ItemPrefab, int> OwnedItems { get; } = new Dictionary<ItemPrefab, int>();
private Dictionary<ItemPrefab, ItemQuantity> OwnedItems { get; } = new Dictionary<ItemPrefab, ItemQuantity>();
private CargoManager CargoManager => campaignUI.Campaign.CargoManager;
private Location CurrentLocation => campaignUI.Campaign.Map?.CurrentLocation;
@@ -302,10 +321,10 @@ namespace Barotrauma
};
var imageWidth = (float)headerGroup.Rect.Height / headerGroup.Rect.Width;
new GUIImage(new RectTransform(new Vector2(imageWidth, 1.0f), headerGroup.RectTransform), "StoreTradingIcon");
new GUITextBlock(new RectTransform(new Vector2(1.0f - imageWidth, 1.0f), headerGroup.RectTransform), TextManager.Get("store"), font: GUI.LargeFont)
new GUITextBlock(new RectTransform(new Vector2(1.0f - imageWidth, 1.0f), headerGroup.RectTransform), TextManager.Get("store"), font: GUIStyle.LargeFont)
{
CanBeFocused = false,
ForceUpperCase = true
ForceUpperCase = ForceUpperCase.Yes
};
// Merchant balance ------------------------------------------------
@@ -319,13 +338,13 @@ namespace Barotrauma
RelativeSpacing = 0.005f
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), merchantBalanceContainer.RectTransform),
TextManager.Get("campaignstore.storebalance"), font: GUI.Font, textAlignment: Alignment.BottomLeft)
TextManager.Get("campaignstore.storebalance"), font: GUIStyle.Font, textAlignment: Alignment.BottomLeft)
{
AutoScaleVertical = true,
ForceUpperCase = true
ForceUpperCase = ForceUpperCase.Yes
};
merchantBalanceBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), merchantBalanceContainer.RectTransform),
"", font: GUI.SubHeadingFont)
"", font: GUIStyle.SubHeadingFont)
{
AutoScaleVertical = true,
TextScale = 1.1f,
@@ -343,11 +362,11 @@ namespace Barotrauma
RelativeSpacing = 0.005f
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), sellValueContainer.RectTransform),
TextManager.Get("campaignstore.sellvalue"), font: GUI.Font, textAlignment: Alignment.BottomLeft)
TextManager.Get("campaignstore.sellvalue"), font: GUIStyle.Font, textAlignment: Alignment.BottomLeft)
{
AutoScaleVertical = true,
CanBeFocused = false,
ForceUpperCase = true
ForceUpperCase = ForceUpperCase.Yes
};
var valueChangeGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), sellValueContainer.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft)
@@ -356,9 +375,9 @@ namespace Barotrauma
RelativeSpacing = 0.02f
};
float blockWidth = GUI.IsFourByThree() ? 0.32f : 0.28f;
Point blockMaxSize = new Point((int)(GameSettings.TextScale * 60), valueChangeGroup.Rect.Height);
Point blockMaxSize = new Point((int)(GameSettings.CurrentConfig.Graphics.TextScale * 60), valueChangeGroup.Rect.Height);
currentSellValueBlock = new GUITextBlock(new RectTransform(new Vector2(blockWidth, 1.0f), valueChangeGroup.RectTransform) { MaxSize = blockMaxSize },
"", font: GUI.SubHeadingFont)
"", font: GUIStyle.SubHeadingFont)
{
AutoScaleVertical = true,
CanBeFocused = false,
@@ -416,7 +435,7 @@ namespace Barotrauma
Visible = false
};
newSellValueBlock = new GUITextBlock(new RectTransform(new Vector2(blockWidth, 1.0f), valueChangeGroup.RectTransform) { MaxSize = blockMaxSize },
"", font: GUI.SubHeadingFont)
"", font: GUIStyle.SubHeadingFont)
{
AutoScaleVertical = true,
CanBeFocused = false,
@@ -435,7 +454,7 @@ namespace Barotrauma
tabSortingMethods.Clear();
foreach (StoreTab tab in tabs)
{
string text = tab switch
LocalizedString text = tab switch
{
StoreTab.SellSub => TextManager.Get("submarine"),
_ => TextManager.Get("campaignstoretab." + tab)
@@ -591,10 +610,10 @@ namespace Barotrauma
};
imageWidth = (float)headerGroup.Rect.Height / headerGroup.Rect.Width;
new GUIImage(new RectTransform(new Vector2(imageWidth, 1.0f), headerGroup.RectTransform), "StoreShoppingCrateIcon");
new GUITextBlock(new RectTransform(new Vector2(1.0f - imageWidth, 1.0f), headerGroup.RectTransform), TextManager.Get("campaignstore.shoppingcrate"), font: GUI.LargeFont, textAlignment: Alignment.Right)
new GUITextBlock(new RectTransform(new Vector2(1.0f - imageWidth, 1.0f), headerGroup.RectTransform), TextManager.Get("campaignstore.shoppingcrate"), font: GUIStyle.LargeFont, textAlignment: Alignment.Right)
{
CanBeFocused = false,
ForceUpperCase = true
ForceUpperCase = ForceUpperCase.Yes
};
// Player balance ------------------------------------------------
@@ -603,13 +622,13 @@ namespace Barotrauma
RelativeSpacing = 0.005f
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), playerBalanceContainer.RectTransform),
TextManager.Get("campaignstore.balance"), font: GUI.Font, textAlignment: Alignment.BottomRight)
TextManager.Get("campaignstore.balance"), font: GUIStyle.Font, textAlignment: Alignment.BottomRight)
{
AutoScaleVertical = true,
ForceUpperCase = true
ForceUpperCase = ForceUpperCase.Yes
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), playerBalanceContainer.RectTransform),
"", textColor: Color.White, font: GUI.SubHeadingFont, textAlignment: Alignment.TopRight)
"", textColor: Color.White, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.TopRight)
{
AutoScaleVertical = true,
TextScale = 1.1f,
@@ -638,11 +657,11 @@ namespace Barotrauma
{
Stretch = true
};
relevantBalanceName = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), relevantBalanceContainer.RectTransform), "", font: GUI.Font)
relevantBalanceName = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), relevantBalanceContainer.RectTransform), "", font: GUIStyle.Font)
{
CanBeFocused = false
};
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), relevantBalanceContainer.RectTransform), "", textColor: Color.White, font: GUI.SubHeadingFont, textAlignment: Alignment.Right)
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), relevantBalanceContainer.RectTransform), "", textColor: Color.White, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right)
{
CanBeFocused = false,
TextScale = 1.1f,
@@ -653,11 +672,11 @@ namespace Barotrauma
{
Stretch = true
};
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), totalContainer.RectTransform), TextManager.Get("campaignstore.total"), font: GUI.Font)
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), totalContainer.RectTransform), TextManager.Get("campaignstore.total"), font: GUIStyle.Font)
{
CanBeFocused = false
};
shoppingCrateTotal = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), totalContainer.RectTransform), "", font: GUI.SubHeadingFont, textAlignment: Alignment.Right)
shoppingCrateTotal = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), totalContainer.RectTransform), "", font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right)
{
CanBeFocused = false,
TextScale = 1.1f
@@ -666,14 +685,14 @@ namespace Barotrauma
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), shoppingCrateInventoryContainer.RectTransform), isHorizontal: true, childAnchor: Anchor.TopRight);
confirmButton = new GUIButton(new RectTransform(new Vector2(0.35f, 1.0f), buttonContainer.RectTransform))
{
ForceUpperCase = true
ForceUpperCase = ForceUpperCase.Yes
};
SetConfirmButtonBehavior();
clearAllButton = new GUIButton(new RectTransform(new Vector2(0.35f, 1.0f), buttonContainer.RectTransform), TextManager.Get("campaignstore.clearall"))
{
ClickSound = GUISoundType.DecreaseQuantity,
Enabled = HasActiveTabPermissions(),
ForceUpperCase = true,
ForceUpperCase = ForceUpperCase.Yes,
OnClicked = (button, userData) =>
{
if (!HasActiveTabPermissions()) { return false; }
@@ -694,9 +713,9 @@ namespace Barotrauma
resolutionWhenCreated = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
}
private string GetMerchantBalanceText() => GetCurrencyFormatted(CurrentLocation?.StoreCurrentBalance ?? 0);
private LocalizedString GetMerchantBalanceText() => GetCurrencyFormatted(CurrentLocation?.StoreCurrentBalance ?? 0);
private string GetPlayerBalanceText() => GetCurrencyFormatted(PlayerMoney);
private LocalizedString GetPlayerBalanceText() => GetCurrencyFormatted(PlayerMoney);
private GUILayoutGroup CreateDealsGroup(GUIListBox parentList, int elementCount = 4)
{
@@ -709,7 +728,7 @@ namespace Barotrauma
var iconWidth = (0.9f * dealsHeader.Rect.Height) / dealsHeader.Rect.Width;
var dealsIcon = new GUIImage(new RectTransform(new Vector2(iconWidth, 0.9f), dealsHeader.RectTransform), "StoreDealIcon", scaleToFit: true);
var text = TextManager.Get(parentList == storeBuyList ? "campaignstore.dailyspecials" : "campaignstore.requestedgoods");
var dealsText = new GUITextBlock(new RectTransform(new Vector2(1.0f - iconWidth, 0.9f), dealsHeader.RectTransform), text, font: GUI.LargeFont);
var dealsText = new GUITextBlock(new RectTransform(new Vector2(1.0f - iconWidth, 0.9f), dealsHeader.RectTransform), text, font: GUIStyle.LargeFont);
storeSpecialColor = dealsIcon.Color;
dealsText.TextColor = storeSpecialColor;
var divider = new GUIImage(new RectTransform(new Point(dealsGroup.Rect.Width, 3), dealsGroup.RectTransform), "HorizontalLine");
@@ -811,7 +830,7 @@ namespace Barotrauma
child.Visible =
(IsBuying || item.Quantity > 0) &&
(!category.HasValue || item.ItemPrefab.Category.HasFlag(category.Value)) &&
(string.IsNullOrEmpty(filter) || item.ItemPrefab.Name.ToLower().Contains(filter));
(string.IsNullOrEmpty(filter) || item.ItemPrefab.Name.Contains(filter, StringComparison.OrdinalIgnoreCase));
}
foreach (GUIButton btn in itemCategoryButtons)
{
@@ -892,7 +911,7 @@ namespace Barotrauma
{
(itemFrame.UserData as PurchasedItem).Quantity = quantity;
SetQuantityLabelText(StoreTab.Buy, itemFrame);
SetOwnedLabelText(itemFrame);
SetOwnedText(itemFrame);
SetPriceGetters(itemFrame, true);
}
SetItemFrameStatus(itemFrame, hasPermissions && quantity > 0);
@@ -967,7 +986,7 @@ namespace Barotrauma
{
(itemFrame.UserData as PurchasedItem).Quantity = itemQuantity;
SetQuantityLabelText(StoreTab.Sell, itemFrame);
SetOwnedLabelText(itemFrame);
SetOwnedText(itemFrame);
SetPriceGetters(itemFrame, false);
}
SetItemFrameStatus(itemFrame, hasPermissions && itemQuantity > 0);
@@ -1045,7 +1064,7 @@ namespace Barotrauma
{
(itemFrame.UserData as PurchasedItem).Quantity = itemQuantity;
SetQuantityLabelText(StoreTab.SellSub, itemFrame);
SetOwnedLabelText(itemFrame);
SetOwnedText(itemFrame);
SetPriceGetters(itemFrame, false);
}
SetItemFrameStatus(itemFrame, hasPermissions && itemQuantity > 0);
@@ -1185,7 +1204,7 @@ namespace Barotrauma
numInput.Enabled = hasPermissions;
numInput.MaxValueInt = GetMaxAvailable(item.ItemPrefab, tab);
}
SetOwnedLabelText(itemFrame);
SetOwnedText(itemFrame);
SetItemFrameStatus(itemFrame, hasPermissions);
}
existingItemFrames.Add(itemFrame);
@@ -1193,7 +1212,7 @@ namespace Barotrauma
suppressBuySell = true;
if (numInput != null)
{
if (numInput.IntValue != item.Quantity) { itemFrame.Flash(GUI.Style.Green); }
if (numInput.IntValue != item.Quantity) { itemFrame.Flash(GUIStyle.Green); }
numInput.IntValue = item.Quantity;
}
suppressBuySell = false;
@@ -1421,14 +1440,8 @@ namespace Barotrauma
width = parentComponent.Rect.Width;
parent = parentComponent.RectTransform;
}
string tooltip = pi.ItemPrefab.Name;
if (!string.IsNullOrWhiteSpace(pi.ItemPrefab.Description))
{
tooltip += $"\n{pi.ItemPrefab.Description}";
}
GUIFrame frame = new GUIFrame(new RectTransform(new Point(width, (int)(GUI.yScale * 80)), parent: parent), style: "ListBoxElement")
{
ToolTip = tooltip,
UserData = pi
};
@@ -1443,7 +1456,7 @@ namespace Barotrauma
var iconRelativeWidth = 0.0f;
var priceAndButtonRelativeWidth = 1.0f - nameAndIconRelativeWidth;
if ((pi.ItemPrefab.InventoryIcon ?? pi.ItemPrefab.sprite) is { } itemIcon)
if ((pi.ItemPrefab.InventoryIcon ?? pi.ItemPrefab.Sprite) is { } itemIcon)
{
iconRelativeWidth = (0.9f * mainGroup.Rect.Height) / mainGroup.Rect.Width;
GUIImage img = new GUIImage(new RectTransform(new Vector2(iconRelativeWidth, 0.9f), mainGroup.RectTransform), itemIcon, scaleToFit: true)
@@ -1468,7 +1481,7 @@ namespace Barotrauma
bool locationHasDealOnItem = isSellingRelatedList ?
CurrentLocation.RequestedGoods.Contains(pi.ItemPrefab) : CurrentLocation.DailySpecials.Contains(pi.ItemPrefab);
GUITextBlock nameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.4f), nameAndQuantityGroup.RectTransform),
pi.ItemPrefab.Name, font: GUI.SubHeadingFont, textAlignment: Alignment.BottomLeft)
pi.ItemPrefab.Name, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.BottomLeft)
{
CanBeFocused = false,
Shadow = locationHasDealOnItem,
@@ -1498,7 +1511,7 @@ namespace Barotrauma
if (isParentOnLeftSideOfInterface)
{
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), nameAndQuantityGroup.RectTransform),
CreateQuantityLabelText(containingTab, pi.Quantity), font: GUI.Font, textAlignment: Alignment.BottomLeft)
CreateQuantityLabelText(containingTab, pi.Quantity), font: GUIStyle.Font, textAlignment: Alignment.BottomLeft)
{
CanBeFocused = false,
Shadow = locationHasDealOnItem,
@@ -1545,8 +1558,7 @@ namespace Barotrauma
var rectTransform = shoppingCrateAmountGroup == null ?
new RectTransform(new Vector2(1.0f, 0.3f), nameAndQuantityGroup.RectTransform) :
new RectTransform(new Vector2(0.6f, 1.0f), shoppingCrateAmountGroup.RectTransform);
new GUITextBlock(rectTransform, CreateOwnedLabelText(OwnedItems.GetValueOrDefault(pi.ItemPrefab, 0)), font: GUI.Font,
textAlignment: shoppingCrateAmountGroup == null ? Alignment.TopLeft : Alignment.CenterLeft)
var ownedLabel = new GUITextBlock(rectTransform, string.Empty, font: GUIStyle.Font, textAlignment: shoppingCrateAmountGroup == null ? Alignment.TopLeft : Alignment.CenterLeft)
{
CanBeFocused = false,
Shadow = locationHasDealOnItem,
@@ -1554,6 +1566,7 @@ namespace Barotrauma
TextScale = 0.85f,
UserData = "owned"
};
SetOwnedText(frame, ownedLabel);
shoppingCrateAmountGroup?.Recalculate();
var buttonRelativeWidth = (0.9f * mainGroup.Rect.Height) / mainGroup.Rect.Width;
@@ -1563,7 +1576,7 @@ namespace Barotrauma
CanBeFocused = false
};
var priceBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), priceFrame.RectTransform, anchor: Anchor.Center),
"0 MK", font: GUI.SubHeadingFont, textAlignment: Alignment.Right)
"0 MK", font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right)
{
CanBeFocused = false,
TextColor = locationHasDealOnItem ? storeSpecialColor : Color.White,
@@ -1577,7 +1590,7 @@ namespace Barotrauma
new RectTransform(new Vector2(1.0f, 0.25f), priceFrame.RectTransform, anchor: Anchor.Center)
{
AbsoluteOffset = new Point(0, priceBlock.RectTransform.ScaledSize.Y)
}, "", font: GUI.SmallFont, textAlignment: Alignment.Center)
}, "", font: GUIStyle.SmallFont, textAlignment: Alignment.Center)
{
CanBeFocused = false,
Strikethrough = new GUITextBlock.StrikethroughSettings(color: priceBlock.TextColor, expand: 1),
@@ -1593,7 +1606,7 @@ namespace Barotrauma
{
ClickSound = GUISoundType.IncreaseQuantity,
Enabled = !forceDisable && pi.Quantity > 0,
ForceUpperCase = true,
ForceUpperCase = ForceUpperCase.Yes,
UserData = "addbutton",
OnClicked = (button, userData) => AddToShoppingCrate(pi)
};
@@ -1604,7 +1617,7 @@ namespace Barotrauma
{
ClickSound = GUISoundType.DecreaseQuantity,
Enabled = !forceDisable,
ForceUpperCase = true,
ForceUpperCase = ForceUpperCase.Yes,
UserData = "removebutton",
OnClicked = (button, userData) => ClearFromShoppingCrate(pi)
};
@@ -1639,7 +1652,7 @@ namespace Barotrauma
if (!subItem.Components.All(c => !(c is Holdable h) || !h.Attachable || !h.Attached)) { continue; }
if (!subItem.Components.All(c => !(c is Wire w) || w.Connections.All(c => c == null))) { continue; }
if (!ItemAndAllContainersInteractable(subItem)) { continue; }
AddToOwnedItems(subItem.Prefab);
AddOwnedItem(subItem);
}
}
@@ -1650,11 +1663,11 @@ namespace Barotrauma
var rootInventoryOwner = item.GetRootInventoryOwner();
var ownedByCrewMember = GameMain.GameSession.CrewManager.GetCharacters().Any(c => c == rootInventoryOwner);
if (!ownedByCrewMember) { continue; }
AddToOwnedItems(item.Prefab);
AddOwnedItem(item);
}
// Add items already purchased
CargoManager?.PurchasedItems?.ForEach(pi => AddToOwnedItems(pi.ItemPrefab, amount: pi.Quantity));
CargoManager?.PurchasedItems?.ForEach(pi => AddNonEmptyOwnedItems(pi));
ownedItemsUpdateTimer = 0.0f;
@@ -1668,15 +1681,30 @@ namespace Barotrauma
return true;
}
void AddToOwnedItems(ItemPrefab itemPrefab, int amount = 1)
void AddOwnedItem(Item item)
{
if (OwnedItems.ContainsKey(itemPrefab))
if (!(item?.Prefab.GetPriceInfo(CurrentLocation) is PriceInfo priceInfo)) { return; }
bool isNonEmpty = !priceInfo.DisplayNonEmpty || item.ConditionPercentage > 5.0f;
if (OwnedItems.TryGetValue(item.Prefab, out ItemQuantity itemQuantity))
{
OwnedItems[itemPrefab] += amount;
OwnedItems[item.Prefab].Add(1, isNonEmpty);
}
else
{
OwnedItems.Add(itemPrefab, amount);
OwnedItems.Add(item.Prefab, new ItemQuantity(1, areNonEmpty: isNonEmpty));
}
}
void AddNonEmptyOwnedItems(PurchasedItem purchasedItem)
{
if (purchasedItem == null) { return; }
if (OwnedItems.TryGetValue(purchasedItem.ItemPrefab, out ItemQuantity itemQuantity))
{
OwnedItems[purchasedItem.ItemPrefab].Add(purchasedItem.Quantity, true);
}
else
{
OwnedItems.Add(purchasedItem.ItemPrefab, new ItemQuantity(purchasedItem.Quantity));
}
}
}
@@ -1692,7 +1720,7 @@ namespace Barotrauma
{
icon.Color = pi.ItemPrefab.InventoryIconColor * (enabled ? 1.0f: 0.5f);
}
else if (pi.ItemPrefab?.sprite != null)
else if (pi.ItemPrefab?.Sprite != null)
{
icon.Color = pi.ItemPrefab.SpriteColor * (enabled ? 1.0f : 0.5f);
}
@@ -1737,35 +1765,89 @@ namespace Barotrauma
itemFrame.UserData = pi;
}
private void SetQuantityLabelText(StoreTab mode, GUIComponent itemFrame)
private static void SetQuantityLabelText(StoreTab mode, GUIComponent itemFrame)
{
if (itemFrame == null) { return; }
if (itemFrame.FindChild("quantitylabel", recursive: true) is GUITextBlock label)
if (itemFrame?.FindChild("quantitylabel", recursive: true) is GUITextBlock label)
{
label.Text = CreateQuantityLabelText(mode, (itemFrame.UserData as PurchasedItem).Quantity);
}
}
private string CreateQuantityLabelText(StoreTab mode, int quantity) => mode != StoreTab.Buy ?
TextManager.GetWithVariable("campaignstore.quantity", "[amount]", quantity.ToString()) :
TextManager.GetWithVariable("campaignstore.instock", "[amount]", quantity.ToString());
private void SetOwnedLabelText(GUIComponent itemComponent)
private static LocalizedString CreateQuantityLabelText(StoreTab mode, int quantity)
{
if (itemComponent == null) { return; }
var itemCount = 0;
if (itemComponent.UserData is PurchasedItem pi)
try
{
itemCount = OwnedItems.GetValueOrDefault(pi.ItemPrefab, itemCount);
string textTag = mode switch
{
StoreTab.Buy => "campaignstore.instock",
StoreTab.Sell => "campaignstore.ownedinventory",
StoreTab.SellSub => "campaignstore.ownedsub",
_ => throw new NotImplementedException()
};
return TextManager.GetWithVariable(textTag, "[amount]", quantity.ToString());
}
if (itemComponent.FindChild("owned", recursive: true) is GUITextBlock label)
catch (NotImplementedException e)
{
label.Text = CreateOwnedLabelText(itemCount);
string errorMsg = $"Error creating a store quantity label text: unknown store tab.\n{e.StackTrace.CleanupStackTrace()}";
#if DEBUG
DebugConsole.ShowError(errorMsg);
#else
DebugConsole.AddWarning(errorMsg);
#endif
}
return string.Empty;
}
private string CreateOwnedLabelText(int itemCount) => itemCount > 0 ?
TextManager.GetWithVariable("campaignstore.owned", "[amount]", itemCount.ToString()) : "";
private void SetOwnedText(GUIComponent itemComponent, GUITextBlock ownedLabel = null)
{
ownedLabel ??= itemComponent?.FindChild("owned", recursive: true) as GUITextBlock;
if (itemComponent == null && ownedLabel == null) { return; }
PurchasedItem purchasedItem = itemComponent?.UserData as PurchasedItem;
ItemQuantity itemQuantity = null;
LocalizedString ownedLabelText = string.Empty;
if (purchasedItem != null && OwnedItems.TryGetValue(purchasedItem.ItemPrefab, out itemQuantity) && itemQuantity.Total > 0)
{
if (itemQuantity.AllNonEmpty)
{
ownedLabelText = TextManager.GetWithVariable("campaignstore.owned", "[amount]", itemQuantity.Total.ToString());
}
else
{
ownedLabelText = TextManager.GetWithVariables("campaignstore.ownedspecific",
("[nonempty]", itemQuantity.NonEmpty.ToString()),
("[total]", itemQuantity.Total.ToString()));
}
}
if (itemComponent != null)
{
LocalizedString toolTip = string.Empty;
if (purchasedItem.ItemPrefab != null)
{
toolTip = purchasedItem.ItemPrefab.Name;
if (!purchasedItem.ItemPrefab.Description.IsNullOrEmpty())
{
toolTip += $"\n{purchasedItem.ItemPrefab.Description}";
}
if (itemQuantity != null)
{
if (itemQuantity.AllNonEmpty)
{
toolTip += $"\n\n{ownedLabelText}";
}
else
{
toolTip += $"\n\n{TextManager.GetWithVariable("campaignstore.ownednonempty", "[amount]", itemQuantity.NonEmpty.ToString())}";
toolTip += $"\n{TextManager.GetWithVariable("campaignstore.ownedtotal", "[amount]", itemQuantity.Total.ToString())}";
}
}
}
itemComponent.ToolTip = toolTip;
}
if (ownedLabel != null)
{
ownedLabel.Text = ownedLabelText;
}
}
private int GetMaxAvailable(ItemPrefab itemPrefab, StoreTab mode)
{
@@ -1799,7 +1881,7 @@ namespace Barotrauma
}
}
private string GetCurrencyFormatted(int amount) =>
private LocalizedString GetCurrencyFormatted(int amount) =>
TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", amount));
private bool ModifyBuyQuantity(PurchasedItem item, int quantity)
@@ -1916,7 +1998,7 @@ namespace Barotrauma
var dialog = new GUIMessageBox(
TextManager.Get("newsupplies"),
TextManager.GetWithVariable("suppliespurchasedmessage", "[location]", campaignUI?.Campaign?.Map?.CurrentLocation?.Name),
new string[] { TextManager.Get("Ok") });
new LocalizedString[] { TextManager.Get("Ok") });
dialog.Buttons[0].OnClicked += dialog.Close;
return false;
@@ -1995,7 +2077,7 @@ namespace Barotrauma
var confirmDialog = new GUIMessageBox(
TextManager.Get("FireWarningHeader"),
TextManager.Get("CampaignStore.SellWarningText"),
new string[] { TextManager.Get("Yes"), TextManager.Get("No") });
new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") });
confirmDialog.Buttons[0].OnClicked = (b, o) => SellItems();
confirmDialog.Buttons[0].OnClicked += confirmDialog.Close;
confirmDialog.Buttons[1].OnClicked = confirmDialog.Close;
@@ -2040,12 +2122,12 @@ namespace Barotrauma
ownedItemsUpdateTimer += deltaTime;
if (ownedItemsUpdateTimer >= timerUpdateInterval)
{
var prevOwnedItems = new Dictionary<ItemPrefab, int>(OwnedItems);
var prevOwnedItems = new Dictionary<ItemPrefab, ItemQuantity>(OwnedItems);
UpdateOwnedItems();
var refresh = (prevOwnedItems.Count != OwnedItems.Count) ||
(prevOwnedItems.Select(kvp => kvp.Value).Sum() != OwnedItems.Select(kvp => kvp.Value).Sum()) ||
(OwnedItems.Any(kvp => kvp.Value > 0 && !prevOwnedItems.ContainsKey(kvp.Key)) ||
prevOwnedItems.Any(kvp => !OwnedItems.TryGetValue(kvp.Key, out var itemCount) || kvp.Value != itemCount));
(prevOwnedItems.Select(kvp => kvp.Value.Total).Sum() != OwnedItems.Select(kvp => kvp.Value.Total).Sum()) ||
(OwnedItems.Any(kvp => kvp.Value.Total > 0 && !prevOwnedItems.ContainsKey(kvp.Key)) ||
prevOwnedItems.Any(kvp => !OwnedItems.TryGetValue(kvp.Key, out ItemQuantity itemQuantity) || kvp.Value.Total != itemQuantity.Total));
if (refresh)
{
needsItemsToSellRefresh = true;
@@ -31,19 +31,12 @@ namespace Barotrauma
private readonly List<SubmarineInfo> subsToShow;
private readonly SubmarineDisplayContent[] submarineDisplays = new SubmarineDisplayContent[submarinesPerPage];
private SubmarineInfo selectedSubmarine = null;
private string purchaseAndSwitchText, purchaseOnlyText, deliveryText, currentSubText, deliveryFeeText, priceText, switchText, missingPreviewText, currencyShorthandText, currencyLongText;
private LocalizedString purchaseAndSwitchText, purchaseOnlyText, deliveryText, currentSubText, deliveryFeeText, priceText, switchText, missingPreviewText, currencyShorthandText, currencyLongText;
private readonly RectTransform parent;
private readonly Action closeAction;
private Sprite pageIndicator;
public static readonly string[] DeliveryTextVariables = new string[] { "[submarinename1]", "[location1]", "[location2]", "[submarinename2]", "[amount]", "[currencyname]" };
public static readonly string[] SwitchTextVariables = new string[] { "[submarinename1]", "[submarinename2]" };
public static readonly string[] PurchaseAndSwitchTextVariables = new string[] { "[submarinename1]", "[amount]", "[currencyname]", "[submarinename2]" };
public static readonly string[] PurchaseTextVariables = new string[] { "[submarinename]", "[amount]", "[currencyname]" };
private static readonly string[] notEnoughCreditsDeliveryTextVariables = new string[] { "[currencyname]", "[submarinename]", "[location1]", "[location2]" };
private static readonly string[] notEnoughCreditsPurchaseTextVariables = new string[] { "[currencyname]", "[submarinename]" };
private readonly string[] messageBoxOptions;
private readonly LocalizedString[] messageBoxOptions;
public const int DeliveryFeePerDistanceTravelled = 1000;
public static bool ContentRefreshRequired = false;
@@ -77,11 +70,11 @@ namespace Barotrauma
if (GameMain.Client == null)
{
messageBoxOptions = new string[2] { TextManager.Get("Yes"), TextManager.Get("Cancel") };
messageBoxOptions = new LocalizedString[2] { TextManager.Get("Yes"), TextManager.Get("Cancel") };
}
else
{
messageBoxOptions = new string[2] { TextManager.Get("Yes") + " " + TextManager.Get("initiatevoting"), TextManager.Get("Cancel") };
messageBoxOptions = new LocalizedString[2] { TextManager.Get("Yes") + " " + TextManager.Get("initiatevoting"), TextManager.Get("Cancel") };
}
if (Submarine.MainSub?.Info == null) { return; }
@@ -107,7 +100,7 @@ namespace Barotrauma
}
currencyShorthandText = TextManager.Get("currencyformat");
currencyLongText = TextManager.Get("credit").ToLower();
currencyLongText = TextManager.Get("credit").Value.ToLowerInvariant();
UpdateSubmarines();
missingPreviewText = TextManager.Get("SubPreviewImageNotFound");
@@ -135,9 +128,9 @@ namespace Barotrauma
};
content = new GUILayoutGroup(new RectTransform(new Point(background.Rect.Width - HUDLayoutSettings.Padding * 4, background.Rect.Height - HUDLayoutSettings.Padding * 4), background.RectTransform, Anchor.Center)) { AbsoluteSpacing = (int)(HUDLayoutSettings.Padding * 1.5f) };
GUITextBlock header = new GUITextBlock(new RectTransform(new Vector2(1f, 0.0f), content.RectTransform), transferService ? TextManager.Get("switchsubmarineheader") : TextManager.GetWithVariable("outpostshipyard", "[location]", GameMain.GameSession.Map.CurrentLocation.Name), font: GUI.LargeFont);
GUITextBlock header = new GUITextBlock(new RectTransform(new Vector2(1f, 0.0f), content.RectTransform), transferService ? TextManager.Get("switchsubmarineheader") : TextManager.GetWithVariable("outpostshipyard", "[location]", GameMain.GameSession.Map.CurrentLocation.Name), font: GUIStyle.LargeFont);
header.CalculateHeightFromText(0, true);
GUITextBlock credits = new GUITextBlock(new RectTransform(Vector2.One, header.RectTransform), "", font: GUI.SubHeadingFont, textAlignment: Alignment.CenterRight)
GUITextBlock credits = new GUITextBlock(new RectTransform(Vector2.One, header.RectTransform), "", font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterRight)
{
TextGetter = CampaignUI.GetMoney
};
@@ -159,7 +152,7 @@ namespace Barotrauma
specsFrame = new GUIListBox(new RectTransform(new Vector2(0.39f, 1f), infoFrame.RectTransform), style: null) { Spacing = GUI.IntScale(5), Padding = new Vector4(HUDLayoutSettings.Padding / 2f, HUDLayoutSettings.Padding, 0, 0) };
new GUIFrame(new RectTransform(new Vector2(0.02f, 0.8f), infoFrame.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.1f) }, style: "VerticalLine");
GUIListBox descriptionFrame = new GUIListBox(new RectTransform(new Vector2(0.59f, 1f), infoFrame.RectTransform), style: null) { Padding = new Vector4(HUDLayoutSettings.Padding / 2f, HUDLayoutSettings.Padding * 1.5f, HUDLayoutSettings.Padding * 1.5f, HUDLayoutSettings.Padding / 2f) };
descriptionTextBlock = new GUITextBlock(new RectTransform(new Vector2(1, 0), descriptionFrame.Content.RectTransform), string.Empty, font: GUI.Font, wrap: true) { CanBeFocused = false };
descriptionTextBlock = new GUITextBlock(new RectTransform(new Vector2(1, 0), descriptionFrame.Content.RectTransform), string.Empty, font: GUIStyle.Font, wrap: true) { CanBeFocused = false };
GUILayoutGroup buttonFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.075f), content.RectTransform), childAnchor: Anchor.CenterRight) { IsHorizontal = true, AbsoluteSpacing = HUDLayoutSettings.Padding };
@@ -180,7 +173,7 @@ namespace Barotrauma
SetConfirmButtonState(false);
pageIndicatorHolder = new GUIFrame(new RectTransform(new Vector2(1f, 1.5f), submarineControlsGroup.RectTransform), style: null);
pageIndicator = GUI.Style.GetComponentStyle("GUIPageIndicator").GetDefaultSprite();
pageIndicator = GUIStyle.GetComponentStyle("GUIPageIndicator").GetDefaultSprite();
UpdatePaging();
for (int i = 0; i < submarineDisplays.Length; i++)
@@ -191,9 +184,9 @@ namespace Barotrauma
};
submarineDisplayElement.submarineImage = new GUIImage(new RectTransform(new Vector2(0.8f, 1f), submarineDisplayElement.background.RectTransform, Anchor.Center), null, true);
submarineDisplayElement.middleTextBlock = new GUITextBlock(new RectTransform(new Vector2(0.8f, 1f), submarineDisplayElement.background.RectTransform, Anchor.Center), string.Empty, textAlignment: Alignment.Center);
submarineDisplayElement.submarineName = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { AbsoluteOffset = new Point(0, HUDLayoutSettings.Padding) }, string.Empty, textAlignment: Alignment.Center, font: GUI.SubHeadingFont);
submarineDisplayElement.submarineClass = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { AbsoluteOffset = new Point(0, HUDLayoutSettings.Padding + (int)GUI.Font.MeasureString(submarineDisplayElement.submarineName.Text).Y) }, string.Empty, textAlignment: Alignment.Center);
submarineDisplayElement.submarineFee = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.BottomCenter, Pivot.BottomCenter) { AbsoluteOffset = new Point(0, HUDLayoutSettings.Padding) }, string.Empty, textAlignment: Alignment.Center, font: GUI.SubHeadingFont);
submarineDisplayElement.submarineName = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { AbsoluteOffset = new Point(0, HUDLayoutSettings.Padding) }, string.Empty, textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont);
submarineDisplayElement.submarineClass = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { AbsoluteOffset = new Point(0, HUDLayoutSettings.Padding + (int)GUIStyle.Font.MeasureString(submarineDisplayElement.submarineName.Text).Y) }, string.Empty, textAlignment: Alignment.Center);
submarineDisplayElement.submarineFee = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.BottomCenter, Pivot.BottomCenter) { AbsoluteOffset = new Point(0, HUDLayoutSettings.Padding) }, string.Empty, textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont);
submarineDisplayElement.selectSubmarineButton = new GUIButton(new RectTransform(Vector2.One, submarineDisplayElement.background.RectTransform), style: null);
submarineDisplayElement.previewButton = new GUIButton(new RectTransform(Vector2.One * 0.12f, submarineDisplayElement.background.RectTransform, anchor: Anchor.BottomRight, pivot: Pivot.BottomRight, scaleBasis: ScaleBasis.BothHeight) { AbsoluteOffset = new Point((int)(0.03f * background.Rect.Height)) }, style: "ExpandButton")
{
@@ -342,7 +335,7 @@ namespace Barotrauma
if (!GameMain.GameSession.IsSubmarineOwned(subToDisplay))
{
string amountString = currencyShorthandText.Replace("[credits]", subToDisplay.Price.ToString());
LocalizedString amountString = currencyShorthandText.Replace("[credits]", subToDisplay.Price.ToString());
submarineDisplays[i].submarineFee.Text = priceText.Replace("[amount]", amountString).Replace("[currencyname]", string.Empty).TrimEnd();
}
else
@@ -351,7 +344,7 @@ namespace Barotrauma
{
if (deliveryFee > 0)
{
string amountString = currencyShorthandText.Replace("[credits]", deliveryFee.ToString());
LocalizedString amountString = currencyShorthandText.Replace("[credits]", deliveryFee.ToString());
submarineDisplays[i].submarineFee.Text = deliveryFeeText.Replace("[amount]", amountString).Replace("[currencyname]", string.Empty).TrimEnd();
}
else
@@ -535,7 +528,7 @@ namespace Barotrauma
listBackground.Sprite = previewImage;
listBackground.SetCrop(true);
ScalableFont font = GUI.Font;
GUIFont font = GUIStyle.Font;
info.CreateSpecsWindow(specsFrame, font);
descriptionTextBlock.Text = info.Description;
descriptionTextBlock.CalculateHeightFromText();
@@ -590,8 +583,11 @@ namespace Barotrauma
{
if (GameMain.GameSession.Campaign.Money < deliveryFee && deliveryFee > 0)
{
new GUIMessageBox(TextManager.Get("deliveryrequestheader"), TextManager.GetWithVariables("notenoughmoneyfordeliverytext", notEnoughCreditsDeliveryTextVariables,
new string[] { currencyLongText, selectedSubmarine.DisplayName, deliveryLocationName, GameMain.GameSession.Map.CurrentLocation.Name }));
new GUIMessageBox(TextManager.Get("deliveryrequestheader"), TextManager.GetWithVariables("notenoughmoneyfordeliverytext",
("[currencyname]", currencyLongText),
("[submarinename]", selectedSubmarine.DisplayName),
("[location1]", deliveryLocationName),
("[location2]", GameMain.GameSession.Map.CurrentLocation.Name)));
return;
}
@@ -599,13 +595,19 @@ namespace Barotrauma
if (deliveryFee > 0)
{
msgBox = new GUIMessageBox(TextManager.Get("deliveryrequestheader"), TextManager.GetWithVariables("deliveryrequesttext", DeliveryTextVariables,
new string[6] { selectedSubmarine.DisplayName, deliveryLocationName, GameMain.GameSession.Map.CurrentLocation.Name, CurrentOrPendingSubmarine().DisplayName, deliveryFee.ToString(), currencyLongText }), messageBoxOptions);
msgBox = new GUIMessageBox(TextManager.Get("deliveryrequestheader"), TextManager.GetWithVariables("deliveryrequesttext",
("[submarinename1]", selectedSubmarine.DisplayName),
("[location1]", deliveryLocationName),
("[location2]", GameMain.GameSession.Map.CurrentLocation.Name),
("[submarinename2]", CurrentOrPendingSubmarine().DisplayName),
("[amount]", deliveryFee.ToString()),
("[currencyname]", currencyLongText)), messageBoxOptions);
}
else
{
msgBox = new GUIMessageBox(TextManager.Get("switchsubmarineheader"), TextManager.GetWithVariables("switchsubmarinetext", SwitchTextVariables,
new string[2] { CurrentOrPendingSubmarine().DisplayName, selectedSubmarine.DisplayName }), messageBoxOptions);
msgBox = new GUIMessageBox(TextManager.Get("switchsubmarineheader"), TextManager.GetWithVariables("switchsubmarinetext",
("[submarinename1]", CurrentOrPendingSubmarine().DisplayName),
("[submarinename2]", selectedSubmarine.DisplayName)), messageBoxOptions);
}
msgBox.Buttons[0].OnClicked = (applyButton, obj) =>
@@ -629,8 +631,9 @@ namespace Barotrauma
{
if (GameMain.GameSession.Campaign.Money < selectedSubmarine.Price)
{
new GUIMessageBox(TextManager.Get("purchasesubmarineheader"), TextManager.GetWithVariables("notenoughmoneyforpurchasetext", notEnoughCreditsPurchaseTextVariables,
new string[2] { currencyLongText, selectedSubmarine.DisplayName }));
new GUIMessageBox(TextManager.Get("purchasesubmarineheader"), TextManager.GetWithVariables("notenoughmoneyforpurchasetext",
("[currencyname]", currencyLongText),
("[submarinename]", selectedSubmarine.DisplayName)));
return;
}
@@ -638,8 +641,11 @@ namespace Barotrauma
if (!purchaseOnly)
{
msgBox = new GUIMessageBox(TextManager.Get("purchaseandswitchsubmarineheader"), TextManager.GetWithVariables("purchaseandswitchsubmarinetext", PurchaseAndSwitchTextVariables,
new string[4] { selectedSubmarine.DisplayName, selectedSubmarine.Price.ToString(), currencyLongText, CurrentOrPendingSubmarine().DisplayName }), messageBoxOptions);
msgBox = new GUIMessageBox(TextManager.Get("purchaseandswitchsubmarineheader"), TextManager.GetWithVariables("purchaseandswitchsubmarinetext",
("[submarinename1]", selectedSubmarine.DisplayName),
("[amount]", selectedSubmarine.Price.ToString()),
("[currencyname]", currencyLongText),
("[submarinename2]", CurrentOrPendingSubmarine().DisplayName)), messageBoxOptions);
msgBox.Buttons[0].OnClicked = (applyButton, obj) =>
{
@@ -658,8 +664,10 @@ namespace Barotrauma
}
else
{
msgBox = new GUIMessageBox(TextManager.Get("purchasesubmarineheader"), TextManager.GetWithVariables("purchasesubmarinetext", PurchaseTextVariables,
new string[3] { selectedSubmarine.DisplayName, selectedSubmarine.Price.ToString(), currencyLongText }), messageBoxOptions);
msgBox = new GUIMessageBox(TextManager.Get("purchasesubmarineheader"), TextManager.GetWithVariables("purchasesubmarinetext",
("[submarinename]", selectedSubmarine.DisplayName),
("[amount]", selectedSubmarine.Price.ToString()),
("[currencyname]", currencyLongText)), messageBoxOptions);
msgBox.Buttons[0].OnClicked = (applyButton, obj) =>
{
@@ -99,15 +99,15 @@ namespace Barotrauma
{
if (currentPing < lowPingThreshold)
{
return GUI.Style.Green;
return GUIStyle.Green;
}
else if (currentPing < mediumPingThreshold)
{
return GUI.Style.Yellow;
return GUIStyle.Yellow;
}
else
{
return GUI.Style.Red;
return GUIStyle.Red;
}
}
@@ -119,10 +119,10 @@ namespace Barotrauma
public void Initialize()
{
spectateIcon = GUI.Style.GetComponentStyle("SpectateIcon").Sprites[GUIComponent.ComponentState.None][0];
disconnectedIcon = GUI.Style.GetComponentStyle("DisconnectedIcon").Sprites[GUIComponent.ComponentState.None][0];
ownerIcon = GUI.Style.GetComponentStyle("OwnerIcon").GetDefaultSprite();
moderatorIcon = GUI.Style.GetComponentStyle("ModeratorIcon").GetDefaultSprite();
spectateIcon = GUIStyle.GetComponentStyle("SpectateIcon").Sprites[GUIComponent.ComponentState.None][0];
disconnectedIcon = GUIStyle.GetComponentStyle("DisconnectedIcon").Sprites[GUIComponent.ComponentState.None][0];
ownerIcon = GUIStyle.GetComponentStyle("OwnerIcon").GetDefaultSprite();
moderatorIcon = GUIStyle.GetComponentStyle("ModeratorIcon").GetDefaultSprite();
initialized = true;
}
@@ -142,7 +142,7 @@ namespace Barotrauma
talentResetButton.Enabled = talentApplyButton.Enabled = talentCount > 0;
if (talentApplyButton.Enabled && talentApplyButton.FlashTimer <= 0.0f)
{
talentApplyButton.Flash(GUI.Style.Orange);
talentApplyButton.Flash(GUIStyle.Orange);
}
}
@@ -243,7 +243,7 @@ namespace Barotrauma
var reputationButton = createTabButton(InfoFrameTab.Reputation, "reputation");
var balanceFrame = new GUIFrame(new RectTransform(new Point(innerLayoutGroup.Rect.Width, innerLayoutGroup.Rect.Height - infoFrameHolderHeight), parent: innerLayoutGroup.RectTransform), style: "InnerFrame");
new GUITextBlock(new RectTransform(Vector2.One, balanceFrame.RectTransform), "", textAlignment: Alignment.Right, parseRichText: true)
new GUITextBlock(new RectTransform(Vector2.One, balanceFrame.RectTransform), "", textAlignment: Alignment.Right)
{
TextGetter = () => TextManager.GetWithVariable("campaignmoney", "[money]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", campaignMode.Money))
};
@@ -353,7 +353,7 @@ namespace Barotrauma
{
if (teamIDs.Count > 1)
{
new GUITextBlock(new RectTransform(new Vector2(1.0f, nameHeight), content.RectTransform), CombatMission.GetTeamName(teamIDs[i]), textColor: i == 0 ? GUI.Style.Green : GUI.Style.Orange) { ForceUpperCase = true };
new GUITextBlock(new RectTransform(new Vector2(1.0f, nameHeight), content.RectTransform), CombatMission.GetTeamName(teamIDs[i]), textColor: i == 0 ? GUIStyle.Green : GUIStyle.Orange) { ForceUpperCase = ForceUpperCase.Yes };
}
headerFrames[i] = new GUILayoutGroup(new RectTransform(Vector2.Zero, content.RectTransform, Anchor.TopLeft, Pivot.BottomLeft) { AbsoluteOffset = new Point(2, -1) }, isHorizontal: true)
@@ -396,7 +396,7 @@ namespace Barotrauma
for (int i = 0; i < teamIDs.Count; i++)
{
headerFrames[i].RectTransform.RelativeSize = new Vector2(1f - crewListArray[i].ScrollBar.Rect.Width / (float)crewListArray[i].Rect.Width, GUI.HotkeyFont.Size / (float)crewFrame.RectTransform.Rect.Height * 1.5f);
headerFrames[i].RectTransform.RelativeSize = new Vector2(1f - crewListArray[i].ScrollBar.Rect.Width / (float)crewListArray[i].Rect.Width, GUIStyle.HotkeyFont.Size / (float)crewFrame.RectTransform.Rect.Height * 1.5f);
if (!GameMain.IsMultiplayer)
{
@@ -446,9 +446,9 @@ namespace Barotrauma
jobButton.RectTransform.RelativeSize = new Vector2(jobColumnWidthPercentage * sizeMultiplier, 1f);
characterButton.RectTransform.RelativeSize = new Vector2((1f - jobColumnWidthPercentage * sizeMultiplier) * sizeMultiplier, 1f);
jobButton.TextBlock.Font = characterButton.TextBlock.Font = GUI.HotkeyFont;
jobButton.TextBlock.Font = characterButton.TextBlock.Font = GUIStyle.HotkeyFont;
jobButton.CanBeFocused = characterButton.CanBeFocused = false;
jobButton.TextBlock.ForceUpperCase = characterButton.TextBlock.ForceUpperCase = true;
jobButton.TextBlock.ForceUpperCase = characterButton.TextBlock.ForceUpperCase = ForceUpperCase.Yes;
jobColumnWidth = jobButton.Rect.Width;
characterColumnWidth = characterButton.Rect.Width;
@@ -493,7 +493,7 @@ namespace Barotrauma
};
GUITextBlock characterNameBlock = new GUITextBlock(new RectTransform(new Point(characterColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
ToolBox.LimitString(character.Info.Name, GUI.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: character.Info.Job.Prefab.UIColor);
ToolBox.LimitString(character.Info.Name, GUIStyle.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: character.Info.Job.Prefab.UIColor);
linkedGUIList.Add(new LinkedGUI(character, frame, !character.IsDead, null));
}
@@ -510,9 +510,9 @@ namespace Barotrauma
characterButton.RectTransform.RelativeSize = new Vector2(characterColumnWidthPercentage * sizeMultiplier, 1f);
pingButton.RectTransform.RelativeSize = new Vector2(pingColumnWidthPercentage * sizeMultiplier, 1f);
jobButton.TextBlock.Font = characterButton.TextBlock.Font = pingButton.TextBlock.Font = GUI.HotkeyFont;
jobButton.TextBlock.Font = characterButton.TextBlock.Font = pingButton.TextBlock.Font = GUIStyle.HotkeyFont;
jobButton.CanBeFocused = characterButton.CanBeFocused = pingButton.CanBeFocused = false;
jobButton.TextBlock.ForceUpperCase = characterButton.TextBlock.ForceUpperCase = pingButton.ForceUpperCase = true;
jobButton.TextBlock.ForceUpperCase = characterButton.TextBlock.ForceUpperCase = pingButton.ForceUpperCase = ForceUpperCase.Yes;
jobColumnWidth = jobButton.Rect.Width;
characterColumnWidth = characterButton.Rect.Width;
@@ -583,11 +583,11 @@ namespace Barotrauma
else
{
GUITextBlock characterNameBlock = new GUITextBlock(new RectTransform(new Point(characterColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
ToolBox.LimitString(character.Info.Name, GUI.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: character.Info.Job.Prefab.UIColor);
ToolBox.LimitString(character.Info.Name, GUIStyle.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: character.Info.Job.Prefab.UIColor);
if (character is AICharacter)
{
linkedGUIList.Add(new LinkedGUI(character, frame, !character.IsDead, new GUITextBlock(new RectTransform(new Point(pingColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform), TextManager.Get("tabmenu.bot"), textAlignment: Alignment.Center) { ForceUpperCase = true }));
linkedGUIList.Add(new LinkedGUI(character, frame, !character.IsDead, new GUITextBlock(new RectTransform(new Point(pingColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform), TextManager.Get("tabmenu.bot"), textAlignment: Alignment.Center) { ForceUpperCase = ForceUpperCase.Yes }));
}
else
{
@@ -677,16 +677,16 @@ namespace Barotrauma
float characterNameWidthAdjustment = (iconSize.X + paddedFrame.AbsoluteSpacing) / characterColumnWidth;
characterNameBlock = new GUITextBlock(new RectTransform(new Point(characterColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
ToolBox.LimitString(client.Name, GUI.Font, (int)(characterColumnWidth - paddedFrame.Rect.Width * characterNameWidthAdjustment)), textAlignment: Alignment.Center, textColor: nameColor);
ToolBox.LimitString(client.Name, GUIStyle.Font, (int)(characterColumnWidth - paddedFrame.Rect.Width * characterNameWidthAdjustment)), textAlignment: Alignment.Center, textColor: nameColor);
float iconWidth = iconSize.X / (float)characterColumnWidth;
int xOffset = (int)(jobColumnWidth + characterNameBlock.TextPos.X - GUI.Font.MeasureString(characterNameBlock.Text).X / 2f - paddedFrame.AbsoluteSpacing - iconWidth * paddedFrame.Rect.Width);
int xOffset = (int)(jobColumnWidth + characterNameBlock.TextPos.X - GUIStyle.Font.MeasureString(characterNameBlock.Text).X / 2f - paddedFrame.AbsoluteSpacing - iconWidth * paddedFrame.Rect.Width);
new GUIImage(new RectTransform(new Vector2(iconWidth, 1f), paddedFrame.RectTransform) { AbsoluteOffset = new Point(xOffset + 2, 0) }, permissionIcon) { IgnoreLayoutGroups = true };
}
else
{
characterNameBlock = new GUITextBlock(new RectTransform(new Point(characterColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
ToolBox.LimitString(client.Name, GUI.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: nameColor);
ToolBox.LimitString(client.Name, GUIStyle.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: nameColor);
}
if (client.Character != null && client.Character.IsDead)
@@ -724,14 +724,14 @@ namespace Barotrauma
}
else
{
Vector2 stringOffset = GUI.GlobalFont.MeasureString(inLobbyString) / 2f;
GUI.GlobalFont.DrawString(spriteBatch, inLobbyString, area.Center.ToVector2() - stringOffset, Color.White);
Vector2 stringOffset = GUIStyle.GlobalFont.MeasureString(inLobbyString) / 2f;
GUIStyle.GlobalFont.DrawString(spriteBatch, inLobbyString, area.Center.ToVector2() - stringOffset, Color.White);
}
}
private void DrawDisconnectedIcon(SpriteBatch spriteBatch, Rectangle area)
{
disconnectedIcon.Draw(spriteBatch, area, GUI.Style.Red);
disconnectedIcon.Draw(spriteBatch, area, GUIStyle.Red);
}
/// <summary>
@@ -788,7 +788,7 @@ namespace Barotrauma
new GUICustomComponent(new RectTransform(new Vector2(0.425f, 1.0f), headerArea.RectTransform),
onDraw: (sb, component) => DrawNotInGameIcon(sb, component.Rect, client));
ScalableFont font = paddedFrame.Rect.Width < 280 ? GUI.SmallFont : GUI.Font;
GUIFont font = paddedFrame.Rect.Width < 280 ? GUIStyle.SmallFont : GUIStyle.Font;
var headerTextArea = new GUILayoutGroup(new RectTransform(new Vector2(0.575f, 1.0f), headerArea.RectTransform))
{
@@ -796,9 +796,9 @@ namespace Barotrauma
Stretch = true
};
GUITextBlock clientNameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), headerTextArea.RectTransform), ToolBox.LimitString(client.Name, GUI.Font, headerTextArea.Rect.Width), textColor: Color.White, font: GUI.Font)
GUITextBlock clientNameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), headerTextArea.RectTransform), ToolBox.LimitString(client.Name, GUIStyle.Font, headerTextArea.Rect.Width), textColor: Color.White, font: GUIStyle.Font)
{
ForceUpperCase = true,
ForceUpperCase = ForceUpperCase.Yes,
Padding = Vector4.Zero
};
@@ -885,22 +885,22 @@ namespace Barotrauma
switch (type)
{
case PlayerConnectionChangeType.Joined:
textColor = GUI.Style.Green;
textColor = GUIStyle.Green;
break;
case PlayerConnectionChangeType.Kicked:
textColor = GUI.Style.Orange;
textColor = GUIStyle.Orange;
break;
case PlayerConnectionChangeType.Disconnected:
textColor = GUI.Style.Yellow;
textColor = GUIStyle.Yellow;
break;
case PlayerConnectionChangeType.Banned:
textColor = GUI.Style.Red;
textColor = GUIStyle.Red;
break;
}
if (logList != null)
{
var textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), logList.Content.RectTransform), line, wrap: true, font: GUI.SmallFont, parseRichText: true)
var textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), logList.Content.RectTransform), RichString.Rich(line), wrap: true, font: GUIStyle.SmallFont)
{
TextColor = textColor,
CanBeFocused = false,
@@ -935,14 +935,14 @@ namespace Barotrauma
AbsoluteSpacing = GUI.IntScale(10)
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), locationInfoContainer.RectTransform), location.Name, font: GUI.LargeFont);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), locationInfoContainer.RectTransform), location.Type.Name, font: GUI.SubHeadingFont);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), locationInfoContainer.RectTransform), location.Name, font: GUIStyle.LargeFont);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), locationInfoContainer.RectTransform), location.Type.Name, font: GUIStyle.SubHeadingFont);
var biomeLabel = new GUITextBlock(new RectTransform(new Vector2(0.5f, 0.0f), locationInfoContainer.RectTransform),
TextManager.Get("Biome", fallBackTag: "location"), font: GUI.SubHeadingFont, textAlignment: Alignment.CenterLeft);
TextManager.Get("Biome", "location"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterLeft);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), biomeLabel.RectTransform), Level.Loaded.LevelData.Biome.DisplayName, textAlignment: Alignment.CenterRight);
var difficultyLabel = new GUITextBlock(new RectTransform(new Vector2(0.5f, 0.0f), locationInfoContainer.RectTransform),
TextManager.Get("LevelDifficulty"), font: GUI.SubHeadingFont, textAlignment: Alignment.CenterLeft);
TextManager.Get("LevelDifficulty"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterLeft);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), difficultyLabel.RectTransform), ((int)Level.Loaded.LevelData.Difficulty) + " %", textAlignment: Alignment.CenterRight);
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), missionFrameContent.RectTransform) { AbsoluteOffset = new Point(0, locationInfoContainer.Rect.Height + padding) }, style: "HorizontalLine")
@@ -974,7 +974,7 @@ namespace Barotrauma
if (GameMain.GameSession?.Missions != null)
{
int spacing = GUI.IntScale(5);
int iconSize = (int)(GUI.LargeFont.MeasureChar('T').Y + GUI.Font.MeasureChar('T').Y * 4 + spacing * 4);
int iconSize = (int)(GUIStyle.LargeFont.MeasureChar('T').Y + GUIStyle.Font.MeasureChar('T').Y * 4 + spacing * 4);
foreach (Mission mission in GameMain.GameSession.Missions)
{
@@ -983,28 +983,27 @@ namespace Barotrauma
{
AbsoluteSpacing = spacing
};
string descriptionText = mission.Description;
foreach (string missionMessage in mission.ShownMessages)
LocalizedString descriptionText = mission.Description;
foreach (LocalizedString missionMessage in mission.ShownMessages)
{
descriptionText += "\n\n" + missionMessage;
}
string rewardText = mission.GetMissionRewardText(Submarine.MainSub);
string reputationText = mission.GetReputationRewardText(mission.Locations[0]);
RichString rewardText = mission.GetMissionRewardText(Submarine.MainSub);
RichString reputationText = mission.GetReputationRewardText(mission.Locations[0]);
var missionNameRichTextData = RichTextData.GetRichTextData(mission.Name, out string missionNameString);
var missionRewardRichTextData = RichTextData.GetRichTextData(rewardText, out string missionRewardString);
var missionReputationRichTextData = RichTextData.GetRichTextData(reputationText, out string missionReputationString);
var missionDescriptionRichTextData = RichTextData.GetRichTextData(descriptionText, out string missionDescriptionString);
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));
missionNameString = ToolBox.WrapText(missionNameString, missionTextGroup.Rect.Width, GUI.LargeFont);
missionRewardString = ToolBox.WrapText(missionRewardString, missionTextGroup.Rect.Width, GUI.Font);
missionReputationString = ToolBox.WrapText(missionReputationString, missionTextGroup.Rect.Width, GUI.Font);
missionDescriptionString = ToolBox.WrapText(missionDescriptionString, missionTextGroup.Rect.Width, GUI.Font);
Vector2 missionNameSize = GUI.LargeFont.MeasureString(missionNameString);
Vector2 missionDescriptionSize = GUI.Font.MeasureString(missionDescriptionString);
Vector2 missionRewardSize = GUI.Font.MeasureString(missionRewardString);
Vector2 missionReputationSize = GUI.Font.MeasureString(missionReputationString);
Vector2 missionNameSize = GUIStyle.LargeFont.MeasureString(missionNameString);
Vector2 missionDescriptionSize = GUIStyle.Font.MeasureString(missionDescriptionString);
Vector2 missionRewardSize = GUIStyle.Font.MeasureString(missionRewardString);
Vector2 missionReputationSize = GUIStyle.Font.MeasureString(missionReputationString);
float ySize = missionNameSize.Y + missionDescriptionSize.Y + missionRewardSize.Y + missionReputationSize.Y + missionTextGroup.AbsoluteSpacing * 4;
bool displayDifficulty = mission.Difficulty.HasValue;
@@ -1030,7 +1029,7 @@ namespace Barotrauma
UpdateMissionStateIcon(mission, icon);
mission.OnMissionStateChanged += (mission) => UpdateMissionStateIcon(mission, icon);
}
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionNameRichTextData, missionNameString, font: GUI.LargeFont);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionNameString, font: GUIStyle.LargeFont);
GUILayoutGroup difficultyIndicatorGroup = null;
if (displayDifficulty)
{
@@ -1048,20 +1047,20 @@ namespace Barotrauma
};
}
}
var rewardTextBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionRewardRichTextData, missionRewardString);
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), missionReputationRichTextData, missionReputationString);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionDescriptionRichTextData, missionDescriptionString);
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
{
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: GUI.LargeFont);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), TextManager.Get("NoMission"), font: GUIStyle.LargeFont);
}
}
@@ -1101,11 +1100,11 @@ namespace Barotrauma
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);
string missionNameString = ToolBox.WrapText(TextManager.Get("tabmenu.traitor"), missionTextGroup.Rect.Width, GUI.LargeFont);
string missionDescriptionString = ToolBox.WrapText(traitor.TraitorCurrentObjective, missionTextGroup.Rect.Width, GUI.Font);
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 = GUI.LargeFont.MeasureString(missionNameString);
Vector2 missionDescriptionSize = GUI.Font.MeasureString(missionDescriptionString);
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);
@@ -1118,7 +1117,7 @@ namespace Barotrauma
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: GUI.LargeFont);
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);
}
@@ -1164,21 +1163,21 @@ namespace Barotrauma
var subInfoTextLayout = new GUILayoutGroup(new RectTransform(Vector2.One, paddedFrame.RectTransform));
string className = !sub.Info.HasTag(SubmarineTag.Shuttle) ? TextManager.Get($"submarineclass.{sub.Info.SubmarineClass}") : TextManager.Get("shuttle");
LocalizedString className = !sub.Info.HasTag(SubmarineTag.Shuttle) ? TextManager.Get($"submarineclass.{sub.Info.SubmarineClass}") : TextManager.Get("shuttle");
int nameHeight = (int)GUI.LargeFont.MeasureString(sub.Info.DisplayName, true).Y;
int classHeight = (int)GUI.SubHeadingFont.MeasureString(className).Y;
int nameHeight = (int)GUIStyle.LargeFont.MeasureString(sub.Info.DisplayName, true).Y;
int classHeight = (int)GUIStyle.SubHeadingFont.MeasureString(className).Y;
var submarineNameText = new GUITextBlock(new RectTransform(new Point(subInfoTextLayout.Rect.Width, nameHeight + HUDLayoutSettings.Padding / 2), subInfoTextLayout.RectTransform), sub.Info.DisplayName, textAlignment: Alignment.CenterLeft, font: GUI.LargeFont) { CanBeFocused = false };
var submarineNameText = new GUITextBlock(new RectTransform(new Point(subInfoTextLayout.Rect.Width, nameHeight + HUDLayoutSettings.Padding / 2), subInfoTextLayout.RectTransform), sub.Info.DisplayName, textAlignment: Alignment.CenterLeft, font: GUIStyle.LargeFont) { CanBeFocused = false };
submarineNameText.RectTransform.MinSize = new Point(0, (int)submarineNameText.TextSize.Y);
var submarineClassText = new GUITextBlock(new RectTransform(new Point(subInfoTextLayout.Rect.Width, classHeight), subInfoTextLayout.RectTransform), className, textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont) { CanBeFocused = false };
var submarineClassText = new GUITextBlock(new RectTransform(new Point(subInfoTextLayout.Rect.Width, classHeight), subInfoTextLayout.RectTransform), className, textAlignment: Alignment.CenterLeft, font: GUIStyle.SubHeadingFont) { CanBeFocused = false };
submarineClassText.RectTransform.MinSize = new Point(0, (int)submarineClassText.TextSize.Y);
if (GameMain.GameSession?.GameMode is CampaignMode campaign)
{
GUILayoutGroup headerLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.09f), paddedFrame.RectTransform) { RelativeOffset = new Vector2(0f, 0.43f) }, isHorizontal: true) { Stretch = true };
GUIImage headerIcon = new GUIImage(new RectTransform(Vector2.One, headerLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "SubmarineIcon");
new GUITextBlock(new RectTransform(Vector2.One, headerLayout.RectTransform), TextManager.Get("uicategory.upgrades"), font: GUI.LargeFont);
new GUITextBlock(new RectTransform(Vector2.One, headerLayout.RectTransform), TextManager.Get("uicategory.upgrades"), font: GUIStyle.LargeFont);
var upgradeRootLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.48f), paddedFrame.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft), isHorizontal: true);
@@ -1206,7 +1205,7 @@ namespace Barotrauma
else
{
var specsListBox = new GUIListBox(new RectTransform(new Vector2(1f, 0.57f), paddedFrame.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft));
sub.Info.CreateSpecsWindow(specsListBox, GUI.Font, includeTitle: false, includeClass: false, includeDescription: true);
sub.Info.CreateSpecsWindow(specsListBox, GUIStyle.Font, includeTitle: false, includeClass: false, includeDescription: true);
}
}
private Color unselectedColor = new Color(240, 255, 255, 225);
@@ -1216,8 +1215,8 @@ namespace Barotrauma
private Color pressedColor = new Color(60, 60, 60, 225);
private readonly List<(GUIButton button, GUIComponent icon)> talentButtons = new List<(GUIButton button, GUIComponent icon)>();
private readonly List<(string talentTree, int index, GUIImage icon, GUIFrame background, GUIFrame backgroundGlow)> talentCornerIcons = new List<(string talentTree, int index, GUIImage icon, GUIFrame background, GUIFrame backgroundGlow)>();
private List<string> selectedTalents = new List<string>();
private readonly List<(Identifier talentTree, int index, GUIImage icon, GUIFrame background, GUIFrame backgroundGlow)> talentCornerIcons = new List<(Identifier talentTree, int index, GUIImage icon, GUIFrame background, GUIFrame backgroundGlow)>();
private List<Identifier> selectedTalents = new List<Identifier>();
private GUITextBlock experienceText;
private GUIProgressBar experienceBar;
@@ -1231,11 +1230,11 @@ namespace Barotrauma
private readonly ImmutableDictionary<TalentTree.TalentTreeStageState, GUIComponentStyle> talentStageStyles = new Dictionary<TalentTree.TalentTreeStageState, GUIComponentStyle>
{
{ TalentTree.TalentTreeStageState.Invalid, GUI.Style.GetComponentStyle("TalentTreeLocked") },
{ TalentTree.TalentTreeStageState.Locked, GUI.Style.GetComponentStyle("TalentTreeLocked") },
{ TalentTree.TalentTreeStageState.Unlocked, GUI.Style.GetComponentStyle("TalentTreePurchased") },
{ TalentTree.TalentTreeStageState.Available, GUI.Style.GetComponentStyle("TalentTreeUnlocked") },
{ TalentTree.TalentTreeStageState.Highlighted, GUI.Style.GetComponentStyle("TalentTreeAvailable") },
{ TalentTree.TalentTreeStageState.Invalid, GUIStyle.GetComponentStyle("TalentTreeLocked") },
{ TalentTree.TalentTreeStageState.Locked, GUIStyle.GetComponentStyle("TalentTreeLocked") },
{ TalentTree.TalentTreeStageState.Unlocked, GUIStyle.GetComponentStyle("TalentTreePurchased") },
{ TalentTree.TalentTreeStageState.Available, GUIStyle.GetComponentStyle("TalentTreeUnlocked") },
{ TalentTree.TalentTreeStageState.Highlighted, GUIStyle.GetComponentStyle("TalentTreeAvailable") },
}.ToImmutableDictionary();
private readonly ImmutableDictionary<TalentTree.TalentTreeStageState, Color> talentStageBackgroundColors = new Dictionary<TalentTree.TalentTreeStageState, Color>
@@ -1287,7 +1286,7 @@ namespace Barotrauma
{
AbsoluteSpacing = GUI.IntScale(5)
};
GUILayoutGroup talentInfoLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.25f), talentFrameLayoutGroup.RectTransform, Anchor.Center), isHorizontal: true);
CharacterInfo info = controlledCharacter.Info;
@@ -1300,18 +1299,18 @@ namespace Barotrauma
});
GUILayoutGroup nameLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.3f, 1f), talentInfoLayoutGroup.RectTransform)) { RelativeSpacing = 0.05f };
Vector2 nameSize = GUI.SubHeadingFont.MeasureString(info.Name);
GUITextBlock nameBlock = new GUITextBlock(new RectTransform(Vector2.One, nameLayout.RectTransform), info.Name, font: GUI.SubHeadingFont) { TextColor = job.Prefab.UIColor };
Vector2 nameSize = GUIStyle.SubHeadingFont.MeasureString(info.Name);
GUITextBlock nameBlock = new GUITextBlock(new RectTransform(Vector2.One, nameLayout.RectTransform), info.Name, font: GUIStyle.SubHeadingFont) { TextColor = job.Prefab.UIColor };
nameBlock.RectTransform.NonScaledSize = nameSize.Pad(nameBlock.Padding).ToPoint();
Vector2 jobSize = GUI.SmallFont.MeasureString(job.Name);
GUITextBlock jobBlock = new GUITextBlock(new RectTransform(Vector2.One, nameLayout.RectTransform), job.Name, font: GUI.SmallFont) { TextColor = job.Prefab.UIColor };
Vector2 jobSize = GUIStyle.SmallFont.MeasureString(job.Name);
GUITextBlock jobBlock = new GUITextBlock(new RectTransform(Vector2.One, nameLayout.RectTransform), job.Name, font: GUIStyle.SmallFont) { TextColor = job.Prefab.UIColor };
jobBlock.RectTransform.NonScaledSize = jobSize.Pad(jobBlock.Padding).ToPoint();
string traitString = TextManager.AddPunctuation(':', TextManager.Get("PersonalityTrait"), TextManager.Get("personalitytrait." + info.PersonalityTrait.Name.Replace(" ", "")));
Vector2 traitSize = GUI.SmallFont.MeasureString(traitString);
GUITextBlock traitBlock = new GUITextBlock(new RectTransform(Vector2.One, nameLayout.RectTransform), traitString, font: GUI.SmallFont);
LocalizedString traitString = TextManager.AddPunctuation(':', TextManager.Get("PersonalityTrait"), TextManager.Get("personalitytrait." + info.PersonalityTrait.Name.Replace(" ", "")));
Vector2 traitSize = GUIStyle.SmallFont.MeasureString(traitString);
GUITextBlock traitBlock = new GUITextBlock(new RectTransform(Vector2.One, nameLayout.RectTransform), traitString, font: GUIStyle.SmallFont);
traitBlock.RectTransform.NonScaledSize = traitSize.Pad(traitBlock.Padding).ToPoint();
GUIFrame endocrineFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.35f), nameLayout.RectTransform, Anchor.BottomCenter), style: null);
@@ -1365,7 +1364,7 @@ namespace Barotrauma
}
}
IEnumerable<TalentPrefab> endocrineTalents = info.GetEndocrineTalents().Select(e => TalentPrefab.TalentPrefabs.Find(c => c.Identifier.Equals(e, StringComparison.OrdinalIgnoreCase)));
IEnumerable<TalentPrefab> endocrineTalents = info.GetEndocrineTalents().Select(e => TalentPrefab.TalentPrefabs.Find(c => c.Identifier == e));
if (endocrineTalents.Count() > 0)
{
@@ -1377,15 +1376,15 @@ namespace Barotrauma
GUILayoutGroup skillLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.45f, 1f), talentInfoLayoutGroup.RectTransform)) { Stretch = true };
string skillString = TextManager.Get("skills");
Vector2 skillSize = GUI.SubHeadingFont.MeasureString(skillString);
GUITextBlock skillBlock = new GUITextBlock(new RectTransform(Vector2.One, skillLayout.RectTransform), skillString, font: GUI.SubHeadingFont);
LocalizedString skillString = TextManager.Get("skills");
Vector2 skillSize = GUIStyle.SubHeadingFont.MeasureString(skillString);
GUITextBlock skillBlock = new GUITextBlock(new RectTransform(Vector2.One, skillLayout.RectTransform), skillString, font: GUIStyle.SubHeadingFont);
skillBlock.RectTransform.NonScaledSize = skillSize.Pad(skillBlock.Padding).ToPoint();
skillListBox = new GUIListBox(new RectTransform(new Vector2(1f, 1f - skillBlock.RectTransform.RelativeSize.Y), skillLayout.RectTransform), style: null);
CreateTalentSkillList(controlledCharacter, skillListBox);
if (!TalentTree.JobTalentTrees.TryGetValue(controlledCharacter.Info.Job.Prefab.Identifier, out TalentTree talentTree)) { return; }
if (!TalentTree.JobTalentTrees.TryGet(controlledCharacter.Info.Job.Prefab.Identifier, out TalentTree talentTree)) { return; }
new GUIFrame(new RectTransform(new Vector2(1f, 1f), talentFrameLayoutGroup.RectTransform), style: "HorizontalLine");
@@ -1401,7 +1400,7 @@ namespace Barotrauma
int elementPadding = GUI.IntScale(8);
Point headerSize = subtreeTitleFrame.RectTransform.NonScaledSize;
GUIFrame subTreeTitleBackground = new GUIFrame(new RectTransform(new Point(headerSize.X - elementPadding, headerSize.Y), subtreeTitleFrame.RectTransform, anchor: Anchor.Center), style: "SubtreeHeader");
subTreeNames.Add(new GUITextBlock(new RectTransform(Vector2.One, subTreeTitleBackground.RectTransform, anchor: Anchor.TopCenter), subTree.DisplayName, font: GUI.SubHeadingFont, textAlignment: Alignment.Center));
subTreeNames.Add(new GUITextBlock(new RectTransform(Vector2.One, subTreeTitleBackground.RectTransform, anchor: Anchor.TopCenter), subTree.DisplayName, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Center));
for (int i = 0; i < 4; i++)
{
@@ -1439,7 +1438,7 @@ namespace Barotrauma
GUIButton talentButton = new GUIButton(new RectTransform(Vector2.One, croppedTalentFrame.RectTransform, anchor: Anchor.Center), style: null)
{
ToolTip = $"{talent.DisplayName}\n\n{talent.Description}",
ToolTip = RichString.Rich(talent.DisplayName + "\n\n" + talent.Description),
UserData = talent.Identifier,
PressedColor = pressedColor,
OnClicked = (button, userData) =>
@@ -1447,7 +1446,7 @@ namespace Barotrauma
// deselect other buttons in tier by removing their selected talents from pool
foreach (GUIButton guiButton in talentOptionLayoutGroup.GetAllChildren<GUIButton>())
{
if (guiButton.UserData is string otherTalentIdentifier && guiButton != button)
if (guiButton.UserData is Identifier otherTalentIdentifier && guiButton != button)
{
if (!controlledCharacter.HasTalent(otherTalentIdentifier))
{
@@ -1455,7 +1454,7 @@ namespace Barotrauma
}
}
}
string talentIdentifier = userData as string;
Identifier talentIdentifier = (Identifier)userData;
if (TalentTree.IsViableTalentForCharacter(controlledCharacter, talentIdentifier, selectedTalents))
{
@@ -1479,10 +1478,10 @@ namespace Barotrauma
GUIComponent iconImage;
if (talent.Icon is null)
{
iconImage = new GUITextBlock(new RectTransform(Vector2.One, talentButton.RectTransform, anchor: Anchor.Center), text: "???", font: GUI.LargeFont, textAlignment: Alignment.Center, style: null)
iconImage = new GUITextBlock(new RectTransform(Vector2.One, talentButton.RectTransform, anchor: Anchor.Center), text: "???", font: GUIStyle.LargeFont, textAlignment: Alignment.Center, style: null)
{
OutlineColor = GUI.Style.Red,
TextColor = GUI.Style.Red,
OutlineColor = GUIStyle.Red,
TextColor = GUIStyle.Red,
PressedColor = unselectableColor,
CanBeFocused = false,
};
@@ -1511,18 +1510,18 @@ namespace Barotrauma
GUIFrame experienceBarFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.5f), experienceLayout.RectTransform), style: null);
experienceBar = new GUIProgressBar(new RectTransform(new Vector2(1f, 1f), experienceBarFrame.RectTransform, Anchor.CenterLeft),
barSize: controlledCharacter.Info.GetProgressTowardsNextLevel(), color: GUI.Style.Green)
barSize: controlledCharacter.Info.GetProgressTowardsNextLevel(), color: GUIStyle.Green)
{
IsHorizontal = true,
};
experienceText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), experienceBarFrame.RectTransform, anchor: Anchor.Center), "", font: GUI.Font, textAlignment: Alignment.CenterRight)
experienceText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), experienceBarFrame.RectTransform, anchor: Anchor.Center), "", font: GUIStyle.Font, textAlignment: Alignment.CenterRight)
{
Shadow = true,
ToolTip = TextManager.Get("experiencetooltip")
};
talentPointText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), experienceLayout.RectTransform, anchor: Anchor.Center), "", font: GUI.SubHeadingFont, parseRichText: true, textAlignment: Alignment.CenterRight) { AutoScaleVertical = true };
talentPointText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), experienceLayout.RectTransform, anchor: Anchor.Center), "", font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterRight) { AutoScaleVertical = true };
talentResetButton = new GUIButton(new RectTransform(new Vector2(0.19f, 1f), talentBottomFrame.RectTransform), text: TextManager.Get("reset"), style: "GUIButtonFreeScale")
{
@@ -1545,22 +1544,23 @@ namespace Barotrauma
{
GUILayoutGroup skillContainer = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.2f), parent.Content.RectTransform), isHorizontal: true) { CanBeFocused = false };
skillNames.Add(new GUITextBlock(new RectTransform(new Vector2(0.7f, 1f), skillContainer.RectTransform), TextManager.Get($"skillname.{skill.Identifier}", returnNull: true) ?? skill.Identifier));
skillNames.Add(new GUITextBlock(new RectTransform(new Vector2(0.7f, 1f), skillContainer.RectTransform), TextManager.Get($"skillname.{skill.Identifier}").Fallback(skill.Identifier.Value)));
new GUITextBlock(new RectTransform(new Vector2(0.15f, 1.0f), skillContainer.RectTransform), Math.Floor(skill.Level).ToString("F0"), textAlignment: Alignment.CenterRight) { Padding = new Vector4(0, 0, 4, 0) };
float modifiedSkillLevel = character.GetSkillLevel(skill.Identifier);
if (!MathUtils.NearlyEqual(MathF.Floor(modifiedSkillLevel), MathF.Floor(skill.Level)))
{
int skillChange = (int)MathF.Floor(modifiedSkillLevel - skill.Level);
//TODO: if/when we upgrade to C# 9, do neater pattern matching here
string stringColor = true switch
{
true when skillChange > 0 => XMLExtensions.ColorToString(GUI.Style.Green),
true when skillChange < 0 => XMLExtensions.ColorToString(GUI.Style.Red),
_ => XMLExtensions.ColorToString(GUI.Style.TextColor)
true when skillChange > 0 => XMLExtensions.ColorToString(GUIStyle.Green),
true when skillChange < 0 => XMLExtensions.ColorToString(GUIStyle.Red),
_ => XMLExtensions.ColorToString(GUIStyle.TextColorNormal)
};
string changeText = $"(‖color:{stringColor}‖{(skillChange > 0 ? "+" : string.Empty) + skillChange}‖color:end‖)";
new GUITextBlock(new RectTransform(new Vector2(0.15f, 1.0f), skillContainer.RectTransform), changeText, parseRichText: true) { Padding = Vector4.Zero };
RichString changeText = RichString.Rich($"(‖color:{stringColor}‖{(skillChange > 0 ? "+" : string.Empty) + skillChange}‖color:end‖)");
new GUITextBlock(new RectTransform(new Vector2(0.15f, 1.0f), skillContainer.RectTransform), changeText) { Padding = Vector4.Zero };
}
skillContainer.Recalculate();
}
@@ -1601,8 +1601,8 @@ namespace Barotrauma
}
else if (talentCount > 0)
{
string pointsUsed = $"‖color:{XMLExtensions.ColorToString(GUI.Style.Red)}‖{-talentCount}‖color:end‖";
string localizedString = TextManager.GetWithVariables("talentmenu.points.spending", new []{ "[amount]", "[used]" }, new []{ pointsLeft, pointsUsed});
string pointsUsed = $"‖color:{XMLExtensions.ColorToString(GUIStyle.Red)}‖{-talentCount}‖color:end‖";
LocalizedString localizedString = TextManager.GetWithVariables("talentmenu.points.spending", ("[amount]", pointsLeft), ("[used]", pointsUsed));
talentPointText.SetRichText(localizedString);
}
else
@@ -1622,19 +1622,19 @@ namespace Barotrauma
foreach (var talentButton in talentButtons)
{
string talentIdentifier = talentButton.button.UserData as string;
Identifier talentIdentifier = (Identifier)talentButton.button.UserData;
bool unselectable = !TalentTree.IsViableTalentForCharacter(controlledCharacter, talentIdentifier, selectedTalents) || controlledCharacter.HasTalent(talentIdentifier);
Color newTalentColor = unselectable ? unselectableColor : unselectedColor;
Color hoverColor = Color.White;
if (controlledCharacter.HasTalent(talentIdentifier))
{
newTalentColor = GUI.Style.Green;
newTalentColor = GUIStyle.Green;
}
else if (selectedTalents.Contains(talentIdentifier))
{
newTalentColor = GUI.Style.Orange;
hoverColor = Color.Lerp(GUI.Style.Orange, Color.White, 0.7f);
newTalentColor = GUIStyle.Orange;
hoverColor = Color.Lerp(GUIStyle.Orange, Color.White, 0.7f);
}
talentButton.icon.Color = newTalentColor;
@@ -1647,7 +1647,7 @@ namespace Barotrauma
private void ApplyTalents(Character controlledCharacter)
{
selectedTalents = TalentTree.CheckTalentSelection(controlledCharacter, selectedTalents);
foreach (string talent in selectedTalents)
foreach (Identifier talent in selectedTalents)
{
controlledCharacter.GiveTalent(talent);
if (GameMain.Client != null)
@@ -19,11 +19,7 @@ namespace Barotrauma
private set;
}
public bool Slice
{
get;
set;
}
public bool Slice => Slices != null;
public Rectangle[] Slices
{
@@ -54,7 +50,7 @@ namespace Barotrauma
public TransitionMode TransitionMode { get; private set; }
public UISprite(XElement element)
public UISprite(ContentXElement element)
{
Sprite = new Sprite(element);
MaintainAspectRatio = element.GetAttributeBool("maintainaspectratio", false);
@@ -69,6 +65,7 @@ namespace Barotrauma
}
Vector4 sliceVec = element.GetAttributeVector4("slice", Vector4.Zero);
Slices = null;
if (sliceVec != Vector4.Zero)
{
minBorderScale = element.GetAttributeFloat("minborderscale", 0.1f);
@@ -76,7 +73,6 @@ namespace Barotrauma
Rectangle slice = new Rectangle((int)sliceVec.X, (int)sliceVec.Y, (int)(sliceVec.Z - sliceVec.X), (int)(sliceVec.W - sliceVec.Y));
Slice = true;
Slices = new Rectangle[9];
//top-left
@@ -245,7 +245,7 @@ namespace Barotrauma
* |----------------------------|
*/
GUILayoutGroup tooltipLayout = new GUILayoutGroup(rectT(0.95f,0.95f, ItemInfoFrame, Anchor.Center)) { Stretch = true };
new GUITextBlock(rectT(1, 0, tooltipLayout), string.Empty, font: GUI.SubHeadingFont) { UserData = "itemname" };
new GUITextBlock(rectT(1, 0, tooltipLayout), string.Empty, font: GUIStyle.SubHeadingFont) { UserData = "itemname" };
new GUITextBlock(rectT(1, 0, tooltipLayout), TextManager.Get("UpgradeUITooltip.UpgradeListHeader"));
new GUIListBox(rectT(1, 0.5f, tooltipLayout), style: null) { ScrollBarVisible = false, AutoHideScrollBar = false, SmoothScroll = true, UserData = "upgradelist"};
new GUITextBlock(rectT(1, 0, tooltipLayout), string.Empty) { UserData = "moreindicator" };
@@ -268,7 +268,7 @@ namespace Barotrauma
GUILayoutGroup leftLayout = new GUILayoutGroup(rectT(0.5f, 1, topHeaderLayout)) { RelativeSpacing = 0.05f };
GUILayoutGroup locationLayout = new GUILayoutGroup(rectT(1, 0.5f, leftLayout), isHorizontal: true);
GUIImage submarineIcon = new GUIImage(rectT(new Point(locationLayout.Rect.Height, locationLayout.Rect.Height), locationLayout), style: "SubmarineIcon", scaleToFit: true);
new GUITextBlock(rectT(1.0f - submarineIcon.RectTransform.RelativeSize.X, 1, locationLayout), TextManager.Get("UpgradeUI.Title"), font: GUI.LargeFont);
new GUITextBlock(rectT(1.0f - submarineIcon.RectTransform.RelativeSize.X, 1, locationLayout), TextManager.Get("UpgradeUI.Title"), font: GUIStyle.LargeFont);
categoryButtonLayout = new GUILayoutGroup(rectT(0.4f, 0.3f, leftLayout), isHorizontal: true) { Stretch = true };
GUIButton upgradeButton = new GUIButton(rectT(1, 1f, categoryButtonLayout), TextManager.Get("UICategory.Upgrades"), style: "GUITabButton") { UserData = UpgradeTab.Upgrade, Selected = selectedUpgradeTab == UpgradeTab.Upgrade };
GUIButton repairButton = new GUIButton(rectT(1, 1f, categoryButtonLayout), TextManager.Get("UICategory.Maintenance"), style: "GUITabButton") { UserData = UpgradeTab.Repairs, Selected = selectedUpgradeTab == UpgradeTab.Repairs };
@@ -285,9 +285,9 @@ namespace Barotrauma
*/
GUILayoutGroup rightLayout = new GUILayoutGroup(rectT(0.5f, 1, topHeaderLayout), childAnchor: Anchor.TopRight);
GUILayoutGroup priceLayout = new GUILayoutGroup(rectT(1, 0.8f, rightLayout), childAnchor: Anchor.Center) { RelativeSpacing = 0.08f };
new GUITextBlock(rectT(1f, 0f, priceLayout), TextManager.Get("CampaignStore.Balance"), font: GUI.SubHeadingFont, textAlignment: Alignment.Right);
new GUITextBlock(rectT(1f, 0f, priceLayout), FormatCurrency(AvailableMoney, format: true), font: GUI.SubHeadingFont, textAlignment: Alignment.Right) { TextGetter = () => FormatCurrency(AvailableMoney, format: true) };
new GUIFrame(rectT(0.5f, 0.1f, rightLayout, Anchor.BottomRight), style: "HorizontalLine") { IgnoreLayoutGroups = true };
new GUITextBlock(rectT(1f, 0f, priceLayout), TextManager.Get("CampaignStore.Balance"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right);
new GUITextBlock(rectT(1f, 0f, priceLayout), FormatCurrency(AvailableMoney, format: true), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right) { TextGetter = () => FormatCurrency(AvailableMoney, format: true) };
new GUIFrame(rectT(0.5f, 0.1f, rightLayout, Anchor.BottomRight), style: "HorizontalLine") { IgnoreLayoutGroups = true };
repairButton.OnClicked = upgradeButton.OnClicked = (button, o) =>
{
@@ -351,7 +351,7 @@ namespace Barotrauma
if (schematicsSprite == null) { return; }
float schematicsScale = Math.Min(component.Rect.Width / 2 / schematicsSprite.size.X, component.Rect.Height / schematicsSprite.size.Y);
Vector2 center = new Vector2(component.Rect.Center.X, component.Rect.Center.Y);
schematicsSprite.Draw(spriteBatch, new Vector2(component.Rect.X, center.Y), GUI.Style.Green, new Vector2(0, schematicsSprite.size.Y / 2),
schematicsSprite.Draw(spriteBatch, new Vector2(component.Rect.X, center.Y), GUIStyle.Green, new Vector2(0, schematicsSprite.size.Y / 2),
scale: schematicsScale);
var swappableItemList = selectedUpgradeCategoryLayout?.FindChild("prefablist", true) as GUIListBox;
@@ -359,10 +359,10 @@ namespace Barotrauma
ItemPrefab swapTo = highlightedElement?.UserData as ItemPrefab ?? selectedItem.PendingItemSwap;
if (swapTo?.SwappableItem == null) { return; }
Sprite? schematicsSprite2 = swapTo.SwappableItem?.SchematicSprite;
schematicsSprite2?.Draw(spriteBatch, new Vector2(component.Rect.Right, center.Y), GUI.Style.Orange, new Vector2(schematicsSprite2.size.X, schematicsSprite2.size.Y / 2),
schematicsSprite2?.Draw(spriteBatch, new Vector2(component.Rect.Right, center.Y), GUIStyle.Orange, new Vector2(schematicsSprite2.size.X, schematicsSprite2.size.Y / 2),
scale: Math.Min(component.Rect.Width / 2 / schematicsSprite2.size.X, component.Rect.Height / schematicsSprite2.size.Y));
var arrowSprite = GUI.Style?.GetComponentStyle("GUIButtonToggleRight")?.GetDefaultSprite();
var arrowSprite = GUIStyle.GetComponentStyle("GUIButtonToggleRight")?.GetDefaultSprite();
if (arrowSprite != null)
{
arrowSprite.Draw(spriteBatch, center, scale: GUI.Scale);
@@ -428,7 +428,7 @@ namespace Barotrauma
if (AvailableMoney >= hullRepairCost)
{
string body = TextManager.GetWithVariable("WallRepairs.PurchasePromptBody", "[amount]", hullRepairCost.ToString());
LocalizedString body = TextManager.GetWithVariable("WallRepairs.PurchasePromptBody", "[amount]", hullRepairCost.ToString());
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), body, () =>
{
if (AvailableMoney >= hullRepairCost)
@@ -463,7 +463,7 @@ namespace Barotrauma
{
if (AvailableMoney >= itemRepairCost && !Campaign.PurchasedItemRepairs)
{
string body = TextManager.GetWithVariable("ItemRepairs.PurchasePromptBody", "[amount]", itemRepairCost.ToString());
LocalizedString body = TextManager.GetWithVariable("ItemRepairs.PurchasePromptBody", "[amount]", itemRepairCost.ToString());
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), body, () =>
{
if (AvailableMoney >= itemRepairCost && !Campaign.PurchasedItemRepairs)
@@ -493,7 +493,7 @@ namespace Barotrauma
{
foreach (var (item, itemFrame) in itemPreviews)
{
itemFrame.OutlineColor = itemFrame.Color = isHovered && item.GetComponent<DockingPort>() == null ? GUI.Style.Orange : previewWhite;
itemFrame.OutlineColor = itemFrame.Color = isHovered && item.GetComponent<DockingPort>() == null ? GUIStyle.Orange : previewWhite;
}
return true;
});
@@ -509,7 +509,7 @@ namespace Barotrauma
if (AvailableMoney >= shuttleRetrieveCost && !Campaign.PurchasedLostShuttles)
{
string body = TextManager.GetWithVariable("ReplaceLostShuttles.PurchasePromptBody", "[amount]", shuttleRetrieveCost.ToString());
LocalizedString body = TextManager.GetWithVariable("ReplaceLostShuttles.PurchasePromptBody", "[amount]", shuttleRetrieveCost.ToString());
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), body, () =>
{
if (AvailableMoney >= shuttleRetrieveCost && !Campaign.PurchasedLostShuttles)
@@ -540,7 +540,7 @@ namespace Barotrauma
{
if (subInfo.LeftBehindDockingPortIDs.Contains(item.ID))
{
itemFrame.OutlineColor = itemFrame.Color = subInfo.BlockedDockingPortIDs.Contains(item.ID) ? GUI.Style.Red : GUI.Style.Green;
itemFrame.OutlineColor = itemFrame.Color = subInfo.BlockedDockingPortIDs.Contains(item.ID) ? GUIStyle.Red : GUIStyle.Green;
}
else
{
@@ -551,7 +551,7 @@ namespace Barotrauma
}, disableElement: true);
}
private void CreateRepairEntry(GUIComponent parent, string title, string imageStyle, int price, GUIButton.OnClickedHandler onPressed, bool isDisabled, Func<bool, bool>? onHover = null, bool disableElement = false)
private void CreateRepairEntry(GUIComponent parent, LocalizedString title, string imageStyle, int price, GUIButton.OnClickedHandler onPressed, bool isDisabled, Func<bool, bool>? onHover = null, bool disableElement = false)
{
GUIFrame frameChild = new GUIFrame(rectT(new Point(parent.Rect.Width, (int) (96 * GUI.Scale)), parent), style: "UpgradeUIFrame");
frameChild.SelectedColor = frameChild.Color;
@@ -569,7 +569,7 @@ namespace Barotrauma
GUILayoutGroup contentLayout = new GUILayoutGroup(rectT(0.9f, 0.85f, frameChild, Anchor.Center), isHorizontal: true);
var repairIcon = new GUIFrame(rectT(new Point(contentLayout.Rect.Height, contentLayout.Rect.Height), contentLayout), style: imageStyle);
GUILayoutGroup textLayout = new GUILayoutGroup(rectT(0.8f - repairIcon.RectTransform.RelativeSize.X, 1, contentLayout)) { Stretch = true };
new GUITextBlock(rectT(1, 0, textLayout), title, font: GUI.SubHeadingFont) { CanBeFocused = false, AutoScaleHorizontal = true };
new GUITextBlock(rectT(1, 0, textLayout), title, font: GUIStyle.SubHeadingFont) { CanBeFocused = false, AutoScaleHorizontal = true };
new GUITextBlock(rectT(1, 0, textLayout), FormatCurrency(price));
GUILayoutGroup buyButtonLayout = new GUILayoutGroup(rectT(0.2f, 1, contentLayout), childAnchor: Anchor.Center) { UserData = "buybutton" };
new GUIButton(rectT(0.7f, 0.5f, buyButtonLayout), string.Empty, style: "RepairBuyButton") { ClickSound = GUISoundType.HireRepairClick, Enabled = AvailableMoney >= price && !isDisabled, OnClicked = onPressed };
@@ -661,7 +661,7 @@ namespace Barotrauma
* |-----------------------------|--------------------------|
*/
GUILayoutGroup contentLayout = new GUILayoutGroup(rectT(0.9f, 0.85f, frameChild, Anchor.Center));
var itemCategoryLabel = new GUITextBlock(rectT(1, 1, contentLayout), category.Name, font: GUI.SubHeadingFont) { CanBeFocused = false };
var itemCategoryLabel = new GUITextBlock(rectT(1, 1, contentLayout), category.Name, font: GUIStyle.SubHeadingFont) { CanBeFocused = false };
GUILayoutGroup indicatorLayout = new GUILayoutGroup(rectT(0.5f, 0.25f, contentLayout, Anchor.BottomRight), isHorizontal: true, childAnchor: Anchor.TopRight) { UserData = "indicators", IgnoreLayoutGroups = true, RelativeSpacing = 0.01f };
foreach (var prefab in prefabs)
@@ -742,7 +742,7 @@ namespace Barotrauma
GUIComponent[] categoryFrames = GetFrames(category);
foreach (GUIComponent itemFrame in itemPreviews.Values)
{
itemFrame.OutlineColor = itemFrame.Color = categoryFrames.Contains(itemFrame) ? GUI.Style.Orange : previewWhite;
itemFrame.OutlineColor = itemFrame.Color = categoryFrames.Contains(itemFrame) ? GUIStyle.Orange : previewWhite;
itemFrame.Children.ForEach(c => c.Color = itemFrame.Color);
}
@@ -790,7 +790,7 @@ namespace Barotrauma
GUIComponent[] categoryFrames = GetFrames(category);
foreach (GUIComponent itemFrame in itemPreviews.Values)
{
itemFrame.OutlineColor = itemFrame.Color = categoryFrames.Contains(itemFrame) ? GUI.Style.Orange : previewWhite;
itemFrame.OutlineColor = itemFrame.Color = categoryFrames.Contains(itemFrame) ? GUIStyle.Orange : previewWhite;
itemFrame.Children.ForEach(c => c.Color = itemFrame.Color);
}
return true;
@@ -851,8 +851,8 @@ namespace Barotrauma
if (linkedItems.Min(it => it.ID) < item.ID) { return; }
var currentOrPending = item.PendingItemSwap ?? item.Prefab;
string name = currentOrPending.Name;
string nameWithQuantity = "";
LocalizedString name = currentOrPending.Name;
LocalizedString nameWithQuantity = "";
if (linkedItems.Count > 1)
{
foreach (ItemPrefab distinctItem in linkedItems.Select(it => it.Prefab).Distinct())
@@ -881,7 +881,7 @@ namespace Barotrauma
};
GUILayoutGroup buttonLayout = new GUILayoutGroup(rectT(1f, 1f, toggleButton.Frame), isHorizontal: true);
string slotText = "";
LocalizedString slotText = "";
if (linkedItems.Count > 1)
{
slotText = TextManager.GetWithVariable("weaponslot", "[number]", string.Join(", ", linkedItems.Select(it => (swappableEntities.IndexOf(it) + 1).ToString())));
@@ -891,13 +891,13 @@ namespace Barotrauma
slotText = TextManager.GetWithVariable("weaponslot", "[number]", (swappableEntities.IndexOf(item) + 1).ToString());
}
new GUITextBlock(rectT(0.3f, 1f, buttonLayout), text: slotText, font: GUI.SubHeadingFont);
new GUITextBlock(rectT(0.3f, 1f, buttonLayout), text: slotText, font: GUIStyle.SubHeadingFont);
GUILayoutGroup group = new GUILayoutGroup(rectT(0.7f, 1f, buttonLayout), isHorizontal: true) { Stretch = true };
string title = item.PendingItemSwap != null ? TextManager.GetWithVariable("upgrades.pendingitem", "[itemname]", name) : nameWithQuantity;
GUITextBlock text = new GUITextBlock(rectT(0.7f, 1f, group), text: title, font: GUI.SubHeadingFont, textAlignment: Alignment.Right, parseRichText: true)
var title = item.PendingItemSwap != null ? TextManager.GetWithVariable("upgrades.pendingitem", "[itemname]", name) : nameWithQuantity;
GUITextBlock text = new GUITextBlock(rectT(0.7f, 1f, group), text: RichString.Rich(title), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right)
{
TextColor = GUI.Style.Orange
TextColor = GUIStyle.Orange
};
GUIImage arrowImage = new GUIImage(rectT(0.5f, 1f, group, scaleBasis: ScaleBasis.BothHeight), style: "SlideDownArrow", scaleToFit: true);
@@ -911,7 +911,7 @@ namespace Barotrauma
List<GUIFrame> frames = new List<GUIFrame>();
if (currentOrPending != null)
{
bool canUninstall = item.PendingItemSwap != null || !string.IsNullOrEmpty(currentOrPending.SwappableItem?.ReplacementOnUninstall);
bool canUninstall = item.PendingItemSwap != null || !(currentOrPending.SwappableItem?.ReplacementOnUninstall.IsEmpty ?? true);
bool isUninstallPending = item.Prefab.SwappableItem != null && item.PendingItemSwap?.Identifier == item.Prefab.SwappableItem.ReplacementOnUninstall;
if (isUninstallPending) { canUninstall = false; }
@@ -928,9 +928,7 @@ namespace Barotrauma
{
string textTag = item.PendingItemSwap != null ? "upgrades.cancelitemswappromptbody" : "upgrades.itemuninstallpromptbody";
if (isUninstallPending) { textTag = "upgrades.cancelitemuninstallpromptbody"; }
string promptBody = TextManager.GetWithVariables(textTag,
new[] { "[itemtouninstall]" },
new[] { isUninstallPending ? item.Name : currentOrPending.Name });
LocalizedString promptBody = TextManager.GetWithVariable(textTag, "[itemtouninstall]", isUninstallPending ? item.Name : currentOrPending.Name);
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("upgrades.refundprompttitle"), promptBody, () =>
{
if (GameMain.NetworkMember != null)
@@ -970,9 +968,9 @@ namespace Barotrauma
buyButton.Enabled = true;
buyButton.OnClicked += (button, o) =>
{
string promptBody = TextManager.GetWithVariables(isPurchased ? "upgrades.itemswappromptbody" : "upgrades.purchaseitemswappromptbody",
new[] { "[itemtoinstall]", "[amount]" },
new[] { replacement.Name, (replacement.SwappableItem.GetPrice(Campaign?.Map?.CurrentLocation) * linkedItems.Count).ToString() });
LocalizedString promptBody = TextManager.GetWithVariables(isPurchased ? "upgrades.itemswappromptbody" : "upgrades.purchaseitemswappromptbody",
("[itemtoinstall]", replacement.Name),
("[amount]", (replacement.SwappableItem.GetPrice(Campaign?.Map?.CurrentLocation) * linkedItems.Count).ToString()));
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), promptBody, () =>
{
if (GameMain.NetworkMember != null)
@@ -1019,7 +1017,7 @@ namespace Barotrauma
var linkedItems = Campaign.UpgradeManager.GetLinkedItemsToSwap(item);
foreach (var itemPreview in itemPreviews)
{
itemPreview.Value.OutlineColor = itemPreview.Value.Color = linkedItems.Contains(itemPreview.Key) ? GUI.Style.Orange : previewWhite;
itemPreview.Value.OutlineColor = itemPreview.Value.Color = linkedItems.Contains(itemPreview.Key) ? GUIStyle.Orange : previewWhite;
}
foreach (GUIComponent otherComponent in toggleButton.Parent.Children)
{
@@ -1041,7 +1039,7 @@ namespace Barotrauma
foreach (var itemPreview in itemPreviews)
{
if (currentStoreLayout?.SelectedData is CategoryData categoryData && !categoryData.Category.ItemTags.Any(t => itemPreview.Key.HasTag(t))) { continue; }
itemPreview.Value.OutlineColor = itemPreview.Value.Color = GUI.Style.Orange;
itemPreview.Value.OutlineColor = itemPreview.Value.Color = GUIStyle.Orange;
}
}
activeItemSwapSlideDown = toggleButton.Selected ? toggleButton : null;
@@ -1058,7 +1056,7 @@ namespace Barotrauma
return CreateUpgradeEntry(rectTransform, prefab.Sprite, prefab.Name, prefab.Description, price, new CategoryData(category, prefab), addBuyButton, upgradePrefab: prefab, currentLevel: campaign.UpgradeManager.GetUpgradeLevel(prefab, category));
}
public static GUIFrame CreateUpgradeEntry(RectTransform parent, Sprite sprite, string title, string body, int price, object? userData, bool addBuyButton = true, bool addProgressBar = true, string buttonStyle = "UpgradeBuyButton", UpgradePrefab upgradePrefab = null, int currentLevel = 0)
public static GUIFrame CreateUpgradeEntry(RectTransform parent, Sprite sprite, LocalizedString title, LocalizedString body, int price, object? userData, bool addBuyButton = true, bool addProgressBar = true, string buttonStyle = "UpgradeBuyButton", UpgradePrefab? upgradePrefab = null, int currentLevel = 0)
{
float progressBarHeight = 0.25f;
@@ -1080,29 +1078,29 @@ namespace Barotrauma
GUILayoutGroup imageLayout = new GUILayoutGroup(rectT(new Point(prefabLayout.Rect.Height, prefabLayout.Rect.Height), prefabLayout), childAnchor: Anchor.Center);
var icon = new GUIImage(rectT(0.9f, 0.9f, imageLayout, scaleBasis: ScaleBasis.BothHeight), sprite, scaleToFit: true) { CanBeFocused = false };
GUILayoutGroup textLayout = new GUILayoutGroup(rectT(0.8f - imageLayout.RectTransform.RelativeSize.X, 1, prefabLayout));
var name = new GUITextBlock(rectT(1, 0.25f, textLayout), title, font: GUI.SubHeadingFont, parseRichText: true) { AutoScaleHorizontal = true, AutoScaleVertical = true, Padding = Vector4.Zero };
var name = new GUITextBlock(rectT(1, 0.25f, textLayout), RichString.Rich(title), font: GUIStyle.SubHeadingFont) { AutoScaleHorizontal = true, AutoScaleVertical = true, Padding = Vector4.Zero };
GUILayoutGroup descriptionLayout = new GUILayoutGroup(rectT(1, 0.75f - progressBarHeight, textLayout));
var description = new GUITextBlock(rectT(1, 1, descriptionLayout), body, font: GUI.SmallFont, wrap: true, textAlignment: Alignment.TopLeft) { Padding = Vector4.Zero };
var description = new GUITextBlock(rectT(1, 1, descriptionLayout), body, font: GUIStyle.SmallFont, wrap: true, textAlignment: Alignment.TopLeft) { Padding = Vector4.Zero };
GUILayoutGroup? progressLayout = null;
GUILayoutGroup? buyButtonLayout = null;
if (addProgressBar)
{
progressLayout = new GUILayoutGroup(rectT(1, 0.25f, textLayout), isHorizontal: true, childAnchor: Anchor.CenterLeft) { UserData = "progressbar" };
new GUIProgressBar(rectT(0.8f, 0.75f, progressLayout), 0.0f, GUI.Style.Orange);
new GUITextBlock(rectT(0.2f, 1, progressLayout), string.Empty, font: GUI.SmallFont, textAlignment: Alignment.Center) { Padding = Vector4.Zero };
new GUIProgressBar(rectT(0.8f, 0.75f, progressLayout), 0.0f, GUIStyle.Orange);
new GUITextBlock(rectT(0.2f, 1, progressLayout), string.Empty, font: GUIStyle.SmallFont, textAlignment: Alignment.Center) { Padding = Vector4.Zero };
}
if (addBuyButton)
{
string formattedPrice = FormatCurrency(Math.Abs(price));
var formattedPrice = FormatCurrency(Math.Abs(price));
//negative price = refund
if (price < 0) { formattedPrice = "+" + formattedPrice; }
buyButtonLayout = new GUILayoutGroup(rectT(0.2f, 1, prefabLayout), childAnchor: Anchor.TopCenter) { UserData = "buybutton" };
var priceText = new GUITextBlock(rectT(1, 0.2f, buyButtonLayout), formattedPrice, textAlignment: Alignment.Center);
if (price < 0)
{
priceText.TextColor = GUI.Style.Green;
priceText.TextColor = GUIStyle.Green;
}
else if (price == 0)
{
@@ -1120,8 +1118,8 @@ namespace Barotrauma
// cut the description if it overflows and add a tooltip to it
for (int i = 100; i > 0 && description.Rect.Height > descriptionLayout.Rect.Height; i--)
{
string[] lines = description.WrappedText.Split('\n');
var newString = string.Join('\n', lines.Take(lines.Length - 1));
var lines = description.WrappedText.Split('\n');
var newString = string.Join('\n', lines.Take(lines.Count - 1));
if (0 >= newString.Length - 4) { break; }
description.Text = newString.Substring(0, newString.Length - 4) + "...";
@@ -1185,7 +1183,9 @@ namespace Barotrauma
buyButton.OnClicked += (button, o) =>
{
string promptBody = TextManager.GetWithVariables("Upgrades.PurchasePromptBody", new []{ "[upgradename]", "[amount]"}, new []{ prefab.Name, prefab.Price.GetBuyprice(Campaign.UpgradeManager.GetUpgradeLevel(prefab, category), Campaign.Map?.CurrentLocation).ToString() });
LocalizedString promptBody = TextManager.GetWithVariables("Upgrades.PurchasePromptBody",
("[upgradename]", prefab.Name),
("[amount]", prefab.Price.GetBuyprice(Campaign.UpgradeManager.GetUpgradeLevel(prefab, category), Campaign.Map?.CurrentLocation).ToString()));
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), promptBody, () =>
{
if (GameMain.NetworkMember != null)
@@ -1225,7 +1225,7 @@ namespace Barotrauma
itemName.Text = entity is Item ? entity.Name : TextManager.Get("upgradecategory.walls");
if (slotIndex > -1)
{
itemName.Text = TextManager.GetWithVariables("weaponslotwithname", new string[] { "[number]", "[weaponname]" }, new string[] { slotIndex.ToString(), itemName.Text });
itemName.Text = TextManager.GetWithVariables("weaponslotwithname", ("[number]", slotIndex.ToString()), ("[weaponname]", itemName.Text));
}
upgradeList.Content.ClearChildren();
for (var i = 0; i < upgrades.Count && i < maxUpgrades; i++)
@@ -1246,7 +1246,7 @@ namespace Barotrauma
{
if (textBlock.UserData is Tuple<int, UpgradePrefab> tuple && tuple.Item2 == prefab)
{
string tooltip = CreateListEntry(tuple.Item2.Name, level + tuple.Item1);
var tooltip = CreateListEntry(tuple.Item2.Name, level + tuple.Item1);
textBlock.Text = tooltip;
found = true;
break;
@@ -1275,7 +1275,7 @@ namespace Barotrauma
moreIndicator.CalculateHeightFromText();
layout.Recalculate();
static string CreateListEntry(string name, int level) => TextManager.GetWithVariables("upgradeuitooltip.upgradelistelement", new[] { "[upgradename]", "[level]" }, new[] { name, $"{level}" });
static LocalizedString CreateListEntry(LocalizedString name, int level) => TextManager.GetWithVariables("upgradeuitooltip.upgradelistelement", ("[upgradename]", name), ("[level]", $"{level}"));
}
public static IEnumerable<UpgradeCategory> GetApplicableCategories(Submarine drawnSubmarine)
@@ -1343,7 +1343,7 @@ namespace Barotrauma
if (selectedUpgradeCategoryLayout != null)
{
var linkedItems = HoveredItem is Item ? Campaign.UpgradeManager.GetLinkedItemsToSwap((Item)HoveredItem) : new List<Item>();
if (selectedUpgradeCategoryLayout.FindChild(c => c.UserData as Item == HoveredItem || linkedItems.Contains(c.UserData as Item), recursive: true) is GUIButton itemElement)
if (selectedUpgradeCategoryLayout.FindChild(c => c.UserData as Item == HoveredItem || linkedItems.Contains((Item)c.UserData), recursive: true) is GUIButton itemElement)
{
if (!itemElement.Selected) { itemElement.OnClicked(itemElement, itemElement.UserData); }
(itemElement.Parent?.Parent?.Parent as GUIListBox)?.ScrollToElement(itemElement);
@@ -1417,9 +1417,9 @@ namespace Barotrauma
*/
submarineInfoFrame = new GUILayoutGroup(rectT(0.25f, 0.2f, mainStoreLayout, Anchor.TopRight)) { IgnoreLayoutGroups = true };
// submarine name
new GUITextBlock(rectT(1, 0, submarineInfoFrame), submarine.Info.DisplayName, textAlignment: Alignment.Right, font: GUI.LargeFont);
new GUITextBlock(rectT(1, 0, submarineInfoFrame), submarine.Info.DisplayName, textAlignment: Alignment.Right, font: GUIStyle.LargeFont);
// submarine class
new GUITextBlock(rectT(1, 0, submarineInfoFrame), $"{TextManager.GetWithVariable("submarineclass.classsuffixformat", "[type]", TextManager.Get($"submarineclass.{submarine.Info.SubmarineClass}"))}", textAlignment: Alignment.Right, font: GUI.Font);
new GUITextBlock(rectT(1, 0, submarineInfoFrame), $"{TextManager.GetWithVariable("submarineclass.classsuffixformat", "[type]", TextManager.Get($"submarineclass.{submarine.Info.SubmarineClass}"))}", textAlignment: Alignment.Right, font: GUIStyle.Font);
var description = new GUITextBlock(rectT(1, 0, submarineInfoFrame), submarine.Info.Description, textAlignment: Alignment.Right, wrap: true);
submarineInfoFrame.RectTransform.ScreenSpaceOffset = new Point(0, (int)(16 * GUI.Scale));
@@ -1448,7 +1448,7 @@ namespace Barotrauma
Point size = new Point((int) (spriteSize * item.Scale / dockedBorders.Width * hullContainer.Rect.Width));
itemFrame = new GUIImage(rectT(size, component, Anchor.Center), icon, scaleToFit: true)
{
SelectedColor = GUI.Style.Orange,
SelectedColor = GUIStyle.Orange,
Color = previewWhite,
HoverCursor = CursorState.Hand,
SpriteEffects = item.Rotation > 90.0f && item.Rotation < 270.0f ? SpriteEffects.FlipVertically : SpriteEffects.None
@@ -1457,7 +1457,7 @@ namespace Barotrauma
{
new GUIImage(new RectTransform(new Vector2(0.8f), itemFrame.RectTransform, Anchor.TopLeft) { RelativeOffset = new Vector2(-0.2f) }, "WeaponSwitchIcon.DropShadow", scaleToFit: true)
{
SelectedColor = GUI.Style.Orange,
SelectedColor = GUIStyle.Orange,
Color = previewWhite,
CanBeFocused = false
};
@@ -1468,7 +1468,7 @@ namespace Barotrauma
Point size = new Point((int) (item.Rect.Width * item.Scale / dockedBorders.Width * hullContainer.Rect.Width), (int) (item.Rect.Height * item.Scale / dockedBorders.Height * hullContainer.Rect.Height));
itemFrame = new GUIFrame(rectT(size, component, Anchor.Center), style: "ScanLines")
{
SelectedColor = GUI.Style.Orange,
SelectedColor = GUIStyle.Orange,
OutlineColor = previewWhite,
Color = previewWhite,
OutlineThickness = 2,
@@ -1540,7 +1540,7 @@ namespace Barotrauma
// calculate the center point so we can draw a line from X to Y instead of drawing a rotated rectangle that is filled
Vector2 point1 = hullVertex[1] + (hullVertex[2] - hullVertex[1]) / 2;
Vector2 point2 = hullVertex[0] + (hullVertex[3] - hullVertex[0]) / 2;
GUI.DrawLine(spriteBatch, point1, point2, (highlightWalls ? GUI.Style.Orange * 0.6f : Color.DarkCyan * 0.3f), width: 10);
GUI.DrawLine(spriteBatch, point1, point2, (highlightWalls ? GUIStyle.Orange * 0.6f : Color.DarkCyan * 0.3f), width: 10);
if (GameMain.DebugDraw)
{
// the "collision box" is a bit bigger than the line we draw so this can be useful data (maybe)
@@ -1553,14 +1553,14 @@ namespace Barotrauma
{
int currentLevel = campaign.UpgradeManager.GetUpgradeLevel(prefab, category);
string progressText = TextManager.GetWithVariables("upgrades.progressformat", new[] { "[level]", "[maxlevel]" }, new[] { currentLevel.ToString(), prefab.MaxLevel.ToString() });
LocalizedString progressText = TextManager.GetWithVariables("upgrades.progressformat", ("[level]", currentLevel.ToString()), ("[maxlevel]", prefab.MaxLevel.ToString()));
if (prefabFrame.FindChild("progressbar", true) is { } progressParent)
{
GUIProgressBar bar = progressParent.GetChild<GUIProgressBar>();
if (bar != null)
{
bar.BarSize = currentLevel / (float) prefab.MaxLevel;
bar.Color = currentLevel >= prefab.MaxLevel ? GUI.Style.Green : GUI.Style.Orange;
bar.Color = currentLevel >= prefab.MaxLevel ? GUIStyle.Green : GUIStyle.Orange;
}
GUITextBlock block = progressParent.GetChild<GUITextBlock>();
@@ -1620,7 +1620,7 @@ namespace Barotrauma
else
{
parent.Enabled = false;
parent.SelectedColor = GUI.Style.Red * 0.5f;
parent.SelectedColor = GUIStyle.Red * 0.5f;
}
}
@@ -1632,12 +1632,12 @@ namespace Barotrauma
{
if (component.UserData != prefab) { continue; }
Dictionary<string, GUIComponentStyle> styles = GUI.Style.GetComponentStyle("upgradeindicator").ChildStyles;
Dictionary<Identifier, GUIComponentStyle> styles = GUIStyle.GetComponentStyle("upgradeindicator").ChildStyles;
if (!styles.ContainsKey("upgradeindicatoron") || !styles.ContainsKey("upgradeindicatordim") || !styles.ContainsKey("upgradeindicatoroff")) { continue; }
GUIComponentStyle onStyle = styles["upgradeindicatoron"];
GUIComponentStyle dimStyle = styles["upgradeindicatordim"];
GUIComponentStyle offStyle = styles["upgradeindicatoroff"];
GUIComponentStyle onStyle = styles["upgradeindicatoron".ToIdentifier()];
GUIComponentStyle dimStyle = styles["upgradeindicatordim".ToIdentifier()];
GUIComponentStyle offStyle = styles["upgradeindicatoroff".ToIdentifier()];
if (campaign.UpgradeManager.GetUpgradeLevel(prefab, category) >= prefab.MaxLevel)
{
@@ -1694,7 +1694,7 @@ namespace Barotrauma
private bool HasPermission => campaignUI.Campaign.AllowedToManageCampaign();
public static string FormatCurrency(int money, bool format = true)
public static LocalizedString FormatCurrency(int money, bool format = true)
{
return TextManager.GetWithVariable("CurrencyFormat", "[credits]", format ? string.Format(CultureInfo.InvariantCulture, "{0:N0}", money) : money.ToString());
}
@@ -34,23 +34,29 @@ namespace Barotrauma
public class TextSettings
{
public string Text;
public LocalizedString Text;
public int Width;
public TextSettings(Identifier textTag, int width)
{
Text = TextManager.GetFormatted(textTag);
Width = width;
}
public TextSettings(XElement element)
{
Text = TextManager.GetFormatted(element.GetAttributeString("text", string.Empty), true);
Text = TextManager.GetFormatted(element.GetAttributeIdentifier("text", Identifier.Empty));
Width = element.GetAttributeInt("width", 450);
}
}
public class VideoSettings
{
public string File;
public readonly string File;
public VideoSettings(XElement element)
public VideoSettings(string file)
{
File = element.GetAttributeString("file", string.Empty);
File = file;
}
}
@@ -75,13 +81,13 @@ namespace Barotrauma
}
videoView = new GUICustomComponent(new RectTransform(Point.Zero, videoFrame.RectTransform, Anchor.Center), (spriteBatch, guiCustomComponent) => { DrawVideo(spriteBatch, guiCustomComponent.Rect); });
title = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft), string.Empty, font: GUI.LargeFont, textColor: new Color(253, 174, 0), textAlignment: Alignment.Left);
title = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft), string.Empty, font: GUIStyle.LargeFont, textColor: new Color(253, 174, 0), textAlignment: Alignment.Left);
textContent = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft), string.Empty, font: GUI.Font, textAlignment: Alignment.TopLeft);
textContent = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft), string.Empty, font: GUIStyle.Font, textAlignment: Alignment.TopLeft);
objectiveTitle = new GUITextBlock(new RectTransform(new Vector2(1f, 0f), textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUI.SubHeadingFont, textAlignment: Alignment.CenterRight, textColor: Color.White);
objectiveTitle = new GUITextBlock(new RectTransform(new Vector2(1f, 0f), textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterRight, textColor: Color.White);
objectiveTitle.Text = TextManager.Get("Tutorial.NewObjective");
objectiveText = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUI.SubHeadingFont, textColor: new Color(4, 180, 108), textAlignment: Alignment.CenterRight);
objectiveText = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUIStyle.SubHeadingFont, textColor: new Color(4, 180, 108), textAlignment: Alignment.CenterRight);
objectiveTitle.Visible = objectiveText.Visible = false;
}
@@ -120,7 +126,12 @@ namespace Barotrauma
background.AddToGUIUpdateList(ignoreChildren, order);
}
public void LoadContent(string contentPath, VideoSettings videoSettings, TextSettings textSettings, string contentId, bool startPlayback, string objective = "", Action callback = null)
public void LoadContent(string contentPath, VideoSettings videoSettings, TextSettings textSettings, Identifier contentId, bool startPlayback)
{
LoadContent(contentPath, videoSettings, textSettings, contentId, startPlayback, new RawLString(""), null);
}
public void LoadContent(string contentPath, VideoSettings videoSettings, TextSettings textSettings, Identifier contentId, bool startPlayback, LocalizedString objective, Action callback = null)
{
callbackOnStop = callback;
filePath = contentPath + videoSettings.File;
@@ -183,10 +194,10 @@ namespace Barotrauma
title.RectTransform.NonScaledSize = new Point(scaledTextWidth, scaledTitleHeight);
title.RectTransform.AbsoluteOffset = new Point((int)(5 * GUI.Scale), (int)(10 * GUI.Scale));
if (textSettings != null && !string.IsNullOrEmpty(textSettings.Text))
if (textSettings != null && !textSettings.Text.IsNullOrEmpty())
{
textSettings.Text = ToolBox.WrapText(textSettings.Text, scaledTextWidth, GUI.Font);
int wrappedHeight = textSettings.Text.Split('\n').Length * scaledTextHeight;
textSettings.Text = ToolBox.WrapText(textSettings.Text, scaledTextWidth, GUIStyle.Font);
int wrappedHeight = textSettings.Text.Value.Split('\n').Length * scaledTextHeight;
textFrame.RectTransform.NonScaledSize = new Point(scaledTextWidth + scaledBorderSize, wrappedHeight + scaledBorderSize + scaledButtonSize.Y + scaledTitleHeight);
@@ -203,7 +214,7 @@ namespace Barotrauma
textContent.RectTransform.AbsoluteOffset = new Point(0, scaledBorderSize + scaledTitleHeight);
}
if (!string.IsNullOrEmpty(objectiveText.Text))
if (!objectiveText.Text.IsNullOrEmpty())
{
int scaledXOffset = (int)(-10 * GUI.Scale);
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
@@ -19,12 +18,11 @@ namespace Barotrauma
private Func<int> getYesVotes, getNoVotes, getMaxVotes;
private bool votePassed;
private string votingOnText;
private List<RichTextData> votingOnTextData;
private RichString votingOnText;
private float votingTime = 100f;
private float timer;
private VoteType currentVoteType;
private Color submarineColor => GUI.Style.Orange;
private Color submarineColor => GUIStyle.Orange;
private Point createdForResolution;
public VotingInterface(Client starter, SubmarineInfo info, VoteType type, float votingTime)
@@ -60,14 +58,14 @@ namespace Barotrauma
int yOffset = padding;
int paddedWidth = frame.Rect.Width - padding * 2;
votingTextBlock = new GUITextBlock(new RectTransform(new Point(paddedWidth, 0), frame.RectTransform), votingOnTextData, votingOnText, wrap: true);
votingTextBlock = new GUITextBlock(new RectTransform(new Point(paddedWidth, 0), frame.RectTransform), votingOnText, wrap: true);
votingTextBlock.RectTransform.NonScaledSize = votingTextBlock.RectTransform.MinSize = votingTextBlock.RectTransform.MaxSize = new Point(votingTextBlock.Rect.Width, votingTextBlock.Rect.Height);
votingTextBlock.RectTransform.IsFixedSize = true;
votingTextBlock.RectTransform.AbsoluteOffset = new Point(padding, yOffset);
yOffset += votingTextBlock.Rect.Height + spacing;
voteCounter = new GUITextBlock(new RectTransform(new Point(paddedWidth, 0), frame.RectTransform), "(0/0)", GUI.Style.Green, textAlignment: Alignment.Center);
voteCounter = new GUITextBlock(new RectTransform(new Point(paddedWidth, 0), frame.RectTransform), "(0/0)", GUIStyle.Green, textAlignment: Alignment.Center);
voteCounter.RectTransform.NonScaledSize = voteCounter.RectTransform.MinSize = voteCounter.RectTransform.MaxSize = new Point(voteCounter.Rect.Width, voteCounter.Rect.Height);
voteCounter.RectTransform.IsFixedSize = true;
voteCounter.RectTransform.AbsoluteOffset = new Point(padding, yOffset);
@@ -150,26 +148,41 @@ namespace Barotrauma
switch (type)
{
case VoteType.PurchaseAndSwitchSub:
votingOnText = TextManager.GetWithVariables("submarinepurchaseandswitchvote", new string[] { "[playername]", "[submarinename]", "[amount]", "[currencyname]" }, new string[] { characterRichString, submarineRichString, info.Price.ToString(), TextManager.Get("credit").ToLower() });
votingOnText = TextManager.GetWithVariables("submarinepurchaseandswitchvote",
("[playername]", characterRichString),
("[submarinename]", submarineRichString),
("[amount]", info.Price.ToString()),
("[currencyname]", TextManager.Get("credit").ToLower()));
break;
case VoteType.PurchaseSub:
votingOnText = TextManager.GetWithVariables("submarinepurchasevote", new string[] { "[playername]", "[submarinename]", "[amount]", "[currencyname]" }, new string[] { characterRichString, submarineRichString, info.Price.ToString(), TextManager.Get("credit").ToLower() });
votingOnText = TextManager.GetWithVariables("submarinepurchasevote",
("[playername]", characterRichString),
("[submarinename]", submarineRichString),
("[amount]", info.Price.ToString()),
("[currencyname]", TextManager.Get("credit").ToLower()));
break;
case VoteType.SwitchSub:
int deliveryFee = SubmarineSelection.DeliveryFeePerDistanceTravelled * GameMain.GameSession.Map.DistanceToClosestLocationWithOutpost(GameMain.GameSession.Map.CurrentLocation, out Location endLocation);
if (deliveryFee > 0)
{
votingOnText = TextManager.GetWithVariables("submarineswitchfeevote", new string[] { "[playername]", "[submarinename]", "[locationname]", "[amount]", "[currencyname]" }, new string[] { characterRichString, submarineRichString, endLocation.Name, deliveryFee.ToString(), TextManager.Get("credit").ToLower() });
votingOnText = TextManager.GetWithVariables("submarineswitchfeevote",
("[playername]", characterRichString),
("[submarinename]", submarineRichString),
("[locationname]", endLocation.Name),
("[amount]", deliveryFee.ToString()),
("[currencyname]", TextManager.Get("credit").ToLower()));
}
else
{
votingOnText = TextManager.GetWithVariables("submarineswitchnofeevote", new string[] { "[playername]", "[submarinename]" }, new string[] { characterRichString, submarineRichString });
votingOnText = TextManager.GetWithVariables("submarineswitchnofeevote",
("[playername]", characterRichString),
("[submarinename]", submarineRichString));
}
break;
}
votingOnTextData = RichTextData.GetRichTextData(votingOnText, out votingOnText);
votingOnText = RichString.Rich(votingOnText);
}
private int SubmarineYesVotes()
@@ -189,31 +202,50 @@ namespace Barotrauma
private void SendSubmarineVoteEndMessage(SubmarineInfo info, VoteType type)
{
GameMain.NetworkMember.AddChatMessage(GetSubmarineVoteResultMessage(info, type, yesVotes.ToString(), noVotes.ToString(), votePassed), ChatMessageType.Server);
GameMain.NetworkMember.AddChatMessage(GetSubmarineVoteResultMessage(info, type, yesVotes.ToString(), noVotes.ToString(), votePassed).Value, ChatMessageType.Server);
}
public static string GetSubmarineVoteResultMessage(SubmarineInfo info, VoteType type, string yesVoteString, string noVoteString, bool votePassed)
public static LocalizedString GetSubmarineVoteResultMessage(SubmarineInfo info, VoteType type, string yesVoteString, string noVoteString, bool votePassed)
{
string result = string.Empty;
LocalizedString result = string.Empty;
switch (type)
{
case VoteType.PurchaseAndSwitchSub:
result = TextManager.GetWithVariables(votePassed ? "submarinepurchaseandswitchvotepassed" : "submarinepurchaseandswitchvotefailed", new string[] { "[submarinename]", "[amount]", "[currencyname]", "[yesvotecount]", "[novotecount]" }, new string[] { info.DisplayName, info.Price.ToString(), TextManager.Get("credit").ToLower(), yesVoteString, noVoteString });
result = TextManager.GetWithVariables(votePassed ? "submarinepurchaseandswitchvotepassed" : "submarinepurchaseandswitchvotefailed",
("[submarinename]", info.DisplayName),
("[amount]", info.Price.ToString()),
("[currencyname]", TextManager.Get("credit").ToLower()),
("[yesvotecount]", yesVoteString),
("[novotecount]" , noVoteString));
break;
case VoteType.PurchaseSub:
result = TextManager.GetWithVariables(votePassed ? "submarinepurchasevotepassed" : "submarinepurchasevotefailed", new string[] { "[submarinename]", "[amount]", "[currencyname]", "[yesvotecount]", "[novotecount]" }, new string[] { info.DisplayName, info.Price.ToString(), TextManager.Get("credit").ToLower(), yesVoteString, noVoteString });
result = TextManager.GetWithVariables(votePassed ? "submarinepurchasevotepassed" : "submarinepurchasevotefailed",
("[submarinename]", info.DisplayName),
("[amount]", info.Price.ToString()),
("[currencyname]", TextManager.Get("credit").ToLower()),
("[yesvotecount]", yesVoteString),
("[novotecount]", noVoteString));
break;
case VoteType.SwitchSub:
int deliveryFee = SubmarineSelection.DeliveryFeePerDistanceTravelled * GameMain.GameSession.Map.DistanceToClosestLocationWithOutpost(GameMain.GameSession.Map.CurrentLocation, out Location endLocation);
if (deliveryFee > 0)
{
result = TextManager.GetWithVariables(votePassed ? "submarineswitchfeevotepassed" : "submarineswitchfeevotefailed", new string[] { "[submarinename]", "[locationname]", "[amount]", "[currencyname]", "[yesvotecount]", "[novotecount]" }, new string[] { info.DisplayName, endLocation.Name, deliveryFee.ToString(), TextManager.Get("credit").ToLower(), yesVoteString, noVoteString });
result = TextManager.GetWithVariables(votePassed ? "submarineswitchfeevotepassed" : "submarineswitchfeevotefailed",
("[submarinename]", info.DisplayName),
("[locationname]", endLocation.Name),
("[amount]", deliveryFee.ToString()),
("[currencyname]", TextManager.Get("credit").ToLower()),
("[yesvotecount]", yesVoteString),
("[novotecount]", noVoteString));
}
else
{
result = TextManager.GetWithVariables(votePassed ? "submarineswitchnofeevotepassed" : "submarineswitchnofeevotefailed", new string[] { "[submarinename]", "[yesvotecount]", "[novotecount]" }, new string[] { info.DisplayName, yesVoteString, noVoteString });
result = TextManager.GetWithVariables(votePassed ? "submarineswitchnofeevotepassed" : "submarineswitchnofeevotefailed",
("[submarinename]", info.DisplayName),
("[yesvotecount]", yesVoteString),
("[novotecount]", noVoteString));
}
break;
default:
@@ -17,7 +17,7 @@ namespace Barotrauma
}
public Shape shape;
public string tooltip;
public LocalizedString tooltip;
public bool showTooltip = true;
public Rectangle DrawRect => new Rectangle((int)(DrawPos.X - (float)size / 2), (int)(DrawPos.Y - (float)size / 2), size, size);
public Rectangle InputRect
@@ -42,7 +42,7 @@ namespace Barotrauma
/// </summary>
public bool isFilled;
public int inputAreaMargin;
public Color color = GUI.Style.Red;
public Color color = GUIStyle.Red;
public Color? secondaryColor;
public Color textColor = Color.White;
public Color textBackgroundColor = Color.Black * 0.5f;
@@ -183,7 +183,7 @@ namespace Barotrauma
}
if (IsSelected)
{
if (showTooltip && !string.IsNullOrEmpty(tooltip))
if (showTooltip && !tooltip.IsNullOrEmpty())
{
var offset = tooltipOffset ?? new Vector2(size, -size / 2f);
GUI.DrawString(spriteBatch, DrawPos + offset, tooltip, textColor, textBackgroundColor);