hitting is now an ability

This commit is contained in:
2026-05-02 11:19:56 +02:00
parent 24f057c15f
commit fb30a08b89
19 changed files with 588 additions and 395 deletions

View File

@@ -61,6 +61,7 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
#region Forge
private AbilityHandle? _empoweredActionHandle;
private AbilityHandle? _hitAbilityHandle;
public required EntityAttribute HealthAttribute { get; set; }
public required EntityAttribute ManaAttribute { get; set; }
@@ -103,12 +104,12 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
#region Publics
public EntityAttributes Attributes { get; set; } = null!;
public EntityTags Tags { get; set; } = null!;
public EffectsManager EffectsManager { get; set; } = null!;
public EntityAbilities Abilities { get; set; } = null!;
public EventManager Events { get; set; } = null!;
public Variables SharedVariables { get; }
public required EntityAttributes Attributes { get; set; }
public required EntityTags Tags { get; set; }
public required EffectsManager EffectsManager { get; set; }
public required EntityAbilities Abilities { get; set; }
public required EventManager Events { get; set; }
public required Variables SharedVariables { get; set; }
#endregion
@@ -125,7 +126,8 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
[ExportGroup("Abilities")]
[ExportSubgroup("Common and defaults")]
[Export] public ForgeAbilityData? EmpoweredActionAbility;
[Export] public required ForgeAbilityData HitAbility { get; set; }
[Export] public required ForgeAbilityData EmpoweredActionAbility { get; set; }
[Export] public ForgeAbilityData[] DefaultGrantedAbilities = [];
[ExportGroup("Effects")]
@@ -443,7 +445,7 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
}
// Damage dealing
private readonly List<IDamageable> _hitEnemies = new List<IDamageable>();
private readonly List<IForgeEntity> _hitEnemies = [];
#endregion
@@ -454,17 +456,12 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
// General use stuff
List<AttributeSet> attributeSetList = [];
foreach (Node node in GetChildren())
foreach (var node in GetChildren())
{
if (node is ForgeAttributeSet attributeSetNode)
{
AttributeSet? attributeSet = attributeSetNode.GetAttributeSet();
if (attributeSet is not null)
{
attributeSetList.Add(attributeSet);
}
}
if (node is not ForgeAttributeSet attributeSetNode) continue;
var attributeSet = attributeSetNode.GetAttributeSet();
if (attributeSet is not null)
attributeSetList.Add(attributeSet);
}
Attributes = new EntityAttributes([.. attributeSetList]);
HealthAttribute = Attributes["PlayerAttributeSet.Health"];
@@ -682,21 +679,31 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
}
#region LifecycleManagement
public override void _ExitTree()
{
base._ExitTree();
ForgeManagers.Instance.CuesManager.UnregisterCue(Tag.RequestTag(TagsManager, "cues.resources.health"), this);
}
public void OnResolved()
{
#region Forge
EffectsManager = new EffectsManager(this, CuesManager);
CuesManager.RegisterCue(Tag.RequestTag(TagsManager, "cues.resources.health"), this);
if (EmpoweredActionAbility != null)
{
_empoweredActionHandle = Abilities.GrantAbilityPermanently(
EmpoweredActionAbility.GetAbilityData(),
abilityLevel: 1,
levelOverridePolicy: LevelComparison.None,
sourceEntity: this);
}
_hitAbilityHandle = Abilities.GrantAbilityPermanently(
HitAbility.GetAbilityData(),
abilityLevel: 1,
levelOverridePolicy: LevelComparison.None,
sourceEntity: this);
_empoweredActionHandle = Abilities.GrantAbilityPermanently(
EmpoweredActionAbility.GetAbilityData(),
abilityLevel: 1,
levelOverridePolicy: LevelComparison.None,
sourceEntity: this);
foreach (var defaultGrantedAbility in DefaultGrantedAbilities)
{
@@ -713,6 +720,10 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
EffectsManager.ApplyEffect(new Effect(effect.GetEffectData(), new EffectOwnership(this, this)));
}
// Apply children node effects
// var effectApplier = new EffectApplier(this);
// effectApplier.ApplyEffects(this, this, this);
// Subscribe default empowered actions effects to the Empowered Action Used event
foreach (var effect in EmpoweredActionEffects)
{
@@ -1924,9 +1935,9 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
public void EnemyHitWhileSliding(Node enemy)
{
if(enemy is not IDamageable damageable)
if(enemy is not IForgeEntity entity)
return;
_hitEnemies.Add(damageable);
_hitEnemies.Add(entity);
TriggerDamage();
}
@@ -2145,8 +2156,8 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
for (var i = 0; i < DashDamageDetector.GetCollisionCount(); i++)
{
var collidedObject = DashDamageDetector.GetCollider(i);
if (collidedObject is not IDamageable damageable) continue;
_hitEnemies.Add(damageable);
if (collidedObject is not IForgeEntity entity) continue;
_hitEnemies.Add(entity);
}
TriggerDamage();
@@ -2296,9 +2307,9 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
public void ManageAttackedEnemyPostDash(Node? enemy)
{
if (enemy is IDamageable damageable)
if (enemy is IForgeEntity entity)
{
_hitEnemies.Add(damageable);
_hitEnemies.Add(entity);
TriggerDamage();
}
if (enemy is IStunnable stunnable)
@@ -2332,9 +2343,9 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
LookAround(delta);
}
// private float _oldMana = 100;
public override void _Process(double delta)
{
Abilities.UpdateAbilities(delta);
EffectsManager.UpdateEffects(delta);
}
@@ -2478,9 +2489,9 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
public void StopDashAction()
{
if (_targetObject is IDamageable damageable)
if (_targetObject is IForgeEntity entity)
{
_hitEnemies.Add(damageable);
_hitEnemies.Add(entity);
TriggerDamage();
}
if (_targetObject is IStunnable stunnable)
@@ -2536,9 +2547,12 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
return;
}
if (!WeaponSystem.InHandState.Active) return;
if (_hitAbilityHandle is null) return;
if (!_hitAbilityHandle.CanActivate(out _)) return;
var attackToDo = _isEnemyInDashAttackRange ? "dash_attack" : "standard_attack";
_playerState.SendEvent(attackToDo);
_playerState.SendEvent("standard_attack");
}
public void ResetAttackCooldown()
@@ -2559,16 +2573,27 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
public void RegisterHitEnnemy(Node3D body)
{
if (body is not IDamageable damageable) return;
_hitEnemies.Add(damageable);
if (body is not IForgeEntity entity) return;
_hitEnemies.Add(entity);
// return;
// if (body is not IDamageable damageable) return;
// _hitEnemies.Add(damageable);
}
public void TriggerDamage()
{
if (_hitEnemies.Count == 0) return;
foreach (var damageable in _hitEnemies)
damageable.TakeDamage(new DamageRecord(GlobalPosition, RDamage));
if (_hitAbilityHandle is null) return;
if (!_hitAbilityHandle.CanActivate(out _)) return;
foreach (var entity in _hitEnemies)
{
// TODO: WTF why doesn't health move
// GD.Print(entity.Attributes["EnemyAttributeSet.Health"].CurrentValue);
_hitAbilityHandle.Activate(out _, entity);
}
_hitEnemies.Clear();
HeadSystem.OnHitTarget();
@@ -2587,12 +2612,6 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
{
ResetTimeScale();
}
public HealthChangedRecord ReduceHealth(IDamageable source, DamageRecord damageRecord)
{
// var record = CHealth!.ReduceHealth(source, damageRecord);
// HealthChanged?.Invoke(this, record);
return new HealthChangedRecord(100, 0, 100);
}
public void RegisterKnockback(KnockbackRecord knockbackRecord)
{
// CKnockback!.RegisterKnockback(knockbackRecord);
@@ -2609,7 +2628,6 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
{
Kill();
}
public void Kill()
{
HeadSystem.OnStartDeathAnimation();
@@ -2635,6 +2653,19 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
public void OnDamageReceived(EventData data)
{
var newHealth = HealthAttribute.CurrentValue + data.EventMagnitude;
CuesManager.ExecuteCue(
Tag.RequestTag(TagsManager, "cues.resources.health"),
this,
new CueParameters(
(int) data.EventMagnitude,
data.EventMagnitude / HealthAttribute.Max,
data.Source,
new Dictionary<StringKey, object>
{
{"test", "hello"}
})
);
if (newHealth > HealthAttribute.Min) return;
var tagsManager = TagsManager;