private static List<string> GetDistrictsForLine(TransportLine transportLine, NetManager theNetworkManager, DistrictManager theDistrictManager, out int stopCount)
        {
            var stop = TransportLine.GetPrevStop(transportLine.m_stops);
            var firstStop = stop;
            stopCount = 0;
            var districts = new List<string>();
            while (stop != 0)
            {
                stopCount++;
                var position = theNetworkManager.m_nodes.m_buffer[stop].m_position;
                var district = theDistrictManager.GetDistrict(position);
                if (district != 0)
                {
                    var districtName = theDistrictManager.GetDistrictName(district);
                    districtName = districtName.Trim();
                    if (districts.Contains(districtName) == false)
                        districts.Add(districtName);
                }
                else
                {
                    if (districts.Contains(string.Empty) == false)
                        districts.Add(string.Empty);
                }

                stop = TransportLine.GetNextStop(stop);
                if (stop == firstStop)
                    break;
            }
            return districts;
        }
        public override void SimulationStep(ushort buildingID, ref Building buildingData, ref Building.Frame frameData)
        {
            base.SimulationStep(buildingID, ref buildingData, ref frameData);
            if (Singleton <SimulationManager> .instance.m_randomizer.Int32(10U) == 0)
            {
                DistrictManager instance = Singleton <DistrictManager> .instance;
                byte            district = instance.GetDistrict(buildingData.m_position);
                ushort          num      = instance.m_districts.m_buffer[(int)district].m_Style;
                if ((int)num > 0 && (int)num - 1 < instance.m_Styles.Length)
                {
                    DistrictStyle districtStyle = instance.m_Styles[(int)num - 1];
                    if (districtStyle != null && (UnityEngine.Object) this.m_info.m_class != (UnityEngine.Object)null && (districtStyle.AffectsService(this.m_info.GetService(), this.m_info.GetSubService(), this.m_info.m_class.m_level) && !districtStyle.Contains(this.m_info)) && (int)Singleton <ZoneManager> .instance.m_lastBuildIndex == (int)Singleton <SimulationManager> .instance.m_currentBuildIndex)
                    {
                        buildingData.m_flags |= Building.Flags.Demolishing;
                        ++Singleton <SimulationManager> .instance.m_currentBuildIndex;
                    }
                }
            }
            if ((buildingData.m_flags & Building.Flags.ZonesUpdated) != Building.Flags.None)
            {
                SimulationManager instance = Singleton <SimulationManager> .instance;
                if ((int)buildingData.m_fireIntensity != 0 || instance.m_randomizer.Int32(10U) != 0 || (int)Singleton <ZoneManager> .instance.m_lastBuildIndex != (int)instance.m_currentBuildIndex)
                {
                    return;
                }
                buildingData.m_flags &= ~Building.Flags.ZonesUpdated;
                if (buildingData.CheckZoning(this.m_info.m_class.GetZone(), this.m_info.m_class.GetSecondaryZone()))
                {
                    return;
                }
                buildingData.m_flags |= Building.Flags.Demolishing;
                PrivateBuildingAIDetour.CheckNearbyBuildingZones(buildingData.m_position);
                ++instance.m_currentBuildIndex;
            }
            else
            {
                if ((buildingData.m_flags & (Building.Flags.Abandoned | Building.Flags.Downgrading)) == Building.Flags.None || (int)buildingData.m_majorProblemTimer != (int)byte.MaxValue && (buildingData.m_flags & Building.Flags.Abandoned) != Building.Flags.None)
                {
                    return;
                }
                SimulationManager instance1 = Singleton <SimulationManager> .instance;
                ZoneManager       instance2 = Singleton <ZoneManager> .instance;
                int num1;
                switch (this.m_info.m_class.m_service)
                {
                case ItemClass.Service.Residential:
                    num1 = instance2.m_actualResidentialDemand;
                    break;

                case ItemClass.Service.Commercial:
                    num1 = instance2.m_actualCommercialDemand;
                    break;

                case ItemClass.Service.Industrial:
                    num1 = instance2.m_actualWorkplaceDemand;
                    break;

                case ItemClass.Service.Office:
                    num1 = instance2.m_actualWorkplaceDemand;
                    break;

                default:
                    num1 = 0;
                    break;
                }
                if (instance1.m_randomizer.Int32(100U) >= num1 || (int)instance2.m_lastBuildIndex != (int)instance1.m_currentBuildIndex || (double)Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(buildingData.m_position)) > (double)buildingData.m_position.y)
                {
                    return;
                }
                ItemClass.SubService subService = this.m_info.m_class.m_subService;
                ItemClass.Level      level      = ItemClass.Level.Level1;
                int width = buildingData.Width;
                int num2  = buildingData.Length;
                if (this.m_info.m_class.m_service == ItemClass.Service.Industrial)
                {
                    ZoneBlock.GetIndustryType(buildingData.m_position, out subService, out level);
                }
                else if (this.m_info.m_class.m_service == ItemClass.Service.Commercial)
                {
                    ZoneBlock.GetCommercialType(buildingData.m_position, this.m_info.m_class.GetZone(), width, num2, out subService, out level);
                }
                DistrictManager instance3          = Singleton <DistrictManager> .instance;
                byte            district           = instance3.GetDistrict(buildingData.m_position);
                ushort          num3               = instance3.m_districts.m_buffer[(int)district].m_Style;
                BuildingInfo    randomBuildingInfo = Singleton <BuildingManager> .instance.GetRandomBuildingInfo(ref Singleton <SimulationManager> .instance.m_randomizer, this.m_info.m_class.m_service, subService, level, width, num2, this.m_info.m_zoningMode, (int)num3);

                if (randomBuildingInfo == null)
                {
                    return;
                }
                buildingData.m_flags |= Building.Flags.Demolishing;
                float num4 = buildingData.m_angle + 1.570796f;
                float num5;
                if (this.m_info.m_zoningMode == BuildingInfo.ZoningMode.CornerLeft && randomBuildingInfo.m_zoningMode == BuildingInfo.ZoningMode.CornerRight)
                {
                    num5 = num4 - 1.570796f;
                    num2 = width;
                }
                else if (this.m_info.m_zoningMode == BuildingInfo.ZoningMode.CornerRight && randomBuildingInfo.m_zoningMode == BuildingInfo.ZoningMode.CornerLeft)
                {
                    num5 = num4 + 1.570796f;
                    num2 = width;
                }
                ushort building;
                if (Singleton <BuildingManager> .instance.CreateBuilding(out building, ref Singleton <SimulationManager> .instance.m_randomizer, randomBuildingInfo, buildingData.m_position, buildingData.m_angle, num2, Singleton <SimulationManager> .instance.m_currentBuildIndex))
                {
                    ++Singleton <SimulationManager> .instance.m_currentBuildIndex;
                    switch (this.m_info.m_class.m_service)
                    {
                    case ItemClass.Service.Residential:
                        instance2.m_actualResidentialDemand = Mathf.Max(0, instance2.m_actualResidentialDemand - 5);
                        break;

                    case ItemClass.Service.Commercial:
                        instance2.m_actualCommercialDemand = Mathf.Max(0, instance2.m_actualCommercialDemand - 5);
                        break;

                    case ItemClass.Service.Industrial:
                        instance2.m_actualWorkplaceDemand = Mathf.Max(0, instance2.m_actualWorkplaceDemand - 5);
                        break;

                    case ItemClass.Service.Office:
                        instance2.m_actualWorkplaceDemand = Mathf.Max(0, instance2.m_actualWorkplaceDemand - 5);
                        break;
                    }
                }
                ++instance1.m_currentBuildIndex;
            }
        }
示例#3
0
        /// <summary>
        /// Eventual handler of all service requests
        /// </summary>
        private static bool IsTransferAllowed(Vector3 source, Vector3 destination, ushort buildingID, ushort destBuildingID, TransferManager.TransferReason reason, bool isResidentTransfer)
        {
            ServiceBuildingOptions opts            = ServiceBuildingOptions.GetInstance();
            DistrictManager        districtManager = Singleton <DistrictManager> .instance;
            byte srcDistrict = districtManager.GetDistrict(source);
            byte dstDistrict = districtManager.GetDistrict(destination);

            if (srcDistrict != 0 && !IsActive(srcDistrict))
            {
                Utils.LogGeneral($"IsTransferAllowed: srcDistrict {srcDistrict} not active, setting to zero!");
                srcDistrict = 0;
            }

            if (dstDistrict != 0 && !IsActive(dstDistrict))
            {
                Utils.LogGeneral($"IsTransferAllowed: dstDistrict {dstDistrict} not active, setting to zero!");
                dstDistrict = 0;
            }

            // check whether this transfer represents a resident going out to do something
            if (isResidentTransfer)
            {
                switch (reason)
                {
                // resident going to a hospital or clinic
                case TransferManager.TransferReason.Sick:
                case TransferManager.TransferReason.Sick2:
                    return(Settings.RestrictCitizenHealthAccess ?
                           (dstDistrict == 0 || srcDistrict == dstDistrict || opts.IsTargetCovered(destBuildingID, srcDistrict)) : true);

                // resident going to an educational building
                case TransferManager.TransferReason.Student1:
                case TransferManager.TransferReason.Student2:
                case TransferManager.TransferReason.Student3:
                    return(Settings.RestrictCitizenEducationalAccess ?
                           (dstDistrict == 0 || srcDistrict == dstDistrict || opts.IsTargetCovered(destBuildingID, srcDistrict)) : true);

                // resident going to a park
                case TransferManager.TransferReason.Entertainment:
                case TransferManager.TransferReason.EntertainmentB:
                case TransferManager.TransferReason.EntertainmentC:
                case TransferManager.TransferReason.EntertainmentD:
                    return(Settings.RestrictCitizenParkAccess ?
                           (dstDistrict == 0 || srcDistrict == dstDistrict || opts.IsTargetCovered(destBuildingID, srcDistrict)) : true);

                // resident going to a shop
                case TransferManager.TransferReason.Shopping:
                case TransferManager.TransferReason.ShoppingB:
                case TransferManager.TransferReason.ShoppingC:
                case TransferManager.TransferReason.ShoppingD:
                case TransferManager.TransferReason.ShoppingE:
                case TransferManager.TransferReason.ShoppingF:
                case TransferManager.TransferReason.ShoppingG:
                case TransferManager.TransferReason.ShoppingH:
                    return(Settings.RestrictCitizenShoppingAccess ?
                           (dstDistrict == 0 || srcDistrict == dstDistrict || opts.IsTargetCovered(destBuildingID, srcDistrict)) : true);

                // resident going to work
                case TransferManager.TransferReason.Worker0:
                case TransferManager.TransferReason.Worker1:
                case TransferManager.TransferReason.Worker2:
                case TransferManager.TransferReason.Worker3:
                    return(Settings.RestrictCitizenWorkAccess ?
                           (dstDistrict == 0 || srcDistrict == dstDistrict || opts.IsTargetCovered(destBuildingID, srcDistrict)) : true);

                default:
                    return(true);
                }
            }
            else
            {
                switch (reason)
                {
                // vehicle fetching something
                case TransferManager.TransferReason.Garbage:
                case TransferManager.TransferReason.Crime:
                case TransferManager.TransferReason.Sick:
                case TransferManager.TransferReason.Sick2:
                case TransferManager.TransferReason.Dead:
                case TransferManager.TransferReason.Fire:
                case TransferManager.TransferReason.Fire2:
                case TransferManager.TransferReason.Taxi:
                case TransferManager.TransferReason.Snow:
                case TransferManager.TransferReason.RoadMaintenance:
                    return(!Settings.RestrictServiceDispatching ? true :
                           (srcDistrict == 0 ||
                            srcDistrict == dstDistrict ||
                            opts.IsTargetCovered(buildingID, dstDistrict)));

                // vehicle freeing building capacity
                case TransferManager.TransferReason.DeadMove:
                case TransferManager.TransferReason.GarbageMove:
                case TransferManager.TransferReason.SnowMove:
                    return(!Settings.RestrictMaterialTransfer ? true :
                           (dstDistrict == 0 ||
                            srcDistrict == dstDistrict ||
                            opts.IsTargetCovered(destBuildingID, srcDistrict)));        //inverted logic: destination must cover source of move!

                // ignore prisons
                case TransferManager.TransferReason.CriminalMove:
                    return(true);

                default:
                    return(true);
                }
            }
        }
示例#4
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);
        }
示例#6
0
        private void ProcessHumansUpdated()
        {
            SkylinesOverwatch.Data data = SkylinesOverwatch.Data.Instance;
            uint[] humans = data.HumansUpdated;

            if (humans.Length == 0)
            {
                return;
            }

            CitizenManager instance = Singleton <CitizenManager> .instance;

            foreach (uint i in humans)
            {
                if (!data.IsResident(i))
                {
                    continue;
                }

                Citizen[] residents = instance.m_citizens.m_buffer;
                Citizen   resident  = residents[(int)i];

                if (resident.Dead)
                {
                    continue;
                }

                if ((resident.m_flags & Citizen.Flags.Created) == Citizen.Flags.None)
                {
                    continue;
                }

                if ((resident.m_flags & Citizen.Flags.DummyTraffic) != Citizen.Flags.None)
                {
                    continue;
                }

                if (!Kill(resident))
                {
                    continue;
                }

                residents[(int)i].Sick = false;
                residents[(int)i].Dead = true;
                residents[(int)i].SetParkedVehicle(i, 0);

                ushort home = resident.GetBuildingByLocation();

                if (home == 0)
                {
                    home = resident.m_homeBuilding;
                }

                if (home != 0)
                {
                    DistrictManager dm = Singleton <DistrictManager> .instance;

                    Vector3 position = Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)home].m_position;

                    byte district = dm.GetDistrict(position);

                    District[] buffer = dm.m_districts.m_buffer;
                    buffer[(int)district].m_deathData.m_tempCount = buffer[(int)district].m_deathData.m_tempCount + 1;
                }

                if (_randomizer.Int32(2) == 0)
                {
                    instance.ReleaseCitizen(i);
                }

                SkylinesOverwatch.Helper.Instance.RequestHumanRemoval(i);
            }
        }
        protected override void ProduceGoods(ushort buildingID, ref Building buildingData, ref Building.Frame frameData, int productionRate, ref Citizen.BehaviourData behaviour, int aliveWorkerCount, int totalWorkerCount, int workPlaceCount, int aliveVisitorCount, int totalVisitorCount, int visitPlaceCount)
        {
            base.ProduceGoods(buildingID, ref buildingData, ref frameData, productionRate, ref behaviour, aliveWorkerCount, totalWorkerCount, workPlaceCount, aliveVisitorCount, totalVisitorCount, visitPlaceCount);
            int num = productionRate * this.m_noiseAccumulation / 100;

            if (num != 0)
            {
                Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, num, buildingData.m_position, this.m_noiseRadius);
            }
            base.HandleDead(buildingID, ref buildingData, ref behaviour, totalWorkerCount);
            TransferManager.TransferReason vehicleReason = this.m_transportInfo.m_vehicleReason;
            if (vehicleReason != TransferManager.TransferReason.None)
            {
                int num2 = (productionRate * this.m_maxVehicleCount + 99) / 100;
                if (this.m_transportInfo.m_transportType == TransportInfo.TransportType.Taxi)
                {
                    DistrictManager instance          = Singleton <DistrictManager> .instance;
                    byte            district          = instance.GetDistrict(buildingData.m_position);
                    District[]      expr_B4_cp_0_cp_0 = instance.m_districts.m_buffer;
                    byte            expr_B4_cp_0_cp_1 = district;
                    expr_B4_cp_0_cp_0 [(int)expr_B4_cp_0_cp_1].m_productionData.m_tempTaxiCapacity = expr_B4_cp_0_cp_0 [(int)expr_B4_cp_0_cp_1].m_productionData.m_tempTaxiCapacity + (uint)num2;
                }
                int            num3      = 0;
                int            num4      = 0;
                ushort         num5      = 0;
                VehicleManager instance2 = Singleton <VehicleManager> .instance;
                ushort         num6      = buildingData.m_ownVehicles;
                int            num7      = 0;
                while (num6 != 0)
                {
                    if ((TransferManager.TransferReason)instance2.m_vehicles.m_buffer [(int)num6].m_transferType == vehicleReason)
                    {
                        VehicleInfo info = instance2.m_vehicles.m_buffer [(int)num6].Info;
                        int         num8;
                        int         num9;
                        info.m_vehicleAI.GetSize(num6, ref instance2.m_vehicles.m_buffer [(int)num6], out num8, out num9);
                        num3++;
                        if ((instance2.m_vehicles.m_buffer [(int)num6].m_flags & Vehicle.Flags.GoingBack) != Vehicle.Flags.None)
                        {
                            num4++;
                        }
                        else
                        {
                            if ((instance2.m_vehicles.m_buffer [(int)num6].m_flags & Vehicle.Flags.WaitingTarget) != Vehicle.Flags.None)
                            {
                                num5 = num6;
                            }
                            else
                            {
                                if (instance2.m_vehicles.m_buffer [(int)num6].m_targetBuilding != 0)
                                {
                                    num5 = num6;
                                }
                            }
                        }
                    }
                    num6 = instance2.m_vehicles.m_buffer [(int)num6].m_nextOwnVehicle;
                    if (++num7 > 65536)
                    {
                        CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                        break;
                    }
                }
                if (this.m_maxVehicleCount < 65536 && num3 - num4 > num2 && num5 != 0)
                {
                    VehicleInfo info2 = instance2.m_vehicles.m_buffer [(int)num5].Info;
                    info2.m_vehicleAI.SetTarget(num5, ref instance2.m_vehicles.m_buffer [(int)num5], buildingID);
                }
                if (num3 < num2)
                {
                    TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                    offer.Priority = 0;
                    offer.Building = buildingID;
                    offer.Position = buildingData.m_position;
                    offer.Amount   = Mathf.Min(2, num2 - num3);
                    offer.Active   = true;
                    Singleton <TransferManager> .instance.AddOutgoingOffer(vehicleReason, offer);
                }
            }
        }
        new protected int HandleCommonConsumption(ushort buildingID, ref Building data, ref Building.Frame frameData, ref int electricityConsumption, ref int heatingConsumption, ref int waterConsumption, ref int sewageAccumulation, ref int garbageAccumulation, DistrictPolicies.Services policies)
        {
            int             num      = 100;
            DistrictManager instance = Singleton <DistrictManager> .instance;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            instance.m_districts.m_buffer[(int)district].AddUsageData(electricityUsage, heatingUsage, waterUsage, sewageUsage);
            data.m_problems = problem;
            return(num);
        }
