コード例 #1
0
        /// <summary>
        /// Writes all reachable modules and their (randomized) edges to the console for debugging purposes.
        /// </summary>
        public void WriteReachableToConsole()
        {
            foreach (var vertex in Reachable.Where(kvp => kvp.Value == true))
            {
                if (!Modules.Any(v => v.WarpCode == vertex.Key))
                {
                    continue;
                }
                var module = Modules.Find(v => v.WarpCode == vertex.Key);

                StringBuilder sb = new StringBuilder();
                sb.Append($"{module.WarpCode}");

                if (module.Tags.Count > 0)
                {
                    sb.Append($" [{module.Tags.Aggregate((i, j) => $"{i},{j}")}]");
                }

                if (!string.IsNullOrWhiteSpace(module.LockedTag))
                {
                    sb.Append($" -[{module.LockedTag}]-");
                }

                if (module.Unlock.Count > 0)
                {
                    sb.Append($" =[{module.Unlock.Aggregate((i, j) => $"{i},{j}")}]=");
                }

                sb.AppendLine();

                foreach (var edge in module.LeadsTo)
                {
                    sb.Append($"-> {edge.WarpCode} ({RandomLookup[edge.WarpCode]})");

                    if (edge.Tags.Count > 0)
                    {
                        sb.Append($" [{edge.Tags.Aggregate((i, j) => $"{i},{j}")}]");
                    }

                    if (edge.UnlockSets.Count > 0)
                    {
                        sb.Append(" =[");
                        foreach (var set in edge.UnlockSets)
                        {
                            sb.Append($"{set.Aggregate((i, j) => $"{i},{j}")};");
                        }
                        sb.Append("]=");
                    }

                    sb.AppendLine();
                }

                Console.Write(sb.ToString());
            }
        }
コード例 #2
0
ファイル: Hero.cs プロジェクト: Neasiac/RoguelikeEva
        bool CheckMovementInitialization()
        {
            if (Selected && // we're selected
                Player.SelectedNode != null && // player has clicked on a map node
                (Player.SelectedNode.OccupiedBy == null || Player.SelectedNode.OccupiedBy.GetComponent <Hero>() == null) && // the map node is not occupied by an allied unit
                Reachable != null && Reachable.Contains(Player.SelectedNode))    // destination tile is reachable
            {
                // action upon completion
                Path.PathAction action;
                if (Player.SelectedNode.OccupiedBy == null)
                {
                    action = Path.PathAction.Move;
                }
                else if (Player.SelectedNode.OccupiedBy.GetComponent <Monster>() != null)
                {
                    action = Path.PathAction.Attack;
                }
                else
                {
                    action = Path.PathAction.Use;
                }

                // if we're attacking, check whether we still can
                if (action == Path.PathAction.Attack)
                {
                    if (AlreadyAttacked)
                    {
                        return(false);
                    }

                    AlreadyAttacked = true;
                }

                // forbid user interaction while moving
                Player.InvalidateSelection();
                Player.Mode = Player.PlayerMode.Waiting;
                Player.InvalidateHighlight(Reachable);

                // initilize movement
                AStarPathFinder pf = new AStarPathFinder(action);
                Path            = pf.Find(Tile, Player.SelectedNode);
                Tile.OccupiedBy = null;
                Tile            = null;

                return(true);
            }

            return(false);
        }
コード例 #3
0
        /// <summary>
        /// Begin the reachability search.
        /// </summary>
        public void CheckReachability()
        {
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            // Reset objects needed for reachability testing.
            Reachable = Modules.ToDictionary(m => m.WarpCode, b => false);
            OnceQueue.Clear();

            // Check reachability again to find unlocked edges.
            CheckReachabilityDFS(Reachable);

            // Continue to check to find newly unlocked edges, until none are unlocked.
            do
            {
                ReachableUpdated = false;
                var touched = Reachable.ToDictionary(kvp => kvp.Key, kvp => false);
                CheckReachabilityDFS(touched);
            } while (ReachableUpdated);

            Console.WriteLine($" > Time used to create digraph and check reachability...{sw.Elapsed}");
        }
コード例 #4
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public AttributeClassBuilder(Reachable.ReachableContext context, AssemblyCompiler compiler, TypeDefinition typeDef)
     : base(context, compiler, typeDef)
 {
 }
コード例 #5
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public EnumInfoClassBuilder(Reachable.ReachableContext context, AssemblyCompiler compiler, TypeDefinition typeDef, EnumClassBuilder enumClassBuilder)
     : base(context, compiler, typeDef)
 {
     this.enumClassBuilder = enumClassBuilder;
 }
コード例 #6
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public NullableEnumBaseClassBuilder(Reachable.ReachableContext context, AssemblyCompiler compiler, TypeDefinition typeDef)
     : base(context, compiler, typeDef)
 {
 }
コード例 #7
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;
        }
コード例 #8
0
 public static bool FilterIconShow(int groupId, int id, int value) => Reachable.Contains(new UberStateCondition(groupId, id, value));
