public static bool CanAddVehicle(ushort depotID, ref Building depot)
        {
            DepotAI buildingAi = depot.Info.m_buildingAI as DepotAI;
            int     num        = (PlayerBuildingAI.GetProductionRate(100, Singleton <EconomyManager> .instance.GetBudget(buildingAi.m_info.m_class)) * buildingAi.m_maxVehicleCount + 99) / 100;

            return(buildingAi.GetVehicleCount(depotID, ref depot) < num);
        }
        public static bool CanOperation(ushort buildingID, ref Building buildingData, bool userReject = true)
        {
            if ((MainDataStore.resourceCategory[buildingID] == 4) && userReject)
            {
                return(false);
            }

            if (ResourceBuildingAI.IsSpecialBuilding(buildingID))
            {
                return(false);
            }

            if (buildingData.Info.m_buildingAI is ParkBuildingAI)
            {
                return(false);
            }

            if (buildingData.Info.m_buildingAI is CampusBuildingAI)
            {
                return(false);
            }

            if (buildingData.Info.m_class.m_service == ItemClass.Service.Beautification)
            {
                return(false);
            }
            PlayerBuildingAI AI = buildingData.Info.m_buildingAI as PlayerBuildingAI;

            return(AI.RequireRoadAccess());
        }
Пример #3
0
        public static bool IsGasBuilding(ushort id, bool fastCheck = true)
        {
            if (!fastCheck)
            {
                var buildingData = Singleton <BuildingManager> .instance.m_buildings.m_buffer[id];
                if (buildingData.Info.m_buildingAI is ParkBuildingAI)
                {
                    return(false);
                }

                if (buildingData.Info.m_buildingAI is CampusBuildingAI)
                {
                    return(false);
                }

                PlayerBuildingAI AI = buildingData.Info.m_buildingAI as PlayerBuildingAI;
                if (AI.RequireRoadAccess() == false)
                {
                    return(false);
                }
            }

            if (MainDataStore.resourceCategory[id] != 0)
            {
                return(true);
            }
            return(false);
        }
Пример #4
0
 public static bool CanAddVehicle(ushort depotID, ref Building depot, TransportInfo transportInfo)
 {
     if (depot.Info == null)
     {
         return(false);
     }
     if (depot.Info.m_buildingAI is DepotAI)
     {
         DepotAI buildingAi = depot.Info.m_buildingAI as DepotAI;
         if (transportInfo.m_vehicleType == buildingAi.m_transportInfo?.m_vehicleType ||
             transportInfo.m_vehicleType == buildingAi.m_secondaryTransportInfo?.m_vehicleType)
         {
             int num = (PlayerBuildingAI.GetProductionRate(100,
                                                           Singleton <EconomyManager> .instance.GetBudget(buildingAi.m_info.m_class)) *
                        buildingAi.m_maxVehicleCount + 99) / 100;
             return(buildingAi.GetVehicleCount(depotID, ref depot) < num);
         }
     }
     if (depot.Info.m_buildingAI is ShelterAI)
     {
         ShelterAI buildingAi = depot.Info.m_buildingAI as ShelterAI;
         int       num        = (PlayerBuildingAI.GetProductionRate(100, Singleton <EconomyManager> .instance.GetBudget(buildingAi.m_info.m_class)) * buildingAi.m_evacuationBusCount + 99) / 100;
         int       count      = 0;
         int       cargo      = 0;
         int       capacity   = 0;
         int       outside    = 0;
         CommonBuildingAIReverseDetour.CalculateOwnVehicles(buildingAi, depotID, ref depot, buildingAi.m_transportInfo.m_vehicleReason, ref count, ref cargo, ref capacity, ref outside);
         return(count < num);
     }
     return(false);
 }
Пример #5
0
        public override int GetWaterRate(ushort buildingID, ref Building data)
        {
            int productionRate = (int)data.m_productionRate;
            int budget         = Singleton <EconomyManager> .instance.GetBudget(this.m_info.m_class);

            productionRate = PlayerBuildingAI.GetProductionRate(productionRate, budget);
            return(productionRate * (this.m_waterConsumption) / 100);
        }
        protected int getBudgetForVehicles(Type AIType, int vehiclesExcessNum, int minBudget, int maxBudget)
        {
            if (!Singleton <BuildingManager> .exists)
            {
                return(100);
            }

            int budget = Singleton <EconomyManager> .instance.GetBudget(GetService(), GetSubService(), Singleton <SimulationManager> .instance.m_isNightTime);

            int productionRate = PlayerBuildingAI.GetProductionRate(100, budget);

            int newBudget      = minBudget;
            int targetBldCount = 0;

            BuildingManager bm = Singleton <BuildingManager> .instance;

            foreach (ushort n in ServiceBuildingNs(GetService()))
            {
                Building bld = bm.m_buildings.m_buffer[(int)n];
                if ((bld.m_flags & Building.Flags.Active) == 0)
                {
                    continue;
                }

                if (bld.Info.m_buildingAI.GetType() == AIType)
                {
                    int normalVehicleCapacity  = getNormalVehicleCapacity(ref bld);
                    int currentVehicleCapacity = (productionRate * normalVehicleCapacity + 99) / 100;
                    int vehiclesInUse          = countVehiclesInUse(ref bld);

                    if (vehiclesInUse + vehiclesExcessNum == currentVehicleCapacity)
                    {
                        // Perfect number of vehicles
                        newBudget = Math.Max(newBudget, budget);
                    }
                    else
                    {
                        int targetVehiclesCount = vehiclesInUse + vehiclesExcessNum;
                        int bldTargetBudget     = getMinimumBudgetToGetVehicles(normalVehicleCapacity, targetVehiclesCount, maxBudget);
                        newBudget = Math.Max(newBudget, bldTargetBudget);
                    }

                    targetBldCount++;
                }
            }
            //Debug.Log(string.Format("New budget: {0}", newBudget));

            if (targetBldCount > 0)
            {
                return(newBudget);
            }
            else
            {
                return(-1);
            }
        }
        public static bool CanWareHouseTransfer(TransferOffer offerIn, TransferOffer offerOut, TransferReason material)
        {
            BuildingManager bM = Singleton <BuildingManager> .instance;

            if (offerIn.Building == 0 || offerIn.Building > Singleton <BuildingManager> .instance.m_buildings.m_size)
            {
                return(true);
            }

            if (offerOut.Building == 0 || offerOut.Building > Singleton <BuildingManager> .instance.m_buildings.m_size)
            {
                return(true);
            }

            if (bM.m_buildings.m_buffer[offerOut.Building].Info.m_buildingAI is WarehouseAI)
            {
                if (bM.m_buildings.m_buffer[offerIn.Building].Info.m_buildingAI is OutsideConnectionAI)
                {
                    if (MoreEffectiveTransfer.warehouseAdvancedBalance)
                    {
                        var AI = bM.m_buildings.m_buffer[offerOut.Building].Info.m_buildingAI as WarehouseAI;
                        TransferManager.TransferReason actualTransferReason = AI.GetActualTransferReason(offerOut.Building, ref bM.m_buildings.m_buffer[offerOut.Building]);
                        if (actualTransferReason != TransferManager.TransferReason.None)
                        {
                            int budget = Singleton <EconomyManager> .instance.GetBudget(AI.m_info.m_class);

                            int productionRate = PlayerBuildingAI.GetProductionRate(100, budget);
                            int num            = (productionRate * AI.m_truckCount + 99) / 100;
                            int num2           = 0;
                            int num3           = 0;
                            int num4           = 0;
                            int num5           = 0;
                            CustomCommonBuildingAI.InitDelegate();
                            CustomCommonBuildingAI.CalculateOwnVehicles(AI, offerOut.Building, ref bM.m_buildings.m_buffer[offerOut.Building], actualTransferReason, ref num2, ref num3, ref num4, ref num5);
                            if (num2 * 1.25f > (num - 1))
                            {
                                return(false);
                            }
                            else
                            {
                                return(true);
                            }
                        }
                    }
                    else
                    {
                        return(true);
                    }
                }
            }

            return(true);
        }
        public static RI_BuildingFactor GetFactorBuilding(PlayerBuildingAI ai)
        {
            if (ai is ExtractingFacilityAI)
            {
                if (Mod.IsField(ai)) // Extracting farms don't use .Workers, they're redone from scratch
                {
                    return(new RI_BuildingFactor {
                        Costs = 4m, Production = 2m, Workers = 1m
                    });
                }
                return(new RI_BuildingFactor {
                    Costs = 1m, Production = 1m, Workers = 2m
                });
            }
            if (ai is ProcessingFacilityAI)
            {
                if (Mod.IsField(ai)) // Pasture
                {
                    return(new RI_BuildingFactor {
                        Costs = 2m, Production = 1m, Workers = 3m
                    });
                }
            }
            if (ai is WarehouseAI ai_w)
            {
                // Warehouse production affects truck count (unused for Extractor Warehouses)
                switch (ai_w.m_storageType)
                {
                case TransferManager.TransferReason.Grain:
                    return(new RI_BuildingFactor {
                        Costs = 2m, Production = 1m, Workers = 4m
                    });

                case TransferManager.TransferReason.Logs:
                case TransferManager.TransferReason.Ore:
                case TransferManager.TransferReason.Oil:
                    return(new RI_BuildingFactor {
                        Costs = 1m, Production = 1m, Workers = 2m
                    });
                }
                return(new RI_BuildingFactor {
                    Costs = 0.5m, Production = 2m, Workers = 1m
                });
            }

            Mod.DebugLine($"GetFactorBuilding: Unknown PlayerBuildingAI={ai.name}");
            return(new RI_BuildingFactor {
                Costs = 1m, Production = 1m, Workers = 1m
            });
        }
        public static RI_EmployeeRatio GetEmployeeRatio(PlayerBuildingAI ai)
        {
            if (ai is IndustryBuildingAI)
            {
                return(_getEmployeeRatioIB((IndustryBuildingAI)ai));
            }
            if (ai is WarehouseAI)
            {
                return(_getEmployeeRatioW((WarehouseAI)ai));
            }

            Mod.DebugLine($"GetEmployeeRatio: Unknown PlayerBuildingAI={ai.name}");
            return(new RI_EmployeeRatio {
                Level = new int[] { 1, 1, 1, 1 }
            });
        }
