diff --git a/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterNetworking.cs b/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterNetworking.cs index 718df5313..0c6239d21 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterNetworking.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterNetworking.cs @@ -416,7 +416,7 @@ namespace Barotrauma int optionIndex = msg.ReadRangedInteger(-1, orderPrefab.AllOptions.Length); if (optionIndex > -1) { - option = orderPrefab.Options[optionIndex]; + option = orderPrefab.AllOptions[optionIndex]; } } GameMain.GameSession?.CrewManager?.SetOrderHighlight(this, orderPrefab.Identifier, option); diff --git a/Barotrauma/BarotraumaClient/ClientSource/GUI/GUIListBox.cs b/Barotrauma/BarotraumaClient/ClientSource/GUI/GUIListBox.cs index a6867eb60..6b7265865 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/GUI/GUIListBox.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/GUI/GUIListBox.cs @@ -59,9 +59,7 @@ namespace Barotrauma private bool useGridLayout; - private float targetScroll; - - private GUIComponent pendingScroll; + private GUIComponent scrollToElement; public bool AllowMouseWheelScroll { get; set; } = true; @@ -238,8 +236,6 @@ namespace Barotrauma public GUIComponent DraggedElement => draggedElement; - private bool scheduledScroll = false; - private readonly bool isHorizontal; /// For horizontal listbox, default side is on the bottom. For vertical, it's on the right. @@ -429,7 +425,14 @@ namespace Barotrauma int index = children.IndexOf(component); if (index < 0) { return; } - targetScroll = MathHelper.Clamp(MathHelper.Lerp(0, 1, MathUtils.InverseLerp(0, (children.Count - 0.9f), index)), ScrollBar.MinValue, ScrollBar.MaxValue); + if (!Content.Children.Contains(component) || !component.Visible) + { + scrollToElement = null; + } + else + { + scrollToElement = component; + } } public void ScrollToEnd(float duration) @@ -533,7 +536,7 @@ namespace Barotrauma } } - if (SelectTop && Content.Children.Any() && pendingScroll == null) + if (SelectTop && Content.Children.Any() && scrollToElement == null) { GUIComponent component = Content.Children.FirstOrDefault(c => (c.Rect.Y - Content.Rect.Y) / (float)c.Rect.Height > -0.1f); @@ -563,7 +566,6 @@ namespace Barotrauma { if (SelectTop) { - pendingScroll = child; ScrollToElement(child); Select(i, autoScroll: false, takeKeyBoardFocus: true); } @@ -728,25 +730,29 @@ namespace Barotrauma } } } - - if (SmoothScroll) - { - if (targetScroll > -1) - { - float distance = Math.Abs(targetScroll - BarScroll); - float speed = Math.Max(distance * BarSize, 0.1f); - BarScroll = (1.0f - speed) * BarScroll + speed * targetScroll; - if (MathUtils.NearlyEqual(BarScroll, targetScroll) || GUIScrollBar.DraggingBar != null) - { - targetScroll = -1; - pendingScroll = null; - } - } - } + if (scrollToElement != null) + { + if (!scrollToElement.Visible || !Content.Children.Contains(scrollToElement)) + { + scrollToElement = null; + } + else + { + float diff = isHorizontal ? scrollToElement.Rect.X - Content.Rect.X : scrollToElement.Rect.Y - Content.Rect.Y; + float speed = MathHelper.Clamp(Math.Abs(diff) * 0.1f, 5.0f, 100.0f); + System.Diagnostics.Debug.WriteLine(speed); + if (Math.Abs(diff) < speed || GUIScrollBar.DraggingBar != null) + { + speed = Math.Abs(diff); + scrollToElement = null; + } + BarScroll += speed * Math.Sign(diff) / TotalSize; + } + } + if ((GUI.IsMouseOn(this) || GUI.IsMouseOn(ScrollBar)) && AllowMouseWheelScroll && PlayerInput.ScrollWheelSpeed != 0) { - float speed = PlayerInput.ScrollWheelSpeed / 500.0f * BarSize; if (SmoothScroll) { if (ClampScrollToElements) @@ -762,13 +768,6 @@ namespace Barotrauma SelectNext(takeKeyBoardFocus: true); } } - else - { - pendingScroll = null; - if (targetScroll < 0) { targetScroll = BarScroll; } - targetScroll -= speed; - targetScroll = Math.Clamp(targetScroll, ScrollBar.MinValue, ScrollBar.MaxValue); - } } else { @@ -799,7 +798,6 @@ namespace Barotrauma Select(index, force, !SmoothScroll && autoScroll, takeKeyBoardFocus: takeKeyBoardFocus); if (SmoothScroll) { - pendingScroll = child; ScrollToElement(child); } break; @@ -819,7 +817,6 @@ namespace Barotrauma Select(index, force, !SmoothScroll && autoScroll, takeKeyBoardFocus: takeKeyBoardFocus); if (SmoothScroll) { - pendingScroll = child; ScrollToElement(child); } break; diff --git a/Barotrauma/BarotraumaClient/ClientSource/GUI/UpgradeStore.cs b/Barotrauma/BarotraumaClient/ClientSource/GUI/UpgradeStore.cs index db3b4336a..f8d583f84 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/GUI/UpgradeStore.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/GUI/UpgradeStore.cs @@ -119,9 +119,15 @@ namespace Barotrauma RefreshUpgradeList(); foreach (var itemPreview in itemPreviews) { - if (itemPreview.Key?.PendingItemSwap?.UpgradePreviewSprite == null) { continue; } - if (!(itemPreview.Value is GUIImage image)) { continue; } - image.Sprite = itemPreview.Key.PendingItemSwap.UpgradePreviewSprite; + if (!(itemPreview.Value is GUIImage image) || itemPreview.Key == null) { continue; } + if (itemPreview.Key.PendingItemSwap == null) + { + image.Sprite = itemPreview.Key.Prefab.UpgradePreviewSprite; + } + else if (itemPreview.Key.PendingItemSwap.UpgradePreviewSprite != null) + { + image.Sprite = itemPreview.Key.PendingItemSwap.UpgradePreviewSprite; + } } break; } @@ -241,7 +247,7 @@ namespace Barotrauma GUILayoutGroup tooltipLayout = new GUILayoutGroup(rectT(0.95f,0.95f, ItemInfoFrame, Anchor.Center)) { Stretch = true }; new GUITextBlock(rectT(1, 0, tooltipLayout), string.Empty, font: GUI.SubHeadingFont) { UserData = "itemname" }; new GUITextBlock(rectT(1, 0, tooltipLayout), TextManager.Get("UpgradeUITooltip.UpgradeListHeader")); - new GUIListBox(rectT(1, 0.5f, tooltipLayout), style: null) { ScrollBarVisible = false, AutoHideScrollBar = false, UserData = "upgradelist"}; + new GUIListBox(rectT(1, 0.5f, tooltipLayout), style: null) { ScrollBarVisible = false, AutoHideScrollBar = false, SmoothScroll = true, UserData = "upgradelist"}; new GUITextBlock(rectT(1, 0, tooltipLayout), string.Empty) { UserData = "moreindicator" }; ItemInfoFrame.Children.ForEach(c => { c.CanBeFocused = false; c.Children.ForEach(c2 => c2.CanBeFocused = false); }); @@ -1276,8 +1282,7 @@ namespace Barotrauma if (selectedUpgradeCategoryLayout.FindChild(c => c.UserData as Item == HoveredItem, recursive: true) is GUIButton itemElement) { if (!itemElement.Selected) { itemElement.OnClicked(itemElement, itemElement.UserData); } - //TODO: enable this if/when we make ScrollToElement work with child elements of different sizes - //(itemElement.Parent?.Parent?.Parent as GUIListBox)?.ScrollToElement(itemElement); + (itemElement.Parent?.Parent?.Parent as GUIListBox)?.ScrollToElement(itemElement); } } } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Machines/Pump.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Machines/Pump.cs index e35c9a17b..3877a2ccf 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Machines/Pump.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Machines/Pump.cs @@ -16,8 +16,8 @@ namespace Barotrauma.Items.Components private GUITickBox powerLight; private GUITickBox autoControlIndicator; - private List> pumpOutEmitters = new List>(); - private List> pumpInEmitters = new List>(); + private readonly List<(Vector2 position, ParticleEmitter emitter)> pumpOutEmitters = new List<(Vector2 position, ParticleEmitter emitter)>(); + private readonly List<(Vector2 position, ParticleEmitter emitter)> pumpInEmitters = new List<(Vector2 position, ParticleEmitter emitter)>(); public float CurrentBrokenVolume { @@ -35,14 +35,10 @@ namespace Barotrauma.Items.Components switch (subElement.Name.ToString().ToLowerInvariant()) { case "pumpoutemitter": - pumpOutEmitters.Add(new Pair( - subElement.GetAttributeVector2("position", Vector2.Zero), - new ParticleEmitter(subElement))); + pumpOutEmitters.Add((subElement.GetAttributeVector2("position", Vector2.Zero), new ParticleEmitter(subElement))); break; case "pumpinemitter": - pumpInEmitters.Add(new Pair( - subElement.GetAttributeVector2("position", Vector2.Zero), - new ParticleEmitter(subElement))); + pumpInEmitters.Add((subElement.GetAttributeVector2("position", Vector2.Zero), new ParticleEmitter(subElement))); break; } } @@ -148,21 +144,43 @@ namespace Barotrauma.Items.Components { if (FlowPercentage < 0.0f) { - foreach (Pair pumpOutEmitter in pumpOutEmitters) + foreach (var (position, emitter) in pumpOutEmitters) { - //only emit "pump out" particles when underwater - Vector2 particlePos = item.Rect.Location.ToVector2() + pumpOutEmitter.First; - if (item.CurrentHull != null && item.CurrentHull.Surface < particlePos.Y) continue; + if (item.CurrentHull != null && item.CurrentHull.Surface < item.Rect.Location.Y + position.Y) { continue; } - pumpOutEmitter.Second.Emit(deltaTime, item.WorldRect.Location.ToVector2() + pumpOutEmitter.First * item.Scale, item.CurrentHull, + //only emit "pump out" particles when underwater + Vector2 relativeParticlePos = (item.WorldRect.Location.ToVector2() + position * item.Scale) - item.WorldPosition; + float angle = 0.0f; + if (item.FlippedX) + { + relativeParticlePos.X = -relativeParticlePos.X; + angle = MathHelper.Pi; + } + if (item.FlippedY) + { + relativeParticlePos.Y = -relativeParticlePos.Y; + } + + emitter.Emit(deltaTime, item.WorldPosition + relativeParticlePos, item.CurrentHull, angle, velocityMultiplier: MathHelper.Lerp(0.5f, 1.0f, -FlowPercentage / 100.0f)); } } else if (FlowPercentage > 0.0f) { - foreach (Pair pumpInEmitter in pumpInEmitters) + foreach (var (position, emitter) in pumpInEmitters) { - pumpInEmitter.Second.Emit(deltaTime, item.WorldRect.Location.ToVector2() + pumpInEmitter.First * item.Scale, item.CurrentHull, + Vector2 relativeParticlePos = (item.WorldRect.Location.ToVector2() + position * item.Scale) - item.WorldPosition; + float angle = 0.0f; + if (item.FlippedX) + { + relativeParticlePos.X = -relativeParticlePos.X; + angle = MathHelper.Pi; + } + if (item.FlippedY) + { + relativeParticlePos.Y = -relativeParticlePos.Y; + } + emitter.Emit(deltaTime, item.WorldPosition + relativeParticlePos, item.CurrentHull, angle, velocityMultiplier: MathHelper.Lerp(0.5f, 1.0f, FlowPercentage / 100.0f)); } } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Wearable.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Wearable.cs index ed67bbe2c..9692249c8 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Wearable.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Wearable.cs @@ -10,7 +10,7 @@ namespace Barotrauma.Items.Components int roundedValue = (int)Math.Round((1 - damageMultiplier) * 100); if (roundedValue == 0) { return; } string colorStr = XMLExtensions.ColorToString(GUI.Style.Green); - description += $"\n ‖color:{colorStr}‖{roundedValue.ToString("+0;-#")}%‖color:end‖ {TextManager.Get("AfflictionName." + afflictionIdentifier, true) ?? afflictionIdentifier}"; + description += $"\n ‖color:{colorStr}‖{roundedValue.ToString("-0;+#")}%‖color:end‖ {AfflictionPrefab.List.FirstOrDefault(ap => ap.Identifier.Equals(afflictionIdentifier, StringComparison.OrdinalIgnoreCase))?.Name ?? afflictionIdentifier}"; } public override void AddTooltipInfo(ref string description) diff --git a/Barotrauma/BarotraumaClient/ClientSource/Map/Hull.cs b/Barotrauma/BarotraumaClient/ClientSource/Map/Hull.cs index cd5668d22..a89cb1d2f 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Map/Hull.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Map/Hull.cs @@ -169,40 +169,43 @@ namespace Barotrauma } } - if (EditWater) + if (!IdFreed) { - Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition); - if (Submarine.RectContains(WorldRect, position)) + if (EditWater) { - if (PlayerInput.PrimaryMouseButtonHeld()) + Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition); + if (Submarine.RectContains(WorldRect, position)) { - WaterVolume += 1500.0f; - networkUpdatePending = true; - serverUpdateDelay = 0.5f; + if (PlayerInput.PrimaryMouseButtonHeld()) + { + WaterVolume += 1500.0f; + networkUpdatePending = true; + serverUpdateDelay = 0.5f; + } + else if (PlayerInput.SecondaryMouseButtonHeld()) + { + WaterVolume -= 1500.0f; + networkUpdatePending = true; + serverUpdateDelay = 0.5f; + } } - else if (PlayerInput.SecondaryMouseButtonHeld()) + } + else if (EditFire) + { + Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition); + if (Submarine.RectContains(WorldRect, position)) { - WaterVolume -= 1500.0f; - networkUpdatePending = true; - serverUpdateDelay = 0.5f; + if (PlayerInput.PrimaryMouseButtonClicked()) + { + new FireSource(position, this, isNetworkMessage: true); + networkUpdatePending = true; + serverUpdateDelay = 0.5f; + } } } } - else if (EditFire) - { - Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition); - if (Submarine.RectContains(WorldRect, position)) - { - if (PlayerInput.PrimaryMouseButtonClicked()) - { - new FireSource(position, this, isNetworkMessage: true); - networkUpdatePending = true; - serverUpdateDelay = 0.5f; - } - } - } - - if (waterVolume < 1.0f) return; + + if (waterVolume < 1.0f) { return; } for (int i = 1; i < waveY.Length - 1; i++) { float maxDelta = Math.Max(Math.Abs(rightDelta[i]), Math.Abs(leftDelta[i])); diff --git a/Barotrauma/BarotraumaClient/ClientSource/Map/Levels/LevelObjects/LevelObject.cs b/Barotrauma/BarotraumaClient/ClientSource/Map/Levels/LevelObjects/LevelObject.cs index e2584cf07..7396a16b5 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Map/Levels/LevelObjects/LevelObject.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Map/Levels/LevelObjects/LevelObject.cs @@ -210,7 +210,7 @@ namespace Barotrauma if (ParticleEmitterTriggers[i] != null && !ParticleEmitterTriggers[i].IsTriggered) { continue; } Vector2 emitterPos = LocalToWorld(Prefab.EmitterPositions[i]); ParticleEmitters[i].Emit(deltaTime, emitterPos, hullGuess: null, - angle: ParticleEmitters[i].Prefab.Properties.CopyEntityAngle ? -CurrentRotation + MathHelper.PiOver2 : 0.0f); + angle: ParticleEmitters[i].Prefab.Properties.CopyEntityAngle ? -CurrentRotation + MathHelper.Pi : 0.0f); } } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Networking/GameClient.cs b/Barotrauma/BarotraumaClient/ClientSource/Networking/GameClient.cs index 1dc23c7d1..a9fbed672 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Networking/GameClient.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Networking/GameClient.cs @@ -2088,6 +2088,7 @@ namespace Barotrauma.Networking float autoRestartTimer = autoRestartEnabled ? inc.ReadSingle() : 0.0f; bool radiationEnabled = inc.ReadBoolean(); + byte maxMissionCount = inc.ReadByte(); //ignore the message if we already a more up-to-date one //or if we're still waiting for the initial update @@ -2153,6 +2154,7 @@ namespace Barotrauma.Networking GameMain.NetLobbyScreen.SetRadiationEnabled(radiationEnabled); GameMain.NetLobbyScreen.SetBotSpawnMode(botSpawnMode); GameMain.NetLobbyScreen.SetBotCount(botCount); + GameMain.NetLobbyScreen.SetMaxMissionCount(maxMissionCount); GameMain.NetLobbyScreen.SetAutoRestart(autoRestartEnabled, autoRestartTimer); serverSettings.VoiceChatEnabled = voiceChatEnabled; diff --git a/Barotrauma/BarotraumaClient/ClientSource/Networking/ServerSettings.cs b/Barotrauma/BarotraumaClient/ClientSource/Networking/ServerSettings.cs index 2753462b3..07f3a2f9a 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Networking/ServerSettings.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Networking/ServerSettings.cs @@ -151,7 +151,7 @@ namespace Barotrauma.Networking } } - public void ClientAdminWrite(NetFlags dataToSend, int? missionTypeOr = null, int? missionTypeAnd = null, float? levelDifficulty = null, bool? autoRestart = null, int traitorSetting = 0, int botCount = 0, int botSpawnMode = 0, bool? radiationEnabled = null, bool? useRespawnShuttle = null) + public void ClientAdminWrite(NetFlags dataToSend, int? missionTypeOr = null, int? missionTypeAnd = null, float? levelDifficulty = null, bool? autoRestart = null, int traitorSetting = 0, int botCount = 0, int botSpawnMode = 0, bool? radiationEnabled = null, bool? useRespawnShuttle = null, int maxMissionCount = 0) { if (!GameMain.Client.HasPermission(Networking.ClientPermissions.ManageSettings)) return; @@ -217,6 +217,8 @@ namespace Barotrauma.Networking outMsg.Write(autoRestart != null); outMsg.Write(autoRestart ?? false); outMsg.Write(radiationEnabled ?? RadiationEnabled); + outMsg.Write((byte)maxMissionCount + 1); + outMsg.WritePadBits(); } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Screens/CampaignSetupUI.cs b/Barotrauma/BarotraumaClient/ClientSource/Screens/CampaignSetupUI.cs index 19d9c2348..3d9cad979 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Screens/CampaignSetupUI.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Screens/CampaignSetupUI.cs @@ -6,6 +6,7 @@ using Barotrauma.IO; using System.Linq; using System.Xml.Linq; using System.Globalization; +using Barotrauma.Extensions; namespace Barotrauma { @@ -42,6 +43,12 @@ namespace Barotrauma } public GUITickBox EnableRadiationToggle { get; set; } + public GUILayoutGroup CampaignSettingsContent { get; set; } + + public GUIButton CampaignCustomizeButton { get; set; } + public GUIMessageBox CampaignCustomizeSettings { get; set; } + + public GUITextBlock MaxMissionCountText; private readonly bool isMultiplayer; @@ -177,10 +184,19 @@ namespace Barotrauma if (isMultiplayer) { settings.RadiationEnabled = GameMain.NetLobbyScreen.IsRadiationEnabled(); + settings.MaxMissionCount = GameMain.NetLobbyScreen.GetMaxMissionCount(); } else { settings.RadiationEnabled = EnableRadiationToggle?.Selected ?? false; + if (MaxMissionCountText != null && Int32.TryParse(MaxMissionCountText.Text, out int missionCount)) + { + settings.MaxMissionCount = missionCount; + } + else + { + settings.MaxMissionCount = CampaignSettings.DefaultMaxMissionCount; + } } if (selectedSub.HasTag(SubmarineTag.Shuttle) || !hasRequiredContentPackages) @@ -265,14 +281,14 @@ namespace Barotrauma if (!isMultiplayer) { - if (MapGenerationParams.Instance.RadiationParams != null) + CampaignCustomizeButton = new GUIButton(new RectTransform(new Vector2(0.25f, 1f), buttonContainer.RectTransform, Anchor.CenterLeft), TextManager.Get("SettingsButton")) { - EnableRadiationToggle = new GUITickBox(new RectTransform(new Vector2(0.3f, 1f), buttonContainer.RectTransform), TextManager.Get("CampaignOption.EnableRadiation"), font: GUI.Style.Font) + OnClicked = (tb, userdata) => { - Selected = true, - ToolTip = TextManager.Get("campaignoption.enableradiation.tooltip") - }; - } + CreateCustomizeWindow(); + return true; + } + }; var disclaimerBtn = new GUIButton(new RectTransform(new Vector2(1.0f, 0.8f), rightColumn.RectTransform, Anchor.TopRight) { AbsoluteOffset = new Point(5) }, style: "GUINotificationButton") { @@ -290,6 +306,52 @@ namespace Barotrauma UpdateLoadMenu(saveFiles); } + private void CreateCustomizeWindow() + { + CampaignCustomizeSettings = new GUIMessageBox("", "", new string[] { TextManager.Get("OK") }, new Vector2(0.2f, 0.2f)); + CampaignCustomizeSettings.Buttons[0].OnClicked += CampaignCustomizeSettings.Close; + + CampaignSettingsContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), CampaignCustomizeSettings.Content.RectTransform, Anchor.TopCenter)) + { + RelativeSpacing = 0.1f + }; + + if (MapGenerationParams.Instance.RadiationParams != null) + { + EnableRadiationToggle = new GUITickBox(new RectTransform(new Vector2(0.3f, 0.3f), CampaignSettingsContent.RectTransform), TextManager.Get("CampaignOption.EnableRadiation"), font: GUI.Style.Font) + { + Selected = true, + ToolTip = TextManager.Get("campaignoption.enableradiation.tooltip") + }; + } + var maxMissionCountSettingHolder = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.3f), CampaignSettingsContent.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft) + { + Stretch = true, + ToolTip = TextManager.Get("maxmissioncounttooltip") + }; + var maxMissionCountDescription = new GUITextBlock(new RectTransform(new Vector2(0.7f, 0.0f), maxMissionCountSettingHolder.RectTransform), TextManager.Get("maxmissioncount", fallBackTag: "missions"), wrap: true); + var maxMissionCountContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), maxMissionCountSettingHolder.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft) { RelativeSpacing = 0.05f, Stretch = true }; + var maxMissionCountButtons = new GUIButton[2]; + maxMissionCountButtons[0] = new GUIButton(new RectTransform(new Vector2(0.15f, 0.8f), maxMissionCountContainer.RectTransform), style: "GUIButtonToggleLeft") + { + OnClicked = (button, obj) => + { + MaxMissionCountText.Text = Math.Clamp(Int32.Parse(MaxMissionCountText.Text) - 1, CampaignSettings.MinMissionCountLimit, CampaignSettings.MaxMissionCountLimit).ToString(); + return true; + } + }; + MaxMissionCountText = new GUITextBlock(new RectTransform(new Vector2(0.7f, 1.0f), maxMissionCountContainer.RectTransform), CampaignSettings.DefaultMaxMissionCount.ToString(), textAlignment: Alignment.Center, style: "GUITextBox"); + maxMissionCountButtons[1] = new GUIButton(new RectTransform(new Vector2(0.15f, 0.8f), maxMissionCountContainer.RectTransform), style: "GUIButtonToggleRight") + { + OnClicked = (button, obj) => + { + MaxMissionCountText.Text = Math.Clamp(Int32.Parse(MaxMissionCountText.Text) + 1, CampaignSettings.MinMissionCountLimit, CampaignSettings.MaxMissionCountLimit).ToString(); + return true; + } + }; + maxMissionCountContainer.Children.ForEach(c => c.ToolTip = maxMissionCountSettingHolder.ToolTip); + } + private void CreateMultiplayerCampaignSubList(RectTransform parent) { GUILayoutGroup subHolder = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.725f), parent)) diff --git a/Barotrauma/BarotraumaClient/ClientSource/Screens/CampaignUI.cs b/Barotrauma/BarotraumaClient/ClientSource/Screens/CampaignUI.cs index 2f6ad173d..2a07d654a 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Screens/CampaignUI.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Screens/CampaignUI.cs @@ -23,6 +23,8 @@ namespace Barotrauma private GUIListBox missionList; private readonly List missionTickBoxes = new List(); + private bool hasMaxMissions; + private GUIButton repairHullsButton, replaceShuttlesButton, repairItemsButton; private SubmarineSelection submarineSelection; @@ -323,7 +325,17 @@ namespace Barotrauma map.Update(deltaTime, mapContainer); foreach (GUITickBox tickBox in missionTickBoxes) { - tickBox.Enabled = Campaign.AllowedToManageCampaign(); + bool disable = hasMaxMissions && !tickBox.Selected; + tickBox.Enabled = Campaign.AllowedToManageCampaign() && !disable; + tickBox.Box.DisabledColor = disable ? tickBox.Box.Color * 0.5f : tickBox.Box.Color * 0.8f; + foreach (GUIComponent child in tickBox.Parent.Parent.Children) + { + if (child is GUITextBlock textBlock) + { + textBlock.SelectedTextColor = textBlock.HoverTextColor = textBlock.TextColor = + disable ? new Color(textBlock.TextColor, 0.5f) : new Color(textBlock.TextColor, 1.0f); + } + } } } @@ -498,7 +510,6 @@ namespace Barotrauma }; tickBox.RectTransform.MinSize = new Point(tickBox.Rect.Height, 0); tickBox.RectTransform.IsFixedSize = true; - tickBox.Box.DisabledColor = tickBox.Box.Color * 0.8f; tickBox.Enabled = Campaign.AllowedToManageCampaign(); tickBox.OnSelected += (GUITickBox tb) => { @@ -512,6 +523,9 @@ namespace Barotrauma { Campaign.Map.CurrentLocation.DeselectMission(mission); } + + UpdateMaxMissions(connection.OtherLocation(currentDisplayLocation)); + if ((Campaign is MultiPlayerCampaign multiPlayerCampaign) && !multiPlayerCampaign.SuppressStateSending && Campaign.AllowedToManageCampaign()) { @@ -593,8 +607,19 @@ namespace Barotrauma missionList.UpdateScrollBarSize(); } } + UpdateMaxMissions(connection.OtherLocation(currentDisplayLocation)); - StartButton = new GUIButton(new RectTransform(new Vector2(0.5f, 0.1f), content.RectTransform), + var buttonArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), content.RectTransform), isHorizontal: true); + + new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), buttonArea.RectTransform), "", font: GUI.Style.SubHeadingFont) + { + TextGetter = () => + { + return TextManager.AddPunctuation(':', TextManager.Get("Missions"), $"{Campaign.NumberOfMissionsAtLocation(Campaign.GetCurrentDisplayLocation())}/{Campaign.Settings.MaxMissionCount}"); + } + }; + + StartButton = new GUIButton(new RectTransform(new Vector2(0.4f, 1.0f), buttonArea.RectTransform), TextManager.Get("StartCampaignButton"), style: "GUIButtonLarge") { OnClicked = (GUIButton btn, object obj) => @@ -621,6 +646,8 @@ namespace Barotrauma Visible = Campaign.AllowedToEndRound() }; + buttonArea.RectTransform.MinSize = new Point(0, StartButton.RectTransform.MinSize.Y); + if (Level.Loaded != null && connection?.LevelData == Level.Loaded.LevelData && currentDisplayLocation == Campaign.Map?.CurrentLocation) @@ -692,5 +719,10 @@ namespace Barotrauma { return TextManager.GetWithVariable("PlayerCredits", "[credits]", (GameMain.GameSession?.Campaign == null) ? "0" : string.Format(CultureInfo.InvariantCulture, "{0:N0}", GameMain.GameSession.Campaign.Money)); } + + private void UpdateMaxMissions(Location location) + { + hasMaxMissions = Campaign.NumberOfMissionsAtLocation(location) >= Campaign.Settings.MaxMissionCount; + } } } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Screens/MainMenuScreen.cs b/Barotrauma/BarotraumaClient/ClientSource/Screens/MainMenuScreen.cs index 89ebc3243..dcb4ae206 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Screens/MainMenuScreen.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Screens/MainMenuScreen.cs @@ -1164,15 +1164,18 @@ namespace Barotrauma StartNewGame = StartGame }; - var startButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), innerNewGame.RectTransform, Anchor.Center), isHorizontal: true, childAnchor: Anchor.BottomRight); + var startButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), innerNewGame.RectTransform, Anchor.Center), isHorizontal: true, childAnchor: Anchor.BottomRight) + { + RelativeSpacing = 0.05f + }; campaignSetupUI.StartButton.RectTransform.Parent = startButtonContainer.RectTransform; campaignSetupUI.StartButton.RectTransform.MinSize = new Point( (int)(campaignSetupUI.StartButton.TextBlock.TextSize.X * 1.5f), campaignSetupUI.StartButton.RectTransform.MinSize.Y); startButtonContainer.RectTransform.MinSize = new Point(0, campaignSetupUI.StartButton.RectTransform.MinSize.Y); - if (campaignSetupUI.EnableRadiationToggle != null) + if (campaignSetupUI.CampaignCustomizeButton != null) { - campaignSetupUI.EnableRadiationToggle.RectTransform.Parent = startButtonContainer.RectTransform; + campaignSetupUI.CampaignCustomizeButton.RectTransform.Parent = startButtonContainer.RectTransform; } campaignSetupUI.InitialMoneyText.RectTransform.Parent = startButtonContainer.RectTransform; } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Screens/NetLobbyScreen.cs b/Barotrauma/BarotraumaClient/ClientSource/Screens/NetLobbyScreen.cs index 192630005..7e9f8c97a 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Screens/NetLobbyScreen.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Screens/NetLobbyScreen.cs @@ -45,6 +45,10 @@ namespace Barotrauma private readonly GUITickBox radiationEnabledTickBox; + private readonly GUIButton[] maxMissionCountButtons; + private readonly GUITextBlock maxMissionCountText; + private readonly GUITextBlock maxMissionCountDescription; + private readonly GUIButton[] traitorProbabilityButtons; private readonly GUITextBlock traitorProbabilityText; @@ -1158,6 +1162,31 @@ namespace Barotrauma }; } + var maxMissionCountSettingHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), settingsContent.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft) { Stretch = true }; + maxMissionCountDescription = new GUITextBlock(new RectTransform(new Vector2(0.7f, 0.0f), maxMissionCountSettingHolder.RectTransform), TextManager.Get("maxmissioncount", fallBackTag: "missions"), wrap: true) + { + ToolTip = TextManager.Get("maxmissioncounttooltip") + }; + var maxMissionCountContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), maxMissionCountSettingHolder.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft) { RelativeSpacing = 0.05f, Stretch = true }; + maxMissionCountButtons = new GUIButton[2]; + maxMissionCountButtons[0] = new GUIButton(new RectTransform(new Vector2(0.15f, 1.0f), maxMissionCountContainer.RectTransform), style: "GUIButtonToggleLeft") + { + OnClicked = (button, obj) => + { + GameMain.Client.ServerSettings.ClientAdminWrite(ServerSettings.NetFlags.Misc, maxMissionCount: -1); + return true; + } + }; + maxMissionCountText = new GUITextBlock(new RectTransform(new Vector2(0.7f, 1.0f), maxMissionCountContainer.RectTransform), "0", textAlignment: Alignment.Center, style: "GUITextBox"); + maxMissionCountButtons[1] = new GUIButton(new RectTransform(new Vector2(0.15f, 1.0f), maxMissionCountContainer.RectTransform), style: "GUIButtonToggleRight") + { + OnClicked = (button, obj) => + { + GameMain.Client.ServerSettings.ClientAdminWrite(ServerSettings.NetFlags.Misc, maxMissionCount: 1); + return true; + } + }; + maxMissionCountSettingHolder.Children.ForEach(c => c.ToolTip = maxMissionCountSettingHolder.ToolTip); List settingsElements = settingsContent.Children.ToList(); for (int i = 0; i < settingsElements.Count; i++) @@ -1311,6 +1340,13 @@ namespace Barotrauma { radiationEnabledTickBox.Enabled = CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings); } + maxMissionCountDescription.Enabled = CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings); + maxMissionCountText.Enabled = CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings); + foreach (var button in maxMissionCountButtons) + { + button.Enabled = CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings); + } + traitorProbabilityButtons[0].Enabled = traitorProbabilityButtons[1].Enabled = traitorProbabilityText.Enabled = !CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings); botCountButtons[0].Enabled = botCountButtons[1].Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings); diff --git a/Barotrauma/BarotraumaClient/ClientSource/Screens/SubEditorScreen.cs b/Barotrauma/BarotraumaClient/ClientSource/Screens/SubEditorScreen.cs index 9665e80fd..92cc56d16 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Screens/SubEditorScreen.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Screens/SubEditorScreen.cs @@ -1555,8 +1555,13 @@ namespace Barotrauma if (!string.IsNullOrEmpty(specialSavePath) && (string.IsNullOrEmpty(Submarine.MainSub?.Info.FilePath) || Path.GetFileNameWithoutExtension(Submarine.MainSub.Info.Name) != nameBox.Text || Path.GetDirectoryName(Submarine.MainSub?.Info.FilePath) != specialSavePath)) { + string submarineTypeTag = "SubmarineType." + Submarine.MainSub.Info.Type; + if (Submarine.MainSub.Info.Type == SubmarineType.EnemySubmarine && !TextManager.ContainsTag(submarineTypeTag)) + { + submarineTypeTag = "MissionType.Pirate"; + } var msgBox = new GUIMessageBox("", TextManager.GetWithVariables("savesubtospecialfolderprompt", - new string[] { "[type]", "[outpostpath]" }, new string[] { TextManager.Get("submarinetype." + Submarine.MainSub.Info.Type), specialSavePath }), + new string[] { "[type]", "[outpostpath]" }, new string[] { TextManager.Get(submarineTypeTag), specialSavePath }), new string[] { TextManager.Get("yes"), TextManager.Get("no") }); msgBox.Buttons[0].OnClicked = (bt, userdata) => { diff --git a/Barotrauma/BarotraumaClient/LinuxClient.csproj b/Barotrauma/BarotraumaClient/LinuxClient.csproj index a87aad1a8..08278ea16 100644 --- a/Barotrauma/BarotraumaClient/LinuxClient.csproj +++ b/Barotrauma/BarotraumaClient/LinuxClient.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma - 0.1400.3.0 + 0.14.4.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 Barotrauma diff --git a/Barotrauma/BarotraumaClient/MacClient.csproj b/Barotrauma/BarotraumaClient/MacClient.csproj index e6e7e370a..55e4f0cba 100644 --- a/Barotrauma/BarotraumaClient/MacClient.csproj +++ b/Barotrauma/BarotraumaClient/MacClient.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma - 0.1400.3.0 + 0.14.4.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 Barotrauma diff --git a/Barotrauma/BarotraumaClient/WindowsClient.csproj b/Barotrauma/BarotraumaClient/WindowsClient.csproj index cc82d78d0..3984442e8 100644 --- a/Barotrauma/BarotraumaClient/WindowsClient.csproj +++ b/Barotrauma/BarotraumaClient/WindowsClient.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma - 0.1400.3.0 + 0.14.4.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 Barotrauma diff --git a/Barotrauma/BarotraumaServer/LinuxServer.csproj b/Barotrauma/BarotraumaServer/LinuxServer.csproj index 98f689559..86da86dd9 100644 --- a/Barotrauma/BarotraumaServer/LinuxServer.csproj +++ b/Barotrauma/BarotraumaServer/LinuxServer.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma Dedicated Server - 0.1400.3.0 + 0.14.4.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 DedicatedServer diff --git a/Barotrauma/BarotraumaServer/MacServer.csproj b/Barotrauma/BarotraumaServer/MacServer.csproj index 60929758d..5bd315fdf 100644 --- a/Barotrauma/BarotraumaServer/MacServer.csproj +++ b/Barotrauma/BarotraumaServer/MacServer.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma Dedicated Server - 0.1400.3.0 + 0.14.4.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 DedicatedServer diff --git a/Barotrauma/BarotraumaServer/ServerSource/GameSession/GameModes/MultiPlayerCampaign.cs b/Barotrauma/BarotraumaServer/ServerSource/GameSession/GameModes/MultiPlayerCampaign.cs index 0769792c7..49abc7448 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/GameSession/GameModes/MultiPlayerCampaign.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/GameSession/GameModes/MultiPlayerCampaign.cs @@ -684,6 +684,8 @@ namespace Barotrauma if (Map.SelectedLocation == null) { Map.SelectRandomLocation(preferUndiscovered: true); } if (Map.SelectedConnection != null) { Map.SelectMission(selectedMissionIndices); } + CheckTooManyMissions(Map.CurrentLocation, sender); + List currentBuyCrateItems = new List(CargoManager.ItemsInBuyCrate); currentBuyCrateItems.ForEach(i => CargoManager.ModifyItemQuantityInBuyCrate(i.ItemPrefab, -i.Quantity)); buyCrateItems.ForEach(i => CargoManager.ModifyItemQuantityInBuyCrate(i.ItemPrefab, i.Quantity)); diff --git a/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs b/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs index f98d6a2b3..75273e01c 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs @@ -1899,6 +1899,7 @@ namespace Barotrauma.Networking } outmsg.Write(serverSettings.RadiationEnabled); + outmsg.Write((byte)serverSettings.MaxMissionCount); } else { diff --git a/Barotrauma/BarotraumaServer/ServerSource/Networking/ServerSettings.cs b/Barotrauma/BarotraumaServer/ServerSource/Networking/ServerSettings.cs index 994d9190c..affe37a85 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Networking/ServerSettings.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Networking/ServerSettings.cs @@ -162,6 +162,11 @@ namespace Barotrauma.Networking RadiationEnabled = incMsg.ReadBoolean(); + int maxMissionCount = MaxMissionCount + incMsg.ReadByte() - 1; + if (maxMissionCount < CampaignSettings.MinMissionCountLimit) maxMissionCount = CampaignSettings.MaxMissionCountLimit; + if (maxMissionCount > CampaignSettings.MaxMissionCountLimit) maxMissionCount = CampaignSettings.MinMissionCountLimit; + MaxMissionCount = maxMissionCount; + changed |= true; } @@ -324,6 +329,7 @@ namespace Barotrauma.Networking GameMain.NetLobbyScreen.SetBotSpawnMode(BotSpawnMode); GameMain.NetLobbyScreen.SetBotCount(BotCount); + GameMain.NetLobbyScreen.SetMaxMissionCount(MaxMissionCount); List monsterNames = CharacterPrefab.Prefabs.Select(p => p.Identifier).ToList(); MonsterEnabled = new Dictionary(); diff --git a/Barotrauma/BarotraumaServer/WindowsServer.csproj b/Barotrauma/BarotraumaServer/WindowsServer.csproj index 00cb9e609..a483f6318 100644 --- a/Barotrauma/BarotraumaServer/WindowsServer.csproj +++ b/Barotrauma/BarotraumaServer/WindowsServer.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma Dedicated Server - 0.1400.3.0 + 0.14.4.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 DedicatedServer diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/HumanAIController.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/HumanAIController.cs index bb204ccc1..e4d777e7f 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/HumanAIController.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/HumanAIController.cs @@ -479,7 +479,7 @@ namespace Barotrauma Character.AnimController.InWater || Character.AnimController.HeadInWater || Character.CurrentHull == null || - (Character.Submarine.TeamID != Character.TeamID && !Character.IsEscorted) || // these instances should maybe be combined to a method + (Character.Submarine?.TeamID != Character.TeamID && !Character.IsEscorted) || // these instances should maybe be combined to a method ObjectiveManager.IsCurrentObjective() || ObjectiveManager.CurrentObjective.GetSubObjectivesRecursive(true).Any(o => o.KeepDivingGearOn); if (oxygenLow && Character.CurrentHull.Oxygen > 0) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/ShipCommandManager.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/ShipCommandManager.cs index c85cf7885..23856db00 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/ShipCommandManager.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/ShipCommandManager.cs @@ -244,12 +244,12 @@ namespace Barotrauma availableIssues.Sort((x, y) => y.Importance.CompareTo(x.Importance)); attendedIssues.Sort((x, y) => x.Importance.CompareTo(y.Importance)); - ShipIssueWorker mostImportantIssue = availableIssues.First(); + ShipIssueWorker mostImportantIssue = availableIssues.FirstOrDefault(); float bestValue = 0f; Character bestCharacter = null; - if (mostImportantIssue.Importance > MinimumIssueThreshold) + if (mostImportantIssue != null && mostImportantIssue.Importance > MinimumIssueThreshold) { IEnumerable bestCharacters = CrewManager.GetCharactersSortedForOrder(mostImportantIssue.SuggestedOrderPrefab, AlliedCharacters, character, true); @@ -296,7 +296,7 @@ namespace Barotrauma } } - if (bestCharacter != null) + if (bestCharacter != null && mostImportantIssue != null) { #if DEBUG ShipCommandLog("Setting " + mostImportantIssue + " for character " + bestCharacter); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/Ragdoll.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/Ragdoll.cs index f2343388a..43d9dc327 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/Ragdoll.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/Ragdoll.cs @@ -637,7 +637,7 @@ namespace Barotrauma impactQueue.Enqueue(new Impact(f1, f2, contact, velocity)); } } - return !f2.IsSensor; + return true; } Vector2 colliderBottom = GetColliderBottom(); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Attack.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Attack.cs index b50cda9b3..c89b02b76 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Attack.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Attack.cs @@ -514,7 +514,7 @@ namespace Barotrauma DamageParticles(deltaTime, worldPosition); - var attackResult = targetLimb.character.ApplyAttack(attacker, worldPosition, this, deltaTime, playSound, targetLimb, penetration:Penetration); + var attackResult = targetLimb.character.ApplyAttack(attacker, worldPosition, this, deltaTime, playSound, targetLimb, penetration: Penetration); var effectType = attackResult.Damage > 0.0f ? ActionType.OnUse : ActionType.OnFailure; foreach (StatusEffect effect in statusEffects) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Jobs/JobPrefab.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Jobs/JobPrefab.cs index 86271a9c7..c918b7363 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Jobs/JobPrefab.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Jobs/JobPrefab.cs @@ -300,7 +300,6 @@ namespace Barotrauma } foreach (XElement element in mainElement.Elements()) { - if (!element.Name.ToString().Equals("job", StringComparison.OrdinalIgnoreCase)) { continue; } if (element.IsOverride()) { var job = new JobPrefab(element.FirstElement(), file.Path) @@ -311,6 +310,7 @@ namespace Barotrauma } else { + if (!element.Name.ToString().Equals("job", StringComparison.OrdinalIgnoreCase)) { continue; } var job = new JobPrefab(element, file.Path) { ContentPackage = file.ContentPackage diff --git a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/CampaignMode.cs b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/CampaignMode.cs index 1ecab703e..300a5ce2b 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/CampaignMode.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/CampaignMode.cs @@ -17,25 +17,33 @@ namespace Barotrauma // Anything that uses this field I wasn't sure if actually needed the proper campaign settings to be passed down public static CampaignSettings Unsure = Empty; public bool RadiationEnabled { get; set; } + public int MaxMissionCount { get; set; } + + public const int DefaultMaxMissionCount = 2; + public const int MaxMissionCountLimit = 10; + public const int MinMissionCountLimit = 1; public CampaignSettings(IReadMessage inc) { RadiationEnabled = inc.ReadBoolean(); + MaxMissionCount = inc.ReadInt32(); } public CampaignSettings(XElement element) { RadiationEnabled = element.GetAttributeBool(nameof(RadiationEnabled).ToLower(), true); + MaxMissionCount = element.GetAttributeInt(nameof(MaxMissionCount).ToLower(), DefaultMaxMissionCount); } public void Serialize(IWriteMessage msg) { msg.Write(RadiationEnabled); + msg.Write(MaxMissionCount); } public XElement Save() { - return new XElement(nameof(CampaignSettings), new XAttribute(nameof(RadiationEnabled).ToLower(), RadiationEnabled)); + return new XElement(nameof(CampaignSettings), new XAttribute(nameof(RadiationEnabled).ToLower(), RadiationEnabled), new XAttribute(nameof(MaxMissionCount).ToLower().ToLower(), MaxMissionCount)); } } @@ -874,5 +882,25 @@ namespace Barotrauma map?.Remove(); map = null; } + + public int NumberOfMissionsAtLocation(Location location) + { + return Map.CurrentLocation.SelectedMissions.Count(m => m.Locations.Contains(location)); + } + + public void CheckTooManyMissions(Location currentLocation, Client sender) + { + foreach (Location location in currentLocation.Connections.Select(c => c.OtherLocation(currentLocation))) + { + if (NumberOfMissionsAtLocation(location) > Settings.MaxMissionCount) + { + DebugConsole.AddWarning($"Client {sender.Name} had too many missions selected for location {location.Name}! Count was {NumberOfMissionsAtLocation(location)}. Deselecting extra missions."); + foreach (Mission mission in currentLocation.SelectedMissions.Where(m => m.Locations[1] == location).Skip(Settings.MaxMissionCount).ToList()) + { + currentLocation.DeselectMission(mission); + } + } + } + } } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/DockingPort.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/DockingPort.cs index 4488c262b..974921b4d 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/DockingPort.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/DockingPort.cs @@ -807,22 +807,22 @@ namespace Barotrauma.Items.Components for (int i = 0; i < 2; i++) { Gap doorGap = i == 0 ? Door?.LinkedGap : DockingTarget?.Door?.LinkedGap; - if (doorGap == null) continue; + if (doorGap == null) { continue; } doorGap.DisableHullRechecks = true; - if (doorGap.linkedTo.Count >= 2) continue; + if (doorGap.linkedTo.Count >= 2) { continue; } if (IsHorizontal) { if (item.WorldPosition.X < DockingTarget.item.WorldPosition.X) { - if (!doorGap.linkedTo.Contains(hulls[0])) doorGap.linkedTo.Add(hulls[0]); + if (!doorGap.linkedTo.Contains(hulls[0])) { doorGap.linkedTo.Add(hulls[0]); } } else { - if (!doorGap.linkedTo.Contains(hulls[1])) doorGap.linkedTo.Add(hulls[1]); + if (!doorGap.linkedTo.Contains(hulls[1])) { doorGap.linkedTo.Add(hulls[1]); } } //make sure the left hull is linked to the gap first (gap logic assumes that the first hull is the one to the left) - if (doorGap.linkedTo.Count > 1 && doorGap.linkedTo[0].Rect.X > doorGap.linkedTo[1].Rect.X) + if (doorGap.linkedTo.Count > 1 && doorGap.linkedTo[0].WorldRect.X > doorGap.linkedTo[1].WorldRect.X) { var temp = doorGap.linkedTo[0]; doorGap.linkedTo[0] = doorGap.linkedTo[1]; @@ -831,16 +831,16 @@ namespace Barotrauma.Items.Components } else { - if (item.WorldPosition.Y < DockingTarget.item.WorldPosition.Y) + if (item.WorldPosition.Y > DockingTarget.item.WorldPosition.Y) { - if (!doorGap.linkedTo.Contains(hulls[0])) doorGap.linkedTo.Add(hulls[0]); + if (!doorGap.linkedTo.Contains(hulls[0])) { doorGap.linkedTo.Add(hulls[0]); } } else { - if (!doorGap.linkedTo.Contains(hulls[1])) doorGap.linkedTo.Add(hulls[1]); + if (!doorGap.linkedTo.Contains(hulls[1])) { doorGap.linkedTo.Add(hulls[1]); } } //make sure the upper hull is linked to the gap first (gap logic assumes that the first hull is above the second one) - if (doorGap.linkedTo.Count > 1 && doorGap.linkedTo[0].Rect.Y < doorGap.linkedTo[1].Rect.Y) + if (doorGap.linkedTo.Count > 1 && doorGap.linkedTo[0].WorldRect.Y < doorGap.linkedTo[1].WorldRect.Y) { var temp = doorGap.linkedTo[0]; doorGap.linkedTo[0] = doorGap.linkedTo[1]; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Engine.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Engine.cs index e4502d68c..0e9457394 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Engine.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Engine.cs @@ -172,14 +172,23 @@ namespace Barotrauma.Items.Components float scaledDamageRange = propellerDamage.DamageRange * item.Scale; - Vector2 propellerWorldPos = item.WorldPosition + PropellerPos * item.Scale; + Vector2 propellerWorldPos = item.WorldPosition + PropellerPos * item.Scale; + float broadRange = Math.Max(scaledDamageRange * 2, 500); foreach (Character character in Character.CharacterList) { if (!character.Enabled || character.Removed) { continue; } - float distSqr = Vector2.DistanceSquared(character.WorldPosition, propellerWorldPos); - if (distSqr > scaledDamageRange * scaledDamageRange) { continue; } - character.LastDamageSource = item; - propellerDamage.DoDamage(null, character, propellerWorldPos, 1.0f, true); + if (Math.Abs(character.WorldPosition.X - propellerWorldPos.X) > broadRange) { continue; } + if (Math.Abs(character.WorldPosition.Y - propellerWorldPos.Y) > broadRange) { continue; } + + foreach (Limb limb in character.AnimController.Limbs) + { + if (limb.IsSevered || !limb.body.Enabled) { continue; } + float distSqr = Vector2.DistanceSquared(limb.WorldPosition, propellerWorldPos); + if (distSqr > scaledDamageRange * scaledDamageRange) { continue; } + character.LastDamageSource = item; + propellerDamage.DoDamage(null, character, propellerWorldPos, 1.0f, true); + break; + } } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Projectile.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Projectile.cs index 104d8cb08..7e5cd03e6 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Projectile.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Projectile.cs @@ -72,6 +72,8 @@ namespace Barotrauma.Items.Components } } + public Character Attacker { get; set; } + public IEnumerable Hits { get { return hits; } @@ -723,7 +725,7 @@ namespace Barotrauma.Items.Components if (limb.IsSevered || limb.character == null || limb.character.Removed) { return false; } limb.character.LastDamageSource = item; - if (Attack != null) { attackResult = Attack.DoDamageToLimb(User, limb, item.WorldPosition, 1.0f); } + if (Attack != null) { attackResult = Attack.DoDamageToLimb(User ?? Attacker, limb, item.WorldPosition, 1.0f); } if (limb.character != null) { character = limb.character; } } else if (target.Body.UserData is Item targetItem) @@ -731,18 +733,18 @@ namespace Barotrauma.Items.Components if (targetItem.Removed) { return false; } if (Attack != null && targetItem.Prefab.DamagedByProjectiles && targetItem.Condition > 0) { - attackResult = Attack.DoDamage(User, targetItem, item.WorldPosition, 1.0f); + attackResult = Attack.DoDamage(User ?? Attacker, targetItem, item.WorldPosition, 1.0f); } } else if (target.Body.UserData is IDamageable damageable) { - if (Attack != null) { attackResult = Attack.DoDamage(User, damageable, item.WorldPosition, 1.0f); } + if (Attack != null) { attackResult = Attack.DoDamage(User ?? Attacker, damageable, item.WorldPosition, 1.0f); } } else if (target.Body.UserData is VoronoiCell voronoiCell && voronoiCell.IsDestructible && Attack != null && Math.Abs(Attack.LevelWallDamage) > 0.0f) { if (Level.Loaded?.ExtraWalls.Find(w => w.Body == target.Body) is DestructibleLevelWall destructibleWall) { - attackResult = Attack.DoDamage(User, destructibleWall, item.WorldPosition, 1.0f); + attackResult = Attack.DoDamage(User ?? Attacker, destructibleWall, item.WorldPosition, 1.0f); } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Turret.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Turret.cs index 076aff11c..7e93b1ab2 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Turret.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Turret.cs @@ -696,6 +696,7 @@ namespace Barotrauma.Items.Components Projectile projectileComponent = projectile.GetComponent(); if (projectileComponent != null) { + projectileComponent.Attacker = user; projectileComponent.Use(); projectile.GetComponent()?.Attach(item, projectile); projectileComponent.User = user; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs index 0cb65f4e2..09aa00461 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs @@ -691,6 +691,29 @@ namespace Barotrauma get { return Prefab.Linkable; } } + /// + /// Can be used to move the item from XML (e.g. to correct the positions of items whose sprite origin has been changed) + /// + public float PositionX + { + get { return Position.X; } + private set + { + Move(new Vector2((value - Position.X) * Scale, 0.0f)); + } + } + /// + /// Can be used to move the item from XML (e.g. to correct the positions of items whose sprite origin has been changed) + /// + public float PositionY + { + get { return Position.Y; } + private set + { + Move(new Vector2(0.0f, (value - Position.Y) * Scale)); + } + } + public BallastFloraBranch Infector { get; set; } public ItemPrefab PendingItemSwap { get; set; } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs index d2a4ce88b..c7256157a 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs @@ -516,7 +516,7 @@ namespace Barotrauma [Serialize(null, false)] public string EquipConfirmationText { get; set; } - [Serialize(true, false, description: "Can the item be rotated in the sprite editor.")] + [Serialize(true, false, description: "Can the item be rotated in the submarine editor.")] public bool AllowRotatingInEditor { get; set; } [Serialize(false, false)] diff --git a/Barotrauma/BarotraumaShared/SharedSource/Map/FireSource.cs b/Barotrauma/BarotraumaShared/SharedSource/Map/FireSource.cs index cb846612f..ee66d4483 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Map/FireSource.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Map/FireSource.cs @@ -94,7 +94,7 @@ namespace Barotrauma public FireSource(Vector2 worldPosition, Hull spawningHull = null, bool isNetworkMessage = false) { hull = Hull.FindHull(worldPosition, spawningHull); - if (hull == null || worldPosition.Y < hull.WorldSurface) return; + if (hull == null || worldPosition.Y < hull.WorldSurface) { return; } #if CLIENT if (!isNetworkMessage && GameMain.Client != null) { return; } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Map/Hull.cs b/Barotrauma/BarotraumaShared/SharedSource/Map/Hull.cs index 93b0bc920..de7ad710f 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Map/Hull.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Map/Hull.cs @@ -574,6 +574,9 @@ namespace Barotrauma Pressure = rect.Y - rect.Height + waterVolume / rect.Width; BallastFlora?.OnMapLoaded(); +#if CLIENT + lastAmbientLightEditTime = 0.0; +#endif } public void AddToGrid(Submarine submarine) @@ -683,6 +686,11 @@ namespace Barotrauma public void AddFireSource(FireSource fireSource) { + if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) + { + //clients aren't allowed to create fire sources in hulls whose IDs have been freed (dynamic hulls between docking ports), because they can't be synced + if (IdFreed) { return; } + } if (fireSource is DummyFireSource dummyFire) { FakeFireSources.Add(dummyFire); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Networking/ServerSettings.cs b/Barotrauma/BarotraumaShared/SharedSource/Networking/ServerSettings.cs index f0e7e3349..8b72e0075 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Networking/ServerSettings.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Networking/ServerSettings.cs @@ -892,6 +892,8 @@ namespace Barotrauma.Networking get; set; } + // we do not serialize this value because it relies on a default setting + public int MaxMissionCount { get; set; } = CampaignSettings.DefaultMaxMissionCount; public void SetPassword(string password) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Screens/NetLobbyScreen.cs b/Barotrauma/BarotraumaShared/SharedSource/Screens/NetLobbyScreen.cs index e7c3e5da5..8cd8dae34 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Screens/NetLobbyScreen.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Screens/NetLobbyScreen.cs @@ -53,7 +53,41 @@ namespace Barotrauma return GameMain.Server.ServerSettings.RadiationEnabled; #endif } - + + public void SetMaxMissionCount(int maxMissionCount) + { +#if SERVER + if (GameMain.Server != null) + { + if (maxMissionCount < CampaignSettings.MinMissionCountLimit) maxMissionCount = CampaignSettings.MaxMissionCountLimit; + if (maxMissionCount > CampaignSettings.MaxMissionCountLimit) maxMissionCount = CampaignSettings.MinMissionCountLimit; + + GameMain.Server.ServerSettings.MaxMissionCount = maxMissionCount; + lastUpdateID++; + } +#endif +#if CLIENT + (maxMissionCountText as GUITextBlock).Text = maxMissionCount.ToString(); +#endif + } + + public int GetMaxMissionCount() + { +#if CLIENT + // this seems rather silly, but it matches the radiation enabled check structurally. is this right? + if (maxMissionCountText != null && Int32.TryParse(maxMissionCountText.Text, out int result)) + { + return result; + } + else + { + return 0; + } +#elif SERVER + return GameMain.Server.ServerSettings.MaxMissionCount; +#endif + } + public void ToggleTraitorsEnabled(int dir) { #if SERVER diff --git a/Barotrauma/BarotraumaShared/SharedSource/Serialization/SerializableProperty.cs b/Barotrauma/BarotraumaShared/SharedSource/Serialization/SerializableProperty.cs index 0bff8f737..f04d1fc1a 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Serialization/SerializableProperty.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Serialization/SerializableProperty.cs @@ -790,7 +790,7 @@ namespace Barotrauma } } - void FixValue(SerializableProperty property, object parentObject, XAttribute attribute) + static void FixValue(SerializableProperty property, object parentObject, XAttribute attribute) { if (attribute.Value.Length > 0 && attribute.Value[0] == '*') { @@ -813,6 +813,29 @@ namespace Barotrauma property.TrySetValue(parentObject, ((Point)property.GetValue(parentObject)).Multiply(multiplier)); } } + else if (attribute.Value.Length > 0 && attribute.Value[0] == '+') + { + if (property.PropertyType == typeof(int)) + { + float.TryParse(attribute.Value.Substring(1), NumberStyles.Float, CultureInfo.InvariantCulture, out float addition); + property.TrySetValue(parentObject, (int)(((int)property.GetValue(parentObject)) + addition)); + } + else if (property.PropertyType == typeof(float)) + { + float.TryParse(attribute.Value.Substring(1), NumberStyles.Float, CultureInfo.InvariantCulture, out float addition); + property.TrySetValue(parentObject, (float)property.GetValue(parentObject) + addition); + } + else if (property.PropertyType == typeof(Vector2)) + { + var addition = XMLExtensions.ParseVector2(attribute.Value.Substring(1)); + property.TrySetValue(parentObject, (Vector2)property.GetValue(parentObject) + addition); + } + else if (property.PropertyType == typeof(Point)) + { + var addition = XMLExtensions.ParsePoint(attribute.Value.Substring(1)); + property.TrySetValue(parentObject, ((Point)property.GetValue(parentObject)) + addition); + } + } else { property.TrySetValue(parentObject, attribute.Value); diff --git a/Barotrauma/BarotraumaShared/Submarines/Azimuth.sub b/Barotrauma/BarotraumaShared/Submarines/Azimuth.sub index 0211065aa..8cd68e513 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Azimuth.sub and b/Barotrauma/BarotraumaShared/Submarines/Azimuth.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Berilia.sub b/Barotrauma/BarotraumaShared/Submarines/Berilia.sub index a24f1c7c1..3e0c87dbc 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Berilia.sub and b/Barotrauma/BarotraumaShared/Submarines/Berilia.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Dugong.sub b/Barotrauma/BarotraumaShared/Submarines/Dugong.sub index 7bcc4f257..0d93cd70f 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Dugong.sub and b/Barotrauma/BarotraumaShared/Submarines/Dugong.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/DugongPirate.sub b/Barotrauma/BarotraumaShared/Submarines/DugongPirate.sub deleted file mode 100644 index 788d06689..000000000 Binary files a/Barotrauma/BarotraumaShared/Submarines/DugongPirate.sub and /dev/null differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Humpback.sub b/Barotrauma/BarotraumaShared/Submarines/Humpback.sub index 75588c8c2..642369fbc 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Humpback.sub and b/Barotrauma/BarotraumaShared/Submarines/Humpback.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/HumpbackPirate.sub b/Barotrauma/BarotraumaShared/Submarines/HumpbackPirate.sub deleted file mode 100644 index 8b7dbc7f0..000000000 Binary files a/Barotrauma/BarotraumaShared/Submarines/HumpbackPirate.sub and /dev/null differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Kastrull.sub b/Barotrauma/BarotraumaShared/Submarines/Kastrull.sub index 93e64afe2..a3aba369b 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Kastrull.sub and b/Barotrauma/BarotraumaShared/Submarines/Kastrull.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Orca.sub b/Barotrauma/BarotraumaShared/Submarines/Orca.sub index 76b34a13b..10ea9b77e 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Orca.sub and b/Barotrauma/BarotraumaShared/Submarines/Orca.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/R-29.sub b/Barotrauma/BarotraumaShared/Submarines/R-29.sub index a58addced..a9c57b323 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/R-29.sub and b/Barotrauma/BarotraumaShared/Submarines/R-29.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Remora.sub b/Barotrauma/BarotraumaShared/Submarines/Remora.sub index 46cff2776..a58fee96f 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Remora.sub and b/Barotrauma/BarotraumaShared/Submarines/Remora.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Typhon.sub b/Barotrauma/BarotraumaShared/Submarines/Typhon.sub index 0863bbd82..6b9f2045f 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Typhon.sub and b/Barotrauma/BarotraumaShared/Submarines/Typhon.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Typhon2.sub b/Barotrauma/BarotraumaShared/Submarines/Typhon2.sub index 024fb5f2f..f3e02a871 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Typhon2.sub and b/Barotrauma/BarotraumaShared/Submarines/Typhon2.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Typhon2Pirate.sub b/Barotrauma/BarotraumaShared/Submarines/Typhon2Pirate.sub deleted file mode 100644 index 01c1d86da..000000000 Binary files a/Barotrauma/BarotraumaShared/Submarines/Typhon2Pirate.sub and /dev/null differ diff --git a/Barotrauma/BarotraumaShared/changelog.txt b/Barotrauma/BarotraumaShared/changelog.txt index b6e56b539..80851ac36 100644 --- a/Barotrauma/BarotraumaShared/changelog.txt +++ b/Barotrauma/BarotraumaShared/changelog.txt @@ -1,3 +1,34 @@ +--------------------------------------------------------------------------------------------------------- +v0.14.4.0 (unstable) +--------------------------------------------------------------------------------------------------------- + +Changes: +- Restrict the number of missions you can choose per level to 2. +- Removed Endworm's weak point in the mouth. +- Alien/physicorium shells now break the limbs again, like they used to. Reduced the damage from 1000 to 800. +- Pulse laser doesn't bypass all the damagemodifiers anymore (because it uses burndamage instead of burn). Increased the damage slightly. + +Fixes: +- Fixed some incorrect room names in the beacon stations. +- Fixed propeller damage area triggering very inaccurately, particularly on shuttle engines. +- Fixed hull indicators fading in when loading a sub in the editor (they should only get hidden and fade in when editing the ambient light value). +- Fixed inability to override jobs with mods (unstable only). +- Fixed rotated levelobjects emitting particles in a wrong direction (e.g. cave vents). +- Fixed LevelTriggers staying active when the character who activated them leaves them (e.g. gas vents draining oxygen even after you've left their trigger area). Unstable only. +- Removed duplicate front piece from pirate Humpback. +- Fixed boss health bar not showing up when damaging boss monsters with the pulse laser. +- Fixed gaps sometimes getting linked incorrectly to the hulls between docking hatches, preventing water from flowing down from the lower hull in mirrored subs. Happened in mirrored Kastrull for example. +- Fixed fires in hulls between docking ports never going out client-side. +- Fixed Moloch's armor not always breaking when shot with a railgun. +- Fixed Moloch's armor breaking when shot with canister shots or chainguns. +- Fixed the armor penetration of railgun shell not working. +- Fixed a crash related to bots entering dry rooms inside alien ruins. (unstable only) +- Fixed nav terminal's, sonar monitor's and status monitor's selection rectangles being offset from the sprite in the sub editor. +- Fixed mirrored pumps emitting particles from the wrong side of the pump. +- Fixed turret icon not switching back to the previous one in the sub preview when cancelling a pending turret upgrade. +- Fixed occasional "sequence contains no elements" crash when updating pirate AI. +- Fixed occasional "index out of range" console errors when a client receives an update about the pirates' AI state. + --------------------------------------------------------------------------------------------------------- v0.1400.3.0 (unstable) ---------------------------------------------------------------------------------------------------------