v1.0.21.0 (summer patch hotfix)

This commit is contained in:
Regalis11
2023-06-21 16:14:31 +03:00
parent f95be0511c
commit d6a886bf6b
29 changed files with 241 additions and 136 deletions

View File

@@ -201,9 +201,9 @@ namespace Barotrauma
keys[(int)InputType.Use].Held = useInput;
keys[(int)InputType.Use].SetState(false, useInput);
bool crouching = msg.ReadBoolean();
if (AnimController is HumanoidAnimController)
{
bool crouching = msg.ReadBoolean();
keys[(int)InputType.Crouch].Held = crouching;
keys[(int)InputType.Crouch].SetState(false, crouching);
}
@@ -269,7 +269,34 @@ namespace Barotrauma
if (readStatus)
{
ReadStatus(msg);
AIController?.ClientRead(msg);
bool isEnemyAi = msg.ReadBoolean();
if (isEnemyAi)
{
byte aiState = msg.ReadByte();
if (AIController is EnemyAIController enemyAi)
{
enemyAi.State = (AIState)aiState;
}
else
{
DebugConsole.AddWarning($"Received enemy AI data for a character with no {nameof(EnemyAIController)}. Ignoring...");
}
bool isPet = msg.ReadBoolean();
if (isPet)
{
byte happiness = msg.ReadByte();
byte hunger = msg.ReadByte();
if ((AIController as EnemyAIController)?.PetBehavior is PetBehavior petBehavior)
{
petBehavior.Happiness = (float)happiness / byte.MaxValue * petBehavior.MaxHappiness;
petBehavior.Hunger = (float)hunger / byte.MaxValue * petBehavior.MaxHunger;
}
else
{
DebugConsole.AddWarning($"Received pet AI data for a character with no {nameof(PetBehavior)}. Ignoring...");
}
}
}
}
msg.ReadPadBits();

View File

@@ -111,7 +111,7 @@ namespace Barotrauma
/// </summary>
public static float AspectRatioAdjustment => HorizontalAspectRatio < 1.4f ? (1.0f - (1.4f - HorizontalAspectRatio)) : 1.0f;
public static bool IsUltrawide => HorizontalAspectRatio > 2.0f;
public static bool IsUltrawide => HorizontalAspectRatio > 2.3f;
public static int UIWidth
{
@@ -2438,13 +2438,15 @@ namespace Barotrauma
var pauseMenuInner = new GUIFrame(new RectTransform(new Vector2(0.13f, 0.3f), PauseMenu.RectTransform, Anchor.Center) { MinSize = new Point(250, 300) });
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.7f, 0.6f), pauseMenuInner.RectTransform, Anchor.Center))
float padding = 0.06f;
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.7f, 0.8f), pauseMenuInner.RectTransform, Anchor.BottomCenter) { RelativeOffset = new Vector2(0.0f, padding) })
{
Stretch = true,
RelativeSpacing = 0.05f
};
new GUIButton(new RectTransform(new Vector2(0.1f, 0.1f), pauseMenuInner.RectTransform, Anchor.TopRight) { AbsoluteOffset = new Point((int)(15 * GUI.Scale)) },
new GUIButton(new RectTransform(new Vector2(0.1f, 0.07f), pauseMenuInner.RectTransform, Anchor.TopRight) { RelativeOffset = new Vector2(padding) },
"", style: "GUIBugButton")
{
IgnoreLayoutGroups = true,
@@ -2520,6 +2522,13 @@ namespace Barotrauma
}
GUITextBlock.AutoScaleAndNormalize(buttonContainer.Children.Where(c => c is GUIButton).Select(c => ((GUIButton)c).TextBlock));
//scale to ensure there's enough room for all the buttons
pauseMenuInner.RectTransform.MinSize = new Point(
pauseMenuInner.RectTransform.MinSize.X,
Math.Max(
(int)(buttonContainer.Children.Sum(c => c.Rect.Height + buttonContainer.Rect.Height * buttonContainer.RelativeSpacing)),
pauseMenuInner.RectTransform.MinSize.X));
}
void CreateButton(string textTag, GUIComponent parent, Action action, string verificationTextTag = null)

