示例#1
0
        private void UpdateDistance()
        {
            if (_lastUpdated == SimulationManager.instance.m_currentGameTime)
            {
                return;
            }

            _lastUpdated = SimulationManager.instance.m_currentGameTime;
            if (!SkylinesOverwatch.Data.Instance.IsHearse(_id) || !Helper.IsBuildingWithDead(_target))
            {
                _distance = float.PositiveInfinity;
                return;
            }

            Building b = Singleton <BuildingManager> .instance.m_buildings.m_buffer[_target];
            Vehicle  v = Singleton <VehicleManager> .instance.m_vehicles.m_buffer[_id];

            _distance = (b.m_position - v.GetLastFramePosition()).sqrMagnitude;

            if (_distance <= Settings.Instance.ImmediateRange1)
            {
                _distance = float.NegativeInfinity;
                return;
            }

            if (v.m_targetBuilding != _target)
            {
                _distance = float.PositiveInfinity;
                return;
            }
        }
        private void UpdateHearses()
        {
            SkylinesOverwatch.Data data = SkylinesOverwatch.Data.Instance;

            foreach (ushort vehicleID in data.VehiclesRemoved)
            {
                if (!data.IsHearse(vehicleID))
                {
                    continue;
                }

                if (_lasttargets.ContainsKey(vehicleID) &&
                    Helper.IsBuildingWithDead(_lasttargets[vehicleID]))
                {
                    foreach (ushort id in _cemeteries.Keys)
                    {
                        _cemeteries[id].AddPickup(_lasttargets[vehicleID]);
                    }
                }
                _oldtargets.Remove(vehicleID);
                if (_lasttargets.ContainsKey(vehicleID))
                {
                    _master.Remove(_lasttargets[vehicleID]);
                }
                _lasttargets.Remove(vehicleID);
                _lastchangetimes.Remove(vehicleID);
                _PathfindCount.Remove(vehicleID);
            }

            if (!SimulationManager.instance.SimulationPaused)
            {
                uint num1 = Singleton <SimulationManager> .instance.m_currentFrameIndex >> 4 & 7u;
                uint num2 = _lastProcessedFrame >> 4 & 7u;
                foreach (ushort vehicleID in data.VehiclesUpdated)
                {
                    if (!data.IsHearse(vehicleID))
                    {
                        continue;
                    }

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

                    if (!_cemeteries.ContainsKey(v.m_sourceBuilding))
                    {
                        continue;
                    }

                    if (v.m_flags.IsFlagSet(Vehicle.Flags.Stopped))
                    {
                        if (!_stopped.Contains(vehicleID))
                        {
                            Singleton <VehicleManager> .instance.RemoveFromGrid(vehicleID, ref Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID], false);

                            _stopped.Add(vehicleID);
                        }
                        continue;
                    }

                    if (v.m_flags.IsFlagSet(Vehicle.Flags.Stopped) || v.m_flags.IsFlagSet(Vehicle.Flags.WaitingSpace) || v.m_flags.IsFlagSet(Vehicle.Flags.WaitingPath) || v.m_flags.IsFlagSet(Vehicle.Flags.WaitingLoading) || v.m_flags.IsFlagSet(Vehicle.Flags.WaitingCargo))
                    {
                        continue;
                    }
                    if (!v.m_flags.IsFlagSet(Vehicle.Flags.Spawned))
                    {
                        continue;
                    }
                    if (v.m_path == 0u)
                    {
                        continue;
                    }

                    _PathfindCount.Remove(vehicleID);

                    if (_stopped.Contains(vehicleID))
                    {
                        _stopped.Remove(vehicleID);
                    }
                    else if (!v.m_flags.IsFlagSet(Vehicle.Flags.WaitingTarget))
                    {
                        uint num3 = vehicleID & 7u;
                        if (num1 != num3 && num2 != num3)
                        {
                            _updated.Remove(vehicleID);
                            continue;
                        }
                        else if (_updated.Contains(vehicleID))
                        {
                            continue;
                        }
                    }

                    _updated.Add(vehicleID);

                    int vehicleStatus = GetHearseStatus(ref v);

                    if (vehicleStatus == VEHICLE_STATUS_HEARSE_RETURN && _lasttargets.ContainsKey(vehicleID))
                    {
                        if (Helper.IsBuildingWithDead(_lasttargets[vehicleID]))
                        {
                            foreach (ushort id in _cemeteries.Keys)
                            {
                                _cemeteries[id].AddPickup(_lasttargets[vehicleID]);
                            }
                        }
                        _lasttargets.Remove(vehicleID);
                        continue;
                    }
                    if (vehicleStatus != VEHICLE_STATUS_HEARSE_COLLECT && vehicleStatus != VEHICLE_STATUS_HEARSE_WAIT)
                    {
                        continue;
                    }

                    ushort target = _cemeteries[v.m_sourceBuilding].AssignTarget(vehicleID);

                    if (target != 0 && target != v.m_targetBuilding)
                    {
                        if (Helper.IsBuildingWithDead(v.m_targetBuilding))
                        {
                            foreach (ushort id in _cemeteries.Keys)
                            {
                                _cemeteries[id].AddPickup(v.m_targetBuilding);
                            }
                        }

                        _master.Remove(v.m_targetBuilding);
                        if (vehicleStatus == VEHICLE_STATUS_HEARSE_COLLECT)
                        {
                            _lasttargets[vehicleID] = v.m_targetBuilding;
                            if (_lastchangetimes.ContainsKey(vehicleID))
                            {
                                _lastchangetimes[vehicleID] = SimulationManager.instance.m_currentGameTime;
                            }
                            else
                            {
                                _lastchangetimes.Add(vehicleID, SimulationManager.instance.m_currentGameTime);
                            }
                        }
                        _CustomHearseAI.SetTarget(vehicleID, ref Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID], target);
                    }
                    else
                    {
                        if (_master.ContainsKey(v.m_targetBuilding))
                        {
                            if (_master[v.m_targetBuilding].Vehicle != vehicleID)
                            {
                                _master[v.m_targetBuilding] = new Claimant(vehicleID, v.m_targetBuilding);
                            }
                        }
                        else
                        {
                            _master.Add(v.m_targetBuilding, new Claimant(vehicleID, v.m_targetBuilding));
                        }
                    }
                }
            }

            foreach (ushort vehicleID in data.Hearses)
            {
                if (Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID].m_flags.IsFlagSet(Vehicle.Flags.WaitingPath))
                {
                    PathManager instance      = Singleton <PathManager> .instance;
                    byte        pathFindFlags = instance.m_pathUnits.m_buffer[(int)((UIntPtr)Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID].m_path)].m_pathFindFlags;
                    if ((pathFindFlags & 4) != 0)
                    {
                        _PathfindCount.Remove(vehicleID);
                    }
                    else if ((pathFindFlags & 8) != 0)
                    {
                        int vehicleStatus = GetHearseStatus(ref Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID]);
                        if (_lasttargets.ContainsKey(vehicleID))
                        {
                            Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID].m_flags &= ~Vehicle.Flags.WaitingPath;
                            Singleton <PathManager> .instance.ReleasePath(Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID].m_path);

                            Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID].m_path = 0u;
                            _CustomHearseAI.SetTarget(vehicleID, ref Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID], _lasttargets[vehicleID]);
                            _lasttargets.Remove(vehicleID);
                        }
                        else if ((vehicleStatus == VEHICLE_STATUS_HEARSE_WAIT || vehicleStatus == VEHICLE_STATUS_HEARSE_COLLECT) &&
                                 (Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID].m_flags.IsFlagSet(Vehicle.Flags.Spawned)) &&
                                 _cemeteries.ContainsKey(Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID].m_sourceBuilding) &&
                                 (!_PathfindCount.ContainsKey(vehicleID) || _PathfindCount[vehicleID] < 20))
                        {
                            if (!_PathfindCount.ContainsKey(vehicleID))
                            {
                                _PathfindCount[vehicleID] = 0;
                            }
                            _PathfindCount[vehicleID]++;
                            ushort target = _cemeteries[Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID].m_sourceBuilding].GetUnclaimedTarget(vehicleID);
                            if (target == 0)
                            {
                                _PathfindCount[vehicleID] = ushort.MaxValue;
                            }
                            else
                            {
                                if (Dispatcher._oldtargets != null)
                                {
                                    if (!Dispatcher._oldtargets.ContainsKey(vehicleID))
                                    {
                                        Dispatcher._oldtargets.Add(vehicleID, new HashSet <ushort>());
                                    }
                                    Dispatcher._oldtargets[vehicleID].Add(target);
                                }
                                Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID].m_flags &= ~Vehicle.Flags.WaitingPath;
                                Singleton <PathManager> .instance.ReleasePath(Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID].m_path);

                                Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID].m_path = 0u;
                                _CustomHearseAI.SetTarget(vehicleID, ref Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID], target);
                            }
                        }
                    }
                }
            }
        }
        public void SetTarget(ushort vehicleID, ref Vehicle data, ushort targetBuilding)
        {
            if (!data.m_flags.IsFlagSet(Vehicle.Flags.Spawned))
            {
                if (Identity.ModConf.MinimizeHearses)
                {
                    if (Dispatcher._cemeteries != null && Dispatcher._cemeteries.ContainsKey(data.m_sourceBuilding))
                    {
                        if (Dispatcher._cemeteries[data.m_sourceBuilding]._primary.Count > 0 || Dispatcher._cemeteries[data.m_sourceBuilding]._secondary.Count > 0 || Dispatcher._cemeteries[data.m_sourceBuilding]._checkups.Count > 0)
                        {
                            if ((!Dispatcher._cemeteries[data.m_sourceBuilding]._primary.Contains(targetBuilding) && !Dispatcher._cemeteries[data.m_sourceBuilding]._secondary.Contains(targetBuilding)) || !Helper.IsBuildingWithDead(targetBuilding))
                            {
                                data.Unspawn(vehicleID);
                                return;
                            }
                        }
                    }
                    else
                    {
                        data.Unspawn(vehicleID);
                        return;
                    }
                }

                if (Dispatcher._cemeteries != null && Dispatcher._cemeteries.ContainsKey(data.m_sourceBuilding))
                {
                    int max, now;
                    Dispatcher._cemeteries[data.m_sourceBuilding].CaluculateWorkingVehicles(out max, out now);

                    if (now > max)
                    {
                        data.Unspawn(vehicleID);
                        return;
                    }
                }
            }

            BuildingManager instance = Singleton <BuildingManager> .instance;

            ushort current = data.m_targetBuilding;

            uint   path = data.m_path;
            byte   pathPositionIndex = data.m_pathPositionIndex;
            byte   lastPathOffset    = data.m_lastPathOffset;
            ushort target            = targetBuilding;

            int vehicleStatus = Dispatcher.GetHearseStatus(ref data);
            int retry_max     = 1;

            if (vehicleStatus == Dispatcher.VEHICLE_STATUS_HEARSE_WAIT)
            {
                if (Dispatcher._oldtargets != null)
                {
                    Dispatcher._oldtargets.Remove(vehicleID);
                }
                retry_max = 20;
            }

            for (int retry = 0; retry < retry_max; retry++)
            {
                if (retry > 0)
                {
                    if (Dispatcher._cemeteries == null || !Dispatcher._cemeteries.ContainsKey(data.m_sourceBuilding))
                    {
                        break;
                    }
                    target = Dispatcher._cemeteries[data.m_sourceBuilding].GetUnclaimedTarget(vehicleID);
                    if (target == 0)
                    {
                        break;
                    }

                    if (Dispatcher._oldtargets != null)
                    {
                        if (!Dispatcher._oldtargets.ContainsKey(vehicleID))
                        {
                            Dispatcher._oldtargets.Add(vehicleID, new HashSet <ushort>());
                        }
                        Dispatcher._oldtargets[vehicleID].Add(target);
                    }
                }

                this.RemoveTarget(vehicleID, ref data);
                data.m_targetBuilding = targetBuilding;
                data.m_flags         &= ~Vehicle.Flags.WaitingTarget;
                data.m_waitCounter    = 0;
                if (targetBuilding != 0)
                {
                    instance.m_buildings.m_buffer[(int)targetBuilding].AddGuestVehicle(vehicleID, ref data);
                }
                else
                {
                    if (data.m_flags.IsFlagSet(Vehicle.Flags.TransferToTarget))
                    {
                        if (data.m_transferSize > 0)
                        {
                            TransferManager.TransferOffer offer = default(TransferManager.TransferOffer);
                            offer.Priority = 7;
                            offer.Vehicle  = vehicleID;
                            if (data.m_sourceBuilding != 0)
                            {
                                offer.Position = (data.GetLastFramePosition() + Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_position) * 0.5f;
                            }
                            else
                            {
                                offer.Position = data.GetLastFramePosition();
                            }
                            offer.Amount = 1;
                            offer.Active = true;
                            Singleton <TransferManager> .instance.AddOutgoingOffer((TransferManager.TransferReason) data.m_transferType, offer);

                            data.m_flags |= Vehicle.Flags.WaitingTarget;
                        }
                        else
                        {
                            data.m_flags |= Vehicle.Flags.GoingBack;
                        }
                    }
                    if (data.m_flags.IsFlagSet(Vehicle.Flags.TransferToSource))
                    {
                        VehicleInfo m_info = Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID].Info;
                        int         num    = ((HearseAI)m_info.m_vehicleAI).m_corpseCapacity;
                        if (this.ShouldReturnToSource(vehicleID, ref data))
                        {
                            num = (int)data.m_transferSize;
                        }
                        else if (data.m_sourceBuilding != 0)
                        {
                            BuildingInfo info = instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].Info;
                            if (info == null)
                            {
                                return;
                            }
                            int num2;
                            int num3;
                            info.m_buildingAI.GetMaterialAmount(data.m_sourceBuilding, ref instance.m_buildings.m_buffer[(int)data.m_sourceBuilding], TransferManager.TransferReason.Dead, out num2, out num3);
                            num = Mathf.Min(num, num3 - num2);
                        }
                        if ((int)data.m_transferSize < num)
                        {
                            TransferManager.TransferOffer offer2 = default(TransferManager.TransferOffer);
                            offer2.Priority = 7;
                            offer2.Vehicle  = vehicleID;
                            if (data.m_sourceBuilding != 0)
                            {
                                offer2.Position = (data.GetLastFramePosition() + Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)data.m_sourceBuilding].m_position) * 0.5f;
                            }
                            else
                            {
                                offer2.Position = data.GetLastFramePosition();
                            }
                            offer2.Amount = 1;
                            offer2.Active = true;
                            Singleton <TransferManager> .instance.AddIncomingOffer((TransferManager.TransferReason) data.m_transferType, offer2);

                            data.m_flags |= Vehicle.Flags.WaitingTarget;
                        }
                        else
                        {
                            data.m_flags |= Vehicle.Flags.GoingBack;
                        }
                    }
                }

                if ((targetBuilding == 0 ||
                     (vehicleStatus != Dispatcher.VEHICLE_STATUS_HEARSE_COLLECT && vehicleStatus != Dispatcher.VEHICLE_STATUS_HEARSE_WAIT)))
                {
                    if (!StartPathFind(vehicleID, ref data))
                    {
                        data.Unspawn(vehicleID);
                    }
                    return;
                }

                if (StartPathFind(vehicleID, ref Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID]))
                {
                    if (Dispatcher._oldtargets != null)
                    {
                        if (!Dispatcher._oldtargets.ContainsKey(vehicleID))
                        {
                            Dispatcher._oldtargets.Add(vehicleID, new HashSet <ushort>());
                        }
                        Dispatcher._oldtargets[vehicleID].Add(target);
                    }
                    if (Dispatcher._master != null)
                    {
                        if (Dispatcher._master.ContainsKey(target))
                        {
                            if (Dispatcher._master[target].Vehicle != vehicleID)
                            {
                                Dispatcher._master[target] = new Claimant(vehicleID, target);
                            }
                        }
                        else if (target != 0)
                        {
                            Dispatcher._master.Add(target, new Claimant(vehicleID, target));
                        }
                    }
                    return;
                }
            }

            if (vehicleStatus == Dispatcher.VEHICLE_STATUS_HEARSE_COLLECT)
            {
                target = current;
                RemoveTarget(vehicleID, ref Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID]);
                Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID].m_targetBuilding    = target;
                Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID].m_path              = path;
                Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID].m_pathPositionIndex = pathPositionIndex;
                Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID].m_lastPathOffset    = lastPathOffset;
                Singleton <BuildingManager> .instance.m_buildings.m_buffer[(int)current].AddGuestVehicle(vehicleID, ref Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID]);

                if (Dispatcher._master != null)
                {
                    if (Dispatcher._master.ContainsKey(target))
                    {
                        if (Dispatcher._master[target].Vehicle != vehicleID)
                        {
                            Dispatcher._master[target] = new Claimant(vehicleID, target);
                        }
                    }
                    else if (target != 0)
                    {
                        Dispatcher._master.Add(target, new Claimant(vehicleID, target));
                    }
                }
            }
            else
            {
                Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID].Unspawn(vehicleID);
            }
        }
