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:
@@ -35,6 +35,7 @@ namespace ProjectM.Server
|
||||
|
||||
ComponentLookup<GhostOwner> m_GhostOwnerLookup;
|
||||
BufferLookup<InventorySlot> m_InvLookup;
|
||||
ComponentLookup<RegionTag> m_RegionLookup;
|
||||
|
||||
[BurstCompile]
|
||||
public void OnCreate(ref SystemState state)
|
||||
@@ -43,6 +44,7 @@ namespace ProjectM.Server
|
||||
state.RequireForUpdate<ResourceLedger>();
|
||||
m_GhostOwnerLookup = state.GetComponentLookup<GhostOwner>(true);
|
||||
m_InvLookup = state.GetBufferLookup<InventorySlot>(false);
|
||||
m_RegionLookup = state.GetComponentLookup<RegionTag>(true);
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
@@ -56,6 +58,7 @@ namespace ProjectM.Server
|
||||
// hoisted out of the per-hit sweep (invariant for the tick).
|
||||
m_GhostOwnerLookup.Update(ref state);
|
||||
m_InvLookup.Update(ref state);
|
||||
m_RegionLookup.Update(ref state);
|
||||
bool haveDb = SystemAPI.TryGetSingleton<ItemDatabase>(out var itemDb);
|
||||
|
||||
var playerByConn = new NativeHashMap<int, Entity>(8, Allocator.Temp);
|
||||
@@ -72,6 +75,7 @@ namespace ProjectM.Server
|
||||
var tgtYieldPerHit = new NativeList<float>(Allocator.Temp);
|
||||
var tgtVariant = new NativeList<byte>(Allocator.Temp);
|
||||
var tgtIsClutter = new NativeList<bool>(Allocator.Temp);
|
||||
var tgtToLedger = new NativeList<bool>(Allocator.Temp);
|
||||
|
||||
foreach (var (xform, hr, node, e) in
|
||||
SystemAPI.Query<RefRO<LocalTransform>, RefRO<HitRadius>, RefRO<ResourceNode>>().WithEntityAccess())
|
||||
@@ -84,6 +88,7 @@ namespace ProjectM.Server
|
||||
tgtYieldPerHit.Add(node.ValueRO.HarvestPerHit);
|
||||
tgtVariant.Add(0);
|
||||
tgtIsClutter.Add(false);
|
||||
tgtToLedger.Add(m_RegionLookup.HasComponent(e) && m_RegionLookup[e].Region == RegionId.Base);
|
||||
}
|
||||
|
||||
foreach (var (xform, hr, clutter, e) in
|
||||
@@ -97,6 +102,7 @@ namespace ProjectM.Server
|
||||
tgtYieldPerHit.Add(clutter.ValueRO.ScrapPerHit);
|
||||
tgtVariant.Add(clutter.ValueRO.Variant);
|
||||
tgtIsClutter.Add(true);
|
||||
tgtToLedger.Add(m_RegionLookup.HasComponent(e) && m_RegionLookup[e].Region == RegionId.Base);
|
||||
}
|
||||
|
||||
var destroyed = new NativeArray<bool>(tgtEntity.Length, Allocator.Temp);
|
||||
@@ -144,7 +150,10 @@ namespace ProjectM.Server
|
||||
// firing player's GhostOwner (AbilityFireSystem); the owner is read OPTIONALLY (cached lookup) so
|
||||
// an un-owned projectile (or a test projectile with no GhostOwner) falls through to the ledger.
|
||||
int remainder = amount;
|
||||
if (m_GhostOwnerLookup.HasComponent(projEntity)
|
||||
// Base-region nodes credit the SHARED ledger DIRECTLY (the build currency pool); expedition / un-tagged
|
||||
// nodes keep the personal-inventory reroute (spill-to-ledger). Untagged -> not Base -> inventory path.
|
||||
if (!tgtToLedger[bestIdx]
|
||||
&& m_GhostOwnerLookup.HasComponent(projEntity)
|
||||
&& playerByConn.TryGetValue(m_GhostOwnerLookup[projEntity].NetworkId, out var player)
|
||||
&& m_InvLookup.HasBuffer(player))
|
||||
{
|
||||
@@ -208,6 +217,7 @@ namespace ProjectM.Server
|
||||
tgtYieldPerHit.Dispose();
|
||||
tgtVariant.Dispose();
|
||||
tgtIsClutter.Dispose();
|
||||
tgtToLedger.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user