public override void UpdateNode(ushort nodeID, ref NetNode data)
        {
            if ((data.m_flags & NetNode.Flags.Untouchable) != NetNode.Flags.None)
            {
                ushort index = NetNode.FindOwnerBuilding(nodeID, 32f);
                if (index != 0)
                {
                    BuildingManager      buildingManager = Singleton <BuildingManager> .instance;
                    Notification.Problem oldProblems     = buildingManager.m_buildings.m_buffer[index].m_problems;
                    Notification.Problem newProblems;
                    if (data.CountSegments() != 0)
                    {
                        newProblems = Notification.RemoveProblems(oldProblems, Notification.Problem.WaterNotConnected);
                    }
                    else
                    {
                        newProblems = Notification.AddProblems(oldProblems, Notification.Problem.WaterNotConnected);
                    }
                    if (newProblems != oldProblems)
                    {
                        buildingManager.m_buildings.m_buffer[index].m_problems = newProblems;
                        buildingManager.UpdateNotifications(index, oldProblems, newProblems);
                    }
                }
                data.m_problems = Notification.RemoveProblems(data.m_problems, Notification.Problem.WaterNotConnected);
            }
            float minX = data.m_position.x - 100f;
            float maxX = data.m_position.x + 100f;
            float minZ = data.m_position.z - 100f;
            float maxZ = data.m_position.z + 100f;

            Singleton <WaterManager> .instance.UpdateGrid(minX, minZ, maxX, maxZ);
        }
 public static void Postfix(ushort buildingID, ref Building buildingData, ref Building.Frame frameData)
 {
     // Update problems
     ConstructionAI.ProcessBuildingConstruction(buildingID, ref buildingData, ref frameData);
     if (!buildingData.m_flags.IsFlagSet(Building.Flags.Completed))
     {
         if (MainDataStore.constructionResourceBuffer[buildingID] >= 8000)
         {
             Notification.Problem problem = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoResources);
             buildingData.m_problems = problem;
         }
         else
         {
             if (RealConstruction.debugMode)
             {
                 if (buildingData.m_problems == Notification.Problem.None)
                 {
                     Notification.Problem problem = Notification.AddProblems(buildingData.m_problems, Notification.Problem.NoResources);
                     buildingData.m_problems = problem;
                 }
             }
         }
     }
     else
     {
         Notification.Problem problem = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoResources);
         buildingData.m_problems = problem;
     }
 }
Beispiel #3
0
        //TODO: Maybe move this logic into it's own module later?
        public int HandleWorkers(ushort buildingID, ref Building buildingData, ref Citizen.BehaviourData behaviour, ref int aliveWorkerCount, ref int totalWorkerCount, ref int workPlaceCount)
        {
            int b = 0;

            base.GetWorkBehaviour(buildingID, ref buildingData, ref behaviour, ref aliveWorkerCount, ref totalWorkerCount);
            int num;
            int num2;
            int num3;
            int num4;

            //this.CalculateWorkplaceCount(new Randomizer((int)buildingID), buildingData.Width, buildingData.Length, out num, out num2, out num3, out num4);
            num            = this.occupants.m_workPlaceCount0;
            num2           = this.occupants.m_workPlaceCount1;
            num3           = this.occupants.m_workPlaceCount2;
            num4           = this.occupants.m_workPlaceCount3;
            workPlaceCount = num + num2 + num3 + num4;
            if (buildingData.m_fireIntensity == 0)
            {
                base.HandleWorkPlaces(buildingID, ref buildingData, num, num2, num3, num4, ref behaviour, aliveWorkerCount, totalWorkerCount);
                if (aliveWorkerCount != 0 && workPlaceCount != 0)
                {
                    int num5 = (behaviour.m_efficiencyAccumulation + aliveWorkerCount - 1) / aliveWorkerCount;
                    b = 2 * num5 - 200 * num5 / ((100 * aliveWorkerCount + workPlaceCount - 1) / workPlaceCount + 100);
                }
            }
            Notification.Problem problem = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoWorkers | Notification.Problem.NoEducatedWorkers);
            int num6 = (num4 * 300 + num3 * 200 + num2 * 100) / (workPlaceCount + 1);
            int num7 = (behaviour.m_educated3Count * 300 + behaviour.m_educated2Count * 200 + behaviour.m_educated1Count * 100) / (aliveWorkerCount + 1);

            if (aliveWorkerCount < workPlaceCount >> 1)
            {
                buildingData.m_workerProblemTimer = (byte)Mathf.Min(255, (int)(buildingData.m_workerProblemTimer + 1));
                if (buildingData.m_workerProblemTimer >= 128)
                {
                    problem = Notification.AddProblems(problem, Notification.Problem.NoWorkers | Notification.Problem.MajorProblem);
                }
                else if (buildingData.m_workerProblemTimer >= 64)
                {
                    problem = Notification.AddProblems(problem, Notification.Problem.NoWorkers);
                }
            }
            else if (num7 < num6 - 50)
            {
                buildingData.m_workerProblemTimer = (byte)Mathf.Min(255, (int)(buildingData.m_workerProblemTimer + 1));
                if (buildingData.m_workerProblemTimer >= 128)
                {
                    problem = Notification.AddProblems(problem, Notification.Problem.NoEducatedWorkers | Notification.Problem.MajorProblem);
                }
                else if (buildingData.m_workerProblemTimer >= 64)
                {
                    problem = Notification.AddProblems(problem, Notification.Problem.NoEducatedWorkers);
                }
            }
            else
            {
                buildingData.m_workerProblemTimer = 0;
            }
            buildingData.m_problems = problem;
            return(Mathf.Max(1, b));
        }
Beispiel #4
0
 internal static void CheckNodeProblems(ushort nodeID, ref NetNode data)
 {
     if (data.m_transportLine != 0)
     {
         bool flag = false;
         if ((data.m_flags & NetNode.Flags.Temporary) == NetNode.Flags.None)
         {
             NetManager instance = Singleton <NetManager> .instance;
             int        num      = 0;
             for (int i = 0; i < 8; i++)
             {
                 ushort segment = data.GetSegment(i);
                 if (segment != 0)
                 {
                     num++;
                     if (instance.m_segments.m_buffer[(int)segment].m_path == 0u || (instance.m_segments.m_buffer[(int)segment].m_flags & NetSegment.Flags.PathFailed) != NetSegment.Flags.None)
                     {
                         flag = true;
                     }
                 }
             }
             if (num <= 1)
             {
                 flag = true;
             }
         }
         if (flag)
         {
             data.m_problems = Notification.AddProblems(data.m_problems, Notification.Problem.LineNotConnected);
         }
         else
         {
             data.m_problems = Notification.RemoveProblems(data.m_problems, Notification.Problem.LineNotConnected);
         }
     }
 }
        public static int HandleWorkers(PrivateBuildingAI thisAI, ushort buildingID, ref Building buildingData, ref Citizen.BehaviourData behaviour, ref int aliveWorkerCount, ref int totalWorkerCount, ref int workPlaceCount)
        {
            //Not messed with this code too much yet. Still requires cleaning up.

            int b = 0;
            int level0, level1, level2, level3;

            //Fix for crashing? Modification added for this statement
            if (thisAI != null)
            {
                GetWorkBehaviour(thisAI, buildingID, ref buildingData, ref behaviour, ref aliveWorkerCount, ref totalWorkerCount);
                thisAI.CalculateWorkplaceCount(new Randomizer((int)buildingID), buildingData.Width, buildingData.Length, out level0, out level1, out level2, out level3);
                workPlaceCount = level0 + level1 + level2 + level3;

                if ((int)buildingData.m_fireIntensity == 0)
                {
                    HandleWorkPlaces(thisAI, buildingID, ref buildingData, level0, level1, level2, level3, ref behaviour, aliveWorkerCount, totalWorkerCount);
                    if (aliveWorkerCount != 0 && workPlaceCount != 0)
                    {
                        int num = (behaviour.m_efficiencyAccumulation + aliveWorkerCount - 1) / aliveWorkerCount;
                        b = 2 * num - 200 * num / ((100 * aliveWorkerCount + workPlaceCount - 1) / workPlaceCount + 100);
                    }
                }

                Notification.Problem problems1 = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoWorkers | Notification.Problem.NoEducatedWorkers);
                int num1 = (level3 * 300 + level2 * 200 + level1 * 100) / (workPlaceCount + 1);
                int num2 = (behaviour.m_educated3Count * 300 + behaviour.m_educated2Count * 200 + behaviour.m_educated1Count * 100) / (aliveWorkerCount + 1);

                //Start of modification

                if (Chances.WorkHour())
                {
                    if (aliveWorkerCount < workPlaceCount >> 1)
                    {
                        buildingData.m_workerProblemTimer = (byte)Mathf.Min((int)byte.MaxValue, (int)buildingData.m_workerProblemTimer + 1);
                        if ((int)buildingData.m_workerProblemTimer >= 128)
                        {
                            problems1 = Notification.AddProblems(problems1, Notification.Problem.NoWorkers | Notification.Problem.MajorProblem);
                        }
                        else if ((int)buildingData.m_workerProblemTimer >= 64)
                        {
                            problems1 = Notification.AddProblems(problems1, Notification.Problem.NoWorkers);
                        }
                    }
                    else if (num2 < num1 - 50)
                    {
                        buildingData.m_workerProblemTimer = (byte)Mathf.Min((int)byte.MaxValue, (int)buildingData.m_workerProblemTimer + 1);
                        if ((int)buildingData.m_workerProblemTimer >= 128)
                        {
                            problems1 = Notification.AddProblems(problems1, Notification.Problem.NoEducatedWorkers | Notification.Problem.MajorProblem);
                        }
                        else if ((int)buildingData.m_workerProblemTimer >= 64)
                        {
                            problems1 = Notification.AddProblems(problems1, Notification.Problem.NoEducatedWorkers);
                        }
                    }
                }

                //End of modification

                buildingData.m_problems = problems1;
            }
            return(Mathf.Max(1, b));
        }
Beispiel #6
0
        protected void HandleCrime(ushort buildingID, ref Building data, int crimeAccumulation, int citizenCount)
        {
            int number = 10;

            if (crimeAccumulation != 0)
            {
                ItemClass ic         = data.Info.m_class;
                int       percentage = (int)((ic.m_level >= 0) ? ic.m_level : 0);

                // TODO -  Should be replaced by height of building??
                // Values to be determined and will not be added to XML yet
                if (ic.m_service == ItemClass.Service.Residential)
                {
                    number = 16;

                    if (ic.m_subService == ItemClass.SubService.ResidentialHigh)
                    {
                        crimeAccumulation /= 2;
                    }
                }
                else if (ic.m_service == ItemClass.Service.Office)
                {
                    crimeAccumulation /= 5; // Not enough?
                }
                else if (ic.m_subService == ItemClass.SubService.CommercialHigh)
                {
                    crimeAccumulation /= 3;
                }

                // Percentage reduction
                crimeAccumulation = (crimeAccumulation * (number - percentage)) / number;

                // ----- End of changes -----

                if (Singleton <SimulationManager> .instance.m_isNightTime)
                {
                    // crime multiplies by 1.25 at night
                    crimeAccumulation = crimeAccumulation * 5 >> 2;
                }

                if (data.m_eventIndex != 0)
                {
                    EventManager instance = Singleton <EventManager> .instance;
                    EventInfo    info     = instance.m_events.m_buffer[(int)data.m_eventIndex].Info;
                    crimeAccumulation = info.m_eventAI.GetCrimeAccumulation(data.m_eventIndex, ref instance.m_events.m_buffer[(int)data.m_eventIndex], crimeAccumulation);
                }
                crimeAccumulation = Singleton <SimulationManager> .instance.m_randomizer.Int32((uint)crimeAccumulation);

                if (!Singleton <UnlockManager> .instance.Unlocked(ItemClass.Service.PoliceDepartment))
                {
                    crimeAccumulation = 0;
                }
            }
            data.m_crimeBuffer = (ushort)Mathf.Min(citizenCount * 100, (int)data.m_crimeBuffer + crimeAccumulation);
//Debugging.writeDebugToFile(data.Info.gameObject.name + " -> number:" + citizenCount + ", crime_buffer: " + data.m_crimeBuffer + " + " + crimeAccumulation);
            int crimeBuffer = (int)data.m_crimeBuffer;

            if (citizenCount != 0 && crimeBuffer > citizenCount * 25 && Singleton <SimulationManager> .instance.m_randomizer.Int32(5u) == 0)
            {
                int num  = 0;
                int num2 = 0;
                int num3 = 0;
                int num4 = 0;
                this.CalculateGuestVehicles(buildingID, ref data, TransferManager.TransferReason.Crime, ref num, ref num2, ref num3, ref num4);
                if (num == 0)
                {
                    TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                    offer.Priority = crimeBuffer / Mathf.Max(1, citizenCount * 10);
                    offer.Building = buildingID;
                    offer.Position = data.m_position;
                    offer.Amount   = 1;
                    Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.Crime, offer);
                }
            }
            Notification.Problem problem = Notification.RemoveProblems(data.m_problems, Notification.Problem.Crime);
            if ((int)data.m_crimeBuffer > citizenCount * 90)
            {
                problem = Notification.AddProblems(problem, Notification.Problem.Crime | Notification.Problem.MajorProblem);
            }
            else if ((int)data.m_crimeBuffer > citizenCount * 60)
            {
                problem = Notification.AddProblems(problem, Notification.Problem.Crime);
            }
            data.m_problems = problem;
        }
Beispiel #7
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);
        }
        public override void SimulationStep(ushort segmentID, ref NetSegment data)
        {
            //Start PlayerNEtAI.SimulationStep

            if (this.HasMaintenanceCost(segmentID, ref data))
            {
                NetManager playerNetAIinstance  = Singleton <NetManager> .instance;
                Vector3    playerNetAIposition  = playerNetAIinstance.m_nodes.m_buffer[(int)data.m_startNode].m_position;
                Vector3    playerNetAIposition2 = playerNetAIinstance.m_nodes.m_buffer[(int)data.m_endNode].m_position;
                int        playerNetAInum       = this.GetMaintenanceCost(playerNetAIposition, playerNetAIposition2);
                bool       playerNetAIflag      = (ulong)(Singleton <SimulationManager> .instance.m_currentFrameIndex >> 8 & 15u) == (ulong)((long)(segmentID & 15));
                if (playerNetAInum != 0)
                {
                    if (playerNetAIflag)
                    {
                        playerNetAInum = playerNetAInum * 16 / 100 - playerNetAInum / 100 * 15;
                    }
                    else
                    {
                        playerNetAInum /= 100;
                    }
                    Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.Maintenance, playerNetAInum, this.m_info.m_class);
                }
                if (playerNetAIflag)
                {
                    float playerNetAInum2 = (float)playerNetAIinstance.m_nodes.m_buffer[(int)data.m_startNode].m_elevation;
                    float playerNetAInum3 = (float)playerNetAIinstance.m_nodes.m_buffer[(int)data.m_endNode].m_elevation;
                    if (this.IsUnderground())
                    {
                        playerNetAInum2 = -playerNetAInum2;
                        playerNetAInum3 = -playerNetAInum3;
                    }
                    int constructionCost = this.GetConstructionCost(playerNetAIposition, playerNetAIposition2, playerNetAInum2, playerNetAInum3);
                    if (constructionCost != 0)
                    {
                        StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt64>(StatisticType.CityValue);

                        if (statisticBase != null)
                        {
                            statisticBase.Add(constructionCost);
                        }
                    }
                }
            }
            //End  PlayerNEtAI.SimulationStep

            if (!this.m_invisible)
            {
                NetManager           instance = Singleton <NetManager> .instance;
                Notification.Problem problem  = Notification.RemoveProblems(data.m_problems, Notification.Problem.Flood);
                Vector3 position  = instance.m_nodes.m_buffer[(int)data.m_startNode].m_position;
                Vector3 position2 = instance.m_nodes.m_buffer[(int)data.m_endNode].m_position;
                Vector3 vector    = (position + position2) * 0.5f;
                float   num       = Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(vector));

                if (num > vector.y + ModSettings.PedestrianPathFloodedTolerance)
                {
                    if ((data.m_flags & NetSegment.Flags.Flooded) == NetSegment.Flags.None)
                    {
                        data.m_flags        |= NetSegment.Flags.Flooded;
                        data.m_modifiedIndex = Singleton <SimulationManager> .instance.m_currentBuildIndex++;
                    }
                    problem = Notification.AddProblems(problem, Notification.Problem.Flood | Notification.Problem.MajorProblem);
                }
                else
                {
                    data.m_flags &= ~NetSegment.Flags.Flooded;
                    if (num > vector.y + ModSettings.PedestrianPathFloodingTolerance)
                    {
                        problem = Notification.AddProblems(problem, Notification.Problem.Flood);
                    }
                }
                DistrictManager instance2 = Singleton <DistrictManager> .instance;
                byte            district  = instance2.GetDistrict(vector);
                DistrictPolicies.CityPlanning cityPlanningPolicies = instance2.m_districts.m_buffer[(int)district].m_cityPlanningPolicies;
                if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.BikeBan) != DistrictPolicies.CityPlanning.None)
                {
                    data.m_flags |= NetSegment.Flags.BikeBan;
                }
                else
                {
                    data.m_flags &= ~NetSegment.Flags.BikeBan;
                }
                data.m_problems = problem;
            }
            if ((data.m_flags & NetSegment.Flags.Collapsed) != NetSegment.Flags.None && (ulong)(Singleton <SimulationManager> .instance.m_currentFrameIndex >> 8 & 15u) == (ulong)((long)(segmentID & 15)))
            {
                int           delta         = Mathf.RoundToInt(data.m_averageLength);
                StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt32>(StatisticType.DestroyedLength);

                statisticBase.Add(delta);
            }
        }