示例#9
0
        //Static or Override?

        ///////////////////////////////////////////////////////////

        public override void SimulationStep(ushort buildingID, ref Building buildingData, ref Building.Frame frameData)
        {
            if (Tracker.GetAccessibilityActive() && !m_logged)                                                  //Simply check to see if a log is needed, usage is activated in AI classes
            {
                TrafficLog.TryAddBuildingLog(buildingID);
                m_logged = true;
            }
            //base.SimulationStep(buildingID, ref buildingData, ref frameData);

            DistrictManager instanceG = Singleton <DistrictManager> .instance;

            //DistrictManagerDetour instanceG = Singleton<DistrictManagerDetour>.instance;

            //Create a new policy or modify an existing policy
            DistrictPolicies.Policies policyG = DistrictPolicies.Policies.Recycling;
            //tra tra = new tra();
            //Tracker.Activate();
            //tra.serialize(new byte[255]);
            if (instanceG.IsDistrictPolicySet(policyG, instanceG.GetDistrict(buildingData.m_position)))
            {
                //This functiion does implement a district effect. However, Abandonment as a resource
                //does not induce abandonment itself.
                //Singleton<ImmaterialResourceManager>.instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, 1000000, buildingData.m_position, 400);
                //base.EmptyBuilding(buildingID, ref buildingData);
                //base.ManualDeactivation(buildingID, ref buildingData);
                Vector3 m_vector3 = buildingData.m_position;

                //string m_districtname = instanceG.GetDistrictName(instanceG.GetDistrict(m_vector3), true);
                string m_districtname = instanceG.GetDistrictName(instanceG.GetDistrict(m_vector3));

                byte m_districtbyte = instanceG.GetDistrict(m_vector3);
                Debug.Log("CommonBuildingAIDetour: " + m_districtname + " X: " + m_vector3.x + " Y: " + m_vector3.y + " Z: " + m_vector3.z);

                //This function adds gentrification by district. The concept works but
                //it is implemented in the wrong place and by an arbitrary cause
                //that requires a temporary slowdown via RNG to avoid overburdening
                //the chirper ChirperPanel instance.

                //TRANSFER LATER, GENTRIFICATION TRACKING

                /*
                 * System.Random rng = new System.Random();
                 * int r = rng.Next(0, 10);
                 * if (r==5)
                 * {
                 *  Tracker.Load(m_districtbyte, 1);
                 *  //Tracker.Load(m_districtbyte, 1);
                 *  int m_gentrifiedint = Convert.ToInt32(Tracker.Get(m_districtbyte));
                 *  string m_gentrifiedstring = Convert.ToString(m_gentrifiedint);
                 *  ChirpPanel chirper = Singleton<ChirpPanel>.instance;
                 *  if ((m_gentrifiedint % 100) == 0)
                 *  {
                 *      //chirper.AddMessage(new ChirpMessage(m_districtname + " Gentrification Status: ", m_gentrifiedstring + " households have been gentrified"));
                 *  }
                 *  //Debug.Log(m_districtname + " Gentrification Status: "+ m_gentrifiedstring + " (" + Convert.ToString(m_districtbyte) + ") " + "households have been gentrified");
                 * }
                 */
            }

            if ((buildingData.m_flags & Building.Flags.Abandoned) != Building.Flags.None)
            {
                GuideController guideController = Singleton <GuideManager> .instance.m_properties;
                if (guideController != null)
                {
                    Singleton <BuildingManager> .instance.m_buildingAbandoned1.Activate(guideController.m_buildingAbandoned1, buildingID);

                    Singleton <BuildingManager> .instance.m_buildingAbandoned2.Activate(guideController.m_buildingAbandoned2, buildingID);
                }
                if ((int)buildingData.m_majorProblemTimer < (int)byte.MaxValue)
                {
                    ++buildingData.m_majorProblemTimer;
                }
                float radius = (float)(buildingData.Width + buildingData.Length) * 2.5f;
                Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Abandonment, 10, buildingData.m_position, radius);
            }
            else if ((buildingData.m_flags & Building.Flags.BurnedDown) != Building.Flags.None)
            {
                GuideController guideController = Singleton <GuideManager> .instance.m_properties;
                if (guideController != null)
                {
                    Singleton <BuildingManager> .instance.m_buildingBurned.Activate(guideController.m_buildingBurned, buildingID);
                }
                float radius = (float)(buildingData.Width + buildingData.Length) * 2.5f;
                Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.Abandonment, 10, buildingData.m_position, radius);
            }
            else if ((buildingData.m_flags & Building.Flags.Completed) == Building.Flags.None)
            {
                bool flag             = (buildingData.m_flags & Building.Flags.Upgrading) != Building.Flags.None;
                int  constructionTime = this.GetConstructionTime();
                frameData.m_constructState = constructionTime != 0 ? (byte)Mathf.Min((int)byte.MaxValue, (int)frameData.m_constructState + 1088 / constructionTime) : byte.MaxValue;
                if ((int)frameData.m_constructState == (int)byte.MaxValue)
                {
                    this.BuildingCompleted(buildingID, ref buildingData);
                    if (Singleton <GuideManager> .instance.m_properties != null)
                    {
                        Singleton <BuildingManager> .instance.m_buildingLevelUp.Deactivate(buildingID, true);
                    }
                }
                else if (flag)
                {
                    GuideController guideController = Singleton <GuideManager> .instance.m_properties;
                    if (guideController != null)
                    {
                        Singleton <BuildingManager> .instance.m_buildingLevelUp.Activate(guideController.m_buildingLevelUp, buildingID);
                    }
                }
                if (!flag)
                {
                    return;
                }
                this.SimulationStepActive(buildingID, ref buildingData, ref frameData);
            }
            else
            {
                this.SimulationStepActive(buildingID, ref buildingData, ref frameData);
            }
        }
示例#10
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;
        }
示例#11
0
        public static void SimulationStep(ref ZoneBlock block, ushort blockID)
        {
            ZoneManager instance1 = Singleton <ZoneManager> .instance;
            int         rowCount  = block.RowCount;
            Vector2     xDir      = new Vector2(Mathf.Cos(block.m_angle), Mathf.Sin(block.m_angle)) * 8f;
            Vector2     zDir      = new Vector2(xDir.y, -xDir.x);
            ulong       num1      = block.m_valid & (ulong)~((long)block.m_occupied1 | (long)block.m_occupied2);
            int         z         = 0;

            ItemClass.Zone zone = ItemClass.Zone.Unzoned;
            for (int index = 0; index < 4 && zone == ItemClass.Zone.Unzoned; ++index)
            {
                z = Singleton <SimulationManager> .instance.m_randomizer.Int32((uint)rowCount);

                if (((long)num1 & 1L << (z << 3)) != 0L)
                {
                    zone = block.GetZone(0, z);
                }
            }
            DistrictManager instance2 = Singleton <DistrictManager> .instance;
            byte            district1 = instance2.GetDistrict(block.m_position);
            int             num2;

            switch (zone)
            {
            case ItemClass.Zone.ResidentialLow:
                num2 = instance1.m_actualResidentialDemand + instance2.m_districts.m_buffer[(int)district1].CalculateResidentialLowDemandOffset();
                break;

            case ItemClass.Zone.ResidentialHigh:
                num2 = instance1.m_actualResidentialDemand + instance2.m_districts.m_buffer[(int)district1].CalculateResidentialHighDemandOffset();
                break;

            case ItemClass.Zone.CommercialLow:
                num2 = instance1.m_actualCommercialDemand + instance2.m_districts.m_buffer[(int)district1].CalculateCommercialLowDemandOffset();
                break;

            case ItemClass.Zone.CommercialHigh:
                num2 = instance1.m_actualCommercialDemand + instance2.m_districts.m_buffer[(int)district1].CalculateCommercialHighDemandOffset();
                break;

            case ItemClass.Zone.Industrial:
                num2 = instance1.m_actualWorkplaceDemand + instance2.m_districts.m_buffer[(int)district1].CalculateIndustrialDemandOffset();
                break;

            case ItemClass.Zone.Office:
                num2 = instance1.m_actualWorkplaceDemand + instance2.m_districts.m_buffer[(int)district1].CalculateOfficeDemandOffset();
                break;

            default:
                return;
            }
            Vector2 vector2_1 = VectorUtils.XZ(block.m_position);
            Vector2 vector2_2 = vector2_1 - 3.5f * xDir + ((float)z - 3.5f) * zDir;

            int[] xBuffer = instance1.m_tmpXBuffer;
            for (int index = 0; index < 13; ++index)
            {
                xBuffer[index] = 0;
            }
            Quad2 quad = new Quad2();

            quad.a = vector2_1 - 4f * xDir + ((float)z - 10f) * zDir;
            quad.b = vector2_1 + 3f * xDir + ((float)z - 10f) * zDir;
            quad.c = vector2_1 + 3f * xDir + ((float)z + 2f) * zDir;
            quad.d = vector2_1 - 4f * xDir + ((float)z + 2f) * zDir;
            Vector2 vector2_3 = quad.Min();
            Vector2 vector2_4 = quad.Max();
            //begin mod
            int num3 = Mathf.Max((int)(((double)vector2_3.x - 46.0) / 64.0 + FakeZoneManager.HALFGRID), 0);
            int num4 = Mathf.Max((int)(((double)vector2_3.y - 46.0) / 64.0 + FakeZoneManager.HALFGRID), 0);
            int num5 = Mathf.Min((int)(((double)vector2_4.x + 46.0) / 64.0 + FakeZoneManager.HALFGRID), FakeZoneManager.GRIDSIZE - 1);
            int num6 = Mathf.Min((int)(((double)vector2_4.y + 46.0) / 64.0 + FakeZoneManager.HALFGRID), FakeZoneManager.GRIDSIZE - 1);

            //end mod
            for (int index1 = num4; index1 <= num6; ++index1)
            {
                for (int index2 = num3; index2 <= num5; ++index2)
                {
                    //begin mod
                    ushort num7 = instance1.m_zoneGrid[index1 * FakeZoneManager.GRIDSIZE + index2];
                    //end mod
                    int num8 = 0;
                    while ((int)num7 != 0)
                    {
                        Vector3 vector3 = instance1.m_blocks.m_buffer[(int)num7].m_position;
                        if ((double)Mathf.Max(Mathf.Max(vector2_3.x - 46f - vector3.x, vector2_3.y - 46f - vector3.z), Mathf.Max((float)((double)vector3.x - (double)vector2_4.x - 46.0), (float)((double)vector3.z - (double)vector2_4.y - 46.0))) < 0.0)
                        {
                            //begin mod
                            CheckBlock(ref block, ref instance1.m_blocks.m_buffer[(int)num7], xBuffer, zone, vector2_2, xDir, zDir, quad);
                        }
                        //end mod
                        num7 = instance1.m_blocks.m_buffer[(int)num7].m_nextGridBlock;
                        if (++num8 >= 49152)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
            for (int index = 0; index < 13; ++index)
            {
                uint num7  = (uint)xBuffer[index];
                int  num8  = 0;
                bool flag1 = ((int)num7 & 196608) == 196608;
                bool flag2 = false;
                while (((int)num7 & 1) != 0)
                {
                    ++num8;
                    flag2  = ((int)num7 & 65536) != 0;
                    num7 >>= 1;
                }
                if (num8 == 5 || num8 == 6)
                {
                    num8 = (!flag2 ? 4 : num8 - (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) + 2)) | 131072;
                }
                else if (num8 == 7)
                {
                    num8 = 4 | 131072;
                }
                if (flag1)
                {
                    num8 |= 65536;
                }
                xBuffer[index] = num8;
            }
            int num9 = xBuffer[6] & (int)ushort.MaxValue;

            if (num9 == 0)
            {
                return;
            }
            //begin mod
            bool flag3 = IsGoodPlace(ref block, vector2_2);

            //end mod
            if (Singleton <SimulationManager> .instance.m_randomizer.Int32(100U) >= num2)
            {
                if (!flag3)
                {
                    return;
                }
                instance1.m_goodAreaFound[(int)zone] = (short)1024;
            }
            else if (!flag3 && (int)instance1.m_goodAreaFound[(int)zone] > -1024)
            {
                if ((int)instance1.m_goodAreaFound[(int)zone] != 0)
                {
                    return;
                }
                instance1.m_goodAreaFound[(int)zone] = (short)-1;
            }
            else
            {
                int  index1 = 6;
                int  index2 = 6;
                bool flag1  = true;
                while (true)
                {
                    if (flag1)
                    {
                        while (index1 != 0 && (xBuffer[index1 - 1] & (int)ushort.MaxValue) == num9)
                        {
                            --index1;
                        }
                        while (index2 != 12 && (xBuffer[index2 + 1] & (int)ushort.MaxValue) == num9)
                        {
                            ++index2;
                        }
                    }
                    else
                    {
                        while (index1 != 0 && (xBuffer[index1 - 1] & (int)ushort.MaxValue) >= num9)
                        {
                            --index1;
                        }
                        while (index2 != 12 && (xBuffer[index2 + 1] & (int)ushort.MaxValue) >= num9)
                        {
                            ++index2;
                        }
                    }
                    int num7 = index1;
                    int num8 = index2;
                    while (num7 != 0 && (xBuffer[num7 - 1] & (int)ushort.MaxValue) >= 2)
                    {
                        --num7;
                    }
                    while (num8 != 12 && (xBuffer[num8 + 1] & (int)ushort.MaxValue) >= 2)
                    {
                        ++num8;
                    }
                    bool flag2 = num7 != 0 && num7 == index1 - 1;
                    bool flag4 = num8 != 12 && num8 == index2 + 1;
                    if (flag2 && flag4)
                    {
                        if (index2 - index1 <= 2)
                        {
                            if (num9 <= 2)
                            {
                                if (!flag1)
                                {
                                    goto label_88;
                                }
                            }
                            else
                            {
                                --num9;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    else if (flag2)
                    {
                        if (index2 - index1 <= 1)
                        {
                            if (num9 <= 2)
                            {
                                if (!flag1)
                                {
                                    goto label_88;
                                }
                            }
                            else
                            {
                                --num9;
                            }
                        }
                        else
                        {
                            goto label_73;
                        }
                    }
                    else if (flag4)
                    {
                        if (index2 - index1 <= 1)
                        {
                            if (num9 <= 2)
                            {
                                if (!flag1)
                                {
                                    goto label_88;
                                }
                            }
                            else
                            {
                                --num9;
                            }
                        }
                        else
                        {
                            goto label_79;
                        }
                    }
                    else if (index1 == index2)
                    {
                        if (num9 <= 2)
                        {
                            if (!flag1)
                            {
                                goto label_88;
                            }
                        }
                        else
                        {
                            --num9;
                        }
                    }
                    else
                    {
                        goto label_88;
                    }
                    flag1 = false;
                }
                ++index1;
                --index2;
                goto label_88;
label_73:
                ++index1;
                goto label_88;
label_79:
                --index2;
label_88:
                int index3;
                int index4;
                if (num9 == 1 && index2 - index1 >= 1)
                {
                    index1 += Singleton <SimulationManager> .instance.m_randomizer.Int32((uint)(index2 - index1));

                    index2 = index1 + 1;
                    index3 = index1 + Singleton <SimulationManager> .instance.m_randomizer.Int32(2U);

                    index4 = index3;
                }
                else
                {
                    do
                    {
                        index3 = index1;
                        index4 = index2;
                        if (index2 - index1 == 2)
                        {
                            if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0)
                            {
                                --index4;
                            }
                            else
                            {
                                ++index3;
                            }
                        }
                        else if (index2 - index1 == 3)
                        {
                            if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0)
                            {
                                index4 -= 2;
                            }
                            else
                            {
                                index3 += 2;
                            }
                        }
                        else if (index2 - index1 == 4)
                        {
                            if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0)
                            {
                                index2 -= 2;
                                index4 -= 3;
                            }
                            else
                            {
                                index1 += 2;
                                index3 += 3;
                            }
                        }
                        else if (index2 - index1 == 5)
                        {
                            if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0)
                            {
                                index2 -= 3;
                                index4 -= 2;
                            }
                            else
                            {
                                index1 += 3;
                                index3 += 2;
                            }
                        }
                        else if (index2 - index1 >= 6)
                        {
                            if (index1 == 0 || index2 == 12)
                            {
                                if (index1 == 0)
                                {
                                    index1 = 3;
                                    index3 = 2;
                                }
                                if (index2 == 12)
                                {
                                    index2 = 9;
                                    index4 = 10;
                                }
                            }
                            else if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0)
                            {
                                index2 = index1 + 3;
                                index4 = index3 + 2;
                            }
                            else
                            {
                                index1 = index2 - 3;
                                index3 = index4 - 2;
                            }
                        }
                    }while (index2 - index1 > 3 || index4 - index3 > 3);
                }
                int a1    = 4;
                int num10 = index2 - index1 + 1;
                BuildingInfo.ZoningMode zoningMode1 = BuildingInfo.ZoningMode.Straight;
                bool flag5 = true;
                for (int index5 = index1; index5 <= index2; ++index5)
                {
                    a1 = Mathf.Min(a1, xBuffer[index5] & (int)ushort.MaxValue);
                    if ((xBuffer[index5] & 131072) == 0)
                    {
                        flag5 = false;
                    }
                }
                if (index2 > index1)
                {
                    if ((xBuffer[index1] & 65536) != 0)
                    {
                        zoningMode1 = BuildingInfo.ZoningMode.CornerLeft;
                        index4      = index1 + index4 - index3;
                        index3      = index1;
                    }
                    if ((xBuffer[index2] & 65536) != 0 && (zoningMode1 != BuildingInfo.ZoningMode.CornerLeft || Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0))
                    {
                        zoningMode1 = BuildingInfo.ZoningMode.CornerRight;
                        index3      = index2 + index3 - index4;
                        index4      = index2;
                    }
                }
                int a2    = 4;
                int num11 = index4 - index3 + 1;
                BuildingInfo.ZoningMode zoningMode2 = BuildingInfo.ZoningMode.Straight;
                bool flag6 = true;
                for (int index5 = index3; index5 <= index4; ++index5)
                {
                    a2 = Mathf.Min(a2, xBuffer[index5] & (int)ushort.MaxValue);
                    if ((xBuffer[index5] & 131072) == 0)
                    {
                        flag6 = false;
                    }
                }
                if (index4 > index3)
                {
                    if ((xBuffer[index3] & 65536) != 0)
                    {
                        zoningMode2 = BuildingInfo.ZoningMode.CornerLeft;
                    }
                    if ((xBuffer[index4] & 65536) != 0 && (zoningMode2 != BuildingInfo.ZoningMode.CornerLeft || Singleton <SimulationManager> .instance.m_randomizer.Int32(2U) == 0))
                    {
                        zoningMode2 = BuildingInfo.ZoningMode.CornerRight;
                    }
                }
                ItemClass.SubService subService = ItemClass.SubService.None;
                ItemClass.Level      level      = ItemClass.Level.Level1;
                ItemClass.Service    service;
                switch (zone)
                {
                case ItemClass.Zone.ResidentialLow:
                    service    = ItemClass.Service.Residential;
                    subService = ItemClass.SubService.ResidentialLow;
                    break;

                case ItemClass.Zone.ResidentialHigh:
                    service    = ItemClass.Service.Residential;
                    subService = ItemClass.SubService.ResidentialHigh;
                    break;

                case ItemClass.Zone.CommercialLow:
                    service    = ItemClass.Service.Commercial;
                    subService = ItemClass.SubService.CommercialLow;
                    break;

                case ItemClass.Zone.CommercialHigh:
                    service    = ItemClass.Service.Commercial;
                    subService = ItemClass.SubService.CommercialHigh;
                    break;

                case ItemClass.Zone.Industrial:
                    service = ItemClass.Service.Industrial;
                    break;

                case ItemClass.Zone.Office:
                    service = ItemClass.Service.Office;
                    break;

                default:
                    return;
                }
                BuildingInfo            info        = (BuildingInfo)null;
                Vector3                 vector3     = Vector3.zero;
                int                     num12       = 0;
                int                     num13       = 0;
                int                     width       = 0;
                BuildingInfo.ZoningMode zoningMode3 = BuildingInfo.ZoningMode.Straight;
                for (int index5 = 0; index5 < 6; ++index5)
                {
                    switch (index5)
                    {
                    case 0:
                        if (zoningMode1 != BuildingInfo.ZoningMode.Straight)
                        {
                            num12       = index1 + index2 + 1;
                            num13       = a1;
                            width       = num10;
                            zoningMode3 = zoningMode1;
                            goto default;
                        }
                        else
                        {
                            break;
                        }

                    case 1:
                        if (zoningMode2 != BuildingInfo.ZoningMode.Straight)
                        {
                            num12       = index3 + index4 + 1;
                            num13       = a2;
                            width       = num11;
                            zoningMode3 = zoningMode2;
                            goto default;
                        }
                        else
                        {
                            break;
                        }

                    case 2:
                        if (zoningMode1 != BuildingInfo.ZoningMode.Straight && a1 >= 4)
                        {
                            num12       = index1 + index2 + 1;
                            num13       = !flag5 ? 2 : 3;
                            width       = num10;
                            zoningMode3 = zoningMode1;
                            goto default;
                        }
                        else
                        {
                            break;
                        }

                    case 3:
                        if (zoningMode2 != BuildingInfo.ZoningMode.Straight && a2 >= 4)
                        {
                            num12       = index3 + index4 + 1;
                            num13       = !flag6 ? 2 : 3;
                            width       = num11;
                            zoningMode3 = zoningMode2;
                            goto default;
                        }
                        else
                        {
                            break;
                        }

                    case 4:
                        num12       = index1 + index2 + 1;
                        num13       = a1;
                        width       = num10;
                        zoningMode3 = BuildingInfo.ZoningMode.Straight;
                        goto default;

                    case 5:
                        num12       = index3 + index4 + 1;
                        num13       = a2;
                        width       = num11;
                        zoningMode3 = BuildingInfo.ZoningMode.Straight;
                        goto default;

                    default:
                        vector3 = block.m_position + VectorUtils.X_Y((float)((double)num13 * 0.5 - 4.0) * xDir + (float)((double)num12 * 0.5 + (double)z - 10.0) * zDir);
                        if (zone == ItemClass.Zone.Industrial)
                        {
                            ZoneBlock.GetIndustryType(vector3, out subService, out level);
                        }
                        else if (zone == ItemClass.Zone.CommercialLow || zone == ItemClass.Zone.CommercialHigh)
                        {
                            ZoneBlock.GetCommercialType(vector3, zone, width, num13, out subService, out level);
                        }
                        else if (zone == ItemClass.Zone.ResidentialLow || zone == ItemClass.Zone.ResidentialHigh)
                        {
                            ZoneBlock.GetResidentialType(vector3, zone, width, num13, out subService, out level);
                        }
                        else if (zone == ItemClass.Zone.Office)
                        {
                            ZoneBlock.GetOfficeType(vector3, zone, width, num13, out subService, out level);
                        }
                        byte   district2 = instance2.GetDistrict(vector3);
                        ushort style     = instance2.m_districts.m_buffer[(int)district2].m_Style;
                        if (Singleton <BuildingManager> .instance.m_BuildingWrapper != null)
                        {
                            Singleton <BuildingManager> .instance.m_BuildingWrapper.OnCalculateSpawn(vector3, ref service, ref subService, ref level, ref style);
                        }
                        info = Singleton <BuildingManager> .instance.GetRandomBuildingInfo(ref Singleton <SimulationManager> .instance.m_randomizer, service, subService, level, width, num13, zoningMode3, (int)style);

                        if (info == null)
                        {
                            break;
                        }
                        goto label_169;
                    }
                }
label_169:
                if (info == null || (double)Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(vector3)) > (double)vector3.y || Singleton <DisasterManager> .instance.IsEvacuating(vector3))
                {
                    return;
                }
                float angle = block.m_angle + 1.570796f;
                if (zoningMode3 == BuildingInfo.ZoningMode.CornerLeft && info.m_zoningMode == BuildingInfo.ZoningMode.CornerRight)
                {
                    angle -= 1.570796f;
                    num13  = width;
                }
                else if (zoningMode3 == BuildingInfo.ZoningMode.CornerRight && info.m_zoningMode == BuildingInfo.ZoningMode.CornerLeft)
                {
                    angle += 1.570796f;
                    num13  = width;
                }
                ushort building;
                if (Singleton <BuildingManager> .instance.CreateBuilding(out building, ref Singleton <SimulationManager> .instance.m_randomizer, info, vector3, angle, num13, Singleton <SimulationManager> .instance.m_currentBuildIndex))
                {
                    ++Singleton <SimulationManager> .instance.m_currentBuildIndex;
                    switch (service)
                    {
                    case ItemClass.Service.Residential:
                        instance1.m_actualResidentialDemand = Mathf.Max(0, instance1.m_actualResidentialDemand - 5);
                        break;

                    case ItemClass.Service.Commercial:
                        instance1.m_actualCommercialDemand = Mathf.Max(0, instance1.m_actualCommercialDemand - 5);
                        break;

                    case ItemClass.Service.Industrial:
                        instance1.m_actualWorkplaceDemand = Mathf.Max(0, instance1.m_actualWorkplaceDemand - 5);
                        break;

                    case ItemClass.Service.Office:
                        instance1.m_actualWorkplaceDemand = Mathf.Max(0, instance1.m_actualWorkplaceDemand - 5);
                        break;
                    }
                    switch (zone)
                    {
                    case ItemClass.Zone.ResidentialHigh:
                    case ItemClass.Zone.CommercialHigh:
                        Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)building].m_flags |= Building.Flags.HighDensity;
                        break;
                    }
                }
                instance1.m_goodAreaFound[(int)zone] = (short)1024;
            }
        }
        public override void OnAfterSimulationFrame()
        {
            if (!LoadingExtension.installed)
            {
                return;
            }

            if (s_info == null)
            {
                return;
            }

            BuildingManager instance = Singleton <BuildingManager> .instance;

            int    num6          = (int)(Singleton <SimulationManager> .instance.m_currentFrameIndex & 255u);
            ushort minBuildingID = (ushort)(num6 * 192);
            ushort maxBuildingID = (ushort)((num6 + 1) * 192 - 1);

            //check if building should be added as part of a resilient district
            DistrictManager instance2 = Singleton <DistrictManager> .instance;

            for (ushort i = minBuildingID; i < maxBuildingID; i++)
            {
                if (instance.m_buildings.m_buffer[i].m_flags == Building.Flags.None)
                {
                    continue;
                }
                Building build         = instance.m_buildings.m_buffer[i];
                byte     districtID    = instance2.GetDistrict(build.m_position);
                int      districtIndex = s_info.GetResilientDistrictIndex(districtID);
                if (districtIndex != -1)
                {
                    if (s_info.m_districts[districtIndex].unsuscribed)
                    {
                        //s_info.RemoveBuilding(i);
                        s_info.UnsuscribeBuilding(i);
                    }
                    else if (s_info.m_districts[districtIndex].resiliencyActivated)
                    {
                        bool newly_added = s_info.AddBuilding(i, true);
                        if (newly_added)
                        {
                            ResilientBuildings.ResilientDistrict rd = s_info.m_districts[districtIndex];
                            rd.totalBuildings++;
                            s_info.m_districts[districtIndex] = rd;
                        }
                    }
                }
            }

            //districts timers
            for (int i = 0; i < s_info.m_districts.Count; i++)
            {
                if (s_info.m_districts[i].unsuscribed)
                {
                    ResilientBuildings.ResilientDistrict rd = s_info.m_districts[i];
                    rd.unsuscribeTimer++;
                    s_info.m_districts[i] = rd;
                    if (rd.unsuscribeTimer > REMOVE_DISTRICT_AFTER_UPDATES)
                    {
                        s_info.RemoveDistrict(rd.districtID);
                    }
                }
            }


            //check all buildings in resilients list
            for (int i = 0; i < s_info.m_resilients.Count; i++)
            {
                ushort buildingID = s_info.m_resilients[i].buildingID;

                //sync with buildManager, update only buildings that just had a SimulationStep
                if (buildingID < minBuildingID || buildingID >= maxBuildingID)
                {
                    continue;
                }

                ResilientBuildings.ResilientInfoV1 build = s_info.m_resilients[i];

                if (s_info.m_resilients[i].unsuscribed)                //building unsuscribed
                {
                    build.unsuscribeTimer++;
                    if (build.unsuscribeTimer > REMOVE_AFTER_UPDATES)
                    {
                        s_info.m_resilients.RemoveAt(i);
                        i--;
                        continue;
                    }
                    s_info.m_resilients[i] = build;
                    continue;
                }

                if (instance.m_buildings.m_buffer[buildingID].m_flags == Building.Flags.None)                //building was bulldozed, remove it from the list
                {
                    s_info.m_resilients.RemoveAt(i);
                    i--;
                    continue;
                }


                //update infos
                BuildingInfo buildinfo = Singleton <BuildingManager> .instance.m_buildings.m_buffer[buildingID].Info;

                if (buildinfo.m_class.m_service == ItemClass.Service.Residential)
                {
                    s_info.UpdateResidentFamilies(i);
                }
                else
                {
                    s_info.UpdateWorkers(i);

                    if (buildinfo.m_class.m_service == ItemClass.Service.Commercial)
                    {
                        s_info.UpdateVisitsCount(i);
                    }
                    else if (buildinfo.m_class.m_service == ItemClass.Service.Industrial)
                    {
                        if (buildinfo.m_buildingAI.GetType().Equals(typeof(IndustrialExtractorAI)))
                        {
                            s_info.UpdatePrimaryResourceExport(i);
                        }
                        else if (buildinfo.m_buildingAI.GetType().Equals(typeof(IndustrialBuildingAI)))
                        {
                            s_info.UpdateGoodsExport(i);
                        }
                    }
                }

                if (build.resiliencyActivated)
                {
                    //instance.m_buildings.m_buffer[buildingID].m_electricityProblemTimer = 0;
                    //instance.m_buildings.m_buffer[buildingID].m_majorProblemTimer = 0;
                    //instance.m_buildings.m_buffer[buildingID].m_problems = Notification.Problem.TurnedOff;

                    //building will not be removed when dezoning, it must be bulldozed
                    //instance.m_buildings.m_buffer[buildingID].m_flags &= ~Building.Flags.ZonesUpdated;

                    //avoid major problem to trigger abandonment
                    instance.m_buildings.m_buffer[buildingID].m_majorProblemTimer = 0;
                    instance.m_buildings.m_buffer[buildingID].m_problems         &= ~Notification.Problem.MajorProblem;

                    //lower cap on unhappiness if problems
                    if (instance.m_buildings.m_buffer[buildingID].m_problems != Notification.Problem.None)
                    {
                        instance.m_buildings.m_buffer[buildingID].m_happiness = 60;
                    }

                    //reoccupy building when it is abandoned/burned down
                    if ((instance.m_buildings.m_buffer[buildingID].m_flags & (Building.Flags.Abandoned | Building.Flags.BurnedDown)) != Building.Flags.None)
                    {
                        //reset timers
                        instance.m_buildings.m_buffer[buildingID].m_electricityProblemTimer = 0;
                        instance.m_buildings.m_buffer[buildingID].m_waterProblemTimer       = 0;
                        instance.m_buildings.m_buffer[buildingID].m_majorProblemTimer       = 0;
                        instance.m_buildings.m_buffer[buildingID].m_deathProblemTimer       = 0;
                        instance.m_buildings.m_buffer[buildingID].m_serviceProblemTimer     = 0;
                        instance.m_buildings.m_buffer[buildingID].m_taxProblemTimer         = 0;
                        instance.m_buildings.m_buffer[buildingID].m_outgoingProblemTimer    = 0;
                        instance.m_buildings.m_buffer[buildingID].m_incomingProblemTimer    = 0;
                        instance.m_buildings.m_buffer[buildingID].m_heatingProblemTimer     = 0;
                        instance.m_buildings.m_buffer[buildingID].m_healthProblemTimer      = 0;
                        instance.m_buildings.m_buffer[buildingID].m_workerProblemTimer      = 0;

                        //reset buffers
                        instance.m_buildings.m_buffer[buildingID].m_crimeBuffer       = 0;
                        instance.m_buildings.m_buffer[buildingID].m_customBuffer1     = 0;
                        instance.m_buildings.m_buffer[buildingID].m_customBuffer2     = 0;
                        instance.m_buildings.m_buffer[buildingID].m_electricityBuffer = 0;
                        instance.m_buildings.m_buffer[buildingID].m_heatingBuffer     = 0;
                        instance.m_buildings.m_buffer[buildingID].m_garbageBuffer     = 0;
                        instance.m_buildings.m_buffer[buildingID].m_sewageBuffer      = 0;
                        instance.m_buildings.m_buffer[buildingID].m_waterBuffer       = 0;

                        //renovate building
                        Building.Frame carpentry = instance.m_buildings.m_buffer[buildingID].GetLastFrameData();
                        carpentry.m_constructState /= 2;
                        carpentry.m_fireDamage      = 0;
                        instance.m_buildings.m_buffer[buildingID].SetFrameData(Singleton <SimulationManager> .instance.m_currentFrameIndex, carpentry);

                        //repopulate building
                        instance.m_buildings.m_buffer[buildingID].m_flags = Building.Flags.Created;
                        instance.m_buildings.m_buffer[buildingID].Info.m_buildingAI.CreateBuilding(buildingID, ref instance.m_buildings.m_buffer[buildingID]);

                        //user feedback : remove notification
                        instance.m_buildings.m_buffer[buildingID].m_problems = Notification.Problem.None;
                    }

                    if (instance.m_buildings.m_buffer[buildingID].GetLastFrameData().m_fireDamage > 230 && Settings.inst.extinguishFires)                    //extinguish fire at last minute
                    {
                        instance.m_buildings.m_buffer[buildingID].m_fireIntensity = 0;
//						Building.Frame carpentry = instance.m_buildings.m_buffer[buildingID].GetLastFrameData();
//						carpentry.m_fireDamage = 0;
//						instance.m_buildings.m_buffer[buildingID].SetFrameData(Singleton<SimulationManager>.instance.m_currentFrameIndex+1, carpentry);
                    }
                }

                s_UI.CheckUpdateUI(buildingID);
            }
        }
