예제 #1
0
 public RoomCollection(RomData romData, Random rand, SpriteGroupCollection spriteGroupCollection, SpriteRequirementCollection spriteRequirementCollection)
 {
     this.romData = romData;
     this.rand    = rand;
     this.spriteGroupCollection       = spriteGroupCollection;
     this.spriteRequirementCollection = spriteRequirementCollection;
 }
예제 #2
0
 public Room(int roomId, RomData romData, SpriteGroupCollection spriteGroupCollection, SpriteRequirementCollection spriteRequirementCollection)
 {
     this.RoomId  = roomId;
     this.romData = romData;
     this.spriteGroupCollection       = spriteGroupCollection;
     this.spriteRequirementCollection = spriteRequirementCollection;
 }
예제 #3
0
        private void SetSpriteGroups(SpriteGroupCollection sg, SpriteRequirementCollection sr)
        {
            var req = sr.SpriteRequirements.FirstOrDefault(x => x.SpriteId == optionFlags.DebugForceEnemyId);
            var owg = sg.SpriteGroups.FirstOrDefault(x => x.GroupId == 7);
            var dg  = sg.SpriteGroups.FirstOrDefault(x => x.GroupId == 68);

            if (req != null)
            {
                if (req.SubGroup0.Count > 0)
                {
                    owg.SubGroup0 = req.SubGroup0.FirstOrDefault();
                    dg.SubGroup0  = req.SubGroup0.FirstOrDefault();
                }
                if (req.SubGroup1.Count > 0)
                {
                    owg.SubGroup1 = req.SubGroup1.FirstOrDefault();
                    dg.SubGroup1  = req.SubGroup1.FirstOrDefault();
                }
                if (req.SubGroup2.Count > 0)
                {
                    owg.SubGroup2 = req.SubGroup2.FirstOrDefault();
                    dg.SubGroup2  = req.SubGroup2.FirstOrDefault();
                }
                if (req.SubGroup3.Count > 0)
                {
                    owg.SubGroup3 = req.SubGroup3.FirstOrDefault();
                    dg.SubGroup3  = req.SubGroup3.FirstOrDefault();
                }
                else
                {
                    // give switches and traps a fighting chance if the sprite doesn't need slot 3
                    dg.SubGroup3 = 82;
                }
            }
        }
예제 #4
0
        public void RandomizeRoomSpriteGroups(SpriteGroupCollection spriteGroups)
        {
            foreach (var r in Rooms.Where(x => RoomIdConstants.DontRandomizeRooms.Contains(x.RoomId) == false))
            {
                List <SpriteRequirement> doNotUpdateSprites = spriteRequirementCollection
                                                              .DoNotRandomizeSprites
                                                              .Where(x => x.CanSpawnInRoom(r) &&
                                                                     r.Sprites.Select(y => y.SpriteId).ToList().Contains(x.SpriteId)
                                                                     )
                                                              .ToList();

                var possibleSpriteGroups = spriteGroups.GetPossibleDungeonSpriteGroups(r, doNotUpdateSprites).ToList();

                //Debug.Assert(possibleSpriteGroups.Count > 0);
                if (possibleSpriteGroups.Count > 0)
                {
                    r.GraphicsBlockId = possibleSpriteGroups[rand.Next(possibleSpriteGroups.Count)].DungeonGroupId;
                }
            }

            // force any rooms we need to
            foreach (var sg in spriteGroups.SpriteGroups.Where(x => x.ForceRoomsToGroup != null && x.ForceRoomsToGroup.Count > 0))
            {
                foreach (var forcedR in Rooms.Where(x => sg.ForceRoomsToGroup.Contains(x.RoomId)))
                {
                    forcedR.GraphicsBlockId = sg.DungeonGroupId;
                }
            }
        }
        public void RandomizeAreaSpriteGroups(SpriteGroupCollection spriteGroups)
        {
            // TODO: this needs to be updated???

            foreach (var a in OverworldAreas.Where(x => OverworldAreaConstants.DoNotRandomizeAreas.Contains(x.AreaId) == false))
            {
                List <SpriteRequirement> doNotUpdateSprites = spriteRequirementCollection
                                                              .DoNotRandomizeSprites
                                                              .Where(x => //x.CanSpawnInRoom(a)
                                                                          //&&
                                                                     a.Sprites.Select(y => y.SpriteId).ToList().Contains(x.SpriteId)
                                                                     )
                                                              .ToList();

                var possibleSpriteGroups = spriteGroups.GetPossibleOverworldSpriteGroups(doNotUpdateSprites).ToList();

                //Debug.Assert(possibleSpriteGroups.Count > 0);

                a.GraphicsBlockId = (byte)possibleSpriteGroups[rand.Next(possibleSpriteGroups.Count)].GroupId;
            }

            OverworldGroupRequirementCollection owReqs = new OverworldGroupRequirementCollection();

            // force any areas we need to
            foreach (var sg in owReqs.OverworldRequirements)
            {
                foreach (var forcedR in OverworldAreas.Where(x => sg.Areas.Contains(x.AreaId)))
                {
                    forcedR.GraphicsBlockId = (byte)sg.GroupId;
                }
            }
        }
