Beispiel #1
0
        public IEnumerable <SpriteRequirement> GetPossibleEnemySprites(Room room, OptionFlags optionFlags = null)
        {
            // TODO: add more logic to this?
            // needs to check for two subgroups, etc.

            return(spriteRequirementsCollection.GetUsableDungeonEnemySprites().Where(x => x.SpriteInGroup(this) && x.CanSpawnInRoom(room)));
        }
        public void RandomizeDungeonEnemies(OptionFlags optionFlags)
        {
            GenerateGroups();

            RandomizeRooms(optionFlags);

            WriteRom();
        }
Beispiel #3
0
 public BossRandomizer(Random rand, OptionFlags optionFlags, StringBuilder spoilerFile, Graph graph)
 {
     this.rand        = rand;
     this.optionFlags = optionFlags;
     this.spoilerFile = spoilerFile;
     this.graph       = graph;
     this.bossPool    = new BossPool(rand);
 }
Beispiel #4
0
        public void SetRomInfoOptionFlags(OptionFlags optionFlags)
        {
            var optionByteArray = optionFlags.ToByteArray();

            if (optionByteArray.Length > 0x100 - EnemizerInfoFlagsOffset)
            {
                throw new Exception("Option flags is too long to fit in the space allocated. Need to move data/code in asm file.");
            }
            Array.Copy(optionByteArray, 0, romData, EnemizerInfoTableBaseAddress + EnemizerInfoFlagsOffset, optionByteArray.Length);
            SetPatchBytes(EnemizerInfoTableBaseAddress + EnemizerInfoFlagsOffset, optionByteArray.Length);
        }
        public void RandomizeOverworldEnemies(OptionFlags optionFlags)
        {
            // TODO: replace this with something less hard coded because we also need to move squirrels and stuff in MS glade and probably Zora
            romData[0x04CF4F] = 0x10; //move bird from tree stump in lost woods // TODO: did this cause a crash?

            GenerateGroups();

            RandomizeAreas(optionFlags);

            WriteRom();
        }
        private void RandomizeAreas(OptionFlags optionFlags)
        {
            areas.RandomizeAreaSpriteGroups(spriteGroupCollection);

            foreach (var area in areas.OverworldAreas.Where(x => OverworldAreaConstants.DoNotRandomizeAreas.Contains(x.AreaId) == false))
            {
                // pick random sprite group
                //area.GraphicsBlockId = ??;
                area.RandomizeSprites(optionFlags);
                area.RandomizeBushSprite();
            }
        }
Beispiel #7
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;
                }
            }
        }
Beispiel #8
0
        public void RandomizeSprites(OptionFlags optionFlags)
        {
            var spriteGroup = spriteGroupCollection.SpriteGroups.First(x => x.GroupId == this.GraphicsBlockId);

            var 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();

                spritesToUpdate /*.Where(x => x.SpriteId != SpriteConstants.RavenSprite)*/.ToList()
                .ForEach(x => x.SpriteId = possibleSprites[rand.Next(possibleSprites.Length)]);

                if (spritesToUpdate.Count(x => x.SpriteId == SpriteConstants.FloppingFishSprite) > 1)
                {
                    possibleSprites = possibleSprites.Where(x => x != SpriteConstants.FloppingFishSprite).ToArray();

                    if (possibleSprites.Length > 0)
                    {
                        bool first = true;
                        foreach (var s in spritesToUpdate.Where(x => x.SpriteId == SpriteConstants.FloppingFishSprite).ToList())
                        {
                            if (first)
                            {
                                first = false;
                                continue;
                            }

                            s.SpriteId = possibleSprites[rand.Next(possibleSprites.Length)];
                        }
                    }
                }

                // Kodongo are not allowed in overworld for now, until ASM can be fixed, then this won't be needed at all.

                /*
                 * // Kodongo in Raven place will crash the game
                 * possibleSprites = possibleSprites.Where(x => x != SpriteConstants.KodongosSprite).ToArray();
                 *
                 * if (possibleSprites.Length == 0)
                 * {
                 *  // TODO: should throw an error but let's just leave it for now
                 *  return;
                 * }
                 * spritesToUpdate.Where(x => x.SpriteId == SpriteConstants.RavenSprite).ToList()
                 *  .ForEach(x => x.SpriteId = possibleSprites[rand.Next(possibleSprites.Length)]);
                 * //*/
            }
        }
Beispiel #9
0
 void UpdateFromOptions(OptionFlags optionFlags, RawRoomEdgeCollection rawRoomEdgeCollection)
 {
     if (optionFlags.RandomizeEnemies &&
         (optionFlags.RandomizeEnemiesType == RandomizeEnemiesType.Chaos ||
          optionFlags.RandomizeEnemiesType == RandomizeEnemiesType.Insanity))   // TODO: what else?
     {
         foreach (var r in rawRoomEdgeCollection.RawRoomEdges.Where(x => x.requirements.Contains("Bow")))
         {
             r.requirements = r.requirements.Replace(",Bow,", "");
             r.requirements = r.requirements.Replace("Bow,", "");
             r.requirements = r.requirements.Replace(",Bow", "");
             r.requirements = r.requirements.Replace("Bow", "");
         }
     }
 }
        private void RandomizeRooms(OptionFlags optionFlags)
        {
            roomCollection.LoadRooms();

            roomCollection.RandomizeRoomSpriteGroups(spriteGroupCollection);

            foreach (var room in roomCollection.Rooms.Where(x => RoomIdConstants.DontRandomizeRooms.Contains(x.RoomId) == false))
            {
                room.RandomizeSprites(rand, optionFlags, spriteGroupCollection, spriteRequirementCollection);

                // randomize the pot sprite table
                // this isn't actually used yet (needs asm changes), but we will write it anyways
                room.RandomizePotSprites(rand, spriteGroupCollection, spriteRequirementCollection);
            }
        }
