Files
DepthsOfGreed/Assets/Scripts/HandbookUI/SupplyBasementBinding.cs
T

110 lines
6.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections.Generic;
using TMPro;
using UnityEngine;
namespace DepthsOfGreed.HandbookUI
{
public sealed partial class SupplyBasementController
{
[Header("Versorgungssystem – optional")]
[Tooltip("MonoBehaviour mit ISupplyGameplay. Leer = bisherige Bedien- und Fahrvorschau.")]
[SerializeField] private MonoBehaviour supplyBackend;
public TMP_Text[] storageAmounts, bufferAmounts, magazineAmounts;
public bool HasSupplyBackend => supplyBackend && supplyBackend is ISupplyGameplay;
public ISupplyGameplay SupplyBackend => HasSupplyBackend ? (ISupplyGameplay)supplyBackend : null;
private SupplyState supplyState;
private float commandMessageUntil;
private readonly List<BuiltObjectSnapshot> supplyObjects = new List<BuiltObjectSnapshot>();
public void BindSupplyBackend(MonoBehaviour backend)
{
if (backend && !(backend is ISupplyGameplay))
{ Debug.LogError("Versorgung: Komponente muss ISupplyGameplay implementieren.", backend); return; }
supplyBackend = backend;
// Filled on the next UI refresh; safe even before Awake.
nextRefresh = 0;
}
private IReadOnlyList<BuiltObjectSnapshot> GetSupplyObjects()
{
if (!HasSupplyBackend)
return placement && placement.Backend != null ? placement.Backend.BuiltObjects : null;
supplyState = SupplyBackend.ReadState();
supplyObjects.Clear();
if (supplyState?.towers != null)
foreach (var t in supplyState.towers)
if (t != null && t.type) supplyObjects.Add(new BuiltObjectSnapshot { instanceId = t.instanceId, type = t.type });
Priority = supplyState == null ? -1 : (int)supplyState.priority;
RenderPriority(); RenderAmounts();
return supplyObjects;
}
private TowerSupplyState FindTower(long id)
{
if (supplyState?.towers != null) foreach (var t in supplyState.towers) if (t != null && t.instanceId == id) return t;
return null;
}
private bool TrySetBackendConnection(long id, bool connected)
{
if (!HasSupplyBackend) return false;
var result = SupplyBackend.SetConnected(id, connected);
if (result.accepted) ConnectionChanged?.Invoke(id, connected);
else ShowCommandMessage(result.message);
RefreshConnections(); return true;
}
private bool TrySetBackendPriority(int kind)
{
if (!HasSupplyBackend) return false;
int desired = Priority == kind ? -1 : kind;
var result = SupplyBackend.SetPriority((SupplyKind)desired);
if (result.accepted) PriorityChanged?.Invoke(desired);
else ShowCommandMessage(result.message);
RefreshConnections(); return true;
}
private void ShowCommandMessage(string message)
{ truckStatus.text = string.IsNullOrWhiteSpace(message) ? "Aktion derzeit nicht möglich" : message; commandMessageUntil = Time.unscaledTime + 2; }
private void RenderPriority()
{
for (int i = 0; i < priorityButtons.Length; i++)
{
priorityButtons[i].GetComponent<UnityEngine.UI.Image>().color = Priority == i ? ColorFor(i) : new Color(.72f,.72f,.72f);
priorityLabels[i].text = Priority == i ? "Vorrang aktiv" : "Vorrang geben";
}
}
private static string Amount(float value, float capacity)
=> Mathf.Max(0,value).ToString("0.#") + " / " + Mathf.Max(0,capacity).ToString("0.#");
private void RenderAmounts()
{
for (int i = 0; i < 3; i++)
{
SupplyChannelState channel = null;
if (supplyState?.channels != null) foreach (var item in supplyState.channels) if (item != null && (int)item.kind == i) { channel = item; break; }
if (storageAmounts != null && i < storageAmounts.Length && storageAmounts[i]) storageAmounts[i].text = channel == null ? "— / —" : Amount(channel.storage, channel.storageCapacity);
if (bufferAmounts != null && i < bufferAmounts.Length && bufferAmounts[i]) bufferAmounts[i].text = channel == null ? "Vorrat: —" : Amount(channel.buffer, channel.bufferCapacity);
}
}
private void RenderMagazine(int slot, long id)
{
if (magazineAmounts == null || slot >= magazineAmounts.Length || !magazineAmounts[slot]) return;
var state = HasSupplyBackend ? FindTower(id) : null;
magazineAmounts[slot].gameObject.SetActive(state != null);
if (state != null) magazineAmounts[slot].text = "Magazin: " + Amount(state.magazine, state.magazineCapacity);
}
private float StopX(SupplyStop stop) => stop == SupplyStop.Distributor ? unloadingPosition : loadingPositions[Mathf.Clamp((int)stop,0,2)];
private void RenderBackendTruck()
{
var state = supplyState?.truck;
if (state == null) { if(Time.unscaledTime >= commandMessageUntil)truckStatus.text = "LKW bereit"; return; }
var p = truck.anchoredPosition;
p.x = state.phase == SupplyTruckPhase.Driving
? Mathf.Lerp(StopX(state.from), StopX(state.to), Mathf.Clamp01(state.progress)) : StopX(state.to);
truck.anchoredPosition = p;
float direction = StopX(state.to) - StopX(state.from);
if (state.phase == SupplyTruckPhase.Driving && Mathf.Abs(direction) > .1f)
truck.localScale = new Vector3(Mathf.Abs(truckScale.x)*Mathf.Sign(direction),truckScale.y,truckScale.z);
if(Time.unscaledTime < commandMessageUntil)return;
string phase = state.phase == SupplyTruckPhase.Loading ? "Beladen" : state.phase == SupplyTruckPhase.Unloading ? "Abladen" : state.phase == SupplyTruckPhase.Driving ? "Unterwegs" : "Bereit";
int kind = (int)state.cargoKind;
truckStatus.text = phase + (kind >= 0 && kind < kinds.Length ? " · " + kinds[kind] + " " + Amount(state.cargo,state.cargoCapacity) : "");
}
}
}