diff --git a/maps/GYMs/enemies.tscn b/maps/GYMs/enemies.tscn index c62f6a92..2a73974b 100644 --- a/maps/GYMs/enemies.tscn +++ b/maps/GYMs/enemies.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=19 format=3 uid="uid://q7uc1h2jpbd2"] +[gd_scene load_steps=21 format=3 uid="uid://q7uc1h2jpbd2"] [ext_resource type="PackedScene" uid="uid://bei4nhkf8lwdo" path="res://player_controller/PlayerController.tscn" id="1_62kkh"] [ext_resource type="Material" uid="uid://31aulub2nqov" path="res://assets/greybox/m_greybox.tres" id="2_3uydm"] [ext_resource type="PackedScene" uid="uid://dxt0e2ugmttqq" path="res://scenes/enemies/grounded_enemy/grounded_enemy.tscn" id="3_3uydm"] [ext_resource type="PackedScene" uid="uid://cmlud1hwkd6sv" path="res://scenes/enemies/flying_enemy/flying_enemy.tscn" id="5_8fd2t"] +[ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://components/movement/RMovement.cs" id="5_ybosk"] [ext_resource type="Script" uid="uid://b44cse62qru7j" path="res://components/knockback/RKnockback.cs" id="6_1hrkh"] [ext_resource type="PackedScene" uid="uid://c305mfrtumcyq" path="res://scenes/spawners/spawner.tscn" id="6_7m3bq"] [ext_resource type="Resource" uid="uid://bqq6uukbdfysr" path="res://scenes/enemies/grounded_enemy/grounded_enemy_movement.tres" id="7_caohq"] @@ -40,6 +41,11 @@ glow_enabled = true script = ExtResource("6_1hrkh") metadata/_custom_type_script = "uid://b44cse62qru7j" +[sub_resource type="Resource" id="Resource_5fa36"] +script = ExtResource("5_ybosk") +GravityModifier = 5.0 +metadata/_custom_type_script = "uid://dtpxijlnb2c5" + [sub_resource type="Resource" id="Resource_ybosk"] script = ExtResource("9_2e4ci") StartingHealth = 1.0 @@ -117,26 +123,34 @@ use_collision = true size = Vector3(6.5, 11, 5.5) material = ExtResource("2_3uydm") +[node name="FixedDashthroughTarget" parent="." instance=ExtResource("15_5fa36")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14, 3.5, 2.5) + [node name="Enemy" parent="." node_paths=PackedStringArray("Target") instance=ExtResource("3_3uydm")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -16.83681) Target = NodePath("../Player") RKnockback = SubResource("Resource_q21h6") +RMovement = SubResource("Resource_5fa36") [node name="Enemy2" parent="." node_paths=PackedStringArray("Target") instance=ExtResource("3_3uydm")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 0, -16.83681) Target = NodePath("../Player") +RMovement = SubResource("Resource_5fa36") [node name="Enemy3" parent="." node_paths=PackedStringArray("Target") instance=ExtResource("3_3uydm")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7, 0, 0.16319084) Target = NodePath("../Player") +RMovement = SubResource("Resource_5fa36") [node name="FlyingEnemy" parent="." node_paths=PackedStringArray("Target") instance=ExtResource("5_8fd2t")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8, 7, -16) Target = NodePath("../Player") +RMovement = SubResource("Resource_5fa36") [node name="FlyingEnemy2" parent="." node_paths=PackedStringArray("Target") instance=ExtResource("5_8fd2t")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10, 7, -16) Target = NodePath("../Player") +RMovement = SubResource("Resource_5fa36") [node name="GroundedSpawner" parent="." node_paths=PackedStringArray("Target") instance=ExtResource("6_7m3bq")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12, 2.5, -15) @@ -155,6 +169,3 @@ HealthInputs = ExtResource("11_2e4ci") DamageInputs = ExtResource("9_gp7s3") Target = NodePath("../Player") IsActiveOnStart = false - -[node name="FixedDashthroughTarget" parent="." instance=ExtResource("15_5fa36")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 3.5, 0) diff --git a/player_controller/PlayerController.tscn b/player_controller/PlayerController.tscn index 2351f368..b4ac0571 100644 --- a/player_controller/PlayerController.tscn +++ b/player_controller/PlayerController.tscn @@ -105,6 +105,7 @@ script = ExtResource("1_poq2x") RDamage = SubResource("Resource_cb2lu") RKnockback = SubResource("Resource_abfq8") RHealth = SubResource("Resource_ue7xq") +TargetingDistance = 5.0 WalkSpeed = 7.5 AccelerationFloor = 4.0 DecelerationFloor = 3.0 diff --git a/player_controller/Scripts/PlayerController.cs b/player_controller/Scripts/PlayerController.cs index b5316c91..7b2b8bf2 100644 --- a/player_controller/Scripts/PlayerController.cs +++ b/player_controller/Scripts/PlayerController.cs @@ -1653,15 +1653,14 @@ public partial class PlayerController : CharacterBody3D, if (!CanPerformEmpoweredAction()) return; - DashSystem.StartPreparingDash(); - DashIndicatorMesh.Visible = true; + // DashIndicatorMesh.Visible = true; if (!isOnFloorCustom()) ReduceTimeScaleWhileAiming(); } public void HandleAiming(float delta) { - DashIndicatorMeshCylinder.Height = DashSystem.PlannedLocation.DistanceTo(GlobalPosition); - DashIndicatorNode.LookAt(DashSystem.PlannedLocation); + // DashIndicatorMeshCylinder.Height = DashSystem.PlannedLocation.DistanceTo(GlobalPosition); + // DashIndicatorNode.LookAt(DashSystem.PlannedLocation); if (CanPerformEmpoweredAction()) DashSystem.PrepareDash(); @@ -1670,7 +1669,7 @@ public partial class PlayerController : CharacterBody3D, { DashSystem.StopPreparingDash(); - DashIndicatorMesh.Visible = false; + // DashIndicatorMesh.Visible = false; } /////////////////////////// @@ -1701,7 +1700,14 @@ public partial class PlayerController : CharacterBody3D, // feet of the capsule var correction = DashSystem.CollisionNormal == Vector3.Down ? _playerHeight : DashSystem.DashCastRadius; var correctedLocation = DashSystem.PlannedLocation + Vector3.Down * correction; - + + if (DashSystem.CanDashThroughTarget && DashSystem.CollidedObject is ITargetable targetable) + correctedLocation = ComputePositionAfterTargetedDash(targetable.GetTargetGlobalPosition(), DashSystem.CollisionPoint); + if (DashSystem.CollidedObject is IDamageable damageable) + _hitEnemies.Add(damageable); + // Start invincibility timer for the duration of the dash and a bit more afterwards + OnHitInvincibility(); + _preDashVelocity = Velocity; _dashDirection = (correctedLocation - GlobalPosition).Normalized(); @@ -1720,6 +1726,8 @@ public partial class PlayerController : CharacterBody3D, } public void OnAimedDashFinished() { + TriggerDamage(); + if (_customMantle) { _playerState.SendEvent("mantle"); @@ -1829,20 +1837,18 @@ public partial class PlayerController : CharacterBody3D, MantleSystem.ProcessMantle(_grounded.Active); HandleEnemyTargeting(); - if (_closeEnemyDetector.IsColliding()) - // Manage dash target and tutorial specific stuff - if (WeaponSystem.InHandState.Active && !_aiming.Active && TutorialDone) - { - DashIndicatorMesh.Visible = false; - } - if (!WeaponSystem.InHandState.Active && TutorialDone) - { - DashIndicatorMesh.Visible = true; - - DashIndicatorMeshCylinder.Height = WeaponSystem.GlobalPosition.DistanceTo(GlobalPosition) * 2; - DashIndicatorNode.LookAt(WeaponSystem.GlobalPosition); - } + // if (WeaponSystem.InHandState.Active && !_aiming.Active && TutorialDone) + // { + // DashIndicatorMesh.Visible = false; + // } + // if (!WeaponSystem.InHandState.Active && TutorialDone) + // { + // DashIndicatorMesh.Visible = true; + // + // DashIndicatorMeshCylinder.Height = WeaponSystem.GlobalPosition.DistanceTo(GlobalPosition) * 2; + // DashIndicatorNode.LookAt(WeaponSystem.GlobalPosition); + // } } /////////////////////////// @@ -1857,9 +1863,19 @@ public partial class PlayerController : CharacterBody3D, { _isEnemyInDashAttackRange = false; _closeEnemyDetector.SetRotation(HeadSystem.GetGlobalLookRotation()); - var enemyTargetState = PlayerUi.TargetState.NoTarget; var positionOnScreen = Vector2.Zero; + + if (DashSystem.CanDashThroughTarget && DashSystem.CollidedObject is ITargetable dashTarget) + { + enemyTargetState = PlayerUi.TargetState.TargetDashThrough; + _targetLocation = dashTarget.GetTargetGlobalPosition(); + positionOnScreen = _camera.UnprojectPosition(_targetLocation); + PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen)); + return; + } + + if (!_closeEnemyDetector.IsColliding()) { PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen)); @@ -1877,8 +1893,8 @@ public partial class PlayerController : CharacterBody3D, _targetLocation = target.GetTargetGlobalPosition(); var targetDistance = _targetLocation.DistanceTo(GlobalPosition); positionOnScreen = _camera.UnprojectPosition(_targetLocation); - - _isEnemyInDashAttackRange = targetDistance < TargetInRangeDistance; + + _isEnemyInDashAttackRange = true; //targetDistance < TargetInRangeDistance; // Removing the "almost dash" UI if (_isEnemyInDashAttackRange) { enemyTargetState = PlayerUi.TargetState.TargetDashThrough; @@ -1976,20 +1992,25 @@ public partial class PlayerController : CharacterBody3D, } else { - var locationOtherSide = _targetLocation + (_targetLocation - _targetHitLocation); - GlobalPosition = locationOtherSide; + GlobalPosition = ComputePositionAfterTargetedDash(_targetLocation, _targetHitLocation); var postDashVelocity = _preDashVelocity.Length() > PostDashSpeed ? _preDashVelocity.Length() : PostDashSpeed; Velocity = _dashDirection * postDashVelocity; } _isInvincible = false; _playerState.SendEvent("attack_finished"); } + + public Vector3 ComputePositionAfterTargetedDash(Vector3 targetLocation, Vector3 targetHitLocation) + { + return targetLocation + (targetLocation - targetHitLocation); + } public void OnInputHitPressed() { if (_aiming.Active && WeaponSystem.InHandState.Active) { ThrowWeapon(); + return; } var attackToDo = _isEnemyInDashAttackRange ? "dash_attack" : "standard_attack"; diff --git a/scenes/enemies/flying_enemy/flying_enemy.tscn b/scenes/enemies/flying_enemy/flying_enemy.tscn index 8e48d499..059205ee 100644 --- a/scenes/enemies/flying_enemy/flying_enemy.tscn +++ b/scenes/enemies/flying_enemy/flying_enemy.tscn @@ -60,7 +60,7 @@ RHealth = ExtResource("2_ma2bq") metadata/_custom_type_script = "uid://bjwrpv3jpsc1e" [node name="CHealthBar" parent="." instance=ExtResource("7_ykkxn")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.2, 0) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.70000005, 0) [node name="CDamageable" type="Node" parent="."] script = ExtResource("8_uotso") diff --git a/systems/dash/DashSystem.cs b/systems/dash/DashSystem.cs index 95193f59..ebf343dc 100644 --- a/systems/dash/DashSystem.cs +++ b/systems/dash/DashSystem.cs @@ -1,10 +1,11 @@ using Godot; +using Movementtests.interfaces; namespace Movementtests.systems; public partial class DashSystem: Node3D { - public record DashLocation(bool HasHit, Vector3 TargetLocation, Vector3 CollisionPoint, Vector3 CollisionNormal); + public record DashLocation(bool HasHit, Vector3 TargetLocation, Vector3 CollisionPoint, Vector3 CollisionNormal, GodotObject HitObject = null); [Export(PropertyHint.Range, "0,0.2,0.01,or_greater")] @@ -13,9 +14,11 @@ public partial class DashSystem: Node3D public float PostDashSpeed { get; set; } = 0f; public bool HasHit { get; set; } + public bool CanDashThroughTarget { get; set; } public Vector3 TargetLocation { get; set; } public Vector3 CollisionPoint { get; set; } public Vector3 CollisionNormal { get; set; } + public GodotObject CollidedObject { get; set; } public Vector3 PlannedLocation { get; set; } public bool ShouldMantle { get; set; } @@ -84,21 +87,27 @@ public partial class DashSystem: Node3D var collisionPoint = DashCast3D.GetCollisionPoint(0); var collisionNormal = DashCast3D.GetCollisionNormal(0); + var collidedObject = DashCast3D.GetCollider(0); var fraction = DashCast3D.GetClosestCollisionSafeFraction(); var globalSweepPath = targetLocation - DashCast3D.GlobalPosition; var locationAlongPath = DashCast3D.GlobalPosition + globalSweepPath * fraction; - return new DashLocation(true, locationAlongPath, collisionPoint, collisionNormal); + return new DashLocation(true, locationAlongPath, collisionPoint, collisionNormal, collidedObject); } public void PrepareDash() { DashCast3D.SetRotation(_head.GetGlobalLookRotation()); - (HasHit, PlannedLocation, CollisionPoint, CollisionNormal) = ComputeDashLocation(); + (HasHit, PlannedLocation, CollisionPoint, CollisionNormal, CollidedObject) = ComputeDashLocation(); + CanDashThroughTarget = false; + if (CollidedObject is ITargetable targetable) + { + _dashTarget.SetVisible(false); + CanDashThroughTarget = true; + return; + } - // TODO: Position mantle system to planned location, aligned with ground planned and facing the same way as the dash - // Then query it being careful when dashing underneath a platform and such MantleSystem.SetGlobalPosition(PlannedLocation); MantleSystem.SetRotation(new Vector3( MantleSystem.Rotation.X, @@ -115,6 +124,7 @@ public partial class DashSystem: Node3D _dashTarget.SetVisible(true); var targetLocation = ShouldMantle ? MantleSystem.FirstMantleProfilePoint : PlannedLocation; _dashTarget.SetGlobalPosition(targetLocation); + return; var shouldShowDropIndicator = !HasHit && !ShouldMantle; _dashDropIndicator.SetVisible(shouldShowDropIndicator); @@ -141,13 +151,9 @@ public partial class DashSystem: Node3D public void StopPreparingDash() { + CanDashThroughTarget = false; _dashTarget.SetVisible(false); _dashDropIndicator.SetVisible(false); _dashDropLocationIndicator.SetVisible(false); } - - public void StartPreparingDash() - { - _dashTarget.SetVisible(true); - } } diff --git a/systems/dash/dash_system.tscn b/systems/dash/dash_system.tscn index 04c43955..fc69ac07 100644 --- a/systems/dash/dash_system.tscn +++ b/systems/dash/dash_system.tscn @@ -28,7 +28,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0) shape = SubResource("SphereShape3D_jngg2") target_position = Vector3(0, 0, -12) max_results = 1 -collision_mask = 256 +collision_mask = 304 debug_shape_custom_color = Color(0.911631, 0.11884, 0.656218, 1) [node name="DashCastDrop" type="ShapeCast3D" parent="."] @@ -36,7 +36,7 @@ transform = Transform3D(1, 0, 0, 0, -4.371139e-08, 1, 0, -1, -4.371139e-08, 0, 1 shape = SubResource("SphereShape3D_jngg2") target_position = Vector3(0, 0, -50) max_results = 1 -collision_mask = 256 +collision_mask = 304 debug_shape_custom_color = Color(0.911631, 0.11884, 0.656218, 1) [node name="DashTarget" type="MeshInstance3D" parent="."]