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>
55 lines
2.5 KiB
C#
55 lines
2.5 KiB
C#
using Unity.Collections;
|
|
using Unity.Entities;
|
|
|
|
namespace ProjectM.Simulation
|
|
{
|
|
/// <summary>
|
|
/// Shared harvest-yield deposit routing used by BOTH the projectile-sweep harvest (ResourceHarvestSystem) and
|
|
/// the melee-cone harvest (MeleeComboSystem), so the two can't drift. (They previously did: the melee path
|
|
/// hard-coded <see cref="Tuning.DefaultStackMax"/> and silently ignored per-item stack caps.) Base-region yield
|
|
/// credits the shared ledger DIRECTLY (the build-currency pool); expedition / un-tagged yield routes to the
|
|
/// harvesting player's PERSONAL inventory — per-item StackMax from the item catalog, fallback DefaultStackMax —
|
|
/// and spills any overflow to the ledger (the no-loss valve). Pure + Burst-friendly.
|
|
/// </summary>
|
|
public static class HarvestMath
|
|
{
|
|
/// <summary>
|
|
/// Routes one harvested yield to its sink. Returns true if the yield landed somewhere (inventory or ledger);
|
|
/// callers use this to avoid consuming a target for zero credit (e.g. no ledger singleton present).
|
|
/// <paramref name="player"/> may be <see cref="Entity.Null"/> (unresolvable owner) — the yield then falls
|
|
/// through to the ledger. <paramref name="ledger"/> is only touched when <paramref name="haveLedger"/> is true.
|
|
/// </summary>
|
|
public static bool DepositYield(
|
|
byte yieldId, int amount, bool toLedger, Entity player,
|
|
BufferLookup<InventorySlot> invLookup,
|
|
DynamicBuffer<StorageEntry> ledger, bool haveLedger,
|
|
bool haveDb, in ItemDatabase itemDb)
|
|
{
|
|
int remainder = amount;
|
|
bool deposited = false;
|
|
|
|
if (!toLedger && player != Entity.Null && invLookup.HasBuffer(player))
|
|
{
|
|
int stackMax = Tuning.DefaultStackMax;
|
|
if (haveDb && itemDb.Value.IsCreated)
|
|
{
|
|
ref var blob = ref itemDb.Value.Value;
|
|
if (blob.TryGetItem(yieldId, out var def) && def.StackMax > 0)
|
|
stackMax = def.StackMax;
|
|
}
|
|
var inv = invLookup[player];
|
|
remainder = InventoryMath.Deposit(inv, yieldId, amount, stackMax, Tuning.InventoryMaxSlots);
|
|
deposited = true;
|
|
}
|
|
|
|
if (remainder > 0 && haveLedger)
|
|
{
|
|
StorageMath.Deposit(ledger, yieldId, remainder);
|
|
deposited = true;
|
|
}
|
|
|
|
return deposited;
|
|
}
|
|
}
|
|
}
|