(a410fd46c) Trying to help the merge script through a jungle of merges
This commit is contained in:
@@ -202,6 +202,8 @@
|
|||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Screens\SubEditorScreen.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Screens\SubEditorScreen.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Serialization\SerializableEntityEditor.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Serialization\SerializableEntityEditor.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Sounds\OggSound.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Sounds\OggSound.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Sounds\OpenAL\Al.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Sounds\OpenAL\Alc.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Sounds\Sound.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Sounds\Sound.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Sounds\SoundChannel.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Sounds\SoundChannel.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Sounds\SoundFilters.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Sounds\SoundFilters.cs" />
|
||||||
@@ -220,7 +222,6 @@
|
|||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Sprite\SpriteSheet.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Sprite\SpriteSheet.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\StatusEffects\StatusEffect.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\StatusEffects\StatusEffect.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Utils\LocalizationCSVtoXML.cs">
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Utils\LocalizationCSVtoXML.cs">
|
||||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Utils\MathUtils.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Utils\MathUtils.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Utils\OpenFileDialog.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Utils\OpenFileDialog.cs" />
|
||||||
|
|||||||
@@ -118,9 +118,6 @@
|
|||||||
<Content Include="MonoGame.Framework.dll.config">
|
<Content Include="MonoGame.Framework.dll.config">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="OpenTK.dll.config">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Shaders\solidcolor_opengl.fx" />
|
<Content Include="Shaders\solidcolor_opengl.fx" />
|
||||||
<Content Include="SharpFont.dll.config">
|
<Content Include="SharpFont.dll.config">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
@@ -350,7 +347,7 @@
|
|||||||
<Import Project="ClientCode.projitems" Label="Shared" />
|
<Import Project="ClientCode.projitems" Label="Shared" />
|
||||||
<Import Project="..\BarotraumaShared\SharedCode.projitems" Label="Shared" />
|
<Import Project="..\BarotraumaShared\SharedCode.projitems" Label="Shared" />
|
||||||
<Import Project="..\BarotraumaShared\SharedContent.projitems" Label="Shared" />
|
<Import Project="..\BarotraumaShared\SharedContent.projitems" Label="Shared" />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<Import Project="..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets" Condition="Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets')" />
|
<Import Project="..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets" Condition="Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets')" />
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
@@ -368,8 +365,9 @@
|
|||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
<!-- Write version number to a "Version.txt" file in the output folder -->
|
<!-- Write version number to a "Version.txt" file in the output folder -->
|
||||||
<GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
|
<GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
|
||||||
<Output TaskParameter="Assemblies" ItemName="CurrentAssembly" />
|
<Output TaskParameter="Assemblies" ItemName="CurrentAssembly" />
|
||||||
</GetAssemblyIdentity>
|
</GetAssemblyIdentity>
|
||||||
<Exec Command="echo v%(CurrentAssembly.Version) > $(TargetDir)Version.txt"></Exec>
|
<Exec Command="echo v%(CurrentAssembly.Version) > $(TargetDir)Version.txt">
|
||||||
|
</Exec>
|
||||||
</Target>
|
</Target>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -117,9 +117,6 @@
|
|||||||
<Content Include="MonoGame.Framework.dll.config">
|
<Content Include="MonoGame.Framework.dll.config">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="OpenTK.dll.config">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Shaders\solidcolor_opengl.fx" />
|
<Content Include="Shaders\solidcolor_opengl.fx" />
|
||||||
<Content Include="SharpFont.dll.config">
|
<Content Include="SharpFont.dll.config">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
|||||||
Binary file not shown.
@@ -1,25 +0,0 @@
|
|||||||
<configuration>
|
|
||||||
<dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/>
|
|
||||||
<dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/>
|
|
||||||
<dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/>
|
|
||||||
<dllmap os="linux" dll="alut.dll" target="libalut.so.0"/>
|
|
||||||
<dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
|
|
||||||
<dllmap os="linux" dll="libX11" target="libX11.so.6"/>
|
|
||||||
<dllmap os="linux" dll="libXi" target="libXi.so.6"/>
|
|
||||||
<!-- <dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/> -->
|
|
||||||
<dllmap os="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/>
|
|
||||||
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
|
|
||||||
<dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
|
|
||||||
<dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
|
|
||||||
<dllmap os="osx" dll="libGLESv1_CM.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
|
|
||||||
<dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
|
|
||||||
<dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/>
|
|
||||||
<dllmap os="osx" dll="SDL2.dll" target="libSDL2.dylib"/>
|
|
||||||
<!-- XQuartz compatibility (X11 on Mac) -->
|
|
||||||
<dllmap os="osx" dll="libGL.so.1" target="/usr/X11/lib/libGL.dylib"/>
|
|
||||||
<dllmap os="osx" dll="libX11" target="/usr/X11/lib/libX11.dylib"/>
|
|
||||||
<dllmap os="osx" dll="libXcursor.so.1" target="/usr/X11/lib/libXcursor.dylib"/>
|
|
||||||
<dllmap os="osx" dll="libXi" target="/usr/X11/lib/libXi.dylib"/>
|
|
||||||
<dllmap os="osx" dll="libXinerama" target="/usr/X11/lib/libXinerama.dylib"/>
|
|
||||||
<dllmap os="osx" dll="libXrandr.so.2" target="/usr/X11/lib/libXrandr.dylib"/>
|
|
||||||
</configuration>
|
|
||||||
@@ -39,10 +39,14 @@ namespace Barotrauma
|
|||||||
else if (Entity is Item)
|
else if (Entity is Item)
|
||||||
{
|
{
|
||||||
color = Color.CadetBlue;
|
color = Color.CadetBlue;
|
||||||
|
// disable the indicators for items, because they clutter the debug view
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
color = Color.WhiteSmoke;
|
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, SightRange, 100, color, thickness: 1 / Screen.Selected.Cam.Zoom);
|
||||||
ShapeExtensions.DrawCircle(spriteBatch, pos, 6, 8, color, thickness: 2 / Screen.Selected.Cam.Zoom);
|
ShapeExtensions.DrawCircle(spriteBatch, pos, 6, 8, color, thickness: 2 / Screen.Selected.Cam.Zoom);
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
//hull subs don't match => teleport the camera to the other sub
|
//hull subs don't match => teleport the camera to the other sub
|
||||||
character.Submarine = serverHull.Submarine;
|
character.Submarine = serverHull.Submarine;
|
||||||
character.CurrentHull = currentHull = serverHull;
|
character.CurrentHull = CurrentHull = serverHull;
|
||||||
SetPosition(serverPos.Position);
|
SetPosition(serverPos.Position);
|
||||||
character.MemLocalState.Clear();
|
character.MemLocalState.Clear();
|
||||||
}
|
}
|
||||||
@@ -369,11 +369,11 @@ namespace Barotrauma
|
|||||||
LimbJoints.ForEach(j => j.UpdateDeformations(deltaTime));
|
LimbJoints.ForEach(j => j.UpdateDeformations(deltaTime));
|
||||||
foreach (var deformation in SpriteDeformations)
|
foreach (var deformation in SpriteDeformations)
|
||||||
{
|
{
|
||||||
|
if (character.IsDead && deformation.DeformationParams.StopWhenHostIsDead) { continue; }
|
||||||
if (deformation.DeformationParams.UseMovementSine)
|
if (deformation.DeformationParams.UseMovementSine)
|
||||||
{
|
{
|
||||||
if (this is AnimController animator)
|
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);
|
deformation.Phase = MathUtils.WrapAngleTwoPi(animator.WalkPos * deformation.DeformationParams.Frequency + MathHelper.Pi * deformation.DeformationParams.SineOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -538,13 +538,10 @@ namespace Barotrauma
|
|||||||
if (wearable.InheritLimbDepth)
|
if (wearable.InheritLimbDepth)
|
||||||
{
|
{
|
||||||
depth = ActiveSprite.Depth - depthStep;
|
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);
|
depth = depthLimb.ActiveSprite.Depth - depthStep;
|
||||||
if (depthLimb != null)
|
|
||||||
{
|
|
||||||
depth = depthLimb.ActiveSprite.Depth - depthStep;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var wearableItemComponent = wearable.WearableComponent;
|
var wearableItemComponent = wearable.WearableComponent;
|
||||||
|
|||||||
@@ -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) },
|
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));
|
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);
|
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
|
IsFixedSize = false
|
||||||
}, color: Color.Black * 0.9f);
|
}, color: Color.Black * 0.9f);
|
||||||
@@ -80,9 +92,6 @@ namespace Barotrauma
|
|||||||
ResetAutoComplete();
|
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()
|
public static void AddToGUIUpdateList()
|
||||||
@@ -130,6 +139,12 @@ namespace Barotrauma
|
|||||||
textBox.Deselect();
|
textBox.Deselect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (isOpen && PlayerInput.KeyHit(Keys.Escape))
|
||||||
|
{
|
||||||
|
isOpen = false;
|
||||||
|
GUI.ForceMouseOn(null);
|
||||||
|
textBox.Deselect();
|
||||||
|
}
|
||||||
|
|
||||||
if (isOpen)
|
if (isOpen)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -230,11 +230,18 @@ namespace Barotrauma
|
|||||||
if (GameMain.ShowPerf)
|
if (GameMain.ShowPerf)
|
||||||
{
|
{
|
||||||
int y = 10;
|
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;
|
y += 15;
|
||||||
GameMain.PerformanceCounter.DrawTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), null, 0, Color.Green);
|
GameMain.PerformanceCounter.DrawTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), null, 0, Color.Green);
|
||||||
y += 50;
|
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;
|
y += 15;
|
||||||
GameMain.PerformanceCounter.UpdateTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), null, 0, Color.LightBlue);
|
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);
|
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);
|
float elapsedMillisecs = GameMain.PerformanceCounter.GetAverageElapsedMillisecs(key);
|
||||||
DrawString(spriteBatch, new Vector2(300, y),
|
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);
|
Color.Lerp(Color.LightGreen, Color.Red, elapsedMillisecs / 10.0f), Color.Black * 0.5f, 0, SmallFont);
|
||||||
|
|
||||||
y += 15;
|
y += 15;
|
||||||
|
|||||||
@@ -85,7 +85,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
float totalSize = RectTransform.Children
|
float totalSize = RectTransform.Children
|
||||||
.Where(c => !c.GUIComponent.IgnoreLayoutGroups)
|
.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 +=
|
totalSize +=
|
||||||
(RectTransform.Children.Count() - 1) *
|
(RectTransform.Children.Count() - 1) *
|
||||||
|
|||||||
@@ -117,7 +117,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
LayoutGroup = new GUILayoutGroup(new RectTransform(Vector2.One, rectT), isHorizontal: true) { Stretch = true };
|
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,
|
ClampText = false,
|
||||||
// For some reason the caret in the number inputs is dimmer than it should.
|
// For some reason the caret in the number inputs is dimmer than it should.
|
||||||
@@ -126,7 +128,7 @@ namespace Barotrauma
|
|||||||
CaretColor = Color.White
|
CaretColor = Color.White
|
||||||
};
|
};
|
||||||
TextBox.OnTextChanged += TextChanged;
|
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 = new GUIButton(new RectTransform(new Vector2(1.0f, 0.5f), buttonArea.RectTransform), "+");
|
||||||
PlusButton.OnButtonDown += () =>
|
PlusButton.OnButtonDown += () =>
|
||||||
{
|
{
|
||||||
@@ -201,6 +203,8 @@ namespace Barotrauma
|
|||||||
TextBox.textFilterFunction = text => new string(text.Where(c => char.IsDigit(c) || c == '.' || c == '-').ToArray());
|
TextBox.textFilterFunction = text => new string(text.Where(c => char.IsDigit(c) || c == '.' || c == '-').ToArray());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LayoutGroup.Recalculate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReduceValue()
|
private void ReduceValue()
|
||||||
|
|||||||
@@ -35,8 +35,6 @@ namespace Barotrauma
|
|||||||
this.graphicsDevice = graphicsDevice;
|
this.graphicsDevice = graphicsDevice;
|
||||||
componentStyles = new Dictionary<string, GUIComponentStyle>();
|
componentStyles = new Dictionary<string, GUIComponentStyle>();
|
||||||
|
|
||||||
GameMain.Instance.OnResolutionChanged += () => { RescaleFonts(); };
|
|
||||||
|
|
||||||
XDocument doc;
|
XDocument doc;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -89,6 +87,8 @@ namespace Barotrauma
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GameMain.Instance.OnResolutionChanged += () => { RescaleFonts(); };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ namespace Barotrauma
|
|||||||
protected Color textColor;
|
protected Color textColor;
|
||||||
|
|
||||||
private string wrappedText;
|
private string wrappedText;
|
||||||
|
private string censoredText;
|
||||||
|
|
||||||
public delegate string TextGetterHandler();
|
public delegate string TextGetterHandler();
|
||||||
public TextGetterHandler TextGetter;
|
public TextGetterHandler TextGetter;
|
||||||
@@ -175,6 +176,17 @@ namespace Barotrauma
|
|||||||
SetTextPos();
|
SetTextPos();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool Censor
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CensoredText
|
||||||
|
{
|
||||||
|
get { return censoredText; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is the new constructor.
|
/// This is the new constructor.
|
||||||
@@ -204,6 +216,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
RectTransform.ScaleChanged += SetTextPos;
|
RectTransform.ScaleChanged += SetTextPos;
|
||||||
RectTransform.SizeChanged += SetTextPos;
|
RectTransform.SizeChanged += SetTextPos;
|
||||||
|
|
||||||
|
Censor = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CalculateHeightFromText()
|
public void CalculateHeightFromText()
|
||||||
@@ -225,13 +239,19 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (text == null) return;
|
if (text == null) return;
|
||||||
|
|
||||||
|
censoredText = "";
|
||||||
|
for (int i=0;i<text.Length;i++)
|
||||||
|
{
|
||||||
|
censoredText += "\u2022";
|
||||||
|
}
|
||||||
|
|
||||||
var rect = Rect;
|
var rect = Rect;
|
||||||
|
|
||||||
overflowClipActive = false;
|
overflowClipActive = false;
|
||||||
wrappedText = text;
|
wrappedText = text;
|
||||||
|
|
||||||
TextSize = MeasureText(text);
|
TextSize = MeasureText(text);
|
||||||
|
|
||||||
if (Wrap && rect.Width > 0)
|
if (Wrap && rect.Width > 0)
|
||||||
{
|
{
|
||||||
wrappedText = ToolBox.WrapText(text, rect.Width - padding.X - padding.Z, Font, textScale);
|
wrappedText = ToolBox.WrapText(text, rect.Width - padding.X - padding.Z, Font, textScale);
|
||||||
@@ -338,7 +358,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
Font.DrawString(spriteBatch,
|
Font.DrawString(spriteBatch,
|
||||||
Wrap ? wrappedText : text,
|
Censor ? censoredText : (Wrap ? wrappedText : text),
|
||||||
pos,
|
pos,
|
||||||
textColor * (textColor.A / 255.0f),
|
textColor * (textColor.A / 255.0f),
|
||||||
0.0f, origin, TextScale,
|
0.0f, origin, TextScale,
|
||||||
|
|||||||
@@ -142,6 +142,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool Censor
|
||||||
|
{
|
||||||
|
get { return textBlock.Censor; }
|
||||||
|
set { textBlock.Censor = value; }
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToolTip
|
public override string ToolTip
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -253,9 +259,12 @@ namespace Barotrauma
|
|||||||
textBlock.Text = textBlock.Text.Substring(0, (int)maxTextLength);
|
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)
|
if (store)
|
||||||
@@ -267,9 +276,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void CalculateCaretPos()
|
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;
|
int totalIndex = 0;
|
||||||
for (int i = 0; i < lines.Length; i++)
|
for (int i = 0; i < lines.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -282,7 +292,7 @@ namespace Barotrauma
|
|||||||
int index = currentLineLength - diff;
|
int index = currentLineLength - diff;
|
||||||
Vector2 lineTextSize = Font.MeasureString(lines[i].Substring(0, index));
|
Vector2 lineTextSize = Font.MeasureString(lines[i].Substring(0, index));
|
||||||
Vector2 lastLineSize = Font.MeasureString(lines[i]);
|
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;
|
caretPos = new Vector2(lineTextSize.X, totalTextHeight - lastLineSize.Y) + textBlock.TextPos - textBlock.Origin;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -290,7 +300,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
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;
|
caretPos = new Vector2(textSize.X, 0) + textBlock.TextPos - textBlock.Origin;
|
||||||
}
|
}
|
||||||
caretPosDirty = false;
|
caretPosDirty = false;
|
||||||
@@ -298,17 +309,18 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected List<Tuple<Vector2, int>> GetAllPositions()
|
protected List<Tuple<Vector2, int>> GetAllPositions()
|
||||||
{
|
{
|
||||||
|
string textDrawn = Censor ? textBlock.CensoredText : textBlock.WrappedText;
|
||||||
var positions = new List<Tuple<Vector2, int>>();
|
var positions = new List<Tuple<Vector2, int>>();
|
||||||
if (textBlock.WrappedText.Contains("\n"))
|
if (textDrawn.Contains("\n"))
|
||||||
{
|
{
|
||||||
string[] lines = textBlock.WrappedText.Split('\n');
|
string[] lines = textDrawn.Split('\n');
|
||||||
int index = 0;
|
int index = 0;
|
||||||
int totalIndex = 0;
|
int totalIndex = 0;
|
||||||
for (int i = 0; i < lines.Length; i++)
|
for (int i = 0; i < lines.Length; i++)
|
||||||
{
|
{
|
||||||
string line = lines[i];
|
string line = lines[i];
|
||||||
totalIndex += line.Length;
|
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++)
|
for (int j = 0; j <= line.Length; j++)
|
||||||
{
|
{
|
||||||
Vector2 lineTextSize = Font.MeasureString(line.Substring(0, j));
|
Vector2 lineTextSize = Font.MeasureString(line.Substring(0, j));
|
||||||
@@ -321,9 +333,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
textDrawn = Censor ? textBlock.CensoredText : textBlock.Text;
|
||||||
for (int i = 0; i <= textBlock.Text.Length; i++)
|
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;
|
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);
|
//DebugConsole.NewMessage($"index: {i}, pos: {indexPos}", Color.WhiteSmoke);
|
||||||
positions.Add(new Tuple<Vector2, int>(textBlock.Rect.Location.ToVector2() + indexPos, i));
|
positions.Add(new Tuple<Vector2, int>(textBlock.Rect.Location.ToVector2() + indexPos, i));
|
||||||
@@ -822,6 +835,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void CalculateSelection()
|
private void CalculateSelection()
|
||||||
{
|
{
|
||||||
|
string textDrawn = Censor ? textBlock.CensoredText : textBlock.WrappedText;
|
||||||
InitSelectionStart();
|
InitSelectionStart();
|
||||||
selectionEndIndex = CaretIndex;
|
selectionEndIndex = CaretIndex;
|
||||||
selectionEndPos = caretPos;
|
selectionEndPos = caretPos;
|
||||||
@@ -829,12 +843,12 @@ namespace Barotrauma
|
|||||||
if (IsLeftToRight)
|
if (IsLeftToRight)
|
||||||
{
|
{
|
||||||
selectedText = Text.Substring(selectionStartIndex, selectedCharacters);
|
selectedText = Text.Substring(selectionStartIndex, selectedCharacters);
|
||||||
selectionRectSize = Font.MeasureString(textBlock.WrappedText.Substring(selectionStartIndex, selectedCharacters));
|
selectionRectSize = Font.MeasureString(textDrawn.Substring(selectionStartIndex, selectedCharacters));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
selectedText = Text.Substring(selectionEndIndex, selectedCharacters);
|
selectedText = Text.Substring(selectionEndIndex, selectedCharacters);
|
||||||
selectionRectSize = Font.MeasureString(textBlock.WrappedText.Substring(selectionEndIndex, selectedCharacters));
|
selectionRectSize = Font.MeasureString(textDrawn.Substring(selectionEndIndex, selectedCharacters));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ namespace Barotrauma
|
|||||||
BottomLeft, BottomCenter, BottomRight
|
BottomLeft, BottomCenter, BottomRight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum ScaleBasis
|
||||||
|
{
|
||||||
|
Normal, BothWidth, BothHeight
|
||||||
|
}
|
||||||
|
|
||||||
public class RectTransform
|
public class RectTransform
|
||||||
{
|
{
|
||||||
#region Fields and Properties
|
#region Fields and Properties
|
||||||
@@ -286,6 +291,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ScaleBasis scaleBasis;
|
||||||
|
|
||||||
public bool IsLastChild
|
public bool IsLastChild
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -320,9 +327,10 @@ namespace Barotrauma
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Initialization
|
#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);
|
Init(parent, anchor, pivot);
|
||||||
|
this.scaleBasis = scaleBasis;
|
||||||
this.relativeSize = relativeSize;
|
this.relativeSize = relativeSize;
|
||||||
this.minSize = minSize;
|
this.minSize = minSize;
|
||||||
this.maxSize = maxSize;
|
this.maxSize = maxSize;
|
||||||
@@ -340,6 +348,7 @@ namespace Barotrauma
|
|||||||
public RectTransform(Point absoluteSize, RectTransform parent = null, Anchor anchor = Anchor.TopLeft, Pivot? pivot = null)
|
public RectTransform(Point absoluteSize, RectTransform parent = null, Anchor anchor = Anchor.TopLeft, Pivot? pivot = null)
|
||||||
{
|
{
|
||||||
Init(parent, anchor, pivot);
|
Init(parent, anchor, pivot);
|
||||||
|
this.scaleBasis = ScaleBasis.Normal;
|
||||||
this.nonScaledSize = absoluteSize;
|
this.nonScaledSize = absoluteSize;
|
||||||
RecalculateScale();
|
RecalculateScale();
|
||||||
RecalculateRelativeSize();
|
RecalculateRelativeSize();
|
||||||
@@ -416,7 +425,16 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected void RecalculateAbsoluteSize()
|
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;
|
recalculateRect = true;
|
||||||
SizeChanged?.Invoke();
|
SizeChanged?.Invoke();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,14 +159,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public GameMain()
|
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";
|
Content.RootDirectory = "Content";
|
||||||
/*#endif*/
|
|
||||||
|
|
||||||
GraphicsDeviceManager = new GraphicsDeviceManager(this);
|
GraphicsDeviceManager = new GraphicsDeviceManager(this);
|
||||||
|
|
||||||
@@ -280,7 +273,7 @@ namespace Barotrauma
|
|||||||
canLoadInSeparateThread = true;
|
canLoadInSeparateThread = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
loadingCoroutine = CoroutineManager.StartCoroutine(Load(canLoadInSeparateThread), "", canLoadInSeparateThread);
|
loadingCoroutine = CoroutineManager.StartCoroutine(Load(canLoadInSeparateThread), "Load", canLoadInSeparateThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitUserStats()
|
private void InitUserStats()
|
||||||
@@ -541,7 +534,9 @@ namespace Barotrauma
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected override void UnloadContent()
|
protected override void UnloadContent()
|
||||||
{
|
{
|
||||||
|
CoroutineManager.StopCoroutines("Load");
|
||||||
Video.Close();
|
Video.Close();
|
||||||
|
VoipCapture.Instance?.Dispose();
|
||||||
SoundManager?.Dispose();
|
SoundManager?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,11 @@ namespace Barotrauma
|
|||||||
Character character = characterInfo.Character;
|
Character character = characterInfo.Character;
|
||||||
if (character == null || character.IsDead)
|
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).";
|
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);
|
DebugConsole.ThrowError(errorMsg);
|
||||||
@@ -126,7 +130,7 @@ namespace Barotrauma
|
|||||||
statusText = characterInfo.CauseOfDeath.Type == CauseOfDeathType.Affliction ?
|
statusText = characterInfo.CauseOfDeath.Type == CauseOfDeathType.Affliction ?
|
||||||
characterInfo.CauseOfDeath.Affliction.CauseOfDeathDescription :
|
characterInfo.CauseOfDeath.Affliction.CauseOfDeathDescription :
|
||||||
TextManager.Get("CauseOfDeathDescription." + characterInfo.CauseOfDeath.Type.ToString());
|
TextManager.Get("CauseOfDeathDescription." + characterInfo.CauseOfDeath.Type.ToString());
|
||||||
}
|
}
|
||||||
statusColor = Color.DarkRed;
|
statusColor = Color.DarkRed;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using Barotrauma.Networking;
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using Microsoft.Xna.Framework.Input;
|
using Microsoft.Xna.Framework.Input;
|
||||||
using OpenTK.Audio.OpenAL;
|
using OpenAL;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -75,6 +75,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
settingsFrame = new GUIFrame(new RectTransform(new Vector2(0.8f, 0.8f), GUI.Canvas, Anchor.Center));
|
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 };
|
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 --------------------------------------------------------------
|
/// General tab --------------------------------------------------------------
|
||||||
@@ -96,7 +98,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
foreach (ContentPackage contentPackage in ContentPackage.List)
|
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,
|
UserData = contentPackage,
|
||||||
OnSelected = SelectContentPackage,
|
OnSelected = SelectContentPackage,
|
||||||
@@ -132,7 +134,7 @@ namespace Barotrauma
|
|||||||
if (newLanguage == Language) return true;
|
if (newLanguage == Language) return true;
|
||||||
|
|
||||||
Language = newLanguage;
|
Language = newLanguage;
|
||||||
ApplySettings();
|
UnsavedSettings = true;
|
||||||
|
|
||||||
var msgBox = new GUIMessageBox(TextManager.Get("RestartRequiredLabel"), TextManager.Get("RestartRequiredLanguage"));
|
var msgBox = new GUIMessageBox(TextManager.Get("RestartRequiredLabel"), TextManager.Get("RestartRequiredLanguage"));
|
||||||
//change fonts to the default font of the new language to make sure
|
//change fonts to the default font of the new language to make sure
|
||||||
@@ -250,7 +252,7 @@ namespace Barotrauma
|
|||||||
return true;
|
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"),
|
ToolTip = TextManager.Get("EnableVSyncToolTip"),
|
||||||
OnSelected = (GUITickBox box) =>
|
OnSelected = (GUITickBox box) =>
|
||||||
@@ -266,7 +268,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
//TODO: remove hardcoded texts after the texts have been added to localization
|
//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");
|
TextManager.Get("PauseOnFocusLost", returnNull: true) ?? "Pause on focus lost");
|
||||||
pauseOnFocusLostBox.Selected = PauseOnFocusLost;
|
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.";
|
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);
|
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"),
|
ToolTip = TextManager.Get("SpecularLightingToolTip"),
|
||||||
Selected = SpecularityEnabled,
|
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"),
|
ToolTip = TextManager.Get("ChromaticAberrationToolTip"),
|
||||||
Selected = ChromaticAberrationEnabled,
|
Selected = ChromaticAberrationEnabled,
|
||||||
@@ -443,7 +445,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
voiceChatScrollBar.OnMoved(voiceChatScrollBar, voiceChatScrollBar.BarScroll);
|
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.Selected = MuteOnFocusLost;
|
||||||
muteOnFocusLostBox.ToolTip = TextManager.Get("MuteOnFocusLostToolTip");
|
muteOnFocusLostBox.ToolTip = TextManager.Get("MuteOnFocusLostToolTip");
|
||||||
muteOnFocusLostBox.OnSelected = (tickBox) =>
|
muteOnFocusLostBox.OnSelected = (tickBox) =>
|
||||||
@@ -455,13 +457,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), audioSliders.RectTransform), TextManager.Get("VoiceChat"));
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), audioSliders.RectTransform), TextManager.Get("VoiceChat"));
|
||||||
|
|
||||||
IList<string> deviceNames = Alc.GetString((IntPtr)null, AlcGetStringList.CaptureDeviceSpecifier);
|
IList<string> deviceNames = Alc.GetStringList((IntPtr)null, Alc.CaptureDeviceSpecifier);
|
||||||
foreach (string name in deviceNames)
|
foreach (string name in deviceNames)
|
||||||
{
|
{
|
||||||
DebugConsole.NewMessage(name + " " + name.Length.ToString(), Color.Lime);
|
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.Selected = UseDirectionalVoiceChat;
|
||||||
directionalVoiceChat.ToolTip = TextManager.Get("DirectionalVoiceChatToolTip");
|
directionalVoiceChat.ToolTip = TextManager.Get("DirectionalVoiceChatToolTip");
|
||||||
directionalVoiceChat.OnSelected = (tickBox) =>
|
directionalVoiceChat.OnSelected = (tickBox) =>
|
||||||
@@ -470,14 +472,13 @@ namespace Barotrauma
|
|||||||
UnsavedSettings = true;
|
UnsavedSettings = true;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(VoiceCaptureDevice)) VoiceCaptureDevice = deviceNames[0];
|
if (string.IsNullOrWhiteSpace(VoiceCaptureDevice)) VoiceCaptureDevice = deviceNames[0];
|
||||||
#if (!OSX)
|
#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)
|
foreach (string name in deviceNames)
|
||||||
{
|
{
|
||||||
deviceList.AddItem(TextManager.EnsureUTF8(name), name);
|
deviceList.AddItem(TrimAudioDeviceName(name), name);
|
||||||
}
|
}
|
||||||
deviceList.OnSelected = (GUIComponent selected, object obj) =>
|
deviceList.OnSelected = (GUIComponent selected, object obj) =>
|
||||||
{
|
{
|
||||||
@@ -488,28 +489,32 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
#else
|
#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)))
|
TextManager.AddPunctuation(':', TextManager.Get("CurrentDevice"), TextManager.EnsureUTF8(VoiceCaptureDevice)))
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("CurrentDeviceToolTip.OSX"),
|
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"),
|
ToolTip = TextManager.Get("RefreshDefaultDeviceToolTip"),
|
||||||
OnClicked = (bt, userdata) =>
|
OnClicked = (bt, userdata) =>
|
||||||
{
|
{
|
||||||
deviceNames = Alc.GetString((IntPtr)null, AlcGetStringList.CaptureDeviceSpecifier);
|
deviceNames = Alc.GetStringList((IntPtr)null, Alc.CaptureDeviceSpecifier);
|
||||||
if (VoiceCaptureDevice == deviceNames[0]) return true;
|
if (VoiceCaptureDevice == deviceNames[0]) return true;
|
||||||
|
|
||||||
VoipCapture.ChangeCaptureDevice(deviceNames[0]);
|
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);
|
suavemente.Flash(Color.Blue);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
suavemente.RectTransform.Parent = defaultDeviceGroup.RectTransform;
|
||||||
#endif
|
#endif
|
||||||
//var radioButtonFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.12f), audioSliders.RectTransform));
|
//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++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
string langStr = "VoiceMode." + ((VoiceMode)i).ToString();
|
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")
|
ToolTip = TextManager.Get(langStr + "ToolTip")
|
||||||
};
|
};
|
||||||
@@ -651,7 +656,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
aimAssistSlider.OnMoved(aimAssistSlider, aimAssistSlider.BarScroll);
|
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"),
|
ToolTip = TextManager.Get("EnableMouseLookToolTip"),
|
||||||
Selected = EnableMouseLook,
|
Selected = EnableMouseLook,
|
||||||
@@ -776,6 +781,19 @@ namespace Barotrauma
|
|||||||
SelectTab(selectedTab);
|
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 Tab currentTab;
|
||||||
private void SelectTab(Tab tab)
|
private void SelectTab(Tab tab)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -423,7 +423,14 @@ namespace Barotrauma
|
|||||||
columns++;
|
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;
|
subRect.X = startX;
|
||||||
int startY = dir < 0 ?
|
int startY = dir < 0 ?
|
||||||
slot.EquipButtonRect.Y - subRect.Height - (int)(35 * UIScale) :
|
slot.EquipButtonRect.Y - subRect.Height - (int)(35 * UIScale) :
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ namespace Barotrauma
|
|||||||
drawPos.Y = -drawPos.Y;
|
drawPos.Y = -drawPos.Y;
|
||||||
|
|
||||||
Color clr = currentHull == null ? Color.Blue : Color.White;
|
Color clr = currentHull == null ? Color.Blue : Color.White;
|
||||||
|
if (isObstructed)
|
||||||
|
{
|
||||||
|
clr = Color.Black;
|
||||||
|
}
|
||||||
if (IsSelected) clr = Color.Red;
|
if (IsSelected) clr = Color.Red;
|
||||||
if (IsHighlighted) clr = Color.DarkRed;
|
if (IsHighlighted) clr = Color.DarkRed;
|
||||||
|
|
||||||
@@ -50,7 +54,7 @@ namespace Barotrauma
|
|||||||
GUI.DrawLine(spriteBatch,
|
GUI.DrawLine(spriteBatch,
|
||||||
drawPos,
|
drawPos,
|
||||||
new Vector2(e.DrawPosition.X, -e.DrawPosition.Y),
|
new Vector2(e.DrawPosition.X, -e.DrawPosition.Y),
|
||||||
Color.Green, width: 5);
|
isObstructed ? Color.Gray : Color.Green, width: 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI.SmallFont.DrawString(spriteBatch,
|
GUI.SmallFont.DrawString(spriteBatch,
|
||||||
|
|||||||
@@ -194,8 +194,7 @@ namespace Barotrauma.Networking
|
|||||||
Hull.EditFire = false;
|
Hull.EditFire = false;
|
||||||
Hull.EditWater = false;
|
Hull.EditWater = false;
|
||||||
|
|
||||||
newName = newName.Replace(":", "").Replace(";", "");
|
Name = newName;
|
||||||
name = newName;
|
|
||||||
|
|
||||||
entityEventManager = new ClientEntityEventManager(this);
|
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) })
|
var passwordBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 0.1f), msgBox.InnerFrame.RectTransform, Anchor.Center) { MinSize = new Point(0, 20) })
|
||||||
{
|
{
|
||||||
IgnoreLayoutGroups = true,
|
IgnoreLayoutGroups = true,
|
||||||
UserData = "password"
|
UserData = "password",
|
||||||
|
Censor = true
|
||||||
};
|
};
|
||||||
|
|
||||||
var okButton = msgBox.Buttons[0];
|
var okButton = msgBox.Buttons[0];
|
||||||
@@ -1303,6 +1303,11 @@ namespace Barotrauma.Networking
|
|||||||
if (existingClient.ID == myID)
|
if (existingClient.ID == myID)
|
||||||
{
|
{
|
||||||
existingClient.SetPermissions(permissions, permittedConsoleCommands);
|
existingClient.SetPermissions(permissions, permittedConsoleCommands);
|
||||||
|
name = tc.Name;
|
||||||
|
if (GameMain.NetLobbyScreen.CharacterNameBox != null)
|
||||||
|
{
|
||||||
|
GameMain.NetLobbyScreen.CharacterNameBox.Text = name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
currentClients.Add(existingClient);
|
currentClients.Add(existingClient);
|
||||||
}
|
}
|
||||||
@@ -1562,6 +1567,7 @@ namespace Barotrauma.Networking
|
|||||||
outmsg.Write(GameMain.NetLobbyScreen.LastUpdateID);
|
outmsg.Write(GameMain.NetLobbyScreen.LastUpdateID);
|
||||||
outmsg.Write(ChatMessage.LastID);
|
outmsg.Write(ChatMessage.LastID);
|
||||||
outmsg.Write(LastClientListUpdateID);
|
outmsg.Write(LastClientListUpdateID);
|
||||||
|
outmsg.Write(name);
|
||||||
|
|
||||||
var campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
|
var campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
|
||||||
if (campaign == null || campaign.LastSaveID == 0)
|
if (campaign == null || campaign.LastSaveID == 0)
|
||||||
@@ -1581,8 +1587,8 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
if (outmsg.LengthBytes + chatMsgQueue[i].EstimateLengthBytesClient() > client.Configuration.MaximumTransmissionUnit - 5)
|
if (outmsg.LengthBytes + chatMsgQueue[i].EstimateLengthBytesClient() > client.Configuration.MaximumTransmissionUnit - 5)
|
||||||
{
|
{
|
||||||
//not enough room in this packet
|
//no more room in this packet
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
chatMsgQueue[i].ClientWrite(outmsg);
|
chatMsgQueue[i].ClientWrite(outmsg);
|
||||||
}
|
}
|
||||||
@@ -1617,7 +1623,7 @@ namespace Barotrauma.Networking
|
|||||||
if (outmsg.LengthBytes + chatMsgQueue[i].EstimateLengthBytesClient() > client.Configuration.MaximumTransmissionUnit - 5)
|
if (outmsg.LengthBytes + chatMsgQueue[i].EstimateLengthBytesClient() > client.Configuration.MaximumTransmissionUnit - 5)
|
||||||
{
|
{
|
||||||
//not enough room in this packet
|
//not enough room in this packet
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
chatMsgQueue[i].ClientWrite(outmsg);
|
chatMsgQueue[i].ClientWrite(outmsg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,5 +11,15 @@ namespace Barotrauma.Networking
|
|||||||
respawnTimer = Math.Max(0.0f, respawnTimer - deltaTime);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,15 +71,16 @@ namespace Barotrauma.Networking
|
|||||||
Stretch = true
|
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,
|
IsHorizontal = true,
|
||||||
Stretch = 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),
|
TextManager.AddPunctuation(':', TextManager.Get("ServerListVersion"), string.IsNullOrEmpty(GameVersion) ? TextManager.Get("Unknown") : GameVersion),
|
||||||
textAlignment: Alignment.Right);
|
textAlignment: Alignment.Right);
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,15 @@ namespace Barotrauma.Steam
|
|||||||
return instance.client.SteamId;
|
return instance.client.SteamId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetUsername()
|
||||||
|
{
|
||||||
|
if (instance == null || !instance.isInitialized)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return instance.client.Username;
|
||||||
|
}
|
||||||
|
|
||||||
public static ulong GetWorkshopItemIDFromUrl(string url)
|
public static ulong GetWorkshopItemIDFromUrl(string url)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Lidgren.Network;
|
using Lidgren.Network;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using OpenTK.Audio.OpenAL;
|
using OpenAL;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
@@ -69,7 +69,7 @@ namespace Barotrauma.Networking
|
|||||||
VoipConfig.SetupEncoding();
|
VoipConfig.SetupEncoding();
|
||||||
|
|
||||||
//set up capture device
|
//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)
|
if (captureDevice == IntPtr.Zero)
|
||||||
{
|
{
|
||||||
@@ -88,20 +88,20 @@ namespace Barotrauma.Networking
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
AlcError alcError = Alc.GetError(captureDevice);
|
int alcError = Alc.GetError(captureDevice);
|
||||||
if (alcError != AlcError.NoError)
|
if (alcError != Alc.NoError)
|
||||||
{
|
{
|
||||||
throw new Exception("Failed to open capture device: " + alcError.ToString() + " (ALC)");
|
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)");
|
throw new Exception("Failed to open capture device: " + alError.ToString() + " (AL)");
|
||||||
}
|
}
|
||||||
|
|
||||||
Alc.CaptureStart(captureDevice);
|
Alc.CaptureStart(captureDevice);
|
||||||
alcError = Alc.GetError(captureDevice);
|
alcError = Alc.GetError(captureDevice);
|
||||||
if (alcError != AlcError.NoError)
|
if (alcError != Alc.NoError)
|
||||||
{
|
{
|
||||||
throw new Exception("Failed to start capturing: " + alcError.ToString());
|
throw new Exception("Failed to start capturing: " + alcError.ToString());
|
||||||
}
|
}
|
||||||
@@ -132,11 +132,11 @@ namespace Barotrauma.Networking
|
|||||||
short[] uncompressedBuffer = new short[VoipConfig.BUFFER_SIZE];
|
short[] uncompressedBuffer = new short[VoipConfig.BUFFER_SIZE];
|
||||||
while (capturing)
|
while (capturing)
|
||||||
{
|
{
|
||||||
AlcError alcError;
|
int alcError;
|
||||||
Alc.GetInteger(captureDevice, AlcGetInteger.CaptureSamples, 1, out int sampleCount);
|
Alc.GetInteger(captureDevice, Alc.EnumCaptureSamples, out int sampleCount);
|
||||||
|
|
||||||
alcError = Alc.GetError(captureDevice);
|
alcError = Alc.GetError(captureDevice);
|
||||||
if (alcError != AlcError.NoError)
|
if (alcError != Alc.NoError)
|
||||||
{
|
{
|
||||||
throw new Exception("Failed to determine sample count: " + alcError.ToString());
|
throw new Exception("Failed to determine sample count: " + alcError.ToString());
|
||||||
}
|
}
|
||||||
@@ -160,7 +160,7 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
|
|
||||||
alcError = Alc.GetError(captureDevice);
|
alcError = Alc.GetError(captureDevice);
|
||||||
if (alcError != AlcError.NoError)
|
if (alcError != Alc.NoError)
|
||||||
{
|
{
|
||||||
throw new Exception("Failed to capture samples: " + alcError.ToString());
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -335,12 +335,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
subName = doc.Root.GetAttributeString("submarine", "");
|
subName = doc.Root.GetAttributeString("submarine", "");
|
||||||
saveTime = doc.Root.GetAttributeString("savetime", "");
|
saveTime = doc.Root.GetAttributeString("savetime", "");
|
||||||
|
|
||||||
if (long.TryParse(saveTime, out long unixTime))
|
|
||||||
{
|
|
||||||
DateTime time = ToolBox.Epoch.ToDateTime(unixTime);
|
|
||||||
saveTime = time.ToString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -350,6 +344,11 @@ namespace Barotrauma
|
|||||||
if (splitSaveFile.Length > 1) { subName = splitSaveFile[1]; }
|
if (splitSaveFile.Length > 1) { subName = splitSaveFile[1]; }
|
||||||
if (splitSaveFile.Length > 2) { saveTime = splitSaveFile[2]; }
|
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),
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform, Anchor.BottomLeft),
|
||||||
text: subName, font: GUI.SmallFont)
|
text: subName, font: GUI.SmallFont)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Barotrauma.Extensions;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -231,7 +232,16 @@ namespace Barotrauma
|
|||||||
"", style: "ItemCategory" + category.ToString())
|
"", style: "ItemCategory" + category.ToString())
|
||||||
{
|
{
|
||||||
UserData = category,
|
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);
|
itemCategoryButtons.Add(categoryButton);
|
||||||
|
|
||||||
@@ -487,10 +497,15 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
//refresh store view
|
//refresh store view
|
||||||
FillStoreItemList();
|
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)
|
private void DrawMap(SpriteBatch spriteBatch, GUICustomComponent mapContainer)
|
||||||
{
|
{
|
||||||
GameMain.GameSession?.Map?.Draw(spriteBatch, 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")
|
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);
|
content.RectTransform.RecalculateChildren(true, true);
|
||||||
amountInput?.LayoutGroup.Recalculate();
|
amountInput?.LayoutGroup.Recalculate();
|
||||||
textBlock.Text = ToolBox.LimitString(textBlock.Text, textBlock.Font, textBlock.Rect.Width);
|
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)
|
private bool BuyItem(GUIComponent component, object obj)
|
||||||
@@ -776,12 +795,24 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void RefreshMyItems()
|
private void RefreshMyItems()
|
||||||
{
|
{
|
||||||
myItemList.Content.ClearChildren();
|
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
|
||||||
|
foreach (PurchasedItem pi in Campaign.CargoManager.PurchasedItems)
|
||||||
foreach (PurchasedItem ip 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<GUINumberInput>().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) =>
|
myItemList.Content.RectTransform.SortChildren((x, y) =>
|
||||||
(x.GUIComponent.UserData as PurchasedItem).ItemPrefab.Name.CompareTo((y.GUIComponent.UserData as PurchasedItem).ItemPrefab.Name));
|
(x.GUIComponent.UserData as PurchasedItem).ItemPrefab.Name.CompareTo((y.GUIComponent.UserData as PurchasedItem).ItemPrefab.Name));
|
||||||
myItemList.Content.RectTransform.SortChildren((x, y) =>
|
myItemList.Content.RectTransform.SortChildren((x, y) =>
|
||||||
@@ -821,17 +852,28 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void FillStoreItemList()
|
private void FillStoreItemList()
|
||||||
{
|
{
|
||||||
storeItemList.ClearChildren();
|
|
||||||
|
|
||||||
int width = storeItemList.Rect.Width;
|
int width = storeItemList.Rect.Width;
|
||||||
|
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
|
||||||
foreach (MapEntityPrefab mapEntityPrefab in MapEntityPrefab.List)
|
foreach (MapEntityPrefab mapEntityPrefab in MapEntityPrefab.List)
|
||||||
{
|
{
|
||||||
if (!(mapEntityPrefab is ItemPrefab itemPrefab)) { continue; }
|
if (!(mapEntityPrefab is ItemPrefab itemPrefab)) { continue; }
|
||||||
PriceInfo priceInfo = itemPrefab.GetPrice(Campaign.Map.CurrentLocation);
|
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(
|
storeItemList.Content.RectTransform.SortChildren(
|
||||||
(x, y) => (x.GUIComponent.UserData as PurchasedItem).ItemPrefab.Name.CompareTo((y.GUIComponent.UserData as PurchasedItem).ItemPrefab.Name));
|
(x, y) => (x.GUIComponent.UserData as PurchasedItem).ItemPrefab.Name.CompareTo((y.GUIComponent.UserData as PurchasedItem).ItemPrefab.Name));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -968,7 +968,10 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
label = new GUITextBlock(new RectTransform(textLabelSize, parent.RectTransform), TextManager.Get("Password"), textAlignment: textAlignment);
|
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"))
|
isPublicBox = new GUITickBox(new RectTransform(tickBoxSize, parent.RectTransform), TextManager.Get("PublicServer"))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -147,6 +147,12 @@ namespace Barotrauma
|
|||||||
get { return playerList; }
|
get { return playerList; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GUITextBox CharacterNameBox
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
public GUIButton StartButton
|
public GUIButton StartButton
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@@ -920,7 +926,26 @@ namespace Barotrauma
|
|||||||
UserData = characterInfo
|
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)
|
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,
|
Selected = true,
|
||||||
Enabled = false,
|
Enabled = false,
|
||||||
|
Visible = false,
|
||||||
ToolTip = TextManager.Get("ReadyToStartTickBox"),
|
ToolTip = TextManager.Get("ReadyToStartTickBox"),
|
||||||
UserData = "clientready"
|
UserData = "clientready"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -70,8 +70,14 @@ namespace Barotrauma
|
|||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoHolder.RectTransform), TextManager.Get("YourName"));
|
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), "")
|
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;
|
clientNameBox.OnTextChanged += RefreshJoinButtonState;
|
||||||
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoHolder.RectTransform), TextManager.Get("ServerIP"));
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoHolder.RectTransform), TextManager.Get("ServerIP"));
|
||||||
@@ -236,7 +242,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
serverInfo = (ServerInfo)obj;
|
serverInfo = (ServerInfo)obj;
|
||||||
ipBox.UserData = serverInfo;
|
ipBox.UserData = serverInfo;
|
||||||
ipBox.Text = serverInfo.ServerName;
|
ipBox.Text = ToolBox.LimitString(serverInfo.ServerName, ipBox.Font, ipBox.Rect.Width);
|
||||||
}
|
}
|
||||||
catch (InvalidCastException)
|
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 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),
|
var gameStartedBox = new GUITickBox(new RectTransform(new Vector2(columnRelativeWidth[4], 0.4f), serverContent.RectTransform, Anchor.Center),
|
||||||
label: "", style: "GUIServerListRoundStartedTickBox") {
|
label: "", style: "GUIServerListRoundStartedTickBox") {
|
||||||
ToolTip = TextManager.Get((serverInfo.GameStarted) ? "ServerListRoundStarted" : "ServerListRoundNotStarted"),
|
ToolTip = TextManager.Get((serverInfo.GameStarted) ? "ServerListRoundStarted" : "ServerListRoundNotStarted"),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using OpenTK.Audio.OpenAL;
|
using OpenAL;
|
||||||
using NVorbis;
|
using NVorbis;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ namespace Barotrauma.Sounds
|
|||||||
|
|
||||||
reader = new VorbisReader(filename);
|
reader = new VorbisReader(filename);
|
||||||
|
|
||||||
ALFormat = reader.Channels == 1 ? ALFormat.Mono16 : ALFormat.Stereo16;
|
ALFormat = reader.Channels == 1 ? Al.FormatMono16 : Al.FormatStereo16;
|
||||||
SampleRate = reader.SampleRate;
|
SampleRate = reader.SampleRate;
|
||||||
|
|
||||||
if (!stream)
|
if (!stream)
|
||||||
@@ -35,26 +35,26 @@ namespace Barotrauma.Sounds
|
|||||||
|
|
||||||
CastBuffer(floatBuffer, shortBuffer, readSamples);
|
CastBuffer(floatBuffer, shortBuffer, readSamples);
|
||||||
|
|
||||||
AL.BufferData((int)ALBuffer, ALFormat, shortBuffer,
|
Al.BufferData(ALBuffer, ALFormat, shortBuffer,
|
||||||
readSamples * sizeof(short), SampleRate);
|
readSamples * sizeof(short), SampleRate);
|
||||||
|
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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);
|
MuffleBuffer(floatBuffer, SampleRate, reader.Channels);
|
||||||
|
|
||||||
CastBuffer(floatBuffer, shortBuffer, readSamples);
|
CastBuffer(floatBuffer, shortBuffer, readSamples);
|
||||||
|
|
||||||
AL.BufferData((int)ALMuffledBuffer, ALFormat, shortBuffer,
|
Al.BufferData(ALMuffledBuffer, ALFormat, shortBuffer,
|
||||||
readSamples * sizeof(short), SampleRate);
|
readSamples * sizeof(short), SampleRate);
|
||||||
|
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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();
|
reader.Dispose();
|
||||||
@@ -98,4 +98,4 @@ namespace Barotrauma.Sounds
|
|||||||
base.Dispose();
|
base.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using OpenTK.Audio.OpenAL;
|
using OpenAL;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ namespace Barotrauma.Sounds
|
|||||||
get { return !Stream ? alMuffledBuffer : 0; }
|
get { return !Stream ? alMuffledBuffer : 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public ALFormat ALFormat
|
public int ALFormat
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
protected set;
|
protected set;
|
||||||
@@ -91,26 +91,26 @@ namespace Barotrauma.Sounds
|
|||||||
|
|
||||||
if (!stream)
|
if (!stream)
|
||||||
{
|
{
|
||||||
AL.GenBuffer(out alBuffer);
|
Al.GenBuffer(out alBuffer);
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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!");
|
throw new Exception("Generated OpenAL buffer is invalid!");
|
||||||
}
|
}
|
||||||
|
|
||||||
AL.GenBuffer(out alMuffledBuffer);
|
Al.GenBuffer(out alMuffledBuffer);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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!");
|
throw new Exception("Generated OpenAL buffer is invalid!");
|
||||||
}
|
}
|
||||||
@@ -186,32 +186,32 @@ namespace Barotrauma.Sounds
|
|||||||
Owner.KillChannels(this);
|
Owner.KillChannels(this);
|
||||||
if (alBuffer != 0)
|
if (alBuffer != 0)
|
||||||
{
|
{
|
||||||
if (!AL.IsBuffer(alBuffer))
|
if (!Al.IsBuffer(alBuffer))
|
||||||
{
|
{
|
||||||
throw new Exception("Buffer to delete is invalid!");
|
throw new Exception("Buffer to delete is invalid!");
|
||||||
}
|
}
|
||||||
|
|
||||||
AL.DeleteBuffer(ref alBuffer); alBuffer = 0;
|
Al.DeleteBuffer(alBuffer); alBuffer = 0;
|
||||||
|
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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 (alMuffledBuffer != 0)
|
||||||
{
|
{
|
||||||
if (!AL.IsBuffer(alMuffledBuffer))
|
if (!Al.IsBuffer(alMuffledBuffer))
|
||||||
{
|
{
|
||||||
throw new Exception("Buffer to delete is invalid!");
|
throw new Exception("Buffer to delete is invalid!");
|
||||||
}
|
}
|
||||||
|
|
||||||
AL.DeleteBuffer(ref alMuffledBuffer); alMuffledBuffer = 0;
|
Al.DeleteBuffer(alMuffledBuffer); alMuffledBuffer = 0;
|
||||||
|
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using OpenTK.Audio.OpenAL;
|
using OpenAL;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
@@ -15,49 +15,49 @@ namespace Barotrauma.Sounds
|
|||||||
|
|
||||||
public SoundSourcePool(int sourceCount = SoundManager.SOURCE_COUNT)
|
public SoundSourcePool(int sourceCount = SoundManager.SOURCE_COUNT)
|
||||||
{
|
{
|
||||||
ALError alError = ALError.NoError;
|
int alError = Al.NoError;
|
||||||
|
|
||||||
ALSources = new uint[sourceCount];
|
ALSources = new uint[sourceCount];
|
||||||
for (int i = 0; i < sourceCount; i++)
|
for (int i = 0; i < sourceCount; i++)
|
||||||
{
|
{
|
||||||
AL.GenSource(out ALSources[i]);
|
Al.GenSource(out ALSources[i]);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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!");
|
throw new Exception("Generated alSource[" + i.ToString() + "] is invalid!");
|
||||||
}
|
}
|
||||||
|
|
||||||
AL.SourceStop(ALSources[i]);
|
Al.SourceStop(ALSources[i]);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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);
|
Al.Sourcef(ALSources[i], Al.MinGain, 0.0f);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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);
|
Al.Sourcef(ALSources[i], Al.MaxGain, 1.0f);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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);
|
Al.Sourcef(ALSources[i], Al.RolloffFactor, 1.0f);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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++)
|
for (int i = 0; i < ALSources.Length; i++)
|
||||||
{
|
{
|
||||||
AL.DeleteSource(ref ALSources[i]);
|
Al.DeleteSource(ALSources[i]);
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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;
|
ALSources = null;
|
||||||
@@ -95,35 +95,35 @@ namespace Barotrauma.Sounds
|
|||||||
if (position != null)
|
if (position != null)
|
||||||
{
|
{
|
||||||
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
|
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
|
||||||
AL.Source(alSource, ALSourceb.SourceRelative, false);
|
Al.Sourcei(alSource, Al.SourceRelative, Al.False);
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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);
|
Al.Source3f(alSource, Al.Position, position.Value.X, position.Value.Y, position.Value.Z);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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
|
else
|
||||||
{
|
{
|
||||||
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
|
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
|
||||||
AL.Source(alSource, ALSourceb.SourceRelative, true);
|
Al.Sourcei(alSource, Al.SourceRelative, Al.True);
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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);
|
Al.Source3f(alSource, Al.Position, 0.0f, 0.0f, 0.0f);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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;
|
if (ALSourceIndex < 0) return;
|
||||||
|
|
||||||
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
|
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
|
||||||
AL.Source(alSource, ALSourcef.ReferenceDistance, near);
|
Al.Sourcef(alSource, Al.ReferenceDistance, near);
|
||||||
|
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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;
|
if (ALSourceIndex < 0) return;
|
||||||
|
|
||||||
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
|
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
|
||||||
AL.Source(alSource, ALSourcef.MaxDistance, far);
|
Al.Sourcef(alSource, Al.MaxDistance, far);
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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;
|
float effectiveGain = gain;
|
||||||
if (category != null) effectiveGain *= Sound.Owner.GetCategoryGainMultiplier(category);
|
if (category != null) effectiveGain *= Sound.Owner.GetCategoryGainMultiplier(category);
|
||||||
|
|
||||||
AL.Source(alSource, ALSourcef.Gain, effectiveGain);
|
Al.Sourcef(alSource, Al.Gain, effectiveGain);
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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)
|
if (!IsStream)
|
||||||
{
|
{
|
||||||
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
|
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
|
||||||
AL.Source(alSource, ALSourceb.Looping, looping);
|
Al.Sourcei(alSource, Al.Looping, looping ? Al.True : Al.False);
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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)
|
if (!IsStream)
|
||||||
{
|
{
|
||||||
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
|
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
|
||||||
int playbackPos; AL.GetSource(alSource, ALGetSourcei.SampleOffset, out playbackPos);
|
int playbackPos; Al.GetSourcei(alSource, Al.SampleOffset, out playbackPos);
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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);
|
Al.SourcePlay(alSource);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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);
|
Al.Sourcei(alSource, Al.SampleOffset, playbackPos);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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 (ALSourceIndex < 0) return false;
|
||||||
if (IsStream && !reachedEndSample) return true;
|
if (IsStream && !reachedEndSample) return true;
|
||||||
bool playing = AL.GetSourceState(Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex)) == ALSourceState.Playing;
|
int state;
|
||||||
ALError alError = AL.GetError();
|
Al.GetSourcei(Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.SourceState, out state);
|
||||||
if (alError != ALError.NoError)
|
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;
|
return playing;
|
||||||
}
|
}
|
||||||
@@ -357,47 +359,47 @@ namespace Barotrauma.Sounds
|
|||||||
{
|
{
|
||||||
if (!IsStream)
|
if (!IsStream)
|
||||||
{
|
{
|
||||||
AL.BindBufferToSource(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), 0);
|
Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, 0);
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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!");
|
throw new Exception(sound.Filename + " has an invalid buffer!");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint alBuffer = sound.Owner.GetCategoryMuffle(category) || muffle ? sound.ALMuffledBuffer : sound.ALBuffer;
|
uint alBuffer = sound.Owner.GetCategoryMuffle(category) || muffle ? sound.ALMuffledBuffer : sound.ALBuffer;
|
||||||
AL.BindBufferToSource(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), alBuffer);
|
Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, (int)alBuffer);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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));
|
Al.SourcePlay(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex));
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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
|
else
|
||||||
{
|
{
|
||||||
AL.BindBufferToSource(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), (uint)sound.ALBuffer);
|
Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, (int)sound.ALBuffer);
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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);
|
Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Looping, Al.False);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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];
|
streamShortBuffer = new short[STREAM_BUFFER_SIZE];
|
||||||
@@ -406,15 +408,15 @@ namespace Barotrauma.Sounds
|
|||||||
emptyBuffers = new List<uint>();
|
emptyBuffers = new List<uint>();
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
AL.GenBuffer(out streamBuffers[i]);
|
Al.GenBuffer(out streamBuffers[i]);
|
||||||
|
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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!");
|
throw new Exception("Generated streamBuffer[" + i.ToString() + "] is invalid!");
|
||||||
}
|
}
|
||||||
@@ -445,57 +447,57 @@ namespace Barotrauma.Sounds
|
|||||||
{
|
{
|
||||||
if (ALSourceIndex >= 0)
|
if (ALSourceIndex >= 0)
|
||||||
{
|
{
|
||||||
AL.SourceStop(Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex));
|
Al.SourceStop(Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex));
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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)
|
if (IsStream)
|
||||||
{
|
{
|
||||||
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
|
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
|
||||||
|
|
||||||
AL.SourceStop(alSource);
|
Al.SourceStop(alSource);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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 buffersToUnqueue = 0;
|
||||||
int[] unqueuedBuffers = null;
|
uint[] unqueuedBuffers = null;
|
||||||
|
|
||||||
buffersToUnqueue = 0;
|
buffersToUnqueue = 0;
|
||||||
AL.GetSource(alSource, ALGetSourcei.BuffersProcessed, out buffersToUnqueue);
|
Al.GetSourcei(alSource, Al.BuffersProcessed, out buffersToUnqueue);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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];
|
unqueuedBuffers = new uint[buffersToUnqueue];
|
||||||
AL.SourceUnqueueBuffers((int)alSource, buffersToUnqueue, unqueuedBuffers);
|
Al.SourceUnqueueBuffers(alSource, buffersToUnqueue, unqueuedBuffers);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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);
|
Al.Sourcei(alSource, Al.Buffer, 0);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
AL.DeleteBuffer(ref streamBuffers[i]);
|
Al.DeleteBuffer(streamBuffers[i]);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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
|
else
|
||||||
{
|
{
|
||||||
AL.BindBufferToSource(Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), 0);
|
Al.Sourcei(Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, 0);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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);
|
uint alSource = Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex);
|
||||||
|
|
||||||
bool playing = AL.GetSourceState(alSource) == ALSourceState.Playing;
|
int state;
|
||||||
ALError alError = AL.GetError();
|
Al.GetSourcei(Sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.SourceState, out state);
|
||||||
if (alError != ALError.NoError)
|
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 buffersToUnqueue = 0;
|
||||||
int[] unqueuedBuffers = null;
|
uint[] unqueuedBuffers = null;
|
||||||
if (!startedPlaying)
|
if (!startedPlaying)
|
||||||
{
|
{
|
||||||
buffersToUnqueue = 0;
|
buffersToUnqueue = 0;
|
||||||
AL.GetSource(alSource, ALGetSourcei.BuffersProcessed, out buffersToUnqueue);
|
Al.GetSourcei(alSource, Al.BuffersProcessed, out buffersToUnqueue);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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];
|
unqueuedBuffers = new uint[buffersToUnqueue+emptyBuffers.Count];
|
||||||
AL.SourceUnqueueBuffers((int)alSource, buffersToUnqueue, unqueuedBuffers);
|
Al.SourceUnqueueBuffers(alSource, buffersToUnqueue, unqueuedBuffers);
|
||||||
for (int i = 0; i < emptyBuffers.Count; i++)
|
for (int i = 0; i < emptyBuffers.Count; i++)
|
||||||
{
|
{
|
||||||
unqueuedBuffers[buffersToUnqueue + i] = (int)emptyBuffers[i];
|
unqueuedBuffers[buffersToUnqueue + i] = emptyBuffers[i];
|
||||||
}
|
}
|
||||||
buffersToUnqueue += emptyBuffers.Count;
|
buffersToUnqueue += emptyBuffers.Count;
|
||||||
emptyBuffers.Clear();
|
emptyBuffers.Clear();
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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
|
else
|
||||||
{
|
{
|
||||||
startedPlaying = false;
|
startedPlaying = false;
|
||||||
buffersToUnqueue = 4;
|
buffersToUnqueue = 4;
|
||||||
unqueuedBuffers = new int[4];
|
unqueuedBuffers = new uint[4];
|
||||||
for (int i = 0; i < 4; i++)
|
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)
|
if (readSamples > 0)
|
||||||
{
|
{
|
||||||
AL.BufferData<short>(unqueuedBuffers[i], Sound.ALFormat, buffer, readSamples, Sound.SampleRate);
|
Al.BufferData<short>(unqueuedBuffers[i], Sound.ALFormat, buffer, readSamples, Sound.SampleRate);
|
||||||
|
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
if (alError != Al.NoError)
|
||||||
{
|
{
|
||||||
throw new Exception("Failed to assign data to stream buffer: " +
|
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]);
|
Al.SourceQueueBuffer(alSource, unqueuedBuffers[i]);
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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)
|
else if (readSamples < 0)
|
||||||
@@ -637,10 +641,11 @@ namespace Barotrauma.Sounds
|
|||||||
emptyBuffers.Add((uint)unqueuedBuffers[i]);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using OpenTK.Audio.OpenAL;
|
using OpenAL;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -20,7 +20,7 @@ namespace Barotrauma.Sounds
|
|||||||
}
|
}
|
||||||
|
|
||||||
private IntPtr alcDevice;
|
private IntPtr alcDevice;
|
||||||
private OpenTK.ContextHandle alcContext;
|
private IntPtr alcContext;
|
||||||
|
|
||||||
public enum SourcePoolIndex
|
public enum SourcePoolIndex
|
||||||
{
|
{
|
||||||
@@ -42,11 +42,11 @@ namespace Barotrauma.Sounds
|
|||||||
{
|
{
|
||||||
if (Disabled) { return; }
|
if (Disabled) { return; }
|
||||||
listenerPosition = value;
|
listenerPosition = value;
|
||||||
AL.Listener(ALListener3f.Position,value.X,value.Y,value.Z);
|
Al.Listener3f(Al.Position,value.X,value.Y,value.Z);
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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; }
|
if (Disabled) { return; }
|
||||||
listenerOrientation[0] = value.X; listenerOrientation[1] = value.Y; listenerOrientation[2] = value.Z;
|
listenerOrientation[0] = value.X; listenerOrientation[1] = value.Y; listenerOrientation[2] = value.Z;
|
||||||
AL.Listener(ALListenerfv.Orientation, ref listenerOrientation);
|
Al.Listenerfv(Al.Orientation, listenerOrientation);
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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; }
|
if (Disabled) { return; }
|
||||||
listenerOrientation[3] = value.X; listenerOrientation[4] = value.Y; listenerOrientation[5] = value.Z;
|
listenerOrientation[3] = value.X; listenerOrientation[4] = value.Y; listenerOrientation[5] = value.Z;
|
||||||
AL.Listener(ALListenerfv.Orientation, ref listenerOrientation);
|
Al.Listenerfv(Al.Orientation, listenerOrientation);
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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 (Disabled) { return; }
|
||||||
if (Math.Abs(ListenerGain - value) < 0.001f) { return; }
|
if (Math.Abs(ListenerGain - value) < 0.001f) { return; }
|
||||||
listenerGain = value;
|
listenerGain = value;
|
||||||
AL.Listener(ALListenerf.Gain, listenerGain);
|
Al.Listenerf(Al.Gain, listenerGain);
|
||||||
ALError alError = AL.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AlcError alcError = Alc.GetError(alcDevice);
|
int alcError = Alc.GetError(alcDevice);
|
||||||
if (alcError != AlcError.NoError)
|
if (alcError != Alc.NoError)
|
||||||
{
|
{
|
||||||
//The audio device probably wasn't ready, this happens quite often
|
//The audio device probably wasn't ready, this happens quite often
|
||||||
//Just wait a while and try again
|
//Just wait a while and try again
|
||||||
@@ -136,7 +136,7 @@ namespace Barotrauma.Sounds
|
|||||||
alcDevice = Alc.OpenDevice(null);
|
alcDevice = Alc.OpenDevice(null);
|
||||||
|
|
||||||
alcError = Alc.GetError(alcDevice);
|
alcError = Alc.GetError(alcDevice);
|
||||||
if (alcError != AlcError.NoError)
|
if (alcError != Alc.NoError)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Error initializing ALC device: " + alcError.ToString() + ". Disabling audio playback...");
|
DebugConsole.ThrowError("Error initializing ALC device: " + alcError.ToString() + ". Disabling audio playback...");
|
||||||
Disabled = true;
|
Disabled = true;
|
||||||
@@ -161,14 +161,14 @@ namespace Barotrauma.Sounds
|
|||||||
}
|
}
|
||||||
|
|
||||||
alcError = Alc.GetError(alcDevice);
|
alcError = Alc.GetError(alcDevice);
|
||||||
if (alcError != AlcError.NoError)
|
if (alcError != Alc.NoError)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Error after assigning ALC context: " + alcError.ToString() + ". Disabling audio playback...");
|
DebugConsole.ThrowError("Error after assigning ALC context: " + alcError.ToString() + ". Disabling audio playback...");
|
||||||
Disabled = true;
|
Disabled = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALError alError = ALError.NoError;
|
int alError = Al.NoError;
|
||||||
|
|
||||||
sourcePools = new SoundSourcePool[2];
|
sourcePools = new SoundSourcePool[2];
|
||||||
sourcePools[(int)SourcePoolIndex.Default] = new SoundSourcePool(SOURCE_COUNT);
|
sourcePools[(int)SourcePoolIndex.Default] = new SoundSourcePool(SOURCE_COUNT);
|
||||||
@@ -177,12 +177,12 @@ namespace Barotrauma.Sounds
|
|||||||
sourcePools[(int)SourcePoolIndex.Voice] = new SoundSourcePool(8);
|
sourcePools[(int)SourcePoolIndex.Voice] = new SoundSourcePool(8);
|
||||||
playingChannels[(int)SourcePoolIndex.Voice] = new SoundChannel[8];
|
playingChannels[(int)SourcePoolIndex.Voice] = new SoundChannel[8];
|
||||||
|
|
||||||
AL.DistanceModel(ALDistanceModel.LinearDistanceClamped);
|
Al.DistanceModel(Al.LinearDistanceClamped);
|
||||||
|
|
||||||
alError = AL.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != ALError.NoError)
|
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;
|
Disabled = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -239,7 +239,7 @@ namespace Barotrauma.Sounds
|
|||||||
{
|
{
|
||||||
if (Disabled || srcInd < 0 || srcInd >= sourcePools[(int)poolIndex].ALSources.Length) return 0;
|
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!");
|
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++)
|
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.Sourcef(sourcePools[0].ALSources[i], Al.MaxGain, i == ind ? 1.0f : 0.0f);
|
||||||
AL.Source(sourcePools[0].ALSources[i], ALSourcef.MinGain, 0.0f);
|
Al.Sourcef(sourcePools[0].ALSources[i], Al.MinGain, 0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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--)
|
for (int i = loadedSounds.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
loadedSounds[i].Dispose();
|
loadedSounds[i].Dispose();
|
||||||
@@ -514,7 +511,7 @@ namespace Barotrauma.Sounds
|
|||||||
sourcePools[(int)SourcePoolIndex.Default]?.Dispose();
|
sourcePools[(int)SourcePoolIndex.Default]?.Dispose();
|
||||||
sourcePools[(int)SourcePoolIndex.Voice]?.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() + ")");
|
throw new Exception("Failed to detach the current ALC context! (error code: " + Alc.GetError(alcDevice).ToString() + ")");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using OpenTK.Audio.OpenAL;
|
using OpenAL;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
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)
|
public VideoSound(SoundManager owner, string filename, int sampleRate, Video vid) : base(owner, filename, true, false)
|
||||||
{
|
{
|
||||||
ALFormat = ALFormat.Stereo16;
|
ALFormat = Al.FormatStereo16;
|
||||||
SampleRate = sampleRate;
|
SampleRate = sampleRate;
|
||||||
|
|
||||||
sampleQueue = new Queue<short[]>();
|
sampleQueue = new Queue<short[]>();
|
||||||
@@ -110,4 +110,4 @@ namespace Barotrauma.Sounds
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Barotrauma.Networking;
|
using Barotrauma.Networking;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using OpenTK.Audio.OpenAL;
|
using OpenAL;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ namespace Barotrauma.Sounds
|
|||||||
{
|
{
|
||||||
VoipConfig.SetupEncoding();
|
VoipConfig.SetupEncoding();
|
||||||
|
|
||||||
ALFormat = ALFormat.Mono16;
|
ALFormat = Al.FormatMono16;
|
||||||
SampleRate = VoipConfig.FREQUENCY;
|
SampleRate = VoipConfig.FREQUENCY;
|
||||||
|
|
||||||
queue = q;
|
queue = q;
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ namespace Barotrauma.SpriteDeformations
|
|||||||
[Serialize(false, true)]
|
[Serialize(false, true)]
|
||||||
public bool UseMovementSine { get; set; }
|
public bool UseMovementSine { get; set; }
|
||||||
|
|
||||||
|
[Serialize(false, true)]
|
||||||
|
public bool StopWhenHostIsDead { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Only used if UseMovementSine is enabled. Multiplier for Pi.
|
/// Only used if UseMovementSine is enabled. Multiplier for Pi.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||||
<NuGetPackageImportStamp>
|
<NuGetPackageImportStamp>
|
||||||
</NuGetPackageImportStamp>
|
</NuGetPackageImportStamp>
|
||||||
<AllowedReferenceRelatedFileExtensions>.pdb</AllowedReferenceRelatedFileExtensions>
|
<AllowedReferenceRelatedFileExtensions>.pdb</AllowedReferenceRelatedFileExtensions>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseWindows|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseWindows|x64'">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<OutputPath>..\bin\ReleaseWindows\</OutputPath>
|
<OutputPath>..\bin\ReleaseWindows\</OutputPath>
|
||||||
<DefineConstants>TRACE;WINDOWS;CLIENT</DefineConstants>
|
<DefineConstants>TRACE;WINDOWS;CLIENT;X64</DefineConstants>
|
||||||
<Optimize>true</Optimize>
|
<Optimize>true</Optimize>
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugWindows|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugWindows|x64'">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<OutputPath>..\bin\DebugWindows\</OutputPath>
|
<OutputPath>..\bin\DebugWindows\</OutputPath>
|
||||||
<DefineConstants>TRACE;WINDOWS;CLIENT;DEBUG</DefineConstants>
|
<DefineConstants>TRACE;DEBUG;WINDOWS;CLIENT;X64</DefineConstants>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseWindows|x86'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseWindows|x86'">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<OutputPath>..\bin\x86\ReleaseWindows\</OutputPath>
|
<OutputPath>..\bin\x86\ReleaseWindows\</OutputPath>
|
||||||
<DefineConstants>TRACE;WINDOWS;CLIENT</DefineConstants>
|
<DefineConstants>TRACE;WINDOWS;CLIENT;X86</DefineConstants>
|
||||||
<Optimize>true</Optimize>
|
<Optimize>true</Optimize>
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugWindows|x86'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugWindows|x86'">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<OutputPath>..\bin\x86\DebugWindows\</OutputPath>
|
<OutputPath>..\bin\x86\DebugWindows\</OutputPath>
|
||||||
<DefineConstants>TRACE;WINDOWS;CLIENT;DEBUG</DefineConstants>
|
<DefineConstants>TRACE;DEBUG;WINDOWS;CLIENT;X86</DefineConstants>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
@@ -95,9 +95,6 @@
|
|||||||
<Reference Include="NVorbis, Version=0.8.6.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="NVorbis, Version=0.8.6.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\..\Libraries\NuGet\NVorbis.0.8.6\lib\net35\NVorbis.dll</HintPath>
|
<HintPath>..\..\Libraries\NuGet\NVorbis.0.8.6\lib\net35\NVorbis.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="OpenTK, Version=3.0.1.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\..\Libraries\NuGet\OpenTK.3.0.1\lib\net20\OpenTK.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
<Reference Include="RestSharp, Version=105.2.3.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="RestSharp, Version=105.2.3.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\..\Libraries\NuGet\RestSharp.105.2.3\lib\net45\RestSharp.dll</HintPath>
|
<HintPath>..\..\Libraries\NuGet\RestSharp.105.2.3\lib\net45\RestSharp.dll</HintPath>
|
||||||
@@ -215,16 +212,16 @@
|
|||||||
<Content Include="Shaders\losshader.fx" />
|
<Content Include="Shaders\losshader.fx" />
|
||||||
<Content Include="Shaders\postprocess.fx" />
|
<Content Include="Shaders\postprocess.fx" />
|
||||||
<Content Include="Shaders\watershader.fx" />
|
<Content Include="Shaders\watershader.fx" />
|
||||||
<Content Include="wrap_oal.dll">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="MonoGame.Framework.dll.config">
|
<Content Include="MonoGame.Framework.dll.config">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="OpenTK.dll.config">
|
<Content Include="SharpFont.dll.config">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="SharpFont.dll.config">
|
<Content Include="soft_oal_x64.dll">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="soft_oal_x86.dll">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -306,7 +303,7 @@
|
|||||||
<Import Project="ClientCode.projitems" Label="Shared" />
|
<Import Project="ClientCode.projitems" Label="Shared" />
|
||||||
<Import Project="..\BarotraumaShared\SharedCode.projitems" Label="Shared" />
|
<Import Project="..\BarotraumaShared\SharedCode.projitems" Label="Shared" />
|
||||||
<Import Project="..\BarotraumaShared\SharedContent.projitems" Label="Shared" />
|
<Import Project="..\BarotraumaShared\SharedContent.projitems" Label="Shared" />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<Import Project="..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets" Condition="Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets')" />
|
<Import Project="..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets" Condition="Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets')" />
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
<package id="NLog" version="4.3.8" targetFramework="net45" />
|
<package id="NLog" version="4.3.8" targetFramework="net45" />
|
||||||
<package id="nVLC" version="3.0.0" targetFramework="net45" />
|
<package id="nVLC" version="3.0.0" targetFramework="net45" />
|
||||||
<package id="NVorbis" version="0.8.6" targetFramework="net45" />
|
<package id="NVorbis" version="0.8.6" targetFramework="net45" />
|
||||||
<package id="OpenTK" version="3.0.1" targetFramework="net45" />
|
|
||||||
<package id="RestSharp" version="105.2.3" targetFramework="net45" />
|
<package id="RestSharp" version="105.2.3" targetFramework="net45" />
|
||||||
<package id="SharpDX" version="4.2.0" targetFramework="net45" />
|
<package id="SharpDX" version="4.2.0" targetFramework="net45" />
|
||||||
<package id="SharpDX.Direct2D1" version="4.2.0" targetFramework="net45" />
|
<package id="SharpDX.Direct2D1" version="4.2.0" targetFramework="net45" />
|
||||||
|
|||||||
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("0.9.0.3")]
|
[assembly: AssemblyVersion("0.9.0.4")]
|
||||||
[assembly: AssemblyFileVersion("0.9.0.3")]
|
[assembly: AssemblyFileVersion("0.9.0.4")]
|
||||||
|
|||||||
@@ -273,10 +273,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Condition="$(Configuration.EndsWith('Linux'))">
|
<ItemGroup Condition="$(Configuration.EndsWith('Linux')) Or $(Configuration.EndsWith('Mac'))">
|
||||||
<None Include="Launch_BarotraumaServer">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Include="DedicatedServer">
|
<None Include="DedicatedServer">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|||||||
@@ -153,20 +153,5 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
return this.Permissions.HasFlag(permission);
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,12 +30,13 @@ namespace Barotrauma
|
|||||||
if (entities.Entity is Item)
|
if (entities.Entity is Item)
|
||||||
{
|
{
|
||||||
message.Write((byte)SpawnableType.Item);
|
message.Write((byte)SpawnableType.Item);
|
||||||
|
DebugConsole.Log("Writing item spawn data " + entities.Entity.ToString() + " (ID: " + entities.Entity.ID + ")");
|
||||||
((Item)entities.Entity).WriteSpawnData(message);
|
((Item)entities.Entity).WriteSpawnData(message);
|
||||||
}
|
}
|
||||||
else if (entities.Entity is Character)
|
else if (entities.Entity is Character)
|
||||||
{
|
{
|
||||||
message.Write((byte)SpawnableType.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);
|
((Character)entities.Entity).WriteSpawnData(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -576,7 +576,7 @@ namespace Barotrauma.Networking
|
|||||||
HandleOwnership(msgContent, inc.SenderConnection);
|
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))
|
if (inc.SenderConnection != OwnerConnection && serverSettings.BanList.IsBanned(inc.SenderEndPoint.Address, 0))
|
||||||
{
|
{
|
||||||
inc.SenderConnection.Deny(DisconnectReason.Banned.ToString());
|
inc.SenderConnection.Deny(DisconnectReason.Banned.ToString());
|
||||||
@@ -661,7 +661,13 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (GameMain.Config.UseSteamMatchmaking)
|
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
|
else
|
||||||
{
|
{
|
||||||
@@ -865,6 +871,8 @@ namespace Barotrauma.Networking
|
|||||||
c.LastRecvLobbyUpdate = NetIdUtils.Clamp(inc.ReadUInt16(), c.LastRecvLobbyUpdate, GameMain.NetLobbyScreen.LastUpdateID);
|
c.LastRecvLobbyUpdate = NetIdUtils.Clamp(inc.ReadUInt16(), c.LastRecvLobbyUpdate, GameMain.NetLobbyScreen.LastUpdateID);
|
||||||
c.LastRecvChatMsgID = NetIdUtils.Clamp(inc.ReadUInt16(), c.LastRecvChatMsgID, c.LastChatMsgQueueID);
|
c.LastRecvChatMsgID = NetIdUtils.Clamp(inc.ReadUInt16(), c.LastRecvChatMsgID, c.LastChatMsgQueueID);
|
||||||
c.LastRecvClientListUpdate = NetIdUtils.Clamp(inc.ReadUInt16(), c.LastRecvClientListUpdate, LastClientListUpdateID);
|
c.LastRecvClientListUpdate = NetIdUtils.Clamp(inc.ReadUInt16(), c.LastRecvClientListUpdate, LastClientListUpdateID);
|
||||||
|
|
||||||
|
TryChangeClientName(c, inc.ReadString());
|
||||||
|
|
||||||
c.LastRecvCampaignSave = inc.ReadUInt16();
|
c.LastRecvCampaignSave = inc.ReadUInt16();
|
||||||
if (c.LastRecvCampaignSave > 0)
|
if (c.LastRecvCampaignSave > 0)
|
||||||
@@ -2066,11 +2074,44 @@ namespace Barotrauma.Networking
|
|||||||
public override void AddChatMessage(ChatMessage message)
|
public override void AddChatMessage(ChatMessage message)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(message.Text)) { return; }
|
if (string.IsNullOrEmpty(message.Text)) { return; }
|
||||||
Log(message.TextWithSender, ServerLog.MessageType.Chat);
|
Log(message.TextWithSender, ServerLog.MessageType.Chat);
|
||||||
|
|
||||||
base.AddChatMessage(message);
|
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)
|
public override void KickPlayer(string playerName, string reason)
|
||||||
{
|
{
|
||||||
playerName = playerName.ToLowerInvariant();
|
playerName = playerName.ToLowerInvariant();
|
||||||
|
|||||||
@@ -432,7 +432,7 @@ namespace Barotrauma.Networking
|
|||||||
DebugConsole.NewMessage(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (invalid name)", Color.Red);
|
DebugConsole.NewMessage(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (invalid name)", Color.Red);
|
||||||
return;
|
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, "");
|
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);
|
Log(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (name taken by the server)", ServerLog.MessageType.Error);
|
||||||
|
|||||||
+27
-7
@@ -48,6 +48,9 @@ namespace Barotrauma.Networking
|
|||||||
private List<ServerEntityEvent> uniqueEvents;
|
private List<ServerEntityEvent> uniqueEvents;
|
||||||
|
|
||||||
private UInt16 lastSentToAll;
|
private UInt16 lastSentToAll;
|
||||||
|
private UInt16 lastSentToAnyone;
|
||||||
|
private double lastSentToAnyoneTime;
|
||||||
|
private double lastWarningTime;
|
||||||
|
|
||||||
public List<ServerEntityEvent> Events
|
public List<ServerEntityEvent> Events
|
||||||
{
|
{
|
||||||
@@ -99,6 +102,8 @@ namespace Barotrauma.Networking
|
|||||||
bufferedEvents = new List<BufferedEvent>();
|
bufferedEvents = new List<BufferedEvent>();
|
||||||
|
|
||||||
uniqueEvents = new List<ServerEntityEvent>();
|
uniqueEvents = new List<ServerEntityEvent>();
|
||||||
|
|
||||||
|
lastWarningTime = -10.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateEvent(IServerSerializable entity, object[] extraData = null)
|
public void CreateEvent(IServerSerializable entity, object[] extraData = null)
|
||||||
@@ -198,6 +203,7 @@ namespace Barotrauma.Networking
|
|||||||
var inGameClients = clients.FindAll(c => c.InGame && !c.NeedsMidRoundSync);
|
var inGameClients = clients.FindAll(c => c.InGame && !c.NeedsMidRoundSync);
|
||||||
if (inGameClients.Count > 0)
|
if (inGameClients.Count > 0)
|
||||||
{
|
{
|
||||||
|
lastSentToAnyone = inGameClients[0].LastRecvEntityEventID;
|
||||||
lastSentToAll = inGameClients[0].LastRecvEntityEventID;
|
lastSentToAll = inGameClients[0].LastRecvEntityEventID;
|
||||||
if (server.OwnerConnection != null)
|
if (server.OwnerConnection != null)
|
||||||
{
|
{
|
||||||
@@ -207,25 +213,39 @@ namespace Barotrauma.Networking
|
|||||||
lastSentToAll = owner.LastRecvEntityEventID;
|
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); });
|
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));
|
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
|
// This event is 10 seconds older than the last one we've successfully sent,
|
||||||
// UNLESS the event was created when the client was still midround syncing, in which case we'll wait until the timeout
|
// kick everyone that hasn't received it yet, this is way too old
|
||||||
// runs out before kicking the client
|
// 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<Client> toKick = inGameClients.FindAll(c =>
|
List<Client> toKick = inGameClients.FindAll(c =>
|
||||||
NetIdUtils.IdMoreRecent((UInt16)(lastSentToAll + 1), c.LastRecvEntityEventID) &&
|
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 =>
|
toKick.ForEach(c =>
|
||||||
{
|
{
|
||||||
DebugConsole.NewMessage(c.Name + " was kicked due to excessive desync (expected old event " + (c.LastRecvEntityEventID + 1).ToString() + ")", Color.Red);
|
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 "
|
GameServer.Log("Disconnecting client " + c.Name + " due to excessive desync (expected old event "
|
||||||
+ (c.LastRecvEntityEventID + 1).ToString() +
|
+ (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);
|
" Events queued: " + events.Count + ", last sent to all: " + lastSentToAll, ServerLog.MessageType.Error);
|
||||||
server.DisconnectClient(c, "", "ServerMessage.ExcessiveDesyncOldEvent");
|
server.DisconnectClient(c, "", "ServerMessage.ExcessiveDesyncOldEvent");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Barotrauma.Items.Components;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -9,19 +10,15 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
private List<Client> GetClientsToRespawn()
|
private List<Client> GetClientsToRespawn()
|
||||||
{
|
{
|
||||||
GameServer server = networkMember as GameServer;
|
|
||||||
|
|
||||||
return networkMember.ConnectedClients.FindAll(c =>
|
return networkMember.ConnectedClients.FindAll(c =>
|
||||||
c.InGame &&
|
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));
|
(c.Character == null || c.Character.IsDead));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<CharacterInfo> GetBotsToRespawn()
|
private List<CharacterInfo> GetBotsToRespawn()
|
||||||
{
|
{
|
||||||
GameServer server = networkMember as GameServer;
|
if (GameMain.Server.ServerSettings.BotSpawnMode == BotSpawnMode.Normal)
|
||||||
|
|
||||||
if (server.ServerSettings.BotSpawnMode == BotSpawnMode.Normal)
|
|
||||||
{
|
{
|
||||||
return Character.CharacterList
|
return Character.CharacterList
|
||||||
.FindAll(c => c.TeamID == Character.TeamType.Team1 && c.AIController != null && c.Info != null && c.IsDead)
|
.FindAll(c => c.TeamID == Character.TeamType.Team1 && c.AIController != null && c.Info != null && c.IsDead)
|
||||||
@@ -29,14 +26,14 @@ namespace Barotrauma.Networking
|
|||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
int currPlayerCount = server.ConnectedClients.Count(c =>
|
int currPlayerCount = GameMain.Server.ConnectedClients.Count(c =>
|
||||||
c.InGame &&
|
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
|
var existingBots = Character.CharacterList
|
||||||
.FindAll(c => c.TeamID == Character.TeamType.Team1 && c.AIController != null && c.Info != null);
|
.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);
|
requiredBots -= existingBots.Count(b => !b.IsDead);
|
||||||
|
|
||||||
List<CharacterInfo> botsToRespawn = new List<CharacterInfo>();
|
List<CharacterInfo> botsToRespawn = new List<CharacterInfo>();
|
||||||
@@ -58,21 +55,19 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
partial void UpdateWaiting(float deltaTime)
|
partial void UpdateWaiting(float deltaTime)
|
||||||
{
|
{
|
||||||
var server = networkMember as GameServer;
|
|
||||||
|
|
||||||
int characterToRespawnCount = GetClientsToRespawn().Count;
|
int characterToRespawnCount = GetClientsToRespawn().Count;
|
||||||
int totalCharacterCount = server.ConnectedClients.Count;
|
int totalCharacterCount = GameMain.Server.ConnectedClients.Count;
|
||||||
/*if (server.Character != null)
|
/*if (server.Character != null)
|
||||||
{
|
{
|
||||||
totalCharacterCount++;
|
totalCharacterCount++;
|
||||||
if (server.Character.IsDead) characterToRespawnCount++;
|
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)
|
if (startCountdown != CountdownStarted)
|
||||||
{
|
{
|
||||||
CountdownStarted = startCountdown;
|
CountdownStarted = startCountdown;
|
||||||
server.CreateEntityEvent(this);
|
GameMain.Server.CreateEntityEvent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CountdownStarted) return;
|
if (!CountdownStarted) return;
|
||||||
@@ -80,7 +75,7 @@ namespace Barotrauma.Networking
|
|||||||
respawnTimer -= deltaTime;
|
respawnTimer -= deltaTime;
|
||||||
if (respawnTimer <= 0.0f)
|
if (respawnTimer <= 0.0f)
|
||||||
{
|
{
|
||||||
respawnTimer = server.ServerSettings.RespawnInterval;
|
respawnTimer = GameMain.Server.ServerSettings.RespawnInterval;
|
||||||
|
|
||||||
DispatchShuttle();
|
DispatchShuttle();
|
||||||
}
|
}
|
||||||
@@ -98,13 +93,10 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
partial void DispatchShuttle()
|
partial void DispatchShuttle()
|
||||||
{
|
{
|
||||||
var server = networkMember as GameServer;
|
|
||||||
if (server == null) return;
|
|
||||||
|
|
||||||
if (respawnShuttle != null)
|
if (respawnShuttle != null)
|
||||||
{
|
{
|
||||||
state = State.Transporting;
|
state = State.Transporting;
|
||||||
server.CreateEntityEvent(this);
|
GameMain.Server.CreateEntityEvent(this);
|
||||||
|
|
||||||
ResetShuttle();
|
ResetShuttle();
|
||||||
|
|
||||||
@@ -124,17 +116,78 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
state = State.Waiting;
|
state = State.Waiting;
|
||||||
GameServer.Log("Respawning everyone in main sub.", ServerLog.MessageType.Spawning);
|
GameServer.Log("Respawning everyone in main sub.", ServerLog.MessageType.Spawning);
|
||||||
server.CreateEntityEvent(this);
|
GameMain.Server.CreateEntityEvent(this);
|
||||||
|
|
||||||
RespawnCharacters();
|
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<DockingPort>() != null);
|
||||||
|
dockingPorts.ForEach(d => d.GetComponent<DockingPort>().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()
|
partial void RespawnCharactersProjSpecific()
|
||||||
{
|
{
|
||||||
var server = networkMember as GameServer;
|
|
||||||
if (server == null) return;
|
|
||||||
|
|
||||||
var respawnSub = respawnShuttle ?? Submarine.MainSub;
|
var respawnSub = respawnShuttle ?? Submarine.MainSub;
|
||||||
|
|
||||||
var clients = GetClientsToRespawn();
|
var clients = GetClientsToRespawn();
|
||||||
@@ -150,7 +203,7 @@ namespace Barotrauma.Networking
|
|||||||
var botsToSpawn = GetBotsToRespawn();
|
var botsToSpawn = GetBotsToRespawn();
|
||||||
characterInfos.AddRange(botsToSpawn);
|
characterInfos.AddRange(botsToSpawn);
|
||||||
|
|
||||||
server.AssignJobs(clients);
|
GameMain.Server.AssignJobs(clients);
|
||||||
foreach (Client c in clients)
|
foreach (Client c in clients)
|
||||||
{
|
{
|
||||||
c.CharacterInfo.Job = new Job(c.AssignedJob);
|
c.CharacterInfo.Job = new Job(c.AssignedJob);
|
||||||
@@ -241,7 +294,6 @@ namespace Barotrauma.Networking
|
|||||||
item.Description = shuttleSpawnPoints[i].IdCardDesc;
|
item.Description = shuttleSpawnPoints[i].IdCardDesc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -236,8 +236,8 @@ namespace Barotrauma.Networking
|
|||||||
TraitorsEnabled = traitorsEnabled;
|
TraitorsEnabled = traitorsEnabled;
|
||||||
GameMain.NetLobbyScreen.SetTraitorsEnabled(traitorsEnabled);
|
GameMain.NetLobbyScreen.SetTraitorsEnabled(traitorsEnabled);
|
||||||
|
|
||||||
var botSpawnMode = BotSpawnMode.Fill;
|
var botSpawnMode = BotSpawnMode.Normal;
|
||||||
Enum.TryParse(doc.Root.GetAttributeString("BotSpawnMode", "Fill"), out botSpawnMode);
|
Enum.TryParse(doc.Root.GetAttributeString("BotSpawnMode", "Normal"), out botSpawnMode);
|
||||||
BotSpawnMode = botSpawnMode;
|
BotSpawnMode = botSpawnMode;
|
||||||
|
|
||||||
//"65-90", "97-122", "48-59" = upper and lower case english alphabet and numbers
|
//"65-90", "97-122", "48-59" = upper and lower case english alphabet and numbers
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -2306,11 +2306,16 @@
|
|||||||
<None Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialOutpost.sub">
|
<None Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialOutpost.sub">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="$(MSBuildThisFileDirectory)MonoKickstart_LICENSE">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Include="$(MSBuildThisFileDirectory)OpenALSoft_LICENSE">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<None Include="$(MSBuildThisFileDirectory)Submarines\Berilia.sub">
|
<None Include="$(MSBuildThisFileDirectory)Submarines\Berilia.sub">
|
||||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="$(MSBuildThisFileDirectory)Submarines\Dugong_Tutorial.sub">
|
<None Include="$(MSBuildThisFileDirectory)Submarines\Dugong_Tutorial.sub">
|
||||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
|
||||||
</None>
|
</None>
|
||||||
<None Include="$(MSBuildThisFileDirectory)Submarines\TutorialOutpost.sub" />
|
<None Include="$(MSBuildThisFileDirectory)Submarines\TutorialOutpost.sub" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -3448,7 +3453,6 @@
|
|||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="$(MSBuildThisFileDirectory)Submarines\Muikku.sub">
|
<None Include="$(MSBuildThisFileDirectory)Submarines\Muikku.sub">
|
||||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
|
||||||
</None>
|
</None>
|
||||||
<None Include="$(MSBuildThisFileDirectory)Submarines\Orca.sub">
|
<None Include="$(MSBuildThisFileDirectory)Submarines\Orca.sub">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
|||||||
@@ -22,6 +22,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private float soundRange;
|
private float soundRange;
|
||||||
private float sightRange;
|
private float sightRange;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How long does it take for the ai target to fade out if not kept alive.
|
||||||
|
/// </summary>
|
||||||
|
public float FadeOutTime { get; private set; } = 3;
|
||||||
|
|
||||||
public float SoundRange
|
public float SoundRange
|
||||||
{
|
{
|
||||||
@@ -121,6 +126,7 @@ namespace Barotrauma
|
|||||||
MinSoundRange = element.GetAttributeFloat("minsoundrange", SoundRange);
|
MinSoundRange = element.GetAttributeFloat("minsoundrange", SoundRange);
|
||||||
MaxSightRange = element.GetAttributeFloat("maxsightrange", SightRange);
|
MaxSightRange = element.GetAttributeFloat("maxsightrange", SightRange);
|
||||||
MaxSoundRange = element.GetAttributeFloat("maxsoundrange", SoundRange);
|
MaxSoundRange = element.GetAttributeFloat("maxsoundrange", SoundRange);
|
||||||
|
FadeOutTime = element.GetAttributeFloat("fadeouttime", FadeOutTime);
|
||||||
SonarLabel = element.GetAttributeString("sonarlabel", "");
|
SonarLabel = element.GetAttributeString("sonarlabel", "");
|
||||||
string typeString = element.GetAttributeString("type", "Any");
|
string typeString = element.GetAttributeString("type", "Any");
|
||||||
if (Enum.TryParse(typeString, out TargetType t))
|
if (Enum.TryParse(typeString, out TargetType t))
|
||||||
|
|||||||
@@ -435,7 +435,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (gap.Submarine != Character.Submarine) { continue; }
|
if (gap.Submarine != Character.Submarine) { continue; }
|
||||||
if (gap.Open < 1 || gap.IsRoomToRoom) { 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 (!path.Unreachable)
|
||||||
{
|
{
|
||||||
if (escapePoint != Vector2.Zero)
|
if (escapePoint != Vector2.Zero)
|
||||||
@@ -1182,7 +1182,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else if (target.Entity != null)
|
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; }
|
if (character.CurrentHull != null && target.Entity is Hull) { continue; }
|
||||||
|
|
||||||
Door door = null;
|
Door door = null;
|
||||||
@@ -1203,6 +1203,12 @@ namespace Barotrauma
|
|||||||
break;
|
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)
|
else if (target.Entity is Structure s)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -154,6 +154,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
currentTarget = target;
|
currentTarget = target;
|
||||||
Vector2 pos = host.SimPosition;
|
Vector2 pos = host.SimPosition;
|
||||||
|
// TODO: remove this and handle differently?
|
||||||
if (character != null && character.Submarine == null)
|
if (character != null && character.Submarine == null)
|
||||||
{
|
{
|
||||||
var targetHull = Hull.FindHull(FarseerPhysics.ConvertUnits.ToDisplayUnits(target), null, false);
|
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;
|
bool useNewPath = currentPath == null || needsNewPath;
|
||||||
if (!useNewPath && currentPath != null && currentPath.CurrentNode != null && newPath.Nodes.Any() && !newPath.Unreachable)
|
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)
|
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;
|
float penalty = 0.0f;
|
||||||
if (nextNode.Waypoint.ConnectedGap != null && nextNode.Waypoint.ConnectedGap.Open < 0.9f)
|
if (nextNode.Waypoint.ConnectedGap != null && nextNode.Waypoint.ConnectedGap.Open < 0.9f)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -215,11 +215,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected virtual void OnCompleted()
|
protected virtual void OnCompleted()
|
||||||
{
|
{
|
||||||
if (Completed != null)
|
Completed?.Invoke();
|
||||||
{
|
//if (Completed != null)
|
||||||
Completed();
|
//{
|
||||||
Completed = null;
|
// Completed();
|
||||||
}
|
// Completed = null;
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Reset() { }
|
public virtual void Reset() { }
|
||||||
|
|||||||
@@ -181,8 +181,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (closeEnough)
|
if (closeEnough)
|
||||||
{
|
{
|
||||||
character.AIController.SteeringManager.Reset();
|
OnCompleted();
|
||||||
character.AnimController.TargetDir = Target.WorldPosition.X > character.WorldPosition.X ? Direction.Right : Direction.Left;
|
|
||||||
}
|
}
|
||||||
return false;
|
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;
|
return isCompleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,5 +217,15 @@ namespace Barotrauma
|
|||||||
float interactionDistance = Target is Item i ? i.InteractDistance * 0.9f : 0;
|
float interactionDistance = Target is Item i ? i.InteractDistance * 0.9f : 0;
|
||||||
CloseEnough = Math.Max(interactionDistance, CloseEnough);
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ namespace Barotrauma
|
|||||||
bool isRoomNameFound = currentTarget.DisplayName != null;
|
bool isRoomNameFound = currentTarget.DisplayName != null;
|
||||||
errorMsg = "(Character " + character.Name + " idling, target " + (isRoomNameFound ? currentTarget.DisplayName : currentTarget.ToString()) + ")";
|
errorMsg = "(Character " + character.Name + " idling, target " + (isRoomNameFound ? currentTarget.DisplayName : currentTarget.ToString()) + ")";
|
||||||
#endif
|
#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);
|
PathSteering.SetPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (targetCharacterName == null) targetCharacterName = "";
|
if (targetCharacterName == null) targetCharacterName = "";
|
||||||
if (targetRoomName == null) targetRoomName = "";
|
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 "";
|
if (msg == null) return "";
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
|
|||||||
@@ -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;
|
float closestDist = 0.0f;
|
||||||
PathNode startNode = null;
|
PathNode startNode = null;
|
||||||
foreach (PathNode node in nodes)
|
foreach (PathNode node in nodes)
|
||||||
{
|
{
|
||||||
Vector2 nodePos = node.Position;
|
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 xDiff = Math.Abs(start.X - nodePos.X);
|
||||||
float yDiff = Math.Abs(start.Y - nodePos.Y);
|
float yDiff = Math.Abs(start.Y - nodePos.Y);
|
||||||
@@ -185,7 +190,7 @@ namespace Barotrauma
|
|||||||
if (insideSubmarine)
|
if (insideSubmarine)
|
||||||
{
|
{
|
||||||
var body = Submarine.PickBody(
|
var body = Submarine.PickBody(
|
||||||
start, node.Waypoint.SimPosition, null,
|
start, nodePos, null,
|
||||||
Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionStairs);
|
Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionStairs);
|
||||||
|
|
||||||
if (body != null)
|
if (body != null)
|
||||||
@@ -215,7 +220,11 @@ namespace Barotrauma
|
|||||||
foreach (PathNode node in nodes)
|
foreach (PathNode node in nodes)
|
||||||
{
|
{
|
||||||
Vector2 nodePos = node.Position;
|
Vector2 nodePos = node.Position;
|
||||||
|
if (hostSub != null)
|
||||||
|
{
|
||||||
|
Vector2 diff = hostSub.SimPosition - node.Waypoint.Submarine.SimPosition;
|
||||||
|
nodePos -= diff;
|
||||||
|
}
|
||||||
float dist = Vector2.DistanceSquared(end, nodePos);
|
float dist = Vector2.DistanceSquared(end, nodePos);
|
||||||
if (insideSubmarine)
|
if (insideSubmarine)
|
||||||
{
|
{
|
||||||
@@ -229,7 +238,7 @@ namespace Barotrauma
|
|||||||
//if searching for a path inside the sub, make sure the waypoint is visible
|
//if searching for a path inside the sub, make sure the waypoint is visible
|
||||||
if (insideSubmarine)
|
if (insideSubmarine)
|
||||||
{
|
{
|
||||||
var body = Submarine.PickBody(end, node.Waypoint.SimPosition, null,
|
var body = Submarine.PickBody(end, nodePos, null,
|
||||||
Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionStairs );
|
Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionStairs );
|
||||||
|
|
||||||
if (body != null)
|
if (body != null)
|
||||||
@@ -237,7 +246,6 @@ namespace Barotrauma
|
|||||||
//if (body.UserData is Submarine) continue;
|
//if (body.UserData is Submarine) continue;
|
||||||
if (body.UserData is Structure && !((Structure)body.UserData).IsPlatform) continue;
|
if (body.UserData is Structure && !((Structure)body.UserData).IsPlatform) continue;
|
||||||
if (body.UserData is Item && body.FixtureList[0].CollisionCategories.HasFlag(Physics.CollisionWall)) continue;
|
if (body.UserData is Item && body.FixtureList[0].CollisionCategories.HasFlag(Physics.CollisionWall)) continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2030,6 +2030,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
//Do ragdoll shenanigans before Stun because it's still technically a stun, innit? Less network updates for us!
|
//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 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)
|
if (IsForceRagdolled)
|
||||||
{
|
{
|
||||||
IsRagdolled = IsForceRagdolled;
|
IsRagdolled = IsForceRagdolled;
|
||||||
@@ -2039,7 +2044,7 @@ namespace Barotrauma
|
|||||||
IsRagdolled = IsKeyDown(InputType.Ragdoll);
|
IsRagdolled = IsKeyDown(InputType.Ragdoll);
|
||||||
}
|
}
|
||||||
//Keep us ragdolled if we were forced or we're too speedy to unragdoll
|
//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)
|
if (ragdollingLockTimer > 0.0f)
|
||||||
{
|
{
|
||||||
@@ -2589,7 +2594,7 @@ namespace Barotrauma
|
|||||||
if (info != null) { info.Remove(); }
|
if (info != null) { info.Remove(); }
|
||||||
|
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
|
GameMain.GameSession?.CrewManager?.KillCharacter(this);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CharacterList.Remove(this);
|
CharacterList.Remove(this);
|
||||||
|
|||||||
@@ -89,6 +89,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static void StopCoroutines(string name)
|
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);
|
Coroutines.RemoveAll(c => c.Name == name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,31 +107,42 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static void ExecuteCoroutineThread(CoroutineHandle handle)
|
public static void ExecuteCoroutineThread(CoroutineHandle handle)
|
||||||
{
|
{
|
||||||
while (true)
|
try
|
||||||
{
|
{
|
||||||
if (handle.Coroutine.Current != null)
|
while (true)
|
||||||
{
|
{
|
||||||
WaitForSeconds wfs = handle.Coroutine.Current as WaitForSeconds;
|
if (handle.Coroutine.Current != null)
|
||||||
if (wfs != null)
|
|
||||||
{
|
{
|
||||||
Thread.Sleep((int)(wfs.TotalTime * 1000));
|
WaitForSeconds wfs = handle.Coroutine.Current as WaitForSeconds;
|
||||||
}
|
if (wfs != null)
|
||||||
else
|
|
||||||
{
|
|
||||||
switch ((CoroutineStatus)handle.Coroutine.Current)
|
|
||||||
{
|
{
|
||||||
case CoroutineStatus.Success:
|
Thread.Sleep((int)(wfs.TotalTime * 1000));
|
||||||
return;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch ((CoroutineStatus)handle.Coroutine.Current)
|
||||||
|
{
|
||||||
|
case CoroutineStatus.Success:
|
||||||
|
return;
|
||||||
|
|
||||||
case CoroutineStatus.Failure:
|
case CoroutineStatus.Failure:
|
||||||
DebugConsole.ThrowError("Coroutine \"" + handle.Name + "\" has failed");
|
DebugConsole.ThrowError("Coroutine \"" + handle.Name + "\" has failed");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Thread.Yield();
|
Thread.Yield();
|
||||||
if (!handle.Coroutine.MoveNext()) return;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ namespace Barotrauma
|
|||||||
List<Vector2> positions = new List<Vector2>();
|
List<Vector2> positions = new List<Vector2>();
|
||||||
foreach (var allowedPosition in availablePositions)
|
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());
|
positions.Add(allowedPosition.Position.ToVector2());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace Barotrauma
|
|||||||
public float GetAverageElapsedMillisecs(string identifier)
|
public float GetAverageElapsedMillisecs(string identifier)
|
||||||
{
|
{
|
||||||
if (!avgTicksPerFrame.ContainsKey(identifier)) return 0.0f;
|
if (!avgTicksPerFrame.ContainsKey(identifier)) return 0.0f;
|
||||||
return avgTicksPerFrame[identifier] / TimeSpan.TicksPerMillisecond;
|
return avgTicksPerFrame[identifier] / (float)TimeSpan.TicksPerMillisecond;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Update(double deltaTime)
|
public bool Update(double deltaTime)
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (item.GetComponent<Items.Components.Repairable>() != null)
|
if (item.GetComponent<Items.Components.Repairable>() != 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"));
|
Level.Loaded.Seed + (outpost == Level.Loaded.StartOutpost ? "start" : "end"));
|
||||||
InitializeWatchman(spawnedCharacter);
|
InitializeWatchman(spawnedCharacter);
|
||||||
var objectiveManager = (spawnedCharacter.AIController as HumanAIController)?.ObjectiveManager;
|
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)
|
if (watchmanJob != null)
|
||||||
{
|
{
|
||||||
spawnedCharacter.GiveJobItems();
|
spawnedCharacter.GiveJobItems();
|
||||||
|
|||||||
@@ -241,6 +241,14 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var sub in Submarine.Loaded)
|
||||||
|
{
|
||||||
|
if (sub.IsOutpost)
|
||||||
|
{
|
||||||
|
sub.DisableObstructedWayPoints();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Entity.Spawner = new EntitySpawner();
|
Entity.Spawner = new EntitySpawner();
|
||||||
|
|
||||||
if (GameMode.Mission != null) Mission = GameMode.Mission;
|
if (GameMode.Mission != null) Mission = GameMode.Mission;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
public partial class GameSettings
|
public partial class GameSettings
|
||||||
{
|
{
|
||||||
const string savePath = "config.xml";
|
const string savePath = "config.xml";
|
||||||
const string playerSavePath = "config_player.xml";
|
const string playerSavePath = "config_player.xml";
|
||||||
const string vanillaContentPackagePath = "Data/ContentPackages/Vanilla";
|
const string vanillaContentPackagePath = "Data/ContentPackages/Vanilla";
|
||||||
@@ -43,9 +43,9 @@ namespace Barotrauma
|
|||||||
public bool SpecularityEnabled { get; set; }
|
public bool SpecularityEnabled { get; set; }
|
||||||
public bool ChromaticAberrationEnabled { 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 MuteOnFocusLost { get; set; }
|
||||||
public bool UseDirectionalVoiceChat { get; set; } = true;
|
public bool UseDirectionalVoiceChat { get; set; }
|
||||||
|
|
||||||
public enum VoiceMode
|
public enum VoiceMode
|
||||||
{
|
{
|
||||||
@@ -57,7 +57,7 @@ namespace Barotrauma
|
|||||||
public VoiceMode VoiceSetting { get; set; }
|
public VoiceMode VoiceSetting { get; set; }
|
||||||
public string VoiceCaptureDevice { get; set; }
|
public string VoiceCaptureDevice { get; set; }
|
||||||
|
|
||||||
public float NoiseGateThreshold { get; set; } = -45;
|
public float NoiseGateThreshold { get; set; }
|
||||||
|
|
||||||
private KeyOrMouse[] keyMapping;
|
private KeyOrMouse[] keyMapping;
|
||||||
|
|
||||||
@@ -69,12 +69,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool useSteamMatchmaking;
|
private bool useSteamMatchmaking;
|
||||||
private bool requireSteamAuthentication;
|
private bool requireSteamAuthentication;
|
||||||
|
public string QuickStartSubmarineName;
|
||||||
public string QuickStartSubmarineName
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
//steam functionality can be enabled/disabled in debug builds
|
//steam functionality can be enabled/disabled in debug builds
|
||||||
@@ -126,7 +121,7 @@ namespace Barotrauma
|
|||||||
set { jobPreferences = value; }
|
set { jobPreferences = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public int CharacterHeadIndex { get; set; } = 1;
|
public int CharacterHeadIndex { get; set; }
|
||||||
public int CharacterHairIndex { get; set; }
|
public int CharacterHairIndex { get; set; }
|
||||||
public int CharacterBeardIndex { get; set; }
|
public int CharacterBeardIndex { get; set; }
|
||||||
public int CharacterMoustacheIndex { get; set; }
|
public int CharacterMoustacheIndex { get; set; }
|
||||||
@@ -160,7 +155,6 @@ namespace Barotrauma
|
|||||||
#if CLIENT
|
#if CLIENT
|
||||||
if (applyButton != null)
|
if (applyButton != null)
|
||||||
{
|
{
|
||||||
//applyButton.Selected = unsavedSettings;
|
|
||||||
applyButton.Enabled = unsavedSettings;
|
applyButton.Enabled = unsavedSettings;
|
||||||
applyButton.Text = TextManager.Get(unsavedSettings ? "ApplySettingsButtonUnsavedChanges" : "ApplySettingsButton");
|
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
|
public float SoundVolume
|
||||||
{
|
{
|
||||||
@@ -229,9 +223,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private HashSet<string> selectedContentPackagePaths = new HashSet<string>();
|
private HashSet<string> selectedContentPackagePaths = new HashSet<string>();
|
||||||
|
|
||||||
public string MasterServerUrl { get; set; }
|
public string MasterServerUrl { get; set; }
|
||||||
public bool AutoCheckUpdates { get; set; }
|
public bool AutoCheckUpdates { get; set; }
|
||||||
public bool WasGameUpdated { get; set; }
|
public bool WasGameUpdated { get; set; }
|
||||||
|
|
||||||
private string defaultPlayerName;
|
private string defaultPlayerName;
|
||||||
public string DefaultPlayerName
|
public string DefaultPlayerName
|
||||||
@@ -256,9 +250,9 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
private const float MinHUDScale = 0.75f, MaxHUDScale = 1.25f;
|
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;
|
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<string> CompletedTutorialNames { get; private set; }
|
public List<string> CompletedTutorialNames { get; private set; }
|
||||||
|
|
||||||
@@ -267,7 +261,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public bool CampaignDisclaimerShown, EditorDisclaimerShown;
|
public bool CampaignDisclaimerShown, EditorDisclaimerShown;
|
||||||
|
|
||||||
private static bool sendUserStatistics;
|
private static bool sendUserStatistics = true;
|
||||||
public static bool SendUserStatistics
|
public static bool SendUserStatistics
|
||||||
{
|
{
|
||||||
get { return sendUserStatistics; }
|
get { return sendUserStatistics; }
|
||||||
@@ -353,13 +347,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (doc != null)
|
if (doc != null)
|
||||||
{
|
{
|
||||||
foreach (XElement subElement in doc.Root.Elements())
|
LoadControls(doc);
|
||||||
{
|
|
||||||
if (subElement.Name.ToString().ToLowerInvariant() == "keymapping")
|
|
||||||
{
|
|
||||||
LoadKeyBinds(subElement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,35 +403,15 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Load DefaultConfig
|
|
||||||
private void LoadDefaultConfig(bool setLanguage = true)
|
private void LoadDefaultConfig(bool setLanguage = true)
|
||||||
{
|
{
|
||||||
XDocument doc = XMLExtensions.TryLoadXml(savePath);
|
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)
|
if (doc == null)
|
||||||
{
|
{
|
||||||
GraphicsWidth = 1024;
|
GraphicsWidth = 1024;
|
||||||
GraphicsHeight = 678;
|
GraphicsHeight = 768;
|
||||||
|
|
||||||
MasterServerUrl = "";
|
MasterServerUrl = "";
|
||||||
|
|
||||||
SelectedContentPackages.Add(ContentPackage.List.Any() ? ContentPackage.List[0] : new ContentPackage(""));
|
SelectedContentPackages.Add(ContentPackage.List.Any() ? ContentPackage.List[0] : new ContentPackage(""));
|
||||||
|
|
||||||
jobPreferences = new List<string>();
|
jobPreferences = new List<string>();
|
||||||
foreach (JobPrefab job in JobPrefab.List)
|
foreach (JobPrefab job in JobPrefab.List)
|
||||||
{
|
{
|
||||||
@@ -452,158 +420,24 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
XElement graphicsMode = doc.Root.Element("graphicsmode");
|
bool resetLanguage = setLanguage || string.IsNullOrEmpty(Language);
|
||||||
GraphicsWidth = 0;
|
SetDefaultValues(resetLanguage);
|
||||||
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);
|
|
||||||
|
|
||||||
SetDefaultBindings(doc, legacy: false);
|
SetDefaultBindings(doc, legacy: false);
|
||||||
|
|
||||||
foreach (XElement subElement in doc.Root.Elements())
|
MasterServerUrl = doc.Root.GetAttributeString("masterserverurl", MasterServerUrl);
|
||||||
{
|
WasGameUpdated = doc.Root.GetAttributeBool("wasgameupdated", WasGameUpdated);
|
||||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
VerboseLogging = doc.Root.GetAttributeBool("verboselogging", VerboseLogging);
|
||||||
{
|
SaveDebugConsoleLogs = doc.Root.GetAttributeBool("savedebugconsolelogs", SaveDebugConsoleLogs);
|
||||||
case "keymapping":
|
AutoUpdateWorkshopItems = doc.Root.GetAttributeBool("autoupdateworkshopitems", AutoUpdateWorkshopItems);
|
||||||
LoadKeyBinds(subElement);
|
|
||||||
break;
|
|
||||||
case "gameplay":
|
|
||||||
jobPreferences = new List<string>();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<string> missingPackagePaths = new List<string>();
|
LoadGeneralSettings(doc, resetLanguage);
|
||||||
List<ContentPackage> incompatiblePackages = new List<ContentPackage>();
|
LoadGraphicSettings(doc);
|
||||||
foreach (XElement subElement in doc.Root.Elements())
|
LoadAudioSettings(doc);
|
||||||
{
|
LoadControls(doc);
|
||||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
LoadContentPackages(doc);
|
||||||
{
|
UnsavedSettings = false;
|
||||||
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<string> 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(); }
|
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Save DefaultConfig
|
|
||||||
private void SaveNewDefaultConfig()
|
private void SaveNewDefaultConfig()
|
||||||
{
|
{
|
||||||
XDocument doc = new XDocument();
|
XDocument doc = new XDocument();
|
||||||
@@ -619,6 +453,7 @@ namespace Barotrauma
|
|||||||
new XAttribute("autocheckupdates", AutoCheckUpdates),
|
new XAttribute("autocheckupdates", AutoCheckUpdates),
|
||||||
new XAttribute("musicvolume", musicVolume),
|
new XAttribute("musicvolume", musicVolume),
|
||||||
new XAttribute("soundvolume", soundVolume),
|
new XAttribute("soundvolume", soundVolume),
|
||||||
|
new XAttribute("microphonevolume", microphoneVolume),
|
||||||
new XAttribute("voicechatvolume", voiceChatVolume),
|
new XAttribute("voicechatvolume", voiceChatVolume),
|
||||||
new XAttribute("verboselogging", VerboseLogging),
|
new XAttribute("verboselogging", VerboseLogging),
|
||||||
new XAttribute("savedebugconsolelogs", SaveDebugConsoleLogs),
|
new XAttribute("savedebugconsolelogs", SaveDebugConsoleLogs),
|
||||||
@@ -637,7 +472,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
doc.Root.Add(new XAttribute("wasgameupdated", true));
|
doc.Root.Add(new XAttribute("wasgameupdated", true));
|
||||||
}
|
}
|
||||||
|
|
||||||
XElement gMode = doc.Root.Element("graphicsmode");
|
XElement gMode = doc.Root.Element("graphicsmode");
|
||||||
if (gMode == null)
|
if (gMode == null)
|
||||||
{
|
{
|
||||||
@@ -738,7 +573,6 @@ namespace Barotrauma
|
|||||||
"Saving game settings failed.\n" + e.Message + "\n" + e.StackTrace);
|
"Saving game settings failed.\n" + e.Message + "\n" + e.StackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Load PlayerConfig
|
#region Load PlayerConfig
|
||||||
public void LoadPlayerConfig()
|
public void LoadPlayerConfig()
|
||||||
@@ -760,143 +594,27 @@ namespace Barotrauma
|
|||||||
private bool LoadPlayerConfigInternal()
|
private bool LoadPlayerConfigInternal()
|
||||||
{
|
{
|
||||||
XDocument doc = XMLExtensions.LoadXml(playerSavePath);
|
XDocument doc = XMLExtensions.LoadXml(playerSavePath);
|
||||||
|
|
||||||
if (doc == null || doc.Root == null)
|
if (doc == null || doc.Root == null)
|
||||||
{
|
{
|
||||||
ShowUserStatisticsPrompt = true;
|
ShowUserStatisticsPrompt = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
LoadGeneralSettings(doc);
|
||||||
|
LoadGraphicSettings(doc);
|
||||||
|
LoadAudioSettings(doc);
|
||||||
|
LoadControls(doc);
|
||||||
|
LoadContentPackages(doc);
|
||||||
|
|
||||||
Language = doc.Root.GetAttributeString("language", Language);
|
XElement tutorialsElement = doc.Root.Element("tutorials");
|
||||||
AutoCheckUpdates = doc.Root.GetAttributeBool("autocheckupdates", AutoCheckUpdates);
|
if (tutorialsElement != null)
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
losMode = LosMode.Transparent;
|
foreach (XElement element in tutorialsElement.Elements())
|
||||||
}
|
|
||||||
|
|
||||||
#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))
|
|
||||||
{
|
{
|
||||||
VoiceSetting = voiceSetting;
|
CompletedTutorialNames.Add(element.GetAttributeString("name", ""));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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<string>();
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UnsavedSettings = false;
|
UnsavedSettings = false;
|
||||||
|
|
||||||
selectedContentPackagePaths = new HashSet<string>();
|
|
||||||
|
|
||||||
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -957,7 +675,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
foreach (ContentPackage incompatiblePackage in incompatiblePackages)
|
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() }));
|
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("vsync", VSyncEnabled),
|
||||||
new XAttribute("displaymode", windowMode));
|
new XAttribute("displaymode", windowMode));
|
||||||
}
|
}
|
||||||
|
|
||||||
XElement audio = doc.Root.Element("audio");
|
XElement audio = doc.Root.Element("audio");
|
||||||
if (audio == null)
|
if (audio == null)
|
||||||
{
|
{
|
||||||
@@ -1048,6 +766,8 @@ namespace Barotrauma
|
|||||||
audio.ReplaceAttributes(
|
audio.ReplaceAttributes(
|
||||||
new XAttribute("musicvolume", musicVolume),
|
new XAttribute("musicvolume", musicVolume),
|
||||||
new XAttribute("soundvolume", soundVolume),
|
new XAttribute("soundvolume", soundVolume),
|
||||||
|
new XAttribute("voicechatvolume", voiceChatVolume),
|
||||||
|
new XAttribute("microphonevolume", microphoneVolume),
|
||||||
new XAttribute("muteonfocuslost", MuteOnFocusLost),
|
new XAttribute("muteonfocuslost", MuteOnFocusLost),
|
||||||
new XAttribute("usedirectionalvoicechat", UseDirectionalVoiceChat),
|
new XAttribute("usedirectionalvoicechat", UseDirectionalVoiceChat),
|
||||||
new XAttribute("voicesetting", VoiceSetting),
|
new XAttribute("voicesetting", VoiceSetting),
|
||||||
@@ -1153,12 +873,149 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
#endregion
|
#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<string>();
|
||||||
|
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<string>();
|
||||||
|
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)
|
private void LoadKeyBinds(XElement element)
|
||||||
{
|
{
|
||||||
foreach (XAttribute attribute in element.Attributes())
|
foreach (XAttribute attribute in element.Attributes())
|
||||||
{
|
{
|
||||||
if (!Enum.TryParse(attribute.Name.ToString(), true, out InputType inputType)) { continue; }
|
if (!Enum.TryParse(attribute.Name.ToString(), true, out InputType inputType)) { continue; }
|
||||||
|
|
||||||
if (int.TryParse(attribute.Value.ToString(), out int mouseButton))
|
if (int.TryParse(attribute.Value.ToString(), out int mouseButton))
|
||||||
{
|
{
|
||||||
keyMapping[(int)inputType] = new KeyOrMouse(mouseButton);
|
keyMapping[(int)inputType] = new KeyOrMouse(mouseButton);
|
||||||
@@ -1169,7 +1026,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
keyMapping[(int)inputType] = new KeyOrMouse(key);
|
keyMapping[(int)inputType] = new KeyOrMouse(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1184,5 +1041,62 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
return keyMapping[(int)inputType];
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ namespace Barotrauma.Items.Components
|
|||||||
private Body doorBody;
|
private Body doorBody;
|
||||||
|
|
||||||
private bool docked;
|
private bool docked;
|
||||||
|
private bool obstructedWayPointsDisabled;
|
||||||
|
|
||||||
private float forceLockTimer;
|
private float forceLockTimer;
|
||||||
//if the submarine isn't in the correct position to lock within this time after docking has been activated,
|
//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;
|
bodies = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item.Submarine.EnableObstructedWaypoints();
|
||||||
|
obstructedWayPointsDisabled = false;
|
||||||
|
|
||||||
#if SERVER
|
#if SERVER
|
||||||
if (GameMain.Server != null)
|
if (GameMain.Server != null)
|
||||||
{
|
{
|
||||||
@@ -813,6 +817,11 @@ namespace Barotrauma.Items.Components
|
|||||||
dockingState = MathHelper.Lerp(dockingState, 1.0f, deltaTime * 10.0f);
|
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()
|
protected override void RemoveComponentSpecific()
|
||||||
@@ -983,6 +992,5 @@ namespace Barotrauma.Items.Components
|
|||||||
Undock();
|
Undock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -413,7 +413,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
target = ConvertUnits.ToSimUnits(Level.Loaded.StartPosition);
|
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()
|
public void SetDestinationLevelStart()
|
||||||
|
|||||||
@@ -174,6 +174,12 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
private void Launch(Vector2 impulse)
|
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.Drop(null);
|
||||||
|
|
||||||
item.body.Enabled = true;
|
item.body.Enabled = true;
|
||||||
|
|||||||
@@ -122,6 +122,16 @@ namespace Barotrauma.Items.Components
|
|||||||
Update(deltaTime, cam);
|
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)
|
public override void Update(float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
UpdateProjSpecific(deltaTime);
|
UpdateProjSpecific(deltaTime);
|
||||||
|
|||||||
@@ -338,9 +338,15 @@ namespace Barotrauma.Items.Components
|
|||||||
canPlaceNode = true;
|
canPlaceNode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector2 relativeNodePos = newNodePos - item.Position;
|
||||||
|
if (sub != null)
|
||||||
|
{
|
||||||
|
relativeNodePos += sub.HiddenSubPosition;
|
||||||
|
}
|
||||||
|
|
||||||
sectionExtents = new Vector2(
|
sectionExtents = new Vector2(
|
||||||
Math.Max(Math.Abs((newNodePos.X + sub.HiddenSubPosition.X) - item.Position.X), sectionExtents.X),
|
Math.Max(Math.Abs(relativeNodePos.X), sectionExtents.X),
|
||||||
Math.Max(Math.Abs((newNodePos.Y + sub.HiddenSubPosition.Y) - item.Position.Y), sectionExtents.Y));
|
Math.Max(Math.Abs(relativeNodePos.Y), sectionExtents.Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Use(float deltaTime, Character character = null)
|
public override bool Use(float deltaTime, Character character = null)
|
||||||
|
|||||||
@@ -286,6 +286,23 @@ namespace Barotrauma.Items.Components
|
|||||||
if (!equipLimb.WearingItems.Contains(wearableSprite))
|
if (!equipLimb.WearingItems.Contains(wearableSprite))
|
||||||
{
|
{
|
||||||
equipLimb.WearingItems.Add(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));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1042,8 +1042,8 @@ namespace Barotrauma
|
|||||||
//aitarget goes silent/invisible if the components don't keep it active
|
//aitarget goes silent/invisible if the components don't keep it active
|
||||||
if (aiTarget != null)
|
if (aiTarget != null)
|
||||||
{
|
{
|
||||||
aiTarget.SightRange -= deltaTime * 1000.0f;
|
aiTarget.SightRange -= deltaTime * (aiTarget.MaxSightRange / aiTarget.FadeOutTime);
|
||||||
aiTarget.SoundRange -= deltaTime * 1000.0f;
|
aiTarget.SoundRange -= deltaTime * (aiTarget.MaxSoundRange / aiTarget.FadeOutTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool broken = condition <= 0.0f;
|
bool broken = condition <= 0.0f;
|
||||||
@@ -2017,6 +2017,8 @@ namespace Barotrauma
|
|||||||
if (element.GetAttributeBool("flippedy", false)) item.FlipY(false);
|
if (element.GetAttributeBool("flippedy", false)) item.FlipY(false);
|
||||||
|
|
||||||
item.condition = element.GetAttributeFloat("condition", item.Prefab.Health);
|
item.condition = element.GetAttributeFloat("condition", item.Prefab.Health);
|
||||||
|
item.lastSentCondition = item.condition;
|
||||||
|
|
||||||
item.SetActiveSprite();
|
item.SetActiveSprite();
|
||||||
|
|
||||||
foreach (ItemComponent component in item.components)
|
foreach (ItemComponent component in item.components)
|
||||||
|
|||||||
@@ -1366,6 +1366,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<InterestingPosition> suitablePositions = positionsOfInterest.FindAll(p => positionType.HasFlag(p.PositionType));
|
List<InterestingPosition> 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())
|
if (!suitablePositions.Any())
|
||||||
{
|
{
|
||||||
string errorMsg = "Could not find a suitable position of interest. (PositionType: " + positionType + ", minDistFromSubs: " + minDistFromSubs + ")\n" + Environment.StackTrace;
|
string errorMsg = "Could not find a suitable position of interest. (PositionType: " + positionType + ", minDistFromSubs: " + minDistFromSubs + ")\n" + Environment.StackTrace;
|
||||||
|
|||||||
@@ -1433,7 +1433,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Submarine sub = new Submarine(path);
|
Submarine sub = new Submarine(path);
|
||||||
sub.Load(unloadPrevious);
|
sub.Load(unloadPrevious);
|
||||||
|
|
||||||
return sub;
|
return sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1564,6 +1564,94 @@ namespace Barotrauma
|
|||||||
PreviewImage = null;
|
PreviewImage = null;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<PathNode> outdoorNodes;
|
||||||
|
private List<PathNode> 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<PathNode> obstructedNodes = new HashSet<PathNode>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Permanently disables obstructed waypoints obstructed by the level.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Temporarily disables waypoints obstructed by the other sub.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Only affects temporarily disabled waypoints.
|
||||||
|
/// </summary>
|
||||||
|
public void EnableObstructedWaypoints()
|
||||||
|
{
|
||||||
|
foreach (var node in obstructedNodes)
|
||||||
|
{
|
||||||
|
node.Waypoint.isObstructed = false;
|
||||||
|
}
|
||||||
|
obstructedNodes.Clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ namespace Barotrauma
|
|||||||
public Ladder Ladders;
|
public Ladder Ladders;
|
||||||
public Structure Stairs;
|
public Structure Stairs;
|
||||||
|
|
||||||
|
public bool isObstructed;
|
||||||
|
|
||||||
private ushort gapId;
|
private ushort gapId;
|
||||||
public Gap ConnectedGap
|
public Gap ConnectedGap
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
partial class Client : IDisposable
|
partial class Client : IDisposable
|
||||||
{
|
{
|
||||||
|
public const int MaxNameLength = 20;
|
||||||
|
|
||||||
public string Name;
|
public string Name;
|
||||||
public byte ID;
|
public byte ID;
|
||||||
|
|
||||||
@@ -205,6 +207,21 @@ namespace Barotrauma.Networking
|
|||||||
SetPermissions(permissions, permittedCommands);
|
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()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
DisposeProjSpecific();
|
DisposeProjSpecific();
|
||||||
|
|||||||
@@ -174,8 +174,8 @@ namespace Barotrauma.Networking
|
|||||||
get { return name; }
|
get { return name; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(value)) return;
|
if (string.IsNullOrEmpty(value)) { return; }
|
||||||
name = value;
|
name = value.Replace(":", "").Replace(";", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -158,41 +158,11 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
shuttleTransportTimer -= deltaTime;
|
shuttleTransportTimer -= deltaTime;
|
||||||
|
|
||||||
#if CLIENT
|
UpdateTransportingProjSpecific(deltaTime);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
partial void UpdateTransportingProjSpecific(float deltaTime);
|
||||||
|
|
||||||
private void UpdateReturning(float deltaTime)
|
private void UpdateReturning(float deltaTime)
|
||||||
{
|
{
|
||||||
//if (shuttleReturnTimer == maxTransportTime &&
|
//if (shuttleReturnTimer == maxTransportTime &&
|
||||||
@@ -216,56 +186,13 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
shuttleSteering.SetDestinationLevelStart();
|
shuttleSteering.SetDestinationLevelStart();
|
||||||
}
|
}
|
||||||
|
UpdateReturningProjSpecific();
|
||||||
|
|
||||||
#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<DockingPort>() != null);
|
|
||||||
dockingPorts.ForEach(d => d.GetComponent<DockingPort>().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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void DispatchShuttle();
|
partial void DispatchShuttle();
|
||||||
|
|
||||||
|
partial void UpdateReturningProjSpecific();
|
||||||
|
|
||||||
private IEnumerable<object> ForceShuttleToPos(Vector2 position, float speed)
|
private IEnumerable<object> ForceShuttleToPos(Vector2 position, float speed)
|
||||||
{
|
{
|
||||||
@@ -314,6 +241,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
//restore other items to full condition and recharge batteries
|
//restore other items to full condition and recharge batteries
|
||||||
item.Condition = item.Prefab.Health;
|
item.Condition = item.Prefab.Health;
|
||||||
|
item.GetComponent<Repairable>()?.ResetDeterioration();
|
||||||
var powerContainer = item.GetComponent<PowerContainer>();
|
var powerContainer = item.GetComponent<PowerContainer>();
|
||||||
if (powerContainer != null)
|
if (powerContainer != null)
|
||||||
{
|
{
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user