Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 3 additions & 61 deletions Forge.Tests/Core/Curve.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ namespace Gamesmiths.Forge.Tests.Core;
/// <summary>
/// Initializes a new instance of the <see cref="Curve"/> class.
/// </summary>
/// <param name="keys">The keys for the curve.</param>
public readonly struct Curve(CurveKey[] keys) : ICurve, IEquatable<Curve>
/// <param name="Keys">The keys for the curve.</param>
public readonly record struct Curve(CurveKey[] Keys) : ICurve
{
private readonly CurveKey[] _keys = [.. keys.OrderBy(x => x.Time)];
private readonly CurveKey[] _keys = [.. Keys.OrderBy(x => x.Time)];

/// <summary>
/// Evaluates the curve at a given time.
Expand Down Expand Up @@ -47,62 +47,4 @@ public float Evaluate(float value)
// Fallback.
return 1.0f;
}

/// <inheritdoc/>
public override int GetHashCode()
{
var hash = default(HashCode);
foreach (CurveKey key in _keys)
{
hash.Add(key);
}

return hash.ToHashCode();
}

/// <inheritdoc/>
public override bool Equals(object? obj)
{
if (obj is Curve other)
{
return Equals(other);
}

return false;
}

/// <inheritdoc/>
public bool Equals(Curve other)
{
if (_keys is null)
{
return other._keys is null;
}

return _keys.SequenceEqual(other._keys);
}

/// <summary>
/// Determines if two <see cref="Curve"/> objects are equal.
/// </summary>
/// <param name="lhs">The first <see cref="Curve"/> to compare.</param>
/// <param name="rhs">The second <see cref="Curve"/> to compare.</param>
/// <returns><see langword="true"/> if the values of <paramref name="lhs"/> and <paramref name="rhs"/> are equal;
/// otherwise, <see langword="false"/>.</returns>
public static bool operator ==(Curve lhs, Curve rhs)
{
return lhs.Equals(rhs);
}

/// <summary>
/// Determines if two <see cref="Curve"/> objects are not equal.
/// </summary>
/// <param name="lhs">The first <see cref="Curve"/> to compare.</param>
/// <param name="rhs">The second <see cref="Curve"/> to compare.</param>
/// <returns><see langword="true"/> if the values of <paramref name="lhs"/> and <paramref name="rhs"/> are not
/// equal; otherwise, <see langword="false"/>.</returns>
public static bool operator !=(Curve lhs, Curve rhs)
{
return !(lhs == rhs);
}
}
72 changes: 4 additions & 68 deletions Forge.Tests/Core/CurveKey.cs
Original file line number Diff line number Diff line change
@@ -1,74 +1,10 @@
// Copyright © Gamesmiths Guild.

namespace Gamesmiths.Forge.Core;
namespace Gamesmiths.Forge.Tests.Core;

