Exemple #1
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;
        }
Exemple #2
0
        public override void SimulationStep(ushort disasterID, ref DisasterData data)
        {
            //Begin Disaster AI SimulationStep
            if ((data.m_flags & DisasterData.Flags.Clearing) != DisasterData.Flags.None)
            {
                if (!this.IsStillClearing(disasterID, ref data))
                {
                    this.EndDisaster(disasterID, ref data);
                }
            }
            else if ((data.m_flags & DisasterData.Flags.Active) != DisasterData.Flags.None)
            {
                if (!this.IsStillActive(disasterID, ref data))
                {
                    this.DeactivateDisaster(disasterID, ref data);
                }
            }
            else if ((data.m_flags & DisasterData.Flags.Emerging) != DisasterData.Flags.None)
            {
                if (!this.IsStillEmerging(disasterID, ref data))
                {
                    this.ActivateDisaster(disasterID, ref data);
                }
            }
            if ((data.m_flags & DisasterData.Flags.Detected) != DisasterData.Flags.None)
            {
                if ((data.m_flags & DisasterData.Flags.Warning) != DisasterData.Flags.None)
                {
                    if (data.m_broadcastCooldown > 0)
                    {
                        data.m_broadcastCooldown -= 1;
                    }
                    if (data.m_broadcastCooldown == 0)
                    {
                        data.m_broadcastCooldown = 36;
                        if (this.m_info.m_warningBroadcast != null)
                        {
                            Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_warningBroadcast);
                        }
                    }
                }
                else
                {
                    StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt32>(StatisticType.DisasterCount);

                    statisticBase.Add(16);
                    InstanceID id = default(InstanceID);
                    id.Disaster = disasterID;
                    InstanceManager.Group group = Singleton <InstanceManager> .instance.GetGroup(id);

                    if (data.m_broadcastCooldown >= 200)
                    {
                        if (data.m_broadcastCooldown > 200)
                        {
                            data.m_broadcastCooldown -= 1;
                        }
                        if (data.m_broadcastCooldown == 200 && (group == null || group.m_refCount >= 2))
                        {
                            data.m_broadcastCooldown = 236;
                            if (this.m_info.m_activeBroadcast != null)
                            {
                                Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_activeBroadcast);
                            }
                        }
                    }
                    else
                    {
                        if (data.m_broadcastCooldown > 0)
                        {
                            data.m_broadcastCooldown -= 1;
                        }
                        if (data.m_broadcastCooldown == 0)
                        {
                            data.m_broadcastCooldown = 236;
                            if (this.m_info.m_activeBroadcast != null)
                            {
                                Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_activeBroadcast);
                            }
                        }
                    }
                    if (group == null || group.m_refCount >= 2)
                    {
                        if (data.m_chirpCooldown > 0)
                        {
                            data.m_chirpCooldown -= 1;
                        }
                        else if (this.m_info.m_prefabDataIndex != -1)
                        {
                            string key = PrefabCollection <DisasterInfo> .PrefabName((uint)this.m_info.m_prefabDataIndex);

                            if (Locale.Exists("CHIRP_DISASTER", key))
                            {
                                string disasterName = Singleton <DisasterManager> .instance.GetDisasterName(disasterID);

                                Singleton <MessageManager> .instance.TryCreateMessage("CHIRP_DISASTER", key, Singleton <MessageManager> .instance.GetRandomResidentID(), disasterName);

                                data.m_chirpCooldown = (byte)Singleton <SimulationManager> .instance.m_randomizer.Int32(8, 24);
                            }
                        }
                    }
                }
                GuideController properties = Singleton <GuideManager> .instance.m_properties;
                if (this.m_info.m_disasterWarningGuide != null && properties != null)
                {
                    this.m_info.m_disasterWarningGuide.Activate(properties.m_disasterWarning, this.m_info);
                }
            }
            if ((data.m_flags & DisasterData.Flags.Repeat) != DisasterData.Flags.None && ((data.m_flags & (DisasterData.Flags.Finished | DisasterData.Flags.UnReported)) == DisasterData.Flags.Finished || (data.m_flags & (DisasterData.Flags.Clearing | DisasterData.Flags.UnDetected)) == (DisasterData.Flags.Clearing | DisasterData.Flags.UnDetected)))
            {
                this.StartDisaster(disasterID, ref data);
            }
            //End DisasterAI.Simulation Step
            if ((data.m_flags & DisasterData.Flags.Emerging) != DisasterData.Flags.None)
            {
                uint currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                if (currentFrameIndex + 1755u > data.m_activationFrame)
                {
                    Singleton <DisasterManager> .instance.DetectDisaster(disasterID, false);

                    Singleton <WeatherManager> .instance.m_forceWeatherOn = 2f;
                    Singleton <WeatherManager> .instance.m_targetFog      = 0f;
                    //Begin Edit
                    float newTornadoTargetRain = Mathf.Clamp(((float)data.m_intensity) / 100, 0.25f, 1.0f);
                    Singleton <WeatherManager> .instance.m_targetRain = newTornadoTargetRain;
                    Debug.Log("[RF]TornadoAIDetour Limtied Tornado Rain to " + Singleton <WeatherManager> .instance.m_targetRain);
                    //End Edit
                    Singleton <WeatherManager> .instance.m_targetCloud = 1f;
                }
            }
            else if ((data.m_flags & DisasterData.Flags.Active) != DisasterData.Flags.None)
            {
                Singleton <WeatherManager> .instance.m_forceWeatherOn = 2f;
                Singleton <WeatherManager> .instance.m_targetFog      = 0f;
                //Begin Edit
                float newTornadoTargetRain = Mathf.Clamp(((float)data.m_intensity) / 100, 0.25f, 1.0f);
                Singleton <WeatherManager> .instance.m_targetRain = newTornadoTargetRain;
                Debug.Log("[RF]TornadoAIDetour Limtied Tornado Rain to " + Singleton <WeatherManager> .instance.m_targetRain);
                //End Edit
                Singleton <WeatherManager> .instance.m_targetCloud = 1f;
            }
        }
