Skip to content

Commit

Permalink
Merge pull request #378 from coloursofnoise/hide-csidepostcard
Browse files Browse the repository at this point in the history
  • Loading branch information
0x0ade authored Sep 28, 2021
2 parents d24cc63 + a562249 commit 46b63e2
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 16 deletions.
43 changes: 28 additions & 15 deletions Celeste.Mod.mm/MonoModRules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,10 @@ class PatchPathfinderRenderAttribute : Attribute { };
class PatchTotalHeartGemChecksAttribute : Attribute { };

/// <summary>
/// Same as above, but for references in routines.
/// Patch TotalHeartGems to refer to TotalHeartGemsInVanilla, and whether to show the UnlockCSide postcard
/// </summary>
[MonoModCustomMethodAttribute(nameof(MonoModRules.PatchTotalHeartGemChecksInRoutine))]
class PatchTotalHeartGemChecksInRoutineAttribute : Attribute { };
[MonoModCustomMethodAttribute(nameof(MonoModRules.PatchTotalHeartGemCSidePostcard))]
class PatchTotalHeartGemCSidePostcardAttribute : Attribute { };

/// <summary>
/// Patch a reference to TotalHeartGems in the OuiJournalGlobal constructor to unharcode the check for golden berry unlock.
Expand Down Expand Up @@ -1475,20 +1475,21 @@ public static void PatchPathfinderRender(ILContext context, CustomAttribute attr

}

public static void PatchTotalHeartGemChecks(MethodDefinition method, CustomAttribute attrib) {
MethodDefinition m_getTotalHeartGemsInVanilla = method.Module.GetType("Celeste.SaveData").FindMethod("System.Int32 get_TotalHeartGemsInVanilla()");
public static void PatchTotalHeartGemChecks(ILContext context, CustomAttribute attrib) {
MethodDefinition m_getTotalHeartGemsInVanilla = context.Module.GetType("Celeste.SaveData").FindMethod("System.Int32 get_TotalHeartGemsInVanilla()");

Mono.Collections.Generic.Collection<Instruction> instrs = method.Body.Instructions;
for (int instri = 0; instri < instrs.Count; instri++) {
Instruction instr = instrs[instri];
ILCursor cursor = new ILCursor(context);

if (instr.MatchCallvirt(out MethodReference m) && m.Name == "get_TotalHeartGems") {
// replace the call to the TotalHeartGems property with a call to TotalHeartGemsInVanilla.
instr.Operand = m_getTotalHeartGemsInVanilla;
}
}
cursor.GotoNext(instr => instr.MatchCallvirt("Celeste.SaveData", "get_TotalHeartGems"));
cursor.Next.Operand = m_getTotalHeartGemsInVanilla;
}
public static void PatchTotalHeartGemChecksInRoutine(MethodDefinition method, CustomAttribute attrib) {

public static void PatchTotalHeartGemCSidePostcard(MethodDefinition method, CustomAttribute attrib) {
FieldDefinition f_SaveData_Instance = method.Module.GetType("Celeste.SaveData").FindField("Instance");
MethodDefinition m_SaveData_get_LevelSetStats = method.Module.GetType("Celeste.SaveData").FindMethod("Celeste.LevelSetStats get_LevelSetStats()");
MethodDefinition m_LevelSetStats_get_MaxAreaMode = method.Module.GetType("Celeste.LevelSetStats").FindMethod("System.Int32 get_MaxAreaMode()");


// Routines are stored in compiler-generated methods.
foreach (TypeDefinition nest in method.DeclaringType.NestedTypes) {
if (!nest.Name.StartsWith("<" + method.Name + ">d__"))
Expand All @@ -1497,7 +1498,19 @@ public static void PatchTotalHeartGemChecksInRoutine(MethodDefinition method, Cu
break;
}

PatchTotalHeartGemChecks(method, attrib);
new ILContext(method).Invoke(il => {
ILCursor cursor = new ILCursor(il);

cursor.GotoNext(MoveType.After, instr => instr.MatchLdfld("Celeste.Session", "UnlockedCSide"));
cursor.Emit(cursor.Next.OpCode, cursor.Next.Operand);
cursor.Emit(OpCodes.Ldsfld, f_SaveData_Instance);
cursor.Emit(OpCodes.Callvirt, m_SaveData_get_LevelSetStats);
cursor.Emit(OpCodes.Callvirt, m_LevelSetStats_get_MaxAreaMode);
cursor.Emit(OpCodes.Ldc_I4_2);
cursor.Next.OpCode = OpCodes.Blt_S;

PatchTotalHeartGemChecks(il, attrib);
});
}

public static void PatchOuiJournalStatsHeartGemCheck(ILContext context, CustomAttribute attrib) {
Expand Down
22 changes: 22 additions & 0 deletions Celeste.Mod.mm/Patches/LevelSetStats.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Celeste {
class patch_LevelSetStats : LevelSetStats {
public int MaxAreaMode {
get {
if (Name == "Celeste") {
return (int) AreaMode.CSide;
}
int areaOffset = AreaOffset;
int maxAreaMode = 0;
for (int i = 0; i <= MaxArea; i++) {
ModeProperties[] mode = AreaData.Areas[areaOffset + i].Mode;
foreach (ModeProperties modeProperties in mode) {
if ((int) modeProperties.MapData.Area.Mode > maxAreaMode) {
maxAreaMode = (int) modeProperties.MapData.Area.Mode;
}
}
}
return maxAreaMode;
}
}
}
}
2 changes: 1 addition & 1 deletion Celeste.Mod.mm/Patches/OverworldLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public patch_OverworldLoader(Overworld.StartMode startMode, HiresSnow snow = nul
private extern void CheckVariantsPostcardAtLaunch();

[MonoModIgnore] // don't change anything in the method...
[PatchTotalHeartGemChecksInRoutine] // except for replacing TotalHeartGems with TotalHeartGemsInVanilla through MonoModRules
[PatchTotalHeartGemCSidePostcard] // except for replacing TotalHeartGems with TotalHeartGemsInVanilla through MonoModRules
private extern IEnumerator Routine(Session session);
}
}

0 comments on commit 46b63e2

Please sign in to comment.