/// <summary>
/// Represents a key into a <see cref="Curve"/>.
/// </summary>
/// <param name="time">The time of the curve key.</param>
/// <param name="value">The value of the curve key.</param>
public readonly struct CurveKey(float time, float value) : IEquatable<CurveKey>
{
/// <summary>
/// Gets the time of this curve key.
/// </summary>
public float Time { get; } = time;

/// <summary>
/// Gets the value of this curve key.
/// </summary>
public float Value { get; } = value;

/// <inheritdoc/>
public override int GetHashCode()
{
var hash = default(HashCode);
hash.Add(Time);
hash.Add(Value);
return hash.ToHashCode();
}

/// <inheritdoc/>
public override bool Equals(object? obj)
{
if (obj is CurveKey other)
{
return Equals(other);
}

return false;
}

/// <inheritdoc/>
public bool Equals(CurveKey other)
{
#pragma warning disable S1244 // Floating point numbers should not be tested for equality
return Time == other.Time
&& Value.Equals(other.Value);
#pragma warning restore S1244 // Floating point numbers should not be tested for equality
}

/// <summary>
/// Determines if two <see cref="CurveKey"/> objects are equal.
/// </summary>
/// <param name="lhs">The first <see cref="CurveKey"/> to compare.</param>
/// <param name="rhs">The second <see cref="CurveKey"/> to compare.</param>
/// <returns><see langword="true"/> if the values of <paramref name="lhs"/> and <paramref name="rhs"/> are equal;
/// otherwise, <see langword="false"/>.</returns>
public static bool operator ==(CurveKey lhs, CurveKey rhs)
{
return lhs.Equals(rhs);
}

/// <summary>
/// Determines if two <see cref="CurveKey"/> objects are not equal.
/// </summary>
/// <param name="lhs">The first <see cref="CurveKey"/> to compare.</param>
/// <param name="rhs">The second <see cref="CurveKey"/> to compare.</param>
/// <returns><see langword="true"/> if the values of <paramref name="lhs"/> and <paramref name="rhs"/> are not
/// equal; otherwise, <see langword="false"/>.</returns>
public static bool operator !=(CurveKey lhs, CurveKey rhs)
{
return !(lhs == rhs);
}
}
/// <param name="Time">The time of the curve key.</param>
/// <param name="Value">The value of the curve key.</param>
public readonly record struct CurveKey(float Time, float Value);
8 changes: 4 additions & 4 deletions Forge.Tests/Cues/CueTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2456,10 +2456,10 @@ private static EffectData CreateDurationStackableEffectData(
StackMagnitudePolicy.Sum,
StackOverflowPolicy.AllowApplication,
StackExpirationPolicy.RemoveSingleStackAndRefreshDuration,
levelDenialPolicy: LevelComparison.None,
levelOverridePolicy: LevelComparison.Lower | LevelComparison.Equal | LevelComparison.Higher,
levelOverrideStackCountPolicy: StackLevelOverrideStackCountPolicy.IncreaseStacks,
applicationRefreshPolicy: StackApplicationRefreshPolicy.RefreshOnSuccessfulApplication),
LevelDenialPolicy: LevelComparison.None,
LevelOverridePolicy: LevelComparison.Lower | LevelComparison.Equal | LevelComparison.Higher,
LevelOverrideStackCountPolicy: StackLevelOverrideStackCountPolicy.IncreaseStacks,
ApplicationRefreshPolicy: StackApplicationRefreshPolicy.RefreshOnSuccessfulApplication),
snapshopLevel: false,
requireModifierSuccessToTriggerCue: requireModifierSuccessToTriggerCue,
suppressStackingCues: suppressStackingCues,
Expand Down
2 changes: 1 addition & 1 deletion Forge.Tests/Effects/EffectsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public void Attribute_based_effect_with_curve_modifies_values_based_on_curve_loo
new ScalableFloat(coefficient),
new ScalableFloat(preMultiplyAdditiveValue),
new ScalableFloat(postMultiplyAdditiveValue),
lookupCurve: new Curve(
LookupCurve: new Curve(
[
new CurveKey(6, 4),
new CurveKey(8, 3),
Expand Down
4 changes: 2 additions & 2 deletions Forge.Tests/Effects/TargetTagRequirementsComponentTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ public void Effect_meets_application_requirements_with_query()
new DurationData(DurationType.Infinite),
effectComponents:
[
new TargetTagRequirementsEffectComponent(new TagRequirements(tagQuery: query))
new TargetTagRequirementsEffectComponent(new TagRequirements(TagQuery: query))
]);

var effect = new Effect(effectData, new EffectOwnership(entity, entity));
Expand Down Expand Up @@ -391,7 +391,7 @@ public void Effect_does_not_meet_application_requirements_with_query()
new DurationData(DurationType.Infinite),
effectComponents:
[
new TargetTagRequirementsEffectComponent(new TagRequirements(tagQuery: query))
new TargetTagRequirementsEffectComponent(new TagRequirements(TagQuery: query))
]);

var effect = new Effect(effectData, new EffectOwnership(entity, entity));
Expand Down
98 changes: 49 additions & 49 deletions Forge.Tests/Samples/QuickStartTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,9 @@ public void Periodic_effect_example()
)
},
periodicData: new PeriodicData(
period: new ScalableFloat(2.0f),
executeOnApplication: true,
periodInhibitionRemovedPolicy: PeriodInhibitionRemovedPolicy.ResetPeriod
Period: new ScalableFloat(2.0f),
ExecuteOnApplication: true,
PeriodInhibitionRemovedPolicy: PeriodInhibitionRemovedPolicy.ResetPeriod
)
);

