Пример #1
0
        /// <summary>Load legacy save data with the given key, if it's valid.</summary>
        /// <param name="key">The save key to load.</param>
        /// <param name="playerId">The parsed <see cref="Farmer.UniqueMultiplayerID"/> value.</param>
        /// <param name="data">The save data for the player.</param>
        private bool TryLoadSaveData(string key, out long playerId, out LegacySaveData data)
        {
            const string prefix = "spacechase0.anotherhungermod.";

            // extract player ID
            if (!key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
            {
                playerId = 0;
                data     = null;
                return(false);
            }
            {
                string raw = key.Substring(prefix.Length);
                if (!long.TryParse(raw, out playerId))
                {
                    playerId = 0;
                    data     = null;
                    return(false);
                }
            }

            // load data
            data = this.DataHelper.ReadSaveData <LegacySaveData>(key);
            return(data != null);
        }
Пример #2
0
        /// <summary>Migrate tractors and garages from older versions of the mod.</summary>
        /// <remarks>The Robin construction logic is derived from <see cref="NPC.reloadSprite"/> and <see cref="Farm.resetForPlayerEntry"/>.</remarks>
        private void LoadLegacyData()
        {
            // fix building types
            foreach (BuildableGameLocation location in this.GetBuildableLocations())
            {
                foreach (Stable stable in location.buildings.OfType <Stable>())
                {
                    if (stable.buildingType.Value == this.BlueprintBuildingType)
                    {
                        stable.buildingType.Value = "Stable";
                        stable.maxOccupants.Value = this.MaxOccupantsID;
                    }
                }
            }

            // get save data
            LegacySaveData saveData = this.Helper.Data.ReadSaveData <LegacySaveData>("tractors"); // 4.6

            if (saveData?.Buildings == null)
            {
                saveData = this.Helper.Data.ReadJsonFile <LegacySaveData>(this.LegacySaveDataRelativePath); // pre-4.6
            }
            if (saveData?.Buildings == null)
            {
                return;
            }

            // add tractor + garages
            BuildableGameLocation[] locations = this.GetBuildableLocations().ToArray();
            foreach (LegacySaveDataBuilding garageData in saveData.Buildings)
            {
                // get location
                BuildableGameLocation location = locations.FirstOrDefault(p => p.NameOrUniqueName == (garageData.Map ?? "Farm"));
                if (location == null)
                {
                    this.Monitor.Log($"Ignored legacy tractor garage in unknown location '{garageData.Map}'.", LogLevel.Warn);
                    continue;
                }

                // add garage
                Stable garage = location.buildings.OfType <Stable>().FirstOrDefault(p => p.tileX.Value == (int)garageData.Tile.X && p.tileY.Value == (int)garageData.Tile.Y);
                if (garage == null)
                {
                    garage = new Stable(garageData.TractorID, this.GetBlueprint(), garageData.Tile);
                    garage.daysOfConstructionLeft.Value = 0;
                    location.buildings.Add(garage);
                }
                garage.maxOccupants.Value = this.MaxOccupantsID;
                garage.load();
            }
        }
Пример #3
0
        /*********
        ** Private methods
        *********/
        /// <summary>Apply legacy save data to the player's current fields, if valid and the field doesn't already have a value.</summary>
        /// <param name="data">The save data to apply.</param>
        /// <returns>Returns the player IDs whose fields were changed.</returns>
        private IEnumerable <long> TryApply(LegacySaveData data)
        {
            foreach (var pair in data?.Players ?? new())
            {
                if (pair.Value?.Mana is not > 0 && pair.Value?.ManaCap is not > 0)
                {
                    continue;
                }

                Farmer player = Game1.getFarmerMaybeOffline(pair.Key);
                if (this.SetMaxManaIfNotSet(player, pair.Value.ManaCap) | this.SetCurrentManaIfNotSet(player, pair.Value.Mana))
                {
                    yield return(pair.Key);
                }
            }
        }
Пример #4
0
        /// <summary>Migrate the legacy <c>TractorModSave.json</c> file to the new config files.</summary>
        /// <param name="helper">Provides simplified APIs for writing mods.</param>
        private void MigrateLegacySaveData(IModHelper helper)
        {
            // get file
            const string filename = "TractorModSave.json";
            FileInfo     file     = new FileInfo(Path.Combine(helper.DirectoryPath, filename));

            if (!file.Exists)
            {
                return;
            }

            // read legacy data
            this.Monitor.Log($"Found legacy {filename}, migrating to new save data...");
            IDictionary <string, CustomSaveData> saves = new Dictionary <string, CustomSaveData>();

            {
                LegacySaveData data = helper.ReadJsonFile <LegacySaveData>(filename);
                if (data.Saves != null && data.Saves.Any())
                {
                    foreach (LegacySaveData.LegacySaveEntry saveData in data.Saves)
                    {
                        saves[$"{saveData.FarmerName}_{saveData.SaveSeed}"] = new CustomSaveData(
                            saveData.TractorHouse.Select(p => new CustomSaveBuilding(new Vector2(p.X, p.Y), this.GarageBuildingType, "Farm", 0))
                            );
                    }
                }
            }

            // write new files
            foreach (var save in saves)
            {
                if (save.Value.Buildings.Any())
                {
                    helper.WriteJsonFile(this.GetDataPath(save.Key), save.Value);
                }
            }

            // delete old file
            file.Delete();
        }
Пример #5
0
        /*********
        ** Private methods
        *********/
        /// <summary>Apply legacy save data to the player's current fields, if valid and the field doesn't already have a value.</summary>
        /// <param name="legacyData">The save data to apply.</param>
        /// <returns>Returns the player IDs whose fields were changed.</returns>
        private IEnumerable <long> TryApply(LegacySaveData legacyData)
        {
            foreach (var pair in legacyData?.Players ?? new())
            {
                // get player spellbook
                Farmer player = Game1.getFarmerMaybeOffline(pair.Key);
                if (player == null)
                {
                    continue;
                }
                SpellBook book = player.GetSpellBook();

                // apply data
                bool changed = false;
                book.Mutate(data =>
                {
                    // free spell point
                    if (data.FreePoints <= 0)
                    {
                        int freePoints = pair.Value.FreePoints;
                        if (freePoints > 0)
                        {
                            data.FreePoints = Math.Max(0, freePoints);
                            changed         = true;
                        }
                    }

                    // known spells
                    if (!data.KnownSpells.Any())
                    {
                        PreparedSpell[] knownSpells = (pair.Value.SpellBook?.KnownSpells ?? new())
                                                      .Select(p => new PreparedSpell(p.Key, p.Value))
                                                      .ToArray();
                        if (knownSpells.Any())
                        {
                            data.KnownSpells = knownSpells.ToDictionary(p => p.SpellId);
                            changed          = true;
                        }
                    }

                    // prepared spells
                    if (!data.Prepared.Any())
                    {
                        var preparedSpells = (pair.Value.SpellBook?.Prepared ?? new PreparedSpell[][] { })
                                             .Select(spells => new PreparedSpellBar {
                            Spells = spells.ToList()
                        })
                                             .ToArray();
                        if (preparedSpells.Any(bar => bar.Spells.Any(spell => spell != null)))
                        {
                            data.Prepared = preparedSpells;
                            changed       = true;
                        }
                    }

                    // prepared index
                    if (data.SelectedPrepared <= 0)
                    {
                        int index = pair.Value.SpellBook?.SelectedPrepared ?? 0;
                        if (index > 0)
                        {
                            data.SelectedPrepared = index;
                            changed = true;
                        }
                    }
                });

                if (changed)
                {
                    yield return(pair.Key);
                }
            }
        }