public static void AddKnownPlayerLocation(Vector3D coords, string faction, double radius, int duration = -1, int maxEncounters = -1, int minThreatToAvoidAbandonment = -1)
        {
            bool foundExistingLocation = false;
            var  sphere = new BoundingSphereD(coords, radius);
            List <KnownPlayerLocation> intersectingLocations = new List <KnownPlayerLocation>();

            foreach (var location in Locations)
            {
                if (location.NpcFaction != faction)
                {
                    continue;
                }

                if (!sphere.Intersects(location.Sphere) && location.Sphere.Contains(coords) == ContainmentType.Disjoint)
                {
                    continue;
                }

                intersectingLocations.Add(location);
                foundExistingLocation = true;
            }

            if (foundExistingLocation == false)
            {
                Logger.AddMsg("Creating KnownPlayerLocation at " + coords.ToString() + " / Radius: " + radius.ToString(), true);
                Locations.Add(new KnownPlayerLocation(faction, coords, radius, duration, maxEncounters, minThreatToAvoidAbandonment));
                AlertPlayersOfNewKPL(coords, radius, faction);
            }
            else
            {
                var currentLocation = new KnownPlayerLocation(faction, coords, radius, duration, maxEncounters, minThreatToAvoidAbandonment);

                foreach (var location in intersectingLocations)
                {
                    var dirFromCurrentToIntersection = Vector3D.Normalize(location.Coords - currentLocation.Coords);
                    var coordsBetweenCenters         = dirFromCurrentToIntersection * (Vector3D.Distance(location.Coords, currentLocation.Coords) / 2) + currentLocation.Coords;
                    var radiusToUse    = location.Radius == currentLocation.Radius ? currentLocation.Radius : currentLocation.Radius > location.Radius ? currentLocation.Radius : location.Radius;
                    var outerRimCoords = -dirFromCurrentToIntersection * radiusToUse + currentLocation.Coords;
                    var finalRadius    = Vector3D.Distance(outerRimCoords, coordsBetweenCenters);
                    currentLocation = new KnownPlayerLocation(faction, coordsBetweenCenters, finalRadius, duration, maxEncounters, minThreatToAvoidAbandonment);
                    Locations.Remove(location);
                }

                Locations.Add(currentLocation);
                AlertPlayersOfNewKPL(coords, radius, faction);
                Logger.AddMsg("Known Player Location(s) Already Exist, Merging Locations.", true);
            }

            SaveLocations();
        }
        public static bool IsPositionInKnownPlayerLocation(KnownPlayerLocation location, Vector3D coords, bool matchFaction = false, string faction = "")
        {
            if (matchFaction == true && faction != location.NpcFaction)
            {
                return(false);
            }

            if (Vector3D.Distance(coords, location.Coords) > location.Radius)
            {
                return(false);
            }

            return(true);
        }