using UnityEngine; namespace DanieleMarotta.RiversongCodeShowcase { [GameSystemGroup(typeof(EconomySystemGroup))] [UpdateAfter(typeof(ProductionRequirementsGameSystem))] public class ProductionTickGameSystem : GameSystem, IUpdatable { [InjectService] private GameConfig _config; [InjectService] private World _world; [InjectService] private IEntityCache _entityCache; public ProductionTickGameSystem(IServiceLocator serviceLocator) : base(serviceLocator) { } public void Update() { if (_world.TimeState.DayNightCycleStep != DayNightCycleStep.Day) return; var state = _world.ProductionState; state.ProductionTickTimer += Time.deltaTime; if (state.ProductionTickTimer < _config.Economy.ProductionTickInterval) return; state.ProductionTickTimer = 0; ProductionTick(); } private void ProductionTick() { var laborEfficiencyModifier = _world.ProductionState.LaborEfficiencyModifier; foreach (var producer in _entityCache.GetProducers()) { ref var storage = ref producer.GetStorageRW(); ref var productionState = ref producer.GetProductionStateRW(); ref var recipe = ref productionState.Recipe; if (productionState.State == ProducerState.NotWorking) { if (!productionState.AllRequirementsMet || !storage.ReservePutting(recipe.OutputProductHandle, recipe.OutputAmount)) continue; foreach (var (productHandle, amount) in recipe.Inputs) storage.Take(productHandle, amount); productionState.State = ProducerState.Working; } ref var sleepState = ref producer.GetSleepStateRW(); var efficiencyMultiplier = Mathf.Max(0, 1 + sleepState.EfficiencyModifier + laborEfficiencyModifier); productionState.Progress += Mathf.RoundToInt(1000 * efficiencyMultiplier); if (productionState.Progress < 1000 * recipe.ProductionTime) continue; productionState.Progress = 0; if (!storage.FulfillPut(recipe.OutputProductHandle, recipe.OutputAmount)) Debug.LogError("Producer failed fulfilling put"); productionState.State = ProducerState.NotWorking; } } } }