Beispiel #1
0
        static bool Prefix(ref int __result, ushort instanceID, ref CitizenInstance citizenData, Citizen.AgeGroup ageGroup)
        {
            // Cache as best we can. The order of calls is car, bike, taxi
            AIUtils.citizenCache = citizenData.m_citizen;  // Not needed, but just in case

            Citizen citizen      = Singleton <CitizenManager> .instance.m_citizens.m_buffer[(int)((UIntPtr)citizenData.m_citizen)];
            ushort  homeBuilding = citizen.m_homeBuilding;

            ItemClass.SubService subService = ItemClass.SubService.ResidentialLow;
            if (homeBuilding != 0)
            {
                DistrictManager instance = Singleton <DistrictManager> .instance;
                Building        building = Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)homeBuilding];
                District        district = instance.m_districts.m_buffer[instance.GetDistrict(building.m_position)];
                DistrictPolicies.CityPlanning cityPlanningPolicies = district.m_cityPlanningPolicies;

                AIUtils.livesInBike = (cityPlanningPolicies & DistrictPolicies.CityPlanning.EncourageBiking) != DistrictPolicies.CityPlanning.None;
                subService          = Singleton <BuildingManager> .instance.m_buildings.m_buffer[homeBuilding].Info.GetSubService();
            }

            // Set the cache
            AIUtils.cacheArray = AIUtils.GetArray(citizen.WealthLevel, subService, ageGroup);

            // Original method return value.
            __result = AIUtils.cacheArray[DataStore.CAR];

            if (Debugging.UseTransportLog)
            {
                Debugging.WriteToLog(Debugging.TransportLogName, citizen.WealthLevel + "-wealth " + ageGroup + " has " + __result + "% chance of driving.");
            }

            // Don't execute base method after this.
            return(false);
        }
        public override void GetPollutionRates(int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution)
        {
            ItemClass @class = this.m_info.m_class;
            int       level  = (int)(@class.m_level >= 0 ? @class.m_level : 0); // Force it to 0 if the level was set to None

            groundPollution = DataStore.office[level][DataStore.GROUND_POLLUTION];
            noisePollution  = DataStore.office[level][DataStore.NOISE_POLLUTION];
        }
Beispiel #3
0
        public int CaculateLandFee(Building building, ushort buildingID)
        {
            DistrictManager instance = Singleton <DistrictManager> .instance;
            byte            district = instance.GetDistrict(building.m_position);

            DistrictPolicies.Services     servicePolicies      = instance.m_districts.m_buffer[district].m_servicePolicies;
            DistrictPolicies.Taxation     taxationPolicies     = instance.m_districts.m_buffer[district].m_taxationPolicies;
            DistrictPolicies.CityPlanning cityPlanningPolicies = instance.m_districts.m_buffer[district].m_cityPlanningPolicies;

            GetLandRent(building, out int landFee);
            float taxRate;

            taxRate = Singleton <EconomyManager> .instance.GetTaxRate(building.Info.m_class, taxationPolicies);

            if (instance.IsPolicyLoaded(DistrictPolicies.Policies.ExtraInsulation))
            {
                if ((servicePolicies & DistrictPolicies.Services.ExtraInsulation) != DistrictPolicies.Services.None)
                {
                    taxRate = taxRate * 95 / 100;
                }
            }
            if ((servicePolicies & DistrictPolicies.Services.Recycling) != DistrictPolicies.Services.None)
            {
                taxRate = taxRate * 95 / 100;
            }

            if (((taxationPolicies & DistrictPolicies.Taxation.DontTaxLeisure) != DistrictPolicies.Taxation.None) && (building.Info.m_class.m_subService == ItemClass.SubService.CommercialLeisure))
            {
                landFee = 0;
            }

            if (BuildingData.buildingMoney[buildingID] > 0)
            {
                if ((building.Info.m_class.m_service == ItemClass.Service.Commercial) || (building.Info.m_class.m_service == ItemClass.Service.Industrial))
                {
                    if (BuildingData.buildingMoney[buildingID] > (taxRate * landFee / 100f))
                    {
                        return((int)(taxRate * landFee / 100f));
                    }
                    else
                    {
                        return(0);
                    }
                }
                else if (building.Info.m_class.m_service == ItemClass.Service.Office)
                {
                    Citizen.BehaviourData behaviourData = default;
                    int aliveWorkerCount = 0;
                    int totalWorkerCount = 0;
                    RealCityCommonBuildingAI.InitDelegate();
                    RealCityCommonBuildingAI.GetWorkBehaviour((OfficeBuildingAI)building.Info.m_buildingAI, buildingID, ref building, ref behaviourData, ref aliveWorkerCount, ref totalWorkerCount);
                    return((int)(totalWorkerCount * taxRate / 10f));
                }
            }

            return(0);
        }
        public override void GetPollutionRates(int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution)
        {
            groundPollution = 0;
            noisePollution  = 0;
            int[] array = getArray(this.m_info, EXTRACT_LEVEL);

            groundPollution = (productionRate * array[DataStore.GROUND_POLLUTION]) / 100;
            noisePollution  = (productionRate * array[DataStore.NOISE_POLLUTION]) / 100;
        }
