Files
MovementTests/addons/forge/resources/abilities/ForgeAbilityData.cs
Minimata c4be97e0de
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 21s
Create tag and build when new code gets to main / Test (push) Successful in 6m56s
Create tag and build when new code gets to main / Export (push) Successful in 9m3s
added forge addon
2026-02-08 15:16:01 +01:00

181 lines
4.4 KiB
C#

// Copyright © Gamesmiths Guild.
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Gamesmiths.Forge.Abilities;
using Gamesmiths.Forge.Effects;
using Godot;
using Godot.Collections;
namespace Gamesmiths.Forge.Godot.Resources.Abilities;
[Tool]
[GlobalClass]
[Icon("uid://l04b8et2244r")]
public partial class ForgeAbilityData : Resource
{
private AbilityData? _data;
private AbilityInstancingPolicy _instancingPolicy;
[Export]
public string Name { get; set; } = string.Empty;
[Export]
public AbilityInstancingPolicy InstancingPolicy
{
get => _instancingPolicy;
set
{
_instancingPolicy = value;
NotifyPropertyListChanged();
}
}
[Export]
public bool RetriggerInstancedAbility { get; set; }
[Export]
public ForgeEffectData[]? CooldownEffects { get; set; }
[Export]
public ForgeEffectData? CostEffect { get; set; }
[Export]
public ForgeAbilityBehavior? AbilityBehavior { get; set; }
[ExportGroup("Trigger")]
[Export]
public TriggerSource TriggerSource { get; set; }
[Export]
public ForgeTag? TriggerTag { get; set; }
[Export]
public int Priority { get; set; }
[ExportGroup("Tags")]
[Export]
public ForgeTagContainer? AbilityTags { get; set; }
[Export]
public ForgeTagContainer? CancelAbilitiesWithTag { get; set; }
[Export]
public ForgeTagContainer? BlockAbilitiesWithTag { get; set; }
[Export]
public ForgeTagContainer? ActivationOwnedTags { get; set; }
[Export]
public ForgeTagContainer? ActivationRequiredTags { get; set; }
[Export]
public ForgeTagContainer? ActivationBlockedTags { get; set; }
[Export]
public ForgeTagContainer? SourceRequiredTags { get; set; }
[Export]
public ForgeTagContainer? SourceBlockedTags { get; set; }
[Export]
public ForgeTagContainer? TargetRequiredTags { get; set; }
[Export]
public ForgeTagContainer? TargetBlockedTags { get; set; }
public AbilityData GetAbilityData()
{
if (_data.HasValue)
{
return _data.Value;
}
List<EffectData> cooldownEffects = [];
foreach (ForgeEffectData cooldownEffect in CooldownEffects ?? [])
{
cooldownEffects.Add(cooldownEffect.GetEffectData());
}
_data = new AbilityData(
Name,
CostEffect?.GetEffectData(),
[.. cooldownEffects],
AbilityTags?.GetTagContainer(),
InstancingPolicy,
RetriggerInstancedAbility,
GetTriggerData(),
CancelAbilitiesWithTag?.GetTagContainer(),
BlockAbilitiesWithTag?.GetTagContainer(),
ActivationOwnedTags?.GetTagContainer(),
ActivationRequiredTags?.GetTagContainer(),
ActivationBlockedTags?.GetTagContainer(),
SourceRequiredTags?.GetTagContainer(),
SourceBlockedTags?.GetTagContainer(),
TargetRequiredTags?.GetTagContainer(),
TargetBlockedTags?.GetTagContainer(),
() => AbilityBehavior?.GetBehavior()!);
return _data.Value;
}
#if TOOLS
public override void _ValidateProperty(Dictionary property)
{
if (property["name"].AsStringName() == PropertyName.RetriggerInstancedAbility
&& InstancingPolicy != AbilityInstancingPolicy.PerEntity)
{
property["usage"] = (int)PropertyUsageFlags.NoEditor;
}
}
#endif
private AbilityTriggerData? GetTriggerData()
{
if (TriggerSource == TriggerSource.None)
{
return null;
}
Tags.Tag triggerTag = TriggerTag!.GetTag();
switch (TriggerSource)
{
case TriggerSource.Event:
IAbilityBehavior? behavior = AbilityBehavior?.GetBehavior();
if (behavior is not null)
{
System.Type behaviorType = behavior.GetType();
System.Type? payloadInterface =
System.Array.Find(behaviorType.GetInterfaces(), x =>
x.IsGenericType &&
x.GetGenericTypeDefinition() == typeof(IAbilityBehavior<>));
if (payloadInterface is not null)
{
System.Type payloadType = payloadInterface.GetGenericArguments()[0];
MethodInfo method = typeof(AbilityTriggerData)
.GetMethods(BindingFlags.Public | BindingFlags.Static)
.First(x => x.Name == nameof(AbilityTriggerData.ForEvent)
&& x.IsGenericMethodDefinition)
.MakeGenericMethod(payloadType);
return (AbilityTriggerData)method.Invoke(null, [triggerTag, Priority])!;
}
}
GD.Print($"call {triggerTag} - {Name}");
return AbilityTriggerData.ForEvent(triggerTag, Priority);
case TriggerSource.TagAdded:
return AbilityTriggerData.ForTagAdded(triggerTag);
case TriggerSource.TagPresent:
return AbilityTriggerData.ForTagPresent(triggerTag);
default:
return null;
}
}
}