Esempio n. 1
0
        // { "customLocation": [{x, y}] } where x, y are relative to map (for a custom location ex. a new house)
        // { "customRegion": [{x1, y1}, {x2, y2}] where x, y are relative to map (for a custom region ex. a new farm)
        // Any custom locations with given location on the map
        public Dictionary <string, MapVector[]> GetCustomMapLocations()
        {
            var customMapVectors = new Dictionary <string, MapVector[]>();

            foreach (KeyValuePair <string, JObject[]> mapVectors in Config.CustomMapLocations)
            {
                var mapVectorArr = new MapVector[mapVectors.Value.Length];
                for (int i = 0; i < mapVectors.Value.Length; i++)
                {
                    var mapVector = mapVectors.Value[i];

                    // Marker doesn't need to specify corresponding Tile position
                    if (mapVector.GetValue("TileX") == null || mapVector.GetValue("TileY") == null)
                    {
                        mapVectorArr[i] = new MapVector(
                            (int)mapVector.GetValue("MapX"),
                            (int)mapVector.GetValue("MapY")
                            );
                    }
                    // Region must specify corresponding Tile positions for
                    // Calculations on movement within location
                    else
                    {
                        mapVectorArr[i] = new MapVector(
                            (int)mapVector.GetValue("MapX"),
                            (int)mapVector.GetValue("MapY"),
                            (int)mapVector.GetValue("TileX"),
                            (int)mapVector.GetValue("TileY")
                            );
                    }
                }
                customMapVectors.Add(mapVectors.Key, mapVectorArr);
            }

            return(customMapVectors);
        }
Esempio n. 2
0
        // { "customLocation": [{x, y}] } where x, y are relative to map (for a custom location ex. a new house)
        // { "customRegion": [{x1, y1}, {x2, y2}] where x, y are relative to map (for a custom region ex. a new farm)
        // Any custom locations with given location on the map
        public Dictionary <string, MapVector[]> GetCustomMapLocations()
        {
            var customMapVectors = new Dictionary <string, MapVector[]>();
            var moddedLocations  = new List <string>();

            foreach (KeyValuePair <string, JObject[]> mapVectors in Config.CustomMapLocations)
            {
                var mapVectorArr = new MapVector[mapVectors.Value.Length];
                for (int i = 0; i < mapVectors.Value.Length; i++)
                {
                    var mapVector = mapVectors.Value[i];

                    // Marker doesn't need to specify corresponding Tile position
                    if (mapVector.GetValue("TileX") == null || mapVector.GetValue("TileY") == null)
                    {
                        mapVectorArr[i] = new MapVector(
                            (int)mapVector.GetValue("MapX"),
                            (int)mapVector.GetValue("MapY")
                            );
                    }
                    // Region must specify corresponding Tile positions for
                    // Calculations on movement within location
                    else
                    {
                        mapVectorArr[i] = new MapVector(
                            (int)mapVector.GetValue("MapX"),
                            (int)mapVector.GetValue("MapY"),
                            (int)mapVector.GetValue("TileX"),
                            (int)mapVector.GetValue("TileY")
                            );
                    }
                }
                moddedLocations.Add(mapVectors.Key);
                customMapVectors.Add(mapVectors.Key, mapVectorArr);
            }

            // Automatically adjust tracking for modded maps that are sized differently from vanilla map
            foreach (var location in Game1.locations)
            {
                if (!location.IsOutdoors || location.Name == "Summit" || customMapVectors.ContainsKey(location.Name) || !ModConstants.MapVectors.TryGetValue(location.Name, out var mapVector))
                {
                    continue;
                }
                if (mapVector.LastOrDefault().TileX != location.Map.DisplayWidth / Game1.tileSize ||
                    mapVector.LastOrDefault().TileY != location.Map.DisplayHeight / Game1.tileSize)
                {
                    moddedLocations.Add(location.Name);
                    customMapVectors.Add(location.Name,
                                         new MapVector[]
                    {
                        mapVector.FirstOrDefault(),
                        new MapVector(
                            mapVector.LastOrDefault().MapX,
                            mapVector.LastOrDefault().MapY,
                            location.Map.DisplayWidth / Game1.tileSize,
                            location.Map.DisplayHeight / Game1.tileSize
                            )
                    });
                }
            }

            if (moddedLocations.Count > 0)
            {
                if (moddedLocations.Count == 1)
                {
                    Monitor.Log($"Detected modded location {moddedLocations[0]}. Adjusting map tracking to scale.", LogLevel.Debug);
                }
                else
                {
                    var locationList = "";
                    for (var i = 0; i < moddedLocations.Count; i++)
                    {
                        locationList += moddedLocations[i] + (i + 1 == moddedLocations.Count ? ", " : "");
                    }

                    Monitor.Log($"Detected modded locations {locationList}. Adjusting map tracking to scale.", LogLevel.Debug);
                }
            }

            return(customMapVectors);
        }
