-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathNewSuperLuckysTaleMemory.cs
More file actions
110 lines (84 loc) · 4.03 KB
/
NewSuperLuckysTaleMemory.cs
File metadata and controls
110 lines (84 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
using LiveSplit.Model;
using LiveSplit.VoxSplitter;
using System;
using System.Collections.Generic;
namespace LiveSplit.NewSuperLuckysTale {
public class NewSuperLuckysTaleMemory : Memory {
private Pointer<IntPtr> loading;
private StringPointer level;
private Pointer<bool> cutscene;
private bool isReady = true;
private int cutsceneCount = 0;
private readonly RemainingDictionary remainingSplits;
private bool allLevels = false;
private bool allPuzzles = false;
private readonly MonoHelper mono;
public NewSuperLuckysTaleMemory(LiveSplitState state, Logger logger) : base(state, logger) {
SetProcessNames("nslt", "New Super Lucky's Tale");
remainingSplits = new RemainingDictionary(logger);
mono = new MonoHelper(this);
}
public override bool IsReady() => base.IsReady() && mono.IsCompleted;
protected override void OnHook() {
mono.Run(() => {
MonoNestedPointerFactory ptrFactory = new MonoNestedPointerFactory(this, mono);
loading = ptrFactory.Make<IntPtr>("UiLoadingScreen", "<Instance>k__BackingField", "_spinningImage", 0x30);
level = ptrFactory.MakeString("GameScenesInterface", "_persistentLevelName", 0x14);
level.StringType = EStringType.UTF16Sized;
cutscene = ptrFactory.Make<bool>("CutsceneSequence", "<HasActiveCutscene>k__BackingField");
Logger.Log(ptrFactory.ToString());
});
}
public override bool Update() {
if(!isReady && loading.New != default && !String.IsNullOrEmpty(level.New)) {
isReady = true;
}
return isReady;
}
public override bool Start(int start) {
return loading.Old == default && loading.New != default
&& (level.New.Contains("TitleScreen") || level.New.Equals("LW_Intro_Cinematic") || start == (int)EStart.AnyLevel);
}
public override void OnStart(HashSet<string> splits) {
if(splits.Contains("Levels")) { allLevels = splits.Remove("Levels"); }
if(splits.Contains("Puzzles")) { allPuzzles = splits.Remove("Puzzles"); }
remainingSplits.Setup(splits);
cutsceneCount = 0;
}
public override bool Split() {
return remainingSplits.Count != 0 && (SplitLevels() || SplitCutscenes());
bool SplitLevels() {
if(!level.Changed || !(level.New.StartsWith("Chapter") || String.IsNullOrEmpty(level.New))) {
return false;
}
if(remainingSplits.ContainsKey("Level") && remainingSplits.Split("Level", level.Old)) {
return true;
}
bool isPuzzle = (level.Old.Contains("_Marble_") && level.Old.EndsWith("_Outro")) || level.Old.Contains("_SlidingBlock_");
if((allLevels && !isPuzzle) || (allPuzzles && isPuzzle)) {
Logger.Log("Split any level " + level.Old);
return true;
}
return false;
}
bool SplitCutscenes() {
if(!remainingSplits.ContainsKey("Cutscene")) { return false; }
// Remove if more cutscenes are added
if(!level.New.Equals("SP_Boss_01", StringComparison.Ordinal)) { return false; }
if(level.Changed) {
cutsceneCount = 0;
}
if(!cutscene.Old && cutscene.New) {
return remainingSplits.Split("Cutscene", level.New + "_" + (++cutsceneCount));
}
return false;
}
}
public override bool Loading() => loading.New != default || level.New.Equals("LW_Intro_Cinematic", StringComparison.Ordinal);
public override void OnExit() {
state.IsGameTimePaused = true;
isReady = false;
}
public override void Dispose() => mono.Dispose();
}
}