using System.Collections.Generic; using AfterHours.Core; using AfterHours.Data; using AfterHours.Shop; using Unity.Netcode; using UnityEngine; namespace AfterHours.Economy { /// /// Bestellungen beim Großhandel: Ware wird sofort bezahlt, trifft aber /// erst nach einer Lieferzeit in der passenden Lagerkiste ein. Nur Server. /// public sealed class SupplierService : NetworkBehaviour { public static SupplierService Instance { get; private set; } [SerializeField] private ProductCatalog _catalog; [SerializeField] private float _deliveryLeadHours = 4f; private readonly List _pending = new(); private void Awake() => Instance = this; public override void OnNetworkDespawn() { if (Instance == this) Instance = null; } private void Update() { if (!IsServer || GameClock.Instance == null) return; float now = GameClock.Instance.TotalHours; for (int i = _pending.Count - 1; i >= 0; i--) { if (now < _pending[i].DeliveryTime) continue; Deliver(_pending[i]); _pending.RemoveAt(i); } } /// Server: Bestellung aufgeben. False, wenn Produkt unbekannt oder Geld nicht reicht. public bool PlaceOrder(int productId, int quantity) { if (!IsServer || quantity <= 0) return false; if (!_catalog.TryGet(productId, out var product)) return false; float cost = product.WholesalePrice * quantity; if (!ShopEconomy.Instance.TrySpend(cost)) return false; var order = new PurchaseOrder { DeliveryTime = GameClock.Instance.TotalHours + _deliveryLeadHours }; order.Add(productId, quantity, product.WholesalePrice); _pending.Add(order); return true; } private void Deliver(PurchaseOrder order) { order.Delivered = true; foreach (var line in order.Lines) { var crate = StorageCrateRegistry.Instance.FindFor(line.ProductId); if (crate == null) { Debug.LogWarning($"[SupplierService] Keine Lagerkiste für ProductId {line.ProductId} — Lieferung verworfen."); continue; } crate.Restock(line.Quantity); } } } }