using System; using Cysharp.Threading.Tasks; using Unity.Mathematics; namespace DanieleMarotta.RiversongCodeShowcase { [InitializeAfter(typeof(PopulationNeedsSystem))] public class TierUpgradeSystem : GameSystem, IInitializable, IDisposable, IUpdatable { [InjectService] private IEntityCache _entityCache; [InjectService] private IProductStorageCommonLogic _storageCommonLogic; [InjectService] private ISignalBus _signalBus; [InjectService] private GameConfig _config; public TierUpgradeSystem(IServiceLocator serviceLocator) : base(serviceLocator) { } public UniTask InitializeAsync() { _signalBus.Subscribe(OnEndOfWeek); return UniTask.CompletedTask; } public void Dispose() { _signalBus.Unsubscribe(OnEndOfWeek); } private void OnEndOfWeek(EndOfWeekSignal signal) { var config = _config.Buildings; foreach (var house in _entityCache.GetHouses()) { ref var needsState = ref house.GetNeedsStateRW(); if (needsState.UpgradeState != TierUpgradeState.NotReady || !needsState.AllNeedsMet || needsState.NeedsMetForWeeks < config.WeeksWithNeedsMetToUpgrade) continue; needsState.UpgradeState = TierUpgradeState.FetchingMaterials; } } public void Update() { foreach (var house in _entityCache.GetHouses()) { ref var needsState = ref house.GetNeedsStateRW(); if (needsState.UpgradeState != TierUpgradeState.FetchingMaterials) continue; var products = house.Definition.HouseTiers[house.TierIndex].UpgradeMaterials; ref var storage = ref house.GetStorageRW(); if (!_storageCommonLogic.TakeAllOrNothing(ref storage, products)) continue; needsState.UpgradeState = TierUpgradeState.AllMaterialsFetched; _ = UpgradeBuildingAsync(house); } } private async UniTask UpgradeBuildingAsync(Building house) { await UniTask.WaitForSeconds(1); house.TierIndex++; var tiers = house.Definition.HouseTiers; house.PopulationCapacity = tiers[math.min(house.TierIndex, tiers.Count - 1)].Capacity; _signalBus.Raise(new BuildingUpgradedSignal(house)); OnBuildingUpgraded(house); } private void OnBuildingUpgraded(Building house) { var maxTier = house.Definition.HouseTiers.Count - 1; ref var needsState = ref house.GetNeedsStateRW(); needsState.UpgradeState = house.TierIndex < maxTier ? TierUpgradeState.NotReady : TierUpgradeState.MaxedOut; } } }