コード例 #9
0
        /// <summary>
        /// If the edge contains the Locked tag it should be skipped unless an enabled fix or glitch is also tagged or
        /// if all of the edge's unlocks are reachable.
        /// </summary>
        /// <param name="edge">Edge to check.</param>
        /// <returns>True if the edge can be skipped.</returns>
        private bool IsLockedEdge(ModuleEdge edge)
        {
            bool isLocked = false;

            if (edge.IsLocked)
            {
                // Check to see if we can bypass this lock with an allowed glitch or enabled fix.
                if ((AllowGlitchClip && edge.IsClip) ||
                    (AllowGlitchDlz && edge.IsDlz) ||
                    (AllowGlitchFlu && edge.IsFlu) ||                       // How to handle FluReq? One FLU still requires Carth...
                    (AllowGlitchGpw && edge.IsGpw) ||
                    (EnabledFixBox && edge.IsFixBox) ||
                    (EnabledFixElev && edge.IsFixElev) ||
                    (EnabledFixMap && edge.IsFixMap) ||
                    (EnabledFixSpice && edge.IsFixSpice) ||
                    (EnabledUnlockDanRuins && edge.IsUnlockDanRuins) ||
                    (EnabledUnlockManSub && edge.IsUnlockManSub) ||
                    (EnabledUnlockStaBastila && edge.IsUnlockStaBastila) ||
                    (EnabledUnlockUnkSummit && edge.IsUnlockUnkSummit))
                {
                    isLocked = false;
                }
                else
                {
                    // Check to see if the edge can be unlocked by any of the possible sets.
                    var unlocked = true;
                    foreach (var set in edge.UnlockSets)
                    {
                        // Reset assumption to true, as we're just looking for one false in each set.
                        unlocked = true;

                        // ALL vertices within a set need to be reachable.
                        foreach (var target in set)
                        {
                            // If the tag is not in Reachable, then it's a one that we haven't seen and the edge is still locked.
                            if (!Reachable.ContainsKey(target))
                            {
                                Reachable.Add(target, false);
                                unlocked = false;
                                break;
                            }

                            // If not Reachable, then the edge is still locked.
                            if (!Reachable[target])
                            {
                                unlocked = false;
                                break;
                            }
                        }

                        // If a reachable set has been found, break out of the loop.
                        if (unlocked)
                        {
                            break;
                        }
                    }

                    // Set return value.
                    isLocked = !unlocked;
                }
            }
            else
            {
                // Edge isn't locked.
                isLocked = false;
            }
            return(isLocked);
        }
コード例 #10
0
        /// <summary>
        /// Recursive method to perform Depth-First Search reachability checking.
        /// </summary>
        /// <param name="touched">Dictionary indicating if each module has been checked during this cycle.</param>
        /// <param name="v">The current module to check.</param>
        private void DepthFirstSearch(Dictionary <string, bool> touched, ModuleVertex v)
        {
            // This module has been reached, so assume reachable.
            touched[v.WarpCode] = true;
            if (touched[v.WarpCode] != Reachable[v.WarpCode])
            {
                ReachableUpdated      = true;
                Reachable[v.WarpCode] = true;
            }

            // Any tags associated with this vertex are also reachable.
            foreach (var t in v.Tags)
            {
                if (!Reachable.ContainsKey(t))
                {
                    Reachable.Add(t, true);
                }
                else
                {
                    Reachable[t] = true;
                }
            }

            // Check to see if the locked tag is reachable too.
            if (!string.IsNullOrWhiteSpace(v.LockedTag))
            {
                var isUnlocked = true;

                // If ALL tags are reachable, this tag is also reachable.
                foreach (var ul in v.Unlock)
                {
                    if (Reachable.ContainsKey(ul) && Reachable[ul])
                    {
                        isUnlocked = true;
                    }
                    else
                    {
                        isUnlocked = false;
                        break;
                    }
                }

                if (!Reachable.ContainsKey(v.LockedTag))
                {
                    Reachable.Add(v.LockedTag, isUnlocked);
                }
                else
                {
                    Reachable[v.LockedTag] = isUnlocked;
                }
            }

            // Check each edge that hasn't been reached already.
            foreach (var edge in v.LeadsTo)
            {
                // If this is a once edge, determine how to handle it.
                if (IsOnceEdge(edge))
                {
                    // Ignore once edges if setting is enabled.
                    if (!IgnoreOnceEdges)
                    {
                        // If allowed, enqueue the once edge for checking at the end of this cycle.
                        if (!Reachable[RandomLookup[edge.WarpCode]] && !OnceQueue.Contains(edge))
                        {
                            OnceQueue.Enqueue(edge);
                            ReachableUpdated = true;
                        }
                    }
                    continue;
                }
                // If this is a locked edge, determine if it is still locked.
                if (EnforceEdgeTagLocked && IsLockedEdge(edge))
                {
                    continue;
                }
                if (!touched[RandomLookup[edge.WarpCode]])
                {
                    DepthFirstSearch(touched, Modules.Find(m => m.WarpCode == RandomLookup[edge.WarpCode]));
                }
            }
        }
コード例 #11
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public AndroidAppApplicationDerivedBuilder(Reachable.ReachableContext context, AssemblyCompiler compiler, TypeDefinition typeDef)
     : base(context, compiler, typeDef)
 {
     if (IsDot42InternalApplication())
         Dot42InternalApplicationBuilder = this;
 }
コード例 #12
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public NullableMarkerClassBuilder(Reachable.ReachableContext context, AssemblyCompiler compiler, TypeDefinition typeDef, ClassBuilder underlyingBuilder)
     : base(context, compiler, typeDef)
 {
     _underlyingBuilder = underlyingBuilder;
 }
コード例 #13
0
        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;
        }