示例#13
0
 public District GetDistrict(long id)
 {
     return(_districtManagerManager.GetDistrict(id));
 }
示例#14
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);
                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;
                }
                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.");
            }
        }
示例#15
0
        protected override void ProduceGoods(ushort buildingID, ref Building buildingData, ref Building.Frame frameData, int productionRate, int finalProductionRate, ref Citizen.BehaviourData behaviour, int aliveWorkerCount, int totalWorkerCount, int workPlaceCount, int aliveVisitorCount, int totalVisitorCount, int visitPlaceCount)
        {
            DistrictManager instance = Singleton <DistrictManager> .instance;
            byte            district = instance.GetDistrict(buildingData.m_position);

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

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

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

                    buildingData.m_customBuffer1 = (ushort)num10;
                    buildingData.m_customBuffer2 = (ushort)(num8 / 100);
                }
                if (this.m_outputResource != TransferManager.TransferReason.None)
                {
                    int num11  = (num5 * this.m_outputVehicleCount + 99) / 100;
                    int num12  = 0;
                    int num13  = 0;
                    int num14  = 0;
                    int value2 = 0;
                    base.CalculateOwnVehicles(buildingID, ref buildingData, this.m_outputResource, ref num12, ref num13, ref num14, ref value2);
                    buildingData.m_tempExport = (byte)Mathf.Clamp(value2, (int)buildingData.m_tempExport, 255);
                    if (buildingData.m_finalExport != 0)
                    {
                        District[] buffer2 = instance.m_districts.m_buffer;
                        byte       b3      = district;
                        buffer2[(int)b3].m_playerConsumption.m_finalExportAmount = buffer2[(int)b3].m_playerConsumption.m_finalExportAmount + (uint)buildingData.m_finalExport;
                    }
                    int num15 = num8;
                    if (num15 >= 8000 && num12 < num11)
                    {
                        TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                        offer.Priority = Mathf.Max(1, num15 * 8 / num7);
                        offer.Building = buildingID;
                        offer.Position = buildingData.m_position;
                        offer.Amount   = 1;
                        offer.Active   = true;
                        Singleton <TransferManager> .instance.AddOutgoingOffer(this.m_outputResource, offer);
                    }
                }
            }
            buildingData.m_problems   = problem;
            buildingData.m_education3 = (byte)Mathf.Clamp(finalProductionRate * this.m_productionRate / Mathf.Max(1, this.m_productionRate), 0, 255);
            base.ProduceGoods(buildingID, ref buildingData, ref frameData, productionRate, finalProductionRate, ref behaviour, aliveWorkerCount, totalWorkerCount, workPlaceCount, aliveVisitorCount, totalVisitorCount, visitPlaceCount);
        }
示例#16
0
        public static bool RenderPropsPrefix(BuildingAI __instance, RenderManager.CameraInfo cameraInfo, ushort buildingID, ref Building data, int layerMask, ref RenderManager.Instance instance, bool renderFixed, bool renderNonfixed, bool isActive)
        {
            if (__instance.m_info.m_props == null || ((layerMask & __instance.m_info.m_treeLayers) == 0 && !cameraInfo.CheckRenderDistance(instance.m_position, __instance.m_info.m_maxPropDistance + 72f)))
            {
                return(false);
            }
            int             length          = data.Length;
            Texture         _HeightMap      = null;
            Vector4         _HeightMapping  = Vector4.zero;
            Vector4         _SurfaceMapping = Vector4.zero;
            Matrix4x4       lhs             = Matrix4x4.zero;
            bool            flag            = false;
            DistrictManager instance2       = Singleton <DistrictManager> .instance;
            byte            district        = instance2.GetDistrict(data.m_position);
            Vector3         position        = data.m_position;
            ushort          num             = Building.FindParentBuilding(buildingID);

            if (num != 0)
            {
                position = Singleton <BuildingManager> .instance.m_buildings.m_buffer[num].m_position;
            }
            byte park = instance2.GetPark(position);

            for (int i = 0; i < __instance.m_info.m_props.Length; i++)
            {
                BuildingInfo.Prop prop = __instance.m_info.m_props[i];
                Randomizer        r    = new Randomizer((buildingID << 6) | prop.m_index);
                if (r.Int32(100u) >= prop.m_probability || length < prop.m_requiredLength)
                {
                    continue;
                }
                PropInfo finalProp = prop.m_finalProp;
                TreeInfo finalTree = prop.m_finalTree;
                if (finalProp != null)
                {
                    finalProp = finalProp.GetVariation(ref r, ref instance2.m_districts.m_buffer[district], park);
                    float num2  = finalProp.m_minScale + (float)r.Int32(10000u) * (finalProp.m_maxScale - finalProp.m_minScale) * 0.0001f;
                    Color color = finalProp.GetColor(ref r);
                    if ((layerMask & (1 << finalProp.m_prefabDataLayer)) == 0 && !finalProp.m_hasEffects)
                    {
                        continue;
                    }
                    Vector4 dataVector = instance.m_dataVector3;
                    Vector3 vector;
                    if (prop.m_fixedHeight)
                    {
                        if (!renderFixed)
                        {
                            continue;
                        }
                        if (__instance.m_info.m_isFloating)
                        {
                            if (!flag)
                            {
                                Singleton <TerrainManager> .instance.HeightMap_sampleWaterHeightAndNormal(instance.m_position, 0.15f, out float h, out Vector3 normal);

                                Vector3 position2 = instance.m_position;
                                position2.y = h;
                                Quaternion q = Quaternion.FromToRotation(Vector3.up, normal) * instance.m_rotation;
                                lhs  = Matrix4x4.TRS(position2, q, Vector3.one);
                                flag = true;
                            }
                            Matrix4x4 rhs = default(Matrix4x4);
                            rhs.SetTRS(prop.m_position, Quaternion.AngleAxis(prop.m_radAngle * 57.29578f, Vector3.down), new Vector3(num2, num2, num2));
                            rhs    = lhs * rhs;
                            vector = rhs.MultiplyPoint(Vector3.zero);
                            if (cameraInfo.CheckRenderDistance(vector, finalProp.m_maxRenderDistance))
                            {
                                InstanceID propRenderID = GetPropRenderIDReverse(__instance, buildingID, i, ref data);
                                PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID, rhs, vector, num2, data.m_angle + prop.m_radAngle, color, dataVector, isActive);
                                continue;
                            }
                        }
                        else
                        {
                            vector = instance.m_dataMatrix1.MultiplyPoint(prop.m_position);
                            if (__instance.m_info.m_requireHeightMap)
                            {
                                vector.y = (float)(int)instance.m_extraData.GetUShort(i) * 0.015625f;
                            }
                        }
                    }
                    else
                    {
                        if (!renderNonfixed)
                        {
                            continue;
                        }
                        vector = instance.m_dataMatrix1.MultiplyPoint(prop.m_position);
                        if (!__instance.m_info.m_isFloating)
                        {
                            vector.y = (float)(int)instance.m_extraData.GetUShort(i) * 0.015625f;
                        }
                        if (!__instance.m_info.m_colorizeEverything || finalProp.m_isDecal)
                        {
                            dataVector.z = 0f;
                        }
                    }
                    if (!cameraInfo.CheckRenderDistance(vector, finalProp.m_maxRenderDistance))
                    {
                        continue;
                    }
                    InstanceID propRenderID2 = GetPropRenderIDReverse(__instance, buildingID, i, ref data);
                    if (finalProp.m_requireWaterMap)
                    {
                        if (_HeightMap == null)
                        {
                            Singleton <TerrainManager> .instance.GetWaterMapping(data.m_position, out _HeightMap, out _HeightMapping, out _SurfaceMapping);
                        }
#if UseTask
                        var localData     = data;
                        var localInstance = instance;
                        Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, localData.m_angle + prop.m_radAngle, color, dataVector, isActive, localInstance.m_dataTexture0, localInstance.m_dataVector1, localInstance.m_dataVector2, _HeightMap, _HeightMapping, _SurfaceMapping));
#else
                        PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, data.m_angle + prop.m_radAngle, color, dataVector, isActive, instance.m_dataTexture0, instance.m_dataVector1, instance.m_dataVector2, _HeightMap, _HeightMapping, _SurfaceMapping);
#endif
                    }
                    else if (finalProp.m_requireHeightMap)
                    {
#if UseTask
                        var localData     = data;
                        var localInstance = instance;
                        Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, localData.m_angle + prop.m_radAngle, color, dataVector, isActive, localInstance.m_dataTexture0, localInstance.m_dataVector1, localInstance.m_dataVector2));
#else
                        PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, data.m_angle + prop.m_radAngle, color, dataVector, isActive, instance.m_dataTexture0, instance.m_dataVector1, instance.m_dataVector2);
#endif
                    }
                    else
                    {
#if UseTask
                        var localData     = data;
                        var localInstance = instance;
                        Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, localData.m_angle + prop.m_radAngle, color, dataVector, isActive));
#else
                        PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, data.m_angle + prop.m_radAngle, color, dataVector, isActive);
