Skip to content

Commit

Permalink
Merge pull request #661 from nhruo123/strawberry_seed_bug
Browse files Browse the repository at this point in the history
  • Loading branch information
DemoJameson authored Aug 21, 2023
2 parents 0609fca + 6c97339 commit 9e691ca
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Celeste.Mod.mm/Mod/Entities/GenericStrawberrySeed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ private IEnumerator ReturnRoutine() {

public void OnAllCollected() {
finished = true;
follower.Leader.LoseFollower(follower);
follower.Leader?.LoseFollower(follower);
Depth = -2000002;
Tag = Tags.FrozenUpdate;
wiggler.Start();
Expand Down
47 changes: 47 additions & 0 deletions Celeste.Mod.mm/Patches/StrawberrySeed.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
using Microsoft.Xna.Framework;
using System.Linq;
using MonoMod;
using System;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;

namespace Celeste {
public class patch_StrawberrySeed : StrawberrySeed {
Expand All @@ -23,6 +28,10 @@ public patch_StrawberrySeed(Strawberry strawberry, Vector2 position, int index,
private extern void orig_OnPlayer(Player player);
#pragma warning restore CS0626

[MonoModIgnore]
[PatchPatchStrawberrySeedOnAllCollected]
public new extern void OnAllCollected();

private void OnPlayer(Player player) {
orig_OnPlayer(player);

Expand All @@ -38,3 +47,41 @@ private void OnPlayer(Player player) {
}
}
}
namespace MonoMod {
/// <summary>
/// Patches OnAllCollected to add a check if this.follower.Leader is null.
/// </summary>
[MonoModCustomMethodAttribute(nameof(MonoModRules.PatchStrawberrySeedOnAllCollected))]
class PatchPatchStrawberrySeedOnAllCollectedAttribute : Attribute { }

static partial class MonoModRules {

public static void PatchStrawberrySeedOnAllCollected(ILContext context, CustomAttribute attrib) {
ILCursor cursor = new(context);
ILLabel beforeLoseFollower = cursor.DefineLabel();
ILLabel afterLoseFollower = cursor.DefineLabel();

// we want to add a null check on Leader before calling LoseFollower so we change:
// this.follower.Leader.LoseFollower(this.follower);
// to
// this.follower.Leader?.LoseFollower(this.follower);

// move cursor to the point where Leader is on top of the stack, and then duplicate it for the branch true
cursor.GotoNext(MoveType.After, inst => inst.MatchLdfld("Celeste.Follower", "Leader"));
cursor.Emit(OpCodes.Dup);

// brach to the calling path if we are not null
cursor.Emit(OpCodes.Brtrue, beforeLoseFollower);
// on null discard duplicated value and jump over the calling path
cursor.Emit(OpCodes.Pop);
cursor.Emit(OpCodes.Br, afterLoseFollower);

cursor.GotoNext(MoveType.Before, inst => inst.MatchLdarg(0));
cursor.MarkLabel(beforeLoseFollower);

cursor.GotoNext(MoveType.After, inst => inst.MatchCallvirt("Celeste.Leader", "LoseFollower"));
cursor.MarkLabel(afterLoseFollower);
}

}
}

0 comments on commit 9e691ca

Please sign in to comment.