Beispiel #5
0
        public override void GetPollutionRates(int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution)
        {
            ItemClass @class = this.m_info.m_class;
            int       level  = (int)(@class.m_level >= 0 ? @class.m_level : 0); // Force it to 0 if the level was set to None

            int[] array = (@class.m_subService == ItemClass.SubService.ResidentialHigh) ? DataStore.residentialHigh[level] : DataStore.residentialLow[level];

            groundPollution = array[DataStore.GROUND_POLLUTION];
            noisePollution  = array[DataStore.NOISE_POLLUTION];
        }
        public override void SimulationStep(ushort buildingID, ref Building buildingData, ref Building.Frame frameData)
        {
            base.SimulationStep(buildingID, ref buildingData, ref frameData);
            SimulationManager instance  = Singleton <SimulationManager> .instance;
            DistrictManager   instance2 = Singleton <DistrictManager> .instance;
            byte district = instance2.GetDistrict(buildingData.m_position);

            DistrictPolicies.CityPlanning cityPlanningPolicies = instance2.m_districts.m_buffer[(int)district].m_cityPlanningPolicies;
            if ((buildingData.m_flags & (Building.Flags.Completed | Building.Flags.Upgrading)) != Building.Flags.None)
            {
                instance2.m_districts.m_buffer[(int)district].AddResidentialData(buildingData.Width * buildingData.Length, (buildingData.m_flags & Building.Flags.Abandoned) != Building.Flags.None, (buildingData.m_flags & Building.Flags.Collapsed) != Building.Flags.None && frameData.m_fireDamage == 255, (buildingData.m_flags & Building.Flags.Collapsed) != Building.Flags.None && frameData.m_fireDamage != 255, this.m_info.m_class.m_subService);
            }
            if ((buildingData.m_levelUpProgress == 255 || (buildingData.m_flags & Building.Flags.Collapsed) == Building.Flags.None) && buildingData.m_fireIntensity == 0)
            {
/*
 *              if ((this.m_info.m_class.m_subService == ItemClass.SubService.ResidentialHigh || this.m_info.m_class.m_subService == ItemClass.SubService.ResidentialHighEco) &&
 *                  (cityPlanningPolicies & DistrictPolicies.CityPlanning.HighriseBan) != DistrictPolicies.CityPlanning.None && this.m_info.m_class.m_level == ItemClass.Level.Level5 &&
 *                  instance.m_randomizer.Int32(10u) == 0 && Singleton<ZoneManager>.instance.m_lastBuildIndex == instance.m_currentBuildIndex)
 *              {
 *                  District[] expr_184_cp_0 = instance2.m_districts.m_buffer;
 *                  byte expr_184_cp_1 = district;
 *                  expr_184_cp_0[(int)expr_184_cp_1].m_cityPlanningPoliciesEffect = (expr_184_cp_0[(int)expr_184_cp_1].m_cityPlanningPoliciesEffect | DistrictPolicies.CityPlanning.HighriseBan);
 *                  buildingData.m_flags |= Building.Flags.Demolishing;
 *                  instance.m_currentBuildIndex += 1u;
 *              }
 */
                if (instance.m_randomizer.Int32(10u) == 0)
                {
                    DistrictPolicies.Specialization specializationPolicies = instance2.m_districts.m_buffer[(int)district].m_specializationPolicies;
                    DistrictPolicies.Specialization specialization         = this.SpecialPolicyNeeded();
                    if (specialization != DistrictPolicies.Specialization.None)
                    {
                        if ((specializationPolicies & specialization) == DistrictPolicies.Specialization.None)
                        {
                            if (Singleton <ZoneManager> .instance.m_lastBuildIndex == instance.m_currentBuildIndex)
                            {
                                buildingData.m_flags         |= Building.Flags.Demolishing;
                                instance.m_currentBuildIndex += 1u;
                            }
                        }
                        else
                        {
                            District[] expr_240_cp_0 = instance2.m_districts.m_buffer;
                            byte       expr_240_cp_1 = district;
                            expr_240_cp_0[(int)expr_240_cp_1].m_specializationPoliciesEffect = (expr_240_cp_0[(int)expr_240_cp_1].m_specializationPoliciesEffect | specialization);
                        }
                    }
                    else if ((specializationPolicies & DistrictPolicies.Specialization.Selfsufficient) != DistrictPolicies.Specialization.None && Singleton <ZoneManager> .instance.m_lastBuildIndex == instance.m_currentBuildIndex)
                    {
                        buildingData.m_flags         |= Building.Flags.Demolishing;
                        instance.m_currentBuildIndex += 1u;
                    }
                }
            }
        }
        public override void GetPollutionRates(int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution)
        {
            groundPollution = 0;
            noisePollution  = 0;

            if (!m_pollutionEnabled)
            {
                return;
            }

            base.GetPollutionRates(productionRate, cityPlanningPolicies, out groundPollution, out noisePollution);
        }
Beispiel #8
0
        public override void GetPollutionRates(int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution)
        {
            ItemClass @class = this.m_info.m_class;

            groundPollution = 0;
            noisePollution  = 0;
            int level = (int)(@class.m_level >= 0 ? @class.m_level : 0); // Force it to 0 if the level was set to None

            int[] array = getArray(this.m_info, level);

            groundPollution = (productionRate * array[DataStore.GROUND_POLLUTION]) / 100;
            noisePollution  = (productionRate * array[DataStore.NOISE_POLLUTION]) / 100;
        }
Beispiel #9
0
        public override void GetPollutionRates(int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution)
        {
            ItemClass item  = this.m_info.m_class;
            int       level = (int)(item.m_level >= 0 ? item.m_level : 0); // Force it to 0 if the level was set to None

            int[] array = GetArray(this.m_info, level);

            groundPollution = array[DataStore.GROUND_POLLUTION];
            noisePollution  = (productionRate * array[DataStore.NOISE_POLLUTION]) / 100;
            if (item.m_subService == ItemClass.SubService.CommercialLeisure)
            {
                if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.NoLoudNoises) != DistrictPolicies.CityPlanning.None)
                {
                    noisePollution /= 2;
                }
            }
        }
        private int GetBikeProbability(ushort instanceID, ref CitizenInstance citizenData, Citizen.AgeGroup ageGroup)
        {
            Log.Error("CustomResidentAI.GetBikeProbability called!");
            CitizenManager citizenManager    = Singleton <CitizenManager> .instance;
            uint           citizenId         = citizenData.m_citizen;
            ushort         homeId            = citizenManager.m_citizens.m_buffer[(int)((UIntPtr)citizenId)].m_homeBuilding;
            int            bikeEncouragement = 0;

            if (homeId != 0)
            {
                Vector3         position        = Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)homeId].m_position;
                DistrictManager districtManager = Singleton <DistrictManager> .instance;
                byte            district        = districtManager.GetDistrict(position);
                DistrictPolicies.CityPlanning cityPlanningPolicies = districtManager.m_districts.m_buffer[(int)district].m_cityPlanningPolicies;
                if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.EncourageBiking) != DistrictPolicies.CityPlanning.None)
                {
                    bikeEncouragement = 10;
                }
            }
            switch (ageGroup)
            {
            case Citizen.AgeGroup.Child:
                return(ResidentAI.BIKE_PROBABILITY_CHILD + bikeEncouragement);

            case Citizen.AgeGroup.Teen:
                return(ResidentAI.BIKE_PROBABILITY_TEEN + bikeEncouragement);

            case Citizen.AgeGroup.Young:
                return(ResidentAI.BIKE_PROBABILITY_YOUNG + bikeEncouragement);

            case Citizen.AgeGroup.Adult:
                return(ResidentAI.BIKE_PROBABILITY_ADULT + bikeEncouragement);

            case Citizen.AgeGroup.Senior:
                return(ResidentAI.BIKE_PROBABILITY_SENIOR + bikeEncouragement);

            default:
                return(0);
            }
        }