View File

@@ -160,8 +160,9 @@ namespace Barotrauma
int crewAreaY = ButtonAreaTop.Bottom + Padding;
int crewAreaHeight = ObjectiveAnchor.Top - Padding - crewAreaY;
float crewAreaWidthMultiplier = GUI.IsUltrawide ? GUI.HorizontalAspectRatio : 1.0f;
CrewArea = new Rectangle(Padding, crewAreaY, (int)(Math.Max(400 * GUI.Scale, 220) * crewAreaWidthMultiplier), crewAreaHeight);
CrewArea = new Rectangle(Padding, crewAreaY,
(int)MathHelper.Clamp(400 * GUI.Scale, 220, GameMain.GraphicsHeight * 0.4f),
crewAreaHeight);
InventoryAreaLower = new Rectangle(ChatBoxArea.Right + Padding * 7, inventoryTopY, GameMain.GraphicsWidth - Padding * 9 - ChatBoxArea.Width, GameMain.GraphicsHeight - inventoryTopY);
int healthWindowWidth = (int)(GameMain.GraphicsWidth * 0.5f);

View File

@@ -95,6 +95,7 @@ namespace Barotrauma
{
CanBeFocused = false
};
crewArea.RectTransform.NonScaledSize = HUDLayoutSettings.CrewArea.Size;
// AbsoluteOffset is set in UpdateProjectSpecific based on crewListOpenState
crewList = new GUIListBox(new RectTransform(Vector2.One, crewArea.RectTransform), style: null, isScrollBarOnDefaultSide: false)

View File

@@ -561,7 +561,7 @@ namespace Barotrauma.Lights
if (IsSegmentFacing(losVertices[0].Pos, losVertices[1].Pos, lightSourcePos))
{
Array.Reverse(ShadowVertices);
Array.Reverse(ShadowVertices, 0, ShadowVertexCount);
}
CalculateLosPenumbraVertices(lightSourcePos);

View File

