Skip to content

Commit

Permalink
merge tas helper better invincible
Browse files Browse the repository at this point in the history
  • Loading branch information
LozenChen committed Dec 31, 2024
1 parent 4740979 commit 9ecb9a7
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 1 deletion.
5 changes: 5 additions & 0 deletions CelesteTAS-EverestInterop/Dialog/English.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ TAS_ATTEMPT_TO_CONNECT_TO_STUDIO= Attempt To Connect To Studio
TAS_SHOW_STUDIO_UPDATE_BANNER= Show Studio Update Banner
TAS_OPEN_CONSOLE_IN_TAS= Allow Opening Console in TAS
TAS_SCROLLABLE_HISTORY_LOG= Scrollable Console History Log
TAS_BETTER_INVINCIBILITY= Better Invincibility
TAS_BETTER_INVINCIBLE_DESCRIPTION= Only applies to TAS.{n}
Now "Set Invincible true" command makes you invincible only during this TAS,{n}
and player will not bounce at the bottom of a level boundary,{n}
or accidentally refill dash while Maddy shouldn't. So this avoids desync.
TAS_HIDE_FREEZE_FRAMES= Hide Freeze Frames during TAS
TAS_HIDE_FREEZE_FRAMES_DESCRIPTION_1=When a freeze frame is encountered, run it and continue to the next frame
TAS_HIDE_FREEZE_FRAMES_DESCRIPTION_2=before rendering. Applies only while a TAS is active.
Expand Down
4 changes: 4 additions & 0 deletions CelesteTAS-EverestInterop/Dialog/Simplified Chinese.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ TAS_LAUNCH_STUDIO_AT_BOOT= 启动游戏时打开 Studio
TAS_ATTEMPT_TO_CONNECT_TO_STUDIO= 尝试连接 Studio
TAS_OPEN_CONSOLE_IN_TAS= 允许在 TAS 中打开控制台
TAS_SCROLLABLE_HISTORY_LOG= 可滚动的控制台历史记录
TAS_BETTER_INVINCIBILITY= 更好的无敌
TAS_BETTER_INVINCIBLE_DESCRIPTION= 仅在 TAS 中生效.{n}
现在 "Set Invincible true" 指令会产生一个仅在 TAS 期间生效的无敌效果,{n}
且这个无敌不会导致玩家在关卡底部弹跳, 意外恢复冲刺等, 从而避免了 TAS desync.
TAS_HIDE_FREEZE_FRAMES= TAS 时跳过冻结帧
TAS_HIDE_FREEZE_FRAMES_DESCRIPTION_1=运行到冻结帧时自动跳过进入下一帧
TAS_HIDE_FREEZE_FRAMES_DESCRIPTION_2=仅在 TAS 时启用
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using MonoMod.Cil;
using Celeste;
using TAS.Module;
using TAS.Utils;

namespace TAS.EverestInterop;
internal static class BetterInvincible {
// merged from TAS Helper

// make you invincible while still make tas sync
// it will not persist after SL, and that's what we want!

// if it (before savepoint) gets deleted, then tas file changes, so it should be detected and disable run will be invoked, and savestate will be cleared
// if it (after savepoint) gets deleted, .... yeah it just gets deleted, when restart from savestate, Invincible = false will be loaded (as it's saved as such)

// note that if you use RESTART hotkey ("=" by default), then LoadState will be invoked (if it's saved), but DisableRun won't!!

public static bool Invincible = false;

[Initialize]

private static void Initialize() {
typeof(Player).GetMethod("orig_Die").IlHook(il => {
ILCursor cursor = new ILCursor(il);
if (cursor.TryGotoNext(MoveType.After, ins => ins.MatchLdfld<Assists>("Invincible"))) {
cursor.EmitDelegate(ModifyInvincible);
}
});
}


[DisableRun]
private static void OnDisableRun() {
Invincible = false;
}

private static bool ModifyInvincible(bool origValue) {
// Manager.Running may be redundant..
return origValue || (Invincible && Manager.Running && TasSettings.BetterInvincible); // safe guard, in case that disable run thing doesn't work somehow
}

public static bool Handle(Assists assist, bool value) {
if (!Manager.Running || !TasSettings.BetterInvincible) {
return false;
}
bool beforeInvincible = assist.Invincible;
if (beforeInvincible == value) {
return true;
}
if (!beforeInvincible) {
assist.Invincible = false;
SaveData.Instance.Assists = assist;
// Assists is a struct, so it needs to be re-assign
}
Invincible = !beforeInvincible;
// if originally invincible = true, but set to false, then betterInv = false
// if originally inv = false, but set to true, then inv = false, and betterInv = true
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ internal class LegacyTasHelperSettings {
public LegacyTasHelperSettings() {
bool b1 = TasSettings.EnableOpenConsoleInTas;
bool b2 = TasSettings.EnableScrollableHistoryLog;
// not implemented yet
bool b3 = TasSettings.BetterInvincible;
// implement these if they do merge into celeste tas
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public static class SpeedrunToolInterop {
private static Dictionary<Follower, bool> followers;
private static bool disallowUnsafeInput;
private static Random auraRandom;
private static bool betterInvincible = false;

[Load]
private static void Load() {
Expand All @@ -60,6 +61,7 @@ public static void AddSaveLoadAction() {
followers = HitboxSimplified.Followers.DeepCloneShared();
disallowUnsafeInput = SafeCommand.DisallowUnsafeInput;
auraRandom = DesyncFixer.AuraHelperSharedRandom.DeepCloneShared();
betterInvincible = Manager.Running && BetterInvincible.Invincible;
};
Action<Dictionary<Type, Dictionary<string, object>>, Level> load = (_, _) => {
EntityDataHelper.CachedEntityData = savedEntityData.DeepCloneShared();
Expand All @@ -81,13 +83,18 @@ public static void AddSaveLoadAction() {
HitboxSimplified.Followers = followers.DeepCloneShared();
SafeCommand.DisallowUnsafeInput = disallowUnsafeInput;
DesyncFixer.AuraHelperSharedRandom = auraRandom.DeepCloneShared();
BetterInvincible.Invincible = Manager.Running && betterInvincible;
// note that tas will not invoke enable/disable run if it's using load state
// so if our "Set Invincible true" is after the savepoint, invoked, and get deleted later
// then Invincible will still be true after load state
};
Action clear = () => {
savedEntityData = null;
pressKeys = null;
followers = null;
InfoWatchEntity.SavedRequireWatchEntities.Clear();
auraRandom = null;
betterInvincible = false;
};

ConstructorInfo constructor = typeof(SaveLoadAction).GetConstructors()[0];
Expand Down
6 changes: 6 additions & 0 deletions CelesteTAS-EverestInterop/Source/Module/CelesteTasMenu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ private static EaseInSubMenu CreateMoreOptionsSubMenu(TextMenu menu) {
}));
subMenu.Add(new TextMenu.OnOff("Open Console In Tas".ToDialogText(), TasSettings.EnableOpenConsoleInTas).Change(value => TasSettings.EnableOpenConsoleInTas = value));
subMenu.Add(new TextMenu.OnOff("Scrollable History Log".ToDialogText(), TasSettings.EnableScrollableHistoryLog).Change(value => TasSettings.EnableScrollableHistoryLog = value));
TextMenu.Item betterInvincible;
subMenu.Add(betterInvincible = new TextMenu.OnOff("Better Invincibility".ToDialogText(), TasSettings.BetterInvincible).Change(value => {
TasSettings.BetterInvincible = value;
BetterInvincible.Invincible = false; // in case that value doesn't get reset for some unknown reason... yeah i have such bug report
}));
subMenu.AddDescription(menu, betterInvincible, "Better Invincible Description".ToDialogText());

TextMenu.Item hideFreezeFramesItem;
subMenu.Add(hideFreezeFramesItem = new TextMenu.OnOff("Hide Freeze Frames".ToDialogText(), TasSettings.HideFreezeFrames).Change(value =>
Expand Down
12 changes: 12 additions & 0 deletions CelesteTAS-EverestInterop/Source/Module/CelesteTasSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,18 @@ public bool EnableScrollableHistoryLog {
_EnableScrollableHistoryLog = value;
}
}

[YamlMember(Alias = "BetterInvincible")]
public bool _BetterInvincible = true;

[YamlIgnore]

public bool BetterInvincible {
get => Enabled && _BetterInvincible;
set {
_BetterInvincible = value;
}
}
public bool HideFreezeFrames { get; set; } = false;
public bool Mod9DLighting { get; set; } = false;
public bool IgnoreGcCollect { get; set; } = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,10 @@ private static void SetGameSetting(string settingName, string[] valueArgs) {
return;
}

if (settingName == "Invincible" && BetterInvincible.Handle((Assists)settings, (bool)values[0])) {
return;
}

if (!HandleSpecialCases(settingName, values[0])) {
field.SetValue(settings, values[0]);

Expand Down

0 comments on commit 9ecb9a7

Please sign in to comment.