public void LoadSpriteGroups() { Loaded = true; for (int i = 0; i < 144; i++) { SpriteGroup sg = new SpriteGroup(romData, spriteRequirementsCollection, i); SpriteGroups.Add(sg); } }
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}"); } }