Expand Down Expand Up @@ -282,23 +282,23 @@ public void Stacking_poison_effect_example()
)
},
periodicData: new PeriodicData(
period: new ScalableFloat(2.0f),
executeOnApplication: false,
periodInhibitionRemovedPolicy: PeriodInhibitionRemovedPolicy.ResetPeriod
Period: new ScalableFloat(2.0f),
ExecuteOnApplication: false,
PeriodInhibitionRemovedPolicy: PeriodInhibitionRemovedPolicy.ResetPeriod
),
stackingData: new StackingData(
stackLimit: new ScalableInt(3), // Max 3 stacks
initialStack: new ScalableInt(1), // Starts with 1 stack
overflowPolicy: StackOverflowPolicy.DenyApplication, // Deny if max stacks reached
magnitudePolicy: StackMagnitudePolicy.Sum, // Total damage increases with stacks
expirationPolicy: StackExpirationPolicy.ClearEntireStack, // All stacks expire together
applicationRefreshPolicy: StackApplicationRefreshPolicy.RefreshOnSuccessfulApplication,
stackPolicy: StackPolicy.AggregateBySource, // Aggregate stacks from the same source
stackLevelPolicy: StackLevelPolicy.SegregateLevels, // Each stack can have its own level
StackLimit: new ScalableInt(3), // Max 3 stacks
InitialStack: new ScalableInt(1), // Starts with 1 stack
OverflowPolicy: StackOverflowPolicy.DenyApplication, // Deny if max stacks reached
MagnitudePolicy: StackMagnitudePolicy.Sum, // Total damage increases with stacks
ExpirationPolicy: StackExpirationPolicy.ClearEntireStack, // All stacks expire together
ApplicationRefreshPolicy: StackApplicationRefreshPolicy.RefreshOnSuccessfulApplication,
StackPolicy: StackPolicy.AggregateBySource, // Aggregate stacks from the same source
StackLevelPolicy: StackLevelPolicy.SegregateLevels, // Each stack can have its own level

// The next two values must be defined because this is a periodic effect with stacking
executeOnSuccessfulApplication: false, // Do not execute on successful application
applicationResetPeriodPolicy: StackApplicationResetPeriodPolicy.ResetOnSuccessfulApplication
ExecuteOnSuccessfulApplication: false, // Do not execute on successful application
ApplicationResetPeriodPolicy: StackApplicationResetPeriodPolicy.ResetOnSuccessfulApplication
)
);

Expand Down Expand Up @@ -351,20 +351,20 @@ public void Unique_effect_example()
)
},
stackingData: new StackingData(
stackLimit: new ScalableInt(1), // Only 1 instance allowed
initialStack: new ScalableInt(1), // Starts with 1 stack
overflowPolicy: StackOverflowPolicy.AllowApplication, // Allow application even if max stacks reached
magnitudePolicy: StackMagnitudePolicy.Sum, // Total damage increases with stacks
expirationPolicy: StackExpirationPolicy.ClearEntireStack, // All stacks expire together
applicationRefreshPolicy: StackApplicationRefreshPolicy.RefreshOnSuccessfulApplication,
stackPolicy: StackPolicy.AggregateByTarget, // Only one effect per target
ownerDenialPolicy: StackOwnerDenialPolicy.AlwaysAllow, // Always allow application regardless of owner
ownerOverridePolicy: StackOwnerOverridePolicy.Override, // Override existing effect if applied again
ownerOverrideStackCountPolicy: StackOwnerOverrideStackCountPolicy.ResetStacks,
stackLevelPolicy: StackLevelPolicy.AggregateLevels, // Aggregate levels of the effect
levelOverridePolicy: LevelComparison.Equal | LevelComparison.Higher,
levelDenialPolicy: LevelComparison.Lower, // Deny lower-level effects
levelOverrideStackCountPolicy: StackLevelOverrideStackCountPolicy.ResetStacks
StackLimit: new ScalableInt(1), // Only 1 instance allowed
InitialStack: new ScalableInt(1), // Starts with 1 stack
OverflowPolicy: StackOverflowPolicy.AllowApplication, // Allow application even if max stacks reached
MagnitudePolicy: StackMagnitudePolicy.Sum, // Total damage increases with stacks
ExpirationPolicy: StackExpirationPolicy.ClearEntireStack, // All stacks expire together
ApplicationRefreshPolicy: StackApplicationRefreshPolicy.RefreshOnSuccessfulApplication,
StackPolicy: StackPolicy.AggregateByTarget, // Only one effect per target
OwnerDenialPolicy: StackOwnerDenialPolicy.AlwaysAllow, // Always allow application regardless of owner
OwnerOverridePolicy: StackOwnerOverridePolicy.Override, // Override existing effect if applied again
OwnerOverrideStackCountPolicy: StackOwnerOverrideStackCountPolicy.ResetStacks,
StackLevelPolicy: StackLevelPolicy.AggregateLevels, // Aggregate levels of the effect
LevelOverridePolicy: LevelComparison.Equal | LevelComparison.Higher,
LevelDenialPolicy: LevelComparison.Lower, // Deny lower-level effects
LevelOverrideStackCountPolicy: StackLevelOverrideStackCountPolicy.ResetStacks
)
);

