Unstable 0.14.4.0

This commit is contained in:
Markus Isberg
2021-06-09 17:09:20 +03:00
parent de04525d51
commit 1f3e588fcd
54 changed files with 468 additions and 133 deletions

View File

@@ -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);

View File

@@ -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;
/// <param name="isScrollBarOnDefaultSide">For horizontal listbox, default side is on the bottom. For vertical, it's on the right.</param>
@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -16,8 +16,8 @@ namespace Barotrauma.Items.Components
private GUITickBox powerLight;
private GUITickBox autoControlIndicator;
private List<Pair<Vector2, ParticleEmitter>> pumpOutEmitters = new List<Pair<Vector2, ParticleEmitter>>();
private List<Pair<Vector2, ParticleEmitter>> pumpInEmitters = new List<Pair<Vector2, ParticleEmitter>>();
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<Vector2, ParticleEmitter>(
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<Vector2, ParticleEmitter>(
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<Vector2, ParticleEmitter> 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<Vector2, ParticleEmitter> 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));
}
}

View File

@@ -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)

View File

@@ -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]));

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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))

View File

@@ -23,6 +23,8 @@ namespace Barotrauma
private GUIListBox missionList;
private readonly List<GUITickBox> missionTickBoxes = new List<GUITickBox>();
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;
}
}
}

View File

@@ -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;
}

View File

@@ -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<GUIComponent> 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);

View File

@@ -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) =>
{

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product>
<Version>0.1400.3.0</Version>
<Version>0.14.4.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product>
<Version>0.1400.3.0</Version>
<Version>0.14.4.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product>
<Version>0.1400.3.0</Version>
<Version>0.14.4.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product>
<Version>0.1400.3.0</Version>
<Version>0.14.4.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product>
<Version>0.1400.3.0</Version>
<Version>0.14.4.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName>

View File

@@ -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<PurchasedItem> currentBuyCrateItems = new List<PurchasedItem>(CargoManager.ItemsInBuyCrate);
currentBuyCrateItems.ForEach(i => CargoManager.ModifyItemQuantityInBuyCrate(i.ItemPrefab, -i.Quantity));
buyCrateItems.ForEach(i => CargoManager.ModifyItemQuantityInBuyCrate(i.ItemPrefab, i.Quantity));

View File

@@ -1899,6 +1899,7 @@ namespace Barotrauma.Networking
}
outmsg.Write(serverSettings.RadiationEnabled);
outmsg.Write((byte)serverSettings.MaxMissionCount);
}
else
{

View File

@@ -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<string> monsterNames = CharacterPrefab.Prefabs.Select(p => p.Identifier).ToList();
MonsterEnabled = new Dictionary<string, bool>();

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product>
<Version>0.1400.3.0</Version>
<Version>0.14.4.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName>

View File

@@ -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<AIObjectiveFindSafety>() ||
ObjectiveManager.CurrentObjective.GetSubObjectivesRecursive(true).Any(o => o.KeepDivingGearOn);
if (oxygenLow && Character.CurrentHull.Oxygen > 0)

View File

@@ -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<Character> 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);

View File

@@ -637,7 +637,7 @@ namespace Barotrauma
impactQueue.Enqueue(new Impact(f1, f2, contact, velocity));
}
}
return !f2.IsSensor;
return true;
}
Vector2 colliderBottom = GetColliderBottom();

View File

@@ -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)

View File

@@ -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

View File

@@ -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);
}
}
}
}
}
}

View File

@@ -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];

View File

@@ -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;
}
}
}

View File

@@ -72,6 +72,8 @@ namespace Barotrauma.Items.Components
}
}
public Character Attacker { get; set; }
public IEnumerable<Body> 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);
}
}

View File

@@ -696,6 +696,7 @@ namespace Barotrauma.Items.Components
Projectile projectileComponent = projectile.GetComponent<Projectile>();
if (projectileComponent != null)
{
projectileComponent.Attacker = user;
projectileComponent.Use();
projectile.GetComponent<Rope>()?.Attach(item, projectile);
projectileComponent.User = user;

View File

@@ -691,6 +691,29 @@ namespace Barotrauma
get { return Prefab.Linkable; }
}
/// <summary>
/// Can be used to move the item from XML (e.g. to correct the positions of items whose sprite origin has been changed)
/// </summary>
public float PositionX
{
get { return Position.X; }
private set
{
Move(new Vector2((value - Position.X) * Scale, 0.0f));
}
}
/// <summary>
/// Can be used to move the item from XML (e.g. to correct the positions of items whose sprite origin has been changed)
/// </summary>
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; }

View File

@@ -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)]

View File

@@ -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; }

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -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

View File

@@ -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);

View File

@@ -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)
---------------------------------------------------------------------------------------------------------