Beispiel #9
0
        public override void SimulationStep(ushort eventID, ref EventData data)
        {
            //begin mod
            var crawlerVehicle = Configuration.Get(eventID).Crawler;
            var rocketVehicle  = Configuration.Get(eventID).Rocket;
            //end mod
            VehicleManager  instance1 = Singleton <VehicleManager> .instance;
            BuildingManager instance2 = Singleton <BuildingManager> .instance;
            EventManager    instance3 = Singleton <EventManager> .instance;
            ushort          vehicleID1;
            ushort          vehicleID2;

            this.FindVehicles(eventID, ref data, out vehicleID1, out vehicleID2);
            bool flag1 = false;

            if ((data.m_flags & (EventData.Flags.Active | EventData.Flags.Expired | EventData.Flags.Completed | EventData.Flags.Disorganizing | EventData.Flags.Cancelled)) == EventData.Flags.None)
            {
                if ((data.m_flags & EventData.Flags.Ready) == EventData.Flags.None && this.m_resourceConsumption != 0)
                {
                    int num1 = (int)data.m_popularityDelta * 10;
                    int num2 = Mathf.Clamp(num1 / this.m_resourceConsumption, 0, 256);
                    data.m_startFrame  += (uint)(256 - num2);
                    data.m_expireFrame += (uint)(256 - num2);
                    int num3 = num1 - num2 * this.m_resourceConsumption;
                    data.m_popularityDelta = (short)Mathf.Clamp(num3 / 10, 0, (int)short.MaxValue);
                    int  num4 = 0;
                    uint currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                    if (data.m_startFrame > currentFrameIndex)
                    {
                        num4 = ((int)data.m_startFrame - (int)currentFrameIndex) * this.m_resourceConsumption;
                    }
                    if ((int)data.m_building != 0 && num4 > num3)
                    {
                        int    num5       = 100000;
                        ushort vehicleID3 = instance2.m_buildings.m_buffer[(int)data.m_building].m_guestVehicles;
                        int    num6       = 0;
                        while ((int)vehicleID3 != 0)
                        {
                            switch ((TransferManager.TransferReason)instance1.m_vehicles.m_buffer[(int)vehicleID3].m_transferType)
                            {
                            case TransferManager.TransferReason.Coal:
                            case TransferManager.TransferReason.Petrol:
                                int size;
                                int max;
                                instance1.m_vehicles.m_buffer[(int)vehicleID3].Info.m_vehicleAI.GetSize(vehicleID3, ref instance1.m_vehicles.m_buffer[(int)vehicleID3], out size, out max);
                                num3 += Mathf.Min(size, max);
                                break;
                            }
                            vehicleID3 = instance1.m_vehicles.m_buffer[(int)vehicleID3].m_nextGuestVehicle;
                            if (++num6 > 16384)
                            {
                                CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace);

                                break;
                            }
                        }
                        if (num3 <= num5 - 8000)
                        {
                            Singleton <TransferManager> .instance.AddIncomingOffer((data.m_flags & EventData.Flags.Preparing) == EventData.Flags.None?TransferManager.TransferReason.Coal : TransferManager.TransferReason.Petrol, new TransferManager.TransferOffer()
                            {
                                Priority = Mathf.Max(1, (num5 - num3) * 8 / num5),
                                Building = data.m_building,
                                Position = instance2.m_buildings.m_buffer[(int)data.m_building].m_position,
                                Amount   = 1,
                                Active   = false
                            });
                        }
                        if (num3 < 16000)
                        {
                            flag1 = true;
                        }
                    }
                }
                if ((data.m_flags & (EventData.Flags.Preparing | EventData.Flags.Ready)) != EventData.Flags.None && (int)data.m_building != 0)
                {
                    if ((int)vehicleID1 == 0 && crawlerVehicle != null)
                    {
                        Vector3 position = instance2.m_buildings.m_buffer[(int)data.m_building].CalculatePosition(this.m_rocketSpawnPosition);
                        if (instance1.CreateVehicle(out vehicleID1, ref Singleton <SimulationManager> .instance.m_randomizer, crawlerVehicle, position, TransferManager.TransferReason.None, false, false))
                        {
                            crawlerVehicle.m_vehicleAI.SetSource(vehicleID1, ref instance1.m_vehicles.m_buffer[(int)vehicleID1], data.m_building);
                            crawlerVehicle.m_vehicleAI.SetTarget(vehicleID1, ref instance1.m_vehicles.m_buffer[(int)vehicleID1], data.m_building);
                        }
                    }
                    if ((int)vehicleID1 != 0 && (int)vehicleID2 == 0 && rocketVehicle != null)
                    {
                        Vector3 position = instance2.m_buildings.m_buffer[(int)data.m_building].CalculatePosition(this.m_rocketSpawnPosition);
                        if (instance1.CreateVehicle(out vehicleID2, ref Singleton <SimulationManager> .instance.m_randomizer, rocketVehicle, position, TransferManager.TransferReason.None, false, false))
                        {
                            rocketVehicle.m_vehicleAI.SetSource(vehicleID2, ref instance1.m_vehicles.m_buffer[(int)vehicleID2], data.m_building);
                            rocketVehicle.m_vehicleAI.SetTarget(vehicleID2, ref instance1.m_vehicles.m_buffer[(int)vehicleID2], data.m_building);
                            ushort lastVehicle = instance1.m_vehicles.m_buffer[(int)vehicleID1].GetLastVehicle(vehicleID1);
                            if ((int)lastVehicle != 0)
                            {
                                instance1.m_vehicles.m_buffer[(int)vehicleID2].m_leadingVehicle   = lastVehicle;
                                instance1.m_vehicles.m_buffer[(int)lastVehicle].m_trailingVehicle = vehicleID2;
                            }
                        }
                    }
                }
            }
            if ((int)data.m_building != 0)
            {
                ushort num = instance2.m_buildings.m_buffer[(int)data.m_building].m_eventIndex;
                if ((int)num == (int)eventID)
                {
                    Notification.Problem problems = instance2.m_buildings.m_buffer[(int)data.m_building].m_problems;
                    Notification.Problem problem  = Notification.RemoveProblems(problems, Notification.Problem.NoResources);
                    if (flag1)
                    {
                        instance2.m_buildings.m_buffer[(int)data.m_building].m_incomingProblemTimer = (byte)Mathf.Min((int)byte.MaxValue, (int)instance2.m_buildings.m_buffer[(int)data.m_building].m_incomingProblemTimer + 1);
                        if ((int)instance2.m_buildings.m_buffer[(int)data.m_building].m_incomingProblemTimer >= 4)
                        {
                            problem = Notification.AddProblems(problem, Notification.Problem.NoResources);
                        }
                    }
                    else
                    {
                        instance2.m_buildings.m_buffer[(int)data.m_building].m_incomingProblemTimer = (byte)0;
                    }
                    if (problem != problems)
                    {
                        instance2.m_buildings.m_buffer[(int)data.m_building].m_problems = problem;
                        Singleton <BuildingManager> .instance.UpdateNotifications(data.m_building, problems, problem);
                    }
                    GuideController properties = Singleton <GuideManager> .instance.m_properties;
                    if (properties != null)
                    {
                        Singleton <BuildingManager> .instance.m_rocketLaunchSite.Activate(properties.m_rocketLaunchSite, data.m_building);
                    }
                }
                if ((int)num != 0 && (instance3.m_events.m_buffer[(int)num].m_flags & (EventData.Flags.Preparing | EventData.Flags.Active | EventData.Flags.Completed | EventData.Flags.Cancelled | EventData.Flags.Ready)) == EventData.Flags.None)
                {
                    num = instance3.m_events.m_buffer[(int)num].m_nextBuildingEvent;
                }
                bool flag2 = false;
                if ((int)vehicleID1 != 0 && crawlerVehicle != null)
                {
                    Vector3 position          = instance2.m_buildings.m_buffer[(int)data.m_building].CalculatePosition(this.m_doorPosition);
                    Vector3 lastFramePosition = instance1.m_vehicles.m_buffer[(int)vehicleID1].GetLastFramePosition();
                    Vector3 targetPos0        = (Vector3)instance1.m_vehicles.m_buffer[(int)vehicleID1].m_targetPos0;
                    Vector3 b = lastFramePosition + Vector3.ClampMagnitude(targetPos0 - lastFramePosition, crawlerVehicle.m_maxSpeed * 16f);
                    flag2 = (double)Vector3.Distance(position, b) < 40.0;
                }
                if (flag2)
                {
                    if ((data.m_flags & EventData.Flags.Loading) == EventData.Flags.None)
                    {
                        data.m_flags |= EventData.Flags.Loading;
                        if (this.m_doorOpenEffect != null && (int)num == (int)eventID)
                        {
                            InstanceID instance4 = new InstanceID();
                            instance4.Event = eventID;
                            EffectInfo.SpawnArea spawnArea = new EffectInfo.SpawnArea(Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)data.m_building].CalculatePosition(this.m_doorPosition), Vector3.up, 10f);
                            Singleton <EffectManager> .instance.DispatchEffect(this.m_doorOpenEffect, instance4, spawnArea, Vector3.zero, 0.0f, 1f, Singleton <AudioManager> .instance.DefaultGroup);
                        }
                    }
                }
                else if ((data.m_flags & EventData.Flags.Loading) != EventData.Flags.None)
                {
                    data.m_flags &= ~EventData.Flags.Loading;
                    if (this.m_doorCloseEffect != null && (int)num == (int)eventID)
                    {
                        InstanceID instance4 = new InstanceID();
                        instance4.Event = eventID;
                        EffectInfo.SpawnArea spawnArea = new EffectInfo.SpawnArea(Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)data.m_building].CalculatePosition(this.m_doorPosition), Vector3.up, 10f);
                        Singleton <EffectManager> .instance.DispatchEffect(this.m_doorCloseEffect, instance4, spawnArea, Vector3.zero, 0.0f, 1f, Singleton <AudioManager> .instance.DefaultGroup);
                    }
                }
            }
            base.SimulationStep(eventID, ref data);
        }
        private void CheckBuildingLevel(ushort buildingID, ref Building buildingData, ref Building.Frame frameData, ref Citizen.BehaviourData behaviour)
        {
            DistrictManager instance = Singleton <DistrictManager> .instance;
            byte            district = instance.GetDistrict(buildingData.m_position);

            DistrictPolicies.CityPlanning cityPlanningPolicies = instance.m_districts.m_buffer[(int)district].m_cityPlanningPolicies;
            int num  = behaviour.m_educated1Count + behaviour.m_educated2Count * 2 + behaviour.m_educated3Count * 3;
            int num2 = behaviour.m_teenCount + behaviour.m_youngCount * 2 + behaviour.m_adultCount * 3 + behaviour.m_seniorCount * 3;
            int averageEducation;

            ItemClass.Level level;
            int             num3;

            if (num2 != 0)
            {
                averageEducation = (num * 300 + (num2 >> 1)) / num2;
                num = (num * 72 + (num2 >> 1)) / num2;
                if (num < 15)
                {
                    level = ItemClass.Level.Level1;
                    num3  = 1 + num;
                }
                else if (num < 30)
                {
                    level = ItemClass.Level.Level2;
                    num3  = 1 + (num - 15);
                }
                else if (num < 45)
                {
                    level = ItemClass.Level.Level3;
                    num3  = 1 + (num - 30);
                }
                else if (num < 60)
                {
                    level = ItemClass.Level.Level4;
                    num3  = 1 + (num - 45);
                }
                else
                {
                    level = ItemClass.Level.Level5;
                    num3  = 1;
                }
                if (level < this.m_info.m_class.m_level)
                {
                    num3 = 1;
                }
                else if (level > this.m_info.m_class.m_level)
                {
                    num3 = 15;
                }
            }
            else
            {
                level            = ItemClass.Level.Level1;
                averageEducation = 0;
                num3             = 0;
            }
            int num4;

            Singleton <ImmaterialResourceManager> .instance.CheckLocalResource(ImmaterialResourceManager.Resource.LandValue, buildingData.m_position, out num4);

            ItemClass.Level level2;
            int             num5;

            if (num3 != 0)
            {
                if (num4 < 6)
                {
                    level2 = ItemClass.Level.Level1;
                    num5   = 1 + (num4 * 15 + 3) / 6;
                }
                else if (num4 < 21)
                {
                    level2 = ItemClass.Level.Level2;
                    num5   = 1 + ((num4 - 6) * 15 + 7) / 15;
                }
                else if (num4 < 41)
                {
                    level2 = ItemClass.Level.Level3;
                    num5   = 1 + ((num4 - 21) * 15 + 10) / 20;
                }
                else if (num4 < 61)
                {
                    level2 = ItemClass.Level.Level4;
                    num5   = 1 + ((num4 - 41) * 15 + 10) / 20;
                }
                else
                {
                    level2 = ItemClass.Level.Level5;
                    num5   = 1;
                }
                if (level2 < this.m_info.m_class.m_level)
                {
                    num5 = 1;
                }
                else if (level2 > this.m_info.m_class.m_level)
                {
                    num5 = 15;
                }
            }
            else
            {
                level2 = ItemClass.Level.Level1;
                num5   = 0;
            }
            bool flag = false;

            if (this.m_info.m_class.m_level == ItemClass.Level.Level2)
            {
                if (num4 == 0)
                {
                    flag = true;
                }
            }
            else if (this.m_info.m_class.m_level == ItemClass.Level.Level3)
            {
                if (num4 < 11)
                {
                    flag = true;
                }
            }
            else if (this.m_info.m_class.m_level == ItemClass.Level.Level4)
            {
                if (num4 < 31)
                {
                    flag = true;
                }
            }
            else if (this.m_info.m_class.m_level == ItemClass.Level.Level5 && num4 < 51)
            {
                flag = true;
            }
            ItemClass.Level level3 = (ItemClass.Level)Mathf.Min((int)level, (int)level2);
            Singleton <BuildingManager> .instance.m_LevelUpWrapper.OnCalculateResidentialLevelUp(ref level3, ref num3, ref num5, ref flag, averageEducation, num4, buildingID, this.m_info.m_class.m_service, this.m_info.m_class.m_subService, this.m_info.m_class.m_level);

            if (flag)
            {
                buildingData.m_serviceProblemTimer = (byte)Mathf.Min(255, (int)(buildingData.m_serviceProblemTimer + 1));
                if (buildingData.m_serviceProblemTimer >= 8)
                {
                    buildingData.m_problems = Notification.AddProblems(buildingData.m_problems, Notification.Problem.LandValueLow | Notification.Problem.MajorProblem);
                }
                else if (buildingData.m_serviceProblemTimer >= 4)
                {
                    buildingData.m_problems = Notification.AddProblems(buildingData.m_problems, Notification.Problem.LandValueLow);
                }
                else
                {
                    buildingData.m_problems = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.LandValueLow);
                }
            }
            else
            {
                buildingData.m_serviceProblemTimer = 0;
                buildingData.m_problems            = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.LandValueLow);
            }

/* Remove high rise ban
 *          if (level3 > this.m_info.m_class.m_level)
 *          {
 *              num3 = 0;
 *              num5 = 0;
 *              if (this.m_info.m_class.m_subService == ItemClass.SubService.ResidentialHigh && (cityPlanningPolicies & DistrictPolicies.CityPlanning.HighriseBan) != DistrictPolicies.CityPlanning.None && level3 == ItemClass.Level.Level5)
 *              {
 *                  District[] expr_41B_cp_0 = instance.m_districts.m_buffer;
 *                  byte expr_41B_cp_1 = district;
 *                  expr_41B_cp_0[(int)expr_41B_cp_1].m_cityPlanningPoliciesEffect = (expr_41B_cp_0[(int)expr_41B_cp_1].m_cityPlanningPoliciesEffect | DistrictPolicies.CityPlanning.HighriseBan);
 *                  level3 = ItemClass.Level.Level4;
 *                  num3 = 1;
 *              }
 *              if (buildingData.m_problems == Notification.Problem.None && level3 > this.m_info.m_class.m_level && this.GetUpgradeInfo(buildingID, ref buildingData) != null)
 *              {
 *                  frameData.m_constructState = 0;
 *                  base.StartUpgrading(buildingID, ref buildingData);
 *              }
 *          }
 */
            buildingData.m_levelUpProgress = (byte)(num3 | num5 << 4);
        }
        public static void ProcessBuildingDataFinal(ushort buildingID, ref Building buildingData)
        {
            if (RealCityPrivateBuildingAI.preBuidlingId > buildingID)
            {
                RealCityPrivateBuildingAI.allOfficeHighTechWorkCountFinal = RealCityPrivateBuildingAI.allOfficeHighTechWorkCount;
                RealCityPrivateBuildingAI.allOfficeLevel1WorkCountFinal   = RealCityPrivateBuildingAI.allOfficeLevel1WorkCount;
                RealCityPrivateBuildingAI.allOfficeLevel2WorkCountFinal   = RealCityPrivateBuildingAI.allOfficeLevel2WorkCount;
                RealCityPrivateBuildingAI.allOfficeLevel3WorkCountFinal   = RealCityPrivateBuildingAI.allOfficeLevel3WorkCount;
                RealCityPrivateBuildingAI.profitBuildingCountFinal        = RealCityPrivateBuildingAI.profitBuildingCount;
                BuildingData.commBuildingNumFinal                    = BuildingData.commBuildingNum;
                BuildingData.commBuildingNum                         = 0;
                RealCityPrivateBuildingAI.profitBuildingCount        = 0;
                RealCityPrivateBuildingAI.allOfficeLevel1WorkCount   = 0;
                RealCityPrivateBuildingAI.allOfficeLevel2WorkCount   = 0;
                RealCityPrivateBuildingAI.allOfficeLevel3WorkCount   = 0;
                RealCityPrivateBuildingAI.allOfficeHighTechWorkCount = 0;
            }
            RealCityPrivateBuildingAI.preBuidlingId = buildingID;
            if (buildingData.Info.m_class.m_service == ItemClass.Service.Residential)
            {
                BuildingData.buildingMoney[buildingID] = 0;
            }

            float building_money = BuildingData.buildingMoney[buildingID];

            if (buildingData.Info.m_class.m_service == ItemClass.Service.Industrial)
            {
                if (building_money < 0)
                {
                    RealCityEconomyExtension.industrialLackMoneyCount++;
                }
                else
                {
                    RealCityEconomyExtension.industrialEarnMoneyCount++;
                }
            }

            if (building_money < 0)
            {
                BuildingData.buildingMoneyThreat[buildingID] = 1.0f;
            }

            switch (buildingData.Info.m_class.m_service)
            {
            case ItemClass.Service.Residential:
                float familyMoney = GetResidentialBuildingAverageMoney(buildingData);
                if (familyMoney < (MainDataStore.highWealth >> 1))
                {
                    BuildingData.buildingMoneyThreat[buildingID] = 1.0f - familyMoney / MainDataStore.highWealth;
                }
                else
                {
                    BuildingData.buildingMoneyThreat[buildingID] = (((MainDataStore.highWealth << 1) - (MainDataStore.highWealth >> 1)) - familyMoney) / (MainDataStore.highWealth << 1);
                }

                if (BuildingData.buildingMoneyThreat[buildingID] < 0)
                {
                    BuildingData.buildingMoneyThreat[buildingID] = 0;
                }
                break;

            case ItemClass.Service.Commercial:
            case ItemClass.Service.Industrial:
            case ItemClass.Service.Office:
                float averageBuildingSalary = BuildingUI.CaculateEmployeeOutcome(buildingData, out _);

                if (MainDataStore.citizenCount > 0.0)
                {
                    float averageCitySalary = MainDataStore.citizenSalaryTotal / MainDataStore.citizenCount;
                    float salaryFactor      = averageBuildingSalary / averageCitySalary;
                    if (salaryFactor > 3f)
                    {
                        salaryFactor = 3f;
                    }
                    else if (salaryFactor < 0.0f)
                    {
                        salaryFactor = 0.0f;
                    }

                    BuildingData.buildingMoneyThreat[buildingID] = (1.0f - salaryFactor / 3f);
                }
                else
                {
                    BuildingData.buildingMoneyThreat[buildingID] = 1.0f;
                }

                break;
            }

            if (buildingData.Info.m_class.m_service == ItemClass.Service.Commercial)
            {
                //get all commercial building for resident.
                if (buildingData.m_customBuffer2 > 2000)
                {
                    BuildingData.commBuildingNum++;
                    BuildingData.commBuildingID[BuildingData.commBuildingNum] = buildingID;
                }
                if (BuildingData.buildingMoney[buildingID] < 0)
                {
                    RealCityEconomyExtension.commercialLackMoneyCount++;
                }
                else
                {
                    RealCityEconomyExtension.commercialEarnMoneyCount++;
                }
            }

            if (buildingData.m_problems == Notification.Problem.None)
            {
                //mark no good
                if ((buildingData.Info.m_class.m_service == ItemClass.Service.Commercial) && (RealCity.debugMode))
                {
                    Notification.Problem problem = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoGoods);
                    if (buildingData.m_customBuffer2 < 500)
                    {
                        problem = Notification.AddProblems(problem, Notification.Problem.NoGoods | Notification.Problem.MajorProblem);
                    }
                    else if (buildingData.m_customBuffer2 < 1000)
                    {
                        problem = Notification.AddProblems(problem, Notification.Problem.NoGoods);
                    }
                    else
                    {
                        problem = Notification.Problem.None;
                    }
                    buildingData.m_problems = problem;
                }
            }
        }
