v1.6.18.1 (Unto the Breach Hotfix 1)
This commit is contained in:
+3
-3
@@ -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
|
||||
{
|
||||
|
||||
+2
-3
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-4
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
-1
@@ -22,7 +22,6 @@ namespace Barotrauma.Abilities
|
||||
|
||||
foreach (Character character in Character.GetFriendlyCrew(Character))
|
||||
{
|
||||
if (character.Info is null) { return; }
|
||||
character.Info.AdditionalTalentPoints += amount;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user