/// <summary>
 /// Copied from original game code at game version 1.5.0-f4.
 /// </summary>
 /// <param name="ambulanceAI">The ambulance AI.</param>
 /// <param name="vehicleID">The vehicle identifier.</param>
 /// <param name="data">The data.</param>
 /// <returns>True if vehicle should return to source.</returns>
 private static bool AmbulanceAI_ShouldReturnToSource_Original(AmbulanceAI ambulanceAI, ushort vehicleID, ref Vehicle data)
 {
     if ((int)data.m_sourceBuilding != 0)
     {
         BuildingManager instance = Singleton <BuildingManager> .instance;
         if ((instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_flags & Building.Flags.Active) == Building.Flags.None && (int)instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_fireIntensity == 0)
         {
             return(true);
         }
     }
     return(false);
 }
 public static bool Prefix(ref AmbulanceAI __instance, ushort vehicleID, ref Vehicle data, TransferManager.TransferReason material, TransferManager.TransferOffer offer)
 {
     if (material == (TransferManager.TransferReason)data.m_transferType)
     {
         if ((data.m_flags & Vehicle.Flags.WaitingTarget) != (Vehicle.Flags) 0)
         {
             if (offer.Building != 0)
             {
                 __instance.SetTarget(vehicleID, ref data, offer.Building);
                 return(false);
             }
         }
     }
     return(true);
 }
        /// <summary>
        /// Vehicles with no target should always return to source.
        /// </summary>
        /// <param name="ambulanceAI">The ambulance AI.</param>
        /// <param name="vehicleId">The vehicle identifier.</param>
        /// <param name="vehicle">The vehicle.</param>
        /// <returns>True if vehicle should return to source.</returns>
        private static bool AmbulanceAI_ShouldReturnToSource_Override(AmbulanceAI ambulanceAI, ushort vehicleId, ref Vehicle vehicle)
        {
            Calls++;
            if (vehicle.m_sourceBuilding == 0)
            {
                return(false);
            }

            if (vehicle.m_targetBuilding == 0 && (vehicle.m_flags & Vehicle.Flags.TransferToTarget) == ~VehicleHelper.VehicleAll)
            {
                BuildingManager instance = Singleton <BuildingManager> .instance;
                if (instance.m_buildings.m_buffer[vehicle.m_sourceBuilding].m_fireIntensity == 0)
                {
                    return(true);
                }
            }

            return(AmbulanceAI_ShouldReturnToSource_Original(ambulanceAI, vehicleId, ref vehicle));
        }
        /// <summary>
        /// Vehicles with no target should always return to source.
        /// </summary>
        /// <param name="ambulanceAI">The ambulance AI.</param>
        /// <param name="vehicleId">The vehicle identifier.</param>
        /// <param name="vehicle">The vehicle.</param>
        /// <returns>True if vehicle should return to source.</returns>
        private static bool AmbulanceAI_ShouldReturnToSource_Override(AmbulanceAI ambulanceAI, ushort vehicleId, ref Vehicle vehicle)
        {
            Calls++;
            if (vehicle.m_sourceBuilding == 0)
            {
                return false;
            }

            if (vehicle.m_targetBuilding == 0 && (vehicle.m_flags & Vehicle.Flags.TransferToTarget) == ~Vehicle.Flags.All)
            {
                BuildingManager instance = Singleton<BuildingManager>.instance;
                if (instance.m_buildings.m_buffer[vehicle.m_sourceBuilding].m_fireIntensity == 0)
                {
                    return true;
                }
            }

            return AmbulanceAI_ShouldReturnToSource_Original(ambulanceAI, vehicleId, ref vehicle);
        }
 /// <summary>
 /// Copied from original game code at game version 1.5.0-f4.
 /// </summary>
 /// <param name="ambulanceAI">The ambulance AI.</param>
 /// <param name="vehicleID">The vehicle identifier.</param>
 /// <param name="data">The data.</param>
 /// <returns>True if vehicle should return to source.</returns>
 private static bool AmbulanceAI_ShouldReturnToSource_Original(AmbulanceAI ambulanceAI, ushort vehicleID, ref Vehicle data)
 {
     if ((int)data.m_sourceBuilding != 0)
     {
         BuildingManager instance = Singleton<BuildingManager>.instance;
         if ((instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_flags & Building.Flags.Active) == Building.Flags.None && (int)instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_fireIntensity == 0)
             return true;
     }
     return false;
 }
        public static bool Prefix(ref AmbulanceAI __instance, ushort vehicleID, ref Vehicle data, ref bool __result)
        {
            if (Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)data.m_targetBuilding].m_flags.IsFlagSet(Building.Flags.Untouchable))
            {
                if (data.m_targetBuilding == 0)
                {
                    Singleton <VehicleManager> .instance.ReleaseVehicle(vehicleID);

                    __result = true;
                }

                int          num  = Mathf.Min(0, (int)data.m_transferSize - __instance.m_patientCapacity);
                BuildingInfo info = Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)data.m_targetBuilding].Info;
                info.m_buildingAI.ModifyMaterialBuffer(data.m_targetBuilding, ref Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)data.m_targetBuilding], (TransferManager.TransferReason)data.m_transferType, ref num);
                var instance = Singleton <BuildingManager> .instance;

                if (instance.m_buildings.m_buffer[(int)data.m_targetBuilding].Info.m_buildingAI is OutsideConnectionAI)
                {
                    if (Loader.isRealCityRunning)
                    {
                        double x = instance.m_buildings.m_buffer[(int)data.m_targetBuilding].m_position.x - instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_position.x;
                        double z = instance.m_buildings.m_buffer[(int)data.m_targetBuilding].m_position.z - instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_position.z;
                        x = (x > 0) ? x : -x;
                        z = (z > 0) ? z : -z;
                        double distance = (x + z);
                        int    money    = (int)(-num * distance * 2f);
                        Singleton <EconomyManager> .instance.AddPrivateIncome(money, ItemClass.Service.HealthCare, ItemClass.SubService.None, ItemClass.Level.Level3, 115333);

                        CustomPlayerBuildingAI.canReturn[vehicleID] = true;
                        if (Loader.isRealCityV10)
                        {
                            RealCityUtil.InitDelegate();
                            if (RealCityUtil.GetRealCityV10())
                            {
                                RealCityUtil.SetOutsideGovermentMoney(RealCityUtil.GetOutsideGovermentMoney() - money);
                            }
                        }
                    }
                }

                if ((instance.m_buildings.m_buffer[(int)data.m_targetBuilding].m_flags & Building.Flags.IncomingOutgoing) == Building.Flags.Incoming)
                {
                    ushort num3 = instance.FindBuilding(instance.m_buildings.m_buffer[(int)data.m_targetBuilding].m_position, 200f, info.m_class.m_service, ItemClass.SubService.None, Building.Flags.Outgoing, Building.Flags.Incoming);
                    if (num3 != 0)
                    {
                        BuildingInfo info3      = instance.m_buildings.m_buffer[(int)num3].Info;
                        Randomizer   randomizer = new Randomizer((int)vehicleID);
                        Vector3      vector;
                        Vector3      vector2;
                        info3.m_buildingAI.CalculateSpawnPosition(num3, ref instance.m_buildings.m_buffer[(int)num3], ref randomizer, __instance.m_info, out vector, out vector2);
                        Quaternion rotation = Quaternion.identity;
                        Vector3    forward  = vector2 - vector;
                        if (forward.sqrMagnitude > 0.01f)
                        {
                            rotation = Quaternion.LookRotation(forward);
                        }
                        data.m_frame0       = new Vehicle.Frame(vector, rotation);
                        data.m_frame1       = data.m_frame0;
                        data.m_frame2       = data.m_frame0;
                        data.m_frame3       = data.m_frame0;
                        data.m_targetPos0   = vector;
                        data.m_targetPos0.w = 2f;
                        data.m_targetPos1   = vector2;
                        data.m_targetPos1.w = 2f;
                        data.m_targetPos2   = data.m_targetPos1;
                        data.m_targetPos3   = data.m_targetPos1;
                        __instance.FrameDataUpdated(vehicleID, ref data, ref data.m_frame0);
                        __instance.SetTarget(vehicleID, ref data, 0);
                        __result = false;
                    }
                }
                return(false);
            }
            return(true);
        }