added forge addon
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

This commit is contained in:
2026-02-08 15:16:01 +01:00
parent 2b74c9e70c
commit c4be97e0de
163 changed files with 6975 additions and 141 deletions

View File

@@ -0,0 +1,60 @@
// Copyright © Gamesmiths Guild.
using Gamesmiths.Forge.Cues;
using Godot;
using Godot.Collections;
namespace Gamesmiths.Forge.Godot.Resources;
[Tool]
[GlobalClass]
[Icon("uid://din7fexs0x53h")]
public partial class ForgeCue : Resource
{
private CueMagnitudeType _magnitudeType;
[Export]
public required ForgeTagContainer CueKeys { get; set; }
[Export]
public int MinValue { get; set; }
[Export]
public int MaxValue { get; set; }
[Export]
public CueMagnitudeType MagnitudeType
{
get => _magnitudeType;
set
{
_magnitudeType = value;
NotifyPropertyListChanged();
}
}
[Export]
public string? MagnitudeAttribute { get; set; }
public CueData GetCueData()
{
return new CueData(
CueKeys.GetTagContainer(),
MinValue,
MaxValue,
MagnitudeType,
string.IsNullOrEmpty(MagnitudeAttribute) ? null : MagnitudeAttribute);
}
#if TOOLS
public override void _ValidateProperty(Dictionary property)
{
if (property["name"].AsStringName() == PropertyName.MagnitudeAttribute
&& (MagnitudeType == CueMagnitudeType.EffectLevel || MagnitudeType == CueMagnitudeType.StackCount))
{
property["usage"] = (int)PropertyUsageFlags.NoEditor;
}
}
#endif
}

View File

@@ -0,0 +1 @@
uid://cmrsxccn0ei4j

View File

