// Wuchang: Fallen Feathers Load Remover // Supports Load Removal (Compare to IGT) // Splits for campaigns can be obtained from: // Pointers and Script by TheDementedSalad state("Project_Plague-Win64-Shipping"){} state("Project_Plague-WinGDK-Shipping"){} startup { Assembly.Load(File.ReadAllBytes("Components/asl-help")).CreateInstance("Basic"); vars.Helper.AlertLoadless(); vars.completedSplits = new HashSet(); vars.Inventory = new Dictionary(); vars.splitstoComplete = new HashSet(); } init { /*switch (modules.First().ModuleMemorySize) { case (152428544): version = "SteamRelease"; break; } */ IntPtr gWorld = vars.Helper.ScanRel(3, "48 8B 05 ???????? 48 3B C? 48 0F 44 C? 48 89 05 ???????? E8"); IntPtr gEngine = vars.Helper.ScanRel(3, "48 89 05 ???????? 48 85 c9 74 ?? e8 ???????? 48 8d 4d"); IntPtr fNames = vars.Helper.ScanRel(3, "48 8d 0d ???????? e8 ???????? c6 05 ?????????? 0f 10 07"); IntPtr gSyncLoad = vars.Helper.ScanRel(21, "33 C0 0F 57 C0 F2 0F 11 05"); if (gWorld == IntPtr.Zero || gEngine == IntPtr.Zero) { const string Msg = "Not all required addresses could be found by scanning."; throw new Exception(Msg); } vars.Helper["isLoading"] = vars.Helper.Make(gSyncLoad); vars.Helper["TransitionDesc"] = vars.Helper.MakeString(gEngine, 0xAE0, 0x0); vars.Helper["LoadingScreen"] = vars.Helper.Make(gEngine, 0x1058, 0x108, 0x38, 0x30, 0xE8); vars.Helper["LoadingScreen"].FailAction = MemoryWatcher.ReadFailAction.SetZeroOrNull; vars.Helper["AcknowledgedPawn"] = vars.Helper.Make(gEngine, 0x1058, 0x38, 0x0, 0x30, 0x398, 0x18); vars.Helper["AcknowledgedPawn"].FailAction = MemoryWatcher.ReadFailAction.SetZeroOrNull; vars.Helper["Cutscene"] = vars.Helper.Make(gEngine, 0x1058, 0x38, 0x0, 0x30, 0x398, 0x19E8); vars.Helper["Item1"] = vars.Helper.Make(gEngine, 0x1058, 0x38, 0x0, 0x30, 0x2F8, 0x4D0, 0x920, 0x0, 0x0); vars.FNameToString = (Func)(fName => { var nameIdx = (fName & 0x000000000000FFFF) >> 0x00; var chunkIdx = (fName & 0x00000000FFFF0000) >> 0x10; var number = (fName & 0xFFFFFFFF00000000) >> 0x20; IntPtr chunk = vars.Helper.Read(fNames + 0x10 + (int)chunkIdx * 0x8); IntPtr entry = chunk + (int)nameIdx * sizeof(short); int length = vars.Helper.Read(entry) >> 6; string name = vars.Helper.ReadString(length, ReadStringType.UTF8, entry + sizeof(short)); return number == 0 ? name : name + "_" + number; }); vars.FNameToShortString = (Func)(fName => { string name = vars.FNameToString(fName); int dot = name.LastIndexOf('.'); int slash = name.LastIndexOf('/'); return name.Substring(Math.Max(dot, slash) + 1); }); vars.FNameToShortString2 = (Func)(fName => { string name = vars.FNameToString(fName); int under = name.LastIndexOf('_'); return name.Substring(0, under + 1); }); vars.FNameToShortString3 = (Func)(fName => { string name = vars.FNameToString(fName); int check = name.IndexOf('.'); return name.Substring(check + 1); }); } update { //Uncomment debug information in the event of an update. //print(modules.First().ModuleMemorySize.ToString()); vars.Helper.Update(); vars.Helper.MapPointers(); if(timer.CurrentPhase == TimerPhase.NotRunning) { vars.completedSplits.Clear(); } print(current.Item1.ToString()); //print(vars.FNameToString(current.Item1)); } onStart { vars.Inventory.Clear(); } start { return current.TransitionDesc == "/Game/Maps/ProjectMain" && !current.Cutscene && old.Cutscene; } split { } isLoading { return current.TransitionDesc == "/Game/MapsEntry/Lobby" || current.LoadingScreen == 1f || current.isLoading || vars.FNameToShortString2(current.AcknowledgedPawn) != "BP_CombatCharacter_Player_Final_C_" || current.Cutscene; } reset {}