Release 1.10.6.0 - Autumn Update 2025 Hotfix 1
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user