Beispiel #1
0
 public JediComponent()
 {
     memory          = new JediMemory();
     settings        = new JediSettings();
     control         = new JediMasterControl();
     splitCollection = new SplitCollection();
 }
        /// <summary>
        /// Constructs the class. This constructor is useful for saving settings.
        /// </summary>
        public EndIsNighSettings(SplitCollection splitCollection, SplitCollectionControl collectionControl,
                                 SettingsControl settingsControl)
        {
            this.settingsControl   = settingsControl;
            this.splitCollection   = splitCollection;
            this.collectionControl = collectionControl;

            settingsControl.Settings = this;
        }
Beispiel #3
0
        /// <summary>
        /// Constructs the component.
        /// </summary>
        public EndIsNighComponent()
        {
            memory = new EndIsNighMemory();

            dataClasses = new AutosplitDataClass[]
            {
                new MapGrid(memory),
                new TumorCollection(memory),
                new BodyPartCollection(memory),
                new CartridgeCollection(memory),
                new WorldEventCollection(memory),
            };

            splitCollection = new SplitCollection(this, dataClasses);
            settingsControl = new EndIsNighControl();
            settingsControl.CollectionControl.SplitCollection = splitCollection;
            settings = new EndIsNighSettings(splitCollection, settingsControl.CollectionControl, settingsControl.SettingsControl);

            textComponent = new InfoTextComponent("Death Count", "0")
            {
                LongestString = int.MaxValue.ToString()
            };
        }
