Mobmover tweaks (#15942)

This commit is contained in:
metalgearsloth
2023-05-01 18:29:35 +10:00
committed by GitHub
parent d5b3585c09
commit ec9d31d9ab
5 changed files with 151 additions and 107 deletions

View File

@@ -108,10 +108,11 @@ namespace Content.Shared.Movement.Systems
float frameTime,
EntityQuery<TransformComponent> xformQuery,
EntityQuery<InputMoverComponent> moverQuery,
EntityQuery<MovementRelayTargetComponent> relayTargetQuery)
EntityQuery<MobMoverComponent> mobMoverQuery,
EntityQuery<MovementRelayTargetComponent> relayTargetQuery,
EntityQuery<SharedPullableComponent> pullableQuery,
EntityQuery<MovementSpeedModifierComponent> modifierQuery)
{
DebugTools.Assert(!UsedMobMovement.ContainsKey(uid));
bool canMove = mover.CanMove;
if (relayTargetQuery.TryGetComponent(uid, out var relayTarget) && relayTarget.Entities.Count > 0)
{
@@ -135,59 +136,11 @@ namespace Content.Shared.Movement.Systems
}
// Update relative movement
if (mover.LerpAccumulator > 0f)
if (mover.LerpTarget < Timing.CurTime)
{
Dirty(mover);
mover.LerpAccumulator -= frameTime;
if (mover.LerpAccumulator <= 0f)
if (TryUpdateRelative(mover, xform, xformQuery))
{
mover.LerpAccumulator = 0f;
var relative = xform.GridUid;
relative ??= xform.MapUid;
// So essentially what we want:
// 1. If we go from grid to map then preserve our rotation and continue as usual
// 2. If we go from grid -> grid then (after lerp time) snap to nearest cardinal (probably imperceptible)
// 3. If we go from map -> grid then (after lerp time) snap to nearest cardinal
if (!mover.RelativeEntity.Equals(relative))
{
// Okay need to get our old relative rotation with respect to our new relative rotation
// e.g. if we were right side up on our current grid need to get what that is on our new grid.
var currentRotation = Angle.Zero;
var targetRotation = Angle.Zero;
// Get our current relative rotation
if (xformQuery.TryGetComponent(mover.RelativeEntity, out var oldRelativeXform))
{
currentRotation = oldRelativeXform.WorldRotation + mover.RelativeRotation;
}
if (xformQuery.TryGetComponent(relative, out var relativeXform))
{
// This is our current rotation relative to our new parent.
mover.RelativeRotation = (currentRotation - relativeXform.WorldRotation).FlipPositive();
}
// If we went from grid -> map we'll preserve our worldrotation
if (relative != null && _mapManager.IsMap(relative.Value))
{
targetRotation = currentRotation.FlipPositive().Reduced();
}
// If we went from grid -> grid OR grid -> map then snap the target to cardinal and lerp there.
// OR just rotate to zero (depending on cvar)
else if (relative != null && _mapManager.IsGrid(relative.Value))
{
if (CameraRotationLocked)
targetRotation = Angle.Zero;
else
targetRotation = mover.RelativeRotation.GetCardinalDir().ToAngle().Reduced();
}
mover.RelativeEntity = relative;
mover.TargetRelativeRotation = targetRotation;
}
Dirty(mover);
}
}
@@ -223,7 +176,7 @@ namespace Content.Shared.Movement.Systems
if (!canMove
|| physicsComponent.BodyStatus != BodyStatus.OnGround
|| TryComp(uid, out SharedPullableComponent? pullable) && pullable.BeingPulled)
|| pullableQuery.TryGetComponent(uid, out var pullable) && pullable.BeingPulled)
{
UsedMobMovement[uid] = false;
return;
@@ -249,14 +202,14 @@ namespace Content.Shared.Movement.Systems
touching = ev.CanMove;
if (!touching && TryComp<MobMoverComponent>(uid, out var mobMover))
touching |= IsAroundCollider(PhysicsSystem, xform, mobMover, physicsComponent);
touching |= IsAroundCollider(PhysicsSystem, xform, mobMover, physicsUid, physicsComponent);
}
}
// Regular movement.
// Target velocity.
// This is relative to the map / grid we're on.
var moveSpeedComponent = CompOrNull<MovementSpeedModifierComponent>(uid);
var moveSpeedComponent = modifierQuery.CompOrNull(uid);
var walkSpeed = moveSpeedComponent?.CurrentWalkSpeed ?? MovementSpeedModifierComponent.DefaultBaseWalkSpeed;
var sprintSpeed = moveSpeedComponent?.CurrentSprintSpeed ?? MovementSpeedModifierComponent.DefaultBaseSprintSpeed;
@@ -308,8 +261,8 @@ namespace Content.Shared.Movement.Systems
// TODO apparently this results in a duplicate move event because "This should have its event run during
// island solver"??. So maybe SetRotation needs an argument to avoid raising an event?
if (!weightless && TryComp<MobMoverComponent>(mover.Owner, out var mobMover) &&
TryGetSound(weightless, mover, mobMover, xform, out var sound))
if (!weightless && mobMoverQuery.TryGetComponent(uid, out var mobMover) &&
TryGetSound(weightless, uid, mover, mobMover, xform, out var sound))
{
var soundModifier = mover.Sprinting ? 1.0f : FootstepWalkingAddedVolumeMultiplier;
@@ -347,7 +300,8 @@ namespace Content.Shared.Movement.Systems
{
var speed = velocity.Length;
if (speed < minimumFrictionSpeed) return;
if (speed < minimumFrictionSpeed)
return;
var drop = 0f;
@@ -356,7 +310,8 @@ namespace Content.Shared.Movement.Systems
var newSpeed = MathF.Max(0f, speed - drop);
if (newSpeed.Equals(speed)) return;
if (newSpeed.Equals(speed))
return;
newSpeed /= speed;
velocity *= newSpeed;
@@ -370,7 +325,8 @@ namespace Content.Shared.Movement.Systems
var currentSpeed = Vector2.Dot(currentVelocity, wishDir);
var addSpeed = wishSpeed - currentSpeed;
if (addSpeed <= 0f) return;
if (addSpeed <= 0f)
return;
var accelSpeed = accel * frameTime * wishSpeed;
accelSpeed = MathF.Min(accelSpeed, addSpeed);
@@ -386,9 +342,9 @@ namespace Content.Shared.Movement.Systems
/// <summary>
/// Used for weightlessness to determine if we are near a wall.
/// </summary>
private bool IsAroundCollider(SharedPhysicsSystem broadPhaseSystem, TransformComponent transform, MobMoverComponent mover, PhysicsComponent collider)
private bool IsAroundCollider(SharedPhysicsSystem broadPhaseSystem, TransformComponent transform, MobMoverComponent mover, EntityUid physicsUid, PhysicsComponent collider)
{
var enlargedAABB = _lookup.GetWorldAABB(collider.Owner, transform).Enlarged(mover.GrabRangeVV);
var enlargedAABB = _lookup.GetWorldAABB(physicsUid, transform).Enlarged(mover.GrabRangeVV);
foreach (var otherCollider in broadPhaseSystem.GetCollidingEntities(transform.MapID, enlargedAABB))
{
@@ -412,11 +368,12 @@ namespace Content.Shared.Movement.Systems
protected abstract bool CanSound();
private bool TryGetSound(bool weightless, InputMoverComponent mover, MobMoverComponent mobMover, TransformComponent xform, [NotNullWhen(true)] out SoundSpecifier? sound)
private bool TryGetSound(bool weightless, EntityUid uid, InputMoverComponent mover, MobMoverComponent mobMover, TransformComponent xform, [NotNullWhen(true)] out SoundSpecifier? sound)
{
sound = null;
if (!CanSound() || !_tags.HasTag(mover.Owner, "FootstepSound")) return false;
if (!CanSound() || !_tags.HasTag(uid, "FootstepSound"))
return false;
var coordinates = xform.Coordinates;
var distanceNeeded = mover.Sprinting ? StepSoundMoveDistanceRunning : StepSoundMoveDistanceWalking;
@@ -443,27 +400,28 @@ namespace Content.Shared.Movement.Systems
mobMover.LastPosition = coordinates;
if (mobMover.StepSoundDistance < distanceNeeded) return false;
if (mobMover.StepSoundDistance < distanceNeeded)
return false;
mobMover.StepSoundDistance -= distanceNeeded;
if (TryComp<FootstepModifierComponent>(mover.Owner, out var moverModifier))
if (TryComp<FootstepModifierComponent>(uid, out var moverModifier))
{
sound = moverModifier.Sound;
return true;
}
if (_inventory.TryGetSlotEntity(mover.Owner, "shoes", out var shoes) &&
if (_inventory.TryGetSlotEntity(uid, "shoes", out var shoes) &&
TryComp<FootstepModifierComponent>(shoes, out var modifier))
{
sound = modifier.Sound;
return true;
}
return TryGetFootstepSound(xform, shoes != null, out sound);
return TryGetFootstepSound(uid, xform, shoes != null, out sound);
}
private bool TryGetFootstepSound(TransformComponent xform, bool haveShoes, [NotNullWhen(true)] out SoundSpecifier? sound)
private bool TryGetFootstepSound(EntityUid uid, TransformComponent xform, bool haveShoes, [NotNullWhen(true)] out SoundSpecifier? sound)
{
sound = null;
@@ -480,7 +438,7 @@ namespace Content.Shared.Movement.Systems
}
var position = grid.LocalToTile(xform.Coordinates);
var soundEv = new GetFootstepSoundEvent(xform.Owner);
var soundEv = new GetFootstepSoundEvent(uid);
// If the coordinates have a FootstepModifier component
// i.e. component that emit sound on footsteps emit that sound