Ejemplo n.º 1
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="dungeonData">
 /// The mutable dungeon data parent class.
 /// </param>
 public DungeonItemDictionary(
     IDungeonItemFactory.Factory factory, IMutableDungeon dungeonData)
     : base(new Dictionary <DungeonItemID, IDungeonItem>())
 {
     _dungeonData = dungeonData;
     _factory     = new Lazy <IDungeonItemFactory>(() => factory());
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Subscribes to the DungeonDataCreated event on the IDungeon interface.
        /// </summary>
        /// <param name="sender">
        /// The sending object of the event.
        /// </param>
        /// <param name="e">
        /// The arguments of the DungeonDataCreated event.
        /// </param>
        private void OnDungeonDataCreated(object sender, IMutableDungeon e)
        {
            if (e == this)
            {
                foreach (KeyDoorID smallKeyDoor in _dungeon.SmallKeyDoors)
                {
                    SmallKeyDoors.Add(smallKeyDoor, KeyDoorDictionary[smallKeyDoor]);
                }

                foreach (KeyDoorID bigKeyDoor in _dungeon.BigKeyDoors)
                {
                    BigKeyDoors.Add(bigKeyDoor, KeyDoorDictionary[bigKeyDoor]);
                }

                foreach (DungeonItemID item in _dungeon.Items)
                {
                    Items.Add(item, ItemDictionary[item]);
                }

                foreach (DungeonItemID boss in _dungeon.Bosses)
                {
                    BossItems.Add(ItemDictionary[boss]);
                }

                foreach (DungeonNodeID node in _dungeon.Nodes)
                {
                    _ = Nodes[node];
                }

                _dungeon.DungeonDataCreated -= OnDungeonDataCreated;
            }
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="factory">
        /// The factory for creating new dungeon nodes.
        /// </param>
        /// <param name="dungeonData">
        /// The dungeon data.
        /// </param>
        public DungeonNodeDictionary(
            IDungeonNode.Factory factory, IMutableDungeon dungeonData)
            : base(new Dictionary <DungeonNodeID, IDungeonNode>())
        {
            _factory = factory;

            _dungeonData = dungeonData;
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Returns a new dungeon item instance of the specified ID.
        /// </summary>
        /// <param name="id">
        /// The dungeon node identity.
        /// </param>
        /// <param name="dungeonData">
        /// The dungeon mutable data parent class.
        /// </param>
        /// <returns>A new dungeon item instance.</returns>
        public static IDungeonItem GetDungeonItem(
            DungeonItemID id, IMutableDungeon dungeonData)
        {
            if (dungeonData == null)
            {
                throw new ArgumentNullException(nameof(dungeonData));
            }

            return(new DungeonItem(id, dungeonData, GetDungeonItemNode(id, dungeonData)));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Returns whether the key layout is possible in the current game state.
        /// </summary>
        /// <param name="dungeonData">
        /// The dungeon mutable data.
        /// </param>
        /// <param name="smallKeys">
        /// A 32-bit signed integer representing the number of small keys collected.
        /// </param>
        /// <param name="bigKey">
        /// A boolean representing whether the big key was collected.
        /// </param>
        /// <returns>
        /// A boolean representing whether the key layout is possible.
        /// </returns>
        public bool CanBeTrue(IMutableDungeon dungeonData, int smallKeys, bool bigKey)
        {
            if (dungeonData == null)
            {
                throw new ArgumentNullException(nameof(dungeonData));
            }

            if (!_requirement.Met)
            {
                return(false);
            }

            int accessible   = 0;
            int inaccessible = 0;

            foreach (var item in _bigKeyLocations)
            {
                if (dungeonData.Items[item].Accessibility > AccessibilityLevel.Partial)
                {
                    accessible++;
                }
                else
                {
                    inaccessible++;
                }
            }

            if (bigKey && accessible == 0)
            {
                return(false);
            }

            if (!bigKey && inaccessible == 0)
            {
                return(false);
            }

            foreach (var child in _children)
            {
                if (child.CanBeTrue(dungeonData, smallKeys, bigKey))
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Returns whether the key layout is possible in the current game state.
        /// </summary>
        /// <param name="dungeonData">
        /// The dungeon mutable data.
        /// </param>
        /// <param name="smallKeys">
        /// A 32-bit signed integer representing the number of small keys collected.
        /// </param>
        /// <param name="bigKey">
        /// A boolean representing whether the big key was collected.
        /// </param>
        /// <returns>
        /// A boolean representing whether the key layout is possible.
        /// </returns>
        public bool CanBeTrue(IMutableDungeon dungeonData, int smallKeys, bool bigKey)
        {
            if (dungeonData == null)
            {
                throw new ArgumentNullException(nameof(dungeonData));
            }

            if (!_requirement.Met)
            {
                return(false);
            }

            int inaccessible = 0;

            foreach (var item in _smallKeyLocations)
            {
                if (dungeonData.Items[item].Accessibility <= AccessibilityLevel.Partial)
                {
                    inaccessible++;
                }
            }

            if (_bigKeyInLocations && !bigKey)
            {
                inaccessible--;
            }

            if (!ValidateMinimumKeyCount(_dungeon.SmallKeys, smallKeys, inaccessible))
            {
                return(false);
            }

            if (!ValidateMaximumKeyCount(smallKeys, inaccessible))
            {
                return(false);
            }

            foreach (var child in _children)
            {
                if (child.CanBeTrue(dungeonData, smallKeys, bigKey))
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Subscribes to the DungeonDataCreated event on the IDungeon interface.
        /// </summary>
        /// <param name="sender">
        /// The sending object of the event.
        /// </param>
        /// <param name="e">
        /// The arguments of the DungeonDataCreated event.
        /// </param>
        private void OnDungeonDataCreated(object?sender, IMutableDungeon e)
        {
            if (e == this)
            {
                foreach (var smallKeyDoor in _dungeon.SmallKeyDoors)
                {
                    SmallKeyDoors.Add(smallKeyDoor, KeyDoors[smallKeyDoor]);
                }

                foreach (var bigKeyDoor in _dungeon.BigKeyDoors)
                {
                    BigKeyDoors.Add(bigKeyDoor, KeyDoors[bigKeyDoor]);
                }

                foreach (var item in _dungeon.DungeonItems)
                {
                    Items.Add(item, DungeonItems[item]);
                }

                foreach (var boss in _dungeon.Bosses)
                {
                    Bosses.Add(DungeonItems[boss]);
                }

                foreach (var smallKeyDrop in _dungeon.SmallKeyDrops)
                {
                    SmallKeyDrops.Add(smallKeyDrop, DungeonItems[smallKeyDrop]);
                }

                foreach (var bigKeyDrop in _dungeon.BigKeyDrops)
                {
                    BigKeyDrops.Add(bigKeyDrop, DungeonItems[bigKeyDrop]);
                }

                foreach (var node in _dungeon.Nodes)
                {
                    _ = Nodes[node];
                }

                _dungeon.DungeonDataCreated -= OnDungeonDataCreated;
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Process the dungeon state permutation.
        /// </summary>
        /// <param name="state">
        /// The permutation to be processed.
        /// </param>
        /// <param name="finalQueue">
        /// The final queue.
        /// </param>
        /// <param name="nextQueue">
        /// The next queue to which this permutation will be added.
        /// </param>
        private void ProcessDungeonState(
            IMutableDungeon dungeonData, IDungeonState state,
            BlockingCollection <IDungeonState> finalQueue,
            BlockingCollection <IDungeonState>?nextQueue)
        {
            dungeonData.ApplyState(state);

            int availableKeys = dungeonData.GetAvailableSmallKeys(state.SequenceBreak) +
                                state.KeysCollected - state.UnlockedDoors.Count;

            if (availableKeys == 0)
            {
                finalQueue.Add(state);
                return;
            }

            var accessibleKeyDoors = dungeonData.GetAccessibleKeyDoors(state.SequenceBreak);

            if (accessibleKeyDoors.Count == 0)
            {
                finalQueue.Add(state);
                return;
            }

            foreach (var keyDoor in accessibleKeyDoors)
            {
                var newPermutation = state.UnlockedDoors.GetRange(0, state.UnlockedDoors.Count);
                newPermutation.Add(keyDoor);

                if (nextQueue == null)
                {
                    return;
                }

                nextQueue.Add(
                    _stateFactory(
                        newPermutation, state.KeysCollected, state.BigKeyCollected,
                        state.SequenceBreak));
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Process the final dungeon state permutation.
        /// </summary>
        /// <param name="state">
        /// The permutation to be processed.
        /// </param>
        private static void ProcessFinalDungeonState(
            IMutableDungeon dungeonData, IDungeonState state,
            BlockingCollection <IDungeonResult> inLogicQueue,
            BlockingCollection <IDungeonResult> outOfLogicQueue)
        {
            dungeonData.ApplyState(state);

            if (!dungeonData.ValidateKeyLayout(state))
            {
                return;
            }

            var result = dungeonData.GetDungeonResult(state);

            if (state.SequenceBreak)
            {
                outOfLogicQueue.Add(result);
            }
            else
            {
                inLogicQueue.Add(result);
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Returns a dungeon node to which the specified item ID belongs.
        /// </summary>
        /// <param name="id">
        /// The dungeon node identity.
        /// </param>
        /// <param name="dungeonData">
        /// The dungeon mutable data parent class.
        /// </param>
        /// <returns>
        /// A dungeon node.
        /// </returns>
        private static IRequirementNode GetDungeonItemNode(
            DungeonItemID id, IMutableDungeon dungeonData)
        {
            switch (id)
            {
            case DungeonItemID.HCSanctuary:
            {
                return(dungeonData.Nodes[DungeonNodeID.HCSanctuary]);
            }

            case DungeonItemID.HCMapChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.HCFront]);
            }

            case DungeonItemID.HCBoomerangChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.HCPastEscapeFirstKeyDoor]);
            }

            case DungeonItemID.HCZeldasCell:
            {
                return(dungeonData.Nodes[DungeonNodeID.HCPastEscapeSecondKeyDoor]);
            }

            case DungeonItemID.HCDarkCross:
            {
                return(dungeonData.Nodes[DungeonNodeID.HCDarkRoomFront]);
            }

            case DungeonItemID.HCSecretRoomLeft:
            case DungeonItemID.HCSecretRoomMiddle:
            case DungeonItemID.HCSecretRoomRight:
            {
                return(dungeonData.Nodes[DungeonNodeID.HCBack]);
            }

            case DungeonItemID.ATRoom03:
            {
                return(dungeonData.Nodes[DungeonNodeID.AT]);
            }

            case DungeonItemID.ATDarkMaze:
            {
                return(dungeonData.Nodes[DungeonNodeID.ATPastFirstKeyDoor]);
            }

            case DungeonItemID.ATBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.ATBoss]);
            }

            case DungeonItemID.EPCannonballChest:
            case DungeonItemID.EPMapChest:
            case DungeonItemID.EPCompassChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.EP]);
            }

            case DungeonItemID.EPBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.EPBigChest]);
            }

            case DungeonItemID.EPBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.EPPastRightKeyDoor]);
            }

            case DungeonItemID.EPBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.EPBoss]);
            }

            case DungeonItemID.DPMapChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.DPFront]);
            }

            case DungeonItemID.DPTorch:
            {
                return(dungeonData.Nodes[DungeonNodeID.DPTorch]);
            }

            case DungeonItemID.DPBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.DPBigChest]);
            }

            case DungeonItemID.DPCompassChest:
            case DungeonItemID.DPBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.DPPastRightKeyDoor]);
            }

            case DungeonItemID.DPBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.DPBoss]);
            }

            case DungeonItemID.ToHBasementCage:
            case DungeonItemID.ToHMapChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.ToH]);
            }

            case DungeonItemID.ToHBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.ToHBasementTorchRoom]);
            }

            case DungeonItemID.ToHCompassChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.ToHPastBigKeyDoor]);
            }

            case DungeonItemID.ToHBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.ToHBigChest]);
            }

            case DungeonItemID.ToHBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.ToHBoss]);
            }

            case DungeonItemID.PoDShooterRoom:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoD]);
            }

            case DungeonItemID.PoDMapChest:
            case DungeonItemID.PoDArenaLedge:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDPastFirstRedGoriyaRoom]);
            }

            case DungeonItemID.PoDBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDBigKeyChestArea]);
            }

            case DungeonItemID.PoDStalfosBasement:
            case DungeonItemID.PoDArenaBridge:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDLobbyArena]);
            }

            case DungeonItemID.PoDCompassChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDPastCollapsingWalkwayKeyDoor]);
            }

            case DungeonItemID.PoDDarkBasementLeft:
            case DungeonItemID.PoDDarkBasementRight:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDDarkBasement]);
            }

            case DungeonItemID.PoDHarmlessHellway:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDHarmlessHellwayRoom]);
            }

            case DungeonItemID.PoDDarkMazeTop:
            case DungeonItemID.PoDDarkMazeBottom:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDDarkMaze]);
            }

            case DungeonItemID.PoDBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDBigChest]);
            }

            case DungeonItemID.PoDBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDBoss]);
            }

            case DungeonItemID.SPEntrance:
            {
                return(dungeonData.Nodes[DungeonNodeID.SPAfterRiver]);
            }

            case DungeonItemID.SPMapChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.SPB1]);
            }

            case DungeonItemID.SPBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.SPBigChest]);
            }

            case DungeonItemID.SPCompassChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.SPB1PastRightHammerBlocks]);
            }

            case DungeonItemID.SPWestChest:
            case DungeonItemID.SPBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.SPB1PastLeftKeyDoor]);
            }

            case DungeonItemID.SPFloodedRoomLeft:
            case DungeonItemID.SPFloodedRoomRight:
            case DungeonItemID.SPWaterfallRoom:
            {
                return(dungeonData.Nodes[DungeonNodeID.SPB1PastBackFirstKeyDoor]);
            }

            case DungeonItemID.SPBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.SPBoss]);
            }

            case DungeonItemID.SWBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.SWFrontBackConnector]);
            }

            case DungeonItemID.SWMapChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.SWBigChestAreaBottom]);
            }

            case DungeonItemID.SWBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.SWBigChest]);
            }

            case DungeonItemID.SWPotPrison:
            case DungeonItemID.SWCompassChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.SWFrontLeftSide]);
            }

            case DungeonItemID.SWPinballRoom:
            {
                return(dungeonData.Nodes[DungeonNodeID.SWFrontRightSide]);
            }

            case DungeonItemID.SWBridgeRoom:
            {
                return(dungeonData.Nodes[DungeonNodeID.SWBack]);
            }

            case DungeonItemID.SWBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.SWBoss]);
            }

            case DungeonItemID.TTMapChest:
            case DungeonItemID.TTAmbushChest:
            case DungeonItemID.TTCompassChest:
            case DungeonItemID.TTBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.TT]);
            }

            case DungeonItemID.TTAttic:
            {
                return(dungeonData.Nodes[DungeonNodeID.TTPastSecondKeyDoor]);
            }

            case DungeonItemID.TTBlindsCell:
            {
                return(dungeonData.Nodes[DungeonNodeID.TTPastFirstKeyDoor]);
            }

            case DungeonItemID.TTBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.TTBigChest]);
            }

            case DungeonItemID.TTBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.TTBoss]);
            }

            case DungeonItemID.IPCompassChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPB1LeftSide]);
            }

            case DungeonItemID.IPSpikeRoom:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPSpikeRoom]);
            }

            case DungeonItemID.IPMapChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPB2PastLiftBlock]);
            }

            case DungeonItemID.IPBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPB1RightSide]);
            }

            case DungeonItemID.IPFreezorChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPFreezorChest]);
            }

            case DungeonItemID.IPBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPBigChest]);
            }

            case DungeonItemID.IPIcedTRoom:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPB5]);
            }

            case DungeonItemID.IPBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPBoss]);
            }

            case DungeonItemID.MMBridgeChest:
            case DungeonItemID.MMSpikeChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.MMPastEntranceGap]);
            }

            case DungeonItemID.MMMainLobby:
            {
                return(dungeonData.Nodes[DungeonNodeID.MMB1LobbyBeyondBlueBlocks]);
            }

            case DungeonItemID.MMCompassChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.MMB1PastFourTorchRoom]);
            }

            case DungeonItemID.MMBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.MMF1PastFourTorchRoom]);
            }

            case DungeonItemID.MMBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.MMBigChest]);
            }

            case DungeonItemID.MMMapChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.MMB1RightSideBeyondBlueBlocks]);
            }

            case DungeonItemID.MMBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.MMBoss]);
            }

            case DungeonItemID.TRCompassChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRF1CompassChestArea]);
            }

            case DungeonItemID.TRRollerRoomLeft:
            case DungeonItemID.TRRollerRoomRight:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRF1RollerRoom]);
            }

            case DungeonItemID.TRChainChomps:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRF1PastSecondKeyDoor]);
            }

            case DungeonItemID.TRBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRB1PastBigKeyChestKeyDoor]);
            }

            case DungeonItemID.TRBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRBigChest]);
            }

            case DungeonItemID.TRCrystarollerRoom:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRB1RightSide]);
            }

            case DungeonItemID.TRLaserBridgeTopLeft:
            case DungeonItemID.TRLaserBridgeTopRight:
            case DungeonItemID.TRLaserBridgeBottomLeft:
            case DungeonItemID.TRLaserBrdigeBottomRight:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRLaserBridgeChests]);
            }

            case DungeonItemID.TRBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRBoss]);
            }

            case DungeonItemID.GTHopeRoomLeft:
            case DungeonItemID.GTHopeRoomRight:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FRight]);
            }

            case DungeonItemID.GTBobsTorch:
            {
                return(dungeonData.Nodes[DungeonNodeID.GTBobsTorch]);
            }

            case DungeonItemID.GTDMsRoomTopLeft:
            case DungeonItemID.GTDMsRoomTopRight:
            case DungeonItemID.GTDMsRoomBottomLeft:
            case DungeonItemID.GTDMsRoomBottomRight:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FLeftDMsRoom]);
            }

            case DungeonItemID.GTMapChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FLeftMapChestRoom]);
            }

            case DungeonItemID.GTFiresnakeRoom:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FLeftPastFiresnakeRoomGap]);
            }

            case DungeonItemID.GTRandomizerRoomTopLeft:
            case DungeonItemID.GTRandomizerRoomTopRight:
            case DungeonItemID.GTRandomizerRoomBottomLeft:
            case DungeonItemID.GTRandomizerRoomBottomRight:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FLeftRandomizerRoom]);
            }

            case DungeonItemID.GTTileRoom:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FRightTileRoom]);
            }

            case DungeonItemID.GTCompassRoomTopLeft:
            case DungeonItemID.GTCompassRoomTopRight:
            case DungeonItemID.GTCompassRoomBottomLeft:
            case DungeonItemID.GTCompassRoomBottomRight:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FRightCompassRoom]);
            }

            case DungeonItemID.GTBobsChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FBottomRoom]);
            }

            case DungeonItemID.GTBigKeyRoomTopLeft:
            case DungeonItemID.GTBigKeyRoomTopRight:
            case DungeonItemID.GTBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.GTB1BossChests]);
            }

            case DungeonItemID.GTBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.GTBigChest]);
            }

            case DungeonItemID.GTMiniHelmasaurRoomLeft:
            case DungeonItemID.GTMiniHelmasaurRoomRight:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT5FPastFourTorchRooms]);
            }

            case DungeonItemID.GTPreMoldormChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT6FPastFirstKeyDoor]);
            }

            case DungeonItemID.GTMoldormChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.GTBoss3Item]);
            }

            case DungeonItemID.GTBoss1:
            {
                return(dungeonData.Nodes[DungeonNodeID.GTBoss1]);
            }

            case DungeonItemID.GTBoss2:
            {
                return(dungeonData.Nodes[DungeonNodeID.GTBoss2]);
            }

            case DungeonItemID.GTBoss3:
            {
                return(dungeonData.Nodes[DungeonNodeID.GTBoss3]);
            }

            case DungeonItemID.GTFinalBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.GTFinalBoss]);
            }
            }

            throw new ArgumentOutOfRangeException(nameof(id));
        }
