diff --git a/Config/DefaultGameplayTags.ini b/Config/DefaultGameplayTags.ini index 1934d36..40069f9 100644 --- a/Config/DefaultGameplayTags.ini +++ b/Config/DefaultGameplayTags.ini @@ -8,6 +8,7 @@ FastReplication=False InvalidTagCharacters="\"\'," NumBitsForContainerSize=6 NetIndexFirstBitSegment=16 ++GameplayTagList=(Tag="GameplayCue.Ability.Hero1.Poison",DevComment="") +GameplayTagList=(Tag="GameplayCue.Ability.Hero1.PuhBack",DevComment="") +GameplayTagList=(Tag="GameplayCue.Ability.Hero1.Shield",DevComment="") diff --git a/Content/Characters/Abilities/Death/AM_Character_Death.uasset b/Content/Characters/(Shared)/Abilities/Death/AM_Character_Death.uasset similarity index 78% rename from Content/Characters/Abilities/Death/AM_Character_Death.uasset rename to Content/Characters/(Shared)/Abilities/Death/AM_Character_Death.uasset index 55783f4..4cd5c96 100644 Binary files a/Content/Characters/Abilities/Death/AM_Character_Death.uasset and b/Content/Characters/(Shared)/Abilities/Death/AM_Character_Death.uasset differ diff --git a/Content/Characters/Abilities/Death/AN_Character_Death.uasset b/Content/Characters/(Shared)/Abilities/Death/AN_Character_Death.uasset similarity index 99% rename from Content/Characters/Abilities/Death/AN_Character_Death.uasset rename to Content/Characters/(Shared)/Abilities/Death/AN_Character_Death.uasset index a7d479c..0a93b09 100644 Binary files a/Content/Characters/Abilities/Death/AN_Character_Death.uasset and b/Content/Characters/(Shared)/Abilities/Death/AN_Character_Death.uasset differ diff --git a/Content/Characters/Abilities/Death/GA_Character_Death.uasset b/Content/Characters/(Shared)/Abilities/Death/GA_Character_Death.uasset similarity index 67% rename from Content/Characters/Abilities/Death/GA_Character_Death.uasset rename to Content/Characters/(Shared)/Abilities/Death/GA_Character_Death.uasset index ca8dd47..f37ebce 100644 Binary files a/Content/Characters/Abilities/Death/GA_Character_Death.uasset and b/Content/Characters/(Shared)/Abilities/Death/GA_Character_Death.uasset differ diff --git a/Content/Characters/(Shared)/Abilities/GA_Cast.uasset b/Content/Characters/(Shared)/Abilities/GA_Cast.uasset new file mode 100644 index 0000000..e943730 Binary files /dev/null and b/Content/Characters/(Shared)/Abilities/GA_Cast.uasset differ diff --git a/Content/Characters/Abilities/Revive/AM_Character_Revive.uasset b/Content/Characters/(Shared)/Abilities/Revive/AM_Character_Revive.uasset similarity index 78% rename from Content/Characters/Abilities/Revive/AM_Character_Revive.uasset rename to Content/Characters/(Shared)/Abilities/Revive/AM_Character_Revive.uasset index 33d2c96..3a67978 100644 Binary files a/Content/Characters/Abilities/Revive/AM_Character_Revive.uasset and b/Content/Characters/(Shared)/Abilities/Revive/AM_Character_Revive.uasset differ diff --git a/Content/Characters/Abilities/Revive/AN_Character_Revive.uasset b/Content/Characters/(Shared)/Abilities/Revive/AN_Character_Revive.uasset similarity index 99% rename from Content/Characters/Abilities/Revive/AN_Character_Revive.uasset rename to Content/Characters/(Shared)/Abilities/Revive/AN_Character_Revive.uasset index b184e15..8dccaa6 100644 Binary files a/Content/Characters/Abilities/Revive/AN_Character_Revive.uasset and b/Content/Characters/(Shared)/Abilities/Revive/AN_Character_Revive.uasset differ diff --git a/Content/Characters/Abilities/Revive/GA_Character_Revive.uasset b/Content/Characters/(Shared)/Abilities/Revive/GA_Character_Revive.uasset similarity index 72% rename from Content/Characters/Abilities/Revive/GA_Character_Revive.uasset rename to Content/Characters/(Shared)/Abilities/Revive/GA_Character_Revive.uasset index c5f1a32..51f9051 100644 Binary files a/Content/Characters/Abilities/Revive/GA_Character_Revive.uasset and b/Content/Characters/(Shared)/Abilities/Revive/GA_Character_Revive.uasset differ diff --git a/Content/Characters/(Shared)/BP_Character.uasset b/Content/Characters/(Shared)/BP_Character.uasset new file mode 100644 index 0000000..0ed53e0 Binary files /dev/null and b/Content/Characters/(Shared)/BP_Character.uasset differ diff --git a/Content/Core/Effects/BP_PoolRegen_Health.uasset b/Content/Characters/(Shared)/Effects/BP_PoolRegen_Health.uasset similarity index 50% rename from Content/Core/Effects/BP_PoolRegen_Health.uasset rename to Content/Characters/(Shared)/Effects/BP_PoolRegen_Health.uasset index ebb9981..1e9e215 100644 Binary files a/Content/Core/Effects/BP_PoolRegen_Health.uasset and b/Content/Characters/(Shared)/Effects/BP_PoolRegen_Health.uasset differ diff --git a/Content/Characters/(Shared)/Effects/BP_PoolRegen_Stamina.uasset b/Content/Characters/(Shared)/Effects/BP_PoolRegen_Stamina.uasset new file mode 100644 index 0000000..d84b79f Binary files /dev/null and b/Content/Characters/(Shared)/Effects/BP_PoolRegen_Stamina.uasset differ diff --git a/Content/Characters/(Shared)/Effects/GE_Cooldown.uasset b/Content/Characters/(Shared)/Effects/GE_Cooldown.uasset new file mode 100644 index 0000000..27fa16d Binary files /dev/null and b/Content/Characters/(Shared)/Effects/GE_Cooldown.uasset differ diff --git a/Content/Core/Effects/GE_Cost_Stamina.uasset b/Content/Characters/(Shared)/Effects/GE_Cost_Stamina.uasset similarity index 55% rename from Content/Core/Effects/GE_Cost_Stamina.uasset rename to Content/Characters/(Shared)/Effects/GE_Cost_Stamina.uasset index 117b77e..da18624 100644 Binary files a/Content/Core/Effects/GE_Cost_Stamina.uasset and b/Content/Characters/(Shared)/Effects/GE_Cost_Stamina.uasset differ diff --git a/Content/Characters/(Shared)/Effects/GE_Regen.uasset b/Content/Characters/(Shared)/Effects/GE_Regen.uasset new file mode 100644 index 0000000..b24e0e8 Binary files /dev/null and b/Content/Characters/(Shared)/Effects/GE_Regen.uasset differ diff --git a/Content/Characters/BP_Character.uasset b/Content/Characters/BP_Character.uasset deleted file mode 100644 index d99eba5..0000000 Binary files a/Content/Characters/BP_Character.uasset and /dev/null differ diff --git a/Content/Characters/Children/Creature/BP_Creature.uasset b/Content/Characters/Children/Creature/BP_Creature.uasset deleted file mode 100644 index 51c0f59..0000000 Binary files a/Content/Characters/Children/Creature/BP_Creature.uasset and /dev/null differ diff --git a/Content/Characters/Children/Creature1/BP_Creature1.uasset b/Content/Characters/Children/Creature1/BP_Creature1.uasset deleted file mode 100644 index 925af2e..0000000 Binary files a/Content/Characters/Children/Creature1/BP_Creature1.uasset and /dev/null differ diff --git a/Content/Characters/Children/Creature1/Effects/GE_Creature1.uasset b/Content/Characters/Children/Creature1/Effects/GE_Creature1.uasset deleted file mode 100644 index 9b13402..0000000 Binary files a/Content/Characters/Children/Creature1/Effects/GE_Creature1.uasset and /dev/null differ diff --git a/Content/Characters/Children/Creature2/BP_Creature2.uasset b/Content/Characters/Children/Creature2/BP_Creature2.uasset deleted file mode 100644 index 7ef86d7..0000000 Binary files a/Content/Characters/Children/Creature2/BP_Creature2.uasset and /dev/null differ diff --git a/Content/Characters/Children/Creature2/Effects/GE_Creature2.uasset b/Content/Characters/Children/Creature2/Effects/GE_Creature2.uasset deleted file mode 100644 index 383d1c5..0000000 Binary files a/Content/Characters/Children/Creature2/Effects/GE_Creature2.uasset and /dev/null differ diff --git a/Content/Characters/Children/Hero1/Abilities/Ability4/GA_Hero1_Ability4.uasset b/Content/Characters/Children/Hero1/Abilities/Ability4/GA_Hero1_Ability4.uasset deleted file mode 100644 index b07365d..0000000 Binary files a/Content/Characters/Children/Hero1/Abilities/Ability4/GA_Hero1_Ability4.uasset and /dev/null differ diff --git a/Content/Characters/Children/Hero1/Abilities/Blast/GA_Hero1_Blast.uasset b/Content/Characters/Children/Hero1/Abilities/Blast/GA_Hero1_Blast.uasset deleted file mode 100644 index 321b3af..0000000 Binary files a/Content/Characters/Children/Hero1/Abilities/Blast/GA_Hero1_Blast.uasset and /dev/null differ diff --git a/Content/Characters/Children/Hero1/Abilities/Blast/GC_Hero1_Blast_Area.uasset b/Content/Characters/Children/Hero1/Abilities/Blast/GC_Hero1_Blast_Area.uasset deleted file mode 100644 index 9e087ab..0000000 Binary files a/Content/Characters/Children/Hero1/Abilities/Blast/GC_Hero1_Blast_Area.uasset and /dev/null differ diff --git a/Content/Characters/Children/Hero1/Abilities/Shield/GA_Hero1_Shield.uasset b/Content/Characters/Children/Hero1/Abilities/Shield/GA_Hero1_Shield.uasset deleted file mode 100644 index 31a3309..0000000 Binary files a/Content/Characters/Children/Hero1/Abilities/Shield/GA_Hero1_Shield.uasset and /dev/null differ diff --git a/Content/Characters/Children/Hero1/Abilities/Shield/GE_Hero1_Shield.uasset b/Content/Characters/Children/Hero1/Abilities/Shield/GE_Hero1_Shield.uasset deleted file mode 100644 index 86c9dc2..0000000 Binary files a/Content/Characters/Children/Hero1/Abilities/Shield/GE_Hero1_Shield.uasset and /dev/null differ diff --git a/Content/Characters/Children/Hero1/Abilities/Shield/VFX_Hero1_Shield.uasset b/Content/Characters/Children/Hero1/Abilities/Shield/VFX_Hero1_Shield.uasset deleted file mode 100644 index 34f4d2a..0000000 Binary files a/Content/Characters/Children/Hero1/Abilities/Shield/VFX_Hero1_Shield.uasset and /dev/null differ diff --git a/Content/Characters/Children/Hero1/BP_Hero1.uasset b/Content/Characters/Children/Hero1/BP_Hero1.uasset deleted file mode 100644 index 3503d97..0000000 Binary files a/Content/Characters/Children/Hero1/BP_Hero1.uasset and /dev/null differ diff --git a/Content/Characters/Children/Hero2/BP_Hero2.uasset b/Content/Characters/Children/Hero2/BP_Hero2.uasset deleted file mode 100644 index ebf411e..0000000 Binary files a/Content/Characters/Children/Hero2/BP_Hero2.uasset and /dev/null differ diff --git a/Content/Characters/Children/Hero2/Effects/GE_Hero2.uasset b/Content/Characters/Children/Hero2/Effects/GE_Hero2.uasset deleted file mode 100644 index 0f4f65e..0000000 Binary files a/Content/Characters/Children/Hero2/Effects/GE_Hero2.uasset and /dev/null differ diff --git a/Content/Characters/Creature1/Attributes/GE_Creature1.uasset b/Content/Characters/Creature1/Attributes/GE_Creature1.uasset new file mode 100644 index 0000000..73270c6 Binary files /dev/null and b/Content/Characters/Creature1/Attributes/GE_Creature1.uasset differ diff --git a/Content/Characters/Creature1/BP_Creature1.uasset b/Content/Characters/Creature1/BP_Creature1.uasset new file mode 100644 index 0000000..6e5a98a Binary files /dev/null and b/Content/Characters/Creature1/BP_Creature1.uasset differ diff --git a/Content/Characters/Children/Creature1/Materials/MI_Creature1_01.uasset b/Content/Characters/Creature1/Materials/MI_Creature1_01.uasset similarity index 91% rename from Content/Characters/Children/Creature1/Materials/MI_Creature1_01.uasset rename to Content/Characters/Creature1/Materials/MI_Creature1_01.uasset index 2c11e3d..c15433e 100644 Binary files a/Content/Characters/Children/Creature1/Materials/MI_Creature1_01.uasset and b/Content/Characters/Creature1/Materials/MI_Creature1_01.uasset differ diff --git a/Content/Characters/Children/Creature1/Materials/MI_Creature1_02.uasset b/Content/Characters/Creature1/Materials/MI_Creature1_02.uasset similarity index 91% rename from Content/Characters/Children/Creature1/Materials/MI_Creature1_02.uasset rename to Content/Characters/Creature1/Materials/MI_Creature1_02.uasset index 2a0c935..37f1c59 100644 Binary files a/Content/Characters/Children/Creature1/Materials/MI_Creature1_02.uasset and b/Content/Characters/Creature1/Materials/MI_Creature1_02.uasset differ diff --git a/Content/Characters/Creature2/Attributes/GE_Creature2.uasset b/Content/Characters/Creature2/Attributes/GE_Creature2.uasset new file mode 100644 index 0000000..27ba3b0 Binary files /dev/null and b/Content/Characters/Creature2/Attributes/GE_Creature2.uasset differ diff --git a/Content/Characters/Creature2/BP_Creature2.uasset b/Content/Characters/Creature2/BP_Creature2.uasset new file mode 100644 index 0000000..766f172 Binary files /dev/null and b/Content/Characters/Creature2/BP_Creature2.uasset differ diff --git a/Content/Characters/Children/Creature2/Materials/MI_Creature2_01.uasset b/Content/Characters/Creature2/Materials/MI_Creature2_01.uasset similarity index 90% rename from Content/Characters/Children/Creature2/Materials/MI_Creature2_01.uasset rename to Content/Characters/Creature2/Materials/MI_Creature2_01.uasset index e36d5a9..f5654b6 100644 Binary files a/Content/Characters/Children/Creature2/Materials/MI_Creature2_01.uasset and b/Content/Characters/Creature2/Materials/MI_Creature2_01.uasset differ diff --git a/Content/Characters/Children/Creature2/Materials/MI_Creature2_02.uasset b/Content/Characters/Creature2/Materials/MI_Creature2_02.uasset similarity index 91% rename from Content/Characters/Children/Creature2/Materials/MI_Creature2_02.uasset rename to Content/Characters/Creature2/Materials/MI_Creature2_02.uasset index 752f5f7..980576b 100644 Binary files a/Content/Characters/Children/Creature2/Materials/MI_Creature2_02.uasset and b/Content/Characters/Creature2/Materials/MI_Creature2_02.uasset differ diff --git a/Content/Characters/Children/Hero1/Abilities/Blast/AM_Hero1_Blast.uasset b/Content/Characters/Hero1/Abilities/Blast/AM_Hero1_Blast.uasset similarity index 83% rename from Content/Characters/Children/Hero1/Abilities/Blast/AM_Hero1_Blast.uasset rename to Content/Characters/Hero1/Abilities/Blast/AM_Hero1_Blast.uasset index 654e440..ed7e432 100644 Binary files a/Content/Characters/Children/Hero1/Abilities/Blast/AM_Hero1_Blast.uasset and b/Content/Characters/Hero1/Abilities/Blast/AM_Hero1_Blast.uasset differ diff --git a/Content/Characters/Children/Hero1/Abilities/Blast/AN_Hero1_Blast.uasset b/Content/Characters/Hero1/Abilities/Blast/AN_Hero1_Blast.uasset similarity index 99% rename from Content/Characters/Children/Hero1/Abilities/Blast/AN_Hero1_Blast.uasset rename to Content/Characters/Hero1/Abilities/Blast/AN_Hero1_Blast.uasset index c8d7d96..805ca91 100644 Binary files a/Content/Characters/Children/Hero1/Abilities/Blast/AN_Hero1_Blast.uasset and b/Content/Characters/Hero1/Abilities/Blast/AN_Hero1_Blast.uasset differ diff --git a/Content/Characters/Hero1/Abilities/Blast/GA_Hero1_Blast.uasset b/Content/Characters/Hero1/Abilities/Blast/GA_Hero1_Blast.uasset new file mode 100644 index 0000000..ebb2103 Binary files /dev/null and b/Content/Characters/Hero1/Abilities/Blast/GA_Hero1_Blast.uasset differ diff --git a/Content/Characters/Hero1/Abilities/Blast/GC_Hero1_Blast_Area.uasset b/Content/Characters/Hero1/Abilities/Blast/GC_Hero1_Blast_Area.uasset new file mode 100644 index 0000000..d77cc69 Binary files /dev/null and b/Content/Characters/Hero1/Abilities/Blast/GC_Hero1_Blast_Area.uasset differ diff --git a/Content/Characters/Children/Hero1/Abilities/Blast/GE_Hero1_Blast_Target.uasset b/Content/Characters/Hero1/Abilities/Blast/GE_Hero1_Blast_Target.uasset similarity index 72% rename from Content/Characters/Children/Hero1/Abilities/Blast/GE_Hero1_Blast_Target.uasset rename to Content/Characters/Hero1/Abilities/Blast/GE_Hero1_Blast_Target.uasset index 13ed499..b629bab 100644 Binary files a/Content/Characters/Children/Hero1/Abilities/Blast/GE_Hero1_Blast_Target.uasset and b/Content/Characters/Hero1/Abilities/Blast/GE_Hero1_Blast_Target.uasset differ diff --git a/Content/Characters/Children/Hero1/Abilities/Blast/VFX_Hero1_Blast_Area.uasset b/Content/Characters/Hero1/Abilities/Blast/VFX_Hero1_Blast_Area.uasset similarity index 94% rename from Content/Characters/Children/Hero1/Abilities/Blast/VFX_Hero1_Blast_Area.uasset rename to Content/Characters/Hero1/Abilities/Blast/VFX_Hero1_Blast_Area.uasset index 2cfdb18..122bf6b 100644 Binary files a/Content/Characters/Children/Hero1/Abilities/Blast/VFX_Hero1_Blast_Area.uasset and b/Content/Characters/Hero1/Abilities/Blast/VFX_Hero1_Blast_Area.uasset differ diff --git a/Content/Characters/Children/Hero1/Abilities/Jump/GA_Hero1_Jump.uasset b/Content/Characters/Hero1/Abilities/Jump/GA_Hero1_Jump.uasset similarity index 76% rename from Content/Characters/Children/Hero1/Abilities/Jump/GA_Hero1_Jump.uasset rename to Content/Characters/Hero1/Abilities/Jump/GA_Hero1_Jump.uasset index fade22b..703b478 100644 Binary files a/Content/Characters/Children/Hero1/Abilities/Jump/GA_Hero1_Jump.uasset and b/Content/Characters/Hero1/Abilities/Jump/GA_Hero1_Jump.uasset differ diff --git a/Content/Characters/Hero1/Abilities/Poison/AM_Hero1_Poison.uasset b/Content/Characters/Hero1/Abilities/Poison/AM_Hero1_Poison.uasset new file mode 100644 index 0000000..3251b27 Binary files /dev/null and b/Content/Characters/Hero1/Abilities/Poison/AM_Hero1_Poison.uasset differ diff --git a/Content/Characters/Hero1/Abilities/Poison/AN_Hero1_Poison.uasset b/Content/Characters/Hero1/Abilities/Poison/AN_Hero1_Poison.uasset new file mode 100644 index 0000000..a592b92 Binary files /dev/null and b/Content/Characters/Hero1/Abilities/Poison/AN_Hero1_Poison.uasset differ diff --git a/Content/Characters/Hero1/Abilities/Poison/GA_Hero1_Poison.uasset b/Content/Characters/Hero1/Abilities/Poison/GA_Hero1_Poison.uasset new file mode 100644 index 0000000..f30c29b Binary files /dev/null and b/Content/Characters/Hero1/Abilities/Poison/GA_Hero1_Poison.uasset differ diff --git a/Content/Characters/Hero1/Abilities/Poison/GC_Hero1_Poison_Target.uasset b/Content/Characters/Hero1/Abilities/Poison/GC_Hero1_Poison_Target.uasset new file mode 100644 index 0000000..d479e09 Binary files /dev/null and b/Content/Characters/Hero1/Abilities/Poison/GC_Hero1_Poison_Target.uasset differ diff --git a/Content/Characters/Hero1/Abilities/Poison/GE_Hero1_Poison_Target.uasset b/Content/Characters/Hero1/Abilities/Poison/GE_Hero1_Poison_Target.uasset new file mode 100644 index 0000000..aca458d Binary files /dev/null and b/Content/Characters/Hero1/Abilities/Poison/GE_Hero1_Poison_Target.uasset differ diff --git a/Content/Characters/Hero1/Abilities/Poison/VFX_Hero1_Poison_Target.uasset b/Content/Characters/Hero1/Abilities/Poison/VFX_Hero1_Poison_Target.uasset new file mode 100644 index 0000000..bb42a4a Binary files /dev/null and b/Content/Characters/Hero1/Abilities/Poison/VFX_Hero1_Poison_Target.uasset differ diff --git a/Content/Characters/Hero1/Abilities/Shield/AM_Hero1_Shield.uasset b/Content/Characters/Hero1/Abilities/Shield/AM_Hero1_Shield.uasset new file mode 100644 index 0000000..f99b7e2 Binary files /dev/null and b/Content/Characters/Hero1/Abilities/Shield/AM_Hero1_Shield.uasset differ diff --git a/Content/Characters/Hero1/Abilities/Shield/AN_Hero1_Shield.uasset b/Content/Characters/Hero1/Abilities/Shield/AN_Hero1_Shield.uasset new file mode 100644 index 0000000..98e74e8 Binary files /dev/null and b/Content/Characters/Hero1/Abilities/Shield/AN_Hero1_Shield.uasset differ diff --git a/Content/Characters/Hero1/Abilities/Shield/GA_Hero1_Shield.uasset b/Content/Characters/Hero1/Abilities/Shield/GA_Hero1_Shield.uasset new file mode 100644 index 0000000..0d9156f Binary files /dev/null and b/Content/Characters/Hero1/Abilities/Shield/GA_Hero1_Shield.uasset differ diff --git a/Content/Characters/Children/Hero1/Abilities/Shield/GC_Hero1_Shield.uasset b/Content/Characters/Hero1/Abilities/Shield/GC_Hero1_Shield.uasset similarity index 77% rename from Content/Characters/Children/Hero1/Abilities/Shield/GC_Hero1_Shield.uasset rename to Content/Characters/Hero1/Abilities/Shield/GC_Hero1_Shield.uasset index cf29839..ec59901 100644 Binary files a/Content/Characters/Children/Hero1/Abilities/Shield/GC_Hero1_Shield.uasset and b/Content/Characters/Hero1/Abilities/Shield/GC_Hero1_Shield.uasset differ diff --git a/Content/Characters/Hero1/Abilities/Shield/GE_Hero1_Shield.uasset b/Content/Characters/Hero1/Abilities/Shield/GE_Hero1_Shield.uasset new file mode 100644 index 0000000..bb48ca1 Binary files /dev/null and b/Content/Characters/Hero1/Abilities/Shield/GE_Hero1_Shield.uasset differ diff --git a/Content/Characters/Hero1/Abilities/Shield/VFX_Hero1_Shield.uasset b/Content/Characters/Hero1/Abilities/Shield/VFX_Hero1_Shield.uasset new file mode 100644 index 0000000..d278a96 Binary files /dev/null and b/Content/Characters/Hero1/Abilities/Shield/VFX_Hero1_Shield.uasset differ diff --git a/Content/Characters/Children/Hero1/Attributes/CT_Hero1_Attributes.uasset b/Content/Characters/Hero1/Attributes/CT_Hero1_Attributes.uasset similarity index 51% rename from Content/Characters/Children/Hero1/Attributes/CT_Hero1_Attributes.uasset rename to Content/Characters/Hero1/Attributes/CT_Hero1_Attributes.uasset index 14824e4..fd26407 100644 Binary files a/Content/Characters/Children/Hero1/Attributes/CT_Hero1_Attributes.uasset and b/Content/Characters/Hero1/Attributes/CT_Hero1_Attributes.uasset differ diff --git a/Content/Characters/Children/Hero1/Attributes/GE_Hero1_Attributes.uasset b/Content/Characters/Hero1/Attributes/GE_Hero1_Attributes.uasset similarity index 85% rename from Content/Characters/Children/Hero1/Attributes/GE_Hero1_Attributes.uasset rename to Content/Characters/Hero1/Attributes/GE_Hero1_Attributes.uasset index dfa35dc..d0edd8f 100644 Binary files a/Content/Characters/Children/Hero1/Attributes/GE_Hero1_Attributes.uasset and b/Content/Characters/Hero1/Attributes/GE_Hero1_Attributes.uasset differ diff --git a/Content/Characters/Hero1/BP_Hero1.uasset b/Content/Characters/Hero1/BP_Hero1.uasset new file mode 100644 index 0000000..54f7bcd Binary files /dev/null and b/Content/Characters/Hero1/BP_Hero1.uasset differ diff --git a/Content/Characters/Children/Hero1/Materials/MI_Hero1_01.uasset b/Content/Characters/Hero1/Materials/MI_Hero1_01.uasset similarity index 91% rename from Content/Characters/Children/Hero1/Materials/MI_Hero1_01.uasset rename to Content/Characters/Hero1/Materials/MI_Hero1_01.uasset index cf5e4c7..c85553d 100644 Binary files a/Content/Characters/Children/Hero1/Materials/MI_Hero1_01.uasset and b/Content/Characters/Hero1/Materials/MI_Hero1_01.uasset differ diff --git a/Content/Characters/Children/Hero1/Materials/MI_Hero1_02.uasset b/Content/Characters/Hero1/Materials/MI_Hero1_02.uasset similarity index 90% rename from Content/Characters/Children/Hero1/Materials/MI_Hero1_02.uasset rename to Content/Characters/Hero1/Materials/MI_Hero1_02.uasset index 3d68dab..fe83511 100644 Binary files a/Content/Characters/Children/Hero1/Materials/MI_Hero1_02.uasset and b/Content/Characters/Hero1/Materials/MI_Hero1_02.uasset differ diff --git a/Content/Characters/Children/Hero2/Abilities/Ability1/GA_Hero2_Ability1.uasset b/Content/Characters/Hero2/Abilities/Ability1/GA_Hero2_Ability1.uasset similarity index 83% rename from Content/Characters/Children/Hero2/Abilities/Ability1/GA_Hero2_Ability1.uasset rename to Content/Characters/Hero2/Abilities/Ability1/GA_Hero2_Ability1.uasset index a02617f..4d98c01 100644 Binary files a/Content/Characters/Children/Hero2/Abilities/Ability1/GA_Hero2_Ability1.uasset and b/Content/Characters/Hero2/Abilities/Ability1/GA_Hero2_Ability1.uasset differ diff --git a/Content/Characters/Children/Hero2/Abilities/Ability2/GA_Hero2_Ability2.uasset b/Content/Characters/Hero2/Abilities/Ability2/GA_Hero2_Ability2.uasset similarity index 83% rename from Content/Characters/Children/Hero2/Abilities/Ability2/GA_Hero2_Ability2.uasset rename to Content/Characters/Hero2/Abilities/Ability2/GA_Hero2_Ability2.uasset index 6737ba2..dcb0820 100644 Binary files a/Content/Characters/Children/Hero2/Abilities/Ability2/GA_Hero2_Ability2.uasset and b/Content/Characters/Hero2/Abilities/Ability2/GA_Hero2_Ability2.uasset differ diff --git a/Content/Characters/Children/Hero2/Abilities/Ability3/GA_Hero2_Ability3.uasset b/Content/Characters/Hero2/Abilities/Ability3/GA_Hero2_Ability3.uasset similarity index 83% rename from Content/Characters/Children/Hero2/Abilities/Ability3/GA_Hero2_Ability3.uasset rename to Content/Characters/Hero2/Abilities/Ability3/GA_Hero2_Ability3.uasset index afd0df4..4ec5dbe 100644 Binary files a/Content/Characters/Children/Hero2/Abilities/Ability3/GA_Hero2_Ability3.uasset and b/Content/Characters/Hero2/Abilities/Ability3/GA_Hero2_Ability3.uasset differ diff --git a/Content/Characters/Children/Hero2/Abilities/Ability4/GA_Hero2_Ability4.uasset b/Content/Characters/Hero2/Abilities/Ability4/GA_Hero2_Ability4.uasset similarity index 83% rename from Content/Characters/Children/Hero2/Abilities/Ability4/GA_Hero2_Ability4.uasset rename to Content/Characters/Hero2/Abilities/Ability4/GA_Hero2_Ability4.uasset index 81ec68d..814c274 100644 Binary files a/Content/Characters/Children/Hero2/Abilities/Ability4/GA_Hero2_Ability4.uasset and b/Content/Characters/Hero2/Abilities/Ability4/GA_Hero2_Ability4.uasset differ diff --git a/Content/Characters/Hero2/Attributes/GE_Hero2_Attributes.uasset b/Content/Characters/Hero2/Attributes/GE_Hero2_Attributes.uasset new file mode 100644 index 0000000..8f6af04 Binary files /dev/null and b/Content/Characters/Hero2/Attributes/GE_Hero2_Attributes.uasset differ diff --git a/Content/Characters/Hero2/BP_Hero2.uasset b/Content/Characters/Hero2/BP_Hero2.uasset new file mode 100644 index 0000000..9b02050 Binary files /dev/null and b/Content/Characters/Hero2/BP_Hero2.uasset differ diff --git a/Content/Characters/Children/Hero2/Materials/MI_Hero2_01.uasset b/Content/Characters/Hero2/Materials/MI_Hero2_01.uasset similarity index 90% rename from Content/Characters/Children/Hero2/Materials/MI_Hero2_01.uasset rename to Content/Characters/Hero2/Materials/MI_Hero2_01.uasset index 4596b73..aae0fc0 100644 Binary files a/Content/Characters/Children/Hero2/Materials/MI_Hero2_01.uasset and b/Content/Characters/Hero2/Materials/MI_Hero2_01.uasset differ diff --git a/Content/Characters/Children/Hero2/Materials/MI_Hero2_02.uasset b/Content/Characters/Hero2/Materials/MI_Hero2_02.uasset similarity index 92% rename from Content/Characters/Children/Hero2/Materials/MI_Hero2_02.uasset rename to Content/Characters/Hero2/Materials/MI_Hero2_02.uasset index 360963a..48bb5ce 100644 Binary files a/Content/Characters/Children/Hero2/Materials/MI_Hero2_02.uasset and b/Content/Characters/Hero2/Materials/MI_Hero2_02.uasset differ diff --git a/Content/Core/Debug/DA_Debug_Abilities.uasset b/Content/Core/Debug/DA_Debug_Abilities.uasset index 39fa80f..d619851 100644 Binary files a/Content/Core/Debug/DA_Debug_Abilities.uasset and b/Content/Core/Debug/DA_Debug_Abilities.uasset differ diff --git a/Content/Core/Debug/DA_Debug_Cheats.uasset b/Content/Core/Debug/DA_Debug_Cheats.uasset index 9d53ecd..b8e39b9 100644 Binary files a/Content/Core/Debug/DA_Debug_Cheats.uasset and b/Content/Core/Debug/DA_Debug_Cheats.uasset differ diff --git a/Content/Core/Debug/DA_Debug_Pools.uasset b/Content/Core/Debug/DA_Debug_Pools.uasset index 2332c28..d2d75a9 100644 Binary files a/Content/Core/Debug/DA_Debug_Pools.uasset and b/Content/Core/Debug/DA_Debug_Pools.uasset differ diff --git a/Content/Core/Debug/DA_Debug_Spawns.uasset b/Content/Core/Debug/DA_Debug_Spawns.uasset index c050097..f6e5b6c 100644 Binary files a/Content/Core/Debug/DA_Debug_Spawns.uasset and b/Content/Core/Debug/DA_Debug_Spawns.uasset differ diff --git a/Content/Core/Debug/DA_Debug_Tweaks.uasset b/Content/Core/Debug/DA_Debug_Tweaks.uasset index 47f87f0..2de255d 100644 Binary files a/Content/Core/Debug/DA_Debug_Tweaks.uasset and b/Content/Core/Debug/DA_Debug_Tweaks.uasset differ diff --git a/Content/Core/Effects/BP_PoolRegen_Stamina.uasset b/Content/Core/Effects/BP_PoolRegen_Stamina.uasset deleted file mode 100644 index 793dc64..0000000 Binary files a/Content/Core/Effects/BP_PoolRegen_Stamina.uasset and /dev/null differ diff --git a/Content/Core/Effects/GE_Cooldown.uasset b/Content/Core/Effects/GE_Cooldown.uasset deleted file mode 100644 index f16387f..0000000 Binary files a/Content/Core/Effects/GE_Cooldown.uasset and /dev/null differ diff --git a/Content/Core/Effects/GE_Regen.uasset b/Content/Core/Effects/GE_Regen.uasset deleted file mode 100644 index e6be213..0000000 Binary files a/Content/Core/Effects/GE_Regen.uasset and /dev/null differ diff --git a/Content/Core/GameModes/BP_PlayerController.uasset b/Content/Core/GameModes/BP_PlayerController.uasset index 4e0091a..37f8c6c 100644 Binary files a/Content/Core/GameModes/BP_PlayerController.uasset and b/Content/Core/GameModes/BP_PlayerController.uasset differ diff --git a/Content/Core/GameModes/DA_TargetAcquisition.uasset b/Content/Core/GameModes/DA_TargetAcquisition.uasset index a12e0d1..1cbd4e6 100644 Binary files a/Content/Core/GameModes/DA_TargetAcquisition.uasset and b/Content/Core/GameModes/DA_TargetAcquisition.uasset differ diff --git a/Content/Core/GameModes/GM_CogSample.uasset b/Content/Core/GameModes/GM_CogSample.uasset index 8237ce8..bbc67f3 100644 Binary files a/Content/Core/GameModes/GM_CogSample.uasset and b/Content/Core/GameModes/GM_CogSample.uasset differ diff --git a/Content/Core/GameModes/GM_Default.uasset b/Content/Core/GameModes/GM_Default.uasset new file mode 100644 index 0000000..53e70bc Binary files /dev/null and b/Content/Core/GameModes/GM_Default.uasset differ diff --git a/Content/Core/Hud/BP_Hud.uasset b/Content/Core/Hud/BP_Hud.uasset new file mode 100644 index 0000000..1b29adb Binary files /dev/null and b/Content/Core/Hud/BP_Hud.uasset differ diff --git a/Content/Core/Hud/WBP_Hud.uasset b/Content/Core/Hud/WBP_Hud.uasset new file mode 100644 index 0000000..c615adb Binary files /dev/null and b/Content/Core/Hud/WBP_Hud.uasset differ diff --git a/Content/Core/Hud/WBP_Status.uasset b/Content/Core/Hud/WBP_Status.uasset new file mode 100644 index 0000000..a5b3ef8 Binary files /dev/null and b/Content/Core/Hud/WBP_Status.uasset differ diff --git a/Content/Core/Hud/WBP_StatusBar.uasset b/Content/Core/Hud/WBP_StatusBar.uasset new file mode 100644 index 0000000..1e75789 Binary files /dev/null and b/Content/Core/Hud/WBP_StatusBar.uasset differ diff --git a/Content/Core/IKRetargeter_Mixamo.uasset b/Content/Core/IKRetargeter_Mixamo.uasset deleted file mode 100644 index 84604f3..0000000 Binary files a/Content/Core/IKRetargeter_Mixamo.uasset and /dev/null differ diff --git a/Content/Maps/L_Default.umap b/Content/Maps/L_Default.umap index 9809742..d875dcb 100644 Binary files a/Content/Maps/L_Default.umap and b/Content/Maps/L_Default.umap differ diff --git a/Content/__ExternalActors__/Maps/L_Default/2/KZ/3Y4PAKEW3L97J087BUDMVI.uasset b/Content/__ExternalActors__/Maps/L_Default/2/KZ/3Y4PAKEW3L97J087BUDMVI.uasset new file mode 100644 index 0000000..b32da00 Binary files /dev/null and b/Content/__ExternalActors__/Maps/L_Default/2/KZ/3Y4PAKEW3L97J087BUDMVI.uasset differ diff --git a/Content/__ExternalActors__/Maps/L_Default/5/88/NDHUEK1ROBM2RCW7ZU51MM.uasset b/Content/__ExternalActors__/Maps/L_Default/5/88/NDHUEK1ROBM2RCW7ZU51MM.uasset index 92c176e..b1ece1a 100644 Binary files a/Content/__ExternalActors__/Maps/L_Default/5/88/NDHUEK1ROBM2RCW7ZU51MM.uasset and b/Content/__ExternalActors__/Maps/L_Default/5/88/NDHUEK1ROBM2RCW7ZU51MM.uasset differ diff --git a/Content/__ExternalActors__/Maps/L_Default/6/U3/6O7DJ03I0JB041XHH0L21L.uasset b/Content/__ExternalActors__/Maps/L_Default/6/U3/6O7DJ03I0JB041XHH0L21L.uasset index 83504b5..a136afd 100644 Binary files a/Content/__ExternalActors__/Maps/L_Default/6/U3/6O7DJ03I0JB041XHH0L21L.uasset and b/Content/__ExternalActors__/Maps/L_Default/6/U3/6O7DJ03I0JB041XHH0L21L.uasset differ diff --git a/Content/__ExternalActors__/Maps/L_Default/B/VG/ORCXCB1C1RR2JCZX4AT8D1.uasset b/Content/__ExternalActors__/Maps/L_Default/B/VG/ORCXCB1C1RR2JCZX4AT8D1.uasset new file mode 100644 index 0000000..5546698 Binary files /dev/null and b/Content/__ExternalActors__/Maps/L_Default/B/VG/ORCXCB1C1RR2JCZX4AT8D1.uasset differ diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Abilities.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Abilities.cpp index b07bf00..762aa2a 100644 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Abilities.cpp +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Abilities.cpp @@ -153,12 +153,13 @@ void UCogAbilityWindow_Abilities::RenderAbilitiesTable(UAbilitySystemComponent& { TArray& Abilities = AbilitySystemComponent.GetActivatableAbilities(); - if (ImGui::BeginTable("Abilities", 4, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBodyUntilResize | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersH | ImGuiTableFlags_NoBordersInBody)) + if (ImGui::BeginTable("Abilities", 5, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBodyUntilResize | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersH | ImGuiTableFlags_NoBordersInBody)) { ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("Ability"); ImGui::TableSetupColumn("Level"); ImGui::TableSetupColumn("Input"); + ImGui::TableSetupColumn("Cooldown"); ImGui::TableHeadersRow(); static int SelectedIndex = -1; @@ -240,6 +241,12 @@ void UCogAbilityWindow_Abilities::RenderAbilitiesTable(UAbilitySystemComponent& ImGui::Text("%d", Spec.InputPressed); } + //------------------------ + // Cooldown + //------------------------ + ImGui::TableNextColumn(); + RenderAbilityCooldown(AbilitySystemComponent, *Ability); + ImGui::PopStyleColor(1); ImGui::PopID(); @@ -250,6 +257,21 @@ void UCogAbilityWindow_Abilities::RenderAbilitiesTable(UAbilitySystemComponent& } } +//-------------------------------------------------------------------------------------------------------------------------- +void UCogAbilityWindow_Abilities::RenderAbilityCooldown(const UAbilitySystemComponent& AbilitySystemComponent, UGameplayAbility& Ability) +{ + float RemainingTime, CooldownDuration; + Ability.GetCooldownTimeRemainingAndDuration(Ability.GetCurrentAbilitySpec()->Handle, AbilitySystemComponent.AbilityActorInfo.Get(), RemainingTime, CooldownDuration); + + if (CooldownDuration > 0) + { + ImGui::PushStyleColor(ImGuiCol_PlotHistogram, IM_COL32(100, 100, 100, 255)); + ImGui::PushStyleColor(ImGuiCol_FrameBg, IM_COL32(0, 0, 0, 100)); + ImGui::ProgressBar(RemainingTime / CooldownDuration, ImVec2(-1, ImGui::GetTextLineHeightWithSpacing() * 0.8f), TCHAR_TO_ANSI(*FString::Printf(TEXT("%.2f / %.2f"), RemainingTime, CooldownDuration))); + ImGui::PopStyleColor(2); + } +} + //-------------------------------------------------------------------------------------------------------------------------- void UCogAbilityWindow_Abilities::RenderAbilityContextMenu(UAbilitySystemComponent& AbilitySystemComponent, FGameplayAbilitySpec& Spec, int Index) { diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Attributes.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Attributes.cpp index 9f09afa..eb778ca 100644 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Attributes.cpp +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Attributes.cpp @@ -12,7 +12,7 @@ void UCogAbilityWindow_Attributes::RenderHelp() { ImGui::Text( - "This window display the gameplay attributes of the selected actor. " + "This window displays the gameplay attributes of the selected actor. " "Attributes can be sorted by name, category or attribute set. " "Attributes with the Current value greater than the Base value are displayed in green. " "Attributes with the Current value lower than the Base value are displayed in red. " diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Effects.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Effects.cpp index fd18185..4d5039a 100644 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Effects.cpp +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Effects.cpp @@ -309,7 +309,7 @@ void UCogAbilityWindow_Effects::RenderRemainingTime(const UAbilitySystemComponen ImGui::PushStyleColor(ImGuiCol_PlotHistogram, IM_COL32(100, 100, 100, 255)); ImGui::PushStyleColor(ImGuiCol_FrameBg, IM_COL32(0, 0, 0, 100)); - ImGui::ProgressBar(RemainingTime / Duration, ImVec2(FCogWindowWidgets::GetFontWidth() * 15, ImGui::GetTextLineHeightWithSpacing() * 0.8f), TCHAR_TO_ANSI(*FString::Printf(TEXT("%.2f / %.2f"), RemainingTime, Duration))); + ImGui::ProgressBar(RemainingTime / Duration, ImVec2(-1, ImGui::GetTextLineHeightWithSpacing() * 0.8f), TCHAR_TO_ANSI(*FString::Printf(TEXT("%.2f / %.2f"), RemainingTime, Duration))); ImGui::PopStyleColor(2); } } diff --git a/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Abilities.h b/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Abilities.h index 6681dc4..c91670e 100644 --- a/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Abilities.h +++ b/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Abilities.h @@ -35,6 +35,8 @@ protected: virtual void RenderAbilitiesTable(UAbilitySystemComponent& AbilitySystemComponent); + virtual void RenderAbilityCooldown(const UAbilitySystemComponent& AbilitySystemComponent, UGameplayAbility& Ability); + virtual void RenderAbilityContextMenu(UAbilitySystemComponent& AbilitySystemComponent, FGameplayAbilitySpec& Spec, int Index); virtual void RenderOpenAbilities(); diff --git a/Plugins/CogEngine/Source/CogEngine/Private/CogEngineWindow_Audio.cpp b/Plugins/CogEngine/Source/CogEngine/Private/CogEngineWindow_Audio.cpp new file mode 100644 index 0000000..db9ed3a --- /dev/null +++ b/Plugins/CogEngine/Source/CogEngine/Private/CogEngineWindow_Audio.cpp @@ -0,0 +1,19 @@ +#include "CogEngineWindow_Audio.h" + +#include "Engine/Engine.h" + +//-------------------------------------------------------------------------------------------------------------------------- +void UCogEngineWindow_Audio::RenderHelp() +{ + ImGui::Text( + "This window displays audio settings. " + ); +} + +//-------------------------------------------------------------------------------------------------------------------------- +void UCogEngineWindow_Audio::RenderContent() +{ + Super::RenderContent(); + + +} diff --git a/Plugins/CogEngine/Source/CogEngine/Private/CogEngineWindow_Stats.cpp b/Plugins/CogEngine/Source/CogEngine/Private/CogEngineWindow_Stats.cpp index becd9be..54a3457 100644 --- a/Plugins/CogEngine/Source/CogEngine/Private/CogEngineWindow_Stats.cpp +++ b/Plugins/CogEngine/Source/CogEngine/Private/CogEngineWindow_Stats.cpp @@ -12,7 +12,7 @@ ImVec4 StatGreenColor(0.5f, 1.0f, 0.6f, 1.0f); void UCogEngineWindow_Stats::RenderHelp() { ImGui::Text( - "This window display engine stats such as FPS, Ping, Packet Loss. " + "This window displays engine stats such as FPS, Ping, Packet Loss. " ); } diff --git a/Plugins/CogEngine/Source/CogEngine/Public/CogEngineWindow_Audio.h b/Plugins/CogEngine/Source/CogEngine/Public/CogEngineWindow_Audio.h new file mode 100644 index 0000000..e297aa9 --- /dev/null +++ b/Plugins/CogEngine/Source/CogEngine/Public/CogEngineWindow_Audio.h @@ -0,0 +1,19 @@ +#pragma once + +#include "CoreMinimal.h" +#include "CogWindow.h" +#include "CogEngineWindow_Audio.generated.h" + +UCLASS() +class COGENGINE_API UCogEngineWindow_Audio : public UCogWindow +{ + GENERATED_BODY() + +public: + +protected: + + virtual void RenderHelp() override; + + virtual void RenderContent() override; +}; diff --git a/Plugins/CogInput/Source/CogInput/Private/CogInputWindow_Actions.cpp b/Plugins/CogInput/Source/CogInput/Private/CogInputWindow_Actions.cpp index 3f97f87..edd4cfc 100644 --- a/Plugins/CogInput/Source/CogInput/Private/CogInputWindow_Actions.cpp +++ b/Plugins/CogInput/Source/CogInput/Private/CogInputWindow_Actions.cpp @@ -12,7 +12,7 @@ void UCogInputWindow_Actions::RenderHelp() { ImGui::Text( - "This window display the current state of each Input Action. " + "This window displays the current state of each Input Action. " "It can also be used to inject inputs to help debugging. " "The input action are read from a Input Mapping Context defined in '%s' data asset. " , TCHAR_TO_ANSI(*GetNameSafe(ActionsAsset.Get())) diff --git a/Source/CogSample/CogDefines.h b/Source/CogSample/CogDefines.h index 45a03a2..4cb5e46 100644 --- a/Source/CogSample/CogDefines.h +++ b/Source/CogSample/CogDefines.h @@ -6,12 +6,14 @@ #define USE_COG (ENABLE_DRAW_DEBUG && !NO_LOGGING) #endif -#if !USE_COG +#if USE_COG -#define COG(expr) (0) +#define IF_COG(expr) { expr; } +#define COG_LOG_CATEGORY FLogCategoryBase -#else //!ENABLE_COG +#else //USE_COG -#define COG(expr) { expr; } +#define IF_COG(expr) (0) +#define COG_LOG_CATEGORY FNoLoggingCategory -#endif //!ENABLE_COG +#endif //USE_COG diff --git a/Source/CogSample/CogSampleCharacter.cpp b/Source/CogSample/CogSampleCharacter.cpp index ead5ef2..183a4d2 100644 --- a/Source/CogSample/CogSampleCharacter.cpp +++ b/Source/CogSample/CogSampleCharacter.cpp @@ -9,6 +9,7 @@ #include "CogSampleFunctionLibrary_Team.h" #include "CogSampleGameplayAbility.h" #include "CogSampleLogCategories.h" +#include "CogSamplePlayerController.h" #include "CogSampleRootMotionParams.h" #include "CogSampleTagLibrary.h" #include "Components/CapsuleComponent.h" @@ -93,6 +94,8 @@ void ACogSampleCharacter::BeginPlay() Subsystem->AddMappingContext(DefaultMappingContext, 0); } } + + TryFinishInitialize(); } //-------------------------------------------------------------------------------------------------------------------------- @@ -132,7 +135,7 @@ ECogInterfacesAllegiance ACogSampleCharacter::GetAllegianceWithOtherActor(const //-------------------------------------------------------------------------------------------------------------------------- void ACogSampleCharacter::InitializeAbilitySystem() { - if (bIsInitialized) + if (bIsAbilitySystemInitialized) { return; } @@ -205,7 +208,32 @@ void ACogSampleCharacter::InitializeAbilitySystem() GameplayEffectAddedHandle = AbilitySystem->OnActiveGameplayEffectAddedDelegateToSelf.AddUObject(this, &ACogSampleCharacter::OnGameplayEffectAdded); GameplayEffectRemovedHandle = AbilitySystem->OnAnyGameplayEffectRemovedDelegate().AddUObject(this, &ACogSampleCharacter::OnGameplayEffectRemoved); + bIsAbilitySystemInitialized = true; + + TryFinishInitialize(); +} + +//-------------------------------------------------------------------------------------------------------------------------- +void ACogSampleCharacter::TryFinishInitialize() +{ + if (bIsInitialized) + { + return; + } + + if (bIsAbilitySystemInitialized == false) + { + return; + } + + if (HasActorBegunPlay() == false) + { + return; + } + bIsInitialized = true; + + OnInitialized.Broadcast(this); } //-------------------------------------------------------------------------------------------------------------------------- @@ -252,9 +280,6 @@ void ACogSampleCharacter::SetupPlayerInputComponent(class UInputComponent* Playe { if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked(PlayerInputComponent)) { - EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Started, this, &ACharacter::Jump); - EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping); - EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &ACogSampleCharacter::Move); EnhancedInputComponent->BindAction(MoveZAction, ETriggerEvent::Triggered, this, &ACogSampleCharacter::MoveZ); EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &ACogSampleCharacter::Look); @@ -341,21 +366,37 @@ void ACogSampleCharacter::ActivateItem(const FInputActionValue& Value, int32 Ind //-------------------------------------------------------------------------------------------------------------------------- void ACogSampleCharacter::Move(const FInputActionValue& Value) { - const FVector2D MovementVector = Value.Get(); + FVector2D MoveInput2D = Value.Get(); + + MoveInput.X = MoveInput2D.X; + MoveInput.Y = MoveInput2D.Y; + + MoveInputInWorldSpace = MoveInput; if (Controller != nullptr) { - const FRotator Rotation = Controller->GetControlRotation(); - const FRotator YawRotation(0, Rotation.Yaw, 0); - - const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X); - const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y); - - AddMovementInput(ForwardDirection, MovementVector.Y); - AddMovementInput(RightDirection, MovementVector.X); + MoveInputInWorldSpace = TransformInputInWorldSpace(MoveInput); + AddMovementInput(MoveInputInWorldSpace); } } +//-------------------------------------------------------------------------------------------------------------------------- +FVector ACogSampleCharacter::TransformInputInWorldSpace(const FVector& Input) const +{ + if (Controller == nullptr) + { + return Input; + } + + FRotator ControlRotation = Controller->GetControlRotation(); + ControlRotation.Pitch = 0.0f; + ControlRotation.Roll = 0.0f; + + FVector WorldInput = ControlRotation.RotateVector(FVector(Input.Y, Input.X, 0.0f)); + + return WorldInput; +} + //-------------------------------------------------------------------------------------------------------------------------- void ACogSampleCharacter::MoveZ(const FInputActionValue& Value) { @@ -380,18 +421,27 @@ void ACogSampleCharacter::Look(const FInputActionValue& Value) } //-------------------------------------------------------------------------------------------------------------------------- -void ACogSampleCharacter::OnDamageReceived(float MitigatedDamage, float UnmitigatedDamage, AActor* DamageDealer, const FGameplayEffectSpec& EffectSpec) +void ACogSampleCharacter::HandleDamageReceived(const FCogSampleDamageEventParams& Params) { + OnDamageReceived.Broadcast(Params); + #if USE_COG - FCogDebugMetric::AddMetric(this, "Damage Received", MitigatedDamage, UnmitigatedDamage, false); + FCogDebugMetric::AddMetric(this, "Damage Received", Params.MitigatedDamage, Params.UnmitigatedDamage, false); #endif //USE_COG } //-------------------------------------------------------------------------------------------------------------------------- -void ACogSampleCharacter::OnDamageDealt(float MitigatedDamage, float UnmitigatedDamage, AActor* DamageReceiver, const FGameplayEffectSpec& EffectSpec) +void ACogSampleCharacter::HandleDamageDealt(const FCogSampleDamageEventParams& Params) { + OnDamageDealt.Broadcast(Params); + + if (ACogSamplePlayerController* PlayerController = Cast(GetController())) + { + PlayerController->OnPawnDealtDamage.Broadcast(Params); + } + #if USE_COG - FCogDebugMetric::AddMetric(this, "Damage Dealt", MitigatedDamage, UnmitigatedDamage, false); + FCogDebugMetric::AddMetric(this, "Damage Dealt", Params.MitigatedDamage, Params.UnmitigatedDamage, false); #endif //USE_COG } @@ -463,27 +513,27 @@ void ACogSampleCharacter::OnGhostTagNewOrRemoved(const FGameplayTag InTag, int32 check(InTag == Tag_Status_Ghost); bool bHasGhostTags = NewCount > 0; - if (bIsGhost == bHasGhostTags) + if (bIsInGhostMode == bHasGhostTags) { return; } - bIsGhost = bHasGhostTags; + bIsInGhostMode = bHasGhostTags; - SetActorEnableCollision(bIsGhost == false); - CameraBoom->bDoCollisionTest = bIsGhost == false; + SetActorEnableCollision(bIsInGhostMode == false); + CameraBoom->bDoCollisionTest = bIsInGhostMode == false; if (UCogSampleCharacterMovementComponent* MovementComponent = Cast(GetMovementComponent())) { - MovementComponent->bCheatFlying = bIsGhost; - MovementComponent->SetMovementMode(bIsGhost ? MOVE_Flying : MOVE_Falling); + MovementComponent->bCheatFlying = bIsInGhostMode; + MovementComponent->SetMovementMode(bIsInGhostMode ? MOVE_Flying : MOVE_Falling); } if (APlayerController* PlayerController = Cast(Controller)) { if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem(PlayerController->GetLocalPlayer())) { - if (bIsGhost) + if (bIsInGhostMode) { Subsystem->AddMappingContext(GhostMappingContext, 0); } @@ -619,4 +669,5 @@ FVector ACogSampleCharacter::GetTargetLocation() const void ACogSampleCharacter::GetTargetCapsules(TArray& Capsules) const { Capsules.Add(GetCapsuleComponent()); -} \ No newline at end of file +} + diff --git a/Source/CogSample/CogSampleCharacter.h b/Source/CogSample/CogSampleCharacter.h index 3f8048a..226f2ad 100644 --- a/Source/CogSample/CogSampleCharacter.h +++ b/Source/CogSample/CogSampleCharacter.h @@ -7,6 +7,7 @@ #include "CogDefines.h" #include "CogInterfaceAllegianceActor.h" #include "CogInterfaceDebugFilteredActor.h" +#include "CogSampleDamageEvent.h" #include "CogSampleTargetableInterface.h" #include "CogSampleTeamInterface.h" #include "GameFramework/Character.h" @@ -57,6 +58,9 @@ public: bool ActivateWhenGiven = false; }; +//-------------------------------------------------------------------------------------------------------------------------- +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FCogSampleCharacterEventDelegate, ACogSampleCharacter*, Character); + //-------------------------------------------------------------------------------------------------------------------------- UCLASS(config=Game) class ACogSampleCharacter : public ACharacter @@ -74,9 +78,10 @@ public: //---------------------------------------------------------------------------------------------------------------------- // ACharacter overrides //---------------------------------------------------------------------------------------------------------------------- - virtual void BeginPlay(); + + virtual void BeginPlay() override; - virtual void EndPlay(const EEndPlayReason::Type EndPlayReason); + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; virtual void MarkComponentsAsPendingKill() override; @@ -84,35 +89,42 @@ public: virtual void PossessedBy(AController* NewController) override; + void OnAcknowledgePossession(APlayerController* InController); + //---------------------------------------------------------------------------------------------------------------------- // IAbilitySystemInterface overrides //---------------------------------------------------------------------------------------------------------------------- + UFUNCTION(BlueprintPure) UAbilitySystemComponent* GetAbilitySystemComponent() const override; //---------------------------------------------------------------------------------------------------------------------- // ICogInterfacesAllegianceActor overrides //---------------------------------------------------------------------------------------------------------------------- + ECogInterfacesAllegiance GetAllegianceWithOtherActor(const AActor* OtherActor) const override; //---------------------------------------------------------------------------------------------------------------------- // ICogSampleTargetInterface overrides //---------------------------------------------------------------------------------------------------------------------- + virtual FVector GetTargetLocation() const override; virtual void GetTargetCapsules(TArray& Capsules) const override; //---------------------------------------------------------------------------------------------------------------------- - void OnAcknowledgePossession(APlayerController* InController); - - void OnDamageReceived(float DamageAmount, float UnmitigatedDamageAmount, AActor* DamageDealer, const FGameplayEffectSpec& EffectSpec); - - void OnDamageDealt(float DamageAmount, float UnmitigatedDamageAmount, AActor* DamageReceiver, const FGameplayEffectSpec& EffectSpec); - - void OnKilled(AActor* InInstigator, AActor* InCauser, const FGameplayEffectSpec& InEffectSpec, float InMagnitude); - - void OnRevived(AActor* InInstigator, AActor* InCauser, const FGameplayEffectSpec& InEffectSpec, float InMagnitude); + // Team + //---------------------------------------------------------------------------------------------------------------------- + UFUNCTION(BlueprintPure) + virtual int32 GetTeam() const override { return Team; } + + UFUNCTION(BlueprintCallable) + void SetTeamID(int32 Value); + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Team, Replicated, meta = (AllowPrivateAccess = "true")) + int32 Team = 0; + //---------------------------------------------------------------------------------------------------------------------- // Camera //---------------------------------------------------------------------------------------------------------------------- @@ -120,17 +132,21 @@ public: UCameraComponent* GetFollowCamera() const { return FollowCamera; } - /** Camera boom positioning the camera behind the character */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true")) USpringArmComponent* CameraBoom; - /** Follow camera */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true")) UCameraComponent* FollowCamera; //---------------------------------------------------------------------------------------------------------------------- // Input //---------------------------------------------------------------------------------------------------------------------- + FVector TransformInputInWorldSpace(const FVector& Input) const; + + FVector GetMoveInput() const { return MoveInput; } + + FVector GetMoveInputInWorldSpace() const { return MoveInputInWorldSpace; } + /** MappingContext */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true")) UInputMappingContext* DefaultMappingContext; @@ -139,10 +155,6 @@ public: UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true")) UInputMappingContext* GhostMappingContext; - /** Jump Input Action */ - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true")) - UInputAction* JumpAction; - /** Move Input Action */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true")) UInputAction* MoveAction; @@ -161,6 +173,17 @@ public: //---------------------------------------------------------------------------------------------------------------------- // Ability //---------------------------------------------------------------------------------------------------------------------- + UFUNCTION(BlueprintPure) + bool IsInitialized() const { return bIsInitialized; } + + void HandleDamageReceived(const FCogSampleDamageEventParams& Params); + + void HandleDamageDealt(const FCogSampleDamageEventParams& Params); + + void OnKilled(AActor* InInstigator, AActor* InCauser, const FGameplayEffectSpec& InEffectSpec, float InMagnitude); + + void OnRevived(AActor* InInstigator, AActor* InCauser, const FGameplayEffectSpec& InEffectSpec, float InMagnitude); + UPROPERTY(BlueprintReadOnly, Category = Ability, meta = (AllowPrivateAccess = "true")) UAbilitySystemComponent* AbilitySystem = nullptr; @@ -176,19 +199,15 @@ public: UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Ability) TArray> Effects; - //---------------------------------------------------------------------------------------------------------------------- - // Team - //---------------------------------------------------------------------------------------------------------------------- - - UFUNCTION(BlueprintPure) - virtual int32 GetTeam() const override { return Team; } + UPROPERTY(BlueprintAssignable) + FCogSampleCharacterEventDelegate OnInitialized; - UFUNCTION(BlueprintCallable) - void SetTeamID(int32 Value); + UPROPERTY(BlueprintAssignable) + FCogSampleDamageEventDelegate OnDamageDealt; + + UPROPERTY(BlueprintAssignable) + FCogSampleDamageEventDelegate OnDamageReceived; - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Team, Replicated, meta = (AllowPrivateAccess = "true")) - int32 Team = 0; - //---------------------------------------------------------------------------------------------------------------------- // Root Motion //---------------------------------------------------------------------------------------------------------------------- @@ -200,6 +219,7 @@ private: //---------------------------------------------------------------------------------------------------------------------- // Inputs //---------------------------------------------------------------------------------------------------------------------- + void Move(const FInputActionValue& Value); void MoveZ(const FInputActionValue& Value); @@ -212,9 +232,16 @@ private: void ActivateItem(const FInputActionValue& Value, int32 Index); + FVector MoveInput; + + FVector MoveInputInWorldSpace; + //---------------------------------------------------------------------------------------------------------------------- - // Ability system + // Ability //---------------------------------------------------------------------------------------------------------------------- + + void TryFinishInitialize(); + void InitializeAbilitySystem(); void ShutdownAbilitySystem(); @@ -232,15 +259,6 @@ private: UFUNCTION() void OnRep_ActiveAbilityHandles(); - //---------------------------------------------------------------------------------------------------------------------- - // Root Motion - //---------------------------------------------------------------------------------------------------------------------- - UFUNCTION(Reliable, Client) - void Client_ApplyRootMotion(const FCogSampleRootMotionParams& Params); - - uint16 ApplyRootMotionShared(const FCogSampleRootMotionParams& Params); - - //---------------------------------------------------------------------------------------------------------------------- UPROPERTY(ReplicatedUsing=OnRep_ActiveAbilityHandles, Transient) TArray ActiveAbilityHandles; @@ -252,9 +270,19 @@ private: FDelegateHandle ScaleAttributeDelegateHandle; - bool bIsGhost = false; + bool bIsAbilitySystemInitialized = false; bool bIsInitialized = false; + bool bIsInGhostMode = false; + + //---------------------------------------------------------------------------------------------------------------------- + // Root Motion + //---------------------------------------------------------------------------------------------------------------------- + + UFUNCTION(Reliable, Client) + void Client_ApplyRootMotion(const FCogSampleRootMotionParams& Params); + + uint16 ApplyRootMotionShared(const FCogSampleRootMotionParams& Params); }; diff --git a/Source/CogSample/CogSampleDamageEvent.h b/Source/CogSample/CogSampleDamageEvent.h new file mode 100644 index 0000000..6399da3 --- /dev/null +++ b/Source/CogSample/CogSampleDamageEvent.h @@ -0,0 +1,26 @@ +#pragma once + +#include "CoreMinimal.h" +#include "CogSampleDamageEvent.generated.h" + +//-------------------------------------------------------------------------------------------------------------------------- +USTRUCT(BlueprintType) +struct FCogSampleDamageEventParams +{ + GENERATED_BODY() + +public: + UPROPERTY(BlueprintReadWrite) + float MitigatedDamage = 0; + + UPROPERTY(BlueprintReadWrite) + float UnmitigatedDamage = 0; + + UPROPERTY(BlueprintReadWrite) + AActor* DamageDealer = nullptr; + + UPROPERTY(BlueprintReadWrite) + AActor* DamageReceiver = nullptr; +}; + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FCogSampleDamageEventDelegate, const FCogSampleDamageEventParams&, Params); diff --git a/Source/CogSample/CogSampleExecCalculation_Damage.cpp b/Source/CogSample/CogSampleExecCalculation_Damage.cpp index 24145cf..72650ed 100644 --- a/Source/CogSample/CogSampleExecCalculation_Damage.cpp +++ b/Source/CogSample/CogSampleExecCalculation_Damage.cpp @@ -59,39 +59,45 @@ void UCogSampleExecCalculation_Damage::Execute_Implementation(const FGameplayEff //----------------------------------------------------------------------------------------------------- // Get flat Damage //----------------------------------------------------------------------------------------------------- - float IncomingDamage = 0.0f; - ExecutionParams.AttemptCalculateTransientAggregatorMagnitude(Tag_Effect_Data_Damage, EvaluationParameters, IncomingDamage); + float UnmitigatedDamage = 0.0f; + ExecutionParams.AttemptCalculateTransientAggregatorMagnitude(Tag_Effect_Data_Damage, EvaluationParameters, UnmitigatedDamage); //----------------------------------------------------------------------------------------------------- // Apply resistances //----------------------------------------------------------------------------------------------------- - float ReceivedDamage = 0.0f; + float MitigatedDamage = 0.0f; if (TargetAbilitySystem->HasMatchingGameplayTag(Tag_Status_Immune_Damage) == false) { float Resistances = 0.0f; ExecutionParams.AttemptCalculateCapturedAttributeMagnitude(DamageStatics().DamageResistanceDef, EvaluationParameters, Resistances); Resistances = FMath::Min(Resistances, 1.0f); - ReceivedDamage = IncomingDamage * (1.0f - Resistances); + MitigatedDamage = UnmitigatedDamage * (1.0f - Resistances); } if (SpecAssetTags.HasTag(Tag_Effect_Type_Damage_Kill)) { - IncomingDamage = TargetAbilitySystem->GetNumericAttribute(UCogSampleAttributeSet_Health::GetMaxHealthAttribute()); - ReceivedDamage = IncomingDamage; + UnmitigatedDamage = TargetAbilitySystem->GetNumericAttribute(UCogSampleAttributeSet_Health::GetMaxHealthAttribute()); + MitigatedDamage = UnmitigatedDamage; } //----------------------------------------------------------------------------------------------------- // Apply Damage //----------------------------------------------------------------------------------------------------- - if (ReceivedDamage > 0.0f) + if (MitigatedDamage > 0.0f) { - OutExecutionOutput.AddOutputModifier(FGameplayModifierEvaluatedData(UCogSampleAttributeSet_Health::GetHealthAttribute(), EGameplayModOp::Additive, -ReceivedDamage)); + OutExecutionOutput.AddOutputModifier(FGameplayModifierEvaluatedData(UCogSampleAttributeSet_Health::GetHealthAttribute(), EGameplayModOp::Additive, -MitigatedDamage)); - TargetCharacter->OnDamageReceived(ReceivedDamage, IncomingDamage, SourceCharacter, EffectSpec); + FCogSampleDamageEventParams Params; + Params.DamageDealer = SourceCharacter; + Params.DamageReceiver = TargetCharacter; + Params.MitigatedDamage = MitigatedDamage; + Params.UnmitigatedDamage = UnmitigatedDamage; + + TargetCharacter->HandleDamageReceived(Params); if (SourceCharacter != nullptr) { - SourceCharacter->OnDamageDealt(ReceivedDamage, IncomingDamage, TargetCharacter, EffectSpec); + SourceCharacter->HandleDamageDealt(Params); } } } diff --git a/Source/CogSample/CogSampleFunctionLibrary_Gameplay.cpp b/Source/CogSample/CogSampleFunctionLibrary_Gameplay.cpp index 42bc85b..72821cc 100644 --- a/Source/CogSample/CogSampleFunctionLibrary_Gameplay.cpp +++ b/Source/CogSample/CogSampleFunctionLibrary_Gameplay.cpp @@ -9,10 +9,16 @@ #include "GameFramework/Character.h" #include "GameplayCueNotifyTypes.h" #include "GameplayEffectTypes.h" +#include "GameplayTagContainer.h" #include "Kismet/KismetMathLibrary.h" #include "Particles/ParticleSystemComponent.h" #include "ScalableFloat.h" +#if USE_COG +#include "CogDebugDraw.h" +#include "CogDebugLog.h" +#endif //USE_COG + //-------------------------------------------------------------------------------------------------------------------------- void UCogSampleFunctionLibrary_Gameplay::AdjustAttributeForMaxChange(UAbilitySystemComponent* AbilityComponent, FGameplayAttributeData& AffectedAttribute, float OldValue, float NewMaxValue, const FGameplayAttribute& AffectedAttributeProperty) { @@ -250,4 +256,62 @@ FVector2D UCogSampleFunctionLibrary_Gameplay::ScreenToViewport(const FVector2D& float UCogSampleFunctionLibrary_Gameplay::ScreenToViewport(const float Value, const FVector2D& DisplaySize) { return Value * 2.0f / FMath::Min(DisplaySize.X, DisplaySize.Y); -} \ No newline at end of file +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool UCogSampleFunctionLibrary_Gameplay::HasLineOfSight( + const UWorld* World, + const FVector& Start, + const FVector& End, + const FCollisionObjectQueryParams& BlockersParams, + const FCollisionQueryParams& QueryParams, + const COG_LOG_CATEGORY& LogCategory) +{ + IF_COG(FCogDebugDraw::Sphere(LogCategory, World, Start, 5.0f, FColor::Black, false, 0)); + IF_COG(FCogDebugDraw::Sphere(LogCategory, World, End, 10.0f, FColor::Black, false, 0)); + + FHitResult BlockerRaycastHit; + if (World->LineTraceSingleByObjectType(BlockerRaycastHit, Start, End, BlockersParams, QueryParams)) + { + IF_COG(FCogDebugDraw::Segment(LogCategory, World, Start, End, FColor(0, 0, 0, 10), false, 0)); + IF_COG(FCogDebugDraw::Sphere(LogCategory, World, BlockerRaycastHit.ImpactPoint, 5.0f, FColor::Red, false, 0)); + } + else + { + IF_COG(FCogDebugDraw::Segment(LogCategory, World, Start, End, FColor(255, 255, 255, 10), false, 0)); + + //-------------------------------------------------------------------------------------------------------------- + // We didn't touch a blocker, we have line of sight. + //-------------------------------------------------------------------------------------------------------------- + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool UCogSampleFunctionLibrary_Gameplay::IsActorAbilitySystemMatchingTags(const UAbilitySystemComponent* AbilitySystem, const FGameplayTagContainer& RequiredTags, const FGameplayTagContainer& IgnoredTags) +{ + if (AbilitySystem == nullptr) + { + return false; + } + + const bool bHasRequiredTags = AbilitySystem->HasAllMatchingGameplayTags(RequiredTags); + const bool bHasIgnoredTags = AbilitySystem->HasAnyMatchingGameplayTags(IgnoredTags); + + if (bHasRequiredTags && bHasIgnoredTags == false) + { + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool UCogSampleFunctionLibrary_Gameplay::IsActorMatchingTags(const AActor* Actor, const FGameplayTagContainer& RequiredTags, const FGameplayTagContainer& IgnoredTags) +{ + const UAbilitySystemComponent* AbilitySystem = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Actor); + bool Result = IsActorAbilitySystemMatchingTags(AbilitySystem, RequiredTags, IgnoredTags); + return Result; +} diff --git a/Source/CogSample/CogSampleFunctionLibrary_Gameplay.h b/Source/CogSample/CogSampleFunctionLibrary_Gameplay.h index 7974fc8..bc8eed4 100644 --- a/Source/CogSample/CogSampleFunctionLibrary_Gameplay.h +++ b/Source/CogSample/CogSampleFunctionLibrary_Gameplay.h @@ -1,6 +1,7 @@ #pragma once #include "CoreMinimal.h" +#include "CogDefines.h" #include "CogSampleFunctionLibrary_Gameplay.generated.h" class UAbilitySystemComponent; @@ -10,6 +11,7 @@ struct FGameplayAttribute; struct FGameplayAttributeData; struct FGameplayCueNotify_SpawnResult; struct FGameplayCueParameters; +struct FGameplayTagContainer; //-------------------------------------------------------------------------------------------------------------------------- #define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \ @@ -73,4 +75,11 @@ public: static FVector2D ScreenToViewport(const FVector2D& value, const FVector2D& displaySize); static float ScreenToViewport(const float value, const FVector2D& displaySize); + + static bool HasLineOfSight(const UWorld* World, const FVector& Start, const FVector& End, const FCollisionObjectQueryParams& BlockersParams, const FCollisionQueryParams& QueryParams, const COG_LOG_CATEGORY& LogCategory); + + static bool IsActorAbilitySystemMatchingTags(const UAbilitySystemComponent* AbilitySystem, const FGameplayTagContainer& RequiredTags, const FGameplayTagContainer& IgnoredTags); + + static bool IsActorMatchingTags(const AActor* Actor, const FGameplayTagContainer& RequiredTags, const FGameplayTagContainer& IgnoredTags); + }; diff --git a/Source/CogSample/CogSamplePlayerController.cpp b/Source/CogSample/CogSamplePlayerController.cpp index 6ce3d86..a0e75f5 100644 --- a/Source/CogSample/CogSamplePlayerController.cpp +++ b/Source/CogSample/CogSamplePlayerController.cpp @@ -51,6 +51,32 @@ void ACogSamplePlayerController::Tick(float DeltaSeconds) TArray TagretToIgnore; FCogSampleTargetAcquisitionResult Result; TargetAcquisition->FindBestTarget(this, TagretToIgnore, nullptr, true, FVector2D::ZeroVector, false, Result); - Target = Result.Target; + SetTarget(Result.Target); } -} \ No newline at end of file +} + +//-------------------------------------------------------------------------------------------------------------------------- +void ACogSamplePlayerController::SetTarget(AActor* Value) +{ + if (Value == Target) + { + return; + } + + AActor* OldTarget = Target.Get(); + + Target = Value; + + if (GetLocalRole() == ROLE_AutonomousProxy) + { + Server_SetTarget(Value); + } + + OnTargetChanged.Broadcast(this, Target.Get(), OldTarget); +} + +//-------------------------------------------------------------------------------------------------------------------------- +void ACogSamplePlayerController::Server_SetTarget_Implementation(AActor* Value) +{ + Target = Value; +} diff --git a/Source/CogSample/CogSamplePlayerController.h b/Source/CogSample/CogSamplePlayerController.h index 89cc44b..840bf3d 100644 --- a/Source/CogSample/CogSamplePlayerController.h +++ b/Source/CogSample/CogSamplePlayerController.h @@ -2,11 +2,16 @@ #include "CoreMinimal.h" #include "AbilitySystemInterface.h" +#include "CogSampleDamageEvent.h" #include "GameFramework/PlayerController.h" #include "CogSamplePlayerController.generated.h" class UCogSampleTargetAcquisition; +//-------------------------------------------------------------------------------------------------------------------------- +DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FCogSampleTargetChangedEventDelegate, ACogSamplePlayerController*, Controller, AActor*, NewTarget, AActor*, OldTarget); + +//-------------------------------------------------------------------------------------------------------------------------- UCLASS(config=Game) class ACogSamplePlayerController : public APlayerController { @@ -22,12 +27,25 @@ public: virtual void Tick(float DeltaSeconds); + void SetTarget(AActor* Value); + + AActor* GetTarget() const { return Target.Get(); } + + UPROPERTY(BlueprintAssignable) + FCogSampleTargetChangedEventDelegate OnTargetChanged; + + UPROPERTY(BlueprintAssignable) + FCogSampleDamageEventDelegate OnPawnDealtDamage; + private: + UFUNCTION(Reliable, Server) + void Server_SetTarget(AActor* Value); + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = TargetAcquisition, meta = (AllowPrivateAccess = "true")) UCogSampleTargetAcquisition* TargetAcquisition = nullptr; UPROPERTY(BlueprintReadOnly, Category = TargetAcquisition, meta = (AllowPrivateAccess = "true")) - TSoftObjectPtr Target = nullptr; + TWeakObjectPtr Target = nullptr; }; diff --git a/Source/CogSample/CogSampleTargetAcquisition.cpp b/Source/CogSample/CogSampleTargetAcquisition.cpp index 4ba3299..e3b7e2c 100644 --- a/Source/CogSample/CogSampleTargetAcquisition.cpp +++ b/Source/CogSample/CogSampleTargetAcquisition.cpp @@ -15,9 +15,9 @@ #endif //USE_COG //-------------------------------------------------------------------------------------------------------------------------- -// UCogSampleTargetAcquisition_Generic +// FCogSampleTargetTargetAcquisitionParams //-------------------------------------------------------------------------------------------------------------------------- -struct FCogSampleTargetCandidateEvaluationParameters +struct FCogSampleTargetTargetAcquisitionParams { const AActor* Source; FVector SourceLocation; @@ -35,18 +35,11 @@ struct FCogSampleTargetCandidateEvaluationParameters FVector2D SearchDirectionScreenOrigin = FVector2D::ZeroVector; FVector2D SearchDirectionNormalized = FVector2D::ZeroVector; bool IsDebugPersistent = false; + bool IsCrosshairInsideAnyCandidate = false; }; //-------------------------------------------------------------------------------------------------------------------------- -struct FCogSampleTargetCandidateEvaluationResult -{ - AActor* BestTarget; - float MinScore; - bool bFoundLocationInsideShape; -}; - -//-------------------------------------------------------------------------------------------------------------------------- -// UCogSampleTargetAcquisition_Generic +// UCogSampleTargetAcquisition //-------------------------------------------------------------------------------------------------------------------------- void UCogSampleTargetAcquisition::FindBestTargets( const APlayerController* Controller, @@ -60,7 +53,7 @@ void UCogSampleTargetAcquisition::FindBestTargets( { TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::FindBestTargets); - COG(FCogDebugDraw::String2D(LogCogTargetAcquisition, Controller, GetName(), FVector2D(20, 20), FColor::White, bIsDebugPersistent)); + IF_COG(FCogDebugDraw::String2D(LogCogTargetAcquisition, Controller, GetName(), FVector2D(20, 20), FColor::White, bIsDebugPersistent)); TArray TempTargetsToIgnore(TargetsToIgnore); @@ -136,7 +129,7 @@ void UCogSampleTargetAcquisition::FindBestTarget( const FVector2D SearchDirectionNormalized = (TargetSwitchSearchDirection.IsNearlyZero() == false) ? TargetSwitchSearchDirection.GetSafeNormal() : FVector2D::ZeroVector; if (SearchDirectionNormalized.IsNearlyZero() == false) { - COG(FCogDebugDraw::Segment2D(LogCogTargetAcquisition, Controller, FVector2D::ZeroVector, FVector2D(SearchDirectionNormalized.X, -SearchDirectionNormalized.Y), FColor(255, 255, 0, 255), bIsDebugPersistent)); + IF_COG(FCogDebugDraw::Segment2D(LogCogTargetAcquisition, Controller, FVector2D::ZeroVector, FVector2D(SearchDirectionNormalized.X, -SearchDirectionNormalized.Y), FColor(255, 255, 0, 255), bIsDebugPersistent)); } #endif //USE_COG @@ -155,7 +148,7 @@ void UCogSampleTargetAcquisition::FindBestTarget( const FQuat CapsuleRotation = (CastRotation + FRotator(90, 0, 0)).Quaternion(); const FCollisionShape CapsuleShape = FCollisionShape::MakeCapsule(CapsuleRadius, CapsuleHalfHeight); - COG(FCogDebugDraw::Capsule(LogCogTargetAcquisition, Controller, CapsuleCenter, CapsuleHalfHeight, CapsuleRadius, CapsuleRotation, FColor::Yellow, bIsDebugPersistent, 0)); + IF_COG(FCogDebugDraw::Capsule(LogCogTargetAcquisition, Controller, CapsuleCenter, CapsuleHalfHeight, CapsuleRadius, CapsuleRotation, FColor::Yellow, bIsDebugPersistent, 0)); //------------------------------------------------- // Gather targets asynchronously @@ -220,7 +213,7 @@ void UCogSampleTargetAcquisition::FindBestTarget( { if (CheckIfTargetValid(Controller, Character, Actor) == false) { - COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, "Filter", UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(Actor), FColor::Red, bIsDebugPersistent)); + IF_COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, "Filter", UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(Actor), FColor::Red, bIsDebugPersistent)); continue; } @@ -255,20 +248,161 @@ bool UCogSampleTargetAcquisition::GetViewInfo( return true; } +//-------------------------------------------------------------------------------------------------------------------------- +void UCogSampleTargetAcquisition::FindBestTargetInCandidates( + const APlayerController* Controller, + const TArray& TargetsToIgnore, + const TArray& Candidates, + const FVector2D ScreenSearchDirection, + const FVector2D SearchDirectionScreenOrigin, + const bool bIsDebugPersistent, + FCogSampleTargetAcquisitionResult& Result) const +{ + TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::FindBestTargetInCandidates); + + ACogSampleCharacter* Character = Cast(Controller->GetPawn()); + if (Character == nullptr) + { + return; + } + + //---------------------------------------------------------------------------------------------------------------------- + // Compute view matrix to project each candidate capsules in screen space + //---------------------------------------------------------------------------------------------------------------------- + FMatrix ViewProjectionMatrix; + FIntRect ViewRect; + if (GetViewInfo(Controller, ViewProjectionMatrix, ViewRect) == false) + { + return; + } + + + + FVector2D ScreenSize(ViewRect.Width(), ViewRect.Height()); + FVector2D ScreenCrosshairPosition = ScreenSize * 0.5f;; + + //---------------------------------------------------------------------------------------------------------------------- + // Draw screen limits + //---------------------------------------------------------------------------------------------------------------------- + +#if USE_COG + + FCogDebugDraw::Circle2D(LogCogTargetAcquisition, Controller, ScreenCrosshairPosition, 5.0f, FColor(255, 255, 255, 255), bIsDebugPersistent); + + if (bUseScreenLimit) + { + if (ScreenLimitType == ECogSampleTargetAcquisitionScreenLimitType::Rectangle) + { + FCogDebugDraw::Rect2D( + LogCogTargetAcquisition, + Controller, + UCogSampleFunctionLibrary_Gameplay::ViewportToScreen(FVector2D(-ScreenMaxX, -ScreenMaxY), ScreenSize), + UCogSampleFunctionLibrary_Gameplay::ViewportToScreen(FVector2D(ScreenMaxX, ScreenMaxY), ScreenSize), + FColor(255, 255, 255, 255), + bIsDebugPersistent); + } + else + { + FCogDebugDraw::Circle2D( + LogCogTargetAcquisition, + Controller, + ScreenCrosshairPosition, + UCogSampleFunctionLibrary_Gameplay::ViewportToScreen(ScreenMaxX, ScreenSize), + FColor(255, 255, 255, 255), + bIsDebugPersistent); + } + } +#endif //USE_COG + + const FRotator YawRotation = GetReferentialRotation(Character, YawReferential); + const FVector YawDirection = YawRotation.Vector(); + + FCogSampleTargetTargetAcquisitionParams Params; + Params.Source = Character; + Params.SourceLocation = UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(Character); + Params.Controller = Controller; + Params.TargetsToIgnore = TargetsToIgnore; + Params.bWorldDistanceIgnoreZ = WorldDistanceIgnoreZ; + Params.MaxWorldDistance = WorldDistanceMax; + Params.CrosshairPosition = ScreenCrosshairPosition; + Params.YawDirection = YawDirection; + Params.CameraRight = Character->GetFollowCamera()->GetComponentQuat().GetRightVector(); + Params.ViewProjectionMatrix = ViewProjectionMatrix; + Params.ViewRect = ViewRect; + Params.BlockersParams = UCogSampleFunctionLibrary_Gameplay::ConfigureCollisionObjectParams(BlockerTypes); + Params.bUseSearchDirection = ScreenSearchDirection.IsNearlyZero() == false; + Params.SearchDirectionScreenOrigin = SearchDirectionScreenOrigin; + Params.SearchDirectionNormalized = Params.bUseSearchDirection ? ScreenSearchDirection.GetSafeNormal() : FVector2D::ZeroVector; + Params.IsDebugPersistent = bIsDebugPersistent; + Params.IsCrosshairInsideAnyCandidate = false; + + //---------------------------------------------------------------------------------------------------------------------- + // Evaluate candidates actors + //---------------------------------------------------------------------------------------------------------------------- + float MinScore = FLT_MAX; + AActor* BestTarget = nullptr; + + bool bIsCrosshairInsideAnyTarget = false; + for (int32 i = 0; i < Candidates.Num(); ++i) + { + AActor* Candidate = Candidates[i]; + if (Candidate == nullptr) + { + continue; + } + + float CandidateScore = 0.0f; + bool bIsCrosshairInsideCandidate = false; + if (EvaluateCandidate(Candidate, Params, CandidateScore, bIsCrosshairInsideCandidate) == false) + { + continue; + } + + //----------------------------------------------------------------------------------------- + // If the crosshair is inside this candidate, we can discard subsequent candidates + // that are not inside but also the best previous candidate since we were not inside it. + //----------------------------------------------------------------------------------------- + if (bPrioritizeTargetWithCrosshairInsideThem && bIsCrosshairInsideCandidate && bIsCrosshairInsideAnyTarget == false) + { + BestTarget = nullptr; + MinScore = FLT_MAX; + } + + Params.IsCrosshairInsideAnyCandidate |= bIsCrosshairInsideCandidate; + + if (CandidateScore > MinScore) + { + continue; + } + + MinScore = CandidateScore; + BestTarget = Candidate; + } + + if (BestTarget != nullptr) + { + Result.Target = BestTarget; + Result.Score = MinScore; + + IF_COG(FCogDebugDraw::Point(LogCogTargetAcquisition, Controller, UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(Result.Target), 20.0f, FColor::Green, Params.IsDebugPersistent, 100)); + } +} + //-------------------------------------------------------------------------------------------------------------------------- bool UCogSampleTargetAcquisition::EvaluateCandidate( - AActor* CandidateTarget, - const FCogSampleTargetCandidateEvaluationParameters& EvalParams, - FCogSampleTargetCandidateEvaluationResult& EvalResult) const + AActor* Candidate, + const FCogSampleTargetTargetAcquisitionParams& EvalParams, + float& CandidateScore, + bool& bIsCrosshairInsideCandidate) const { TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::EvaluateCandidate); - if (EvalParams.TargetsToIgnore.Contains(CandidateTarget)) + if (EvalParams.TargetsToIgnore.Contains(Candidate)) { return false; } - const FVector CandidateTargetLocation = UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(CandidateTarget); + const FVector CandidateTargetLocation = UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(Candidate); FVector CandidateLocationDelta = CandidateTargetLocation - EvalParams.SourceLocation; if (EvalParams.bWorldDistanceIgnoreZ) @@ -285,7 +419,7 @@ bool UCogSampleTargetAcquisition::EvaluateCandidate( //-------------------------------------------------------------------------------------------------------------- if (CandidateWorldDistance > EvalParams.MaxWorldDistance) { - COG(FCogDebugDraw::String(LogCogTargetAcquisition, EvalParams.Controller, FString::Printf(TEXT("Dist: %0.2f"), CandidateWorldDistance * 0.01f), CandidateTargetLocation, FColor::Red, EvalParams.IsDebugPersistent)); + IF_COG(FCogDebugDraw::String(LogCogTargetAcquisition, EvalParams.Controller, FString::Printf(TEXT("Dist: %0.2f"), CandidateWorldDistance * 0.01f), CandidateTargetLocation, FColor::Red, EvalParams.IsDebugPersistent)); return false; } @@ -297,7 +431,7 @@ bool UCogSampleTargetAcquisition::EvaluateCandidate( const float CandidateYaw = FRotator::NormalizeAxis(FMath::RadiansToDegrees(FMath::Acos(CandidateDot))); if (bUseYawLimit && CandidateYaw > YawMax) { - COG(FCogDebugDraw::String(LogCogTargetAcquisition, EvalParams.Controller, FString::Printf(TEXT("Yaw: %0.2f"), CandidateYaw), CandidateTargetLocation, FColor::Red, EvalParams.IsDebugPersistent)); + IF_COG(FCogDebugDraw::String(LogCogTargetAcquisition, EvalParams.Controller, FString::Printf(TEXT("Yaw: %0.2f"), CandidateYaw), CandidateTargetLocation, FColor::Red, EvalParams.IsDebugPersistent)); return false; } @@ -309,7 +443,7 @@ bool UCogSampleTargetAcquisition::EvaluateCandidate( FVector2D CandidateClosestScreenLocation; float CandidateClosestScreenDistance; const UCapsuleComponent* CandidateBestHitZone = nullptr; - if (!ComputeCandidateScreenLocation(CandidateTarget, EvalParams, CandidateTargetLocation, CandidateScreenLocation, CandidateClosestScreenLocation, CandidateClosestScreenDistance)) + if (!ComputeCandidateScreenLocation(Candidate, EvalParams, CandidateTargetLocation, CandidateScreenLocation, CandidateClosestScreenLocation, CandidateClosestScreenDistance)) { return false; } @@ -328,32 +462,22 @@ bool UCogSampleTargetAcquisition::EvaluateCandidate( //-------------------------------------------------------------------------------------------------------------- // Raycast to verify this target is not blocked by a collision. //-------------------------------------------------------------------------------------------------------------- - if (!HasLineOfSightToTarget(EvalParams.Source, CandidateTarget, EvalParams.BlockersParams)) + if (HasLineOfSightToTarget(EvalParams.Source, EvalParams.SourceLocation, Candidate, CandidateTargetLocation, EvalParams.BlockersParams) == false) { return false; } - const bool bIsInsideCandidate = CandidateClosestScreenDistance < 0.0f; - if (!IsSearchDirectionUsed && bPrioritizeInsideHitZones) + bIsCrosshairInsideCandidate = CandidateClosestScreenDistance < 0.0f; + if (!IsSearchDirectionUsed && bPrioritizeTargetWithCrosshairInsideThem) { //-------------------------------------------------------------------------------------------------------------- // We always prioritize the candidates if the crosshair is inside them. Thus if we are inside another candidate // but not inside this one, we discard it (unless we are switching the lock target) //-------------------------------------------------------------------------------------------------------------- - if (EvalResult.bFoundLocationInsideShape && bIsInsideCandidate == false) + if (EvalParams.IsCrosshairInsideAnyCandidate && bIsCrosshairInsideCandidate == false) { return false; } - - //-------------------------------------------------------------------------------------------------------------- - // if we are inside the capsule of this candidate, we can discard subsequent candidates that are not inside - // but also the best previous candidate since we were not inside it. - //-------------------------------------------------------------------------------------------------------------- - if (bIsInsideCandidate && EvalResult.bFoundLocationInsideShape == false) - { - EvalResult.BestTarget = nullptr; - EvalResult.MinScore = FLT_MAX; - } } //-------------------------------------------------------------------------------------------------------------- @@ -403,7 +527,7 @@ bool UCogSampleTargetAcquisition::EvaluateCandidate( if (FMath::Abs(TargetAngleWithSearchDirection) > SearchDirectionMaxAngle) { - COG(FCogDebugDraw::String(LogCogTargetAcquisition, EvalParams.Controller, FString::Printf(TEXT("MaxAngle: %0.2f"), TargetAngleWithSearchDirection), CandidateTargetLocation, FColor::Red, EvalParams.IsDebugPersistent)); + IF_COG(FCogDebugDraw::String(LogCogTargetAcquisition, EvalParams.Controller, FString::Printf(TEXT("MaxAngle: %0.2f"), TargetAngleWithSearchDirection), CandidateTargetLocation, FColor::Red, EvalParams.IsDebugPersistent)); return false; } @@ -416,19 +540,15 @@ bool UCogSampleTargetAcquisition::EvaluateCandidate( //-------------------------------------------------------------------------------------------------------------- // Compute final score by summing all the scores. The best score is the smallest one. //-------------------------------------------------------------------------------------------------------------- - const float TargetScore = CandidateWorldDistanceScore + CandidateScreenDistanceScore + CandidateYawScore + SearchDirectionDistanceScore + SearchDirectionAngleScore; + CandidateScore = CandidateWorldDistanceScore + CandidateScreenDistanceScore + CandidateYawScore + SearchDirectionDistanceScore + SearchDirectionAngleScore; //-------------------------------------------------------------------------------------------------------------- // Draw the score of each candidate //-------------------------------------------------------------------------------------------------------------- #if USE_COG - /* - if (FCogDebugLog::IsLogCategoryActive(LogCogTargetAcquisition)) { - ImVec2 CandidateClosestViewportLocation = ImGui::ScreenToViewport(ImGui::ToImVec2(CandidateClosestScreenLocation)); - FCogDebugDraw::Point(LogCogTargetAcquisition, EvalParams.Controller, CandidateTargetLocation, 8.0f, FColor::Blue, EvalParams.IsDebugPersistent, 0); FString Text; @@ -438,11 +558,9 @@ bool UCogSampleTargetAcquisition::EvaluateCandidate( { Text.Append(FString::Printf(TEXT ( - "XY: %.0f %.0f \n" "SD: %.0f => %.0f => %.0f \n" ), - CandidateClosestViewportLocation.x * 100.0f, CandidateClosestViewportLocation.y * 100.0f, - CandidateClosestScreenDistance, CandidateScreenDistanceRatio * 100, CandidateScreenDistanceScore * 100)); + CandidateClosestScreenDistance, CandidateScreenDistanceRatio * 100, CandidateScreenDistanceScore * 100)); } if (bUseWorldDistanceScore) @@ -470,146 +588,24 @@ bool UCogSampleTargetAcquisition::EvaluateCandidate( SearchDirectionAngleScore * 100)); } - Text.Append(FString::Printf(TEXT("==> %.0f \n"), TargetScore * 100)); + Text.Append(FString::Printf(TEXT("==> %.0f \n"), CandidateScore * 100)); } else { - Text = FString::Printf(TEXT("%0.f"), TargetScore * 100); + Text = FString::Printf(TEXT("%0.f"), CandidateScore * 100); } FCogDebugDraw::String(LogCogTargetAcquisition, EvalParams.Controller, Text, CandidateTargetLocation, FColor::White, EvalParams.IsDebugPersistent); } - */ #endif //USE_COG - if (EvalResult.MinScore < TargetScore) - { - return false; - } - - EvalResult.BestTarget = CandidateTarget; - EvalResult.MinScore = TargetScore; - EvalResult.bFoundLocationInsideShape = EvalResult.bFoundLocationInsideShape || bIsInsideCandidate; return true; } -//-------------------------------------------------------------------------------------------------------------------------- -void UCogSampleTargetAcquisition::FindBestTargetInCandidates( - const APlayerController* Controller, - const TArray& TargetsToIgnore, - const TArray& Candidates, - const FVector2D ScreenSearchDirection, - const FVector2D SearchDirectionScreenOrigin, - const bool bIsDebugPersistent, - FCogSampleTargetAcquisitionResult& Result) const -{ - TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::FindBestTargetInCandidates); - - ACogSampleCharacter* Character = Cast(Controller->GetPawn()); - if (Character == nullptr) - { - return; - } - - //---------------------------------------------------------------------------------------------------------------------- - // Compute view matrix to project each candidate capsules in screen space - //---------------------------------------------------------------------------------------------------------------------- - FMatrix ViewProjectionMatrix; - FIntRect ViewRect; - if (GetViewInfo(Controller, ViewProjectionMatrix, ViewRect) == false) - { - return; - } - - //---------------------------------------------------------------------------------------------------------------------- - // Draw screen limits - //---------------------------------------------------------------------------------------------------------------------- - FVector2D ScreenCrosshairPosition(0.5f * ViewRect.Width(), 0.5f * ViewRect.Height()); - - COG(FCogDebugDraw::Circle2D(LogCogTargetAcquisition, Controller, ScreenCrosshairPosition, 5.0f, FColor(255, 255, 255, 255), bIsDebugPersistent)); - -#if USE_COG - //if (bUseScreenLimit) - //{ - // if (ScreenLimitType == ECogSampleTargetAcquisitionScreenLimitType::Rectangle) - // { - // COG(FCogDebugDraw::Rect2D( - // LogCogTargetAcquisition, - // Controller, - // FVector2D(-ScreenMaxX, -ScreenMaxY), - // FVector2D(ScreenMaxX, ScreenMaxY), - // FColor(255, 255, 255, 255), - // bIsDebugPersistent)); - // } - // else - // { - // COG(FCogDebugDraw::Circle2D( - // LogCogTargetAcquisition, - // Controller, - // ScreenCrosshairPosition, - // ImGui::ViewportToScreen(ScreenMaxX), - // FColor(255, 255, 255, 255), - // bIsDebugPersistent)); - // } - //} -#endif //USE_COG - - const FRotator YawRotation = GetReferentialRotation(Character, YawReferential); - const FVector YawDirection = YawRotation.Vector(); - - FCogSampleTargetCandidateEvaluationParameters EvalParams; - EvalParams.Source = Character; - EvalParams.SourceLocation = Character->GetActorLocation(); - EvalParams.Controller = Controller; - EvalParams.TargetsToIgnore = TargetsToIgnore; - EvalParams.bWorldDistanceIgnoreZ = WorldDistanceIgnoreZ; - EvalParams.MaxWorldDistance = WorldDistanceMax; - EvalParams.CrosshairPosition = ScreenCrosshairPosition; - EvalParams.YawDirection = YawDirection; - EvalParams.CameraRight = Character->GetFollowCamera()->GetComponentQuat().GetRightVector(); - EvalParams.ViewProjectionMatrix = ViewProjectionMatrix; - EvalParams.ViewRect = ViewRect; - EvalParams.BlockersParams = UCogSampleFunctionLibrary_Gameplay::ConfigureCollisionObjectParams(BlockerTypes); - EvalParams.bUseSearchDirection = ScreenSearchDirection.IsNearlyZero() == false; - EvalParams.SearchDirectionScreenOrigin = SearchDirectionScreenOrigin; - EvalParams.SearchDirectionNormalized = EvalParams.bUseSearchDirection ? ScreenSearchDirection.GetSafeNormal() : FVector2D::ZeroVector; - EvalParams.IsDebugPersistent = bIsDebugPersistent; - - FCogSampleTargetCandidateEvaluationResult EvalResult - { - nullptr, - FLT_MAX, - false - }; - - //---------------------------------------------------------------------------------------------------------------------- - // Evaluate candidates actors - //---------------------------------------------------------------------------------------------------------------------- - for (int32 i = 0; i < Candidates.Num(); ++i) - { - AActor* Candidate = Candidates[i]; - check(Candidate != nullptr); - if (Candidate == nullptr) - { - continue; - } - - EvaluateCandidate(Candidate, EvalParams, EvalResult); - } - - if (EvalResult.BestTarget != nullptr) - { - Result.Target = EvalResult.BestTarget; - Result.Score = EvalResult.MinScore; - - COG(FCogDebugDraw::Point(LogCogTargetAcquisition, Controller, UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(Result.Target), 10.0f, FColor::Green, EvalParams.IsDebugPersistent, 0)); - } -} - //-------------------------------------------------------------------------------------------------------------------------- bool UCogSampleTargetAcquisition::ComputeCandidateScreenLocation( const AActor* CandidateActor, - const FCogSampleTargetCandidateEvaluationParameters& EvalParams, + const FCogSampleTargetTargetAcquisitionParams& Params, const FVector& CandidateTargetLocation, FVector2D& CandidateScreenLocation, FVector2D& CandidateClosestScreenLocation, @@ -636,39 +632,34 @@ bool UCogSampleTargetAcquisition::ComputeCandidateScreenLocation( const FVector CapsuleLocation = Capsule->GetComponentLocation(); const FVector CapsuleTop = CapsuleLocation + FVector::UpVector * (HalfHeight - Radius); const FVector CapsuleBottom = CapsuleLocation - FVector::UpVector * (HalfHeight - Radius); - const FVector CapsuleRight = CapsuleLocation - EvalParams.CameraRight * Radius; + const FVector CapsuleRight = CapsuleLocation - Params.CameraRight * Radius; FVector2D CapsuleTop2D; FVector2D CapsuleBot2D; FVector2D CapsuleRight2D; - if (FSceneView::ProjectWorldToScreen(CapsuleTop, EvalParams.ViewRect, EvalParams.ViewProjectionMatrix, CapsuleTop2D) == false) + if (FSceneView::ProjectWorldToScreen(CapsuleTop, Params.ViewRect, Params.ViewProjectionMatrix, CapsuleTop2D) == false) { continue; } - if (FSceneView::ProjectWorldToScreen(CapsuleBottom, EvalParams.ViewRect, EvalParams.ViewProjectionMatrix, CapsuleBot2D) == false) + if (FSceneView::ProjectWorldToScreen(CapsuleBottom, Params.ViewRect, Params.ViewProjectionMatrix, CapsuleBot2D) == false) { continue; } - if (FSceneView::ProjectWorldToScreen(CapsuleRight, EvalParams.ViewRect, EvalParams.ViewProjectionMatrix, CapsuleRight2D) == false) + if (FSceneView::ProjectWorldToScreen(CapsuleRight, Params.ViewRect, Params.ViewProjectionMatrix, CapsuleRight2D) == false) { continue; } - //if (Type == ECogSampleTargetAcquisitionType::Melee && CandidateCharacter != nullptr && !UCogFunctionLibrary_Targeting::IsTargetCapsuleReachableByMelee(EvalParams.Source, CandidateCharacter, Capsule)) - //{ - // continue; - //} - const FVector2D CapsuleCenter2D = CapsuleBot2D + 0.5f * (CapsuleTop2D - CapsuleBot2D); const float CapsuleRadius2D = FVector2D::Distance(CapsuleCenter2D, CapsuleRight2D); FVector2D Projection; float Time; float ScreenCenterToCapsuleDistance; - UCogSampleFunctionLibrary_Gameplay::FindCapsulePointDistance(CapsuleBot2D, CapsuleTop2D, CapsuleRadius2D, EvalParams.CrosshairPosition, Projection, Time, ScreenCenterToCapsuleDistance); + UCogSampleFunctionLibrary_Gameplay::FindCapsulePointDistance(CapsuleBot2D, CapsuleTop2D, CapsuleRadius2D, Params.CrosshairPosition, Projection, Time, ScreenCenterToCapsuleDistance); if (ScreenCenterToCapsuleDistance < CandidateClosestScreenDistance) { @@ -680,16 +671,16 @@ bool UCogSampleTargetAcquisition::ComputeCandidateScreenLocation( #if USE_COG const FColor CapsuleColor = (ScreenCenterToCapsuleDistance > 0.0f) ? FColor(255, 255, 255, 100) : FColor(0, 255, 0, 200); - FCogDebugDraw::Segment2D(LogCogTargetAcquisition, CandidateActor, CapsuleBot2D + FVector2D(CapsuleRadius2D, 0), CapsuleTop2D + FVector2D(CapsuleRadius2D, 0), CapsuleColor, EvalParams.IsDebugPersistent); - FCogDebugDraw::Segment2D(LogCogTargetAcquisition, CandidateActor, CapsuleBot2D - FVector2D(CapsuleRadius2D, 0), CapsuleTop2D - FVector2D(CapsuleRadius2D, 0), CapsuleColor, EvalParams.IsDebugPersistent); - FCogDebugDraw::Circle2D(LogCogTargetAcquisition, CandidateActor, CapsuleTop2D, CapsuleRadius2D, CapsuleColor, EvalParams.IsDebugPersistent); - FCogDebugDraw::Circle2D(LogCogTargetAcquisition, CandidateActor, CapsuleBot2D, CapsuleRadius2D, CapsuleColor, EvalParams.IsDebugPersistent); + FCogDebugDraw::Segment2D(LogCogTargetAcquisition, CandidateActor, CapsuleBot2D + FVector2D(CapsuleRadius2D, 0), CapsuleTop2D + FVector2D(CapsuleRadius2D, 0), CapsuleColor, Params.IsDebugPersistent); + FCogDebugDraw::Segment2D(LogCogTargetAcquisition, CandidateActor, CapsuleBot2D - FVector2D(CapsuleRadius2D, 0), CapsuleTop2D - FVector2D(CapsuleRadius2D, 0), CapsuleColor, Params.IsDebugPersistent); + FCogDebugDraw::Circle2D(LogCogTargetAcquisition, CandidateActor, CapsuleTop2D, CapsuleRadius2D, CapsuleColor, Params.IsDebugPersistent); + FCogDebugDraw::Circle2D(LogCogTargetAcquisition, CandidateActor, CapsuleBot2D, CapsuleRadius2D, CapsuleColor, Params.IsDebugPersistent); #endif //USE_COG } } else { - if (FSceneView::ProjectWorldToScreen(CandidateTargetLocation, EvalParams.ViewRect, EvalParams.ViewProjectionMatrix, CandidateScreenLocation)) + if (FSceneView::ProjectWorldToScreen(CandidateTargetLocation, Params.ViewRect, Params.ViewProjectionMatrix, CandidateScreenLocation)) { CandidateClosestScreenDistance = CandidateScreenLocation.Length(); CandidateClosestScreenLocation = CandidateScreenLocation; @@ -700,7 +691,7 @@ bool UCogSampleTargetAcquisition::ComputeCandidateScreenLocation( #if USE_COG if (bFoundValidCandidate) { - FCogDebugDraw::Circle2D(LogCogTargetAcquisition, CandidateActor, CandidateClosestScreenLocation, 2.0f, FColor(0, 255, 0, 255), EvalParams.IsDebugPersistent); + FCogDebugDraw::Circle2D(LogCogTargetAcquisition, CandidateActor, CandidateClosestScreenLocation, 2.0f, FColor(0, 255, 0, 255), Params.IsDebugPersistent); } #endif //USE_COG @@ -729,13 +720,13 @@ bool UCogSampleTargetAcquisition::CheckCandidateWithinScreenDistance( { if (FMath::Abs(CandidateViewportLocation.X) > ScreenMaxX) { - COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, FString::Printf(TEXT("MaxX: %0.2f"), CandidateViewportLocation.X), CandidateLocation, FColor::Red, bIsDebugPersistent)); + IF_COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, FString::Printf(TEXT("MaxX: %0.2f"), CandidateViewportLocation.X), CandidateLocation, FColor::Red, bIsDebugPersistent)); return false; } if (FMath::Abs(CandidateViewportLocation.Y) > ScreenMaxY) { - COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, FString::Printf(TEXT("MaxY: %0.2f"), CandidateViewportLocation.Y), CandidateLocation, FColor::Red, bIsDebugPersistent)); + IF_COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, FString::Printf(TEXT("MaxY: %0.2f"), CandidateViewportLocation.Y), CandidateLocation, FColor::Red, bIsDebugPersistent)); return false; } } @@ -746,7 +737,7 @@ bool UCogSampleTargetAcquisition::CheckCandidateWithinScreenDistance( { if (CandidateViewportDistance > ScreenMaxX) { - COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, FString::Printf(TEXT("Max: %0.2f"), CandidateViewportDistance), CandidateLocation, FColor::Red, bIsDebugPersistent)); + IF_COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, FString::Printf(TEXT("Max: %0.2f"), CandidateViewportDistance), CandidateLocation, FColor::Red, bIsDebugPersistent)); return false; } } @@ -767,25 +758,30 @@ bool UCogSampleTargetAcquisition::CheckIfTargetValid( return false; } + if (UCogSampleFunctionLibrary_Gameplay::IsActorMatchingTags(Target, RequiredTags, IgnoredTags) == false) + { + return false; + } + return true; } //-------------------------------------------------------------------------------------------------------------------------- bool UCogSampleTargetAcquisition::HasLineOfSightToTarget( const AActor* Source, + const FVector& SourceLocation, const AActor* Target, + const FVector& TargetLocation, const FCollisionObjectQueryParams& BlockersParams) const { TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::HasLineOfSightToTarget); - const FVector Origin = Source->GetActorLocation(); - static const FName BlockerTraceTag(TEXT("FindLockTarget_Blocker")); FCollisionQueryParams TargetQueryParams(BlockerTraceTag, SCENE_QUERY_STAT_ONLY(CogSampleTargetAcquisition), false); + TargetQueryParams.AddIgnoredActor(Source); TargetQueryParams.AddIgnoredActor(Target); - return true; - //return FCogHitDetectionHelper::HasLineOfSight(Source->GetWorld(), Origin, Target.GetTargetLocation(), BlockersParams, TargetQueryParams, LogCogTargetAcquisition); + return UCogSampleFunctionLibrary_Gameplay::HasLineOfSight(Source->GetWorld(), SourceLocation, TargetLocation, BlockersParams, TargetQueryParams, LogCogTargetAcquisition); } //-------------------------------------------------------------------------------------------------------------------------- @@ -797,8 +793,11 @@ bool UCogSampleTargetAcquisition::HasLineOfSightToTargetBrokenForTooLong( { TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::HasLineOfSightToTargetBrokenForTooLong); + const FVector& SourceLocation = UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(Source); + const FVector& TargetLocation = UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(Target); + const FCollisionObjectQueryParams BlockersParams = UCogSampleFunctionLibrary_Gameplay::ConfigureCollisionObjectParams(BlockerTypes); - bool HasLineOfSight = HasLineOfSightToTarget(Source, Target, BlockersParams); + const bool HasLineOfSight = HasLineOfSightToTarget(Source, SourceLocation, Target, TargetLocation, BlockersParams); if (HasLineOfSight) { Timer = 0.0f; @@ -824,18 +823,18 @@ FVector UCogSampleTargetAcquisition::GetReferentialLocation(const ACogSampleChar switch (Referential) { - case ECogSampleTargetAcquisitionLocationReferential::Character: - { - Location = UCogSampleFunctionLibrary_Gameplay::GetActorBottomLocation(Character); - break; - } + case ECogSampleTargetAcquisitionLocationReferential::Character: + { + Location = UCogSampleFunctionLibrary_Gameplay::GetActorBottomLocation(Character); + break; + } - case ECogSampleTargetAcquisitionLocationReferential::Camera: - { - Location = Character->GetFollowCamera()->GetComponentLocation(); - break; - } + case ECogSampleTargetAcquisitionLocationReferential::Camera: + { + Location = Character->GetFollowCamera()->GetComponentLocation(); + break; + } } return Location; @@ -848,38 +847,38 @@ FRotator UCogSampleTargetAcquisition::GetReferentialRotation(const ACogSampleCha switch (Referential) { - case ECogSampleTargetAcquisitionRotationReferential::Character: - { - Rotation = Character->GetActorRotation(); - break; - } + case ECogSampleTargetAcquisitionRotationReferential::Character: + { + Rotation = Character->GetActorRotation(); + break; + } - case ECogSampleTargetAcquisitionRotationReferential::MoveInput: - { - //const FVector WorldInput = Character->TransformInputInWorldSpace(Character->GetDesiredMoveInput()); - //if (WorldInput.IsNearlyZero()) - //{ - // Rotation = Character->GetActorRotation(); - //} - //else - //{ - // Rotation = WorldInput.GetSafeNormal().Rotation(); - //} - //break; - } + case ECogSampleTargetAcquisitionRotationReferential::MoveInput: + { + const FVector WorldInput = Character->GetMoveInputInWorldSpace(); + if (WorldInput.IsNearlyZero()) + { + Rotation = Character->GetActorRotation(); + } + else + { + Rotation = WorldInput.GetSafeNormal().Rotation(); + } + break; + } - case ECogSampleTargetAcquisitionRotationReferential::Camera: - { - Rotation = Character->GetFollowCamera()->GetComponentRotation(); - break; - } + case ECogSampleTargetAcquisitionRotationReferential::Camera: + { + Rotation = Character->GetFollowCamera()->GetComponentRotation(); + break; + } - case ECogSampleTargetAcquisitionRotationReferential::CameraFlatten: - { - const FVector CameraForwardFlat = Character->GetFollowCamera()->GetComponentQuat().GetForwardVector().GetSafeNormal2D(); - Rotation = CameraForwardFlat.Rotation(); - break; - } + case ECogSampleTargetAcquisitionRotationReferential::CameraFlatten: + { + const FVector CameraForwardFlat = Character->GetFollowCamera()->GetComponentQuat().GetForwardVector().GetSafeNormal2D(); + Rotation = CameraForwardFlat.Rotation(); + break; + } } return Rotation; diff --git a/Source/CogSample/CogSampleTargetAcquisition.h b/Source/CogSample/CogSampleTargetAcquisition.h index 20af702..e7e9c9e 100644 --- a/Source/CogSample/CogSampleTargetAcquisition.h +++ b/Source/CogSample/CogSampleTargetAcquisition.h @@ -4,14 +4,14 @@ #include "CogSampleFunctionLibrary_Team.h" #include "Engine/DataAsset.h" #include "Engine/EngineTypes.h" +#include "GameplayTagContainer.h" #include "WorldCollision.h" #include "CogSampleTargetAcquisition.generated.h" class ACogSampleCharacter; class APlayerController; class UCurveFloat; -struct FCogSampleTargetCandidateEvaluationResult; -struct FCogSampleTargetCandidateEvaluationParameters; +struct FCogSampleTargetTargetAcquisitionParams; //-------------------------------------------------------------------------------------------------------------------------- UENUM(BlueprintType) @@ -89,7 +89,10 @@ public: int32 Allegiance = 0; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "General") - bool AcceptDead = false; + FGameplayTagContainer RequiredTags; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "General") + FGameplayTagContainer IgnoredTags; //-------------------------------------------------------------------------------------------------------------- // Detection @@ -118,7 +121,7 @@ public: bool bUseScreenLimit = true; UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Limit|Screen", meta = (EditCondition = "bUseScreenLimit", EditConditionHides)) - bool bPrioritizeInsideHitZones = true; + bool bPrioritizeTargetWithCrosshairInsideThem = true; UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Limit|Screen", meta = (EditCondition = "bUseScreenLimit", EditConditionHides)) bool ScreenTestUseAspectRatio = true; @@ -237,10 +240,6 @@ public: const AActor* Source, const AActor* Target) const; - //-------------------------------------------------------------------------------------------------------------- - // Utility - //-------------------------------------------------------------------------------------------------------------- - void FindBestTargetInCandidates( const APlayerController* Controller, const TArray& TargetsToIgnore, @@ -261,13 +260,16 @@ public: bool HasLineOfSightToTarget( const AActor* Source, + const FVector& SourceLocation, const AActor* Target, + const FVector& TargetLocation, const FCollisionObjectQueryParams& BlockersParams) const; bool EvaluateCandidate( AActor* CandidateTarget, - const FCogSampleTargetCandidateEvaluationParameters& EvaluationParameters, - FCogSampleTargetCandidateEvaluationResult& EvaluationResult) const; + const FCogSampleTargetTargetAcquisitionParams& EvaluationParameters, + float& CandidateScore, + bool& bIsCrosshairInsideCandidate) const; bool CheckCandidateWithinScreenDistance( const APlayerController* Controller, @@ -279,7 +281,7 @@ public: bool ComputeCandidateScreenLocation( const AActor* CandidateTarget, - const FCogSampleTargetCandidateEvaluationParameters& EvalParams, + const FCogSampleTargetTargetAcquisitionParams& EvalParams, const FVector& CandidateTargetLocation, FVector2D& CandidateScreenLocation, FVector2D& CandidateClosestScreenLocation, diff --git a/Source/CogSample/CogSampleTask_WaitAttributeChanged.cpp b/Source/CogSample/CogSampleTask_WaitAttributeChanged.cpp new file mode 100644 index 0000000..1ea3f1c --- /dev/null +++ b/Source/CogSample/CogSampleTask_WaitAttributeChanged.cpp @@ -0,0 +1,40 @@ +#include "CogSampleTask_WaitAttributeChanged.h" + +//-------------------------------------------------------------------------------------------------------------------------- +UCogSampleTask_WaitAttributeChanged* UCogSampleTask_WaitAttributeChanged::ListenForAttributeChange(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAttribute Attribute) +{ + if (!IsValid(AbilitySystemComponent) || !Attribute.IsValid()) + { + return nullptr; + } + + UCogSampleTask_WaitAttributeChanged* WaitForAttributeChangedTask = NewObject(); + WaitForAttributeChangedTask->AbilitySystemComponent = AbilitySystemComponent; + WaitForAttributeChangedTask->AttributeToListenFor = Attribute; + + return WaitForAttributeChangedTask; +} + +//-------------------------------------------------------------------------------------------------------------------------- +void UCogSampleTask_WaitAttributeChanged::Activate() +{ + AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(AttributeToListenFor).AddUObject(this, &UCogSampleTask_WaitAttributeChanged::AttributeChanged); +} + +//-------------------------------------------------------------------------------------------------------------------------- +void UCogSampleTask_WaitAttributeChanged::EndTask() +{ + if (IsValid(AbilitySystemComponent)) + { + AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(AttributeToListenFor).RemoveAll(this); + } + + SetReadyToDestroy(); + MarkAsGarbage(); +} + +//-------------------------------------------------------------------------------------------------------------------------- +void UCogSampleTask_WaitAttributeChanged::AttributeChanged(const FOnAttributeChangeData& Data) +{ + OnAttributeChanged.Broadcast(Data.Attribute, Data.NewValue, Data.OldValue); +} \ No newline at end of file diff --git a/Source/CogSample/CogSampleTask_WaitAttributeChanged.h b/Source/CogSample/CogSampleTask_WaitAttributeChanged.h new file mode 100644 index 0000000..2f1d0df --- /dev/null +++ b/Source/CogSample/CogSampleTask_WaitAttributeChanged.h @@ -0,0 +1,40 @@ +#pragma once + +#include "CoreMinimal.h" +#include "AbilitySystemComponent.h" +#include "Kismet/BlueprintAsyncActionBase.h" + +#include "CogSampleTask_WaitAttributeChanged.generated.h" + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnAttributeChangedDelegate, FGameplayAttribute, Attribute, float, NewValue, float, OldValue) +; +/** + * Blueprint node to automatically register a listener for all attribute changes in an AbilitySystemComponent. + */ +UCLASS(BlueprintType, meta = (ExposedAsyncProxy = AsyncTask)) +class UCogSampleTask_WaitAttributeChanged : public UBlueprintAsyncActionBase +{ + GENERATED_BODY() +public: + + UPROPERTY(BlueprintAssignable) + FOnAttributeChangedDelegate OnAttributeChanged; + + UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true")) + static UCogSampleTask_WaitAttributeChanged* ListenForAttributeChange(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAttribute Attribute); + + virtual void Activate() override; + + UFUNCTION(BlueprintCallable) + void EndTask(); + +protected: + + UPROPERTY() + UAbilitySystemComponent* AbilitySystemComponent = nullptr; + + FGameplayAttribute AttributeToListenFor; + + void AttributeChanged(const FOnAttributeChangeData& Data); + +}; \ No newline at end of file