@@ -482,7 +482,7 @@ namespace Barotrauma.Lights
{
foreach (MapEntity e in (Submarine.VisibleEntities ?? MapEntity.mapEntityList))
{
if (e is Item item && item.GetComponent<Wire>() is Wire wire)
if (e is Item item && !item.HiddenInGame && item.GetComponent<Wire>() is Wire wire)
{
wire.DebugDraw(spriteBatch, alpha: 0.4f);
}
@@ -719,6 +719,7 @@ namespace Barotrauma.Lights
{
foreach (var ch in convexHulls)
{
if (!ch.Enabled) { continue; }
Vector2 currentViewPos = pos;
Vector2 defaultViewPos = ViewTarget.DrawPosition;
if (ch.ParentEntity?.Submarine != null)
@@ -742,10 +743,13 @@ namespace Barotrauma.Lights
{
if (!convexHull.Enabled || !convexHull.Intersects(camView)) { continue; }
Vector2 relativeLightPos = pos;
if (convexHull.ParentEntity?.Submarine != null) { relativeLightPos -= convexHull.ParentEntity.Submarine.Position; }
Vector2 relativeViewPos = pos;
if (convexHull.ParentEntity?.Submarine != null)
{
relativeViewPos -= convexHull.ParentEntity.Submarine.DrawPosition;
}
convexHull.CalculateLosVertices(relativeLightPos);
convexHull.CalculateLosVertices(relativeViewPos);
for (int i = 0; i < convexHull.ShadowVertexCount; i++)
{

View File

@@ -206,6 +206,8 @@ namespace Barotrauma.Lights
private readonly List<ConvexHullList> convexHullsInRange;
private readonly HashSet<ConvexHull> visibleConvexHulls = new HashSet<ConvexHull>();
public Texture2D texture;
public SpriteEffects LightSpriteEffect;
@@ -717,6 +719,8 @@ namespace Barotrauma.Lights
public void RayCastTask(Vector2 drawPos, float rotation)
{
visibleConvexHulls.Clear();
Vector2 drawOffset = Vector2.Zero;
float boundsExtended = TextureRange;
if (OverrideLightTexture != null)
@@ -904,17 +908,12 @@ namespace Barotrauma.Lights
bool isPoint1 = MathUtils.LineToPointDistanceSquared(seg1.Start.WorldPos, seg1.End.WorldPos, p.WorldPos) < 25.0f;
bool isPoint2 = MathUtils.LineToPointDistanceSquared(seg2.Start.WorldPos, seg2.End.WorldPos, p.WorldPos) < 25.0f;
bool markAsVisible = false;
if (isPoint1 && isPoint2)
{
//hit at the current segmentpoint -> place the segmentpoint into the list
verts.Add(p.WorldPos);
foreach (ConvexHullList hullList in convexHullsInRange)
{
hullList.IsHidden.Remove(p.ConvexHull);
hullList.IsHidden.Remove(seg1.ConvexHull);
hullList.IsHidden.Remove(seg2.ConvexHull);
}
markAsVisible = true;
}
else if (intersection1.index != intersection2.index)
{
@@ -922,13 +921,13 @@ namespace Barotrauma.Lights
//we definitely want to generate new geometry here
verts.Add(isPoint1 ? p.WorldPos : intersection1.pos);
verts.Add(isPoint2 ? p.WorldPos : intersection2.pos);
foreach (ConvexHullList hullList in convexHullsInRange)
{
hullList.IsHidden.Remove(p.ConvexHull);
hullList.IsHidden.Remove(seg1.ConvexHull);
hullList.IsHidden.Remove(seg2.ConvexHull);
}
markAsVisible = true;
}
if (markAsVisible)
{
visibleConvexHulls.Add(p.ConvexHull);
visibleConvexHulls.Add(seg1.ConvexHull);
visibleConvexHulls.Add(seg2.ConvexHull);
}
//if neither of the conditions above are met, we just assume
//that the raycasts both resulted on the same segment
@@ -1396,6 +1395,14 @@ namespace Barotrauma.Lights
return;
}
foreach (var visibleConvexHull in visibleConvexHulls)
{
foreach (var convexHullList in convexHullsInRange)
{
convexHullList.IsHidden.Remove(visibleConvexHull);
}
}
CalculateLightVertices(verts);
LastRecalculationTime = (float)Timing.TotalTime;

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product>
<Version>1.0.20.1</Version>
<Version>1.0.21.0</Version>
<Copyright>Copyright © FakeFish 2018-2023</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>1.0.20.1</Version>
<Version>1.0.21.0</Version>
<Copyright>Copyright © FakeFish 2018-2023</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>1.0.20.1</Version>
<Version>1.0.21.0</Version>
<Copyright>Copyright © FakeFish 2018-2023</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>1.0.20.1</Version>
<Version>1.0.21.0</Version>
<Copyright>Copyright © FakeFish 2018-2023</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>1.0.20.1</Version>
<Version>1.0.21.0</Version>
<Copyright>Copyright © FakeFish 2018-2023</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName>

View File

@@ -376,10 +376,9 @@ namespace Barotrauma
tempBuffer.WriteBoolean(aiming);
tempBuffer.WriteBoolean(shoot);
tempBuffer.WriteBoolean(use);
if (AnimController is HumanoidAnimController)
{
tempBuffer.WriteBoolean(((HumanoidAnimController)AnimController).Crouching);
}
tempBuffer.WriteBoolean(AnimController is HumanoidAnimController { Crouching: true });
tempBuffer.WriteBoolean(attack);
Vector2 relativeCursorPos = cursorPosition - AimRefPosition;
@@ -430,7 +429,17 @@ namespace Barotrauma
if (writeStatus)
{
WriteStatus(tempBuffer);
AIController?.ServerWrite(tempBuffer);
tempBuffer.WriteBoolean(AIController is EnemyAIController);
if (AIController is EnemyAIController enemyAi)
{
tempBuffer.WriteByte((byte)enemyAi.State);
tempBuffer.WriteBoolean(enemyAi.PetBehavior is PetBehavior);
if (enemyAi.PetBehavior is PetBehavior petBehavior)
{
tempBuffer.WriteByte((byte)((petBehavior.Happiness / petBehavior.MaxHappiness) * byte.MaxValue));
tempBuffer.WriteByte((byte)((petBehavior.Hunger / petBehavior.MaxHunger) * byte.MaxValue));
}
}
HealthUpdatePending = false;
}
}

View File

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

View File

@@ -521,8 +521,5 @@ namespace Barotrauma
protected virtual void OnStateChanged(AIState from, AIState to) { }
protected virtual void OnTargetChanged(AITarget previousTarget, AITarget newTarget) { }
public virtual void ClientRead(IReadMessage msg) { }
public virtual void ServerWrite(IWriteMessage msg) { }
}
}

View File

@@ -4055,18 +4055,6 @@ namespace Barotrauma
}
return null;
}
public override void ServerWrite(IWriteMessage msg)
{
msg.WriteByte((byte)State);
PetBehavior?.ServerWrite(msg);
}
public override void ClientRead(IReadMessage msg)
{
State = (AIState)msg.ReadByte();
PetBehavior?.ClientRead(msg);
}
}
//the "memory" of the Character