Esempio n. 3
0
        // Any custom locations with given location on the map
        private void LoadCustomMapLocations()
        {
            foreach (var mapVectors in ModMain.CustomData.CustomMapLocations)
            {
                var mapVectorArr = new MapVector[mapVectors.Value.Length];
                for (var i = 0; i < mapVectors.Value.Length; i++)
                {
                    var mapVector = mapVectors.Value[i];

                    // Marker doesn't need to specify corresponding Tile position
                    if (mapVector.GetValue("TileX") == null || mapVector.GetValue("TileY") == null)
                    {
                        mapVectorArr[i] = new MapVector(
                            (int)mapVector.GetValue("MapX"),
                            (int)mapVector.GetValue("MapY")
                            );
                    }
                    // Region must specify corresponding Tile positions for
                    // Calculations on movement within location
                    else
                    {
                        mapVectorArr[i] = new MapVector(
                            (int)mapVector.GetValue("MapX"),
                            (int)mapVector.GetValue("MapY"),
                            (int)mapVector.GetValue("TileX"),
                            (int)mapVector.GetValue("TileY")
                            );
                    }
                }

                MapVectors.Add(mapVectors.Key, mapVectorArr);
            }

            // Automatically adjust tracking for modded maps that are sized differently from vanilla map
            foreach (var location in Game1.locations)
            {
                var locationName = location.uniqueName.Value ?? location.Name;

                if (!location.IsOutdoors || locationName == "Summit" || MapVectors.ContainsKey(locationName) ||
                    !ModConstants.MapVectors.TryGetValue(locationName, out var mapVector))
                {
                    continue;
                }
                if (mapVector.LastOrDefault().TileX != location.Map.DisplayWidth / Game1.tileSize ||
                    mapVector.LastOrDefault().TileY != location.Map.DisplayHeight / Game1.tileSize)
                {
                    MapVectors.Add(locationName,
                                   new[]
                    {
                        mapVector.FirstOrDefault(),
                        new MapVector(
                            mapVector.LastOrDefault().MapX,
                            mapVector.LastOrDefault().MapY,
                            location.Map.DisplayWidth / Game1.tileSize,
                            location.Map.DisplayHeight / Game1.tileSize
                            )
                    });
                }
            }

            var customLocations = MapVectors.Keys.ToArray();

            if (MapVectors.Keys.Count > 0)
            {
                if (customLocations.Length == 1)
                {
                    ModMain.IMonitor.Log($"Handled tracking for custom location: {customLocations[0]}.", LogLevel.Debug);
                }
                else
                {
                    var locationList = "";
                    for (var i = 0; i < customLocations.Length; i++)
                    {
                        locationList += customLocations[i] + (i + 1 == customLocations.Length ? "" : ", ");
                    }

                    ModMain.IMonitor.Log($"Handled tracking for custom locations: {locationList}.", LogLevel.Debug);
                }
            }
        }
