Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
jakzo committed Dec 16, 2023
2 parents 1458430 + 1f70e16 commit 2c3c46d
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 0 deletions.
50 changes: 50 additions & 0 deletions projects/Boneworks/SpeedrunTools/src/Features/ArenaSplitState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using MelonLoader;
using HarmonyLib;
using UnityEngine;
using StressLevelZero.Arena;

namespace Sst.Features {
class ArenaSplitState : Feature {
// State that the ASL finds using signature scanning
private static byte[] State = {
// 0 = magic string start
// Signature is set dynamically to avoid finding this hardcoded array
0x00, // 0xD5
0xE2,
0x03,
0x34,
0xC2,
0xDF,
0x63,
// 7 = arena index
0x00,
};

private static bool _isCurrentChallengeCompleted = true;

public ArenaSplitState() { State[0] = 0xD5; }

[HarmonyPatch(typeof(Arena_GameManager),
nameof(Arena_GameManager.RingTheBell))]
class ArenaGameManager_RingTheBell_Patch {
[HarmonyPostfix()]
internal static void Postfix(Arena_GameManager __instance) {
_isCurrentChallengeCompleted =
__instance.activeChallenge?.profile?.completedHard ?? true;
}
}

[HarmonyPatch(typeof(Arena_GameManager),
nameof(Arena_GameManager.SaveChallengeCompletion))]
class ArenaGameManager_SaveChallengeCompletion_Patch {
[HarmonyPostfix()]
internal static void Postfix(Arena_GameManager __instance) {
if (!_isCurrentChallengeCompleted &&
__instance.activeChallenge.profile.completedHard) {
_isCurrentChallengeCompleted = true;
State[7]++;
}
}
}
}
}
1 change: 1 addition & 0 deletions projects/Boneworks/SpeedrunTools/src/Mod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class Mod : MelonMod {
new Features.Gripless(),
new Features.Armless(),
new Features.RestartLevel(),
new Features.ArenaSplitState(),

// Dev features
new Features.Speedometer(),
Expand Down
110 changes: 110 additions & 0 deletions scripts/Boneworks100.asl
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
state("BONEWORKS") {
int levelNumber : "GameAssembly.dll", 0x01E7E4E0, 0xB8, 0x590;
}

init {
var module = modules.First(x => x.ModuleName == "vrclient_x64.dll");

var scanner =
new SignatureScanner(game, module.BaseAddress, module.ModuleMemorySize);

vars.loadingPointer = scanner.Scan(new SigScanTarget(
3,
"4889??????????488B??????????48FF????488B??????????488B??4889??????????488D??????????488B??????????48FF??????????????????????????????488B??????????418B") {
OnFound = (process, scanners, addr) =>
addr + 0x4 + process.ReadValue<int>(addr)
});
if (vars.loadingPointer == IntPtr.Zero) {
throw new Exception("Game engine not initialized - retrying");
}

vars.isLoading =
new MemoryWatcher<bool>(new DeepPointer(vars.loadingPointer, 0xC54));

var arenaTarget = new SigScanTarget(7, "D5 E2 03 34 C2 DF 63 ??");
IntPtr ptr = IntPtr.Zero;
foreach (var page in game.MemoryPages(true)) {
var pageScanner =
new SignatureScanner(game, page.BaseAddress, (int)page.RegionSize);
ptr = pageScanner.Scan(arenaTarget);
if (ptr != IntPtr.Zero)
break;
}
if (ptr == IntPtr.Zero) {
throw new Exception("Arena state not found - retrying");
}
vars.arenaWatcher = new MemoryWatcher<byte>(ptr);

// Index in levelOrder to start the run at (for practice)
vars.startingSplit = 0;

// Will split when entering each level in this list in this order
// If entering a level later in the list it will split until it reaches it
vars.levelOrder = new int[] {
2, // scene_theatrigon_movie01 -> scene_breakroom
4, // scene_museum
5, // scene_streets
5, // scene_streets
6, // scene_runoff
6, // scene_runoff
7, // scene_sewerStation
8, // scene_warehouse
9, // scene_subwayStation
10, // scene_tower
11, // scene_towerBoss
12, // scene_theatrigon_movie02 -> scene_dungeon
14, // scene_arena
15, // scene_throneRoom
1, // scene_mainMenu
18, // scene_redactedChamber
19, // sandbox_handgunBox
22, // scene_hoverJunkers
16, // arena_fantasy
23, // zombie_warehouse
// 23, // zombie_warehouse
// 23, // zombie_warehouse
1, // scene_mainMenu
};
vars.levelOrderIdx = 0;
vars.targetLevelOrderIdx = vars.startingSplit;
}

update {
vars.isLoading.Update(game);
vars.arenaWatcher.Update(game);
}

isLoading { return vars.isLoading.Current; }

start {
if (vars.isLoading.Current &&
current.levelNumber == vars.levelOrder[vars.startingSplit]) {
vars.levelOrderIdx = 0;
return true;
}
return false;
}

split {
if (vars.arenaWatcher.Current != vars.arenaWatcher.Old) {
return true;
}

if (vars.isLoading.Current &&
(!vars.isLoading.Old || current.levelNumber != old.levelNumber)) {
var nextLevelOrderIdx = vars.levelOrderIdx + 1;
if (nextLevelOrderIdx < vars.levelOrder.Length &&
vars.levelOrder[nextLevelOrderIdx] == current.levelNumber) {
vars.targetLevelOrderIdx = nextLevelOrderIdx;
}
}

if (vars.levelOrderIdx < vars.targetLevelOrderIdx) {
vars.levelOrderIdx++;
return true;
}

return false;
}

exit { timer.IsGameTimePaused = true; }

0 comments on commit 2c3c46d

Please sign in to comment.