Expand tutorial on equipmenthandler

This commit is contained in:
Griatch 2022-08-30 23:03:39 +02:00
parent 9c45feaf10
commit 805fbd5edb
423 changed files with 689 additions and 3613 deletions

View file

@ -469,8 +469,8 @@ class CombatActionFlee(CombatAction):
def use(self, *args, **kwargs):
# it's safe to do this twice
self.msg(
"$You() retreats, and will leave combat next round unless someone successfully "
"blocks them."
"$You() $conj(retreat), and will leave combat next round unless someone successfully "
"blocks the escape."
)
self.combathandler.flee(self.combatant)
@ -513,14 +513,16 @@ class CombatActionBlock(CombatAction):
advantage=advantage,
disadvantage=disadvantage,
)
self.msg(f"$You() tries to block the retreat of $You({fleeing_target.key}). {txt}")
self.msg(
f"$You() $conj(try) to block the retreat of $You({fleeing_target.key}). {txt}",
)
if is_success:
# managed to stop the target from fleeing/disengaging
self.combathandler.unflee(fleeing_target)
self.msg(f"$You() $conj(block) the retreat of $You({fleeing_target.key})")
else:
self.msg(f"$You({fleeing_target.key}) dodges away from you $You()!")
self.msg(f"$You({fleeing_target.key}) $conj(dodge) away from you $You()!")
class CombatActionDoNothing(CombatAction):

View file

@ -161,7 +161,7 @@ class EquipmentHandler:
"""
# first checks two-handed wield, then one-handed; the two
# should never appear simultaneously anyhow (checked in `use` method).
# should never appear simultaneously anyhow (checked in `move` method).
slots = self.slots
weapon = slots[WieldLocation.TWO_HANDS]
if not weapon:
@ -232,7 +232,7 @@ class EquipmentHandler:
def move(self, obj):
"""
Moves item to the place it things it should be in - this makes use of the object's wield
slot to decide where it goes. If it doesn't have any, it goes into backpack.
slot to decide where it goes. The item is assumed to already be in the backpack.
Args:
obj (EvAdventureObject): Thing to use.
@ -242,36 +242,42 @@ class EquipmentHandler:
of the error, suitable to echo to user.
Notes:
If using an item already in the backpack, it should first be `removed` from the
backpack, before applying here - otherwise, it will be added a second time!
this will cleanly move any 'colliding' items to the backpack to
This will cleanly move any 'colliding' items to the backpack to
make the use possible (such as moving sword + shield to backpack when wielding
a two-handed weapon). If wanting to warn the user about this, it needs to happen
before this call.
"""
# first check if we have room for this
self.validate_slot_usage(obj)
# make sure to remove from backpack first, if it's there, since we'll be re-adding it
self.remove(obj)
self.validate_slot_usage(obj)
slots = self.slots
use_slot = getattr(obj, "inventory_use_slot", WieldLocation.BACKPACK)
to_backpack = []
if use_slot is WieldLocation.TWO_HANDS:
# two-handed weapons can't co-exist with weapon/shield-hand used items
to_backpack = [slots[WieldLocation.WEAPON_HAND], slots[WieldLocation.SHIELD_HAND]]
slots[WieldLocation.WEAPON_HAND] = slots[WieldLocation.SHIELD_HAND] = None
slots[use_slot] = obj
elif use_slot in (WieldLocation.WEAPON_HAND, WieldLocation.SHIELD_HAND):
# can't keep a two-handed weapon if adding a one-handed weapon or shield
to_backpack = [slots[WieldLocation.TWO_HANDS]]
slots[WieldLocation.TWO_HANDS] = None
slots[use_slot] = obj
elif use_slot is WieldLocation.BACKPACK:
# backpack has multiple slots.
slots[use_slot].append(obj)
# it belongs in backpack, so goes back to it
to_backpack = [obj]
else:
# for others (body, head), just replace whatever's there
replaced = [obj]
slots[use_slot] = obj
for to_backpack_obj in to_backpack:
# put stuff in backpack
slots[use_slot].append(to_backpack_obj)
# store new state
self._save()
@ -403,7 +409,8 @@ class EquipmentHandler:
(slots[WieldLocation.BODY], WieldLocation.BODY),
(slots[WieldLocation.HEAD], WieldLocation.HEAD),
] + [(item, WieldLocation.BACKPACK) for item in slots[WieldLocation.BACKPACK]]
# remove any None-results from empty slots
if only_objs:
# remove any None-results from empty slots
return [tup[0] for tup in lst if tup[0]]
return [tup for tup in lst if tup[0]]
# keep empty slots
return [tup for tup in lst]

View file

@ -32,22 +32,18 @@ class EvAdventureMixin:
self.helmet = create.create_object(
EvAdventureHelmet,
key="helmet",
attributes=[("inventory_use_slot", enums.WieldLocation.HEAD), ("armor", 1)],
)
self.shield = create.create_object(
EvAdventureShield,
key="shield",
attributes=[("inventory_use_slot", enums.WieldLocation.SHIELD_HAND), ("armor", 1)],
)
self.armor = create.create_object(
EvAdventureArmor,
key="armor",
attributes=[("inventory_use_slot", enums.WieldLocation.BODY), ("armor", 11)],
)
self.weapon = create.create_object(
EvAdventureWeapon,
key="weapon",
attributes=[("inventory_use_slot", enums.WieldLocation.WEAPON_HAND)],
)
self.big_weapon = create.create_object(
EvAdventureWeapon,

View file

@ -0,0 +1,58 @@
"""
Test the EvAdventure equipment handler.
"""
from evennia.utils.test_resources import BaseEvenniaTest
from ..enums import Ability, WieldLocation
from ..equipment import EquipmentError
from .mixins import EvAdventureMixin
class TestEquipment(EvAdventureMixin, BaseEvenniaTest):
def test_count_slots(self):
self.assertEqual(self.character.equipment.count_slots(), 0)
def test_max_slots(self):
self.assertEqual(self.character.equipment.max_slots, 11)
setattr(self.character, Ability.CON.value, 3)
self.assertEqual(self.character.equipment.max_slots, 13)
def test_validate_slot_usage(self):
helmet = self.helmet
self.assertTrue(self.character.equipment.validate_slot_usage(helmet))
helmet.size = 20 # a very large helmet
with self.assertRaises(EquipmentError):
self.assertFalse(self.character.equipment.validate_slot_usage(helmet))
def test_add__remove(self):
self.character.equipment.add(self.helmet)
self.assertEqual(self.character.equipment.slots[WieldLocation.BACKPACK], [self.helmet])
self.character.equipment.remove(self.helmet)
self.assertEqual(self.character.equipment.slots[WieldLocation.BACKPACK], [])
def test_move__get_current_slot(self):
self.character.equipment.add(self.helmet)
self.assertEqual(
self.character.equipment.get_current_slot(self.helmet), WieldLocation.BACKPACK
)
self.character.equipment.move(self.helmet)
self.assertEqual(self.character.equipment.get_current_slot(self.helmet), WieldLocation.HEAD)
def test_get_wearable_or_wieldable_objects_from_backpack(self):
self.character.equipment.add(self.helmet)
self.character.equipment.add(self.weapon)
self.assertEqual(
self.character.equipment.get_wieldable_objects_from_backpack(), [self.weapon]
)
self.assertEqual(
self.character.equipment.get_wearable_objects_from_backpack(), [self.helmet]
)
self.assertEqual(
self.character.equipment.get_all(),
[(self.helmet, WieldLocation.BACKPACK), (self.weapon, WieldLocation.BACKPACK)],
)