Beispiel #11
0
        public override BuildingInfo GetUpgradeInfo(ushort buildingID, ref Building data)
        {
            if (this.m_info.m_class.m_level == ItemClass.Level.Level5)
            {
                return(null);
            }
            Randomizer randomizer = new Randomizer((int)buildingID);

            for (int i = 0; i <= (int)this.m_info.m_class.m_level; i++)
            {
                randomizer.Int32(1000u);
            }
            ItemClass.Level level    = this.m_info.m_class.m_level + 1;
            DistrictManager instance = Singleton <DistrictManager> .instance;
            byte            district = instance.GetDistrict(data.m_position);

            DistrictPolicies.CityPlanning cityPlanningPolicies = instance.m_districts.m_buffer[(int)district].m_cityPlanningPolicies;
            highRiseBan = ((cityPlanningPolicies & DistrictPolicies.CityPlanning.HighriseBan) != DistrictPolicies.CityPlanning.None);
            ushort style = instance.m_districts.m_buffer[(int)district].m_Style;

            return(Singleton <BuildingManager> .instance.GetRandomBuildingInfo(ref randomizer, this.m_info.m_class.m_service, this.m_info.m_class.m_subService, level, data.Width, data.Length, this.m_info.m_zoningMode, (int)style));
        }
        static bool Prefix(CommercialBuildingAI __instance, ItemClass.Level level, int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution)
        {
            ItemClass item = __instance.m_info.m_class;

            int[] array = CommercialBuildingAIMod.GetArray(__instance.m_info, (int)level);

            groundPollution = array[DataStore.GROUND_POLLUTION];
            noisePollution  = (productionRate * array[DataStore.NOISE_POLLUTION]) / 100;
            if (item.m_subService == ItemClass.SubService.CommercialLeisure)
            {
                if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.NoLoudNoises) != DistrictPolicies.CityPlanning.None)
                {
                    noisePollution /= 2;
                }
            }

            // Don't execute base method after this.
            return(false);
        }
Beispiel #13
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;
        }
Beispiel #14
0
        public void CustomCalculateSegmentPositionPathFinder(ushort vehicleId, ref Vehicle vehicleData, PathUnit.Position position, uint laneId, byte offset, out Vector3 pos, out Vector3 dir, out float maxSpeed)
        {
            var netManager = Singleton <NetManager> .instance;

            netManager.m_lanes.m_buffer[laneId].CalculatePositionAndDirection(offset * 0.003921569f, out pos, out dir);
            var segmentInfo = netManager.m_segments.m_buffer[position.m_segment].Info;

            if (segmentInfo.m_lanes != null && segmentInfo.m_lanes.Length > position.m_lane)
            {
                // NON-STOCK CODE START
                float laneSpeedLimit = 1f;
#if BENCHMARK
                using (var bm = new Benchmark(null, "GetLockFreeGameSpeedLimit")) {
#endif
                if (!Options.customSpeedLimitsEnabled)
                {
                    laneSpeedLimit = segmentInfo.m_lanes[position.m_lane].m_speedLimit;
                }
                else
                {
                    // === START INLINED VERSION OF SpeedLimitManager.GetLockFreeGameSpeedLimit ===
                    ushort?[] fastArray = Flags.laneSpeedLimitArray[position.m_segment];
                    if (fastArray != null && fastArray.Length > position.m_lane && fastArray[position.m_lane] != null)
                    {
                        // === START INLINED VERSION OF SpeedLimitManager.ToGameSpeedLimit ===
                        laneSpeedLimit = (float)fastArray[position.m_lane];
                        if (laneSpeedLimit == 0)
                        {
                            laneSpeedLimit = SpeedLimitManager.MAX_SPEED;
                        }
                        else
                        {
                            laneSpeedLimit = laneSpeedLimit / 50f;
                        }
                        // === END INLINED VERSION OF SpeedLimitManager.ToGameSpeedLimit ===
                        // laneSpeedLimit = ToGameSpeedLimit((ushort)fastArray[position.m_lane]);
                    }
                    else
                    {
                        laneSpeedLimit = segmentInfo.m_lanes[position.m_lane].m_speedLimit;
                    }
                    // === END INLINED VERSION OF SpeedLimitManager.GetLockFreeGameSpeedLimit ===
                    //laneSpeedLimit = SpeedLimitManager.Instance.GetLockFreeGameSpeedLimit(position.m_segment, position.m_lane, laneID, segmentInfo.m_lanes[position.m_lane]); // info2.m_lanes[position.m_lane].m_speedLimit; // NON-STOCK CODE
                }
                //laneSpeedLimit = Options.customSpeedLimitsEnabled ? SpeedLimitManager.Instance.GetLockFreeGameSpeedLimit(position.m_segment, position.m_lane, laneId, info.m_lanes[position.m_lane]) : info.m_lanes[position.m_lane].m_speedLimit; // NON-STOCK CODE
#if BENCHMARK
            }
#endif
                // NON-STOCK CODE END
                maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, laneSpeedLimit, netManager.m_lanes.m_buffer[laneId].m_curve);
            }
            else
            {
                maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, 1f, 0f);
            }

            // NON-STOCK CODE START (stock code replaced)
            bool isRecklessDriver = VehicleStateManager.Instance.VehicleStates[vehicleId].recklessDriver;
