v1.6.18.1 (Unto the Breach Hotfix 1)

This commit is contained in:
Regalis11
2024-10-28 15:03:46 +02:00
parent a29662c074
commit 7eac44ea7d
47 changed files with 246 additions and 124 deletions
@@ -74,7 +74,6 @@ namespace Barotrauma
private float pathBackTimer;
private const float DefaultCoolDown = 10.0f;
private const float PathBackCheckTime = 1.0f;
private IEnumerable<Body> myBodies;
private float aimTimer;
private float reloadTimer;
private float spreadTimer;
@@ -1375,9 +1374,10 @@ namespace Barotrauma
float aimFactor = MathHelper.PiOver2 * (1 - AimAccuracy);
if (VectorExtensions.Angle(VectorExtensions.Forward(Weapon.body.TransformedRotation), Enemy.WorldPosition - Weapon.WorldPosition) < MathHelper.PiOver4 + aimFactor)
{
myBodies ??= character.AnimController.Limbs.Select(l => l.body.FarseerBody);
// Check that we don't hit friendlies. No need to check the walls, because there's a separate check for that at 1096 (which intentionally has a small delay)
var pickedBodies = Submarine.PickBodies(Weapon.SimPosition, Submarine.GetRelativeSimPosition(from: Weapon, to: Enemy), myBodies, Physics.CollisionCharacter);
var pickedBodies = Submarine.PickBodies(Weapon.SimPosition, Submarine.GetRelativeSimPosition(from: Weapon, to: Enemy),
ignoredBodies: character.AnimController.LimbBodies,
Physics.CollisionCharacter);
foreach (var body in pickedBodies)
{
Character target = body.UserData switch
@@ -64,6 +64,9 @@ namespace Barotrauma
}
}
private readonly List<Body> limbBodies = new List<Body>();
public IEnumerable<Body> LimbBodies => limbBodies;
public bool HasMultipleLimbsOfSameType => limbs != null && limbs.Length > limbDictionary.Count;
private bool frozen;
@@ -524,6 +527,7 @@ namespace Barotrauma
protected void CreateLimbs()
{
limbBodies.Clear();
limbs?.ForEach(l => l.Remove());
Mass = 0;
DebugConsole.Log($"Creating limbs from {RagdollParams.Name}.");
@@ -618,6 +622,7 @@ namespace Barotrauma
{
throw new Exception($"Failed to add a limb to the character \"{Character?.ConfigPath ?? "null"}\" (limb index {ID} out of bounds). The ragdoll file may be configured incorrectly.");
}
limbBodies.Add(limb.body.FarseerBody);
Limbs[ID] = limb;
Mass += limb.Mass;
if (!limbDictionary.ContainsKey(limb.type)) { limbDictionary.Add(limb.type, limb); }
@@ -629,6 +634,7 @@ namespace Barotrauma
limb.body.FarseerBody.OnCollision += OnLimbCollision;
Array.Resize(ref limbs, Limbs.Length + 1);
Limbs[Limbs.Length - 1] = limb;
limbBodies.Add(limb.body.FarseerBody);
Mass += limb.Mass;
if (!limbDictionary.ContainsKey(limb.type)) { limbDictionary.Add(limb.type, limb); }
SetupDrawOrder();
@@ -636,14 +642,14 @@ namespace Barotrauma
public void RemoveLimb(Limb limb)
{
if (!Limbs.Contains(limb)) return;
if (!Limbs.Contains(limb)) { return; }
Limb[] newLimbs = new Limb[Limbs.Length - 1];
int i = 0;
foreach (Limb existingLimb in Limbs)
{
if (existingLimb == limb) continue;
if (existingLimb == limb) { continue; }
newLimbs[i] = existingLimb;
i++;
}
@@ -680,8 +686,11 @@ namespace Barotrauma
}
LimbJoints = newJoints;
}
limbBodies.Remove(limb.body.FarseerBody);
limb.Remove();
System.Diagnostics.Debug.Assert(!limbs.Contains(limb));
System.Diagnostics.Debug.Assert(limbs.None(l => l.Removed));
foreach (LimbJoint limbJoint in attachedJoints)
{
GameMain.World.Remove(limbJoint.Joint);
@@ -2243,6 +2252,7 @@ namespace Barotrauma
}
limbs = null;
}
limbBodies.Clear();
if (collider != null)
{
@@ -5709,13 +5709,17 @@ namespace Barotrauma
return sameRoomHulls.Contains(character.CurrentHull);
}
/// <summary>
/// Returns all friendly crew members that are alive.
/// Filters out pets and characters that don't have <see cref="CharacterInfo"/>.
/// </summary>
public static IEnumerable<Character> GetFriendlyCrew(Character character)
{
if (character is null)
{
return Enumerable.Empty<Character>();
}
return CharacterList.Where(c => HumanAIController.IsFriendly(character, c, onlySameTeam: true) && !c.IsDead);
return CharacterList.Where(c => c.Info != null && !c.IsDead && !c.IsPet && HumanAIController.IsFriendly(character, c, onlySameTeam: true));
}
public bool HasRecipeForItem(Identifier recipeIdentifier)
@@ -184,6 +184,13 @@ namespace Barotrauma
private set;
}
[Serialize(10, IsPropertySaveable.No, description: "Determines the order of the characters in the campaign setup ui.")]
public int CampaignSetupUIOrder
{
get;
private set;
}
[Serialize(false, IsPropertySaveable.No, description: "If set to true, a client that has chosen this as their preferred job will get it regardless of the maximum number or the amount of spawnpoints in the sub.")]
public bool AllowAlways
{
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Abilities
{
@@ -14,8 +13,8 @@ namespace Barotrauma.Abilities
protected override bool MatchesConditionSpecific()
{
IEnumerable<Character> crewmembers = Character.GetFriendlyCrew(character);
int differentCrewAmount = crewmembers.Select(c => c.Info?.Job?.Prefab.Identifier).Distinct().Count();
IEnumerable<Character> crewMembers = Character.GetFriendlyCrew(character);
int differentCrewAmount = crewMembers.Select(c => c.Info.Job?.Prefab.Identifier).Distinct().Count();
return differentCrewAmount >= amount;
}
}
@@ -1,6 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Linq;
namespace Barotrauma.Abilities
{
@@ -14,7 +12,7 @@ namespace Barotrauma.Abilities
protected override bool MatchesConditionSpecific()
{
return Character.GetFriendlyCrew(character).Where(c => c.Info != null && (c.Info.GetCurrentLevel() - character.Info.GetCurrentLevel() >= levelsBehind)).Any();
return Character.GetFriendlyCrew(character).Any(c => c.Info.GetCurrentLevel() - character.Info.GetCurrentLevel() >= levelsBehind);
}
}
}
@@ -28,7 +28,7 @@ namespace Barotrauma.Abilities
foreach (Character character in Character.GetFriendlyCrew(Character))
{
JobPrefab? characterJob = character.Info?.Job?.Prefab;
JobPrefab? characterJob = character.Info.Job?.Prefab;
if (characterJob is null) { continue; }
switch (characterJob.Identifier == apprenticeJob.Identifier)
@@ -30,7 +30,7 @@
foreach (Character otherCharacter in Character.GetFriendlyCrew(Character))
{
if (otherCharacter == Character) { continue; }
otherCharacter.Info?.IncreaseSkillLevel(identifier, abilitySkillGain.Value, gainedFromAbility: true);
otherCharacter.Info.IncreaseSkillLevel(identifier, abilitySkillGain.Value, gainedFromAbility: true);
}
}
else
@@ -75,7 +75,7 @@ namespace Barotrauma.Abilities
{
foreach (Character c in Character.GetFriendlyCrew(Character))
{
c?.Info?.ChangeSavedStatValue(statType, value, identifier, removeOnDeath, maxValue: maxValue, setValue: setValue);
c.Info.ChangeSavedStatValue(statType, value, identifier, removeOnDeath, maxValue: maxValue, setValue: setValue);
}
}
else
@@ -22,7 +22,6 @@ namespace Barotrauma.Abilities
foreach (Character character in Character.GetFriendlyCrew(Character))
{
if (character.Info is null) { return; }
character.Info.AdditionalTalentPoints += amount;
}
}
@@ -35,7 +35,7 @@ namespace Barotrauma.Abilities
GameAnalyticsManager.AddMoneyGainedEvent(moneyAmount, GameAnalyticsManager.MoneySource.Ability, CharacterTalent.Prefab.Identifier.Value);
foreach (Character character in Character.GetFriendlyCrew(Character))
{
character.Info?.GiveExperience(experienceAmount);
character.Info.GiveExperience(experienceAmount);
}
timesGiven++;
if (max > 0 && timesGiven >= max) { break; }
@@ -168,7 +168,7 @@ namespace Barotrauma
logError: false);
}
humanPrefab ??= NPCSet.Get(NPCSetIdentifier, NPCIdentifier, logError: true);
humanPrefab ??= NPCSet.Get(NPCSetIdentifier, NPCIdentifier, logError: true, contentPackageToLogInError: ParentEvent.Prefab.ContentPackage);
if (humanPrefab != null)
{
@@ -568,7 +568,7 @@ namespace Barotrauma
Identifier characterIdentifier = element.GetAttributeIdentifier("identifier", Identifier.Empty);
Identifier characterFrom = element.GetAttributeIdentifier("from", Identifier.Empty);
HumanPrefab humanPrefab = NPCSet.Get(characterFrom, characterIdentifier);
HumanPrefab humanPrefab = NPCSet.Get(characterFrom, characterIdentifier, contentPackageToLogInError: Prefab.ContentPackage);
if (humanPrefab == null)
{
DebugConsole.ThrowError($"Couldn't spawn character for mission: character prefab \"{characterIdentifier}\" not found in the NPC set \"{characterFrom}\".",
@@ -128,7 +128,7 @@ namespace Barotrauma
{
Identifier characterIdentifier = characterElement.GetAttributeIdentifier("identifier", Identifier.Empty);
Identifier characterFrom = characterElement.GetAttributeIdentifier("from", Identifier.Empty);
HumanPrefab humanPrefab = NPCSet.Get(characterFrom, characterIdentifier);
HumanPrefab humanPrefab = NPCSet.Get(characterFrom, characterIdentifier, contentPackageToLogInError: Prefab.ContentPackage);
if (humanPrefab == null)
{
DebugConsole.ThrowError($"Error in mission \"{prefab.Identifier}\". Character prefab \"{characterIdentifier}\" not found in the NPC set \"{characterFrom}\".",
@@ -234,7 +234,8 @@ namespace Barotrauma.Items.Components
base.Update(deltaTime, cam);
if (targetCharacter != null)
{
if (SetTaintedOnDeath && targetCharacter.IsDead && !tainted)
if (SetTaintedOnDeath && !tainted &&
targetCharacter.IsDead && targetCharacter.CauseOfDeath is not { Type: CauseOfDeathType.Disconnected })
{
SetTainted(true);
}
@@ -850,7 +850,8 @@ namespace Barotrauma.Items.Components
private bool CanAutoInteractWithContained(Item containedItem)
{
return AutoInteractWithContained && autoInteractWithContainedTags.Any(t => containedItem.HasTag(t));
return AutoInteractWithContained &&
(autoInteractWithContainedTags.None() || autoInteractWithContainedTags.Any(t => containedItem.HasTag(t)));
}
private void SetContainedActive(bool active)
@@ -210,7 +210,7 @@ namespace Barotrauma.Items.Components
{
if (!powerOnSoundPlayed && powerOnSound != null)
{
SoundPlayer.PlaySound(powerOnSound.Sound, item.WorldPosition, powerOnSound.Volume, powerOnSound.Range, hullGuess: item.CurrentHull, ignoreMuffling: powerOnSound.IgnoreMuffling, freqMult: powerOnSound.GetRandomFrequencyMultiplier());
SoundPlayer.PlaySound(powerOnSound, item.WorldPosition, hullGuess: item.CurrentHull);
powerOnSoundPlayed = true;
}
}
@@ -243,7 +243,16 @@ namespace Barotrauma.Items.Components
public void SetPhysicsBodyPosition(bool ignoreContacts = true)
{
if (PhysicsBody == null) { return; }
Vector2 offset = ConvertUnits.ToSimUnits(BodyOffset * item.Scale);
if (item.FlippedX)
{
offset.X = -offset.X;
}
if (item.FlippedY)
{
offset.Y = -offset.Y;
}
if (!MathUtils.NearlyEqual(item.RotationRad, 0))
{
Matrix transform = Matrix.CreateRotationZ(-item.RotationRad);
@@ -260,6 +269,15 @@ namespace Barotrauma.Items.Components
PhysicsBody.UpdateDrawPosition();
}
public override void FlipX(bool relativeToSub)
{
SetPhysicsBodyPosition();
}
public override void FlipY(bool relativeToSub)
{
SetPhysicsBodyPosition();
}
public override void OnMapLoaded()
{
base.OnMapLoaded();
@@ -15,7 +15,7 @@ namespace Barotrauma
Humans = element.Elements().Select(npcElement => new HumanPrefab(npcElement, file, Identifier)).ToImmutableArray();
}
public static HumanPrefab? Get(Identifier setIdentifier, Identifier npcidentifier, bool logError = true)
public static HumanPrefab? Get(Identifier setIdentifier, Identifier npcidentifier, bool logError = true, ContentPackage? contentPackageToLogInError = null)
{
HumanPrefab? prefab = Sets.Where(set => set.Identifier == setIdentifier).SelectMany(npcSet => npcSet.Humans.Where(npcSetHuman => npcSetHuman.Identifier == npcidentifier)).FirstOrDefault();
@@ -23,7 +23,7 @@ namespace Barotrauma
{
if (logError)
{
DebugConsole.ThrowError($"Could not find human prefab \"{npcidentifier}\" from \"{setIdentifier}\".");
DebugConsole.ThrowError($"Could not find human prefab \"{npcidentifier}\" from \"{setIdentifier}\".", contentPackage: contentPackageToLogInError);
}
return null;
}
@@ -196,36 +196,40 @@ namespace Barotrauma
private class Entry
{
private readonly HumanPrefab humanPrefab = null;
private readonly Identifier setIdentifier = Identifier.Empty;
private readonly Identifier npcIdentifier = Identifier.Empty;
public readonly Identifier SetIdentifier = Identifier.Empty;
public readonly Identifier NpcIdentifier = Identifier.Empty;
public readonly Identifier FactionIdentifier = Identifier.Empty;
public readonly ContentPackage ContentPackage;
public Entry(HumanPrefab humanPrefab, Identifier factionIdentifier)
public Entry(HumanPrefab humanPrefab, Identifier factionIdentifier, ContentPackage contentPackage)
{
this.humanPrefab = humanPrefab;
this.FactionIdentifier = factionIdentifier;
FactionIdentifier = factionIdentifier;
ContentPackage = contentPackage;
}
public Entry(Identifier setIdentifier, Identifier npcIdentifier, Identifier factionIdentifier)
public Entry(Identifier setIdentifier, Identifier npcIdentifier, Identifier factionIdentifier, ContentPackage contentPackage)
{
this.setIdentifier = setIdentifier;
this.npcIdentifier = npcIdentifier;
this.FactionIdentifier = factionIdentifier;
SetIdentifier = setIdentifier;
NpcIdentifier = npcIdentifier;
FactionIdentifier = factionIdentifier;
ContentPackage = contentPackage;
}
public HumanPrefab HumanPrefab
=> humanPrefab ?? NPCSet.Get(setIdentifier, npcIdentifier);
=> humanPrefab ?? NPCSet.Get(SetIdentifier, NpcIdentifier, contentPackageToLogInError: ContentPackage);
}
private readonly List<Entry> entries = new List<Entry>();
public void Add(HumanPrefab humanPrefab, Identifier factionIdentifier)
=> entries.Add(new Entry(humanPrefab, factionIdentifier));
public void Add(HumanPrefab humanPrefab, Identifier factionIdentifier, ContentPackage contentPackage)
=> entries.Add(new Entry(humanPrefab, factionIdentifier, contentPackage));
public void Add(Identifier setIdentifier, Identifier npcIdentifier, Identifier factionIdentifier)
=> entries.Add(new Entry(setIdentifier, npcIdentifier, factionIdentifier));
public void Add(Identifier setIdentifier, Identifier npcIdentifier, Identifier factionIdentifier, ContentPackage contentPackage)
=> entries.Add(new Entry(setIdentifier, npcIdentifier, factionIdentifier, contentPackage));
public IEnumerator<HumanPrefab> GetEnumerator()
{
@@ -244,7 +248,10 @@ namespace Barotrauma
{
if (entry.FactionIdentifier == Identifier.Empty || factions.Any(f => f.Identifier == entry.FactionIdentifier))
{
yield return entry.HumanPrefab;
if (entry.HumanPrefab != null)
{
yield return entry.HumanPrefab;
}
}
}
}
@@ -315,11 +322,11 @@ namespace Barotrauma
Identifier faction = npcElement.GetAttributeIdentifier("faction", Identifier.Empty);
if (from != Identifier.Empty)
{
newCollection.Add(from, npcElement.GetAttributeIdentifier("identifier", Identifier.Empty), faction);
newCollection.Add(from, npcElement.GetAttributeIdentifier("identifier", Identifier.Empty), faction, npcElement.ContentPackage);
}
else
{
newCollection.Add(new HumanPrefab(npcElement, file, npcSetIdentifier: from), faction);
newCollection.Add(new HumanPrefab(npcElement, file, npcSetIdentifier: from), faction, npcElement.ContentPackage);
}
}
humanPrefabCollections.Add(newCollection);
+22
View File
@@ -1,4 +1,26 @@
-------------------------------------------------------------------------------------------------------------------------------------------------
v1.6.18.1
-------------------------------------------------------------------------------------------------------------------------------------------------
- Fixed several issues when the server rejects a name change due to a client trying to change their name too often: the server would start spamming the "can't change name" message, team and job preference selection would stop working too, and the game would crash when attempting to open the job preferences.
- Fixed equipped genes becoming tainted if you die due to disconnection.
- Fixed kill/death counters not working in the Sub vs. Sub PvP missions.
- Fixed gravity spheres not rotating in the sub editor.
- Fixed current generators not getting properly mirrored in ruins in mirrored levels.
- Fixed spawnpoints for escorted characters and prisoners not working.
- Fixed crashing if an AI character's husk infection is removed when they're using a ranged weapon.
- Fixed psychosis effect persisting if you leave the outpost midway through the "minds unraveled" event.
- Fixed night club merchants spawning in outposts without a night club.
- Fixed night club merchants not selling beer or rum (literally unplayable).
- Fixed bots cleaning up live grenades.
- Fixed server getting stuck in an infinite "restart loop" if autorestart or starting when everyone is ready is enabled and the selected perks are not suitable for the selected sub. The server would just attempt an immediate restart if the players wanted to cancel and reselect the perks.
- Fixed "All" option not working in the server browser's language filter dropdown.
- Fixed Raate Colony pvp map missing hulls near upper turrets.
Modding:
- Fixed outpost generation parameters that reference non-existent NPC prefabs causing a crash during outpost generation.
-------------------------------------------------------------------------------------------------------------------------------------------------
v1.6.17.0
-------------------------------------------------------------------------------------------------------------------------------------------------