Content update for ECS physics (#13291)

This commit is contained in:
metalgearsloth
2023-01-15 15:38:59 +11:00
committed by GitHub
parent 46d24bc36b
commit bf79d76666
61 changed files with 431 additions and 379 deletions

View File

@@ -78,6 +78,8 @@ namespace Content.Shared.Friction
foreach (var body in mapComponent.AwakeBodies)
{
var uid = body.Owner;
// Only apply friction when it's not a mob (or the mob doesn't have control)
if (prediction && !body.Predict ||
body.BodyStatus == BodyStatus.InAir ||
@@ -86,46 +88,45 @@ namespace Content.Shared.Friction
continue;
}
if (body.LinearVelocity.Equals(Vector2.Zero) && body.AngularVelocity.Equals(0f)) continue;
if (body.LinearVelocity.Equals(Vector2.Zero) && body.AngularVelocity.Equals(0f))
continue;
DebugTools.Assert(!Deleted(body.Owner));
if (!xformQuery.TryGetComponent(body.Owner, out var xform))
if (!xformQuery.TryGetComponent(uid, out var xform))
{
Logger.ErrorS("physics", $"Unable to get transform for {ToPrettyString(body.Owner)} in tilefrictioncontroller");
continue;
}
var surfaceFriction = GetTileFriction(body, xform);
var surfaceFriction = GetTileFriction(uid, body, xform);
var bodyModifier = 1f;
if (frictionQuery.TryGetComponent(body.Owner, out var frictionComp))
if (frictionQuery.TryGetComponent(uid, out var frictionComp))
{
bodyModifier = frictionComp.Modifier;
}
var ev = new TileFrictionEvent(bodyModifier);
RaiseLocalEvent(body.Owner, ref ev);
RaiseLocalEvent(uid, ref ev);
bodyModifier = ev.Modifier;
// If we're sandwiched between 2 pullers reduce friction
// Might be better to make this dynamic and check how many are in the pull chain?
// Either way should be much faster for now.
if (pullerQuery.TryGetComponent(body.Owner, out var puller) && puller.Pulling != null &&
pullableQuery.TryGetComponent(body.Owner, out var pullable) && pullable.BeingPulled)
if (pullerQuery.TryGetComponent(uid, out var puller) && puller.Pulling != null &&
pullableQuery.TryGetComponent(uid, out var pullable) && pullable.BeingPulled)
{
bodyModifier *= 0.2f;
}
var friction = _frictionModifier * surfaceFriction * bodyModifier;
ReduceLinearVelocity(prediction, body, friction, frameTime);
ReduceAngularVelocity(prediction, body, friction, frameTime);
ReduceLinearVelocity(uid, prediction, body, friction, frameTime);
ReduceAngularVelocity(uid, prediction, body, friction, frameTime);
}
}
private void ReduceLinearVelocity(bool prediction, PhysicsComponent body, float friction, float frameTime)
private void ReduceLinearVelocity(EntityUid uid, bool prediction, PhysicsComponent body, float friction, float frameTime)
{
var speed = body.LinearVelocity.Length;
@@ -153,10 +154,10 @@ namespace Content.Shared.Friction
var newSpeed = MathF.Max(0.0f, speed - drop);
newSpeed /= speed;
_physics.SetLinearVelocity(body, body.LinearVelocity * newSpeed);
_physics.SetLinearVelocity(uid, body.LinearVelocity * newSpeed, body: body);
}
private void ReduceAngularVelocity(bool prediction, PhysicsComponent body, float friction, float frameTime)
private void ReduceAngularVelocity(EntityUid uid, bool prediction, PhysicsComponent body, float friction, float frameTime)
{
var speed = MathF.Abs(body.AngularVelocity);
@@ -184,14 +185,14 @@ namespace Content.Shared.Friction
var newSpeed = MathF.Max(0.0f, speed - drop);
newSpeed /= speed;
_physics.SetAngularVelocity(body, body.AngularVelocity * newSpeed);
_physics.SetAngularVelocity(uid, body.AngularVelocity * newSpeed, body: body);
}
[Pure]
private float GetTileFriction(PhysicsComponent body, TransformComponent xform)
private float GetTileFriction(EntityUid uid, PhysicsComponent body, TransformComponent xform)
{
// TODO: Make IsWeightless event-based; we already have grid traversals tracked so just raise events
if (_gravity.IsWeightless(body.Owner, body, xform))
if (_gravity.IsWeightless(uid, body, xform))
return 0.0f;
if (!xform.Coordinates.IsValid(EntityManager)) return 0.0f;
@@ -201,7 +202,8 @@ namespace Content.Shared.Friction
var tile = grid.GetTileRef(xform.Coordinates);
// If it's a map but on an empty tile then just assume it has gravity.
if (tile.Tile.IsEmpty && HasComp<MapComponent>(xform.GridUid) &&
if (tile.Tile.IsEmpty &&
HasComp<MapComponent>(xform.GridUid) &&
(!TryComp<GravityComponent>(xform.GridUid, out var gravity) || gravity.Enabled))
{
return DefaultFriction;