Beispiel #1
0
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays)
        {
#if DEBUG
            //Log._Debug($"CustomShipAI.CustomStartPathFind called for vehicle {vehicleID}");
#endif

            /// NON-STOCK CODE START ///
            ExtVehicleType vehicleType = VehicleStateManager.Instance._GetVehicleState(vehicleID).VehicleType;
            if (vehicleType == ExtVehicleType.None)
            {
#if DEBUG
                Log.Warning($"CustomShipAI.CustomStartPathFind: Vehicle {vehicleID} does not have a valid vehicle type!");
#endif
                vehicleType = ExtVehicleType.Ship;
            }
            else if (vehicleType == ExtVehicleType.CargoShip)
            {
                vehicleType = ExtVehicleType.CargoVehicle;
            }
            /// NON-STOCK CODE END ///

            VehicleInfo       info = this.m_info;
            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             startSqrDistA;
            float             startSqrDistB;
            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float             endSqrDistA;
            float             endSqrDistB;
            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.PublicTransport, NetInfo.LaneType.Vehicle, info.m_vehicleType, false, false, 64f, out startPosA, out startPosB, out startSqrDistA, out startSqrDistB) &&
                CustomPathManager.FindPathPosition(endPos, ItemClass.Service.PublicTransport, NetInfo.LaneType.Vehicle, info.m_vehicleType, false, false, 64f, out endPosA, out endPosB, out endSqrDistA, out endSqrDistB))
            {
                if (!startBothWays || startSqrDistA < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                if (!endBothWays || endSqrDistA < 10f)
                {
                    endPosB = default(PathUnit.Position);
                }
                uint path;
                if (CustomPathManager._instance.CreatePath((ExtVehicleType)vehicleType, vehicleID, ExtCitizenInstance.ExtPathType.None, out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, NetInfo.LaneType.Vehicle, info.m_vehicleType, 20000f))
                {
#if USEPATHWAITCOUNTER
                    VehicleState state = VehicleStateManager.Instance._GetVehicleState(vehicleID);
                    state.PathWaitCounter = 0;
#endif

                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, bool undergroundTarget)
        {
#if PATHRECALC
            VehicleState state           = VehicleStateManager._GetVehicleState(vehicleID);
            bool         recalcRequested = state.PathRecalculationRequested;
            state.PathRecalculationRequested = false;
#endif

            VehicleInfo info           = this.m_info;
            ushort      driverInstance = CustomPassengerCarAI.GetDriverInstance(vehicleID, ref vehicleData);
            if (driverInstance == 0)
            {
                return(false);
            }
            CitizenManager          instance    = Singleton <CitizenManager> .instance;
            CitizenInfo             info2       = instance.m_instances.m_buffer[(int)driverInstance].Info;
            NetInfo.LaneType        laneTypes   = NetInfo.LaneType.Vehicle | NetInfo.LaneType.Pedestrian;
            VehicleInfo.VehicleType vehicleType = this.m_info.m_vehicleType;
            bool   allowUnderground             = (vehicleData.m_flags & Vehicle.Flags.Underground) != 0;
            bool   randomParking  = false;
            ushort targetBuilding = instance.m_instances.m_buffer[(int)driverInstance].m_targetBuilding;
            if (targetBuilding != 0 && Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)targetBuilding].Info.m_class.m_service > ItemClass.Service.Office)
            {
                randomParking = true;
            }
            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             num;
            float             num2;
            PathUnit.Position endPosA;
            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out num, out num2) &&
                info2.m_citizenAI.FindPathPosition(driverInstance, ref instance.m_instances.m_buffer[(int)driverInstance], endPos, laneTypes, vehicleType, undergroundTarget, out endPosA))
            {
                if (!startBothWays || num < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                PathUnit.Position endPosB   = default(PathUnit.Position);
                SimulationManager instance2 = Singleton <SimulationManager> .instance;
                uint path;
                PathUnit.Position def = default(PathUnit.Position);
                if (Singleton <CustomPathManager> .instance.CreatePath(
#if PATHRECALC
                        recalcRequested
#else
                        false
#endif
                        , ExtVehicleType.PassengerCar, out path, ref instance2.m_randomizer, instance2.m_currentBuildIndex, ref startPosA, ref startPosB, ref endPosA, ref endPosB, ref def, laneTypes, vehicleType, 20000f, false, false, false, false, randomParking))
                {
                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
Beispiel #3
0
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, bool undergroundTarget)
        {
#if DEBUG
            //Log._Debug($"CustomPoliceCarAI.CustomStartPathFind called for vehicle {vehicleID}");
#endif

#if PATHRECALC
            VehicleState state           = VehicleStateManager._GetVehicleState(vehicleID);
            bool         recalcRequested = state.PathRecalculationRequested;
            state.PathRecalculationRequested = false;
#endif
            ExtVehicleType vehicleType = (vehicleData.m_flags & Vehicle.Flags.Emergency2) != 0 ? ExtVehicleType.Emergency : ExtVehicleType.Service;
            VehicleStateManager.Instance._GetVehicleState(vehicleID).VehicleType = vehicleType;

            VehicleInfo       info             = this.m_info;
            bool              allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0;
            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             startDistSqrA;
            float             startDistSqrB;
            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float             endDistSqrA;
            float             endDistSqrB;
            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out startDistSqrA, out startDistSqrB) &&
                CustomPathManager.FindPathPosition(endPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, undergroundTarget, false, 32f, out endPosA, out endPosB, out endDistSqrA, out endDistSqrB))
            {
                if (!startBothWays || startDistSqrA < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                if (!endBothWays || endDistSqrA < 10f)
                {
                    endPosB = default(PathUnit.Position);
                }
                uint path;
                //Log._Debug($"CustomPoliceCarAI.CustomStartPathFind: Vehicle {vehicleID}, type {vehicleType}");
                if (CustomPathManager._instance.CreatePath(
#if PATHRECALC
                        recalcRequested,
#endif
                        vehicleType, vehicleID, ExtCitizenInstance.ExtPathType.None, out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, 20000f, this.IsHeavyVehicle(), this.IgnoreBlocked(vehicleID, ref vehicleData), false, false))
                {
#if USEPATHWAITCOUNTER
                    VehicleState state = VehicleStateManager.Instance._GetVehicleState(vehicleID);
                    state.PathWaitCounter = 0;
#endif

                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
Beispiel #4
0
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, bool undergroundTarget)
        {
            ExtVehicleType?vehicleType = CustomVehicleAI.DetermineVehicleTypeFromVehicle(vehicleID, ref vehicleData);

            /*if (vehicleType == null) {
             *      Log._Debug($"CustomCarAI.CustomStartPathFind: Could not determine ExtVehicleType from class type. typeof this={this.GetType().ToString()}");
             * } else {
             *      Log._Debug($"CustomCarAI.CustomStartPathFind: vehicleType={vehicleType}. typeof this={this.GetType().ToString()}");
             * }*/

            VehicleInfo info             = this.m_info;
            bool        allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0;

            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             num;
            float             num2;

            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float             num3;
            float             num4;

            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out num, out num2) &&
                CustomPathManager.FindPathPosition(endPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, undergroundTarget, false, 32f, out endPosA, out endPosB, out num3, out num4))
            {
                if (!startBothWays || num < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                if (!endBothWays || num3 < 10f)
                {
                    endPosB = default(PathUnit.Position);
                }
                uint path;
                bool res = false;
                if (vehicleType == null)
                {
                    res = Singleton <CustomPathManager> .instance.CreatePath(out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, NetInfo.LaneType.Vehicle, info.m_vehicleType, 20000f, this.IsHeavyVehicle(), this.IgnoreBlocked(vehicleID, ref vehicleData), false, false);
                }
                else
                {
                    res = Singleton <CustomPathManager> .instance.CreatePath((ExtVehicleType)vehicleType, out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, NetInfo.LaneType.Vehicle, info.m_vehicleType, 20000f, this.IsHeavyVehicle(), this.IgnoreBlocked(vehicleID, ref vehicleData), false, false);
                }
                if (res)
                {
                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays)
        {
#if DEBUG
            //Log._Debug($"CustomTramBaseAI.CustomStartPathFind called for vehicle {vehicleID}");
#endif

            VehicleInfo info = this.m_info;
            bool        allowUnderground;
            bool        allowUnderground2;
            if (info.m_vehicleType == VehicleInfo.VehicleType.Metro)
            {
                allowUnderground  = true;
                allowUnderground2 = true;
            }
            else
            {
                allowUnderground  = ((vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0);
                allowUnderground2 = false;
            }
            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             startSqrDistA;
            float             startSqrDistB;
            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float             endSqrDistA;
            float             endSqrDistB;
            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out startSqrDistA, out startSqrDistB) &&
                CustomPathManager.FindPathPosition(endPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle, info.m_vehicleType, allowUnderground2, false, 32f, out endPosA, out endPosB, out endSqrDistA, out endSqrDistB))
            {
                if (!startBothWays || startSqrDistB > startSqrDistA * 1.2f)
                {
                    startPosB = default(PathUnit.Position);
                }
                if (!endBothWays || endSqrDistB > endSqrDistA * 1.2f)
                {
                    endPosB = default(PathUnit.Position);
                }
                uint path;
                if (CustomPathManager._instance.CreatePath(ExtVehicleType.Tram, vehicleID, ExtCitizenInstance.ExtPathType.None, out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, NetInfo.LaneType.Vehicle, info.m_vehicleType, 20000f, false, false, true, false))
                {
#if USEPATHWAITCOUNTER
                    VehicleState state = VehicleStateManager.Instance._GetVehicleState(vehicleID);
                    state.PathWaitCounter = 0;
#endif

                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
        public static bool BaseCustomStartPathFind(bool heavyVehicle, bool ignoreBlocked, ref VehicleInfo info, ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays)
        {
#if PATHRECALC
            VehicleState state           = VehicleStateManager._GetVehicleState(vehicleID);
            bool         recalcRequested = state.PathRecalculationRequested;
            state.PathRecalculationRequested = false;
#endif

            bool allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0;
            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             num;
            float             num2;
            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float             num3;
            float             num4;
            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out num, out num2) &&
                CustomPathManager.FindPathPosition(endPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, false, false, 32f, out endPosA, out endPosB, out num3, out num4))
            {
                if (!startBothWays || num < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                if (!endBothWays || num3 < 10f)
                {
                    endPosB = default(PathUnit.Position);
                }
                uint           path;
                ExtVehicleType?extVehicleType = VehicleStateManager.DetermineVehicleType(vehicleID, ref vehicleData);
                bool           res            = false;
                if (extVehicleType == null)
                {
                    res = Singleton <PathManager> .instance.CreatePath(out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, NetInfo.LaneType.Vehicle, info.m_vehicleType, 20000f, heavyVehicle, ignoreBlocked, false, false);
                }
                else
                {
                    res = Singleton <CustomPathManager> .instance.CreatePath(
#if PATHRECALC
                        recalcRequested,
#endif
                        (ExtVehicleType)extVehicleType, out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, ref startPosA, ref startPosB, ref endPosA, ref endPosB, NetInfo.LaneType.Vehicle, info.m_vehicleType, 20000f, heavyVehicle, ignoreBlocked, false, false);
                }
                if (res)
                {
                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, bool undergroundTarget)
        {
#if DEBUG
            //Log._Debug($"CustomTaxiAI.CustomStartPathFind called for vehicle {vehicleID}");
#endif

            CitizenManager instance            = Singleton <CitizenManager> .instance;
            ushort         passengerInstanceId = CustomTaxiAI.GetPassengerInstance(vehicleID, ref vehicleData);
            if (passengerInstanceId == 0 || (instance.m_instances.m_buffer[(int)passengerInstanceId].m_flags & CitizenInstance.Flags.Character) != CitizenInstance.Flags.None)
            {
                return(base.StartPathFind(vehicleID, ref vehicleData, startPos, endPos, startBothWays, endBothWays, undergroundTarget));
            }
            VehicleInfo             info        = this.m_info;
            CitizenInfo             info2       = instance.m_instances.m_buffer[(int)passengerInstanceId].Info;
            NetInfo.LaneType        laneTypes   = NetInfo.LaneType.Vehicle | NetInfo.LaneType.Pedestrian | NetInfo.LaneType.TransportVehicle;
            VehicleInfo.VehicleType vehicleType = this.m_info.m_vehicleType;
            bool allowUnderground = (vehicleData.m_flags & Vehicle.Flags.Underground) != 0;
            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             startSqrDistA;
            float             startSqrDistB;
            PathUnit.Position endPosA;
            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out startSqrDistA, out startSqrDistB) &&
                info2.m_citizenAI.FindPathPosition(passengerInstanceId, ref instance.m_instances.m_buffer[(int)passengerInstanceId], endPos, laneTypes, vehicleType, undergroundTarget, out endPosA))
            {
                if ((instance.m_instances.m_buffer[(int)passengerInstanceId].m_flags & CitizenInstance.Flags.CannotUseTransport) == CitizenInstance.Flags.None)
                {
                    laneTypes |= NetInfo.LaneType.PublicTransport;

                    uint citizenId = instance.m_instances.m_buffer[passengerInstanceId].m_citizen;
                    if (citizenId != 0u && (instance.m_citizens.m_buffer[citizenId].m_flags & Citizen.Flags.Evacuating) != Citizen.Flags.None)
                    {
                        laneTypes |= NetInfo.LaneType.EvacuationTransport;
                    }
                }
                if (!startBothWays || startSqrDistA < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                PathUnit.Position endPosB   = default(PathUnit.Position);
                SimulationManager instance2 = Singleton <SimulationManager> .instance;
                uint path;
                if (CustomPathManager._instance.CreatePath(
                        ExtVehicleType.Taxi, vehicleID, 0, out path, ref instance2.m_randomizer, instance2.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, laneTypes, vehicleType, 20000f, IsHeavyVehicle(), IgnoreBlocked(vehicleID, ref vehicleData), false, (vehicleData.m_flags & Vehicle.Flags.Spawned) != 0))
                {
                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
        /// <summary>
        /// Starts path-finding of the walking path from parking position <paramref name="parkPos"/> to target position <paramref name="targetPos"/>.
        /// </summary>
        /// <param name="parkPos">Parking position</param>
        /// <param name="targetPos">Target position</param>
        /// <returns></returns>
        internal bool CalculateReturnPath(Vector3 parkPos, Vector3 targetPos)
        {
            ReleaseReturnPath();

            PathUnit.Position parkPathPos;
            PathUnit.Position targetPathPos;
            if (CustomPathManager.FindPathPositionWithSpiralLoop(parkPos, ItemClass.Service.Road, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, false, false, GlobalConfig.Instance.ParkingAI.MaxBuildingToPedestrianLaneDistance, out parkPathPos) &&
                CustomPathManager.FindPathPositionWithSpiralLoop(targetPos, ItemClass.Service.Road, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, false, false, GlobalConfig.Instance.ParkingAI.MaxBuildingToPedestrianLaneDistance, out targetPathPos))
            {
                PathUnit.Position dummyPathPos = default(PathUnit.Position);
                uint             pathId;
                PathCreationArgs args;
                args.extPathType         = ExtCitizenInstance.ExtPathType.WalkingOnly;
                args.extVehicleType      = ExtVehicleType.None;
                args.vehicleId           = 0;
                args.buildIndex          = Singleton <SimulationManager> .instance.m_currentBuildIndex;
                args.startPosA           = parkPathPos;
                args.startPosB           = dummyPathPos;
                args.endPosA             = targetPathPos;
                args.endPosB             = dummyPathPos;
                args.vehiclePosition     = dummyPathPos;
                args.laneTypes           = NetInfo.LaneType.Pedestrian;
                args.vehicleTypes        = VehicleInfo.VehicleType.None;
                args.maxLength           = 20000f;
                args.isHeavyVehicle      = false;
                args.hasCombustionEngine = false;
                args.ignoreBlocked       = false;
                args.ignoreFlooded       = false;
                args.randomParking       = false;
                args.stablePath          = false;
                args.skipQueue           = false;

                if (CustomPathManager._instance.CreatePath(out pathId, ref Singleton <SimulationManager> .instance.m_randomizer, args))
                {
#if DEBUG
                    if (GlobalConfig.Instance.Debug.Switches[2])
                    {
                        Log._Debug($"ExtCitizenInstance.CalculateReturnPath: Path-finding starts for return path of citizen instance {instanceId}, path={pathId}, parkPathPos.segment={parkPathPos.m_segment}, parkPathPos.lane={parkPathPos.m_lane}, targetPathPos.segment={targetPathPos.m_segment}, targetPathPos.lane={targetPathPos.m_lane}");
                    }
#endif

                    returnPathId    = pathId;
                    returnPathState = ExtPathState.Calculating;
                    return(true);
                }
            }

#if DEBUG
            if (GlobalConfig.Instance.Debug.Switches[2])
            {
                Log._Debug($"ExtCitizenInstance.CalculateReturnPath: Could not find path position(s) for either the parking position or target position of citizen instance {instanceId}.");
            }
#endif

            return(false);
        }
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, bool undergroundTarget)
        {
#if PATHRECALC
            VehicleState state           = VehicleStateManager._GetVehicleState(vehicleID);
            bool         recalcRequested = state.PathRecalculationRequested;
            state.PathRecalculationRequested = false;
#endif

            CitizenManager instance          = Singleton <CitizenManager> .instance;
            ushort         passengerInstance = CustomTaxiAI.GetPassengerInstance(vehicleID, ref vehicleData);
            if (passengerInstance == 0 || (instance.m_instances.m_buffer[(int)passengerInstance].m_flags & CitizenInstance.Flags.Character) != CitizenInstance.Flags.None)
            {
                return(base.StartPathFind(vehicleID, ref vehicleData, startPos, endPos, startBothWays, endBothWays, undergroundTarget));
            }
            VehicleInfo             info        = this.m_info;
            CitizenInfo             info2       = instance.m_instances.m_buffer[(int)passengerInstance].Info;
            NetInfo.LaneType        laneType    = NetInfo.LaneType.Vehicle | NetInfo.LaneType.Pedestrian | NetInfo.LaneType.TransportVehicle;
            VehicleInfo.VehicleType vehicleType = this.m_info.m_vehicleType;
            bool allowUnderground = (vehicleData.m_flags & Vehicle.Flags.Underground) != 0;
            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             num;
            float             num2;
            PathUnit.Position endPosA;
            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out num, out num2) &&
                info2.m_citizenAI.FindPathPosition(passengerInstance, ref instance.m_instances.m_buffer[(int)passengerInstance], endPos, laneType, vehicleType, undergroundTarget, out endPosA))
            {
                if ((instance.m_instances.m_buffer[(int)passengerInstance].m_flags & CitizenInstance.Flags.CannotUseTransport) == CitizenInstance.Flags.None)
                {
                    laneType |= NetInfo.LaneType.PublicTransport;
                }
                if (!startBothWays || num < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                PathUnit.Position endPosB   = default(PathUnit.Position);
                SimulationManager instance2 = Singleton <SimulationManager> .instance;
                uint path;
                if (Singleton <CustomPathManager> .instance.CreatePath(
#if PATHRECALC
                        recalcRequested,
#endif
                        ExtVehicleType.Taxi, out path, ref instance2.m_randomizer, instance2.m_currentBuildIndex, ref startPosA, ref startPosB, ref endPosA, ref endPosB, laneType, vehicleType, 20000f))
                {
                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, bool undergroundTarget)
        {
#if DEBUG
            //Log._Debug($"CustomAmbulanceAI.CustomStartPathFind called for vehicle {vehicleID}");
#endif

            ExtVehicleType vehicleType = VehicleStateManager.Instance.OnStartPathFind(vehicleID, ref vehicleData, (vehicleData.m_flags & Vehicle.Flags.Emergency2) != 0 ? ExtVehicleType.Emergency : ExtVehicleType.Service);

            VehicleInfo       info             = this.m_info;
            bool              allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0;
            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             startDistSqrA;
            float             startDistSqrB;
            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float             endDistSqrA;
            float             endDistSqrB;
            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out startDistSqrA, out startDistSqrB) &&
                CustomPathManager.FindPathPosition(endPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, undergroundTarget, false, 32f, out endPosA, out endPosB, out endDistSqrA, out endDistSqrB))
            {
                if (!startBothWays || startDistSqrA < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                if (!endBothWays || endDistSqrA < 10f)
                {
                    endPosB = default(PathUnit.Position);
                }
                uint path;
                // NON-STOCK CODE START
                if (CustomPathManager._instance.CreatePath(vehicleType, vehicleID, ExtCitizenInstance.ExtPathType.None, out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, 20000f, this.IsHeavyVehicle(), this.IgnoreBlocked(vehicleID, ref vehicleData), false, (vehicleData.m_flags & Vehicle.Flags.Spawned) != 0))
                {
                    // NON-STOCK CODE END
                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            else
            {
                PathfindFailure(vehicleID, ref vehicleData);
            }
            return(false);
        }
Beispiel #11
0
        internal void Load()
        {
            try {
                Log.Info($"TMPELifecycle.Load() called. Mode={Mode}, UpdateMode={UpdateMode}, Scene={Scene}");

                if (Scene == "ThemeEditor")
                {
                    return;
                }

                IsGameLoaded = false;

                InGameUtil.Instantiate();

                VersionUtil.CheckGameVersion();

                IsGameLoaded = true;

                CustomPathManager.OnLevelLoaded();

                ModUI.OnLevelLoaded();
                if (PlayMode)
                {
                    UIView uiView = UIView.GetAView();
                    uiView.AddUIComponent(typeof(UITransportDemand));
                    uiView.gameObject.AddComponent <RemoveVehicleButtonExtender>();
                    uiView.gameObject.AddComponent <RemoveCitizenInstanceButtonExtender>();
                    uiView.gameObject.AddComponent <RoadSelectionPanels>();
                }

                Patcher.Install();

                Log.Info("Notifying managers...");
                foreach (ICustomManager manager in RegisteredManagers)
                {
                    Log.Info($"OnLevelLoading: {manager.GetType().Name}");
                    manager.OnLevelLoading();
                }

                // must be subscribed last to notify other mods about TMPE changes
                // after all TMPE rules are applied.
                GeometryNotifierDisposable = GeometryManager.Instance.Subscribe(new GeometryNotifier());
                Notifier.Instance.OnLevelLoaded();
                Log.Info("OnLevelLoaded complete.");
            } catch (Exception ex) {
                ex.LogException(true);
            }
        }
Beispiel #12
0
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, bool undergroundTarget)
        {
#if PATHRECALC
            VehicleState state           = VehicleStateManager._GetVehicleState(vehicleID);
            bool         recalcRequested = state.PathRecalculationRequested;
            state.PathRecalculationRequested = false;
#endif

            VehicleInfo       info             = this.m_info;
            bool              allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0;
            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             num;
            float             num2;
            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float             num3;
            float             num4;
            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out num, out num2) &&
                CustomPathManager.FindPathPosition(endPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, undergroundTarget, false, 32f, out endPosA, out endPosB, out num3, out num4))
            {
                if (!startBothWays || num < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                if (!endBothWays || num3 < 10f)
                {
                    endPosB = default(PathUnit.Position);
                }
                uint path;
                if (Singleton <CustomPathManager> .instance.CreatePath(
#if PATHRECALC
                        recalcRequested,
#endif
                        (vehicleData.m_flags & Vehicle.Flags.Emergency2) != 0 ? ExtVehicleType.Emergency : ExtVehicleType.Service, out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, ref startPosA, ref startPosB, ref endPosA, ref endPosB, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, 20000f, this.IsHeavyVehicle(), this.IgnoreBlocked(vehicleID, ref vehicleData), false, false))
                {
                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
Beispiel #13
0
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, bool undergroundTarget)
        {
            VehicleInfo info           = this.m_info;
            ushort      driverInstance = CustomPassengerCarAI.GetDriverInstance(vehicleID, ref vehicleData);

            if (driverInstance == 0)
            {
                return(false);
            }
            CitizenManager instance = Singleton <CitizenManager> .instance;
            CitizenInfo    info2    = instance.m_instances.m_buffer[(int)driverInstance].Info;

            NetInfo.LaneType        laneTypes   = NetInfo.LaneType.Vehicle | NetInfo.LaneType.Pedestrian;
            VehicleInfo.VehicleType vehicleType = this.m_info.m_vehicleType;
            bool allowUnderground = (vehicleData.m_flags & Vehicle.Flags.Underground) != Vehicle.Flags.None;

            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             num;
            float             num2;

            PathUnit.Position endPosA;
            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out num, out num2) &&
                info2.m_citizenAI.FindPathPosition(driverInstance, ref instance.m_instances.m_buffer[(int)driverInstance], endPos, laneTypes, vehicleType, undergroundTarget, out endPosA))
            {
                if (!startBothWays || num < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                PathUnit.Position endPosB   = default(PathUnit.Position);
                SimulationManager instance2 = Singleton <SimulationManager> .instance;
                uint path;
                if (Singleton <CustomPathManager> .instance.CreatePath(ExtVehicleType.PassengerCar, out path, ref instance2.m_randomizer, instance2.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, laneTypes, vehicleType, 20000f))
                {
                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
        /// <summary>
        /// Starts path-finding of the walking path from parking position <paramref name="parkPos"/> to target position <paramref name="targetPos"/>.
        /// </summary>
        /// <param name="parkPos">Parking position</param>
        /// <param name="targetPos">Target position</param>
        /// <returns></returns>
        internal bool CalculateReturnPath(Vector3 parkPos, Vector3 targetPos)
        {
            ReleaseReturnPath();

            PathUnit.Position parkPathPos;
            PathUnit.Position targetPathPos;
            if (CustomPathManager.FindPathPositionWithSpiralLoop(parkPos, ItemClass.Service.Road, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, false, false, GlobalConfig.Instance.MaxBuildingToPedestrianLaneDistance, out parkPathPos) &&
                CustomPathManager.FindPathPositionWithSpiralLoop(targetPos, ItemClass.Service.Road, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, false, false, GlobalConfig.Instance.MaxBuildingToPedestrianLaneDistance, out targetPathPos))
            {
                PathUnit.Position dummyPathPos = default(PathUnit.Position);
                uint pathId;

                if (CustomPathManager._instance.CreatePath(false, ExtVehicleType.None, 0, ExtCitizenInstance.ExtPathType.WalkingOnly, out pathId, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, parkPathPos, dummyPathPos, targetPathPos, dummyPathPos, dummyPathPos, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, 20000f, false, false, false, false, false, false))
                {
#if DEBUG
                    if (GlobalConfig.Instance.DebugSwitches[2])
                    {
                        Log._Debug($"ExtCitizenInstance.CalculateReturnPath: Path-finding starts for return path of citizen instance {InstanceId}, path={pathId}, parkPathPos.segment={parkPathPos.m_segment}, parkPathPos.lane={parkPathPos.m_lane}, targetPathPos.segment={targetPathPos.m_segment}, targetPathPos.lane={targetPathPos.m_lane}");
                    }
#endif

                    ReturnPathId    = pathId;
                    ReturnPathState = ExtPathState.Calculating;
                    return(true);
                }
            }

#if DEBUG
            if (GlobalConfig.Instance.DebugSwitches[2])
            {
                Log._Debug($"ExtCitizenInstance.CalculateReturnPath: Could not find path position(s) for either the parking position or target position of citizen instance {InstanceId}.");
            }
#endif

            return(false);
        }
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays)
        {
#if DEBUG
            //Log._Debug($"CustomShipAI.CustomStartPathFind called for vehicle {vehicleID}");
#endif

            /// NON-STOCK CODE START ///
            ExtVehicleType vehicleType = ExtVehicleType.None;
#if BENCHMARK
            using (var bm = new Benchmark(null, "vehicleType")) {
#endif
            vehicleType = vehicleData.Info.m_vehicleAI is PassengerShipAI ? ExtVehicleType.PassengerShip : ExtVehicleType.CargoVehicle;
#if BENCHMARK
        }
#endif
            /// NON-STOCK CODE END ///

            VehicleInfo info = this.m_info;
            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float startSqrDistA;
            float startSqrDistB;
            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float endSqrDistA;
            float endSqrDistB;
            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.PublicTransport, NetInfo.LaneType.Vehicle, info.m_vehicleType, false, false, 64f, out startPosA, out startPosB, out startSqrDistA, out startSqrDistB) &&
                CustomPathManager.FindPathPosition(endPos, ItemClass.Service.PublicTransport, NetInfo.LaneType.Vehicle, info.m_vehicleType, false, false, 64f, out endPosA, out endPosB, out endSqrDistA, out endSqrDistB))
            {
                if (!startBothWays || startSqrDistA < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                if (!endBothWays || endSqrDistA < 10f)
                {
                    endPosB = default(PathUnit.Position);
                }
                uint path;
                // NON-STOCK CODE START
                PathCreationArgs args;
                args.extPathType         = ExtCitizenInstance.ExtPathType.None;
                args.extVehicleType      = vehicleType;
                args.vehicleId           = vehicleID;
                args.buildIndex          = Singleton <SimulationManager> .instance.m_currentBuildIndex;
                args.startPosA           = startPosA;
                args.startPosB           = startPosB;
                args.endPosA             = endPosA;
                args.endPosB             = endPosB;
                args.vehiclePosition     = default(PathUnit.Position);
                args.laneTypes           = NetInfo.LaneType.Vehicle;
                args.vehicleTypes        = info.m_vehicleType;
                args.maxLength           = 20000f;
                args.isHeavyVehicle      = false;
                args.hasCombustionEngine = false;
                args.ignoreBlocked       = false;
                args.ignoreFlooded       = false;
                args.ignoreCosts         = false;
                args.randomParking       = false;
                args.stablePath          = false;
                args.skipQueue           = false;

                if (CustomPathManager._instance.CreatePath(out path, ref Singleton <SimulationManager> .instance.m_randomizer, args))
                {
                    // NON-STOCK CODE END

                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
Beispiel #16
0
    class CustomTransportLineAI : TransportLineAI {     // TODO inherit from NetAI (in order to keep the correct references to `base`)
        public static bool CustomStartPathFind(ushort segmentID, ref NetSegment data, ItemClass.Service netService, ItemClass.Service netService2, VehicleInfo.VehicleType vehicleType, bool skipQueue)
        {
            if (data.m_path != 0u)
            {
                Singleton <PathManager> .instance.ReleasePath(data.m_path);

                data.m_path = 0u;
            }

            NetManager netManager = Singleton <NetManager> .instance;

            if ((netManager.m_nodes.m_buffer[(int)data.m_startNode].m_flags & NetNode.Flags.Ambiguous) != NetNode.Flags.None)
            {
                for (int i = 0; i < 8; i++)
                {
                    ushort segment = netManager.m_nodes.m_buffer[(int)data.m_startNode].GetSegment(i);
                    if (segment != 0 && segment != segmentID && netManager.m_segments.m_buffer[(int)segment].m_path != 0u)
                    {
                        return(true);
                    }
                }
            }
            if ((netManager.m_nodes.m_buffer[(int)data.m_endNode].m_flags & NetNode.Flags.Ambiguous) != NetNode.Flags.None)
            {
                for (int j = 0; j < 8; j++)
                {
                    ushort segment2 = netManager.m_nodes.m_buffer[(int)data.m_endNode].GetSegment(j);
                    if (segment2 != 0 && segment2 != segmentID && netManager.m_segments.m_buffer[(int)segment2].m_path != 0u)
                    {
                        return(true);
                    }
                }
            }

            Vector3 position  = netManager.m_nodes.m_buffer[(int)data.m_startNode].m_position;
            Vector3 position2 = netManager.m_nodes.m_buffer[(int)data.m_endNode].m_position;

#if DEBUG
            bool debug = GlobalConfig.Instance.Debug.Switches[18];
            if (debug)
            {
                Log._Debug($"TransportLineAI.CustomStartPathFind({segmentID}, ..., {netService}, {netService2}, {vehicleType}, {skipQueue}): startNode={data.m_startNode} @ {position}, endNode={data.m_endNode} @ {position2} -- line: {netManager.m_nodes.m_buffer[(int)data.m_startNode].m_transportLine}/{netManager.m_nodes.m_buffer[(int)data.m_endNode].m_transportLine}");
            }
#endif

            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             startSqrDistA;
            float             startSqrDistB;
            if (!CustomPathManager.FindPathPosition(position, netService, netService2, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, vehicleType, true, false, 32f, out startPosA, out startPosB, out startSqrDistA, out startSqrDistB))
            {
                CustomTransportLineAI.CheckSegmentProblems(segmentID, ref data);
                return(true);
            }

            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float             endSqrDistA;
            float             endSqrDistB;
            if (!CustomPathManager.FindPathPosition(position2, netService, netService2, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, vehicleType, true, false, 32f, out endPosA, out endPosB, out endSqrDistA, out endSqrDistB))
            {
                CustomTransportLineAI.CheckSegmentProblems(segmentID, ref data);
                return(true);
            }

            if ((netManager.m_nodes.m_buffer[(int)data.m_startNode].m_flags & NetNode.Flags.Fixed) != NetNode.Flags.None)
            {
                startPosB = default(PathUnit.Position);
            }

            if ((netManager.m_nodes.m_buffer[(int)data.m_endNode].m_flags & NetNode.Flags.Fixed) != NetNode.Flags.None)
            {
                endPosB = default(PathUnit.Position);
            }

            if (vehicleType != VehicleInfo.VehicleType.None)
            {
                startPosA.m_offset = 128;
                startPosB.m_offset = 128;
                endPosA.m_offset   = 128;
                endPosB.m_offset   = 128;
            }
            else
            {
                startPosA.m_offset = (byte)Mathf.Clamp(startPosA.m_offset, 1, 254);
                startPosB.m_offset = (byte)Mathf.Clamp(startPosB.m_offset, 1, 254);
                endPosA.m_offset   = (byte)Mathf.Clamp(endPosA.m_offset, 1, 254);
                endPosB.m_offset   = (byte)Mathf.Clamp(endPosB.m_offset, 1, 254);
            }

            bool stopLane  = CustomTransportLineAI.GetStopLane(ref startPosA, vehicleType);
            bool stopLane2 = CustomTransportLineAI.GetStopLane(ref startPosB, vehicleType);
            bool stopLane3 = CustomTransportLineAI.GetStopLane(ref endPosA, vehicleType);
            bool stopLane4 = CustomTransportLineAI.GetStopLane(ref endPosB, vehicleType);

            if ((!stopLane && !stopLane2) || (!stopLane3 && !stopLane4))
            {
                CustomTransportLineAI.CheckSegmentProblems(segmentID, ref data);
                return(true);
            }

            ExtVehicleType extVehicleType = ExtVehicleType.None;
#if BENCHMARK
            using (var bm = new Benchmark(null, "extVehicleType")) {
#endif
            if ((vehicleType & VehicleInfo.VehicleType.Car) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.Bus;
            }
            if ((vehicleType & (VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Metro | VehicleInfo.VehicleType.Monorail)) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.PassengerTrain;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Tram) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.Tram;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Ship) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.PassengerShip;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Plane) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.PassengerPlane;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Ferry) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.Ferry;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Blimp) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.Blimp;
            }
            if ((vehicleType & VehicleInfo.VehicleType.CableCar) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.CableCar;
            }
#if BENCHMARK
        }
#endif
            //Log._Debug($"Transport line. extVehicleType={extVehicleType}");
            uint path;
            // NON-STOCK CODE START
            PathCreationArgs args;
            args.extPathType         = ExtCitizenInstance.ExtPathType.None;
            args.extVehicleType      = extVehicleType;
            args.vehicleId           = 0;
            args.spawned             = true;
            args.buildIndex          = Singleton <SimulationManager> .instance.m_currentBuildIndex;
            args.startPosA           = startPosA;
            args.startPosB           = startPosB;
            args.endPosA             = endPosA;
            args.endPosB             = endPosB;
            args.vehiclePosition     = default(PathUnit.Position);
            args.vehicleTypes        = vehicleType;
            args.isHeavyVehicle      = false;
            args.hasCombustionEngine = false;
            args.ignoreBlocked       = true;
            args.ignoreFlooded       = false;
            args.ignoreCosts         = false;
            args.randomParking       = false;
            args.stablePath          = true;
            args.skipQueue           = skipQueue;

            if (vehicleType == VehicleInfo.VehicleType.None)
            {
                args.laneTypes = NetInfo.LaneType.Pedestrian;
                args.maxLength = 160000f;
            }
            else
            {
                args.laneTypes = (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle);
                args.maxLength = 20000f;
            }

            if (CustomPathManager._instance.CreatePath(out path, ref Singleton <SimulationManager> .instance.m_randomizer, args))
            {
                // NON-STOCK CODE END
                if (startPosA.m_segment != 0 && startPosB.m_segment != 0)
                {
                    netManager.m_nodes.m_buffer[data.m_startNode].m_flags |= NetNode.Flags.Ambiguous;
                }
                else
                {
                    netManager.m_nodes.m_buffer[data.m_startNode].m_flags &= ~NetNode.Flags.Ambiguous;
                }
                if (endPosA.m_segment != 0 && endPosB.m_segment != 0)
                {
                    netManager.m_nodes.m_buffer[data.m_endNode].m_flags |= NetNode.Flags.Ambiguous;
                }
                else
                {
                    netManager.m_nodes.m_buffer[data.m_endNode].m_flags &= ~NetNode.Flags.Ambiguous;
                }
                data.m_path   = path;
                data.m_flags |= NetSegment.Flags.WaitingPath;
#if DEBUG
                if (debug)
                {
                    Log._Debug($"TransportLineAI.CustomStartPathFind({segmentID}, ..., {netService}, {netService2}, {vehicleType}, {skipQueue}): Started calculating path {path} for extVehicleType={extVehicleType}, startPosA=[seg={startPosA.m_segment}, lane={startPosA.m_lane}, off={startPosA.m_offset}], startPosB=[seg={startPosB.m_segment}, lane={startPosB.m_lane}, off={startPosB.m_offset}], endPosA=[seg={endPosA.m_segment}, lane={endPosA.m_lane}, off={endPosA.m_offset}], endPosB=[seg={endPosB.m_segment}, lane={endPosB.m_lane}, off={endPosB.m_offset}]");
                }
#endif
                return(false);
            }

            CustomTransportLineAI.CheckSegmentProblems(segmentID, ref data);
            return(true);
        }
Beispiel #17
0
        public bool ExtStartPathFind(ushort vehicleID, ref Vehicle vehicleData, ushort driverInstanceId, ref ExtCitizenInstance driverExtInstance, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, bool undergroundTarget)
        {
#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;

            if (debug)
            {
                Log.Warning($"CustomPassengerCarAI.ExtStartPathFind({vehicleID}): called for vehicle {vehicleID}, driverInstanceId={driverInstanceId}, startPos={startPos}, endPos={endPos}, sourceBuilding={vehicleData.m_sourceBuilding}, targetBuilding={vehicleData.m_targetBuilding} pathMode={driverExtInstance.pathMode}");
            }
#endif

            PathUnit.Position startPosA = default(PathUnit.Position);
            PathUnit.Position startPosB = default(PathUnit.Position);
            PathUnit.Position endPosA   = default(PathUnit.Position);
            float sqrDistA = 0f;
            float sqrDistB;

            CitizenManager citizenManager = Singleton <CitizenManager> .instance;
            ushort targetBuildingId       = citizenManager.m_instances.m_buffer[(int)driverInstanceId].m_targetBuilding;
            uint driverCitizenId          = citizenManager.m_instances.m_buffer[(int)driverInstanceId].m_citizen;

            // NON-STOCK CODE START
            bool calculateEndPos    = true;
            bool allowRandomParking = true;
            bool movingToParkingPos = false;
            bool foundStartingPos   = false;
            bool skipQueue          = (vehicleData.m_flags & Vehicle.Flags.Spawned) != 0;
            ExtPathType extPathType = ExtPathType.None;
#if BENCHMARK
            using (var bm = new Benchmark(null, "ParkingAI")) {
#endif
            if (Options.prohibitPocketCars)
            {
                //if (driverExtInstance != null) {
#if DEBUG
                if (debug)
                {
                    Log.Warning($"CustomPassengerCarAI.ExtStartPathFind({vehicleID}): PathMode={driverExtInstance.pathMode} for vehicle {vehicleID}, driver citizen instance {driverExtInstance.instanceId}!");
                }
#endif

                if (targetBuildingId != 0 && (Singleton <BuildingManager> .instance.m_buildings.m_buffer[targetBuildingId].m_flags & Building.Flags.IncomingOutgoing) != Building.Flags.None)
                {
                    // target is outside connection
                    driverExtInstance.pathMode = ExtPathMode.CalculatingCarPathToTarget;
                }
                else
                {
                    if (driverExtInstance.pathMode == ExtPathMode.DrivingToTarget || driverExtInstance.pathMode == ExtPathMode.DrivingToKnownParkPos || driverExtInstance.pathMode == ExtPathMode.ParkingFailed)
                    {
                        skipQueue = true;
                    }

                    bool allowTourists = false;
                    if (driverExtInstance.pathMode == ExtPathMode.ParkingFailed)
                    {
                        // previous parking attempt failed
                        driverExtInstance.pathMode = ExtPathMode.CalculatingCarPathToAltParkPos;
                        allowTourists = true;

#if DEBUG
                        if (debug)
                        {
                            Log._Debug($"CustomPassengerCarAI.ExtStartPathFind({vehicleID}): Vehicle {vehicleID} shall move to an alternative parking position! CurrentPathMode={driverExtInstance.pathMode} FailedParkingAttempts={driverExtInstance.failedParkingAttempts}");
                        }
#endif

                        if (driverExtInstance.parkingPathStartPosition != null)
                        {
                            startPosA        = (PathUnit.Position)driverExtInstance.parkingPathStartPosition;
                            foundStartingPos = true;
#if DEBUG
                            if (debug)
                            {
                                Log._Debug($"CustomPassengerCarAI.ExtStartPathFind({vehicleID}): Setting starting pos for {vehicleID} to segment={startPosA.m_segment}, laneIndex={startPosA.m_lane}, offset={startPosA.m_offset}");
                            }
#endif
                        }
                        startBothWays = false;

                        if (driverExtInstance.failedParkingAttempts > GlobalConfig.Instance.ParkingAI.MaxParkingAttempts)
                        {
                            // maximum number of parking attempts reached
#if DEBUG
                            if (debug)
                            {
                                Log._Debug($"CustomPassengerCarAI.ExtStartPathFind({vehicleID}): Reached maximum number of parking attempts for vehicle {vehicleID}! GIVING UP.");
                            }
#endif
                            driverExtInstance.Reset();

                            // pocket car fallback
                            //vehicleData.m_flags |= Vehicle.Flags.Parking;
                            return(false);
                        }
                        else
                        {
#if DEBUG
                            if (fineDebug)
                            {
                                Log._Debug($"CustomPassengerCarAI.ExtStartPathFind({vehicleID}): Increased number of parking attempts for vehicle {vehicleID}: {driverExtInstance.failedParkingAttempts}/{GlobalConfig.Instance.ParkingAI.MaxParkingAttempts}");
                            }
#endif
                        }
                    }
                    else
                    {
                        driverExtInstance.pathMode = ExtPathMode.CalculatingCarPathToKnownParkPos;
                    }

                    ushort homeId = Singleton <CitizenManager> .instance.m_citizens.m_buffer[driverCitizenId].m_homeBuilding;
                    bool calcEndPos;
                    Vector3 parkPos;

                    if (AdvancedParkingManager.Instance.FindParkingSpaceForCitizen(endPos, vehicleData.Info, ref driverExtInstance, homeId, targetBuildingId == homeId, vehicleID, allowTourists, out parkPos, ref endPosA, out calcEndPos))
                    {
                        calculateEndPos    = calcEndPos;
                        allowRandomParking = false;
                        movingToParkingPos = true;

                        if (!driverExtInstance.CalculateReturnPath(parkPos, endPos))
                        {
#if DEBUG
                            if (debug)
                            {
                                Log._Debug($"CustomPassengerCarAI.ExtStartPathFind({vehicleID}): Could not calculate return path for citizen instance {driverExtInstance.instanceId}, vehicle {vehicleID}. Resetting instance.");
                            }
#endif
                            driverExtInstance.Reset();
                            return(false);
                        }
                    }
                    else if (driverExtInstance.pathMode == ExtPathMode.CalculatingCarPathToAltParkPos)
                    {
                        // no alternative parking spot found: abort
#if DEBUG
                        if (debug)
                        {
                            Log._Debug($"CustomPassengerCarAI.ExtStartPathFind({vehicleID}): No alternative parking spot found for vehicle {vehicleID}, citizen instance {driverExtInstance.instanceId} with CurrentPathMode={driverExtInstance.pathMode}! GIVING UP.");
                        }
#endif
                        driverExtInstance.Reset();
                        return(false);
                    }
                    else
                    {
                        // calculate a direct path to target
#if DEBUG
                        if (debug)
                        {
                            Log._Debug($"CustomPassengerCarAI.ExtStartPathFind({vehicleID}): No alternative parking spot found for vehicle {vehicleID}, citizen instance {driverExtInstance.instanceId} with CurrentPathMode={driverExtInstance.pathMode}! Setting CurrentPathMode to 'CalculatingCarPath'.");
                        }
#endif
                        driverExtInstance.pathMode = ExtPathMode.CalculatingCarPathToTarget;
                    }
                }

                extPathType = driverExtInstance.GetPathType();

                /*} else {
                 #if DEBUG
                 *      if (debug)
                 *              Log.Warning($"CustomPassengerCarAI.CustomStartPathFind: No driver citizen instance found for vehicle {vehicleID}!");
                 #endif
                 * }*/
            }
#if BENCHMARK
        }
#endif

            NetInfo.LaneType laneTypes = NetInfo.LaneType.Vehicle;
            if (!movingToParkingPos)
            {
                laneTypes |= NetInfo.LaneType.Pedestrian;
            }
            // NON-STOCK CODE END

            VehicleInfo.VehicleType vehicleTypes = this.m_info.m_vehicleType;
            bool allowUnderground = (vehicleData.m_flags & Vehicle.Flags.Underground) != 0;
            bool randomParking    = false;
            bool combustionEngine = this.m_info.m_class.m_subService == ItemClass.SubService.ResidentialLow;
            if (allowRandomParking &&             // NON-STOCK CODE
                !movingToParkingPos &&
                targetBuildingId != 0 &&
                (
                    Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)targetBuildingId].Info.m_class.m_service > ItemClass.Service.Office ||
                    (citizenManager.m_instances.m_buffer[driverInstanceId].m_flags & CitizenInstance.Flags.TargetIsNode) != CitizenInstance.Flags.None
                ))
            {
                randomParking = true;
            }

#if DEBUG
            if (fineDebug)
            {
                Log._Debug($"CustomPassengerCarAI.ExtStartPathFind({vehicleID}): Requesting path-finding for passenger car {vehicleID}, startPos={startPos}, endPos={endPos}, extPathType={extPathType}");
            }
#endif

            // NON-STOCK CODE START
            if (!foundStartingPos)
            {
                foundStartingPos = CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, vehicleTypes, allowUnderground, false, 32f, out startPosA, out startPosB, out sqrDistA, out sqrDistB);
            }

            bool foundEndPos = !calculateEndPos || citizenManager.m_instances.m_buffer[(int)driverInstanceId].Info.m_citizenAI.FindPathPosition(driverInstanceId, ref citizenManager.m_instances.m_buffer[(int)driverInstanceId], endPos, Options.prohibitPocketCars && (targetBuildingId == 0 || (Singleton <BuildingManager> .instance.m_buildings.m_buffer[targetBuildingId].m_flags & Building.Flags.IncomingOutgoing) == Building.Flags.None) ? NetInfo.LaneType.Pedestrian : (laneTypes | NetInfo.LaneType.Pedestrian), vehicleTypes, undergroundTarget, out endPosA);
            // NON-STOCK CODE END

            if (foundStartingPos &&
                foundEndPos)                   // NON-STOCK CODE

            {
                if (!startBothWays || sqrDistA < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                PathUnit.Position endPosB = default(PathUnit.Position);
                SimulationManager simMan  = Singleton <SimulationManager> .instance;
                uint path;
                PathUnit.Position dummyPathPos = default(PathUnit.Position);
                // NON-STOCK CODE START
                PathCreationArgs args;
                args.extPathType         = extPathType;
                args.extVehicleType      = ExtVehicleType.PassengerCar;
                args.vehicleId           = vehicleID;
                args.buildIndex          = simMan.m_currentBuildIndex;
                args.startPosA           = startPosA;
                args.startPosB           = startPosB;
                args.endPosA             = endPosA;
                args.endPosB             = endPosB;
                args.vehiclePosition     = dummyPathPos;
                args.laneTypes           = laneTypes;
                args.vehicleTypes        = vehicleTypes;
                args.maxLength           = 20000f;
                args.isHeavyVehicle      = this.IsHeavyVehicle();
                args.hasCombustionEngine = this.CombustionEngine();
                args.ignoreBlocked       = this.IgnoreBlocked(vehicleID, ref vehicleData);
                args.ignoreFlooded       = false;
                args.ignoreCosts         = false;
                args.randomParking       = randomParking;
                args.stablePath          = false;
                args.skipQueue           = (vehicleData.m_flags & Vehicle.Flags.Spawned) != 0;

                if (CustomPathManager._instance.CreatePath(out path, ref simMan.m_randomizer, args))
                {
#if DEBUG
                    if (debug)
                    {
                        Log._Debug($"CustomPassengerCarAI.ExtStartPathFind({vehicleID}): Path-finding starts for passenger car {vehicleID}, path={path}, startPosA.segment={startPosA.m_segment}, startPosA.lane={startPosA.m_lane}, laneType={laneTypes}, vehicleType={vehicleTypes}, endPosA.segment={endPosA.m_segment}, endPosA.lane={endPosA.m_lane}");
                    }
#endif
                    // NON-STOCK CODE END

                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
        public override void OnCreated(ILoading loading) {
            SelfDestruct.DestructOldInstances(this);

            base.OnCreated(loading);

            Log.Message("Setting ToolMode");
            ToolMode = TrafficManagerMode.None;

            Log.Message("Init RevertMethods");
			OriginalMethods = new MethodInfo[9];
			CustomMethods = new MethodInfo[9];
			CustomRedirects = new RedirectCallsState[9];

            Log.Message("Setting Despawn to False");
            DespawnEnabled = true;

            Log.Message("Init DetourInited");
            DetourInited = false;

            Log.Message("Init Custom PathManager");
            CustomPathManager = new CustomPathManager();
        }
Beispiel #19
0
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, bool undergroundTarget)
        {
#if DEBUG
            //Log._Debug($"CustomTaxiAI.CustomStartPathFind called for vehicle {vehicleID}");
#endif

            CitizenManager instance            = Singleton <CitizenManager> .instance;
            ushort         passengerInstanceId = CustomTaxiAI.GetPassengerInstance(vehicleID, ref vehicleData);
            if (passengerInstanceId == 0 || (instance.m_instances.m_buffer[(int)passengerInstanceId].m_flags & CitizenInstance.Flags.Character) != CitizenInstance.Flags.None)
            {
                return(base.StartPathFind(vehicleID, ref vehicleData, startPos, endPos, startBothWays, endBothWays, undergroundTarget));
            }
            VehicleInfo             info         = this.m_info;
            CitizenInfo             info2        = instance.m_instances.m_buffer[(int)passengerInstanceId].Info;
            NetInfo.LaneType        laneTypes    = NetInfo.LaneType.Vehicle | NetInfo.LaneType.Pedestrian | NetInfo.LaneType.TransportVehicle;
            VehicleInfo.VehicleType vehicleTypes = this.m_info.m_vehicleType;
            bool allowUnderground = (vehicleData.m_flags & Vehicle.Flags.Underground) != 0;
            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             startSqrDistA;
            float             startSqrDistB;
            PathUnit.Position endPosA;
            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out startSqrDistA, out startSqrDistB) &&
                info2.m_citizenAI.FindPathPosition(passengerInstanceId, ref instance.m_instances.m_buffer[(int)passengerInstanceId], endPos, laneTypes, vehicleTypes, undergroundTarget, out endPosA))
            {
                if ((instance.m_instances.m_buffer[(int)passengerInstanceId].m_flags & CitizenInstance.Flags.CannotUseTransport) == CitizenInstance.Flags.None)
                {
                    laneTypes |= NetInfo.LaneType.PublicTransport;

                    uint citizenId = instance.m_instances.m_buffer[passengerInstanceId].m_citizen;
                    if (citizenId != 0u && (instance.m_citizens.m_buffer[citizenId].m_flags & Citizen.Flags.Evacuating) != Citizen.Flags.None)
                    {
                        laneTypes |= NetInfo.LaneType.EvacuationTransport;
                    }
                }
                if (!startBothWays || startSqrDistA < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                PathUnit.Position endPosB = default(PathUnit.Position);
                SimulationManager simMan  = Singleton <SimulationManager> .instance;
                uint path;
                // NON-STOCK CODE START
                PathCreationArgs args;
                args.extPathType         = ExtCitizenInstance.ExtPathType.None;
                args.extVehicleType      = ExtVehicleType.Taxi;
                args.vehicleId           = vehicleID;
                args.buildIndex          = simMan.m_currentBuildIndex;
                args.startPosA           = startPosA;
                args.startPosB           = startPosB;
                args.endPosA             = endPosA;
                args.endPosB             = endPosB;
                args.vehiclePosition     = default(PathUnit.Position);
                args.laneTypes           = laneTypes;
                args.vehicleTypes        = vehicleTypes;
                args.maxLength           = 20000f;
                args.isHeavyVehicle      = this.IsHeavyVehicle();
                args.hasCombustionEngine = this.CombustionEngine();
                args.ignoreBlocked       = this.IgnoreBlocked(vehicleID, ref vehicleData);
                args.ignoreFlooded       = false;
                args.ignoreCosts         = false;
                args.randomParking       = false;
                args.stablePath          = false;
                args.skipQueue           = (vehicleData.m_flags & Vehicle.Flags.Spawned) != 0;

                if (CustomPathManager._instance.CreatePath(out path, ref simMan.m_randomizer, args))
                {
                    // NON-STOCK CODE END
                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
        public bool ExtStartPathFind(ushort instanceID, ref CitizenInstance instanceData, ref ExtCitizenInstance extInstance, ref ExtCitizen extCitizen, Vector3 startPos, Vector3 endPos, VehicleInfo vehicleInfo, bool enableTransport, bool ignoreCost)
        {
#if DEBUG
            bool citDebug  = GlobalConfig.Instance.Debug.CitizenId == 0 || GlobalConfig.Instance.Debug.CitizenId == instanceData.m_citizen;
            bool debug     = GlobalConfig.Instance.Debug.Switches[2] && citDebug;
            bool fineDebug = GlobalConfig.Instance.Debug.Switches[4] && citDebug;

            if (debug)
            {
                Log.Warning($"CustomCitizenAI.ExtStartPathFind({instanceID}): called for citizen {instanceData.m_citizen}, startPos={startPos}, endPos={endPos}, sourceBuilding={instanceData.m_sourceBuilding}, targetBuilding={instanceData.m_targetBuilding}, pathMode={extInstance.pathMode}");
            }
#endif

            // NON-STOCK CODE START
            CitizenManager citizenManager  = Singleton <CitizenManager> .instance;
            ushort         parkedVehicleId = citizenManager.m_citizens.m_buffer[instanceData.m_citizen].m_parkedVehicle;
            ushort         homeId          = citizenManager.m_citizens.m_buffer[instanceData.m_citizen].m_homeBuilding;
            CarUsagePolicy carUsageMode    = CarUsagePolicy.Allowed;

            // disallow car usage if citizen is on a walking tour
            if ((instanceData.m_flags & CitizenInstance.Flags.OnTour) != CitizenInstance.Flags.None)
            {
                carUsageMode = CarUsagePolicy.Forbidden;
                vehicleInfo  = null;                // TODO check if citizens may use bikes on walking tours
            }

#if BENCHMARK
            using (var bm = new Benchmark(null, "ParkingAI.Preparation")) {
#endif
            if (Options.prohibitPocketCars)
            {
                switch (extInstance.pathMode)
                {
                case ExtPathMode.RequiresWalkingPathToParkedCar:
                case ExtPathMode.CalculatingWalkingPathToParkedCar:
                case ExtPathMode.WalkingToParkedCar:
                case ExtPathMode.ApproachingParkedCar:
                    if (parkedVehicleId == 0 || carUsageMode == CarUsagePolicy.Forbidden)
                    {
                        // parked vehicle not present or citizen is on a walking tour
#if DEBUG
                        if (debug)
                        {
                            Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen has CurrentPathMode={extInstance.pathMode} but no parked vehicle present OR citizen is on a walking tour (carUsageMode={carUsageMode}). Change to 'None'.");
                        }
#endif

                        extInstance.Reset();
                    }
                    else
                    {
#if DEBUG
                        if (fineDebug)
                        {
                            Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen has CurrentPathMode={extInstance.pathMode}.  Change to 'CalculatingWalkingPathToParkedCar'.");
                        }
#endif
                        extInstance.pathMode = ExtPathMode.CalculatingWalkingPathToParkedCar;
                    }
                    break;

                case ExtPathMode.RequiresWalkingPathToTarget:
                case ExtPathMode.CalculatingWalkingPathToTarget:
                case ExtPathMode.WalkingToTarget:
#if DEBUG
                    if (fineDebug)
                    {
                        Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen has CurrentPathMode={extInstance.pathMode}. Change to 'CalculatingWalkingPathToTarget'.");
                    }
#endif
                    extInstance.pathMode = ExtPathMode.CalculatingWalkingPathToTarget;
                    break;

                case ExtPathMode.RequiresCarPath:
                case ExtPathMode.DrivingToTarget:
                case ExtPathMode.DrivingToKnownParkPos:
                case ExtPathMode.DrivingToAltParkPos:
                case ExtPathMode.CalculatingCarPathToAltParkPos:
                case ExtPathMode.CalculatingCarPathToKnownParkPos:
                case ExtPathMode.CalculatingCarPathToTarget:
                    if (parkedVehicleId == 0 || carUsageMode == CarUsagePolicy.Forbidden)
                    {
                        // parked vehicle not present or citizen is on a walking tour

#if DEBUG
                        if (debug)
                        {
                            Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen has CurrentPathMode={extInstance.pathMode} but no parked vehicle present OR citizen is on a walking tour (carUsageMode={carUsageMode}). Change to 'None'.");
                        }
#endif

                        extInstance.Reset();
                    }
                    else
                    {
#if DEBUG
                        if (fineDebug)
                        {
                            Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen has CurrentPathMode={extInstance.pathMode}.  Change to 'RequiresCarPath'.");
                        }
#endif

                        extInstance.pathMode = ExtPathMode.RequiresCarPath;
                    }
                    break;

                default:
#if DEBUG
                    if (debug)
                    {
                        Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen has CurrentPathMode={extInstance.pathMode}. Change to 'None'.");
                    }
#endif
                    extInstance.Reset();
                    break;
                }

                /*
                 * the following holds:
                 * - pathMode is now either CalculatingWalkingPathToParkedCar, CalculatingWalkingPathToTarget, RequiresCarPath or None.
                 * - if pathMode is CalculatingWalkingPathToParkedCar or RequiresCarPath: parked car is present and citizen is not on a walking tour
                 */

                /*
                 * reuse parked vehicle info
                 */
                if (parkedVehicleId != 0)
                {
                    vehicleInfo = Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[parkedVehicleId].Info;
                }

                /*
                 * check if the citizen must use their car on their current path
                 */
                if (parkedVehicleId != 0 &&                         // parked car present
                    carUsageMode != CarUsagePolicy.Forbidden &&     // cititzen is not on a walking tour
                    extInstance.pathMode == ExtPathMode.None &&     // initiating a new path
                    homeId != 0 &&                                  // home building present
                    instanceData.m_targetBuilding == homeId         // current target is home
                    )
                {
                    /*
                     * citizen travels back home
                     * -> check if their car should be returned
                     */
                    if ((extCitizen.lastTransportMode & ExtCitizen.ExtTransportMode.Car) != ExtCitizen.ExtTransportMode.None)
                    {
                        /*
                         * citizen travelled by car
                         * -> return car back home
                         */
                        extInstance.pathMode = ExtCitizenInstance.ExtPathMode.CalculatingWalkingPathToParkedCar;

#if DEBUG
                        if (fineDebug)
                        {
                            Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen used their car before and is not at home. Forcing to walk to parked car.");
                        }
#endif
                    }
                    else
                    {
                        /*
                         * citizen travelled by other means of transport
                         * -> check distance between home and parked car. if too far away: force to take the car back home
                         */
                        float distHomeToParked = (Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[parkedVehicleId].m_position - Singleton <BuildingManager> .instance.m_buildings.m_buffer[homeId].m_position).magnitude;

                        if (distHomeToParked > GlobalConfig.Instance.ParkingAI.MaxParkedCarDistanceToHome)
                        {
                            /*
                             * force to take car back home
                             */
                            extInstance.pathMode = ExtCitizenInstance.ExtPathMode.CalculatingWalkingPathToParkedCar;

#if DEBUG
                            if (fineDebug)
                            {
                                Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen wants to go home and parked car is too far away ({distHomeToParked}). Forcing walking to parked car.");
                            }
#endif
                        }
                    }
                }

                /*
                 * modify path-finding constraints (vehicleInfo, endPos) if citizen is forced to walk
                 */
                if (extInstance.pathMode == ExtPathMode.CalculatingWalkingPathToParkedCar || extInstance.pathMode == ExtPathMode.CalculatingWalkingPathToTarget)
                {
                    /*
                     * vehicle must not be used since we need a walking path to either
                     * 1. a parked car or
                     * 2. the target building
                     */
                    vehicleInfo  = null;
                    carUsageMode = CarUsagePolicy.Forbidden;

                    if (extInstance.pathMode == ExtCitizenInstance.ExtPathMode.CalculatingWalkingPathToParkedCar)
                    {
                        /*
                         * walk to parked car
                         * -> end position is parked car
                         */
                        endPos = Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[parkedVehicleId].m_position;
#if DEBUG
                        if (fineDebug)
                        {
                            Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen shall go to parked vehicle @ {endPos}");
                        }
#endif
                    }
                }
                else if (extInstance.pathMode == ExtPathMode.RequiresCarPath)
                {
                    /*
                     * citizen stands in front of their parked vehicle
                     * -> find a car-only path now
                     */
                    carUsageMode = CarUsagePolicy.Forced;
                    startPos     = Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[parkedVehicleId].m_position;                       // force to start from the parked car

#if DEBUG
                    if (fineDebug)
                    {
                        Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen is forced to drive their car");
                    }
#endif
                }
            }
#if BENCHMARK
        }
#endif
#if DEBUG
            if (fineDebug)
            {
                Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen is allowed to drive their car? {carUsageMode}");
            }
#endif
            // NON-STOCK CODE END

            /*
             * semi-stock code: determine path-finding parameters (laneTypes, vehicleTypes, extVehicleType, etc.)
             */
            NetInfo.LaneType laneTypes           = NetInfo.LaneType.Pedestrian;
            VehicleInfo.VehicleType vehicleTypes = VehicleInfo.VehicleType.None;
            bool randomParking            = false;
            bool combustionEngine         = false;
            ExtVehicleType extVehicleType = ExtVehicleType.None;
            if (vehicleInfo != null)
            {
                if (vehicleInfo.m_class.m_subService == ItemClass.SubService.PublicTransportTaxi)
                {
                    if ((instanceData.m_flags & CitizenInstance.Flags.CannotUseTaxi) == CitizenInstance.Flags.None && Singleton <DistrictManager> .instance.m_districts.m_buffer[0].m_productionData.m_finalTaxiCapacity != 0u)
                    {
                        SimulationManager instance = Singleton <SimulationManager> .instance;
                        if (instance.m_isNightTime || instance.m_randomizer.Int32(2u) == 0)
                        {
                            laneTypes     |= (NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle);
                            vehicleTypes  |= vehicleInfo.m_vehicleType;
                            extVehicleType = ExtVehicleType.Taxi;                             // NON-STOCK CODE
                            // NON-STOCK CODE START
                            if (Options.prohibitPocketCars)
                            {
                                extInstance.pathMode = ExtPathMode.TaxiToTarget;
                            }
                            // NON-STOCK CODE END
                        }
                    }
                }
                else
                // NON-STOCK CODE START
                if (vehicleInfo.m_vehicleType == VehicleInfo.VehicleType.Car)
                {
                    if (carUsageMode != CarUsagePolicy.Forbidden)
                    {
                        extVehicleType   = ExtVehicleType.PassengerCar;
                        laneTypes       |= NetInfo.LaneType.Vehicle;
                        vehicleTypes    |= vehicleInfo.m_vehicleType;
                        combustionEngine = vehicleInfo.m_class.m_subService == ItemClass.SubService.ResidentialLow;
                    }
                }
                else if (vehicleInfo.m_vehicleType == VehicleInfo.VehicleType.Bicycle)
                {
                    extVehicleType = ExtVehicleType.Bicycle;
                    laneTypes     |= NetInfo.LaneType.Vehicle;
                    vehicleTypes  |= vehicleInfo.m_vehicleType;
                }
                // NON-STOCK CODE END
            }

            // NON-STOCK CODE START
            ExtPathType extPathType   = ExtPathType.None;
            PathUnit.Position endPosA = default(PathUnit.Position);
            bool calculateEndPos      = true;
            bool allowRandomParking   = true;
#if BENCHMARK
            using (var bm = new Benchmark(null, "ParkingAI.Main")) {
#endif
            if (Options.prohibitPocketCars)
            {
                // Parking AI

                if (extInstance.pathMode == ExtCitizenInstance.ExtPathMode.RequiresCarPath)
                {
#if DEBUG
                    if (debug)
                    {
                        Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Setting startPos={startPos} for citizen instance {instanceID}. CurrentDepartureMode={extInstance.pathMode}");
                    }
#endif

                    if (instanceData.m_targetBuilding == 0 || (Singleton <BuildingManager> .instance.m_buildings.m_buffer[instanceData.m_targetBuilding].m_flags & Building.Flags.IncomingOutgoing) == Building.Flags.None)
                    {
                        /*
                         * the citizen is starting their journey and the target is not an outside connection
                         * -> find a suitable parking space near the target
                         */

#if DEBUG
                        if (debug)
                        {
                            Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Finding parking space at target for citizen instance {instanceID}. CurrentDepartureMode={extInstance.pathMode} parkedVehicleId={parkedVehicleId}");
                        }
#endif

                        // find a parking space in the vicinity of the target
                        bool    calcEndPos;
                        Vector3 parkPos;
                        if (AdvancedParkingManager.Instance.FindParkingSpaceForCitizen(endPos, vehicleInfo, ref extInstance, homeId, instanceData.m_targetBuilding == homeId, 0, false, out parkPos, ref endPosA, out calcEndPos) && extInstance.CalculateReturnPath(parkPos, endPos))
                        {
                            // success
                            extInstance.pathMode = ExtCitizenInstance.ExtPathMode.CalculatingCarPathToKnownParkPos;
                            calculateEndPos      = calcEndPos;                              // if true, the end path position still needs to be calculated
                            allowRandomParking   = false;                                   // find a direct path to the calculated parking position
#if DEBUG
                            if (debug)
                            {
                                Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Finding known parking space for citizen instance {instanceID}, parked vehicle {parkedVehicleId} succeeded and return path {extInstance.returnPathId} ({extInstance.returnPathState}) is calculating. PathMode={extInstance.pathMode}");
                            }
#endif

                            /*if (! extInstance.CalculateReturnPath(parkPos, endPos)) {
                             *      // TODO retry?
                             *      if (debug)
                             *              Log._Debug($"CustomCitizenAI.CustomStartPathFind: [PFFAIL] Could not calculate return path for citizen instance {instanceID}, parked vehicle {parkedVehicleId}. Calling OnPathFindFailed.");
                             *      CustomHumanAI.OnPathFindFailure(extInstance);
                             *      return false;
                             * }*/
                        }
                    }

                    if (extInstance.pathMode == ExtPathMode.RequiresCarPath)
                    {
                        /*
                         * no known parking space found (pathMode has not been updated in the block above)
                         * -> calculate direct path to target
                         */
#if DEBUG
                        if (debug)
                        {
                            Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen instance {instanceID} is still at CurrentPathMode={extInstance.pathMode} (no parking space found?). Setting it to CalculatingCarPath. parkedVehicleId={parkedVehicleId}");
                        }
#endif
                        extInstance.pathMode = ExtCitizenInstance.ExtPathMode.CalculatingCarPathToTarget;
                    }
                }

                /*
                 * determine path type from path mode
                 */
                extPathType = extInstance.GetPathType();

                /*
                 * the following holds:
                 * - pathMode is now either CalculatingWalkingPathToParkedCar, CalculatingWalkingPathToTarget, CalculatingCarPathToTarget, CalculatingCarPathToKnownParkPos or None.
                 */
            }
#if BENCHMARK
        }
#endif

            /*
             * enable random parking if exact parking space was not calculated yet
             */
            if (extVehicleType == ExtVehicleType.PassengerCar || extVehicleType == ExtVehicleType.Bicycle)
            {
                if (allowRandomParking &&
                    instanceData.m_targetBuilding != 0 &&
                    (
                        Singleton <BuildingManager> .instance.m_buildings.m_buffer[instanceData.m_targetBuilding].Info.m_class.m_service > ItemClass.Service.Office ||
                        (instanceData.m_flags & CitizenInstance.Flags.TargetIsNode) != 0
                    ))
                {
                    randomParking = true;
                }
            }
            // NON-STOCK CODE END

            /*
             * determine the path position of the parked vehicle
             */
            PathUnit.Position parkedVehiclePathPos = default(PathUnit.Position);
            if (parkedVehicleId != 0 && extVehicleType == ExtVehicleType.PassengerCar)
            {
                Vector3 position = Singleton <VehicleManager> .instance.m_parkedVehicles.m_buffer[parkedVehicleId].m_position;
                CustomPathManager.FindPathPositionWithSpiralLoop(position, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, VehicleInfo.VehicleType.Car, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, false, false, GlobalConfig.Instance.ParkingAI.MaxBuildingToPedestrianLaneDistance, out parkedVehiclePathPos);
            }
            bool allowUnderground = (instanceData.m_flags & (CitizenInstance.Flags.Underground | CitizenInstance.Flags.Transition)) != CitizenInstance.Flags.None;

#if DEBUG
            if (debug)
            {
                Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Requesting path-finding for citizen instance {instanceID}, citizen {instanceData.m_citizen}, extVehicleType={extVehicleType}, extPathType={extPathType}, startPos={startPos}, endPos={endPos}, sourceBuilding={instanceData.m_sourceBuilding}, targetBuilding={instanceData.m_targetBuilding} pathMode={extInstance.pathMode}");
            }
#endif

            /*
             * determine start & end path positions
             */
            bool foundEndPos   = !calculateEndPos || FindPathPosition(instanceID, ref instanceData, endPos, Options.prohibitPocketCars && (instanceData.m_targetBuilding == 0 || (Singleton <BuildingManager> .instance.m_buildings.m_buffer[instanceData.m_targetBuilding].m_flags & Building.Flags.IncomingOutgoing) == Building.Flags.None) ? NetInfo.LaneType.Pedestrian : laneTypes, vehicleTypes, false, out endPosA);         // NON-STOCK CODE: with Parking AI enabled, the end position must be a pedestrian position
            bool foundStartPos = false;
            PathUnit.Position startPosA;

            if (Options.prohibitPocketCars && (extInstance.pathMode == ExtPathMode.CalculatingCarPathToTarget || extInstance.pathMode == ExtPathMode.CalculatingCarPathToKnownParkPos))
            {
                /*
                 * citizen will enter their car now
                 * -> find a road start position
                 */
                foundStartPos = CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, laneTypes & ~NetInfo.LaneType.Pedestrian, vehicleTypes, allowUnderground, false, GlobalConfig.Instance.ParkingAI.MaxBuildingToPedestrianLaneDistance, out startPosA);
            }
            else
            {
                foundStartPos = FindPathPosition(instanceID, ref instanceData, startPos, laneTypes, vehicleTypes, allowUnderground, out startPosA);
            }

            /*
             * start path-finding
             */
            if (foundStartPos &&            // TODO probably fails if vehicle is parked too far away from road
                foundEndPos                 // NON-STOCK CODE
                )
            {
                if (enableTransport)
                {
                    /*
                     * public transport usage is allowed for this path
                     */
                    if ((instanceData.m_flags & CitizenInstance.Flags.CannotUseTransport) == CitizenInstance.Flags.None)
                    {
                        if (carUsageMode != CarUsagePolicy.Forced)                           // NON-STOCK CODE

                        /*
                         * citizen may use public transport
                         */
                        {
                            laneTypes |= NetInfo.LaneType.PublicTransport;

                            uint citizenId = instanceData.m_citizen;
                            if (citizenId != 0u && (citizenManager.m_citizens.m_buffer[citizenId].m_flags & Citizen.Flags.Evacuating) != Citizen.Flags.None)
                            {
                                laneTypes |= NetInfo.LaneType.EvacuationTransport;
                            }
                        }
                    }
                    else if (Options.prohibitPocketCars)                         // TODO check for incoming connection

                    /*
                     * citizen tried to use public transport but waiting time was too long
                     * -> add public transport demand for source building
                     */
                    {
                        if (instanceData.m_sourceBuilding != 0)
                        {
#if DEBUG
                            if (debug)
                            {
                                Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Citizen instance {instanceID} cannot uses public transport from building {instanceData.m_sourceBuilding} to {instanceData.m_targetBuilding}. Incrementing public transport demand.");
                            }
#endif
                            ExtBuildingManager.Instance.ExtBuildings[instanceData.m_sourceBuilding].AddPublicTransportDemand((uint)GlobalConfig.Instance.ParkingAI.PublicTransportDemandWaitingIncrement, true);
                        }
                    }
                }

                PathUnit.Position dummyPathPos = default(PathUnit.Position);
                uint path;
                // NON-STOCK CODE START
                PathCreationArgs args;
                args.extPathType         = extPathType;
                args.extVehicleType      = extVehicleType;
                args.vehicleId           = 0;
                args.buildIndex          = Singleton <SimulationManager> .instance.m_currentBuildIndex;
                args.startPosA           = startPosA;
                args.startPosB           = dummyPathPos;
                args.endPosA             = endPosA;
                args.endPosB             = dummyPathPos;
                args.vehiclePosition     = parkedVehiclePathPos;
                args.laneTypes           = laneTypes;
                args.vehicleTypes        = vehicleTypes;
                args.maxLength           = 20000f;
                args.isHeavyVehicle      = false;
                args.hasCombustionEngine = combustionEngine;
                args.ignoreBlocked       = false;
                args.ignoreFlooded       = false;
                args.ignoreCosts         = ignoreCost;
                args.randomParking       = randomParking;
                args.stablePath          = false;
                args.skipQueue           = false;

                if ((instanceData.m_flags & CitizenInstance.Flags.OnTour) != 0)
                {
                    args.stablePath = true;
                    args.maxLength  = 160000f;
                    //args.laneTypes &= ~(NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle);
                }
                else
                {
                    args.stablePath = false;
                    args.maxLength  = 20000f;
                }

                bool res = CustomPathManager._instance.CreatePath(out path, ref Singleton <SimulationManager> .instance.m_randomizer, args);
                // NON-STOCK CODE END

                if (res)
                {
#if DEBUG
                    if (debug)
                    {
                        Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): Path-finding starts for citizen instance {instanceID}, path={path}, extVehicleType={extVehicleType}, startPosA.segment={startPosA.m_segment}, startPosA.lane={startPosA.m_lane}, laneType={laneTypes}, vehicleType={vehicleTypes}, endPosA.segment={endPosA.m_segment}, endPosA.lane={endPosA.m_lane}, vehiclePos.m_segment={parkedVehiclePathPos.m_segment}, vehiclePos.m_lane={parkedVehiclePathPos.m_lane}, vehiclePos.m_offset={parkedVehiclePathPos.m_offset}");
                    }
#endif

                    if (instanceData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(instanceData.m_path);
                    }
                    instanceData.m_path   = path;
                    instanceData.m_flags |= CitizenInstance.Flags.WaitingPath;
                    return(true);
                }
            }

#if DEBUG
            if (Options.prohibitPocketCars)
            {
                if (debug)
                {
                    Log._Debug($"CustomCitizenAI.ExtStartPathFind({instanceID}): CustomCitizenAI.CustomStartPathFind: [PFFAIL] failed for citizen instance {instanceID} (CurrentPathMode={extInstance.pathMode}). startPosA.segment={startPosA.m_segment}, startPosA.lane={startPosA.m_lane}, startPosA.offset={startPosA.m_offset}, endPosA.segment={endPosA.m_segment}, endPosA.lane={endPosA.m_lane}, endPosA.offset={endPosA.m_offset}, foundStartPos={foundStartPos}, foundEndPos={foundEndPos}");
                }
            }
#endif
            return(false);
        }
    class CustomTransportLineAI : TransportLineAI {     // TODO inherit from NetAI (in order to keep the correct references to `base`)
        public static bool CustomStartPathFind(ushort segmentID, ref NetSegment data, ItemClass.Service netService, VehicleInfo.VehicleType vehicleType, bool skipQueue)
        {
            if (data.m_path != 0u)
            {
                Singleton <PathManager> .instance.ReleasePath(data.m_path);

                data.m_path = 0u;
            }
            NetManager instance = Singleton <NetManager> .instance;

            if ((instance.m_nodes.m_buffer[(int)data.m_startNode].m_flags & NetNode.Flags.Ambiguous) != NetNode.Flags.None)
            {
                for (int i = 0; i < 8; i++)
                {
                    ushort segment = instance.m_nodes.m_buffer[(int)data.m_startNode].GetSegment(i);
                    if (segment != 0 && segment != segmentID && instance.m_segments.m_buffer[(int)segment].m_path != 0u)
                    {
                        return(true);
                    }
                }
            }
            if ((instance.m_nodes.m_buffer[(int)data.m_endNode].m_flags & NetNode.Flags.Ambiguous) != NetNode.Flags.None)
            {
                for (int j = 0; j < 8; j++)
                {
                    ushort segment2 = instance.m_nodes.m_buffer[(int)data.m_endNode].GetSegment(j);
                    if (segment2 != 0 && segment2 != segmentID && instance.m_segments.m_buffer[(int)segment2].m_path != 0u)
                    {
                        return(true);
                    }
                }
            }
            Vector3 position  = instance.m_nodes.m_buffer[(int)data.m_startNode].m_position;
            Vector3 position2 = instance.m_nodes.m_buffer[(int)data.m_endNode].m_position;

            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             startSqrDistA;
            float             startSqrDistB;

            if (!CustomPathManager.FindPathPosition(position, netService, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, vehicleType, true, false, 32f, out startPosA, out startPosB, out startSqrDistA, out startSqrDistB))
            {
                CustomTransportLineAI.CheckSegmentProblems(segmentID, ref data);
                return(true);
            }
            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float             endSqrDistA;
            float             endSqrDistB;

            if (!CustomPathManager.FindPathPosition(position2, netService, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, vehicleType, true, false, 32f, out endPosA, out endPosB, out endSqrDistA, out endSqrDistB))
            {
                CustomTransportLineAI.CheckSegmentProblems(segmentID, ref data);
                return(true);
            }
            if ((instance.m_nodes.m_buffer[(int)data.m_startNode].m_flags & NetNode.Flags.Fixed) != NetNode.Flags.None)
            {
                startPosB = default(PathUnit.Position);
            }
            if ((instance.m_nodes.m_buffer[(int)data.m_endNode].m_flags & NetNode.Flags.Fixed) != NetNode.Flags.None)
            {
                endPosB = default(PathUnit.Position);
            }
            startPosA.m_offset = 128;
            startPosB.m_offset = 128;
            endPosA.m_offset   = 128;
            endPosB.m_offset   = 128;
            bool stopLane  = CustomTransportLineAI.GetStopLane(ref startPosA, vehicleType);
            bool stopLane2 = CustomTransportLineAI.GetStopLane(ref startPosB, vehicleType);
            bool stopLane3 = CustomTransportLineAI.GetStopLane(ref endPosA, vehicleType);
            bool stopLane4 = CustomTransportLineAI.GetStopLane(ref endPosB, vehicleType);

            if ((!stopLane && !stopLane2) || (!stopLane3 && !stopLane4))
            {
                CustomTransportLineAI.CheckSegmentProblems(segmentID, ref data);
                return(true);
            }
            uint           path;
            ExtVehicleType extVehicleType = ExtVehicleType.Bus;

            if ((vehicleType & (VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Metro)) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.PassengerTrain;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Tram) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.Tram;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Ship) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.PassengerShip;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Plane) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.PassengerPlane;
            }
            //Log._Debug($"Transport line. extVehicleType={extVehicleType}");

            if (CustomPathManager._instance.CreatePath(extVehicleType, 0, ExtCitizenInstance.ExtPathType.None, out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, vehicleType, 20000f, false, true, true, skipQueue))
            {
                if (startPosA.m_segment != 0 && startPosB.m_segment != 0)
                {
                    NetNode[] expr_2F5_cp_0 = instance.m_nodes.m_buffer;
                    ushort    expr_2F5_cp_1 = data.m_startNode;
                    expr_2F5_cp_0[(int)expr_2F5_cp_1].m_flags = (expr_2F5_cp_0[(int)expr_2F5_cp_1].m_flags | NetNode.Flags.Ambiguous);
                }
                else
                {
                    NetNode[] expr_321_cp_0 = instance.m_nodes.m_buffer;
                    ushort    expr_321_cp_1 = data.m_startNode;
                    expr_321_cp_0[(int)expr_321_cp_1].m_flags = (expr_321_cp_0[(int)expr_321_cp_1].m_flags & ~NetNode.Flags.Ambiguous);
                }
                if (endPosA.m_segment != 0 && endPosB.m_segment != 0)
                {
                    NetNode[] expr_360_cp_0 = instance.m_nodes.m_buffer;
                    ushort    expr_360_cp_1 = data.m_endNode;
                    expr_360_cp_0[(int)expr_360_cp_1].m_flags = (expr_360_cp_0[(int)expr_360_cp_1].m_flags | NetNode.Flags.Ambiguous);
                }
                else
                {
                    NetNode[] expr_38C_cp_0 = instance.m_nodes.m_buffer;
                    ushort    expr_38C_cp_1 = data.m_endNode;
                    expr_38C_cp_0[(int)expr_38C_cp_1].m_flags = (expr_38C_cp_0[(int)expr_38C_cp_1].m_flags & ~NetNode.Flags.Ambiguous);
                }
                data.m_path   = path;
                data.m_flags |= NetSegment.Flags.WaitingPath;
                return(false);
            }
            CustomTransportLineAI.CheckSegmentProblems(segmentID, ref data);
            return(true);
        }
Beispiel #22
0
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, bool undergroundTarget)
        {
#if DEBUG
            //Log._Debug($"CustomCargoTruckAI.CustomStartPathFind called for vehicle {vehicleID}");
#endif

#if BENCHMARK
            using (var bm = new Benchmark(null, "OnStartPathFind")) {
#endif
            ExtVehicleType vehicleType = VehicleStateManager.Instance.OnStartPathFind(vehicleID, ref vehicleData, null);
            if (vehicleType == ExtVehicleType.None)
            {
#if DEBUG
                Log.Warning($"CustomCargoTruck.CustomStartPathFind: Vehicle {vehicleID} does not have a valid vehicle type!");
#endif
            }
#if BENCHMARK
        }
#endif

            if ((vehicleData.m_flags & (Vehicle.Flags.TransferToSource | Vehicle.Flags.GoingBack)) != 0)
            {
                return(base.StartPathFind(vehicleID, ref vehicleData, startPos, endPos, startBothWays, endBothWays, undergroundTarget));
            }

            bool allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0;
            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float startDistSqrA;
            float startDistSqrB;
            bool startPosFound = CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, VehicleInfo.VehicleType.Car, allowUnderground, false, 32f, out startPosA, out startPosB, out startDistSqrA, out startDistSqrB);
            PathUnit.Position startAltPosA;
            PathUnit.Position startAltPosB;
            float startAltDistSqrA;
            float startAltDistSqrB;
            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.PublicTransport, NetInfo.LaneType.Vehicle, VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Ship, allowUnderground, false, 32f, out startAltPosA, out startAltPosB, out startAltDistSqrA, out startAltDistSqrB))
            {
                if (!startPosFound || startAltDistSqrA < startDistSqrA)
                {
                    startPosA     = startAltPosA;
                    startPosB     = startAltPosB;
                    startDistSqrA = startAltDistSqrA;
                    startDistSqrB = startAltDistSqrB;
                }
                startPosFound = true;
            }
            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float endDistSqrA;
            float endDistSqrB;
            bool endPosFound = CustomPathManager.FindPathPosition(endPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, VehicleInfo.VehicleType.Car, undergroundTarget, false, 32f, out endPosA, out endPosB, out endDistSqrA, out endDistSqrB);
            PathUnit.Position endAltPosA;
            PathUnit.Position endAltPosB;
            float endAltDistSqrA;
            float endAltDistSqrB;
            if (CustomPathManager.FindPathPosition(endPos, ItemClass.Service.PublicTransport, NetInfo.LaneType.Vehicle, VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Ship, undergroundTarget, false, 32f, out endAltPosA, out endAltPosB, out endAltDistSqrA, out endAltDistSqrB))
            {
                if (!endPosFound || endAltDistSqrA < endDistSqrA)
                {
                    endPosA     = endAltPosA;
                    endPosB     = endAltPosB;
                    endDistSqrA = endAltDistSqrA;
                    endDistSqrB = endAltDistSqrB;
                }
                endPosFound = true;
            }
            if (startPosFound && endPosFound)
            {
                CustomPathManager pathMan = CustomPathManager._instance;
                if (!startBothWays || startDistSqrA < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                if (!endBothWays || endDistSqrA < 10f)
                {
                    endPosB = default(PathUnit.Position);
                }
                NetInfo.LaneType        laneTypes    = NetInfo.LaneType.Vehicle | NetInfo.LaneType.CargoVehicle;
                VehicleInfo.VehicleType vehicleTypes = VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Ship;
                uint path;
                // NON-STOCK CODE START
                PathCreationArgs args;
                args.extPathType         = ExtCitizenInstance.ExtPathType.None;
                args.extVehicleType      = ExtVehicleType.CargoVehicle;
                args.vehicleId           = vehicleID;
                args.buildIndex          = Singleton <SimulationManager> .instance.m_currentBuildIndex;
                args.startPosA           = startPosA;
                args.startPosB           = startPosB;
                args.endPosA             = endPosA;
                args.endPosB             = endPosB;
                args.vehiclePosition     = default(PathUnit.Position);
                args.laneTypes           = laneTypes;
                args.vehicleTypes        = vehicleTypes;
                args.maxLength           = 20000f;
                args.isHeavyVehicle      = this.IsHeavyVehicle();
                args.hasCombustionEngine = this.CombustionEngine();
                args.ignoreBlocked       = this.IgnoreBlocked(vehicleID, ref vehicleData);
                args.ignoreFlooded       = false;
                args.randomParking       = false;
                args.stablePath          = false;
                args.skipQueue           = (vehicleData.m_flags & Vehicle.Flags.Spawned) != 0;

                if (pathMan.CreatePath(out path, ref Singleton <SimulationManager> .instance.m_randomizer, args))
                {
                    // NON-STOCK CODE END
                    if (vehicleData.m_path != 0u)
                    {
                        pathMan.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
Beispiel #23
0
 public bool CustomFindPathPosition(ushort instanceID, ref CitizenInstance citizenData, Vector3 pos, NetInfo.LaneType laneTypes, VehicleInfo.VehicleType vehicleTypes, bool allowUnderground, out PathUnit.Position position)
 {
     return(CustomPathManager.FindCitizenPathPosition(pos, laneTypes, vehicleTypes, NetInfo.LaneType.None, VehicleInfo.VehicleType.None, (citizenData.m_flags & CitizenInstance.Flags.CannotUseTransport) == CitizenInstance.Flags.None, allowUnderground, out position));
 }
Beispiel #24
0
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, bool undergroundTarget)
        {
#if DEBUG
            //Log._Debug($"CustomBusAI.CustomStartPathFind called for vehicle {vehicleID}");
#endif

            VehicleInfo       info             = this.m_info;
            bool              allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0;
            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             startDistSqrA;
            float             startDistSqrB;
            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float             endDistSqrA;
            float             endDistSqrB;
            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out startDistSqrA, out startDistSqrB) &&
                CustomPathManager.FindPathPosition(endPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, undergroundTarget, false, 32f, out endPosA, out endPosB, out endDistSqrA, out endDistSqrB))
            {
                if (!startBothWays || startDistSqrA < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                if (!endBothWays || endDistSqrA < 10f)
                {
                    endPosB = default(PathUnit.Position);
                }
                uint path;
                // NON-STOCK CODE START
                PathCreationArgs args;
                args.extPathType         = ExtCitizenInstance.ExtPathType.None;
                args.extVehicleType      = ExtVehicleType.Bus;
                args.vehicleId           = vehicleID;
                args.buildIndex          = Singleton <SimulationManager> .instance.m_currentBuildIndex;
                args.startPosA           = startPosA;
                args.startPosB           = startPosB;
                args.endPosA             = endPosA;
                args.endPosB             = endPosB;
                args.vehiclePosition     = default(PathUnit.Position);
                args.laneTypes           = NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle;
                args.vehicleTypes        = info.m_vehicleType;
                args.maxLength           = 20000f;
                args.isHeavyVehicle      = this.IsHeavyVehicle();
                args.hasCombustionEngine = this.CombustionEngine();
                args.ignoreBlocked       = this.IgnoreBlocked(vehicleID, ref vehicleData);
                args.ignoreFlooded       = false;
                args.randomParking       = false;
                args.stablePath          = true;
                args.skipQueue           = true;

                if (CustomPathManager._instance.CreatePath(out path, ref Singleton <SimulationManager> .instance.m_randomizer, args))
                {
                    // NON-STOCK CODE END

                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
Beispiel #25
0
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, bool undergroundTarget)
        {
            if (vehicleData.m_transferType == (byte)TransferManager.TransferReason.Mail)
            {
                return(base.StartPathFind(vehicleID, ref vehicleData, startPos, endPos, startBothWays, endBothWays, undergroundTarget));
            }

            if ((vehicleData.m_flags & (Vehicle.Flags.TransferToSource | Vehicle.Flags.GoingBack)) != 0)
            {
                return(base.StartPathFind(vehicleID, ref vehicleData, startPos, endPos, startBothWays, endBothWays, undergroundTarget));
            }

            bool allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != (Vehicle.Flags) 0;

            PathUnit.Position startPosA     = default(PathUnit.Position);
            PathUnit.Position startPosB     = default(PathUnit.Position);
            float             startDistSqrA = default(float);
            float             startDistSqrB = default(float);

            // try to find road start position
            bool startPosFound = CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, VehicleInfo.VehicleType.Car, allowUnderground, false, 32f, out startPosA, out startPosB, out startDistSqrA, out startDistSqrB);

            // try to find other start position (plane, train, ship)
            PathUnit.Position altStartPosA     = default(PathUnit.Position);
            PathUnit.Position altStartPosB     = default(PathUnit.Position);
            float             altStartDistSqrA = default(float);
            float             altStartDistSqrB = default(float);

            if (PathManager.FindPathPosition(startPos, ItemClass.Service.PublicTransport, NetInfo.LaneType.Vehicle, VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Ship | VehicleInfo.VehicleType.Plane, allowUnderground, false, 32f, out altStartPosA, out altStartPosB, out altStartDistSqrA, out altStartDistSqrB))
            {
                if (!startPosFound || (altStartDistSqrA < startDistSqrA && (Mathf.Abs(startPos.x) > 4800f || Mathf.Abs(startPos.z) > 4800f)))
                {
                    startPosA     = altStartPosA;
                    startPosB     = altStartPosB;
                    startDistSqrA = altStartDistSqrA;
                    startDistSqrB = altStartDistSqrB;
                }
                startPosFound = true;
            }

            PathUnit.Position endPosA     = default(PathUnit.Position);
            PathUnit.Position endPosB     = default(PathUnit.Position);
            float             endDistSqrA = default(float);
            float             endDistSqrB = default(float);

            // try to find road end position
            bool endPosFound = PathManager.FindPathPosition(endPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, VehicleInfo.VehicleType.Car, undergroundTarget, false, 32f, out endPosA, out endPosB, out endDistSqrA, out endDistSqrB);

            // try to find other end position (plane, train, ship)
            PathUnit.Position altEndPosA     = default(PathUnit.Position);
            PathUnit.Position altEndPosB     = default(PathUnit.Position);
            float             altEndDistSqrA = default(float);
            float             altEndDistSqrB = default(float);

            if (PathManager.FindPathPosition(endPos, ItemClass.Service.PublicTransport, NetInfo.LaneType.Vehicle, VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Ship | VehicleInfo.VehicleType.Plane, undergroundTarget, false, 32f, out altEndPosA, out altEndPosB, out altEndDistSqrA, out altEndDistSqrB))
            {
                if (!endPosFound || (altEndDistSqrA < endDistSqrA && (Mathf.Abs(endPos.x) > 4800f || Mathf.Abs(endPos.z) > 4800f)))
                {
                    endPosA     = altEndPosA;
                    endPosB     = altEndPosB;
                    endDistSqrA = altEndDistSqrA;
                    endDistSqrB = altEndDistSqrB;
                }
                endPosFound = true;
            }

            if (startPosFound && endPosFound)
            {
                CustomPathManager pathManager = CustomPathManager._instance;
                if (!startBothWays || startDistSqrA < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                if (!endBothWays || endDistSqrA < 10f)
                {
                    endPosB = default(PathUnit.Position);
                }
                uint path;

                PathCreationArgs args;
                args.extPathType         = ExtCitizenInstance.ExtPathType.None;
                args.extVehicleType      = ExtVehicleType.Service;
                args.vehicleId           = vehicleID;
                args.spawned             = (vehicleData.m_flags & Vehicle.Flags.Spawned) != 0;
                args.buildIndex          = Singleton <SimulationManager> .instance.m_currentBuildIndex;
                args.startPosA           = startPosA;
                args.startPosB           = startPosB;
                args.endPosA             = endPosA;
                args.endPosB             = endPosB;
                args.vehiclePosition     = default(PathUnit.Position);
                args.laneTypes           = NetInfo.LaneType.Vehicle | NetInfo.LaneType.CargoVehicle;
                args.vehicleTypes        = VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Ship | VehicleInfo.VehicleType.Plane;
                args.maxLength           = 20000f;
                args.isHeavyVehicle      = this.IsHeavyVehicle();
                args.hasCombustionEngine = this.CombustionEngine();
                args.ignoreBlocked       = this.IgnoreBlocked(vehicleID, ref vehicleData);
                args.ignoreFlooded       = false;
                args.ignoreCosts         = false;
                args.randomParking       = false;
                args.stablePath          = false;
                args.skipQueue           = (vehicleData.m_flags & Vehicle.Flags.Spawned) != 0;

                if (pathManager.CreatePath(out path, ref Singleton <SimulationManager> .instance.m_randomizer, args))
                {
                    if (vehicleData.m_path != 0)
                    {
                        pathManager.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
        /*private void BaseSimulationStep(ushort vehicleId, ref Vehicle vehicleData, Vector3 physicsLodRefPos) {
         *      if ((vehicleData.m_flags & Vehicle.Flags.WaitingPath) != (Vehicle.Flags)0) {
         *              PathManager instance = Singleton<PathManager>.instance;
         *              byte pathFindFlags = instance.m_pathUnits.m_buffer[(int)((UIntPtr)vehicleData.m_path)].m_pathFindFlags;
         *              if ((pathFindFlags & 4) != 0) {
         *                      vehicleData.m_pathPositionIndex = 255;
         *                      vehicleData.m_flags &= ~Vehicle.Flags.WaitingPath;
         *                      vehicleData.m_flags &= ~Vehicle.Flags.Arriving;
         *                      PathfindSuccess(vehicleId, ref vehicleData);
         *                      TrySpawn(vehicleId, ref vehicleData);
         *                      VehicleStateManager.OnPathFindReady(vehicleId, ref vehicleData); // NON-STOCK CODE
         *              } else if ((pathFindFlags & 8) != 0 || ((pathFindFlags & 1) != 0 && vehicleData.m_blockCounter == 255)) { // NON-STOCK CODE
         *                      vehicleData.m_flags &= ~Vehicle.Flags.WaitingPath;
         *                      Singleton<PathManager>.instance.ReleasePath(vehicleData.m_path);
         *                      vehicleData.m_path = 0u;
         *                      PathfindFailure(vehicleId, ref vehicleData);
         *                      return;
         *              }
         *      } else if ((vehicleData.m_flags & Vehicle.Flags.WaitingSpace) != 0) {
         *              TrySpawn(vehicleId, ref vehicleData);
         *      }
         *
         *      try {
         *              VehicleStateManager.LogTraffic(vehicleId, ref vehicleData, true);
         *      } catch (Exception e) {
         *              Log.Error("CarAI CustomSimulationStep Error: " + e.ToString());
         *      }
         *
         *      try {
         *              VehicleStateManager.UpdateVehiclePos(vehicleId, ref vehicleData);
         *      } catch (Exception e) {
         *              Log.Error("CarAI CustomSimulationStep Error: " + e.ToString());
         *      }
         *
         *      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;
         *      }
         *      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[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 vehicleData, 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 ((vehicleData.m_flags & (Vehicle.Flags.Spawned | Vehicle.Flags.WaitingPath | Vehicle.Flags.WaitingSpace)) ==
         *              0 && vehicleData.m_cargoParent == 0) {
         *              Singleton<VehicleManager>.instance.ReleaseVehicle(vehicleId);
         *      } else if (vehicleData.m_blockCounter >= maxBlockCounter && Options.enableDespawning) {
         *              Singleton<VehicleManager>.instance.ReleaseVehicle(vehicleId);
         *      } else if (vehicleData.m_leadingVehicle == 0 && CustomVehicleAI.ShouldRecalculatePath(vehicleId, ref vehicleData, maxBlockCounter)) {
         *              CustomVehicleAI.MarkPathRecalculation(vehicleId);
         *              InvalidPath(vehicleId, ref vehicleData, vehicleId, ref vehicleData);
         *      }
         * }*/

        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, bool undergroundTarget)
        {
            if ((vehicleData.m_flags & (Vehicle.Flags.TransferToSource | Vehicle.Flags.GoingBack)) != 0)
            {
                return(CustomCargoTruckAI.BaseCustomStartPathFind(this.IsHeavyVehicle(), this.IgnoreBlocked(vehicleID, ref vehicleData), ref this.m_info, vehicleID, ref vehicleData, startPos, endPos, startBothWays, endBothWays));
            }
            bool allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0;

            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             num;
            float             num2;
            bool startPosFound = CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, VehicleInfo.VehicleType.Car, allowUnderground, false, 32f, out startPosA, out startPosB, out num, out num2);

            PathUnit.Position position;
            PathUnit.Position position2;
            float             num3;
            float             num4;

            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.PublicTransport, NetInfo.LaneType.Vehicle, VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Ship, allowUnderground, false, 32f, out position, out position2, out num3, out num4))
            {
                if (!startPosFound || num3 < num)
                {
                    startPosA = position;
                    startPosB = position2;
                    num       = num3;
                    num2      = num4;
                }
                startPosFound = true;
            }
            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float             num5;
            float             num6;
            bool endPosFound = CustomPathManager.FindPathPosition(endPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, VehicleInfo.VehicleType.Car, undergroundTarget, false, 32f, out endPosA, out endPosB, out num5, out num6);

            PathUnit.Position position3;
            PathUnit.Position position4;
            float             num7;
            float             num8;

            if (CustomPathManager.FindPathPosition(endPos, ItemClass.Service.PublicTransport, NetInfo.LaneType.Vehicle, VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Ship, undergroundTarget, false, 32f, out position3, out position4, out num7, out num8))
            {
                if (!endPosFound || num7 < num5)
                {
                    endPosA = position3;
                    endPosB = position4;
                    num5    = num7;
                    num6    = num8;
                }
                endPosFound = true;
            }
            if (startPosFound && endPosFound)
            {
                CustomPathManager instance = Singleton <CustomPathManager> .instance;
                if (!startBothWays || num < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                if (!endBothWays || num5 < 10f)
                {
                    endPosB = default(PathUnit.Position);
                }
                NetInfo.LaneType        laneTypes    = NetInfo.LaneType.Vehicle | NetInfo.LaneType.CargoVehicle;
                VehicleInfo.VehicleType vehicleTypes = VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Ship;
                uint path;
                if (instance.CreatePath(ExtVehicleType.CargoVehicle, out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, ref startPosA, ref startPosB, ref endPosA, ref endPosB, laneTypes, vehicleTypes, 20000f, this.IsHeavyVehicle(), this.IgnoreBlocked(vehicleID, ref vehicleData), false, false))
                {
                    if (vehicleData.m_path != 0u)
                    {
                        instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
Beispiel #27
0
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays)
        {
#if DEBUG
            //Log._Debug($"CustomTramBaseAI.CustomStartPathFind called for vehicle {vehicleID}");
#endif

#if BENCHMARK
            using (var bm = new Benchmark(null, "OnStartPathFind")) {
#endif
            VehicleStateManager.Instance.OnStartPathFind(vehicleID, ref vehicleData, null);
#if BENCHMARK
        }
#endif

            VehicleInfo info = this.m_info;
            bool allowUnderground;
            bool allowUnderground2;
            if (info.m_vehicleType == VehicleInfo.VehicleType.Metro)
            {
                allowUnderground  = true;
                allowUnderground2 = true;
            }
            else
            {
                allowUnderground  = ((vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0);
                allowUnderground2 = false;
            }
            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float startSqrDistA;
            float startSqrDistB;
            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float endSqrDistA;
            float endSqrDistB;
            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out startSqrDistA, out startSqrDistB) &&
                CustomPathManager.FindPathPosition(endPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle, info.m_vehicleType, allowUnderground2, false, 32f, out endPosA, out endPosB, out endSqrDistA, out endSqrDistB))
            {
                if (!startBothWays || startSqrDistB > startSqrDistA * 1.2f)
                {
                    startPosB = default(PathUnit.Position);
                }
                if (!endBothWays || endSqrDistB > endSqrDistA * 1.2f)
                {
                    endPosB = default(PathUnit.Position);
                }
                uint path;
                // NON-STOCK CODE START
                PathCreationArgs args;
                args.extPathType         = ExtCitizenInstance.ExtPathType.None;
                args.extVehicleType      = ExtVehicleType.Tram;
                args.vehicleId           = vehicleID;
                args.buildIndex          = Singleton <SimulationManager> .instance.m_currentBuildIndex;
                args.startPosA           = startPosA;
                args.startPosB           = startPosB;
                args.endPosA             = endPosA;
                args.endPosB             = endPosB;
                args.vehiclePosition     = default(PathUnit.Position);
                args.laneTypes           = NetInfo.LaneType.Vehicle;
                args.vehicleTypes        = info.m_vehicleType;
                args.maxLength           = 20000f;
                args.isHeavyVehicle      = false;
                args.hasCombustionEngine = false;
                args.ignoreBlocked       = this.IgnoreBlocked(vehicleID, ref vehicleData);
                args.ignoreFlooded       = false;
                args.randomParking       = false;
                args.stablePath          = true;
                args.skipQueue           = true;

                if (CustomPathManager._instance.CreatePath(out path, ref Singleton <SimulationManager> .instance.m_randomizer, args))
                {
                    // NON-STOCK CODE END
                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
Beispiel #28
0
        public bool CustomStartPathFind(ushort vehicleId,
                                        ref Vehicle vehicleData,
                                        Vector3 startPos,
                                        Vector3 endPos,
                                        bool startBothWays,
                                        bool endBothWays,
                                        bool undergroundTarget)
        {
            ExtVehicleType vehicleType =
                ExtVehicleManager.Instance.OnStartPathFind(vehicleId, ref vehicleData, null);

            if (vehicleType == ExtVehicleType.None)
            {
                Log._DebugOnlyWarning(
                    $"CustomCargoTruck.CustomStartPathFind: Vehicle {vehicleId} " +
                    $"does not have a valid vehicle type!");
            }

            if ((vehicleData.m_flags & (Vehicle.Flags.TransferToSource
                                        | Vehicle.Flags.GoingBack)) != 0)
            {
                return(base.StartPathFind(
                           vehicleId,
                           ref vehicleData,
                           startPos,
                           endPos,
                           startBothWays,
                           endBothWays,
                           undergroundTarget));
            }

            bool allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground
                                                            | Vehicle.Flags.Transition)) != 0;
            bool startPosFound = PathManager.FindPathPosition(
                startPos,
                ItemClass.Service.Road,
                NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle,
                VehicleInfo.VehicleType.Car,
                allowUnderground,
                false,
                32f,
                out PathUnit.Position startPosA,
                out PathUnit.Position startPosB,
                out float startDistSqrA,
                out _);

            if (PathManager.FindPathPosition(
                    startPos,
                    ItemClass.Service.PublicTransport,
                    NetInfo.LaneType.Vehicle,
                    VehicleInfo.VehicleType.Train
                    | VehicleInfo.VehicleType.Ship
                    | VehicleInfo.VehicleType.Plane,
                    allowUnderground,
                    false,
                    32f,
                    out PathUnit.Position startAltPosA,
                    out PathUnit.Position startAltPosB,
                    out float startAltDistSqrA,
                    out _))
            {
                if (!startPosFound ||
                    (startAltDistSqrA < startDistSqrA &&
                     (Mathf.Abs(endPos.x) > 8000f ||
                      Mathf.Abs(endPos.z) > 8000f)))
                {
                    startPosA     = startAltPosA;
                    startPosB     = startAltPosB;
                    startDistSqrA = startAltDistSqrA;
                }

                startPosFound = true;
            }

            bool endPosFound = PathManager.FindPathPosition(
                endPos,
                ItemClass.Service.Road,
                NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle,
                VehicleInfo.VehicleType.Car,
                undergroundTarget,
                false,
                32f,
                out PathUnit.Position endPosA,
                out PathUnit.Position endPosB,
                out float endDistSqrA,
                out _);

            if (PathManager.FindPathPosition(
                    endPos,
                    ItemClass.Service.PublicTransport,
                    NetInfo.LaneType.Vehicle,
                    VehicleInfo.VehicleType.Train
                    | VehicleInfo.VehicleType.Ship
                    | VehicleInfo.VehicleType.Plane,
                    undergroundTarget,
                    false,
                    32f,
                    out PathUnit.Position endAltPosA,
                    out PathUnit.Position endAltPosB,
                    out float endAltDistSqrA,
                    out _))
            {
                if (!endPosFound ||
                    (endAltDistSqrA < endDistSqrA &&
                     (Mathf.Abs(endPos.x) > 8000f ||
                      Mathf.Abs(endPos.z) > 8000f)))
                {
                    endPosA     = endAltPosA;
                    endPosB     = endAltPosB;
                    endDistSqrA = endAltDistSqrA;
                }

                endPosFound = true;
            }

            if (!startPosFound || !endPosFound)
            {
                return(false);
            }

            CustomPathManager pathMan = CustomPathManager._instance;

            if (!startBothWays || startDistSqrA < 10f)
            {
                startPosB = default;
            }

            if (!endBothWays || endDistSqrA < 10f)
            {
                endPosB = default;
            }

            const NetInfo.LaneType LANE_TYPES = NetInfo.LaneType.Vehicle
                                                | NetInfo.LaneType.CargoVehicle;
            const VehicleInfo.VehicleType VEHICLE_TYPES = VehicleInfo.VehicleType.Car
                                                          | VehicleInfo.VehicleType.Train
                                                          | VehicleInfo.VehicleType.Ship
                                                          | VehicleInfo.VehicleType.Plane;

            // NON-STOCK CODE START
            PathCreationArgs args;

            args.extPathType         = ExtPathType.None;
            args.extVehicleType      = ExtVehicleType.CargoVehicle;
            args.vehicleId           = vehicleId;
            args.spawned             = (vehicleData.m_flags & Vehicle.Flags.Spawned) != 0;
            args.buildIndex          = Singleton <SimulationManager> .instance.m_currentBuildIndex;
            args.startPosA           = startPosA;
            args.startPosB           = startPosB;
            args.endPosA             = endPosA;
            args.endPosB             = endPosB;
            args.vehiclePosition     = default;
            args.laneTypes           = LANE_TYPES;
            args.vehicleTypes        = VEHICLE_TYPES;
            args.maxLength           = 20000f;
            args.isHeavyVehicle      = IsHeavyVehicle();
            args.hasCombustionEngine = CombustionEngine();
            args.ignoreBlocked       = IgnoreBlocked(vehicleId, ref vehicleData);
            args.ignoreFlooded       = false;
            args.ignoreCosts         = false;
            args.randomParking       = false;
            args.stablePath          = false;
            args.skipQueue           = (vehicleData.m_flags & Vehicle.Flags.Spawned) != 0;

            if (!pathMan.CustomCreatePath(
                    out uint path,
                    ref Singleton <SimulationManager> .instance.m_randomizer,
                    args))
            {
                return(false);
            }

            // NON-STOCK CODE END
            if (vehicleData.m_path != 0u)
            {
                pathMan.ReleasePath(vehicleData.m_path);
            }

            vehicleData.m_path   = path;
            vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
            return(true);
        }
Beispiel #29
0
    class CustomTransportLineAI : TransportLineAI {     // TODO inherit from NetAI (in order to keep the correct references to `base`)
        public static bool CustomStartPathFind(ushort segmentID, ref NetSegment data, ItemClass.Service netService, ItemClass.Service netService2, VehicleInfo.VehicleType vehicleType, bool skipQueue)
        {
            if (data.m_path != 0u)
            {
                Singleton <PathManager> .instance.ReleasePath(data.m_path);

                data.m_path = 0u;
            }
            NetManager netManager = Singleton <NetManager> .instance;

            if ((netManager.m_nodes.m_buffer[(int)data.m_startNode].m_flags & NetNode.Flags.Ambiguous) != NetNode.Flags.None)
            {
                for (int i = 0; i < 8; i++)
                {
                    ushort segment = netManager.m_nodes.m_buffer[(int)data.m_startNode].GetSegment(i);
                    if (segment != 0 && segment != segmentID && netManager.m_segments.m_buffer[(int)segment].m_path != 0u)
                    {
                        return(true);
                    }
                }
            }
            if ((netManager.m_nodes.m_buffer[(int)data.m_endNode].m_flags & NetNode.Flags.Ambiguous) != NetNode.Flags.None)
            {
                for (int j = 0; j < 8; j++)
                {
                    ushort segment2 = netManager.m_nodes.m_buffer[(int)data.m_endNode].GetSegment(j);
                    if (segment2 != 0 && segment2 != segmentID && netManager.m_segments.m_buffer[(int)segment2].m_path != 0u)
                    {
                        return(true);
                    }
                }
            }
            Vector3 position  = netManager.m_nodes.m_buffer[(int)data.m_startNode].m_position;
            Vector3 position2 = netManager.m_nodes.m_buffer[(int)data.m_endNode].m_position;

#if DEBUG
            bool debug = GlobalConfig.Instance.Debug.Switches[18];
            if (debug)
            {
                Log._Debug($"TransportLineAI.CustomStartPathFind({segmentID}, ..., {netService}, {netService2}, {vehicleType}, {skipQueue}): startNode={data.m_startNode} @ {position}, endNode={data.m_endNode} @ {position2} -- line: {netManager.m_nodes.m_buffer[(int)data.m_startNode].m_transportLine}/{netManager.m_nodes.m_buffer[(int)data.m_endNode].m_transportLine}");
            }
#endif
            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             startSqrDistA;
            float             startSqrDistB;
            if (!CustomPathManager.FindPathPosition(position, netService, netService2, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, vehicleType, true, false, 32f, out startPosA, out startPosB, out startSqrDistA, out startSqrDistB))
            {
                CustomTransportLineAI.CheckSegmentProblems(segmentID, ref data);
                return(true);
            }
            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float             endSqrDistA;
            float             endSqrDistB;
            if (!CustomPathManager.FindPathPosition(position2, netService, netService2, NetInfo.LaneType.Pedestrian, VehicleInfo.VehicleType.None, vehicleType, true, false, 32f, out endPosA, out endPosB, out endSqrDistA, out endSqrDistB))
            {
                CustomTransportLineAI.CheckSegmentProblems(segmentID, ref data);
                return(true);
            }
            if ((netManager.m_nodes.m_buffer[(int)data.m_startNode].m_flags & NetNode.Flags.Fixed) != NetNode.Flags.None)
            {
                startPosB = default(PathUnit.Position);
            }
            if ((netManager.m_nodes.m_buffer[(int)data.m_endNode].m_flags & NetNode.Flags.Fixed) != NetNode.Flags.None)
            {
                endPosB = default(PathUnit.Position);
            }
            startPosA.m_offset = 128;
            startPosB.m_offset = 128;
            endPosA.m_offset   = 128;
            endPosB.m_offset   = 128;
            bool stopLane  = CustomTransportLineAI.GetStopLane(ref startPosA, vehicleType);
            bool stopLane2 = CustomTransportLineAI.GetStopLane(ref startPosB, vehicleType);
            bool stopLane3 = CustomTransportLineAI.GetStopLane(ref endPosA, vehicleType);
            bool stopLane4 = CustomTransportLineAI.GetStopLane(ref endPosB, vehicleType);
            if ((!stopLane && !stopLane2) || (!stopLane3 && !stopLane4))
            {
                CustomTransportLineAI.CheckSegmentProblems(segmentID, ref data);
                return(true);
            }

            ExtVehicleType extVehicleType = ExtVehicleType.Bus;
            if ((vehicleType & (VehicleInfo.VehicleType.Train | VehicleInfo.VehicleType.Metro | VehicleInfo.VehicleType.Monorail)) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.PassengerTrain;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Tram) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.Tram;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Ship) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.PassengerShip;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Plane) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.PassengerPlane;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Ferry) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.Ferry;
            }
            if ((vehicleType & VehicleInfo.VehicleType.Blimp) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.Blimp;
            }
            if ((vehicleType & VehicleInfo.VehicleType.CableCar) != VehicleInfo.VehicleType.None)
            {
                extVehicleType = ExtVehicleType.CableCar;
            }
            //Log._Debug($"Transport line. extVehicleType={extVehicleType}");
            uint path;
            if (CustomPathManager._instance.CreatePath(extVehicleType, 0, ExtCitizenInstance.ExtPathType.None, out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, vehicleType, 20000f, false, true, true, skipQueue))
            {
                if (startPosA.m_segment != 0 && startPosB.m_segment != 0)
                {
                    netManager.m_nodes.m_buffer[data.m_startNode].m_flags |= NetNode.Flags.Ambiguous;
                }
                else
                {
                    netManager.m_nodes.m_buffer[data.m_startNode].m_flags &= ~NetNode.Flags.Ambiguous;
                }
                if (endPosA.m_segment != 0 && endPosB.m_segment != 0)
                {
                    netManager.m_nodes.m_buffer[data.m_endNode].m_flags |= NetNode.Flags.Ambiguous;
                }
                else
                {
                    netManager.m_nodes.m_buffer[data.m_endNode].m_flags &= ~NetNode.Flags.Ambiguous;
                }
                data.m_path   = path;
                data.m_flags |= NetSegment.Flags.WaitingPath;
#if DEBUG
                if (debug)
                {
                    Log._Debug($"TransportLineAI.CustomStartPathFind({segmentID}, ..., {netService}, {netService2}, {vehicleType}, {skipQueue}): Started calculating path {path} for extVehicleType={extVehicleType}, startPosA=[seg={startPosA.m_segment}, lane={startPosA.m_lane}, off={startPosA.m_offset}], startPosB=[seg={startPosB.m_segment}, lane={startPosB.m_lane}, off={startPosB.m_offset}], endPosA=[seg={endPosA.m_segment}, lane={endPosA.m_lane}, off={endPosA.m_offset}], endPosB=[seg={endPosB.m_segment}, lane={endPosB.m_lane}, off={endPosB.m_offset}]");
                }
#endif
                return(false);
            }
            CustomTransportLineAI.CheckSegmentProblems(segmentID, ref data);
            return(true);
        }
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays, bool undergroundTarget)
        {
#if DEBUG
            bool vehDebug  = GlobalConfig.Instance.Debug.VehicleId == 0 || GlobalConfig.Instance.Debug.VehicleId == vehicleID;
            bool debug     = GlobalConfig.Instance.Debug.Switches[2] && vehDebug;
            bool fineDebug = GlobalConfig.Instance.Debug.Switches[4] && vehDebug;

            if (debug)
            {
                Log.Warning($"CustomCarAI.CustomStartPathFind({vehicleID}): called for vehicle {vehicleID}, startPos={startPos}, endPos={endPos}, startBothWays={startBothWays}, endBothWays={endBothWays}, undergroundTarget={undergroundTarget}");
            }
#endif

            ExtVehicleType vehicleType = ExtVehicleType.None;
#if BENCHMARK
            using (var bm = new Benchmark(null, "OnStartPathFind")) {
#endif
            vehicleType = VehicleStateManager.Instance.OnStartPathFind(vehicleID, ref vehicleData, null);
            if (vehicleType == ExtVehicleType.None)
            {
#if DEBUG
                Log.Warning($"CustomCarAI.CustomStartPathFind({vehicleID}): Vehicle {vehicleID} does not have a valid vehicle type!");
#endif
                vehicleType = ExtVehicleType.RoadVehicle;
            }
#if BENCHMARK
        }
#endif
            VehicleInfo info      = this.m_info;
            bool allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0;
            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float startDistSqrA;
            float startDistSqrB;
            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float endDistSqrA;
            float endDistSqrB;
            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out startDistSqrA, out startDistSqrB) &&
                CustomPathManager.FindPathPosition(endPos, ItemClass.Service.Road, NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle, info.m_vehicleType, undergroundTarget, false, 32f, out endPosA, out endPosB, out endDistSqrA, out endDistSqrB))
            {
                if (!startBothWays || startDistSqrA < 10f)
                {
                    startPosB = default(PathUnit.Position);
                }
                if (!endBothWays || endDistSqrA < 10f)
                {
                    endPosB = default(PathUnit.Position);
                }
                uint path;

                // NON-STOCK CODE START
                PathCreationArgs args;
                args.extPathType         = ExtCitizenInstance.ExtPathType.None;
                args.extVehicleType      = vehicleType;
                args.vehicleId           = vehicleID;
                args.buildIndex          = Singleton <SimulationManager> .instance.m_currentBuildIndex;
                args.startPosA           = startPosA;
                args.startPosB           = startPosB;
                args.endPosA             = endPosA;
                args.endPosB             = endPosB;
                args.vehiclePosition     = default(PathUnit.Position);
                args.laneTypes           = NetInfo.LaneType.Vehicle | NetInfo.LaneType.TransportVehicle;
                args.vehicleTypes        = info.m_vehicleType;
                args.maxLength           = 20000f;
                args.isHeavyVehicle      = this.IsHeavyVehicle();
                args.hasCombustionEngine = this.CombustionEngine();
                args.ignoreBlocked       = this.IgnoreBlocked(vehicleID, ref vehicleData);
                args.ignoreFlooded       = false;
                args.ignoreCosts         = false;
                args.randomParking       = false;
                args.stablePath          = false;
                args.skipQueue           = (vehicleData.m_flags & Vehicle.Flags.Spawned) != 0;

                if (CustomPathManager._instance.CreatePath(out path, ref Singleton <SimulationManager> .instance.m_randomizer, args))
                {
#if DEBUG
                    if (debug)
                    {
                        Log._Debug($"CustomCarAI.CustomStartPathFind({vehicleID}): Path-finding starts for vehicle {vehicleID}, path={path}, extVehicleType={vehicleType}, startPosA.segment={startPosA.m_segment}, startPosA.lane={startPosA.m_lane}, info.m_vehicleType={info.m_vehicleType}, endPosA.segment={endPosA.m_segment}, endPosA.lane={endPosA.m_lane}");
                    }
#endif

                    // NON-STOCK CODE END
                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }
Beispiel #31
0
        public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vector3 startPos, Vector3 endPos, bool startBothWays, bool endBothWays)
        {
            /// NON-STOCK CODE START ///
            ExtVehicleType?vehicleType = CustomVehicleAI.DetermineVehicleTypeFromVehicle(vehicleID, ref vehicleData);
            //Log._Debug($"CustomTrainAI.CustomStartPathFind. vehicleID={vehicleID}. type={this.GetType().ToString()} vehicleType={vehicleType}");
            /// NON-STOCK CODE END ///

            VehicleInfo info = this.m_info;

            if ((vehicleData.m_flags & Vehicle.Flags.Spawned) == Vehicle.Flags.None && Vector3.Distance(startPos, endPos) < 100f)
            {
                startPos = endPos;
            }
            bool allowUnderground;
            bool allowUnderground2;

            if (info.m_vehicleType == VehicleInfo.VehicleType.Metro)
            {
                allowUnderground  = true;
                allowUnderground2 = true;
            }
            else
            {
                allowUnderground  = ((vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != Vehicle.Flags.None);
                allowUnderground2 = false;
            }
            PathUnit.Position startPosA;
            PathUnit.Position startPosB;
            float             num;
            float             num2;

            PathUnit.Position endPosA;
            PathUnit.Position endPosB;
            float             num3;
            float             num4;

            if (CustomPathManager.FindPathPosition(startPos, ItemClass.Service.PublicTransport, NetInfo.LaneType.Vehicle, info.m_vehicleType, allowUnderground, false, 32f, out startPosA, out startPosB, out num, out num2) &&
                CustomPathManager.FindPathPosition(endPos, ItemClass.Service.PublicTransport, NetInfo.LaneType.Vehicle, info.m_vehicleType, allowUnderground2, false, 32f, out endPosA, out endPosB, out num3, out num4))
            {
                if (!startBothWays || num2 > num * 1.2f)
                {
                    startPosB = default(PathUnit.Position);
                }
                if (!endBothWays || num4 > num3 * 1.2f)
                {
                    endPosB = default(PathUnit.Position);
                }
                uint path;
                bool res = false;
                if (vehicleType == null)
                {
                    res = Singleton <PathManager> .instance.CreatePath(out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, NetInfo.LaneType.Vehicle, info.m_vehicleType, 20000f, false, false, true, false);
                }
                else
                {
                    res = Singleton <CustomPathManager> .instance.CreatePath((ExtVehicleType)vehicleType, out path, ref Singleton <SimulationManager> .instance.m_randomizer, Singleton <SimulationManager> .instance.m_currentBuildIndex, startPosA, startPosB, endPosA, endPosB, NetInfo.LaneType.Vehicle, info.m_vehicleType, 20000f, false, false, true, false);
                }
                if (res)
                {
                    if (vehicleData.m_path != 0u)
                    {
                        Singleton <PathManager> .instance.ReleasePath(vehicleData.m_path);
                    }
                    vehicleData.m_path   = path;
                    vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
                    return(true);
                }
            }
            return(false);
        }