Skip to content

Commit

Permalink
rewrite Sleepy Eye tent location logic
Browse files Browse the repository at this point in the history
This removes the dependency on SpaceCore, and fixes the location not being saved correctly in Stardew Valley 1.5 (since the player is in the farmhouse by the time the Saving event is called).
  • Loading branch information
Pathoschild committed Jun 14, 2021
1 parent 07b6b9f commit 66ec2c0
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 146 deletions.
24 changes: 24 additions & 0 deletions SleepyEye/Framework/CampData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Microsoft.Xna.Framework;
using StardewValley;

namespace SleepyEye.Framework
{
/// <summary>Metadata about where and when the player camped.</summary>
internal class CampData
{
/*********
** Accessors
*********/
/// <summary>The name of the game location.</summary>
public string Location { get; set; }

/// <summary>The player's map pixel position.</summary>
public Vector2 Position { get; set; }

/// <summary>The mine level, if applicable.</summary>
public int? MineLevel { get; set; }

/// <summary>The <see cref="WorldDate.TotalDays"/> value when the player slept.</summary>
public int DaysPlayed { get; set; }
}
}
96 changes: 96 additions & 0 deletions SleepyEye/Mod.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
using System;
using System.Collections.Generic;
using SleepyEye.Framework;
using SpaceShared;
using SpaceShared.APIs;
using StardewModdingAPI;
using StardewModdingAPI.Events;
using StardewValley;
using StardewValley.Locations;
using StardewValley.Menus;

namespace SleepyEye
{
/// <summary>The mod entry point.</summary>
internal class Mod : StardewModdingAPI.Mod
{
/*********
** Fields
*********/
/// <summary>The data key in the save file for the tent location.</summary>
private readonly string TentLocationKey = "tent-location";


/*********
** Accessors
*********/
/// <summary>The static mod instance.</summary>
public static Mod Instance;


/*********
** Public methods
*********/
/// <inheritdoc />
public override void Entry(IModHelper helper)
{
Expand All @@ -28,8 +42,28 @@ public override void Entry(IModHelper helper)
Log.Monitor = this.Monitor;
helper.Events.Display.MenuChanged += this.OnMenuChanged;
helper.Events.GameLoop.GameLaunched += this.OnGameLaunched;
helper.Events.GameLoop.DayStarted += this.OnDayStarted;
}

/// <summary>Remember the location where the player saved, and restore it on the next day.</summary>
internal void RememberLocation()
{
if (Context.IsMainPlayer) // TODO multiplayer support
{
this.Helper.Data.WriteSaveData(this.TentLocationKey, new CampData
{
Location = Game1.player.currentLocation?.NameOrUniqueName,
Position = Game1.player.Position,
MineLevel = (Game1.currentLocation as MineShaft)?.mineLevel,
DaysPlayed = Game1.Date.TotalDays
});
}
}


/*********
** Private methods
*********/
/// <summary>Raised after the game is launched, right before the first update tick. This happens once per game session (unrelated to loading saves). All mods are loaded and initialised at this point, so this is a good time to set up mod integrations.</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
Expand All @@ -43,6 +77,23 @@ private void OnGameLaunched(object sender, GameLaunchedEventArgs e)
}
}

/// <summary>Raised after the game begins a new day (including when the player loads a save).</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
private void OnDayStarted(object sender, DayStartedEventArgs e)
{
// move player back to their tent location
if (Context.IsMainPlayer)
{
CampData camp = this.Helper.Data.ReadSaveData<CampData>(this.TentLocationKey);
if (camp != null && camp.DaysPlayed == Game1.Date.TotalDays - 1)
{
this.Helper.Data.WriteSaveData<CampData>(this.TentLocationKey, null);
this.TryRestoreLocation(camp);
}
}
}

/// <summary>Raised after a game menu is opened, closed, or replaced.</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
Expand All @@ -61,6 +112,51 @@ private void OnMenuChanged(object sender, MenuChangedEventArgs e)
itemPriceAndStock.Add(item, new[] { item.salePrice(), item.Stack });
}