예제 #6
0
        public void RandomizeRom(RomData romData, SpriteGroupCollection spriteGroupCollection, SpriteRequirementCollection spriteRequirementCollection)
        {
            FillDungeonPool();
            FillBossPool();

            GenerateRandomizedBosses();
            SetBossSpriteGroups(spriteGroupCollection, spriteRequirementCollection);
            WriteRom(romData);
        }
        public OverworldAreaCollection(RomData romData, Random rand, SpriteGroupCollection spriteGroupCollection, SpriteRequirementCollection spriteRequirementCollection)
        {
            this.romData = romData;
            this.rand    = rand;
            this.spriteGroupCollection       = spriteGroupCollection;
            this.spriteRequirementCollection = spriteRequirementCollection;

            LoadAreas();
        }
예제 #8
0
        public OverworldEnemyRandomizer(RomData romData, Random rand, SpriteGroupCollection spriteGroupCollection, SpriteRequirementCollection spriteRequirementCollection)
        {
            this.romData = romData;
            this.rand    = rand;
            this.spriteGroupCollection       = spriteGroupCollection;
            this.spriteRequirementCollection = spriteRequirementCollection;

            areas = new OverworldAreaCollection(romData, rand, spriteGroupCollection, spriteRequirementCollection);
        }
예제 #9
0
        public DungeonEnemyRandomizer(RomData romData, Random rand, SpriteGroupCollection spriteGroupCollection, SpriteRequirementCollection spriteRequirementCollection)
        {
            this.romData = romData;
            this.rand    = rand;
            this.spriteGroupCollection       = spriteGroupCollection;
            this.spriteRequirementCollection = spriteRequirementCollection;

            this.roomCollection = new RoomCollection(romData, rand, spriteGroupCollection, spriteRequirementCollection);
        }
예제 #10
0
        public void RandomizePotSprites(Random rand, SpriteGroupCollection spriteGroupCollection, SpriteRequirementCollection spriteRequirementCollection)
        {
            var spriteGroup = spriteGroupCollection.SpriteGroups.First(x => x.DungeonGroupId == this.GraphicsBlockId);

            var possibleSprites = spriteGroup.GetPossibleEnemySprites(this).Where(x => x.Overlord == false).Select(x => x.SpriteId).ToArray();

            if (possibleSprites.Length > 0)
            {
                romData[SpriteConstants.RandomizedPotEnemyTableBaseAddress + this.RoomId] = (byte)possibleSprites[rand.Next(possibleSprites.Length)];
            }
        }
예제 #11
0
        public void RandomizeRoomSpriteGroups(SpriteGroupCollection spriteGroups, OptionFlags optionFlags)
        {
            // skip rooms that are set to do not randomize because that would be pointless to process them
            foreach (var r in Rooms)
            {
                if (RoomIdConstants.DontRandomizeRooms.Contains(r.RoomId))
                {
                    continue;
                }

                if (optionFlags.EasyModeEscape && RoomIdConstants.NoSpecialEnemiesRoomsInStandardMode.Contains(r.RoomId))
                {
                    continue;
                }

                List <SpriteRequirement> doNotUpdateSprites = spriteRequirementCollection
                                                              .DoNotRandomizeSprites
                                                              .Where(x => x.CanSpawnInRoom(r) &&
                                                                     r.Sprites.Select(y => y.SpriteId).ToList().Contains(x.SpriteId)
                                                                     )
                                                              .ToList();

                /* TODO: put this back after I figure out what I screwed up
                 * List<SpriteRequirement> forcedSprites = spriteRequirementCollection.SpriteRequirements
                 *                          .Where(x => false == x.CanBeRandomizedInRoom(r))
                 *                          .Where(x => x.CanSpawnInRoom(r)
                 *                                      && r.Sprites.Select(y => y.SpriteId).ToList().Contains(x.SpriteId)
                 *                              )
                 *                          .ToList();
                 * doNotUpdateSprites.AddRange(forcedSprites);
                 *
                 * //*/


                var possibleSpriteGroups = spriteGroups.GetPossibleDungeonSpriteGroups(r, doNotUpdateSprites).ToList();

                //Debug.Assert(possibleSpriteGroups.Count > 0);
                if (possibleSpriteGroups.Count > 0)
                {
                    r.GraphicsBlockId = possibleSpriteGroups[rand.Next(possibleSpriteGroups.Count)].DungeonGroupId;
                }
            }

            // force any rooms we need to
            foreach (var sg in spriteGroups.SpriteGroups.Where(x => x.ForceRoomsToGroup != null && x.ForceRoomsToGroup.Count > 0))
            {
                foreach (var forcedR in Rooms.Where(x => sg.ForceRoomsToGroup.Contains(x.RoomId)))
                {
                    forcedR.GraphicsBlockId = sg.DungeonGroupId;
                }
            }
        }