Expand Down Expand Up @@ -456,7 +456,7 @@ public void Preventing_effect_application_based_on_tags()
new TargetTagRequirementsEffectComponent(
applicationTagRequirements: new TagRequirements(
// Prevent application if target has "status.immune.fire"
ignoreTags: tagsManager.RequestTagContainer(new[] { "status.immune.fire" })
IgnoreTags: tagsManager.RequestTagContainer(new[] { "status.immune.fire" })
)
)
}
Expand Down Expand Up @@ -638,17 +638,17 @@ public void Triggering_a_cue_through_effects()
)
},
periodicData: new PeriodicData(
period: new ScalableFloat(1.0f), // Ticks every second
executeOnApplication: true,
periodInhibitionRemovedPolicy: PeriodInhibitionRemovedPolicy.ResetPeriod
Period: new ScalableFloat(1.0f), // Ticks every second
ExecuteOnApplication: true,
PeriodInhibitionRemovedPolicy: PeriodInhibitionRemovedPolicy.ResetPeriod
),
cues: new[] {
new CueData(
cueTags: tagsManager.RequestTagContainer(new[] { "cues.damage.fire" }),
minValue: 0,
maxValue: 100,
magnitudeType: CueMagnitudeType.AttributeValueChange,
magnitudeAttribute: "PlayerAttributeSet.Health" // Tracks health changes
CueTags: tagsManager.RequestTagContainer(new[] { "cues.damage.fire" }),
MinValue: 0,
MaxValue: 100,
MagnitudeType: CueMagnitudeType.AttributeValueChange,
MagnitudeAttribute: "PlayerAttributeSet.Health" // Tracks health changes
)
}
);
Expand Down Expand Up @@ -700,10 +700,10 @@ public void Manually_triggering_a_cue()

// Manually trigger a fire damage cue
var parameters = new CueParameters(
magnitude: 25, // Raw damage value
normalizedMagnitude: 0.25f, // Normalized between 0-1
source: player,
customParameters: new Dictionary<StringKey, object>
Magnitude: 25, // Raw damage value
NormalizedMagnitude: 0.25f, // Normalized between 0-1
Source: player,
CustomParameters: new Dictionary<StringKey, object>
{
{ "DamageType", "Fire" },
{ "IsCritical", true }
Expand Down Expand Up @@ -797,12 +797,12 @@ public StrengthDamageCalculator()
StrengthAttribute = new AttributeCaptureDefinition(
"PlayerAttributeSet.Strength",
AttributeCaptureSource.Source,
snapshot: true);
Snapshot: true);

SpeedAttribute = new AttributeCaptureDefinition(
"PlayerAttributeSet.Speed",
AttributeCaptureSource.Source,
snapshot: true);
Snapshot: true);

AttributesToCapture.Add(StrengthAttribute);
AttributesToCapture.Add(SpeedAttribute);
Expand Down Expand Up @@ -833,17 +833,17 @@ public HealthDrainExecution()
TargetHealth = new AttributeCaptureDefinition(
"PlayerAttributeSet.Health",
AttributeCaptureSource.Target,
snapshot: false);
Snapshot: false);

SourceHealth = new AttributeCaptureDefinition(
"PlayerAttributeSet.Health",
AttributeCaptureSource.Source,
snapshot: false);
Snapshot: false);

SourceStrength = new AttributeCaptureDefinition(
"PlayerAttributeSet.Strength",
AttributeCaptureSource.Source,
snapshot: false);
Snapshot: false);

// Register attributes for capture
AttributesToCapture.Add(TargetHealth);
Expand Down Expand Up @@ -922,7 +922,7 @@ public void OnUpdate(IForgeEntity? target, CueParameters? parameters)
// Logic for updating persistent cues (e.g., adjust fire intensity)
if (parameters.HasValue)
{
Console.WriteLine($"Fire damage cue updated with magnitude: {parameters.Value.Magnitude}");
Console.WriteLine($"Fire damage cue updated with Magnitude: {parameters.Value.Magnitude}");
}
}
}
Expand Down
Loading
Loading