Unstable 0.1300.0.3

This commit is contained in:
Markus Isberg
2021-03-25 15:40:24 +02:00
parent 874616027b
commit 58c50a235d
136 changed files with 2486 additions and 1008 deletions
@@ -37,7 +37,7 @@ namespace Barotrauma
public float MinZoom
{
get { return minZoom;}
set { minZoom = MathHelper.Clamp(value, 0.01f, 10.0f); }
set { minZoom = MathHelper.Clamp(value, 0.001f, 10.0f); }
}
private float maxZoom = 2.0f;
@@ -51,8 +51,6 @@ namespace Barotrauma
private float zoom;
private float offsetAmount;
private Matrix transform, shaderTransform, viewMatrix;
private Vector2 position;
private float rotation;
@@ -67,16 +65,9 @@ namespace Barotrauma
public float Shake;
private Vector2 shakePosition;
private float shakeTimer;
//the area of the world inside the camera view
private Rectangle worldView;
private float globalZoomScale = 1.0f;
private Point resolution;
private Vector2 targetPos;
//used to smooth out the movement when in freecam
private float targetZoom;
private Vector2 velocity;
@@ -89,10 +80,10 @@ namespace Barotrauma
zoom = MathHelper.Clamp(value, GameMain.DebugDraw ? 0.01f : MinZoom, MaxZoom);
Vector2 center = WorldViewCenter;
float newWidth = resolution.X / zoom;
float newHeight = resolution.Y / zoom;
float newWidth = Resolution.X / zoom;
float newHeight = Resolution.Y / zoom;
worldView = new Rectangle(
WorldView = new Rectangle(
(int)(center.X - newWidth / 2.0f),
(int)(center.Y + newHeight / 2.0f),
(int)newWidth,
@@ -122,29 +113,20 @@ namespace Barotrauma
}
}
public float OffsetAmount
{
get { return offsetAmount; }
set { offsetAmount = value; }
}
public float OffsetAmount { get; set; }
public Point Resolution
{
get { return resolution; }
}
public Point Resolution { get; private set; }
public Rectangle WorldView
{
get { return worldView; }
}
//the area of the world inside the camera view
public Rectangle WorldView { get; private set; }
public Vector2 WorldViewCenter
{
get
{
return new Vector2(
worldView.X + worldView.Width / 2.0f,
worldView.Y - worldView.Height / 2.0f);
WorldView.X + WorldView.Width / 2.0f,
WorldView.Y - WorldView.Height / 2.0f);
}
}
@@ -171,12 +153,13 @@ namespace Barotrauma
UpdateTransform(false);
}
public Vector2 TargetPos
~Camera()
{
get { return targetPos; }
set { targetPos = value; }
GameMain.Instance.ResolutionChanged -= CreateMatrices;
}
public Vector2 TargetPos { get; set; }
public Vector2 GetPosition()
{
return position;
@@ -204,21 +187,29 @@ namespace Barotrauma
public void SetResolution(Point res)
{
resolution = res;
Resolution = res;
worldView = new Rectangle(0, 0, res.X, res.Y);
WorldView = new Rectangle(0, 0, res.X, res.Y);
viewMatrix = Matrix.CreateTranslation(new Vector3(res.X / 2.0f, res.Y / 2.0f, 0));
globalZoomScale = (float)Math.Pow(new Vector2(GUI.UIWidth, resolution.Y).Length() / GUI.ReferenceResolution.Length(), 2);
float newGlobalZoomScale = (float)new Vector2(GUI.UIWidth, Resolution.Y).Length() / GUI.ReferenceResolution.Length();
if (globalZoomScale > 0.0f)
{
Zoom *= newGlobalZoomScale / globalZoomScale;
targetZoom *= newGlobalZoomScale / globalZoomScale;
prevZoom *= newGlobalZoomScale / globalZoomScale;
}
globalZoomScale = newGlobalZoomScale;
}
public void UpdateTransform(bool interpolate = true)
public void UpdateTransform(bool interpolate = true, bool updateListener = true)
{
Vector2 interpolatedPosition = interpolate ? Timing.Interpolate(prevPosition, position) : position;
float interpolatedZoom = interpolate ? Timing.Interpolate(prevZoom, zoom) : zoom;
worldView.X = (int)(interpolatedPosition.X - worldView.Width / 2.0);
worldView.Y = (int)(interpolatedPosition.Y + worldView.Height / 2.0);
WorldView = new Rectangle((int)(interpolatedPosition.X - WorldView.Width / 2.0),
(int)(interpolatedPosition.Y + WorldView.Height / 2.0),
WorldView.Width, WorldView.Height);
transform = Matrix.CreateTranslation(
new Vector3(-interpolatedPosition.X, interpolatedPosition.Y, 0)) *
@@ -227,19 +218,22 @@ namespace Barotrauma
shaderTransform = Matrix.CreateTranslation(
new Vector3(
-interpolatedPosition.X - resolution.X / interpolatedZoom / 2.0f,
-interpolatedPosition.Y - resolution.Y / interpolatedZoom / 2.0f, 0)) *
-interpolatedPosition.X - Resolution.X / interpolatedZoom / 2.0f,
-interpolatedPosition.Y - Resolution.Y / interpolatedZoom / 2.0f, 0)) *
Matrix.CreateScale(new Vector3(interpolatedZoom, interpolatedZoom, 1)) *
viewMatrix * Matrix.CreateRotationZ(-rotation);
if (Character.Controlled == null)
if (updateListener)
{
GameMain.SoundManager.ListenerPosition = new Vector3(WorldViewCenter.X, WorldViewCenter.Y, -(100.0f / zoom));
}
else
{
GameMain.SoundManager.ListenerPosition = new Vector3(Character.Controlled.WorldPosition.X, Character.Controlled.WorldPosition.Y, -(100.0f / zoom));
if (Character.Controlled == null)
{
GameMain.SoundManager.ListenerPosition = new Vector3(WorldViewCenter.X, WorldViewCenter.Y, -(100.0f / zoom));
}
else
{
GameMain.SoundManager.ListenerPosition = new Vector3(Character.Controlled.WorldPosition.X, Character.Controlled.WorldPosition.Y, -(100.0f / zoom));
}
}
@@ -257,7 +251,7 @@ namespace Barotrauma
/// </summary>
public bool Freeze { get; set; }
public void MoveCamera(float deltaTime, bool allowMove = true, bool allowZoom = true, Rectangle? overrideMouseOn = null)
public void MoveCamera(float deltaTime, bool allowMove = true, bool allowZoom = true)
{
prevPosition = position;
prevZoom = zoom;
@@ -265,7 +259,7 @@ namespace Barotrauma
float moveSpeed = 20.0f / zoom;
Vector2 moveCam = Vector2.Zero;
if (targetPos == Vector2.Zero)
if (TargetPos == Vector2.Zero)
{
Vector2 moveInput = Vector2.Zero;
if (allowMove && !Freeze)
@@ -294,7 +288,7 @@ namespace Barotrauma
}
}
if (allowZoom && (GUI.MouseOn == null || (overrideMouseOn?.Contains(PlayerInput.MousePosition) ?? false)))
if (allowZoom)
{
Vector2 mouseInWorld = ScreenToWorld(PlayerInput.MousePosition);
Vector2 diffViewCenter;
@@ -318,14 +312,14 @@ namespace Barotrauma
else if (allowMove)
{
Vector2 mousePos = PlayerInput.MousePosition;
Vector2 offset = mousePos - resolution.ToVector2() / 2;
offset.X = offset.X / (resolution.X * 0.4f);
offset.Y = -offset.Y / (resolution.Y * 0.3f);
Vector2 offset = mousePos - Resolution.ToVector2() / 2;
offset.X = offset.X / (Resolution.X * 0.6f);
offset.Y = -offset.Y / (Resolution.Y * 0.6f);
if (offset.LengthSquared() > 1.0f) offset.Normalize();
offset *= offsetAmount;
offset *= OffsetAmount;
// Freeze the camera movement by default, when the cursor is on top of an ui element.
// Setting a positive value to the OffsetAmount, will override this behaviour.
if (GUI.MouseOn != null && offsetAmount > 0)
if (GUI.MouseOn != null && OffsetAmount > 0)
{
Freeze = true;
}
@@ -343,25 +337,21 @@ namespace Barotrauma
previousOffset = offset;
}
//how much to zoom out (zoom completely out when offset is 1000)
float zoomOutAmount = GetZoomAmount(offset);
//zoom amount when resolution is not taken into account
float unscaledZoom = MathHelper.Lerp(DefaultZoom, MinZoom, zoomOutAmount);
//zoom with resolution taken into account (zoom further out on smaller resolutions)
float scaledZoom = unscaledZoom * globalZoomScale;
//TODO: remove magic numbers
float minMultiplier = OffsetAmount > 0f ? ((DefaultZoom * 8f * 250f) / OffsetAmount) : 15f;
//an ad-hoc way of allowing the players to have roughly the same maximum view distance regardless of the resolution,
//while still keeping the zoom around 1.0 when not looking further away (because otherwise we'd always be downsampling
//on lower resolutions, which doesn't look that good)
float newZoom = MathHelper.Lerp(unscaledZoom, scaledZoom,
(GameMain.Config == null || GameMain.Config.EnableMouseLook) ? (float)Math.Sqrt(zoomOutAmount) : 0.3f);
//how much to zoom out (0.0 = Default zoom, 1.0 = zoom completely out)
float zoomOutAmount = GetZoomAmount(offset);
float newZoom = MathHelper.Lerp(DefaultZoom, MinZoom * minMultiplier, zoomOutAmount) * globalZoomScale;
//zoom in further if zoomOutAmount is low and resolution is lower than reference
newZoom *= MathHelper.Lerp(0.5f * (1f - Math.Min(globalZoomScale, 1f)), 0f, zoomOutAmount) + 1f;
Zoom += (newZoom - zoom) / ZoomSmoothness;
//force targetzoom to the current zoom value, so the camera stays at the same zoom when switching to freecam
targetZoom = Zoom;
Vector2 diff = (targetPos + offset) - position;
Vector2 diff = (TargetPos + offset) - position;
moveCam = diff / MoveSmoothness;
}
@@ -426,7 +416,7 @@ namespace Barotrauma
private float GetZoomAmount(Vector2 offset)
{
return Math.Min(offset.Length() / 1000.0f, 1.0f);
return Math.Min(offset.Length() / Math.Max(1f, OffsetAmount), 1.0f);
}
public float GetZoomAmountFromPrevious()
@@ -224,8 +224,7 @@ namespace Barotrauma
float targetOffsetAmount = 0.0f;
if (moveCam)
{
if (NeedsAir &&
pressureProtection < 80.0f &&
if (NeedsAir && !IsProtectedFromPressure() &&
(AnimController.CurrentHull == null || AnimController.CurrentHull.LethalPressure > 0.0f))
{
float pressure = AnimController.CurrentHull == null ? 100.0f : AnimController.CurrentHull.LethalPressure;
@@ -382,19 +381,44 @@ namespace Barotrauma
partial void KillProjSpecific(CauseOfDeathType causeOfDeath, Affliction causeOfDeathAffliction, bool log)
{
HintManager.OnCharacterKilled(this);
if (GameMain.NetworkMember != null && controlled == this)
{
string chatMessage = CauseOfDeath.Type == CauseOfDeathType.Affliction ?
CauseOfDeath.Affliction.SelfCauseOfDeathDescription :
TextManager.Get("Self_CauseOfDeathDescription." + CauseOfDeath.Type.ToString(), fallBackTag: "Self_CauseOfDeathDescription.Damage");
if (GameMain.Client != null) chatMessage += " " + TextManager.Get("DeathChatNotification");
if (GameMain.Client != null) { chatMessage += " " + TextManager.Get("DeathChatNotification"); }
if (GameMain.GameSession?.GameMode is CampaignMode && GameMain.NetworkMember.RespawnManager != null && Level.Loaded?.Type != LevelData.LevelType.Outpost)
{
CoroutineManager.InvokeAfter(() =>
{
if (controlled != null || (!(GameMain.GameSession?.IsRunning ?? false))) { return; }
var respawnPrompt = new GUIMessageBox(
TextManager.Get("tutorial.tryagainheader"), TextManager.Get("respawnquestionprompt"),
new string[] { TextManager.Get("respawnquestionpromptrespawn"), TextManager.Get("respawnquestionpromptwait") });
respawnPrompt.Buttons[0].OnClicked += (btn, userdata) =>
{
GameMain.Client?.SendRespawnPromptResponse(waitForNextRoundRespawn: false);
respawnPrompt.Close();
return true;
};
respawnPrompt.Buttons[1].OnClicked += (btn, userdata) =>
{
GameMain.Client?.SendRespawnPromptResponse(waitForNextRoundRespawn: true);
respawnPrompt.Close();
return true;
};
}, delay: 5.0f);
}
GameMain.NetworkMember.AddChatMessage(chatMessage, ChatMessageType.Dead);
GameMain.LightManager.LosEnabled = false;
controlled = null;
}
PlaySound(CharacterSound.SoundType.Die);
}
@@ -100,7 +100,22 @@ namespace Barotrauma
Color textColor = Color.White * (0.5f + skill.Level / 200.0f);
var skillName = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), skillsArea.RectTransform), TextManager.Get("SkillName." + skill.Identifier), textColor: textColor, font: font) { Padding = Vector4.Zero };
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), skillName.RectTransform), ((int)skill.Level).ToString(), textColor: textColor, font: font, textAlignment: Alignment.CenterRight);
float modifiedSkillLevel = skill.Level;
if (Character != null)
{
modifiedSkillLevel = Character.GetSkillLevel(skill.Identifier);
}
if (!MathUtils.NearlyEqual(MathF.Round(modifiedSkillLevel), MathF.Round(skill.Level)))
{
int skillChange = (int)MathF.Round(modifiedSkillLevel - skill.Level);
string changeText = $"{(skillChange > 0 ? "+" : "") + skillChange}";
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), skillName.RectTransform), $"{(int)skill.Level} ({changeText})", textColor: textColor, font: font, textAlignment: Alignment.CenterRight);
}
else
{
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), skillName.RectTransform), ((int)skill.Level).ToString(), textColor: textColor, font: font, textAlignment: Alignment.CenterRight);
}
}
}
else if (Character != null && Character.IsDead)
@@ -330,6 +330,8 @@ namespace Barotrauma
GameMain.Client.HasSpawned = true;
GameMain.Client.Character = this;
GameMain.LightManager.LosEnabled = true;
GameMain.LightManager.LosAlpha = 1f;
GameMain.Client.WaitForNextRoundRespawn = null;
}
else
{
@@ -516,6 +518,7 @@ namespace Barotrauma
if (!character.IsDead) { Controlled = character; }
GameMain.LightManager.LosEnabled = true;
GameMain.LightManager.LosAlpha = 1f;
character.memInput.Clear();
character.memState.Clear();
@@ -997,8 +997,8 @@ namespace Barotrauma
cprButton.Visible =
Character == Character.Controlled?.SelectedCharacter
&& (Character.IsUnconscious || Character.Stun > 0.0f)
&& !Character.IsDead
&& Character.IsKnockedDown
&& openHealthWindow == this;
cprButton.IgnoreLayoutGroups = !cprButton.Visible;
cprButton.Selected =
@@ -1247,6 +1247,7 @@ namespace Barotrauma
GameMain.DebugDraw = false;
GameMain.LightManager.LightingEnabled = true;
GameMain.LightManager.LosEnabled = true;
GameMain.LightManager.LosAlpha = 1f;
}
NewMessage(HumanAIController.debugai ? "AI debug info visible" : "AI debug info hidden", Color.White);
});
@@ -14,10 +14,7 @@ namespace Barotrauma
base.State = value;
if (state == HostagesKilledState && !string.IsNullOrEmpty(hostagesKilledMessage))
{
new GUIMessageBox(string.Empty, hostagesKilledMessage, buttons: new string[0], type: GUIMessageBox.Type.InGame, icon: Prefab.Icon, parseRichText: true)
{
IconColor = Prefab.IconColor
};
CreateMessageBox(string.Empty, hostagesKilledMessage);
}
}
}
@@ -44,6 +41,15 @@ namespace Barotrauma
{
Item.ReadSpawnData(msg);
}
if (character.Submarine != null && character.AIController is EnemyAIController enemyAi)
{
enemyAi.UnattackableSubmarines.Add(character.Submarine);
enemyAi.UnattackableSubmarines.Add(Submarine.MainSub);
foreach (Submarine sub in Submarine.MainSub.DockedTo)
{
enemyAi.UnattackableSubmarines.Add(sub);
}
}
}
if (characters.Contains(null))
{
@@ -1,4 +1,5 @@
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -7,6 +8,19 @@ namespace Barotrauma
{
abstract partial class Mission
{
private readonly List<string> shownMessages = new List<string>();
public IEnumerable<string> ShownMessages
{
get { return shownMessages; }
}
public Color GetDifficultyColor()
{
int v = Difficulty ?? MissionPrefab.MinDifficulty;
float t = MathUtils.InverseLerp(MissionPrefab.MinDifficulty, MissionPrefab.MaxDifficulty, v);
return ToolBox.GradientLerp(t, GUI.Style.Green, GUI.Style.Orange, GUI.Style.Red);
}
public string GetMissionRewardText()
{
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", Reward));
@@ -71,6 +85,7 @@ namespace Barotrauma
protected void CreateMessageBox(string header, string message)
{
shownMessages.Add(message);
new GUIMessageBox(header, message, buttons: new string[0], type: GUIMessageBox.Type.InGame, icon: Prefab.Icon, parseRichText: true)
{
IconColor = Prefab.IconColor
@@ -1,7 +1,5 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Linq;
namespace Barotrauma
@@ -565,34 +565,26 @@ namespace Barotrauma
}
else
{
string guiScaleString = $"GUI.Scale: {Scale}";
string guixScaleString = $"GUI.xScale: {xScale}";
string guiyScaleString = $"GUI.yScale: {yScale}";
string relativeHorizontalAspectRatioString = $"RelativeHorizontalAspectRatio: {RelativeHorizontalAspectRatio}";
string relativeVerticalAspectRatioString = $"RelativeVerticalAspectRatio: {RelativeVerticalAspectRatio}";
Vector2 guiScaleStringSize = SmallFont.MeasureString(guiScaleString);
Vector2 guixScaleStringSize = SmallFont.MeasureString(guixScaleString);
Vector2 guiyScaleStringSize = SmallFont.MeasureString(guiyScaleString);
Vector2 relativeHorizontalAspectRatioStringSize = SmallFont.MeasureString(relativeHorizontalAspectRatioString);
Vector2 relativeVerticalAspectRatioStringSize = SmallFont.MeasureString(relativeVerticalAspectRatioString);
string[] strings = new string[]
{
$"GUI.Scale: {Scale}",
$"GUI.xScale: {xScale}",
$"GUI.yScale: {yScale}",
$"RelativeHorizontalAspectRatio: {RelativeHorizontalAspectRatio}",
$"RelativeVerticalAspectRatio: {RelativeVerticalAspectRatio}",
$"Cam.Zoom: {Screen.Selected.Cam?.Zoom ?? 0f}",
};
int padding = IntScale(10);
int yPos = padding;
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)guiScaleStringSize.X - padding, yPos), guiScaleString, Color.LightGreen, Color.Black, 0, SmallFont);
yPos += (int)guiScaleStringSize.Y + padding / 2;
foreach (string str in strings)
{
Vector2 stringSize = SmallFont.MeasureString(str);
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)guixScaleStringSize.X - padding, yPos), guixScaleString, Color.LightGreen, Color.Black, 0, SmallFont);
yPos += (int)guixScaleStringSize.Y + padding / 2;
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)guiyScaleStringSize.X - padding, yPos), guiyScaleString, Color.LightGreen, Color.Black, 0, SmallFont);
yPos += (int)guiyScaleStringSize.Y + padding / 2;
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)relativeHorizontalAspectRatioStringSize.X - padding, yPos), relativeHorizontalAspectRatioString, Color.LightGreen, Color.Black, 0, SmallFont);
yPos += (int)relativeHorizontalAspectRatioStringSize.Y + padding / 2;
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)relativeVerticalAspectRatioStringSize.X - padding, yPos), relativeVerticalAspectRatioString, Color.LightGreen, Color.Black, 0, SmallFont);
yPos += (int)relativeVerticalAspectRatioStringSize.Y + padding / 2;
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)stringSize.X - padding, yPos), str, Color.LightGreen, Color.Black, 0, SmallFont);
yPos += (int)stringSize.Y + padding / 2;
}
}
}
@@ -194,6 +194,8 @@ namespace Barotrauma
public bool ScrollBarEnabled { get; set; } = true;
public bool KeepSpaceForScrollBar { get; set; }
public bool CanTakeKeyBoardFocus { get; set; } = true;
public bool ScrollBarVisible
{
get
@@ -891,7 +893,7 @@ namespace Barotrauma
}
// If one of the children is the subscriber, we don't want to register, because it will unregister the child.
if (takeKeyBoardFocus && RectTransform.GetAllChildren().None(rt => rt.GUIComponent == GUI.KeyboardDispatcher.Subscriber))
if (takeKeyBoardFocus && CanTakeKeyBoardFocus && RectTransform.GetAllChildren().None(rt => rt.GUIComponent == GUI.KeyboardDispatcher.Subscriber))
{
Selected = true;
GUI.KeyboardDispatcher.Subscriber = this;
@@ -261,7 +261,7 @@ namespace Barotrauma
public readonly List<RichTextData> RichTextData = null;
private readonly bool hasColorHighlight = false;
public bool HasColorHighlight => RichTextData != null;
public struct ClickableArea
{
@@ -295,7 +295,6 @@ namespace Barotrauma
if (parseRichText)
{
RichTextData = Barotrauma.RichTextData.GetRichTextData(text, out text);
hasColorHighlight = RichTextData != null;
}
//if the text is in chinese/korean/japanese and we're not using a CJK-compatible font,
@@ -326,7 +325,6 @@ namespace Barotrauma
: this(rectT, text, textColor, font, textAlignment, wrap, style, color, playerInput)
{
this.RichTextData = richTextData;
hasColorHighlight = richTextData != null;
}
public void CalculateHeightFromText(int padding = 0, bool removeExtraSpacing = false)
@@ -634,7 +632,7 @@ namespace Barotrauma
currentTextColor = selectedTextColor;
}
if (!hasColorHighlight)
if (!HasColorHighlight)
{
string textToShow = Censor ? censoredText : (Wrap ? wrappedText : text);
Color colorToShow = currentTextColor * (currentTextColor.A / 255.0f);
@@ -94,7 +94,7 @@ namespace Barotrauma
}
}
private static Point maxPoint = new Point(int.MaxValue, int.MaxValue);
public readonly static Point MaxPoint = new Point(int.MaxValue, int.MaxValue);
private Point? maxSize;
/// <summary>
@@ -103,7 +103,7 @@ namespace Barotrauma
/// </summary>
public Point MaxSize
{
get { return maxSize ?? maxPoint; }
get { return maxSize ?? MaxPoint; }
set
{
if (maxSize == value) { return; }
@@ -18,7 +18,7 @@ namespace Barotrauma
private static UISprite spectateIcon, disconnectedIcon;
private static Sprite ownerIcon, moderatorIcon;
private enum InfoFrameTab { Crew, Mission, Reputation, MyCharacter, Traitor };
private enum InfoFrameTab { Crew, Mission, Reputation, MyCharacter, Traitor, Submarine };
private static InfoFrameTab selectedTab;
private GUIFrame infoFrame, contentFrame;
@@ -181,77 +181,79 @@ namespace Barotrauma
infoFrame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: null);
new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, infoFrame.RectTransform, Anchor.Center), style: "GUIBackgroundBlocker");
Vector2 contentFrameSize = selectedTab switch
//this used to be a switch expression but i changed it because it killed enc :(
Vector2 contentFrameSize;
switch (selectedTab)
{
InfoFrameTab.MyCharacter => new Vector2(0.33f, 0.5f),
_ => new Vector2(0.33f, 0.667f)
};
case InfoFrameTab.MyCharacter:
contentFrameSize = new Vector2(0.45f, 0.5f);
break;
default:
contentFrameSize = new Vector2(0.45f, 0.667f);
break;
}
contentFrame = new GUIFrame(new RectTransform(contentFrameSize, infoFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { RelativeOffset = new Vector2(0.025f, 0.12f) });
var innerLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.958f, 0.943f), contentFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { AbsoluteOffset = new Point(0, GUI.IntScale(17.5f)) })
{
RelativeSpacing = 0.01f,
Stretch = true
};
var buttonArea = new GUILayoutGroup(new RectTransform(new Point(innerLayoutGroup.Rect.Width, GUI.IntScale(25f)), parent: innerLayoutGroup.RectTransform), isHorizontal: true)
var horizontalLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.958f, 0.943f), contentFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { AbsoluteOffset = new Point(0, GUI.IntScale(25f)) }, isHorizontal: true)
{
RelativeSpacing = 0.01f
};
var buttonArea = new GUILayoutGroup(new RectTransform(new Vector2(0.07f, 1f), parent: horizontalLayoutGroup.RectTransform), isHorizontal: false)
{
AbsoluteSpacing = GUI.IntScale(5f)
};
var innerLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.92f, 1f), horizontalLayoutGroup.RectTransform))
{
RelativeSpacing = 0.01f,
Stretch = true
};
float absoluteSpacing = innerLayoutGroup.RelativeSpacing * innerLayoutGroup.Rect.Height;
int multiplier = GameMain.GameSession?.GameMode is CampaignMode ? 2 : 1;
int infoFrameHolderHeight = Math.Min((int)(0.926f * innerLayoutGroup.Rect.Height), (int)(innerLayoutGroup.Rect.Height - multiplier * (GUI.IntScale(25f) + absoluteSpacing)));
int infoFrameHolderHeight = Math.Min((int)(0.97f * innerLayoutGroup.Rect.Height), (int)(innerLayoutGroup.Rect.Height - multiplier * (GUI.IntScale(15f) + absoluteSpacing)));
infoFrameHolder = new GUIFrame(new RectTransform(new Point(innerLayoutGroup.Rect.Width, infoFrameHolderHeight), parent: innerLayoutGroup.RectTransform), style: null);
var crewButton = new GUIButton(new RectTransform(new Vector2(0.245f, 1.0f), buttonArea.RectTransform), TextManager.Get("Crew"), style: "GUITabButton")
GUIButton createTabButton(InfoFrameTab tab, string textTag)
{
UserData = InfoFrameTab.Crew,
OnClicked = SelectInfoFrameTab
};
tabButtons.Add(crewButton);
var newButton = new GUIButton(new RectTransform(Vector2.One, buttonArea.RectTransform, scaleBasis: ScaleBasis.BothWidth), style: $"InfoFrameTabButton.{tab}")
{
UserData = tab,
ToolTip = TextManager.Get(textTag),
OnClicked = SelectInfoFrameTab
};
tabButtons.Add(newButton);
return newButton;
}
var missionButton = new GUIButton(new RectTransform(new Vector2(0.245f, 1.0f), buttonArea.RectTransform), TextManager.Get("Mission"), style: "GUITabButton")
{
UserData = InfoFrameTab.Mission,
OnClicked = SelectInfoFrameTab
};
tabButtons.Add(missionButton);
var crewButton = createTabButton(InfoFrameTab.Crew, "crew");
var missionButton = createTabButton(InfoFrameTab.Mission, "mission");
if (GameMain.GameSession?.GameMode is CampaignMode campaignMode)
{
var reputationButton = new GUIButton(new RectTransform(new Vector2(0.245f, 1.0f), buttonArea.RectTransform), TextManager.Get("reputation"), style: "GUITabButton")
{
UserData = InfoFrameTab.Reputation,
OnClicked = SelectInfoFrameTab
};
tabButtons.Add(reputationButton);
var reputationButton = createTabButton(InfoFrameTab.Reputation, "reputation");
var balanceFrame = new GUIFrame(new RectTransform(new Point(buttonArea.RectTransform.NonScaledSize.X, (int)(buttonArea.RectTransform.NonScaledSize.Y * 1.5f)), parent: innerLayoutGroup.RectTransform), style: "InnerFrame");
var submarineButton = createTabButton(InfoFrameTab.Submarine, "submarine");
var balanceFrame = new GUIFrame(new RectTransform(new Point(innerLayoutGroup.Rect.Width, innerLayoutGroup.Rect.Height - infoFrameHolderHeight), parent: innerLayoutGroup.RectTransform), style: "InnerFrame");
new GUITextBlock(new RectTransform(Vector2.One, balanceFrame.RectTransform), "", textAlignment: Alignment.Right, parseRichText: true)
{
TextGetter = () => TextManager.GetWithVariable("campaignmoney", "[money]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", campaignMode.Money))
};
}
bool isTraitor = GameMain.Client?.Character?.IsTraitor ?? false;
if (isTraitor && GameMain.Client.TraitorMission != null)
else
{
var traitorButton = new GUIButton(new RectTransform(new Vector2(0.245f, 1.0f), buttonArea.RectTransform), TextManager.Get("tabmenu.traitor"), style: "GUITabButton")
bool isTraitor = GameMain.Client?.Character?.IsTraitor ?? false;
if (isTraitor && GameMain.Client.TraitorMission != null)
{
UserData = InfoFrameTab.Traitor,
OnClicked = SelectInfoFrameTab
};
tabButtons.Add(traitorButton);
var traitorButton = createTabButton(InfoFrameTab.Traitor, "tabmenu.traitor");
}
}
if (GameMain.NetworkMember != null)
{
var myCharacterButton = new GUIButton(new RectTransform(new Vector2(0.245f, 1.0f), buttonArea.RectTransform), TextManager.Get("tabmenu.character"), style: "GUITabButton")
{
UserData = InfoFrameTab.MyCharacter,
OnClicked = SelectInfoFrameTab
};
tabButtons.Add(myCharacterButton);
var myCharacterButton = createTabButton(InfoFrameTab.MyCharacter, "tabmenu.character");
}
}
@@ -288,6 +290,9 @@ namespace Barotrauma
if (GameMain.NetworkMember == null) { return false; }
GameMain.NetLobbyScreen.CreatePlayerFrame(infoFrameHolder);
break;
case InfoFrameTab.Submarine:
CreateSubmarineInfo(infoFrameHolder, Submarine.MainSub);
break;
}
return true;
@@ -879,13 +884,16 @@ namespace Barotrauma
UserData = line
};
textBlock.CalculateHeightFromText();
foreach (var data in textBlock.RichTextData)
if (textBlock.HasColorHighlight)
{
textBlock.ClickableAreas.Add(new GUITextBlock.ClickableArea()
foreach (var data in textBlock.RichTextData)
{
Data = data,
OnClick = GameMain.NetLobbyScreen.SelectPlayer
});
textBlock.ClickableAreas.Add(new GUITextBlock.ClickableArea()
{
Data = data,
OnClick = GameMain.NetLobbyScreen.SelectPlayer
});
}
}
}
}
@@ -930,27 +938,38 @@ namespace Barotrauma
foreach (Mission mission in GameMain.GameSession.Missions)
{
GUIFrame missionDescriptionHolder = new GUIFrame(new RectTransform(Vector2.One, missionList.Content.RectTransform), style: null);
GUILayoutGroup missionTextGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.744f, 0f), missionDescriptionHolder.RectTransform, Anchor.CenterLeft) { RelativeOffset = new Vector2(0.225f, 0f) }, false, childAnchor: Anchor.TopLeft);
GUILayoutGroup missionTextGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.744f, 0f), missionDescriptionHolder.RectTransform, Anchor.CenterLeft) { RelativeOffset = new Vector2(0.225f, 0f) }, false, childAnchor: Anchor.TopLeft)
{
AbsoluteSpacing = GUI.IntScale(5)
};
string descriptionText = mission.Description;
foreach (string missionMessage in mission.ShownMessages)
{
descriptionText += "\n\n" + missionMessage;
}
string rewardText = mission.GetMissionRewardText();
string reputationText = mission.GetReputationRewardText(mission.Locations[0]);
var missionNameRichTextData = RichTextData.GetRichTextData(mission.Name, out string missionNameString);
var missionDescriptionRichTextData = RichTextData.GetRichTextData(mission.Description, out string missionDescriptionString);
var missionRewardRichTextData = RichTextData.GetRichTextData(rewardText, out string missionRewardString);
var missionReputationRichTextData = RichTextData.GetRichTextData(reputationText, out string missionReputationString);
var missionDescriptionRichTextData = RichTextData.GetRichTextData(descriptionText, out string missionDescriptionString);
missionNameString = ToolBox.WrapText(missionNameString, missionTextGroup.Rect.Width, GUI.LargeFont);
missionDescriptionString = ToolBox.WrapText(missionDescriptionString, missionTextGroup.Rect.Width, GUI.Font);
missionRewardString = ToolBox.WrapText(missionRewardString, missionTextGroup.Rect.Width, GUI.Font);
missionReputationString = ToolBox.WrapText(missionReputationString, missionTextGroup.Rect.Width, GUI.Font);
missionDescriptionString = ToolBox.WrapText(missionDescriptionString, missionTextGroup.Rect.Width, GUI.Font);
Vector2 missionNameSize = GUI.LargeFont.MeasureString(missionNameString);
Vector2 missionDescriptionSize = GUI.Font.MeasureString(missionDescriptionString);
Vector2 missionRewardSize = GUI.Font.MeasureString(missionRewardString);
Vector2 missionReputationSize = GUI.Font.MeasureString(missionReputationString);
missionDescriptionHolder.RectTransform.NonScaledSize = new Point(missionDescriptionHolder.RectTransform.NonScaledSize.X, (int)(missionNameSize.Y + missionDescriptionSize.Y + missionRewardSize.Y + missionReputationSize.Y));
float ySize = missionNameSize.Y + missionDescriptionSize.Y + missionRewardSize.Y + missionReputationSize.Y + missionTextGroup.AbsoluteSpacing * 4;
bool displayDifficulty = mission.Difficulty.HasValue;
if (displayDifficulty) { ySize += missionRewardSize.Y; }
missionDescriptionHolder.RectTransform.NonScaledSize = new Point(missionDescriptionHolder.RectTransform.NonScaledSize.X, (int)ySize);
missionTextGroup.RectTransform.NonScaledSize = new Point(missionTextGroup.RectTransform.NonScaledSize.X, missionDescriptionHolder.RectTransform.NonScaledSize.Y);
if (mission.Prefab.Icon != null)
@@ -960,10 +979,38 @@ namespace Barotrauma
int iconHeight = Math.Max(missionTextGroup.RectTransform.NonScaledSize.Y, (int)(iconWidth * iconAspectRatio));
Point iconSize = new Point(iconWidth, iconHeight);
new GUIImage(new RectTransform(iconSize, missionDescriptionHolder.RectTransform), mission.Prefab.Icon, null, true) { Color = mission.Prefab.IconColor, CanBeFocused = false };
new GUIImage(new RectTransform(iconSize, missionDescriptionHolder.RectTransform), mission.Prefab.Icon, null, true)
{
Color = mission.Prefab.IconColor,
HoverColor = mission.Prefab.IconColor,
SelectedColor = mission.Prefab.IconColor,
CanBeFocused = false
};
}
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionNameRichTextData, missionNameString, font: GUI.LargeFont);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionRewardRichTextData, missionRewardString);
GUILayoutGroup difficultyIndicatorGroup = null;
if (displayDifficulty)
{
difficultyIndicatorGroup = new GUILayoutGroup(new RectTransform(new Point(missionTextGroup.Rect.Width, (int)missionRewardSize.Y), parent: missionTextGroup.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft)
{
AbsoluteSpacing = 1
};
var difficultyColor = mission.GetDifficultyColor();
for (int i = 0; i < mission.Difficulty.Value; i++)
{
new GUIImage(new RectTransform(Vector2.One, difficultyIndicatorGroup.RectTransform, scaleBasis: ScaleBasis.Smallest), "DifficultyIndicator", scaleToFit: true)
{
CanBeFocused = false,
Color = difficultyColor
};
}
}
var rewardTextBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionRewardRichTextData, missionRewardString);
if (difficultyIndicatorGroup != null)
{
difficultyIndicatorGroup.RectTransform.Resize(new Point((int)(difficultyIndicatorGroup.Rect.Width - rewardTextBlock.Padding.X - rewardTextBlock.Padding.Z), difficultyIndicatorGroup.Rect.Height));
difficultyIndicatorGroup.RectTransform.AbsoluteOffset = new Point((int)rewardTextBlock.Padding.X, 0);
}
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionReputationRichTextData, missionReputationString);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionDescriptionRichTextData, missionDescriptionString);
}
@@ -1004,5 +1051,84 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionNameString, font: GUI.LargeFont);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionDescriptionString);
}
private void CreateSubmarineInfo(GUIFrame infoFrame, Submarine sub)
{
GUIFrame subInfoFrame = new GUIFrame(new RectTransform(Vector2.One, infoFrame.RectTransform, Anchor.TopCenter), style: "GUIFrameListBox");
GUIFrame paddedFrame = new GUIFrame(new RectTransform(Vector2.One * 0.97f, subInfoFrame.RectTransform, Anchor.Center), style: null);
var previewButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.43f), paddedFrame.RectTransform), style: null)
{
OnClicked = (btn, obj) => { SubmarinePreview.Create(sub.Info); return false; },
};
var previewImage = sub.Info.PreviewImage ?? SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name.Equals(sub.Info.Name, StringComparison.OrdinalIgnoreCase))?.PreviewImage;
if (previewImage == null)
{
new GUITextBlock(new RectTransform(Vector2.One, previewButton.RectTransform), TextManager.Get("SubPreviewImageNotFound"));
}
else
{
var submarinePreviewBackground = new GUIFrame(new RectTransform(Vector2.One, previewButton.RectTransform), style: null)
{
Color = Color.Black,
HoverColor = Color.Black,
SelectedColor = Color.Black,
PressedColor = Color.Black,
CanBeFocused = false,
};
new GUIImage(new RectTransform(new Vector2(0.98f), submarinePreviewBackground.RectTransform, Anchor.Center), previewImage, scaleToFit: true) { CanBeFocused = false };
new GUIFrame(new RectTransform(Vector2.One, submarinePreviewBackground.RectTransform), "InnerGlow", color: Color.Black) { CanBeFocused = false };
}
new GUIFrame(new RectTransform(Vector2.One * 0.12f, previewButton.RectTransform, anchor: Anchor.BottomRight, pivot: Pivot.BottomRight, scaleBasis: ScaleBasis.BothHeight)
{
AbsoluteOffset = new Point((int)(0.03f * previewButton.Rect.Height))
},
"ExpandButton", Color.White)
{
Color = Color.White,
HoverColor = Color.White,
PressedColor = Color.White
};
var subInfoTextLayout = new GUILayoutGroup(new RectTransform(Vector2.One, paddedFrame.RectTransform));
string className = !sub.Info.HasTag(SubmarineTag.Shuttle) ? TextManager.Get($"submarineclass.{sub.Info.SubmarineClass}") : TextManager.Get("shuttle");
int nameHeight = (int)GUI.LargeFont.MeasureString(sub.Info.DisplayName, true).Y;
int classHeight = (int)GUI.SubHeadingFont.MeasureString(className).Y;
var submarineNameText = new GUITextBlock(new RectTransform(new Point(subInfoTextLayout.Rect.Width, nameHeight + HUDLayoutSettings.Padding / 2), subInfoTextLayout.RectTransform), sub.Info.DisplayName, textAlignment: Alignment.CenterLeft, font: GUI.LargeFont) { CanBeFocused = false };
submarineNameText.RectTransform.MinSize = new Point(0, (int)submarineNameText.TextSize.Y);
var submarineClassText = new GUITextBlock(new RectTransform(new Point(subInfoTextLayout.Rect.Width, classHeight), subInfoTextLayout.RectTransform), className, textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont) { CanBeFocused = false };
submarineClassText.RectTransform.MinSize = new Point(0, (int)submarineClassText.TextSize.Y);
if (GameMain.GameSession?.GameMode is CampaignMode campaign)
{
var upgradeRootLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.57f), paddedFrame.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft), true);
var upgradeCategoryPanel = UpgradeStore.CreateUpgradeCategoryList(new RectTransform(new Vector2(0.4f, 1f), upgradeRootLayout.RectTransform));
upgradeCategoryPanel.HideChildrenOutsideFrame = true;
UpgradeStore.UpdateCategoryList(upgradeCategoryPanel, campaign, sub, UpgradeStore.GetApplicableCategories(sub).ToArray());
GUIComponent[] toRemove = upgradeCategoryPanel.Content.FindChildren(c => !c.Enabled).ToArray();
toRemove.ForEach(c => upgradeCategoryPanel.RemoveChild(c));
var upgradePanel = new GUIListBox(new RectTransform(new Vector2(0.6f, 1f), upgradeRootLayout.RectTransform));
upgradeCategoryPanel.OnSelected = (component, userData) =>
{
upgradePanel.ClearChildren();
if (userData is UpgradeStore.CategoryData categoryData && Submarine.MainSub != null)
{
foreach (UpgradePrefab prefab in categoryData.Prefabs)
{
var frame = UpgradeStore.CreateUpgradeFrame(prefab, categoryData.Category, campaign, new RectTransform(new Vector2(1f, 0.3f), upgradePanel.Content.RectTransform), addBuyButton: false);
UpgradeStore.UpdateUpgradeEntry(frame, prefab, categoryData.Category, campaign);
}
}
return true;
};
}
}
}
}
@@ -15,7 +15,7 @@ namespace Barotrauma
internal class UpgradeStore
{
private readonly struct CategoryData
public readonly struct CategoryData
{
public readonly UpgradeCategory Category;
public readonly List<UpgradePrefab> Prefabs;
@@ -125,7 +125,7 @@ namespace Barotrauma
{
if (component.UserData is CategoryData data)
{
UpdateUpgradeEntry(component, data.SinglePrefab, data.Category);
UpdateUpgradeEntry(component, data.SinglePrefab, data.Category, Campaign);
}
}
}
@@ -133,29 +133,35 @@ namespace Barotrauma
// update the small indicator icons on the list
if (currentStoreLayout?.Parent != null)
{
foreach (GUIComponent component in currentStoreLayout.Content.Children)
{
if (!(component.UserData is CategoryData data)) { continue; }
if (component.FindChild("indicators", true) is { } indicators)
{
UpdateCategoryIndicators(indicators, component, data.Prefabs, data.Category);
}
}
UpdateCategoryList(currentStoreLayout, Campaign, drawnSubmarine, applicableCategories);
}
}
// reset the order first
foreach (UpgradeCategory category in UpgradeCategory.Categories)
//TODO: move this somewhere else
public static void UpdateCategoryList(GUIListBox categoryList, CampaignMode campaign, Submarine drawnSubmarine, IEnumerable<UpgradeCategory> applicableCategories)
{
foreach (GUIComponent component in categoryList.Content.Children)
{
if (!(component.UserData is CategoryData data)) { continue; }
if (component.FindChild("indicators", true) is { } indicators)
{
GUIComponent component = currentStoreLayout.Content.FindChild(c => c.UserData is CategoryData categoryData && categoryData.Category == category);
component?.SetAsLastChild();
UpdateCategoryIndicators(indicators, component, data.Prefabs, data.Category, campaign, drawnSubmarine, applicableCategories);
}
}
// send the disabled components to the bottom
List<GUIComponent> lastChilds = currentStoreLayout.Content.Children.Where(component => !component.Enabled).ToList();
// reset the order first
foreach (UpgradeCategory category in UpgradeCategory.Categories)
{
GUIComponent component = categoryList.Content.FindChild(c => c.UserData is CategoryData categoryData && categoryData.Category == category);
component?.SetAsLastChild();
}
foreach (var lastChild in lastChilds)
{
lastChild.SetAsLastChild();
}
// send the disabled components to the bottom
List<GUIComponent> lastChilds = categoryList.Content.Children.Where(component => !component.Enabled).ToList();
foreach (var lastChild in lastChilds)
{
lastChild.SetAsLastChild();
}
}
@@ -511,9 +517,10 @@ namespace Barotrauma
}
}
private void CreateUpgradeTab()
//TODO: put this somewhere else
public static GUIListBox CreateUpgradeCategoryList(RectTransform rectTransform)
{
currentStoreLayout = new GUIListBox(rectT(1.0f, 1.5f, storeLayout), style: null)
var upgradeCategoryList = new GUIListBox(rectTransform, style: null)
{
AutoHideScrollBar = false,
ScrollBarVisible = false,
@@ -548,7 +555,7 @@ namespace Barotrauma
foreach (var (category, prefabs) in upgrades)
{
var frameChild = new GUIFrame(rectT(1, 0.15f, currentStoreLayout.Content), style: "UpgradeUIFrame")
var frameChild = new GUIFrame(rectT(1, 0.15f, upgradeCategoryList.Content), style: "UpgradeUIFrame")
{
UserData = new CategoryData(category, prefabs),
GlowOnSelect = true
@@ -565,9 +572,9 @@ namespace Barotrauma
* |-----------------------------|--------------------------|
*/
GUILayoutGroup contentLayout = new GUILayoutGroup(rectT(0.9f, 0.85f, frameChild, Anchor.Center));
var itemCategoryLabel = new GUITextBlock(rectT(1, 1, contentLayout), category.Name, font: GUI.SubHeadingFont) { CanBeFocused = false };
GUILayoutGroup indicatorLayout = new GUILayoutGroup(rectT(0.5f, 0.25f, contentLayout, Anchor.BottomRight), isHorizontal: true, childAnchor: Anchor.TopRight) { UserData = "indicators", IgnoreLayoutGroups = true, RelativeSpacing = 0.01f };
var itemCategoryLabel = new GUITextBlock(rectT(1, 1, contentLayout), category.Name, font: GUI.SubHeadingFont) { CanBeFocused = false };
GUILayoutGroup indicatorLayout = new GUILayoutGroup(rectT(0.5f, 0.25f, contentLayout, Anchor.BottomRight), isHorizontal: true, childAnchor: Anchor.TopRight) { UserData = "indicators", IgnoreLayoutGroups = true, RelativeSpacing = 0.01f };
foreach (var prefab in prefabs)
{
GUIImage upgradeIndicator = new GUIImage(rectT(0.1f, 1f, indicatorLayout), style: "UpgradeIndicator", scaleToFit: true) { UserData = prefab, CanBeFocused = false };
@@ -582,6 +589,13 @@ namespace Barotrauma
indicatorLayout.Recalculate();
}
return upgradeCategoryList;
}
private void CreateUpgradeTab()
{
currentStoreLayout = CreateUpgradeCategoryList(rectT(1.0f, 1.5f, storeLayout));
selectedUpgradeCategoryLayout = new GUIFrame(rectT(GUI.IsFourByThree() ? 0.3f : 0.25f, 1, mainStoreLayout), style: null) { CanBeFocused = false };
RefreshUpgradeList();
@@ -637,7 +651,7 @@ namespace Barotrauma
}
}
private void CreateUpgradeEntry(UpgradePrefab prefab, UpgradeCategory category, GUIComponent parent, List<Item> itemsOnSubmarine)
public static GUIFrame CreateUpgradeFrame(UpgradePrefab prefab, UpgradeCategory category, CampaignMode campaign, RectTransform rectTransform, bool addBuyButton = true)
{
/* UPGRADE PREFAB ENTRY
* |------------------------------------------------------------------|
@@ -648,8 +662,8 @@ namespace Barotrauma
* | | progress bar | x / y | |
* |------------------------------------------------------------------|
*/
GUIFrame prefabFrame = new GUIFrame(rectT(1f, 0.25f, parent), style: "ListBoxElement") { SelectedColor = Color.Transparent, UserData = new CategoryData(category, prefab) };
GUILayoutGroup prefabLayout = new GUILayoutGroup(rectT(0.98f,0.95f, prefabFrame, Anchor.Center), isHorizontal: true);
GUIFrame prefabFrame = new GUIFrame(rectTransform, style: "ListBoxElement") { SelectedColor = Color.Transparent, UserData = new CategoryData(category, prefab) };
GUILayoutGroup prefabLayout = new GUILayoutGroup(rectT(0.98f, 0.95f, prefabFrame, Anchor.Center), isHorizontal: true) { Stretch = true };
GUILayoutGroup imageLayout = new GUILayoutGroup(rectT(new Point(prefabLayout.Rect.Height, prefabLayout.Rect.Height), prefabLayout), childAnchor: Anchor.Center);
var icon = new GUIImage(rectT(0.9f, 0.9f, imageLayout), prefab.Sprite, scaleToFit: true) { CanBeFocused = false };
GUILayoutGroup textLayout = new GUILayoutGroup(rectT(0.8f - imageLayout.RectTransform.RelativeSize.X, 1, prefabLayout));
@@ -659,9 +673,13 @@ namespace Barotrauma
GUILayoutGroup progressLayout = new GUILayoutGroup(rectT(1, 0.25f, textLayout), isHorizontal: true, childAnchor: Anchor.CenterLeft) { UserData = "progressbar" };
new GUIProgressBar(rectT(0.8f, 0.75f, progressLayout), 0.0f, GUI.Style.Orange);
new GUITextBlock(rectT(0.2f, 1, progressLayout), string.Empty, font: GUI.SmallFont, textAlignment: Alignment.Center) { Padding = Vector4.Zero };
GUILayoutGroup buyButtonLayout = new GUILayoutGroup(rectT(0.2f, 1, prefabLayout), childAnchor: Anchor.TopCenter) { UserData = "buybutton" };
new GUITextBlock(rectT(1, 0.4f, buyButtonLayout), FormatCurrency(prefab.Price.GetBuyprice(Campaign.UpgradeManager.GetUpgradeLevel(prefab, category), Campaign.Map?.CurrentLocation)), textAlignment: Alignment.Center) { Padding = Vector4.Zero };
GUILayoutGroup buyButtonLayout = null;
if (addBuyButton)
{
buyButtonLayout = new GUILayoutGroup(rectT(0.2f, 1, prefabLayout), childAnchor: Anchor.TopCenter) { UserData = "buybutton" };
new GUITextBlock(rectT(1, 0.4f, buyButtonLayout), FormatCurrency(prefab.Price.GetBuyprice(campaign.UpgradeManager.GetUpgradeLevel(prefab, category), campaign.Map?.CurrentLocation)), textAlignment: Alignment.Center) { Padding = Vector4.Zero };
var buyButton = new GUIButton(rectT(0.7f, 0.5f, buyButtonLayout), string.Empty, style: "UpgradeBuyButton") { Enabled = false };
}
description.CalculateHeightFromText();
// cut the description if it overflows and add a tooltip to it
@@ -677,14 +695,33 @@ namespace Barotrauma
}
// Recalculate everything to prevent jumping
if (parent is GUILayoutGroup group) { group.Recalculate(); }
if (rectTransform.Parent.GUIComponent is GUILayoutGroup group) { group.Recalculate(); }
descriptionLayout.Recalculate();
prefabLayout.Recalculate();
imageLayout.Recalculate();
textLayout.Recalculate();
progressLayout.Recalculate();
buyButtonLayout.Recalculate();
buyButtonLayout?.Recalculate();
return prefabFrame;
}
private void CreateUpgradeEntry(UpgradePrefab prefab, UpgradeCategory category, GUIComponent parent, List<Item> itemsOnSubmarine)
{
GUIFrame prefabFrame = CreateUpgradeFrame(prefab, category, Campaign, rectT(1f, 0.25f, parent));
var prefabLayout = prefabFrame.GetChild<GUILayoutGroup>();
GUILayoutGroup[] childLayouts = prefabLayout.GetAllChildren<GUILayoutGroup>().ToArray();
var imageLayout = childLayouts[0];
var icon = imageLayout.GetChild<GUIImage>();
var textLayout = childLayouts[1];
var name = textLayout.GetChild<GUITextBlock>();
GUILayoutGroup[] textChildLayouts = textLayout.GetAllChildren<GUILayoutGroup>().ToArray();
var descriptionLayout = textChildLayouts[0];
var description = descriptionLayout.GetChild<GUITextBlock>();
var progressLayout = textChildLayouts[1];
var buyButtonLayout = childLayouts[2];
var buyButton = buyButtonLayout.GetChild<GUIButton>();
if (!HasPermission || itemsOnSubmarine != null && !itemsOnSubmarine.Any(it => category.CanBeApplied(it, prefab)))
{
@@ -713,7 +750,7 @@ namespace Barotrauma
return true;
};
UpdateUpgradeEntry(prefabFrame, prefab, category);
UpdateUpgradeEntry(prefabFrame, prefab, category, Campaign);
}
private void CreateItemTooltip(MapEntity entity)
@@ -778,6 +815,18 @@ namespace Barotrauma
static string CreateListEntry(string name, int level) => TextManager.GetWithVariables("upgradeuitooltip.upgradelistelement", new[] { "[upgradename]", "[level]" }, new[] { name, $"{level}" });
}
public static IEnumerable<UpgradeCategory> GetApplicableCategories(Submarine drawnSubmarine)
{
Item[] entitiesOnSub = drawnSubmarine.GetItems(true).Where(i => drawnSubmarine.IsEntityFoundOnThisSub(i, true)).ToArray();
foreach (UpgradeCategory category in UpgradeCategory.Categories)
{
if (entitiesOnSub.Any(item => category.CanBeApplied(item, null)))
{
yield return category;
}
}
}
private void UpdateSubmarinePreview(float deltaTime, GUICustomComponent parent)
{
if (!parent.Children.Any() || Submarine.MainSub != null && Submarine.MainSub != drawnSubmarine || GameMain.GraphicsWidth != screenResolution.X || GameMain.GraphicsHeight != screenResolution.Y)
@@ -789,16 +838,8 @@ namespace Barotrauma
CreateSubmarinePreview(drawnSubmarine, parent);
CreateHullBorderVerticies(drawnSubmarine, parent);
List<Item> entitiesOnSub = drawnSubmarine.GetItems(true).Where(i => drawnSubmarine.IsEntityFoundOnThisSub(i, true)).ToList();
applicableCategories.Clear();
foreach (UpgradeCategory category in UpgradeCategory.Categories)
{
if (entitiesOnSub.Any(item => category.CanBeApplied(item, null)))
{
applicableCategories.Add(category);
}
}
applicableCategories.AddRange(GetApplicableCategories(drawnSubmarine));
}
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
@@ -1002,9 +1043,9 @@ namespace Barotrauma
}
}
private void UpdateUpgradeEntry(GUIComponent prefabFrame, UpgradePrefab prefab, UpgradeCategory category)
public static void UpdateUpgradeEntry(GUIComponent prefabFrame, UpgradePrefab prefab, UpgradeCategory category, CampaignMode campaign)
{
int currentLevel = Campaign.UpgradeManager.GetUpgradeLevel(prefab, category);
int currentLevel = campaign.UpgradeManager.GetUpgradeLevel(prefab, category);
string progressText = TextManager.GetWithVariables("upgrades.progressformat", new[] { "[level]", "[maxlevel]" }, new[] { currentLevel.ToString(), prefab.MaxLevel.ToString() });
if (prefabFrame.FindChild("progressbar", true) is { } progressParent)
@@ -1023,7 +1064,7 @@ namespace Barotrauma
if (prefabFrame.FindChild("buybutton", true) is { } buttonParent)
{
GUITextBlock priceLabel = buttonParent.GetChild<GUITextBlock>();
int price = prefab.Price.GetBuyprice(Campaign.UpgradeManager.GetUpgradeLevel(prefab, category), Campaign.Map?.CurrentLocation);
int price = prefab.Price.GetBuyprice(campaign.UpgradeManager.GetUpgradeLevel(prefab, category), campaign.Map?.CurrentLocation);
if (priceLabel != null && !WaitForServerUpdate)
{
@@ -1038,7 +1079,7 @@ namespace Barotrauma
if (button != null)
{
button.Enabled = currentLevel < prefab.MaxLevel;
if (WaitForServerUpdate || !HasPermission || price > Campaign.Money)
if (WaitForServerUpdate || !campaign.AllowedToManageCampaign() || price > campaign.Money)
{
button.Enabled = false;
}
@@ -1046,7 +1087,14 @@ namespace Barotrauma
}
}
private void UpdateCategoryIndicators(GUIComponent indicators, GUIComponent parent, List<UpgradePrefab> prefabs, UpgradeCategory category)
private static void UpdateCategoryIndicators(
GUIComponent indicators,
GUIComponent parent,
List<UpgradePrefab> prefabs,
UpgradeCategory category,
CampaignMode campaign,
Submarine drawnSubmarine,
IEnumerable<UpgradeCategory> applicableCategories)
{
// Disables the parent and only re-enables if the submarine contains valid items
if (!category.IsWallUpgrade && drawnSubmarine != null)
@@ -1078,13 +1126,13 @@ namespace Barotrauma
GUIComponentStyle dimStyle = styles["upgradeindicatordim"];
GUIComponentStyle offStyle = styles["upgradeindicatoroff"];
if (Campaign.UpgradeManager.GetUpgradeLevel(prefab, category) >= prefab.MaxLevel)
if (campaign.UpgradeManager.GetUpgradeLevel(prefab, category) >= prefab.MaxLevel)
{
// we check this to avoid flickering from re-applying the same style
if (image.Style == onStyle) { continue; }
image.ApplyStyle(onStyle);
}
else if (Campaign.UpgradeManager.GetUpgradeLevel(prefab, category) > 0)
else if (campaign.UpgradeManager.GetUpgradeLevel(prefab, category) > 0)
{
if (image.Style == dimStyle) { continue; }
image.ApplyStyle(dimStyle);
@@ -1229,13 +1229,19 @@ namespace Barotrauma
base.OnExiting(sender, args);
}
public void ShowOpenUrlInWebBrowserPrompt(string url)
public void ShowOpenUrlInWebBrowserPrompt(string url, string promptExtensionTag = null)
{
if (string.IsNullOrEmpty(url)) { return; }
if (GUIMessageBox.VisibleBox?.UserData as string == "verificationprompt") { return; }
var msgBox = new GUIMessageBox("", TextManager.GetWithVariable("openlinkinbrowserprompt", "[link]", url),
new string[] { TextManager.Get("Yes"), TextManager.Get("No") })
string text = TextManager.GetWithVariable("openlinkinbrowserprompt", "[link]", url);
string extensionText = TextManager.Get(promptExtensionTag, returnNull: true, useEnglishAsFallBack: false);
if (!string.IsNullOrEmpty(extensionText))
{
text += $"\n\n{extensionText}";
}
var msgBox = new GUIMessageBox("", text, new string[] { TextManager.Get("Yes"), TextManager.Get("No") })
{
UserData = "verificationprompt"
};
@@ -168,6 +168,7 @@ namespace Barotrauma
{
chatBox.ToggleButton = new GUIButton(new RectTransform(new Point((int)(182f * GUI.Scale * 0.4f), (int)(99f * GUI.Scale * 0.4f)), chatBox.GUIFrame.Parent.RectTransform), style: "ChatToggleButton")
{
ToolTip = TextManager.Get("chat"),
ClampMouseRectToParent = false
};
chatBox.ToggleButton.RectTransform.AbsoluteOffset = new Point(0, HUDLayoutSettings.ChatBoxArea.Height - chatBox.ToggleButton.Rect.Height);
@@ -289,19 +290,7 @@ namespace Barotrauma
new RectTransform(crewListEntrySize, parent: crewList.Content.RectTransform, anchor: Anchor.TopRight),
style: "CrewListBackground")
{
UserData = character,
OnSecondaryClicked = (comp, data) =>
{
if (data == null) { return false; }
var client = GameMain.NetworkMember?.ConnectedClients?.Find(c => c.Character == data);
if (client != null)
{
CreateModerationContextMenu(PlayerInput.MousePosition.ToPoint(), client);
return true;
}
return false;
}
UserData = character
};
var iconRelativeWidth = (float)crewListEntrySize.Y / background.Rect.Width;
@@ -379,7 +368,17 @@ namespace Barotrauma
background.RectTransform),
style: null)
{
UserData = character
UserData = character,
OnSecondaryClicked = (comp, data) =>
{
if (data == null) { return false; }
if (GameMain.NetworkMember?.ConnectedClients?.Find(c => c.Character == data) is Client client)
{
CreateModerationContextMenu(PlayerInput.MousePosition.ToPoint(), client);
return true;
}
return false;
}
};
SetCharacterButtonTooltip(characterButton);
@@ -389,7 +388,6 @@ namespace Barotrauma
}
else
{
characterButton.CanBeFocused = false;
characterButton.CanBeSelected = false;
}
@@ -1089,7 +1087,8 @@ namespace Barotrauma
public void CreateModerationContextMenu(Point mousePos, Client client)
{
if (GUIContextMenu.CurrentContextMenu != null) { return; }
if (IsSinglePlayer || client == null || (!GameMain.Client?.PreviouslyConnectedClients?.Contains(client) ?? true)) { return; }
if (IsSinglePlayer || client == null || ((!GameMain.Client?.PreviouslyConnectedClients?.Contains(client)) ?? true)) { return; }
bool hasSteam = client.SteamID > 0 && SteamManager.IsInitialized,
canKick = GameMain.Client.HasPermission(ClientPermissions.Kick),
@@ -1638,7 +1637,8 @@ namespace Barotrauma
#if DEBUG
if (Character.Controlled == null) { return true; }
#endif
return Character.Controlled != null && characters.Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled));
return Character.Controlled != null &&
(characters.Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled)) || GetOrderableFriendlyNPCs().Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled)));
}
private Entity FindEntityContext()
@@ -124,22 +124,22 @@ namespace Barotrauma
{
var backgroundSprite = GUI.Style.GetComponentStyle("CommandBackground").GetDefaultSprite();
Vector2 centerPos = new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight) / 2;
string wrappedText = ToolBox.WrapText(overlayText, GameMain.GraphicsWidth / 3, GUI.Font);
Vector2 textSize = GUI.Font.MeasureString(wrappedText);
Vector2 textPos = centerPos - textSize / 2;
backgroundSprite.Draw(spriteBatch,
centerPos,
Color.White * (overlayTextColor.A / 255.0f),
origin: backgroundSprite.size / 2,
rotate: 0.0f,
scale: new Vector2(1.5f, 0.7f) * (GameMain.GraphicsWidth / 3 / backgroundSprite.size.X));
scale: new Vector2(GameMain.GraphicsWidth / 2 / backgroundSprite.size.X, textSize.Y / backgroundSprite.size.Y * 1.5f));
string wrappedText = ToolBox.WrapText(overlayText, GameMain.GraphicsWidth / 3, GUI.Font);
Vector2 textSize = GUI.Font.MeasureString(wrappedText);
Vector2 textPos = centerPos - textSize / 2;
GUI.DrawString(spriteBatch, textPos + Vector2.One, wrappedText, Color.Black * (overlayTextColor.A / 255.0f));
GUI.DrawString(spriteBatch, textPos, wrappedText, overlayTextColor);
if (!string.IsNullOrEmpty(overlayTextBottom))
{
Vector2 bottomTextPos = centerPos + new Vector2(0.0f, textSize.Y + 30 * GUI.Scale) - GUI.Font.MeasureString(overlayTextBottom) / 2;
Vector2 bottomTextPos = centerPos + new Vector2(0.0f, textSize.Y / 2 + 40 * GUI.Scale) - GUI.Font.MeasureString(overlayTextBottom) / 2;
GUI.DrawString(spriteBatch, bottomTextPos + Vector2.One, overlayTextBottom, Color.Black * (overlayTextColor.A / 255.0f));
GUI.DrawString(spriteBatch, bottomTextPos, overlayTextBottom, overlayTextColor);
}
@@ -152,7 +152,7 @@ namespace Barotrauma
if (ReadyCheckButton != null) { ReadyCheckButton.Visible = false; }
return;
}
if (Submarine.MainSub == null) { return; }
if (Submarine.MainSub == null || Level.Loaded == null) { return; }
endRoundButton.Visible = false;
var availableTransition = GetAvailableTransition(out _, out Submarine leavingSub);
@@ -211,6 +211,7 @@ namespace Barotrauma
HintManager.OnAvailableTransition(availableTransition);
//opening the campaign map pauses the game and prevents HintManager from running -> update it manually to get the hint to show up immediately
HintManager.Update();
Map.SelectLocation(-1);
endRoundButton.OnClicked(EndRoundButton, null);
prevCampaignUIAutoOpenType = availableTransition;
}
@@ -239,11 +239,20 @@ namespace Barotrauma
timer = Math.Min(timer + CoroutineManager.DeltaTime, textDuration);
yield return CoroutineStatus.Running;
}
var outpost = GameMain.GameSession.Level.StartOutpost;
var borders = outpost.GetDockedBorders();
borders.Location += outpost.WorldPosition.ToPoint();
GameMain.GameScreen.Cam.Position = new Vector2(borders.X + borders.Width / 2, borders.Y - borders.Height / 2);
float startZoom = 0.8f /
((float)Math.Max(borders.Width, borders.Height) / (float)GameMain.GameScreen.Cam.Resolution.X);
GameMain.GameScreen.Cam.MinZoom = Math.Min(startZoom, GameMain.GameScreen.Cam.MinZoom);
var transition = new CameraTransition(prevControlled, GameMain.GameScreen.Cam,
null, null,
fadeOut: false,
duration: 5,
startZoom: 1.5f, endZoom: 1.0f)
losFadeIn: true,
waitDuration: 1,
panDuration: 5,
startZoom: startZoom, endZoom: 1.0f)
{
AllowInterrupt = true,
RemoveControlFromCharacter = false
@@ -274,7 +283,8 @@ namespace Barotrauma
var transition = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam,
null, null,
fadeOut: false,
duration: 5,
losFadeIn: true,
panDuration: 5,
startZoom: 0.5f, endZoom: 1.0f)
{
AllowInterrupt = true,
@@ -327,7 +337,7 @@ namespace Barotrauma
var endTransition = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null,
Alignment.Center,
fadeOut: false,
duration: EndTransitionDuration);
panDuration: EndTransitionDuration);
GameMain.Client.EndCinematic = endTransition;
Location portraitLocation = Map?.SelectedLocation ?? Map?.CurrentLocation ?? Level.Loaded?.StartLocation;
@@ -335,7 +345,7 @@ namespace Barotrauma
{
overlaySprite = portraitLocation.Type.GetPortrait(portraitLocation.PortraitId);
}
float fadeOutDuration = endTransition.Duration;
float fadeOutDuration = endTransition.PanDuration;
float t = 0.0f;
while (t < fadeOutDuration || endTransition.Running)
{
@@ -498,7 +508,7 @@ namespace Barotrauma
var transition = new CameraTransition(endObject ?? Submarine.MainSub, GameMain.GameScreen.Cam,
null, Alignment.Center,
fadeOut: true,
duration: 10,
panDuration: 10,
startZoom: null, endZoom: 0.2f);
while (transition.Running)
@@ -298,11 +298,20 @@ namespace Barotrauma
timer = Math.Min(timer + CoroutineManager.DeltaTime, textDuration);
yield return CoroutineStatus.Running;
}
var outpost = GameMain.GameSession.Level.StartOutpost;
var borders = outpost.GetDockedBorders();
borders.Location += outpost.WorldPosition.ToPoint();
GameMain.GameScreen.Cam.Position = new Vector2(borders.X + borders.Width / 2, borders.Y - borders.Height / 2);
float startZoom = 0.8f /
((float)Math.Max(borders.Width, borders.Height) / (float)GameMain.GameScreen.Cam.Resolution.X);
GameMain.GameScreen.Cam.MinZoom = Math.Min(startZoom, GameMain.GameScreen.Cam.MinZoom);
var transition = new CameraTransition(prevControlled, GameMain.GameScreen.Cam,
null, null,
fadeOut: false,
duration: 5,
startZoom: 1.5f, endZoom: 1.0f)
losFadeIn: true,
waitDuration: 1,
panDuration: 5,
startZoom: startZoom, endZoom: 1.0f)
{
AllowInterrupt = true,
RemoveControlFromCharacter = false
@@ -327,19 +336,13 @@ namespace Barotrauma
else
{
ISpatialEntity transitionTarget;
if (prevControlled != null)
{
transitionTarget = prevControlled;
}
else
{
transitionTarget = Submarine.MainSub;
}
transitionTarget = (ISpatialEntity)prevControlled ?? Submarine.MainSub;
var transition = new CameraTransition(transitionTarget, GameMain.GameScreen.Cam,
null, null,
fadeOut: false,
duration: 5,
losFadeIn: prevControlled != null,
panDuration: 5,
startZoom: 0.5f, endZoom: 1.0f)
{
AllowInterrupt = true,
@@ -409,13 +412,13 @@ namespace Barotrauma
var endTransition = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null,
transitionType == TransitionType.LeaveLocation ? Alignment.BottomCenter : Alignment.Center,
fadeOut: false,
duration: EndTransitionDuration);
panDuration: EndTransitionDuration);
GUI.ClearMessages();
Location portraitLocation = Map.SelectedLocation ?? Map.CurrentLocation;
overlaySprite = portraitLocation.Type.GetPortrait(portraitLocation.PortraitId);
float fadeOutDuration = endTransition.Duration;
float fadeOutDuration = endTransition.PanDuration;
float t = 0.0f;
while (t < fadeOutDuration || endTransition.Running)
{
@@ -509,7 +512,7 @@ namespace Barotrauma
var transition = new CameraTransition(endObject ?? Submarine.MainSub, GameMain.GameScreen.Cam,
null, Alignment.Center,
fadeOut: true,
duration: 10,
panDuration: 10,
startZoom: null, endZoom: 0.2f);
while (transition.Running)
@@ -614,7 +614,7 @@ namespace Barotrauma.Tutorials
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
GameMain.LightManager.LosEnabled = false;
var cinematic = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, Alignment.CenterLeft, Alignment.CenterRight, duration: 5.0f);
var cinematic = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, Alignment.CenterLeft, Alignment.CenterRight, panDuration: 5.0f);
while (cinematic.Running)
{
@@ -288,7 +288,7 @@ namespace Barotrauma.Tutorials
yield return new WaitForSeconds(waitBeforeFade);
var endCinematic = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null, Alignment.Center, duration: fadeOutTime);
var endCinematic = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null, Alignment.Center, panDuration: fadeOutTime);
currentTutorialCompleted = Completed = true;
while (endCinematic.Running) yield return null;
Stop();
@@ -40,56 +40,82 @@ namespace Barotrauma
private GUILayoutGroup topLeftButtonGroup;
private GUIButton crewListButton, commandButton, tabMenuButton;
private GUILayoutGroup TopLeftButtonGroup
{
get
{
if (topLeftButtonGroup == null)
{
topLeftButtonGroup = new GUILayoutGroup(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ButtonAreaTop, GUI.Canvas), isHorizontal: true, childAnchor: Anchor.CenterLeft)
{
AbsoluteSpacing = HUDLayoutSettings.Padding,
CanBeFocused = false
};
int buttonHeight = GUI.IntScale(40);
Vector2 buttonSpriteSize = GUI.Style.GetComponentStyle("CrewListToggleButton").GetDefaultSprite().size;
int buttonWidth = (int)((buttonHeight / buttonSpriteSize.Y) * buttonSpriteSize.X);
Point buttonSize = new Point(buttonWidth, buttonHeight);
// Crew list button
crewListButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "CrewListToggleButton")
{
ToolTip = TextManager.GetWithVariable("hudbutton.crewlist", "[key]", GameMain.Config.KeyBindText(InputType.CrewOrders)),
OnClicked = (GUIButton btn, object userdata) =>
{
if (CrewManager == null) { return false; }
CrewManager.IsCrewMenuOpen = !CrewManager.IsCrewMenuOpen;
return true;
}
};
// Command interface button
commandButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform),style: "CommandButton")
{
ToolTip = TextManager.GetWithVariable("hudbutton.commandinterface", "[key]", GameMain.Config.KeyBindText(InputType.Command)),
OnClicked = (button, userData) =>
{
if (CrewManager == null) { return false; }
CrewManager.ToggleCommandUI();
return true;
}
};
// Tab menu button
tabMenuButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "TabMenuButton")
{
ToolTip = TextManager.GetWithVariable("hudbutton.tabmenu", "[key]", GameMain.Config.KeyBindText(InputType.InfoTab)),
OnClicked = (button, userData) =>
{
return ToggleTabMenu();
}
};
}
return topLeftButtonGroup;
private GUIComponent respawnInfoFrame, respawnButtonContainer;
private GUITextBlock respawnInfoText;
private GUITickBox respawnTickBox;
private GUILayoutGroup TopLeftButtonGroup;
private void CreateTopLeftButtons()
{
if (topLeftButtonGroup != null)
{
topLeftButtonGroup.RectTransform.Parent = null;
topLeftButtonGroup = null;
crewListButton = commandButton = tabMenuButton = null;
}
topLeftButtonGroup = new GUILayoutGroup(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ButtonAreaTop, GUI.Canvas), isHorizontal: true, childAnchor: Anchor.CenterLeft)
{
AbsoluteSpacing = HUDLayoutSettings.Padding,
CanBeFocused = false
};
topLeftButtonGroup.RectTransform.ParentChanged += (_) =>
{
GameMain.Instance.ResolutionChanged -= CreateTopLeftButtons;
};
int buttonHeight = GUI.IntScale(40);
Vector2 buttonSpriteSize = GUI.Style.GetComponentStyle("CrewListToggleButton").GetDefaultSprite().size;
int buttonWidth = (int)((buttonHeight / buttonSpriteSize.Y) * buttonSpriteSize.X);
Point buttonSize = new Point(buttonWidth, buttonHeight);
crewListButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "CrewListToggleButton")
{
ToolTip = TextManager.GetWithVariable("hudbutton.crewlist", "[key]", GameMain.Config.KeyBindText(InputType.CrewOrders)),
OnClicked = (GUIButton btn, object userdata) =>
{
if (CrewManager == null) { return false; }
CrewManager.IsCrewMenuOpen = !CrewManager.IsCrewMenuOpen;
return true;
}
};
commandButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "CommandButton")
{
ToolTip = TextManager.GetWithVariable("hudbutton.commandinterface", "[key]", GameMain.Config.KeyBindText(InputType.Command)),
OnClicked = (button, userData) =>
{
if (CrewManager == null) { return false; }
CrewManager.ToggleCommandUI();
return true;
}
};
tabMenuButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "TabMenuButton")
{
ToolTip = TextManager.GetWithVariable("hudbutton.tabmenu", "[key]", GameMain.Config.KeyBindText(InputType.InfoTab)),
OnClicked = (button, userData) =>
{
return ToggleTabMenu();
}
};
GameMain.Instance.ResolutionChanged += CreateTopLeftButtons;
respawnInfoFrame = new GUIFrame(new RectTransform(new Vector2(0.5f, 1.0f), parent: topLeftButtonGroup.RectTransform)
{ MaxSize = new Point(HUDLayoutSettings.ButtonAreaTop.Width / 3, int.MaxValue) }, style: null)
{
Visible = false
};
respawnInfoText = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), respawnInfoFrame.RectTransform), "", wrap: true);
respawnButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), respawnInfoFrame.RectTransform, Anchor.CenterRight), isHorizontal: true, childAnchor: Anchor.CenterLeft)
{
AbsoluteSpacing = HUDLayoutSettings.Padding,
Stretch = true
};
respawnTickBox = new GUITickBox(new RectTransform(Vector2.One * 0.9f, respawnButtonContainer.RectTransform, Anchor.Center), TextManager.Get("respawnquestionpromptrespawn"))
{
ToolTip = TextManager.Get("respawnquestionprompt"),
OnSelected = (tickbox) =>
{
GameMain.Client?.SendRespawnPromptResponse(waitForNextRoundRespawn: !tickbox.Selected);
return true;
}
};
}
public void AddToGUIUpdateList()
@@ -101,20 +127,15 @@ namespace Barotrauma
if ((!(GameMode is CampaignMode campaign) || (!campaign.ForceMapUI && !campaign.ShowCampaignUI)) &&
!CoroutineManager.IsCoroutineRunning("LevelTransition") && !CoroutineManager.IsCoroutineRunning("SubmarineTransition"))
{
if (crewListButton != null)
if (topLeftButtonGroup == null)
{
crewListButton.Selected = CrewManager != null && CrewManager.IsCrewMenuOpen;
CreateTopLeftButtons();
}
if (commandButton != null)
{
commandButton.Selected = CrewManager.IsCommandInterfaceOpen;
commandButton.Enabled = CrewManager.CanIssueOrders;
}
if (tabMenuButton != null)
{
tabMenuButton.Selected = IsTabMenuOpen;
}
TopLeftButtonGroup.AddToGUIUpdateList();
crewListButton.Selected = CrewManager != null && CrewManager.IsCrewMenuOpen;
commandButton.Selected = CrewManager.IsCommandInterfaceOpen;
commandButton.Enabled = CrewManager.CanIssueOrders;
tabMenuButton.Selected = IsTabMenuOpen;
topLeftButtonGroup.AddToGUIUpdateList();
}
if (GameMain.NetworkMember != null)
@@ -130,7 +151,7 @@ namespace Barotrauma
if (tabMenu == null)
{
if (PlayerInput.KeyHit(InputType.InfoTab) && GUI.KeyboardDispatcher.Subscriber is GUITextBox == false)
if (PlayerInput.KeyHit(InputType.InfoTab) && !(GUI.KeyboardDispatcher.Subscriber is GUITextBox))
{
ToggleTabMenu();
}
@@ -138,8 +159,8 @@ namespace Barotrauma
else
{
tabMenu.Update();
if (PlayerInput.KeyHit(InputType.InfoTab) && GUI.KeyboardDispatcher.Subscriber is GUITextBox == false)
if ((PlayerInput.KeyHit(InputType.InfoTab) || PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Escape)) &&
!(GUI.KeyboardDispatcher.Subscriber is GUITextBox))
{
ToggleTabMenu();
}
@@ -167,6 +188,17 @@ namespace Barotrauma
HintManager.Update();
}
public void SetRespawnInfo(bool visible, string text, Color textColor, bool buttonsVisible, bool waitForNextRoundRespawn)
{
if (topLeftButtonGroup == null) { return; }
respawnInfoFrame.Visible = visible;
if (!visible) { return; }
respawnInfoText.Text = text;
respawnInfoText.TextColor = textColor;
respawnButtonContainer.Visible = buttonsVisible;
respawnTickBox.Selected = !waitForNextRoundRespawn;
}
public void Draw(SpriteBatch spriteBatch)
{
GameMode?.Draw(spriteBatch);
@@ -1,4 +1,5 @@
using Barotrauma.IO;
using Barotrauma.Extensions;
using Barotrauma.IO;
using Barotrauma.Items.Components;
using Microsoft.Xna.Framework;
using System;
@@ -21,41 +22,16 @@ namespace Barotrauma
private static GUIMessageBox ActiveHintMessageBox { get; set; }
private static Action OnUpdate { get; set; }
private static double TimeStoppedInteracting { get; set; }
private static double TimeRoundStarted { get; set; }
/// <summary>
/// Seconds before any reminders can be shown
/// </summary>
private static int TimeBeforeReminders { get; set; }
/// <summary>
/// Seconds before another reminder can be shown
/// </summary>
private static int ReminderCooldown { get; set; }
private static double TimeReminderLastDisplayed { get; set; }
private static Queue<HintInfo> HintQueue { get; } = new Queue<HintInfo>();
public struct HintInfo
{
public string Identifier { get; }
public string Text { get; }
public Sprite Icon { get; }
public Color? IconColor { get; }
public Action OnDisplay { get; }
public Action OnUpdate { get; }
public HintInfo(string hintIdentifier, string text, Sprite icon, Color? iconColor, Action onDisplay, Action onUpdate)
{
Identifier = hintIdentifier;
Text = text;
Icon = icon;
IconColor = iconColor;
OnDisplay = onDisplay;
OnUpdate = onUpdate;
}
}
private static HashSet<Hull> BallastHulls { get; } = new HashSet<Hull>();
public static void Init()
@@ -127,15 +103,6 @@ namespace Barotrauma
return;
}
}
else if (HintQueue.TryDequeue(out var hint))
{
ActiveHintMessageBox = new GUIMessageBox(hint.Identifier, hint.Text, hint.Icon);
if (hint.IconColor.HasValue) { ActiveHintMessageBox.IconColor = hint.IconColor.Value; }
OnUpdate = hint.OnUpdate;
ActiveHintMessageBox.InnerFrame.Flash(color: hint.IconColor ?? Color.Orange, flashDuration: 0.75f);
SoundPlayer.PlayUISound(GUISoundType.UIMessage);
hint.OnDisplay?.Invoke();
}
CheckIsInteracting();
CheckIfDivingGearOutOfOxygen();
@@ -166,21 +133,21 @@ namespace Barotrauma
// onstartedinteracting.brokenitem
if (item.Repairables.Any(r => item.ConditionPercentage < r.RepairThreshold))
{
if (EnqueueHint($"{hintIdentifierBase}.brokenitem")) { return; }
if (DisplayHint($"{hintIdentifierBase}.brokenitem")) { return; }
}
// onstartedinteracting.lootingisstealing
if (item.Submarine?.Info?.Type == SubmarineType.Outpost &&
item.ContainedItems.Any(i => i.SpawnedInOutpost))
{
if (EnqueueHint($"{hintIdentifierBase}.lootingisstealing")) { return; }
if (DisplayHint($"{hintIdentifierBase}.lootingisstealing")) { return; }
}
// onstartedinteracting.turretperiscope
if (item.HasTag("periscope") &&
item.GetConnectedComponents<Turret>().FirstOrDefault(t => t.Item.HasTag("turret")) is Turret)
{
if (EnqueueHint($"{hintIdentifierBase}.turretperiscope",
if (DisplayHint($"{hintIdentifierBase}.turretperiscope",
variableTags: new string[] { "[shootkey]", "[deselectkey]", },
variableValues: new string[] { GameMain.Config.KeyBindText(InputType.Shoot), GameMain.Config.KeyBindText(InputType.Deselect) }))
{ return; }
@@ -193,7 +160,7 @@ namespace Barotrauma
if (!hintIdentifier.StartsWith(hintIdentifierBase)) { continue; }
if (!HintTags.TryGetValue(hintIdentifier, out var hintTags)) { continue; }
if (!item.HasTag(hintTags)) { continue; }
if (EnqueueHint(hintIdentifier)) { return; }
if (DisplayHint(hintIdentifier)) { return; }
}
}
@@ -206,7 +173,7 @@ namespace Barotrauma
Character.Controlled.SelectedConstruction.OwnInventory?.AllItems is IEnumerable<Item> containedItems &&
containedItems.Count(i => i.HasTag("reactorfuel")) > 1)
{
if (EnqueueHint("onisinteracting.reactorwithextrarods")) { return; }
if (DisplayHint("onisinteracting.reactorwithextrarods")) { return; }
}
}
@@ -214,6 +181,7 @@ namespace Barotrauma
{
// Make sure everything's been reset properly, OnRoundEnded() isn't always called when exiting a game
Reset();
TimeRoundStarted = GameMain.GameScreen.GameTime;
var initRoundHandle = CoroutineManager.StartCoroutine(InitRound(), "HintManager.InitRound");
if (!CanDisplayHints(requireGameScreen: false, requireControllingCharacter: false)) { return; }
@@ -252,10 +220,15 @@ namespace Barotrauma
OnStartedControlling();
while (ActiveHintMessageBox != null)
{
yield return CoroutineStatus.Running;
}
if (!GameMain.GameSession.GameMode.IsSinglePlayer &&
GameMain.Config.VoiceSetting == GameSettings.VoiceMode.Disabled)
{
EnqueueHint("onroundstarted.voipdisabled", onUpdate: () =>
DisplayHint("onroundstarted.voipdisabled", onUpdate: () =>
{
if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.Disabled) { return; }
ActiveHintMessageBox.Close();
@@ -281,7 +254,6 @@ namespace Barotrauma
ActiveHintMessageBox = null;
}
OnUpdate = null;
HintQueue.Clear();
HintsIgnoredThisRound.Clear();
}
@@ -292,7 +264,7 @@ namespace Barotrauma
if (spottedCharacter == null || spottedCharacter.Removed || spottedCharacter.IsDead) { return; }
if (Character.Controlled.SelectedConstruction != sonar) { return; }
if (HumanAIController.IsFriendly(Character.Controlled, spottedCharacter)) { return; }
EnqueueHint("onsonarspottedenemy");
DisplayHint("onsonarspottedenemy");
}
public static void OnAfflictionDisplayed(Character character, List<Affliction> displayedAfflictions)
@@ -305,7 +277,8 @@ namespace Barotrauma
if (affliction.Prefab.IsBuff) { continue; }
if (affliction.Prefab == AfflictionPrefab.OxygenLow) { continue; }
if (affliction.Prefab == AfflictionPrefab.RadiationSickness && (GameMain.GameSession.Map?.Radiation?.IsEntityRadiated(character) ?? false)) { continue; }
EnqueueHint("onafflictiondisplayed",
if (affliction.Strength < affliction.Prefab.ShowIconThreshold) { continue; }
DisplayHint("onafflictiondisplayed",
variableTags: new string[1] { "[key]" },
variableValues: new string[1] { GameMain.Config.KeyBindText(InputType.Health) },
icon: affliction.Prefab.Icon,
@@ -325,12 +298,13 @@ namespace Barotrauma
if (character != Character.Controlled) { return; }
if (character.SelectedConstruction != null || character.FocusedItem != null) { return; }
if (item == null || !item.IsShootable || !item.RequireAimToUse) { return; }
if (GUI.MouseOn != null) { return; }
if (TimeStoppedInteracting + 1 > Timing.TotalTime) { return; }
if (GUI.MouseOn != null) { return; }
if (Character.Controlled.Inventory?.visualSlots != null && Character.Controlled.Inventory.visualSlots.Any(s => s.InteractRect.Contains(PlayerInput.MousePosition))) { return; }
string hintIdentifier = "onshootwithoutaiming";
if (!HintTags.TryGetValue(hintIdentifier, out var tags)) { return; }
if (!item.HasTag(tags)) { return; }
EnqueueHint(hintIdentifier,
DisplayHint(hintIdentifier,
variableTags: new string[1] { "[key]" },
variableValues: new string[1] { GameMain.Config.KeyBindText(InputType.Aim) },
onUpdate: () =>
@@ -347,14 +321,14 @@ namespace Barotrauma
if (!CanDisplayHints()) { return; }
if (character != Character.Controlled) { return; }
if (door == null || door.Stuck < 20.0f) { return; }
EnqueueHint("onweldingdoor");
DisplayHint("onweldingdoor");
}
public static void OnTryOpenStuckDoor(Character character)
{
if (!CanDisplayHints()) { return; }
if (character != Character.Controlled) { return; }
EnqueueHint("ontryopenstuckdoor");
DisplayHint("ontryopenstuckdoor");
}
public static void OnShowCampaignInterface(CampaignMode.InteractionType interactionType)
@@ -362,36 +336,34 @@ namespace Barotrauma
if (!CanDisplayHints()) { return; }
if (interactionType == CampaignMode.InteractionType.None) { return; }
string hintIdentifier = $"onshowcampaigninterface.{interactionType.ToString().ToLowerInvariant()}";
EnqueueHint(hintIdentifier,
onUpdate: () =>
{
DisplayHint(hintIdentifier, onUpdate: () =>
{
if (!(GameMain.GameSession?.Campaign is CampaignMode campaign) ||
(!campaign.ShowCampaignUI && !campaign.ForceMapUI) ||
campaign.CampaignUI?.SelectedTab != CampaignMode.InteractionType.Map)
{
ActiveHintMessageBox.Close();
}
});
if (!(GameMain.GameSession?.Campaign is CampaignMode campaign) ||
(!campaign.ShowCampaignUI && !campaign.ForceMapUI) ||
campaign.CampaignUI?.SelectedTab != CampaignMode.InteractionType.Map)
{
ActiveHintMessageBox.Close();
}
});
}
public static void OnShowCommandInterface()
{
IgnoreReminder("commandinterface");
if (!CanDisplayHints()) { return; }
EnqueueHint("onshowcommandinterface",
onUpdate: () =>
{
if (CrewManager.IsCommandInterfaceOpen) { return; }
ActiveHintMessageBox.Close();
});
DisplayHint("onshowcommandinterface", onUpdate: () =>
{
if (CrewManager.IsCommandInterfaceOpen) { return; }
ActiveHintMessageBox.Close();
});
}
public static void OnShowHealthInterface()
{
if (!CanDisplayHints()) { return; }
if (CharacterHealth.OpenHealthWindow == null) { return; }
EnqueueHint("onshowhealthinterface", onUpdate: () =>
DisplayHint("onshowhealthinterface", onUpdate: () =>
{
if (CharacterHealth.OpenHealthWindow != null) { return; }
ActiveHintMessageBox.Close();
@@ -408,7 +380,7 @@ namespace Barotrauma
if (!CanDisplayHints()) { return; }
if (character != Character.Controlled) { return; }
if (item == null || !item.SpawnedInOutpost || !item.StolenDuringRound) { return; }
EnqueueHint("onstoleitem", onUpdate: () =>
DisplayHint("onstoleitem", onUpdate: () =>
{
if (item == null || item.Removed || item.GetRootInventoryOwner() != character)
{
@@ -421,7 +393,7 @@ namespace Barotrauma
{
if (!CanDisplayHints()) { return; }
if (character != Character.Controlled || !character.LockHands) { return; }
EnqueueHint("onhandcuffed", onUpdate: () =>
DisplayHint("onhandcuffed", onUpdate: () =>
{
if (character != null && !character.Removed && character.LockHands) { return; }
ActiveHintMessageBox.Close();
@@ -434,7 +406,7 @@ namespace Barotrauma
if (reactor == null) { return; }
if (reactor.Item.Submarine?.Info?.Type != SubmarineType.Player || reactor.Item.Submarine.TeamID != Character.Controlled.TeamID) { return; }
if (!HasValidJob("engineer")) { return; }
EnqueueHint("onreactoroutoffuel", onUpdate: () =>
DisplayHint("onreactoroutoffuel", onUpdate: () =>
{
if (reactor?.Item != null && !reactor.Item.Removed && reactor.AvailableFuel < 1) { return; }
ActiveHintMessageBox.Close();
@@ -445,7 +417,7 @@ namespace Barotrauma
{
if (!CanDisplayHints()) { return; }
if (transitionType == CampaignMode.TransitionType.None) { return; }
EnqueueHint($"onavailabletransition.{transitionType.ToString().ToLowerInvariant()}");
DisplayHint($"onavailabletransition.{transitionType.ToString().ToLowerInvariant()}");
}
public static void OnShowSubInventory(Item item)
@@ -462,12 +434,31 @@ namespace Barotrauma
IgnoreReminder("characterchange");
}
public static void OnCharacterUnconscious(Character character)
{
if (!CanDisplayHints()) { return; }
if (character != Character.Controlled) { return; }
if (character.IsDead) { return; }
if (character.CharacterHealth != null && character.Vitality < character.CharacterHealth.MinVitality) { return; }
DisplayHint("oncharacterunconscious");
}
public static void OnCharacterKilled(Character character)
{
if (!CanDisplayHints()) { return; }
if (character != Character.Controlled) { return; }
if (GameMain.IsMultiplayer) { return; }
if (GameMain.GameSession?.CrewManager == null) { return; }
if (GameMain.GameSession.CrewManager.GetCharacters().None(c => !c.IsDead)) { return; }
DisplayHint("oncharacterkilled");
}
private static void OnStartedControlling()
{
if (Level.IsLoadedOutpost) { return; }
if (Character.Controlled?.Info?.Job?.Prefab == null) { return; }
string hintIdentifier = $"onstartedcontrolling.job.{Character.Controlled.Info.Job.Prefab.Identifier}";
EnqueueHint(hintIdentifier,
DisplayHint(hintIdentifier,
icon: Character.Controlled.Info.Job.Prefab.Icon,
iconColor: Character.Controlled.Info.Job.Prefab.UIColor,
onDisplay: () =>
@@ -500,7 +491,7 @@ namespace Barotrauma
if (!steering.SteeringPath.Finished && steering.SteeringPath.NextNode != null) { return; }
if (steering.LevelStartSelected && (Level.Loaded.StartOutpost == null || !steering.Item.Submarine.AtStartExit)) { return; }
if (steering.LevelEndSelected && (Level.Loaded.EndOutpost == null || !steering.Item.Submarine.AtEndExit)) { return; }
EnqueueHint("onautopilotreachedoutpost");
DisplayHint("onautopilotreachedoutpost");
}
public static void OnStatusEffectApplied(ItemComponent component, ActionType actionType, Character character)
@@ -509,7 +500,7 @@ namespace Barotrauma
if (character != Character.Controlled) { return; }
// Could make this more generic if there will ever be any other status effect related hints
if (!(component is Repairable) || actionType != ActionType.OnFailure) { return; }
EnqueueHint("onrepairfailed");
DisplayHint("onrepairfailed");
}
private static void CheckIfDivingGearOutOfOxygen()
@@ -517,12 +508,12 @@ namespace Barotrauma
if (!CanDisplayHints()) { return; }
var divingGear = Character.Controlled.GetEquippedItem("diving");
if (divingGear?.OwnInventory == null) { return; }
if (divingGear.GetContainedItemConditionPercentage() > 0.05f) { return; }
EnqueueHint("ondivinggearoutofoxygen", onUpdate: () =>
if (divingGear.GetContainedItemConditionPercentage() > 0.0f) { return; }
DisplayHint("ondivinggearoutofoxygen", onUpdate: () =>
{
if (divingGear == null || divingGear.Removed ||
Character.Controlled == null || !Character.Controlled.HasEquippedItem(divingGear) ||
divingGear.GetContainedItemConditionPercentage() > 0.05f)
divingGear.GetContainedItemConditionPercentage() > 0.0f)
{
ActiveHintMessageBox.Close();
}
@@ -535,15 +526,21 @@ namespace Barotrauma
if (Character.Controlled.CurrentHull == null) { return; }
foreach (var gap in Character.Controlled.CurrentHull.ConnectedGaps)
{
if (!gap.IsRoomToRoom) { continue; }
if (gap.ConnectedDoor == null || gap.ConnectedDoor.Impassable) { continue; }
if (Vector2.DistanceSquared(Character.Controlled.WorldPosition, gap.ConnectedDoor.Item.WorldPosition) > 400 * 400) { continue; }
if (!gap.IsRoomToRoom)
{
if (!(Character.Controlled.GetEquippedItem("deepdiving") is Item)) { continue; }
if (Character.Controlled.IsProtectedFromPressure()) { continue; }
if (DisplayHint("divingsuitwarning", extendTextTag: false)) { return; }
continue;
}
foreach (var me in gap.linkedTo)
{
if (me == Character.Controlled.CurrentHull) { continue; }
if (!(me is Hull adjacentHull)) { continue; }
if (adjacentHull.LethalPressure > 5.0f && EnqueueHint("onadjacenthull.highpressure")) { return; }
if (adjacentHull.WaterPercentage > 75 && !BallastHulls.Contains(adjacentHull) && EnqueueHint("onadjacenthull.highwaterpercentage")) { return; }
if (adjacentHull.LethalPressure > 5.0f && DisplayHint("onadjacenthull.highpressure")) { return; }
if (adjacentHull.WaterPercentage > 75 && !BallastHulls.Contains(adjacentHull) && DisplayHint("onadjacenthull.highwaterpercentage")) { return; }
}
}
}
@@ -552,23 +549,23 @@ namespace Barotrauma
{
if (!CanDisplayHints()) { return; }
if (Level.Loaded == null) { return; }
if (Timing.TotalTime < GameMain.GameSession.RoundStartTime + TimeBeforeReminders) { return; }
if (Timing.TotalTime < TimeReminderLastDisplayed + ReminderCooldown) { return; }
if (GameMain.GameScreen.GameTime < TimeRoundStarted + TimeBeforeReminders) { return; }
if (GameMain.GameScreen.GameTime < TimeReminderLastDisplayed + ReminderCooldown) { return; }
string hintIdentifierBase = "reminder";
if (GameMain.GameSession.GameMode.IsSinglePlayer)
{
if (EnqueueHint($"{hintIdentifierBase}.characterchange"))
if (DisplayHint($"{hintIdentifierBase}.characterchange"))
{
TimeReminderLastDisplayed = Timing.TotalTime;
TimeReminderLastDisplayed = GameMain.GameScreen.GameTime;
return;
}
}
if (Level.Loaded.Type != LevelData.LevelType.Outpost)
{
if (EnqueueHint($"{hintIdentifierBase}.commandinterface",
if (DisplayHint($"{hintIdentifierBase}.commandinterface",
variableTags: new string[] { "[commandkey]" },
variableValues: new string[] { GameMain.Config.KeyBindText(InputType.Command) },
onUpdate: () =>
@@ -577,12 +574,12 @@ namespace Barotrauma
ActiveHintMessageBox.Close();
}))
{
TimeReminderLastDisplayed = Timing.TotalTime;
TimeReminderLastDisplayed = GameMain.GameScreen.GameTime;
return;
}
}
if (EnqueueHint($"{hintIdentifierBase}.tabmenu",
if (DisplayHint($"{hintIdentifierBase}.tabmenu",
variableTags: new string[] { "[infotabkey]" },
variableValues: new string[] { GameMain.Config.KeyBindText(InputType.InfoTab) },
onUpdate: () =>
@@ -591,21 +588,21 @@ namespace Barotrauma
ActiveHintMessageBox.Close();
}))
{
TimeReminderLastDisplayed = Timing.TotalTime;
TimeReminderLastDisplayed = GameMain.GameScreen.GameTime;
return;
}
if (Character.Controlled.Inventory?.GetItemInLimbSlot(InvSlotType.Bag)?.Prefab?.Identifier == "toolbelt")
{
if (EnqueueHint($"{hintIdentifierBase}.toolbelt"))
if (DisplayHint($"{hintIdentifierBase}.toolbelt"))
{
TimeReminderLastDisplayed = Timing.TotalTime;
TimeReminderLastDisplayed = GameMain.GameScreen.GameTime;
return;
}
}
}
private static bool EnqueueHint(string hintIdentifier, string[] variableTags = null, string[] variableValues = null, Sprite icon = null, Color? iconColor = null, Action onDisplay = null, Action onUpdate = null)
private static bool DisplayHint(string hintIdentifier, bool extendTextTag = true, string[] variableTags = null, string[] variableValues = null, Sprite icon = null, Color? iconColor = null, Action onDisplay = null, Action onUpdate = null)
{
if (string.IsNullOrEmpty(hintIdentifier)) { return false; }
if (!HintIdentifiers.Contains(hintIdentifier)) { return false; }
@@ -613,7 +610,7 @@ namespace Barotrauma
if (HintsIgnoredThisRound.Contains(hintIdentifier)) { return false; }
string text;
string textTag = $"hint.{hintIdentifier}";
string textTag = extendTextTag ? $"hint.{hintIdentifier}" : hintIdentifier;
if (variableTags != null && variableTags != null && variableTags.Length > 0 && variableTags.Length == variableValues.Length)
{
text = TextManager.GetWithVariables(textTag, variableTags, variableValues, returnNull: true);
@@ -631,9 +628,16 @@ namespace Barotrauma
return false;
}
var hint = new HintInfo(hintIdentifier, text, icon, iconColor, onDisplay, onUpdate);
HintQueue.Enqueue(hint);
HintsIgnoredThisRound.Add(hintIdentifier);
ActiveHintMessageBox = new GUIMessageBox(hintIdentifier, text, icon);
if (iconColor.HasValue) { ActiveHintMessageBox.IconColor = iconColor.Value; }
OnUpdate = onUpdate;
SoundPlayer.PlayUISound(GUISoundType.UIMessage);
ActiveHintMessageBox.InnerFrame.Flash(color: iconColor ?? Color.Orange, flashDuration: 0.75f);
onDisplay?.Invoke();
return true;
}
@@ -678,6 +682,7 @@ namespace Barotrauma
{
if (HintIdentifiers == null) { return false; }
if (GameMain.Config.DisableInGameHints) { return false; }
if (ActiveHintMessageBox != null) { return false; }
if (requireControllingCharacter && Character.Controlled == null) { return false; }
var gameMode = GameMain.GameSession?.GameMode;
if (!(gameMode is CampaignMode || gameMode is MissionMode)) { return false; }
@@ -266,7 +266,9 @@ namespace Barotrauma
displayedMission.Description;
GUIImage missionIcon = new GUIImage(new RectTransform(new Point((int)(missionContentHorizontal.Rect.Height)), missionContentHorizontal.RectTransform), displayedMission.Prefab.Icon, scaleToFit: true)
{
Color = displayedMission.Prefab.IconColor
Color = displayedMission.Prefab.IconColor,
HoverColor = displayedMission.Prefab.IconColor,
SelectedColor = displayedMission.Prefab.IconColor
};
missionIcon.RectTransform.MinSize = new Point((int)(missionContentHorizontal.Rect.Height * 0.9f));
if (selectedMissions.Contains(displayedMission))
@@ -278,8 +280,27 @@ namespace Barotrauma
{
RelativeSpacing = 0.05f
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
var missionNameTextBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
displayedMission.Name, font: GUI.SubHeadingFont);
if (displayedMission.Difficulty.HasValue)
{
var groupSize = missionNameTextBlock.Rect.Size;
groupSize.X -= (int)(missionNameTextBlock.Padding.X + missionNameTextBlock.Padding.Z);
var indicatorGroup = new GUILayoutGroup(new RectTransform(groupSize, missionTextContent.RectTransform) { AbsoluteOffset = new Point((int)missionNameTextBlock.Padding.X, 0) },
isHorizontal: true, childAnchor: Anchor.CenterLeft)
{
AbsoluteSpacing = 1
};
var difficultyColor = displayedMission.GetDifficultyColor();
for (int i = 0; i < displayedMission.Difficulty; i++)
{
new GUIImage(new RectTransform(Vector2.One, indicatorGroup.RectTransform, scaleBasis: ScaleBasis.Smallest) { IsFixedSize = true }, "DifficultyIndicator", scaleToFit: true)
{
CanBeFocused = false,
Color = difficultyColor
};
}
}
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
missionMessage, wrap: true, parseRichText: true);
if (selectedMissions.Contains(displayedMission) && displayedMission.Completed && displayedMission.Reward > 0)
@@ -430,7 +451,7 @@ namespace Barotrauma
Faction unlockFaction = null;
if (!string.IsNullOrEmpty(unlockEvent.UnlockPathFaction))
{
unlockFaction = GameMain.GameSession.Campaign.Factions.Find(f => f.Prefab.Identifier == unlockEvent.UnlockPathFaction);
unlockFaction = GameMain.GameSession.Campaign.Factions.Find(f => f.Prefab.Identifier.Equals(unlockEvent.UnlockPathFaction, StringComparison.OrdinalIgnoreCase));
unlockReputation = unlockFaction?.Reputation;
}
float normalizedUnlockReputation = MathUtils.InverseLerp(unlockReputation.MinReputation, unlockReputation.MaxReputation, unlockEvent.UnlockPathReputation);
@@ -160,13 +160,6 @@ namespace Barotrauma
CreateSlots();
}
public override void RemoveItem(Item item)
{
if (!Contains(item)) { return; }
base.RemoveItem(item);
CreateSlots();
}
public override void CreateSlots()
{
if (visualSlots == null) { visualSlots = new VisualSlot[capacity]; }
@@ -381,15 +381,11 @@ namespace Barotrauma.Items.Components
private void DrawOutputOverLay(SpriteBatch spriteBatch, GUICustomComponent overlayComponent)
{
if (!outputContainer.Inventory.IsEmpty()) { return; }
overlayComponent.RectTransform.SetAsLastChild();
FabricationRecipe targetItem = fabricatedItem ?? selectedItem;
if (targetItem != null)
{
var itemIcon = targetItem.TargetItem.InventoryIcon ?? targetItem.TargetItem.sprite;
Rectangle slotRect = outputContainer.Inventory.visualSlots[0].Rect;
if (fabricatedItem != null)
@@ -402,11 +398,15 @@ namespace Barotrauma.Items.Components
GUI.Style.Green * 0.5f, isFilled: true);
}
itemIcon.Draw(
spriteBatch,
slotRect.Center.ToVector2(),
color: targetItem.TargetItem.InventoryIconColor * 0.4f,
scale: Math.Min(slotRect.Width / itemIcon.size.X, slotRect.Height / itemIcon.size.Y) * 0.9f);
if (outputContainer.Inventory.IsEmpty())
{
var itemIcon = targetItem.TargetItem.InventoryIcon ?? targetItem.TargetItem.sprite;
itemIcon.Draw(
spriteBatch,
slotRect.Center.ToVector2(),
color: targetItem.TargetItem.InventoryIconColor * 0.4f,
scale: Math.Min(slotRect.Width / itemIcon.size.X, slotRect.Height / itemIcon.size.Y) * 0.9f);
}
}
if (tooltip != null)
@@ -16,7 +16,8 @@ namespace Barotrauma.Items.Components
{
Default,
Disruption,
Destructible
Destructible,
LongRange
}
private PathFinder pathFinder;
@@ -69,6 +70,9 @@ namespace Barotrauma.Items.Components
private const float DisruptionUpdateInterval = 0.2f;
private float disruptionUpdateTimer;
private const float LongRangeUpdateInterval = 10.0f;
private float longRangeUpdateTimer;
private float showDirectionalIndicatorTimer;
private readonly List<LevelObject> nearbyObjects = new List<LevelObject>();
@@ -122,6 +126,10 @@ namespace Barotrauma.Items.Components
{
BlipType.Destructible,
new Color[] { Color.TransparentBlack, new Color(74, 113, 75) * 0.8f, new Color(151, 236, 172) * 0.8f, new Color(153, 217, 234) * 0.8f }
},
{
BlipType.LongRange,
new Color[] { Color.TransparentBlack, Color.TransparentBlack, new Color(254, 68, 19) * 0.8f, Color.TransparentBlack }
}
};
@@ -674,7 +682,6 @@ namespace Barotrauma.Items.Components
}
disruptionUpdateTimer -= deltaTime;
for (var pingIndex = 0; pingIndex < activePingsCount; ++pingIndex)
{
var activePing = activePings[pingIndex];
@@ -684,12 +691,44 @@ namespace Barotrauma.Items.Components
pingRadius, activePing.PrevPingRadius, displayScale, range / zoom, passive: false, pingStrength: 2.0f);
activePing.PrevPingRadius = pingRadius;
}
if (disruptionUpdateTimer <= 0.0f)
{
disruptionUpdateTimer = DisruptionUpdateInterval;
}
longRangeUpdateTimer -= deltaTime;
if (longRangeUpdateTimer <= 0.0f)
{
foreach (Character c in Character.CharacterList)
{
if (c.AnimController.CurrentHull != null || !c.Enabled) { continue; }
if (c.Params.HideInSonar) { continue; }
if (!c.IsUnconscious && c.Params.DistantSonarRange > 0.0f &&
((c.WorldPosition - transducerCenter) * displayScale).LengthSquared() > DisplayRadius * DisplayRadius)
{
float dist = Vector2.Distance(c.WorldPosition, transducerCenter);
Vector2 targetDir = (c.WorldPosition - transducerCenter) / dist;
int blipCount = (int)MathHelper.Clamp(c.Mass, 50, 200);
for (int i = 0; i < blipCount; i++)
{
float angle = Rand.Range(-0.5f, 0.5f);
Vector2 blipDir = MathUtils.RotatePoint(targetDir, angle);
Vector2 invBlipDir = MathUtils.RotatePoint(targetDir, -angle);
var longRangeBlip = new SonarBlip(transducerCenter + blipDir * Range * 0.9f, Rand.Range(1.9f, 2.1f), Rand.Range(1.0f, 1.5f), BlipType.LongRange)
{
Velocity = -invBlipDir * (MathUtils.Round(Rand.Range(8000.0f, 15000.0f), 2000.0f) - Math.Abs(angle * angle * 10000.0f)),
Rotation = (float)Math.Atan2(-invBlipDir.Y, invBlipDir.X),
Alpha = MathUtils.Pow2((c.Params.DistantSonarRange - dist) / c.Params.DistantSonarRange)
};
longRangeBlip.Size.Y *= 5.0f;
sonarBlips.Add(longRangeBlip);
}
}
}
longRangeUpdateTimer = LongRangeUpdateInterval;
}
if (currentMode == Mode.Active && currentPingIndex != -1)
{
return;
@@ -946,6 +985,19 @@ namespace Barotrauma.Items.Components
if (connectedSubs.Contains(sub)) { continue; }
if (sub.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
if (item.Submarine != null)
{
//hide enemy team
if (sub.TeamID == CharacterTeamType.Team1 && (item.Submarine.TeamID == CharacterTeamType.Team2 || Character.Controlled?.TeamID == CharacterTeamType.Team2))
{
continue;
}
else if (sub.TeamID == CharacterTeamType.Team2 && (item.Submarine.TeamID == CharacterTeamType.Team1 || Character.Controlled?.TeamID == CharacterTeamType.Team1))
{
continue;
}
}
DrawMarker(spriteBatch,
sub.Info.DisplayName,
sub.Info.HasTag(SubmarineTag.Shuttle) ? "shuttle" : "submarine",
@@ -1045,15 +1097,17 @@ namespace Barotrauma.Items.Components
foreach (DockingPort dockingPort in DockingPort.List)
{
if (Level.Loaded != null && dockingPort.Item.Submarine.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
if (dockingPort.Item.Submarine == null) { continue; }
if (dockingPort.Item.Submarine.Info.IsWreck) { continue; }
//don't show the docking ports of the opposing team on the sonar
if (item.Submarine != null)
{
if ((dockingPort.Item.Submarine.TeamID == CharacterTeamType.Team1 && item.Submarine.TeamID == CharacterTeamType.Team2) ||
(dockingPort.Item.Submarine.TeamID == CharacterTeamType.Team2 && item.Submarine.TeamID == CharacterTeamType.Team1))
if (dockingPort.Item.Submarine.TeamID == CharacterTeamType.Team1 && (item.Submarine.TeamID == CharacterTeamType.Team2 || Character.Controlled?.TeamID == CharacterTeamType.Team2))
{
continue;
}
else if (dockingPort.Item.Submarine.TeamID == CharacterTeamType.Team2 && (item.Submarine.TeamID == CharacterTeamType.Team1 || Character.Controlled?.TeamID == CharacterTeamType.Team1))
{
continue;
}
@@ -1555,12 +1609,12 @@ namespace Barotrauma.Items.Components
float scale = (strength + 3.0f) * blip.Scale * blipScale;
Color color = ToolBox.GradientLerp(strength, blipColorGradient[blip.BlipType]);
sonarBlip.Draw(spriteBatch, center + pos, color, sonarBlip.Origin, blip.Rotation ?? MathUtils.VectorToAngle(pos),
sonarBlip.Draw(spriteBatch, center + pos, color * blip.Alpha, sonarBlip.Origin, blip.Rotation ?? MathUtils.VectorToAngle(pos),
blip.Size * scale * 0.5f, SpriteEffects.None, 0);
pos += Rand.Range(0.0f, 1.0f) * dir + Rand.Range(-scale, scale) * normal;
sonarBlip.Draw(spriteBatch, center + pos, color * 0.5f, sonarBlip.Origin, 0, scale, SpriteEffects.None, 0);
sonarBlip.Draw(spriteBatch, center + pos, color * 0.5f * blip.Alpha, sonarBlip.Origin, 0, scale, SpriteEffects.None, 0);
}
private void DrawMarker(SpriteBatch spriteBatch, string label, string iconIdentifier, object targetIdentifier, Vector2 worldPosition, Vector2 transducerPosition, float scale, Vector2 center, float radius,
@@ -1778,6 +1832,7 @@ namespace Barotrauma.Items.Components
public float? Rotation;
public Vector2 Size;
public Sonar.BlipType BlipType;
public float Alpha = 1.0f;
public SonarBlip(Vector2 pos, float fadeTimer, float scale, Sonar.BlipType blipType = Sonar.BlipType.Default)
{
@@ -727,7 +727,19 @@ namespace Barotrauma.Items.Components
}
}
pressureWarningText.Visible = item.Submarine != null && item.Submarine.AtDamageDepth && Timing.TotalTime % 1.0f < 0.8f;
pressureWarningText.Visible = item.Submarine != null && Timing.TotalTime % 1.0f < 0.8f;
float depthEffectThreshold = 500.0f;
if (Level.Loaded != null && pressureWarningText.Visible &&
item.Submarine.RealWorldDepth > Level.Loaded.RealWorldCrushDepth - depthEffectThreshold && item.Submarine.RealWorldDepth > item.Submarine.RealWorldCrushDepth - depthEffectThreshold)
{
pressureWarningText.Visible = true;
pressureWarningText.Text = item.Submarine.AtDamageDepth ? TextManager.Get("SteeringDepthWarning") : TextManager.Get("SteeringDepthWarningLow").Replace("[crushdepth]", ((int)item.Submarine.RealWorldCrushDepth).ToString());
}
else
{
pressureWarningText.Visible = false;
}
iceSpireWarningText.Visible = item.Submarine != null && !pressureWarningText.Visible && showIceSpireWarning && Timing.TotalTime % 1.0f < 0.8f;
if (Vector2.DistanceSquared(PlayerInput.MousePosition, steerArea.Rect.Center.ToVector2()) < steerRadius * steerRadius)
@@ -1,5 +1,4 @@
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
@@ -28,15 +27,7 @@ namespace Barotrauma.Items.Components
int x = panelRect.X, y = panelRect.Y;
int width = panelRect.Width, height = panelRect.Height;
Vector2 scale = new Vector2(GUI.Scale);
if (panel.GuiFrame.RectTransform.MaxSize.X < int.MaxValue)
{
scale.X = panel.GuiFrame.RectTransform.MaxSize.X / panel.GuiFrame.Rect.Width;
}
if (panel.GuiFrame.RectTransform.MaxSize.Y < int.MaxValue)
{
scale.Y = panel.GuiFrame.RectTransform.MaxSize.Y / panel.GuiFrame.Rect.Height;
}
Vector2 scale = GetScale(panel.GuiFrame.RectTransform.MaxSize, panel.GuiFrame.Rect.Size);
bool mouseInRect = panelRect.Contains(PlayerInput.MousePosition);
@@ -66,15 +57,15 @@ namespace Barotrauma.Items.Components
//two passes: first the connector, then the wires to get the wires to render in front
for (int i = 0; i < 2; i++)
{
Vector2 rightPos = new Vector2(x + width - 80 * scale.X, y + 60 * scale.Y);
Vector2 leftPos = new Vector2(x + 80 * scale.X, y + 60 * scale.Y);
Vector2 rightPos = GetRightPos(x, y, width, scale);
Vector2 leftPos = GetLeftPos(x, y, scale);
Vector2 rightWirePos = new Vector2(x + width - 5 * scale.X, y + 30 * scale.Y);
Vector2 leftWirePos = new Vector2(x + 5 * scale.X, y + 30 * scale.Y);
int wireInterval = (height - (int)(20 * scale.Y)) / Math.Max(totalWireCount, 1);
int connectorIntervalLeft = (height - (int)(100 * scale.Y)) / Math.Max(panel.Connections.Count(c => c.IsOutput), 1);
int connectorIntervalRight = (height - (int)(100 * scale.Y)) / Math.Max(panel.Connections.Count(c => !c.IsOutput), 1);
int connectorIntervalLeft = GetConnectorIntervalLeft(height, scale, panel);
int connectorIntervalRight = GetConnectorIntervalRight(height, scale, panel);
foreach (Connection c in panel.Connections)
{
@@ -101,15 +92,12 @@ namespace Barotrauma.Items.Components
{
if (i == 0)
{
c.DrawConnection(spriteBatch, panel, rightPos,
new Vector2(rightPos.X - GUI.SmallFont.MeasureString(c.DisplayName.ToUpper()).X - 25 * panel.Scale, rightPos.Y + 5 * panel.Scale),
scale);
c.DrawConnection(spriteBatch, panel, rightPos, GetOutputLabelPosition(rightPos, panel, c), scale);
}
else
{
c.DrawWires(spriteBatch, panel, rightPos, rightWirePos, mouseInRect, equippedWire, wireInterval);
}
rightPos.Y += connectorIntervalLeft;
rightWirePos.Y += c.Wires.Count(w => w != null) * wireInterval;
}
@@ -117,15 +105,12 @@ namespace Barotrauma.Items.Components
{
if (i == 0)
{
c.DrawConnection(spriteBatch, panel, leftPos,
new Vector2(leftPos.X + 25 * panel.Scale, leftPos.Y - 5 * panel.Scale - GUI.SmallFont.MeasureString(c.DisplayName.ToUpper()).Y),
scale);
c.DrawConnection(spriteBatch, panel, leftPos, GetInputLabelPosition(leftPos, panel, c), scale);
}
else
{
c.DrawWires(spriteBatch, panel, leftPos, leftWirePos, mouseInRect, equippedWire, wireInterval);
}
leftPos.Y += connectorIntervalRight;
leftWirePos.Y += c.Wires.Count(w => w != null) * wireInterval;
}
@@ -215,14 +200,11 @@ namespace Barotrauma.Items.Components
private void DrawConnection(SpriteBatch spriteBatch, ConnectionPanel panel, Vector2 position, Vector2 labelPos, Vector2 scale)
{
string text = DisplayName.ToUpper();
Vector2 textSize = GUI.SmallFont.MeasureString(text);
//nasty
var labelSprite = GUI.Style.GetComponentStyle("ConnectionPanelLabel")?.Sprites.Values.First().First();
if (labelSprite != null)
if (GUI.Style.GetComponentStyle("ConnectionPanelLabel")?.Sprites.Values.First().First() is UISprite labelSprite)
{
Rectangle labelArea = new Rectangle(labelPos.ToPoint(), textSize.ToPoint());
labelArea.Inflate(10 * scale.X, 3 * scale.Y);
Rectangle labelArea = GetLabelArea(labelPos, text, scale);
labelSprite.Draw(spriteBatch, labelArea, IsPower ? GUI.Style.Red : Color.SteelBlue);
}
@@ -390,5 +372,115 @@ namespace Barotrauma.Items.Components
}
}
}
public static bool CheckConnectionLabelOverlap(ConnectionPanel panel, out Point newRectSize)
{
Rectangle panelRect = panel.GuiFrame.Rect;
int x = panelRect.X, y = panelRect.Y;
Vector2 scale = GetScale(panel.GuiFrame.RectTransform.MaxSize, panel.GuiFrame.Rect.Size);
Vector2 rightPos = GetRightPos(x, y, panelRect.Width, scale);
Vector2 leftPos = GetLeftPos(x, y, scale);
int connectorIntervalLeft = GetConnectorIntervalLeft(panelRect.Height, scale, panel);
int connectorIntervalRight = GetConnectorIntervalRight(panelRect.Height, scale, panel);
newRectSize = panelRect.Size;
var labelAreas = new List<Rectangle>();
for (int i = 0; i < 100; i++)
{
labelAreas.Clear();
foreach (var c in panel.Connections)
{
if (c.IsOutput)
{
var labelArea = GetLabelArea(GetOutputLabelPosition(rightPos, panel, c), c.DisplayName.ToUpper(), scale);
labelAreas.Add(labelArea);
rightPos.Y += connectorIntervalLeft;
}
else
{
var labelArea = GetLabelArea(GetInputLabelPosition(leftPos, panel, c), c.DisplayName.ToUpper(), scale);
labelAreas.Add(labelArea);
leftPos.Y += connectorIntervalRight;
}
}
bool foundOverlap = false;
for (int j = 0; j < labelAreas.Count; j++)
{
for (int k = 0; k < labelAreas.Count; k++)
{
if (k == j) { continue; }
if (!labelAreas[j].Intersects(labelAreas[k])) { continue; }
newRectSize += new Point(10);
Point maxSize = new Point(
Math.Max(panel.GuiFrame.RectTransform.MaxSize.X, newRectSize.X),
Math.Max(panel.GuiFrame.RectTransform.MaxSize.Y, newRectSize.Y));
scale = GetScale(maxSize, newRectSize);
rightPos = GetRightPos(x, y, newRectSize.X, scale);
leftPos = GetLeftPos(x, y, scale);
connectorIntervalLeft = GetConnectorIntervalLeft(newRectSize.Y, scale, panel);
connectorIntervalRight = GetConnectorIntervalRight(newRectSize.Y, scale, panel);
foundOverlap = true;
break;
}
}
if (!foundOverlap) { break; }
}
return newRectSize.X != panel.GuiFrame.Rect.Width || newRectSize.Y > panel.GuiFrame.Rect.Height;
}
private static Vector2 GetScale(Point maxSize, Point size)
{
Vector2 scale = new Vector2(GUI.Scale);
if (maxSize.X < int.MaxValue)
{
scale.X = maxSize.X / size.X;
}
if (maxSize.Y < int.MaxValue)
{
scale.Y = maxSize.Y / size.Y;
}
return scale;
}
private static Vector2 GetInputLabelPosition(Vector2 connectorPosition, ConnectionPanel panel, Connection connection)
{
return new Vector2(
connectorPosition.X + 25 * panel.Scale,
connectorPosition.Y - 5 * panel.Scale - GUI.SmallFont.MeasureString(connection.DisplayName.ToUpper()).Y);
}
private static Vector2 GetOutputLabelPosition(Vector2 connectorPosition, ConnectionPanel panel, Connection connection)
{
return new Vector2(
connectorPosition.X - 25 * panel.Scale - GUI.SmallFont.MeasureString(connection.DisplayName.ToUpper()).X,
connectorPosition.Y + 5 * panel.Scale);
}
private static Rectangle GetLabelArea(Vector2 labelPos, string text, Vector2 scale)
{
Vector2 textSize = GUI.SmallFont.MeasureString(text);
Rectangle labelArea = new Rectangle(labelPos.ToPoint(), textSize.ToPoint());
labelArea.Inflate(10 * scale.X, 3 * scale.Y);
return labelArea;
}
private static Vector2 GetLeftPos(int x, int y, Vector2 scale)
{
return new Vector2(x + 80 * scale.X, y + 60 * scale.Y);
}
private static Vector2 GetRightPos(int x, int y, int width, Vector2 scale)
{
return new Vector2(x + width - 80 * scale.X, y + 60 * scale.Y);
}
private static int GetConnectorIntervalLeft(int height, Vector2 scale, ConnectionPanel panel)
{
return (height - (int)(100 * scale.Y)) / Math.Max(panel.Connections.Count(c => c.IsOutput), 1);
}
private static int GetConnectorIntervalRight(int height, Vector2 scale, ConnectionPanel panel)
{
return (height - (int)(100 * scale.Y)) / Math.Max(panel.Connections.Count(c => !c.IsOutput), 1);
}
}
}
@@ -24,9 +24,15 @@ namespace Barotrauma.Items.Components
get { return GuiFrame.Rect.Width / 400.0f; }
}
partial void InitProjSpecific(XElement element)
private Point originalMaxSize;
private Vector2 originalRelativeSize;
partial void InitProjSpecific()
{
if (GuiFrame == null) { return; }
originalMaxSize = GuiFrame.RectTransform.MaxSize;
originalRelativeSize = GuiFrame.RectTransform.RelativeSize;
CheckForLabelOverlap();
new GUICustomComponent(new RectTransform(Vector2.One, GuiFrame.RectTransform), DrawConnections, null)
{
UserData = this
@@ -40,7 +46,7 @@ namespace Barotrauma.Items.Components
partial void UpdateProjSpecific(float deltaTime)
{
foreach (Wire wire in DisconnectedWires)
foreach (var _ in DisconnectedWires)
{
if (Rand.Range(0.0f, 500.0f) < 1.0f)
{
@@ -112,6 +118,32 @@ namespace Barotrauma.Items.Components
}
}
protected override void OnResolutionChanged()
{
base.OnResolutionChanged();
if (GuiFrame == null) { return; }
CheckForLabelOverlap();
}
private void CheckForLabelOverlap()
{
GuiFrame.RectTransform.MaxSize = originalMaxSize;
GuiFrame.RectTransform.Resize(originalRelativeSize);
if (Connection.CheckConnectionLabelOverlap(this, out Point newRectSize))
{
int xCenter = (int)(GameMain.GraphicsWidth / 2.0f);
int maxNewWidth = 2 * Math.Min(xCenter - HUDLayoutSettings.CrewArea.Right, xCenter - HUDLayoutSettings.ChatBoxArea.Right);
int yCenter = (int)(GameMain.GraphicsHeight / 2.0f);
int maxNewHeight = 2 * Math.Min(yCenter - HUDLayoutSettings.MessageAreaTop.Bottom, HUDLayoutSettings.InventoryTopY - yCenter);
// Make sure we don't expand the panel interface too much
newRectSize = new Point(Math.Min(newRectSize.X, maxNewWidth), Math.Min(newRectSize.Y, maxNewHeight));
GuiFrame.RectTransform.MaxSize = new Point(
Math.Max(GuiFrame.RectTransform.MaxSize.X, newRectSize.X),
Math.Max(GuiFrame.RectTransform.MaxSize.Y, newRectSize.Y));
GuiFrame.RectTransform.Resize(newRectSize);
}
}
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
{
if (GameMain.Client.MidRoundSyncing)
@@ -67,17 +67,19 @@ namespace Barotrauma.Items.Components
item.SendSignal(input, "signal_out");
}
partial void ShowOnDisplay(string input)
partial void ShowOnDisplay(string input, bool addToHistory = true)
{
messageHistory.Add(input);
while (messageHistory.Count > MaxMessages)
if (addToHistory)
{
messageHistory.RemoveAt(0);
}
while (historyBox.Content.CountChildren > MaxMessages)
{
historyBox.RemoveChild(historyBox.Content.Children.First());
messageHistory.Add(input);
while (messageHistory.Count > MaxMessages)
{
messageHistory.RemoveAt(0);
}
while (historyBox.Content.CountChildren > MaxMessages)
{
historyBox.RemoveChild(historyBox.Content.Children.First());
}
}
GUITextBlock newBlock = new GUITextBlock(
@@ -156,7 +156,8 @@ namespace Barotrauma.Items.Components
drawOffset = sub.DrawPosition + sub.HiddenSubPosition;
}
float depth = item.IsSelected ? 0.0f : SubEditorScreen.IsWiringMode() ? 0.02f : wireSprite.Depth + (item.ID % 100) * 0.000001f;// item.GetDrawDepth(wireSprite.Depth, wireSprite);
float baseDepth = UseSpriteDepth ? item.SpriteDepth : wireSprite.Depth;
float depth = item.IsSelected ? 0.0f : SubEditorScreen.IsWiringMode() ? 0.02f : baseDepth + (item.ID % 100) * 0.000001f;// item.GetDrawDepth(wireSprite.Depth, wireSprite);
if (item.IsHighlighted)
{
@@ -302,7 +302,7 @@ namespace Barotrauma
}
if (!string.IsNullOrEmpty(description)) { toolTip += '\n' + description; }
}
if (itemsInSlot.Count() > 2)
if (itemsInSlot.Count() > 1)
{
string colorStr = XMLExtensions.ColorToString(GUI.Style.Blue);
toolTip += $"\n‖color:{colorStr}‖[{GameMain.Config.KeyBindText(InputType.TakeOneFromInventorySlot)}] {TextManager.Get("inputtype.takeonefrominventoryslot")}‖color:end‖";
@@ -569,47 +569,41 @@ namespace Barotrauma
if (!DraggingItems.Any())
{
if (PlayerInput.PrimaryMouseButtonDown() && slots[slotIndex].Any())
var interactableItems = Screen.Selected == GameMain.GameScreen ? slots[slotIndex].Items.Where(it => !it.NonInteractable && !it.NonPlayerTeamInteractable) : slots[slotIndex].Items;
if (PlayerInput.PrimaryMouseButtonDown() && interactableItems.Any())
{
if (PlayerInput.KeyDown(InputType.TakeHalfFromInventorySlot))
{
DraggingItems.AddRange(slots[slotIndex].Items.Skip(slots[slotIndex].ItemCount / 2));
DraggingItems.AddRange(interactableItems.Skip(interactableItems.Count() / 2));
}
else if (PlayerInput.KeyDown(InputType.TakeOneFromInventorySlot))
{
DraggingItems.Add(slots[slotIndex].First());
DraggingItems.Add(interactableItems.First());
}
else
{
DraggingItems.AddRange(slots[slotIndex].Items);
}
if (Screen.Selected == GameMain.GameScreen)
{
DraggingItems.RemoveAll(it => it.NonInteractable || it.NonPlayerTeamInteractable);
DraggingItems.AddRange(interactableItems);
}
DraggingSlot = slot;
}
}
else if (PlayerInput.PrimaryMouseButtonReleased())
{
if (PlayerInput.DoubleClicked() && slots[slotIndex].Any())
var interactableItems = Screen.Selected == GameMain.GameScreen ? slots[slotIndex].Items.Where(it => !it.NonInteractable && !it.NonPlayerTeamInteractable) : slots[slotIndex].Items;
if (PlayerInput.DoubleClicked() && interactableItems.Any())
{
doubleClickedItems.Clear();
if (PlayerInput.KeyDown(InputType.TakeHalfFromInventorySlot))
{
doubleClickedItems.AddRange(slots[slotIndex].Items.Skip(slots[slotIndex].ItemCount / 2));
doubleClickedItems.AddRange(interactableItems.Skip(interactableItems.Count() / 2));
}
else if (PlayerInput.KeyDown(InputType.TakeOneFromInventorySlot))
{
doubleClickedItems.Add(slots[slotIndex].First());
doubleClickedItems.Add(interactableItems.First());
}
else
{
doubleClickedItems.AddRange(slots[slotIndex].Items);
}
if (Screen.Selected == GameMain.GameScreen)
{
doubleClickedItems.RemoveAll(it => it.NonInteractable || it.NonPlayerTeamInteractable);
doubleClickedItems.AddRange(interactableItems);
}
}
}
@@ -618,6 +618,7 @@ namespace Barotrauma
editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) }) { UserData = this };
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.95f, 0.8f), editingHUD.RectTransform, Anchor.Center), style: null)
{
CanTakeKeyBoardFocus = false,
Spacing = (int)(25 * GUI.Scale)
};
@@ -90,7 +90,10 @@ namespace Barotrauma
private GUIComponent CreateEditingHUD(bool inGame = false)
{
editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) }) { UserData = this };
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.95f, 0.8f), editingHUD.RectTransform, Anchor.Center), style: null);
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.95f, 0.8f), editingHUD.RectTransform, Anchor.Center), style: null)
{
CanTakeKeyBoardFocus = false
};
new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, titleFont: GUI.LargeFont);
PositionEditingHUD();
@@ -48,6 +48,7 @@ namespace Barotrauma.Lights
private readonly List<LightSource> lights;
public bool LosEnabled = true;
public float LosAlpha = 1f;
public LosMode LosMode = LosMode.Transparent;
public bool LightingEnabled = true;
@@ -495,9 +496,10 @@ namespace Barotrauma.Lights
if ((!LosEnabled || LosMode == LosMode.None) && !ObstructVision) return;
if (ViewTarget == null) return;
if (Character.Controlled == null) { DebugConsole.NewMessage("aaa", Color.Orange); }
graphics.SetRenderTarget(LosTexture);
spriteBatch.Begin(SpriteSortMode.Deferred, transformMatrix: cam.Transform * Matrix.CreateScale(new Vector3(GameMain.Config.LightMapScale, GameMain.Config.LightMapScale, 1.0f)));
if (ObstructVision)
{
graphics.Clear(Color.Black);
@@ -507,16 +509,17 @@ namespace Barotrauma.Lights
float rotation = MathUtils.VectorToAngle(losOffset);
Vector2 scale = new Vector2(
MathHelper.Clamp(losOffset.Length() / 256.0f, 2.0f, 5.0f), 2.0f);
MathHelper.Clamp(losOffset.Length() / 256.0f, 4.0f, 5.0f), 3.0f);
spriteBatch.Begin(SpriteSortMode.Deferred, transformMatrix: cam.Transform * Matrix.CreateScale(new Vector3(GameMain.Config.LightMapScale, GameMain.Config.LightMapScale, 1.0f)));
spriteBatch.Draw(visionCircle, new Vector2(ViewTarget.WorldPosition.X, -ViewTarget.WorldPosition.Y), null, Color.White, rotation,
new Vector2(visionCircle.Width * 0.2f, visionCircle.Height / 2), scale, SpriteEffects.None, 0.0f);
spriteBatch.End();
}
else
{
graphics.Clear(Color.White);
}
spriteBatch.End();
//--------------------------------------
@@ -465,7 +465,7 @@ namespace Barotrauma
Rectangle rect = mapContainer.Rect;
Vector2 viewSize = new Vector2(rect.Width / zoom, rect.Height / zoom);
Vector2 edgeBuffer = rect.Size.ToVector2() / 2;
Vector2 edgeBuffer = new Vector2(rect.Width * 0.05f);
DrawOffset.X = MathHelper.Clamp(DrawOffset.X, -Width - edgeBuffer.X + viewSize.X / 2.0f, edgeBuffer.X - viewSize.X / 2.0f);
DrawOffset.Y = MathHelper.Clamp(DrawOffset.Y, -Height - edgeBuffer.Y + viewSize.Y / 2.0f, edgeBuffer.Y - viewSize.Y / 2.0f);
@@ -677,11 +677,10 @@ namespace Barotrauma
{
repLabelText = TextManager.Get("reputation");
repLabelSize = GUI.Font.MeasureString(repLabelText);
size.X = Math.Max(size.X, repLabelSize.X);
repBarSize = new Vector2(Math.Max(0.75f * size.X, 100), repLabelSize.Y);
size.X = Math.Max(size.X, (4.0f / 3.0f) * repBarSize.X);
repBarSize = new Vector2(GUI.IntScale(200), repLabelSize.Y);
size.Y += 2 * repLabelSize.Y + GUI.IntScale(5) + repBarSize.Y;
repValueText = HighlightedLocation.Reputation.GetFormattedReputationText(addColorTags: false);
size.X = Math.Max(size.X, repBarSize.X + GUI.Font.MeasureString(repValueText).X + GUI.IntScale(10));
}
GUI.Style.GetComponentStyle("OuterGlow").Sprites[GUIComponent.ComponentState.None][0].Draw(
spriteBatch, new Rectangle((int)(pos.X - 60 * GUI.Scale), (int)(pos.Y - size.Y), (int)(size.X + 120 * GUI.Scale), (int)(size.Y * 2.2f)), Color.Black * hudVisibility);
@@ -696,7 +695,7 @@ namespace Barotrauma
topLeftPos += new Vector2(0.0f, repLabelSize.Y + GUI.IntScale(10));
Rectangle repBarRect = new Rectangle(new Point((int)topLeftPos.X, (int)topLeftPos.Y), new Point((int)repBarSize.X, (int)repBarSize.Y));
RoundSummary.DrawReputationBar(spriteBatch, repBarRect, HighlightedLocation.Reputation.NormalizedValue);
GUI.DrawString(spriteBatch, new Vector2(repBarRect.Right + 4, repBarRect.Top), repValueText, Reputation.GetReputationColor(HighlightedLocation.Reputation.NormalizedValue));
GUI.DrawString(spriteBatch, new Vector2(repBarRect.Right + GUI.IntScale(5), repBarRect.Top), repValueText, Reputation.GetReputationColor(HighlightedLocation.Reputation.NormalizedValue));
}
}
@@ -912,7 +911,7 @@ namespace Barotrauma
Faction unlockFaction = null;
if (!string.IsNullOrEmpty(unlockEvent.UnlockPathFaction))
{
unlockFaction = GameMain.GameSession.Campaign.Factions.Find(f => f.Prefab.Identifier == unlockEvent.UnlockPathFaction);
unlockFaction = GameMain.GameSession.Campaign.Factions.Find(f => f.Prefab.Identifier.Equals(unlockEvent.UnlockPathFaction, StringComparison.OrdinalIgnoreCase));
unlockReputation = unlockFaction?.Reputation;
}
@@ -20,9 +20,6 @@ namespace Barotrauma
public static Vector2 StartMovingPos => startMovingPos;
// Quick undo/redo for size and movement only. TODO: Remove if we do a more general implementation.
private Memento<Rectangle> rectMemento;
public event Action<Rectangle> Resized;
private static bool resizing;
@@ -65,8 +62,6 @@ namespace Barotrauma
}
}
//protected bool isSelected;
private static bool disableSelect;
public static bool DisableSelect
{
@@ -95,7 +95,10 @@ namespace Barotrauma
{
int heightScaled = (int)(20 * GUI.Scale);
editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) }) { UserData = this };
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.95f, 0.8f), editingHUD.RectTransform, Anchor.Center), style: null);
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.95f, 0.8f), editingHUD.RectTransform, Anchor.Center), style: null)
{
CanTakeKeyBoardFocus = false
};
var editor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, titleFont: GUI.LargeFont) { UserData = this };
if (Submarine.MainSub?.Info?.Type == SubmarineType.OutpostModule)
@@ -1,5 +1,6 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma
@@ -32,24 +33,45 @@ namespace Barotrauma
}
}
public void CreatePreviewWindow(GUIComponent parent)
{
var content = new GUIButton(new RectTransform(Vector2.One, parent.RectTransform), style: null)
var content = new GUIFrame(new RectTransform(Vector2.One, parent.RectTransform), style: null);
var previewButton = new GUIButton(new RectTransform(new Vector2(1f, 0.5f), content.RectTransform), style: null)
{
OnClicked = (btn, obj) => { SubmarinePreview.Create(this); return false; }
OnClicked = (btn, obj) => { SubmarinePreview.Create(this); return false; },
};
if (PreviewImage == null)
var previewImage = PreviewImage ?? savedSubmarines.Find(s => s.Name.Equals(Name, StringComparison.OrdinalIgnoreCase))?.PreviewImage;
if (previewImage == null)
{
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), content.RectTransform), TextManager.Get(SavedSubmarines.Contains(this) ? "SubPreviewImageNotFound" : "SubNotDownloaded"));
new GUITextBlock(new RectTransform(Vector2.One, previewButton.RectTransform), TextManager.Get(SavedSubmarines.Contains(this) ? "SubPreviewImageNotFound" : "SubNotDownloaded"));
}
else
{
var submarinePreviewBackground = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.5f), content.RectTransform), style: null) { Color = Color.Black };
new GUIImage(new RectTransform(new Vector2(0.98f), submarinePreviewBackground.RectTransform, Anchor.Center), PreviewImage, scaleToFit: true);
new GUIFrame(new RectTransform(Vector2.One, submarinePreviewBackground.RectTransform), "InnerGlow", color: Color.Black);
var submarinePreviewBackground = new GUIFrame(new RectTransform(Vector2.One, previewButton.RectTransform), style: null)
{
Color = Color.Black,
HoverColor = Color.Black,
SelectedColor = Color.Black,
PressedColor = Color.Black,
CanBeFocused = false,
};
new GUIImage(new RectTransform(new Vector2(0.98f), submarinePreviewBackground.RectTransform, Anchor.Center), previewImage, scaleToFit: true) { CanBeFocused = false };
new GUIFrame(new RectTransform(Vector2.One, submarinePreviewBackground.RectTransform), "InnerGlow", color: Color.Black) { CanBeFocused = false };
}
new GUIFrame(new RectTransform(Vector2.One * 0.12f, previewButton.RectTransform, anchor: Anchor.BottomRight, pivot: Pivot.BottomRight, scaleBasis: ScaleBasis.BothHeight)
{
AbsoluteOffset = new Point((int)(0.03f * previewButton.Rect.Height))
},
"ExpandButton", Color.White)
{
Color = Color.White,
HoverColor = Color.White,
PressedColor = Color.White
};
var descriptionBox = new GUIListBox(new RectTransform(new Vector2(1, 0.5f), content.RectTransform, Anchor.BottomCenter))
{
UserData = "descriptionbox",
@@ -59,36 +81,25 @@ namespace Barotrauma
ScalableFont font = parent.Rect.Width < 350 ? GUI.SmallFont : GUI.Font;
CreateSpecsWindow(descriptionBox, font);
//space
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), descriptionBox.Content.RectTransform), style: null);
if (!string.IsNullOrEmpty(Description))
{
new GUITextBlock(new RectTransform(new Vector2(1, 0), descriptionBox.Content.RectTransform),
TextManager.Get("SaveSubDialogDescription", fallBackTag: "WorkshopItemDescription"), font: GUI.Font, wrap: true)
{ CanBeFocused = false, ForceUpperCase = true };
}
new GUITextBlock(new RectTransform(new Vector2(1, 0), descriptionBox.Content.RectTransform), Description, font: font, wrap: true)
{
CanBeFocused = false
};
CreateSpecsWindow(descriptionBox, font, includesDescription: true);
}
public void CreateSpecsWindow(GUIListBox parent, ScalableFont font)
public void CreateSpecsWindow(GUIListBox parent, ScalableFont font, bool includeTitle = true, bool includesDescription = false)
{
float leftPanelWidth = 0.6f;
float rightPanelWidth = 0.4f / leftPanelWidth;
float rightPanelWidth = 0.4f;
string className = !HasTag(SubmarineTag.Shuttle) ? TextManager.Get($"submarineclass.{SubmarineClass}") : TextManager.Get("shuttle");
int nameHeight = (int)GUI.LargeFont.MeasureString(DisplayName, true).Y;
int classHeight = (int)GUI.SubHeadingFont.MeasureString(className).Y;
int leftPanelWidthInt = (int)(parent.Rect.Width * leftPanelWidth);
var submarineNameText = new GUITextBlock(new RectTransform(new Point(leftPanelWidthInt, nameHeight + HUDLayoutSettings.Padding / 2), parent.Content.RectTransform), DisplayName, textAlignment: Alignment.CenterLeft, font: GUI.LargeFont) { CanBeFocused = false };
submarineNameText.RectTransform.MinSize = new Point(0, (int)submarineNameText.TextSize.Y);
GUITextBlock submarineNameText = null;
if (includeTitle)
{
int nameHeight = (int)GUI.LargeFont.MeasureString(DisplayName, true).Y;
submarineNameText = new GUITextBlock(new RectTransform(new Point(leftPanelWidthInt, nameHeight + HUDLayoutSettings.Padding / 2), parent.Content.RectTransform), DisplayName, textAlignment: Alignment.CenterLeft, font: GUI.LargeFont) { CanBeFocused = false };
submarineNameText.RectTransform.MinSize = new Point(0, (int)submarineNameText.TextSize.Y);
}
var submarineClassText = new GUITextBlock(new RectTransform(new Point(leftPanelWidthInt, classHeight), parent.Content.RectTransform), className, textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont) { CanBeFocused = false };
submarineClassText.RectTransform.MinSize = new Point(0, (int)submarineClassText.TextSize.Y);
@@ -152,8 +163,30 @@ namespace Barotrauma
versionText.RectTransform.MinSize = new Point(0, versionText.Children.First().Rect.Height);
}
submarineNameText.AutoScaleHorizontal = true;
GUITextBlock.AutoScaleAndNormalize(parent.Content.Children.Where(c => c is GUITextBlock && c != submarineNameText).Cast<GUITextBlock>());
if (submarineNameText != null)
{
submarineNameText.AutoScaleHorizontal = true;
}
GUITextBlock descBlock = null;
if (includesDescription)
{
//space
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), parent.Content.RectTransform), style: null);
if (!string.IsNullOrEmpty(Description))
{
var wsItemDesc = new GUITextBlock(new RectTransform(new Vector2(1, 0), parent.Content.RectTransform),
TextManager.Get("SaveSubDialogDescription", fallBackTag: "WorkshopItemDescription"), font: GUI.Font, wrap: true)
{ CanBeFocused = false, ForceUpperCase = true };
descBlock = new GUITextBlock(new RectTransform(new Vector2(1, 0), parent.Content.RectTransform), Description, font: font, wrap: true)
{
CanBeFocused = false
};
}
}
GUITextBlock.AutoScaleAndNormalize(parent.Content.GetAllChildren<GUITextBlock>().Where(c => c != submarineNameText && c != descBlock));
}
}
}
@@ -1,4 +1,5 @@
using Barotrauma.IO;
using Barotrauma.Extensions;
using Barotrauma.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
@@ -83,28 +84,94 @@ namespace Barotrauma
};
var innerFrame = new GUIFrame(new RectTransform(Vector2.One * 0.9f, previewFrame.RectTransform, Anchor.Center));
var verticalLayout = new GUILayoutGroup(new RectTransform(Vector2.One * 0.95f, innerFrame.RectTransform, Anchor.Center), isHorizontal: false);
var topLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.1f), verticalLayout.RectTransform, Anchor.Center), isHorizontal: true, childAnchor: Anchor.CenterLeft);
new GUITextBlock(new RectTransform(new Vector2(0.95f, 1f), topLayout.RectTransform), subInfo.DisplayName, font: GUI.LargeFont);
new GUIButton(new RectTransform(new Vector2(0.05f, 1f), topLayout.RectTransform), TextManager.Get("Close"))
int innerPadding = GUI.IntScale(100f);
var innerPadded = new GUIFrame(new RectTransform(new Point(innerFrame.Rect.Width - innerPadding, innerFrame.Rect.Height - innerPadding), previewFrame.RectTransform, Anchor.Center), style: null)
{
OnClicked = (btn, obj) => { Dispose(); return false; }
OutlineColor = Color.Black,
OutlineThickness = 2
};
new GUICustomComponent(new RectTransform(new Vector2(1f, 0.9f), verticalLayout.RectTransform, Anchor.Center),
(spriteBatch, component) => { camera.UpdateTransform(true); RenderSubmarine(spriteBatch, component.Rect); },
GUITextBlock titleText = null;
GUIListBox specsContainer = null;
new GUICustomComponent(new RectTransform(Vector2.One, innerPadded.RectTransform, Anchor.Center),
(spriteBatch, component) => {
camera.UpdateTransform(interpolate: true, updateListener: false);
Rectangle drawRect = new Rectangle(component.Rect.X + 1, component.Rect.Y + 1, component.Rect.Width - 2, component.Rect.Height - 2);
RenderSubmarine(spriteBatch, drawRect);
},
(deltaTime, component) => {
camera.MoveCamera(deltaTime, overrideMouseOn: component.Rect);
if (component.Rect.Contains(PlayerInput.MousePosition) &&
bool isMouseOnComponent = GUI.MouseOn == component;
camera.MoveCamera(deltaTime, allowZoom: isMouseOnComponent);
if (isMouseOnComponent &&
(PlayerInput.MidButtonHeld() || PlayerInput.LeftButtonHeld()))
{
Vector2 moveSpeed = PlayerInput.MouseSpeed * (float)deltaTime * 60.0f / camera.Zoom;
moveSpeed.X = -moveSpeed.X;
camera.Position += moveSpeed;
}
if (titleText != null && specsContainer != null)
{
specsContainer.Visible = GUI.IsMouseOn(titleText);
}
});
var topContainer = new GUIFrame(new RectTransform(new Vector2(1f, 0.07f), innerPadded.RectTransform, Anchor.TopLeft), style: null)
{
Color = Color.Black * 0.65f
};
var topLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.97f, 5f / 7f), topContainer.RectTransform, Anchor.Center), isHorizontal: true, childAnchor: Anchor.CenterLeft);
titleText = new GUITextBlock(new RectTransform(new Vector2(0.95f, 1f), topLayout.RectTransform), subInfo.DisplayName, font: GUI.LargeFont);
new GUIButton(new RectTransform(new Vector2(0.05f, 1f), topLayout.RectTransform), TextManager.Get("Close"))
{
OnClicked = (btn, obj) => { Dispose(); return false; }
};
specsContainer = new GUIListBox(new RectTransform(new Vector2(0.4f, 1f), innerPadded.RectTransform, Anchor.TopLeft) { RelativeOffset = new Vector2(0.015f, 0.07f) })
{
Color = Color.Black * 0.65f,
ScrollBarEnabled = false,
ScrollBarVisible = false,
Spacing = 5
};
subInfo.CreateSpecsWindow(specsContainer, GUI.Font, includeTitle: false, includesDescription: true);
int width = specsContainer.Rect.Width;
void recalculateSpecsContainerHeight()
{
int totalSize = 0;
var children = specsContainer.Content.Children.Where(c => c.Visible);
foreach (GUIComponent child in children)
{
totalSize += child.Rect.Height;
}
totalSize += specsContainer.Content.CountChildren * specsContainer.Spacing;
if (specsContainer.PadBottom)
{
GUIComponent last = specsContainer.Content.Children.LastOrDefault();
if (last != null)
{
totalSize += specsContainer.Rect.Height - last.Rect.Height;
}
}
specsContainer.RectTransform.Resize(new Point(width, totalSize), true);
specsContainer.RecalculateChildren();
}
//hell
recalculateSpecsContainerHeight();
specsContainer.Content.GetAllChildren<GUITextBlock>().ForEach(c =>
{
var firstChild = c.Children.FirstOrDefault() as GUITextBlock;
if (firstChild != null)
{
firstChild.CalculateHeightFromText(); firstChild.SetTextPos();
c.RectTransform.MinSize = new Point(0, firstChild.Rect.Height);
}
c.CalculateHeightFromText(); c.SetTextPos();
});
recalculateSpecsContainerHeight();
GeneratePreviewMeshes();
}
@@ -15,7 +15,7 @@ namespace Barotrauma.Networking
public static void ClientRead(IReadMessage msg)
{
UInt16 ID = msg.ReadUInt16();
UInt16 id = msg.ReadUInt16();
ChatMessageType type = (ChatMessageType)msg.ReadByte();
PlayerConnectionChangeType changeType = PlayerConnectionChangeType.None;
string txt = "";
@@ -114,7 +114,7 @@ namespace Barotrauma.Networking
if (orderIndex < 0 || orderIndex >= Order.PrefabList.Count)
{
DebugConsole.ThrowError("Invalid order message - order index out of bounds.");
if (NetIdUtils.IdMoreRecent(ID, LastID)) { LastID = ID; }
if (NetIdUtils.IdMoreRecent(id, LastID)) { LastID = id; }
return;
}
else
@@ -155,11 +155,11 @@ namespace Barotrauma.Networking
}
}
if (NetIdUtils.IdMoreRecent(ID, LastID))
if (NetIdUtils.IdMoreRecent(id, LastID))
{
GameMain.Client.AddChatMessage(
new OrderChatMessage(orderPrefab, orderOption, orderPriority, txt, orderTargetPosition ?? targetEntity as ISpatialEntity, targetCharacter, senderCharacter));
LastID = ID;
LastID = id;
}
return;
case ChatMessageType.ServerMessageBox:
@@ -171,7 +171,7 @@ namespace Barotrauma.Networking
break;
}
if (NetIdUtils.IdMoreRecent(ID, LastID))
if (NetIdUtils.IdMoreRecent(id, LastID))
{
switch (type)
{
@@ -200,7 +200,7 @@ namespace Barotrauma.Networking
GameMain.Client.AddChatMessage(txt, type, senderName, senderCharacter, changeType);
break;
}
LastID = ID;
LastID = id;
}
}
}
@@ -159,6 +159,12 @@ namespace Barotrauma.Networking
get { return entityEventManager; }
}
public bool? WaitForNextRoundRespawn
{
get;
set;
}
private readonly object serverEndpoint;
private readonly int ownerKey;
private readonly bool steamP2POwner;
@@ -185,10 +191,10 @@ namespace Barotrauma.Networking
CanBeFocused = false
};
cameraFollowsSub = new GUITickBox(new RectTransform(new Vector2(0.05f, 0.05f), inGameHUD.RectTransform, anchor: Anchor.TopCenter)
cameraFollowsSub = new GUITickBox(new RectTransform(new Vector2(0.05f, 0.05f), inGameHUD.RectTransform, anchor: Anchor.TopCenter, pivot: Pivot.CenterLeft)
{
AbsoluteOffset = new Point(0, 5),
MaxSize = new Point(25, 25)
AbsoluteOffset = new Point(0, HUDLayoutSettings.ButtonAreaTop.Y + HUDLayoutSettings.ButtonAreaTop.Height / 2),
MaxSize = new Point(GUI.IntScale(25))
}, TextManager.Get("CamFollowSubmarine"))
{
Selected = Camera.FollowSub,
@@ -1424,6 +1430,8 @@ namespace Barotrauma.Networking
EndVoteTickBox.Selected = false;
WaitForNextRoundRespawn = null;
roundInitStatus = RoundInitStatus.Starting;
int seed = inc.ReadInt32();
@@ -1690,13 +1698,15 @@ namespace Barotrauma.Networking
}
foreach (Submarine sub in Submarine.MainSubs[i].DockedTo)
{
if (sub.Info.Type == SubmarineType.Outpost) { continue; }
sub.TeamID = teamID;
}
}
if (respawnAllowed)
{
respawnManager = new RespawnManager(this, GameMain.NetLobbyScreen.UsingShuttle && gameMode != GameModePreset.MultiPlayerCampaign ? GameMain.NetLobbyScreen.SelectedShuttle : null);
if (respawnAllowed)
{
bool isOutpost = GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign && Level.Loaded?.Type == LevelData.LevelType.Outpost;
respawnManager = new RespawnManager(this, GameMain.NetLobbyScreen.UsingShuttle && !isOutpost ? GameMain.NetLobbyScreen.SelectedShuttle : null);
}
gameStarted = true;
@@ -1739,6 +1749,7 @@ namespace Barotrauma.Networking
gameStarted = false;
Character.Controlled = null;
WaitForNextRoundRespawn = null;
SpawnAsTraitor = false;
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
GameMain.LightManager.LosEnabled = false;
@@ -1965,14 +1976,19 @@ namespace Barotrauma.Networking
}
foreach (Client client in ConnectedClients)
{
if (!previouslyConnectedClients.Any(c => c.ID == client.ID))
int index = previouslyConnectedClients.FindIndex(c => c.ID == client.ID);
if (index < 0)
{
while (previouslyConnectedClients.Count > 100)
if (previouslyConnectedClients.Count > 100)
{
previouslyConnectedClients.RemoveAt(0);
previouslyConnectedClients.RemoveRange(0, previouslyConnectedClients.Count - 100);
}
previouslyConnectedClients.Add(client);
}
else
{
previouslyConnectedClients.RemoveAt(index);
}
previouslyConnectedClients.Add(client);
}
if (updateClientListId) { LastClientListUpdateID = listId; }
@@ -2452,6 +2468,15 @@ namespace Barotrauma.Networking
chatMsgQueue.Add(chatMessage);
}
public void SendRespawnPromptResponse(bool waitForNextRoundRespawn)
{
WaitForNextRoundRespawn = waitForNextRoundRespawn;
IWriteMessage msg = new WriteOnlyMessage();
msg.Write((byte)ClientPacketHeader.READY_TO_SPAWN);
msg.Write((bool)waitForNextRoundRespawn);
clientPeer?.Send(msg, DeliveryMethod.Reliable);
}
public void RequestFile(FileTransferType fileType, string file, string fileHash)
{
IWriteMessage msg = new WriteOnlyMessage();
@@ -3143,11 +3168,11 @@ namespace Barotrauma.Networking
cameraFollowsSub.Visible = Character.Controlled == null;
}
if (Character.Controlled == null || Character.Controlled.IsDead)
/*if (Character.Controlled == null || Character.Controlled.IsDead)
{
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
GameMain.LightManager.LosEnabled = false;
}
}*/
}
//tab doesn't autoselect the chatbox when debug console is open,
@@ -3255,9 +3280,10 @@ namespace Barotrauma.Networking
if (respawnManager != null)
{
string respawnText = "";
string respawnText = string.Empty;
float textScale = 1.0f;
Color textColor = Color.White;
bool canChooseRespawn = GameMain.GameSession.GameMode is CampaignMode && Character.Controlled == null && Level.Loaded?.Type != LevelData.LevelType.Outpost;
if (respawnManager.CurrentState == RespawnManager.State.Waiting &&
respawnManager.RespawnCountdownStarted)
{
@@ -3275,18 +3301,18 @@ namespace Barotrauma.Networking
{
//oscillate between 0-1
float phase = (float)(Math.Sin(timeLeft * MathHelper.Pi) + 1.0f) * 0.5f;
textScale = 1.0f + phase * 0.5f;
//textScale = 1.0f + phase * 0.5f;
textColor = Color.Lerp(GUI.Style.Red, Color.White, 1.0f - phase);
}
canChooseRespawn = false;
}
if (!string.IsNullOrEmpty(respawnText))
{
GUI.SmallFont.DrawString(spriteBatch, respawnText, new Vector2(120.0f, 10), textColor, 0.0f, Vector2.Zero, textScale, Microsoft.Xna.Framework.Graphics.SpriteEffects.None, 0.0f);
}
GameMain.GameSession?.SetRespawnInfo(
visible: !string.IsNullOrEmpty(respawnText) || canChooseRespawn, text: respawnText, textColor: textColor,
buttonsVisible: canChooseRespawn, waitForNextRoundRespawn: (WaitForNextRoundRespawn ?? true));
}
if (!ShowNetStats) return;
if (!ShowNetStats) { return; }
NetStats.Draw(spriteBatch, new Rectangle(300, 10, 300, 150));
@@ -473,7 +473,36 @@ namespace Barotrauma
SelectedColor = MapGenerationParams.Instance.IndicatorColor,
HoverColor = Color.Lerp(MapGenerationParams.Instance.IndicatorColor, Color.White, 0.5f)
};
missionName.Padding = new Vector4(missionName.Padding.X + icon.Rect.Width * 1.5f, missionName.Padding.Y, missionName.Padding.Z, missionName.Padding.W);
icon.RectTransform.IsFixedSize = true;
GUILayoutGroup difficultyIndicatorGroup = null;
if (mission.Difficulty.HasValue)
{
difficultyIndicatorGroup = new GUILayoutGroup(new RectTransform(Vector2.One * 0.9f, missionName.RectTransform, anchor: Anchor.CenterRight, scaleBasis: ScaleBasis.Smallest) { AbsoluteOffset = new Point((int)missionName.Padding.Z, 0) },
isHorizontal: true, childAnchor: Anchor.CenterRight)
{
AbsoluteSpacing = 1,
UserData = "difficulty"
};
var difficultyColor = mission.GetDifficultyColor();
for (int i = 0; i < mission.Difficulty; i++)
{
new GUIImage(new RectTransform(Vector2.One, difficultyIndicatorGroup.RectTransform, scaleBasis: ScaleBasis.Smallest) { IsFixedSize = true }, "DifficultyIndicator", scaleToFit: true)
{
Color = difficultyColor * 0.5f,
SelectedColor = difficultyColor,
HoverColor = Color.Lerp(difficultyColor, Color.White, 0.5f)
};
}
}
float extraPadding = 0.5f * icon.Rect.Width;
float extraZPadding = difficultyIndicatorGroup != null ? mission.Difficulty.Value * (difficultyIndicatorGroup.Children.First().Rect.Width + difficultyIndicatorGroup.AbsoluteSpacing) : 0;
missionName.Padding = new Vector4(missionName.Padding.X + icon.Rect.Width + extraPadding,
missionName.Padding.Y,
missionName.Padding.Z + extraZPadding + extraPadding,
missionName.Padding.W);
missionName.CalculateHeightFromText();
}
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), mission.GetMissionRewardText(), wrap: true, parseRichText: true);
@@ -494,6 +523,10 @@ namespace Barotrauma
missionPanel.OnAddedToGUIUpdateList = (c) =>
{
missionTextContent.Children.ForEach(child => child.State = c.State);
if (missionTextContent.FindChild("difficulty", recursive: true) is GUILayoutGroup group)
{
group.State = c.State;
}
};
if (mission != availableMissions.Last())
@@ -171,10 +171,7 @@ namespace Barotrauma
Character.Controlled.ObstructVision &&
(Character.Controlled.ViewTarget == Character.Controlled || Character.Controlled.ViewTarget == null);
if (Character.Controlled != null)
{
GameMain.LightManager.UpdateObstructVision(graphics, spriteBatch, cam, Character.Controlled.CursorWorldPosition);
}
GameMain.LightManager.UpdateObstructVision(graphics, spriteBatch, cam, Character.Controlled?.CursorWorldPosition ?? Vector2.Zero);
//------------------------------------------------------------------------
graphics.SetRenderTarget(renderTarget);
@@ -334,12 +331,13 @@ namespace Barotrauma
}
spriteBatch.End();
if (GameMain.LightManager.LosEnabled && GameMain.LightManager.LosMode != LosMode.None && Character.Controlled != null)
if (GameMain.LightManager.LosEnabled && GameMain.LightManager.LosMode != LosMode.None && Lights.LightManager.ViewTarget != null)
{
GameMain.LightManager.LosEffect.CurrentTechnique = GameMain.LightManager.LosEffect.Techniques["LosShader"];
GameMain.LightManager.LosEffect.Parameters["xTexture"].SetValue(renderTargetBackground);
GameMain.LightManager.LosEffect.Parameters["xLosTexture"].SetValue(GameMain.LightManager.LosTexture);
GameMain.LightManager.LosEffect.Parameters["xLosAlpha"].SetValue(GameMain.LightManager.LosAlpha);
Color losColor;
if (GameMain.LightManager.LosMode == LosMode.Transparent)
@@ -348,6 +348,16 @@ namespace Barotrauma
CanBeFocused = false
};
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), optionList.RectTransform), TextManager.Get("EditorDisclaimerWikiLink"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
{
ForceUpperCase = true,
OnClicked = (button, userData) =>
{
string url = TextManager.Get("EditorDisclaimerWikiUrl", returnNull: true) ?? "https://barotraumagame.com/wiki";
GameMain.Instance.ShowOpenUrlInWebBrowserPrompt(url, promptExtensionTag: "wikinotice");
return true;
}
};
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), optionList.RectTransform), TextManager.Get("CreditsButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
{
ForceUpperCase = true,
@@ -1305,9 +1305,9 @@ namespace Barotrauma
StartButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ManageRound) && !GameMain.Client.GameStarted && !CampaignSetupFrame.Visible && !CampaignFrame.Visible;
ServerName.Readonly = !GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
ServerMessage.Readonly = !GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
shuttleTickBox.Enabled = !CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
shuttleTickBox.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
SubList.Enabled = !CampaignFrame.Visible && (GameMain.Client.ServerSettings.Voting.AllowSubVoting || GameMain.Client.HasPermission(ClientPermissions.SelectSub));
shuttleList.Enabled = shuttleList.ButtonEnabled = shuttleTickBox.Enabled = !CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.SelectSub);
shuttleList.Enabled = shuttleList.ButtonEnabled = GameMain.Client.HasPermission(ClientPermissions.SelectSub);
ModeList.Enabled = GameMain.Client.ServerSettings.Voting.AllowModeVoting || GameMain.Client.HasPermission(ClientPermissions.SelectMode);
LogButtons.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
GameMain.Client.ShowLogButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
@@ -533,20 +533,6 @@ namespace Barotrauma
OnSelected = (GUITickBox obj) =>
{
lightingEnabled = obj.Selected;
if (lightingEnabled)
{
//turn off lights that are inside containers
foreach (Item item in Item.ItemList)
{
foreach (LightComponent lightComponent in item.GetComponents<LightComponent>())
{
lightComponent.Light.Color = item.Container != null || (item.body != null && !item.body.Enabled) ?
Color.Transparent :
lightComponent.LightColor;
lightComponent.Light.LightSpriteEffect = lightComponent.Item.SpriteEffects;
}
}
}
return true;
}
};
@@ -2704,16 +2690,6 @@ namespace Barotrauma
cam.Position = Submarine.MainSub.Position + Submarine.MainSub.HiddenSubPosition;
loadFrame = null;
//turn off lights that are inside an inventory (cabinet for example)
foreach (Item item in Item.ItemList)
{
var lightComponent = item.GetComponent<LightComponent>();
if (lightComponent != null)
{
lightComponent.Light.Enabled = item.ParentInventory == null;
}
}
}
private bool LoadSub(GUIButton button, object obj)
@@ -2748,16 +2724,6 @@ namespace Barotrauma
loadFrame = null;
//turn off lights that are inside an inventory (cabinet for example)
foreach (Item item in Item.ItemList)
{
var lightComponent = item.GetComponent<LightComponent>();
if (lightComponent != null)
{
lightComponent.Light.Enabled = item.ParentInventory == null;
}
}
if (selectedSub.Info.GameVersion < new Version("0.8.9.0"))
{
var adjustLightsPrompt = new GUIMessageBox(TextManager.Get("Warning"), TextManager.Get("AdjustLightsPrompt"),
@@ -2857,8 +2823,8 @@ namespace Barotrauma
categorizedEntityList.UpdateScrollBarSize();
categorizedEntityList.BarScroll = 0.0f;
categorizedEntityList.Visible = true;
allEntityList.Visible = false;
// categorizedEntityList.Visible = true;
// allEntityList.Visible = false;
}
private void FilterEntities(string filter)
@@ -3047,6 +3013,37 @@ namespace Barotrauma
public static GUIMessageBox CreatePropertyColorPicker(Color originalColor, SerializableProperty property, ISerializableEntity entity)
{
var entities = new List<(ISerializableEntity Entity, Color OriginalColor, SerializableProperty Property)> { (entity, originalColor, property) };
foreach (ISerializableEntity selectedEntity in MapEntity.SelectedList.Where(selectedEntity => selectedEntity is ISerializableEntity && entity != selectedEntity).Cast<ISerializableEntity>())
{
switch (entity)
{
case ItemComponent _ when selectedEntity is Item item:
foreach (var component in item.Components)
{
if (component.GetType() == entity.GetType() && component != entity)
{
entities.Add((component, (Color) property.GetValue(component), property));
}
}
break;
default:
if (selectedEntity.GetType() == entity.GetType())
{
entities.Add((selectedEntity, (Color) property.GetValue(selectedEntity), property));
}
else if (selectedEntity is { SerializableProperties: { } props} )
{
if (props.TryGetValue(property.NameToLowerInvariant, out SerializableProperty foundProp))
{
entities.Add((selectedEntity, (Color) foundProp.GetValue(selectedEntity), foundProp));
}
}
break;
}
}
bool setValues = true;
object sliderMutex = new object(),
sliderTextMutex = new object(),
@@ -3142,9 +3139,22 @@ namespace Barotrauma
colorPicker.DisposeTextures();
msgBox.Close();
if (entity is MapEntity { Removed: true } me) { return true; }
Color newColor = SetColor(null);
StoreCommand(new PropertyCommand(entity, property.Name, newColor, originalColor));
Dictionary<object, List<ISerializableEntity>> oldProperties = new Dictionary<object, List<ISerializableEntity>>();
foreach (var (sEntity, color, _) in entities)
{
if (sEntity is MapEntity { Removed: true }) { continue; }
if (!oldProperties.ContainsKey(color))
{
oldProperties.Add(color, new List<ISerializableEntity>());
}
oldProperties[color].Add(sEntity);
}
List<ISerializableEntity> affected = entities.Select(t => t.Entity).Where(se => se is MapEntity { Removed: false }).ToList();
StoreCommand(new PropertyCommand(affected, property.Name, newColor, oldProperties));
if (MapEntity.EditingHUD != null && (MapEntity.EditingHUD.UserData == entity || (!(entity is ItemComponent ic) || MapEntity.EditingHUD.UserData == ic.Item)))
{
@@ -3170,8 +3180,12 @@ namespace Barotrauma
{
colorPicker.DisposeTextures();
msgBox.Close();
if (entity is MapEntity { Removed: true } me) { return true; }
property.SetValue(entity, originalColor);
foreach (var (e, color, prop) in entities)
{
if (e is MapEntity { Removed: true }) { continue; }
prop.TrySetValue(e, color);
}
return true;
};
@@ -3218,8 +3232,12 @@ namespace Barotrauma
}
Color color = ToolBox.HSVToRGB(colorPicker.SelectedHue, colorPicker.SelectedSaturation, colorPicker.SelectedValue);
color.A = originalColor.A;
property.TrySetValue(entity, color);
foreach (var (e, origColor, prop) in entities)
{
if (e is MapEntity { Removed: true }) { continue; }
color.A = origColor.A;
prop.TrySetValue(e, color);
}
return color;
void SetSliders(Vector3 hsv)
@@ -3238,9 +3256,11 @@ namespace Barotrauma
void SetColorPicker(Vector3 hsv)
{
bool hueChanged = !MathUtils.NearlyEqual(colorPicker.SelectedHue, hsv.X);
colorPicker.SelectedHue = hsv.X;
colorPicker.SelectedSaturation = hsv.Y;
colorPicker.SelectedValue = hsv.Z;
if (hueChanged) { colorPicker.RefreshHue(); }
}
void SetHex(Vector3 hsv)
@@ -3496,6 +3516,8 @@ namespace Barotrauma
private bool SelectPrefab(GUIComponent component, object obj)
{
allEntityList.Deselect();
categorizedEntityList.Deselect();
if (GUI.MouseOn is GUIButton || GUI.MouseOn?.Parent is GUIButton) { return false; }
AddPreviouslyUsed(obj as MapEntityPrefab);
@@ -3586,7 +3608,7 @@ namespace Barotrauma
SoundPlayer.PlayUISound(GUISoundType.PickItem);
MapEntityPrefab.SelectPrefab(obj);
}
return false;
}
@@ -4332,6 +4354,17 @@ namespace Barotrauma
if (lightingEnabled)
{
//turn off lights that are inside containers
foreach (Item item in Item.ItemList)
{
foreach (LightComponent lightComponent in item.GetComponents<LightComponent>())
{
lightComponent.Light.Color = item.Container != null || (item.body != null && !item.body.Enabled) ?
Color.Transparent :
lightComponent.LightColor;
lightComponent.Light.LightSpriteEffect = lightComponent.Item.SpriteEffects;
}
}
GameMain.LightManager?.Update((float)deltaTime);
}
@@ -1208,7 +1208,7 @@ namespace Barotrauma
SafeAdd((ISerializableEntity) entity, property);
property.PropertyInfo.SetValue(entity, value);
}
else if (entity is ISerializableEntity sEntity && sEntity.SerializableProperties != null)
else if (entity is ISerializableEntity { SerializableProperties: { } } sEntity)
{
var props = sEntity.SerializableProperties;
@@ -30,6 +30,7 @@ namespace Barotrauma.Sounds
public override int FillStreamBuffer(int samplePos, short[] buffer)
{
if (!Stream) throw new Exception("Called FillStreamBuffer on a non-streamed sound!");
if (reader == null) throw new Exception("Called FillStreamBuffer when the reader is null!");
if (samplePos >= reader.TotalSamples * reader.Channels * 2) return 0;
@@ -73,6 +74,8 @@ namespace Barotrauma.Sounds
{
if (!Stream)
{
reader ??= new VorbisReader(Filename);
reader.DecodedPosition = 0;
int bufferSize = (int)reader.TotalSamples * reader.Channels;
@@ -126,7 +129,7 @@ namespace Barotrauma.Sounds
{
if (Stream)
{
reader.Dispose();
reader?.Dispose();
}
base.Dispose();
@@ -14,35 +14,15 @@ namespace Barotrauma.Sounds
get { return disposed; }
}
public SoundManager Owner
{
get;
protected set;
}
public readonly SoundManager Owner;
public string Filename
{
get;
protected set;
}
public readonly string Filename;
public XElement XElement
{
get;
protected set;
}
public readonly XElement XElement;
public bool Stream
{
get;
protected set;
}
public readonly bool Stream;
public bool StreamsReliably
{
get;
protected set;
}
public readonly bool StreamsReliably;
public virtual SoundManager.SourcePoolIndex SourcePoolIndex
{
@@ -79,10 +59,10 @@ namespace Barotrauma.Sounds
public float BaseNear;
public float BaseFar;
public Sound(SoundManager owner, string filename, bool stream, bool streamsReliably, XElement xElement=null)
public Sound(SoundManager owner, string filename, bool stream, bool streamsReliably, XElement xElement=null, bool getFullPath=true)
{
Owner = owner;
Filename = Path.GetFullPath(filename.CleanUpPath()).CleanUpPath();
Filename = getFullPath ? Path.GetFullPath(filename.CleanUpPath()).CleanUpPath() : filename;
Stream = stream;
StreamsReliably = streamsReliably;
XElement = xElement;
@@ -21,12 +21,14 @@ namespace Barotrauma
public readonly string requiredTag;
public DamageSound(Sound sound, Vector2 damageRange, string damageType, string requiredTag = "")
public bool ignoreMuffling;
public DamageSound(Sound sound, Vector2 damageRange, string damageType, bool ignoreMuffling, string requiredTag = "")
{
this.sound = sound;
this.damageRange = damageRange;
this.damageType = damageType;
this.ignoreMuffling = ignoreMuffling;
this.requiredTag = requiredTag;
}
}
@@ -269,6 +271,7 @@ namespace Barotrauma
damageSound,
soundElement.GetAttributeVector2("damagerange", Vector2.Zero),
damageSoundType,
soundElement.GetAttributeBool("ignoremuffling", false),
soundElement.GetAttributeString("requiredtag", "")));
break;
@@ -531,7 +534,7 @@ namespace Barotrauma
Vector2 diff = gap.WorldPosition - listenerPos;
if (Math.Abs(diff.X) < FlowSoundRange && Math.Abs(diff.Y) < FlowSoundRange)
{
if (gap.Open < 0.01f) { continue; }
if (gap.Open < 0.01f || gap.LerpedFlowForce.LengthSquared() < 100.0f) { continue; }
float gapFlow = Math.Abs(gap.LerpedFlowForce.X) + Math.Abs(gap.LerpedFlowForce.Y) * 2.5f;
if (!gap.IsRoomToRoom) { gapFlow *= 2.0f; }
if (gapFlow < 10.0f) { continue; }
@@ -1123,7 +1126,11 @@ namespace Barotrauma
tempList.Add(s);
}
}
tempList.GetRandom().sound?.Play(1.0f, range, position, muffle: ShouldMuffleSound(Character.Controlled, position, range, null));
var damageSound = tempList.GetRandom();
if (damageSound.sound != null)
{
damageSound.sound.Play(1.0f, range, position, muffle: !damageSound.ignoreMuffling && ShouldMuffleSound(Character.Controlled, position, range, null));
}
}
public static void PlayUISound(GUISoundType soundType)
@@ -63,10 +63,8 @@ namespace Barotrauma.Sounds
get { return soundChannel?.CurrentAmplitude ?? 0.0f; }
}
public VoipSound(string name, SoundManager owner, VoipQueue q) : base(owner, "voip", true, true)
public VoipSound(string name, SoundManager owner, VoipQueue q) : base(owner, $"VoIP ({name})", true, true, getFullPath: false)
{
Filename = $"VoIP ({name})";
VoipConfig.SetupEncoding();
ALFormat = Al.FormatMono16;