public void CreatureWithSpellLikeAbilityAttack_HasSpellLikeAbilitySpecialQuality(string creature) { Assert.That(table, Contains.Key(creature)); foreach (var entry in table[creature]) { var valid = helper.ValidateEntry(entry); Assert.That(valid, Is.True, $"Invalid entry: {entry}"); } var creatureType = GetCreatureType(creature); var specialQualities = featsSelector.SelectSpecialQualities(creature, creatureType); var hasSpellLikeAbilityAttack = table[creature] .Select(helper.ParseEntry) .Any(d => d[DataIndexConstants.AttackData.NameIndex] == FeatConstants.SpecialQualities.SpellLikeAbility); //INFO: Want to ignore constant effects such as Doppelganger's Detect Thoughts and Copper Dragon's Spider Climb var hasSpellLikeAbilitySpecialQuality = specialQualities.Any(q => q.Feat == FeatConstants.SpecialQualities.SpellLikeAbility && q.Frequency.TimePeriod != FeatConstants.Frequencies.Constant); Assert.That(hasSpellLikeAbilityAttack, Is.EqualTo(hasSpellLikeAbilitySpecialQuality)); }
public IEnumerable <Feat> GenerateSpecialQualities( string creatureName, CreatureType creatureType, HitPoints hitPoints, Dictionary <string, Ability> abilities, IEnumerable <Skill> skills, bool canUseEquipment, string size, Alignment alignment) { var specialQualitySelections = featsSelector.SelectSpecialQualities(creatureName, creatureType); var specialQualities = new List <Feat>(); var previousCount = specialQualities.Count; var pickedSelections = new List <SpecialQualitySelection>(); do { previousCount = specialQualities.Count; foreach (var specialQualitySelection in specialQualitySelections) { if (!specialQualitySelection.RequirementsMet(abilities, specialQualities, canUseEquipment, size, alignment, hitPoints)) { continue; } pickedSelections.Add(specialQualitySelection); var specialQuality = new Feat(); specialQuality.Name = specialQualitySelection.Feat; specialQuality.Foci = GetFoci(specialQualitySelection, skills, abilities); specialQuality.Frequency = specialQualitySelection.Frequency; specialQuality.Power = specialQualitySelection.Power; if (!string.IsNullOrEmpty(specialQualitySelection.SaveAbility)) { specialQuality.Save = new SaveDieCheck(); specialQuality.Save.BaseAbility = abilities[specialQualitySelection.SaveAbility]; specialQuality.Save.Save = specialQualitySelection.Save; specialQuality.Save.BaseValue = specialQualitySelection.SaveBaseValue; } specialQualities.Add(specialQuality); } specialQualitySelections = specialQualitySelections .Except(pickedSelections) .ToArray(); } while (previousCount != specialQualities.Count && specialQualitySelections.Any()); //HACK: Handling this usecase because the orc creature and orc creature type are identical if (creatureName == CreatureConstants.Orc_Half) { var lightSensitivity = specialQualities.First(f => f.Name == FeatConstants.SpecialQualities.LightSensitivity); specialQualities.Remove(lightSensitivity); } //HACK: Requirements can't handle "remove this", so doing so here for particular use cases var blindFeatNames = new[] { FeatConstants.SpecialQualities.Blindsense, FeatConstants.SpecialQualities.Blindsight, }; var visionFeatNames = new[] { FeatConstants.SpecialQualities.Darkvision, FeatConstants.SpecialQualities.AllAroundVision, FeatConstants.SpecialQualities.LowLightVision, FeatConstants.SpecialQualities.LowLightVision_Superior, }; var blindFeats = specialQualities.Where(f => blindFeatNames.Contains(f.Name)); if (blindFeats.Any()) { specialQualities = specialQualities .Where(f => !visionFeatNames.Contains(f.Name)) .ToList(); } return(specialQualities); }