Merge branch 'dev' of https://github.com/Regalis11/Barotrauma into unstable
This commit is contained in:
@@ -325,6 +325,12 @@ namespace Barotrauma
|
||||
ToggleOpen = PreferChatBoxOpen = GameSettings.CurrentConfig.ChatOpen;
|
||||
}
|
||||
|
||||
public void Toggle()
|
||||
{
|
||||
ToggleOpen = !ToggleOpen;
|
||||
CloseAfterMessageSent = false;
|
||||
}
|
||||
|
||||
public bool TypingChatMessage(GUITextBox textBox, string text)
|
||||
{
|
||||
string command = ChatMessage.GetChatMessageCommand(text, out _);
|
||||
@@ -611,22 +617,29 @@ namespace Barotrauma
|
||||
showNewMessagesButton.Visible = false;
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyHit(InputType.ToggleChatMode) && GUI.KeyboardDispatcher.Subscriber == null && Screen.Selected == GameMain.GameScreen)
|
||||
if (Screen.Selected == GameMain.GameScreen && GUI.KeyboardDispatcher.Subscriber == null)
|
||||
{
|
||||
try
|
||||
if (PlayerInput.KeyHit(InputType.ToggleChatMode))
|
||||
{
|
||||
var mode = GameMain.ActiveChatMode switch
|
||||
try
|
||||
{
|
||||
ChatMode.Local => ChatMode.Radio,
|
||||
ChatMode.Radio => ChatMode.Local,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
ChatModeDropDown.SelectItem(mode);
|
||||
// TODO: Play a sound?
|
||||
var mode = GameMain.ActiveChatMode switch
|
||||
{
|
||||
ChatMode.Local => ChatMode.Radio,
|
||||
ChatMode.Radio => ChatMode.Local,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
ChatModeDropDown.SelectItem(mode);
|
||||
// TODO: Play a sound?
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error toggling chat mode: not implemented for current mode \"{GameMain.ActiveChatMode}\"");
|
||||
}
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
else if (PlayerInput.KeyHit(InputType.ChatBox))
|
||||
{
|
||||
DebugConsole.ThrowError($"Error toggling chat mode: not implemented for current mode \"{GameMain.ActiveChatMode}\"");
|
||||
Toggle();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -128,10 +128,11 @@ namespace Barotrauma
|
||||
|
||||
var sortGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.04f), hireablesGroup.RectTransform), isHorizontal: true)
|
||||
{
|
||||
RelativeSpacing = 0.015f
|
||||
RelativeSpacing = 0.015f,
|
||||
Stretch = true
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.15f, 1.0f), sortGroup.RectTransform), text: TextManager.Get("campaignstore.sortby"));
|
||||
sortingDropDown = new GUIDropDown(new RectTransform(new Vector2(0.4f, 1.0f), sortGroup.RectTransform), elementCount: 5)
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), sortGroup.RectTransform), text: TextManager.Get("campaignstore.sortby"));
|
||||
sortingDropDown = new GUIDropDown(new RectTransform(new Vector2(0.5f, 1.0f), sortGroup.RectTransform), elementCount: 5)
|
||||
{
|
||||
OnSelected = (child, userData) =>
|
||||
{
|
||||
@@ -193,19 +194,20 @@ namespace Barotrauma
|
||||
{
|
||||
RelativeSpacing = 0.01f
|
||||
};
|
||||
validateHiresButton = new GUIButton(new RectTransform(new Vector2(1.0f / 3.0f, 1.0f), group.RectTransform), text: TextManager.Get("campaigncrew.validate"))
|
||||
validateHiresButton = new GUIButton(new RectTransform(new Vector2(0.4f, 1.0f), group.RectTransform), text: TextManager.Get("campaigncrew.validate"))
|
||||
{
|
||||
ClickSound = GUISoundType.ConfirmTransaction,
|
||||
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"))
|
||||
clearAllButton = new GUIButton(new RectTransform(new Vector2(0.4f, 1.0f), group.RectTransform), text: TextManager.Get("campaignstore.clearall"))
|
||||
{
|
||||
ClickSound = GUISoundType.Cart,
|
||||
ForceUpperCase = ForceUpperCase.Yes,
|
||||
Enabled = HasPermission,
|
||||
OnClicked = (b, o) => RemoveAllPendingHires()
|
||||
};
|
||||
GUITextBlock.AutoScaleAndNormalize(validateHiresButton.TextBlock, clearAllButton.TextBlock);
|
||||
|
||||
resolutionWhenCreated = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||
}
|
||||
@@ -528,7 +530,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(" ".ToIdentifier(), Identifier.Empty)));
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoValueGroup.RectTransform), trait.DisplayName);
|
||||
}
|
||||
infoLabelGroup.Recalculate();
|
||||
infoValueGroup.Recalculate();
|
||||
@@ -887,35 +889,35 @@ namespace Barotrauma
|
||||
if (campaign is MultiPlayerCampaign)
|
||||
{
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.Write((byte)ClientPacketHeader.CREW);
|
||||
msg.WriteByte((byte)ClientPacketHeader.CREW);
|
||||
|
||||
msg.Write(updatePending);
|
||||
msg.WriteBoolean(updatePending);
|
||||
if (updatePending)
|
||||
{
|
||||
msg.Write((ushort)PendingHires.Count);
|
||||
msg.WriteUInt16((ushort)PendingHires.Count);
|
||||
foreach (CharacterInfo pendingHire in PendingHires)
|
||||
{
|
||||
msg.Write(pendingHire.GetIdentifierUsingOriginalName());
|
||||
msg.WriteInt32(pendingHire.GetIdentifierUsingOriginalName());
|
||||
}
|
||||
}
|
||||
|
||||
msg.Write(validateHires);
|
||||
msg.WriteBoolean(validateHires);
|
||||
|
||||
bool validRenaming = renameCharacter.info != null && !string.IsNullOrEmpty(renameCharacter.newName);
|
||||
msg.Write(validRenaming);
|
||||
msg.WriteBoolean(validRenaming);
|
||||
if (validRenaming)
|
||||
{
|
||||
int identifier = renameCharacter.info.GetIdentifierUsingOriginalName();
|
||||
msg.Write(identifier);
|
||||
msg.Write(renameCharacter.newName);
|
||||
msg.WriteInt32(identifier);
|
||||
msg.WriteString(renameCharacter.newName);
|
||||
bool existingCrewMember = campaign.CrewManager?.GetCharacterInfos().Any(ci => ci.GetIdentifierUsingOriginalName() == identifier) ?? false;
|
||||
msg.Write(existingCrewMember);
|
||||
msg.WriteBoolean(existingCrewMember);
|
||||
}
|
||||
|
||||
msg.Write(firedCharacter != null);
|
||||
msg.WriteBoolean(firedCharacter != null);
|
||||
if (firedCharacter != null)
|
||||
{
|
||||
msg.Write(firedCharacter.GetIdentifier());
|
||||
msg.WriteInt32(firedCharacter.GetIdentifier());
|
||||
}
|
||||
|
||||
GameMain.Client.ClientPeer?.Send(msg, DeliveryMethod.Reliable);
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Barotrauma
|
||||
WaitingBackground = 6, // Cursor + Hourglass
|
||||
}
|
||||
|
||||
public static class GUI
|
||||
static class GUI
|
||||
{
|
||||
public static GUICanvas Canvas => GUICanvas.Instance;
|
||||
public static CursorState MouseCursor = CursorState.Default;
|
||||
@@ -410,7 +410,7 @@ namespace Barotrauma
|
||||
{
|
||||
y += yStep;
|
||||
DrawString(spriteBatch, new Vector2(10, y),
|
||||
"Sub pos: " + Submarine.MainSub.Position.ToPoint(),
|
||||
"Sub pos: " + Submarine.MainSub.WorldPosition.ToPoint(),
|
||||
Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
|
||||
}
|
||||
|
||||
@@ -879,6 +879,11 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<GUIComponent> GetAdditions()
|
||||
{
|
||||
return additions;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static GUIComponent MouseOn { get; private set; }
|
||||
@@ -958,7 +963,7 @@ namespace Barotrauma
|
||||
// Wire cursors
|
||||
if (Character.Controlled != null)
|
||||
{
|
||||
if (Character.Controlled.SelectedConstruction?.GetComponent<ConnectionPanel>() != null)
|
||||
if (Character.Controlled.SelectedItem?.GetComponent<ConnectionPanel>() != null)
|
||||
{
|
||||
if (Connection.DraggingConnected != null)
|
||||
{
|
||||
@@ -981,7 +986,7 @@ namespace Barotrauma
|
||||
return editor.GetMouseCursorState();
|
||||
// Portrait area during gameplay
|
||||
case GameScreen _ when !(Character.Controlled?.ShouldLockHud() ?? true):
|
||||
if (HUDLayoutSettings.BottomRightInfoArea.Contains(PlayerInput.MousePosition) || CharacterHealth.IsMouseOnHealthBar())
|
||||
if (CharacterHUD.MouseOnCharacterPortrait() || CharacterHealth.IsMouseOnHealthBar())
|
||||
{
|
||||
return CursorState.Hand;
|
||||
}
|
||||
@@ -1018,6 +1023,11 @@ namespace Barotrauma
|
||||
|
||||
if (c.Enabled)
|
||||
{
|
||||
var dragHandle = c as GUIDragHandle ?? parent as GUIDragHandle;
|
||||
if (dragHandle != null)
|
||||
{
|
||||
return dragHandle.Dragging ? CursorState.Dragging : CursorState.Hand;
|
||||
}
|
||||
// Some parent elements take priority
|
||||
// but not when the child is a GUIButton or GUITickBox
|
||||
if (!(parent is GUIButton) && !(parent is GUIListBox) ||
|
||||
@@ -1027,6 +1037,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Children in list boxes can be interacted with despite not having
|
||||
// a GUIButton inside of them so instead of hard coding we check if
|
||||
// the children can be interacted with by checking their hover state
|
||||
@@ -1097,6 +1108,8 @@ namespace Barotrauma
|
||||
return list;
|
||||
case GUIScrollBar bar:
|
||||
return bar;
|
||||
case GUIDragHandle dragHandle:
|
||||
return dragHandle;
|
||||
}
|
||||
}
|
||||
component = parent;
|
||||
@@ -1344,7 +1357,7 @@ namespace Barotrauma
|
||||
/// <param name="createOffset">Should the indicator move based on the camera position?</param>
|
||||
/// <param name="overrideAlpha">Override the distance-based alpha value with the specified alpha value</param>
|
||||
public static void DrawIndicator(SpriteBatch spriteBatch, in Vector2 worldPosition, Camera cam, in Range<float> visibleRange, Sprite sprite, in Color color,
|
||||
bool createOffset = true, float scaleMultiplier = 1.0f, float? overrideAlpha = null)
|
||||
bool createOffset = true, float scaleMultiplier = 1.0f, float? overrideAlpha = null, LocalizedString label = null)
|
||||
{
|
||||
Vector2 diff = worldPosition - cam.WorldViewCenter;
|
||||
float dist = diff.Length();
|
||||
@@ -1394,10 +1407,6 @@ namespace Barotrauma
|
||||
|
||||
angle = MathHelper.Lerp(originalAngle, angle, MathHelper.Clamp(((screenDist + 10f) - iconDiff.Length()) / 10f, 0f, 1f));
|
||||
|
||||
/*Vector2 unclampedDiff = new Vector2(
|
||||
(float)Math.Cos(angle) * screenDist,
|
||||
(float)-Math.Sin(angle) * screenDist);*/
|
||||
|
||||
iconDiff = new Vector2(
|
||||
(float)Math.Cos(angle) * Math.Min(GameMain.GraphicsWidth * 0.4f, screenDist),
|
||||
(float)-Math.Sin(angle) * Math.Min(GameMain.GraphicsHeight * 0.4f, screenDist));
|
||||
@@ -1405,7 +1414,20 @@ namespace Barotrauma
|
||||
Vector2 iconPos = cam.WorldToScreen(cam.WorldViewCenter) + iconDiff;
|
||||
sprite.Draw(spriteBatch, iconPos, color * alpha, rotate: 0.0f, scale: symbolScale);
|
||||
|
||||
if (/*unclampedDiff.Length()*/ screenDist - 10 > iconDiff.Length())
|
||||
if (label != null)
|
||||
{
|
||||
float cursorDist = Vector2.Distance(PlayerInput.MousePosition, iconPos);
|
||||
if (cursorDist < sprite.size.X * symbolScale)
|
||||
{
|
||||
Vector2 textSize = GUIStyle.Font.MeasureString(label);
|
||||
Vector2 textPos = iconPos + new Vector2(sprite.size.X * symbolScale * 0.7f * Math.Sign(-iconDiff.X), -textSize.Y / 2);
|
||||
if (iconDiff.X > 0) { textPos.X -= textSize.X; }
|
||||
DrawString(spriteBatch, textPos + Vector2.One, label, Color.Black);
|
||||
DrawString(spriteBatch, textPos, label, color);
|
||||
}
|
||||
}
|
||||
|
||||
if (screenDist - 10 > iconDiff.Length())
|
||||
{
|
||||
Vector2 normalizedDiff = Vector2.Normalize(targetScreenPos - iconPos);
|
||||
Vector2 arrowOffset = normalizedDiff * sprite.size.X * symbolScale * 0.7f;
|
||||
@@ -1465,9 +1487,9 @@ namespace Barotrauma
|
||||
depth);
|
||||
}
|
||||
|
||||
public static void DrawString(SpriteBatch sb, Vector2 pos, LocalizedString text, Color color, Color? backgroundColor = null, int backgroundPadding = 0, GUIFont font = null)
|
||||
public static void DrawString(SpriteBatch sb, Vector2 pos, LocalizedString text, Color color, Color? backgroundColor = null, int backgroundPadding = 0, GUIFont font = null, ForceUpperCase forceUpperCase = ForceUpperCase.Inherit)
|
||||
{
|
||||
DrawString(sb, pos, text.Value, color, backgroundColor, backgroundPadding, font);
|
||||
DrawString(sb, pos, text.Value, color, backgroundColor, backgroundPadding, font, forceUpperCase);
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
@@ -486,7 +486,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (bounceTimer > 3.0f || bounceDown)
|
||||
{
|
||||
RectTransform.ScreenSpaceOffset = new Point(RectTransform.ScreenSpaceOffset.X, (int) -(bounceJump * 10f));
|
||||
RectTransform.ScreenSpaceOffset = new Point(RectTransform.ScreenSpaceOffset.X, (int) -(bounceJump * 15f * GUI.Scale));
|
||||
if (!bounceDown)
|
||||
{
|
||||
bounceJump += deltaTime * 4;
|
||||
@@ -503,6 +503,7 @@ namespace Barotrauma
|
||||
bounceJump = 0.0f;
|
||||
bounceTimer = 0.0f;
|
||||
bounceDown = false;
|
||||
Bounce = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -730,7 +731,7 @@ namespace Barotrauma
|
||||
public void DrawToolTip(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (!Visible) { return; }
|
||||
DrawToolTip(spriteBatch, ToolTip, GUI.MouseOn.Rect);
|
||||
DrawToolTip(spriteBatch, ToolTip, Rect);
|
||||
}
|
||||
|
||||
public static void DrawToolTip(SpriteBatch spriteBatch, RichString toolTip, Vector2 pos)
|
||||
@@ -781,7 +782,7 @@ namespace Barotrauma
|
||||
if (toolTipBlock.Rect.Bottom > GameMain.GraphicsHeight - 10)
|
||||
{
|
||||
toolTipBlock.RectTransform.AbsoluteOffset -= new Point(
|
||||
(targetElement.Width / 2) * Math.Sign(targetElement.Center.X - toolTipBlock.Center.X),
|
||||
0,
|
||||
toolTipBlock.Rect.Bottom - (GameMain.GraphicsHeight - 10));
|
||||
}
|
||||
toolTipBlock.SetTextPos();
|
||||
@@ -806,9 +807,16 @@ namespace Barotrauma
|
||||
flashColor = (color == null) ? GUIStyle.Red : (Color)color;
|
||||
}
|
||||
|
||||
public void FadeOut(float duration, bool removeAfter, float wait = 0.0f)
|
||||
public void ImmediateFlash(Color? color = null)
|
||||
{
|
||||
CoroutineManager.StartCoroutine(LerpAlpha(0.0f, duration, removeAfter, wait));
|
||||
flashTimer = MathHelper.Pi / 4.0f * 0.1f;
|
||||
flashDuration = 1.0f *0.1f;
|
||||
flashColor = (color == null) ? GUIStyle.Red : (Color)color;
|
||||
}
|
||||
|
||||
public void FadeOut(float duration, bool removeAfter, float wait = 0.0f, Action onRemove = null)
|
||||
{
|
||||
CoroutineManager.StartCoroutine(LerpAlpha(0.0f, duration, removeAfter, wait, onRemove));
|
||||
}
|
||||
|
||||
public void FadeIn(float wait, float duration)
|
||||
@@ -870,7 +878,7 @@ namespace Barotrauma
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
private IEnumerable<CoroutineStatus> LerpAlpha(float to, float duration, bool removeAfter, float wait = 0.0f)
|
||||
private IEnumerable<CoroutineStatus> LerpAlpha(float to, float duration, bool removeAfter, float wait = 0.0f, Action onRemove = null)
|
||||
{
|
||||
State = ComponentState.None;
|
||||
float t = 0.0f;
|
||||
@@ -895,6 +903,7 @@ namespace Barotrauma
|
||||
if (removeAfter && Parent != null)
|
||||
{
|
||||
Parent.RemoveChild(this);
|
||||
onRemove?.Invoke();
|
||||
}
|
||||
|
||||
yield return CoroutineStatus.Success;
|
||||
@@ -1156,7 +1165,7 @@ namespace Barotrauma
|
||||
try
|
||||
{
|
||||
#if USE_STEAM
|
||||
Steam.SteamManager.OverlayCustomURL(url);
|
||||
Steam.SteamManager.OverlayCustomUrl(url);
|
||||
#else
|
||||
ToolBox.OpenFileWithShell(url);
|
||||
#endif
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Barotrauma
|
||||
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);
|
||||
int horizontalPadding = (int)(padding.X + padding.Z), verticalPadding = (int)(padding.Y + padding.W);
|
||||
bool hasHeader = !header.IsNullOrWhiteSpace();
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@@ -131,9 +131,15 @@ namespace Barotrauma
|
||||
optionElement.ToolTip = option.Tooltip;
|
||||
}
|
||||
|
||||
if (!option.IsEnabled)
|
||||
//option doesn't do anything, make it a label
|
||||
if (option.OnSelected == null)
|
||||
{
|
||||
optionElement.TextColor *= 0.5f;
|
||||
optionElement.TextAlignment = Alignment.BottomLeft;
|
||||
optionElement.TextColor = optionElement.DisabledTextColor = GUIStyle.Green;
|
||||
}
|
||||
else if (!option.IsEnabled)
|
||||
{
|
||||
optionElement.TextColor *= 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +152,10 @@ namespace Barotrauma
|
||||
// Resize all children to the size of their text
|
||||
foreach (GUITextBlock block in children.Where(c => c is GUITextBlock).Cast<GUITextBlock>())
|
||||
{
|
||||
block.RectTransform.NonScaledSize = new Point((int) (block.TextSize.X + (block.Padding.X + block.Padding.Z)), (int) (18 * GUI.Scale));
|
||||
bool isLabel = block.UserData is ContextMenuOption option && option.OnSelected == null;
|
||||
block.RectTransform.NonScaledSize = new Point(
|
||||
(int)(block.TextSize.X + (block.Padding.X + block.Padding.Z)),
|
||||
(int)Math.Max(block.TextSize.Y * 1.2f, 18 * GUI.Scale));
|
||||
}
|
||||
|
||||
int largestWidth = children.Max(c => c.Rect.Width + horizontalPadding);
|
||||
@@ -155,7 +164,7 @@ namespace Barotrauma
|
||||
if (HeaderLabel != null)
|
||||
{
|
||||
RectTransform headerTransform = HeaderLabel.RectTransform;
|
||||
headerTransform.MinSize = new Point((int) (HeaderLabel.TextSize.X + (headerPadding.X + headerPadding.Z)), headerTransform.NonScaledSize.Y);
|
||||
headerTransform.MinSize = new Point((int)(HeaderLabel.TextSize.X + (headerPadding.X + headerPadding.Z)), headerTransform.NonScaledSize.Y);
|
||||
if (largestWidth < headerTransform.MinSize.X)
|
||||
{
|
||||
largestWidth = headerTransform.MinSize.X;
|
||||
@@ -171,7 +180,7 @@ namespace Barotrauma
|
||||
// the cropped size of the option list
|
||||
Point newSize = new Point(largestWidth, children.Sum(c => c.Rect.Height) + verticalPadding);
|
||||
// resize the menu itself taking into account the option menus relative Y size
|
||||
RectTransform.NonScaledSize = new Point(newSize.X, (int) (newSize.Y / optionList.RectTransform.RelativeSize.Y));
|
||||
RectTransform.NonScaledSize = new Point(newSize.X, (int)(newSize.Y / optionList.RectTransform.RelativeSize.Y));
|
||||
optionList.RectTransform.NonScaledSize = newSize;
|
||||
|
||||
// move the context menu if it would go outside of screen
|
||||
@@ -227,8 +236,8 @@ namespace Barotrauma
|
||||
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);
|
||||
size.Y += (int) Math.Ceiling(textSize.Y);
|
||||
size.X = Math.Max((int)Math.Ceiling(textSize.X), size.X);
|
||||
size.Y += (int)Math.Ceiling(textSize.Y);
|
||||
return textSize;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
public class GUIDragHandle : GUIComponent
|
||||
{
|
||||
private readonly RectTransform elementToMove;
|
||||
|
||||
private Point originalOffset;
|
||||
|
||||
private Vector2 dragStart;
|
||||
private bool dragStarted;
|
||||
|
||||
public Rectangle DragArea;
|
||||
|
||||
public Func<RectTransform, bool> ValidatePosition;
|
||||
|
||||
public bool Dragging => dragStarted;
|
||||
|
||||
public GUIDragHandle(RectTransform rectT, RectTransform elementToMove, string style = "GUIDragIndicator")
|
||||
: base(style, rectT)
|
||||
{
|
||||
enabled = true;
|
||||
this.elementToMove = elementToMove;
|
||||
DragArea = new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||
}
|
||||
|
||||
protected override void Update(float deltaTime)
|
||||
{
|
||||
if (!Visible) { return; }
|
||||
base.Update(deltaTime);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
if (dragStarted)
|
||||
{
|
||||
Point moveAmount = (PlayerInput.MousePosition - dragStart).ToPoint() - elementToMove.ScreenSpaceOffset;
|
||||
Rectangle rect = elementToMove.Rect;
|
||||
rect.Location += moveAmount;
|
||||
|
||||
moveAmount.X += Math.Max(DragArea.X - rect.X, 0);
|
||||
moveAmount.X -= Math.Max(rect.Right - DragArea.Right, 0);
|
||||
moveAmount.Y += Math.Max(DragArea.Y - rect.Y, 0);
|
||||
moveAmount.Y -= Math.Max(rect.Bottom - DragArea.Bottom, 0);
|
||||
|
||||
if (moveAmount != Point.Zero)
|
||||
{
|
||||
elementToMove.ScreenSpaceOffset += moveAmount;
|
||||
}
|
||||
|
||||
bool isPositionValid = ValidatePosition == null || ValidatePosition.Invoke(elementToMove);
|
||||
|
||||
if (!PlayerInput.PrimaryMouseButtonHeld())
|
||||
{
|
||||
if (!isPositionValid)
|
||||
{
|
||||
elementToMove.ScreenSpaceOffset = originalOffset;
|
||||
elementToMove.GUIComponent?.Flash();
|
||||
SoundPlayer.PlayUISound(GUISoundType.PickItemFail);
|
||||
}
|
||||
dragStarted = false;
|
||||
}
|
||||
}
|
||||
else if (Rect.Contains(PlayerInput.MousePosition) && CanBeFocused && Enabled && GUI.IsMouseOn(this) && !(GUI.MouseOn is GUIButton))
|
||||
{
|
||||
State = Selected ? ComponentState.HoverSelected : ComponentState.Hover;
|
||||
if (PlayerInput.PrimaryMouseButtonDown())
|
||||
{
|
||||
originalOffset = elementToMove.ScreenSpaceOffset;
|
||||
dragStart = PlayerInput.MousePosition - elementToMove.ScreenSpaceOffset.ToVector2();
|
||||
dragStarted = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ExternalHighlight)
|
||||
{
|
||||
State = Selected ? ComponentState.Selected : ComponentState.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
State = ComponentState.Hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (GUIComponent child in Children)
|
||||
{
|
||||
//allow buttons to handle their states themselves
|
||||
if (child is GUIButton) { continue; }
|
||||
child.State = State;
|
||||
child.Enabled = enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,15 +204,7 @@ namespace Barotrauma
|
||||
|
||||
currentHighestParent = FindHighestParent();
|
||||
currentHighestParent.GUIComponent.OnAddedToGUIUpdateList += AddListBoxToGUIUpdateList;
|
||||
rectT.ParentChanged += (RectTransform newParent) =>
|
||||
{
|
||||
currentHighestParent.GUIComponent.OnAddedToGUIUpdateList -= AddListBoxToGUIUpdateList;
|
||||
if (newParent != null)
|
||||
{
|
||||
currentHighestParent = FindHighestParent();
|
||||
currentHighestParent.GUIComponent.OnAddedToGUIUpdateList += AddListBoxToGUIUpdateList;
|
||||
}
|
||||
};
|
||||
rectT.ParentChanged += _ => RefreshListBoxParent();
|
||||
}
|
||||
|
||||
|
||||
@@ -396,6 +388,15 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
|
||||
public void RefreshListBoxParent()
|
||||
{
|
||||
currentHighestParent.GUIComponent.OnAddedToGUIUpdateList -= AddListBoxToGUIUpdateList;
|
||||
if (RectTransform.Parent == null) { return; }
|
||||
|
||||
currentHighestParent = FindHighestParent();
|
||||
currentHighestParent.GUIComponent.OnAddedToGUIUpdateList += AddListBoxToGUIUpdateList;
|
||||
}
|
||||
|
||||
private void AddListBoxToGUIUpdateList(GUIComponent parent)
|
||||
{
|
||||
//the parent is not our parent anymore :(
|
||||
@@ -403,11 +404,13 @@ namespace Barotrauma
|
||||
//and somewhere between this component and the higher parent a component was removed
|
||||
for (int i = 1; i < parentHierarchy.Count; i++)
|
||||
{
|
||||
if (!parentHierarchy[i].IsParentOf(parentHierarchy[i - 1], recursive: false))
|
||||
if (parentHierarchy[i].IsParentOf(parentHierarchy[i - 1], recursive: false))
|
||||
{
|
||||
parent.OnAddedToGUIUpdateList -= AddListBoxToGUIUpdateList;
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
parent.OnAddedToGUIUpdateList -= AddListBoxToGUIUpdateList;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Dropped)
|
||||
|
||||
@@ -85,11 +85,11 @@ namespace Barotrauma
|
||||
get { return sprite; }
|
||||
set
|
||||
{
|
||||
if (sprite == value) return;
|
||||
if (sprite == value) { return; }
|
||||
sprite = value;
|
||||
sourceRect = value == null ? Rectangle.Empty : value.SourceRect;
|
||||
origin = value == null ? Vector2.Zero : value.size / 2;
|
||||
if (scaleToFit) RecalculateScale();
|
||||
if (scaleToFit) { RecalculateScale(); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Barotrauma
|
||||
//scaling the bar linearly with the resolution tends to make them too large on large resolutions
|
||||
float desiredSize = 25.0f;
|
||||
float scaledSize = desiredSize * GUI.Scale;
|
||||
return (int)((desiredSize + scaledSize) / 2.0f);
|
||||
return (int)Math.Min((desiredSize + scaledSize) / 2.0f, Rect.Height / 3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,8 @@ namespace Barotrauma
|
||||
{
|
||||
SelectSingle,
|
||||
SelectMultiple,
|
||||
RequireShiftToSelectMultiple
|
||||
RequireShiftToSelectMultiple,
|
||||
None
|
||||
}
|
||||
|
||||
public SelectMode CurrentSelectMode = SelectMode.SelectSingle;
|
||||
@@ -73,6 +74,8 @@ namespace Barotrauma
|
||||
|
||||
public bool HideChildrenOutsideFrame = true;
|
||||
|
||||
public bool ResizeContentToMakeSpaceForScrollBar = true;
|
||||
|
||||
private bool useGridLayout;
|
||||
|
||||
private GUIComponent scrollToElement;
|
||||
@@ -419,7 +422,7 @@ namespace Barotrauma
|
||||
{
|
||||
dimensionsNeedsRecalculation = false;
|
||||
ContentBackground.RectTransform.Resize(Rect.Size);
|
||||
bool reduceScrollbarSize = KeepSpaceForScrollBar ? ScrollBarEnabled : ScrollBarVisible;
|
||||
bool reduceScrollbarSize = ResizeContentToMakeSpaceForScrollBar && (KeepSpaceForScrollBar ? ScrollBarEnabled : ScrollBarVisible);
|
||||
Point contentSize = reduceScrollbarSize ? CalculateFrameSize(ScrollBar.IsHorizontal, ScrollBarSize) : Rect.Size;
|
||||
Content.RectTransform.Resize(new Point((int)(contentSize.X - Padding.X - Padding.Z), (int)(contentSize.Y - Padding.Y - Padding.W)));
|
||||
if (!IsScrollBarOnDefaultSide) { Content.RectTransform.SetPosition(Anchor.BottomRight); }
|
||||
@@ -598,16 +601,13 @@ namespace Barotrauma
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
float t = 0.0f;
|
||||
float startScroll = BarScroll * BarSize;
|
||||
float startScroll = BarScroll;
|
||||
float distanceToTravel = ScrollBar.MaxValue - startScroll;
|
||||
float progress = startScroll;
|
||||
float speed = distanceToTravel / duration;
|
||||
|
||||
while (t < duration && !MathUtils.NearlyEqual(ScrollBar.MaxValue, progress))
|
||||
while (t < duration && !MathUtils.NearlyEqual(ScrollBar.MaxValue, BarScroll))
|
||||
{
|
||||
t += CoroutineManager.DeltaTime;
|
||||
progress += speed * CoroutineManager.DeltaTime;
|
||||
BarScroll = progress;
|
||||
BarScroll += speed * CoroutineManager.DeltaTime;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
@@ -1056,7 +1056,7 @@ namespace Barotrauma
|
||||
|
||||
public void Select(int childIndex, Force force = Force.No, AutoScroll autoScroll = AutoScroll.Enabled, TakeKeyBoardFocus takeKeyBoardFocus = TakeKeyBoardFocus.No, PlaySelectSound playSelectSound = PlaySelectSound.No)
|
||||
{
|
||||
if (childIndex >= Content.CountChildren || childIndex < 0) { return; }
|
||||
if (childIndex >= Content.CountChildren || childIndex < 0 || CurrentSelectMode == SelectMode.None) { return; }
|
||||
|
||||
GUIComponent child = Content.GetChild(childIndex);
|
||||
if (child is null) { return; }
|
||||
@@ -1155,6 +1155,7 @@ namespace Barotrauma
|
||||
|
||||
public void Select(IEnumerable<GUIComponent> children)
|
||||
{
|
||||
if (CurrentSelectMode == SelectMode.None) { return; }
|
||||
Selected = true;
|
||||
selected.Clear();
|
||||
selected.AddRange(children.Where(c => Content.Children.Contains(c)));
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Barotrauma.Networking;
|
||||
using Barotrauma.Extensions;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -25,15 +23,18 @@ namespace Barotrauma
|
||||
Default,
|
||||
InGame,
|
||||
Vote,
|
||||
Hint
|
||||
Hint,
|
||||
Tutorial
|
||||
}
|
||||
|
||||
private bool IsAnimated => type == Type.InGame || type == Type.Hint || type == Type.Tutorial;
|
||||
|
||||
public List<GUIButton> Buttons { get; private set; } = new List<GUIButton>();
|
||||
public GUILayoutGroup Content { get; private set; }
|
||||
public GUIFrame InnerFrame { get; private set; }
|
||||
public GUITextBlock Header { get; private set; }
|
||||
public GUITextBlock Text { get; private set; }
|
||||
public string Tag { get; private set; }
|
||||
public Identifier Tag { get; private set; }
|
||||
public bool Closed { get; private set; }
|
||||
|
||||
public bool DisplayInLoadingScreens;
|
||||
@@ -60,6 +61,9 @@ namespace Barotrauma
|
||||
public GUIImage BackgroundIcon { get; private set; }
|
||||
private GUIImage newBackgroundIcon;
|
||||
|
||||
/// <summary>
|
||||
/// Close the message box automatically after enough time has passed (<see cref="inGameCloseTime"/>)
|
||||
/// </summary>
|
||||
public bool AutoClose;
|
||||
|
||||
private float openState;
|
||||
@@ -69,6 +73,13 @@ namespace Barotrauma
|
||||
|
||||
private readonly Type type;
|
||||
|
||||
/// <summary>
|
||||
/// Close the message box automatically if the condition is met
|
||||
/// </summary>
|
||||
private readonly Func<bool> autoCloseCondition;
|
||||
|
||||
public bool FlashOnAutoCloseCondition { get; set; }
|
||||
|
||||
public Type MessageBoxType => type;
|
||||
|
||||
public static GUIComponent VisibleBox => MessageBoxes.LastOrDefault();
|
||||
@@ -79,7 +90,9 @@ namespace Barotrauma
|
||||
this.Buttons[0].OnClicked = Close;
|
||||
}
|
||||
|
||||
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)
|
||||
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, Func<bool> autoCloseCondition = null, bool hideCloseButton = false)
|
||||
: 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
|
||||
@@ -116,6 +129,7 @@ namespace Barotrauma
|
||||
Anchor anchor = type switch
|
||||
{
|
||||
Type.InGame => Anchor.TopCenter,
|
||||
Type.Tutorial => Anchor.TopCenter,
|
||||
Type.Hint => Anchor.TopRight,
|
||||
Type.Vote => Anchor.TopRight,
|
||||
_ => Anchor.Center
|
||||
@@ -130,7 +144,7 @@ namespace Barotrauma
|
||||
}
|
||||
GUIStyle.Apply(InnerFrame, "", this);
|
||||
this.type = type;
|
||||
Tag = tag;
|
||||
Tag = tag.ToIdentifier();
|
||||
|
||||
#warning TODO: These should be broken into separate methods at least
|
||||
if (type == Type.Default || type == Type.Vote)
|
||||
@@ -187,12 +201,13 @@ namespace Barotrauma
|
||||
var button = new GUIButton(new RectTransform(new Vector2(0.6f, 1.0f / buttons.Length), buttonContainer.RectTransform), buttons[i]);
|
||||
Buttons.Add(button);
|
||||
}
|
||||
GUITextBlock.AutoScaleAndNormalize(Buttons.Select(btn => btn.TextBlock));
|
||||
}
|
||||
else if (type == Type.InGame)
|
||||
else if (type == Type.InGame || type == Type.Tutorial)
|
||||
{
|
||||
InnerFrame.RectTransform.AbsoluteOffset = new Point(0, GameMain.GraphicsHeight);
|
||||
CanBeFocused = false;
|
||||
AutoClose = true;
|
||||
AutoClose = type == Type.InGame;
|
||||
GUIStyle.Apply(InnerFrame, "", this);
|
||||
|
||||
var horizontalLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.98f, 0.95f), InnerFrame.RectTransform, Anchor.Center),
|
||||
@@ -212,37 +227,43 @@ namespace Barotrauma
|
||||
|
||||
Content = new GUILayoutGroup(new RectTransform(new Vector2(Icon != null ? 0.65f : 0.85f, 1.0f), horizontalLayoutGroup.RectTransform));
|
||||
|
||||
var buttonContainer = new GUIFrame(new RectTransform(new Vector2(0.15f, 1.0f), horizontalLayoutGroup.RectTransform), style: null);
|
||||
Buttons = new List<GUIButton>(1)
|
||||
if (!hideCloseButton)
|
||||
{
|
||||
new GUIButton(new RectTransform(new Vector2(0.3f, 0.5f), buttonContainer.RectTransform, Anchor.Center),
|
||||
style: "UIToggleButton")
|
||||
var buttonContainer = new GUIFrame(new RectTransform(new Vector2(0.15f, 1.0f), horizontalLayoutGroup.RectTransform), style: null);
|
||||
Buttons = new List<GUIButton>(1)
|
||||
{
|
||||
OnClicked = Close
|
||||
}
|
||||
};
|
||||
|
||||
InputType? closeInput = null;
|
||||
if (GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Use].MouseButton == MouseButton.None)
|
||||
{
|
||||
closeInput = InputType.Use;
|
||||
}
|
||||
else if (GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Select].MouseButton == MouseButton.None)
|
||||
{
|
||||
closeInput = InputType.Select;
|
||||
}
|
||||
if (closeInput.HasValue)
|
||||
{
|
||||
Buttons[0].ToolTip = TextManager.ParseInputTypes($"{TextManager.Get("Close")} ([InputType.{closeInput.Value}])");
|
||||
Buttons[0].OnAddedToGUIUpdateList += (GUIComponent component) =>
|
||||
{
|
||||
if (!closing && openState >= 1.0f && PlayerInput.KeyHit(closeInput.Value))
|
||||
new GUIButton(new RectTransform(new Vector2(0.3f, 0.5f), buttonContainer.RectTransform, Anchor.Center),
|
||||
style: "UIToggleButton")
|
||||
{
|
||||
GUIButton btn = component as GUIButton;
|
||||
btn?.OnClicked(btn, btn.UserData);
|
||||
btn?.Flash(GUIStyle.Green);
|
||||
OnClicked = Close
|
||||
}
|
||||
};
|
||||
InputType? closeInput = null;
|
||||
if (GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Use].MouseButton == MouseButton.None)
|
||||
{
|
||||
closeInput = InputType.Use;
|
||||
}
|
||||
else if (GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Select].MouseButton == MouseButton.None)
|
||||
{
|
||||
closeInput = InputType.Select;
|
||||
}
|
||||
if (closeInput.HasValue)
|
||||
{
|
||||
Buttons[0].ToolTip = TextManager.ParseInputTypes($"{TextManager.Get("Close")} ([InputType.{closeInput.Value}])");
|
||||
Buttons[0].OnAddedToGUIUpdateList += (GUIComponent component) =>
|
||||
{
|
||||
if (!closing && openState >= 1.0f && PlayerInput.KeyHit(closeInput.Value))
|
||||
{
|
||||
GUIButton btn = component as GUIButton;
|
||||
btn?.OnClicked(btn, btn.UserData);
|
||||
btn?.Flash(GUIStyle.Green);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Buttons.Clear();
|
||||
}
|
||||
|
||||
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), headerText, wrap: true);
|
||||
@@ -274,7 +295,10 @@ namespace Barotrauma
|
||||
Content.RectTransform.NonScaledSize =
|
||||
new Point(Content.Rect.Width, height);
|
||||
}
|
||||
Buttons[0].RectTransform.MaxSize = new Point((int)(0.4f * Buttons[0].Rect.Y), Buttons[0].Rect.Y);
|
||||
if (!hideCloseButton)
|
||||
{
|
||||
Buttons[0].RectTransform.MaxSize = new Point((int)(0.4f * Buttons[0].Rect.Y), Buttons[0].Rect.Y);
|
||||
}
|
||||
}
|
||||
else if (type == Type.Hint)
|
||||
{
|
||||
@@ -408,6 +432,8 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
this.autoCloseCondition = autoCloseCondition;
|
||||
|
||||
MessageBoxes.Add(this);
|
||||
}
|
||||
|
||||
@@ -448,7 +474,7 @@ namespace Barotrauma
|
||||
{
|
||||
// Message box not of type GUIMessageBox is likely the round summary
|
||||
MessageBoxes[i].AddToGUIUpdateList();
|
||||
break;
|
||||
if (!(MessageBoxes[i].UserData is RoundSummary)) { break; }
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -471,6 +497,7 @@ namespace Barotrauma
|
||||
public void SetBackgroundIcon(Sprite icon)
|
||||
{
|
||||
if (icon == null) { return; }
|
||||
if (icon == BackgroundIcon?.Sprite) { return; }
|
||||
GUIImage newIcon = new GUIImage(new RectTransform(icon.size.ToPoint(), RectTransform), icon)
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
@@ -510,10 +537,10 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (type == Type.InGame || type == Type.Hint)
|
||||
if (IsAnimated)
|
||||
{
|
||||
Vector2 initialPos, defaultPos, endPos;
|
||||
if (type == Type.InGame)
|
||||
if (type == Type.InGame || type == Type.Tutorial)
|
||||
{
|
||||
initialPos = new Vector2(0.0f, GameMain.GraphicsHeight);
|
||||
defaultPos = new Vector2(0.0f, HUDLayoutSettings.InventoryAreaLower.Y - InnerFrame.Rect.Height - 20 * GUI.Scale);
|
||||
@@ -552,6 +579,14 @@ namespace Barotrauma
|
||||
{
|
||||
Close();
|
||||
}
|
||||
else if (autoCloseCondition != null && autoCloseCondition())
|
||||
{
|
||||
Close();
|
||||
if (FlashOnAutoCloseCondition)
|
||||
{
|
||||
InnerFrame.Flash(GUIStyle.Green);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -593,7 +628,7 @@ namespace Barotrauma
|
||||
{
|
||||
newBackgroundIcon.SetAsFirstChild();
|
||||
newBackgroundIcon.RectTransform.AbsoluteOffset = new Point(InnerFrame.Rect.Location.X - (int)(newBackgroundIcon.Rect.Size.X / 1.25f), (int)defaultPos.Y - newBackgroundIcon.Rect.Size.Y / 2);
|
||||
newBackgroundIcon.Color = ToolBox.GradientLerp(iconState, Color.Transparent, Color.White);
|
||||
newBackgroundIcon.Color = Color.Lerp(Color.Transparent, Color.White, iconState);
|
||||
if (newBackgroundIcon.Color.A == 255)
|
||||
{
|
||||
BackgroundIcon = newBackgroundIcon;
|
||||
@@ -608,10 +643,9 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (type == Type.InGame || type == Type.Hint)
|
||||
if (IsAnimated)
|
||||
{
|
||||
closing = true;
|
||||
}
|
||||
@@ -636,6 +670,19 @@ namespace Barotrauma
|
||||
MessageBoxes.Clear();
|
||||
}
|
||||
|
||||
public static void Close(Identifier tag)
|
||||
{
|
||||
foreach (var messageBox in MessageBoxes)
|
||||
{
|
||||
if (messageBox is GUIMessageBox mb && mb.Tag == tag)
|
||||
{
|
||||
mb.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Close(string tag) => Close(tag.ToIdentifier());
|
||||
|
||||
/// <summary>
|
||||
/// Parent does not matter. It's overridden.
|
||||
/// </summary>
|
||||
|
||||
@@ -178,19 +178,19 @@ namespace Barotrauma
|
||||
{
|
||||
public GUIFont(string identifier) : base(identifier) { }
|
||||
|
||||
public bool HasValue => Prefabs.Any();
|
||||
public bool HasValue => !Prefabs.IsEmpty;
|
||||
|
||||
public ScalableFont Value => Prefabs.ActivePrefab.Font;
|
||||
|
||||
public static implicit operator ScalableFont(GUIFont reference) => reference.Value;
|
||||
|
||||
public bool ForceUpperCase => HasValue && Value.ForceUpperCase;
|
||||
public bool ForceUpperCase => Prefabs.ActivePrefab?.Font is { ForceUpperCase: true };
|
||||
|
||||
public uint Size => HasValue ? Value.Size : 0;
|
||||
|
||||
private ScalableFont GetFontForStr(LocalizedString str) => GetFontForStr(str.Value);
|
||||
|
||||
private ScalableFont GetFontForStr(string str) =>
|
||||
public 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)
|
||||
|
||||
@@ -141,11 +141,32 @@ namespace Barotrauma
|
||||
public readonly static GUIColor HealthBarColorMedium = new GUIColor("HealthBarColorMedium");
|
||||
public readonly static GUIColor HealthBarColorHigh = new GUIColor("HealthBarColorHigh");
|
||||
|
||||
public static Point ItemFrameMargin => new Point(50, 56).Multiply(GUI.SlicedSpriteScale);
|
||||
public static Point ItemFrameMargin
|
||||
{
|
||||
get
|
||||
{
|
||||
Point size = new Point(50, 56).Multiply(GUI.SlicedSpriteScale);
|
||||
|
||||
var style = GetComponentStyle("ItemUI");
|
||||
var sprite = style?.Sprites[GUIComponent.ComponentState.None].First();
|
||||
if (sprite != null)
|
||||
{
|
||||
size.X = Math.Min(sprite.Slices[0].Width + sprite.Slices[2].Width, size.X);
|
||||
size.Y = Math.Min(sprite.Slices[0].Height + sprite.Slices[6].Height, size.Y);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
public static Point ItemFrameOffset => new Point(0, 3).Multiply(GUI.SlicedSpriteScale);
|
||||
|
||||
public static GUIComponentStyle GetComponentStyle(string name)
|
||||
=> ComponentStyles.ContainsKey(name) ? ComponentStyles[name] : null;
|
||||
public static GUIComponentStyle GetComponentStyle(string styleName)
|
||||
{
|
||||
return GetComponentStyle(styleName.ToIdentifier());
|
||||
}
|
||||
|
||||
public static GUIComponentStyle GetComponentStyle(Identifier identifier)
|
||||
=> ComponentStyles.TryGet(identifier, out var style) ? style : null;
|
||||
|
||||
public static void Apply(GUIComponent targetComponent, string styleName = "", GUIComponent parent = null)
|
||||
{
|
||||
|
||||
@@ -587,7 +587,7 @@ namespace Barotrauma
|
||||
|
||||
if (Shadow)
|
||||
{
|
||||
Vector2 shadowOffset = new Vector2(GUI.IntScale(2));
|
||||
Vector2 shadowOffset = new Vector2(Math.Max(GUI.IntScale(2), 1));
|
||||
Font.DrawString(spriteBatch, textToShow, pos + shadowOffset, Color.Black, 0.0f, origin, TextScale, SpriteEffects.None, textDepth, alignment: textAlignment, forceUpperCase: ForceUpperCase);
|
||||
}
|
||||
|
||||
|
||||
@@ -412,7 +412,8 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
if (MouseRect.Contains(PlayerInput.MousePosition) && (GUI.MouseOn == null || (!(GUI.MouseOn is GUIButton) && GUI.IsMouseOn(this))))
|
||||
bool isMouseOn = MouseRect.Contains(PlayerInput.MousePosition) && (GUI.MouseOn == null || (!(GUI.MouseOn is GUIButton) && GUI.IsMouseOn(this)));
|
||||
if (isMouseOn || isSelecting)
|
||||
{
|
||||
State = ComponentState.Hover;
|
||||
if (PlayerInput.PrimaryMouseButtonDown())
|
||||
@@ -448,10 +449,6 @@ namespace Barotrauma
|
||||
isSelecting = false;
|
||||
State = ComponentState.None;
|
||||
}
|
||||
if (!isSelecting)
|
||||
{
|
||||
isSelecting = PlayerInput.IsShiftDown();
|
||||
}
|
||||
|
||||
if (mouseHeldInside && !PlayerInput.PrimaryMouseButtonHeld())
|
||||
{
|
||||
|
||||
@@ -177,7 +177,7 @@ namespace Barotrauma
|
||||
radioButtonGroup = rbg;
|
||||
}
|
||||
|
||||
private void ResizeBox()
|
||||
public void ResizeBox()
|
||||
{
|
||||
Vector2 textBlockScale = new Vector2(Math.Max(Rect.Width - box.Rect.Width, 0.0f) / Math.Max(Rect.Width, 1.0f), 1.0f);
|
||||
text.RectTransform.RelativeSize = textBlockScale;
|
||||
|
||||
@@ -25,6 +25,10 @@ namespace Barotrauma
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
public static Rectangle TutorialObjectiveListArea
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public static Rectangle MessageAreaTop
|
||||
{
|
||||
@@ -81,6 +85,11 @@ namespace Barotrauma
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public static Rectangle ItemHUDArea
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public static int Padding
|
||||
{
|
||||
get; private set;
|
||||
@@ -162,25 +171,35 @@ namespace Barotrauma
|
||||
|
||||
HealthWindowAreaLeft = new Rectangle(healthWindowX, healthWindowY, healthWindowWidth, healthWindowHeight);
|
||||
|
||||
int objectiveListAreaX = HealthWindowAreaLeft.Right + Padding;
|
||||
int objectiveListAreaY = ButtonAreaTop.Bottom + Padding;
|
||||
TutorialObjectiveListArea = new Rectangle(objectiveListAreaX, objectiveListAreaY, (GameMain.GraphicsWidth - Padding) - objectiveListAreaX, (AfflictionAreaLeft.Top - Padding) - objectiveListAreaY);
|
||||
|
||||
int votingAreaWidth = (int)(400 * GUI.Scale);
|
||||
int votingAreaX = GameMain.GraphicsWidth - Padding - votingAreaWidth;
|
||||
int votingAreaY = Padding + ButtonAreaTop.Height;
|
||||
|
||||
// Height is based on text content
|
||||
VotingArea = new Rectangle(votingAreaX, votingAreaY, votingAreaWidth, 0);
|
||||
|
||||
ItemHUDArea = new Rectangle(0, ButtonAreaTop.Bottom, GameMain.GraphicsWidth, GameMain.GraphicsHeight - ButtonAreaTop.Bottom - InventoryAreaLower.Height);
|
||||
}
|
||||
|
||||
public static void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, ButtonAreaTop, Color.White * 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);
|
||||
GUI.DrawRectangle(spriteBatch, AfflictionAreaLeft, Color.Red * 0.5f);
|
||||
GUI.DrawRectangle(spriteBatch, InventoryAreaLower, Color.Yellow * 0.5f);
|
||||
GUI.DrawRectangle(spriteBatch, HealthWindowAreaLeft, Color.Red * 0.5f);
|
||||
GUI.DrawRectangle(spriteBatch, BottomRightInfoArea, Color.Green * 0.5f);
|
||||
DrawRectangle(ButtonAreaTop, Color.White * 0.5f);
|
||||
DrawRectangle(TutorialObjectiveListArea, GUIStyle.Blue * 0.5f);
|
||||
DrawRectangle(MessageAreaTop, GUIStyle.Orange * 0.5f);
|
||||
DrawRectangle(CrewArea, Color.Blue * 0.5f);
|
||||
DrawRectangle(ChatBoxArea, Color.Cyan * 0.5f);
|
||||
DrawRectangle(HealthBarArea, Color.Red * 0.5f);
|
||||
DrawRectangle(AfflictionAreaLeft, Color.Red * 0.5f);
|
||||
DrawRectangle(InventoryAreaLower, Color.Yellow * 0.5f);
|
||||
DrawRectangle(HealthWindowAreaLeft, Color.Red * 0.5f);
|
||||
DrawRectangle(BottomRightInfoArea, Color.Green * 0.5f);
|
||||
DrawRectangle(ItemHUDArea, Color.Magenta * 0.3f);
|
||||
|
||||
void DrawRectangle(Rectangle r, Color c) => GUI.DrawRectangle(spriteBatch, r, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -233,7 +233,9 @@ namespace Barotrauma
|
||||
get
|
||||
{
|
||||
Point absoluteOffset = ConvertOffsetRelativeToAnchor(AbsoluteOffset, Anchor);
|
||||
Point relativeOffset = NonScaledParentRect.MultiplySize(RelativeOffset);
|
||||
Point relativeOffset = new Point(
|
||||
(int)(NonScaledParentSize.X * RelativeOffset.X),
|
||||
(int)(NonScaledParentSize.Y * RelativeOffset.Y));
|
||||
relativeOffset = ConvertOffsetRelativeToAnchor(relativeOffset, Anchor);
|
||||
return AnchorPoint + PivotOffset + absoluteOffset + relativeOffset + ScreenSpaceOffset;
|
||||
}
|
||||
@@ -256,6 +258,7 @@ namespace Barotrauma
|
||||
public Rectangle ParentRect => Parent != null ? Parent.Rect : UIRect;
|
||||
protected Rectangle NonScaledRect => new Rectangle(NonScaledTopLeft, NonScaledSize);
|
||||
protected virtual Rectangle NonScaledUIRect => NonScaledRect;
|
||||
protected Point NonScaledParentSize => parent?.NonScaledSize ?? new Point(GUI.UIWidth, GameMain.GraphicsHeight);
|
||||
protected Rectangle NonScaledParentRect => parent != null ? Parent.NonScaledRect : UIRect;
|
||||
protected Rectangle NonScaledParentUIRect => parent != null ? Parent.NonScaledUIRect : UIRect;
|
||||
protected Rectangle UIRect => new Rectangle(0, 0, GUI.UIWidth, GameMain.GraphicsHeight);
|
||||
@@ -336,6 +339,11 @@ namespace Barotrauma
|
||||
public event Action<RectTransform> ChildrenChanged;
|
||||
public event Action ScaleChanged;
|
||||
public event Action SizeChanged;
|
||||
|
||||
public void ResetSizeChanged()
|
||||
{
|
||||
SizeChanged = null;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Initialization
|
||||
@@ -730,17 +738,17 @@ namespace Barotrauma
|
||||
get { return animTargetPos ?? AbsoluteOffset; }
|
||||
}
|
||||
|
||||
public void MoveOverTime(Point targetPos, float duration)
|
||||
public void MoveOverTime(Point targetPos, float duration, Action onDoneMoving = null)
|
||||
{
|
||||
animTargetPos = targetPos;
|
||||
CoroutineManager.StartCoroutine(DoMoveAnimation(targetPos, duration));
|
||||
CoroutineManager.StartCoroutine(DoMoveAnimation(targetPos, duration, onDoneMoving));
|
||||
}
|
||||
public void ScaleOverTime(Point targetSize, float duration)
|
||||
{
|
||||
CoroutineManager.StartCoroutine(DoScaleAnimation(targetSize, duration));
|
||||
}
|
||||
|
||||
private IEnumerable<CoroutineStatus> DoMoveAnimation(Point targetPos, float duration)
|
||||
private IEnumerable<CoroutineStatus> DoMoveAnimation(Point targetPos, float duration, Action onDoneMoving = null)
|
||||
{
|
||||
Vector2 startPos = AbsoluteOffset.ToVector2();
|
||||
float t = 0.0f;
|
||||
@@ -752,6 +760,7 @@ namespace Barotrauma
|
||||
}
|
||||
AbsoluteOffset = targetPos;
|
||||
animTargetPos = null;
|
||||
onDoneMoving?.Invoke();
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
private IEnumerable<CoroutineStatus> DoScaleAnimation(Point targetSize, float duration)
|
||||
|
||||
@@ -238,7 +238,7 @@ namespace Barotrauma
|
||||
errorId = "Store.SelectStore:StoreDoesntExist";
|
||||
msg = $"Error selecting store with identifier \"{identifier}\" at {CurrentLocation}: store with the identifier doesn't exist at the location.";
|
||||
}
|
||||
DebugConsole.ShowError(msg);
|
||||
DebugConsole.LogError(msg);
|
||||
GameAnalyticsManager.AddErrorEventOnce(errorId, GameAnalyticsManager.ErrorSeverity.Error, msg);
|
||||
}
|
||||
}
|
||||
@@ -263,7 +263,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (!msg.IsNullOrEmpty())
|
||||
{
|
||||
DebugConsole.ShowError(msg);
|
||||
DebugConsole.LogError(msg);
|
||||
GameAnalyticsManager.AddErrorEventOnce(errorId, GameAnalyticsManager.ErrorSeverity.Error, msg);
|
||||
}
|
||||
}
|
||||
@@ -1250,7 +1250,7 @@ namespace Barotrauma
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
DebugConsole.ShowError($"Error getting item price: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
DebugConsole.LogError($"Error getting item price: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1808,7 +1808,7 @@ namespace Barotrauma
|
||||
{
|
||||
string errorMsg = $"Error creating a store quantity label text: unknown store tab.\n{e.StackTrace.CleanupStackTrace()}";
|
||||
#if DEBUG
|
||||
DebugConsole.ShowError(errorMsg);
|
||||
DebugConsole.LogError(errorMsg);
|
||||
#else
|
||||
DebugConsole.AddWarning(errorMsg);
|
||||
#endif
|
||||
@@ -1882,7 +1882,7 @@ namespace Barotrauma
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
DebugConsole.ShowError($"Error getting item availability: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
DebugConsole.LogError($"Error getting item availability: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
}
|
||||
if (list != null && list.Find(i => i.ItemPrefab == itemPrefab) is PurchasedItem item)
|
||||
{
|
||||
@@ -1962,7 +1962,7 @@ namespace Barotrauma
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
DebugConsole.ShowError($"Error adding an item to the shopping crate: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
DebugConsole.LogError($"Error adding an item to the shopping crate: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1982,7 +1982,7 @@ namespace Barotrauma
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
DebugConsole.ShowError($"Error clearing the shopping crate: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
DebugConsole.LogError($"Error clearing the shopping crate: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -2029,7 +2029,7 @@ namespace Barotrauma
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
DebugConsole.ShowError($"Error confirming the store transaction: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
DebugConsole.LogError($"Error confirming the store transaction: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
return false;
|
||||
}
|
||||
var itemsToRemove = new List<PurchasedItem>();
|
||||
|
||||
@@ -56,6 +56,7 @@ namespace Barotrauma
|
||||
public SubmarineInfo displayedSubmarine;
|
||||
public GUITextBlock submarineName;
|
||||
public GUITextBlock submarineClass;
|
||||
public GUITextBlock submarineTier;
|
||||
public GUITextBlock submarineFee;
|
||||
public GUIButton selectSubmarineButton;
|
||||
public GUITextBlock middleTextBlock;
|
||||
@@ -162,7 +163,12 @@ namespace Barotrauma
|
||||
IgnoreLayoutGroups = true
|
||||
};
|
||||
new GUIListBox(new RectTransform(Vector2.One, infoFrame.RectTransform)) { IgnoreLayoutGroups = true, CanBeFocused = false };
|
||||
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) };
|
||||
specsFrame = new GUIListBox(new RectTransform(new Vector2(0.39f, 1f), infoFrame.RectTransform), style: null)
|
||||
{
|
||||
CurrentSelectMode = GUIListBox.SelectMode.None,
|
||||
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: GUIStyle.Font, wrap: true) { CanBeFocused = false };
|
||||
@@ -220,16 +226,18 @@ 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: 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.submarineName = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.TopCenter) { AbsoluteOffset = new Point(0, HUDLayoutSettings.Padding) }, string.Empty, textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont);
|
||||
submarineDisplayElement.submarineFee = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.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")
|
||||
submarineDisplayElement.previewButton = new GUIButton(new RectTransform(Vector2.One * 0.12f, submarineDisplayElement.background.RectTransform, anchor: Anchor.BottomRight, scaleBasis: ScaleBasis.BothHeight) { AbsoluteOffset = new Point((int)(0.03f * background.Rect.Height)) }, style: "ExpandButton")
|
||||
{
|
||||
Color = Color.White,
|
||||
HoverColor = Color.White,
|
||||
PressedColor = Color.White
|
||||
};
|
||||
submarineDisplayElement.submarineClass = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.TopCenter) { AbsoluteOffset = new Point(0, HUDLayoutSettings.Padding + (int)GUIStyle.Font.MeasureString(submarineDisplayElement.submarineName.Text).Y) }, string.Empty, textAlignment: Alignment.Left);
|
||||
submarineDisplayElement.submarineTier = new GUITextBlock(new RectTransform(new Vector2(0.5f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.TopRight) { AbsoluteOffset = new Point(0, HUDLayoutSettings.Padding + (int)GUIStyle.Font.MeasureString(submarineDisplayElement.submarineName.Text).Y) }, string.Empty, textAlignment: Alignment.Right);
|
||||
|
||||
submarineDisplays[i] = submarineDisplayElement;
|
||||
}
|
||||
|
||||
@@ -355,6 +363,7 @@ namespace Barotrauma
|
||||
submarineDisplays[i].submarineName.Text = string.Empty;
|
||||
submarineDisplays[i].submarineFee.Text = string.Empty;
|
||||
submarineDisplays[i].submarineClass.Text = string.Empty;
|
||||
submarineDisplays[i].submarineTier.Text = string.Empty;
|
||||
submarineDisplays[i].selectSubmarineButton.Enabled = false;
|
||||
submarineDisplays[i].selectSubmarineButton.OnClicked = null;
|
||||
submarineDisplays[i].displayedSubmarine = null;
|
||||
@@ -387,8 +396,13 @@ namespace Barotrauma
|
||||
return true;
|
||||
};
|
||||
|
||||
submarineDisplays[i].submarineName.Text = subToDisplay.DisplayName;
|
||||
submarineDisplays[i].submarineName.Text = subToDisplay.DisplayName;
|
||||
|
||||
submarineDisplays[i].submarineClass.Text = TextManager.GetWithVariable("submarineclass.classsuffixformat", "[type]", TextManager.Get($"submarineclass.{subToDisplay.SubmarineClass}"));
|
||||
submarineDisplays[i].submarineClass.ToolTip = TextManager.Get("submarineclass.description") + "\n\n" + TextManager.Get($"submarineclass.{subToDisplay.SubmarineClass}.description");
|
||||
|
||||
submarineDisplays[i].submarineTier.Text = TextManager.Get($"submarinetier.{subToDisplay.Tier}");
|
||||
submarineDisplays[i].submarineTier.ToolTip = TextManager.Get("submarinetier.description");
|
||||
|
||||
if (!GameMain.GameSession.IsSubmarineOwned(subToDisplay))
|
||||
{
|
||||
@@ -847,7 +861,7 @@ namespace Barotrauma
|
||||
msgBox = new GUIMessageBox(TextManager.Get("purchasesubmarineheader"), TextManager.GetWithVariables("purchasesubmarinetext",
|
||||
("[submarinename]", selectedSubmarine.DisplayName),
|
||||
("[amount]", selectedSubmarine.Price.ToString()),
|
||||
("[currencyname]", currencyName)), messageBoxOptions);
|
||||
("[currencyname]", currencyName)) + '\n' + TextManager.Get("submarineswitchinstruction"), messageBoxOptions);
|
||||
|
||||
msgBox.Buttons[0].OnClicked = (applyButton, obj) =>
|
||||
{
|
||||
|
||||
@@ -206,9 +206,9 @@ namespace Barotrauma
|
||||
transferMenuButton.RectTransform.AbsoluteOffset = new Point(0, -pos - transferMenu.Rect.Height);
|
||||
}
|
||||
GameSession.UpdateTalentNotificationIndicator(talentPointNotification);
|
||||
if (Character.Controlled is { } controlled && talentResetButton != null && talentApplyButton != null)
|
||||
if (Character.Controlled?.Info is { } characterInfo && talentResetButton != null && talentApplyButton != null)
|
||||
{
|
||||
int talentCount = selectedTalents.Count - controlled.Info.GetUnlockedTalentsInTree().Count();
|
||||
int talentCount = selectedTalents.Count - characterInfo.GetUnlockedTalentsInTree().Count();
|
||||
talentResetButton.Enabled = talentApplyButton.Enabled = talentCount > 0;
|
||||
if (talentApplyButton.Enabled && talentApplyButton.FlashTimer <= 0.0f)
|
||||
{
|
||||
@@ -403,7 +403,7 @@ namespace Barotrauma
|
||||
CreateSubmarineInfo(infoFrameHolder, Submarine.MainSub);
|
||||
break;
|
||||
case InfoFrameTab.Talents:
|
||||
CreateTalentInfo(infoFrameHolder);
|
||||
CreateCharacterInfo(infoFrameHolder);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -631,7 +631,7 @@ namespace Barotrauma
|
||||
|
||||
linkedGUIList = new List<LinkedGUI>();
|
||||
|
||||
List<Client> connectedClients = GameMain.Client.ConnectedClients;
|
||||
var connectedClients = GameMain.Client.ConnectedClients;
|
||||
|
||||
for (int i = 0; i < teamIDs.Count; i++)
|
||||
{
|
||||
@@ -1722,7 +1722,11 @@ namespace Barotrauma
|
||||
|
||||
var subInfoTextLayout = new GUILayoutGroup(new RectTransform(Vector2.One, paddedFrame.RectTransform));
|
||||
|
||||
LocalizedString className = !sub.Info.HasTag(SubmarineTag.Shuttle) ? TextManager.Get($"submarineclass.{sub.Info.SubmarineClass}") : TextManager.Get("shuttle");
|
||||
LocalizedString className = !sub.Info.HasTag(SubmarineTag.Shuttle) ?
|
||||
TextManager.GetWithVariables("submarine.classandtier",
|
||||
("[class]", TextManager.Get($"submarineclass.{sub.Info.SubmarineClass}")),
|
||||
("[tier]", TextManager.Get($"submarinetier.{sub.Info.Tier}"))) :
|
||||
TextManager.Get("shuttle");
|
||||
|
||||
int nameHeight = (int)GUIStyle.LargeFont.MeasureString(sub.Info.DisplayName, true).Y;
|
||||
int classHeight = (int)GUIStyle.SubHeadingFont.MeasureString(className).Y;
|
||||
@@ -1763,7 +1767,10 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
var specsListBox = new GUIListBox(new RectTransform(new Vector2(1f, 0.57f), paddedFrame.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft));
|
||||
var specsListBox = new GUIListBox(new RectTransform(new Vector2(1f, 0.57f), paddedFrame.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft))
|
||||
{
|
||||
CurrentSelectMode = GUIListBox.SelectMode.None
|
||||
};
|
||||
sub.Info.CreateSpecsWindow(specsListBox, GUIStyle.Font, includeTitle: false, includeClass: false, includeDescription: true);
|
||||
}
|
||||
}
|
||||
@@ -1803,162 +1810,126 @@ namespace Barotrauma
|
||||
{ TalentTree.TalentTreeStageState.Highlighted, new Color(50,47,33,255) },
|
||||
}.ToImmutableDictionary();
|
||||
|
||||
private void CreateTalentInfo(GUIFrame infoFrame)
|
||||
private void CreateCharacterInfo(GUIFrame infoFrame)
|
||||
{
|
||||
infoFrame.ClearChildren();
|
||||
talentButtons.Clear();
|
||||
talentCornerIcons.Clear();
|
||||
|
||||
GUIFrame talentFrameBackground = new GUIFrame(new RectTransform(Vector2.One, infoFrame.RectTransform, Anchor.TopCenter), style: "GUIFrameListBox");
|
||||
GUIFrame background = new GUIFrame(new RectTransform(Vector2.One, infoFrame.RectTransform, Anchor.TopCenter), style: "GUIFrameListBox");
|
||||
int padding = GUI.IntScale(15);
|
||||
GUIFrame talentFrameContent = new GUIFrame(new RectTransform(new Point(talentFrameBackground.Rect.Width - padding, talentFrameBackground.Rect.Height - padding), infoFrame.RectTransform, Anchor.Center), style: null);
|
||||
GUIFrame frame = new GUIFrame(new RectTransform(new Point(background.Rect.Width - padding, background.Rect.Height - padding), infoFrame.RectTransform, Anchor.Center), style: null);
|
||||
|
||||
GUIFrame paddedTalentFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.9f), talentFrameContent.RectTransform, Anchor.Center), style: null);
|
||||
|
||||
GUIFrame talentFrameMain = new GUIFrame(new RectTransform(Vector2.One, paddedTalentFrame.RectTransform), style: null);
|
||||
GUIFrame content = new GUIFrame(new RectTransform(new Vector2(0.98f), frame.RectTransform, Anchor.Center), style: null);
|
||||
|
||||
GUIFrame characterSettingsFrame = null;
|
||||
GUILayoutGroup characterLayout = null;
|
||||
if (!(GameMain.NetworkMember is null))
|
||||
{
|
||||
characterSettingsFrame = new GUIFrame(new RectTransform(Vector2.One, talentFrameContent.RectTransform), style: null) { Visible = false };
|
||||
characterSettingsFrame = new GUIFrame(new RectTransform(Vector2.One, frame.RectTransform), style: null) { Visible = false };
|
||||
characterLayout = new GUILayoutGroup(new RectTransform(Vector2.One, characterSettingsFrame.RectTransform));
|
||||
GUIFrame containerFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.9f), characterLayout.RectTransform), style: null);
|
||||
GUIFrame playerFrame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.7f), containerFrame.RectTransform, Anchor.Center), style: null);
|
||||
GameMain.NetLobbyScreen.CreatePlayerFrame(playerFrame, alwaysAllowEditing: true, createPendingText: false);
|
||||
}
|
||||
|
||||
/*Character controlledCharacter = Character.Controlled;
|
||||
if (controlledCharacter == null) { return; }
|
||||
|
||||
if (controlledCharacter.Info is null)
|
||||
{
|
||||
DebugConsole.ThrowError("No character info found for talent UI");
|
||||
return;
|
||||
}*/
|
||||
|
||||
Character controlledCharacter = Character.Controlled;
|
||||
CharacterInfo info = controlledCharacter?.Info ?? GameMain.Client?.CharacterInfo;
|
||||
if (info == null) { return; }
|
||||
|
||||
Job job = info.Job;
|
||||
|
||||
GUILayoutGroup talentFrameLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), talentFrameMain.RectTransform, anchor: Anchor.Center), childAnchor: Anchor.TopCenter)
|
||||
GUILayoutGroup contentLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), content.RectTransform, anchor: Anchor.Center), childAnchor: Anchor.TopCenter)
|
||||
{
|
||||
AbsoluteSpacing = GUI.IntScale(5)
|
||||
AbsoluteSpacing = GUI.IntScale(10),
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
GUILayoutGroup talentInfoLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.25f), talentFrameLayoutGroup.RectTransform, Anchor.Center), isHorizontal: true);
|
||||
GUILayoutGroup topLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.3f), contentLayout.RectTransform, Anchor.Center), isHorizontal: true);
|
||||
|
||||
|
||||
new GUICustomComponent(new RectTransform(new Vector2(0.25f, 1f), talentInfoLayoutGroup.RectTransform), onDraw: (batch, component) =>
|
||||
new GUICustomComponent(new RectTransform(new Vector2(0.25f, 1f), topLayout.RectTransform), onDraw: (batch, component) =>
|
||||
{
|
||||
float posY = component.Rect.Center.Y - component.Rect.Width / 2;
|
||||
info.DrawPortrait(batch, new Vector2(component.Rect.X, posY), Vector2.Zero, component.Rect.Width, false, false);
|
||||
});
|
||||
|
||||
GUILayoutGroup nameLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.3f, 1f), talentInfoLayoutGroup.RectTransform)) { RelativeSpacing = 0.05f };
|
||||
GUILayoutGroup nameLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.3f, 1f), topLayout.RectTransform))
|
||||
{
|
||||
AbsoluteSpacing = GUI.IntScale(5),
|
||||
CanBeFocused = true
|
||||
};
|
||||
|
||||
Vector2 nameSize = GUIStyle.SubHeadingFont.MeasureString(info.Name);
|
||||
GUITextBlock nameBlock = new GUITextBlock(new RectTransform(Vector2.One, nameLayout.RectTransform), info.Name, font: GUIStyle.SubHeadingFont);
|
||||
nameBlock.RectTransform.NonScaledSize = nameSize.Pad(nameBlock.Padding).ToPoint();
|
||||
GUITextBlock nameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), nameLayout.RectTransform), info.Name, font: GUIStyle.SubHeadingFont);
|
||||
|
||||
if (!info.OmitJobInMenus)
|
||||
{
|
||||
nameBlock.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();
|
||||
GUITextBlock jobBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), nameLayout.RectTransform), job.Name, font: GUIStyle.SmallFont) { TextColor = job.Prefab.UIColor };
|
||||
}
|
||||
|
||||
LocalizedString traitString = TextManager.AddPunctuation(':', TextManager.Get("PersonalityTrait"), TextManager.Get("personalitytrait." + info.PersonalityTrait.Name.Replace(" ", "")));
|
||||
LocalizedString traitString = TextManager.AddPunctuation(':', TextManager.Get("PersonalityTrait"), info.PersonalityTrait.DisplayName);
|
||||
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 talentsOutsideTreeFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.35f), nameLayout.RectTransform, Anchor.BottomCenter), style: null);
|
||||
|
||||
if (!(GameMain.NetworkMember is null))
|
||||
IEnumerable<TalentPrefab> talentsOutsideTree = info.GetUnlockedTalentsOutsideTree().Select(e => TalentPrefab.TalentPrefabs.Find(c => c.Identifier == e));
|
||||
if (talentsOutsideTree.Count() > 0)
|
||||
{
|
||||
GUIButton newCharacterBox = new GUIButton(new RectTransform(new Vector2(0.675f, 1f), talentsOutsideTreeFrame.RectTransform, Anchor.TopLeft),
|
||||
text: GameMain.NetLobbyScreen.CampaignCharacterDiscarded ? TextManager.Get("settings") : TextManager.Get("createnew"))
|
||||
//spacing
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), nameLayout.RectTransform), style: null);
|
||||
|
||||
GUILayoutGroup extraTalentLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.3f), nameLayout.RectTransform), childAnchor: Anchor.TopCenter);
|
||||
|
||||
talentPointText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), extraTalentLayout.RectTransform, anchor: Anchor.Center), TextManager.Get("talentmenu.extratalents"), font: GUIStyle.SubHeadingFont);
|
||||
talentPointText.RectTransform.MaxSize = new Point(int.MaxValue, (int)talentPointText.TextSize.Y);
|
||||
|
||||
var extraTalentList = new GUIListBox(new RectTransform(new Vector2(0.9f, 0.8f), extraTalentLayout.RectTransform, anchor: Anchor.Center), isHorizontal: true)
|
||||
{
|
||||
IgnoreLayoutGroups = true
|
||||
AutoHideScrollBar = false,
|
||||
ResizeContentToMakeSpaceForScrollBar = false
|
||||
};
|
||||
newCharacterBox.TextBlock.AutoScaleHorizontal = true;
|
||||
extraTalentList.ScrollBar.RectTransform.SetPosition(Anchor.BottomCenter, Pivot.TopCenter);
|
||||
extraTalentList.RectTransform.MinSize = new Point(0, GUI.IntScale(65));
|
||||
extraTalentLayout.Recalculate();
|
||||
extraTalentList.ForceLayoutRecalculation();
|
||||
|
||||
newCharacterBox.OnClicked = (button, o) =>
|
||||
foreach (var extraTalent in talentsOutsideTree)
|
||||
{
|
||||
if (!GameMain.NetLobbyScreen.CampaignCharacterDiscarded)
|
||||
var img = new GUIImage(new RectTransform(new Point(extraTalentList.Content.Rect.Height), extraTalentList.Content.RectTransform), sprite: extraTalent.Icon, scaleToFit: true)
|
||||
{
|
||||
GameMain.NetLobbyScreen.TryDiscardCampaignCharacter(() =>
|
||||
{
|
||||
newCharacterBox.Text = TextManager.Get("settings");
|
||||
|
||||
if (pendingChangesFrame != null)
|
||||
{
|
||||
NetLobbyScreen.CreateChangesPendingFrame(pendingChangesFrame);
|
||||
}
|
||||
OpenMenu();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
OpenMenu();
|
||||
return true;
|
||||
|
||||
void OpenMenu()
|
||||
{
|
||||
characterSettingsFrame!.Visible = true;
|
||||
talentFrameMain.Visible = false;
|
||||
}
|
||||
};
|
||||
|
||||
if (!(characterLayout is null))
|
||||
{
|
||||
GUILayoutGroup characterCloseButtonLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.1f), characterLayout.RectTransform), childAnchor: Anchor.BottomRight);
|
||||
new GUIButton(new RectTransform(new Vector2(0.4f, 1f), characterCloseButtonLayout.RectTransform), TextManager.Get("ApplySettingsButton")) //TODO: Is this text appropriate for this circumstance for all languages?
|
||||
{
|
||||
OnClicked = (button, o) =>
|
||||
{
|
||||
GameMain.Client?.SendCharacterInfo(GameMain.Client.PendingName);
|
||||
characterSettingsFrame!.Visible = false;
|
||||
talentFrameMain.Visible = true;
|
||||
return true;
|
||||
}
|
||||
ToolTip = RichString.Rich($"‖color:{Color.White.ToStringHex()}‖{extraTalent.DisplayName}‖color:end‖" + "\n\n" + extraTalent.Description),
|
||||
Color = GUIStyle.Green
|
||||
};
|
||||
img.RectTransform.SizeChanged += () =>
|
||||
{
|
||||
img.RectTransform.MaxSize = new Point(img.Rect.Height);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<TalentPrefab> talentsOutsideTree = info.GetUnlockedTalentsOutsideTree().Select(e => TalentPrefab.TalentPrefabs.Find(c => c.Identifier == e));
|
||||
GUILayoutGroup skillLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.45f, 1f), topLayout.RectTransform), childAnchor: Anchor.TopRight)
|
||||
{
|
||||
AbsoluteSpacing = GUI.IntScale(5),
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
if (talentsOutsideTree.Count() > 0)
|
||||
{
|
||||
//TODO: replace with something more generic
|
||||
GUIImage endocrineIcon = new GUIImage(new RectTransform(new Vector2(0.275f, 1f), talentsOutsideTreeFrame.RectTransform, anchor: Anchor.TopRight, scaleBasis: ScaleBasis.Normal), style: "EndocrineReminderIcon")
|
||||
{
|
||||
ToolTip = $"{TextManager.Get("afflictionname.endocrineboost")}\n\n{string.Join(", ", talentsOutsideTree.Select(e => e.DisplayName))}"
|
||||
};
|
||||
}
|
||||
|
||||
GUILayoutGroup skillLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.45f, 1f), talentInfoLayoutGroup.RectTransform)) { Stretch = true };
|
||||
|
||||
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();
|
||||
GUITextBlock skillBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), skillLayout.RectTransform), TextManager.Get("skills"), font: GUIStyle.SubHeadingFont);
|
||||
|
||||
skillListBox = new GUIListBox(new RectTransform(new Vector2(1f, 1f - skillBlock.RectTransform.RelativeSize.Y), skillLayout.RectTransform), style: null);
|
||||
CreateTalentSkillList(controlledCharacter, info, skillListBox);
|
||||
CreateSkillList(controlledCharacter, info, skillListBox);
|
||||
|
||||
if (controlledCharacter != null)
|
||||
new GUIFrame(new RectTransform(new Vector2(1f, 1f), contentLayout.RectTransform), style: "HorizontalLine");
|
||||
|
||||
GUIListBox talentTreeListBox = new GUIListBox(new RectTransform(new Vector2(1f, 0.6f), contentLayout.RectTransform, Anchor.TopCenter), isHorizontal: true, style: null);
|
||||
|
||||
if (controlledCharacter == null)
|
||||
{
|
||||
talentTreeListBox.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!TalentTree.JobTalentTrees.TryGet(info.Job.Prefab.Identifier, out TalentTree talentTree)) { return; }
|
||||
|
||||
new GUIFrame(new RectTransform(new Vector2(1f, 1f), talentFrameLayoutGroup.RectTransform), style: "HorizontalLine");
|
||||
|
||||
GUIListBox talentTreeListBox = new GUIListBox(new RectTransform(new Vector2(1f, 0.7f), talentFrameLayoutGroup.RectTransform, Anchor.TopCenter), isHorizontal: true, style: null);
|
||||
|
||||
selectedTalents = info.GetUnlockedTalentsInTree().ToList();
|
||||
|
||||
List<GUITextBlock> subTreeNames = new List<GUITextBlock>();
|
||||
@@ -1994,24 +1965,24 @@ namespace Barotrauma
|
||||
Point iconSize = cornerIcon.RectTransform.NonScaledSize;
|
||||
cornerIcon.RectTransform.AbsoluteOffset = new Point(iconSize.X / 2, iconSize.Y / 2);
|
||||
|
||||
if (subTree.TalentOptionStages.Count <= i) { continue; }
|
||||
if (subTree.TalentOptionStages.Length <= i) { continue; }
|
||||
|
||||
TalentOption talentOption = subTree.TalentOptionStages[i];
|
||||
GUILayoutGroup talentOptionCenterGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.75f, 0.7f), talentOptionFrame.RectTransform, Anchor.Center), childAnchor: Anchor.CenterLeft);
|
||||
GUILayoutGroup talentOptionLayoutGroup = new GUILayoutGroup(new RectTransform(Vector2.One, talentOptionCenterGroup.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft) { Stretch = true };
|
||||
|
||||
foreach (TalentPrefab talent in talentOption.Talents.OrderBy(t => t.Identifier))
|
||||
foreach (Identifier talentId in talentOption.TalentIdentifiers.OrderBy(t => t))
|
||||
{
|
||||
if (!TalentPrefab.TalentPrefabs.TryGet(talentId, out TalentPrefab talent)) { continue; }
|
||||
GUIFrame talentFrame = new GUIFrame(new RectTransform(Vector2.One, talentOptionLayoutGroup.RectTransform), style: null)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
GUIFrame croppedTalentFrame = new GUIFrame(new RectTransform(Vector2.One, talentFrame.RectTransform, anchor: Anchor.Center, scaleBasis: ScaleBasis.BothHeight), style: null);
|
||||
|
||||
GUIButton talentButton = new GUIButton(new RectTransform(Vector2.One, croppedTalentFrame.RectTransform, anchor: Anchor.Center), style: null)
|
||||
{
|
||||
ToolTip = RichString.Rich(talent.DisplayName + "\n\n" + talent.Description),
|
||||
ToolTip = RichString.Rich($"‖color:{Color.White.ToStringHex()}‖{talent.DisplayName}‖color:end‖" + "\n\n" + talent.Description),
|
||||
UserData = talent.Identifier,
|
||||
PressedColor = pressedColor,
|
||||
Enabled = controlledCharacter != null,
|
||||
@@ -2078,9 +2049,13 @@ namespace Barotrauma
|
||||
}
|
||||
GUITextBlock.AutoScaleAndNormalize(subTreeNames);
|
||||
|
||||
GUILayoutGroup talentBottomFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.07f), talentFrameLayoutGroup.RectTransform, Anchor.TopCenter), isHorizontal: true) { RelativeSpacing = 0.01f };
|
||||
GUILayoutGroup bottomLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.07f), contentLayout.RectTransform, Anchor.TopCenter), isHorizontal: true)
|
||||
{
|
||||
RelativeSpacing = 0.01f,
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
GUILayoutGroup experienceLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.59f, 1f), talentBottomFrame.RectTransform));
|
||||
GUILayoutGroup experienceLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.59f, 1f), bottomLayout.RectTransform));
|
||||
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),
|
||||
@@ -2097,47 +2072,100 @@ namespace Barotrauma
|
||||
|
||||
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")
|
||||
talentResetButton = new GUIButton(new RectTransform(new Vector2(0.19f, 1f), bottomLayout.RectTransform), text: TextManager.Get("reset"), style: "GUIButtonFreeScale")
|
||||
{
|
||||
OnClicked = ResetTalentSelection
|
||||
};
|
||||
talentApplyButton = new GUIButton(new RectTransform(new Vector2(0.19f, 1f), talentBottomFrame.RectTransform), text: TextManager.Get("applysettingsbutton"), style: "GUIButtonFreeScale")
|
||||
talentApplyButton = new GUIButton(new RectTransform(new Vector2(0.19f, 1f), bottomLayout.RectTransform), text: TextManager.Get("applysettingsbutton"), style: "GUIButtonFreeScale")
|
||||
{
|
||||
OnClicked = ApplyTalentSelection,
|
||||
};
|
||||
GUITextBlock.AutoScaleAndNormalize(talentResetButton.TextBlock, talentApplyButton.TextBlock);
|
||||
}
|
||||
|
||||
if (!(GameMain.NetworkMember is null))
|
||||
{
|
||||
GUIButton newCharacterBox = new GUIButton(new RectTransform(new Vector2(0.5f, 0.2f), skillLayout.RectTransform, Anchor.BottomRight),
|
||||
text: GameMain.NetLobbyScreen.CampaignCharacterDiscarded ? TextManager.Get("settings") : TextManager.Get("createnew"), style: "GUIButtonSmall")
|
||||
{
|
||||
IgnoreLayoutGroups = false
|
||||
};
|
||||
newCharacterBox.TextBlock.AutoScaleHorizontal = true;
|
||||
|
||||
newCharacterBox.OnClicked = (button, o) =>
|
||||
{
|
||||
if (!GameMain.NetLobbyScreen.CampaignCharacterDiscarded)
|
||||
{
|
||||
GameMain.NetLobbyScreen.TryDiscardCampaignCharacter(() =>
|
||||
{
|
||||
newCharacterBox.Text = TextManager.Get("settings");
|
||||
if (pendingChangesFrame != null)
|
||||
{
|
||||
NetLobbyScreen.CreateChangesPendingFrame(pendingChangesFrame);
|
||||
}
|
||||
OpenMenu();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
OpenMenu();
|
||||
return true;
|
||||
|
||||
void OpenMenu()
|
||||
{
|
||||
characterSettingsFrame!.Visible = true;
|
||||
content.Visible = false;
|
||||
}
|
||||
};
|
||||
|
||||
if (!(characterLayout is null))
|
||||
{
|
||||
GUILayoutGroup characterCloseButtonLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.1f), characterLayout.RectTransform), childAnchor: Anchor.BottomCenter);
|
||||
new GUIButton(new RectTransform(new Vector2(0.4f, 1f), characterCloseButtonLayout.RectTransform), TextManager.Get("ApplySettingsButton")) //TODO: Is this text appropriate for this circumstance for all languages?
|
||||
{
|
||||
OnClicked = (button, o) =>
|
||||
{
|
||||
GameMain.Client?.SendCharacterInfo(GameMain.Client.PendingName);
|
||||
characterSettingsFrame!.Visible = false;
|
||||
content.Visible = true;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
UpdateTalentInfo();
|
||||
}
|
||||
|
||||
private void CreateTalentSkillList(Character character, CharacterInfo info, GUIListBox parent)
|
||||
private void CreateSkillList(Character character, CharacterInfo info, GUIListBox parent)
|
||||
{
|
||||
parent.Content.ClearChildren();
|
||||
List<GUITextBlock> skillNames = new List<GUITextBlock>();
|
||||
foreach (Skill skill in info.Job.GetSkills())
|
||||
{
|
||||
GUILayoutGroup skillContainer = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.2f), parent.Content.RectTransform), isHorizontal: true) { CanBeFocused = false };
|
||||
GUILayoutGroup skillContainer = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.0f), parent.Content.RectTransform), isHorizontal: true) { CanBeFocused = true };
|
||||
var skillName = new GUITextBlock(new RectTransform(new Vector2(0.7f, 0.0f), skillContainer.RectTransform), TextManager.Get($"skillname.{skill.Identifier}").Fallback(skill.Identifier.Value));
|
||||
skillNames.Add(skillName);
|
||||
skillName.RectTransform.MinSize = new Point(0, skillName.Rect.Height);
|
||||
skillContainer.RectTransform.MinSize = new Point(0, skillName.Rect.Height);
|
||||
|
||||
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) };
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.15f, 1.0f), skillContainer.RectTransform), Math.Floor(skill.Level).ToString("F0"), textAlignment: Alignment.TopRight);
|
||||
|
||||
float modifiedSkillLevel = character?.GetSkillLevel(skill.Identifier) ?? skill.Level;
|
||||
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
|
||||
string stringColor = skillChange switch
|
||||
{
|
||||
true when skillChange > 0 => XMLExtensions.ColorToString(GUIStyle.Green),
|
||||
true when skillChange < 0 => XMLExtensions.ColorToString(GUIStyle.Red),
|
||||
_ => XMLExtensions.ColorToString(GUIStyle.TextColorNormal)
|
||||
> 0 => XMLExtensions.ToStringHex(GUIStyle.Green),
|
||||
< 0 => XMLExtensions.ToStringHex(GUIStyle.Red),
|
||||
_ => XMLExtensions.ToStringHex(GUIStyle.TextColorNormal)
|
||||
};
|
||||
|
||||
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();
|
||||
//skillContainer.Recalculate();
|
||||
}
|
||||
|
||||
parent.RecalculateChildren();
|
||||
@@ -2216,7 +2244,7 @@ namespace Barotrauma
|
||||
talentButton.icon.HoverColor = hoverColor;
|
||||
}
|
||||
|
||||
CreateTalentSkillList(controlledCharacter, controlledCharacter.Info, skillListBox);
|
||||
CreateSkillList(controlledCharacter, controlledCharacter.Info, skillListBox);
|
||||
}
|
||||
|
||||
private void ApplyTalents(Character controlledCharacter)
|
||||
|
||||
@@ -17,7 +17,7 @@ using PlayerBalanceElement = Barotrauma.CampaignUI.PlayerBalanceElement;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
internal class UpgradeStore
|
||||
internal sealed class UpgradeStore
|
||||
{
|
||||
public readonly struct CategoryData
|
||||
{
|
||||
@@ -432,13 +432,21 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
Location location = Campaign.Map.CurrentLocation;
|
||||
int hullRepairCost = location?.GetAdjustedMechanicalCost(CampaignMode.HullRepairCost) ?? CampaignMode.HullRepairCost;
|
||||
int itemRepairCost = location?.GetAdjustedMechanicalCost(CampaignMode.ItemRepairCost) ?? CampaignMode.ItemRepairCost;
|
||||
int shuttleRetrieveCost = location?.GetAdjustedMechanicalCost(CampaignMode.ShuttleReplaceCost) ?? CampaignMode.ShuttleReplaceCost;
|
||||
|
||||
int hullRepairCost = Campaign.GetHullRepairCost();
|
||||
int itemRepairCost = Campaign.GetItemRepairCost();
|
||||
int shuttleRetrieveCost = CampaignMode.ShuttleReplaceCost;
|
||||
if (location != null)
|
||||
{
|
||||
hullRepairCost = location.GetAdjustedMechanicalCost(hullRepairCost);
|
||||
itemRepairCost = location.GetAdjustedMechanicalCost(itemRepairCost);
|
||||
shuttleRetrieveCost = location.GetAdjustedMechanicalCost(shuttleRetrieveCost);
|
||||
}
|
||||
|
||||
CreateRepairEntry(currentStoreLayout.Content, TextManager.Get("repairallwalls"), "RepairHullButton", hullRepairCost, (button, o) =>
|
||||
{
|
||||
if (Campaign.PurchasedHullRepairs)
|
||||
//cost is zero = nothing to repair
|
||||
if (Campaign.PurchasedHullRepairs || hullRepairCost <= 0)
|
||||
{
|
||||
button.Enabled = false;
|
||||
return false;
|
||||
@@ -471,7 +479,7 @@ namespace Barotrauma
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}, Campaign.PurchasedHullRepairs || !HasPermission, isHovered =>
|
||||
}, Campaign.PurchasedHullRepairs || !HasPermission || hullRepairCost <= 0, isHovered =>
|
||||
{
|
||||
highlightWalls = isHovered;
|
||||
return true;
|
||||
@@ -479,7 +487,8 @@ namespace Barotrauma
|
||||
|
||||
CreateRepairEntry(currentStoreLayout.Content, TextManager.Get("repairallitems"), "RepairItemsButton", itemRepairCost, (button, o) =>
|
||||
{
|
||||
if (PlayerBalance >= itemRepairCost && !Campaign.PurchasedItemRepairs)
|
||||
//cost is zero = nothing to repair
|
||||
if (PlayerBalance >= itemRepairCost && !Campaign.PurchasedItemRepairs && itemRepairCost > 0)
|
||||
{
|
||||
LocalizedString body = TextManager.GetWithVariable("ItemRepairs.PurchasePromptBody", "[amount]", itemRepairCost.ToString());
|
||||
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), body, () =>
|
||||
@@ -505,9 +514,8 @@ namespace Barotrauma
|
||||
button.Enabled = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}, Campaign.PurchasedItemRepairs || !HasPermission, isHovered =>
|
||||
}, Campaign.PurchasedItemRepairs || !HasPermission || itemRepairCost <= 0, isHovered =>
|
||||
{
|
||||
foreach (var (item, itemFrame) in itemPreviews)
|
||||
{
|
||||
@@ -839,7 +847,8 @@ namespace Barotrauma
|
||||
|
||||
foreach (UpgradePrefab prefab in prefabs)
|
||||
{
|
||||
CreateUpgradeEntry(prefab, category, parent.Content, entitiesOnSub);
|
||||
if (prefab.MaxLevel is 0) { continue; }
|
||||
CreateUpgradeEntry(prefab, category, parent.Content, submarine, entitiesOnSub);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -865,7 +874,7 @@ namespace Barotrauma
|
||||
itemPrefab.SwappableItem.CanBeBought &&
|
||||
itemPrefab.SwappableItem.SwapIdentifier.Equals(item.Prefab.SwappableItem.SwapIdentifier, StringComparison.OrdinalIgnoreCase)).Cast<ItemPrefab>();
|
||||
|
||||
var linkedItems = Campaign.UpgradeManager.GetLinkedItemsToSwap(item) ?? new List<Item>() { item };
|
||||
var linkedItems = UpgradeManager.GetLinkedItemsToSwap(item) ?? new List<Item>() { item };
|
||||
//create the swap entry only for one of the items (the one with the smallest ID)
|
||||
if (linkedItems.Min(it => it.ID) < item.ID) { return; }
|
||||
|
||||
@@ -901,7 +910,7 @@ namespace Barotrauma
|
||||
GUILayoutGroup buttonLayout = new GUILayoutGroup(rectT(1f, 1f, toggleButton.Frame), isHorizontal: true);
|
||||
|
||||
LocalizedString slotText = "";
|
||||
if (linkedItems.Count > 1)
|
||||
if (linkedItems.Count() > 1)
|
||||
{
|
||||
slotText = TextManager.GetWithVariable("weaponslot", "[number]", string.Join(", ", linkedItems.Select(it => (swappableEntities.IndexOf(it) + 1).ToString())));
|
||||
}
|
||||
@@ -973,7 +982,7 @@ namespace Barotrauma
|
||||
|
||||
bool isPurchased = item.AvailableSwaps.Contains(replacement);
|
||||
|
||||
int price = isPurchased || replacement == item.Prefab ? 0 : replacement.SwappableItem.GetPrice(Campaign.Map?.CurrentLocation) * linkedItems.Count;
|
||||
int price = isPurchased || replacement == item.Prefab ? 0 : replacement.SwappableItem.GetPrice(Campaign.Map?.CurrentLocation) * linkedItems.Count();
|
||||
|
||||
frames.Add(CreateUpgradeEntry(rectT(1f, 0.25f, parent.Content), replacement.UpgradePreviewSprite, replacement.Name, replacement.Description,
|
||||
price, replacement,
|
||||
@@ -989,7 +998,7 @@ namespace Barotrauma
|
||||
{
|
||||
LocalizedString promptBody = TextManager.GetWithVariables(isPurchased ? "upgrades.itemswappromptbody" : "upgrades.purchaseitemswappromptbody",
|
||||
("[itemtoinstall]", replacement.Name),
|
||||
("[amount]", (replacement.SwappableItem.GetPrice(Campaign?.Map?.CurrentLocation) * linkedItems.Count).ToString()));
|
||||
("[amount]", (replacement.SwappableItem.GetPrice(Campaign?.Map?.CurrentLocation) * linkedItems.Count()).ToString()));
|
||||
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), promptBody, () =>
|
||||
{
|
||||
if (GameMain.NetworkMember != null)
|
||||
@@ -1033,7 +1042,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (toggleButton.Selected)
|
||||
{
|
||||
var linkedItems = Campaign.UpgradeManager.GetLinkedItemsToSwap(item);
|
||||
var linkedItems = UpgradeManager.GetLinkedItemsToSwap(item);
|
||||
foreach (var itemPreview in itemPreviews)
|
||||
{
|
||||
itemPreview.Value.OutlineColor = itemPreview.Value.Color = linkedItems.Contains(itemPreview.Key) ? GUIStyle.Orange : previewWhite;
|
||||
@@ -1104,7 +1113,7 @@ namespace Barotrauma
|
||||
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, GUIStyle.Orange);
|
||||
new GUITextBlock(rectT(0.2f, 1, progressLayout), string.Empty, font: GUIStyle.SmallFont, textAlignment: Alignment.Center) { Padding = Vector4.Zero };
|
||||
@@ -1116,7 +1125,11 @@ namespace Barotrauma
|
||||
//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);
|
||||
var priceText = new GUITextBlock(rectT(1, 0.2f, buyButtonLayout), formattedPrice, textAlignment: Alignment.Center)
|
||||
{
|
||||
//prices on swappable items are always visible, upgrade prices are enabled in UpdateUpgradeEntry for purchasable upgrades
|
||||
Visible = userData is ItemPrefab
|
||||
};
|
||||
if (price < 0)
|
||||
{
|
||||
priceText.TextColor = GUIStyle.Green;
|
||||
@@ -1175,9 +1188,10 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateUpgradeEntry(UpgradePrefab prefab, UpgradeCategory category, GUIComponent parent, List<Item>? itemsOnSubmarine)
|
||||
private void CreateUpgradeEntry(UpgradePrefab prefab, UpgradeCategory category, GUIComponent parent, Submarine submarine, List<Item>? itemsOnSubmarine)
|
||||
{
|
||||
if (Campaign is null) { return; }
|
||||
Submarine? sub = GameMain.GameSession?.Submarine ?? Submarine.MainSub;
|
||||
if (Campaign is null || sub is null) { return; }
|
||||
|
||||
GUIFrame prefabFrame = CreateUpgradeFrame(prefab, category, Campaign, rectT(1f, 0.25f, parent));
|
||||
var prefabLayout = prefabFrame.GetChild<GUILayoutGroup>();
|
||||
@@ -1193,7 +1207,7 @@ namespace Barotrauma
|
||||
var buyButtonLayout = childLayouts[2];
|
||||
var buyButton = buyButtonLayout.GetChild<GUIButton>();
|
||||
|
||||
if (!HasPermission || (itemsOnSubmarine != null && !itemsOnSubmarine.Any(it => category.CanBeApplied(it, prefab))))
|
||||
if (!HasPermission || !prefab.IsApplicable(submarine.Info) || (itemsOnSubmarine != null && !itemsOnSubmarine.Any(it => category.CanBeApplied(it, prefab))))
|
||||
{
|
||||
prefabFrame.Enabled = false;
|
||||
description.Enabled = false;
|
||||
@@ -1243,12 +1257,17 @@ namespace Barotrauma
|
||||
List<Upgrade> upgrades = entity.GetUpgrades();
|
||||
int upgradesCount = upgrades.Count;
|
||||
const int maxUpgrades = 4;
|
||||
|
||||
itemName.Text = entity is Item ? entity.Name : TextManager.Get("upgradecategory.walls");
|
||||
|
||||
Item? item = entity as Item;
|
||||
itemName.Text = item?.Name ?? TextManager.Get("upgradecategory.walls");
|
||||
if (slotIndex > -1)
|
||||
{
|
||||
itemName.Text = TextManager.GetWithVariables("weaponslotwithname", ("[number]", slotIndex.ToString()), ("[weaponname]", itemName.Text));
|
||||
}
|
||||
if (item?.PendingItemSwap != null)
|
||||
{
|
||||
itemName.Text = RichString.Rich(itemName.Text + "\n" + TextManager.GetWithVariable("upgrades.pendingitem", "[itemname]", item.PendingItemSwap.Name));
|
||||
}
|
||||
upgradeList.Content.ClearChildren();
|
||||
for (var i = 0; i < upgrades.Count && i < maxUpgrades; i++)
|
||||
{
|
||||
@@ -1261,7 +1280,7 @@ namespace Barotrauma
|
||||
// include pending upgrades into the tooltip
|
||||
foreach (var (prefab, category, level) in upgradeManager.PendingUpgrades)
|
||||
{
|
||||
if (entity is Item item && category.CanBeApplied(item, prefab) || entity is Structure && category.IsWallUpgrade)
|
||||
if (item != null && category.CanBeApplied(item, prefab) || entity is Structure && category.IsWallUpgrade)
|
||||
{
|
||||
bool found = false;
|
||||
foreach (GUITextBlock textBlock in upgradeList.Content.Children.Where(c => c is GUITextBlock).Cast<GUITextBlock>())
|
||||
@@ -1305,6 +1324,8 @@ namespace Barotrauma
|
||||
Item[] entitiesOnSub = drawnSubmarine.GetItems(true).Where(i => drawnSubmarine.IsEntityFoundOnThisSub(i, true)).ToArray();
|
||||
foreach (UpgradeCategory category in UpgradeCategory.Categories)
|
||||
{
|
||||
//hide categories with no upgrades in them
|
||||
if (UpgradePrefab.Prefabs.None(p => p.UpgradeCategories.Contains(category))) { continue; }
|
||||
if (entitiesOnSub.Any(item => category.CanBeApplied(item, null)))
|
||||
{
|
||||
yield return category;
|
||||
@@ -1370,12 +1391,16 @@ namespace Barotrauma
|
||||
{
|
||||
if (selectedUpgradeCategoryLayout != null)
|
||||
{
|
||||
var linkedItems = HoveredEntity is Item hoveredItem ? Campaign.UpgradeManager.GetLinkedItemsToSwap(hoveredItem) : new List<Item>();
|
||||
var linkedItems = HoveredEntity is Item hoveredItem ? UpgradeManager.GetLinkedItemsToSwap(hoveredItem) : new List<Item>();
|
||||
if (selectedUpgradeCategoryLayout.FindChild(c => c.UserData is Item item && (item == HoveredEntity || linkedItems.Contains(item)), recursive: true) is GUIButton itemElement)
|
||||
{
|
||||
if (!itemElement.Selected) { itemElement.OnClicked(itemElement, itemElement.UserData); }
|
||||
(itemElement.Parent?.Parent?.Parent as GUIListBox)?.ScrollToElement(itemElement);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScrollToCategory(data => data.Category.CanBeApplied(item, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1436,7 +1461,7 @@ namespace Barotrauma
|
||||
* |--------------------------------------------------|
|
||||
* | name |
|
||||
* |--------------------------------------------------|
|
||||
* | class |
|
||||
* | class + tier |
|
||||
* |--------------------------------------------------|
|
||||
* | description |
|
||||
* | |
|
||||
@@ -1446,13 +1471,24 @@ 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: 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: GUIStyle.Font);
|
||||
|
||||
LocalizedString classText = $"{TextManager.GetWithVariable("submarineclass.classsuffixformat", "[type]", TextManager.Get($"submarineclass.{submarine.Info.SubmarineClass}"))}";
|
||||
// submarine class + tier
|
||||
new GUITextBlock(rectT(1.0f, 0.15f, submarineInfoFrame), classText, textAlignment: Alignment.Right, font: GUIStyle.Font)
|
||||
{
|
||||
ToolTip = TextManager.Get("submarineclass.description") + "\n\n" + TextManager.Get($"submarineclass.{submarine.Info.SubmarineClass}.description")
|
||||
};
|
||||
new GUITextBlock(rectT(1.0f, 0.15f, submarineInfoFrame), TextManager.Get($"submarinetier.{submarine.Info.Tier}"), textAlignment: Alignment.Right, font: GUIStyle.Font)
|
||||
{
|
||||
ToolTip = TextManager.Get("submarinetier.description")
|
||||
};
|
||||
|
||||
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));
|
||||
|
||||
|
||||
description.Padding = new Vector4(description.Padding.X, 24 * GUI.Scale, description.Padding.Z, description.Padding.W);
|
||||
List<Entity> pointsOfInterest = (from category in UpgradeCategory.Categories from item in submarine.GetItems(UpgradeManager.UpgradeAlsoConnectedSubs) where category.CanBeApplied(item, null) && item.IsPlayerTeamInteractable select item).Cast<Entity>().ToList();
|
||||
List<Entity> pointsOfInterest = (from category in UpgradeCategory.Categories from item in submarine.GetItems(UpgradeManager.UpgradeAlsoConnectedSubs)
|
||||
where category.CanBeApplied(item, null) && item.IsPlayerTeamInteractable select item).Cast<Entity>().Distinct().ToList();
|
||||
|
||||
List<ushort> ids = GameMain.GameSession.SubmarineInfo?.LeftBehindDockingPortIDs ?? new List<ushort>();
|
||||
pointsOfInterest.AddRange(submarine.GetItems(UpgradeManager.UpgradeAlsoConnectedSubs).Where(item => ids.Contains(item.ID)));
|
||||
@@ -1600,6 +1636,7 @@ namespace Barotrauma
|
||||
List<GUITextBlock> textBlocks = buttonParent.GetAllChildren<GUITextBlock>().ToList();
|
||||
|
||||
GUITextBlock priceLabel = textBlocks[0];
|
||||
priceLabel.Visible = true;
|
||||
int price = prefab.Price.GetBuyprice(campaign.UpgradeManager.GetUpgradeLevel(prefab, category), campaign.Map?.CurrentLocation);
|
||||
|
||||
if (priceLabel != null && !WaitForServerUpdate)
|
||||
@@ -1638,9 +1675,15 @@ namespace Barotrauma
|
||||
IEnumerable<UpgradeCategory> applicableCategories)
|
||||
{
|
||||
// Disables the parent and only re-enables if the submarine contains valid items
|
||||
if (!category.IsWallUpgrade && drawnSubmarine != null)
|
||||
if (!category.IsWallUpgrade && drawnSubmarine?.Info != null)
|
||||
{
|
||||
if (applicableCategories.Contains(category))
|
||||
if (UpgradePrefab.Prefabs.None(p => p.UpgradeCategories.Contains(category) && p.GetMaxLevel(drawnSubmarine.Info) > 0))
|
||||
{
|
||||
parent.ToolTip = TextManager.Get("upgradecategorynotapplicable");
|
||||
parent.Enabled = false;
|
||||
parent.SelectedColor = GUIStyle.Red * 0.5f;
|
||||
}
|
||||
else if (applicableCategories.Contains(category))
|
||||
{
|
||||
parent.Enabled = true;
|
||||
parent.SelectedColor = parent.Style.SelectedColor;
|
||||
@@ -1660,14 +1703,27 @@ namespace Barotrauma
|
||||
{
|
||||
if (component.UserData != prefab) { continue; }
|
||||
|
||||
if (prefab.MaxLevel is 0)
|
||||
{
|
||||
component.Visible = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
Dictionary<Identifier, GUIComponentStyle> styles = GUIStyle.GetComponentStyle("upgradeindicator").ChildStyles;
|
||||
if (!styles.ContainsKey("upgradeindicatoron") || !styles.ContainsKey("upgradeindicatordim") || !styles.ContainsKey("upgradeindicatoroff")) { continue; }
|
||||
|
||||
GUIComponentStyle onStyle = styles["upgradeindicatoron".ToIdentifier()];
|
||||
GUIComponentStyle dimStyle = styles["upgradeindicatordim".ToIdentifier()];
|
||||
GUIComponentStyle offStyle = styles["upgradeindicatoroff".ToIdentifier()];
|
||||
int maxLevel = prefab.MaxLevel;
|
||||
|
||||
if (campaign.UpgradeManager.GetUpgradeLevel(prefab, category) >= prefab.MaxLevel)
|
||||
if (maxLevel == 0)
|
||||
{
|
||||
SetOff();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (campaign.UpgradeManager.GetUpgradeLevel(prefab, category) >= maxLevel)
|
||||
{
|
||||
// we check this to avoid flickering from re-applying the same style
|
||||
if (image.Style == onStyle) { continue; }
|
||||
@@ -1680,25 +1736,42 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
if (image.Style == offStyle) { continue; }
|
||||
SetOff();
|
||||
}
|
||||
|
||||
void SetOff()
|
||||
{
|
||||
if (image.Style == offStyle) { return; }
|
||||
image.ApplyStyle(offStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ScrollToCategory(Predicate<CategoryData> predicate, GUIListBox.PlaySelectSound playSelectSound = GUIListBox.PlaySelectSound.No)
|
||||
{
|
||||
if (currentStoreLayout == null) { return; }
|
||||
|
||||
CategoryData? mostAppropriateCategory = null;
|
||||
GUIComponent? mostAppropriateChild = null;
|
||||
foreach (GUIComponent child in currentStoreLayout.Content.Children)
|
||||
{
|
||||
if (child.UserData is CategoryData data && predicate(data))
|
||||
{
|
||||
currentStoreLayout.ScrollToElement(child, playSelectSound);
|
||||
break;
|
||||
//choose the category with least items in it as the "most appropriate"
|
||||
//e.g. when selecting junction boxes, we want to select the "junction boxes" category instead of "electrical repairs" which contains many electrical devices
|
||||
if (mostAppropriateCategory == null ||
|
||||
data.Category.ItemTags.Count() < mostAppropriateCategory.Value.Category.ItemTags.Count())
|
||||
{
|
||||
mostAppropriateCategory = data;
|
||||
mostAppropriateChild = child;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mostAppropriateChild != null)
|
||||
{
|
||||
currentStoreLayout.ScrollToElement(mostAppropriateChild, playSelectSound);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -131,9 +131,9 @@ namespace Barotrauma
|
||||
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)
|
||||
public void LoadContent(string contentPath, VideoSettings videoSettings, TextSettings textSettings, Identifier contentId, bool startPlayback, LocalizedString objective, Action onStop = null)
|
||||
{
|
||||
callbackOnStop = callback;
|
||||
callbackOnStop = onStop;
|
||||
filePath = contentPath + videoSettings.File;
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace Barotrauma
|
||||
{
|
||||
currentVoteType = type;
|
||||
CreateVotingGUI();
|
||||
if (starter.ID == GameMain.Client.ID) { SetGUIToVotedState(2); }
|
||||
if (starter.SessionId == GameMain.Client.SessionId) { SetGUIToVotedState(2); }
|
||||
VoteRunning = true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user