#if BENCHMARK
            using (var bm = new Benchmark(null, "CalcMaxSpeed")) {
#endif
            // === START INLINED VERSION OF VehicleBehaviorManager.CalcMaxSpeed ===
            if (Singleton <NetManager> .instance.m_treatWetAsSnow)
            {
                DistrictManager districtManager = Singleton <DistrictManager> .instance;
                byte district = districtManager.GetDistrict(pos);
                DistrictPolicies.CityPlanning cityPlanningPolicies = districtManager.m_districts.m_buffer[(int)district].m_cityPlanningPolicies;
                if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.StuddedTires) != DistrictPolicies.CityPlanning.None)
                {
                    if (Options.strongerRoadConditionEffects)
                    {
                        if (maxSpeed > VehicleBehaviorManager.ICY_ROADS_STUDDED_MIN_SPEED)
                        {
                            maxSpeed = VehicleBehaviorManager.ICY_ROADS_STUDDED_MIN_SPEED + (float)(255 - netManager.m_segments.m_buffer[position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - VehicleBehaviorManager.ICY_ROADS_STUDDED_MIN_SPEED);
                        }
                    }
                    else
                    {
                        maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[position.m_segment].m_wetness * 0.0005882353f;                                 // vanilla: -15% .. ±0%
                    }
                    districtManager.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= DistrictPolicies.CityPlanning.StuddedTires;
                }
                else
                {
                    if (Options.strongerRoadConditionEffects)
                    {
                        if (maxSpeed > VehicleBehaviorManager.ICY_ROADS_MIN_SPEED)
                        {
                            maxSpeed = VehicleBehaviorManager.ICY_ROADS_MIN_SPEED + (float)(255 - netManager.m_segments.m_buffer[position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - VehicleBehaviorManager.ICY_ROADS_MIN_SPEED);
                        }
                    }
                    else
                    {
                        maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[position.m_segment].m_wetness * 0.00117647066f;                                 // vanilla: -30% .. ±0%
                    }
                }
            }
            else
            {
                if (Options.strongerRoadConditionEffects)
                {
                    float minSpeed = Math.Min(maxSpeed * VehicleBehaviorManager.WET_ROADS_FACTOR, VehicleBehaviorManager.WET_ROADS_MAX_SPEED);                             // custom: -25% .. 0
                    if (maxSpeed > minSpeed)
                    {
                        maxSpeed = minSpeed + (float)(255 - netManager.m_segments.m_buffer[position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - minSpeed);
                    }
                }
                else
                {
                    maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[position.m_segment].m_wetness * 0.0005882353f;                             // vanilla: -15% .. ±0%
                }
            }

            if (Options.strongerRoadConditionEffects)
            {
                float minSpeed = Math.Min(maxSpeed * VehicleBehaviorManager.BROKEN_ROADS_FACTOR, VehicleBehaviorManager.BROKEN_ROADS_MAX_SPEED);
                if (maxSpeed > minSpeed)
                {
                    maxSpeed = minSpeed + (float)netManager.m_segments.m_buffer[position.m_segment].m_condition * 0.0039215686f * (maxSpeed - minSpeed);
                }
            }
            else
            {
                maxSpeed *= 1f + (float)netManager.m_segments.m_buffer[position.m_segment].m_condition * 0.0005882353f;                         // vanilla: ±0% .. +15 %
            }

            // === START INLINED VERSION OF VehicleBehaviorManager.ApplyRealisticSpeeds ===
            if (Options.realisticSpeeds)
            {
                // === START INLINED VERSION OF VehicleBehaviorManager.ApplyRealisticSpeeds ===
                float vehicleRand = 0.01f * (float)(vehicleId % 100);
                // float vehicleRand = 0.01f * (float)GetVehicleRand(vehicleId);
                // === END INLINED VERSION OF VehicleBehaviorManager.ApplyRealisticSpeeds ===
                if (this.m_info.m_isLargeVehicle)
                {
                    maxSpeed *= 0.9f + vehicleRand * 0.1f;                             // a little variance, 0.9 .. 1
                }
                else if (isRecklessDriver)
                {
                    maxSpeed *= 1.3f + vehicleRand * 1.7f;                             // woohooo, 1.3 .. 3
                }
                else
                {
                    maxSpeed *= 0.8f + vehicleRand * 0.5f;                             // a little variance, 0.8 .. 1.3
                }
            }
            else if (isRecklessDriver)
            {
                maxSpeed *= 1.5f;
            }
            // === END INLINED VERSION OF VehicleBehaviorManager.ApplyRealisticSpeeds ===

            //maxSpeed = ApplyRealisticSpeeds(maxSpeed, vehicleId, this.m_info, isRecklessDriver);
            maxSpeed = Math.Max(VehicleBehaviorManager.MIN_SPEED, maxSpeed);                     // at least 10 km/h
            // === END INLINED VERSION OF VehicleBehaviorManager.CalcMaxSpeed ===
            //maxSpeed = VehicleBehaviorManager.Instance.CalcMaxSpeed(vehicleId, this.m_info, position, ref netManager.m_segments.m_buffer[position.m_segment], pos, maxSpeed, isRecklessDriver);
#if BENCHMARK
        }
#endif
            // NON-STOCK CODE END
        }
Beispiel #15
0
        public void CustomCalculateSegmentPosition(ushort vehicleId, ref Vehicle vehicleData, PathUnit.Position nextPosition,
                                                   PathUnit.Position position, uint laneID, byte offset, PathUnit.Position prevPos, uint prevLaneID,
                                                   byte prevOffset, int index, out Vector3 pos, out Vector3 dir, out float maxSpeed)
        {
            var netManager = Singleton <NetManager> .instance;
            ushort targetNodeId;
            ushort nextTargetNodeId;

            if (offset < position.m_offset)
            {
                targetNodeId     = netManager.m_segments.m_buffer[position.m_segment].m_startNode;
                nextTargetNodeId = netManager.m_segments.m_buffer[position.m_segment].m_endNode;
            }
            else
            {
                targetNodeId     = netManager.m_segments.m_buffer[position.m_segment].m_endNode;
                nextTargetNodeId = netManager.m_segments.m_buffer[position.m_segment].m_startNode;
            }
            var prevTargetNodeId = prevOffset == 0 ? netManager.m_segments.m_buffer[prevPos.m_segment].m_startNode : netManager.m_segments.m_buffer[prevPos.m_segment].m_endNode;

            Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData();
            Vector3 lastFrameVehiclePos = lastFrameData.m_position;
            float sqrVelocity           = lastFrameData.m_velocity.sqrMagnitude;

            netManager.m_lanes.m_buffer[laneID].CalculatePositionAndDirection(offset * 0.003921569f, out pos, out dir);

            float braking = this.m_info.m_braking;

            if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) != (Vehicle.Flags) 0)
            {
                braking *= 2f;
            }

            // car position on the Bezier curve of the lane
            var vehiclePosOnBezier = netManager.m_lanes.m_buffer[prevLaneID].CalculatePosition(prevOffset * 0.003921569f);
            //ushort currentSegmentId = netManager.m_lanes.m_buffer[prevLaneID].m_segment;

            // this seems to be like the required braking force in order to stop the vehicle within its half length.
            var crazyValue             = 0.5f * sqrVelocity / braking + m_info.m_generatedInfo.m_size.z * 0.5f;
            bool withinBrakingDistance = Vector3.Distance(lastFrameVehiclePos, vehiclePosOnBezier) >= crazyValue - 1f;

            // NON-STOCK CODE START
#if BENCHMARK
            using (var bm = new Benchmark(null, "UpdateVehiclePosition")) {
#endif
            VehicleStateManager.Instance.UpdateVehiclePosition(vehicleId, ref vehicleData, lastFrameData.m_velocity.magnitude);
#if BENCHMARK
        }
