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;
        }
Esempio n. 2
0
        public static void OnKill(string name, DamageType dt)
        {
            name = name.Replace("(Clone)", "");
            var et = EnemyFromName(name);

            if (et == EnemyType.Unknown && Randomizer.Dev)
            {
                Randomizer.Log($"Unknown Enemy {name}");
            }
            UberInc.Int(10, 10); // enemies killed
            switch (et)
            {
            case EnemyType.Miner:
            case EnemyType.ShieldMiner:
                UberInc.Int(10, 40);
                break;

            case EnemyType.Skeeto:
            case EnemyType.SmallSkeeto:
            case EnemyType.Bee:
                UberInc.Int(10, 41);
                break;

            case EnemyType.Tentacle:
                UberInc.Int(10, 42);
                break;

            case EnemyType.DropSlime:
            case EnemyType.ShellSlime:
            case EnemyType.Slime:
            case EnemyType.SpikeSlime:
                UberInc.Int(10, 43);
                break;

            case EnemyType.Fish:
            case EnemyType.Waterworm:
                UberInc.Int(10, 44);
                break;

            case EnemyType.Balloon:
            case EnemyType.Baneling:
                UberInc.Int(10, 45);
                break;

            case EnemyType.Scourge: // is both a flier and explosive
                UberInc.Int(10, 41);
                UberInc.Int(10, 45);
                break;

            case EnemyType.BombSlime: // is both a slime and explosive
                UberInc.Int(10, 43);
                UberInc.Int(10, 45);
                break;

            default:
                break;
            }
            switch (dt)
            {
            case DamageType.Sword:
                UberInc.Int(10, 11);
                break;

            case DamageType.Hammer:
                UberInc.Int(10, 12);
                break;

            case DamageType.Bow:
                UberInc.Int(10, 13);
                break;

            case DamageType.SpiritSpear:
                UberInc.Int(10, 14);
                break;

            case DamageType.SpiritSentry:
                UberInc.Int(10, 15);
                break;

            case DamageType.Blaze:
                UberInc.Int(10, 16);
                break;

            case DamageType.Grenade:
                UberInc.Int(10, 17);
                break;

            case DamageType.Heat:
                UberInc.Int(10, 18);
                break;

            case DamageType.Chakram:
                UberInc.Int(10, 19);
                break;

            case DamageType.ChargeJump:
                UberInc.Int(10, 20);
                break;

            case DamageType.Glow:
                UberInc.Int(10, 21);
                break;

            case DamageType.Projectile:
                UberInc.Int(10, 22);
                break;

            case DamageType.Water:
                UberInc.Int(10, 23);
                break;

            default:
                break;
            }
        }
        public static void UpdateReachableAsync(int sleepTime = 30)
        {
            try {
                Thread.Sleep(sleepTime); // wait to let values update
                if (Updating)
                {
                    return;
                }
                Updating = true;
                var argsList = new List <string> {
                    "-jar",
                    $"{Randomizer.BasePath}SeedGen.jar ",
                    "ReachCheck",
                    $"\"{SeedController.SeedFile}\"",
                    $"{InterOp.get_max_health()}",
                    $"{Convert.ToInt32(10*InterOp.get_max_energy())}",
                    $"{UberGet.value(6, 0).Int}",
                    $"{InterOp.get_ore()}",
                    $"{InterOp.get_experience()}",
                };
                // ^ this should probably be an array at this point...
                // TODO: send which key doors are already open
                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");
                }
                var proc = new System.Diagnostics.Process();
                proc.StartInfo.FileName               = @"java.exe";
                proc.StartInfo.Arguments              = String.Join(" ", argsList);
                proc.StartInfo.CreateNoWindow         = true;
                proc.StartInfo.UseShellExecute        = false;
                proc.StartInfo.RedirectStandardOutput = true;
                proc.StartInfo.WorkingDirectory       = Randomizer.BasePath;
                proc.Start();
                if (!proc.WaitForExit(7500))
                {
                    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]);
                            Reachable.Add(cond);
                        }
                        catch (Exception e) { Randomizer.Error($"GetReachableAsync (post-return) while parsing |{rawCond}|", e); }
                    }
                }
