Unstable 0.1500.5.0 (almost forgor edition 💀)
This commit is contained in:
@@ -3,7 +3,6 @@ using FarseerPhysics;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
@@ -54,6 +53,27 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(true, false, description: "Should the rope snap when the character drops the aim?")]
|
||||
public bool SnapWhenNotAimed
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(30.0f, false, description: "How much mass is required for the target to pull the source towards it. Static and kinematic targets are always treated heavy enough.")]
|
||||
public float TargetMinMass
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(false, false)]
|
||||
public bool LerpForces
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
private bool snapped;
|
||||
public bool Snapped
|
||||
{
|
||||
@@ -85,6 +105,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
partial void InitProjSpecific(XElement element);
|
||||
|
||||
public void Snap() => Snapped = true;
|
||||
|
||||
public void Attach(ISpatialEntity source, Item target)
|
||||
{
|
||||
@@ -118,14 +139,15 @@ namespace Barotrauma.Items.Components
|
||||
Vector2 diff = target.WorldPosition - source.WorldPosition;
|
||||
if (diff.LengthSquared() > MaxLength * MaxLength)
|
||||
{
|
||||
Snapped = true;
|
||||
Snap();
|
||||
return;
|
||||
}
|
||||
|
||||
#if CLIENT
|
||||
item.ResetCachedVisibleSize();
|
||||
#endif
|
||||
|
||||
var projectile = target.GetComponent<Projectile>();
|
||||
if (projectile == null) { return; }
|
||||
if (SnapOnCollision)
|
||||
{
|
||||
raycastTimer += deltaTime;
|
||||
@@ -135,28 +157,24 @@ namespace Barotrauma.Items.Components
|
||||
collisionCategory: Physics.CollisionLevel | Physics.CollisionWall,
|
||||
customPredicate: (Fixture f) =>
|
||||
{
|
||||
var projectile = target?.GetComponent<Projectile>();
|
||||
if (projectile != null)
|
||||
foreach (Body body in projectile.Hits)
|
||||
{
|
||||
foreach (Body body in projectile.Hits)
|
||||
Submarine alreadyHitSub = null;
|
||||
if (body.UserData is Structure hitStructure)
|
||||
{
|
||||
Submarine alreadyHitSub = null;
|
||||
if (body.UserData is Structure hitStructure)
|
||||
{
|
||||
alreadyHitSub = hitStructure.Submarine;
|
||||
}
|
||||
else if (body.UserData is Submarine hitSub)
|
||||
{
|
||||
alreadyHitSub = hitSub;
|
||||
}
|
||||
if (alreadyHitSub != null)
|
||||
{
|
||||
if (f.Body?.UserData is MapEntity me && me.Submarine == alreadyHitSub) { return false; }
|
||||
if (f.Body?.UserData as Submarine == alreadyHitSub) { return false; }
|
||||
}
|
||||
alreadyHitSub = hitStructure.Submarine;
|
||||
}
|
||||
else if (body.UserData is Submarine hitSub)
|
||||
{
|
||||
alreadyHitSub = hitSub;
|
||||
}
|
||||
if (alreadyHitSub != null)
|
||||
{
|
||||
if (f.Body?.UserData is MapEntity me && me.Submarine == alreadyHitSub) { return false; }
|
||||
if (f.Body?.UserData as Submarine == alreadyHitSub) { return false; }
|
||||
}
|
||||
}
|
||||
Submarine targetSub = target?.GetComponent<Projectile>()?.StickTarget?.UserData as Submarine ?? target.Submarine;
|
||||
Submarine targetSub = projectile.StickTarget?.UserData as Submarine ?? target.Submarine;
|
||||
|
||||
if (f.Body?.UserData is MapEntity mapEntity && mapEntity.Submarine != null)
|
||||
{
|
||||
@@ -175,7 +193,7 @@ namespace Barotrauma.Items.Components
|
||||
return true;
|
||||
}) != null)
|
||||
{
|
||||
Snapped = true;
|
||||
Snap();
|
||||
return;
|
||||
}
|
||||
raycastTimer = 0.0f;
|
||||
@@ -183,27 +201,107 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
Vector2 forceDir = diff;
|
||||
if (forceDir.LengthSquared() > 0.01f)
|
||||
float distance = diff.Length();
|
||||
if (distance > 0.001f)
|
||||
{
|
||||
forceDir = Vector2.Normalize(forceDir);
|
||||
}
|
||||
|
||||
if (Math.Abs(ProjectilePullForce) > 0.001f)
|
||||
{
|
||||
var projectile = target.GetComponent<Projectile>();
|
||||
projectile?.Item?.body?.ApplyForce(-forceDir * ProjectilePullForce);
|
||||
projectile.Item?.body?.ApplyForce(-forceDir * ProjectilePullForce);
|
||||
}
|
||||
|
||||
if (Math.Abs(SourcePullForce) > 0.001f)
|
||||
if (projectile.StickTarget != null)
|
||||
{
|
||||
var sourceBody = GetBodyToPull(source);
|
||||
sourceBody?.ApplyForce(forceDir * SourcePullForce);
|
||||
}
|
||||
|
||||
if (Math.Abs(TargetPullForce) > 0.001f)
|
||||
{
|
||||
var targetBody = GetBodyToPull(target);
|
||||
targetBody?.ApplyForce(-forceDir * TargetPullForce);
|
||||
float targetMass = float.MaxValue;
|
||||
Character targetCharacter = null;
|
||||
if (projectile.StickTarget.UserData is Limb targetLimb)
|
||||
{
|
||||
targetCharacter = targetLimb.character;
|
||||
targetMass = targetLimb.ragdoll.Mass;
|
||||
}
|
||||
else if (projectile.StickTarget.UserData is Character character)
|
||||
{
|
||||
targetCharacter = character;
|
||||
targetMass = character.Mass;
|
||||
}
|
||||
else if (projectile.StickTarget.UserData is Item item)
|
||||
{
|
||||
targetMass = projectile.StickTarget.Mass;
|
||||
}
|
||||
if (projectile.StickTarget.BodyType != BodyType.Dynamic)
|
||||
{
|
||||
targetMass = float.MaxValue;
|
||||
}
|
||||
var user = item.GetComponent<Projectile>()?.User;
|
||||
if (targetMass > TargetMinMass)
|
||||
{
|
||||
if (Math.Abs(SourcePullForce) > 0.001f)
|
||||
{
|
||||
var sourceBody = GetBodyToPull(source);
|
||||
if (sourceBody != null)
|
||||
{
|
||||
var targetBody = GetBodyToPull(target);
|
||||
if (targetBody != null && !(targetBody.UserData is Character))
|
||||
{
|
||||
sourceBody.ApplyForce(targetBody.LinearVelocity * sourceBody.Mass);
|
||||
}
|
||||
float forceMultiplier = 1;
|
||||
if (user != null)
|
||||
{
|
||||
user.AnimController.Hang();
|
||||
if (user.InWater)
|
||||
{
|
||||
if (user.IsRagdolled)
|
||||
{
|
||||
forceMultiplier = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
forceMultiplier = user.IsRagdolled ? 0.1f : 0.4f;
|
||||
// Prevents too easy smashing to the walls
|
||||
forceDir.X /= 4;
|
||||
// Prevents rubberbanding up and down
|
||||
if (forceDir.Y < 0)
|
||||
{
|
||||
forceDir.Y = 0;
|
||||
}
|
||||
}
|
||||
if (targetCharacter != null)
|
||||
{
|
||||
var myCollider = user.AnimController.Collider;
|
||||
var targetCollider = targetCharacter.AnimController.Collider;
|
||||
if (myCollider.LinearVelocity != Vector2.Zero && targetCollider.LinearVelocity != Vector2.Zero)
|
||||
{
|
||||
if (Vector2.Dot(Vector2.Normalize(myCollider.LinearVelocity), Vector2.Normalize(targetCollider.LinearVelocity)) < 0)
|
||||
{
|
||||
myCollider.ApplyForce(targetCollider.LinearVelocity * targetCollider.Mass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
float force = LerpForces ? MathHelper.Lerp(0, SourcePullForce, MathUtils.InverseLerp(0, MaxLength / 2, distance)) * forceMultiplier : SourcePullForce * forceMultiplier;
|
||||
sourceBody.ApplyForce(forceDir * force);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Math.Abs(TargetPullForce) > 0.001f)
|
||||
{
|
||||
var targetBody = GetBodyToPull(target);
|
||||
if (user != null && targetCharacter != null && !user.AnimController.InWater)
|
||||
{
|
||||
// Prevents rubberbanding horizontally when dragging a corpse.
|
||||
if ((forceDir.X < 0) != (user.AnimController.Dir < 0))
|
||||
{
|
||||
forceDir.X = Math.Clamp(forceDir.X, -0.1f, 0.1f);
|
||||
}
|
||||
}
|
||||
float force = LerpForces ? MathHelper.Lerp(0, TargetPullForce, MathUtils.InverseLerp(0, MaxLength / 3, distance)) : TargetPullForce;
|
||||
targetBody?.ApplyForce(-forceDir * force);
|
||||
targetCharacter?.AnimController.Collider.ApplyForce(-forceDir * force * 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,19 +329,23 @@ namespace Barotrauma.Items.Components
|
||||
return ownerCharacter.AnimController.Collider;
|
||||
}
|
||||
var projectile = targetItem.GetComponent<Projectile>();
|
||||
if (projectile != null)
|
||||
if (projectile != null && projectile.StickTarget != null)
|
||||
{
|
||||
if (projectile.StickTarget?.UserData is Structure structure)
|
||||
if (projectile.StickTarget.UserData is Structure structure)
|
||||
{
|
||||
return structure.Submarine?.PhysicsBody;
|
||||
}
|
||||
else if (projectile.StickTarget?.UserData is Submarine sub)
|
||||
else if (projectile.StickTarget.UserData is Submarine sub)
|
||||
{
|
||||
return sub?.PhysicsBody;
|
||||
return sub.PhysicsBody;
|
||||
}
|
||||
else if (projectile.StickTarget?.UserData is Character character)
|
||||
else if (projectile.StickTarget.UserData is Item item)
|
||||
{
|
||||
return character.AnimController.Collider;
|
||||
return item.body;
|
||||
}
|
||||
else if (projectile.StickTarget.UserData is Limb limb)
|
||||
{
|
||||
return limb.body;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user