Пример #10
0
        public void CaluculateWorkingVehicles(out int max, out int now)
        {
            max = (PlayerBuildingAI.GetProductionRate(100, Singleton <EconomyManager> .instance.GetBudget(Singleton <BuildingManager> .instance.m_buildings.m_buffer[_buildingID].Info.m_class)) * ((LandfillSiteAI)Singleton <BuildingManager> .instance.m_buildings.m_buffer[_buildingID].Info.m_buildingAI).m_garbageTruckCount + 99) / 100;
            now = 0;
            VehicleManager instance = Singleton <VehicleManager> .instance;
            ushort         num      = Singleton <BuildingManager> .instance.m_buildings.m_buffer[_buildingID].m_ownVehicles;

            while (num != 0)
            {
                if ((TransferManager.TransferReason)instance.m_vehicles.m_buffer[(int)num].m_transferType == TransferManager.TransferReason.Garbage)
                {
                    now++;
                }
                num = instance.m_vehicles.m_buffer[(int)num].m_nextOwnVehicle;
            }
        }
Пример #11
0
 private static void RevertBuilding(ref BuildingInfo info)
 {
     if (m_CpmNetDict != null)
     {
         for (int j = 0; j < info.m_paths.Count(); j++)
         {
             NetInfo ninfo = info.m_paths[j].m_netInfo;
             if (m_CpmNetDict.ContainsKey(ninfo.name))
             {
                 if (ninfo.m_netAI != null)
                 {
                     PlayerNetAI pnai = ninfo.GetComponent <PlayerNetAI>();
                     if (pnai != null)
                     {
                         pnai.m_createPassMilestone = m_CpmNetDict[ninfo.name];
                     }
                 }
             }
         }
     }
     if (m_CpmBuildingDict != null)
     {
         if (m_CpmBuildingDict.ContainsKey(info.name))
         {
             PlayerBuildingAI pbai = info.GetComponent <PlayerBuildingAI>();
             if (pbai != null)
             {
                 pbai.m_createPassMilestone  = m_CpmBuildingDict[info.name][0];
                 pbai.m_createPassMilestone2 = m_CpmBuildingDict[info.name][1];
                 pbai.m_createPassMilestone3 = m_CpmBuildingDict[info.name][2];
                 info.m_buildingAI           = pbai;
                 if (info.m_subBuildings != null && info.m_subBuildings.Count() > 0)
                 {
                     foreach (BuildingInfo.SubInfo subBuilding in info.m_subBuildings)
                     {
                         if (subBuilding.m_buildingInfo != null)
                         {
                             RevertBuilding(ref subBuilding.m_buildingInfo);
                         }
                     }
                 }
             }
         }
     }
 }
        private void _switchWorkPlaces(PlayerBuildingAI ai, int minimumSize, ref int wp0, ref int wp1, ref int wp2, ref int wp3)
        {
            int oldTotal           = wp0 + wp1 + wp2 + wp3;
            RI_EmployeeRatio ratio = RI_Data.GetEmployeeRatio(ai);

            if (oldTotal >= minimumSize)
            {
                decimal factor = RI_Data.GetFactorBuilding(ai).Workers;
                //Mod.DebugLine($"{ai.name} - AI: {ai.GetType().ToString()}, factor: {factor}x");
                //Mod.DebugLine($"    _switchWorkplaces: old={oldTotal}; wp0={wp0}, wp1={wp1}, wp2={wp2}, wp3={wp3}");
                wp0 = Convert.ToInt32(Math.Round(wp0 / factor));
                wp1 = Convert.ToInt32(Math.Round(wp1 / factor));
                wp2 = Convert.ToInt32(Math.Round(wp2 / factor));
                wp3 = Convert.ToInt32(Math.Round(wp3 / factor));
                //Mod.DebugLine($"    _switchWorkplaces: new={wp0 + wp1 + wp2 + wp3}; wp0={wp0}, wp1={wp1}, wp2={wp2}, wp3={wp3}");
                //Mod.DebugLine($"");
            }
        }
Пример #13
0
        private static void RemoveCreatePassMileStone(ref BuildingInfo info)
        {
            PlayerBuildingAI pbai = info.GetComponent <PlayerBuildingAI>();

            if (pbai != null)
            {
                if (pbai.m_createPassMilestone != null)
                {
                    if (m_CpmBuildingDict == null)
                    {
                        m_CpmBuildingDict = new Dictionary <string, List <ManualMilestone> >();
                    }
                    if (m_CpmBuildingDict.ContainsKey(info.name) == false)
                    {
                        m_CpmBuildingDict.Add(info.name, new List <ManualMilestone>());
                    }
                    m_CpmBuildingDict[info.name].Add(pbai.m_createPassMilestone);
                    m_CpmBuildingDict[info.name].Add(pbai.m_createPassMilestone2);
                    m_CpmBuildingDict[info.name].Add(pbai.m_createPassMilestone3);
                    pbai.m_createPassMilestone  = null;
                    pbai.m_createPassMilestone2 = null;
                    pbai.m_createPassMilestone3 = null;
                    info.m_buildingAI           = pbai;
                }
                foreach (BuildingInfo.PathInfo path in info.m_paths)
                {
                    if (path.m_netInfo != null)
                    {
                        RemoveCreatePassMileStone(path.m_netInfo);
                    }
                }
                if (info.m_subBuildings != null)
                {
                    foreach (var subBuilding in info.m_subBuildings)
                    {
                        if (subBuilding.m_buildingInfo != null)
                        {
                            RemoveCreatePassMileStone(ref subBuilding.m_buildingInfo);
                        }
                    }
                }
            }
        }
Пример #14
0
        public override string GetLocalizedStats(ushort buildingID, ref Building data)
        {
            string str = string.Empty;

            if ((UnityEngine.Object) this.m_transportInfo != (UnityEngine.Object)null && this.m_maxVehicleCount != 0)
            {
                switch (this.m_transportInfo.m_transportType)
                {
                case TransportInfo.TransportType.Taxi:
                    int vehicleCount1 = this.GetVehicleCount(buildingID, ref data);
                    int num1          = (PlayerBuildingAI.GetProductionRate(100, Singleton <EconomyManager> .instance.GetBudget(this.m_info.m_class)) * this.m_maxVehicleCount + 99) / 100;
                    str += LocaleFormatter.FormatGeneric("AIINFO_TAXIDEPOT_VEHICLES", (object)vehicleCount1, (object)num1);
                    break;

                case TransportInfo.TransportType.Tram:
                    int vehicleCount2 = this.GetVehicleCount(buildingID, ref data);
                    int num2          = (PlayerBuildingAI.GetProductionRate(100, Singleton <EconomyManager> .instance.GetBudget(this.m_info.m_class)) * this.m_maxVehicleCount + 99) / 100;
                    str += LocaleFormatter.FormatGeneric("AIINFO_TRAMDEPOT_TRAMCOUNT", (object)vehicleCount2, (object)num2);
                    break;

                case TransportInfo.TransportType.Bus:
                    int vehicleCount3 = this.GetVehicleCount(buildingID, ref data);
                    int num3          = (PlayerBuildingAI.GetProductionRate(100, Singleton <EconomyManager> .instance.GetBudget(this.m_info.m_class)) * this.m_maxVehicleCount + 99) / 100;
                    str += LocaleFormatter.FormatGeneric("AIINFO_BUSDEPOT_BUSCOUNT", (object)vehicleCount3, (object)num3);
                    break;

                //begin mod
                case TransportInfo.TransportType.Metro:
                    int vehicleCount4 = this.GetVehicleCount(buildingID, ref data);
                    int num4          = (PlayerBuildingAI.GetProductionRate(100, Singleton <EconomyManager> .instance.GetBudget(this.m_info.m_class)) * this.m_maxVehicleCount + 99) / 100;
                    str += $"Metro trains in use: {vehicleCount4}";    // of {num4}";
                    break;

                case TransportInfo.TransportType.Train:
                    int vehicleCount5 = this.GetVehicleCount(buildingID, ref data);
                    int num5          = (PlayerBuildingAI.GetProductionRate(100, Singleton <EconomyManager> .instance.GetBudget(this.m_info.m_class)) * this.m_maxVehicleCount + 99) / 100;
                    str += $"Trains in use: {vehicleCount5}";    // of {num5}";
                    break;
                    //end mod
                }
            }
            return(str);
        }
