Skip to content

Commit

Permalink
v1.9.2
Browse files Browse the repository at this point in the history
Bugfix: Predictor doesn't work properly when encountering Strawberry Jam Wonky Cassette Blocks
  • Loading branch information
LozenChen committed Feb 16, 2024
1 parent d73b1c5 commit 1ba4afd
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 16 deletions.
20 changes: 12 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ This mod is based on [CelesteTAS](https://github.com/EverestAPI/CelesteTAS-Evere

# Features:

- Check the menu in game! The menu should contain enough descriptions about TAS Helper features.

- In the following, hazards mean vanilla's CrystalStaticSpinner, Lightning and DustStaticSpinner, FrostHelper's CustomSpinner/AttachedLightning, VivHelper's CustomSpinner, and ChronoHelper's ShatterSpinner/DarkLightning.

- Cycle Hitbox Colors -> basically same as that in CelesteTAS mod, plus a bit modification when hazards are not in view or when spinner freezes.
Expand All @@ -24,7 +26,7 @@ This mod is based on [CelesteTAS](https://github.com/EverestAPI/CelesteTAS-Evere

- Camera Target -> show which direction the camera moves towards. Basically *CameraTarget = Player's position + CameraOffset*, plus CameraTarget should be bounded in room and some other modification, then *CameraPosition = (1-r)\*PreviousCameraPosition + r\*CameraTarget*, where *r = 0.074*. We visualize this by drawing the points Position, PreviousPosition and CameraTarget, and drawing a link from PreviousPosition to CameraTarget.

- CustomInfoHelper -> provide some fields / properties which are not easy to compute in CelesteTas's CustomInfo. Check [CustomInfoHelper](https://github.com/LozenChen/TAS-Helper/blob/main/Source/Gameplay/CustomInfoHelper.cs)
- CustomInfoHelper -> provide some fields / properties which are not easy to compute in CelesteTAS's CustomInfo. Check [CustomInfoHelper](https://github.com/LozenChen/TAS-Helper/blob/main/Source/Gameplay/CustomInfoHelper.cs)

- Order-of-Operation Stepping -> just like frame advance, but in a subframe scale, thus visualize order of operations in a frame. The bottom-left message indicates the next action (if there's no "begin/end" postfix) / current action (if there is) of the game engine.

Expand All @@ -38,7 +40,13 @@ This mod is based on [CelesteTAS](https://github.com/EverestAPI/CelesteTAS-Evere

- Add some commands -> Currently we have, spinner_freeze cmd, nearest_timeactive cmd, setting-related cmd, OoO config cmd. Check [Commands](https://github.com/LozenChen/TAS-Helper/blob/main/Docs/Commands.md)

- ... Check the menu in game!
- ...

# Feature Request:

If you have feature requests related to TAS, you can ping/DM me @Lozen#0956 on Celeste discord server. Please describe your feature request as detailed as possible. However, there is no guarantee that the final result will be same as what you've demanded.

When a feature is useful and standard enough to become a part of CelesteTAS, this feature will first be merged into TAS Helper (so you can get it at first time), and a pull request/an issue on this feature will be submitted to CelesteTAS simultaneously.

# Some details:

Expand All @@ -56,7 +64,7 @@ This mod is based on [CelesteTAS](https://github.com/EverestAPI/CelesteTAS-Evere

- Push on XMinty's AutoWatch PR on CelesteTAS, to support more entities (e.g. for an entity with a re-awake timer, watch the timer if it's not zero).

- SpeedrunTool multi-saveslots PR (hard afaik, even though we've effectively created a 2-nd saveslot in Tas Helper)
- SpeedrunTool multi-saveslots PR (hard afaik, even though we've effectively created a 2-nd saveslot in TAS Helper)

- Auto completion in Celeste Studio (when using something like "set invincible true"), and some other gadgets for Studio. (Update: relating codes already exist in Studio, but it seems they have not been used)

Expand All @@ -66,12 +74,8 @@ This mod is based on [CelesteTAS](https://github.com/EverestAPI/CelesteTAS-Evere

- Laggy when there are too many spinners (e.g. Strawberry Jam GrandMaster HeartSide) -> Partially solved in v1.4.7.

- TAS Helper does not save settings (change settings in the menu) when closing game with the X instead of the exit button in game -> Can't reproduce. It's said that turning off and on tashelper after changing settings will work. After several changes on settings system, i guess this bug should be addressed after v1.6.5.

- Predictor can't handle commands like StunPause Simulate (StunPause Input is ok), SetCommands, InvokeCommands and so on. -> Currently don't plan to support them. Tell me if you need this feature.

- Celeste TAS hotkeys randomly work improperly -> Not sure if it's caused by TAS Helper.

- Use SRT save, then reload asset, then SRT load. This causes crash -> I guess it's a general issue and only happens for mod developers, so just ignore it.

- Predictor can't handle SJ cassette blocks well -> Not sure but I guess the reason is, they have special hook such that SJ cassette blocks also update in freeze frames, and my simulator doesn't take this into account.
- ~~Use SRT save, then reload asset, then SRT load. This causes crash -> I guess it's a general issue and only happens for mod developers, so just ignore it.~~
26 changes: 26 additions & 0 deletions Source/Maintenance/MaintenanceRoutine.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//#define Maintenance

#if Maintenance
using Celeste.Mod.TASHelper.Utils;

namespace Celeste.Mod.TASHelper.Maintenance;
internal static class MaintenaceRoutine {

private static void CheckSpeedrunTool() {
// Tiny SRT needs "sync fork" from SpeedrunTool
}

[Initialize]
private static void CheckSimplifiedTriggers() {
// check if new triggers appear and need to be "simplified"
List<Type> types = ModUtils.GetTypes().Where(x => x.IsSameOrSubclassOf(typeof(Trigger))).ToList();
foreach (Type type in types) {
Logger.Log("TAS Helper Maintenance", type.FullName);
}
}

private static void CheckTasSync() {
// run tases of the most popular maps
}
}
#endif
2 changes: 1 addition & 1 deletion Source/Module/Loader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Celeste.Mod.TASHelper.Module;

internal static class Loader {

// order: all mods load -> all mods initialize ~= all mods load content
// order: all mods (load settings -> load) -> all mods initialize ~= all mods load content

public static void Load() {
Reloading = GFX.Loaded; // Tas Helper load -> GFX load -> Tas Helper unload -> Tas Helper reload. So GFX.Loaded can be used to detect this
Expand Down
1 change: 1 addition & 0 deletions Source/Module/WhatsNew.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public static void CreateUpdateLog() {
AddLog("1.8.22", "Performance Optimization. It improves by 25%.");
AddLog("1.9.0", "Feature: Movement Overshoot Assistant. This shows how far player would go if there were no walls.", "Add OUI console commands, so you can goto some common OUIs very quickly.");
AddLog("1.9.1", "Rename some internal class names to resolve some custom info issues.");
AddLog("1.9.2", "Bugfix: Predictor doesn't work properly when encountering Strawberry Jam Wonky Cassette Blocks.");
UpdateLogs.Sort((x, y) => new Version(y.Item1).CompareTo(new Version(x.Item1)));
}

Expand Down
7 changes: 6 additions & 1 deletion Source/Predictor/PredictorCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ private static void AlmostEngineUpdate(Engine engine, GameTime gameTime) {
}
if (!Engine.DashAssistFreeze) {
if (Engine.FreezeTimer > 0f) {
SJ_CassetteHookFreeze?.Invoke(null, parameterless);
Engine.FreezeTimer = Math.Max(Engine.FreezeTimer - Engine.RawDeltaTime, 0f);
}
else if (engine.scene != null) {
Expand Down Expand Up @@ -183,14 +184,18 @@ public static void Initialize() {
});

typeof(Level).GetMethod("BeforeRender").HookBefore(DelayedActions);

#pragma warning disable CS8601
SJ_CassetteHookFreeze = ModUtils.GetType("StrawberryJam2021", "Celeste.Mod.StrawberryJam2021.Entities.WonkyCassetteBlockController")?.GetMethod("FreezeUpdate", BindingFlags.NonPublic | BindingFlags.Static);
#pragma warning restore CS8601
HookHelper.SkipMethod(typeof(PredictorCore), nameof(InPredictMethod), typeof(GameInfo).GetMethod("Update", BindingFlags.Public | BindingFlags.Static));
HookHelper.SkipMethod(typeof(PredictorCore), nameof(PreventSendStateToStudio), typeof(TAS.Manager).GetMethod("SendStateToStudio", BindingFlags.Public | BindingFlags.Static));

InitializeChecks();
InitializeCachePeriod();
}

private static MethodInfo SJ_CassetteHookFreeze;

private static void AfterMInputUpdate() {
PredictorRenderer.ClearCachedMessage();
FreezeTimerBeforeUpdate = Engine.FreezeTimer;
Expand Down
12 changes: 7 additions & 5 deletions Source/Utils/HookHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ private static void OnAfterUpdate(On.Monocle.Scene.orig_AfterUpdate orig, Monocl
}

internal static class _Level {
// name it as _Level instead of Level, so custom info will not find it using "Level", so "Level.Wind" will work properly in infohud
// name it as "_Level" instead of "Level", so custom info will not find it using "Level", so "Level.Wind" will work properly in infohud
public delegate void LoadLevelHandler(_Celeste.Level level, Player.IntroTypes playerIntro, bool isFromLoader = false);

public static event LoadLevelHandler LoadLevel;
Expand Down Expand Up @@ -331,7 +331,9 @@ private static void OnEntityListDebugRender(On.Monocle.EntityList.orig_DebugRend
public static class CILCodeHelper {
public static void CILCodeLogger(this ILCursor ilCursor, int logCount = 999999, bool useCommand = true) {
// remember, Commands.Log can only work in Initialize()
Celeste.Commands.Log("------------------------------");
if (useCommand) {
Celeste.Commands.Log("------------------------------");
}
Logger.Log(LogLevel.Debug, "TAS Helper", "---- CILCodeLogger ----");
if (Apply) {
if (AsShift) {
Expand All @@ -344,13 +346,13 @@ public static void CILCodeLogger(this ILCursor ilCursor, int logCount = 999999,
while (logCount > 0 && ilCursor.Next is not null) {
string str;
if (ilCursor.Next.Operand is ILLabel label) {
str = $"{ilCursor.Next.Offset.ToString("x4")}, {ilCursor.Next.OpCode}, {ilCursor.Next.Operand} | {label.Target.Offset.ToString("x4")}, {label.Target.OpCode}, {label.Target.Operand}";
str = $"{ilCursor.Next.Offset:x4}, {ilCursor.Next.OpCode}, {ilCursor.Next.Operand} | {label.Target.Offset:x4}, {label.Target.OpCode}, {label.Target.Operand}";
}
else if (ilCursor.Next.Operand is Instruction ins) {
str = $"{ilCursor.Next.Offset.ToString("x4")}, {ilCursor.Next.OpCode} | {ins.Offset.ToString("x4")}, {ins.OpCode}, {ins.Operand}";
str = $"{ilCursor.Next.Offset:x4}, {ilCursor.Next.OpCode} | {ins.Offset:x4}, {ins.OpCode}, {ins.Operand}";
}
else {
str = $"{ilCursor.Next.Offset.ToString("x4")}, {ilCursor.Next.OpCode}, {ilCursor.Next.Operand}";
str = $"{ilCursor.Next.Offset:x4}, {ilCursor.Next.OpCode}, {ilCursor.Next.Operand}";
}
Mod.Logger.Log(LogLevel.Debug, "TAS Helper", str);
if (useCommand) {
Expand Down
2 changes: 1 addition & 1 deletion everest.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
- Name: TASHelper
Version: 1.9.1
Version: 1.9.2
DLL: bin/Release/net4.5.2/TASHelper.dll
Dependencies:
- Name: Everest
Expand Down

0 comments on commit 1ba4afd

Please sign in to comment.