@@ -0,0 +1,514 @@
// Copyright © Gamesmiths Guild.
using System.Collections.Generic;
using System.Diagnostics;
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.Effects.Stacking;
using Gamesmiths.Forge.Godot.Resources.Calculators;
using Gamesmiths.Forge.Godot.Resources.Components;
using Gamesmiths.Forge.Godot.Resources.Magnitudes;
using Godot;
using Godot.Collections;
namespace Gamesmiths.Forge.Godot.Resources;
[Tool]
[GlobalClass]
[Icon("uid://obsk7rrtq1xd")]
public partial class ForgeEffectData : Resource
{
private EffectData? _data;
private DurationType _durationType;
private bool _hasPeriodicApplication;
private bool _canStack;
private StackPolicy _sourcePolicy;
private StackLevelPolicy _levelPolicy;
private StackOwnerOverridePolicy _instigatorOverridePolicy;
private LevelComparison _levelOverridePolicy;
[Export]
public string Name { get; set; } = string.Empty;
[Export]
public bool SnapshotLevel { get; set; } = true;
[ExportGroup("Modifier Data")]
[Export(PropertyHint.ResourceType, "ForgeModifier")]
public Array<ForgeModifier>? Modifiers { get; set; }
[ExportGroup("Components")]
[Export(PropertyHint.ResourceType, "ForgeEffectComponent")]
public Array<ForgeEffectComponent>? Components { get; set; }
[ExportGroup("Executions")]
[Export(PropertyHint.ResourceType, "ForgeCustomExecution")]
public Array<ForgeCustomExecution>? Executions { get; set; }
[ExportGroup("Duration Data")]
[Export]
public DurationType DurationType
{
get => _durationType;
set
{
_durationType = value;
if (value == DurationType.Instant)
{
_hasPeriodicApplication = false;
_canStack = false;
}
NotifyPropertyListChanged();
}
}
[Export]
public ForgeModifierMagnitude? Duration { get; set; }
[ExportGroup("Periodic Data")]
[Export]
public bool HasPeriodicApplication
{
get => _hasPeriodicApplication;
set
{
_hasPeriodicApplication = value;
NotifyPropertyListChanged();
}
}
[Export]
public ForgeScalableFloat? Period { get; set; }
[Export]
public bool ExecuteOnApplication { get; set; }
[ExportGroup("Stacking Data")]
[Export]
public bool CanStack
{
get => _canStack;
set
{
_canStack = value;
NotifyPropertyListChanged();
}
}
[Export]
public ForgeScalableInt StackLimit { get; set; } = new(1);
[Export]
public ForgeScalableInt InitialStack { get; set; } = new(1);
[Export]
public StackPolicy SourcePolicy
{
get => _sourcePolicy;
set
{
_sourcePolicy = value;
NotifyPropertyListChanged();
}
}
[Export]
[ExportSubgroup("Aggregate by Target", "Instigator")]
public StackOwnerDenialPolicy InstigatorDenialPolicy { get; set; }
[Export]
public StackOwnerOverridePolicy InstigatorOverridePolicy
{
get => _instigatorOverridePolicy;
set
{
_instigatorOverridePolicy = value;
NotifyPropertyListChanged();
}
}
[Export]
public StackOwnerOverrideStackCountPolicy InstigatorOverrideStackCountPolicy { get; set; }
[Export]
public StackLevelPolicy LevelPolicy
{
get => _levelPolicy;
set
{
_levelPolicy = value;
NotifyPropertyListChanged();
}
}
[Export]
[ExportSubgroup("Aggregate Levels", "Level")]
public LevelComparison LevelDenialPolicy { get; set; }
[Export]
public LevelComparison LevelOverridePolicy
{
get => _levelOverridePolicy;
set
{
_levelOverridePolicy = value;
NotifyPropertyListChanged();
}
}
[Export]
public StackLevelOverrideStackCountPolicy LevelOverrideStackCountPolicy { get; set; }
[Export]
public StackMagnitudePolicy MagnitudePolicy { get; set; }
[Export]
public StackOverflowPolicy OverflowPolicy { get; set; }
[Export]
public StackExpirationPolicy ExpirationPolicy { get; set; }
[Export]
[ExportSubgroup("Has Duration")]
public StackApplicationRefreshPolicy ApplicationRefreshPolicy { get; set; }
[Export]
[ExportSubgroup("Periodic Effects")]
public StackApplicationResetPeriodPolicy ApplicationResetPeriodPolicy { get; set; }
[Export]
public bool ExecuteOnSuccessfulApplication { get; set; }
[ExportGroup("Cues")]
[Export(PropertyHint.ResourceType, "ForgeCue")]
public Array<ForgeCue>? Cues { get; set; }
[Export]
public CueTriggerRequirement RequireModifierSuccessToTriggerCue { get; set; }
[Export]
public bool SuppressStackingCues { get; set; }
public EffectData GetEffectData()
{
if (_data.HasValue)
{
return _data.Value;
}
Modifiers ??= [];
Components ??= [];
Executions ??= [];
Cues ??= [];
var modifiers = new List<Modifier>();
foreach (ForgeModifier modifier in Modifiers)
{
modifiers.Add(modifier.GetModifier());
}
var components = new List<IEffectComponent>();
foreach (ForgeEffectComponent component in Components)
{
components.Add(component.GetComponent());
}
var executions = new List<CustomExecution>();
foreach (ForgeCustomExecution execution in Executions)
{
executions.Add(execution.GetExecutionClass());
}
var cues = new List<CueData>();
foreach (ForgeCue cue in Cues)
{
cues.Add(cue.GetCueData());
}
Debug.Assert(Name is not null, $"{nameof(Duration)} is not set.");
_data = new EffectData(
Name,
GetDurationData(),
[.. modifiers],
GetStackingData(),
GetPeriodicData(),
SnapshotLevel,
[.. components],
RequireModifierSuccessToTriggerCue,
SuppressStackingCues,
[.. executions],
[.. cues]);
return _data.Value;
}
#if TOOLS
public override void _ValidateProperty(Dictionary property)
{
if (property["name"].AsStringName() == PropertyName.SnapshotLevel)
{
if (DurationType == DurationType.Instant)
{
property["usage"] = (int)(PropertyUsageFlags.Default | PropertyUsageFlags.ReadOnly);
SnapshotLevel = true;
}
// This is used to sure Modifiers are set as snapshot for instant effects.
if (Modifiers is not null)
{
foreach (ForgeModifier modifier in Modifiers)
{
modifier.IsInstantEffect = DurationType == DurationType.Instant;
}
}
}
if (property["name"].AsStringName() == PropertyName.Duration && DurationType != DurationType.HasDuration)
{
property["usage"] = (int)(PropertyUsageFlags.Default | PropertyUsageFlags.ReadOnly);
}
if (DurationType == DurationType.Instant
&& property["name"].AsStringName() == PropertyName.HasPeriodicApplication)
{
property["usage"] = (int)(PropertyUsageFlags.Default | PropertyUsageFlags.ReadOnly);
}
if (!HasPeriodicApplication
&& (property["name"].AsStringName() == PropertyName.Period ||
property["name"].AsStringName() == PropertyName.ExecuteOnApplication ||
property["name"].AsStringName() == PropertyName.ApplicationResetPeriodPolicy ||
property["name"].AsStringName() == PropertyName.ExecuteOnSuccessfulApplication))
{
property["usage"] = (int)(PropertyUsageFlags.Default | PropertyUsageFlags.ReadOnly);
}
if ((DurationType == DurationType.Instant || !CanStack)
&& (property["name"].AsStringName() == PropertyName.StackLimit ||
property["name"].AsStringName() == PropertyName.InitialStack ||
property["name"].AsStringName() == PropertyName.SourcePolicy ||
property["name"].AsStringName() == PropertyName.InstigatorDenialPolicy ||
property["name"].AsStringName() == PropertyName.InstigatorOverridePolicy ||
property["name"].AsStringName() == PropertyName.InstigatorOverrideStackCountPolicy ||
property["name"].AsStringName() == PropertyName.LevelPolicy ||
property["name"].AsStringName() == PropertyName.LevelDenialPolicy ||
property["name"].AsStringName() == PropertyName.LevelOverridePolicy ||
property["name"].AsStringName() == PropertyName.LevelOverrideStackCountPolicy ||
property["name"].AsStringName() == PropertyName.MagnitudePolicy ||
property["name"].AsStringName() == PropertyName.OverflowPolicy ||
property["name"].AsStringName() == PropertyName.ExpirationPolicy ||
property["name"].AsStringName() == PropertyName.ApplicationRefreshPolicy ||
property["name"].AsStringName() == PropertyName.ApplicationResetPeriodPolicy ||
property["name"].AsStringName() == PropertyName.ExecuteOnSuccessfulApplication))
{
property["usage"] = (int)(PropertyUsageFlags.Default | PropertyUsageFlags.ReadOnly);
}
if (SourcePolicy == StackPolicy.AggregateBySource
&& (property["name"].AsStringName() == PropertyName.InstigatorDenialPolicy ||
property["name"].AsStringName() == PropertyName.InstigatorOverridePolicy ||
property["name"].AsStringName() == PropertyName.InstigatorOverrideStackCountPolicy))
{
property["usage"] = (int)(PropertyUsageFlags.Default | PropertyUsageFlags.ReadOnly);
}
if (InstigatorOverridePolicy != StackOwnerOverridePolicy.Override
&& property["name"].AsStringName() == PropertyName.InstigatorOverrideStackCountPolicy)
{
property["usage"] = (int)(PropertyUsageFlags.Default | PropertyUsageFlags.ReadOnly);
}
if (LevelPolicy == StackLevelPolicy.SegregateLevels
&& (property["name"].AsStringName() == PropertyName.LevelDenialPolicy ||
property["name"].AsStringName() == PropertyName.LevelOverridePolicy ||
property["name"].AsStringName() == PropertyName.LevelOverrideStackCountPolicy))
{
property["usage"] = (int)(PropertyUsageFlags.Default | PropertyUsageFlags.ReadOnly);
}
if (LevelOverridePolicy == 0 && property["name"].AsStringName() == PropertyName.LevelOverrideStackCountPolicy)
{
property["usage"] = (int)(PropertyUsageFlags.Default | PropertyUsageFlags.ReadOnly);
}
if (DurationType != DurationType.HasDuration &&
property["name"].AsStringName() == PropertyName.ApplicationRefreshPolicy)
{
property["usage"] = (int)(PropertyUsageFlags.Default | PropertyUsageFlags.ReadOnly);
}
}
#endif
private DurationData GetDurationData()
{
return new DurationData(DurationType, GetDurationModifier());
}
private ModifierMagnitude? GetDurationModifier()
{
if (DurationType != DurationType.HasDuration)
{
return null;
}
Debug.Assert(Duration is not null, $"{nameof(Duration)} reference is missing.");
return Duration.GetModifier();
}
private StackingData? GetStackingData()
{
if (!CanStack)
{
return null;
}
return new StackingData(
StackLimit.GetScalableInt(),
InitialStack.GetScalableInt(),
SourcePolicy,
LevelPolicy,
MagnitudePolicy,
OverflowPolicy,
ExpirationPolicy,
GetOwnerDenialPolicy(),
GetOwnerOverridePolicy(),
GetOwnerOverrideStackCountPolicy(),
GetLevelDenialPolicy(),
GetLevelOverridePolicy(),
GetLevelOverrideStackCountPolicy(),
GetApplicationRefreshPolicy(),
GetApplicationResetPeriodPolicy(),
GetExecuteOnSuccessfulApplication());
}
private StackOwnerDenialPolicy? GetOwnerDenialPolicy()
{
if (SourcePolicy != StackPolicy.AggregateByTarget)
{
return null;
}
return InstigatorDenialPolicy;
}
private StackOwnerOverridePolicy? GetOwnerOverridePolicy()
{
if (SourcePolicy != StackPolicy.AggregateByTarget)
{
return null;
}
return InstigatorOverridePolicy;
}
private StackOwnerOverrideStackCountPolicy? GetOwnerOverrideStackCountPolicy()
{
if (SourcePolicy != StackPolicy.AggregateByTarget ||
InstigatorOverridePolicy != StackOwnerOverridePolicy.Override)
{
return null;
}
return InstigatorOverrideStackCountPolicy;
}
private LevelComparison? GetLevelDenialPolicy()
{
if (LevelPolicy != StackLevelPolicy.AggregateLevels)
{
return null;
}
return LevelDenialPolicy;
}
private LevelComparison? GetLevelOverridePolicy()
{
if (LevelPolicy != StackLevelPolicy.AggregateLevels)
{
return null;
}
return LevelOverridePolicy;
}
private StackLevelOverrideStackCountPolicy? GetLevelOverrideStackCountPolicy()
{
if (LevelPolicy != StackLevelPolicy.AggregateLevels ||
LevelOverridePolicy == 0)
{
return null;
}
return LevelOverrideStackCountPolicy;
}
private StackApplicationRefreshPolicy? GetApplicationRefreshPolicy()
{
if (DurationType != DurationType.HasDuration)
{
return null;
}
return ApplicationRefreshPolicy;
}
private StackApplicationResetPeriodPolicy? GetApplicationResetPeriodPolicy()
{
if (!HasPeriodicApplication)
{
return null;
}
return ApplicationResetPeriodPolicy;
}
private bool? GetExecuteOnSuccessfulApplication()
{
if (!HasPeriodicApplication)
{
return null;
}
return ExecuteOnSuccessfulApplication;
}
private PeriodicData? GetPeriodicData()
{
if (!HasPeriodicApplication)
{
return null;
}
Debug.Assert(Period is not null, $"{nameof(Period)} reference is missing.");
return new PeriodicData(
Period.GetScalableFloat(),
ExecuteOnApplication,
PeriodInhibitionRemovedPolicy.NeverReset);
}
}