Esempio n. 4
0
        // MAIN METHOD FOR PINPOINTING CHARACTERS ON THE MAP
        // Calculated from mapping of game tile positions to pixel coordinates of the map in MapModConstants.
        // Requires MapModConstants and modified map page in ./assets
        public static Vector2 LocationToMap(string locationName, int tileX = -1, int tileY = -1,
                                            Dictionary <string, MapVector[]> CustomMapLocations = null, bool isPlayer = false)
        {
            if (FarmBuildings.TryGetValue(locationName, out var mapLoc))
            {
                return(mapLoc.Value);
            }

            if (locationName.StartsWith("UndergroundMine"))
            {
                var mine = locationName.Substring("UndergroundMine".Length, locationName.Length - "UndergroundMine".Length);
                if (int.TryParse(mine, out var mineLevel))
                {
                    // Skull cave
                    if (mineLevel > 120)
                    {
                        locationName = "SkullCave";
                    }
                    // Mines
                    else
                    {
                        locationName = "Mine";
                    }
                }
            }

            if (CustomMapLocations != null &&
                !CustomMapLocations.ContainsKey(locationName) && !ModConstants.MapVectors.ContainsKey(locationName))
            {
                return(new Vector2(-1000, -1000));
            }
            if (!ModConstants.MapVectors.ContainsKey(locationName))
            {
                return(new Vector2(-1000, -1000));
            }

            MapVector[] locVectors = (CustomMapLocations != null && CustomMapLocations.ContainsKey(locationName)) ? CustomMapLocations[locationName] : ModConstants.MapVectors[locationName];

            ;      int x;
            int        y;

            // Precise (static) regions and indoor locations
            if (locVectors.Count() == 1 || tileX == -1 || tileY == -1)
            {
                x = locVectors.FirstOrDefault().MapX;
                y = locVectors.FirstOrDefault().MapY;
            }
            else
            {
                // Sort map vectors by distance to point
                var vectors = locVectors.OrderBy(vector =>
                                                 Math.Sqrt(Math.Pow(vector.TileX - tileX, 2) + Math.Pow(vector.TileY - tileY, 2)));

                MapVector lower        = null;
                MapVector upper        = null;
                var       hasEqualTile = false;

                // Create rectangle bound from two pre-defined points (lower & upper bound) and calculate map scale for that area
                foreach (var vector in vectors)
                {
                    if (lower != null && upper != null)
                    {
                        if (lower.TileX == upper.TileX || lower.TileY == upper.TileY)
                        {
                            hasEqualTile = true;
                        }
                        else
                        {
                            break;
                        }
                    }

                    if ((lower == null || hasEqualTile) && tileX >= vector.TileX && tileY >= vector.TileY)
                    {
                        lower = vector;
                        continue;
                    }

                    if ((upper == null || hasEqualTile) && tileX <= vector.TileX && tileY <= vector.TileY)
                    {
                        upper = vector;
                    }
                }

                // Handle null cases - not enough vectors to calculate using lower/upper bound strategy
                // Uses fallback strategy - get closest points such that lower != upper
                var tilePos = "(" + tileX + ", " + tileY + ")";
                if (lower == null)
                {
                    lower = upper == vectors.First() ? vectors.Skip(1).First() : vectors.First();
                }

                if (upper == null)
                {
                    upper = lower == vectors.First() ? vectors.Skip(1).First() : vectors.First();
                }

                x = (int)(lower.MapX +
                          (tileX - lower.TileX) / (double)(upper.TileX - lower.TileX) * (upper.MapX - lower.MapX));
                y = (int)(lower.MapY +
                          (tileY - lower.TileY) / (double)(upper.TileY - lower.TileY) * (upper.MapY - lower.MapY));

                if (DEBUG_MODE && isPlayer)
                {
                    _tileUpper = new Vector2(upper.TileX, upper.TileY);
                    _tileLower = new Vector2(lower.TileX, lower.TileY);
                }
            }

            return(new Vector2(x, y));
        }
