forge friendlier health and damage management
Removed knockback though
This commit is contained in:
31
forge/abilities/ForgeSimpleHitBehavior.cs
Normal file
31
forge/abilities/ForgeSimpleHitBehavior.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using Gamesmiths.Forge.Abilities;
|
||||
using Gamesmiths.Forge.Effects;
|
||||
using Gamesmiths.Forge.Godot.Resources;
|
||||
using Gamesmiths.Forge.Godot.Resources.Abilities;
|
||||
using Godot;
|
||||
|
||||
namespace Movementtests.forge.abilities;
|
||||
|
||||
public class SimpleHitBehavior(ForgeEffectData? damage) : IAbilityBehavior
|
||||
{
|
||||
public void OnStarted(AbilityBehaviorContext context)
|
||||
{
|
||||
if (context.Target == null || damage == null) return;
|
||||
|
||||
var effect = new Effect(damage.GetEffectData(), new EffectOwnership(context.Owner, context.Target));
|
||||
context.Target.EffectsManager.ApplyEffect(effect);
|
||||
|
||||
context.AbilityHandle.CommitAbility();
|
||||
context.InstanceHandle.End();
|
||||
}
|
||||
|
||||
public void OnEnded(AbilityBehaviorContext context) {}
|
||||
}
|
||||
|
||||
[Tool]
|
||||
[GlobalClass]
|
||||
public partial class ForgeSimpleHitBehavior : ForgeAbilityBehavior
|
||||
{
|
||||
[Export] public ForgeEffectData? DamageEffect { get; set; }
|
||||
public override IAbilityBehavior GetBehavior() => new SimpleHitBehavior(DamageEffect);
|
||||
}
|
||||
1
forge/abilities/ForgeSimpleHitBehavior.cs.uid
Normal file
1
forge/abilities/ForgeSimpleHitBehavior.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://n6efm5o4uxvr
|
||||
@@ -11,7 +11,7 @@ public class PlayerAttributeSet : AttributeSet
|
||||
|
||||
public PlayerAttributeSet()
|
||||
{
|
||||
Health = InitializeAttribute(nameof(Health), 100, 0, 150);
|
||||
Health = InitializeAttribute(nameof(Health), 100, 0, 100);
|
||||
Mana = InitializeAttribute(nameof(Mana), 100, 0, 100);
|
||||
Strength = InitializeAttribute(nameof(Strength), 10, 0, 99);
|
||||
Speed = InitializeAttribute(nameof(Speed), 5, 0, 10);
|
||||
|
||||
@@ -16,19 +16,33 @@ using Movementtests.systems;
|
||||
namespace Movementtests.tools.calculators;
|
||||
|
||||
|
||||
public class RaiseEventTagExecution(TagContainer eventTags) : CustomExecution
|
||||
public class RaiseEventTagExecution(TagContainer? ownerEventTags, TagContainer? targetEventTags) : CustomExecution
|
||||
{
|
||||
public override ModifierEvaluatedData[] EvaluateExecution(Effect effect, IForgeEntity target, EffectEvaluatedData? effectEvaluatedData)
|
||||
{
|
||||
var owner = effect.Ownership.Owner;
|
||||
if (owner == null) return [];
|
||||
|
||||
var magnitude = effectEvaluatedData is { ModifiersEvaluatedData.Length: > 0 }
|
||||
? effectEvaluatedData.ModifiersEvaluatedData[0].Magnitude
|
||||
: 0f;
|
||||
if (owner != null && ownerEventTags != null)
|
||||
{
|
||||
owner.Events.Raise(new EventData
|
||||
{
|
||||
EventTags = eventTags,
|
||||
EventTags = ownerEventTags,
|
||||
Source = owner,
|
||||
EventMagnitude = 12f
|
||||
EventMagnitude = magnitude
|
||||
});
|
||||
}
|
||||
|
||||
if (targetEventTags != null)
|
||||
{
|
||||
target.Events.Raise(new EventData
|
||||
{
|
||||
EventTags = targetEventTags,
|
||||
Source = owner,
|
||||
EventMagnitude = magnitude
|
||||
});
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
@@ -39,10 +53,11 @@ public class RaiseEventTagExecution(TagContainer eventTags) : CustomExecution
|
||||
[GlobalClass]
|
||||
public partial class ForgeRaiseEventTagExecution : ForgeCustomExecution
|
||||
{
|
||||
[Export] ForgeTagContainer EventTags { get; set; }
|
||||
[Export] ForgeTagContainer? EventTags { get; set; }
|
||||
[Export] ForgeTagContainer? TargetEventTags { get; set; }
|
||||
|
||||
public override CustomExecution GetExecutionClass()
|
||||
{
|
||||
return new RaiseEventTagExecution(EventTags.GetTagContainer());
|
||||
return new RaiseEventTagExecution(EventTags?.GetTagContainer(), TargetEventTags?.GetTagContainer());
|
||||
}
|
||||
}
|
||||
@@ -4,4 +4,4 @@
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_l686n")
|
||||
RegisteredTags = Array[String](["character.player", "character.enemy", "weapon", "status.stunned", "status.burning", "status.frozen", "abilities.weapon.land", "abilities.weapon.flying", "abilities.weapon.left", "events.combat.damage", "events.combat.hit", "events.weapon.flyingTick", "events.weapon.startedFlying", "events.weapon.stoppedFlying", "events.weapon.handToFlying", "events.weapon.flyingToHand", "events.weapon.plantedToHand", "events.weapon.plantedToFlying", "events.weapon.planted", "cooldown.empoweredAction", "cooldown.empoweredSwordThrow", "cues.resources.mana", "events.player.empowered_action_used", "cues.resources.mana.inhibited"])
|
||||
RegisteredTags = Array[String](["character.player", "character.enemy", "weapon", "status.stunned", "status.burning", "status.frozen", "abilities.weapon.land", "abilities.weapon.flying", "abilities.weapon.left", "events.combat.damage", "events.combat.hit", "events.weapon.flyingTick", "events.weapon.startedFlying", "events.weapon.stoppedFlying", "events.weapon.handToFlying", "events.weapon.flyingToHand", "events.weapon.plantedToHand", "events.weapon.plantedToFlying", "events.weapon.planted", "cooldown.empoweredAction", "cooldown.empoweredSwordThrow", "cues.resources.mana", "events.player.empowered_action_used", "cues.resources.mana.inhibited", "cues.resources.health", "cooldown.enemy.hit", "status.invincible", "events.combat.death"])
|
||||
|
||||
100
forge/resources/ability_datas/on_hit_invinciblity.tres
Normal file
100
forge/resources/ability_datas/on_hit_invinciblity.tres
Normal file
@@ -0,0 +1,100 @@
|
||||
[gd_resource type="Resource" script_class="ForgeAbilityData" format=3 uid="uid://b0ikxp5j8fn3n"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_xjqwu"]
|
||||
[ext_resource type="Script" uid="uid://dngf30hxy5go4" path="res://addons/forge/resources/components/ModifierTags.cs" id="2_a16tf"]
|
||||
[ext_resource type="Script" uid="uid://cn3b4ya15fg7e" path="res://addons/forge/resources/magnitudes/ForgeScalableFloat.cs" id="3_1wliv"]
|
||||
[ext_resource type="Script" uid="uid://2gm1hdhi8u08" path="res://addons/forge/resources/magnitudes/ForgeModifierMagnitude.cs" id="4_7dtdc"]
|
||||
[ext_resource type="Script" uid="uid://1hgogislo1l6" path="res://addons/forge/resources/magnitudes/ForgeScalableInt.cs" id="5_ewbg3"]
|
||||
[ext_resource type="Script" uid="uid://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="6_0akms"]
|
||||
[ext_resource type="Script" uid="uid://cl5hudinl1rex" path="res://forge/abilities/ForgeEffectApplicationBehavior.cs" id="7_mhqpo"]
|
||||
[ext_resource type="Script" uid="uid://dpakv7agvir6y" path="res://addons/forge/resources/ForgeTag.cs" id="8_4vjp3"]
|
||||
[ext_resource type="Script" uid="uid://dhxfbxh54pyxp" path="res://addons/forge/resources/abilities/ForgeAbilityData.cs" id="9_go27d"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_87uc3"]
|
||||
script = ExtResource("1_xjqwu")
|
||||
ContainerTags = Array[String](["status.invincible"])
|
||||
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_5ht6k"]
|
||||
script = ExtResource("2_a16tf")
|
||||
TagsToAdd = SubResource("Resource_87uc3")
|
||||
metadata/_custom_type_script = "uid://dngf30hxy5go4"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_bn2qi"]
|
||||
script = ExtResource("3_1wliv")
|
||||
BaseValue = 1.0
|
||||
|
||||
[sub_resource type="Resource" id="Resource_pl2a2"]
|
||||
script = ExtResource("3_1wliv")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_g02pf"]
|
||||
script = ExtResource("3_1wliv")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_7ak88"]
|
||||
script = ExtResource("3_1wliv")
|
||||
BaseValue = 1.0
|
||||
|
||||
[sub_resource type="Resource" id="Resource_f12ll"]
|
||||
script = ExtResource("3_1wliv")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_xodo6"]
|
||||
script = ExtResource("3_1wliv")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_mcqfd"]
|
||||
script = ExtResource("3_1wliv")
|
||||
BaseValue = 2.0
|
||||
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_w3q2i"]
|
||||
script = ExtResource("4_7dtdc")
|
||||
ScalableFloat = SubResource("Resource_mcqfd")
|
||||
Coefficient = SubResource("Resource_7ak88")
|
||||
PreMultiplyAdditiveValue = SubResource("Resource_xodo6")
|
||||
PostMultiplyAdditiveValue = SubResource("Resource_f12ll")
|
||||
CalculatorCoefficient = SubResource("Resource_bn2qi")
|
||||
CalculatorPreMultiplyAdditiveValue = SubResource("Resource_g02pf")
|
||||
CalculatorPostMultiplyAdditiveValue = SubResource("Resource_pl2a2")
|
||||
metadata/_custom_type_script = "uid://2gm1hdhi8u08"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_vgvi5"]
|
||||
script = ExtResource("5_ewbg3")
|
||||
BaseValue = 1
|
||||
|
||||
[sub_resource type="Resource" id="Resource_0ujop"]
|
||||
script = ExtResource("5_ewbg3")
|
||||
BaseValue = 1
|
||||
|
||||
[sub_resource type="Resource" id="Resource_s8mqp"]
|
||||
script = ExtResource("6_0akms")
|
||||
Name = "Add Invincible tag effect"
|
||||
Modifiers = Array[Object]([])
|
||||
Components = Array[Object]([SubResource("Resource_5ht6k")])
|
||||
Executions = []
|
||||
DurationType = 2
|
||||
Duration = SubResource("Resource_w3q2i")
|
||||
StackLimit = SubResource("Resource_0ujop")
|
||||
InitialStack = SubResource("Resource_vgvi5")
|
||||
Cues = []
|
||||
metadata/_custom_type_script = "uid://b83hf13nj37k3"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_tcrdt"]
|
||||
script = ExtResource("7_mhqpo")
|
||||
EffectData = SubResource("Resource_s8mqp")
|
||||
Name = "OnHitInvincibility"
|
||||
Description = "Adds the invincible tag for a given period"
|
||||
metadata/_custom_type_script = "uid://cl5hudinl1rex"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_xs7wf"]
|
||||
script = ExtResource("8_4vjp3")
|
||||
Tag = "events.combat.damage"
|
||||
metadata/_custom_type_script = "uid://dpakv7agvir6y"
|
||||
|
||||
[resource]
|
||||
script = ExtResource("9_go27d")
|
||||
Name = "OnHitInvincibility"
|
||||
InstancingPolicy = 1
|
||||
CooldownEffects = []
|
||||
AbilityBehavior = SubResource("Resource_tcrdt")
|
||||
TriggerSource = 1
|
||||
TriggerTag = SubResource("Resource_xs7wf")
|
||||
metadata/_custom_type_script = "uid://dhxfbxh54pyxp"
|
||||
17
forge/resources/cues/player_health_changed_cue.tres
Normal file
17
forge/resources/cues/player_health_changed_cue.tres
Normal file
@@ -0,0 +1,17 @@
|
||||
[gd_resource type="Resource" script_class="ForgeCue" format=3 uid="uid://bsqvfefpb7jix"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_tvgrb"]
|
||||
[ext_resource type="Script" uid="uid://cmrsxccn0ei4j" path="res://addons/forge/resources/ForgeCue.cs" id="2_dyb6j"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_f35o6"]
|
||||
script = ExtResource("1_tvgrb")
|
||||
ContainerTags = Array[String](["cues.resources.health"])
|
||||
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
|
||||
|
||||
[resource]
|
||||
script = ExtResource("2_dyb6j")
|
||||
CueKeys = SubResource("Resource_f35o6")
|
||||
MaxValue = 100
|
||||
MagnitudeType = 2
|
||||
MagnitudeAttribute = "PlayerAttributeSet.Health"
|
||||
metadata/_custom_type_script = "uid://cmrsxccn0ei4j"
|
||||
@@ -1,15 +1,15 @@
|
||||
[gd_resource type="Resource" script_class="ForgeCue" format=3 uid="uid://dn7b8frkoxpxr"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_lbula"]
|
||||
[ext_resource type="Script" uid="uid://cmrsxccn0ei4j" path="res://addons/forge/resources/ForgeCue.cs" id="2_jijlk"]
|
||||
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_0pc1u"]
|
||||
[ext_resource type="Script" uid="uid://cmrsxccn0ei4j" path="res://addons/forge/resources/ForgeCue.cs" id="2_g0vcr"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_4mhqs"]
|
||||
script = ExtResource("1_lbula")
|
||||
script = ExtResource("1_0pc1u")
|
||||
ContainerTags = Array[String](["cues.resources.mana"])
|
||||
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
|
||||
|
||||
[resource]
|
||||
script = ExtResource("2_jijlk")
|
||||
script = ExtResource("2_g0vcr")
|
||||
CueKeys = SubResource("Resource_4mhqs")
|
||||
MaxValue = 100
|
||||
MagnitudeType = 2
|
||||
|
||||
@@ -1,54 +1,54 @@
|
||||
[gd_resource type="Resource" script_class="ForgeEffectData" format=3 uid="uid://dh437cuxgjv6b"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://1hgogislo1l6" path="res://addons/forge/resources/magnitudes/ForgeScalableInt.cs" id="1_mlifq"]
|
||||
[ext_resource type="Resource" uid="uid://dn7b8frkoxpxr" path="res://forge/resources/cues/player_mana_changed_cue.tres" id="1_nsr3v"]
|
||||
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_q8tml"]
|
||||
[ext_resource type="Script" uid="uid://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="2_5tp50"]
|
||||
[ext_resource type="Script" uid="uid://cn3b4ya15fg7e" path="res://addons/forge/resources/magnitudes/ForgeScalableFloat.cs" id="2_pm3n3"]
|
||||
[ext_resource type="Script" uid="uid://b0eq12mjqfage" path="res://addons/forge/resources/components/TargetTagRequirements.cs" id="2_xbgy2"]
|
||||
[ext_resource type="Script" uid="uid://bdfcavbjyhxxa" path="res://addons/forge/resources/ForgeModifier.cs" id="3_nsr3v"]
|
||||
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_b244r"]
|
||||
[ext_resource type="Script" uid="uid://b0eq12mjqfage" path="res://addons/forge/resources/components/TargetTagRequirements.cs" id="2_h46co"]
|
||||
[ext_resource type="Resource" uid="uid://dn7b8frkoxpxr" path="res://forge/resources/cues/player_mana_changed_cue.tres" id="3_kw6jm"]
|
||||
[ext_resource type="Script" uid="uid://1hgogislo1l6" path="res://addons/forge/resources/magnitudes/ForgeScalableInt.cs" id="4_fgmkc"]
|
||||
[ext_resource type="Script" uid="uid://cn3b4ya15fg7e" path="res://addons/forge/resources/magnitudes/ForgeScalableFloat.cs" id="5_m4art"]
|
||||
[ext_resource type="Script" uid="uid://bdfcavbjyhxxa" path="res://addons/forge/resources/ForgeModifier.cs" id="6_73cww"]
|
||||
[ext_resource type="Script" uid="uid://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="7_xa46f"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_5yygy"]
|
||||
script = ExtResource("1_q8tml")
|
||||
script = ExtResource("1_b244r")
|
||||
ContainerTags = Array[String](["character.player.mana.regen.inhibited", "cues.resources.mana.inhibited"])
|
||||
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_ncjx6"]
|
||||
script = ExtResource("2_xbgy2")
|
||||
script = ExtResource("2_h46co")
|
||||
OngoingIgnoredTags = SubResource("Resource_5yygy")
|
||||
metadata/_custom_type_script = "uid://b0eq12mjqfage"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_pm3n3"]
|
||||
script = ExtResource("1_mlifq")
|
||||
script = ExtResource("4_fgmkc")
|
||||
BaseValue = 1
|
||||
|
||||
[sub_resource type="Resource" id="Resource_q8tml"]
|
||||
script = ExtResource("2_pm3n3")
|
||||
script = ExtResource("5_m4art")
|
||||
BaseValue = 1.0
|
||||
|
||||
[sub_resource type="Resource" id="Resource_xbgy2"]
|
||||
script = ExtResource("2_pm3n3")
|
||||
script = ExtResource("5_m4art")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_rhldn"]
|
||||
script = ExtResource("2_pm3n3")
|
||||
script = ExtResource("5_m4art")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_p6h8c"]
|
||||
script = ExtResource("2_pm3n3")
|
||||
script = ExtResource("5_m4art")
|
||||
BaseValue = 1.0
|
||||
|
||||
[sub_resource type="Resource" id="Resource_yqxv4"]
|
||||
script = ExtResource("2_pm3n3")
|
||||
script = ExtResource("5_m4art")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_b6opn"]
|
||||
script = ExtResource("2_pm3n3")
|
||||
script = ExtResource("5_m4art")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_5frso"]
|
||||
script = ExtResource("2_pm3n3")
|
||||
script = ExtResource("5_m4art")
|
||||
BaseValue = 2.0
|
||||
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_okenf"]
|
||||
script = ExtResource("3_nsr3v")
|
||||
script = ExtResource("6_73cww")
|
||||
Attribute = "PlayerAttributeSet.Mana"
|
||||
ScalableFloat = SubResource("Resource_5frso")
|
||||
Coefficient = SubResource("Resource_p6h8c")
|
||||
@@ -60,16 +60,16 @@ CalculatorPostMultiplyAdditiveValue = SubResource("Resource_xbgy2")
|
||||
metadata/_custom_type_script = "uid://bdfcavbjyhxxa"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_w35mq"]
|
||||
script = ExtResource("2_pm3n3")
|
||||
script = ExtResource("5_m4art")
|
||||
BaseValue = 0.1
|
||||
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_nsr3v"]
|
||||
script = ExtResource("1_mlifq")
|
||||
script = ExtResource("4_fgmkc")
|
||||
BaseValue = 1
|
||||
|
||||
[resource]
|
||||
script = ExtResource("2_5tp50")
|
||||
script = ExtResource("7_xa46f")
|
||||
Name = "Mana Regeneration"
|
||||
Modifiers = Array[Object]([SubResource("Resource_okenf")])
|
||||
Components = [SubResource("Resource_ncjx6")]
|
||||
@@ -79,5 +79,5 @@ HasPeriodicApplication = true
|
||||
Period = SubResource("Resource_w35mq")
|
||||
StackLimit = SubResource("Resource_nsr3v")
|
||||
InitialStack = SubResource("Resource_pm3n3")
|
||||
Cues = Array[Object]([ExtResource("1_nsr3v")])
|
||||
Cues = Array[Object]([ExtResource("3_kw6jm")])
|
||||
metadata/_custom_type_script = "uid://b83hf13nj37k3"
|
||||
|
||||
8
forge/resources/tag_containers/status_invincible.tres
Normal file
8
forge/resources/tag_containers/status_invincible.tres
Normal file
@@ -0,0 +1,8 @@
|
||||
[gd_resource type="Resource" script_class="ForgeTagContainer" format=3 uid="uid://cw2ytd34jsxj"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_vmvhu"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_vmvhu")
|
||||
ContainerTags = Array[String](["status.invincible"])
|
||||
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
|
||||
@@ -6,7 +6,7 @@ using Gamesmiths.Forge.Godot.Resources.Abilities;
|
||||
using Godot;
|
||||
using Movementtests.systems;
|
||||
|
||||
[Tool, GlobalClass, Meta(typeof(IAutoConnect))]
|
||||
[Tool, GlobalClass, Meta(typeof(IAutoConnect), typeof(IAutoOn))]
|
||||
public partial class AbilitySelection : Control
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
@@ -11,9 +11,7 @@ extends OverlaidMenu
|
||||
@onready var player_damage_spin_box: SpinBox = %PlayerDamageSpinBox
|
||||
|
||||
func _ready() -> void:
|
||||
player_invicible_toggle.button_pressed = player.IsInvincibleOverride
|
||||
player_health_spin_box.value = player.RHealth.StartingHealth
|
||||
player_damage_spin_box.value = player.RDamage.DamageDealt
|
||||
player_invicible_toggle.button_pressed = player.IsInvincible
|
||||
|
||||
|
||||
func _on_kill_player_button_pressed() -> void:
|
||||
@@ -21,7 +19,7 @@ func _on_kill_player_button_pressed() -> void:
|
||||
close()
|
||||
|
||||
func _on_player_invicible_toggled(toggled_on: bool) -> void:
|
||||
player.IsInvincibleOverride = toggled_on
|
||||
player.IsInvincible = toggled_on
|
||||
|
||||
|
||||
func _on_restart_current_level_pressed() -> void:
|
||||
@@ -38,8 +36,8 @@ func _on_level_selected() -> void:
|
||||
close()
|
||||
|
||||
func _on_player_health_changed(value: float) -> void:
|
||||
player.SetPlayerHealthOverride(value)
|
||||
pass
|
||||
|
||||
|
||||
func _on_player_damage_changed(value: float) -> void:
|
||||
player.SetPlayerDamageOverride(value)
|
||||
pass
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_heart.png")]
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_heart.png"), Meta(typeof(IAutoConnect))]
|
||||
public partial class CHealthbar : Sprite3D
|
||||
{
|
||||
private Healthbar _healthbar;
|
||||
public Healthbar Healthbar => _healthbar;
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_healthbar = GetNode<Healthbar>("%Healthbar");
|
||||
}
|
||||
[Node("%Healthbar")] public required ResourceBar ResourceBar { get; set;}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
using System;
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Gamesmiths.Forge.Abilities;
|
||||
using Gamesmiths.Forge.Core;
|
||||
using Gamesmiths.Forge.Effects;
|
||||
using Gamesmiths.Forge.Events;
|
||||
using Gamesmiths.Forge.Godot.Core;
|
||||
using Gamesmiths.Forge.Godot.Nodes;
|
||||
using Gamesmiths.Forge.Godot.Resources.Abilities;
|
||||
using Gamesmiths.Forge.Statescript;
|
||||
using Gamesmiths.Forge.Tags;
|
||||
using Godot;
|
||||
@@ -14,10 +18,9 @@ using Movementtests.systems;
|
||||
using Movementtests.tools;
|
||||
using Node = Godot.Node;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_beetle.png")]
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_beetle.png"), Meta(typeof(IAutoOn), typeof(IAutoConnect))]
|
||||
public partial class Enemy : CharacterBody3D,
|
||||
IDamageable,
|
||||
IDamageDealer,
|
||||
IHealthable,
|
||||
IKillable,
|
||||
IMoveable,
|
||||
@@ -27,6 +30,8 @@ public partial class Enemy : CharacterBody3D,
|
||||
IStunnable,
|
||||
IForgeEntity
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
// Signals and events
|
||||
public event Action<IDamageable, DamageRecord> DamageTaken = null!;
|
||||
public event Action<IHealthable, HealthChangedRecord> HealthChanged = null!;
|
||||
@@ -34,7 +39,7 @@ public partial class Enemy : CharacterBody3D,
|
||||
|
||||
// Public export components
|
||||
[Export]
|
||||
public Node3D Target { get; set; } = null!;
|
||||
public Node3D? Target { get; set; }
|
||||
|
||||
[Export]
|
||||
public float EnemyHeight { get; set; } = 1f;
|
||||
@@ -48,16 +53,16 @@ public partial class Enemy : CharacterBody3D,
|
||||
|
||||
[ExportGroup("Damage")]
|
||||
[Export]
|
||||
public RDamage RDamage { get; set; } = null!;
|
||||
public RDamage? RDamage { get; set; }
|
||||
public IDamageable CDamageable { get; set; } = null!;
|
||||
|
||||
[Export]
|
||||
public RKnockback RKnockback { get; set; } = null!;
|
||||
public RKnockback? RKnockback { get; set; }
|
||||
public IKnockbackable CKnockback { get; set; } = null!;
|
||||
|
||||
[ExportGroup("Movement")]
|
||||
[Export]
|
||||
public RMovement RMovement { get; set; } = null!;
|
||||
public RMovement? RMovement { get; set; }
|
||||
public IMoveable CMovement { get; set; } = null!;
|
||||
|
||||
// Public stuff
|
||||
@@ -94,12 +99,14 @@ public partial class Enemy : CharacterBody3D,
|
||||
set => _forgeEntity.Events = value;
|
||||
}
|
||||
|
||||
[Export] public ForgeAbilityData? HitAbility;
|
||||
|
||||
public Variables SharedVariables { get; }
|
||||
|
||||
// Private stuff
|
||||
private Area3D _damageBox = null!;
|
||||
internal Node3D _target = null!;
|
||||
private Healthbar _healthbar = null!;
|
||||
private ResourceBar _resourceBar = null!;
|
||||
private ForgeEntity _forgeEntity;
|
||||
|
||||
public override void _Ready()
|
||||
@@ -108,6 +115,8 @@ public partial class Enemy : CharacterBody3D,
|
||||
SetupSignals();
|
||||
}
|
||||
|
||||
private AbilityHandle? _hitAbilityHandle;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
_damageBox = GetNode<Area3D>("DamageBox");
|
||||
@@ -119,14 +128,18 @@ public partial class Enemy : CharacterBody3D,
|
||||
CHealth = (GetNode<Node>("CHealth") as IHealthable)!;
|
||||
CKnockback = (GetNode<Node>("CKnockback") as IKnockbackable)!;
|
||||
|
||||
_healthbar = GetNode<CHealthbar>("CHealthBar").Healthbar;
|
||||
_resourceBar = GetNode<CHealthbar>("CHealthBar").ResourceBar;
|
||||
|
||||
CMovement.RMovement = RMovement;
|
||||
CHealth.RHealth = RHealth;
|
||||
CHealth.CurrentHealth = RHealth.StartingHealth;
|
||||
CKnockback.RKnockback = RKnockback;
|
||||
|
||||
_healthbar.Initialize(CHealth.CurrentHealth);
|
||||
if (HitAbility != null)
|
||||
_hitAbilityHandle = Abilities.GrantAbilityPermanently(HitAbility.GetAbilityData(), 1, LevelComparison.None, this);
|
||||
|
||||
Events.Subscribe(Tag.RequestTag(ForgeManagers.Instance.TagsManager, "events.combat.hit"),
|
||||
data => {});
|
||||
}
|
||||
|
||||
public void SetupSignals()
|
||||
@@ -135,7 +148,7 @@ public partial class Enemy : CharacterBody3D,
|
||||
CDamageable.DamageTaken += (source, record) => ReduceHealth(source, record);
|
||||
CDamageable.DamageTaken += (_, record) => RegisterKnockback(new KnockbackRecord(record));
|
||||
CHealth.HealthDepleted += Kill;
|
||||
HealthChanged += (_, record) => _healthbar.SetHealth(record.CurrentHealth);
|
||||
HealthChanged += (_, record) => _resourceBar.SetValue(record.CurrentHealth);
|
||||
}
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
@@ -160,13 +173,19 @@ public partial class Enemy : CharacterBody3D,
|
||||
|
||||
public void ProcessGameplay(double delta)
|
||||
{
|
||||
if (IsStunned) return;
|
||||
if (IsStunned || _hitAbilityHandle == null) return;
|
||||
|
||||
var bodies = _damageBox.GetOverlappingBodies();
|
||||
foreach (var body in bodies)
|
||||
{
|
||||
if(body is IDamageable spawnable)
|
||||
spawnable.TakeDamage(new DamageRecord(GlobalPosition, RDamage));
|
||||
if (body is not IForgeEntity forgeEntity) continue;
|
||||
var canActivate = _hitAbilityHandle.CanActivate(out var _);
|
||||
if (!canActivate) return;
|
||||
|
||||
_hitAbilityHandle.Activate(out var _, forgeEntity);
|
||||
|
||||
// if(body is IDamageable spawnable)
|
||||
// spawnable.TakeDamage(new DamageRecord(GlobalPosition, RDamage));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,16 +6,192 @@
|
||||
[ext_resource type="Script" uid="uid://b6y3ugfydvch0" path="res://scenes/components/damage/RDamageModifier.cs" id="2_r3cnf"]
|
||||
[ext_resource type="Resource" uid="uid://bohbojc68j7y1" path="res://scenes/enemies/grounded_enemy/grounded_enemy_health.tres" id="2_w4lm8"]
|
||||
[ext_resource type="Resource" uid="uid://bqq6uukbdfysr" path="res://scenes/enemies/grounded_enemy/grounded_enemy_movement.tres" id="4_na24f"]
|
||||
[ext_resource type="Script" uid="uid://dhxfbxh54pyxp" path="res://addons/forge/resources/abilities/ForgeAbilityData.cs" id="6_4jf2q"]
|
||||
[ext_resource type="Resource" uid="uid://cw2ytd34jsxj" path="res://forge/resources/tag_containers/status_invincible.tres" id="6_5lf6m"]
|
||||
[ext_resource type="Script" uid="uid://cn3b4ya15fg7e" path="res://addons/forge/resources/magnitudes/ForgeScalableFloat.cs" id="6_jryek"]
|
||||
[ext_resource type="Script" uid="uid://n6efm5o4uxvr" path="res://forge/abilities/ForgeSimpleHitBehavior.cs" id="6_msmv1"]
|
||||
[ext_resource type="Resource" uid="uid://bsqvfefpb7jix" path="res://forge/resources/cues/player_health_changed_cue.tres" id="6_oo2a1"]
|
||||
[ext_resource type="Script" uid="uid://8uj04dfe8oql" path="res://addons/forge/nodes/ForgeEntity.cs" id="6_x50ya"]
|
||||
[ext_resource type="Script" uid="uid://cxihb42t2mfqi" path="res://addons/forge/nodes/ForgeAttributeSet.cs" id="6_yk4hc"]
|
||||
[ext_resource type="Script" uid="uid://b0u23nkpaimyc" path="res://scenes/components/damage/CDamageable.cs" id="7_1tw73"]
|
||||
[ext_resource type="Script" uid="uid://b0eq12mjqfage" path="res://addons/forge/resources/components/TargetTagRequirements.cs" id="7_5eesh"]
|
||||
[ext_resource type="PackedScene" uid="uid://bwx2um43k0ou4" path="res://scenes/components/health/CHealthbar.tscn" id="7_18xwy"]
|
||||
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="7_f22p3"]
|
||||
[ext_resource type="Script" uid="uid://2gm1hdhi8u08" path="res://addons/forge/resources/magnitudes/ForgeModifierMagnitude.cs" id="7_msmv1"]
|
||||
[ext_resource type="PackedScene" uid="uid://dbr7ioio158ew" path="res://scenes/components/movement/CGroundedMovement.tscn" id="7_qyswd"]
|
||||
[ext_resource type="Script" uid="uid://ccovd5i0wr3kk" path="res://addons/forge/editor/attributes/AttributeValues.cs" id="7_x50ya"]
|
||||
[ext_resource type="Script" uid="uid://bdfcavbjyhxxa" path="res://addons/forge/resources/ForgeModifier.cs" id="8_3gkmr"]
|
||||
[ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://scenes/components/movement/RMovement.cs" id="8_6d4gl"]
|
||||
[ext_resource type="Script" uid="uid://1hgogislo1l6" path="res://addons/forge/resources/magnitudes/ForgeScalableInt.cs" id="8_m0osh"]
|
||||
[ext_resource type="Script" uid="uid://br7ut4lbau66w" path="res://forge/calculators/ForgeRaiseEventTagExecution.cs" id="8_q86ag"]
|
||||
[ext_resource type="Script" uid="uid://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="9_3gkmr"]
|
||||
[ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://scenes/components/knockback/CKnockback.tscn" id="10_jqqi6"]
|
||||
[ext_resource type="Resource" uid="uid://cektf6waf4s04" path="res://scenes/enemies/grounded_enemy/grounded_enemy_knockback.tres" id="11_8k3xb"]
|
||||
[ext_resource type="Script" uid="uid://dngf30hxy5go4" path="res://addons/forge/resources/components/ModifierTags.cs" id="12_3gkmr"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_nt1hl"]
|
||||
script = ExtResource("7_5eesh")
|
||||
ApplicationIgnoredTags = ExtResource("6_5lf6m")
|
||||
metadata/_custom_type_script = "uid://b0eq12mjqfage"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_f35o6"]
|
||||
script = ExtResource("7_f22p3")
|
||||
ContainerTags = Array[String](["events.combat.hit"])
|
||||
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_46obe"]
|
||||
script = ExtResource("7_f22p3")
|
||||
ContainerTags = Array[String](["events.combat.damage"])
|
||||
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_33a4r"]
|
||||
script = ExtResource("8_q86ag")
|
||||
EventTags = SubResource("Resource_f35o6")
|
||||
TargetEventTags = SubResource("Resource_46obe")
|
||||
metadata/_custom_type_script = "uid://br7ut4lbau66w"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_rjo6h"]
|
||||
script = ExtResource("8_m0osh")
|
||||
BaseValue = 1
|
||||
|
||||
[sub_resource type="Resource" id="Resource_8qlid"]
|
||||
script = ExtResource("6_jryek")
|
||||
BaseValue = 1.0
|
||||
|
||||
[sub_resource type="Resource" id="Resource_lbthk"]
|
||||
script = ExtResource("6_jryek")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_hguc3"]
|
||||
script = ExtResource("6_jryek")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_ugrvo"]
|
||||
script = ExtResource("6_jryek")
|
||||
BaseValue = 1.0
|
||||
|
||||
[sub_resource type="Resource" id="Resource_6406e"]
|
||||
script = ExtResource("6_jryek")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_x0rol"]
|
||||
script = ExtResource("6_jryek")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_1s1j3"]
|
||||
script = ExtResource("6_jryek")
|
||||
BaseValue = -10.0
|
||||
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_khx4r"]
|
||||
script = ExtResource("8_3gkmr")
|
||||
Attribute = "PlayerAttributeSet.Health"
|
||||
ScalableFloat = SubResource("Resource_1s1j3")
|
||||
Coefficient = SubResource("Resource_ugrvo")
|
||||
PreMultiplyAdditiveValue = SubResource("Resource_x0rol")
|
||||
PostMultiplyAdditiveValue = SubResource("Resource_6406e")
|
||||
CalculatorCoefficient = SubResource("Resource_8qlid")
|
||||
CalculatorPreMultiplyAdditiveValue = SubResource("Resource_hguc3")
|
||||
CalculatorPostMultiplyAdditiveValue = SubResource("Resource_lbthk")
|
||||
metadata/_custom_type_script = "uid://bdfcavbjyhxxa"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_xmw7i"]
|
||||
script = ExtResource("8_m0osh")
|
||||
BaseValue = 1
|
||||
|
||||
[sub_resource type="Resource" id="Resource_lj45k"]
|
||||
script = ExtResource("9_3gkmr")
|
||||
Name = "SimpleHitEffect"
|
||||
Modifiers = Array[Object]([SubResource("Resource_khx4r")])
|
||||
Components = [SubResource("Resource_nt1hl")]
|
||||
Executions = [SubResource("Resource_33a4r")]
|
||||
StackLimit = SubResource("Resource_xmw7i")
|
||||
InitialStack = SubResource("Resource_rjo6h")
|
||||
Cues = [ExtResource("6_oo2a1")]
|
||||
metadata/_custom_type_script = "uid://b83hf13nj37k3"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_m0osh"]
|
||||
script = ExtResource("6_msmv1")
|
||||
DamageEffect = SubResource("Resource_lj45k")
|
||||
Name = "Simple hit"
|
||||
Description = "This is a simple hit from an enemy"
|
||||
metadata/_custom_type_script = "uid://n6efm5o4uxvr"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_msmv1"]
|
||||
script = ExtResource("7_f22p3")
|
||||
ContainerTags = Array[String](["status.stunned"])
|
||||
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_xdbds"]
|
||||
script = ExtResource("7_f22p3")
|
||||
ContainerTags = Array[String](["cooldown.enemy.hit"])
|
||||
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_gna8g"]
|
||||
script = ExtResource("12_3gkmr")
|
||||
TagsToAdd = SubResource("Resource_xdbds")
|
||||
metadata/_custom_type_script = "uid://dngf30hxy5go4"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_oo2a1"]
|
||||
script = ExtResource("6_jryek")
|
||||
BaseValue = 1.0
|
||||
|
||||
[sub_resource type="Resource" id="Resource_q86ag"]
|
||||
script = ExtResource("6_jryek")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_5eesh"]
|
||||
script = ExtResource("6_jryek")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_5lf6m"]
|
||||
script = ExtResource("6_jryek")
|
||||
BaseValue = 1.0
|
||||
|
||||
[sub_resource type="Resource" id="Resource_bv3hg"]
|
||||
script = ExtResource("6_jryek")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_tb7hu"]
|
||||
script = ExtResource("6_jryek")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_bw6ul"]
|
||||
script = ExtResource("6_jryek")
|
||||
BaseValue = 1.0
|
||||
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_g5uhf"]
|
||||
script = ExtResource("7_msmv1")
|
||||
ScalableFloat = SubResource("Resource_bw6ul")
|
||||
Coefficient = SubResource("Resource_5lf6m")
|
||||
PreMultiplyAdditiveValue = SubResource("Resource_tb7hu")
|
||||
PostMultiplyAdditiveValue = SubResource("Resource_bv3hg")
|
||||
CalculatorCoefficient = SubResource("Resource_oo2a1")
|
||||
CalculatorPreMultiplyAdditiveValue = SubResource("Resource_5eesh")
|
||||
CalculatorPostMultiplyAdditiveValue = SubResource("Resource_q86ag")
|
||||
metadata/_custom_type_script = "uid://2gm1hdhi8u08"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_vl5ta"]
|
||||
script = ExtResource("8_m0osh")
|
||||
BaseValue = 1
|
||||
|
||||
[sub_resource type="Resource" id="Resource_82a7m"]
|
||||
script = ExtResource("8_m0osh")
|
||||
BaseValue = 1
|
||||
|
||||
[sub_resource type="Resource" id="Resource_0gdnn"]
|
||||
script = ExtResource("9_3gkmr")
|
||||
Name = "HitCooldown"
|
||||
Modifiers = []
|
||||
Components = [SubResource("Resource_gna8g")]
|
||||
Executions = []
|
||||
DurationType = 2
|
||||
Duration = SubResource("Resource_g5uhf")
|
||||
StackLimit = SubResource("Resource_82a7m")
|
||||
InitialStack = SubResource("Resource_vl5ta")
|
||||
Cues = []
|
||||
metadata/_custom_type_script = "uid://b83hf13nj37k3"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_ub34u"]
|
||||
script = ExtResource("6_4jf2q")
|
||||
Name = "Hit"
|
||||
CooldownEffects = [SubResource("Resource_0gdnn")]
|
||||
AbilityBehavior = SubResource("Resource_m0osh")
|
||||
ActivationBlockedTags = SubResource("Resource_msmv1")
|
||||
metadata/_custom_type_script = "uid://dhxfbxh54pyxp"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_4jf2q"]
|
||||
script = ExtResource("7_f22p3")
|
||||
@@ -39,7 +215,7 @@ Default = 1
|
||||
Min = 1
|
||||
Max = 100
|
||||
|
||||
[sub_resource type="ViewportTexture" id="ViewportTexture_ub34u"]
|
||||
[sub_resource type="ViewportTexture" id="ViewportTexture_5lf6m"]
|
||||
viewport_path = NodePath("SubViewport")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_qj0ob"]
|
||||
@@ -87,6 +263,7 @@ DeathEffects = Array[Object]([])
|
||||
RDamage = ExtResource("2_bn56u")
|
||||
RKnockback = ExtResource("11_8k3xb")
|
||||
RMovement = ExtResource("4_na24f")
|
||||
HitAbility = SubResource("Resource_ub34u")
|
||||
|
||||
[node name="ForgeEntity" type="Node" parent="." unique_id=432521027]
|
||||
script = ExtResource("6_x50ya")
|
||||
@@ -110,7 +287,7 @@ metadata/_custom_type_script = "uid://bjwrpv3jpsc1e"
|
||||
|
||||
[node name="CHealthBar" parent="." unique_id=1278247727 instance=ExtResource("7_18xwy")]
|
||||
transform = Transform3D(0.4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.2, 0)
|
||||
texture = SubResource("ViewportTexture_ub34u")
|
||||
texture = SubResource("ViewportTexture_5lf6m")
|
||||
|
||||
[node name="CDamageable" type="Node" parent="." unique_id=1601518000]
|
||||
script = ExtResource("7_1tw73")
|
||||
|
||||
@@ -7,14 +7,13 @@
|
||||
[ext_resource type="Script" uid="uid://b44cse62qru7j" path="res://scenes/components/knockback/RKnockback.cs" id="3_cb2lu"]
|
||||
[ext_resource type="Resource" uid="uid://bl5crtu1gkrtr" path="res://inputs/base_mode/base_mode.tres" id="3_cresl"]
|
||||
[ext_resource type="PackedScene" uid="uid://c4ikbhojckpnc" path="res://scenes/components/health/CHealth.tscn" id="3_q7bng"]
|
||||
[ext_resource type="Script" uid="uid://baiapod3csndf" path="res://scenes/components/health/RHealth.cs" id="4_abfq8"]
|
||||
[ext_resource type="Resource" uid="uid://bjyd801wvverk" path="res://scenes/player_controller/resources/player_health.tres" id="4_m8gvy"]
|
||||
[ext_resource type="Resource" uid="uid://cpdaw41ah5gic" path="res://inputs/base_mode/rotate_y.tres" id="4_rxwoh"]
|
||||
[ext_resource type="Resource" uid="uid://dh437cuxgjv6b" path="res://forge/resources/effect_datas/mana_regeneration.tres" id="5_2rkt1"]
|
||||
[ext_resource type="Resource" uid="uid://ccrb5xsnphc8" path="res://inputs/base_mode/rotate_floorplane.tres" id="5_4u7i3"]
|
||||
[ext_resource type="PackedScene" uid="uid://hpsg4fqwrx1u" path="res://scenes/components/damage/CDamageable.tscn" id="5_jb43f"]
|
||||
[ext_resource type="Resource" uid="uid://f3vs6l4m623s" path="res://inputs/base_mode/move_left.tres" id="5_q14ux"]
|
||||
[ext_resource type="Resource" uid="uid://ifeavnlps7hy" path="res://forge/resources/behaviors/exploding_sword.tres" id="5_u8yay"]
|
||||
[ext_resource type="Resource" uid="uid://b0ikxp5j8fn3n" path="res://forge/resources/ability_datas/on_hit_invinciblity.tres" id="5_u8yay"]
|
||||
[ext_resource type="PackedScene" uid="uid://duju3atqgltkg" path="res://scenes/explosion/explosion.tscn" id="5_ue7xq"]
|
||||
[ext_resource type="Resource" uid="uid://dyru7mxo121w6" path="res://scenes/player_controller/resources/player_normal_damage_mod.tres" id="6_cmijs"]
|
||||
[ext_resource type="Resource" uid="uid://t612lts1wi1s" path="res://inputs/base_mode/move_right.tres" id="6_q7bng"]
|
||||
@@ -58,7 +57,7 @@
|
||||
[ext_resource type="Texture2D" uid="uid://chvt6g0xn5c2m" path="res://scenes/player_controller/components/dash/light-ring.jpg" id="32_lgpc8"]
|
||||
[ext_resource type="Script" uid="uid://b4dwolbvt8our" path="res://addons/godot_state_charts/history_state.gd" id="41_ruloh"]
|
||||
[ext_resource type="Texture2D" uid="uid://c40orhfdgsim" path="res://assets/ui/IconGodotNode/white/icon_circle.png" id="45_u8rdp"]
|
||||
[ext_resource type="PackedScene" uid="uid://cyw8p0p6a78tl" path="res://scenes/ui/healthbar/healthbar.tscn" id="47_76kmc"]
|
||||
[ext_resource type="PackedScene" uid="uid://cyw8p0p6a78tl" path="res://scenes/ui/resourcebar/healthbar.tscn" id="47_76kmc"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_mpigw"]
|
||||
script = ExtResource("2_u8yay")
|
||||
@@ -70,6 +69,11 @@ script = ExtResource("11_u8yay")
|
||||
Tag = "events.player.empowered_action_used"
|
||||
metadata/_custom_type_script = "uid://dpakv7agvir6y"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_2rkt1"]
|
||||
script = ExtResource("11_u8yay")
|
||||
Tag = "status.invincible"
|
||||
metadata/_custom_type_script = "uid://dpakv7agvir6y"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_cb2lu"]
|
||||
script = ExtResource("2_x835q")
|
||||
DamageDealt = 10.0
|
||||
@@ -80,11 +84,6 @@ script = ExtResource("3_cb2lu")
|
||||
Modifier = 5.0
|
||||
metadata/_custom_type_script = "uid://b44cse62qru7j"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_ue7xq"]
|
||||
script = ExtResource("4_abfq8")
|
||||
StartingHealth = 10.0
|
||||
metadata/_custom_type_script = "uid://baiapod3csndf"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_u8yay"]
|
||||
script = ExtResource("11_2rkt1")
|
||||
Default = 100
|
||||
@@ -156,8 +155,9 @@ collision_mask = 272
|
||||
script = ExtResource("1_poq2x")
|
||||
BaseTags = SubResource("Resource_mpigw")
|
||||
EmpoweredActionUsed = SubResource("Resource_5gbhg")
|
||||
InvincibleTag = SubResource("Resource_2rkt1")
|
||||
EmpoweredActionAbility = ExtResource("10_2rkt1")
|
||||
WeaponExplosionBehavior = ExtResource("5_u8yay")
|
||||
DefaultGrantedAbilities = [ExtResource("5_u8yay")]
|
||||
DefaultPermanentEffects = [ExtResource("5_2rkt1")]
|
||||
EmpoweredActionEffects = [ExtResource("6_u8yay")]
|
||||
AimAssistStrength = 0.3
|
||||
@@ -165,7 +165,6 @@ AimAssistReductionWhenCloseToTarget = 0.1
|
||||
AimAssistReductionStartDistance = 8.0
|
||||
RDamage = SubResource("Resource_cb2lu")
|
||||
RKnockback = SubResource("Resource_abfq8")
|
||||
RHealth = SubResource("Resource_ue7xq")
|
||||
TargetingDistance = 5.0
|
||||
Explosion = ExtResource("5_ue7xq")
|
||||
WalkSpeed = 7.5
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Gamesmiths.Forge.Attributes;
|
||||
using Gamesmiths.Forge.Core;
|
||||
using Gamesmiths.Forge.Cues;
|
||||
using Gamesmiths.Forge.Godot.Core;
|
||||
@@ -7,12 +10,12 @@ using Gamesmiths.Forge.Tags;
|
||||
using Movementtests.interfaces;
|
||||
using Movementtests.tools;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_text_panel.png")]
|
||||
public partial class PlayerUi : Control, ICueHandler
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_text_panel.png"), Meta(typeof(IAutoOn), typeof(IAutoConnect))]
|
||||
public partial class PlayerUi : Control
|
||||
{
|
||||
private TextureRect _enemyTarget = null!;
|
||||
private Healthbar _healthbar = null!;
|
||||
private Healthbar _manabar = null!;
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
#region Utils
|
||||
|
||||
public enum TargetState
|
||||
{
|
||||
@@ -20,29 +23,33 @@ public partial class PlayerUi : Control, ICueHandler
|
||||
TargetWouldNotKill,
|
||||
TargetWouldKill
|
||||
}
|
||||
|
||||
public record TargetProperties(TargetState State, Vector2 Position);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nodes
|
||||
|
||||
[Node] public required TextureRect EnemyTarget { get; set; }
|
||||
[Node] public required ResourceBar Healthbar { get; set; }
|
||||
[Node] public required ResourceBar Manabar { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Exports
|
||||
|
||||
[Export]
|
||||
public Color WouldKillColor { get; set; } = new Color("009c8f");
|
||||
[Export]
|
||||
public Color WouldNotKillColor { get; set; } = new Color("fc001c");
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_enemyTarget = GetNode<TextureRect>("%EnemyTarget");
|
||||
_healthbar = GetNode<Healthbar>("%Healthbar");
|
||||
_manabar = GetNode<Healthbar>("%Manabar");
|
||||
#endregion
|
||||
|
||||
|
||||
public void Initialize(EntityAttribute health, EntityAttribute mana)
|
||||
{
|
||||
var tagsManager = ForgeManagers.Instance.TagsManager;
|
||||
var cuesManager = ForgeManagers.Instance.CuesManager;
|
||||
cuesManager.RegisterCue(Tag.RequestTag(tagsManager, "cues.resources.mana"), this);
|
||||
}
|
||||
|
||||
public void Initialize(float initialHealth, float initialMana)
|
||||
{
|
||||
_healthbar.Initialize(initialHealth);
|
||||
_manabar.Initialize(initialMana);
|
||||
Healthbar.Initialize(health, Tag.RequestTag(tagsManager, "cues.resources.health"));
|
||||
Manabar.Initialize(mana, Tag.RequestTag(tagsManager, "cues.resources.mana"));
|
||||
}
|
||||
|
||||
public void SetEnemyTargetProperties(TargetProperties targetProperties)
|
||||
@@ -57,38 +64,8 @@ public partial class PlayerUi : Control, ICueHandler
|
||||
TargetState.TargetWouldKill => WouldKillColor,
|
||||
_ => WouldNotKillColor
|
||||
};
|
||||
_enemyTarget.SetVisible(visible);
|
||||
_enemyTarget.SetPosition(position - _enemyTarget.Size / 2);
|
||||
_enemyTarget.SetModulate(modulation);
|
||||
}
|
||||
|
||||
public void OnHealthChanged(IHealthable healthable, HealthChangedRecord healthChanged)
|
||||
{
|
||||
_healthbar.CurrentHealth = healthChanged.CurrentHealth;
|
||||
}
|
||||
|
||||
public void OnManaChanged(float newValue)
|
||||
{
|
||||
_manabar.CurrentHealth = newValue;
|
||||
}
|
||||
|
||||
public void OnExecute(IForgeEntity? target, CueParameters? parameters)
|
||||
{
|
||||
if (target == null || !parameters.HasValue || !IsInstanceValid(_manabar)) return;
|
||||
|
||||
float magnitude = parameters.Value.Magnitude;
|
||||
_manabar.CurrentHealth += magnitude;
|
||||
}
|
||||
|
||||
public void OnApply(IForgeEntity? target, CueParameters? parameters)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnRemove(IForgeEntity? target, bool interrupted)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnUpdate(IForgeEntity? target, CueParameters? parameters)
|
||||
{
|
||||
EnemyTarget.SetVisible(visible);
|
||||
EnemyTarget.SetPosition(position - EnemyTarget.Size / 2);
|
||||
EnemyTarget.SetModulate(modulation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,10 @@ using Chickensoft.Introspection;
|
||||
using Gamesmiths.Forge.Abilities;
|
||||
using Gamesmiths.Forge.Attributes;
|
||||
using Gamesmiths.Forge.Core;
|
||||
using Gamesmiths.Forge.Cues;
|
||||
using Gamesmiths.Forge.Effects;
|
||||
using Gamesmiths.Forge.Effects.Calculator;
|
||||
using Gamesmiths.Forge.Effects.Components;
|
||||
using Gamesmiths.Forge.Effects.Duration;
|
||||
using Gamesmiths.Forge.Effects.Magnitudes;
|
||||
using Gamesmiths.Forge.Effects.Modifiers;
|
||||
using Gamesmiths.Forge.Effects.Periodic;
|
||||
using Gamesmiths.Forge.Events;
|
||||
using Gamesmiths.Forge.Godot.Core;
|
||||
using Gamesmiths.Forge.Godot.Nodes;
|
||||
@@ -27,11 +24,7 @@ using Movementtests.addons.godot_state_charts.csharp;
|
||||
using Movementtests.interfaces;
|
||||
using Movementtests.systems;
|
||||
using Movementtests.player_controller.Scripts;
|
||||
using Movementtests.scenes.player_controller.scripts;
|
||||
using Movementtests.tools;
|
||||
using Movementtests.forge.abilities;
|
||||
using Movementtests.managers;
|
||||
using Movementtests.tools.calculators;
|
||||
using RustyOptions;
|
||||
using Node = Godot.Node;
|
||||
|
||||
@@ -39,12 +32,7 @@ public record struct EmpoweredActionPayload;
|
||||
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_character.png"), Meta(typeof(IAutoNode))]
|
||||
public partial class PlayerController : CharacterBody3D,
|
||||
IDamageable,
|
||||
IDamageDealer,
|
||||
IHealthable,
|
||||
IKnockbackable,
|
||||
IForgeEntity
|
||||
public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandler
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
@@ -53,7 +41,7 @@ public partial class PlayerController : CharacterBody3D,
|
||||
public InventoryManager InventoryManager => this.DependOn<InventoryManager>();
|
||||
#endregion
|
||||
|
||||
#region Enums
|
||||
#region Utils
|
||||
|
||||
public enum BufferedActions
|
||||
{
|
||||
@@ -66,6 +54,14 @@ public partial class PlayerController : CharacterBody3D,
|
||||
|
||||
#endregion
|
||||
|
||||
#region Forge
|
||||
|
||||
private AbilityHandle? _empoweredActionHandle;
|
||||
public required EntityAttribute HealthAttribute { get; set; }
|
||||
public required EntityAttribute ManaAttribute { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Signals
|
||||
|
||||
[Signal]
|
||||
@@ -79,27 +75,25 @@ public partial class PlayerController : CharacterBody3D,
|
||||
|
||||
#region Publics
|
||||
|
||||
public HeadSystem HeadSystem = null!;
|
||||
public StairsSystem StairsSystem = null!;
|
||||
public MantleSystem MantleSystem = null!;
|
||||
public DashSystem DashSystem = null!;
|
||||
public CollisionShape3D StandingCollider = null!;
|
||||
public CollisionShape3D SlideCollider = null!;
|
||||
public WeaponSystem WeaponSystem = null!;
|
||||
public WallHugSystem WallHugSystem = null!;
|
||||
public PlayerUi PlayerUi = null!;
|
||||
public Node3D DashIndicatorNode = null!;
|
||||
public MeshInstance3D DashIndicatorMesh = null!;
|
||||
public CylinderMesh DashIndicatorMeshCylinder = null!;
|
||||
public RayCast3D WallRunSnapper = null!;
|
||||
public ShapeCast3D GroundDetector = null!;
|
||||
public ShapeCast3D CeilingDetector = null!;
|
||||
public RayCast3D DirectGroundDetector = null!;
|
||||
public Area3D WeaponHitbox = null!;
|
||||
public AudioStreamPlayer3D SfxPlayer = null!;
|
||||
|
||||
public ShapeCast3D DashDamageDetector = null!;
|
||||
public Area3D SlidingEnemyDetector = null!;
|
||||
[Node("HeadSystem")] public required HeadSystem HeadSystem { get; set; }
|
||||
[Node("StairsSystem")] public required StairsSystem StairsSystem { get; set; }
|
||||
[Node("HeadSystem/MantleSystem")] public required MantleSystem MantleSystem { get; set; }
|
||||
[Node("DashSystem")] public required DashSystem DashSystem { get; set; }
|
||||
[Node("StandingCollider")] public required CollisionShape3D StandingCollider { get; set; }
|
||||
[Node("SlideCollider")] public required CollisionShape3D SlideCollider { get; set; }
|
||||
[Node("WeaponSystem")] public required WeaponSystem WeaponSystem { get; set; }
|
||||
[Node("WallHugSystem")] public required WallHugSystem WallHugSystem { get; set; }
|
||||
[Node("UI")] public required PlayerUi PlayerUi { get; set; }
|
||||
[Node("GroundDetector")] public required ShapeCast3D GroundDetector { get; set; }
|
||||
[Node("CeilingDetector")] public required ShapeCast3D CeilingDetector { get; set; }
|
||||
[Node("DirectGroundDetector")] public required RayCast3D DirectGroundDetector { get; set; }
|
||||
[Node("%WeaponHitbox")] public required Area3D WeaponHitbox { get; set; }
|
||||
[Node("SFXPlayer")] public required AudioStreamPlayer3D SfxPlayer { get; set; }
|
||||
[Node("DashDamage")] public required ShapeCast3D DashDamageDetector { get; set; }
|
||||
[Node("SlidingEnemyDetector")] public required Area3D SlidingEnemyDetector { get; set; }
|
||||
[Node("%CloseEnemyDetector")] public required ShapeCast3D CloseEnemyDetector { get; set; }
|
||||
[Node("AimAssistRayCast")] public required RayCast3D AimAssistRayCast { get; set; }
|
||||
[Node("HeadSystem/CameraSmooth/Camera3D")] public required Camera3D Camera { get; set; }
|
||||
|
||||
public EntityAttributes Attributes { get; set; } = null!;
|
||||
public EntityTags Tags { get; set; } = null!;
|
||||
@@ -117,17 +111,14 @@ public partial class PlayerController : CharacterBody3D,
|
||||
// Forge stuff
|
||||
[ExportCategory("Forge")]
|
||||
[ExportGroup("General")]
|
||||
[Export]
|
||||
public ForgeTagContainer BaseTags { get; set; }
|
||||
[Export] public ForgeTag EmpoweredActionUsed;
|
||||
[Export] public required ForgeTagContainer BaseTags { get; set; }
|
||||
[Export] public required ForgeTag EmpoweredActionUsed { get; set; }
|
||||
[Export] public required ForgeTag InvincibleTag { get; set; }
|
||||
|
||||
[ExportGroup("Abilities")]
|
||||
[ExportSubgroup("Common and defaults")]
|
||||
[Export] public ForgeAbilityData EmpoweredActionAbility = null!;
|
||||
[Export] public ForgeAbilityData[] DefaultPermanentAbilities = [];
|
||||
|
||||
[ExportSubgroup("WeaponThrow")] [Export]
|
||||
public ForgeAbilityBehavior WeaponExplosionBehavior;
|
||||
[Export] public ForgeAbilityData? EmpoweredActionAbility;
|
||||
[Export] public ForgeAbilityData[] DefaultGrantedAbilities = [];
|
||||
|
||||
[ExportGroup("Effects")]
|
||||
[ExportSubgroup("Common and defaults")]
|
||||
@@ -147,7 +138,6 @@ public partial class PlayerController : CharacterBody3D,
|
||||
|
||||
[ExportGroup("Damage")] [Export] public RDamage RDamage { get; set; } = null!;
|
||||
[Export] public RKnockback? RKnockback { get; set; } = null!;
|
||||
[Export] public RHealth? RHealth { get; set; } = null!;
|
||||
|
||||
[ExportGroup("Targeting")]
|
||||
[Export(PropertyHint.Range, "0,20,0.1,or_greater")]
|
||||
@@ -409,46 +399,64 @@ public partial class PlayerController : CharacterBody3D,
|
||||
private Transition _onGroundSlideJump = null!;
|
||||
private Transition _onAirGlideDoubleJump = null!;
|
||||
|
||||
// Damage
|
||||
public CDamageable? CDamageable { get; set; }
|
||||
public CHealth? CHealth { get; set; }
|
||||
public CKnockback? CKnockback { get; set; }
|
||||
public float CurrentHealth { get; set; }
|
||||
#endregion
|
||||
|
||||
private bool _isInvincible;
|
||||
public bool IsInvincibleOverride { get; set; }
|
||||
#region DamageManagement
|
||||
|
||||
// Invincibility
|
||||
private ActiveEffectHandle? _invincibleEffect;
|
||||
public bool IsInvincible
|
||||
{
|
||||
get => _isInvincible || IsInvincibleOverride;
|
||||
set => _isInvincible = value;
|
||||
get => Tags.CombinedTags.HasTag(InvincibleTag.GetTag());
|
||||
set => SetInvincible(value);
|
||||
}
|
||||
public void SetInvincible(bool invincible)
|
||||
{
|
||||
if (invincible && !IsInvincible)
|
||||
{
|
||||
var invincibility = new EffectData(
|
||||
"Invincibility",
|
||||
new DurationData(DurationType.Infinite),
|
||||
effectComponents:
|
||||
[
|
||||
new ModifierTagsEffectComponent(
|
||||
InvincibleTag.GetTag().GetSingleTagContainer()!
|
||||
)
|
||||
]);
|
||||
GD.Print("Applying invincibility");
|
||||
_invincibleEffect = EffectsManager.ApplyEffect(new Effect(invincibility,
|
||||
new EffectOwnership(this, this)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (_invincibleEffect == null) return;
|
||||
EffectsManager.RemoveEffect(_invincibleEffect);
|
||||
GD.Print("Removing effect");
|
||||
_invincibleEffect = null;
|
||||
}
|
||||
|
||||
// Damage dealing
|
||||
private readonly List<IDamageable> _hitEnemies = new List<IDamageable>();
|
||||
|
||||
private ShapeCast3D _closeEnemyDetector = null!;
|
||||
private RayCast3D _aimAssisRayCast = null!;
|
||||
private Camera3D _camera = null!;
|
||||
|
||||
private AbilityHandle? _empoweredActionHandle;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public void OnReady()
|
||||
{
|
||||
LoadSettings();
|
||||
|
||||
// General use stuff
|
||||
PlayerUi = GetNode<PlayerUi>("UI");
|
||||
_closeEnemyDetector = GetNode<ShapeCast3D>("%CloseEnemyDetector");
|
||||
_closeEnemyDetector.TargetPosition = _closeEnemyDetector.TargetPosition.Normalized() * TargetingDistance;
|
||||
_aimAssisRayCast = GetNode<RayCast3D>("AimAssistRayCast");
|
||||
_aimAssisRayCast.TargetPosition = _aimAssisRayCast.TargetPosition.Normalized() * (TargetingDistance*1.5f);
|
||||
CloseEnemyDetector = GetNode<ShapeCast3D>("%CloseEnemyDetector");
|
||||
CloseEnemyDetector.TargetPosition = CloseEnemyDetector.TargetPosition.Normalized() * TargetingDistance;
|
||||
AimAssistRayCast = GetNode<RayCast3D>("AimAssistRayCast");
|
||||
AimAssistRayCast.TargetPosition = AimAssistRayCast.TargetPosition.Normalized() * (TargetingDistance*1.5f);
|
||||
|
||||
#region Forge
|
||||
|
||||
var tagsManager = ForgeManagers.Instance.TagsManager;
|
||||
var cuesManager = ForgeManagers.Instance.CuesManager;
|
||||
|
||||
List<AttributeSet> attributeSetList = [];
|
||||
foreach (Node node in GetChildren())
|
||||
{
|
||||
@@ -468,15 +476,24 @@ public partial class PlayerController : CharacterBody3D,
|
||||
Abilities = new(this);
|
||||
Events = new();
|
||||
|
||||
HealthAttribute = Attributes["PlayerAttributeSet.Health"];
|
||||
ManaAttribute = Attributes["PlayerAttributeSet.Mana"];
|
||||
|
||||
cuesManager.RegisterCue(Tag.RequestTag(tagsManager, "cues.resources.health"), this);
|
||||
|
||||
if (EmpoweredActionAbility != null)
|
||||
{
|
||||
_empoweredActionHandle = Abilities.GrantAbilityPermanently(
|
||||
EmpoweredActionAbility.GetAbilityData(),
|
||||
abilityLevel: 1,
|
||||
levelOverridePolicy: LevelComparison.None,
|
||||
sourceEntity: this);
|
||||
foreach (var ability in DefaultPermanentAbilities)
|
||||
}
|
||||
|
||||
foreach (var defaultGrantedAbility in DefaultGrantedAbilities)
|
||||
{
|
||||
Abilities.GrantAbilityPermanently(
|
||||
ability.GetAbilityData(),
|
||||
defaultGrantedAbility.GetAbilityData(),
|
||||
abilityLevel: 1,
|
||||
levelOverridePolicy: LevelComparison.None,
|
||||
sourceEntity: this);
|
||||
@@ -496,37 +513,23 @@ public partial class PlayerController : CharacterBody3D,
|
||||
EffectsManager.ApplyEffect(new Effect(effect.GetEffectData(), new EffectOwnership(this, this)));
|
||||
});
|
||||
}
|
||||
|
||||
Events.Subscribe(Tag.RequestTag(ForgeManagers.Instance.TagsManager, "events.combat.damage"), OnDamageReceived);
|
||||
Events.Subscribe(Tag.RequestTag(ForgeManagers.Instance.TagsManager, "events.combat.death"), OnDeath);
|
||||
|
||||
PlayerUi.Initialize(HealthAttribute, ManaAttribute);
|
||||
#endregion
|
||||
|
||||
// DashIndicator = GetNode<TextureRect>("%DashIndicator");
|
||||
TargetSpeed = WalkSpeed;
|
||||
DashIndicatorNode = GetNode<Node3D>("DashIndicator");
|
||||
DashIndicatorMesh = GetNode<MeshInstance3D>("DashIndicator/DashIndicatorMesh");
|
||||
DashIndicatorMeshCylinder = (DashIndicatorMesh.Mesh as CylinderMesh)!;
|
||||
DashIndicatorMesh.Visible = false;
|
||||
|
||||
SfxPlayer = GetNode<AudioStreamPlayer3D>("SFXPlayer");
|
||||
_audioStream = (SfxPlayer.GetStreamPlayback() as AudioStreamPlaybackInteractive)!;
|
||||
|
||||
// Camera stuff
|
||||
HeadSystem = GetNode<HeadSystem>("HeadSystem");
|
||||
_camera = GetNode<Camera3D>("HeadSystem/CameraSmooth/Camera3D");
|
||||
Node3D cameraSmooth = GetNode<Node3D>("HeadSystem/CameraSmooth");
|
||||
|
||||
// Movement stuff
|
||||
WeaponSystem = GetNode<WeaponSystem>("WeaponSystem");
|
||||
MantleSystem = GetNode<MantleSystem>("HeadSystem/MantleSystem");
|
||||
StandingCollider = GetNode<CollisionShape3D>("StandingCollider");
|
||||
SlideCollider = GetNode<CollisionShape3D>("SlideCollider");
|
||||
DashSystem = GetNode<DashSystem>("DashSystem");
|
||||
StairsSystem = GetNode<StairsSystem>("StairsSystem");
|
||||
WallHugSystem = GetNode<WallHugSystem>("WallHugSystem");
|
||||
WallRunSnapper = GetNode<RayCast3D>("%WallRunSnapper");
|
||||
GroundDetector = GetNode<ShapeCast3D>("GroundDetector");
|
||||
CeilingDetector = GetNode<ShapeCast3D>("CeilingDetector");
|
||||
DirectGroundDetector = GetNode<RayCast3D>("DirectGroundDetector");
|
||||
DashDamageDetector = GetNode<ShapeCast3D>("DashDamage");
|
||||
SlidingEnemyDetector = GetNode<Area3D>("SlidingEnemyDetector");
|
||||
RayCast3D stairsBelowRayCast3D = GetNode<RayCast3D>("StairsBelowRayCast3D");
|
||||
RayCast3D stairsAheadRayCast3D = GetNode<RayCast3D>("StairsAheadRayCast3D");
|
||||
_headCollisionDetectors = new RayCast3D[NumOfHeadCollisionDetectors];
|
||||
@@ -545,25 +548,17 @@ public partial class PlayerController : CharacterBody3D,
|
||||
WeaponHitbox.Monitoring = false;
|
||||
WeaponHitbox.BodyEntered += RegisterHitEnnemy;
|
||||
|
||||
CHealth = GetNode<Node>("CHealth") as CHealth;
|
||||
CKnockback = GetNode<Node>("CKnockback") as CKnockback;
|
||||
CDamageable = GetNode<Node>("CDamageable") as CDamageable;
|
||||
if (CHealth == null) throw new Exception("CHealth not found!");
|
||||
if (CKnockback == null) throw new Exception("CKnockback not found!");
|
||||
if (CDamageable == null) throw new Exception("CDamageable not found!");
|
||||
|
||||
if (RHealth != null)
|
||||
{
|
||||
CHealth.RHealth = RHealth;
|
||||
CHealth.CurrentHealth = RHealth.StartingHealth;
|
||||
}
|
||||
if (RKnockback != null) CKnockback!.RKnockback = RKnockback;
|
||||
|
||||
PlayerUi.Initialize(CHealth.CurrentHealth, Attributes["PlayerAttributeSet.Mana"].BaseValue);
|
||||
CDamageable.DamageTaken += (damageable, record) => ReduceHealth(damageable, record);
|
||||
CDamageable.DamageTaken += (_, record) => RegisterKnockback(new KnockbackRecord(record));
|
||||
CHealth.HealthChanged += PlayerUi.OnHealthChanged;
|
||||
CHealth.HealthDepleted += (_) => Kill();
|
||||
// if (RHealth != null)
|
||||
// {
|
||||
// CHealth.RHealth = RHealth;
|
||||
// CHealth.CurrentHealth = RHealth.StartingHealth;
|
||||
// }
|
||||
// if (RKnockback != null) CKnockback!.RKnockback = RKnockback;
|
||||
//
|
||||
// CDamageable.DamageTaken += (damageable, record) => ReduceHealth(damageable, record);
|
||||
// CDamageable.DamageTaken += (_, record) => RegisterKnockback(new KnockbackRecord(record));
|
||||
// CHealth.HealthChanged += PlayerUi.OnHealthChanged;
|
||||
// CHealth.HealthDepleted += (_) => Kill();
|
||||
|
||||
#region StateManagement
|
||||
|
||||
@@ -633,7 +628,7 @@ public partial class PlayerController : CharacterBody3D,
|
||||
Gravity = (float)ProjectSettings.GetSetting("physics/3d/default_gravity");
|
||||
MantleSystem.Init();
|
||||
StairsSystem.Init(stairsBelowRayCast3D, stairsAheadRayCast3D, cameraSmooth);
|
||||
DashSystem.Init(HeadSystem, _camera);
|
||||
DashSystem.Init(HeadSystem, Camera);
|
||||
WeaponSystem.Init();
|
||||
WallHugSystem.Init();
|
||||
|
||||
@@ -729,6 +724,8 @@ public partial class PlayerController : CharacterBody3D,
|
||||
var weaponLandedToken = WeaponSystem.Events.Subscribe(WeaponSystem.WeaponStoppedFlyingEventTag, OnWeaponLanded);
|
||||
}
|
||||
|
||||
#region LifecycleManagement
|
||||
|
||||
public void OnResolved()
|
||||
{
|
||||
// Initialize weapon with inventory abilities
|
||||
@@ -737,8 +734,7 @@ public partial class PlayerController : CharacterBody3D,
|
||||
{
|
||||
foreach (var ability in abilities)
|
||||
{
|
||||
if (ability is not ForgeAbilityBehavior abilityBehavior) continue;
|
||||
WeaponSystem.GrantNewAbilityForEvent(weaponEvent, abilityBehavior);
|
||||
WeaponSystem.GrantNewAbilityForEvent(weaponEvent, ability);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -753,6 +749,10 @@ public partial class PlayerController : CharacterBody3D,
|
||||
InventoryManager.WeaponEventAbilityRemoved -= OnWeaponEventAbilityRemoved;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WeaponEvents
|
||||
|
||||
public void OnWeaponLeft(EventData data)
|
||||
{
|
||||
var target = data.Target;
|
||||
@@ -790,9 +790,10 @@ public partial class PlayerController : CharacterBody3D,
|
||||
WeaponSystem.RemoveAbilityForEvent(data.ForEvent, data.Ability);
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// Settings & tutorial //
|
||||
///////////////////////////
|
||||
#endregion
|
||||
|
||||
#region Settings
|
||||
|
||||
public void LoadSettings()
|
||||
{
|
||||
var config = new ConfigFile();
|
||||
@@ -813,23 +814,24 @@ public partial class PlayerController : CharacterBody3D,
|
||||
_aimAssistMultiplier = (float) config.GetValue("InputSettings", "AimAssist", 1.0f);
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// Toolbox Utils //
|
||||
///////////////////////////
|
||||
#endregion
|
||||
|
||||
#region Toolbox
|
||||
|
||||
public void SetPlayerHealthOverride(float newHealthValue)
|
||||
{
|
||||
RHealth.StartingHealth = newHealthValue;
|
||||
CHealth!.CurrentHealth = newHealthValue;
|
||||
PlayerUi.Initialize(CHealth.CurrentHealth, Attributes["PlayerAttributeSet.Mana"].BaseValue);
|
||||
// RHealth.StartingHealth = newHealthValue;
|
||||
// CHealth!.CurrentHealth = newHealthValue;
|
||||
// PlayerUi.Initialize(CHealth.CurrentHealth, Attributes["PlayerAttributeSet.Mana"].BaseValue);
|
||||
}
|
||||
public void SetPlayerDamageOverride(float newDamageValue)
|
||||
{
|
||||
RDamage.DamageDealt = newDamageValue;
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// Grounded management //
|
||||
///////////////////////////
|
||||
#endregion
|
||||
|
||||
#region GroundManagement
|
||||
|
||||
public void OnGrounded()
|
||||
{
|
||||
@@ -882,10 +884,7 @@ public partial class PlayerController : CharacterBody3D,
|
||||
_audioStream.SwitchToClipByName("land");
|
||||
}
|
||||
|
||||
public bool IsGroundLike()
|
||||
{
|
||||
return GroundDetector.GetCollisionResult().Count > 0;
|
||||
}
|
||||
public bool IsGroundLike() => GroundDetector.GetCollisionResult().Count > 0;
|
||||
|
||||
public void HandleGrounded(float delta)
|
||||
{
|
||||
@@ -973,10 +972,9 @@ public partial class PlayerController : CharacterBody3D,
|
||||
return IsOnFloor() || StairsSystem.WasSnappedToStairsLastFrame();
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// Airborne management //
|
||||
///////////////////////////
|
||||
#endregion
|
||||
|
||||
#region AirborneManagement
|
||||
public void OnAirborne()
|
||||
{
|
||||
if (_aiming.Active)
|
||||
@@ -1027,6 +1025,8 @@ public partial class PlayerController : CharacterBody3D,
|
||||
Velocity = new Vector3(horizontalVelocity.X, verticalVelocity, horizontalVelocity.Z);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
///////////////////////////
|
||||
// Movement input //
|
||||
///////////////////////////
|
||||
@@ -1091,17 +1091,17 @@ public partial class PlayerController : CharacterBody3D,
|
||||
// Camera stuff
|
||||
private Vector2 ComputeAimAssist()
|
||||
{
|
||||
_aimAssisRayCast.SetRotation(HeadSystem.GetGlobalLookRotation());
|
||||
if (!_aimAssisRayCast.IsColliding()) return Vector2.Zero;
|
||||
AimAssistRayCast.SetRotation(HeadSystem.GetGlobalLookRotation());
|
||||
if (!AimAssistRayCast.IsColliding()) return Vector2.Zero;
|
||||
|
||||
// Hard dependency on the aim assist to be an Area3D and having a parent
|
||||
var collidedObject = _aimAssisRayCast.GetCollider() as Area3D;
|
||||
var collidedObject = AimAssistRayCast.GetCollider() as Area3D;
|
||||
if (collidedObject is null) return Vector2.Zero;
|
||||
if (collidedObject.GetParent() is not ITargetable targetable) return Vector2.Zero;
|
||||
|
||||
var targetPosition = targetable.GetTargetGlobalPosition();
|
||||
var targetPositionOnCamera = _camera.UnprojectPosition(targetPosition);
|
||||
var centerOfScreen = _camera.GetViewport().GetVisibleRect().Size / 2f;
|
||||
var targetPositionOnCamera = Camera.UnprojectPosition(targetPosition);
|
||||
var centerOfScreen = Camera.GetViewport().GetVisibleRect().Size / 2f;
|
||||
var aimAssistDirection = centerOfScreen - targetPositionOnCamera;
|
||||
var aimAssist = aimAssistDirection * AimAssistStrength / 1000f;
|
||||
|
||||
@@ -2061,7 +2061,7 @@ public partial class PlayerController : CharacterBody3D,
|
||||
if (!isOnFloorCustom())
|
||||
ReduceTimeScaleWhileAiming();
|
||||
|
||||
_aimAssisRayCast.TargetPosition = _aimAssisRayCast.TargetPosition.Normalized() *
|
||||
AimAssistRayCast.TargetPosition = AimAssistRayCast.TargetPosition.Normalized() *
|
||||
(DashSystem.DashCast3D.TargetPosition.Length() + DashSystem.DashCastRadius);
|
||||
}
|
||||
public void HandleAiming(float delta)
|
||||
@@ -2076,7 +2076,7 @@ public partial class PlayerController : CharacterBody3D,
|
||||
{
|
||||
DashSystem.StopPreparingDash();
|
||||
|
||||
_aimAssisRayCast.TargetPosition = _aimAssisRayCast.TargetPosition.Normalized() * (TargetingDistance*1.5f);
|
||||
AimAssistRayCast.TargetPosition = AimAssistRayCast.TargetPosition.Normalized() * (TargetingDistance*1.5f);
|
||||
|
||||
// DashIndicatorMesh.Visible = false;
|
||||
}
|
||||
@@ -2337,6 +2337,11 @@ public partial class PlayerController : CharacterBody3D,
|
||||
// private float _oldMana = 100;
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (Engine.GetProcessFrames() % 60 == 0)
|
||||
{
|
||||
GD.Print(_invincibleEffect);
|
||||
GD.Print(Tags.CombinedTags.Count);
|
||||
}
|
||||
EffectsManager.UpdateEffects(delta);
|
||||
}
|
||||
|
||||
@@ -2351,7 +2356,7 @@ public partial class PlayerController : CharacterBody3D,
|
||||
public void HandleEnemyTargeting()
|
||||
{
|
||||
_isEnemyInDashAttackRange = false;
|
||||
_closeEnemyDetector.SetRotation(HeadSystem.GetGlobalLookRotation());
|
||||
CloseEnemyDetector.SetRotation(HeadSystem.GetGlobalLookRotation());
|
||||
var enemyTargetState = PlayerUi.TargetState.NoTarget;
|
||||
var positionOnScreen = Vector2.Zero;
|
||||
|
||||
@@ -2359,20 +2364,20 @@ public partial class PlayerController : CharacterBody3D,
|
||||
{
|
||||
enemyTargetState = PlayerUi.TargetState.TargetWouldKill;
|
||||
_targetLocation = dashTarget.GetTargetGlobalPosition();
|
||||
positionOnScreen = _camera.UnprojectPosition(_targetLocation);
|
||||
positionOnScreen = Camera.UnprojectPosition(_targetLocation);
|
||||
PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!_closeEnemyDetector.IsColliding())
|
||||
if (!CloseEnemyDetector.IsColliding())
|
||||
{
|
||||
PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen));
|
||||
return;
|
||||
}
|
||||
|
||||
_targetHitLocation = _closeEnemyDetector.GetCollisionPoint(0);
|
||||
_targetObject = _closeEnemyDetector.GetCollider(0);
|
||||
_targetHitLocation = CloseEnemyDetector.GetCollisionPoint(0);
|
||||
_targetObject = CloseEnemyDetector.GetCollider(0);
|
||||
if (_targetObject is not ITargetable target)
|
||||
{
|
||||
PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen));
|
||||
@@ -2381,7 +2386,7 @@ public partial class PlayerController : CharacterBody3D,
|
||||
|
||||
_targetLocation = target.GetTargetGlobalPosition();
|
||||
// var targetDistance = _targetLocation.DistanceTo(GlobalPosition);
|
||||
positionOnScreen = _camera.UnprojectPosition(_targetLocation);
|
||||
positionOnScreen = Camera.UnprojectPosition(_targetLocation);
|
||||
|
||||
var wouldKill = false;
|
||||
if (_targetObject is IHealthable h and IDamageable d)
|
||||
@@ -2399,20 +2404,21 @@ public partial class PlayerController : CharacterBody3D,
|
||||
if (IsInvincible)
|
||||
return damageRecord with { Damage = new RDamage(0, damageRecord.Damage.DamageType) };
|
||||
|
||||
var finalDamage = CDamageable!.TakeDamage(damageRecord);
|
||||
DamageTaken?.Invoke(this, finalDamage);
|
||||
// var finalDamage = CDamageable!.TakeDamage(damageRecord);
|
||||
// DamageTaken?.Invoke(this, finalDamage);
|
||||
|
||||
HeadSystem.OnGetHit();
|
||||
_audioStream.SwitchToClipByName("damage_taken");
|
||||
TriggerHitstop();
|
||||
OnHitInvincibility();
|
||||
|
||||
return finalDamage;
|
||||
return damageRecord;
|
||||
}
|
||||
|
||||
public DamageRecord ComputeDamage(DamageRecord damageRecord)
|
||||
{
|
||||
return CDamageable!.ComputeDamage(damageRecord);
|
||||
// return CDamageable!.ComputeDamage(damageRecord);
|
||||
return damageRecord;
|
||||
}
|
||||
|
||||
public void OnHitInvincibility()
|
||||
@@ -2590,19 +2596,25 @@ public partial class PlayerController : CharacterBody3D,
|
||||
}
|
||||
public HealthChangedRecord ReduceHealth(IDamageable source, DamageRecord damageRecord)
|
||||
{
|
||||
var record = CHealth!.ReduceHealth(source, damageRecord);
|
||||
HealthChanged?.Invoke(this, record);
|
||||
return record;
|
||||
// var record = CHealth!.ReduceHealth(source, damageRecord);
|
||||
// HealthChanged?.Invoke(this, record);
|
||||
return new HealthChangedRecord(100, 0, 100);
|
||||
}
|
||||
public void RegisterKnockback(KnockbackRecord knockbackRecord)
|
||||
{
|
||||
CKnockback!.RegisterKnockback(knockbackRecord);
|
||||
// CKnockback!.RegisterKnockback(knockbackRecord);
|
||||
}
|
||||
|
||||
public Vector3 ComputeKnockback()
|
||||
{
|
||||
var kb = CKnockback!.ComputeKnockback();
|
||||
return kb;
|
||||
// var kb = CKnockback!.ComputeKnockback();
|
||||
// return kb;
|
||||
return Vector3.Zero;
|
||||
}
|
||||
|
||||
public void OnDeath(EventData data)
|
||||
{
|
||||
Kill();
|
||||
}
|
||||
|
||||
public void Kill()
|
||||
@@ -2625,4 +2637,43 @@ public partial class PlayerController : CharacterBody3D,
|
||||
{
|
||||
_audioStream.SwitchToClipByName("footsteps");
|
||||
}
|
||||
|
||||
// Forge Damage handling
|
||||
public void OnDamageReceived(EventData data)
|
||||
{
|
||||
var newHealth = HealthAttribute.CurrentValue + data.EventMagnitude;
|
||||
if (newHealth > HealthAttribute.Min) return;
|
||||
|
||||
var tagsManager = ForgeManagers.Instance.TagsManager;
|
||||
Events.Raise(new EventData
|
||||
{
|
||||
EventTags = Tag.RequestTag(tagsManager, "events.combat.death").GetSingleTagContainer()!,
|
||||
Source = data.Source,
|
||||
Target = data.Target
|
||||
});
|
||||
}
|
||||
|
||||
public void OnExecute(IForgeEntity? target, CueParameters? parameters)
|
||||
{
|
||||
if (target == null || !parameters.HasValue) return;
|
||||
|
||||
float magnitude = parameters.Value.Magnitude;
|
||||
if (magnitude >= 0) return;
|
||||
|
||||
HeadSystem.OnGetHit();
|
||||
_audioStream.SwitchToClipByName("damage_taken");
|
||||
TriggerHitstop();
|
||||
}
|
||||
|
||||
public void OnApply(IForgeEntity? target, CueParameters? parameters)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnRemove(IForgeEntity? target, bool interrupted)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnUpdate(IForgeEntity? target, CueParameters? parameters)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_heart.png")]
|
||||
public partial class Healthbar : ProgressBar
|
||||
{
|
||||
private Timer _damageCatchUpTimer = null!;
|
||||
private ProgressBar _damagedHealth = null!;
|
||||
|
||||
[Export] public StyleBox? BarStyle;
|
||||
|
||||
private float _currentHealth;
|
||||
public float CurrentHealth
|
||||
{
|
||||
get => _currentHealth;
|
||||
set => SetHealth(value);
|
||||
}
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_damageCatchUpTimer = GetNode<Timer>("DamageCatchUp");
|
||||
_damagedHealth = GetNode<ProgressBar>("Damagebar");
|
||||
|
||||
_damageCatchUpTimer.Timeout += OnDamageCatchUp;
|
||||
Visible = false;
|
||||
|
||||
if (BarStyle != null)
|
||||
AddThemeStyleboxOverride("fill", BarStyle);
|
||||
}
|
||||
|
||||
public void Initialize(float initialHealth)
|
||||
{
|
||||
_currentHealth = initialHealth;
|
||||
MaxValue = initialHealth;
|
||||
Value = initialHealth;
|
||||
_damagedHealth.MaxValue = initialHealth;
|
||||
_damagedHealth.Value = initialHealth;
|
||||
}
|
||||
|
||||
public void SetHealth(float newHealth)
|
||||
{
|
||||
var previousHealth = _currentHealth;
|
||||
_currentHealth = Mathf.Min(newHealth, (float) MaxValue);
|
||||
_currentHealth = newHealth;
|
||||
Value = _currentHealth;
|
||||
|
||||
Visible = _currentHealth < MaxValue;
|
||||
|
||||
if (_currentHealth < previousHealth)
|
||||
{
|
||||
_damageCatchUpTimer.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
_damagedHealth.Value = _currentHealth;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDamageCatchUp()
|
||||
{
|
||||
_damagedHealth.Value = _currentHealth;
|
||||
}
|
||||
}
|
||||
92
scenes/ui/resourcebar/ResourceBar.cs
Normal file
92
scenes/ui/resourcebar/ResourceBar.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Gamesmiths.Forge.Attributes;
|
||||
using Gamesmiths.Forge.Core;
|
||||
using Gamesmiths.Forge.Cues;
|
||||
using Gamesmiths.Forge.Godot.Core;
|
||||
using Gamesmiths.Forge.Tags;
|
||||
|
||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_heart.png"), Meta(typeof(IAutoOn), typeof(IAutoConnect))]
|
||||
public partial class ResourceBar : ProgressBar, ICueHandler
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
[Node("DamageCatchUp")] public required Timer DamageCatchUp { get; set; }
|
||||
[Node("Damagebar")] public required ProgressBar DamageBar { get; set; }
|
||||
|
||||
[Export] public StyleBox? BarStyle;
|
||||
|
||||
private float _currentValue;
|
||||
public float CurrentValue
|
||||
{
|
||||
get => _currentValue;
|
||||
set => SetValue(value);
|
||||
}
|
||||
|
||||
public void OnReady()
|
||||
{
|
||||
DamageCatchUp.Timeout += OnDamageCatchUp;
|
||||
Visible = false;
|
||||
|
||||
if (BarStyle != null)
|
||||
AddThemeStyleboxOverride("fill", BarStyle);
|
||||
}
|
||||
|
||||
public void Initialize(EntityAttribute attribute, Tag cueTag)
|
||||
{
|
||||
_currentValue = attribute.BaseValue;
|
||||
MaxValue = attribute.Max;
|
||||
Value = attribute.BaseValue;
|
||||
DamageBar.MaxValue = attribute.Max;
|
||||
DamageBar.Value = attribute.BaseValue;
|
||||
|
||||
var cuesManager = ForgeManagers.Instance.CuesManager;
|
||||
cuesManager.RegisterCue(cueTag, this);
|
||||
}
|
||||
|
||||
public void SetValue(float newValue)
|
||||
{
|
||||
var previousValue = _currentValue;
|
||||
_currentValue = Mathf.Min(newValue, (float) MaxValue);
|
||||
_currentValue = newValue;
|
||||
Value = _currentValue;
|
||||
|
||||
Visible = _currentValue < MaxValue;
|
||||
|
||||
if (_currentValue < previousValue)
|
||||
{
|
||||
DamageCatchUp.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
DamageBar.Value = _currentValue;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDamageCatchUp()
|
||||
{
|
||||
DamageBar.Value = _currentValue;
|
||||
}
|
||||
|
||||
public void OnExecute(IForgeEntity? target, CueParameters? parameters)
|
||||
{
|
||||
if (target == null || !parameters.HasValue) return;
|
||||
|
||||
float magnitude = parameters.Value.Magnitude;
|
||||
CurrentValue += magnitude;
|
||||
}
|
||||
|
||||
public void OnApply(IForgeEntity? target, CueParameters? parameters)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnRemove(IForgeEntity? target, bool interrupted)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnUpdate(IForgeEntity? target, CueParameters? parameters)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
using Godot;
|
||||
using GdUnit4;
|
||||
using static GdUnit4.Assertions;
|
||||
using Movementtests.interfaces;
|
||||
using Movementtests.systems.damage;
|
||||
|
||||
namespace Movementtests.tests;
|
||||
|
||||
[TestSuite, RequireGodotRuntime]
|
||||
public class PlayerControllerUnitTest
|
||||
{
|
||||
private PlayerController _player;
|
||||
|
||||
[BeforeTest]
|
||||
public void SetupTest()
|
||||
{
|
||||
_player = new PlayerController();
|
||||
_player.TargetSpeed = 7.0f;
|
||||
_player.Gravity = 9.8f;
|
||||
|
||||
var rHealth = new RHealth(100.0f);
|
||||
_player.RHealth = rHealth;
|
||||
_player.CHealth = new CHealth { RHealth = rHealth, CurrentHealth = 100.0f };
|
||||
}
|
||||
|
||||
[AfterTest]
|
||||
public void CleanupTest()
|
||||
{
|
||||
_player?.Free();
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void TestCalculateGravityForce()
|
||||
{
|
||||
_player.Weight = 3.0f;
|
||||
// gravity is 9.8f
|
||||
AssertFloat(_player.CalculateGravityForce()).IsEqualApprox(29.4f, 0.001f);
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void TestIsPlayerInputtingForward()
|
||||
{
|
||||
// Test Keyboard Input
|
||||
_player.InputDeviceChanged(false);
|
||||
_player.OnInputMoveKeyboard(Vector3.Forward);
|
||||
AssertBool(_player.IsPlayerInputtingForward()).IsTrue();
|
||||
|
||||
_player.OnInputMoveKeyboard(Vector3.Back);
|
||||
AssertBool(_player.IsPlayerInputtingForward()).IsFalse();
|
||||
|
||||
// Test Gamepad Input
|
||||
_player.InputDeviceChanged(true);
|
||||
_player.OnInputMove(new Vector3(0, 0, -1));
|
||||
AssertBool(_player.IsPlayerInputtingForward()).IsTrue();
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void TestSetVerticalVelocity()
|
||||
{
|
||||
_player.Velocity = new Vector3(1, 0, 2);
|
||||
_player.SetVerticalVelocity(5.0f);
|
||||
AssertVector(_player.Velocity).IsEqual(new Vector3(1, 5, 2));
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void TestComputeHVelocityGround()
|
||||
{
|
||||
_player.Velocity = Vector3.Zero;
|
||||
_player.AccelerationFloor = 10.0f;
|
||||
|
||||
float delta = 0.1f;
|
||||
Vector3 newVelocity = _player.ComputeHVelocity(delta, _player.AccelerationFloor, _player.DecelerationFloor, Vector3.Forward);
|
||||
AssertVector(newVelocity).IsEqual(new Vector3(0, 0, -7.0f));
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void TestComputeHVelocityAir()
|
||||
{
|
||||
_player.Velocity = new Vector3(5, 0, 0);
|
||||
_player.AccelerationAir = 2.0f;
|
||||
_player.DecelerationAir = 2.0f;
|
||||
|
||||
float delta = 0.5f;
|
||||
Vector3 newVelocity = _player.ComputeHVelocity(delta, _player.AccelerationAir, _player.DecelerationAir, Vector3.Zero);
|
||||
|
||||
AssertVector(newVelocity).IsEqual(Vector3.Zero);
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void TestReduceHealth()
|
||||
{
|
||||
var damageRecord = new DamageRecord(Vector3.Zero, new RDamage(25.0f, EDamageTypes.Normal));
|
||||
_player.ReduceHealth(_player, damageRecord);
|
||||
AssertFloat(_player.CHealth.CurrentHealth).IsEqual(75.0f);
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void TestDashCooldownTimeout()
|
||||
{
|
||||
_player.CanDash = false;
|
||||
_player.DashCooldownTimeout();
|
||||
AssertBool(_player.CanDash).IsTrue();
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void TestGetInputLocalHDirection()
|
||||
{
|
||||
_player.InputDeviceChanged(false);
|
||||
_player.OnInputMoveKeyboard(new Vector3(1, 0, 1));
|
||||
|
||||
Vector3 expected = new Vector3(1, 0, 1).Normalized();
|
||||
AssertVector(_player.GetInputLocalHDirection()).IsEqualApprox(expected, new Vector3(0.001f, 0.001f, 0.001f));
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void TestComputeKnockback()
|
||||
{
|
||||
var cKnockback = new CKnockback();
|
||||
cKnockback.RKnockback = new RKnockback(10.0f);
|
||||
_player.CKnockback = cKnockback;
|
||||
|
||||
var damageRecord = new DamageRecord(new Vector3(10, 0, 0), new RDamage(0, EDamageTypes.Normal));
|
||||
var knockbackRecord = new KnockbackRecord(damageRecord, 1.0f);
|
||||
|
||||
_player.GlobalPosition = Vector3.Zero;
|
||||
cKnockback.GlobalPosition = Vector3.Zero;
|
||||
|
||||
_player.RegisterKnockback(knockbackRecord);
|
||||
|
||||
Vector3 knockback = cKnockback.ComputeKnockback();
|
||||
AssertVector(knockback).IsEqual(new Vector3(-10, 0, 0));
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
uid://kmphtu0ovixi
|
||||
Reference in New Issue
Block a user