Blood in the Water Hotfix 2 - 1.4.6.0

This commit is contained in:
Markus Isberg
2024-05-02 14:08:04 +03:00
parent ff1b8951a7
commit 0a0a9784c5
26 changed files with 304 additions and 191 deletions
@@ -123,7 +123,7 @@ namespace Barotrauma
{
Abandon = true;
}
else if (item.ParentInventory != null)
else if (item.ParentInventory != null && item.GetRootInventoryOwner() != character)
{
if (!objectiveManager.HasOrder<AIObjectiveCleanupItems>())
{
@@ -368,7 +368,7 @@ namespace Barotrauma
return new AIObjectiveGoTo(moveToTarget, character, objectiveManager, repeat: false, getDivingGearIfNeeded: AllowToFindDivingGear, closeEnough: DefaultReach)
{
// If the root container changes, the item is no longer where it was (taken by someone -> need to find another item)
AbortCondition = obj => targetItem == null || targetItem.GetRootInventoryOwner() != moveToTarget,
AbortCondition = obj => targetItem == null || (targetItem.GetRootInventoryOwner() is Entity owner && owner != moveToTarget && owner != character),
SpeakIfFails = false,
endNodeFilter = CreateEndNodeFilter(moveToTarget)
};
@@ -272,6 +272,7 @@ namespace Barotrauma
CumulativeMonsterStrengthRuins = 0;
CumulativeMonsterStrengthWrecks = 0;
CumulativeMonsterStrengthCaves = 0;
distanceTraveled = 0;
}
public void ActivateEvent(Event newEvent)
@@ -726,14 +727,12 @@ namespace Barotrauma
private bool CanStartEventSet(EventSet eventSet)
{
ISpatialEntity refEntity = GetRefEntity();
float distFromStart = (float)Math.Sqrt(MathUtils.LineSegmentToPointDistanceSquared(level.StartExitPosition.ToPoint(), level.StartPosition.ToPoint(), refEntity.WorldPosition.ToPoint()));
float distFromEnd = (float)Math.Sqrt(MathUtils.LineSegmentToPointDistanceSquared(level.EndExitPosition.ToPoint(), level.EndPosition.ToPoint(), refEntity.WorldPosition.ToPoint()));
if (!eventSet.AllowAtStart)
{
if (distFromStart * Physics.DisplayToRealWorldRatio < 50.0f ||
distFromEnd * Physics.DisplayToRealWorldRatio < 50.0f)
ISpatialEntity refEntity = GetRefEntity();
float distFromStart = (float)Math.Sqrt(MathUtils.LineSegmentToPointDistanceSquared(level.StartExitPosition.ToPoint(), level.StartPosition.ToPoint(), refEntity.WorldPosition.ToPoint()));
float distFromEnd = (float)Math.Sqrt(MathUtils.LineSegmentToPointDistanceSquared(level.EndExitPosition.ToPoint(), level.EndPosition.ToPoint(), refEntity.WorldPosition.ToPoint()));
if (distFromStart * Physics.DisplayToRealWorldRatio < 50.0f || distFromEnd * Physics.DisplayToRealWorldRatio < 50.0f)
{
return false;
}
@@ -182,7 +182,6 @@ namespace Barotrauma.Items.Components
if (source == null || target == null || target.Removed ||
source is Entity { Removed: true } ||
source is Limb { Removed: true } ||
user is null ||
user is { Removed: true })
{
ResetSource();
@@ -312,82 +311,87 @@ namespace Barotrauma.Items.Components
{
targetMass = float.MaxValue;
}
if (!snapped)
// Currently can only apply pull forces to the source, when it's a character, not e.g. when the item would be auto-operated by an AI. Might have to change this.
if (user != null)
{
user.AnimController.HoldToRope();
if (targetCharacter != null)
if (!snapped)
{
targetCharacter.AnimController.DragWithRope();
}
if (user.InWater)
{
user.AnimController.HangWithRope();
}
}
if (Math.Abs(SourcePullForce) > 0.001f && targetMass > TargetMinMass)
{
// This should be the main collider.
var sourceBody = GetBodyToPull(source);
if (sourceBody != null)
{
isReelingIn = user.InWater && user.IsRagdolled || !user.InWater && targetCharacter is { IsIncapacitated: false };
if (isReelingIn)
user.AnimController.HoldToRope();
if (targetCharacter != null)
{
float pullForce = SourcePullForce;
if (!user.InWater)
targetCharacter.AnimController.DragWithRope();
}
if (user.InWater)
{
user.AnimController.HangWithRope();
}
}
if (Math.Abs(SourcePullForce) > 0.001f && targetMass > TargetMinMass)
{
// This should be the main collider.
var sourceBody = GetBodyToPull(source);
if (sourceBody != null)
{
isReelingIn = user.InWater && user.IsRagdolled || !user.InWater && targetCharacter is { IsIncapacitated: false };
if (isReelingIn)
{
// Apply a tiny amount to the character holding the rope, so that the connection "feels" more real.
pullForce *= 0.1f;
}
float lengthFactor = MathUtils.InverseLerp(0, MaxLength / 2, currentRopeLength);
float force = LerpForces ? MathHelper.Lerp(0, pullForce, lengthFactor) : pullForce;
sourceBody.ApplyForce(forceDir * force);
// Take the target velocity into account.
PhysicsBody targetBody = GetBodyToPull(target);
if (targetBody != null)
{
if (targetCharacter != null)
float pullForce = SourcePullForce;
if (!user.InWater)
{
if (targetBody.LinearVelocity != Vector2.Zero && sourceBody.LinearVelocity != Vector2.Zero)
// Apply a tiny amount to the character holding the rope, so that the connection "feels" more real.
pullForce *= 0.1f;
}
float lengthFactor = MathUtils.InverseLerp(0, MaxLength / 2, currentRopeLength);
float force = LerpForces ? MathHelper.Lerp(0, pullForce, lengthFactor) : pullForce;
sourceBody.ApplyForce(forceDir * force);
// Take the target velocity into account.
PhysicsBody targetBody = GetBodyToPull(target);
if (targetBody != null)
{
if (targetCharacter != null)
{
Vector2 targetDir = Vector2.Normalize(targetBody.LinearVelocity);
float movementDot = Vector2.Dot(Vector2.Normalize(sourceBody.LinearVelocity), targetDir);
if (movementDot < 0)
if (targetBody.LinearVelocity != Vector2.Zero && sourceBody.LinearVelocity != Vector2.Zero)
{
// Pushing to a different dir -> add some counter force
const float multiplier = 5;
float inverseLengthFactor = MathHelper.Lerp(1, 0, lengthFactor);
sourceBody.ApplyForce(targetBody.LinearVelocity * Math.Min(targetBody.Mass * multiplier, 250) * sourceBody.Mass * -movementDot * inverseLengthFactor);
}
float forceDot = Vector2.Dot(forceDir, targetDir);
if (forceDot > 0)
{
// Pulling to the same dir -> add extra force
float targetSpeed = targetBody.LinearVelocity.Length();
const float multiplier = 25;
sourceBody.ApplyForce(forceDir * targetSpeed * sourceBody.Mass * multiplier * forceDot * lengthFactor);
}
float colliderMainLimbDistance = Vector2.Distance(sourceBody.SimPosition, user.AnimController.MainLimb.SimPosition);
const float minDist = 1;
const float maxDist = 10;
if (colliderMainLimbDistance > minDist)
{
// Move the ragdoll closer to the collider, if it's too far (the correction force in HumanAnimController is not enough -> the ragdoll would lag behind and get teleported).
float correctionForce = MathHelper.Lerp(10.0f, NetConfig.MaxPhysicsBodyVelocity, MathUtils.InverseLerp(minDist, maxDist, colliderMainLimbDistance));
Vector2 targetPos = sourceBody.SimPosition + new Vector2((float)Math.Sin(-sourceBody.Rotation), (float)Math.Cos(-sourceBody.Rotation)) * 0.4f;
user.AnimController.MainLimb.MoveToPos(targetPos, correctionForce);
Vector2 targetDir = Vector2.Normalize(targetBody.LinearVelocity);
float movementDot = Vector2.Dot(Vector2.Normalize(sourceBody.LinearVelocity), targetDir);
if (movementDot < 0)
{
// Pushing to a different dir -> add some counter force
const float multiplier = 5;
float inverseLengthFactor = MathHelper.Lerp(1, 0, lengthFactor);
sourceBody.ApplyForce(targetBody.LinearVelocity * Math.Min(targetBody.Mass * multiplier, 250) * sourceBody.Mass * -movementDot * inverseLengthFactor);
}
float forceDot = Vector2.Dot(forceDir, targetDir);
if (forceDot > 0)
{
// Pulling to the same dir -> add extra force
float targetSpeed = targetBody.LinearVelocity.Length();
const float multiplier = 25;
sourceBody.ApplyForce(forceDir * targetSpeed * sourceBody.Mass * multiplier * forceDot * lengthFactor);
}
float colliderMainLimbDistance = Vector2.Distance(sourceBody.SimPosition, user.AnimController.MainLimb.SimPosition);
const float minDist = 1;
const float maxDist = 10;
if (colliderMainLimbDistance > minDist)
{
// Move the ragdoll closer to the collider, if it's too far (the correction force in HumanAnimController is not enough -> the ragdoll would lag behind and get teleported).
float correctionForce = MathHelper.Lerp(10.0f, NetConfig.MaxPhysicsBodyVelocity, MathUtils.InverseLerp(minDist, maxDist, colliderMainLimbDistance));
Vector2 targetPos = sourceBody.SimPosition + new Vector2((float)Math.Sin(-sourceBody.Rotation), (float)Math.Cos(-sourceBody.Rotation)) * 0.4f;
user.AnimController.MainLimb.MoveToPos(targetPos, correctionForce);
}
}
}
}
else
{
sourceBody.ApplyForce(targetBody.LinearVelocity * sourceBody.Mass);
else
{
sourceBody.ApplyForce(targetBody.LinearVelocity * sourceBody.Mass);
}
}
}
}
}
}
if (Math.Abs(TargetPullForce) > 0.001f && !user.IsRagdolled)
if (Math.Abs(TargetPullForce) > 0.001f && user is not { IsRagdolled: true})
{
PhysicsBody targetBody = GetBodyToPull(target);
if (targetBody == null) { return; }
@@ -3452,6 +3452,30 @@ namespace Barotrauma
}
}
/// <summary>
/// Returns this item and all the other items in the stack (either in the same inventory slot, or the same dropped stack).
/// </summary>
/// <returns></returns>
public IEnumerable<Item> GetStackedItems()
{
yield return this;
foreach (var stackedItem in DroppedStack)
{
if (stackedItem == this) { continue; }
yield return stackedItem;
}
if (ParentInventory != null)
{
int slotIndex = ParentInventory.FindIndex(this);
foreach (var stackedItem in ParentInventory.GetItemsAt(slotIndex))
{
if (stackedItem == this) { continue; }
yield return stackedItem;
}
}
}
public void Equip(Character character)
{
if (Removed)
@@ -348,6 +348,12 @@ namespace Barotrauma.Networking
if (serverMessageText == val) { return; }
#if SERVER
GameMain.Server?.SendChatMessage(TextManager.AddPunctuation(':', TextManager.Get("servermotd"), val).Value, ChatMessageType.Server);
#elif CLIENT
if (GameMain.NetLobbyScreen.ServerMessageButton is { } serverMessageButton)
{
serverMessageButton.Flash(GUIStyle.Green);
serverMessageButton.Pulsate(Vector2.One, Vector2.One * 1.2f, 1.0f);
}
#endif
serverMessageText = val;
ServerDetailsChanged = true;
@@ -1122,16 +1122,16 @@ namespace Barotrauma
{
if (!file.TryGet(out ContentPath _) || (file.TryGet(out ContentPath contentPath) && contentPath.IsNullOrWhiteSpace()))
{
DebugConsole.ThrowError($"Error in a <TriggerAnimation> element of {subElement.ParseContentPathFromUri()}: neither path nor filename defined!");
DebugConsole.ThrowError($"Error in a <TriggerAnimation> element of {subElement.ParseContentPathFromUri()}: neither path nor filename defined!",
contentPackage: subElement.ContentPackage);
break;
}
}
else
{
float priority = subElement.GetAttributeFloat("priority", def: 0f);
Identifier[] expectedSpeciesNames = subElement.GetAttributeIdentifierArray("expectedspecies", Array.Empty<Identifier>());
animationsToTrigger ??= new List<AnimLoadInfo>();
animationsToTrigger.Add(new AnimLoadInfo(animType, file, priority, expectedSpeciesNames.ToImmutableArray()));
}
float priority = subElement.GetAttributeFloat("priority", def: 0f);
Identifier[] expectedSpeciesNames = subElement.GetAttributeIdentifierArray("expectedspecies", Array.Empty<Identifier>());
animationsToTrigger ??= new List<AnimLoadInfo>();
animationsToTrigger.Add(new AnimLoadInfo(animType, file, priority, expectedSpeciesNames.ToImmutableArray()));
break;
}
}