#endif
            // NON-STOCK CODE END

            bool isRecklessDriver = VehicleStateManager.Instance.VehicleStates[vehicleId].recklessDriver;
            if (targetNodeId == prevTargetNodeId && withinBrakingDistance)
            {
                // NON-STOCK CODE START (stock code replaced)
#if BENCHMARK
                using (var bm = new Benchmark(null, "MayChangeSegment")) {
#endif
                //bool isRecklessDriver = VehicleStateManager.Instance.IsRecklessDriver(vehicleId, ref vehicleData); // NON-STOCK CODE

                if (!VehicleBehaviorManager.Instance.MayChangeSegment(vehicleId, ref VehicleStateManager.Instance.VehicleStates[vehicleId], ref vehicleData, sqrVelocity, isRecklessDriver, ref prevPos, ref netManager.m_segments.m_buffer[prevPos.m_segment], prevTargetNodeId, prevLaneID, ref position, targetNodeId, ref netManager.m_nodes.m_buffer[targetNodeId], laneID, ref nextPosition, nextTargetNodeId, out maxSpeed))                         // NON-STOCK CODE
                {
                    return;
                }
#if BENCHMARK
            }
#endif
                // NON-STOCK CODE END
            }

            var segmentInfo = netManager.m_segments.m_buffer[position.m_segment].Info;
            if (segmentInfo.m_lanes != null && segmentInfo.m_lanes.Length > position.m_lane)
            {
                // NON-STOCK CODE START
                // NON-STOCK CODE START
                float laneSpeedLimit = 1f;
#if BENCHMARK
                using (var bm = new Benchmark(null, "GetLockFreeGameSpeedLimit")) {
#endif
                if (!Options.customSpeedLimitsEnabled)
                {
                    laneSpeedLimit = segmentInfo.m_lanes[position.m_lane].m_speedLimit;
                }
                else
                {
                    // === START INLINED VERSION OF SpeedLimitManager.GetLockFreeGameSpeedLimit ===
                    ushort?[] fastArray = Flags.laneSpeedLimitArray[position.m_segment];
                    if (fastArray != null && fastArray.Length > position.m_lane && fastArray[position.m_lane] != null)
                    {
                        // === START INLINED VERSION OF SpeedLimitManager.ToGameSpeedLimit ===
                        laneSpeedLimit = (float)fastArray[position.m_lane];
                        if (laneSpeedLimit == 0)
                        {
                            laneSpeedLimit = SpeedLimitManager.MAX_SPEED;
                        }
                        else
                        {
                            laneSpeedLimit = laneSpeedLimit / 50f;
                        }
                        // === END INLINED VERSION OF SpeedLimitManager.ToGameSpeedLimit ===
                        // laneSpeedLimit = ToGameSpeedLimit((ushort)fastArray[position.m_lane]);
                    }
                    else
                    {
                        laneSpeedLimit = segmentInfo.m_lanes[position.m_lane].m_speedLimit;
                    }
                    // === END INLINED VERSION OF SpeedLimitManager.GetLockFreeGameSpeedLimit ===
                    //laneSpeedLimit = SpeedLimitManager.Instance.GetLockFreeGameSpeedLimit(position.m_segment, position.m_lane, laneID, segmentInfo.m_lanes[position.m_lane]); // info2.m_lanes[position.m_lane].m_speedLimit; // NON-STOCK CODE
                }
#if BENCHMARK
            }
#endif
                // NON-STOCK CODE END
                maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, laneSpeedLimit, netManager.m_lanes.m_buffer[laneID].m_curve);
            }
            else
            {
                maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, 1f, 0f);
            }

            // NON-STOCK CODE START (stock code replaced)
#if BENCHMARK
            using (var bm = new Benchmark(null, "CalcMaxSpeed")) {
#endif
            // === START INLINED VERSION OF VehicleBehaviorManager.CalcMaxSpeed ===
            if (Singleton <NetManager> .instance.m_treatWetAsSnow)
            {
                DistrictManager districtManager = Singleton <DistrictManager> .instance;
                byte district = districtManager.GetDistrict(pos);
                DistrictPolicies.CityPlanning cityPlanningPolicies = districtManager.m_districts.m_buffer[(int)district].m_cityPlanningPolicies;
                if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.StuddedTires) != DistrictPolicies.CityPlanning.None)
                {
                    if (Options.strongerRoadConditionEffects)
                    {
                        if (maxSpeed > VehicleBehaviorManager.ICY_ROADS_STUDDED_MIN_SPEED)
                        {
                            maxSpeed = VehicleBehaviorManager.ICY_ROADS_STUDDED_MIN_SPEED + (float)(255 - netManager.m_segments.m_buffer[position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - VehicleBehaviorManager.ICY_ROADS_STUDDED_MIN_SPEED);
                        }
                    }
                    else
                    {
                        maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[position.m_segment].m_wetness * 0.0005882353f;                                 // vanilla: -15% .. ±0%
                    }
                    districtManager.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= DistrictPolicies.CityPlanning.StuddedTires;
                }
                else
                {
                    if (Options.strongerRoadConditionEffects)
                    {
                        if (maxSpeed > VehicleBehaviorManager.ICY_ROADS_MIN_SPEED)
                        {
                            maxSpeed = VehicleBehaviorManager.ICY_ROADS_MIN_SPEED + (float)(255 - netManager.m_segments.m_buffer[position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - VehicleBehaviorManager.ICY_ROADS_MIN_SPEED);
                        }
                    }
                    else
                    {
                        maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[position.m_segment].m_wetness * 0.00117647066f;                                 // vanilla: -30% .. ±0%
                    }
                }
            }
            else
            {
                if (Options.strongerRoadConditionEffects)
                {
                    float minSpeed = Math.Min(maxSpeed * VehicleBehaviorManager.WET_ROADS_FACTOR, VehicleBehaviorManager.WET_ROADS_MAX_SPEED);                             // custom: -25% .. 0
                    if (maxSpeed > minSpeed)
                    {
                        maxSpeed = minSpeed + (float)(255 - netManager.m_segments.m_buffer[position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - minSpeed);
                    }
                }
                else
                {
                    maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[position.m_segment].m_wetness * 0.0005882353f;                             // vanilla: -15% .. ±0%
                }
            }

            if (Options.strongerRoadConditionEffects)
            {
                float minSpeed = Math.Min(maxSpeed * VehicleBehaviorManager.BROKEN_ROADS_FACTOR, VehicleBehaviorManager.BROKEN_ROADS_MAX_SPEED);
                if (maxSpeed > minSpeed)
                {
                    maxSpeed = minSpeed + (float)netManager.m_segments.m_buffer[position.m_segment].m_condition * 0.0039215686f * (maxSpeed - minSpeed);
                }
            }
            else
            {
                maxSpeed *= 1f + (float)netManager.m_segments.m_buffer[position.m_segment].m_condition * 0.0005882353f;                         // vanilla: ±0% .. +15 %
            }

            // === START INLINED VERSION OF VehicleBehaviorManager.ApplyRealisticSpeeds ===
            if (Options.realisticSpeeds)
            {
                // === START INLINED VERSION OF VehicleBehaviorManager.ApplyRealisticSpeeds ===
                float vehicleRand = 0.01f * (float)(vehicleId % 100);
                // float vehicleRand = 0.01f * (float)GetVehicleRand(vehicleId);
                // === END INLINED VERSION OF VehicleBehaviorManager.ApplyRealisticSpeeds ===
                if (this.m_info.m_isLargeVehicle)
                {
                    maxSpeed *= 0.9f + vehicleRand * 0.1f;                             // a little variance, 0.9 .. 1
                }
                else if (isRecklessDriver)
                {
                    maxSpeed *= 1.3f + vehicleRand * 1.7f;                             // woohooo, 1.3 .. 3
                }
                else
                {
                    maxSpeed *= 0.8f + vehicleRand * 0.5f;                             // a little variance, 0.8 .. 1.3
                }
            }
            else if (isRecklessDriver)
            {
                maxSpeed *= 1.5f;
            }
            // === END INLINED VERSION OF VehicleBehaviorManager.ApplyRealisticSpeeds ===

            //maxSpeed = ApplyRealisticSpeeds(maxSpeed, vehicleId, this.m_info, isRecklessDriver);
            maxSpeed = Math.Max(VehicleBehaviorManager.MIN_SPEED, maxSpeed);                     // at least 10 km/h
            // === END INLINED VERSION OF VehicleBehaviorManager.CalcMaxSpeed ===
            //maxSpeed = VehicleBehaviorManager.Instance.CalcMaxSpeed(vehicleId, this.m_info, position, ref netManager.m_segments.m_buffer[position.m_segment], pos, maxSpeed, isRecklessDriver);
#if BENCHMARK
        }
#endif
            // NON-STOCK CODE END
        }
        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);
        }
