Economy: base-local mining loop (mine at base, any attack harvests, scheduled sieges)
Consolidate the divorced combat + economy halves into one base-local loop. BaseFieldSpawnSystem tops up RegionTag{Base} Ore nodes around the plot; harvest routes Base->shared ledger and Expedition/untagged->personal inventory for BOTH the projectile (ResourceHarvestSystem) and melee (MeleeComboSystem server-only block, writes Remaining back for VFX). Activate the reserved Schedule source in ThreatDirectorSystem so base sieges arm WITHOUT an expedition trip (the loop-closer: previously zero waves ever attacked a base-only player). Region-filter the ExpeditionFieldSystem teardown so it no longer wipes the permanent base field. HudSystem shows phase-aware loop copy. See DR-031.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -66,6 +66,27 @@ namespace ProjectM.Server
|
||||
threat.PendingReturns = 0; // consume regardless so returns can't pile up
|
||||
}
|
||||
|
||||
// ---- SOURCE: scheduled base sieges. A timed cadence arms a siege even with NO expedition trip, so
|
||||
// the base-defense loop has stakes on its own. The first fire is one full interval out (a mine/build
|
||||
// grace window); size escalates by the live wave number. All ticks wrap-safe (TickUtil.NonZero). ----
|
||||
if (config.ScheduleEnabled != 0 && config.ScheduleIntervalTicks > 0)
|
||||
{
|
||||
if (threat.NextScheduledTick == 0 || cycle.Phase != CyclePhase.Calm)
|
||||
{
|
||||
// Seed, and DEFER while a siege runs, so the next scheduled siege is always one full interval
|
||||
// AFTER the current one resolves -> a guaranteed calm/build window even if a siege runs long.
|
||||
threat.NextScheduledTick = TickUtil.NonZero(now + config.ScheduleIntervalTicks);
|
||||
}
|
||||
else if (cycle.Phase == CyclePhase.Calm && threat.PendingSiegeSize == 0
|
||||
&& !new NetworkTick(threat.NextScheduledTick).IsNewerThan(serverTick))
|
||||
{
|
||||
int wave = SystemAPI.TryGetSingleton<WaveState>(out var ws) ? ws.WaveNumber : 0;
|
||||
threat.PendingSiegeSize = math.max(1, config.SizeBase + config.ScheduleSizePerWave * wave);
|
||||
threat.ArmTick = TickUtil.NonZero(now + config.PostExpeditionDelayTicks);
|
||||
threat.NextScheduledTick = TickUtil.NonZero(now + config.ScheduleIntervalTicks);
|
||||
}
|
||||
}
|
||||
|
||||
// ---- BOUNDED RESOLUTION: a Siege can't drag forever. Record its start; after SiegeTimeoutTicks cull
|
||||
// the remaining Husks + stop spawning so CyclePhaseSystem's DefendCleared returns the base to Calm. ----
|
||||
if (cycle.Phase == CyclePhase.Siege)
|
||||
|
||||
Reference in New Issue
Block a user