from ttfrog.db.schema.item import Item, ItemType, Spell def test_equipment_inventory(db, carl): with db.transaction(): # trigger the creation of inventory mappings db.add_or_update(carl) # create some items ten_foot_pole = Item(name="10ft. Pole", item_type=ItemType.ITEM, consumable=False) fireball = Spell(name="Fireball", level=3, concentration=False) db.add_or_update([ten_foot_pole, fireball]) # add the pole to carl's equipment, and the spell to his spell list. assert carl.equipment.add(ten_foot_pole) assert carl.spells.add(fireball) # can't mix and match inventory item types assert not carl.equipment.add(fireball) assert not carl.spells.add(ten_foot_pole) # add two more 10 foot poles. You can never have too many. carl.equipment.add(ten_foot_pole) carl.equipment.add(ten_foot_pole) db.add_or_update(carl) all_carls_poles = carl.equipment.get(ten_foot_pole) assert len(all_carls_poles) == 3 # check the "contains" logic assert ten_foot_pole in carl.equipment assert ten_foot_pole not in carl.spells assert fireball in carl.spells assert fireball not in carl.equipment # equip one pole assert carl.equip(all_carls_poles[0]) # can't equip it twice assert not carl.equip(all_carls_poles[0]) # unequip it assert carl.unequip(all_carls_poles[0]) # can't unequip the unequipped ones assert not carl.unequip(all_carls_poles[1]) assert not carl.unequip(all_carls_poles[2]) # drop one pole assert carl.equipment.remove(all_carls_poles[0]) assert ten_foot_pole in carl.equipment # drop the remaining poles assert carl.equipment.remove(all_carls_poles[1]) assert carl.equipment.remove(all_carls_poles[2]) assert ten_foot_pole not in carl.equipment # can't drop what you don't have assert not carl.equipment.remove(all_carls_poles[0]) def test_inventory_bundles(db, carl): with db.transaction(): arrows = Item(name="Arrows", item_type=ItemType.ITEM, consumable=True, count=20) db.add_or_update([carl, arrows]) quiver = carl.equipment.add(arrows) db.add_or_update(carl) # full quiver assert arrows in carl.equipment assert quiver.count == 20 # use one assert quiver.use(1) == 19 assert quiver.count == 19 # cannot use more than you have assert not quiver.use(20) # cannot use a negative amount assert not quiver.use(-1) # consume all remaining arrows assert quiver.use(19) == 0 assert arrows not in carl.equipment def test_spell_slots(db, carl, wizard): with db.transaction(): prestidigitation = Spell(name="Prestidigitation", level=0, concentration=False) fireball = Spell(name="Fireball", level=3, concentration=False) db.add_or_update([carl, prestidigitation, fireball]) carl.spells.add(prestidigitation) carl.spells.add(fireball) db.add_or_update(carl) # verify carl has the spell slots granted by wizard at 1st level print(carl.levels) print(carl.spell_slots) assert len(carl.spell_slots) == 2 assert carl.spell_slots[0].spell_level == 1 assert carl.spell_slots[1].spell_level == 1 # carl knows the spells but hasn't prepared them assert prestidigitation in carl.spells assert fireball in carl.spells assert prestidigitation not in carl.prepared_spells assert fireball not in carl.prepared_spells # prepare the cantrip carls_prestidigitation = carl.spells.get(prestidigitation)[0] assert carl.prepare(carls_prestidigitation) assert carl.cast(carls_prestidigitation) # prepare() and cast() require a spell from the spell inventory carls_fireball = carl.spells.get(fireball)[0] # can't prepare a 3rd level spell if you don't have 3rd level slots assert carl.spellcaster_level == 1 assert not carl.prepare(carls_fireball) # make carl a 5th level wizard so he gets a 3rd level spell slot carl.level_up(wizard, num_levels=4) assert carl.level == 5 assert carl.spellcaster_level == 3 # cast fireball until he's out of 3rd level slots assert carl.prepare(carls_fireball) assert carl.cast(carls_fireball) assert carl.cast(carls_fireball) assert not carl.cast(carls_fireball) # level up to 7th level, gaining 1 4th level slot and 1 more 3rd level slot carl.add_class(wizard) carl.level_up(wizard, num_levels=2) assert carl.spellcaster_level == 4 assert len(carl.spell_slots_available[4]) == 1 assert len(carl.spell_slots_available[3]) == 1 # cast at 4th level assert carl.cast(carls_fireball, 4) assert not carl.cast(carls_fireball, 4) # use the last 3rd level slot assert carl.cast(carls_fireball) assert not carl.cast(carls_fireball)