View File

@@ -200,7 +200,8 @@ namespace Barotrauma
Leak.linkedTo.Any(e => e is Hull h && (character.CurrentHull == h || h.linkedTo.Contains(character.CurrentHull))),
endNodeFilter = IsSuitableEndNode,
// The Go To objective can be abandoned if the leak is fixed (in which case we don't want to use the dialogue)
SpeakCannotReachCondition = () => !CheckObjectiveSpecific()
// Only report about contextual targets.
SpeakCannotReachCondition = () => isPriority && !CheckObjectiveSpecific()
},
onAbandon: () =>
{

View File

@@ -223,23 +223,30 @@ namespace Barotrauma
Hull targetHull = GetTargetHull();
if (!IsFollowOrder)
{
// Abandon if going through unsafe paths or targeting unsafe hulls.
bool isUnreachable = HumanAIController.UnreachableHulls.Contains(targetHull);
if (!objectiveManager.CurrentObjective.IgnoreUnsafeHulls)
{
if (HumanAIController.UnsafeHulls.Contains(targetHull))
// Wait orders check this so that the bot temporarily leaves the unsafe hull.
// Non-orders (that are not set to ignore the unsafe hulls) abandon. In practice this means e.g. repair and clean up item subobjectives (of the looping parent objective).
// Other orders are only abandoned if the hull is unreachable, because the path is invalid or not found at all.
if (IsWaitOrder || !objectiveManager.HasOrders())
{
isUnreachable = true;
HumanAIController.AskToRecalculateHullSafety(targetHull);
}
else if (PathSteering?.CurrentPath != null)
{
foreach (WayPoint wp in PathSteering.CurrentPath.Nodes)
if (HumanAIController.UnsafeHulls.Contains(targetHull))
{
if (wp.CurrentHull == null) { continue; }
if (HumanAIController.UnsafeHulls.Contains(wp.CurrentHull))
isUnreachable = true;
HumanAIController.AskToRecalculateHullSafety(targetHull);
}
else if (PathSteering?.CurrentPath != null)
{
foreach (WayPoint wp in PathSteering.CurrentPath.Nodes)
{
isUnreachable = true;
HumanAIController.AskToRecalculateHullSafety(wp.CurrentHull);
if (wp.CurrentHull == null) { continue; }
if (HumanAIController.UnsafeHulls.Contains(wp.CurrentHull))
{
isUnreachable = true;
HumanAIController.AskToRecalculateHullSafety(wp.CurrentHull);
}
}
}
}

View File

@@ -222,7 +222,8 @@ namespace Barotrauma
{
var objective = new AIObjectiveGoTo(Item, character, objectiveManager)
{
TargetName = Item.Name
TargetName = Item.Name,
SpeakCannotReachCondition = () => isPriority
};
if (repairTool != null)
{

View File

@@ -287,7 +287,7 @@ namespace Barotrauma
if (affliction.Prefab == null) { throw new Exception("Affliction prefab was null"); }
float bestSuitability = 0.0f;
Item bestItem = null;
foreach (KeyValuePair<Identifier, float> treatmentSuitability in affliction.Prefab.TreatmentSuitability)
foreach (KeyValuePair<Identifier, float> treatmentSuitability in affliction.Prefab.TreatmentSuitabilities)
{
if (currentTreatmentSuitabilities.ContainsKey(treatmentSuitability.Key) &&
currentTreatmentSuitabilities[treatmentSuitability.Key] > bestSuitability)

View File

@@ -109,6 +109,7 @@ namespace Barotrauma
foreach (Affliction affliction in allAfflictions)
{
if (affliction.Prefab.IsBuff) { continue; }
if (!affliction.Prefab.HasTreatments) { continue; }
if (!ignoreTreatmentThreshold)
{
//other afflictions of the same type increase the "treatability"
@@ -116,7 +117,6 @@ namespace Barotrauma
float totalAfflictionStrength = character.CharacterHealth.GetTotalAdjustedAfflictionStrength(affliction);
if (totalAfflictionStrength < affliction.Prefab.TreatmentThreshold) { continue; }
}
if (affliction.Prefab.TreatmentSuitability.None(kvp => kvp.Value > 0)) { continue; }
if (allAfflictions.Any(otherAffliction => affliction.Prefab.IgnoreTreatmentIfAfflictedBy.Contains(otherAffliction.Identifier))) { continue; }
yield return affliction;
}

View File

@@ -435,37 +435,34 @@ namespace Barotrauma
spawnPoint ??= WayPoint.WayPointList.Where(wp => wp.SpawnType == SpawnType.Human && wp.Submarine?.Info.Type == SubmarineType.Player).GetRandomUnsynced();
spawnPos = spawnPoint?.WorldPosition ?? Submarine.MainSub.WorldPosition;
}
var pet = Character.Create(speciesName, spawnPos, seed, spawnInitialItems: false);
var petBehavior = (pet?.AIController as EnemyAIController)?.PetBehavior;
if (petBehavior != null)
var characterPrefab = CharacterPrefab.FindBySpeciesName(speciesName.ToIdentifier());
if (characterPrefab == null)
{
petBehavior.Owner = owner;
var petBehaviorElement = subElement.Element("petbehavior");
if (petBehaviorElement != null)
DebugConsole.ThrowError($"Failed to load the pet \"{speciesName}\". Character prefab not found.");
continue;
}
var pet = Character.Create(characterPrefab, spawnPos, seed, spawnInitialItems: false);
if (pet != null)
{
var petBehavior = (pet.AIController as EnemyAIController)?.PetBehavior;
if (petBehavior != null)
{
petBehavior.Hunger = petBehaviorElement.GetAttributeFloat("hunger", 50.0f);
petBehavior.Happiness = petBehaviorElement.GetAttributeFloat("happiness", 50.0f);
petBehavior.Owner = owner;
var petBehaviorElement = subElement.Element("petbehavior");
if (petBehaviorElement != null)
{
petBehavior.Hunger = petBehaviorElement.GetAttributeFloat("hunger", 50.0f);
petBehavior.Happiness = petBehaviorElement.GetAttributeFloat("happiness", 50.0f);
}
}
}
var inventoryElement = subElement.Element("inventory");
if (inventoryElement != null)
{
pet.SpawnInventoryItems(pet.Inventory, inventoryElement.FromPackage(null));
}
}
}
}
public void ServerWrite(IWriteMessage msg)
{
msg.WriteRangedSingle(Happiness, 0.0f, MaxHappiness, 8);
msg.WriteRangedSingle(Hunger, 0.0f, MaxHunger, 8);
}
public void ClientRead(IReadMessage msg)
{
Happiness = msg.ReadRangedSingle(0.0f, MaxHappiness, 8);
Hunger = msg.ReadRangedSingle(0.0f, MaxHunger, 8);
}
}
}