#endif
                    }
                }
                else
                {
                    if (!(finalTree != null))
                    {
                        continue;
                    }
                    finalTree = finalTree.GetVariation(ref r);
                    float scale      = finalTree.m_minScale + (float)r.Int32(10000u) * (finalTree.m_maxScale - finalTree.m_minScale) * 0.0001f;
                    float brightness = finalTree.m_minBrightness + (float)r.Int32(10000u) * (finalTree.m_maxBrightness - finalTree.m_minBrightness) * 0.0001f;
                    if ((layerMask & (1 << finalTree.m_prefabDataLayer)) != 0 && ((!prop.m_fixedHeight) ? renderNonfixed : renderFixed))
                    {
                        Vector3 position3 = instance.m_dataMatrix1.MultiplyPoint(prop.m_position);
                        if (!prop.m_fixedHeight || __instance.m_info.m_requireHeightMap)
                        {
                            position3.y = (float)(int)instance.m_extraData.GetUShort(i) * 0.015625f;
                        }
                        Vector4 dataVector2 = instance.m_dataVector3;
                        if (!__instance.m_info.m_colorizeEverything)
                        {
                            dataVector2.z = 0f;
                        }
#if UseTask
                        var localData     = data;
                        var localInstance = instance;
                        Patcher.Dispatcher.Add(() => TreeInstance.RenderInstance(cameraInfo, finalTree, position3, scale, brightness, dataVector2));
#else
                        TreeInstance.RenderInstance(cameraInfo, finalTree, position3, scale, brightness, dataVector2);
#endif
                    }
                }
            }

            return(false);
        }
示例#17
0
        protected override void ProduceGoods(ushort buildingID, ref Building buildingData, ref Building.Frame frameData, int productionRate, int finalProductionRate, ref Citizen.BehaviourData behaviour, int aliveWorkerCount, int totalWorkerCount, int workPlaceCount, int aliveVisitorCount, int totalVisitorCount, int visitPlaceCount)
        {
            DistrictManager instance = Singleton <DistrictManager> .instance;
            byte            district = instance.GetDistrict(buildingData.m_position);
            byte            b        = instance.GetPark(buildingData.m_position);

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

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

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

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

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

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

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

                            int productionRate2 = PlayerBuildingAI.GetProductionRate(100, budget);
                            int num64           = (productionRate2 * this.m_outputVehicleCount + 99) / 100;
                            int num65           = num32;
                            if (num65 >= 8000 && num61 < num64)
                            {
                                TransferManager.TransferOffer offer5 = default(TransferManager.TransferOffer);
                                offer5.Priority = Mathf.Max(1, num65 * 8 / num31);
                                offer5.Building = buildingID;
                                offer5.Position = buildingData.m_position;
                                offer5.Amount   = 1;
                                offer5.Active   = true;
                                Singleton <TransferManager> .instance.AddOutgoingOffer(this.m_outputResource, offer5);
                            }
                        }
                        instance.m_parks.m_buffer[(int)b].AddBufferStatusFish(this.m_outputResource, num32, 0, num31);
                    }
                }
                if (buildingData.m_finalImport != 0)
                {
                    District[] buffer2 = instance.m_districts.m_buffer;
                    byte       b3      = district;
                    buffer2[(int)b3].m_playerConsumption.m_finalImportAmount = buffer2[(int)b3].m_playerConsumption.m_finalImportAmount + (uint)buildingData.m_finalImport;
                }
                if (buildingData.m_finalExport != 0)
                {
                    District[] buffer3 = instance.m_districts.m_buffer;
                    byte       b4      = district;
                    buffer3[(int)b4].m_playerConsumption.m_finalExportAmount = buffer3[(int)b4].m_playerConsumption.m_finalExportAmount + (uint)buildingData.m_finalExport;
                }
                int num66 = finalProductionRate * this.m_noiseAccumulation / 100;
                if (num66 != 0)
                {
                    Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, num66, position, this.m_noiseRadius);
                }
            }
            buildingData.m_problems   = problem;
            buildingData.m_education3 = (byte)Mathf.Clamp(finalProductionRate * num13 / Mathf.Max(1, this.m_outputRate), 0, 255);
            buildingData.m_health     = (byte)Mathf.Clamp(finalProductionRate, 0, 255);
            if (b != 0)
            {
                instance.m_parks.m_buffer[(int)b].AddWorkers(aliveWorkerCount);
            }
            else if (this.m_industryType != DistrictPark.ParkType.Industry)
            {
                GuideController properties2 = Singleton <GuideManager> .instance.m_properties;
                if (properties2 != null)
                {
                    Singleton <BuildingManager> .instance.m_industryBuildingOutsideIndustryArea.Activate(properties2.m_industryBuildingOutsideIndustryArea, buildingID);
                }
            }
            base.ProduceGoods(buildingID, ref buildingData, ref frameData, productionRate, finalProductionRate, ref behaviour, aliveWorkerCount, totalWorkerCount, workPlaceCount, aliveVisitorCount, totalVisitorCount, visitPlaceCount);
        }
        public static void CalculateBuildingMoneyAndSalary(Building building, ushort buildingID)
        {
            if (BuildingData.buildingMoney[buildingID] > MainDataStore.maxBuildingMoneyLimit)
            {
                BuildingData.buildingMoney[buildingID] = MainDataStore.maxBuildingMoneyLimit;
            }
            else if (BuildingData.buildingMoney[buildingID] < -MainDataStore.maxBuildingMoneyLimit)
            {
                BuildingData.buildingMoney[buildingID] = -MainDataStore.maxBuildingMoneyLimit;
            }


            if (building.Info.m_class.m_service == ItemClass.Service.Industrial || building.Info.m_class.m_service == ItemClass.Service.Commercial || building.Info.m_class.m_service == ItemClass.Service.Office)
            {
                Citizen.BehaviourData behaviourData = default;
                int aliveWorkerCount = 0;
                int totalWorkerCount = 0;
                RealCityCommonBuildingAI.InitDelegate();
                RealCityCommonBuildingAI.GetWorkBehaviour((CommonBuildingAI)building.Info.m_buildingAI, buildingID, ref building, ref behaviourData, ref aliveWorkerCount, ref totalWorkerCount);
                float bossTake       = 0;
                float investToOffice = 0;
                float profitShare    = 0;

                switch (building.Info.m_class.m_subService)
                {
                case ItemClass.SubService.OfficeGeneric:
                case ItemClass.SubService.OfficeHightech:
                    profitShare = 1f; break;

                case ItemClass.SubService.IndustrialFarming:
                case ItemClass.SubService.IndustrialForestry:
                    if (building.Info.m_buildingAI is IndustrialExtractorAI)
                    {
                        bossTake       = MainDataStore.bossRatioInduExtractor;
                        investToOffice = MainDataStore.investRatioInduExtractor;
                        profitShare    = MainDataStore.profitShareRatioInduExtractor;
                    }
                    else
                    {
                        bossTake       = MainDataStore.bossRatioInduOther;
                        investToOffice = MainDataStore.investRatioInduOther;
                        profitShare    = MainDataStore.profitShareRatioInduOther;
                    }
                    break;

                case ItemClass.SubService.IndustrialOil:
                case ItemClass.SubService.IndustrialOre:
                    bossTake       = MainDataStore.bossRatioInduOther;
                    investToOffice = MainDataStore.investRatioInduOther;
                    profitShare    = MainDataStore.profitShareRatioInduOther; break;

                case ItemClass.SubService.IndustrialGeneric:
                    if (building.Info.m_class.m_level == ItemClass.Level.Level1)
                    {
                        bossTake       = MainDataStore.bossRatioInduLevel1;
                        investToOffice = MainDataStore.investRatioInduLevel1;
                        profitShare    = MainDataStore.profitShareRatioInduLevel1;
                    }
                    else if (building.Info.m_class.m_level == ItemClass.Level.Level2)
                    {
                        bossTake       = MainDataStore.bossRatioInduLevel2;
                        investToOffice = MainDataStore.investRatioInduLevel2;
                        profitShare    = MainDataStore.profitShareRatioInduLevel2;
                    }
                    else
                    {
                        bossTake       = MainDataStore.bossRatioInduLevel3;
                        investToOffice = MainDataStore.investRatioInduLevel3;
                        profitShare    = MainDataStore.profitShareRatioInduLevel3;
                    }
                    break;

                case ItemClass.SubService.CommercialHigh:
                case ItemClass.SubService.CommercialLow:
                    if (building.Info.m_class.m_level == ItemClass.Level.Level1)
                    {
                        bossTake       = MainDataStore.bossRatioCommLevel1;
                        investToOffice = MainDataStore.investRatioCommLevel1;
                        profitShare    = MainDataStore.profitShareRatioCommLevel1;
                    }
                    else if (building.Info.m_class.m_level == ItemClass.Level.Level2)
                    {
                        bossTake       = MainDataStore.bossRatioCommLevel2;
                        investToOffice = MainDataStore.investRatioCommLevel2;
                        profitShare    = MainDataStore.profitShareRatioCommLevel2;
                    }
                    else
                    {
                        bossTake       = MainDataStore.bossRatioCommLevel3;
                        investToOffice = MainDataStore.investRatioCommLevel3;
                        profitShare    = MainDataStore.profitShareRatioCommLevel1;
                    }
                    break;

                case ItemClass.SubService.CommercialTourist:
                    bossTake       = MainDataStore.bossRatioCommTou;
                    investToOffice = MainDataStore.investRatioCommTou;
                    profitShare    = MainDataStore.profitShareRatioCommTou;
                    break;

                case ItemClass.SubService.CommercialLeisure:
                    bossTake       = MainDataStore.bossRatioCommOther;
                    investToOffice = MainDataStore.investRatioCommOther;
                    profitShare    = MainDataStore.profitShareRatioCommOther; break;

                case ItemClass.SubService.CommercialEco:
                    bossTake       = MainDataStore.bossRatioCommECO;
                    investToOffice = MainDataStore.investRatioCommECO;
                    profitShare    = MainDataStore.profitShareRatioCommECO; break;
                }
                // boss take and return to office
                if (BuildingData.buildingMoney[buildingID] > 0)
                {
                    //Reduce Boss fee
                    long investToOfficeFee = (long)(BuildingData.buildingMoney[buildingID] * investToOffice);
                    long bossTakeFee       = (long)(BuildingData.buildingMoney[buildingID] * bossTake);
                    if (building.Info.m_class.m_service == ItemClass.Service.Commercial)
                    {
                        //Commercial have help tourism
                        MainDataStore.outsideTouristMoney += ((bossTakeFee - investToOfficeFee) * MainDataStore.outsideCompanyProfitRatio * MainDataStore.outsideTouristSalaryProfitRatio);
                    }
                    RealCityPrivateBuildingAI.profitBuildingMoney += investToOfficeFee;
                    BuildingData.buildingMoney[buildingID]        -= bossTakeFee;
                }

                if (building.Info.m_class.m_service == ItemClass.Service.Office)
                {
                    float allOfficeWorker     = RealCityPrivateBuildingAI.allOfficeLevel1WorkCountFinal + RealCityPrivateBuildingAI.allOfficeLevel2WorkCountFinal + RealCityPrivateBuildingAI.allOfficeLevel3WorkCountFinal + RealCityPrivateBuildingAI.allOfficeHighTechWorkCountFinal;
                    float averageOfficeSalary = 0;
                    if (allOfficeWorker != 0)
                    {
                        averageOfficeSalary = (RealCityPrivateBuildingAI.profitBuildingMoneyFinal / allOfficeWorker);
                    }

                    if (building.Info.m_class.m_subService == ItemClass.SubService.OfficeGeneric)
                    {
                        if (building.Info.m_class.m_level == ItemClass.Level.Level1)
                        {
                            BuildingData.buildingMoney[buildingID] = averageOfficeSalary * totalWorkerCount * 0.6f;
                        }
                        else if (building.Info.m_class.m_level == ItemClass.Level.Level2)
                        {
                            BuildingData.buildingMoney[buildingID] = averageOfficeSalary * totalWorkerCount * 0.8f;
                        }
                        else if (building.Info.m_class.m_level == ItemClass.Level.Level3)
                        {
                            BuildingData.buildingMoney[buildingID] = averageOfficeSalary * totalWorkerCount * 1f;
                        }
                    }
                    else if (building.Info.m_class.m_subService == ItemClass.SubService.OfficeHightech)
                    {
                        BuildingData.buildingMoney[buildingID] = averageOfficeSalary * totalWorkerCount * 0.75f;
                    }

                    ProcessLandFeeOffice(building, buildingID, totalWorkerCount);
                }

                //Calculate building salary
                int buildingAsset = (int)(BuildingData.buildingMoney[buildingID] + building.m_customBuffer1 * RealCityIndustryBuildingAI.GetResourcePrice(RealCityPrivateBuildingAI.GetIncomingProductionType(buildingID, building)));
                int salary        = 0;
                if ((buildingAsset > 0) && (totalWorkerCount != 0))
                {
                    salary = (int)(buildingAsset * profitShare / totalWorkerCount);
                    switch (building.Info.m_class.m_subService)
                    {
                    case ItemClass.SubService.IndustrialFarming:
                    case ItemClass.SubService.IndustrialForestry:
                    case ItemClass.SubService.IndustrialOil:
                    case ItemClass.SubService.IndustrialOre:
                        salary = Math.Min(salary, MainDataStore.salaryInduOtherMax); break;

                    case ItemClass.SubService.IndustrialGeneric:
                        if (building.Info.m_class.m_level == ItemClass.Level.Level1)
                        {
                            salary = Math.Min(salary, MainDataStore.salaryInduLevel1Max);
                        }
                        else if (building.Info.m_class.m_level == ItemClass.Level.Level2)
                        {
                            salary = Math.Min(salary, MainDataStore.salaryInduLevel2Max);
                        }
                        else
                        {
                            salary = Math.Min(salary, MainDataStore.salaryInduLevel3Max);
                        }
                        break;

                    case ItemClass.SubService.CommercialHigh:
                    case ItemClass.SubService.CommercialLow:
                        if (building.Info.m_class.m_level == ItemClass.Level.Level1)
                        {
                            salary = Math.Min(salary, MainDataStore.salaryCommLevel1Max);
                        }
                        else if (building.Info.m_class.m_level == ItemClass.Level.Level2)
                        {
                            salary = Math.Min(salary, MainDataStore.salaryCommLevel2Max);
                        }
                        else
                        {
                            salary = Math.Min(salary, MainDataStore.salaryCommLevel3Max);
                        }
                        break;

                    case ItemClass.SubService.CommercialTourist:
                        salary = Math.Min(salary, MainDataStore.salaryCommTouMax); break;

                    case ItemClass.SubService.CommercialLeisure:
                        salary = Math.Min(salary, MainDataStore.salaryCommOtherMax); break;

                    case ItemClass.SubService.CommercialEco:
                        salary = Math.Min(salary, MainDataStore.salaryCommECOMax); break;
                    }
                }

                if (salary > 0)
                {
                    BuildingData.buildingWorkCount[buildingID] = salary;
                }
                else
                {
                    BuildingData.buildingWorkCount[buildingID] = 0;
                }
            }
            else
            {
                //resident building
                ItemClass                 @class             = building.Info.m_class;
                int                       incomeAccumulation = 0;
                DistrictManager           instance           = Singleton <DistrictManager> .instance;
                byte                      district           = instance.GetDistrict(building.m_position);
                DistrictPolicies.Taxation taxationPolicies   = instance.m_districts.m_buffer[district].m_taxationPolicies;
                if (@class.m_subService == ItemClass.SubService.ResidentialLow)
                {
                    switch (@class.m_level)
                    {
                    case ItemClass.Level.Level1:
                        incomeAccumulation = MainDataStore.residentLowLevel1Rent;
                        break;

                    case ItemClass.Level.Level2:
                        incomeAccumulation = MainDataStore.residentLowLevel2Rent;
                        break;

                    case ItemClass.Level.Level3:
                        incomeAccumulation = MainDataStore.residentLowLevel3Rent;
                        break;

                    case ItemClass.Level.Level4:
                        incomeAccumulation = MainDataStore.residentLowLevel4Rent;
                        break;

                    case ItemClass.Level.Level5:
                        incomeAccumulation = MainDataStore.residentLowLevel5Rent;
                        break;
                    }
                }
                else if (@class.m_subService == ItemClass.SubService.ResidentialLowEco)
                {
                    switch (@class.m_level)
                    {
                    case ItemClass.Level.Level1:
                        incomeAccumulation = MainDataStore.residentLowLevel1Rent;
                        break;

                    case ItemClass.Level.Level2:
                        incomeAccumulation = MainDataStore.residentLowLevel2Rent;
                        break;

                    case ItemClass.Level.Level3:
                        incomeAccumulation = MainDataStore.residentLowLevel3Rent;
                        break;

                    case ItemClass.Level.Level4:
                        incomeAccumulation = MainDataStore.residentLowLevel4Rent;
                        break;

                    case ItemClass.Level.Level5:
                        incomeAccumulation = MainDataStore.residentLowLevel5Rent;
                        break;
                    }
                }
                else if (@class.m_subService == ItemClass.SubService.ResidentialHigh)
                {
                    switch (@class.m_level)
                    {
                    case ItemClass.Level.Level1:
                        incomeAccumulation = MainDataStore.residentHighLevel1Rent;
                        break;

                    case ItemClass.Level.Level2:
                        incomeAccumulation = MainDataStore.residentHighLevel2Rent;
                        break;

                    case ItemClass.Level.Level3:
                        incomeAccumulation = MainDataStore.residentHighLevel3Rent;
                        break;

                    case ItemClass.Level.Level4:
                        incomeAccumulation = MainDataStore.residentHighLevel4Rent;
                        break;

                    case ItemClass.Level.Level5:
                        incomeAccumulation = MainDataStore.residentHighLevel5Rent;
                        break;
                    }
                }
                else
                {
                    switch (@class.m_level)
                    {
                    case ItemClass.Level.Level1:
                        incomeAccumulation = MainDataStore.residentHighLevel1Rent;
                        break;

                    case ItemClass.Level.Level2:
                        incomeAccumulation = MainDataStore.residentHighLevel2Rent;
                        break;

                    case ItemClass.Level.Level3:
                        incomeAccumulation = MainDataStore.residentHighLevel3Rent;
                        break;

                    case ItemClass.Level.Level4:
                        incomeAccumulation = MainDataStore.residentHighLevel4Rent;
                        break;

                    case ItemClass.Level.Level5:
                        incomeAccumulation = MainDataStore.residentHighLevel5Rent;
                        break;
                    }
                }
                int num2;
                num2 = Singleton <EconomyManager> .instance.GetTaxRate(@class, taxationPolicies);

                incomeAccumulation = (int)((num2 * incomeAccumulation) / 100f);
                BuildingData.buildingWorkCount[buildingID] = incomeAccumulation;
            }
        }
