/*
* Ghostory has intentional support for Autosplitters built into the game. The data is exposed
* through the static class "AutosplitData", which has the following fields:
///
/// The current state of the game in human readable format.
///
/// Possible values are:
/// "Main Menu", "Entering Level", "Playing", "Restarting", "Exiting Level", "Cutscene", "Menu", "Victory", or null.
///
public static string gameState = null;
///
/// The index of the level the player is in. -1 if not in a level.
///
public static int levelIndex = -1;
///
/// The in-game time for the current attempt on this level.
///
public static float attemptTime = 0f;
///
/// The total playtime of this game session.
///
public static float totalPlaytime = 0f;
///
/// The number of chalices that you have collected.
///
public static int chaliceCount = 0;
///
/// The total number of jumps in this game session.
///
public static int jumpCount = 0;
///
/// The total number of keys picked up in this game session.
///
public static int keysCount = 0;
///
/// The total number of doors opened in this game session.
///
public static int doorsCount = 0;
///
/// The total number of cages opened in this game session.
///
public static int cagesCount = 0;
*
* If you have an idea for a new speedrun category that can't be autosplit with these values,
* jump into Ghostory Steam discussion forum and let the game's developer (me!) know.
*/
state("Ghostory") {}
startup
{
vars.Unity = Assembly.Load(File.ReadAllBytes(@"Components\UnityASL.bin")).CreateInstance("UnityASL.Unity");
settings.Add("resetOnLevelRestart", false, "Reset on level restart");
settings.Add("keySplit", false, "Split on collected key");
settings.Add("doorSplit", false, "Split on opened door");
settings.Add("cageSplit", false, "Split on opened cage");
}
init
{
vars.Unity.TryOnLoad = (Func)(helper => {
var myClass = helper.GetClass("Assembly-CSharp", "AutosplitData");
vars.Unity.MakeString(myClass.Static, myClass["gameState"]).Name = "gameState";
vars.Unity.Make(myClass.Static, myClass["levelIndex"]).Name = "levelIndex";
vars.Unity.Make(myClass.Static, myClass["attemptTime"]).Name = "attemptTime";
vars.Unity.Make(myClass.Static, myClass["totalPlaytime"]).Name = "totalPlaytime";
vars.Unity.Make(myClass.Static, myClass["chaliceCount"]).Name = "chaliceCount";
vars.Unity.Make(myClass.Static, myClass["jumpCount"]).Name = "jumpCount";
vars.Unity.Make(myClass.Static, myClass["keysCount"]).Name = "keysCount";
vars.Unity.Make(myClass.Static, myClass["doorsCount"]).Name = "doorsCount";
vars.Unity.Make(myClass.Static, myClass["cagesCount"]).Name = "cagesCount";
return true;
});
vars.Unity.Load(game);
}
update
{
if (!vars.Unity.Loaded) return false;
vars.Unity.Update();
}
start
{
// Start the timer when you start to control the character.
if (vars.Unity["gameState"].Changed && vars.Unity["gameState"].Current == "Playing") {
return true;
}
}
split
{
// 0 is main menu, 1-40 are playable levels, 41 is credits scene.
if (
vars.Unity["levelIndex"].Changed &&
vars.Unity["levelIndex"].Current > 0 &&
vars.Unity["levelIndex"].Current < 41
) {
return true;
}
// Hitting the Victory game state is the final split
if (vars.Unity["gameState"].Changed && vars.Unity["gameState"].Current == "Victory") {
return true;
}
if (settings["keySplit"]) {
if (vars.Unity["keysCount"].Changed) {
return true;
}
}
if (settings["doorSplit"]) {
if (vars.Unity["doorsCount"].Changed) {
return true;
}
}
if (settings["cageSplit"]) {
if (vars.Unity["cagesCount"].Changed) {
return true;
}
}
}
isLoading
{
// Pause the timer any time when you're not controlling the character.
return vars.Unity["gameState"].Current != "Playing";
}
reset
{
// Reset when returned to menu.
if (vars.Unity["levelIndex"].Changed && vars.Unity["levelIndex"].Current == 0) {
return true;
}
if (settings["resetOnLevelRestart"]) {
// Reset when restarting a level.
if (vars.Unity["gameState"].Changed && vars.Unity["gameState"].Current == "Restarting") {
return true;
}
}
}
exit
{
vars.Unity.Reset();
}
shutdown
{
vars.Unity.Reset();
}