View File

@@ -7,6 +7,7 @@ using System.Xml.Linq;
using Barotrauma.Extensions;
using System.Collections.Immutable;
using Barotrauma.Items.Components;
using System.Linq;
namespace Barotrauma
{
@@ -841,20 +842,16 @@ namespace Barotrauma
/// </summary>
public readonly Sprite AfflictionOverlay;
public IEnumerable<KeyValuePair<Identifier, float>> TreatmentSuitability
public ImmutableDictionary<Identifier, float> TreatmentSuitabilities
{
get
{
foreach (var itemPrefab in ItemPrefab.Prefabs)
{
float suitability = itemPrefab.GetTreatmentSuitability(Identifier) + itemPrefab.GetTreatmentSuitability(AfflictionType);
if (!MathUtils.NearlyEqual(suitability, 0.0f))
{
yield return new KeyValuePair<Identifier, float>(itemPrefab.Identifier, suitability);
}
}
}
}
get;
private set;
} = new Dictionary<Identifier, float>().ToImmutableDictionary();
/// <summary>
/// Can this affliction be treated with some item?
/// </summary>
public bool HasTreatments { get; private set; }
public AfflictionPrefab(ContentXElement element, AfflictionsFile file, Type type) : base(file, element.GetAttributeIdentifier("identifier", ""))
{
@@ -974,6 +971,22 @@ namespace Barotrauma
constructor = type.GetConstructor(new[] { typeof(AfflictionPrefab), typeof(float) });
}
private void RefreshTreatmentSuitabilities()
{
var newTreatmentSuitabilities = new Dictionary<Identifier, float>();
foreach (var itemPrefab in ItemPrefab.Prefabs)
{
float suitability = itemPrefab.GetTreatmentSuitability(Identifier) + itemPrefab.GetTreatmentSuitability(AfflictionType);
if (!MathUtils.NearlyEqual(suitability, 0.0f))
{
newTreatmentSuitabilities.TryAdd(itemPrefab.Identifier, suitability);
}
}
HasTreatments = newTreatmentSuitabilities.Any(kvp => kvp.Value > 0);
TreatmentSuitabilities = newTreatmentSuitabilities.ToImmutableDictionary();
}
public LocalizedString GetDescription(float strength, Description.TargetType targetType)
{
foreach (var description in Descriptions)
@@ -993,9 +1006,16 @@ namespace Barotrauma
return defaultDescription;
}
public static void LoadAllEffects()
/// <summary>
/// Should be called before each round: loads all StatusEffects and refreshes treatment suitabilities.
/// </summary>
public static void LoadAllEffectsAndTreatmentSuitabilities()
{
Prefabs.ForEach(p => p.LoadEffects());
foreach (var prefab in Prefabs)
{
prefab.RefreshTreatmentSuitabilities();
prefab.LoadEffects();
}
}
public static void ClearAllEffects()
@@ -1003,7 +1023,7 @@ namespace Barotrauma
Prefabs.ForEach(p => p.ClearEffects());
}
public void LoadEffects()
private void LoadEffects()
{
ClearEffects();
foreach (var subElement in configElement.Elements())
@@ -1032,7 +1052,7 @@ namespace Barotrauma
}
}
public void ClearEffects()
private void ClearEffects()
{
effects.Clear();
periodicEffects.Clear();

View File

@@ -1136,7 +1136,7 @@ namespace Barotrauma
}
}
foreach (KeyValuePair<Identifier, float> treatment in affliction.Prefab.TreatmentSuitability)
foreach (KeyValuePair<Identifier, float> treatment in affliction.Prefab.TreatmentSuitabilities)
{
float suitability = treatment.Value * strength;
if (treatment.Value > strength)

View File

@@ -392,7 +392,7 @@ namespace Barotrauma
DateTime startTime = DateTime.Now;
#endif
RoundDuration = 0.0f;
AfflictionPrefab.LoadAllEffects();
AfflictionPrefab.LoadAllEffectsAndTreatmentSuitabilities();
MirrorLevel = mirrorLevel;
if (SubmarineInfo == null)

View File

@@ -135,7 +135,7 @@ namespace Barotrauma.Items.Components
private void CreateTriggerBody()
{
System.Diagnostics.Debug.Assert(trigger == null, "LevelResource trigger already created!");
var body = item.body ?? holdable.Body;
var body = item.body ?? holdable?.Body;
if (body != null && Attached)
{
trigger = new PhysicsBody(body.Width, body.Height, body.Radius,

View File

@@ -178,7 +178,7 @@ namespace Barotrauma
if (eventSet is null) { continue; }
int count = childElement.GetAttributeInt("count", 0);
if (count < 1) { continue; }
FinishedEvents.Add(eventSet, count);
FinishedEvents.TryAdd(eventSet, count);
}
static EventSet FindSetRecursive(EventSet parentSet, Identifier setIdentifier)
@@ -365,7 +365,7 @@ namespace Barotrauma
if (FinishedEvents.Any())
{
var finishedEventsElement = new XElement(nameof(FinishedEvents));
foreach (var (set, count) in FinishedEvents)
foreach (var (set, count) in FinishedEvents.DistinctBy(f => f.Key.Identifier))
{
var element = new XElement(nameof(FinishedEvents),
new XAttribute("set", set.Identifier),

View File

@@ -1353,44 +1353,38 @@ namespace Barotrauma
if (startWaypoint.WorldPosition.X > endWaypoint.WorldPosition.X)
{
var temp = startWaypoint;
startWaypoint = endWaypoint;
endWaypoint = temp;
(endWaypoint, startWaypoint) = (startWaypoint, endWaypoint);
}
if (hallwayLength > 100 && isHorizontal)
{
//if the hallway is longer than 100 pixels, generate some waypoints inside it
//for vertical hallways this isn't necessarily, it's done as a part of the ladder generation in AlignLadders
WayPoint prevWayPoint = startWaypoint;
WayPoint firstWayPoint = null;
for (float x = leftHull.Rect.Right + 50; x < rightHull.Rect.X - 50; x += 100.0f)
{
var newWayPoint = new WayPoint(new Vector2(x, hullBounds.Y + 110.0f), SpawnType.Path, sub);
firstWayPoint ??= newWayPoint;
prevWayPoint.linkedTo.Add(newWayPoint);
newWayPoint.linkedTo.Add(prevWayPoint);
prevWayPoint = newWayPoint;
}
if (firstWayPoint != null)
{
firstWayPoint.linkedTo.Add(startWaypoint);
startWaypoint.linkedTo.Add(firstWayPoint);
}
if (prevWayPoint != null)
{
prevWayPoint.linkedTo.Add(endWaypoint);
endWaypoint.linkedTo.Add(prevWayPoint);
}
}
WayPoint closestWaypoint = null;
float closestDistSqr = 30.0f * 30.0f;
foreach (WayPoint waypoint in WayPoint.WayPointList)
else
{
if (waypoint == startWaypoint) { continue; }
float dist = Vector2.DistanceSquared(waypoint.WorldPosition, startWaypoint.WorldPosition);
if (dist < closestDistSqr)
{
closestWaypoint = waypoint;
closestDistSqr = dist;
}
}
if (closestWaypoint != null)
{
startWaypoint.linkedTo.Add(closestWaypoint);
closestWaypoint.linkedTo.Add(startWaypoint);
startWaypoint.linkedTo.Add(endWaypoint);
endWaypoint.linkedTo.Add(startWaypoint);
}
}
}
@@ -1444,7 +1438,7 @@ namespace Barotrauma
{
foreach (MapEntity me in entities[module])
{
if (!(me is Gap gap)) { continue; }
if (me is not Gap gap) { continue; }
var door = gap.ConnectedDoor;
if (door != null && !door.UseBetweenOutpostModules) { continue; }
if (placedModules.Any(m => m.PreviousGap == gap || m.ThisGap == gap))
@@ -1524,15 +1518,38 @@ namespace Barotrauma
static void RemoveLinkedEntity(MapEntity linked)
{
if (linked is Item linkedItem && linkedItem.Connections != null)
if (linked is Item linkedItem)
{
foreach (Connection connection in linkedItem.Connections)
if (linkedItem.Connections != null)
{
foreach (Wire w in connection.Wires.ToArray())
foreach (Connection connection in linkedItem.Connections)
{
w?.Item.Remove();
foreach (Wire w in connection.Wires.ToArray())
{
w?.Item.Remove();
}
}
}
//if we end up removing a ladder, remove its waypoints too
if (linkedItem.GetComponent<Ladder>() is Ladder ladder)
{
var ladderWaypoints = WayPoint.WayPointList.FindAll(wp => wp.Ladders == ladder);
foreach (var ladderWaypoint in ladderWaypoints)
{
//got through all waypoints linked to the ladder waypoints, and link them together
//so we don't end up breaking up any paths by removing the ladder waypoints
for (int i = 0; i < ladderWaypoint.linkedTo.Count; i++)
{
if (ladderWaypoint.linkedTo[i] is not WayPoint waypoint1 || waypoint1.Ladders == ladder) { continue; }
for (int j = i + 1; j < ladderWaypoint.linkedTo.Count; j++)
{
if (ladderWaypoint.linkedTo[j] is not WayPoint waypoint2 || waypoint2.Ladders == ladder) { continue; }
waypoint1.ConnectTo(waypoint2);
}
}
}
ladderWaypoints.ForEach(wp => wp.Remove());
}
}
linked.Remove();
}

View File

@@ -1,3 +1,22 @@
---------------------------------------------------------------------------------------------------------
v1.0.21.0
---------------------------------------------------------------------------------------------------------
Fixes:
- Fixed LOS effect sometimes "lagging behind" when the sub is moving fast.
- Fixed some minor visual issues (occasional jitter/flickering) on the LOS effect.
- Fixed some issues in the bot AI that we're causing a large performance hit particularly in situations when there's lots of bots in a sub with leaks.
- Fixed bots abandoning their orders (such as operating a turret) if the room is unsafe (e.g. flooded).
- Fixed an issue in character syncing that occasionally caused disconnects with the error message "Exception thrown while reading segment EntityPosition, tried to read too much data from segment".
- Fixed wires set to be hidden in-game (e.g. invisible circuits built outside the sub) being visible on the Electrician's Goggles.
- Fixed an issue with level resources that caused crashes with certain mods (e.g. ones that include subs with piezo crystals).
- Fixed NPCs waiting on some outpost modules never reaching their targets, causing peculiar behavior.
- Fixed waypoints sometimes not getting connected between outpost modules if there's a very short hallway between them. Addresses some cities missing connections between waypoints, causing AI to be unable to navigate through the modules.
- Fixed some UI layout issues (most noticeably, ultra-wide crew list) on certain resolutions like 3440x1440.
- Fixed campaign saves occasionally failing to load with the error "an item with the same key has already been added". Seemed to only occur when using certain mods.
- Fixed crashing when you e.g. use a pet from some mod in the campaign, disable the mod and reload the save.
- Waypoint adjustments to most submarines, outposts, wrecks, and beacons. Especially on ladders. Should take care of the remaining AI issues on ladders (the old subs in the saves don't get updated, but the fixes apply to new subs that you don't yet own. And ofc all the subs in a new game!)
---------------------------------------------------------------------------------------------------------
v1.0.20.1
---------------------------------------------------------------------------------------------------------
@@ -5,7 +24,7 @@ v1.0.20.1
Fixes:
- Fixed hidden structures not colliding anymore.
- Wiring debugger: Fixed tooltip rendering under the outer frame of the connection panel.
- Wiring debugger: Fixed the glow sprite on connections having an inconsistent size in different resolutions-
- Wiring debugger: Fixed the glow sprite on connections having an inconsistent size in different resolutions.
- Fixed jailbreak_sootman event getting stuck at the 1st SpawnAction, preventing most of the event from working at all.
---------------------------------------------------------------------------------------------------------