/// <summary>Restore tractor and garage data removed by <see cref="StashCustomData"/>.</summary> /// <remarks>The Robin construction logic is derived from <see cref="NPC.reloadSprite"/> and <see cref="StardewValley.Farm.resetForPlayerEntry"/>.</remarks> private void RestoreCustomData() { // get save data CustomSaveData saveData = this.Helper.ReadJsonFile <CustomSaveData>(this.GetDataPath(Constants.SaveFolderName)); if (saveData?.Buildings == null) { return; } // add tractor + garages BluePrint blueprint = this.GetBlueprint(); BuildableGameLocation[] locations = CommonHelper.GetLocations().OfType <BuildableGameLocation>().ToArray(); foreach (CustomSaveBuilding garageData in saveData.Buildings) { // get location BuildableGameLocation location = locations.FirstOrDefault(p => this.GetMapName(p) == (garageData.Map ?? "Farm")); if (location == null) { this.Monitor.Log($"Ignored tractor garage in unknown location '{garageData.Map}'."); continue; } // add garage TractorGarage garage = new TractorGarage(blueprint, garageData.Tile, Math.Max(0, garageData.DaysOfConstructionLeft - 1)); location.buildings.Add(garage); // add Robin construction if (garage.isUnderConstruction() && !this.IsRobinBusy) { this.IsRobinBusy = true; NPC robin = Game1.getCharacterFromName("Robin"); // update Robin robin.ignoreMultiplayerUpdates = true; robin.sprite.setCurrentAnimation(new List <FarmerSprite.AnimationFrame> { new FarmerSprite.AnimationFrame(24, 75), new FarmerSprite.AnimationFrame(25, 75), new FarmerSprite.AnimationFrame(26, 300, false, false, farmer => this.Helper.Reflection.GetPrivateMethod(robin, "robinHammerSound").Invoke(farmer)), new FarmerSprite.AnimationFrame(27, 1000, false, false, farmer => this.Helper.Reflection.GetPrivateMethod(robin, "robinVariablePause").Invoke(farmer)) }); robin.ignoreScheduleToday = true; Game1.warpCharacter(robin, location.Name, new Vector2(garage.tileX + garage.tilesWide / 2, garage.tileY + garage.tilesHigh / 2), false, false); robin.position.X += Game1.tileSize / 4; robin.position.Y -= Game1.tileSize / 2; robin.CurrentDialogue.Clear(); robin.CurrentDialogue.Push(new Dialogue(Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.3926"), robin)); } // spawn tractor if (this.Tractor == null && !garage.isUnderConstruction()) { this.Tractor = this.SpawnTractor(location, garage.tileX + 1, garage.tileY + 1); } } }
private void SpawnGarage(BuildableGameLocation location, int tileX, int tileY, int daysOfConstructionLeft, Guid tractorID, int?hatID) { // add new garage TractorGarage garage = new TractorGarage(tractorID, this.GetBlueprint(), new Vector2(tileX, tileY), daysOfConstructionLeft); location.buildings.Add(garage); // add Robin construction if (garage.isUnderConstruction() && !this.IsRobinBusy && garage.daysOfConstructionLeft.Value < this.GarageConstructionDays) { this.IsRobinBusy = true; NPC robin = Game1.getCharacterFromName("Robin"); // update Robin robin.Sprite.setCurrentAnimation(new List <FarmerSprite.AnimationFrame> { new FarmerSprite.AnimationFrame(24, 75), new FarmerSprite.AnimationFrame(25, 75), new FarmerSprite.AnimationFrame(26, 300, false, false, farmer => this.Helper.Reflection.GetMethod(robin, "robinHammerSound").Invoke(farmer)), new FarmerSprite.AnimationFrame(27, 1000, false, false, farmer => this.Helper.Reflection.GetMethod(robin, "robinVariablePause").Invoke(farmer)) }); robin.ignoreScheduleToday = true; Game1.warpCharacter(robin, location, new Vector2(garage.tileX.Value + garage.tilesWide.Value / 2, garage.tileY.Value + garage.tilesHigh.Value / 2)); robin.position.X += Game1.tileSize / 4; robin.position.Y -= Game1.tileSize / 2; robin.CurrentDialogue.Clear(); robin.CurrentDialogue.Push(new Dialogue(Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.3926"), robin)); } // spawn tractor if needed if (this.Tractor == null && !garage.isUnderConstruction()) { Tractor tractor = new Tractor(tractorID, tileX + 1, tileY + 1, this.Config, this.Attachments, this.Helper.Content.GetActualAssetKey(this.GetTextureKey("tractor")), this.Helper.Translation, this.Helper.Reflection); tractor.SetLocation(location, new Vector2(tileX + 1, tileY + 1)); if (hatID.HasValue) { tractor.hat.Value = new Hat(hatID.Value); } this.Tractor = tractor; } }