public Character() { Alignment = new Alignment(); Class = new CharacterClass(); Race = new Race(); InterestingTrait = string.Empty; Combat = new Combat(); Ability = new Ability(); Equipment = new Equipment(); Magic = new Magic(); }
private int GetAdjustedDexterityBonus(Dictionary<string, Stat> stats, Equipment equipment) { if (equipment.Armor == null) return stats[StatConstants.Dexterity].Bonus; var maxDexterityBonuses = adjustmentsSelector.SelectFrom(TableNameConstants.Set.Adjustments.MaxDexterityBonus); var armorBonus = maxDexterityBonuses[equipment.Armor.Name]; if (equipment.Armor.Traits.Contains(TraitConstants.SpecialMaterials.Mithral)) armorBonus += 2; return Math.Min(stats[StatConstants.Dexterity].Bonus, armorBonus); }
private int GetArmorBonus(Equipment equipment) { var armorBonus = 0; if (equipment.Armor != null) armorBonus += GetTotalItemArmorBonus(equipment.Armor); var itemNamesGrantingArmorBonuses = collectionsSelector.SelectFrom(TableNameConstants.Set.Collection.ArmorClassModifiers, GroupConstants.ArmorBonus); var itemsGrantingArmorBonus = equipment.Treasure.Items.Where(i => itemNamesGrantingArmorBonuses.Contains(i.Name)); if (itemsGrantingArmorBonus.Any() == false) return armorBonus; var maxArmorBonus = itemsGrantingArmorBonus.Max(i => i.Magic.Bonus); return Math.Max(armorBonus, maxArmorBonus); }
public ArmorClass GenerateWith(Equipment equipment, int adjustedDexterityBonus, IEnumerable<Feat> feats, Race race) { var armorClass = new ArmorClass(); armorClass.AdjustedDexterityBonus = adjustedDexterityBonus; armorClass.ArmorBonus = GetArmorBonus(equipment); armorClass.DeflectionBonus = GetDeflectionBonus(equipment.Treasure.Items); armorClass.DodgeBonus = GetDodgeBonus(feats); armorClass.NaturalArmorBonus = GetNaturalArmorBonus(equipment.Treasure.Items, feats, race); armorClass.ShieldBonus = GetShieldBonus(equipment); armorClass.SizeModifier = GetSizeModifier(race); var circumstantialDodgeBonus = IsDodgeBonusCircumstantial(feats); var circumstantialNaturalArmorBonus = IsNaturalArmorBonusCircumstantial(feats); armorClass.CircumstantialBonus = circumstantialDodgeBonus || circumstantialNaturalArmorBonus; return armorClass; }
public Combat GenerateWith(BaseAttack baseAttack, CharacterClass characterClass, Race race, IEnumerable<Feat> feats, Dictionary<String, Stat> stats, Equipment equipment) { var combat = new Combat(); combat.BaseAttack = baseAttack; combat.BaseAttack.BaseBonus += GetBonusFromFeats(feats); combat.BaseAttack.CircumstantialBonus = IsAttackBonusCircumstantial(feats); combat.AdjustedDexterityBonus = GetAdjustedDexterityBonus(stats, equipment); combat.ArmorClass = armorClassGenerator.GenerateWith(equipment, combat.AdjustedDexterityBonus, feats, race); if (stats.ContainsKey(StatConstants.Constitution)) combat.HitPoints = hitPointsGenerator.GenerateWith(characterClass, stats[StatConstants.Constitution].Bonus, race, feats); else combat.HitPoints = hitPointsGenerator.GenerateWith(characterClass, 0, race, feats); combat.SavingThrows = savingThrowsGenerator.GenerateWith(characterClass, feats, stats); combat.InitiativeBonus = GetInitiativeBonus(combat.AdjustedDexterityBonus, feats); return combat; }
public Equipment GenerateWith(IEnumerable<Feat> feats, CharacterClass characterClass, Race race) { var equipment = new Equipment(); var npcs = collectionsSelector.SelectFrom(TableNameConstants.Set.Collection.ClassNameGroups, GroupConstants.NPCs); var effectiveLevel = characterClass.Level; if (npcs.Contains(characterClass.Name)) effectiveLevel = Math.Max(effectiveLevel / 2, 1); equipment.Treasure = treasureGenerator.GenerateAtLevel(effectiveLevel); equipment.Armor = armorGenerator.GenerateArmorFrom(feats, characterClass, race); var twoWeaponFeats = collectionsSelector.SelectFrom(TableNameConstants.Set.Collection.FeatGroups, GroupConstants.TwoHanded); var hasTwoWeaponFeats = feats.Any(f => twoWeaponFeats.Contains(f.Name)); var meleeWeapons = collectionsSelector.SelectFrom(TableNameConstants.Set.Collection.ItemGroups, AttributeConstants.Melee); var twoHandedWeapons = collectionsSelector.SelectFrom(TableNameConstants.Set.Collection.ItemGroups, AttributeConstants.TwoHanded); var oneHandedMeleeWeapons = meleeWeapons.Except(twoHandedWeapons); var foci = feats.Where(f => f.Name != FeatConstants.WeaponFamiliarity).SelectMany(f => f.Foci); if (hasTwoWeaponFeats && foci.Intersect(oneHandedMeleeWeapons).Any()) { equipment.PrimaryHand = weaponGenerator.GenerateOneHandedMeleeFrom(feats, characterClass, race); equipment.OffHand = weaponGenerator.GenerateOneHandedMeleeFrom(feats, characterClass, race); } else { equipment.PrimaryHand = weaponGenerator.GenerateFrom(feats, characterClass, race); } var hasUnarmedStrikeFocus = foci.Any(f => f == FeatConstants.Foci.UnarmedStrike); if (equipment.PrimaryHand != null) { var baseWeaponTypes = collectionsSelector.SelectFrom(TableNameConstants.Set.Collection.ItemGroups, equipment.PrimaryHand.Name); if (WeaponRequiresAmmunition(baseWeaponTypes)) { var ammunitionType = baseWeaponTypes.Last(); var ammunition = weaponGenerator.GenerateAmmunition(feats, characterClass, race, ammunitionType); if (ammunition != null) equipment.Treasure.Items = equipment.Treasure.Items.Union(new[] { ammunition }); } if (equipment.PrimaryHand.Attributes.Contains(AttributeConstants.TwoHanded)) equipment.OffHand = equipment.PrimaryHand; if (equipment.PrimaryHand.Attributes.Contains(AttributeConstants.Melee) == false) { var meleeWeapon = weaponGenerator.GenerateMeleeFrom(feats, characterClass, race); if (meleeWeapon != null) { equipment.Treasure.Items = equipment.Treasure.Items.Union(new[] { meleeWeapon }); if (meleeWeapon.Attributes.Contains(AttributeConstants.TwoHanded) == false) { var shield = armorGenerator.GenerateShieldFrom(feats, characterClass, race); if (shield != null) equipment.Treasure.Items = equipment.Treasure.Items.Union(new[] { shield }); } } } else { var rangedWeapon = weaponGenerator.GenerateRangedFrom(feats, characterClass, race); if (rangedWeapon != null) { equipment.Treasure.Items = equipment.Treasure.Items.Union(new[] { rangedWeapon }); var baseRangedWeaponTypes = collectionsSelector.SelectFrom(TableNameConstants.Set.Collection.ItemGroups, rangedWeapon.Name); if (WeaponRequiresAmmunition(baseRangedWeaponTypes)) { var ammunitionType = baseRangedWeaponTypes.Last(); var ammunition = weaponGenerator.GenerateAmmunition(feats, characterClass, race, ammunitionType); if (ammunition != null) equipment.Treasure.Items = equipment.Treasure.Items.Union(new[] { ammunition }); } } } } if (equipment.OffHand == null && (equipment.PrimaryHand == null || equipment.PrimaryHand.Attributes.Contains(AttributeConstants.Melee))) equipment.OffHand = armorGenerator.GenerateShieldFrom(feats, characterClass, race); return equipment; }
public void Setup() { mockArmorClassGenerator = new Mock<IArmorClassGenerator>(); mockHitPointsGenerator = new Mock<IHitPointsGenerator>(); mockSavingThrowsGenerator = new Mock<ISavingThrowsGenerator>(); mockAdjustmentsSelector = new Mock<IAdjustmentsSelector>(); mockCollectionsSelector = new Mock<ICollectionsSelector>(); combatGenerator = new CombatGenerator(mockArmorClassGenerator.Object, mockHitPointsGenerator.Object, mockSavingThrowsGenerator.Object, mockAdjustmentsSelector.Object, mockCollectionsSelector.Object); characterClass = new CharacterClass(); feats = new List<Feat>(); stats = new Dictionary<string, Stat>(); equipment = new Equipment(); race = new Race(); maxDexterityBonuses = new Dictionary<string, int>(); sizeModifiers = new Dictionary<string, int>(); averageBaseAttacks = new List<string>(); goodBaseAttacks = new List<string>(); racialBaseAttackAdjustments = new Dictionary<string, int>(); initiativeFeats = new List<string>(); attackBonusFeats = new List<string>(); poorBaseAttacks = new List<string>(); characterClass.Name = "class name"; characterClass.Level = 20; race.Size = "size"; stats[StatConstants.Constitution] = new Stat(StatConstants.Constitution); stats[StatConstants.Constitution].Value = 9266; stats[StatConstants.Dexterity] = new Stat(StatConstants.Dexterity); stats[StatConstants.Dexterity].Value = 42; stats[StatConstants.Strength] = new Stat(StatConstants.Strength); stats[StatConstants.Strength].Value = 600; racialBaseAttackAdjustments[string.Empty] = 0; sizeModifiers[race.Size] = 0; maxDexterityBonuses[string.Empty] = 42; averageBaseAttacks.Add("other class name"); goodBaseAttacks.Add("other class name"); poorBaseAttacks.Add(characterClass.Name); mockAdjustmentsSelector.Setup(s => s.SelectFrom(TableNameConstants.Set.Adjustments.MaxDexterityBonus)).Returns(maxDexterityBonuses); mockAdjustmentsSelector.Setup(s => s.SelectFrom(TableNameConstants.Set.Adjustments.SizeModifiers)).Returns(sizeModifiers); mockCollectionsSelector.Setup(s => s.SelectFrom(TableNameConstants.Set.Collection.ClassNameGroups, GroupConstants.GoodBaseAttack)).Returns(goodBaseAttacks); mockCollectionsSelector.Setup(s => s.SelectFrom(TableNameConstants.Set.Collection.ClassNameGroups, GroupConstants.AverageBaseAttack)).Returns(averageBaseAttacks); mockCollectionsSelector.Setup(s => s.SelectFrom(TableNameConstants.Set.Collection.ClassNameGroups, GroupConstants.PoorBaseAttack)).Returns(poorBaseAttacks); mockCollectionsSelector.Setup(s => s.SelectFrom(TableNameConstants.Set.Collection.FeatGroups, GroupConstants.Initiative)).Returns(initiativeFeats); mockCollectionsSelector.Setup(s => s.SelectFrom(TableNameConstants.Set.Collection.FeatGroups, FeatConstants.AttackBonus)).Returns(attackBonusFeats); mockAdjustmentsSelector.Setup(s => s.SelectFrom(TableNameConstants.Set.Adjustments.RacialBaseAttackAdjustments)).Returns(racialBaseAttackAdjustments); }
public void Setup() { equipment = new Equipment(); }
private void SetUpGenerators() { mockAlignmentGenerator = new Mock<IAlignmentGenerator>(); mockAbilitiesGenerator = new Mock<IAbilitiesGenerator>(); mockCombatGenerator = new Mock<ICombatGenerator>(); mockTreasureGenerator = new Mock<IEquipmentGenerator>(); mockCharacterClassGenerator = new Mock<ICharacterClassGenerator>(); mockRaceGenerator = new Mock<IRaceGenerator>(); mockMagicGenerator = new Mock<IMagicGenerator>(); generator = new ConfigurableIterationGenerator(4); alignment = new Alignment(); characterClass = new CharacterClass(); race = new Race(); ability = new Ability(); equipment = new Equipment(); combat = new Combat(); baseAttack = new BaseAttack(); feats = new List<Feat>(); magic = new Magic(); alignment.Goodness = "goodness"; alignment.Lawfulness = "lawfulness"; characterClass.Level = 1; characterClass.Name = "class name"; race.BaseRace = BaseRace; race.Metarace = RaceConstants.Metaraces.None; ability.Feats = feats; ability.Stats["stat"] = new Stat("stat"); mockCombatGenerator.Setup(g => g.GenerateBaseAttackWith(It.IsAny<CharacterClass>(), It.IsAny<Race>(), It.IsAny<Dictionary<string, Stat>>())).Returns(() => new BaseAttack()); mockTreasureGenerator.Setup(g => g.GenerateWith(It.IsAny<IEnumerable<Feat>>(), It.IsAny<CharacterClass>(), It.IsAny<Race>())).Returns(() => new Equipment()); mockCombatGenerator.Setup(g => g.GenerateWith(It.IsAny<BaseAttack>(), It.IsAny<CharacterClass>(), It.IsAny<Race>(), It.IsAny<IEnumerable<Feat>>(), It.IsAny<Dictionary<string, Stat>>(), It.IsAny<Equipment>())).Returns(() => new Combat()); mockMagicGenerator.Setup(g => g.GenerateWith(It.IsAny<Alignment>(), It.IsAny<CharacterClass>(), It.IsAny<Race>(), It.IsAny<Dictionary<string, Stat>>(), It.IsAny<IEnumerable<Feat>>(), It.IsAny<Equipment>())).Returns(() => new Magic()); mockAlignmentGenerator.Setup(g => g.GenerateWith(mockAlignmentRandomizer.Object)).Returns(alignment); mockCharacterClassGenerator.Setup(g => g.GenerateWith(alignment, mockLevelRandomizer.Object, mockClassNameRandomizer.Object)).Returns(characterClass); mockCharacterClassGenerator.Setup(g => g.GenerateWith(alignment, mockSetLevelRandomizer.Object, mockClassNameRandomizer.Object)).Returns(characterClass); mockRaceGenerator.Setup(g => g.GenerateWith(alignment, characterClass, mockBaseRaceRandomizer.Object, mockMetaraceRandomizer.Object)).Returns(race); mockAbilitiesGenerator.Setup(g => g.GenerateStats(characterClass, race, mockStatsRandomizer.Object)).Returns(ability.Stats); mockAbilitiesGenerator.Setup(g => g.GenerateWith(characterClass, race, ability.Stats, baseAttack)).Returns(ability); mockTreasureGenerator.Setup(g => g.GenerateWith(ability.Feats, characterClass, race)).Returns(equipment); mockCombatGenerator.Setup(g => g.GenerateWith(baseAttack, characterClass, race, ability.Feats, ability.Stats, equipment)).Returns(combat); mockCombatGenerator.Setup(g => g.GenerateBaseAttackWith(characterClass, race, ability.Stats)).Returns(baseAttack); mockMagicGenerator.Setup(g => g.GenerateWith(alignment, characterClass, race, ability.Stats, ability.Feats, equipment)).Returns(magic); }
public void Setup() { mockAdjustmentsSelector = new Mock<IAdjustmentsSelector>(); mockCollectionsSelector = new Mock<ICollectionsSelector>(); armorClassGenerator = new ArmorClassGenerator(mockCollectionsSelector.Object, mockAdjustmentsSelector.Object); equipment = new Equipment(); feats = new List<Feat>(); armorBonuses = new Dictionary<string, int>(); sizeModifiers = new Dictionary<string, int>(); adjustedDexterityBonus = 0; race = new Race(); armorBonuses[string.Empty] = 0; mockAdjustmentsSelector.Setup(s => s.SelectFrom(TableNameConstants.Set.Adjustments.ArmorBonuses)).Returns(armorBonuses); mockAdjustmentsSelector.Setup(s => s.SelectFrom(TableNameConstants.Set.Adjustments.SizeModifiers)).Returns(sizeModifiers); mockCollectionsSelector.Setup(s => s.SelectFrom(TableNameConstants.Set.Collection.ArmorClassModifiers, GroupConstants.Size)) .Returns(Enumerable.Empty<string>()); mockCollectionsSelector.Setup(s => s.SelectFrom(TableNameConstants.Set.Collection.ArmorClassModifiers, GroupConstants.NaturalArmor)) .Returns(Enumerable.Empty<string>()); mockCollectionsSelector.Setup(s => s.SelectFrom(TableNameConstants.Set.Collection.ArmorClassModifiers, GroupConstants.Deflection)) .Returns(Enumerable.Empty<string>()); race.Size = "size"; sizeModifiers["size"] = 0; sizeModifiers["other size"] = 0; }
private int GetShieldBonus(Equipment equipment) { var shieldBonus = 0; if (equipment.OffHand != null && equipment.OffHand.ItemType == ItemTypeConstants.Armor && equipment.OffHand.Attributes.Contains(AttributeConstants.Shield)) shieldBonus += GetTotalItemArmorBonus(equipment.OffHand); return shieldBonus; }
public void Setup() { mockSpellsGenerator = new Mock<ISpellsGenerator>(); mockAnimalGenerator = new Mock<IAnimalGenerator>(); mockCollectionsSelector = new Mock<ICollectionsSelector>(); mockAdjustmentsSelector = new Mock<IAdjustmentsSelector>(); magicGenerator = new MagicGenerator(mockSpellsGenerator.Object, mockAnimalGenerator.Object, mockCollectionsSelector.Object, mockAdjustmentsSelector.Object); characterClass = new CharacterClass(); feats = new List<Feat>(); alignment = new Alignment(); race = new Race(); stats = new Dictionary<string, Stat>(); equipment = new Equipment(); arcaneSpellFailures = new Dictionary<string, int>(); classesThatPrepareSpells = new List<string>(); characterClass.Name = "class name"; classesThatPrepareSpells.Add(characterClass.Name); classesThatPrepareSpells.Add("other class"); mockAdjustmentsSelector.Setup(s => s.SelectFrom(TableNameConstants.Set.Adjustments.ArcaneSpellFailures)).Returns(arcaneSpellFailures); mockCollectionsSelector.Setup(s => s.SelectFrom(TableNameConstants.Set.Collection.ClassNameGroups, GroupConstants.PreparesSpells)).Returns(classesThatPrepareSpells); }