mirror of
https://github.com/evennia/evennia.git
synced 2026-03-28 02:36:32 +01:00
Apply black to evadventure files
This commit is contained in:
parent
6e8e3963dd
commit
7815a06e3a
12 changed files with 653 additions and 327 deletions
|
|
@ -27,6 +27,7 @@ class EquipmentHandler:
|
|||
until you clean them.
|
||||
|
||||
"""
|
||||
|
||||
save_attribute = "inventory_slots"
|
||||
|
||||
def __init__(self, obj):
|
||||
|
|
@ -47,8 +48,8 @@ class EquipmentHandler:
|
|||
WieldLocation.TWO_HANDS: None,
|
||||
WieldLocation.BODY: None,
|
||||
WieldLocation.HEAD: None,
|
||||
WieldLocation.BACKPACK: []
|
||||
}
|
||||
WieldLocation.BACKPACK: [],
|
||||
},
|
||||
)
|
||||
|
||||
def _count_slots(self):
|
||||
|
|
@ -64,8 +65,7 @@ class EquipmentHandler:
|
|||
if slot is not WieldLocation.BACKPACK
|
||||
)
|
||||
backpack_usage = sum(
|
||||
getattr(slotobj, "size", 0) or 0
|
||||
for slotobj in slots[WieldLocation.BACKPACK]
|
||||
getattr(slotobj, "size", 0) or 0 for slotobj in slots[WieldLocation.BACKPACK]
|
||||
)
|
||||
return wield_usage + backpack_usage
|
||||
|
||||
|
|
@ -101,9 +101,11 @@ class EquipmentHandler:
|
|||
current_slot_usage = self._count_slots()
|
||||
if current_slot_usage + size > max_slots:
|
||||
slots_left = max_slots - current_slot_usage
|
||||
raise EquipmentError(f"Equipment full ($int2str({slots_left}) slots "
|
||||
f"remaining, {obj.key} needs $int2str({size}) "
|
||||
f"$pluralize(slot, {size})).")
|
||||
raise EquipmentError(
|
||||
f"Equipment full ($int2str({slots_left}) slots "
|
||||
f"remaining, {obj.key} needs $int2str({size}) "
|
||||
f"$pluralize(slot, {size}))."
|
||||
)
|
||||
return True
|
||||
|
||||
@property
|
||||
|
|
@ -120,11 +122,13 @@ class EquipmentHandler:
|
|||
|
||||
"""
|
||||
slots = self.slots
|
||||
return sum((
|
||||
getattr(slots[WieldLocation.BODY], "armor", 0),
|
||||
getattr(slots[WieldLocation.SHIELD_HAND], "armor", 0),
|
||||
getattr(slots[WieldLocation.HEAD], "armor", 0),
|
||||
))
|
||||
return sum(
|
||||
(
|
||||
getattr(slots[WieldLocation.BODY], "armor", 0),
|
||||
getattr(slots[WieldLocation.SHIELD_HAND], "armor", 0),
|
||||
getattr(slots[WieldLocation.HEAD], "armor", 0),
|
||||
)
|
||||
)
|
||||
|
||||
@property
|
||||
def weapon(self):
|
||||
|
|
@ -423,6 +427,7 @@ class EvAdventureNPC(LivingMixin, DefaultCharacter):
|
|||
EvAdventureCharacter class instead.
|
||||
|
||||
"""
|
||||
|
||||
hit_dice = AttributeProperty(default=1)
|
||||
armor = AttributeProperty(default=11)
|
||||
morale = AttributeProperty(default=9)
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ class CombatAction:
|
|||
Inherit from this to make new actions.
|
||||
|
||||
"""
|
||||
key = 'action'
|
||||
|
||||
key = "action"
|
||||
help_text = "Combat action to perform."
|
||||
# action to echo to everyone.
|
||||
post_action_text = "{combatant} performed an action."
|
||||
|
|
@ -107,6 +108,7 @@ class CombatActionDoNothing(CombatAction):
|
|||
Do nothing this turn.
|
||||
|
||||
"""
|
||||
|
||||
help_text = "Hold you position, doing nothing."
|
||||
post_action_text = "{combatant} does nothing this turn."
|
||||
|
||||
|
|
@ -124,24 +126,29 @@ class CombatActionStunt(CombatAction):
|
|||
spend a use unless they succeed.
|
||||
|
||||
"""
|
||||
|
||||
give_advantage = True
|
||||
give_disadvantage = False
|
||||
max_uses = 1
|
||||
priority = -1
|
||||
attack_type = Ability.DEX
|
||||
defense_type = Ability.DEX
|
||||
help_text = ("Perform a stunt against a target. This will give you or an ally advantage "
|
||||
"on your next action against the same target [range 0-1, one use per combat. "
|
||||
"Bonus lasts for two turns].")
|
||||
help_text = (
|
||||
"Perform a stunt against a target. This will give you or an ally advantage "
|
||||
"on your next action against the same target [range 0-1, one use per combat. "
|
||||
"Bonus lasts for two turns]."
|
||||
)
|
||||
|
||||
def use(self, attacker, defender, *args, beneficiary=None, **kwargs):
|
||||
# quality doesn't matter for stunts, they are either successful or not
|
||||
|
||||
is_success, _ = rules.EvAdventureRollEngine.opposed_saving_throw(
|
||||
attacker, defender,
|
||||
is_success, _ = rules.EvAdventureRollEngine.opposed_saving_throw(
|
||||
attacker,
|
||||
defender,
|
||||
attack_type=self.attack_type,
|
||||
defense_type=self.defense_type,
|
||||
advantage=False, disadvantage=disadvantage,
|
||||
advantage=False,
|
||||
disadvantage=disadvantage,
|
||||
)
|
||||
if is_success:
|
||||
beneficiary = beneficiary if beneficiary else attacker
|
||||
|
|
@ -161,6 +168,7 @@ class CombatActionAttack(CombatAction):
|
|||
melee attack.
|
||||
|
||||
"""
|
||||
|
||||
key = "attack"
|
||||
priority = 1
|
||||
|
||||
|
|
@ -176,14 +184,17 @@ class CombatActionAttack(CombatAction):
|
|||
disadvantage = bool(self.combathandler.disadvantage_matrix[attacker].pop(defender, False))
|
||||
|
||||
is_hit, quality = rules.EvAdventureRollEngine.opposed_saving_throw(
|
||||
attacker, defender,
|
||||
attacker,
|
||||
defender,
|
||||
attack_type=attacker.weapon.attack_type,
|
||||
defense_type=attacker.weapon.defense_type,
|
||||
advantage=advantage, disadvantage=disadvantage
|
||||
advantage=advantage,
|
||||
disadvantage=disadvantage,
|
||||
)
|
||||
if is_hit:
|
||||
self.combathandler.resolve_damage(attacker, defender,
|
||||
critical=quality == "critical success")
|
||||
self.combathandler.resolve_damage(
|
||||
attacker, defender, critical=quality == "critical success"
|
||||
)
|
||||
|
||||
# TODO messaging here
|
||||
|
||||
|
|
@ -204,6 +215,7 @@ class CombatActionUseItem(CombatAction):
|
|||
combat_post_use
|
||||
|
||||
"""
|
||||
|
||||
def get_help(self, item, *args):
|
||||
return item.combat_get_help(*args)
|
||||
|
||||
|
|
@ -227,6 +239,7 @@ class CombatActionFlee(CombatAction):
|
|||
end of the second turn.
|
||||
|
||||
"""
|
||||
|
||||
key = "flee"
|
||||
priority = -1
|
||||
|
||||
|
|
@ -234,37 +247,42 @@ class CombatActionFlee(CombatAction):
|
|||
# it's safe to do this twice
|
||||
self.combathandler.flee(combatant)
|
||||
|
||||
|
||||
class CombatActionChase(CombatAction):
|
||||
|
||||
"""
|
||||
Chasing is a way to counter a 'flee' action. It is a maximum movement towards the target
|
||||
and will mean a DEX contest, if the fleeing target loses, they are moved back from
|
||||
'disengaging' range and remain in combat at the new distance (likely 2 if max movement
|
||||
is 2). Advantage/disadvantage are considered.
|
||||
"""
|
||||
Chasing is a way to counter a 'flee' action. It is a maximum movement towards the target
|
||||
and will mean a DEX contest, if the fleeing target loses, they are moved back from
|
||||
'disengaging' range and remain in combat at the new distance (likely 2 if max movement
|
||||
is 2). Advantage/disadvantage are considered.
|
||||
|
||||
"""
|
||||
key = "chase"
|
||||
priority = -5 # checked last
|
||||
"""
|
||||
|
||||
attack_type = Ability.DEX # or is it CON?
|
||||
defense_type = Ability.DEX
|
||||
key = "chase"
|
||||
priority = -5 # checked last
|
||||
|
||||
def use(self, combatant, fleeing_target, *args, **kwargs):
|
||||
attack_type = Ability.DEX # or is it CON?
|
||||
defense_type = Ability.DEX
|
||||
|
||||
advantage = bool(self.advantage_matrix[attacker].pop(fleeing_target, False))
|
||||
disadvantage = bool(self.disadvantage_matrix[attacker].pop(fleeing_target, False))
|
||||
def use(self, combatant, fleeing_target, *args, **kwargs):
|
||||
|
||||
is_success, _ = rules.EvAdventureRollEngine.opposed_saving_throw(
|
||||
combatant, fleeing_target,
|
||||
attack_type=self.attack_type, defense_type=self.defense_type,
|
||||
advantage=advantage, disadvantage=disadvantage
|
||||
)
|
||||
advantage = bool(self.advantage_matrix[attacker].pop(fleeing_target, False))
|
||||
disadvantage = bool(self.disadvantage_matrix[attacker].pop(fleeing_target, False))
|
||||
|
||||
if is_success:
|
||||
# managed to stop the target from fleeing/disengaging
|
||||
self.combatant.unflee(fleeing_target)
|
||||
else:
|
||||
pass # they are getting away!
|
||||
is_success, _ = rules.EvAdventureRollEngine.opposed_saving_throw(
|
||||
combatant,
|
||||
fleeing_target,
|
||||
attack_type=self.attack_type,
|
||||
defense_type=self.defense_type,
|
||||
advantage=advantage,
|
||||
disadvantage=disadvantage,
|
||||
)
|
||||
|
||||
if is_success:
|
||||
# managed to stop the target from fleeing/disengaging
|
||||
self.combatant.unflee(fleeing_target)
|
||||
else:
|
||||
pass # they are getting away!
|
||||
|
||||
|
||||
class EvAdventureCombatHandler(DefaultScript):
|
||||
|
|
@ -283,7 +301,7 @@ class EvAdventureCombatHandler(DefaultScript):
|
|||
CombatActionChase,
|
||||
CombatActionUseItem,
|
||||
CombatActionStunt,
|
||||
CombatActionAttack
|
||||
CombatActionAttack,
|
||||
]
|
||||
|
||||
# attributes
|
||||
|
|
@ -345,7 +363,8 @@ class EvAdventureCombatHandler(DefaultScript):
|
|||
for combatant in self.combatants:
|
||||
# read the current action type selected by the player
|
||||
action, args, kwargs = self.action_queue.get(
|
||||
combatant, (CombatActionDoNothing(self, combatant), (), {}))
|
||||
combatant, (CombatActionDoNothing(self, combatant), (), {})
|
||||
)
|
||||
# perform the action on the CombatAction instance
|
||||
action.use(combatant, *args, **kwargs)
|
||||
|
||||
|
|
@ -380,11 +399,13 @@ class EvAdventureCombatHandler(DefaultScript):
|
|||
|
||||
for combatant in self.combatants:
|
||||
new_advantage_matrix[combatant] = {
|
||||
target: set_at_turn for target, turn in advantage_matrix.items()
|
||||
target: set_at_turn
|
||||
for target, turn in advantage_matrix.items()
|
||||
if set_at_turn > oldest_stunt_age
|
||||
}
|
||||
new_disadvantage_matrix[combatant] = {
|
||||
target: set_at_turn for target, turn in disadvantage_matrix.items()
|
||||
target: set_at_turn
|
||||
for target, turn in disadvantage_matrix.items()
|
||||
if set_at_turn > oldest_stunt_age
|
||||
}
|
||||
|
||||
|
|
@ -500,8 +521,11 @@ class EvAdventureCombatHandler(DefaultScript):
|
|||
|
||||
if defender.hp > 0:
|
||||
# they are weakened, but with hp
|
||||
self.msg("You are alive, but out of the fight. If you want to press your luck, "
|
||||
"you need to rejoin the combat.", targets=defender)
|
||||
self.msg(
|
||||
"You are alive, but out of the fight. If you want to press your luck, "
|
||||
"you need to rejoin the combat.",
|
||||
targets=defender,
|
||||
)
|
||||
defender.at_defeat() # note - NPC monsters may still 'die' here
|
||||
else:
|
||||
# outright killed
|
||||
|
|
@ -537,19 +561,16 @@ combat_script = """
|
|||
"""
|
||||
|
||||
|
||||
|
||||
def _register_action(caller, raw_string, **kwargs):
|
||||
"""
|
||||
Register action with handler.
|
||||
|
||||
"""
|
||||
action = kwargs.get['action']
|
||||
action_args = kwargs['action_args']
|
||||
action_kwargs = kwargs['action_kwargs']
|
||||
action = kwargs.get["action"]
|
||||
action_args = kwargs["action_args"]
|
||||
action_kwargs = kwargs["action_kwargs"]
|
||||
combat = caller.scripts.get("combathandler")
|
||||
combat.register_action(
|
||||
caller, action=action, *action_args, **action_kwargs
|
||||
)
|
||||
combat.register_action(caller, action=action, *action_args, **action_kwargs)
|
||||
|
||||
|
||||
def node_select_target(caller, raw_string, **kwargs):
|
||||
|
|
@ -558,9 +579,9 @@ def node_select_target(caller, raw_string, **kwargs):
|
|||
with all other actions.
|
||||
|
||||
"""
|
||||
action = kwargs.get('action')
|
||||
action_args = kwargs.get('action_args')
|
||||
action_kwargs = kwargs.get('action_kwargs')
|
||||
action = kwargs.get("action")
|
||||
action_args = kwargs.get("action_args")
|
||||
action_kwargs = kwargs.get("action_kwargs")
|
||||
combat = caller.scripts.get("combathandler")
|
||||
text = "Select target for |w{action}|n."
|
||||
|
||||
|
|
@ -568,22 +589,26 @@ def node_select_target(caller, raw_string, **kwargs):
|
|||
options = [
|
||||
{
|
||||
"desc": combatant.key,
|
||||
"goto": (_register_action, {"action": action,
|
||||
"args": action_args,
|
||||
"kwargs": action_kwargs})
|
||||
"goto": (
|
||||
_register_action,
|
||||
{"action": action, "args": action_args, "kwargs": action_kwargs},
|
||||
),
|
||||
}
|
||||
for combatant in combat.combatants]
|
||||
for combatant in combat.combatants
|
||||
]
|
||||
# make the apply-self option always the last one
|
||||
options.append(
|
||||
{
|
||||
"desc": "(yourself)",
|
||||
"goto": (_register_action, {"action": action,
|
||||
"args": action_args,
|
||||
"kwargs": action_kwargs})
|
||||
"goto": (
|
||||
_register_action,
|
||||
{"action": action, "args": action_args, "kwargs": action_kwargs},
|
||||
),
|
||||
}
|
||||
)
|
||||
return text, options
|
||||
|
||||
|
||||
def node_select_action(caller, raw_string, **kwargs):
|
||||
"""
|
||||
Menu node for selecting a combat action.
|
||||
|
|
@ -593,13 +618,14 @@ def node_select_action(caller, raw_string, **kwargs):
|
|||
text = combat.get_previous_turn_status(caller)
|
||||
options = combat.get_available_options(caller)
|
||||
|
||||
|
||||
options = {
|
||||
"desc": action,
|
||||
"goto": ("node_select_target", {"action": action,
|
||||
})
|
||||
|
||||
"goto": (
|
||||
"node_select_target",
|
||||
{
|
||||
"action": action,
|
||||
},
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
return text, options
|
||||
|
|
|
|||
|
|
@ -16,11 +16,13 @@ To get the `value` of an enum (must always be hashable, useful for Attribute loo
|
|||
"""
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class Ability(Enum):
|
||||
"""
|
||||
The six base abilities (defense is always bonus + 10)
|
||||
|
||||
"""
|
||||
|
||||
STR = "strength"
|
||||
DEX = "dexterity"
|
||||
CON = "constitution"
|
||||
|
|
@ -45,11 +47,13 @@ class Ability(Enum):
|
|||
CRITICAL_FAILURE = "critical_failure"
|
||||
CRITICAL_SUCCESS = "critical_success"
|
||||
|
||||
|
||||
class WieldLocation(Enum):
|
||||
"""
|
||||
Wield (or wear) locations.
|
||||
|
||||
"""
|
||||
|
||||
# wield/wear location
|
||||
BACKPACK = "backpack"
|
||||
WEAPON_HAND = "weapon_hand"
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@ from evennia.typeclasses.attributes import AttributeProperty
|
|||
from .enums import WieldLocation, Ability
|
||||
|
||||
|
||||
|
||||
class EvAdventureObject(DefaultObject):
|
||||
"""
|
||||
Base in-game entity.
|
||||
|
||||
"""
|
||||
|
||||
# inventory management
|
||||
inventory_use_slot = AttributeProperty(default=WieldLocation.BACKPACK)
|
||||
# how many inventory slots it uses (can be a fraction)
|
||||
|
|
@ -41,6 +41,7 @@ class EvAdventureObjectFiller(EvAdventureObject):
|
|||
meaning it's unusable.
|
||||
|
||||
"""
|
||||
|
||||
quality = AttributeProperty(default=0)
|
||||
|
||||
|
||||
|
|
@ -49,6 +50,7 @@ class EvAdventureWeapon(EvAdventureObject):
|
|||
Base weapon class for all EvAdventure weapons.
|
||||
|
||||
"""
|
||||
|
||||
inventory_use_slot = AttributeProperty(WieldLocation.WEAPON_HAND)
|
||||
|
||||
attack_type = AttributeProperty(default=Ability.STR)
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ class EvAdventureQuest:
|
|||
check_<name> and complete_<name>
|
||||
|
||||
"""
|
||||
|
||||
# name + category must be globally unique. They are
|
||||
# queried as name:category or just name, if category is empty.
|
||||
name = ""
|
||||
|
|
@ -44,11 +45,9 @@ class EvAdventureQuest:
|
|||
def check():
|
||||
pass
|
||||
|
||||
|
||||
def progress(self, quester, *args, **kwargs):
|
||||
"""
|
||||
""" """
|
||||
|
||||
"""
|
||||
|
||||
class EvAdventureQuestHandler:
|
||||
"""
|
||||
|
|
@ -63,15 +62,14 @@ class EvAdventureQuestHandler:
|
|||
```
|
||||
|
||||
"""
|
||||
|
||||
quest_storage_attribute = "_quests"
|
||||
quest_storage_attribute_category = "evadventure"
|
||||
|
||||
def __init__(self, obj):
|
||||
self.obj = obj
|
||||
self.storage = obj.attributes.get(
|
||||
self.quest_storage_attribute,
|
||||
category=self.quest_storage_attribute_category,
|
||||
default={}
|
||||
self.quest_storage_attribute, category=self.quest_storage_attribute_category, default={}
|
||||
)
|
||||
|
||||
def quest_storage_key(self, name, category):
|
||||
|
|
@ -116,6 +114,3 @@ class EvAdventureQuestHandler:
|
|||
start immediately.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -227,26 +227,26 @@ character_generation = {
|
|||
"suspected",
|
||||
],
|
||||
"alignment": [
|
||||
('1-5', "law"),
|
||||
('6-15', "neutrality"),
|
||||
('16-20', "chaos"),
|
||||
("1-5", "law"),
|
||||
("6-15", "neutrality"),
|
||||
("16-20", "chaos"),
|
||||
],
|
||||
"armor": [
|
||||
('1-3', "no armor"),
|
||||
('4-14', "gambeson"),
|
||||
('15-19', "brigandine"),
|
||||
('20', "chain"),
|
||||
("1-3", "no armor"),
|
||||
("4-14", "gambeson"),
|
||||
("15-19", "brigandine"),
|
||||
("20", "chain"),
|
||||
],
|
||||
"helmets and shields": [
|
||||
('1-13', "no helmet or shield"),
|
||||
('14-16', "helmet"),
|
||||
('17-19', "shield"),
|
||||
('20', "helmet and shield"),
|
||||
("1-13", "no helmet or shield"),
|
||||
("14-16", "helmet"),
|
||||
("17-19", "shield"),
|
||||
("20", "helmet and shield"),
|
||||
],
|
||||
"starting weapon": [ # note: these are all d6 dmg weapons
|
||||
('1-7', "dagger"),
|
||||
('8-13', "club"),
|
||||
('14-20', "staff"),
|
||||
("1-7", "dagger"),
|
||||
("8-13", "club"),
|
||||
("14-20", "staff"),
|
||||
],
|
||||
"dungeoning gear": [
|
||||
"rope, 50ft",
|
||||
|
|
@ -315,55 +315,303 @@ character_generation = {
|
|||
"small bell",
|
||||
],
|
||||
"name": [
|
||||
"Abbo", "Adelaide", "Ellis", "Eleanor", "Lief", "Luanda", "Ablerus", "Agatha",
|
||||
"Eneto", "Elizabeth", "Luke", "Lyra", "Acot", "Aleida", "Enio", "Elspeth", "Martin",
|
||||
"Mabel", "Alexander", "Alexia", "Eral", "Emeline", "Merrick", "Maerwynn", "Almanzor",
|
||||
"Alianor", "Erasmus", "Emma", "Mortimer", "Malkyn", "Althalos", "Aline", "Eustace",
|
||||
"Emmony", "Ogden", "Margaret", "Ancelot", "Alma", "Everard", "Enna", "Oliver", "Margery",
|
||||
"Asher", "Alys", "Faustus", "Enndolynn", "Orion", "Maria", "Aster", "Amabel", "Favian",
|
||||
"Eve", "Oswald", "Marion", "Balan", "Amice", "Fendrel", "Evita", "Pelagon", "Matilda",
|
||||
"Balthazar", "Anastas", "Finn", "Felice", "Pello", "Millicent", "Barat", "Angmar",
|
||||
"Florian", "Fern", "Peyton", "Mirabelle", "Bartholomew", "Annabel", "Francis", "Floria",
|
||||
"Philip", "Muriel", "Basil", "Arabella", "Frederick", "Fredegonde", "Poeas", "Nabarne",
|
||||
"Benedict", "Ariana", "Gaidon", "Gillian", "Quinn", "Nell", "Berinon", "Ayleth", "Gavin",
|
||||
"Gloriana", "Ralph", "Nesea", "Bertram", "Barberry", "Geoffrey", "Godeleva", "Randolph",
|
||||
"Niree", "Beves", "Barsaba", "Gerard", "Godiva", "Reginald", "Odette", "Bilmer",
|
||||
"Basilia", "Gervase", "Gunnilda", "Reynold", "Odila", "Blanko", "Beatrix", "Gilbert",
|
||||
"Gussalen", "Richard", "Oria", "Bodo", "Benevolence", "Giles", "Gwendolynn", "Robert",
|
||||
"Osanna", "Borin", "Bess", "Godfrey", "Hawise", "Robin", "Ostrythe", "Bryce", "Brangian",
|
||||
"Gregory", "Helena", "Roger", "Ottilia", "Carac", "Brigida", "Gringoire", "Helewise",
|
||||
"Ronald", "Panope", "Caspar", "Brunhild", "Gunthar", "Hester", "Rowan", "Paternain",
|
||||
"Cassius", "Camilla", "Guy", "Hildegard", "Rulf", "Pechel", "Cedric", "Canace", "Gyras",
|
||||
"Idony", "Sabin", "Pepper", "Cephalos", "Cecily", "Hadrian", "Isabella", "Sevrin",
|
||||
"Petronilla", "Chadwick", "Cedany", "Hedelf", "Iseult", "Silas", "Phrowenia", "Charillos",
|
||||
"Christina", "Hewelin", "Isolde", "Simon", "Poppy", "Charles", "Claramunda", "Hilderith",
|
||||
"Jacquelyn", "Solomon", "Quenell", "Chermon", "Clarice", "Humbert", "Jasmine", "Stephen",
|
||||
"Raisa", "Clement", "Clover", "Hyllus", "Jessamine", "Terrowin", "Reyna", "Clifton",
|
||||
"Collette", "Ianto", "Josselyn", "Thomas", "Rixende", "Clovis", "Constance", "Ibykos",
|
||||
"Juliana", "Tristan", "Rosamund", "Cyon", "Damaris", "Inigo", "Karitate", "Tybalt",
|
||||
"Rose", "Dain", "Daphne", "Itylus", "Katelyn", "Ulric", "Ryia", "Dalmas", "Demona",
|
||||
"James", "Katja", "Walter", "Sarah", "Danor", "Dimia", "Jasper", "Katrina", "Wander",
|
||||
"Seraphina", "Destrian", "Dione", "Jiles", "Kaylein", "Warin", "Thea", "Domeka",
|
||||
"Dorothea", "Joffridus", "Kinna", "Waverly", "Trillby", "Donald", "Douce", "Jordan",
|
||||
"Krea", "Willahelm", "Wendel", "Doran", "Duraina", "Joris", "Kypris", "William",
|
||||
"Wilberga", "Dumphey", "Dyota", "Josef", "Landerra", "Wimarc", "Winifred", "Eadmund",
|
||||
"Eberhild", "Laurence", "Larraza", "Wystan", "Wofled", "Eckardus", "Edelot", "Leofrick",
|
||||
"Linet", "Xalvador", "Wymarc", "Edward", "Edyva", "Letholdus", "Loreena", "Zane", "Ysmay",
|
||||
"Abbo",
|
||||
"Adelaide",
|
||||
"Ellis",
|
||||
"Eleanor",
|
||||
"Lief",
|
||||
"Luanda",
|
||||
"Ablerus",
|
||||
"Agatha",
|
||||
"Eneto",
|
||||
"Elizabeth",
|
||||
"Luke",
|
||||
"Lyra",
|
||||
"Acot",
|
||||
"Aleida",
|
||||
"Enio",
|
||||
"Elspeth",
|
||||
"Martin",
|
||||
"Mabel",
|
||||
"Alexander",
|
||||
"Alexia",
|
||||
"Eral",
|
||||
"Emeline",
|
||||
"Merrick",
|
||||
"Maerwynn",
|
||||
"Almanzor",
|
||||
"Alianor",
|
||||
"Erasmus",
|
||||
"Emma",
|
||||
"Mortimer",
|
||||
"Malkyn",
|
||||
"Althalos",
|
||||
"Aline",
|
||||
"Eustace",
|
||||
"Emmony",
|
||||
"Ogden",
|
||||
"Margaret",
|
||||
"Ancelot",
|
||||
"Alma",
|
||||
"Everard",
|
||||
"Enna",
|
||||
"Oliver",
|
||||
"Margery",
|
||||
"Asher",
|
||||
"Alys",
|
||||
"Faustus",
|
||||
"Enndolynn",
|
||||
"Orion",
|
||||
"Maria",
|
||||
"Aster",
|
||||
"Amabel",
|
||||
"Favian",
|
||||
"Eve",
|
||||
"Oswald",
|
||||
"Marion",
|
||||
"Balan",
|
||||
"Amice",
|
||||
"Fendrel",
|
||||
"Evita",
|
||||
"Pelagon",
|
||||
"Matilda",
|
||||
"Balthazar",
|
||||
"Anastas",
|
||||
"Finn",
|
||||
"Felice",
|
||||
"Pello",
|
||||
"Millicent",
|
||||
"Barat",
|
||||
"Angmar",
|
||||
"Florian",
|
||||
"Fern",
|
||||
"Peyton",
|
||||
"Mirabelle",
|
||||
"Bartholomew",
|
||||
"Annabel",
|
||||
"Francis",
|
||||
"Floria",
|
||||
"Philip",
|
||||
"Muriel",
|
||||
"Basil",
|
||||
"Arabella",
|
||||
"Frederick",
|
||||
"Fredegonde",
|
||||
"Poeas",
|
||||
"Nabarne",
|
||||
"Benedict",
|
||||
"Ariana",
|
||||
"Gaidon",
|
||||
"Gillian",
|
||||
"Quinn",
|
||||
"Nell",
|
||||
"Berinon",
|
||||
"Ayleth",
|
||||
"Gavin",
|
||||
"Gloriana",
|
||||
"Ralph",
|
||||
"Nesea",
|
||||
"Bertram",
|
||||
"Barberry",
|
||||
"Geoffrey",
|
||||
"Godeleva",
|
||||
"Randolph",
|
||||
"Niree",
|
||||
"Beves",
|
||||
"Barsaba",
|
||||
"Gerard",
|
||||
"Godiva",
|
||||
"Reginald",
|
||||
"Odette",
|
||||
"Bilmer",
|
||||
"Basilia",
|
||||
"Gervase",
|
||||
"Gunnilda",
|
||||
"Reynold",
|
||||
"Odila",
|
||||
"Blanko",
|
||||
"Beatrix",
|
||||
"Gilbert",
|
||||
"Gussalen",
|
||||
"Richard",
|
||||
"Oria",
|
||||
"Bodo",
|
||||
"Benevolence",
|
||||
"Giles",
|
||||
"Gwendolynn",
|
||||
"Robert",
|
||||
"Osanna",
|
||||
"Borin",
|
||||
"Bess",
|
||||
"Godfrey",
|
||||
"Hawise",
|
||||
"Robin",
|
||||
"Ostrythe",
|
||||
"Bryce",
|
||||
"Brangian",
|
||||
"Gregory",
|
||||
"Helena",
|
||||
"Roger",
|
||||
"Ottilia",
|
||||
"Carac",
|
||||
"Brigida",
|
||||
"Gringoire",
|
||||
"Helewise",
|
||||
"Ronald",
|
||||
"Panope",
|
||||
"Caspar",
|
||||
"Brunhild",
|
||||
"Gunthar",
|
||||
"Hester",
|
||||
"Rowan",
|
||||
"Paternain",
|
||||
"Cassius",
|
||||
"Camilla",
|
||||
"Guy",
|
||||
"Hildegard",
|
||||
"Rulf",
|
||||
"Pechel",
|
||||
"Cedric",
|
||||
"Canace",
|
||||
"Gyras",
|
||||
"Idony",
|
||||
"Sabin",
|
||||
"Pepper",
|
||||
"Cephalos",
|
||||
"Cecily",
|
||||
"Hadrian",
|
||||
"Isabella",
|
||||
"Sevrin",
|
||||
"Petronilla",
|
||||
"Chadwick",
|
||||
"Cedany",
|
||||
"Hedelf",
|
||||
"Iseult",
|
||||
"Silas",
|
||||
"Phrowenia",
|
||||
"Charillos",
|
||||
"Christina",
|
||||
"Hewelin",
|
||||
"Isolde",
|
||||
"Simon",
|
||||
"Poppy",
|
||||
"Charles",
|
||||
"Claramunda",
|
||||
"Hilderith",
|
||||
"Jacquelyn",
|
||||
"Solomon",
|
||||
"Quenell",
|
||||
"Chermon",
|
||||
"Clarice",
|
||||
"Humbert",
|
||||
"Jasmine",
|
||||
"Stephen",
|
||||
"Raisa",
|
||||
"Clement",
|
||||
"Clover",
|
||||
"Hyllus",
|
||||
"Jessamine",
|
||||
"Terrowin",
|
||||
"Reyna",
|
||||
"Clifton",
|
||||
"Collette",
|
||||
"Ianto",
|
||||
"Josselyn",
|
||||
"Thomas",
|
||||
"Rixende",
|
||||
"Clovis",
|
||||
"Constance",
|
||||
"Ibykos",
|
||||
"Juliana",
|
||||
"Tristan",
|
||||
"Rosamund",
|
||||
"Cyon",
|
||||
"Damaris",
|
||||
"Inigo",
|
||||
"Karitate",
|
||||
"Tybalt",
|
||||
"Rose",
|
||||
"Dain",
|
||||
"Daphne",
|
||||
"Itylus",
|
||||
"Katelyn",
|
||||
"Ulric",
|
||||
"Ryia",
|
||||
"Dalmas",
|
||||
"Demona",
|
||||
"James",
|
||||
"Katja",
|
||||
"Walter",
|
||||
"Sarah",
|
||||
"Danor",
|
||||
"Dimia",
|
||||
"Jasper",
|
||||
"Katrina",
|
||||
"Wander",
|
||||
"Seraphina",
|
||||
"Destrian",
|
||||
"Dione",
|
||||
"Jiles",
|
||||
"Kaylein",
|
||||
"Warin",
|
||||
"Thea",
|
||||
"Domeka",
|
||||
"Dorothea",
|
||||
"Joffridus",
|
||||
"Kinna",
|
||||
"Waverly",
|
||||
"Trillby",
|
||||
"Donald",
|
||||
"Douce",
|
||||
"Jordan",
|
||||
"Krea",
|
||||
"Willahelm",
|
||||
"Wendel",
|
||||
"Doran",
|
||||
"Duraina",
|
||||
"Joris",
|
||||
"Kypris",
|
||||
"William",
|
||||
"Wilberga",
|
||||
"Dumphey",
|
||||
"Dyota",
|
||||
"Josef",
|
||||
"Landerra",
|
||||
"Wimarc",
|
||||
"Winifred",
|
||||
"Eadmund",
|
||||
"Eberhild",
|
||||
"Laurence",
|
||||
"Larraza",
|
||||
"Wystan",
|
||||
"Wofled",
|
||||
"Eckardus",
|
||||
"Edelot",
|
||||
"Leofrick",
|
||||
"Linet",
|
||||
"Xalvador",
|
||||
"Wymarc",
|
||||
"Edward",
|
||||
"Edyva",
|
||||
"Letholdus",
|
||||
"Loreena",
|
||||
"Zane",
|
||||
"Ysmay",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
reactions = [
|
||||
('2', "Hostile"),
|
||||
('3-5', "Unfriendly"),
|
||||
('6-8', "Unsure"),
|
||||
('9-11', "Talkative"),
|
||||
('12', "Helpful"),
|
||||
("2", "Hostile"),
|
||||
("3-5", "Unfriendly"),
|
||||
("6-8", "Unsure"),
|
||||
("9-11", "Talkative"),
|
||||
("12", "Helpful"),
|
||||
]
|
||||
|
||||
initiative = [
|
||||
('1-3', "Enemy acts first"),
|
||||
('4-6', "PC acts first"),
|
||||
("1-3", "Enemy acts first"),
|
||||
("4-6", "PC acts first"),
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -377,4 +625,3 @@ death_and_dismemberment = [
|
|||
"rattled", # -1d4 WIS
|
||||
"disfigured", # -1d4 CHA
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -28,12 +28,13 @@ from evennia.utils.evtable import EvTable
|
|||
from .enums import Ability
|
||||
from .random_tables import (
|
||||
character_generation as chargen_table,
|
||||
death_and_dismemberment as death_table
|
||||
death_and_dismemberment as death_table,
|
||||
)
|
||||
|
||||
|
||||
# Basic rolls
|
||||
|
||||
|
||||
class EvAdventureRollEngine:
|
||||
"""
|
||||
This groups all dice rolls of EvAdventure. These could all have been normal functions, but we
|
||||
|
|
@ -66,10 +67,11 @@ class EvAdventureRollEngine:
|
|||
"""
|
||||
max_diesize = 1000
|
||||
roll_string = roll_string.lower()
|
||||
if 'd' not in roll_string:
|
||||
raise TypeError(f"Dice roll '{roll_string}' was not recognized. "
|
||||
"Must be `<number>d<dicesize>`.")
|
||||
number, diesize = roll_string.split('d', 1)
|
||||
if "d" not in roll_string:
|
||||
raise TypeError(
|
||||
f"Dice roll '{roll_string}' was not recognized. " "Must be `<number>d<dicesize>`."
|
||||
)
|
||||
number, diesize = roll_string.split("d", 1)
|
||||
try:
|
||||
number = int(number)
|
||||
diesize = int(diesize)
|
||||
|
|
@ -104,8 +106,15 @@ class EvAdventureRollEngine:
|
|||
else:
|
||||
return min(self.roll("1d20"), self.roll("1d20"))
|
||||
|
||||
def saving_throw(self, character, bonus_type=Ability.STR, target=15,
|
||||
advantage=False, disadvantage=False, modifier=0):
|
||||
def saving_throw(
|
||||
self,
|
||||
character,
|
||||
bonus_type=Ability.STR,
|
||||
target=15,
|
||||
advantage=False,
|
||||
disadvantage=False,
|
||||
modifier=0,
|
||||
):
|
||||
"""
|
||||
A saving throw without a clear enemy to beat. In _Knave_ all unopposed saving
|
||||
throws always tries to beat 15, so (d20 + bonus + modifier) > 15.
|
||||
|
|
@ -142,9 +151,15 @@ class EvAdventureRollEngine:
|
|||
return (dice_roll + bonus + modifier) > target, quality
|
||||
|
||||
def opposed_saving_throw(
|
||||
self, attacker, defender,
|
||||
attack_type=Ability.STR, defense_type=Ability.ARMOR,
|
||||
advantage=False, disadvantage=False, modifier=0):
|
||||
self,
|
||||
attacker,
|
||||
defender,
|
||||
attack_type=Ability.STR,
|
||||
defense_type=Ability.ARMOR,
|
||||
advantage=False,
|
||||
disadvantage=False,
|
||||
modifier=0,
|
||||
):
|
||||
"""
|
||||
An saving throw that tries to beat an active opposing side.
|
||||
|
||||
|
|
@ -167,10 +182,14 @@ class EvAdventureRollEngine:
|
|||
|
||||
"""
|
||||
defender_defense = getattr(defender, defense_type.value, 1) + 10
|
||||
return self.saving_throw(attacker, bonus_type=attack_type,
|
||||
target=defender_defense,
|
||||
advantage=advantage, disadvantage=disadvantage,
|
||||
modifier=modifier)
|
||||
return self.saving_throw(
|
||||
attacker,
|
||||
bonus_type=attack_type,
|
||||
target=defender_defense,
|
||||
advantage=advantage,
|
||||
disadvantage=disadvantage,
|
||||
modifier=modifier,
|
||||
)
|
||||
|
||||
def roll_random_table(self, dieroll, table_choices):
|
||||
"""
|
||||
|
|
@ -204,7 +223,7 @@ class EvAdventureRollEngine:
|
|||
min_range = 10**6
|
||||
for (valrange, choice) in table_choices:
|
||||
|
||||
minval, *maxval = valrange.split('-', 1)
|
||||
minval, *maxval = valrange.split("-", 1)
|
||||
minval = abs(int(minval))
|
||||
maxval = abs(int(maxval[0]) if maxval else minval)
|
||||
|
||||
|
|
@ -240,7 +259,7 @@ class EvAdventureRollEngine:
|
|||
bool: False if morale roll failed, True otherwise.
|
||||
|
||||
"""
|
||||
return self.roll('2d6') <= defender.morale
|
||||
return self.roll("2d6") <= defender.morale
|
||||
|
||||
def heal(self, character, amount):
|
||||
"""
|
||||
|
|
@ -265,7 +284,7 @@ class EvAdventureRollEngine:
|
|||
int: How much HP was healed. This is never more than how damaged we are.
|
||||
|
||||
"""
|
||||
self.heal(character, self.roll('1d8') + character.constitution)
|
||||
self.heal(character, self.roll("1d8") + character.constitution)
|
||||
|
||||
death_map = {
|
||||
"weakened": "strength",
|
||||
|
|
@ -282,7 +301,7 @@ class EvAdventureRollEngine:
|
|||
|
||||
"""
|
||||
|
||||
result = self.roll_random_table('1d8', death_table)
|
||||
result = self.roll_random_table("1d8", death_table)
|
||||
if result == "dead":
|
||||
character.handle_death()
|
||||
else:
|
||||
|
|
@ -304,16 +323,15 @@ class EvAdventureRollEngine:
|
|||
character.hp = new_hp
|
||||
|
||||
character.msg(
|
||||
"~" * 78 +
|
||||
"\n|yYou survive your brush with death, "
|
||||
"~" * 78 + "\n|yYou survive your brush with death, "
|
||||
f"but are |r{result.upper()}|y and permenently |rlose {loss} {abi}|y.|n\n"
|
||||
f"|GYou recover |g{new_hp}|G health|.\n"
|
||||
+ "~" * 78
|
||||
f"|GYou recover |g{new_hp}|G health|.\n" + "~" * 78
|
||||
)
|
||||
|
||||
|
||||
# character generation
|
||||
|
||||
|
||||
class EvAdventureCharacterGeneration:
|
||||
"""
|
||||
This collects all the rules for generating a new character. An instance of this class can be
|
||||
|
|
@ -341,6 +359,7 @@ class EvAdventureCharacterGeneration:
|
|||
there is no GM to adjudicate a different choice).
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Initialize starting values
|
||||
|
|
@ -351,7 +370,7 @@ class EvAdventureCharacterGeneration:
|
|||
roll_engine = EvAdventureRollEngine()
|
||||
|
||||
# name will likely be modified later
|
||||
self.name = roll_engine.roll_random_table('1d282', chargen_table['name'])
|
||||
self.name = roll_engine.roll_random_table("1d282", chargen_table["name"])
|
||||
|
||||
# base attribute bonuses (flat +1 bonus)
|
||||
self.strength = 2
|
||||
|
|
@ -362,17 +381,17 @@ class EvAdventureCharacterGeneration:
|
|||
self.charisma = 2
|
||||
|
||||
# physical attributes (only for rp purposes)
|
||||
self.physique = roll_engine.roll_random_table('1d20', chargen_table['physique'])
|
||||
self.face = roll_engine.roll_random_table('1d20', chargen_table['face'])
|
||||
self.skin = roll_engine.roll_random_table('1d20', chargen_table['skin'])
|
||||
self.hair = roll_engine.roll_random_table('1d20', chargen_table['hair'])
|
||||
self.clothing = roll_engine.roll_random_table('1d20', chargen_table['clothing'])
|
||||
self.speech = roll_engine.roll_random_table('1d20', chargen_table['speech'])
|
||||
self.virtue = roll_engine.roll_random_table('1d20', chargen_table['virtue'])
|
||||
self.vice = roll_engine.roll_random_table('1d20', chargen_table['vice'])
|
||||
self.background = roll_engine.roll_random_table('1d20', chargen_table['background'])
|
||||
self.misfortune = roll_engine.roll_random_table('1d20', chargen_table['misfortune'])
|
||||
self.alignment = roll_engine.roll_random_table('1d20', chargen_table['alignment'])
|
||||
self.physique = roll_engine.roll_random_table("1d20", chargen_table["physique"])
|
||||
self.face = roll_engine.roll_random_table("1d20", chargen_table["face"])
|
||||
self.skin = roll_engine.roll_random_table("1d20", chargen_table["skin"])
|
||||
self.hair = roll_engine.roll_random_table("1d20", chargen_table["hair"])
|
||||
self.clothing = roll_engine.roll_random_table("1d20", chargen_table["clothing"])
|
||||
self.speech = roll_engine.roll_random_table("1d20", chargen_table["speech"])
|
||||
self.virtue = roll_engine.roll_random_table("1d20", chargen_table["virtue"])
|
||||
self.vice = roll_engine.roll_random_table("1d20", chargen_table["vice"])
|
||||
self.background = roll_engine.roll_random_table("1d20", chargen_table["background"])
|
||||
self.misfortune = roll_engine.roll_random_table("1d20", chargen_table["misfortune"])
|
||||
self.alignment = roll_engine.roll_random_table("1d20", chargen_table["alignment"])
|
||||
|
||||
# same for all
|
||||
self.exploration_speed = 120
|
||||
|
|
@ -383,22 +402,23 @@ class EvAdventureCharacterGeneration:
|
|||
self.level = 1
|
||||
|
||||
# random equipment
|
||||
self.armor = roll_engine.roll_random_table('1d20', chargen_table['armor'])
|
||||
self.armor = roll_engine.roll_random_table("1d20", chargen_table["armor"])
|
||||
|
||||
_helmet_and_shield = roll_engine.roll_random_table(
|
||||
'1d20', chargen_table["helmets and shields"])
|
||||
"1d20", chargen_table["helmets and shields"]
|
||||
)
|
||||
self.helmet = "helmet" if "helmet" in _helmet_and_shield else "none"
|
||||
self.shield = "shield" if "shield" in _helmet_and_shield else "none"
|
||||
|
||||
self.weapon = roll_engine.roll_random_table('1d20', chargen_table["starting weapon"])
|
||||
self.weapon = roll_engine.roll_random_table("1d20", chargen_table["starting weapon"])
|
||||
|
||||
self.backpack = [
|
||||
"ration",
|
||||
"ration",
|
||||
roll_engine.roll_random_table('1d20', chargen_table["dungeoning gear"]),
|
||||
roll_engine.roll_random_table('1d20', chargen_table["dungeoning gear"]),
|
||||
roll_engine.roll_random_table('1d20', chargen_table["general gear 1"]),
|
||||
roll_engine.roll_random_table('1d20', chargen_table["general gear 2"]),
|
||||
roll_engine.roll_random_table("1d20", chargen_table["dungeoning gear"]),
|
||||
roll_engine.roll_random_table("1d20", chargen_table["dungeoning gear"]),
|
||||
roll_engine.roll_random_table("1d20", chargen_table["general gear 1"]),
|
||||
roll_engine.roll_random_table("1d20", chargen_table["general gear 2"]),
|
||||
]
|
||||
|
||||
def build_desc(self):
|
||||
|
|
@ -489,12 +509,14 @@ class EvAdventureCharacterGeneration:
|
|||
|
||||
# character improvement
|
||||
|
||||
|
||||
class EvAdventureImprovement:
|
||||
"""
|
||||
Handle XP gains and level upgrades. Grouped in a class in order to
|
||||
make it easier to override the mechanism.
|
||||
|
||||
"""
|
||||
|
||||
xp_per_level = 1000
|
||||
amount_of_abilities_to_upgrade = 3
|
||||
max_ability_bonus = 10 # bonus +10, defense 20
|
||||
|
|
@ -546,12 +568,14 @@ class EvAdventureImprovement:
|
|||
except AttributeError:
|
||||
pass
|
||||
|
||||
character.hp_max = max(character.max_hp + 1,
|
||||
EvAdventureRollEngine.roll(f"{character.level}d8"))
|
||||
character.hp_max = max(
|
||||
character.max_hp + 1, EvAdventureRollEngine.roll(f"{character.level}d8")
|
||||
)
|
||||
|
||||
|
||||
# character sheet visualization
|
||||
|
||||
|
||||
class EvAdventureCharacterSheet:
|
||||
"""
|
||||
Generate a character sheet. This is grouped in a class in order to make
|
||||
|
|
@ -596,9 +620,9 @@ class EvAdventureCharacterSheet:
|
|||
equipment = character.equipment.wielded + character.equipment.worn + character.carried
|
||||
# divide into chunks of max 10 length (to go into two columns)
|
||||
equipment_table = EvTable(
|
||||
table=[equipment[i: i + 10] for i in range(0, len(equipment), 10)]
|
||||
table=[equipment[i : i + 10] for i in range(0, len(equipment), 10)]
|
||||
)
|
||||
form = EvForm({"FORMCHAR": 'x', "TABLECHAR": 'c', "SHEET": sheet})
|
||||
form = EvForm({"FORMCHAR": "x", "TABLECHAR": "c", "SHEET": sheet})
|
||||
form.map(
|
||||
cells={
|
||||
1: character.key,
|
||||
|
|
@ -610,12 +634,12 @@ class EvAdventureCharacterSheet:
|
|||
7: f"{character.hp}/{character.hp_max}",
|
||||
8: character.xp,
|
||||
9: character.exploration_speed,
|
||||
'A': character.combat_speed,
|
||||
'B': character.db.desc,
|
||||
"A": character.combat_speed,
|
||||
"B": character.db.desc,
|
||||
},
|
||||
tables={
|
||||
1: equipment_table,
|
||||
}
|
||||
},
|
||||
)
|
||||
return str(form)
|
||||
|
||||
|
|
|
|||
|
|
@ -14,25 +14,33 @@ class EvAdventureMixin:
|
|||
Provides a set of pre-made characters.
|
||||
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.character = create.create_object(EvAdventureCharacter, key="testchar")
|
||||
self.helmet = create.create_object(
|
||||
EvAdventureObject, key="helmet",
|
||||
attributes=[("inventory_use_slot", enums.WieldLocation.HEAD),
|
||||
("armor", 1)])
|
||||
EvAdventureObject,
|
||||
key="helmet",
|
||||
attributes=[("inventory_use_slot", enums.WieldLocation.HEAD), ("armor", 1)],
|
||||
)
|
||||
self.shield = create.create_object(
|
||||
EvAdventureObject, key="shield",
|
||||
attributes=[("inventory_use_slot", enums.WieldLocation.SHIELD_HAND),
|
||||
("armor", 1)])
|
||||
EvAdventureObject,
|
||||
key="shield",
|
||||
attributes=[("inventory_use_slot", enums.WieldLocation.SHIELD_HAND), ("armor", 1)],
|
||||
)
|
||||
self.armor = create.create_object(
|
||||
EvAdventureObject, key="armor",
|
||||
attributes=[("inventory_use_slot", enums.WieldLocation.BODY),
|
||||
("armor", 11)])
|
||||
EvAdventureObject,
|
||||
key="armor",
|
||||
attributes=[("inventory_use_slot", enums.WieldLocation.BODY), ("armor", 11)],
|
||||
)
|
||||
self.weapon = create.create_object(
|
||||
EvAdventureObject, key="weapon",
|
||||
attributes=[("inventory_use_slot", enums.WieldLocation.WEAPON_HAND)])
|
||||
EvAdventureObject,
|
||||
key="weapon",
|
||||
attributes=[("inventory_use_slot", enums.WieldLocation.WEAPON_HAND)],
|
||||
)
|
||||
self.big_weapon = create.create_object(
|
||||
EvAdventureObject, key="big_weapon",
|
||||
attributes=[("inventory_use_slot", enums.WieldLocation.TWO_HANDS)])
|
||||
EvAdventureObject,
|
||||
key="big_weapon",
|
||||
attributes=[("inventory_use_slot", enums.WieldLocation.TWO_HANDS)],
|
||||
)
|
||||
self.item = create.create_object(EvAdventureObject, key="backpack item")
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from evennia.utils.test_resources import BaseEvenniaTest
|
|||
from evennia.utils import create
|
||||
from .mixins import EvAdventureMixin
|
||||
from .. import combat_turnbased
|
||||
from .. charactersd import EvAdventureCharacter
|
||||
from ..charactersd import EvAdventureCharacter
|
||||
|
||||
|
||||
class EvAdventureTurnbasedCombatHandlerTest(EvAdventureMixin, BaseEvenniaTest):
|
||||
|
|
@ -16,8 +16,12 @@ class EvAdventureTurnbasedCombatHandlerTest(EvAdventureMixin, BaseEvenniaTest):
|
|||
Test the turn-based combat-handler implementation.
|
||||
|
||||
"""
|
||||
@patch("evennia.contrib.tutorials.evadventure.combat_turnbased"
|
||||
".EvAdventureCombatHandler.interval", new=-1)
|
||||
|
||||
@patch(
|
||||
"evennia.contrib.tutorials.evadventure.combat_turnbased"
|
||||
".EvAdventureCombatHandler.interval",
|
||||
new=-1,
|
||||
)
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.combathandler = combat_turnbased.EvAdventureCombatHandler.objects.create()
|
||||
|
|
@ -50,8 +54,6 @@ class EvAdventureTurnbasedCombatHandlerTest(EvAdventureMixin, BaseEvenniaTest):
|
|||
def test_attack(self, mock_randint):
|
||||
mock_randint = 8
|
||||
self.combathandler.register_action(
|
||||
combat_turnbased.CombatActionAttack,
|
||||
self.combatant, self.target)
|
||||
combat_turnbased.CombatActionAttack, self.combatant, self.target
|
||||
)
|
||||
self.combathandler._end_turn()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ class EvAdventureRollEngineTest(BaseEvenniaTest):
|
|||
Test the roll engine in the rules module. This is the core of any RPG.
|
||||
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.roll_engine = rules.EvAdventureRollEngine()
|
||||
|
|
@ -40,15 +41,15 @@ class EvAdventureRollEngineTest(BaseEvenniaTest):
|
|||
|
||||
def test_roll_limits(self):
|
||||
with self.assertRaises(TypeError):
|
||||
self.roll_engine.roll('100d6', max_number=10) # too many die
|
||||
self.roll_engine.roll("100d6", max_number=10) # too many die
|
||||
with self.assertRaises(TypeError):
|
||||
self.roll_engine.roll('100') # no d
|
||||
self.roll_engine.roll("100") # no d
|
||||
with self.assertRaises(TypeError):
|
||||
self.roll_engine.roll('dummy') # non-numerical
|
||||
self.roll_engine.roll("dummy") # non-numerical
|
||||
with self.assertRaises(TypeError):
|
||||
self.roll_engine.roll('Ad4') # non-numerical
|
||||
self.roll_engine.roll("Ad4") # non-numerical
|
||||
with self.assertRaises(TypeError):
|
||||
self.roll_engine.roll('1d10000') # limit is d1000
|
||||
self.roll_engine.roll("1d10000") # limit is d1000
|
||||
|
||||
@patch("evennia.contrib.tutorials.evadventure.rules.randint")
|
||||
def test_roll_with_advantage_disadvantage(self, mock_randint):
|
||||
|
|
@ -61,19 +62,18 @@ class EvAdventureRollEngineTest(BaseEvenniaTest):
|
|||
|
||||
# cancel each other out
|
||||
self.assertEqual(
|
||||
self.roll_engine.roll_with_advantage_or_disadvantage(
|
||||
disadvantage=True, advantage=True), 9)
|
||||
self.roll_engine.roll_with_advantage_or_disadvantage(disadvantage=True, advantage=True),
|
||||
9,
|
||||
)
|
||||
mock_randint.assert_called_once()
|
||||
mock_randint.reset_mock()
|
||||
|
||||
# run with advantage/disadvantage
|
||||
self.assertEqual(
|
||||
self.roll_engine.roll_with_advantage_or_disadvantage(advantage=True), 9)
|
||||
self.assertEqual(self.roll_engine.roll_with_advantage_or_disadvantage(advantage=True), 9)
|
||||
mock_randint.assert_has_calls([call(1, 20), call(1, 20)])
|
||||
mock_randint.reset_mock()
|
||||
|
||||
self.assertEqual(
|
||||
self.roll_engine.roll_with_advantage_or_disadvantage(disadvantage=True), 9)
|
||||
self.assertEqual(self.roll_engine.roll_with_advantage_or_disadvantage(disadvantage=True), 9)
|
||||
mock_randint.assert_has_calls([call(1, 20), call(1, 20)])
|
||||
mock_randint.reset_mock()
|
||||
|
||||
|
|
@ -86,39 +86,40 @@ class EvAdventureRollEngineTest(BaseEvenniaTest):
|
|||
character.dexterity = 1
|
||||
|
||||
self.assertEqual(
|
||||
self.roll_engine.saving_throw(character, bonus_type=enums.Ability.STR),
|
||||
(False, None))
|
||||
self.roll_engine.saving_throw(character, bonus_type=enums.Ability.STR), (False, None)
|
||||
)
|
||||
self.assertEqual(
|
||||
self.roll_engine.saving_throw(character, bonus_type=enums.Ability.DEX, modifier=1),
|
||||
(False, None))
|
||||
(False, None),
|
||||
)
|
||||
self.assertEqual(
|
||||
self.roll_engine.saving_throw(
|
||||
character,
|
||||
advantage=True,
|
||||
bonus_type=enums.Ability.DEX, modifier=6),
|
||||
(False, None))
|
||||
character, advantage=True, bonus_type=enums.Ability.DEX, modifier=6
|
||||
),
|
||||
(False, None),
|
||||
)
|
||||
self.assertEqual(
|
||||
self.roll_engine.saving_throw(
|
||||
character,
|
||||
disadvantage=True,
|
||||
bonus_type=enums.Ability.DEX, modifier=7),
|
||||
(True, None))
|
||||
character, disadvantage=True, bonus_type=enums.Ability.DEX, modifier=7
|
||||
),
|
||||
(True, None),
|
||||
)
|
||||
|
||||
mock_randint.return_value = 1
|
||||
self.assertEqual(
|
||||
self.roll_engine.saving_throw(
|
||||
character,
|
||||
disadvantage=True,
|
||||
bonus_type=enums.Ability.STR, modifier=2),
|
||||
(False, enums.Ability.CRITICAL_FAILURE))
|
||||
character, disadvantage=True, bonus_type=enums.Ability.STR, modifier=2
|
||||
),
|
||||
(False, enums.Ability.CRITICAL_FAILURE),
|
||||
)
|
||||
|
||||
mock_randint.return_value = 20
|
||||
self.assertEqual(
|
||||
self.roll_engine.saving_throw(
|
||||
character,
|
||||
disadvantage=True,
|
||||
bonus_type=enums.Ability.STR, modifier=2),
|
||||
(True, enums.Ability.CRITICAL_SUCCESS))
|
||||
character, disadvantage=True, bonus_type=enums.Ability.STR, modifier=2
|
||||
),
|
||||
(True, enums.Ability.CRITICAL_SUCCESS),
|
||||
)
|
||||
|
||||
@patch("evennia.contrib.tutorials.evadventure.rules.randint")
|
||||
def test_opposed_saving_throw(self, mock_randint):
|
||||
|
|
@ -130,18 +131,19 @@ class EvAdventureRollEngineTest(BaseEvenniaTest):
|
|||
|
||||
self.assertEqual(
|
||||
self.roll_engine.opposed_saving_throw(
|
||||
attacker, defender,
|
||||
attack_type=enums.Ability.STR, defense_type=enums.Ability.ARMOR
|
||||
attacker, defender, attack_type=enums.Ability.STR, defense_type=enums.Ability.ARMOR
|
||||
),
|
||||
(False, None)
|
||||
(False, None),
|
||||
)
|
||||
self.assertEqual(
|
||||
self.roll_engine.opposed_saving_throw(
|
||||
attacker, defender,
|
||||
attack_type=enums.Ability.STR, defense_type=enums.Ability.ARMOR,
|
||||
modifier=2
|
||||
attacker,
|
||||
defender,
|
||||
attack_type=enums.Ability.STR,
|
||||
defense_type=enums.Ability.ARMOR,
|
||||
modifier=2,
|
||||
),
|
||||
(True, None)
|
||||
(True, None),
|
||||
)
|
||||
|
||||
@patch("evennia.contrib.tutorials.evadventure.rules.randint")
|
||||
|
|
@ -150,36 +152,40 @@ class EvAdventureRollEngineTest(BaseEvenniaTest):
|
|||
|
||||
self.assertEqual(
|
||||
self.roll_engine.roll_random_table(
|
||||
"1d20", random_tables.character_generation['physique']),
|
||||
"scrawny"
|
||||
"1d20", random_tables.character_generation["physique"]
|
||||
),
|
||||
"scrawny",
|
||||
)
|
||||
self.assertEqual(
|
||||
self.roll_engine.roll_random_table("1d20", random_tables.character_generation["vice"]),
|
||||
"irascible",
|
||||
)
|
||||
self.assertEqual(
|
||||
self.roll_engine.roll_random_table(
|
||||
"1d20", random_tables.character_generation['vice']),
|
||||
"irascible"
|
||||
"1d20", random_tables.character_generation["alignment"]
|
||||
),
|
||||
"neutrality",
|
||||
)
|
||||
self.assertEqual(
|
||||
self.roll_engine.roll_random_table(
|
||||
"1d20", random_tables.character_generation['alignment']),
|
||||
"neutrality"
|
||||
)
|
||||
self.assertEqual(
|
||||
self.roll_engine.roll_random_table(
|
||||
"1d20", random_tables.character_generation['helmets and shields']),
|
||||
"no helmet or shield"
|
||||
"1d20", random_tables.character_generation["helmets and shields"]
|
||||
),
|
||||
"no helmet or shield",
|
||||
)
|
||||
# testing faulty rolls outside of the table ranges
|
||||
mock_randint.return_value = 25
|
||||
self.assertEqual(
|
||||
self.roll_engine.roll_random_table(
|
||||
"1d20", random_tables.character_generation['helmets and shields']),
|
||||
"helmet and shield"
|
||||
"1d20", random_tables.character_generation["helmets and shields"]
|
||||
),
|
||||
"helmet and shield",
|
||||
)
|
||||
mock_randint.return_value = -10
|
||||
self.assertEqual(
|
||||
self.roll_engine.roll_random_table(
|
||||
"1d20", random_tables.character_generation['helmets and shields']),
|
||||
"no helmet or shield"
|
||||
"1d20", random_tables.character_generation["helmets and shields"]
|
||||
),
|
||||
"no helmet or shield",
|
||||
)
|
||||
|
||||
@patch("evennia.contrib.tutorials.evadventure.rules.randint")
|
||||
|
|
@ -202,11 +208,11 @@ class EvAdventureRollEngineTest(BaseEvenniaTest):
|
|||
|
||||
mock_randint.return_value = 5
|
||||
self.roll_engine.heal_from_rest(character)
|
||||
self.assertEqual(character.hp, 7) # hp + 1d8 + consititution bonus
|
||||
self.assertEqual(character.hp, 7) # hp + 1d8 + consititution bonus
|
||||
mock_randint.assert_called_with(1, 8) # 1d8
|
||||
|
||||
self.roll_engine.heal_from_rest(character)
|
||||
self.assertEqual(character.hp, 8) # can't have more than max hp
|
||||
self.assertEqual(character.hp, 8) # can't have more than max hp
|
||||
|
||||
@patch("evennia.contrib.tutorials.evadventure.rules.randint")
|
||||
def test_roll_death(self, mock_randint):
|
||||
|
|
@ -246,32 +252,33 @@ class EvAdventureCharacterGenerationTest(BaseEvenniaTest):
|
|||
self.assertEqual(self.chargen.misfortune, "exiled")
|
||||
self.assertEqual(self.chargen.armor, "gambeson")
|
||||
self.assertEqual(self.chargen.shield, "shield")
|
||||
self.assertEqual(self.chargen.backpack, ['ration', 'ration', 'waterskin',
|
||||
'waterskin', 'drill', 'twine'])
|
||||
self.assertEqual(
|
||||
self.chargen.backpack, ["ration", "ration", "waterskin", "waterskin", "drill", "twine"]
|
||||
)
|
||||
|
||||
def test_build_desc(self):
|
||||
self.assertEqual(
|
||||
self.chargen.build_desc(),
|
||||
"Herbalist. Wears stained clothes, and has hoarse speech. Has a scrawny physique, "
|
||||
"a broken face, pockmarked skin and greased hair. Is honest, but irascible. "
|
||||
"Has been exiled in the past. Favors neutrality."
|
||||
"Has been exiled in the past. Favors neutrality.",
|
||||
)
|
||||
|
||||
@parameterized.expand([
|
||||
# source, target, value, new_source_val, new_target_val
|
||||
(enums.Ability.CON, enums.Ability.STR, 1, 1, 3),
|
||||
(enums.Ability.INT, enums.Ability.DEX, 1, 1, 3),
|
||||
(enums.Ability.CHA, enums.Ability.CON, 1, 1, 3),
|
||||
(enums.Ability.STR, enums.Ability.WIS, 1, 1, 3),
|
||||
(enums.Ability.WIS, enums.Ability.CHA, 1, 1, 3),
|
||||
(enums.Ability.DEX, enums.Ability.DEX, 1, 2, 2),
|
||||
])
|
||||
@parameterized.expand(
|
||||
[
|
||||
# source, target, value, new_source_val, new_target_val
|
||||
(enums.Ability.CON, enums.Ability.STR, 1, 1, 3),
|
||||
(enums.Ability.INT, enums.Ability.DEX, 1, 1, 3),
|
||||
(enums.Ability.CHA, enums.Ability.CON, 1, 1, 3),
|
||||
(enums.Ability.STR, enums.Ability.WIS, 1, 1, 3),
|
||||
(enums.Ability.WIS, enums.Ability.CHA, 1, 1, 3),
|
||||
(enums.Ability.DEX, enums.Ability.DEX, 1, 2, 2),
|
||||
]
|
||||
)
|
||||
def test_adjust_attribute(self, source, target, value, new_source_val, new_target_val):
|
||||
self.chargen.adjust_attribute(source, target, value)
|
||||
self.assertEqual(
|
||||
getattr(self.chargen, source.value), new_source_val, f"{source}->{target}")
|
||||
self.assertEqual(
|
||||
getattr(self.chargen, target.value), new_target_val, f"{source}->{target}")
|
||||
self.assertEqual(getattr(self.chargen, source.value), new_source_val, f"{source}->{target}")
|
||||
self.assertEqual(getattr(self.chargen, target.value), new_target_val, f"{source}->{target}")
|
||||
|
||||
def test_adjust_consecutive(self):
|
||||
# gradually shift all to STR (starts at 2)
|
||||
|
|
@ -311,6 +318,7 @@ class EvAdventureEquipmentTest(EvAdventureMixin, BaseEvenniaTest):
|
|||
Test the equipment mechanism.
|
||||
|
||||
"""
|
||||
|
||||
def _get_empty_slots(self):
|
||||
return {
|
||||
enums.WieldLocation.BACKPACK: [],
|
||||
|
|
@ -324,15 +332,17 @@ class EvAdventureEquipmentTest(EvAdventureMixin, BaseEvenniaTest):
|
|||
def test_equipmenthandler_max_slots(self):
|
||||
self.assertEqual(self.character.equipment.max_slots, 11)
|
||||
|
||||
@parameterized.expand([
|
||||
# size, pass_validation?
|
||||
(1, True),
|
||||
(2, True),
|
||||
(11, True),
|
||||
(12, False),
|
||||
(20, False),
|
||||
(25, False)
|
||||
])
|
||||
@parameterized.expand(
|
||||
[
|
||||
# size, pass_validation?
|
||||
(1, True),
|
||||
(2, True),
|
||||
(11, True),
|
||||
(12, False),
|
||||
(20, False),
|
||||
(25, False),
|
||||
]
|
||||
)
|
||||
def test_validate_slot_usage(self, size, is_ok):
|
||||
obj = MagicMock()
|
||||
obj.size = size
|
||||
|
|
@ -343,15 +353,17 @@ class EvAdventureEquipmentTest(EvAdventureMixin, BaseEvenniaTest):
|
|||
with self.assertRaises(characters.EquipmentError):
|
||||
self.character.equipment.validate_slot_usage(obj)
|
||||
|
||||
@parameterized.expand([
|
||||
# item, where
|
||||
("helmet", enums.WieldLocation.HEAD),
|
||||
("shield", enums.WieldLocation.SHIELD_HAND),
|
||||
("armor", enums.WieldLocation.BODY),
|
||||
("weapon", enums.WieldLocation.WEAPON_HAND),
|
||||
("big_weapon", enums.WieldLocation.TWO_HANDS),
|
||||
("item", enums.WieldLocation.BACKPACK),
|
||||
])
|
||||
@parameterized.expand(
|
||||
[
|
||||
# item, where
|
||||
("helmet", enums.WieldLocation.HEAD),
|
||||
("shield", enums.WieldLocation.SHIELD_HAND),
|
||||
("armor", enums.WieldLocation.BODY),
|
||||
("weapon", enums.WieldLocation.WEAPON_HAND),
|
||||
("big_weapon", enums.WieldLocation.TWO_HANDS),
|
||||
("item", enums.WieldLocation.BACKPACK),
|
||||
]
|
||||
)
|
||||
def test_use(self, itemname, where):
|
||||
self.assertEqual(self.character.equipment.slots, self._get_empty_slots())
|
||||
|
||||
|
|
@ -366,32 +378,32 @@ class EvAdventureEquipmentTest(EvAdventureMixin, BaseEvenniaTest):
|
|||
def test_store(self):
|
||||
self.character.equipment.store(self.weapon)
|
||||
self.assertEqual(self.character.equipment.slots[enums.WieldLocation.WEAPON_HAND], None)
|
||||
self.assertTrue(
|
||||
self.weapon in self.character.equipment.slots[enums.WieldLocation.BACKPACK])
|
||||
self.assertTrue(self.weapon in self.character.equipment.slots[enums.WieldLocation.BACKPACK])
|
||||
|
||||
def test_two_handed_exclusive(self):
|
||||
"""Two-handed weapons can't be used together with weapon+shield"""
|
||||
self.character.equipment.use(self.big_weapon)
|
||||
self.assertEqual(
|
||||
self.character.equipment.slots[enums.WieldLocation.TWO_HANDS], self.big_weapon)
|
||||
self.character.equipment.slots[enums.WieldLocation.TWO_HANDS], self.big_weapon
|
||||
)
|
||||
# equipping sword or shield removes two-hander
|
||||
self.character.equipment.use(self.shield)
|
||||
self.assertEqual(
|
||||
self.character.equipment.slots[enums.WieldLocation.SHIELD_HAND], self.shield)
|
||||
self.assertEqual(
|
||||
self.character.equipment.slots[enums.WieldLocation.TWO_HANDS], None)
|
||||
self.character.equipment.slots[enums.WieldLocation.SHIELD_HAND], self.shield
|
||||
)
|
||||
self.assertEqual(self.character.equipment.slots[enums.WieldLocation.TWO_HANDS], None)
|
||||
self.character.equipment.use(self.weapon)
|
||||
self.assertEqual(
|
||||
self.character.equipment.slots[enums.WieldLocation.WEAPON_HAND], self.weapon)
|
||||
self.character.equipment.slots[enums.WieldLocation.WEAPON_HAND], self.weapon
|
||||
)
|
||||
|
||||
# the two-hander removes the two weapons
|
||||
self.character.equipment.use(self.big_weapon)
|
||||
self.assertEqual(
|
||||
self.character.equipment.slots[enums.WieldLocation.TWO_HANDS], self.big_weapon)
|
||||
self.assertEqual(
|
||||
self.character.equipment.slots[enums.WieldLocation.SHIELD_HAND], None)
|
||||
self.assertEqual(
|
||||
self.character.equipment.slots[enums.WieldLocation.WEAPON_HAND], None)
|
||||
self.character.equipment.slots[enums.WieldLocation.TWO_HANDS], self.big_weapon
|
||||
)
|
||||
self.assertEqual(self.character.equipment.slots[enums.WieldLocation.SHIELD_HAND], None)
|
||||
self.assertEqual(self.character.equipment.slots[enums.WieldLocation.WEAPON_HAND], None)
|
||||
|
||||
def test_remove__with_obj(self):
|
||||
self.character.equipment.use(self.shield)
|
||||
|
|
@ -399,16 +411,19 @@ class EvAdventureEquipmentTest(EvAdventureMixin, BaseEvenniaTest):
|
|||
self.character.equipment.store(self.weapon)
|
||||
|
||||
self.assertEqual(
|
||||
self.character.equipment.slots[enums.WieldLocation.SHIELD_HAND], self.shield)
|
||||
self.assertEqual(self.character.equipment.slots[enums.WieldLocation.BACKPACK],
|
||||
[self.item, self.weapon])
|
||||
self.character.equipment.slots[enums.WieldLocation.SHIELD_HAND], self.shield
|
||||
)
|
||||
self.assertEqual(
|
||||
self.character.equipment.slots[enums.WieldLocation.BACKPACK], [self.item, self.weapon]
|
||||
)
|
||||
|
||||
self.assertEqual(self.character.equipment.remove(self.shield), [self.shield])
|
||||
self.assertEqual(self.character.equipment.remove(self.item), [self.item])
|
||||
|
||||
self.assertEqual(self.character.equipment.slots[enums.WieldLocation.SHIELD_HAND], None)
|
||||
self.assertEqual(self.character.equipment.slots[enums.WieldLocation.BACKPACK],
|
||||
[self.weapon])
|
||||
self.assertEqual(
|
||||
self.character.equipment.slots[enums.WieldLocation.BACKPACK], [self.weapon]
|
||||
)
|
||||
|
||||
def test_remove__with_slot(self):
|
||||
self.character.equipment.use(self.shield)
|
||||
|
|
@ -416,17 +431,20 @@ class EvAdventureEquipmentTest(EvAdventureMixin, BaseEvenniaTest):
|
|||
self.character.equipment.store(self.helmet)
|
||||
|
||||
self.assertEqual(
|
||||
self.character.equipment.slots[enums.WieldLocation.SHIELD_HAND], self.shield)
|
||||
self.assertEqual(self.character.equipment.slots[enums.WieldLocation.BACKPACK],
|
||||
[self.item, self.helmet])
|
||||
|
||||
self.assertEqual(self.character.equipment.remove(enums.WieldLocation.SHIELD_HAND),
|
||||
[self.shield])
|
||||
self.assertEqual(self.character.equipment.remove(enums.WieldLocation.BACKPACK),
|
||||
[self.item, self.helmet])
|
||||
self.character.equipment.slots[enums.WieldLocation.SHIELD_HAND], self.shield
|
||||
)
|
||||
self.assertEqual(
|
||||
self.character.equipment.slots[enums.WieldLocation.BACKPACK], [self.item, self.helmet]
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
self.character.equipment.slots[enums.WieldLocation.SHIELD_HAND], None)
|
||||
self.character.equipment.remove(enums.WieldLocation.SHIELD_HAND), [self.shield]
|
||||
)
|
||||
self.assertEqual(
|
||||
self.character.equipment.remove(enums.WieldLocation.BACKPACK), [self.item, self.helmet]
|
||||
)
|
||||
|
||||
self.assertEqual(self.character.equipment.slots[enums.WieldLocation.SHIELD_HAND], None)
|
||||
self.assertEqual(self.character.equipment.slots[enums.WieldLocation.BACKPACK], [])
|
||||
|
||||
def test_properties(self):
|
||||
|
|
|
|||
|
|
@ -13,6 +13,3 @@ from . import enums
|
|||
from . import combat_turnbased
|
||||
from . import rules
|
||||
from . import random_tables
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,5 +2,3 @@
|
|||
Various utilities.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue