add GameLoop.OneSecondUpdateTicking/Ticked

This commit is contained in:
Jesse Plamondon-Willard 2018-12-25 15:10:22 -05:00
parent 6ad52d607c
commit 8e0573d7d9
No known key found for this signature in database
GPG Key ID: 7D7C8097B62033CE
8 changed files with 100 additions and 0 deletions

View File

@ -5,6 +5,7 @@
* Tweaked installer to reduce antivirus false positives.
* For modders:
* Added `GameLoop.OneSecondUpdateTicking/Ticked` events.
* Added `Specialised.LoadStageChanged` for mods which need to do something at a specific point in the game's save loading process.
* You can now use read/write save data as soon as the save is loaded (instead of once the world is initialised).

View File

@ -14,6 +14,12 @@ namespace StardewModdingAPI.Events
/// <summary>Raised after the game state is updated (≈60 times per second).</summary>
event EventHandler<UpdateTickedEventArgs> UpdateTicked;
/// <summary>Raised once per second before the game state is updated.</summary>
event EventHandler<OneSecondUpdateTickingEventArgs> OneSecondUpdateTicking;
/// <summary>Raised once per second after the game state is updated.</summary>
event EventHandler<OneSecondUpdateTickedEventArgs> OneSecondUpdateTicked;
/// <summary>Raised before the game creates a new save file.</summary>
event EventHandler<SaveCreatingEventArgs> SaveCreating;

View File

@ -0,0 +1,32 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IGameLoopEvents.OneSecondUpdateTicked"/> event.</summary>
public class OneSecondUpdateTickedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The number of ticks elapsed since the game started, including the current tick.</summary>
public uint Ticks { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="ticks">The number of ticks elapsed since the game started, including the current tick.</param>
internal OneSecondUpdateTickedEventArgs(uint ticks)
{
this.Ticks = ticks;
}
/// <summary>Get whether <see cref="Ticks"/> is a multiple of the given <paramref name="number"/>. This is mainly useful if you want to run logic intermittently (e.g. <code>e.IsMultipleOf(30)</code> for every half-second).</summary>
/// <param name="number">The factor to check.</param>
public bool IsMultipleOf(uint number)
{
return this.Ticks % number == 0;
}
}
}

View File

@ -0,0 +1,32 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IGameLoopEvents.OneSecondUpdateTicking"/> event.</summary>
public class OneSecondUpdateTickingEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The number of ticks elapsed since the game started, including the current tick.</summary>
public uint Ticks { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="ticks">The number of ticks elapsed since the game started, including the current tick.</param>
internal OneSecondUpdateTickingEventArgs(uint ticks)
{
this.Ticks = ticks;
}
/// <summary>Get whether <see cref="Ticks"/> is a multiple of the given <paramref name="number"/>. This is mainly useful if you want to run logic intermittently (e.g. <code>e.IsMultipleOf(30)</code> for every half-second).</summary>
/// <param name="number">The factor to check.</param>
public bool IsMultipleOf(uint number)
{
return this.Ticks % number == 0;
}
}
}

View File

@ -58,6 +58,12 @@ namespace StardewModdingAPI.Framework.Events
/// <summary>Raised after the game performs its overall update tick (≈60 times per second).</summary>
public readonly ManagedEvent<UpdateTickedEventArgs> UpdateTicked;
/// <summary>Raised once per second before the game performs its overall update tick.</summary>
public readonly ManagedEvent<OneSecondUpdateTickingEventArgs> OneSecondUpdateTicking;
/// <summary>Raised once per second after the game performs its overall update tick.</summary>
public readonly ManagedEvent<OneSecondUpdateTickedEventArgs> OneSecondUpdateTicked;
/// <summary>Raised before the game creates the save file.</summary>
public readonly ManagedEvent<SaveCreatingEventArgs> SaveCreating;
@ -380,6 +386,8 @@ namespace StardewModdingAPI.Framework.Events
this.GameLaunched = ManageEventOf<GameLaunchedEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.GameLaunched));
this.UpdateTicking = ManageEventOf<UpdateTickingEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.UpdateTicking));
this.UpdateTicked = ManageEventOf<UpdateTickedEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.UpdateTicked));
this.OneSecondUpdateTicking = ManageEventOf<OneSecondUpdateTickingEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.OneSecondUpdateTicking));
this.OneSecondUpdateTicked = ManageEventOf<OneSecondUpdateTickedEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.OneSecondUpdateTicked));
this.SaveCreating = ManageEventOf<SaveCreatingEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.SaveCreating));
this.SaveCreated = ManageEventOf<SaveCreatedEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.SaveCreated));
this.Saving = ManageEventOf<SavingEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.Saving));

View File

@ -30,6 +30,20 @@ namespace StardewModdingAPI.Framework.Events
remove => this.EventManager.UpdateTicked.Remove(value);
}
/// <summary>Raised once per second before the game state is updated.</summary>
public event EventHandler<OneSecondUpdateTickingEventArgs> OneSecondUpdateTicking
{
add => this.EventManager.OneSecondUpdateTicking.Add(value);
remove => this.EventManager.OneSecondUpdateTicking.Remove(value);
}
/// <summary>Raised once per second after the game state is updated.</summary>
public event EventHandler<OneSecondUpdateTickedEventArgs> OneSecondUpdateTicked
{
add => this.EventManager.OneSecondUpdateTicked.Add(value);
remove => this.EventManager.OneSecondUpdateTicked.Remove(value);
}
/// <summary>Raised before the game creates a new save file.</summary>
public event EventHandler<SaveCreatingEventArgs> SaveCreating
{

View File

@ -878,8 +878,11 @@ namespace StardewModdingAPI.Framework
this.OnLoadStageChanged(LoadStage.Loaded);
// update tick
bool isOneSecond = this.TicksElapsed % 60 == 0;
this.Events.UnvalidatedUpdateTicking.Raise(new UnvalidatedUpdateTickingEventArgs(this.TicksElapsed));
this.Events.UpdateTicking.Raise(new UpdateTickingEventArgs(this.TicksElapsed));
if (isOneSecond)
this.Events.OneSecondUpdateTicking.Raise(new OneSecondUpdateTickingEventArgs(this.TicksElapsed));
try
{
this.Input.UpdateSuppression();
@ -891,6 +894,8 @@ namespace StardewModdingAPI.Framework
}
this.Events.UnvalidatedUpdateTicked.Raise(new UnvalidatedUpdateTickedEventArgs(this.TicksElapsed));
this.Events.UpdateTicked.Raise(new UpdateTickedEventArgs(this.TicksElapsed));
if (isOneSecond)
this.Events.OneSecondUpdateTicked.Raise(new OneSecondUpdateTickedEventArgs(this.TicksElapsed));
/*********
** Update events

View File

@ -135,6 +135,8 @@
<Compile Include="Events\MultiplayerEvents.cs" />
<Compile Include="Events\NpcListChangedEventArgs.cs" />
<Compile Include="Events\ObjectListChangedEventArgs.cs" />
<Compile Include="Events\OneSecondUpdateTickedEventArgs.cs" />
<Compile Include="Events\OneSecondUpdateTickingEventArgs.cs" />
<Compile Include="Events\PeerContextReceivedEventArgs.cs" />
<Compile Include="Events\PeerDisconnectedEventArgs.cs" />
<Compile Include="Events\PlayerEvents.cs" />