diff --git a/Barotrauma/BarotraumaClient/MacClient.csproj b/Barotrauma/BarotraumaClient/MacClient.csproj index 29dd488d3..dff098df6 100644 --- a/Barotrauma/BarotraumaClient/MacClient.csproj +++ b/Barotrauma/BarotraumaClient/MacClient.csproj @@ -188,7 +188,61 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs b/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs index 847902e84..864fd5996 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs @@ -264,57 +264,17 @@ namespace Barotrauma partial void ImpactProjSpecific(float impact, Body body) { - float volume = Math.Min(impact - 3.0f, 1.0f); + float volume = MathHelper.Clamp(impact - 3.0f, 0.5f, 1.0f); - partial void UpdateNetPlayerPositionProjSpecific(float deltaTime, float lowestSubPos) - { - if (character != GameMain.Client.Character || !character.AllowInput) + if (body.UserData is Limb limb && character.Stun <= 0f) { - Limb limb = (Limb)body.UserData; - if (impact > 3.0f && limb.LastImpactSoundTime < Timing.TotalTime - Limb.SoundInterval) - { - limb.LastImpactSoundTime = (float)Timing.TotalTime; - if (!string.IsNullOrWhiteSpace(limb.HitSoundTag)) - { - SoundPlayer.PlaySound(limb.HitSoundTag, volume, impact * 100.0f, limb.WorldPosition, character.CurrentHull); - } - - //unconscious/dead characters can't correct their position using AnimController movement - // -> we need to correct it manually - if (!character.AllowInput) - { - float mainLimbDistSqrd = Vector2.DistanceSquared(MainLimb.PullJointWorldAnchorA, Collider.SimPosition); - float mainLimbErrorTolerance = 0.1f; - //if the main limb is roughly at the correct position and the collider isn't moving (much at least), - //don't attempt to correct the position. - if (mainLimbDistSqrd > mainLimbErrorTolerance || Collider.LinearVelocity.LengthSquared() > 0.05f) - { - SoundPlayer.PlaySound(wearable.Sound, volume, impact * 100.0f, limb.WorldPosition, character.CurrentHull); - } - } - } - character.MemLocalState.Clear(); + if (impact > 3.0f) { PlayImpactSound(limb); } } - else + else if (body.UserData is Limb || body == Collider.FarseerBody) { - if (!character.IsRemotePlayer) + if (!character.IsRemotePlayer && impact > ImpactTolerance) { - if (character.Submarine == null) - { - //transform in-sub coordinates to outside coordinates - if (character.MemLocalState[i].Position.Y > lowestSubPos) - { - character.MemLocalState[i].TransformInToOutside(); - } - } - else if (currentHull?.Submarine != null) - { - //transform outside coordinates to in-sub coordinates - if (character.MemLocalState[i].Position.Y < lowestSubPos) - { - character.MemLocalState[i].TransformOutToInside(currentHull.Submarine); - } - } + SoundPlayer.PlayDamageSound("LimbBlunt", strongestImpact, Collider); } } if (Character.Controlled == character) @@ -323,6 +283,29 @@ namespace Barotrauma } } + public void PlayImpactSound(Limb limb) + { + limb.LastImpactSoundTime = (float)Timing.TotalTime; + if (!string.IsNullOrWhiteSpace(limb.HitSoundTag)) + { + bool inWater = limb.inWater; + if (character.CurrentHull != null && + character.CurrentHull.Surface > character.CurrentHull.Rect.Y - character.CurrentHull.Rect.Height && + limb.SimPosition.Y < ConvertUnits.ToSimUnits(character.CurrentHull.Rect.Y - character.CurrentHull.Rect.Height) + limb.body.GetMaxExtent()) + { + inWater = true; + } + SoundPlayer.PlaySound(inWater ? "footstep_water" : limb.HitSoundTag, limb.WorldPosition, hullGuess: character.CurrentHull); + } + foreach (WearableSprite wearable in limb.WearingItems) + { + if (limb.type == wearable.Limb && !string.IsNullOrWhiteSpace(wearable.Sound)) + { + SoundPlayer.PlaySound(wearable.Sound, limb.WorldPosition, hullGuess: character.CurrentHull); + } + } + } + partial void Splash(Limb limb, Hull limbHull) { //create a splash particle @@ -385,6 +368,8 @@ namespace Barotrauma partial void UpdateProjSpecific(float deltaTime) { + if (!character.Enabled || SimplePhysicsEnabled) { return; } + LimbJoints.ForEach(j => j.UpdateDeformations(deltaTime)); foreach (var deformation in SpriteDeformations) { diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Attack.cs b/Barotrauma/BarotraumaClient/Source/Characters/Attack.cs index 7d293d643..3b3626b65 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/Attack.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/Attack.cs @@ -50,7 +50,7 @@ namespace Barotrauma if (sound != null) { - SoundPlayer.PlaySound(sound.Sound, sound.Volume, sound.Range, worldPosition); + SoundPlayer.PlaySound(sound.Sound, worldPosition, sound.Volume, sound.Range); } } } diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Character.cs b/Barotrauma/BarotraumaClient/Source/Characters/Character.cs index e4668eccd..11f6f191c 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/Character.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/Character.cs @@ -731,7 +731,7 @@ namespace Barotrauma var matchingSoundsList = matchingSounds.ToList(); var selectedSound = matchingSoundsList[Rand.Int(matchingSoundsList.Count)]; - soundChannel = SoundPlayer.PlaySound(selectedSound.Sound, selectedSound.Volume, selectedSound.Range, AnimController.WorldPosition, CurrentHull); + soundChannel = SoundPlayer.PlaySound(selectedSound.Sound, AnimController.WorldPosition, selectedSound.Volume, selectedSound.Range, CurrentHull); soundTimer = soundInterval; } diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Health/CharacterHealth.cs b/Barotrauma/BarotraumaClient/Source/Characters/Health/CharacterHealth.cs index 2bcb03cb3..3799e1756 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/Health/CharacterHealth.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/Health/CharacterHealth.cs @@ -1427,6 +1427,8 @@ namespace Barotrauma { foreach (Limb limb in Character.AnimController.Limbs) { + if (limb.HealthIndex < 0 || limb.HealthIndex >= limbHealths.Count) { continue; } + limb.BurnOverlayStrength = 0.0f; limb.DamageOverlayStrength = 0.0f; if (limbHealths[limb.HealthIndex].Afflictions.Count == 0) continue; diff --git a/Barotrauma/BarotraumaClient/Source/DebugConsole.cs b/Barotrauma/BarotraumaClient/Source/DebugConsole.cs index d9b25edd0..a3b0fdc51 100644 --- a/Barotrauma/BarotraumaClient/Source/DebugConsole.cs +++ b/Barotrauma/BarotraumaClient/Source/DebugConsole.cs @@ -377,23 +377,27 @@ namespace Barotrauma GameMain.SubEditorScreen.Select(); })); - commands.Add(new Command("editparticles|particleeditor", "", (string[] args) => + commands.Add(new Command("editparticles|particleeditor", "editparticles/particleeditor: Switch to the Particle Editor to edit particle effects.", (string[] args) => { GameMain.ParticleEditorScreen.Select(); })); - commands.Add(new Command("editlevels|editlevel|leveleditor", "", (string[] args) => + commands.Add(new Command("editlevels|leveleditor", "editlevels/leveleditor: Switch to the Level Editor to edit levels.", (string[] args) => { GameMain.LevelEditorScreen.Select(); })); - commands.Add(new Command("editsprites|editsprite|spriteeditor|spriteedit", "", (string[] args) => + commands.Add(new Command("editsprites|spriteeditor", "editsprites/spriteeditor: Switch to the Sprite Editor to edit the source rects and origins of sprites.", (string[] args) => { GameMain.SpriteEditorScreen.Select(); })); - commands.Add(new Command("charactereditor|editcharacter|editcharacters|editanimation|editanimations|animedit|animationeditor|animeditor|animationedit", "charactereditor: Edit characters, animations, ragdolls....", (string[] args) => + commands.Add(new Command("editcharacters|charactereditor", "editcharacters/charactereditor: Switch to the Character Editor to edit/create the ragdolls and animations of characters.", (string[] args) => { + if (Screen.Selected == GameMain.GameScreen) + { + NewMessage("WARNING: Switching between the character editor and the game view may cause odd behaviour or bugs. Use with caution.", Color.Orange); + } GameMain.CharacterEditorScreen.Select(); })); diff --git a/Barotrauma/BarotraumaClient/Source/Fonts/ScalableFont.cs b/Barotrauma/BarotraumaClient/Source/Fonts/ScalableFont.cs index de6bcb3ab..a5ef20967 100644 --- a/Barotrauma/BarotraumaClient/Source/Fonts/ScalableFont.cs +++ b/Barotrauma/BarotraumaClient/Source/Fonts/ScalableFont.cs @@ -414,28 +414,6 @@ namespace Barotrauma return retVal; } - public Vector2 MeasureChar(char c) - { - Vector2 retVal = Vector2.Zero; - retVal.Y = baseHeight * 1.8f; - if (texCoords.TryGetValue(c, out GlyphData gd)) - { - retVal.X = gd.advance; - } - return retVal; - } - - public Vector2 MeasureChar(char c) - { - Vector2 retVal = Vector2.Zero; - retVal.Y = baseHeight * 1.8f; - if (texCoords.TryGetValue(c, out GlyphData gd)) - { - retVal.X = gd.advance; - } - return retVal; - } - public void Dispose() { FontList.Remove(this); diff --git a/Barotrauma/BarotraumaClient/Source/GUI/ChatBox.cs b/Barotrauma/BarotraumaClient/Source/GUI/ChatBox.cs index 490c0d21a..ff3cd1dae 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/ChatBox.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/ChatBox.cs @@ -18,9 +18,7 @@ namespace Barotrauma private GUITextBox inputBox; private GUIButton toggleButton; - - private GUIButton radioButton; - + private Point screenResolution; private bool isSinglePlayer; @@ -60,12 +58,7 @@ namespace Barotrauma { get { return guiFrame; } } - - public GUIButton RadioButton - { - get { return radioButton; } - } - + public GUITextBox InputBox { get { return inputBox; } @@ -109,31 +102,7 @@ namespace Barotrauma { gui.Text = ""; }; - - radioButton = new GUIButton(new RectTransform(new Vector2(0.1f, 2.0f), inputBox.RectTransform, - HUDLayoutSettings.ChatBoxAlignment == Alignment.Right ? Anchor.BottomRight : Anchor.BottomLeft, - HUDLayoutSettings.ChatBoxAlignment == Alignment.Right ? Pivot.TopRight : Pivot.TopLeft), - style: null); - new GUIImage(new RectTransform(Vector2.One, radioButton.RectTransform), radioIcon, scaleToFit: true); - radioButton.OnClicked = (GUIButton btn, object userData) => - { - if (inputBox.Selected) - { - inputBox.Text = ""; - inputBox.Deselect(); - } - else - { - inputBox.Select(); - var radioItem = Character.Controlled?.Inventory?.Items.FirstOrDefault(i => i?.GetComponent() != null); - if (radioItem != null && Character.Controlled.HasEquippedItem(radioItem) && radioItem.GetComponent().CanTransmit()) - { - inputBox.Text = "r; "; - } - } - return true; - }; - + ToggleOpen = GameMain.Config.ChatOpen; } @@ -368,7 +337,6 @@ namespace Barotrauma } openState = MathHelper.Clamp(openState, 0.0f, 1.0f); int hiddenBoxOffset = guiFrame.Rect.Width + toggleButton.Rect.Width; - if (radioButton != null) hiddenBoxOffset += (int)(radioButton.Rect.Width * 1.5f); guiFrame.RectTransform.AbsoluteOffset = new Point((int)MathHelper.SmoothStep(hiddenBoxOffset * (HUDLayoutSettings.ChatBoxAlignment == Alignment.Left ? -1 : 1), 0, openState), 0); } diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIComponent.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIComponent.cs index a02ea16c4..18a473973 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUIComponent.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIComponent.cs @@ -154,6 +154,8 @@ namespace Barotrauma public bool IgnoreLayoutGroups; + public bool IgnoreLayoutGroups; + public virtual ScalableFont Font { get; diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIListBox.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIListBox.cs index 049ea780e..528ce8e2b 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUIListBox.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIListBox.cs @@ -511,10 +511,8 @@ namespace Barotrauma pos = 0; totalSize += child.Rect.Width + spacing; } - else - { - pos += child.Rect.Height + spacing; - } + pos += child.Rect.Height + spacing; + if (child == children.Last()) { totalSize += child.Rect.Width + spacing; @@ -527,10 +525,7 @@ namespace Barotrauma pos = 0; totalSize += child.Rect.Height + spacing; } - else - { - pos += child.Rect.Width + spacing; - } + pos += child.Rect.Width + spacing; if (child == children.Last()) { diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIMessageBox.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIMessageBox.cs index cab257fd3..86e835550 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUIMessageBox.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIMessageBox.cs @@ -113,6 +113,12 @@ namespace Barotrauma Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 }; Tag = tag; + InnerFrame = new GUIFrame(new RectTransform(new Point(width, height), RectTransform, Anchor.Center) { IsFixedSize = false }, style: null); + GUI.Style.Apply(InnerFrame, "", this); + + Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 }; + Tag = tag; + if (height == 0) { string wrappedText = ToolBox.WrapText(text, Content.Rect.Width, GUI.Font); diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIStyle.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIStyle.cs index c2b17e553..1e588a5ec 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUIStyle.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIStyle.cs @@ -1,4 +1,5 @@ -using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; using System; using System.Collections.Generic; using System.Xml.Linq; @@ -9,6 +10,8 @@ namespace Barotrauma { private Dictionary componentStyles; + private XElement configElement; + public ScalableFont Font { get; private set; } public ScalableFont SmallFont { get; private set; } public ScalableFont LargeFont { get; private set; } @@ -45,24 +48,6 @@ namespace Barotrauma { switch (subElement.Name.ToString().ToLowerInvariant()) { - case "font": - Font = new ScalableFont(subElement, graphicsDevice); - break; - case "smallfont": - SmallFont = new ScalableFont(subElement, graphicsDevice); - break; - case "largefont": - LargeFont = new ScalableFont(subElement, graphicsDevice); - break; - case "objectivetitle": - ObjectiveTitleFont = new ScalableFont(subElement, graphicsDevice); - break; - case "objectivename": - ObjectiveNameFont = new ScalableFont(subElement, graphicsDevice); - break; - case "videotitle": - VideoTitleFont = new ScalableFont(subElement, graphicsDevice); - break; case "cursor": CursorSprite = new Sprite(subElement); break; @@ -72,12 +57,58 @@ namespace Barotrauma case "focusindicator": FocusIndicator = new SpriteSheet(subElement); break; + case "font": + Font = LoadFont(subElement, graphicsDevice); + break; + case "smallfont": + SmallFont = LoadFont(subElement, graphicsDevice); + break; + case "largefont": + LargeFont = LoadFont(subElement, graphicsDevice); + break; + case "objectivetitle": + ObjectiveTitleFont = LoadFont(subElement, graphicsDevice); + break; + case "objectivename": + ObjectiveNameFont = LoadFont(subElement, graphicsDevice); + break; + case "videotitle": + VideoTitleFont = LoadFont(subElement, graphicsDevice); + break; default: GUIComponentStyle componentStyle = new GUIComponentStyle(subElement); componentStyles.Add(subElement.Name.ToString().ToLowerInvariant(), componentStyle); break; } } + } + + private void RescaleFonts() + { + foreach (XElement subElement in configElement.Elements()) + { + switch (subElement.Name.ToString().ToLowerInvariant()) + { + case "font": + Font.Size = GetFontSize(subElement); + break; + case "smallfont": + SmallFont.Size = GetFontSize(subElement); + break; + case "largefont": + LargeFont.Size = GetFontSize(subElement); + break; + case "objectivetitle": + ObjectiveTitleFont.Size = GetFontSize(subElement); + break; + case "objectivename": + ObjectiveNameFont.Size = GetFontSize(subElement); + break; + case "videotitle": + VideoTitleFont.Size = GetFontSize(subElement); + break; + } + } return element.GetAttributeBool("dynamicloading", false); } @@ -159,6 +190,32 @@ namespace Barotrauma return style; } + private ScalableFont LoadFont(XElement element, GraphicsDevice graphicsDevice) + { + string file = element.GetAttributeString("file", ""); + uint size = GetFontSize(element); + return new ScalableFont(file, size, graphicsDevice); + } + + private uint GetFontSize(XElement element) + { + foreach (XElement subElement in element.Elements()) + { + Point maxResolution = subElement.GetAttributePoint("maxresolution", new Point(int.MaxValue, int.MaxValue)); + if (GameMain.GraphicsWidth <= maxResolution.X && GameMain.GraphicsHeight <= maxResolution.Y) + { + return (uint)subElement.GetAttributeInt("size", 14); + } + } + return 14; + } + + public GUIComponentStyle GetComponentStyle(string name) + { + componentStyles.TryGetValue(name.ToLowerInvariant(), out GUIComponentStyle style); + return style; + } + public void Apply(GUIComponent targetComponent, string styleName = "", GUIComponent parent = null) { GUIComponentStyle componentStyle = null; diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs index 0968704c5..65a234dfb 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs @@ -333,7 +333,7 @@ namespace Barotrauma { spriteBatch.End(); spriteBatch.GraphicsDevice.ScissorRectangle = prevScissorRect; - spriteBatch.Begin(SpriteSortMode.Deferred); + spriteBatch.Begin(SpriteSortMode.Deferred, rasterizerState: GameMain.ScissorTestEnable); } if (OutlineColor.A * currColor.A > 0.0f) GUI.DrawRectangle(spriteBatch, rect, OutlineColor * (currColor.A / 255.0f), false); diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUITextBox.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUITextBox.cs index b21e70a49..73fcd1b3a 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUITextBox.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUITextBox.cs @@ -123,6 +123,12 @@ namespace Barotrauma } } + public bool OverflowClip + { + get { return textBlock.OverflowClip; } + set { textBlock.OverflowClip = value; } + } + public override bool Enabled { get { return enabled; } @@ -318,7 +324,7 @@ namespace Barotrauma for (int i = 0; i <= textBlock.Text.Length; i++) { Vector2 textSize = Font.MeasureString(textBlock.Text.Substring(0, i)); - Vector2 indexPos = new Vector2(textSize.X + textBlock.Padding.X, textSize.Y + textBlock.Padding.Y); + Vector2 indexPos = new Vector2(textSize.X + textBlock.Padding.X, textSize.Y + textBlock.Padding.Y) + textBlock.TextPos - textBlock.Origin; //DebugConsole.NewMessage($"index: {i}, pos: {indexPos}", Color.WhiteSmoke); positions.Add(new Tuple(textBlock.Rect.Location.ToVector2() + indexPos, i)); } @@ -405,7 +411,7 @@ namespace Barotrauma { isSelecting = PlayerInput.KeyDown(Keys.LeftShift) || PlayerInput.KeyDown(Keys.RightShift); } - + if (CaretEnabled) { if (textBlock.OverflowClipActive) @@ -428,7 +434,7 @@ namespace Barotrauma CalculateCaretPos(); } } - + if (GUI.KeyboardDispatcher.Subscriber == this) { state = ComponentState.Selected; @@ -547,15 +553,7 @@ namespace Barotrauma public void ReceiveTextInput(char inputChar) { - if (selectedCharacters > 0) - { - RemoveSelectedText(); - } - if (SetText(Text.Insert(CaretIndex, inputChar.ToString()))) - { - CaretIndex = Math.Min(Text.Length, CaretIndex + 1); - OnTextChanged?.Invoke(this, Text); - } + ReceiveTextInput(inputChar.ToString()); } public void ReceiveTextInput(string input) @@ -564,10 +562,16 @@ namespace Barotrauma { RemoveSelectedText(); } + Vector2 textPos = textBlock.TextPos; + bool wasOverflowClipActive = textBlock.OverflowClipActive; if (SetText(Text.Insert(CaretIndex, input))) { CaretIndex = Math.Min(Text.Length, CaretIndex + input.Length); OnTextChanged?.Invoke(this, Text); + if (textBlock.OverflowClipActive && wasOverflowClipActive && !MathUtils.NearlyEqual(textBlock.TextPos, textPos)) + { + textBlock.TextPos = textPos + Vector2.UnitX * Font.MeasureString(input).X; + } } } diff --git a/Barotrauma/BarotraumaClient/Source/GameMain.cs b/Barotrauma/BarotraumaClient/Source/GameMain.cs index 4708c53b4..a3335c213 100644 --- a/Barotrauma/BarotraumaClient/Source/GameMain.cs +++ b/Barotrauma/BarotraumaClient/Source/GameMain.cs @@ -178,6 +178,10 @@ namespace Barotrauma GUI.KeyboardDispatcher = new EventInput.KeyboardDispatcher(Window); + GUI.KeyboardDispatcher = new EventInput.KeyboardDispatcher(Window); + + + PerformanceCounter = new PerformanceCounter(); PerformanceCounter = new PerformanceCounter(); @@ -718,6 +722,83 @@ namespace Barotrauma PerformanceCounter.DrawTimeGraph.Update(sw.ElapsedTicks / (float)TimeSpan.TicksPerMillisecond); } + public void ShowCampaignDisclaimer() + { + var msgBox = new GUIMessageBox(TextManager.Get("CampaignDisclaimerTitle"), TextManager.Get("CampaignDisclaimerText"), + new string[] { TextManager.Get("CampaignRoadMapTitle"), TextManager.Get("OK") }); + + msgBox.Buttons[0].OnClicked = (btn, userdata) => + { + var roadMap = new GUIMessageBox(TextManager.Get("CampaignRoadMapTitle"), TextManager.Get("CampaignRoadMapText"), + new string[] { TextManager.Get("Back"), TextManager.Get("OK") }); + roadMap.Buttons[0].OnClicked = (_, __) => { ShowCampaignDisclaimer(); return true; }; + roadMap.Buttons[0].OnClicked += roadMap.Close; + roadMap.Buttons[1].OnClicked += roadMap.Close; + return true; + }; + msgBox.Buttons[0].OnClicked += msgBox.Close; + msgBox.Buttons[1].OnClicked += msgBox.Close; + + Config.CampaignDisclaimerShown = true; + Config.SaveNewPlayerConfig(); + } + + public void ShowEditorDisclaimer() + { + var msgBox = new GUIMessageBox(TextManager.Get("EditorDisclaimerTitle"), TextManager.Get("EditorDisclaimerText")); + var linkHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.25f), msgBox.Content.RectTransform)) { Stretch = true, RelativeSpacing = 0.025f }; + List> links = new List>() + { + new Pair(TextManager.Get("EditorDisclaimerWikiLink"),TextManager.Get("EditorDisclaimerWikiUrl")), + new Pair(TextManager.Get("EditorDisclaimerDiscordLink"),TextManager.Get("EditorDisclaimerDiscordUrl")), + new Pair(TextManager.Get("EditorDisclaimerForumLink"),TextManager.Get("EditorDisclaimerForumUrl")), + }; + foreach (var link in links) + { + new GUIButton(new RectTransform(new Vector2(1.0f, 0.2f), linkHolder.RectTransform), link.First, style: "MainMenuGUIButton", textAlignment: Alignment.Left) + { + UserData = link.Second, + OnClicked = (btn, userdata) => + { + Process.Start(userdata as string); + return true; + } + }; + } + + msgBox.Text.RectTransform.MaxSize = new Point(int.MaxValue, msgBox.Text.Rect.Height); + linkHolder.RectTransform.MaxSize = new Point(int.MaxValue, linkHolder.Rect.Height); + msgBox.RectTransform.MinSize = new Point(0, msgBox.Rect.Height + linkHolder.Rect.Height + msgBox.Buttons.First().Rect.Height * 8); + Config.EditorDisclaimerShown = true; + Config.SaveNewPlayerConfig(); + } + + // ToDo: Move texts/links to localization, when possible. + public void ShowBugReporter() + { + var msgBox = new GUIMessageBox("", ""); + var linkHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), msgBox.Content.RectTransform)) { Stretch = true, RelativeSpacing = 0.05f }; + + List> links = new List>() + { + new Pair("Barotrauma Feedback Form","https://barotraumagame.com/feedback"), + new Pair("Github Issue Form (Needs account)","https://github.com/Regalis11/Barotrauma/issues/new?template=bug_report.md") + }; + foreach (var link in links) + { + new GUIButton(new RectTransform(new Vector2(1.0f, 0.2f), linkHolder.RectTransform), link.First, style: "MainMenuGUIButton", textAlignment: Alignment.Left) + { + UserData = link.Second, + OnClicked = (btn, userdata) => + { + Process.Start(userdata as string); + msgBox.Close(); + return true; + } + }; + } + } + static bool waitForKeyHit = true; public CoroutineHandle ShowLoading(IEnumerable loader, bool waitKeyHit = true) { diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs index 0337bae3c..f97bd8812 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs @@ -69,6 +69,11 @@ namespace Barotrauma public CrewManager(XElement element, bool isSinglePlayer) : this(isSinglePlayer) + { + return characterListBox.Rect; + } + + partial void InitProjectSpecific() { guiFrame = new GUIFrame(new RectTransform(Vector2.One, GUICanvas.Instance), null, Color.Transparent) { @@ -90,64 +95,14 @@ namespace Barotrauma return true; }; - characterListBox = new GUIListBox(new RectTransform(new Point(100, (int)(crewArea.Rect.Height - scrollButtonSize.Y * 1.6f)), crewArea.RectTransform, Anchor.CenterLeft), false, Color.Transparent, null) - { - //Spacing = (int)(3 * GUI.Scale), - ScrollBarEnabled = false, - ScrollBarVisible = false, - CanBeFocused = false - }; - - scrollButtonUp = new GUIButton(new RectTransform(scrollButtonSize, crewArea.RectTransform, Anchor.TopLeft, Pivot.TopLeft), "", Alignment.Center, "GUIButtonVerticalArrow") - { - Visible = false, - UserData = -1, - OnClicked = ScrollCharacterList - }; - scrollButtonDown = new GUIButton(new RectTransform(scrollButtonSize, crewArea.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft), "", Alignment.Center, "GUIButtonVerticalArrow") - { - Visible = false, - UserData = 1, - OnClicked = ScrollCharacterList - }; - scrollButtonDown.Children.ForEach(c => c.SpriteEffects = SpriteEffects.FlipVertically); - - if (isSinglePlayer) - { - ChatBox = new ChatBox(guiFrame, isSinglePlayer: true) + var characterInfo = new CharacterInfo(subElement); + characterInfos.Add(characterInfo); + foreach (XElement invElement in subElement.Elements()) { - OnEnterMessage = (textbox, text) => - { - if (Character.Controlled?.Info == null) - { - textbox.Deselect(); - textbox.Text = ""; - return true; - } - - textbox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Default]; - - if (!string.IsNullOrWhiteSpace(text)) - { - string msgCommand = ChatMessage.GetChatMessageCommand(text, out string msg); - AddSinglePlayerChatMessage( - Character.Controlled.Info.Name, - msg, - ((msgCommand == "r" || msgCommand == "radio") && ChatMessage.CanUseRadio(Character.Controlled)) ? ChatMessageType.Radio : ChatMessageType.Default, - Character.Controlled); - var headset = GetHeadset(Character.Controlled, true); - if (headset != null && headset.CanTransmit()) - { - headset.TransmitSignal(stepsTaken: 0, signal: msg, source: headset.Item, sender: Character.Controlled, sendToChat: false); - } - } - textbox.Deselect(); - textbox.Text = ""; - return true; - } - }; - - ChatBox.InputBox.OnTextChanged += ChatBox.TypingChatMessage; + if (invElement.Name.ToString().ToLowerInvariant() != "inventory") continue; + characterInfo.InventoryData = invElement; + break; + } } var reports = Order.PrefabList.FindAll(o => o.TargetAllCharacters && o.SymbolSprite != null); @@ -186,14 +141,12 @@ namespace Barotrauma Visible = false }; - var characterInfo = new CharacterInfo(subElement); - characterInfos.Add(characterInfo); - foreach (XElement invElement in subElement.Elements()) + var img = new GUIImage(new RectTransform(Vector2.One, btn.RectTransform), order.Prefab.SymbolSprite, scaleToFit: true) { - if (invElement.Name.ToString().ToLowerInvariant() != "inventory") continue; - characterInfo.InventoryData = invElement; - break; - } + Color = order.Color, + HoverColor = Color.Lerp(order.Color, Color.White, 0.5f), + ToolTip = order.Name + }; } screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight); @@ -203,16 +156,6 @@ namespace Barotrauma ToggleCrewAreaOpen = GameMain.Config.CrewMenuOpen; } - - #endregion - - #region Character list management - - public Rectangle GetCharacterListArea() - { - return characterListBox.Rect; - } - partial void InitProjectSpecific() { guiFrame = new GUIFrame(new RectTransform(Vector2.One, GUICanvas.Instance), null, Color.Transparent) @@ -734,22 +677,7 @@ namespace Barotrauma characterListBox.BarScroll = roundedPos; } - #endregion - - #region Dialog - /// - /// Adds the message to the single player chatbox. - /// - public void AddSinglePlayerChatMessage(string senderName, string text, ChatMessageType messageType, Character sender) - { - if (!isSinglePlayer) - { - DebugConsole.ThrowError("Cannot add messages to single player chat box in multiplayer mode!\n" + Environment.StackTrace); - return; - } - if (string.IsNullOrEmpty(text)) { return; } - - ChatBox.AddMessage(ChatMessage.Create(senderName, text, messageType, sender)); + return false; } private IEnumerable KillCharacterAnim(GUIComponent component) @@ -762,12 +690,6 @@ namespace Barotrauma { comp.Color = Color.DarkRed; } - List availableSpeakers = Character.CharacterList.FindAll(c => - c.AIController is HumanAIController && - !c.IsDead && - c.SpeechImpediment <= 100.0f); - pendingConversationLines.AddRange(NPCConversation.CreateRandom(availableSpeakers)); - } yield return new WaitForSeconds(1.0f); @@ -803,6 +725,10 @@ namespace Barotrauma } if (string.IsNullOrEmpty(text)) { return; } + if (sender != null) + { + GameMain.GameSession.CrewManager.SetCharacterSpeaking(sender); + } ChatBox.AddMessage(ChatMessage.Create(senderName, text, messageType, sender)); } @@ -854,15 +780,19 @@ namespace Barotrauma soundIconDisabled.ToolTip = TextManager.Get(mutedLocally ? "MutedLocally" : "MutedGlobally"); } - public void SetPlayerSpeaking(Client client) + public void SetClientSpeaking(Client client) { - if (client?.Character == null) { return; } + if (client?.Character != null) { SetCharacterSpeaking(client.Character); } + } - var playerFrame = characterListBox.Content.FindChild(client.Character)?.FindChild(client.Character); + public void SetCharacterSpeaking(Character character) + { + var playerFrame = characterListBox.Content.FindChild(character)?.FindChild(character); if (playerFrame == null) { return; } var soundIcon = playerFrame.FindChild("soundicon"); soundIcon.Color = new Color(soundIcon.Color, 1.0f); } + #endregion /// diff --git a/Barotrauma/BarotraumaClient/Source/GameSettings.cs b/Barotrauma/BarotraumaClient/Source/GameSettings.cs index ce5b6744b..90399592b 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSettings.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSettings.cs @@ -81,10 +81,17 @@ namespace Barotrauma var leftPanel = new GUILayoutGroup(new RectTransform(new Vector2(0.25f, 1.0f), settingsFramePadding.RectTransform, Anchor.TopLeft)); - new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), leftPanel.RectTransform), + var settingsTitle = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), leftPanel.RectTransform), TextManager.Get("Settings"), textAlignment: Alignment.TopLeft, font: GUI.LargeFont) { ForceUpperCase = true }; + //TODO: enable when new texts can be added + /*new GUIButton(new RectTransform(new Vector2(1.0f, 0.75f), settingsTitle.RectTransform, Anchor.CenterRight), style: "GUIBugButton") + { + ToolTip = "Bug Reporter", + OnClicked = (btn, userdata) => { GameMain.Instance.ShowBugReporter(); return true; } + };*/ + var generalLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), leftPanel.RectTransform, Anchor.TopLeft)); new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), generalLayoutGroup.RectTransform), TextManager.Get("ContentPackages")); @@ -157,7 +164,7 @@ namespace Barotrauma { UserData = tab }; - tabButtons[(int)tab] = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), tabButtonHolder.RectTransform), + tabButtons[(int)tab] = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), tabButtonHolder.RectTransform), TextManager.Get("SettingsTab." + tab.ToString()), style: "GUITabButton") { UserData = tab, @@ -195,7 +202,7 @@ namespace Barotrauma var resolutionDD = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), elementCount: supportedDisplayModes.Count) { OnSelected = SelectResolution, -#if OSX +#if !LINUX ButtonEnabled = GameMain.Config.WindowMode == WindowMode.Windowed #endif }; @@ -235,7 +242,7 @@ namespace Barotrauma { UnsavedSettings = true; GameMain.Config.WindowMode = (WindowMode)guiComponent.UserData; -#if OSX +#if !LINUX resolutionDD.ButtonEnabled = GameMain.Config.WindowMode == WindowMode.Windowed; #endif return true; @@ -431,7 +438,7 @@ namespace Barotrauma UnsavedSettings = true; return true; }; - + new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), audioSliders.RectTransform), TextManager.Get("VoiceChat")); IList deviceNames = Alc.GetString((IntPtr)null, AlcGetStringList.CaptureDeviceSpecifier); @@ -640,7 +647,7 @@ namespace Barotrauma return true; } }; - + var inputFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.75f), controlsLayoutGroup.RectTransform), isHorizontal: true) { Stretch = true, RelativeSpacing = 0.03f }; diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/ItemComponent.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/ItemComponent.cs index 7462d2b18..c5ecaf754 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/ItemComponent.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/ItemComponent.cs @@ -227,10 +227,9 @@ namespace Barotrauma.Items.Components } return; } - - if (!sounds.TryGetValue(type, out List matchingSounds)) return; - + ItemSound itemSound = null; + var matchingSounds = sounds[type]; if (loopingSoundChannel == null || !loopingSoundChannel.IsPlaying) { SoundSelectionMode soundSelectionMode = soundSelectionModes[type]; @@ -265,7 +264,7 @@ namespace Barotrauma.Items.Components private void PlaySound(ItemSound itemSound, Vector2 position, Character user = null) { - if (Vector3.DistanceSquared(GameMain.SoundManager.ListenerPosition, new Vector3(position.X, position.Y, 0.0f)) > itemSound.Range * itemSound.Range) + if (Vector2.DistanceSquared(new Vector2(GameMain.SoundManager.ListenerPosition.X, GameMain.SoundManager.ListenerPosition.Y), position) > itemSound.Range * itemSound.Range) { return; } @@ -293,7 +292,7 @@ namespace Barotrauma.Items.Components { float volume = GetSoundVolume(itemSound); if (volume <= 0.0f) return; - SoundPlayer.PlaySound(itemSound.RoundSound.Sound, volume, itemSound.Range, position, item.CurrentHull); + SoundPlayer.PlaySound(itemSound.RoundSound.Sound, position, volume, itemSound.Range, item.CurrentHull); } } diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Reactor.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Reactor.cs index d46b2029a..893943a62 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Reactor.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Reactor.cs @@ -554,6 +554,8 @@ namespace Barotrauma.Items.Components fissionRateScrollBar.BarScroll = targetFissionRate / 100.0f; turbineOutputScrollBar.BarScroll = targetTurbineOutput / 100.0f; onOffSwitch.BarScroll = shutDown ? Math.Max(onOffSwitch.BarScroll, 0.55f) : Math.Min(onOffSwitch.BarScroll, 0.45f); + + IsActive = true; } } } diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs index 6a8ee3d51..3c20dbb30 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs @@ -439,11 +439,14 @@ namespace Barotrauma.Items.Components { var mission = GameMain.GameSession.Mission; - if (!string.IsNullOrWhiteSpace(mission.SonarLabel) && mission.SonarPosition != Vector2.Zero) + if (!string.IsNullOrWhiteSpace(mission.SonarLabel)) { - DrawMarker(spriteBatch, - mission.SonarLabel, - mission.SonarPosition - transducerCenter, displayScale, center, (rect.Width * 0.47f)); + foreach (Vector2 sonarPosition in mission.SonarPositions) + { + DrawMarker(spriteBatch, + mission.SonarLabel, + sonarPosition - transducerCenter, displayScale, center, (rect.Width * 0.47f)); + } } } diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Signal/Wire.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Signal/Wire.cs index 0927e57ef..9daa403e8 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/Signal/Wire.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Signal/Wire.cs @@ -276,14 +276,6 @@ namespace Barotrauma.Items.Components if (highlighted != null) { highlighted.item.IsHighlighted = true; - - if (Character.Controlled != null) - { - Character.Controlled.FocusedItem = null; - Character.Controlled.ResetInteract = true; - Character.Controlled.ClearInputs(); - } - if (PlayerInput.LeftButtonClicked()) { MapEntity.DisableSelect = true; diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Turret.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Turret.cs index 2e5a6dd04..b79bcda92 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/Turret.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Turret.cs @@ -150,14 +150,14 @@ namespace Barotrauma.Items.Components { if (moveSoundChannel == null && startMoveSound != null) { - moveSoundChannel = SoundPlayer.PlaySound(startMoveSound.Sound, startMoveSound.Volume, startMoveSound.Range, item.WorldPosition); + moveSoundChannel = SoundPlayer.PlaySound(startMoveSound.Sound, item.WorldPosition, startMoveSound.Volume, startMoveSound.Range); } else if (moveSoundChannel == null || !moveSoundChannel.IsPlaying) { if (moveSound != null) { moveSoundChannel.FadeOutAndDispose(); - moveSoundChannel = SoundPlayer.PlaySound(moveSound.Sound, moveSound.Volume, moveSound.Range, item.WorldPosition); + moveSoundChannel = SoundPlayer.PlaySound(moveSound.Sound, item.WorldPosition, moveSound.Volume, moveSound.Range); if (moveSoundChannel != null) moveSoundChannel.Looping = true; } } @@ -169,7 +169,7 @@ namespace Barotrauma.Items.Components if (endMoveSound != null && moveSoundChannel.Sound != endMoveSound.Sound) { moveSoundChannel.FadeOutAndDispose(); - moveSoundChannel = SoundPlayer.PlaySound(endMoveSound.Sound, endMoveSound.Volume, endMoveSound.Range, item.WorldPosition); + moveSoundChannel = SoundPlayer.PlaySound(endMoveSound.Sound, item.WorldPosition, endMoveSound.Volume, endMoveSound.Range); if (moveSoundChannel != null) moveSoundChannel.Looping = false; } else if (!moveSoundChannel.IsPlaying) diff --git a/Barotrauma/BarotraumaClient/Source/Items/Item.cs b/Barotrauma/BarotraumaClient/Source/Items/Item.cs index 119b398ac..501f023e5 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Item.cs @@ -384,7 +384,7 @@ namespace Barotrauma Timing.TotalTime > LastImpactSoundTime + ImpactSoundInterval) { LastImpactSoundTime = (float)Timing.TotalTime; - SoundPlayer.PlaySound(Prefab.ImpactSoundTag, 1.0f, 500.0f, WorldPosition, CurrentHull); + SoundPlayer.PlaySound(Prefab.ImpactSoundTag, WorldPosition, hullGuess: CurrentHull); } } diff --git a/Barotrauma/BarotraumaClient/Source/Items/ItemPrefab.cs b/Barotrauma/BarotraumaClient/Source/Items/ItemPrefab.cs index 76a9c235f..d57d32a62 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/ItemPrefab.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/ItemPrefab.cs @@ -233,11 +233,11 @@ namespace Barotrauma } } - public override void DrawPlacing(SpriteBatch spriteBatch, Rectangle placeRect, float scale = 1.0f) + public override void DrawPlacing(SpriteBatch spriteBatch, Rectangle placeRect, float scale = 1.0f, SpriteEffects spriteEffects = SpriteEffects.None) { if (!ResizeHorizontal && !ResizeVertical) { - sprite.Draw(spriteBatch, new Vector2(placeRect.Center.X, -(placeRect.Y - placeRect.Height / 2)), SpriteColor * 0.8f, scale: Scale * scale); + sprite.Draw(spriteBatch, new Vector2(placeRect.Center.X, -(placeRect.Y - placeRect.Height / 2)), SpriteColor * 0.8f, scale: scale); } else { diff --git a/Barotrauma/BarotraumaClient/Source/Map/Hull.cs b/Barotrauma/BarotraumaClient/Source/Map/Hull.cs index 458192dee..1d5025f22 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Hull.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Hull.cs @@ -650,6 +650,33 @@ namespace Barotrauma Color.Green, width: 2); } } + + foreach (MapEntity e in linkedTo) + { + if (e is Hull) + { + Hull linkedHull = (Hull)e; + Rectangle connectedHullRect = e.Submarine == null ? + linkedHull.rect : + new Rectangle( + (int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X), + (int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y), + linkedHull.WorldRect.Width, linkedHull.WorldRect.Height); + + //center of the hull + Rectangle currentHullRect = Submarine == null ? + WorldRect : + new Rectangle( + (int)(Submarine.DrawPosition.X + WorldPosition.X), + (int)(Submarine.DrawPosition.Y + WorldPosition.Y), + WorldRect.Width, WorldRect.Height); + + GUI.DrawLine(spriteBatch, + new Vector2(currentHullRect.X, -currentHullRect.Y), + new Vector2(connectedHullRect.X, -connectedHullRect.Y), + Color.Green, width: 2); + } + } } public static void UpdateVertices(GraphicsDevice graphicsDevice, Camera cam, WaterRenderer renderer) diff --git a/Barotrauma/BarotraumaClient/Source/Map/Levels/Level.cs b/Barotrauma/BarotraumaClient/Source/Map/Levels/Level.cs index 0b4f41505..4f94c4362 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Levels/Level.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Levels/Level.cs @@ -105,7 +105,7 @@ namespace Barotrauma if (Vector2.DistanceSquared(bodyPos, levelWall.Body.Position) > 0.5f) { - levelWall.Body.SetTransform(bodyPos, levelWall.Body.Rotation); + levelWall.Body.SetTransformIgnoreContacts(ref bodyPos, levelWall.Body.Rotation); } } } diff --git a/Barotrauma/BarotraumaClient/Source/Map/MapEntity.cs b/Barotrauma/BarotraumaClient/Source/Map/MapEntity.cs index a49b60add..cfa1a5486 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/MapEntity.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/MapEntity.cs @@ -504,8 +504,19 @@ namespace Barotrauma { foreach (MapEntity e in selectedList) { + SpriteEffects spriteEffects = SpriteEffects.None; + if (e is Item item) + { + if (item.FlippedX && item.Prefab.CanSpriteFlipX) spriteEffects ^= SpriteEffects.FlipHorizontally; + if (item.flippedY && item.Prefab.CanSpriteFlipY) spriteEffects ^= SpriteEffects.FlipVertically; + } + else if (e is Structure structure) + { + if (structure.FlippedX && structure.Prefab.CanSpriteFlipX) spriteEffects ^= SpriteEffects.FlipHorizontally; + if (structure.flippedY && structure.Prefab.CanSpriteFlipY) spriteEffects ^= SpriteEffects.FlipVertically; + } e.prefab?.DrawPlacing(spriteBatch, - new Rectangle(e.WorldRect.Location + new Point((int)moveAmount.X, (int)-moveAmount.Y), e.WorldRect.Size)); + new Rectangle(e.WorldRect.Location + new Point((int)moveAmount.X, (int)-moveAmount.Y), e.WorldRect.Size), e.Scale, spriteEffects); GUI.DrawRectangle(spriteBatch, new Vector2(e.WorldRect.X, -e.WorldRect.Y) + moveAmount, new Vector2(e.rect.Width, e.rect.Height), diff --git a/Barotrauma/BarotraumaClient/Source/Map/MapEntityPrefab.cs b/Barotrauma/BarotraumaClient/Source/Map/MapEntityPrefab.cs index 2d2a03e2b..97786e794 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/MapEntityPrefab.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/MapEntityPrefab.cs @@ -37,7 +37,7 @@ namespace Barotrauma } } - public virtual void DrawPlacing(SpriteBatch spriteBatch, Rectangle drawRect, float scale = 1.0f) + public virtual void DrawPlacing(SpriteBatch spriteBatch, Rectangle drawRect, float scale = 1.0f, SpriteEffects spriteEffects = SpriteEffects.None) { if (Submarine.MainSub != null) { diff --git a/Barotrauma/BarotraumaClient/Source/Map/Structure.cs b/Barotrauma/BarotraumaClient/Source/Map/Structure.cs index 3bf4ae5f1..8d893af08 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Structure.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Structure.cs @@ -42,13 +42,7 @@ namespace Barotrauma MathHelper.Clamp(value.Y, 0.01f, 10)); } } - - // Only for testing in the debug build. Not saved. -#if DEBUG - [Editable, Serialize(true, false)] -#endif - public bool DrawTiled { get; protected set; } = true; - + protected Vector2 textureOffset = Vector2.Zero; [Editable(MinValueFloat = -1000f, MaxValueFloat = 1000f, ValueStep = 10f), Serialize("0.0, 0.0", true)] public Vector2 TextureOffset @@ -102,7 +96,7 @@ namespace Barotrauma editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) }) { UserData = this }; GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.95f, 0.8f), editingHUD.RectTransform, Anchor.Center), style: null); var editor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, elementHeight: 20); - + var buttonContainer = new GUILayoutGroup(new RectTransform(new Point(listBox.Content.Rect.Width, 20)), isHorizontal: true) { Stretch = true, @@ -241,62 +235,35 @@ namespace Barotrauma } dropShadowOffset.Y = -dropShadowOffset.Y; } + + SpriteEffects oldEffects = Prefab.BackgroundSprite.effects; + Prefab.BackgroundSprite.effects ^= SpriteEffects; - if (DrawTiled) + Point backGroundOffset = new Point( + MathUtils.PositiveModulo((int)-textureOffset.X, Prefab.BackgroundSprite.SourceRect.Width), + MathUtils.PositiveModulo((int)-textureOffset.Y, Prefab.BackgroundSprite.SourceRect.Height)); + + Prefab.BackgroundSprite.DrawTiled( + spriteBatch, + new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)), + new Vector2(rect.Width, rect.Height), + color: color, + textureScale: TextureScale * Scale, + startOffset: backGroundOffset); + + if (UseDropShadow) { - SpriteEffects oldEffects = Prefab.BackgroundSprite.effects; - Prefab.BackgroundSprite.effects ^= SpriteEffects; - - Point backGroundOffset = new Point( - MathUtils.PositiveModulo((int)-textureOffset.X, Prefab.BackgroundSprite.SourceRect.Width), - MathUtils.PositiveModulo((int)-textureOffset.Y, Prefab.BackgroundSprite.SourceRect.Height)); - Prefab.BackgroundSprite.DrawTiled( spriteBatch, - new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)), + new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)) + dropShadowOffset, new Vector2(rect.Width, rect.Height), - color: color, + color: Color.Black * 0.5f, textureScale: TextureScale * Scale, - startOffset: backGroundOffset); - - if (UseDropShadow) - { - Prefab.BackgroundSprite.DrawTiled( - spriteBatch, - new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)) + dropShadowOffset, - new Vector2(rect.Width, rect.Height), - color: Color.Black * 0.5f, - textureScale: TextureScale * Scale, - startOffset: backGroundOffset, - depth: (depth + Prefab.BackgroundSprite.Depth) / 2.0f); - } - - Prefab.BackgroundSprite.effects = oldEffects; + startOffset: backGroundOffset, + depth: (depth + Prefab.BackgroundSprite.Depth) / 2.0f); } - else - { - Prefab.BackgroundSprite.Draw( - spriteBatch, - new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)), - color, - Vector2.Zero, - scale: Scale, - rotate: 0, - spriteEffect: SpriteEffects); - if (UseDropShadow) - { - Prefab.BackgroundSprite.Draw( - spriteBatch, - new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)) + dropShadowOffset, - Color.Black * 0.5f, - Vector2.Zero, - scale: Scale, - rotate: 0, - spriteEffect: SpriteEffects, - depth: (depth + Prefab.BackgroundSprite.Depth) / 2.0f); - } - } + Prefab.BackgroundSprite.effects = oldEffects; } } @@ -323,39 +290,25 @@ namespace Barotrauma Submarine.DamageEffectColor = color; } } + + Point sectionOffset = new Point( + Math.Abs(rect.Location.X - Sections[i].rect.Location.X), + Math.Abs(rect.Location.Y - Sections[i].rect.Location.Y)); - if (DrawTiled) - { - Point sectionOffset = new Point( - Math.Abs(rect.Location.X - Sections[i].rect.Location.X), - Math.Abs(rect.Location.Y - Sections[i].rect.Location.Y)); + if (FlippedX && IsHorizontal) sectionOffset.X = Sections[i].rect.Right - rect.Right; + if (FlippedY && !IsHorizontal) sectionOffset.Y = (rect.Y - rect.Height) - (Sections[i].rect.Y - Sections[i].rect.Height); - if (FlippedX && IsHorizontal) sectionOffset.X = Sections[i].rect.Right - rect.Right; - if (FlippedY && !IsHorizontal) sectionOffset.Y = (rect.Y - rect.Height) - (Sections[i].rect.Y - Sections[i].rect.Height); + sectionOffset.X += MathUtils.PositiveModulo((int)-textureOffset.X, prefab.sprite.SourceRect.Width); + sectionOffset.Y += MathUtils.PositiveModulo((int)-textureOffset.Y, prefab.sprite.SourceRect.Height); - sectionOffset.X += MathUtils.PositiveModulo((int)-textureOffset.X, prefab.sprite.SourceRect.Width); - sectionOffset.Y += MathUtils.PositiveModulo((int)-textureOffset.Y, prefab.sprite.SourceRect.Height); - - prefab.sprite.DrawTiled( - spriteBatch, - new Vector2(Sections[i].rect.X + drawOffset.X, -(Sections[i].rect.Y + drawOffset.Y)), - new Vector2(Sections[i].rect.Width, Sections[i].rect.Height), - color: color, - startOffset: sectionOffset, - depth: depth, - textureScale: TextureScale * Scale); - } - else - { - prefab.sprite.Draw( - spriteBatch, - new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)), - color, - Vector2.Zero, - scale: Scale, - rotate: 0, - spriteEffect: SpriteEffects); - } + prefab.sprite.DrawTiled( + spriteBatch, + new Vector2(Sections[i].rect.X + drawOffset.X, -(Sections[i].rect.Y + drawOffset.Y)), + new Vector2(Sections[i].rect.Width, Sections[i].rect.Height), + color: color, + startOffset: sectionOffset, + depth: depth, + textureScale: TextureScale * Scale); } prefab.sprite.effects = oldEffects; } @@ -376,6 +329,20 @@ namespace Barotrauma -Bodies[i].Rotation, Color.White); } } + + if (SectionCount > 0 && HasBody) + { + for (int i = 0; i < SectionCount; i++) + { + if (GetSection(i).damage > 0) + { + var textPos = SectionPosition(i, true); + textPos.Y = -textPos.Y; + GUI.DrawString(spriteBatch, textPos, "Damage: " + (int)((GetSection(i).damage / Health) * 100f) + "%", Color.Yellow); + } + } + } + AiTarget?.Draw(spriteBatch); } } diff --git a/Barotrauma/BarotraumaClient/Source/Map/StructurePrefab.cs b/Barotrauma/BarotraumaClient/Source/Map/StructurePrefab.cs index 4863ea754..36ba5a87c 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/StructurePrefab.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/StructurePrefab.cs @@ -32,10 +32,19 @@ namespace Barotrauma GUI.DrawRectangle(spriteBatch, new Rectangle(newRect.X, -newRect.Y - GameMain.GraphicsHeight, newRect.Width, newRect.Height + GameMain.GraphicsHeight * 2), Color.White); } - public override void DrawPlacing(SpriteBatch spriteBatch, Rectangle placeRect, float scale = 1.0f) + public override void DrawPlacing(SpriteBatch spriteBatch, Rectangle placeRect, float scale = 1.0f, SpriteEffects spriteEffects = SpriteEffects.None) { - // TODO: the scale property is not used - sprite.DrawTiled(spriteBatch, new Vector2(placeRect.X, -placeRect.Y), new Vector2(placeRect.Width, placeRect.Height), color: Color.White * 0.8f, textureScale: TextureScale * Scale); + SpriteEffects oldEffects = sprite.effects; + sprite.effects ^= spriteEffects; + + sprite.DrawTiled( + spriteBatch, + new Vector2(placeRect.X, -placeRect.Y), + new Vector2(placeRect.Width, placeRect.Height), + color: Color.White * 0.8f, + textureScale: TextureScale * scale); + + sprite.effects = oldEffects; } } } diff --git a/Barotrauma/BarotraumaClient/Source/Map/SubmarineBody.cs b/Barotrauma/BarotraumaClient/Source/Map/SubmarineBody.cs index 8c7476ed8..864b9dd92 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/SubmarineBody.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/SubmarineBody.cs @@ -42,10 +42,17 @@ namespace Barotrauma bool displace = moveAmount.LengthSquared() > 100.0f * 100.0f; foreach (Submarine sub in subsToMove) { - sub.PhysicsBody.SetTransform(sub.PhysicsBody.SimPosition + ConvertUnits.ToSimUnits(moveAmount), 0.0f); sub.PhysicsBody.LinearVelocity = newVelocity; - if (displace) sub.SubBody.DisplaceCharacters(moveAmount); + if (displace) + { + sub.PhysicsBody.SetTransform(sub.PhysicsBody.SimPosition + ConvertUnits.ToSimUnits(moveAmount), 0.0f); + sub.SubBody.DisplaceCharacters(moveAmount); + } + else + { + sub.PhysicsBody.SetTransformIgnoreContacts(sub.PhysicsBody.SimPosition + ConvertUnits.ToSimUnits(moveAmount), 0.0f); + } } if (closestSub != null && subsToMove.Contains(closestSub)) @@ -55,7 +62,6 @@ namespace Barotrauma if (Character.Controlled != null) Character.Controlled.CursorPosition += moveAmount; } - } } } diff --git a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs index fa4a2d3b4..e0e35f159 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs @@ -26,6 +26,7 @@ namespace Barotrauma.Networking //TODO: move these to NetLobbyScreen public GUIButton EndRoundButton; public GUITickBox EndVoteTickBox; + private GUIComponent buttonContainer; private NetStats netStats; @@ -129,7 +130,7 @@ namespace Barotrauma.Networking chatBox.OnEnterMessage += EnterChatMessage; chatBox.InputBox.OnTextChanged += TypingChatMessage; - var buttonContainer = new GUILayoutGroup(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ButtonAreaTop, inGameHUD.RectTransform), + buttonContainer = new GUILayoutGroup(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ButtonAreaTop, inGameHUD.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterRight) { AbsoluteSpacing = 5, @@ -630,13 +631,11 @@ namespace Barotrauma.Networking } else { - GameMain.GameSession?.CrewManager?.SetPlayerSpeaking(myClient); + GameMain.GameSession?.CrewManager?.SetClientSpeaking(myClient); } } } - if (gameStarted) SetRadioButtonColor(); - if (ShowNetStats && client?.ServerConnection != null) { netStats.AddValue(NetStats.NetStatType.ReceivedBytes, client.ServerConnection.Statistics.ReceivedBytes); @@ -2124,9 +2123,7 @@ namespace Barotrauma.Networking protected GUIFrame inGameHUD; protected ChatBox chatBox; public GUIButton ShowLogButton; //TODO: move to NetLobbyScreen - - private float myCharacterFrameOpenState; - + public GUIFrame InGameHUD { get { return inGameHUD; } @@ -2136,22 +2133,7 @@ namespace Barotrauma.Networking { get { return chatBox; } } - - protected void SetRadioButtonColor() - { - if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) - { - chatBox.RadioButton.GetChild().Color = new Color(60, 60, 60, 255); - } - else - { - var radioItem = Character.Controlled?.Inventory?.Items.FirstOrDefault(i => i?.GetComponent() != null); - chatBox.RadioButton.GetChild().Color = - (radioItem != null && Character.Controlled.HasEquippedItem(radioItem) && radioItem.GetComponent().CanTransmit()) ? - Color.White : new Color(60, 60, 60, 255); - } - } - + public bool TypingChatMessage(GUITextBox textBox, string text) { return chatBox.TypingChatMessage(textBox, text); @@ -2183,11 +2165,6 @@ namespace Barotrauma.Networking Screen.Selected == GameMain.GameScreen) { inGameHUD.AddToGUIUpdateList(); - - if (Character.Controlled == null) - { - GameMain.NetLobbyScreen.MyCharacterFrame.AddToGUIUpdateList(); - } } } @@ -2206,24 +2183,17 @@ namespace Barotrauma.Networking if (gameStarted && Screen.Selected == GameMain.GameScreen) { + bool disableButtons = + Character.Controlled != null && + Character.Controlled.SelectedConstruction?.GetComponent() != null; + buttonContainer.Visible = !disableButtons; + if (!GUI.DisableHUD && !GUI.DisableUpperHUD) { inGameHUD.UpdateManually(deltaTime); chatBox.Update(deltaTime); cameraFollowsSub.Visible = Character.Controlled == null; - - if (Character.Controlled == null) - { - myCharacterFrameOpenState = GameMain.NetLobbyScreen.MyCharacterFrameOpen ? myCharacterFrameOpenState + deltaTime * 5 : myCharacterFrameOpenState - deltaTime * 5; - myCharacterFrameOpenState = MathHelper.Clamp(myCharacterFrameOpenState, 0.0f, 1.0f); - - var myCharFrame = GameMain.NetLobbyScreen.MyCharacterFrame; - int padding = GameMain.GraphicsWidth - myCharFrame.Parent.Rect.Right; - - myCharFrame.RectTransform.AbsoluteOffset = - Vector2.SmoothStep(new Vector2(-myCharFrame.Rect.Width - padding, 0.0f), new Vector2(-padding, 0), myCharacterFrameOpenState).ToPoint(); - } } if (Character.Controlled == null || Character.Controlled.IsDead) { diff --git a/Barotrauma/BarotraumaClient/Source/Networking/ServerInfo.cs b/Barotrauma/BarotraumaClient/Source/Networking/ServerInfo.cs index 034fd96bc..47d7e552f 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/ServerInfo.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/ServerInfo.cs @@ -25,6 +25,7 @@ namespace Barotrauma.Networking public SelectionMode? ModeSelectionMode; public SelectionMode? SubSelectionMode; public bool? AllowSpectating; + public bool? VoipEnabled; public bool? AllowRespawn; public YesNoMaybe? TraitorsEnabled; public string GameMode; @@ -150,11 +151,14 @@ namespace Barotrauma.Networking else allowRespawn.Selected = AllowRespawn.Value; - /*new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), columnRight.RectTransform), TextManager.Get("ServerListHasPassword")) + var voipEnabledTickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), columnRight.RectTransform), TextManager.Get("serversettingsvoicechatenabled")) { - Selected = HasPassword, CanBeFocused = false - };*/ + }; + if (!VoipEnabled.HasValue) + new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.8f), voipEnabledTickBox.Box.RectTransform, Anchor.Center), "?", textAlignment: Alignment.Center); + else + voipEnabledTickBox.Selected = VoipEnabled.Value; var usingWhiteList = new GUITickBox(new RectTransform(new Vector2(1, elementHeight), columnRight.RectTransform), TextManager.Get("ServerListUsingWhitelist")) { diff --git a/Barotrauma/BarotraumaClient/Source/Networking/ServerSettings.cs b/Barotrauma/BarotraumaClient/Source/Networking/ServerSettings.cs index 335964b17..7607be585 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/ServerSettings.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/ServerSettings.cs @@ -388,7 +388,7 @@ namespace Barotrauma.Networking ToolTip = TextManager.Get("ServerSettingsMinRespawnToolTip") }; - string minRespawnLabel = TextManager.Get("ServerSettingsMinRespawn"); + string minRespawnLabel = TextManager.Get("ServerSettingsMinRespawn") + " "; CreateLabeledSlider(roundsTab, "", out slider, out sliderLabel); slider.ToolTip = minRespawnText.ToolTip; slider.UserData = minRespawnText; @@ -407,7 +407,7 @@ namespace Barotrauma.Networking ToolTip = TextManager.Get("ServerSettingsRespawnDurationToolTip") }; - string respawnDurationLabel = TextManager.Get("ServerSettingsRespawnDuration"); + string respawnDurationLabel = TextManager.Get("ServerSettingsRespawnDuration") + " "; CreateLabeledSlider(roundsTab, "", out slider, out sliderLabel); slider.ToolTip = respawnDurationText.ToolTip; slider.UserData = respawnDurationText; @@ -471,7 +471,7 @@ namespace Barotrauma.Networking { string translatedLabel = TextManager.Get($"Character.{s}", true); var monsterEnabledBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.1f), monsterFrame.Content.RectTransform) { MinSize = new Point(0, 25) }, - label: translatedLabel != null ? translatedLabel : s) + label: translatedLabel ?? s) { Selected = tempMonsterEnabled[s], OnSelected = (GUITickBox tb) => @@ -573,7 +573,7 @@ namespace Barotrauma.Networking //*********************************************** - string autoRestartDelayLabel = TextManager.Get("ServerSettingsAutoRestartDelay"); + string autoRestartDelayLabel = TextManager.Get("ServerSettingsAutoRestartDelay") + " "; var startIntervalText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), autoRestartDelayLabel); var startIntervalSlider = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), barSize: 0.1f) { @@ -617,7 +617,7 @@ namespace Barotrauma.Networking GetPropertyData("AllowVoteKick").AssignGUIComponent(voteKickBox); CreateLabeledSlider(serverTab, "ServerSettingsKickVotesRequired", out slider, out sliderLabel); - string votesRequiredLabel = sliderLabel.Text; + string votesRequiredLabel = sliderLabel.Text + " "; slider.Step = 0.2f; slider.Range = new Vector2(0.5f, 1.0f); slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) => @@ -629,7 +629,7 @@ namespace Barotrauma.Networking slider.OnMoved(slider, slider.BarScroll); CreateLabeledSlider(serverTab, "ServerSettingsAutobanTime", out slider, out sliderLabel); - string autobanLabel = sliderLabel.Text; + string autobanLabel = sliderLabel.Text + " "; slider.Step = 0.05f; slider.Range = new Vector2(0.0f, MaxAutoBanTime); slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) => @@ -681,8 +681,8 @@ namespace Barotrauma.Networking traitorRatioSlider.Range = new Vector2(1.0f, maxPlayers); } - string traitorRatioLabel = TextManager.Get("ServerSettingsTraitorRatio"); - string traitorCountLabel = TextManager.Get("ServerSettingsTraitorCount"); + string traitorRatioLabel = TextManager.Get("ServerSettingsTraitorRatio") + " "; + string traitorCountLabel = TextManager.Get("ServerSettingsTraitorCount") + " "; traitorRatioSlider.Range = new Vector2(0.1f, 1.0f); traitorRatioSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) => diff --git a/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs b/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs index bcc5d714e..9a729b108 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs @@ -214,6 +214,7 @@ namespace Barotrauma.Steam } if (s.Rules.ContainsKey("allowspectating")) serverInfo.AllowSpectating = s.Rules["allowspectating"] == "True"; if (s.Rules.ContainsKey("allowrespawn")) serverInfo.AllowRespawn = s.Rules["allowrespawn"] == "True"; + if (s.Rules.ContainsKey("voicechatenabled")) serverInfo.VoipEnabled = s.Rules["voicechatenabled"] == "True"; if (s.Rules.ContainsKey("traitors")) { if (Enum.TryParse(s.Rules["traitors"], out YesNoMaybe traitorsEnabled)) serverInfo.TraitorsEnabled = traitorsEnabled; diff --git a/Barotrauma/BarotraumaClient/Source/Networking/Voip/VoipClient.cs b/Barotrauma/BarotraumaClient/Source/Networking/Voip/VoipClient.cs index b1da9bde6..1ad61e4cd 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/Voip/VoipClient.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/Voip/VoipClient.cs @@ -115,7 +115,7 @@ namespace Barotrauma.Networking } } GameMain.NetLobbyScreen.SetPlayerSpeaking(client); - GameMain.GameSession?.CrewManager?.SetPlayerSpeaking(client); + GameMain.GameSession?.CrewManager?.SetClientSpeaking(client); } } diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs b/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs index 3ad2a9ac7..c387484f4 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs @@ -76,6 +76,20 @@ namespace Barotrauma new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, TextManager.Get("SelectedSub") + ":"); subList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.65f), leftColumn.RectTransform)) { ScrollBarVisible = true }; + + var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.07f), leftColumn.RectTransform), isHorizontal: true) + { + Stretch = true, + RelativeSpacing = 0.02f + }; + new GUITextBlock(new RectTransform(new Vector2(0.3f, 1.0f), filterContainer.RectTransform), TextManager.Get("FilterMapEntities"), textAlignment: Alignment.CenterLeft, font: GUI.Font); + var searchBox = new GUITextBox(new RectTransform(new Vector2(0.9f, 1.0f), filterContainer.RectTransform), font: GUI.Font); + + searchBox.OnTextChanged += (textBox, text) => { FilterSubs(subList, text); return true; }; + var clearButton = new GUIButton(new RectTransform(new Vector2(0.15f, 1.0f), filterContainer.RectTransform), "x") + { + OnClicked = (btn, userdata) => { searchBox.Text = ""; FilterSubs(subList, ""); searchBox.Flash(Color.White); return true; } + }; if (!isMultiplayer) { subList.OnSelected = OnSubSelected; } @@ -186,6 +200,16 @@ namespace Barotrauma seedBox.Text = ToolBox.RandomSeed(8); } + private void FilterSubs(GUIListBox subList, string filter) + { + foreach (GUIComponent child in subList.Content.Children) + { + var sub = child.UserData as Submarine; + if (sub == null) { return; } + child.Visible = string.IsNullOrEmpty(filter) ? true : sub.Name.ToLower().Contains(filter.ToLower()); + } + } + private bool OnSubSelected(GUIComponent component, object obj) { if (subPreviewContainer == null) { return false; } diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs b/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs index 655c6fb9d..46c54674e 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs @@ -16,8 +16,11 @@ namespace Barotrauma private GUIListBox characterList; + private MapEntityCategory selectedItemCategory = MapEntityCategory.Equipment; + private GUIListBox myItemList; private GUIListBox storeItemList; + private GUITextBox searchBox; private GUIComponent missionPanel; private GUIComponent selectedLocationInfo; @@ -66,7 +69,7 @@ namespace Barotrauma var outpostBtn = new GUIButton(new RectTransform(new Vector2(0.15f, 0.55f), topPanelContent.RectTransform), TextManager.Get("Outpost"), textAlignment: Alignment.Center, style: "GUISlopedHeader") { - OnClicked = (btn, userdata) => { SelectTab(Tab.Map); return true; } + OnClicked = (btn, userdata) => { SelectTab(Tab.Map); return true; } }; outpostBtn.TextBlock.Font = GUI.LargeFont; outpostBtn.TextBlock.AutoScale = true; @@ -170,10 +173,27 @@ namespace Barotrauma RelativeSpacing = 0.02f }; - new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), storeContent.RectTransform), "", font: GUI.LargeFont) + var storeContentTop = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), storeContent.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft) + { + Stretch = true + }; + + new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), storeContentTop.RectTransform), "", font: GUI.LargeFont) { TextGetter = GetMoney }; + var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 0.5f), storeContentTop.RectTransform), isHorizontal: true) + { + Stretch = true, + RelativeSpacing = 0.02f + }; + new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), filterContainer.RectTransform), TextManager.Get("FilterMapEntities"), textAlignment: Alignment.CenterRight, font: GUI.Font); + searchBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 1.0f), filterContainer.RectTransform), font: GUI.Font); + searchBox.OnTextChanged += (textBox, text) => { FilterStoreItems(null, text); return true; }; + var clearButton = new GUIButton(new RectTransform(new Vector2(0.2f, 1.0f), filterContainer.RectTransform), "x") + { + OnClicked = (btn, userdata) => { searchBox.Text = ""; FilterStoreItems(selectedItemCategory, ""); searchBox.Flash(Color.White); return true; } + }; var storeItemLists = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.8f), storeContent.RectTransform), isHorizontal: true) { @@ -196,7 +216,7 @@ namespace Barotrauma "", style: "ItemCategory" + category.ToString()) { UserData = category, - OnClicked = (btn, userdata) => { SelectItemCategory((MapEntityCategory)userdata); return true; } + OnClicked = (btn, userdata) => { FilterStoreItems((MapEntityCategory)userdata, searchBox.Text); return true; } }; itemCategoryButtons.Add(categoryButton); @@ -212,7 +232,8 @@ namespace Barotrauma CanBeFocused = false }; } - SelectItemCategory(MapEntityCategory.Equipment); + FillStoreItemList(); + FilterStoreItems(MapEntityCategory.Equipment, ""); // repair tab ------------------------------------------------------------------------- @@ -230,7 +251,7 @@ namespace Barotrauma RelativeSpacing = 0.05f, Stretch = true }; - new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.2f), crewContent.RectTransform), "", font: GUI.LargeFont) + new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.2f), repairContent.RectTransform), "", font: GUI.LargeFont) { TextGetter = GetMoney }; @@ -254,14 +275,22 @@ namespace Barotrauma { OnClicked = (btn, userdata) => { - if (campaign.Money >= CampaignMode.HullRepairCost) + if (campaign.PurchasedHullRepairs) { - campaign.Money -= CampaignMode.HullRepairCost; - campaign.PurchasedHullRepairs = true; - GameMain.Client?.SendCampaignState(); - btn.GetChild().Selected = true; + campaign.Money += CampaignMode.HullRepairCost; + campaign.PurchasedHullRepairs = false; } - btn.Enabled = false; + else + { + if (campaign.Money >= CampaignMode.HullRepairCost) + { + campaign.Money -= CampaignMode.HullRepairCost; + campaign.PurchasedHullRepairs = true; + } + } + GameMain.Client?.SendCampaignState(); + btn.GetChild().Selected = campaign.PurchasedHullRepairs; + return true; } }; @@ -289,14 +318,22 @@ namespace Barotrauma { OnClicked = (btn, userdata) => { - if (campaign.Money >= CampaignMode.ItemRepairCost) + if (campaign.PurchasedItemRepairs) { - campaign.Money -= CampaignMode.ItemRepairCost; - campaign.PurchasedItemRepairs = true; - GameMain.Client?.SendCampaignState(); - btn.GetChild().Selected = true; + campaign.Money += CampaignMode.ItemRepairCost; + campaign.PurchasedItemRepairs = false; } - btn.Enabled = false; + else + { + if (campaign.Money >= CampaignMode.ItemRepairCost) + { + campaign.Money -= CampaignMode.ItemRepairCost; + campaign.PurchasedItemRepairs = true; + } + } + GameMain.Client?.SendCampaignState(); + btn.GetChild().Selected = campaign.PurchasedItemRepairs; + return true; } }; @@ -434,7 +471,8 @@ namespace Barotrauma else { //refresh store view - SelectItemCategory(MapEntityCategory.Equipment); + FillStoreItemList(); + FilterStoreItems(MapEntityCategory.Equipment, searchBox.Text); } } @@ -747,43 +785,54 @@ namespace Barotrauma { case Tab.Repair: repairHullsButton.Enabled = - !Campaign.PurchasedHullRepairs && Campaign.Money >= CampaignMode.HullRepairCost && + (Campaign.PurchasedHullRepairs || Campaign.Money >= CampaignMode.HullRepairCost) && (GameMain.Client == null || GameMain.Client.HasPermission(Networking.ClientPermissions.ManageCampaign)); repairHullsButton.GetChild().Selected = Campaign.PurchasedHullRepairs; repairItemsButton.Enabled = - !Campaign.PurchasedItemRepairs && Campaign.Money >= CampaignMode.ItemRepairCost && + (Campaign.PurchasedItemRepairs || Campaign.Money >= CampaignMode.ItemRepairCost) && (GameMain.Client == null || GameMain.Client.HasPermission(Networking.ClientPermissions.ManageCampaign)); repairItemsButton.GetChild().Selected = Campaign.PurchasedItemRepairs; break; } } - private bool SelectItemCategory(MapEntityCategory category) + private void FillStoreItemList() { storeItemList.ClearChildren(); int width = storeItemList.Rect.Width; foreach (MapEntityPrefab mapEntityPrefab in MapEntityPrefab.List) { - if (!(mapEntityPrefab is ItemPrefab itemPrefab) || !itemPrefab.Category.HasFlag(category)) continue; - + if (!(mapEntityPrefab is ItemPrefab itemPrefab)) { continue; } PriceInfo priceInfo = itemPrefab.GetPrice(Campaign.Map.CurrentLocation); if (priceInfo == null) continue; CreateItemFrame(new PurchasedItem(itemPrefab, 0), priceInfo, storeItemList, width); } - storeItemList.Content.RectTransform.SortChildren( (x, y) => (x.GUIComponent.UserData as PurchasedItem).ItemPrefab.Name.CompareTo((y.GUIComponent.UserData as PurchasedItem).ItemPrefab.Name)); + } + private void FilterStoreItems(MapEntityCategory? category, string filter) + { + if (category.HasValue) + { + selectedItemCategory = category.Value; + } + foreach (GUIComponent child in storeItemList.Content.Children) + { + var item = child.UserData as PurchasedItem; + if (item?.ItemPrefab?.Name == null) { continue; } + child.Visible = + (!category.HasValue || item.ItemPrefab.Category.HasFlag(category.Value)) && + (string.IsNullOrEmpty(filter) || item.ItemPrefab.Name.ToLower().Contains(searchBox.Text.ToLower())); + } foreach (GUIButton btn in itemCategoryButtons) { - btn.Selected = (MapEntityCategory)btn.UserData == category; + btn.Selected = (MapEntityCategory)btn.UserData == selectedItemCategory; } - + storeItemList.UpdateScrollBarSize(); storeItemList.BarScroll = 0.0f; - - return true; } public string GetMoney() diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs index bb865ab01..93c47bb39 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs @@ -92,7 +92,6 @@ namespace Barotrauma SoundPlayer.OverrideMusicType = "none"; SoundPlayer.OverrideMusicDuration = null; - GameMain.SoundManager.SetCategoryGainMultiplier("default", 0.0f); GameMain.SoundManager.SetCategoryGainMultiplier("waterambience", 0.0f); GUI.ForceMouseOn(null); @@ -127,6 +126,14 @@ namespace Barotrauma OpenDoors(); GameMain.Instance.OnResolutionChanged += OnResolutionChanged; instance = this; + + if (!GameMain.Config.EditorDisclaimerShown) + { + GameMain.Instance.ShowEditorDisclaimer(); + } + OpenDoors(); + GameMain.Instance.OnResolutionChanged += OnResolutionChanged; + instance = this; } private void ResetVariables() @@ -179,7 +186,6 @@ namespace Barotrauma base.Deselect(); SoundPlayer.OverrideMusicType = null; - GameMain.SoundManager.SetCategoryGainMultiplier("default", GameMain.Config.SoundVolume); GameMain.SoundManager.SetCategoryGainMultiplier("waterambience", GameMain.Config.SoundVolume); GUI.ForceMouseOn(null); @@ -1776,8 +1782,20 @@ namespace Barotrauma Vector2 buttonSize = new Vector2(1, 0.04f); Vector2 toggleSize = new Vector2(0.03f, 0.03f); Point margin = new Point(40, 60); - rightPanel = new GUIFrame(new RectTransform(new Vector2(0.15f, 0.95f), parent: Frame.RectTransform, anchor: Anchor.CenterRight) { RelativeOffset = new Vector2(0.01f, 0) }); - var layoutGroup = new GUILayoutGroup(new RectTransform(new Point(rightPanel.Rect.Width - margin.X, rightPanel.Rect.Height - margin.Y), rightPanel.RectTransform, Anchor.Center)); + rightPanel = new GUIFrame(new RectTransform(new Vector2(0.15f, 1.0f), parent: Frame.RectTransform, anchor: Anchor.CenterRight), style: "GUIFrameRight"); + var layoutGroup = new GUILayoutGroup(new RectTransform(new Point(rightPanel.Rect.Width - margin.X, rightPanel.Rect.Height - margin.Y), rightPanel.RectTransform, Anchor.Center)) + { + Stretch = true + }; + + var disclaimerBtnHolder = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.04f), layoutGroup.RectTransform), style: null); + + var disclaimerBtn = new GUIButton(new RectTransform(new Vector2(1.0f, 0.8f), disclaimerBtnHolder.RectTransform, Anchor.TopRight), style: "GUINotificationButton") + { + OnClicked = (btn, userdata) => { GameMain.Instance.ShowEditorDisclaimer(); return true; } + }; + disclaimerBtn.RectTransform.MaxSize = new Point(disclaimerBtn.Rect.Height); + var characterDropDown = new GUIDropDown(new RectTransform(new Vector2(1, 0.04f), layoutGroup.RectTransform), elementCount: 10, style: null); characterDropDown.ListBox.Color = new Color(characterDropDown.ListBox.Color.R, characterDropDown.ListBox.Color.G, characterDropDown.ListBox.Color.B, byte.MaxValue); foreach (var file in AllFiles) @@ -1808,14 +1826,16 @@ namespace Barotrauma return true; }; } - var charButtons = new GUIFrame(new RectTransform(buttonSize, parent: layoutGroup.RectTransform), style: null); - var prevCharacterButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1), charButtons.RectTransform, Anchor.TopLeft), GetCharacterEditorTranslation("PreviousCharacter")); + var charButtons = new GUIFrame(new RectTransform(new Vector2(buttonSize.X, buttonSize.Y * 1.5f), parent: layoutGroup.RectTransform), style: null); + var prevCharacterButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), charButtons.RectTransform, Anchor.TopLeft), GetCharacterEditorTranslation("PreviousCharacter")); + prevCharacterButton.TextBlock.AutoScale = true; prevCharacterButton.OnClicked += (b, obj) => { SpawnCharacter(GetPreviousConfigFile()); return true; }; - var nextCharacterButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1), charButtons.RectTransform, Anchor.TopRight), GetCharacterEditorTranslation("NextCharacter")); + var nextCharacterButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), charButtons.RectTransform, Anchor.TopRight), GetCharacterEditorTranslation("NextCharacter")); + prevCharacterButton.TextBlock.AutoScale = true; nextCharacterButton.OnClicked += (b, obj) => { SpawnCharacter(GetNextConfigFile()); diff --git a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs index e9adfa167..f136ff3a2 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs @@ -158,14 +158,7 @@ namespace Barotrauma get; private set; } - - public GUIFrame MyCharacterFrame - { - get { return myCharacterFrame; } - } - - public bool MyCharacterFrameOpen; - + public GUIFrame InfoFrame { get { return infoFrame; } @@ -293,44 +286,6 @@ namespace Barotrauma myCharacterFrame = new GUIFrame(new RectTransform(new Vector2(0.3f - panelSpacing, 0.65f), defaultModeContainer.RectTransform, Anchor.TopRight)); playerInfoContainer = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), myCharacterFrame.RectTransform, Anchor.Center), style: null); - playYourself = new GUITickBox(new RectTransform(new Vector2(0.06f, 0.06f), myCharacterFrame.RectTransform) { RelativeOffset = new Vector2(0.05f,0.05f) }, - TextManager.Get("PlayYourself")) - { - Selected = true, - OnSelected = TogglePlayYourself, - UserData = "playyourself" - }; - - var toggleMyPlayerFrame = new GUIButton(new RectTransform(new Point(25, 70), myCharacterFrame.RectTransform, Anchor.TopLeft, Pivot.TopRight), "", style: "GUIButtonHorizontalArrow"); - toggleMyPlayerFrame.OnClicked += (GUIButton btn, object userdata) => - { - MyCharacterFrameOpen = !MyCharacterFrameOpen; - foreach (GUIComponent child in btn.Children) - { - child.SpriteEffects = MyCharacterFrameOpen ? SpriteEffects.FlipHorizontally : SpriteEffects.None; - } - return true; - }; - - playYourself = new GUITickBox(new RectTransform(new Vector2(0.06f, 0.06f), myCharacterFrame.RectTransform) { RelativeOffset = new Vector2(0.05f,0.05f) }, - TextManager.Get("PlayYourself")) - { - Selected = true, - OnSelected = TogglePlayYourself, - UserData = "playyourself" - }; - - var toggleMyPlayerFrame = new GUIButton(new RectTransform(new Point(25, 70), myCharacterFrame.RectTransform, Anchor.TopLeft, Pivot.TopRight), "", style: "GUIButtonHorizontalArrow"); - toggleMyPlayerFrame.OnClicked += (GUIButton btn, object userdata) => - { - MyCharacterFrameOpen = !MyCharacterFrameOpen; - foreach (GUIComponent child in btn.Children) - { - child.SpriteEffects = MyCharacterFrameOpen ? SpriteEffects.FlipHorizontally : SpriteEffects.None; - } - return true; - }; - playYourself = new GUITickBox(new RectTransform(new Vector2(0.06f, 0.06f), myCharacterFrame.RectTransform) { RelativeOffset = new Vector2(0.05f,0.05f) }, TextManager.Get("PlayYourself")) { @@ -725,7 +680,6 @@ namespace Barotrauma public override void Deselect() { textBox.Deselect(); - myCharacterFrame.GetChild().Visible = true; CampaignCharacterDiscarded = false; } @@ -740,10 +694,7 @@ namespace Barotrauma textBox.Select(); textBox.OnEnterPressed = GameMain.Client.EnterChatMessage; textBox.OnTextChanged += GameMain.Client.TypingChatMessage; - - myCharacterFrame.RectTransform.AbsoluteOffset = new Point(0, 0); - myCharacterFrame.GetChild().Visible = false; - + subList.Enabled = AllowSubSelection;// || GameMain.Server != null; shuttleList.Enabled = AllowSubSelection;// || GameMain.Server != null; diff --git a/Barotrauma/BarotraumaClient/Source/Screens/SpriteEditorScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/SpriteEditorScreen.cs index 56adb609f..f924e04a8 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/SpriteEditorScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/SpriteEditorScreen.cs @@ -329,6 +329,8 @@ namespace Barotrauma { element.Elements("sprite").ForEach(s => CreateSprite(s)); element.Elements("Sprite").ForEach(s => CreateSprite(s)); + element.Elements("backgroundsprite").ForEach(s => CreateSprite(s)); + element.Elements("BackgroundSprite").ForEach(s => CreateSprite(s)); element.Elements("brokensprite").ForEach(s => CreateSprite(s)); element.Elements("BrokenSprite").ForEach(s => CreateSprite(s)); element.Elements("containedsprite").ForEach(s => CreateSprite(s)); diff --git a/Barotrauma/BarotraumaClient/Source/Screens/SteamWorkshopScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/SteamWorkshopScreen.cs index a9918309b..a2a112ec5 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/SteamWorkshopScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/SteamWorkshopScreen.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; +using System.Text; using System.Windows.Forms; namespace Barotrauma @@ -43,7 +44,6 @@ namespace Barotrauma private ContentPackage itemContentPackage; private Facepunch.Steamworks.Workshop.Editor itemEditor; - //private Facepunch.Steamworks.Overlay overlay; public SteamWorkshopScreen() { @@ -131,7 +131,7 @@ namespace Barotrauma OutlineColor = new Color(72, 124, 77, 255), OnClicked = (btn, userdata) => { - System.Diagnostics.Process.Start("steam://url/SteamWorkshopPage/" + SteamManager.AppID); + SteamManager.OverlayCustomURL("steam://url/SteamWorkshopPage/" + SteamManager.AppID); return true; } }; @@ -370,7 +370,7 @@ namespace Barotrauma catch (Exception e) { pendingPreviewImageDownloads.Remove(item.PreviewImageUrl); - DebugConsole.ThrowError("Downloading the preview image of the Workshop item \"" + item.Title + "\" failed.", e); + DebugConsole.ThrowError("Downloading the preview image of the Workshop item \"" + EnsureUTF8(item.Title) + "\" failed.", e); } } @@ -381,7 +381,7 @@ namespace Barotrauma CanBeFocused = false }; - var titleText = new GUITextBlock(new RectTransform(new Vector2(0.5f, 0.0f), rightColumn.RectTransform), item.Title, textAlignment: Alignment.CenterLeft, wrap: true) + var titleText = new GUITextBlock(new RectTransform(new Vector2(0.5f, 0.0f), rightColumn.RectTransform), EnsureUTF8(item.Title), textAlignment: Alignment.CenterLeft, wrap: true) { CanBeFocused = false }; @@ -398,14 +398,14 @@ namespace Barotrauma { if (SteamManager.UpdateWorkshopItem(item, out string errorMsg)) { - new GUIMessageBox("", TextManager.Get("WorkshopItemUpdated").Replace("[itemname]", item.Title)); + new GUIMessageBox("", TextManager.Get("WorkshopItemUpdated").Replace("[itemname]", EnsureUTF8(item.Title))); } else { DebugConsole.ThrowError(errorMsg); new GUIMessageBox( TextManager.Get("Error"), - TextManager.Get("WorkshopItemUpdateFailed").Replace("[itemname]", item.Title).Replace("[errormessage]", errorMsg)); + TextManager.Get("WorkshopItemUpdateFailed").Replace("[itemname]", EnsureUTF8(item.Title)).Replace("[errormessage]", errorMsg)); } btn.Enabled = false; btn.Visible = false; @@ -594,6 +594,7 @@ namespace Barotrauma { tickBox.Enabled = false; } + GameMain.Config.EnsureCoreContentPackageSelected(); } if (updateButton != null) { @@ -624,11 +625,11 @@ namespace Barotrauma //spacing new GUIFrame(new RectTransform(new Vector2(1.0f, 0.005f), content.RectTransform), style: null); - new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform), item.Title, textAlignment: Alignment.TopLeft, font: GUI.LargeFont, wrap: true); + new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform), EnsureUTF8(item.Title), textAlignment: Alignment.TopLeft, font: GUI.LargeFont, wrap: true); var creatorHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), content.RectTransform)) { IsHorizontal = true, Stretch = true }; - new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), creatorHolder.RectTransform), TextManager.Get("WorkshopItemCreator") + ": " + item.OwnerName, textAlignment: Alignment.BottomLeft, wrap: true); + new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), creatorHolder.RectTransform), TextManager.Get("WorkshopItemCreator") + ": " + EnsureUTF8(item.OwnerName), textAlignment: Alignment.BottomLeft, wrap: true); new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), creatorHolder.RectTransform, Anchor.BottomRight), TextManager.Get("WorkshopShowItemInSteam"), style: null) { @@ -638,13 +639,7 @@ namespace Barotrauma OutlineColor = new Color(72, 124, 77, 255), OnClicked = (btn, userdata) => { - // Failed attempt, might have to be activated before accessing because as of now it just throws a null for overlay - /*if (overlay.Enabled) - { - overlay.OpenUrl("steam://url/CommunityFilePage/" + item.Id); - }*/ - - System.Diagnostics.Process.Start("steam://url/CommunityFilePage/" + item.Id); + SteamManager.OverlayCustomURL("steam://url/CommunityFilePage/" + item.Id); return true; } }; @@ -667,7 +662,7 @@ namespace Barotrauma //spacing new GUIFrame(new RectTransform(new Vector2(1.0f, 0.0f), descriptionContainer.Content.RectTransform) { MinSize = new Point(0, 5) }, style: null); - new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), descriptionContainer.Content.RectTransform), item.Description, wrap: true) + new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), descriptionContainer.Content.RectTransform), EnsureUTF8(item.Description), wrap: true) { CanBeFocused = false }; @@ -745,25 +740,28 @@ namespace Barotrauma itemEditor.Tags.Add("Submarine"); itemEditor.Description = sub.Description; - string previewImagePath = Path.GetFullPath(Path.Combine(SteamManager.WorkshopItemStagingFolder, SteamManager.PreviewImageName)); - try + if (sub.PreviewImage != null) { - using (Stream s = File.Create(previewImagePath)) + string previewImagePath = Path.GetFullPath(Path.Combine(SteamManager.WorkshopItemStagingFolder, SteamManager.PreviewImageName)); + try { - sub.PreviewImage.Texture.SaveAsPng(s, (int)sub.PreviewImage.size.X, (int)sub.PreviewImage.size.Y); - itemEditor.PreviewImage = previewImagePath; + using (Stream s = File.Create(previewImagePath)) + { + sub.PreviewImage.Texture.SaveAsPng(s, (int)sub.PreviewImage.size.X, (int)sub.PreviewImage.size.Y); + itemEditor.PreviewImage = previewImagePath; + } + if (new FileInfo(previewImagePath).Length > 1024 * 1024) + { + new GUIMessageBox(TextManager.Get("Error"), TextManager.Get("WorkshopItemPreviewImageTooLarge")); + itemEditor.PreviewImage = SteamManager.DefaultPreviewImagePath; + } } - if (new FileInfo(previewImagePath).Length > 1024 * 1024) + catch (Exception e) { - new GUIMessageBox(TextManager.Get("Error"), TextManager.Get("WorkshopItemPreviewImageTooLarge")); - itemEditor.PreviewImage = SteamManager.DefaultPreviewImagePath; + DebugConsole.ThrowError("Saving submarine preview image failed.", e); + itemEditor.PreviewImage = null; } } - catch (Exception e) - { - DebugConsole.ThrowError("Saving submarine preview image failed.", e); - itemEditor.PreviewImage = null; - } } private void CreateWorkshopItem(ContentPackage contentPackage) { @@ -800,7 +798,7 @@ namespace Barotrauma if (!item.Installed) { new GUIMessageBox(TextManager.Get("Error"), - TextManager.Get("WorkshopErrorInstallRequiredToEdit").Replace("[itemname]", item.Title)); + TextManager.Get("WorkshopErrorInstallRequiredToEdit").Replace("[itemname]", EnsureUTF8(item.Title))); return; } SteamManager.CreateWorkshopItemStaging(item, out itemEditor, out itemContentPackage); @@ -1235,7 +1233,7 @@ namespace Barotrauma string pleaseWaitText = TextManager.Get("WorkshopPublishPleaseWait"); var msgBox = new GUIMessageBox( pleaseWaitText, - TextManager.Get("WorkshopPublishInProgress").Replace("[itemname]", item.Title), + TextManager.Get("WorkshopPublishInProgress").Replace("[itemname]", EnsureUTF8(item.Title)), new string[] { TextManager.Get("Cancel") }); msgBox.Buttons[0].OnClicked = (btn, userdata) => @@ -1257,13 +1255,13 @@ namespace Barotrauma if (string.IsNullOrEmpty(item.Error)) { - new GUIMessageBox("", TextManager.Get("WorkshopItemPublished").Replace("[itemname]", item.Title)); + new GUIMessageBox("", TextManager.Get("WorkshopItemPublished").Replace("[itemname]", EnsureUTF8(item.Title))); } else { new GUIMessageBox( TextManager.Get("Error"), - TextManager.Get("WorkshopItemPublishFailed").Replace("[itemname]", item.Title) + item.Error); + TextManager.Get("WorkshopItemPublishFailed").Replace("[itemname]", EnsureUTF8(item.Title)) + item.Error); } createItemFrame.ClearChildren(); @@ -1292,6 +1290,12 @@ namespace Barotrauma { } + private string EnsureUTF8(string text) + { + byte[] bytes = Encoding.Default.GetBytes(text); + return Encoding.UTF8.GetString(bytes); + } + #endregion } } diff --git a/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs index ea5e58cc2..88890c05e 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs @@ -183,6 +183,12 @@ namespace Barotrauma TextGetter = GetSubName }; + var disclaimerBtn = new GUIButton(new RectTransform(new Vector2(0.1f, 1.0f), paddedTopPanel.RectTransform, Anchor.CenterRight), style: "GUINotificationButton") + { + OnClicked = (btn, userdata) => { GameMain.Instance.ShowEditorDisclaimer(); return true; } + }; + disclaimerBtn.RectTransform.MaxSize = new Point(disclaimerBtn.Rect.Height); + linkedSubBox = new GUIDropDown(new RectTransform(new Vector2(0.15f, 0.9f), paddedTopPanel.RectTransform) { RelativeOffset = new Vector2(0.385f, 0.0f) }, TextManager.Get("AddSubButton"), elementCount: 20) { @@ -452,9 +458,10 @@ namespace Barotrauma //spacing new GUIFrame(new RectTransform(new Vector2(1.0f, 0.0f), showEntitiesHolder.RectTransform) { MinSize = new Point(0, 3) }, style: null); - new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.025f), paddedLeftPanel.RectTransform, Anchor.BottomCenter) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("PreviouslyUsedLabel")); - previouslyUsedList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.2f), paddedLeftPanel.RectTransform, Anchor.BottomCenter) { AbsoluteOffset = new Point(10, 0) }) + new GUITextBlock(new RectTransform(new Vector2(0.95f, 0.025f), paddedLeftPanel.RectTransform, Anchor.BottomCenter) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("PreviouslyUsedLabel")); + previouslyUsedList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.2f), paddedLeftPanel.RectTransform, Anchor.BottomCenter)) { + ScrollBarVisible = true, OnSelected = SelectPrefab }; @@ -886,6 +893,10 @@ namespace Barotrauma GUI.AddMessage(TextManager.Get("SubSavedNotification").Replace("[filepath]", Submarine.MainSub.FilePath), Color.Green); Submarine.RefreshSavedSub(savePath); + if (prevSavePath != null && prevSavePath != savePath) + { + Submarine.RefreshSavedSub(prevSavePath); + } linkedSubBox.ClearChildren(); foreach (Submarine sub in Submarine.SavedSubmarines) @@ -1278,9 +1289,8 @@ namespace Barotrauma { if (CharacterMode) SetCharacterMode(false); if (WiringMode) SetWiringMode(false); - - var innerFrame = new GUIFrame(new RectTransform(new Vector2(0.2f, 0.36f), loadFrame.RectTransform, Anchor.Center) { MinSize = new Point(350, 500) }); - + + loadFrame = new GUIButton(new RectTransform(Vector2.One, GUI.Canvas), style: "GUIBackgroundBlocker") { OnClicked = (btn, userdata) => { if (GUI.MouseOn == btn || GUI.MouseOn == btn.TextBlock) loadFrame = null; return true; }, @@ -1288,10 +1298,9 @@ namespace Barotrauma var innerFrame = new GUIFrame(new RectTransform(new Vector2(0.2f, 0.36f), loadFrame.RectTransform, Anchor.Center) { MinSize = new Point(350, 500) }); - var paddedLoadFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), innerFrame.RectTransform, Anchor.Center)) { Stretch = true, RelativeSpacing = 0.05f }; + var paddedLoadFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), innerFrame.RectTransform, Anchor.Center)) { Stretch = true, RelativeSpacing = 0.02f }; var deleteButtonHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), paddedLoadFrame.RectTransform, Anchor.Center)); - var subList = new GUIListBox(new RectTransform(new Vector2(1.0f, 1.0f), paddedLoadFrame.RectTransform)) { ScrollBarVisible = true, @@ -1302,6 +1311,19 @@ namespace Barotrauma } }; + var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), paddedLoadFrame.RectTransform), isHorizontal: true) + { + Stretch = true, + RelativeSpacing = 0.02f + }; + new GUITextBlock(new RectTransform(new Vector2(0.3f, 1.0f), filterContainer.RectTransform), TextManager.Get("FilterMapEntities"), textAlignment: Alignment.CenterLeft, font: GUI.Font); + var searchBox = new GUITextBox(new RectTransform(new Vector2(0.9f, 1.0f), filterContainer.RectTransform), font: GUI.Font); + searchBox.OnTextChanged += (textBox, text) => { FilterSubs(subList, text); return true; }; + var clearButton = new GUIButton(new RectTransform(new Vector2(0.15f, 1.0f), filterContainer.RectTransform), "x") + { + OnClicked = (btn, userdata) => { searchBox.Text = ""; FilterSubs(subList, ""); searchBox.Flash(Color.White); return true; } + }; + foreach (Submarine sub in Submarine.SavedSubmarines) { GUITextBlock textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), subList.Content.RectTransform) { MinSize = new Point(0, 30) }, @@ -1363,6 +1385,16 @@ namespace Barotrauma } private void FilterSubs(GUIListBox subList, string filter) + { + foreach (GUIComponent child in subList.Content.Children) + { + var sub = child.UserData as Submarine; + if (sub == null) { return; } + child.Visible = string.IsNullOrEmpty(filter) ? true : sub.Name.ToLower().Contains(filter.ToLower()); + } + } + + private bool LoadSub(GUIButton button, object obj) { if (loadFrame == null) { diff --git a/Barotrauma/BarotraumaClient/Source/Serialization/SerializableEntityEditor.cs b/Barotrauma/BarotraumaClient/Source/Serialization/SerializableEntityEditor.cs index cb0e9cd57..6d244e815 100644 --- a/Barotrauma/BarotraumaClient/Source/Serialization/SerializableEntityEditor.cs +++ b/Barotrauma/BarotraumaClient/Source/Serialization/SerializableEntityEditor.cs @@ -510,6 +510,7 @@ namespace Barotrauma ToolTip = toolTip, Font = GUI.SmallFont, Text = value, + OverflowClip = true, OnEnterPressed = (textBox, text) => { if (property.TrySetValue(entity, text)) diff --git a/Barotrauma/BarotraumaClient/Source/Sounds/SoundPlayer.cs b/Barotrauma/BarotraumaClient/Source/Sounds/SoundPlayer.cs index aca4de939..3c1705000 100644 --- a/Barotrauma/BarotraumaClient/Source/Sounds/SoundPlayer.cs +++ b/Barotrauma/BarotraumaClient/Source/Sounds/SoundPlayer.cs @@ -35,6 +35,7 @@ namespace Barotrauma { public readonly string File; public readonly string Type; + public readonly bool DuckVolume; public readonly Vector2 IntensityRange; @@ -43,6 +44,7 @@ namespace Barotrauma this.File = Path.GetFullPath(element.GetAttributeString("file", "")); this.Type = element.GetAttributeString("type", "").ToLowerInvariant(); this.IntensityRange = element.GetAttributeVector2("intensityrange", new Vector2(0.0f, 100.0f)); + this.DuckVolume = element.GetAttributeBool("duckvolume", false); } } @@ -451,8 +453,7 @@ namespace Barotrauma "ambient", new Vector2(GameMain.SoundManager.ListenerPosition.X, GameMain.SoundManager.ListenerPosition.Y) + Rand.Vector(100.0f), Rand.Range(0.5f, 1.0f), - 1000.0f, - new Vector2(GameMain.SoundManager.ListenerPosition.X, GameMain.SoundManager.ListenerPosition.Y) + Rand.Vector(100.0f)); + 1000.0f); ambientSoundTimer = Rand.Range(ambientSoundInterval.X, ambientSoundInterval.Y); } @@ -466,23 +467,31 @@ namespace Barotrauma return matchingSounds[Rand.Int(matchingSounds.Count)]; } + /// + /// Play a sound defined in a sound xml file without any positional effects. + /// public static SoundChannel PlaySound(string soundTag, float volume = 1.0f) { var sound = GetSound(soundTag); return sound?.Play(volume); } - public static SoundChannel PlaySound(string soundTag, float volume, float range, Vector2 position, Hull hullGuess = null) + /// + /// Play a sound defined in a sound xml file. If the volume or range parameters are omitted, the volume and range defined in the sound xml are used. + /// + public static SoundChannel PlaySound(string soundTag, Vector2 position, float? volume = null, float? range = null, Hull hullGuess = null) { var sound = GetSound(soundTag); if (sound == null) return null; - return PlaySound(sound, sound.BaseGain * volume, range, position, hullGuess); + return PlaySound(sound, position, volume ?? sound.BaseGain, range ?? sound.BaseFar, hullGuess); } - public static SoundChannel PlaySound(Sound sound, float volume, float range, Vector2 position, Hull hullGuess = null) + public static SoundChannel PlaySound(Sound sound, Vector2 position, float? volume = null, float? range = null, Hull hullGuess = null) { - if (Vector2.DistanceSquared(new Vector2(GameMain.SoundManager.ListenerPosition.X, GameMain.SoundManager.ListenerPosition.Y), position) > range * range) return null; - return sound.Play(sound.BaseGain * volume, range, position, muffle: ShouldMuffleSound(Character.Controlled, position, range, hullGuess)); + float far = range ?? sound.BaseFar; + + if (Vector2.DistanceSquared(new Vector2(GameMain.SoundManager.ListenerPosition.X, GameMain.SoundManager.ListenerPosition.Y), position) > far * far) return null; + return sound.Play(volume ?? sound.BaseGain, far, position, muffle: ShouldMuffleSound(Character.Controlled, position, far, hullGuess)); } private static void UpdateMusic(float deltaTime) @@ -516,7 +525,7 @@ namespace Barotrauma //switch the music if nothing playing atm or the currently playing clip is not suitable anymore else if (targetMusic[0] == null || currentMusic[0] == null || !suitableMusic.Any(m => m.File == currentMusic[0].Filename)) { - targetMusic[0] = suitableMusic.GetRandom(); + targetMusic[0] = suitableMusic.GetRandom(); } //get the appropriate intensity layers for current situation @@ -551,6 +560,7 @@ namespace Barotrauma updateMusicTimer = UpdateMusicInterval; } + int activeTrackCount = targetMusic.Count(m => m != null); for (int i = 0; i < MaxMusicChannels; i++) { //nothing should be playing on this channel @@ -590,7 +600,12 @@ namespace Barotrauma musicChannel[i] = currentMusic[i].Play(0.0f, "music"); musicChannel[i].Looping = true; } - musicChannel[i].Gain = MathHelper.Lerp(musicChannel[i].Gain, 1.0f, MusicLerpSpeed * deltaTime); + float targetGain = 1.0f; + if (targetMusic[i].DuckVolume) + { + targetGain = (float)Math.Sqrt(1.0f / activeTrackCount); + } + musicChannel[i].Gain = MathHelper.Lerp(musicChannel[i].Gain, targetGain, MusicLerpSpeed * deltaTime); } } } @@ -658,8 +673,7 @@ namespace Barotrauma foreach (Character character in Character.CharacterList) { if (character.IsDead || !character.Enabled) continue; - EnemyAIController enemyAI = character.AIController as EnemyAIController; - if (enemyAI == null || (!enemyAI.AttackHumans && !enemyAI.AttackRooms)) continue; + if (!(character.AIController is EnemyAIController enemyAI) || (!enemyAI.AttackHumans && !enemyAI.AttackRooms)) continue; if (targetSubmarine != null) { @@ -677,9 +691,16 @@ namespace Barotrauma } } - if (GameMain.GameSession != null && Timing.TotalTime < GameMain.GameSession.RoundStartTime + 120.0) + if (GameMain.GameSession != null) { - return "start"; + if (Submarine.Loaded != null && Level.Loaded != null && Submarine.MainSub.AtEndPosition) + { + return "levelend"; + } + if (Timing.TotalTime < GameMain.GameSession.RoundStartTime + 120.0) + { + return "start"; + } } return "default"; diff --git a/Barotrauma/BarotraumaClient/Source/Sprite/DeformAnimations/SpriteDeformation.cs b/Barotrauma/BarotraumaClient/Source/Sprite/DeformAnimations/SpriteDeformation.cs index 52d33b786..19097bf21 100644 --- a/Barotrauma/BarotraumaClient/Source/Sprite/DeformAnimations/SpriteDeformation.cs +++ b/Barotrauma/BarotraumaClient/Source/Sprite/DeformAnimations/SpriteDeformation.cs @@ -104,14 +104,7 @@ namespace Barotrauma.SpriteDeformations public Point Resolution { - get - { - if (deformationParams.Resolution.X != Deformation.GetLength(0) || deformationParams.Resolution.Y != Deformation.GetLength(1)) - { - Deformation = new Vector2[deformationParams.Resolution.X, deformationParams.Resolution.Y]; - } - return deformationParams.Resolution; - } + get { return deformationParams.Resolution; } set { SetResolution(value); } } @@ -202,6 +195,15 @@ namespace Barotrauma.SpriteDeformations public static Vector2[,] GetDeformation(IEnumerable animations, Vector2 scale) { + foreach (SpriteDeformation animation in animations) + { + if (animation.deformationParams.Resolution.X != animation.Deformation.GetLength(0) || + animation.deformationParams.Resolution.Y != animation.Deformation.GetLength(1)) + { + animation.Deformation = new Vector2[animation.deformationParams.Resolution.X, animation.deformationParams.Resolution.Y]; + } + } + Point resolution = animations.First().Resolution; if (animations.Any(a => a.Resolution != resolution)) { @@ -211,7 +213,6 @@ namespace Barotrauma.SpriteDeformations } Vector2[,] deformation = new Vector2[resolution.X, resolution.Y]; - foreach (SpriteDeformation animation in animations) { animation.GetDeformation(out Vector2[,] animDeformation, out float multiplier); diff --git a/Barotrauma/BarotraumaClient/Source/StatusEffects/StatusEffect.cs b/Barotrauma/BarotraumaClient/Source/StatusEffects/StatusEffect.cs index 778e11f82..4198d21b7 100644 --- a/Barotrauma/BarotraumaClient/Source/StatusEffects/StatusEffect.cs +++ b/Barotrauma/BarotraumaClient/Source/StatusEffects/StatusEffect.cs @@ -62,7 +62,7 @@ namespace Barotrauma { foreach (RoundSound sound in sounds) { - soundChannel = SoundPlayer.PlaySound(sound.Sound, sound.Volume, sound.Range, entity.WorldPosition, hull); + soundChannel = SoundPlayer.PlaySound(sound.Sound, entity.WorldPosition, sound.Volume, sound.Range, hull); if (soundChannel != null) soundChannel.Looping = loopSound; } } @@ -82,7 +82,7 @@ namespace Barotrauma selectedSoundIndex = Rand.Int(sounds.Count); } var selectedSound = sounds[selectedSoundIndex]; - soundChannel = SoundPlayer.PlaySound(selectedSound.Sound, selectedSound.Volume, selectedSound.Range, entity.WorldPosition, hull); + soundChannel = SoundPlayer.PlaySound(selectedSound.Sound, entity.WorldPosition, selectedSound.Volume, selectedSound.Range, hull); if (soundChannel != null) soundChannel.Looping = loopSound; } } diff --git a/Barotrauma/BarotraumaServer/Server.csproj b/Barotrauma/BarotraumaServer/Server.csproj index 3cab79257..3647a5b6d 100644 --- a/Barotrauma/BarotraumaServer/Server.csproj +++ b/Barotrauma/BarotraumaServer/Server.csproj @@ -215,7 +215,7 @@ - + PreserveNewest @@ -229,6 +229,9 @@ PreserveNewest + + PreserveNewest + diff --git a/Barotrauma/BarotraumaServer/Source/Characters/CharacterNetworking.cs b/Barotrauma/BarotraumaServer/Source/Characters/CharacterNetworking.cs index 5f0639ff0..d00a8d7eb 100644 --- a/Barotrauma/BarotraumaServer/Source/Characters/CharacterNetworking.cs +++ b/Barotrauma/BarotraumaServer/Source/Characters/CharacterNetworking.cs @@ -21,9 +21,9 @@ namespace Barotrauma { if (!Enabled) { return 1000.0f; } - if (recipient.Character == null) + if (recipient.Character == null || recipient.Character.IsDead) { - return 0.1f; + return 0.2f; } else { diff --git a/Barotrauma/BarotraumaServer/Source/GameMain.cs b/Barotrauma/BarotraumaServer/Source/GameMain.cs index 53e3623d6..279693165 100644 --- a/Barotrauma/BarotraumaServer/Source/GameMain.cs +++ b/Barotrauma/BarotraumaServer/Source/GameMain.cs @@ -53,6 +53,21 @@ namespace Barotrauma get { return Config.SelectedContentPackages; } } + + private static ContentPackage vanillaContent; + public static ContentPackage VanillaContent + { + get + { + if (vanillaContent == null) + { + // TODO: Dynamic method for defining and finding the vanilla content package. + vanillaContent = ContentPackage.List.SingleOrDefault(cp => Path.GetFileName(cp.Path).ToLowerInvariant() == "vanilla 0.9.xml"); + } + return vanillaContent; + } + } + public readonly string[] CommandLineArgs; public GameMain(string[] args) diff --git a/Barotrauma/BarotraumaServer/Source/GameSession/GameModes/MultiPlayerCampaign.cs b/Barotrauma/BarotraumaServer/Source/GameSession/GameModes/MultiPlayerCampaign.cs index 7cacaa130..271e444c2 100644 --- a/Barotrauma/BarotraumaServer/Source/GameSession/GameModes/MultiPlayerCampaign.cs +++ b/Barotrauma/BarotraumaServer/Source/GameSession/GameModes/MultiPlayerCampaign.cs @@ -212,15 +212,31 @@ namespace Barotrauma return; } - if (purchasedHullRepairs && !this.PurchasedHullRepairs && Money >= HullRepairCost) + if (purchasedHullRepairs != this.PurchasedHullRepairs) { - this.PurchasedHullRepairs = true; - Money -= HullRepairCost; + if (purchasedHullRepairs && Money >= HullRepairCost) + { + this.PurchasedHullRepairs = true; + Money -= HullRepairCost; + } + else if (!purchasedHullRepairs) + { + this.PurchasedHullRepairs = false; + Money += HullRepairCost; + } } - if (purchasedItemRepairs && !this.PurchasedItemRepairs && Money >= ItemRepairCost) + if (purchasedItemRepairs != this.PurchasedItemRepairs) { - this.PurchasedItemRepairs = true; - Money -= ItemRepairCost; + if (purchasedItemRepairs && Money >= ItemRepairCost) + { + this.PurchasedItemRepairs = true; + Money -= ItemRepairCost; + } + else if (!purchasedItemRepairs) + { + this.PurchasedItemRepairs = false; + Money += ItemRepairCost; + } } Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex); diff --git a/Barotrauma/BarotraumaServer/Source/Items/Components/Machines/Reactor.cs b/Barotrauma/BarotraumaServer/Source/Items/Components/Machines/Reactor.cs index af7fefd81..5d6439226 100644 --- a/Barotrauma/BarotraumaServer/Source/Items/Components/Machines/Reactor.cs +++ b/Barotrauma/BarotraumaServer/Source/Items/Components/Machines/Reactor.cs @@ -20,6 +20,8 @@ namespace Barotrauma.Items.Components if (!item.CanClientAccess(c)) return; + IsActive = true; + if (!autoTemp && AutoTemp) blameOnBroken = c; if (turbineOutput < targetTurbineOutput) blameOnBroken = c; if (fissionRate > targetFissionRate) blameOnBroken = c; diff --git a/Barotrauma/BarotraumaServer/Source/Map/Hull.cs b/Barotrauma/BarotraumaServer/Source/Map/Hull.cs index 3b10a7a24..3fc9ec6d3 100644 --- a/Barotrauma/BarotraumaServer/Source/Map/Hull.cs +++ b/Barotrauma/BarotraumaServer/Source/Map/Hull.cs @@ -33,7 +33,8 @@ namespace Barotrauma //update client hulls if the amount of water has changed by >10% //or if oxygen percentage has changed by 5% if (Math.Abs(lastSentVolume - waterVolume) > Volume * 0.1f || - Math.Abs(lastSentOxygen - OxygenPercentage) > 5f) + Math.Abs(lastSentOxygen - OxygenPercentage) > 5f || + FireSources.Count > 0) { sendUpdateTimer -= deltaTime; if (sendUpdateTimer < 0.0f) diff --git a/Barotrauma/BarotraumaServer/Source/Networking/RespawnManager.cs b/Barotrauma/BarotraumaServer/Source/Networking/RespawnManager.cs index 8b489f1a0..593bec08f 100644 --- a/Barotrauma/BarotraumaServer/Source/Networking/RespawnManager.cs +++ b/Barotrauma/BarotraumaServer/Source/Networking/RespawnManager.cs @@ -182,6 +182,15 @@ namespace Barotrauma.Networking } else { + //tell the respawning client they're no longer a traitor + if (GameMain.Server.TraitorManager != null && clients[i].Character != null) + { + if (GameMain.Server.TraitorManager.TraitorList.Any(t => t.Character == clients[i].Character)) + { + GameMain.Server.SendDirectChatMessage(TextManager.Get("traitorrespawnmessage"), clients[i], ChatMessageType.MessageBox); + } + } + clients[i].Character = character; character.OwnerClientIP = clients[i].Connection.RemoteEndPoint.Address.ToString(); character.OwnerClientName = clients[i].Name; diff --git a/Barotrauma/BarotraumaServer/Source/Networking/SteamManager.cs b/Barotrauma/BarotraumaServer/Source/Networking/SteamManager.cs index 025e42e8b..99b9ac68b 100644 --- a/Barotrauma/BarotraumaServer/Source/Networking/SteamManager.cs +++ b/Barotrauma/BarotraumaServer/Source/Networking/SteamManager.cs @@ -56,6 +56,7 @@ namespace Barotrauma.Steam Instance.server.SetKey("usingwhitelist", (server.ServerSettings.Whitelist != null && server.ServerSettings.Whitelist.Enabled).ToString()); Instance.server.SetKey("modeselectionmode", server.ServerSettings.ModeSelectionMode.ToString()); Instance.server.SetKey("subselectionmode", server.ServerSettings.SubSelectionMode.ToString()); + Instance.server.SetKey("voicechatenabled", server.ServerSettings.VoiceChatEnabled.ToString()); Instance.server.SetKey("allowspectating", server.ServerSettings.AllowSpectating.ToString()); Instance.server.SetKey("allowrespawn", server.ServerSettings.AllowRespawn.ToString()); Instance.server.SetKey("traitors", server.ServerSettings.TraitorsEnabled.ToString()); diff --git a/Barotrauma/BarotraumaShared/SharedCode.projitems b/Barotrauma/BarotraumaShared/SharedCode.projitems index f1aa81dab..f15f9dbd1 100644 --- a/Barotrauma/BarotraumaShared/SharedCode.projitems +++ b/Barotrauma/BarotraumaShared/SharedCode.projitems @@ -45,6 +45,7 @@ + diff --git a/Barotrauma/BarotraumaShared/SharedContent.projitems b/Barotrauma/BarotraumaShared/SharedContent.projitems index e95896c42..36cf4eb81 100644 --- a/Barotrauma/BarotraumaShared/SharedContent.projitems +++ b/Barotrauma/BarotraumaShared/SharedContent.projitems @@ -361,6 +361,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -424,6 +430,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -436,6 +445,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -1168,9 +1180,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -1225,9 +1234,6 @@ PreserveNewest - - PreserveNewest - @@ -1422,36 +1428,15 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - PreserveNewest PreserveNewest - - PreserveNewest - PreserveNewest - - PreserveNewest - - - PreserveNewest - PreserveNewest @@ -2043,6 +2028,51 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs index fb8bdbdf1..876971cab 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs @@ -122,6 +122,7 @@ namespace Barotrauma private readonly float memoryFadeTime = 0.5f; public LatchOntoAI LatchOntoAI { get; private set; } + public SwarmBehavior SwarmBehavior { get; private set; } public bool AttackHumans { @@ -215,6 +216,10 @@ namespace Barotrauma case "latchonto": LatchOntoAI = new LatchOntoAI(subElement, this); break; + case "swarm": + case "swarmbehavior": + SwarmBehavior = new SwarmBehavior(subElement, this); + break; case "targetpriority": targetingPriorities.Add(subElement.GetAttributeString("tag", "").ToLowerInvariant(), new TargetingPriority(subElement)); break; @@ -364,12 +369,8 @@ namespace Barotrauma default: throw new NotImplementedException(); } - - // Just some debug code that makes the characters to follow the mouse cursor - //run = true; - //Vector2 mousePos = ConvertUnits.ToSimUnits(Screen.Selected.Cam.ScreenToWorld(PlayerInput.MousePosition)); - //steeringManager.SteeringSeek(mousePos, Character.AnimController.GetCurrentSpeed(run)); - + + SwarmBehavior?.Update(deltaTime); steeringManager.Update(Character.AnimController.GetCurrentSpeed(run)); } @@ -790,6 +791,7 @@ namespace Barotrauma { UpdateLimbAttack(deltaTime, AttackingLimb, attackSimPos, distance); } + return false; } private bool SteerThroughGap(Structure wall, WallSection section, Vector2 targetWorldPos, float deltaTime) @@ -1070,6 +1072,8 @@ namespace Barotrauma private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure; + private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure; + //goes through all the AItargets, evaluates how preferable it is to attack the target, //whether the Character can see/hear the target and chooses the most preferable target within //sight/hearing range diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs index 9015503f5..adb39a51a 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs @@ -66,7 +66,8 @@ namespace Barotrauma if (!goToObjective.IsCompleted() && !goToObjective.CanBeCompleted) { abandon = true; - character?.Speak(TextManager.Get("DialogCannotRepair").Replace("[itemname]", Item.Name), null, 0.0f, "cannotrepair", 10.0f); + // TODO: Add: "Can't repair [item]!" + //character?.Speak(TextManager.Get("DialogCannotRepair").Replace("[itemname]", Item.Name), null, 0.0f, "cannotrepair", 10.0f); } goToObjective = null; } @@ -116,7 +117,8 @@ namespace Barotrauma { // If the current condition is less than the previous condition, we can't complete the task, so let's abandon it. The item is probably deteriorating at a greater speed than we can repair it. abandon = true; - character?.Speak(TextManager.Get("DialogCannotRepair").Replace("[itemname]", Item.Name), null, 0.0f, "cannotrepair", 10.0f); + // TODO: Add: "Can't repair [item]!" + //character?.Speak(TextManager.Get("DialogCannotRepair").Replace("[itemname]", Item.Name), null, 0.0f, "cannotrepair", 10.0f); } } repairable.CurrentFixer = abandon && repairable.CurrentFixer == character ? null : character; diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/SwarmBehavior.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/SwarmBehavior.cs index 76adf9000..3eb217589 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/SwarmBehavior.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/SwarmBehavior.cs @@ -14,16 +14,11 @@ namespace Barotrauma private float maxDistFromCenter; private float cohesion; - public List Members { get; private set; } = new List(); - public HashSet ActiveMembers { get; private set; } = new HashSet(); + private List members = new List(); - private EnemyAIController ai; + private AIController ai; - public bool IsActive { get; set; } - public bool IsEnoughMembers => ActiveMembers.Count > 1; - - - public SwarmBehavior(XElement element, EnemyAIController ai) + public SwarmBehavior(XElement element, AIController ai) { this.ai = ai; minDistFromClosest = ConvertUnits.ToSimUnits(element.GetAttributeFloat("mindistfromclosest", 10.0f)); @@ -37,36 +32,21 @@ namespace Barotrauma { if (character.AIController is EnemyAIController enemyAI && enemyAI.SwarmBehavior != null) { - enemyAI.SwarmBehavior.Members = swarm.ToList(); + enemyAI.SwarmBehavior.members = swarm.ToList(); } } } - public void Refresh() + public void Update(float deltaTime) { - Members.RemoveAll(m => m.IsDead || m.Removed); - foreach (var member in Members) - { - if (!member.AIController.Enabled && member.IsRemotePlayer || Character.Controlled == member || !((EnemyAIController)member.AIController).SwarmBehavior.IsActive) - { - ActiveMembers.Remove(member); - } - else - { - ActiveMembers.Add(member); - } - } - } + members.RemoveAll(m => m.IsDead || m.Removed); + if (members.Count < 2) { return; } - public void UpdateSteering(float deltaTime) - { - if (!IsActive) { return; } - if (!IsEnoughMembers) { return; } //calculate the "center of mass" of the swarm and the distance to the closest character in the swarm float closestDistSqr = float.MaxValue; Vector2 center = Vector2.Zero; AICharacter closest = null; - foreach (AICharacter member in Members) + foreach (AICharacter member in members) { center += member.SimPosition; if (member == ai.Character) { continue; } @@ -77,7 +57,7 @@ namespace Barotrauma closest = member; } } - center /= Members.Count; + center /= members.Count; if (closest == null) { return; } @@ -103,11 +83,11 @@ namespace Barotrauma if (cohesion > 0.0f) { Vector2 avgVel = Vector2.Zero; - foreach (AICharacter member in Members) + foreach (AICharacter member in members) { avgVel += member.AnimController.TargetMovement; } - avgVel /= Members.Count; + avgVel /= members.Count; ai.SteeringManager.SteeringManual(deltaTime, avgVel * cohesion); } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Animation/FishAnimController.cs b/Barotrauma/BarotraumaShared/Source/Characters/Animation/FishAnimController.cs index 2839536b5..6f049f1a6 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Animation/FishAnimController.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Animation/FishAnimController.cs @@ -588,6 +588,7 @@ namespace Barotrauma } } + float prevWalkPos = WalkPos; WalkPos -= MainLimb.LinearVelocity.X * (CurrentAnimationParams.CycleSpeed / RagdollParams.JointScale / 100.0f); Vector2 transformedStepSize = Vector2.Zero; @@ -623,6 +624,11 @@ namespace Barotrauma bool playFootstepSound = false; if (limb.type == LimbType.LeftFoot) { + if (Math.Sign(Math.Sin(prevWalkPos)) > 0 && Math.Sign(transformedStepSize.Y) < 0) + { + playFootstepSound = true; + } + limb.DebugRefPos = footPos + Vector2.UnitX * movement.X * 0.1f; limb.DebugTargetPos = footPos + new Vector2( transformedStepSize.X + movement.X * 0.1f, @@ -631,13 +637,20 @@ namespace Barotrauma } else if (limb.type == LimbType.RightFoot) { + if (Math.Sign(Math.Sin(prevWalkPos)) < 0 && Math.Sign(transformedStepSize.Y) > 0) + { + playFootstepSound = true; + } + limb.DebugRefPos = footPos + Vector2.UnitX * movement.X * 0.1f; limb.DebugTargetPos = footPos + new Vector2( -transformedStepSize.X + movement.X * 0.1f, (-transformedStepSize.Y > 0.0f) ? -transformedStepSize.Y : 0.0f); limb.MoveToPos(limb.DebugTargetPos, FootMoveForce); } - +#if CLIENT + if (playFootstepSound) { PlayImpactSound(limb); } +#endif if (CurrentGroundedParams.FootAnglesInRadians.ContainsKey(limb.limbParams.ID)) { SmoothRotateWithoutWrapping(limb, diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Animation/HumanoidAnimController.cs b/Barotrauma/BarotraumaShared/Source/Characters/Animation/HumanoidAnimController.cs index da531aed0..5de8c9140 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Animation/HumanoidAnimController.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Animation/HumanoidAnimController.cs @@ -1131,12 +1131,12 @@ namespace Barotrauma #if CLIENT if (Math.Abs(leftFootPos - prevLeftFootPos) > stepHeight && leftFoot.LastImpactSoundTime < Timing.TotalTime - Limb.SoundInterval) { - SoundPlayer.PlaySound("footstep_armor_heavy", volume: 0.5f, range: 500.0f, position: leftFoot.WorldPosition); + SoundPlayer.PlaySound("footstep_armor_heavy", leftFoot.WorldPosition, hullGuess: currentHull); leftFoot.LastImpactSoundTime = (float)Timing.TotalTime; } if (Math.Abs(rightFootPos - prevRightFootPos) > stepHeight && rightFoot.LastImpactSoundTime < Timing.TotalTime - Limb.SoundInterval) { - SoundPlayer.PlaySound("footstep_armor_heavy", volume: 0.5f, range: 500.0f, position: rightFoot.WorldPosition); + SoundPlayer.PlaySound("footstep_armor_heavy", rightFoot.WorldPosition, hullGuess: currentHull); rightFoot.LastImpactSoundTime = (float)Timing.TotalTime; } #endif diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Attack.cs b/Barotrauma/BarotraumaShared/Source/Characters/Attack.cs index 8e0c79593..f89ae0d22 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Attack.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Attack.cs @@ -283,6 +283,7 @@ namespace Barotrauma if (afflictionPrefab == null) { DebugConsole.ThrowError("Error in Attack (" + parentDebugName + ") - Affliction prefab \"" + afflictionName + "\" not found."); + continue; } } else @@ -292,6 +293,7 @@ namespace Barotrauma if (afflictionPrefab == null) { DebugConsole.ThrowError("Error in Attack (" + parentDebugName + ") - Affliction prefab \"" + afflictionIdentifier + "\" not found."); + continue; } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs index daf290686..41e76e756 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs @@ -2172,7 +2172,8 @@ namespace Barotrauma public void Speak(string message, ChatMessageType? messageType = null, float delay = 0.0f, string identifier = "", float minDurationBetweenSimilar = 0.0f) { - if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) return; + if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; } + if (string.IsNullOrEmpty(message)) { return; } //already sent a similar message a moment ago if (!string.IsNullOrEmpty(identifier) && minDurationBetweenSimilar > 0.0f && @@ -2181,7 +2182,6 @@ namespace Barotrauma { return; } - aiChatMessageQueue.Add(new AIChatMessage(message, messageType, identifier, delay)); } @@ -2642,6 +2642,10 @@ namespace Barotrauma GameMain.GameSession?.CrewManager?.RemoveCharacter(this); #endif +#if CLIENT + GameMain.GameSession?.CrewManager?.RemoveCharacter(this); +#endif + #if CLIENT GameMain.GameSession?.CrewManager?.RemoveCharacter(this); #endif diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Health/CharacterHealth.cs b/Barotrauma/BarotraumaShared/Source/Characters/Health/CharacterHealth.cs index 8a2aa9ca9..4f5769f34 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Health/CharacterHealth.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Health/CharacterHealth.cs @@ -266,6 +266,12 @@ namespace Barotrauma public Affliction GetAffliction(string afflictionType, Limb limb) { + if (limb.HealthIndex < 0 || limb.HealthIndex >= limbHealths.Count) + { + DebugConsole.ThrowError("Limb health index out of bounds. Character\"" + Character.Name + + "\" only has health configured for" + limbHealths.Count + " limbs but the limb " + limb.type + " is targeting index " + limb.HealthIndex); + return null; + } foreach (Affliction affliction in limbHealths[limb.HealthIndex].Afflictions) { if (affliction.Prefab.AfflictionType == afflictionType) return affliction; @@ -467,7 +473,13 @@ namespace Barotrauma private void AddLimbAffliction(Limb limb, Affliction newAffliction) { - if (!newAffliction.Prefab.LimbSpecific) return; + if (!newAffliction.Prefab.LimbSpecific || limb == null) return; + if (limb.HealthIndex < 0 || limb.HealthIndex >= limbHealths.Count) + { + DebugConsole.ThrowError("Limb health index out of bounds. Character\"" + Character.Name + + "\" only has health configured for" + limbHealths.Count + " limbs but the limb " + limb.type + " is targeting index " + limb.HealthIndex); + return; + } AddLimbAffliction(limbHealths[limb.HealthIndex], newAffliction); } diff --git a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs index d6c2f4fce..73736a5fd 100644 --- a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs +++ b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs @@ -228,7 +228,7 @@ namespace Barotrauma { string errorMsg = "Failed to spawn an item. Arguments: \"" + string.Join(" ", args) + "\"."; ThrowError(errorMsg, e); - GameAnalyticsManager.AddErrorEventOnce("DebugConsole.SpawnItem:Error", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); + GameAnalyticsManager.AddErrorEventOnce("DebugConsole.SpawnItem:Error", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg + '\n' + e.Message + '\n' + e.StackTrace); } }, () => @@ -615,7 +615,7 @@ namespace Barotrauma NewMessage(Hull.EditWater ? "Water editing on" : "Water editing off", Color.White); }, isCheat: true)); - commands.Add(new Command("water|editwater", "water/editwater: Toggle water editing. Allows adding water into rooms by holding the left mouse button and removing it by holding the right mouse button.", (string[] args) => + commands.Add(new Command("fire|editfire", "fire/editfire: Allows putting up fires by left clicking.", (string[] args) => { Hull.EditFire = !Hull.EditFire; NewMessage(Hull.EditFire ? "Fire spawning on" : "Fire spawning off", Color.White); diff --git a/Barotrauma/BarotraumaShared/Source/Events/Missions/Mission.cs b/Barotrauma/BarotraumaShared/Source/Events/Missions/Mission.cs index c317d6e7a..7df6131cd 100644 --- a/Barotrauma/BarotraumaShared/Source/Events/Missions/Mission.cs +++ b/Barotrauma/BarotraumaShared/Source/Events/Missions/Mission.cs @@ -55,9 +55,9 @@ namespace Barotrauma get { return true; } } - public virtual Vector2 SonarPosition + public virtual IEnumerable SonarPositions { - get { return Vector2.Zero; } + get { return Enumerable.Empty(); } } public string SonarLabel diff --git a/Barotrauma/BarotraumaShared/Source/Events/Missions/MonsterMission.cs b/Barotrauma/BarotraumaShared/Source/Events/Missions/MonsterMission.cs index 7da9e0e3f..01905d2cf 100644 --- a/Barotrauma/BarotraumaShared/Source/Events/Missions/MonsterMission.cs +++ b/Barotrauma/BarotraumaShared/Source/Events/Missions/MonsterMission.cs @@ -1,4 +1,6 @@ using Microsoft.Xna.Framework; +using System.Collections.Generic; +using System.Linq; namespace Barotrauma { @@ -10,30 +12,36 @@ namespace Barotrauma private int monsterCount; - private Vector2 sonarPosition; + private readonly List monsters = new List(); + private readonly List sonarPositions = new List(); - public override Vector2 SonarPosition + public override IEnumerable SonarPositions { - get { return monster != null && !monster.IsDead ? sonarPosition : Vector2.Zero; } + get + { + return sonarPositions; + } } public MonsterMission(MissionPrefab prefab, Location[] locations) : base(prefab, locations) { monsterFile = prefab.ConfigElement.GetAttributeString("monsterfile", ""); + monsterCount = prefab.ConfigElement.GetAttributeInt("monstercount", 1); } public override void Start(Level level) { Level.Loaded.TryGetInterestingPosition(true, Level.PositionType.MainPath, Level.Loaded.Size.X * 0.3f, out Vector2 spawnPos); - bool isClient = false; -#if CLIENT - isClient = GameMain.Client != null; -#endif - monster = Character.Create(monsterFile, spawnPos, ToolBox.RandomSeed(8), null, isClient, true, false); - monster.Enabled = false; - sonarPosition = spawnPos; + bool isClient = GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient; + for (int i = 0; i < monsterCount; i++) + { + monsters.Add(Character.Create(monsterFile, spawnPos, ToolBox.RandomSeed(8), null, isClient, true, false)); + } + monsters.ForEach(m => m.Enabled = false); + SwarmBehavior.CreateSwarm(monsters.Cast()); + sonarPositions.Add(spawnPos); } public override void Update(float deltaTime) @@ -45,7 +53,15 @@ namespace Barotrauma var activeMonsters = monsters.Where(m => m != null && !m.Removed && !m.IsDead); if (activeMonsters.Any()) { - sonarPosition = monster.Position; + Vector2 centerOfMass = Vector2.Zero; + foreach (var monster in activeMonsters) + { + //don't add another label if there's another monster roughly at the same spot + if (sonarPositions.All(p => Vector2.DistanceSquared(p, monster.Position) > 1000.0f * 1000.0f)) + { + sonarPositions.Add(monster.Position); + } + } } diff --git a/Barotrauma/BarotraumaShared/Source/Events/Missions/SalvageMission.cs b/Barotrauma/BarotraumaShared/Source/Events/Missions/SalvageMission.cs index 00febbf8a..7d5d16917 100644 --- a/Barotrauma/BarotraumaShared/Source/Events/Missions/SalvageMission.cs +++ b/Barotrauma/BarotraumaShared/Source/Events/Missions/SalvageMission.cs @@ -16,11 +16,18 @@ namespace Barotrauma private int state; - public override Vector2 SonarPosition + public override IEnumerable SonarPositions { get { - return state > 0 ? Vector2.Zero : ConvertUnits.ToDisplayUnits(item.SimPosition); + if (state > 0 ) + { + Enumerable.Empty(); + } + else + { + yield return ConvertUnits.ToDisplayUnits(item.SimPosition); + } } } diff --git a/Barotrauma/BarotraumaShared/Source/Events/MonsterEvent.cs b/Barotrauma/BarotraumaShared/Source/Events/MonsterEvent.cs index c5db6fa09..6c65cee87 100644 --- a/Barotrauma/BarotraumaShared/Source/Events/MonsterEvent.cs +++ b/Barotrauma/BarotraumaShared/Source/Events/MonsterEvent.cs @@ -227,17 +227,17 @@ namespace Barotrauma monsters = new List(); float offsetAmount = spawnPosType == Level.PositionType.MainPath ? 1000 : 100; for (int i = 0; i < amount; i++) - { + { CoroutineManager.InvokeAfter(() => { - bool isClient = false; -#if CLIENT - isClient = GameMain.Client != null; -#endif + bool isClient = GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient; monsters.Add(Character.Create(characterFile, spawnPos + Rand.Vector(offsetAmount, Rand.RandSync.Server), i.ToString(), null, isClient, true, true)); if (monsters.Count == amount) { spawnReady = true; + //this will do nothing if the monsters have no swarm behavior defined, + //otherwise it'll make the spawned characters act as a swarm + SwarmBehavior.CreateSwarm(monsters.Cast()); } }, Rand.Range(0f, amount / 2, Rand.RandSync.Server)); } diff --git a/Barotrauma/BarotraumaShared/Source/GameSettings.cs b/Barotrauma/BarotraumaShared/Source/GameSettings.cs index 763de75fc..e85d877db 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSettings.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSettings.cs @@ -855,6 +855,9 @@ namespace Barotrauma 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()) @@ -977,14 +980,8 @@ namespace Barotrauma ToolBox.IsProperFilenameCase(file.Path); } } - if (!SelectedContentPackages.Any()) - { - var availablePackage = ContentPackage.List.FirstOrDefault(cp => cp.IsCompatible() && cp.CorePackage); - if (availablePackage != null) - { - SelectedContentPackages.Add(availablePackage); - } - } + + EnsureCoreContentPackageSelected(); //save to get rid of the invalid selected packages in the config file if (missingPackagePaths.Count > 0 || incompatiblePackages.Count > 0) { SaveNewPlayerConfig(); } @@ -1003,6 +1000,25 @@ namespace Barotrauma .Replace("[gameversion]", GameMain.Version.ToString())); } } + + public void EnsureCoreContentPackageSelected() + { + if (SelectedContentPackages.Any(cp => cp.CorePackage)) { return; } + + if (GameMain.VanillaContent != null) + { + SelectedContentPackages.Add(GameMain.VanillaContent); + } + else + { + var availablePackage = ContentPackage.List.FirstOrDefault(cp => cp.IsCompatible() && cp.CorePackage); + if (availablePackage != null) + { + SelectedContentPackages.Add(availablePackage); + } + } + } + #endregion #region Save PlayerConfig @@ -1032,7 +1048,9 @@ namespace Barotrauma new XAttribute("aimassistamount", aimAssistAmount), new XAttribute("enablemouselook", EnableMouseLook), new XAttribute("chatopen", ChatOpen), - new XAttribute("crewmenuopen", CrewMenuOpen)); + new XAttribute("crewmenuopen", CrewMenuOpen), + new XAttribute("campaigndisclaimershown", CampaignDisclaimerShown), + new XAttribute("editordisclaimershown", EditorDisclaimerShown)); if (!ShowUserStatisticsPrompt) { diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RangedWeapon.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RangedWeapon.cs index 966bd5761..b15306910 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RangedWeapon.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RangedWeapon.cs @@ -122,10 +122,12 @@ namespace Barotrauma.Items.Components foreach (Item subItem in containedSubItems) { projectile = subItem.GetComponent(); - //apply OnUse statuseffects to the container in case it has to react to it somehow //(play a sound, spawn more projectiles, reduce condition...) - subItem.GetComponent()?.Item.ApplyStatusEffects(ActionType.OnUse, deltaTime); + if (subItem.Condition > 0.0f) + { + subItem.GetComponent()?.Item.ApplyStatusEffects(ActionType.OnUse, deltaTime); + } if (projectile != null) break; } } diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs index 6fe79715c..777ecb668 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs @@ -71,8 +71,10 @@ namespace Barotrauma.Items.Components var targetItem = inputContainer.Inventory.Items.LastOrDefault(i => i != null); if (targetItem == null) { return; } - progressState = Math.Min(progressTimer / targetItem.Prefab.DeconstructTime, 1.0f); - if (progressTimer > targetItem.Prefab.DeconstructTime) + float deconstructTime = targetItem.Prefab.DeconstructItems.Any() ? targetItem.Prefab.DeconstructTime : 1.0f; + + progressState = Math.Min(progressTimer / deconstructTime, 1.0f); + if (progressTimer > deconstructTime) { foreach (DeconstructItem deconstructProduct in targetItem.Prefab.DeconstructItems) { @@ -100,10 +102,13 @@ namespace Barotrauma.Items.Components } } - inputContainer.Inventory.RemoveItem(targetItem); - Entity.Spawner.AddToRemoveQueue(targetItem); - MoveInputQueue(); - PutItemsToLinkedContainer(); + if (targetItem.Prefab.DeconstructItems.Any()) + { + inputContainer.Inventory.RemoveItem(targetItem); + Entity.Spawner.AddToRemoveQueue(targetItem); + MoveInputQueue(); + PutItemsToLinkedContainer(); + } if (inputContainer.Inventory.Items.Any(i => i != null)) { diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Reactor.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Reactor.cs index a26222b4b..ee38171f6 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Reactor.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Reactor.cs @@ -473,6 +473,8 @@ namespace Barotrauma.Items.Components { if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return false; } + IsActive = true; + float degreeOfSuccess = DegreeOfSuccess(character); //characters with insufficient skill levels don't refuel the reactor diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs index 6fb2e7564..8d160a611 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs @@ -328,6 +328,19 @@ namespace Barotrauma.Items.Components return true; } + public override void OnItemLoaded() + { + sonar = item.GetComponent(); + } + + public override bool Select(Character character) + { + if (!CanBeSelected) return false; + + user = character; + return true; + } + public override void Update(float deltaTime, Camera cam) { networkUpdateTimer -= deltaTime; diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Power/PowerTransfer.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Power/PowerTransfer.cs index 157e5f8c8..097e26985 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Power/PowerTransfer.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Power/PowerTransfer.cs @@ -201,7 +201,7 @@ namespace Barotrauma.Items.Components if (sparkSounds.Count > 0) { var sparkSound = sparkSounds[Rand.Int(sparkSounds.Count)]; - SoundPlayer.PlaySound(sparkSound.Sound, sparkSound.Volume, sparkSound.Range, pt.item.WorldPosition, pt.item.CurrentHull); + SoundPlayer.PlaySound(sparkSound.Sound, pt.item.WorldPosition, sparkSound.Volume, sparkSound.Range, pt.item.CurrentHull); } Vector2 baseVel = Rand.Vector(300.0f); diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Power/Powered.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Power/Powered.cs index 00ec9ae00..7f3ee64e6 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Power/Powered.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Power/Powered.cs @@ -103,7 +103,7 @@ namespace Barotrauma.Items.Components ApplyStatusEffects(ActionType.OnActive, deltaTime, null); if (!powerOnSoundPlayed && powerOnSound != null) { - SoundPlayer.PlaySound(powerOnSound.Sound, powerOnSound.Volume, powerOnSound.Range, item.WorldPosition, item.CurrentHull); + SoundPlayer.PlaySound(powerOnSound.Sound, item.WorldPosition, powerOnSound.Volume, powerOnSound.Range, item.CurrentHull); powerOnSoundPlayed = true; } } diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs index 6e6b4915f..4b68000a9 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs @@ -219,7 +219,7 @@ namespace Barotrauma.Items.Components if (voltage > 0.1f && sparkSounds.Count > 0) { var sparkSound = sparkSounds[Rand.Int(sparkSounds.Count)]; - SoundPlayer.PlaySound(sparkSound.Sound, sparkSound.Volume, sparkSound.Range, item.WorldPosition, item.CurrentHull); + SoundPlayer.PlaySound(sparkSound.Sound, item.WorldPosition, sparkSound.Volume, sparkSound.Range, item.CurrentHull); } #endif lightBrightness = 0.0f; diff --git a/Barotrauma/BarotraumaShared/Source/Items/Item.cs b/Barotrauma/BarotraumaShared/Source/Items/Item.cs index 7d32387b4..e0cb0818a 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Item.cs @@ -928,14 +928,9 @@ namespace Barotrauma public void ApplyStatusEffects(ActionType type, float deltaTime, Character character = null, Limb limb = null, bool isNetworkEvent = false) { - if (statusEffectLists == null) return; - - if (!statusEffectLists.TryGetValue(type, out List statusEffects)) return; - - bool broken = condition <= 0.0f; - foreach (StatusEffect effect in statusEffects) + if (!hasStatusEffectsOfType[(int)type]) { return; } + foreach (StatusEffect effect in statusEffectLists[type]) { - if (broken && effect.type != ActionType.OnBroken) continue; ApplyStatusEffect(effect, type, deltaTime, character, limb, isNetworkEvent, false); } } @@ -1052,6 +1047,8 @@ namespace Barotrauma aiTarget.SoundRange -= deltaTime * 1000.0f; } + bool broken = condition <= 0.0f; + if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer) { sendConditionUpdateTimer -= deltaTime; @@ -1127,6 +1124,10 @@ namespace Barotrauma container = container.Container; } } + if (!broken) + { + ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime); + } ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime); if (body == null || !body.Enabled || !inWater || ParentInventory != null || Removed) { return; } @@ -1206,7 +1207,7 @@ namespace Barotrauma if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return true; } - if (ImpactTolerance > 0.0f && impact > ImpactTolerance) + if (ImpactTolerance > 0.0f && condition > 0.0f && impact > ImpactTolerance) { ApplyStatusEffects(ActionType.OnImpact, 1.0f); #if SERVER diff --git a/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs b/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs index 686cd222f..11bf41f6c 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs @@ -24,8 +24,6 @@ namespace Barotrauma private bool removed; - private bool removed; - #if CLIENT private List burnDecals = new List(); #endif diff --git a/Barotrauma/BarotraumaShared/Source/Map/Hull.cs b/Barotrauma/BarotraumaShared/Source/Map/Hull.cs index e4048f75a..604b6395c 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Hull.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Hull.cs @@ -299,6 +299,25 @@ namespace Barotrauma } } + public string DisplayName + { + get; + private set; + } + + private string roomName; + [Editable, Serialize("", true, translationTextTag: "RoomName.")] + public string RoomName + { + get { return roomName; } + set + { + if (roomName == value) { return; } + roomName = value; + DisplayName = TextManager.Get(roomName, returnNull: true) ?? roomName; + } + } + public override Rectangle Rect { get @@ -633,11 +652,6 @@ namespace Barotrauma public void AddFireSource(FireSource fireSource) { FireSources.Add(fireSource); - - if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer && !IdFreed) - { - GameMain.NetworkMember.CreateEntityEvent(this); - } } public override void Update(float deltaTime, Camera cam) @@ -805,11 +819,6 @@ namespace Barotrauma public void RemoveFire(FireSource fire) { FireSources.Remove(fire); - - if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer && !Removed && !IdFreed) - { - GameMain.NetworkMember.CreateEntityEvent(this); - } } public IEnumerable GetConnectedHulls(int? searchDepth) diff --git a/Barotrauma/BarotraumaShared/Source/Map/MapEntity.cs b/Barotrauma/BarotraumaShared/Source/Map/MapEntity.cs index d55c8c0e8..a239508b9 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/MapEntity.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/MapEntity.cs @@ -522,15 +522,9 @@ namespace Barotrauma } } } - - // The value should always be copied from the prefab. Editing is enabled only for testing the scale in the sub editor (changes are not saved). - -#if DEBUG + [Serialize(1f, false), Editable(0.1f, 10f, DecimalCount = 3, ValueStep = 0.1f)] -#else - [Serialize(1f, false)] -#endif - public float Scale { get; set; } = 1; + public virtual float Scale { get; set; } = 1; #endregion } } diff --git a/Barotrauma/BarotraumaShared/Source/Map/Structure.cs b/Barotrauma/BarotraumaShared/Source/Map/Structure.cs index 1dc9e5844..b07e79468 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Structure.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Structure.cs @@ -159,6 +159,32 @@ namespace Barotrauma private set; } + private float scale = 1.0f; + public override float Scale + { + get { return scale; } + set + { + if (scale == value) { return; } + scale = MathHelper.Clamp(value, 0.1f, 10.0f); + + float relativeScale = scale / prefab.Scale; + + if (!ResizeHorizontal || !ResizeVertical) + { + int newWidth = ResizeHorizontal ? rect.Width : (int)(defaultRect.Width * relativeScale); + int newHeight = ResizeVertical ? rect.Height : (int)(defaultRect.Height * relativeScale); + Rect = new Rectangle(rect.X, rect.Y, newWidth, newHeight); + if (Sections != null) + { + UpdateSections(); + } + } + } + } + + private Rectangle defaultRect; + public override Rectangle Rect { get @@ -169,9 +195,13 @@ namespace Barotrauma { Rectangle oldRect = Rect; base.Rect = value; - if (Prefab.Body) CreateSections(); + if (Prefab.Body) + { + CreateSections(); + } else { + if (Sections == null) { return; } foreach (WallSection sec in Sections) { Rectangle secRect = sec.rect; @@ -189,11 +219,11 @@ namespace Barotrauma public float BodyWidth { - get { return Prefab.BodyWidth > 0.0f ? Prefab.BodyWidth : rect.Width; } + get { return Prefab.BodyWidth > 0.0f ? Prefab.BodyWidth * scale : rect.Width; } } public float BodyHeight { - get { return Prefab.BodyHeight > 0.0f ? Prefab.BodyHeight : rect.Height; } + get { return Prefab.BodyHeight > 0.0f ? Prefab.BodyHeight * scale : rect.Height; } } /// @@ -965,6 +995,7 @@ namespace Barotrauma private void UpdateSections() { + if (Bodies == null) return; foreach (Body b in Bodies) { GameMain.World.RemoveBody(b); @@ -1028,9 +1059,9 @@ namespace Barotrauma if (BodyWidth > 0.0f) rect.Width = (int)BodyWidth; if (BodyHeight > 0.0f) rect.Height = Math.Max((int)Math.Round(BodyHeight * (rect.Height / (float)this.rect.Height)), 1); } - if (FlippedX) diffFromCenter = -diffFromCenter; + if (FlippedX) { diffFromCenter = -diffFromCenter; } - Vector2 bodyOffset = ConvertUnits.ToSimUnits(Prefab.BodyOffset); + Vector2 bodyOffset = ConvertUnits.ToSimUnits(Prefab.BodyOffset) * scale; if (FlippedX) { bodyOffset.X = -bodyOffset.X; } if (FlippedY) { bodyOffset.Y = -bodyOffset.Y; } @@ -1050,7 +1081,8 @@ namespace Barotrauma { newBody.Position = structureCenter + bodyOffset + new Vector2( (float)Math.Cos(IsHorizontal ? -BodyRotation : MathHelper.PiOver2 - BodyRotation), - (float)Math.Sin(IsHorizontal ? -BodyRotation : MathHelper.PiOver2 - BodyRotation)) * ConvertUnits.ToSimUnits(diffFromCenter); + (float)Math.Sin(IsHorizontal ? -BodyRotation : MathHelper.PiOver2 - BodyRotation)) + * ConvertUnits.ToSimUnits(diffFromCenter); newBody.Rotation = -BodyRotation; } else @@ -1191,6 +1223,9 @@ namespace Barotrauma { XElement element = new XElement("Structure"); + int width = ResizeHorizontal ? rect.Width : defaultRect.Width; + int height = ResizeVertical ? rect.Height : defaultRect.Height; + element.Add( new XAttribute("name", prefab.Name), new XAttribute("identifier", prefab.Identifier), @@ -1203,15 +1238,6 @@ namespace Barotrauma if (FlippedX) element.Add(new XAttribute("flippedx", true)); if (FlippedY) element.Add(new XAttribute("flippedy", true)); - if (FlippedX) element.Add(new XAttribute("flippedx", true)); - if (FlippedY) element.Add(new XAttribute("flippedy", true)); - - if (FlippedX) element.Add(new XAttribute("flippedx", true)); - if (FlippedY) element.Add(new XAttribute("flippedy", true)); - - if (FlippedX) element.Add(new XAttribute("flippedx", true)); - if (FlippedY) element.Add(new XAttribute("flippedy", true)); - for (int i = 0; i < Sections.Length; i++) { if (Sections[i].damage == 0.0f) continue; diff --git a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs index a0fd7465d..ab486666c 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs @@ -1117,6 +1117,7 @@ namespace Barotrauma } } savedSubmarines.Add(new Submarine(filePath)); + savedSubmarines = savedSubmarines.OrderBy(s => s.filePath ?? "").ToList(); } public static void RefreshSavedSubs() diff --git a/Barotrauma/BarotraumaShared/Source/Networking/ServerSettings.cs b/Barotrauma/BarotraumaShared/Source/Networking/ServerSettings.cs index 3a4f36a23..0a5ca7bb0 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/ServerSettings.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/ServerSettings.cs @@ -377,6 +377,12 @@ namespace Barotrauma.Networking private set; } + [Serialize(true, true)] + public bool VoipEnabled { + get; + private set; + } + [Serialize(true, true)] public bool EndRoundAtLevelEnd { diff --git a/Barotrauma/BarotraumaShared/Source/Networking/SteamManager.cs b/Barotrauma/BarotraumaShared/Source/Networking/SteamManager.cs index 3928675b6..19d821993 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/SteamManager.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/SteamManager.cs @@ -66,6 +66,16 @@ namespace Barotrauma.Steam if (!USE_STEAM) return; instance = new SteamManager(); } + + public static void OverlayCustomURL(string url) + { + if (instance == null || !instance.isInitialized || instance.client == null) + { + return; + } + + instance.client.Overlay.OpenUrl(url); + } public static bool UnlockAchievement(string achievementName) { diff --git a/Barotrauma/BarotraumaShared/Source/PlayerInput.cs b/Barotrauma/BarotraumaShared/Source/PlayerInput.cs index e13028523..8ad826eea 100644 --- a/Barotrauma/BarotraumaShared/Source/PlayerInput.cs +++ b/Barotrauma/BarotraumaShared/Source/PlayerInput.cs @@ -162,6 +162,21 @@ namespace Barotrauma get { return binding; } } + public void SetState() + { + hit = binding.IsHit(); + if (hit) hitQueue = true; + + held = binding.IsDown(); + if (held) heldQueue = true; + } +#endif + + public KeyOrMouse State + { + get { return binding; } + } + public void SetState() { hit = binding.IsHit(); diff --git a/Barotrauma/BarotraumaShared/Source/SteamAchievementManager.cs b/Barotrauma/BarotraumaShared/Source/SteamAchievementManager.cs index d707be008..9dfe58a9e 100644 --- a/Barotrauma/BarotraumaShared/Source/SteamAchievementManager.cs +++ b/Barotrauma/BarotraumaShared/Source/SteamAchievementManager.cs @@ -336,9 +336,12 @@ namespace Barotrauma UnlockAchievement("survivereactormeltdown"); } #endif - - var charactersInSub = Character.CharacterList.FindAll(c => !c.IsDead && + var charactersInSub = Character.CharacterList.FindAll(c => + !c.IsDead && + c.TeamID != Character.TeamType.FriendlyNPC && + !(c.AIController is EnemyAIController) && (c.Submarine == gameSession.Submarine || (Level.Loaded?.EndOutpost != null && c.Submarine == Level.Loaded.EndOutpost))); + if (charactersInSub.Count == 1) { //there must be some non-enemy casualties to get the last mant standing achievement @@ -346,7 +349,11 @@ namespace Barotrauma { UnlockAchievement(charactersInSub[0], "lastmanstanding"); } - else if (!Character.CharacterList.Any(c => !(c.AIController is EnemyAIController))) + //lone sailor achievement if alone in the sub and there are no other characters with the same team ID + else if (!Character.CharacterList.Any(c => + c != charactersInSub[0] && + c.TeamID == charactersInSub[0].TeamID && + !(c.AIController is EnemyAIController))) { UnlockAchievement(charactersInSub[0], "lonesailor"); } diff --git a/Barotrauma/BarotraumaShared/Submarines/Dugong.sub b/Barotrauma/BarotraumaShared/Submarines/Dugong.sub index 6b354c42d..1875ad5b0 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Dugong.sub and b/Barotrauma/BarotraumaShared/Submarines/Dugong.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Orca.sub b/Barotrauma/BarotraumaShared/Submarines/Orca.sub index 4d734b45c..bc01cbce0 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Orca.sub and b/Barotrauma/BarotraumaShared/Submarines/Orca.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Typhon.sub b/Barotrauma/BarotraumaShared/Submarines/Typhon.sub index 14f516834..102edb6f8 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Typhon.sub and b/Barotrauma/BarotraumaShared/Submarines/Typhon.sub differ