//        else
//          Randomizer.Log($"got output |{rawOutput}| from cmd. args: \"{String.Join(" ", argsList)}\" stderr was {proc.StandardError.ReadToEnd()}", false);
                InterOp.refresh_inlogic_filter();
            }
            catch (Exception e) { Randomizer.Error("GetReachableAsync", e); }
            Updating = false;
        }
        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)
                    {
                        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 "hintMessage":
                    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 "test1":
                    PsuedoLocs.BINDING_ONE.OnCollect();
                    break;

                case "test2":
                    PsuedoLocs.BINDING_TWO.OnCollect();
                    break;

                case "test3":
                    PsuedoLocs.BINDING_THREE.OnCollect();
                    break;

                case "test4":
                    if (SeedController.HasInternalSpoilers)
                    {
                        UberSet.Bool(34543, 11226, true);
                        Print("spoiler unlocked", toMessageLog: false);
                    }
                    break;

                case "test5":
                    tpCheatToggle = !tpCheatToggle;
                    Print($"TPCheat {(tpCheatToggle ? "enabled" : "disabled")}", 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;

                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(Current.Text, Current.Frames / 60f, Current.Pos);
                        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 NewGameInit()
        {
            if (!InterOp.is_loading_game())
            {
                InterOp.clear_quest_messages();
                Randomizer.Log("New Game Init", false);

                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.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.save();

                NeedsNewGameInit = false;
            }
        }
        public static void ResolveUberStateChange(UberState state, UberValue old)
        {
            try {
                UberId key = state.GetUberId();
                if (!UberStates.TryGetValue(key, out UberState oldState))
                {
                    oldState       = state.Clone();
                    oldState.Value = old;
                    UberStates.Add(key, oldState);
                }

                UberValue value = state.Value;
                if (value.Int == old.Int)
                {
                    return;
                }

                var oldValFmt = old.FmtVal(state.Type); // get this now because we overwrite the value by reference
                if (ShouldRevert(state))
                {
                    Randomizer.Log($"Reverting state change of {state.Name} from {oldValFmt} to {state.FmtVal()}", false);
                    oldState.Write();
                    return;
                }

                HandleSpecial(state);
                UberStates[key].Value = state.Value;
                var  pos   = InterOp.get_position();
                bool found = false;
                if (value.Int > 0)
                {
                    var id = state.GetUberId();
                    if (SkipUberStateMapCount.GetOrElse(key, 0) > 0)
                    {
                        var p = id.toCond().Pickup().Concat(id.toCond(state.ValueAsInt()).Pickup());
                        if (p.NonEmpty)
                        {
                            SkipUberStateMapCount[key] -= 1;
                            Randomizer.Log($"Suppressed granting {p} from {id}={state.ValueAsInt()}. Will suppress {SkipUberStateMapCount[key]} more times", false, "DEBUG");
                            return;
                        }
                    }
                    found = SeedController.OnUberState(state);
                    if (!found)
                    {
                        HintsController.OnLupoState(id);
                    }
                }

                if (SyncedUberStates.Contains(key))
                {
                    Randomizer.Client.SendUpdate(key, state.ValueAsFloat());
                }

                BonusItemController.OnUberState(state);
                var zone = ZoneType.Void;
                if (InterOp.get_game_state() == GameState.Game)
                {
                    zone = InterOp.get_player_area().toZone();
                }
                if ((value.Int == 0 || !found) && !(state.GroupName == "statsUberStateGroup" || state.GroupName == "achievementsGroup" || state.GroupID == 8 || state.GroupID == 10))
                {
                    Randomizer.Debug($"State change: {state.GroupName}.{state.Name} ({state.GroupID}|{state.ID}) {state.Type} {oldValFmt}->{state.FmtVal()} at ({Math.Round(pos.X)}, {Math.Round(pos.Y)}) in {zone}");
                }
                //Randomizer.Debug($"{state.GroupName}.{state.Name}, {state.GroupID}, {state.ID}, {state.Type}, {oldValFmt}, {state.FmtVal()}, {zone}, {Math.Round(pos.X)},{Math.Round(pos.Y)}");
            }
            catch (Exception e) {
                Randomizer.Error($"USC.Update {state}", e);
            }
        }