예제 #12
0
 void SetBossSpriteGroups(SpriteGroupCollection spriteGroupCollection, SpriteRequirementCollection spriteRequirementCollection)
 {
     foreach (var d in this.DungeonPool)
     {
         var group  = spriteGroupCollection.SpriteGroups.Where(x => x.DungeonGroupId == d.SelectedBoss.BossGraphics).FirstOrDefault();
         var sprite = spriteRequirementCollection.SpriteRequirements.Where(x => x.SpriteId == d.SelectedBoss.BossSpriteId).FirstOrDefault();
         if (group != null && sprite != null)
         {
             group.PreserveSubGroup0 = sprite.SubGroup0.Count > 0;
             group.PreserveSubGroup1 = sprite.SubGroup1.Count > 0;
             group.PreserveSubGroup2 = sprite.SubGroup2.Count > 0;
             group.PreserveSubGroup3 = sprite.SubGroup3.Count > 0;
         }
     }
 }
예제 #13
0
        public OverworldArea(RomData romData, int AreaId, Random rand, SpriteGroupCollection spriteGroupCollection, SpriteRequirementCollection spriteRequirementCollection)
        {
            this.romData = romData;
            this.AreaId  = AreaId;
            this.spriteGroupCollection       = spriteGroupCollection;
            this.spriteRequirementCollection = spriteRequirementCollection;
            this.rand = rand;

            int spriteTableBaseSnesAddress = (09 << 16) // bank 9
                                             + (romData[AddressConstants.OverworldSpritePointerTableBaseAddress + (AreaId * 2) + 1] << 8)
                                             + (romData[AddressConstants.OverworldSpritePointerTableBaseAddress + (AreaId * 2)]);

            SpriteTableBaseAddress = Utilities.SnesToPCAddress(spriteTableBaseSnesAddress);

            LoadGraphicsBlock();
            LoadSprites();
        }
예제 #14
0
        public void SetDebugMode()
        {
            var rand = new Random();
            var sr   = new SpriteRequirementCollection();
            var sg   = new SpriteGroupCollection(romData, rand, sr);

            sg.LoadSpriteGroups();
            var rc  = new RoomCollection(romData, rand, sg, sr);
            var owa = new OverworldAreaCollection(romData, rand, sg, sr);

            rc.LoadRooms();

            if (optionFlags.DebugForceBoss)
            {
                // this is set in the boss randomizer because there is too much to do after picking a boss
            }
            if (optionFlags.DebugForceEnemy)
            {
                SetDungeonEnemy(rc);
                SetOverworldEnemy(owa);
                SetSpriteGroups(sg, sr);
            }
            if (optionFlags.DebugOpenShutterDoors)
            {
                RemoveKillRooms(rc);
            }
            if (optionFlags.DebugForceEnemyDamageZero)
            {
                SetEnemyDamageZero();
            }

            if (optionFlags.DebugShowRoomIdInRupeeCounter)
            {
                // put the room id in the rupee slot
                this.romData[0x1017A9]     = 0xA0;
                this.romData[0x1017A9 + 1] = 0x00;
                this.romData[0x1017A9 + 2] = 0x7E;
            }

            rc.UpdateRom();
            owa.UpdateRom();
            sg.UpdateRom();
        }
