diff --git a/Celeste.Mod.mm/Patches/Dust.cs b/Celeste.Mod.mm/Patches/Dust.cs index a9dd73be3..f38f61d67 100755 --- a/Celeste.Mod.mm/Patches/Dust.cs +++ b/Celeste.Mod.mm/Patches/Dust.cs @@ -1,4 +1,10 @@ -using Microsoft.Xna.Framework; +using System; +using Celeste; +using Microsoft.Xna.Framework; +using Mono.Cecil; +using Monocle; +using MonoMod; +using MonoMod.Cil; namespace Celeste { // Dust is static. @@ -7,5 +13,45 @@ class patch_Dust { public static void Burst(Vector2 position, float direction, int count = 1) { Dust.Burst(position, direction, count, null); } + + [MonoModIgnore] + [PatchDustBurst] + public static extern void Burst(Vector2 position, float direction, int count, ParticleType particleType); + + [MonoModIgnore] + [PatchDustBurst] + public static extern void BurstFG(Vector2 position, float direction, int count, float range, ParticleType particleType); + } } + +namespace MonoMod { + + /// + /// Add an early return if Engine.Scene is not a Level, to avoid a crash. + /// + [MonoModCustomMethodAttribute(nameof(MonoModRules.PatchDustBurst))] + class PatchDustBurstAttribute : Attribute {} + + static partial class MonoModRules { + + public static void PatchDustBurst(ILContext context, CustomAttribute attrib) { + ILCursor cursor = new ILCursor(context); + + ILLabel beforeRet = cursor.DefineLabel(); + int loc = -1; + + cursor.GotoNext(MoveType.After, + instr => instr.MatchIsinst(out var _), + instr => instr.MatchStloc(out loc)); + cursor.EmitLdloc(loc); + cursor.EmitBrfalse(beforeRet); + + cursor.GotoNext(MoveType.Before, + instr => instr.MatchRet()); + cursor.MarkLabel(beforeRet); + } + + } + +}