from dungeonsheets.content_registry import default_content_registry default_content_registry.add_module(__name__) class Weapon: """A weapon that be used to deal damage. Attributes ========== Parameters ========== wielder The character (or NPC) that is using the weapon. """ name = "" cost = "0 gp" base_damage = "1d4" damage_bonus = 0 attack_bonus = 0 damage_type = "p" weight = 1 # In lbs properties = "" ability = "strength" is_finesse = False features_applied = False def __init__(self, wielder=None): self.wielder = wielder @classmethod def improved_version(cls, bonus): bonus = int(bonus) class NewWeapon(cls): name = f"+{bonus} " + cls.name damage_bonus = bonus attack_bonus = bonus return NewWeapon def apply_features(self): if (not self.features_applied) and (self.wielder is not None): self.features_applied = True for f in self.wielder.features: f.weapon_func(self) @property def ability_mod(self): if self.wielder is None: return 0 else: if self.is_finesse: return max( self.wielder.strength.modifier, self.wielder.dexterity.modifier ) else: return getattr(self.wielder, self.ability).modifier @property def attack_modifier(self): self.apply_features() mod = self.attack_bonus if self.wielder is not None: mod += self.ability_mod if self.wielder.is_proficient(self): mod += self.wielder.proficiency_bonus return mod @property def damage(self): self.apply_features() dam_str = str(self.base_damage) bonus = self.damage_bonus if self.wielder is not None: bonus += self.ability_mod if bonus != 0: dam_str += "{:+d}".format(bonus) return dam_str def __str__(self): return self.name def __repr__(self): return '"{:s}"'.format(self.name) class MeleeWeapon(Weapon): name = "Melee Weapons" ability = "strength" class RangedWeapon(Weapon): name = "Ranged Weapons" ability = "dexterity" class SimpleWeapon(Weapon): name = "Simple Weapons" class MartialWeapon(Weapon): name = "Martial Weapons" class Club(SimpleWeapon, MeleeWeapon): name = "Club" cost = "1 sp" base_damage = "1d4" damage_type = "b" weight = 2 properties = "Light" ability = "strength" class Dagger(SimpleWeapon, MeleeWeapon): name = "Dagger" cost = "2 gp" base_damage = "1d4" damage_type = "p" weight = 1 properties = "Finesse, light, thrown (range 20/60)" is_finesse = True ability = "strength" class Greatclub(SimpleWeapon, MeleeWeapon): name = "Greatclub" cost = "2 sp" base_damage = "1d8" damage_type = "b" weight = 10 properties = "Two-handed" ability = "strength" class Handaxe(SimpleWeapon, MeleeWeapon): name = "Handaxe" cost = "5 gp" base_damage = "1d6" damage_type = "s" weight = 2 properties = "Light, thrown (range 20/60)" ability = "strength" class Javelin(SimpleWeapon, MeleeWeapon): name = "Javelin" cost = "5 sp" base_damage = "1d6" damage_type = "p" weight = 2 properties = "Thrown (range 30/120)" ability = "strength" class LightHammer(SimpleWeapon, MeleeWeapon): name = "Light hammer" cost = "2 gp" base_damage = "1d4" damage_type = "b" weight = 2 properties = "Light, thrown (range 20/60)" ability = "strength" class Mace(SimpleWeapon, MeleeWeapon): name = "Mace" cost = "5 gp" base_damage = "1d6" damage_type = "b" weight = 4 properties = "" ability = "strength" class Quarterstaff(SimpleWeapon, MeleeWeapon): name = "Quarterstaff" cost = "2 sp" base_damage = "1d6" damage_type = "b" weight = 4 properties = "Versatile (1d8)" ability = "strength" class Sickle(SimpleWeapon, MeleeWeapon): name = "Sickle" cost = "1 gp" base_damage = "1d4" damage_type = "s" weight = 2 properties = "Light" ability = "strength" class Spear(SimpleWeapon, MeleeWeapon): name = "Spear" cost = "1 gp" base_damage = "1d6" damage_type = "p" weight = 3 properties = "Thrown (range 20/60), versatile (1d8)" ability = "strength" class LightCrossbow(SimpleWeapon, RangedWeapon): name = "Light crossbow" cost = "25 gp" base_damage = "1d8" damage_type = "p" weight = 5 properties = "Ammunition (range 80/320), loading, two-handed" ability = "dexterity" class Dart(SimpleWeapon, RangedWeapon): name = "Dart" cost = "5 cp" base_damage = "1d4" damage_type = "p" weight = 0.25 properties = "Finesse, thrown (range 20/60)" is_finesse = True ability = "dexterity" class Shortbow(SimpleWeapon, RangedWeapon): name = "Shortbow" cost = "25 gp" base_damage = "1d6" damage_type = "p" weight = 2 properties = "Ammunition (range 80/320), two-handed" ability = "dexterity" class Sling(SimpleWeapon, RangedWeapon): name = "Sling" cost = "1 sp" base_damage = "1d4" damage_type = "b" weight = 0 properties = "Ammunition (range 30/120)" ability = "dexterity" class Battleaxe(MartialWeapon, MeleeWeapon): name = "Battleaxe" cost = "10 gp" base_damage = "1d8" damage_type = "s" weight = 4 properties = "Versatile (1d10)" ability = "strength" class Flail(MartialWeapon, MeleeWeapon): name = "Flail" cost = "10gp" base_damage = "1d8" damage_type = "b" weight = 2 properties = "" ability = "strength" class Glaive(MartialWeapon, MeleeWeapon): name = "Glaive" cost = "20 gp" base_damage = "1d10" damage_type = "s" weight = 6 properties = "Heavy, reach, two-handed" ability = "strength" class Greataxe(MartialWeapon, MeleeWeapon): name = "Greataxe" cost = "30 gp" base_damage = "1d12" damage_type = "s" weight = 7 properties = "Heavy, two-handed" ability = "strength" class Greatsword(MartialWeapon, MeleeWeapon): name = "Greatsword" cost = "50 gp" base_damage = "2d6" damage_type = "s" weight = 6 properties = "Heavy, two-handed" ability = "strength" class Halberd(MartialWeapon, MeleeWeapon): name = "Halberd" cost = "20 gp" base_damage = "1d10" damage_type = "s" weight = 6 properties = "Heavy, reach, two-handed" ability = "strength" class Lance(MartialWeapon, MeleeWeapon): name = "Lance" cost = "10gp" base_damage = "1d12" damage_type = "p" weight = 6 properties = "Reach, special" ability = "strength" class Longsword(MartialWeapon, MeleeWeapon): name = "Longsword" cost = "15 gp" base_damage = "1d8" damage_type = "s" weight = 3 properties = "Versatile (1d10)" ability = "strength" class Maul(MartialWeapon, MeleeWeapon): name = "Maul" cost = "10 gp" base_damage = "2d6" damage_type = "b" weight = 10 properties = "Heavy, two-handed" ability = "strength" class Morningstar(MartialWeapon, MeleeWeapon): name = "Morningstar" cost = "15 gp" base_damage = "1d8" damage_type = "p" weight = 4 properties = "" ability = "strength" class Pike(MartialWeapon, MeleeWeapon): name = "Pike" cost = "5 gp" base_damage = "1d10" damage_type = "p" weight = 18 properties = "Heavy, reach, two-handed" ability = "strength" class Rapier(MartialWeapon, MeleeWeapon): name = "Rapier" cost = "25 gp" base_damage = "1d8" damage_type = "p" weight = 2 properties = "Finesse" is_finesse = True ability = "strength" class Scimitar(MartialWeapon, MeleeWeapon): name = "Scimitar" cost = "25 gp" base_damage = "1d6" damage_type = "s" weight = 3 properties = "Finesse, light" is_finesse = True ability = "strength" class Shortsword(MartialWeapon, MeleeWeapon): name = "Shortsword" cost = "10 gp" base_damage = "1d6" damage_type = "p" weight = 0 properties = "Finesse, light" is_finesse = True ability = "strength" class ThrowingHammer(MartialWeapon, MeleeWeapon): name = "Throwing Hammer" cost = "15 gp" base_damage = "1d6" damage_type = "b" weight = 4 properties = "Thrown (range 60/120)" ability = "strength" class Trident(MartialWeapon, MeleeWeapon): name = "Trident" cost = "5 gp" base_damage = "1d6" damage_type = "p" weight = 4 properties = "Thrown (range 20/60), versatile (1d8)" ability = "strength" class WarPick(MartialWeapon, MeleeWeapon): name = "War pick" cost = "5 gp" base_damage = "1d8" damage_type = "p" weight = 2 properties = "" ability = "strength" class Warhammer(MartialWeapon, MeleeWeapon): name = "Warhammer" cost = "15 gp" base_damage = "1d8" damage_type = "b" weight = 2 properties = "Versatile (1d10)" ability = "strength" class Whip(MartialWeapon, MeleeWeapon): name = "Whip" cost = "2 gp" base_damage = "1d4" damage_type = "s" weight = 3 properties = "Finesse, reach" is_finesse = True ability = "strength" class Blowgun(MartialWeapon, RangedWeapon): name = "Blowgun" cost = "10 gp" base_damage = "1" damage_type = "p" weight = 1 properties = "Ammunition (range 25/100), loading" ability = "dexterity" class HandCrossbow(MartialWeapon, RangedWeapon): name = "Hand Crossbow" cost = "75 gp" base_damage = "1d6" damage_type = "p" weight = 3 properties = "Ammunition (range 30/120), light, loading" ability = "dexterity" class HeavyCrossbow(MartialWeapon, RangedWeapon): name = "Heavy Crossbow" cost = "50 gp" base_damage = "1d10" damage_type = "p" weight = 18 properties = "Ammunition (range 100/400), heaving, loading, two-handed" ability = "dexterity" class Longbow(MartialWeapon, RangedWeapon): name = "Longbow" cost = "50 gp" base_damage = "1d8" damage_type = "p" weight = 2 properties = "Ammunition (range 150/600), heavy, two-handed" ability = "dexterity" class Net(MartialWeapon, RangedWeapon): name = "Net" cost = "1 gp" base_damage = "-" damage_type = "" weight = 3 properties = "Special, thrown (range 5/15)" ability = "strength" class Unarmed(MeleeWeapon): name = "Unarmed" cost = "0 gp" base_damage = "1" damage_type = "b" weight = 0 properties = "" ability = "strength" MonkUnarmedStrike = Unarmed UnarmedStrike = Unarmed class SunBolt(RangedWeapon): name = "Sun Bolt" cost = "0 gp" base_damage = "1d4" damage_type = "r" weight = 0 properties = "(range 20/60)" ability = "dexterity" # Custom weapons class HeavyPunch(MeleeWeapon): base_damage = "1d4" name = "Heavy Punch" damage_type = "b" damage_bonus = 10 # Heavy weapon master attack_bonus = -5 # Heavy weapon master class Bite(MeleeWeapon): name = "Bite" base_damage = "1d4" damage_type = "p" cost = "0 gp" weight = 0 properties = "" ability = "strength" class Talons(MeleeWeapon): name = "Talons" base_damage = "1d4" damage_type = "s" cost = "0 gp" weight = 0 properties = "" ability = "strength" class Claws(MeleeWeapon): name = "Claws" base_damage = "1d4" damage_type = "s" cost = "0 gp" weight = 0 properties = "" ability = "strength" class Firearm(RangedWeapon): name = "Firearm" ability = "dexterity" damage_type = "p" class Blunderbuss(Firearm): name = "Blunderbuss" base_damage = "2d8" cost = "300 gp" weight = 10 properties = "Ammunition (range 15/60), Reload 1, Misfire 2" class Pistol(Firearm): name = "Pistol" base_damage = "1d10" cost = "150 gp" weight = 3 properties = "Ammunition (range 60/240), Reload 4, Misfire 1" class Musket(Firearm): name = "Musket" base_damage = "1d12" cost = "300" weight = 10 properties = "Ammunition (range 120/480), Two-Handed, Reload 1, Misfire 2" # Magic Items class FlameTongue(Greatsword): name = "Flame Tongue +1" damage_bonus = 1 attack_bonus = 1 base_damage = "4d6" damage_type = "f" class SpearOfLightning(Spear): name = "Spear +1" damage_bonus = 1 attack_bonus = 1 # Some lists of weapons for easy proficiency resolution simple_melee_weapons = ( Club, Dagger, Greatclub, Handaxe, Javelin, LightHammer, Mace, Quarterstaff, Sickle, Spear, ) simple_ranged_weapons = (LightCrossbow, Dart, Shortbow, Sling) simple_weapons = simple_melee_weapons + simple_ranged_weapons martial_melee_weapons = ( Battleaxe, Flail, Glaive, Greataxe, Greatsword, Halberd, Lance, Longsword, Maul, Morningstar, Pike, Rapier, Scimitar, Shortsword, ThrowingHammer, Trident, WarPick, Warhammer, Whip, ) martial_ranged_weapons = (Blowgun, HandCrossbow, HeavyCrossbow, Longbow, Net) martial_weapons = martial_melee_weapons + martial_ranged_weapons monk_weapons = ( Shortsword, Unarmed, Club, Dagger, Handaxe, Javelin, LightHammer, Mace, Quarterstaff, Sickle, Spear, SunBolt, ) firearms = (Firearm, Blunderbuss, Pistol, Musket)