Beispiel #12
0
        public static void SimulationStep(ref TransportLine thisLine, ushort lineID)
        {
            //begin mod(+): change for initialization
            if (!CachedTransportLineData._init)
            {
                return;
            }
            //end mod

            TransportInfo     info      = thisLine.Info;
            NetManager        instance1 = Singleton <NetManager> .instance;
            SimulationManager instance2 = Singleton <SimulationManager> .instance;

            Notification.Problem problems1 = Notification.Problem.None;
            Notification.Problem problem1  = Notification.Problem.None;
            Notification.Problem problem2  = Notification.Problem.None;
            Notification.Problem problems2 = Notification.Problem.TooLong | Notification.Problem.MajorProblem;
            if ((int)thisLine.m_stops != 0)
            {
                problem1  = instance1.m_nodes.m_buffer[(int)thisLine.m_stops].m_problems;
                problems1 = problem1;
            }
            bool  flag1 = (instance2.m_currentFrameIndex & 4095U) >= 3840U;
            float num1  = 0.0f;
            bool  flag2 = false;

            if (thisLine.Complete)
            {
                //begin mod(*): moved this section to a separate method
                int num3 = CountLineActiveVehicles(lineID, out int num2);
                //end mod
                bool flag3 = !instance2.m_isNightTime
                    ? (thisLine.m_flags & TransportLine.Flags.DisabledDay) == TransportLine.Flags.None
                    : (thisLine.m_flags & TransportLine.Flags.DisabledNight) == TransportLine.Flags.None;
                uint range = 0;
                int  num6  = 0;
                int  num7  = 0;
                int  num8  = 0;
                if ((int)thisLine.m_stops != 0)
                {
                    CitizenManager instance3 = Singleton <CitizenManager> .instance;
                    ushort         stops     = thisLine.m_stops;
                    ushort         num4      = stops;
                    int            num5      = 0;
                    while ((int)num4 != 0)
                    {
                        ushort num9 = 0;
                        if (flag3)
                        {
                            instance1.m_nodes.m_buffer[(int)num4].m_flags &=
                                NetNode.Flags.OneWayOutTrafficLights | NetNode.Flags.UndergroundTransition |
                                NetNode.Flags.Created | NetNode.Flags.Deleted | NetNode.Flags.Original |
                                NetNode.Flags.End | NetNode.Flags.Middle | NetNode.Flags.Bend | NetNode.Flags.Junction |
                                NetNode.Flags.Moveable | NetNode.Flags.Untouchable | NetNode.Flags.Outside |
                                NetNode.Flags.Temporary | NetNode.Flags.Double | NetNode.Flags.Fixed |
                                NetNode.Flags.OnGround | NetNode.Flags.Ambiguous | NetNode.Flags.Water |
                                NetNode.Flags.Sewage | NetNode.Flags.ForbidLaneConnection |
                                NetNode.Flags.LevelCrossing | NetNode.Flags.OneWayIn | NetNode.Flags.Heating |
                                NetNode.Flags.Electricity | NetNode.Flags.Collapsed | NetNode.Flags.DisableOnlyMiddle |
                                NetNode.Flags.AsymForward | NetNode.Flags.AsymBackward |
                                NetNode.Flags.CustomTrafficLights;
                        }
                        else
                        {
                            instance1.m_nodes.m_buffer[(int)num4].m_flags |= NetNode.Flags.Disabled;
                        }
                        problem2 |= (instance1.m_nodes.m_buffer[(int)num4].m_problems ^ problem1) & problems2;
                        for (int index = 0; index < 8; ++index)
                        {
                            ushort segment = instance1.m_nodes.m_buffer[(int)num4].GetSegment(index);
                            if ((int)segment != 0 && (int)instance1.m_segments.m_buffer[(int)segment].m_startNode ==
                                (int)num4)
                            {
                                num6 +=
                                    Mathf.Max((int)instance1.m_segments.m_buffer[(int)segment].m_trafficLightState0,
                                              (int)instance1.m_segments.m_buffer[(int)segment].m_trafficLightState1);
                                num1 += instance1.m_segments.m_buffer[(int)segment].m_averageLength;
                                num7 += (int)instance1.m_segments.m_buffer[(int)segment].m_trafficBuffer;
                                num9  = instance1.m_segments.m_buffer[(int)segment].m_endNode;
                                if ((instance1.m_segments.m_buffer[(int)segment].m_flags &
                                     NetSegment.Flags.PathLength) == NetSegment.Flags.None)
                                {
                                    flag2 = true;
                                    break;
                                }
                                break;
                            }
                        }
                        ushort num10 = instance1.m_nodes.m_buffer[(int)num4].m_targetCitizens;
                        int    num11 = 0;
                        while ((int)num10 != 0)
                        {
                            ++num8;
                            num10 = instance3.m_instances.m_buffer[(int)num10].m_nextTargetInstance;
                            if (++num11 >= 32768)
                            {
                                CODebugBase <LogChannel> .Error(LogChannel.Core,
                                                                "Invalid list detected!\n" + System.Environment.StackTrace);

                                break;
                            }
                        }
                        ++range;
                        num4 = num9;
                        if ((int)num4 != (int)stops)
                        {
                            if (++num5 >= 32768)
                            {
                                CODebugBase <LogChannel> .Error(LogChannel.Core,
                                                                "Invalid list detected!\n" + System.Environment.StackTrace);

                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                if (!flag2)
                {
                    thisLine.m_totalLength = num1;
                }
                if ((int)range != 0)
                {
                    thisLine.m_averageInterval = (byte)Mathf.Min((float)byte.MaxValue,
                                                                 (float)(((long)num6 + (long)(range >> 1)) / (long)range));
                }
                //begin mod(-): let's count maintenance once a week
                //end mod
                TransferManager.TransferReason vehicleReason = info.m_vehicleReason;
                if (vehicleReason != TransferManager.TransferReason.None)
                {
                    //begin mod: calculate target vehicle count or read saved value
                    int num4 = 0;
                    if (CachedTransportLineData._lineData[(int)lineID].BudgetControl || info.m_class.m_service == ItemClass.Service.Disaster)
                    {
                        num4 = !flag3 ? 0 : (!flag2 ? thisLine.CalculateTargetVehicleCount() : num3);
                        CachedTransportLineData._lineData[(int)lineID].TargetVehicleCount = num4;
                    }
                    else if (flag3)
                    {
                        num4 = CachedTransportLineData._lineData[(int)lineID].TargetVehicleCount;
                    }
                    //end mod
                    if (range != 0U && num2 < num4)
                    {
                        ushort stop = thisLine.GetStop(instance2.m_randomizer.Int32(range));
                        if (stop != (ushort)0)
                        {
                            Singleton <TransferManager> .instance.AddIncomingOffer(vehicleReason, new TransferManager.TransferOffer()
                            {
                                Priority      = num4 - num2 + 1,
                                TransportLine = lineID,
                                Position      = instance1.m_nodes.m_buffer[(int)stop].m_position,
                                Amount        = 1,
                                Active        = false
                            });
                        }
                    }
                    else if (num3 > num4)
                    {
                        //begin mod(*): encapsulate into method
                        TransportLineDetour.RemoveActiveVehicle(lineID, false, num3);
                        //end mod
                    }
                }
                TransferManager.TransferReason material = info.m_citizenReason;
                switch (material)
                {
                case TransferManager.TransferReason.None:
                    goto label_99;

                case TransferManager.TransferReason.Entertainment:
                    switch (instance2.m_randomizer.Int32(4U))
                    {
                    case 0:
                        material = TransferManager.TransferReason.Entertainment;
                        break;

                    case 1:
                        material = TransferManager.TransferReason.EntertainmentB;
                        break;

                    case 2:
                        material = TransferManager.TransferReason.EntertainmentC;
                        break;

                    case 3:
                        material = TransferManager.TransferReason.EntertainmentD;
                        break;
                    }
                    //begin mod: to shut up compiler
                    break;

                //end mod
                case TransferManager.TransferReason.TouristA:
                    switch (instance2.m_randomizer.Int32(20U))
                    {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                        material = TransferManager.TransferReason.TouristA;
                        break;

                    case 4:
                    case 5:
                    case 6:
                    case 7:
                        material = TransferManager.TransferReason.TouristB;
                        break;

                    case 8:
                    case 9:
                    case 10:
                    case 11:
                        material = TransferManager.TransferReason.TouristC;
                        break;

                    case 12:
                    case 13:
                    case 14:
                    case 15:
                        material = TransferManager.TransferReason.TouristD;
                        break;

                    case 16:
                        material = TransferManager.TransferReason.Entertainment;
                        break;

                    case 17:
                        material = TransferManager.TransferReason.EntertainmentB;
                        break;

                    case 18:
                        material = TransferManager.TransferReason.EntertainmentC;
                        break;

                    case 19:
                        material = TransferManager.TransferReason.EntertainmentD;
                        break;
                    }
                    //begin mod: to shut up compiler
                    break;
                    //end mod
                }
                if (vehicleReason == TransferManager.TransferReason.None)
                {
                    if ((double)thisLine.m_totalLength <= 1920.0)
                    {
                        if (!flag2)
                        {
                            problems1 = Notification.RemoveProblems(problems1, Notification.Problem.TooLong);
                        }
                    }
                    else if ((double)thisLine.m_totalLength <= 3840.0)
                    {
                        if (!flag2)
                        {
                            problems1 = Notification.RemoveProblems(problems1, Notification.Problem.TooLong);
                        }
                        num7 = (num7 * 17 + 10) / 20;
                    }
                    else if ((double)thisLine.m_totalLength <= 5760.0)
                    {
                        if (!flag2)
                        {
                            problems1 =
                                Notification.AddProblems(
                                    Notification.RemoveProblems(problems1, Notification.Problem.TooLong),
                                    Notification.Problem.TooLong);
                        }
                        num7 = (num7 * 14 + 10) / 20;
                    }
                    else
                    {
                        if (!flag2)
                        {
                            problems1 = Notification.AddProblems(problems1,
                                                                 Notification.Problem.TooLong | Notification.Problem.MajorProblem);
                        }
                        num7 = (num7 * 8 + 10) / 20;
                    }
                    if (flag1)
                    {
                        Singleton <StatisticsManager> .instance.Acquire <StatisticInt32>(StatisticType.WalkingTourLength)
                        .Add(Mathf.RoundToInt(thisLine.m_totalLength));
                    }
                }
                else
                {
                    num7 = Mathf.Max(0,
                                     num7 + 50 - (int)thisLine.m_ticketPrice * 50 / Mathf.Max(1, info.m_ticketPrice));
                }
                int num12;
                if (flag3)
                {
                    if (flag2)
                    {
                        num12 = num8;
                    }
                    else
                    {
                        int num4 = Mathf.Max(1, info.m_citizenPullRequirement);
                        num12 = (num7 + num4 - 1) / num4;
                    }
                }
                else
                {
                    num12 = 0;
                }
                if ((int)range != 0 && num8 < num12)
                {
                    ushort stop = thisLine.GetStop(instance2.m_randomizer.Int32(range));
                    if ((int)stop != 0)
                    {
                        Singleton <TransferManager> .instance.AddOutgoingOffer(material,
                                                                               new TransferManager.TransferOffer()
                        {
                            Priority      = Mathf.Max(1, (num12 - num8) * 8 / num12),
                            TransportLine = lineID,
                            Position      = Singleton <NetManager> .instance.m_nodes.m_buffer[(int)stop].m_position,
                            Amount        = 1,
                            Active        = false
                        });
                    }
                }
            }
            else
            {
                if ((int)thisLine.m_stops != 0)
                {
                    ushort stops = thisLine.m_stops;
                    ushort num2  = stops;
                    int    num3  = 0;
                    while ((int)num2 != 0)
                    {
                        ushort num4 = 0;
                        problem2 |= (instance1.m_nodes.m_buffer[(int)num2].m_problems ^ problem1) & problems2;
                        for (int index = 0; index < 8; ++index)
                        {
                            ushort segment = instance1.m_nodes.m_buffer[(int)num2].GetSegment(index);
                            if ((int)segment != 0 && (int)instance1.m_segments.m_buffer[(int)segment].m_startNode ==
                                (int)num2)
                            {
                                num1 += instance1.m_segments.m_buffer[(int)segment].m_averageLength;
                                num4  = instance1.m_segments.m_buffer[(int)segment].m_endNode;
                                if ((instance1.m_segments.m_buffer[(int)segment].m_flags &
                                     NetSegment.Flags.PathLength) == NetSegment.Flags.None)
                                {
                                    flag2 = true;
                                    break;
                                }
                                break;
                            }
                        }
                        num2 = num4;
                        if ((int)num2 != (int)stops)
                        {
                            if (++num3 >= 32768)
                            {
                                CODebugBase <LogChannel> .Error(LogChannel.Core,
                                                                "Invalid list detected!\n" + System.Environment.StackTrace);

                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                if (!flag2)
                {
                    thisLine.m_totalLength = num1;
                    if (info.m_citizenReason != TransferManager.TransferReason.None &&
                        info.m_vehicleReason == TransferManager.TransferReason.None)
                    {
                        problems1 = (double)thisLine.m_totalLength > 1920.0
                            ? ((double)thisLine.m_totalLength > 3840.0
                                ? ((double)thisLine.m_totalLength > 5760.0
                                    ? Notification.AddProblems(problems1,
                                                               Notification.Problem.TooLong | Notification.Problem.MajorProblem)
                                    : Notification.AddProblems(
                                       Notification.RemoveProblems(problems1, Notification.Problem.TooLong),
                                       Notification.Problem.TooLong))
                                : Notification.RemoveProblems(problems1, Notification.Problem.TooLong))
                            : Notification.RemoveProblems(problems1, Notification.Problem.TooLong);
                    }
                }
            }
label_99:
            if ((int)thisLine.m_stops != 0 && (problem2 | problems1 ^ problem1) != Notification.Problem.None)
            {
                ushort stops = thisLine.m_stops;
                ushort num2  = stops;
                int    num3  = 0;
                while ((int)num2 != 0)
                {
                    Notification.Problem problems = instance1.m_nodes.m_buffer[(int)num2].m_problems;
                    Notification.Problem problem3 = Notification.RemoveProblems(problems, problems2);
                    if ((problems1 & problems2 &
                         ~(Notification.Problem.MajorProblem | Notification.Problem.FatalProblem)) !=
                        Notification.Problem.None)
                    {
                        problem3 = Notification.AddProblems(problem3, problems1 & problems2);
                    }
                    if (problems != problem3)
                    {
                        instance1.m_nodes.m_buffer[(int)num2].m_problems = problem3;
                        instance1.UpdateNodeNotifications(num2, problems, problem3);
                    }
                    num2 = TransportLine.GetNextStop(num2);
                    if ((int)num2 != (int)stops)
                    {
                        if (++num3 >= 32768)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core,
                                                            "Invalid list detected!\n" + System.Environment.StackTrace);

                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            if (!flag1)
            {
                return;
            }
            thisLine.m_passengers.Update();
            Singleton <TransportManager> .instance.m_passengers[(int)info.m_transportType]
            .Add(ref thisLine.m_passengers);
            thisLine.m_passengers.Reset();


            //begin mod(+): update statistics + fetch maintenance costs
            if (thisLine.Complete)
            {
                ushort stops1 = thisLine.m_stops;
                ushort stop1  = stops1;
                do
                {
                    CachedNodeData.m_cachedNodeData[(int)stop1].StartNewWeek();
                    stop1 = TransportLine.GetNextStop(stop1);
                } while ((int)stops1 != (int)stop1 && (int)stop1 != 0);

                var          itemClass = info.m_class;
                PrefabData[] prefabs   =
                    VehiclePrefabs.instance.GetPrefabs(itemClass.m_service, itemClass.m_subService, itemClass.m_level);
                int amount = 0;
                CountLineActiveVehicles(lineID, out int _, (num3) =>
                {
                    Vehicle vehicle       = VehicleManager.instance.m_vehicles.m_buffer[num3];
                    PrefabData prefabData = Array.Find(prefabs,
                                                       item => item.PrefabDataIndex == vehicle.Info.m_prefabDataIndex);
                    if (prefabData != null)
                    {
                        amount += prefabData.MaintenanceCost;
                        CachedVehicleData.m_cachedVehicleData[num3].StartNewWeek(prefabData.MaintenanceCost);
                    }
                });
                if (amount != 0)
                {
                    Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.Maintenance, amount,
                                                                       info.m_class);
                }
                //end mod
            }
        }
        new protected int HandleCommonConsumption(ushort buildingID, ref Building data, ref Building.Frame frameData, ref int electricityConsumption, ref int heatingConsumption, ref int waterConsumption, ref int sewageAccumulation, ref int garbageAccumulation, DistrictPolicies.Services policies)
        {
            int             num      = 100;
            DistrictManager instance = Singleton <DistrictManager> .instance;

            Notification.Problem problem = Notification.RemoveProblems(data.m_problems, Notification.Problem.Electricity | Notification.Problem.Water | Notification.Problem.Sewage | Notification.Problem.Flood | Notification.Problem.Heating);
            bool flag             = data.m_electricityProblemTimer != 0;
            bool flag2            = false;
            bool flag3            = false;
            int  electricityUsage = 0;
            int  heatingUsage     = 0;
            int  waterUsage       = 0;
            int  sewageUsage      = 0;

            if (electricityConsumption != 0)
            {
                int num2 = Mathf.RoundToInt((20f - Singleton <WeatherManager> .instance.SampleTemperature(data.m_position, false)) * 8f);
                num2 = Mathf.Clamp(num2, 0, 400);
                int num3 = heatingConsumption;
                heatingConsumption = (num3 * num2 + Singleton <SimulationManager> .instance.m_randomizer.Int32(100u)) / 100;
                if ((policies & DistrictPolicies.Services.PowerSaving) != DistrictPolicies.Services.None)
                {
                    electricityConsumption = Mathf.Max(1, electricityConsumption * 90 / 100);
                    Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, 32, this.m_info.m_class);
                }
                bool flag4 = false;
                int  num4  = heatingConsumption * 2 - (int)data.m_heatingBuffer;
                if (num4 > 0 && (policies & DistrictPolicies.Services.OnlyElectricity) == DistrictPolicies.Services.None)
                {
                    int num5 = Singleton <WaterManager> .instance.TryFetchHeating(data.m_position, heatingConsumption, num4, out flag4);

                    data.m_heatingBuffer += (ushort)num5;
                }
                if ((int)data.m_heatingBuffer < heatingConsumption)
                {
                    if ((policies & DistrictPolicies.Services.NoElectricity) != DistrictPolicies.Services.None)
                    {
                        flag3 = true;
                        data.m_heatingProblemTimer = (byte)Mathf.Min(255, (int)(data.m_heatingProblemTimer + 1));
                        if (data.m_heatingProblemTimer >= 65)
                        {
                            num     = 0;
                            problem = Notification.AddProblems(problem, Notification.Problem.Heating | Notification.Problem.MajorProblem);
                        }
                        else if (data.m_heatingProblemTimer >= 3)
                        {
                            num    /= 2;
                            problem = Notification.AddProblems(problem, Notification.Problem.Heating);
                        }
                    }
                    else
                    {
                        num2 = ((num2 + 50) * (heatingConsumption - (int)data.m_heatingBuffer) + heatingConsumption - 1) / heatingConsumption;
                        electricityConsumption += (num3 * num2 + Singleton <SimulationManager> .instance.m_randomizer.Int32(100u)) / 100;
                        if (flag4)
                        {
                            flag3 = true;
                            data.m_heatingProblemTimer = (byte)Mathf.Min(255, (int)(data.m_heatingProblemTimer + 1));
                            if (data.m_heatingProblemTimer >= 3)
                            {
                                problem = Notification.AddProblems(problem, Notification.Problem.Heating);
                            }
                        }
                    }
                    heatingUsage         = (int)data.m_heatingBuffer;
                    data.m_heatingBuffer = 0;
                }
                else
                {
                    heatingUsage          = heatingConsumption;
                    data.m_heatingBuffer -= (ushort)heatingConsumption;
                }
                int num6;
                int a;
                if (this.CanStockpileElectricity(buildingID, ref data, out num6, out a))
                {
                    num4 = num6 + electricityConsumption * 2 - (int)data.m_electricityBuffer;
                    if (num4 > 0)
                    {
                        int num7 = electricityConsumption;
                        if ((int)data.m_electricityBuffer < num6)
                        {
                            num7 += Mathf.Min(a, num6 - (int)data.m_electricityBuffer);
                        }
                        int num8 = Singleton <ElectricityManager> .instance.TryFetchElectricity(data.m_position, num7, num4);

                        data.m_electricityBuffer += (ushort)num8;
                        if (num8 < num4 && num8 < num7)
                        {
                            flag2   = true;
                            problem = Notification.AddProblems(problem, Notification.Problem.Electricity);
                            if (data.m_electricityProblemTimer < 64)
                            {
                                data.m_electricityProblemTimer = 64;
                            }
                        }
                    }
                }
                else
                {
                    num4 = electricityConsumption * 2 - (int)data.m_electricityBuffer;
                    if (num4 > 0)
                    {
                        int num9 = Singleton <ElectricityManager> .instance.TryFetchElectricity(data.m_position, electricityConsumption, num4);

                        data.m_electricityBuffer += (ushort)num9;
                    }
                }
                if ((int)data.m_electricityBuffer < electricityConsumption)
                {
                    flag2 = true;
                    data.m_electricityProblemTimer = (byte)Mathf.Min(255, (int)(data.m_electricityProblemTimer + 1));
                    if (data.m_electricityProblemTimer >= 65)
                    {
                        num     = 0;
                        problem = Notification.AddProblems(problem, Notification.Problem.Electricity | Notification.Problem.MajorProblem);
                    }
                    else if (data.m_electricityProblemTimer >= 3)
                    {
                        num    /= 2;
                        problem = Notification.AddProblems(problem, Notification.Problem.Electricity);
                    }
                    electricityUsage         = (int)data.m_electricityBuffer;
                    data.m_electricityBuffer = 0;
                    if (Singleton <UnlockManager> .instance.Unlocked(ItemClass.Service.Electricity))
                    {
                        GuideController properties = Singleton <GuideManager> .instance.m_properties;
                        if (properties != null)
                        {
                            int publicServiceIndex      = ItemClass.GetPublicServiceIndex(ItemClass.Service.Electricity);
                            int electricityCapacity     = instance.m_districts.m_buffer[0].GetElectricityCapacity();
                            int electricityConsumption2 = instance.m_districts.m_buffer[0].GetElectricityConsumption();
                            if (electricityCapacity >= electricityConsumption2)
                            {
                                Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex].Activate(properties.m_serviceNeeded2, ItemClass.Service.Electricity);
                            }
                            else
                            {
                                Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex].Activate(properties.m_serviceNeeded, ItemClass.Service.Electricity);
                            }
                        }
                    }
                }
                else
                {
                    electricityUsage          = electricityConsumption;
                    data.m_electricityBuffer -= (ushort)electricityConsumption;
                }
            }
            else
            {
                heatingConsumption = 0;
            }
            if (!flag2)
            {
                data.m_electricityProblemTimer = 0;
            }
            if (flag != flag2)
            {
                Singleton <BuildingManager> .instance.UpdateBuildingColors(buildingID);
            }
            if (!flag3)
            {
                data.m_heatingProblemTimer = 0;
            }
            bool flag5 = false;
            int  num10 = sewageAccumulation;

            if (waterConsumption != 0)
            {
                if ((policies & DistrictPolicies.Services.WaterSaving) != DistrictPolicies.Services.None)
                {
                    waterConsumption = Mathf.Max(1, waterConsumption * 85 / 100);
                    if (sewageAccumulation != 0)
                    {
                        sewageAccumulation = Mathf.Max(1, sewageAccumulation * 85 / 100);
                    }
                    Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, 32, this.m_info.m_class);
                }
                int num11;
                int a2;
                if (this.CanStockpileWater(buildingID, ref data, out num11, out a2))
                {
                    int num12 = num11 + waterConsumption * 2 - (int)data.m_waterBuffer;
                    if (num12 > 0)
                    {
                        int num13 = waterConsumption;
                        if ((int)data.m_waterBuffer < num11)
                        {
                            num13 += Mathf.Min(a2, num11 - (int)data.m_waterBuffer);
                        }
                        int num14 = Singleton <WaterManager> .instance.TryFetchWater(data.m_position, num13, num12, ref data.m_waterPollution);

                        data.m_waterBuffer += (ushort)num14;
                        if (num14 < num12 && num14 < num13)
                        {
                            flag5   = true;
                            problem = Notification.AddProblems(problem, Notification.Problem.Water);
                            if (data.m_waterProblemTimer < 64)
                            {
                                data.m_waterProblemTimer = 64;
                            }
                        }
                    }
                }
                else
                {
                    int num15 = waterConsumption * 2 - (int)data.m_waterBuffer;
                    if (num15 > 0)
                    {
                        int num16 = Singleton <WaterManager> .instance.TryFetchWater(data.m_position, waterConsumption, num15, ref data.m_waterPollution);

                        data.m_waterBuffer += (ushort)num16;
                    }
                }
                if ((int)data.m_waterBuffer < waterConsumption)
                {
                    flag5 = true;
                    data.m_waterProblemTimer = (byte)Mathf.Min(255, (int)(data.m_waterProblemTimer + 1));
                    if (data.m_waterProblemTimer >= 65)
                    {
                        num     = 0;
                        problem = Notification.AddProblems(problem, Notification.Problem.Water | Notification.Problem.MajorProblem);
                    }
                    else if (data.m_waterProblemTimer >= 3)
                    {
                        num    /= 2;
                        problem = Notification.AddProblems(problem, Notification.Problem.Water);
                    }
                    num10              = sewageAccumulation * (waterConsumption + (int)data.m_waterBuffer) / (waterConsumption << 1);
                    waterUsage         = (int)data.m_waterBuffer;
                    data.m_waterBuffer = 0;
                    if (Singleton <UnlockManager> .instance.Unlocked(ItemClass.Service.Water))
                    {
                        GuideController properties2 = Singleton <GuideManager> .instance.m_properties;
                        if (properties2 != null)
                        {
                            int publicServiceIndex2 = ItemClass.GetPublicServiceIndex(ItemClass.Service.Water);
                            int waterCapacity       = instance.m_districts.m_buffer[0].GetWaterCapacity();
                            int waterConsumption2   = instance.m_districts.m_buffer[0].GetWaterConsumption();
                            if (waterCapacity >= waterConsumption2)
                            {
                                Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex2].Activate(properties2.m_serviceNeeded2, ItemClass.Service.Water);
                            }
                            else
                            {
                                Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex2].Activate(properties2.m_serviceNeeded, ItemClass.Service.Water);
                            }
                        }
                    }
                }
                else
                {
                    num10               = sewageAccumulation;
                    waterUsage          = waterConsumption;
                    data.m_waterBuffer -= (ushort)waterConsumption;
                }
            }
            int num17;
            int b;

            if (this.CanStockpileWater(buildingID, ref data, out num17, out b))
            {
                int num18 = Mathf.Max(0, num17 + num10 * 2 - (int)data.m_sewageBuffer);
                if (num18 < num10)
                {
                    if (!flag5 && (data.m_problems & Notification.Problem.Water) == Notification.Problem.None)
                    {
                        flag5 = true;
                        data.m_waterProblemTimer = (byte)Mathf.Min(255, (int)(data.m_waterProblemTimer + 1));
                        if (data.m_waterProblemTimer >= 65)
                        {
                            num     = 0;
                            problem = Notification.AddProblems(problem, Notification.Problem.Sewage | Notification.Problem.MajorProblem);
                        }
                        else if (data.m_waterProblemTimer >= 3)
                        {
                            num    /= 2;
                            problem = Notification.AddProblems(problem, Notification.Problem.Sewage);
                        }
                    }
                    sewageUsage         = num18;
                    data.m_sewageBuffer = (ushort)(num17 + num10 * 2);
                }
                else
                {
                    sewageUsage          = num10;
                    data.m_sewageBuffer += (ushort)num10;
                }
                int num19 = num10 + Mathf.Max(num10, b);
                num18 = Mathf.Min(num19, (int)data.m_sewageBuffer);
                if (num18 > 0)
                {
                    int num20 = Singleton <WaterManager> .instance.TryDumpSewage(data.m_position, num19, num18);

                    data.m_sewageBuffer -= (ushort)num20;
                    if (num20 < num19 && num20 < num18 && !flag5 && (data.m_problems & Notification.Problem.Water) == Notification.Problem.None)
                    {
                        flag5   = true;
                        problem = Notification.AddProblems(problem, Notification.Problem.Sewage);
                        if (data.m_waterProblemTimer < 64)
                        {
                            data.m_waterProblemTimer = 64;
                        }
                    }
                }
            }
            else if (num10 != 0)
            {
                int num21 = Mathf.Max(0, num10 * 2 - (int)data.m_sewageBuffer);
                if (num21 < num10)
                {
                    if (!flag5 && (data.m_problems & Notification.Problem.Water) == Notification.Problem.None)
                    {
                        flag5 = true;
                        data.m_waterProblemTimer = (byte)Mathf.Min(255, (int)(data.m_waterProblemTimer + 1));
                        if (data.m_waterProblemTimer >= 65)
                        {
                            num     = 0;
                            problem = Notification.AddProblems(problem, Notification.Problem.Sewage | Notification.Problem.MajorProblem);
                        }
                        else if (data.m_waterProblemTimer >= 3)
                        {
                            num    /= 2;
                            problem = Notification.AddProblems(problem, Notification.Problem.Sewage);
                        }
                    }
                    sewageUsage         = num21;
                    data.m_sewageBuffer = (ushort)(num10 * 2);
                }
                else
                {
                    sewageUsage          = num10;
                    data.m_sewageBuffer += (ushort)num10;
                }
                num21 = Mathf.Min(num10 * 2, (int)data.m_sewageBuffer);
                if (num21 > 0)
                {
                    int num22 = Singleton <WaterManager> .instance.TryDumpSewage(data.m_position, num10 * 2, num21);

                    data.m_sewageBuffer -= (ushort)num22;
                }
            }
            if (!flag5)
            {
                data.m_waterProblemTimer = 0;
            }
            if (garbageAccumulation != 0)
            {
                int num23 = (int)(65535 - data.m_garbageBuffer);
                if (num23 < garbageAccumulation)
                {
                    num = 0;
                    data.m_garbageBuffer = (ushort)num23;
                }
                else
                {
                    //start edit
                    StormDrainAI stormDrainAI = data.Info.m_buildingAI as StormDrainAI;
                    if (stormDrainAI == null)
                    {
                        data.m_garbageBuffer += (ushort)garbageAccumulation;
                    }
                    else if (stormDrainAI.m_filter == false)
                    {
                        data.m_garbageBuffer += (ushort)garbageAccumulation;
                    }
                    else
                    {
                        int pollutantAccumulation = Hydraulics.removePollutants(buildingID, Hydraulics.getPollutants(buildingID));
                        data.m_garbageBuffer += (ushort)pollutantAccumulation;
                        //Debug.Log("[RF]CommonBuildingAI.handleCommonConsumption garbagebuffer = " + data.m_garbageBuffer.ToString());
                    }
                    //end edit
                }
            }
            if (garbageAccumulation != 0)
            {
                int num24 = (int)data.m_garbageBuffer;
                if (num24 >= 200 && Singleton <SimulationManager> .instance.m_randomizer.Int32(5u) == 0 && Singleton <UnlockManager> .instance.Unlocked(ItemClass.Service.Garbage))
                {
                    int num25 = 0;
                    int num26 = 0;
                    int num27 = 0;
                    int num28 = 0;
                    this.CalculateGuestVehicles(buildingID, ref data, TransferManager.TransferReason.Garbage, ref num25, ref num26, ref num27, ref num28);
                    num24 -= num27 - num26;
                    if (num24 >= 200)
                    {
                        TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                        offer.Priority = num24 / 1000;
                        offer.Building = buildingID;
                        offer.Position = data.m_position;
                        offer.Amount   = 1;
                        Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.Garbage, offer);
                    }
                }
            }
            bool flag6;

            if (this.CanSufferFromFlood(out flag6))
            {
                float num29 = Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(data.m_position));

                if (num29 > data.m_position.y)
                {
                    bool flag7 = num29 > data.m_position.y + Mathf.Max(4f, this.m_info.m_collisionHeight);
                    if ((!flag6 || flag7) && (data.m_flags & Building.Flags.Flooded) == Building.Flags.None && data.m_fireIntensity == 0)
                    {
                        DisasterManager instance2 = Singleton <DisasterManager> .instance;
                        ushort          num30     = instance2.FindDisaster <FloodBaseAI>(data.m_position);
                        if (num30 == 0)
                        {
                            DisasterInfo disasterInfo = DisasterManager.FindDisasterInfo <GenericFloodAI>();
                            if (disasterInfo != null && instance2.CreateDisaster(out num30, disasterInfo))
                            {
                                instance2.m_disasters.m_buffer[(int)num30].m_intensity      = 10;
                                instance2.m_disasters.m_buffer[(int)num30].m_targetPosition = data.m_position;
                                disasterInfo.m_disasterAI.StartNow(num30, ref instance2.m_disasters.m_buffer[(int)num30]);
                            }
                        }
                        if (num30 != 0)
                        {
                            InstanceID srcID = default(InstanceID);
                            InstanceID dstID = default(InstanceID);
                            srcID.Disaster = num30;
                            dstID.Building = buildingID;
                            Singleton <InstanceManager> .instance.CopyGroup(srcID, dstID);

                            DisasterInfo info = instance2.m_disasters.m_buffer[(int)num30].Info;
                            info.m_disasterAI.ActivateNow(num30, ref instance2.m_disasters.m_buffer[(int)num30]);
                            if ((instance2.m_disasters.m_buffer[(int)num30].m_flags & DisasterData.Flags.Significant) != DisasterData.Flags.None)
                            {
                                instance2.DetectDisaster(num30, false);
                                instance2.FollowDisaster(num30);
                            }
                        }
                        data.m_flags |= Building.Flags.Flooded;
                    }
                    if (flag7)
                    {
                        frameData.m_constructState = (byte)Mathf.Max(0, (int)frameData.m_constructState - 1088 / this.GetCollapseTime());
                        data.SetFrameData(Singleton <SimulationManager> .instance.m_currentFrameIndex, frameData);
                        InstanceID id = default(InstanceID);
                        id.Building = buildingID;
                        InstanceManager.Group group = Singleton <InstanceManager> .instance.GetGroup(id);

                        if (group != null)
                        {
                            ushort disaster = group.m_ownerInstance.Disaster;
                            if (disaster != 0)
                            {
                                DisasterData[] expr_D18_cp_0 = Singleton <DisasterManager> .instance.m_disasters.m_buffer;
                                ushort         expr_D18_cp_1 = disaster;
                                expr_D18_cp_0[(int)expr_D18_cp_1].m_collapsedCount = (ushort)(expr_D18_cp_0[(int)expr_D18_cp_1].m_collapsedCount + 1);
                            }
                        }
                        if (frameData.m_constructState == 0)
                        {
                            Singleton <InstanceManager> .instance.SetGroup(id, null);
                        }
                        data.m_levelUpProgress = 0;
                        data.m_fireIntensity   = 0;
                        data.m_garbageBuffer   = 0;
                        data.m_flags          |= Building.Flags.Collapsed;
                        num = 0;
                        this.RemovePeople(buildingID, ref data, 90);
                        this.BuildingDeactivated(buildingID, ref data);
                        if (this.m_info.m_hasParkingSpaces != VehicleInfo.VehicleType.None)
                        {
                            Singleton <BuildingManager> .instance.UpdateParkingSpaces(buildingID, ref data);
                        }
                        Singleton <BuildingManager> .instance.UpdateBuildingRenderer(buildingID, true);

                        Singleton <BuildingManager> .instance.UpdateBuildingColors(buildingID);

                        GuideController properties3 = Singleton <GuideManager> .instance.m_properties;
                        if (properties3 != null)
                        {
                            Singleton <BuildingManager> .instance.m_buildingFlooded.Deactivate(buildingID, false);

                            Singleton <BuildingManager> .instance.m_buildingFlooded2.Deactivate(buildingID, false);
                        }
                    }
                    else if (!flag6)
                    {
                        if ((data.m_flags & Building.Flags.RoadAccessFailed) == Building.Flags.None)
                        {
                            int num31 = 0;
                            int num32 = 0;
                            int num33 = 0;
                            int num34 = 0;
                            this.CalculateGuestVehicles(buildingID, ref data, TransferManager.TransferReason.FloodWater, ref num31, ref num32, ref num33, ref num34);
                            if (num31 == 0)
                            {
                                TransferManager.TransferOffer offer2 = default(TransferManager.TransferOffer);
                                offer2.Priority = 5;
                                offer2.Building = buildingID;
                                offer2.Position = data.m_position;
                                offer2.Amount   = 1;
                                Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.FloodWater, offer2);
                            }
                        }
                        if (num29 > data.m_position.y + (float)ModSettings.BuildingFloodedTolerance / 100f)
                        {
                            num     = 0;
                            problem = Notification.AddProblems(problem, Notification.Problem.Flood | Notification.Problem.MajorProblem);
                        }
                        else if (num29 > data.m_position.y + (float)ModSettings.BuildingFloodingTolerance / 100f)
                        {
                            num    /= 2;
                            problem = Notification.AddProblems(problem, Notification.Problem.Flood);
                        }
                        GuideController properties4 = Singleton <GuideManager> .instance.m_properties;
                        if (properties4 != null)
                        {
                            if (Singleton <LoadingManager> .instance.SupportsExpansion(Expansion.NaturalDisasters) && Singleton <UnlockManager> .instance.Unlocked(UnlockManager.Feature.WaterPumping))
                            {
                                Singleton <BuildingManager> .instance.m_buildingFlooded2.Activate(properties4.m_buildingFlooded2, buildingID);
                            }
                            else
                            {
                                Singleton <BuildingManager> .instance.m_buildingFlooded.Activate(properties4.m_buildingFlooded, buildingID);
                            }
                        }
                    }
                }
                else if ((data.m_flags & Building.Flags.Flooded) != Building.Flags.None)
                {
                    InstanceID id2 = default(InstanceID);
                    id2.Building = buildingID;
                    Singleton <InstanceManager> .instance.SetGroup(id2, null);

                    data.m_flags &= ~Building.Flags.Flooded;
                }
            }
            byte district = instance.GetDistrict(data.m_position);

            instance.m_districts.m_buffer[(int)district].AddUsageData(electricityUsage, heatingUsage, waterUsage, sewageUsage);
            data.m_problems = problem;
            return(num);
        }