Пример #15
0
 public static bool IsField(PlayerBuildingAI ai)
 {
     if (ai is ExtractingFacilityAI)
     {
         if (ai.m_info.m_class.m_subService == ItemClass.SubService.PlayerIndustryFarming)
         {
             return(true);
         }
     }
     if (ai is ProcessingFacilityAI) // Rebalance pastures as fields
     {
         foreach (string name in RI_Data.GetProcessorFieldNameStarts())
         {
             if (ai.name.Length >= name.Length && ai.name.Substring(0, name.Length) == name)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
        protected int getMinimumBudgetToGetVehicles(int normalVehicleCapacity, int requiredVehiclesCount, int maxBudget)
        {
            // Should not be, but just in case...
            if (normalVehicleCapacity <= 0)
            {
                return(100);
            }

            int productionRate;
            int productionRateMax = PlayerBuildingAI.GetProductionRate(100, maxBudget);

            do
            {
                requiredVehiclesCount--;
                productionRate = requiredVehiclesCount * 100 / normalVehicleCapacity;
                if (productionRate < 25)
                {
                    return(50);
                }
            } while (productionRate >= productionRateMax);

            int budget;

            if (productionRate < 100)
            {
                budget = (int)Mathf.Sqrt(productionRate * 100);
            }
            else if (productionRate > 100)
            {
                budget = (int)(150f - 50f * Mathf.Sqrt(9f - 4f * (1f + productionRate / 100f)));
            }
            else
            {
                budget = 100;
            }
            budget += 1;

            return(budget);
        }
Пример #17
0
        private static MovableBridgeAIData StripCustomAI(PrefabInfo prefab)
        {
            if (prefab is BuildingInfo buildingInfo && buildingInfo.m_buildingAI is MovableBridgeAI customAI)
            {
                if (prefab.editorCategory != "MovableBridge")
                {
                    throw new Exception("Missing 'MovableBridge' editorCategory!");
                }

                PlayerBuildingAI vanillaAI = buildingInfo.gameObject.AddComponent <PlayerBuildingAI>();
                vanillaAI.CopyFrom(customAI);

                var data = new MovableBridgeAIData();
                data.CopyFrom(customAI);

                UnityEngine.Object.DestroyImmediate(customAI);

                buildingInfo.m_buildingAI = vanillaAI;
                vanillaAI.m_info          = buildingInfo;

                UnityEngine.Debug.Log("Stripped " + data.ToString());

                return(data);
            }
        public IEnumerator ScanForDisconnectedBuildings()
        {
            SearchProgress = 0.0f;
            BuildingManager bm = BuildingManager.instance;

            SearchStep       = 1.0f / bm.m_buildings.m_buffer.Length;
            SearchInProgress = true;
            DisconnectedBuildings.Clear();

            StringBuilder sb = new StringBuilder();

            sb.AppendLine("[BND] Scanning for disconnected buildings");
            sb.AppendLine("[BND] ");
            sb.AppendLine("[BND] =( Building ID )===( Location )=");
            sb.AppendLine();
            Building[] mBuffer        = bm.m_buildings.m_buffer;
            int        counter        = 0;
            MethodInfo findRoadAccess = typeof(PlayerBuildingAI).GetMethod("FindRoadAccess", BindingFlags.Instance | BindingFlags.NonPublic);

            for (uint i = 0; i < mBuffer.Length; i++)
            {
                Building building = mBuffer[i];

                if ((building.m_flags & Building.Flags.Created) != 0 && building.Info)
                {
                    if (building.Info.m_buildingAI is PlayerBuildingAI)
                    {
                        counter++;
                        PlayerBuildingAI buildingAI = building.Info.m_buildingAI as PlayerBuildingAI;
                        bool             connected  = true;
                        if ((building.m_flags & Building.Flags.Collapsed) == Building.Flags.None && buildingAI.RequireRoadAccess())
                        {
                            Vector3 position = buildingAI.m_info.m_zoningMode != BuildingInfo.ZoningMode.CornerLeft
                                ? (buildingAI.m_info.m_zoningMode != BuildingInfo.ZoningMode.CornerRight
                                    ? building.CalculateSidewalkPosition(0.0f, 4f)
                                    : building.CalculateSidewalkPosition(building.Width * -4f, 4f))
                                : building.CalculateSidewalkPosition(building.Width * 4f, 4f);
                            object[] args = { (ushort)i, building, position };
                            if (!(bool)findRoadAccess.Invoke(buildingAI, args))
                            {
                                connected = false;
                            }
                        }

                        if (!connected)
                        {
                            DisconnectedBuildings.Add(i, building.m_position);
                            sb.AppendLine("==(" + i + ")===(" + building.m_position + ")=");
                            sb.Append("building ")
                            .Append(" " + (building.Info ? building.Info.m_class.name : "") + " ")
                            .Append(building.m_flags.ToString())
                            .Append(" [name: ").Append(building.Info.name).Append("]");
                            sb.AppendLine("---------------------------------------");
                        }
                    }
                    else if ((building.m_flags & Building.Flags.RoadAccessFailed) != 0 || (building.m_problems & Notification.Problem.RoadNotConnected) != 0)
                    {
                        DisconnectedBuildings.Add(i, building.m_position);
                        sb.AppendLine("==(" + i + ")===(" + building.m_position + ")=");
                        sb.Append("building ")
                        .Append(" " + (building.Info ? building.Info.m_class.name : "") + " ")
                        .Append(building.m_flags.ToString())
                        .Append(" [name: ").Append(building.Info.name).Append("]");
                        sb.AppendLine("---------------------------------------");
                    }
                }

                SearchProgress = SearchStep * i;
                if (i % 128 == 0)
                {
                    yield return(null);
                }
            }

            SearchInProgress = false;
            Debug.Log("[BND] Disconnected building instances count: " + counter);
            Debug.Log("[BND] Scan report\n" + sb + "\n\n=======================================================");
        }
Пример #19
0
        public override string GetLocalizedStats(ushort buildingID, ref Building data)
        {
            string text = string.Empty;

            if ((UnityEngine.Object) this.m_transportInfo != (UnityEngine.Object)null && this.m_maxVehicleCount != 0)
            {
                switch (this.m_transportInfo.m_transportType)
                {
                case TransportInfo.TransportType.Bus:
                case TransportInfo.TransportType.TouristBus:
                {
                    int vehicleCount = this.GetVehicleCount(buildingID, ref data);
                    int budget       = Singleton <EconomyManager> .instance.GetBudget(this.m_info.m_class);

                    int productionRate = PlayerBuildingAI.GetProductionRate(100, budget);
                    int num            = (productionRate * this.m_maxVehicleCount + 99) / 100;
                    text += LocaleFormatter.FormatGeneric("AIINFO_BUSDEPOT_BUSCOUNT", new object[]
                        {
                            vehicleCount,
                            num
                        });
                    break;
                }

                case TransportInfo.TransportType.Ship:
                    if (this.m_transportInfo.m_vehicleType == VehicleInfo.VehicleType.Ferry)
                    {
                        int vehicleCount2 = this.GetVehicleCount(buildingID, ref data);
                        int budget2       = Singleton <EconomyManager> .instance.GetBudget(this.m_info.m_class);

                        int productionRate2 = PlayerBuildingAI.GetProductionRate(100, budget2);
                        int num2            = (productionRate2 * this.m_maxVehicleCount + 99) / 100;
                        text += LocaleFormatter.FormatGeneric("AIINFO_FERRYDEPOT_FERRYCOUNT", new object[]
                        {
                            vehicleCount2,
                            num2
                        });
                    }
                    break;

                case TransportInfo.TransportType.Airplane:
                    if (this.m_transportInfo.m_vehicleType == VehicleInfo.VehicleType.Blimp)
                    {
                        int vehicleCount3 = this.GetVehicleCount(buildingID, ref data);
                        int budget3       = Singleton <EconomyManager> .instance.GetBudget(this.m_info.m_class);

                        int productionRate3 = PlayerBuildingAI.GetProductionRate(100, budget3);
                        int num3            = (productionRate3 * this.m_maxVehicleCount + 99) / 100;
                        text += LocaleFormatter.FormatGeneric("AIINFO_BLIMPDEPOT_BLIMPCOUNT", new object[]
                        {
                            vehicleCount3,
                            num3
                        });
                    }
                    break;

                case TransportInfo.TransportType.Taxi:
                {
                    int vehicleCount4 = this.GetVehicleCount(buildingID, ref data);
                    int budget4       = Singleton <EconomyManager> .instance.GetBudget(this.m_info.m_class);

                    int productionRate4 = PlayerBuildingAI.GetProductionRate(100, budget4);
                    int num4            = (productionRate4 * this.m_maxVehicleCount + 99) / 100;
                    text += LocaleFormatter.FormatGeneric("AIINFO_TAXIDEPOT_VEHICLES", new object[]
                        {
                            vehicleCount4,
                            num4
                        });
                    break;
                }

                case TransportInfo.TransportType.Tram:
                {
                    int vehicleCount5 = this.GetVehicleCount(buildingID, ref data);
                    int budget5       = Singleton <EconomyManager> .instance.GetBudget(this.m_info.m_class);

                    int productionRate5 = PlayerBuildingAI.GetProductionRate(100, budget5);
                    int num5            = (productionRate5 * this.m_maxVehicleCount + 99) / 100;
                    text += LocaleFormatter.FormatGeneric("AIINFO_TRAMDEPOT_TRAMCOUNT", new object[]
                        {
                            vehicleCount5,
                            num5
                        });
                    break;
                }

                //begin mod
                case TransportInfo.TransportType.Metro:
                {
                    int vehicleCount6 = this.GetVehicleCount(buildingID, ref data);
                    int budget6       = Singleton <EconomyManager> .instance.GetBudget(this.m_info.m_class);

                    int productionRate6 = PlayerBuildingAI.GetProductionRate(100, budget6);
                    int num6            = (productionRate6 * this.m_maxVehicleCount + 99) / 100;
                    text += LocaleFormatter.FormatGeneric("AIINFO_TRAMDEPOT_TRAMCOUNT", new object[]
                        {
                            vehicleCount6,
                            num6
                        }).Replace("Tram", "Metro");
                    break;
                }

                case TransportInfo.TransportType.Train:
                {
                    int vehicleCount7 = this.GetVehicleCount(buildingID, ref data);
                    int budget7       = Singleton <EconomyManager> .instance.GetBudget(this.m_info.m_class);

                    int productionRate7 = PlayerBuildingAI.GetProductionRate(100, budget7);
                    int num7            = (productionRate7 * this.m_maxVehicleCount + 99) / 100;
                    text += LocaleFormatter.FormatGeneric("AIINFO_TRAMDEPOT_TRAMCOUNT", new object[]
                        {
                            vehicleCount7,
                            num7
                        }).Replace("Tram", "Train");
                    break;
                    //end mod
                }
                }
            }
            return(text);
        }
Пример #20
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);
            }
        }
Пример #21
0
        private void FindBuildingType(Building data)
        {
            var productionRate = data.m_fireIntensity != 0 ? 0 : PlayerBuildingAI.GetProductionRate(data.m_productionRate,
                                                                                                    EconomyManager.instance.GetBudget(data.Info.m_class));

            switch (data.Info.m_buildingAI)
            {
            case FireStationAI ai:
                strs[2] = (ai.m_fireDepartmentAccumulation * productionRate / 100).ToString();
                strs[1] = Localization.Get(LocalizationCategory.ServiceInfo, "FireFighting");
                strs[4] = (ai.m_fireDepartmentRadius / 8).ToString("F0");
                strs[3] = Localization.Get(LocalizationCategory.ServiceInfo, "Radius");
                strs[5] = Localization.Get(LocalizationCategory.ServiceInfo, "KittensSaved") + ": " + GetLlamaSightings(1.4);
                break;

            case MonumentAI ai:
                strs[2] = (ai.m_entertainmentAccumulation * productionRate / 100).ToString();
                strs[1] = Localization.Get(LocalizationCategory.ServiceInfo, "Entertainment");
                strs[4] = (ai.m_entertainmentRadius / 8).ToString("F0");
                strs[3] = Localization.Get(LocalizationCategory.ServiceInfo, "Radius");
                var tourism = ai.m_attractivenessAccumulation * productionRate / 100;
                strs[5] = Localization.Get(LocalizationCategory.ServiceInfo, "Attractiveness") + ": " + tourism.ToString();
                break;

            case HospitalAI ai:
                strs[2] = (ai.m_healthCareAccumulation * productionRate / 100).ToString();
                strs[1] = Localization.Get(LocalizationCategory.ServiceInfo, "Healthcare");
                strs[4] = (ai.m_healthCareRadius / 8).ToString("F0");
                strs[3] = Localization.Get(LocalizationCategory.ServiceInfo, "Radius");
                break;

            case CemeteryAI ai:
                strs[2] = (ai.m_deathCareAccumulation * productionRate / 100).ToString();
                strs[1] = Localization.Get(LocalizationCategory.ServiceInfo, "Deathcare");
                strs[4] = (ai.m_deathCareRadius / 8).ToString("F0");
                strs[3] = Localization.Get(LocalizationCategory.ServiceInfo, "Radius");
                break;

            case ParkAI ai:
                strs[2] = (ai.m_entertainmentAccumulation * productionRate / 100).ToString();
                strs[1] = Localization.Get(LocalizationCategory.ServiceInfo, "Entertainment");
                strs[4] = (ai.m_entertainmentRadius / 8).ToString("F0");
                strs[3] = Localization.Get(LocalizationCategory.ServiceInfo, "Radius");
                strs[5] = Localization.Get(LocalizationCategory.ServiceInfo, "Llamas") + ": " + GetLlamaSightings(2);
                break;

            case SchoolAI ai:
                strs[2] = (ai.m_educationAccumulation * productionRate / 100).ToString();
                strs[1] = Localization.Get(LocalizationCategory.ServiceInfo, "Education");
                strs[4] = (ai.m_educationRadius / 8).ToString("F0");
                strs[3] = Localization.Get(LocalizationCategory.ServiceInfo, "Radius");
                strs[5] = Localization.Get(LocalizationCategory.ServiceInfo, "ClassesSkipped") + ": " + GetLlamaSightings(2);
                break;

            case PoliceStationAI ai:
                strs[2] = (ai.m_policeDepartmentAccumulation * productionRate / 100).ToString();
                strs[1] = Localization.Get(LocalizationCategory.ServiceInfo, "Police");
                strs[4] = (ai.m_policeDepartmentRadius / 8).ToString("F0");
                strs[3] = Localization.Get(LocalizationCategory.ServiceInfo, "Radius");
                break;

            case CargoStationAI ai:
                strs[2] = (ai.m_cargoTransportAccumulation * productionRate / 100).ToString();
                strs[1] = Localization.Get(LocalizationCategory.ServiceInfo, "Cargo");
                strs[4] = (ai.m_cargoTransportRadius / 8).ToString("F0");
                strs[3] = Localization.Get(LocalizationCategory.ServiceInfo, "Radius");
                break;
            }
        }
Пример #22
0
        protected override void ProduceGoods(ushort buildingID, ref Building buildingData, ref Building.Frame frameData, int productionRate, int finalProductionRate, ref Citizen.BehaviourData behaviour, int aliveWorkerCount, int totalWorkerCount, int workPlaceCount, int aliveVisitorCount, int totalVisitorCount, int visitPlaceCount)
        {
            DistrictManager instance = Singleton <DistrictManager> .instance;
            byte            district = instance.GetDistrict(buildingData.m_position);
            byte            b        = instance.GetPark(buildingData.m_position);

            if (b != 0)
            {
                if (!instance.m_parks.m_buffer[(int)b].IsIndustry)
                {
                    b = 0;
                }
                else if (this.m_industryType == DistrictPark.ParkType.Industry || this.m_industryType != instance.m_parks.m_buffer[(int)b].m_parkType)
                {
                    b = 0;
                }
            }
            float num  = (float)buildingData.Width * -4f;
            float num2 = (float)buildingData.Width * 4f;
            float num3 = (float)buildingData.Length * -4f;
            float num4 = (float)buildingData.Length * 4f;

            if (this.m_info.m_subBuildings != null)
            {
                for (int i = 0; i < this.m_info.m_subBuildings.Length; i++)
                {
                    if (this.m_info.m_subBuildings[i].m_buildingInfo != null)
                    {
                        float num5 = (float)this.m_info.m_subBuildings[i].m_buildingInfo.m_cellWidth;
                        float num6 = (float)this.m_info.m_subBuildings[i].m_buildingInfo.m_cellLength;
                        float x    = this.m_info.m_subBuildings[i].m_position.x;
                        float num7 = -this.m_info.m_subBuildings[i].m_position.z;
                        num  = Mathf.Min(num, x - num5 * 4f);
                        num2 = Mathf.Max(num2, x + num5 * 4f);
                        num3 = Mathf.Min(num3, num7 - num6 * 4f);
                        num4 = Mathf.Max(num4, num7 + num6 * 4f);
                    }
                }
            }
            float   angle    = buildingData.m_angle;
            float   num8     = -(num + num2) * 0.5f;
            float   num9     = -(num3 + num4) * 0.5f;
            float   num10    = Mathf.Sin(angle);
            float   num11    = Mathf.Cos(angle);
            Vector3 position = buildingData.m_position - new Vector3(num11 * num8 + num10 * num9, 0f, num10 * num8 - num11 * num9);

            Notification.Problem problem = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoResources | Notification.Problem.NoPlaceforGoods | Notification.Problem.NoInputProducts | Notification.Problem.NoFishingGoods);
            bool flag = this.m_info.m_class.m_service == ItemClass.Service.Fishing;

            DistrictPolicies.Park parkPolicies = instance.m_parks.m_buffer[(int)b].m_parkPolicies;
            DistrictPark[]        buffer       = instance.m_parks.m_buffer;
            byte b2 = b;

            buffer[(int)b2].m_parkPoliciesEffect = (buffer[(int)b2].m_parkPoliciesEffect | (parkPolicies & (DistrictPolicies.Park.ImprovedLogistics | DistrictPolicies.Park.WorkSafety | DistrictPolicies.Park.AdvancedAutomation)));
            if ((parkPolicies & DistrictPolicies.Park.ImprovedLogistics) != DistrictPolicies.Park.None)
            {
                int num12 = this.GetMaintenanceCost() / 100;
                num12 = finalProductionRate * num12 / 1000;
                if (num12 != 0)
                {
                    Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.Maintenance, num12, this.m_info.m_class);
                }
            }
            int num13 = this.m_outputRate;

            if ((parkPolicies & DistrictPolicies.Park.AdvancedAutomation) != DistrictPolicies.Park.None)
            {
                num13 = (num13 * 110 + 50) / 100;
                int num14 = this.GetMaintenanceCost() / 100;
                num14 = finalProductionRate * num14 / 1000;
                if (num14 != 0)
                {
                    Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.Maintenance, num14, this.m_info.m_class);
                }
            }
            if ((parkPolicies & DistrictPolicies.Park.WorkSafety) != DistrictPolicies.Park.None)
            {
                int num15 = (aliveWorkerCount + (int)(Singleton <SimulationManager> .instance.m_currentFrameIndex >> 8 & 15U)) / 16;
                if (num15 != 0)
                {
                    Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, num15, this.m_info.m_class);
                }
            }
            if (finalProductionRate != 0)
            {
                int num16 = this.m_pollutionAccumulation;
                if (b != 0)
                {
                    int num17;
                    int num18;
                    instance.m_parks.m_buffer[(int)b].GetProductionFactors(out num17, out num18);
                    finalProductionRate = (finalProductionRate * num17 + 50) / 100;
                    num16 = (num16 * num18 + 50) / 100;
                }
                else if (this.m_industryType != DistrictPark.ParkType.Industry)
                {
                    finalProductionRate = 0;
                }
                int num19 = 0;
                int num20 = 0;
                if (this.m_inputResource1 != TransferManager.TransferReason.None)
                {
                    num19 = this.GetInputBufferSize1(parkPolicies, (int)instance.m_parks.m_buffer[(int)b].m_finalStorageDelta);
                    num20 = (int)buildingData.m_customBuffer2;
                    int num21 = (this.m_inputRate1 * finalProductionRate + 99) / 100;
                    if (num20 < num21)
                    {
                        finalProductionRate = (num20 * 100 + this.m_inputRate1 - 1) / this.m_inputRate1;
                        problem             = Notification.AddProblems(problem, (!flag) ? ((!this.IsRawMaterial(this.m_inputResource1)) ? Notification.Problem.NoInputProducts : Notification.Problem.NoResources) : Notification.Problem.NoFishingGoods);
                    }
                }
                int num22 = 0;
                int num23 = 0;
                if (this.m_inputResource2 != TransferManager.TransferReason.None)
                {
                    num22 = this.GetInputBufferSize2(parkPolicies, (int)instance.m_parks.m_buffer[(int)b].m_finalStorageDelta);
                    num23 = ((int)buildingData.m_teens << 8 | (int)buildingData.m_youngs);
                    int num24 = (this.m_inputRate2 * finalProductionRate + 99) / 100;
                    if (num23 < num24)
                    {
                        finalProductionRate = (num23 * 100 + this.m_inputRate2 - 1) / this.m_inputRate2;
                        problem             = Notification.AddProblems(problem, (!flag) ? ((!this.IsRawMaterial(this.m_inputResource2)) ? Notification.Problem.NoInputProducts : Notification.Problem.NoResources) : Notification.Problem.NoFishingGoods);
                    }
                }
                int num25 = 0;
                int num26 = 0;
                if (this.m_inputResource3 != TransferManager.TransferReason.None)
                {
                    num25 = this.GetInputBufferSize3(parkPolicies, (int)instance.m_parks.m_buffer[(int)b].m_finalStorageDelta);
                    num26 = ((int)buildingData.m_adults << 8 | (int)buildingData.m_seniors);
                    int num27 = (this.m_inputRate3 * finalProductionRate + 99) / 100;
                    if (num26 < num27)
                    {
                        finalProductionRate = (num26 * 100 + this.m_inputRate3 - 1) / this.m_inputRate3;
                        problem             = Notification.AddProblems(problem, (!flag) ? ((!this.IsRawMaterial(this.m_inputResource3)) ? Notification.Problem.NoInputProducts : Notification.Problem.NoResources) : Notification.Problem.NoFishingGoods);
                    }
                }
                int num28 = 0;
                int num29 = 0;
                if (this.m_inputResource4 != TransferManager.TransferReason.None)
                {
                    num28 = this.GetInputBufferSize4(parkPolicies, (int)instance.m_parks.m_buffer[(int)b].m_finalStorageDelta);
                    num29 = ((int)buildingData.m_education1 << 8 | (int)buildingData.m_education2);
                    int num30 = (this.m_inputRate4 * finalProductionRate + 99) / 100;
                    if (num29 < num30)
                    {
                        finalProductionRate = (num29 * 100 + this.m_inputRate4 - 1) / this.m_inputRate4;
                        problem             = Notification.AddProblems(problem, (!flag) ? ((!this.IsRawMaterial(this.m_inputResource4)) ? Notification.Problem.NoInputProducts : Notification.Problem.NoResources) : Notification.Problem.NoFishingGoods);
                    }
                }
                int num31 = 0;
                int num32 = 0;
                if (this.m_outputResource != TransferManager.TransferReason.None)
                {
                    num31 = this.GetOutputBufferSize(parkPolicies, (int)instance.m_parks.m_buffer[(int)b].m_finalStorageDelta);
                    num32 = (int)buildingData.m_customBuffer1;
                    int num33 = (num13 * finalProductionRate + 99) / 100;
                    if (num31 - num32 < num33)
                    {
                        num33 = Mathf.Max(0, num31 - num32);
                        finalProductionRate = (num33 * 100 + num13 - 1) / num13;
                        if (this.m_outputVehicleCount != 0)
                        {
                            problem = Notification.AddProblems(problem, Notification.Problem.NoPlaceforGoods);
                            if (this.m_info.m_class.m_service == ItemClass.Service.PlayerIndustry)
                            {
                                GuideController properties = Singleton <GuideManager> .instance.m_properties;
                                if (properties != null)
                                {
                                    Singleton <BuildingManager> .instance.m_warehouseNeeded.Activate(properties.m_warehouseNeeded, buildingID);
                                }
                            }
                        }
                    }
                }
                if (this.m_inputResource1 != TransferManager.TransferReason.None)
                {
                    int num34 = (this.m_inputRate1 * finalProductionRate + 99) / 100;
                    num20 = Mathf.Max(0, num20 - num34);
                    buildingData.m_customBuffer2 = (ushort)num20;
                    instance.m_parks.m_buffer[(int)b].AddConsumptionAmount(this.m_inputResource1, num34);
                }
                if (this.m_inputResource2 != TransferManager.TransferReason.None)
                {
                    int num35 = (this.m_inputRate2 * finalProductionRate + 99) / 100;
                    num23 = Mathf.Max(0, num23 - num35);
                    buildingData.m_youngs = (byte)(num23 & 255);
                    buildingData.m_teens  = (byte)(num23 >> 8);
                    instance.m_parks.m_buffer[(int)b].AddConsumptionAmount(this.m_inputResource2, num35);
                }
                if (this.m_inputResource3 != TransferManager.TransferReason.None)
                {
                    int num36 = (this.m_inputRate3 * finalProductionRate + 99) / 100;
                    num26 = Mathf.Max(0, num26 - num36);
                    buildingData.m_seniors = (byte)(num26 & 255);
                    buildingData.m_adults  = (byte)(num26 >> 8);
                    instance.m_parks.m_buffer[(int)b].AddConsumptionAmount(this.m_inputResource3, num36);
                }
                if (this.m_inputResource4 != TransferManager.TransferReason.None)
                {
                    int num37 = (this.m_inputRate4 * finalProductionRate + 99) / 100;
                    num29 = Mathf.Max(0, num29 - num37);
                    buildingData.m_education2 = (byte)(num29 & 255);
                    buildingData.m_education1 = (byte)(num29 >> 8);
                    instance.m_parks.m_buffer[(int)b].AddConsumptionAmount(this.m_inputResource4, num37);
                }
                if (this.m_outputResource != TransferManager.TransferReason.None)
                {
                    int num38 = (num13 * finalProductionRate + 99) / 100;
                    num32 = Mathf.Min(num31, num32 + num38);
                    buildingData.m_customBuffer1 = (ushort)num32;
                    instance.m_parks.m_buffer[(int)b].AddProductionAmountFish(this.m_outputResource, num38);
                }
                num16 = (finalProductionRate * num16 + 50) / 100;
                if (num16 != 0)
                {
                    num16 = UniqueFacultyAI.DecreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, num16);
                    Singleton <NaturalResourceManager> .instance.TryDumpResource(NaturalResourceManager.Resource.Pollution, num16, num16, position, this.m_pollutionRadius);
                }
                base.HandleDead2(buildingID, ref buildingData, ref behaviour, totalWorkerCount);
                if (b != 0 || this.m_industryType == DistrictPark.ParkType.Industry)
                {
                    int num39 = 0;
                    if (this.m_inputResource1 != TransferManager.TransferReason.None)
                    {
                        int num40 = 0;
                        int num41 = 0;
                        int num42 = 0;
                        int num43 = 0;
                        base.CalculateGuestVehicles(buildingID, ref buildingData, this.m_inputResource1, ref num40, ref num41, ref num42, ref num43);
                        if (num43 != 0)
                        {
                            num39 |= 1;
                        }
                        int num44 = num19 - num20 - num41;
                        if (num44 >= 8000)
                        {
                            TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                            offer.Priority = Mathf.Max(1, num44 * 8 / num19);
                            offer.Building = buildingID;
                            offer.Position = buildingData.m_position;
                            offer.Amount   = 1;
                            offer.Active   = false;
                            Singleton <TransferManager> .instance.AddIncomingOffer(this.m_inputResource1, offer);
                        }
                        instance.m_parks.m_buffer[(int)b].AddBufferStatus(this.m_inputResource1, num20, num41, num19);
                    }
                    if (this.m_inputResource2 != TransferManager.TransferReason.None)
                    {
                        int num45 = 0;
                        int num46 = 0;
                        int num47 = 0;
                        int num48 = 0;
                        base.CalculateGuestVehicles(buildingID, ref buildingData, this.m_inputResource2, ref num45, ref num46, ref num47, ref num48);
                        if (num48 != 0)
                        {
                            num39 |= 2;
                        }
                        int num49 = num22 - num23 - num46;
                        if (num49 >= 8000)
                        {
                            TransferManager.TransferOffer offer2 = default(TransferManager.TransferOffer);
                            offer2.Priority = Mathf.Max(1, num49 * 8 / num22);
                            offer2.Building = buildingID;
                            offer2.Position = buildingData.m_position;
                            offer2.Amount   = 1;
                            offer2.Active   = false;
                            Singleton <TransferManager> .instance.AddIncomingOffer(this.m_inputResource2, offer2);
                        }
                        instance.m_parks.m_buffer[(int)b].AddBufferStatus(this.m_inputResource2, num23, num46, num22);
                    }
                    if (this.m_inputResource3 != TransferManager.TransferReason.None)
                    {
                        int num50 = 0;
                        int num51 = 0;
                        int num52 = 0;
                        int num53 = 0;
                        base.CalculateGuestVehicles(buildingID, ref buildingData, this.m_inputResource3, ref num50, ref num51, ref num52, ref num53);
                        if (num53 != 0)
                        {
                            num39 |= 4;
                        }
                        int num54 = num25 - num26 - num51;
                        if (num54 >= 8000)
                        {
                            TransferManager.TransferOffer offer3 = default(TransferManager.TransferOffer);
                            offer3.Priority = Mathf.Max(1, num54 * 8 / num25);
                            offer3.Building = buildingID;
                            offer3.Position = buildingData.m_position;
                            offer3.Amount   = 1;
                            offer3.Active   = false;
                            Singleton <TransferManager> .instance.AddIncomingOffer(this.m_inputResource3, offer3);
                        }
                        instance.m_parks.m_buffer[(int)b].AddBufferStatus(this.m_inputResource3, num26, num51, num25);
                    }
                    if (this.m_inputResource4 != TransferManager.TransferReason.None)
                    {
                        int num55 = 0;
                        int num56 = 0;
                        int num57 = 0;
                        int num58 = 0;
                        base.CalculateGuestVehicles(buildingID, ref buildingData, this.m_inputResource4, ref num55, ref num56, ref num57, ref num58);
                        if (num58 != 0)
                        {
                            num39 |= 8;
                        }
                        int num59 = num28 - num29 - num56;
                        if (num59 >= 8000)
                        {
                            TransferManager.TransferOffer offer4 = default(TransferManager.TransferOffer);
                            offer4.Priority = Mathf.Max(1, num59 * 8 / num28);
                            offer4.Building = buildingID;
                            offer4.Position = buildingData.m_position;
                            offer4.Amount   = 1;
                            offer4.Active   = false;
                            Singleton <TransferManager> .instance.AddIncomingOffer(this.m_inputResource4, offer4);
                        }
                        instance.m_parks.m_buffer[(int)b].AddBufferStatus(this.m_inputResource4, num29, num56, num28);
                    }
                    buildingData.m_tempImport |= (byte)num39;
                    if (this.m_outputResource != TransferManager.TransferReason.None)
                    {
                        if (this.m_outputVehicleCount == 0)
                        {
                            if (num32 == num31)
                            {
                                int num60 = (num32 * IndustryBuildingAI.GetResourcePrice(this.m_outputResource, ItemClass.Service.None) + 50) / 100;
                                if ((instance.m_districts.m_buffer[(int)district].m_cityPlanningPolicies & DistrictPolicies.CityPlanning.SustainableFishing) != DistrictPolicies.CityPlanning.None)
                                {
                                    num60 = (num60 * 105 + 99) / 100;
                                }
                                num60 = UniqueFacultyAI.IncreaseByBonus(UniqueFacultyAI.FacultyBonus.Science, num60);
                                Singleton <EconomyManager> .instance.AddResource(EconomyManager.Resource.ResourcePrice, num60, this.m_info.m_class);

                                if (b != 0)
                                {
                                    instance.m_parks.m_buffer[(int)b].AddExportAmountFish(this.m_outputResource, num32);
                                }
                                num32 = 0;
                                buildingData.m_customBuffer1 = (ushort)num32;
                                buildingData.m_tempExport    = byte.MaxValue;
                            }
                        }
                        else
                        {
                            int num61 = 0;
                            int num62 = 0;
                            int num63 = 0;
                            int value = 0;
                            base.CalculateOwnVehicles(buildingID, ref buildingData, this.m_outputResource, ref num61, ref num62, ref num63, ref value);
                            buildingData.m_tempExport = (byte)Mathf.Clamp(value, (int)buildingData.m_tempExport, 255);
                            int budget = Singleton <EconomyManager> .instance.GetBudget(this.m_info.m_class);

                            int productionRate2 = PlayerBuildingAI.GetProductionRate(100, budget);
                            int num64           = (productionRate2 * this.m_outputVehicleCount + 99) / 100;
                            int num65           = num32;
                            if (num65 >= 8000 && num61 < num64)
                            {
                                TransferManager.TransferOffer offer5 = default(TransferManager.TransferOffer);
                                offer5.Priority = Mathf.Max(1, num65 * 8 / num31);
                                offer5.Building = buildingID;
                                offer5.Position = buildingData.m_position;
                                offer5.Amount   = 1;
                                offer5.Active   = true;
                                Singleton <TransferManager> .instance.AddOutgoingOffer(this.m_outputResource, offer5);
                            }
                        }
                        instance.m_parks.m_buffer[(int)b].AddBufferStatusFish(this.m_outputResource, num32, 0, num31);
                    }
                }
                if (buildingData.m_finalImport != 0)
                {
                    District[] buffer2 = instance.m_districts.m_buffer;
                    byte       b3      = district;
                    buffer2[(int)b3].m_playerConsumption.m_finalImportAmount = buffer2[(int)b3].m_playerConsumption.m_finalImportAmount + (uint)buildingData.m_finalImport;
                }
                if (buildingData.m_finalExport != 0)
                {
                    District[] buffer3 = instance.m_districts.m_buffer;
                    byte       b4      = district;
                    buffer3[(int)b4].m_playerConsumption.m_finalExportAmount = buffer3[(int)b4].m_playerConsumption.m_finalExportAmount + (uint)buildingData.m_finalExport;
                }
                int num66 = finalProductionRate * this.m_noiseAccumulation / 100;
                if (num66 != 0)
                {
                    Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, num66, position, this.m_noiseRadius);
                }
            }
            buildingData.m_problems   = problem;
            buildingData.m_education3 = (byte)Mathf.Clamp(finalProductionRate * num13 / Mathf.Max(1, this.m_outputRate), 0, 255);
            buildingData.m_health     = (byte)Mathf.Clamp(finalProductionRate, 0, 255);
            if (b != 0)
            {
                instance.m_parks.m_buffer[(int)b].AddWorkers(aliveWorkerCount);
            }
            else if (this.m_industryType != DistrictPark.ParkType.Industry)
            {
                GuideController properties2 = Singleton <GuideManager> .instance.m_properties;
                if (properties2 != null)
                {
                    Singleton <BuildingManager> .instance.m_industryBuildingOutsideIndustryArea.Activate(properties2.m_industryBuildingOutsideIndustryArea, buildingID);
                }
            }
            base.ProduceGoods(buildingID, ref buildingData, ref frameData, productionRate, finalProductionRate, ref behaviour, aliveWorkerCount, totalWorkerCount, workPlaceCount, aliveVisitorCount, totalVisitorCount, visitPlaceCount);
        }
        /// <summary>
        /// Collects building info for debug use.
        /// </summary>
        /// <param name="buildings">The buildings.</param>
        /// <param name="vehicles">The vehicles.</param>
        /// <param name="districtManager">The district manager.</param>
        /// <param name="citizenManager">The citizen manager.</param>
        /// <param name="buildingId">The building identifier.</param>
        /// <param name="serviceBuilding">The service building.</param>
        /// <param name="targetBuilding">The target building.</param>
        /// <param name="buildingStamp">The building stamp.</param>
        /// <param name="verbose">If set to <c>true</c> include more information.</param>
        /// <returns>The debug information.</returns>
        private static Log.InfoList DebugInfoMsg(
            Building[] buildings,
            Vehicle[] vehicles,
            DistrictManager districtManager,
            CitizenManager citizenManager,
            ushort buildingId,
            ServiceBuildingInfo serviceBuilding,
            TargetBuildingInfo targetBuilding,
            BuildingStamp buildingStamp,
            bool verbose = false)
        {
            Log.InfoList info = new Log.InfoList();

            info.Add("BuildingId", buildingId);

            if (buildingStamp != null)
            {
                info.Add("O", "BuildingStamp");
            }

            if (serviceBuilding != null)
            {
                info.Add("O", "ServiceBuilding");
            }

            if (targetBuilding != null)
            {
                info.Add("O", "TargetBuilding");
            }

            List <KeyValuePair <string, TargetBuildingInfo> >  targetBuildings  = null;
            List <KeyValuePair <string, ServiceBuildingInfo> > serviceBuildings = null;

            if (verbose && Global.Buildings != null)
            {
                //if (serviceBuilding == null)
                //{
                //    serviceBuilding = Global.Buildings.GetServiceBuilding(buildingId);
                //}

                //if (targetBuilding == null)
                //{
                //    targetBuilding = Global.Buildings.GetTargetBuilding(buildingId);
                //}

                targetBuildings  = new List <KeyValuePair <string, TargetBuildingInfo> >();
                serviceBuildings = new List <KeyValuePair <string, ServiceBuildingInfo> >();

                if (serviceBuilding == null)
                {
                    if (Global.Buildings.Garbage.ServiceBuildings != null && Global.Buildings.Garbage.ServiceBuildings.TryGetValue(buildingId, out serviceBuilding))
                    {
                        serviceBuildings.Add(new KeyValuePair <string, ServiceBuildingInfo>("GB", serviceBuilding));
                    }

                    if (Global.Buildings.DeathCare.ServiceBuildings != null && Global.Buildings.DeathCare.ServiceBuildings.TryGetValue(buildingId, out serviceBuilding))
                    {
                        serviceBuildings.Add(new KeyValuePair <string, ServiceBuildingInfo>("DCB", serviceBuilding));
                    }

                    if (Global.Buildings.HealthCare.ServiceBuildings != null && Global.Buildings.HealthCare.ServiceBuildings.TryGetValue(buildingId, out serviceBuilding))
                    {
                        serviceBuildings.Add(new KeyValuePair <string, ServiceBuildingInfo>("HCB", serviceBuilding));
                    }

                    serviceBuilding = null;
                }

                if (targetBuilding == null)
                {
                    if (Global.Buildings.DeathCare.TargetBuildings != null && Global.Buildings.DeathCare.TargetBuildings.TryGetValue(buildingId, out targetBuilding))
                    {
                        targetBuildings.Add(new KeyValuePair <string, TargetBuildingInfo>("DPB", targetBuilding));
                    }

                    if (Global.Buildings.Garbage.TargetBuildings != null && Global.Buildings.Garbage.TargetBuildings.TryGetValue(buildingId, out targetBuilding))
                    {
                        targetBuildings.Add(new KeyValuePair <string, TargetBuildingInfo>("DB", targetBuilding));
                    }

                    if (Global.Buildings.HealthCare.TargetBuildings != null && Global.Buildings.HealthCare.TargetBuildings.TryGetValue(buildingId, out targetBuilding))
                    {
                        targetBuildings.Add(new KeyValuePair <string, TargetBuildingInfo>("SPB", targetBuilding));
                    }

                    targetBuilding = null;
                }
            }

            try
            {
                info.Add("AI", buildings[buildingId].Info.m_buildingAI.GetType());
                info.Add("InfoName", buildings[buildingId].Info.name);

                string name = GetBuildingName(buildingId);
                if (!String.IsNullOrEmpty(name) && name != buildings[buildingId].Info.name)
                {
                    info.Add("BuildingName", name);
                }
            }
            catch
            {
                info.Add("Error", "Info");
            }

            try
            {
                byte district = districtManager.GetDistrict(buildings[buildingId].m_position);
                info.Add("District", district);
                info.Add("DistrictName", districtManager.GetDistrictName(district));
            }
            catch (Exception ex)
            {
                info.Add("Exception", "District", ex.GetType().ToString(), ex.Message);
            }

            if (buildingStamp != null)
            {
                info.Add("Source", buildingStamp.Source);
                info.Add("SimulationTimeStamp", buildingStamp.SimulationTimeStamp);
                info.Add("SimulationTimeDelta", buildingStamp.SimulationTimeDelta);
            }

            AddServiceBuildingInfoToDebugInfoMsg(info, buildings, serviceBuilding, "B");
            if (serviceBuildings != null)
            {
                foreach (KeyValuePair <string, ServiceBuildingInfo> building in serviceBuildings)
                {
                    AddServiceBuildingInfoToDebugInfoMsg(info, buildings, building.Value, building.Key);
                }
            }

            AddTargetBuildingInfoToDebugInfoMsg(info, targetBuilding, "B");
            if (targetBuildings != null)
            {
                foreach (KeyValuePair <string, TargetBuildingInfo> building in targetBuildings)
                {
                    AddTargetBuildingInfoToDebugInfoMsg(info, building.Value, building.Key);
                }
            }

            if (verbose && Global.Buildings != null)
            {
                info.Add("Categories", Global.Buildings.GetCategories(buildingId));
            }

            float radius = float.NaN;

            int materialMax         = 0;
            int materialAmount      = 0;
            int serviceVehicleCount = 0;

            try
            {
                if (GetCapacityAmount(buildingId, ref buildings[buildingId], out materialAmount, out materialMax, out serviceVehicleCount))
                {
                    info.Add("CapacityAmount", materialAmount);
                    info.Add("CapacityMax", materialMax);
                    info.Add("ServiceVehicleCount", serviceVehicleCount);
                }

                serviceVehicleCount = 0;

                if (buildings[buildingId].Info.m_buildingAI is CemeteryAI)
                {
                    radius = ((CemeteryAI)buildings[buildingId].Info.m_buildingAI).m_deathCareRadius;

                    info.Add("DeathCareRadius", ((CemeteryAI)buildings[buildingId].Info.m_buildingAI).m_deathCareRadius);
                    info.Add("CorpseCapacity", ((CemeteryAI)buildings[buildingId].Info.m_buildingAI).m_corpseCapacity);
                    info.Add("GraveCount", ((CemeteryAI)buildings[buildingId].Info.m_buildingAI).m_graveCount);
                    info.Add("CustomBuffer1", buildings[buildingId].m_customBuffer1);                                                                                    // GraveUsed?
                    info.Add("CustomBuffer2", buildings[buildingId].m_customBuffer2);
                    info.Add("PR_HC_Calc", ((buildings[buildingId].m_productionRate * ((CemeteryAI)buildings[buildingId].Info.m_buildingAI).m_hearseCount) + 99) / 100); // Hearse capacity?
                    info.Add("IsFull", buildings[buildingId].Info.m_buildingAI.IsFull(buildingId, ref buildings[buildingId]));

                    buildings[buildingId].Info.m_buildingAI.GetMaterialAmount(buildingId, ref buildings[buildingId], TransferManager.TransferReason.Dead, out materialAmount, out materialMax);
                }
                else if (buildings[buildingId].Info.m_buildingAI is LandfillSiteAI)
                {
                    radius = ((LandfillSiteAI)buildings[buildingId].Info.m_buildingAI).m_collectRadius;

                    info.Add("CollectRadius", ((LandfillSiteAI)buildings[buildingId].Info.m_buildingAI).m_collectRadius);
                    info.Add("GarbageAmount", ((LandfillSiteAI)buildings[buildingId].Info.m_buildingAI).GetGarbageAmount(buildingId, ref buildings[buildingId]));
                    info.Add("GarbageCapacity", ((LandfillSiteAI)buildings[buildingId].Info.m_buildingAI).m_garbageCapacity);
                    info.Add("GarbageBuffer", buildings[buildingId].m_garbageBuffer);
                    info.Add("CustomBuffer1", buildings[buildingId].m_customBuffer1); // Garbage?
                    info.Add("IsFull", buildings[buildingId].Info.m_buildingAI.IsFull(buildingId, ref buildings[buildingId]));

                    buildings[buildingId].Info.m_buildingAI.GetMaterialAmount(buildingId, ref buildings[buildingId], TransferManager.TransferReason.Garbage, out materialAmount, out materialMax);
                }
                else if (buildings[buildingId].Info.m_buildingAI is HospitalAI)
                {
                    radius = ((HospitalAI)buildings[buildingId].Info.m_buildingAI).m_healthCareRadius;

                    info.Add("HealthCareRadius", ((HospitalAI)buildings[buildingId].Info.m_buildingAI).m_healthCareRadius);
                    info.Add("PatientCapacity", ((HospitalAI)buildings[buildingId].Info.m_buildingAI).m_patientCapacity);
                    info.Add("IsFull", buildings[buildingId].Info.m_buildingAI.IsFull(buildingId, ref buildings[buildingId]));

                    buildings[buildingId].Info.m_buildingAI.GetMaterialAmount(buildingId, ref buildings[buildingId], TransferManager.TransferReason.Sick, out materialAmount, out materialMax);
                }

                info.Add("materialMax", materialMax);
                info.Add("materialAmount", materialAmount);
                info.Add("materialFree", materialMax - materialAmount);
            }
            catch
            {
                info.Add("Error", "Material");
            }

            ushort ownVehicleCount  = 0;
            ushort madeVehicleCount = 0;

            try
            {
                ushort vehicleId = buildings[buildingId].m_ownVehicles;
                while (vehicleId != 0 && ownVehicleCount < ushort.MaxValue)
                {
                    ownVehicleCount++;
                    try
                    {
                        if ((vehicles[vehicleId].m_transferType == (byte)TransferManager.TransferReason.Garbage || vehicles[vehicleId].m_transferType == (byte)TransferManager.TransferReason.Dead) &&
                            vehicles[vehicleId].Info != null &&
                            (vehicles[vehicleId].m_flags & Vehicle.Flags.Created) == Vehicle.Flags.Created &&
                            (vehicles[vehicleId].m_flags & VehicleHelper.VehicleExists) != ~VehicleHelper.VehicleAll)
                        {
                            madeVehicleCount++;
                        }
                    }
                    catch
                    {
                        info.Add("Error", "Vehicle");
                    }

                    vehicleId = vehicles[vehicleId].m_nextOwnVehicle;
                }
                info.Add("OwnVehicles", ownVehicleCount);
                info.Add("MadeVehicles", madeVehicleCount);
            }
            catch
            {
                info.Add("Error", "Vehicles");
            }

            int productionRate = buildings[buildingId].m_productionRate;

            info.Add("VehicleCount", serviceVehicleCount);
            info.Add("ProductionRate", productionRate);
            info.Add("VehicleCountNominal", ((productionRate * serviceVehicleCount) + 99) / 100);

            try
            {
                int budget = Singleton <EconomyManager> .instance.GetBudget(buildings[buildingId].Info.m_buildingAI.m_info.m_class);

                productionRate = PlayerBuildingAI.GetProductionRate(productionRate, budget);
                int productionRate100     = PlayerBuildingAI.GetProductionRate(100, budget);
                int actualVehicleCount    = ((productionRate * serviceVehicleCount) + 99) / 100;
                int actualVehicleCount100 = ((productionRate100 * serviceVehicleCount) + 99) / 100;

                if (!float.IsNaN(radius))
                {
                    info.Add("Radius", radius);
                }

                info.Add("Budget", budget);
                info.Add("ProductionRateActual", productionRate, productionRate100);
                info.Add("VehicleCountActual", actualVehicleCount, actualVehicleCount100);
                info.Add("SpareVehicles", actualVehicleCount - ownVehicleCount, actualVehicleCount100 - ownVehicleCount);

                if (!float.IsNaN(radius))
                {
                    info.Add("ProductionRange", (double)productionRate * (double)radius * 0.00999999977648258);
                }
            }
            catch
            {
                info.Add("Error", "Budget");
            }

            try
            {
                float range = buildings[buildingId].Info.m_buildingAI.GetCurrentRange(buildingId, ref buildings[buildingId]);
                range = range * range * Global.Settings.RangeModifier;
                if (range < Global.Settings.RangeMinimum)
                {
                    info.Add("Range", range, '<', Global.Settings.RangeMinimum);
                }
                else if (range > Global.Settings.RangeMaximum)
                {
                    info.Add("Range", range, '>', Global.Settings.RangeMaximum);
                }
                else
                {
                    info.Add("Range", range, ">=<");
                }
            }
            catch
            {
                info.Add("Error", "Range");
            }

            try
            {
                List <string> needs = new List <string>();

                if (buildings[buildingId].m_garbageBuffer >= Global.Settings.Garbage.MinimumAmountForDispatch)
                {
                    needs.Add("Filthy");
                }
                else if (buildings[buildingId].m_garbageBuffer >= Global.Settings.Garbage.MinimumAmountForPatrol)
                {
                    needs.Add("Dirty");
                }
                else if (buildings[buildingId].m_garbageBuffer > 0)
                {
                    needs.Add("Dusty");
                }

                if (buildings[buildingId].m_deathProblemTimer > 0)
                {
                    needs.Add("Dead");
                }

                if (buildings[buildingId].m_garbageBuffer * Dispatcher.ProblemBufferModifier >= Dispatcher.ProblemLimitForgotten ||
                    buildings[buildingId].m_deathProblemTimer * Dispatcher.ProblemTimerModifier >= Dispatcher.ProblemLimitForgotten)
                {
                    needs.Add("Forgotten");
                }

                info.Add("Needs", needs);
            }
            catch
            {
                info.Add("Error", "Needs");
            }

            info.Add("DeathProblemTimer", buildings[buildingId].m_deathProblemTimer);
            info.Add("HealthProblemTimer", buildings[buildingId].m_healthProblemTimer);
            info.Add("MajorProblemTimer", buildings[buildingId].m_majorProblemTimer);

            try
            {
                int  citizens = 0;
                int  count    = 0;
                uint unitId   = buildings[buildingId].m_citizenUnits;
                while (unitId != 0)
                {
                    CitizenUnit unit = citizenManager.m_units.m_buffer[unitId];

                    try
                    {
                        for (int i = 0; i < 5; i++)
                        {
                            uint citizenId = unit.GetCitizen(i);
                            if (citizenId != 0)
                            {
                                Citizen citizen = citizenManager.m_citizens.m_buffer[citizenId];
                                if (citizen.Dead && citizen.GetBuildingByLocation() == buildingId)
                                {
                                    citizens++;
                                }
                            }
                        }
                    }
                    catch
                    {
                        info.Add("Error", "Citizen");
                    }

                    count++;
                    if (count > (int)ushort.MaxValue * 10)
                    {
                        break;
                    }

                    unitId = unit.m_nextUnit;
                }
                info.Add("DeadCitizens", citizens);
            }
            catch
            {
                info.Add("Error", "Citizens");
            }

            try
            {
                info.Add("GarbageAmount", buildings[buildingId].Info.m_buildingAI.GetGarbageAmount(buildingId, ref buildings[buildingId]));
                info.Add("GarbageBuffer", buildings[buildingId].m_garbageBuffer);
            }
            catch
            {
                info.Add("Error", "Garbage");
            }

            try
            {
                string problems = buildings[buildingId].m_problems.ToString();
                if (problems.IndexOfAny(new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }) >= 0)
                {
                    foreach (Notification.Problem problem in Enum.GetValues(typeof(Notification.Problem)))
                    {
                        if (problem != Notification.Problem.None && (buildings[buildingId].m_problems & problem) == problem)
                        {
                            problems += ", " + problem.ToString();
                        }
                    }
                }
                info.Add("Problems", problems);
            }
            catch
            {
                info.Add("Error", "Problems");
            }

            info.Add("FireIntensoty", buildings[buildingId].m_fireIntensity);

            try
            {
                string flags = buildings[buildingId].m_flags.ToString();
                if (flags.IndexOfAny(new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }) >= 0)
                {
                    foreach (Building.Flags flag in Enum.GetValues(typeof(Building.Flags)))
                    {
                        if (flag != Building.Flags.None && (buildings[buildingId].m_flags & flag) == flag)
                        {
                            flags += ", " + flag.ToString();
                        }
                    }
                }
                info.Add("Flags", flags);
            }
            catch
            {
                info.Add("Error", "Flags");
            }

            try
            {
                string status = buildings[buildingId].Info.m_buildingAI.GetLocalizedStatus(buildingId, ref buildings[buildingId]);
                if (!String.IsNullOrEmpty(status))
                {
                    info.Add("Status", status);
                }
            }
            catch
            {
                info.Add("Error", "Status");
            }

            try
            {
                info.Add("AI", buildings[buildingId].Info.m_buildingAI.GetType().AssemblyQualifiedName);
            }
            catch
            {
                info.Add("Error", "AI");
            }

            return(info);
        }
 public static bool Prefix(PlayerBuildingAI __instance, ref VehicleInfo __result)
 {
     __result = null;
     return(false);
 }
        public void Update()
        {
            if (servicePanel == null)
            {
                return;
            }

            var buildingId = GetParentInstanceId().Building;

            if (this.enabled && info.isVisible && BuildingManager.instance != null && ((SimulationManager.instance.m_currentFrameIndex & 15u) == 15u || lastSelected != buildingId))
            {
                Debug.Log("running");
                lastSelected = buildingId;
                Building data           = BuildingManager.instance.m_buildings.m_buffer[buildingId];
                var      service        = data.Info.m_class.m_service;
                var      productionRate = PlayerBuildingAI.GetProductionRate(data.m_productionRate, EconomyManager.instance.GetBudget(data.Info.m_class));
                if (data.m_fireIntensity != 0)
                {
                    productionRate = 0;
                }


                var sb = new StringBuilder();
                var ii = 0;
                var ai = data.Info.m_buildingAI;

                if (ai is FireStationAI)
                {
                    var strength = (int)(((FireStationAI)data.Info.m_buildingAI).m_fireDepartmentAccumulation * productionRate / 100);
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "FireFighting") + ": " + strength.ToString());
                    var radius = (int)(((FireStationAI)data.Info.m_buildingAI).m_fireDepartmentRadius / 8);
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "Radius") + ": " + radius.ToString());
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "KittensSaved") + ": " + GetLlamaSightings(1.4));
                    ii += 3;
                }
                else if (ai is MonumentAI)
                {
                    var strength = (int)(((MonumentAI)data.Info.m_buildingAI).m_entertainmentAccumulation * productionRate / 100);
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "Entertainment") + ": " + strength.ToString());
                    var radius = (int)(((MonumentAI)data.Info.m_buildingAI).m_entertainmentRadius / 8);
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "Radius") + ": " + radius.ToString());
                    var tourism = (int)(((MonumentAI)data.Info.m_buildingAI).m_attractivenessAccumulation * productionRate / 100);
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "Attractiveness") + ": " + tourism);
                    ii += 3;
                }
                else if (ai is HospitalAI)
                {
                    var strength = (int)(((HospitalAI)data.Info.m_buildingAI).m_healthCareAccumulation * productionRate / 100);
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "Healthcare") + ": " + strength.ToString());
                    var radius = (int)(((HospitalAI)data.Info.m_buildingAI).m_healthCareRadius / 8);
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "Radius") + ": " + radius.ToString());
                    ii += 2;
                }
                else if (ai is CemeteryAI)
                {
                    var strength = (int)(((CemeteryAI)data.Info.m_buildingAI).m_deathCareAccumulation * productionRate / 100);
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "Deathcare") + ": " + strength.ToString());
                    var radius = (int)(((CemeteryAI)data.Info.m_buildingAI).m_deathCareRadius / 8);
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "Radius") + ": " + radius.ToString());
                    ii += 3;
                }
                else if (ai is ParkAI)
                {
                    var strength = (int)(((ParkAI)data.Info.m_buildingAI).m_entertainmentAccumulation * productionRate / 100);
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "Entertainment") + ": " + strength.ToString());
                    var radius = (int)(((ParkAI)data.Info.m_buildingAI).m_entertainmentRadius / 8);
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "Radius") + ": " + radius.ToString());
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "Llamas") + ": " + GetLlamaSightings(2));
                    ii += 3;
                }
                else if (ai is SchoolAI)
                {
                    var strength = (int)(((SchoolAI)data.Info.m_buildingAI).m_educationAccumulation * productionRate / 100);
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "Education") + ": " + strength.ToString());
                    var radius = (int)(((SchoolAI)data.Info.m_buildingAI).m_educationRadius / 8);
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "Radius") + ": " + radius.ToString());
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "ClassesSkipped") + ": " + GetLlamaSightings(2));
                    ii += 3;
                }
                else if (ai is PoliceStationAI)
                {
                    var strength = (int)(((PoliceStationAI)data.Info.m_buildingAI).m_policeDepartmentAccumulation * productionRate / 100);
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "Police") + ": " + strength.ToString());
                    var radius = (int)(((PoliceStationAI)data.Info.m_buildingAI).m_policeDepartmentRadius / 8);
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "Radius") + ": " + radius.ToString());
                    ii += 2;
                }
                else if (ai is CargoStationAI)
                {
                    var strength = (int)(((CargoStationAI)data.Info.m_buildingAI).m_cargoTransportAccumulation * productionRate / 100);
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "Cargo") + ": " + strength.ToString());
                    var radius = (int)(((CargoStationAI)data.Info.m_buildingAI).m_cargoTransportRadius / 8);
                    sb.AppendLine(Localization.Get(LocalizationCategory.ServiceInfo, "Radius") + ": " + radius.ToString());
                    ii += 2;
                }
                label1.relativePosition = new Vector3(0, info.height + info.relativePosition.y - 14 * ii);
                label1.text             = sb.ToString();
            }
        }
