254 lines
7.8 KiB
C#
254 lines
7.8 KiB
C#
using System;
|
|
using GameCult.Aetheria.State.Unity;
|
|
using NUnit.Framework;
|
|
|
|
public class StatRecipeTests
|
|
{
|
|
[Test]
|
|
public void AddModifierScalesByConditionSample()
|
|
{
|
|
var recipe = new StatRecipe
|
|
{
|
|
BaseValue = 10,
|
|
Modifiers = new[]
|
|
{
|
|
new StatRecipeModifier
|
|
{
|
|
Condition = StatConditionMask.Quality,
|
|
Operation = StatModifierOperation.Add,
|
|
Amount = 6
|
|
}
|
|
}
|
|
};
|
|
|
|
var value = recipe.Evaluate(new StatEvaluationContext(quality: 0.5f, durability: 1, heat: 1));
|
|
|
|
Assert.AreEqual(13, value, 0.0001f);
|
|
}
|
|
|
|
[Test]
|
|
public void MultiplyModifierInterpolatesFromIdentity()
|
|
{
|
|
var recipe = new StatRecipe
|
|
{
|
|
BaseValue = 10,
|
|
Modifiers = new[]
|
|
{
|
|
new StatRecipeModifier
|
|
{
|
|
Condition = StatConditionMask.Durability,
|
|
Operation = StatModifierOperation.Multiply,
|
|
Amount = 2
|
|
}
|
|
}
|
|
};
|
|
|
|
var value = recipe.Evaluate(new StatEvaluationContext(quality: 1, durability: 0.25f, heat: 1));
|
|
|
|
Assert.AreEqual(12.5f, value, 0.0001f);
|
|
}
|
|
|
|
[Test]
|
|
public void OverrideModifierInterpolatesTowardTargetValue()
|
|
{
|
|
var recipe = new StatRecipe
|
|
{
|
|
BaseValue = 10,
|
|
Modifiers = new[]
|
|
{
|
|
new StatRecipeModifier
|
|
{
|
|
Condition = StatConditionMask.Heat,
|
|
Operation = StatModifierOperation.Override,
|
|
Amount = 20
|
|
}
|
|
}
|
|
};
|
|
|
|
var value = recipe.Evaluate(new StatEvaluationContext(quality: 1, durability: 1, heat: 0.25f));
|
|
|
|
Assert.AreEqual(12.5f, value, 0.0001f);
|
|
}
|
|
|
|
[Test]
|
|
public void DependencyMaskOnlyIncludesEnabledConditions()
|
|
{
|
|
var recipe = new StatRecipe
|
|
{
|
|
Modifiers = new[]
|
|
{
|
|
new StatRecipeModifier
|
|
{
|
|
Condition = StatConditionMask.Quality,
|
|
Enabled = false
|
|
},
|
|
new StatRecipeModifier
|
|
{
|
|
Condition = StatConditionMask.Range,
|
|
Enabled = true
|
|
}
|
|
}
|
|
};
|
|
|
|
Assert.AreEqual(StatConditionMask.Range, recipe.DependencyMask);
|
|
}
|
|
|
|
[Test]
|
|
public void DisabledAndConditionlessModifiersDoNotAffectEvaluation()
|
|
{
|
|
var recipe = new StatRecipe
|
|
{
|
|
BaseValue = 10,
|
|
Modifiers = new[]
|
|
{
|
|
new StatRecipeModifier
|
|
{
|
|
Condition = StatConditionMask.Quality,
|
|
Operation = StatModifierOperation.Add,
|
|
Amount = 100,
|
|
Enabled = false
|
|
},
|
|
new StatRecipeModifier
|
|
{
|
|
Condition = StatConditionMask.None,
|
|
Operation = StatModifierOperation.Add,
|
|
Amount = 100,
|
|
Enabled = true
|
|
},
|
|
new StatRecipeModifier
|
|
{
|
|
Condition = StatConditionMask.Heat,
|
|
Operation = StatModifierOperation.Add,
|
|
Amount = 4,
|
|
Enabled = true
|
|
}
|
|
}
|
|
};
|
|
|
|
var value = recipe.Evaluate(new StatEvaluationContext(quality: 1, durability: 1, heat: 0.25f));
|
|
|
|
Assert.AreEqual(11, value, 0.0001f);
|
|
Assert.AreEqual(StatConditionMask.Heat, recipe.DependencyMask);
|
|
}
|
|
|
|
[Test]
|
|
public void ContextOverrideReplacesSingleCondition()
|
|
{
|
|
var context = new StatEvaluationContext(quality: 0.2f, durability: 0.3f, heat: 0.4f, range: 0.5f);
|
|
|
|
var next = context.WithCondition(StatConditionMask.Range, 0.75f);
|
|
|
|
Assert.AreEqual(0.2f, next.Quality, 0.0001f);
|
|
Assert.AreEqual(0.3f, next.Durability, 0.0001f);
|
|
Assert.AreEqual(0.4f, next.Heat, 0.0001f);
|
|
Assert.AreEqual(0.75f, next.Range, 0.0001f);
|
|
}
|
|
|
|
[Test]
|
|
public void RecipeTokensMapCatalogStringsToRuntimeEnums()
|
|
{
|
|
Assert.AreEqual(StatConditionMask.Quality, StatRecipeTokens.ToConditionMask("quality"));
|
|
Assert.AreEqual(StatConditionMask.PilotSkill, StatRecipeTokens.ToConditionMask("pilotSkill"));
|
|
Assert.AreEqual(StatConditionMask.None, StatRecipeTokens.ToConditionMask("unknown"));
|
|
Assert.AreEqual(StatModifierOperation.Multiply, StatRecipeTokens.ToModifierOperation("multiply"));
|
|
Assert.AreEqual(StatModifierOperation.Override, StatRecipeTokens.ToModifierOperation("override"));
|
|
Assert.AreEqual(StatModifierOperation.Add, StatRecipeTokens.ToModifierOperation("unknown"));
|
|
}
|
|
|
|
[Test]
|
|
public void LegacyStatDependencyMaskIncludesOnlyActiveLegacyInputs()
|
|
{
|
|
var stat = new PerformanceStat
|
|
{
|
|
QualityExponent = 2,
|
|
DurabilityExponentMultiplier = 0,
|
|
HeatExponentMultiplier = 3
|
|
};
|
|
|
|
Assert.AreEqual(StatConditionMask.Quality, stat.GetDependencyMask(includeHeat: false));
|
|
Assert.AreEqual(StatConditionMask.Quality | StatConditionMask.Heat, stat.GetDependencyMask(includeHeat: true));
|
|
}
|
|
|
|
[Test]
|
|
public void LegacyStatEvaluationUsesExplicitContextExponents()
|
|
{
|
|
var stat = new PerformanceStat
|
|
{
|
|
Min = 0,
|
|
Max = 100,
|
|
QualityExponent = 2,
|
|
DurabilityExponentMultiplier = 1,
|
|
HeatExponentMultiplier = 1
|
|
};
|
|
|
|
var value = stat.EvaluateRecipeOrLegacy(
|
|
new StatEvaluationContext(quality: 0.5f, durability: 0.5f, heat: 0.5f),
|
|
durabilityExponent: 2,
|
|
thermalExponent: 2,
|
|
includeHeat: true);
|
|
|
|
Assert.AreEqual(3.125f, value, 0.0001f);
|
|
}
|
|
|
|
[Test]
|
|
public void ConsumableBaselinePreservesLinearEffectivenessCompatibility()
|
|
{
|
|
var stat = new PerformanceStat
|
|
{
|
|
Min = 10,
|
|
Max = 30,
|
|
QualityExponent = 2,
|
|
DurabilityExponentMultiplier = 10
|
|
};
|
|
|
|
var value = stat.EvaluateConsumableBaseline(
|
|
new StatEvaluationContext(quality: 0.5f, durability: 0.5f, heat: 1));
|
|
|
|
Assert.AreEqual(12.5f, value, 0.0001f);
|
|
}
|
|
|
|
[Test]
|
|
public void EntityModifierApplicationLeavesBaseValueWhenNoEntityModifiersExist()
|
|
{
|
|
var stat = new PerformanceStat();
|
|
|
|
Assert.AreEqual(42f, stat.ApplyEntityModifiers(null, 42f), 0.0001f);
|
|
}
|
|
|
|
[Test]
|
|
public void BehaviorValueReaderReadsEnumFromString()
|
|
{
|
|
var value = BehaviorValue("multiply", 0);
|
|
|
|
var operation = AetheriaRuntimeBehaviorValueReader.ReadEnum(value, StatModifierOperation.Add);
|
|
|
|
Assert.AreEqual(StatModifierOperation.Multiply, operation);
|
|
}
|
|
|
|
[Test]
|
|
public void BehaviorValueReaderReadsEnumFromNumberOrFallback()
|
|
{
|
|
var value = BehaviorValue("", (int)StatModifierOperation.Override);
|
|
var unknown = BehaviorValue("", 999);
|
|
|
|
Assert.AreEqual(
|
|
StatModifierOperation.Override,
|
|
AetheriaRuntimeBehaviorValueReader.ReadEnum(value, StatModifierOperation.Add));
|
|
Assert.AreEqual(
|
|
StatModifierOperation.Add,
|
|
AetheriaRuntimeBehaviorValueReader.ReadEnum(unknown, StatModifierOperation.Add));
|
|
}
|
|
|
|
private static AetheriaRuntimeBehaviorValue BehaviorValue(string stringValue, double numberValue)
|
|
{
|
|
return new AetheriaRuntimeBehaviorValue(
|
|
"",
|
|
stringValue,
|
|
numberValue,
|
|
false,
|
|
"",
|
|
"",
|
|
Array.Empty<AetheriaRuntimeBehaviorValue>(),
|
|
Array.Empty<AetheriaRuntimeBehaviorMapEntry>());
|
|
}
|
|
}
|