Beispiel #14
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)
        {
            var GetOutgoingTransferReason = typeof(MarketAI).GetMethod("GetOutgoingTransferReason", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(ushort) }, null);

            base.ProduceGoods(buildingID, ref buildingData, ref frameData, productionRate, finalProductionRate, ref behaviour, aliveWorkerCount, totalWorkerCount, workPlaceCount, aliveVisitorCount, totalVisitorCount, visitPlaceCount);
            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 (!MarketBuffers.ContainsKey(buildingID))
            {
                AddMarketBufferToBuildingData(buildingID);
            }
            var marketBuffer = MarketBuffers[buildingID];

            if (m_info.m_subBuildings != null)
            {
                for (int i = 0; i < m_info.m_subBuildings.Length; i++)
                {
                    if (m_info.m_subBuildings[i].m_buildingInfo != null)
                    {
                        float num5 = (float)m_info.m_subBuildings[i].m_buildingInfo.m_cellWidth;
                        float num6 = (float)m_info.m_subBuildings[i].m_buildingInfo.m_cellLength;
                        float x    = m_info.m_subBuildings[i].m_position.x;
                        float num7 = -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   num8         = num4 - num3;
            float   angle        = buildingData.m_angle;
            float   num9         = -(num + num2) * 0.5f;
            float   num10        = -(num3 + num4) * 0.5f;
            float   num11        = num8 * 0.25f - (num3 + num4) * 0.5f;
            float   num12        = Mathf.Sin(angle);
            float   num13        = Mathf.Cos(angle);
            Vector3 position     = buildingData.m_position - new Vector3(num13 * num9 + num12 * num10, 0f, num12 * num9 - num13 * num10);
            Vector3 position2    = buildingData.m_position - new Vector3(num13 * num9 + num12 * num11, 0f, num12 * num9 - num13 * num11);
            float   currentRange = GetCurrentRange(buildingID, ref buildingData);

            Notification.Problem problem = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoCustomers | Notification.Problem.NoGoods | Notification.Problem.NoFishingGoods);
            int num14 = productionRate * m_healthCareAccumulation / 100;

            if (num14 != 0)
            {
                Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.HealthCare, num14, buildingData.m_position, m_healthCareRadius);
            }
            if (finalProductionRate != 0)
            {
                if (m_entertainmentAccumulation != 0)
                {
                    int rate = productionRate * GetEntertainmentAccumulation(buildingID, ref buildingData) / 100;
                    Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Entertainment, rate, position, currentRange);
                }
                if (m_attractivenessAccumulation != 0)
                {
                    int num15 = GetAttractivenessAccumulation(buildingID, ref buildingData);
                    Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Attractiveness, num15);

                    num15 = productionRate * num15 * 15 / 100;
                    Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Attractiveness, num15, position2, num8);
                }
                if (m_noiseAccumulation != 0)
                {
                    Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, m_noiseAccumulation, buildingData.m_position, m_noiseRadius);
                }
                base.HandleDead(buildingID, ref buildingData, ref behaviour, totalWorkerCount + totalVisitorCount);
                int goodsCapacity = m_goodsCapacity;
                TransferManager.TransferReason outgoingTransferReason = (TransferManager.TransferReason)GetOutgoingTransferReason.Invoke(this, new object[] { buildingID });
                int[] productionRateArr = new int[m_incomingResources.Length];
                if (productionRate != 0)
                {
                    for (int i = 0; i < m_incomingResources.Length; i++)
                    {
                        productionRateArr[i] = productionRate;
                        int num16 = goodsCapacity;
                        if (m_incomingResources[i] != TransferManager.TransferReason.None)
                        {
                            num16 = Mathf.Min(num16, (int)marketBuffer.inputAmountBuffer[i]);
                        }
                        if (outgoingTransferReason != TransferManager.TransferReason.None)
                        {
                            num16 = Mathf.Min(num16, goodsCapacity - (int)marketBuffer.outputAmountBuffer[i]);
                        }
                        productionRateArr[i] = Mathf.Max(0, Mathf.Min(productionRateArr[i], (num16 * 200 + goodsCapacity - 1) / goodsCapacity));
                        int num17 = (visitPlaceCount * productionRateArr[i] + 9) / 10;
                        if (Singleton <SimulationManager> .instance.m_isNightTime)
                        {
                            num17 = num17 + 1 >> 1;
                        }
                        num17 = Mathf.Max(0, Mathf.Min(num17, num16));
                        if (m_incomingResources[i] != TransferManager.TransferReason.None)
                        {
                            marketBuffer.inputAmountBuffer[i] -= (ushort)num17;
                        }
                        if (outgoingTransferReason != TransferManager.TransferReason.None)
                        {
                            marketBuffer.outputAmountBuffer[i] += (ushort)num17;
                        }
                        productionRateArr[i] += (num17 + 9) / 10;
                    }
                }
                int num18 = 0;
                int num19 = 0;
                int num20 = 0;
                int value = 0;
                for (int i = 0; i < m_incomingResources.Length; i++)
                {
                    if (marketBuffer.inputAmountBuffer[i] > 0)
                    {
                        isAmount = true;
                        break;
                    }
                    if (i == m_incomingResources.Length - 1 && isAmount)
                    {
                        isAmount = false;
                    }
                }
                for (int i = 0; i < m_incomingResources.Length; i++)
                {
                    if (m_incomingResources[i] != TransferManager.TransferReason.None)
                    {
                        base.CalculateGuestVehicles(buildingID, ref buildingData, m_incomingResources[i], ref num18, ref num19, ref num20, ref value);
                        buildingData.m_tempImport = (byte)Mathf.Clamp(value, (int)buildingData.m_tempImport, 255);
                    }
                }
                buildingData.m_tempExport = (byte)Mathf.Clamp(behaviour.m_touristCount, (int)buildingData.m_tempExport, 255);
                buildingData.m_adults     = (byte)productionRateArr[0];
                int num21 = visitPlaceCount * 500;
                for (int k = 0; k < m_incomingResources.Length; k++)
                {
                    if ((int)marketBuffer.outputAmountBuffer[k] > goodsCapacity - (num21 >> 1) && aliveVisitorCount <= visitPlaceCount >> 1)
                    {
                        buildingData.m_outgoingProblemTimer = (byte)Mathf.Min(255, (int)(buildingData.m_outgoingProblemTimer + 1));
                        if (buildingData.m_outgoingProblemTimer >= 192)
                        {
                            problem = Notification.AddProblems(problem, Notification.Problem.NoCustomers | Notification.Problem.MajorProblem);
                        }
                        else if (buildingData.m_outgoingProblemTimer >= 128)
                        {
                            problem = Notification.AddProblems(problem, Notification.Problem.NoCustomers);
                        }
                    }
                    else
                    {
                        buildingData.m_outgoingProblemTimer = 0;
                    }
                }
                for (int i = 0; i < m_incomingResources.Length; i++)
                {
                    if (marketBuffer.inputAmountBuffer[i] == 0 && !isAmount && m_incomingResources[i] != TransferManager.TransferReason.None)
                    {
                        buildingData.m_incomingProblemTimer = (byte)Mathf.Min(255, (int)(buildingData.m_incomingProblemTimer + 1));
                        Notification.Problem problem2 = (m_incomingResources[i] != TransferManager.TransferReason.Fish) ? Notification.Problem.NoGoods : Notification.Problem.NoFishingGoods;
                        if (buildingData.m_incomingProblemTimer < 64)
                        {
                            problem = Notification.AddProblems(problem, problem2);
                        }
                        else
                        {
                            problem = Notification.AddProblems(problem, Notification.Problem.MajorProblem | problem2);
                        }
                    }
                    else
                    {
                        buildingData.m_incomingProblemTimer = 0;
                    }
                }
                for (int i = 0; i < m_incomingResources.Length; i++)
                {
                    if (buildingData.m_fireIntensity == 0 && m_incomingResources[i] != TransferManager.TransferReason.None)
                    {
                        int num22 = goodsCapacity - (int)marketBuffer.inputAmountBuffer[i] - num20;
                        int num23 = m_goodsCapacity / 4;
                        num22 -= num23 >> 1;
                        if (num22 >= 0)
                        {
                            TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                            offer.Priority = num22 * 8 / num23;
                            offer.Building = buildingID;
                            offer.Position = buildingData.m_position;
                            offer.Amount   = 1;
                            offer.Active   = false;
                            Singleton <TransferManager> .instance.AddIncomingOffer(m_incomingResources[i], offer);
                        }
                    }
                }

                if (buildingData.m_fireIntensity == 0 && outgoingTransferReason != TransferManager.TransferReason.None)
                {
                    for (int k = 0; k < m_incomingResources.Length; k++)
                    {
                        int num24 = (int)marketBuffer.outputAmountBuffer[k] - aliveVisitorCount * 100;
                        int num25 = Mathf.Max(0, visitPlaceCount - totalVisitorCount);
                        if (num24 >= 100 && num25 > 0)
                        {
                            TransferManager.TransferOffer offer2 = default(TransferManager.TransferOffer);
                            offer2.Priority = Mathf.Max(1, num24 * 8 / goodsCapacity);
                            offer2.Building = buildingID;
                            offer2.Position = buildingData.m_position;
                            offer2.Amount   = Mathf.Min(num24 / 100, num25);
                            offer2.Active   = false;
                            Singleton <TransferManager> .instance.AddOutgoingOffer(outgoingTransferReason, offer2);
                        }
                    }
                }
                MarketBuffers[buildingID] = marketBuffer;
            }
            buildingData.m_problems = problem;
        }
