/// <summary> /// Creates the service vehicle. /// </summary> /// <param name="serviceBuildingId">The service building identifier.</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> /// The vehicle information. /// </returns> /// <exception cref="System.NotImplementedException">Target citizen not implemented yet.</exception> /// <exception cref="System.InvalidOperationException">Hospital assigments reuires target citizen.</exception> /// <exception cref="System.ArgumentException">Unhandled material.</exception> /// <exception cref="ArgumentException">Unhandled material.</exception> public static VehicleInfo CreateServiceVehicle(ushort serviceBuildingId, TransferManager.TransferReason material, ushort targetBuildingId, uint targetCitizenId, out ushort vehicleId) { if (targetCitizenId != 0) { throw new NotImplementedException("Target citizen not implemented yet"); } vehicleId = 0; VehicleManager manager = Singleton<VehicleManager>.instance; ColossalFramework.Math.Randomizer randomizer = Singleton<SimulationManager>.instance.m_randomizer; Building building = BuildingHelper.GetBuilding(serviceBuildingId); if (building.Info.m_buildingAI is HospitalAI && targetCitizenId == 0) { throw new InvalidOperationException("Hospital assigments reuires target citizen"); } VehicleInfo info = manager.GetRandomVehicleInfo(ref randomizer, building.Info.m_class.m_service, building.Info.m_class.m_subService, building.Info.m_class.m_level); if (info == null) { Log.Debug(typeof(VehicleKeeper), "CreateVehicle", "GetRandomVehicleInfo", "no vehicle"); return null; } bool transferToSource; bool transferToTarget; switch (material) { case TransferManager.TransferReason.Dead: transferToSource = true; transferToTarget = false; break; case TransferManager.TransferReason.DeadMove: transferToSource = false; transferToTarget = true; break; case TransferManager.TransferReason.Garbage: transferToSource = true; transferToTarget = false; break; case TransferManager.TransferReason.GarbageMove: transferToSource = false; transferToTarget = true; break; default: throw new ArgumentException("Unhandled material: " + material.ToString()); } if (!manager.CreateVehicle(out vehicleId, ref randomizer, info, building.m_position, material, transferToSource, transferToTarget)) { Log.Debug(typeof(VehicleKeeper), "CreateVehicle", "CreateVehicle", "not created"); return null; } info.m_vehicleAI.SetSource(vehicleId, ref manager.m_vehicles.m_buffer[vehicleId], serviceBuildingId); if (targetBuildingId != 0 && !AssignTarget(vehicleId, ref manager.m_vehicles.m_buffer[vehicleId], material, targetBuildingId, 0)) { Log.Debug(typeof(VehicleKeeper), "CreateVehicle", "SetTarget", "target not set"); return null; } return info; }
private static bool CreateVehicle(VehicleManager vMgr, out ushort vehicle, ref Randomizer r, VehicleInfo info, Vector3 position, TransferManager.TransferReason type, bool transferToSource, bool transferToTarget) { bool AttemptFlag = false; uint ReserveMax = (vMgr.m_vehicles.m_size - 1) - Mod.RESERVEAMOUNT; //we subtract 1 cause game doesn't use entry 0 for a real vehicle. int CurrentVehicleNum = vMgr.m_vehicleCount; //vMgr.m_vehicles.ItemCount(); //found they were never different ~+\- a nanosecond. int m_VecCount = vMgr.m_vehicleCount; //unly Mod.timesCV_CalledTotal++; //stat tracking. if (CurrentVehicleNum >= ReserveMax && type != TransferManager.TransferReason.Fire && type != TransferManager.TransferReason.Sick && type != TransferManager.TransferReason.Garbage && type != TransferManager.TransferReason.Dead && type != TransferManager.TransferReason.Crime && type != TransferManager.TransferReason.Bus && type != TransferManager.TransferReason.MetroTrain && type != TransferManager.TransferReason.PassengerTrain && type != TransferManager.TransferReason.DeadMove && type != TransferManager.TransferReason.CriminalMove && type != TransferManager.TransferReason.Taxi && type != TransferManager.TransferReason.GarbageMove && type != TransferManager.TransferReason.Tram && type != TransferManager.TransferReason.RoadMaintenance && type != TransferManager.TransferReason.Snow && type != TransferManager.TransferReason.SnowMove && type != TransferManager.TransferReason.Fire2 && type != TransferManager.TransferReason.ForestFire && type != TransferManager.TransferReason.FloodWater && type !=TransferManager.TransferReason.SickMove && type != TransferManager.TransferReason.Sick2 && type !=TransferManager.TransferReason.EvacuateVipA && type != TransferManager.TransferReason.EvacuateVipB && type != TransferManager.TransferReason.EvacuateVipC && type != TransferManager.TransferReason.EvacuateVipD) { Mod.timesFailedByReserve++; //stat tracking Mod.timesFailedToCreate++; //stat tracking vehicle = 0; return false; } if (CurrentVehicleNum >= ReserveMax) { AttemptFlag = true; Mod.timesReservedAttempted++; //stat tracking. if (CurrentVehicleNum == (vMgr.m_vehicles.m_size -1)) { Mod.timesLimitReached++; } //stattracking if (Mod.DEBUG_LOG_ON && Mod.DEBUG_LOG_LEVEL >= 3) { Helper.dbgLog(" Vehicles[" + CurrentVehicleNum.ToString() + "] max reached, attempting to use reserve for a " + type.ToString() + " - " + System.DateTime.Now.ToString() + " : " + DateTime.Now.Millisecond.ToString() + " counter=" + Mod.timesReservedAttempted.ToString() + " reservemax=" + ReserveMax.ToString()); } } //Original Untouched Below except for attemptflag and Mod.timeFailedToCreate Counters and debug logging. ushort num; if (!vMgr.m_vehicles.CreateItem(out num, ref r)) { vehicle = 0; if (AttemptFlag) { Mod.timesReserveAttemptFailed++ ; //stat tracking. if (Mod.DEBUG_LOG_ON && Mod.DEBUG_LOG_LEVEL >= 2) { Helper.dbgLog(" Vehicles[" + CurrentVehicleNum.ToString() + "] max reached, attempted to use reserve for a " + type.ToString() + " but Failed! " + System.DateTime.Now.ToString() + " : " + DateTime.Now.Millisecond.ToString() + " counter=" + Mod.timesReservedAttempted.ToString()); } } Mod.timesFailedToCreate++; //stat tracking return false; } vehicle = num; Vehicle.Frame frame = new Vehicle.Frame(position, Quaternion.identity); vMgr.m_vehicles.m_buffer[vehicle].m_flags = Vehicle.Flags.Created; if (transferToSource) { vMgr.m_vehicles.m_buffer[vehicle].m_flags = vMgr.m_vehicles.m_buffer[vehicle].m_flags | Vehicle.Flags.TransferToSource; } if (transferToTarget) { vMgr.m_vehicles.m_buffer[vehicle].m_flags = vMgr.m_vehicles.m_buffer[vehicle].m_flags | Vehicle.Flags.TransferToTarget; } vMgr.m_vehicles.m_buffer[vehicle].Info = info; vMgr.m_vehicles.m_buffer[vehicle].m_frame0 = frame; vMgr.m_vehicles.m_buffer[vehicle].m_frame1 = frame; vMgr.m_vehicles.m_buffer[vehicle].m_frame2 = frame; vMgr.m_vehicles.m_buffer[vehicle].m_frame3 = frame; vMgr.m_vehicles.m_buffer[vehicle].m_targetPos0 = Vector4.zero; vMgr.m_vehicles.m_buffer[vehicle].m_targetPos1 = Vector4.zero; vMgr.m_vehicles.m_buffer[vehicle].m_targetPos2 = Vector4.zero; vMgr.m_vehicles.m_buffer[vehicle].m_targetPos3 = Vector4.zero; vMgr.m_vehicles.m_buffer[vehicle].m_sourceBuilding = 0; vMgr.m_vehicles.m_buffer[vehicle].m_targetBuilding = 0; vMgr.m_vehicles.m_buffer[vehicle].m_transferType = (byte)type; vMgr.m_vehicles.m_buffer[vehicle].m_transferSize = 0; vMgr.m_vehicles.m_buffer[vehicle].m_waitCounter = 0; vMgr.m_vehicles.m_buffer[vehicle].m_blockCounter = 0; vMgr.m_vehicles.m_buffer[vehicle].m_nextGridVehicle = 0; vMgr.m_vehicles.m_buffer[vehicle].m_nextOwnVehicle = 0; vMgr.m_vehicles.m_buffer[vehicle].m_nextGuestVehicle = 0; vMgr.m_vehicles.m_buffer[vehicle].m_nextLineVehicle = 0; vMgr.m_vehicles.m_buffer[vehicle].m_transportLine = 0; vMgr.m_vehicles.m_buffer[vehicle].m_leadingVehicle = 0; vMgr.m_vehicles.m_buffer[vehicle].m_trailingVehicle = 0; vMgr.m_vehicles.m_buffer[vehicle].m_cargoParent = 0; vMgr.m_vehicles.m_buffer[vehicle].m_firstCargo = 0; vMgr.m_vehicles.m_buffer[vehicle].m_nextCargo = 0; vMgr.m_vehicles.m_buffer[vehicle].m_citizenUnits = 0; vMgr.m_vehicles.m_buffer[vehicle].m_path = 0; vMgr.m_vehicles.m_buffer[vehicle].m_lastFrame = 0; vMgr.m_vehicles.m_buffer[vehicle].m_pathPositionIndex = 0; vMgr.m_vehicles.m_buffer[vehicle].m_lastPathOffset = 0; vMgr.m_vehicles.m_buffer[vehicle].m_gateIndex = 0; vMgr.m_vehicles.m_buffer[vehicle].m_waterSource = 0; info.m_vehicleAI.CreateVehicle(vehicle, ref vMgr.m_vehicles.m_buffer[vehicle]); info.m_vehicleAI.FrameDataUpdated(vehicle, ref vMgr.m_vehicles.m_buffer[vehicle], ref vMgr.m_vehicles.m_buffer[vehicle].m_frame0); vMgr.m_vehicleCount = (int)(vMgr.m_vehicles.ItemCount() - 1); return true; }