b1041003f0
- Restore swallowed [Test] on EnemyAIMathTests.SlideVelocity_DegenerateNormal_DeflectsToTangent (dead regression guard for the shipped enemy-stuck-on-cover fix; now runs + passes). - Extract shared HarvestMath.DepositYield used by ResourceHarvestSystem + MeleeComboSystem; fixes melee mining silently ignoring per-item StackMax (it hard-coded DefaultStackMax) and hoists the melee ledger-buffer fetch out of the per-target loop. - StatMath.Apply switches on the raw byte (case (byte)ModOp.X) instead of casting to the enum inside the Bursted fold — removes the latent cross-assembly enum-in-Burst ICE trap. - Add [Min] guards on CycleDirectorAuthoring loss-critical ints (CoreIntegrityMax>=1 so a mis-authored 0 can't bake an instant-loss core; siege sizes >=0). 456/456 EditMode tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
43 lines
1.5 KiB
C#
43 lines
1.5 KiB
C#
using Unity.Collections;
|
|
using Unity.Entities;
|
|
|
|
namespace ProjectM.Simulation
|
|
{
|
|
/// <summary>
|
|
/// Pure, deterministic folding of a StatModifier set into an effective value for one StatTarget:
|
|
/// effective = (base + sum flat) * (1 + sum percentAdd) * product(1 + percentMult).
|
|
/// Order-independent within each op class, Burst-friendly, and unit-tested like AutoTarget.Resolve.
|
|
/// Returns the raw fold; consumers clamp domain bounds (e.g. cooldown >= 1 tick).
|
|
/// </summary>
|
|
public static class StatMath
|
|
{
|
|
public static float Apply(float baseValue, StatTarget target, in DynamicBuffer<StatModifier> mods)
|
|
{
|
|
return Apply(baseValue, target, mods.AsNativeArray());
|
|
}
|
|
|
|
public static float Apply(float baseValue, StatTarget target, in NativeArray<StatModifier> mods)
|
|
{
|
|
float flat = 0f;
|
|
float percentAdd = 0f;
|
|
float percentMult = 1f;
|
|
byte t = (byte)target;
|
|
|
|
for (int i = 0; i < mods.Length; i++)
|
|
{
|
|
var m = mods[i];
|
|
if (m.Target != t)
|
|
continue;
|
|
switch (m.Op)
|
|
{
|
|
case (byte)ModOp.Flat: flat += m.Value; break;
|
|
case (byte)ModOp.PercentAdd: percentAdd += m.Value; break;
|
|
case (byte)ModOp.PercentMult: percentMult *= 1f + m.Value; break;
|
|
}
|
|
}
|
|
|
|
return (baseValue + flat) * (1f + percentAdd) * percentMult;
|
|
}
|
|
}
|
|
}
|