Example #1
0
        private static bool CalculateFillBuffer(ZoneTool z, Vector3 position, Vector3 direction, ItemClass.Zone requiredZone, bool occupied1, bool occupied2)
        {
            var m_fillBuffer1 = (ulong[])typeof(ZoneTool).GetField("m_fillBuffer1", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(z);

            for (int index = 0; index < 64; ++index)
            {
                m_fillBuffer1[index] = 0UL;
            }
            if (!occupied2)
            {
                float       angle    = Mathf.Atan2(-direction.x, direction.z);
                float       num1     = position.x - 256f;
                float       num2     = position.z - 256f;
                float       num3     = position.x + 256f;
                float       num4     = position.z + 256f;
                int         num5     = Mathf.Max((int)((num1 - 46f) / 64f + FakeZoneManager.HALFGRID), 0);
                int         num6     = Mathf.Max((int)((num2 - 46f) / 64f + FakeZoneManager.HALFGRID), 0);
                int         num7     = Mathf.Min((int)((num3 + 46f) / 64f + FakeZoneManager.HALFGRID), FakeZoneManager.GRIDSIZE - 1);
                int         num8     = Mathf.Min((int)((num4 + 46f) / 64f + FakeZoneManager.HALFGRID), FakeZoneManager.GRIDSIZE - 1);
                ZoneManager instance = Singleton <ZoneManager> .instance;
                for (int index1 = num6; index1 <= num8; ++index1)
                {
                    for (int index2 = num5; index2 <= num7; ++index2)
                    {
                        ushort blockIndex = instance.m_zoneGrid[index1 * FakeZoneManager.GRIDSIZE + index2];
                        int    num9       = 0;
                        while ((int)blockIndex != 0)
                        {
                            Vector3 vector3 = instance.m_blocks.m_buffer[(int)blockIndex].m_position;
                            if ((double)Mathf.Max(Mathf.Max(num1 - 46f - vector3.x, num2 - 46f - vector3.z), Mathf.Max((float)((double)vector3.x - (double)num3 - 46.0), (float)((double)vector3.z - (double)num4 - 46.0))) < 0.0)
                            {
                                CalculateFillBuffer(z, position, direction, angle, blockIndex, ref instance.m_blocks.m_buffer[(int)blockIndex], requiredZone, occupied1, occupied2);
                            }
                            blockIndex = instance.m_blocks.m_buffer[(int)blockIndex].m_nextGridBlock;
                            if (++num9 >= ZoneManager.MAX_BLOCK_COUNT)
                            {
                                CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace);

                                break;
                            }
                        }
                    }
                }
            }
            if (((long)m_fillBuffer1[32] & 4294967296L) != 0L)
            {
                m_fillPositions.Clear();
                int     num1 = 0;
                int     num2 = 32;
                int     num3 = 32;
                int     num4 = 32;
                int     num5 = 32;
                FillPos fillPos1;
                fillPos1.m_x = (byte)32;
                fillPos1.m_z = (byte)32;
                m_fillPositions.Add(fillPos1);
                m_fillBuffer1[32] &= 18446744069414584319UL;
                while (num1 < m_fillPositions.m_size)
                {
                    FillPos fillPos2 = m_fillPositions.m_buffer[num1++];
                    if ((int)fillPos2.m_z > 0)
                    {
                        FillPos fillPos3 = fillPos2;
                        --fillPos3.m_z;
                        if (((long)m_fillBuffer1[(int)fillPos3.m_z] & 1L << (int)fillPos3.m_x) != 0L)
                        {
                            m_fillPositions.Add(fillPos3);
                            m_fillBuffer1[(int)fillPos3.m_z] &= (ulong)~(1L << (int)fillPos3.m_x);
                            if ((int)fillPos3.m_z < num3)
                            {
                                num3 = (int)fillPos3.m_z;
                            }
                        }
                    }
                    if ((int)fillPos2.m_x > 0)
                    {
                        FillPos fillPos3 = fillPos2;
                        --fillPos3.m_x;
                        if (((long)m_fillBuffer1[(int)fillPos3.m_z] & 1L << (int)fillPos3.m_x) != 0L)
                        {
                            m_fillPositions.Add(fillPos3);
                            m_fillBuffer1[(int)fillPos3.m_z] &= (ulong)~(1L << (int)fillPos3.m_x);
                            if ((int)fillPos3.m_x < num2)
                            {
                                num2 = (int)fillPos3.m_x;
                            }
                        }
                    }
                    if ((int)fillPos2.m_x < 63)
                    {
                        FillPos fillPos3 = fillPos2;
                        ++fillPos3.m_x;
                        if (((long)m_fillBuffer1[(int)fillPos3.m_z] & 1L << (int)fillPos3.m_x) != 0L)
                        {
                            m_fillPositions.Add(fillPos3);
                            m_fillBuffer1[(int)fillPos3.m_z] &= (ulong)~(1L << (int)fillPos3.m_x);
                            if ((int)fillPos3.m_x > num4)
                            {
                                num4 = (int)fillPos3.m_x;
                            }
                        }
                    }
                    if ((int)fillPos2.m_z < 63)
                    {
                        FillPos fillPos3 = fillPos2;
                        ++fillPos3.m_z;
                        if (((long)m_fillBuffer1[(int)fillPos3.m_z] & 1L << (int)fillPos3.m_x) != 0L)
                        {
                            m_fillPositions.Add(fillPos3);
                            m_fillBuffer1[(int)fillPos3.m_z] &= (ulong)~(1L << (int)fillPos3.m_x);
                            if ((int)fillPos3.m_z > num5)
                            {
                                num5 = (int)fillPos3.m_z;
                            }
                        }
                    }
                }
                for (int index = 0; index < 64; ++index)
                {
                    m_fillBuffer1[index] = 0UL;
                }
                for (int index = 0; index < m_fillPositions.m_size; ++index)
                {
                    FillPos fillPos2 = m_fillPositions.m_buffer[index];
                    m_fillBuffer1[(int)fillPos2.m_z] |= (ulong)(1L << (int)fillPos2.m_x);
                }
                return(true);
            }
            for (int index = 0; index < 64; ++index)
            {
                m_fillBuffer1[index] = 0UL;
            }
            return(false);
        }
        protected void EnsureCitizenUnits(ushort buildingID, ref Building data, int homeCount, int workCount, int visitCount, int studentCount)
        {
            int totalWorkCount  = (workCount + 4) / 5;
            int totalVisitCount = (visitCount + 4) / 5;
            int totalHomeCount  = homeCount;

            int[] workersRequired = new int[] { 0, 0, 0, 0 };

            if ((data.m_flags & (Building.Flags.Abandoned | Building.Flags.BurnedDown)) == Building.Flags.None)
            {
                Citizen.Wealth wealthLevel = Citizen.GetWealthLevel(this.m_info.m_class.m_level);
                uint           num         = 0u;
                uint           num2        = data.m_citizenUnits;
                int            num3        = 0;
                while (num2 != 0u)
                {
                    CitizenUnit.Flags flags = citizenUnitArray[(int)((UIntPtr)num2)].m_flags;
                    if ((ushort)(flags & CitizenUnit.Flags.Home) != 0)
                    {
                        citizenUnitArray[(int)((UIntPtr)num2)].SetWealthLevel(wealthLevel);
                        homeCount--;
                    }
                    if ((ushort)(flags & CitizenUnit.Flags.Work) != 0)
                    {
                        workCount -= 5;
                        for (int i = 0; i < 5; i++)
                        {
                            uint citizen = citizenUnitArray[(int)((UIntPtr)num2)].GetCitizen(i);
                            if (citizen != 0u)
                            {
                                // Tick off education to see what is there
                                workersRequired[(int)citizenArray[(int)((UIntPtr)citizen)].EducationLevel]--;
                            }
                        }
                    }
                    if ((ushort)(flags & CitizenUnit.Flags.Visit) != 0)
                    {
                        visitCount -= 5;
                    }
                    if ((ushort)(flags & CitizenUnit.Flags.Student) != 0)
                    {
                        studentCount -= 5;
                    }
                    num  = num2;
                    num2 = citizenUnitArray[(int)((UIntPtr)num2)].m_nextUnit;
                    if (++num3 > 524288)
                    {
                        CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                        break;
                    }
                } // end while

                /*
                 *              homeCount = Mathf.Max(0, homeCount);
                 *              workCount = Mathf.Max(0, workCount);
                 */
                visitCount   = Mathf.Max(0, visitCount);
                studentCount = Mathf.Max(0, studentCount);

                if (homeCount > 0 || workCount > 0 || visitCount > 0 || studentCount > 0)
                {
                    uint num4 = 0u;
                    if (citizenManager.CreateUnits(out num4, ref Singleton <SimulationManager> .instance.m_randomizer, buildingID, 0, homeCount, workCount, visitCount, 0, studentCount))
                    {
                        if (num != 0u)
                        {
                            citizenUnitArray[(int)((UIntPtr)num)].m_nextUnit = num4;
                        }
                        else
                        {
                            data.m_citizenUnits = num4;
                        }
                    }
                }

                if (DataStore.strictCapacity)
                {
                    // This is done to have the count in numbers of citizen units and only if the building is of a privateBuilding (Res, Com, Ind, Office)
                    // There also appears to be an issue that without allowRemovalOfCitizens flag, the population will dip, then shoot up.
                    if (DataStore.allowRemovalOfCitizens && (data.Info.GetAI() is PrivateBuildingAI))
                    {
                        // Stop incoming offers to get HandleWorkers() to start fresh
                        TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                        offer.Building = buildingID;
                        Singleton <TransferManager> .instance.RemoveIncomingOffer(TransferManager.TransferReason.Worker0, offer);

                        Singleton <TransferManager> .instance.RemoveIncomingOffer(TransferManager.TransferReason.Worker1, offer);

                        Singleton <TransferManager> .instance.RemoveIncomingOffer(TransferManager.TransferReason.Worker2, offer);

                        Singleton <TransferManager> .instance.RemoveIncomingOffer(TransferManager.TransferReason.Worker3, offer);

                        int worker0 = 0;
                        int worker1 = 0;
                        int worker2 = 0;
                        int worker3 = 0;
                        ((PrivateBuildingAI)data.Info.GetAI()).CalculateWorkplaceCount(new Randomizer((int)buildingID), data.Width, data.Length,
                                                                                       out worker0, out worker1, out worker2, out worker3);

                        // Update the workers required once figuring out how many are needed by the new building
                        workersRequired[0] += worker0;
                        workersRequired[1] += worker1;
                        workersRequired[2] += worker2;
                        workersRequired[3] += worker3;

                        if (workCount < 0)
                        {
                            RemoveWorkerBuilding(buildingID, ref data, totalWorkCount);
                        }
                        else if (homeCount < 0)
                        {
                            RemoveHouseHold(buildingID, ref data, totalHomeCount);
                        }

                        /*
                         *  if (visitCount < 0)
                         *  {
                         *      RemoveVisitorsBuilding(buildingID, ref data, totalVisitCount);
                         *  }
                         */
                        PromoteWorkers(buildingID, ref data, ref workersRequired);
                        // Do nothing for students
                    } // end if PrivateBuildingAI
                }     // end strictCapacity
            }         // end if good building
        }             // end EnsureCitizenUnits
        //PostOfficeAI.CalculateOwnVehicles rewritten as a public static method (private instance method).
        public static void CalculateVehicles(ushort buildingID, ref Building data, ref int unsortedMail, ref int sortedMail, ref int unsortedCapacity, ref int sortedCapacity, ref int ownVanCount, ref int ownTruckCount, ref int import, ref int export)
        {
            VehicleManager instance = Singleton <VehicleManager> .instance;
            ushort         num      = data.m_ownVehicles;
            int            num2     = 0;

            while (num != 0)
            {
                switch (instance.m_vehicles.m_buffer[num].m_transferType)
                {
                case 92:
                {
                    ownVanCount++;
                    VehicleInfo info = instance.m_vehicles.m_buffer[num].Info;
                    info.m_vehicleAI.GetSize(num, ref instance.m_vehicles.m_buffer[num], out int size, out int max);
                    unsortedMail     += Mathf.Min(size, max);
                    unsortedCapacity += Mathf.Min(size, max);
                    sortedMail       += Mathf.Max(0, max - size);
                    sortedCapacity   += Mathf.Max(0, max - size);
                    break;
                }

                case 93:
                    ownTruckCount++;
                    if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.TransferToTarget) != 0)
                    {
                        VehicleInfo info4 = instance.m_vehicles.m_buffer[num].Info;
                        info4.m_vehicleAI.GetSize(num, ref instance.m_vehicles.m_buffer[num], out int _, out int max4);
                        sortedCapacity += max4;
                        if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.Exporting) != 0)
                        {
                            export++;
                        }
                    }
                    else if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.TransferToSource) != 0)
                    {
                        VehicleInfo info5 = instance.m_vehicles.m_buffer[num].Info;
                        info5.m_vehicleAI.GetSize(num, ref instance.m_vehicles.m_buffer[num], out int size5, out int max5);
                        unsortedMail     += Mathf.Min(size5, max5);
                        unsortedCapacity += max5;
                        if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.Importing) != 0)
                        {
                            import++;
                        }
                    }
                    break;

                case 94:
                case 96:
                    ownTruckCount++;
                    if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.TransferToTarget) != 0)
                    {
                        VehicleInfo info2 = instance.m_vehicles.m_buffer[num].Info;
                        info2.m_vehicleAI.GetSize(num, ref instance.m_vehicles.m_buffer[num], out int _, out int max2);
                        unsortedCapacity += max2;
                        if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.Exporting) != 0)
                        {
                            export++;
                        }
                    }
                    else if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.TransferToSource) != 0)
                    {
                        VehicleInfo info3 = instance.m_vehicles.m_buffer[num].Info;
                        info3.m_vehicleAI.GetSize(num, ref instance.m_vehicles.m_buffer[num], out int size3, out int max3);
                        sortedMail     += Mathf.Min(size3, max3);
                        sortedCapacity += max3;
                        if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.Importing) != 0)
                        {
                            import++;
                        }
                    }
                    break;

                case 95:
                    ownTruckCount++;
                    if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.Exporting) != 0)
                    {
                        export++;
                    }
                    break;
                }
                num = instance.m_vehicles.m_buffer[num].m_nextOwnVehicle;
                if (++num2 > 16384)
                {
                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                    break;
                }
            }
            num  = data.m_guestVehicles;
            num2 = 0;
            do
            {
                if (num == 0)
                {
                    return;
                }
                switch (instance.m_vehicles.m_buffer[num].m_transferType)
                {
                case 93:
                    if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.TransferToSource) != 0)
                    {
                        if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.Exporting) != 0)
                        {
                            export++;
                        }
                    }
                    else if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.TransferToTarget) != 0)
                    {
                        VehicleInfo info6 = instance.m_vehicles.m_buffer[num].Info;
                        info6.m_vehicleAI.GetSize(num, ref instance.m_vehicles.m_buffer[num], out int size6, out int max6);
                        unsortedMail     += Mathf.Min(size6, max6);
                        unsortedCapacity += Mathf.Min(size6, max6);
                        if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.Importing) != 0)
                        {
                            import++;
                        }
                    }
                    break;

                case 94:
                case 96:
                    if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.TransferToSource) != 0)
                    {
                        if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.Exporting) != 0)
                        {
                            export++;
                        }
                    }
                    else if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.TransferToTarget) != 0)
                    {
                        VehicleInfo info7 = instance.m_vehicles.m_buffer[num].Info;
                        info7.m_vehicleAI.GetSize(num, ref instance.m_vehicles.m_buffer[num], out int size7, out int max7);
                        sortedMail     += Mathf.Min(size7, max7);
                        sortedCapacity += Mathf.Min(size7, max7);
                        if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.Importing) != 0)
                        {
                            import++;
                        }
                    }
                    break;

                case 95:
                    if ((instance.m_vehicles.m_buffer[num].m_flags & Vehicle.Flags.Exporting) != 0)
                    {
                        export++;
                    }
                    break;
                }
                num = instance.m_vehicles.m_buffer[num].m_nextGuestVehicle;
            }while (++num2 <= 16384);
            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);
        }