/// <summary>Move the player back to where they camped, if possible.</summary>
/// <param name="camp">The metadata about where and when the player camped.</param>
private void TryRestoreLocation(CampData camp)
{
Log.Debug("Previously slept in a tent, replacing player position.");

// get location
GameLocation location = Game1.getLocationFromName(camp.Location);
if (location == null)
{
Game1.addHUDMessage(new HUDMessage("You camped somewhere strange, so you've returned home."));
return;
}
if (location.Name == this.GetFestivalLocation())
{
Game1.addHUDMessage(new HUDMessage("You camped on the festival grounds, so you've returned home."));
return;
}

// restore position
if (location is MineShaft)
{
Log.Trace("Slept in a mine.");
Game1.enterMine(camp.MineLevel ?? 0);
}
else
{
Game1.player.currentLocation = Game1.currentLocation = location;
Game1.player.Position = camp.Position;
}
}

/// <summary>Get the location where a festival will be today, if any.</summary>
internal string GetFestivalLocation()
{
try
{
return Game1.temporaryContent.Load<Dictionary<string, string>>($"Data\\Festivals\\{Game1.currentSeason}{Game1.dayOfMonth}")["conditions"].Split('/')[0];
}
catch
{
return null;
}
}

/// <summary>Apply the given mod configuration.</summary>
/// <param name="config">The configuration model.</param>
private void ApplyConfig(ModConfig config)
Expand Down
4 changes: 0 additions & 4 deletions SleepyEye/SleepyEye.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,4 @@
<ItemGroup>
<Reference Include="PyTK" HintPath="$(GameModsPath)\PyTK\PyTK.dll" Private="False" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\SpaceCore\SpaceCore.csproj" Private="False" />
</ItemGroup>
</Project>
3 changes: 1 addition & 2 deletions SleepyEye/TentTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using PyTK.CustomElementHandler;
using SpaceCore;
using StardewModdingAPI;
using StardewValley;
using SFarmer = StardewValley.Farmer;
Expand Down Expand Up @@ -125,7 +124,7 @@ public override void tickUpdate(GameTime time, SFarmer who)
this.CancelUse(who);

this.StartedSaving = this.GetTicks();
Sleep.SaveLocation = true;
Mod.Instance.RememberLocation();
Game1.player.isInBed.Value = true;
Game1.NewDay(0);
}
Expand Down
3 changes: 1 addition & 2 deletions SleepyEye/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ tent to sleep anywhere!
## Install
1. Install the latest version of...
* [SMAPI](https://smapi.io);
* [PyTK](https://www.nexusmods.com/stardewvalley/mods/1726);
* and [SpaceCore](https://www.nexusmods.com/stardewvalley/mods/1348).
* and [PyTK](https://www.nexusmods.com/stardewvalley/mods/1726).
2. Install [this mod from Nexus Mods](http://www.nexusmods.com/stardewvalley/mods/1152).
3. Run the game using SMAPI.

Expand Down
7 changes: 6 additions & 1 deletion SleepyEye/docs/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
# Release notes
## Upcoming release
* Updated for Stardew Valley 1.5.
* The time you need to hold the tent button is now configurable.
* The place-tent delay is now configurable.
* Holding the tent button now triggers a save after the delay without waiting for you to release the button.
* SpaceCore is no longer required.
* Fixed compatibility with [unofficial 64-bit mode](https://stardewvalleywiki.com/Modding:Migrate_to_64-bit_on_Windows).
* Improved documentation.
* Internal refactoring.

**Update note:**
If you slept in a tent before updating the mod, you'll start the day at home. The tent location
will be saved correctly thereafter.

## 1.0.4
Released 26 November 2019 for Stardew Valley 1.4.

Expand Down
3 changes: 0 additions & 3 deletions SleepyEye/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
"EntryDll": "SleepyEye.dll",
"UpdateKeys": [ "Nexus:1152" ],
"Dependencies": [
{
"UniqueID": "spacechase0.SpaceCore"
},
{
"UniqueID": "Platonymous.Toolkit"
}
Expand Down
20 changes: 0 additions & 20 deletions SpaceCore/Sleep.cs

This file was deleted.

Loading

0 comments on commit 66ec2c0

Please sign in to comment.