Esempio n. 5
0
        // MAIN METHOD FOR PINPOINTING CHARACTERS ON THE MAP
        // Calculated from mapping of game tile positions to pixel coordinates of the map in MapModConstants.
        // Requires MapModConstants and modified map page in ./assets
        public static Vector2 LocationToMap(string locationName, int tileX = -1, int tileY = -1,
                                            Dictionary <string, MapVector[]> CustomMapVectors = null, bool isPlayer = false)
        {
            if (FarmBuildings.TryGetValue(locationName, out var mapLoc))
            {
                return(mapLoc.Value);
            }

            if (locationName.StartsWith("UndergroundMine"))
            {
                var mine = locationName.Substring("UndergroundMine".Length, locationName.Length - "UndergroundMine".Length);
                if (int.TryParse(mine, out var mineLevel))
                {
                    // Skull cave
                    if (mineLevel > 120)
                    {
                        locationName = "SkullCave";
                    }
                    // Mines
                    else
                    {
                        locationName = "Mine";
                    }
                }
            }

            MapVector[] locVectors;

            if (CustomMapVectors != null && (locationName == "Farm" || locationName == "FarmHouse" || locationName == "Cellar"))
            {
                // Handle different farm types for custom vectors
                var farms = new string[5] {
                    "Farm", "Farm_Riverland", "Farm_Forest", "Farm_Hills", "Farm_Wilderness"
                };
                if (CustomMapVectors.Keys.Any(locName => locName == farms.ElementAtOrDefault(Game1.whichFarm)))
                {
                    if (!CustomMapVectors.TryGetValue(locationName, out locVectors))
                    {
                        if (!ModConstants.MapVectors.TryGetValue(locationName, out locVectors))
                        {
                            return(Vector2.Zero);
                        }
                    }
                }
                else
                {
                    if (!ModConstants.MapVectors.TryGetValue(locationName, out locVectors))
                    {
                        return(Vector2.Zero);
                    }
                }
            }
            // If not in custom vectors, use default
            else if (!(CustomMapVectors != null && CustomMapVectors.TryGetValue(locationName, out locVectors)))
            {
                if (!ModConstants.MapVectors.TryGetValue(locationName, out locVectors))
                {
                    return(Vector2.Zero);
                }
            }

            if (locVectors == null)
            {
                return(Vector2.Zero);
            }

            int x;
            int y;

            // Precise (static) regions and indoor locations
            if (locVectors.Count() == 1 || tileX == -1 || tileY == -1)
            {
                x = locVectors.FirstOrDefault().MapX;
                y = locVectors.FirstOrDefault().MapY;
            }
            else
            {
                // Sort map vectors by distance to point
                var vectors = locVectors.OrderBy(vector =>
                                                 Math.Sqrt(Math.Pow(vector.TileX - tileX, 2) + Math.Pow(vector.TileY - tileY, 2)));

                MapVector lower      = null;
                MapVector upper      = null;
                var       isSameAxis = false;

                // Create rectangle bound from two pre-defined points (lower & upper bound) and calculate map scale for that area
                foreach (var vector in vectors)
                {
                    if (lower != null && upper != null)
                    {
                        if (lower.TileX == upper.TileX || lower.TileY == upper.TileY)
                        {
                            isSameAxis = true;
                        }
                        else
                        {
                            break;
                        }
                    }

                    if ((lower == null || isSameAxis) && tileX >= vector.TileX && tileY >= vector.TileY)
                    {
                        lower = vector;
                        continue;
                    }

                    if ((upper == null || isSameAxis) && tileX <= vector.TileX && tileY <= vector.TileY)
                    {
                        upper = vector;
                    }
                }

                // Handle null cases - not enough vectors to calculate using lower/upper bound strategy
                // Uses fallback strategy - get closest points such that lower != upper
                var tilePos = "(" + tileX + ", " + tileY + ")";
                if (lower == null)
                {
                    lower = upper == vectors.First() ? vectors.Skip(1).First() : vectors.First();
                }

                if (upper == null)
                {
                    upper = lower == vectors.First() ? vectors.Skip(1).First() : vectors.First();
                }

                x = (int)MathHelper.Clamp((int)(lower.MapX + (tileX - lower.TileX) / (double)(upper.TileX - lower.TileX) * (upper.MapX - lower.MapX)), 0, 1200);
                y = (int)MathHelper.Clamp((int)(lower.MapY + (tileY - lower.TileY) / (double)(upper.TileY - lower.TileY) * (upper.MapY - lower.MapY)), 0, 720);

                if (DEBUG_MODE && isPlayer)
                {
                    _tileUpper = new Vector2(upper.TileX, upper.TileY);
                    _tileLower = new Vector2(lower.TileX, lower.TileY);
                }
            }

            return(new Vector2(x, y));
        }