Ejemplo n.º 11
0
 /// <summary>
 /// Returns whether the key layout is possible in the current game state.
 /// </summary>
 /// <param name="dungeonData">
 /// The dungeon mutable data.
 /// </param>
 /// <param name="smallKeys">
 /// A 32-bit signed integer representing the number of small keys collected.
 /// </param>
 /// <param name="bigKey">
 /// A boolean representing whether the big key was collected.
 /// </param>
 /// <returns>
 /// A boolean representing whether the key layout is possible.
 /// </returns>
 public bool CanBeTrue(IMutableDungeon dungeonData, IDungeonState state)
 {
     return(_requirement.Met);
 }
Ejemplo n.º 12
0
 public void FinishMutableDungeonCreation(IMutableDungeon dungeonData)
 {
     DungeonDataCreated?.Invoke(this, dungeonData);
 }
Ejemplo n.º 13
0
        /// <summary>
        /// Updates the accessibility and number of accessible items for the contained sections
        /// using parallel operation.
        /// </summary>
        private void UpdateSectionAccessibilityParallel()
        {
            var keyDoorPermutationQueue =
                new List <BlockingCollection <(List <KeyDoorID>, int, bool, bool)> >();
            var keyDoorTasks = new List <Task[]>();
            var finalKeyDoorPermutationQueue =
                new BlockingCollection <(List <KeyDoorID>, int, bool, bool)>();
            var resultQueue =
                new BlockingCollection <
                    (List <AccessibilityLevel>, AccessibilityLevel, int, bool)>();

            for (int i = 0; i <= SmallKeyDoors.Count; i++)
            {
                keyDoorPermutationQueue.Add(
                    new BlockingCollection <(List <KeyDoorID>, int, bool, bool)>());
            }

            List <int>  smallKeyValues = GetSmallKeyValues();
            List <bool> bigKeyValues   = GetBigKeyValues();

            foreach (int smallKeyValue in smallKeyValues)
            {
                foreach (bool bigKeyValue in bigKeyValues)
                {
                    keyDoorPermutationQueue[0].Add(
                        (new List <KeyDoorID>(), smallKeyValue, bigKeyValue, false));
                }
            }

            keyDoorPermutationQueue[0].CompleteAdding();

            for (int i = 0; i < keyDoorPermutationQueue.Count; i++)
            {
                int currentIteration = i;

                keyDoorTasks.Add(Enumerable.Range(1, Math.Max(1, Environment.ProcessorCount - 1))
                                 .Select(_ => Task.Factory.StartNew(() =>
                {
                    foreach (var item in keyDoorPermutationQueue[currentIteration].GetConsumingEnumerable())
                    {
                        IMutableDungeon dungeonData = GetDungeonData();

                        dungeonData.SetSmallKeyDoorState(item.Item1);
                        dungeonData.SetBigKeyDoorState(item.Item3);

                        int availableKeys = dungeonData.GetFreeKeys() + item.Item2 - item.Item1.Count;
                        int availableKeysSequenceBreak = dungeonData.GetFreeKeysSequenceBreak() +
                                                         item.Item2 - item.Item1.Count;
                        bool sequenceBreak = item.Item4;

                        if (availableKeysSequenceBreak == 0)
                        {
                            finalKeyDoorPermutationQueue.Add(item);
                            DungeonDataQueue.Enqueue(dungeonData);
                            continue;
                        }

                        if (availableKeys == 0)
                        {
                            finalKeyDoorPermutationQueue.Add(item);
                            sequenceBreak = true;
                        }

                        var accessibleKeyDoors = dungeonData.GetAccessibleKeyDoors();

                        if (accessibleKeyDoors.Count == 0)
                        {
                            finalKeyDoorPermutationQueue.Add(item);
                            DungeonDataQueue.Enqueue(dungeonData);
                            continue;
                        }

                        foreach (var keyDoor in accessibleKeyDoors)
                        {
                            List <KeyDoorID> newPermutation = item.Item1.GetRange(0, item.Item1.Count);
                            newPermutation.Add(keyDoor.Item1);
                            keyDoorPermutationQueue[currentIteration + 1].Add(
                                (newPermutation, item.Item2, item.Item3, sequenceBreak || keyDoor.Item2));
                        }

                        DungeonDataQueue.Enqueue(dungeonData);
                    }
                },
                                                                    CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default)).ToArray());
            }

            for (int i = 0; i < keyDoorTasks.Count; i++)
            {
                Task.WaitAll(keyDoorTasks[i]);
                keyDoorPermutationQueue[i].Dispose();

                if (i + 1 < keyDoorPermutationQueue.Count)
                {
                    keyDoorPermutationQueue[i + 1].CompleteAdding();
                }
                else
                {
                    finalKeyDoorPermutationQueue.CompleteAdding();
                }
            }

            Task[] finalKeyDoorTasks = Enumerable.Range(1, Math.Max(1, Environment.ProcessorCount - 1))
                                       .Select(_ => Task.Factory.StartNew(() =>
            {
                foreach (var item in finalKeyDoorPermutationQueue.GetConsumingEnumerable())
                {
                    IMutableDungeon dungeonData = GetDungeonData();

                    dungeonData.SetSmallKeyDoorState(item.Item1);
                    dungeonData.SetBigKeyDoorState(item.Item3);

                    if (!dungeonData.ValidateKeyLayout(item.Item2, item.Item3))
                    {
                        DungeonDataQueue.Enqueue(dungeonData);
                        continue;
                    }

                    List <AccessibilityLevel> bossAccessibility = dungeonData.GetBossAccessibility();

                    var accessibility =
                        dungeonData.GetItemAccessibility(item.Item2, item.Item3, item.Item4);

                    resultQueue.Add(
                        (bossAccessibility, accessibility.Item1, accessibility.Item2,
                         accessibility.Item3));

                    DungeonDataQueue.Enqueue(dungeonData);
                }
            },
                                                                          CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default)).ToArray();

            Task.WaitAll(finalKeyDoorTasks);
            finalKeyDoorPermutationQueue.Dispose();
            resultQueue.CompleteAdding();

            List <AccessibilityLevel> lowestBossAccessibilities  = new List <AccessibilityLevel>();
            List <AccessibilityLevel> highestBossAccessibilities = new List <AccessibilityLevel>();

            for (int i = 0; i < Bosses.Count; i++)
            {
                lowestBossAccessibilities.Add(AccessibilityLevel.Normal);
                highestBossAccessibilities.Add(AccessibilityLevel.None);
            }

            AccessibilityLevel lowestAccessibility  = AccessibilityLevel.Normal;
            AccessibilityLevel highestAccessibility = AccessibilityLevel.None;
            int highestAccessible = 0;

            foreach (var item in resultQueue.GetConsumingEnumerable())
            {
                for (int i = 0; i < item.Item1.Count; i++)
                {
                    if (item.Item1[i] < lowestBossAccessibilities[i] && !item.Item4)
                    {
                        lowestBossAccessibilities[i] = item.Item1[i];
                    }

                    if (item.Item1[i] > highestBossAccessibilities[i])
                    {
                        highestBossAccessibilities[i] = item.Item1[i];
                    }
                }

                if (item.Item2 < lowestAccessibility && !item.Item4)
                {
                    lowestAccessibility = item.Item2;
                }

                if (item.Item2 > highestAccessibility)
                {
                    highestAccessibility = item.Item2;
                }

                if (item.Item3 > highestAccessible)
                {
                    highestAccessible = item.Item3;
                }
            }

            resultQueue.Dispose();

            AccessibilityLevel finalAccessibility = highestAccessibility;

            if (finalAccessibility == AccessibilityLevel.Normal &&
                lowestAccessibility < AccessibilityLevel.Normal)
            {
                finalAccessibility = AccessibilityLevel.SequenceBreak;
            }

            switch (finalAccessibility)
            {
            case AccessibilityLevel.None:
            {
                (Sections[0] as IDungeonItemSection).Accessibility = finalAccessibility;
                (Sections[0] as IDungeonItemSection).Accessible    = 0;
            }
            break;

            case AccessibilityLevel.Inspect:
            case AccessibilityLevel.Partial:
            {
                (Sections[0] as IDungeonItemSection).Accessibility = finalAccessibility;
                (Sections[0] as IDungeonItemSection).Accessible    = highestAccessible;
            }
            break;

            case AccessibilityLevel.SequenceBreak:
            case AccessibilityLevel.Normal:
            case AccessibilityLevel.Cleared:
            {
                (Sections[0] as IDungeonItemSection).Accessibility = finalAccessibility;
                (Sections[0] as IDungeonItemSection).Accessible    = Sections[0].Available;
            }
            break;
            }

            for (int i = 0; i < Bosses.Count; i++)
            {
                if (highestBossAccessibilities[i] == AccessibilityLevel.Normal &&
                    lowestBossAccessibilities[i] != AccessibilityLevel.Normal)
                {
                    highestBossAccessibilities[i] = AccessibilityLevel.SequenceBreak;
                }

                (Sections[i + 1] as IBossSection).Accessibility = highestBossAccessibilities[i];
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Updates the accessibility and number of accessible items for the contained sections.
        /// </summary>
        private void UpdateSectionAccessibilitySerial()
        {
            var keyDoorPermutationQueue =
                new List <BlockingCollection <(List <KeyDoorID>, int, bool, bool)> >();
            var finalKeyDoorPermutationQueue =
                new BlockingCollection <(List <KeyDoorID>, int, bool, bool)>();
            var resultQueue =
                new BlockingCollection <
                    (List <AccessibilityLevel>, AccessibilityLevel, int, bool)>();

            for (int i = 0; i <= SmallKeyDoors.Count; i++)
            {
                keyDoorPermutationQueue.Add(
                    new BlockingCollection <(List <KeyDoorID>, int, bool, bool)>());
            }

            List <int>  smallKeyValues = GetSmallKeyValues();
            List <bool> bigKeyValues   = GetBigKeyValues();

            foreach (int smallKeyValue in smallKeyValues)
            {
                foreach (bool bigKeyValue in bigKeyValues)
                {
                    keyDoorPermutationQueue[0].Add(
                        (new List <KeyDoorID>(), smallKeyValue, bigKeyValue, false));
                }
            }

            keyDoorPermutationQueue[0].CompleteAdding();

            for (int i = 0; i < keyDoorPermutationQueue.Count; i++)
            {
                foreach (var item in keyDoorPermutationQueue[i].GetConsumingEnumerable())
                {
                    IMutableDungeon dungeonData = GetDungeonData();

                    dungeonData.SetSmallKeyDoorState(item.Item1);
                    dungeonData.SetBigKeyDoorState(item.Item3);

                    int availableKeys = dungeonData.GetFreeKeys() + item.Item2 - item.Item1.Count;
                    int availableKeysSequenceBreak = dungeonData.GetFreeKeysSequenceBreak() +
                                                     item.Item2 - item.Item1.Count;
                    bool sequenceBreak = item.Item4;

                    if (availableKeysSequenceBreak == 0)
                    {
                        finalKeyDoorPermutationQueue.Add(item);
                        DungeonDataQueue.Enqueue(dungeonData);
                        continue;
                    }

                    if (availableKeys == 0)
                    {
                        finalKeyDoorPermutationQueue.Add(item);
                        sequenceBreak = true;
                    }

                    var accessibleKeyDoors = dungeonData.GetAccessibleKeyDoors();

                    if (accessibleKeyDoors.Count == 0)
                    {
                        finalKeyDoorPermutationQueue.Add(item);
                        DungeonDataQueue.Enqueue(dungeonData);
                        continue;
                    }

                    foreach (var keyDoor in accessibleKeyDoors)
                    {
                        List <KeyDoorID> newPermutation = item.Item1.GetRange(0, item.Item1.Count);

                        if (!accessibleKeyDoors.Exists(x => !x.Item2))
                        {
                            finalKeyDoorPermutationQueue.Add(item);
                        }

                        newPermutation.Add(keyDoor.Item1);
                        keyDoorPermutationQueue[i + 1].Add((newPermutation, item.Item2,
                                                            item.Item3, sequenceBreak || keyDoor.Item2));
                    }

                    DungeonDataQueue.Enqueue(dungeonData);
                }

                keyDoorPermutationQueue[i].Dispose();

                if (i + 1 < keyDoorPermutationQueue.Count)
                {
                    keyDoorPermutationQueue[i + 1].CompleteAdding();
                }
                else
                {
                    finalKeyDoorPermutationQueue.CompleteAdding();
                }
            }

            foreach (var item in finalKeyDoorPermutationQueue.GetConsumingEnumerable())
            {
                IMutableDungeon dungeonData = GetDungeonData();

                dungeonData.SetSmallKeyDoorState(item.Item1);
                dungeonData.SetBigKeyDoorState(item.Item3);

                if (!dungeonData.ValidateKeyLayout(item.Item2, item.Item3))
                {
                    DungeonDataQueue.Enqueue(dungeonData);
                    continue;
                }

                List <AccessibilityLevel> bossAccessibility = dungeonData.GetBossAccessibility();

                var accessibility =
                    dungeonData.GetItemAccessibility(item.Item2, item.Item3, item.Item4);

                resultQueue.Add(
                    (bossAccessibility, accessibility.Item1, accessibility.Item2, accessibility.Item3));

                DungeonDataQueue.Enqueue(dungeonData);
            }

            finalKeyDoorPermutationQueue.Dispose();
            resultQueue.CompleteAdding();

            List <AccessibilityLevel> lowestBossAccessibilities  = new List <AccessibilityLevel>();
            List <AccessibilityLevel> highestBossAccessibilities = new List <AccessibilityLevel>();

            for (int i = 0; i < Bosses.Count; i++)
            {
                lowestBossAccessibilities.Add(AccessibilityLevel.Normal);
                highestBossAccessibilities.Add(AccessibilityLevel.None);
            }

            AccessibilityLevel lowestAccessibility  = AccessibilityLevel.Normal;
            AccessibilityLevel highestAccessibility = AccessibilityLevel.None;
            int highestAccessible = 0;

            foreach (var item in resultQueue.GetConsumingEnumerable())
            {
                for (int i = 0; i < item.Item1.Count; i++)
                {
                    if (item.Item1[i] < lowestBossAccessibilities[i] && !item.Item4)
                    {
                        lowestBossAccessibilities[i] = item.Item1[i];
                    }

                    if (item.Item1[i] > highestBossAccessibilities[i])
                    {
                        highestBossAccessibilities[i] = item.Item1[i];
                    }
                }

                if (item.Item2 < lowestAccessibility && !item.Item4)
                {
                    lowestAccessibility = item.Item2;
                }

                if (item.Item2 > highestAccessibility)
                {
                    highestAccessibility = item.Item2;
                }

                if (item.Item3 > highestAccessible)
                {
                    highestAccessible = item.Item3;
                }
            }

            resultQueue.Dispose();

            AccessibilityLevel finalAccessibility = highestAccessibility;

            if (finalAccessibility == AccessibilityLevel.Normal &&
                lowestAccessibility < AccessibilityLevel.Normal)
            {
                finalAccessibility = AccessibilityLevel.SequenceBreak;
            }

            switch (finalAccessibility)
            {
            case AccessibilityLevel.None:
            {
                (Sections[0] as IDungeonItemSection).Accessibility = finalAccessibility;
                (Sections[0] as IDungeonItemSection).Accessible    = 0;
            }
            break;

            case AccessibilityLevel.Inspect:
            case AccessibilityLevel.Partial:
            {
                (Sections[0] as IDungeonItemSection).Accessibility = finalAccessibility;
                (Sections[0] as IDungeonItemSection).Accessible    = highestAccessible;
            }
            break;

            case AccessibilityLevel.SequenceBreak:
            case AccessibilityLevel.Normal:
            case AccessibilityLevel.Cleared:
            {
                (Sections[0] as IDungeonItemSection).Accessibility = finalAccessibility;
                (Sections[0] as IDungeonItemSection).Accessible    = Sections[0].Available;
            }
            break;
            }

            for (int i = 0; i < Bosses.Count; i++)
            {
                if (highestBossAccessibilities[i] == AccessibilityLevel.Normal &&
                    lowestBossAccessibilities[i] != AccessibilityLevel.Normal)
                {
                    highestBossAccessibilities[i] = AccessibilityLevel.SequenceBreak;
                }

                (Sections[i + 1] as IBossSection).Accessibility = highestBossAccessibilities[i];
            }
        }
Ejemplo n.º 15
0
 /// <summary>
 /// Returns a new dungeon item for the specified dungeon data and dungeon item ID.
 /// </summary>
 /// <param name="dungeonData">
 /// The dungeon data.
 /// </param>
 /// <param name="id">
 /// The dungeon item ID.
 /// </param>
 /// <returns>
 /// A new dungeon item.
 /// </returns>
 public IDungeonItem GetDungeonItem(IMutableDungeon dungeonData, DungeonItemID id)
 {
     return(_factory(dungeonData, id, GetDungeonItemNode(dungeonData, id)));
 }
Ejemplo n.º 16
0
        /// <summary>
        /// Returns a dungeon node to which the specified item ID belongs.
        /// </summary>
        /// <param name="dungeonData">
        /// The dungeon mutable data parent class.
        /// </param>
        /// <param name="id">
        /// The dungeon node identity.
        /// </param>
        /// <returns>
        /// A dungeon node.
        /// </returns>
        private static IRequirementNode GetDungeonItemNode(IMutableDungeon dungeonData, DungeonItemID id)
        {
            switch (id)
            {
            case DungeonItemID.HCSanctuary:
            {
                return(dungeonData.Nodes[DungeonNodeID.HCSanctuary]);
            }

            case DungeonItemID.HCMapChest:
            case DungeonItemID.HCMapGuardDrop:
            {
                return(dungeonData.Nodes[DungeonNodeID.HCFront]);
            }

            case DungeonItemID.HCBoomerangChest:
            case DungeonItemID.HCBoomerangGuardDrop:
            {
                return(dungeonData.Nodes[DungeonNodeID.HCPastEscapeFirstKeyDoor]);
            }

            case DungeonItemID.HCZeldasCell:
            {
                return(dungeonData.Nodes[DungeonNodeID.HCZeldasCell]);
            }

            case DungeonItemID.HCDarkCross:
            {
                return(dungeonData.Nodes[DungeonNodeID.HCDarkRoomFront]);
            }

            case DungeonItemID.HCSecretRoomLeft:
            case DungeonItemID.HCSecretRoomMiddle:
            case DungeonItemID.HCSecretRoomRight:
            {
                return(dungeonData.Nodes[DungeonNodeID.HCBack]);
            }

            case DungeonItemID.HCKeyRatDrop:
            {
                return(dungeonData.Nodes[DungeonNodeID.HCPastDarkCrossKeyDoor]);
            }

            case DungeonItemID.HCBigKeyDrop:
            {
                return(dungeonData.Nodes[DungeonNodeID.HCPastEscapeSecondKeyDoor]);
            }

            case DungeonItemID.ATRoom03:
            {
                return(dungeonData.Nodes[DungeonNodeID.AT]);
            }

            case DungeonItemID.ATDarkMaze:
            {
                return(dungeonData.Nodes[DungeonNodeID.ATPastFirstKeyDoor]);
            }

            case DungeonItemID.ATBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.ATBoss]);
            }

            case DungeonItemID.ATDarkArcherDrop:
            {
                return(dungeonData.Nodes[DungeonNodeID.ATPastSecondKeyDoor]);
            }

            case DungeonItemID.ATCircleOfPotsDrop:
            {
                return(dungeonData.Nodes[DungeonNodeID.ATPastThirdKeyDoor]);
            }

            case DungeonItemID.EPCannonballChest:
            case DungeonItemID.EPMapChest:
            case DungeonItemID.EPCompassChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.EP]);
            }

            case DungeonItemID.EPBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.EPBigChest]);
            }

            case DungeonItemID.EPBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.EPPastRightKeyDoor]);
            }

            case DungeonItemID.EPBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.EPBoss]);
            }

            case DungeonItemID.EPDarkSquarePot:
            {
                return(dungeonData.Nodes[DungeonNodeID.EPRightDarkRoom]);
            }

            case DungeonItemID.EPDarkEyegoreDrop:
            {
                return(dungeonData.Nodes[DungeonNodeID.EPBackDarkRoom]);
            }

            case DungeonItemID.DPMapChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.DPFront]);
            }

            case DungeonItemID.DPTorch:
            {
                return(dungeonData.Nodes[DungeonNodeID.DPTorch]);
            }

            case DungeonItemID.DPBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.DPBigChest]);
            }

            case DungeonItemID.DPCompassChest:
            case DungeonItemID.DPBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.DPPastRightKeyDoor]);
            }

            case DungeonItemID.DPBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.DPBoss]);
            }

            case DungeonItemID.DPTiles1Pot:
            {
                return(dungeonData.Nodes[DungeonNodeID.DPBack]);
            }

            case DungeonItemID.DPBeamosHallPot:
            {
                return(dungeonData.Nodes[DungeonNodeID.DP2F]);
            }

            case DungeonItemID.DPTiles2Pot:
            {
                return(dungeonData.Nodes[DungeonNodeID.DP2FPastFirstKeyDoor]);
            }

            case DungeonItemID.ToHBasementCage:
            case DungeonItemID.ToHMapChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.ToH]);
            }

            case DungeonItemID.ToHBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.ToHBasementTorchRoom]);
            }

            case DungeonItemID.ToHCompassChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.ToHPastBigKeyDoor]);
            }

            case DungeonItemID.ToHBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.ToHBigChest]);
            }

            case DungeonItemID.ToHBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.ToHBoss]);
            }

            case DungeonItemID.PoDShooterRoom:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoD]);
            }

            case DungeonItemID.PoDMapChest:
            case DungeonItemID.PoDArenaLedge:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDPastFirstRedGoriyaRoom]);
            }

            case DungeonItemID.PoDBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDBigKeyChestArea]);
            }

            case DungeonItemID.PoDStalfosBasement:
            case DungeonItemID.PoDArenaBridge:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDLobbyArena]);
            }

            case DungeonItemID.PoDCompassChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDPastCollapsingWalkwayKeyDoor]);
            }

            case DungeonItemID.PoDDarkBasementLeft:
            case DungeonItemID.PoDDarkBasementRight:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDDarkBasement]);
            }

            case DungeonItemID.PoDHarmlessHellway:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDHarmlessHellwayRoom]);
            }

            case DungeonItemID.PoDDarkMazeTop:
            case DungeonItemID.PoDDarkMazeBottom:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDDarkMaze]);
            }

            case DungeonItemID.PoDBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDBigChest]);
            }

            case DungeonItemID.PoDBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.PoDBoss]);
            }

            case DungeonItemID.SPEntrance:
            {
                return(dungeonData.Nodes[DungeonNodeID.SPAfterRiver]);
            }

            case DungeonItemID.SPMapChest:
            case DungeonItemID.SPPotRowPot:
            {
                return(dungeonData.Nodes[DungeonNodeID.SPB1]);
            }

            case DungeonItemID.SPBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.SPBigChest]);
            }

            case DungeonItemID.SPCompassChest:
            case DungeonItemID.SPTrench2Pot:
            {
                return(dungeonData.Nodes[DungeonNodeID.SPB1PastRightHammerBlocks]);
            }

            case DungeonItemID.SPWestChest:
            case DungeonItemID.SPBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.SPB1PastLeftKeyDoor]);
            }

            case DungeonItemID.SPFloodedRoomLeft:
            case DungeonItemID.SPFloodedRoomRight:
            case DungeonItemID.SPWaterfallRoom:
            case DungeonItemID.SPWaterwayPot:
            {
                return(dungeonData.Nodes[DungeonNodeID.SPB1PastBackFirstKeyDoor]);
            }

            case DungeonItemID.SPBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.SPBoss]);
            }

            case DungeonItemID.SPTrench1Pot:
            {
                return(dungeonData.Nodes[DungeonNodeID.SPB1PastFirstRightKeyDoor]);
            }

            case DungeonItemID.SPHookshotPot:
            {
                return(dungeonData.Nodes[DungeonNodeID.SPB1KeyLedge]);
            }

            case DungeonItemID.SWBigKeyChest:
            case DungeonItemID.SWWestLobbyPot:
            {
                return(dungeonData.Nodes[DungeonNodeID.SWFrontBackConnector]);
            }

            case DungeonItemID.SWMapChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.SWBigChestAreaBottom]);
            }

            case DungeonItemID.SWBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.SWBigChest]);
            }

            case DungeonItemID.SWPotPrison:
            case DungeonItemID.SWCompassChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.SWFrontLeftSide]);
            }

            case DungeonItemID.SWPinballRoom:
            {
                return(dungeonData.Nodes[DungeonNodeID.SWFrontRightSide]);
            }

            case DungeonItemID.SWBridgeRoom:
            {
                return(dungeonData.Nodes[DungeonNodeID.SWBack]);
            }

            case DungeonItemID.SWBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.SWBoss]);
            }

            case DungeonItemID.SWSpikeCornerDrop:
            {
                return(dungeonData.Nodes[DungeonNodeID.SWBackPastCurtains]);
            }

            case DungeonItemID.TTMapChest:
            case DungeonItemID.TTAmbushChest:
            case DungeonItemID.TTCompassChest:
            case DungeonItemID.TTBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.TT]);
            }

            case DungeonItemID.TTAttic:
            {
                return(dungeonData.Nodes[DungeonNodeID.TTPastSecondKeyDoor]);
            }

            case DungeonItemID.TTBlindsCell:
            case DungeonItemID.TTSpikeSwitchPot:
            {
                return(dungeonData.Nodes[DungeonNodeID.TTPastFirstKeyDoor]);
            }

            case DungeonItemID.TTBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.TTBigChest]);
            }

            case DungeonItemID.TTBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.TTBoss]);
            }

            case DungeonItemID.TTHallwayPot:
            {
                return(dungeonData.Nodes[DungeonNodeID.TTPastBigKeyDoor]);
            }

            case DungeonItemID.IPCompassChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPB1LeftSide]);
            }

            case DungeonItemID.IPSpikeRoom:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPSpikeRoom]);
            }

            case DungeonItemID.IPMapChest:
            case DungeonItemID.IPHammerBlockDrop:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPB2PastLiftBlock]);
            }

            case DungeonItemID.IPBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPB1RightSide]);
            }

            case DungeonItemID.IPFreezorChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPFreezorChest]);
            }

            case DungeonItemID.IPBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPBigChest]);
            }

            case DungeonItemID.IPIcedTRoom:
            case DungeonItemID.IPManyPotsPot:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPB5]);
            }

            case DungeonItemID.IPBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPBoss]);
            }

            case DungeonItemID.IPJellyDrop:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPPastEntranceFreezorRoom]);
            }

            case DungeonItemID.IPConveyerDrop:
            {
                return(dungeonData.Nodes[DungeonNodeID.IPB2LeftSide]);
            }

            case DungeonItemID.MMBridgeChest:
            case DungeonItemID.MMSpikeChest:
            case DungeonItemID.MMSpikesPot:
            {
                return(dungeonData.Nodes[DungeonNodeID.MMPastEntranceGap]);
            }

            case DungeonItemID.MMMainLobby:
            {
                return(dungeonData.Nodes[DungeonNodeID.MMB1LobbyBeyondBlueBlocks]);
            }

            case DungeonItemID.MMCompassChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.MMB1PastFourTorchRoom]);
            }

            case DungeonItemID.MMBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.MMF1PastFourTorchRoom]);
            }

            case DungeonItemID.MMBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.MMBigChest]);
            }

            case DungeonItemID.MMMapChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.MMB1RightSideBeyondBlueBlocks]);
            }

            case DungeonItemID.MMBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.MMBoss]);
            }

            case DungeonItemID.MMFishbonePot:
            {
                return(dungeonData.Nodes[DungeonNodeID.MMB1TopSide]);
            }

            case DungeonItemID.MMConveyerCrystalDrop:
            {
                return(dungeonData.Nodes[DungeonNodeID.MMB1LeftSidePastFirstKeyDoor]);
            }

            case DungeonItemID.TRCompassChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRF1CompassChestArea]);
            }

            case DungeonItemID.TRRollerRoomLeft:
            case DungeonItemID.TRRollerRoomRight:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRF1RollerRoom]);
            }

            case DungeonItemID.TRChainChomps:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRF1PastSecondKeyDoor]);
            }

            case DungeonItemID.TRBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRB1PastBigKeyChestKeyDoor]);
            }

            case DungeonItemID.TRBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRBigChest]);
            }

            case DungeonItemID.TRCrystarollerRoom:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRB1RightSide]);
            }

            case DungeonItemID.TRLaserBridgeTopLeft:
            case DungeonItemID.TRLaserBridgeTopRight:
            case DungeonItemID.TRLaserBridgeBottomLeft:
            case DungeonItemID.TRLaserBrdigeBottomRight:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRLaserBridgeChests]);
            }

            case DungeonItemID.TRBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRBoss]);
            }

            case DungeonItemID.TRPokey1Drop:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRF1PastFirstKeyDoor]);
            }

            case DungeonItemID.TRPokey2Drop:
            {
                return(dungeonData.Nodes[DungeonNodeID.TRB1]);
            }

            case DungeonItemID.GTHopeRoomLeft:
            case DungeonItemID.GTHopeRoomRight:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FRight]);
            }

            case DungeonItemID.GTBobsTorch:
            {
                return(dungeonData.Nodes[DungeonNodeID.GTBobsTorch]);
            }

            case DungeonItemID.GTDMsRoomTopLeft:
            case DungeonItemID.GTDMsRoomTopRight:
            case DungeonItemID.GTDMsRoomBottomLeft:
            case DungeonItemID.GTDMsRoomBottomRight:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FLeftDMsRoom]);
            }

            case DungeonItemID.GTMapChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FLeftMapChestRoom]);
            }

            case DungeonItemID.GTFiresnakeRoom:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FLeftPastFiresnakeRoomGap]);
            }

            case DungeonItemID.GTRandomizerRoomTopLeft:
            case DungeonItemID.GTRandomizerRoomTopRight:
            case DungeonItemID.GTRandomizerRoomBottomLeft:
            case DungeonItemID.GTRandomizerRoomBottomRight:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FLeftRandomizerRoom]);
            }

            case DungeonItemID.GTTileRoom:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FRightTileRoom]);
            }

            case DungeonItemID.GTCompassRoomTopLeft:
            case DungeonItemID.GTCompassRoomTopRight:
            case DungeonItemID.GTCompassRoomBottomLeft:
            case DungeonItemID.GTCompassRoomBottomRight:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FRightCompassRoom]);
            }

            case DungeonItemID.GTBobsChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FBottomRoom]);
            }

            case DungeonItemID.GTBigKeyRoomTopLeft:
            case DungeonItemID.GTBigKeyRoomTopRight:
            case DungeonItemID.GTBigKeyChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.GTB1BossChests]);
            }

            case DungeonItemID.GTBigChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.GTBigChest]);
            }

            case DungeonItemID.GTMiniHelmasaurRoomLeft:
            case DungeonItemID.GTMiniHelmasaurRoomRight:
            case DungeonItemID.GTMiniHelmasaurDrop:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT5FPastFourTorchRooms]);
            }

            case DungeonItemID.GTPreMoldormChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT6FPastFirstKeyDoor]);
            }

            case DungeonItemID.GTMoldormChest:
            {
                return(dungeonData.Nodes[DungeonNodeID.GTBoss3Item]);
            }

            case DungeonItemID.GTBoss1:
            {
                return(dungeonData.Nodes[DungeonNodeID.GTBoss1]);
            }

            case DungeonItemID.GTBoss2:
            {
                return(dungeonData.Nodes[DungeonNodeID.GTBoss2]);
            }

            case DungeonItemID.GTBoss3:
            {
                return(dungeonData.Nodes[DungeonNodeID.GTBoss3]);
            }

            case DungeonItemID.GTFinalBoss:
            {
                return(dungeonData.Nodes[DungeonNodeID.GTFinalBoss]);
            }

            case DungeonItemID.GTConveyorCrossPot:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FLeft]);
            }

            case DungeonItemID.GTDoubleSwitchPot:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FLeftPastBonkableGaps]);
            }

            case DungeonItemID.GTConveyorStarPitsPot:
            {
                return(dungeonData.Nodes[DungeonNodeID.GT1FRightPastCompassRoomPortal]);
            }
            }

            throw new ArgumentOutOfRangeException(nameof(id));
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Returns the requirement for the specified key door.
        /// </summary>
        /// <param name="id">
        /// The key door ID.
        /// </param>
        /// <param name="dungeonData">
        /// The mutable dungeon data.
        /// </param>
        /// <returns>
        /// The requirement for the specified key door.
        /// </returns>
        public static IRequirementNode GetKeyDoorNode(KeyDoorID id, IMutableDungeon dungeonData)
        {
            if (dungeonData == null)
            {
                throw new ArgumentNullException(nameof(dungeonData));
            }

            return(id switch
            {
                KeyDoorID.HCEscapeFirstKeyDoor => dungeonData.Nodes[DungeonNodeID.HCEscapeFirstKeyDoor],
                KeyDoorID.HCEscapeSecondKeyDoor => dungeonData.Nodes[DungeonNodeID.HCEscapeSecondKeyDoor],
                KeyDoorID.HCDarkCrossKeyDoor => dungeonData.Nodes[DungeonNodeID.HCDarkCrossKeyDoor],
                KeyDoorID.HCSewerRatRoomKeyDoor => dungeonData.Nodes[DungeonNodeID.HCSewerRatRoomKeyDoor],
                KeyDoorID.ATFirstKeyDoor => dungeonData.Nodes[DungeonNodeID.ATDarkMaze],
                KeyDoorID.ATSecondKeyDoor => dungeonData.Nodes[DungeonNodeID.ATSecondKeyDoor],
                KeyDoorID.ATThirdKeyDoor => dungeonData.Nodes[DungeonNodeID.ATPastSecondKeyDoor],
                KeyDoorID.ATFourthKeyDoor => dungeonData.Nodes[DungeonNodeID.ATFourthKeyDoor],
                KeyDoorID.EPRightKeyDoor => dungeonData.Nodes[DungeonNodeID.EPRightKeyDoor],
                KeyDoorID.EPBackKeyDoor => dungeonData.Nodes[DungeonNodeID.EPBackDarkRoom],
                KeyDoorID.EPBigChest => dungeonData.Nodes[DungeonNodeID.EP],
                KeyDoorID.EPBigKeyDoor => dungeonData.Nodes[DungeonNodeID.EPBigKeyDoor],
                KeyDoorID.DPRightKeyDoor => dungeonData.Nodes[DungeonNodeID.DPRightKeyDoor],
                KeyDoorID.DP1FKeyDoor => dungeonData.Nodes[DungeonNodeID.DPBack],
                KeyDoorID.DP2FFirstKeyDoor => dungeonData.Nodes[DungeonNodeID.DP2FFirstKeyDoor],
                KeyDoorID.DP2FSecondKeyDoor => dungeonData.Nodes[DungeonNodeID.DP2FSecondKeyDoor],
                KeyDoorID.DPBigChest => dungeonData.Nodes[DungeonNodeID.DPFront],
                KeyDoorID.DPBigKeyDoor => dungeonData.Nodes[DungeonNodeID.DPPastFourTorchWall],
                KeyDoorID.ToHKeyDoor => dungeonData.Nodes[DungeonNodeID.ToH],
                KeyDoorID.ToHBigKeyDoor => dungeonData.Nodes[DungeonNodeID.ToH],
                KeyDoorID.ToHBigChest => dungeonData.Nodes[DungeonNodeID.ToHPastBigKeyDoor],
                KeyDoorID.PoDFrontKeyDoor => dungeonData.Nodes[DungeonNodeID.PoDFrontKeyDoor],
                KeyDoorID.PoDBigKeyChestKeyDoor => dungeonData.Nodes[DungeonNodeID.PoDLobbyArena],
                KeyDoorID.PoDCollapsingWalkwayKeyDoor => dungeonData.Nodes[DungeonNodeID.PoDCollapsingWalkwayKeyDoor],
                KeyDoorID.PoDDarkMazeKeyDoor => dungeonData.Nodes[DungeonNodeID.PoDDarkMazeKeyDoor],
                KeyDoorID.PoDHarmlessHellwayKeyDoor => dungeonData.Nodes[DungeonNodeID.PoDHarmlessHellwayKeyDoor],
                KeyDoorID.PoDBossAreaKeyDoor => dungeonData.Nodes[DungeonNodeID.PoDBossAreaKeyDoor],
                KeyDoorID.PoDBigChest => dungeonData.Nodes[DungeonNodeID.PoDBigChestLedge],
                KeyDoorID.PoDBigKeyDoor => dungeonData.Nodes[DungeonNodeID.PoDPastBossAreaKeyDoor],
                KeyDoorID.SP1FKeyDoor => dungeonData.Nodes[DungeonNodeID.SPAfterRiver],
                KeyDoorID.SPB1FirstRightKeyDoor => dungeonData.Nodes[DungeonNodeID.SPB1FirstRightKeyDoor],
                KeyDoorID.SPB1SecondRightKeyDoor => dungeonData.Nodes[DungeonNodeID.SPB1SecondRightKeyDoor],
                KeyDoorID.SPB1LeftKeyDoor => dungeonData.Nodes[DungeonNodeID.SPB1LeftKeyDoor],
                KeyDoorID.SPB1BackFirstKeyDoor => dungeonData.Nodes[DungeonNodeID.SPB1BackFirstKeyDoor],
                KeyDoorID.SPBossRoomKeyDoor => dungeonData.Nodes[DungeonNodeID.SPBossRoomKeyDoor],
                KeyDoorID.SPBigChest => dungeonData.Nodes[DungeonNodeID.SPB1PastRightHammerBlocks],
                KeyDoorID.SWFrontLeftKeyDoor => dungeonData.Nodes[DungeonNodeID.SWFrontLeftKeyDoor],
                KeyDoorID.SWFrontRightKeyDoor => dungeonData.Nodes[DungeonNodeID.SWFrontRightKeyDoor],
                KeyDoorID.SWWorthlessKeyDoor => dungeonData.Nodes[DungeonNodeID.SWWorthlessKeyDoor],
                KeyDoorID.SWBackFirstKeyDoor => dungeonData.Nodes[DungeonNodeID.SWBackFirstKeyDoor],
                KeyDoorID.SWBackSecondKeyDoor => dungeonData.Nodes[DungeonNodeID.SWBackSecondKeyDoor],
                KeyDoorID.SWBigChest => dungeonData.Nodes[DungeonNodeID.SWBigChestAreaTop],
                KeyDoorID.TTFirstKeyDoor => dungeonData.Nodes[DungeonNodeID.TTFirstKeyDoor],
                KeyDoorID.TTSecondKeyDoor => dungeonData.Nodes[DungeonNodeID.TTPastFirstKeyDoor],
                KeyDoorID.TTBigChestKeyDoor => dungeonData.Nodes[DungeonNodeID.TTBigChestKeyDoor],
                KeyDoorID.TTBigKeyDoor => dungeonData.Nodes[DungeonNodeID.TTBigChestKeyDoor],
                KeyDoorID.TTBigChest => dungeonData.Nodes[DungeonNodeID.TTPastHammerBlocks],
                KeyDoorID.IP1FKeyDoor => dungeonData.Nodes[DungeonNodeID.IPPastEntranceFreezorRoom],
                KeyDoorID.IPB2KeyDoor => dungeonData.Nodes[DungeonNodeID.IPB2KeyDoor],
                KeyDoorID.IPB3KeyDoor => dungeonData.Nodes[DungeonNodeID.IPB3KeyDoor],
                KeyDoorID.IPB4KeyDoor => dungeonData.Nodes[DungeonNodeID.IPB4KeyDoor],
                KeyDoorID.IPB5KeyDoor => dungeonData.Nodes[DungeonNodeID.IPB5PastBigKeyDoor],
                KeyDoorID.IPB6KeyDoor => dungeonData.Nodes[DungeonNodeID.IPB6KeyDoor],
                KeyDoorID.IPBigKeyDoor => dungeonData.Nodes[DungeonNodeID.IPB5],
                KeyDoorID.IPBigChest => dungeonData.Nodes[DungeonNodeID.IPBigChestArea],
                KeyDoorID.MMB1TopRightKeyDoor => dungeonData.Nodes[DungeonNodeID.MMB1TopRightKeyDoor],
                KeyDoorID.MMB1TopLeftKeyDoor => dungeonData.Nodes[DungeonNodeID.MMB1TopLeftKeyDoor],
                KeyDoorID.MMB1LeftSideFirstKeyDoor => dungeonData.Nodes[DungeonNodeID.MMB1LeftSideFirstKeyDoor],
                KeyDoorID.MMB1LeftSideSecondKeyDoor => dungeonData.Nodes[DungeonNodeID.MMB1LeftSideSecondKeyDoor],
                KeyDoorID.MMB1RightSideKeyDoor => dungeonData.Nodes[DungeonNodeID.MMB1RightSideKeyDoor],
                KeyDoorID.MMB2WorthlessKeyDoor => dungeonData.Nodes[DungeonNodeID.MMB2WorthlessKeyDoor],
                KeyDoorID.MMBigChest => dungeonData.Nodes[DungeonNodeID.MMPastEntranceGap],
                KeyDoorID.MMPortalBigKeyDoor => dungeonData.Nodes[DungeonNodeID.MMPastEntranceGap],
                KeyDoorID.MMBridgeBigKeyDoor => dungeonData.Nodes[DungeonNodeID.MMBridgeBigKeyDoor],
                KeyDoorID.MMBossRoomBigKeyDoor => dungeonData.Nodes[DungeonNodeID.MMB2PastCaneOfSomariaSwitch],
                KeyDoorID.TR1FFirstKeyDoor => dungeonData.Nodes[DungeonNodeID.TRF1FirstKeyDoor],
                KeyDoorID.TR1FSecondKeyDoor => dungeonData.Nodes[DungeonNodeID.TRF1SecondKeyDoor],
                KeyDoorID.TR1FThirdKeyDoor => dungeonData.Nodes[DungeonNodeID.TRF1PastSecondKeyDoor],
                KeyDoorID.TRB1BigKeyChestKeyDoor => dungeonData.Nodes[DungeonNodeID.TRB1BigKeyChestKeyDoor],
                KeyDoorID.TRB1toB2KeyDoor => dungeonData.Nodes[DungeonNodeID.TRB1RightSide],
                KeyDoorID.TRB2KeyDoor => dungeonData.Nodes[DungeonNodeID.TRB2KeyDoor],
                KeyDoorID.TRBigChest => dungeonData.Nodes[DungeonNodeID.TRB1BigChestArea],
                KeyDoorID.TRB1BigKeyDoor => dungeonData.Nodes[DungeonNodeID.TRB1BigKeyDoor],
                KeyDoorID.TRBossRoomBigKeyDoor => dungeonData.Nodes[DungeonNodeID.TRB3BossRoomEntry],
                KeyDoorID.GT1FLeftToRightKeyDoor => dungeonData.Nodes[DungeonNodeID.GT1FLeftToRightKeyDoor],
                KeyDoorID.GT1FMapChestRoomKeyDoor => dungeonData.Nodes[DungeonNodeID.GT1FMapChestRoomKeyDoor],
                KeyDoorID.GT1FSpikeTrapPortalRoomKeyDoor => dungeonData.Nodes[DungeonNodeID.GT1FSpikeTrapPortalRoomKeyDoor],
                KeyDoorID.GT1FFiresnakeRoomKeyDoor => dungeonData.Nodes[DungeonNodeID.GT1FFiresnakeRoomKeyDoor],
                KeyDoorID.GT1FTileRoomKeyDoor => dungeonData.Nodes[DungeonNodeID.GT1FTileRoomKeyDoor],
                KeyDoorID.GT1FCollapsingWalkwayKeyDoor => dungeonData.Nodes[DungeonNodeID.GT1FCollapsingWalkwayKeyDoor],
                KeyDoorID.GT6FFirstKeyDoor => dungeonData.Nodes[DungeonNodeID.GT6FFirstKeyDoor],
                KeyDoorID.GT6FSecondKeyDoor => dungeonData.Nodes[DungeonNodeID.GT6FSecondKeyDoor],
                KeyDoorID.GTBigChest => dungeonData.Nodes[DungeonNodeID.GT1FBottomRoom],
                KeyDoorID.GT3FBigKeyDoor => dungeonData.Nodes[DungeonNodeID.GT3FBigKeyDoor],
                KeyDoorID.GT7FBigKeyDoor => dungeonData.Nodes[DungeonNodeID.GT6FPastBossRoomGap],
                _ => null
            });
Ejemplo n.º 18
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="factory">
 /// The key door factory.
 /// </param>
 /// <param name="dungeonData">
 /// The mutable dungeon data parent class.
 /// </param>
 public KeyDoorDictionary(IKeyDoorFactory.Factory factory, IMutableDungeon dungeonData)
     : base(new Dictionary <KeyDoorID, IKeyDoor>())
 {
     _dungeonData = dungeonData;
     _factory     = new Lazy <IKeyDoorFactory>(() => factory());
 }
Ejemplo n.º 19
0
 /// <summary>
 /// Returns whether the key layout is possible in the current game state.
 /// </summary>
 /// <param name="dungeonData">
 /// The dungeon mutable data.
 /// </param>
 /// <param name="smallKeys">
 /// A 32-bit signed integer representing the number of small keys collected.
 /// </param>
 /// <param name="bigKey">
 /// A boolean representing whether the big key was collected.
 /// </param>
 /// <returns>
 /// A boolean representing whether the key layout is possible.
 /// </returns>
 public bool CanBeTrue(IMutableDungeon dungeonData, int smallKeys, bool bigKey)
 {
     return(_requirement.Met);
 }
Ejemplo n.º 20
0
        /// <summary>
        /// Returns whether the key layout is possible in the current game state.
        /// </summary>
        /// <param name="dungeonData">
        /// The dungeon mutable data.
        /// </param>
        /// <param name="smallKeys">
        /// A 32-bit signed integer representing the number of small keys collected.
        /// </param>
        /// <param name="bigKey">
        /// A boolean representing whether the big key was collected.
        /// </param>
        /// <returns>
        /// A boolean representing whether the key layout is possible.
        /// </returns>
        public bool CanBeTrue(IMutableDungeon dungeonData, IDungeonState state)
        {
            if (dungeonData == null)
            {
                throw new ArgumentNullException(nameof(dungeonData));
            }

            if (!_requirement.Met)
            {
                return(false);
            }

            int accessible   = 0;
            int inaccessible = 0;

            foreach (var item in _bigKeyLocations)
            {
                switch (dungeonData.DungeonItems[item].Accessibility)
                {
                case AccessibilityLevel.SequenceBreak:
                {
                    if (state.SequenceBreak)
                    {
                        accessible++;
                    }
                    else
                    {
                        inaccessible++;
                    }
                }
                break;

                case AccessibilityLevel.Normal:
                {
                    accessible++;
                }
                break;

                default:
                {
                    inaccessible++;
                }
                break;
                }
            }

            if (state.BigKeyCollected && accessible == 0)
            {
                return(false);
            }

            if (!state.BigKeyCollected && inaccessible == 0)
            {
                return(false);
            }

            foreach (var child in _children)
            {
                if (child.CanBeTrue(dungeonData, state))
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 21
0
 /// <summary>
 /// Re-registers a dungeon data instance to the queue.
 /// </summary>
 /// <param name="dungeonData">
 /// The dungeon data instance to be registered to the queue.
 /// </param>
 private void ReturnDungeonData(IMutableDungeon dungeonData)
 {
     DungeonDataQueue.Enqueue(dungeonData);
 }
Ejemplo n.º 22
0
        /// <summary>
        /// Returns whether the key layout is possible in the current game state.
        /// </summary>
        /// <param name="dungeonData">
        /// The dungeon mutable data.
        /// </param>
        /// <param name="state">
        /// The dungeon state data.
        /// </param>
        /// <returns>
        /// A boolean representing whether the key layout is possible.
        /// </returns>
        public bool CanBeTrue(IMutableDungeon dungeonData, IDungeonState state)
        {
            if (dungeonData == null)
            {
                throw new ArgumentNullException(nameof(dungeonData));
            }

            if (!_requirement.Met)
            {
                return(false);
            }

            int inaccessible = 0;

            foreach (var item in _smallKeyLocations)
            {
                switch (dungeonData.DungeonItems[item].Accessibility)
                {
                case AccessibilityLevel.SequenceBreak:
                {
                    if (!state.SequenceBreak)
                    {
                        inaccessible++;
                    }
                }
                break;

                case AccessibilityLevel.Normal:
                    break;

                default:
                {
                    inaccessible++;
                }
                break;
                }
            }

            if (_bigKeyInLocations && !state.BigKeyCollected)
            {
                inaccessible--;
            }

            if (!ValidateMinimumKeyCount(state.KeysCollected, inaccessible))
            {
                return(false);
            }

            int dungeonSmallKeys = _mode.KeyDropShuffle ?
                                   _dungeon.SmallKeys + _dungeon.SmallKeyDrops.Count : _dungeon.SmallKeys;

            if (!ValidateMaximumKeyCount(dungeonSmallKeys, state.KeysCollected, inaccessible))
            {
                return(false);
            }

            foreach (var child in _children)
            {
                if (child.CanBeTrue(dungeonData, state))
                {
                    return(true);
                }
            }

            return(false);
        }