using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; namespace DepthsOfGreed.HandbookUI { public sealed class HandbookStatisticsController : MonoBehaviour { public SupplyBasementController supplyView; public TestPlacementController placement; public TMP_Text resourcesText,emptyText; public TMP_Text[] channelTitles,channelStocks,channelRates,channelTimes; public TMP_Text[] towerNames,towerMagazines,towerRates; public GameObject[] towerRows; public Button perSecondButton,perMinuteButton; public TMP_Text rateHeading; private bool perMinute=true; private float nextRefresh; private readonly List towers=new List(); private readonly string[] names={"Physisch","Energiezellen","Sondermunition"}; void Awake(){perSecondButton.onClick.AddListener(()=>SetUnit(false));perMinuteButton.onClick.AddListener(()=>SetUnit(true));} void OnEnable(){nextRefresh=0;} public void SetUnit(bool minute){perMinute=minute;nextRefresh=0;} public static string FormatRate(float? rate,bool minute) { if(!rate.HasValue || float.IsNaN(rate.Value) || float.IsInfinity(rate.Value) || rate.Value<0)return "—"; return (rate.Value*(minute?60:1)).ToString("0.#")+(minute?" / min":" / s"); } public static string Estimate(float buffer,float? rate) { if(!rate.HasValue || float.IsNaN(rate.Value) || float.IsInfinity(rate.Value) || rate.Value<0)return "—"; if(rate.Value==0)return "kein Verbrauch"; float seconds=Mathf.Max(0,buffer)/rate.Value; if(seconds>5999)return "> 99 min"; int rounded=Mathf.CeilToInt(seconds);return "ca. "+(rounded/60).ToString("00")+":"+(rounded%60).ToString("00"); } void Update(){if(Time.unscaledTime().color=perMinute?new Color(.82f,.82f,.82f):new Color(.55f,.55f,.55f); perMinuteButton.GetComponent().color=perMinute?new Color(.55f,.55f,.55f):new Color(.82f,.82f,.82f); rateHeading.text=perMinute?"Verbrauch / min":"Verbrauch / s"; for(int i=0;i<3;i++) { SupplyChannelState channel=null; if(state?.channels!=null)foreach(var c in state.channels)if(c!=null && (int)c.kind==i){channel=c;break;} channelTitles[i].text=names[i]; channelStocks[i].text=channel==null?"Lager — · Verteiler —":"Lager "+channel.storage.ToString("0.#")+" / "+channel.storageCapacity.ToString("0.#")+"\nVerteiler "+channel.buffer.ToString("0.#")+" / "+channel.bufferCapacity.ToString("0.#"); channelRates[i].text="Verbrauch: "+FormatRate(channel?.consumedPerSecond,perMinute); channelTimes[i].text="Verteiler ohne Nachschub: "+Estimate(channel==null?0:channel.buffer,channel?.consumedPerSecond); } towers.Clear(); if(state?.towers!=null){foreach(var t in state.towers)if(t!=null && t.type)towers.Add(t);} else if(placement && placement.Backend!=null && !(supplyView && supplyView.HasSupplyBackend)) foreach(var t in placement.Backend.BuiltObjects)if(t.type && t.type.supply.kind!=SupplyKind.None) towers.Add(new TowerSupplyState{instanceId=t.instanceId,type=t.type,magazine=-1,magazineCapacity=-1}); towers.Sort((a,b)=>{int type=string.CompareOrdinal(a.type.id,b.type.id);return type!=0?type:a.instanceId.CompareTo(b.instanceId);}); emptyText.gameObject.SetActive(towers.Count==0); for(int i=0;i=towers.Count)continue;var t=towers[i]; towerNames[i].text=t.type.displayName+" #"+t.instanceId; towerMagazines[i].text=t.magazine<0?"—":t.magazine.ToString("0.#")+" / "+t.magazineCapacity.ToString("0.#"); towerRates[i].text=FormatRate(t.consumedPerSecond,perMinute); } } } }