EB-2: felt spend - turrets burn a shared Charge pool, ledger-fed Fabricator mints it from Ore
Mined Ore now has an ongoing sink: a ledger-fed Fabricator converts Ore->Charge (1 Ore -> 3 Charge / 30t) and turrets spend Charge per shot, soft-failing (no shot, no cooldown burn) when the shared pool runs dry. - ResourceId.Charge=4 rides the existing [GhostField] StorageEntry ledger (no new wire). - TurretFireSystem: single ledger resolve + atomic spend / soft-fail / partial-refund. - Fabricator.InputFromLedger (byte, server-only) feeds input from the shared ledger, read live in-loop so two machines split a finite pool; both modes deposit to ledger. - HudSystem: violet Charge chip + global quiet-turret cue when siege && Charge==0. - StorageMath.TotalOf backs the affordability read; catalog re-enables the Fabricator (4 entries). See DR-033. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,7 @@ namespace ProjectM.Client
|
||||
static readonly Color AetherCyan = new(0.30f, 0.85f, 1f);
|
||||
static readonly Color OreAmber = new(1f, 0.72f, 0.35f);
|
||||
static readonly Color BioGreen = new(0.55f, 0.85f, 0.45f);
|
||||
static readonly Color ChargeViolet = new(0.80f, 0.45f, 1f);
|
||||
static readonly Color PanelDark = new(0.08f, 0.11f, 0.15f, 0.90f);
|
||||
static readonly Color PanelWarm = new(0.16f, 0.09f, 0.09f, 0.88f);
|
||||
static readonly Color PipDim = new(0.25f, 0.30f, 0.36f, 0.9f);
|
||||
@@ -58,7 +59,7 @@ namespace ProjectM.Client
|
||||
readonly List<VisualElement> _pips = new();
|
||||
|
||||
// resources
|
||||
Label _aetherNum, _oreNum, _bioNum;
|
||||
Label _aetherNum, _oreNum, _bioNum, _chargeNum;
|
||||
|
||||
// build palette + hints
|
||||
VisualElement _paletteRow, _hintBar, _facingArrow;
|
||||
@@ -190,7 +191,7 @@ namespace ProjectM.Client
|
||||
}
|
||||
|
||||
// ---- Resources (feed palette affordability) ----
|
||||
int aether = 0, ore = 0, bio = 0;
|
||||
int aether = 0, ore = 0, bio = 0, charge = 0;
|
||||
if (SystemAPI.TryGetSingletonEntity<ResourceLedger>(out var ledgerE))
|
||||
{
|
||||
var buf = SystemAPI.GetBuffer<StorageEntry>(ledgerE);
|
||||
@@ -200,11 +201,20 @@ namespace ProjectM.Client
|
||||
if (en.ItemId == ResourceId.Aether) aether = en.Count;
|
||||
else if (en.ItemId == ResourceId.Ore) ore = en.Count;
|
||||
else if (en.ItemId == ResourceId.Biomass) bio = en.Count;
|
||||
else if (en.ItemId == ResourceId.Charge) charge = en.Count;
|
||||
}
|
||||
}
|
||||
_aetherNum.text = aether.ToString();
|
||||
_oreNum.text = ore.ToString();
|
||||
_bioNum.text = bio.ToString();
|
||||
_chargeNum.text = charge.ToString();
|
||||
// EB-2 quiet-turret cue (GLOBAL, not per-turret, so the deterministic Charge split never reads as one
|
||||
// broken turret): a dry base during a siege tells the player to build a Fabricator.
|
||||
if (siege && charge == 0 && !onExpedition)
|
||||
{
|
||||
_locationText.text = "TURRETS OUT OF CHARGE - build a Fabricator (Ore -> Charge)";
|
||||
_locationText.style.color = new Color(1f, 0.4f, 0.9f);
|
||||
}
|
||||
|
||||
// ---- Threat readout (top-right) — hidden entirely at base with zero husks; its reappearance is the cue ----
|
||||
bool showThreat = siege || huskCount > 0;
|
||||
@@ -710,6 +720,7 @@ namespace ProjectM.Client
|
||||
strip.Add(ResourceChip(theme != null ? theme.AetherIcon : null, AetherCyan, "0", out _aetherNum, 26, 20));
|
||||
strip.Add(ResourceChip(theme != null ? theme.OreIcon : null, OreAmber, "0", out _oreNum, 30, 22));
|
||||
strip.Add(ResourceChip(theme != null ? theme.BioIcon : null, BioGreen, "0", out _bioNum, 26, 20));
|
||||
strip.Add(ResourceChip(null, ChargeViolet, "0", out _chargeNum, 26, 20)); // EB-2 turret ammo (flat violet, no icon)
|
||||
|
||||
root.Add(strip);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user