/*
Senua's Saga: Hellblade II Autosplitter + Load Remover
Made by CactusDuper (@CactusDuper on Discord)
Thank you for your help Salad :)

https://www.speedrun.com/Hellblade2

Last updated: 5 June 2024
*/

state("Hellblade2-Win64-Shipping", "Steam"){}

state("Hellblade2-WinGDK-Shipping", "Xbox"){}


startup
{
	Assembly.Load(File.ReadAllBytes("Components/asl-help")).CreateInstance("Basic");

	settings.Add("ch1", true, "First Chapter");
	settings.Add("0_1_8", false, "Landfall", "ch1");
	settings.Add("0_2_13", false, "Shore of Slaves", "ch1");
	settings.Add("0_3_15", false, "Capsized Ship", "ch1");
	settings.Add("1_0_0", true, "Slavemaster Found (Ch1 end)", "ch1");
	
	settings.Add("ch2", true, "Second Chapter");
	settings.Add("1_1_4", false, "Freyslaug Sighted", "ch2");
	settings.Add("1_2_8", false, "Settlement Entrance", "ch2");
	settings.Add("1_3_16", false, "Return Home", "ch2");
	settings.Add("1_4_24", false, "Draugar Ceremony", "ch2");
	settings.Add("1_5_29", false, "Draugar Battle", "ch2");
	settings.Add("2_0_0", true, "Meeting the Stranger (Ch2 end)", "ch2");

	settings.Add("ch3", true, "Third Chapter");
	settings.Add("2_1_6", false, "Red Hills", "ch3");
	settings.Add("2_2_16", false, "Illtauga", "ch3");
	settings.Add("2_3_25", false, "On the Hill", "ch3");
	settings.Add("3_0_0", true, "Find the Hiddenfolk (Ch3 end)", "ch3");

	settings.Add("ch4", true, "Fourth Chapter");
	settings.Add("3_1_11", false, "Enter the Caves", "ch4");
	settings.Add("3_2_16", false, "Trial of Wisdom", "ch4");
	settings.Add("3_3_26", false, "Into Darkness", "ch4");
	settings.Add("3_4_41", false, "Act of Sacrifice", "ch4");
	settings.Add("3_5_47", false, "Breaking Through", "ch4");
	settings.Add("3_6_52", false, "A Gift Returned", "ch4");
	settings.Add("4_0_0", true, "The First Ritual (Ch4 end)", "ch4");

	settings.Add("ch5", true, "Fifth Chapter");
	settings.Add("4_1_2", false, "To the Sea", "ch5");
	settings.Add("4_2_12", false, "Sjavarrisi", "ch5");
	settings.Add("4_3_22", false, "Another Question", "ch5");
	settings.Add("4_4_29", false, "Astrior's Story", "ch5");
	settings.Add("4_5_33", false, "Waking the Giant", "ch5");
	settings.Add("5_0_0", true, "The Second Ritual (Ch5 end)", "ch5");

	settings.Add("ch6", true, "Sixth Chapter");
	settings.Add("5_1_14", false, "Into the Forest", "ch6");
	settings.Add("5_2_18", false, "Borgarvirki", "ch6");
	settings.Add("5_3_33", false, "Heart of Darkness", "ch6");
	settings.Add("5_3_36", true, "The Last Lie (Finish)", "ch6");
	//final one is 5_3_36 (no control after this point)
}

init
{
	IntPtr gameEngine = vars.Helper.ScanRel(3, "48 8B 0D ???????? 66 0F 5A C9 E8");

	// GEngine->GameInstance->Unk_FByteProperty->PostConstructLinkNext->Outer->Outer->Focused_ChapterIndex
	vars.Helper["chapterIndex"] = vars.Helper.Make<int>(gameEngine, 0x10D0, 0xC0, 0x60, 0x20, 0x20, 0x418);

	// GEngine->GameInstance->Unk_FByteProperty->PostConstructLinkNext->Outer->Outer->Focused_CheckpointIndex
	vars.Helper["checkpointIndex"] = vars.Helper.Make<int>(gameEngine, 0x10D0, 0xC0, 0x60, 0x20, 0x20, 0x41C);

	// GEngine->GameInstance->Unk_FByteProperty->PostConstructLinkNext->Outer->Outer->Focused_DevCheckpointIndex
	vars.Helper["devCheckpointIndex"] = vars.Helper.Make<int>(gameEngine, 0x10D0, 0xC0, 0x60, 0x20, 0x20, 0x420);

	// GEngine->GameInstance->Unk_FByteProperty->PostConstructLinkNext->Outer->Outer->bIsLoading
	vars.Helper["isLoading"] = vars.Helper.Make<bool>(gameEngine, 0x10D0, 0xC0, 0x60, 0x20, 0x20, 0x43A);

	// GEngine->GameInstance->Unk_FByteProperty->PostConstructLinkNext->Outer->Outer->bIsGamePaused
	vars.Helper["isPaused"] = vars.Helper.Make<bool>(gameEngine, 0x10D0, 0xC0, 0x60, 0x20, 0x20, 0x441);

	// GEngine->GameInstance->Unk_FByteProperty->PostConstructLinkNext->Outer->Outer->bMenuMusic
	vars.Helper["isMenuMusic"] = vars.Helper.Make<bool>(gameEngine, 0x10D0, 0xC0, 0x60, 0x20, 0x20, 0x446);

	// GEngine->GameInstance->Unk_FByteProperty->PostConstructLinkNext->Outer->Outer->ActiveChapterIndex
	vars.Helper["activeChapterIndex"] = vars.Helper.Make<int>(gameEngine, 0x10D0, 0xC0, 0x60, 0x20, 0x20, 0x57C);

	// GEngine->GameInstance->Unk_FByteProperty->PostConstructLinkNext->Outer->Outer->IsSkipCinematicsAvailable
	vars.Helper["IsSkipCinematicsAvailable"] = vars.Helper.Make<bool>(gameEngine, 0x10D0, 0xC0, 0x60, 0x20, 0x20, 0x44C);
		
	vars.completedSplits = new HashSet<string>();
}

onStart
{
	vars.completedSplits.Clear();
}

start
{
	return (current.activeChapterIndex == 0 && current.checkpointIndex == 0 && current.devCheckpointIndex == 1);
}

update
{	
	vars.Helper.Update();
	vars.Helper.MapPointers();
}

split
{
	string setting = "";

	if (current.activeChapterIndex != old.activeChapterIndex || current.checkpointIndex != old.checkpointIndex || current.devCheckpointIndex != old.devCheckpointIndex)
	{
		setting = current.activeChapterIndex + "_" + current.checkpointIndex + "_" + current.devCheckpointIndex;
	}
	
	return (settings.ContainsKey(setting) && settings[setting] && vars.completedSplits.Add(setting));
}

isLoading
{
	return (current.isLoading || current.isPaused || current.isMenuMusic || current.IsSkipCinematicsAvailable);
}

reset
{
	return current.activeChapterIndex == -1 && current.isMenuMusic;
}

exit
{
}