added fixed dash targets and can dash towards enemies to hit them, get a knockback or dash through if killed
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAction_00601_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F7c0f83388bfc4d2c9d09befcec9dd79bc90908_003Fb8_003F4d300c4d_003FAction_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAction_00601_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F7c0f83388bfc4d2c9d09befcec9dd79bc90908_003Fb8_003F4d300c4d_003FAction_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACharacterBody3D_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fe56b84c3fa498fb86fc1eba376f62f482127e3fe80415c5fb2acde2bf6d89793_003FCharacterBody3D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnemy_005FScriptMethods_002Egenerated_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F8e71dc81611862c01a2cb998a1f327de14747655_003FEnemy_005FScriptMethods_002Egenerated_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnemy_005FScriptMethods_002Egenerated_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F8e71dc81611862c01a2cb998a1f327de14747655_003FEnemy_005FScriptMethods_002Egenerated_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANode_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fdf73a4db74df89d59655c5fb6326406f47fbfa9af1fa81518fe0a07c49d34133_003FNode_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANode_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fdf73a4db74df89d59655c5fb6326406f47fbfa9af1fa81518fe0a07c49d34133_003FNode_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASceneTree_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F8d6960554e939a669841b1ece03d27df4ab42f92bb80be3767eaec8cdaccf84b_003FSceneTree_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASceneTree_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F8d6960554e939a669841b1ece03d27df4ab42f92bb80be3767eaec8cdaccf84b_003FSceneTree_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
|||||||
@@ -20,4 +20,12 @@ public partial class CDamageable : Node, IDamageable
|
|||||||
DamageTaken?.Invoke(this, finalDamageRecord);
|
DamageTaken?.Invoke(this, finalDamageRecord);
|
||||||
return finalDamageRecord;
|
return finalDamageRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DamageRecord ComputeDamage(DamageRecord damageRecord)
|
||||||
|
{
|
||||||
|
var finalDamage = 0f;
|
||||||
|
foreach (var damageable in DamageModifiers.ToIDamageables())
|
||||||
|
finalDamage += damageable.ComputeDamage(damageRecord).Damage.DamageDealt;
|
||||||
|
return damageRecord with { Damage = new RDamage(finalDamage, damageRecord.Damage.DamageType) };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,4 +30,13 @@ public partial class RDamageModifier : Resource, IDamageable
|
|||||||
DamageTaken?.Invoke(this, finalDamageRecord);
|
DamageTaken?.Invoke(this, finalDamageRecord);
|
||||||
return finalDamageRecord;
|
return finalDamageRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DamageRecord ComputeDamage(DamageRecord damageRecord)
|
||||||
|
{
|
||||||
|
if (damageRecord.Damage.DamageType != DamageType)
|
||||||
|
return damageRecord with { Damage = new RDamage(0, damageRecord.Damage.DamageType) };
|
||||||
|
|
||||||
|
var finalDamage = damageRecord.Damage.DamageDealt * Modifier;
|
||||||
|
return damageRecord with { Damage = new RDamage(finalDamage, damageRecord.Damage.DamageType) };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public partial class CKnockback : Node3D, IKnockbackable
|
|||||||
|
|
||||||
var knockbackDirection = GlobalPosition - _damageRecord.Source.GlobalPosition;
|
var knockbackDirection = GlobalPosition - _damageRecord.Source.GlobalPosition;
|
||||||
_damageRecord = null;
|
_damageRecord = null;
|
||||||
return knockbackDirection.Normalized() * RKnockback.Modifier;
|
var finalKnockback = knockbackDirection.Normalized() * RKnockback.Modifier;
|
||||||
|
return finalKnockback;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,4 +9,5 @@ public interface IDamageable
|
|||||||
{
|
{
|
||||||
event Action<IDamageable, DamageRecord> DamageTaken;
|
event Action<IDamageable, DamageRecord> DamageTaken;
|
||||||
DamageRecord TakeDamage(DamageRecord damageRecord);
|
DamageRecord TakeDamage(DamageRecord damageRecord);
|
||||||
|
DamageRecord ComputeDamage(DamageRecord damageRecord);
|
||||||
}
|
}
|
||||||
12
interfaces/IStunnable.cs
Normal file
12
interfaces/IStunnable.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Movementtests.interfaces;
|
||||||
|
|
||||||
|
public interface IStunnable
|
||||||
|
{
|
||||||
|
bool IsStunned { get; set; }
|
||||||
|
[Export] float StunDuration { get; set; }
|
||||||
|
|
||||||
|
void Stun();
|
||||||
|
void Unstun();
|
||||||
|
}
|
||||||
1
interfaces/IStunnable.cs.uid
Normal file
1
interfaces/IStunnable.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://cr8ify1hgetw6
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
[gd_scene load_steps=24 format=3 uid="uid://q7uc1h2jpbd2"]
|
[gd_scene load_steps=25 format=3 uid="uid://q7uc1h2jpbd2"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://bei4nhkf8lwdo" path="res://player_controller/PlayerController.tscn" id="1_62kkh"]
|
[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="Material" uid="uid://31aulub2nqov" path="res://assets/greybox/m_greybox.tres" id="2_3uydm"]
|
||||||
[ext_resource type="Script" uid="uid://jitubgv6judn" path="res://components/damage/RDamage.cs" id="2_sysok"]
|
|
||||||
[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://dxt0e2ugmttqq" path="res://scenes/enemies/grounded_enemy/grounded_enemy.tscn" id="3_3uydm"]
|
||||||
[ext_resource type="Script" uid="uid://b4cwruitopcee" path="res://components/health/RDeathEffect.cs" id="5_7m3bq"]
|
[ext_resource type="Script" uid="uid://b4cwruitopcee" path="res://components/health/RDeathEffect.cs" id="5_7m3bq"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cmlud1hwkd6sv" path="res://scenes/enemies/flying_enemy/flying_enemy.tscn" id="5_8fd2t"]
|
[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://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="PackedScene" uid="uid://c305mfrtumcyq" path="res://scenes/spawners/spawner.tscn" id="6_7m3bq"]
|
||||||
[ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://components/movement/RMovement.cs" id="6_ybosk"]
|
[ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://components/movement/RMovement.cs" id="6_ybosk"]
|
||||||
[ext_resource type="Resource" uid="uid://bqq6uukbdfysr" path="res://scenes/enemies/grounded_enemy/grounded_enemy_movement.tres" id="7_caohq"]
|
[ext_resource type="Resource" uid="uid://bqq6uukbdfysr" path="res://scenes/enemies/grounded_enemy/grounded_enemy_movement.tres" id="7_caohq"]
|
||||||
@@ -14,10 +14,7 @@
|
|||||||
[ext_resource type="Resource" uid="uid://dgo65k2ceqfvy" path="res://scenes/enemies/flying_enemy/flying_enemy_damage.tres" id="9_gp7s3"]
|
[ext_resource type="Resource" uid="uid://dgo65k2ceqfvy" path="res://scenes/enemies/flying_enemy/flying_enemy_damage.tres" id="9_gp7s3"]
|
||||||
[ext_resource type="Resource" uid="uid://bwqjaom4k7rc3" path="res://scenes/enemies/flying_enemy/flying_enemy_movement.tres" id="10_spw1u"]
|
[ext_resource type="Resource" uid="uid://bwqjaom4k7rc3" path="res://scenes/enemies/flying_enemy/flying_enemy_movement.tres" id="10_spw1u"]
|
||||||
[ext_resource type="Resource" uid="uid://dg1xbjhyhgnnk" path="res://scenes/enemies/flying_enemy/flying_enemy_health.tres" id="11_2e4ci"]
|
[ext_resource type="Resource" uid="uid://dg1xbjhyhgnnk" path="res://scenes/enemies/flying_enemy/flying_enemy_health.tres" id="11_2e4ci"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://qup00a7x2sji" path="res://scenes/FixedDashTarget/fixed_dashthrough_target.tscn" id="15_5fa36"]
|
||||||
[sub_resource type="Resource" id="Resource_2e4ci"]
|
|
||||||
script = ExtResource("2_sysok")
|
|
||||||
metadata/_custom_type_script = "uid://jitubgv6judn"
|
|
||||||
|
|
||||||
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_0xm2m"]
|
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_0xm2m"]
|
||||||
sky_horizon_color = Color(0.662243, 0.671743, 0.686743, 1)
|
sky_horizon_color = Color(0.662243, 0.671743, 0.686743, 1)
|
||||||
@@ -45,6 +42,10 @@ glow_enabled = true
|
|||||||
script = ExtResource("5_7m3bq")
|
script = ExtResource("5_7m3bq")
|
||||||
metadata/_custom_type_script = "uid://b4cwruitopcee"
|
metadata/_custom_type_script = "uid://b4cwruitopcee"
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_q21h6"]
|
||||||
|
script = ExtResource("6_1hrkh")
|
||||||
|
metadata/_custom_type_script = "uid://b44cse62qru7j"
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_5fa36"]
|
[sub_resource type="Resource" id="Resource_5fa36"]
|
||||||
script = ExtResource("6_ybosk")
|
script = ExtResource("6_ybosk")
|
||||||
GravityModifier = 1.0
|
GravityModifier = 1.0
|
||||||
@@ -70,7 +71,6 @@ metadata/_custom_type_script = "uid://baiapod3csndf"
|
|||||||
[node name="Player" parent="." instance=ExtResource("1_62kkh")]
|
[node name="Player" parent="." instance=ExtResource("1_62kkh")]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 7.5)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 7.5)
|
||||||
TutorialDone = true
|
TutorialDone = true
|
||||||
RDamage = SubResource("Resource_2e4ci")
|
|
||||||
|
|
||||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
environment = SubResource("Environment_1bvp3")
|
environment = SubResource("Environment_1bvp3")
|
||||||
@@ -120,6 +120,12 @@ use_collision = true
|
|||||||
size = Vector3(6.5, 11, 5.5)
|
size = Vector3(6.5, 11, 5.5)
|
||||||
material = ExtResource("2_3uydm")
|
material = ExtResource("2_3uydm")
|
||||||
|
|
||||||
|
[node name="CSGBox3D9" type="CSGBox3D" parent="Greybox"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 50.154, 0, -20.4585)
|
||||||
|
use_collision = true
|
||||||
|
size = Vector3(6.5, 2, 116)
|
||||||
|
material = ExtResource("2_3uydm")
|
||||||
|
|
||||||
[node name="CSGBox3D4" type="CSGBox3D" parent="Greybox"]
|
[node name="CSGBox3D4" type="CSGBox3D" parent="Greybox"]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 18.154, 4.5, -14.2085)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 18.154, 4.5, -14.2085)
|
||||||
use_collision = true
|
use_collision = true
|
||||||
@@ -136,16 +142,19 @@ material = ExtResource("2_3uydm")
|
|||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -16.83681)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -16.83681)
|
||||||
Target = NodePath("../Player")
|
Target = NodePath("../Player")
|
||||||
DeathEffects = Array[Object]([SubResource("Resource_sysok")])
|
DeathEffects = Array[Object]([SubResource("Resource_sysok")])
|
||||||
|
RKnockback = SubResource("Resource_q21h6")
|
||||||
RMovement = SubResource("Resource_5fa36")
|
RMovement = SubResource("Resource_5fa36")
|
||||||
|
|
||||||
[node name="Enemy2" parent="." node_paths=PackedStringArray("Target") instance=ExtResource("3_3uydm")]
|
[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)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 0, -16.83681)
|
||||||
Target = NodePath("../Player")
|
Target = NodePath("../Player")
|
||||||
|
RKnockback = SubResource("Resource_q21h6")
|
||||||
RMovement = SubResource("Resource_blhrq")
|
RMovement = SubResource("Resource_blhrq")
|
||||||
|
|
||||||
[node name="Enemy3" parent="." node_paths=PackedStringArray("Target") instance=ExtResource("3_3uydm")]
|
[node name="Enemy3" parent="." node_paths=PackedStringArray("Target") instance=ExtResource("3_3uydm")]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.5, 0, -16.83681)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7, 0, 0.16319084)
|
||||||
Target = NodePath("../Player")
|
Target = NodePath("../Player")
|
||||||
|
RKnockback = SubResource("Resource_q21h6")
|
||||||
RMovement = SubResource("Resource_5fa36")
|
RMovement = SubResource("Resource_5fa36")
|
||||||
|
|
||||||
[node name="FlyingEnemy" parent="." node_paths=PackedStringArray("Target") instance=ExtResource("5_8fd2t")]
|
[node name="FlyingEnemy" parent="." node_paths=PackedStringArray("Target") instance=ExtResource("5_8fd2t")]
|
||||||
@@ -175,3 +184,6 @@ HealthInputs = ExtResource("11_2e4ci")
|
|||||||
DamageInputs = ExtResource("9_gp7s3")
|
DamageInputs = ExtResource("9_gp7s3")
|
||||||
Target = NodePath("../Player")
|
Target = NodePath("../Player")
|
||||||
IsActiveOnStart = false
|
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)
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
[gd_scene load_steps=58 format=3 uid="uid://bei4nhkf8lwdo"]
|
[gd_scene load_steps=64 format=3 uid="uid://bei4nhkf8lwdo"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://bbbrf5ckydfna" path="res://player_controller/Scripts/PlayerController.cs" id="1_poq2x"]
|
[ext_resource type="Script" uid="uid://bbbrf5ckydfna" path="res://player_controller/Scripts/PlayerController.cs" id="1_poq2x"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cf3rrgr1imvv4" path="res://scenes/path/path.tscn" id="2_6lejt"]
|
[ext_resource type="PackedScene" uid="uid://cf3rrgr1imvv4" path="res://scenes/path/path.tscn" id="2_6lejt"]
|
||||||
|
[ext_resource type="Script" uid="uid://jitubgv6judn" path="res://components/damage/RDamage.cs" id="2_x835q"]
|
||||||
|
[ext_resource type="Script" uid="uid://b44cse62qru7j" path="res://components/knockback/RKnockback.cs" id="3_cb2lu"]
|
||||||
[ext_resource type="Resource" uid="uid://bl5crtu1gkrtr" path="res://systems/inputs/base_mode/base_mode.tres" id="3_cresl"]
|
[ext_resource type="Resource" uid="uid://bl5crtu1gkrtr" path="res://systems/inputs/base_mode/base_mode.tres" id="3_cresl"]
|
||||||
[ext_resource type="PackedScene" uid="uid://c4ikbhojckpnc" path="res://components/health/CHealth.tscn" id="3_q7bng"]
|
[ext_resource type="PackedScene" uid="uid://c4ikbhojckpnc" path="res://components/health/CHealth.tscn" id="3_q7bng"]
|
||||||
|
[ext_resource type="Script" uid="uid://baiapod3csndf" path="res://components/health/RHealth.cs" id="4_abfq8"]
|
||||||
[ext_resource type="Resource" uid="uid://bjyd801wvverk" path="res://player_controller/resources/player_health.tres" id="4_m8gvy"]
|
[ext_resource type="Resource" uid="uid://bjyd801wvverk" path="res://player_controller/resources/player_health.tres" id="4_m8gvy"]
|
||||||
[ext_resource type="Resource" uid="uid://cpdaw41ah5gic" path="res://systems/inputs/base_mode/rotate_y.tres" id="4_rxwoh"]
|
[ext_resource type="Resource" uid="uid://cpdaw41ah5gic" path="res://systems/inputs/base_mode/rotate_y.tres" id="4_rxwoh"]
|
||||||
[ext_resource type="Resource" uid="uid://ccrb5xsnphc8" path="res://systems/inputs/base_mode/rotate_floorplane.tres" id="5_4u7i3"]
|
[ext_resource type="Resource" uid="uid://ccrb5xsnphc8" path="res://systems/inputs/base_mode/rotate_floorplane.tres" id="5_4u7i3"]
|
||||||
@@ -49,6 +52,21 @@
|
|||||||
[ext_resource type="Script" uid="uid://b4dwolbvt8our" path="res://addons/godot_state_charts/history_state.gd" id="41_ruloh"]
|
[ext_resource type="Script" uid="uid://b4dwolbvt8our" path="res://addons/godot_state_charts/history_state.gd" id="41_ruloh"]
|
||||||
[ext_resource type="Texture2D" uid="uid://buu21kg4kkhiw" path="res://guide_examples/shared/fireball/fireball.svg" id="42_cmijs"]
|
[ext_resource type="Texture2D" uid="uid://buu21kg4kkhiw" path="res://guide_examples/shared/fireball/fireball.svg" id="42_cmijs"]
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_cb2lu"]
|
||||||
|
script = ExtResource("2_x835q")
|
||||||
|
DamageDealt = 3.0
|
||||||
|
metadata/_custom_type_script = "uid://jitubgv6judn"
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_abfq8"]
|
||||||
|
script = ExtResource("3_cb2lu")
|
||||||
|
Modifier = 10.0
|
||||||
|
metadata/_custom_type_script = "uid://b44cse62qru7j"
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_ue7xq"]
|
||||||
|
script = ExtResource("4_abfq8")
|
||||||
|
StartingHealth = 10.0
|
||||||
|
metadata/_custom_type_script = "uid://baiapod3csndf"
|
||||||
|
|
||||||
[sub_resource type="CapsuleMesh" id="CapsuleMesh_xc2g5"]
|
[sub_resource type="CapsuleMesh" id="CapsuleMesh_xc2g5"]
|
||||||
height = 1.7
|
height = 1.7
|
||||||
|
|
||||||
@@ -58,9 +76,6 @@ radius = 0.45
|
|||||||
[sub_resource type="SphereShape3D" id="SphereShape3D_q14ux"]
|
[sub_resource type="SphereShape3D" id="SphereShape3D_q14ux"]
|
||||||
radius = 1.0
|
radius = 1.0
|
||||||
|
|
||||||
[sub_resource type="SphereShape3D" id="SphereShape3D_cmijs"]
|
|
||||||
radius = 1.0
|
|
||||||
|
|
||||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_nodcl"]
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_nodcl"]
|
||||||
transparency = 1
|
transparency = 1
|
||||||
albedo_color = Color(0, 0.627451, 0.6313726, 0.49019608)
|
albedo_color = Color(0, 0.627451, 0.6313726, 0.49019608)
|
||||||
@@ -71,6 +86,9 @@ top_radius = 0.2
|
|||||||
bottom_radius = 0.2
|
bottom_radius = 0.2
|
||||||
height = 1.0
|
height = 1.0
|
||||||
|
|
||||||
|
[sub_resource type="SphereShape3D" id="SphereShape3D_cmijs"]
|
||||||
|
radius = 1.0
|
||||||
|
|
||||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_6lejt"]
|
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_6lejt"]
|
||||||
radius = 1.0
|
radius = 1.0
|
||||||
height = 3.5
|
height = 3.5
|
||||||
@@ -84,6 +102,9 @@ blend_mode = 1
|
|||||||
[node name="Player" type="CharacterBody3D"]
|
[node name="Player" type="CharacterBody3D"]
|
||||||
collision_mask = 272
|
collision_mask = 272
|
||||||
script = ExtResource("1_poq2x")
|
script = ExtResource("1_poq2x")
|
||||||
|
RDamage = SubResource("Resource_cb2lu")
|
||||||
|
RKnockback = SubResource("Resource_abfq8")
|
||||||
|
RHealth = SubResource("Resource_ue7xq")
|
||||||
WalkSpeed = 7.5
|
WalkSpeed = 7.5
|
||||||
AccelerationFloor = 4.0
|
AccelerationFloor = 4.0
|
||||||
DecelerationFloor = 3.0
|
DecelerationFloor = 3.0
|
||||||
@@ -206,13 +227,6 @@ monitorable = false
|
|||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -1.5)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -1.5)
|
||||||
shape = SubResource("SphereShape3D_q14ux")
|
shape = SubResource("SphereShape3D_q14ux")
|
||||||
|
|
||||||
[node name="CloseEnemyDetector" type="ShapeCast3D" parent="."]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0)
|
|
||||||
shape = SubResource("SphereShape3D_cmijs")
|
|
||||||
target_position = Vector3(0, 0, -5)
|
|
||||||
collision_mask = 16
|
|
||||||
|
|
||||||
[node name="StairsSystem" type="Node3D" parent="."]
|
[node name="StairsSystem" type="Node3D" parent="."]
|
||||||
script = ExtResource("7_bmt5a")
|
script = ExtResource("7_bmt5a")
|
||||||
|
|
||||||
@@ -307,6 +321,13 @@ visible = false
|
|||||||
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, 1, 0, -1, -4.371139e-08, 0, 0, -1)
|
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, 1, 0, -1, -4.371139e-08, 0, 0, -1)
|
||||||
mesh = SubResource("CylinderMesh_nodcl")
|
mesh = SubResource("CylinderMesh_nodcl")
|
||||||
|
|
||||||
|
[node name="CloseEnemyDetector" type="ShapeCast3D" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0)
|
||||||
|
shape = SubResource("SphereShape3D_cmijs")
|
||||||
|
target_position = Vector3(0, 0, -5)
|
||||||
|
collision_mask = 48
|
||||||
|
|
||||||
[node name="GroundDetector" type="ShapeCast3D" parent="."]
|
[node name="GroundDetector" type="ShapeCast3D" parent="."]
|
||||||
shape = SubResource("CapsuleShape3D_6lejt")
|
shape = SubResource("CapsuleShape3D_6lejt")
|
||||||
collision_mask = 256
|
collision_mask = 256
|
||||||
@@ -446,7 +467,7 @@ layout_mode = 2
|
|||||||
|
|
||||||
[node name="EnemyTarget" type="TextureRect" parent="UI"]
|
[node name="EnemyTarget" type="TextureRect" parent="UI"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
modulate = Color(0.9882353, 0, 0.10980392, 1)
|
modulate = Color(0, 0.61278194, 0.56044877, 1)
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchors_preset = 8
|
anchors_preset = 8
|
||||||
anchor_left = 0.5
|
anchor_left = 0.5
|
||||||
@@ -537,6 +558,49 @@ to = NodePath("../../AtLeastOneCharge")
|
|||||||
event = &"power_used"
|
event = &"power_used"
|
||||||
delay_in_seconds = "0.0"
|
delay_in_seconds = "0.0"
|
||||||
|
|
||||||
|
[node name="Attack" type="Node" parent="StateChart/Root"]
|
||||||
|
script = ExtResource("26_infe6")
|
||||||
|
initial_state = NodePath("Ready")
|
||||||
|
|
||||||
|
[node name="Ready" type="Node" parent="StateChart/Root/Attack"]
|
||||||
|
script = ExtResource("27_34snm")
|
||||||
|
|
||||||
|
[node name="ToStandardAttack" type="Node" parent="StateChart/Root/Attack/Ready"]
|
||||||
|
script = ExtResource("28_n7qhm")
|
||||||
|
to = NodePath("../../StandardAttack")
|
||||||
|
event = &"standard_attack"
|
||||||
|
delay_in_seconds = "0.0"
|
||||||
|
|
||||||
|
[node name="ToDashAttack" type="Node" parent="StateChart/Root/Attack/Ready"]
|
||||||
|
script = ExtResource("28_n7qhm")
|
||||||
|
to = NodePath("../../DashAttack")
|
||||||
|
event = &"dash_attack"
|
||||||
|
delay_in_seconds = "0.0"
|
||||||
|
|
||||||
|
[node name="StandardAttack" type="Node" parent="StateChart/Root/Attack"]
|
||||||
|
script = ExtResource("27_34snm")
|
||||||
|
|
||||||
|
[node name="ToReady" type="Node" parent="StateChart/Root/Attack/StandardAttack"]
|
||||||
|
script = ExtResource("28_n7qhm")
|
||||||
|
to = NodePath("../../Ready")
|
||||||
|
event = &"attack_finished"
|
||||||
|
delay_in_seconds = "0.0"
|
||||||
|
|
||||||
|
[node name="ToDashAttack" type="Node" parent="StateChart/Root/Attack/StandardAttack"]
|
||||||
|
script = ExtResource("28_n7qhm")
|
||||||
|
to = NodePath("../../DashAttack")
|
||||||
|
event = &"dash_attack"
|
||||||
|
delay_in_seconds = "0.0"
|
||||||
|
|
||||||
|
[node name="DashAttack" type="Node" parent="StateChart/Root/Attack"]
|
||||||
|
script = ExtResource("27_34snm")
|
||||||
|
|
||||||
|
[node name="ToReady" type="Node" parent="StateChart/Root/Attack/DashAttack"]
|
||||||
|
script = ExtResource("28_n7qhm")
|
||||||
|
to = NodePath("../../Ready")
|
||||||
|
event = &"attack_finished"
|
||||||
|
delay_in_seconds = "0.0"
|
||||||
|
|
||||||
[node name="Movement" type="Node" parent="StateChart/Root"]
|
[node name="Movement" type="Node" parent="StateChart/Root"]
|
||||||
script = ExtResource("26_infe6")
|
script = ExtResource("26_infe6")
|
||||||
initial_state = NodePath("Grounded")
|
initial_state = NodePath("Grounded")
|
||||||
|
|||||||
@@ -11,10 +11,18 @@ public partial class PlayerUi : Control
|
|||||||
NoTarget,
|
NoTarget,
|
||||||
TargetTooFar,
|
TargetTooFar,
|
||||||
TargetInRange,
|
TargetInRange,
|
||||||
|
TargetDashThrough
|
||||||
}
|
}
|
||||||
|
|
||||||
public record TargetProperties(TargetState State, Vector2 Position);
|
public record TargetProperties(TargetState State, Vector2 Position);
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Color DashThroughColor { get; set; } = new Color("009c8f");
|
||||||
|
[Export]
|
||||||
|
public Color DashBlockedColor { get; set; } = new Color("fc001c");
|
||||||
|
[Export]
|
||||||
|
public Color DashOutOfRangeColor { get; set; } = new Color("ffffff");
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
_dashIcons[0] = GetNode<TextureRect>("%Dash1");
|
_dashIcons[0] = GetNode<TextureRect>("%Dash1");
|
||||||
@@ -29,7 +37,14 @@ public partial class PlayerUi : Control
|
|||||||
var (state, position) = targetProperties;
|
var (state, position) = targetProperties;
|
||||||
|
|
||||||
var visible = state != TargetState.NoTarget;
|
var visible = state != TargetState.NoTarget;
|
||||||
var modulation = state == TargetState.TargetInRange ? new Color("ffffff") : new Color("fc001c");
|
|
||||||
|
var modulation = state switch
|
||||||
|
{
|
||||||
|
TargetState.TargetTooFar => DashOutOfRangeColor,
|
||||||
|
TargetState.TargetInRange => DashBlockedColor,
|
||||||
|
TargetState.TargetDashThrough => DashThroughColor,
|
||||||
|
_ => DashOutOfRangeColor
|
||||||
|
};
|
||||||
_enemyTarget.SetVisible(visible);
|
_enemyTarget.SetVisible(visible);
|
||||||
_enemyTarget.SetPosition(position - _enemyTarget.Size / 2);
|
_enemyTarget.SetPosition(position - _enemyTarget.Size / 2);
|
||||||
_enemyTarget.SetModulate(modulation);
|
_enemyTarget.SetModulate(modulation);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using Movementtests.addons.godot_state_charts.csharp;
|
|||||||
using Movementtests.interfaces;
|
using Movementtests.interfaces;
|
||||||
using Movementtests.systems;
|
using Movementtests.systems;
|
||||||
using Movementtests.player_controller.Scripts;
|
using Movementtests.player_controller.Scripts;
|
||||||
|
using Movementtests.systems.damage;
|
||||||
using RustyOptions;
|
using RustyOptions;
|
||||||
|
|
||||||
public partial class PlayerController : CharacterBody3D,
|
public partial class PlayerController : CharacterBody3D,
|
||||||
@@ -323,6 +324,11 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
private StateChartState _onWallHanging;
|
private StateChartState _onWallHanging;
|
||||||
private StateChartState _onWallRunning;
|
private StateChartState _onWallRunning;
|
||||||
|
|
||||||
|
private StateChartState _attack;
|
||||||
|
private StateChartState _attackReady;
|
||||||
|
private StateChartState _attackStandard;
|
||||||
|
private StateChartState _attackDash;
|
||||||
|
|
||||||
private Transition _onDashEnded;
|
private Transition _onDashEnded;
|
||||||
|
|
||||||
private Transition _onJumpFromWall;
|
private Transition _onJumpFromWall;
|
||||||
@@ -340,7 +346,6 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
public float CurrentHealth { get; set; }
|
public float CurrentHealth { get; set; }
|
||||||
|
|
||||||
private bool _isInvincible;
|
private bool _isInvincible;
|
||||||
private bool _canAttack = true;
|
|
||||||
private readonly List<IDamageable> _hitEnemies = new List<IDamageable>();
|
private readonly List<IDamageable> _hitEnemies = new List<IDamageable>();
|
||||||
|
|
||||||
private ShapeCast3D _closeEnemyDetector;
|
private ShapeCast3D _closeEnemyDetector;
|
||||||
@@ -464,6 +469,12 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
_onLeaveWallFromRun = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/Running/OnLeaveWall"));
|
_onLeaveWallFromRun = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/Running/OnLeaveWall"));
|
||||||
_onAirborneToGrounded = Transition.Of(GetNode("StateChart/Root/Movement/Airborne/OnGrounded"));
|
_onAirborneToGrounded = Transition.Of(GetNode("StateChart/Root/Movement/Airborne/OnGrounded"));
|
||||||
|
|
||||||
|
// Attack states
|
||||||
|
_attack = StateChartState.Of(GetNode("StateChart/Root/Attack"));
|
||||||
|
_attackReady = StateChartState.Of(GetNode("StateChart/Root/Attack/Ready"));
|
||||||
|
_attackStandard = StateChartState.Of(GetNode("StateChart/Root/Attack/StandardAttack"));
|
||||||
|
_attackDash = StateChartState.Of(GetNode("StateChart/Root/Attack/DashAttack"));
|
||||||
|
|
||||||
// State timers
|
// State timers
|
||||||
_powerCooldownTimer = GetNode<Timer>("PowerCooldown");
|
_powerCooldownTimer = GetNode<Timer>("PowerCooldown");
|
||||||
_timeScaleAimInAirTimer = GetNode<Timer>("TimeScaleAimInAir");
|
_timeScaleAimInAirTimer = GetNode<Timer>("TimeScaleAimInAir");
|
||||||
@@ -571,6 +582,10 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
_onJumpFromWallFalling.Taken += OnJumpFromWall;
|
_onJumpFromWallFalling.Taken += OnJumpFromWall;
|
||||||
_onLeaveWallFromRun.Taken += OnLeaveWallFromRun;
|
_onLeaveWallFromRun.Taken += OnLeaveWallFromRun;
|
||||||
_onAirborneToGrounded.Taken += OnAirborneToGrounded;
|
_onAirborneToGrounded.Taken += OnAirborneToGrounded;
|
||||||
|
|
||||||
|
// Attack states
|
||||||
|
_attackStandard.StateEntered += OnStandardAttackStarted;
|
||||||
|
_attackDash.StateEntered += OnDashAttackStarted;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
@@ -1705,9 +1720,13 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
}
|
}
|
||||||
public void OnAimedDashFinished()
|
public void OnAimedDashFinished()
|
||||||
{
|
{
|
||||||
var postDashVelocity = _preDashVelocity.Length() > PostDashSpeed ? PostDashSpeed : _preDashVelocity.Length();
|
if (_customMantle)
|
||||||
|
{
|
||||||
|
_playerState.SendEvent("mantle");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var postDashVelocity = _preDashVelocity.Length() > PostDashSpeed ? _preDashVelocity.Length() : PostDashSpeed;
|
||||||
Velocity = _dashDirection * postDashVelocity;
|
Velocity = _dashDirection * postDashVelocity;
|
||||||
if (_customMantle) _playerState.SendEvent("mantle");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Weapon dashing
|
// Weapon dashing
|
||||||
@@ -1823,8 +1842,18 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
DashIndicatorNode.LookAt(WeaponSystem.GlobalPosition);
|
DashIndicatorNode.LookAt(WeaponSystem.GlobalPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////
|
||||||
|
// Hit Management ///////
|
||||||
|
///////////////////////////
|
||||||
|
|
||||||
|
private bool _isEnemyInDashAttackRange;
|
||||||
|
private Vector3 _targetHitLocation;
|
||||||
|
private Vector3 _targetLocation;
|
||||||
|
private Object _targetObject;
|
||||||
public void HandleEnemyTargeting()
|
public void HandleEnemyTargeting()
|
||||||
{
|
{
|
||||||
|
_isEnemyInDashAttackRange = false;
|
||||||
_closeEnemyDetector.SetRotation(HeadSystem.GetGlobalLookRotation());
|
_closeEnemyDetector.SetRotation(HeadSystem.GetGlobalLookRotation());
|
||||||
|
|
||||||
var enemyTargetState = PlayerUi.TargetState.NoTarget;
|
var enemyTargetState = PlayerUi.TargetState.NoTarget;
|
||||||
@@ -1835,23 +1864,34 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var collidedObject = _closeEnemyDetector.GetCollider(0);
|
_targetHitLocation = _closeEnemyDetector.GetCollisionPoint(0);
|
||||||
if (collidedObject is not ITargetable target)
|
_targetObject = _closeEnemyDetector.GetCollider(0);
|
||||||
|
if (_targetObject is not ITargetable target)
|
||||||
{
|
{
|
||||||
PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen));
|
PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var targetPos = target.GetTargetGlobalPosition();
|
_targetLocation = target.GetTargetGlobalPosition();
|
||||||
var targetDistance = targetPos.DistanceTo(GlobalPosition);
|
var targetDistance = _targetLocation.DistanceTo(GlobalPosition);
|
||||||
enemyTargetState = targetDistance > TargetInRangeDistance ? PlayerUi.TargetState.TargetInRange : PlayerUi.TargetState.TargetTooFar;
|
positionOnScreen = _camera.UnprojectPosition(_targetLocation);
|
||||||
positionOnScreen = _camera.UnprojectPosition(targetPos);
|
|
||||||
|
_isEnemyInDashAttackRange = targetDistance < TargetInRangeDistance;
|
||||||
|
if (_isEnemyInDashAttackRange)
|
||||||
|
{
|
||||||
|
enemyTargetState = PlayerUi.TargetState.TargetDashThrough;
|
||||||
|
if (_targetObject is IDamageable damageable && _targetObject is IHealthable healthable)
|
||||||
|
{
|
||||||
|
var wouldBeDamage = damageable.ComputeDamage(new DamageRecord(this, RDamage));
|
||||||
|
if (wouldBeDamage.Damage.DamageDealt < healthable.CurrentHealth)
|
||||||
|
enemyTargetState = PlayerUi.TargetState.TargetInRange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else enemyTargetState = PlayerUi.TargetState.TargetTooFar;
|
||||||
|
|
||||||
PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen));
|
PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen));
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////
|
|
||||||
// Hit Management ///////
|
|
||||||
///////////////////////////
|
|
||||||
public DamageRecord TakeDamage(DamageRecord damageRecord)
|
public DamageRecord TakeDamage(DamageRecord damageRecord)
|
||||||
{
|
{
|
||||||
if (_isInvincible)
|
if (_isInvincible)
|
||||||
@@ -1868,12 +1908,72 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
return finalDamage;
|
return finalDamage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DamageRecord ComputeDamage(DamageRecord damageRecord)
|
||||||
|
{
|
||||||
|
return CDamageable.ComputeDamage(damageRecord);
|
||||||
|
}
|
||||||
|
|
||||||
public void OnHitInvincibility()
|
public void OnHitInvincibility()
|
||||||
{
|
{
|
||||||
_isInvincible = true;
|
_isInvincible = true;
|
||||||
_invincibilityTimer.Start();
|
_invincibilityTimer.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnStandardAttackStarted()
|
||||||
|
{
|
||||||
|
_attackCooldown.Start();
|
||||||
|
HeadSystem.OnHit();
|
||||||
|
_audioStream!.SwitchToClipByName("attacks");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnDashAttackStarted()
|
||||||
|
{
|
||||||
|
_audioStream!.SwitchToClipByName("attacks");
|
||||||
|
|
||||||
|
_isInvincible = true;
|
||||||
|
|
||||||
|
var actualDashLocation = _targetLocation + Vector3.Down*HeadSystem.Position.Y;
|
||||||
|
var travel = actualDashLocation - GlobalPosition;
|
||||||
|
_preDashVelocity = Velocity;
|
||||||
|
_dashDirection = travel.Normalized();
|
||||||
|
var dashTween = CreatePositionTween(actualDashLocation, AimedDashTime);
|
||||||
|
dashTween.Finished += OnDashAttackEnded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnDashAttackEnded()
|
||||||
|
{
|
||||||
|
if (_targetObject is IDamageable damageable)
|
||||||
|
{
|
||||||
|
_hitEnemies.Add(damageable);
|
||||||
|
TriggerDamage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_targetObject is IStunnable stunnable)
|
||||||
|
{
|
||||||
|
stunnable.Stun();
|
||||||
|
}
|
||||||
|
|
||||||
|
var shouldKnockback = false;
|
||||||
|
if (_targetObject is IHealthable healthable)
|
||||||
|
{
|
||||||
|
if (healthable.CurrentHealth > 0) shouldKnockback = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldKnockback)
|
||||||
|
{
|
||||||
|
Velocity = -_dashDirection*RKnockback.Modifier;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var locationOtherSide = _targetLocation + (_targetLocation - _targetHitLocation);
|
||||||
|
GlobalPosition = locationOtherSide;
|
||||||
|
var postDashVelocity = _preDashVelocity.Length() > PostDashSpeed ? _preDashVelocity.Length() : PostDashSpeed;
|
||||||
|
Velocity = _dashDirection * postDashVelocity;
|
||||||
|
}
|
||||||
|
_isInvincible = false;
|
||||||
|
_playerState.SendEvent("attack_finished");
|
||||||
|
}
|
||||||
|
|
||||||
public void OnInputHitPressed()
|
public void OnInputHitPressed()
|
||||||
{
|
{
|
||||||
if (_aiming.Active && WeaponSystem.InHandState.Active)
|
if (_aiming.Active && WeaponSystem.InHandState.Active)
|
||||||
@@ -1881,24 +1981,15 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
ThrowWeapon();
|
ThrowWeapon();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!WeaponSystem.InHandState.Active) return;
|
var attackToDo = _isEnemyInDashAttackRange ? "dash_attack" : "standard_attack";
|
||||||
if (!_canAttack) return;
|
_playerState.SendEvent(attackToDo);
|
||||||
|
|
||||||
_canAttack = false;
|
|
||||||
_attackCooldown.Start();
|
|
||||||
PerformHit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetAttackCooldown()
|
public void ResetAttackCooldown()
|
||||||
{
|
{
|
||||||
_canAttack = true;
|
_playerState.SendEvent("attack_finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PerformHit()
|
|
||||||
{
|
|
||||||
HeadSystem.OnHit();
|
|
||||||
_audioStream!.SwitchToClipByName("attacks");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnHitboxActivated()
|
public void OnHitboxActivated()
|
||||||
{
|
{
|
||||||
@@ -1942,6 +2033,7 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
}
|
}
|
||||||
public void ReduceHealth(IDamageable source, DamageRecord damageRecord)
|
public void ReduceHealth(IDamageable source, DamageRecord damageRecord)
|
||||||
{
|
{
|
||||||
|
GD.Print("That's NOT fine");
|
||||||
CHealth.ReduceHealth(source, damageRecord);
|
CHealth.ReduceHealth(source, damageRecord);
|
||||||
HealthChanged?.Invoke(this, CHealth.CurrentHealth);
|
HealthChanged?.Invoke(this, CHealth.CurrentHealth);
|
||||||
}
|
}
|
||||||
@@ -1952,7 +2044,8 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
|
|
||||||
public Vector3 ComputeKnockback()
|
public Vector3 ComputeKnockback()
|
||||||
{
|
{
|
||||||
return CKnockback.ComputeKnockback();
|
var kb = CKnockback.ComputeKnockback();
|
||||||
|
return kb;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Kill(IHealthable source)
|
public void Kill(IHealthable source)
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ locale/translations=PackedStringArray("res://addons/maaacks_game_template/base/t
|
|||||||
3d_physics/layer_3="3"
|
3d_physics/layer_3="3"
|
||||||
3d_physics/layer_4="4"
|
3d_physics/layer_4="4"
|
||||||
3d_physics/layer_5="enemies"
|
3d_physics/layer_5="enemies"
|
||||||
|
3d_physics/layer_6="InteractiveGeo"
|
||||||
3d_physics/layer_9="terrain"
|
3d_physics/layer_9="terrain"
|
||||||
3d_physics/layer_17="weapon"
|
3d_physics/layer_17="weapon"
|
||||||
|
|
||||||
|
|||||||
31
scenes/FixedDashTarget/FixedDashthroughTarget.cs
Normal file
31
scenes/FixedDashTarget/FixedDashthroughTarget.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using Godot;
|
||||||
|
using System;
|
||||||
|
using Movementtests.interfaces;
|
||||||
|
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class FixedDashthroughTarget : AnimatableBody3D, ITargetable, IStunnable
|
||||||
|
{
|
||||||
|
public Vector3 GetTargetGlobalPosition()
|
||||||
|
{
|
||||||
|
return GlobalPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
private uint _defaultCollisionMask;
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
_defaultCollisionMask = CollisionMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsStunned { get; set; }
|
||||||
|
public float StunDuration { get; set; } = 0.1f;
|
||||||
|
public void Stun()
|
||||||
|
{
|
||||||
|
_defaultCollisionMask = 0;
|
||||||
|
GetTree().CreateTimer(StunDuration).Timeout += Unstun;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Unstun()
|
||||||
|
{
|
||||||
|
_defaultCollisionMask = CollisionMask;
|
||||||
|
}
|
||||||
|
}
|
||||||
1
scenes/FixedDashTarget/FixedDashthroughTarget.cs.uid
Normal file
1
scenes/FixedDashTarget/FixedDashthroughTarget.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://c10qfkvmrm6uq
|
||||||
30
scenes/FixedDashTarget/fixed_dashthrough_target.tscn
Normal file
30
scenes/FixedDashTarget/fixed_dashthrough_target.tscn
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
[gd_scene load_steps=5 format=3 uid="uid://qup00a7x2sji"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://c10qfkvmrm6uq" path="res://scenes/FixedDashTarget/FixedDashthroughTarget.cs" id="1_r0j7a"]
|
||||||
|
|
||||||
|
[sub_resource type="SphereShape3D" id="SphereShape3D_nkm8n"]
|
||||||
|
radius = 1.0
|
||||||
|
|
||||||
|
[sub_resource type="SphereMesh" id="SphereMesh_r0j7a"]
|
||||||
|
radius = 1.0
|
||||||
|
height = 2.0
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_kgb3i"]
|
||||||
|
albedo_color = Color(5.1018596e-06, 0.6818665, 0.7627612, 1)
|
||||||
|
metallic = 0.8
|
||||||
|
metallic_specular = 0.6
|
||||||
|
roughness = 0.1
|
||||||
|
emission_enabled = true
|
||||||
|
emission = Color(0, 0.68968636, 0.7473501, 1)
|
||||||
|
|
||||||
|
[node name="FixedDashthroughTarget" type="AnimatableBody3D"]
|
||||||
|
collision_layer = 288
|
||||||
|
collision_mask = 0
|
||||||
|
script = ExtResource("1_r0j7a")
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||||
|
shape = SubResource("SphereShape3D_nkm8n")
|
||||||
|
|
||||||
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||||
|
mesh = SubResource("SphereMesh_r0j7a")
|
||||||
|
surface_material_override/0 = SubResource("StandardMaterial3D_kgb3i")
|
||||||
@@ -11,7 +11,8 @@ public partial class Enemy : CharacterBody3D,
|
|||||||
IMoveable,
|
IMoveable,
|
||||||
ISpawnable,
|
ISpawnable,
|
||||||
IKnockbackable,
|
IKnockbackable,
|
||||||
ITargetable
|
ITargetable,
|
||||||
|
IStunnable
|
||||||
{
|
{
|
||||||
// Signals and events
|
// Signals and events
|
||||||
public event Action<IDamageable, DamageRecord> DamageTaken;
|
public event Action<IDamageable, DamageRecord> DamageTaken;
|
||||||
@@ -44,10 +45,15 @@ public partial class Enemy : CharacterBody3D,
|
|||||||
public IMoveable CMovement { get; set; }
|
public IMoveable CMovement { get; set; }
|
||||||
|
|
||||||
// Public stuff
|
// Public stuff
|
||||||
public float CurrentHealth { get; set; }
|
public float CurrentHealth
|
||||||
|
{
|
||||||
|
get => CHealth.CurrentHealth;
|
||||||
|
set => CHealth.CurrentHealth = value;
|
||||||
|
}
|
||||||
|
|
||||||
// Private stuff
|
// Private stuff
|
||||||
private Area3D _damageBox;
|
private Area3D _damageBox;
|
||||||
|
private Node3D _target;
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
@@ -58,6 +64,7 @@ public partial class Enemy : CharacterBody3D,
|
|||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
_damageBox = GetNode<Area3D>("DamageBox");
|
_damageBox = GetNode<Area3D>("DamageBox");
|
||||||
|
_target = GetNode<Node3D>("CTarget");
|
||||||
|
|
||||||
CDamageable = GetNode<Node>("CDamageable") as IDamageable;
|
CDamageable = GetNode<Node>("CDamageable") as IDamageable;
|
||||||
CMovement = GetNode<Node>("CMovement") as IMoveable;
|
CMovement = GetNode<Node>("CMovement") as IMoveable;
|
||||||
@@ -106,6 +113,8 @@ public partial class Enemy : CharacterBody3D,
|
|||||||
|
|
||||||
public void ProcessGameplay(double delta)
|
public void ProcessGameplay(double delta)
|
||||||
{
|
{
|
||||||
|
if (IsStunned) return;
|
||||||
|
|
||||||
var bodies = _damageBox.GetOverlappingBodies();
|
var bodies = _damageBox.GetOverlappingBodies();
|
||||||
foreach (var body in bodies)
|
foreach (var body in bodies)
|
||||||
{
|
{
|
||||||
@@ -130,6 +139,14 @@ public partial class Enemy : CharacterBody3D,
|
|||||||
return finalDamage;
|
return finalDamage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DamageRecord ComputeDamage(DamageRecord damageRecord)
|
||||||
|
{
|
||||||
|
if (CDamageable is null)
|
||||||
|
return damageRecord with { Damage = new RDamage(0, damageRecord.Damage.DamageType) };
|
||||||
|
|
||||||
|
return CDamageable.ComputeDamage(damageRecord);
|
||||||
|
}
|
||||||
|
|
||||||
public void ReduceHealth(IDamageable source, DamageRecord damageRecord)
|
public void ReduceHealth(IDamageable source, DamageRecord damageRecord)
|
||||||
{
|
{
|
||||||
if (CHealth is null) return;
|
if (CHealth is null) return;
|
||||||
@@ -160,8 +177,22 @@ public partial class Enemy : CharacterBody3D,
|
|||||||
|
|
||||||
public Vector3 GetTargetGlobalPosition()
|
public Vector3 GetTargetGlobalPosition()
|
||||||
{
|
{
|
||||||
var target = GetNode<Node3D>("CTarget");
|
if (_target is null) return GlobalPosition;
|
||||||
if (target is null) return GlobalPosition;
|
return _target.GlobalPosition;
|
||||||
return target.GlobalPosition;
|
}
|
||||||
|
|
||||||
|
// Stun management
|
||||||
|
public bool IsStunned { get; set; } = false;
|
||||||
|
|
||||||
|
[Export(PropertyHint.Range, "0.1, 2, 0.1, or_greater")]
|
||||||
|
public float StunDuration { get; set; } = 1f;
|
||||||
|
public void Stun()
|
||||||
|
{
|
||||||
|
IsStunned = true;
|
||||||
|
GetTree().CreateTimer(StunDuration).Timeout += Unstun;
|
||||||
|
}
|
||||||
|
public void Unstun()
|
||||||
|
{
|
||||||
|
IsStunned = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,19 +42,15 @@ albedo_color = Color(0.06469653, 0.06469653, 0.06469653, 1)
|
|||||||
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_4yfjf"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_4yfjf"]
|
||||||
|
|
||||||
[node name="FlyingEnemy" type="CharacterBody3D" node_paths=PackedStringArray("CHealth", "CDamage", "CKnockback", "CMovement")]
|
[node name="FlyingEnemy" type="CharacterBody3D"]
|
||||||
collision_layer = 16
|
collision_layer = 16
|
||||||
collision_mask = 273
|
collision_mask = 273
|
||||||
motion_mode = 1
|
motion_mode = 1
|
||||||
script = ExtResource("1_q8l7o")
|
script = ExtResource("1_q8l7o")
|
||||||
CHealth = NodePath("CHealth")
|
|
||||||
RHealth = ExtResource("2_ma2bq")
|
RHealth = ExtResource("2_ma2bq")
|
||||||
DeathEffects = Array[Object]([])
|
DeathEffects = Array[Object]([])
|
||||||
CDamage = NodePath("CDamageable")
|
|
||||||
RDamage = ExtResource("2_on7rt")
|
RDamage = ExtResource("2_on7rt")
|
||||||
CKnockback = NodePath("CKnockback")
|
|
||||||
RKnockback = ExtResource("11_mpa2u")
|
RKnockback = ExtResource("11_mpa2u")
|
||||||
CMovement = NodePath("CMovement")
|
|
||||||
RMovement = ExtResource("4_dejyg")
|
RMovement = ExtResource("4_dejyg")
|
||||||
|
|
||||||
[node name="CHealth" type="Node" parent="."]
|
[node name="CHealth" type="Node" parent="."]
|
||||||
@@ -74,6 +70,8 @@ TerrainCollision = 256
|
|||||||
[node name="CKnockback" parent="." instance=ExtResource("10_dejyg")]
|
[node name="CKnockback" parent="." instance=ExtResource("10_dejyg")]
|
||||||
RKnockback = ExtResource("11_mpa2u")
|
RKnockback = ExtResource("11_mpa2u")
|
||||||
|
|
||||||
|
[node name="CTarget" type="Marker3D" parent="."]
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||||
shape = SubResource("SphereShape3D_b46rq")
|
shape = SubResource("SphereShape3D_b46rq")
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_qj0ob"]
|
[sub_resource type="Resource" id="Resource_qj0ob"]
|
||||||
script = ExtResource("2_r3cnf")
|
script = ExtResource("2_r3cnf")
|
||||||
Modifier = 3.0
|
Modifier = 1.0
|
||||||
metadata/_custom_type_script = "uid://b6y3ugfydvch0"
|
metadata/_custom_type_script = "uid://b6y3ugfydvch0"
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_6d4gl"]
|
[sub_resource type="Resource" id="Resource_6d4gl"]
|
||||||
|
|||||||
@@ -4,4 +4,5 @@
|
|||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1_h6jgd")
|
script = ExtResource("1_h6jgd")
|
||||||
|
StartingHealth = 10.0
|
||||||
metadata/_custom_type_script = "uid://baiapod3csndf"
|
metadata/_custom_type_script = "uid://baiapod3csndf"
|
||||||
|
|||||||
Reference in New Issue
Block a user