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; } }
private static string getZoneHintMessage(ZoneType zone, bool justUnlocked) { if (zone == ZoneType.Void) { return($"no hint for Void(area {InterOp.get_player_area()})"); } var items = HintObjects.GetOrElse(zone, new List <Checkable>()); var found = items.FindAll(i => i.Has()); if (!justUnlocked && !HaveHintForZone(zone)) { return($"{zone}: {found.Count}/?? key items (Hint not unlocked)"); } if (items.Count > 0) { var g = found.Count == items.Count ? "$" : ""; if (found.Count > 0) { return($"{zone}: {g}{found.Count}/{items.Count}{g} key items\nfound: {String.Join(", ", found.Select(i => i.DisplayName))}"); } else { return($"{zone}: {found.Count}/{items.Count} key items"); } } return($"No key items in {zone}"); }
public static void InitLupoPrices() { foreach (var lp in lupoPrices) { InterOp.set_lupo_area_price(lp.Key, 2 * lp.Value); } }
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); }
private static UberState createUberStateEntry(UberId id) { if (!InterOp.get_uber_state_exists(id.GroupID, id.ID)) { Randomizer.Error("cuse", $"Failed to find {id} in uber state system.", false); return(null); } byte[] buffer = new byte[256]; int len = InterOp.get_uber_state_name(id.GroupID, id.ID, buffer, buffer.Length); string name = System.Text.Encoding.ASCII.GetString(buffer, 0, len); len = InterOp.get_uber_state_group_name(id.GroupID, id.ID, buffer, buffer.Length); string groupName = System.Text.Encoding.ASCII.GetString(buffer, 0, len); var s = new UberState() { ID = id.ID, GroupID = id.GroupID, Name = name, GroupName = groupName, Type = InterOp.get_uber_state_type(id.GroupID, id.ID), }; s.Value = CreateValue(s.Type, InterOp.get_uber_state_value(id.GroupID, id.ID)); return(s); }
public static void Init() { Engine.ExecRaw(Program); Ready = true; bool cursorLock = IniFlag("CursorLock"); bool disableDebug = IniFlag("DisableDebugControls"); if (cursorLock || disableDebug) { Randomizer.TitleScreenCallback = () => { if (disableDebug) { Randomizer.Memory.Debug = false; } if (cursorLock) { InterOp.toggle_cursorlock(); } }; } if (IniFlag("dev")) { Randomizer.Dev = true; } }
public TrackData() { if (TrackFileController.DontTrackYet) { keystones = 0; spiritLight = 0; ore = 0; skills = new HashSet <String>(); upgraded = new HashSet <String>(); events = new HashSet <String>(); teleporters = new HashSet <String>(); } try { keystones = InterOp.get_keystones(); spiritLight = InterOp.get_experience(); ore = InterOp.get_ore(); skills = SaveController.SkillsFound.Select((AbilityType type) => trackName(type)).ToHashSet(); upgraded = SaveController.UpgradedWeapons.Select((AbilityType type) => $"{type.GetDescription().Replace(" ", "")}").ToHashSet(); if (SaveController.HasAbility(AbilityType.DamageUpgrade1) && SaveController.HasAbility(AbilityType.DamageUpgrade2)) { upgraded.Add(trackName(AbilityType.DamageUpgrade1)); } events = SaveController.WorldEvents.Select((QuestEventType type) => type.GetDescription()).ToHashSet(); teleporters = Teleporter.TeleporterStates.Keys.Where((TeleporterType t) => (new Teleporter(t)).Has()).Select((TeleporterType t) => t.GetDescription()).ToHashSet(); } catch (Exception e) { Randomizer.Error("TrackData()", e); } }
public static void Init() { Engine.ExecRaw(Program); Engine.ExecRaw(Binds); Ready = true; bool cursorLock = IniFlag("CursorLock"); bool disableDebug = IniFlag("DisableDebugControls"); if (cursorLock || disableDebug) { Randomizer.TitleScreenCallback = () => { if (disableDebug) { InterOp.set_debug_controls(false); } if (cursorLock) { InterOp.toggle_cursorlock(); } }; } if (IniFlag("dev")) { Randomizer.Dev = true; } int maxLogLines = Randomizer.Dev ? 1000 : 100; var logLines = File.ReadAllLines(Randomizer.LogFile); if (logLines.Length > maxLogLines) { File.WriteAllLines(Randomizer.LogFile, logLines.Skip(logLines.Length / 2)); } }
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 void UpdateReachable(int sleepTime = 30) { if (InterOp.get_game_state() == GameState.Game) { var t = new Thread(() => UpdateReachableAsync(sleepTime)); t.Start(); } }
public static int Bootstrap(string dllPath) { if (!Initialize()) { return(1); } InterOp.RegisterCSharpBindings(); return(0); }
public static void OnMapPan(AreaType type) { if (SeedController.HintsDisabled) { return; } var msg = getZoneHintMessage(type.toZone(), false) + GetKeySkillHints(); if (msg.Count(c => c == '\n') == 2) // if there's exactly 3 lines, insert an extra linebreak at the top { msg = "\n" + msg; // so the middle text isn't obscured by the filter button } InterOp.update_map_hint(msg); }
public static void Update() { float h = InterOp.get_uber_state_value(4, (int)BonusType.HealthRegen); if (h > 0) { InterOp.add_health(h * 0.0028f); } float e = InterOp.get_uber_state_value(4, (int)BonusType.EnergyRegen); if (e > 0) { InterOp.add_energy(e * 0.00028f); } }
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 SetAbility(AbilityType ability, bool setTo = true) { if (setTo) { Data.SkillsFound.Add(ability); } else { Data.SkillsFound.Remove(ability); } InterOp.set_ability(ability, setTo); if (ability.Equip().HasValue) { InterOp.set_equipment(ability.Equip().Value, setTo); } TrackFileController.Write(); }
public static void Update() { if (InterOp.get_game_state() == GameState.Game) { DontTrackYet = false; } if (IgnoreUpdateFrames > 0) { IgnoreUpdateFrames--; return; } try { if (Last == null || Last.ore != InterOp.get_ore() || Last.spiritLight != InterOp.get_experience()) { Write(); } } catch (Exception e) { Randomizer.Error("Track.Update", e); Randomizer.Log($"Last: {Last}", false); } }
public static void Update() { try { if (NeedsNewGameInit) { NewGameInit(); } if (!SkipListeners) { // We do ToArray here so we can change the hashset while we are looping. foreach (var state in TickingUberStates.ToArray()) { // Maybe change this to use our own cache lookup? var value = InterOp.get_uber_state_value(state.GroupID, state.ID); InterOp.set_uber_state_value(state.GroupID, state.ID, value + 1); } } if (FullSyncNextUpdate) { FullSyncNextUpdate = false; Randomizer.Client.SendBulk(SyncedUberStates.Where(uid => uid.State() != null).ToDictionary(uid => uid, (uid) => uid.State().ValueAsFloat())); var bad = SyncedUberStates.Where(uid => uid.State() == null).ToList(); foreach (var baduid in bad) { SyncedUberStates.Remove(baduid); } } while (Randomizer.Client.UberStateQueue.TryTake(out var stateUpdate)) { var(id, val) = stateUpdate.FromNet(); if (id.State().ValueAsFloat() != val) { InterOp.set_uber_state_value(id.GroupID, id.ID, val); } } } catch (Exception e) { Randomizer.Error("USC.Update", e, false); } }
public static void Tick() { var signal = Engine.ExecFunction("Tick"); if (signal != null && signal != "none") { Engine.SetVar("signal", "none"); HandleSignal(signal); } FramesTillUnlockReload = Math.Max(0, FramesTillUnlockReload - 1); if (FramesTillNextSend > 0) { FramesTillNextSend--; } else { if (CanPrint) { Current = MessageQueue.Peek(); FramesTillNextSend = Current.Frames; try { if (Current.Clear) { InterOp.clear_visible_hints(); } InterOp.display_hint(Current.Text, Current.Frames / 60f, Current.Pos, Current.Mute); if (IniFlag("LogOnPrint")) { Randomizer.Log($"Sending {Current.Text} for {Current.Frames} ({MessageQueue.Count} remaining in queue)", false); } MessageQueue.Dequeue(); } catch (Exception e) { Randomizer.Error("AHK.sendMsg", e, false); } } else { Current = null; } } }
public static void PopulateUberStates() { uberStateLookup = new Dictionary <UberId, UberState>(); unsafe { var size = 0; var states = InterOp.get_uber_states(ref size); for (var i = 0; i < size; ++i) { var def = states[i]; var name = Marshal.PtrToStringAnsi(def.Name); var groupName = Marshal.PtrToStringAnsi(def.GroupName); uberStateLookup.Add(new UberId(def.GroupID, def.ID), new UberState() { ID = def.ID, GroupID = def.GroupID, Name = name, GroupName = groupName, Type = def.Type }); } } }
private static void HandleSpecial(UberState state) { if (state.Name == "arenaBByteStateSerialized" && state.Value.Byte == 4) { // lumaPoolsStateGroup.arenaByteStateSerialized new UberId(5377, 1373).State().Write(state.Value); } else if (state.Name == "craftCutsceneState" && 0 < state.Value.Byte && state.Value.Byte < 3) { state.Write(new UberValue((byte)3)); // Give diamond in the rough pickup. new UberId(23987, 14832).State().Write(new UberValue(true)); } // the below is a fix for a vanilla bug where you can just miss getting voice if you else if (state.Name == "findToadQuestUberState" && state.Value.Int == 2 || // (a) skip the kwolok cutscene too fast state.Name == "cleanseWellspringQuestUberState" && state.Value.Int == 4 // (b) come to kwolok after wellspring and get the cutscenes stacked awkwardly ) { Randomizer.InputUnlockCallback = () => { // this is really questionable!! var voiceState = new UberId(46462, 59806).State(); if (!voiceState.Value.Bool) { voiceState.Write(new UberValue(true)); InterOp.set_max_health(InterOp.get_max_health() + 10); InterOp.set_max_energy(InterOp.get_max_energy() + 1); InterOp.fill_health(); InterOp.fill_energy(); InterOp.save(); } // should happen in both branches if (SeedController.Flags.Contains(Flag.ALLWISPS)) { HintsController.ProgressWithHints(); } } } ; }
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); } }
public static void Refresh(this UberId id) => InterOp.refresh_uber_state(id.GroupID, id.ID);
public static void HandleSignal(string signal) { switch (signal) { case "reload": if (FramesTillUnlockReload == 0) { iniFlagCache.Clear(); FramesTillNextSend = 0; Randomizer.Client.Connect(); SeedController.ReadSeed(); if (InterOp.get_game_state() == GameState.Game) { PsuedoLocs.RELOAD_SEED.OnCollect(); } FramesTillUnlockReload = 120; } break; case "lastPickup": FramesTillNextSend = 1; // the only reason this isn't = 0 is that spamming this could get really annoying MessageQueue.Enqueue(Last); break; case "progressAndHints": HintsController.ProgressWithHints(); break; case "dev": Randomizer.Dev = !Randomizer.Dev; Randomizer.Log($"Dev: {Randomizer.Dev}"); break; case "exitapp": Environment.Exit(Environment.ExitCode); break; case "toggleDebug": InterOp.set_debug_controls(!InterOp.get_debug_controls()); Print($"Debug {(InterOp.get_debug_controls() ? "enabled" : "disabled")}", toMessageLog: false); break; case "toggleCursorLock": Print($"Cursor Lock {(InterOp.toggle_cursorlock() ? "enabled" : "disabled")}", toMessageLog: false); break; case "binding1": PsuedoLocs.BINDING_ONE.OnCollect(); break; case "binding2": PsuedoLocs.BINDING_TWO.OnCollect(); break; case "binding3": PsuedoLocs.BINDING_THREE.OnCollect(); break; case "binding4": PsuedoLocs.BINDING_FOUR.OnCollect(); break; case "binding5": PsuedoLocs.BINDING_FIVE.OnCollect(); break; case "unlockSpoiers": if (SeedController.Settings.RaceMode) { return; // no cheat } UberSet.Bool(GameComplete, true); Print("spoiler unlocked", toMessageLog: false); break; case "tpCheat": if (SeedController.Settings.RaceMode) { return; // no cheat } tpCheatToggle = !tpCheatToggle; Print($"TPCheat {(tpCheatToggle ? "enabled" : "disabled")}", toMessageLog: false); break; case "warpCredits": if (UberGet.Bool(GameComplete)) { InterOp.start_credits(); } else { Print($"Credit warp not unlocked!", toMessageLog: false); } break; case "printCoords": var pos = InterOp.get_position(); Print($"{pos.X}, {pos.Y}", toMessageLog: false); break; case "nameSpoilerToggle": MapController.NameLabels = !MapController.NameLabels; Print($"Loc name labels {(MapController.NameLabels ? "enabled" : "disabled")}", toMessageLog: false); break; case "logicprovidertoggle": MapController.RustLogic = !MapController.RustLogic; Print($"Logic Provider: {(MapController.RustLogic ? "Rust" : "Java")}", toMessageLog: false); MapController.UpdateReachable(); break; default: Randomizer.Log($"Recieved unknown signal {signal}"); break; } }
public static void Tick() { var signal = Engine.ExecFunction("Tick"); if (signal != null && signal != "none") { Engine.SetVar("signal", "none"); switch (signal) { case "reload": if (FramesTillUnlockReload == 0) { FramesTillNextSend = 0; SeedController.ReadSeed(); Randomizer.Memory.OnInit(); if (Randomizer.Memory.GameState == Memory.GameState.Game) { PsuedoLocs.RELOAD_SEED.Pickup().Grant(); } FramesTillUnlockReload = 60; } break; case "lastPickup": FramesTillNextSend = 1; // the only reason this isn't = 0 is that spamming this could get really annoying MessageQueue.Enqueue(Last); break; case "hintMessage": HintsController.ShowHintMessage(); break; case "dev": Randomizer.Dev = !Randomizer.Dev; Randomizer.Log($"Dev: {Randomizer.Dev}"); break; case "exitapp": Environment.Exit(Environment.ExitCode); break; case "toggleDebug": Randomizer.Memory.Debug = !Randomizer.Memory.Debug; Print($"Debug {(Randomizer.Memory.Debug ? "enabled" : "disabled")}", toMessageLog: false); break; case "toggleCursorLock": Print($"Cursor Lock {(InterOp.toggle_cursorlock() ? "enabled" : "disabled")}", toMessageLog: false); break; case "test1": PsuedoLocs.BINDING_ONE.Pickup().Grant(); break; case "test2": PsuedoLocs.BINDING_TWO.Pickup().Grant(); break; case "test3": PsuedoLocs.BINDING_THREE.Pickup().Grant(); break; case "test4": Print("magic", 180, false); InterOp.magic_function(); break; case "test5": tpCheatToggle = !tpCheatToggle; Print($"TPCheat {(tpCheatToggle ? "enabled" : "disabled")}"); break; default: Randomizer.Log($"Recieved unknown signal {signal}"); break; } } FramesTillUnlockReload = Math.Max(0, FramesTillUnlockReload - 1); if (FramesTillNextSend > 0) { FramesTillNextSend--; } else { if (CanPrint) { Current = MessageQueue.Peek(); FramesTillNextSend = Current.Frames; try { InterOp.clear_visible_hints(); InterOp.display_hint(InterOp.Util.getIl2cppStringPointer(Current.Text), Current.Frames / 60f); if (IniFlag("LogOnPrint")) { Randomizer.Log($"Sending {Current.Text} for {Current.Frames} ({MessageQueue.Count} remaining in queue)", false); } MessageQueue.Dequeue(); } catch (Exception e) { Randomizer.Error("AHK.sendMsg", e, false); } } else { Current = null; } } }
public bool Met() { var value = InterOp.get_uber_state_value(Id.GroupID, Id.ID); return(Target.HasValue ? Target.Value >= value : value > 0); }
public static void UpdateReachableAsync(int sleepTime = 30) { try { Thread.Sleep(sleepTime); // wait to let values update if (Updating) { return; } Updating = true; var argsList = RustLogic ? new List <string> { "reach-check", // TODO maybe we won't pass these explicitly? since it's samefolder shit "--areas", $"\"{Randomizer.BasePath}areas.wotw\"", "--locations", $"\"{Randomizer.BasePath}loc_data.csv\"", "--uber-states", $"\"{Randomizer.BasePath}state_data.csv\"", } : new List <string> { "-jar", $"\"{Randomizer.BasePath}SeedGen.jar\" ", "ReachCheck" }; argsList.AddRange(new List <string> { $"\"{SeedController.SeedFile}\"", $"{InterOp.get_max_health()}", $"{Convert.ToInt32(10*InterOp.get_max_energy())}", $"{UberGet.value(6, 0).Int}", $"{InterOp.get_ore()}", $"{InterOp.get_experience()}", }); if (RustLogic) { argsList.AddRange(TrackedConds.Where(c => c.Met()).Select(t => $"u:{t.Id.GroupID},{t.Id.ID}")); } argsList.AddRange(SaveController.SkillsFound.Select((AbilityType at) => $"s:{(int)at}")); argsList.AddRange(Teleporter.TeleporterStates.Keys.Where(t => new Teleporter(t).Has()).Select(t => $"t:{(int)t}")); if (new QuestEvent(QuestEventType.Water).Has()) { argsList.Add("w:0"); } argsList.AddRange(TrackedShards.Where(sh => new Shard(sh).Has()).Select(t => $"sh:{(int)t}")); var proc = new System.Diagnostics.Process(); proc.StartInfo.FileName = RustLogic ? @"seedgen.exe" : @"java.exe"; proc.StartInfo.Arguments = String.Join(" ", argsList); proc.StartInfo.CreateNoWindow = true; proc.StartInfo.UseShellExecute = false; proc.StartInfo.RedirectStandardOutput = true; proc.StartInfo.RedirectStandardError = true; proc.StartInfo.WorkingDirectory = Randomizer.BasePath; proc.Start(); if (!proc.WaitForExit(10000)) { Randomizer.Warn("MapController.waitForProc", "timed out waiting for reach check", false); } Reachable.Clear(); var rawOutput = proc.StandardOutput.ReadToEnd(); if (rawOutput.Trim() != "") { foreach (var rawCond in rawOutput.Split(',')) { try { var frags = rawCond.Split('|'); var cond = new UberStateCondition(int.Parse(frags[0]), frags[1]); if (cond.Loc().Type == LocType.Shop) { if (cond.Met() || hintTypes.Contains(cond.Pickup().Type)) { continue; // bought it or it's a hint. Either way it's known to be non progression, so it does not show on the map } if (ShopSlot.Twillen.Any(e => e.State.Equals(cond.Id))) { Reachable.Add(new UberStateCondition(2, "20000")); } else if (ShopSlot.Opher.Any(e => e.State.Equals(cond.Id))) { Reachable.Add(new UberStateCondition(1, "20000")); } else if (ShopSlot.LupoStore.Any(e => e.State.Equals(cond.Id))) { Reachable.Add(new UberStateCondition(48248, "20000")); } } Reachable.Add(cond); } catch (Exception e) { Randomizer.Error($"GetReachableAsync (post-return) while parsing |{rawCond}|", e); } } } /* * if(Randomizer.Dev) * Randomizer.Log($"Reach check:\nseed_gen_cli.exe {String.Join(" ", argsList)}\n gave output: \n{rawOutput}\n stderr was {proc.StandardError.ReadToEnd()}\nReachable after: {String.Join(" ", Reachable.Select(r => r.ToString()))}", false); */ InterOp.refresh_inlogic_filter(); } catch (Exception e) { Randomizer.Error("GetReachableAsync", e); } Updating = false; }
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 HandleSyncedUberStateChange(UberId id, float value) { InterOp.set_uber_state_value(id.GroupID, id.ID, value); }
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); } }