Example #4
0
        public void updateBidings()
        {
            BuildingInfo basicInfo = Singleton <BuildingManager> .instance.m_buildings.m_buffer[m_buildingIdSelecionado.Building].Info;
            DepotAI      basicAI   = basicInfo.GetAI() as DepotAI;

            if (basicAI == null)
            {
                closeDepotInfo(null, null);
                return;
            }

            TransportStationAI stationAI = basicInfo.GetAI() as TransportStationAI;
            HarborAI           harborAI  = basicInfo.GetAI() as HarborAI;


            vehiclesInUseLabel.text = LocaleFormatter.FormatGeneric("TRANSPORT_LINE_VEHICLECOUNT", new object[] { basicAI.GetVehicleCount(m_buildingIdSelecionado.Building, ref Singleton <BuildingManager> .instance.m_buildings.m_buffer[m_buildingIdSelecionado.Building]).ToString() });
            if (stationAI != null)
            {
                passengersLastWeek.isVisible = true;
                int passengerCount = stationAI.GetPassengerCount(m_buildingIdSelecionado.Building, ref Singleton <BuildingManager> .instance.m_buildings.m_buffer[m_buildingIdSelecionado.Building]);
                passengersLastWeek.text = LocaleFormatter.FormatGeneric("AIINFO_PASSENGERS_SERVICED", new object[] { passengerCount });
            }
            else
            {
                passengersLastWeek.isVisible = false;
            }

            upkeepCost.text = LocaleFormatter.FormatUpkeep(basicAI.GetResourceRate(m_buildingIdSelecionado.Building, ref Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)m_buildingIdSelecionado.Building], EconomyManager.Resource.Maintenance), false);

            uint num         = Singleton <BuildingManager> .instance.m_buildings.m_buffer[m_buildingIdSelecionado.Building].m_citizenUnits;
            int  num2        = 0;
            int  num3        = 0;
            int  unskill     = 0;
            int  oneSchool   = 0;
            int  twoSchool   = 0;
            int  threeSchool = 0;

            CitizenManager instance = Singleton <CitizenManager> .instance;

            while (num != 0u)
            {
                uint nextUnit = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_nextUnit;
                if ((ushort)(instance.m_units.m_buffer[(int)((UIntPtr)num)].m_flags & CitizenUnit.Flags.Work) != 0)
                {
                    for (int i = 0; i < 5; i++)
                    {
                        uint citizen = instance.m_units.m_buffer[(int)((UIntPtr)num)].GetCitizen(i);
                        if (citizen != 0u && !instance.m_citizens.m_buffer[(int)((UIntPtr)citizen)].Dead && (instance.m_citizens.m_buffer[(int)((UIntPtr)citizen)].m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None)
                        {
                            num3++;
                            switch (instance.m_citizens.m_buffer[(int)((UIntPtr)citizen)].EducationLevel)
                            {
                            case Citizen.Education.Uneducated:
                                unskill++;
                                break;

                            case Citizen.Education.OneSchool:
                                oneSchool++;
                                break;

                            case Citizen.Education.TwoSchools:
                                twoSchool++;
                                break;

                            case Citizen.Education.ThreeSchools:
                                threeSchool++;
                                break;
                            }
                        }
                    }
                }
                num = nextUnit;
                if (++num2 > 524288)
                {
                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                    break;
                }
            }

            workerChart.SetValues(new int[] { unskill, oneSchool, twoSchool, threeSchool }, new int[] { basicAI.m_workPlaceCount0, basicAI.m_workPlaceCount1, basicAI.m_workPlaceCount2, basicAI.m_workPlaceCount3 });
        }
        public static bool FindPathPositionWithSpiralLoop(Vector3 position, Vector3?secondaryPosition, ItemClass.Service service, NetInfo.LaneType laneType, VehicleInfo.VehicleType vehicleType, VehicleInfo.VehicleType stopType, bool allowUnderground, bool requireConnect, float maxDistance, out PathUnit.Position pathPosA, out PathUnit.Position pathPosB, out float distanceSqrA, out float distanceSqrB)
        {
            int iMin = Mathf.Max((int)((position.z - (float)NetManager.NODEGRID_CELL_SIZE) / (float)NetManager.NODEGRID_CELL_SIZE + (float)NetManager.NODEGRID_RESOLUTION / 2f), 0);
            int iMax = Mathf.Min((int)((position.z + (float)NetManager.NODEGRID_CELL_SIZE) / (float)NetManager.NODEGRID_CELL_SIZE + (float)NetManager.NODEGRID_RESOLUTION / 2f), NetManager.NODEGRID_RESOLUTION - 1);

            int jMin = Mathf.Max((int)((position.x - (float)NetManager.NODEGRID_CELL_SIZE) / (float)NetManager.NODEGRID_CELL_SIZE + (float)NetManager.NODEGRID_RESOLUTION / 2f), 0);
            int jMax = Mathf.Min((int)((position.x + (float)NetManager.NODEGRID_CELL_SIZE) / (float)NetManager.NODEGRID_CELL_SIZE + (float)NetManager.NODEGRID_RESOLUTION / 2f), NetManager.NODEGRID_RESOLUTION - 1);

            int width  = iMax - iMin + 1;
            int height = jMax - jMin + 1;

            int centerI = (int)(position.z / (float)NetManager.NODEGRID_CELL_SIZE + (float)NetManager.NODEGRID_RESOLUTION / 2f);
            int centerJ = (int)(position.x / (float)NetManager.NODEGRID_CELL_SIZE + (float)NetManager.NODEGRID_RESOLUTION / 2f);

            NetManager netManager = Singleton <NetManager> .instance;

            /*pathPosA.m_segment = 0;
             * pathPosA.m_lane = 0;
             * pathPosA.m_offset = 0;*/
            distanceSqrA = 1E+10f;

            /*pathPosB.m_segment = 0;
             * pathPosB.m_lane = 0;
             * pathPosB.m_offset = 0;*/
            distanceSqrB = 1E+10f;
            float minDist = float.MaxValue;

            PathUnit.Position myPathPosA     = default(PathUnit.Position);
            float             myDistanceSqrA = float.MaxValue;

            PathUnit.Position myPathPosB     = default(PathUnit.Position);
            float             myDistanceSqrB = float.MaxValue;

            int  lastSpiralDist = 0;
            bool found          = false;

            LoopUtil.SpiralLoop(centerI, centerJ, width, height, delegate(int i, int j) {
                if (i < 0 || i >= NetManager.NODEGRID_RESOLUTION || j < 0 || j >= NetManager.NODEGRID_RESOLUTION)
                {
                    return(true);
                }

                int spiralDist = Math.Max(Math.Abs(i - centerI), Math.Abs(j - centerJ));                 // maximum norm

                if (found && spiralDist > lastSpiralDist)
                {
                    // last iteration
                    return(false);
                }

                ushort segmentId = netManager.m_segmentGrid[i * NetManager.NODEGRID_RESOLUTION + j];
                int iterations   = 0;
                while (segmentId != 0)
                {
                    NetInfo segmentInfo = netManager.m_segments.m_buffer[segmentId].Info;
                    if (segmentInfo != null &&
                        segmentInfo.m_class.m_service == service &&
                        (netManager.m_segments.m_buffer[segmentId].m_flags & (NetSegment.Flags.Collapsed | NetSegment.Flags.Flooded)) == NetSegment.Flags.None && (allowUnderground || !segmentInfo.m_netAI.IsUnderground())
                        )
                    {
                        ushort startNodeId   = netManager.m_segments.m_buffer[segmentId].m_startNode;
                        ushort endNodeId     = netManager.m_segments.m_buffer[segmentId].m_endNode;
                        Vector3 startNodePos = netManager.m_nodes.m_buffer[startNodeId].m_position;
                        Vector3 endNodePos   = netManager.m_nodes.m_buffer[endNodeId].m_position;

                        Vector3 posA; int laneIndexA; float laneOffsetA;
                        Vector3 posB; int laneIndexB; float laneOffsetB;

                        if (netManager.m_segments.m_buffer[segmentId].GetClosestLanePosition(position, laneType, vehicleType, stopType, requireConnect, out posA, out laneIndexA, out laneOffsetA, out posB, out laneIndexB, out laneOffsetB))
                        {
                            float dist = Vector3.SqrMagnitude(position - posA);
                            if (secondaryPosition != null)
                            {
                                dist += Vector3.SqrMagnitude((Vector3)secondaryPosition - posA);
                            }

                            if (dist < minDist)
                            {
                                found = true;

                                minDist = dist;
                                myPathPosA.m_segment = segmentId;
                                myPathPosA.m_lane    = (byte)laneIndexA;
                                myPathPosA.m_offset  = (byte)Mathf.Clamp(Mathf.RoundToInt(laneOffsetA * 255f), 0, 255);
                                myDistanceSqrA       = dist;

                                dist = Vector3.SqrMagnitude(position - posB);
                                if (secondaryPosition != null)
                                {
                                    dist += Vector3.SqrMagnitude((Vector3)secondaryPosition - posB);
                                }

                                if (laneIndexB < 0)
                                {
                                    myPathPosB.m_segment = 0;
                                    myPathPosB.m_lane    = 0;
                                    myPathPosB.m_offset  = 0;
                                    myDistanceSqrB       = float.MaxValue;
                                }
                                else
                                {
                                    myPathPosB.m_segment = segmentId;
                                    myPathPosB.m_lane    = (byte)laneIndexB;
                                    myPathPosB.m_offset  = (byte)Mathf.Clamp(Mathf.RoundToInt(laneOffsetB * 255f), 0, 255);
                                    myDistanceSqrB       = dist;
                                }
                            }
                        }
                    }

                    segmentId = netManager.m_segments.m_buffer[segmentId].m_nextGridSegment;
                    if (++iterations >= NetManager.MAX_SEGMENT_COUNT)
                    {
                        CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);
                        break;
                    }
                }

                lastSpiralDist = spiralDist;
                return(true);
            });

            pathPosA     = myPathPosA;
            distanceSqrA = myDistanceSqrA;
            pathPosB     = myPathPosB;
            distanceSqrB = myDistanceSqrB;

            return(pathPosA.m_segment != 0);
        }
        public void SimulationStep(ushort lineID)
        {
            TransportInfo info = this.Info;

            if (this.Complete)
            {
                int num = 0;
                if (this.m_vehicles != 0)
                {
                    VehicleManager instance = Singleton <VehicleManager> .instance;
                    ushort         num2     = this.m_vehicles;
                    int            num3     = 0;
                    while (num2 != 0)
                    {
                        ushort nextLineVehicle = instance.m_vehicles.m_buffer [(int)num2].m_nextLineVehicle;
                        num++;
                        num2 = nextLineVehicle;
                        if (++num3 > 65536)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
                bool flag;
                if (Singleton <SimulationManager> .instance.m_isNightTime)
                {
                    flag = ((this.m_flags & TransportLine.Flags.DisabledNight) == TransportLine.Flags.None);
                }
                else
                {
                    flag = ((this.m_flags & TransportLine.Flags.DisabledDay) == TransportLine.Flags.None);
                }
                uint  num4 = 0u;
                float num5 = 0f;
                if (this.m_stops != 0)
                {
                    NetManager instance2 = Singleton <NetManager> .instance;
                    ushort     stops     = this.m_stops;
                    ushort     num6      = stops;
                    int        num7      = 0;
                    while (num6 != 0)
                    {
                        ushort num8 = 0;
                        if (flag)
                        {
                            NetNode[] expr_107_cp_0 = instance2.m_nodes.m_buffer;
                            ushort    expr_107_cp_1 = num6;
                            expr_107_cp_0 [(int)expr_107_cp_1].m_flags = (expr_107_cp_0 [(int)expr_107_cp_1].m_flags & ~NetNode.Flags.Disabled);
                        }
                        else
                        {
                            NetNode[] expr_12D_cp_0 = instance2.m_nodes.m_buffer;
                            ushort    expr_12D_cp_1 = num6;
                            expr_12D_cp_0 [(int)expr_12D_cp_1].m_flags = (expr_12D_cp_0 [(int)expr_12D_cp_1].m_flags | NetNode.Flags.Disabled);
                        }
                        for (int i = 0; i < 8; i++)
                        {
                            ushort segment = instance2.m_nodes.m_buffer [(int)num6].GetSegment(i);
                            if (segment != 0 && instance2.m_segments.m_buffer [(int)segment].m_startNode == num6)
                            {
                                num5 += instance2.m_segments.m_buffer [(int)segment].m_averageLength;
                                num8  = instance2.m_segments.m_buffer [(int)segment].m_endNode;
                                break;
                            }
                        }
                        num4 += 1u;
                        num6  = num8;
                        if (num6 == stops)
                        {
                            break;
                        }
                        if (++num7 >= 32768)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
                int num9 = num * info.m_maintenanceCostPerVehicle / 100;
                if (num9 != 0)
                {
                    Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.Maintenance, num9, info.m_class);
                }
                int budget = Singleton <EconomyManager> .instance.GetBudget(info.m_class);

                int num10;
                if (flag)
                {
                    num10 = Mathf.CeilToInt((float)budget * num5 / (info.m_defaultVehicleDistance * 100f));
                }
                else
                {
                    num10 = 0;
                }
                if (num4 != 0u && num < num10)
                {
                    TransferManager.TransferReason vehicleReason = info.m_vehicleReason;
                    int index = Singleton <SimulationManager> .instance.m_randomizer.Int32(num4);

                    ushort stop = this.GetStop(index);
                    if (vehicleReason != TransferManager.TransferReason.None && stop != 0)
                    {
                        TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                        offer.Priority      = num10 - num + 1;
                        offer.TransportLine = lineID;
                        offer.Position      = Singleton <NetManager> .instance.m_nodes.m_buffer [(int)stop].m_position;
                        offer.Amount        = 1;
                        offer.Active        = false;
                        Singleton <TransferManager> .instance.AddIncomingOffer(vehicleReason, offer);
                    }
                }
                else
                {
                    if (num > num10)
                    {
                        int index2 = Singleton <SimulationManager> .instance.m_randomizer.Int32((uint)num);

                        ushort vehicle = this.GetVehicle(index2);
                        if (vehicle != 0)
                        {
                            VehicleManager instance3 = Singleton <VehicleManager> .instance;
                            VehicleInfo    info2     = instance3.m_vehicles.m_buffer [(int)vehicle].Info;
                            info2.m_vehicleAI.SetTransportLine(vehicle, ref instance3.m_vehicles.m_buffer [(int)vehicle], 0);
                        }
                    }
                }
            }
            if ((Singleton <SimulationManager> .instance.m_currentFrameIndex & 4095u) >= 3840u)
            {
                this.m_passengers.Update();
                Singleton <TransportManager> .instance.m_passengers [(int)info.m_transportType].Add(ref this.m_passengers);
                this.m_passengers.Reset();
            }
        }
Example #7
0
        private HashSet <Instance> GetMarqueeList(Ray mouseRay)
        {
            HashSet <Instance> list = new HashSet <Instance>();

            Building[]     buildingBuffer = Singleton <BuildingManager> .instance.m_buildings.m_buffer;
            NetNode[]      nodeBuffer     = Singleton <NetManager> .instance.m_nodes.m_buffer;
            NetSegment[]   segmentBuffer  = Singleton <NetManager> .instance.m_segments.m_buffer;
            TreeInstance[] treeBuffer     = Singleton <TreeManager> .instance.m_trees.m_buffer;

            m_selection.a = m_clickPositionAbs;
            m_selection.c = RaycastMouseLocation(mouseRay);

            if (m_selection.a.x == m_selection.c.x && m_selection.a.z == m_selection.c.z)
            {
                m_selection = default;
            }
            else
            {
                float   angle = Camera.main.transform.localEulerAngles.y * Mathf.Deg2Rad;
                Vector3 down  = new Vector3(Mathf.Cos(angle), 0, -Mathf.Sin(angle));
                Vector3 right = new Vector3(-down.z, 0, down.x);

                Vector3 a        = m_selection.c - m_selection.a;
                float   dotDown  = Vector3.Dot(a, down);
                float   dotRight = Vector3.Dot(a, right);

                if ((dotDown > 0 && dotRight > 0) || (dotDown <= 0 && dotRight <= 0))
                {
                    m_selection.b = m_selection.a + dotDown * down;
                    m_selection.d = m_selection.a + dotRight * right;
                }
                else
                {
                    m_selection.b = m_selection.a + dotRight * right;
                    m_selection.d = m_selection.a + dotDown * down;
                }

                Vector3 min = m_selection.Min();
                Vector3 max = m_selection.Max();

                int gridMinX = Mathf.Max((int)((min.x - 16f) / 64f + 135f), 0);
                int gridMinZ = Mathf.Max((int)((min.z - 16f) / 64f + 135f), 0);
                int gridMaxX = Mathf.Min((int)((max.x + 16f) / 64f + 135f), 269);
                int gridMaxZ = Mathf.Min((int)((max.z + 16f) / 64f + 135f), 269);

                InstanceID      id         = new InstanceID();
                ItemClass.Layer itemLayers = GetItemLayers();

                if (PO.Active && (filterProcs || filterPicker))
                {
                    foreach (PO_Object obj in PO.Objects)
                    {
                        if (!filterProcs)
                        { // Implies filterPicker is true
                            if (obj.GetPrefab() != Filters.Picker.Info)
                            {
                                continue;
                            }
                        }
                        if (!obj.isHidden() && PointInRectangle(m_selection, obj.Position))
                        {
                            id.NetLane = obj.Id;
                            list.AddObject(id);
                        }
                    }
                }

                for (int i = gridMinZ; i <= gridMaxZ; i++)
                {
                    for (int j = gridMinX; j <= gridMaxX; j++)
                    {
                        if (filterBuildings || filterSurfaces || (filterPicker && Filters.Picker.IsBuilding))
                        {
                            ushort building = BuildingManager.instance.m_buildingGrid[i * 270 + j];
                            int    count    = 0;
                            while (building != 0u)
                            {
                                if (IsBuildingValid(ref buildingBuffer[building], itemLayers) && PointInRectangle(m_selection, buildingBuffer[building].m_position))
                                {
                                    if (Filters.Filter(buildingBuffer[building].Info, ref buildingBuffer[building]))
                                    {
                                        id.Building = Building.FindParentBuilding(building);
                                        if (id.Building == 0)
                                        {
                                            id.Building = building;
                                        }
                                        list.Add(id);
                                    }
                                }
                                building = buildingBuffer[building].m_nextGridBuilding;

                                if (++count > 49152)
                                {
                                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Buildings: Invalid list detected!\n" + Environment.StackTrace);

                                    break;
                                }
                            }
                        }

                        if (filterProps || filterDecals || filterSurfaces || (filterPicker && Filters.Picker.IsProp))
                        {
                            PropLayer.Manager.GetMarqueeList(ref i, ref j, ref id, ref m_selection, ref list);
                        }

                        if (filterNodes || filterBuildings || (filterPicker && Filters.Picker.IsNode))
                        {
                            ushort node  = NetManager.instance.m_nodeGrid[i * 270 + j];
                            int    count = 0;
                            while (node != 0u)
                            {
                                if (IsNodeValid(ref nodeBuffer[node], itemLayers) && PointInRectangle(m_selection, nodeBuffer[node].m_position))
                                {
                                    ushort building = NetNode.FindOwnerBuilding(node, 363f);

                                    if (building != 0)
                                    {
                                        if (filterBuildings)
                                        {
                                            id.Building = Building.FindParentBuilding(building);
                                            if (id.Building == 0)
                                            {
                                                id.Building = building;
                                            }
                                            list.Add(id);
                                        }
                                    }
                                    else if (filterNodes || (filterPicker && Filters.Picker.IsNode))
                                    {
                                        if (Filters.Filter(nodeBuffer[node]))
                                        {
                                            id.NetNode = node;
                                            list.Add(id);
                                        }
                                    }
                                }
                                node = nodeBuffer[node].m_nextGridNode;

                                if (++count > 32768)
                                {
                                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Nodes: Invalid list detected!\n" + Environment.StackTrace);
                                }
                            }
                        }

                        if (filterSegments || filterBuildings || (filterPicker && Filters.Picker.IsSegment))
                        {
                            ushort segment = NetManager.instance.m_segmentGrid[i * 270 + j];
                            int    count   = 0;
                            while (segment != 0u)
                            {
                                if (IsSegmentValid(ref segmentBuffer[segment], itemLayers) && PointInRectangle(m_selection, segmentBuffer[segment].m_bounds.center))
                                {
                                    ushort building = FindOwnerBuilding(segment, 363f);

                                    if (building != 0)
                                    {
                                        if (filterBuildings)
                                        {
                                            id.Building = Building.FindParentBuilding(building);
                                            if (id.Building == 0)
                                            {
                                                id.Building = building;
                                            }
                                            list.Add(id);
                                        }
                                    }
                                    else if (filterSegments || (filterPicker && Filters.Picker.IsSegment))
                                    {
                                        if (Filters.Filter(segmentBuffer[segment]))
                                        {
                                            id.NetSegment = segment;
                                            list.Add(id);
                                        }
                                    }
                                }
                                segment = segmentBuffer[segment].m_nextGridSegment;

                                if (++count > 36864)
                                {
                                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Segments: Invalid list detected!\n" + Environment.StackTrace);
                                }
                            }
                        }
                    }
                }

                if (filterTrees || (filterPicker && Filters.Picker.IsTree))
                {
                    gridMinX = Mathf.Max((int)((min.x - 8f) / 32f + 270f), 0);
                    gridMinZ = Mathf.Max((int)((min.z - 8f) / 32f + 270f), 0);
                    gridMaxX = Mathf.Min((int)((max.x + 8f) / 32f + 270f), 539);
                    gridMaxZ = Mathf.Min((int)((max.z + 8f) / 32f + 270f), 539);

                    for (int i = gridMinZ; i <= gridMaxZ; i++)
                    {
                        for (int j = gridMinX; j <= gridMaxX; j++)
                        {
                            uint tree = TreeManager.instance.m_treeGrid[i * 540 + j];

                            while (tree != 0)
                            {
                                if (PointInRectangle(m_selection, treeBuffer[tree].Position))
                                {
                                    if (Filters.Filter(treeBuffer[tree].Info))
                                    {
                                        id.Tree = tree;
                                        list.Add(id);
                                    }
                                }
                                tree = treeBuffer[tree].m_nextGridTree;
                            }
                        }
                    }
                }
            }

            return(list);
        }
        /*********** building updates *************/

        //residential building history updates
        public void UpdateResidentFamilies(int resilient_index)
        {
            if (!Settings.inst.listResidentsAndWorkers)
            {
                return;
            }

            List <uint> current_families_id = new List <uint>();

            Building       build          = Singleton <BuildingManager> .instance.m_buildings.m_buffer[m_resilients[resilient_index].buildingID];
            CitizenManager instance       = Singleton <CitizenManager> .instance;
            uint           num            = build.m_citizenUnits;
            int            num2           = 0;
            int            aliveHomeCount = 0;

            while (num != 0u)
            {
                uint nextUnit = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_nextUnit;
                if ((ushort)(instance.m_units.m_buffer[(int)((UIntPtr)num)].m_flags & CitizenUnit.Flags.Home) != 0)
                {
                    current_families_id.Add(num);
                    aliveHomeCount++;
                }
                num = nextUnit;

                if (++num2 > 524288)
                {
                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                    break;
                }
            }

            //update history family list with any new names
            int index_families_before_now = Math.Max(m_resilients[resilient_index].namesBuffer.Count - aliveHomeCount, 0);

            for (int i = 0; i < current_families_id.Count; i++)
            {
//				if(!m_resilients[resilient_index].idsBuffer.Contains(current_families_id[i]))
//				{
//					m_resilients[resilient_index].idsBuffer.Add(current_families_id[i]);
//				}

                uint        valid_citizen = 0u;
                CitizenUnit cu            = Singleton <CitizenManager> .instance.m_units.m_buffer[current_families_id[i]];
                if (cu.m_citizen0 != 0u)
                {
                    valid_citizen = cu.m_citizen0;
                }
                else if (cu.m_citizen1 != 0u)
                {
                    valid_citizen = cu.m_citizen1;
                }
                else if (cu.m_citizen2 != 0u)
                {
                    valid_citizen = cu.m_citizen2;
                }
                else if (cu.m_citizen3 != 0u)
                {
                    valid_citizen = cu.m_citizen3;
                }
                else if (cu.m_citizen4 != 0u)
                {
                    valid_citizen = cu.m_citizen4;
                }

                if (valid_citizen != 0u)
                {
                    int        family      = Singleton <CitizenManager> .instance.m_citizens.m_buffer[valid_citizen].m_family;
                    Randomizer randomizer2 = new Randomizer(family);
                    string     name        = "NAME_FEMALE_LAST";
                    //					if (Citizen.GetGender(citizenID) == Citizen.Gender.Male)
                    //					{
                    //						text = "NAME_MALE_FIRST";
                    //						text2 = "NAME_MALE_LAST";
                    //					}
                    name = Locale.Get(name, randomizer2.Int32(Locale.Count(name)));
                    name = name.Substring(4);                                                                                                                            //remove placeholder in front

                    if (m_resilients[resilient_index].namesBuffer.Count == 0 || m_resilients[resilient_index].namesBuffer.LastIndexOf(name) < index_families_before_now) //-1 if family was never present, otherwise check if it is not currently in
                    {
                        m_resilients[resilient_index].namesBuffer.Add(name);
                    }
                }
            }
        }
        //workers building history update
        public void UpdateWorkers(int resilient_index)
        {
            if (!Settings.inst.listResidentsAndWorkers)
            {
                return;
            }

            List <uint> current_workers_ids = new List <uint>();

            Building       build    = Singleton <BuildingManager> .instance.m_buildings.m_buffer[m_resilients[resilient_index].buildingID];
            CitizenManager instance = Singleton <CitizenManager> .instance;
            uint           num      = build.m_citizenUnits;
            int            num2     = 0;

            while (num != 0u)
            {
                if ((ushort)(instance.m_units.m_buffer[(int)((UIntPtr)num)].m_flags & CitizenUnit.Flags.Work) != 0)
                {
                    CitizenUnit work_unit = instance.m_units.m_buffer[(int)((UIntPtr)num)];
                    if (work_unit.m_citizen0 != 0u)
                    {
                        current_workers_ids.Add(work_unit.m_citizen0);
                    }
                    if (work_unit.m_citizen1 != 0u)
                    {
                        current_workers_ids.Add(work_unit.m_citizen1);
                    }
                    if (work_unit.m_citizen2 != 0u)
                    {
                        current_workers_ids.Add(work_unit.m_citizen2);
                    }
                    if (work_unit.m_citizen3 != 0u)
                    {
                        current_workers_ids.Add(work_unit.m_citizen3);
                    }
                    if (work_unit.m_citizen4 != 0u)
                    {
                        current_workers_ids.Add(work_unit.m_citizen4);
                    }
                    current_workers_ids.Add(num);
                }

                num = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_nextUnit;

                if (++num2 > 524288)
                {
                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                    break;
                }
            }

            //update history family list with any new names
            for (int i = 0; i < current_workers_ids.Count; i++)
            {
//				if(!m_resilients[resilient_index].idsBuffer.Contains(current_workers_ids[i]))
//				{
//					m_resilients[resilient_index].idsBuffer.Add(current_workers_ids[i]);
//				}
                string name = Singleton <CitizenManager> .instance.GetCitizenName(current_workers_ids[i]);

                if (name == null || name.Length == 0)
                {
                    //CODebugBase<LogChannel>.Error(LogChannel.Modding, "empty citizen name for " + current_workers_ids[i]);
                }
                else
                if (!m_resilients[resilient_index].namesBuffer.Contains(name))
                {
                    m_resilients[resilient_index].namesBuffer.Add(name);
                }
            }
        }
Example #10
0
        /// <summary>
        /// Lightweight simulation step method.
        /// This method is occasionally being called for different cars.
        /// </summary>
        /// <param name="vehicleId"></param>
        /// <param name="vehicleData"></param>
        /// <param name="physicsLodRefPos"></param>
        public void CustomSimulationStep(ushort vehicleId, ref Vehicle vehicleData, Vector3 physicsLodRefPos)
        {
            PathManager pathMan = Singleton <PathManager> .instance;

#if DEBUG
            /*if (!Options.disableSomething1) {
             *      Log._Debug($"CustomCarAI.CustomSimulationStep({vehicleId}) called. flags: {vehicleData.m_flags} pfFlags: {pathMan.m_pathUnits.m_buffer[vehicleData.m_path].m_pathFindFlags}");
             * }*/
#endif

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

#if USEPATHWAITCOUNTER
                if ((pathFindFlags & (PathUnit.FLAG_READY | PathUnit.FLAG_FAILED)) != 0)
                {
                    VehicleState state = VehicleStateManager.Instance()._GetVehicleState(vehicleId);
                    state.PathWaitCounter = 0;                     // NON-STOCK CODE
                }
#endif

                if ((pathFindFlags & PathUnit.FLAG_READY) != 0)
                {
                    vehicleData.m_pathPositionIndex = 255;
                    vehicleData.m_flags            &= ~Vehicle.Flags.WaitingPath;
                    vehicleData.m_flags            &= ~Vehicle.Flags.Arriving;
                    this.PathfindSuccess(vehicleId, ref vehicleData);
                    this.TrySpawn(vehicleId, ref vehicleData);
                }
                else if ((pathFindFlags & PathUnit.FLAG_FAILED) != 0 || vehicleData.m_path == 0)                     // path == 0: non-stock code!
                {
                    vehicleData.m_flags &= ~Vehicle.Flags.WaitingPath;
                    Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);

                    vehicleData.m_path = 0u;
                    this.PathfindFailure(vehicleId, ref vehicleData);
                    return;
                }
#if USEPATHWAITCOUNTER
                else
                {
                    VehicleState state = VehicleStateManager.Instance()._GetVehicleState(vehicleId);
                    state.PathWaitCounter = (ushort)Math.Min(ushort.MaxValue, (int)state.PathWaitCounter + 1);                   // NON-STOCK CODE
                }
#endif
            }
            else
            {
                if ((vehicleData.m_flags & Vehicle.Flags.WaitingSpace) != 0)
                {
                    this.TrySpawn(vehicleId, ref vehicleData);
                }
            }

            /// NON-STOCK CODE START ///
            VehicleStateManager vehStateManager = VehicleStateManager.Instance();
            if (Options.prioritySignsEnabled || Options.timedLightsEnabled)
            {
                try {
                    vehStateManager.UpdateVehiclePos(vehicleId, ref vehicleData);
                } catch (Exception e) {
                    Log.Error("CarAI CustomSimulationStep Error: " + e.ToString());
                }
            }

            if (!Options.isStockLaneChangerUsed())
            {
                try {
                    vehStateManager.LogTraffic(vehicleId, ref vehicleData, true);
                } catch (Exception e) {
                    Log.Error("CarAI CustomSimulationStep Error: " + e.ToString());
                }
            }
            /// NON-STOCK CODE END ///

            Vector3 lastFramePosition = vehicleData.GetLastFramePosition();
            int     lodPhysics;
            if (Vector3.SqrMagnitude(physicsLodRefPos - lastFramePosition) >= 1210000f)
            {
                lodPhysics = 2;
            }
            else if (Vector3.SqrMagnitude(Singleton <SimulationManager> .instance.m_simulationView.m_position - lastFramePosition) >= 250000f)
            {
                lodPhysics = 1;
            }
            else
            {
                lodPhysics = 0;
            }
            this.SimulationStep(vehicleId, ref vehicleData, vehicleId, ref vehicleData, lodPhysics);
            if (vehicleData.m_leadingVehicle == 0 && vehicleData.m_trailingVehicle != 0)
            {
                VehicleManager instance2 = Singleton <VehicleManager> .instance;
                ushort         num       = vehicleData.m_trailingVehicle;
                int            num2      = 0;
                while (num != 0)
                {
                    ushort      trailingVehicle = instance2.m_vehicles.m_buffer[(int)num].m_trailingVehicle;
                    VehicleInfo info            = instance2.m_vehicles.m_buffer[(int)num].Info;
                    info.m_vehicleAI.SimulationStep(num, ref instance2.m_vehicles.m_buffer[(int)num], vehicleId, ref vehicleData, lodPhysics);
                    num = trailingVehicle;
                    if (++num2 > 16384)
                    {
                        CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                        break;
                    }
                }
            }
#if PATHRECALC
            ushort recalcSegmentId = 0;
#endif
            int privateServiceIndex = ItemClass.GetPrivateServiceIndex(this.m_info.m_class.m_service);
            int maxBlockCounter     = (privateServiceIndex == -1) ? 150 : 100;
            if ((vehicleData.m_flags & (Vehicle.Flags.Spawned | Vehicle.Flags.WaitingPath | Vehicle.Flags.WaitingSpace)) == 0 && vehicleData.m_cargoParent == 0)
            {
                Singleton <VehicleManager> .instance.ReleaseVehicle(vehicleId);
            }
            else if ((int)vehicleData.m_blockCounter >= maxBlockCounter && Options.enableDespawning)
            {
                Singleton <VehicleManager> .instance.ReleaseVehicle(vehicleId);
            }
#if PATHRECALC
            else if (vehicleData.m_leadingVehicle == 0 && CustomVehicleAI.ShouldRecalculatePath(vehicleId, ref vehicleData, maxBlockCounter, out recalcSegmentId))
            {
                CustomVehicleAI.MarkPathRecalculation(vehicleId, recalcSegmentId);
                InvalidPath(vehicleId, ref vehicleData, vehicleId, ref vehicleData);
            }
#endif
        }
Example #11
0
        protected override void StartActions()
        {
            if (m_ghostMode)
            {
                for (ushort a = 1; a < BuildingManager.instance.m_buildings.m_buffer.Length; a++)
                {
                    if (BuildingManager.instance.m_buildings.m_buffer[a].Info.m_buildingAI is PrivateBuildingAI)
                    {
                        Vector3            position     = BuildingManager.instance.m_buildings.m_buffer[a].m_position;
                        int                num          = Mathf.Max((int)((position.x - 35f) / 64f + 135f), 0);
                        int                num2         = Mathf.Max((int)((position.z - 35f) / 64f + 135f), 0);
                        int                num3         = Mathf.Min((int)((position.x + 35f) / 64f + 135f), 269);
                        int                num4         = Mathf.Min((int)((position.z + 35f) / 64f + 135f), 269);
                        Array16 <Building> buildings    = Singleton <BuildingManager> .instance.m_buildings;
                        ushort[]           buildingGrid = Singleton <BuildingManager> .instance.m_buildingGrid;
                        for (int i = num2; i <= num4; i++)
                        {
                            for (int j = num; j <= num3; j++)
                            {
                                ushort num5 = buildingGrid[i * 270 + j];
                                int    num6 = 0;
                                while (num5 != 0)
                                {
                                    ushort         nextGridBuilding = buildings.m_buffer[num5].m_nextGridBuilding;
                                    Building.Flags flags            = buildings.m_buffer[num5].m_flags;
                                    if ((flags & (Building.Flags.Created | Building.Flags.Deleted | Building.Flags.Demolishing | Building.Flags.Collapsed)) == Building.Flags.Created)
                                    {
                                        BuildingInfo info = buildings.m_buffer[num5].Info;
                                        if (info != null && info.m_placementStyle == ItemClass.Placement.Automatic)
                                        {
                                            ItemClass.Zone zone          = info.m_class.GetZone();
                                            ItemClass.Zone secondaryZone = info.m_class.GetSecondaryZone();
                                            if (zone != ItemClass.Zone.None && VectorUtils.LengthSqrXZ(buildings.m_buffer[num5].m_position - position) <= 1225f)
                                            {
                                                buildings.m_buffer[num5].CheckZoning(zone, secondaryZone, true);
                                            }
                                        }
                                    }
                                    num5 = nextGridBuilding;
                                    if (++num6 >= 49152)
                                    {
                                        CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                                        break;
                                    }
                                }
                            }
                        }
                    }
                }

                for (ushort i = 1; i < ZoneManager.instance.m_blocks.m_buffer.Length; i++)
                {
                    bool changed = false;
                    for (int x = 0; x < 4; x++)
                    {
                        for (int z = 0; z < 8; z++)
                        {
                            changed = ZoneMixerOverrides.GetBlockZoneSanitize(ref ZoneManager.instance.m_blocks.m_buffer[i], x, z) | changed;
                        }
                    }
                    if (changed)
                    {
                        ZoneManager.instance.m_blocks.m_buffer[i].RefreshZoning(i);
                    }
                }

                K45DialogControl.ShowModal(new K45DialogControl.BindProperties()
                {
                    icon        = ZoneMixerMod.Instance.IconName,
                    title       = Locale.Get("K45_ZM_GHOST_MODE_MODAL_TITLE"),
                    message     = Locale.Get("K45_ZM_GHOST_MODE_MODAL_MESSAGE"),
                    showButton1 = true,
                    textButton1 = Locale.Get("K45_ZM_OK_BUTTON")
                }, (x) => true);
            }
        }
        /// <summary>
        /// Lightweight simulation step method.
        /// This method is occasionally being called for different cars.
        /// </summary>
        /// <param name="vehicleId"></param>
        /// <param name="vehicleData"></param>
        /// <param name="physicsLodRefPos"></param>
        public void CustomSimulationStep(ushort vehicleId, ref Vehicle vehicleData, Vector3 physicsLodRefPos)
        {
#if DEBUG
            bool vehDebug  = GlobalConfig.Instance.Debug.CitizenId == 0 || GlobalConfig.Instance.Debug.VehicleId == vehicleId;
            bool debug     = GlobalConfig.Instance.Debug.Switches[2] && vehDebug;
            bool fineDebug = GlobalConfig.Instance.Debug.Switches[4] && vehDebug;
#endif

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

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

#if DEBUG
                if (debug)
                {
                    Log._Debug($"CustomCarAI.CustomSimulationStep({vehicleId}): Path: {vehicleData.m_path}, mainPathState={mainPathState}");
                }
#endif
                ExtSoftPathState finalPathState = ExtSoftPathState.None;
#if BENCHMARK
                using (var bm = new Benchmark(null, "UpdateCarPathState")) {
#endif
                finalPathState = ExtCitizenInstance.ConvertPathStateToSoftPathState(mainPathState);
                if (Options.prohibitPocketCars && VehicleStateManager.Instance.VehicleStates[vehicleId].vehicleType == ExtVehicleType.PassengerCar)
                {
                    ushort driverInstanceId = CustomPassengerCarAI.GetDriverInstanceId(vehicleId, ref vehicleData);
                    finalPathState = AdvancedParkingManager.Instance.UpdateCarPathState(vehicleId, ref vehicleData, ref Singleton <CitizenManager> .instance.m_instances.m_buffer[driverInstanceId], ref ExtCitizenInstanceManager.Instance.ExtInstances[driverInstanceId], mainPathState);

#if DEBUG
                    if (debug)
                    {
                        Log._Debug($"CustomCarAI.CustomSimulationStep({vehicleId}): Applied Parking AI logic. Path: {vehicleData.m_path}, mainPathState={mainPathState}, finalPathState={finalPathState}");
                    }
#endif
                }
#if BENCHMARK
            }
#endif

                switch (finalPathState)
                {
                case ExtSoftPathState.Ready:
#if DEBUG
                    if (debug)
                    {
                        Log._Debug($"CustomCarAI.CustomSimulationStep({vehicleId}): Path-finding succeeded for vehicle {vehicleId} (finalPathState={finalPathState}). Path: {vehicleData.m_path} -- calling CarAI.PathfindSuccess");
                    }
#endif

                    vehicleData.m_pathPositionIndex = 255;
                    vehicleData.m_flags            &= ~Vehicle.Flags.WaitingPath;
                    vehicleData.m_flags            &= ~Vehicle.Flags.Arriving;
                    this.PathfindSuccess(vehicleId, ref vehicleData);
                    this.TrySpawn(vehicleId, ref vehicleData);
                    break;

                case ExtSoftPathState.Ignore:
#if DEBUG
                    if (debug)
                    {
                        Log._Debug($"CustomCarAI.CustomSimulationStep({vehicleId}): Path-finding result shall be ignored for vehicle {vehicleId} (finalPathState={finalPathState}). Path: {vehicleData.m_path} -- ignoring");
                    }
#endif
                    return;

                case ExtSoftPathState.Calculating:
                default:
#if DEBUG
                    if (debug)
                    {
                        Log._Debug($"CustomCarAI.CustomSimulationStep({vehicleId}): Path-finding result undetermined for vehicle {vehicleId} (finalPathState={finalPathState}). Path: {vehicleData.m_path} -- continue");
                    }
#endif
                    break;

                case ExtSoftPathState.FailedHard:
#if DEBUG
                    if (debug)
                    {
                        Log._Debug($"CustomCarAI.CustomSimulationStep({vehicleId}): HARD path-finding failure for vehicle {vehicleId} (finalPathState={finalPathState}). Path: {vehicleData.m_path} -- calling CarAI.PathfindFailure");
                    }
#endif
                    vehicleData.m_flags &= ~Vehicle.Flags.WaitingPath;
                    Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);

                    vehicleData.m_path = 0u;
                    this.PathfindFailure(vehicleId, ref vehicleData);
                    return;

                case ExtSoftPathState.FailedSoft:
#if DEBUG
                    if (debug)
                    {
                        Log._Debug($"CustomCarAI.CustomSimulationStep({vehicleId}): SOFT path-finding failure for vehicle {vehicleId} (finalPathState={finalPathState}). Path: {vehicleData.m_path} -- calling CarAI.InvalidPath");
                    }
#endif
                    // path mode has been updated, repeat path-finding
                    vehicleData.m_flags &= ~Vehicle.Flags.WaitingPath;
                    this.InvalidPath(vehicleId, ref vehicleData, vehicleId, ref vehicleData);
                    break;
                }
                // NON-STOCK CODE END
            }
            else
            {
                if ((vehicleData.m_flags & Vehicle.Flags.WaitingSpace) != 0)
                {
                    this.TrySpawn(vehicleId, ref vehicleData);
                }
            }

            // NON-STOCK CODE START
