Core Game Loop Additions
This commit is contained in:
@@ -24,6 +24,9 @@ namespace ProjectM.Client
|
||||
RectTransform _cooldownFill;
|
||||
Text _healthText;
|
||||
Text _threatText;
|
||||
Text _phaseText;
|
||||
Text _resourceText;
|
||||
Text _locationText;
|
||||
GameObject _respawnOverlay;
|
||||
EntityQuery _huskQuery;
|
||||
|
||||
@@ -48,6 +51,55 @@ namespace ProjectM.Client
|
||||
|
||||
bool haveTick = SystemAPI.TryGetSingleton<NetworkTime>(out var nt);
|
||||
|
||||
// Macro-loop HUD (phase + cycle + countdown + location), read before the per-player early-out so it persists pre-spawn.
|
||||
bool haveCycle = SystemAPI.TryGetSingleton<CycleState>(out var cyc);
|
||||
if (_phaseText != null && haveCycle)
|
||||
{
|
||||
var endTick = new NetworkTick(cyc.PhaseEndTick);
|
||||
string detail;
|
||||
if (cyc.Phase == CyclePhase.Defend)
|
||||
detail = _huskQuery.CalculateEntityCount() + " HUSKS";
|
||||
else if (haveTick && cyc.PhaseEndTick != 0 && endTick.IsValid && endTick.IsNewerThan(nt.ServerTick))
|
||||
detail = (endTick.TicksSince(nt.ServerTick) / 60) + "s";
|
||||
else
|
||||
detail = "";
|
||||
_phaseText.text = PhaseLabel(cyc.Phase) + (detail.Length > 0 ? " - " + detail : "") + " CYCLE " + cyc.CycleNumber;
|
||||
_phaseText.color = PhaseColor(cyc.Phase);
|
||||
}
|
||||
else if (_phaseText != null)
|
||||
{
|
||||
_phaseText.text = "";
|
||||
}
|
||||
|
||||
if (_locationText != null)
|
||||
{
|
||||
var cam = Camera.main;
|
||||
bool onExpedition = cam != null && cam.transform.position.x > 500f;
|
||||
_locationText.text = onExpedition
|
||||
? "ON EXPEDITION - return through the gate"
|
||||
: "AT BASE" + (haveCycle && cyc.Phase == CyclePhase.Expedition ? " - step into the gate to deploy" : "");
|
||||
_locationText.color = onExpedition ? new Color(1f, 0.8f, 0.4f) : new Color(0.6f, 0.85f, 1f);
|
||||
}
|
||||
|
||||
if (_resourceText != null)
|
||||
{
|
||||
string res = "";
|
||||
if (SystemAPI.TryGetSingletonEntity<ResourceLedger>(out var ledgerE))
|
||||
{
|
||||
var buf = SystemAPI.GetBuffer<StorageEntry>(ledgerE);
|
||||
int aether = 0, ore = 0, bio = 0;
|
||||
for (int i = 0; i < buf.Length; i++)
|
||||
{
|
||||
var en = buf[i];
|
||||
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;
|
||||
}
|
||||
res = "AETHER " + aether + " ORE " + ore + " BIO " + bio;
|
||||
}
|
||||
_resourceText.text = res;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
float hp = 0f, maxHp = 1f, cdFrac = 1f;
|
||||
bool dead = false, shielded = false;
|
||||
@@ -77,7 +129,7 @@ namespace ProjectM.Client
|
||||
break;
|
||||
}
|
||||
|
||||
_canvas.enabled = found;
|
||||
_canvas.enabled = found || haveCycle;
|
||||
if (!found) return;
|
||||
|
||||
float frac = maxHp > 0f ? Mathf.Clamp01(hp / maxHp) : 0f;
|
||||
@@ -139,6 +191,27 @@ namespace ProjectM.Client
|
||||
trt.anchorMin = new Vector2(1, 1); trt.anchorMax = new Vector2(1, 1); trt.pivot = new Vector2(1, 1);
|
||||
trt.anchoredPosition = new Vector2(-40, -30); trt.sizeDelta = new Vector2(380, 50);
|
||||
|
||||
// Cycle phase + number (top-center).
|
||||
_phaseText = MakeText("PhaseText", _canvas.transform, "EXPEDITION CYCLE 1", 34, TextAnchor.UpperCenter,
|
||||
new Color(0.55f, 0.9f, 1f), font);
|
||||
var prt = _phaseText.rectTransform;
|
||||
prt.anchorMin = new Vector2(0.5f, 1f); prt.anchorMax = new Vector2(0.5f, 1f); prt.pivot = new Vector2(0.5f, 1f);
|
||||
prt.anchoredPosition = new Vector2(0, -24); prt.sizeDelta = new Vector2(600, 50);
|
||||
|
||||
// Resource ledger counts (top-center, below phase).
|
||||
_resourceText = MakeText("ResourceText", _canvas.transform, "", 24, TextAnchor.UpperCenter,
|
||||
new Color(0.7f, 0.95f, 0.8f), font);
|
||||
var rrt = _resourceText.rectTransform;
|
||||
rrt.anchorMin = new Vector2(0.5f, 1f); rrt.anchorMax = new Vector2(0.5f, 1f); rrt.pivot = new Vector2(0.5f, 1f);
|
||||
rrt.anchoredPosition = new Vector2(0, -64); rrt.sizeDelta = new Vector2(600, 40);
|
||||
|
||||
// Location + gate hint (top-center, below resources).
|
||||
_locationText = MakeText("LocationText", _canvas.transform, "", 22, TextAnchor.UpperCenter,
|
||||
new Color(0.6f, 0.85f, 1f), font);
|
||||
var lrt = _locationText.rectTransform;
|
||||
lrt.anchorMin = new Vector2(0.5f, 1f); lrt.anchorMax = new Vector2(0.5f, 1f); lrt.pivot = new Vector2(0.5f, 1f);
|
||||
lrt.anchoredPosition = new Vector2(0, -96); lrt.sizeDelta = new Vector2(760, 36);
|
||||
|
||||
// Downed / respawning overlay (full screen, toggled by Dead).
|
||||
_respawnOverlay = new GameObject("RespawnOverlay", typeof(RectTransform));
|
||||
_respawnOverlay.transform.SetParent(_canvas.transform, false);
|
||||
@@ -211,5 +284,27 @@ namespace ProjectM.Client
|
||||
if (f == null) f = Font.CreateDynamicFontFromOSFont(new[] { "Arial", "Liberation Sans", "DejaVu Sans" }, 28);
|
||||
return f;
|
||||
}
|
||||
|
||||
static Color PhaseColor(byte phase)
|
||||
{
|
||||
switch (phase)
|
||||
{
|
||||
case CyclePhase.Expedition: return new Color(0.45f, 0.85f, 1f);
|
||||
case CyclePhase.Defend: return new Color(1f, 0.5f, 0.3f);
|
||||
case CyclePhase.Build: return new Color(0.45f, 0.95f, 0.6f);
|
||||
default: return Color.white;
|
||||
}
|
||||
}
|
||||
|
||||
static string PhaseLabel(byte phase)
|
||||
{
|
||||
switch (phase)
|
||||
{
|
||||
case CyclePhase.Expedition: return "EXPEDITION";
|
||||
case CyclePhase.Defend: return "DEFEND";
|
||||
case CyclePhase.Build: return "BUILD";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user