Esempio n. 6
0
        // { "customLocation": [{x, y}] } where x, y are relative to map (for a custom location ex. a new house)
        // { "customRegion": [{x1, y1}, {x2, y2}] where x, y are relative to map (for a custom region ex. a new farm)
        // Any custom locations with given location on the map
        private void LoadCustomMapLocations()
        {
            // Merge SVE Config with main config
            var CustomMapLocations = SVEConfig != null
        ? ModMain.Config.CustomMapLocations.Concat(SVEConfig.CustomMapLocations).ToLookup(x => x.Key, x => x.Value)
                                     .ToDictionary(x => x.Key, g => g.First())
        : ModMain.Config.CustomMapLocations;

            foreach (var mapVectors in CustomMapLocations)
            {
                var mapVectorArr = new MapVector[mapVectors.Value.Length];
                for (var i = 0; i < mapVectors.Value.Length; i++)
                {
                    // Don't use IF2R config for greenhouse if not default farm (hard-coded location)
                    if (ModMain.IsSVE && mapVectors.Key == "Greenhouse" && Game1.whichFarm != 0)
                    {
                        mapVectorArr[i] = ModConstants.MapVectors["Greenhouse"].FirstOrDefault();
                    }
                    else
                    {
                        var mapVector = mapVectors.Value[i];

                        // Marker doesn't need to specify corresponding Tile position
                        if (mapVector.GetValue("TileX") == null || mapVector.GetValue("TileY") == null)
                        {
                            mapVectorArr[i] = new MapVector(
                                (int)mapVector.GetValue("MapX"),
                                (int)mapVector.GetValue("MapY")
                                );
                        }
                        // Region must specify corresponding Tile positions for
                        // Calculations on movement within location
                        else
                        {
                            mapVectorArr[i] = new MapVector(
                                (int)mapVector.GetValue("MapX"),
                                (int)mapVector.GetValue("MapY"),
                                (int)mapVector.GetValue("TileX"),
                                (int)mapVector.GetValue("TileY")
                                );
                        }
                    }
                }
                MapVectors.Add(mapVectors.Key, mapVectorArr);
            }

            foreach (var location in ModMain.Config.CustomMapTextures)
            {
                Locations.Add(location.Key, new CustomLocation(location.Value));
            }

            // Automatically adjust tracking for modded maps that are sized differently from vanilla map
            foreach (var location in Game1.locations)
            {
                var locationName = location.uniqueName.Value ?? location.Name;

                if (!location.IsOutdoors || locationName == "Summit" || MapVectors.ContainsKey(locationName) ||
                    !ModConstants.MapVectors.TryGetValue(locationName, out var mapVector))
                {
                    continue;
                }
                if (mapVector.LastOrDefault().TileX != location.Map.DisplayWidth / Game1.tileSize ||
                    mapVector.LastOrDefault().TileY != location.Map.DisplayHeight / Game1.tileSize)
                {
                    MapVectors.Add(locationName,
                                   new[]
                    {
                        mapVector.FirstOrDefault(),
                        new MapVector(
                            mapVector.LastOrDefault().MapX,
                            mapVector.LastOrDefault().MapY,
                            location.Map.DisplayWidth / Game1.tileSize,
                            location.Map.DisplayHeight / Game1.tileSize
                            )
                    });
                }
            }

            var customLocations = MapVectors.Keys.ToArray();

            if (MapVectors.Keys.Count > 0)
            {
                if (customLocations.Length == 1)
                {
                    Monitor.Log($"Handled tracking for custom location: {customLocations[0]}.", LogLevel.Debug);
                }
                else
                {
                    var locationList = "";
                    for (var i = 0; i < customLocations.Length; i++)
                    {
                        locationList += customLocations[i] + (i + 1 == customLocations.Length ? "" : ", ");
                    }

                    Monitor.Log($"Handled tracking for custom locations: {locationList}.", LogLevel.Debug);
                }
            }
        }