using System.IO;
using Omegasis.BuildEndurance.Framework;
using StardewModdingAPI;
using StardewModdingAPI.Events;
using StardewValley;
namespace Omegasis.BuildEndurance
{
/// The mod entry point.
public class BuildEndurance : Mod
{
/*********
** Fields
*********/
/// The relative path for the current player's data file.
private string RelativeDataPath => Path.Combine("data", $"{Constants.SaveFolderName}.json");
/// The mod settings.
private ModConfig Config;
/// The data for the current player.
private PlayerData PlayerData;
/// Whether the player has been exhausted today.
private bool WasExhausted;
/// Whether the player has collapsed today.
private bool WasCollapsed;
/// Whether the player recently gained XP for tool use.
private bool HasRecentToolExp;
/// Whether the player was eating last time we checked.
private bool WasEating;
public IModHelper ModHelper;
public IMonitor ModMonitor;
/*********
** Public methods
*********/
/// The mod entry point, called after the mod is first loaded.
/// Provides simplified APIs for writing mods.
public override void Entry(IModHelper helper)
{
this.Config = helper.ReadConfig();
helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked;
helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded;
helper.Events.GameLoop.Saving += this.OnSaving;
this.ModHelper = this.Helper;
this.ModMonitor = this.Monitor;
}
/*********
** Private methods
*********/
/// Raised after the game state is updated (≈60 times per second).
/// The event sender.
/// The event arguments.
private void OnUpdateTicked(object sender, UpdateTickedEventArgs e)
{
if (!Context.IsWorldReady)
return;
// nerf how quickly tool xp is gained (I hope)
if (e.IsOneSecond && this.HasRecentToolExp)
this.HasRecentToolExp = false;
// give XP when player finishes eating
if (Game1.player.isEating)
this.WasEating = true;
else if (this.WasEating)
{
this.PlayerData.CurrentExp += this.Config.ExpForEating;
this.WasEating = false;
}
// give XP when player uses tool
if (!this.HasRecentToolExp && Game1.player.UsingTool)
{
this.PlayerData.CurrentExp += this.Config.ExpForToolUse;
this.HasRecentToolExp = true;
}
// give XP when exhausted
if (!this.WasExhausted && Game1.player.exhausted.Value)
{
this.PlayerData.CurrentExp += this.Config.ExpForExhaustion;
this.WasExhausted = true;
//this.Monitor.Log("The player is exhausted");
}
// give XP when player stays up too late or collapses
if (!this.WasCollapsed && this.shouldFarmerPassout())
{
this.PlayerData.CurrentExp += this.Config.ExpForCollapsing;
this.WasCollapsed = true;
//this.Monitor.Log("The player has collapsed!");
}
}
/// Raised after the player loads a save slot and the world is initialised.
/// The event sender.
/// The event arguments.
private void OnSaveLoaded(object sender, SaveLoadedEventArgs e)
{
// reset state
this.WasExhausted = false;
this.WasCollapsed = false;
this.HasRecentToolExp = false;
this.WasEating = false;
// load player data
this.PlayerData = this.Helper.Data.ReadJsonFile(this.RelativeDataPath) ?? new PlayerData();
if (this.PlayerData.OriginalMaxStamina == 0)
this.PlayerData.OriginalMaxStamina = Game1.player.MaxStamina;
// reset if needed
if (this.PlayerData.ClearModEffects)
{
Game1.player.MaxStamina = this.PlayerData.OriginalMaxStamina;
this.PlayerData.ExpToNextLevel = this.Config.ExpToNextLevel;
this.PlayerData.CurrentExp = this.Config.CurrentExp;
this.PlayerData.CurrentLevelStaminaBonus = 0;
this.PlayerData.OriginalMaxStamina = Game1.player.MaxStamina;
this.PlayerData.BaseStaminaBonus = 0;
this.PlayerData.CurrentLevel = 0;
this.PlayerData.ClearModEffects = false;
}
// else apply stamina
else
{
Game1.player.MaxStamina = this.PlayerData.NightlyStamina <= 0
? this.PlayerData.BaseStaminaBonus + this.PlayerData.CurrentLevelStaminaBonus + this.PlayerData.OriginalMaxStamina
: this.PlayerData.NightlyStamina;
}
}
/// Raised before the game begins writes data to the save file (except the initial save creation).
/// The event sender.
/// The event arguments.
private void OnSaving(object sender, SavingEventArgs e)
{
// reset data
this.WasExhausted = false;
this.WasCollapsed = false;
// update player data
this.PlayerData.CurrentExp += this.Config.ExpForSleeping;
if (this.PlayerData.OriginalMaxStamina == 0)
this.PlayerData.OriginalMaxStamina = Game1.player.MaxStamina; //grab the initial stamina value
if (this.PlayerData.CurrentLevel < this.Config.MaxLevel)
{
while (this.PlayerData.CurrentExp >= this.PlayerData.ExpToNextLevel && this.PlayerData.CurrentLevelTry and emulate the old Game1.shouldFarmerPassout logic.
public bool shouldFarmerPassout()
{
if (Game1.player.stamina <= 0 || Game1.player.health <= 0 || Game1.timeOfDay >= 2600) return true;
else return false;
}
}
}