Esempio n. 1
0
        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);
            }
        }