Beispiel #15
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);

            DistrictPolicies.Services servicePolicies = instance.m_districts.m_buffer[(int)district].m_servicePolicies;
            Notification.Problem      problem         = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.WaterNotConnected | Notification.Problem.NoResources | Notification.Problem.NoNaturalResources | Notification.Problem.FishFarmWaterDirty | Notification.Problem.NoPlaceForFishingGoods);
            int num  = 0;
            int num2 = 0;
            int num3 = 0;

            if (this.m_extractionPositions != null && this.m_extractionPositions.Length > 0)
            {
                for (int i = 0; i < this.m_extractionPositions.Length; i++)
                {
                    Vector3 position = buildingData.CalculatePosition(this.m_extractionPositions[i]);
                    int     b;
                    int     num4;
                    int     value;
                    Singleton <TerrainManager> .instance.CountWaterCoverage(position, 20f, out b, out num4, out value);

                    num += Mathf.Clamp(value, 0, 128);
                    num3 = Mathf.Max(num3, b);
                }
                if (this.m_info.name == "Algae Tank")
                {
                    this.m_info.m_placementMode = BuildingInfo.PlacementMode.Roadside;
                    num2 = 0;
                    num3 = 1;
                }
                else
                {
                    num2 = num / this.m_extractionPositions.Length;
                }
            }
            else
            {
                finalProductionRate = 0;
            }
            if (num2 > 32)
            {
                GuideController properties = Singleton <GuideManager> .instance.m_properties;
                if (properties != null)
                {
                    Singleton <BuildingManager> .instance.m_fishingPollutionDetected.Activate(properties.m_fishingPollutionDetected, buildingID);
                }
            }
            if (num3 == 0)
            {
                finalProductionRate = 0;
            }
            if (finalProductionRate != 0)
            {
                int num5 = finalProductionRate;
                if (num2 > 96)
                {
                    problem = (Notification.Problem.FishFarmWaterDirty | Notification.Problem.FatalProblem);
                }
                else if (num2 > 64)
                {
                    problem = Notification.AddProblems(problem, Notification.Problem.FishFarmWaterDirty | Notification.Problem.MajorProblem);
                }
                else if (num2 > 32)
                {
                    problem = Notification.AddProblems(problem, Notification.Problem.FishFarmWaterDirty);
                }
                finalProductionRate = finalProductionRate * Mathf.Clamp(255 - num2 * 2, 0, 255) / 255;
                int num6 = finalProductionRate * this.m_noiseAccumulation / 100;
                if (num6 != 0)
                {
                    Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, num6, buildingData.m_position, this.m_noiseRadius);
                }
                base.HandleDead(buildingID, ref buildingData, ref behaviour, totalWorkerCount);
                int num7 = 0;
                int num8 = 0;
                if (this.m_outputResource != TransferManager.TransferReason.None)
                {
                    int num9 = (this.m_productionRate * finalProductionRate + 99) / 100;
                    if (this.m_info.m_class.m_level == ItemClass.Level.Level3 && (servicePolicies & DistrictPolicies.Services.AlgaeBasedWaterFiltering) != DistrictPolicies.Services.None)
                    {
                        District[] buffer = instance.m_districts.m_buffer;
                        byte       b2     = district;
                        buffer[(int)b2].m_servicePoliciesEffect = (buffer[(int)b2].m_servicePoliciesEffect | DistrictPolicies.Services.AlgaeBasedWaterFiltering);
                        num9 = (num9 * 50 + 49) / 100;
                    }
                    int cycleBufferSize = this.GetCycleBufferSize(buildingID, ref buildingData);
                    int num10           = (int)buildingData.m_customBuffer1;
                    num7 = this.GetStorageBufferSize(buildingID, ref buildingData);
                    num8 = (int)(buildingData.m_customBuffer2 * 100);
                    if (num9 >= cycleBufferSize - num10)
                    {
                        if (cycleBufferSize > num7 - num8)
                        {
                            num9    = cycleBufferSize - num10;
                            num10   = cycleBufferSize;
                            problem = Notification.AddProblems(problem, Notification.Problem.NoPlaceForFishingGoods);
                        }
                        else
                        {
                            num10 = num10 + num9 - cycleBufferSize;
                            num8 += cycleBufferSize;
                        }
                    }
                    else
                    {
                        num10 += num9;
                    }
                    Singleton <StatisticsManager> .instance.Acquire <StatisticInt64>(StatisticType.FishFarmed).Add(num9);

                    buildingData.m_customBuffer1 = (ushort)num10;
                    buildingData.m_customBuffer2 = (ushort)(num8 / 100);
                }
                if (this.m_outputResource != TransferManager.TransferReason.None)
                {
                    int num11  = (num5 * this.m_outputVehicleCount + 99) / 100;
                    int num12  = 0;
                    int num13  = 0;
                    int num14  = 0;
                    int value2 = 0;
                    base.CalculateOwnVehicles(buildingID, ref buildingData, this.m_outputResource, ref num12, ref num13, ref num14, ref value2);
                    buildingData.m_tempExport = (byte)Mathf.Clamp(value2, (int)buildingData.m_tempExport, 255);
                    if (buildingData.m_finalExport != 0)
                    {
                        District[] buffer2 = instance.m_districts.m_buffer;
                        byte       b3      = district;
                        buffer2[(int)b3].m_playerConsumption.m_finalExportAmount = buffer2[(int)b3].m_playerConsumption.m_finalExportAmount + (uint)buildingData.m_finalExport;
                    }
                    int num15 = num8;
                    if (num15 >= 8000 && num12 < num11)
                    {
                        TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                        offer.Priority = Mathf.Max(1, num15 * 8 / num7);
                        offer.Building = buildingID;
                        offer.Position = buildingData.m_position;
                        offer.Amount   = 1;
                        offer.Active   = true;
                        Singleton <TransferManager> .instance.AddOutgoingOffer(this.m_outputResource, offer);
                    }
                }
            }
            buildingData.m_problems   = problem;
            buildingData.m_education3 = (byte)Mathf.Clamp(finalProductionRate * this.m_productionRate / Mathf.Max(1, this.m_productionRate), 0, 255);
            base.ProduceGoods(buildingID, ref buildingData, ref frameData, productionRate, finalProductionRate, ref behaviour, aliveWorkerCount, totalWorkerCount, workPlaceCount, aliveVisitorCount, totalVisitorCount, visitPlaceCount);
        }
        new int HandleCommonConsumption(ushort buildingID, ref Building data, ref int electricityConsumption, ref int heatingConsumption, ref int waterConsumption, ref int sewageAccumulation, ref int garbageAccumulation, DistrictPolicies.Services policies)
        {
            int             num      = 100;
            DistrictManager instance = Singleton <DistrictManager> .instance;

            Notification.Problem problem = Notification.RemoveProblems(data.m_problems, Notification.Problem.Electricity | Notification.Problem.Water | Notification.Problem.Sewage | Notification.Problem.Flood | Notification.Problem.Heating);
            bool flag             = data.m_electricityProblemTimer != 0;
            bool flag2            = false;
            bool flag3            = false;
            int  electricityUsage = 0;
            int  heatingUsage     = 0;
            int  waterUsage       = 0;
            int  sewageUsage      = 0;

            if (electricityConsumption != 0)
            {
                int num2 = Mathf.RoundToInt((20f - Singleton <WeatherManager> .instance.SampleTemperature(data.m_position, false)) * 8f);
                num2 = Mathf.Clamp(num2, 0, 400);
                int num3 = heatingConsumption;
                heatingConsumption = (num3 * num2 + Singleton <SimulationManager> .instance.m_randomizer.Int32(100u)) / 100;
                if ((policies & DistrictPolicies.Services.PowerSaving) != DistrictPolicies.Services.None)
                {
                    electricityConsumption = Mathf.Max(1, electricityConsumption * 90 / 100);
                    Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, 32, this.m_info.m_class);
                }
                bool flag4 = false;
                int  num4  = heatingConsumption * 2 - (int)data.m_heatingBuffer;
                if (num4 > 0 && (policies & DistrictPolicies.Services.OnlyElectricity) == DistrictPolicies.Services.None)
                {
                    int num5 = Singleton <WaterManager> .instance.TryFetchHeating(data.m_position, heatingConsumption, num4, out flag4);

                    data.m_heatingBuffer += (ushort)num5;
                }
                if ((int)data.m_heatingBuffer < heatingConsumption)
                {
                    if ((policies & DistrictPolicies.Services.NoElectricity) != DistrictPolicies.Services.None)
                    {
                        flag3 = true;
                        data.m_heatingProblemTimer = (byte)Mathf.Min(255, (int)(data.m_heatingProblemTimer + 1));
                        if (data.m_heatingProblemTimer >= 65)
                        {
                            num     = 0;
                            problem = Notification.AddProblems(problem, Notification.Problem.Heating | Notification.Problem.MajorProblem);
                        }
                        else if (data.m_heatingProblemTimer >= 3)
                        {
                            num    /= 2;
                            problem = Notification.AddProblems(problem, Notification.Problem.Heating);
                        }
                    }
                    else
                    {
                        num2 = ((num2 + 50) * (heatingConsumption - (int)data.m_heatingBuffer) + heatingConsumption - 1) / heatingConsumption;
                        electricityConsumption += (num3 * num2 + Singleton <SimulationManager> .instance.m_randomizer.Int32(100u)) / 100;
                        if (flag4)
                        {
                            flag3 = true;
                            data.m_heatingProblemTimer = (byte)Mathf.Min(255, (int)(data.m_heatingProblemTimer + 1));
                            if (data.m_heatingProblemTimer >= 3)
                            {
                                problem = Notification.AddProblems(problem, Notification.Problem.Heating);
                            }
                        }
                    }
                    heatingUsage         = (int)data.m_heatingBuffer;
                    data.m_heatingBuffer = 0;
                }
                else
                {
                    heatingUsage          = heatingConsumption;
                    data.m_heatingBuffer -= (ushort)heatingConsumption;
                }
                num4 = electricityConsumption * 2 - (int)data.m_electricityBuffer;
                if (num4 > 0)
                {
                    int num6 = Singleton <ElectricityManager> .instance.TryFetchElectricity(data.m_position, electricityConsumption, num4);

                    data.m_electricityBuffer += (ushort)num6;
                }
                if ((int)data.m_electricityBuffer < electricityConsumption)
                {
                    flag2 = true;
                    data.m_electricityProblemTimer = (byte)Mathf.Min(255, (int)(data.m_electricityProblemTimer + 1));
                    if (data.m_electricityProblemTimer >= 65)
                    {
                        num     = 0;
                        problem = Notification.AddProblems(problem, Notification.Problem.Electricity | Notification.Problem.MajorProblem);
                    }
                    else if (data.m_electricityProblemTimer >= 3)
                    {
                        num    /= 2;
                        problem = Notification.AddProblems(problem, Notification.Problem.Electricity);
                    }
                    electricityUsage         = (int)data.m_electricityBuffer;
                    data.m_electricityBuffer = 0;
                    if (Singleton <UnlockManager> .instance.Unlocked(ItemClass.Service.Electricity))
                    {
                        GuideController properties = Singleton <GuideManager> .instance.m_properties;
                        if (properties != null)
                        {
                            int publicServiceIndex      = ItemClass.GetPublicServiceIndex(ItemClass.Service.Electricity);
                            int electricityCapacity     = instance.m_districts.m_buffer[0].GetElectricityCapacity();
                            int electricityConsumption2 = instance.m_districts.m_buffer[0].GetElectricityConsumption();
                            if (electricityCapacity >= electricityConsumption2)
                            {
                                Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex].Activate(properties.m_serviceNeeded2, ItemClass.Service.Electricity);
                            }
                            else
                            {
                                Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex].Activate(properties.m_serviceNeeded, ItemClass.Service.Electricity);
                            }
                        }
                    }
                }
                else
                {
                    electricityUsage          = electricityConsumption;
                    data.m_electricityBuffer -= (ushort)electricityConsumption;
                }
            }
            else
            {
                heatingConsumption = 0;
            }
            if (!flag2)
            {
                data.m_electricityProblemTimer = 0;
            }
            if (flag != flag2)
            {
                Singleton <BuildingManager> .instance.UpdateBuildingColors(buildingID);
            }
            if (!flag3)
            {
                data.m_heatingProblemTimer = 0;
            }
            bool flag5 = false;
            int  num7  = sewageAccumulation;

            if (waterConsumption != 0)
            {
                if ((policies & DistrictPolicies.Services.WaterSaving) != DistrictPolicies.Services.None)
                {
                    waterConsumption = Mathf.Max(1, waterConsumption * 85 / 100);
                    if (sewageAccumulation != 0)
                    {
                        sewageAccumulation = Mathf.Max(1, sewageAccumulation * 85 / 100);
                    }
                    Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, 32, this.m_info.m_class);
                }
                int num8 = waterConsumption * 2 - (int)data.m_waterBuffer;
                if (num8 > 0)
                {
                    int num9 = Singleton <WaterManager> .instance.TryFetchWater(data.m_position, waterConsumption, num8, ref data.m_waterPollution);

                    data.m_waterBuffer += (ushort)num9;
                }
                if ((int)data.m_waterBuffer < waterConsumption)
                {
                    flag5 = true;
                    data.m_waterProblemTimer = (byte)Mathf.Min(255, (int)(data.m_waterProblemTimer + 1));
                    if (data.m_waterProblemTimer >= 65)
                    {
                        num     = 0;
                        problem = Notification.AddProblems(problem, Notification.Problem.Water | Notification.Problem.MajorProblem);
                    }
                    else if (data.m_waterProblemTimer >= 3)
                    {
                        num    /= 2;
                        problem = Notification.AddProblems(problem, Notification.Problem.Water);
                    }
                    num7               = sewageAccumulation * (waterConsumption + (int)data.m_waterBuffer) / (waterConsumption << 1);
                    waterUsage         = (int)data.m_waterBuffer;
                    data.m_waterBuffer = 0;
                    if (Singleton <UnlockManager> .instance.Unlocked(ItemClass.Service.Water))
                    {
                        GuideController properties2 = Singleton <GuideManager> .instance.m_properties;
                        if (properties2 != null)
                        {
                            int publicServiceIndex2 = ItemClass.GetPublicServiceIndex(ItemClass.Service.Water);
                            int waterCapacity       = instance.m_districts.m_buffer[0].GetWaterCapacity();
                            int waterConsumption2   = instance.m_districts.m_buffer[0].GetWaterConsumption();
                            if (waterCapacity >= waterConsumption2)
                            {
                                Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex2].Activate(properties2.m_serviceNeeded2, ItemClass.Service.Water);
                            }
                            else
                            {
                                Singleton <GuideManager> .instance.m_serviceNeeded[publicServiceIndex2].Activate(properties2.m_serviceNeeded, ItemClass.Service.Water);
                            }
                        }
                    }
                }
                else
                {
                    num7                = sewageAccumulation;
                    waterUsage          = waterConsumption;
                    data.m_waterBuffer -= (ushort)waterConsumption;
                }
            }
            if (num7 != 0)
            {
                int num10 = num7 * 2 - (int)data.m_sewageBuffer;
                if (num10 < num7)
                {
                    if (!flag5 && (data.m_problems & Notification.Problem.Water) == Notification.Problem.None)
                    {
                        flag5 = true;
                        data.m_waterProblemTimer = (byte)Mathf.Min(255, (int)(data.m_waterProblemTimer + 1));
                        if (data.m_waterProblemTimer >= 65)
                        {
                            num     = 0;
                            problem = Notification.AddProblems(problem, Notification.Problem.Sewage | Notification.Problem.MajorProblem);
                        }
                        else if (data.m_waterProblemTimer >= 3)
                        {
                            num    /= 2;
                            problem = Notification.AddProblems(problem, Notification.Problem.Sewage);
                        }
                    }
                    sewageUsage         = num10;
                    data.m_sewageBuffer = (ushort)(num7 * 2);
                }
                else
                {
                    sewageUsage          = num7;
                    data.m_sewageBuffer += (ushort)num7;
                }
            }
            if (!flag5)
            {
                data.m_waterProblemTimer = 0;
            }
            if (garbageAccumulation != 0)
            {
                int num11 = (int)(65535 - data.m_garbageBuffer);
                if (num11 < garbageAccumulation)
                {
                    num = 0;
                    data.m_garbageBuffer = (ushort)num11;
                }
                else
                {
                    //start edit
                    StormDrainAI stormDrainAI = data.Info.m_buildingAI as StormDrainAI;
                    if (stormDrainAI == null)
                    {
                        data.m_garbageBuffer += (ushort)garbageAccumulation;
                    }
                    else if (stormDrainAI.m_filter == false)
                    {
                        data.m_garbageBuffer += (ushort)garbageAccumulation;
                    }
                    else
                    {
                        int pollutantAccumulation = Hydraulics.removePollutants(buildingID, Hydraulics.getPollutants(buildingID));
                        data.m_garbageBuffer += (ushort)pollutantAccumulation;
                        //Debug.Log("[RF]CommonBuildingAI.handleCommonConsumption garbagebuffer = " + data.m_garbageBuffer.ToString());
                    }
                    //end edit
                }
            }
            if (num7 != 0)
            {
                int num12 = Mathf.Min(num7 * 2, (int)data.m_sewageBuffer);
                if (num12 > 0)
                {
                    int num13 = Singleton <WaterManager> .instance.TryDumpSewage(data.m_position, num7 * 2, num12);

                    data.m_sewageBuffer -= (ushort)num13;
                }
            }
            if (garbageAccumulation != 0)
            {
                int num14 = (int)data.m_garbageBuffer;
                if (num14 >= 200 && Singleton <SimulationManager> .instance.m_randomizer.Int32(5u) == 0 && Singleton <UnlockManager> .instance.Unlocked(ItemClass.Service.Garbage))
                {
                    int num15 = 0;
                    int num16 = 0;
                    int num17 = 0;
                    int num18 = 0;
                    this.CalculateGuestVehicles(buildingID, ref data, TransferManager.TransferReason.Garbage, ref num15, ref num16, ref num17, ref num18);
                    num14 -= num17 - num16;
                    if (num14 >= 200)
                    {
                        TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                        offer.Priority = num14 / 1000;
                        offer.Building = buildingID;
                        offer.Position = data.m_position;
                        offer.Amount   = 1;
                        Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.Garbage, offer);
                    }
                }
            }
            if (this.CanSufferFromFlood())
            {
                float num19 = Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(data.m_position));

                if (num19 > data.m_position.y)
                {
                    if (num19 > data.m_position.y + (float)ModSettings.BuildingFloodedTolerance / 100f)
                    {
                        //Debug.Log("[RF].CBAId Detoured Flooded Notification");
                        num     = 0;
                        problem = Notification.AddProblems(problem, Notification.Problem.Flood | Notification.Problem.MajorProblem);
                    }
                    else if (num19 > data.m_position.y + (float)ModSettings.BuildingFloodingTolerance / 100f)
                    {
                        //Debug.Log("[RF].CBAId Detoured Flooding Notification");
                        num    /= 2;
                        problem = Notification.AddProblems(problem, Notification.Problem.Flood);
                        GuideController properties3 = Singleton <GuideManager> .instance.m_properties;
                        if (properties3 != null)
                        {
                            Singleton <BuildingManager> .instance.m_buildingFlooded.Activate(properties3.m_buildingFlooded, buildingID);
                        }
                    }
                }
                //Debug.Log("[RF].CBAId Detouring was sucessful!");
            }

            byte district = instance.GetDistrict(data.m_position);

            instance.m_districts.m_buffer[(int)district].AddUsageData(electricityUsage, heatingUsage, waterUsage, sewageUsage);
            data.m_problems = problem;
            return(num);
        }
        public override void SimulationStep(ushort segmentID, ref NetSegment data)
        {
            //Start PlayerNEtAI.SimulationStep

            NetManager instance = Singleton <NetManager> .instance;

            Notification.Problem problem = Notification.RemoveProblems(data.m_problems, Notification.Problem.Flood);
            float num  = 0f;
            uint  num2 = data.m_lanes;
            int   num3 = 0;

            while (num3 < this.m_info.m_lanes.Length && num2 != 0u)
            {
                NetInfo.Lane lane = this.m_info.m_lanes[num3];
                if (lane.m_laneType == NetInfo.LaneType.Vehicle)
                {
                    num += instance.m_lanes.m_buffer[(int)((UIntPtr)num2)].m_length;
                }
                num2 = instance.m_lanes.m_buffer[(int)((UIntPtr)num2)].m_nextLane;
                num3++;
            }
            int num4 = Mathf.RoundToInt(num) << 4;
            int num5 = 0;

            if (num4 != 0)
            {
                num5 = (int)((byte)Mathf.Min((int)(data.m_trafficBuffer * 100) / num4, 100));
            }
            data.m_trafficBuffer = 0;
            if (num5 > (int)data.m_trafficDensity)
            {
                data.m_trafficDensity = (byte)Mathf.Min((int)(data.m_trafficDensity + 5), num5);
            }
            else if (num5 < (int)data.m_trafficDensity)
            {
                data.m_trafficDensity = (byte)Mathf.Max((int)(data.m_trafficDensity - 5), num5);
            }
            Vector3 position  = instance.m_nodes.m_buffer[(int)data.m_startNode].m_position;
            Vector3 position2 = instance.m_nodes.m_buffer[(int)data.m_endNode].m_position;
            Vector3 vector    = (position + position2) * 0.5f;
            bool    flag      = false;

            if ((this.m_info.m_setVehicleFlags & Vehicle.Flags.Underground) == (Vehicle.Flags) 0)
            {
                float num6 = Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(vector));

                if (num6 > vector.y + ModSettings.TrainTrackFloodedTolerance)
                {
                    flag          = true;
                    data.m_flags |= NetSegment.Flags.Flooded;
                    problem       = Notification.AddProblems(problem, Notification.Problem.Flood | Notification.Problem.MajorProblem);
                }
                else
                {
                    data.m_flags &= ~NetSegment.Flags.Flooded;
                    if (num6 > vector.y + ModSettings.TrainTrackFloodingTolerance)
                    {
                        flag    = true;
                        problem = Notification.AddProblems(problem, Notification.Problem.Flood);
                    }
                }
                int num7 = (int)data.m_wetness;
                if (!instance.m_treatWetAsSnow)
                {
                    if (flag)
                    {
                        num7 = 255;
                    }
                    else
                    {
                        int   num8 = -(num7 + 63 >> 5);
                        float num9 = Singleton <WeatherManager> .instance.SampleRainIntensity(vector, false);

                        if (num9 != 0f)
                        {
                            int num10 = Mathf.RoundToInt(Mathf.Min(num9 * 4000f, 1000f));
                            num8 += Singleton <SimulationManager> .instance.m_randomizer.Int32(num10, num10 + 99) / 100;
                        }
                        num7 = Mathf.Clamp(num7 + num8, 0, 255);
                    }
                }
                if (num7 != (int)data.m_wetness)
                {
                    if (Mathf.Abs((int)data.m_wetness - num7) > 10)
                    {
                        data.m_wetness = (byte)num7;
                        InstanceID empty = InstanceID.Empty;
                        empty.NetSegment = segmentID;
                        instance.AddSmoothColor(empty);
                        empty.NetNode = data.m_startNode;
                        instance.AddSmoothColor(empty);
                        empty.NetNode = data.m_endNode;
                        instance.AddSmoothColor(empty);
                    }
                    else
                    {
                        data.m_wetness            = (byte)num7;
                        instance.m_wetnessChanged = 256;
                    }
                }
            }
            int num11 = (int)(100 - (data.m_trafficDensity - 100) * (data.m_trafficDensity - 100) / 100);
            int num12 = this.m_noiseAccumulation * num11 / 100;

            if (num12 != 0)
            {
                float num13 = Vector3.Distance(position, position2);
                int   num14 = Mathf.FloorToInt(num13 / this.m_noiseRadius);
                for (int i = 0; i < num14; i++)
                {
                    Vector3 position3 = Vector3.Lerp(position, position2, (float)(i + 1) / (float)(num14 + 1));
                    Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, num12, position3, this.m_noiseRadius);
                }
            }
            data.m_problems = problem;
        }
