Skip to content

Commit dee6e74

Browse files
Merge pull request #977 from JaThePlayer/feat/moreEvents
Introduce events for Player.Update and Level.Update.
2 parents 4d359c5 + f58831e commit dee6e74

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

Celeste.Mod.mm/Mod/Everest/Everest.Events.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,21 @@ internal static void Exit(_Level level, LevelExit exit, LevelExit.Mode mode, _Se
187187
public static event CompleteHandler OnComplete;
188188
internal static void Complete(_Level level)
189189
=> OnComplete?.Invoke(level);
190+
191+
/// <summary>
192+
/// Called at the very beginning of <see cref="global::Celeste.Level.Update"/>.
193+
/// </summary>
194+
public static event Action<_Level> OnBeforeUpdate;
195+
internal static void BeforeUpdate(_Level level)
196+
=> OnBeforeUpdate?.Invoke(level);
197+
198+
/// <summary>
199+
/// Called at the very end of <see cref="global::Celeste.Level.Update"/>.
200+
/// </summary>
201+
public static event Action<_Level> OnAfterUpdate;
202+
203+
internal static void AfterUpdate(_Level level)
204+
=> OnAfterUpdate?.Invoke(level);
190205
}
191206

192207
public static class Session {
@@ -196,17 +211,41 @@ internal static void SliderChanged(patch_Session session, patch_Session.Slider s
196211
}
197212

198213
public static class Player {
214+
/// <summary>
215+
/// Called at the end of <see cref="global::Celeste.Player.Added"/>.
216+
/// </summary>
199217
public static event Action<_Player> OnSpawn;
200218
internal static void Spawn(_Player player)
201219
=> OnSpawn?.Invoke(player);
202220

221+
/// <summary>
222+
/// Called in <see cref="global::Celeste.Player.Die"/>, only if a PlayerDeadBody will be returned from the method.
223+
/// </summary>
203224
public static event Action<_Player> OnDie;
204225
internal static void Die(_Player player)
205226
=> OnDie?.Invoke(player);
206227

228+
/// <summary>
229+
/// Called in the Player constructor during <see cref="StateMachine"/> initialisation, to be used to register custom Player states.
230+
/// </summary>
207231
public static event Action<_Player> OnRegisterStates;
208232
internal static void RegisterStates(_Player player)
209233
=> OnRegisterStates?.Invoke(player);
234+
235+
/// <summary>
236+
/// Called at the very beginning of <see cref="global::Celeste.Player.Update"/>.
237+
/// </summary>
238+
public static event Action<_Player> OnBeforeUpdate;
239+
internal static void BeforeUpdate(_Player player)
240+
=> OnBeforeUpdate?.Invoke(player);
241+
242+
/// <summary>
243+
/// Called at the very end of <see cref="global::Celeste.Player.Update"/>.
244+
/// </summary>
245+
public static event Action<_Player> OnAfterUpdate;
246+
247+
internal static void AfterUpdate(_Player player)
248+
=> OnAfterUpdate?.Invoke(player);
210249
}
211250

212251
public static class Seeker {

Celeste.Mod.mm/Patches/Level.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -972,8 +972,14 @@ public static void PatchLevelUpdate(ILContext context, CustomAttribute attrib) {
972972
MethodReference m_Everest_CoreModule_Settings = MonoModRule.Modder.Module.GetType("Celeste.Mod.Core.CoreModule").FindProperty("Settings").GetMethod;
973973
TypeDefinition t_Everest_CoreModuleSettings = MonoModRule.Modder.Module.GetType("Celeste.Mod.Core.CoreModuleSettings");
974974
MethodReference m_ButtonBinding_Pressed = MonoModRule.Modder.Module.GetType("Celeste.Mod.ButtonBinding").FindProperty("Pressed").GetMethod;
975-
975+
TypeDefinition t_Everest_Events_Level = MonoModRule.Modder.Module.GetType("Celeste.Mod.Everest/Events/Level");
976+
MethodReference m_Everest_Events_Level_BeforeUpdate = t_Everest_Events_Level.FindMethod(nameof(Everest.Events.Level.BeforeUpdate));
977+
MethodReference m_Everest_Events_Level_AfterUpdate = t_Everest_Events_Level.FindMethod(nameof(Everest.Events.Level.AfterUpdate));
978+
976979
ILCursor cursor = new ILCursor(context);
980+
981+
// Invoke Celeste.Mod.Everest.Events.Level.OnBeforeUpdate
982+
cursor.Emit(OpCodes.Ldarg_0).Emit(OpCodes.Call, m_Everest_Events_Level_BeforeUpdate);
977983

978984
// Insert CheckForErrors() at the beginning so we can display an error screen if needed
979985
cursor.Emit(OpCodes.Ldarg_0).Emit(OpCodes.Call, m_CheckForErrors);
@@ -1005,6 +1011,13 @@ ldc.i4.s 9
10051011
cursor.Emit(OpCodes.Call, m_Everest_CoreModule_Settings);
10061012
cursor.Emit(OpCodes.Call, t_Everest_CoreModuleSettings.FindProperty("DebugMap").GetMethod);
10071013
cursor.Emit(OpCodes.Call, m_ButtonBinding_Pressed);
1014+
1015+
// Invoke Everest.Events.Level.OnAfterUpdate before each ret.
1016+
cursor.Index = 0;
1017+
while (cursor.TryGotoNext(MoveType.AfterLabel, instr => instr.MatchRet())) {
1018+
cursor.Emit(OpCodes.Ldarg_0).Emit(OpCodes.Call, m_Everest_Events_Level_AfterUpdate);
1019+
cursor.Index++;
1020+
}
10081021
}
10091022

10101023
public static void PatchLevelRender(ILContext context, CustomAttribute attrib) {

Celeste.Mod.mm/Patches/Player.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ private void CreateTrail() {
135135
[PatchPlayerOrigUpdate] // Manipulate the method via MonoModRules
136136
public extern void orig_Update();
137137
public override void Update() {
138+
Everest.Events.Player.BeforeUpdate(this);
138139
orig_Update();
139140

140141
Level level = Scene as Level;
@@ -144,6 +145,8 @@ public override void Update() {
144145
framesAlive++;
145146
if (framesAlive >= 8)
146147
diedInGBJ = 0;
148+
149+
Everest.Events.Player.AfterUpdate(this);
147150
}
148151

149152
public bool _IsOverWater() {

0 commit comments

Comments
 (0)