View File

@@ -0,0 +1 @@
uid://b83hf13nj37k3

View File

@@ -0,0 +1,230 @@
// Copyright © Gamesmiths Guild.
using System.Diagnostics;
using Gamesmiths.Forge.Effects.Magnitudes;
using Gamesmiths.Forge.Effects.Modifiers;
using Gamesmiths.Forge.Godot.Resources.Calculators;
using Gamesmiths.Forge.Godot.Resources.Magnitudes;
using Godot;
using Godot.Collections;
namespace Gamesmiths.Forge.Godot.Resources;
[Tool]
[GlobalClass]
[Icon("uid://bbwv58ku4cv0i")]
public partial class ForgeModifier : Resource
{
private MagnitudeCalculationType _calculationType;
private AttributeCalculationType _attributeCalculationType;
[ExportGroup("Target Attribute")]
[Export]
public string? Attribute { get; set; }
[Export]
public ModifierOperation Operation { get; set; }
[Export]
public int Channel { get; set; }
[ExportGroup("Magnitude")]
[Export]
public MagnitudeCalculationType CalculationType
{
get => _calculationType;
set
{
_calculationType = value;
NotifyPropertyListChanged();
}
}
[ExportGroup("Scalable Float")]
[Export]
public ForgeScalableFloat? ScalableFloat { get; set; }
[ExportGroup("Attribute Based")]
[Export]
public string? CapturedAttribute { get; set; }
[ExportSubgroup("Attribute Based Capture Definition")]
[Export]
public AttributeCaptureSource CaptureSource { get; set; }
[Export]
public bool SnapshotAttribute { get; set; } = true;
[ExportSubgroup("Attribute Based Calculation")]
[Export]
public AttributeCalculationType AttributeCalculationType
{
get => _attributeCalculationType;
set
{
_attributeCalculationType = value;
NotifyPropertyListChanged();
}
}
[Export]
public ForgeScalableFloat Coefficient { get; set; } = new(1);
[Export]
public ForgeScalableFloat PreMultiplyAdditiveValue { get; set; } = new(0);
[Export]
public ForgeScalableFloat PostMultiplyAdditiveValue { get; set; } = new(0);
[Export]
public int FinalChannel { get; set; }
[ExportGroup("Custom Calculator Class")]
[Export]
public ForgeCustomCalculator? CustomCalculatorClass { get; set; }
[Export]
public ForgeScalableFloat CalculatorCoefficient { get; set; } = new(1);
[Export]
public ForgeScalableFloat CalculatorPreMultiplyAdditiveValue { get; set; } = new(0);
[Export]
public ForgeScalableFloat CalculatorPostMultiplyAdditiveValue { get; set; } = new(0);
[ExportGroup("Set by Caller Float")]
[Export]
public ForgeTag? CallerTargetTag { get; set; }
#if TOOLS
public bool IsInstantEffect { get; set; }
#endif
public Modifier GetModifier()
{
Debug.Assert(Attribute is not null, $"{nameof(Attribute)} reference is missing.");
return new Modifier(
Attribute,
Operation,
new ModifierMagnitude(
CalculationType,
GetScalableFloatMagnitude(),
GetAttributeBasedFloat(),
GetCustomCalculationBasedFloat(),
GetSetByCallerFloat()),
Channel);
}
#if TOOLS
public override void _ValidateProperty(Dictionary property)
{
if (property["name"].AsStringName() == PropertyName.ScalableFloat
&& CalculationType != MagnitudeCalculationType.ScalableFloat)
{
property["usage"] = (int)PropertyUsageFlags.NoEditor;
}
if (CalculationType != MagnitudeCalculationType.AttributeBased
&& (property["name"].AsStringName() == PropertyName.CapturedAttribute ||
property["name"].AsStringName() == PropertyName.CaptureSource ||
property["name"].AsStringName() == PropertyName.SnapshotAttribute ||
property["name"].AsStringName() == PropertyName.AttributeCalculationType ||
property["name"].AsStringName() == PropertyName.Coefficient ||
property["name"].AsStringName() == PropertyName.PreMultiplyAdditiveValue ||
property["name"].AsStringName() == PropertyName.PostMultiplyAdditiveValue ||
property["name"].AsStringName() == PropertyName.FinalChannel))
{
property["usage"] = (int)PropertyUsageFlags.NoEditor;
}
else if (property["name"].AsStringName() == PropertyName.SnapshotAttribute && IsInstantEffect)
{
property["usage"] = (int)(PropertyUsageFlags.Default | PropertyUsageFlags.ReadOnly);
SnapshotAttribute = true;
}
if (property["name"].AsStringName() == PropertyName.FinalChannel &&
AttributeCalculationType != AttributeCalculationType.MagnitudeEvaluatedUpToChannel)
{
property["usage"] = (int)PropertyUsageFlags.NoEditor;
}
if (CalculationType != MagnitudeCalculationType.CustomCalculatorClass
&& (property["name"].AsStringName() == PropertyName.CustomCalculatorClass ||
property["name"].AsStringName() == PropertyName.CalculatorCoefficient ||
property["name"].AsStringName() == PropertyName.CalculatorPreMultiplyAdditiveValue ||
property["name"].AsStringName() == PropertyName.CalculatorPostMultiplyAdditiveValue))
{
property["usage"] = (int)PropertyUsageFlags.NoEditor;
}
if (CalculationType != MagnitudeCalculationType.SetByCaller
&& (property["name"].AsStringName() == PropertyName.CallerTargetTag))
{
property["usage"] = (int)PropertyUsageFlags.NoEditor;
}
}
#endif
private ScalableFloat? GetScalableFloatMagnitude()
{
if (CalculationType != MagnitudeCalculationType.ScalableFloat)
{
return null;
}
Debug.Assert(ScalableFloat is not null, $"{nameof(ScalableFloat)} reference is missing.");
return ScalableFloat.GetScalableFloat();
}
private AttributeBasedFloat? GetAttributeBasedFloat()
{
if (CalculationType != MagnitudeCalculationType.AttributeBased)
{
return null;
}
Debug.Assert(CapturedAttribute is not null, $"{nameof(CapturedAttribute)} reference is missing.");
return new AttributeBasedFloat(
new AttributeCaptureDefinition(
CapturedAttribute,
CaptureSource,
SnapshotAttribute),
AttributeCalculationType,
Coefficient.GetScalableFloat(),
PreMultiplyAdditiveValue.GetScalableFloat(),
PostMultiplyAdditiveValue.GetScalableFloat(),
FinalChannel);
}
private CustomCalculationBasedFloat? GetCustomCalculationBasedFloat()
{
if (CalculationType != MagnitudeCalculationType.CustomCalculatorClass)
{
return null;
}
Debug.Assert(CustomCalculatorClass is not null, $"{nameof(CustomCalculatorClass)} reference is missing.");
return new CustomCalculationBasedFloat(
CustomCalculatorClass.GetCustomCalculatorClass(),
CalculatorCoefficient.GetScalableFloat(),
CalculatorPreMultiplyAdditiveValue.GetScalableFloat(),
CalculatorPostMultiplyAdditiveValue.GetScalableFloat(),
null);
}
private SetByCallerFloat? GetSetByCallerFloat()
{
if (CalculationType != MagnitudeCalculationType.SetByCaller)
{
return null;
}
return new SetByCallerFloat(CallerTargetTag!.GetTag());
}
}

