Made several tutorial doc pages
This commit is contained in:
parent
fe9157da16
commit
39735626e1
393 changed files with 4534 additions and 170 deletions
|
|
@ -57,8 +57,10 @@ class LivingMixin:
|
|||
|
||||
if healer is self:
|
||||
self.msg(f"|gYou heal yourself for {healed} health.|n")
|
||||
else:
|
||||
elif healer:
|
||||
self.msg(f"|g{healer.key} heals you for {healed} health.|n")
|
||||
else:
|
||||
self.msg(f"You are healed for {healed} health.")
|
||||
|
||||
def at_damage(self, damage, attacker=None):
|
||||
"""
|
||||
|
|
@ -82,15 +84,14 @@ class LivingMixin:
|
|||
"""
|
||||
pass
|
||||
|
||||
def at_do_loot(self, looted):
|
||||
def at_pay(self, amount):
|
||||
"""
|
||||
Called when looting another entity.
|
||||
|
||||
Args:
|
||||
looted: The thing to loot.
|
||||
Get coins, but no more than we actually have.
|
||||
|
||||
"""
|
||||
looted.at_looted()
|
||||
amount = min(amount, self.coins)
|
||||
self.coins -= amount
|
||||
return amount
|
||||
|
||||
def at_looted(self, looter):
|
||||
"""
|
||||
|
|
@ -101,9 +102,8 @@ class LivingMixin:
|
|||
|
||||
"""
|
||||
max_steal = rules.dice.roll("1d10")
|
||||
owned = self.coin
|
||||
stolen = max(max_steal, owned)
|
||||
self.coins -= stolen
|
||||
stolen = self.at_pay(max_steal)
|
||||
|
||||
looter.coins += stolen
|
||||
|
||||
self.location.msg_contents(
|
||||
|
|
@ -125,6 +125,16 @@ class LivingMixin:
|
|||
"""
|
||||
pass
|
||||
|
||||
def at_do_loot(self, defeated_enemy):
|
||||
"""
|
||||
Called when looting another entity.
|
||||
|
||||
Args:
|
||||
defeated_enemy: The thing to loot.
|
||||
|
||||
"""
|
||||
defeated_enemy.at_looted(self)
|
||||
|
||||
def post_loot(self, defeated_enemy):
|
||||
"""
|
||||
Called just after having looted an enemy.
|
||||
|
|
@ -138,8 +148,7 @@ class LivingMixin:
|
|||
|
||||
class EvAdventureCharacter(LivingMixin, DefaultCharacter):
|
||||
"""
|
||||
A Character for use with EvAdventure. This also works fine for
|
||||
monsters and NPCS.
|
||||
A Character for use with EvAdventure.
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -153,17 +162,12 @@ class EvAdventureCharacter(LivingMixin, DefaultCharacter):
|
|||
wisdom = AttributeProperty(default=1)
|
||||
charisma = AttributeProperty(default=1)
|
||||
|
||||
exploration_speed = AttributeProperty(default=120)
|
||||
combat_speed = AttributeProperty(default=40)
|
||||
|
||||
hp = AttributeProperty(default=4)
|
||||
hp_max = AttributeProperty(default=4)
|
||||
level = AttributeProperty(default=1)
|
||||
xp = AttributeProperty(default=0)
|
||||
coins = AttributeProperty(default=0) # copper coins
|
||||
|
||||
morale = AttributeProperty(default=9) # only used for NPC/monster morale checks
|
||||
|
||||
@lazy_property
|
||||
def equipment(self):
|
||||
"""Allows to access equipment like char.equipment.worn"""
|
||||
|
|
@ -244,13 +248,6 @@ class EvAdventureCharacter(LivingMixin, DefaultCharacter):
|
|||
"""
|
||||
if self.location.allow_death:
|
||||
rules.dice.roll_death(self)
|
||||
if self.hp > 0:
|
||||
# still alive, but lost some stats
|
||||
self.location.msg_contents(
|
||||
"|y$You() $conj(stagger) back and fall to the ground - alive, "
|
||||
"but unable to move.|n",
|
||||
from_obj=self,
|
||||
)
|
||||
else:
|
||||
self.location.msg_contents("|y$You() $conj(yield), beaten and out of the fight.|n")
|
||||
self.hp = self.hp_max
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ class EquipmentHandler:
|
|||
(
|
||||
# armor is listed using its defense, so we remove 10 from it
|
||||
# (11 is base no-armor value in Knave)
|
||||
getattr(slots[WieldLocation.BODY], "armor", 11) - 10,
|
||||
getattr(slots[WieldLocation.BODY], "armor", 1),
|
||||
# shields and helmets are listed by their bonus to armor
|
||||
getattr(slots[WieldLocation.SHIELD_HAND], "armor", 0),
|
||||
getattr(slots[WieldLocation.HEAD], "armor", 0),
|
||||
|
|
|
|||
|
|
@ -39,11 +39,11 @@ class EvAdventureObject(DefaultObject):
|
|||
value = AttributeProperty(0)
|
||||
|
||||
# can also be an iterable, for adding multiple obj-type tags
|
||||
obj_type = ObjType.TREASURE.value
|
||||
obj_type = ObjType.GEAR
|
||||
|
||||
def at_object_creation(self):
|
||||
for obj_type in make_iter(self.obj_type):
|
||||
self.tags.add(obj_type, category="obj_type")
|
||||
self.tags.add(obj_type.value, category="obj_type")
|
||||
|
||||
def get_display_header(self, looker, **kwargs):
|
||||
return "" # this is handled by get_obj_stats
|
||||
|
|
@ -68,43 +68,7 @@ class EvAdventureObject(DefaultObject):
|
|||
str: The help text, by default taken from the `.help_text` property.
|
||||
|
||||
"""
|
||||
return self.help_text
|
||||
|
||||
def at_pre_use(self, user, *args, **kwargs):
|
||||
"""
|
||||
Called before this item is used.
|
||||
|
||||
Args:
|
||||
user (Object): The one using the item.
|
||||
*args, **kwargs: Optional arguments.
|
||||
|
||||
Return:
|
||||
bool: False to stop usage.
|
||||
|
||||
"""
|
||||
return self.uses > 0
|
||||
|
||||
def at_use(self, user, *args, **kwargs):
|
||||
"""
|
||||
Called when this item is used.
|
||||
|
||||
Args:
|
||||
user (Object): The one using the item.
|
||||
*args, **kwargs: Optional arguments.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def at_post_use(self, user, *args, **kwargs):
|
||||
"""
|
||||
Called after this item was used.
|
||||
|
||||
Args:
|
||||
user (Object): The one using the item.
|
||||
*args, **kwargs: Optional arguments.
|
||||
|
||||
"""
|
||||
self.uses -= 1
|
||||
return "No help for this item."
|
||||
|
||||
|
||||
class EvAdventureObjectFiller(EvAdventureObject):
|
||||
|
|
@ -124,13 +88,13 @@ class EvAdventureObjectFiller(EvAdventureObject):
|
|||
quality = AttributeProperty(0)
|
||||
|
||||
|
||||
class EvAdventureQuest(EvAdventureObject):
|
||||
class EvAdventureQuestObject(EvAdventureObject):
|
||||
"""
|
||||
A quest object. These cannot be sold and only be used for quest resolution.
|
||||
|
||||
"""
|
||||
|
||||
obj_type = ObjType.QUEST.value
|
||||
obj_type = ObjType.QUEST
|
||||
value = AttributeProperty(0)
|
||||
|
||||
|
||||
|
|
@ -140,7 +104,7 @@ class EvAdventureTreasure(EvAdventureObject):
|
|||
|
||||
"""
|
||||
|
||||
obj_type = ObjType.TREASURE.value
|
||||
obj_type = ObjType.TREASURE
|
||||
value = AttributeProperty(100)
|
||||
|
||||
|
||||
|
|
@ -151,7 +115,7 @@ class EvAdventureConsumable(EvAdventureObject):
|
|||
|
||||
"""
|
||||
|
||||
obj_type = ObjType.CONSUMABLE.value
|
||||
obj_type = ObjType.CONSUMABLE
|
||||
size = AttributeProperty(0.25)
|
||||
uses = AttributeProperty(1)
|
||||
|
||||
|
|
@ -188,7 +152,7 @@ class WeaponEmptyHand:
|
|||
|
||||
"""
|
||||
|
||||
obj_type = ObjType.WEAPON.value
|
||||
obj_type = ObjType.WEAPON
|
||||
key = "Empty Fists"
|
||||
inventory_use_slot = WieldLocation.WEAPON_HAND
|
||||
attack_type = Ability.STR
|
||||
|
|
@ -206,7 +170,7 @@ class EvAdventureWeapon(EvAdventureObject):
|
|||
|
||||
"""
|
||||
|
||||
obj_type = ObjType.WEAPON.value
|
||||
obj_type = ObjType.WEAPON
|
||||
inventory_use_slot = AttributeProperty(WieldLocation.WEAPON_HAND)
|
||||
quality = AttributeProperty(3)
|
||||
|
||||
|
|
@ -217,7 +181,7 @@ class EvAdventureWeapon(EvAdventureObject):
|
|||
damage_roll = AttributeProperty("1d6")
|
||||
|
||||
|
||||
class EvAdventureRunestone(EvAdventureWeapon):
|
||||
class EvAdventureRunestone(EvAdventureWeapon, EvAdventureConsumable):
|
||||
"""
|
||||
Base class for magic runestones. In _Knave_, every spell is represented by a rune stone
|
||||
that takes up an inventory slot. It is wielded as a weapon in order to create the specific
|
||||
|
|
@ -226,14 +190,23 @@ class EvAdventureRunestone(EvAdventureWeapon):
|
|||
|
||||
"""
|
||||
|
||||
obj_type = (ObjType.WEAPON.value, ObjType.MAGIC.value)
|
||||
inventory_use_slot = AttributeProperty(WieldLocation.TWO_HANDS)
|
||||
obj_type = (ObjType.WEAPON, ObjType.MAGIC)
|
||||
inventory_use_slot = WieldLocation.TWO_HANDS
|
||||
quality = AttributeProperty(3)
|
||||
|
||||
attack_type = AttributeProperty(Ability.INT)
|
||||
defense_type = AttributeProperty(Ability.DEX)
|
||||
damage_roll = AttributeProperty("1d8")
|
||||
|
||||
def at_post_use(self, user, *args, **kwargs):
|
||||
"""Called after the spell was cast"""
|
||||
self.uses -= 1
|
||||
# the rune stone is not deleted after use, but
|
||||
# it needs to be refreshed after resting.
|
||||
|
||||
def refresh(self):
|
||||
self.uses = 1
|
||||
|
||||
|
||||
class EvAdventureArmor(EvAdventureObject):
|
||||
"""
|
||||
|
|
@ -241,9 +214,10 @@ class EvAdventureArmor(EvAdventureObject):
|
|||
|
||||
"""
|
||||
|
||||
obj_type = ObjType.ARMOR.value
|
||||
inventory_use_slot = AttributeProperty(WieldLocation.BODY)
|
||||
armor = AttributeProperty(11)
|
||||
obj_type = ObjType.ARMOR
|
||||
inventory_use_slot = WieldLocation.BODY
|
||||
|
||||
armor = AttributeProperty(1)
|
||||
quality = AttributeProperty(3)
|
||||
|
||||
|
||||
|
|
@ -253,9 +227,8 @@ class EvAdventureShield(EvAdventureArmor):
|
|||
|
||||
"""
|
||||
|
||||
obj_type = ObjType.SHIELD.value
|
||||
inventory_use_slot = AttributeProperty(WieldLocation.SHIELD_HAND)
|
||||
armor = AttributeProperty(1)
|
||||
obj_type = ObjType.SHIELD
|
||||
inventory_use_slot = WieldLocation.SHIELD_HAND
|
||||
|
||||
|
||||
class EvAdventureHelmet(EvAdventureArmor):
|
||||
|
|
@ -264,6 +237,5 @@ class EvAdventureHelmet(EvAdventureArmor):
|
|||
|
||||
"""
|
||||
|
||||
obj_type = ObjType.HELMET.value
|
||||
inventory_use_slot = AttributeProperty(WieldLocation.HEAD)
|
||||
armor = AttributeProperty(1)
|
||||
obj_type = ObjType.HELMET
|
||||
inventory_use_slot = WieldLocation.HEAD
|
||||
|
|
|
|||
|
|
@ -289,18 +289,6 @@ class EvAdventureRollEngine:
|
|||
"""
|
||||
return self.roll("2d6") <= defender.morale
|
||||
|
||||
def heal(self, character, amount):
|
||||
"""
|
||||
Heal specific amount, but not more than our max.
|
||||
|
||||
Args:
|
||||
character (EvAdventureCharacter): The character to heal
|
||||
amount (int): How many HP to heal.
|
||||
|
||||
"""
|
||||
damage = character.hp_max - character.hp
|
||||
character.hp += min(damage, amount)
|
||||
|
||||
def heal_from_rest(self, character):
|
||||
"""
|
||||
A meal and a full night's rest allow for regaining 1d8 + Const bonus HP.
|
||||
|
|
@ -312,7 +300,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)
|
||||
character.heal(self.roll("1d8") + character.constitution)
|
||||
|
||||
death_map = {
|
||||
"weakened": "strength",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
"""
|
||||
Test characters.
|
||||
|
||||
"""
|
||||
|
||||
from evennia.utils import create
|
||||
from evennia.utils.test_resources import BaseEvenniaTest
|
||||
|
||||
from ..characters import EvAdventureCharacter
|
||||
|
||||
|
||||
class TestCharacters(BaseEvenniaTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.character = create.create_object(EvAdventureCharacter, key="testchar")
|
||||
|
||||
def test_abilities(self):
|
||||
self.character.strength += 2
|
||||
self.assertEqual(self.character.strength, 3)
|
||||
|
||||
def test_heal(self):
|
||||
"""Make sure we don't heal too much"""
|
||||
self.character.hp = 0
|
||||
self.character.hp_max = 8
|
||||
|
||||
self.character.heal(1)
|
||||
self.assertEqual(self.character.hp, 1)
|
||||
self.character.heal(100)
|
||||
self.assertEqual(self.character.hp, 8)
|
||||
|
||||
def test_at_damage(self):
|
||||
self.character.hp = 8
|
||||
self.character.at_damage(5)
|
||||
self.assertEqual(self.character.hp, 3)
|
||||
|
||||
def test_at_pay(self):
|
||||
self.character.coins = 100
|
||||
|
||||
result = self.character.at_pay(60)
|
||||
self.assertEqual(result, 60)
|
||||
self.assertEqual(self.character.coins, 40)
|
||||
|
||||
# can't get more coins than we have
|
||||
result = self.character.at_pay(100)
|
||||
self.assertEqual(result, 40)
|
||||
self.assertEqual(self.characer.coins, 0)
|
||||
Loading…
Add table
Add a link
Reference in a new issue