Beispiel #4
0
        /// <summary>
        /// Perform an intersection operation between two islands using a reflow strategy.
        /// </summary>
        /// <param name="dst">The destination of where the intersected path will be placed.</param>
        /// <param name="islandSegsA">A list of all the nodes in island A.</param>
        /// <param name="islandSegsB">A list of all the nodes in island B.</param>
        /// <param name="onIslA">If the islands were processed, this output parameter contains a node
        /// on the new shape.</param>
        /// <returns>The results from the operation.</returns>
        /// <remarks>islandSegsA and islandSegsB should only contain elements in the island, and should not
        /// be confused with all nodes in the parent loop.</remarks>
        public static BoundingMode Intersection(
            BLoop dst,
            List <BNode> islandSegsA,
            List <BNode> islandSegsB,
            out BNode onIslA)
        {
            // For the intersection, if there's ANY geometry return, it's a copy.
            // It's expected after this operation that the original islands will
            // be destroyed and only the copies will be left.

            float leftWinding  = BNode.CalculateWinding(islandSegsA[0].Travel());
            float rightWinding = BNode.CalculateWinding(islandSegsB[0].Travel());

            if (leftWinding > 0.0f != rightWinding > 0.0f)
            {
                islandSegsB[0].ReverseChainOrder();
            }

            onIslA = null;

            List <Utils.BezierSubdivSample> delCollisions = new List <Utils.BezierSubdivSample>();

            GetLoopCollisionInfo(islandSegsA, islandSegsB, delCollisions);
            Utils.BezierSubdivSample.CleanIntersectionList(delCollisions);

            if (delCollisions.Count == 0)
            {
                BoundingMode bm = GetLoopBoundingMode(islandSegsA, islandSegsB);

                if (bm == BoundingMode.NoCollision)
                {
                    return(BoundingMode.NoCollision);
                }
                else if (bm == BoundingMode.RightSurroundsLeft)
                {
                    // If the right is fully surrounded, the right is kept.
                    Dictionary <BNode, BNode> insertCloneMap = BNode.CloneNodes(islandSegsA, false);
                    foreach (BNode bn in insertCloneMap.Values)
                    {
                        onIslA = bn;
                        bn.SetParent(dst);
                    }

                    onIslA = islandSegsA[0];
                    return(BoundingMode.RightSurroundsLeft);
                }
                else if (bm == BoundingMode.LeftSurroundsRight)
                {
                    // If the left is fully surrounded, the left is kept.
                    Dictionary <BNode, BNode> insertCloneMap = BNode.CloneNodes(islandSegsB, false);
                    foreach (BNode bn in insertCloneMap.Values)
                    {
                        onIslA = bn;
                        bn.SetParent(dst);
                    }

                    onIslA = islandSegsA[0];
                    return(BoundingMode.LeftSurroundsRight);
                }
            }

            // Make copies of both, remap and keep their intersection.
            Dictionary <BNode, BNode> cloneMapA = BNode.CloneNodes(islandSegsA, false);
            Dictionary <BNode, BNode> cloneMapB = BNode.CloneNodes(islandSegsB, false);

            foreach (BNode bn in cloneMapA.Values)
            {
                bn.SetParent(dst);
            }

            foreach (BNode bn in cloneMapB.Values)
            {
                bn.SetParent(dst);
            }

            for (int i = 0; i < delCollisions.Count; ++i)
            {
                Utils.BezierSubdivSample bss = delCollisions[i];

                bss.a.node = cloneMapA[bss.a.node];
                bss.b.node = cloneMapB[bss.b.node];


                delCollisions[i] = bss;
            }

            Dictionary <Utils.NodeTPos, BNode.SubdivideInfo> colSlideInfo = SliceCollisionInfo(delCollisions);
            Dictionary <Utils.NodeTPos, BNode> createdSubdivs             = new Dictionary <Utils.NodeTPos, BNode>();
            SplitCollection splitCol = new SplitCollection(dst, delCollisions, createdSubdivs);

            //left.nodes.Clear();
            //foreach(BNode bn in islandSegsA)
            //    bn.SetParent(null, false);
            //
            ////right.DumpInto(dst); // Move everything in from the other loop
            foreach (BNode bn in islandSegsB)
            {
                bn.SetParent(dst, false);
            }

            HashSet <BNode> looseEnds = new HashSet <BNode>();

            foreach (Utils.BezierSubdivSample bss in delCollisions)
            {
                BNode.SubdivideInfo sdiA = colSlideInfo[bss.GetTPosA()];
                BNode.SubdivideInfo sdiB = colSlideInfo[bss.GetTPosB()];
                float wind    = Utils.Vector2Cross(sdiA.subOut, sdiB.subOut);
                BNode colNode = createdSubdivs[bss.GetTPosA()];
                onIslA = colNode;

                if (wind < 0.0f != leftWinding < 0.0f)
                {
                    BNode nA = splitCol.GetNextTo(bss.GetTPosA());
                    BNode nB = splitCol.GetPreviousTo(bss.GetTPosB());

                    nA.TanIn  = sdiA.nextIn;
                    nB.TanOut = sdiB.prevOut;

                    colNode.UseTanIn  = bss.b.node.IsLine() == false;
                    colNode.UseTanOut = bss.a.node.IsLine() == false;
                    colNode.TanIn     = sdiB.subIn;
                    colNode.TanOut    = sdiA.subOut;

                    nB.next      = colNode;
                    colNode.prev = nB;
                    nA.prev      = colNode;
                    colNode.next = nA;

                    looseEnds.Add(bss.a.node);
                    looseEnds.Add(splitCol.GetSplitInfo(bss.b.node).origNext);
                }
                else
                {
                    BNode nA = splitCol.GetPreviousTo(bss.GetTPosA());
                    BNode nB = splitCol.GetNextTo(bss.GetTPosB());

                    nA.TanOut = sdiA.prevOut;
                    nB.TanIn  = sdiB.nextIn;

                    colNode.UseTanIn  = bss.a.node.IsLine() == false;
                    colNode.UseTanOut = bss.b.node.IsLine() == false;
                    colNode.TanIn     = sdiA.subIn;
                    colNode.TanOut    = sdiB.subOut;

                    nA.next      = colNode;
                    colNode.prev = nA;
                    nB.prev      = colNode;
                    colNode.next = nB;

                    looseEnds.Add(splitCol.GetSplitInfo(bss.a.node).origNext);
                    looseEnds.Add(bss.b.node);
                }
            }

            // Figure out what internal items need to be removed by
            // checking which nodes have unmatching connectivity.
            ClipLooseEnds(looseEnds);
            return(BoundingMode.Collision);
        }