Beispiel #18
0
        public override void SimulationStep(ushort segmentID, ref NetSegment data)
        {
            //Start PlayerNEtAI.SimulationStep

            if (this.HasMaintenanceCost(segmentID, ref data))
            {
                NetManager playerNetAIinstance  = Singleton <NetManager> .instance;
                Vector3    playerNetAIposition  = playerNetAIinstance.m_nodes.m_buffer[(int)data.m_startNode].m_position;
                Vector3    playerNetAIposition2 = playerNetAIinstance.m_nodes.m_buffer[(int)data.m_endNode].m_position;
                int        playerNetAInum       = this.GetMaintenanceCost(playerNetAIposition, playerNetAIposition2);
                bool       playerNetAIflag      = (ulong)(Singleton <SimulationManager> .instance.m_currentFrameIndex >> 8 & 15u) == (ulong)((long)(segmentID & 15));
                if (playerNetAInum != 0)
                {
                    if (playerNetAIflag)
                    {
                        playerNetAInum = playerNetAInum * 16 / 100 - playerNetAInum / 100 * 15;
                    }
                    else
                    {
                        playerNetAInum /= 100;
                    }
                    Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.Maintenance, playerNetAInum, this.m_info.m_class);
                }
                if (playerNetAIflag)
                {
                    float playerNetAInum2 = (float)playerNetAIinstance.m_nodes.m_buffer[(int)data.m_startNode].m_elevation;
                    float playerNetAInum3 = (float)playerNetAIinstance.m_nodes.m_buffer[(int)data.m_endNode].m_elevation;
                    if (this.IsUnderground())
                    {
                        playerNetAInum2 = -playerNetAInum2;
                        playerNetAInum3 = -playerNetAInum3;
                    }
                    int constructionCost = this.GetConstructionCost(playerNetAIposition, playerNetAIposition2, playerNetAInum2, playerNetAInum3);
                    if (constructionCost != 0)
                    {
                        StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt64>(StatisticType.CityValue);

                        if (statisticBase != null)
                        {
                            statisticBase.Add(constructionCost);
                        }
                    }
                }
            }
            //End  PlayerNEtAI.SimulationStep


            SimulationManager instance  = Singleton <SimulationManager> .instance;
            NetManager        instance2 = Singleton <NetManager> .instance;

            Notification.Problem problem = Notification.RemoveProblems(data.m_problems, Notification.Problem.Flood | Notification.Problem.Snow);
            if ((data.m_flags & NetSegment.Flags.AccessFailed) != NetSegment.Flags.None && Singleton <SimulationManager> .instance.m_randomizer.Int32(16u) == 0)
            {
                data.m_flags &= ~NetSegment.Flags.AccessFailed;
            }
            float num  = 0f;
            uint  num2 = data.m_lanes;
            int   num3 = 0;

            while (num3 < this.m_info.m_lanes.Length && num2 != 0u)
            {
                NetInfo.Lane lane = this.m_info.m_lanes[num3];
                if ((byte)(lane.m_laneType & (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle)) != 0 && (lane.m_vehicleType & ~VehicleInfo.VehicleType.Bicycle) != VehicleInfo.VehicleType.None)
                {
                    num += instance2.m_lanes.m_buffer[(int)((UIntPtr)num2)].m_length;
                }
                num2 = instance2.m_lanes.m_buffer[(int)((UIntPtr)num2)].m_nextLane;
                num3++;
            }
            int num4 = 0;

            if (data.m_trafficBuffer == 65535)
            {
                if ((data.m_flags & NetSegment.Flags.Blocked) == NetSegment.Flags.None)
                {
                    data.m_flags        |= NetSegment.Flags.Blocked;
                    data.m_modifiedIndex = instance.m_currentBuildIndex++;
                }
            }
            else
            {
                data.m_flags &= ~NetSegment.Flags.Blocked;
                int num5 = Mathf.RoundToInt(num) << 4;
                if (num5 != 0)
                {
                    num4 = (int)((byte)Mathf.Min((int)(data.m_trafficBuffer * 100) / num5, 100));
                }
            }
            data.m_trafficBuffer = 0;
            if (num4 > (int)data.m_trafficDensity)
            {
                data.m_trafficDensity = (byte)Mathf.Min((int)(data.m_trafficDensity + 5), num4);
            }
            else if (num4 < (int)data.m_trafficDensity)
            {
                data.m_trafficDensity = (byte)Mathf.Max((int)(data.m_trafficDensity - 5), num4);
            }
            Vector3 position  = instance2.m_nodes.m_buffer[(int)data.m_startNode].m_position;
            Vector3 position2 = instance2.m_nodes.m_buffer[(int)data.m_endNode].m_position;
            Vector3 vector    = (position + position2) * 0.5f;
            bool    flag      = false;

            if ((this.m_info.m_setVehicleFlags & Vehicle.Flags.Underground) == (Vehicle.Flags) 0)
            {
                float num6 = Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(vector));

                // NON-STOCK CODE START
                if (num6 > vector.y + (float)ModSettings.RoadwayFloodedTolerance / 100)
                {
                    flag          = true;
                    data.m_flags |= NetSegment.Flags.Flooded;
                    //Debug.Log("[RF] Successfully detoured roadway flooded tolerance");
                    problem = Notification.AddProblems(problem, Notification.Problem.Flood | Notification.Problem.MajorProblem);

                    /*DisasterData floodedSinkHoleData = new DisasterData();
                     * floodedSinkHoleData.m_targetPosition = data.m_middlePosition;
                     * floodedSinkHoleData.m_intensity = (byte)instance.m_randomizer.Int32(100u);
                     */
                    Vector3 min = data.m_bounds.min;
                    Vector3 max = data.m_bounds.max;
                    RoadBaseAI.FloodParkedCars(min.x, min.z, max.x, max.z);
                }

                else
                {
                    data.m_flags &= ~NetSegment.Flags.Flooded;

                    // Rainfall compatibility
                    float add = (float)ModSettings.RoadwayFloodingTolerance / 100;
                    //Debug.Log("[RF] Successfully detoured roadway flooding tolerance");
                    if (num6 > vector.y + add)
                    {
                        flag    = true;
                        problem = Notification.AddProblems(problem, Notification.Problem.Flood);
                    }
                }
                //Debug.Log("[RF] Successfully detoured roadway flooding tolerance: not flooding");
                // NON-STOCK CODE END
            }
            DistrictManager instance3 = Singleton <DistrictManager> .instance;
            byte            district  = instance3.GetDistrict(vector);

            DistrictPolicies.CityPlanning cityPlanningPolicies = instance3.m_districts.m_buffer[(int)district].m_cityPlanningPolicies;
            int num7 = (int)(100 - (data.m_trafficDensity - 100) * (data.m_trafficDensity - 100) / 100);

            if ((this.m_info.m_vehicleTypes & VehicleInfo.VehicleType.Car) != VehicleInfo.VehicleType.None)
            {
                if ((this.m_info.m_setVehicleFlags & Vehicle.Flags.Underground) == (Vehicle.Flags) 0)
                {
                    if (flag && (data.m_flags & (NetSegment.Flags.AccessFailed | NetSegment.Flags.Blocked)) == NetSegment.Flags.None && instance.m_randomizer.Int32(10u) == 0)
                    {
                        TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                        offer.Priority   = 4;
                        offer.NetSegment = segmentID;
                        offer.Position   = vector;
                        offer.Amount     = 1;
                        Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.FloodWater, offer);
                    }
                    int num8 = (int)data.m_wetness;
                    if (!instance2.m_treatWetAsSnow)
                    {
                        if (flag)
                        {
                            num8 = 255;
                        }
                        else
                        {
                            int   num9  = -(num8 + 63 >> 5);
                            float num10 = Singleton <WeatherManager> .instance.SampleRainIntensity(vector, false);

                            if (num10 != 0f)
                            {
                                int num11 = Mathf.RoundToInt(Mathf.Min(num10 * 4000f, 1000f));
                                num9 += instance.m_randomizer.Int32(num11, num11 + 99) / 100;
                            }
                            num8 = Mathf.Clamp(num8 + num9, 0, 255);
                        }
                    }
                    else if (this.m_accumulateSnow)
                    {
                        if (flag)
                        {
                            num8 = 128;
                        }
                        else
                        {
                            float num12 = Singleton <WeatherManager> .instance.SampleRainIntensity(vector, false);

                            if (num12 != 0f)
                            {
                                int num13 = Mathf.RoundToInt(num12 * 400f);
                                int num14 = instance.m_randomizer.Int32(num13, num13 + 99) / 100;
                                if (Singleton <UnlockManager> .instance.Unlocked(UnlockManager.Feature.Snowplow))
                                {
                                    num8 = Mathf.Min(num8 + num14, 255);
                                }
                                else
                                {
                                    num8 = Mathf.Min(num8 + num14, 128);
                                }
                            }
                            else if (Singleton <SimulationManager> .instance.m_randomizer.Int32(4u) == 0)
                            {
                                num8 = Mathf.Max(num8 - 1, 0);
                            }
                            if (num8 >= 64 && (data.m_flags & (NetSegment.Flags.AccessFailed | NetSegment.Flags.Blocked | NetSegment.Flags.Flooded)) == NetSegment.Flags.None && instance.m_randomizer.Int32(10u) == 0)
                            {
                                TransferManager.TransferOffer offer2 = default(TransferManager.TransferOffer);
                                offer2.Priority   = num8 / 50;
                                offer2.NetSegment = segmentID;
                                offer2.Position   = vector;
                                offer2.Amount     = 1;
                                Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.Snow, offer2);
                            }
                            if (num8 >= 192)
                            {
                                problem = Notification.AddProblems(problem, Notification.Problem.Snow);
                            }
                            District[] expr_5B7_cp_0_cp_0 = instance3.m_districts.m_buffer;
                            byte       expr_5B7_cp_0_cp_1 = district;
                            expr_5B7_cp_0_cp_0[(int)expr_5B7_cp_0_cp_1].m_productionData.m_tempSnowCover = expr_5B7_cp_0_cp_0[(int)expr_5B7_cp_0_cp_1].m_productionData.m_tempSnowCover + (uint)num8;
                        }
                    }
                    if (num8 != (int)data.m_wetness)
                    {
                        if (Mathf.Abs((int)data.m_wetness - num8) > 10)
                        {
                            data.m_wetness = (byte)num8;
                            InstanceID empty = InstanceID.Empty;
                            empty.NetSegment = segmentID;
                            instance2.AddSmoothColor(empty);
                            empty.NetNode = data.m_startNode;
                            instance2.AddSmoothColor(empty);
                            empty.NetNode = data.m_endNode;
                            instance2.AddSmoothColor(empty);
                        }
                        else
                        {
                            data.m_wetness             = (byte)num8;
                            instance2.m_wetnessChanged = 256;
                        }
                    }
                }
                int num15;
                if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.StuddedTires) != DistrictPolicies.CityPlanning.None)
                {
                    num7  = num7 * 3 + 1 >> 1;
                    num15 = Mathf.Min(700, (int)(50 + data.m_trafficDensity * 6));
                }
                else
                {
                    num15 = Mathf.Min(500, (int)(50 + data.m_trafficDensity * 4));
                }
                if (!this.m_highwayRules)
                {
                    int num16 = instance.m_randomizer.Int32(num15, num15 + 99) / 100;
                    data.m_condition = (byte)Mathf.Max((int)data.m_condition - num16, 0);
                    if (data.m_condition < 192 && (data.m_flags & (NetSegment.Flags.AccessFailed | NetSegment.Flags.Blocked | NetSegment.Flags.Flooded)) == NetSegment.Flags.None && instance.m_randomizer.Int32(20u) == 0)
                    {
                        TransferManager.TransferOffer offer3 = default(TransferManager.TransferOffer);
                        offer3.Priority   = (int)((255 - data.m_condition) / 50);
                        offer3.NetSegment = segmentID;
                        offer3.Position   = vector;
                        offer3.Amount     = 1;
                        Singleton <TransferManager> .instance.AddIncomingOffer(TransferManager.TransferReason.RoadMaintenance, offer3);
                    }
                }
            }
            if (!this.m_highwayRules)
            {
                if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.HeavyTrafficBan) != DistrictPolicies.CityPlanning.None)
                {
                    data.m_flags |= NetSegment.Flags.HeavyBan;
                }
                else
                {
                    data.m_flags &= ~NetSegment.Flags.HeavyBan;
                }
                if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.BikeBan) != DistrictPolicies.CityPlanning.None)
                {
                    data.m_flags |= NetSegment.Flags.BikeBan;
                }
                else
                {
                    data.m_flags &= ~NetSegment.Flags.BikeBan;
                }
                if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.OldTown) != DistrictPolicies.CityPlanning.None)
                {
                    data.m_flags |= NetSegment.Flags.CarBan;
                }
                else
                {
                    data.m_flags &= ~NetSegment.Flags.CarBan;
                }
            }
            int num17 = this.m_noiseAccumulation * num7 / 100;

            if (num17 != 0)
            {
                float num18 = Vector3.Distance(position, position2);
                int   num19 = Mathf.FloorToInt(num18 / this.m_noiseRadius);
                for (int i = 0; i < num19; i++)
                {
                    Vector3 position3 = Vector3.Lerp(position, position2, (float)(i + 1) / (float)(num19 + 1));
                    Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, num17, position3, this.m_noiseRadius);
                }
            }
            if (data.m_trafficDensity >= 50 && data.m_averageLength < 25f && (instance2.m_nodes.m_buffer[(int)data.m_startNode].m_flags & (NetNode.Flags.LevelCrossing | NetNode.Flags.TrafficLights)) == NetNode.Flags.TrafficLights && (instance2.m_nodes.m_buffer[(int)data.m_endNode].m_flags & (NetNode.Flags.LevelCrossing | NetNode.Flags.TrafficLights)) == NetNode.Flags.TrafficLights)
            {
                GuideController properties = Singleton <GuideManager> .instance.m_properties;
                if (properties != null)
                {
                    Singleton <NetManager> .instance.m_shortRoadTraffic.Activate(properties.m_shortRoadTraffic, segmentID);
                }
            }
            if ((data.m_flags & NetSegment.Flags.Collapsed) != NetSegment.Flags.None)
            {
                GuideController properties2 = Singleton <GuideManager> .instance.m_properties;
                if (properties2 != null)
                {
                    Singleton <NetManager> .instance.m_roadDestroyed.Activate(properties2.m_roadDestroyed, segmentID);

                    Singleton <NetManager> .instance.m_roadDestroyed2.Activate(properties2.m_roadDestroyed2, this.m_info.m_class.m_service);
                }
                if ((ulong)(instance.m_currentFrameIndex >> 8 & 15u) == (ulong)((long)(segmentID & 15)))
                {
                    int           delta         = Mathf.RoundToInt(data.m_averageLength);
                    StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt32>(StatisticType.DestroyedLength);

                    statisticBase.Add(delta);
                }
            }
            data.m_problems = problem;
        }
        public static void Postfix(ushort buildingID, ref Building buildingData, ref Building.Frame frameData)
        {
            // Update problems
            if (CustomPlayerBuildingAI.CanOperation(buildingID, ref buildingData) && buildingData.m_flags.IsFlagSet(Building.Flags.Completed) && (RealConstruction.operationConsumption != 2))
            {
                OperationAI.ProcessPlayerBuildingOperation(buildingID, ref buildingData);
                if (MainDataStore.operationResourceBuffer[buildingID] > 100)
                {
                    if (buildingData.Info.m_class.m_service == ItemClass.Service.PlayerIndustry)
                    {
                        if (buildingData.Info.m_class.m_subService == ItemClass.SubService.PlayerIndustryFarming)
                        {
                            if (RealConstruction.operationConsumption == 1)
                            {
                                MainDataStore.operationResourceBuffer[buildingID] -= 5;
                            }
                            else
                            {
                                MainDataStore.operationResourceBuffer[buildingID] -= 10;
                            }
                        }
                        else if (buildingData.Info.m_class.m_subService == ItemClass.SubService.PlayerIndustryForestry)
                        {
                            if (RealConstruction.operationConsumption == 1)
                            {
                                MainDataStore.operationResourceBuffer[buildingID] -= 10;
                            }
                            else
                            {
                                MainDataStore.operationResourceBuffer[buildingID] -= 20;
                            }
                        }
                        else if (buildingData.Info.m_class.m_subService == ItemClass.SubService.PlayerIndustryOre)
                        {
                            if (RealConstruction.operationConsumption == 1)
                            {
                                MainDataStore.operationResourceBuffer[buildingID] -= 15;
                            }
                            else
                            {
                                MainDataStore.operationResourceBuffer[buildingID] -= 30;
                            }
                        }
                        else if (buildingData.Info.m_class.m_subService == ItemClass.SubService.PlayerIndustryOil)
                        {
                            if (RealConstruction.operationConsumption == 1)
                            {
                                MainDataStore.operationResourceBuffer[buildingID] -= 20;
                            }
                            else
                            {
                                MainDataStore.operationResourceBuffer[buildingID] -= 40;
                            }
                        }
                        else
                        {
                            if (RealConstruction.operationConsumption == 1)
                            {
                                MainDataStore.operationResourceBuffer[buildingID] -= 25;
                            }
                            else
                            {
                                MainDataStore.operationResourceBuffer[buildingID] -= 50;
                            }
                        }
                    }
                    else
                    {
                        if (RealConstruction.operationConsumption == 1)
                        {
                            MainDataStore.operationResourceBuffer[buildingID] -= 50;
                        }
                        else
                        {
                            MainDataStore.operationResourceBuffer[buildingID] -= 100;
                        }
                    }

                    if (CustomPlayerBuildingAI.CanRemoveNoResource(buildingID, ref buildingData))
                    {
                        Notification.Problem problem = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoResources);
                        buildingData.m_problems = problem;
                    }
                }
                else
                {
                    MainDataStore.operationResourceBuffer[buildingID] = 0;
                    if (RealConstruction.debugMode)
                    {
                        if (buildingData.m_problems == Notification.Problem.None)
                        {
                            Notification.Problem problem = Notification.AddProblems(buildingData.m_problems, Notification.Problem.NoResources);
                            buildingData.m_problems = problem;
                        }
                    }
                    else
                    {
                        if (CustomPlayerBuildingAI.CanRemoveNoResource(buildingID, ref buildingData))
                        {
                            Notification.Problem problem = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoResources);
                            buildingData.m_problems = problem;
                        }
                    }
                }
            }
            else
            {
                if (CustomPlayerBuildingAI.CanRemoveNoResource(buildingID, ref buildingData))
                {
                    Notification.Problem problem = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoResources);
                    buildingData.m_problems = problem;
                }
            }

            if (CustomPlayerBuildingAI.CanConstruction(buildingID, ref buildingData))
            {
                if (!buildingData.m_flags.IsFlagSet(Building.Flags.Completed))
                {
                    ConstructionAI.ProcessBuildingConstruction(buildingID, ref buildingData, ref frameData);
                    if (MainDataStore.constructionResourceBuffer[buildingID] >= 8000)
                    {
                        Notification.Problem problem = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoResources);
                        buildingData.m_problems = problem;
                    }
                    else
                    {
                        if (RealConstruction.debugMode)
                        {
                            if (buildingData.m_problems == Notification.Problem.None)
                            {
                                Notification.Problem problem = Notification.AddProblems(buildingData.m_problems, Notification.Problem.NoResources);
                                buildingData.m_problems = problem;
                            }
                        }
                    }
                }
            }

            //
            if (ResourceBuildingAI.IsSpecialBuilding((ushort)buildingID))
            {
                if (buildingData.m_flags.IsFlagSet(Building.Flags.Completed))
                {
                    ResourceBuildingAI.ProcessCityResourceDepartmentBuildingGoods(buildingID, ref buildingData);
                    ResourceBuildingAI.ProcessCityResourceDepartmentBuildingOutgoing(buildingID, ref buildingData);
                    ResourceBuildingAI.ProcessCityResourceDepartmentBuildingIncoming(buildingID, ref buildingData);
                }
            }
        }
