예제 #1
0
        public void should_load_all_sprites_groups()
        {
            Random rand = new Random(0);

            RomData romData            = Utilities.LoadRom("rando.sfc");
            var     spriteRequirements = new SpriteRequirementCollection();

            SpriteGroupCollection sgc = new SpriteGroupCollection(romData, rand, spriteRequirements);

            sgc.LoadSpriteGroups();
            sgc.RandomizeDungeonGroups();
            sgc.UpdateRom();

            foreach (var sg in sgc.SpriteGroups)
            {
                output.WriteLine($"SpriteGroupID: {sg.GroupId} (Dungeon GroupId: {sg.DungeonGroupId}), Sub0: {sg.SubGroup0} Sub1: {sg.SubGroup1} Sub2: {sg.SubGroup2} Sub3: {sg.SubGroup3} ");
                if (sg.GroupId == 77)
                {
                    Assert.Equal(81, sg.SubGroup0);
                }
            }
        }
예제 #2
0
        private void loadRomButton_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();

            if (ofd.ShowDialog() == true)
            {
                RomData romData            = LoadRom(ofd.FileName);
                var     spriteRequirements = new SpriteRequirementCollection();

                SpriteGroupCollection sgc = new SpriteGroupCollection(romData, new Random(), spriteRequirements);
                sgc.LoadSpriteGroups();

                RoomCollection rc = new RoomCollection(romData, new Random(), spriteRequirements);
                rc.LoadRooms();

                var vm = new VM();
                vm.spriteGroupCollection = sgc;
                vm.roomCollection        = rc;

                this.DataContext = vm;
            }
        }
예제 #3
0
 public RoomCollection(RomData romData, Random rand, SpriteGroupCollection spriteGroupCollection, SpriteRequirementCollection spriteRequirementCollection)
 {
     this.romData = romData;
     this.rand    = rand;
     this.spriteGroupCollection       = spriteGroupCollection;
     this.spriteRequirementCollection = spriteRequirementCollection;
 }
예제 #4
0
 public SpriteGroup(RomData romData, SpriteRequirementCollection spriteRequirementsCollection, int groupId, params int[] forcedRooms)
     : this(romData, spriteRequirementsCollection, groupId)
 {
     this.ForceRoomsToGroup.AddRange(forcedRooms);
 }
예제 #5
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)];
            }
        }
예제 #6
0
 public Room(int roomId, RomData romData, SpriteGroupCollection spriteGroupCollection, SpriteRequirementCollection spriteRequirementCollection)
 {
     this.RoomId  = roomId;
     this.romData = romData;
     this.spriteGroupCollection       = spriteGroupCollection;
     this.spriteRequirementCollection = spriteRequirementCollection;
 }
예제 #7
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}");
            }
        }
예제 #8
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();
        }
예제 #9
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();
        }
예제 #11
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);
        }
예제 #12
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);
        }