示例#19
0
        protected override void ProduceGoods(ushort buildingID, ref Building buildingData, ref Building.Frame frameData, int productionRate, int finalProductionRate, ref Citizen.BehaviourData behaviour, int aliveWorkerCount, int totalWorkerCount, int workPlaceCount, int aliveVisitorCount, int totalVisitorCount, int visitPlaceCount)
        {
            base.ProduceGoods(buildingID, ref buildingData, ref frameData, productionRate, finalProductionRate, ref behaviour, aliveWorkerCount, totalWorkerCount, workPlaceCount, aliveVisitorCount, totalVisitorCount, visitPlaceCount);
            int num = productionRate * m_deathCareAccumulation / 100;

            if (num != 0)
            {
                Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.DeathCare, num, buildingData.m_position, m_deathCareRadius);
            }
            if (finalProductionRate != 0)
            {
                int            num2     = buildingData.m_customBuffer1;
                int            num3     = (m_burialRate * finalProductionRate * 100 + m_corpseCapacity - 1) / m_corpseCapacity;
                CitizenManager instance = Singleton <CitizenManager> .instance;
                uint           num4     = buildingData.m_citizenUnits;
                int            num5     = 0;
                int            num6     = 0;
                int            num7     = 0;
                while (num4 != 0)
                {
                    uint nextUnit = instance.m_units.m_buffer[num4].m_nextUnit;
                    if ((instance.m_units.m_buffer[num4].m_flags & CitizenUnit.Flags.Visit) != 0)
                    {
                        for (int i = 0; i < 5; i++)
                        {
                            uint citizen = instance.m_units.m_buffer[num4].GetCitizen(i);
                            if (citizen != 0)
                            {
                                if (instance.m_citizens.m_buffer[citizen].Dead)
                                {
                                    if (instance.m_citizens.m_buffer[citizen].CurrentLocation == Citizen.Location.Visit)
                                    {
                                        if (Singleton <SimulationManager> .instance.m_randomizer.Int32(10000u) < num3)
                                        {
                                            instance.ReleaseCitizen(citizen);
                                            num7++;
                                            num2++;
                                        }
                                        else
                                        {
                                            num6++;
                                        }
                                    }
                                    else
                                    {
                                        num6++;
                                    }
                                }
                                else if (instance.m_citizens.m_buffer[citizen].Sick && instance.m_citizens.m_buffer[citizen].CurrentLocation == Citizen.Location.Visit)
                                {
                                    instance.m_citizens.m_buffer[citizen].Sick = false;
                                }
                            }
                        }
                    }
                    num4 = nextUnit;
                    if (++num5 > 524288)
                    {
                        CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                        break;
                    }
                }
                behaviour.m_deadCount += num6;
                if (m_graveCount == 0)
                {
                    for (int j = num7; j < num2; j++)
                    {
                        if (Singleton <SimulationManager> .instance.m_randomizer.Int32(10000u) < num3)
                        {
                            num7++;
                            num2--;
                        }
                        else
                        {
                            num6++;
                        }
                    }
                }
                buildingData.m_tempExport = (byte)Mathf.Min(buildingData.m_tempExport + num7, 255);
                DistrictManager instance2 = Singleton <DistrictManager> .instance;
                byte            district  = instance2.GetDistrict(buildingData.m_position);
                bool            flag      = IsFull(buildingID, ref buildingData);
                if (m_graveCount != 0)
                {
                    num2 = Mathf.Min(num2, m_graveCount);
                    buildingData.m_customBuffer1 = (ushort)num2;
                    instance2.m_districts.m_buffer[district].m_productionData.m_tempDeadAmount   += (uint)num2;
                    instance2.m_districts.m_buffer[district].m_productionData.m_tempDeadCapacity += (uint)m_graveCount;
                }
                else
                {
                    buildingData.m_customBuffer1 = (ushort)num2;
                    instance2.m_districts.m_buffer[district].m_productionData.m_tempCremateCapacity += (uint)m_corpseCapacity;
                }
                bool flag2 = IsFull(buildingID, ref buildingData);
                if (flag != flag2)
                {
                    if (flag2)
                    {
                        if ((object)m_fullPassMilestone != null)
                        {
                            m_fullPassMilestone.Unlock();
                        }
                    }
                    else if ((object)m_fullPassMilestone != null)
                    {
                        m_fullPassMilestone.Relock();
                    }
                }
                int count    = 0;
                int count2   = 0;
                int cargo    = 0;
                int capacity = 0;
                int outside  = 0;
                CalculateOwnVehicles(buildingID, ref buildingData, TransferManager.TransferReason.Dead, ref count, ref cargo, ref capacity, ref outside);
                CalculateGuestVehicles(buildingID, ref buildingData, TransferManager.TransferReason.DeadMove, ref count2, ref cargo, ref capacity, ref outside);
                int num8 = m_corpseCapacity - num6 - capacity;
                int num9 = (finalProductionRate * m_hearseCount + 99) / 100;
                if ((buildingData.m_flags & Building.Flags.Downgrading) != 0)
                {
                    if (m_graveCount != 0)
                    {
                        int count3    = 0;
                        int cargo2    = 0;
                        int capacity2 = 0;
                        int outside2  = 0;
                        CalculateOwnVehicles(buildingID, ref buildingData, TransferManager.TransferReason.DeadMove, ref count3, ref cargo2, ref capacity2, ref outside2);
                        if (num2 > 0 && count3 < num9)
                        {
                            TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                            offer.Priority = 7;
                            offer.Building = buildingID;
                            offer.Position = buildingData.m_position;
                            offer.Amount   = 1;
                            offer.Active   = true;
                            Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.DeadMove, offer);
                        }
                    }
                }
                else if (m_graveCount != 0)
                {
                    num8 = Mathf.Min(num8, m_graveCount - num2 - num6 - capacity + 9);
                    int num10 = num8 / 10;
                    if (count != 0)
                    {
                        num10--;
                    }
                    bool flag4 = num10 >= 1 && count < num9 && (num10 > 1);

                    if (flag4)
                    {
                        TransferManager.TransferOffer offer3 = default(TransferManager.TransferOffer);
                        offer3.Priority = 2 - count;
                        offer3.Building = buildingID;
                        offer3.Position = buildingData.m_position;
                        offer3.Amount   = 1;
                        offer3.Active   = true;
                        Singleton <TransferManager> .instance.AddIncomingOffer(TransferManager.TransferReason.Dead, offer3);
                    }

                    if (buildingData.m_customBuffer1 > (m_corpseCapacity * 2 / 3))
                    {
                        TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                        offer.Priority = 0;
                        offer.Building = buildingID;
                        offer.Position = buildingData.m_position;
                        offer.Amount   = 1;
                        offer.Active   = true;
                        Singleton <TransferManager> .instance.AddOutgoingOffer(TransferManager.TransferReason.DeadMove, offer);
                    }
                }
                else
                {
                    int  num11 = num8 / 10;
                    bool flag5 = num11 >= 1 && (num11 > 1 || count >= num9 || Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0);
                    bool flag6 = num11 >= 1 && count < num9 && (num11 > 1 || !flag5);
                    if (flag5)
                    {
                        TransferManager.TransferOffer offer4 = default(TransferManager.TransferOffer);
                        offer4.Priority = Mathf.Max(1, num8 * 6 / m_corpseCapacity);
                        offer4.Building = buildingID;
                        offer4.Position = buildingData.m_position;
                        offer4.Amount   = Mathf.Max(1, num11 - 1);
                        offer4.Active   = false;
                        Singleton <TransferManager> .instance.AddIncomingOffer(TransferManager.TransferReason.DeadMove, offer4);
                    }
                    if (flag6)
                    {
                        TransferManager.TransferOffer offer5 = default(TransferManager.TransferOffer);
                        offer5.Priority = 2 - count;
                        offer5.Building = buildingID;
                        offer5.Position = buildingData.m_position;
                        offer5.Amount   = 1;
                        offer5.Active   = true;
                        Singleton <TransferManager> .instance.AddIncomingOffer(TransferManager.TransferReason.Dead, offer5);
                    }
                }
            }
        }
        private static bool CalculateLocalResources(int x, int z, ushort[] buffer, int[] global, ushort[] target, int index)
        {
            //int num10 = ((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate1, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate3, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate2, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate4, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate5, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate6, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate7, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate8, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate12, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate10, 100, 500, 100, 200) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate17, 60, 100, 0, 50) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate16, 60, 100, 0, 50) - ImmaterialResourceManager.CalculateResourceEffect(100 - resourceRate17, 60, 100, 0, 50) - ImmaterialResourceManager.CalculateResourceEffect(100 - resourceRate16, 60, 100, 0, 50) - ImmaterialResourceManager.CalculateResourceEffect(num9, 50, (int)byte.MaxValue, 50, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate9, 10, 100, 0, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate15, 10, 100, 0, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate14, 50, 100, 10, 50) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate11, 15, 50, 100, 200) + (ImmaterialResourceManager.CalculateResourceEffect(resourceRate13, 33, 67, 300, 0) * Mathf.Max(0, 32 - num9) >> 5)) / 10 : 0;

            int   resourceRate1  = (int)buffer[index] + global[0];
            int   resourceRate2  = (int)buffer[index + 1] + global[1];
            int   resourceRate3  = (int)buffer[index + 2] + global[2];
            int   resourceRate4  = (int)buffer[index + 3] + global[3];
            int   resourceRate5  = (int)buffer[index + 4] + global[4];
            int   resourceRate6  = (int)buffer[index + 5] + global[5];
            int   resourceRate7  = (int)buffer[index + 6] + global[6];
            int   resourceRate8  = (int)buffer[index + 7] + global[7];
            int   resourceRate9  = (int)buffer[index + 8] + global[8];
            int   num1           = (int)buffer[index + 9] + global[9];
            int   num2           = (int)buffer[index + 10] + global[10];
            int   num3           = (int)buffer[index + 11] + global[11];
            int   num4           = (int)buffer[index + 12] + global[12];
            int   resourceRate10 = (int)buffer[index + 13] + global[13];
            int   num5           = (int)buffer[index + 14] + global[14];
            int   num6           = (int)buffer[index + 15] + global[15];
            int   num7           = (int)buffer[index + 16] + global[16];
            int   num8           = (int)buffer[index + 17] + global[17];
            int   resourceRate11 = (int)buffer[index + 18] + global[18];
            int   resourceRate12 = (int)buffer[index + 19] + global[19];
            Rect  area           = new Rect((float)(((double)x - 128.0 - 1.5) * 38.4000015258789), (float)(((double)z - 128.0 - 1.5) * 38.4000015258789), 153.6f, 153.6f);
            float groundPollution;
            float waterProximity;

            Singleton <NaturalResourceManager> .instance.AveragePollutionAndWater(area, out groundPollution, out waterProximity);

            int num9           = (int)((double)groundPollution * 100.0);
            int resourceRate13 = (int)((double)waterProximity * 100.0);

            if (resourceRate13 > 33 && resourceRate13 < 99)
            {
                area = new Rect((float)(((double)x - 128.0 + 0.25) * 38.4000015258789), (float)(((double)z - 128.0 + 0.25) * 38.4000015258789), 19.2f, 19.2f);
                Singleton <NaturalResourceManager> .instance.AveragePollutionAndWater(area, out groundPollution, out waterProximity);

                resourceRate13 = Mathf.Max(Mathf.Min(resourceRate13, (int)((double)waterProximity * 100.0)), 33);
            }
            int resourceRate14 = num8 * 2 / (resourceRate2 + 50);
            int resourceRate15;
            int resourceRate16;
            int resourceRate17;

            if (num4 == 0)
            {
                resourceRate15 = 0;
                resourceRate16 = 50;
                resourceRate17 = 50;
            }
            else
            {
                resourceRate15 = num1 / num4;
                resourceRate16 = num2 / num4;
                resourceRate17 = num3 / num4;
                num7          += Mathf.Min(num4, 10) * 10;
            }

            //Accessibility Grid Test Chamber
            float[,] grid3;
            //Now it calls every 256^2 steps
            //However, there are unexplained errors, and the ratings are never properly reached
            int num10 = 0;

            try
            {
                if (Tracker.CheckAccessibilityUpdate())
                {
                    grid3 = TrafficLog.CollectRatings();
                }
                else
                {
                    grid3 = TrafficLog.GetLastGrid();
                }
                float accessValue;
                try
                {
                    //Debug.Log("Attemping Grid Query. X: " + x + " . Z: " + z + ". + Value: " + grid3[x, z] + ".");
                    accessValue = grid3[x, z];
                }
                catch (IndexOutOfRangeException e)
                {
                    accessValue = 0;
                }
                catch (NullReferenceException e)
                {
                    accessValue = 0;
                }
                //Debug.Log("X: " + x + " Z: " + z + "AccessValue: " + accessValue);
                num10 = (int)accessValue;
            }
            catch (NullReferenceException e)
            {
                num10 = 0;
            }

            //num10 Notes

            /*
             * HealthCare = 0,                 * Yes
             * FireDepartment = 1,             * Yes
             * PoliceDepartment = 2,           * Yes
             * EducationElementary = 3,        * Yes
             * EducationHighSchool = 4,        * Yes
             * EducationUniversity = 5,        * Yes
             * DeathCare = 6,                  * Yes
             * PublicTransport = 7,            * Yes / Imperfect
             * NoisePollution = 8,             * Yes
             * CrimeRate = 9,                  * Yes
             * Health = 10,                    * Yes
             * Wellbeing = 11,                 * Ambiguous
             * Density = 12,                   * Ambiguous
             * Entertainment = 13,             * Yes
             * LandValue = 14,                 * Ambiguous
             * Attractiveness = 15,            * Global
             * Coverage = 16,                  * Ambiguous
             * FireHazard = 17,                * Useless
             * Abandonment = 18,               * X
             * CargoTransport = 19,            * Yes
             *
             * Ground Pollution                * Yes
             * Water Proximity                 * Yes
             */

            ////////////////////num10 Test Chamber///////////////

            //Water Proximity - Needs scaling
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(Math.Sqrt(waterProximity))*20) : 0);

            //Ground Pollution - Needs scaling
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(groundPollution) * 10) : 0);

            //Wellbeing - Needs scaling
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(num3) * 2) : 0);

            //Density
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(num4) * 10) : 0);

            //Land Value???
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(num5) * 1) : 0);

            //Attractiveness - Either broken or a totally global variable that provides city-wide bonuses?
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(buffer[index + 15]) * 1) : 0);

            //Coverage - Unclear but it seems to matter when building become inhabited
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(num7) * 1) : 0);

            //Fire Hazard - Even water towers set this off.
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(num8) * 1) : 0);

            //Abandonment
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (Convert.ToInt32(resourceRate11) * 1) : 0);

            //////////////////////////Num10/////////////////////////////
            //Original

            //int num10 = ((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate1, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate3, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate2, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate4, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate5, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate6, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate7, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate8, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate12, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate10, 100, 500, 100, 200) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate17, 60, 100, 0, 50) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate16, 60, 100, 0, 50) - ImmaterialResourceManager.CalculateResourceEffect(100 - resourceRate17, 60, 100, 0, 50) - ImmaterialResourceManager.CalculateResourceEffect(100 - resourceRate16, 60, 100, 0, 50) - ImmaterialResourceManager.CalculateResourceEffect(num9, 50, (int)byte.MaxValue, 50, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate9, 10, 100, 0, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate15, 10, 100, 0, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate14, 50, 100, 10, 50) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate11, 15, 50, 100, 200) + (ImmaterialResourceManager.CalculateResourceEffect(resourceRate13, 33, 67, 300, 0) * Mathf.Max(0, 32 - num9) >> 5)) / 10 : 0;

            //Add arbirary value

            if (((x % 2 == 1) & (z % 2 == 1)))
            {
                Vector3         m_vector3 = new Vector3((Convert.ToInt32(x * 38.4000015258789)) - 4915, 0, (Convert.ToInt32(z * 38.4000015258789) - 4915));
                DistrictManager DM        = Singleton <DistrictManager> .instance;
                byte            m_byte    = DM.GetDistrict(m_vector3);
                string          m_name    = DM.GetDistrictName(m_byte); //Full Name

                //Solve Single Operator Crash
                if ((m_name.Length == 1) & ((m_name.EndsWith("+") | m_name.EndsWith("-")) | (m_name.EndsWith("*") | m_name.EndsWith("/"))))
                {
                    Singleton <ChirpPanel> .instance.AddMessage(new ChirpMessage("System", "Invalid Syntax: Cannot Pass Single Operator Token"));

                    DM.StartCoroutine(DM.SetDistrictName(m_byte, null));
                }
                else
                {
                    string m_lastvalidname;
                    m_lastvalidname = m_name;
                    string m_realname        = m_name;                                         //Real Name
                    string m_operator        = Tracker.GetOperator(m_byte);                    //Operator
                    string m_deltaS          = "";                                             //Value String
                    double m_deltaD          = 0;                                              //Value Number
                    string m_currentOperator = Tracker.GetOperator(m_byte);
                    double m_CurrentValue    = Convert.ToDouble(Tracker.GetLandValue(m_byte)); //Set current operator
                    num10 = Convert.ToInt32(m_CurrentValue);
                    if ((m_name.EndsWith("+") | m_name.EndsWith("-")) | (m_name.EndsWith("*") | m_name.EndsWith("/")))
                    {
                        num10 = 0;
                        Tracker.SetOperator(m_byte, m_name.Substring(m_name.Length - 1)); //Set new operator
                        m_operator = Tracker.GetOperator(m_byte);                         // Get Operator
                        try
                        {
                            m_deltaS = getSubstring(m_name.Substring(0, m_name.Length - 1));    //Get the Value
                        }
                        catch (ArgumentOutOfRangeException e)
                        {
                            m_deltaS = "0";
                        }
                        try
                        {
                            m_deltaD = Convert.ToDouble(m_deltaS);
                        }
                        catch (FormatException e2)
                        {
                            m_deltaD = 0;
                        }

                        if (!((m_name.Length - (m_deltaS.Length + 1)) < 0))
                        {
                            m_realname = m_name.Substring(0, (m_name.Length - (m_deltaS.Length + 1)));  //Get name without value and operator
                        }
                        while (m_realname.EndsWith(" "))
                        {
                            m_realname = m_realname.Substring(0, m_realname.Length - 1);   //Remove extra spaces from end
                        }
                        while (m_realname.StartsWith(" "))
                        {
                            m_realname = m_realname.Substring(1, m_realname.Length);    //Remove extra spaces from start
                        }
                        while (((m_realname.EndsWith("+") | m_realname.EndsWith("-")) | (m_realname.EndsWith("*") | m_realname.EndsWith("/"))))
                        {
                            if (m_realname.Length > 1)
                            {
                                m_realname = m_realname.Substring(0, m_realname.Length - 1);   //Remove extra operators
                            }
                        }
                        if (!((m_realname.EndsWith("+") | m_realname.EndsWith("-")) | (m_realname.EndsWith("*") | m_realname.EndsWith("/"))))
                        {
                            DM.StartCoroutine(DM.SetDistrictName(m_byte, m_realname));      // Rename District
                        }
                        else
                        {
                            if (m_realname.IsNullOrWhiteSpace())
                            {
                                DM.StartCoroutine(DM.SetDistrictName(m_byte, m_lastvalidname));
                            }
                            else //Not null but ends in an operator
                            {
                                DM.StartCoroutine(DM.SetDistrictName(m_byte, m_lastvalidname));
                            }
                        }
                        Tracker.SetLandValue(m_byte, m_deltaS);                         //Assign number to Array
                    }
                    else
                    {
                        m_operator = " ";
                    }
                    m_currentOperator = Tracker.GetOperator(m_byte);        //Reassign operator

                    string landModifier = Tracker.GetLandValue(m_byte);

                    if (m_operator.EndsWith("+"))
                    {
                        num10 = Mathf.Clamp(Convert.ToInt32(num10 + Convert.ToDouble(landModifier)), 0, ushort.MaxValue);       //  + current or new value to num10
                    }
                    else if (m_operator.EndsWith("-"))
                    {
                        num10 = Mathf.Clamp(Convert.ToInt32(num10 - Convert.ToDouble(landModifier)), 0, ushort.MaxValue);       //  - current or new value to num10
                    }
                    else if (m_operator.EndsWith("*"))
                    {
                        num10 = Mathf.Clamp(Convert.ToInt32(num10 * Convert.ToDouble(landModifier)), 0, ushort.MaxValue);       //  * current or new value to num10
                    }
                    else if (m_operator.EndsWith("/"))
                    {
                        try
                        {
                            num10 = Mathf.Clamp(Convert.ToInt32(num10 / Convert.ToDouble(landModifier)), 0, ushort.MaxValue);   //  / current or new value to num10
                        }
                        catch (DivideByZeroException e4) { }
                    }
                    Tracker.SetLandValue(m_byte, Convert.ToString(num10));
                }
            }

            //ResourceRate1 = Medicine
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate1, 1, 2, 1, 1000) >> 5) / 10 : 0);

            //ResourceRate2 = Fire Protection
            //num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate2, 1, 1000, 1, 3000) >> 5) / 1 : 0);

            //ResourceRate3 = Police Protection
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate3, 1, 2, 1, 1000) >> 5) / 10 : 0);

            //ResourceRate4 = Elementary
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate4, 1, 2, 1, 1000) >> 5) / 10 : 0);

            //ResourceRate5 = High School
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate5, 1, 2, 1, 1000) >> 5) / 10 : 0);

            //ResourceRate6 = College
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate6, 1, 2, 1, 1000) >> 5) / 10 : 0);

            //ResourceRate7 = Deathcare
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate7, 1, 2, 1, 1000) >> 5) / 10 : 0);

            //ResourceRate8 = Public Transport
            //num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate8, 1, 1000, 1, 3000) >> 5) / 1 : 0);

            //ResourceRate9 = NoisePollition
            //num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate9, 1, 2, 1, 1000) >> 5) / 1 : 0);

            //ResourceRate10 = Entertainment
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate10, 1, 500, 1, 3000) >> 5) / 10 : 0);

            //ResourceRate11 = -? (Abandonment (R))
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate11, 1, 2, 1, 1000) >> 5) / 10 : 0);

            //ResourceRate12 = Cargo Transport
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate12, 1, 2, 1, 1000) >> 5) / 10 : 0);

            //ResourceRate13 = Proximity to Water and Pollution
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate13, 1, 2, 1, 1000) >> 5) / 10 : 0);

            //ResourceRate14 = FireHazard over Fire Protection? (R) - Water and shoreline confirmed add value.
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate14, 1, 2, 1, 1000) >> 5) / 10 : 0);

            //ResourceRate15 = If Density=0 then 0, otherwise its Crime Rate divided by density? (R)
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate15, 1, 2, 1, 1000) >> 5) / 10 : 0);

            //ResourceRate16 = Starts at a positive value, reduced by public buildings. If Density = 0 then 50, otherwise its health divided by density? (R)
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate16, 1, 2, 1, 1000) >> 5) / 10 : 0);

            //ResourceRate17 = If Density= 0 then 50, otherwise Wellbeing deivided by density? (R)
            //int num10 = (((Singleton<GameAreaManager>.instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= 254 || z <= 1 ? 1 : (z >= 254 ? 1 : 0))) == 0 ? (num5 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate17, 1, 2, 1, 1000) >> 5) / 10 : 0);

            /* 1. Yes
             * 2. Yes
             * 3. Yes
             * 4. Yes
             * 5. Yes
             * 6. Yes
             * 7. Yes
             * 8. Yes but imperfect
             * 9. Yes
             * 10. Yes
             * 11. Unproven
             * 12. Yes
             * 13. Yes
             * 14. Inconsistent
             * 15. Yes but uncertain
             * 16. Yes but weird
             * 17. Various buildings have effect, weird
             */
            //End

            int num11 = Mathf.Clamp(resourceRate1, 0, (int)ushort.MaxValue);
            int num12 = Mathf.Clamp(resourceRate2, 0, (int)ushort.MaxValue);
            int num13 = Mathf.Clamp(resourceRate3, 0, (int)ushort.MaxValue);
            int num14 = Mathf.Clamp(resourceRate4, 0, (int)ushort.MaxValue);
            int num15 = Mathf.Clamp(resourceRate5, 0, (int)ushort.MaxValue);
            int num16 = Mathf.Clamp(resourceRate6, 0, (int)ushort.MaxValue);
            int num17 = Mathf.Clamp(resourceRate7, 0, (int)ushort.MaxValue);
            int num18 = Mathf.Clamp(resourceRate8, 0, (int)ushort.MaxValue);
            int num19 = Mathf.Clamp(resourceRate9, 0, (int)ushort.MaxValue);
            int num20 = Mathf.Clamp(resourceRate15, 0, (int)ushort.MaxValue);
            int num21 = Mathf.Clamp(resourceRate16, 0, (int)ushort.MaxValue);
            int num22 = Mathf.Clamp(resourceRate17, 0, (int)ushort.MaxValue);
            int num23 = Mathf.Clamp(num4, 0, (int)ushort.MaxValue);
            int num24 = Mathf.Clamp(resourceRate10, 0, (int)ushort.MaxValue);

            /////////////////////////////////Clamp Land Value//////////////////////////////
            //Landvalue comes from num10
            //Original
            //int landvalue = Mathf.Clamp(num10, 0, (int)ushort.MaxValue);
            //Test
            int             landvalue = Mathf.Clamp(num10, 0, (int)ushort.MaxValue);
            int             num25     = Mathf.Clamp(num6, 0, (int)ushort.MaxValue);
            int             coverage  = Mathf.Clamp(num7, 0, (int)ushort.MaxValue);
            int             num26     = Mathf.Clamp(resourceRate14, 0, (int)ushort.MaxValue);
            int             num27     = Mathf.Clamp(resourceRate11, 0, (int)ushort.MaxValue);
            int             num28     = Mathf.Clamp(resourceRate12, 0, (int)ushort.MaxValue);
            DistrictManager instance  = Singleton <DistrictManager> .instance;
            byte            district  = instance.GetDistrict(x * 2, z * 2);

            /////////////////////////////////Apply to District//////////////////////////////
            //Districts have landvalue, pollution and coverage. num9 refers to ground pollution, coverage
            //has something to do with num7. The method assigns templandvalue, temppollution and tempcoverage.
            //The first two are the inputs * coverage, tempcoverage is simply coverage.
            instance.m_districts.m_buffer[(int)district].AddGroundData(landvalue, num9, coverage);

            bool flag = false;

            if (num11 != (int)target[index])
            {
                target[index] = (ushort)num11;
                flag          = true;
            }
            if (num12 != (int)target[index + 1])
            {
                target[index + 1] = (ushort)num12;
                flag = true;
            }
            if (num13 != (int)target[index + 2])
            {
                target[index + 2] = (ushort)num13;
                flag = true;
            }
            if (num14 != (int)target[index + 3])
            {
                target[index + 3] = (ushort)num14;
                flag = true;
            }
            if (num15 != (int)target[index + 4])
            {
                target[index + 4] = (ushort)num15;
                flag = true;
            }
            if (num16 != (int)target[index + 5])
            {
                target[index + 5] = (ushort)num16;
                flag = true;
            }
            if (num17 != (int)target[index + 6])
            {
                target[index + 6] = (ushort)num17;
                flag = true;
            }
            if (num18 != (int)target[index + 7])
            {
                target[index + 7] = (ushort)num18;
                flag = true;
            }
            if (num19 != (int)target[index + 8])
            {
                target[index + 8] = (ushort)num19;
                flag = true;
            }
            if (num20 != (int)target[index + 9])
            {
                target[index + 9] = (ushort)num20;
                flag = true;
            }
            if (num21 != (int)target[index + 10])
            {
                target[index + 10] = (ushort)num21;
                flag = true;
            }
            if (num22 != (int)target[index + 11])
            {
                target[index + 11] = (ushort)num22;
                flag = true;
            }
            if (num23 != (int)target[index + 12])
            {
                target[index + 12] = (ushort)num23;
                flag = true;
            }
            if (num24 != (int)target[index + 13])
            {
                target[index + 13] = (ushort)num24;
                flag = true;
            }

            ///////////////////////////////Flag///////////////////////
            //What this means is unceertain, flag is a bool returned. If a condition is met
            //then it is true, otherwise false. This probably does not matter.
            if (landvalue != (int)target[index + 14])
            {
                target[index + 14] = (ushort)landvalue;
                flag = true;
            }
            if (num25 != (int)target[index + 15])
            {
                target[index + 15] = (ushort)num25;
                flag = true;
            }
            if (coverage != (int)target[index + 16])
            {
                target[index + 16] = (ushort)coverage;
                flag = true;
            }
            if (num26 != (int)target[index + 17])
            {
                target[index + 17] = (ushort)num26;
                flag = true;
            }
            if (num27 != (int)target[index + 18])
            {
                target[index + 18] = (ushort)num27;
                flag = true;
            }
            if (num28 != (int)target[index + 19])
            {
                target[index + 19] = (ushort)num28;
                flag = true;
            }
            return(flag);
        }
