Release 1.10.6.0 - Autumn Update 2025 Hotfix 1

This commit is contained in:
Regalis11
2025-09-25 11:11:35 +03:00
parent bad999d5fc
commit b2d91cde7c
25 changed files with 435 additions and 226 deletions
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<contentpackage name="[DebugOnlyTest]testGapSub" modversion="1.0.3" corepackage="False" gameversion="1.9.5.0">
<contentpackage name="[DebugOnlyTest]testGapSub" modversion="1.0.4" corepackage="False" gameversion="1.10.4.0">
<Submarine file="%ModDir%/testGapSub.sub" />
</contentpackage>
@@ -1,5 +1,6 @@
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
@@ -12,8 +13,8 @@ namespace Barotrauma.Items.Components
[Serialize(1.0f, IsPropertySaveable.No, description: "How fast the item changes the color of the walls.")]
public float SprayStrength { get; set; }
private readonly Dictionary<Identifier, Color> liquidColors;
private ItemContainer liquidContainer;
public readonly ImmutableDictionary<Identifier, Color> LiquidColors;
public ItemContainer LiquidContainer { get; private set; }
public Sprayer(Item item, ContentXElement element) : base(item, element)
{
@@ -26,7 +27,7 @@ namespace Barotrauma.Items.Components
{
case "paintcolors":
{
liquidColors = new Dictionary<Identifier, Color>();
var liquidColors = new Dictionary<Identifier, Color>();
foreach (XElement paintElement in subElement.Elements())
{
Identifier paintName = paintElement.GetAttributeIdentifier("paintitem", Identifier.Empty);
@@ -37,6 +38,7 @@ namespace Barotrauma.Items.Components
liquidColors.Add(paintName, paintColor);
}
}
LiquidColors = liquidColors.ToImmutableDictionary();
}
break;
}
@@ -46,7 +48,7 @@ namespace Barotrauma.Items.Components
public override void OnItemLoaded()
{
liquidContainer = item.GetComponent<ItemContainer>();
LiquidContainer = item.GetComponent<ItemContainer>();
}
partial void InitProjSpecific(ContentXElement element);
@@ -59,6 +59,8 @@ namespace Barotrauma
private float higherSurface;
private float lowerSurface;
private float waterFlowThisFrame;
private Vector2 lerpedFlowForce;
//if set to true, hull connections of this gap won't be updated when changes are being done to hulls
@@ -503,6 +505,7 @@ namespace Barotrauma
delta = Math.Min(delta, hull1.Volume * Hull.MaxCompress - hull1.WaterVolume);
hull1.WaterVolume += delta;
hull2.WaterVolume -= delta;
waterFlowThisFrame += delta;
if (hull1.WaterVolume > hull1.Volume)
{
hull1.Pressure = Math.Max(hull1.Pressure, (hull1.Pressure + hull2.Pressure+subOffset.Y) / 2);
@@ -529,7 +532,7 @@ namespace Barotrauma
{
hull2.Pressure = Math.Max(hull2.Pressure, ((hull1.Pressure-subOffset.Y) + hull2.Pressure) / 2);
}
waterFlowThisFrame += delta;
flowForce = new Vector2(delta * (float)(Timing.Step / deltaTime), 0.0f);
}
@@ -569,6 +572,7 @@ namespace Barotrauma
delta = Math.Max(delta, 0.0f);
hull1.WaterVolume += delta;
hull2.WaterVolume -= delta;
waterFlowThisFrame += delta;
flowForce = new Vector2(
0.0f,
@@ -597,6 +601,7 @@ namespace Barotrauma
}
hull1.WaterVolume -= delta;
hull2.WaterVolume += delta;
waterFlowThisFrame += delta;
flowForce = new Vector2(
hull1.WaveY[hull1.GetWaveIndex(rect.X)] - hull1.WaveY[hull1.GetWaveIndex(rect.Right)],
@@ -734,6 +739,11 @@ namespace Barotrauma
return (linkedTo[0] == hull1 ? linkedTo[1] : linkedTo[0]) as Hull;
}
public void ResetWaterFlowThisFrame()
{
waterFlowThisFrame = 0.0f;
}
private static readonly HashSet<Hull> checkedHulls = new HashSet<Hull>();
/// <summary>
@@ -758,10 +768,24 @@ namespace Barotrauma
const float decay = 0.95f;
maxFlow = Math.Min(maxFlow, gap.GetWaterFlowFromOutside(targetHull, deltaTime, ignoreCurrentWater: true)) * decay;
//if the hulls are not linked (i.e. not parts of the same room), limit the flow a bit
var sourceHull = gap.GetOtherLinkedHull(targetHull);
if (sourceHull != null && !sourceHull.linkedTo.Contains(targetHull))
{
maxFlow *= 0.5f;
}
//take the amount of water that has already passed through this gap into account
//(if there's multiple leaks to the outside recursively passing water through the same gap, the flow should not go above the maximum flow through this gap)
maxFlow -= gap.waterFlowThisFrame;
if (maxFlow <= 0.001f) { return; }
checkedHulls.Add(targetHull);
gap.waterFlowThisFrame += maxFlow;
//don't multiply by deltatime here, we already did that in GetWaterFlowFromOutside
targetHull.WaterVolume += maxFlow;
//lerp lethal pressure up very fast
@@ -401,7 +401,11 @@ namespace Barotrauma
private set;
}
private readonly HashSet<int> pendingSectionUpdates = new HashSet<int>();
/// <summary>
/// Note that sector != section: a sector is a group of <see cref="BackgroundSectionsPerNetworkEvent"/> sections that are updated together in a single network event.
/// </summary>
private readonly HashSet<int> pendingSectorUpdates = new HashSet<int>();
public int xBackgroundMax, yBackgroundMax;
@@ -413,8 +417,8 @@ namespace Barotrauma
}
}
private const int sectorWidth = 4;
private const int sectorHeight = 4;
private const int SectionWidth = 4;
private const int SectionHeight = 4;
private const float minColorStrength = 0.0f;
private const float maxColorStrength = 0.7f;
@@ -808,7 +812,7 @@ namespace Barotrauma
int start = sectorToUpdate * BackgroundSectionsPerNetworkEvent;
int end = Math.Min((sectorToUpdate + 1) * BackgroundSectionsPerNetworkEvent, BackgroundSections.Count - 1);
msg.WriteRangedInteger(sectorToUpdate, 0, BackgroundSections.Count - 1);
for (int i = start; i < end; i++)
for (int i = start; i <= end; i++)
{
msg.WriteRangedSingle(BackgroundSections[i].ColorStrength, 0.0f, 1.0f, 8);
msg.WriteUInt32(BackgroundSections[i].Color.PackedValue);
@@ -859,12 +863,12 @@ namespace Barotrauma
}
}
private void SharedBackgroundSectionRead(IReadMessage msg, Action<BackgroundSectionNetworkUpdate> action, out int sectorToUpdate)
private void SharedBackgroundSectionRead(IReadMessage msg, Action<BackgroundSectionNetworkUpdate> action, out int sectionToUpdate)
{
sectorToUpdate = msg.ReadRangedInteger(0, BackgroundSections.Count - 1);
int start = sectorToUpdate * BackgroundSectionsPerNetworkEvent;
int end = Math.Min((sectorToUpdate + 1) * BackgroundSectionsPerNetworkEvent, BackgroundSections.Count - 1);
for (int i = start; i < end; i++)
sectionToUpdate = msg.ReadRangedInteger(0, BackgroundSections.Count - 1);
int start = sectionToUpdate * BackgroundSectionsPerNetworkEvent;
int end = Math.Min((sectionToUpdate + 1) * BackgroundSectionsPerNetworkEvent, BackgroundSections.Count - 1);
for (int i = start; i <= end; i++)
{
float colorStrength = msg.ReadRangedSingle(0.0f, 1.0f, 8);
Color color = new Color(msg.ReadUInt32());
@@ -1460,14 +1464,14 @@ namespace Barotrauma
BackgroundSections = new List<BackgroundSection>(xBackgroundMax * yBackgroundMax);
int sections = xBackgroundMax * yBackgroundMax;
float xSectors = xBackgroundMax / (float)sectorWidth;
float xSectors = xBackgroundMax / (float)SectionWidth;
for (int y = 0; y < yBackgroundMax; y++)
{
for (int x = 0; x < xBackgroundMax; x++)
{
ushort index = (ushort)BackgroundSections.Count;
int sector = (int)Math.Floor(index / (float)sectorWidth - xSectors * y) + y / sectorHeight * (int)Math.Ceiling(xSectors);
int sector = (int)Math.Floor(index / (float)SectionWidth - xSectors * y) + y / SectionHeight * (int)Math.Ceiling(xSectors);
BackgroundSections.Add(new BackgroundSection(new Rectangle(x * sectionWidth, y * -sectionHeight, sectionWidth, sectionHeight), index, (ushort)y));
}
}
@@ -1504,6 +1508,12 @@ namespace Barotrauma
return BackgroundSections[xIndex + yIndex * xBackgroundMax];
}
public Vector2 GetBackgroundSectionWorldPos(BackgroundSection backgroundSection)
{
Vector2 subOffset = Submarine == null ? Vector2.Zero : Submarine.Position;
return Rect.Location.ToVector2() + subOffset + new Vector2(backgroundSection.Rect.X, backgroundSection.Rect.Y);
}
public IEnumerable<BackgroundSection> GetBackgroundSectionsViaContaining(Rectangle rectArea)
{
if (BackgroundSections == null || BackgroundSections.Count == 0)
@@ -1573,7 +1583,7 @@ namespace Barotrauma
if (sectionUpdated && GameMain.NetworkMember != null && requiresUpdate)
{
networkUpdatePending = true;
pendingSectionUpdates.Add((int)Math.Floor(section.Index / (float)BackgroundSectionsPerNetworkEvent));
pendingSectorUpdates.Add((int)Math.Floor(section.Index / (float)BackgroundSectionsPerNetworkEvent));
#if CLIENT
serverUpdateDelay = 0.5f;
#endif
@@ -654,6 +654,10 @@ namespace Barotrauma
structure.Update(deltaTime, cam);
}
foreach (Gap gap in Gap.GapList)
{
gap.ResetWaterFlowThisFrame();
}
//update gaps in random order, because otherwise in rooms with multiple gaps
//the water/air will always tend to flow through the first gap in the list,
//which may lead to weird behavior like water draining down only through
@@ -1,4 +1,4 @@
#nullable enable
#nullable enable
using System;
using System.Collections.Generic;
@@ -99,7 +99,7 @@ namespace Barotrauma
{
if (inc.BitPosition >= inc.LengthBits)
{
throw new Exception("Failed to find the end of the bit field: end of the message reached.");
throw new NetStructReadException("Failed to find the end of the bit field: end of the message reached.");
}
currentByte = inc.ReadByte();
bytes.Add(currentByte);
@@ -1,5 +1,4 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
@@ -13,6 +12,11 @@ using Microsoft.Xna.Framework;
namespace Barotrauma
{
public class NetStructReadException : Exception
{
public NetStructReadException(string message, Exception? innerException = null) : base(message, innerException) { }
}
/// <summary>
/// Marks fields and properties as to be serialized and deserialized by <see cref="INetSerializableStruct"/>.
/// Also contains settings for some types like maximum and minimum values for numbers to reduce bits used.
@@ -730,8 +734,15 @@ namespace Barotrauma
/// <returns>A new struct of type T with fields and properties deserialized</returns>
public static T Read<T>(IReadMessage inc) where T : INetSerializableStruct
{
ReadOnlyBitField bitField = new ReadOnlyBitField(inc);
return ReadInternal<T>(inc, bitField);
try
{
ReadOnlyBitField bitField = new ReadOnlyBitField(inc);
return ReadInternal<T>(inc, bitField);
}
catch (Exception e)
{
throw new NetStructReadException($"Failed to read {nameof(INetSerializableStruct)}", e);
}
}
public static T ReadInternal<T>(IReadMessage inc, ReadOnlyBitField bitField) where T : INetSerializableStruct
@@ -749,7 +760,7 @@ namespace Barotrauma
}
catch (Exception exception)
{
throw new Exception($"Failed to assign" +
throw new NetStructReadException($"Failed to assign" +
$" {value ?? "[NULL]"} ({value?.GetType().Name ?? "[NULL]"})" +
$" to {typeof(T).Name}.{property.Name} ({property.Type.Name})", exception);
}
@@ -648,6 +648,17 @@ namespace Barotrauma.Networking
private set;
}
/// <summary>
/// Does the server allow interacting with NPCs that offer services (e.g. stores) remotely?
/// Can be enabled if you're using mods that allow remote interactions - disabled by default to prevent modified clients from cheating.
/// </summary>
[Serialize(false, IsPropertySaveable.Yes)]
public bool AllowRemoteCampaignInteractions
{
get;
private set;
} = false;
private bool voiceChatEnabled;
[Serialize(true, IsPropertySaveable.Yes)]
public bool VoiceChatEnabled
+10
View File
@@ -1,4 +1,14 @@
-------------------------------------------------------------------------------------------------------------------------------------------------
v1.10.6.0
-------------------------------------------------------------------------------------------------------------------------------------------------
- Fixed contextual orders no longer working even if you were within radio/speaking range of a bot.
- Fixes to several multiplayer exploits, including one that allowed clients to cause server-side lag by sending specifically crafted messages to the server, even if the server didn't allow them to join.
- Fixed a bug caused by the water flow changes in the previous update: water flow through gaps in inside the submarine was much faster than intended when there were multiple breaches on the submarine's outer hull.
- Reduced the water flow through gaps when the hulls on are not linked. Linked hulls are intended to behave as if they were one room, and should allow unrestricted water flow.
- Railgun shells now disappear shortly after the first impact: the change in the previous update (which allowed them to penetrate multiple limbs/targets) had the side-effect that a shell that went through a single limb could fall back on the submarine and still do full damage.
-------------------------------------------------------------------------------------------------------------------------------------------------
v1.10.5.0
-------------------------------------------------------------------------------------------------------------------------------------------------