Beispiel #17
0
        static bool Prefix(IndustrialBuildingAI __instance, ItemClass.Level level, int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution)
        {
            ItemClass @class = __instance.m_info.m_class;

            groundPollution = 0;
            noisePollution  = 0;
            int[] array = IndustrialBuildingAIMod.GetArray(__instance.m_info, (int)level);

            groundPollution = (productionRate * array[DataStore.GROUND_POLLUTION]) / 100;
            noisePollution  = (productionRate * array[DataStore.NOISE_POLLUTION]) / 100;

            // Don't execute base method after this.
            return(false);
        }
Beispiel #18
0
        protected override void CalculateSegmentPosition(ushort vehicleID, ref Vehicle vehicleData, PathUnit.Position nextPosition, PathUnit.Position position, uint laneID, byte offset, PathUnit.Position prevPos, uint prevLaneID, byte prevOffset, int index, out Vector3 pos, out Vector3 dir, out float maxSpeed)
        {
            NetManager instance = Singleton <NetManager> .instance;

            instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CalculatePositionAndDirection((float)offset * 0.003921569f, out pos, out dir);
            Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData();
            Vector3       position2     = lastFrameData.m_position;
            Vector3       b             = instance.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].CalculatePosition((float)prevOffset * 0.003921569f);
            float         num           = 0.5f * lastFrameData.m_velocity.sqrMagnitude / this.m_info.m_braking + this.m_info.m_generatedInfo.m_size.z * 0.5f;

            if (Vector3.Distance(position2, b) >= num - 1f)
            {
                Segment3 segment;
                segment.a = pos;
                ushort num2;
                ushort num3;
                if (offset < position.m_offset)
                {
                    segment.b = pos + dir.normalized * this.m_info.m_generatedInfo.m_size.z;
                    num2      = instance.m_segments.m_buffer[(int)position.m_segment].m_startNode;
                    num3      = instance.m_segments.m_buffer[(int)position.m_segment].m_endNode;
                }
                else
                {
                    segment.b = pos - dir.normalized * this.m_info.m_generatedInfo.m_size.z;
                    num2      = instance.m_segments.m_buffer[(int)position.m_segment].m_endNode;
                    num3      = instance.m_segments.m_buffer[(int)position.m_segment].m_startNode;
                }
                ushort num4;
                if (prevOffset == 0)
                {
                    num4 = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_startNode;
                }
                else
                {
                    num4 = instance.m_segments.m_buffer[(int)prevPos.m_segment].m_endNode;
                }
                if (num2 == num4)
                {
                    NetNode.Flags flags  = instance.m_nodes.m_buffer[(int)num2].m_flags;
                    NetLane.Flags flags2 = (NetLane.Flags)instance.m_lanes.m_buffer[(int)((UIntPtr)prevLaneID)].m_flags;
                    bool          flag   = (flags & NetNode.Flags.TrafficLights) != NetNode.Flags.None;
                    bool          flag2  = (flags & NetNode.Flags.LevelCrossing) != NetNode.Flags.None;
                    bool          flag3  = (flags2 & NetLane.Flags.JoinedJunction) != NetLane.Flags.None;
                    if ((flags & (NetNode.Flags.Junction | NetNode.Flags.OneWayOut | NetNode.Flags.OneWayIn)) == NetNode.Flags.Junction && instance.m_nodes.m_buffer[(int)num2].CountSegments() != 2)
                    {
                        float len = vehicleData.CalculateTotalLength(vehicleID) + 2f;
                        if (!instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].CheckSpace(len))
                        {
                            bool flag4 = false;
                            if (nextPosition.m_segment != 0 && instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_length < 30f)
                            {
                                NetNode.Flags flags3 = instance.m_nodes.m_buffer[(int)num3].m_flags;
                                if ((flags3 & (NetNode.Flags.Junction | NetNode.Flags.OneWayOut | NetNode.Flags.OneWayIn)) != NetNode.Flags.Junction || instance.m_nodes.m_buffer[(int)num3].CountSegments() == 2)
                                {
                                    uint laneID2 = PathManager.GetLaneID(nextPosition);
                                    if (laneID2 != 0u)
                                    {
                                        flag4 = instance.m_lanes.m_buffer[(int)((UIntPtr)laneID2)].CheckSpace(len);
                                    }
                                }
                            }
                            if (!flag4)
                            {
                                maxSpeed = 0f;
                                return;
                            }
                        }
                    }
                    if (flag && (!flag3 || flag2))
                    {
                        uint    currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                        uint    num5 = (uint)(((int)num4 << 8) / 32768);
                        uint    num6 = currentFrameIndex - num5 & 255u;
                        NetInfo info = instance.m_nodes.m_buffer[(int)num2].Info;
                        RoadBaseAI.TrafficLightState vehicleLightState;
                        RoadBaseAI.TrafficLightState pedestrianLightState;
                        bool flag5;
                        bool pedestrians;
                        RoadBaseAI.GetTrafficLightState(num4, ref instance.m_segments.m_buffer[(int)prevPos.m_segment], currentFrameIndex - num5, out vehicleLightState, out pedestrianLightState, out flag5, out pedestrians);
                        if (!flag5 && num6 >= 196u)
                        {
                            flag5 = true;
                            RoadBaseAI.SetTrafficLightState(num4, ref instance.m_segments.m_buffer[(int)prevPos.m_segment], currentFrameIndex - num5, vehicleLightState, pedestrianLightState, flag5, pedestrians);
                        }
                        if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) == 0 || info.m_class.m_service != ItemClass.Service.Road)
                        {
                            switch (vehicleLightState)
                            {
                            case RoadBaseAI.TrafficLightState.RedToGreen:
                                if (num6 < 60u)
                                {
                                    maxSpeed = 0f;
                                    return;
                                }
                                break;

                            case RoadBaseAI.TrafficLightState.Red:
                                maxSpeed = 0f;
                                return;

                            case RoadBaseAI.TrafficLightState.GreenToRed:
                                if (num6 >= 30u)
                                {
                                    maxSpeed = 0f;
                                    return;
                                }
                                break;
                            }
                        }
                    }
                }
            }
            NetInfo info2 = instance.m_segments.m_buffer[(int)position.m_segment].Info;

            if (info2.m_lanes != null && info2.m_lanes.Length > (int)position.m_lane)
            {
                maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, LaneManager.GetLaneSpeed(laneID, info2.m_lanes[(int)position.m_lane]), instance.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_curve);
            }
            else
            {
                maxSpeed = this.CalculateTargetSpeed(vehicleID, ref vehicleData, 1f, 0f);
            }
            if (instance.m_treatWetAsSnow)
            {
                DistrictManager instance2 = Singleton <DistrictManager> .instance;
                byte            district  = instance2.GetDistrict(pos);
                DistrictPolicies.CityPlanning cityPlanningPolicies = instance2.m_districts.m_buffer[(int)district].m_cityPlanningPolicies;
                if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.StuddedTires) != DistrictPolicies.CityPlanning.None)
                {
                    maxSpeed *= 1f - (float)instance.m_segments.m_buffer[(int)position.m_segment].m_wetness * 0.0005882353f;
                    District[] expr_5C2_cp_0 = instance2.m_districts.m_buffer;
                    byte       expr_5C2_cp_1 = district;
                    expr_5C2_cp_0[(int)expr_5C2_cp_1].m_cityPlanningPoliciesEffect = (expr_5C2_cp_0[(int)expr_5C2_cp_1].m_cityPlanningPoliciesEffect | DistrictPolicies.CityPlanning.StuddedTires);
                }
                else
                {
                    maxSpeed *= 1f - (float)instance.m_segments.m_buffer[(int)position.m_segment].m_wetness * 0.00117647066f;
                }
            }
            else
            {
                maxSpeed *= 1f - (float)instance.m_segments.m_buffer[(int)position.m_segment].m_wetness * 0.0005882353f;
            }
            maxSpeed *= 1f + (float)instance.m_segments.m_buffer[(int)position.m_segment].m_condition * 0.0005882353f;
        }
