/// <summary> /// Starts the transfer. /// </summary> /// <param name="vehicleId">The vehicle identifier.</param> /// <param name="vehicle">The vehicle.</param> /// <param name="material">The material.</param> /// <param name="targetBuildingId">The target building identifier.</param> /// <param name="targetCitizenId">The target citizen identifier.</param> /// <returns>True on success.</returns> private static bool StartTransfer(ushort vehicleId, ref Vehicle vehicle, TransferManager.TransferReason material, ushort targetBuildingId, uint targetCitizenId) { TransferManager.TransferOffer offer = TransferManagerHelper.MakeOffer(targetBuildingId, targetCitizenId); vehicle.m_flags &= ~Vehicle.Flags.GoingBack; vehicle.m_flags |= Vehicle.Flags.WaitingTarget; // Cast AI as games original AI so detoured methods are called, but not methods from not replaced classes. if (Global.Settings.AssignmentCompatibilityMode == ServiceDispatcherSettings.ModCompatibilityMode.UseInstanciatedClassMethods || !Global.Settings.AllowReflection()) { vehicle.Info.m_vehicleAI.StartTransfer(vehicleId, ref vehicle, material, offer); } else if (vehicle.Info.m_vehicleAI is HearseAI) { ((HearseAI)vehicle.Info.m_vehicleAI.CastTo <HearseAI>()).StartTransfer(vehicleId, ref vehicle, material, offer); } else if (vehicle.Info.m_vehicleAI is GarbageTruckAI) { ((GarbageTruckAI)vehicle.Info.m_vehicleAI.CastTo <GarbageTruckAI>()).StartTransfer(vehicleId, ref vehicle, material, offer); } else if (vehicle.Info.m_vehicleAI is AmbulanceAI) { ((AmbulanceAI)vehicle.Info.m_vehicleAI.CastTo <AmbulanceAI>()).StartTransfer(vehicleId, ref vehicle, material, offer); } else { vehicle.Info.m_vehicleAI.StartTransfer(vehicleId, ref vehicle, material, offer); } if (vehicle.m_targetBuilding == targetBuildingId && (targetCitizenId == 0 || Singleton <CitizenManager> .instance.m_citizens.m_buffer[targetCitizenId].m_vehicle == vehicleId)) { return(true); } Log.Warning(typeof(VehicleHelper), "StartTransfer", "Target Not Assigned", vehicleId, targetBuildingId, targetCitizenId, material, vehicle.m_sourceBuilding, vehicle.m_targetBuilding, (TransferManager.TransferReason)vehicle.m_transferType, vehicle.m_flags); return(false); }
/// <summary> /// Starts the transfer. /// </summary> /// <param name="serviceBuildingId">The building identifier.</param> /// <param name="building">The building.</param> /// <param name="material">The material.</param> /// <param name="targetBuildingId">The target building identifier.</param> /// <param name="targetCitizenId">The target citizen identifier.</param> /// <param name="vehicleId">The vehicle identifier.</param> /// <returns>Vehicle info for the created vehicle.</returns> public static VehicleInfo StartTransfer(ushort serviceBuildingId, ref Building building, TransferManager.TransferReason material, ushort targetBuildingId, uint targetCitizenId, out ushort vehicleId) { if (building.Info.m_buildingAI is HospitalAI && targetCitizenId == 0) { return(VehicleHelper.CreateServiceVehicle(serviceBuildingId, material, targetBuildingId, targetCitizenId, out vehicleId)); } Vehicle[] vehicles = Singleton <VehicleManager> .instance.m_vehicles.m_buffer; Citizen[] citizens = Singleton <CitizenManager> .instance.m_citizens.m_buffer; TransferManager.TransferOffer offer = TransferManagerHelper.MakeOffer(targetBuildingId, targetCitizenId); int count; HashSet <ushort> ownVehicles = new HashSet <ushort>(); count = 0; vehicleId = building.m_ownVehicles; while (vehicleId != 0) { ownVehicles.Add(vehicleId); if (count >= ushort.MaxValue) { throw new Exception("Loop counter too high"); } count++; vehicleId = vehicles[vehicleId].m_nextOwnVehicle; } // Cast AI as games original AI so detoured methods are called, but not methods from not replaced classes. if (Global.Settings.CreationCompatibilityMode == ServiceDispatcherSettings.ModCompatibilityMode.UseInstanciatedClassMethods || !Global.Settings.AllowReflection()) { building.Info.m_buildingAI.StartTransfer(serviceBuildingId, ref building, material, offer); } else if (building.Info.m_buildingAI is CemeteryAI) { ((CemeteryAI)building.Info.m_buildingAI.CastTo <CemeteryAI>()).StartTransfer(serviceBuildingId, ref building, material, offer); } else if (building.Info.m_buildingAI is LandfillSiteAI) { ((LandfillSiteAI)building.Info.m_buildingAI.CastTo <LandfillSiteAI>()).StartTransfer(serviceBuildingId, ref building, material, offer); } else if (building.Info.m_buildingAI is HospitalAI) { ((HospitalAI)building.Info.m_buildingAI.CastTo <HospitalAI>()).StartTransfer(serviceBuildingId, ref building, material, offer); } else { building.Info.m_buildingAI.StartTransfer(serviceBuildingId, ref building, material, offer); } ushort newVehicleId = 0; ushort waitingVehicleId = 0; Vehicle.Flags findFlags = Vehicle.Flags.Created; switch (material) { case TransferManager.TransferReason.Dead: case TransferManager.TransferReason.Garbage: case TransferManager.TransferReason.Sick: findFlags |= Vehicle.Flags.TransferToSource; break; case TransferManager.TransferReason.DeadMove: case TransferManager.TransferReason.GarbageMove: case TransferManager.TransferReason.SickMove: findFlags |= Vehicle.Flags.TransferToSource; break; } count = 0; vehicleId = building.m_ownVehicles; while (vehicleId != 0) { if (!ownVehicles.Contains(vehicleId) && (vehicles[vehicleId].m_flags & findFlags) == findFlags && vehicles[vehicleId].Info != null) { if (vehicles[vehicleId].m_targetBuilding == targetBuildingId && (targetCitizenId == 0 || citizens[targetCitizenId].m_vehicle == vehicleId)) { return(vehicles[vehicleId].Info); } newVehicleId = vehicleId; if ((vehicles[vehicleId].m_flags & Vehicle.Flags.WaitingTarget) == Vehicle.Flags.WaitingTarget) { waitingVehicleId = vehicleId; } } if (count >= ushort.MaxValue) { throw new Exception("Loop counter too high"); } count++; vehicleId = vehicles[vehicleId].m_nextOwnVehicle; } if (waitingVehicleId != 0) { vehicleId = waitingVehicleId; //Log.DevDebug(typeof(BuildingHelper), "StartTransfer", "Waiting Vehicle", serviceBuildingId, targetBuildingId, targetCitizenId, material, vehicleId, vehicles[vehicleId].m_flags); } else if (newVehicleId != 0) { vehicleId = newVehicleId; //Log.DevDebug(typeof(BuildingHelper), "StartTransfer", "Guess Vehicle", serviceBuildingId, targetBuildingId, targetCitizenId, material, vehicleId, vehicles[vehicleId].m_flags); } else { vehicleId = 0; Log.Info(typeof(BuildingHelper), "StartTransfer", "Lost Vehicle", serviceBuildingId, targetBuildingId, targetCitizenId, material); return(null); } if (!VehicleHelper.AssignTarget(vehicleId, ref vehicles[vehicleId], material, targetBuildingId, targetCitizenId)) { return(null); } return(vehicles[vehicleId].Info); }