Skip to content

Instantly share code, notes, and snippets.

@CryZe
Last active February 26, 2019 12:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CryZe/f1ab31823e5a26e37e8e0f32e7047f17 to your computer and use it in GitHub Desktop.
Save CryZe/f1ab31823e5a26e37e8e0f32e7047f17 to your computer and use it in GitHub Desktop.
Fully working A Hat in Time Auto Splitter written in TypeScript
set_process_name("HatinTimeGame.exe")
class GameState:
timer_state = 0
act_timer_is_visible = 0
real_game_time = 0.0
time_piece_count = 0
class AutoSplitter:
base_address = None
current = None
old = None
def update_game_state(self):
if self.base_address != None:
self.old = self.current
self.current = GameState()
self.current.timer_state = read_i32(self.base_address)
self.current.act_timer_is_visible = read_i32(self.base_address + 20)
self.current.real_game_time = read_f64(self.base_address + 48)
self.current.time_piece_count = read_i32(self.base_address + 64)
def update(self):
if self.base_address == None:
address = scan_signature("""
54 49 4D 52
?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ??
?? ?? ?? ??
?? ?? ?? ??
?? ?? ?? ??
?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ??
45 4E 44 20
""")
if address != None:
print_message("Fully connected")
self.base_address = address + 4
self.current = None
self.old = None
set_tick_rate(60.0)
else:
print_message("Not found")
set_tick_rate(1.0)
self.update_game_state()
def should_start(self):
if self.current != None and self.old != None:
return self.current.timer_state == 1 and self.old.timer_state == 0
def should_split(self):
if self.current != None and self.old != None:
just_got_time_piece = self.current.time_piece_count == self.old.time_piece_count + 1
is_in_credits = self.current.timer_state == 2
return just_got_time_piece or is_in_credits
def should_reset(self):
if self.current != None and self.old != None:
return self.current.timer_state == 0 and self.old.timer_state == 1
def is_loading(self):
return True
def game_time(self):
if self.current != None:
return self.current.real_game_time
print_message("Hello World")
setProcessName('HatinTimeGame.exe')
interface State {
baseAddress: Address | null,
current: GameState | null,
old: GameState | null,
}
interface GameState {
timerState: i32, // +0
actTimerIsVisible: i32, // +20
realGameTime: f64, // +48
timePieceCount: i32, // +64
}
const state: State = {
baseAddress: null,
current: null,
old: null,
};
function updateGameState(state: State) {
if (state.baseAddress != null) {
const timerState = readI32(state.baseAddress);
const actTimerIsVisible = readI32(state.baseAddress.addU64(new u64(20)));
const realGameTime = readF64(state.baseAddress.addU64(new u64(48)));
const timePieceCount = readI32(state.baseAddress.addU64(new u64(64)));
state.old = state.current;
state.current = { timerState, actTimerIsVisible, realGameTime, timePieceCount };
}
}
function update() {
if (state.baseAddress == null) {
const address = scanSignature(
`54 49 4D 52
?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ??
?? ?? ?? ??
?? ?? ?? ??
?? ?? ?? ??
?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ??
45 4E 44 20`,
);
if (address != null) {
printMessage(`Fully connected ${address.toHexString()}`);
state.baseAddress = address.addU64(new u64(4));
state.current = null;
state.old = null;
setTickRate(60.0);
} else {
printMessage("Not found");
setTickRate(1.0);
}
}
updateGameState(state);
}
function shouldStart() {
const { current, old } = state;
if (current != null && old != null) {
return current.timerState == 1 && old.timerState == 0;
} else {
return false;
}
}
function shouldSplit() {
const { current, old } = state;
if (current != null && old != null) {
const justGotTimePiece = current.timePieceCount == old.timePieceCount + 1
&& current.actTimerIsVisible == 1;
const isInCredits = current.timerState == 2;
return justGotTimePiece || isInCredits;
} else {
return false;
}
}
function shouldReset() {
const { current, old } = state;
if (current != null && old != null) {
return current.timerState == 0 && old.timerState == 1;
} else {
return false;
}
}
const isLoading = () => true;
function gameTime() {
const { current } = state;
if (current != null) {
return current.realGameTime;
} else {
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment