Skip to content

Commit

Permalink
fix: AuraHelper desync (#67)
Browse files Browse the repository at this point in the history
* fix AuraHelper desync

* fix desync after saveload

* feat: robust

---------

Co-authored-by: DemoJameson <[email protected]>
  • Loading branch information
LozenChen and DemoJameson authored Feb 19, 2024
1 parent 9da5255 commit 4557329
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
46 changes: 46 additions & 0 deletions CelesteTAS-EverestInterop/Source/EverestInterop/DesyncFixer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ public static class DesyncFixer {
private const string pushedRandomFlag = "CelesteTAS_PushedRandom";
private static int debrisAmount;

// this random needs to be used all through aura entity's lifetime
internal static Random AuraHelperSharedRandom = new Random(1234);

[Initialize]
private static void Initialize() {
Dictionary<MethodInfo, int> methods = new() {
Expand Down Expand Up @@ -56,6 +59,12 @@ private static void Initialize() {
if (ModUtils.GetType("EmoteMod", "Celeste.Mod.EmoteMod.EmoteWheelModule") is { } emoteModuleType) {
emoteModuleType.GetMethodInfo("Player_Update")?.IlHook(PreventEmoteMod);
}

if (ModUtils.GetType("AuraHelper", "AuraHelper.Lantern") is { } auraLanternType) {
auraLanternType.GetConstructor(new Type[] { typeof(Vector2), typeof(string), typeof(int) })?.IlHook(SetupAuraHelperRandom);
auraLanternType.GetMethod("Update")?.IlHook(FixAuraEntityDesync);
ModUtils.GetType("AuraHelper", "AuraHelper.Generator")?.GetMethod("Update")?.IlHook(FixAuraEntityDesync);
}
}

[Load]
Expand Down Expand Up @@ -230,4 +239,41 @@ private static void PreventEmoteMod(ILCursor ilCursor, ILContext ilContext) {
private static int IsEmoteWheelBindingPressed(ButtonBinding binding, int count) {
return binding.Pressed ? count : 0;
}

private static void SetupAuraHelperRandom(ILContext il) {
ILCursor cursor = new ILCursor(il);
cursor.Emit(OpCodes.Ldarg_1);
cursor.EmitDelegate(CreateAuraHelperRandom);
}

private static void CreateAuraHelperRandom(Vector2 vector2) {
if (Manager.Running) {
int seed = vector2.GetHashCode();
if (Engine.Scene.GetLevel() is { } level) {
seed += level.Session.LevelData.LoadSeed;
}
AuraHelperSharedRandom = new Random(seed);
}
}

private static void FixAuraEntityDesync(ILContext il) {
ILCursor cursor = new ILCursor(il);
cursor.EmitDelegate(AuraPushRandom);
while (cursor.TryGotoNext(MoveType.AfterLabel, i => i.OpCode == OpCodes.Ret)) {
cursor.EmitDelegate(AuraPopRandom);
cursor.Index++;
}
}

private static void AuraPushRandom() {
if (Manager.Running) {
Calc.PushRandom(AuraHelperSharedRandom);
}
}

private static void AuraPopRandom() {
if (Manager.Running) {
Calc.PopRandom();
}
}
}
6 changes: 5 additions & 1 deletion CelesteTAS-EverestInterop/Source/Utils/SpeedrunToolUtils.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -30,6 +30,7 @@ internal static class SpeedrunToolUtils {
private static Dictionary<Follower, bool> followers;
private static Dictionary<int, int> insertedSlots = new();
private static bool disallowUnsafeInput;
private static Random auraRandom;

public static void AddSaveLoadAction() {
Action<Dictionary<Type, Dictionary<string, object>>, Level> save = (_, _) => {
Expand All @@ -48,6 +49,7 @@ public static void AddSaveLoadAction() {
followers = HitboxSimplified.Followers.DeepCloneShared();
insertedSlots = SaveAndQuitReenterCommand.InsertedSlots.DeepCloneShared();
disallowUnsafeInput = SafeCommand.DisallowUnsafeInput;
auraRandom = DesyncFixer.AuraHelperSharedRandom.DeepCloneShared();
};
Action<Dictionary<Type, Dictionary<string, object>>, Level> load = (_, _) => {
EntityDataHelper.CachedEntityData = savedEntityData.DeepCloneShared();
Expand All @@ -69,12 +71,14 @@ public static void AddSaveLoadAction() {
HitboxSimplified.Followers = followers.DeepCloneShared();
SaveAndQuitReenterCommand.InsertedSlots = insertedSlots.DeepCloneShared();
SafeCommand.DisallowUnsafeInput = disallowUnsafeInput;
DesyncFixer.AuraHelperSharedRandom = auraRandom.DeepCloneShared();
};
Action clear = () => {
savedEntityData = null;
pressKeys = null;
followers = null;
InfoWatchEntity.SavedRequireWatchEntities.Clear();
auraRandom = null;
};

ConstructorInfo constructor = typeof(SaveLoadAction).GetConstructors()[0];
Expand Down

0 comments on commit 4557329

Please sign in to comment.