Beispiel #5
0
        /// <summary>
        /// Perform a difference operation between two islands using a reflow strategy.
        /// </summary>
        /// <param name="dstloop">The destination of where the differenced path will be placed.</param>
        /// <param name="islandSegsA">A list of all the nodes in island A.</param>
        /// <param name="islandSegsB">A list of all the nodes in island B.</param>
        /// <param name="onIslA">A node on the resulting path.</param>
        /// <param name="processFullOverlaps">If true, check and handle is one of the parameter islands
        /// completly wraps around the other island.</param>
        /// <returns>The results from the operation.</returns>
        /// <remarks>islandSegsA and islandSegsB should only contain elements in the island, and should not
        /// be confused with all nodes in the parent loop.</remarks>
        public static BoundingMode Difference(BLoop dstloop, List <BNode> islandSegsA, List <BNode> islandSegsB, out BNode onIslA, bool processFullOverlaps)
        {
            // If there is any interaction, a copy of islandB is made and used - this means
            // if islandB should be removed, it is up to the caller to remove it themselves.
            //
            // This is done because we don't know if the shape being subtracted is part of a
            // bigger operation where it's subtracted against multiple islands for multi-island
            // loop subtraction, or shape subtraction.

            float leftWind  = BNode.CalculateWinding(islandSegsA[0].Travel());
            float rightWind = BNode.CalculateWinding(islandSegsB[0].Travel());

            // They need to have opposite windings.
            if (leftWind > 0.0f == rightWind > 0.0f)
            {
                islandSegsB[0].ReverseChainOrder();
            }


            List <Utils.BezierSubdivSample> delCollisions = new List <Utils.BezierSubdivSample>();

            GetLoopCollisionInfo(islandSegsA, islandSegsB, delCollisions);
            Utils.BezierSubdivSample.CleanIntersectionList(delCollisions);

            onIslA = null;

            // If we have an odd number of collisions, we have a problem because we have
            // any entry without an exit which will lead to corrupt topology. For now we
            // don't have a way to resolve that, but at least we can exit on 1 without
            // causing issues (in theory at least).
            if (delCollisions.Count == 1)
            {
                return(BoundingMode.NoCollision);
            }

            if (delCollisions.Count == 0)
            {
                BoundingMode bm = GetLoopBoundingMode(islandSegsA, islandSegsB);

                if (processFullOverlaps == false)
                {
                    onIslA = islandSegsA[0];
                    return(bm);
                }

                if (bm == BoundingMode.NoCollision)
                {
                    onIslA = islandSegsA[0];
                    return(BoundingMode.NoCollision);
                }
                else if (bm == BoundingMode.RightSurroundsLeft)
                {
                    // Everything was subtracted out
                    foreach (BNode bn in islandSegsA)
                    {
                        onIslA = bn;
                        bn.SetParent(null);
                    }

                    return(BoundingMode.RightSurroundsLeft);
                }
                else if (bm == BoundingMode.LeftSurroundsRight)
                {
                    // Leave the reverse winding inside as a hollow cavity - and
                    // nothing needs to be changed.
                    Dictionary <BNode, BNode> insertCloneMap = BNode.CloneNodes(islandSegsB, false);
                    foreach (BNode bn in insertCloneMap.Values)
                    {
                        bn.SetParent(dstloop);
                    }

                    onIslA = islandSegsA[0];

                    return(BoundingMode.LeftSurroundsRight);
                }
            }

            // Make sure we have no overlaps of intersections. We currently
            // can't handle such things.
            HashSet <Utils.NodeTPos> intersections = new HashSet <Utils.NodeTPos>();

            foreach (Utils.BezierSubdivSample bss in delCollisions)
            {
                if (intersections.Add(bss.a.TPos()) == false)
                {
                    return(BoundingMode.Degenerate);
                }

                if (intersections.Add(bss.b.TPos()) == false)
                {
                    return(BoundingMode.Degenerate);
                }
            }

            // Add everything in the copy in. We'll clip loose ends later to get
            // rid of the trash.
            Dictionary <BNode, BNode> cloneMap = BNode.CloneNodes(islandSegsB, false);

            foreach (BNode bn in cloneMap.Values)
            {
                bn.SetParent(dstloop);
            }

            // Well, if we're going to make a copy in its place, that means we need to remap
            // all references...
            for (int i = 0; i < delCollisions.Count; ++i)
            {
                Utils.BezierSubdivSample bss = delCollisions[i];
                bss.b.node       = cloneMap[bss.b.node];
                delCollisions[i] = bss;
            }

            Dictionary <Utils.NodeTPos, BNode.SubdivideInfo> colSlideInfo = SliceCollisionInfo(delCollisions);
            Dictionary <Utils.NodeTPos, BNode> createdSubdivs             = new Dictionary <Utils.NodeTPos, BNode>();
            SplitCollection splitCol = new SplitCollection(dstloop, delCollisions, createdSubdivs);

            HashSet <BNode> looseEnds = new HashSet <BNode>();

            // Note that nothing from B will be tagged as a loose end. Instead, we're
            // forcing the entire island of B to be removed after the Per-Island
            // processing.
            foreach (Utils.BezierSubdivSample bss in delCollisions)
            {
                BNode.SubdivideInfo sdiA = colSlideInfo[bss.GetTPosA()];
                BNode.SubdivideInfo sdiB = colSlideInfo[bss.GetTPosB()];
                float wind    = Utils.Vector2Cross(sdiA.subOut, sdiB.subOut);
                BNode colNode = createdSubdivs[bss.GetTPosA()];
                onIslA = colNode;

                if (leftWind > 0 == wind > 0.0f)
                {
                    // A CCW transition will go from A to B.
                    BNode nA = splitCol.GetPreviousTo(bss.GetTPosA());
                    BNode nB = splitCol.GetNextTo(bss.GetTPosB());

                    nA.TanOut = sdiA.prevOut;
                    nB.TanIn  = sdiB.nextIn;

                    colNode.UseTanIn  = bss.a.node.IsLine() == false;
                    colNode.UseTanOut = bss.b.node.IsLine() == false;
                    colNode.TanIn     = sdiA.subIn;
                    colNode.TanOut    = sdiB.subOut;

                    nA.next      = colNode;
                    colNode.prev = nA;
                    nB.prev      = colNode;
                    colNode.next = nB;

                    looseEnds.Add(bss.b.node);
                    looseEnds.Add(bss.a.node.next);
                }
                else
                {
                    // A CW transition will go from the other to it.
                    BNode nA = splitCol.GetNextTo(bss.GetTPosA());
                    BNode nB = splitCol.GetPreviousTo(bss.GetTPosB());

                    nA.TanIn  = sdiA.nextIn;
                    nB.TanOut = sdiB.prevOut;

                    colNode.UseTanIn  = bss.b.node.IsLine() == false;
                    colNode.UseTanOut = bss.a.node.IsLine() == false;
                    colNode.TanIn     = sdiB.subIn;
                    colNode.TanOut    = sdiA.subOut;

                    nB.next      = colNode;
                    colNode.prev = nB;
                    nA.prev      = colNode;
                    colNode.next = nA;

                    looseEnds.Add(bss.b.node.next);
                    looseEnds.Add(bss.a.node);
                }
            }

            // Figure out what internal items need to be removed by
            // checking which nodes have unmatching connectivity.
            ClipLooseEnds(looseEnds);

            return(BoundingMode.Collision);
        }