View File

@@ -0,0 +1 @@
uid://bdfcavbjyhxxa

View File

@@ -0,0 +1,126 @@
// Copyright © Gamesmiths Guild.
using System.Diagnostics;
using Gamesmiths.Forge.Godot.Core;
using Gamesmiths.Forge.Tags;
using Godot;
using Godot.Collections;
namespace Gamesmiths.Forge.Godot.Resources;
[Tool]
[GlobalClass]
[Icon("uid://dscm401i41h52")]
public partial class QueryExpression : Resource
{
private TagQueryExpressionType _expressionType;
[Export]
public TagQueryExpressionType ExpressionType
{
get => _expressionType;
set
{
_expressionType = value;
NotifyPropertyListChanged();
}
}
[Export]
public Array<QueryExpression>? Expressions { get; set; }
[Export]
public ForgeTagContainer? TagContainer { get; set; }
public override void _ValidateProperty(Dictionary property)
{
if ((ExpressionType == TagQueryExpressionType.Undefined || IsExpressionType())
&& property["name"].AsStringName() == PropertyName.TagContainer)
{
property["usage"] = (int)PropertyUsageFlags.NoEditor;
}
if ((ExpressionType == TagQueryExpressionType.Undefined || !IsExpressionType())
&& property["name"].AsStringName() == PropertyName.Expressions)
{
property["usage"] = (int)PropertyUsageFlags.NoEditor;
}
}
public bool IsExpressionType()
{
return ExpressionType == TagQueryExpressionType.AnyExpressionsMatch
|| ExpressionType == TagQueryExpressionType.AllExpressionsMatch
|| ExpressionType == TagQueryExpressionType.NoExpressionsMatch;
}
public TagQueryExpression GetQueryExpression()
{
TagContainer ??= new();
var expression = new TagQueryExpression(ForgeManagers.Instance.TagsManager);
switch (_expressionType)
{
case TagQueryExpressionType.AnyExpressionsMatch:
expression = expression.AnyExpressionsMatch();
AddExpressions(expression);
break;
case TagQueryExpressionType.AllExpressionsMatch:
expression = expression.AllExpressionsMatch();
AddExpressions(expression);
break;
case TagQueryExpressionType.NoExpressionsMatch:
expression = expression.NoExpressionsMatch();
AddExpressions(expression);
break;
case TagQueryExpressionType.AnyTagsMatch:
expression = expression.AnyTagsMatch();
expression.AddTags(TagContainer.GetTagContainer());
break;
case TagQueryExpressionType.AllTagsMatch:
expression = expression.AllTagsMatch();
expression.AddTags(TagContainer.GetTagContainer());
break;
case TagQueryExpressionType.NoTagsMatch:
expression = expression.NoTagsMatch();
expression.AddTags(TagContainer.GetTagContainer());
break;
case TagQueryExpressionType.AnyTagsMatchExact:
expression = expression.AnyTagsMatchExact();
expression.AddTags(TagContainer.GetTagContainer());
break;
case TagQueryExpressionType.AllTagsMatchExact:
expression = expression.AllTagsMatchExact();
expression.AddTags(TagContainer.GetTagContainer());
break;
case TagQueryExpressionType.NoTagsMatchExact:
expression = expression.NoTagsMatchExact();
expression.AddTags(TagContainer.GetTagContainer());
break;
}
return expression;
}
private void AddExpressions(TagQueryExpression expression)
{
Debug.Assert(
Expressions is not null,
$"{nameof(Expressions)} reference is missing.");
foreach (QueryExpression innerExpression in Expressions)
{
expression.AddExpression(innerExpression.GetQueryExpression());
}
}
}

