gd,fix: fixed a bug where the dash could mantle you nowhere. Automatic mantle at the end of dash.

This commit is contained in:
2025-05-27 15:15:07 +02:00
parent 1d8a8c7423
commit d8a1604af9
6 changed files with 139 additions and 63 deletions

View File

@ -1,4 +1,7 @@
using System.Collections.Generic;
using System.Runtime.InteropServices.JavaScript;
using Godot;
using RustyOptions;
namespace PolarBears.PlayerControllerAddon;
@ -34,7 +37,15 @@ public partial class PlayerController : CharacterBody3D
private bool _canDoubleJump = true;
private bool _movementEnabled = true;
private bool _isTweening = false;
private record TweenInputs(Vector3 Location, float Duration);
private Queue<TweenInputs> _tweenInputs = new Queue<TweenInputs>();
private bool _shouldMantle = false;
private Vector3 _dashLocation = Vector3.Zero;
private Vector3 _mantleLocation = Vector3.Zero;
private float _currentSpeed;
@ -65,8 +76,6 @@ public partial class PlayerController : CharacterBody3D
RayCast3D stairsBelowRayCast3D = GetNode<RayCast3D>("StairsBelowRayCast3D");
RayCast3D stairsAheadRayCast3D = GetNode<RayCast3D>("StairsAheadRayCast3D");
ShapeCast3D wallInFrontCast3D = GetNode<ShapeCast3D>("WallInFrontCast3D");
ShapeCast3D mantleCast3D = GetNode<ShapeCast3D>("MantleCast3D");
Node3D cameraSmooth = GetNode<Node3D>("Head/CameraSmooth");
@ -100,7 +109,7 @@ public partial class PlayerController : CharacterBody3D
StairsSystem.Init(stairsBelowRayCast3D, stairsAheadRayCast3D, cameraSmooth);
MantleSystem = GetNode<MantleSystem>("MantleSystem");
MantleSystem.Init(wallInFrontCast3D, Head, mantleCast3D);
MantleSystem.Init(Head);
DashSystem = GetNode<DashSystem>("DashSystem");
DashSystem.Init(Head, camera);
@ -139,32 +148,58 @@ public partial class PlayerController : CharacterBody3D
_movementEnabled = true;
}
private void TweenToLocation(Vector3 location, float duration)
public void EndTween()
{
Tween tween = GetTree().CreateTween();
var callback = new Callable(this, MethodName.EnableMovement);
EnableMovement();
_isTweening = false;
}
private void TweenToLocation(TweenInputs inputs)
{
var (location, duration) = inputs;
var tween = GetTree().CreateTween();
var callback = new Callable(this, MethodName.EndTween);
tween.TweenProperty(this, "position", location, duration);
tween.TweenCallback(callback);
DisableMovement();
_isTweening = true;
tween.Play();
}
private void QueueTween(TweenInputs inputs)
{
_tweenInputs.Enqueue(inputs);
}
private void QueueTween(Vector3 location, float duration)
{
QueueTween(new TweenInputs(location, duration));
}
public override void _PhysicsProcess(double delta)
{
if (_tweenInputs.Count > 0 && !_isTweening)
TweenToLocation(_tweenInputs.Dequeue());
if (Input.IsActionPressed("aim_dash"))
{
_dashLocation = DashSystem.PrepareDash().Unwrap();
(_shouldMantle, _dashLocation, _mantleLocation) = DashSystem.PrepareDash();
}
if (Input.IsActionJustReleased("aim_dash"))
{
DashSystem.Dash();
TweenToLocation(_dashLocation, 0.1f);
QueueTween(_dashLocation, 0.1f);
if (_shouldMantle)
{
QueueTween(_mantleLocation, 0.1f);
}
}
var mantleLocationResult = MantleSystem.CheckWallInFront();
var mantleLocationResult = MantleSystem.FindMantleInFrontOfPlayer();
if (isOnFloorCustom())
{
_lastFrameWasOnFloor = Engine.GetPhysicsFrames();
@ -189,10 +224,10 @@ public partial class PlayerController : CharacterBody3D
&& !doesCapsuleHaveCrouchingHeight
&& !isPlayerDead)
{
if (mantleLocationResult.IsOk(out var mantleLocation))
if (mantleLocationResult.IsSome(out var mantleLocation))
{
var duration = 0.1f * mantleLocation.DistanceTo(Position);
TweenToLocation(mantleLocation, duration);
QueueTween(mantleLocation, duration);
}
else if (isOnFloorCustom())
{