/// <summary>
        /// Reset all data structures.
        /// </summary>
        public static void Clear()
        {
            m_data.Clear();

            // Somewhat hacky, sticking this call in here ...
            OutsideConnectionInfo.Reload();
        }
        public static bool Prefix(TransferManager.TransferReason material, ref TransferManager.TransferOffer offer)
        {
            Logger.LogMaterial($"TransferManager::AddIncomingOffer: {Utils.ToString(ref offer, material)}!", material);

            // Inactive outside connections should not be adding offers ...
            if (OutsideConnectionInfo.IsInvalidIncomingOutsideConnection(offer.Building))
            {
                Logger.LogMaterial($"TransferManager::AddIncomingOffer: Disallowing outside connection B{offer.Building} because of missing cargo buildings!", material);
                return(false);
            }

            if (!(TransferManagerInfo.IsDistrictOffer(material) || TransferManagerInfo.IsSupplyChainOffer(material)))
            {
                // Fix for certain assets that have sub buildings that should not be making offers ...
                if (offer.Building != 0 && BuildingManager.instance.m_buildings.m_buffer[offer.Building].m_parentBuilding != 0)
                {
                    if (material == TransferManager.TransferReason.ParkMaintenance)
                    {
                        Logger.LogMaterial($"TransferManager::AddIncomingOffer: Filtering out subBuilding {Utils.ToString(ref offer, material)}!", material);
                        return(false);
                    }
                }

                return(true);
            }

            if (material == TransferManager.TransferReason.Taxi && offer.Citizen != 0)
            {
                var instance       = CitizenManager.instance.m_citizens.m_buffer[offer.Citizen].m_instance;
                var targetBuilding = CitizenManager.instance.m_instances.m_buffer[instance].m_targetBuilding;
                var targetPosition = BuildingManager.instance.m_buildings.m_buffer[targetBuilding].m_position;

                if (!TaxiMod.CanUseTaxis(offer.Position, targetPosition))
                {
                    Logger.LogMaterial($"TransferManager::AddIncomingOffer: Filtering out {Utils.ToString(ref offer, material)}!", material);
                    var instanceId = CitizenManager.instance.m_citizens.m_buffer[offer.Citizen].m_instance;
                    CitizenManager.instance.m_instances.m_buffer[instanceId].m_flags      &= ~CitizenInstance.Flags.WaitingTaxi;
                    CitizenManager.instance.m_instances.m_buffer[instanceId].m_flags      |= CitizenInstance.Flags.BoredOfWaiting;
                    CitizenManager.instance.m_instances.m_buffer[instanceId].m_flags      |= CitizenInstance.Flags.CannotUseTaxi;
                    CitizenManager.instance.m_instances.m_buffer[instanceId].m_waitCounter = byte.MaxValue;
                    return(false);
                }
            }

            TransferManagerAddOffer.ModifyOffer(material, ref offer);
            return(true);
        }
        public static bool Prefix(ref TransferManager.TransferReason material, ref TransferManager.TransferOffer offer)
        {
            Logger.LogMaterial($"TransferManager::AddOutgoingOffer: {Utils.ToString(ref offer, material)}!", material);

            // Inactive outside connections should not be adding offers ...
            if (OutsideConnectionInfo.IsInvalidOutgoingOutsideConnection(offer.Building))
            {
                Logger.LogMaterial($"TransferManager::AddOutgoingOffer: Disallowing outside connection B{offer.Building} because of missing cargo buildings!", material);
                return(false);
            }

            // Change these offers ... a bug in the base game.  Citizens should not offer health care services.
            if ((material == TransferManager.TransferReason.ElderCare || material == TransferManager.TransferReason.ChildCare) && offer.Citizen != 0)
            {
                offer.Active = true;
                TransferManager.instance.AddIncomingOffer(material, offer);
                return(false);
            }

            // Too many requests for helicopters ...
            if (material == TransferManager.TransferReason.Sick2)
            {
                if (Singleton <SimulationManager> .instance.m_randomizer.Int32(10U) != 0)
                {
                    material = TransferManager.TransferReason.Sick;
                }
            }

            if (!(TransferManagerInfo.IsDistrictOffer(material) || TransferManagerInfo.IsSupplyChainOffer(material)))
            {
                // Fix for certain assets that have sub buildings that should not be making offers ...
                if (offer.Building != 0 && BuildingManager.instance.m_buildings.m_buffer[offer.Building].m_parentBuilding != 0)
                {
                    if (material == TransferManager.TransferReason.ParkMaintenance)
                    {
                        Logger.LogMaterial($"TransferManager::AddOutgoingOffer: Filtering out subBuilding {Utils.ToString(ref offer, material)}!", material);
                        return(false);
                    }
                }

                return(true);
            }

            TransferManagerAddOffer.ModifyOffer(material, ref offer);
            return(true);
        }
        public static bool Prefix(ushort vehicleID, ref Vehicle vehicleData, ref bool __result)
        {
            ushort outsideRoadConnection = OutsideConnectionInfo.FindNearestOutsideRoadConnection(ref vehicleData.m_segment);

            if (outsideRoadConnection == 0)
            {
                return(true);
            }

            if ((vehicleData.m_flags & Vehicle.Flags.Spawned) != 0)
            {
                __result = true;
                return(false);
            }

            bool spawnVehicle = false;

            // If in the process of spawning next batch of vehicles ...
            if (m_vehicleSpawnCounter[outsideRoadConnection] >= 0)
            {
                if (vehicleID >= m_vehicleSpawnCounter[outsideRoadConnection])
                {
                    m_vehicleSpawnCounter[outsideRoadConnection] = vehicleID;
                }
                else
                {
                    var counter = vehicleID;
                    while (counter < m_vehicleSpawnCounter[outsideRoadConnection])
                    {
                        counter += VehicleManager.MAX_VEHICLE_COUNT;
                    }

                    m_vehicleSpawnCounter[outsideRoadConnection] = counter;
                }

                spawnVehicle = true;

                if (m_vehicleSpawnCounter[outsideRoadConnection] >= 2 * VehicleManager.MAX_VEHICLE_COUNT)
                {
                    // Logger.Log($"CarAI::TrySpawn: (batch spawn end) source={outsideRoadConnection}");
                    m_vehicleSpawnCounter[outsideRoadConnection] = -1;
                }
            }
            else if (CheckOverlap(vehicleData.m_segment, (ushort)0, 1000f))
            {
                m_congestionStatus[outsideRoadConnection] = true;
                vehicleData.m_flags |= Vehicle.Flags.WaitingSpace;
            }
            else
            {
                spawnVehicle = true;

                // It was previously congested ... setup the vehicleSpawnCounter
                if (m_congestionStatus[outsideRoadConnection])
                {
                    // Logger.Log($"CarAI::TrySpawn: (batch spawn start) source={outsideRoadConnection}");
                    m_congestionStatus[outsideRoadConnection]    = false;
                    m_vehicleSpawnCounter[outsideRoadConnection] = vehicleID;
                }
            }

            if (spawnVehicle)
            {
                vehicleData.Spawn(vehicleID);
                vehicleData.m_flags &= Vehicle.Flags.Created | Vehicle.Flags.Deleted | Vehicle.Flags.Spawned | Vehicle.Flags.Inverted | Vehicle.Flags.TransferToTarget | Vehicle.Flags.TransferToSource | Vehicle.Flags.Emergency1 | Vehicle.Flags.Emergency2 | Vehicle.Flags.WaitingPath | Vehicle.Flags.Stopped | Vehicle.Flags.Leaving | Vehicle.Flags.Arriving | Vehicle.Flags.Reversed | Vehicle.Flags.TakingOff | Vehicle.Flags.Flying | Vehicle.Flags.Landing | Vehicle.Flags.WaitingCargo | Vehicle.Flags.GoingBack | Vehicle.Flags.WaitingTarget | Vehicle.Flags.Importing | Vehicle.Flags.Exporting | Vehicle.Flags.Parking | Vehicle.Flags.CustomName | Vehicle.Flags.OnGravel | Vehicle.Flags.WaitingLoading | Vehicle.Flags.Congestion | Vehicle.Flags.DummyTraffic | Vehicle.Flags.Underground | Vehicle.Flags.Transition | Vehicle.Flags.InsideBuilding | Vehicle.Flags.LeftHandDrive;

                __result = true;
                return(false);
            }

            __result = false;
            return(false);
        }