View File

@@ -0,0 +1 @@
uid://2v5alkmjnjhy

View File

@@ -0,0 +1,21 @@
// Copyright © Gamesmiths Guild.
using Gamesmiths.Forge.Godot.Core;
using Gamesmiths.Forge.Tags;
using Godot;
namespace Gamesmiths.Forge.Godot.Resources;
[Tool]
[GlobalClass]
[Icon("uid://vsfdeevye6jm")]
public partial class ForgeTag : Resource
{
[Export]
public required string Tag { get; set; }
public Tag GetTag()
{
return Tags.Tag.RequestTag(ForgeManagers.Instance.TagsManager, Tag);
}
}

View File

@@ -0,0 +1 @@
uid://dpakv7agvir6y

View File

@@ -0,0 +1,42 @@
// Copyright © Gamesmiths Guild.
using System.Collections.Generic;
using Gamesmiths.Forge.Godot.Core;
using Gamesmiths.Forge.Tags;
using Godot;
using Godot.Collections;
namespace Gamesmiths.Forge.Godot.Resources;
[Tool]
[GlobalClass]
[Icon("uid://ddeg62ps243fn")]
public partial class ForgeTagContainer : Resource
{
[Export]
public Array<string>? ContainerTags { get; set; }
public TagContainer GetTagContainer()
{
if (ContainerTags is null)
{
return new TagContainer(ForgeManagers.Instance.TagsManager);
}
var tags = new HashSet<Tag>();
foreach (var tag in ContainerTags)
{
try
{
tags.Add(Tag.RequestTag(ForgeManagers.Instance.TagsManager, tag));
}
catch (TagNotRegisteredException)
{
GD.PushWarning($"Tag [{tag}] is not registered.");
}
}
return new TagContainer(ForgeManagers.Instance.TagsManager, tags);
}
}

View File

@@ -0,0 +1 @@
uid://cw525n4mjqgw0

View File

@@ -0,0 +1,14 @@
// Copyright © Gamesmiths Guild.
using Gamesmiths.Forge.Abilities;
using Godot;
namespace Gamesmiths.Forge.Godot.Resources.Abilities;
[Tool]
[GlobalClass]
[Icon("uid://bcx7anhepqfmd")]
public abstract partial class ForgeAbilityBehavior : Resource
{
public abstract IAbilityBehavior GetBehavior();
}

View File

@@ -0,0 +1 @@
uid://bc4as0wtj8mve

View File

@@ -0,0 +1,180 @@
// 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;
}
}
}

View File

@@ -0,0 +1 @@
uid://dhxfbxh54pyxp

View File