Пример #26
0
        public static int GetProductionRate(ref Building b)
        {
            int budget = Singleton <EconomyManager> .instance.GetBudget(b.Info.m_class);

            return(PlayerBuildingAI.GetProductionRate(100, budget));
        }
Пример #27
0
        public void CustomNodeSimulationStep(ushort nodeID, ref NetNode data)
        {
            if ((Singleton <SimulationManager> .instance.m_currentFrameIndex & 4095u) >= 3840u)
            {
                data.m_finalCounter += data.m_tempCounter;

                data.m_tempCounter = 0;

                var date         = DateTime.Now;
                var resetCounter = false;
                if (StatisticsFixManager.instance.SaveData.resetTimes.ContainsKey(nodeID))
                {
                    date = StatisticsFixManager.instance.SaveData.resetTimes[nodeID];

                    if (CityEventManager.CITY_TIME.Year != date.Year ||
                        CityEventManager.CITY_TIME.StartOfWeek(DayOfWeek.Monday).DayOfYear !=
                        date.StartOfWeek(DayOfWeek.Monday).DayOfYear)
                    {
                        resetCounter = true;
                    }
                }
                else
                {
                    resetCounter = true;
                }

                if (resetCounter)
                {
                    StatisticsFixManager.instance.SaveData.resetTimes[nodeID] =
                        CityEventManager.CITY_TIME;
                    data.m_tempCounter  = 0;
                    data.m_finalCounter = 0;
                }
                if (StatisticsFixManager.instance.SaveData.lastWeekPassengerCount == null)
                {
                    StatisticsFixManager.instance.SaveData.lastWeekPassengerCount = new Dictionary <ushort, ushort>();
                }

                StatisticsFixManager.instance.SaveData.lastWeekPassengerCount[nodeID] = data.m_finalCounter;
            }

            if (this.m_publicTransportAccumulation != 0)
            {
                NetManager instance = Singleton <NetManager> .instance;
                int        num      = 0;
                for (int i = 0; i < 8; i++)
                {
                    ushort segment = data.GetSegment(i);
                    if (segment != 0 && (instance.m_segments.m_buffer[(int)segment].m_flags & NetSegment.Flags.PathFailed) == NetSegment.Flags.None)
                    {
                        num += this.m_publicTransportAccumulation >> 1;
                    }
                }
                if (num != 0)
                {
                    int budget = Singleton <EconomyManager> .instance.GetBudget(this.m_info.m_class);

                    int productionRate = PlayerBuildingAI.GetProductionRate(100, budget);
                    num = num * productionRate / 100;
                }
                if (num != 0)
                {
                    Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.PublicTransport, num, data.m_position, this.m_publicTransportRadius);
                }
            }
            if ((data.m_problems & Notification.Problem.LineNotConnected) != Notification.Problem.None && data.CountSegments() <= 1 && (data.m_flags & NetNode.Flags.Temporary) == NetNode.Flags.None)
            {
                GuideController properties = Singleton <GuideManager> .instance.m_properties;
                if (properties != null)
                {
                    Singleton <NetManager> .instance.m_transportNodeNotConnected.Activate(properties.m_lineNotFinished, nodeID, Notification.Problem.LineNotConnected, false);
                }
            }
        }