Beispiel #19
0
        internal static float CalcMaxSpeed(ushort vehicleId, ref Vehicle vehicleData, PathUnit.Position position, Vector3 pos, float maxSpeed, bool isRecklessDriver)
        {
            var     netManager   = Singleton <NetManager> .instance;
            NetInfo segmentInfo  = netManager.m_segments.m_buffer[(int)position.m_segment].Info;
            bool    highwayRules = (segmentInfo.m_netAI is RoadBaseAI && ((RoadBaseAI)segmentInfo.m_netAI).m_highwayRules);

            if (!highwayRules)
            {
                if (netManager.m_treatWetAsSnow)
                {
                    DistrictManager districtManager = Singleton <DistrictManager> .instance;
                    byte            district        = districtManager.GetDistrict(pos);
                    DistrictPolicies.CityPlanning cityPlanningPolicies = districtManager.m_districts.m_buffer[(int)district].m_cityPlanningPolicies;
                    if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.StuddedTires) != DistrictPolicies.CityPlanning.None)
                    {
                        if (Options.strongerRoadConditionEffects)
                        {
                            if (maxSpeed > ICY_ROADS_STUDDED_MIN_SPEED)
                            {
                                maxSpeed = ICY_ROADS_STUDDED_MIN_SPEED + (float)(255 - netManager.m_segments.m_buffer[(int)position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - ICY_ROADS_STUDDED_MIN_SPEED);
                            }
                        }
                        else
                        {
                            maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[(int)position.m_segment].m_wetness * 0.0005882353f;                             // vanilla: -15% .. �
                        }
                        districtManager.m_districts.m_buffer[(int)district].m_cityPlanningPoliciesEffect |= DistrictPolicies.CityPlanning.StuddedTires;
                    }
                    else
                    {
                        if (Options.strongerRoadConditionEffects)
                        {
                            if (maxSpeed > ICY_ROADS_MIN_SPEED)
                            {
                                maxSpeed = ICY_ROADS_MIN_SPEED + (float)(255 - netManager.m_segments.m_buffer[(int)position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - ICY_ROADS_MIN_SPEED);
                            }
                        }
                        else
                        {
                            maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[(int)position.m_segment].m_wetness * 0.00117647066f;                             // vanilla: -30% .. �
                        }
                    }
                }
                else
                {
                    if (Options.strongerRoadConditionEffects)
                    {
                        float minSpeed = Math.Min(maxSpeed * WET_ROADS_FACTOR, WET_ROADS_MAX_SPEED);
                        if (maxSpeed > minSpeed)
                        {
                            maxSpeed = minSpeed + (float)(255 - netManager.m_segments.m_buffer[(int)position.m_segment].m_wetness) * 0.0039215686f * (maxSpeed - minSpeed);
                        }
                    }
                    else
                    {
                        maxSpeed *= 1f - (float)netManager.m_segments.m_buffer[(int)position.m_segment].m_wetness * 0.0005882353f;                         // vanilla: -15% .. �
                    }
                }

                if (Options.strongerRoadConditionEffects)
                {
                    float minSpeed = Math.Min(maxSpeed * BROKEN_ROADS_FACTOR, BROKEN_ROADS_MAX_SPEED);
                    if (maxSpeed > minSpeed)
                    {
                        maxSpeed = minSpeed + (float)netManager.m_segments.m_buffer[(int)position.m_segment].m_condition * 0.0039215686f * (maxSpeed - minSpeed);
                    }
                }
                else
                {
                    maxSpeed *= 1f + (float)netManager.m_segments.m_buffer[(int)position.m_segment].m_condition * 0.0005882353f;                     // vanilla: � .. +15 %
                }
            }

            ExtVehicleType?vehicleType = CustomVehicleAI.DetermineVehicleTypeFromVehicle(vehicleId, ref vehicleData);
            float          vehicleRand = Math.Min(1f, (float)(vehicleId % 101) * 0.01f);    // we choose 101 because it's a prime number

            if (isRecklessDriver)
            {
                maxSpeed *= 1.5f + vehicleRand * 1.5f;                 // woohooo, 1.5 .. 3
            }
            else if ((vehicleType & ExtVehicleType.PassengerCar) != ExtVehicleType.None)
            {
                maxSpeed *= 0.8f + vehicleRand * 0.3f;                 // a little variance, 0.8 .. 1.1
            }
            else if ((vehicleType & ExtVehicleType.Taxi) != ExtVehicleType.None)
            {
                maxSpeed *= 0.9f + vehicleRand * 0.4f;            // a little variance, 0.9 .. 1.3
            }
            maxSpeed = Math.Max(MIN_SPEED, maxSpeed);             // at least 10 km/h

            return(maxSpeed);
        }