Beispiel #11
0
        public GraphData(RomData romData, OptionFlags optionFlags, RomEntranceCollection romEntrances, RomExitCollection romExits, RomChestCollection romChests)
        {
            this.romData      = romData;
            this.romEntrances = romEntrances;
            this.romExits     = romExits;
            this.romChests    = romChests;

            RawEntranceCollection     rawEntranceCollection     = new RawEntranceCollection();
            RawExitCollection         rawExitCollection         = new RawExitCollection();
            RawItemLocationCollection rawItemLocationCollection = new RawItemLocationCollection();
            RawItemEdgeCollection     rawItemEdgeCollection     = new RawItemEdgeCollection();
            RawRoomEdgeCollection     rawRoomEdgeCollection     = new RawRoomEdgeCollection();

            romChests.LoadChests(rawItemLocationCollection);

            UpdateFromRom(rawEntranceCollection, rawExitCollection, rawItemLocationCollection, rawItemEdgeCollection);
            UpdateFromOptions(optionFlags, rawRoomEdgeCollection);
            FillNodesAndEdges(rawEntranceCollection, rawExitCollection, rawItemLocationCollection, rawItemEdgeCollection, rawRoomEdgeCollection);

            _rawItemLocationCollection = rawItemLocationCollection;
        }
        private void RandomizeRooms(OptionFlags optionFlags)
        {
            roomCollection.LoadRooms();
            roomCollection.RandomizeRoomSpriteGroups(spriteGroupCollection, optionFlags);

            foreach (var room in roomCollection.Rooms)
            {
                if (RoomIdConstants.DontRandomizeRooms.Contains(room.RoomId))
                {
                    continue;
                }

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

                room.RandomizeSprites(rand, optionFlags, spriteGroupCollection, spriteRequirementCollection);

                // randomize the pot sprite table
                // this isn't actually used yet (needs asm changes), but we will write it anyways
                room.RandomizePotSprites(rand, spriteGroupCollection, spriteRequirementCollection);
            }
        }
Beispiel #13
0
 public Bees(RomData romData, OptionFlags optionFlags, Random rand)
 {
     this.romData     = romData;
     this.optionFlags = optionFlags;
     this.rand        = rand;
 }
Beispiel #14
0
        public IEnumerable <SpriteRequirement> GetPossibleEnemySprites(OverworldArea area, OptionFlags optionFlags = null)
        {
            // TODO: add more logic to this?
            // needs to check for two subgroups, etc.

            return(spriteRequirementsCollection.GetUsableOverworldEnemySprites().Where(x => x.SpriteInGroup(this)));
        }
Beispiel #15
0
 public DebugMode(RomData romData, OptionFlags optionFlags)
 {
     this.romData     = romData;
     this.optionFlags = optionFlags;
 }
 public ManualBossRandomizer(Random rand, OptionFlags optionFlags, StringBuilder spoilerFile, Graph graph) : base(rand, optionFlags, spoilerFile, graph)
 {
 }
Beispiel #17
0
 public GraphData(RomData romData, OptionFlags optionFlags)
     : this(romData, optionFlags, new RomEntranceCollection(romData), new RomExitCollection(romData), new RomChestCollection(romData))
 {
 }
Beispiel #18
0
 public OverworldGlitchedGraphData(RomData romData, OptionFlags optionFlags, RomEntranceCollection romEntrances, RomExitCollection romExits, RomChestCollection romChests)
     : base(romData, optionFlags, romEntrances, romExits, romChests)
 {
 }
Beispiel #19
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}");
            }
        }
 public ChaosBossRandomizer(Random rand, OptionFlags optionFlags, StringBuilder spoilerFile, Graph graph)
     : base(rand, optionFlags, spoilerFile, graph)
 {
     this.bossPool = new ChaosBossPool(rand);
 }
Beispiel #21
0
        public int[] GetAbsorbableSprites(SpriteRequirementCollection spriteRequirementCollection, OptionFlags optionFlags)
        {
            var absorbables = spriteRequirementCollection.SpriteRequirements
                              .Where(x => x.Absorbable == true)
                              .Where(x => optionFlags.AbsorbableTypes
                                     .Where(y => y.Value)
                                     .Select(y => (int)y.Key + 0xD8)
                                     .Contains(x.SpriteId)
                                     )
                              .Select(x => x.SpriteId)
                              .ToArray();

            return(absorbables);
        }