Beispiel #1
0
        /// <summary>
        /// Determines whether the specified vehicle has a problem.
        /// </summary>
        /// <param name="vehicleId">The vehicle identifier.</param>
        /// <param name="vehicle">The vehicle.</param>
        /// <returns>
        /// True if the vehicle has at least one problem.
        /// </returns>
        public static bool HasProblem(ushort vehicleId, ref Vehicle vehicle)
        {
            // Don't check unspawned vehicles.
            if (vehicle.Info == null || (vehicle.m_flags & Vehicle.Flags.Spawned) == ~VehicleHelper.VehicleAll)
            {
                return(false);
            }

            // Cargo parent?
            if (vehicle.m_cargoParent != 0 && !Global.Settings.Experimental.AllowTrackingOfCargoChildren)
            {
                return(false);
            }

            // Trailer?
            if (vehicle.m_leadingVehicle != 0)
            {
                if (!Global.Settings.Experimental.TrackLostTrailers)
                {
                    return(false);
                }

                return(TrailerHasProblem(vehicleId, ref vehicle));
            }

            // Only check vehicles we dispatch unless told to check other vehicles as well.
            if (!(Global.Settings.RecoveryCrews.DispatchVehicles || IsDispatchersResponsibility(ref vehicle)))
            {
                return(false);
            }

            // Check vehicles flags.
            if ((vehicle.m_flags & FlagsToCheck) != ~VehicleHelper.VehicleAll)
            {
                return(true);
            }

            if (ConfusionHelper.VehicleIsConfused(ref vehicle))
            {
                return(true);
            }

            return(false);
        }
Beispiel #2
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;
        }
        /// <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);
                        }
                    }
                }
            }
        }