Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace Celeste.Mod.Registry.DecalRegistryHandlers;

internal sealed class StaticMoverDecalRegistryHandler : DecalRegistryHandler {
private int _x, _y, _width, _height;
private bool _jumpThrus;

public override string Name => "staticMover";

Expand All @@ -12,13 +13,14 @@ public override void Parse(XmlAttributeCollection xml) {
_y = Get(xml, "y", 0);
_width = Get(xml, "width", 16);
_height = Get(xml, "height", 16);
_jumpThrus = GetBool(xml, "jumpThrus", false);
}

public override void ApplyTo(Decal decal) {
int x = _x, y = _y, width = _width, height = _height;

decal.ScaleRectangle(ref x, ref y, ref width, ref height);

((patch_Decal)decal).MakeStaticMover(x, y, width, height);
((patch_Decal)decal).MakeStaticMover(x, y, width, height, _jumpThrus);
}
}
38 changes: 29 additions & 9 deletions Celeste.Mod.mm/Patches/Decal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public Vector2 Scale {

private StaticMover staticMover;

public List<Solid> Solids => solids;

public patch_Decal(string texture, Vector2 position, Vector2 scale, int depth)
: base(texture, position, scale, depth) {
// no-op. MonoMod ignores this - we only need this to make the compiler shut up.
Expand Down Expand Up @@ -231,15 +233,24 @@ public void MakeStaticMover(int x, int y, int w, int h, bool jumpThrus = false)
SolidChecker = s => !solids.Contains(s) && s.CollideRect(new Rectangle((int) X + x, (int) Y + y, w, h)),
OnDestroy = () => {
RemoveSelf();
solids.ForEach(s => s.RemoveSelf());
solids.ForEach(s => {
s.DestroyStaticMovers();
s.RemoveSelf();
});
},
OnDisable = () => {
Active = Visible = Collidable = false;
solids.ForEach(s => s.Collidable = false);
solids.ForEach(s => {
s.Collidable = false;
s.DisableStaticMovers();
});
},
OnEnable = () => {
Active = Visible = Collidable = true;
solids.ForEach(s => s.Collidable = true);
solids.ForEach(s => {
s.Collidable = true;
s.EnableStaticMovers();
});
},
OnMove = v => {
Position += v;
Expand All @@ -249,17 +260,23 @@ public void MakeStaticMover(int x, int y, int w, int h, bool jumpThrus = false)
s.MoveV(v.Y, liftSpeed.Y);
});
},
OnShake = v => Position += v,
OnShake = v => {
Position += v;
solids.ForEach(s => s.OnShake(v));
},
OnAttach = p => {
p.Add(new EntityRemovedListener(() => {
RemoveSelf();
solids.ForEach(s => s.RemoveSelf());
solids.ForEach(s => {
s.DestroyStaticMovers();
s.RemoveSelf();
});
}));
CoreModule.Session.AttachedDecals.Add(string.Format("{0}||{1}||{2}", Name, Position.X, Position.Y));
}
};
if (jumpThrus)
staticMover.JumpThruChecker = s => s.CollideRect(new Rectangle((int) X + x, (int) X + y, w, h));
staticMover.JumpThruChecker = s => s.CollideRect(new Rectangle((int) X + x, (int) Y + y, w, h));
Add(staticMover);
}

Expand Down Expand Up @@ -298,9 +315,12 @@ public void MakeOverlay() {

public override void Awake(Scene scene) {
base.Awake(scene);
if (staticMover?.Platform == null && CoreModule.Session.AttachedDecals.Contains(string.Format("{0}||{1}||{2}", Name, Position.X, Position.Y))) {
RemoveSelf();
}

((patch_EntityList) (object) scene.Entities).PostAwake += () => {
if (staticMover?.Platform == null && CoreModule.Session.AttachedDecals.Contains(string.Format("{0}||{1}||{2}", Name, Position.X, Position.Y))) {
RemoveSelf();
}
};
}

public extern void orig_Added(Scene scene);
Expand Down
13 changes: 13 additions & 0 deletions Celeste.Mod.mm/Patches/Monocle/EntityList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace Monocle {
// No public constructors.
Expand All @@ -25,6 +26,8 @@ class patch_EntityList {
/// </summary>
public List<Entity> ToAdd => toAdd;

public event Action PostAwake;

internal void ClearEntities() {
entities.Clear();
}
Expand Down Expand Up @@ -53,6 +56,8 @@ private void _HandleEntityData(Entity entity) {
// so this should be very rare in practice.
}
}

private void _PostAwake() => Interlocked.Exchange(ref PostAwake, null)?.Invoke();
}

public static class EntityListExt {
Expand Down Expand Up @@ -107,6 +112,9 @@ public static void PatchEntityListUpdate(ILContext context, CustomAttribute attr
}

public static void PatchEntityListUpdateLists(ILContext context, CustomAttribute attrib) {
TypeDefinition t_EntityList = MonoModRule.Modder.FindType("Monocle.EntityList").Resolve();
MethodDefinition m_PostAwake = t_EntityList.FindMethod("_PostAwake");

ILCursor cursor = new ILCursor(context);

// if (!current.Contains(entity)) { if (current.Add(entity)) {
Expand Down Expand Up @@ -139,6 +147,11 @@ public static void PatchEntityListUpdateLists(ILContext context, CustomAttribute
cursor.GotoPrev(instr => instr.OpCode == OpCodes.Callvirt && (instr.Operand as MethodReference).GetID().Contains("List`1<Monocle.Entity>::Contains"));
cursor.Prev.Previous.Operand = currentOperand;
cursor.Next.Operand = hashRemoveOperand;

// at the end, call PostAwake
cursor.GotoNext(MoveType.AfterLabel, instr => instr.MatchRet());
cursor.EmitLdarg0();
cursor.EmitCallvirt(m_PostAwake);
}

public static void PatchEntityListAdd(ILContext context, CustomAttribute attrib) {
Expand Down