Exemple #3
0
        public void CustomSimulationStep(ushort instanceId,
                                         ref CitizenInstance instanceData,
                                         Vector3 physicsLodRefPos)
        {
#if DEBUG
            bool citizenDebug = (DebugSettings.CitizenInstanceId == 0 ||
                                 DebugSettings.CitizenInstanceId == instanceId) &&
                                (DebugSettings.CitizenId == 0 ||
                                 DebugSettings.CitizenId == instanceData.m_citizen) &&
                                (DebugSettings.SourceBuildingId == 0 ||
                                 DebugSettings.SourceBuildingId == instanceData.m_sourceBuilding) &&
                                (DebugSettings.TargetBuildingId == 0 ||
                                 DebugSettings.TargetBuildingId == instanceData.m_targetBuilding);
            bool logParkingAi = DebugSwitch.BasicParkingAILog.Get() && citizenDebug;
#else
            var logParkingAi = false;
#endif
            CitizenManager citizenManager = Singleton <CitizenManager> .instance;
            uint           citizenId      = instanceData.m_citizen;

            if ((instanceData.m_flags & (CitizenInstance.Flags.Blown
                                         | CitizenInstance.Flags.Floating)) != CitizenInstance.Flags.None &&
                (instanceData.m_flags & CitizenInstance.Flags.Character) == CitizenInstance.Flags.None)
            {
                citizenManager.ReleaseCitizenInstance(instanceId);
                if (citizenId != 0u)
                {
                    citizenManager.ReleaseCitizen(citizenId);
                }

                return;
            }

            Citizen[] citizensBuffer = citizenManager.m_citizens.m_buffer;
            if ((instanceData.m_flags & CitizenInstance.Flags.WaitingPath) != CitizenInstance.Flags.None)
            {
                PathManager pathManager   = Singleton <PathManager> .instance;
                byte        pathFindFlags = pathManager.m_pathUnits.m_buffer[instanceData.m_path].m_pathFindFlags;

                // NON-STOCK CODE START
                ExtPathState mainPathState = ExtPathState.Calculating;
                if ((pathFindFlags & PathUnit.FLAG_FAILED) != 0 || instanceData.m_path == 0)
                {
                    mainPathState = ExtPathState.Failed;
                }
                else if ((pathFindFlags & PathUnit.FLAG_READY) != 0)
                {
                    mainPathState = ExtPathState.Ready;
                }

                if (logParkingAi)
                {
                    Log._Debug(
                        $"CustomHumanAI.CustomSimulationStep({instanceId}): " +
                        $"Path: {instanceData.m_path}, mainPathState={mainPathState}");
                }

                ExtSoftPathState finalPathState;
                using (var bm = Benchmark.MaybeCreateBenchmark(
                           null,
                           "ConvertPathStateToSoftPathState+UpdateCitizenPathState"))
                {
                    finalPathState = ExtCitizenInstance.ConvertPathStateToSoftPathState(mainPathState);

                    if (Options.parkingAI)
                    {
                        finalPathState = AdvancedParkingManager.Instance.UpdateCitizenPathState(
                            instanceId,
                            ref instanceData,
                            ref ExtCitizenInstanceManager
                            .Instance.ExtInstances[
                                instanceId],
                            ref ExtCitizenManager
                            .Instance.ExtCitizens[
                                citizenId],
                            ref citizensBuffer[
                                instanceData.m_citizen],
                            mainPathState);
                        if (logParkingAi)
                        {
                            Log._Debug(
                                $"CustomHumanAI.CustomSimulationStep({instanceId}): " +
                                $"Applied Parking AI logic. Path: {instanceData.m_path}, " +
                                $"mainPathState={mainPathState}, finalPathState={finalPathState}, " +
                                $"extCitizenInstance={ExtCitizenInstanceManager.Instance.ExtInstances[instanceId]}");
                        }
                    } // if Options.parkingAi
                }

                switch (finalPathState)
                {
                case ExtSoftPathState.Ready: {
                    if (logParkingAi)
                    {
                        Log._Debug(
                            $"CustomHumanAI.CustomSimulationStep({instanceId}): Path-finding " +
                            $"succeeded for citizen instance {instanceId} " +
                            $"(finalPathState={finalPathState}). Path: {instanceData.m_path} " +
                            "-- calling HumanAI.PathfindSuccess");
                    }

                    if (citizenId == 0 ||
                        citizensBuffer[instanceData.m_citizen].m_vehicle == 0)
                    {
                        Spawn(instanceId, ref instanceData);
                    }

                    instanceData.m_pathPositionIndex = 255;
                    instanceData.m_flags            &= ~CitizenInstance.Flags.WaitingPath;
                    instanceData.m_flags            &= ~(CitizenInstance.Flags.HangAround
                                                         | CitizenInstance.Flags.Panicking
                                                         | CitizenInstance.Flags.SittingDown
                                                         | CitizenInstance.Flags.Cheering);

                    // NON-STOCK CODE START (transferred from ResidentAI.PathfindSuccess)
                    const Citizen.Flags CTZ_MASK = Citizen.Flags.Tourist
                                                   | Citizen.Flags.MovingIn
                                                   | Citizen.Flags.DummyTraffic;
                    if (citizenId != 0 &&
                        (citizensBuffer[citizenId].m_flags & CTZ_MASK) == Citizen.Flags.MovingIn)
                    {
                        StatisticBase statisticBase = Singleton <StatisticsManager>
                                                      .instance.Acquire <StatisticInt32>(StatisticType.MoveRate);

                        statisticBase.Add(1);
                    }

                    // NON-STOCK CODE END
                    PathfindSuccess(instanceId, ref instanceData);
                    break;
                }

                case ExtSoftPathState.Ignore: {
                    if (logParkingAi)
                    {
                        Log._Debug(
                            $"CustomHumanAI.CustomSimulationStep({instanceId}): " +
                            "Path-finding result shall be ignored for citizen instance " +
                            $"{instanceId} (finalPathState={finalPathState}). " +
                            $"Path: {instanceData.m_path} -- ignoring");
                    }

                    return;
                }

                case ExtSoftPathState.Calculating:
                default: {
                    if (logParkingAi)
                    {
                        Log._Debug(
                            $"CustomHumanAI.CustomSimulationStep({instanceId}): " +
                            $"Path-finding result undetermined for citizen instance {instanceId} " +
                            $"(finalPathState={finalPathState}). " +
                            $"Path: {instanceData.m_path} -- continue");
                    }

                    break;
                }

                case ExtSoftPathState.FailedHard: {
                    if (logParkingAi)
                    {
                        Log._Debug(
                            $"CustomHumanAI.CustomSimulationStep({instanceId}): " +
                            $"HARD path-finding failure for citizen instance {instanceId} " +
                            $"(finalPathState={finalPathState}). Path: {instanceData.m_path} " +
                            "-- calling HumanAI.PathfindFailure");
                    }

                    instanceData.m_flags &= ~CitizenInstance.Flags.WaitingPath;
                    instanceData.m_flags &= ~(CitizenInstance.Flags.HangAround
                                              | CitizenInstance.Flags.Panicking
                                              | CitizenInstance.Flags.SittingDown
                                              | CitizenInstance.Flags.Cheering);
                    Singleton <PathManager> .instance.ReleasePath(instanceData.m_path);

                    instanceData.m_path = 0u;
                    PathfindFailure(instanceId, ref instanceData);
                    return;
                }

                case ExtSoftPathState.FailedSoft: {
                    if (logParkingAi)
                    {
                        Log._Debug(
                            $"CustomHumanAI.CustomSimulationStep({instanceId}): " +
                            $"SOFT path-finding failure for citizen instance {instanceId} " +
                            $"(finalPathState={finalPathState}). Path: {instanceData.m_path} " +
                            "-- calling HumanAI.InvalidPath");
                    }

                    // path mode has been updated, repeat path-finding
                    instanceData.m_flags &= ~CitizenInstance.Flags.WaitingPath;
                    instanceData.m_flags &= ~(CitizenInstance.Flags.HangAround
                                              | CitizenInstance.Flags.Panicking
                                              | CitizenInstance.Flags.SittingDown
                                              | CitizenInstance.Flags.Cheering);
                    InvalidPath(instanceId, ref instanceData);
                    break;
                }
                }

                // NON-STOCK CODE END
            }

            // NON-STOCK CODE START
            using (var bm = Benchmark.MaybeCreateBenchmark(null, "ExtSimulationStep")) {
                if (Options.parkingAI)
                {
                    if (ExtSimulationStep(
                            instanceId,
                            ref instanceData,
                            ref ExtCitizenInstanceManager.Instance.ExtInstances[instanceId],
                            physicsLodRefPos))
                    {
                        return;
                    }
                }
            }

            // NON-STOCK CODE END
            base.SimulationStep(instanceId, ref instanceData, physicsLodRefPos);

            VehicleManager vehicleManager = Singleton <VehicleManager> .instance;
            ushort         vehicleId      = 0;
            if (instanceData.m_citizen != 0u)
            {
                vehicleId = citizensBuffer[instanceData.m_citizen].m_vehicle;
            }

            if (vehicleId != 0)
            {
                Vehicle[]   vehiclesBuffer = vehicleManager.m_vehicles.m_buffer;
                VehicleInfo vehicleInfo    = vehiclesBuffer[vehicleId].Info;

                if (vehicleInfo.m_vehicleType == VehicleInfo.VehicleType.Bicycle)
                {
                    vehicleInfo.m_vehicleAI.SimulationStep(
                        vehicleId,
                        ref vehiclesBuffer[vehicleId],
                        vehicleId,
                        ref vehiclesBuffer[vehicleId],
                        0);
                    vehicleId = 0;
                }
            }

            if (vehicleId != 0 ||
                (instanceData.m_flags & (CitizenInstance.Flags.Character
                                         | CitizenInstance.Flags.WaitingPath
                                         | CitizenInstance.Flags.Blown
                                         | CitizenInstance.Flags.Floating)) !=
                CitizenInstance.Flags.None)
            {
                return;
            }

            instanceData.m_flags &= ~(CitizenInstance.Flags.HangAround
                                      | CitizenInstance.Flags.Panicking
                                      | CitizenInstance.Flags.SittingDown);
            ArriveAtDestination(instanceId, ref instanceData, false);
            citizenManager.ReleaseCitizenInstance(instanceId);
        }