示例#21
0
        new int HandleCommonConsumption(ushort buildingID, ref Building data, ref int electricityConsumption, ref int heatingConsumption, ref int waterConsumption, ref int sewageAccumulation, ref int garbageAccumulation, DistrictPolicies.Services policies)
        {
            int             num      = 100;
            DistrictManager instance = Singleton <DistrictManager> .instance;

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

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

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

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

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

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

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

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

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

            instance.m_districts.m_buffer[(int)district].AddUsageData(electricityUsage, heatingUsage, waterUsage, sewageUsage);
            data.m_problems = problem;
            return(num);
        }
        protected override void ProduceGoods(ushort buildingID, ref Building buildingData, ref Building.Frame frameData, int productionRate, ref Citizen.BehaviourData behaviour, int aliveWorkerCount, int totalWorkerCount, int workPlaceCount, int aliveVisitorCount, int totalVisitorCount, int visitPlaceCount)
        {
            bool flag = false;

            if (buildingData.m_netNode != 0)
            {
                NetManager instance = NetManager.instance;
                for (int i = 0; i < 8; i++)
                {
                    if (instance.m_nodes.m_buffer[(int)buildingData.m_netNode].GetSegment(i) != 0)
                    {
                        flag = true;
                        break;
                    }
                }
            }
            if (!flag)
            {
                productionRate = 0;
            }
            DistrictManager instance2 = Singleton <DistrictManager> .instance;
            byte            district  = instance2.GetDistrict(buildingData.m_position);

            int waterProdMp = m_waterConsumption * m_consumption_multiplier;



            int waterRate = waterProdMp;

            //Debug.Log("Produce goods");
            //Debug.Log("waterRate      = " + waterRate);
            //Debug.Log("productionRate = " + productionRate);

            if (waterRate != 0)
            {
                int bufferedWater = (int)(buildingData.m_waterBuffer * m_bufferMultiplier);

                //Debug.Log("bufferedWater = " + bufferedWater);

                int missingWater = waterRate * 10 - bufferedWater;

                //Debug.Log("missingWater = " + missingWater);

                if (missingWater > 0)
                {
                    byte pollution    = 0;
                    int  fetchedWater = WaterManager.instance.TryFetchWater(buildingData.m_position, missingWater, missingWater, ref pollution);

                    if (buildingData.m_productionRate < 100)
                    {
                        int fetchedWater2 = WaterManager.instance.TryFetchWater(buildingData.m_position, missingWater / 2, missingWater / 2, ref pollution);

                        if (fetchedWater2 > 0)
                        {
                            if (buildingData.m_productionRate + 3 <= 100)
                            {
                                buildingData.m_productionRate += 3;
                            }
                        }
                    }


                    //Debug.Log("fetchedWater = " + fetchedWater);

                    bufferedWater += fetchedWater;
                }



                int waterFinalRate = waterRate * productionRate / 100;

                if (bufferedWater - waterFinalRate > 0)
                {
                    //Debug.Log("dumping water");
                    bufferedWater -= waterFinalRate;

                    // Dump water to env
                    this.HandleWaterSource(buildingID, ref buildingData, true, waterFinalRate, waterFinalRate, this.m_maxWaterDistance);
                }

                //if (bufferedWater - waterFinalRate * 4 > 0)
                //{
                //    if (buildingData.m_productionRate + 3 <= 100)
                //        buildingData.m_productionRate += 3;
                //}

                if (bufferedWater - waterFinalRate * 4 < 0)
                {
                    if (buildingData.m_productionRate > 3)
                    {
                        buildingData.m_productionRate -= 3;
                    }
                }

                // Decrease buffer
                buildingData.m_waterBuffer = (ushort)((bufferedWater) / m_bufferMultiplier);


                //Debug.Log("m_waterBuffer =" + bufferedWater);

                DistrictManager.instance.m_districts.m_buffer[district].m_playerConsumption.m_tempWaterConsumption += (uint)waterRate;
            }


            base.HandleDead(buildingID, ref buildingData, ref behaviour, totalWorkerCount);
            int noiseRate = productionRate * this.m_noiseAccumulation / 100;

            if (noiseRate != 0)
            {
                Singleton <ImmaterialResourceManager> .instance.AddResource(ImmaterialResourceManager.Resource.NoisePollution, noiseRate, buildingData.m_position, this.m_noiseRadius);
            }
            base.ProduceGoods(buildingID, ref buildingData, ref frameData, productionRate, ref behaviour, aliveWorkerCount, totalWorkerCount, workPlaceCount, aliveVisitorCount, totalVisitorCount, visitPlaceCount);
        }
示例#23
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);
        }