예제 #15
0
        public void RandomizeSprites(Random rand, OptionFlags optionFlags, SpriteGroupCollection spriteGroupCollection, SpriteRequirementCollection spriteRequirementCollection)
        {
            SpriteGroup spriteGroup = null;

            int[] possibleSprites = new int[0];

            spriteGroup = spriteGroupCollection.SpriteGroups.First(x => x.DungeonGroupId == this.GraphicsBlockId);

            possibleSprites = spriteGroup.GetPossibleEnemySprites(this, optionFlags).Select(x => x.SpriteId).ToArray();

            if (possibleSprites.Length > 0)
            {
                var spritesToUpdate = this.Sprites.Where(x => spriteRequirementCollection.RandomizableSprites.Select(y => y.SpriteId).Contains(x.SpriteId))
                                      .ToList();

                // TODO: something less hacky for shutters.
                var keySprites     = spritesToUpdate.Where(x => x.HasAKey).ToList();
                var shutterSprites = spritesToUpdate.Where(x => this.IsShutterRoom && !x.HasAKey).ToList();

                var killableSprites    = spriteRequirementCollection.KillableSprites.Where(x => possibleSprites.Contains(x.SpriteId)).Select(x => x.SpriteId).ToList();
                var killableKeySprites = spriteRequirementCollection.KillableSprites.Where(x => x.CannotHaveKey == false && possibleSprites.Contains(x.SpriteId)).Select(x => x.SpriteId).ToList();
                var waterSprites       = spriteRequirementCollection.WaterSprites.Where(x => possibleSprites.Contains(x.SpriteId)).Select(x => x.SpriteId).ToList();

                if (keySprites.Count > 0 && killableKeySprites.Count == 0)
                {
                    throw new Exception("Key in room without any killable enemies");
                }
                if (shutterSprites.Count > 0 && killableSprites.Count == 0)
                {
                    throw new Exception("Shutter room without any killable enemies");
                }
                if (this.IsWaterRoom && waterSprites.Count == 0)
                {
                    throw new Exception("Water room without any water sprites");
                }

                Debug.Assert(possibleSprites.Contains(SpriteConstants.EmptySprite) == false);
                Debug.Assert(killableSprites.Contains(SpriteConstants.EmptySprite) == false);
                Debug.Assert(killableKeySprites.Contains(SpriteConstants.EmptySprite) == false);
                Debug.Assert(waterSprites.Contains(SpriteConstants.EmptySprite) == false);

                int[] possibleAbsorbableSprites = GetAbsorbableSprites(spriteRequirementCollection, optionFlags);
                int   stalCount = 0;

                if (this.IsWaterRoom)
                {
                    spritesToUpdate.ToList()
                    .ForEach(x => x.SpriteId = waterSprites[rand.Next(waterSprites.Count)]);

                    return;
                }
                else
                {
                    // remove water sprites
                    possibleSprites = possibleSprites.Where(x => waterSprites.Contains(x) == false).ToArray();
                }

                foreach (var s in spritesToUpdate.Where(x => x.HasAKey == false).ToList())
                {
                    int spriteId = -1;

                    // don't put stal in shutter rooms
                    if (false == this.IsShutterRoom && rand.Next(0, 100) <= 5)
                    {
                        //spawn a stal
                        spriteId = SpriteConstants.StalSprite;
                    }
                    else
                    {
                        spriteId = possibleSprites[rand.Next(possibleSprites.Length)];
                    }

                    if (optionFlags.EnemiesAbsorbable && optionFlags.AbsorbableSpawnRate > 0 && optionFlags.AbsorbableTypes.Where(x => x.Value).Count() > 0)
                    {
                        if (rand.Next(0, 100) <= optionFlags.AbsorbableSpawnRate)
                        {
                            spriteId = possibleAbsorbableSprites[rand.Next(possibleAbsorbableSprites.Length)];
                        }
                    }

                    s.SpriteId = spriteId;

                    if (spriteId == SpriteConstants.StalSprite)
                    {
                        stalCount++;
                        if (stalCount > 2)// && possibleSprites.Count() > 1) // max 2 in a room
                        {
                            possibleSprites = possibleSprites.Where(x => x != SpriteConstants.StalSprite).ToArray();
                        }
                    }
                    //*/
                }

                spritesToUpdate.Where(x => x.HasAKey).ToList()
                .ForEach(x => x.SpriteId = killableKeySprites[rand.Next(killableKeySprites.Count)]);

                // TODO: something less hacky for shutters.
                spritesToUpdate.Where(x => !x.HasAKey && this.IsShutterRoom).ToList()
                .ForEach(x => x.SpriteId = killableSprites[rand.Next(killableSprites.Count)]);
            }
            else if (!RoomIdConstants.BossRooms.Contains(this.RoomId))
            {
                // TODO: log this because it's not a boss room
                Debug.WriteLine($"Skipped randomizing sprites in room {this.RoomId}");
            }
        }