Exemple #4
0
        public void CustomSimulationStep(ushort instanceID, ref CitizenInstance instanceData, Vector3 physicsLodRefPos)
        {
            uint citizenId = instanceData.m_citizen;

            if ((instanceData.m_flags & (CitizenInstance.Flags.Blown | CitizenInstance.Flags.Floating)) != CitizenInstance.Flags.None && (instanceData.m_flags & CitizenInstance.Flags.Character) == CitizenInstance.Flags.None)
            {
                Singleton <CitizenManager> .instance.ReleaseCitizenInstance(instanceID);

                if (citizenId != 0u)
                {
                    Singleton <CitizenManager> .instance.ReleaseCitizen(citizenId);
                }
                return;
            }

            if ((instanceData.m_flags & CitizenInstance.Flags.WaitingPath) != CitizenInstance.Flags.None)
            {
                PathManager pathManager   = Singleton <PathManager> .instance;
                byte        pathFindFlags = pathManager.m_pathUnits.m_buffer[instanceData.m_path].m_pathFindFlags;

                // NON-STOCK CODE START
                ExtPathState mainPathState = ExtPathState.Calculating;
                if ((pathFindFlags & PathUnit.FLAG_FAILED) != 0 || instanceData.m_path == 0)
                {
                    mainPathState = ExtPathState.Failed;
                }
                else if ((pathFindFlags & PathUnit.FLAG_READY) != 0)
                {
                    mainPathState = ExtPathState.Ready;
                }

#if DEBUG
                if (GlobalConfig.Instance.Debug.Switches[2])
                {
                    Log._Debug($"CustomHumanAI.CustomSimulationStep({instanceID}): Path: {instanceData.m_path}, mainPathState={mainPathState}");
                }
#endif

                ExtSoftPathState finalPathState = ExtSoftPathState.None;
#if BENCHMARK
                using (var bm = new Benchmark(null, "ConvertPathStateToSoftPathState+UpdateCitizenPathState")) {
#endif
                finalPathState = ExtCitizenInstance.ConvertPathStateToSoftPathState(mainPathState);
                if (Options.prohibitPocketCars)
                {
                    finalPathState = AdvancedParkingManager.Instance.UpdateCitizenPathState(instanceID, ref instanceData, ref ExtCitizenInstanceManager.Instance.ExtInstances[instanceID], ref Singleton <CitizenManager> .instance.m_citizens.m_buffer[instanceData.m_citizen], mainPathState);
#if DEBUG
                    if (GlobalConfig.Instance.Debug.Switches[2])
                    {
                        Log._Debug($"CustomHumanAI.CustomSimulationStep({instanceID}): Applied Parking AI logic. Path: {instanceData.m_path}, mainPathState={mainPathState}, finalPathState={finalPathState}, extCitizenInstance={ExtCitizenInstanceManager.Instance.ExtInstances[instanceID]}");
                    }
#endif
                }
#if BENCHMARK
            }
#endif

                switch (finalPathState)
                {
                case ExtSoftPathState.Ready:
#if DEBUG
                    if (GlobalConfig.Instance.Debug.Switches[2])
                    {
                        Log._Debug($"CustomHumanAI.CustomSimulationStep({instanceID}): Path-finding succeeded for citizen instance {instanceID} (finalPathState={finalPathState}). Path: {instanceData.m_path} -- calling HumanAI.PathfindSuccess");
                    }
#endif
                    this.Spawn(instanceID, ref instanceData);
                    instanceData.m_pathPositionIndex = 255;
                    instanceData.m_flags            &= ~CitizenInstance.Flags.WaitingPath;
                    instanceData.m_flags            &= ~(CitizenInstance.Flags.HangAround | CitizenInstance.Flags.Panicking | CitizenInstance.Flags.SittingDown | CitizenInstance.Flags.Cheering);
                    // NON-STOCK CODE START (transferred from ResidentAI.PathfindSuccess)
                    if (citizenId != 0 && (Singleton <CitizenManager> .instance.m_citizens.m_buffer[citizenId].m_flags & (Citizen.Flags.Tourist | Citizen.Flags.MovingIn | Citizen.Flags.DummyTraffic)) == Citizen.Flags.MovingIn)
                    {
                        StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt32>(StatisticType.MoveRate);

                        statisticBase.Add(1);
                    }
                    // NON-STOCK CODE END
                    this.PathfindSuccess(instanceID, ref instanceData);
                    break;

                case ExtSoftPathState.Ignore:
#if DEBUG
                    if (GlobalConfig.Instance.Debug.Switches[2])
                    {
                        Log._Debug($"CustomHumanAI.CustomSimulationStep({instanceID}): Path-finding result shall be ignored for citizen instance {instanceID} (finalPathState={finalPathState}). Path: {instanceData.m_path} -- ignoring");
                    }
#endif
                    return;

                case ExtSoftPathState.Calculating:
                default:
#if DEBUG
                    if (GlobalConfig.Instance.Debug.Switches[2])
                    {
                        Log._Debug($"CustomHumanAI.CustomSimulationStep({instanceID}): Path-finding result undetermined for citizen instance {instanceID} (finalPathState={finalPathState}). Path: {instanceData.m_path} -- continue");
                    }
#endif
                    break;

                case ExtSoftPathState.FailedHard:
#if DEBUG
                    if (GlobalConfig.Instance.Debug.Switches[2])
                    {
                        Log._Debug($"CustomHumanAI.CustomSimulationStep({instanceID}): HARD path-finding failure for citizen instance {instanceID} (finalPathState={finalPathState}). Path: {instanceData.m_path} -- calling HumanAI.PathfindFailure");
                    }
#endif
                    instanceData.m_flags &= ~CitizenInstance.Flags.WaitingPath;
                    instanceData.m_flags &= ~(CitizenInstance.Flags.HangAround | CitizenInstance.Flags.Panicking | CitizenInstance.Flags.SittingDown | CitizenInstance.Flags.Cheering);
                    Singleton <PathManager> .instance.ReleasePath(instanceData.m_path);

                    instanceData.m_path = 0u;
                    this.PathfindFailure(instanceID, ref instanceData);
                    return;

                case ExtSoftPathState.FailedSoft:
#if DEBUG
                    if (GlobalConfig.Instance.Debug.Switches[2])
                    {
                        Log._Debug($"CustomHumanAI.CustomSimulationStep({instanceID}): SOFT path-finding failure for citizen instance {instanceID} (finalPathState={finalPathState}). Path: {instanceData.m_path} -- calling HumanAI.InvalidPath");
                    }
#endif
                    // path mode has been updated, repeat path-finding
                    instanceData.m_flags &= ~CitizenInstance.Flags.WaitingPath;
                    instanceData.m_flags &= ~(CitizenInstance.Flags.HangAround | CitizenInstance.Flags.Panicking | CitizenInstance.Flags.SittingDown | CitizenInstance.Flags.Cheering);
                    this.InvalidPath(instanceID, ref instanceData);
                    return;
                }
                // NON-STOCK CODE END
            }

            // NON-STOCK CODE START
#if BENCHMARK
            using (var bm = new Benchmark(null, "ExtSimulationStep")) {
#endif
            if (Options.prohibitPocketCars)
            {
                if (ExtSimulationStep(instanceID, ref instanceData, ref ExtCitizenInstanceManager.Instance.ExtInstances[instanceID], physicsLodRefPos))
                {
                    return;
                }
            }
#if BENCHMARK
        }
#endif
            // NON-STOCK CODE END

            base.SimulationStep(instanceID, ref instanceData, physicsLodRefPos);

            CitizenManager citizenManager = Singleton <CitizenManager> .instance;
            VehicleManager vehicleManager = Singleton <VehicleManager> .instance;
            ushort vehicleId = 0;
            if (instanceData.m_citizen != 0u)
            {
                vehicleId = citizenManager.m_citizens.m_buffer[instanceData.m_citizen].m_vehicle;
            }
            if (vehicleId != 0)
            {
                VehicleInfo vehicleInfo = vehicleManager.m_vehicles.m_buffer[(int)vehicleId].Info;
                if (vehicleInfo.m_vehicleType == VehicleInfo.VehicleType.Bicycle)
                {
                    vehicleInfo.m_vehicleAI.SimulationStep(vehicleId, ref vehicleManager.m_vehicles.m_buffer[(int)vehicleId], vehicleId, ref vehicleManager.m_vehicles.m_buffer[(int)vehicleId], 0);
                    vehicleId = 0;
                }
            }
            if (vehicleId == 0 && (instanceData.m_flags & (CitizenInstance.Flags.Character | CitizenInstance.Flags.WaitingPath | CitizenInstance.Flags.Blown | CitizenInstance.Flags.Floating)) == CitizenInstance.Flags.None)
            {
                instanceData.m_flags &= ~(CitizenInstance.Flags.HangAround | CitizenInstance.Flags.Panicking | CitizenInstance.Flags.SittingDown);
                this.ArriveAtDestination(instanceID, ref instanceData, false);
                citizenManager.ReleaseCitizenInstance(instanceID);
            }
        }
        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);
            }
        }
