(6d989732) Unstable v0.9.708.0

This commit is contained in:
Juan Pablo Arce
2020-02-12 16:05:02 -03:00
parent 2783125162
commit 27e10f7c2e
37 changed files with 420 additions and 345 deletions
@@ -302,8 +302,9 @@ namespace Barotrauma
{ {
if (character.Info != null) if (character.Info != null)
{ {
character.Info.DrawPortrait(spriteBatch, HUDLayoutSettings.PortraitArea.Location.ToVector2(), targetWidth: HUDLayoutSettings.PortraitArea.Width); character.Info.DrawBackground(spriteBatch);
character.Info.DrawJobIcon(spriteBatch); character.Info.DrawJobIcon(spriteBatch, scale: 1.25f);
character.Info.DrawPortrait(spriteBatch, HUDLayoutSettings.PortraitArea.Location.ToVector2(), new Vector2((int)(-4 * GUI.Scale), (int)(2 * GUI.Scale)), targetWidth: HUDLayoutSettings.PortraitArea.Width, true);
} }
mouseOnPortrait = HUDLayoutSettings.PortraitArea.Contains(PlayerInput.MousePosition) && !character.ShouldLockHud(); mouseOnPortrait = HUDLayoutSettings.PortraitArea.Contains(PlayerInput.MousePosition) && !character.ShouldLockHud();
if (mouseOnPortrait) if (mouseOnPortrait)
@@ -352,7 +353,7 @@ namespace Barotrauma
GUIComponent.DrawToolTip( GUIComponent.DrawToolTip(
spriteBatch, spriteBatch,
character.Info?.Job == null ? character.DisplayName : character.Name + " (" + character.Info.Job.Name + ")", character.Info?.Job == null ? character.DisplayName : character.Name + " (" + character.Info.Job.Name + ")",
HUDLayoutSettings.PortraitTooltipArea); HUDLayoutSettings.PortraitArea);
} }
} }
@@ -10,6 +10,24 @@ namespace Barotrauma
{ {
partial class CharacterInfo partial class CharacterInfo
{ {
public const float BgScale = 1.2f;
private static Sprite infoAreaPortraitBG;
private static Vector2 infoBGPosition;
private static Vector2 jobIconPos;
public static void Init()
{
GameMain.Instance.OnResolutionChanged += SetUILayout;
infoAreaPortraitBG = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(833, 298, 142, 98), null, 0);
SetUILayout();
}
private static void SetUILayout()
{
jobIconPos = HUDLayoutSettings.BottomRightInfoArea.Center.ToVector2() + new Vector2(12 * GUI.Scale, 24 * GUI.Scale);
infoBGPosition = HUDLayoutSettings.BottomRightInfoArea.Location.ToVector2();
}
public GUIFrame CreateInfoFrame(GUIFrame frame) public GUIFrame CreateInfoFrame(GUIFrame frame)
{ {
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), frame.RectTransform, Anchor.TopCenter) { RelativeOffset = new Vector2(0.0f, 0.1f) }) var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), frame.RectTransform, Anchor.TopCenter) { RelativeOffset = new Vector2(0.0f, 0.1f) })
@@ -160,24 +178,25 @@ namespace Barotrauma
sprite.SourceRect = new Rectangle(location, sprite.SourceRect.Size); sprite.SourceRect = new Rectangle(location, sprite.SourceRect.Size);
} }
public void DrawPortrait(SpriteBatch spriteBatch, Vector2 screenPos, float targetWidth, bool flip = false) public void DrawBackground(SpriteBatch spriteBatch)
{
infoAreaPortraitBG.Draw(spriteBatch, infoBGPosition, Color.White, Vector2.Zero, 0.0f,
scale: new Vector2(
HUDLayoutSettings.BottomRightInfoArea.Width / (float)infoAreaPortraitBG.SourceRect.Width,
HUDLayoutSettings.BottomRightInfoArea.Height / (float)infoAreaPortraitBG.SourceRect.Height));
}
public void DrawPortrait(SpriteBatch spriteBatch, Vector2 screenPos, Vector2 offset, float targetWidth, bool flip = false)
{ {
float backgroundScale = 1;
if (PortraitBackground != null)
{
backgroundScale = targetWidth / PortraitBackground.size.X;
PortraitBackground.Draw(spriteBatch, screenPos, scale: backgroundScale);
}
if (Portrait != null) if (Portrait != null)
{ {
// Scale down the head sprite 10% // Scale down the head sprite 10%
float scale = targetWidth * 0.9f / Portrait.size.X; float scale = targetWidth * 0.9f / Portrait.size.X;
Vector2 offset = Portrait.size * backgroundScale / 4;
if (Head.SheetIndex.HasValue) if (Head.SheetIndex.HasValue)
{ {
Portrait.SourceRect = new Rectangle(CalculateOffset(Portrait, Head.SheetIndex.Value.ToPoint()), Portrait.SourceRect.Size); Portrait.SourceRect = new Rectangle(CalculateOffset(Portrait, Head.SheetIndex.Value.ToPoint()), Portrait.SourceRect.Size);
} }
Portrait.Draw(spriteBatch, screenPos + offset, scale: scale, spriteEffect: flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None); Portrait.Draw(spriteBatch, screenPos + offset, Color.White, Portrait.Origin, scale: scale, spriteEffect: flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None);
if (AttachmentSprites != null) if (AttachmentSprites != null)
{ {
float depthStep = 0.000001f; float depthStep = 0.000001f;
@@ -216,7 +235,8 @@ namespace Barotrauma
public void DrawJobIcon(SpriteBatch spriteBatch, Vector2? pos = null, float scale = 1.0f) public void DrawJobIcon(SpriteBatch spriteBatch, Vector2? pos = null, float scale = 1.0f)
{ {
if (jobIcon == null) return; if (jobIcon == null) return;
jobIcon.Draw(spriteBatch, pos ?? jobIconPos, Job.Prefab.UIColor, scale: .5f * GUI.Scale * scale); float combinedScale = .5f * GUI.Scale * scale;
jobIcon.Draw(spriteBatch, pos ?? jobIconPos, Job.Prefab.UIColor, scale: combinedScale);
} }
private void DrawAttachmentSprite(SpriteBatch spriteBatch, WearableSprite attachment, Sprite head, Vector2 drawPos, float scale, float depthStep, SpriteEffects spriteEffects = SpriteEffects.None) private void DrawAttachmentSprite(SpriteBatch spriteBatch, WearableSprite attachment, Sprite head, Vector2 drawPos, float scale, float depthStep, SpriteEffects spriteEffects = SpriteEffects.None)
@@ -202,7 +202,7 @@ namespace Barotrauma
if (openHealthWindow == value) return; if (openHealthWindow == value) return;
if (value != null && !value.UseHealthWindow) return; if (value != null && !value.UseHealthWindow) return;
var prevOpenHealthWindow = openHealthWindow; var prevOpenHealthWindow = openHealthWindow;
if (prevOpenHealthWindow != null) if (prevOpenHealthWindow != null)
{ {
@@ -262,18 +262,21 @@ namespace Barotrauma
character.OnAttacked += OnAttacked; character.OnAttacked += OnAttacked;
bool horizontal = true; bool horizontal = true;
healthBar = new GUIProgressBar(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.HealthBarAreaLeft, GUI.Canvas),
barSize: 1.0f, color: GUIColorSettings.HealthBarColorHigh, style: horizontal ? "CharacterHealthBar" : "GUIProgressBarVertical") healthBar = new GUIProgressBar(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.HealthBarArea, GUI.Canvas),
barSize: 1.0f, color: GUIColorSettings.HealthBarColorHigh, style: horizontal ? "GUIProgressBar" : "GUIProgressBarVertical")
{ {
Enabled = true, Enabled = true,
HoverCursor = CursorState.Hand, HoverCursor = CursorState.Hand,
IsHorizontal = horizontal IsHorizontal = horizontal
}; };
healthBarShadow = new GUIProgressBar(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.HealthBarAreaLeft, GUI.Canvas),
barSize: 1.0f, color: Color.Green, style: horizontal ? "CharacterHealthBar" : "GUIProgressBarVertical", showFrame: false) healthBarShadow = new GUIProgressBar(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.HealthBarArea, GUI.Canvas),
barSize: 1.0f, color: Color.Green, style: horizontal ? "GUIProgressBar" : "GUIProgressBarVertical", showFrame: false)
{ {
IsHorizontal = horizontal IsHorizontal = horizontal
}; };
healthBarShadow.Visible = false;
healthShadowSize = 1.0f; healthShadowSize = 1.0f;
healthInterfaceFrame = new GUIFrame(new RectTransform(new Vector2(0.7f, 0.55f), GUI.Canvas, anchor: Anchor.Center, scaleBasis: ScaleBasis.Smallest), style: "ItemUI"); healthInterfaceFrame = new GUIFrame(new RectTransform(new Vector2(0.7f, 0.55f), GUI.Canvas, anchor: Anchor.Center, scaleBasis: ScaleBasis.Smallest), style: "ItemUI");
@@ -390,7 +393,7 @@ namespace Barotrauma
new GUICustomComponent(new RectTransform(new Vector2(0.15f, 1.0f), nameContainer.RectTransform), new GUICustomComponent(new RectTransform(new Vector2(0.15f, 1.0f), nameContainer.RectTransform),
onDraw: (spriteBatch, component) => onDraw: (spriteBatch, component) =>
{ {
character.Info.DrawPortrait(spriteBatch, new Vector2(component.Rect.X, component.Rect.Center.Y - component.Rect.Width / 2), component.Rect.Width); character.Info.DrawPortrait(spriteBatch, new Vector2(component.Rect.X, component.Rect.Center.Y - component.Rect.Width / 2), character.Info.Portrait.size * .25f, component.Rect.Width);
character.Info.DrawJobIcon(spriteBatch, new Vector2(component.Rect.Right + component.Rect.Width, (float)component.Rect.Top + component.Rect.Height * 0.75f), 0.75f); character.Info.DrawJobIcon(spriteBatch, new Vector2(component.Rect.Right + component.Rect.Width, (float)component.Rect.Top + component.Rect.Height * 0.75f), 0.75f);
}); });
characterName = new GUITextBlock(new RectTransform(new Vector2(0.85f, 1.0f), nameContainer.RectTransform), "", textAlignment: Alignment.BottomLeft, font: GUI.SubHeadingFont) characterName = new GUITextBlock(new RectTransform(new Vector2(0.85f, 1.0f), nameContainer.RectTransform), "", textAlignment: Alignment.BottomLeft, font: GUI.SubHeadingFont)
@@ -542,6 +545,14 @@ namespace Barotrauma
inventoryScale = Inventory.UIScale; inventoryScale = Inventory.UIScale;
uiScale = GUI.Scale; uiScale = GUI.Scale;
healthBar.RectTransform.AbsoluteOffset = HUDLayoutSettings.HealthBarArea.Location;
healthBar.RectTransform.NonScaledSize = HUDLayoutSettings.HealthBarArea.Size;
healthBar.RectTransform.RelativeOffset = Vector2.Zero;
healthBarShadow.RectTransform.AbsoluteOffset = HUDLayoutSettings.HealthBarArea.Location;
healthBarShadow.RectTransform.NonScaledSize = HUDLayoutSettings.HealthBarArea.Size;
healthBarShadow.RectTransform.RelativeOffset = Vector2.Zero;
switch (alignment) switch (alignment)
{ {
case Alignment.Left: case Alignment.Left:
@@ -869,7 +880,7 @@ namespace Barotrauma
highlightedLimbIndex = -1; highlightedLimbIndex = -1;
} }
Rectangle hoverArea = Rectangle.Union(HUDLayoutSettings.AfflictionAreaLeft, HUDLayoutSettings.HealthBarAreaLeft); Rectangle hoverArea = Rectangle.Union(HUDLayoutSettings.AfflictionAreaLeft, HUDLayoutSettings.HealthBarArea);
healthBar.CanBeFocused = healthBarShadow.CanBeFocused = !Character.ShouldLockHud(); healthBar.CanBeFocused = healthBarShadow.CanBeFocused = !Character.ShouldLockHud();
if (Character.AllowInput && UseHealthWindow && healthBar.Enabled && healthBar.CanBeFocused && if (Character.AllowInput && UseHealthWindow && healthBar.Enabled && healthBar.CanBeFocused &&
@@ -959,7 +970,7 @@ namespace Barotrauma
public void DrawStatusHUD(SpriteBatch spriteBatch) public void DrawStatusHUD(SpriteBatch spriteBatch)
{ {
//Rectangle interactArea = healthBar.Rect; //Rectangle interactArea = healthBar.Rect;
if (openHealthWindow != this) if (Character.Controlled?.SelectedCharacter == null)
{ {
List<Pair<Affliction, string>> statusIcons = new List<Pair<Affliction, string>>(); List<Pair<Affliction, string>> statusIcons = new List<Pair<Affliction, string>>();
if (Character.CurrentHull == null || Character.CurrentHull.LethalPressure > 5.0f) if (Character.CurrentHull == null || Character.CurrentHull.LethalPressure > 5.0f)
@@ -975,11 +986,12 @@ namespace Barotrauma
Pair<Affliction, string> highlightedIcon = null; Pair<Affliction, string> highlightedIcon = null;
Vector2 highlightedIconPos = Vector2.Zero; Vector2 highlightedIconPos = Vector2.Zero;
Rectangle afflictionArea = HUDLayoutSettings.AfflictionAreaLeft; Rectangle afflictionArea = HUDLayoutSettings.AfflictionAreaLeft;
Point pos = afflictionArea.Location + healthBar.RectTransform.ScreenSpaceOffset;
bool horizontal = afflictionArea.Width > afflictionArea.Height; bool horizontal = afflictionArea.Width > afflictionArea.Height;
int iconSize = horizontal ? afflictionArea.Height : afflictionArea.Width; int iconSize = horizontal ? afflictionArea.Height : afflictionArea.Width;
Point pos = new Point(afflictionArea.Right - iconSize, afflictionArea.Top);
foreach (Pair<Affliction, string> statusIcon in statusIcons) foreach (Pair<Affliction, string> statusIcon in statusIcons)
{ {
Affliction affliction = statusIcon.First; Affliction affliction = statusIcon.First;
@@ -1018,7 +1030,7 @@ namespace Barotrauma
scale: iconSize / afflictionPrefab.Icon.size.X); scale: iconSize / afflictionPrefab.Icon.size.X);
if (horizontal) if (horizontal)
pos.X += iconSize + (int)(5 * GUI.Scale); pos.X -= iconSize + (int)(5 * GUI.Scale);
else else
pos.Y += iconSize + (int)(5 * GUI.Scale); pos.Y += iconSize + (int)(5 * GUI.Scale);
} }
@@ -1800,7 +1812,13 @@ namespace Barotrauma
(int)(limbHealth.HighlightArea.Width * scale), (int)(limbHealth.HighlightArea.Width * scale),
(int)(limbHealth.HighlightArea.Height * scale)); (int)(limbHealth.HighlightArea.Height * scale));
} }
public void SetHealthBarVisibility(bool value)
{
healthBar.Visible = value;
healthBarShadow.Visible = value;
}
public void ClientRead(IReadMessage inc) public void ClientRead(IReadMessage inc)
{ {
List<Pair<AfflictionPrefab, float>> newAfflictions = new List<Pair<AfflictionPrefab, float>>(); List<Pair<AfflictionPrefab, float>> newAfflictions = new List<Pair<AfflictionPrefab, float>>();
@@ -782,6 +782,12 @@ namespace Barotrauma
commands.Add(new Command("lobby|lobbyscreen", "", (string[] args) => commands.Add(new Command("lobby|lobbyscreen", "", (string[] args) =>
{ {
if (GameMain.Client != null)
{
ThrowError("This command cannot be used in multiplayer.");
return;
}
GameMain.LobbyScreen.Select(); GameMain.LobbyScreen.Select();
})); }));
@@ -1,5 +1,6 @@
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using System;
namespace Barotrauma namespace Barotrauma
{ {
@@ -27,14 +28,14 @@ namespace Barotrauma
{ {
GUI.DrawString(spriteBatch, new Vector2(10, y), "EventManager", Color.White, Color.Black * 0.6f, 0, GUI.SmallFont); GUI.DrawString(spriteBatch, new Vector2(10, y), "EventManager", Color.White, Color.Black * 0.6f, 0, GUI.SmallFont);
GUI.DrawString(spriteBatch, new Vector2(15, y + 20), "Event cooldown: " + eventCoolDown, Color.White, Color.Black * 0.6f, 0, GUI.SmallFont); GUI.DrawString(spriteBatch, new Vector2(15, y + 20), "Event cooldown: " + eventCoolDown, Color.White, Color.Black * 0.6f, 0, GUI.SmallFont);
GUI.DrawString(spriteBatch, new Vector2(15, y + 35), "Current intensity: " + (int)(currentIntensity * 100), Color.Lerp(Color.White, GUI.Style.Red, currentIntensity), Color.Black * 0.6f, 0, GUI.SmallFont); GUI.DrawString(spriteBatch, new Vector2(15, y + 35), "Current intensity: " + (int)Math.Round(currentIntensity * 100), Color.Lerp(Color.White, GUI.Style.Red, currentIntensity), Color.Black * 0.6f, 0, GUI.SmallFont);
GUI.DrawString(spriteBatch, new Vector2(15, y + 50), "Target intensity: " + (int)(targetIntensity * 100), Color.Lerp(Color.White, GUI.Style.Red, targetIntensity), Color.Black * 0.6f, 0, GUI.SmallFont); GUI.DrawString(spriteBatch, new Vector2(15, y + 50), "Target intensity: " + (int)Math.Round(targetIntensity * 100), Color.Lerp(Color.White, GUI.Style.Red, targetIntensity), Color.Black * 0.6f, 0, GUI.SmallFont);
GUI.DrawString(spriteBatch, new Vector2(15, y + 65), "AvgHealth: " + (int)(avgCrewHealth * 100), Color.Lerp(GUI.Style.Red, GUI.Style.Green, avgCrewHealth), Color.Black * 0.6f, 0, GUI.SmallFont); GUI.DrawString(spriteBatch, new Vector2(15, y + 65), "AvgHealth: " + (int)Math.Round(avgCrewHealth * 100), Color.Lerp(GUI.Style.Red, GUI.Style.Green, avgCrewHealth), Color.Black * 0.6f, 0, GUI.SmallFont);
GUI.DrawString(spriteBatch, new Vector2(15, y + 80), "AvgHullIntegrity: " + (int)(avgHullIntegrity * 100), Color.Lerp(GUI.Style.Red, GUI.Style.Green, avgHullIntegrity), Color.Black * 0.6f, 0, GUI.SmallFont); GUI.DrawString(spriteBatch, new Vector2(15, y + 80), "AvgHullIntegrity: " + (int)Math.Round(avgHullIntegrity * 100), Color.Lerp(GUI.Style.Red, GUI.Style.Green, avgHullIntegrity), Color.Black * 0.6f, 0, GUI.SmallFont);
GUI.DrawString(spriteBatch, new Vector2(15, y + 95), "FloodingAmount: " + (int)(floodingAmount * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, floodingAmount), Color.Black * 0.6f, 0, GUI.SmallFont); GUI.DrawString(spriteBatch, new Vector2(15, y + 95), "FloodingAmount: " + (int)Math.Round(floodingAmount * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, floodingAmount), Color.Black * 0.6f, 0, GUI.SmallFont);
GUI.DrawString(spriteBatch, new Vector2(15, y + 110), "FireAmount: " + (int)(fireAmount * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, fireAmount), Color.Black * 0.6f, 0, GUI.SmallFont); GUI.DrawString(spriteBatch, new Vector2(15, y + 110), "FireAmount: " + (int)Math.Round(fireAmount * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, fireAmount), Color.Black * 0.6f, 0, GUI.SmallFont);
GUI.DrawString(spriteBatch, new Vector2(15, y + 125), "EnemyDanger: " + (int)(enemyDanger * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, enemyDanger), Color.Black * 0.6f, 0, GUI.SmallFont); GUI.DrawString(spriteBatch, new Vector2(15, y + 125), "EnemyDanger: " + (int)Math.Round(enemyDanger * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, enemyDanger), Color.Black * 0.6f, 0, GUI.SmallFont);
#if DEBUG #if DEBUG
if (PlayerInput.KeyDown(Microsoft.Xna.Framework.Input.Keys.LeftAlt) && if (PlayerInput.KeyDown(Microsoft.Xna.Framework.Input.Keys.LeftAlt) &&
@@ -101,7 +101,7 @@ namespace Barotrauma
InputBox.TextBlock.RectTransform.MaxSize InputBox.TextBlock.RectTransform.MaxSize
= new Point((int)(InputBox.Rect.Width - chatSendButton.Rect.Width * 1.25f - InputBox.TextBlock.Padding.Z), int.MaxValue); = new Point((int)(InputBox.Rect.Width - chatSendButton.Rect.Width * 1.25f - InputBox.TextBlock.Padding.Z), int.MaxValue);
showNewMessagesButton = new GUIButton(new RectTransform(new Vector2(1f, 0.125f), GUIFrame.RectTransform, Anchor.BottomCenter) { RelativeOffset = new Vector2(0.0f, -0.125f) }, TextManager.Get("chat.shownewmessages")); showNewMessagesButton = new GUIButton(new RectTransform(new Vector2(1f, 0.075f), GUIFrame.RectTransform, Anchor.BottomCenter) { RelativeOffset = new Vector2(0.0f, 0.125f) }, TextManager.Get("chat.shownewmessages"));
showNewMessagesButton.OnClicked += (GUIButton btn, object userdata) => showNewMessagesButton.OnClicked += (GUIButton btn, object userdata) =>
{ {
chatBox.ScrollBar.BarScrollValue = 1f; chatBox.ScrollBar.BarScrollValue = 1f;
@@ -239,7 +239,8 @@ namespace Barotrauma
{ {
var popupMsg = new GUIFrame(new RectTransform(Vector2.One, GUIFrame.RectTransform), style: "GUIToolTip") var popupMsg = new GUIFrame(new RectTransform(Vector2.One, GUIFrame.RectTransform), style: "GUIToolTip")
{ {
Visible = false Visible = false,
CanBeFocused = false
}; };
var senderText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), popupMsg.RectTransform, Anchor.TopRight), var senderText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), popupMsg.RectTransform, Anchor.TopRight),
senderName, textColor: senderColor, font: GUI.SmallFont, textAlignment: Alignment.TopRight) senderName, textColor: senderColor, font: GUI.SmallFont, textAlignment: Alignment.TopRight)
@@ -306,7 +307,7 @@ namespace Barotrauma
GUIFrame.RectTransform.NonScaledSize -= new Point(toggleButtonWidth, 0); GUIFrame.RectTransform.NonScaledSize -= new Point(toggleButtonWidth, 0);
GUIFrame.RectTransform.AbsoluteOffset += new Point(toggleButtonWidth, 0); GUIFrame.RectTransform.AbsoluteOffset += new Point(toggleButtonWidth, 0);
popupMessageOffset = GameMain.GameSession.CrewManager.ReportButtonFrame.Rect.Width + GUIFrame.Rect.Width; popupMessageOffset = GameMain.GameSession.CrewManager.ReportButtonFrame.Rect.Width + GUIFrame.Rect.Width + (int)(20 * GUI.Scale);
} }
public void Update(float deltaTime) public void Update(float deltaTime)
@@ -233,9 +233,11 @@ namespace Barotrauma
{ {
get { return textBlock.WrappedText; } get { return textBlock.WrappedText; }
} }
public bool Readonly { get; set; }
public GUITextBox(RectTransform rectT, string text = "", Color? textColor = null, ScalableFont font = null, public GUITextBox(RectTransform rectT, string text = "", Color? textColor = null, ScalableFont font = null,
Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null, bool createClearButton = false) Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null, bool createClearButton = false)
: base(style, rectT) : base(style, rectT)
{ {
HoverCursor = CursorState.IBeam; HoverCursor = CursorState.IBeam;
@@ -670,6 +672,7 @@ namespace Barotrauma
public void ReceiveTextInput(string input) public void ReceiveTextInput(string input)
{ {
if (Readonly) { return; }
if (selectedCharacters > 0) if (selectedCharacters > 0)
{ {
RemoveSelectedText(); RemoveSelectedText();
@@ -693,7 +696,7 @@ namespace Barotrauma
switch (command) switch (command)
{ {
case '\b': //backspace case '\b' when !Readonly: //backspace
if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl)) if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
{ {
SetText(string.Empty, false); SetText(string.Empty, false);
@@ -715,7 +718,7 @@ namespace Barotrauma
case (char)0x3: // ctrl-c case (char)0x3: // ctrl-c
CopySelectedText(); CopySelectedText();
break; break;
case (char)0x16: // ctrl-v case (char)0x16 when !Readonly: // ctrl-v
string text = GetCopiedText(); string text = GetCopiedText();
RemoveSelectedText(); RemoveSelectedText();
if (SetText(Text.Insert(CaretIndex, text))) if (SetText(Text.Insert(CaretIndex, text)))
@@ -726,12 +729,15 @@ namespace Barotrauma
break; break;
case (char)0x18: // ctrl-x case (char)0x18: // ctrl-x
CopySelectedText(); CopySelectedText();
RemoveSelectedText(); if (!Readonly)
{
RemoveSelectedText();
}
break; break;
case (char)0x1: // ctrl-a case (char)0x1: // ctrl-a
SelectAll(); SelectAll();
break; break;
case (char)0x1A: // ctrl-z case (char)0x1A when !Readonly: // ctrl-z
text = memento.Undo(); text = memento.Undo();
if (text != Text) if (text != Text)
{ {
@@ -741,7 +747,7 @@ namespace Barotrauma
OnTextChanged?.Invoke(this, Text); OnTextChanged?.Invoke(this, Text);
} }
break; break;
case (char)0x12: // ctrl-r case (char)0x12 when !Readonly: // ctrl-r
text = memento.Redo(); text = memento.Redo();
if (text != Text) if (text != Text)
{ {
@@ -798,7 +804,7 @@ namespace Barotrauma
caretTimer = 0; caretTimer = 0;
HandleSelection(); HandleSelection();
break; break;
case Keys.Delete: case Keys.Delete when !Readonly:
if (selectedCharacters > 0) if (selectedCharacters > 0)
{ {
RemoveSelectedText(); RemoveSelectedText();
@@ -30,7 +30,6 @@ namespace Barotrauma
get; private set; get; private set;
} }
public static Rectangle CrewArea public static Rectangle CrewArea
{ {
get; private set; get; private set;
@@ -55,10 +54,16 @@ namespace Barotrauma
{ {
get; private set; get; private set;
}*/ }*/
public static Rectangle HealthBarAreaLeft public static Rectangle HealthBarArea
{ {
get; private set; get; private set;
} }
public static Rectangle BottomRightInfoArea
{
get; private set;
}
public static Rectangle AfflictionAreaLeft public static Rectangle AfflictionAreaLeft
{ {
get; private set; get; private set;
@@ -74,11 +79,6 @@ namespace Barotrauma
get; private set; get; private set;
} }
public static Rectangle PortraitTooltipArea
{
get; private set;
}
public static int Padding public static int Padding
{ {
get; private set; get; private set;
@@ -91,6 +91,7 @@ namespace Barotrauma
GameMain.Instance.OnResolutionChanged += CreateAreas; GameMain.Instance.OnResolutionChanged += CreateAreas;
GameMain.Config.OnHUDScaleChanged += CreateAreas; GameMain.Config.OnHUDScaleChanged += CreateAreas;
CreateAreas(); CreateAreas();
CharacterInfo.Init();
} }
} }
@@ -104,23 +105,26 @@ namespace Barotrauma
public static void CreateAreas() public static void CreateAreas()
{ {
Padding = (int)(10 * GUI.Scale); Padding = (int)(11 * GUI.Scale);
if (inventoryTopY == 0) { inventoryTopY = GameMain.GraphicsHeight - 30; } if (inventoryTopY == 0) { inventoryTopY = GameMain.GraphicsHeight - 30; }
//slice from the top of the screen for misc buttons (info, end round, server controls) //slice from the top of the screen for misc buttons (info, end round, server controls)
ButtonAreaTop = new Rectangle(Padding, Padding, GameMain.GraphicsWidth - Padding * 2, (int)(50 * GUI.Scale)); ButtonAreaTop = new Rectangle(Padding, Padding, GameMain.GraphicsWidth - Padding * 2, (int)(50 * GUI.Scale));
int infoAreaWidth = (int)(142 * GUI.Scale * CharacterInfo.BgScale);
int infoAreaHeight = (int)(98 * GUI.Scale * CharacterInfo.BgScale);
int portraitSize = (int)(125 * GUI.Scale); int portraitSize = (int)(125 * GUI.Scale);
PortraitArea = new Rectangle(Padding * 2, Padding * 2, portraitSize, portraitSize); BottomRightInfoArea = new Rectangle(GameMain.GraphicsWidth - Padding * 2 - infoAreaWidth, GameMain.GraphicsHeight - Padding * 2 - infoAreaHeight, infoAreaWidth, infoAreaHeight);
PortraitTooltipArea = new Rectangle(PortraitArea.X + portraitSize / 2 + Padding, PortraitArea.Top - portraitSize, portraitSize, portraitSize); PortraitArea = new Rectangle(GameMain.GraphicsWidth - Padding - portraitSize, GameMain.GraphicsHeight - Padding - portraitSize, portraitSize, portraitSize);
//horizontal slices at the corners of the screen for health bar and affliction icons //horizontal slices at the corners of the screen for health bar and affliction icons
int healthBarWidth = (int)Math.Max(250 * GUI.Scale, 150); int healthBarHeight = (int)Math.Max(25f * GUI.Scale, 12.5f);
int healthBarHeight = (int)Math.Max(15f * GUI.Scale, 12.5f);
int afflictionAreaHeight = (int)(50 * GUI.Scale); int afflictionAreaHeight = (int)(50 * GUI.Scale);
HealthBarAreaLeft = new Rectangle(PortraitArea.X, PortraitArea.Y + Padding / 2 + portraitSize, healthBarWidth, healthBarHeight); int healthBarWidth = BottomRightInfoArea.Width;
AfflictionAreaLeft = new Rectangle(PortraitArea.X, HealthBarAreaLeft.Y + healthBarHeight + Padding, healthBarWidth, afflictionAreaHeight); //int healthBarWidth = (int)((BottomRightInfoArea.Width + CharacterInventory.SlotSize.X + CharacterInventory.Spacing) * 1.1f);
HealthBarArea = new Rectangle(BottomRightInfoArea.X, BottomRightInfoArea.Y - healthBarHeight - (int)(8 * GUI.Scale), healthBarWidth, healthBarHeight);
AfflictionAreaLeft = new Rectangle(HealthBarArea.X, HealthBarArea.Y - Padding - afflictionAreaHeight, HealthBarArea.Width, afflictionAreaHeight);
//HealthBarAreaRight = new Rectangle(Padding, GameMain.GraphicsHeight - healthBarHeight - Padding, healthBarWidth, healthBarHeight); //HealthBarAreaRight = new Rectangle(Padding, GameMain.GraphicsHeight - healthBarHeight - Padding, healthBarWidth, healthBarHeight);
/*if (HealthBarAreaRight.Y + healthBarHeight * 0.75f < PortraitArea.Y) /*if (HealthBarAreaRight.Y + healthBarHeight * 0.75f < PortraitArea.Y)
@@ -134,15 +138,14 @@ namespace Barotrauma
bool isFourByThree = GUI.IsFourByThree(); bool isFourByThree = GUI.IsFourByThree();
int chatBoxWidth = !isFourByThree ? (int)(475 * GUI.Scale) : (int)(375 * GUI.Scale); int chatBoxWidth = !isFourByThree ? (int)(475 * GUI.Scale) : (int)(375 * GUI.Scale);
int chatBoxHeight = (int)Math.Max(GameMain.GraphicsHeight * 0.22f, 150); int chatBoxHeight = (int)Math.Max(GameMain.GraphicsHeight * 0.25f, 150);
ChatBoxArea = new Rectangle(Padding, GameMain.GraphicsHeight - Padding - chatBoxHeight, chatBoxWidth, chatBoxHeight); ChatBoxArea = new Rectangle(Padding, GameMain.GraphicsHeight - Padding - chatBoxHeight, chatBoxWidth, chatBoxHeight);
int objectiveAnchorWidth = (int)(250 * GUI.Scale); int objectiveAnchorWidth = (int)(250 * GUI.Scale);
int objectiveAnchorOffsetY = (int)(150 * GUI.Scale); int objectiveAnchorOffsetY = (int)(150 * GUI.Scale);
ObjectiveAnchor = new Rectangle(Padding, ChatBoxArea.Y - objectiveAnchorOffsetY, objectiveAnchorWidth, 0); ObjectiveAnchor = new Rectangle(Padding, ChatBoxArea.Y - objectiveAnchorOffsetY, objectiveAnchorWidth, 0);
var crewAreaY = AfflictionAreaLeft.Bottom + Padding; CrewArea = new Rectangle(Padding, Padding, (int)Math.Max(400 * GUI.Scale, 220), ObjectiveAnchor.Top - Padding * 2);
CrewArea = new Rectangle(Padding, crewAreaY, (int)Math.Max(400 * GUI.Scale, 220), ObjectiveAnchor.Top - Padding - crewAreaY);
InventoryAreaLower = new Rectangle(Padding, inventoryTopY, GameMain.GraphicsWidth - Padding * 2, GameMain.GraphicsHeight - inventoryTopY); InventoryAreaLower = new Rectangle(Padding, inventoryTopY, GameMain.GraphicsWidth - Padding * 2, GameMain.GraphicsHeight - inventoryTopY);
@@ -160,10 +163,11 @@ namespace Barotrauma
GUI.DrawRectangle(spriteBatch, MessageAreaTop, GUI.Style.Orange * 0.5f); GUI.DrawRectangle(spriteBatch, MessageAreaTop, GUI.Style.Orange * 0.5f);
GUI.DrawRectangle(spriteBatch, CrewArea, Color.Blue * 0.5f); GUI.DrawRectangle(spriteBatch, CrewArea, Color.Blue * 0.5f);
GUI.DrawRectangle(spriteBatch, ChatBoxArea, Color.Cyan * 0.5f); GUI.DrawRectangle(spriteBatch, ChatBoxArea, Color.Cyan * 0.5f);
GUI.DrawRectangle(spriteBatch, HealthBarAreaLeft, Color.Red * 0.5f); GUI.DrawRectangle(spriteBatch, HealthBarArea, Color.Red * 0.5f);
GUI.DrawRectangle(spriteBatch, AfflictionAreaLeft, Color.Red * 0.5f); GUI.DrawRectangle(spriteBatch, AfflictionAreaLeft, Color.Red * 0.5f);
GUI.DrawRectangle(spriteBatch, InventoryAreaLower, Color.Yellow * 0.5f); GUI.DrawRectangle(spriteBatch, InventoryAreaLower, Color.Yellow * 0.5f);
GUI.DrawRectangle(spriteBatch, HealthWindowAreaLeft, Color.Red * 0.5f); GUI.DrawRectangle(spriteBatch, HealthWindowAreaLeft, Color.Red * 0.5f);
GUI.DrawRectangle(spriteBatch, BottomRightInfoArea, Color.Green * 0.5f);
} }
} }
@@ -226,7 +226,7 @@ namespace Barotrauma
} }
ReportButtonFrame = new GUILayoutGroup(new RectTransform( ReportButtonFrame = new GUILayoutGroup(new RectTransform(
new Point((HUDLayoutSettings.ChatBoxArea.Height - (int)((reports.Count - 1) * 5 * GUI.Scale)) / reports.Count, HUDLayoutSettings.ChatBoxArea.Height - chatBox.ToggleButton.Rect.Height), guiFrame.RectTransform)) new Point((HUDLayoutSettings.ChatBoxArea.Height - chatBox.ToggleButton.Rect.Height - (int)((reports.Count - 1) * 5 * GUI.Scale)) / reports.Count, HUDLayoutSettings.ChatBoxArea.Height - chatBox.ToggleButton.Rect.Height), guiFrame.RectTransform))
{ {
AbsoluteSpacing = (int)(5 * GUI.Scale), AbsoluteSpacing = (int)(5 * GUI.Scale),
UserData = "reportbuttons", UserData = "reportbuttons",
@@ -1604,13 +1604,8 @@ namespace Barotrauma
private void CreateOrderCategoryNodes() private void CreateOrderCategoryNodes()
{ {
var points = shortcutCenterNode != null ? // TODO: Calculate firstAngle parameter based on category count
GetCircumferencePointCount(availableCategories.Count) : var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, nodeDistance, availableCategories.Count, MathHelper.ToRadians(225));
availableCategories.Count;
var firstAngle = shortcutCenterNode != null ?
GetFirstNodeAngle(availableCategories.Count) :
0.0f;
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, nodeDistance, points, firstAngle);
var offsetIndex = 0; var offsetIndex = 0;
availableCategories.ForEach(oc => CreateOrderCategoryNode(oc, offsets[offsetIndex++].ToPoint(), offsetIndex)); availableCategories.ForEach(oc => CreateOrderCategoryNode(oc, offsets[offsetIndex++].ToPoint(), offsetIndex));
} }
@@ -2396,7 +2391,7 @@ namespace Barotrauma
var reportButtonParent = ChatBox ?? GameMain.Client?.ChatBox; var reportButtonParent = ChatBox ?? GameMain.Client?.ChatBox;
if (reportButtonParent == null) { return; } if (reportButtonParent == null) { return; }
ReportButtonFrame.RectTransform.AbsoluteOffset = new Point(reportButtonParent.GUIFrame.Rect.Right + (int)(10 * GUI.Scale), reportButtonParent.GUIFrame.Rect.Y - reportButtonParent.ToggleButton.Rect.Height); ReportButtonFrame.RectTransform.AbsoluteOffset = new Point(reportButtonParent.GUIFrame.Rect.Right + (int)(10 * GUI.Scale), reportButtonParent.GUIFrame.Rect.Y);
bool hasFires = Character.Controlled.CurrentHull.FireSources.Count > 0; bool hasFires = Character.Controlled.CurrentHull.FireSources.Count > 0;
ToggleReportButton("reportfire", hasFires); ToggleReportButton("reportfire", hasFires);
@@ -2445,15 +2440,22 @@ namespace Barotrauma
{ {
Character character; Character character;
character = Character.Create(characterInfos[i], waypoints[i].WorldPosition, characterInfos[i].Name); character = Character.Create(characterInfos[i], waypoints[i].WorldPosition, characterInfos[i].Name);
if (character.Info != null && !character.Info.StartItemsGiven)
{
character.GiveJobItems(waypoints[i]);
character.Info.StartItemsGiven = true;
}
if (character.Info?.InventoryData != null) if (character.Info != null)
{ {
character.Info.SpawnInventoryItems(character.Inventory, character.Info.InventoryData); if (!character.Info.StartItemsGiven && character.Info.InventoryData != null)
{
DebugConsole.ThrowError($"Error when initializing a single player round: character \"{character.Name}\" has not been given their initial items but has saved inventory data. Using the saved inventory data instead of giving the character new items.");
}
if (character.Info.InventoryData != null)
{
character.Info.SpawnInventoryItems(character.Inventory, character.Info.InventoryData);
}
else if (!character.Info.StartItemsGiven)
{
character.GiveJobItems(waypoints[i]);
}
character.Info.StartItemsGiven = true;
} }
AddCharacter(character); AddCharacter(character);
@@ -366,7 +366,8 @@ namespace Barotrauma.Tutorials
{ {
if (CharacterHealth.OpenHealthWindow != null && doctor.AnimController.Anim != AnimController.Animation.CPR) if (CharacterHealth.OpenHealthWindow != null && doctor.AnimController.Anim != AnimController.Animation.CPR)
{ {
CharacterHealth.OpenHealthWindow.CPRButton.Pulsate(Vector2.One, Vector2.One * 1.5f, 1.0f); //Disabled pulse until it's replaced by a better effect
//CharacterHealth.OpenHealthWindow.CPRButton.Pulsate(Vector2.One, Vector2.One * 1.5f, 1.0f);
CharacterHealth.OpenHealthWindow.CPRButton.Flash(); CharacterHealth.OpenHealthWindow.CPRButton.Flash();
} }
yield return null; yield return null;
@@ -97,6 +97,18 @@ namespace Barotrauma.Tutorials
stunbaton.Unequip(officer); stunbaton.Unequip(officer);
officer.Inventory.RemoveItem(stunbaton); officer.Inventory.RemoveItem(stunbaton);
var smg = FindOrGiveItem(officer, "smg");
smg.Unequip(officer);
officer.Inventory.RemoveItem(smg);
var divingknife = FindOrGiveItem(officer, "divingknife");
divingknife.Unequip(officer);
officer.Inventory.RemoveItem(divingknife);
var steroids = FindOrGiveItem(officer, "steroids");
steroids.Unequip(officer);
officer.Inventory.RemoveItem(steroids);
var ballistichelmet = var ballistichelmet =
officer.Inventory.FindItemByIdentifier("ballistichelmet1") ?? officer.Inventory.FindItemByIdentifier("ballistichelmet1") ??
officer.Inventory.FindItemByIdentifier("ballistichelmet2") ?? officer.Inventory.FindItemByIdentifier("ballistichelmet2") ??
@@ -41,7 +41,9 @@ namespace Barotrauma
private Point screenResolution; private Point screenResolution;
public Vector2[] SlotPositions; public Vector2[] SlotPositions;
public static Point SlotSize;
public static int Spacing;
private Layout layout; private Layout layout;
public Layout CurrentLayout public Layout CurrentLayout
{ {
@@ -245,20 +247,18 @@ namespace Barotrauma
} }
private void SetSlotPositions(Layout layout) private void SetSlotPositions(Layout layout)
{ {
int spacing;
bool isFourByThree = GUI.IsFourByThree(); bool isFourByThree = GUI.IsFourByThree();
if (isFourByThree) if (isFourByThree)
{ {
spacing = (int)(5 * UIScale); Spacing = (int)(5 * UIScale);
} }
else else
{ {
spacing = (int)(10 * UIScale); Spacing = (int)(8 * UIScale);
} }
Point slotSize = !isFourByThree ? (SlotSpriteSmall.size * UIScale).ToPoint() : (SlotSpriteSmall.size * UIScale * .925f).ToPoint(); SlotSize = !isFourByThree ? (SlotSpriteSmall.size * UIScale).ToPoint() : (SlotSpriteSmall.size * UIScale * .925f).ToPoint();
int bottomOffset = slotSize.Y + spacing * 2 + ContainedIndicatorHeight; int bottomOffset = SlotSize.Y + Spacing * 2 + ContainedIndicatorHeight;
if (slots == null) { CreateSlots(); } if (slots == null) { CreateSlots(); }
@@ -271,11 +271,12 @@ namespace Barotrauma
int personalSlotCount = SlotTypes.Count(s => PersonalSlots.HasFlag(s)); int personalSlotCount = SlotTypes.Count(s => PersonalSlots.HasFlag(s));
int normalSlotCount = SlotTypes.Count(s => !PersonalSlots.HasFlag(s)); int normalSlotCount = SlotTypes.Count(s => !PersonalSlots.HasFlag(s));
int x = GameMain.GraphicsWidth / 2 - normalSlotCount * (slotSize.X + spacing) / 2; int x = GameMain.GraphicsWidth / 2 - normalSlotCount * (SlotSize.X + Spacing) / 2;
int upperX = GameMain.GraphicsWidth - slotSize.X * 2; int upperX = HUDLayoutSettings.BottomRightInfoArea.X - Spacing * 2 - SlotSize.X - SlotSize.X / 2;
//int upperX = GameMain.GraphicsWidth - personalSlotCount * (slotSize.X + spacing) + (int)(11 * GUI.Scale) + spacing;
//make sure the rightmost normal slot doesn't overlap with the personal slots //make sure the rightmost normal slot doesn't overlap with the personal slots
x -= Math.Max((x + normalSlotCount * (slotSize.X + spacing)) - (upperX - personalSlotCount * (slotSize.X + spacing)), 0); x -= Math.Max((x + normalSlotCount * (SlotSize.X + Spacing)) - (upperX - personalSlotCount * (SlotSize.X + Spacing)), 0);
int hideButtonSlotIndex = -1; int hideButtonSlotIndex = -1;
for (int i = 0; i < SlotPositions.Length; i++) for (int i = 0; i < SlotPositions.Length; i++)
@@ -283,26 +284,26 @@ namespace Barotrauma
if (PersonalSlots.HasFlag(SlotTypes[i])) if (PersonalSlots.HasFlag(SlotTypes[i]))
{ {
SlotPositions[i] = new Vector2(upperX, GameMain.GraphicsHeight - bottomOffset); SlotPositions[i] = new Vector2(upperX, GameMain.GraphicsHeight - bottomOffset);
upperX -= slotSize.X + spacing; upperX -= SlotSize.X + Spacing;
personalSlotArea = (hideButtonSlotIndex == -1) ? personalSlotArea = (hideButtonSlotIndex == -1) ?
new Rectangle(SlotPositions[i].ToPoint(), slotSize) : new Rectangle(SlotPositions[i].ToPoint(), SlotSize) :
Rectangle.Union(personalSlotArea, new Rectangle(SlotPositions[i].ToPoint(), slotSize)); Rectangle.Union(personalSlotArea, new Rectangle(SlotPositions[i].ToPoint(), SlotSize));
hideButtonSlotIndex = i; hideButtonSlotIndex = i;
} }
else else
{ {
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset); SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset);
x += slotSize.X + spacing; x += SlotSize.X + Spacing;
} }
} }
if (hideButtonSlotIndex > -1) if (hideButtonSlotIndex > -1)
{ {
hideButton.RectTransform.SetPosition(Anchor.TopLeft, Pivot.TopLeft); hideButton.RectTransform.SetPosition(Anchor.TopLeft, Pivot.TopLeft);
hideButton.RectTransform.NonScaledSize = new Point(slotSize.X / 2, slotSize.Y + slots[hideButtonSlotIndex].EquipButtonRect.Height); hideButton.RectTransform.NonScaledSize = new Point(SlotSize.X / 2, HUDLayoutSettings.BottomRightInfoArea.Height);
hideButton.RectTransform.AbsoluteOffset = new Point( hideButton.RectTransform.AbsoluteOffset = new Point(
personalSlotArea.Right + spacing, personalSlotArea.Right + Spacing,
personalSlotArea.Y - slots[hideButtonSlotIndex].EquipButtonRect.Height); HUDLayoutSettings.BottomRightInfoArea.Y);
hideButton.Visible = true; hideButton.Visible = true;
} }
} }
@@ -311,7 +312,7 @@ namespace Barotrauma
{ {
int extraOffset = 0; int extraOffset = 0;
int x = HUDLayoutSettings.InventoryAreaLower.Right; int x = HUDLayoutSettings.InventoryAreaLower.Right;
int personalSlotX = HUDLayoutSettings.InventoryAreaLower.Right - slotSize.X - spacing; int personalSlotX = HUDLayoutSettings.InventoryAreaLower.Right - SlotSize.X - Spacing;
for (int i = 0; i < slots.Length; i++) for (int i = 0; i < slots.Length; i++)
{ {
if (HideSlot(i)) continue; if (HideSlot(i)) continue;
@@ -321,7 +322,7 @@ namespace Barotrauma
} }
else else
{ {
x -= slotSize.X + spacing; x -= SlotSize.X + Spacing;
} }
} }
@@ -331,13 +332,13 @@ namespace Barotrauma
if (HideSlot(i)) continue; if (HideSlot(i)) continue;
if (PersonalSlots.HasFlag(SlotTypes[i])) if (PersonalSlots.HasFlag(SlotTypes[i]))
{ {
SlotPositions[i] = new Vector2(personalSlotX, GameMain.GraphicsHeight - bottomOffset * 2 - extraOffset - spacing * 2); SlotPositions[i] = new Vector2(personalSlotX, GameMain.GraphicsHeight - bottomOffset * 2 - extraOffset - Spacing * 2);
personalSlotX -= slots[i].Rect.Width + spacing; personalSlotX -= slots[i].Rect.Width + Spacing;
} }
else else
{ {
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset - extraOffset); SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset - extraOffset);
x += slots[i].Rect.Width + spacing; x += slots[i].Rect.Width + Spacing;
} }
} }
@@ -345,7 +346,7 @@ namespace Barotrauma
for (int i = 0; i < SlotPositions.Length; i++) for (int i = 0; i < SlotPositions.Length; i++)
{ {
if (!HideSlot(i)) continue; if (!HideSlot(i)) continue;
x -= slots[i].Rect.Width + spacing; x -= slots[i].Rect.Width + Spacing;
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset - extraOffset); SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset - extraOffset);
} }
} }
@@ -359,28 +360,28 @@ namespace Barotrauma
if (HideSlot(i)) continue; if (HideSlot(i)) continue;
if (PersonalSlots.HasFlag(SlotTypes[i])) if (PersonalSlots.HasFlag(SlotTypes[i]))
{ {
SlotPositions[i] = new Vector2(personalSlotX, GameMain.GraphicsHeight - bottomOffset * 2 - spacing * 2); SlotPositions[i] = new Vector2(personalSlotX, GameMain.GraphicsHeight - bottomOffset * 2 - Spacing * 2);
personalSlotX += slots[i].Rect.Width + spacing; personalSlotX += slots[i].Rect.Width + Spacing;
} }
else else
{ {
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset); SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset);
x += slots[i].Rect.Width + spacing; x += slots[i].Rect.Width + Spacing;
} }
} }
for (int i = 0; i < SlotPositions.Length; i++) for (int i = 0; i < SlotPositions.Length; i++)
{ {
if (!HideSlot(i)) continue; if (!HideSlot(i)) continue;
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset); SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset);
x += slots[i].Rect.Width + spacing; x += slots[i].Rect.Width + Spacing;
} }
} }
break; break;
case Layout.Center: case Layout.Center:
{ {
int columns = 5; int columns = 5;
int startX = (GameMain.GraphicsWidth / 2) - (slotSize.X * columns + spacing * (columns - 1)) / 2; int startX = (GameMain.GraphicsWidth / 2) - (SlotSize.X * columns + Spacing * (columns - 1)) / 2;
int startY = GameMain.GraphicsHeight / 2 - (slotSize.Y * 2); int startY = GameMain.GraphicsHeight / 2 - (SlotSize.Y * 2);
int x = startX, y = startY; int x = startX, y = startY;
for (int i = 0; i < SlotPositions.Length; i++) for (int i = 0; i < SlotPositions.Length; i++)
{ {
@@ -388,10 +389,10 @@ namespace Barotrauma
if (SlotTypes[i] == InvSlotType.Card || SlotTypes[i] == InvSlotType.Headset || SlotTypes[i] == InvSlotType.InnerClothes) if (SlotTypes[i] == InvSlotType.Card || SlotTypes[i] == InvSlotType.Headset || SlotTypes[i] == InvSlotType.InnerClothes)
{ {
SlotPositions[i] = new Vector2(x, y); SlotPositions[i] = new Vector2(x, y);
x += slots[i].Rect.Width + spacing; x += slots[i].Rect.Width + Spacing;
} }
} }
y += slots[0].Rect.Height + spacing + ContainedIndicatorHeight + slots[0].EquipButtonRect.Height; y += slots[0].Rect.Height + Spacing + ContainedIndicatorHeight + slots[0].EquipButtonRect.Height;
x = startX; x = startX;
int n = 0; int n = 0;
for (int i = 0; i < SlotPositions.Length; i++) for (int i = 0; i < SlotPositions.Length; i++)
@@ -400,12 +401,12 @@ namespace Barotrauma
if (SlotTypes[i] != InvSlotType.Card && SlotTypes[i] != InvSlotType.Headset && SlotTypes[i] != InvSlotType.InnerClothes) if (SlotTypes[i] != InvSlotType.Card && SlotTypes[i] != InvSlotType.Headset && SlotTypes[i] != InvSlotType.InnerClothes)
{ {
SlotPositions[i] = new Vector2(x, y); SlotPositions[i] = new Vector2(x, y);
x += slots[i].Rect.Width + spacing; x += slots[i].Rect.Width + Spacing;
n++; n++;
if (n >= columns) if (n >= columns)
{ {
x = startX; x = startX;
y += slots[i].Rect.Height + spacing + ContainedIndicatorHeight + slots[i].EquipButtonRect.Height; y += slots[i].Rect.Height + Spacing + ContainedIndicatorHeight + slots[i].EquipButtonRect.Height;
n = 0; n = 0;
} }
} }
@@ -99,7 +99,7 @@ namespace Barotrauma.Items.Components
//left column //left column
//---------------------------------------------------------- //----------------------------------------------------------
GUIFrame inventoryWindow = new GUIFrame(new RectTransform(new Vector2(0.1f, 0.5f), GuiFrame.RectTransform, Anchor.TopLeft, Pivot.TopRight) GUIFrame inventoryWindow = new GUIFrame(new RectTransform(new Vector2(0.1f, 0.75f), GuiFrame.RectTransform, Anchor.TopLeft, Pivot.TopRight)
{ {
MinSize = new Point(85, 220), MinSize = new Point(85, 220),
RelativeOffset = new Vector2(-0.02f, 0) RelativeOffset = new Vector2(-0.02f, 0)
@@ -112,8 +112,8 @@ namespace Barotrauma.Items.Components
Stretch = true Stretch = true
}; };
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), inventoryContent.RectTransform), "", /*new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), inventoryContent.RectTransform), "",
textAlignment: Alignment.Center, font: GUI.SubHeadingFont, wrap: true); textAlignment: Alignment.Center, font: GUI.SubHeadingFont, wrap: true);*/
inventoryContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.9f), inventoryContent.RectTransform), style: null); inventoryContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.9f), inventoryContent.RectTransform), style: null);
//---------------------------------------------------------- //----------------------------------------------------------
@@ -381,16 +381,17 @@ namespace Barotrauma.Items.Components
var itemContainer = item.GetComponent<ItemContainer>(); var itemContainer = item.GetComponent<ItemContainer>();
if (itemContainer != null) if (itemContainer != null)
{ {
itemContainer.UILabel = "";
itemContainer.AllowUIOverlap = true; itemContainer.AllowUIOverlap = true;
itemContainer.Inventory.RectTransform = inventoryContainer.RectTransform; itemContainer.Inventory.RectTransform = inventoryContainer.RectTransform;
var inventoryLabel = inventoryContainer.Parent?.GetChild<GUITextBlock>(); /*var inventoryLabel = inventoryContainer.Parent?.GetChild<GUITextBlock>();
if (inventoryLabel != null) if (inventoryLabel != null)
{ {
inventoryLabel.RectTransform.MinSize = new Point(100, 0); inventoryLabel.RectTransform.MinSize = new Point(100, 0);
inventoryLabel.Text = itemContainer.GetUILabel(); inventoryLabel.Text = itemContainer.GetUILabel();
inventoryLabel.CalculateHeightFromText(); inventoryLabel.CalculateHeightFromText();
(inventoryLabel.Parent as GUILayoutGroup).Recalculate(); (inventoryLabel.Parent as GUILayoutGroup).Recalculate();
} }*/
} }
} }
@@ -663,7 +663,7 @@ namespace Barotrauma.Items.Components
if (Vector2.DistanceSquared(PlayerInput.MousePosition, steerArea.Rect.Center.ToVector2()) < steerRadius * steerRadius) if (Vector2.DistanceSquared(PlayerInput.MousePosition, steerArea.Rect.Center.ToVector2()) < steerRadius * steerRadius)
{ {
if (PlayerInput.PrimaryMouseButtonHeld()) if (PlayerInput.PrimaryMouseButtonHeld() && !CrewManager.IsCommandInterfaceOpen)
{ {
Vector2 displaySubPos = (-sonar.DisplayOffset * sonar.Zoom) / sonar.Range * sonar.DisplayRadius * sonar.Zoom; Vector2 displaySubPos = (-sonar.DisplayOffset * sonar.Zoom) / sonar.Range * sonar.DisplayRadius * sonar.Zoom;
displaySubPos.Y = -displaySubPos.Y; displaySubPos.Y = -displaySubPos.Y;
@@ -55,7 +55,7 @@ namespace Barotrauma
float sizeY = Inventory.UnequippedIndicator.size.Y * Inventory.UIScale * Inventory.IndicatorScaleAdjustment; float sizeY = Inventory.UnequippedIndicator.size.Y * Inventory.UIScale * Inventory.IndicatorScaleAdjustment;
Vector2 equipIndicatorPos = new Vector2(Rect.Left, Rect.Center.Y + (Rect.Height / 2 + 25 * Inventory.UIScale) * buttonDir - sizeY / 2f); Vector2 equipIndicatorPos = new Vector2(Rect.Left, Rect.Center.Y + (Rect.Height / 2 + 15 * Inventory.UIScale) * buttonDir - sizeY / 2f);
equipIndicatorPos += DrawOffset; equipIndicatorPos += DrawOffset;
return new Rectangle((int)equipIndicatorPos.X, (int)equipIndicatorPos.Y, (int)Rect.Width, (int)sizeY); return new Rectangle((int)equipIndicatorPos.X, (int)equipIndicatorPos.Y, (int)Rect.Width, (int)sizeY);
@@ -141,7 +141,7 @@ namespace Barotrauma
//TODO: define this in xml //TODO: define this in xml
slotSpriteSmall = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(10, 6, 119, 120), null, 0); slotSpriteSmall = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(10, 6, 119, 120), null, 0);
// Adjustment to match the old size of 75,71 // Adjustment to match the old size of 75,71
SlotSpriteSmall.size = new Vector2(SlotSpriteSmall.SourceRect.Width * 0.625f, SlotSpriteSmall.SourceRect.Height * 0.625f); SlotSpriteSmall.size = new Vector2(SlotSpriteSmall.SourceRect.Width * 0.575f, SlotSpriteSmall.SourceRect.Height * 0.575f);
} }
return slotSpriteSmall; return slotSpriteSmall;
} }
@@ -152,7 +152,7 @@ namespace Barotrauma
{ {
get get
{ {
return !GUI.IsFourByThree() ? 0.85f : 0.75f; return !GUI.IsFourByThree() ? 0.8f : 0.7f;
} }
} }
@@ -773,10 +773,10 @@ namespace Barotrauma
if (selInv != null) if (selInv != null)
{ {
foreach (var slot in selInv.slots) for (int i = 0; i < selInv.slots.Length; i++)
{ {
if (slot.InteractRect.Contains(PlayerInput.MousePosition) || InventorySlot slot = selInv.slots[i];
slot.EquipButtonRect.Contains(PlayerInput.MousePosition)) if (slot.InteractRect.Contains(PlayerInput.MousePosition) || (slot.EquipButtonRect.Contains(PlayerInput.MousePosition) && selInv.Items[i].AllowedSlots.Any(a => a == InvSlotType.Any)))
{ {
return CursorState.Hand; return CursorState.Hand;
} }
@@ -801,9 +801,10 @@ namespace Barotrauma
} }
} }
foreach (var slot in inv.slots) for (int i = 0; i < inv.slots.Length; i++)
{ {
if (slot.EquipButtonRect.Contains(PlayerInput.MousePosition)) InventorySlot slot = inv.slots[i];
if (slot.EquipButtonRect.Contains(PlayerInput.MousePosition) && inv.Items[i].AllowedSlots.Any(a => a == InvSlotType.Any))
{ {
return CursorState.Hand; return CursorState.Hand;
} }
@@ -60,8 +60,6 @@ namespace Barotrauma.Networking
private bool connected; private bool connected;
private bool roundInitialized;
private byte myID; private byte myID;
private List<Client> otherClients; private List<Client> otherClients;
@@ -150,8 +148,6 @@ namespace Barotrauma.Networking
this.ownerKey = ownerKey; this.ownerKey = ownerKey;
this.steamP2POwner = steamP2POwner; this.steamP2POwner = steamP2POwner;
roundInitialized = false;
allowReconnect = true; allowReconnect = true;
netStats = new NetStats(); netStats = new NetStats();
@@ -467,10 +463,10 @@ namespace Barotrauma.Networking
string pwMsg = TextManager.Get("PasswordRequired"); string pwMsg = TextManager.Get("PasswordRequired");
var msgBox = new GUIMessageBox(pwMsg, "", new string[] { TextManager.Get("OK"), TextManager.Get("Cancel") }, var msgBox = new GUIMessageBox(pwMsg, "", new string[] { TextManager.Get("OK"), TextManager.Get("Cancel") },
relativeSize: new Vector2(0.25f, 0.2f), minSize: new Point(400, 150)); relativeSize: new Vector2(0.25f, 0.1f), minSize: new Point(400, 170));
var passwordBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 0.1f), msgBox.InnerFrame.RectTransform, Anchor.Center) { MinSize = new Point(0, 20) }) var passwordHolder = new GUILayoutGroup(new RectTransform(Vector2.One, msgBox.Content.RectTransform), childAnchor: Anchor.TopCenter);
var passwordBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 1f) , passwordHolder.RectTransform) { MinSize = new Point(0, 20) })
{ {
IgnoreLayoutGroups = true,
UserData = "password", UserData = "password",
Censor = true Censor = true
}; };
@@ -712,9 +708,6 @@ namespace Barotrauma.Networking
case ServerPacketHeader.STARTGAME: case ServerPacketHeader.STARTGAME:
startGameCoroutine = GameMain.Instance.ShowLoading(StartGame(inc), false); startGameCoroutine = GameMain.Instance.ShowLoading(StartGame(inc), false);
break; break;
case ServerPacketHeader.STARTGAMEFINALIZE:
ReadStartGameFinalize(inc);
break;
case ServerPacketHeader.ENDGAME: case ServerPacketHeader.ENDGAME:
string endMessage = inc.ReadString(); string endMessage = inc.ReadString();
bool missionSuccessful = inc.ReadBoolean(); bool missionSuccessful = inc.ReadBoolean();
@@ -774,26 +767,7 @@ namespace Barotrauma.Networking
break; break;
} }
} }
private void ReadStartGameFinalize(IReadMessage inc)
{
int levelEqualityCheckVal = inc.ReadInt32();
if (Level.Loaded.EqualityCheckVal != levelEqualityCheckVal)
{
string errorMsg = "Level equality check failed. The level generated at your end doesn't match the level generated by the server (seed: " + Level.Loaded.Seed +
", sub: " + Submarine.MainSub.Name + " (" + Submarine.MainSub.MD5Hash.ShortHash + ")" +
", mirrored: " + Level.Loaded.Mirrored + ").";
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:LevelsDontMatch" + Level.Loaded.Seed, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
throw new Exception(errorMsg);
}
GameMain.GameSession.Mission?.ClientReadInitial(inc);
roundInitialized = true;
}
private void OnDisconnect() private void OnDisconnect()
{ {
if (SteamManager.IsInitialized) if (SteamManager.IsInitialized)
@@ -902,7 +876,6 @@ namespace Barotrauma.Networking
} }
else else
{ {
connected = false;
connectCancelled = true; connectCancelled = true;
string msg = ""; string msg = "";
@@ -1145,11 +1118,9 @@ namespace Barotrauma.Networking
EndVoteTickBox.Selected = false; EndVoteTickBox.Selected = false;
roundInitialized = false;
int seed = inc.ReadInt32(); int seed = inc.ReadInt32();
string levelSeed = inc.ReadString(); string levelSeed = inc.ReadString();
//int levelEqualityCheckVal = inc.ReadInt32(); int levelEqualityCheckVal = inc.ReadInt32();
float levelDifficulty = inc.ReadSingle(); float levelDifficulty = inc.ReadSingle();
byte losMode = inc.ReadByte(); byte losMode = inc.ReadByte();
@@ -1185,8 +1156,6 @@ namespace Barotrauma.Networking
serverSettings.ReadMonsterEnabled(inc); serverSettings.ReadMonsterEnabled(inc);
bool includesFinalize = inc.ReadBoolean(); inc.ReadPadBits();
GameModePreset gameMode = GameModePreset.List.Find(gm => gm.Identifier == modeIdentifier); GameModePreset gameMode = GameModePreset.List.Find(gm => gm.Identifier == modeIdentifier);
MultiPlayerCampaign campaign = MultiPlayerCampaign campaign =
GameMain.NetLobbyScreen.SelectedMode == GameMain.GameSession?.GameMode.Preset && gameMode == GameMain.NetLobbyScreen.SelectedMode ? GameMain.NetLobbyScreen.SelectedMode == GameMain.GameSession?.GameMode.Preset && gameMode == GameMain.NetLobbyScreen.SelectedMode ?
@@ -1274,44 +1243,7 @@ namespace Barotrauma.Networking
mirrorLevel: campaign.Map.CurrentLocation != campaign.Map.SelectedConnection.Locations[0]); mirrorLevel: campaign.Map.CurrentLocation != campaign.Map.SelectedConnection.Locations[0]);
} }
if (includesFinalize) GameMain.GameSession.Mission?.ClientReadInitial(inc);
{
ReadStartGameFinalize(inc);
}
//wait for up to 30 seconds for the server to send the STARTGAMEFINALIZE message
DateTime timeOut = DateTime.Now + new TimeSpan(0, 0, seconds: 30);
while (DateTime.Now < timeOut)
{
if (!connected)
{
yield return CoroutineStatus.Success;
}
if (roundInitialized)
{
break;
}
try
{
clientPeer?.Update((float)Timing.Step);
}
catch (Exception e)
{
DebugConsole.ThrowError("There was an error initializing the round.", e, true);
roundInitialized = false;
break;
}
//waiting for a STARTGAMEFINALIZE message
yield return CoroutineStatus.Running;
}
if (!roundInitialized)
{
DebugConsole.ThrowError("Error while starting the round (did not receive STARTROUNDFINALIZE message from the server). Stopping the round...");
CoroutineManager.StartCoroutine(EndGame(""));
yield return CoroutineStatus.Failure;
}
if (GameMain.GameSession.Submarine.IsFileCorrupted) if (GameMain.GameSession.Submarine.IsFileCorrupted)
{ {
@@ -1331,12 +1263,23 @@ namespace Barotrauma.Networking
} }
} }
if (Level.Loaded.EqualityCheckVal != levelEqualityCheckVal)
{
string errorMsg = "Level equality check failed. The level generated at your end doesn't match the level generated by the server (seed: " + Level.Loaded.Seed +
", sub: " + Submarine.MainSub.Name + " (" + Submarine.MainSub.MD5Hash.ShortHash + ")" +
", mirrored: " + Level.Loaded.Mirrored + ").";
DebugConsole.ThrowError(errorMsg, createMessageBox: true);
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:LevelsDontMatch" + levelSeed, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
CoroutineManager.StartCoroutine(EndGame(""));
yield return CoroutineStatus.Failure;
}
if (respawnAllowed) { respawnManager = new RespawnManager(this, GameMain.NetLobbyScreen.UsingShuttle ? GameMain.NetLobbyScreen.SelectedShuttle : null); } if (respawnAllowed) { respawnManager = new RespawnManager(this, GameMain.NetLobbyScreen.UsingShuttle ? GameMain.NetLobbyScreen.SelectedShuttle : null); }
GameMain.GameSession.EventManager.PreloadContent(contentToPreload); GameMain.GameSession.EventManager.PreloadContent(contentToPreload);
gameStarted = true;
ServerSettings.ServerDetailsChanged = true; ServerSettings.ServerDetailsChanged = true;
gameStarted = true;
GameMain.GameScreen.Select(); GameMain.GameScreen.Select();
@@ -1484,7 +1427,7 @@ namespace Barotrauma.Networking
existingClient.Muted = tc.Muted; existingClient.Muted = tc.Muted;
existingClient.AllowKicking = tc.AllowKicking; existingClient.AllowKicking = tc.AllowKicking;
GameMain.NetLobbyScreen.SetPlayerNameAndJobPreference(existingClient); GameMain.NetLobbyScreen.SetPlayerNameAndJobPreference(existingClient);
if (Screen.Selected != GameMain.NetLobbyScreen && tc.CharacterID > 0) if (tc.CharacterID > 0)
{ {
existingClient.Character = Entity.FindEntityByID(tc.CharacterID) as Character; existingClient.Character = Entity.FindEntityByID(tc.CharacterID) as Character;
if (existingClient.Character == null) if (existingClient.Character == null)
@@ -91,7 +91,6 @@ namespace Barotrauma.Networking
return; return;
} }
incomingLidgrenMessages.Clear();
netClient.ReadMessages(incomingLidgrenMessages); netClient.ReadMessages(incomingLidgrenMessages);
foreach (NetIncomingMessage inc in incomingLidgrenMessages) foreach (NetIncomingMessage inc in incomingLidgrenMessages)
@@ -108,6 +107,8 @@ namespace Barotrauma.Networking
break; break;
} }
} }
incomingLidgrenMessages.Clear();
} }
private void HandleDataMessage(NetIncomingMessage inc) private void HandleDataMessage(NetIncomingMessage inc)
@@ -107,6 +107,8 @@ namespace Barotrauma
//elements that can only be used by the host //elements that can only be used by the host
private readonly List<GUIComponent> clientDisabledElements = new List<GUIComponent>(); private readonly List<GUIComponent> clientDisabledElements = new List<GUIComponent>();
//elements that can't be interacted with but don't look disabled
private readonly List<GUITextBox> clientReadonlyElements = new List<GUITextBox>();
//elements that aren't shown client-side //elements that aren't shown client-side
private readonly List<GUIComponent> clientHiddenElements = new List<GUIComponent>(); private readonly List<GUIComponent> clientHiddenElements = new List<GUIComponent>();
@@ -704,9 +706,12 @@ namespace Barotrauma
}; };
ServerName.OnDeselected += (textBox, key) => ServerName.OnDeselected += (textBox, key) =>
{ {
GameMain.Client.ServerSettings.ClientAdminWrite(ServerSettings.NetFlags.Name); if (!textBox.Readonly)
{
GameMain.Client.ServerSettings.ClientAdminWrite(ServerSettings.NetFlags.Name);
}
}; };
clientDisabledElements.Add(ServerName); clientReadonlyElements.Add(ServerName);
SettingsButton = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), lobbyHeader.RectTransform, Anchor.TopRight), SettingsButton = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), lobbyHeader.RectTransform, Anchor.TopRight),
TextManager.Get("ServerSettingsButton")); TextManager.Get("ServerSettingsButton"));
@@ -755,9 +760,12 @@ namespace Barotrauma
}; };
ServerMessage.OnDeselected += (textBox, key) => ServerMessage.OnDeselected += (textBox, key) =>
{ {
GameMain.Client.ServerSettings.ClientAdminWrite(ServerSettings.NetFlags.Message); if (!textBox.Readonly)
{
GameMain.Client.ServerSettings.ClientAdminWrite(ServerSettings.NetFlags.Message);
}
}; };
clientDisabledElements.Add(ServerMessage); clientReadonlyElements.Add(ServerMessage);
//submarine list ------------------------------------------------------------------ //submarine list ------------------------------------------------------------------
@@ -1221,6 +1229,7 @@ namespace Barotrauma
//disable/hide elements the clients are not supposed to use/see //disable/hide elements the clients are not supposed to use/see
clientDisabledElements.ForEach(c => c.Enabled = false); clientDisabledElements.ForEach(c => c.Enabled = false);
clientReadonlyElements.ForEach(c => c.Readonly = true);
clientHiddenElements.ForEach(c => c.Visible = false); clientHiddenElements.ForEach(c => c.Visible = false);
UpdatePermissions(); UpdatePermissions();
@@ -1268,8 +1277,8 @@ namespace Barotrauma
public void UpdatePermissions() public void UpdatePermissions()
{ {
ServerName.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings); ServerName.Readonly = !GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
ServerMessage.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings); ServerMessage.Readonly = !GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
missionTypeList.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings); missionTypeList.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
foreach (var tickBox in missionTypeTickBoxes) foreach (var tickBox in missionTypeTickBoxes)
{ {
@@ -1288,8 +1297,8 @@ namespace Barotrauma
SettingsButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ManageSettings); SettingsButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
SettingsButton.OnClicked = GameMain.Client.ServerSettings.ToggleSettingsFrame; SettingsButton.OnClicked = GameMain.Client.ServerSettings.ToggleSettingsFrame;
StartButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ManageRound) && !GameMain.Client.GameStarted && !campaignContainer.Visible; StartButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ManageRound) && !GameMain.Client.GameStarted && !campaignContainer.Visible;
ServerName.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings); ServerName.Readonly = !GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
ServerMessage.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings); ServerMessage.Readonly = !GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
shuttleTickBox.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings); shuttleTickBox.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
SubList.Enabled = GameMain.Client.ServerSettings.Voting.AllowSubVoting || GameMain.Client.HasPermission(ClientPermissions.SelectSub); SubList.Enabled = GameMain.Client.ServerSettings.Voting.AllowSubVoting || GameMain.Client.HasPermission(ClientPermissions.SelectSub);
shuttleList.Enabled = GameMain.Client.HasPermission(ClientPermissions.SelectSub); shuttleList.Enabled = GameMain.Client.HasPermission(ClientPermissions.SelectSub);
@@ -1313,8 +1322,6 @@ namespace Barotrauma
if (GameMain.Client == null) return; if (GameMain.Client == null) return;
spectateButton.Visible = true; spectateButton.Visible = true;
spectateButton.Enabled = true; spectateButton.Enabled = true;
StartButton.Visible = false;
} }
public void SetCampaignCharacterInfo(CharacterInfo newCampaignCharacterInfo) public void SetCampaignCharacterInfo(CharacterInfo newCampaignCharacterInfo)
@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace> <RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors> <Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product> <Product>Barotrauma</Product>
<Version>0.9.707.0</Version> <Version>0.9.708.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright> <Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms> <Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName> <AssemblyName>Barotrauma</AssemblyName>
+1 -1
View File
@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace> <RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors> <Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product> <Product>Barotrauma</Product>
<Version>0.9.707.0</Version> <Version>0.9.708.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright> <Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms> <Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName> <AssemblyName>Barotrauma</AssemblyName>
@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace> <RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors> <Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product> <Product>Barotrauma</Product>
<Version>0.9.707.0</Version> <Version>0.9.708.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright> <Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms> <Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName> <AssemblyName>Barotrauma</AssemblyName>
@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace> <RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors> <Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product> <Product>Barotrauma Dedicated Server</Product>
<Version>0.9.707.0</Version> <Version>0.9.708.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright> <Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms> <Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName> <AssemblyName>DedicatedServer</AssemblyName>
+1 -1
View File
@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace> <RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors> <Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product> <Product>Barotrauma Dedicated Server</Product>
<Version>0.9.707.0</Version> <Version>0.9.708.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright> <Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms> <Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName> <AssemblyName>DedicatedServer</AssemblyName>
@@ -627,7 +627,7 @@ namespace Barotrauma.Networking
//game already started -> send start message immediately //game already started -> send start message immediately
if (gameStarted) if (gameStarted)
{ {
SendStartMessage(roundStartSeed, GameMain.GameSession.Level.Seed, Submarine.MainSub, GameMain.GameSession.GameMode.Preset, connectedClient, true); SendStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.GameMode.Preset, connectedClient);
} }
} }
break; break;
@@ -1796,8 +1796,6 @@ namespace Barotrauma.Networking
campaign.Map.SelectRandomLocation(preferUndiscovered: true); campaign.Map.SelectRandomLocation(preferUndiscovered: true);
} }
SendStartMessage(roundStartSeed, campaign.Map.SelectedConnection.Level.Seed, Submarine.MainSub, GameMain.GameSession.GameMode.Preset, connectedClients, false);
GameMain.GameSession.StartRound(campaign.Map.SelectedConnection.Level, GameMain.GameSession.StartRound(campaign.Map.SelectedConnection.Level,
reloadSub: true, reloadSub: true,
loadSecondSub: teamCount > 1, loadSecondSub: teamCount > 1,
@@ -1810,8 +1808,6 @@ namespace Barotrauma.Networking
} }
else else
{ {
SendStartMessage(roundStartSeed, GameMain.NetLobbyScreen.LevelSeed, Submarine.MainSub, GameMain.GameSession.GameMode.Preset, connectedClients, false);
GameMain.GameSession.StartRound(GameMain.NetLobbyScreen.LevelSeed, serverSettings.SelectedLevelDifficulty, teamCount > 1); GameMain.GameSession.StartRound(GameMain.NetLobbyScreen.LevelSeed, serverSettings.SelectedLevelDifficulty, teamCount > 1);
Log("Game mode: " + selectedMode.Name, ServerLog.MessageType.ServerMessage); Log("Game mode: " + selectedMode.Name, ServerLog.MessageType.ServerMessage);
Log("Submarine: " + selectedSub.Name, ServerLog.MessageType.ServerMessage); Log("Submarine: " + selectedSub.Name, ServerLog.MessageType.ServerMessage);
@@ -1950,7 +1946,7 @@ namespace Barotrauma.Networking
GameAnalyticsManager.AddDesignEvent("Traitors:" + (TraitorManager == null ? "Disabled" : "Enabled")); GameAnalyticsManager.AddDesignEvent("Traitors:" + (TraitorManager == null ? "Disabled" : "Enabled"));
SendRoundStartFinalize(connectedClients); SendStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.GameMode.Preset, connectedClients);
yield return CoroutineStatus.Running; yield return CoroutineStatus.Running;
@@ -1969,21 +1965,22 @@ namespace Barotrauma.Networking
yield return CoroutineStatus.Success; yield return CoroutineStatus.Success;
} }
private void SendStartMessage(int seed, string levelSeed, Submarine selectedSub, GameModePreset selectedMode, List<Client> clients, bool includesFinalize) private void SendStartMessage(int seed, Submarine selectedSub, GameModePreset selectedMode, List<Client> clients)
{ {
foreach (Client client in clients) foreach (Client client in clients)
{ {
SendStartMessage(seed, levelSeed, selectedSub, selectedMode, client, includesFinalize); SendStartMessage(seed, selectedSub, selectedMode, client);
} }
} }
private void SendStartMessage(int seed, string levelSeed, Submarine selectedSub, GameModePreset selectedMode, Client client, bool includesFinalize) private void SendStartMessage(int seed, Submarine selectedSub, GameModePreset selectedMode, Client client)
{ {
IWriteMessage msg = new WriteOnlyMessage(); IWriteMessage msg = new WriteOnlyMessage();
msg.Write((byte)ServerPacketHeader.STARTGAME); msg.Write((byte)ServerPacketHeader.STARTGAME);
msg.Write(seed); msg.Write(seed);
msg.Write(levelSeed); msg.Write(GameMain.GameSession.Level.Seed);
msg.Write(GameMain.GameSession.Level.EqualityCheckVal);
msg.Write(serverSettings.SelectedLevelDifficulty); msg.Write(serverSettings.SelectedLevelDifficulty);
msg.Write((byte)GameMain.Config.LosMode); msg.Write((byte)GameMain.Config.LosMode);
@@ -2023,32 +2020,6 @@ namespace Barotrauma.Networking
serverSettings.WriteMonsterEnabled(msg); serverSettings.WriteMonsterEnabled(msg);
msg.Write(includesFinalize); msg.WritePadBits();
if (includesFinalize)
{
msg.Write(GameMain.GameSession.Level.EqualityCheckVal);
GameMain.GameSession.Mission?.ServerWriteInitial(msg, client);
}
//GameMain.GameSession.Mission?.ServerWriteInitial(msg, client);
serverPeer.Send(msg, client.Connection, DeliveryMethod.Reliable);
}
private void SendRoundStartFinalize(List<Client> clients)
{
foreach (Client client in clients)
{
SendRoundStartFinalize(client);
}
}
private void SendRoundStartFinalize(Client client)
{
IWriteMessage msg = new WriteOnlyMessage();
msg.Write((byte)ServerPacketHeader.STARTGAMEFINALIZE);
msg.Write(GameMain.GameSession.Level.EqualityCheckVal);
GameMain.GameSession.Mission?.ServerWriteInitial(msg, client); GameMain.GameSession.Mission?.ServerWriteInitial(msg, client);
serverPeer.Send(msg, client.Connection, DeliveryMethod.Reliable); serverPeer.Send(msg, client.Connection, DeliveryMethod.Reliable);
@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace> <RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors> <Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product> <Product>Barotrauma Dedicated Server</Product>
<Version>0.9.707.0</Version> <Version>0.9.708.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright> <Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms> <Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName> <AssemblyName>DedicatedServer</AssemblyName>
@@ -28,6 +28,8 @@ namespace Barotrauma
public float FadeOutTime { get; private set; } = 1; public float FadeOutTime { get; private set; } = 1;
public bool Static { get; private set; } public bool Static { get; private set; }
public bool StaticSound { get; private set; }
public bool StaticSight { get; private set; }
public float SoundRange public float SoundRange
{ {
@@ -152,8 +154,8 @@ namespace Barotrauma
else else
{ {
// Non-static ai targets must be kept alive by a custom logic (e.g. item components) // Non-static ai targets must be kept alive by a custom logic (e.g. item components)
SightRange = MinSightRange; SightRange = StaticSight ? MaxSightRange : MinSightRange;
SoundRange = MinSoundRange; SoundRange = StaticSound ? MaxSoundRange : MinSoundRange;
} }
} }
@@ -167,6 +169,13 @@ namespace Barotrauma
MaxSoundRange = element.GetAttributeFloat("maxsoundrange", SoundRange); MaxSoundRange = element.GetAttributeFloat("maxsoundrange", SoundRange);
FadeOutTime = element.GetAttributeFloat("fadeouttime", FadeOutTime); FadeOutTime = element.GetAttributeFloat("fadeouttime", FadeOutTime);
Static = element.GetAttributeBool("static", Static); Static = element.GetAttributeBool("static", Static);
StaticSight = element.GetAttributeBool("staticsight", StaticSight);
StaticSound = element.GetAttributeBool("staticsound", StaticSound);
if (Static)
{
StaticSound = true;
StaticSight = true;
}
SonarDisruption = element.GetAttributeFloat("sonardisruption", 0.0f); SonarDisruption = element.GetAttributeFloat("sonardisruption", 0.0f);
SonarLabel = element.GetAttributeString("sonarlabel", ""); SonarLabel = element.GetAttributeString("sonarlabel", "");
SonarIconIdentifier = element.GetAttributeString("sonaricon", ""); SonarIconIdentifier = element.GetAttributeString("sonaricon", "");
@@ -189,11 +198,37 @@ namespace Barotrauma
if (!Static && FadeOutTime > 0) if (!Static && FadeOutTime > 0)
{ {
// The aitarget goes silent/invisible if the components don't keep it active // The aitarget goes silent/invisible if the components don't keep it active
SightRange -= deltaTime * (MaxSightRange / FadeOutTime); if (!StaticSight)
SoundRange -= deltaTime * (MaxSoundRange / FadeOutTime); {
DecreaseSightRange(deltaTime);
}
if (!StaticSound)
{
DecreaseSoundRange(deltaTime);
}
} }
} }
public void IncreaseSoundRange(float deltaTime, float speed = 1)
{
SoundRange += speed * deltaTime * (MaxSoundRange / FadeOutTime);
}
public void IncreaseSightRange(float deltaTime, float speed = 1)
{
SightRange += speed * deltaTime * (MaxSightRange / FadeOutTime);
}
public void DecreaseSoundRange(float deltaTime, float speed = 1)
{
SoundRange -= speed * deltaTime * (MaxSoundRange / FadeOutTime);
}
public void DecreaseSightRange(float deltaTime, float speed = 1)
{
SightRange -= speed * deltaTime * (MaxSightRange / FadeOutTime);
}
public bool IsWithinSector(Vector2 worldPosition) public bool IsWithinSector(Vector2 worldPosition)
{ {
if (sectorRad >= MathHelper.TwoPi) return true; if (sectorRad >= MathHelper.TwoPi) return true;
@@ -313,6 +313,10 @@ namespace Barotrauma
selectedCharacter = value; selectedCharacter = value;
if (selectedCharacter != null) if (selectedCharacter != null)
selectedCharacter.selectedBy = this; selectedCharacter.selectedBy = this;
#if CLIENT
CharacterHealth.SetHealthBarVisibility(value == null);
#endif
} }
} }
@@ -262,37 +262,8 @@ namespace Barotrauma
#if CLIENT #if CLIENT
private Sprite jobIcon; private Sprite jobIcon;
private Vector2 jobIconPos
{
get { return new Vector2(HUDLayoutSettings.HealthBarAreaLeft.Right, HUDLayoutSettings.HealthBarAreaLeft.Y - HUDLayoutSettings.Padding); }
}
#endif #endif
private Sprite portraitBackground;
public Sprite PortraitBackground
{
get
{
if (portraitBackground == null)
{
var portraitBackgroundElement = CharacterConfigElement.Element("portraitbackground");
if (portraitBackgroundElement != null)
{
portraitBackground = new Sprite(portraitBackgroundElement.Element("sprite"));
}
}
return portraitBackground;
}
private set
{
if (portraitBackground != null)
{
portraitBackground.Remove();
}
portraitBackground = value;
}
}
private List<WearableSprite> attachmentSprites; private List<WearableSprite> attachmentSprites;
public List<WearableSprite> AttachmentSprites public List<WearableSprite> AttachmentSprites
{ {
@@ -956,8 +927,20 @@ namespace Barotrauma
DebugConsole.ThrowError("Invalid inventory data in character \"" + Name + "\" - no slot indices found"); DebugConsole.ThrowError("Invalid inventory data in character \"" + Name + "\" - no slot indices found");
continue; continue;
} }
//make sure there's no other item in the slot
//this should not happen normally, but can occur if the character is accidentally given new job items while also loading previous items in the campaign
for (int i = 0; i < inventory.Capacity; i++)
{
if (slotIndices.Contains(i) && inventory.Items[i] != null && inventory.Items[i] != newItem)
{
DebugConsole.ThrowError($"Error while loading character inventory data. The slot {i} was already occupied by the item \"{inventory.Items[i].Name} ({inventory.Items[i].ID})\" when loading the item \"{newItem.Name} ({newItem.ID})\"");
inventory.Items[i].Drop(null, createNetworkEvent: false);
}
}
inventory.TryPutItem(newItem, slotIndices[0], false, false, null); inventory.TryPutItem(newItem, slotIndices[0], false, false, null);
newItem.ParentInventory = inventory;
//force the item to the correct slots //force the item to the correct slots
// e.g. putting the item in a hand slot will also put it in the first available Any-slot, // e.g. putting the item in a hand slot will also put it in the first available Any-slot,
@@ -1016,7 +999,6 @@ namespace Barotrauma
Character = null; Character = null;
HeadSprite = null; HeadSprite = null;
Portrait = null; Portrait = null;
PortraitBackground = null;
AttachmentSprites = null; AttachmentSprites = null;
} }
} }
@@ -1436,6 +1436,7 @@ namespace Barotrauma
#endif #endif
} }
spawnedCharacter.GiveJobItems(spawnPoint); spawnedCharacter.GiveJobItems(spawnPoint);
spawnedCharacter.Info.StartItemsGiven = true;
} }
else else
{ {
@@ -41,6 +41,9 @@ namespace Barotrauma
private readonly List<ScriptedEvent> activeEvents = new List<ScriptedEvent>(); private readonly List<ScriptedEvent> activeEvents = new List<ScriptedEvent>();
#if DEBUG && SERVER
private DateTime nextIntensityLogTime;
#endif
private EventManagerSettings settings; private EventManagerSettings settings;
@@ -86,7 +89,6 @@ namespace Barotrauma
intensityUpdateTimer = 0.0f; intensityUpdateTimer = 0.0f;
CalculateCurrentIntensity(0.0f); CalculateCurrentIntensity(0.0f);
currentIntensity = targetIntensity; currentIntensity = targetIntensity;
eventThreshold = settings.DefaultEventThreshold;
eventCoolDown = 0.0f; eventCoolDown = 0.0f;
} }
@@ -114,6 +116,10 @@ namespace Barotrauma
{ {
settings = suitableSettings[Rand.Int(suitableSettings.Count, Rand.RandSync.Server)]; settings = suitableSettings[Rand.Int(suitableSettings.Count, Rand.RandSync.Server)];
} }
if (settings != null)
{
eventThreshold = settings.DefaultEventThreshold;
}
} }
public IEnumerable<ContentFile> GetFilesToPreload() public IEnumerable<ContentFile> GetFilesToPreload()
@@ -320,6 +326,14 @@ namespace Barotrauma
//(the intensity is used for controlling the background music) //(the intensity is used for controlling the background music)
CalculateCurrentIntensity(deltaTime); CalculateCurrentIntensity(deltaTime);
#if DEBUG && SERVER
if (DateTime.Now > nextIntensityLogTime)
{
DebugConsole.NewMessage("EventManager intensity: " + (int)Math.Round(currentIntensity * 100) + " %");
nextIntensityLogTime = DateTime.Now + new TimeSpan(0, minutes: 1, seconds: 0);
}
#endif
if (isClient) { return; } if (isClient) { return; }
roundDuration += deltaTime; roundDuration += deltaTime;
@@ -331,6 +345,9 @@ namespace Barotrauma
if (settings == null) if (settings == null)
{ {
DebugConsole.ThrowError("Could not select EventManager settings. Disabling EventManager for the round..."); DebugConsole.ThrowError("Could not select EventManager settings. Disabling EventManager for the round...");
#if SERVER
GameMain.Server?.SendChatMessage("Could not select EventManager settings. Disabling EventManager for the round...", Networking.ChatMessageType.Error);
#endif
Enabled = false; Enabled = false;
return; return;
} }
@@ -393,19 +410,20 @@ namespace Barotrauma
int characterCount = 0; int characterCount = 0;
foreach (Character character in Character.CharacterList) foreach (Character character in Character.CharacterList)
{ {
if (character.IsDead) continue; if (character.IsDead || character.TeamID == Character.TeamType.FriendlyNPC) { continue; }
#if CLIENT if (character.AIController is HumanAIController || character.IsRemotePlayer)
if ((character.AIController is HumanAIController || character.IsRemotePlayer || character == Character.Controlled) &&
(GameMain.Client?.Character == null || GameMain.Client.Character.TeamID == character.TeamID))
{ {
avgCrewHealth += character.Vitality / character.MaxVitality * (character.IsUnconscious ? 0.5f : 1.0f); avgCrewHealth += character.Vitality / character.MaxVitality * (character.IsUnconscious ? 0.5f : 1.0f);
characterCount++; characterCount++;
} }
#endif
} }
if (characterCount > 0) if (characterCount > 0)
{ {
avgCrewHealth = avgCrewHealth / characterCount; avgCrewHealth /= characterCount;
}
else
{
avgCrewHealth = 0.5f;
} }
// enemy amount -------------------------------------------------------- // enemy amount --------------------------------------------------------
@@ -21,9 +21,6 @@ namespace Barotrauma
public readonly float EventCooldown = 360.0f; public readonly float EventCooldown = 360.0f;
public readonly float MinEventDifficulty = 0.0f;
public readonly float MaxEventDifficulty = 100.0f;
public readonly float MinLevelDifficulty = 0.0f; public readonly float MinLevelDifficulty = 0.0f;
public readonly float MaxLevelDifficulty = 100.0f; public readonly float MaxLevelDifficulty = 100.0f;
@@ -77,9 +74,6 @@ namespace Barotrauma
DefaultEventThreshold = element.GetAttributeFloat("DefaultEventThreshold", 0.2f); DefaultEventThreshold = element.GetAttributeFloat("DefaultEventThreshold", 0.2f);
EventCooldown = element.GetAttributeFloat("EventCooldown", 360.0f); EventCooldown = element.GetAttributeFloat("EventCooldown", 360.0f);
MinEventDifficulty = element.GetAttributeFloat("MinEventDifficulty", 0.0f);
MaxEventDifficulty = element.GetAttributeFloat("MaxEventDifficulty", 100.0f);
MinLevelDifficulty = element.GetAttributeFloat("MinLevelDifficulty", 0.0f); MinLevelDifficulty = element.GetAttributeFloat("MinLevelDifficulty", 0.0f);
MaxLevelDifficulty = element.GetAttributeFloat("MaxLevelDifficulty", 100.0f); MaxLevelDifficulty = element.GetAttributeFloat("MaxLevelDifficulty", 100.0f);
} }
@@ -261,32 +261,43 @@ namespace Barotrauma.Items.Components
if (picker.Inventory == null) { return; } if (picker.Inventory == null) { return; }
item.Submarine = picker.Submarine; item.Submarine = picker.Submarine;
if (item.body != null) if (item.body != null)
{ {
item.body.ResetDynamics(); if (item.body.Removed)
Limb heldHand, arm;
if (picker.Inventory.IsInLimbSlot(item, InvSlotType.LeftHand))
{ {
heldHand = picker.AnimController.GetLimb(LimbType.LeftHand); DebugConsole.ThrowError(
arm = picker.AnimController.GetLimb(LimbType.LeftArm); "Failed to drop the Holdable component of the item \"" + item.Name + "\" (body has been removed"
+ (item.Removed ? ", item has been removed)" : ")"));
} }
else else
{ {
heldHand = picker.AnimController.GetLimb(LimbType.RightHand); item.body.ResetDynamics();
arm = picker.AnimController.GetLimb(LimbType.RightArm); Limb heldHand, arm;
if (picker.Inventory.IsInLimbSlot(item, InvSlotType.LeftHand))
{
heldHand = picker.AnimController.GetLimb(LimbType.LeftHand);
arm = picker.AnimController.GetLimb(LimbType.LeftArm);
}
else
{
heldHand = picker.AnimController.GetLimb(LimbType.RightHand);
arm = picker.AnimController.GetLimb(LimbType.RightArm);
}
if (heldHand != null && arm != null)
{
//hand simPosition is actually in the wrist so need to move the item out from it slightly
Vector2 diff = new Vector2(
(heldHand.SimPosition.X - arm.SimPosition.X) / 2f,
(heldHand.SimPosition.Y - arm.SimPosition.Y) / 2.5f);
item.SetTransform(heldHand.SimPosition + diff, 0.0f);
}
else
{
item.SetTransform(picker.SimPosition, 0.0f);
}
} }
if (heldHand != null && arm != null)
{
//hand simPosition is actually in the wrist so need to move the item out from it slightly
Vector2 diff = new Vector2(
(heldHand.SimPosition.X - arm.SimPosition.X) / 2f,
(heldHand.SimPosition.Y - arm.SimPosition.Y) / 2.5f);
item.SetTransform(heldHand.SimPosition + diff, 0.0f);
}
else
{
item.SetTransform(picker.SimPosition, 0.0f);
}
} }
picker.DeselectItem(item); picker.DeselectItem(item);
@@ -204,14 +204,14 @@ namespace Barotrauma.Items.Components
if (picker == null || picker.Inventory == null) if (picker == null || picker.Inventory == null)
{ {
if (item.ParentInventory != null && item.ParentInventory.Owner != null) if (item.ParentInventory != null && item.ParentInventory.Owner != null && !item.ParentInventory.Owner.Removed)
{ {
bodyDropPos = item.ParentInventory.Owner.SimPosition; bodyDropPos = item.ParentInventory.Owner.SimPosition;
if (item.body != null) item.body.ResetDynamics(); if (item.body != null) item.body.ResetDynamics();
} }
} }
else else if (!picker.Removed)
{ {
DropConnectedWires(picker); DropConnectedWires(picker);
@@ -224,9 +224,18 @@ namespace Barotrauma.Items.Components
if (item.body != null && !item.body.Enabled) if (item.body != null && !item.body.Enabled)
{ {
item.body.ResetDynamics(); if (item.body.Removed)
item.SetTransform(bodyDropPos, 0.0f); {
item.body.Enabled = true; DebugConsole.ThrowError(
"Failed to drop the Pickable component of the item \"" + item.Name + "\" (body has been removed"
+ (item.Removed ? ", item has been removed)" : ")"));
}
else
{
item.body.ResetDynamics();
item.SetTransform(bodyDropPos, 0.0f);
item.body.Enabled = true;
}
} }
} }
@@ -101,22 +101,14 @@ namespace Barotrauma.Items.Components
Vector2 currForce = new Vector2(force * maxForce * forceMultiplier * voltageFactor, 0.0f); Vector2 currForce = new Vector2(force * maxForce * forceMultiplier * voltageFactor, 0.0f);
//less effective when in a bad condition //less effective when in a bad condition
currForce *= MathHelper.Lerp(0.5f, 2.0f, item.Condition / item.MaxCondition); currForce *= MathHelper.Lerp(0.5f, 2.0f, item.Condition / item.MaxCondition);
item.Submarine.ApplyForce(currForce); item.Submarine.ApplyForce(currForce);
UpdatePropellerDamage(deltaTime); UpdatePropellerDamage(deltaTime);
float maxChangeSpeed = 0.5f;
if (item.AiTarget != null) float modifier = 2;
{ float noise = currForce.Length() * forceMultiplier * modifier / maxForce;
var aiTarget = item.AiTarget; float min = Math.Max(1 - maxChangeSpeed, 0);
aiTarget.SoundRange = MathHelper.Lerp(aiTarget.MinSoundRange, aiTarget.MaxSoundRange, Math.Min(currForce.Length() * forceMultiplier / maxForce, 1.0f)); float max = 1 + maxChangeSpeed;
} UpdateAITargets(Math.Clamp(noise, min, max), deltaTime);
if (item.CurrentHull != null)
{
var aiTarget = item.CurrentHull.AiTarget;
float noise = MathHelper.Lerp(aiTarget.MinSoundRange, aiTarget.MaxSoundRange, Math.Min(currForce.Length() * forceMultiplier / maxForce, 1.0f));
aiTarget.SoundRange = Math.Max(noise, aiTarget.SoundRange);
}
#if CLIENT #if CLIENT
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{ {
@@ -128,6 +120,19 @@ namespace Barotrauma.Items.Components
} }
} }
private void UpdateAITargets(float increaseSpeed, float deltaTime)
{
if (item.AiTarget != null)
{
item.AiTarget.IncreaseSoundRange(deltaTime, increaseSpeed);
if (item.CurrentHull != null && item.CurrentHull.AiTarget != null)
{
// It's possible that some othe item increases the hull's soundrange more than the engine.
item.CurrentHull.AiTarget.SoundRange = Math.Max(item.CurrentHull.AiTarget.SoundRange, item.AiTarget.SoundRange);
}
}
}
private void UpdatePropellerDamage(float deltaTime) private void UpdatePropellerDamage(float deltaTime)
{ {
damageTimer += deltaTime; damageTimer += deltaTime;
@@ -1279,10 +1279,10 @@ namespace Barotrauma
} }
} }
if (!isActive) { return; }
aiTarget?.Update(deltaTime); aiTarget?.Update(deltaTime);
if (!isActive) { return; }
ApplyStatusEffects(ActionType.Always, deltaTime, character: (parentInventory as CharacterInventory)?.Owner as Character); ApplyStatusEffects(ActionType.Always, deltaTime, character: (parentInventory as CharacterInventory)?.Owner as Character);
for (int i = 0; i < updateableComponents.Count; i++) for (int i = 0; i < updateableComponents.Count; i++)
@@ -1988,7 +1988,9 @@ namespace Barotrauma
{ {
if (body.Removed) if (body.Removed)
{ {
DebugConsole.ThrowError("Failed to drop the item \"" + Name + "\" (body has been removed)."); DebugConsole.ThrowError(
"Failed to drop the item \"" + Name + "\" (body has been removed"
+ (Removed ? ", item has been removed)" : ")"));
} }
else else
{ {
@@ -60,7 +60,6 @@ namespace Barotrauma.Networking
QUERY_STARTGAME, //ask the clients whether they're ready to start QUERY_STARTGAME, //ask the clients whether they're ready to start
STARTGAME, //start a new round STARTGAME, //start a new round
STARTGAMEFINALIZE, //finalize round initialization
ENDGAME, ENDGAME,
TRAITOR_MESSAGE, TRAITOR_MESSAGE,
+18
View File
@@ -1,3 +1,21 @@
---------------------------------------------------------------------------------------------------------
v0.9.708.0
---------------------------------------------------------------------------------------------------------
- Minor UI improvements.
- Reverted "improved the way clients initialize rounds to prevent timeouts if loading the round takes too long". There were a couple of oversights in the logic that caused issues such as combat missions not starting and campaign failing to start after the first completed round.
- Fixed EventManager intensity being calculated incorrectly in multiplayer, causing monster spawns to be more sparse in multiplayer than in singleplayer.
- Updated tutorial videos.
- Increased duffel bag capacity to 20 to make sure it can hold all the items in a character's inventory (+ a couple more).
- Fixed "Commando" security officer variant spawning without an SMG magazine.
- Potential fix to crashes in "Body.SetTransformIgnoreContacts".
- Fixed bots spawned with the "spawn" console command being unable to communicate via headsets after the first round in the single player campaign.
- Fixed engine's AI target changing it's range too rapidly when the engine's force changes rapidly, causing monsters to often lose track of the sub after just spotting it.
- Do not allow steering input on the nav terminal while command interface is enabled.
- Fixed lobby command (which switches to the single player lobby) being usable in multiplayer.
- Prevented chat message popups (the individual messages that popup when the chatbox is hidden) from getting cursor focus and blocking turret usage.
- Made reactor's fuel rod panel a little larger.
--------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------
v0.9.707.0 v0.9.707.0
--------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------