class GiantBat(Animal): name = "Giant Bat" hit_dice = dice.D8(2) attack_bonus = AttackBonusTable.get_by_hit_dice(hit_dice.amount) attack_sets = [AttackSet(Bite(dice.D4(1)))] base_armor_class = 14 morale = 8 movement = movement.MovementSet(walk=units.FeetPerGameTurn(10), fly=units.FeetPerGameTurn(60)) no_appearing = AppearingSet(dice_dungeon=dice.D10(1), dice_wild=dice.D10(1), dice_lair=dice.D10(1)) save_as = Fighter.level_table.levels[hit_dice.amount].saving_throws_set xp = 75
class TwoHandedSword(MeleeWeapon): name = "Two-Handed Sword" melee_damage = dice.D10(1) price = coins.Gold(18) size = Size.Large weight = units.Pound(10)
class Polearm(MeleeWeapon): name = "Polearm" melee_damage = dice.D10(1) price = coins.Gold(9) size = Size.Large weight = units.Pound(15)
class GreatAxe(Axe): name = "Great Axe" melee_damage = dice.D10(1) price = coins.Gold(14) size = Size.Large weight = units.Pound(15)
class Maul(Bludgeon): name = "Maul" melee_damage = dice.D10(1) price = coins.Gold(10) size = Size.Large weight = units.Pound(16)
class Goblin(Humanoid): name = "Goblin" hit_dice = dice.D1(1) attack_bonus = AttackBonusTable.get_by_hit_dice(1) attack_sets = None base_armor_class = 11 morale = 7 movement = movement.MovementSet(walk=units.FeetPerGameTurn(30)) no_appearing = AppearingSet(dice_dungeon=dice.D4(2), dice_wild=dice.D10(6), dice_lair=dice.D10(6)) save_as = Fighter.level_table.levels[hit_dice.amount].saving_throws_set special_abilities = SpecialAbilitySet((Darkvision, )) size = Size.Small weight = units.Pound(45) xp = 10
class Moose(Animal): name = "Moose" hit_dice = dice.D8(3) attack_bonus = AttackBonusTable.get_by_hit_dice(hit_dice.amount) attack_sets = [AttackSet(Headbutt(dice.D6(1)))] base_armor_class = 13 morale = 5 movement = movement.MovementSet(walk=units.FeetPerGameTurn(80), turning_distance=units.Feet(10)) no_appearing = AppearingSet(dice_wild=dice.D10(3)) save_as = Fighter.level_table.levels[hit_dice.amount].saving_throws_set xp = 145
class Deer(Antelope): name = "Deer" hit_dice = dice.D8(1) attack_bonus = AttackBonusTable.get_by_hit_dice(hit_dice.amount) attack_sets = [AttackSet(Headbutt(dice.D4(1)))] base_armor_class = 13 morale = 5 movement = movement.MovementSet(walk=units.FeetPerGameTurn(80), turning_distance=units.Feet(10)) no_appearing = AppearingSet(dice_wild=dice.D10(3)) save_as = Fighter.level_table.levels[hit_dice.amount].saving_throws_set size = Size.Medium weight = units.Pound(220) xp = 25
class RidingHorse(Horse): name = "Riding Horse" attack_bonus = AttackBonusTable.get_by_hit_dice(2) attack_sets = [AttackSet(Hoof(dice.D4(1)), amount=2)] base_armor_class = 13 carry_capacity = CarryCapacity(units.Pound(250), units.Pound(500)) hit_dice = dice.D8(2) morale = 7 movement = movement.MovementSet(walk=units.FeetPerGameTurn(80), turning_distance=units.Feet(10)) no_appearing = AppearingSet(dice_wild=dice.D10(10)) save_as = Fighter.level_table.levels[2].saving_throws_set special_abilities = None treasure_type = None xp = 75
class GemsAndJewelryQualityTable(object): rows = [ GJQRow(0, 20, QualityType.Ornamental, 10, dice.D10(1)), GJQRow(21, 45, QualityType.Semiprecious, 50, dice.D8(1)), GJQRow(46, 75, QualityType.Fancy, 100, dice.D6(1)), GJQRow(76, 95, QualityType.Precious, 500, dice.D4(1)), GJQRow(96, 100, QualityType.Gem, 1000, dice.D2(1)), GJQRow(None, None, QualityType.Fancy, 5000, 1), ] _inner_table = {row.quality_type: row for row in rows} @classmethod def get_row_from_percent(cls, percent): return next((row for row in cls.rows if row.min_percent <= percent <= row.max_percent)) @classmethod def get_row_from_quality(cls, quality_type): return cls._inner_table.get(quality_type)
class Skeleton(Undead): name = "Skeleton" hit_dice = dice.D8(1) attack_bonus = AttackBonusTable.get_by_hit_dice(hit_dice.amount) base_armor_class = 13 morale = 12 movement = movement.MovementSet(walk=units.FeetPerGameTurn(40)) no_appearing = AppearingSet(dice_dungeon=dice.D6(3), dice_wild=dice.D10(3)) save_as = Fighter.level_table.levels[hit_dice.amount].saving_throws_set size = Size.Medium special_abilities = (specialabilities.EdgedWeaponResistance, specialabilities.ProjectileResistance, specialabilities.SleepImmunity, specialabilities.CharmImmunity, specialabilities.HoldImmunity, specialabilities.Mindless) treasure_type = None weight = units.Pound(100) xp = 25
class PolarBear(Bear): name = "Polar Bear" hit_dice = dice.D8(6) attack_bonus = AttackBonusTable.get_by_hit_dice(hit_dice.amount) attack_sets = [ AttackChain( AttackSet(Claw(dice.D6(1)), amount=2, special_properties=specialproperties.BearHug), AttackSet(Bite(dice.D10(1))) ), AttackSet(Crush(dice.D8(2))) ] base_armor_class = 14 morale = 8 movement = movement.MovementSet(walk=units.FeetPerGameTurn(40)) no_appearing = AppearingSet(dice_dungeon=dice.D1(1), dice_wild=dice.D2(1), dice_lair=dice.D2(1)) save_as = Fighter.level_table.levels[hit_dice.amount].saving_throws_set special_abilities = SpecialAbilitySet((LastBreath,)) size = Size.Large weight = units.Pound(992) xp = 500
class Basilisk(Reptilian): name = "Basilisk" hit_dice = dice.D8(6) attack_bonus = AttackBonusTable.get_by_hit_dice(hit_dice.amount) attack_sets = [ AttackSet(Bite(dice.D10(1))), AttackSet(Gaze(None), special_properties=specialproperties.Petrify) ] base_armor_class = 16 morale = 9 movement = movement.MovementSet(walk=units.FeetPerGameTurn(20), turning_distance=units.Feet(10)) no_appearing = AppearingSet(dice_dungeon=dice.D6(1), dice_wild=dice.D6(1), dice_lair=dice.D6(1)) save_as = Fighter.level_table.levels[hit_dice.amount].saving_throws_set size = Size.Large special_abilities = specialabilities.CombatFrenzy, treasure_type = TreasureType.F weight = units.Pound(300) xp = 610
class TreasureTable(object): rows = [ TreasureRow(TreasureType.A, TreasureElement(50, coins.Copper, dice.D6(5)), TreasureElement(60, coins.Silver, dice.D6(5)), TreasureElement(40, coins.Electrum, dice.D4(5)), TreasureElement(70, coins.Gold, dice.D6(10)), TreasureElement(50, coins.Platinum, dice.D10(1)), TreasureElement(50, (Gem, ), dice.D6(6)), TreasureElement(50, (Jewelry, ), dice.D6(6)), TreasureElement(30, (RandomMagicItem, ), 3)), TreasureRow(TreasureType.B, TreasureElement(75, coins.Copper, dice.D10(5)), TreasureElement(50, coins.Silver, dice.D6(5)), TreasureElement(50, coins.Electrum, dice.D4(5)), TreasureElement(50, coins.Gold, dice.D6(3)), TreasureElement(25, Gem, dice.D6(1)), TreasureElement(25, Jewelry, dice.D6(1)), TreasureElement(10, ( Armor, Weapon, ), 1)), TreasureRow(TreasureType.C, TreasureElement(60, coins.Copper, dice.D6(6)), TreasureElement(60, coins.Silver, dice.D4(5)), TreasureElement(30, coins.Electrum, dice.D6(2)), TreasureElement(25, Gem, dice.D4(1)), TreasureElement(25, Jewelry, dice.D4(1)), TreasureElement(15, ( Armor, Weapon, ), dice.D2(1))), TreasureRow(TreasureType.D, TreasureElement(30, coins.Copper, dice.D6(4)), TreasureElement(45, coins.Silver, dice.D6(6)), TreasureElement(90, coins.Gold, dice.D8(5)), TreasureElement(30, Gem, dice.D8(1)), TreasureElement(30, Jewelry, dice.D8(1)), TreasureElement(20, RandomMagicItem, dice.D2(1), Potion)), TreasureRow( TreasureType.E, TreasureElement(30, coins.Copper, dice.D8(2)), TreasureElement(60, coins.Silver, dice.D6(10)), TreasureElement(50, coins.Electrum, dice.D8(3)), TreasureElement(50, coins.Gold, dice.D10(4)), TreasureElement(10, Gem, dice.D10(1)), TreasureElement(10, Jewelry, dice.D10(1)), TreasureElement(30, RandomMagicItem, dice.D4(1), MagicScroll)), TreasureRow( TreasureType.F, TreasureElement(40, coins.Silver, dice.D8(3)), TreasureElement(50, coins.Electrum, dice.D8(4)), TreasureElement(85, coins.Gold, dice.D10(6)), TreasureElement(70, coins.Platinum, dice.D8(2)), TreasureElement(20, Gem, dice.D12(2)), TreasureElement(10, Jewelry, dice.D12(1)), TreasureElement(35, RandomMagicItem, dice.D4(1), Potion, MagicScroll)), TreasureRow( TreasureType.G, TreasureElement(90, coins.Gold, dice.D6(4, multiplier=10)), TreasureElement(75, coins.Platinum, dice.D8(5)), TreasureElement(25, Gem, dice.D6(3)), TreasureElement(25, Jewelry, dice.D10(1)), TreasureElement(50, RandomMagicItem, dice.D4(1), MagicScroll)), TreasureRow( TreasureType.H, TreasureElement(75, coins.Copper, dice.D10(8)), TreasureElement(75, coins.Silver, dice.D10(6, multiplier=10)), TreasureElement(75, coins.Electrum, dice.D10(3, multiplier=10)), TreasureElement(75, coins.Gold, dice.D8(5, multiplier=10)), TreasureElement(75, coins.Platinum, dice.D8(9)), TreasureElement(50, Gem, dice.D100(1)), TreasureElement(50, Jewelry, dice.D4(10)), TreasureElement(20, RandomMagicItem, dice.D4(1), Potion, MagicScroll)), TreasureRow(TreasureType.I, TreasureElement(80, coins.Platinum, dice.D10(3)), TreasureElement(50, Gem, dice.D6(2)), TreasureElement(50, Jewelry, dice.D6(2)), TreasureElement(15, RandomMagicItem, 1)), TreasureRow( TreasureType.J, TreasureElement(45, coins.Copper, dice.D8(3)), TreasureElement(45, coins.Silver, dice.D8(1)), ), TreasureRow( TreasureType.K, TreasureElement(90, coins.Silver, dice.D10(2)), TreasureElement(35, coins.Electrum, dice.D8(1)), ), TreasureRow( TreasureType.L, TreasureElement(50, Gem, dice.D4(1)), ), TreasureRow( TreasureType.M, TreasureElement(90, coins.Gold, dice.D10(4)), TreasureElement(90, coins.Platinum, dice.D8(2, multiplier=10)), TreasureElement(55, Gem, dice.D4(5)), TreasureElement(45, Jewelry, dice.D6(2)), ), TreasureRow( TreasureType.N, TreasureElement(40, Potion, dice.D4(2)), ), TreasureRow( TreasureType.O, TreasureElement(50, MagicScroll, dice.D4(1)), ), TreasureRow( TreasureType.P, TreasureElement(100, coins.Copper, dice.D8(3)), ), TreasureRow( TreasureType.Q, TreasureElement(100, coins.Silver, dice.D6(3)), ), TreasureRow( TreasureType.R, TreasureElement(100, coins.Electrum, dice.D6(2)), ), TreasureRow( TreasureType.S, TreasureElement(100, coins.Gold, dice.D4(2)), ), TreasureRow( TreasureType.T, TreasureElement(100, coins.Platinum, dice.D6(1)), ), TreasureRow( TreasureType.U, TreasureElement(50, coins.Copper, dice.D20(1)), TreasureElement(50, coins.Silver, dice.D20(1)), TreasureElement(25, coins.Gold, dice.D20(1)), TreasureElement(5, Gem, dice.D4(1)), TreasureElement(5, Jewelry, dice.D4(1)), TreasureElement(2, RandomMagicItem, 1), ), TreasureRow( TreasureType.V, TreasureElement(25, coins.Silver, dice.D20(1)), TreasureElement(25, coins.Electrum, dice.D20(1)), TreasureElement(50, coins.Gold, dice.D20(1)), TreasureElement(25, coins.Platinum, dice.D20(1)), TreasureElement(10, Gem, dice.D4(1)), TreasureElement(10, Jewelry, dice.D4(1)), TreasureElement(5, RandomMagicItem, 1), ), ] inner_table = {row.treasure_type: row for row in rows} @classmethod def get_row(cls, treasure_type): """ :type treasure_type: TreasureType :rtype: TreasureRow """ return cls.inner_table.get(treasure_type)
class FallingStone(Trap): name = "Falling Stone Trap" attack = Attack(dice.D10(1, flat_bonus=1)) saving_throw = savingthrows.ParalysisStone target_type = targettypes.Touch