Beispiel #20
0
        public static void SimulationStepActive(CommercialBuildingAI thisAI, ushort buildingID, ref Building buildingData, ref Building.Frame frameData)
        {
            //This is a mess because I pulled it directly from the decompiled code and patched it up slightly.
            //It works though, and that's all I'm bothered about for now.

            if (thisAI)
            {
                DistrictManager               instance1            = Singleton <DistrictManager> .instance;
                byte                          district             = instance1.GetDistrict(buildingData.m_position);
                DistrictPolicies.Services     policies             = instance1.m_districts.m_buffer[(int)district].m_servicePolicies;
                DistrictPolicies.Taxation     taxationPolicies     = instance1.m_districts.m_buffer[(int)district].m_taxationPolicies;
                DistrictPolicies.CityPlanning cityPlanningPolicies = instance1.m_districts.m_buffer[(int)district].m_cityPlanningPolicies;
                instance1.m_districts.m_buffer[(int)district].m_servicePoliciesEffect |= policies & (DistrictPolicies.Services.PowerSaving | DistrictPolicies.Services.WaterSaving | DistrictPolicies.Services.SmokeDetectors | DistrictPolicies.Services.Recycling | DistrictPolicies.Services.RecreationalUse | DistrictPolicies.Services.ExtraInsulation | DistrictPolicies.Services.NoElectricity | DistrictPolicies.Services.OnlyElectricity | DistrictPolicies.Services.RecyclePlastic);
                switch (thisAI.m_info.m_class.m_subService)
                {
                case ItemClass.SubService.CommercialLow:
                    if ((taxationPolicies & (DistrictPolicies.Taxation.TaxRaiseComLow | DistrictPolicies.Taxation.TaxLowerComLow)) != (DistrictPolicies.Taxation.TaxRaiseComLow | DistrictPolicies.Taxation.TaxLowerComLow))
                    {
                        instance1.m_districts.m_buffer[(int)district].m_taxationPoliciesEffect |= taxationPolicies & (DistrictPolicies.Taxation.TaxRaiseComLow | DistrictPolicies.Taxation.TaxLowerComLow);
                    }
                    instance1.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= cityPlanningPolicies & DistrictPolicies.CityPlanning.SmallBusiness;
                    break;

                case ItemClass.SubService.CommercialHigh:
                    if ((taxationPolicies & (DistrictPolicies.Taxation.TaxRaiseComHigh | DistrictPolicies.Taxation.TaxLowerComHigh)) != (DistrictPolicies.Taxation.TaxRaiseComHigh | DistrictPolicies.Taxation.TaxLowerComHigh))
                    {
                        instance1.m_districts.m_buffer[(int)district].m_taxationPoliciesEffect |= taxationPolicies & (DistrictPolicies.Taxation.TaxRaiseComHigh | DistrictPolicies.Taxation.TaxLowerComHigh);
                    }
                    instance1.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= cityPlanningPolicies & DistrictPolicies.CityPlanning.BigBusiness;
                    break;

                case ItemClass.SubService.CommercialLeisure:
                    instance1.m_districts.m_buffer[(int)district].m_taxationPoliciesEffect     |= taxationPolicies & DistrictPolicies.Taxation.DontTaxLeisure;
                    instance1.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= cityPlanningPolicies & DistrictPolicies.CityPlanning.NoLoudNoises;
                    break;

                case ItemClass.SubService.CommercialTourist:
                    instance1.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= cityPlanningPolicies & DistrictPolicies.CityPlanning.LightningRods;
                    break;

                case ItemClass.SubService.CommercialEco:
                    instance1.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= cityPlanningPolicies;
                    break;
                }
                Citizen.BehaviourData behaviour = new Citizen.BehaviourData();
                int aliveWorkerCount            = 0;
                int totalWorkerCount            = 0;
                int workPlaceCount = 0;
                int num1           = NewPrivateBuildingAI.HandleWorkers(thisAI, buildingID, ref buildingData, ref behaviour, ref aliveWorkerCount, ref totalWorkerCount, ref workPlaceCount);

                if ((buildingData.m_flags & Building.Flags.Evacuating) != Building.Flags.None)
                {
                    num1 = 0;
                }

                int width      = buildingData.Width;
                int length     = buildingData.Length;
                int num2       = MaxIncomingLoadSize(thisAI);
                int aliveCount = 0;
                int totalCount = 0;
                GetVisitBehaviour(thisAI, buildingID, ref buildingData, ref behaviour, ref aliveCount, ref totalCount);
                int visitCount = thisAI.CalculateVisitplaceCount(new Randomizer((int)buildingID), width, length);
                int num3       = Mathf.Max(0, visitCount - totalCount);
                int a1         = visitCount * 500;
                int num4       = Mathf.Max(a1, num2 * 4);
                TransferManager.TransferReason incomingTransferReason = GetIncomingTransferReason(thisAI);
                TransferManager.TransferReason outgoingTransferReason = GetOutgoingTransferReason(thisAI, buildingID);
                if (num1 != 0)
                {
                    int num5 = num4;
                    if (incomingTransferReason != TransferManager.TransferReason.None)
                    {
                        num5 = Mathf.Min(num5, (int)buildingData.m_customBuffer1);
                    }
                    if (outgoingTransferReason != TransferManager.TransferReason.None)
                    {
                        num5 = Mathf.Min(num5, num4 - (int)buildingData.m_customBuffer2);
                    }
                    int num6 = Mathf.Max(0, Mathf.Min(num1, (num5 * 200 + num4 - 1) / num4));
                    int a2   = (visitCount * num6 + 9) / 10;
                    if (Singleton <SimulationManager> .instance.m_isNightTime)
                    {
                        a2 = a2 + 1 >> 1;
                    }
                    int num7 = Mathf.Max(0, Mathf.Min(a2, num5));
                    if (incomingTransferReason != TransferManager.TransferReason.None)
                    {
                        buildingData.m_customBuffer1 -= (ushort)num7;
                    }
                    if (outgoingTransferReason != TransferManager.TransferReason.None)
                    {
                        buildingData.m_customBuffer2 += (ushort)num7;
                    }
                    num1 = (num7 + 9) / 10;
                }
                int electricityConsumption;
                int waterConsumption;
                int sewageAccumulation;
                int garbageAccumulation;
                int incomeAccumulation;
                thisAI.GetConsumptionRates(new Randomizer((int)buildingID), num1, out electricityConsumption, out waterConsumption, out sewageAccumulation, out garbageAccumulation, out incomeAccumulation);
                int heatingConsumption = 0;
                if (electricityConsumption != 0 && instance1.IsPolicyLoaded(DistrictPolicies.Policies.ExtraInsulation))
                {
                    if ((policies & DistrictPolicies.Services.ExtraInsulation) != DistrictPolicies.Services.None)
                    {
                        heatingConsumption = Mathf.Max(1, electricityConsumption * 3 + 8 >> 4);
                        incomeAccumulation = incomeAccumulation * 95 / 100;
                    }
                    else
                    {
                        heatingConsumption = Mathf.Max(1, electricityConsumption + 2 >> 2);
                    }
                }
                if (garbageAccumulation != 0 && (policies & DistrictPolicies.Services.Recycling) != DistrictPolicies.Services.None)
                {
                    garbageAccumulation = Mathf.Max(1, garbageAccumulation * 85 / 100);
                    incomeAccumulation  = incomeAccumulation * 95 / 100;
                }
                int taxRate;
                switch (thisAI.m_info.m_class.m_subService)
                {
                case ItemClass.SubService.CommercialLeisure:
                    taxRate = (buildingData.m_flags & Building.Flags.HighDensity) == Building.Flags.None ? Singleton <EconomyManager> .instance.GetTaxRate(ItemClass.Service.Commercial, ItemClass.SubService.CommercialLow, thisAI.m_info.m_class.m_level, taxationPolicies) : Singleton <EconomyManager> .instance.GetTaxRate(ItemClass.Service.Commercial, ItemClass.SubService.CommercialHigh, thisAI.m_info.m_class.m_level, taxationPolicies);

                    if ((taxationPolicies & DistrictPolicies.Taxation.DontTaxLeisure) != DistrictPolicies.Taxation.None)
                    {
                        taxRate = 0;
                    }
                    if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.NoLoudNoises) != DistrictPolicies.CityPlanning.None && Singleton <SimulationManager> .instance.m_isNightTime)
                    {
                        electricityConsumption = electricityConsumption + 1 >> 1;
                        waterConsumption       = waterConsumption + 1 >> 1;
                        sewageAccumulation     = sewageAccumulation + 1 >> 1;
                        garbageAccumulation    = garbageAccumulation + 1 >> 1;
                        incomeAccumulation     = 0;
                        break;
                    }
                    break;

                case ItemClass.SubService.CommercialTourist:
                    taxRate = (buildingData.m_flags & Building.Flags.HighDensity) == Building.Flags.None ? Singleton <EconomyManager> .instance.GetTaxRate(ItemClass.Service.Commercial, ItemClass.SubService.CommercialLow, thisAI.m_info.m_class.m_level, taxationPolicies) : Singleton <EconomyManager> .instance.GetTaxRate(ItemClass.Service.Commercial, ItemClass.SubService.CommercialHigh, thisAI.m_info.m_class.m_level, taxationPolicies);

                    break;

                default:
                    taxRate = Singleton <EconomyManager> .instance.GetTaxRate(thisAI.m_info.m_class, taxationPolicies);

                    break;
                }
                if (num1 != 0)
                {
                    int num5 = HandleCommonConsumption(thisAI, buildingID, ref buildingData, ref frameData, ref electricityConsumption, ref heatingConsumption, ref waterConsumption, ref sewageAccumulation, ref garbageAccumulation, policies);
                    num1 = (num1 * num5 + 99) / 100;
                    if (num1 != 0)
                    {
                        int amount1 = incomeAccumulation;
                        if (amount1 != 0)
                        {
                            if (thisAI.m_info.m_class.m_subService == ItemClass.SubService.CommercialLow)
                            {
                                if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.SmallBusiness) != DistrictPolicies.CityPlanning.None)
                                {
                                    Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, 12, thisAI.m_info.m_class);

                                    amount1 *= 2;
                                }
                            }
                            else if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.BigBusiness) != DistrictPolicies.CityPlanning.None)
                            {
                                Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.PolicyCost, 25, thisAI.m_info.m_class);

                                amount1 *= 3;
                            }
                            if ((policies & DistrictPolicies.Services.RecreationalUse) != DistrictPolicies.Services.None)
                            {
                                amount1 = (amount1 * 105 + 99) / 100;
                            }
                            int num6 = Singleton <EconomyManager> .instance.AddPrivateIncome(amount1, ItemClass.Service.Commercial, thisAI.m_info.m_class.m_subService, thisAI.m_info.m_class.m_level, taxRate);

                            int amount2 = (behaviour.m_touristCount * num6 + (aliveCount >> 1)) / Mathf.Max(1, aliveCount);
                            int amount3 = Mathf.Max(0, num6 - amount2);
                            if (amount3 != 0)
                            {
                                Singleton <EconomyManager> .instance.AddResource(EconomyManager.Resource.CitizenIncome, amount3, thisAI.m_info.m_class);
                            }
                            if (amount2 != 0)
                            {
                                Singleton <EconomyManager> .instance.AddResource(EconomyManager.Resource.TourismIncome, amount2, thisAI.m_info.m_class);
                            }
                        }
                        int groundPollution;
                        int noisePollution;
                        thisAI.GetPollutionRates(num1, cityPlanningPolicies, out groundPollution, out noisePollution);
                        if (groundPollution != 0 && Singleton <SimulationManager> .instance.m_randomizer.Int32(3U) == 0)
                        {
                            Singleton <NaturalResourceManager> .instance.TryDumpResource(NaturalResourceManager.Resource.Pollution, groundPollution, groundPollution, buildingData.m_position, 60f);
                        }
                        if (noisePollution != 0)
                        {
                            Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, noisePollution, buildingData.m_position, 60f);
                        }
                        if (num5 < 100)
                        {
                            buildingData.m_flags |= Building.Flags.RateReduced;
                        }
                        else
                        {
                            buildingData.m_flags &= ~Building.Flags.RateReduced;
                        }
                        buildingData.m_flags |= Building.Flags.Active;
                    }
                    else
                    {
                        buildingData.m_flags &= ~(Building.Flags.RateReduced | Building.Flags.Active);
                    }
                }
                else
                {
                    electricityConsumption  = 0;
                    heatingConsumption      = 0;
                    waterConsumption        = 0;
                    sewageAccumulation      = 0;
                    garbageAccumulation     = 0;
                    buildingData.m_problems = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.Electricity | Notification.Problem.Water | Notification.Problem.Sewage | Notification.Problem.Flood | Notification.Problem.Heating);
                    buildingData.m_flags   &= ~(Building.Flags.RateReduced | Building.Flags.Active);
                }
                int   health    = 0;
                int   wellbeing = 0;
                float radius    = (float)(buildingData.Width + buildingData.Length) * 2.5f;
                if (behaviour.m_healthAccumulation != 0)
                {
                    if (aliveWorkerCount + aliveCount != 0)
                    {
                        health = (behaviour.m_healthAccumulation + (aliveWorkerCount + aliveCount >> 1)) / (aliveWorkerCount + aliveCount);
                    }
                    Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Health, behaviour.m_healthAccumulation, buildingData.m_position, radius);
                }
                if (behaviour.m_wellbeingAccumulation != 0)
                {
                    if (aliveWorkerCount + aliveCount != 0)
                    {
                        wellbeing = (behaviour.m_wellbeingAccumulation + (aliveWorkerCount + aliveCount >> 1)) / (aliveWorkerCount + aliveCount);
                    }
                    Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Wellbeing, behaviour.m_wellbeingAccumulation, buildingData.m_position, radius);
                }
                int num8 = Citizen.GetHappiness(health, wellbeing) * 15 / 100;
                int a3   = aliveWorkerCount * 20 / workPlaceCount;
                if ((buildingData.m_problems & Notification.Problem.MajorProblem) == Notification.Problem.None)
                {
                    num8 += 20;
                }
                if (buildingData.m_problems == Notification.Problem.None)
                {
                    num8 += 25;
                }
                int num9  = num8 + Mathf.Min(a3, (int)buildingData.m_customBuffer1 * a3 / num4) + (a3 - Mathf.Min(a3, (int)buildingData.m_customBuffer2 * a3 / num4));
                int num10 = (int)(8 - thisAI.m_info.m_class.m_level);
                int num11 = (int)(11 - thisAI.m_info.m_class.m_level);
                if (thisAI.m_info.m_class.m_subService == ItemClass.SubService.CommercialHigh)
                {
                    ++num10;
                    ++num11;
                }
                if (taxRate < num10)
                {
                    num9 += num10 - taxRate;
                }
                if (taxRate > num11)
                {
                    num9 -= taxRate - num11;
                }
                if (taxRate >= num11 + 4)
                {
                    if ((int)buildingData.m_taxProblemTimer != 0 || Singleton <SimulationManager> .instance.m_randomizer.Int32(32U) == 0)
                    {
                        int num5 = taxRate - num11 >> 2;
                        buildingData.m_taxProblemTimer = (byte)Mathf.Min((int)byte.MaxValue, (int)buildingData.m_taxProblemTimer + num5);
                        if ((int)buildingData.m_taxProblemTimer >= 96)
                        {
                            buildingData.m_problems = Notification.AddProblems(buildingData.m_problems, Notification.Problem.TaxesTooHigh | Notification.Problem.MajorProblem);
                        }
                        else if ((int)buildingData.m_taxProblemTimer >= 32)
                        {
                            buildingData.m_problems = Notification.AddProblems(buildingData.m_problems, Notification.Problem.TaxesTooHigh);
                        }
                    }
                }
                else
                {
                    buildingData.m_taxProblemTimer = (byte)Mathf.Max(0, (int)buildingData.m_taxProblemTimer - 1);
                    buildingData.m_problems        = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.TaxesTooHigh);
                }
                int entertainment;
                int attractiveness;
                GetAccumulation(thisAI, new Randomizer((int)buildingID), num1, taxRate, cityPlanningPolicies, taxationPolicies, out entertainment, out attractiveness);
                if (entertainment != 0)
                {
                    Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Entertainment, entertainment, buildingData.m_position, radius);
                }
                if (attractiveness != 0)
                {
                    Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Attractiveness, attractiveness);
                }
                int happiness = Mathf.Clamp(num9, 0, 100);
                buildingData.m_health       = (byte)health;
                buildingData.m_happiness    = (byte)happiness;
                buildingData.m_citizenCount = (byte)(aliveWorkerCount + aliveCount);
                HandleDead(thisAI, buildingID, ref buildingData, ref behaviour, totalWorkerCount + totalCount);
                int crimeAccumulation = behaviour.m_crimeAccumulation / 10;
                if (thisAI.m_info.m_class.m_subService == ItemClass.SubService.CommercialLeisure)
                {
                    crimeAccumulation = crimeAccumulation * 5 + 3 >> 2;
                }
                if ((policies & DistrictPolicies.Services.RecreationalUse) != DistrictPolicies.Services.None)
                {
                    crimeAccumulation = crimeAccumulation * 3 + 3 >> 2;
                }
                HandleCrime(thisAI, buildingID, ref buildingData, crimeAccumulation, (int)buildingData.m_citizenCount);
                int num12 = (int)buildingData.m_crimeBuffer;
                if (aliveWorkerCount != 0)
                {
                    Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Density, aliveWorkerCount, buildingData.m_position, radius);

                    int num5 = (behaviour.m_educated0Count * 100 + behaviour.m_educated1Count * 50 + behaviour.m_educated2Count * 30) / aliveWorkerCount + 50;
                    buildingData.m_fireHazard = (byte)num5;
                }
                else
                {
                    buildingData.m_fireHazard = (byte)0;
                }
                int crimeRate = (int)buildingData.m_citizenCount == 0 ? 0 : (num12 + ((int)buildingData.m_citizenCount >> 1)) / (int)buildingData.m_citizenCount;
                int count     = 0;
                int cargo     = 0;
                int capacity  = 0;
                int outside   = 0;
                if (incomingTransferReason != TransferManager.TransferReason.None)
                {
                    CalculateGuestVehicles(thisAI, buildingID, ref buildingData, incomingTransferReason, ref count, ref cargo, ref capacity, ref outside);
                    buildingData.m_tempImport = (byte)Mathf.Clamp(outside, (int)buildingData.m_tempImport, (int)byte.MaxValue);
                }
                buildingData.m_tempExport = (byte)Mathf.Clamp(behaviour.m_touristCount, (int)buildingData.m_tempExport, (int)byte.MaxValue);
                SimulationManager _simulationManager = Singleton <SimulationManager> .instance;
                if ((long)((_simulationManager.m_currentFrameIndex & 3840U) >> 8) == (long)((int)buildingID & 15) && (thisAI.m_info.m_class.m_subService == ItemClass.SubService.CommercialLow || thisAI.m_info.m_class.m_subService == ItemClass.SubService.CommercialHigh) && ((int)Singleton <ZoneManager> .instance.m_lastBuildIndex == (int)_simulationManager.m_currentBuildIndex && (buildingData.m_flags & Building.Flags.Upgrading) == Building.Flags.None))
                {
                    CheckBuildingLevel(thisAI, buildingID, ref buildingData, ref frameData, ref behaviour, aliveCount);
                }
                if ((buildingData.m_flags & (Building.Flags.Completed | Building.Flags.Upgrading)) == Building.Flags.None)
                {
                    return;
                }
                Notification.Problem problems1 = Notification.RemoveProblems(buildingData.m_problems, Notification.Problem.NoCustomers | Notification.Problem.NoGoods);

                //Begin edited section

                if ((int)buildingData.m_customBuffer2 > num4 - (a1 >> 1) && aliveCount <= visitCount >> 1)
                {
                    if (_simulationManager.m_currentDayTimeHour > 19 && _simulationManager.m_currentDayTimeHour < 20)
                    {
                        buildingData.m_outgoingProblemTimer = (byte)Mathf.Min(byte.MaxValue, buildingData.m_outgoingProblemTimer + 1);

                        if (buildingData.m_outgoingProblemTimer >= 192)
                        {
                            problems1 = Notification.AddProblems(problems1, Notification.Problem.NoCustomers | Notification.Problem.MajorProblem);
                        }
                        else if (buildingData.m_outgoingProblemTimer >= 128)
                        {
                            problems1 = Notification.AddProblems(problems1, Notification.Problem.NoCustomers);
                        }
                    }
                    else
                    {
                        buildingData.m_outgoingProblemTimer = 0;
                    }
                }
                else
                {
                    buildingData.m_outgoingProblemTimer = (byte)0;
                }

                if (!CityEventManager.instance.EventStartsWithin(3D) && !CityEventManager.instance.EventTakingPlace() && !CityEventManager.instance.EventJustEnded())
                {
                    if ((int)buildingData.m_customBuffer1 == 0)
                    {
                        buildingData.m_incomingProblemTimer = (byte)Mathf.Min((int)byte.MaxValue, (int)buildingData.m_incomingProblemTimer + 1);
                        problems1 = (int)buildingData.m_incomingProblemTimer >= 64 ? Notification.AddProblems(problems1, Notification.Problem.NoGoods | Notification.Problem.MajorProblem) : Notification.AddProblems(problems1, Notification.Problem.NoGoods);
                    }
                    else
                    {
                        buildingData.m_incomingProblemTimer = (byte)0;
                    }

                    float currentHour = _simulationManager.m_currentDayTimeHour;

                    //Artifically shop at night to keep industry happy. Will give the effect of industry stocking up commercial over night.
                    //Note: ModifyMaterialBuffer is expensive, so if there's any performance impact with the mod now, it'll most likely be this.
                    if ((currentHour > 20f || currentHour < 4f))
                    {
                        if (_simulationManager.m_randomizer.Int32(80) < 2)
                        {
                            //Simulate 2 people buying things
                            int amount = -200;
                            thisAI.ModifyMaterialBuffer(buildingID, ref buildingData, TransferManager.TransferReason.Shopping, ref amount);
                        }
                    }
                    else if (Experiments.ExperimentsToggle.AllowActiveCommercialFix && _simulationManager.m_randomizer.Int32(40) < 5) //Added in as a potential fix to random inactive buildings. Lack of customers still shuts down commercial.
                    {
                        int amount = -50;
                        thisAI.ModifyMaterialBuffer(buildingID, ref buildingData, TransferManager.TransferReason.Shopping, ref amount);
                    }
                }
                else
                {
                    buildingData.m_incomingProblemTimer = 0;
                }

                //End edited section

                buildingData.m_problems = problems1;
                instance1.m_districts.m_buffer[(int)district].AddCommercialData(ref behaviour, health, happiness, crimeRate, workPlaceCount, aliveWorkerCount, Mathf.Max(0, workPlaceCount - totalWorkerCount), visitCount, aliveCount, num3, (int)thisAI.m_info.m_class.m_level, electricityConsumption, heatingConsumption, waterConsumption, sewageAccumulation, garbageAccumulation, incomeAccumulation, Mathf.Min(100, (int)buildingData.m_garbageBuffer / 50), (int)buildingData.m_waterPollution * 100 / (int)byte.MaxValue, (int)buildingData.m_finalImport, (int)buildingData.m_finalExport, thisAI.m_info.m_class.m_subService);
                if ((int)buildingData.m_fireIntensity == 0 && incomingTransferReason != TransferManager.TransferReason.None)
                {
                    int num5 = num4 - (int)buildingData.m_customBuffer1 - capacity - (num2 >> 1);
                    if (num5 >= 0)
                    {
                        Singleton <TransferManager> .instance.AddIncomingOffer(incomingTransferReason, new TransferManager.TransferOffer()
                        {
                            Priority = num5 * 8 / num2,
                            Building = buildingID,
                            Position = buildingData.m_position,
                            Amount   = 1,
                            Active   = false
                        });
                    }
                }
                if ((int)buildingData.m_fireIntensity == 0 && outgoingTransferReason != TransferManager.TransferReason.None)
                {
                    int num5 = (int)buildingData.m_customBuffer2 - aliveCount * 100;
                    if (num5 >= 100 && num3 > 0)
                    {
                        Singleton <TransferManager> .instance.AddOutgoingOffer(outgoingTransferReason, new TransferManager.TransferOffer()
                        {
                            Priority = Mathf.Max(1, num5 * 8 / num4),
                            Building = buildingID,
                            Position = buildingData.m_position,
                            Amount   = Mathf.Min(num5 / 100, num3),
                            Active   = false
                        });
                    }
                }

                PrivateBuildingAI baseAI = thisAI as PrivateBuildingAI; //Because we don't have access to base here.

                if (baseAI != null)
                {
                    NewPrivateBuildingAI.SimulationStepActive(baseAI, buildingID, ref buildingData, ref frameData);
                }

                HandleFire(thisAI, buildingID, ref buildingData, ref frameData, policies);
            }
            else
            {
                Debug.LogError("Commercial building " + buildingID + " has no AI! This could have been bad.");
            }
        }