@@ -0,0 +1,26 @@
// Copyright © Gamesmiths Guild.
namespace Gamesmiths.Forge.Godot.Resources.Abilities;
public enum TriggerSource
{
/// <summary>
/// No trigger source specified.
/// </summary>
None = 0,
/// <summary>
/// Triggered by an event.
/// </summary>
Event = 1,
/// <summary>
/// Triggered when a tag is added.
/// </summary>
TagAdded = 2,
/// <summary>
/// Triggered when a tag is present and removed when tag is gone.
/// </summary>
TagPresent = 3,
}

View File

@@ -0,0 +1 @@
uid://d3lbq2rw5iixv

View File

@@ -0,0 +1,14 @@
// Copyright © Gamesmiths Guild.
using Gamesmiths.Forge.Effects.Calculator;
using Godot;
namespace Gamesmiths.Forge.Godot.Resources.Calculators;
[Tool]
[GlobalClass]
[Icon("uid://b3mnlhfvbttw0")]
public abstract partial class ForgeCustomCalculator : Resource
{
public abstract CustomModifierMagnitudeCalculator GetCustomCalculatorClass();
}

View File

@@ -0,0 +1 @@
uid://con2lyo7d2slo

View File

@@ -0,0 +1,14 @@
// Copyright © Gamesmiths Guild.
using Gamesmiths.Forge.Effects.Calculator;
using Godot;
namespace Gamesmiths.Forge.Godot.Resources.Calculators;
[Tool]
[GlobalClass]
[Icon("uid://dy874wbbpsewt")]
public abstract partial class ForgeCustomExecution : Resource
{
public abstract CustomExecution GetExecutionClass();
}

View File

@@ -0,0 +1 @@
uid://8vdy1awpc2a4

View File

@@ -0,0 +1,21 @@
// Copyright © Gamesmiths Guild.
using Gamesmiths.Forge.Effects.Components;
using Gamesmiths.Forge.Godot.Core;
using Gamesmiths.Forge.Godot.Resources.Magnitudes;
using Godot;
namespace Gamesmiths.Forge.Godot.Resources.Components;
[Tool]
[GlobalClass]
public partial class ChanceToApplyEffect : ForgeEffectComponent
{
[Export]
public ForgeScalableFloat Chance { get; set; } = new(1);
public override IEffectComponent GetComponent()
{
return new ChanceToApplyEffectComponent(new ForgeRandom(), Chance.GetScalableFloat());
}
}

View File

@@ -0,0 +1 @@
uid://c10ov6sgvcunw

View File

@@ -0,0 +1,14 @@
// Copyright © Gamesmiths Guild.
using Gamesmiths.Forge.Effects.Components;
using Godot;
namespace Gamesmiths.Forge.Godot.Resources.Components;
[Tool]
[GlobalClass]
[Icon("uid://bcx7anhepqfmd")]
public abstract partial class ForgeEffectComponent : Resource
{
public abstract IEffectComponent GetComponent();
}

View File

@@ -0,0 +1 @@
uid://cpcrmq51kgbpu

View File

@@ -0,0 +1,51 @@
// Copyright © Gamesmiths Guild.
using System.Diagnostics;
using Gamesmiths.Forge.Abilities;
using Gamesmiths.Forge.Core;
using Gamesmiths.Forge.Effects.Components;
using Gamesmiths.Forge.Godot.Resources.Abilities;
using Gamesmiths.Forge.Godot.Resources.Magnitudes;
using Godot;
namespace ForgeGodot.Addons.Forge.Resources.Components;
[Tool]
[GlobalClass]
public partial class ForgeGrantAbilityConfig : Resource
{
[Export]
public ForgeAbilityData? AbilityData { get; set; }
[Export]
public ForgeScalableInt AbilityLevel { get; set; } = new(1);
[Export]
public AbilityDeactivationPolicy RemovalPolicy { get; set; } = AbilityDeactivationPolicy.CancelImmediately;
[Export]
public AbilityDeactivationPolicy InhibitionPolicy { get; set; } = AbilityDeactivationPolicy.CancelImmediately;
[Export]
public bool TryActivateOnGrant { get; set; }
[Export]
public bool TryActivateOnEnable { get; set; }
[Export]
public LevelComparison LevelOverridePolicy { get; set; } = LevelComparison.None;
public GrantAbilityConfig GetGrantAbilityConfig()
{
Debug.Assert(AbilityData is not null, $"{nameof(AbilityData)} reference is missing.");
return new GrantAbilityConfig(
AbilityData.GetAbilityData(),
AbilityLevel.GetScalableInt(),
RemovalPolicy,
InhibitionPolicy,
TryActivateOnGrant,
TryActivateOnEnable,
LevelOverridePolicy);
}
}

View File

@@ -0,0 +1 @@
uid://72kj3n4lm1em

View File

@@ -0,0 +1 @@
uid://b665wpo0okpml

View File

@@ -0,0 +1,28 @@
// Copyright © Gamesmiths Guild.
using System.Collections.Generic;
using ForgeGodot.Addons.Forge.Resources.Components;
using Gamesmiths.Forge.Effects.Components;
using Godot;
namespace Gamesmiths.Forge.Godot.Resources.Components;
[Tool]
[GlobalClass]
public partial class GrantAbility : ForgeEffectComponent
{
[Export]
public ForgeGrantAbilityConfig[] GrantAbilityConfigs { get; set; } = [];
public override IEffectComponent GetComponent()
{
List<GrantAbilityConfig> configs = [];
foreach (ForgeGrantAbilityConfig config in GrantAbilityConfigs)
{
configs.Add(config.GetGrantAbilityConfig());
}
return new GrantAbilityEffectComponent([.. configs]);
}
}

View File

@@ -0,0 +1 @@
uid://b3wo2uge4ddnj

View File

@@ -0,0 +1,21 @@
// Copyright © Gamesmiths Guild.
using Gamesmiths.Forge.Effects.Components;
using Godot;
namespace Gamesmiths.Forge.Godot.Resources.Components;
[Tool]
[GlobalClass]
public partial class ModifierTags : ForgeEffectComponent
{
[Export]
public ForgeTagContainer? TagsToAdd { get; set; }
public override IEffectComponent GetComponent()
{
TagsToAdd ??= new();
return new ModifierTagsEffectComponent(TagsToAdd.GetTagContainer());
}
}