Exemple #6
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;
        }
        public override void SimulationStep(ushort disasterID, ref DisasterData data)
        {
            //Begin Disaster AI SimulationStep
            if ((data.m_flags & DisasterData.Flags.Clearing) != DisasterData.Flags.None)
            {
                if (!this.IsStillClearing(disasterID, ref data))
                {
                    this.EndDisaster(disasterID, ref data);
                }
            }
            else if ((data.m_flags & DisasterData.Flags.Active) != DisasterData.Flags.None)
            {
                if (!this.IsStillActive(disasterID, ref data))
                {
                    this.DeactivateDisaster(disasterID, ref data);
                }
            }
            else if ((data.m_flags & DisasterData.Flags.Emerging) != DisasterData.Flags.None)
            {
                if (!this.IsStillEmerging(disasterID, ref data))
                {
                    this.ActivateDisaster(disasterID, ref data);
                }
            }
            if ((data.m_flags & DisasterData.Flags.Detected) != DisasterData.Flags.None)
            {
                if ((data.m_flags & DisasterData.Flags.Warning) != DisasterData.Flags.None)
                {
                    if (data.m_broadcastCooldown > 0)
                    {
                        data.m_broadcastCooldown -= 1;
                    }
                    if (data.m_broadcastCooldown == 0)
                    {
                        data.m_broadcastCooldown = 36;
                        if (this.m_info.m_warningBroadcast != null)
                        {
                            Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_warningBroadcast);
                        }
                    }
                }
                else
                {
                    StatisticBase statisticBase = Singleton <StatisticsManager> .instance.Acquire <StatisticInt32>(StatisticType.DisasterCount);

                    statisticBase.Add(16);
                    InstanceID id = default(InstanceID);
                    id.Disaster = disasterID;
                    InstanceManager.Group group = Singleton <InstanceManager> .instance.GetGroup(id);

                    if (data.m_broadcastCooldown >= 200)
                    {
                        if (data.m_broadcastCooldown > 200)
                        {
                            data.m_broadcastCooldown -= 1;
                        }
                        if (data.m_broadcastCooldown == 200 && (group == null || group.m_refCount >= 2))
                        {
                            data.m_broadcastCooldown = 236;
                            if (this.m_info.m_activeBroadcast != null)
                            {
                                Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_activeBroadcast);
                            }
                        }
                    }
                    else
                    {
                        if (data.m_broadcastCooldown > 0)
                        {
                            data.m_broadcastCooldown -= 1;
                        }
                        if (data.m_broadcastCooldown == 0)
                        {
                            data.m_broadcastCooldown = 236;
                            if (this.m_info.m_activeBroadcast != null)
                            {
                                Singleton <AudioManager> .instance.QueueBroadcast(this.m_info.m_activeBroadcast);
                            }
                        }
                    }
                    if (group == null || group.m_refCount >= 2)
                    {
                        if (data.m_chirpCooldown > 0)
                        {
                            data.m_chirpCooldown -= 1;
                        }
                        else if (this.m_info.m_prefabDataIndex != -1)
                        {
                            string key = PrefabCollection <DisasterInfo> .PrefabName((uint)this.m_info.m_prefabDataIndex);

                            if (Locale.Exists("CHIRP_DISASTER", key))
                            {
                                string disasterName = Singleton <DisasterManager> .instance.GetDisasterName(disasterID);

                                Singleton <MessageManager> .instance.TryCreateMessage("CHIRP_DISASTER", key, Singleton <MessageManager> .instance.GetRandomResidentID(), disasterName);

                                data.m_chirpCooldown = (byte)Singleton <SimulationManager> .instance.m_randomizer.Int32(8, 24);
                            }
                        }
                    }
                }
                GuideController properties = Singleton <GuideManager> .instance.m_properties;
                if (this.m_info.m_disasterWarningGuide != null && properties != null)
                {
                    this.m_info.m_disasterWarningGuide.Activate(properties.m_disasterWarning, this.m_info);
                }
            }
            if ((data.m_flags & DisasterData.Flags.Repeat) != DisasterData.Flags.None && ((data.m_flags & (DisasterData.Flags.Finished | DisasterData.Flags.UnReported)) == DisasterData.Flags.Finished || (data.m_flags & (DisasterData.Flags.Clearing | DisasterData.Flags.UnDetected)) == (DisasterData.Flags.Clearing | DisasterData.Flags.UnDetected)))
            {
                this.StartDisaster(disasterID, ref data);
            }
            //End DisasterAI.Simulation Step
            if ((data.m_flags & DisasterData.Flags.Emerging) != DisasterData.Flags.None)
            {
                if (data.m_activationFrame != 0u)
                {
                    uint currentFrameIndex = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                    if (currentFrameIndex + 1755u >= data.m_activationFrame)
                    {
                        if ((data.m_flags & DisasterData.Flags.Significant) != DisasterData.Flags.None)
                        {
                            Singleton <DisasterManager> .instance.DetectDisaster(disasterID, false);
                        }
                        if ((data.m_flags & DisasterData.Flags.SelfTrigger) != DisasterData.Flags.None)
                        {
                            Singleton <WeatherManager> .instance.m_forceWeatherOn = 2f;
                            Singleton <WeatherManager> .instance.m_targetFog      = 0f;
                            //Begin Edit
                            float newThunderstormTargetRain = Mathf.Clamp(((float)data.m_intensity) / 100, 0.25f, 1.0f);
                            Singleton <WeatherManager> .instance.m_targetRain = newThunderstormTargetRain;
                            Debug.Log("[RF]ThunderStormAIDetour Limtied Thunderstorm Rain to " + Singleton <WeatherManager> .instance.m_targetRain);
                            Singleton <WeatherManager> .instance.m_targetCloud = newThunderstormTargetRain;
                            //end edit
                        }
                    }
                }
            }
            else if ((data.m_flags & DisasterData.Flags.Active) != DisasterData.Flags.None && (data.m_flags & DisasterData.Flags.SelfTrigger) != DisasterData.Flags.None)
            {
                Singleton <WeatherManager> .instance.m_forceWeatherOn = 2f;
                Singleton <WeatherManager> .instance.m_targetFog      = 0f;
                //Begin Edit
                float newThunderstormTargetRain = Mathf.Clamp(((float)data.m_intensity) / 100, 0.25f, 1.0f);
                Singleton <WeatherManager> .instance.m_targetRain = newThunderstormTargetRain;
                Debug.Log("[RF]ThunderStormAIDetour Limtied Thunderstorm Rain to " + Singleton <WeatherManager> .instance.m_targetRain);
                Singleton <WeatherManager> .instance.m_targetCloud = newThunderstormTargetRain;
                //end edit
                uint currentFrameIndex2 = Singleton <SimulationManager> .instance.m_currentFrameIndex;
                int  num = 100;
                num = Mathf.Min(num, (int)(currentFrameIndex2 - data.m_activationFrame >> 3));
                num = Mathf.Min(num, (int)(data.m_activationFrame + this.m_activeDuration - currentFrameIndex2 >> 3));
                num = (num * (int)data.m_intensity + 50) / 100;
                Randomizer randomizer = new Randomizer(data.m_randomSeed ^ (ulong)(currentFrameIndex2 >> 8));
                int        num2       = randomizer.Int32(Mathf.Max(1, num / 20), Mathf.Max(1, 1 + num / 10));
                float      num3       = this.m_radius * (0.25f + (float)data.m_intensity * 0.0075f);
                InstanceID id         = default(InstanceID);
                id.Disaster = disasterID;
                InstanceManager.Group group = Singleton <InstanceManager> .instance.GetGroup(id);

                for (int i = 0; i < num2; i++)
                {
                    float   f              = (float)randomizer.Int32(10000u) * 0.0006283185f;
                    float   num4           = Mathf.Sqrt((float)randomizer.Int32(10000u) * 0.0001f) * num3;
                    uint    startFrame     = currentFrameIndex2 + randomizer.UInt32(256u);
                    Vector3 targetPosition = data.m_targetPosition;
                    targetPosition.x += Mathf.Cos(f) * num4;
                    targetPosition.z += Mathf.Sin(f) * num4;
                    targetPosition.y  = Singleton <TerrainManager> .instance.SampleRawHeightSmoothWithWater(targetPosition, false, 0f);

                    Quaternion quaternion = Quaternion.AngleAxis((float)randomizer.Int32(360u), Vector3.up);
                    quaternion *= Quaternion.AngleAxis((float)randomizer.Int32(-15, 15), Vector3.right);
                    Singleton <WeatherManager> .instance.QueueLightningStrike(startFrame, targetPosition, quaternion, group);
                }
            }
        }