示例#24
0
        // Detours

        public static void SimulationStep(ref ZoneBlock zoneBlock, ushort blockID)
        {
            // This is the decompiled ZoneBlock.SimulationStep() method
            // Segments which were changed are marked with "begin mod" and "end mod"

            if (Debugger.Enabled && debugCount < 10)
            {
                debugCount++;
                Debugger.LogFormat("Building Themes: Detoured ZoneBlock.SimulationStep was called. blockID: {0}, position: {1}.", blockID, zoneBlock.m_position);
            }

            ZoneManager zoneManager = Singleton <ZoneManager> .instance;
            int         rowCount    = zoneBlock.RowCount;
            float       m_angle     = zoneBlock.m_angle;

            Vector2 xDirection    = new Vector2(Mathf.Cos(m_angle), Mathf.Sin(m_angle)) * 8f;
            Vector2 zDirection    = new Vector2(xDirection.y, -xDirection.x);
            ulong   num           = zoneBlock.m_valid & ~(zoneBlock.m_occupied1 | zoneBlock.m_occupied2);
            int     spawnpointRow = 0;

            ItemClass.Zone zone = ItemClass.Zone.Unzoned;
            int            num3 = 0;

            while (num3 < 4 && zone == ItemClass.Zone.Unzoned)
            {
                spawnpointRow = Singleton <SimulationManager> .instance.m_randomizer.Int32((uint)rowCount);

                if ((num & 1uL << (spawnpointRow << 3)) != 0uL)
                {
                    zone = zoneBlock.GetZone(0, spawnpointRow);
                }
                num3++;
            }
            DistrictManager instance2 = Singleton <DistrictManager> .instance;

            Vector3 m_position = (Vector3)zoneBlock.m_position;

            byte district = instance2.GetDistrict(m_position);
            int  num4;

            switch (zone)
            {
            case ItemClass.Zone.ResidentialLow:
                num4  = zoneManager.m_actualResidentialDemand;
                num4 += instance2.m_districts.m_buffer[(int)district].CalculateResidentialLowDemandOffset();
                break;

            case ItemClass.Zone.ResidentialHigh:
                num4  = zoneManager.m_actualResidentialDemand;
                num4 += instance2.m_districts.m_buffer[(int)district].CalculateResidentialHighDemandOffset();
                break;

            case ItemClass.Zone.CommercialLow:
                num4  = zoneManager.m_actualCommercialDemand;
                num4 += instance2.m_districts.m_buffer[(int)district].CalculateCommercialLowDemandOffset();
                break;

            case ItemClass.Zone.CommercialHigh:
                num4  = zoneManager.m_actualCommercialDemand;
                num4 += instance2.m_districts.m_buffer[(int)district].CalculateCommercialHighDemandOffset();
                break;

            case ItemClass.Zone.Industrial:
                num4  = zoneManager.m_actualWorkplaceDemand;
                num4 += instance2.m_districts.m_buffer[(int)district].CalculateIndustrialDemandOffset();
                break;

            case ItemClass.Zone.Office:
                num4  = zoneManager.m_actualWorkplaceDemand;
                num4 += instance2.m_districts.m_buffer[(int)district].CalculateOfficeDemandOffset();
                break;

            default:
                return;
            }
            Vector2 a       = VectorUtils.XZ(m_position);
            Vector2 vector3 = a - 3.5f * xDirection + ((float)spawnpointRow - 3.5f) * zDirection;

            int[] tmpXBuffer = zoneManager.m_tmpXBuffer;
            for (int i = 0; i < 13; i++)
            {
                tmpXBuffer[i] = 0;
            }

            Quad2 quad = default(Quad2);

            quad.a = a - 4f * xDirection + ((float)spawnpointRow - 10f) * zDirection;
            quad.b = a + 3f * xDirection + ((float)spawnpointRow - 10f) * zDirection;
            quad.c = a + 3f * xDirection + ((float)spawnpointRow + 2f) * zDirection;
            quad.d = a - 4f * xDirection + ((float)spawnpointRow + 2f) * zDirection;
            Vector2 vector4 = quad.Min();
            Vector2 vector5 = quad.Max();

            //begin mod
            int num5 = Mathf.Max((int)((vector4.x - 46f) / 64f + _zoneGridHalfResolution), 0);
            int num6 = Mathf.Max((int)((vector4.y - 46f) / 64f + _zoneGridHalfResolution), 0);
            int num7 = Mathf.Min((int)((vector5.x + 46f) / 64f + _zoneGridHalfResolution), _zoneGridResolution - 1);
            int num8 = Mathf.Min((int)((vector5.y + 46f) / 64f + _zoneGridHalfResolution), _zoneGridResolution - 1);

            //end mod
            for (int j = num6; j <= num8; j++)
            {
                for (int k = num5; k <= num7; k++)
                {
                    //begin mod
                    ushort num9 = zoneManager.m_zoneGrid[j * _zoneGridResolution + k];
                    //end mod
                    int num10 = 0;
                    while (num9 != 0)
                    {
                        Vector3 positionVar = zoneManager.m_blocks.m_buffer[(int)num9].m_position;
                        float   num11       = Mathf.Max(Mathf.Max(vector4.x - 46f - positionVar.x, vector4.y - 46f - positionVar.z),
                                                        Mathf.Max(positionVar.x - vector5.x - 46f, positionVar.z - vector5.y - 46f));

                        if (num11 < 0f)
                        {
                            _CheckBlock.Invoke(zoneBlock, new object[] { zoneManager.m_blocks.m_buffer[(int)num9], tmpXBuffer, zone, vector3, xDirection, zDirection, quad });
                        }
                        num9 = zoneManager.m_blocks.m_buffer[(int)num9].m_nextGridBlock;
                        if (++num10 >= 49152)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
            }

            for (int l = 0; l < 13; l++)
            {
                uint num12 = (uint)tmpXBuffer[l];
                int  num13 = 0;
                bool flag  = (num12 & 196608u) == 196608u;
                bool flag2 = false;
                while ((num12 & 1u) != 0u)
                {
                    num13++;
                    flag2   = ((num12 & 65536u) != 0u);
                    num12 >>= 1;
                }
                if (num13 == 5 || num13 == 6)
                {
                    if (flag2)
                    {
                        num13 -= Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) + 2;
                    }
                    else
                    {
                        num13 = 4;
                    }
                    num13 |= 131072;
                }
                else if (num13 == 7)
                {
                    num13  = 4;
                    num13 |= 131072;
                }
                if (flag)
                {
                    num13 |= 65536;
                }
                tmpXBuffer[l] = num13;
            }
            int num14 = tmpXBuffer[6] & 65535;

            if (num14 == 0)
            {
                return;
            }

            bool flag3 = (bool)_IsGoodPlace.Invoke(zoneBlock, new object[] { vector3 });

            if (Singleton <SimulationManager> .instance.m_randomizer.Int32(100u) >= num4)
            {
                if (flag3)
                {
                    zoneManager.m_goodAreaFound[(int)zone] = 1024;
                }
                return;
            }
            if (!flag3 && zoneManager.m_goodAreaFound[(int)zone] > -1024)
            {
                if (zoneManager.m_goodAreaFound[(int)zone] == 0)
                {
                    zoneManager.m_goodAreaFound[(int)zone] = -1;
                }
                return;
            }
            int  num15 = 6;
            int  num16 = 6;
            bool flag4 = true;

            while (true)
            {
                if (flag4)
                {
                    while (num15 != 0)
                    {
                        if ((tmpXBuffer[num15 - 1] & 65535) != num14)
                        {
                            break;
                        }
                        num15--;
                    }
                    while (num16 != 12)
                    {
                        if ((tmpXBuffer[num16 + 1] & 65535) != num14)
                        {
                            break;
                        }
                        num16++;
                    }
                }
                else
                {
                    while (num15 != 0)
                    {
                        if ((tmpXBuffer[num15 - 1] & 65535) < num14)
                        {
                            break;
                        }
                        num15--;
                    }
                    while (num16 != 12)
                    {
                        if ((tmpXBuffer[num16 + 1] & 65535) < num14)
                        {
                            break;
                        }
                        num16++;
                    }
                }
                int num17 = num15;
                int num18 = num16;
                while (num17 != 0)
                {
                    if ((tmpXBuffer[num17 - 1] & 65535) < 2)
                    {
                        break;
                    }
                    num17--;
                }
                while (num18 != 12)
                {
                    if ((tmpXBuffer[num18 + 1] & 65535) < 2)
                    {
                        break;
                    }
                    num18++;
                }
                bool flag5 = num17 != 0 && num17 == num15 - 1;
                bool flag6 = num18 != 12 && num18 == num16 + 1;
                if (flag5 && flag6)
                {
                    if (num16 - num15 > 2)
                    {
                        break;
                    }
                    if (num14 <= 2)
                    {
                        if (!flag4)
                        {
                            goto Block_34;
                        }
                    }
                    else
                    {
                        num14--;
                    }
                }
                else if (flag5)
                {
                    if (num16 - num15 > 1)
                    {
                        goto Block_36;
                    }
                    if (num14 <= 2)
                    {
                        if (!flag4)
                        {
                            goto Block_38;
                        }
                    }
                    else
                    {
                        num14--;
                    }
                }
                else if (flag6)
                {
                    if (num16 - num15 > 1)
                    {
                        goto Block_40;
                    }
                    if (num14 <= 2)
                    {
                        if (!flag4)
                        {
                            goto Block_42;
                        }
                    }
                    else
                    {
                        num14--;
                    }
                }
                else
                {
                    if (num15 != num16)
                    {
                        goto IL_884;
                    }
                    if (num14 <= 2)
                    {
                        if (!flag4)
                        {
                            goto Block_45;
                        }
                    }
                    else
                    {
                        num14--;
                    }
                }
                flag4 = false;
            }
            num15++;
            num16--;
Block_34:
            goto IL_891;
Block_36:
            num15++;
Block_38:
            goto IL_891;
Block_40:
            num16--;
Block_42:
Block_45:
IL_884:
IL_891:
            int num19;
            int num20;

            if (num14 == 1 && num16 - num15 >= 1)
            {
                num15 += Singleton <SimulationManager> .instance.m_randomizer.Int32((uint)(num16 - num15));

                num16 = num15 + 1;
                num19 = num15 + Singleton <SimulationManager> .instance.m_randomizer.Int32(2u);

                num20 = num19;
            }
            else
            {
                do
                {
                    num19 = num15;
                    num20 = num16;
                    if (num16 - num15 == 2)
                    {
                        if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0)
                        {
                            num20--;
                        }
                        else
                        {
                            num19++;
                        }
                    }
                    else if (num16 - num15 == 3)
                    {
                        if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0)
                        {
                            num20 -= 2;
                        }
                        else
                        {
                            num19 += 2;
                        }
                    }
                    else if (num16 - num15 == 4)
                    {
                        if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0)
                        {
                            num16 -= 2;
                            num20 -= 3;
                        }
                        else
                        {
                            num15 += 2;
                            num19 += 3;
                        }
                    }
                    else if (num16 - num15 == 5)
                    {
                        if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0)
                        {
                            num16 -= 3;
                            num20 -= 2;
                        }
                        else
                        {
                            num15 += 3;
                            num19 += 2;
                        }
                    }
                    else if (num16 - num15 >= 6)
                    {
                        if (num15 == 0 || num16 == 12)
                        {
                            if (num15 == 0)
                            {
                                num15 = 3;
                                num19 = 2;
                            }
                            if (num16 == 12)
                            {
                                num16 = 9;
                                num20 = 10;
                            }
                        }
                        else if (Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0)
                        {
                            num16 = num15 + 3;
                            num20 = num19 + 2;
                        }
                        else
                        {
                            num15 = num16 - 3;
                            num19 = num20 - 2;
                        }
                    }
                }while (num16 - num15 > 3 || num20 - num19 > 3);
            }
            int depth_A = 4;
            int width_A = num16 - num15 + 1;

            BuildingInfo.ZoningMode zoningMode = BuildingInfo.ZoningMode.Straight;
            bool flag7 = true;

            for (int m = num15; m <= num16; m++)
            {
                depth_A = Mathf.Min(depth_A, tmpXBuffer[m] & 65535);
                if ((tmpXBuffer[m] & 131072) == 0)
                {
                    flag7 = false;
                }
            }
            if (num16 > num15)
            {
                if ((tmpXBuffer[num15] & 65536) != 0)
                {
                    zoningMode = BuildingInfo.ZoningMode.CornerLeft;
                    num20      = num15 + num20 - num19;
                    num19      = num15;
                }
                if ((tmpXBuffer[num16] & 65536) != 0 && (zoningMode != BuildingInfo.ZoningMode.CornerLeft || Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0))
                {
                    zoningMode = BuildingInfo.ZoningMode.CornerRight;
                    num19      = num16 + num19 - num20;
                    num20      = num16;
                }
            }
            int depth_B = 4;
            int width_B = num20 - num19 + 1;

            BuildingInfo.ZoningMode zoningMode2 = BuildingInfo.ZoningMode.Straight;
            bool flag8 = true;

            for (int n = num19; n <= num20; n++)
            {
                depth_B = Mathf.Min(depth_B, tmpXBuffer[n] & 65535);
                if ((tmpXBuffer[n] & 131072) == 0)
                {
                    flag8 = false;
                }
            }
            if (num20 > num19)
            {
                if ((tmpXBuffer[num19] & 65536) != 0)
                {
                    zoningMode2 = BuildingInfo.ZoningMode.CornerLeft;
                }
                if ((tmpXBuffer[num20] & 65536) != 0 && (zoningMode2 != BuildingInfo.ZoningMode.CornerLeft || Singleton <SimulationManager> .instance.m_randomizer.Int32(2u) == 0))
                {
                    zoningMode2 = BuildingInfo.ZoningMode.CornerRight;
                }
            }
            ItemClass.SubService subService = ItemClass.SubService.None;
            ItemClass.Level      level      = ItemClass.Level.Level1;
            ItemClass.Service    service;
            switch (zone)
            {
            case ItemClass.Zone.ResidentialLow:
                service    = ItemClass.Service.Residential;
                subService = ItemClass.SubService.ResidentialLow;
                break;

            case ItemClass.Zone.ResidentialHigh:
                service    = ItemClass.Service.Residential;
                subService = ItemClass.SubService.ResidentialHigh;
                break;

            case ItemClass.Zone.CommercialLow:
                service    = ItemClass.Service.Commercial;
                subService = ItemClass.SubService.CommercialLow;
                break;

            case ItemClass.Zone.CommercialHigh:
                service    = ItemClass.Service.Commercial;
                subService = ItemClass.SubService.CommercialHigh;
                break;

            case ItemClass.Zone.Industrial:
                service = ItemClass.Service.Industrial;
                break;

            case ItemClass.Zone.Office:
                service    = ItemClass.Service.Office;
                subService = ItemClass.SubService.None;
                break;

            default:
                return;
            }
            BuildingInfo buildingInfo = null;
            Vector3      vector6      = Vector3.zero;
            int          num25_row    = 0;
            int          length       = 0;
            int          width        = 0;

            BuildingInfo.ZoningMode zoningMode3 = BuildingInfo.ZoningMode.Straight;
            int num28 = 0;

            // begin mod
            int depth_alt = Mathf.Min(depth_A, 4);
            int width_alt = width_A;

            // end mod

            while (num28 < 8) // while (num28 < 6)
            {
                switch (num28)
                {
                // Corner cases

                case 0:
                    if (zoningMode != BuildingInfo.ZoningMode.Straight)
                    {
                        num25_row   = num15 + num16 + 1;
                        length      = depth_A;
                        width       = width_A;
                        zoningMode3 = zoningMode;
                        goto IL_D6A;
                    }
                    break;

                case 1:
                    if (zoningMode2 != BuildingInfo.ZoningMode.Straight)
                    {
                        num25_row   = num19 + num20 + 1;
                        length      = depth_B;
                        width       = width_B;
                        zoningMode3 = zoningMode2;
                        goto IL_D6A;
                    }
                    break;

                case 2:
                    if (zoningMode != BuildingInfo.ZoningMode.Straight)
                    {
                        if (depth_A >= 4)
                        {
                            num25_row   = num15 + num16 + 1;
                            length      = ((!flag7) ? 2 : 3);
                            width       = width_A;
                            zoningMode3 = zoningMode;
                            goto IL_D6A;
                        }
                    }
                    break;

                case 3:
                    if (zoningMode2 != BuildingInfo.ZoningMode.Straight)
                    {
                        if (depth_B >= 4)
                        {
                            num25_row   = num19 + num20 + 1;
                            length      = ((!flag8) ? 2 : 3);
                            width       = width_B;
                            zoningMode3 = zoningMode2;
                            goto IL_D6A;
                        }
                    }
                    break;

                // begin mod
                case 4:
                    if (zoningMode != BuildingInfo.ZoningMode.Straight)
                    {
                        if (width_alt > 1)
                        {
                            width_alt--;
                        }
                        else if (depth_alt > 1)
                        {
                            depth_alt--;
                            width_alt = width_A;
                        }
                        else
                        {
                            break;
                        }

                        if (width_alt == width_A)
                        {
                            num25_row = num15 + num16 + 1;
                        }
                        else
                        {
                            if (zoningMode == BuildingInfo.ZoningMode.CornerLeft)
                            {
                                num25_row = num15 + num16 + 1 - (width_A - width_alt);
                            }
                            else
                            {
                                num25_row = num15 + num16 + 1 + (width_A - width_alt);
                            }
                        }

                        length = depth_alt;
                        width  = width_alt;

                        zoningMode3 = zoningMode;

                        num28--;
                        goto IL_D6A;
                    }
                    break;

                // end mod
                // Straight cases
                case 5:
                    num25_row   = num15 + num16 + 1;
                    length      = depth_A;
                    width       = width_A;
                    zoningMode3 = BuildingInfo.ZoningMode.Straight;
                    goto IL_D6A;

                case 6:
                    // begin mod

                    // reset variables
                    depth_alt = Mathf.Min(depth_A, 4);
                    width_alt = width_A;

                    // end mod

                    //int width_B = num20 - num19 + 1;
                    num25_row   = num19 + num20 + 1;
                    length      = depth_B;
                    width       = width_B;
                    zoningMode3 = BuildingInfo.ZoningMode.Straight;
                    goto IL_D6A;

                // begin mod
                case 7:

                    if (width_alt > 1)
                    {
                        width_alt--;
                    }
                    else
                    {
                        break;
                    }

                    if (width_alt == width_A)
                    {
                        num25_row = num15 + num16 + 1;
                    }
                    else if (width_A % 2 != width_alt % 2)
                    {
                        num25_row = num15 + num16;
                    }
                    else
                    {
                        num25_row = num15 + num16 + 1;
                    }

                    length = depth_alt;
                    width  = width_alt;

                    zoningMode3 = BuildingInfo.ZoningMode.Straight;

                    num28--;
                    goto IL_D6A;

                // end mod
                default:
                    goto IL_D6A;
                }
IL_DF0:
                num28++;
                continue;
IL_D6A:
                vector6 = m_position + VectorUtils.X_Y(((float)length * 0.5f - 4f) * xDirection + ((float)num25_row * 0.5f + (float)spawnpointRow - 10f) * zDirection);
                if (zone == ItemClass.Zone.Industrial)
                {
                    ZoneBlock.GetIndustryType(vector6, out subService, out level);
                }
                else if (zone == ItemClass.Zone.CommercialLow || zone == ItemClass.Zone.CommercialHigh)
                {
                    ZoneBlock.GetCommercialType(vector6, zone, width, length, out subService, out level);
                }

                byte   district2 = instance2.GetDistrict(vector6);
                ushort style     = instance2.m_districts.m_buffer[(int)district2].m_Style;

                // begin mod

                // Here we are calling a custom getRandomBuildingInfo method

                buildingInfo = BuildingManagerDetour.GetRandomBuildingInfo_Spawn(vector6, ref Singleton <SimulationManager> .instance.m_randomizer, service, subService, level, width, length, zoningMode3, style);

                // end mod

                if (buildingInfo != null)
                {
                    // begin mod

                    // If the depth of the found prefab is smaller than the one we were looking for, recalculate the size
                    // This is done by checking the position of every prop
                    // Plots only get shrinked when no assets are placed on the extra space

                    // This is needed for themes which only contain small buildings (e.g. 1x2)
                    // because those buildings would occupy more space than needed!

                    if (buildingInfo.GetWidth() == width && buildingInfo.GetLength() != length)
                    {
                        // Calculate the z position of the furthest away prop
                        float biggestPropPosZ = 0;

                        if (buildingInfo.m_props != null)
                        {
                            foreach (var prop in buildingInfo.m_props)
                            {
                                if (prop == null)
                                {
                                    continue;
                                }

                                biggestPropPosZ = Mathf.Max(biggestPropPosZ, buildingInfo.m_expandFrontYard ? prop.m_position.z : -prop.m_position.z);
                            }
                        }

                        // Check if the furthest away prop is outside of the bounds of the prefab
                        float occupiedExtraSpace = biggestPropPosZ - buildingInfo.GetLength() * 4;
                        if (occupiedExtraSpace <= 0)
                        {
                            // No? Then shrink the plot to the prefab length so no space is wasted!
                            length = buildingInfo.GetLength();
                        }
                        else
                        {
                            // Yes? Shrink the plot so all props are in the bounds
                            int newLength = buildingInfo.GetLength() + Mathf.CeilToInt(occupiedExtraSpace / 8);
                            length = Mathf.Min(length, newLength);
                        }

                        vector6 = m_position + VectorUtils.X_Y(((float)length * 0.5f - 4f) * xDirection + ((float)num25_row * 0.5f + (float)spawnpointRow - 10f) * zDirection);
                    }

                    // This block handles Corner buildings. We always shrink them
                    else if (buildingInfo.GetLength() == width && buildingInfo.GetWidth() != length)
                    {
                        length  = buildingInfo.GetWidth();
                        vector6 = m_position + VectorUtils.X_Y(((float)length * 0.5f - 4f) * xDirection + ((float)num25_row * 0.5f + (float)spawnpointRow - 10f) * zDirection);
                    }

                    // end mod

                    if (Debugger.Enabled)
                    {
                        Debugger.LogFormat("Found prefab: {5} - {0}, {1}, {2}, {3} x {4}", service, subService, level, width, length, buildingInfo.name);
                    }
                    break;
                }
                if (Debugger.Enabled)
                {
                }
                goto IL_DF0;
            }
            if (buildingInfo == null)
            {
                if (Debugger.Enabled)
                {
                    Debugger.LogFormat("No prefab found: {0}, {1}, {2}, {3} x {4}", service, subService, level, width, length);
                }
                return;
            }
            float num29 = Singleton <TerrainManager> .instance.WaterLevel(VectorUtils.XZ(vector6));

            if (num29 > vector6.y)
            {
                return;
            }
            float num30 = m_angle + 1.57079637f;

            if (zoningMode3 == BuildingInfo.ZoningMode.CornerLeft && buildingInfo.m_zoningMode == BuildingInfo.ZoningMode.CornerRight)
            {
                num30 -= 1.57079637f;
                length = width;
            }
            else if (zoningMode3 == BuildingInfo.ZoningMode.CornerRight && buildingInfo.m_zoningMode == BuildingInfo.ZoningMode.CornerLeft)
            {
                num30 += 1.57079637f;
                length = width;
            }
            ushort num31;

            if (Singleton <BuildingManager> .instance.CreateBuilding(out num31, ref Singleton <SimulationManager> .instance.m_randomizer, buildingInfo, vector6, num30, length, Singleton <SimulationManager> .instance.m_currentBuildIndex))
            {
                Singleton <SimulationManager> .instance.m_currentBuildIndex += 1u;
                switch (service)
                {
                case ItemClass.Service.Residential:
                    zoneManager.m_actualResidentialDemand = Mathf.Max(0, zoneManager.m_actualResidentialDemand - 5);
                    break;

                case ItemClass.Service.Commercial:
                    zoneManager.m_actualCommercialDemand = Mathf.Max(0, zoneManager.m_actualCommercialDemand - 5);
                    break;

                case ItemClass.Service.Industrial:
                    zoneManager.m_actualWorkplaceDemand = Mathf.Max(0, zoneManager.m_actualWorkplaceDemand - 5);
                    break;

                case ItemClass.Service.Office:
                    zoneManager.m_actualWorkplaceDemand = Mathf.Max(0, zoneManager.m_actualWorkplaceDemand - 5);
                    break;
                }

                switch (zone)
                {
                case ItemClass.Zone.ResidentialHigh:
                case ItemClass.Zone.CommercialHigh:
                {
                    Building[] expr_FD7_cp_0 = Singleton <BuildingManager> .instance.m_buildings.m_buffer;
                    ushort     expr_FD7_cp_1 = num31;
                    expr_FD7_cp_0[(int)expr_FD7_cp_1].m_flags = (expr_FD7_cp_0[(int)expr_FD7_cp_1].m_flags | Building.Flags.HighDensity);
                    break;
                }
                }
            }
            zoneManager.m_goodAreaFound[(int)zone] = 1024;
        }
        /// <summary>
        /// Collects building info for debug use.
        /// </summary>
        /// <param name="buildings">The buildings.</param>
        /// <param name="vehicles">The vehicles.</param>
        /// <param name="districtManager">The district manager.</param>
        /// <param name="citizenManager">The citizen manager.</param>
        /// <param name="buildingId">The building identifier.</param>
        /// <param name="serviceBuilding">The service building.</param>
        /// <param name="targetBuilding">The target building.</param>
        /// <param name="buildingStamp">The building stamp.</param>
        /// <param name="verbose">If set to <c>true</c> include more information.</param>
        /// <returns>The debug information.</returns>
        private static Log.InfoList DebugInfoMsg(
            Building[] buildings,
            Vehicle[] vehicles,
            DistrictManager districtManager,
            CitizenManager citizenManager,
            ushort buildingId,
            ServiceBuildingInfo serviceBuilding,
            TargetBuildingInfo targetBuilding,
            BuildingStamp buildingStamp,
            bool verbose = false)
        {
            Log.InfoList info = new Log.InfoList();

            info.Add("BuildingId", buildingId);

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

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

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

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

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

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

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

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

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

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

                    serviceBuilding = null;
                }

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

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

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

                    targetBuilding = null;
                }
            }

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

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

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

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

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

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

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

            float radius = float.NaN;

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

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

                serviceVehicleCount = 0;

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

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

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

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

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

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

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

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

            ushort ownVehicleCount  = 0;
            ushort madeVehicleCount = 0;

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

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

            int productionRate = buildings[buildingId].m_productionRate;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            return(info);
        }
        private static bool CalculateLocalResources(int x, int z, ushort[] buffer, int[] global, ushort[] target, int index)
        {
            int resourceRate1  = (int)buffer[index] + global[0];
            int resourceRate2  = (int)buffer[index + 1] + global[1];
            int resourceRate3  = (int)buffer[index + 2] + global[2];
            int resourceRate4  = (int)buffer[index + 3] + global[3];
            int resourceRate5  = (int)buffer[index + 4] + global[4];
            int resourceRate6  = (int)buffer[index + 5] + global[5];
            int resourceRate7  = (int)buffer[index + 6] + global[6];
            int resourceRate8  = (int)buffer[index + 7] + global[7];
            int resourceRate9  = (int)buffer[index + 8] + global[8];
            int num1           = (int)buffer[index + 9] + global[9];
            int num2           = (int)buffer[index + 10] + global[10];
            int num3           = (int)buffer[index + 11] + global[11];
            int a              = (int)buffer[index + 12] + global[12];
            int resourceRate10 = (int)buffer[index + 13] + global[13];
            int num4           = (int)buffer[index + 14] + global[14];
            int num5           = (int)buffer[index + 15] + global[15];
            int num6           = (int)buffer[index + 16] + global[16];
            int num7           = (int)buffer[index + 17] + global[17];
            int resourceRate11 = (int)buffer[index + 18] + global[18];
            int resourceRate12 = (int)buffer[index + 19] + global[19];
            int resourceRate13 = (int)buffer[index + 20] + global[20];
            int resourceRate14 = (int)buffer[index + 21];
            int num8           = (int)buffer[index + 22] + global[22];
            int resourceRate15 = (int)buffer[index + 23] + global[23];
            //begin mod
            Rect area = new Rect((float)(((double)x - HALFGRID - 1.5) * 38.4f), (float)(((double)z - HALFGRID - 1.5) * 38.4f), 153.6f, 153.6f);
            //end mod
            float groundPollution;
            float waterProximity;

            Singleton <NaturalResourceManager> .instance.AveragePollutionAndWater(area, out groundPollution, out waterProximity);

            int num9  = (int)((double)groundPollution * 100.0);
            int num10 = (int)((double)waterProximity * 100.0);

            if (num10 > 33 && num10 < 99)
            {
                //begin mod
                area = new Rect((float)(((double)x - HALFGRID + 0.25) * 38.4000015258789), (float)(((double)z - HALFGRID + 0.25) * 38.4000015258789), 19.2f, 19.2f);
                //end mod
                Singleton <NaturalResourceManager> .instance.AveragePollutionAndWater(area, out groundPollution, out waterProximity);

                num10 = Mathf.Max(Mathf.Min(num10, (int)((double)waterProximity * 100.0)), 33);
            }
            int resourceRate16 = num7 * 2 / (resourceRate2 + 50);
            int resourceRate17;
            int resourceRate18;
            int resourceRate19;

            if (a == 0)
            {
                resourceRate17 = 0;
                resourceRate18 = 50;
                resourceRate19 = 50;
            }
            else
            {
                resourceRate17 = num1 / a;
                resourceRate18 = num2 / a;
                resourceRate19 = num3 / a;
                num6          += Mathf.Min(a, 10) * 10;
            }
            //begin mod
            int num11 = ((Singleton <GameAreaManager> .instance.PointOutOfArea(VectorUtils.X_Y(area.center)) ? 1 : 0) | (x <= 1 || x >= GRID - 2 || z <= 1 ? 1 : (z >= GRID - 2 ? 1 : 0))) == 0 ? (num4 + ImmaterialResourceManager.CalculateResourceEffect(resourceRate1, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate3, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate2, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate4, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate5, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate6, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate7, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate8, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate12, 100, 500, 50, 100) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate10, 100, 500, 100, 200) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate19, 60, 100, 0, 50) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate18, 60, 100, 0, 50) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate13, 50, 100, 20, 25) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate15, 50, 100, 20, 25) + ImmaterialResourceManager.CalculateResourceEffect(resourceRate14, 100, 1000, 0, 25) - ImmaterialResourceManager.CalculateResourceEffect(100 - resourceRate19, 60, 100, 0, 50) - ImmaterialResourceManager.CalculateResourceEffect(100 - resourceRate18, 60, 100, 0, 50) - ImmaterialResourceManager.CalculateResourceEffect(num9, 50, (int)byte.MaxValue, 50, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate9, 10, 100, 0, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate17, 10, 100, 0, 100) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate16, 50, 100, 10, 50) - ImmaterialResourceManager.CalculateResourceEffect(resourceRate11, 15, 50, 100, 200) + (ImmaterialResourceManager.CalculateResourceEffect(num10, 33, 67, 300, 0) * Mathf.Max(0, 32 - num9) >> 5)) / 10 : 0;
            //end mod
            int             num12     = Mathf.Clamp(resourceRate1, 0, (int)ushort.MaxValue);
            int             num13     = Mathf.Clamp(resourceRate2, 0, (int)ushort.MaxValue);
            int             num14     = Mathf.Clamp(resourceRate3, 0, (int)ushort.MaxValue);
            int             num15     = Mathf.Clamp(resourceRate4, 0, (int)ushort.MaxValue);
            int             num16     = Mathf.Clamp(resourceRate5, 0, (int)ushort.MaxValue);
            int             num17     = Mathf.Clamp(resourceRate6, 0, (int)ushort.MaxValue);
            int             num18     = Mathf.Clamp(resourceRate7, 0, (int)ushort.MaxValue);
            int             num19     = Mathf.Clamp(resourceRate8, 0, (int)ushort.MaxValue);
            int             num20     = Mathf.Clamp(resourceRate9, 0, (int)ushort.MaxValue);
            int             num21     = Mathf.Clamp(resourceRate17, 0, (int)ushort.MaxValue);
            int             num22     = Mathf.Clamp(resourceRate18, 0, (int)ushort.MaxValue);
            int             num23     = Mathf.Clamp(resourceRate19, 0, (int)ushort.MaxValue);
            int             num24     = Mathf.Clamp(a, 0, (int)ushort.MaxValue);
            int             num25     = Mathf.Clamp(resourceRate10, 0, (int)ushort.MaxValue);
            int             landvalue = Mathf.Clamp(num11, 0, (int)ushort.MaxValue);
            int             num26     = Mathf.Clamp(num5, 0, (int)ushort.MaxValue);
            int             coverage  = Mathf.Clamp(num6, 0, (int)ushort.MaxValue);
            int             num27     = Mathf.Clamp(resourceRate16, 0, (int)ushort.MaxValue);
            int             num28     = Mathf.Clamp(resourceRate11, 0, (int)ushort.MaxValue);
            int             num29     = Mathf.Clamp(resourceRate12, 0, (int)ushort.MaxValue);
            int             num30     = Mathf.Clamp(resourceRate13, 0, (int)ushort.MaxValue);
            int             num31     = Mathf.Clamp(resourceRate14, 0, (int)ushort.MaxValue);
            int             num32     = Mathf.Clamp(num8, 0, (int)ushort.MaxValue);
            int             num33     = Mathf.Clamp(resourceRate15, 0, (int)ushort.MaxValue);
            DistrictManager instance  = Singleton <DistrictManager> .instance;
            //begin mod
            byte district = instance.GetDistrict(x * FakeDistrictManager.GRID / GRID, z * FakeDistrictManager.GRID / GRID);

            //end mod
            instance.m_districts.m_buffer[(int)district].AddGroundData(landvalue, num9, coverage);
            bool flag = false;

            if (num12 != (int)target[index])
            {
                target[index] = (ushort)num12;
                flag          = true;
            }
            if (num13 != (int)target[index + 1])
            {
                target[index + 1] = (ushort)num13;
                flag = true;
            }
            if (num14 != (int)target[index + 2])
            {
                target[index + 2] = (ushort)num14;
                flag = true;
            }
            if (num15 != (int)target[index + 3])
            {
                target[index + 3] = (ushort)num15;
                flag = true;
            }
            if (num16 != (int)target[index + 4])
            {
                target[index + 4] = (ushort)num16;
                flag = true;
            }
            if (num17 != (int)target[index + 5])
            {
                target[index + 5] = (ushort)num17;
                flag = true;
            }
            if (num18 != (int)target[index + 6])
            {
                target[index + 6] = (ushort)num18;
                flag = true;
            }
            if (num19 != (int)target[index + 7])
            {
                target[index + 7] = (ushort)num19;
                flag = true;
            }
            if (num20 != (int)target[index + 8])
            {
                target[index + 8] = (ushort)num20;
                flag = true;
            }
            if (num21 != (int)target[index + 9])
            {
                target[index + 9] = (ushort)num21;
                flag = true;
            }
            if (num22 != (int)target[index + 10])
            {
                target[index + 10] = (ushort)num22;
                flag = true;
            }
            if (num23 != (int)target[index + 11])
            {
                target[index + 11] = (ushort)num23;
                flag = true;
            }
            if (num24 != (int)target[index + 12])
            {
                target[index + 12] = (ushort)num24;
                flag = true;
            }
            if (num25 != (int)target[index + 13])
            {
                target[index + 13] = (ushort)num25;
                flag = true;
            }
            if (landvalue != (int)target[index + 14])
            {
                target[index + 14] = (ushort)landvalue;
                flag = true;
            }
            if (num26 != (int)target[index + 15])
            {
                target[index + 15] = (ushort)num26;
                flag = true;
            }
            if (coverage != (int)target[index + 16])
            {
                target[index + 16] = (ushort)coverage;
                flag = true;
            }
            if (num27 != (int)target[index + 17])
            {
                target[index + 17] = (ushort)num27;
                flag = true;
            }
            if (num28 != (int)target[index + 18])
            {
                target[index + 18] = (ushort)num28;
                flag = true;
            }
            if (num29 != (int)target[index + 19])
            {
                target[index + 19] = (ushort)num29;
                flag = true;
            }
            if (num30 != (int)target[index + 20])
            {
                target[index + 20] = (ushort)num30;
                flag = true;
            }
            if (num31 != (int)target[index + 21])
            {
                target[index + 21] = (ushort)num31;
                flag = true;
            }
            if (num32 != (int)target[index + 22])
            {
                target[index + 22] = (ushort)num32;
                flag = true;
            }
            if (num33 != (int)target[index + 23])
            {
                target[index + 23] = (ushort)num33;
                flag = true;
            }
            return(flag);
        }
