public void LoadSpriteGroups()
        {
            Loaded = true;

            for (int i = 0; i < 144; i++)
            {
                SpriteGroup sg = new SpriteGroup(romData, spriteRequirementsCollection, i);

                SpriteGroups.Add(sg);
            }
        }
Exemple #2
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}");
            }
        }