public override void UpdateBeforeMapSolve(bool prediction, PhysicsMap map, float frameTime) { base.UpdateBeforeMapSolve(prediction, map, frameTime); foreach (var body in map.AwakeBodies) { if (prediction && !body.Predict) { continue; } var speed = body.LinearVelocity.Length; if (speed <= 0.0f || body.BodyStatus == BodyStatus.InAir) { continue; } // This is the *actual* amount that speed will drop by, we just do some multiplication around it to be easier. var drop = 0.0f; float control; // Only apply friction when it's not a mob (or the mob doesn't have control). if (SharedMoverController.UseMobMovement(_broadPhaseSystem, body, _physicsManager)) { continue; } var surfaceFriction = GetTileFriction(body); var bodyModifier = body.Owner.GetComponentOrNull <SharedTileFrictionModifier>()?.Modifier ?? 1.0f; var friction = _frictionModifier * surfaceFriction * bodyModifier; if (friction > 0.0f) { // TBH I can't really tell if this makes a difference. if (!prediction) { control = speed < _stopSpeed ? _stopSpeed : speed; } else { control = speed; } drop += control * friction * frameTime; } var newSpeed = MathF.Max(0.0f, speed - drop); newSpeed /= speed; body.LinearVelocity *= newSpeed; } }
public override void UpdateBeforeMapSolve(bool prediction, PhysicsMap map, float frameTime) { base.UpdateBeforeMapSolve(prediction, map, frameTime); foreach (var body in map.AwakeBodies) { // Only apply friction when it's not a mob (or the mob doesn't have control) if (prediction && !body.Predict || body.BodyStatus == BodyStatus.InAir || SharedMoverController.UseMobMovement(_broadPhaseSystem, body, _physicsManager)) { continue; } var surfaceFriction = GetTileFriction(body); var bodyModifier = body.Owner.GetComponentOrNull <SharedTileFrictionModifier>()?.Modifier ?? 1.0f; var friction = _frictionModifier * surfaceFriction * bodyModifier; ReduceLinearVelocity(prediction, body, friction, frameTime); ReduceAngularVelocity(prediction, body, friction, frameTime); } }