Mob Movement Major Refactor (#36847)
* Conveyor optimisations - Optimise movement for moving stuff. Better flags + less resolves + slapped parallelrobustjob on it. - Sleeping for entities getting conveyed into walls. * Blocker version * Finish * Final * Fix conveyor power mispredict * Bagel save * Revert "Bagel save" This reverts commit 1b93fda81fb852d89b89b0beae0b80f8a61165f2. * Conveyor resave * Init Commit * windows yelling at me to update commit * working commit, need prediciton and more dehardcoding * Project 0 warnings * Working Commit (Near Final) * ryder got confused commit * I love Merge Conflicts :) * Working commit, no prediction * Forgot the yaml changes * Comments and typos * Apparently while the reduced launch mult of lube was initialized it was never used so I revered back to default * Fixed an incorrect divisor * bit of cleanup * Prediciton fixed, and puddles now affect all entities * FORGOT TO RENAME A VERY IMPORTANT VARIABLE OOPS * Really big I forgor moment * Even bigger I forgor moment * four more merge conflicts to fix four more oopsies * fixed actual divide by zero moment and also im very dumb * Even bigger I forgor moment * four more merge conflicts to fix four more oopsies * fixed actual divide by zero moment and also im very dumb * Fix all test fails * code cleanup * Webedit whitespace * Code cleaup * whitespace webedit * whitespace webedit * whitespace webedit * whitespace removal * Comments and cleanup * Re-Added 20 warnings as per Ork's request * Cleanups * Spacing fix * bugfixes and cleanup * Small bugfix * Fix prediction * Mob movement rewrite * Bandaid * Working version * Tentatively working * Friction to fix cornering * More fixes * Refactor mob movement Trying to cleanup relay ordering / tryupdaterelative being cooked, purge ToParent, and fix all the eye rotation shenanigans. * Building * Re-implement jetpacks * Reorganise weightless movement * More work * Fix camera * reh * Revert bagel * Revert this * Revert held move buttons * Puddles work but are unpredicted and unoptimized * Fixes * Puddle code... * Actually dirty the slipComp for real * Sliding component done plus an extra suggestion from ArtisticRoomba * Atomized Commit * Added Friction field to Reagent Prototype per design discussion * Cleaned up Working Commit * a * Delete stinkers * Fix this code smell * Reviewed * Funky re-save * Our conveyance * Better conveyor sleeping * Remove this * Revert "Better conveyor sleeping" This reverts commit f5281f64bbae95b7b9feb56295c5cf931f9fb2e1. * Revert that Way too janky * Also this * a * Working Commit - Still a lot to do * Acceleration refactor * Minor jetpack cleanup * frictionnomovement no longer nullable * Shared Mover Feels 99% done * OffGrid/Weightless/Throwing Friction saved * Fix merge conflicts * Fix a debug assert * Final Commit for today * Some fixes * Actually use those CCVars Properly * Need to fix throwing * Second to last Commit for real * Jetpack bug fixed * Jetpack bug fixed * Test fail patch * Small patch * Skates Component cleanup + Bring Accel back to 5 (oops) * Fix test fail oops * yaml cleanup make dragons not fat --------- Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com> Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
1fbc845126
commit
36030ef154
@@ -1,4 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Net;
|
||||
using System.Numerics;
|
||||
using Content.Shared.Bed.Sleep;
|
||||
using Content.Shared.CCVar;
|
||||
@@ -21,6 +22,7 @@ using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Physics.Controllers;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager.Exceptions;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
using PullableComponent = Content.Shared.Movement.Pulling.Components.PullableComponent;
|
||||
@@ -61,12 +63,10 @@ public abstract partial class SharedMoverController : VirtualController
|
||||
|
||||
private static readonly ProtoId<TagPrototype> FootstepSoundTag = "FootstepSound";
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="CCVars.StopSpeed"/>
|
||||
/// </summary>
|
||||
private float _stopSpeed;
|
||||
|
||||
private bool _relativeMovement;
|
||||
private float _minDamping;
|
||||
private float _airDamping;
|
||||
private float _offGridDamping;
|
||||
|
||||
/// <summary>
|
||||
/// Cache the mob movement calculation to re-use elsewhere.
|
||||
@@ -90,10 +90,14 @@ public abstract partial class SharedMoverController : VirtualController
|
||||
FootstepModifierQuery = GetEntityQuery<FootstepModifierComponent>();
|
||||
MapGridQuery = GetEntityQuery<MapGridComponent>();
|
||||
|
||||
SubscribeLocalEvent<MovementSpeedModifierComponent, TileFrictionEvent>(OnTileFriction);
|
||||
|
||||
InitializeInput();
|
||||
InitializeRelay();
|
||||
Subs.CVar(_configManager, CCVars.RelativeMovement, value => _relativeMovement = value, true);
|
||||
Subs.CVar(_configManager, CCVars.StopSpeed, value => _stopSpeed = value, true);
|
||||
Subs.CVar(_configManager, CCVars.MinFriction, value => _minDamping = value, true);
|
||||
Subs.CVar(_configManager, CCVars.AirFriction, value => _airDamping = value, true);
|
||||
Subs.CVar(_configManager, CCVars.OffgridFriction, value => _offGridDamping = value, true);
|
||||
UpdatesBefore.Add(typeof(TileFrictionController));
|
||||
}
|
||||
|
||||
@@ -121,157 +125,213 @@ public abstract partial class SharedMoverController : VirtualController
|
||||
/// Movement while considering actionblockers, weightlessness, etc.
|
||||
/// </summary>
|
||||
protected void HandleMobMovement(
|
||||
EntityUid uid,
|
||||
InputMoverComponent mover,
|
||||
EntityUid physicsUid,
|
||||
PhysicsComponent physicsComponent,
|
||||
TransformComponent xform,
|
||||
Entity<InputMoverComponent> entity,
|
||||
float frameTime)
|
||||
{
|
||||
var canMove = mover.CanMove;
|
||||
if (RelayTargetQuery.TryGetComponent(uid, out var relayTarget))
|
||||
var uid = entity.Owner;
|
||||
var mover = entity.Comp;
|
||||
|
||||
// If we're a relay then apply all of our data to the parent instead and go next.
|
||||
if (RelayQuery.TryComp(uid, out var relay))
|
||||
{
|
||||
if (_mobState.IsIncapacitated(relayTarget.Source) ||
|
||||
TryComp<SleepingComponent>(relayTarget.Source, out _) ||
|
||||
!MoverQuery.TryGetComponent(relayTarget.Source, out var relayedMover))
|
||||
if (!MoverQuery.TryComp(relay.RelayEntity, out var relayTargetMover))
|
||||
return;
|
||||
|
||||
// Always lerp rotation so relay entities aren't cooked.
|
||||
LerpRotation(uid, mover, frameTime);
|
||||
var dirtied = false;
|
||||
|
||||
if (relayTargetMover.RelativeEntity != mover.RelativeEntity)
|
||||
{
|
||||
canMove = false;
|
||||
relayTargetMover.RelativeEntity = mover.RelativeEntity;
|
||||
dirtied = true;
|
||||
}
|
||||
else
|
||||
|
||||
if (relayTargetMover.RelativeRotation != mover.RelativeRotation)
|
||||
{
|
||||
mover.RelativeEntity = relayedMover.RelativeEntity;
|
||||
mover.RelativeRotation = relayedMover.RelativeRotation;
|
||||
mover.TargetRelativeRotation = relayedMover.TargetRelativeRotation;
|
||||
relayTargetMover.RelativeRotation = mover.RelativeRotation;
|
||||
dirtied = true;
|
||||
}
|
||||
|
||||
if (relayTargetMover.TargetRelativeRotation != mover.TargetRelativeRotation)
|
||||
{
|
||||
relayTargetMover.TargetRelativeRotation = mover.TargetRelativeRotation;
|
||||
dirtied = true;
|
||||
}
|
||||
|
||||
if (relayTargetMover.CanMove != mover.CanMove)
|
||||
{
|
||||
relayTargetMover.CanMove = mover.CanMove;
|
||||
dirtied = true;
|
||||
}
|
||||
|
||||
if (dirtied)
|
||||
{
|
||||
Dirty(relay.RelayEntity, relayTargetMover);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Update relative movement
|
||||
if (mover.LerpTarget < Timing.CurTime)
|
||||
if (!XformQuery.TryComp(entity.Owner, out var xform))
|
||||
return;
|
||||
|
||||
RelayTargetQuery.TryComp(uid, out var relayTarget);
|
||||
var relaySource = relayTarget?.Source;
|
||||
|
||||
// If we're not the target of a relay then handle lerp data.
|
||||
if (relaySource == null)
|
||||
{
|
||||
if (TryUpdateRelative(mover, xform))
|
||||
// Update relative movement
|
||||
if (mover.LerpTarget < Timing.CurTime)
|
||||
{
|
||||
Dirty(uid, mover);
|
||||
TryUpdateRelative(uid, mover, xform);
|
||||
}
|
||||
|
||||
LerpRotation(uid, mover, frameTime);
|
||||
}
|
||||
|
||||
LerpRotation(uid, mover, frameTime);
|
||||
|
||||
if (!canMove
|
||||
|| physicsComponent.BodyStatus != BodyStatus.OnGround && !CanMoveInAirQuery.HasComponent(uid)
|
||||
// If we can't move then just use tile-friction / no movement handling.
|
||||
if (!mover.CanMove
|
||||
|| !PhysicsQuery.TryComp(uid, out var physicsComponent)
|
||||
|| PullableQuery.TryGetComponent(uid, out var pullable) && pullable.BeingPulled)
|
||||
{
|
||||
UsedMobMovement[uid] = false;
|
||||
return;
|
||||
}
|
||||
|
||||
UsedMobMovement[uid] = true;
|
||||
// Specifically don't use mover.Owner because that may be different to the actual physics body being moved.
|
||||
var weightless = _gravity.IsWeightless(physicsUid, physicsComponent, xform);
|
||||
var (walkDir, sprintDir) = GetVelocityInput(mover);
|
||||
var touching = false;
|
||||
// If the body is in air but isn't weightless then it can't move
|
||||
// TODO: MAKE ISWEIGHTLESS EVENT BASED
|
||||
var weightless = _gravity.IsWeightless(uid, physicsComponent, xform);
|
||||
var inAirHelpless = false;
|
||||
|
||||
// Handle wall-pushes.
|
||||
if (weightless)
|
||||
if (physicsComponent.BodyStatus != BodyStatus.OnGround && !CanMoveInAirQuery.HasComponent(uid))
|
||||
{
|
||||
if (xform.GridUid != null)
|
||||
touching = true;
|
||||
|
||||
if (!touching)
|
||||
if (!weightless)
|
||||
{
|
||||
var ev = new CanWeightlessMoveEvent(uid);
|
||||
RaiseLocalEvent(uid, ref ev, true);
|
||||
// No gravity: is our entity touching anything?
|
||||
touching = ev.CanMove;
|
||||
|
||||
if (!touching && TryComp<MobMoverComponent>(uid, out var mobMover))
|
||||
touching |= IsAroundCollider(PhysicsSystem, xform, mobMover, physicsUid, physicsComponent);
|
||||
UsedMobMovement[uid] = false;
|
||||
return;
|
||||
}
|
||||
inAirHelpless = true;
|
||||
}
|
||||
|
||||
UsedMobMovement[uid] = true;
|
||||
|
||||
var moveSpeedComponent = ModifierQuery.CompOrNull(uid);
|
||||
|
||||
float friction;
|
||||
float accel;
|
||||
Vector2 wishDir;
|
||||
var velocity = physicsComponent.LinearVelocity;
|
||||
|
||||
// Get current tile def for things like speed/friction mods
|
||||
ContentTileDefinition? tileDef = null;
|
||||
|
||||
// Don't bother getting the tiledef here if we're weightless or in-air
|
||||
// since no tile-based modifiers should be applying in that situation
|
||||
if (MapGridQuery.TryComp(xform.GridUid, out var gridComp)
|
||||
&& _mapSystem.TryGetTileRef(xform.GridUid.Value, gridComp, xform.Coordinates, out var tile)
|
||||
&& !(weightless || physicsComponent.BodyStatus == BodyStatus.InAir))
|
||||
var touching = false;
|
||||
// Whether we use tilefriction or not
|
||||
if (weightless || inAirHelpless)
|
||||
{
|
||||
tileDef = (ContentTileDefinition) _tileDefinitionManager[tile.Tile.TypeId];
|
||||
}
|
||||
// Find the speed we should be moving at and make sure we're not trying to move faster than that
|
||||
var walkSpeed = moveSpeedComponent?.WeightlessWalkSpeed ?? MovementSpeedModifierComponent.DefaultBaseWalkSpeed;
|
||||
var sprintSpeed = moveSpeedComponent?.WeightlessSprintSpeed ?? MovementSpeedModifierComponent.DefaultBaseSprintSpeed;
|
||||
|
||||
// Regular movement.
|
||||
// Target velocity.
|
||||
// This is relative to the map / grid we're on.
|
||||
var moveSpeedComponent = ModifierQuery.CompOrNull(uid);
|
||||
wishDir = AssertValidWish(mover, walkSpeed, sprintSpeed);
|
||||
|
||||
var walkSpeed = moveSpeedComponent?.CurrentWalkSpeed ?? MovementSpeedModifierComponent.DefaultBaseWalkSpeed;
|
||||
var sprintSpeed = moveSpeedComponent?.CurrentSprintSpeed ?? MovementSpeedModifierComponent.DefaultBaseSprintSpeed;
|
||||
var ev = new CanWeightlessMoveEvent(uid);
|
||||
RaiseLocalEvent(uid, ref ev, true);
|
||||
|
||||
var total = walkDir * walkSpeed + sprintDir * sprintSpeed;
|
||||
touching = ev.CanMove || xform.GridUid != null || MapGridQuery.HasComp(xform.GridUid);
|
||||
|
||||
var parentRotation = GetParentGridAngle(mover);
|
||||
var wishDir = _relativeMovement ? parentRotation.RotateVec(total) : total;
|
||||
// If we're not on a grid, and not able to move in space check if we're close enough to a grid to touch.
|
||||
if (!touching && MobMoverQuery.TryComp(uid, out var mobMover))
|
||||
touching |= IsAroundCollider(PhysicsSystem, xform, mobMover, uid, physicsComponent);
|
||||
|
||||
DebugTools.Assert(MathHelper.CloseToPercent(total.Length(), wishDir.Length()));
|
||||
|
||||
float friction;
|
||||
float weightlessModifier;
|
||||
float accel;
|
||||
var velocity = physicsComponent.LinearVelocity;
|
||||
|
||||
// Whether we use weightless friction or not.
|
||||
if (weightless)
|
||||
{
|
||||
if (gridComp == null && !MapGridQuery.HasComp(xform.GridUid))
|
||||
friction = moveSpeedComponent?.OffGridFriction ?? MovementSpeedModifierComponent.DefaultOffGridFriction;
|
||||
else if (wishDir != Vector2.Zero && touching)
|
||||
friction = moveSpeedComponent?.WeightlessFriction ?? MovementSpeedModifierComponent.DefaultWeightlessFriction;
|
||||
// If we're touching then use the weightless values
|
||||
if (touching)
|
||||
{
|
||||
touching = true;
|
||||
if (wishDir != Vector2.Zero)
|
||||
friction = moveSpeedComponent?.WeightlessFriction ?? _airDamping;
|
||||
else
|
||||
friction = moveSpeedComponent?.WeightlessFrictionNoInput ?? _airDamping;
|
||||
}
|
||||
// Otherwise use the off-grid values.
|
||||
else
|
||||
friction = moveSpeedComponent?.WeightlessFrictionNoInput ?? MovementSpeedModifierComponent.DefaultWeightlessFrictionNoInput;
|
||||
{
|
||||
friction = moveSpeedComponent?.OffGridFriction ?? _offGridDamping;
|
||||
}
|
||||
|
||||
weightlessModifier = moveSpeedComponent?.WeightlessModifier ?? MovementSpeedModifierComponent.DefaultWeightlessModifier;
|
||||
accel = moveSpeedComponent?.WeightlessAcceleration ?? MovementSpeedModifierComponent.DefaultWeightlessAcceleration;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wishDir != Vector2.Zero || moveSpeedComponent?.FrictionNoInput == null)
|
||||
if (MapGridQuery.TryComp(xform.GridUid, out var gridComp)
|
||||
&& _mapSystem.TryGetTileRef(xform.GridUid.Value, gridComp, xform.Coordinates, out var tile))
|
||||
tileDef = (ContentTileDefinition) _tileDefinitionManager[tile.Tile.TypeId];
|
||||
|
||||
var walkSpeed = moveSpeedComponent?.CurrentWalkSpeed ?? MovementSpeedModifierComponent.DefaultBaseWalkSpeed;
|
||||
var sprintSpeed = moveSpeedComponent?.CurrentSprintSpeed ?? MovementSpeedModifierComponent.DefaultBaseSprintSpeed;
|
||||
|
||||
wishDir = AssertValidWish(mover, walkSpeed, sprintSpeed);
|
||||
|
||||
if (wishDir != Vector2.Zero)
|
||||
{
|
||||
friction = tileDef?.MobFriction ?? moveSpeedComponent?.Friction ?? MovementSpeedModifierComponent.DefaultFriction;
|
||||
friction = moveSpeedComponent?.Friction ?? MovementSpeedModifierComponent.DefaultFriction;
|
||||
friction *= tileDef?.MobFriction ?? tileDef?.Friction ?? 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
friction = tileDef?.MobFrictionNoInput ?? moveSpeedComponent.FrictionNoInput ?? MovementSpeedModifierComponent.DefaultFrictionNoInput;
|
||||
friction = moveSpeedComponent?.FrictionNoInput ?? MovementSpeedModifierComponent.DefaultFrictionNoInput;
|
||||
friction *= tileDef?.Friction ?? 1f;
|
||||
}
|
||||
|
||||
weightlessModifier = 1f;
|
||||
accel = tileDef?.MobAcceleration ?? moveSpeedComponent?.Acceleration ?? MovementSpeedModifierComponent.DefaultAcceleration;
|
||||
accel = moveSpeedComponent?.Acceleration ?? MovementSpeedModifierComponent.DefaultAcceleration;
|
||||
accel *= tileDef?.MobAcceleration ?? 1f;
|
||||
}
|
||||
|
||||
// This way friction never exceeds acceleration when you're trying to move.
|
||||
// If you want to slow down an entity with "friction" you shouldn't be using this system.
|
||||
if (wishDir != Vector2.Zero)
|
||||
friction = Math.Min(friction, accel);
|
||||
friction = Math.Max(friction, _minDamping);
|
||||
var minimumFrictionSpeed = moveSpeedComponent?.MinimumFrictionSpeed ?? MovementSpeedModifierComponent.DefaultMinimumFrictionSpeed;
|
||||
Friction(minimumFrictionSpeed, frameTime, friction, ref velocity);
|
||||
|
||||
wishDir *= weightlessModifier;
|
||||
|
||||
if (!weightless || touching)
|
||||
Accelerate(ref velocity, in wishDir, accel, frameTime);
|
||||
|
||||
SetWishDir((uid, mover), wishDir);
|
||||
|
||||
PhysicsSystem.SetLinearVelocity(physicsUid, velocity, body: physicsComponent);
|
||||
/*
|
||||
* SNAKING!!! >-( 0 ================>
|
||||
* Snaking is a feature where you can move faster by strafing in a direction perpendicular to the
|
||||
* direction you intend to move while still holding the movement key for the direction you're trying to move.
|
||||
* Snaking only works if acceleration exceeds friction, and it's effectiveness scales as acceleration continues
|
||||
* to exceed friction.
|
||||
* Snaking works because friction is applied first in the direction of our current velocity, while acceleration
|
||||
* is applied after in our "Wish Direction" and is capped by the dot of our wish direction and current direction.
|
||||
* This means when you change direction, you're technically able to accelerate more than what the velocity cap
|
||||
* allows, but friction normally eats up the extra movement you gain.
|
||||
* By strafing as stated above you can increase your speed by about 1.4 (square root of 2).
|
||||
* This only works if friction is low enough so be sure that anytime you are letting a mob move in a low friction
|
||||
* environment you take into account the fact they can snake! Also be sure to lower acceleration as well to
|
||||
* prevent jerky movement!
|
||||
*/
|
||||
PhysicsSystem.SetLinearVelocity(uid, velocity, body: physicsComponent);
|
||||
|
||||
// Ensures that players do not spiiiiiiin
|
||||
PhysicsSystem.SetAngularVelocity(physicsUid, 0, body: physicsComponent);
|
||||
PhysicsSystem.SetAngularVelocity(uid, 0, body: physicsComponent);
|
||||
|
||||
// Handle footsteps at the end
|
||||
if (total != Vector2.Zero)
|
||||
if (wishDir != Vector2.Zero)
|
||||
{
|
||||
if (!NoRotateQuery.HasComponent(uid))
|
||||
{
|
||||
// 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?
|
||||
var worldRot = _transform.GetWorldRotation(xform);
|
||||
_transform.SetLocalRotation(xform, xform.LocalRotation + wishDir.ToWorldAngle() - worldRot);
|
||||
|
||||
_transform.SetLocalRotation(uid, xform.LocalRotation + wishDir.ToWorldAngle() - worldRot, xform);
|
||||
}
|
||||
|
||||
if (!weightless && MobMoverQuery.TryGetComponent(uid, out var mobMover) &&
|
||||
@@ -284,9 +344,9 @@ public abstract partial class SharedMoverController : VirtualController
|
||||
.WithVariation(sound.Params.Variation ?? mobMover.FootstepVariation);
|
||||
|
||||
// If we're a relay target then predict the sound for all relays.
|
||||
if (relayTarget != null)
|
||||
if (relaySource != null)
|
||||
{
|
||||
_audio.PlayPredicted(sound, uid, relayTarget.Source, audioParams);
|
||||
_audio.PlayPredicted(sound, uid, relaySource.Value, audioParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -334,14 +394,12 @@ public abstract partial class SharedMoverController : VirtualController
|
||||
adjustment = Math.Clamp(adjustment, -angleDiff, angleDiff);
|
||||
}
|
||||
|
||||
mover.RelativeRotation += adjustment;
|
||||
mover.RelativeRotation.FlipPositive();
|
||||
mover.RelativeRotation = (mover.RelativeRotation + adjustment).FlipPositive();
|
||||
Dirty(uid, mover);
|
||||
}
|
||||
else if (!angleDiff.Equals(Angle.Zero))
|
||||
{
|
||||
mover.TargetRelativeRotation.FlipPositive();
|
||||
mover.RelativeRotation = mover.TargetRelativeRotation;
|
||||
mover.RelativeRotation = mover.TargetRelativeRotation.FlipPositive();
|
||||
Dirty(uid, mover);
|
||||
}
|
||||
}
|
||||
@@ -353,18 +411,10 @@ public abstract partial class SharedMoverController : VirtualController
|
||||
if (speed < minimumFrictionSpeed)
|
||||
return;
|
||||
|
||||
var drop = 0f;
|
||||
// This equation is lifted from the Physics Island solver.
|
||||
// We re-use it here because Kinematic Controllers can't/shouldn't use the Physics Friction
|
||||
velocity *= Math.Clamp(1.0f - frameTime * friction, 0.0f, 1.0f);
|
||||
|
||||
var control = MathF.Max(_stopSpeed, speed);
|
||||
drop += control * friction * frameTime;
|
||||
|
||||
var newSpeed = MathF.Max(0f, speed - drop);
|
||||
|
||||
if (newSpeed.Equals(speed))
|
||||
return;
|
||||
|
||||
newSpeed /= speed;
|
||||
velocity *= newSpeed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -542,4 +592,30 @@ public abstract partial class SharedMoverController : VirtualController
|
||||
sound = haveShoes ? tileDef.FootstepSounds : tileDef.BarestepSounds;
|
||||
return sound != null;
|
||||
}
|
||||
|
||||
private Vector2 AssertValidWish(InputMoverComponent mover, float walkSpeed, float sprintSpeed)
|
||||
{
|
||||
var (walkDir, sprintDir) = GetVelocityInput(mover);
|
||||
|
||||
var total = walkDir * walkSpeed + sprintDir * sprintSpeed;
|
||||
|
||||
var parentRotation = GetParentGridAngle(mover);
|
||||
var wishDir = _relativeMovement ? parentRotation.RotateVec(total) : total;
|
||||
|
||||
DebugTools.Assert(MathHelper.CloseToPercent(total.Length(), wishDir.Length()));
|
||||
|
||||
return wishDir;
|
||||
}
|
||||
|
||||
private void OnTileFriction(Entity<MovementSpeedModifierComponent> ent, ref TileFrictionEvent args)
|
||||
{
|
||||
if (!TryComp<PhysicsComponent>(ent, out var physicsComponent) || !XformQuery.TryComp(ent, out var xform))
|
||||
return;
|
||||
|
||||
// TODO: Make IsWeightless event based!!!
|
||||
if (physicsComponent.BodyStatus != BodyStatus.OnGround || _gravity.IsWeightless(ent, physicsComponent, xform))
|
||||
args.Modifier *= ent.Comp.BaseWeightlessFriction;
|
||||
else
|
||||
args.Modifier *= ent.Comp.BaseFriction;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user