diff --git a/Barotrauma/BarotraumaClient/ClientCode.projitems b/Barotrauma/BarotraumaClient/ClientCode.projitems
index 96e169d05..26cd574b9 100644
--- a/Barotrauma/BarotraumaClient/ClientCode.projitems
+++ b/Barotrauma/BarotraumaClient/ClientCode.projitems
@@ -202,6 +202,8 @@
+
+
@@ -220,7 +222,6 @@
- Never
diff --git a/Barotrauma/BarotraumaClient/LinuxClient.csproj b/Barotrauma/BarotraumaClient/LinuxClient.csproj
index c96a76c05..a96474014 100644
--- a/Barotrauma/BarotraumaClient/LinuxClient.csproj
+++ b/Barotrauma/BarotraumaClient/LinuxClient.csproj
@@ -118,9 +118,6 @@
PreserveNewest
-
- PreserveNewest
-
PreserveNewest
@@ -350,7 +347,7 @@
-
+
@@ -368,8 +365,9 @@
-
+
-
+
+
\ No newline at end of file
diff --git a/Barotrauma/BarotraumaClient/MacClient.csproj b/Barotrauma/BarotraumaClient/MacClient.csproj
index b57d6b7cc..82c7835d0 100644
--- a/Barotrauma/BarotraumaClient/MacClient.csproj
+++ b/Barotrauma/BarotraumaClient/MacClient.csproj
@@ -117,9 +117,6 @@
PreserveNewest
-
- PreserveNewest
-
PreserveNewest
diff --git a/Barotrauma/BarotraumaClient/OpenAL32.dll b/Barotrauma/BarotraumaClient/OpenAL32.dll
deleted file mode 100644
index f903a0c63..000000000
Binary files a/Barotrauma/BarotraumaClient/OpenAL32.dll and /dev/null differ
diff --git a/Barotrauma/BarotraumaClient/OpenTK.dll.config b/Barotrauma/BarotraumaClient/OpenTK.dll.config
deleted file mode 100644
index 140d56665..000000000
--- a/Barotrauma/BarotraumaClient/OpenTK.dll.config
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Barotrauma/BarotraumaClient/Source/Characters/AI/AITarget.cs b/Barotrauma/BarotraumaClient/Source/Characters/AI/AITarget.cs
index 318d1d048..73c1c27ad 100644
--- a/Barotrauma/BarotraumaClient/Source/Characters/AI/AITarget.cs
+++ b/Barotrauma/BarotraumaClient/Source/Characters/AI/AITarget.cs
@@ -39,10 +39,14 @@ namespace Barotrauma
else if (Entity is Item)
{
color = Color.CadetBlue;
+ // disable the indicators for items, because they clutter the debug view
+ return;
}
else
{
color = Color.WhiteSmoke;
+ // disable the indicators for structures, because they clutter the debug view
+ return;
}
ShapeExtensions.DrawCircle(spriteBatch, pos, SightRange, 100, color, thickness: 1 / Screen.Selected.Cam.Zoom);
ShapeExtensions.DrawCircle(spriteBatch, pos, 6, 8, color, thickness: 2 / Screen.Selected.Cam.Zoom);
diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs b/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs
index 2e11c7af2..aae0a57f9 100644
--- a/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs
+++ b/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs
@@ -219,7 +219,7 @@ namespace Barotrauma
{
//hull subs don't match => teleport the camera to the other sub
character.Submarine = serverHull.Submarine;
- character.CurrentHull = currentHull = serverHull;
+ character.CurrentHull = CurrentHull = serverHull;
SetPosition(serverPos.Position);
character.MemLocalState.Clear();
}
@@ -369,11 +369,11 @@ namespace Barotrauma
LimbJoints.ForEach(j => j.UpdateDeformations(deltaTime));
foreach (var deformation in SpriteDeformations)
{
+ if (character.IsDead && deformation.DeformationParams.StopWhenHostIsDead) { continue; }
if (deformation.DeformationParams.UseMovementSine)
{
if (this is AnimController animator)
{
- //deformation.Phase = MathUtils.WrapAngleTwoPi(animator.WalkPos + MathHelper.Pi);
deformation.Phase = MathUtils.WrapAngleTwoPi(animator.WalkPos * deformation.DeformationParams.Frequency + MathHelper.Pi * deformation.DeformationParams.SineOffset);
}
}
diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Limb.cs b/Barotrauma/BarotraumaClient/Source/Characters/Limb.cs
index 63beecb56..a3d57f795 100644
--- a/Barotrauma/BarotraumaClient/Source/Characters/Limb.cs
+++ b/Barotrauma/BarotraumaClient/Source/Characters/Limb.cs
@@ -538,13 +538,10 @@ namespace Barotrauma
if (wearable.InheritLimbDepth)
{
depth = ActiveSprite.Depth - depthStep;
- if (wearable.DepthLimb != LimbType.None)
+ Limb depthLimb = (wearable.DepthLimb == LimbType.None) ? this : character.AnimController.GetLimb(wearable.DepthLimb);
+ if (depthLimb != null)
{
- Limb depthLimb = character.AnimController.GetLimb(wearable.DepthLimb);
- if (depthLimb != null)
- {
- depth = depthLimb.ActiveSprite.Depth - depthStep;
- }
+ depth = depthLimb.ActiveSprite.Depth - depthStep;
}
}
var wearableItemComponent = wearable.WearableComponent;
diff --git a/Barotrauma/BarotraumaClient/Source/DebugConsole.cs b/Barotrauma/BarotraumaClient/Source/DebugConsole.cs
index f8a34fd0f..e2ba2d983 100644
--- a/Barotrauma/BarotraumaClient/Source/DebugConsole.cs
+++ b/Barotrauma/BarotraumaClient/Source/DebugConsole.cs
@@ -62,9 +62,21 @@ namespace Barotrauma
{
frame = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.45f), GUI.Canvas) { MinSize = new Point(400, 300), AbsoluteOffset = new Point(10, 10) },
color: new Color(0.4f, 0.4f, 0.4f, 0.8f));
+
var paddedFrame = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.9f), frame.RectTransform, Anchor.Center), style: null);
- listBox = new GUIListBox(new RectTransform(new Point(paddedFrame.Rect.Width, paddedFrame.Rect.Height - 30), paddedFrame.RectTransform)
+ var toggleText = new GUITextBlock(new RectTransform(new Point(paddedFrame.Rect.Width-30, 20), paddedFrame.RectTransform, Anchor.TopLeft), TextManager.Get("DebugConsoleHelpText"), new Color(150,150,200,255), GUI.SmallFont, Alignment.CenterLeft, style: null);
+
+ var closeButton = new GUIButton(new RectTransform(new Point(20, 20), paddedFrame.RectTransform, Anchor.TopRight), "X", color: Color.Red);
+ closeButton.OnClicked += (btn, userdata) =>
+ {
+ isOpen = false;
+ GUI.ForceMouseOn(null);
+ textBox.Deselect();
+ return true;
+ };
+
+ listBox = new GUIListBox(new RectTransform(new Point(paddedFrame.Rect.Width, paddedFrame.Rect.Height - 50), paddedFrame.RectTransform, Anchor.Center)
{
IsFixedSize = false
}, color: Color.Black * 0.9f);
@@ -80,9 +92,6 @@ namespace Barotrauma
ResetAutoComplete();
}
};
-
- NewMessage("Press F3 to open/close the debug console", Color.Cyan);
- NewMessage("Enter \"help\" for a list of available console commands", Color.Cyan);
}
public static void AddToGUIUpdateList()
@@ -130,6 +139,12 @@ namespace Barotrauma
textBox.Deselect();
}
}
+ else if (isOpen && PlayerInput.KeyHit(Keys.Escape))
+ {
+ isOpen = false;
+ GUI.ForceMouseOn(null);
+ textBox.Deselect();
+ }
if (isOpen)
{
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs
index be2740daa..f81002868 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs
@@ -230,11 +230,18 @@ namespace Barotrauma
if (GameMain.ShowPerf)
{
int y = 10;
- DrawString(spriteBatch, new Vector2(300, y), "Draw - Max val: " + GameMain.PerformanceCounter.DrawTimeGraph.LargestValue()+" ms", Color.Green, Color.Black * 0.8f, font: GUI.SmallFont);
+ DrawString(spriteBatch, new Vector2(300, y),
+ "Draw - Avg: " + GameMain.PerformanceCounter.DrawTimeGraph.Average().ToString("0.00") + " ms" +
+ " Max: " + GameMain.PerformanceCounter.DrawTimeGraph.LargestValue().ToString("0.00") + " ms",
+ Color.Green, Color.Black * 0.8f, font: SmallFont);
y += 15;
GameMain.PerformanceCounter.DrawTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), null, 0, Color.Green);
y += 50;
- DrawString(spriteBatch, new Vector2(300, y), "Update - Max val: " + GameMain.PerformanceCounter.UpdateTimeGraph.LargestValue() + " ms", Color.LightBlue, Color.Black * 0.8f, font: GUI.SmallFont);
+
+ DrawString(spriteBatch, new Vector2(300, y),
+ "Update - Avg: " + GameMain.PerformanceCounter.UpdateTimeGraph.Average().ToString("0.00") + " ms" +
+ " Max: " + GameMain.PerformanceCounter.UpdateTimeGraph.LargestValue().ToString("0.00") + " ms",
+ Color.LightBlue, Color.Black * 0.8f, font: SmallFont);
y += 15;
GameMain.PerformanceCounter.UpdateTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), null, 0, Color.LightBlue);
GameMain.PerformanceCounter.UpdateIterationsGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), 20, 0, Color.Red);
@@ -243,7 +250,7 @@ namespace Barotrauma
{
float elapsedMillisecs = GameMain.PerformanceCounter.GetAverageElapsedMillisecs(key);
DrawString(spriteBatch, new Vector2(300, y),
- key + ": " + elapsedMillisecs,
+ key + ": " + elapsedMillisecs.ToString("0.00"),
Color.Lerp(Color.LightGreen, Color.Red, elapsedMillisecs / 10.0f), Color.Black * 0.5f, 0, SmallFont);
y += 15;
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUILayoutGroup.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUILayoutGroup.cs
index 18cbe23c7..e797b022a 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/GUILayoutGroup.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/GUILayoutGroup.cs
@@ -85,7 +85,9 @@ namespace Barotrauma
{
float totalSize = RectTransform.Children
.Where(c => !c.GUIComponent.IgnoreLayoutGroups)
- .Sum(c => isHorizontal ? c.Rect.Width : c.Rect.Height);
+ .Sum(c => isHorizontal ?
+ MathHelper.Clamp(c.Rect.Width, c.MinSize.X, c.MaxSize.X) :
+ MathHelper.Clamp(c.Rect.Height, c.MinSize.Y, c.MaxSize.Y));
totalSize +=
(RectTransform.Children.Count() - 1) *
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUINumberInput.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUINumberInput.cs
index 9ee247a23..2d631d19d 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/GUINumberInput.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/GUINumberInput.cs
@@ -117,7 +117,9 @@ namespace Barotrauma
{
LayoutGroup = new GUILayoutGroup(new RectTransform(Vector2.One, rectT), isHorizontal: true) { Stretch = true };
- TextBox = new GUITextBox(new RectTransform(Vector2.One, LayoutGroup.RectTransform), textAlignment: textAlignment, style: style)
+ float relativeButtonAreaWidth = MathHelper.Clamp(Rect.Height / (float)Rect.Width, 0.1f, 0.5f);
+
+ TextBox = new GUITextBox(new RectTransform(new Vector2(1.0f - relativeButtonAreaWidth, 1.0f), LayoutGroup.RectTransform), textAlignment: textAlignment, style: style)
{
ClampText = false,
// For some reason the caret in the number inputs is dimmer than it should.
@@ -126,7 +128,7 @@ namespace Barotrauma
CaretColor = Color.White
};
TextBox.OnTextChanged += TextChanged;
- var buttonArea = new GUIFrame(new RectTransform(new Vector2(0.02f, 1.0f), LayoutGroup.RectTransform, Anchor.CenterRight) { MinSize = new Point(Rect.Height, 0) }, style: null);
+ var buttonArea = new GUIFrame(new RectTransform(new Vector2(relativeButtonAreaWidth, 1.0f), LayoutGroup.RectTransform, Anchor.CenterRight) { MinSize = new Point(Rect.Height, 0) }, style: null);
PlusButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.5f), buttonArea.RectTransform), "+");
PlusButton.OnButtonDown += () =>
{
@@ -201,6 +203,8 @@ namespace Barotrauma
TextBox.textFilterFunction = text => new string(text.Where(c => char.IsDigit(c) || c == '.' || c == '-').ToArray());
break;
}
+
+ LayoutGroup.Recalculate();
}
private void ReduceValue()
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIStyle.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIStyle.cs
index e93f22c76..780264181 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/GUIStyle.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIStyle.cs
@@ -35,8 +35,6 @@ namespace Barotrauma
this.graphicsDevice = graphicsDevice;
componentStyles = new Dictionary();
- GameMain.Instance.OnResolutionChanged += () => { RescaleFonts(); };
-
XDocument doc;
try
{
@@ -89,6 +87,8 @@ namespace Barotrauma
break;
}
}
+
+ GameMain.Instance.OnResolutionChanged += () => { RescaleFonts(); };
}
///
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs
index 5192c5a0f..8692bf140 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs
@@ -20,6 +20,7 @@ namespace Barotrauma
protected Color textColor;
private string wrappedText;
+ private string censoredText;
public delegate string TextGetterHandler();
public TextGetterHandler TextGetter;
@@ -175,6 +176,17 @@ namespace Barotrauma
SetTextPos();
}
}
+
+ public bool Censor
+ {
+ get;
+ set;
+ }
+
+ public string CensoredText
+ {
+ get { return censoredText; }
+ }
///
/// This is the new constructor.
@@ -204,6 +216,8 @@ namespace Barotrauma
RectTransform.ScaleChanged += SetTextPos;
RectTransform.SizeChanged += SetTextPos;
+
+ Censor = false;
}
public void CalculateHeightFromText()
@@ -225,13 +239,19 @@ namespace Barotrauma
{
if (text == null) return;
+ censoredText = "";
+ for (int i=0;i 0)
{
wrappedText = ToolBox.WrapText(text, rect.Width - padding.X - padding.Z, Font, textScale);
@@ -338,7 +358,7 @@ namespace Barotrauma
}
Font.DrawString(spriteBatch,
- Wrap ? wrappedText : text,
+ Censor ? censoredText : (Wrap ? wrappedText : text),
pos,
textColor * (textColor.A / 255.0f),
0.0f, origin, TextScale,
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUITextBox.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUITextBox.cs
index 886e5aa2c..94ace0ef1 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/GUITextBox.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/GUITextBox.cs
@@ -142,6 +142,12 @@ namespace Barotrauma
}
}
+ public bool Censor
+ {
+ get { return textBlock.Censor; }
+ set { textBlock.Censor = value; }
+ }
+
public override string ToolTip
{
get
@@ -253,9 +259,12 @@ namespace Barotrauma
textBlock.Text = textBlock.Text.Substring(0, (int)maxTextLength);
}
}
- else if (ClampText && Font.MeasureString(textBlock.Text).X > (int)(textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z))
+ else
{
- textBlock.Text = textBlock.Text.Substring(0, textBlock.Text.Length - 1);
+ while (ClampText && textBlock.Text.Length>0 && Font.MeasureString(textBlock.Text).X > (int)(textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z))
+ {
+ textBlock.Text = textBlock.Text.Substring(0, textBlock.Text.Length - 1);
+ }
}
}
if (store)
@@ -267,9 +276,10 @@ namespace Barotrauma
private void CalculateCaretPos()
{
- if (textBlock.WrappedText.Contains("\n"))
+ string textDrawn = Censor ? textBlock.CensoredText : textBlock.WrappedText;
+ if (textDrawn.Contains("\n"))
{
- string[] lines = textBlock.WrappedText.Split('\n');
+ string[] lines = textDrawn.Split('\n');
int totalIndex = 0;
for (int i = 0; i < lines.Length; i++)
{
@@ -282,7 +292,7 @@ namespace Barotrauma
int index = currentLineLength - diff;
Vector2 lineTextSize = Font.MeasureString(lines[i].Substring(0, index));
Vector2 lastLineSize = Font.MeasureString(lines[i]);
- float totalTextHeight = Font.MeasureString(textBlock.WrappedText.Substring(0, totalIndex)).Y;
+ float totalTextHeight = Font.MeasureString(textDrawn.Substring(0, totalIndex)).Y;
caretPos = new Vector2(lineTextSize.X, totalTextHeight - lastLineSize.Y) + textBlock.TextPos - textBlock.Origin;
break;
}
@@ -290,7 +300,8 @@ namespace Barotrauma
}
else
{
- Vector2 textSize = Font.MeasureString(textBlock.Text.Substring(0, CaretIndex));
+ textDrawn = Censor ? textBlock.CensoredText : textBlock.Text;
+ Vector2 textSize = Font.MeasureString(textDrawn.Substring(0, CaretIndex));
caretPos = new Vector2(textSize.X, 0) + textBlock.TextPos - textBlock.Origin;
}
caretPosDirty = false;
@@ -298,17 +309,18 @@ namespace Barotrauma
protected List> GetAllPositions()
{
+ string textDrawn = Censor ? textBlock.CensoredText : textBlock.WrappedText;
var positions = new List>();
- if (textBlock.WrappedText.Contains("\n"))
+ if (textDrawn.Contains("\n"))
{
- string[] lines = textBlock.WrappedText.Split('\n');
+ string[] lines = textDrawn.Split('\n');
int index = 0;
int totalIndex = 0;
for (int i = 0; i < lines.Length; i++)
{
string line = lines[i];
totalIndex += line.Length;
- float totalTextHeight = Font.MeasureString(textBlock.WrappedText.Substring(0, totalIndex)).Y;
+ float totalTextHeight = Font.MeasureString(textDrawn.Substring(0, totalIndex)).Y;
for (int j = 0; j <= line.Length; j++)
{
Vector2 lineTextSize = Font.MeasureString(line.Substring(0, j));
@@ -321,9 +333,10 @@ namespace Barotrauma
}
else
{
+ textDrawn = Censor ? textBlock.CensoredText : textBlock.Text;
for (int i = 0; i <= textBlock.Text.Length; i++)
{
- Vector2 textSize = Font.MeasureString(textBlock.Text.Substring(0, i));
+ Vector2 textSize = Font.MeasureString(textDrawn.Substring(0, i));
Vector2 indexPos = new Vector2(textSize.X + textBlock.Padding.X, textSize.Y + textBlock.Padding.Y) + textBlock.TextPos - textBlock.Origin;
//DebugConsole.NewMessage($"index: {i}, pos: {indexPos}", Color.WhiteSmoke);
positions.Add(new Tuple(textBlock.Rect.Location.ToVector2() + indexPos, i));
@@ -822,6 +835,7 @@ namespace Barotrauma
private void CalculateSelection()
{
+ string textDrawn = Censor ? textBlock.CensoredText : textBlock.WrappedText;
InitSelectionStart();
selectionEndIndex = CaretIndex;
selectionEndPos = caretPos;
@@ -829,12 +843,12 @@ namespace Barotrauma
if (IsLeftToRight)
{
selectedText = Text.Substring(selectionStartIndex, selectedCharacters);
- selectionRectSize = Font.MeasureString(textBlock.WrappedText.Substring(selectionStartIndex, selectedCharacters));
+ selectionRectSize = Font.MeasureString(textDrawn.Substring(selectionStartIndex, selectedCharacters));
}
else
{
selectedText = Text.Substring(selectionEndIndex, selectedCharacters);
- selectionRectSize = Font.MeasureString(textBlock.WrappedText.Substring(selectionEndIndex, selectedCharacters));
+ selectionRectSize = Font.MeasureString(textDrawn.Substring(selectionEndIndex, selectedCharacters));
}
}
}
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/RectTransform.cs b/Barotrauma/BarotraumaClient/Source/GUI/RectTransform.cs
index 365a9a2a9..b2eca2968 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/RectTransform.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/RectTransform.cs
@@ -21,6 +21,11 @@ namespace Barotrauma
BottomLeft, BottomCenter, BottomRight
}
+ public enum ScaleBasis
+ {
+ Normal, BothWidth, BothHeight
+ }
+
public class RectTransform
{
#region Fields and Properties
@@ -286,6 +291,8 @@ namespace Barotrauma
}
}
+ private ScaleBasis scaleBasis;
+
public bool IsLastChild
{
get
@@ -320,9 +327,10 @@ namespace Barotrauma
#endregion
#region Initialization
- public RectTransform(Vector2 relativeSize, RectTransform parent, Anchor anchor = Anchor.TopLeft, Pivot? pivot = null, Point? minSize = null, Point? maxSize = null)
+ public RectTransform(Vector2 relativeSize, RectTransform parent, Anchor anchor = Anchor.TopLeft, Pivot? pivot = null, Point? minSize = null, Point? maxSize = null, ScaleBasis scaleBasis = ScaleBasis.Normal)
{
Init(parent, anchor, pivot);
+ this.scaleBasis = scaleBasis;
this.relativeSize = relativeSize;
this.minSize = minSize;
this.maxSize = maxSize;
@@ -340,6 +348,7 @@ namespace Barotrauma
public RectTransform(Point absoluteSize, RectTransform parent = null, Anchor anchor = Anchor.TopLeft, Pivot? pivot = null)
{
Init(parent, anchor, pivot);
+ this.scaleBasis = ScaleBasis.Normal;
this.nonScaledSize = absoluteSize;
RecalculateScale();
RecalculateRelativeSize();
@@ -416,7 +425,16 @@ namespace Barotrauma
protected void RecalculateAbsoluteSize()
{
- nonScaledSize = NonScaledParentRect.Size.Multiply(RelativeSize).Clamp(MinSize, MaxSize);
+ Point size = NonScaledParentRect.Size;
+ if (scaleBasis == ScaleBasis.BothWidth)
+ {
+ size.Y = size.X;
+ }
+ else if (scaleBasis == ScaleBasis.BothHeight)
+ {
+ size.X = size.Y;
+ }
+ nonScaledSize = size.Multiply(RelativeSize).Clamp(MinSize, MaxSize);
recalculateRect = true;
SizeChanged?.Invoke();
}
diff --git a/Barotrauma/BarotraumaClient/Source/GameMain.cs b/Barotrauma/BarotraumaClient/Source/GameMain.cs
index 6f1f43694..c87ff6bb1 100644
--- a/Barotrauma/BarotraumaClient/Source/GameMain.cs
+++ b/Barotrauma/BarotraumaClient/Source/GameMain.cs
@@ -159,14 +159,7 @@ namespace Barotrauma
public GameMain()
{
-/*#if !DEBUG && OSX
- // Use a separate path for content that's editable due to macOS's .app bundles crashing when edited during runtime
- string macPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "Library/Barotrauma");
- Directory.SetCurrentDirectory(macPath);
- Content.RootDirectory = macPath + "/Content";
-#else*/
Content.RootDirectory = "Content";
-/*#endif*/
GraphicsDeviceManager = new GraphicsDeviceManager(this);
@@ -280,7 +273,7 @@ namespace Barotrauma
canLoadInSeparateThread = true;
#endif
- loadingCoroutine = CoroutineManager.StartCoroutine(Load(canLoadInSeparateThread), "", canLoadInSeparateThread);
+ loadingCoroutine = CoroutineManager.StartCoroutine(Load(canLoadInSeparateThread), "Load", canLoadInSeparateThread);
}
private void InitUserStats()
@@ -541,7 +534,9 @@ namespace Barotrauma
///
protected override void UnloadContent()
{
+ CoroutineManager.StopCoroutines("Load");
Video.Close();
+ VoipCapture.Instance?.Dispose();
SoundManager?.Dispose();
}
diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/RoundSummary.cs b/Barotrauma/BarotraumaClient/Source/GameSession/RoundSummary.cs
index e4e0bb2a6..ffcc67311 100644
--- a/Barotrauma/BarotraumaClient/Source/GameSession/RoundSummary.cs
+++ b/Barotrauma/BarotraumaClient/Source/GameSession/RoundSummary.cs
@@ -114,7 +114,11 @@ namespace Barotrauma
Character character = characterInfo.Character;
if (character == null || character.IsDead)
{
- if (characterInfo.CauseOfDeath.Type == CauseOfDeathType.Affliction && characterInfo.CauseOfDeath.Affliction == null)
+ if (characterInfo.CauseOfDeath == null)
+ {
+ statusText = TextManager.Get("CauseOfDeathDescription.Unknown");
+ }
+ else if (characterInfo.CauseOfDeath.Type == CauseOfDeathType.Affliction && characterInfo.CauseOfDeath.Affliction == null)
{
string errorMsg = "Character \"" + character.Name + "\" had an invalid cause of death (the type of the cause of death was Affliction, but affliction was not specified).";
DebugConsole.ThrowError(errorMsg);
@@ -126,7 +130,7 @@ namespace Barotrauma
statusText = characterInfo.CauseOfDeath.Type == CauseOfDeathType.Affliction ?
characterInfo.CauseOfDeath.Affliction.CauseOfDeathDescription :
TextManager.Get("CauseOfDeathDescription." + characterInfo.CauseOfDeath.Type.ToString());
- }
+ }
statusColor = Color.DarkRed;
}
else
diff --git a/Barotrauma/BarotraumaClient/Source/GameSettings.cs b/Barotrauma/BarotraumaClient/Source/GameSettings.cs
index a19e7fce8..fa1794cd5 100644
--- a/Barotrauma/BarotraumaClient/Source/GameSettings.cs
+++ b/Barotrauma/BarotraumaClient/Source/GameSettings.cs
@@ -3,7 +3,7 @@ using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
-using OpenTK.Audio.OpenAL;
+using OpenAL;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -75,6 +75,8 @@ namespace Barotrauma
{
settingsFrame = new GUIFrame(new RectTransform(new Vector2(0.8f, 0.8f), GUI.Canvas, Anchor.Center));
+ Vector2 tickBoxScale = Vector2.One * 0.05f;
+
var settingsFramePadding = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), settingsFrame.RectTransform, Anchor.TopCenter) { RelativeOffset = new Vector2(0.0f, 0.05f) }) { RelativeSpacing = 0.01f, IsHorizontal = true };
/// General tab --------------------------------------------------------------
@@ -96,7 +98,7 @@ namespace Barotrauma
foreach (ContentPackage contentPackage in ContentPackage.List)
{
- var tickBox = new GUITickBox(new RectTransform(new Point(32, 32), contentPackageList.Content.RectTransform), contentPackage.Name)
+ var tickBox = new GUITickBox(new RectTransform(tickBoxScale, contentPackageList.Content.RectTransform, scaleBasis: ScaleBasis.BothHeight), contentPackage.Name)
{
UserData = contentPackage,
OnSelected = SelectContentPackage,
@@ -132,7 +134,7 @@ namespace Barotrauma
if (newLanguage == Language) return true;
Language = newLanguage;
- ApplySettings();
+ UnsavedSettings = true;
var msgBox = new GUIMessageBox(TextManager.Get("RestartRequiredLabel"), TextManager.Get("RestartRequiredLanguage"));
//change fonts to the default font of the new language to make sure
@@ -250,7 +252,7 @@ namespace Barotrauma
return true;
};
- GUITickBox vsyncTickBox = new GUITickBox(new RectTransform(new Point(32, 32), leftColumn.RectTransform), TextManager.Get("EnableVSync"))
+ GUITickBox vsyncTickBox = new GUITickBox(new RectTransform(tickBoxScale, leftColumn.RectTransform, scaleBasis: ScaleBasis.BothHeight), TextManager.Get("EnableVSync"))
{
ToolTip = TextManager.Get("EnableVSyncToolTip"),
OnSelected = (GUITickBox box) =>
@@ -266,7 +268,7 @@ namespace Barotrauma
};
//TODO: remove hardcoded texts after the texts have been added to localization
- GUITickBox pauseOnFocusLostBox = new GUITickBox(new RectTransform(new Point(32, 32), leftColumn.RectTransform),
+ GUITickBox pauseOnFocusLostBox = new GUITickBox(new RectTransform(tickBoxScale, leftColumn.RectTransform, scaleBasis: ScaleBasis.BothHeight),
TextManager.Get("PauseOnFocusLost", returnNull: true) ?? "Pause on focus lost");
pauseOnFocusLostBox.Selected = PauseOnFocusLost;
pauseOnFocusLostBox.ToolTip = TextManager.Get("PauseOnFocusLostToolTip", returnNull: true) ?? "Pauses the game when its window is not in focus. Note that the game won't be paused when a multiplayer session is active.";
@@ -331,7 +333,7 @@ namespace Barotrauma
};
lightScrollBar.OnMoved(lightScrollBar, lightScrollBar.BarScroll);
- new GUITickBox(new RectTransform(new Point(32, 32), rightColumn.RectTransform), TextManager.Get("SpecularLighting"))
+ new GUITickBox(new RectTransform(tickBoxScale, rightColumn.RectTransform, scaleBasis: ScaleBasis.BothHeight), TextManager.Get("SpecularLighting"))
{
ToolTip = TextManager.Get("SpecularLightingToolTip"),
Selected = SpecularityEnabled,
@@ -343,7 +345,7 @@ namespace Barotrauma
}
};
- new GUITickBox(new RectTransform(new Point(32, 32), rightColumn.RectTransform), TextManager.Get("ChromaticAberration"))
+ new GUITickBox(new RectTransform(tickBoxScale, rightColumn.RectTransform, scaleBasis: ScaleBasis.BothHeight), TextManager.Get("ChromaticAberration"))
{
ToolTip = TextManager.Get("ChromaticAberrationToolTip"),
Selected = ChromaticAberrationEnabled,
@@ -443,7 +445,7 @@ namespace Barotrauma
};
voiceChatScrollBar.OnMoved(voiceChatScrollBar, voiceChatScrollBar.BarScroll);
- GUITickBox muteOnFocusLostBox = new GUITickBox(new RectTransform(new Point(32, 32), audioSliders.RectTransform), TextManager.Get("MuteOnFocusLost"));
+ GUITickBox muteOnFocusLostBox = new GUITickBox(new RectTransform(tickBoxScale, audioSliders.RectTransform, scaleBasis: ScaleBasis.BothHeight), TextManager.Get("MuteOnFocusLost"));
muteOnFocusLostBox.Selected = MuteOnFocusLost;
muteOnFocusLostBox.ToolTip = TextManager.Get("MuteOnFocusLostToolTip");
muteOnFocusLostBox.OnSelected = (tickBox) =>
@@ -455,13 +457,13 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), audioSliders.RectTransform), TextManager.Get("VoiceChat"));
- IList deviceNames = Alc.GetString((IntPtr)null, AlcGetStringList.CaptureDeviceSpecifier);
+ IList deviceNames = Alc.GetStringList((IntPtr)null, Alc.CaptureDeviceSpecifier);
foreach (string name in deviceNames)
{
DebugConsole.NewMessage(name + " " + name.Length.ToString(), Color.Lime);
}
- GUITickBox directionalVoiceChat = new GUITickBox(new RectTransform(new Point(32, 32), audioSliders.RectTransform), TextManager.Get("DirectionalVoiceChat"));
+ GUITickBox directionalVoiceChat = new GUITickBox(new RectTransform(tickBoxScale, audioSliders.RectTransform, scaleBasis: ScaleBasis.BothHeight), TextManager.Get("DirectionalVoiceChat"));
directionalVoiceChat.Selected = UseDirectionalVoiceChat;
directionalVoiceChat.ToolTip = TextManager.Get("DirectionalVoiceChatToolTip");
directionalVoiceChat.OnSelected = (tickBox) =>
@@ -470,14 +472,13 @@ namespace Barotrauma
UnsavedSettings = true;
return true;
};
-
-
+
if (string.IsNullOrWhiteSpace(VoiceCaptureDevice)) VoiceCaptureDevice = deviceNames[0];
#if (!OSX)
- var deviceList = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), audioSliders.RectTransform), TextManager.EnsureUTF8(VoiceCaptureDevice), deviceNames.Count);
+ var deviceList = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), audioSliders.RectTransform), TrimAudioDeviceName(VoiceCaptureDevice), deviceNames.Count);
foreach (string name in deviceNames)
{
- deviceList.AddItem(TextManager.EnsureUTF8(name), name);
+ deviceList.AddItem(TrimAudioDeviceName(name), name);
}
deviceList.OnSelected = (GUIComponent selected, object obj) =>
{
@@ -488,28 +489,32 @@ namespace Barotrauma
return true;
};
#else
- var suavemente = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), audioSliders.RectTransform),
+ var defaultDeviceGroup = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.1f), audioSliders.RectTransform), true, Anchor.CenterLeft);
+ var suavemente = new GUITextBlock(new RectTransform(new Vector2(.7f, 0.75f), null),
TextManager.AddPunctuation(':', TextManager.Get("CurrentDevice"), TextManager.EnsureUTF8(VoiceCaptureDevice)))
{
ToolTip = TextManager.Get("CurrentDeviceToolTip.OSX"),
- TextAlignment = Alignment.CenterX
+ TextAlignment = Alignment.CenterLeft
};
- new GUIButton(new RectTransform(new Vector2(1.0f, 0.15f), audioSliders.RectTransform), TextManager.Get("RefreshDefaultDevice"))
+ string refreshText = ToolBox.WrapText(TextManager.Get("RefreshDefaultDevice"), defaultDeviceGroup.RectTransform.Rect.Width * 0.3f, GUI.Font);
+ new GUIButton(new RectTransform(new Vector2(.3f, 0.75f), defaultDeviceGroup.RectTransform), refreshText)
{
ToolTip = TextManager.Get("RefreshDefaultDeviceToolTip"),
OnClicked = (bt, userdata) =>
{
- deviceNames = Alc.GetString((IntPtr)null, AlcGetStringList.CaptureDeviceSpecifier);
+ deviceNames = Alc.GetStringList((IntPtr)null, Alc.CaptureDeviceSpecifier);
if (VoiceCaptureDevice == deviceNames[0]) return true;
VoipCapture.ChangeCaptureDevice(deviceNames[0]);
- suavemente.Text = TextManager.AddPunctuation(':', TextManager.Get("CurrentDevice"), TextManager.EnsureUTF8(VoiceCaptureDevice));
+ suavemente.Text = TextManager.AddPunctuation(':', TextManager.Get("CurrentDevice"), TrimAudioDeviceName(VoiceCaptureDevice));
suavemente.Flash(Color.Blue);
return true;
}
};
+
+ suavemente.RectTransform.Parent = defaultDeviceGroup.RectTransform;
#endif
//var radioButtonFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.12f), audioSliders.RectTransform));
@@ -517,7 +522,7 @@ namespace Barotrauma
for (int i = 0; i < 3; i++)
{
string langStr = "VoiceMode." + ((VoiceMode)i).ToString();
- var tick = new GUITickBox(new RectTransform(new Point(32, 32), audioSliders.RectTransform), TextManager.Get(langStr))
+ var tick = new GUITickBox(new RectTransform(tickBoxScale, audioSliders.RectTransform, scaleBasis: ScaleBasis.BothHeight), TextManager.Get(langStr))
{
ToolTip = TextManager.Get(langStr + "ToolTip")
};
@@ -651,7 +656,7 @@ namespace Barotrauma
};
aimAssistSlider.OnMoved(aimAssistSlider, aimAssistSlider.BarScroll);
- new GUITickBox(new RectTransform(new Point(32, 32), controlsLayoutGroup.RectTransform), TextManager.Get("EnableMouseLook"))
+ new GUITickBox(new RectTransform(tickBoxScale, controlsLayoutGroup.RectTransform, scaleBasis: ScaleBasis.BothHeight), TextManager.Get("EnableMouseLook"))
{
ToolTip = TextManager.Get("EnableMouseLookToolTip"),
Selected = EnableMouseLook,
@@ -776,6 +781,19 @@ namespace Barotrauma
SelectTab(selectedTab);
}
+ private string TrimAudioDeviceName(string name)
+ {
+ string[] prefixes = { "OpenAL Soft on " };
+ foreach (string prefix in prefixes)
+ {
+ if (name.StartsWith(prefix, StringComparison.InvariantCulture))
+ {
+ return name.Remove(0, prefix.Length);
+ }
+ }
+ return name;
+ }
+
private Tab currentTab;
private void SelectTab(Tab tab)
{
diff --git a/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs b/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs
index 53994493b..29aa5006d 100644
--- a/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs
+++ b/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs
@@ -423,7 +423,14 @@ namespace Barotrauma
columns++;
}
- int startX = slot.Rect.Center.X - (int)(subRect.Width * (columns / 2.0f) + spacing.X * ((columns - 1) / 2.0f));
+ int width = (int)(subRect.Width * columns + spacing.X * (columns - 1));
+ int startX = slot.Rect.Center.X - (int)(width / 2.0f);
+
+ //prevent the inventory from extending outside the left side of the screen
+ startX = Math.Max(startX, 10);
+ //same for the right side of the screen
+ startX -= Math.Max((startX + width) - GameMain.GraphicsWidth, 0);
+
subRect.X = startX;
int startY = dir < 0 ?
slot.EquipButtonRect.Y - subRect.Height - (int)(35 * UIScale) :
diff --git a/Barotrauma/BarotraumaClient/Source/Map/WayPoint.cs b/Barotrauma/BarotraumaClient/Source/Map/WayPoint.cs
index e98516c90..4d53a8289 100644
--- a/Barotrauma/BarotraumaClient/Source/Map/WayPoint.cs
+++ b/Barotrauma/BarotraumaClient/Source/Map/WayPoint.cs
@@ -29,6 +29,10 @@ namespace Barotrauma
drawPos.Y = -drawPos.Y;
Color clr = currentHull == null ? Color.Blue : Color.White;
+ if (isObstructed)
+ {
+ clr = Color.Black;
+ }
if (IsSelected) clr = Color.Red;
if (IsHighlighted) clr = Color.DarkRed;
@@ -50,7 +54,7 @@ namespace Barotrauma
GUI.DrawLine(spriteBatch,
drawPos,
new Vector2(e.DrawPosition.X, -e.DrawPosition.Y),
- Color.Green, width: 5);
+ isObstructed ? Color.Gray : Color.Green, width: 5);
}
GUI.SmallFont.DrawString(spriteBatch,
diff --git a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs
index 26e9bdf38..1fabd3482 100644
--- a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs
+++ b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs
@@ -194,8 +194,7 @@ namespace Barotrauma.Networking
Hull.EditFire = false;
Hull.EditWater = false;
- newName = newName.Replace(":", "").Replace(";", "");
- name = newName;
+ Name = newName;
entityEventManager = new ClientEntityEventManager(this);
@@ -473,7 +472,8 @@ namespace Barotrauma.Networking
var passwordBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 0.1f), msgBox.InnerFrame.RectTransform, Anchor.Center) { MinSize = new Point(0, 20) })
{
IgnoreLayoutGroups = true,
- UserData = "password"
+ UserData = "password",
+ Censor = true
};
var okButton = msgBox.Buttons[0];
@@ -1303,6 +1303,11 @@ namespace Barotrauma.Networking
if (existingClient.ID == myID)
{
existingClient.SetPermissions(permissions, permittedConsoleCommands);
+ name = tc.Name;
+ if (GameMain.NetLobbyScreen.CharacterNameBox != null)
+ {
+ GameMain.NetLobbyScreen.CharacterNameBox.Text = name;
+ }
}
currentClients.Add(existingClient);
}
@@ -1562,6 +1567,7 @@ namespace Barotrauma.Networking
outmsg.Write(GameMain.NetLobbyScreen.LastUpdateID);
outmsg.Write(ChatMessage.LastID);
outmsg.Write(LastClientListUpdateID);
+ outmsg.Write(name);
var campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
if (campaign == null || campaign.LastSaveID == 0)
@@ -1581,8 +1587,8 @@ namespace Barotrauma.Networking
{
if (outmsg.LengthBytes + chatMsgQueue[i].EstimateLengthBytesClient() > client.Configuration.MaximumTransmissionUnit - 5)
{
- //not enough room in this packet
- return;
+ //no more room in this packet
+ break;
}
chatMsgQueue[i].ClientWrite(outmsg);
}
@@ -1617,7 +1623,7 @@ namespace Barotrauma.Networking
if (outmsg.LengthBytes + chatMsgQueue[i].EstimateLengthBytesClient() > client.Configuration.MaximumTransmissionUnit - 5)
{
//not enough room in this packet
- return;
+ break;
}
chatMsgQueue[i].ClientWrite(outmsg);
}
diff --git a/Barotrauma/BarotraumaClient/Source/Networking/RespawnManager.cs b/Barotrauma/BarotraumaClient/Source/Networking/RespawnManager.cs
index e6458d736..dab9f7392 100644
--- a/Barotrauma/BarotraumaClient/Source/Networking/RespawnManager.cs
+++ b/Barotrauma/BarotraumaClient/Source/Networking/RespawnManager.cs
@@ -11,5 +11,15 @@ namespace Barotrauma.Networking
respawnTimer = Math.Max(0.0f, respawnTimer - deltaTime);
}
}
+
+ partial void UpdateTransportingProjSpecific(float deltaTime)
+ {
+ if (shuttleTransportTimer + deltaTime > 15.0f && shuttleTransportTimer <= 15.0f &&
+ GameMain.Client?.Character != null &&
+ GameMain.Client.Character.Submarine == respawnShuttle)
+ {
+ GameMain.Client.AddChatMessage("ServerMessage.ShuttleLeaving", ChatMessageType.Server);
+ }
+ }
}
}
diff --git a/Barotrauma/BarotraumaClient/Source/Networking/ServerInfo.cs b/Barotrauma/BarotraumaClient/Source/Networking/ServerInfo.cs
index 68356b34d..0223c9c69 100644
--- a/Barotrauma/BarotraumaClient/Source/Networking/ServerInfo.cs
+++ b/Barotrauma/BarotraumaClient/Source/Networking/ServerInfo.cs
@@ -71,15 +71,16 @@ namespace Barotrauma.Networking
Stretch = true
};
- var titleHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.97f, 0.07f), previewContainer.RectTransform))
+ var titleHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.07f), previewContainer.RectTransform))
{
IsHorizontal = true,
Stretch = true
};
- var title = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), titleHolder.RectTransform), ServerName, font: GUI.LargeFont, wrap: true);
+ var title = new GUITextBlock(new RectTransform(new Vector2(0.7f, 1.0f), titleHolder.RectTransform), ServerName, font: GUI.LargeFont, wrap: true);
+ title.Text = ToolBox.LimitString(title.Text, title.Font, title.Rect.Width);
- new GUITextBlock(new RectTransform(Vector2.One, title.RectTransform),
+ new GUITextBlock(new RectTransform(new Vector2(0.3f, 1.0f), titleHolder.RectTransform),
TextManager.AddPunctuation(':', TextManager.Get("ServerListVersion"), string.IsNullOrEmpty(GameVersion) ? TextManager.Get("Unknown") : GameVersion),
textAlignment: Alignment.Right);
diff --git a/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs b/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs
index 38b56ce3e..b3c4630fd 100644
--- a/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs
+++ b/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs
@@ -63,6 +63,15 @@ namespace Barotrauma.Steam
return instance.client.SteamId;
}
+ public static string GetUsername()
+ {
+ if (instance == null || !instance.isInitialized)
+ {
+ return "";
+ }
+ return instance.client.Username;
+ }
+
public static ulong GetWorkshopItemIDFromUrl(string url)
{
try
diff --git a/Barotrauma/BarotraumaClient/Source/Networking/Voip/VoipCapture.cs b/Barotrauma/BarotraumaClient/Source/Networking/Voip/VoipCapture.cs
index cd0d3352e..f47145846 100644
--- a/Barotrauma/BarotraumaClient/Source/Networking/Voip/VoipCapture.cs
+++ b/Barotrauma/BarotraumaClient/Source/Networking/Voip/VoipCapture.cs
@@ -1,6 +1,6 @@
using Lidgren.Network;
using Microsoft.Xna.Framework;
-using OpenTK.Audio.OpenAL;
+using OpenAL;
using System;
using System.Linq;
using System.Runtime.InteropServices;
@@ -69,7 +69,7 @@ namespace Barotrauma.Networking
VoipConfig.SetupEncoding();
//set up capture device
- captureDevice = Alc.CaptureOpenDevice(deviceName, VoipConfig.FREQUENCY, ALFormat.Mono16, VoipConfig.BUFFER_SIZE * 5);
+ captureDevice = Alc.CaptureOpenDevice(deviceName, VoipConfig.FREQUENCY, Al.FormatMono16, VoipConfig.BUFFER_SIZE * 5);
if (captureDevice == IntPtr.Zero)
{
@@ -88,20 +88,20 @@ namespace Barotrauma.Networking
return;
}
- ALError alError = AL.GetError();
- AlcError alcError = Alc.GetError(captureDevice);
- if (alcError != AlcError.NoError)
+ int alError = Al.GetError();
+ int alcError = Alc.GetError(captureDevice);
+ if (alcError != Alc.NoError)
{
throw new Exception("Failed to open capture device: " + alcError.ToString() + " (ALC)");
}
- if (alError != ALError.NoError)
+ if (alError != Al.NoError)
{
throw new Exception("Failed to open capture device: " + alError.ToString() + " (AL)");
}
Alc.CaptureStart(captureDevice);
alcError = Alc.GetError(captureDevice);
- if (alcError != AlcError.NoError)
+ if (alcError != Alc.NoError)
{
throw new Exception("Failed to start capturing: " + alcError.ToString());
}
@@ -132,11 +132,11 @@ namespace Barotrauma.Networking
short[] uncompressedBuffer = new short[VoipConfig.BUFFER_SIZE];
while (capturing)
{
- AlcError alcError;
- Alc.GetInteger(captureDevice, AlcGetInteger.CaptureSamples, 1, out int sampleCount);
+ int alcError;
+ Alc.GetInteger(captureDevice, Alc.EnumCaptureSamples, out int sampleCount);
alcError = Alc.GetError(captureDevice);
- if (alcError != AlcError.NoError)
+ if (alcError != Alc.NoError)
{
throw new Exception("Failed to determine sample count: " + alcError.ToString());
}
@@ -160,7 +160,7 @@ namespace Barotrauma.Networking
}
alcError = Alc.GetError(captureDevice);
- if (alcError != AlcError.NoError)
+ if (alcError != Alc.NoError)
{
throw new Exception("Failed to capture samples: " + alcError.ToString());
}
@@ -214,7 +214,7 @@ namespace Barotrauma.Networking
}
}
- Thread.Sleep(VoipConfig.BUFFER_SIZE * 800 / VoipConfig.FREQUENCY);
+ Thread.Sleep(10);
}
}
diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs b/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs
index d3b3cde22..408f4d827 100644
--- a/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs
+++ b/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs
@@ -335,12 +335,6 @@ namespace Barotrauma
}
subName = doc.Root.GetAttributeString("submarine", "");
saveTime = doc.Root.GetAttributeString("savetime", "");
-
- if (long.TryParse(saveTime, out long unixTime))
- {
- DateTime time = ToolBox.Epoch.ToDateTime(unixTime);
- saveTime = time.ToString();
- }
}
else
{
@@ -350,6 +344,11 @@ namespace Barotrauma
if (splitSaveFile.Length > 1) { subName = splitSaveFile[1]; }
if (splitSaveFile.Length > 2) { saveTime = splitSaveFile[2]; }
}
+ if (!string.IsNullOrEmpty(saveTime) && long.TryParse(saveTime, out long unixTime))
+ {
+ DateTime time = ToolBox.Epoch.ToDateTime(unixTime);
+ saveTime = time.ToString();
+ }
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform, Anchor.BottomLeft),
text: subName, font: GUI.SmallFont)
diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs b/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs
index a393d601a..1ec38ed43 100644
--- a/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs
+++ b/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs
@@ -1,4 +1,5 @@
-using Microsoft.Xna.Framework;
+using Barotrauma.Extensions;
+using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
@@ -231,7 +232,16 @@ namespace Barotrauma
"", style: "ItemCategory" + category.ToString())
{
UserData = category,
- OnClicked = (btn, userdata) => { FilterStoreItems((MapEntityCategory)userdata, searchBox.Text); return true; }
+ OnClicked = (btn, userdata) =>
+ {
+ MapEntityCategory newCategory = (MapEntityCategory)userdata;
+ if (newCategory != selectedItemCategory)
+ {
+ searchBox.Text = "";
+ }
+ FilterStoreItems((MapEntityCategory)userdata, searchBox.Text);
+ return true;
+ }
};
itemCategoryButtons.Add(categoryButton);
@@ -487,10 +497,15 @@ namespace Barotrauma
{
//refresh store view
FillStoreItemList();
- FilterStoreItems(MapEntityCategory.Equipment, searchBox.Text);
- }
+
+ MapEntityCategory? category = null;
+ //only select a specific category if the search box is empty
+ //(items from all categories are shown when searching)
+ if (string.IsNullOrEmpty(searchBox.Text)) { category = selectedItemCategory; }
+ FilterStoreItems(category, searchBox.Text);
+ }
}
-
+
private void DrawMap(SpriteBatch spriteBatch, GUICustomComponent mapContainer)
{
GameMain.GameSession?.Map?.Draw(spriteBatch, mapContainer);
@@ -655,7 +670,7 @@ namespace Barotrauma
}
}
- private void CreateItemFrame(PurchasedItem pi, PriceInfo priceInfo, GUIListBox listBox, int width)
+ private GUIComponent CreateItemFrame(PurchasedItem pi, PriceInfo priceInfo, GUIListBox listBox, int width)
{
GUIFrame frame = new GUIFrame(new RectTransform(new Point(listBox.Content.Rect.Width, (int)(GUI.Scale * 50)), listBox.Content.RectTransform), style: "ListBoxElement")
{
@@ -739,6 +754,10 @@ namespace Barotrauma
content.RectTransform.RecalculateChildren(true, true);
amountInput?.LayoutGroup.Recalculate();
textBlock.Text = ToolBox.LimitString(textBlock.Text, textBlock.Font, textBlock.Rect.Width);
+ content.RectTransform.IsFixedSize = true;
+ content.RectTransform.Children.ForEach(c => c.IsFixedSize = true);
+
+ return frame;
}
private bool BuyItem(GUIComponent component, object obj)
@@ -776,12 +795,24 @@ namespace Barotrauma
private void RefreshMyItems()
{
- myItemList.Content.ClearChildren();
-
- foreach (PurchasedItem ip in Campaign.CargoManager.PurchasedItems)
+ HashSet existingItemFrames = new HashSet();
+ foreach (PurchasedItem pi in Campaign.CargoManager.PurchasedItems)
{
- CreateItemFrame(ip, ip.ItemPrefab.GetPrice(Campaign.Map.CurrentLocation), myItemList, myItemList.Rect.Width);
+ var itemFrame = myItemList.Content.GetChildByUserData(pi);
+ if (itemFrame == null)
+ {
+ itemFrame = CreateItemFrame(pi, pi.ItemPrefab.GetPrice(Campaign.Map.CurrentLocation), myItemList, myItemList.Rect.Width);
+ }
+ itemFrame.GetChild(0).GetChild().IntValue = pi.Quantity;
+ existingItemFrames.Add(itemFrame);
}
+
+ var removedItemFrames = myItemList.Content.Children.Except(existingItemFrames).ToList();
+ foreach (GUIComponent removedItemFrame in removedItemFrames)
+ {
+ myItemList.Content.RemoveChild(removedItemFrame);
+ }
+
myItemList.Content.RectTransform.SortChildren((x, y) =>
(x.GUIComponent.UserData as PurchasedItem).ItemPrefab.Name.CompareTo((y.GUIComponent.UserData as PurchasedItem).ItemPrefab.Name));
myItemList.Content.RectTransform.SortChildren((x, y) =>
@@ -821,17 +852,28 @@ namespace Barotrauma
private void FillStoreItemList()
{
- storeItemList.ClearChildren();
-
int width = storeItemList.Rect.Width;
+ HashSet existingItemFrames = new HashSet();
foreach (MapEntityPrefab mapEntityPrefab in MapEntityPrefab.List)
{
if (!(mapEntityPrefab is ItemPrefab itemPrefab)) { continue; }
PriceInfo priceInfo = itemPrefab.GetPrice(Campaign.Map.CurrentLocation);
- if (priceInfo == null) continue;
+ if (priceInfo == null) { continue; }
- CreateItemFrame(new PurchasedItem(itemPrefab, 0), priceInfo, storeItemList, width);
+ var itemFrame = myItemList.Content.GetChildByUserData(priceInfo);
+ if (itemFrame == null)
+ {
+ itemFrame = CreateItemFrame(new PurchasedItem(itemPrefab, 0), priceInfo, storeItemList, width);
+ }
+ existingItemFrames.Add(itemFrame);
}
+
+ var removedItemFrames = storeItemList.Content.Children.Except(existingItemFrames).ToList();
+ foreach (GUIComponent removedItemFrame in removedItemFrames)
+ {
+ storeItemList.Content.RemoveChild(removedItemFrame);
+ }
+
storeItemList.Content.RectTransform.SortChildren(
(x, y) => (x.GUIComponent.UserData as PurchasedItem).ItemPrefab.Name.CompareTo((y.GUIComponent.UserData as PurchasedItem).ItemPrefab.Name));
}
diff --git a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs
index e4fe091d2..759ab39c1 100644
--- a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs
+++ b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs
@@ -968,7 +968,10 @@ namespace Barotrauma
};
label = new GUITextBlock(new RectTransform(textLabelSize, parent.RectTransform), TextManager.Get("Password"), textAlignment: textAlignment);
- passwordBox = new GUITextBox(new RectTransform(textFieldSize, label.RectTransform, Anchor.CenterRight), textAlignment: textAlignment);
+ passwordBox = new GUITextBox(new RectTransform(textFieldSize, label.RectTransform, Anchor.CenterRight), textAlignment: textAlignment)
+ {
+ Censor = true
+ };
isPublicBox = new GUITickBox(new RectTransform(tickBoxSize, parent.RectTransform), TextManager.Get("PublicServer"))
{
diff --git a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs
index 3545ce38e..53b26baba 100644
--- a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs
+++ b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs
@@ -147,6 +147,12 @@ namespace Barotrauma
get { return playerList; }
}
+ public GUITextBox CharacterNameBox
+ {
+ get;
+ private set;
+ }
+
public GUIButton StartButton
{
get;
@@ -920,7 +926,26 @@ namespace Barotrauma
UserData = characterInfo
};
- new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), infoContainer.RectTransform), characterInfo.Name, font: GUI.LargeFont, textAlignment: Alignment.Center, wrap: true);
+ CharacterNameBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.1f), infoContainer.RectTransform), characterInfo.Name, font: GUI.LargeFont, textAlignment: Alignment.Center)
+ {
+ MaxTextLength = Client.MaxNameLength,
+ OverflowClip = true
+ };
+ CharacterNameBox.OnEnterPressed += (tb, text) => { CharacterNameBox.Deselect(); return true; };
+ CharacterNameBox.OnDeselected += (tb, key) =>
+ {
+ if (GameMain.Client == null) { return; }
+ string newName = Client.SanitizeName(tb.Text);
+ if (string.IsNullOrWhiteSpace(newName))
+ {
+ tb.Text = GameMain.Client.Name;
+ }
+ else
+ {
+ ReadyToStartBox.Selected = false;
+ GameMain.Client.Name = tb.Text;
+ };
+ };
GUIComponent headContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.6f, 0.2f), infoContainer.RectTransform, Anchor.TopCenter), isHorizontal: true)
{
@@ -1309,6 +1334,7 @@ namespace Barotrauma
{
Selected = true,
Enabled = false,
+ Visible = false,
ToolTip = TextManager.Get("ReadyToStartTickBox"),
UserData = "clientready"
};
diff --git a/Barotrauma/BarotraumaClient/Source/Screens/ServerListScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/ServerListScreen.cs
index f2ec192dd..c8f44567d 100644
--- a/Barotrauma/BarotraumaClient/Source/Screens/ServerListScreen.cs
+++ b/Barotrauma/BarotraumaClient/Source/Screens/ServerListScreen.cs
@@ -70,8 +70,14 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoHolder.RectTransform), TextManager.Get("YourName"));
clientNameBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.13f), infoHolder.RectTransform), "")
{
- Text = GameMain.Config.DefaultPlayerName
+ Text = GameMain.Config.DefaultPlayerName,
+ MaxTextLength = Client.MaxNameLength,
+ OverflowClip = true
};
+ if (string.IsNullOrEmpty(clientNameBox.Text))
+ {
+ clientNameBox.Text = SteamManager.GetUsername();
+ }
clientNameBox.OnTextChanged += RefreshJoinButtonState;
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoHolder.RectTransform), TextManager.Get("ServerIP"));
@@ -236,7 +242,7 @@ namespace Barotrauma
{
serverInfo = (ServerInfo)obj;
ipBox.UserData = serverInfo;
- ipBox.Text = serverInfo.ServerName;
+ ipBox.Text = ToolBox.LimitString(serverInfo.ServerName, ipBox.Font, ipBox.Rect.Width);
}
catch (InvalidCastException)
{
@@ -411,7 +417,6 @@ namespace Barotrauma
};
var serverName = new GUITextBlock(new RectTransform(new Vector2(columnRelativeWidth[3], 1.0f), serverContent.RectTransform), serverInfo.ServerName, style: "GUIServerListTextBox");
-
var gameStartedBox = new GUITickBox(new RectTransform(new Vector2(columnRelativeWidth[4], 0.4f), serverContent.RectTransform, Anchor.Center),
label: "", style: "GUIServerListRoundStartedTickBox") {
ToolTip = TextManager.Get((serverInfo.GameStarted) ? "ServerListRoundStarted" : "ServerListRoundNotStarted"),
diff --git a/Barotrauma/BarotraumaClient/Source/Sounds/OggSound.cs b/Barotrauma/BarotraumaClient/Source/Sounds/OggSound.cs
index dacc02b24..7f59ebd1e 100644
--- a/Barotrauma/BarotraumaClient/Source/Sounds/OggSound.cs
+++ b/Barotrauma/BarotraumaClient/Source/Sounds/OggSound.cs
@@ -1,5 +1,5 @@
using System;
-using OpenTK.Audio.OpenAL;
+using OpenAL;
using NVorbis;
using System.Collections.Generic;
@@ -21,7 +21,7 @@ namespace Barotrauma.Sounds
reader = new VorbisReader(filename);
- ALFormat = reader.Channels == 1 ? ALFormat.Mono16 : ALFormat.Stereo16;
+ ALFormat = reader.Channels == 1 ? Al.FormatMono16 : Al.FormatStereo16;
SampleRate = reader.SampleRate;
if (!stream)
@@ -35,26 +35,26 @@ namespace Barotrauma.Sounds
CastBuffer(floatBuffer, shortBuffer, readSamples);
- AL.BufferData((int)ALBuffer, ALFormat, shortBuffer,
+ Al.BufferData(ALBuffer, ALFormat, shortBuffer,
readSamples * sizeof(short), SampleRate);
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to set buffer data for non-streamed audio! "+AL.GetErrorString(alError));
+ throw new Exception("Failed to set buffer data for non-streamed audio! "+Al.GetErrorString(alError));
}
MuffleBuffer(floatBuffer, SampleRate, reader.Channels);
CastBuffer(floatBuffer, shortBuffer, readSamples);
- AL.BufferData((int)ALMuffledBuffer, ALFormat, shortBuffer,
+ Al.BufferData(ALMuffledBuffer, ALFormat, shortBuffer,
readSamples * sizeof(short), SampleRate);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to set buffer data for non-streamed audio! " + AL.GetErrorString(alError));
+ throw new Exception("Failed to set buffer data for non-streamed audio! " + Al.GetErrorString(alError));
}
reader.Dispose();
@@ -98,4 +98,4 @@ namespace Barotrauma.Sounds
base.Dispose();
}
}
-}
\ No newline at end of file
+}
diff --git a/Barotrauma/BarotraumaClient/Source/Sounds/Sound.cs b/Barotrauma/BarotraumaClient/Source/Sounds/Sound.cs
index c3b0a474b..a5685cbd1 100644
--- a/Barotrauma/BarotraumaClient/Source/Sounds/Sound.cs
+++ b/Barotrauma/BarotraumaClient/Source/Sounds/Sound.cs
@@ -1,5 +1,5 @@
using System;
-using OpenTK.Audio.OpenAL;
+using OpenAL;
using Microsoft.Xna.Framework;
using System.IO;
@@ -57,7 +57,7 @@ namespace Barotrauma.Sounds
get { return !Stream ? alMuffledBuffer : 0; }
}
- public ALFormat ALFormat
+ public int ALFormat
{
get;
protected set;
@@ -91,26 +91,26 @@ namespace Barotrauma.Sounds
if (!stream)
{
- AL.GenBuffer(out alBuffer);
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.GenBuffer(out alBuffer);
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to create OpenAL buffer for non-streamed sound: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to create OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
}
- if (!AL.IsBuffer(alBuffer))
+ if (!Al.IsBuffer(alBuffer))
{
throw new Exception("Generated OpenAL buffer is invalid!");
}
- AL.GenBuffer(out alMuffledBuffer);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.GenBuffer(out alMuffledBuffer);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to create OpenAL buffer for non-streamed sound: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to create OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
}
- if (!AL.IsBuffer(alMuffledBuffer))
+ if (!Al.IsBuffer(alMuffledBuffer))
{
throw new Exception("Generated OpenAL buffer is invalid!");
}
@@ -186,32 +186,32 @@ namespace Barotrauma.Sounds
Owner.KillChannels(this);
if (alBuffer != 0)
{
- if (!AL.IsBuffer(alBuffer))
+ if (!Al.IsBuffer(alBuffer))
{
throw new Exception("Buffer to delete is invalid!");
}
- AL.DeleteBuffer(ref alBuffer); alBuffer = 0;
+ Al.DeleteBuffer(alBuffer); alBuffer = 0;
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to delete OpenAL buffer for non-streamed sound: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to delete OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
}
}
if (alMuffledBuffer != 0)
{
- if (!AL.IsBuffer(alMuffledBuffer))
+ if (!Al.IsBuffer(alMuffledBuffer))
{
throw new Exception("Buffer to delete is invalid!");
}
- AL.DeleteBuffer(ref alMuffledBuffer); alMuffledBuffer = 0;
+ Al.DeleteBuffer(alMuffledBuffer); alMuffledBuffer = 0;
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to delete OpenAL buffer for non-streamed sound: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to delete OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
}
}
diff --git a/Barotrauma/BarotraumaClient/Source/Sounds/SoundChannel.cs b/Barotrauma/BarotraumaClient/Source/Sounds/SoundChannel.cs
index e939f97bd..a69f4b102 100644
--- a/Barotrauma/BarotraumaClient/Source/Sounds/SoundChannel.cs
+++ b/Barotrauma/BarotraumaClient/Source/Sounds/SoundChannel.cs
@@ -1,5 +1,5 @@
using System;
-using OpenTK.Audio.OpenAL;
+using OpenAL;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
@@ -15,49 +15,49 @@ namespace Barotrauma.Sounds
public SoundSourcePool(int sourceCount = SoundManager.SOURCE_COUNT)
{
- ALError alError = ALError.NoError;
+ int alError = Al.NoError;
ALSources = new uint[sourceCount];
for (int i = 0; i < sourceCount; i++)
{
- AL.GenSource(out ALSources[i]);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.GenSource(out ALSources[i]);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Error generating alSource[" + i.ToString() + "]: " + AL.GetErrorString(alError));
+ throw new Exception("Error generating alSource[" + i.ToString() + "]: " + Al.GetErrorString(alError));
}
- if (!AL.IsSource(ALSources[i]))
+ if (!Al.IsSource(ALSources[i]))
{
throw new Exception("Generated alSource[" + i.ToString() + "] is invalid!");
}
- AL.SourceStop(ALSources[i]);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.SourceStop(ALSources[i]);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Error stopping newly generated alSource[" + i.ToString() + "]: " + AL.GetErrorString(alError));
+ throw new Exception("Error stopping newly generated alSource[" + i.ToString() + "]: " + Al.GetErrorString(alError));
}
- AL.Source(ALSources[i], ALSourcef.MinGain, 0.0f);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Sourcef(ALSources[i], Al.MinGain, 0.0f);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Error setting min gain: " + AL.GetErrorString(alError));
+ throw new Exception("Error setting min gain: " + Al.GetErrorString(alError));
}
- AL.Source(ALSources[i], ALSourcef.MaxGain, 1.0f);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Sourcef(ALSources[i], Al.MaxGain, 1.0f);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Error setting max gain: " + AL.GetErrorString(alError));
+ throw new Exception("Error setting max gain: " + Al.GetErrorString(alError));
}
- AL.Source(ALSources[i], ALSourcef.RolloffFactor, 1.0f);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Sourcef(ALSources[i], Al.RolloffFactor, 1.0f);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Error setting rolloff factor: " + AL.GetErrorString(alError));
+ throw new Exception("Error setting rolloff factor: " + Al.GetErrorString(alError));
}
}
}
@@ -66,11 +66,11 @@ namespace Barotrauma.Sounds
{
for (int i = 0; i < ALSources.Length; i++)
{
- AL.DeleteSource(ref ALSources[i]);
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.DeleteSource(ALSources[i]);
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to delete ALSources[" + i.ToString() + "]: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to delete ALSources[" + i.ToString() + "]: " + Al.GetErrorString(alError));
}
}
ALSources = null;
@@ -95,35 +95,35 @@ namespace Barotrauma.Sounds
if (position != null)
{
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
- AL.Source(alSource, ALSourceb.SourceRelative, false);
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Sourcei(alSource, Al.SourceRelative, Al.False);
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to enable source's relative flag: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to enable source's relative flag: " + Al.GetErrorString(alError));
}
- AL.Source(alSource, ALSource3f.Position, position.Value.X, position.Value.Y, position.Value.Z);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Source3f(alSource, Al.Position, position.Value.X, position.Value.Y, position.Value.Z);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to set source's position: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to set source's position: " + Al.GetErrorString(alError));
}
}
else
{
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
- AL.Source(alSource, ALSourceb.SourceRelative, true);
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Sourcei(alSource, Al.SourceRelative, Al.True);
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to disable source's relative flag: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to disable source's relative flag: " + Al.GetErrorString(alError));
}
- AL.Source(alSource, ALSource3f.Position, 0.0f, 0.0f, 0.0f);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Source3f(alSource, Al.Position, 0.0f, 0.0f, 0.0f);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to reset source's position: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to reset source's position: " + Al.GetErrorString(alError));
}
}
}
@@ -140,12 +140,12 @@ namespace Barotrauma.Sounds
if (ALSourceIndex < 0) return;
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
- AL.Source(alSource, ALSourcef.ReferenceDistance, near);
+ Al.Sourcef(alSource, Al.ReferenceDistance, near);
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to set source's reference distance: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to set source's reference distance: " + Al.GetErrorString(alError));
}
}
}
@@ -161,11 +161,11 @@ namespace Barotrauma.Sounds
if (ALSourceIndex < 0) return;
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
- AL.Source(alSource, ALSourcef.MaxDistance, far);
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Sourcef(alSource, Al.MaxDistance, far);
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to set source's max distance: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to set source's max distance: " + Al.GetErrorString(alError));
}
}
}
@@ -185,11 +185,11 @@ namespace Barotrauma.Sounds
float effectiveGain = gain;
if (category != null) effectiveGain *= Sound.Owner.GetCategoryGainMultiplier(category);
- AL.Source(alSource, ALSourcef.Gain, effectiveGain);
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Sourcef(alSource, Al.Gain, effectiveGain);
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to set source's gain: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to set source's gain: " + Al.GetErrorString(alError));
}
}
}
@@ -207,11 +207,11 @@ namespace Barotrauma.Sounds
if (!IsStream)
{
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
- AL.Source(alSource, ALSourceb.Looping, looping);
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Sourcei(alSource, Al.Looping, looping ? Al.True : Al.False);
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to set source's looping state: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to set source's looping state: " + Al.GetErrorString(alError));
}
}
}
@@ -242,41 +242,41 @@ namespace Barotrauma.Sounds
if (!IsStream)
{
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
- int playbackPos; AL.GetSource(alSource, ALGetSourcei.SampleOffset, out playbackPos);
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ int playbackPos; Al.GetSourcei(alSource, Al.SampleOffset, out playbackPos);
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to get source's playback position: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to get source's playback position: " + Al.GetErrorString(alError));
}
- AL.SourceStop(alSource);
+ Al.SourceStop(alSource);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to stop source: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to stop source: " + Al.GetErrorString(alError));
}
- AL.BindBufferToSource(alSource,(uint)(muffled ? Sound.ALMuffledBuffer : Sound.ALBuffer));
+ Al.Sourcei(alSource, Al.Buffer, muffled ? (int)Sound.ALMuffledBuffer : (int)Sound.ALBuffer);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to bind buffer to source: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to bind buffer to source: " + Al.GetErrorString(alError));
}
- AL.SourcePlay(alSource);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.SourcePlay(alSource);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to replay source: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to replay source: " + Al.GetErrorString(alError));
}
- AL.Source(alSource, ALSourcei.SampleOffset, playbackPos);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Sourcei(alSource, Al.SampleOffset, playbackPos);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to reset playback position: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to reset playback position: " + Al.GetErrorString(alError));
}
}
}
@@ -324,11 +324,13 @@ namespace Barotrauma.Sounds
{
if (ALSourceIndex < 0) return false;
if (IsStream && !reachedEndSample) return true;
- bool playing = AL.GetSourceState(Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex)) == ALSourceState.Playing;
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ int state;
+ Al.GetSourcei(Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.SourceState, out state);
+ bool playing = state == Al.Playing;
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to determine playing state from source: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to determine playing state from source: " + Al.GetErrorString(alError));
}
return playing;
}
@@ -357,47 +359,47 @@ namespace Barotrauma.Sounds
{
if (!IsStream)
{
- AL.BindBufferToSource(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), 0);
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, 0);
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to reset source buffer: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to reset source buffer: " + Al.GetErrorString(alError));
}
- if (!AL.IsBuffer(sound.ALBuffer))
+ if (!Al.IsBuffer(sound.ALBuffer))
{
throw new Exception(sound.Filename + " has an invalid buffer!");
}
uint alBuffer = sound.Owner.GetCategoryMuffle(category) || muffle ? sound.ALMuffledBuffer : sound.ALBuffer;
- AL.BindBufferToSource(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), alBuffer);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, (int)alBuffer);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to bind buffer to source (" + ALSourceIndex.ToString() + ":" + sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex) + "," + sound.ALBuffer.ToString() + "): " + AL.GetErrorString(alError));
+ throw new Exception("Failed to bind buffer to source (" + ALSourceIndex.ToString() + ":" + sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex) + "," + sound.ALBuffer.ToString() + "): " + Al.GetErrorString(alError));
}
- AL.SourcePlay(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex));
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.SourcePlay(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex));
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to play source: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to play source: " + Al.GetErrorString(alError));
}
}
else
{
- AL.BindBufferToSource(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), (uint)sound.ALBuffer);
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, (int)sound.ALBuffer);
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to reset source buffer: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to reset source buffer: " + Al.GetErrorString(alError));
}
- AL.Source(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), ALSourceb.Looping, false);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Looping, Al.False);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to set stream looping state: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to set stream looping state: " + Al.GetErrorString(alError));
}
streamShortBuffer = new short[STREAM_BUFFER_SIZE];
@@ -406,15 +408,15 @@ namespace Barotrauma.Sounds
emptyBuffers = new List();
for (int i = 0; i < 4; i++)
{
- AL.GenBuffer(out streamBuffers[i]);
+ Al.GenBuffer(out streamBuffers[i]);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to generate stream buffers: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to generate stream buffers: " + Al.GetErrorString(alError));
}
- if (!AL.IsBuffer(streamBuffers[i]))
+ if (!Al.IsBuffer(streamBuffers[i]))
{
throw new Exception("Generated streamBuffer[" + i.ToString() + "] is invalid!");
}
@@ -445,57 +447,57 @@ namespace Barotrauma.Sounds
{
if (ALSourceIndex >= 0)
{
- AL.SourceStop(Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex));
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.SourceStop(Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex));
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to stop source: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to stop source: " + Al.GetErrorString(alError));
}
if (IsStream)
{
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
- AL.SourceStop(alSource);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.SourceStop(alSource);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to stop streamed source: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to stop streamed source: " + Al.GetErrorString(alError));
}
int buffersToUnqueue = 0;
- int[] unqueuedBuffers = null;
+ uint[] unqueuedBuffers = null;
buffersToUnqueue = 0;
- AL.GetSource(alSource, ALGetSourcei.BuffersProcessed, out buffersToUnqueue);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.GetSourcei(alSource, Al.BuffersProcessed, out buffersToUnqueue);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to determine processed buffers from streamed source: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to determine processed buffers from streamed source: " + Al.GetErrorString(alError));
}
- unqueuedBuffers = new int[buffersToUnqueue];
- AL.SourceUnqueueBuffers((int)alSource, buffersToUnqueue, unqueuedBuffers);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ unqueuedBuffers = new uint[buffersToUnqueue];
+ Al.SourceUnqueueBuffers(alSource, buffersToUnqueue, unqueuedBuffers);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to unqueue buffers from streamed source: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to unqueue buffers from streamed source: " + Al.GetErrorString(alError));
}
-
- AL.BindBufferToSource(alSource, 0);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+
+ Al.Sourcei(alSource, Al.Buffer, 0);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to reset buffer for streamed source: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to reset buffer for streamed source: " + Al.GetErrorString(alError));
}
for (int i = 0; i < 4; i++)
{
- AL.DeleteBuffer(ref streamBuffers[i]);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.DeleteBuffer(streamBuffers[i]);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to delete streamBuffers[" + i.ToString() + "] ("+streamBuffers[i].ToString()+"): " + AL.GetErrorString(alError));
+ throw new Exception("Failed to delete streamBuffers[" + i.ToString() + "] ("+streamBuffers[i].ToString()+"): " + Al.GetErrorString(alError));
}
}
@@ -503,11 +505,11 @@ namespace Barotrauma.Sounds
}
else
{
- AL.BindBufferToSource(Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), 0);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Sourcei(Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, 0);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to unbind buffer to non-streamed source: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to unbind buffer to non-streamed source: " + Al.GetErrorString(alError));
}
}
@@ -526,47 +528,49 @@ namespace Barotrauma.Sounds
{
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
- bool playing = AL.GetSourceState(alSource) == ALSourceState.Playing;
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ int state;
+ Al.GetSourcei(Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.SourceState, out state);
+ bool playing = state == Al.Playing;
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to determine playing state from streamed source: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to determine playing state from streamed source: " + Al.GetErrorString(alError));
}
int buffersToUnqueue = 0;
- int[] unqueuedBuffers = null;
+ uint[] unqueuedBuffers = null;
if (!startedPlaying)
{
buffersToUnqueue = 0;
- AL.GetSource(alSource, ALGetSourcei.BuffersProcessed, out buffersToUnqueue);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.GetSourcei(alSource, Al.BuffersProcessed, out buffersToUnqueue);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to determine processed buffers from streamed source: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to determine processed buffers from streamed source: " + Al.GetErrorString(alError));
}
- unqueuedBuffers = new int[buffersToUnqueue+emptyBuffers.Count];
- AL.SourceUnqueueBuffers((int)alSource, buffersToUnqueue, unqueuedBuffers);
+ unqueuedBuffers = new uint[buffersToUnqueue+emptyBuffers.Count];
+ Al.SourceUnqueueBuffers(alSource, buffersToUnqueue, unqueuedBuffers);
for (int i = 0; i < emptyBuffers.Count; i++)
{
- unqueuedBuffers[buffersToUnqueue + i] = (int)emptyBuffers[i];
+ unqueuedBuffers[buffersToUnqueue + i] = emptyBuffers[i];
}
buffersToUnqueue += emptyBuffers.Count;
emptyBuffers.Clear();
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to unqueue buffers from streamed source: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to unqueue buffers from streamed source: " + Al.GetErrorString(alError));
}
}
else
{
startedPlaying = false;
buffersToUnqueue = 4;
- unqueuedBuffers = new int[4];
+ unqueuedBuffers = new uint[4];
for (int i = 0; i < 4; i++)
{
- unqueuedBuffers[i] = (int)streamBuffers[i];
+ unqueuedBuffers[i] = streamBuffers[i];
}
}
@@ -612,20 +616,20 @@ namespace Barotrauma.Sounds
if (readSamples > 0)
{
- AL.BufferData(unqueuedBuffers[i], Sound.ALFormat, buffer, readSamples, Sound.SampleRate);
+ Al.BufferData(unqueuedBuffers[i], Sound.ALFormat, buffer, readSamples, Sound.SampleRate);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
throw new Exception("Failed to assign data to stream buffer: " +
- AL.GetErrorString(alError) + ": " + unqueuedBuffers[i].ToString() + "/" + unqueuedBuffers.Length + ", readSamples: " + readSamples);
+ Al.GetErrorString(alError) + ": " + unqueuedBuffers[i].ToString() + "/" + unqueuedBuffers.Length + ", readSamples: " + readSamples);
}
- AL.SourceQueueBuffer((int)alSource, unqueuedBuffers[i]);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.SourceQueueBuffer(alSource, unqueuedBuffers[i]);
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to queue buffer[" + i.ToString() + "] to stream: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to queue buffer[" + i.ToString() + "] to stream: " + Al.GetErrorString(alError));
}
}
else if (readSamples < 0)
@@ -637,10 +641,11 @@ namespace Barotrauma.Sounds
emptyBuffers.Add((uint)unqueuedBuffers[i]);
}
}
-
- if (AL.GetSourceState(alSource) != ALSourceState.Playing)
+
+ Al.GetSourcei(alSource, Al.SourceState, out state);
+ if (state != Al.Playing)
{
- AL.SourcePlay(alSource);
+ Al.SourcePlay(alSource);
}
}
}
diff --git a/Barotrauma/BarotraumaClient/Source/Sounds/SoundManager.cs b/Barotrauma/BarotraumaClient/Source/Sounds/SoundManager.cs
index 14807564c..9948f044e 100644
--- a/Barotrauma/BarotraumaClient/Source/Sounds/SoundManager.cs
+++ b/Barotrauma/BarotraumaClient/Source/Sounds/SoundManager.cs
@@ -2,7 +2,7 @@
using System.Threading;
using System.Collections.Generic;
using System.Xml.Linq;
-using OpenTK.Audio.OpenAL;
+using OpenAL;
using Microsoft.Xna.Framework;
using System.Linq;
using System.IO;
@@ -20,7 +20,7 @@ namespace Barotrauma.Sounds
}
private IntPtr alcDevice;
- private OpenTK.ContextHandle alcContext;
+ private IntPtr alcContext;
public enum SourcePoolIndex
{
@@ -42,11 +42,11 @@ namespace Barotrauma.Sounds
{
if (Disabled) { return; }
listenerPosition = value;
- AL.Listener(ALListener3f.Position,value.X,value.Y,value.Z);
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Listener3f(Al.Position,value.X,value.Y,value.Z);
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to set listener position: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to set listener position: " + Al.GetErrorString(alError));
}
}
}
@@ -59,11 +59,11 @@ namespace Barotrauma.Sounds
{
if (Disabled) { return; }
listenerOrientation[0] = value.X; listenerOrientation[1] = value.Y; listenerOrientation[2] = value.Z;
- AL.Listener(ALListenerfv.Orientation, ref listenerOrientation);
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Listenerfv(Al.Orientation, listenerOrientation);
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to set listener target vector: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to set listener target vector: " + Al.GetErrorString(alError));
}
}
}
@@ -74,11 +74,11 @@ namespace Barotrauma.Sounds
{
if (Disabled) { return; }
listenerOrientation[3] = value.X; listenerOrientation[4] = value.Y; listenerOrientation[5] = value.Z;
- AL.Listener(ALListenerfv.Orientation, ref listenerOrientation);
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Listenerfv(Al.Orientation, listenerOrientation);
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to set listener up vector: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to set listener up vector: " + Al.GetErrorString(alError));
}
}
}
@@ -92,11 +92,11 @@ namespace Barotrauma.Sounds
if (Disabled) { return; }
if (Math.Abs(ListenerGain - value) < 0.001f) { return; }
listenerGain = value;
- AL.Listener(ALListenerf.Gain, listenerGain);
- ALError alError = AL.GetError();
- if (alError != ALError.NoError)
+ Al.Listenerf(Al.Gain, listenerGain);
+ int alError = Al.GetError();
+ if (alError != Al.NoError)
{
- throw new Exception("Failed to set listener gain: " + AL.GetErrorString(alError));
+ throw new Exception("Failed to set listener gain: " + Al.GetErrorString(alError));
}
}
}
@@ -126,8 +126,8 @@ namespace Barotrauma.Sounds
return;
}
- AlcError alcError = Alc.GetError(alcDevice);
- if (alcError != AlcError.NoError)
+ int alcError = Alc.GetError(alcDevice);
+ if (alcError != Alc.NoError)
{
//The audio device probably wasn't ready, this happens quite often
//Just wait a while and try again
@@ -136,7 +136,7 @@ namespace Barotrauma.Sounds
alcDevice = Alc.OpenDevice(null);
alcError = Alc.GetError(alcDevice);
- if (alcError != AlcError.NoError)
+ if (alcError != Alc.NoError)
{
DebugConsole.ThrowError("Error initializing ALC device: " + alcError.ToString() + ". Disabling audio playback...");
Disabled = true;
@@ -161,14 +161,14 @@ namespace Barotrauma.Sounds
}
alcError = Alc.GetError(alcDevice);
- if (alcError != AlcError.NoError)
+ if (alcError != Alc.NoError)
{
DebugConsole.ThrowError("Error after assigning ALC context: " + alcError.ToString() + ". Disabling audio playback...");
Disabled = true;
return;
}
- ALError alError = ALError.NoError;
+ int alError = Al.NoError;
sourcePools = new SoundSourcePool[2];
sourcePools[(int)SourcePoolIndex.Default] = new SoundSourcePool(SOURCE_COUNT);
@@ -177,12 +177,12 @@ namespace Barotrauma.Sounds
sourcePools[(int)SourcePoolIndex.Voice] = new SoundSourcePool(8);
playingChannels[(int)SourcePoolIndex.Voice] = new SoundChannel[8];
- AL.DistanceModel(ALDistanceModel.LinearDistanceClamped);
+ Al.DistanceModel(Al.LinearDistanceClamped);
- alError = AL.GetError();
- if (alError != ALError.NoError)
+ alError = Al.GetError();
+ if (alError != Al.NoError)
{
- DebugConsole.ThrowError("Error setting distance model: " + AL.GetErrorString(alError) + ". Disabling audio playback...");
+ DebugConsole.ThrowError("Error setting distance model: " + Al.GetErrorString(alError) + ". Disabling audio playback...");
Disabled = true;
return;
}
@@ -239,7 +239,7 @@ namespace Barotrauma.Sounds
{
if (Disabled || srcInd < 0 || srcInd >= sourcePools[(int)poolIndex].ALSources.Length) return 0;
- if (!AL.IsSource(sourcePools[(int)poolIndex].ALSources[srcInd]))
+ if (!Al.IsSource(sourcePools[(int)poolIndex].ALSources[srcInd]))
{
throw new Exception("alSources[" + srcInd.ToString() + "] is invalid!");
}
@@ -276,8 +276,8 @@ namespace Barotrauma.Sounds
{
for (int i = 0; i < sourcePools[0].ALSources.Length; i++)
{
- AL.Source(sourcePools[0].ALSources[i], ALSourcef.MaxGain, i == ind ? 1.0f : 0.0f);
- AL.Source(sourcePools[0].ALSources[i], ALSourcef.MinGain, 0.0f);
+ Al.Sourcef(sourcePools[0].ALSources[i], Al.MaxGain, i == ind ? 1.0f : 0.0f);
+ Al.Sourcef(sourcePools[0].ALSources[i], Al.MinGain, 0.0f);
}
}
#endif
@@ -503,10 +503,7 @@ namespace Barotrauma.Sounds
}
}
}
- if (streamingThread != null && !streamingThread.ThreadState.HasFlag(ThreadState.Stopped))
- {
- streamingThread.Join();
- }
+ streamingThread?.Join();
for (int i = loadedSounds.Count - 1; i >= 0; i--)
{
loadedSounds[i].Dispose();
@@ -514,7 +511,7 @@ namespace Barotrauma.Sounds
sourcePools[(int)SourcePoolIndex.Default]?.Dispose();
sourcePools[(int)SourcePoolIndex.Voice]?.Dispose();
- if (!Alc.MakeContextCurrent(OpenTK.ContextHandle.Zero))
+ if (!Alc.MakeContextCurrent(IntPtr.Zero))
{
throw new Exception("Failed to detach the current ALC context! (error code: " + Alc.GetError(alcDevice).ToString() + ")");
}
diff --git a/Barotrauma/BarotraumaClient/Source/Sounds/VideoSound.cs b/Barotrauma/BarotraumaClient/Source/Sounds/VideoSound.cs
index ff877c8a0..011d557ab 100644
--- a/Barotrauma/BarotraumaClient/Source/Sounds/VideoSound.cs
+++ b/Barotrauma/BarotraumaClient/Source/Sounds/VideoSound.cs
@@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using OpenTK.Audio.OpenAL;
+using OpenAL;
using Microsoft.Xna.Framework;
using System.Runtime.InteropServices;
using System.Threading;
@@ -21,7 +21,7 @@ namespace Barotrauma.Sounds
public VideoSound(SoundManager owner, string filename, int sampleRate, Video vid) : base(owner, filename, true, false)
{
- ALFormat = ALFormat.Stereo16;
+ ALFormat = Al.FormatStereo16;
SampleRate = sampleRate;
sampleQueue = new Queue();
@@ -110,4 +110,4 @@ namespace Barotrauma.Sounds
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Barotrauma/BarotraumaClient/Source/Sounds/VoipSound.cs b/Barotrauma/BarotraumaClient/Source/Sounds/VoipSound.cs
index 18126a8ba..5eb8ad951 100644
--- a/Barotrauma/BarotraumaClient/Source/Sounds/VoipSound.cs
+++ b/Barotrauma/BarotraumaClient/Source/Sounds/VoipSound.cs
@@ -1,6 +1,6 @@
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
-using OpenTK.Audio.OpenAL;
+using OpenAL;
using System;
using System.Collections.Generic;
@@ -58,7 +58,7 @@ namespace Barotrauma.Sounds
{
VoipConfig.SetupEncoding();
- ALFormat = ALFormat.Mono16;
+ ALFormat = Al.FormatMono16;
SampleRate = VoipConfig.FREQUENCY;
queue = q;
diff --git a/Barotrauma/BarotraumaClient/Source/Sprite/DeformAnimations/SpriteDeformation.cs b/Barotrauma/BarotraumaClient/Source/Sprite/DeformAnimations/SpriteDeformation.cs
index 19097bf21..da7364bcc 100644
--- a/Barotrauma/BarotraumaClient/Source/Sprite/DeformAnimations/SpriteDeformation.cs
+++ b/Barotrauma/BarotraumaClient/Source/Sprite/DeformAnimations/SpriteDeformation.cs
@@ -40,6 +40,9 @@ namespace Barotrauma.SpriteDeformations
[Serialize(false, true)]
public bool UseMovementSine { get; set; }
+ [Serialize(false, true)]
+ public bool StopWhenHostIsDead { get; set; }
+
///
/// Only used if UseMovementSine is enabled. Multiplier for Pi.
///
diff --git a/Barotrauma/BarotraumaClient/WindowsClient.csproj b/Barotrauma/BarotraumaClient/WindowsClient.csproj
index dc6b33c63..151864bcf 100644
--- a/Barotrauma/BarotraumaClient/WindowsClient.csproj
+++ b/Barotrauma/BarotraumaClient/WindowsClient.csproj
@@ -31,7 +31,7 @@
true
- .pdb
+ .pdb
..\BarotraumaShared\Icon.ico
@@ -39,7 +39,7 @@
true
..\bin\ReleaseWindows\
- TRACE;WINDOWS;CLIENT
+ TRACE;WINDOWS;CLIENT;X64
true
pdbonly
x64
@@ -49,7 +49,7 @@
true
..\bin\DebugWindows\
- TRACE;WINDOWS;CLIENT;DEBUG
+ TRACE;DEBUG;WINDOWS;CLIENT;X64
full
x64
MinimumRecommendedRules.ruleset
@@ -60,7 +60,7 @@
true
..\bin\x86\ReleaseWindows\
- TRACE;WINDOWS;CLIENT
+ TRACE;WINDOWS;CLIENT;X86
true
pdbonly
x86
@@ -70,7 +70,7 @@
true
..\bin\x86\DebugWindows\
- TRACE;WINDOWS;CLIENT;DEBUG
+ TRACE;DEBUG;WINDOWS;CLIENT;X86
full
x86
MinimumRecommendedRules.ruleset
@@ -95,9 +95,6 @@
..\..\Libraries\NuGet\NVorbis.0.8.6\lib\net35\NVorbis.dll
-
- ..\..\Libraries\NuGet\OpenTK.3.0.1\lib\net20\OpenTK.dll
-
..\..\Libraries\NuGet\RestSharp.105.2.3\lib\net45\RestSharp.dll
@@ -215,16 +212,16 @@
-
- PreserveNewest
-
PreserveNewest
-
+
PreserveNewest
-
+
+ PreserveNewest
+
+
PreserveNewest
@@ -306,7 +303,7 @@
-
+
diff --git a/Barotrauma/BarotraumaClient/packages.config b/Barotrauma/BarotraumaClient/packages.config
index e593ce09a..72a6ec439 100644
--- a/Barotrauma/BarotraumaClient/packages.config
+++ b/Barotrauma/BarotraumaClient/packages.config
@@ -8,7 +8,6 @@
-
diff --git a/Barotrauma/BarotraumaServer/Properties/AssemblyInfo.cs b/Barotrauma/BarotraumaServer/Properties/AssemblyInfo.cs
index 34eab06f2..b38e34012 100644
--- a/Barotrauma/BarotraumaServer/Properties/AssemblyInfo.cs
+++ b/Barotrauma/BarotraumaServer/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.9.0.3")]
-[assembly: AssemblyFileVersion("0.9.0.3")]
+[assembly: AssemblyVersion("0.9.0.4")]
+[assembly: AssemblyFileVersion("0.9.0.4")]
diff --git a/Barotrauma/BarotraumaServer/Server.csproj b/Barotrauma/BarotraumaServer/Server.csproj
index 6b66b1b69..9d9e7370d 100644
--- a/Barotrauma/BarotraumaServer/Server.csproj
+++ b/Barotrauma/BarotraumaServer/Server.csproj
@@ -273,10 +273,7 @@
-
-
- PreserveNewest
-
+
PreserveNewest
diff --git a/Barotrauma/BarotraumaServer/Source/Networking/Client.cs b/Barotrauma/BarotraumaServer/Source/Networking/Client.cs
index 28e291e39..611793855 100644
--- a/Barotrauma/BarotraumaServer/Source/Networking/Client.cs
+++ b/Barotrauma/BarotraumaServer/Source/Networking/Client.cs
@@ -153,20 +153,5 @@ namespace Barotrauma.Networking
{
return this.Permissions.HasFlag(permission);
}
-
- public static string SanitizeName(string name)
- {
- name = name.Trim();
- if (name.Length > 20)
- {
- name = name.Substring(0, 20);
- }
- string rName = "";
- for (int i = 0; i < name.Length; i++)
- {
- rName += name[i] < 32 ? '?' : name[i];
- }
- return rName;
- }
}
}
diff --git a/Barotrauma/BarotraumaServer/Source/Networking/EntitySpawner.cs b/Barotrauma/BarotraumaServer/Source/Networking/EntitySpawner.cs
index 1f295253f..45eb98b16 100644
--- a/Barotrauma/BarotraumaServer/Source/Networking/EntitySpawner.cs
+++ b/Barotrauma/BarotraumaServer/Source/Networking/EntitySpawner.cs
@@ -30,12 +30,13 @@ namespace Barotrauma
if (entities.Entity is Item)
{
message.Write((byte)SpawnableType.Item);
+ DebugConsole.Log("Writing item spawn data " + entities.Entity.ToString() + " (ID: " + entities.Entity.ID + ")");
((Item)entities.Entity).WriteSpawnData(message);
}
else if (entities.Entity is Character)
{
message.Write((byte)SpawnableType.Character);
- DebugConsole.NewMessage("WRITING CHARACTER DATA: " + (entities.Entity).ToString() + " (ID: " + entities.Entity.ID + ")", Color.Cyan);
+ DebugConsole.Log("Writing character spawn data: " + entities.Entity.ToString() + " (ID: " + entities.Entity.ID + ")");
((Character)entities.Entity).WriteSpawnData(message);
}
}
diff --git a/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs b/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs
index 1dbc815cb..4e884f7fc 100644
--- a/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs
+++ b/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs
@@ -576,7 +576,7 @@ namespace Barotrauma.Networking
HandleOwnership(msgContent, inc.SenderConnection);
}
- DebugConsole.NewMessage(packetHeader.ToString(), Color.Lime);
+ DebugConsole.Log(packetHeader.ToString());
if (inc.SenderConnection != OwnerConnection && serverSettings.BanList.IsBanned(inc.SenderEndPoint.Address, 0))
{
inc.SenderConnection.Deny(DisconnectReason.Banned.ToString());
@@ -661,7 +661,13 @@ namespace Barotrauma.Networking
if (GameMain.Config.UseSteamMatchmaking)
{
- SteamManager.RefreshServerDetails(this);
+ bool refreshSuccessful = SteamManager.RefreshServerDetails(this);
+ if (GameSettings.VerboseLogging)
+ {
+ Log(refreshSuccessful ?
+ "Refreshed server info on the server list." :
+ "Refreshing server info on the server list failed.", ServerLog.MessageType.ServerMessage);
+ }
}
else
{
@@ -865,6 +871,8 @@ namespace Barotrauma.Networking
c.LastRecvLobbyUpdate = NetIdUtils.Clamp(inc.ReadUInt16(), c.LastRecvLobbyUpdate, GameMain.NetLobbyScreen.LastUpdateID);
c.LastRecvChatMsgID = NetIdUtils.Clamp(inc.ReadUInt16(), c.LastRecvChatMsgID, c.LastChatMsgQueueID);
c.LastRecvClientListUpdate = NetIdUtils.Clamp(inc.ReadUInt16(), c.LastRecvClientListUpdate, LastClientListUpdateID);
+
+ TryChangeClientName(c, inc.ReadString());
c.LastRecvCampaignSave = inc.ReadUInt16();
if (c.LastRecvCampaignSave > 0)
@@ -2066,11 +2074,44 @@ namespace Barotrauma.Networking
public override void AddChatMessage(ChatMessage message)
{
if (string.IsNullOrEmpty(message.Text)) { return; }
- Log(message.TextWithSender, ServerLog.MessageType.Chat);
+ Log(message.TextWithSender, ServerLog.MessageType.Chat);
base.AddChatMessage(message);
}
+ private bool TryChangeClientName(Client c, string newName)
+ {
+ if (c == null || string.IsNullOrEmpty(newName)) { return false; }
+
+ newName = Client.SanitizeName(newName);
+ if (newName == c.Name) { return false; }
+
+ //update client list even if the name cannot be changed to the one sent by the client,
+ //so the client will be informed what their actual name is
+ LastClientListUpdateID++;
+
+ if (!Client.IsValidName(newName, this))
+ {
+ SendDirectChatMessage("Could not change your name to \"" + newName + "\" (the name contains disallowed symbols).", c, ChatMessageType.MessageBox);
+ return false;
+ }
+ if (c.Connection != OwnerConnection && Homoglyphs.Compare(newName.ToLower(), Name.ToLower()))
+ {
+ SendDirectChatMessage("Could not change your name to \"" + newName + "\" (too similar to the server's name).", c, ChatMessageType.MessageBox);
+ return false;
+ }
+ Client nameTaken = ConnectedClients.Find(c2 => c != c2 && Homoglyphs.Compare(c2.Name.ToLower(), newName.ToLower()));
+ if (nameTaken != null)
+ {
+ SendDirectChatMessage("Could not change your name to \"" + newName + "\" (too similar to the name of the client \"" + nameTaken.Name + "\").", c, ChatMessageType.MessageBox);
+ return false;
+ }
+
+ SendChatMessage("Player \"" + c.Name + "\" has changed their name to \"" + newName + "\".", ChatMessageType.Server);
+ c.Name = newName;
+ return true;
+ }
+
public override void KickPlayer(string playerName, string reason)
{
playerName = playerName.ToLowerInvariant();
diff --git a/Barotrauma/BarotraumaServer/Source/Networking/GameServerLogin.cs b/Barotrauma/BarotraumaServer/Source/Networking/GameServerLogin.cs
index 2d720f969..3091825e5 100644
--- a/Barotrauma/BarotraumaServer/Source/Networking/GameServerLogin.cs
+++ b/Barotrauma/BarotraumaServer/Source/Networking/GameServerLogin.cs
@@ -432,7 +432,7 @@ namespace Barotrauma.Networking
DebugConsole.NewMessage(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (invalid name)", Color.Red);
return;
}
- if (inc.SenderConnection != OwnerConnection && Homoglyphs.Compare(clName.ToLower(),Name.ToLower()))
+ if (inc.SenderConnection != OwnerConnection && Homoglyphs.Compare(clName.ToLower(), Name.ToLower()))
{
DisconnectUnauthClient(inc, unauthClient, DisconnectReason.NameTaken, "");
Log(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (name taken by the server)", ServerLog.MessageType.Error);
diff --git a/Barotrauma/BarotraumaServer/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs b/Barotrauma/BarotraumaServer/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs
index d1d613a94..dc2fdfce9 100644
--- a/Barotrauma/BarotraumaServer/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs
+++ b/Barotrauma/BarotraumaServer/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs
@@ -48,6 +48,9 @@ namespace Barotrauma.Networking
private List uniqueEvents;
private UInt16 lastSentToAll;
+ private UInt16 lastSentToAnyone;
+ private double lastSentToAnyoneTime;
+ private double lastWarningTime;
public List Events
{
@@ -99,6 +102,8 @@ namespace Barotrauma.Networking
bufferedEvents = new List();
uniqueEvents = new List();
+
+ lastWarningTime = -10.0;
}
public void CreateEvent(IServerSerializable entity, object[] extraData = null)
@@ -198,6 +203,7 @@ namespace Barotrauma.Networking
var inGameClients = clients.FindAll(c => c.InGame && !c.NeedsMidRoundSync);
if (inGameClients.Count > 0)
{
+ lastSentToAnyone = inGameClients[0].LastRecvEntityEventID;
lastSentToAll = inGameClients[0].LastRecvEntityEventID;
if (server.OwnerConnection != null)
{
@@ -207,25 +213,39 @@ namespace Barotrauma.Networking
lastSentToAll = owner.LastRecvEntityEventID;
}
}
- inGameClients.ForEach(c => { if (NetIdUtils.IdMoreRecent(lastSentToAll, c.LastRecvEntityEventID)) lastSentToAll = c.LastRecvEntityEventID; });
+ inGameClients.ForEach(c =>
+ {
+ if (NetIdUtils.IdMoreRecent(lastSentToAll, c.LastRecvEntityEventID)) { lastSentToAll = c.LastRecvEntityEventID; }
+ if (NetIdUtils.IdMoreRecent(c.LastRecvEntityEventID, lastSentToAnyone)) { lastSentToAnyone = c.LastRecvEntityEventID; }
+ });
+ lastSentToAnyoneTime = events.Find(e => e.ID == lastSentToAnyone)?.CreateTime ?? Timing.TotalTime;
+ if ((Timing.TotalTime - lastSentToAnyoneTime) > 10.0 && (Timing.TotalTime - lastWarningTime) > 5.0)
+ {
+ lastWarningTime = Timing.TotalTime;
+ GameServer.Log("WARNING: ServerEntityEventManager is lagging behind! Last sent id: " + lastSentToAnyone.ToString() + ", latest create id: " + ID.ToString(), ServerLog.MessageType.ServerMessage);
+ //TODO: reset clients if this happens, maybe do it if a majority are behind rather than all of them?
+ }
+
clients.Where(c => c.NeedsMidRoundSync).ForEach(c => { if (NetIdUtils.IdMoreRecent(lastSentToAll, c.FirstNewEventID)) lastSentToAll = (ushort)(c.FirstNewEventID - 1); });
ServerEntityEvent firstEventToResend = events.Find(e => e.ID == (ushort)(lastSentToAll + 1));
- if (firstEventToResend != null && (Timing.TotalTime - firstEventToResend.CreateTime) > 10.0f)
+ if (firstEventToResend != null && ((lastSentToAnyoneTime - firstEventToResend.CreateTime) > 10.0 || (Timing.TotalTime - firstEventToResend.CreateTime) > 30.0))
{
- //it's been 10 seconds since this event was created, kick everyone that hasn't received it yet, this is way too old
- // UNLESS the event was created when the client was still midround syncing, in which case we'll wait until the timeout
- // runs out before kicking the client
+ // This event is 10 seconds older than the last one we've successfully sent,
+ // kick everyone that hasn't received it yet, this is way too old
+ // UNLESS the event was created when the client was still midround syncing,
+ // in which case we'll wait until the timeout runs out before kicking the client
List toKick = inGameClients.FindAll(c =>
NetIdUtils.IdMoreRecent((UInt16)(lastSentToAll + 1), c.LastRecvEntityEventID) &&
- (firstEventToResend.CreateTime > c.MidRoundSyncTimeOut || Timing.TotalTime > c.MidRoundSyncTimeOut));
+ (firstEventToResend.CreateTime > c.MidRoundSyncTimeOut || lastSentToAnyoneTime > c.MidRoundSyncTimeOut));
toKick.ForEach(c =>
{
DebugConsole.NewMessage(c.Name + " was kicked due to excessive desync (expected old event " + (c.LastRecvEntityEventID + 1).ToString() + ")", Color.Red);
GameServer.Log("Disconnecting client " + c.Name + " due to excessive desync (expected old event "
+ (c.LastRecvEntityEventID + 1).ToString() +
- " (created " + (Timing.TotalTime - firstEventToResend.CreateTime).ToString("0.##") + " s ago)" +
+ " (created " + (Timing.TotalTime - firstEventToResend.CreateTime).ToString("0.##") + " s ago, " +
+ (lastSentToAnyoneTime - firstEventToResend.CreateTime).ToString("0.##") + " s older than last event sent to anyone)" +
" Events queued: " + events.Count + ", last sent to all: " + lastSentToAll, ServerLog.MessageType.Error);
server.DisconnectClient(c, "", "ServerMessage.ExcessiveDesyncOldEvent");
}
diff --git a/Barotrauma/BarotraumaServer/Source/Networking/RespawnManager.cs b/Barotrauma/BarotraumaServer/Source/Networking/RespawnManager.cs
index a27e15083..dcd655cbd 100644
--- a/Barotrauma/BarotraumaServer/Source/Networking/RespawnManager.cs
+++ b/Barotrauma/BarotraumaServer/Source/Networking/RespawnManager.cs
@@ -1,4 +1,5 @@
-using Microsoft.Xna.Framework;
+using Barotrauma.Items.Components;
+using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -9,19 +10,15 @@ namespace Barotrauma.Networking
{
private List GetClientsToRespawn()
{
- GameServer server = networkMember as GameServer;
-
return networkMember.ConnectedClients.FindAll(c =>
c.InGame &&
- (!c.SpectateOnly || (!server.ServerSettings.AllowSpectating && server.OwnerConnection != c.Connection)) &&
+ (!c.SpectateOnly || (!GameMain.Server.ServerSettings.AllowSpectating && GameMain.Server.OwnerConnection != c.Connection)) &&
(c.Character == null || c.Character.IsDead));
}
private List GetBotsToRespawn()
{
- GameServer server = networkMember as GameServer;
-
- if (server.ServerSettings.BotSpawnMode == BotSpawnMode.Normal)
+ if (GameMain.Server.ServerSettings.BotSpawnMode == BotSpawnMode.Normal)
{
return Character.CharacterList
.FindAll(c => c.TeamID == Character.TeamType.Team1 && c.AIController != null && c.Info != null && c.IsDead)
@@ -29,14 +26,14 @@ namespace Barotrauma.Networking
.ToList();
}
- int currPlayerCount = server.ConnectedClients.Count(c =>
+ int currPlayerCount = GameMain.Server.ConnectedClients.Count(c =>
c.InGame &&
- (!c.SpectateOnly || (!server.ServerSettings.AllowSpectating && server.OwnerConnection != c.Connection)));
+ (!c.SpectateOnly || (!GameMain.Server.ServerSettings.AllowSpectating && GameMain.Server.OwnerConnection != c.Connection)));
var existingBots = Character.CharacterList
.FindAll(c => c.TeamID == Character.TeamType.Team1 && c.AIController != null && c.Info != null);
- int requiredBots = server.ServerSettings.BotCount - currPlayerCount;
+ int requiredBots = GameMain.Server.ServerSettings.BotCount - currPlayerCount;
requiredBots -= existingBots.Count(b => !b.IsDead);
List botsToRespawn = new List();
@@ -58,21 +55,19 @@ namespace Barotrauma.Networking
partial void UpdateWaiting(float deltaTime)
{
- var server = networkMember as GameServer;
-
int characterToRespawnCount = GetClientsToRespawn().Count;
- int totalCharacterCount = server.ConnectedClients.Count;
+ int totalCharacterCount = GameMain.Server.ConnectedClients.Count;
/*if (server.Character != null)
{
totalCharacterCount++;
if (server.Character.IsDead) characterToRespawnCount++;
}*/
- bool startCountdown = (float)characterToRespawnCount >= Math.Max((float)totalCharacterCount * server.ServerSettings.MinRespawnRatio, 1.0f);
+ bool startCountdown = (float)characterToRespawnCount >= Math.Max((float)totalCharacterCount * GameMain.Server.ServerSettings.MinRespawnRatio, 1.0f);
if (startCountdown != CountdownStarted)
{
CountdownStarted = startCountdown;
- server.CreateEntityEvent(this);
+ GameMain.Server.CreateEntityEvent(this);
}
if (!CountdownStarted) return;
@@ -80,7 +75,7 @@ namespace Barotrauma.Networking
respawnTimer -= deltaTime;
if (respawnTimer <= 0.0f)
{
- respawnTimer = server.ServerSettings.RespawnInterval;
+ respawnTimer = GameMain.Server.ServerSettings.RespawnInterval;
DispatchShuttle();
}
@@ -98,13 +93,10 @@ namespace Barotrauma.Networking
partial void DispatchShuttle()
{
- var server = networkMember as GameServer;
- if (server == null) return;
-
if (respawnShuttle != null)
{
state = State.Transporting;
- server.CreateEntityEvent(this);
+ GameMain.Server.CreateEntityEvent(this);
ResetShuttle();
@@ -124,17 +116,78 @@ namespace Barotrauma.Networking
{
state = State.Waiting;
GameServer.Log("Respawning everyone in main sub.", ServerLog.MessageType.Spawning);
- server.CreateEntityEvent(this);
+ GameMain.Server.CreateEntityEvent(this);
RespawnCharacters();
}
}
+ partial void UpdateReturningProjSpecific()
+ {
+ foreach (Door door in shuttleDoors)
+ {
+ if (door.IsOpen) door.TrySetState(false, false, true);
+ }
+
+ var shuttleGaps = Gap.GapList.FindAll(g => g.Submarine == respawnShuttle && g.ConnectedWall != null);
+ shuttleGaps.ForEach(g => Spawner.AddToRemoveQueue(g));
+
+ var dockingPorts = Item.ItemList.FindAll(i => i.Submarine == respawnShuttle && i.GetComponent() != null);
+ dockingPorts.ForEach(d => d.GetComponent().Undock());
+
+ //shuttle has returned if the path has been traversed or the shuttle is close enough to the exit
+ if (!CoroutineManager.IsCoroutineRunning("forcepos"))
+ {
+ if ((shuttleSteering?.SteeringPath != null && shuttleSteering.SteeringPath.Finished)
+ || (respawnShuttle.WorldPosition.Y + respawnShuttle.Borders.Y > Level.Loaded.StartPosition.Y - Level.ShaftHeight &&
+ Math.Abs(Level.Loaded.StartPosition.X - respawnShuttle.WorldPosition.X) < 1000.0f))
+ {
+ CoroutineManager.StopCoroutines("forcepos");
+ CoroutineManager.StartCoroutine(
+ ForceShuttleToPos(new Vector2(Level.Loaded.StartPosition.X, Level.Loaded.Size.Y + 1000.0f), 100.0f), "forcepos");
+
+ }
+ }
+
+ if (respawnShuttle.WorldPosition.Y > Level.Loaded.Size.Y || shuttleReturnTimer <= 0.0f)
+ {
+ CoroutineManager.StopCoroutines("forcepos");
+
+ ResetShuttle();
+
+ state = State.Waiting;
+ GameServer.Log("The respawn shuttle has left.", ServerLog.MessageType.Spawning);
+ GameMain.Server.CreateEntityEvent(this);
+
+ respawnTimer = GameMain.Server.ServerSettings.RespawnInterval;
+ CountdownStarted = false;
+ }
+ }
+
+ partial void UpdateTransportingProjSpecific(float deltaTime)
+ {
+ //if there are no living chracters inside, transporting can be stopped immediately
+ if (!Character.CharacterList.Any(c => c.Submarine == respawnShuttle && !c.IsDead))
+ {
+ shuttleTransportTimer = 0.0f;
+ }
+
+ if (shuttleTransportTimer <= 0.0f)
+ {
+ GameServer.Log("The respawn shuttle is leaving.", ServerLog.MessageType.ServerMessage);
+ state = State.Returning;
+
+ GameMain.Server.CreateEntityEvent(this);
+
+ CountdownStarted = false;
+ maxTransportTime = GameMain.Server.ServerSettings.MaxTransportTime;
+ shuttleReturnTimer = maxTransportTime;
+ shuttleTransportTimer = maxTransportTime;
+ }
+ }
+
partial void RespawnCharactersProjSpecific()
{
- var server = networkMember as GameServer;
- if (server == null) return;
-
var respawnSub = respawnShuttle ?? Submarine.MainSub;
var clients = GetClientsToRespawn();
@@ -150,7 +203,7 @@ namespace Barotrauma.Networking
var botsToSpawn = GetBotsToRespawn();
characterInfos.AddRange(botsToSpawn);
- server.AssignJobs(clients);
+ GameMain.Server.AssignJobs(clients);
foreach (Client c in clients)
{
c.CharacterInfo.Job = new Job(c.AssignedJob);
@@ -241,7 +294,6 @@ namespace Barotrauma.Networking
item.Description = shuttleSpawnPoints[i].IdCardDesc;
}
}
-
}
}
}
diff --git a/Barotrauma/BarotraumaServer/Source/Networking/ServerSettings.cs b/Barotrauma/BarotraumaServer/Source/Networking/ServerSettings.cs
index ec80a70d9..178889ce4 100644
--- a/Barotrauma/BarotraumaServer/Source/Networking/ServerSettings.cs
+++ b/Barotrauma/BarotraumaServer/Source/Networking/ServerSettings.cs
@@ -236,8 +236,8 @@ namespace Barotrauma.Networking
TraitorsEnabled = traitorsEnabled;
GameMain.NetLobbyScreen.SetTraitorsEnabled(traitorsEnabled);
- var botSpawnMode = BotSpawnMode.Fill;
- Enum.TryParse(doc.Root.GetAttributeString("BotSpawnMode", "Fill"), out botSpawnMode);
+ var botSpawnMode = BotSpawnMode.Normal;
+ Enum.TryParse(doc.Root.GetAttributeString("BotSpawnMode", "Normal"), out botSpawnMode);
BotSpawnMode = botSpawnMode;
//"65-90", "97-122", "48-59" = upper and lower case english alphabet and numbers
diff --git a/Barotrauma/BarotraumaShared/OpenALSoft_LICENSE b/Barotrauma/BarotraumaShared/OpenALSoft_LICENSE
new file mode 100644
index 000000000..8d5d00006
--- /dev/null
+++ b/Barotrauma/BarotraumaShared/OpenALSoft_LICENSE
@@ -0,0 +1,437 @@
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
diff --git a/Barotrauma/BarotraumaShared/SharedContent.projitems b/Barotrauma/BarotraumaShared/SharedContent.projitems
index 4e8cb7f62..cc7685501 100644
--- a/Barotrauma/BarotraumaShared/SharedContent.projitems
+++ b/Barotrauma/BarotraumaShared/SharedContent.projitems
@@ -2306,11 +2306,16 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
- Never
+ PreserveNewest
- Never
@@ -3448,7 +3453,6 @@
PreserveNewest
- Never
PreserveNewest
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/AITarget.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/AITarget.cs
index 5add4a6b3..07e5b86a8 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/AITarget.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/AITarget.cs
@@ -22,6 +22,11 @@ namespace Barotrauma
private float soundRange;
private float sightRange;
+
+ ///
+ /// How long does it take for the ai target to fade out if not kept alive.
+ ///
+ public float FadeOutTime { get; private set; } = 3;
public float SoundRange
{
@@ -121,6 +126,7 @@ namespace Barotrauma
MinSoundRange = element.GetAttributeFloat("minsoundrange", SoundRange);
MaxSightRange = element.GetAttributeFloat("maxsightrange", SightRange);
MaxSoundRange = element.GetAttributeFloat("maxsoundrange", SoundRange);
+ FadeOutTime = element.GetAttributeFloat("fadeouttime", FadeOutTime);
SonarLabel = element.GetAttributeString("sonarlabel", "");
string typeString = element.GetAttributeString("type", "Any");
if (Enum.TryParse(typeString, out TargetType t))
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs
index 3d04ce7ae..059634be8 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs
@@ -435,7 +435,7 @@ namespace Barotrauma
{
if (gap.Submarine != Character.Submarine) { continue; }
if (gap.Open < 1 || gap.IsRoomToRoom) { continue; }
- var path = indoorSteering.PathFinder.FindPath(Character.SimPosition, gap.SimPosition);
+ var path = indoorSteering.PathFinder.FindPath(Character.SimPosition, gap.SimPosition, Character.Submarine);
if (!path.Unreachable)
{
if (escapePoint != Vector2.Zero)
@@ -1182,7 +1182,7 @@ namespace Barotrauma
}
else if (target.Entity != null)
{
- //skip the target if it's a room and the character is already inside a sub
+ // Ignore the target if it's a room and the character is already inside a sub
if (character.CurrentHull != null && target.Entity is Hull) { continue; }
Door door = null;
@@ -1203,6 +1203,12 @@ namespace Barotrauma
break;
}
}
+
+ // Ignore the target if it's a decoy and the character is already inside a sub
+ if (character.CurrentHull != null && targetingTag == "decoy")
+ {
+ continue;
+ }
}
else if (target.Entity is Structure s)
{
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/IndoorsSteeringManager.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/IndoorsSteeringManager.cs
index 633163ab7..72c150ed6 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/IndoorsSteeringManager.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/IndoorsSteeringManager.cs
@@ -154,6 +154,7 @@ namespace Barotrauma
currentTarget = target;
Vector2 pos = host.SimPosition;
+ // TODO: remove this and handle differently?
if (character != null && character.Submarine == null)
{
var targetHull = Hull.FindHull(FarseerPhysics.ConvertUnits.ToDisplayUnits(target), null, false);
@@ -163,7 +164,7 @@ namespace Barotrauma
}
}
- var newPath = pathFinder.FindPath(pos, target, "(Character: " + character.Name + ")");
+ var newPath = pathFinder.FindPath(pos, target, character.Submarine, "(Character: " + character.Name + ")");
bool useNewPath = currentPath == null || needsNewPath;
if (!useNewPath && currentPath != null && currentPath.CurrentNode != null && newPath.Nodes.Any() && !newPath.Unreachable)
{
@@ -448,7 +449,8 @@ namespace Barotrauma
private float? GetNodePenalty(PathNode node, PathNode nextNode)
{
- if (character == null) { return 0.0f; }
+ if (character == null) { return 0.0f; }
+ if (nextNode.Waypoint.isObstructed) { return null; }
float penalty = 0.0f;
if (nextNode.Waypoint.ConnectedGap != null && nextNode.Waypoint.ConnectedGap.Open < 0.9f)
{
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjective.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjective.cs
index 0a1ae5f75..f51799a7a 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjective.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjective.cs
@@ -215,11 +215,12 @@ namespace Barotrauma
protected virtual void OnCompleted()
{
- if (Completed != null)
- {
- Completed();
- Completed = null;
- }
+ Completed?.Invoke();
+ //if (Completed != null)
+ //{
+ // Completed();
+ // Completed = null;
+ //}
}
public virtual void Reset() { }
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs
index 980ca257d..8e5f15598 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs
@@ -181,8 +181,7 @@ namespace Barotrauma
{
if (closeEnough)
{
- character.AIController.SteeringManager.Reset();
- character.AnimController.TargetDir = Target.WorldPosition.X > character.WorldPosition.X ? Direction.Right : Direction.Left;
+ OnCompleted();
}
return false;
}
@@ -204,11 +203,6 @@ namespace Barotrauma
}
}
}
- if (isCompleted)
- {
- character.AIController.SteeringManager.Reset();
- character.AnimController.TargetDir = Target.WorldPosition.X > character.WorldPosition.X ? Direction.Right : Direction.Left;
- }
return isCompleted;
}
@@ -223,5 +217,15 @@ namespace Barotrauma
float interactionDistance = Target is Item i ? i.InteractDistance * 0.9f : 0;
CloseEnough = Math.Max(interactionDistance, CloseEnough);
}
+
+ protected override void OnCompleted()
+ {
+ character.AIController.SteeringManager.Reset();
+ if (Target != null)
+ {
+ character.AnimController.TargetDir = Target.WorldPosition.X > character.WorldPosition.X ? Direction.Right : Direction.Left;
+ }
+ base.OnCompleted();
+ }
}
}
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs
index 95a7972a0..aeabd6331 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs
@@ -156,7 +156,7 @@ namespace Barotrauma
bool isRoomNameFound = currentTarget.DisplayName != null;
errorMsg = "(Character " + character.Name + " idling, target " + (isRoomNameFound ? currentTarget.DisplayName : currentTarget.ToString()) + ")";
#endif
- var path = PathSteering.PathFinder.FindPath(character.SimPosition, currentTarget.SimPosition, errorMsg);
+ var path = PathSteering.PathFinder.FindPath(character.SimPosition, currentTarget.SimPosition, errorMsgStr: errorMsg);
PathSteering.SetPath(path);
}
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Order.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Order.cs
index 202310ced..c481eaa39 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Order.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Order.cs
@@ -173,7 +173,7 @@ namespace Barotrauma
if (targetCharacterName == null) targetCharacterName = "";
if (targetRoomName == null) targetRoomName = "";
- string msg = TextManager.GetWithVariables(messageTag, new string[2] { "[name]", "[roomname]" }, new string[2] { targetCharacterName, targetRoomName }, new bool[2] { false, true });
+ string msg = TextManager.GetWithVariables(messageTag, new string[2] { "[name]", "[roomname]" }, new string[2] { targetCharacterName, targetRoomName }, new bool[2] { false, true }, true);
if (msg == null) return "";
return msg;
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/PathFinder.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/PathFinder.cs
index 967a0b9d8..9f589cf8f 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/PathFinder.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/PathFinder.cs
@@ -157,13 +157,18 @@ namespace Barotrauma
}
}
- public SteeringPath FindPath(Vector2 start, Vector2 end, string errorMsgStr = null)
+ public SteeringPath FindPath(Vector2 start, Vector2 end, Submarine hostSub = null, string errorMsgStr = null)
{
float closestDist = 0.0f;
PathNode startNode = null;
foreach (PathNode node in nodes)
{
Vector2 nodePos = node.Position;
+ if (hostSub != null)
+ {
+ Vector2 diff = hostSub.SimPosition - node.Waypoint.Submarine.SimPosition;
+ nodePos -= diff;
+ }
float xDiff = Math.Abs(start.X - nodePos.X);
float yDiff = Math.Abs(start.Y - nodePos.Y);
@@ -185,7 +190,7 @@ namespace Barotrauma
if (insideSubmarine)
{
var body = Submarine.PickBody(
- start, node.Waypoint.SimPosition, null,
+ start, nodePos, null,
Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionStairs);
if (body != null)
@@ -215,7 +220,11 @@ namespace Barotrauma
foreach (PathNode node in nodes)
{
Vector2 nodePos = node.Position;
-
+ if (hostSub != null)
+ {
+ Vector2 diff = hostSub.SimPosition - node.Waypoint.Submarine.SimPosition;
+ nodePos -= diff;
+ }
float dist = Vector2.DistanceSquared(end, nodePos);
if (insideSubmarine)
{
@@ -229,7 +238,7 @@ namespace Barotrauma
//if searching for a path inside the sub, make sure the waypoint is visible
if (insideSubmarine)
{
- var body = Submarine.PickBody(end, node.Waypoint.SimPosition, null,
+ var body = Submarine.PickBody(end, nodePos, null,
Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionStairs );
if (body != null)
@@ -237,7 +246,6 @@ namespace Barotrauma
//if (body.UserData is Submarine) continue;
if (body.UserData is Structure && !((Structure)body.UserData).IsPlatform) continue;
if (body.UserData is Item && body.FixtureList[0].CollisionCategories.HasFlag(Physics.CollisionWall)) continue;
-
}
}
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs
index f53705889..1ee54d3a3 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs
@@ -2030,6 +2030,11 @@ namespace Barotrauma
//Do ragdoll shenanigans before Stun because it's still technically a stun, innit? Less network updates for us!
bool allowRagdoll = GameMain.NetworkMember != null ? GameMain.NetworkMember.ServerSettings.AllowRagdollButton : true;
+ bool tooFastToUnragdoll = AnimController.Collider.LinearVelocity.LengthSquared() > 1f;
+ if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
+ {
+ tooFastToUnragdoll = false;
+ }
if (IsForceRagdolled)
{
IsRagdolled = IsForceRagdolled;
@@ -2039,7 +2044,7 @@ namespace Barotrauma
IsRagdolled = IsKeyDown(InputType.Ragdoll);
}
//Keep us ragdolled if we were forced or we're too speedy to unragdoll
- else if (allowRagdoll && (!IsRagdolled || AnimController.Collider.LinearVelocity.LengthSquared() < 1f))
+ else if (allowRagdoll && (!IsRagdolled || !tooFastToUnragdoll))
{
if (ragdollingLockTimer > 0.0f)
{
@@ -2589,7 +2594,7 @@ namespace Barotrauma
if (info != null) { info.Remove(); }
#if CLIENT
- GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
+ GameMain.GameSession?.CrewManager?.KillCharacter(this);
#endif
CharacterList.Remove(this);
diff --git a/Barotrauma/BarotraumaShared/Source/CoroutineManager.cs b/Barotrauma/BarotraumaShared/Source/CoroutineManager.cs
index e31ffb9dc..701d6259b 100644
--- a/Barotrauma/BarotraumaShared/Source/CoroutineManager.cs
+++ b/Barotrauma/BarotraumaShared/Source/CoroutineManager.cs
@@ -89,6 +89,14 @@ namespace Barotrauma
public static void StopCoroutines(string name)
{
+ Coroutines.ForEach(c =>
+ {
+ if (c.Name == name)
+ {
+ c.Thread?.Abort();
+ c.Thread?.Join();
+ }
+ });
Coroutines.RemoveAll(c => c.Name == name);
}
@@ -99,31 +107,42 @@ namespace Barotrauma
public static void ExecuteCoroutineThread(CoroutineHandle handle)
{
- while (true)
+ try
{
- if (handle.Coroutine.Current != null)
+ while (true)
{
- WaitForSeconds wfs = handle.Coroutine.Current as WaitForSeconds;
- if (wfs != null)
+ if (handle.Coroutine.Current != null)
{
- Thread.Sleep((int)(wfs.TotalTime * 1000));
- }
- else
- {
- switch ((CoroutineStatus)handle.Coroutine.Current)
+ WaitForSeconds wfs = handle.Coroutine.Current as WaitForSeconds;
+ if (wfs != null)
{
- case CoroutineStatus.Success:
- return;
+ Thread.Sleep((int)(wfs.TotalTime * 1000));
+ }
+ else
+ {
+ switch ((CoroutineStatus)handle.Coroutine.Current)
+ {
+ case CoroutineStatus.Success:
+ return;
- case CoroutineStatus.Failure:
- DebugConsole.ThrowError("Coroutine \"" + handle.Name + "\" has failed");
- return;
+ case CoroutineStatus.Failure:
+ DebugConsole.ThrowError("Coroutine \"" + handle.Name + "\" has failed");
+ return;
+ }
}
}
- }
- Thread.Yield();
- if (!handle.Coroutine.MoveNext()) return;
+ Thread.Yield();
+ if (!handle.Coroutine.MoveNext()) return;
+ }
+ }
+ catch (ThreadAbortException tae)
+ {
+ //not an error, don't worry about it
+ }
+ catch (Exception e)
+ {
+ DebugConsole.ThrowError("Coroutine \"" + handle.Name + "\" has thrown an exception", e);
}
}
diff --git a/Barotrauma/BarotraumaShared/Source/Events/MonsterEvent.cs b/Barotrauma/BarotraumaShared/Source/Events/MonsterEvent.cs
index 6c65cee87..13e1429f2 100644
--- a/Barotrauma/BarotraumaShared/Source/Events/MonsterEvent.cs
+++ b/Barotrauma/BarotraumaShared/Source/Events/MonsterEvent.cs
@@ -112,6 +112,7 @@ namespace Barotrauma
List positions = new List();
foreach (var allowedPosition in availablePositions)
{
+ if (Level.Loaded.ExtraWalls.Any(w => w.Cells.Any(c => c.IsPointInside(allowedPosition.Position.ToVector2())))) { continue; }
positions.Add(allowedPosition.Position.ToVector2());
}
diff --git a/Barotrauma/BarotraumaShared/Source/FrameCounter.cs b/Barotrauma/BarotraumaShared/Source/FrameCounter.cs
index 906746002..647d4c6d8 100644
--- a/Barotrauma/BarotraumaShared/Source/FrameCounter.cs
+++ b/Barotrauma/BarotraumaShared/Source/FrameCounter.cs
@@ -42,7 +42,7 @@ namespace Barotrauma
public float GetAverageElapsedMillisecs(string identifier)
{
if (!avgTicksPerFrame.ContainsKey(identifier)) return 0.0f;
- return avgTicksPerFrame[identifier] / TimeSpan.TicksPerMillisecond;
+ return avgTicksPerFrame[identifier] / (float)TimeSpan.TicksPerMillisecond;
}
public bool Update(double deltaTime)
diff --git a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/CampaignMode.cs b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/CampaignMode.cs
index 3ddd11311..514256b4d 100644
--- a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/CampaignMode.cs
+++ b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/CampaignMode.cs
@@ -98,7 +98,7 @@ namespace Barotrauma
{
if (item.GetComponent() != null)
{
- item.Condition = item.Health;
+ item.Condition = item.Prefab.Health;
}
}
}
@@ -176,7 +176,16 @@ namespace Barotrauma
Level.Loaded.Seed + (outpost == Level.Loaded.StartOutpost ? "start" : "end"));
InitializeWatchman(spawnedCharacter);
var objectiveManager = (spawnedCharacter.AIController as HumanAIController)?.ObjectiveManager;
- objectiveManager?.SetOrder(new AIObjectiveGoTo(watchmanSpawnpoint, spawnedCharacter, objectiveManager, repeat: true, getDivingGearIfNeeded: false));
+ if (objectiveManager != null)
+ {
+ var moveOrder = new AIObjectiveGoTo(watchmanSpawnpoint, spawnedCharacter, objectiveManager, repeat: true, getDivingGearIfNeeded: false);
+ moveOrder.Completed += () =>
+ {
+ // Turn towards the center of the sub. Doesn't work in all possible cases, but this is the simplest solution for now.
+ spawnedCharacter.AnimController.TargetDir = spawnedCharacter.Submarine.WorldPosition.X > spawnedCharacter.WorldPosition.X ? Direction.Right : Direction.Left;
+ };
+ objectiveManager.SetOrder(moveOrder);
+ }
if (watchmanJob != null)
{
spawnedCharacter.GiveJobItems();
diff --git a/Barotrauma/BarotraumaShared/Source/GameSession/GameSession.cs b/Barotrauma/BarotraumaShared/Source/GameSession/GameSession.cs
index 32e255691..30bf32cab 100644
--- a/Barotrauma/BarotraumaShared/Source/GameSession/GameSession.cs
+++ b/Barotrauma/BarotraumaShared/Source/GameSession/GameSession.cs
@@ -241,6 +241,14 @@ namespace Barotrauma
}
}
+ foreach (var sub in Submarine.Loaded)
+ {
+ if (sub.IsOutpost)
+ {
+ sub.DisableObstructedWayPoints();
+ }
+ }
+
Entity.Spawner = new EntitySpawner();
if (GameMode.Mission != null) Mission = GameMode.Mission;
diff --git a/Barotrauma/BarotraumaShared/Source/GameSettings.cs b/Barotrauma/BarotraumaShared/Source/GameSettings.cs
index 26313251a..79f5a57c6 100644
--- a/Barotrauma/BarotraumaShared/Source/GameSettings.cs
+++ b/Barotrauma/BarotraumaShared/Source/GameSettings.cs
@@ -25,7 +25,7 @@ namespace Barotrauma
}
public partial class GameSettings
- {
+ {
const string savePath = "config.xml";
const string playerSavePath = "config_player.xml";
const string vanillaContentPackagePath = "Data/ContentPackages/Vanilla";
@@ -43,9 +43,9 @@ namespace Barotrauma
public bool SpecularityEnabled { get; set; }
public bool ChromaticAberrationEnabled { get; set; }
- public bool PauseOnFocusLost { get; set; } = true;
+ public bool PauseOnFocusLost { get; set; }
public bool MuteOnFocusLost { get; set; }
- public bool UseDirectionalVoiceChat { get; set; } = true;
+ public bool UseDirectionalVoiceChat { get; set; }
public enum VoiceMode
{
@@ -57,7 +57,7 @@ namespace Barotrauma
public VoiceMode VoiceSetting { get; set; }
public string VoiceCaptureDevice { get; set; }
- public float NoiseGateThreshold { get; set; } = -45;
+ public float NoiseGateThreshold { get; set; }
private KeyOrMouse[] keyMapping;
@@ -69,12 +69,7 @@ namespace Barotrauma
private bool useSteamMatchmaking;
private bool requireSteamAuthentication;
-
- public string QuickStartSubmarineName
- {
- get;
- set;
- }
+ public string QuickStartSubmarineName;
#if DEBUG
//steam functionality can be enabled/disabled in debug builds
@@ -126,7 +121,7 @@ namespace Barotrauma
set { jobPreferences = value; }
}
- public int CharacterHeadIndex { get; set; } = 1;
+ public int CharacterHeadIndex { get; set; }
public int CharacterHairIndex { get; set; }
public int CharacterBeardIndex { get; set; }
public int CharacterMoustacheIndex { get; set; }
@@ -160,7 +155,6 @@ namespace Barotrauma
#if CLIENT
if (applyButton != null)
{
- //applyButton.Selected = unsavedSettings;
applyButton.Enabled = unsavedSettings;
applyButton.Text = TextManager.Get(unsavedSettings ? "ApplySettingsButtonUnsavedChanges" : "ApplySettingsButton");
}
@@ -168,7 +162,7 @@ namespace Barotrauma
}
}
- private float soundVolume = 0.5f, musicVolume = 0.3f, voiceChatVolume = 0.5f, microphoneVolume = 1.0f;
+ private float soundVolume, musicVolume, voiceChatVolume, microphoneVolume;
public float SoundVolume
{
@@ -229,9 +223,9 @@ namespace Barotrauma
private HashSet selectedContentPackagePaths = new HashSet();
- public string MasterServerUrl { get; set; }
- public bool AutoCheckUpdates { get; set; }
- public bool WasGameUpdated { get; set; }
+ public string MasterServerUrl { get; set; }
+ public bool AutoCheckUpdates { get; set; }
+ public bool WasGameUpdated { get; set; }
private string defaultPlayerName;
public string DefaultPlayerName
@@ -256,9 +250,9 @@ namespace Barotrauma
}
private const float MinHUDScale = 0.75f, MaxHUDScale = 1.25f;
- public static float HUDScale { get; set; } = 1.0f;
+ public static float HUDScale { get; set; }
private const float MinInventoryScale = 0.75f, MaxInventoryScale = 1.25f;
- public static float InventoryScale { get; set; } = 1.0f;
+ public static float InventoryScale { get; set; }
public List CompletedTutorialNames { get; private set; }
@@ -267,7 +261,7 @@ namespace Barotrauma
public bool CampaignDisclaimerShown, EditorDisclaimerShown;
- private static bool sendUserStatistics;
+ private static bool sendUserStatistics = true;
public static bool SendUserStatistics
{
get { return sendUserStatistics; }
@@ -353,13 +347,7 @@ namespace Barotrauma
}
if (doc != null)
{
- foreach (XElement subElement in doc.Root.Elements())
- {
- if (subElement.Name.ToString().ToLowerInvariant() == "keymapping")
- {
- LoadKeyBinds(subElement);
- }
- }
+ LoadControls(doc);
}
}
@@ -415,35 +403,15 @@ namespace Barotrauma
}
}
- #region Load DefaultConfig
private void LoadDefaultConfig(bool setLanguage = true)
{
XDocument doc = XMLExtensions.TryLoadXml(savePath);
-
- if (setLanguage || string.IsNullOrEmpty(Language))
- {
- Language = doc.Root.GetAttributeString("language", "English");
- }
-
- MasterServerUrl = doc.Root.GetAttributeString("masterserverurl", "");
-
- AutoCheckUpdates = doc.Root.GetAttributeBool("autocheckupdates", true);
- WasGameUpdated = doc.Root.GetAttributeBool("wasgameupdated", false);
-
- VerboseLogging = doc.Root.GetAttributeBool("verboselogging", false);
- SaveDebugConsoleLogs = doc.Root.GetAttributeBool("savedebugconsolelogs", false);
-
- QuickStartSubmarineName = doc.Root.GetAttributeString("quickstartsub", "");
-
if (doc == null)
{
GraphicsWidth = 1024;
- GraphicsHeight = 678;
-
+ GraphicsHeight = 768;
MasterServerUrl = "";
-
SelectedContentPackages.Add(ContentPackage.List.Any() ? ContentPackage.List[0] : new ContentPackage(""));
-
jobPreferences = new List();
foreach (JobPrefab job in JobPrefab.List)
{
@@ -452,158 +420,24 @@ namespace Barotrauma
return;
}
- XElement graphicsMode = doc.Root.Element("graphicsmode");
- GraphicsWidth = 0;
- GraphicsHeight = 0;
- VSyncEnabled = graphicsMode.GetAttributeBool("vsync", true);
-
- XElement graphicsSettings = doc.Root.Element("graphicssettings");
- ParticleLimit = graphicsSettings.GetAttributeInt("particlelimit", 1500);
- LightMapScale = MathHelper.Clamp(graphicsSettings.GetAttributeFloat("lightmapscale", 0.5f), 0.1f, 1.0f);
- SpecularityEnabled = graphicsSettings.GetAttributeBool("specularity", true);
- ChromaticAberrationEnabled = graphicsSettings.GetAttributeBool("chromaticaberration", true);
- HUDScale = graphicsSettings.GetAttributeFloat("hudscale", 1.0f);
- InventoryScale = graphicsSettings.GetAttributeFloat("inventoryscale", 1.0f);
- var losModeStr = graphicsSettings.GetAttributeString("losmode", "Transparent");
- if (!Enum.TryParse(losModeStr, out losMode))
- {
- losMode = LosMode.Transparent;
- }
-
-#if CLIENT
- if (GraphicsWidth == 0 || GraphicsHeight == 0)
- {
- GraphicsWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
- GraphicsHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
- }
-#endif
-
- var windowModeStr = graphicsMode.GetAttributeString("displaymode", "Fullscreen");
- if (!Enum.TryParse(windowModeStr, out WindowMode wm))
- {
- wm = WindowMode.Fullscreen;
- }
- WindowMode = wm;
-
- useSteamMatchmaking = doc.Root.GetAttributeBool("usesteammatchmaking", true);
- requireSteamAuthentication = doc.Root.GetAttributeBool("requiresteamauthentication", true);
- AutoUpdateWorkshopItems = doc.Root.GetAttributeBool("autoupdateworkshopitems", true);
-
-#if DEBUG
- EnableSplashScreen = false;
-#else
- EnableSplashScreen = doc.Root.GetAttributeBool("enablesplashscreen", true);
-#endif
-
- AimAssistAmount = doc.Root.GetAttributeFloat("aimassistamount", 0.5f);
-
+ bool resetLanguage = setLanguage || string.IsNullOrEmpty(Language);
+ SetDefaultValues(resetLanguage);
SetDefaultBindings(doc, legacy: false);
- foreach (XElement subElement in doc.Root.Elements())
- {
- switch (subElement.Name.ToString().ToLowerInvariant())
- {
- case "keymapping":
- LoadKeyBinds(subElement);
- break;
- case "gameplay":
- jobPreferences = new List();
- foreach (XElement ele in subElement.Element("jobpreferences").Elements("job"))
- {
- string jobIdentifier = ele.GetAttributeString("identifier", "");
- if (string.IsNullOrEmpty(jobIdentifier)) continue;
- jobPreferences.Add(jobIdentifier);
- }
- break;
- case "player":
- defaultPlayerName = subElement.GetAttributeString("name", "");
- CharacterHeadIndex = subElement.GetAttributeInt("headindex", CharacterHeadIndex);
- if (Enum.TryParse(subElement.GetAttributeString("gender", "none"), true, out Gender g))
- {
- CharacterGender = g;
- }
- if (Enum.TryParse(subElement.GetAttributeString("race", "white"), true, out Race r))
- {
- CharacterRace = r;
- }
- else
- {
- CharacterRace = Race.White;
- }
- CharacterHairIndex = subElement.GetAttributeInt("hairindex", -1);
- CharacterBeardIndex = subElement.GetAttributeInt("beardindex", -1);
- CharacterMoustacheIndex = subElement.GetAttributeInt("moustacheindex", -1);
- CharacterFaceAttachmentIndex = subElement.GetAttributeInt("faceattachmentindex", -1);
- break;
- }
- }
+ MasterServerUrl = doc.Root.GetAttributeString("masterserverurl", MasterServerUrl);
+ WasGameUpdated = doc.Root.GetAttributeBool("wasgameupdated", WasGameUpdated);
+ VerboseLogging = doc.Root.GetAttributeBool("verboselogging", VerboseLogging);
+ SaveDebugConsoleLogs = doc.Root.GetAttributeBool("savedebugconsolelogs", SaveDebugConsoleLogs);
+ AutoUpdateWorkshopItems = doc.Root.GetAttributeBool("autoupdateworkshopitems", AutoUpdateWorkshopItems);
- List missingPackagePaths = new List();
- List incompatiblePackages = new List();
- foreach (XElement subElement in doc.Root.Elements())
- {
- switch (subElement.Name.ToString().ToLowerInvariant())
- {
- case "contentpackage":
- string path = System.IO.Path.GetFullPath(subElement.GetAttributeString("path", ""));
- var matchingContentPackage = ContentPackage.List.Find(cp => System.IO.Path.GetFullPath(cp.Path) == path);
- if (matchingContentPackage == null)
- {
- missingPackagePaths.Add(path);
- }
- else if (!matchingContentPackage.IsCompatible())
- {
- incompatiblePackages.Add(matchingContentPackage);
- }
- else
- {
- SelectedContentPackages.Add(matchingContentPackage);
- }
- break;
- }
- }
-
- TextManager.LoadTextPacks(SelectedContentPackages);
-
- //display error messages after all content packages have been loaded
- //to make sure the package that contains text files has been loaded before we attempt to use TextManager
- foreach (string missingPackagePath in missingPackagePaths)
- {
- DebugConsole.ThrowError(TextManager.GetWithVariable("ContentPackageNotFound", "[packagepath]", missingPackagePath));
- }
- foreach (ContentPackage incompatiblePackage in incompatiblePackages)
- {
- DebugConsole.ThrowError(TextManager.GetWithVariables(incompatiblePackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage",
- new string[3] { "[packagename]", "[packageversion]", "[gameversion]" }, new string[3] { incompatiblePackage.Name, incompatiblePackage.GameVersion.ToString(), GameMain.Version.ToString() }));
- }
- foreach (ContentPackage contentPackage in SelectedContentPackages)
- {
- bool packageOk = contentPackage.VerifyFiles(out List errorMessages);
- if (!packageOk)
- {
- DebugConsole.ThrowError("Error in content package \"" + contentPackage.Name + "\":\n" + string.Join("\n", errorMessages));
- continue;
- }
- foreach (ContentFile file in contentPackage.Files)
- {
- ToolBox.IsProperFilenameCase(file.Path);
- }
- }
- if (!SelectedContentPackages.Any())
- {
- var availablePackage = ContentPackage.List.FirstOrDefault(cp => cp.IsCompatible() && cp.CorePackage);
- if (availablePackage != null)
- {
- SelectedContentPackages.Add(availablePackage);
- }
- }
-
- //save to get rid of the invalid selected packages in the config file
- if (missingPackagePaths.Count > 0 || incompatiblePackages.Count > 0) { SaveNewPlayerConfig(); }
+ LoadGeneralSettings(doc, resetLanguage);
+ LoadGraphicSettings(doc);
+ LoadAudioSettings(doc);
+ LoadControls(doc);
+ LoadContentPackages(doc);
+ UnsavedSettings = false;
}
- #endregion
- #region Save DefaultConfig
private void SaveNewDefaultConfig()
{
XDocument doc = new XDocument();
@@ -619,6 +453,7 @@ namespace Barotrauma
new XAttribute("autocheckupdates", AutoCheckUpdates),
new XAttribute("musicvolume", musicVolume),
new XAttribute("soundvolume", soundVolume),
+ new XAttribute("microphonevolume", microphoneVolume),
new XAttribute("voicechatvolume", voiceChatVolume),
new XAttribute("verboselogging", VerboseLogging),
new XAttribute("savedebugconsolelogs", SaveDebugConsoleLogs),
@@ -637,7 +472,7 @@ namespace Barotrauma
{
doc.Root.Add(new XAttribute("wasgameupdated", true));
}
-
+
XElement gMode = doc.Root.Element("graphicsmode");
if (gMode == null)
{
@@ -738,7 +573,6 @@ namespace Barotrauma
"Saving game settings failed.\n" + e.Message + "\n" + e.StackTrace);
}
}
- #endregion
#region Load PlayerConfig
public void LoadPlayerConfig()
@@ -760,143 +594,27 @@ namespace Barotrauma
private bool LoadPlayerConfigInternal()
{
XDocument doc = XMLExtensions.LoadXml(playerSavePath);
-
if (doc == null || doc.Root == null)
{
ShowUserStatisticsPrompt = true;
return false;
}
+ LoadGeneralSettings(doc);
+ LoadGraphicSettings(doc);
+ LoadAudioSettings(doc);
+ LoadControls(doc);
+ LoadContentPackages(doc);
- Language = doc.Root.GetAttributeString("language", Language);
- AutoCheckUpdates = doc.Root.GetAttributeBool("autocheckupdates", AutoCheckUpdates);
- sendUserStatistics = doc.Root.GetAttributeBool("senduserstatistics", true);
-
- XElement graphicsMode = doc.Root.Element("graphicsmode");
- GraphicsWidth = graphicsMode.GetAttributeInt("width", GraphicsWidth);
- GraphicsHeight = graphicsMode.GetAttributeInt("height", GraphicsHeight);
- VSyncEnabled = graphicsMode.GetAttributeBool("vsync", VSyncEnabled);
-
- XElement graphicsSettings = doc.Root.Element("graphicssettings");
- ParticleLimit = graphicsSettings.GetAttributeInt("particlelimit", ParticleLimit);
- LightMapScale = MathHelper.Clamp(graphicsSettings.GetAttributeFloat("lightmapscale", LightMapScale), 0.1f, 1.0f);
- SpecularityEnabled = graphicsSettings.GetAttributeBool("specularity", SpecularityEnabled);
- ChromaticAberrationEnabled = graphicsSettings.GetAttributeBool("chromaticaberration", ChromaticAberrationEnabled);
- HUDScale = graphicsSettings.GetAttributeFloat("hudscale", HUDScale);
- InventoryScale = graphicsSettings.GetAttributeFloat("inventoryscale", InventoryScale);
- var losModeStr = graphicsSettings.GetAttributeString("losmode", "Transparent");
- if (!Enum.TryParse(losModeStr, out losMode))
+ XElement tutorialsElement = doc.Root.Element("tutorials");
+ if (tutorialsElement != null)
{
- losMode = LosMode.Transparent;
- }
-
-#if CLIENT
- if (GraphicsWidth == 0 || GraphicsHeight == 0)
- {
- GraphicsWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
- GraphicsHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
- }
-#endif
-
- var windowModeStr = graphicsMode.GetAttributeString("displaymode", "Fullscreen");
- if (!Enum.TryParse(windowModeStr, out windowMode))
- {
- windowMode = WindowMode.Fullscreen;
- }
-
- XElement audioSettings = doc.Root.Element("audio");
- if (audioSettings != null)
- {
- SoundVolume = audioSettings.GetAttributeFloat("soundvolume", SoundVolume);
- MusicVolume = audioSettings.GetAttributeFloat("musicvolume", MusicVolume);
- VoiceChatVolume = audioSettings.GetAttributeFloat("voicechatvolume", VoiceChatVolume);
- MuteOnFocusLost = audioSettings.GetAttributeBool("muteonfocuslost", false);
- UseDirectionalVoiceChat = audioSettings.GetAttributeBool("usedirectionalvoicechat", true);
- string voiceSettingStr = audioSettings.GetAttributeString("voicesetting", "Disabled");
- VoiceCaptureDevice = audioSettings.GetAttributeString("voicecapturedevice", "");
- NoiseGateThreshold = audioSettings.GetAttributeFloat("noisegatethreshold", -45);
- var voiceSetting = VoiceMode.Disabled;
- if (Enum.TryParse(voiceSettingStr, out voiceSetting))
+ foreach (XElement element in tutorialsElement.Elements())
{
- VoiceSetting = voiceSetting;
- }
- }
-
- useSteamMatchmaking = doc.Root.GetAttributeBool("usesteammatchmaking", useSteamMatchmaking);
- requireSteamAuthentication = doc.Root.GetAttributeBool("requiresteamauthentication", requireSteamAuthentication);
-
- EnableSplashScreen = doc.Root.GetAttributeBool("enablesplashscreen", EnableSplashScreen);
-
- PauseOnFocusLost = doc.Root.GetAttributeBool("pauseonfocuslost", PauseOnFocusLost);
- AimAssistAmount = doc.Root.GetAttributeFloat("aimassistamount", AimAssistAmount);
- EnableMouseLook = doc.Root.GetAttributeBool("enablemouselook", EnableMouseLook);
-
- CrewMenuOpen = doc.Root.GetAttributeBool("crewmenuopen", CrewMenuOpen);
- ChatOpen = doc.Root.GetAttributeBool("chatopen", ChatOpen);
-
- CampaignDisclaimerShown = doc.Root.GetAttributeBool("campaigndisclaimershown", false);
- EditorDisclaimerShown = doc.Root.GetAttributeBool("editordisclaimershown", false);
-
- foreach (XElement subElement in doc.Root.Elements())
- {
- switch (subElement.Name.ToString().ToLowerInvariant())
- {
- case "keymapping":
- LoadKeyBinds(subElement);
- break;
- case "gameplay":
- jobPreferences = new List();
- foreach (XElement ele in subElement.Element("jobpreferences").Elements("job"))
- {
- string jobIdentifier = ele.GetAttributeString("identifier", "");
- if (string.IsNullOrEmpty(jobIdentifier)) continue;
- jobPreferences.Add(jobIdentifier);
- }
- break;
- case "player":
- defaultPlayerName = subElement.GetAttributeString("name", defaultPlayerName);
- CharacterHeadIndex = subElement.GetAttributeInt("headindex", CharacterHeadIndex);
- if (Enum.TryParse(subElement.GetAttributeString("gender", "none"), true, out Gender g))
- {
- CharacterGender = g;
- }
- if (Enum.TryParse(subElement.GetAttributeString("race", "white"), true, out Race r))
- {
- CharacterRace = r;
- }
- else
- {
- CharacterRace = Race.White;
- }
- CharacterHairIndex = subElement.GetAttributeInt("hairindex", CharacterHairIndex);
- CharacterBeardIndex = subElement.GetAttributeInt("beardindex", CharacterBeardIndex);
- CharacterMoustacheIndex = subElement.GetAttributeInt("moustacheindex", CharacterMoustacheIndex);
- CharacterFaceAttachmentIndex = subElement.GetAttributeInt("faceattachmentindex", CharacterFaceAttachmentIndex);
- break;
- case "tutorials":
- foreach (XElement tutorialElement in subElement.Elements())
- {
- CompletedTutorialNames.Add(tutorialElement.GetAttributeString("name", ""));
- }
- break;
+ CompletedTutorialNames.Add(element.GetAttributeString("name", ""));
}
}
UnsavedSettings = false;
-
- selectedContentPackagePaths = new HashSet();
-
- foreach (XElement subElement in doc.Root.Elements())
- {
- switch (subElement.Name.ToString().ToLowerInvariant())
- {
- case "contentpackage":
- string path = System.IO.Path.GetFullPath(subElement.GetAttributeString("path", ""));
- selectedContentPackagePaths.Add(path);
- break;
- }
- }
-
- LoadContentPackages(selectedContentPackagePaths);
return true;
}
@@ -957,7 +675,7 @@ namespace Barotrauma
}
foreach (ContentPackage incompatiblePackage in incompatiblePackages)
{
- DebugConsole.ThrowError(TextManager.GetWithVariables(incompatiblePackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage",
+ DebugConsole.ThrowError(TextManager.GetWithVariables(incompatiblePackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage",
new string[3] { "[packagename]", "[packageversion]", "[gameversion]" }, new string[3] { incompatiblePackage.Name, incompatiblePackage.GameVersion.ToString(), GameMain.Version.ToString() }));
}
}
@@ -1038,7 +756,7 @@ namespace Barotrauma
new XAttribute("vsync", VSyncEnabled),
new XAttribute("displaymode", windowMode));
}
-
+
XElement audio = doc.Root.Element("audio");
if (audio == null)
{
@@ -1048,6 +766,8 @@ namespace Barotrauma
audio.ReplaceAttributes(
new XAttribute("musicvolume", musicVolume),
new XAttribute("soundvolume", soundVolume),
+ new XAttribute("voicechatvolume", voiceChatVolume),
+ new XAttribute("microphonevolume", microphoneVolume),
new XAttribute("muteonfocuslost", MuteOnFocusLost),
new XAttribute("usedirectionalvoicechat", UseDirectionalVoiceChat),
new XAttribute("voicesetting", VoiceSetting),
@@ -1153,12 +873,149 @@ namespace Barotrauma
}
#endregion
+ #region Loading Configs
+ private void LoadGeneralSettings(XDocument doc, bool setLanguage = true)
+ {
+ if (setLanguage)
+ {
+ Language = doc.Root.GetAttributeString("language", Language);
+ }
+ AutoCheckUpdates = doc.Root.GetAttributeBool("autocheckupdates", AutoCheckUpdates);
+ sendUserStatistics = doc.Root.GetAttributeBool("senduserstatistics", sendUserStatistics);
+ QuickStartSubmarineName = doc.Root.GetAttributeString("quickstartsubmarine", "");
+ useSteamMatchmaking = doc.Root.GetAttributeBool("usesteammatchmaking", useSteamMatchmaking);
+ requireSteamAuthentication = doc.Root.GetAttributeBool("requiresteamauthentication", requireSteamAuthentication);
+ EnableSplashScreen = doc.Root.GetAttributeBool("enablesplashscreen", EnableSplashScreen);
+ PauseOnFocusLost = doc.Root.GetAttributeBool("pauseonfocuslost", PauseOnFocusLost);
+ AimAssistAmount = doc.Root.GetAttributeFloat("aimassistamount", AimAssistAmount);
+ EnableMouseLook = doc.Root.GetAttributeBool("enablemouselook", EnableMouseLook);
+ CrewMenuOpen = doc.Root.GetAttributeBool("crewmenuopen", CrewMenuOpen);
+ ChatOpen = doc.Root.GetAttributeBool("chatopen", ChatOpen);
+ CampaignDisclaimerShown = doc.Root.GetAttributeBool("campaigndisclaimershown", CampaignDisclaimerShown);
+ EditorDisclaimerShown = doc.Root.GetAttributeBool("editordisclaimershown", EditorDisclaimerShown);
+ XElement gameplayElement = doc.Root.Element("gameplay");
+ if (gameplayElement != null)
+ {
+ jobPreferences = new List();
+ foreach (XElement ele in gameplayElement.Element("jobpreferences").Elements("job"))
+ {
+ string jobIdentifier = ele.GetAttributeString("identifier", "");
+ if (string.IsNullOrEmpty(jobIdentifier)) continue;
+ jobPreferences.Add(jobIdentifier);
+ }
+ }
+
+ XElement playerElement = doc.Root.Element("player");
+ if (playerElement != null)
+ {
+ defaultPlayerName = playerElement.GetAttributeString("name", defaultPlayerName);
+ CharacterHeadIndex = playerElement.GetAttributeInt("headindex", CharacterHeadIndex);
+ if (Enum.TryParse(playerElement.GetAttributeString("gender", "none"), true, out Gender g))
+ {
+ CharacterGender = g;
+ }
+ if (Enum.TryParse(playerElement.GetAttributeString("race", "white"), true, out Race r))
+ {
+ CharacterRace = r;
+ }
+ else
+ {
+ CharacterRace = Race.White;
+ }
+ CharacterHairIndex = playerElement.GetAttributeInt("hairindex", CharacterHairIndex);
+ CharacterBeardIndex = playerElement.GetAttributeInt("beardindex", CharacterBeardIndex);
+ CharacterMoustacheIndex = playerElement.GetAttributeInt("moustacheindex", CharacterMoustacheIndex);
+ CharacterFaceAttachmentIndex = playerElement.GetAttributeInt("faceattachmentindex", CharacterFaceAttachmentIndex);
+ }
+ }
+
+ private void LoadGraphicSettings(XDocument doc)
+ {
+ XElement graphicsMode = doc.Root.Element("graphicsmode");
+ GraphicsWidth = graphicsMode.GetAttributeInt("width", GraphicsWidth);
+ GraphicsHeight = graphicsMode.GetAttributeInt("height", GraphicsHeight);
+ VSyncEnabled = graphicsMode.GetAttributeBool("vsync", VSyncEnabled);
+
+ XElement graphicsSettings = doc.Root.Element("graphicssettings");
+ ParticleLimit = graphicsSettings.GetAttributeInt("particlelimit", ParticleLimit);
+ LightMapScale = MathHelper.Clamp(graphicsSettings.GetAttributeFloat("lightmapscale", LightMapScale), 0.1f, 1.0f);
+ SpecularityEnabled = graphicsSettings.GetAttributeBool("specularity", SpecularityEnabled);
+ ChromaticAberrationEnabled = graphicsSettings.GetAttributeBool("chromaticaberration", ChromaticAberrationEnabled);
+ HUDScale = graphicsSettings.GetAttributeFloat("hudscale", HUDScale);
+ InventoryScale = graphicsSettings.GetAttributeFloat("inventoryscale", InventoryScale);
+ var losModeStr = graphicsSettings.GetAttributeString("losmode", "Transparent");
+ if (!Enum.TryParse(losModeStr, out losMode))
+ {
+ losMode = LosMode.Transparent;
+ }
+#if CLIENT
+ if (GraphicsWidth == 0 || GraphicsHeight == 0)
+ {
+ GraphicsWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
+ GraphicsHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
+ }
+#endif
+ var windowModeStr = graphicsMode.GetAttributeString("displaymode", "Fullscreen");
+ if (!Enum.TryParse(windowModeStr, out windowMode))
+ {
+ windowMode = WindowMode.Fullscreen;
+ }
+ }
+
+ private void LoadAudioSettings(XDocument doc)
+ {
+ XElement audioSettings = doc.Root.Element("audio");
+ if (audioSettings != null)
+ {
+ SoundVolume = audioSettings.GetAttributeFloat("soundvolume", SoundVolume);
+ MusicVolume = audioSettings.GetAttributeFloat("musicvolume", MusicVolume);
+ VoiceChatVolume = audioSettings.GetAttributeFloat("voicechatvolume", VoiceChatVolume);
+ MuteOnFocusLost = audioSettings.GetAttributeBool("muteonfocuslost", MuteOnFocusLost);
+ UseDirectionalVoiceChat = audioSettings.GetAttributeBool("usedirectionalvoicechat", UseDirectionalVoiceChat);
+ VoiceCaptureDevice = audioSettings.GetAttributeString("voicecapturedevice", VoiceCaptureDevice);
+ NoiseGateThreshold = audioSettings.GetAttributeFloat("noisegatethreshold", NoiseGateThreshold);
+ MicrophoneVolume = audioSettings.GetAttributeFloat("microphonevolume", MicrophoneVolume);
+ var voiceSetting = VoiceMode.Disabled;
+ string voiceSettingStr = audioSettings.GetAttributeString("voicesetting", "");
+ if (Enum.TryParse(voiceSettingStr, out voiceSetting))
+ {
+ VoiceSetting = voiceSetting;
+ }
+ }
+ }
+
+ private void LoadControls(XDocument doc)
+ {
+ XElement keyMapping = doc.Root.Element("keymapping");
+ if (keyMapping != null)
+ {
+ LoadKeyBinds(keyMapping);
+ }
+ }
+
+ private void LoadContentPackages(XDocument doc)
+ {
+ selectedContentPackagePaths = new HashSet();
+ foreach (XElement subElement in doc.Root.Elements())
+ {
+ switch (subElement.Name.ToString().ToLowerInvariant())
+ {
+ case "contentpackage":
+ string path = System.IO.Path.GetFullPath(subElement.GetAttributeString("path", ""));
+ selectedContentPackagePaths.Add(path);
+ break;
+ }
+ }
+ LoadContentPackages(selectedContentPackagePaths);
+ }
+ #endregion
+
private void LoadKeyBinds(XElement element)
{
foreach (XAttribute attribute in element.Attributes())
{
if (!Enum.TryParse(attribute.Name.ToString(), true, out InputType inputType)) { continue; }
-
+
if (int.TryParse(attribute.Value.ToString(), out int mouseButton))
{
keyMapping[(int)inputType] = new KeyOrMouse(mouseButton);
@@ -1169,7 +1026,7 @@ namespace Barotrauma
{
keyMapping[(int)inputType] = new KeyOrMouse(key);
}
- }
+ }
}
}
@@ -1184,5 +1041,62 @@ namespace Barotrauma
{
return keyMapping[(int)inputType];
}
+
+ private void SetDefaultValues(bool resetLanguage = true)
+ {
+ GraphicsWidth = 0;
+ GraphicsHeight = 0;
+ VSyncEnabled = true;
+#if DEBUG
+ EnableSplashScreen = false;
+#else
+ EnableSplashScreen = true;
+#endif
+ ParticleLimit = 1500;
+ LightMapScale = 0.5f;
+ SpecularityEnabled = false;
+ ChromaticAberrationEnabled = true;
+ PauseOnFocusLost = true;
+ MuteOnFocusLost = false;
+ UseDirectionalVoiceChat = true;
+ VoiceSetting = VoiceMode.Disabled;
+ VoiceCaptureDevice = null;
+ NoiseGateThreshold = -45;
+ windowMode = WindowMode.Fullscreen;
+ losMode = LosMode.Transparent;
+ useSteamMatchmaking = true;
+ requireSteamAuthentication = true;
+ QuickStartSubmarineName = string.Empty;
+ CharacterHeadIndex = 1;
+ CharacterHairIndex = -1;
+ CharacterBeardIndex = -1;
+ CharacterMoustacheIndex = -1;
+ CharacterFaceAttachmentIndex = -1;
+ CharacterGender = Gender.None;
+ CharacterRace = Race.White;
+ aimAssistAmount = 0.5f;
+ EnableMouseLook = true;
+ CrewMenuOpen = true;
+ ChatOpen = true;
+ soundVolume = 0.5f;
+ musicVolume = 0.3f;
+ voiceChatVolume = 0.5f;
+ microphoneVolume = 1.0f;
+ AutoCheckUpdates = true;
+ defaultPlayerName = string.Empty;
+ HUDScale = 1;
+ InventoryScale = 1;
+ AutoUpdateWorkshopItems = true;
+ CampaignDisclaimerShown = false;
+ if (resetLanguage)
+ {
+ Language = "English";
+ }
+ MasterServerUrl = "http://www.undertowgames.com/baromaster";
+ WasGameUpdated = false;
+ VerboseLogging = false;
+ SaveDebugConsoleLogs = false;
+ AutoUpdateWorkshopItems = true;
+ }
}
}
diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/DockingPort.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/DockingPort.cs
index 51ffb733b..5ff19891e 100644
--- a/Barotrauma/BarotraumaShared/Source/Items/Components/DockingPort.cs
+++ b/Barotrauma/BarotraumaShared/Source/Items/Components/DockingPort.cs
@@ -33,6 +33,7 @@ namespace Barotrauma.Items.Components
private Body doorBody;
private bool docked;
+ private bool obstructedWayPointsDisabled;
private float forceLockTimer;
//if the submarine isn't in the correct position to lock within this time after docking has been activated,
@@ -732,6 +733,9 @@ namespace Barotrauma.Items.Components
bodies = null;
}
+ Item.Submarine.EnableObstructedWaypoints();
+ obstructedWayPointsDisabled = false;
+
#if SERVER
if (GameMain.Server != null)
{
@@ -813,6 +817,11 @@ namespace Barotrauma.Items.Components
dockingState = MathHelper.Lerp(dockingState, 1.0f, deltaTime * 10.0f);
}
}
+ if (!obstructedWayPointsDisabled && dockingState >= 0.99f)
+ {
+ Item.Submarine.DisableObstructedWayPoints(DockingTarget?.Item.Submarine);
+ obstructedWayPointsDisabled = true;
+ }
}
protected override void RemoveComponentSpecific()
@@ -983,6 +992,5 @@ namespace Barotrauma.Items.Components
Undock();
}
}
-
}
}
diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs
index 4250a83ab..c375e83fa 100644
--- a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs
+++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs
@@ -413,7 +413,7 @@ namespace Barotrauma.Items.Components
{
target = ConvertUnits.ToSimUnits(Level.Loaded.StartPosition);
}
- steeringPath = pathFinder.FindPath(ConvertUnits.ToSimUnits(controlledSub == null ? item.WorldPosition : controlledSub.WorldPosition), target, "(Autopilot, target: " + target + ")");
+ steeringPath = pathFinder.FindPath(ConvertUnits.ToSimUnits(controlledSub == null ? item.WorldPosition : controlledSub.WorldPosition), target, errorMsgStr: "(Autopilot, target: " + target + ")");
}
public void SetDestinationLevelStart()
diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Projectile.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Projectile.cs
index f821873bc..12375fecf 100644
--- a/Barotrauma/BarotraumaShared/Source/Items/Components/Projectile.cs
+++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Projectile.cs
@@ -174,6 +174,12 @@ namespace Barotrauma.Items.Components
private void Launch(Vector2 impulse)
{
+ if (item.AiTarget != null)
+ {
+ item.AiTarget.SightRange = item.AiTarget.MaxSightRange;
+ item.AiTarget.SoundRange = item.AiTarget.MaxSoundRange;
+ }
+
item.Drop(null);
item.body.Enabled = true;
diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Repairable.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Repairable.cs
index a81376338..a17399612 100644
--- a/Barotrauma/BarotraumaShared/Source/Items/Components/Repairable.cs
+++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Repairable.cs
@@ -122,6 +122,16 @@ namespace Barotrauma.Items.Components
Update(deltaTime, cam);
}
+ public void ResetDeterioration()
+ {
+ deteriorationTimer = Rand.Range(MinDeteriorationDelay, MaxDeteriorationDelay);
+ item.Condition = item.Prefab.Health;
+#if SERVER
+ //let the clients know the initial deterioration delay
+ item.CreateServerEvent(this);
+#endif
+ }
+
public override void Update(float deltaTime, Camera cam)
{
UpdateProjSpecific(deltaTime);
diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/Wire.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/Wire.cs
index 0d76efa20..c26ed06c5 100644
--- a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/Wire.cs
+++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/Wire.cs
@@ -338,9 +338,15 @@ namespace Barotrauma.Items.Components
canPlaceNode = true;
}
+ Vector2 relativeNodePos = newNodePos - item.Position;
+ if (sub != null)
+ {
+ relativeNodePos += sub.HiddenSubPosition;
+ }
+
sectionExtents = new Vector2(
- Math.Max(Math.Abs((newNodePos.X + sub.HiddenSubPosition.X) - item.Position.X), sectionExtents.X),
- Math.Max(Math.Abs((newNodePos.Y + sub.HiddenSubPosition.Y) - item.Position.Y), sectionExtents.Y));
+ Math.Max(Math.Abs(relativeNodePos.X), sectionExtents.X),
+ Math.Max(Math.Abs(relativeNodePos.Y), sectionExtents.Y));
}
public override bool Use(float deltaTime, Character character = null)
diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Wearable.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Wearable.cs
index 1befb10a5..974b41790 100644
--- a/Barotrauma/BarotraumaShared/Source/Items/Components/Wearable.cs
+++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Wearable.cs
@@ -286,6 +286,23 @@ namespace Barotrauma.Items.Components
if (!equipLimb.WearingItems.Contains(wearableSprite))
{
equipLimb.WearingItems.Add(wearableSprite);
+ equipLimb.WearingItems.Sort((i1, i2) => { return i2.Sprite.Depth.CompareTo(i1.Sprite.Depth); });
+ equipLimb.WearingItems.Sort((i1, i2) =>
+ {
+ if (i1?.WearableComponent == null && i2?.WearableComponent == null)
+ {
+ return 0;
+ }
+ else if (i1?.WearableComponent == null)
+ {
+ return -1;
+ }
+ else if (i2?.WearableComponent == null)
+ {
+ return 1;
+ }
+ return i1.WearableComponent.AllowedSlots.Contains(InvSlotType.OuterClothes).CompareTo(i2.WearableComponent.AllowedSlots.Contains(InvSlotType.OuterClothes));
+ });
}
}
}
diff --git a/Barotrauma/BarotraumaShared/Source/Items/Item.cs b/Barotrauma/BarotraumaShared/Source/Items/Item.cs
index 752d3df85..9f66bfd6e 100644
--- a/Barotrauma/BarotraumaShared/Source/Items/Item.cs
+++ b/Barotrauma/BarotraumaShared/Source/Items/Item.cs
@@ -1042,8 +1042,8 @@ namespace Barotrauma
//aitarget goes silent/invisible if the components don't keep it active
if (aiTarget != null)
{
- aiTarget.SightRange -= deltaTime * 1000.0f;
- aiTarget.SoundRange -= deltaTime * 1000.0f;
+ aiTarget.SightRange -= deltaTime * (aiTarget.MaxSightRange / aiTarget.FadeOutTime);
+ aiTarget.SoundRange -= deltaTime * (aiTarget.MaxSoundRange / aiTarget.FadeOutTime);
}
bool broken = condition <= 0.0f;
@@ -2017,6 +2017,8 @@ namespace Barotrauma
if (element.GetAttributeBool("flippedy", false)) item.FlipY(false);
item.condition = element.GetAttributeFloat("condition", item.Prefab.Health);
+ item.lastSentCondition = item.condition;
+
item.SetActiveSprite();
foreach (ItemComponent component in item.components)
diff --git a/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs b/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs
index 68b5ca6df..41b29c95a 100644
--- a/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs
+++ b/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs
@@ -1366,6 +1366,11 @@ namespace Barotrauma
}
List suitablePositions = positionsOfInterest.FindAll(p => positionType.HasFlag(p.PositionType));
+ //avoid floating ice chunks on the main path
+ if (positionType == PositionType.MainPath)
+ {
+ suitablePositions.RemoveAll(p => extraWalls.Any(w => w.Cells.Any(c => c.IsPointInside(p.Position.ToVector2()))));
+ }
if (!suitablePositions.Any())
{
string errorMsg = "Could not find a suitable position of interest. (PositionType: " + positionType + ", minDistFromSubs: " + minDistFromSubs + ")\n" + Environment.StackTrace;
diff --git a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs
index 2cb8f3192..ec3110b71 100644
--- a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs
+++ b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs
@@ -1433,7 +1433,7 @@ namespace Barotrauma
Submarine sub = new Submarine(path);
sub.Load(unloadPrevious);
-
+
return sub;
}
@@ -1564,6 +1564,94 @@ namespace Barotrauma
PreviewImage = null;
#endif
}
+
+ private List outdoorNodes;
+ private List OutdoorNodes
+ {
+ get
+ {
+ if (outdoorNodes == null)
+ {
+ outdoorNodes = PathNode.GenerateNodes(WayPoint.WayPointList.FindAll(wp => wp.SpawnType == SpawnType.Path && wp.Submarine == this && wp.CurrentHull == null));
+ }
+ return outdoorNodes;
+ }
+ }
+ private HashSet obstructedNodes = new HashSet();
+
+ ///
+ /// Permanently disables obstructed waypoints obstructed by the level.
+ ///
+ public void DisableObstructedWayPoints()
+ {
+ // Check collisions to level
+ foreach (var node in OutdoorNodes)
+ {
+ if (node == null || node.Waypoint == null) { continue; }
+ var wp = node.Waypoint;
+ if (wp.isObstructed) { continue; }
+ foreach (var connection in node.connections)
+ {
+ bool isObstructed = false;
+ var connectedWp = connection.Waypoint;
+ if (connectedWp.isObstructed) { continue; }
+ Vector2 start = ConvertUnits.ToSimUnits(wp.WorldPosition);
+ Vector2 end = ConvertUnits.ToSimUnits(connectedWp.WorldPosition);
+ var body = Submarine.PickBody(start, end, null, Physics.CollisionLevel, allowInsideFixture: false);
+ if (body != null)
+ {
+ connectedWp.isObstructed = true;
+ wp.isObstructed = true;
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Temporarily disables waypoints obstructed by the other sub.
+ ///
+ public void DisableObstructedWayPoints(Submarine otherSub)
+ {
+ if (otherSub == null) { return; }
+ if (otherSub == this) { return; }
+ // Check collisions to other subs. Currently only walls are taken into account.
+ foreach (var node in OutdoorNodes)
+ {
+ if (node == null || node.Waypoint == null) { continue; }
+ var wp = node.Waypoint;
+ if (wp.isObstructed) { continue; }
+ foreach (var connection in node.connections)
+ {
+ bool isObstructed = false;
+ var connectedWp = connection.Waypoint;
+ if (connectedWp.isObstructed) { continue; }
+ Vector2 start = ConvertUnits.ToSimUnits(wp.WorldPosition) - otherSub.SimPosition;
+ Vector2 end = ConvertUnits.ToSimUnits(connectedWp.WorldPosition) - otherSub.SimPosition;
+ var body = Submarine.PickBody(start, end, null, Physics.CollisionWall, allowInsideFixture: false);
+ if (body != null && body.UserData is Structure && !((Structure)body.UserData).IsPlatform)
+ {
+ connectedWp.isObstructed = true;
+ wp.isObstructed = true;
+ obstructedNodes.Add(node);
+ obstructedNodes.Add(connection);
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Only affects temporarily disabled waypoints.
+ ///
+ public void EnableObstructedWaypoints()
+ {
+ foreach (var node in obstructedNodes)
+ {
+ node.Waypoint.isObstructed = false;
+ }
+ obstructedNodes.Clear();
+ }
}
}
diff --git a/Barotrauma/BarotraumaShared/Source/Map/WayPoint.cs b/Barotrauma/BarotraumaShared/Source/Map/WayPoint.cs
index e2df8eafb..4e9cefbe3 100644
--- a/Barotrauma/BarotraumaShared/Source/Map/WayPoint.cs
+++ b/Barotrauma/BarotraumaShared/Source/Map/WayPoint.cs
@@ -32,6 +32,8 @@ namespace Barotrauma
public Ladder Ladders;
public Structure Stairs;
+ public bool isObstructed;
+
private ushort gapId;
public Gap ConnectedGap
{
diff --git a/Barotrauma/BarotraumaShared/Source/Networking/Client.cs b/Barotrauma/BarotraumaShared/Source/Networking/Client.cs
index f701bdf9a..501119553 100644
--- a/Barotrauma/BarotraumaShared/Source/Networking/Client.cs
+++ b/Barotrauma/BarotraumaShared/Source/Networking/Client.cs
@@ -7,6 +7,8 @@ namespace Barotrauma.Networking
{
partial class Client : IDisposable
{
+ public const int MaxNameLength = 20;
+
public string Name;
public byte ID;
@@ -205,6 +207,21 @@ namespace Barotrauma.Networking
SetPermissions(permissions, permittedCommands);
}
+ public static string SanitizeName(string name)
+ {
+ name = name.Trim();
+ if (name.Length > MaxNameLength)
+ {
+ name = name.Substring(0, MaxNameLength);
+ }
+ string rName = "";
+ for (int i = 0; i < name.Length; i++)
+ {
+ rName += name[i] < 32 ? '?' : name[i];
+ }
+ return rName;
+ }
+
public void Dispose()
{
DisposeProjSpecific();
diff --git a/Barotrauma/BarotraumaShared/Source/Networking/NetworkMember.cs b/Barotrauma/BarotraumaShared/Source/Networking/NetworkMember.cs
index e7e60021b..2730bacb3 100644
--- a/Barotrauma/BarotraumaShared/Source/Networking/NetworkMember.cs
+++ b/Barotrauma/BarotraumaShared/Source/Networking/NetworkMember.cs
@@ -174,8 +174,8 @@ namespace Barotrauma.Networking
get { return name; }
set
{
- if (string.IsNullOrEmpty(value)) return;
- name = value;
+ if (string.IsNullOrEmpty(value)) { return; }
+ name = value.Replace(":", "").Replace(";", "");
}
}
diff --git a/Barotrauma/BarotraumaShared/Source/Networking/RespawnManager.cs b/Barotrauma/BarotraumaShared/Source/Networking/RespawnManager.cs
index 0a2c470e5..98f6af3a2 100644
--- a/Barotrauma/BarotraumaShared/Source/Networking/RespawnManager.cs
+++ b/Barotrauma/BarotraumaShared/Source/Networking/RespawnManager.cs
@@ -158,41 +158,11 @@ namespace Barotrauma.Networking
shuttleTransportTimer -= deltaTime;
-#if CLIENT
- GameClient nClient = networkMember as GameClient;
- if (shuttleTransportTimer + deltaTime > 15.0f && shuttleTransportTimer <= 15.0f &&
- nClient.Character != null &&
- nClient.Character.Submarine == respawnShuttle)
- {
- nClient.AddChatMessage("ServerMessage.ShuttleLeaving", ChatMessageType.Server);
- }
-#endif
-
-#if SERVER
- var server = networkMember as GameServer;
- if (server == null) return;
-
- //if there are no living chracters inside, transporting can be stopped immediately
- if (!Character.CharacterList.Any(c => c.Submarine == respawnShuttle && !c.IsDead))
- {
- shuttleTransportTimer = 0.0f;
- }
-
- if (shuttleTransportTimer <= 0.0f)
- {
- GameServer.Log("The respawn shuttle is leaving.", ServerLog.MessageType.ServerMessage);
- state = State.Returning;
-
- server.CreateEntityEvent(this);
-
- CountdownStarted = false;
- maxTransportTime = server.ServerSettings.MaxTransportTime;
- shuttleReturnTimer = maxTransportTime;
- shuttleTransportTimer = maxTransportTime;
- }
-#endif
+ UpdateTransportingProjSpecific(deltaTime);
}
+ partial void UpdateTransportingProjSpecific(float deltaTime);
+
private void UpdateReturning(float deltaTime)
{
//if (shuttleReturnTimer == maxTransportTime &&
@@ -216,56 +186,13 @@ namespace Barotrauma.Networking
{
shuttleSteering.SetDestinationLevelStart();
}
-
-
-#if SERVER
- var server = networkMember as GameServer;
- if (server == null) return;
-
- foreach (Door door in shuttleDoors)
- {
- if (door.IsOpen) door.TrySetState(false, false, true);
- }
-
- var shuttleGaps = Gap.GapList.FindAll(g => g.Submarine == respawnShuttle && g.ConnectedWall != null);
- shuttleGaps.ForEach(g => Spawner.AddToRemoveQueue(g));
-
- var dockingPorts = Item.ItemList.FindAll(i => i.Submarine == respawnShuttle && i.GetComponent() != null);
- dockingPorts.ForEach(d => d.GetComponent().Undock());
-
- //shuttle has returned if the path has been traversed or the shuttle is close enough to the exit
-
- if (!CoroutineManager.IsCoroutineRunning("forcepos"))
- {
- if ((shuttleSteering?.SteeringPath != null && shuttleSteering.SteeringPath.Finished)
- || (respawnShuttle.WorldPosition.Y + respawnShuttle.Borders.Y > Level.Loaded.StartPosition.Y - Level.ShaftHeight &&
- Math.Abs(Level.Loaded.StartPosition.X - respawnShuttle.WorldPosition.X) < 1000.0f))
- {
- CoroutineManager.StopCoroutines("forcepos");
- CoroutineManager.StartCoroutine(
- ForceShuttleToPos(new Vector2(Level.Loaded.StartPosition.X, Level.Loaded.Size.Y + 1000.0f), 100.0f), "forcepos");
-
- }
- }
-
- if (respawnShuttle.WorldPosition.Y > Level.Loaded.Size.Y || shuttleReturnTimer <= 0.0f)
- {
- CoroutineManager.StopCoroutines("forcepos");
-
- ResetShuttle();
-
- state = State.Waiting;
- GameServer.Log("The respawn shuttle has left.", ServerLog.MessageType.Spawning);
- server.CreateEntityEvent(this);
-
- respawnTimer = server.ServerSettings.RespawnInterval;
- CountdownStarted = false;
- }
-#endif
+ UpdateReturningProjSpecific();
}
}
partial void DispatchShuttle();
+
+ partial void UpdateReturningProjSpecific();
private IEnumerable