108 lines
3.6 KiB
Python
108 lines
3.6 KiB
Python
|
from ttfrog.db.schema.constants import DamageType, Defenses
|
||
|
from ttfrog.db.schema.item import Item, ItemType, Rarity, Weapon
|
||
|
from ttfrog.db.schema.modifiers import Modifier
|
||
|
|
||
|
|
||
|
def test_weapons(db):
|
||
|
with db.transaction():
|
||
|
longbow = Weapon(
|
||
|
name="longbow",
|
||
|
damage_die="1d6",
|
||
|
damage_type=DamageType.piercing,
|
||
|
martial=True,
|
||
|
two_handed=True,
|
||
|
ammunition=True,
|
||
|
targets=1,
|
||
|
attack_range=150,
|
||
|
attack_range_long=600,
|
||
|
)
|
||
|
|
||
|
dagger = Weapon(
|
||
|
name="Dagger",
|
||
|
damage_die="1d4",
|
||
|
damage_type=DamageType.slashing,
|
||
|
melee=True,
|
||
|
finesse=True,
|
||
|
light=True,
|
||
|
thrown=True,
|
||
|
attack_range=20,
|
||
|
attack_range_long=60,
|
||
|
)
|
||
|
|
||
|
db.add_or_update([longbow, dagger])
|
||
|
|
||
|
assert longbow.martial
|
||
|
assert longbow.ranged
|
||
|
assert not longbow.melee
|
||
|
|
||
|
assert not dagger.martial
|
||
|
assert dagger.ranged
|
||
|
assert dagger.melee
|
||
|
|
||
|
|
||
|
def test_attunement(db, carl):
|
||
|
with db.transaction():
|
||
|
helm = Item(
|
||
|
name="Iron Helm",
|
||
|
item_type=ItemType.ARMOR,
|
||
|
rarity=Rarity.Common,
|
||
|
)
|
||
|
helm.add_modifier(Modifier("+1 AC (helmet)", target="armor_class", relative_value=1, stacks=True))
|
||
|
|
||
|
shield = Item(
|
||
|
name="Shield of Missile Attraction",
|
||
|
description="""
|
||
|
While holding this shield, you have resistance to damage from ranged weapon attacks.
|
||
|
|
||
|
**Curse.** This shield is cursed. Attuning to it curses you until you are targeted by the remove curse spell
|
||
|
or similar magic. Removing the shield fails to end the curse on you. Whenever a ranged weapon attack is made
|
||
|
against a target within 10 feet of you, the curse causes you to become the target instead.
|
||
|
""",
|
||
|
item_type=ItemType.SHIELD,
|
||
|
rarity=Rarity.Rare,
|
||
|
requires_attunement=True,
|
||
|
)
|
||
|
|
||
|
plus_two_ac = Modifier("+2 AC (Shield", target="armor_class", relative_value=2, stacks=True)
|
||
|
ranged_resistance = Modifier(
|
||
|
"Resistance to Damage From Ranged Weapon Attacks (Shield of Missle Attraction)",
|
||
|
target=DamageType.ranged_weapon_attacks,
|
||
|
new_value=Defenses.resistant,
|
||
|
requires_attunement=True,
|
||
|
)
|
||
|
shield.add_modifier(plus_two_ac)
|
||
|
shield.add_modifier(ranged_resistance)
|
||
|
|
||
|
db.add_or_update([carl, helm, shield])
|
||
|
|
||
|
assert carl.equipment.add(shield)
|
||
|
assert carl.equipment.add(helm)
|
||
|
db.add_or_update(carl)
|
||
|
|
||
|
carls_shield = carl.equipment.get(shield)[0]
|
||
|
|
||
|
assert carl.armor_class == 10
|
||
|
assert len(carl.attuned_items) == 0
|
||
|
|
||
|
carl.equip(carls_shield)
|
||
|
|
||
|
assert plus_two_ac in carl.modifiers["armor_class"]
|
||
|
assert ranged_resistance not in carl.modifiers[DamageType.ranged_weapon_attacks]
|
||
|
assert carl.armor_class == 12
|
||
|
assert carls_shield not in carl.attuned_items
|
||
|
|
||
|
carl.attune(carls_shield)
|
||
|
assert carl.armor_class == 12
|
||
|
assert plus_two_ac in carl.modifiers["armor_class"]
|
||
|
assert ranged_resistance in carl.modifiers[DamageType.ranged_weapon_attacks]
|
||
|
assert carls_shield in carl.attuned_items
|
||
|
|
||
|
assert carl.equip(carl.equipment.get(helm)[0])
|
||
|
assert carl.armor_class == 13
|
||
|
|
||
|
assert carl.unattune(carls_shield)
|
||
|
assert carl.armor_class == 13
|
||
|
assert ranged_resistance not in carl.modifiers[DamageType.ranged_weapon_attacks]
|
||
|
assert carl.unequip(carls_shield)
|
||
|
assert carl.armor_class == 11
|