Beispiel #20
0
        /// <summary>
        /// Returns the pollution generated by this building.
        /// </summary>
        /// <param name="level">Building level</param>
        /// <param name="productionRate">Bulding production rate</param>
        /// <param name="cityPlanningPolicies">Any applicable policies</param>
        /// <param name="groundPollution">Ground pollution generated by this building</param>
        /// <param name="noisePollution">Noise pollution generated by this builidng</param>
        public override void GetPollutionRates(ItemClass.Level level, int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution)
        {
            // If pollution is disabled, return zero.
            if (!m_pollutionEnabled)
            {
                groundPollution = 0;
                noisePollution  = 0;
                return;
            }

            // Otherwise, use base method to calculate normal pollution levels.
            base.GetPollutionRates(level, productionRate, cityPlanningPolicies, out groundPollution, out noisePollution);
        }
        public override void GetPollutionRates(ItemClass.Level level, int productionRate, DistrictPolicies.CityPlanning cityPlanningPolicies, out int groundPollution, out int noisePollution)
        {
            ItemClass @class = this.m_info.m_class;

            int[] array = getArray(this.m_info, (int)level);

            groundPollution = array[DataStore.GROUND_POLLUTION];
            noisePollution  = array[DataStore.NOISE_POLLUTION];
        }
Beispiel #22
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.");
            }
        }
        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 #24
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;
        }
Beispiel #25
0
        public static void GetAccumulation(CommercialBuildingAI thisAI, Randomizer r, int productionRate, int taxRate, DistrictPolicies.CityPlanning cityPlanningPolicies, DistrictPolicies.Taxation taxationPolicies, out int entertainment, out int attractiveness)
        {
            entertainment  = 0;
            attractiveness = 0;

            Debug.LogWarning("GetAccumulation is not overridden!");
        }
Beispiel #26
0
        internal void GetIncome(ushort buildingID, Building buildingData, ref int income, ref int tourists)
        {
            DistrictManager instance = Singleton <DistrictManager> .instance;
            byte            district = instance.GetDistrict(buildingData.m_position);

            DistrictPolicies.Services servicePolicies = instance.m_districts.m_buffer[(int)district].m_servicePolicies;
            ItemClass.Zone            zone            = buildingData.Info.m_class.GetZone();

            int baseIncome = 0;// GetBaseIncome(buildingData.Info.m_class.m_level, zone);

            if ((servicePolicies & DistrictPolicies.Services.Recycling) != DistrictPolicies.Services.None)
            {
                baseIncome = baseIncome * 95 / 100;
            }

            int percentage = 100;

            if (zone == ItemClass.Zone.ResidentialHigh || zone == ItemClass.Zone.ResidentialLow)
            {
                GetCitizenIncome(CitizenUnit.Flags.Home, buildingData, ref income, ref tourists);
            }
            else if (zone == ItemClass.Zone.CommercialHigh || zone == ItemClass.Zone.CommercialLow)
            {
                GetCitizenIncome(CitizenUnit.Flags.Visit, buildingData, ref income, ref tourists);

                DistrictPolicies.CityPlanning cityPlanningPolicies = instance.m_districts.m_buffer[(int)district].m_cityPlanningPolicies;
                if (buildingData.Info.m_class.m_subService == ItemClass.SubService.CommercialLow)
                {
                    if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.SmallBusiness) != DistrictPolicies.CityPlanning.None)
                    {
                        baseIncome += 20;
                    }
                }
                else if ((cityPlanningPolicies & DistrictPolicies.CityPlanning.BigBusiness) != DistrictPolicies.CityPlanning.None)
                {
                    baseIncome += 20;
                }
                if ((servicePolicies & DistrictPolicies.Services.RecreationalUse) != DistrictPolicies.Services.None)
                {
                    baseIncome = (baseIncome * 105 + 99) / 100;
                }
                if (buildingData.m_outgoingProblemTimer >= 128 || buildingData.m_customBuffer1 == 0)
                {
                    percentage = 0;
                }
            }
            else if (zone == ItemClass.Zone.Industrial)
            {
                GetCitizenIncome(CitizenUnit.Flags.Work, buildingData, ref income, ref tourists);

                if (buildingData.m_outgoingProblemTimer >= 128 || buildingData.m_customBuffer1 == 0)
                {
                    percentage = 0;
                }
            }
            else if (zone == ItemClass.Zone.Office)
            {
                GetCitizenIncome(CitizenUnit.Flags.Work, buildingData, ref income, ref tourists);
            }


            income   = (income * baseIncome + 99) / 100;
            tourists = (tourists * baseIncome + 99) / 100;
            if (buildingData.m_electricityProblemTimer >= 1 || buildingData.m_waterProblemTimer >= 1 || buildingData.m_waterProblemTimer >= 1 || buildingData.m_garbageBuffer > 60000)
            {
                percentage = 0;
            }
            float num18 = Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(buildingData.m_position));

            if (num18 > buildingData.m_position.y)
            {
                percentage = 0;
            }
            income   = (income * percentage + 99) / 100;
            tourists = (tourists * percentage * 2 + 99) / 100;
        }