View File

@@ -0,0 +1 @@
uid://dngf30hxy5go4

View File

@@ -0,0 +1,84 @@
// Copyright © Gamesmiths Guild.
using Gamesmiths.Forge.Effects.Components;
using Gamesmiths.Forge.Tags;
using Godot;
namespace Gamesmiths.Forge.Godot.Resources.Components;
[Tool]
[GlobalClass]
public partial class TargetTagRequirements : ForgeEffectComponent
{
[ExportGroup("Application Requirements")]
[Export]
public ForgeTagContainer? ApplicationRequiredTags { get; set; }
[Export]
public ForgeTagContainer? ApplicationIgnoredTags { get; set; }
[Export]
public QueryExpression? ApplicationTagQuery { get; set; }
[ExportGroup("Removal Requirements")]
[Export]
public ForgeTagContainer? RemovalRequiredTags { get; set; }
[Export]
public ForgeTagContainer? RemovalIgnoredTags { get; set; }
[Export]
public QueryExpression? RemovalTagQuery { get; set; }
[ExportGroup("Ongoing Requirements")]
[Export]
public ForgeTagContainer? OngoingRequiredTags { get; set; }
[Export]
public ForgeTagContainer? OngoingIgnoredTags { get; set; }
[Export]
public QueryExpression? OngoingTagQuery { get; set; }
public override IEffectComponent GetComponent()
{
ApplicationRequiredTags ??= new();
ApplicationIgnoredTags ??= new();
RemovalRequiredTags ??= new();
RemovalIgnoredTags ??= new();
OngoingRequiredTags ??= new();
OngoingIgnoredTags ??= new();
var applicationQuery = new TagQuery();
if (ApplicationTagQuery is not null)
{
applicationQuery.Build(ApplicationTagQuery.GetQueryExpression());
}
var removalQuery = new TagQuery();
if (RemovalTagQuery is not null)
{
removalQuery.Build(RemovalTagQuery.GetQueryExpression());
}
var ongoingQuery = new TagQuery();
if (OngoingTagQuery is not null)
{
ongoingQuery.Build(OngoingTagQuery.GetQueryExpression());
}
return new TargetTagRequirementsEffectComponent(
new TagRequirements(
ApplicationRequiredTags.GetTagContainer(),
ApplicationIgnoredTags.GetTagContainer(),
applicationQuery),
new TagRequirements(
RemovalRequiredTags.GetTagContainer(),
RemovalIgnoredTags.GetTagContainer(),
removalQuery),
new TagRequirements(
OngoingRequiredTags.GetTagContainer(),
OngoingIgnoredTags.GetTagContainer(),
ongoingQuery));
}
}

View File

@@ -0,0 +1 @@
uid://b0eq12mjqfage

View File

