private void UpdateBudget(EconomyManager eco, ref District district, ItemClass.Service service, ItemClass.SubService subService = ItemClass.SubService.None) { try { int capacity = 0; int incineratorElectricityCapacity = 0; int consumption = 0; switch (service) { case ItemClass.Service.Electricity: capacity = GetTotalCapacity(ItemClass.Service.Electricity, (ref Building data, PowerPlantAI ai) => { //return ai.GetElectricityRate(0, ref data); int min; int max; ai.GetElectricityProduction(out min, out max); if (ai is WindTurbineAI) { // Get the wind for the specific area. var turbineProduction = Mathf.RoundToInt(PlayerBuildingAI.GetProductionRate(data.m_productionRate, 100) * Singleton <WeatherManager> .instance.SampleWindSpeed(data.m_position, false)); return(turbineProduction * max / 100); } if (ai is SolarPowerPlantAI) { var solarPowerProduction = Mathf.RoundToInt(PlayerBuildingAI.GetProductionRate(data.m_productionRate, 100) * Singleton <WeatherManager> .instance.SampleSunIntensity(data.m_position, false)); return(solarPowerProduction * max / 100); } if (ai is DamPowerHouseAI) { var damProduction = (data.m_productionRate * 100 / 100 * data.GetLastFrameData().m_productionState + 99) / 100; return(damProduction * max / 100); } if (ai is FusionPowerPlantAI) { max = 1000000; } int a; var productionRate = data.m_productionRate; if ((data.m_flags & Building.Flags.Active) != Building.Flags.None) { a = PlayerBuildingAI.GetProductionRate(productionRate, 100); if (ai.m_resourceType != TransferManager.TransferReason.None) { int num = (int)data.m_customBuffer1; a = Mathf.Min(a, num / (ai.m_resourceCapacity / 400) + 10); } } else { a = 0; } return(a * max / 100); }) * 16; // Now check for incinerators, as they also add to our max capacity, but seperatly since we arent adjusting their output wit the electricity slider!!! incineratorElectricityCapacity = GetTotalCapacity(ItemClass.Service.Garbage, (ref Building data, LandfillSiteAI ai) => { if (ai.m_electricityProduction != 0) { return(ai.GetElectricityRate(data.Info.m_instanceID.Building, ref data)); } return(0); }) * 16; consumption = district.GetElectricityConsumption(); break; case ItemClass.Service.Water: var sewageConsumption = district.GetSewageAccumulation(); var waterConsumption = district.GetWaterConsumption(); var waterCapacity = GetTotalCapacity(ItemClass.Service.Water, (ref Building data, WaterFacilityAI ai) => { if (ai.m_waterIntake == 0) { return(0); } if (ai.m_useGroundWater || data.m_waterSource != 0) { return(ai.m_waterIntake * data.m_productionRate / 100); } return(0); }) * 16; var sewageCapacity = GetTotalCapacity(ItemClass.Service.Water, (ref Building data, WaterFacilityAI ai) => { if (ai.m_sewageOutlet == 0) { return(0); } if (ai.m_useGroundWater || data.m_waterSource != 0) { return(ai.m_sewageOutlet * data.m_productionRate / 100); } return(0); }) * 16; // Use the higher consumption here so we get accurate results // The water/sewage is tied together on the same budget. if (GetPercentage(waterCapacity, waterConsumption) > GetPercentage(sewageCapacity, sewageConsumption)) { capacity = sewageCapacity; consumption = sewageConsumption; } else { capacity = waterCapacity; consumption = waterConsumption; } break; case ItemClass.Service.Garbage: consumption = district.GetGarbageAccumulation(); capacity = GetTotalCapacity(ItemClass.Service.Garbage, (ref Building data, LandfillSiteAI ai) => { if (ai.m_electricityProduction != 0) { return((PlayerBuildingAI.GetProductionRate(data.m_productionRate, 100) * ai.m_garbageConsumption + 99) / 100); } return(0); }) * 16; break; } if (capacity == 0 || consumption == 0) { return; } int budget; for (budget = 50; budget < 150; budget++) { if (GetProductionRate(capacity, budget) + incineratorElectricityCapacity >= consumption) { break; } } // How much of our capacity do we need to meet our demands? // This is odd for water specifically. if (AutoBudgetSettings.instance.debug) { consumption += incineratorElectricityCapacity; var neededUsage = Mathf.CeilToInt(((float)consumption / capacity) * 100); DebugMessage("Service: " + service + ", Capacity: " + capacity + ", Consumption: " + consumption + ", Budget: " + budget + ". Buffer: " + AutoBudgetSettings.instance.buffers[(int)service] + ", Needed: " + neededUsage); } // Add 2% to the required amount so we don't end up with crazy stuff happening // When there are big "booms" in player buildings. eco.SetBudget(service, subService, Mathf.Clamp(budget + AutoBudgetSettings.instance.buffers[(int)service], 50, 150), SimulationManager.instance.m_isNightTime); } catch (Exception ex) { Debug.LogException(ex); } }