Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Mnemotechnician committed Sep 12, 2024
1 parent fae94da commit 0935760
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 14 deletions.
10 changes: 8 additions & 2 deletions Content.Shared/Movement/Pulling/Components/PullerComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,16 @@ public sealed partial class PullerComponent : Component
public bool NeedsHands = true;

/// <summary>
/// The specific force of pushing, in newtons per kilogram. This is multiplied by the puller's physics mass.
/// The maximum acceleration of pushing, in meters per second squared.
/// </summary>
[DataField]
public float SpecificForce = 0.3f;
public float PushAcceleration = 0.3f;

/// <summary>
/// The maximum speed to which the pulled entity may be accelerated relative to the push direction, in meters per second.
/// </summary>
[DataField]
public float MaxPushSpeed = 1.2f;

/// <summary>
/// The maximum distance between the puller and the point towards which the puller may attempt to pull it, in meters.
Expand Down
30 changes: 19 additions & 11 deletions Content.Shared/Movement/Pulling/Systems/PullingSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public override void Update(float frameTime)
if (pullerComp.PushingTowards is null)
continue;

// If pushing but the target position is invalid, or the push action has expired, stop pushing
// If pushing but the target position is invalid, or the push action has expired or finished, stop pushing
if (pullerComp.NextPushStop < _timing.CurTime
|| !(pullerComp.PushingTowards.Value.ToMap(EntityManager, _xformSys) is var pushCoordinates)
|| pushCoordinates.MapId != pulledXForm.MapID)
Expand All @@ -122,20 +122,28 @@ public override void Update(float frameTime)
continue;
}

// Actual force calculation. All the Vector2's below are in map coordinates.
var desiredDeltaPos = pushCoordinates.Position - Transform(pulled).Coordinates.ToMapPos(EntityManager, _xformSys);
var desiredForce = pulledPhysics.Mass * desiredDeltaPos;
var maxSourceForce = pullerComp.SpecificForce * pullerPhysics.Mass;
var actualForce = desiredForce.LengthSquared() > maxSourceForce * maxSourceForce ? desiredDeltaPos.Normalized() * maxSourceForce : desiredForce;
if (desiredDeltaPos.LengthSquared() < 0.1f)
{
pullerComp.PushingTowards = null;
continue;
}

// Cannot use ApplyForce here because it will be cleared on the next physics substep which will render it ultimately useless
var velocityAndDirectionAngle = new Angle(pulledPhysics.LinearVelocity) - new Angle(desiredDeltaPos);
var currentRelativeSpeed = pulledPhysics.LinearVelocity.Length() * (float) Math.Cos(velocityAndDirectionAngle.Theta);
var desiredAcceleration = MathF.Max(0f, pullerComp.MaxPushSpeed - currentRelativeSpeed);

var desiredImpulse = pulledPhysics.Mass * desiredDeltaPos;
var maxSourceImpulse = MathF.Min(pullerComp.PushAcceleration, desiredAcceleration) * pullerPhysics.Mass;
var actualImpulse = desiredImpulse.LengthSquared() > maxSourceImpulse * maxSourceImpulse ? desiredDeltaPos.Normalized() * maxSourceImpulse : desiredImpulse;

// Ideally we'd want to apply forces instead of impulses, however...
// We cannot use ApplyForce here because it will be cleared on the next physics substep which will render it ultimately useless
// The alternative is to run this function on every physics substep, but that is way too expensive for such a minor system
_physics.ApplyLinearImpulse(pulled, actualForce);
_physics.ApplyLinearImpulse(puller, -actualForce);
_physics.ApplyLinearImpulse(pulled, actualImpulse);
_physics.ApplyLinearImpulse(puller, -actualImpulse);
pulledComp.BeingActivelyPushed = true;

// Means the pullee has been pushed close enough to the destination
if (actualForce == desiredForce)
pullerComp.PushingTowards = null;
}
query.Dispose();
}
Expand Down
2 changes: 1 addition & 1 deletion Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
- type: GhostHearing
- type: Hands
- type: Puller
specificForce: 1000
pushAcceleration: 1000000 # Will still be capped in max speed
maxPushRange: 20
- type: CombatMode
- type: Physics
Expand Down

0 comments on commit 0935760

Please sign in to comment.