Beispiel #1
0
        //based off code in the SimulationStep
        public static void RemoveActiveVehicle(ushort lineID, bool descreaseTargetVehicleCount, int activeVehiclesCount)
        {
            ushort activeVehicle = GetActiveVehicle(ref Singleton <TransportManager> .instance.m_lines.m_buffer[(int)lineID],
                                                    Singleton <SimulationManager> .instance.m_randomizer.Int32((uint)activeVehiclesCount));

            if ((int)activeVehicle != 0)
            {
                TransportLineDetour.RemoveVehicle(lineID, activeVehicle, descreaseTargetVehicleCount);
            }
        }
Beispiel #2
0
        public static void SimulationStep(ref TransportLine thisLine, ushort lineID)
        {
            //begin mod(+): change for initialization
            if (!CachedTransportLineData._init)
            {
                return;
            }
            //end mod

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

                var          itemClass = info.m_class;
                PrefabData[] prefabs   =
                    VehiclePrefabs.instance.GetPrefabs(itemClass.m_service, itemClass.m_subService, itemClass.m_level);
                int amount = 0;
                CountLineActiveVehicles(lineID, out int _, (num3) =>
                {
                    Vehicle vehicle       = VehicleManager.instance.m_vehicles.m_buffer[num3];
                    PrefabData prefabData = Array.Find(prefabs,
                                                       item => item.PrefabDataIndex == vehicle.Info.m_prefabDataIndex);
                    if (prefabData != null)
                    {
                        amount += prefabData.MaintenanceCost;
                        CachedVehicleData.m_cachedVehicleData[num3].StartNewWeek(prefabData.MaintenanceCost);
                    }
                });
                if (amount != 0)
                {
                    Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.Maintenance, amount,
                                                                       info.m_class);
                }
                //end mod
            }
        }