|
|
|
|
@@ -118,8 +118,10 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
public int MaxNumberOfEmpoweredActions { get; set; } = 1;
|
|
|
|
|
// Simple dash
|
|
|
|
|
[ExportSubgroup("Simple")]
|
|
|
|
|
[Export(PropertyHint.Range, "0,50,0.1")]
|
|
|
|
|
[Export(PropertyHint.Range, "0,50,0.1,or_greater")]
|
|
|
|
|
public float SimpleDashStrength { get; set; } = 10f;
|
|
|
|
|
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
|
|
|
|
|
public float SimpleDashTime { get; set; } = 0.5f;
|
|
|
|
|
// Aimed Dash
|
|
|
|
|
[ExportSubgroup("Special")]
|
|
|
|
|
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
|
|
|
|
|
@@ -128,6 +130,10 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
public float PostDashSpeed { get; set; } = 100f;
|
|
|
|
|
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
|
|
|
|
|
public float TimeScaleAimInAir { get; set; } = 0.05f;
|
|
|
|
|
// Slam
|
|
|
|
|
[ExportSubgroup("Slam")]
|
|
|
|
|
[Export(PropertyHint.Range, "0,100,1,or_greater")]
|
|
|
|
|
public float SlamSpeed { get; set; } = 50.0f;
|
|
|
|
|
|
|
|
|
|
// Sliding and gliding
|
|
|
|
|
[ExportGroup("Slide")]
|
|
|
|
|
@@ -254,12 +260,14 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
private StateChartState _sliding;
|
|
|
|
|
private StateChartState _groundSliding;
|
|
|
|
|
private StateChartState _airGliding;
|
|
|
|
|
private StateChartState _slamming;
|
|
|
|
|
private StateChartState _onWall;
|
|
|
|
|
private StateChartState _onWallHugging;
|
|
|
|
|
private StateChartState _onWallHanging;
|
|
|
|
|
private StateChartState _onWallRunning;
|
|
|
|
|
|
|
|
|
|
private Transition _onJumpFromWall;
|
|
|
|
|
private Transition _onJumpFromWallFalling;
|
|
|
|
|
private Transition _onLeaveWallFromRun;
|
|
|
|
|
|
|
|
|
|
public override void _Ready()
|
|
|
|
|
@@ -322,6 +330,7 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
_sliding = StateChartState.Of(GetNode("StateChart/Root/Movement/Sliding"));
|
|
|
|
|
_groundSliding = StateChartState.Of(GetNode("StateChart/Root/Movement/Sliding/GroundSlide"));
|
|
|
|
|
_airGliding = StateChartState.Of(GetNode("StateChart/Root/Movement/Sliding/AirGlide"));
|
|
|
|
|
_slamming = StateChartState.Of(GetNode("StateChart/Root/Movement/Slamming"));
|
|
|
|
|
|
|
|
|
|
// _actionHanging = StateChartState.Of(GetNode("StateChart/Root/Actions/Hanging"));
|
|
|
|
|
_powerExpired = StateChartState.Of(GetNode("StateChart/Root/PowerReserve/Expired"));
|
|
|
|
|
@@ -336,6 +345,7 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
_doubleJump = StateChartState.Of(GetNode("StateChart/Root/Movement/Jump/DoubleJump"));
|
|
|
|
|
_mantling = StateChartState.Of(GetNode("StateChart/Root/Movement/Mantling"));
|
|
|
|
|
_onJumpFromWall = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/OnJump"));
|
|
|
|
|
_onJumpFromWallFalling = Transition.Of(GetNode("StateChart/Root/Movement/Airborne/Falling/OnWallJump"));
|
|
|
|
|
_onWall = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall"));
|
|
|
|
|
_onWallHugging = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall/Hugging"));
|
|
|
|
|
_onWallHanging = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall/Hanging"));
|
|
|
|
|
@@ -414,6 +424,10 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
_groundSliding.StatePhysicsProcessing += HandleGroundSlide;
|
|
|
|
|
_airGliding.StatePhysicsProcessing += HandleAirGlide;
|
|
|
|
|
|
|
|
|
|
_slamming.StateEntered += SlamStarted;
|
|
|
|
|
_slamming.StateExited += SlamEnded;
|
|
|
|
|
_slamming.StatePhysicsProcessing += HandleSlam;
|
|
|
|
|
|
|
|
|
|
_simpleDashCooldownTimer.Timeout += DashCooldownTimeout;
|
|
|
|
|
_airborneDashCooldownTimer.Timeout += AirborneDashCooldownTimeout;
|
|
|
|
|
|
|
|
|
|
@@ -424,6 +438,7 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
_onWallRunning.StatePhysicsProcessing += HandleWallRunning;
|
|
|
|
|
|
|
|
|
|
_onJumpFromWall.Taken += OnJumpFromWall;
|
|
|
|
|
_onJumpFromWallFalling.Taken += OnJumpFromWall;
|
|
|
|
|
_onLeaveWallFromRun.Taken += OnLeaveWallFromRun;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -478,6 +493,7 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
///////////////////////////
|
|
|
|
|
// Grounded management //
|
|
|
|
|
///////////////////////////
|
|
|
|
|
|
|
|
|
|
public void OnGrounded()
|
|
|
|
|
{
|
|
|
|
|
_isWallJumpAvailable = true;
|
|
|
|
|
@@ -486,28 +502,36 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
if (_simpleDashCooldownTimer.IsStopped())
|
|
|
|
|
_simpleDashCooldownTimer.Start();
|
|
|
|
|
|
|
|
|
|
if (_bufferedAction == BufferedActions.Jump && _currentInputBufferFrames > 0)
|
|
|
|
|
{
|
|
|
|
|
_currentInputBufferFrames = 0;
|
|
|
|
|
PerformJump();
|
|
|
|
|
}
|
|
|
|
|
if (_bufferedAction == BufferedActions.Dash && _currentInputBufferFrames > 0)
|
|
|
|
|
{
|
|
|
|
|
_currentInputBufferFrames = 0;
|
|
|
|
|
SimpleDash();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_bufferedAction == BufferedActions.MantleJump)
|
|
|
|
|
{
|
|
|
|
|
SimpleDash();
|
|
|
|
|
OnJumpStarted(MantleJumpStartVelocity);
|
|
|
|
|
_playerState.SendEvent("jump");
|
|
|
|
|
}
|
|
|
|
|
if (_bufferedAction == BufferedActions.MantleDash)
|
|
|
|
|
{
|
|
|
|
|
SimpleDash(MantleDashStrength);
|
|
|
|
|
if (GetMoveInput().Length() < Mathf.Epsilon)
|
|
|
|
|
{
|
|
|
|
|
_bufferedAction = BufferedActions.None;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
_playerState.SendEvent("dash");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_bufferedAction == BufferedActions.Jump && _currentInputBufferFrames > 0)
|
|
|
|
|
{
|
|
|
|
|
_currentInputBufferFrames = 0;
|
|
|
|
|
_playerState.SendEvent("jump");
|
|
|
|
|
}
|
|
|
|
|
if (_bufferedAction == BufferedActions.Dash && _currentInputBufferFrames > 0)
|
|
|
|
|
{
|
|
|
|
|
if (GetMoveInput().Length() < Mathf.Epsilon)
|
|
|
|
|
{
|
|
|
|
|
_bufferedAction = BufferedActions.None;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
_currentInputBufferFrames = 0;
|
|
|
|
|
_playerState.SendEvent("dash");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_bufferedAction = BufferedActions.None;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool IsGroundLike()
|
|
|
|
|
@@ -528,7 +552,7 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
Velocity = new Vector3(horizontalVelocity.X, Velocity.Y, horizontalVelocity.Z);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void HandleStairs(float delta)
|
|
|
|
|
private void MoveSlideAndHandleStairs(float delta)
|
|
|
|
|
{
|
|
|
|
|
StairsSystem.UpStairsCheckParams upStairsCheckParams = new StairsSystem.UpStairsCheckParams
|
|
|
|
|
{
|
|
|
|
|
@@ -638,7 +662,7 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If all else fail and we go down, we hug
|
|
|
|
|
if (Velocity.Y < 0 && !_coyoteEnabled.Active)
|
|
|
|
|
if (Velocity.Y < 0 && IsInputTowardsWall(wallNormal))
|
|
|
|
|
{
|
|
|
|
|
_playerState.SendEvent("wall_hug");
|
|
|
|
|
}
|
|
|
|
|
@@ -839,22 +863,28 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
_playerState.SendEvent("cancel_aim");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (GetMoveInput().Length() < Mathf.Epsilon) return;
|
|
|
|
|
|
|
|
|
|
// Buffer dash in case of mantle or inputting dash airborne before touching the ground without air dash available
|
|
|
|
|
_currentInputBufferFrames = InputBufferFrames;
|
|
|
|
|
_bufferedAction = _mantling.Active ? BufferedActions.MantleDash : BufferedActions.Dash;
|
|
|
|
|
|
|
|
|
|
if (_airborne.Active)
|
|
|
|
|
{
|
|
|
|
|
if (!_canDashAirborne)
|
|
|
|
|
return;
|
|
|
|
|
_canDashAirborne = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_currentInputBufferFrames = InputBufferFrames;
|
|
|
|
|
_bufferedAction = _mantling.Active ? BufferedActions.MantleDash : BufferedActions.Dash;
|
|
|
|
|
|
|
|
|
|
_playerState.SendEvent("dash");
|
|
|
|
|
}
|
|
|
|
|
public void SimpleDashInDirection(Vector3 direction, float strength = -1)
|
|
|
|
|
{
|
|
|
|
|
if (strength < 0) strength = SimpleDashStrength;
|
|
|
|
|
SetVelocity(direction * strength);
|
|
|
|
|
|
|
|
|
|
GetTree().CreateTimer(SimpleDashTime).Timeout += SimpleDashFinished;
|
|
|
|
|
}
|
|
|
|
|
public void SimpleDash(float strength = -1)
|
|
|
|
|
{
|
|
|
|
|
@@ -863,12 +893,32 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
|
|
|
|
|
public void OnSimpleDashStarted()
|
|
|
|
|
{
|
|
|
|
|
if (!_canDash)
|
|
|
|
|
if (_bufferedAction == BufferedActions.MantleDash)
|
|
|
|
|
{
|
|
|
|
|
SimpleDash(MantleDashStrength);
|
|
|
|
|
_bufferedAction = BufferedActions.None;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!_canDash)
|
|
|
|
|
{
|
|
|
|
|
_playerState.SendEvent("dash_finished");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
_canDash = false;
|
|
|
|
|
SimpleDash();
|
|
|
|
|
_bufferedAction = BufferedActions.None;
|
|
|
|
|
}
|
|
|
|
|
public void HandleSimpleDash(float delta)
|
|
|
|
|
{
|
|
|
|
|
if (MantleSystem.IsMantlePossible && IsPlayerInputtingForward())
|
|
|
|
|
{
|
|
|
|
|
_bufferedAction = BufferedActions.MantleDash;
|
|
|
|
|
_playerState.SendEvent("mantle");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SimpleDashFinished()
|
|
|
|
|
{
|
|
|
|
|
_playerState.SendEvent("dash_finished");
|
|
|
|
|
}
|
|
|
|
|
@@ -876,6 +926,11 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
///////////////////////////
|
|
|
|
|
// On wall management //
|
|
|
|
|
///////////////////////////
|
|
|
|
|
|
|
|
|
|
public bool IsInputTowardsWall(Vector3 wallNormal)
|
|
|
|
|
{
|
|
|
|
|
return wallNormal.Dot(GetInputGlobalHDirection()) < -0.5;
|
|
|
|
|
}
|
|
|
|
|
public void HandleOnWall(float delta)
|
|
|
|
|
{
|
|
|
|
|
if (IsTryingToMantle()) _playerState.SendEvent("mantle");
|
|
|
|
|
@@ -914,10 +969,8 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
WallHug(delta);
|
|
|
|
|
if (isOnFloorCustom())
|
|
|
|
|
_playerState.SendEvent("grounded");
|
|
|
|
|
if (!WallHugSystem.IsWallHugging())
|
|
|
|
|
{
|
|
|
|
|
if (!WallHugSystem.IsWallHugging() || !IsInputTowardsWall(_wallHugStartNormal))
|
|
|
|
|
_playerState.SendEvent("start_falling");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public void HandleWallHanging(float delta)
|
|
|
|
|
{
|
|
|
|
|
@@ -980,7 +1033,9 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
public void OnInputJumpStarted()
|
|
|
|
|
{
|
|
|
|
|
_currentInputBufferFrames = InputBufferFrames;
|
|
|
|
|
_bufferedAction = _mantling.Active ? BufferedActions.MantleJump : BufferedActions.Jump;
|
|
|
|
|
if (_mantling.Active) _bufferedAction = BufferedActions.MantleJump;
|
|
|
|
|
// Don't overwrite mantle jump buffered action
|
|
|
|
|
else if (_bufferedAction == BufferedActions.None) _bufferedAction = BufferedActions.Jump;
|
|
|
|
|
_isJumpInputPressed = true;
|
|
|
|
|
|
|
|
|
|
PerformJump();
|
|
|
|
|
@@ -996,12 +1051,16 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
|
|
|
|
|
public void PerformJump()
|
|
|
|
|
{
|
|
|
|
|
if (MantleSystem.IsMantlePossible)
|
|
|
|
|
if (MantleSystem.IsMantlePossible && !_mantling.Active)
|
|
|
|
|
{
|
|
|
|
|
_playerState.SendEvent("mantle");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (WallHugSystem.IsWallHugging())
|
|
|
|
|
{
|
|
|
|
|
_playerState.SendEvent("wall_jump");
|
|
|
|
|
}
|
|
|
|
|
_playerState.SendEvent("jump");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1012,13 +1071,22 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
}
|
|
|
|
|
public void OnSimpleJumpStarted()
|
|
|
|
|
{
|
|
|
|
|
if (_bufferedAction == BufferedActions.MantleJump)
|
|
|
|
|
{
|
|
|
|
|
SetVelocity(GetInputGlobalHDirection()*SimpleDashStrength);
|
|
|
|
|
OnJumpStarted(MantleJumpStartVelocity);
|
|
|
|
|
_bufferedAction = BufferedActions.None;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
OnJumpStarted(SimpleJumpStartVelocity);
|
|
|
|
|
_bufferedAction = BufferedActions.None;
|
|
|
|
|
}
|
|
|
|
|
public void OnDoubleJumpStarted()
|
|
|
|
|
{
|
|
|
|
|
_canDash = true;
|
|
|
|
|
// _canDashAirborne = true;
|
|
|
|
|
OnJumpStarted(DoubleJumpStartVelocity);
|
|
|
|
|
_bufferedAction = BufferedActions.None;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void HandleJump(float delta, float gravityFactor, int hangFrames)
|
|
|
|
|
@@ -1198,7 +1266,20 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
///////////////////////////
|
|
|
|
|
public void OnInputSlamPressed()
|
|
|
|
|
{
|
|
|
|
|
GD.Print("Slam pressed");
|
|
|
|
|
_playerState.SendEvent("slam");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SlamStarted()
|
|
|
|
|
{
|
|
|
|
|
SetHorizontalVelocity(Vector2.Zero);
|
|
|
|
|
SetVerticalVelocity(-SlamSpeed);
|
|
|
|
|
}
|
|
|
|
|
public void HandleSlam(float delta)
|
|
|
|
|
{
|
|
|
|
|
if (isOnFloorCustom()) _playerState.SendEvent("grounded");
|
|
|
|
|
}
|
|
|
|
|
public void SlamEnded()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///////////////////////////
|
|
|
|
|
@@ -1438,7 +1519,7 @@ public partial class PlayerController : CharacterBody3D
|
|
|
|
|
|
|
|
|
|
LookAround(delta);
|
|
|
|
|
CameraModifications((float) delta);
|
|
|
|
|
HandleStairs((float) delta);
|
|
|
|
|
MoveSlideAndHandleStairs((float) delta);
|
|
|
|
|
MantleSystem.ProcessMantle(_grounded.Active);
|
|
|
|
|
if (WeaponSystem.InHandState.Active)
|
|
|
|
|
RotateWeaponWithPlayer();
|
|
|
|
|
|