Beispiel #6
0
        /// <summary>
        /// Perform a union operation between two islands using a reflow strategy.
        /// </summary>
        /// <param name="dst">The destination of where the conjoined path will be placed.</param>
        /// <param name="islandSegsA">A list of all the nodes in island A. </param>
        /// <param name="islandSegsB">A list of all the nodes in island B.</param>
        /// <param name="onIslA">If the islands were processed, this output parameter contains a node
        /// on the new shape.</param>
        /// <param name="mergeNonCol">If true, other parts that didn't collide (and weren't merged) will be
        /// moved into the final output destination (dst).</param>
        /// <returns>The results from the operation.</returns>
        /// <remarks>islandSegsA and islandSegsB should only contain elements in the island, and should not
        /// be confused with all nodes in the parent loop.</remarks>
        public static BoundingMode Union(BLoop dst, List <BNode> islandSegsA, List <BNode> islandSegsB, out BNode onIslA, bool mergeNonCol)
        {
            float leftWind  = BNode.CalculateWinding(islandSegsA[0].Travel());
            float rightWind = BNode.CalculateWinding(islandSegsB[0].Travel());

            onIslA = islandSegsA[0];

            // It can be either winding, but they must be the same - since islandB is going to be used up in the process,
            // we'll modify that winding to keep islandA the same.
            if (leftWind > 0 != rightWind > 0)
            {
                islandSegsB[0].ReverseChainOrder();
            }

            List <Utils.BezierSubdivSample> delCollisions = new List <Utils.BezierSubdivSample>();

            GetLoopCollisionInfo(islandSegsA, islandSegsB, delCollisions);
            Utils.BezierSubdivSample.CleanIntersectionList(delCollisions);

            // If we didn't find any collisions, it's either because they don't overlap
            // at all, or one island fully wraps around another island.
            if (delCollisions.Count == 0)
            {
                BoundingMode bm = GetLoopBoundingMode(islandSegsA, islandSegsB);

                // If an island is completely surrounded by another island, one of the
                // islands gets "smothered out of existence."
                if (bm == BoundingMode.LeftSurroundsRight)
                {
                    // Just remember everything from the right out of existence.
                    foreach (BNode bn in islandSegsB)
                    {
                        bn.SetParent(null);
                    }

                    return(BoundingMode.LeftSurroundsRight);
                }
                else if (bm == BoundingMode.RightSurroundsLeft)
                {
                    // Remove everything from the left out of existence, and
                    // move everything from the right island into the left;
                    foreach (BNode bn in islandSegsA)
                    {
                        bn.SetParent(null, false);
                    }

                    foreach (BNode bn in islandSegsB)
                    {
                        onIslA = bn;
                        bn.SetParent(dst, false);
                    }

                    return(BoundingMode.RightSurroundsLeft);
                }

                if (mergeNonCol == true)
                {
                    foreach (BNode bn in islandSegsB)
                    {
                        bn.SetParent(dst, false);
                    }
                }

                return(BoundingMode.NoCollision);
            }

            // Dump B into A, and if there's anything straggling,
            // we'll clip it as a loose end afterwards.
            foreach (BNode bn in islandSegsB)
            {
                bn.SetParent(dst, false);
            }

            Dictionary <Utils.NodeTPos, BNode.SubdivideInfo> colSlideInfo = SliceCollisionInfo(delCollisions);

            Dictionary <Utils.NodeTPos, BNode> createdSubdivs = new Dictionary <Utils.NodeTPos, BNode>();
            SplitCollection splitCol = new SplitCollection(dst, delCollisions, createdSubdivs);

            HashSet <BNode> looseEnds = new HashSet <BNode>();

            foreach (Utils.BezierSubdivSample bss in delCollisions)
            {
                BNode.SubdivideInfo sdiA = colSlideInfo[bss.GetTPosA()];
                BNode.SubdivideInfo sdiB = colSlideInfo[bss.GetTPosB()];
                float wind    = Utils.Vector2Cross(sdiA.subOut, sdiB.subOut);
                BNode colNode = createdSubdivs[bss.GetTPosA()];
                onIslA = colNode;

                if (leftWind <= 0.0f != wind <= 0.0f)
                {
                    // A CCW transition will go from A to B.
                    BNode nA = splitCol.GetPreviousTo(bss.GetTPosA());
                    BNode nB = splitCol.GetNextTo(bss.GetTPosB());

                    nA.TanOut = sdiA.prevOut;
                    nB.TanIn  = sdiB.nextIn;

                    colNode.UseTanIn  = bss.a.node.IsLine() == false;
                    colNode.UseTanOut = bss.b.node.IsLine() == false;
                    colNode.TanIn     = sdiA.subIn;
                    colNode.TanOut    = sdiB.subOut;

                    nA.next      = colNode;
                    colNode.prev = nA;
                    nB.prev      = colNode;
                    colNode.next = nB;

                    looseEnds.Add(bss.b.node);
                    looseEnds.Add(splitCol.GetSplitInfo(bss.a.node).origNext);
                }
                else
                {
                    // A CW transition will go from the other to it.
                    BNode nA = splitCol.GetNextTo(bss.GetTPosA());
                    BNode nB = splitCol.GetPreviousTo(bss.GetTPosB());

                    nA.TanIn  = sdiA.nextIn;
                    nB.TanOut = sdiB.prevOut;

                    colNode.UseTanIn  = bss.b.node.IsLine() == false;
                    colNode.UseTanOut = bss.a.node.IsLine() == false;
                    colNode.TanIn     = sdiB.subIn;
                    colNode.TanOut    = sdiA.subOut;

                    nB.next      = colNode;
                    colNode.prev = nB;
                    nA.prev      = colNode;
                    colNode.next = nA;

                    looseEnds.Add(splitCol.GetSplitInfo(bss.b.node).origNext);
                    looseEnds.Add(bss.a.node);
                }
            }

            // Figure out what internal items need to be removed by
            // checking which nodes have unmatching connectivity.
            ClipLooseEnds(looseEnds);

            return(BoundingMode.Collision);
        }