示例#4
0
        private ushort GetClosestTarget(ushort vehicleID, ref HashSet <ushort> targets, bool immediateOnly, SearchDirection immediateDirection)
        {
            Vehicle vehicle = Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID];

            Building[] buildings = Singleton <BuildingManager> .instance.m_buildings.m_buffer;

            List <ushort> removals = new List <ushort>();

            ushort target = vehicle.m_targetBuilding;

            if (_master.ContainsKey(target) && _master[target].IsValid && _master[target].Vehicle != vehicleID)
            {
                target = 0;
            }
            int   targetProblematicLevel = 0;
            float targetdistance         = float.PositiveInfinity;
            float distance = float.PositiveInfinity;

            Vector3 velocity = vehicle.GetLastFrameVelocity();
            Vector3 position = vehicle.GetLastFramePosition();

            double bearing = double.PositiveInfinity;
            double facing  = Math.Atan2(velocity.z, velocity.x);

            if (targets.Contains(target))
            {
                if (!Helper.IsBuildingWithDead(target))
                {
                    removals.Add(target);
                    target = 0;
                }
                else
                {
                    if ((buildings[target].m_problems & Notification.Problem.Death) != Notification.Problem.None)
                    {
                        if (Identity.ModConf.PrioritizeTargetWithRedSigns && (buildings[target].m_problems & Notification.Problem.MajorProblem) != Notification.Problem.None)
                        {
                            targetProblematicLevel = 2;
                        }
                        else
                        {
                            targetProblematicLevel = 1;
                        }
                    }

                    Vector3 a = buildings[target].m_position;

                    targetdistance = distance = (a - position).sqrMagnitude;

                    bearing = Math.Atan2(a.z - position.z, a.x - position.x);
                }
            }
            else if (!immediateOnly)
            {
                target = 0;
            }

            foreach (ushort id in targets)
            {
                if (target == id)
                {
                    continue;
                }

                if (!Helper.IsBuildingWithDead(id))
                {
                    removals.Add(id);
                    continue;
                }

                if (_master.ContainsKey(id) && _master[id].IsValid && !_master[id].IsChallengable)
                {
                    continue;
                }

                if (_master.ContainsKey(id) && _master[id].IsValid && _master[id].Vehicle != vehicleID)
                {
                    Vehicle vehicle2 = Singleton <VehicleManager> .instance.m_vehicles.m_buffer[_master[id].Vehicle];
                    if (vehicle2.m_flags.IsFlagSet(Vehicle.Flags.Spawned) && vehicle2.m_path != 0 &&
                        Singleton <PathManager> .instance.m_pathUnits.m_buffer[vehicle2.m_path].m_nextPathUnit == 0)
                    {
                        byte b = vehicle2.m_pathPositionIndex;
                        if (b == 255)
                        {
                            b = 0;
                        }
                        if ((b & 1) == 0)
                        {
                            b += 1;
                        }
                        if ((b >> 1) + 1 >= Singleton <PathManager> .instance.m_pathUnits.m_buffer[vehicle2.m_path].m_positionCount)
                        {
                            continue;
                        }
                    }
                }

                Vector3 p = buildings[id].m_position;
                float   d = (p - position).sqrMagnitude;

                int candidateProblematicLevel = 0;
                if ((buildings[id].m_problems & Notification.Problem.Death) != Notification.Problem.None)
                {
                    if (Identity.ModConf.PrioritizeTargetWithRedSigns && (buildings[id].m_problems & Notification.Problem.MajorProblem) != Notification.Problem.None)
                    {
                        candidateProblematicLevel = 2;
                    }
                    else
                    {
                        candidateProblematicLevel = 1;
                    }
                }

                if (_oldtargets.ContainsKey(vehicleID) && _oldtargets[vehicleID].Count > 5 && targetProblematicLevel >= candidateProblematicLevel)
                {
                    continue;
                }

                if (_master.ContainsKey(id) && _master[id].IsValid && _master[id].IsChallengable)
                {
                    if (targetProblematicLevel > candidateProblematicLevel)
                    {
                        continue;
                    }

                    if (d > targetdistance * 0.9)
                    {
                        continue;
                    }

                    if (d > distance)
                    {
                        continue;
                    }

                    if (d > _master[id].Distance * 0.9)
                    {
                        continue;
                    }

                    double angle = Helper.GetAngleDifference(facing, Math.Atan2(p.z - position.z, p.x - position.x));

                    int immediateLevel = GetImmediateLevel(d, angle, immediateDirection);

                    if (immediateLevel == 0)
                    {
                        continue;
                    }

                    if (_oldtargets.ContainsKey(vehicleID) && _oldtargets[vehicleID].Contains(id))
                    {
                        continue;
                    }
                }
                else
                {
                    double angle          = Helper.GetAngleDifference(facing, Math.Atan2(p.z - position.z, p.x - position.x));
                    int    immediateLevel = GetImmediateLevel(d, angle, immediateDirection);

                    if (immediateOnly && immediateLevel == 0)
                    {
                        continue;
                    }

                    if (_oldtargets.ContainsKey(vehicleID) && _oldtargets[vehicleID].Contains(id))
                    {
                        continue;
                    }

                    if (targetProblematicLevel > candidateProblematicLevel)
                    {
                        continue;
                    }

                    if (targetProblematicLevel < candidateProblematicLevel)
                    {
                        // No additonal conditions at the moment. Problematic buildings always have priority over nonproblematic buildings
                    }
                    else
                    {
                        if (d > targetdistance * 0.9)
                        {
                            continue;
                        }

                        if (d > distance)
                        {
                            continue;
                        }

                        if (immediateLevel > 0)
                        {
                            // If it's that close, no need to further qualify its priority
                        }
                        else if (IsAlongTheWay(d, angle))
                        {
                            // If it's in the general direction the vehicle is facing, it's good enough
                        }
                        else if (!double.IsPositiveInfinity(bearing))
                        {
                            if (IsAlongTheWay(d, Helper.GetAngleDifference(bearing, Math.Atan2(p.z - position.z, p.x - position.x))))
                            {
                                // If it's in the general direction along the vehicle's target path, we will have to settle for it at this point
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else
                        {
                            // If it's not closeby and not in the direction the vehicle is facing, but our vehicle also has no bearing, we will take whatever is out there
                        }
                    }
                }

                target = id;
                targetProblematicLevel = candidateProblematicLevel;
                distance = d;
            }

            foreach (ushort id in removals)
            {
                _master.Remove(id);
                targets.Remove(id);
            }

            return(target);
        }
示例#5
0
        public ushort AssignTarget(ushort vehicleID)
        {
            Vehicle vehicle = Singleton <VehicleManager> .instance.m_vehicles.m_buffer[vehicleID];
            ushort  target  = 0;

            if (vehicle.m_sourceBuilding != _buildingID)
            {
                return(target);
            }

            if (Singleton <PathManager> .instance.m_pathUnits.m_buffer[vehicle.m_path].m_nextPathUnit == 0)
            {
                byte b = vehicle.m_pathPositionIndex;
                if (b == 255)
                {
                    b = 0;
                }
                if ((b & 1) == 0)
                {
                    b += 1;
                }
                if ((b >> 1) + 1 >= Singleton <PathManager> .instance.m_pathUnits.m_buffer[vehicle.m_path].m_positionCount)
                {
                    return(target);
                }
            }

            ushort current = vehicle.m_targetBuilding;

            if (!Helper.IsBuildingWithDead(current))
            {
                _oldtargets.Remove(vehicleID);
                _master.Remove(current);
                _primary.Remove(current);
                _secondary.Remove(current);

                current = 0;
            }
            else if (_master.ContainsKey(current))
            {
                if (_master[current].IsValid && _master[current].Vehicle != vehicleID)
                {
                    current = 0;
                }
            }

            int vehicleStatus = Dispatcher.GetHearseStatus(ref vehicle);

            if (current != 0 && vehicleStatus == Dispatcher.VEHICLE_STATUS_HEARSE_COLLECT && _lastchangetimes.ContainsKey(vehicleID) && (SimulationManager.instance.m_currentGameTime - _lastchangetimes[vehicleID]).TotalDays < 0.5)
            {
                return(target);
            }

            bool            immediateOnly      = (_primary.Contains(current) || _secondary.Contains(current));
            SearchDirection immediateDirection = GetImmediateSearchDirection(vehicleID);

            if (immediateOnly && immediateDirection == SearchDirection.None)
            {
                target = current;
            }
            else
            {
                target = GetClosestTarget(vehicleID, ref _primary, immediateOnly, immediateDirection);

                if (target == 0)
                {
                    target = GetClosestTarget(vehicleID, ref _secondary, immediateOnly, immediateDirection);
                }
            }

            if (target == 0)
            {
                _oldtargets.Remove(vehicleID);

                if ((vehicle.m_targetBuilding != 0 && WithinPrimaryRange(vehicle.m_targetBuilding)) || _checkups.Count == 0)
                {
                    target = vehicle.m_targetBuilding;
                }
                else
                {
                    target = _checkups[0];
                    _checkups.RemoveAt(0);
                }
            }

            return(target);
        }
示例#6
0
        private ushort GetUnclaimedTarget(ICollection <ushort> targets, ushort vehicleID)
        {
            Building[] buildings = Singleton <BuildingManager> .instance.m_buildings.m_buffer;

            List <ushort> removals = new List <ushort>();

            ushort target = 0;
            int    targetProblematicLevel = 0;
            float  distance = float.PositiveInfinity;

            Building landfill = buildings[(int)_buildingID];

            foreach (ushort id in targets)
            {
                if (target == id)
                {
                    continue;
                }

                if (_oldtargets.ContainsKey(vehicleID) && _oldtargets[vehicleID].Contains(id))
                {
                    continue;
                }

                if (!Helper.IsBuildingWithDead(id))
                {
                    removals.Add(id);
                    continue;
                }

                Vector3 p = buildings[id].m_position;
                float   d = (p - landfill.m_position).sqrMagnitude;

                int candidateProblematicLevel = 0;
                if ((buildings[id].m_problems & Notification.Problem.Death) != Notification.Problem.None)
                {
                    if (Identity.ModConf.PrioritizeTargetWithRedSigns && (buildings[id].m_problems & Notification.Problem.MajorProblem) != Notification.Problem.None)
                    {
                        candidateProblematicLevel = 2;
                    }
                    else
                    {
                        candidateProblematicLevel = 1;
                    }
                }
                if (_master.ContainsKey(id) && _master[id].IsValid)
                {
                    continue;
                }
                else
                {
                    if (targetProblematicLevel > candidateProblematicLevel)
                    {
                        continue;
                    }

                    if (targetProblematicLevel < candidateProblematicLevel)
                    {
                        // No additonal conditions at the moment. Problematic buildings always have priority over nonproblematic buildings
                    }
                    else
                    {
                        if (d > distance)
                        {
                            continue;
                        }
                    }
                }

                target = id;
                targetProblematicLevel = candidateProblematicLevel;
                distance = d;
            }

            foreach (ushort id in removals)
            {
                _master.Remove(id);
                targets.Remove(id);
            }
            return(target);
        }