#if BENCHMARK
            using (var bm = new Benchmark(null, "UpdateVehiclePosition")) {
#endif
            VehicleStateManager.Instance.UpdateVehiclePosition(vehicleId, ref vehicleData);
#if BENCHMARK
        }
#endif
            if (!Options.isStockLaneChangerUsed() && (vehicleData.m_flags & Vehicle.Flags.Spawned) != 0)
            {
#if BENCHMARK
                using (var bm = new Benchmark(null, "LogTraffic")) {
#endif
                // Advanced AI traffic measurement
                VehicleStateManager.Instance.LogTraffic(vehicleId);
#if BENCHMARK
            }
#endif
            }
            // NON-STOCK CODE END

            Vector3 lastFramePosition = vehicleData.GetLastFramePosition();
            int lodPhysics;
            if (Vector3.SqrMagnitude(physicsLodRefPos - lastFramePosition) >= 1210000f)
            {
                lodPhysics = 2;
            }
            else if (Vector3.SqrMagnitude(Singleton <SimulationManager> .instance.m_simulationView.m_position - lastFramePosition) >= 250000f)
            {
                lodPhysics = 1;
            }
            else
            {
                lodPhysics = 0;
            }
            this.SimulationStep(vehicleId, ref vehicleData, vehicleId, ref vehicleData, lodPhysics);
            if (vehicleData.m_leadingVehicle == 0 && vehicleData.m_trailingVehicle != 0)
            {
                VehicleManager vehManager = Singleton <VehicleManager> .instance;
                ushort         trailerId  = vehicleData.m_trailingVehicle;
                int            numIters   = 0;
                while (trailerId != 0)
                {
                    ushort      trailingVehicle = vehManager.m_vehicles.m_buffer[(int)trailerId].m_trailingVehicle;
                    VehicleInfo info            = vehManager.m_vehicles.m_buffer[(int)trailerId].Info;
                    info.m_vehicleAI.SimulationStep(trailerId, ref vehManager.m_vehicles.m_buffer[(int)trailerId], vehicleId, ref vehicleData, lodPhysics);
                    trailerId = trailingVehicle;
                    if (++numIters > 16384)
                    {
                        CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                        break;
                    }
                }
            }

            int privateServiceIndex = ItemClass.GetPrivateServiceIndex(this.m_info.m_class.m_service);
            int maxBlockCounter     = (privateServiceIndex == -1) ? 150 : 100;
            if ((vehicleData.m_flags & (Vehicle.Flags.Spawned | Vehicle.Flags.WaitingPath | Vehicle.Flags.WaitingSpace)) == 0 && vehicleData.m_cargoParent == 0)
            {
                Singleton <VehicleManager> .instance.ReleaseVehicle(vehicleId);
            }
            else if ((int)vehicleData.m_blockCounter >= maxBlockCounter)
            {
                // NON-STOCK CODE START
                bool mayDespawn = true;
#if BENCHMARK
                using (var bm = new Benchmark(null, "MayDespawn")) {
#endif
                mayDespawn = VehicleBehaviorManager.Instance.MayDespawn(ref vehicleData);
#if BENCHMARK
            }
#endif

                if (mayDespawn)
                {
                    // NON-STOCK CODE END
                    Singleton <VehicleManager> .instance.ReleaseVehicle(vehicleId);
                }                 // NON-STOCK CODE
            }
        }
        private bool GetStopPosition(TransportInfo info, ushort segment, ushort building, ushort firstStop, ref Vector3 hitPos, out bool fixedPlatform)
        {
            //begin mod(+): detect key
            bool alternateMode = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
            //end mod

            NetManager       instance1 = Singleton <NetManager> .instance;
            BuildingManager  instance2 = Singleton <BuildingManager> .instance;
            TransportManager instance3 = Singleton <TransportManager> .instance;

            fixedPlatform = false;
            if (info.m_transportType == TransportInfo.TransportType.Pedestrian)
            {
                Vector3 position   = Vector3.zero;
                float   laneOffset = 0.0f;
                uint    laneID     = 0;
                int     laneIndex;
                if ((int)segment != 0 && !instance1.m_segments.m_buffer[(int)segment].GetClosestLanePosition(hitPos, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, VehicleInfo.VehicleType.None, out position, out laneID, out laneIndex, out laneOffset))
                {
                    laneID = 0U;
                    if ((instance1.m_segments.m_buffer[(int)segment].m_flags & NetSegment.Flags.Untouchable) != NetSegment.Flags.None && (int)building == 0)
                    {
                        building = NetSegment.FindOwnerBuilding(segment, 363f);
                    }
                }
                if ((int)building != 0)
                {
                    if (instance2.m_buildings.m_buffer[(int)building].Info.m_hasPedestrianPaths)
                    {
                        laneID = instance2.m_buildings.m_buffer[(int)building].FindLane(NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, hitPos, out position, out laneOffset);
                    }
                    if ((int)laneID == 0)
                    {
                        Vector3 sidewalkPosition = instance2.m_buildings.m_buffer[(int)building].CalculateSidewalkPosition();
                        laneID = instance2.m_buildings.m_buffer[(int)building].FindAccessLane(NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, sidewalkPosition, out position, out laneOffset);
                    }
                }
                if ((int)laneID == 0)
                {
                    return(false);
                }
                if ((double)laneOffset < 0.00392156885936856)
                {
                    laneOffset = 0.003921569f;
                    position   = instance1.m_lanes.m_buffer[laneID].CalculatePosition(laneOffset);
                }
                else if ((double)laneOffset > 0.996078431606293)
                {
                    laneOffset = 0.9960784f;
                    position   = instance1.m_lanes.m_buffer[laneID].CalculatePosition(laneOffset);
                }
                if ((int)this.m_line != 0)
                {
                    firstStop = instance3.m_lines.m_buffer[(int)this.m_line].m_stops;
                    ushort stop = firstStop;
                    int    num  = 0;
                    while ((int)stop != 0)
                    {
                        if ((int)instance1.m_nodes.m_buffer[(int)stop].m_lane == (int)laneID)
                        {
                            hitPos        = instance1.m_nodes.m_buffer[(int)stop].m_position;
                            fixedPlatform = true;
                            return(true);
                        }
                        stop = TransportLine.GetNextStop(stop);
                        if ((int)stop != (int)firstStop)
                        {
                            if (++num >= 32768)
                            {
                                CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace);

                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                hitPos        = position;
                fixedPlatform = true;
                return(true);
            }
            if ((int)segment != 0)
            {
                if ((instance1.m_segments.m_buffer[(int)segment].m_flags & NetSegment.Flags.Untouchable) != NetSegment.Flags.None)
                {
                    building = NetSegment.FindOwnerBuilding(segment, 363f);
                    if ((int)building != 0)
                    {
                        BuildingInfo  info1 = instance2.m_buildings.m_buffer[(int)building].Info;
                        TransportInfo transportLineInfo1 = info1.m_buildingAI.GetTransportLineInfo();
                        TransportInfo transportLineInfo2 = info1.m_buildingAI.GetSecondaryTransportLineInfo();
                        //begin mod(*): check for !alternateMode
                        if (!alternateMode && transportLineInfo1 != null && transportLineInfo1.m_transportType == info.m_transportType || !alternateMode && transportLineInfo2 != null && transportLineInfo2.m_transportType == info.m_transportType)
                        {
                            //end mod
                            segment = (ushort)0;
                        }
                        else
                        {
                            building = (ushort)0;
                        }
                    }
                }
                Vector3 position1;
                uint    laneID1;
                int     laneIndex1;
                float   laneOffset1;
                if ((int)segment != 0 && instance1.m_segments.m_buffer[(int)segment].GetClosestLanePosition(hitPos, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, info.m_vehicleType, out position1, out laneID1, out laneIndex1, out laneOffset1))
                {
                    if (info.m_vehicleType == VehicleInfo.VehicleType.None)
                    {
                        NetLane.Flags flags1 = (NetLane.Flags)((int)instance1.m_lanes.m_buffer[laneID1].m_flags & 768);
                        NetLane.Flags flags2 = info.m_stopFlag;
                        NetInfo       info1  = instance1.m_segments.m_buffer[(int)segment].Info;
                        if (info1.m_vehicleTypes != VehicleInfo.VehicleType.None)
                        {
                            flags2 = NetLane.Flags.None;
                        }
                        if (flags1 != NetLane.Flags.None && flags2 != NetLane.Flags.None && flags1 != flags2)
                        {
                            return(false);
                        }
                        float stopOffset = info1.m_lanes[laneIndex1].m_stopOffset;
                        if ((instance1.m_segments.m_buffer[(int)segment].m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None)
                        {
                            stopOffset = -stopOffset;
                        }
                        Vector3 direction;
                        instance1.m_lanes.m_buffer[laneID1].CalculateStopPositionAndDirection(0.5019608f, stopOffset, out hitPos, out direction);
                        fixedPlatform = true;
                        return(true);
                    }
                    Vector3 position2;
                    uint    laneID2;
                    int     laneIndex2;
                    float   laneOffset2;
                    if (instance1.m_segments.m_buffer[(int)segment].GetClosestLanePosition(position1, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, out position2, out laneID2, out laneIndex2, out laneOffset2))
                    {
                        NetLane.Flags flags = (NetLane.Flags)((int)instance1.m_lanes.m_buffer[laneID1].m_flags & 768);
                        if (flags != NetLane.Flags.None && info.m_stopFlag != NetLane.Flags.None && flags != info.m_stopFlag)
                        {
                            return(false);
                        }
                        float stopOffset = instance1.m_segments.m_buffer[(int)segment].Info.m_lanes[laneIndex2].m_stopOffset;
                        if ((instance1.m_segments.m_buffer[(int)segment].m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None)
                        {
                            stopOffset = -stopOffset;
                        }
                        Vector3 direction;
                        instance1.m_lanes.m_buffer[laneID2].CalculateStopPositionAndDirection(0.5019608f, stopOffset, out hitPos, out direction);
                        fixedPlatform = true;
                        return(true);
                    }
                }
            }
            //begin mod(*): check for !alternateMode
            if (!alternateMode && (int)building != 0)
            {
                //end mod
                ushort num1 = 0;
                if ((instance2.m_buildings.m_buffer[(int)building].m_flags & Building.Flags.Untouchable) != Building.Flags.None)
                {
                    num1 = Building.FindParentBuilding(building);
                }
                if (this.m_building != 0 && (int)firstStop != 0 && (this.m_building == (int)building || this.m_building == (int)num1))
                {
                    hitPos = instance1.m_nodes.m_buffer[(int)firstStop].m_position;
                    return(true);
                }
                VehicleInfo randomVehicleInfo = Singleton <VehicleManager> .instance.GetRandomVehicleInfo(ref Singleton <SimulationManager> .instance.m_randomizer, info.m_class.m_service, info.m_class.m_subService, info.m_class.m_level);

                if (randomVehicleInfo != null)
                {
                    BuildingInfo  info1 = instance2.m_buildings.m_buffer[(int)building].Info;
                    TransportInfo transportLineInfo1 = info1.m_buildingAI.GetTransportLineInfo();
                    if (transportLineInfo1 == null && (int)num1 != 0)
                    {
                        building           = num1;
                        info1              = instance2.m_buildings.m_buffer[(int)building].Info;
                        transportLineInfo1 = info1.m_buildingAI.GetTransportLineInfo();
                    }
                    TransportInfo transportLineInfo2 = info1.m_buildingAI.GetSecondaryTransportLineInfo();
                    if (transportLineInfo1 != null && transportLineInfo1.m_transportType == info.m_transportType || transportLineInfo2 != null && transportLineInfo2.m_transportType == info.m_transportType)
                    {
                        Vector3 vector3 = Vector3.zero;
                        int     num2    = 1000000;
                        for (int index = 0; index < 12; ++index)
                        {
                            Randomizer randomizer = new Randomizer((ulong)index);
                            Vector3    position;
                            Vector3    target;
                            info1.m_buildingAI.CalculateSpawnPosition(building, ref instance2.m_buildings.m_buffer[(int)building], ref randomizer, randomVehicleInfo, out position, out target);
                            int num3 = 0;
                            if (info.m_avoidSameStopPlatform)
                            {
                                num3 = this.GetLineCount(position, target - position, info.m_transportType);
                            }
                            if (num3 < num2)
                            {
                                vector3 = position;
                                num2    = num3;
                            }
                            else if (num3 == num2 && (double)Vector3.SqrMagnitude(position - hitPos) < (double)Vector3.SqrMagnitude(vector3 - hitPos))
                            {
                                vector3 = position;
                            }
                        }
                        if ((int)firstStop != 0)
                        {
                            Vector3 position = instance1.m_nodes.m_buffer[(int)firstStop].m_position;
                            if ((double)Vector3.SqrMagnitude(position - vector3) < 16384.0)
                            {
                                uint lane = instance1.m_nodes.m_buffer[(int)firstStop].m_lane;
                                if ((int)lane != 0)
                                {
                                    ushort segment1 = instance1.m_lanes.m_buffer[lane].m_segment;
                                    if ((int)segment1 != 0 && (instance1.m_segments.m_buffer[(int)segment1].m_flags & NetSegment.Flags.Untouchable) != NetSegment.Flags.None)
                                    {
                                        ushort ownerBuilding = NetSegment.FindOwnerBuilding(segment1, 363f);
                                        if ((int)building == (int)ownerBuilding)
                                        {
                                            hitPos = position;
                                            return(true);
                                        }
                                    }
                                }
                            }
                        }
                        hitPos = vector3;
                        return(num2 != 1000000);
                    }
                }
            }
            return(false);
        }
        private static void ApplyBrush(TreeTool tt)
        {
            //uint useless1 = 0;
            unsafe
            {
                float          single;
                float          single1;
                uint           num;
                int            num1;
                Vector3        vector3        = new Vector3();
                Randomizer     value          = (Randomizer)tt.GetType().GetField("m_randomizer", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(tt);
                ToolController toolController = (ToolController)tt.GetType().GetField("m_toolController", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(tt);
                Vector3        value1         = (Vector3)tt.GetType().GetField("m_mousePosition", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(tt);
                bool           flag           = (bool)tt.GetType().GetField("m_mouseLeftDown", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(tt);
                bool           flag1          = (bool)tt.GetType().GetField("m_mouseRightDown", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(tt);
                TreeInfo       treeInfo       = (TreeInfo)tt.GetType().GetField("m_treeInfo", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(tt);
                float[]        brushData      = toolController.BrushData;
                float          mBrushSize     = tt.m_brushSize * 0.5f;
                float          single2        = 32f;
                int            num2           = 540;
                TreeInstance[] mBuffer        = Singleton <TreeManager> .instance.m_trees.m_buffer;
                uint[]         mTreeGrid      = Singleton <TreeManager> .instance.m_treeGrid;
                float          mStrength      = tt.m_strength;
                int            num3           = Mathf.Max((int)((value1.x - mBrushSize) / single2 + (float)num2 * 0.5f), 0);
                int            num4           = Mathf.Max((int)((value1.z - mBrushSize) / single2 + (float)num2 * 0.5f), 0);
                int            num5           = Mathf.Min((int)((value1.x + mBrushSize) / single2 + (float)num2 * 0.5f), num2 - 1);
                int            num6           = Mathf.Min((int)((value1.z + mBrushSize) / single2 + (float)num2 * 0.5f), num2 - 1);
                for (int i = num4; i <= num6; i++)
                {
                    float mBrushSize1 = (float)(((float)i - (float)num2 * 0.5f + 0.5f) * single2 - value1.z + mBrushSize) / tt.m_brushSize * 64f - 0.5f;
                    int   num7        = Mathf.Clamp(Mathf.FloorToInt(mBrushSize1), 0, 63);
                    int   num8        = Mathf.Clamp(Mathf.CeilToInt(mBrushSize1), 0, 63);
                    for (int j = num3; j <= num5; j++)
                    {
                        float mBrushSize2 = (float)(((float)j - (float)num2 * 0.5f + 0.5f) * single2 - value1.x + mBrushSize) / tt.m_brushSize * 64f - 0.5f;
                        int   num9        = Mathf.Clamp(Mathf.FloorToInt(mBrushSize2), 0, 63);
                        int   num10       = Mathf.Clamp(Mathf.CeilToInt(mBrushSize2), 0, 63);
                        float single3     = brushData[num7 * 64 + num9];
                        float single4     = brushData[num7 * 64 + num10];
                        float single5     = brushData[num8 * 64 + num9];
                        float single6     = brushData[num8 * 64 + num10];
                        float single7     = single3 + (float)((single4 - single3) * (mBrushSize2 - (float)num9));
                        float single8     = single5 + (float)((single6 - single5) * (mBrushSize2 - (float)num9));
                        float single9     = single7 + (float)((single8 - single7) * (mBrushSize1 - (float)num7));
                        int   num11       = (int)(mStrength * (single9 * 1.2f - 0.2f) * 10000f);
                        if (flag && tt.m_prefab != null)
                        {
                            if (value.Int32(10000) < num11)
                            {
                                TreeInfo treeInfo1 = ((Singleton <ToolManager> .instance.m_properties.m_mode & ItemClass.Availability.AssetEditor) == ItemClass.Availability.None ? tt.m_prefab.GetVariation(ref value) : tt.m_prefab);
                                vector3.x = ((float)j - (float)num2 * 0.5f) * single2;
                                vector3.z = ((float)i - (float)num2 * 0.5f) * single2;
                                vector3.x = vector3.x + (float)(((float)value.Int32(10000) + 0.5f) * (single2 / 10000f));
                                vector3.z = vector3.z + (float)(((float)value.Int32(10000) + 0.5f) * (single2 / 10000f));
                                vector3.y = 0f;
                                vector3.y = Singleton <TerrainManager> .instance.SampleDetailHeight(vector3, out single, out single1);

                                if (Mathf.Max(Mathf.Abs(single), Mathf.Abs(single1)) < (float)value.Int32(10000) * 5E-05f)
                                {
                                    float      mSize      = treeInfo.m_generatedInfo.m_size.y;
                                    float      mMinScale  = treeInfo.m_minScale;
                                    Randomizer randomizer = new Randomizer(Singleton <TreeManager> .instance.m_trees.NextFreeItem(ref value));
                                    mMinScale = mMinScale + (float)randomizer.Int32(10000) * ((treeInfo.m_maxScale - treeInfo.m_minScale) * 0.0001f);
                                    mSize     = mSize * mMinScale;
                                    float   single11 = 4.5f;
                                    Vector2 vector2  = VectorUtils.XZ(vector3);
                                    Quad2   quad22   = new Quad2()
                                    {
                                        a = vector2 + new Vector2(-single11, -single11),
                                        b = vector2 + new Vector2(-single11, single11),
                                        c = vector2 + new Vector2(single11, single11),
                                        d = vector2 + new Vector2(single11, -single11)
                                    };
                                    Quad2 quad2  = quad22;
                                    Quad2 quad23 = new Quad2()
                                    {
                                        a = vector2 + new Vector2(-8f, -8f),
                                        b = vector2 + new Vector2(-8f, 8f),
                                        c = vector2 + new Vector2(8f, 8f),
                                        d = vector2 + new Vector2(8f, -8f)
                                    };
                                    Quad2 quad21   = quad23;
                                    float single12 = value1.y - 1000f;
                                    float single13 = value1.y + mSize;
                                    ItemClass.CollisionType collisionType = ItemClass.CollisionType.Terrain;
                                    if (!Singleton <PropManager> .instance.OverlapQuad(quad2, single12, single13, collisionType, 0, 0) && !Singleton <TreeManager> .instance.OverlapQuad(quad21, single12, single13, collisionType, 0, 0) && !Singleton <NetManager> .instance.OverlapQuad(quad2, single12, single13, collisionType, treeInfo1.m_class.m_layer, 0, 0, 0) && !Singleton <BuildingManager> .instance.OverlapQuad(quad2, single12, single13, collisionType, treeInfo1.m_class.m_layer, 0, 0, 0) && !Singleton <TerrainManager> .instance.HasWater(vector2) && !Singleton <GameAreaManager> .instance.QuadOutOfArea(quad2) && !Singleton <TreeManager> .instance.CreateTree(out num, ref value, treeInfo1, vector3, false))
                                    {
                                    }
                                }
                            }
                        }
                        else if (flag1 || tt.m_prefab == null)
                        {
                            uint num12 = mTreeGrid[i * num2 + j];
                            int  num13 = 0;
                            do
                            {
                                if (num12 == 0)
                                {
                                    goto Label10;
                                }
                                uint mNextGridTree = mBuffer[num12].m_nextGridTree;
                                if (value.Int32(10000) < num11)
                                {
                                    Singleton <TreeManager> .instance.ReleaseTree(num12);
                                }
                                num12 = mNextGridTree;
                                num1  = num13 + 1;
                                num13 = num1;
                            }while (num1 < LimitTreeManager.Helper.TreeLimit);
                            CODebugBase <LogChannel> .Error(LogChannel.Core, string.Concat("Invalid list detected!\n", Environment.StackTrace));
                        }

Label10:
                        ;//useless1++;
                    }
                }
            }
        }
Example #15
0
        protected override bool SpawnVehicle(ushort instanceID, ref CitizenInstance citizenData, PathUnit.Position pathPos)
        {
            VehicleManager instance = Singleton <VehicleManager> .instance;
            float          num      = 20f;
            int            num2     = Mathf.Max((int)((citizenData.m_targetPos.x - num) / 32f + 270f), 0);
            int            num3     = Mathf.Max((int)((citizenData.m_targetPos.z - num) / 32f + 270f), 0);
            int            num4     = Mathf.Min((int)((citizenData.m_targetPos.x + num) / 32f + 270f), 539);
            int            num5     = Mathf.Min((int)((citizenData.m_targetPos.z + num) / 32f + 270f), 539);

            for (int i = num3; i <= num5; i++)
            {
                for (int j = num2; j <= num4; j++)
                {
                    ushort num6 = instance.m_vehicleGrid [i * 540 + j];
                    int    num7 = 0;
                    while (num6 != 0)
                    {
                        if (this.TryJoinVehicle(instanceID, ref citizenData, num6, ref instance.m_vehicles.m_buffer [(int)num6]))
                        {
                            citizenData.m_flags      |= CitizenInstance.Flags.EnteringVehicle;
                            citizenData.m_flags      &= ~CitizenInstance.Flags.TryingSpawnVehicle;
                            citizenData.m_flags      &= ~CitizenInstance.Flags.BoredOfWaiting;
                            citizenData.m_waitCounter = 0;
                            return(true);
                        }
                        num6 = instance.m_vehicles.m_buffer [(int)num6].m_nextGridVehicle;
                        if (++num7 > 65536)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
            NetManager     instance2 = Singleton <NetManager> .instance;
            CitizenManager instance3 = Singleton <CitizenManager> .instance;
            Vector3        vector    = Vector3.zero;
            Quaternion     rotation  = Quaternion.identity;
            ushort         num8      = instance3.m_citizens.m_buffer [(int)((UIntPtr)citizenData.m_citizen)].m_parkedVehicle;

            if (num8 != 0)
            {
                vector   = instance.m_parkedVehicles.m_buffer [(int)num8].m_position;
                rotation = instance.m_parkedVehicles.m_buffer [(int)num8].m_rotation;
            }
            VehicleInfo vehicleInfo = this.GetVehicleInfo(instanceID, ref citizenData, false);

            if (vehicleInfo == null || vehicleInfo.m_vehicleType == VehicleInfo.VehicleType.Bicycle)
            {
                instance3.m_citizens.m_buffer [(int)((UIntPtr)citizenData.m_citizen)].SetParkedVehicle(citizenData.m_citizen, 0);
                if ((citizenData.m_flags & CitizenInstance.Flags.TryingSpawnVehicle) == CitizenInstance.Flags.None)
                {
                    citizenData.m_flags      |= CitizenInstance.Flags.TryingSpawnVehicle;
                    citizenData.m_flags      &= ~CitizenInstance.Flags.BoredOfWaiting;
                    citizenData.m_waitCounter = 0;
                }
                return(true);
            }
            if (vehicleInfo.m_class.m_subService == ItemClass.SubService.PublicTransportTaxi)
            {
                instance3.m_citizens.m_buffer [(int)((UIntPtr)citizenData.m_citizen)].SetParkedVehicle(citizenData.m_citizen, 0);
                if ((citizenData.m_flags & CitizenInstance.Flags.WaitingTaxi) == CitizenInstance.Flags.None)
                {
                    citizenData.m_flags      |= CitizenInstance.Flags.WaitingTaxi;
                    citizenData.m_flags      &= ~CitizenInstance.Flags.BoredOfWaiting;
                    citizenData.m_waitCounter = 0;
                }
                return(true);
            }
            uint    laneID  = PathManager.GetLaneID(pathPos);
            Vector3 vector2 = citizenData.m_targetPos;

            if (num8 != 0 && Vector3.SqrMagnitude(vector - vector2) < 1024f)
            {
                vector2 = vector;
            }
            else
            {
                num8 = 0;
            }
            Vector3 a;
            float   num9;

            instance2.m_lanes.m_buffer [(int)((UIntPtr)laneID)].GetClosestPosition(vector2, out a, out num9);
            byte lastPathOffset = (byte)Mathf.Clamp(Mathf.RoundToInt(num9 * 255f), 0, 255);

            a = vector2 + Vector3.ClampMagnitude(a - vector2, 5f);
            ushort num10;

            if (instance.CreateVehicle(out num10, ref Singleton <SimulationManager> .instance.m_randomizer, vehicleInfo, vector2, TransferManager.TransferReason.None, false, false))
            {
                Vehicle.Frame frame = instance.m_vehicles.m_buffer [(int)num10].m_frame0;
                if (num8 != 0)
                {
                    frame.m_rotation = rotation;
                }
                else
                {
                    Vector3 forward = a - citizenData.GetLastFrameData().m_position;
                    if (forward.sqrMagnitude > 0.01f)
                    {
                        frame.m_rotation = Quaternion.LookRotation(forward);
                    }
                }
                instance.m_vehicles.m_buffer [(int)num10].m_frame0 = frame;
                instance.m_vehicles.m_buffer [(int)num10].m_frame1 = frame;
                instance.m_vehicles.m_buffer [(int)num10].m_frame2 = frame;
                instance.m_vehicles.m_buffer [(int)num10].m_frame3 = frame;
                vehicleInfo.m_vehicleAI.FrameDataUpdated(num10, ref instance.m_vehicles.m_buffer [(int)num10], ref frame);
                instance.m_vehicles.m_buffer [(int)num10].m_targetPos0 = new Vector4(a.x, a.y, a.z, 2f);
                Vehicle[] expr_4E5_cp_0 = instance.m_vehicles.m_buffer;
                ushort    expr_4E5_cp_1 = num10;
                expr_4E5_cp_0 [(int)expr_4E5_cp_1].m_flags       = (expr_4E5_cp_0 [(int)expr_4E5_cp_1].m_flags | Vehicle.Flags.Stopped);
                instance.m_vehicles.m_buffer [(int)num10].m_path = citizenData.m_path;
                instance.m_vehicles.m_buffer [(int)num10].m_pathPositionIndex = citizenData.m_pathPositionIndex;
                instance.m_vehicles.m_buffer [(int)num10].m_lastPathOffset    = lastPathOffset;
                instance.m_vehicles.m_buffer [(int)num10].m_transferSize      = (ushort)(citizenData.m_citizen & 65535u);
                vehicleInfo.m_vehicleAI.TrySpawn(num10, ref instance.m_vehicles.m_buffer [(int)num10]);
                if (num8 != 0)
                {
                    InstanceID empty = InstanceID.Empty;
                    empty.ParkedVehicle = num8;
                    InstanceID empty2 = InstanceID.Empty;
                    empty2.Vehicle = num10;
                    Singleton <InstanceManager> .instance.ChangeInstance(empty, empty2);
                }
                citizenData.m_path = 0u;
                instance3.m_citizens.m_buffer [(int)((UIntPtr)citizenData.m_citizen)].SetParkedVehicle(citizenData.m_citizen, 0);
                instance3.m_citizens.m_buffer [(int)((UIntPtr)citizenData.m_citizen)].SetVehicle(citizenData.m_citizen, num10, 0u);
                citizenData.m_flags      |= CitizenInstance.Flags.EnteringVehicle;
                citizenData.m_flags      &= ~CitizenInstance.Flags.TryingSpawnVehicle;
                citizenData.m_flags      &= ~CitizenInstance.Flags.BoredOfWaiting;
                citizenData.m_waitCounter = 0;
                return(true);
            }
            instance3.m_citizens.m_buffer [(int)((UIntPtr)citizenData.m_citizen)].SetParkedVehicle(citizenData.m_citizen, 0);
            if ((citizenData.m_flags & CitizenInstance.Flags.TryingSpawnVehicle) == CitizenInstance.Flags.None)
            {
                citizenData.m_flags      |= CitizenInstance.Flags.TryingSpawnVehicle;
                citizenData.m_flags      &= ~CitizenInstance.Flags.BoredOfWaiting;
                citizenData.m_waitCounter = 0;
            }
            return(true);
        }
        /// <summary>
        /// Lightweight simulation step method.
        /// This method is occasionally being called for different cars.
        /// </summary>
        /// <param name="vehicleId"></param>
        /// <param name="vehicleData"></param>
        /// <param name="physicsLodRefPos"></param>
        public void CustomSimulationStep(ushort vehicleId, ref Vehicle vehicleData, Vector3 physicsLodRefPos)
        {
            if ((vehicleData.m_flags & Vehicle.Flags.WaitingPath) != 0)
            {
                PathManager pathManager   = Singleton <PathManager> .instance;
                byte        pathFindFlags = pathManager.m_pathUnits.m_buffer[vehicleData.m_path].m_pathFindFlags;

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

#if BENCHMARK
                using (var bm = new Benchmark(null, "UpdateCarPathState")) {
#endif
                if (Options.prohibitPocketCars && VehicleStateManager.Instance.VehicleStates[vehicleId].vehicleType == ExtVehicleType.PassengerCar)
                {
                    mainPathState = AdvancedParkingManager.Instance.UpdateCarPathState(vehicleId, ref vehicleData, ref ExtCitizenInstanceManager.Instance.ExtInstances[CustomPassengerCarAI.GetDriverInstanceId(vehicleId, ref vehicleData)], mainPathState);
                }
#if BENCHMARK
            }
#endif
                // NON-STOCK CODE END

                if (mainPathState == ExtPathState.Ready)
                {
                    vehicleData.m_pathPositionIndex = 255;
                    vehicleData.m_flags            &= ~Vehicle.Flags.WaitingPath;
                    vehicleData.m_flags            &= ~Vehicle.Flags.Arriving;
                    this.PathfindSuccess(vehicleId, ref vehicleData);
                    this.TrySpawn(vehicleId, ref vehicleData);
                }
                else if (mainPathState == ExtPathState.Failed)
                {
                    vehicleData.m_flags &= ~Vehicle.Flags.WaitingPath;
                    Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);

                    vehicleData.m_path = 0u;
                    this.PathfindFailure(vehicleId, ref vehicleData);
                    return;
                }
            }
            else
            {
                if ((vehicleData.m_flags & Vehicle.Flags.WaitingSpace) != 0)
                {
                    this.TrySpawn(vehicleId, ref vehicleData);
                }
            }

            // NON-STOCK CODE START
#if BENCHMARK
            using (var bm = new Benchmark(null, "UpdateVehiclePosition")) {
#endif
            VehicleStateManager.Instance.UpdateVehiclePosition(vehicleId, ref vehicleData);
#if BENCHMARK
        }
#endif
            if (!Options.isStockLaneChangerUsed())
            {
#if BENCHMARK
                using (var bm = new Benchmark(null, "LogTraffic")) {
#endif
                // Advanced AI traffic measurement
                VehicleStateManager.Instance.LogTraffic(vehicleId);
#if BENCHMARK
            }
#endif
            }
            // NON-STOCK CODE END

            Vector3 lastFramePosition = vehicleData.GetLastFramePosition();
            int lodPhysics;
            if (Vector3.SqrMagnitude(physicsLodRefPos - lastFramePosition) >= 1210000f)
            {
                lodPhysics = 2;
            }
            else if (Vector3.SqrMagnitude(Singleton <SimulationManager> .instance.m_simulationView.m_position - lastFramePosition) >= 250000f)
            {
                lodPhysics = 1;
            }
            else
            {
                lodPhysics = 0;
            }
            this.SimulationStep(vehicleId, ref vehicleData, vehicleId, ref vehicleData, lodPhysics);
            if (vehicleData.m_leadingVehicle == 0 && vehicleData.m_trailingVehicle != 0)
            {
                VehicleManager vehManager = Singleton <VehicleManager> .instance;
                ushort         trailerId  = vehicleData.m_trailingVehicle;
                int            numIters   = 0;
                while (trailerId != 0)
                {
                    ushort      trailingVehicle = vehManager.m_vehicles.m_buffer[(int)trailerId].m_trailingVehicle;
                    VehicleInfo info            = vehManager.m_vehicles.m_buffer[(int)trailerId].Info;
                    info.m_vehicleAI.SimulationStep(trailerId, ref vehManager.m_vehicles.m_buffer[(int)trailerId], vehicleId, ref vehicleData, lodPhysics);
                    trailerId = trailingVehicle;
                    if (++numIters > 16384)
                    {
                        CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                        break;
                    }
                }
            }

            int privateServiceIndex = ItemClass.GetPrivateServiceIndex(this.m_info.m_class.m_service);
            int maxBlockCounter     = (privateServiceIndex == -1) ? 150 : 100;
            if ((vehicleData.m_flags & (Vehicle.Flags.Spawned | Vehicle.Flags.WaitingPath | Vehicle.Flags.WaitingSpace)) == 0 && vehicleData.m_cargoParent == 0)
            {
                Singleton <VehicleManager> .instance.ReleaseVehicle(vehicleId);
            }
            else if ((int)vehicleData.m_blockCounter >= maxBlockCounter)
            {
                // NON-STOCK CODE START
                bool mayDespawn = true;
#if BENCHMARK
                using (var bm = new Benchmark(null, "MayDespawn")) {
#endif
                mayDespawn = VehicleBehaviorManager.Instance.MayDespawn(ref vehicleData);
#if BENCHMARK
            }
#endif

                if (mayDespawn)
                {
                    // NON-STOCK CODE END
                    Singleton <VehicleManager> .instance.ReleaseVehicle(vehicleId);
                }                 // NON-STOCK CODE
            }
        }
        public ushort FindRoad(Vector3 position)
        {
            Bounds     bounds   = new Bounds(position, new Vector3(20f, 20f, 20f));
            int        num      = Mathf.Max((int)((bounds.min.x - 64f) / 64f + 135f), 0);
            int        num2     = Mathf.Max((int)((bounds.min.z - 64f) / 64f + 135f), 0);
            int        num3     = Mathf.Min((int)((bounds.max.x + 64f) / 64f + 135f), 269);
            int        num4     = Mathf.Min((int)((bounds.max.z + 64f) / 64f + 135f), 269);
            NetManager instance = netManager;

            for (int i = num2; i <= num4; i++)
            {
                for (int j = num; j <= num3; j++)
                {
                    ushort num5 = instance.m_segmentGrid[i * 270 + j];
                    int    num6 = 0;
                    while (num5 != 0)
                    {
                        NetInfo info = instance.m_segments.m_buffer[(int)num5].Info;
                        if (info.m_class.m_service == ItemClass.Service.Road && !info.m_netAI.IsUnderground() &&
                            (info.m_hasForwardVehicleLanes || info.m_hasBackwardVehicleLanes))
                        {
                            ushort  startNode = instance.m_segments.m_buffer[(int)num5].m_startNode;
                            ushort  endNode   = instance.m_segments.m_buffer[(int)num5].m_endNode;
                            Vector3 position2 = instance.m_nodes.m_buffer[(int)startNode].m_position;
                            Vector3 position3 = instance.m_nodes.m_buffer[(int)endNode].m_position;
                            float   num7      =
                                Mathf.Max(Mathf.Max(bounds.min.x - 64f - position2.x, bounds.min.z - 64f - position2.z),
                                          Mathf.Max(position2.x - bounds.max.x - 64f, position2.z - bounds.max.z - 64f));
                            float num8 =
                                Mathf.Max(Mathf.Max(bounds.min.x - 64f - position3.x, bounds.min.z - 64f - position3.z),
                                          Mathf.Max(position3.x - bounds.max.x - 64f, position3.z - bounds.max.z - 64f));
                            if ((num7 < 0f || num8 < 0f) &&
                                instance.m_segments.m_buffer[(int)num5].m_bounds.Intersects(bounds) && instance
                                .m_segments.m_buffer[(int)num5].GetClosestLanePosition(position,
                                                                                       NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle,
                                                                                       VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.All,
                                                                                       VehicleInfo.VehicleType.None, false, out Vector3 b,
                                                                                       out int num9, out float num10, out Vector3 vector, out int num11,
                                                                                       out float num12))
                            {
                                float num13 = Vector3.SqrMagnitude(position - b);
                                if (num13 < 400f)
                                {
                                    return(num5);
                                }
                            }
                        }

                        num5 = instance.m_segments.m_buffer[(int)num5].m_nextGridSegment;
                        if (++num6 >= 36864)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core,
                                                            "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
            }

            return(0);
        }
Example #18
0
        private void UnloadPassengers(ushort vehicleID, ref Vehicle data, ushort currentStop, ushort nextStop)
        {
            if ((int)currentStop == 0)
            {
                return;
            }
            VehicleManager   instance1 = Singleton <VehicleManager> .instance;
            NetManager       instance2 = Singleton <NetManager> .instance;
            TransportManager instance3 = Singleton <TransportManager> .instance;
            Vector3          position  = instance2.m_nodes.m_buffer[(int)currentStop].m_position;
            Vector3          targetPos = Vector3.zero;

            if ((int)nextStop != 0)
            {
                targetPos = instance2.m_nodes.m_buffer[(int)nextStop].m_position;
            }
            int serviceCounter = 0;
            int num            = 0;

            //begin mod (+): calculate passenger count before unloading passengers
            ushort vehicleID1 = vehicleID;

            GetBufferStatus(vehicleID1, ref instance1.m_vehicles.m_buffer[(int)vehicleID1], out string localeKey,
                            out int bufferStatusBefore, out int max);
            //end mod

            while ((int)vehicleID != 0)
            {
                if ((int)data.m_transportLine != 0)
                {
                    BusAI.TransportArriveAtTarget(vehicleID, ref instance1.m_vehicles.m_buffer[(int)vehicleID],
                                                  position, targetPos, ref serviceCounter,
                                                  ref instance3.m_lines.m_buffer[(int)data.m_transportLine].m_passengers, (int)nextStop == 0);
                }
                else
                {
                    BusAI.TransportArriveAtTarget(vehicleID, ref instance1.m_vehicles.m_buffer[(int)vehicleID],
                                                  position, targetPos, ref serviceCounter,
                                                  ref instance3.m_passengers[(int)this.m_transportInfo.m_transportType], (int)nextStop == 0);
                }
                vehicleID = instance1.m_vehicles.m_buffer[(int)vehicleID].m_trailingVehicle;
                if (++num > VehicleManagerMod.MaxVehicleCount)
                {
                    CODebugBase <LogChannel> .Error(LogChannel.Core,
                                                    "Invalid list detected!\n" + System.Environment.StackTrace);

                    break;
                }
            }
            Singleton <StatisticsManager> .instance.Acquire <StatisticArray>(StatisticType.PassengerCount)
            .Acquire <StatisticInt32>((int)this.m_transportInfo.m_transportType, 10)
            .Add(serviceCounter);

            serviceCounter += (int)instance2.m_nodes.m_buffer[(int)currentStop].m_tempCounter;
            instance2.m_nodes.m_buffer[(int)currentStop].m_tempCounter =
                (ushort)Mathf.Min(serviceCounter, (int)ushort.MaxValue);

            //begin mod (+): calculate passenger count after unloading passengers
            GetBufferStatus(vehicleID1, ref instance1.m_vehicles.m_buffer[(int)vehicleID1], out localeKey,
                            out int bufferStatusAfter, out max);
            int diff = bufferStatusBefore - bufferStatusAfter;

            VehicleManagerMod.m_cachedVehicleData[(int)vehicleID1].LastStopGonePassengers = diff;
            VehicleManagerMod.m_cachedVehicleData[(int)vehicleID1].CurrentStop            = currentStop;
            NetManagerMod.m_cachedNodeData[(int)currentStop].PassengersOut += diff;
            //end mod
        }
Example #19
0
        private void RaycastHoverInstance(Ray mouseRay)
        {
            Vector3  origin     = mouseRay.origin;
            Vector3  normalized = mouseRay.direction.normalized;
            Vector3  vector     = mouseRay.origin + normalized * Camera.main.farClipPlane;
            Segment3 ray        = new Segment3(origin, vector);

            Building[]     buildingBuffer = Singleton <BuildingManager> .instance.m_buildings.m_buffer;
            NetNode[]      nodeBuffer     = Singleton <NetManager> .instance.m_nodes.m_buffer;
            NetSegment[]   segmentBuffer  = Singleton <NetManager> .instance.m_segments.m_buffer;
            TreeInstance[] treeBuffer     = Singleton <TreeManager> .instance.m_trees.m_buffer;

            Vector3 location = RaycastMouseLocation(mouseRay);

            InstanceID id = InstanceID.Empty;

            ItemClass.Layer itemLayers = GetItemLayers();

            bool selectPicker   = false;
            bool selectBuilding = true;
            bool selectProps    = true;
            bool selectDecals   = true;
            bool selectSurfaces = true;
            bool selectNodes    = true;
            bool selectSegments = true;
            bool selectTrees    = true;
            bool selectProc     = PO.Active;

            if (marqueeSelection)
            {
                selectPicker   = filterPicker;
                selectBuilding = filterBuildings;
                selectProps    = filterProps;
                selectDecals   = filterDecals;
                selectSurfaces = filterSurfaces;
                selectNodes    = filterNodes;
                selectSegments = filterSegments;
                selectTrees    = filterTrees;
                selectProc     = PO.Active && filterProcs;
            }

            if (MT_Tool == MT_Tools.Group || MT_Tool == MT_Tools.Inplace)
            {
                selectNodes = false;
                selectTrees = false;
            }
            else if (MT_Tool == MT_Tools.Mirror)
            {
                selectBuilding = false;
                selectProps    = false;
                selectDecals   = false;
                selectSurfaces = false;
                selectProc     = false;
                selectTrees    = false;
                selectNodes    = false;
            }

            float smallestDist = 640000f;

            bool repeatSearch;

            do
            {
                if (PO.Active && (selectProc || selectPicker))
                {
                    foreach (PO_Object obj in PO.Objects)
                    {
                        if (!obj.isHidden() && stepOver.isValidPO(obj.Id))
                        {
                            if (!selectProc)
                            { // Implies selectPicker is true
                                if (obj.GetPrefab() != Filters.Picker.Info)
                                {
                                    continue;
                                }
                            }
                            float radius    = obj.Size / 2;
                            bool  inXBounds = obj.Position.x > (location.x - radius) && obj.Position.x < (location.x + radius);
                            bool  inZBounds = obj.Position.z > (location.z - radius) && obj.Position.z < (location.z + radius);
                            if (inXBounds && inZBounds)
                            {
                                float t = obj.GetDistance(location);
                                if (t < smallestDist)
                                {
                                    id.NetLane   = obj.Id;
                                    smallestDist = t;
                                }
                            }
                        }
                    }
                }

                int gridMinX = Mathf.Max((int)((location.x - 16f) / 64f + 135f) - 1, 0);
                int gridMinZ = Mathf.Max((int)((location.z - 16f) / 64f + 135f) - 1, 0);
                int gridMaxX = Mathf.Min((int)((location.x + 16f) / 64f + 135f) + 1, 269);
                int gridMaxZ = Mathf.Min((int)((location.z + 16f) / 64f + 135f) + 1, 269);

                for (int i = gridMinZ; i <= gridMaxZ; i++)
                {
                    for (int j = gridMinX; j <= gridMaxX; j++)
                    {
                        if (selectBuilding || selectSurfaces || (selectPicker && Filters.Picker.IsBuilding))
                        {
                            ushort building = BuildingManager.instance.m_buildingGrid[i * 270 + j];
                            int    count    = 0;
                            while (building != 0u)
                            {
                                if (stepOver.isValidB(building) && IsBuildingValid(ref buildingBuffer[building], itemLayers) && buildingBuffer[building].RayCast(building, ray, out float t) && t < smallestDist)
                                {
                                    if (Filters.Filter(buildingBuffer[building].Info, ref buildingBuffer[building], true))
                                    {
                                        id.Building = Building.FindParentBuilding(building);
                                        if (id.Building == 0)
                                        {
                                            id.Building = building;
                                        }
                                        smallestDist = t;
                                    }
                                }
                                building = buildingBuffer[building].m_nextGridBuilding;

                                if (++count > 49152)
                                {
                                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Buildings: Invalid list detected!\n" + Environment.StackTrace);

                                    break;
                                }
                            }
                        }

                        if (selectProps || selectDecals || selectSurfaces || (selectPicker && Filters.Picker.IsProp))
                        {
                            PropLayer.Manager.RaycastHoverInstance(ref i, ref j, ref stepOver, ref ray, ref smallestDist, ref id);
                        }

                        if (selectNodes || selectBuilding || (selectPicker && Filters.Picker.IsNode))
                        {
                            ushort node  = NetManager.instance.m_nodeGrid[i * 270 + j];
                            int    count = 0;
                            while (node != 0u)
                            {
                                if (stepOver.isValidN(node) && IsNodeValid(ref nodeBuffer[node], itemLayers) && RayCastNode(ref nodeBuffer[node], ray, -1000f, out float t, out float priority) && t < smallestDist)
                                {
                                    ushort building = 0;
                                    if (!Event.current.alt)
                                    {
                                        building = NetNode.FindOwnerBuilding(node, 363f);
                                    }

                                    if (building != 0)
                                    {
                                        if (selectBuilding)
                                        {
                                            id.Building = Building.FindParentBuilding(building);
                                            if (id.Building == 0)
                                            {
                                                id.Building = building;
                                            }
                                            smallestDist = t;
                                        }
                                    }
                                    else if (selectNodes || (selectPicker && Filters.Picker.IsNode))
                                    {
                                        if (Filters.Filter(nodeBuffer[node]))
                                        {
                                            id.NetNode   = node;
                                            smallestDist = t;
                                        }
                                    }
                                }
                                node = nodeBuffer[node].m_nextGridNode;

                                if (++count > 32768)
                                {
                                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Nodes: Invalid list detected!\n" + Environment.StackTrace);
                                }
                            }
                        }

                        if (selectSegments || selectBuilding || (selectPicker && Filters.Picker.IsSegment))
                        {
                            ushort segment = NetManager.instance.m_segmentGrid[i * 270 + j];
                            int    count   = 0;
                            while (segment != 0u)
                            {
                                if (stepOver.isValidS(segment) && IsSegmentValid(ref segmentBuffer[segment], itemLayers) &&
                                    segmentBuffer[segment].RayCast(segment, ray, -1000f, false, out float t, out float priority) && t < smallestDist)
                                {
                                    ushort building = 0;
                                    if (!Event.current.alt)
                                    {
                                        building = FindOwnerBuilding(segment, 363f);
                                    }

                                    if (building != 0)
                                    {
                                        if (selectBuilding)
                                        {
                                            id.Building = Building.FindParentBuilding(building);
                                            if (id.Building == 0)
                                            {
                                                id.Building = building;
                                            }
                                            smallestDist = t;
                                        }
                                    }
                                    else if (selectSegments || (selectPicker && Filters.Picker.IsSegment))
                                    {
                                        if (!selectNodes || (
                                                (!stepOver.isValidN(segmentBuffer[segment].m_startNode) || !RayCastNode(ref nodeBuffer[segmentBuffer[segment].m_startNode], ray, -1000f, out float t2, out priority)) &&
                                                (!stepOver.isValidN(segmentBuffer[segment].m_endNode) || !RayCastNode(ref nodeBuffer[segmentBuffer[segment].m_endNode], ray, -1000f, out t2, out priority))
                                                ))
                                        {
                                            if (Filters.Filter(segmentBuffer[segment]))
                                            {
                                                id.NetSegment = segment;
                                                smallestDist  = t;
                                            }
                                        }
                                    }
                                }
                                segment = segmentBuffer[segment].m_nextGridSegment;

                                if (++count > 36864)
                                {
                                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Segments: Invalid list detected!\n" + Environment.StackTrace);

                                    segment = 0;
                                }
                            }
                        }
                    }
                }

                if (selectTrees || (selectPicker && Filters.Picker.IsTree))
                {
                    gridMinX = Mathf.Max((int)((location.x - 8f) / 32f + 270f), 0);
                    gridMinZ = Mathf.Max((int)((location.z - 8f) / 32f + 270f), 0);
                    gridMaxX = Mathf.Min((int)((location.x + 8f) / 32f + 270f), 539);
                    gridMaxZ = Mathf.Min((int)((location.z + 8f) / 32f + 270f), 539);

                    for (int i = gridMinZ; i <= gridMaxZ; i++)
                    {
                        for (int j = gridMinX; j <= gridMaxX; j++)
                        {
                            uint tree = TreeManager.instance.m_treeGrid[i * 540 + j];
                            while (tree != 0)
                            {
                                if (stepOver.isValidT(tree) && treeBuffer[tree].RayCast(tree, ray, out float t, out float targetSqr) && t < smallestDist)
                                {
                                    if (Filters.Filter(treeBuffer[tree].Info))
                                    {
                                        id.Tree      = tree;
                                        smallestDist = t;
                                    }
                                }
                                tree = treeBuffer[tree].m_nextGridTree;
                            }
                        }
                    }
                }

                repeatSearch = false;
                if (OptionsKeymapping.stepOverKey.IsPressed())
                {
                    if (!_stepProcessed)
                    {
                        _stepProcessed = true;
                        repeatSearch   = true;
                        stepOver.Add(id);
                    }
                }
                else
                {
                    _stepProcessed = false;
                }
            }while (repeatSearch);

            m_hoverInstance = id;
            m_debugPanel?.UpdatePanel(id);
            ActionQueue.instance.current?.OnHover();
        }
Example #20
0
        private void LoadPassengers(ushort vehicleID, ref Vehicle data, ushort currentStop, ushort nextStop)
        {
            if ((int)currentStop == 0 || (int)nextStop == 0)
            {
                return;
            }
            CitizenManager instance1 = Singleton <CitizenManager> .instance;
            VehicleManager instance2 = Singleton <VehicleManager> .instance;
            NetManager     instance3 = Singleton <NetManager> .instance;
            Vector3        position1 = instance3.m_nodes.m_buffer[(int)currentStop].m_position;
            Vector3        position2 = instance3.m_nodes.m_buffer[(int)nextStop].m_position;

            instance3.m_nodes.m_buffer[(int)currentStop].m_maxWaitTime = (byte)0;
            int  tempCounter = (int)instance3.m_nodes.m_buffer[(int)currentStop].m_tempCounter;
            bool flag        = false;
            int  num1        = Mathf.Max((int)(((double)position1.x - 64.0) / 8.0 + 1080.0), 0);
            int  num2        = Mathf.Max((int)(((double)position1.z - 64.0) / 8.0 + 1080.0), 0);
            int  num3        = Mathf.Min((int)(((double)position1.x + 64.0) / 8.0 + 1080.0), 2159);
            int  num4        = Mathf.Min((int)(((double)position1.z + 64.0) / 8.0 + 1080.0), 2159);
            //begin mod(+): track passengers in
            int passengersIn = 0;

            //end mod
            for (int index1 = num2; index1 <= num4 && !flag; ++index1)
            {
                for (int index2 = num1; index2 <= num3 && !flag; ++index2)
                {
                    ushort instanceID = instance1.m_citizenGrid[index1 * 2160 + index2];
                    int    num5       = 0;
                    while ((int)instanceID != 0 && !flag)
                    {
                        ushort nextGridInstance = instance1.m_instances.m_buffer[(int)instanceID].m_nextGridInstance;
                        if ((instance1.m_instances.m_buffer[(int)instanceID].m_flags &
                             CitizenInstance.Flags.WaitingTransport) != CitizenInstance.Flags.None)
                        {
                            Vector3 targetPos = (Vector3)instance1.m_instances.m_buffer[(int)instanceID].m_targetPos;
                            if ((double)Vector3.SqrMagnitude(targetPos - position1) < 4096.0)
                            {
                                CitizenInfo info = instance1.m_instances.m_buffer[(int)instanceID].Info;
                                if (info.m_citizenAI.TransportArriveAtSource(instanceID,
                                                                             ref instance1.m_instances.m_buffer[(int)instanceID], position1, position2))
                                {
                                    ushort trailerID;
                                    uint   unitID;
                                    if (Vehicle.GetClosestFreeTrailer(vehicleID, targetPos, out trailerID, out unitID))
                                    {
                                        if (info.m_citizenAI.SetCurrentVehicle(instanceID,
                                                                               ref instance1.m_instances.m_buffer[(int)instanceID], trailerID, unitID,
                                                                               position1))
                                        {
                                            ++tempCounter;
                                            ++instance2.m_vehicles.m_buffer[(int)trailerID].m_transferSize;
                                            //begin mod(+): increment passengers in
                                            ++passengersIn;
                                            //end mod
                                        }
                                        else
                                        {
                                            flag = true;
                                        }
                                    }
                                    else
                                    {
                                        flag = true;
                                    }
                                }
                            }
                        }
                        instanceID = nextGridInstance;
                        if (++num5 > 65536)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core,
                                                            "Invalid list detected!\n" + System.Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
            instance3.m_nodes.m_buffer[(int)currentStop].m_tempCounter =
                (ushort)Mathf.Min(tempCounter, (int)ushort.MaxValue);

            //begin mod (+): calculate statistics after loading passengers
            int ticketPrice = data.Info.m_vehicleAI.GetTicketPrice(vehicleID, ref data);

            VehicleManagerMod.m_cachedVehicleData[(int)vehicleID].Add(passengersIn, ticketPrice);
            NetManagerMod.m_cachedNodeData[(int)currentStop].PassengersIn += passengersIn;
            //end mod
        }
        public static void DestroyBuildings(int seed, InstanceManager.Group group, Vector3 position, float preRadius, float removeRadius,
                                            float destructionRadiusMin, float destructionRadiusMax, float burnRadiusMin, float burnRadiusMax, float probability)
        {
            int num  = Mathf.Max((int)((position.x - preRadius - 72f) / 64f + 135f), 0);
            int num2 = Mathf.Max((int)((position.z - preRadius - 72f) / 64f + 135f), 0);
            int num3 = Mathf.Min((int)((position.x + preRadius + 72f) / 64f + 135f), 269);
            int num4 = Mathf.Min((int)((position.z + preRadius + 72f) / 64f + 135f), 269);
            Array16 <Building> buildings = Singleton <BuildingManager> .instance.m_buildings;

            ushort[] buildingGrid = Singleton <BuildingManager> .instance.m_buildingGrid;
            for (int i = num2; i <= num4; i++)
            {
                for (int j = num; j <= num3; j++)
                {
                    ushort num5 = buildingGrid[i * 270 + j];
                    int    num6 = 0;
                    while (num5 != 0)
                    {
                        ushort         nextGridBuilding = buildings.m_buffer[(int)num5].m_nextGridBuilding;
                        Building.Flags flags            = buildings.m_buffer[(int)num5].m_flags;
                        if ((flags & (Building.Flags.Created | Building.Flags.Deleted | Building.Flags.Untouchable | Building.Flags.Demolishing)) == Building.Flags.Created)
                        {
                            Vector3 position2 = buildings.m_buffer[(int)num5].m_position;
                            float   num7      = VectorUtils.LengthXZ(position2 - position);
                            if (num7 < preRadius)
                            {
                                Randomizer randomizer = new Randomizer((int)num5 | seed << 16);
                                float      num8       = (destructionRadiusMax - num7) / Mathf.Max(1f, destructionRadiusMax - destructionRadiusMin);
                                float      num9       = (burnRadiusMax - num7) / Mathf.Max(1f, burnRadiusMax - burnRadiusMin);
                                bool       flag       = false;
                                bool       flag2      = (float)randomizer.Int32(10000u) < num8 * probability * 10000f;
                                bool       flag3      = (float)randomizer.Int32(10000u) < num9 * probability * 10000f;
                                if (removeRadius != 0f && num7 - 72f < removeRadius)
                                {
                                    BuildingInfo info = buildings.m_buffer[(int)num5].Info;
                                    if (info.m_circular)
                                    {
                                        float num10 = (float)(buildings.m_buffer[(int)num5].Width + buildings.m_buffer[(int)num5].Length) * 2f;
                                        flag = (num7 < removeRadius + num10);
                                    }
                                    else
                                    {
                                        float   angle   = buildings.m_buffer[(int)num5].m_angle;
                                        Vector2 a       = VectorUtils.XZ(position2);
                                        Vector2 vector  = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle));
                                        Vector2 vector2 = new Vector2(vector.y, -vector.x);
                                        vector  *= (float)buildings.m_buffer[(int)num5].Width * 4f;
                                        vector2 *= (float)buildings.m_buffer[(int)num5].Length * 4f;
                                        Quad2 quad = default(Quad2);
                                        quad.a = a - vector - vector2;
                                        quad.b = a + vector - vector2;
                                        quad.c = a + vector + vector2;
                                        quad.d = a - vector + vector2;
                                        float num11 = VectorUtils.LengthXZ(position - new Vector3(quad.a.x, position2.y, quad.a.y));
                                        float num12 = VectorUtils.LengthXZ(position - new Vector3(quad.b.x, position2.y, quad.b.y));
                                        float num13 = VectorUtils.LengthXZ(position - new Vector3(quad.c.x, position2.y, quad.c.y));
                                        float num14 = VectorUtils.LengthXZ(position - new Vector3(quad.d.x, position2.y, quad.d.y));
                                        flag = (quad.Intersect(VectorUtils.XZ(position)) || num11 < removeRadius || num12 < removeRadius || num13 < removeRadius || num14 < removeRadius);
                                    }
                                }
                                if (flag)
                                {
                                    BuildingInfo info2 = buildings.m_buffer[(int)num5].Info;
                                    info2.m_buildingAI.CollapseBuilding(num5, ref buildings.m_buffer[(int)num5], group, false, true, Mathf.RoundToInt(num9 * 255f));
                                }
                                else if (flag2)
                                {
                                    BuildingInfo    info3 = buildings.m_buffer[(int)num5].Info;
                                    ItemClass.Level lvl   = (ItemClass.Level)buildings.m_buffer[(int)num5].m_level;

                                    float p = 0.5f;

                                    if (info3.m_buildingAI as OfficeBuildingAI != null || info3.m_buildingAI as CommercialBuildingAI != null || info3.m_buildingAI as IndustrialBuildingAI != null)
                                    {
                                        switch (lvl)
                                        {
                                        case ItemClass.Level.Level1:
                                            p = 1f;
                                            break;

                                        case ItemClass.Level.Level2:
                                            p = 0.6f;
                                            break;

                                        case ItemClass.Level.Level3:
                                            p = 0.2f;
                                            break;
                                        }
                                    }
                                    else if (info3.m_buildingAI as ResidentialBuildingAI != null)
                                    {
                                        switch (lvl)
                                        {
                                        case ItemClass.Level.Level1:
                                            p = 1f;
                                            break;

                                        case ItemClass.Level.Level2:
                                            p = 0.8f;
                                            break;

                                        case ItemClass.Level.Level3:
                                            p = 0.6f;
                                            break;

                                        case ItemClass.Level.Level4:
                                            p = 0.4f;
                                            break;

                                        case ItemClass.Level.Level5:
                                            p = 0.2f;
                                            break;
                                        }
                                    }

                                    // Large buildings are tougher
                                    float s = Mathf.Sqrt(buildings.m_buffer[(int)num5].Length * buildings.m_buffer[(int)num5].Width);
                                    if (s > 4)
                                    {
                                        p -= s / 16;
                                    }

                                    // Make shelters a little more useful
                                    if ((flags & Building.Flags.Evacuating) == Building.Flags.Evacuating)
                                    {
                                        p -= 0.2f;
                                    }

                                    if (p > 0 && (float)randomizer.Int32(10000u) < p * 10000f)
                                    {
                                        //Debug.Log("Destroyed: " + info3.name + " (" + info3.m_buildingAI.name + "), level: " + lvl.ToString());
                                        info3.m_buildingAI.CollapseBuilding(num5, ref buildings.m_buffer[(int)num5], group, false, false, Mathf.RoundToInt(num9 * 255f));
                                    }
                                }
                                else if (flag3 && (flags & Building.Flags.Collapsed) == Building.Flags.None && buildings.m_buffer[(int)num5].m_fireIntensity == 0)
                                {
                                    BuildingInfo info4 = buildings.m_buffer[(int)num5].Info;
                                    info4.m_buildingAI.BurnBuilding(num5, ref buildings.m_buffer[(int)num5], group, false);
                                }
                            }
                        }
                        num5 = nextGridBuilding;
                        if (++num6 >= 49152)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
        }
        private void BaseSimulationStep(ushort vehicleId, ref Vehicle data, Vector3 physicsLodRefPos)
        {
            if ((data.m_flags & Vehicle.Flags.WaitingPath) != Vehicle.Flags.None)
            {
                PathManager instance      = Singleton <PathManager> .instance;
                byte        pathFindFlags = instance.m_pathUnits.m_buffer[(int)((UIntPtr)data.m_path)].m_pathFindFlags;
                if ((pathFindFlags & 4) != 0)
                {
                    data.m_pathPositionIndex = 255;
                    data.m_flags            &= ~Vehicle.Flags.WaitingPath;
                    data.m_flags            &= ~Vehicle.Flags.Arriving;
                    PathfindSuccess(vehicleId, ref data);
                    TrySpawn(vehicleId, ref data);
                }
                else if ((pathFindFlags & 8) != 0)
                {
                    data.m_flags &= ~Vehicle.Flags.WaitingPath;
                    Singleton <PathManager> .instance.ReleasePath(data.m_path);

                    data.m_path = 0u;
                    PathfindFailure(vehicleId, ref data);
                    return;
                }
            }
            else if ((data.m_flags & Vehicle.Flags.WaitingSpace) != Vehicle.Flags.None)
            {
                TrySpawn(vehicleId, ref data);
            }
            Vector3 lastFramePosition = data.GetLastFramePosition();
            int     lodPhysics;

            if (Vector3.SqrMagnitude(physicsLodRefPos - lastFramePosition) >= 1210000f)
            {
                lodPhysics = 2;
            }
            else if (
                Vector3.SqrMagnitude(Singleton <SimulationManager> .instance.m_simulationView.m_position -
                                     lastFramePosition) >= 250000f)
            {
                lodPhysics = 1;
            }
            else
            {
                lodPhysics = 0;
            }
            SimulationStep(vehicleId, ref data, vehicleId, ref data, lodPhysics);
            if (data.m_leadingVehicle == 0 && data.m_trailingVehicle != 0)
            {
                VehicleManager instance2 = Singleton <VehicleManager> .instance;
                ushort         num       = data.m_trailingVehicle;
                int            num2      = 0;
                while (num != 0)
                {
                    ushort      trailingVehicle = instance2.m_vehicles.m_buffer[num].m_trailingVehicle;
                    VehicleInfo info            = instance2.m_vehicles.m_buffer[num].Info;
                    info.m_vehicleAI.SimulationStep(num, ref instance2.m_vehicles.m_buffer[num], vehicleId,
                                                    ref data, lodPhysics);
                    num = trailingVehicle;
                    if (++num2 > 16384)
                    {
                        CODebugBase <LogChannel> .Error(LogChannel.Core,
                                                        "Invalid list detected!\n" + Environment.StackTrace);

                        break;
                    }
                }
            }
            int maxBlockCounter = (m_info.m_class.m_service > ItemClass.Service.Office) ? 150 : 100;

            if ((data.m_flags & (Vehicle.Flags.Spawned | Vehicle.Flags.WaitingPath | Vehicle.Flags.WaitingSpace)) ==
                Vehicle.Flags.None && data.m_cargoParent == 0)
            {
                Singleton <VehicleManager> .instance.ReleaseVehicle(vehicleId);
            }
            else if (data.m_blockCounter >= maxBlockCounter && Options.enableDespawning)
            {
                Singleton <VehicleManager> .instance.ReleaseVehicle(vehicleId);
            }
            else if (data.m_leadingVehicle == 0 && CustomVehicleAI.ShouldRecalculatePath(vehicleId, ref data, maxBlockCounter))
            {
                CustomVehicleAI.MarkPathRecalculation(vehicleId);
                InvalidPath(vehicleId, ref data, vehicleId, ref data);
            }
        }
		private static bool RayCast(TreeManager tm, Segment3 ray, ItemClass.Service service, ItemClass.SubService subService, ItemClass.Layer itemLayers, TreeInstance.Flags ignoreFlags, out Vector3 hit, out uint treeIndex)
		{
			unsafe
			{
				int num;
				int num1;
				int num2;
				int num3;
				int num4;
				int num5;
				float single;
				float single1;
				Bounds bound = new Bounds(new Vector3(0f, 512f, 0f), new Vector3(17280f, 1152f, 17280f));
				if (ray.Clip(bound))
				{
					Vector3 vector3 = ray.b - ray.a;
					int num6 = (int)((double)ray.a.x / 32 + 270);
					int num7 = (int)((double)ray.a.z / 32 + 270);
					int num8 = (int)((double)ray.b.x / 32 + 270);
					int num9 = (int)((double)ray.b.z / 32 + 270);
					float single2 = Mathf.Abs(vector3.x);
					float single3 = Mathf.Abs(vector3.z);
					if ((double)single2 < (double)single3)
					{
						num = 0;
						num1 = ((double)vector3.z <= 0 ? -1 : 1);
						if ((double)single3 != 0)
						{
							vector3 = vector3 * (32f / single3);
						}
					}
					else
					{
						num = ((double)vector3.x <= 0 ? -1 : 1);
						num1 = 0;
						if ((double)single2 != 0)
						{
							vector3 = vector3 * (32f / single2);
						}
					}
					float single4 = 2f;
					float single5 = 10000f;
					treeIndex = 0;
					Vector3 vector31 = ray.a;
					Vector3 vector32 = ray.a;
					int num10 = num6;
					int num11 = num7;
					do
					{
						Vector3 vector33 = vector32 + vector3;
						if (num == 0)
						{
							num4 = ((num11 != num7 || num1 <= 0) && (num11 != num9 || num1 >= 0) ? Mathf.Max(num11, 0) : Mathf.Max((int)(((double)vector33.z - 72) / 32 + 270), 0));
							num5 = ((num11 != num7 || num1 >= 0) && (num11 != num9 || num1 <= 0) ? Mathf.Min(num11, 539) : Mathf.Min((int)(((double)vector33.z + 72) / 32 + 270), 539));
							num2 = Mathf.Max((int)(((double)Mathf.Min(vector31.x, vector33.x) - 72) / 32 + 270), 0);
							num3 = Mathf.Min((int)(((double)Mathf.Max(vector31.x, vector33.x) + 72) / 32 + 270), 539);
						}
						else
						{
							num2 = ((num10 != num6 || num <= 0) && (num10 != num8 || num >= 0) ? Mathf.Max(num10, 0) : Mathf.Max((int)(((double)vector33.x - 72) / 32 + 270), 0));
							num3 = ((num10 != num6 || num >= 0) && (num10 != num8 || num <= 0) ? Mathf.Min(num10, 539) : Mathf.Min((int)(((double)vector33.x + 72) / 32 + 270), 539));
							num4 = Mathf.Max((int)(((double)Mathf.Min(vector31.z, vector33.z) - 72) / 32 + 270), 0);
							num5 = Mathf.Min((int)(((double)Mathf.Max(vector31.z, vector33.z) + 72) / 32 + 270), 539);
						}
						for (int i = num4; i <= num5; i++)
						{
							for (int j = num2; j <= num3; j++)
							{
								uint mTreeGrid = tm.m_treeGrid[i * 540 + j];
								int num12 = 0;
								while (mTreeGrid != 0)
								{
									if ((tm.m_trees.m_buffer[mTreeGrid].m_flags & (ushort)ignoreFlags) == (ushort)TreeInstance.Flags.None && (double)ray.DistanceSqr(tm.m_trees.m_buffer[mTreeGrid].Position) < 2500)
									{
										TreeInfo info = tm.m_trees.m_buffer[mTreeGrid].Info;
										if ((service == ItemClass.Service.None || info.m_class.m_service == service) && (subService == ItemClass.SubService.None || info.m_class.m_subService == subService) && (itemLayers == ItemClass.Layer.None || (info.m_class.m_layer & itemLayers) != ItemClass.Layer.None) && tm.m_trees.m_buffer[mTreeGrid].RayCast(mTreeGrid, ray, out single, out single1) && ((double)single < (double)single4 - 9.99999974737875E-05 || (double)single < (double)single4 + 9.99999974737875E-05 && (double)single1 < (double)single5))
										{
											single4 = single;
											single5 = single1;
											treeIndex = mTreeGrid;
										}
									}
									mTreeGrid = tm.m_trees.m_buffer[mTreeGrid].m_nextGridTree;
									int num13 = num12 + 1;
									num12 = num13;
									if (num13 <= LimitTreeManager.Helper.TreeLimit)
									{
										continue;
									}
									CODebugBase<LogChannel>.Error(LogChannel.Core, string.Concat("Invalid list detected!\n", Environment.StackTrace));
									break;
								}
							}
						}
						vector31 = vector32;
						vector32 = vector33;
						num10 = num10 + num;
						num11 = num11 + num1;
					}
					while ((num10 <= num8 || num <= 0) && (num10 >= num8 || num >= 0) && (num11 <= num9 || num1 <= 0) && (num11 >= num9 || num1 >= 0));
					if ((double)single4 != 2)
					{
						hit = ray.Position(single4);
						return true;
					}
				}
				hit = Vector3.zero;
				treeIndex = 0;
				return false;
			}
		}
Example #24
0
        public void SimulationStep(ushort lineID)
        {
            if (!m_initialized)
            {
                m_initialized = true;
                for (int i = 0; i < Singleton <TransportManager> .instance.m_lines.m_buffer.Length; i++)
                {
                    m_flagsLastState[i] = Singleton <TransportManager> .instance.m_lines.m_buffer[i].m_flags;
                }
            }

            var flagsChanged = (m_flagsLastState[lineID] ^ Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_flags);

            m_flagsLastState[lineID] = Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_flags;

            if ((flagsChanged & TransportLine.Flags.Complete) != TransportLine.Flags.None)
            {
                if (TLMConfigWarehouse.getCurrentConfigBool(TLMConfigWarehouse.ConfigIndex.AUTO_COLOR_ENABLED))
                {
                    TLMController.instance.AutoColor(lineID);
                }

                if (TLMConfigWarehouse.getCurrentConfigBool(TLMConfigWarehouse.ConfigIndex.AUTO_NAME_ENABLED))
                {
                    TLMUtils.setLineName(lineID, TLMUtils.calculateAutoName(lineID));
                }
            }

            if (TransportLinesManagerMod.instance != null && TransportLinesManagerMod.debugMode)
            {
                TLMUtils.doLog("LTLMTransportLine SimulationStep!");
            }
            TransportInfo info = Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].Info;

            TLMCW.ConfigIndex lineType = TLMCW.getDefinitionForLine(lineID).toConfigIndex();

            float defaultCostPerPassengerCapacity = TLMCW.getCostPerPassengerCapacityLine(lineType);

            if (Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].Complete)
            {
                int vehicleCount      = 0;
                int installedCapacity = 0;
                if (Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_vehicles != 0)
                {
                    VehicleManager instance  = Singleton <VehicleManager> .instance;
                    ushort         nextId    = Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_vehicles;
                    int            loopCount = 0;
                    while (nextId != 0)
                    {
                        ushort nextLineVehicle = instance.m_vehicles.m_buffer[(int)nextId].m_nextLineVehicle;
                        vehicleCount++;
                        installedCapacity += TLMLineUtils.getVehicleCapacity(nextId);
                        nextId             = nextLineVehicle;
                        if (++loopCount > 16384)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
                uint prefix = 0;
                if (TLMConfigWarehouse.getCurrentConfigInt(TLMConfigWarehouse.getConfigIndexForTransportInfo(info) | TLMConfigWarehouse.ConfigIndex.PREFIX) != (int)ModoNomenclatura.Nenhum)
                {
                    prefix = Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_lineNumber / 1000u;
                }
                float budgetMultiplierPrefix = TLMUtils.getExtensionFromConfigIndex(TLMCW.getConfigIndexForTransportInfo(info)).getBudgetMultiplierForHour(prefix, (int)Singleton <SimulationManager> .instance.m_currentDayTimeHour) / 100f;

                var flagToCheck = (TransportLine.Flags.DisabledNight | TransportLine.Flags.DisabledDay);

                if (budgetMultiplierPrefix == 0 && (Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_flags & flagToCheck) == TransportLine.Flags.None)
                {
                    int flagsToAdd = (int)(TransportLine.Flags.DisabledDay | TransportLine.Flags.DisabledNight) | (int)(TLMTransportLineFlags.ZERO_BUDGET_SETTED);
                    if ((Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_flags & (TransportLine.Flags)TLMTransportLineFlags.ZERO_BUDGET_SETTED) == TransportLine.Flags.None)
                    {
                        if ((Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_flags & TransportLine.Flags.DisabledDay) == TransportLine.Flags.None)
                        {
                            flagsToAdd |= (int)TLMTransportLineFlags.ZERO_BUDGET_DAY;
                        }
                        if ((Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_flags & TransportLine.Flags.DisabledNight) == TransportLine.Flags.None)
                        {
                            flagsToAdd |= (int)TLMTransportLineFlags.ZERO_BUDGET_NIGHT;
                        }
                    }
                    Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_flags |= (TransportLine.Flags)flagsToAdd;
                }
                else if ((budgetMultiplierPrefix > 0 && (Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_flags & (TransportLine.Flags)(TLMTransportLineFlags.ZERO_BUDGET_SETTED)) != TransportLine.Flags.None))
                {
                    bool actDay   = (Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_flags & (TransportLine.Flags)TLMTransportLineFlags.ZERO_BUDGET_DAY) != TransportLine.Flags.None;
                    bool actNight = (Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_flags & (TransportLine.Flags)TLMTransportLineFlags.ZERO_BUDGET_NIGHT) != TransportLine.Flags.None;
                    Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_flags &= (TransportLine.Flags) ~(TLMTransportLineFlags.ZERO_BUDGET_DAY | TLMTransportLineFlags.ZERO_BUDGET_NIGHT | TLMTransportLineFlags.ZERO_BUDGET_SETTED);
                    TLMLineUtils.setLineActive(ref Singleton <TransportManager> .instance.m_lines.m_buffer[lineID], actDay, actNight);
                }

                bool active;
                if (Singleton <SimulationManager> .instance.m_isNightTime)
                {
                    active = ((Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_flags & TransportLine.Flags.DisabledNight) == TransportLine.Flags.None);
                }
                else
                {
                    active = ((Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_flags & TransportLine.Flags.DisabledDay) == TransportLine.Flags.None);
                }
                uint  steps    = 0u;
                float distance = 0f;
                bool  broken   = false;
                if (Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_stops != 0)
                {
                    NetManager instance2 = Singleton <NetManager> .instance;
                    ushort     stops     = Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_stops;
                    ushort     nextStop  = stops;
                    int        count     = 0;
                    while (nextStop != 0)
                    {
                        ushort num8 = 0;
                        if (active)
                        {
                            NetNode[] expr_10A_cp_0 = instance2.m_nodes.m_buffer;
                            ushort    expr_10A_cp_1 = nextStop;
                            expr_10A_cp_0[(int)expr_10A_cp_1].m_flags = (expr_10A_cp_0[(int)expr_10A_cp_1].m_flags & ~NetNode.Flags.Disabled);
                        }
                        else
                        {
                            NetNode[] expr_130_cp_0 = instance2.m_nodes.m_buffer;
                            ushort    expr_130_cp_1 = nextStop;
                            expr_130_cp_0[(int)expr_130_cp_1].m_flags = (expr_130_cp_0[(int)expr_130_cp_1].m_flags | NetNode.Flags.Disabled);
                        }
                        for (int i = 0; i < 8; i++)
                        {
                            ushort segment = instance2.m_nodes.m_buffer[(int)nextStop].GetSegment(i);
                            if (segment != 0 && instance2.m_segments.m_buffer[(int)segment].m_startNode == nextStop)
                            {
                                distance += instance2.m_segments.m_buffer[(int)segment].m_averageLength;
                                num8      = instance2.m_segments.m_buffer[(int)segment].m_endNode;
                                if ((instance2.m_segments.m_buffer[(int)segment].m_flags & NetSegment.Flags.PathLength) == NetSegment.Flags.None)
                                {
                                    broken = true;
                                }
                                break;
                            }
                        }
                        steps   += 1u;
                        nextStop = num8;
                        if (nextStop == stops)
                        {
                            break;
                        }
                        if (++count >= 32768)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
                float lineCost = vehicleCount * info.m_maintenanceCostPerVehicle / 100;// * defaultCostPerPassengerCapacity;
                if (lineCost != 0)
                {
                    Singleton <EconomyManager> .instance.FetchResource(EconomyManager.Resource.Maintenance, m_linesCost.m_buffer[lineID], info.m_class);
                }
                int budget = Singleton <EconomyManager> .instance.GetBudget(info.m_class);

                int necessaryVehicles;

                if (!active)
                {
                    necessaryVehicles = 0;
                }
                else
                {
                    necessaryVehicles = TLMVehiclesLineManager.instance[lineID];
                    if (necessaryVehicles == 0)
                    {
                        if (broken)
                        {
                            necessaryVehicles = vehicleCount;
                        }
                        else
                        {
                            necessaryVehicles = Mathf.CeilToInt(budget * budgetMultiplierPrefix * distance / (info.m_defaultVehicleDistance * 100f));
                        }
                    }
                }
                if (steps != 0u && vehicleCount < necessaryVehicles)
                {
                    TransferManager.TransferReason vehicleReason = info.m_vehicleReason;
                    int index = Singleton <SimulationManager> .instance.m_randomizer.Int32(steps);

                    ushort stop = Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].GetStop(index);
                    if (vehicleReason != TransferManager.TransferReason.None && stop != 0)
                    {
                        TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                        offer.Priority      = necessaryVehicles - vehicleCount + 1;
                        offer.TransportLine = lineID;
                        offer.Position      = Singleton <NetManager> .instance.m_nodes.m_buffer[stop].m_position;
                        offer.Amount        = 1;
                        offer.Active        = false;
                        Singleton <TransferManager> .instance.AddIncomingOffer(vehicleReason, offer);
                    }
                }
                else if (vehicleCount > necessaryVehicles)
                {
                    int index2 = Singleton <SimulationManager> .instance.m_randomizer.Int32((uint)vehicleCount);

                    ushort vehicle = Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].GetVehicle(index2);
                    if (vehicle != 0)
                    {
                        VehicleManager instance3 = Singleton <VehicleManager> .instance;
                        VehicleInfo    info2     = instance3.m_vehicles.m_buffer[(int)vehicle].Info;
                        info2.m_vehicleAI.SetTransportLine(vehicle, ref instance3.m_vehicles.m_buffer[(int)vehicle], 0);
                    }
                }
            }
            if ((Singleton <SimulationManager> .instance.m_currentFrameIndex & 4095u) >= 3840u)
            {
                Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_passengers.Update();
                Singleton <TransportManager> .instance.m_passengers[(int)info.m_transportType].Add(ref Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_passengers);
                Singleton <TransportManager> .instance.m_lines.m_buffer[lineID].m_passengers.Reset();
            }
        }
        internal bool ExtParkVehicle(ushort vehicleID, ref Vehicle vehicleData, uint driverCitizenId, ushort driverCitizenInstanceId, ref ExtCitizenInstance driverExtInstance, ushort targetBuildingId, PathUnit.Position pathPos, uint nextPath, int nextPositionIndex, out byte segmentOffset)
        {
#if DEBUG
            bool citDebug  = GlobalConfig.Instance.Debug.CitizenId == 0 || GlobalConfig.Instance.Debug.CitizenId == driverExtInstance.GetCitizenId();
            bool debug     = GlobalConfig.Instance.Debug.Switches[2] && citDebug;
            bool fineDebug = GlobalConfig.Instance.Debug.Switches[4] && citDebug;
#endif

            PathManager pathManager       = Singleton <PathManager> .instance;
            CitizenManager citizenManager = Singleton <CitizenManager> .instance;
            NetManager netManager         = Singleton <NetManager> .instance;
            VehicleManager vehicleManager = Singleton <VehicleManager> .instance;

            // NON-STOCK CODE START
            bool prohibitPocketCars = false;
            // NON-STOCK CODE END

            if (driverCitizenId != 0u)
            {
                if (Options.prohibitPocketCars && driverCitizenInstanceId != 0)
                {
                    prohibitPocketCars = true;
                }

                uint laneID = PathManager.GetLaneID(pathPos);
                segmentOffset = (byte)Singleton <SimulationManager> .instance.m_randomizer.Int32(1, 254);

                Vector3 refPos;
                Vector3 vector;
                netManager.m_lanes.m_buffer[laneID].CalculatePositionAndDirection((float)segmentOffset * 0.003921569f, out refPos, out vector);
                NetInfo info           = netManager.m_segments.m_buffer[(int)pathPos.m_segment].Info;
                bool isSegmentInverted = (netManager.m_segments.m_buffer[(int)pathPos.m_segment].m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None;
                bool isPosNegative     = info.m_lanes[(int)pathPos.m_lane].m_position < 0f;
                vector.Normalize();
                Vector3 searchDir;
                if (isSegmentInverted != isPosNegative)
                {
                    searchDir.x = -vector.z;
                    searchDir.y = 0f;
                    searchDir.z = vector.x;
                }
                else
                {
                    searchDir.x = vector.z;
                    searchDir.y = 0f;
                    searchDir.z = -vector.x;
                }
                ushort homeID = 0;
                if (driverCitizenId != 0u)
                {
                    homeID = Singleton <CitizenManager> .instance.m_citizens.m_buffer[driverCitizenId].m_homeBuilding;
                }
                Vector3 parkPos    = default(Vector3);
                Quaternion parkRot = default(Quaternion);
                float parkOffset   = -1f;

                // NON-STOCK CODE START
                bool foundParkingSpace = false;

                if (prohibitPocketCars)
                {
#if DEBUG
                    if (debug)
                    {
                        Log._Debug($"Vehicle {vehicleID} tries to park on a parking position now (flags: {vehicleData.m_flags})! CurrentPathMode={driverExtInstance.pathMode} path={vehicleData.m_path} pathPositionIndex={vehicleData.m_pathPositionIndex} segmentId={pathPos.m_segment} laneIndex={pathPos.m_lane} offset={pathPos.m_offset} nextPath={nextPath} refPos={refPos} searchDir={searchDir} home={homeID} driverCitizenId={driverCitizenId} driverCitizenInstanceId={driverCitizenInstanceId}");
                    }
#endif

                    if (driverExtInstance.pathMode == ExtCitizenInstance.ExtPathMode.DrivingToAltParkPos || driverExtInstance.pathMode == ExtCitizenInstance.ExtPathMode.DrivingToKnownParkPos)
                    {
                        // try to use previously found parking space
#if DEBUG
                        if (debug)
                        {
                            Log._Debug($"Vehicle {vehicleID} tries to park on an (alternative) parking position now! CurrentPathMode={driverExtInstance.pathMode} altParkingSpaceLocation={driverExtInstance.parkingSpaceLocation} altParkingSpaceLocationId={driverExtInstance.parkingSpaceLocationId}");
                        }
#endif

                        switch (driverExtInstance.parkingSpaceLocation)
                        {
                        case ExtCitizenInstance.ExtParkingSpaceLocation.RoadSide:
                            uint parkLaneID; int parkLaneIndex;
#if DEBUG
                            if (debug)
                            {
                                Log._Debug($"Vehicle {vehicleID} wants to park road-side @ segment {driverExtInstance.parkingSpaceLocationId}");
                            }
#endif
                            foundParkingSpace = AdvancedParkingManager.Instance.FindParkingSpaceRoadSideForVehiclePos(this.m_info, 0, driverExtInstance.parkingSpaceLocationId, refPos, out parkPos, out parkRot, out parkOffset, out parkLaneID, out parkLaneIndex);
                            break;

                        case ExtCitizenInstance.ExtParkingSpaceLocation.Building:
                            float maxDist = 9999f;
#if DEBUG
                            if (debug)
                            {
                                Log._Debug($"Vehicle {vehicleID} wants to park @ building {driverExtInstance.parkingSpaceLocationId}");
                            }
#endif
                            foundParkingSpace = AdvancedParkingManager.Instance.FindParkingSpacePropAtBuilding(this.m_info, homeID, 0, driverExtInstance.parkingSpaceLocationId, ref Singleton <BuildingManager> .instance.m_buildings.m_buffer[driverExtInstance.parkingSpaceLocationId], pathPos.m_segment, refPos, ref maxDist, true, out parkPos, out parkRot, out parkOffset);
                            break;

                        default:
#if DEBUG
                            Log.Error($"No alternative parking position stored for vehicle {vehicleID}! PathMode={driverExtInstance.pathMode}");
#endif
                            foundParkingSpace = CustomFindParkingSpace(this.m_info, homeID, refPos, searchDir, pathPos.m_segment, out parkPos, out parkRot, out parkOffset);
                            break;
                        }
                    }
                }

                if (!foundParkingSpace)
                {
                    foundParkingSpace =                     /*prohibitPocketCars ?*/
                                        CustomFindParkingSpace(this.m_info, homeID, refPos, searchDir, pathPos.m_segment, out parkPos, out parkRot, out parkOffset) /*:
                                                                                                                                                                     * FindParkingSpace(homeID, refPos, searchDir, pathPos.m_segment, this.m_info.m_generatedInfo.m_size.x, this.m_info.m_generatedInfo.m_size.z, out parkPos, out parkRot, out parkOffset)*/;
                }

                // NON-STOCK CODE END
                ushort parkedVehicleId = 0;
                bool parkedCarCreated  = foundParkingSpace && vehicleManager.CreateParkedVehicle(out parkedVehicleId, ref Singleton <SimulationManager> .instance.m_randomizer, this.m_info, parkPos, parkRot, driverCitizenId);
                if (foundParkingSpace && parkedCarCreated)
                {
                    // we have reached a parking position
#if DEBUG
                    float sqrDist = (refPos - parkPos).sqrMagnitude;
                    if (fineDebug)
                    {
                        Log._Debug($"Vehicle {vehicleID} succeeded in parking! CurrentPathMode={driverExtInstance.pathMode} sqrDist={sqrDist}");
                    }

                    if (GlobalConfig.Instance.Debug.Switches[6] && sqrDist >= 16000)
                    {
                        Log._Debug($"CustomPassengerCarAI.CustomParkVehicle: FORCED PAUSE. Distance very large! Vehicle {vehicleID}. dist={sqrDist}");
                        Singleton <SimulationManager> .instance.SimulationPaused = true;
                    }
#endif

                    citizenManager.m_citizens.m_buffer[driverCitizenId].SetParkedVehicle(driverCitizenId, parkedVehicleId);
                    if (parkOffset >= 0f)
                    {
                        segmentOffset = (byte)(parkOffset * 255f);
                    }

                    // NON-STOCK CODE START
                    if (prohibitPocketCars)
                    {
                        if ((driverExtInstance.pathMode == ExtCitizenInstance.ExtPathMode.DrivingToAltParkPos || driverExtInstance.pathMode == ExtCitizenInstance.ExtPathMode.DrivingToKnownParkPos) && targetBuildingId != 0)
                        {
                            // decrease parking space demand of target building
                            ExtBuildingManager.Instance.ExtBuildings[targetBuildingId].ModifyParkingSpaceDemand(parkPos, GlobalConfig.Instance.ParkingAI.MinFoundParkPosParkingSpaceDemandDelta, GlobalConfig.Instance.ParkingAI.MaxFoundParkPosParkingSpaceDemandDelta);
                        }

                        //if (driverExtInstance.CurrentPathMode == ExtCitizenInstance.PathMode.DrivingToAltParkPos || driverExtInstance.CurrentPathMode == ExtCitizenInstance.PathMode.DrivingToKnownParkPos) {
                        // we have reached an (alternative) parking position and succeeded in finding a parking space
                        driverExtInstance.pathMode = ExtCitizenInstance.ExtPathMode.RequiresWalkingPathToTarget;
                        driverExtInstance.failedParkingAttempts  = 0;
                        driverExtInstance.parkingSpaceLocation   = ExtCitizenInstance.ExtParkingSpaceLocation.None;
                        driverExtInstance.parkingSpaceLocationId = 0;
#if DEBUG
                        if (debug)
                        {
                            Log._Debug($"Vehicle {vehicleID} has reached an (alternative) parking position! CurrentPathMode={driverExtInstance.pathMode} position={parkPos}");
                        }
#endif
                        //}
                    }
                }
                else if (prohibitPocketCars)
                {
                    // could not find parking space. vehicle would despawn.
                    if (targetBuildingId != 0 && (Singleton <BuildingManager> .instance.m_buildings.m_buffer[targetBuildingId].m_flags & Building.Flags.IncomingOutgoing) != Building.Flags.None)
                    {
                        // target is an outside connection
                        return(true);
                    }

                    // Find parking space in the vicinity, redo path-finding to the parking space, park the vehicle and do citizen path-finding to the current target

                    if (!foundParkingSpace && (driverExtInstance.pathMode == ExtCitizenInstance.ExtPathMode.DrivingToAltParkPos || driverExtInstance.pathMode == ExtCitizenInstance.ExtPathMode.DrivingToKnownParkPos) && targetBuildingId != 0)
                    {
                        // increase parking space demand of target building
                        if (driverExtInstance.failedParkingAttempts > 1)
                        {
                            ExtBuildingManager.Instance.ExtBuildings[targetBuildingId].AddParkingSpaceDemand(GlobalConfig.Instance.ParkingAI.FailedParkingSpaceDemandIncrement * (uint)(driverExtInstance.failedParkingAttempts - 1));
                        }
                    }

                    if (!foundParkingSpace)
                    {
                        ++driverExtInstance.failedParkingAttempts;
                    }
                    else
                    {
#if DEBUG
                        if (debug)
                        {
                            Log._Debug($"Parking failed for vehicle {vehicleID}: Parked car could not be created. ABORT.");
                        }
#endif
                        driverExtInstance.failedParkingAttempts = GlobalConfig.Instance.ParkingAI.MaxParkingAttempts + 1;
                    }
                    driverExtInstance.pathMode = ExtCitizenInstance.ExtPathMode.ParkingFailed;
                    driverExtInstance.parkingPathStartPosition = pathPos;

#if DEBUG
                    if (debug)
                    {
                        Log._Debug($"Parking failed for vehicle {vehicleID}! (flags: {vehicleData.m_flags}) pathPos segment={pathPos.m_segment}, lane={pathPos.m_lane}, offset={pathPos.m_offset}. Trying to find parking space in the vicinity. FailedParkingAttempts={driverExtInstance.failedParkingAttempts}, CurrentPathMode={driverExtInstance.pathMode} foundParkingSpace={foundParkingSpace}");
                    }
#endif

                    // invalidate paths of all passengers in order to force path recalculation
                    uint curUnitId = vehicleData.m_citizenUnits;
                    int numIter    = 0;
                    while (curUnitId != 0u)
                    {
                        uint nextUnit = citizenManager.m_units.m_buffer[curUnitId].m_nextUnit;
                        for (int i = 0; i < 5; i++)
                        {
                            uint curCitizenId = citizenManager.m_units.m_buffer[curUnitId].GetCitizen(i);
                            if (curCitizenId != 0u)
                            {
                                ushort citizenInstanceId = citizenManager.m_citizens.m_buffer[curCitizenId].m_instance;
                                if (citizenInstanceId != 0)
                                {
#if DEBUG
                                    if (debug)
                                    {
                                        Log._Debug($"Releasing path for citizen instance {citizenInstanceId} sitting in vehicle {vehicleID} (was {citizenManager.m_instances.m_buffer[citizenInstanceId].m_path}).");
                                    }
#endif
                                    if (citizenInstanceId != driverCitizenInstanceId)
                                    {
#if DEBUG
                                        if (debug)
                                        {
                                            Log._Debug($"Resetting pathmode for passenger citizen instance {citizenInstanceId} sitting in vehicle {vehicleID} (was {ExtCitizenInstanceManager.Instance.ExtInstances[citizenInstanceId].pathMode}).");
                                        }
#endif

                                        ExtCitizenInstanceManager.Instance.ExtInstances[citizenInstanceId].Reset();
                                    }

                                    if (citizenManager.m_instances.m_buffer[citizenInstanceId].m_path != 0)
                                    {
                                        Singleton <PathManager> .instance.ReleasePath(citizenManager.m_instances.m_buffer[citizenInstanceId].m_path);

                                        citizenManager.m_instances.m_buffer[citizenInstanceId].m_path = 0u;
                                    }
                                }
                            }
                        }
                        curUnitId = nextUnit;
                        if (++numIter > CitizenManager.MAX_UNIT_COUNT)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                    return(false);
                    // NON-STOCK CODE END
                }
            }
            else
            {
                segmentOffset = pathPos.m_offset;
            }

            // parking has succeeded
            if (driverCitizenId != 0u)
            {
                uint curCitizenUnitId = vehicleData.m_citizenUnits;
                int numIter           = 0;
                while (curCitizenUnitId != 0u)
                {
                    uint nextUnit = citizenManager.m_units.m_buffer[curCitizenUnitId].m_nextUnit;
                    for (int j = 0; j < 5; j++)
                    {
                        uint citId = citizenManager.m_units.m_buffer[curCitizenUnitId].GetCitizen(j);
                        if (citId != 0u)
                        {
                            ushort citizenInstanceId = citizenManager.m_citizens.m_buffer[citId].m_instance;
                            if (citizenInstanceId != 0)
                            {
                                // NON-STOCK CODE START
                                if (prohibitPocketCars)
                                {
                                    if (driverExtInstance.pathMode == ExtCitizenInstance.ExtPathMode.RequiresWalkingPathToTarget)
                                    {
#if DEBUG
                                        if (debug)
                                        {
                                            Log._Debug($"Parking succeeded: Doing nothing for citizen instance {citizenInstanceId}! path: {citizenManager.m_instances.m_buffer[(int)citizenInstanceId].m_path}");
                                        }
#endif
                                        ExtCitizenInstanceManager.Instance.ExtInstances[citizenInstanceId].pathMode = ExtCitizenInstance.ExtPathMode.RequiresWalkingPathToTarget;
                                        continue;
                                    }
                                }
                                // NON-STOCK CODE END

                                if (pathManager.AddPathReference(nextPath))
                                {
                                    if (citizenManager.m_instances.m_buffer[(int)citizenInstanceId].m_path != 0u)
                                    {
                                        pathManager.ReleasePath(citizenManager.m_instances.m_buffer[(int)citizenInstanceId].m_path);
                                    }
                                    citizenManager.m_instances.m_buffer[(int)citizenInstanceId].m_path = nextPath;
                                    citizenManager.m_instances.m_buffer[(int)citizenInstanceId].m_pathPositionIndex = (byte)nextPositionIndex;
                                    citizenManager.m_instances.m_buffer[(int)citizenInstanceId].m_lastPathOffset    = segmentOffset;
#if DEBUG
                                    if (debug)
                                    {
                                        Log._Debug($"Parking succeeded (default): Setting path of citizen instance {citizenInstanceId} to {nextPath}!");
                                    }
#endif
                                }
                            }
                        }
                    }
                    curCitizenUnitId = nextUnit;
                    if (++numIter > 524288)
                    {
                        CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                        break;
                    }
                }
            }

            if (prohibitPocketCars)
            {
                if (driverExtInstance.pathMode == ExtCitizenInstance.ExtPathMode.RequiresWalkingPathToTarget)
                {
#if DEBUG
                    if (debug)
                    {
                        Log._Debug($"Parking succeeded (alternative parking spot): Citizen instance {driverExtInstance} has to walk for the remaining path!");
                    }
#endif

                    /*driverExtInstance.CurrentPathMode = ExtCitizenInstance.PathMode.CalculatingWalkingPathToTarget;
                     * if (debug)
                     *      Log._Debug($"Setting CurrentPathMode of vehicle {vehicleID} to {driverExtInstance.CurrentPathMode}");*/
                }
            }

            return(true);
        }
Example #26
0
        // from TransportLine

        public static bool UpdateMeshData(ref TransportLine transportLine, ushort lineID)
        {
            //return transportLine.UpdateMeshData(lineID);
            bool             flag      = true;
            int              num       = 0;
            int              num2      = 0;
            int              num3      = 0;
            float            num4      = 0f;
            TransportManager instance  = Singleton <TransportManager> .instance;
            NetManager       instance2 = Singleton <NetManager> .instance;
            PathManager      instance3 = Singleton <PathManager> .instance;
            ushort           stops     = transportLine.m_stops;
            ushort           num5      = stops;
            int              num6      = 0;

            while (num5 != 0)
            {
                ushort num7 = 0;
                for (int i = 0; i < 8; i++)
                {
                    ushort segment = instance2.m_nodes.m_buffer[(int)num5].GetSegment(i);
                    if (segment != 0 && instance2.m_segments.m_buffer[(int)segment].m_startNode == num5)
                    {
                        uint path = instance2.m_segments.m_buffer[(int)segment].m_path;
                        if (path != 0u)
                        {
                            byte pathFindFlags = instance3.m_pathUnits.m_buffer[(int)((UIntPtr)path)].m_pathFindFlags;
                            if ((pathFindFlags & 4) != 0)
                            {
                                if (!TransportLine.CalculatePathSegmentCount(path, ref num2, ref num3, ref num4))
                                {
                                    TransportInfo info = transportLine.Info;
                                    BusTransportLineAI.StartPathFind(segment, ref instance2.m_segments.m_buffer[(int)segment], info.m_netService, info.m_vehicleType, (transportLine.m_flags & TransportLine.Flags.Temporary) != TransportLine.Flags.None);
                                    flag = false;
                                }
                            }
                            else if ((pathFindFlags & 8) == 0)
                            {
                                flag = false;
                            }
                        }
                        num7 = instance2.m_segments.m_buffer[(int)segment].m_endNode;
                        break;
                    }
                }
                num++;
                num2++;
                num5 = num7;
                if (num5 == stops)
                {
                    break;
                }
                if (!flag)
                {
                    break;
                }
                if (++num6 >= 32768)
                {
                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                    break;
                }
            }
            if (!flag)
            {
                return(flag);
            }
            RenderGroup.MeshData meshData = new RenderGroup.MeshData();
            meshData.m_vertices  = new Vector3[num2 * 8];
            meshData.m_normals   = new Vector3[num2 * 8];
            meshData.m_tangents  = new Vector4[num2 * 8];
            meshData.m_uvs       = new Vector2[num2 * 8];
            meshData.m_uvs1      = new Vector2[num2 * 8];
            meshData.m_colors    = new Color32[num2 * 8];
            meshData.m_triangles = new int[num2 * 30];
            TransportManager.LineSegment[] array = new TransportManager.LineSegment[num];
            Bezier3[] array2      = new Bezier3[num3];
            int       num8        = 0;
            int       num9        = 0;
            int       num10       = 0;
            float     lengthScale = Mathf.Ceil(num4 / 64f) / num4;
            float     num11       = 0f;

            num5 = stops;
            Vector3 vector  = new Vector3(100000f, 100000f, 100000f);
            Vector3 vector2 = new Vector3(-100000f, -100000f, -100000f);

            num6 = 0;
            while (num5 != 0)
            {
                ushort num12 = 0;
                for (int j = 0; j < 8; j++)
                {
                    ushort segment2 = instance2.m_nodes.m_buffer[(int)num5].GetSegment(j);
                    if (segment2 != 0 && instance2.m_segments.m_buffer[(int)segment2].m_startNode == num5)
                    {
                        uint path2 = instance2.m_segments.m_buffer[(int)segment2].m_path;
                        if (path2 != 0u && (instance3.m_pathUnits.m_buffer[(int)((UIntPtr)path2)].m_pathFindFlags & 4) != 0)
                        {
                            array[num8].m_curveStart = num10;
                            Vector3 vector3;
                            Vector3 vector4;
                            TransportLine.FillPathSegments(path2, meshData, array2, ref num9, ref num10, ref num11, lengthScale, out vector3, out vector4);
                            vector  = Vector3.Min(vector, vector3);
                            vector2 = Vector3.Max(vector2, vector4);
                            array[num8].m_bounds.SetMinMax(vector3, vector4);
                            array[num8].m_curveEnd = num10;
                        }
                        num12 = instance2.m_segments.m_buffer[(int)segment2].m_endNode;
                        break;
                    }
                }
                TransportLine.FillPathNode(instance2.m_nodes.m_buffer[(int)num5].m_position, meshData, num9);
                num8++;
                num9++;
                num5 = num12;
                if (num5 == stops)
                {
                    break;
                }
                if (++num6 >= 32768)
                {
                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                    break;
                }
            }
            while (!Monitor.TryEnter(instance.m_lineMeshData, SimulationManager.SYNCHRONIZE_TIMEOUT))
            {
            }
            try
            {
                instance.m_lineMeshData[(int)lineID] = meshData;
                instance.m_lineSegments[(int)lineID] = array;
                instance.m_lineCurves[(int)lineID]   = array2;
                transportLine.m_bounds.SetMinMax(vector, vector2);
            }
            finally
            {
                Monitor.Exit(instance.m_lineMeshData);
            }

            return(flag);
        }
        public void Update()
        {
            if (!this.m_buildingInfoPanel.isVisible)
            {
                return;
            }
            Building b = Singleton <BuildingManager> .instance.m_buildings.m_buffer[m_buildingIdSelecionado.Building];

            if (!(b.Info.GetAI() is BuildingAI basicAI))
            {
                closeBuildingInfo(null, null);
                return;
            }

            var           ssds         = ServiceSystemDefinition.from(b.Info);
            List <string> textVehicles = new List <string>();

            foreach (var ssd in ssds)
            {
                var defLevel = Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)m_buildingIdSelecionado.Building].Info.m_class.m_level;

                int count    = 0;
                int cargo    = 0;
                int capacity = 0;
                int inbound  = 0;
                int outbound = 0;
                var extstr   = SVMBuildingAIOverrideUtils.getBuildingOverrideExtensionStrict(b.Info);
                SVMBuildingUtils.CalculateOwnVehicles(m_buildingIdSelecionado.Building, ref b, extstr.GetManagedReasons(b.Info).Where(x => (x.Value.vehicleLevel ?? defLevel) == ssd.level).Select(x => x.Key), ref count, ref cargo, ref capacity, ref inbound, ref outbound);
                var    maxField       = extstr.GetVehicleMaxCountField(ssd.vehicleType, ssd.level);
                int    maxVehicles    = (SVMUtils.GetPrivateField <int>(b.Info.GetAI(), maxField) * SVMBuildingUtils.GetProductionRate(ref b) / 100);
                string maxVehiclesStr = maxField == null || maxVehicles > 0x3FFF ? "∞" : maxVehicles.ToString();
                textVehicles.Add($"{count}/{maxVehiclesStr} ({Locale.Get("SVM_VEHICLE_TYPE", ssd.vehicleType.ToString())})");
            }
            vehiclesInUseLabel.text = string.Join(" | ", textVehicles.ToArray());
            upkeepCost.text         = LocaleFormatter.FormatUpkeep(basicAI.GetResourceRate(m_buildingIdSelecionado.Building, ref Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)m_buildingIdSelecionado.Building], EconomyManager.Resource.Maintenance), false);

            uint num         = Singleton <BuildingManager> .instance.m_buildings.m_buffer[m_buildingIdSelecionado.Building].m_citizenUnits;
            int  num2        = 0;
            int  num3        = 0;
            int  unskill     = 0;
            int  oneSchool   = 0;
            int  twoSchool   = 0;
            int  threeSchool = 0;

            CitizenManager instance = Singleton <CitizenManager> .instance;

            while (num != 0u)
            {
                uint nextUnit = instance.m_units.m_buffer[(int)((UIntPtr)num)].m_nextUnit;
                if ((ushort)(instance.m_units.m_buffer[(int)((UIntPtr)num)].m_flags & CitizenUnit.Flags.Work) != 0)
                {
                    for (int i = 0; i < 5; i++)
                    {
                        uint citizen = instance.m_units.m_buffer[(int)((UIntPtr)num)].GetCitizen(i);
                        if (citizen != 0u && !instance.m_citizens.m_buffer[(int)((UIntPtr)citizen)].Dead && (instance.m_citizens.m_buffer[(int)((UIntPtr)citizen)].m_flags & Citizen.Flags.MovingIn) == Citizen.Flags.None)
                        {
                            num3++;
                            switch (instance.m_citizens.m_buffer[(int)((UIntPtr)citizen)].EducationLevel)
                            {
                            case Citizen.Education.Uneducated:
                                unskill++;
                                break;

                            case Citizen.Education.OneSchool:
                                oneSchool++;
                                break;

                            case Citizen.Education.TwoSchools:
                                twoSchool++;
                                break;

                            case Citizen.Education.ThreeSchools:
                                threeSchool++;
                                break;
                            }
                        }
                    }
                }
                num = nextUnit;
                if (++num2 > 524288)
                {
                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                    break;
                }
            }

            workerChart.SetValues(new int[] { unskill, oneSchool, twoSchool, threeSchool }, new int[] { SVMUtils.GetPrivateField <int>(basicAI, "m_workPlaceCount0"), SVMUtils.GetPrivateField <int>(basicAI, "m_workPlaceCount1"), SVMUtils.GetPrivateField <int>(basicAI, "m_workPlaceCount2"), SVMUtils.GetPrivateField <int>(basicAI, "m_workPlaceCount3") });
        }
Example #28
0
    class CustomTramBaseAI : TramBaseAI {     // TODO inherit from VehicleAI (in order to keep the correct references to `base`)
        public void CustomSimulationStep(ushort vehicleId, ref Vehicle vehicleData, Vector3 physicsLodRefPos)
        {
            if ((vehicleData.m_flags & Vehicle.Flags.WaitingPath) != 0)
            {
                byte pathFindFlags = Singleton <PathManager> .instance.m_pathUnits.m_buffer[vehicleData.m_path].m_pathFindFlags;

                if ((pathFindFlags & PathUnit.FLAG_READY) != 0)
                {
                    try {
                        this.PathfindSuccess(vehicleId, ref vehicleData);
                        this.PathFindReady(vehicleId, ref vehicleData);
                    } catch (Exception e) {
                        Log.Warning($"TramBaseAI.PathFindSuccess/PathFindReady({vehicleId}) threw an exception: {e.ToString()}");
                        vehicleData.m_flags &= ~Vehicle.Flags.WaitingPath;
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);

                        vehicleData.m_path = 0u;
                        this.PathfindFailure(vehicleId, ref vehicleData);
                        return;
                    }
                }
                else if ((pathFindFlags & PathUnit.FLAG_FAILED) != 0 || vehicleData.m_path == 0)
                {
                    vehicleData.m_flags &= ~Vehicle.Flags.WaitingPath;
                    Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);

                    vehicleData.m_path = 0u;
                    this.PathfindFailure(vehicleId, ref vehicleData);
                    return;
                }
            }
            else
            {
                if ((vehicleData.m_flags & Vehicle.Flags.WaitingSpace) != 0)
                {
                    this.TrySpawn(vehicleId, ref vehicleData);
                }
            }

            // NON-STOCK CODE START
#if BENCHMARK
            using (var bm = new Benchmark(null, "UpdateVehiclePosition")) {
#endif
            VehicleStateManager.Instance.UpdateVehiclePosition(vehicleId, ref vehicleData);
#if BENCHMARK
        }
#endif
            if (!Options.isStockLaneChangerUsed())
            {
#if BENCHMARK
                using (var bm = new Benchmark(null, "LogTraffic")) {
#endif
                // Advanced AI traffic measurement
                VehicleStateManager.Instance.LogTraffic(vehicleId);
#if BENCHMARK
            }
#endif
            }
            // NON-STOCK CODE END

            VehicleManager instance = Singleton <VehicleManager> .instance;
            VehicleInfo info        = instance.m_vehicles.m_buffer[(int)vehicleId].Info;
            info.m_vehicleAI.SimulationStep(vehicleId, ref instance.m_vehicles.m_buffer[(int)vehicleId], vehicleId, ref vehicleData, 0);
            if ((vehicleData.m_flags & (Vehicle.Flags.Created | Vehicle.Flags.Deleted)) != Vehicle.Flags.Created)
            {
                return;
            }
            ushort trailingVehicle = instance.m_vehicles.m_buffer[(int)vehicleId].m_trailingVehicle;
            int num = 0;
            while (trailingVehicle != 0)
            {
                info = instance.m_vehicles.m_buffer[(int)trailingVehicle].Info;
                info.m_vehicleAI.SimulationStep(trailingVehicle, ref instance.m_vehicles.m_buffer[(int)trailingVehicle], vehicleId, ref vehicleData, 0);
                if ((vehicleData.m_flags & (Vehicle.Flags.Created | Vehicle.Flags.Deleted)) != Vehicle.Flags.Created)
                {
                    return;
                }
                trailingVehicle = instance.m_vehicles.m_buffer[(int)trailingVehicle].m_trailingVehicle;
                if (++num > 16384)
                {
                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                    break;
                }
            }
            if ((vehicleData.m_flags & (Vehicle.Flags.Spawned | Vehicle.Flags.WaitingPath | Vehicle.Flags.WaitingSpace | Vehicle.Flags.WaitingCargo)) == 0)
            {
                Singleton <VehicleManager> .instance.ReleaseVehicle(vehicleId);
            }
            else if (vehicleData.m_blockCounter == 255)
            {
                // NON-STOCK CODE START
                bool mayDespawn = true;
#if BENCHMARK
                using (var bm = new Benchmark(null, "MayDespawn")) {
#endif
                mayDespawn = VehicleBehaviorManager.Instance.MayDespawn(ref vehicleData);
#if BENCHMARK
            }
#endif

                if (mayDespawn)
                {
                    // NON-STOCK CODE END
                    Singleton <VehicleManager> .instance.ReleaseVehicle(vehicleId);
                }                 // NON-STOCK CODE
            }
        }
    class CustomTramBaseAI : TramBaseAI {     // TODO inherit from VehicleAI (in order to keep the correct references to `base`)
        public void CustomSimulationStep(ushort vehicleId, ref Vehicle vehicleData, Vector3 physicsLodRefPos)
        {
#if USEPATHWAITCOUNTER
            VehicleState state = VehicleStateManager._GetVehicleState(vehicleId);
#endif

            if ((vehicleData.m_flags & Vehicle.Flags.WaitingPath) != 0)
            {
                byte pathFindFlags = Singleton <PathManager> .instance.m_pathUnits.m_buffer[(int)((UIntPtr)vehicleData.m_path)].m_pathFindFlags;

#if USEPATHWAITCOUNTER
                if ((pathFindFlags & (PathUnit.FLAG_READY | PathUnit.FLAG_FAILED)) != 0)
                {
                    VehicleState state = VehicleStateManager.Instance._GetVehicleState(vehicleId);
                    state.PathWaitCounter = 0;                     // NON-STOCK CODE
                }
#endif

                if ((pathFindFlags & PathUnit.FLAG_READY) != 0)
                {
                    try {
                        this.PathfindSuccess(vehicleId, ref vehicleData);
                        this.PathFindReady(vehicleId, ref vehicleData);
                    } catch (Exception e) {
                        Log.Warning($"TramBaseAI.PathFindSuccess/PathFindReady({vehicleId}) threw an exception: {e.ToString()}");
                        vehicleData.m_flags &= ~Vehicle.Flags.WaitingPath;
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);

                        vehicleData.m_path = 0u;
                        this.PathfindFailure(vehicleId, ref vehicleData);
                        return;
                    }
                }
                else if ((pathFindFlags & PathUnit.FLAG_FAILED) != 0 || vehicleData.m_path == 0)
                {
                    vehicleData.m_flags &= ~Vehicle.Flags.WaitingPath;
                    Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);

                    vehicleData.m_path = 0u;
                    this.PathfindFailure(vehicleId, ref vehicleData);
                    return;
                }
#if USEPATHWAITCOUNTER
                else
                {
                    VehicleState state = VehicleStateManager.Instance._GetVehicleState(vehicleId);
                    state.PathWaitCounter = (ushort)Math.Min(ushort.MaxValue, (int)state.PathWaitCounter + 1);                   // NON-STOCK CODE
                }
#endif
            }
            else
            {
                if ((vehicleData.m_flags & Vehicle.Flags.WaitingSpace) != 0)
                {
                    this.TrySpawn(vehicleId, ref vehicleData);
                }
            }

            /// NON-STOCK CODE START ///
            VehicleStateManager vehStateManager = VehicleStateManager.Instance;

            bool   reversed = (vehicleData.m_flags & Vehicle.Flags.Reversed) != 0;
            ushort frontVehicleId;
            if (reversed)
            {
                frontVehicleId = vehicleData.GetLastVehicle(vehicleId);
            }
            else
            {
                frontVehicleId = vehicleId;
            }

            if (Options.prioritySignsEnabled || Options.timedLightsEnabled)
            {
                try {
                    vehStateManager.UpdateVehiclePos(frontVehicleId, ref Singleton <VehicleManager> .instance.m_vehicles.m_buffer[frontVehicleId]);
                } catch (Exception e) {
                    Log.Error("TramAI CustomSimulationStep (2) Error: " + e.ToString());
                }
            }

            if (!Options.isStockLaneChangerUsed())
            {
                try {
                    //Log._Debug($"HandleVehicle for trams. vehicleId={vehicleId} frontVehicleId={frontVehicleId}");
                    vehStateManager.LogTraffic(frontVehicleId, ref Singleton <VehicleManager> .instance.m_vehicles.m_buffer[frontVehicleId], true);
                } catch (Exception e) {
                    Log.Error("TramAI CustomSimulationStep (1) Error: " + e.ToString());
                }
            }
            /// NON-STOCK CODE END ///

            VehicleManager instance = Singleton <VehicleManager> .instance;
            VehicleInfo    info     = instance.m_vehicles.m_buffer[(int)vehicleId].Info;
            info.m_vehicleAI.SimulationStep(vehicleId, ref instance.m_vehicles.m_buffer[(int)vehicleId], vehicleId, ref vehicleData, 0);
            if ((vehicleData.m_flags & (Vehicle.Flags.Created | Vehicle.Flags.Deleted)) != Vehicle.Flags.Created)
            {
                return;
            }
            ushort trailingVehicle = instance.m_vehicles.m_buffer[(int)vehicleId].m_trailingVehicle;
            int    num             = 0;
            while (trailingVehicle != 0)
            {
                info = instance.m_vehicles.m_buffer[(int)trailingVehicle].Info;
                info.m_vehicleAI.SimulationStep(trailingVehicle, ref instance.m_vehicles.m_buffer[(int)trailingVehicle], vehicleId, ref vehicleData, 0);
                if ((vehicleData.m_flags & (Vehicle.Flags.Created | Vehicle.Flags.Deleted)) != Vehicle.Flags.Created)
                {
                    return;
                }
                trailingVehicle = instance.m_vehicles.m_buffer[(int)trailingVehicle].m_trailingVehicle;
                if (++num > 16384)
                {
                    CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                    break;
                }
            }
            if ((vehicleData.m_flags & (Vehicle.Flags.Spawned | Vehicle.Flags.WaitingPath | Vehicle.Flags.WaitingSpace | Vehicle.Flags.WaitingCargo)) == 0 || vehicleData.m_blockCounter == 255)
            {
                Singleton <VehicleManager> .instance.ReleaseVehicle(vehicleId);
            }
        }
Example #30
0
        private static void ApplyZoning(ZoneTool z)
        {
            Vector3 m_startPosition  = (Vector3)z.GetType().GetField("m_startPosition", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(z);
            Vector3 m_mousePosition  = (Vector3)z.GetType().GetField("m_mousePosition", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(z);
            Vector3 m_startDirection = (Vector3)z.GetType().GetField("m_startDirection", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(z);

            Vector2 vector2_1 = VectorUtils.XZ(m_startPosition);
            Vector2 vector2_2 = VectorUtils.XZ(m_mousePosition);
            Vector2 vector2_3 = VectorUtils.XZ(m_startDirection);
            Vector2 vector2_4 = new Vector2(vector2_3.y, -vector2_3.x);
            float   num1      = Mathf.Round((float)((((double)vector2_2.x - (double)vector2_1.x) * (double)vector2_3.x + ((double)vector2_2.y - (double)vector2_1.y) * (double)vector2_3.y) * 0.125)) * 8f;
            float   num2      = Mathf.Round((float)((((double)vector2_2.x - (double)vector2_1.x) * (double)vector2_4.x + ((double)vector2_2.y - (double)vector2_1.y) * (double)vector2_4.y) * 0.125)) * 8f;
            float   num3      = (double)num1 < 0.0 ? -4f : 4f;
            float   num4      = (double)num2 < 0.0 ? -4f : 4f;
            Quad2   quad2     = new Quad2();

            quad2.a = vector2_1 - vector2_3 * num3 - vector2_4 * num4;
            quad2.b = vector2_1 - vector2_3 * num3 + vector2_4 * (num2 + num4);
            quad2.c = vector2_1 + vector2_3 * (num1 + num3) + vector2_4 * (num2 + num4);
            quad2.d = vector2_1 + vector2_3 * (num1 + num3) - vector2_4 * num4;
            if ((double)num3 == (double)num4)
            {
                Vector2 vector2_5 = quad2.b;
                quad2.b = quad2.d;
                quad2.d = vector2_5;
            }
            Vector2 vector2_6 = quad2.Min();
            Vector2 vector2_7 = quad2.Max();
            int     num5      = Mathf.Max((int)((vector2_6.x - 46f) / 64f + FakeZoneManager.HALFGRID), 0);
            int     num6      = Mathf.Max((int)((vector2_6.y - 46f) / 64f + FakeZoneManager.HALFGRID), 0);
            int     num7      = Mathf.Min((int)((vector2_7.x + 46f) / 64f + FakeZoneManager.HALFGRID), FakeZoneManager.GRIDSIZE - 1);
            int     num8      = Mathf.Min((int)((vector2_7.y + 46f) / 64f + FakeZoneManager.HALFGRID), FakeZoneManager.GRIDSIZE - 1);
            var     instance1 = ZoneManager.instance;
            bool    flag      = false;

            for (int index1 = num6; index1 <= num8; ++index1)
            {
                for (int index2 = num5; index2 <= num7; ++index2)
                {
                    ushort blockIndex = instance1.m_zoneGrid[index1 * FakeZoneManager.GRIDSIZE + index2];
                    int    num9       = 0;
                    while ((int)blockIndex != 0)
                    {
                        Vector3 vector3 = instance1.m_blocks.m_buffer[(int)blockIndex].m_position;
                        if ((double)Mathf.Max(Mathf.Max(vector2_6.x - 46f - vector3.x, vector2_6.y - 46f - vector3.z), Mathf.Max((float)((double)vector3.x - (double)vector2_7.x - 46.0), (float)((double)vector3.z - (double)vector2_7.y - 46.0))) < 0.0 && ApplyZoning(z, blockIndex, ref instance1.m_blocks.m_buffer[(int)blockIndex], quad2))
                        {
                            flag = true;
                        }
                        blockIndex = instance1.m_blocks.m_buffer[(int)blockIndex].m_nextGridBlock;
                        if (++num9 >= ZoneManager.MAX_BLOCK_COUNT)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + System.Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
            if (!flag)
            {
                return;
            }
            bool m_zoning = (bool)z.GetType().GetField("m_validPosition", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(z);

            if (m_zoning)
            {
                UsedZone(z, z.m_zone);
            }
            EffectInfo effect = instance1.m_properties.m_fillEffect;

            if (effect == null)
            {
                return;
            }
            InstanceID instance2 = new InstanceID();

            EffectInfo.SpawnArea spawnArea = new EffectInfo.SpawnArea((Vector3)((vector2_1 + vector2_2) * 0.5f), Vector3.up, 1f);
            Singleton <EffectManager> .instance.DispatchEffect(effect, instance2, spawnArea, Vector3.zero, 0.0f, 1f, Singleton <AudioManager> .instance.DefaultGroup);
        }