Beispiel #21
0
        public void OriginalSimulationStep(ushort segmentID, ref NetSegment data)
        {
            if ((data.m_flags & NetSegment.Flags.Original) == NetSegment.Flags.None)
            {
                NetManager netManager = Singleton <NetManager> .instance;
                Vector3    pos        = netManager.m_nodes.m_buffer[(int)data.m_startNode].m_position;
                Vector3    pos2       = netManager.m_nodes.m_buffer[(int)data.m_endNode].m_position;
                int        n          = this.GetMaintenanceCost(pos, pos2);
                bool       f          = (ulong)(Singleton <SimulationManager> .instance.m_currentFrameIndex >> 8 & 15u) == (ulong)((long)(segmentID & 15));
                if (n != 0)
                {
                    if (f)
                    {
                        n = n * 16 / 100 - n / 100 * 15;
                    }
                    else
                    {
                        n /= 100;
                    }
                    Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.Maintenance, n, this.m_info.m_class);
                }
                if (f)
                {
                    float n2 = (float)netManager.m_nodes.m_buffer[(int)data.m_startNode].m_elevation;
                    float n3 = (float)netManager.m_nodes.m_buffer[(int)data.m_endNode].m_elevation;
                    if (this.IsUnderground())
                    {
                        n2 = -n2;
                        n3 = -n3;
                    }
                    int constructionCost = this.GetConstructionCost(pos, pos2, n2, n3);
                    if (constructionCost != 0)
                    {
                        StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt64>(StatisticType.CityValue);

                        if (statisticBase != null)
                        {
                            statisticBase.Add(constructionCost);
                        }
                    }
                }
            }

            SimulationManager instance  = Singleton <SimulationManager> .instance;
            NetManager        instance2 = Singleton <NetManager> .instance;

            Notification.Problem problem = Notification.RemoveProblems(data.m_problems, Notification.Problem.Flood | Notification.Problem.Snow);
            float num  = 0f;
            uint  num2 = data.m_lanes;
            int   num3 = 0;

            while (num3 < this.m_info.m_lanes.Length && num2 != 0u)
            {
                NetInfo.Lane lane = this.m_info.m_lanes[num3].ShallowClone();
                if ((byte)(lane.m_laneType & (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle)) != 0 && (lane.m_vehicleType & ~VehicleInfo.VehicleType.Bicycle) != VehicleInfo.VehicleType.None)
                {
                    num += instance2.m_lanes.m_buffer[(int)((UIntPtr)num2)].m_length;
                }
                num2 = instance2.m_lanes.m_buffer[(int)((UIntPtr)num2)].m_nextLane;
                num3++;
            }
            int num4 = 0;

            if (data.m_trafficBuffer == 65535)
            {
                if ((data.m_flags & NetSegment.Flags.Blocked) == NetSegment.Flags.None)
                {
                    data.m_flags        |= NetSegment.Flags.Blocked;
                    data.m_modifiedIndex = instance.m_currentBuildIndex++;
                }
            }
            else
            {
                data.m_flags &= ~NetSegment.Flags.Blocked;
                int num5 = Mathf.RoundToInt(num) << 4;
                if (num5 != 0)
                {
                    num4 = (int)((byte)Mathf.Min((int)(data.m_trafficBuffer * 100) / num5, 100));
                }
            }
            data.m_trafficBuffer = 0;
            if (num4 > (int)data.m_trafficDensity)
            {
                data.m_trafficDensity = (byte)Mathf.Min((int)(data.m_trafficDensity + 5), num4);
            }
            else if (num4 < (int)data.m_trafficDensity)
            {
                data.m_trafficDensity = (byte)Mathf.Max((int)(data.m_trafficDensity - 5), num4);
            }
            Vector3 position  = instance2.m_nodes.m_buffer[(int)data.m_startNode].m_position;
            Vector3 position2 = instance2.m_nodes.m_buffer[(int)data.m_endNode].m_position;
            Vector3 vector    = (position + position2) * 0.5f;
            bool    flag      = false;

            if ((this.m_info.m_setVehicleFlags & Vehicle.Flags.Underground) == 0)
            {
                float num6 = Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(vector));

                if (num6 > vector.y + 1f)
                {
                    flag          = true;
                    data.m_flags |= NetSegment.Flags.Flooded;
                    problem       = Notification.AddProblems(problem, Notification.Problem.Flood | Notification.Problem.MajorProblem);
                }
                else
                {
                    data.m_flags &= ~NetSegment.Flags.Flooded;
                    if (num6 > vector.y)
                    {
                        flag    = true;
                        problem = Notification.AddProblems(problem, Notification.Problem.Flood);
                    }
                }
            }
            DistrictManager instance3 = Singleton <DistrictManager> .instance;
            byte            district  = instance3.GetDistrict(vector);

            DistrictPolicies.CityPlanning cityPlanningPolicies = instance3.m_districts.m_buffer[(int)district].m_cityPlanningPolicies;
            int num7 = (int)(100 - (data.m_trafficDensity - 100) * (data.m_trafficDensity - 100) / 100);

            if ((this.m_info.m_vehicleTypes & VehicleInfo.VehicleType.Car) != VehicleInfo.VehicleType.None)
            {
                if ((this.m_info.m_setVehicleFlags & Vehicle.Flags.Underground) == 0)
                {
                    int num8 = (int)data.m_wetness;
                    if (!instance2.m_treatWetAsSnow)
                    {
                        if (flag)
                        {
                            num8 = 255;
                        }
                        else
                        {
                            int   num9  = -(num8 + 63 >> 5);
                            float num10 = Singleton <WeatherManager> .instance.SampleRainIntensity(vector, false);

                            if (num10 != 0f)
                            {
                                int num11 = Mathf.RoundToInt(Mathf.Min(num10 * 4000f, 1000f));
                                num9 += instance.m_randomizer.Int32(num11, num11 + 99) / 100;
                            }
                            num8 = Mathf.Clamp(num8 + num9, 0, 255);
                        }
                    }
                    else if (this.m_accumulateSnow)
                    {
                        if (flag)
                        {
                            num8 = 128;
                        }
                        else
                        {
                            float num12 = Singleton <WeatherManager> .instance.SampleRainIntensity(vector, false);

                            if (num12 != 0f)
                            {
                                int num13 = Mathf.RoundToInt(num12 * 400f);
                                int num14 = instance.m_randomizer.Int32(num13, num13 + 99) / 100;
                                if (Singleton <UnlockManager> .instance.Unlocked(UnlockManager.Feature.Snowplow))
                                {
                                    num8 = Mathf.Min(num8 + num14, 255);
                                }
                                else
                                {
                                    num8 = Mathf.Min(num8 + num14, 128);
                                }
                            }
                            else if (Singleton <SimulationManager> .instance.m_randomizer.Int32(4u) == 0)
                            {
                                num8 = Mathf.Max(num8 - 1, 0);
                            }
                            if (num8 >= 64 && (data.m_flags & (NetSegment.Flags.Blocked | NetSegment.Flags.Flooded)) == NetSegment.Flags.None && instance.m_randomizer.Int32(10u) == 0)
                            {
                                TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                                offer.Priority   = num8 / 50;
                                offer.NetSegment = segmentID;
                                offer.Position   = vector;
                                offer.Amount     = 1;
                                Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.Snow, offer);
                            }
                            if (num8 >= 192)
                            {
                                problem = Notification.AddProblems(problem, Notification.Problem.Snow);
                            }
                            District[] expr_4E2_cp_0_cp_0 = instance3.m_districts.m_buffer;
                            byte       expr_4E2_cp_0_cp_1 = district;
                            expr_4E2_cp_0_cp_0[(int)expr_4E2_cp_0_cp_1].m_productionData.m_tempSnowCover = expr_4E2_cp_0_cp_0[(int)expr_4E2_cp_0_cp_1].m_productionData.m_tempSnowCover + (uint)num8;
                        }
                    }
                    if (num8 != (int)data.m_wetness)
                    {
                        if (Mathf.Abs((int)data.m_wetness - num8) > 10)
                        {
                            data.m_wetness = (byte)num8;
                            InstanceID empty = InstanceID.Empty;
                            empty.NetSegment = segmentID;
                            instance2.AddSmoothColor(empty);
                            empty.NetNode = data.m_startNode;
                            instance2.AddSmoothColor(empty);
                            empty.NetNode = data.m_endNode;
                            instance2.AddSmoothColor(empty);
                        }
                        else
                        {
                            data.m_wetness             = (byte)num8;
                            instance2.m_wetnessChanged = 256;
                        }
                    }
                }
                int num15;
                if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.StuddedTires) != DistrictPolicies.CityPlanning.None)
                {
                    num7  = num7 * 3 + 1 >> 1;
                    num15 = Mathf.Min(700, (int)(50 + data.m_trafficDensity * 6));
                }
                else
                {
                    num15 = Mathf.Min(500, (int)(50 + data.m_trafficDensity * 4));
                }
                if (!this.m_highwayRules)
                {
                    int num16 = instance.m_randomizer.Int32(num15, num15 + 99) / 100;
                    data.m_condition = (byte)Mathf.Max((int)data.m_condition - num16, 0);
                    if (data.m_condition < 192 && (data.m_flags & (NetSegment.Flags.Blocked | NetSegment.Flags.Flooded)) == NetSegment.Flags.None && instance.m_randomizer.Int32(20u) == 0)
                    {
                        TransferManager.TransferOffer offer2 = default(TransferManager.TransferOffer);
                        offer2.Priority   = (int)((255 - data.m_condition) / 50);
                        offer2.NetSegment = segmentID;
                        offer2.Position   = vector;
                        offer2.Amount     = 1;
                        Singleton <TransferManager> .instance.AddIncomingOffer(TransferManager.TransferReason.RoadMaintenance, offer2);
                    }
                }
            }
            if (!this.m_highwayRules)
            {
                if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.HeavyTrafficBan) != DistrictPolicies.CityPlanning.None)
                {
                    data.m_flags |= NetSegment.Flags.HeavyBan;
                }
                else
                {
                    data.m_flags &= ~NetSegment.Flags.HeavyBan;
                }
                if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.BikeBan) != DistrictPolicies.CityPlanning.None)
                {
                    data.m_flags |= NetSegment.Flags.BikeBan;
                }
                else
                {
                    data.m_flags &= ~NetSegment.Flags.BikeBan;
                }
                if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.OldTown) != DistrictPolicies.CityPlanning.None)
                {
                    data.m_flags |= NetSegment.Flags.CarBan;
                }
                else
                {
                    data.m_flags &= ~NetSegment.Flags.CarBan;
                }
            }
            int num17 = this.m_noiseAccumulation * num7 / 100;

            if (num17 != 0)
            {
                float num18 = Vector3.Distance(position, position2);
                int   num19 = Mathf.FloorToInt(num18 / this.m_noiseRadius);
                for (int i = 0; i < num19; i++)
                {
                    Vector3 position3 = Vector3.Lerp(position, position2, (float)(i + 1) / (float)(num19 + 1));
                    Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, num17, position3, this.m_noiseRadius);
                }
            }
            if (data.m_trafficDensity >= 50 && data.m_averageLength < 25f && (instance2.m_nodes.m_buffer[(int)data.m_startNode].m_flags & (NetNode.Flags.LevelCrossing | NetNode.Flags.TrafficLights)) == NetNode.Flags.TrafficLights && (instance2.m_nodes.m_buffer[(int)data.m_endNode].m_flags & (NetNode.Flags.LevelCrossing | NetNode.Flags.TrafficLights)) == NetNode.Flags.TrafficLights)
            {
                GuideController properties = Singleton <GuideManager> .instance.m_properties;
                if (properties != null)
                {
                    Singleton <NetManager> .instance.m_shortRoadTraffic.Activate(properties.m_shortRoadTraffic, segmentID, false);
                }
            }
            data.m_problems = problem;
        }