public static void Update() { try { RVAFinder.Update(); if (!Memory.IsHooked) { Memory.HookProcess(); } if (Memory.GameState == GameState.TitleScreen) { if (TitleScreenCallback != null) { OnTitleScreen(); } UberStateController.SkipListenersNextUpdate = true; } else if (Memory.GameState == GameState.Game) { UberStateController.Update(); if (InputUnlockCallback != null && InterOp.player_can_move()) { OnInputUnlock(); } SeedController.UpdateGoal(); TrackFileController.Update(); } AHK.Tick(); } catch (Exception e) { Log($"Update error: {e.Message}\n{e.StackTrace}"); } }
public static void Update() { try { var gs = InterOp.get_game_state(); if (gs == GameState.TitleScreen) { UberStateController.SkipListeners = true; if (TitleScreenCallback != null) { OnTitleScreen(); } } else if (gs == GameState.Game) { UberStateController.SkipListeners = false; UberStateController.Update(); if (InputUnlockCallback != null && InterOp.player_can_move()) { OnInputUnlock(); } SeedController.UpdateGoal(); TrackFileController.Update(); } AHK.Tick(); BonusItemController.Update(); DiscordController.Update(); Client.Update(); } catch (Exception e) { Log($"Update error: {e.Message}\n{e.StackTrace}"); } }
public static bool FilterEnabled(int filterId) { var f = (FilterType)filterId; switch (f) { // TODO case FilterType.Quests: return(!AHK.IniFlag("HideQuestFilter")); case FilterType.Teleports: return(!AHK.IniFlag("HideWarpFilter")); case FilterType.Collectibles: return(!AHK.IniFlag("HideCollectableFilter")); case FilterType.InLogic: return(SeedController.HasInternalSpoilers); case FilterType.Spoilers: return(UberGet.value(34543, 11226).Bool); default: return(true); } }
public static void OnSave(int slot, int backupSlot = -1) { if (Randomizer.Memory.PlayerStats.Health == 0) { DidWeJustDie = true; return; // the game saves right when you die, but we don't want to save progress when that happens. } if (slot == -1) { Randomizer.Log("Error: tried to save to empty slot"); return; } if (slot != CurrentSlot) { // this is a slot swap and not a save CurrentSlot = slot; Data = new SaveData(slot); Data.Load(backupSlot); if (Randomizer.InputUnlockCallback != null) { AHK.Print("Warning: Callback overwritten on slot change!", 240); Randomizer.InputUnlockCallback = null; } return; } Data.Save(backupSlot); }
public static void ProgressWithHints(ZoneType _zone = ZoneType.Void, bool justUnlocked = false) { int duration = justUnlocked ? 300 : 240; if (SeedController.HintsDisabled || InterOp.get_game_state() != GameState.Game) { if (!justUnlocked) { AHK.SendPlainText(new PlainText(SeedController.Progress, duration), justUnlocked); } return; } var zone = _zone == ZoneType.Void ? CurrentZone : _zone; var msg = getZoneHintMessage(zone, justUnlocked); if (justUnlocked) { msg = $"Bought hint: {msg}"; } else { msg = $"{SeedController.Progress}\n{msg}{GetKeySkillHints()}"; } AHK.SendPlainText(new PlainText(msg, duration), justUnlocked); }
public static bool Initialize() { try { if (!Directory.Exists(SaveFolder)) { Directory.CreateDirectory(SaveFolder); } foreach (var fileName in new String[] { LogFile, SeedFile, SeedNameFile }) { if (!File.Exists(fileName)) { File.WriteAllText(fileName, ""); Log($"Wrote blank {fileName} (normal for first-time init)"); } } AHK.Init(); SeedController.ReadSeed(); Memory = new MemoryManager(); if (!Memory.HookProcess()) { return(false); } Memory.PatchNoPause(true); return(true); } catch (Exception e) { Log($"init error: {e.Message}\n{e.StackTrace}"); return(true); } }
public static int Update() { try { if (!Memory.IsHooked) { Memory.HookProcess(); return(-3); } AHK.Tick(); if (Memory.GameState() == GameState.TitleScreen) { StateListener.Ready = false; } else if (Memory.GameState() == GameState.Game) { StateListener.Update(PerformNewGameInit); if (PerformNewGameInit) { UberStateInits(); return(-1); } return(-2); } return(-1); } catch (Exception e) { Log($"Update error: {e.Message}\n{e.StackTrace}"); } return(4); }
public static void NewGameInit() { var memory = Randomizer.Memory; if (!memory.IsLoadingGame()) { Randomizer.Log("New Game Init", false); SaveController.SetAbility(AbilityType.SpiritEdge); foreach (UberState s in DefaultUberStates) { memory.WriteUberState(s); } foreach (UberState s in Kuberstates) { memory.WriteUberState(s); } foreach (UberState s in DialogAndRumors) { memory.WriteUberState(s); } if (SeedController.KSDoorsOpen) { foreach (UberState s in KeystoneDoors) { memory.WriteUberState(s); } } if (!AHK.IniFlag("ShowShortCutscenes")) { foreach (UberState s in ShortCutscenes) { memory.WriteUberState(s); } } if (!AHK.IniFlag("ShowLongCutscenes")) { foreach (UberState s in LongCutscenes) { memory.WriteUberState(s); } } if (PsuedoLocs.GAME_START.Pickup().NonEmpty) { Randomizer.InputUnlockCallback = () => { PsuedoLocs.GAME_START.Pickup().Grant(); InterOp.magic_function(); InterOp.save(); }; } InterOp.discover_everything(); InterOp.bind_sword(); InterOp.save(); NeedsNewGameInit = false; } }
public static void ReadSeed() { var seedName = File.ReadAllText(Randomizer.SeedNameFile); if (seedName.Trim() != "") { pickupMap.Clear(); foreach (var line in File.ReadLines(Randomizer.SeedFile)) { try { var frags = line.Split('|'); var uberId = new UberId(int.Parse(frags[0]), int.Parse(frags[1])); var pickupType = (PickupType)byte.Parse(frags[2]); // Randomizer.Log($"uberId {uberId} -> {pickupType} {frags[3]}"); pickupMap[uberId] = BuildPickup(pickupType, frags[3]); } catch (Exception e) { Randomizer.Log($"Error parsing line: '{line}'\nError: {e.Message} \nStacktrace: {e.StackTrace}", false); } } AHK.Print($"Seed {seedName} loaded", 300); } else { AHK.Print($"No seed loaded; Download a .wotwr file and double-click it to load one", 360); } }
public static void OnNewGame(int slot) { // overwrite the message log TODO: save a backup maybe? File.WriteAllText(Randomizer.MessageLog, ""); SeedController.ReadSeed(); UberStateController.NeedsNewGameInit = true; AHK.OnNewGame(); SaveController.NewGame(slot); }
public static void OnUberState(UberState state) { var id = state.GetUberId(); if (pickupMap.TryGetValue(id, out Pickup p)) { AHK.Print(p.ToString()); p.Grant(); Randomizer.PleaseSave = true; } }
public static void Log(string message, bool printIfDev = true, string level = "INFO") { if (AHK.IniFlag("MuteCSLogs")) { return; } logQueue.Add($"{DateTime.Now:[yyyy-MM-dd HH:mm:ss.fff]} [{level}]: {message}\n"); if (Dev && printIfDev) { AHK.Print(message, 180, toMessageLog: false); } }
public static void OnTree(AbilityType ability) { UberId fakeId = new UberId((int)FakeUberGroups.TREE, (int)ability); if (pickupMap.TryGetValue(fakeId, out Pickup p)) { AHK.Print(p.ToString()); p.Grant(); Randomizer.PleaseSave = true; } else { Randomizer.Log($"Tree {ability} not found in seed. Get a seed from seedpack 10 or later."); } }
public static void OnLupoState(UberId id) { if (SeedController.HintsDisabled) { return; } if (LupoZoneIds.ContainsKey(id)) { ProgressWithHints(LupoZoneIds[id], true); } else if (id.ID == 41666) { AHK.SendPlainText(new PlainText($"Bought Hint: {GetKeySkillHintTwo()}", 300)); } }
public static void Log(string message, bool printIfDev = true, string level = "INFO") { if (AHK.IniFlag("MuteCSLogs")) { return; } if (level == "DEBUG" && !Dev) { return; } File.AppendAllText(LogFile, $"{DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss.fff]")} [{level}]: {message}\n"); if (Dev && printIfDev) { AHK.Print(message, 180, false); } }
public virtual void Grant(bool skipBase = false) { if (skipBase) { return; } if (Frames > 0) { AHK.Pickup(ToString(), Frames); } SaveController.Data.FoundCount++; if (NeedsMagic()) { InterOp.magic_function(); } }
public static void OnNewGame(int slot) { try { // overwrite the message log TODO: save a backup maybe? File.WriteAllText(Randomizer.MessageLog, ""); SeedController.ReadSeed(); UberStateController.NeedsNewGameInit = true; UberStateController.UberStates.Clear(); UberStateController.TickingUberStates.Clear(); AHK.OnNewGame(); SaveController.NewGame(slot); BonusItemController.Refresh(); Client.Connect(); } catch (Exception e) { Randomizer.Error("OnNewGame", e); } }
public static void Initialize() { Disabled = AHK.IniFlag("DisableNetcode"); if (Disabled) { Randomizer.Log("Netcode disabled, skipping discord init", false, "DEBUG"); return; } if (InitRunning) { Randomizer.Log("Init running already, skipping", false, "DEBUG"); return; } InitRunning = true; new Thread(() => { try { if (discord == null) { discord = new Discord.Discord(CLIENT_ID, (UInt64)CreateFlags.Default); } if (UserManager == null) { UserManager = discord.GetUserManager(); } if (ApplicationManager == null) { ApplicationManager = discord.GetApplicationManager(); } Initialized = true; if (GetUser() != null) { Randomizer.Log("User already known, skipping rest of discord init", false, "DEBUG"); Randomizer.Client.Connect(); return; } discord.SetLogHook(LogLevel.Debug, (level, message) => Randomizer.Log($"discord: {message}", level.CompareTo(LogLevel.Info) > 0, level.ToString())); UserManager.OnCurrentUserUpdate += DiscordInitComplete; } catch (Exception e) { Randomizer.Error("DiscInitThread", e); } InitRunning = false; }).Start(); }
public static void Log(string message, bool printIfDev = true) { if (AHK.IniFlag("MuteCSLogs")) { return; } if (LastMessage == message && message.Length > 60) { repeats++; if (repeats > 180) { repeats = 0; File.AppendAllText(LogFile, "suppressed repeats x180\n"); } return; } LastMessage = message; File.AppendAllText(LogFile, message + "\n"); if (Dev && printIfDev) { AHK.Print(message); } }
public static void OnLoad(int slot, int backupSlot = -1) { try { if (slot != CurrentSlot) { if (Randomizer.InputUnlockCallback != null) { AHK.Print("Warning: Callback overwritten on slot change!", 240); Randomizer.InputUnlockCallback = null; } // slot swap CurrentSlot = slot; Data = new SaveData(slot); } UberStateController.SkipListenersNextUpdate = true; Data.Load(backupSlot); if (DidWeJustDie) { InterOp.magic_function(); } } catch (Exception e) { Randomizer.Error("SaveCont.OnLoad", e); } }
private static bool ShouldRevert(UberState state) { if (NeedsNewGameInit || SkipListeners) { return(false); } if (state.Name == "cleanseWellspringQuestUberState" && state.Value.Int < 2 && !AHK.IniFlag("ShowShortCutscenes")) { return(true); } else if (state.Name == "findKuQuest" && state.Value.Int < 4) { return(true); } return(false); }
public static bool InjectDebugEnabled() { return(AHK.IniFlag("DebugInjectLogs")); }
public static bool InjectLogEnabled() { return(!AHK.IniFlag("MuteInjectLogs")); }
public static void NewGameInit() { if (!InterOp.is_loading_game()) { InterOp.clear_quest_messages(); Randomizer.Log($"New Game Init - {SeedController.SeedName}", false); ShopController.SetCostsAfterInit(); foreach (UberState s in DefaultUberStates) { s.Write(); } foreach (UberState s in Kuberstates) { s.Write(); } foreach (UberState s in DialogAndRumors) { s.Write(); } if (SeedController.KSDoorsOpen) { foreach (UberState s in KeystoneDoors) { s.Write(); } } if (!AHK.IniFlag("ShowShortCutscenes")) { foreach (UberState s in ShortCutscenes) { s.Write(); } } if (!AHK.IniFlag("ShowLongCutscenes")) { foreach (UberState s in LongCutscenes) { s.Write(); } } InterOp.discover_everything(); if (SeedController.Settings.LegacySeedgen && !SeedController.Flags.Contains(Flag.NOSWORD)) { SaveController.SetAbility(AbilityType.SpiritEdge); var slotRaw = AHK.IniString("Misc", "SpawnSlot"); var slot = 0; if (slotRaw != string.Empty) { slot = slotRaw.ParseToInt("Spawn Slot Ini") - 1; if (slot > 2 || slot < 0) { AHK.Print($"Ignoring invalid slot specifier {slotRaw}", toMessageLog: false); slot = 0; } } InterOp.bind(slot, 1002); } if (PsuedoLocs.GAME_START.Pickup().NonEmpty) { Randomizer.InputUnlockCallback = () => { MapController.UpdateReachable(2000); PsuedoLocs.GAME_START.OnCollect(); InterOp.save(); }; } else { MapController.UpdateReachable(); } InterOp.set_shard_slots(3); InterOp.save(); NeedsNewGameInit = false; } }
public static void OnGrantCheckable(CheckableHint ch) { CheckableHints[ch].State().Write(new UberValue(true)); AHK.SendPlainText(new PlainText($"Bought Hint: {ch.Hint}", 300)); }
public static bool Initialize() { try { if (logThread == null) { logThread = new Thread(() => { while (true) { try { var txt = logQueue.Take(); while (logQueue.TryTake(out var line)) { txt += line; } File.AppendAllText(LogFile, txt); } catch (Exception e) { if (Dev) { AHK.Print($"error logging: {e}", toMessageLog: false); } } } }); logThread.Start(); } BasePath = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(InterOp.get_base_path()); Debug($"Init: set base path to {BasePath}"); if (!Directory.Exists(SaveFolder)) { Directory.CreateDirectory(SaveFolder); } if (!File.Exists(SeedPathFile)) { File.WriteAllText(SeedPathFile, BasePath + ".currentseed"); } foreach (var fileName in new string[] { LogFile, MessageLog }) { if (!File.Exists(fileName)) { File.WriteAllText(fileName, ""); Log($"Wrote blank {fileName} (normal for first-time init)"); } } AHK.Init(); SeedController.ReadSeed(true); Client.UberStateRegistered = UberStateController.RegisterSyncedUberState; DiscordController.Initialize(); Debug("Init: Complete", false); return(true); } catch (Exception e) { Log($"init error: {e.Message}\n{e.StackTrace}"); return(true); } }