diff --git a/forge/abilities/ForgeSpawnProjectileBehavior.cs b/forge/abilities/ForgeSpawnProjectileBehavior.cs index fae3471d..88fe1bcd 100644 --- a/forge/abilities/ForgeSpawnProjectileBehavior.cs +++ b/forge/abilities/ForgeSpawnProjectileBehavior.cs @@ -1,36 +1,44 @@ using Gamesmiths.Forge.Abilities; +using Gamesmiths.Forge.Core; using Gamesmiths.Forge.Effects; using Gamesmiths.Forge.Godot.Resources; using Gamesmiths.Forge.Godot.Resources.Abilities; using Godot; using Movementtests.interfaces; +using Movementtests.tools; namespace Movementtests.forge.abilities; +public record OnProjectileSpawned(Vector3 Direction, float SpeedMultiplier, Vector3? SpawnOffset = null, uint? CollisionOverride = null); -public class SpawnProjectileBehavior(PackedScene projectileScene) : IAbilityBehavior +public class SpawnProjectileBehavior(PackedScene projectileScene) : IAbilityBehavior { - public void OnStarted(AbilityBehaviorContext context) + public void OnStarted(AbilityBehaviorContext context, OnProjectileSpawned data) { - if (context.Target is not Node3D target || context.Source is not Node3D source) + if (context.Source is not Node3D source || projectileScene.Instantiate() is not Projectile projectile) { context.InstanceHandle.End(); return; } - - var sourceLocation = source.GlobalPosition; - - if (projectileScene.Instantiate() is not Projectile projectile) - { - context.InstanceHandle.End(); - return; - } - - source.GetTree().GetCurrentScene().AddChild(projectile); - var startPos = source is ITargetable targetable ? targetable.GetTargetGlobalPosition() : sourceLocation; - projectile.GlobalPosition = startPos + Vector3.Up; + source.GetTree().GetCurrentScene().AddChild(projectile); + + // Computing projectile properties + var offset = data.SpawnOffset ?? Vector3.Zero; + var startPos = source is ITargetable targetable ? targetable.GetTargetGlobalPosition() : source.GlobalPosition; + var target = context.Target as Node3D; + var magnitude = context.Magnitude != 0 ? context.Magnitude : 1; + var impulse = data.Direction * data.SpeedMultiplier * magnitude; + var collisionOverride = data.CollisionOverride ?? projectile.CollisionMask; + + GD.Print(impulse); + + // Setting up projectile + projectile.GlobalPosition = startPos + offset; projectile.Target = target; + projectile.ImpulseDirection = impulse; + projectile.CollisionMask = collisionOverride; + if (projectile is ISpawnable spawnable) spawnable.Init(); context.AbilityHandle.CommitAbility(); diff --git a/forge/forge_data.tres b/forge/forge_data.tres index 4935e8f8..6f3fda66 100644 --- a/forge/forge_data.tres +++ b/forge/forge_data.tres @@ -4,4 +4,4 @@ [resource] script = ExtResource("1_l686n") -RegisteredTags = Array[String](["character.player", "character.enemy", "status.stunned", "status.burning", "status.frozen", "abilities.weapon.land", "abilities.weapon.flying", "abilities.weapon.left", "events.combat.damage", "events.combat.hit", "events.weapon.flyingTick", "events.weapon.startedFlying", "events.weapon.stoppedFlying", "events.weapon.handToFlying", "events.weapon.flyingToHand", "events.weapon.plantedToHand", "events.weapon.plantedToFlying", "events.weapon.planted", "cooldown.empoweredAction", "cooldown.empoweredSwordThrow", "cues.resources.mana", "events.player.empowered_action_used", "cues.resources.mana.inhibited", "cues.resources.health", "cooldown.enemy.hit", "events.combat.death", "cooldown.hit", "events.player.hit", "cues.enemy.health", "immunity.damage", "status", "traits.damageable", "traits.knockbackable", "events.combat.knockback_dealt", "events.combat.knockback_received", "events.weapon.plantedtick", "events.weapon.unplanted", "abilities.weapon.planted", "events.enemy.try_hit", "events.enemy.launch_projectile", "objects.projectile", "objects.weapon", "events.enemy.request_projectile"]) +RegisteredTags = Array[String](["character.player", "character.enemy", "status.stunned", "status.burning", "status.frozen", "abilities.weapon.land", "abilities.weapon.flying", "abilities.weapon.left", "events.combat.damage", "events.combat.hit", "events.weapon.flyingTick", "events.weapon.startedFlying", "events.weapon.stoppedFlying", "events.weapon.handToFlying", "events.weapon.flyingToHand", "events.weapon.plantedToHand", "events.weapon.plantedToFlying", "events.weapon.planted", "cooldown.empoweredAction", "cooldown.empoweredSwordThrow", "cues.resources.mana", "events.player.empowered_action_used", "cues.resources.mana.inhibited", "cues.resources.health", "cooldown.enemy.hit", "events.combat.death", "cooldown.hit", "events.player.hit", "cues.enemy.health", "immunity.damage", "status", "traits.damageable", "traits.knockbackable", "events.combat.knockback_dealt", "events.combat.knockback_received", "events.weapon.plantedtick", "events.weapon.unplanted", "abilities.weapon.planted", "events.enemy.try_hit", "events.enemy.launch_projectile", "objects.projectile", "objects.weapon", "events.enemy.request_projectile", "events.player.parry"]) diff --git a/forge/resources/ability_datas/lauche_projectile.tres b/forge/resources/ability_datas/lauche_projectile.tres new file mode 100644 index 00000000..b0fd6346 --- /dev/null +++ b/forge/resources/ability_datas/lauche_projectile.tres @@ -0,0 +1,23 @@ +[gd_resource type="Resource" script_class="ForgeAbilityData" format=3 uid="uid://ckfbi6lu255ep"] + +[ext_resource type="Texture2D" uid="uid://g0u88alm6hcb" path="res://assets/ui/IconGodotNode/node/icon_bullet.png" id="1_hixal"] +[ext_resource type="PackedScene" uid="uid://bhp6qunnwhncf" path="res://scenes/projectile/Projectile.tscn" id="2_ljwqp"] +[ext_resource type="Script" uid="uid://dxtjifb8hv8k4" path="res://forge/abilities/ForgeSpawnProjectileBehavior.cs" id="3_urund"] +[ext_resource type="Resource" uid="uid://bkr1xfokymvp4" path="res://forge/resources/tag_containers/on_enemy_lauch_project.tres" id="4_5yymv"] +[ext_resource type="Script" uid="uid://dhxfbxh54pyxp" path="res://addons/forge/resources/abilities/ForgeAbilityData.cs" id="5_xbj7n"] + +[sub_resource type="Resource" id="Resource_idpl5"] +script = ExtResource("3_urund") +Projectile = ExtResource("2_ljwqp") +Name = "Spawn projectile" +Icon = ExtResource("1_hixal") +metadata/_custom_type_script = "uid://dxtjifb8hv8k4" + +[resource] +script = ExtResource("5_xbj7n") +Name = "Launch projectile" +CooldownEffects = [] +AbilityBehavior = SubResource("Resource_idpl5") +TriggerSource = 1 +TriggerTag = ExtResource("4_5yymv") +metadata/_custom_type_script = "uid://dhxfbxh54pyxp" diff --git a/maps/zoos/grounded_flying_ennemies.tscn b/maps/zoos/grounded_flying_ennemies.tscn index c45ae9ae..1bd8b362 100644 --- a/maps/zoos/grounded_flying_ennemies.tscn +++ b/maps/zoos/grounded_flying_ennemies.tscn @@ -6,10 +6,7 @@ [ext_resource type="PackedScene" uid="uid://dxt0e2ugmttqq" path="res://scenes/enemies/grounded_enemy/grounded_enemy.tscn" id="4_1cb4f"] [ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://scenes/components/movement/RMovement.cs" id="5_vuwkd"] [ext_resource type="PackedScene" uid="uid://cmlud1hwkd6sv" path="res://scenes/enemies/flying_enemy/flying_enemy.tscn" id="7_vkl5g"] -[ext_resource type="PackedScene" uid="uid://c305mfrtumcyq" path="res://scenes/spawners/spawner.tscn" id="8_1upfw"] -[ext_resource type="Resource" uid="uid://bqq6uukbdfysr" path="res://scenes/enemies/grounded_enemy/grounded_enemy_movement.tres" id="9_ynw2y"] [ext_resource type="PackedScene" uid="uid://dx3y8sjftqk8f" path="res://scenes/enemies/projectile_enemy/projectile_enemy.tscn" id="10_mm5sa"] -[ext_resource type="Resource" uid="uid://bwqjaom4k7rc3" path="res://scenes/enemies/flying_enemy/flying_enemy_movement.tres" id="11_luuoi"] [sub_resource type="Resource" id="Resource_xixm3"] script = ExtResource("5_vuwkd") @@ -115,19 +112,5 @@ RMovement = SubResource("Resource_xixm3") transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.0893264, -1.9073486e-06, -17.405575) Target = NodePath("../Player") -[node name="GroundedSpawner" parent="." index="15" unique_id=557145011 node_paths=PackedStringArray("Target") instance=ExtResource("8_1upfw")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5, 2.5, -15) -EnemyToSpawn = ExtResource("4_1cb4f") -MovementInputs = ExtResource("9_ynw2y") -Target = NodePath("../Player") -IsActiveOnStart = false - -[node name="FlyingSpawner" parent="." index="16" unique_id=974076606 node_paths=PackedStringArray("Target") instance=ExtResource("8_1upfw")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 18, 11, -14) -EnemyToSpawn = ExtResource("7_vkl5g") -MovementInputs = ExtResource("11_luuoi") -Target = NodePath("../Player") -IsActiveOnStart = false - -[node name="Player" parent="." index="18" unique_id=1309399929] +[node name="Player" parent="." index="16" unique_id=1309399929] transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, 2, 1.5, 9.5) diff --git a/scenes/enemies/Enemy.cs b/scenes/enemies/Enemy.cs index 38b17633..7cf0354d 100644 --- a/scenes/enemies/Enemy.cs +++ b/scenes/enemies/Enemy.cs @@ -13,6 +13,7 @@ using Gamesmiths.Forge.Godot.Resources.Abilities; using Gamesmiths.Forge.Statescript; using Gamesmiths.Forge.Tags; using Godot; +using Movementtests.forge.abilities; using Movementtests.interfaces; using Movementtests.scenes.components.knockback; using Movementtests.systems; @@ -135,11 +136,12 @@ public partial class Enemy : CharacterBody3D, private void ProjectileTokenRequested(EventData obj) { // TODO: replace with token manager - Events.Raise(new EventData + Events.Raise(new EventData { EventTags = Tag.RequestTag(TagsManager, "events.enemy.launch_projectile").GetSingleTagContainer()!, Source = this, - Target = Target as IForgeEntity + Target = Target as IForgeEntity, + Payload = new OnProjectileSpawned(Vector3.Up, 20, Vector3.Up) }); } @@ -150,7 +152,7 @@ public partial class Enemy : CharacterBody3D, public override void _PhysicsProcess(double delta) { - // Only trigger gameplay related effects on specific frames + // Only trigger gameplay-related effects on specific frames if(Engine.GetPhysicsFrames() % 10 == 0) ProcessGameplay(delta); var targetPlanar = new Vector3(Target.GlobalPosition.X, GlobalPosition.Y, Target.GlobalPosition.Z); diff --git a/scenes/enemies/projectile_enemy/projectile_enemy.tscn b/scenes/enemies/projectile_enemy/projectile_enemy.tscn index 11809b54..4bc5fcae 100644 --- a/scenes/enemies/projectile_enemy/projectile_enemy.tscn +++ b/scenes/enemies/projectile_enemy/projectile_enemy.tscn @@ -2,6 +2,7 @@ [ext_resource type="Script" uid="uid://bn7sc6id7n166" path="res://scenes/enemies/Enemy.cs" id="1_ha67n"] [ext_resource type="Resource" uid="uid://qpdw62ubaclc" path="res://forge/resources/ability_datas/grounded_enemy_hit.tres" id="2_nbf6l"] +[ext_resource type="Resource" uid="uid://ckfbi6lu255ep" path="res://forge/resources/ability_datas/lauche_projectile.tres" id="2_rlvdp"] [ext_resource type="Resource" uid="uid://cektf6waf4s04" path="res://scenes/enemies/grounded_enemy/grounded_enemy_knockback.tres" id="3_gciy3"] [ext_resource type="Resource" uid="uid://c3ys18t0tkbq8" path="res://scenes/enemies/projectile_enemy/projectile_enemy_knockback.tres" id="3_ymgar"] [ext_resource type="Resource" uid="uid://rchgikroifmg" path="res://scenes/enemies/projectile_enemy/projectile_enemy_movement.tres" id="4_0f52b"] @@ -15,13 +16,9 @@ [ext_resource type="PackedScene" uid="uid://dbr7ioio158ew" path="res://scenes/components/movement/CGroundedMovement.tscn" id="10_d3cra"] [ext_resource type="Script" uid="uid://1hgogislo1l6" path="res://addons/forge/resources/magnitudes/ForgeScalableInt.cs" id="11_f6vvi"] [ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://scenes/components/movement/RMovement.cs" id="11_fi4yv"] -[ext_resource type="PackedScene" uid="uid://bhp6qunnwhncf" path="res://scenes/projectile/Projectile.tscn" id="12_5ac6t"] [ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://scenes/components/knockback/CKnockback.tscn" id="12_7k8no"] -[ext_resource type="Texture2D" uid="uid://g0u88alm6hcb" path="res://assets/ui/IconGodotNode/node/icon_bullet.png" id="12_rlvdp"] [ext_resource type="Script" uid="uid://72kj3n4lm1em" path="res://addons/forge/resources/components/ForgeGrantAbilityConfig.cs" id="12_ssnfc"] [ext_resource type="Script" uid="uid://b3wo2uge4ddnj" path="res://addons/forge/resources/components/GrantAbility.cs" id="13_5ac6t"] -[ext_resource type="Script" uid="uid://dxtjifb8hv8k4" path="res://forge/abilities/ForgeSpawnProjectileBehavior.cs" id="13_rlvdp"] -[ext_resource type="Resource" uid="uid://bkr1xfokymvp4" path="res://forge/resources/tag_containers/on_enemy_lauch_project.tres" id="13_ssnfc"] [ext_resource type="Script" uid="uid://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="14_rlvdp"] [ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="17_xabdf"] [ext_resource type="Script" uid="uid://br7ut4lbau66w" path="res://forge/calculators/ForgeRaiseEventTagExecution.cs" id="18_ufku3"] @@ -50,32 +47,6 @@ AbilityData = ExtResource("2_nbf6l") AbilityLevel = SubResource("Resource_55uge") metadata/_custom_type_script = "uid://72kj3n4lm1em" -[sub_resource type="Resource" id="Resource_idpl5"] -script = ExtResource("13_rlvdp") -Projectile = ExtResource("12_5ac6t") -Name = "Spawn projectile" -Icon = ExtResource("12_rlvdp") -metadata/_custom_type_script = "uid://dxtjifb8hv8k4" - -[sub_resource type="Resource" id="Resource_5ac6t"] -script = ExtResource("10_b62xo") -Name = "Launch projectile" -CooldownEffects = [] -AbilityBehavior = SubResource("Resource_idpl5") -TriggerSource = 1 -TriggerTag = ExtResource("13_ssnfc") -metadata/_custom_type_script = "uid://dhxfbxh54pyxp" - -[sub_resource type="Resource" id="Resource_rlvdp"] -script = ExtResource("11_f6vvi") -BaseValue = 1 - -[sub_resource type="Resource" id="Resource_ei7hs"] -script = ExtResource("12_ssnfc") -AbilityData = SubResource("Resource_5ac6t") -AbilityLevel = SubResource("Resource_rlvdp") -metadata/_custom_type_script = "uid://72kj3n4lm1em" - [sub_resource type="Resource" id="Resource_5xe4r"] script = ExtResource("17_xabdf") ContainerTags = Array[String](["events.enemy.request_projectile"]) @@ -136,9 +107,19 @@ AbilityLevel = SubResource("Resource_r40oc") TryActivateOnGrant = true metadata/_custom_type_script = "uid://72kj3n4lm1em" +[sub_resource type="Resource" id="Resource_rlvdp"] +script = ExtResource("11_f6vvi") +BaseValue = 1 + +[sub_resource type="Resource" id="Resource_ei7hs"] +script = ExtResource("12_ssnfc") +AbilityData = ExtResource("2_rlvdp") +AbilityLevel = SubResource("Resource_rlvdp") +metadata/_custom_type_script = "uid://72kj3n4lm1em" + [sub_resource type="Resource" id="Resource_ufku3"] script = ExtResource("13_5ac6t") -GrantAbilityConfigs = [SubResource("Resource_xabdf"), SubResource("Resource_ei7hs"), SubResource("Resource_nu2lf")] +GrantAbilityConfigs = [SubResource("Resource_xabdf"), SubResource("Resource_nu2lf"), SubResource("Resource_ei7hs")] metadata/_custom_type_script = "uid://b3wo2uge4ddnj" [sub_resource type="Resource" id="Resource_hgi6f"] @@ -196,6 +177,7 @@ collision_layer = 16 collision_mask = 273 script = ExtResource("1_ha67n") EnemyHeight = 2.0 +LaunchProjectileAbility = ExtResource("2_rlvdp") RKnockback = ExtResource("3_ymgar") RMovement = ExtResource("4_0f52b") diff --git a/scenes/player_controller/PlayerController.tscn b/scenes/player_controller/PlayerController.tscn index 117f0bc0..5a75da5d 100644 --- a/scenes/player_controller/PlayerController.tscn +++ b/scenes/player_controller/PlayerController.tscn @@ -14,6 +14,7 @@ [ext_resource type="PackedScene" uid="uid://duju3atqgltkg" path="res://scenes/explosion/explosion.tscn" id="5_ue7xq"] [ext_resource type="Resource" uid="uid://t612lts1wi1s" path="res://inputs/base_mode/move_right.tres" id="6_q7bng"] [ext_resource type="Resource" uid="uid://cffil4tic3ysg" path="res://forge/resources/effect_datas/inhibit_mana_regen_temporarily.tres" id="6_u8yay"] +[ext_resource type="Texture2D" uid="uid://g0u88alm6hcb" path="res://assets/ui/IconGodotNode/node/icon_bullet.png" id="7_2rkt1"] [ext_resource type="Script" uid="uid://cwbvxlfvmocc1" path="res://scenes/player_controller/scripts/StairsSystem.cs" id="7_bmt5a"] [ext_resource type="Resource" uid="uid://brswsknpgwal2" path="res://inputs/base_mode/move_front.tres" id="7_m8gvy"] [ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://scenes/components/knockback/CKnockback.tscn" id="7_x835q"] @@ -22,10 +23,13 @@ [ext_resource type="Resource" uid="uid://bs8b0oojixm4q" path="res://scenes/player_controller/resources/player_knockback.tres" id="8_m8gvy"] [ext_resource type="Resource" uid="uid://c3e0ivgaxrsyb" path="res://inputs/base_mode/aim_down.tres" id="8_obsfv"] [ext_resource type="PackedScene" uid="uid://wq1okogkhc5l" path="res://scenes/player_controller/components/mantle/mantle_system.tscn" id="8_qu4wy"] +[ext_resource type="PackedScene" uid="uid://bhp6qunnwhncf" path="res://scenes/projectile/Projectile.tscn" id="8_u8yay"] [ext_resource type="AudioStream" uid="uid://clfggn87oeg1s" path="res://scenes/player_controller/audio/InteractiveSFX.tres" id="9_jb43f"] [ext_resource type="Resource" uid="uid://bebstkm608wxx" path="res://inputs/base_mode/aim_pressed.tres" id="9_nob5r"] +[ext_resource type="Script" uid="uid://dxtjifb8hv8k4" path="res://forge/abilities/ForgeSpawnProjectileBehavior.cs" id="9_uqalc"] [ext_resource type="Resource" uid="uid://dccuj66egxfwh" path="res://forge/resources/ability_datas/empowered_action.tres" id="10_2rkt1"] [ext_resource type="Resource" uid="uid://bdit2jy5gbpts" path="res://inputs/base_mode/jump.tres" id="10_4u7i3"] +[ext_resource type="Script" uid="uid://dhxfbxh54pyxp" path="res://addons/forge/resources/abilities/ForgeAbilityData.cs" id="10_b0xmb"] [ext_resource type="Script" uid="uid://cxihb42t2mfqi" path="res://addons/forge/nodes/ForgeAttributeSet.cs" id="10_pw5r7"] [ext_resource type="Script" uid="uid://ccovd5i0wr3kk" path="res://addons/forge/editor/attributes/AttributeValues.cs" id="11_2rkt1"] [ext_resource type="Resource" uid="uid://b5gx3q8nvu72e" path="res://inputs/base_mode/hit.tres" id="11_cresl"] @@ -70,6 +74,27 @@ script = ExtResource("11_u8yay") Tag = "immunity.damage" metadata/_custom_type_script = "uid://dpakv7agvir6y" +[sub_resource type="Resource" id="Resource_xs7wf"] +script = ExtResource("9_uqalc") +Projectile = ExtResource("8_u8yay") +Name = "Spawn projectile on parry" +Icon = ExtResource("7_2rkt1") +metadata/_custom_type_script = "uid://dxtjifb8hv8k4" + +[sub_resource type="Resource" id="Resource_cm4e8"] +script = ExtResource("11_u8yay") +Tag = "events.player.parry" +metadata/_custom_type_script = "uid://dpakv7agvir6y" + +[sub_resource type="Resource" id="Resource_cmmfb"] +script = ExtResource("10_b0xmb") +Name = "Parry projectile" +CooldownEffects = null +AbilityBehavior = SubResource("Resource_xs7wf") +TriggerSource = 1 +TriggerTag = SubResource("Resource_cm4e8") +metadata/_custom_type_script = "uid://dhxfbxh54pyxp" + [sub_resource type="Resource" id="Resource_abfq8"] script = ExtResource("3_cb2lu") Modifier = 5.0 @@ -106,6 +131,9 @@ radius = 0.45 [sub_resource type="SphereShape3D" id="SphereShape3D_q14ux"] radius = 1.0 +[sub_resource type="SphereShape3D" id="SphereShape3D_n24vh"] +radius = 2.25 + [sub_resource type="SphereShape3D" id="SphereShape3D_u8rdp"] radius = 1.5 @@ -149,7 +177,7 @@ EmpoweredActionUsed = SubResource("Resource_5gbhg") InvincibleTag = SubResource("Resource_2rkt1") HitAbility = ExtResource("4_u8yay") EmpoweredActionAbility = ExtResource("10_2rkt1") -DefaultGrantedAbilities = [ExtResource("5_u8yay")] +DefaultGrantedAbilities = [ExtResource("5_u8yay"), SubResource("Resource_cmmfb")] DefaultPermanentEffects = [ExtResource("5_2rkt1")] EmpoweredActionEffects = [ExtResource("6_u8yay")] AimAssistStrength = 0.3 @@ -289,18 +317,28 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.6, 0) MantleEndLocationDistanceFromWall = 0.3 MantleHeightCastStart = 2.5 -[node name="WeaponHitbox" type="Area3D" parent="HeadSystem" unique_id=616313905] +[node name="WeaponHitbox" type="Area3D" parent="." unique_id=616313905] unique_name_in_owner = true -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.6, 0) collision_layer = 0 collision_mask = 16 monitoring = false monitorable = false -[node name="CollisionShape3D" type="CollisionShape3D" parent="HeadSystem/WeaponHitbox" unique_id=1617373708] +[node name="CollisionShape3D" type="CollisionShape3D" parent="WeaponHitbox" unique_id=1617373708] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -1.5) shape = SubResource("SphereShape3D_q14ux") +[node name="Parrybox" type="Area3D" parent="." unique_id=1452001086] +unique_name_in_owner = true +collision_layer = 0 +collision_mask = 48 +monitoring = false +monitorable = false + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Parrybox" unique_id=619469543] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -2) +shape = SubResource("SphereShape3D_n24vh") + [node name="StairsSystem" type="Node3D" parent="." unique_id=703342681] script = ExtResource("7_bmt5a") diff --git a/scenes/player_controller/components/head/HeadSystem.cs b/scenes/player_controller/components/head/HeadSystem.cs index 102cf857..23c34eca 100644 --- a/scenes/player_controller/components/head/HeadSystem.cs +++ b/scenes/player_controller/components/head/HeadSystem.cs @@ -180,11 +180,11 @@ public partial class HeadSystem : Node3D public void OnParryboxActivated() { - EmitSignalHitboxActivated(); + EmitSignalParryboxActivated(); } public void OnParryboxDeactivated() { - EmitSignalHitboxDeactivated(); + EmitSignalParryboxDeactivated(); } internal bool FootstepEmitted; diff --git a/scenes/player_controller/components/head/head_system.tscn b/scenes/player_controller/components/head/head_system.tscn index 0cd0b563..16afb7e3 100644 --- a/scenes/player_controller/components/head/head_system.tscn +++ b/scenes/player_controller/components/head/head_system.tscn @@ -579,12 +579,12 @@ tracks/3/keys = { } tracks/4/type = "method" tracks/4/imported = false -tracks/4/enabled = false +tracks/4/enabled = true tracks/4/path = NodePath("../..") tracks/4/interp = 1 tracks/4/loop_wrap = true tracks/4/keys = { -"times": PackedFloat32Array(0.06666667, 0.18333334), +"times": PackedFloat32Array(0.01666667, 0.16666667), "transitions": PackedFloat32Array(1, 1), "values": [{ "args": [], diff --git a/scenes/player_controller/scripts/PlayerController.cs b/scenes/player_controller/scripts/PlayerController.cs index 80167769..8768d415 100644 --- a/scenes/player_controller/scripts/PlayerController.cs +++ b/scenes/player_controller/scripts/PlayerController.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Chickensoft.AutoInject; using Chickensoft.Introspection; using Chickensoft.Sync.Primitives; @@ -22,6 +23,7 @@ using Godot; using GodotStateCharts; using Movementtests.addons.godot_state_charts.csharp; +using Movementtests.forge.abilities; using Movementtests.interfaces; using Movementtests.systems; using Movementtests.player_controller.Scripts; @@ -39,6 +41,8 @@ public record struct EmpoweredActionPayload; public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandler, IDisposable, ITargetable { public override void _Notification(int what) => this.Notify(what); + + public record struct OnParryPayload(Vector3 ForwardVector); #region Dependencies [Dependency] @@ -97,6 +101,7 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl [Node("CeilingDetector")] public required ShapeCast3D CeilingDetector { get; set; } [Node("DirectGroundDetector")] public required RayCast3D DirectGroundDetector { get; set; } [Node("%WeaponHitbox")] public required Area3D WeaponHitbox { get; set; } + [Node("%Parrybox")] public required Area3D Parrybox { get; set; } [Node("SFXPlayer")] public required AudioStreamPlayer3D SfxPlayer { get; set; } [Node("DashDamage")] public required ShapeCast3D DashDamageDetector { get; set; } [Node("SlidingEnemyDetector")] public required Area3D SlidingEnemyDetector { get; set; } @@ -461,6 +466,7 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl // Damage dealing private readonly List _hitEnemies = []; + private readonly List _parriedEntities = []; #endregion @@ -506,8 +512,8 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl _playerRadius = playerShape.Radius; // Combat stuff - WeaponHitbox.Monitoring = false; WeaponHitbox.BodyEntered += RegisterHitEnnemy; + Parrybox.BodyEntered += RegisterParry; #region StateManagement @@ -569,6 +575,8 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl HeadSystem.Init(); HeadSystem.HitboxActivated += OnHitboxActivated; HeadSystem.HitboxDeactivated += OnHitboxDeactivated; + HeadSystem.ParryboxActivated += OnParryboxActivated; + HeadSystem.ParryboxDeactivated += OnParryboxDeactivated; HeadSystem.StepFoot += OnFootStepped; HeadSystem.DeathAnimationFinished += OnDeathAnimationFinished; @@ -1150,6 +1158,9 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl var wallHugContactPoint = _onWallRunning.Active ? _currentWallContactPoint : Vector3.Zero; var moveInput = GetGlobalMoveInput(); + + WeaponHitbox.SetRotation(HeadSystem.GetGlobalLookRotation()); + Parrybox.SetRotation(HeadSystem.GetGlobalLookRotation()); if (_isUsingGamepad) inputLookDir += ComputeAimAssist(); @@ -2125,7 +2136,7 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl if (!HasParry) return; var attackToDo = _isEnemyInDashAttackRange ? "dash_parry" : "standard_parry"; - _playerState.SendEvent(attackToDo); + _playerState.SendEvent("standard_parry"); } /////////////////////////// @@ -2579,14 +2590,49 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl WeaponHitbox.Monitoring = false; TriggerDamage(); } + + public void OnParryboxActivated() + { + Parrybox.Monitoring = true; + } + public void OnParryboxDeactivated() + { + Parrybox.Monitoring = false; + TriggerParry(); + } public void RegisterHitEnnemy(Node3D body) { if (body is not IForgeEntity entity) return; _hitEnemies.Add(entity); - // return; - // if (body is not IDamageable damageable) return; - // _hitEnemies.Add(damageable); + } + public void RegisterParry(Node3D body) + { + if (body is not IForgeEntity entity) return; + _parriedEntities.Add(entity); + // TriggerParry(); + } + + public void TriggerParry() + { + var payload = new OnProjectileSpawned( + Direction: -HeadSystem.GetGlobalForwardVector(), + SpeedMultiplier: 100, + SpawnOffset: -HeadSystem.GetGlobalForwardVector(), + CollisionOverride: WeaponSystem.CollisionMask); + foreach (var entity in _parriedEntities.Where(entity => IsInstanceValid(entity as Node))) + { + Events.Raise(new EventData + { + EventTags = Tag.RequestTag(TagsManager, "events.player.parry").GetSingleTagContainer()!, + Source = this, + Payload = payload + }); + + if (entity is IKillable killable) killable.Kill(); + else if (entity is Node node) node.QueueFree(); + } + _parriedEntities.Clear(); } public void TriggerDamage() diff --git a/scenes/projectile/Projectile.cs b/scenes/projectile/Projectile.cs index 932df59a..f86a2c41 100644 --- a/scenes/projectile/Projectile.cs +++ b/scenes/projectile/Projectile.cs @@ -72,6 +72,7 @@ public partial class Projectile : RigidBody3D, IForgeEntity, ITargetable, IKilla [Export] public float HomingFactor = 0.2f; public Node3D? Target { get; set; } + public Vector3? ImpulseDirection { get; set; } public void Init() { @@ -80,6 +81,7 @@ public partial class Projectile : RigidBody3D, IForgeEntity, ITargetable, IKilla public Vector3 ComputeImpulseToTarget() { + if (ImpulseDirection != null) return ImpulseDirection.Value; if (Target == null) return Vector3.Zero; return Vector3.Up * Speed; @@ -93,6 +95,7 @@ public partial class Projectile : RigidBody3D, IForgeEntity, ITargetable, IKilla public override void _IntegrateForces(PhysicsDirectBodyState3D state) { + base._IntegrateForces(state); if (Target == null) return; var targetPos = Target is ITargetable targetable ? targetable.GetTargetGlobalPosition() : Target.GlobalPosition; var targetVel = state.LinearVelocity + GlobalPosition.DirectionTo(targetPos) * HomingFactor;