/// <summary>
        /// Logs the transfer offers.
        /// </summary>
        /// <param name="direction">The direction.</param>
        /// <param name="offers">The offers.</param>
        /// <param name="count">The count.</param>
        /// <param name="amount">The amount.</param>
        /// <param name="buildings">The buildings.</param>
        /// <param name="material">The material.</param>
        private static void DebugListLog(
            string direction,
            TransferManager.TransferOffer[] offers,
            ushort[] count,
            int[] amount,
            Building[] buildings,
            TransferManager.TransferReason material)
        {
            for (int priority = 0; priority < 8; priority++)
            {
                int index = ((int)material * 8) + priority;
                for (int i = 0; i < count[index]; i++)
                {
                    Log.InfoList info = new Log.InfoList();
                    TransferManager.TransferOffer offer = offers[(index * 256) + i];

                    info.Add("Active", offer.Active);
                    info.Add("Amount", offer.Amount);
                    info.Add("Priority", offer.Priority);
                    info.Add("Vehicle", offer.Vehicle, VehicleHelper.GetVehicleName(offer.Vehicle));
                    info.Add("Citizen", offer.Citizen, CitizenHelper.GetCitizenName(offer.Citizen));
                    info.Add("TransportLine", offer.TransportLine, TransportLineHelper.GetLineName(offer.TransportLine));
                    info.Add("Building", offer.Building, BuildingHelper.GetBuildingName(offer.Building), BuildingHelper.GetDistrictName(offer.Building));

                    if (buildings != null && offer.Building > 0 && buildings[offer.Building].Info != null && (buildings[offer.Building].m_flags & Building.Flags.Created) == Building.Flags.Created)
                    {
                        info.Add("Garbage", buildings[offer.Building].m_garbageBuffer);
                        info.Add("Dead", buildings[offer.Building].m_deathProblemTimer);
                    }

                    Log.DevDebug(typeof(TransferManagerHelper), "DebugListLog", direction, material, info);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// De-spawns the vehicle.
        /// </summary>
        private static void DeSpawnVehicle(ushort vehicleId)
        {
            if (Global.Buildings != null)
            {
                foreach (BuildingKeeper.StandardServiceBuildings buildings in Global.Buildings.StandardServices)
                {
                    foreach (ServiceBuildingInfo serviceBuilding in buildings.ServiceBuildings.Values)
                    {
                        ServiceVehicleInfo serviceVehicle;

                        if (serviceBuilding.Vehicles.TryGetValue(vehicleId, out serviceVehicle) && serviceVehicle.Target != 0)
                        {
                            TargetBuildingInfo targetBuilding;

                            if (buildings.TargetBuildings.TryGetValue(serviceVehicle.Target, out targetBuilding))
                            {
                                targetBuilding.Handled = false;
                            }
                        }

                        serviceBuilding.Vehicles.Remove(vehicleId);
                    }
                }
            }

            VehicleHelper.DeSpawn(vehicleId);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates a new instance of an information list with garbage vehicle info.
        /// </summary>
        /// <param name="vehicleId">The vehicle identifier.</param>
        /// <param name="vehicle">The vehicle.</param>
        /// <param name="dirtyBuildingId">The dirty building identifier.</param>
        /// <param name="dirtyBuilding">The dirty building.</param>
        /// <returns>The information list.</returns>
        private static Log.InfoList NewGarbageVehicleInfoList(ushort vehicleId, ref Vehicle vehicle, ushort dirtyBuildingId, ref Building dirtyBuilding)
        {
            Log.InfoList infoList = new Log.InfoList();
            infoList.Add("SourceBuilding", vehicle.m_sourceBuilding, BuildingHelper.GetBuildingName(vehicle.m_sourceBuilding));
            infoList.Add("Vehicle", vehicleId, VehicleHelper.GetVehicleName(vehicleId));
            infoList.Add("DirtyBuilding", dirtyBuildingId, BuildingHelper.GetBuildingName(dirtyBuildingId));
            infoList.Add("TargetBuilding", vehicle.m_targetBuilding, BuildingHelper.GetBuildingName(vehicle.m_targetBuilding));

            return(infoList);
        }
        /// <summary>
        /// Logs a list of building info for debug use.
        /// </summary>
        /// <param name="serviceBuildings">The service buildings.</param>
        public static void DebugListLog(IEnumerable <ServiceBuildingInfo> serviceBuildings)
        {
            Building[]      buildings       = Singleton <BuildingManager> .instance.m_buildings.m_buffer;
            Vehicle[]       vehicles        = Singleton <VehicleManager> .instance.m_vehicles.m_buffer;
            DistrictManager districtManager = Singleton <DistrictManager> .instance;
            CitizenManager  citizenManager  = Singleton <CitizenManager> .instance;

            foreach (ServiceBuildingInfo building in serviceBuildings)
            {
                DebugListLog(buildings, vehicles, districtManager, citizenManager, building.BuildingId, building, null, null);
            }

            foreach (ServiceBuildingInfo building in serviceBuildings)
            {
                VehicleHelper.DebugListLog(building);
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Assigns target to vehicle.
        /// </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>The result of the action.</returns>
        /// <exception cref="System.InvalidOperationException">Ambulances must use citizen assignment
        /// or
        /// Material must be specified.</exception>
        /// <exception cref="System.NotImplementedException">Ambulance dispatching not fully implemented yet.</exception>
        public static VehicleResult AssignTarget(ushort vehicleId, ref Vehicle vehicle, TransferManager.TransferReason?material, ushort targetBuildingId, uint targetCitizenId)
        {
            if (targetBuildingId == 0 && targetCitizenId == 0)
            {
                return(VehicleHelper.SetTarget(vehicleId, ref vehicle, targetBuildingId, targetCitizenId));
            }

            if (vehicle.Info.m_vehicleAI is AmbulanceAI && targetCitizenId == 0)
            {
                throw new InvalidOperationException("Ambulances must use citizen assignment");
            }

            if (Global.Settings.AssignmentCompatibilityMode == ServiceDispatcherSettings.ModCompatibilityMode.UseCustomCode)
            {
                if (vehicle.Info.m_vehicleAI is AmbulanceAI)
                {
                    throw new NotImplementedException("Ambulance dispatching not fully implemented yet");
                }

                return(VehicleHelper.SetTarget(vehicleId, ref vehicle, targetBuildingId, targetCitizenId));
            }

            if (material == null || !material.HasValue)
            {
                if (vehicle.Info.m_vehicleAI is HearseAI)
                {
                    material = TransferManager.TransferReason.Dead;
                }
                else if (vehicle.Info.m_vehicleAI is GarbageTruckAI)
                {
                    material = TransferManager.TransferReason.Garbage;
                }
                else if (vehicle.Info.m_vehicleAI is AmbulanceAI)
                {
                    material = TransferManager.TransferReason.Sick;
                }
                else
                {
                    throw new InvalidOperationException("Material must be specified");
                }
            }

            return(new VehicleResult(StartTransfer(vehicleId, ref vehicle, material.Value, targetBuildingId, targetCitizenId), VehicleResult.Result.Assigned));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// De-assigns the vehicle.
        /// </summary>
        private void DeAssign()
        {
            if (Global.Buildings != null)
            {
                foreach (BuildingKeeper.StandardServiceBuildings buildings in Global.Buildings.StandardServices)
                {
                    foreach (ServiceBuildingInfo serviceBuilding in buildings.ServiceBuildings.Values)
                    {
                        ServiceVehicleInfo serviceVehicle;

                        if (serviceBuilding.Vehicles.TryGetValue(this.VehicleId, out serviceVehicle) && serviceVehicle.Target != 0)
                        {
                            TargetBuildingInfo targetBuilding;

                            if (buildings.TargetBuildings.TryGetValue(serviceVehicle.Target, out targetBuilding))
                            {
                                targetBuilding.Handled = false;
                            }

                            if (this.lastDeAssignStamp != Global.CurrentFrame)
                            {
                                if (serviceVehicle.DeAssign().DeSpawned)
                                {
                                    serviceBuilding.Vehicles.Remove(this.VehicleId);
                                }

                                this.lastDeAssignStamp = Global.CurrentFrame;
                            }
                        }
                    }
                }
            }

            if (this.lastDeAssignStamp != Global.CurrentFrame)
            {
                if (Log.LogALot)
                {
                    Log.DevDebug(this, "DeAssign", this.dispatcherType, this.VehicleId);
                }

                VehicleHelper.DeAssign(this.VehicleId);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// De-assign target from vehicle.
        /// </summary>
        /// <param name="vehicle">The vehicle.</param>
        /// <param name="force">If set to <c>true</c> force de-assignment.</param>
        /// <param name="sourceObject">The source object.</param>
        /// <param name="sourceBlock">The source block.</param>
        /// <param name="logMessage">The log message.</param>
        /// <returns>The result of the action.</returns>
        public VehicleResult DeAssign(ref Vehicle vehicle, bool force = false, object sourceObject = null, string sourceBlock = null, string logMessage = null)
        {
            if (this.lastDeAssignStamp == Global.CurrentFrame)
            {
                return(new VehicleResult(vehicle.m_targetBuilding == 0 && this.Target == 0));
            }

            if (force || Global.CurrentFrame - this.LastAssigned > Global.TargetLingerDelay || (vehicle.m_targetBuilding != this.Target && !this.LingerWrongTargets))
            {
                this.lastDeAssignStamp = Global.CurrentFrame;

                if (vehicle.m_targetBuilding == 0 && this.Target == 0)
                {
                    return(new VehicleResult(true));
                }

                if (Log.LogALot && (sourceObject != null || sourceBlock != null || logMessage != null))
                {
                    Log.DevDebug(this, "DeAssign", sourceBlock, logMessage, this.VehicleId, vehicle.m_targetBuilding, this.Target);
                }

                // Set internal target.
                this.Target = 0;

                // Unassign the vehicle.
                ushort        serviceBuildingId = vehicle.m_sourceBuilding;
                VehicleResult result            = VehicleHelper.DeAssign(this.VehicleId, ref vehicle);
                if (result.DeSpawned)
                {
                    ServiceBuildingInfo building = Global.Buildings.GetServiceBuilding(serviceBuildingId);
                    if (building != null)
                    {
                        building.Vehicles.Remove(this.VehicleId);
                    }
                }

                return(result);
            }

            return(new VehicleResult(vehicle.m_targetBuilding == 0 && this.Target == 0));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Creates the specified service building.
        /// </summary>
        /// <param name="serviceBuilding">The service building.</param>
        /// <param name="material">The material.</param>
        /// <param name="dispatcherType">Type of the dispatcher.</param>
        /// <param name="targetBuildingId">The target building identifier.</param>
        /// <param name="targetCitizenId">The target citizen identifier.</param>
        /// <returns>
        /// The service vehicle.
        /// </returns>
        public static ServiceVehicleInfo Create(ServiceBuildingInfo serviceBuilding, TransferManager.TransferReason material, Dispatcher.DispatcherTypes dispatcherType, ushort targetBuildingId, uint targetCitizenId)
        {
            ushort      vehicleId = 0;
            VehicleInfo info      = null;

            if (Global.Settings.CreationCompatibilityMode == ServiceDispatcherSettings.ModCompatibilityMode.UseCustomCode)
            {
                info = VehicleHelper.CreateServiceVehicle(serviceBuilding.BuildingId, material, targetBuildingId, targetCitizenId, out vehicleId);
            }
            else
            {
                info = BuildingHelper.StartTransfer(serviceBuilding.BuildingId, material, targetBuildingId, targetCitizenId, out vehicleId);
            }

            if (info == null)
            {
                return(null);
            }

            VehicleManager manager = Singleton <VehicleManager> .instance;

            return(new ServiceVehicleInfo(vehicleId, ref manager.m_vehicles.m_buffer[vehicleId], targetBuildingId == 0, dispatcherType, targetBuildingId));
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Sets the target and updates the games vehicle object.
        /// </summary>
        /// <param name="targetBuildingId">The target building identifier.</param>
        /// <param name="vehicle">The vehicle.</param>
        /// <param name="material">The material.</param>
        /// <returns>The result of the action.</returns>
        public VehicleResult SetTarget(ushort targetBuildingId, ref Vehicle vehicle, TransferManager.TransferReason?material)
        {
            if (targetBuildingId == 0)
            {
                if (this.Target == 0 && vehicle.m_targetBuilding == 0)
                {
                    return(new VehicleResult(true));
                }

                return(this.DeAssign(ref vehicle, true, "SetTarget"));
            }

            if (Log.LogALot)
            {
                Log.DevDebug(this, "SetTarget", this.VehicleId, targetBuildingId, this.Target, vehicle.m_targetBuilding, vehicle.m_flags);
            }

            VehicleResult result = VehicleHelper.AssignTarget(this.VehicleId, ref vehicle, material, targetBuildingId, 0);

            if (result)
            {
                this.LastAssigned  = Global.CurrentFrame;
                this.FreeToCollect = false;
                this.Target        = targetBuildingId;
            }
            else
            {
                Log.Debug(this, "SetTarget", "Failed", this.VehicleId, targetBuildingId, this.Target, vehicle.m_targetBuilding, vehicle.m_flags);

                this.LastAssigned  = 0;
                this.FreeToCollect = false;
                this.Target        = 0;
            }

            return(result);
        }
        /// <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);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Updates the specified vehicle.
        /// </summary>
        /// <param name="vehicle">The vehicle.</param>
        public void Update(ref Vehicle vehicle)
        {
            this.targetBuildingId = vehicle.m_targetBuilding;
            this.isTrailer        = vehicle.m_leadingVehicle != 0;
            this.hasCargoParent   = vehicle.m_cargoParent != 0;

            if (this.hasCargoParent && !Global.Settings.Experimental.AllowTrackingOfCargoChildren)
            {
                return;
            }

            if (this.isTrailer)
            {
                if (Global.Settings.Experimental.TrackLostTrailers)
                {
                    this.UpdateTrailer(ref vehicle);
                }

                return;
            }

            // Check if vehicle has flag that should be checked.
            Vehicle.Flags flags = vehicle.m_flags & FlagsToCheck;
            if ((flags & VehicleHelper.VehicleAll) != ~VehicleHelper.VehicleAll)
            {
                Vector3 position = vehicle.GetLastFramePosition();

                // Remember first time stamp the vehicle was seen with this flag at this position.
                if (this.checkFlagSinceFrame == 0 || this.checkFlagSinceTime == 0 || flags != this.checkFlags || Math.Truncate((position - this.checkFlagPosition).sqrMagnitude) > 0)
                {
                    this.isFlagged           = false;
                    this.checkFlags          = flags;
                    this.checkFlagPosition   = position;
                    this.checkFlagSinceTime  = Global.SimulationTime;
                    this.checkFlagSinceFrame = Global.CurrentFrame;
                }
                else if (!this.isFlagged && this.CheckFlaggedForFrames > Global.CheckFlagStuckDelay)
                {
                    // Check if stuck with flag.
                    double delta = this.CheckFlaggedForSeconds;

                    if (delta > Global.Settings.RecoveryCrews.DelaySeconds)
                    {
                        Log.Info(this, "IsFlagged", this.checkFlags, this.VehicleId, delta, VehicleHelper.GetVehicleName(this.VehicleId));
                        this.isFlagged = true;
                    }
                }
            }
            else if ((this.checkFlags & VehicleHelper.VehicleAll) != ~VehicleHelper.VehicleAll || this.checkFlagSinceTime != 0 || this.checkFlagSinceFrame != 0)
            {
                this.isFlagged           = false;
                this.checkFlags          = ~VehicleHelper.VehicleAll;
                this.checkFlagSinceTime  = 0;
                this.checkFlagSinceFrame = 0;
            }

            // Check if vehicle is confused.
            if (ConfusionHelper.VehicleIsConfused(ref vehicle))
            {
                if (this.confusedDeAssignedSinceFrame == 0)
                {
                    this.confusedDeAssignedSinceFrame = Global.CurrentFrame;
                }

                if (this.confusedSinceFrame == 0 || this.confusedSinceTime == 0)
                {
                    if (Log.LogALot)
                    {
                        Log.DevDebug(this, "Update", "NewConfused", this.VehicleId, this.ConfusedForSeconds, this.ConfusedForFrames, Global.Settings.RecoveryCrews.DelaySeconds, Global.DeAssignConfusedDelay, vehicle.m_targetBuilding, vehicle.m_flags, VehicleHelper.GetVehicleName(this.VehicleId));
                    }

                    this.isConfused                   = false;
                    this.confusedSinceTime            = Global.SimulationTime;
                    this.confusedSinceFrame           = Global.CurrentFrame;
                    this.confusedDeAssignedSinceFrame = Global.CurrentFrame;
                }
                else if (!this.isConfused && this.ConfusedForFrames > Global.CheckFlagStuckDelay)
                {
                    // Check if stuck confused.
                    double delta = this.ConfusedForSeconds;

                    if (delta > Global.Settings.RecoveryCrews.DelaySeconds)
                    {
                        Log.Info(this, "IsConfused", this.VehicleId, delta, VehicleHelper.GetVehicleName(this.VehicleId));
                        this.isConfused = true;
                    }
                }
            }
            else if (this.confusedSinceTime != 0 || this.confusedSinceFrame != 0 || this.confusedDeAssignedSinceFrame != 0)
            {
                this.isConfused                   = false;
                this.confusedSinceTime            = 0;
                this.confusedSinceFrame           = 0;
                this.confusedDeAssignedSinceFrame = 0;
            }

            this.isStuck = this.isLost || this.isConfused || this.isFlagged || this.isBroken;
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Logs the debug lists.
        /// </summary>
        /// <param name="initializing">if set to <c>true</c> level is loading.</param>
        /// <param name="deInitializing">if set to <c>true</c> level is unloading.</param>
        private static void LogDebugLists(bool initializing, bool deInitializing)
        {
            try
            {
                bool flush = false;

                if (initializing)
                {
                    if (Log.LogDebugLists)
                    {
                        Log.Debug(typeof(Global), "LogDebugLists", "Initializing");
                    }
                }
                else if (deInitializing)
                {
                    if (Log.LogDebugLists)
                    {
                        Log.Debug(typeof(Global), "LogDebugLists", "DeInitializing");
                    }
                }
                else if (CurrentFrame == 0)
                {
                    if (Log.LogDebugLists)
                    {
                        Log.Debug(typeof(Global), "LogDebugLists", "Started");

                        Detours.LogInfo();
                        TransferManagerHelper.LogInfo();
                        VehicleHelper.DebugListLog();
                        BuildingHelper.DebugListLog();
                        TransferManagerHelper.DebugListLog();

                        flush = true;
                    }
                }
                else if (CurrentFrame > 0)
                {
                    if (Log.LogDebugLists)
                    {
                        Log.Debug(typeof(Global), "LogDebugLists", "Running");

                        if (Global.Buildings != null)
                        {
                            Global.Buildings.DebugListLogBuildings();
                        }

                        if (Global.Vehicles != null)
                        {
                            Global.Vehicles.DebugListLogVehicles();
                        }

                        TransferManagerHelper.DebugListLog();
                        flush = true;
                    }

                    if (Global.ServiceProblems != null)
                    {
                        Global.ServiceProblems.DebugListLogServiceProblems();
                        flush = true;
                    }
                }

                if (flush)
                {
                    Log.FlushBuffer();
                }
            }
            catch (Exception ex)
            {
                Log.Error(typeof(Global), "LogDebugLists", ex);
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Updates the specified trailer vehicle.
        /// </summary>
        /// <param name="vehicle">The vehicle.</param>
        private void UpdateTrailer(ref Vehicle vehicle)
        {
            Vehicle[] vehicles = Singleton <VehicleManager> .instance.m_vehicles.m_buffer;

            LostReasons lost = LostReasons.None;

            ushort count  = 0;
            ushort leadId = this.VehicleId;
            ushort nextId = vehicle.m_leadingVehicle;

            while (nextId != 0)
            {
                if (vehicles[nextId].m_trailingVehicle != leadId)
                {
                    lost = LostReasons.IgnorantLead;
                    break;
                }

                if (count >= ushort.MaxValue)
                {
                    throw new Exception("Loop counter too high");
                }
                count++;

                leadId = nextId;
                nextId = vehicles[leadId].m_leadingVehicle;
            }

            if (lost == LostReasons.None && (vehicles[leadId].Info == null || (vehicles[leadId].m_flags & Vehicle.Flags.Spawned) == ~VehicleHelper.VehicleAll))
            {
                lost = LostReasons.NoLead;
            }

            if (lost != LostReasons.None)
            {
                if (this.lostSinceFrame == 0 || this.lostSinceTime == 0 || this.lostReason == LostReasons.None || lost != this.lostReason)
                {
                    if (Log.LogALot)
                    {
                        Log.DevDebug(this, "UpdateTrailer", "NewLost", lost, this.VehicleId, this.LostForSeconds, this.LostForFrames, Global.Settings.RecoveryCrews.DelaySeconds, Global.CheckFlagStuckDelay, vehicle.m_leadingVehicle, vehicle.m_flags, VehicleHelper.GetVehicleName(this.VehicleId));
                    }

                    this.isLost         = false;
                    this.lostReason     = lost;
                    this.lostSinceTime  = Global.SimulationTime;
                    this.lostSinceFrame = Global.CurrentFrame;
                }
                else if (!this.isLost)
                {
                    double delta;

                    if (this.lostReason != LostReasons.None && this.LostForFrames > Global.CheckFlagStuckDelay)
                    {
                        delta = this.LostForSeconds;

                        if (delta > Global.Settings.RecoveryCrews.DelaySeconds)
                        {
                            Log.Info(this, "IsLost", lost, this.VehicleId, delta, VehicleHelper.GetVehicleName(this.VehicleId));
                            this.isLost = true;
                        }
                    }
                }
            }
            else
            {
                this.isLost         = false;
                this.lostReason     = LostReasons.None;
                this.lostSinceTime  = 0;
                this.lostSinceFrame = 0;
            }

            this.isStuck = this.isLost || this.isConfused || this.isFlagged || this.isBroken;
        }
Ejemplo n.º 14
0
        private void DeSpawnTrailer()
        {
            ushort count;
            ushort prevId;
            ushort nextId;

            Vehicle[] vehicles = Singleton <VehicleManager> .instance.m_vehicles.m_buffer;

            LinkedList <ushort> ids = new LinkedList <ushort>(new ushort[] { this.VehicleId });

            count  = 0;
            prevId = this.VehicleId;
            nextId = vehicles[prevId].m_leadingVehicle;
            while (nextId != 0)
            {
                if (vehicles[nextId].m_trailingVehicle != prevId)
                {
                    break;
                }

                ids.AddFirst(nextId);

                if (count >= ushort.MaxValue)
                {
                    throw new Exception("Loop counter too high");
                }
                count++;

                prevId = nextId;
                nextId = vehicles[prevId].m_leadingVehicle;
            }

            count  = 0;
            prevId = this.VehicleId;
            nextId = vehicles[prevId].m_trailingVehicle;
            while (nextId != 0)
            {
                if (vehicles[nextId].m_leadingVehicle != prevId)
                {
                    break;
                }
                ids.AddLast(nextId);

                if (count >= ushort.MaxValue)
                {
                    throw new Exception("Loop counter too high");
                }
                count++;

                prevId = nextId;
                nextId = vehicles[prevId].m_trailingVehicle;
            }

            count = 0;
            foreach (ushort id in ids)
            {
                if (count == 0 && vehicles[id].m_leadingVehicle == 0)
                {
                    DeSpawnVehicle(id);
                }
                else
                {
                    VehicleHelper.DeSpawn(id);
                }

                count++;
            }
        }
        /// <summary>
        /// Categorizes the vehicles.
        /// </summary>
        /// <param name="firstVehicleId">The first vehicle identifier.</param>
        /// <param name="lastVehicleId">The last vehicle identifier.</param>
        private void HandleVehicles(ushort firstVehicleId, int lastVehicleId)
        {
            Vehicle[]  vehicles  = Singleton <VehicleManager> .instance.m_vehicles.m_buffer;
            Building[] buildings = Singleton <BuildingManager> .instance.m_buildings.m_buffer;

            for (ushort id = firstVehicleId; id < lastVehicleId; id++)
            {
                // Is the vehicle?
                if (vehicles[id].m_leadingVehicle != 0 || vehicles[id].m_cargoParent != 0 || vehicles[id].Info == null || (vehicles[id].m_flags & VehicleHelper.VehicleExists) == ~VehicleHelper.VehicleAll)
                {
                    if (this.removedFromGrid != null && this.removedFromGrid.Contains(id))
                    {
                        this.removedFromGrid.Remove(id);
                    }

                    if (this.StuckVehicles != null && this.StuckVehicles.ContainsKey(id))
                    {
                        //if (Log.LogALot)
                        //{
                        //    Log.DevDebug(this, "HandleVehicles", "StuckVehicles", "Gone", id);
                        //}

                        this.StuckVehicles.Remove(id);
                    }
                }
                else
                {
                    // Check target assignments for service vehicles.
                    if ((vehicles[id].m_flags & Vehicle.Flags.TransferToSource) != ~VehicleHelper.VehicleAll &&
                        (vehicles[id].m_flags & (Vehicle.Flags.TransferToTarget | Vehicle.Flags.Arriving | Vehicle.Flags.Stopped)) == ~VehicleHelper.VehicleAll &&
                        (vehicles[id].m_flags & VehicleHelper.VehicleUnavailable) == ~VehicleHelper.VehicleAll &&
                        vehicles[id].m_targetBuilding != vehicles[id].m_sourceBuilding && (buildings[vehicles[id].m_sourceBuilding].m_flags & Building.Flags.Downgrading) == Building.Flags.None)
                    {
                        if (Global.Settings.DeathCare.DispatchVehicles && Global.HearseDispatcher != null && vehicles[id].m_transferType == Global.HearseDispatcher.TransferType)
                        {
                            Global.HearseDispatcher.CheckVehicleTarget(id, ref vehicles[id]);
                        }

                        if (Global.Settings.Garbage.DispatchVehicles && Global.GarbageTruckDispatcher != null && vehicles[id].m_transferType == Global.GarbageTruckDispatcher.TransferType)
                        {
                            Global.GarbageTruckDispatcher.CheckVehicleTarget(id, ref vehicles[id]);
                        }

                        if (Global.Settings.HealthCare.DispatchVehicles && Global.AmbulanceDispatcher != null && vehicles[id].m_transferType == Global.AmbulanceDispatcher.TransferType)
                        {
                            Global.AmbulanceDispatcher.CheckVehicleTarget(id, ref vehicles[id]);
                        }
                    }

                    // Handle grid removals.
                    if (this.removedFromGrid != null)
                    {
                        if ((vehicles[id].m_flags & Vehicle.Flags.Stopped) == ~VehicleHelper.VehicleAll &&
                            (vehicles[id].Info.m_vehicleAI is HearseAI || vehicles[id].Info.m_vehicleAI is AmbulanceAI))
                        {
                            if (this.removedFromGrid.Contains(id))
                            {
                                if (Log.LogALot)
                                {
                                    Log.Debug(this, "HandleVehicles", "Moving", id, vehicles[id].m_targetBuilding, vehicles[id].Info.name, VehicleHelper.GetVehicleName(id), vehicles[id].m_flags);
                                }

                                this.removedFromGrid.Remove(id);
                            }
                        }
                        else if ((Global.Settings.DeathCare.RemoveFromGrid && vehicles[id].Info.m_vehicleAI is HearseAI) ||
                                 (Global.Settings.HealthCare.RemoveFromGrid && vehicles[id].Info.m_vehicleAI is AmbulanceAI))
                        {
                            if (!this.removedFromGrid.Contains(id))
                            {
                                if (Log.LogALot)
                                {
                                    Log.Debug(this, "HandleVehicles", "RemoveFromGrid", id, vehicles[id].m_targetBuilding, vehicles[id].Info.name, VehicleHelper.GetVehicleName(id), vehicles[id].m_flags);
                                }

                                Singleton <VehicleManager> .instance.RemoveFromGrid(id, ref vehicles[id], false);

                                this.removedFromGrid.Add(id);
                            }
                        }
                    }

                    // Try to fix stuck vehicles.
                    if (this.StuckVehicles != null)
                    {
                        if (StuckVehicleInfo.HasProblem(id, ref vehicles[id]))
                        {
                            StuckVehicleInfo stuckVehicle;
                            if (this.StuckVehicles.TryGetValue(id, out stuckVehicle))
                            {
                                stuckVehicle.Update(ref vehicles[id]);
                            }
                            else
                            {
                                stuckVehicle           = new StuckVehicleInfo(id, ref vehicles[id]);
                                this.StuckVehicles[id] = stuckVehicle;

                                if (Log.LogALot)
                                {
                                    Log.DevDebug(this, "HandleVehicles", "StuckVehicles", "New", id, vehicles[id].m_flags, stuckVehicle.Flagged, stuckVehicle.Lost, stuckVehicle.Confused, stuckVehicle.ExtraInfo);
                                }
                            }

                            if (stuckVehicle.HandleProblem())
                            {
                                if (Log.LogALot)
                                {
                                    Log.DevDebug(this, "HandleVehicles", "StuckVehicles", "Handled", id);
                                }

                                this.StuckVehicles.Remove(id);
                            }
                        }
                        else if (this.StuckVehicles.ContainsKey(id))
                        {
                            if (Log.LogALot)
                            {
                                Log.DevDebug(this, "HandleVehicles", "StuckVehicles", "NoProblem", id, vehicles[id].m_flags, vehicles[id].m_flags & StuckVehicleInfo.FlagsToCheck, ConfusionHelper.VehicleIsConfused(ref vehicles[id]));
                            }

                            this.StuckVehicles.Remove(id);
                        }
                    }
                }
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Handles the vehicles problems.
        /// </summary>
        /// <returns>True if a problem was handled.</returns>
        public bool HandleProblem()
        {
            if (this.hasCargoParent &&
                !((this.isFlagged || this.isLost) && Global.Settings.Experimental.AllowRemovalOfStuckCargoChildren) &&
                !(this.isConfused && Global.Settings.Experimental.AllowRemovalOfConfusedCargoChildren))
            {
                if (Log.LogALot)
                {
                    Log.DevDebug(this, "HandleProblem", "StuckLostBroken", "IgnoreCargoChild", this.VehicleId, VehicleHelper.GetVehicleName(this.VehicleId));
                }

                this.lastHandledStamp = Global.CurrentFrame;
                return(false);
            }

            if (this.isTrailer && !Global.Settings.Experimental.RemoveLostTrailers)
            {
                if (Log.LogALot)
                {
                    Log.DevDebug(this, "HandleProblem", "StuckLostBroken", "IgnoreTrailer", this.VehicleId, VehicleHelper.GetVehicleName(this.VehicleId));
                }

                this.lastHandledStamp = Global.CurrentFrame;
                return(false);
            }

            if (this.isStuck && this.lastHandledStamp + Global.CheckFlagStuckDelay < Global.CurrentFrame)
            {
                try
                {
                    if (this.isTrailer)
                    {
                        // Remove trailer vehicle.
                        Log.Debug(this, "HandleProblem", "StuckLostBroken", "DeSpawnTrailer", this.VehicleId, this.ExtraInfo, VehicleHelper.GetVehicleName(this.VehicleId));
                        this.DeSpawnTrailer();
                    }
                    else
                    {
                        // Remove vehicle.
                        Log.Debug(this, "HandleProblem", "StuckLostBroken", "DeSpawn", this.VehicleId, this.ExtraInfo, VehicleHelper.GetVehicleName(this.VehicleId));
                        this.DeSpawn();
                    }

                    return(true);
                }
                catch (Exception ex)
                {
                    Log.Error(this, "HandleProblem", ex, this.VehicleId);
                    this.handlingErrors++;

                    return(this.handlingErrors > 10);
                }
                finally
                {
                    this.isStuck          = false;
                    this.lastHandledStamp = Global.CurrentFrame;
                }
            }

            if (this.ConfusedDeAssignedForFrames > Global.DeAssignConfusedDelay && !this.isTrailer && IsDispatchersResponsibility(this.dispatcherType))
            {
                try
                {
                    // De-assign vehicle.
                    Log.Debug(this, "HandleProblem", "Confused", "DeAssign", this.VehicleId, VehicleHelper.GetVehicleName(this.VehicleId));
                    this.DeAssign();
                }
                catch (Exception ex)
                {
                    Log.Error(this, "HandleProblem", ex, this.VehicleId);
                    this.handlingErrors++;

                    return(this.handlingErrors > 10);
                }
                finally
                {
                    this.confusedDeAssignedSinceFrame = Global.CurrentFrame;
                }
            }

            return(false);
        }
Ejemplo n.º 17
0
 /// <summary>
 /// Initializes the helpers.
 /// </summary>
 public static void InitializeHelpers()
 {
     TransferManagerHelper.DeInitialize();
     VehicleHelper.Initialize();
     BulldozeHelper.Initialize();
 }