示例#27
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
        }
示例#28
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;
        }
示例#29
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;
        }
示例#30
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

            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);
            }
        }
        private static bool ticketPriceForPrefix(ushort vehicleID, ref Vehicle vehicleData, ref int __result)
        {
            var def = TransportSystemDefinition.from(vehicleData.Info);

            if (def == default(TransportSystemDefinition))
            {
                return(true);
            }

            DistrictManager instance = Singleton <DistrictManager> .instance;
            byte            district = instance.GetDistrict(vehicleData.m_targetPos3);

            DistrictPolicies.Services servicePolicies = instance.m_districts.m_buffer[(int)district].m_servicePolicies;
            DistrictPolicies.Event    @event          = instance.m_districts.m_buffer[(int)district].m_eventPolicies & Singleton <EventManager> .instance.GetEventPolicyMask();

            float multiplier;

            if (vehicleData.Info.m_class.m_subService == ItemClass.SubService.PublicTransportTours)
            {
                multiplier = 1;
            }
            else
            {
                if ((servicePolicies & DistrictPolicies.Services.FreeTransport) != DistrictPolicies.Services.None)
                {
                    __result = 0;
                    return(false);
                }
                if ((@event & DistrictPolicies.Event.ComeOneComeAll) != DistrictPolicies.Event.None)
                {
                    __result = 0;
                    return(false);
                }
                if ((servicePolicies & DistrictPolicies.Services.HighTicketPrices) != DistrictPolicies.Services.None)
                {
                    District[] expr_114_cp_0 = instance.m_districts.m_buffer;
                    byte       expr_114_cp_1 = district;
                    expr_114_cp_0[(int)expr_114_cp_1].m_servicePoliciesEffect = (expr_114_cp_0[(int)expr_114_cp_1].m_servicePoliciesEffect | DistrictPolicies.Services.HighTicketPrices);
                    multiplier = 5f / 4f;
                }
                else
                {
                    multiplier = 1;
                }
            }
            if (vehicleData.m_transportLine == 0)
            {
                __result = (int)(def.GetTransportExtension().GetDefaultTicketPrice(0) * multiplier);
                return(false);
            }
            else
            {
                if (TLMTransportLineExtension.instance.IsUsingCustomConfig(vehicleData.m_transportLine))
                {
                    __result = (int)(TLMTransportLineExtension.instance.GetTicketPrice(vehicleData.m_transportLine) * multiplier);
                }
                else
                {
                    __result = (int)(def.GetTransportExtension().GetTicketPrice(TLMLineUtils.getPrefix(vehicleData.m_transportLine)) * multiplier);
                }
                return(false);
            }
        }
        /// <summary>
        /// Collects building info for debug use.
        /// </summary>
        /// <param name="buildings">The buildings.</param>
        /// <param name="vehicles">The vehicles.</param>
        /// <param name="districtManager">The district manager.</param>
        /// <param name="citizenManager">The citizen manager.</param>
        /// <param name="buildingId">The building identifier.</param>
        /// <param name="serviceBuilding">The service building.</param>
        /// <param name="targetBuilding">The target building.</param>
        /// <param name="buildingStamp">The building stamp.</param>
        /// <param name="verbose">If set to <c>true</c> include more information.</param>
        /// <returns>The debug information.</returns>
        private static Log.InfoList DebugInfoMsg(
            Building[] buildings,
            Vehicle[] vehicles,
            DistrictManager districtManager,
            CitizenManager citizenManager,
            ushort buildingId,
            ServiceBuildingInfo serviceBuilding,
            TargetBuildingInfo targetBuilding,
            BuildingStamp buildingStamp,
            bool verbose = false)
        {
            Log.InfoList info = new Log.InfoList();

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

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

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

            List<TargetBuildingInfo> targetBuildings = null;
            List<ServiceBuildingInfo> serviceBuildings = null;

            if (verbose && Global.Buildings != null)
            {
                targetBuildings = new List<TargetBuildingInfo>();
                serviceBuildings = new List<ServiceBuildingInfo>();

                if (serviceBuilding == null)
                {
                    if (Global.Buildings.GarbageBuildings == null || !Global.Buildings.GarbageBuildings.TryGetValue(buildingId, out serviceBuilding))
                    {
                        serviceBuildings.Add(serviceBuilding);
                    }

                    if (Global.Buildings.DeathCareBuildings == null || !Global.Buildings.DeathCareBuildings.TryGetValue(buildingId, out serviceBuilding))
                    {
                        serviceBuildings.Add(serviceBuilding);
                    }

                    if (Global.Buildings.HealthCareBuildings == null || !Global.Buildings.HealthCareBuildings.TryGetValue(buildingId, out serviceBuilding))
                    {
                        serviceBuildings.Add(serviceBuilding);
                    }
                }

                if (targetBuilding == null)
                {
                    if (Global.Buildings.DeadPeopleBuildings == null || !Global.Buildings.DeadPeopleBuildings.TryGetValue(buildingId, out targetBuilding))
                    {
                        targetBuildings.Add(targetBuilding);
                    }

                    if (Global.Buildings.DirtyBuildings == null || !Global.Buildings.DirtyBuildings.TryGetValue(buildingId, out targetBuilding))
                    {
                        targetBuildings.Add(targetBuilding);
                    }

                    if (Global.Buildings.SickPeopleBuildings == null || !Global.Buildings.SickPeopleBuildings.TryGetValue(buildingId, out targetBuilding))
                    {
                        targetBuildings.Add(targetBuilding);
                    }
                }
            }

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

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

            byte district = districtManager.GetDistrict(buildings[buildingId].m_position);
            info.Add("District", district);
            info.Add("DistrictName", districtManager.GetDistrictName(district));

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

            if (serviceBuilding != null)
            {
                info.Add("CanReceive", serviceBuilding.CanReceive);
                info.Add("CapacityLevel", serviceBuilding.CapacityLevel);
                info.Add("CapactyFree", serviceBuilding.CapacityFree);
                info.Add("CapactyMax", serviceBuilding.CapacityMax);
                info.Add("CapactyOverflow", serviceBuilding.CapacityOverflow);
                info.Add("Range", serviceBuilding.Range);
                info.Add("VehiclesFree", serviceBuilding.VehiclesFree);
                info.Add("VehiclesSpare", serviceBuilding.VehiclesSpare);
                info.Add("VehiclesMade", serviceBuilding.VehiclesMade);
                info.Add("VehiclesTotal", serviceBuilding.VehiclesTotal);
            }

            if (serviceBuildings != null)
            {
                for (int i = 0; i < serviceBuildings.Count; i++)
                {
                    serviceBuilding = serviceBuildings[i];
                    string n = (i + 1).ToString();

                    info.Add("CanReceive" + n, serviceBuilding.CanReceive);
                    info.Add("CapacityLevel" + n, serviceBuilding.CapacityLevel);
                    info.Add("CapactyFree" + n, serviceBuilding.CapacityFree);
                    info.Add("CapactyMax" + n, serviceBuilding.CapacityMax);
                    info.Add("CapactyOverflow" + n, serviceBuilding.CapacityOverflow);
                    info.Add("Range" + n, serviceBuilding.Range);
                    info.Add("VehiclesFree" + n, serviceBuilding.VehiclesFree);
                    info.Add("VehiclesSpare" + n, serviceBuilding.VehiclesSpare);
                    info.Add("VehiclesMade" + n, serviceBuilding.VehiclesMade);
                    info.Add("VehiclesTotal" + n, serviceBuilding.VehiclesTotal);
                }
            }

            if (targetBuilding != null)
            {
                info.Add("Demand", targetBuilding.Demand);
                info.Add("HasProblem", targetBuilding.HasProblem);
                info.Add("ProblemSize", targetBuilding.ProblemSize);
                info.Add("ProblemValue", targetBuilding.ProblemValue);
            }

            if (targetBuildings != null)
            {
                for (int i = 0; i < targetBuildings.Count; i++)
                {
                    targetBuilding = targetBuildings[i];
                    string n = (i + 1).ToString();

                    info.Add("Demand" + n, targetBuilding.Demand);
                    info.Add("HasProblem" + n, targetBuilding.HasProblem);
                    info.Add("ProblemSize" + n, targetBuilding.ProblemSize);
                    info.Add("ProblemValue" + n, targetBuilding.ProblemValue);
                }
            }

            if (verbose && Global.Buildings != null)
            {
                Double desolate;

                if (Global.Buildings.DesolateBuildings != null && Global.Buildings.DesolateBuildings.TryGetValue(buildingId, out desolate))
                {
                    info.Add("Desolate", desolate);
                }
            }

            int materialMax = 0;
            int materialAmount = 0;
            int serviceVehicleCount = 0;
            if (buildings[buildingId].Info.m_buildingAI is CemeteryAI)
            {
                serviceVehicleCount = ((CemeteryAI)buildings[buildingId].Info.m_buildingAI).m_hearseCount;
                info.Add("CorpseCapacity", ((CemeteryAI)buildings[buildingId].Info.m_buildingAI).m_corpseCapacity);
                info.Add("GraveCount", ((CemeteryAI)buildings[buildingId].Info.m_buildingAI).m_graveCount);
                info.Add("CustomBuffer1", buildings[buildingId].m_customBuffer1); // GraveCapacity?
                info.Add("CustomBuffer2", buildings[buildingId].m_customBuffer2);
                info.Add("PR_HC_Calc", ((buildings[buildingId].m_productionRate * ((CemeteryAI)buildings[buildingId].Info.m_buildingAI).m_hearseCount) + 99) / 100); // Hearse capacity?
                buildings[buildingId].Info.m_buildingAI.GetMaterialAmount(buildingId, ref buildings[buildingId], TransferManager.TransferReason.Dead, out materialAmount, out materialMax);
            }
            else if (buildings[buildingId].Info.m_buildingAI is LandfillSiteAI)
            {
                serviceVehicleCount = ((LandfillSiteAI)buildings[buildingId].Info.m_buildingAI).m_garbageTruckCount;
                buildings[buildingId].Info.m_buildingAI.GetMaterialAmount(buildingId, ref buildings[buildingId], TransferManager.TransferReason.Garbage, out materialAmount, out materialMax);
            }
            else if (buildings[buildingId].Info.m_buildingAI is HospitalAI)
            {
                serviceVehicleCount = ((HospitalAI)buildings[buildingId].Info.m_buildingAI).m_ambulanceCount;
                info.Add("", ((HospitalAI)buildings[buildingId].Info.m_buildingAI).m_patientCapacity);
                buildings[buildingId].Info.m_buildingAI.GetMaterialAmount(buildingId, ref buildings[buildingId], TransferManager.TransferReason.Sick, out materialAmount, out materialMax);
            }
            info.Add("materialMax", materialMax);
            info.Add("materialAmount", materialAmount);
            info.Add("materialFree", materialMax - materialAmount);

            int productionRate = buildings[buildingId].m_productionRate;

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

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

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

            int budget = Singleton<EconomyManager>.instance.GetBudget(buildings[buildingId].Info.m_buildingAI.m_info.m_class);
            productionRate = PlayerBuildingAI.GetProductionRate(100, budget);
            int actualVehicleCount = ((productionRate * serviceVehicleCount) + 99) / 100;
            info.Add("Budget", budget);
            info.Add("ProductionRateActual", productionRate);
            info.Add("VehicleCountActual", actualVehicleCount);
            info.Add("SpareVehicles", actualVehicleCount - ownVehicleCount);

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

            List<string> needs = new List<string>();
            if (buildings[buildingId].m_garbageBuffer >= Global.Settings.Garbage.MinimumAmountForDispatch)
            {
                needs.Add("Filthy");
            }
            if (buildings[buildingId].m_garbageBuffer >= Global.Settings.Garbage.MinimumAmountForPatrol)
            {
                needs.Add("Dirty");
            }
            else if (buildings[buildingId].m_garbageBuffer > 0)
            {
                needs.Add("Dusty");
            }
            if (buildings[buildingId].m_deathProblemTimer > 0)
            {
                needs.Add("Dead");
            }
            if (buildings[buildingId].m_garbageBuffer * Dispatcher.ProblemBufferModifier >= Dispatcher.ProblemLimitForgotten ||
                buildings[buildingId].m_deathProblemTimer * Dispatcher.ProblemTimerModifier >= Dispatcher.ProblemLimitForgotten)
            {
                needs.Add("Forgotten");
            }
            info.Add("Needs", needs);

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

            int citizens = 0;
            int count = 0;
            uint unitId = buildings[buildingId].m_citizenUnits;
            while (unitId != 0)
            {
                CitizenUnit unit = citizenManager.m_units.m_buffer[unitId];
                for (int i = 0; i < 5; i++)
                {
                    uint citizenId = unit.GetCitizen(i);
                    if (citizenId != 0)
                    {
                        Citizen citizen = citizenManager.m_citizens.m_buffer[citizenId];
                        if (citizen.Dead && citizen.GetBuildingByLocation() == buildingId)
                        {
                            citizens++;
                        }
                    }
                }

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

                unitId = unit.m_nextUnit;
            }
            info.Add("DeadCitizens", citizens);

            info.Add("GarbageAmount", buildings[buildingId].Info.m_buildingAI.GetGarbageAmount(buildingId, ref buildings[buildingId]));
            info.Add("GarbageBuffer", buildings[buildingId].m_garbageBuffer);

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

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

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

            info.Add("AI", buildings[buildingId].Info.m_buildingAI.GetType().AssemblyQualifiedName);

            return info;
        }