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:
@@ -0,0 +1,51 @@
|
||||
using ProjectM.Simulation;
|
||||
using Unity.Entities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ProjectM.Authoring
|
||||
{
|
||||
/// <summary>
|
||||
/// Authoring for the home-base mining field (<see cref="BaseFieldSpawner"/>). Place ONE in the gameplay
|
||||
/// subscene. <see cref="NodePrefab"/> = the SAME ResourceNode ghost prefab the expedition uses; the server
|
||||
/// system overrides each instance to RegionTag{Base} + ResourceId.Ore and scatters them in the
|
||||
/// [<see cref="InnerRadius"/>, <see cref="OuterRadius"/>] annulus around the base plot center. Defaults are
|
||||
/// sized to the baked 32x32 plot (square corner reach ~22.6) inside the ~28.7 boundary ring, so nodes form a
|
||||
/// reachable perimeter ring that never sits on a build cell.
|
||||
/// </summary>
|
||||
public class BaseFieldSpawnerAuthoring : MonoBehaviour
|
||||
{
|
||||
[Tooltip("Resource-node ghost prefab (ResourceNodeAuthoring + GhostAuthoring). Reuse the expedition node prefab.")]
|
||||
public GameObject NodePrefab;
|
||||
|
||||
[Tooltip("Live base-node target; the field refills toward this each respawn pass.")]
|
||||
[Min(1)] public int TargetCount = 10;
|
||||
|
||||
[Tooltip("Inner scatter radius — clears the build plot corner reach (~22.6) + spawn ring.")]
|
||||
[Min(0f)] public float InnerRadius = 23.5f;
|
||||
|
||||
[Tooltip("Outer scatter radius — stays inside the walkable boundary ring (~28.7).")]
|
||||
[Min(0f)] public float OuterRadius = 27f;
|
||||
|
||||
[Tooltip("Server ticks (@60) between top-up passes.")]
|
||||
[Min(1)] public int RespawnIntervalTicks = 600;
|
||||
|
||||
private class BaseFieldSpawnerBaker : Baker<BaseFieldSpawnerAuthoring>
|
||||
{
|
||||
public override void Bake(BaseFieldSpawnerAuthoring authoring)
|
||||
{
|
||||
var entity = GetEntity(authoring, TransformUsageFlags.None);
|
||||
AddComponent(entity, new BaseFieldSpawner
|
||||
{
|
||||
Prefab = authoring.NodePrefab != null
|
||||
? GetEntity(authoring.NodePrefab, TransformUsageFlags.Dynamic)
|
||||
: Entity.Null,
|
||||
TargetCount = authoring.TargetCount,
|
||||
InnerRadius = authoring.InnerRadius,
|
||||
OuterRadius = authoring.OuterRadius,
|
||||
RespawnIntervalTicks = authoring.RespawnIntervalTicks,
|
||||
});
|
||||
AddComponent(entity, new BaseFieldRuntime { Epoch = 0, NextSpawnTick = 0u });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c4055a6a779d06949ae23b16334b810e
|
||||
Reference in New Issue
Block a user