Beispiel #7
0
        public SoulsComponent()
        {
            splitCollection = new SplitCollection();
            memory          = new SoulsMemory();
            masterControl   = new SoulsMasterControl();
            run             = new RunState();

            splitFunctions = new Dictionary <SplitTypes, Func <int[], bool> >
            {
                { SplitTypes.Bonfire, ProcessBonfire },
                { SplitTypes.Boss, ProcessBoss },
                { SplitTypes.Covenant, ProcessCovenant },
                { SplitTypes.Event, ProcessEvent },
                { SplitTypes.Flag, ProcessFlag },
                { SplitTypes.Item, ProcessItem },
                { SplitTypes.Quitout, ProcessQuitout },
                { SplitTypes.Zone, ProcessZone }
            };

            // This array is used for covenant discovery splits. Discovery occurs when the player is prompted to join a
            // covenant via a yes/no confirmation box. That prompt's appearance can be detected through memory, but
            // it's shared among all covenants. As such, position is used to narrow down the covenant.
            covenantLocations = new []
            {
                new Vector3(-28, -53, 87),               // Way of White (in front of Petrus)
                new Vector3(9, 29, 121),                 // Way of White (beside Rhea)
                new Vector3(622, 164, 255),              // Princess (in front of Gwynevere)
                new Vector3(36, 12, -32),                // Sunlight (in front of the sunlight altar)
                new Vector3(93, -311, 4),                // Darkwraith (in front of Kaathe)
                new Vector3(-702, -412, -333),           // Dragon (in front of the everlasting dragon)
                new Vector3(-161, -265, -32),            // Gravelord (below Nito)
                new Vector3(285, -3, -105),              // Forest (below Alvina)
                new Vector3(430, 60, 255),               // Darkmoon (just outside Gwyndolin's boss arena)
                new Vector3(138, -252, 94)               // Chaos (in front of the fair lady)
            };

            // Previously, bonfire resting was determined by reading the last bonfire from memory (i.e. the bonfire to
            // which the player will warp on death or when using an item). That approach works great for most cases,
            // but there's a catch in that the last bonfire seems to update a frame after the resting animation is
            // detected. As a result, it was possible for the autosplitter to split incorrectly if that last bonfire
            // value is already set to the target (in which case you'd split at any bonfire, not just the target).
            // There's unfortunately no foolproof solution to this problem using that last bonfire data alone, which is
            // why position data is used instead.
            //
            // Also note that each position is taken from the player standing right next to the bonfire (rounded to the
            // nearest integer). Positions don't need to be exact (just close enough that, on rest, the target bonfire
            // will be the closest).
            bonfireLocations = new []
            {
                new Vector3(171, 173, 255),             // Anor Londo - Entrance
                new Vector3(504, 135, 175),             // Anor Londo - Interior
                new Vector3(593, 161, 254),             // Anor Londo - Princess
                new Vector3(391, 70, 255),              // Anor Londo - Tomb
                new Vector3(-388, -408, 156),           // Ash Lake - Entrance
                new Vector3(-700, -414, -323),          // Ash Lake - Dragon
                new Vector3(-277, -137, 73),            // Blighttown - Bridge
                new Vector3(-198, -215, 100),           // Blighttown - Swamp
                new Vector3(44, -119, 204),             // Catacombs - Entrance
                new Vector3(48, -112, 301),             // Catacombs - Illusion
                new Vector3(854, -577, 849),            // Chasm of the Abyss
                new Vector3(96, 134, 864),              // Crystal Caves
                new Vector3(165, -77, -55),             // Darkroot Basin
                new Vector3(257, -3, -12),              // Darkroot Garden
                new Vector3(141, -253, 94),             // Daughter of Chaos
                new Vector3(253, -334, 22),             // Demon Ruins - Central
                new Vector3(194, -267, 130),            // Demon Ruins - Entrance
                new Vector3(118, -357, 139),            // Demon Ruins - Firesage
                new Vector3(349, 278, 594),             // Duke's Archives - Balcony
                new Vector3(230, 200, 481),             // Duke's Archives - Entrance
                new Vector3(378, 270, 552),             // Duke's Archives - Prison
                new Vector3(52, -64, 106),              // Firelink Altar
                new Vector3(-51, -61, 55),              // Firelink Shrine
                new Vector3(-318, -236, 123),           // Great Hollow
                new Vector3(581, -444, 444),            // Lost Izalith - Bed of Chaos
                new Vector3(456, -380, 170),            // Lost Izalith - Illusion
                new Vector3(229, -384, 91),             // Lost Izalith - Lava Field
                new Vector3(972, -314, 583),            // Oolacile Sanctuary
                new Vector3(863, -448, 912),            // Oolacile Township - Dungeon
                new Vector3(1041, -332, 875),           // Oolacile Township - Entrance
                new Vector3(-24, 52, 944),              // Painted World
                new Vector3(897, -329, 452),            // Sanctuary Garden
                new Vector3(73, 60, 301),               // Sen's Fortress
                new Vector3(85, -311, 3),               // The Abyss
                new Vector3(-121, -74, 13),             // The Depths
                new Vector3(77, -214, 45),              // Tomb of the Giants - Alcove
                new Vector3(-159, -265, -34),           // Tomb of the Giants - Nito
                new Vector3(97, -200, 104),             // Tomb of the Giants - Patches
                new Vector3(3, 196, 7),                 // Undead Asylum - Courtyard
                new Vector3(34, 193, -26),              // Undead Asylum - Interior
                new Vector3(3, -10, -61),               // Undead Burg
                new Vector3(88, 15, 107),               // Undead Parish - Andre
                new Vector3(24, 10, -23)                // Undead Parish - Sunlight
            };

            Zone abyss           = new Zone(16, 0);
            Zone anorLondo       = new Zone(15, 1);
            Zone asylum          = new Zone(18, 1);
            Zone basin           = new Zone(12, 0);
            Zone firelinkAltar   = new Zone(18, 0);
            Zone firelinkShrine  = new Zone(10, 2);
            Zone paintedWorld    = new Zone(11, 0);
            Zone sanctuaryGarden = new Zone(12, 1);
            Zone sensRoof        = new Zone(15, 0);

            // Since zones are designed to capture transitions between distinct areas, each zone (from the enumeration)
            // maps to both its associated zone (the first item in the list) and a list of neighboring zones (the
            // remaining items).
            zoneMap = new Dictionary <Zones, List <Zone> >
            {
                { Zones.AnorLondo, new List <Zone> {
                      anorLondo, paintedWorld, sensRoof
                  } },
                { Zones.FirelinkAltar, new List <Zone> {
                      firelinkAltar, abyss, firelinkShrine
                  } },
                { Zones.FirelinkShrine, new List <Zone> {
                      firelinkShrine, asylum, firelinkAltar
                  } },
                { Zones.PaintedWorld, new List <Zone> {
                      paintedWorld, anorLondo
                  } },
                { Zones.SanctuaryGarden, new List <Zone> {
                      sanctuaryGarden, basin
                  } },
                { Zones.SensFortressRoof, new List <Zone> {
                      sensRoof, anorLondo
                  } },
                { Zones.TheAbyss, new List <Zone> {
                      abyss, firelinkAltar
                  } },
                { Zones.UndeadAsylum, new List <Zone> {
                      asylum, firelinkShrine
                  } }
            };

            // This list was previously used in the memory class when setting items. It makes more sense to store it
            // here instead.
            List <int> keys = new List <int>();

            keys.AddRange(ItemFlags.OrderedKeys);
            keys.AddRange(ItemFlags.OrderedEmbers);
            keys.AddRange(ItemFlags.OrderedBonfireItems);
            keys.Add((int)SoulFlags.BequeathedLordSoulShardFourKings);
            keys.Add((int)SoulFlags.BequeathedLordSoulShardSeath);
            keys.Add((int)SoulFlags.LordSoulBedOfChaos);
            keys.Add((int)SoulFlags.LordSoulNito);

            for (int i = 0; i < keys.Count; i++)
            {
                keys[i] = Utilities.StripHighestDigit(keys[i], out int digit);
            }

            keyItems = keys.ToArray();
        }
Beispiel #8
0
 public SheepoComponent()
 {
     memory          = new SheepoMemory();
     masterControl   = new SheepoMasterControl();
     splitCollection = new SplitCollection();
 }