@@ -0,0 +1,212 @@
// Copyright © Gamesmiths Guild.
using System.Diagnostics;
using Gamesmiths.Forge.Effects.Magnitudes;
using Gamesmiths.Forge.Godot.Resources.Calculators;
using Gamesmiths.Forge.Godot.Resources.Magnitudes;
using Godot;
using Godot.Collections;
namespace Gamesmiths.Forge.Godot.Resources;
[Tool]
[GlobalClass]
[Icon("uid://cesj1p71jsco5")]
public partial class ForgeModifierMagnitude : Resource
{
private MagnitudeCalculationType _calculationType;
private AttributeCalculationType _attributeCalculationType;
[Export]
public MagnitudeCalculationType CalculationType
{
get => _calculationType;
set
{
_calculationType = value;
NotifyPropertyListChanged();
}
}
[ExportGroup("Scalable Float")]
[Export]
public ForgeScalableFloat? ScalableFloat { get; set; }
[ExportGroup("Attribute Based")]
[Export]
public string? CapturedAttribute { get; set; }
[ExportSubgroup("Attribute Based Capture Definition")]
[Export]
public AttributeCaptureSource CaptureSource { get; set; }
[Export]
public bool SnapshotAttribute { get; set; } = true;
[ExportSubgroup("Attribute Based Calculation")]
[Export]
public AttributeCalculationType AttributeCalculationType
{
get => _attributeCalculationType;
set
{
_attributeCalculationType = value;
NotifyPropertyListChanged();
}
}
[Export]
public ForgeScalableFloat Coefficient { get; set; } = new(1);
[Export]
public ForgeScalableFloat PreMultiplyAdditiveValue { get; set; } = new(0);
[Export]
public ForgeScalableFloat PostMultiplyAdditiveValue { get; set; } = new(0);
[Export]
public int FinalChannel { get; set; }
[ExportGroup("Custom Calculator Class")]
[Export]
public ForgeCustomCalculator? CustomCalculatorClass { get; set; }
[Export]
public ForgeScalableFloat CalculatorCoefficient { get; set; } = new(1);
[Export]
public ForgeScalableFloat CalculatorPreMultiplyAdditiveValue { get; set; } = new(0);
[Export]
public ForgeScalableFloat CalculatorPostMultiplyAdditiveValue { get; set; } = new(0);
[ExportGroup("Set by Caller Float")]
[Export]
public ForgeTag? CallerTargetTag { get; set; }
#if TOOLS
public bool IsInstantEffect { get; set; }
#endif
public ModifierMagnitude GetModifier()
{
return new ModifierMagnitude(
CalculationType,
GetScalableFloatMagnitude(),
GetAttributeBasedFloat(),
GetCustomCalculationBasedFloat(),
GetSetByCallerFloat());
}
#if TOOLS
public override void _ValidateProperty(Dictionary property)
{
if (property["name"].AsStringName() == PropertyName.ScalableFloat
&& CalculationType != MagnitudeCalculationType.ScalableFloat)
{
property["usage"] = (int)PropertyUsageFlags.NoEditor;
}
if (CalculationType != MagnitudeCalculationType.AttributeBased
&& (property["name"].AsStringName() == PropertyName.CapturedAttribute ||
property["name"].AsStringName() == PropertyName.CaptureSource ||
property["name"].AsStringName() == PropertyName.SnapshotAttribute ||
property["name"].AsStringName() == PropertyName.AttributeCalculationType ||
property["name"].AsStringName() == PropertyName.Coefficient ||
property["name"].AsStringName() == PropertyName.PreMultiplyAdditiveValue ||
property["name"].AsStringName() == PropertyName.PostMultiplyAdditiveValue ||
property["name"].AsStringName() == PropertyName.FinalChannel))
{
property["usage"] = (int)PropertyUsageFlags.NoEditor;
}
else if (property["name"].AsStringName() == PropertyName.SnapshotAttribute && IsInstantEffect)
{
property["usage"] = (int)(PropertyUsageFlags.Default | PropertyUsageFlags.ReadOnly);
SnapshotAttribute = true;
}
if (property["name"].AsStringName() == PropertyName.FinalChannel &&
AttributeCalculationType != AttributeCalculationType.MagnitudeEvaluatedUpToChannel)
{
property["usage"] = (int)PropertyUsageFlags.NoEditor;
}
if (CalculationType != MagnitudeCalculationType.CustomCalculatorClass
&& (property["name"].AsStringName() == PropertyName.CustomCalculatorClass ||
property["name"].AsStringName() == PropertyName.CalculatorCoefficient ||
property["name"].AsStringName() == PropertyName.CalculatorPreMultiplyAdditiveValue ||
property["name"].AsStringName() == PropertyName.CalculatorPostMultiplyAdditiveValue))
{
property["usage"] = (int)PropertyUsageFlags.NoEditor;
}
if (CalculationType != MagnitudeCalculationType.SetByCaller
&& (property["name"].AsStringName() == PropertyName.CallerTargetTag))
{
property["usage"] = (int)PropertyUsageFlags.NoEditor;
}
}
#endif
private ScalableFloat? GetScalableFloatMagnitude()
{
if (CalculationType != MagnitudeCalculationType.ScalableFloat)
{
return null;
}
Debug.Assert(ScalableFloat is not null, $"{nameof(ScalableFloat)} reference is missing.");
return ScalableFloat.GetScalableFloat();
}
private AttributeBasedFloat? GetAttributeBasedFloat()
{
if (CalculationType != MagnitudeCalculationType.AttributeBased)
{
return null;
}
Debug.Assert(CapturedAttribute is not null, $"{nameof(CapturedAttribute)} reference is missing.");
return new AttributeBasedFloat(
new AttributeCaptureDefinition(
CapturedAttribute,
CaptureSource,
SnapshotAttribute),
AttributeCalculationType,
Coefficient.GetScalableFloat(),
PreMultiplyAdditiveValue.GetScalableFloat(),
PostMultiplyAdditiveValue.GetScalableFloat(),
FinalChannel);
}
private CustomCalculationBasedFloat? GetCustomCalculationBasedFloat()
{
if (CalculationType != MagnitudeCalculationType.CustomCalculatorClass)
{
return null;
}
Debug.Assert(CustomCalculatorClass is not null, $"{nameof(CustomCalculatorClass)} reference is missing.");
return new CustomCalculationBasedFloat(
CustomCalculatorClass.GetCustomCalculatorClass(),
CalculatorCoefficient.GetScalableFloat(),
CalculatorPreMultiplyAdditiveValue.GetScalableFloat(),
CalculatorPostMultiplyAdditiveValue.GetScalableFloat(),
null);
}
private SetByCallerFloat? GetSetByCallerFloat()
{
if (CalculationType != MagnitudeCalculationType.SetByCaller)
{
return null;
}
return new SetByCallerFloat(CallerTargetTag!.GetTag());
}
}

View File

@@ -0,0 +1 @@
uid://2gm1hdhi8u08

View File

@@ -0,0 +1,34 @@
// Copyright © Gamesmiths Guild.
using Gamesmiths.Forge.Effects.Magnitudes;
using Gamesmiths.Forge.Godot.Core;
using Godot;
namespace Gamesmiths.Forge.Godot.Resources.Magnitudes;
[Tool]
[GlobalClass]
[Icon("uid://dvlaw4yolashm")]
public partial class ForgeScalableFloat : Resource
{
[Export]
public float BaseValue { get; set; }
[Export]
public Curve? ScalingCurve { get; set; }
public ForgeScalableFloat()
{
// Constructor intentionally left blank.
}
public ForgeScalableFloat(float baseValue)
{
BaseValue = baseValue;
}
public ScalableFloat GetScalableFloat()
{
return new ScalableFloat(BaseValue, new ForgeCurve(ScalingCurve));
}
}

View File

@@ -0,0 +1 @@
uid://cn3b4ya15fg7e

View File

@@ -0,0 +1,34 @@
// Copyright © Gamesmiths Guild.
using Gamesmiths.Forge.Effects.Magnitudes;
using Gamesmiths.Forge.Godot.Core;
using Godot;
namespace Gamesmiths.Forge.Godot.Resources.Magnitudes;
[Tool]
[GlobalClass]
[Icon("uid://dnagt7tdo3dos")]
public partial class ForgeScalableInt : Resource
{
[Export]
public int BaseValue { get; set; }
[Export]
public Curve? ScalingCurve { get; set; }
public ForgeScalableInt()
{
// Constructor intentionally left blank.
}
public ForgeScalableInt(int baseValue)
{
BaseValue = baseValue;
}
public ScalableInt GetScalableInt()
{
return new ScalableInt(BaseValue, new ForgeCurve(ScalingCurve));
}
}

View File

@@ -0,0 +1 @@
uid://1hgogislo1l6