mirror of
https://github.com/evennia/evennia.git
synced 2026-03-31 04:57:16 +02:00
Correct for PEP8 compliance. Add contrib entry to README.
This commit is contained in:
parent
011ba18d5b
commit
0fb7d13d63
2 changed files with 116 additions and 106 deletions
|
|
@ -19,6 +19,8 @@ things you want from here into your game folder and change them there.
|
|||
for any game. Allows safe trading of any godds (including coin)
|
||||
* CharGen (Griatch 2011) - A simple Character creator for OOC mode.
|
||||
Meant as a starting point for a more fleshed-out system.
|
||||
* Clothing (BattleJenkins 2017) - A layered clothing system with
|
||||
slots for different types of garments auto-showing in description.
|
||||
* Custom gametime (Griatch, vlgeoff 2017) - Implements Evennia's
|
||||
gametime module but for custom game world-specific calendars.
|
||||
* Dice (Griatch 2012) - A fully featured dice rolling system.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Clothing items, when worn, are added to the character's description
|
|||
in a list. For example, if wearing the following clothing items:
|
||||
|
||||
a thin and delicate necklace
|
||||
a pair of regular ol' shoes
|
||||
a pair of regular ol' shoes
|
||||
one nice hat
|
||||
a very pretty dress
|
||||
|
||||
|
|
@ -16,17 +16,17 @@ A character's description may look like this:
|
|||
|
||||
Superuser(#1)
|
||||
This is User #1.
|
||||
|
||||
Superuser is wearing one nice hat, a thin and delicate necklace,
|
||||
|
||||
Superuser is wearing one nice hat, a thin and delicate necklace,
|
||||
a very pretty dress and a pair of regular ol' shoes.
|
||||
|
||||
|
||||
Characters can also specify the style of wear for their clothing - I.E.
|
||||
to wear a scarf 'tied into a tight knot around the neck' or 'draped
|
||||
loosely across the shoulders' - to add an easy avenue of customization.
|
||||
For example, after entering:
|
||||
|
||||
wear scarf draped loosely across the shoulders
|
||||
|
||||
|
||||
The garment appears like so in the description:
|
||||
|
||||
Superuser(#1)
|
||||
|
|
@ -50,69 +50,67 @@ inherit from ClothedCharacter in your game's characters.py file:
|
|||
from evennia.contrib.clothing import ClothedCharacter
|
||||
|
||||
class Character(ClothedCharacter):
|
||||
|
||||
|
||||
And do the same with the ClothedCharacterCmdSet in your game's
|
||||
default_cmdsets.py:
|
||||
|
||||
from evennia.contrib.clothing import ClothedCharacterCmdSet
|
||||
|
||||
class CharacterCmdSet(default_cmds.CharacterCmdSet):
|
||||
|
||||
|
||||
From here, you can use the default builder commands to create clothes
|
||||
with which to test the system:
|
||||
|
||||
|
||||
@create a pretty shirt : evennia.contrib.clothing.Clothing
|
||||
@set shirt/clothing_type = 'top'
|
||||
|
||||
"""
|
||||
|
||||
from evennia import DefaultObject
|
||||
from evennia import DefaultCharacter
|
||||
from evennia import default_cmds
|
||||
from evennia.commands.default.muxcommand import MuxCommand
|
||||
from evennia.utils import search
|
||||
from evennia.utils import list_to_string
|
||||
from evennia.utils import evtable
|
||||
|
||||
# Options start here.
|
||||
# Maximum character length of 'wear style' strings, or None for unlimited.
|
||||
WEARSTYLE_MAXLENGTH = 50
|
||||
WEARSTYLE_MAXLENGTH = 50
|
||||
# The order in which clothing types appear on the description. Untyped clothing goes last.
|
||||
CLOTHING_TYPE_ORDER = ['hat','jewelry','top','undershirt','gloves','fullbody','bottom','underpants','socks','shoes','accessory']
|
||||
CLOTHING_TYPE_ORDER = ['hat', 'jewelry', 'top', 'undershirt', 'gloves', 'fullbody', 'bottom',
|
||||
'underpants', 'socks', 'shoes', 'accessory']
|
||||
# The maximum number of each type of clothes that can be worn. Unlimited if untyped or not specified.
|
||||
CLOTHING_TYPE_LIMIT = {
|
||||
'hat':1,
|
||||
'gloves':1,
|
||||
'socks':1,
|
||||
'shoes':1
|
||||
'hat': 1,
|
||||
'gloves': 1,
|
||||
'socks': 1,
|
||||
'shoes': 1
|
||||
}
|
||||
# The maximum number of clothing items that can be worn, or None for unlimited.
|
||||
CLOTHING_OVERALL_LIMIT = 20
|
||||
CLOTHING_OVERALL_LIMIT = 20
|
||||
# What types of clothes will automatically cover what other types of clothes when worn.
|
||||
# Note that clothing only gets auto-covered if it's already worn when you put something
|
||||
# on that auto-covers it - for example, it's perfectly possible to have your underpants
|
||||
# showing if you put them on after your pants!
|
||||
CLOTHING_TYPE_AUTOCOVER = {
|
||||
'top':['undershirt'],
|
||||
'bottom':['underpants'],
|
||||
'fullbody':['undershirt','underpants'],
|
||||
'shoes':['socks']
|
||||
'top': ['undershirt'],
|
||||
'bottom': ['underpants'],
|
||||
'fullbody': ['undershirt', 'underpants'],
|
||||
'shoes': ['socks']
|
||||
}
|
||||
# Types of clothes that can't be used to cover other clothes.
|
||||
CLOTHING_TYPE_CANT_COVER_WITH = ['jewelry']
|
||||
|
||||
"""
|
||||
----------------------------------------------------------------------------
|
||||
HELPER FUNCTIONS START HERE
|
||||
----------------------------------------------------------------------------
|
||||
"""
|
||||
|
||||
# HELPER FUNCTIONS START HERE
|
||||
|
||||
def order_clothes_list(clothes_list):
|
||||
"""
|
||||
Orders a given clothes list by the order specified in CLOTHING_TYPE_ORDER.
|
||||
|
||||
|
||||
Args:
|
||||
clothes_list (list): List of clothing items to put in order
|
||||
|
||||
|
||||
Returns:
|
||||
ordered_clothes_list (list): The same list as passed, but re-ordered
|
||||
according to the hierarchy of clothing types
|
||||
|
|
@ -133,17 +131,18 @@ def order_clothes_list(clothes_list):
|
|||
ordered_clothes_list.insert(0, clothes)
|
||||
return ordered_clothes_list
|
||||
|
||||
|
||||
def get_worn_clothes(character, exclude_covered=False):
|
||||
"""
|
||||
Get a list of clothes worn by a given character.
|
||||
|
||||
|
||||
Args:
|
||||
character (obj): The character to get a list of worn clothes from.
|
||||
|
||||
|
||||
Kwargs:
|
||||
exclude_covered (bool): If True, excludes clothes covered by other
|
||||
clothing from the returned list.
|
||||
|
||||
|
||||
Returns:
|
||||
ordered_clothes_list (list): A list of clothing items worn by the
|
||||
given character, ordered according to
|
||||
|
|
@ -153,24 +152,25 @@ def get_worn_clothes(character, exclude_covered=False):
|
|||
clothes_list = []
|
||||
for thing in character.contents:
|
||||
# If uncovered or not excluding covered items
|
||||
if not thing.db.covered_by or exclude_covered == False:
|
||||
if not thing.db.covered_by or exclude_covered is False:
|
||||
# If 'worn' is True, add to the list
|
||||
if thing.db.worn:
|
||||
clothes_list.append(thing)
|
||||
# Might as well put them in order here too.
|
||||
ordered_clothes_list = order_clothes_list(clothes_list)
|
||||
return ordered_clothes_list
|
||||
|
||||
|
||||
|
||||
def clothing_type_count(clothes_list):
|
||||
"""
|
||||
Returns a dictionary of the number of each clothing type
|
||||
in a given list of clothing objects.
|
||||
|
||||
|
||||
Args:
|
||||
clothes_list (list): A list of clothing items from which
|
||||
to count the number of clothing types
|
||||
represented among them.
|
||||
|
||||
|
||||
Returns:
|
||||
types_count (dict): A dictionary of clothing types represented
|
||||
in the given list and the number of each
|
||||
|
|
@ -185,15 +185,16 @@ def clothing_type_count(clothes_list):
|
|||
else:
|
||||
types_count[type] += 1
|
||||
return types_count
|
||||
|
||||
|
||||
|
||||
def single_type_count(clothes_list, type):
|
||||
"""
|
||||
Returns an integer value of the number of a given type of clothing in a list.
|
||||
|
||||
|
||||
Args:
|
||||
clothes_list (list): List of clothing objects to count from
|
||||
type (str): Clothing type to count
|
||||
|
||||
|
||||
Returns:
|
||||
type_count (int): Number of garments of the specified type in the given
|
||||
list of clothing objects
|
||||
|
|
@ -205,19 +206,20 @@ def single_type_count(clothes_list, type):
|
|||
type_count += 1
|
||||
return type_count
|
||||
|
||||
|
||||
class Clothing(DefaultObject):
|
||||
|
||||
|
||||
def wear(self, wearer, wearstyle, quiet=False):
|
||||
"""
|
||||
Sets clothes to 'worn' and optionally echoes to the room.
|
||||
|
||||
Sets clothes to 'worn' and optionally echoes to the room.
|
||||
|
||||
Args:
|
||||
wearer (obj): character object wearing this clothing object
|
||||
wearstyle (True or str): string describing the style of wear or True for none
|
||||
|
||||
|
||||
Kwargs:
|
||||
quiet (bool): If false, does not message the room
|
||||
|
||||
|
||||
Notes:
|
||||
Optionally sets db.worn with a 'wearstyle' that appends a short passage to
|
||||
the end of the name of the clothing to describe how it's worn that shows
|
||||
|
|
@ -230,7 +232,8 @@ class Clothing(DefaultObject):
|
|||
to_cover = []
|
||||
if self.db.clothing_type and self.db.clothing_type in CLOTHING_TYPE_AUTOCOVER:
|
||||
for garment in get_worn_clothes(wearer):
|
||||
if garment.db.clothing_type and garment.db.clothing_type in CLOTHING_TYPE_AUTOCOVER[self.db.clothing_type]:
|
||||
if garment.db.clothing_type and garment.db.clothing_type \
|
||||
in CLOTHING_TYPE_AUTOCOVER[self.db.clothing_type]:
|
||||
to_cover.append(garment)
|
||||
garment.db.covered_by = self
|
||||
# Return if quiet
|
||||
|
|
@ -238,29 +241,29 @@ class Clothing(DefaultObject):
|
|||
return
|
||||
# Echo a message to the room
|
||||
message = "%s puts on %s" % (wearer, self.name)
|
||||
if not wearstyle == True:
|
||||
if wearstyle is not True:
|
||||
message = "%s wears %s %s" % (wearer, self.name, wearstyle)
|
||||
if to_cover:
|
||||
message = message + ", covering %s" % list_to_string(to_cover)
|
||||
wearer.location.msg_contents(message + ".")
|
||||
|
||||
|
||||
def remove(self, wearer, quiet=False):
|
||||
"""
|
||||
Removes worn clothes and optionally echoes to the room.
|
||||
|
||||
|
||||
Args:
|
||||
wearer (obj): character object wearing this clothing object
|
||||
|
||||
|
||||
Kwargs:
|
||||
quiet (bool): If false, does not message the room
|
||||
"""
|
||||
self.db.worn = False
|
||||
remove_message = "%s removes %s." % (wearer, self.name)
|
||||
uncovered_list = []
|
||||
|
||||
|
||||
# Check to see if any other clothes are covered by this object.
|
||||
for thing in wearer.contents:
|
||||
# If anything is covered by
|
||||
# If anything is covered by
|
||||
if thing.db.covered_by == self:
|
||||
thing.db.covered_by = False
|
||||
uncovered_list.append(thing.name)
|
||||
|
|
@ -269,7 +272,7 @@ class Clothing(DefaultObject):
|
|||
# Echo a message to the room
|
||||
if not quiet:
|
||||
wearer.location.msg_contents(remove_message)
|
||||
|
||||
|
||||
def at_get(self, getter):
|
||||
"""
|
||||
Makes absolutely sure clothes aren't already set as 'worn'
|
||||
|
|
@ -277,7 +280,8 @@ class Clothing(DefaultObject):
|
|||
location changed without getting removed.
|
||||
"""
|
||||
self.db.worn = False
|
||||
|
||||
|
||||
|
||||
class ClothedCharacter(DefaultCharacter):
|
||||
"""
|
||||
Character that displays worn clothing when looked at. You can also
|
||||
|
|
@ -291,7 +295,7 @@ class ClothedCharacter(DefaultCharacter):
|
|||
|
||||
Args:
|
||||
looker (Object): Object doing the looking.
|
||||
|
||||
|
||||
Notes:
|
||||
The name of every clothing item carried and worn by the character
|
||||
is appended to their description. If the clothing's db.worn value
|
||||
|
|
@ -309,7 +313,7 @@ class ClothedCharacter(DefaultCharacter):
|
|||
# Append worn, uncovered clothing to the description
|
||||
for garment in clothes_list:
|
||||
# If 'worn' is True, just append the name
|
||||
if garment.db.worn == True:
|
||||
if garment.db.worn is True:
|
||||
worn_string_list.append(garment.name)
|
||||
# Otherwise, append the name and the string value of 'worn'
|
||||
elif garment.db.worn:
|
||||
|
|
@ -323,37 +327,9 @@ class ClothedCharacter(DefaultCharacter):
|
|||
string += "|/|/%s is not wearing anything." % self
|
||||
return string
|
||||
|
||||
"""
|
||||
----------------------------------------------------------------------------
|
||||
COMMANDS START HERE
|
||||
----------------------------------------------------------------------------
|
||||
"""
|
||||
|
||||
class ClothedCharacterCmdSet(default_cmds.CharacterCmdSet):
|
||||
"""
|
||||
Command set for clothing, including new versions of 'give' and 'drop'
|
||||
that take worn and covered clothing into account, as well as a new
|
||||
version of 'inventory' that differentiates between carried and worn
|
||||
items.
|
||||
"""
|
||||
key = "DefaultCharacter"
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
"""
|
||||
Populates the cmdset
|
||||
"""
|
||||
super(ClothedCharacterCmdSet, self).at_cmdset_creation()
|
||||
#
|
||||
# any commands you add below will overload the default ones.
|
||||
#
|
||||
self.add(CmdWear())
|
||||
self.add(CmdRemove())
|
||||
self.add(CmdCover())
|
||||
self.add(CmdUncover())
|
||||
self.add(CmdGive())
|
||||
self.add(CmdDrop())
|
||||
self.add(CmdInventory())
|
||||
|
||||
# COMMANDS START HERE
|
||||
|
||||
class CmdWear(MuxCommand):
|
||||
"""
|
||||
Puts on an item of clothing you are holding.
|
||||
|
|
@ -364,10 +340,10 @@ class CmdWear(MuxCommand):
|
|||
Examples:
|
||||
wear shirt
|
||||
wear scarf wrapped loosely about the shoulders
|
||||
|
||||
|
||||
All the clothes you are wearing are appended to your description.
|
||||
If you provide a 'wear style' after the command, the message you
|
||||
provide will be displayed after the clothing's name.
|
||||
provide will be displayed after the clothing's name.
|
||||
"""
|
||||
|
||||
key = "wear"
|
||||
|
|
@ -387,12 +363,12 @@ class CmdWear(MuxCommand):
|
|||
if not clothing.is_typeclass("evennia.contrib.clothing.Clothing"):
|
||||
self.caller.msg("That's not clothes!")
|
||||
return
|
||||
|
||||
|
||||
# Enforce overall clothing limit.
|
||||
if CLOTHING_OVERALL_LIMIT and len(get_worn_clothes(self.caller)) >= CLOTHING_OVERALL_LIMIT:
|
||||
self.caller.msg("You can't wear any more clothes.")
|
||||
return
|
||||
|
||||
|
||||
# Apply individual clothing type limits.
|
||||
if clothing.db.clothing_type and not clothing.db.worn:
|
||||
type_count = single_type_count(get_worn_clothes(self.caller), clothing.db.clothing_type)
|
||||
|
|
@ -400,7 +376,7 @@ class CmdWear(MuxCommand):
|
|||
if type_count >= CLOTHING_TYPE_LIMIT[clothing.db.clothing_type]:
|
||||
self.caller.msg("You can't wear any more clothes of the type '%s'." % clothing.db.clothing_type)
|
||||
return
|
||||
|
||||
|
||||
if clothing.db.worn and len(self.arglist) == 1:
|
||||
self.caller.msg("You're already wearing %s!" % clothing.name)
|
||||
return
|
||||
|
|
@ -413,14 +389,15 @@ class CmdWear(MuxCommand):
|
|||
else:
|
||||
wearstyle = wearstring
|
||||
clothing.wear(self.caller, wearstyle)
|
||||
|
||||
|
||||
|
||||
class CmdRemove(MuxCommand):
|
||||
"""
|
||||
Takes off an item of clothing.
|
||||
|
||||
|
||||
Usage:
|
||||
remove <obj>
|
||||
|
||||
|
||||
Removes an item of clothing you are wearing. You can't remove
|
||||
clothes that are covered up by something else - you must take
|
||||
off the covering item first.
|
||||
|
|
@ -444,13 +421,14 @@ class CmdRemove(MuxCommand):
|
|||
return
|
||||
clothing.remove(self.caller)
|
||||
|
||||
|
||||
class CmdCover(MuxCommand):
|
||||
"""
|
||||
Covers a worn item of clothing with another you're holding or wearing.
|
||||
|
||||
|
||||
Usage:
|
||||
cover <obj> [with] <obj>
|
||||
|
||||
|
||||
When you cover a clothing item, it is hidden and no longer appears in
|
||||
your description until it's uncovered or the item covering it is removed.
|
||||
You can't remove an item of clothing if it's covered.
|
||||
|
|
@ -463,7 +441,7 @@ class CmdCover(MuxCommand):
|
|||
"""
|
||||
This performs the actual command.
|
||||
"""
|
||||
|
||||
|
||||
if len(self.arglist) < 2:
|
||||
self.caller.msg("Usage: cover <worn clothing> [with] <clothing object>")
|
||||
return
|
||||
|
|
@ -497,17 +475,18 @@ class CmdCover(MuxCommand):
|
|||
self.caller.msg("%s is already covered by %s." % (cover_with.name, to_cover.db.covered_by.name))
|
||||
return
|
||||
if not cover_with.db.worn:
|
||||
cover_with.wear(self.caller, True) #Put on the item to cover with if it's not on already
|
||||
cover_with.wear(self.caller, True) # Put on the item to cover with if it's not on already
|
||||
self.caller.location.msg_contents("%s covers %s with %s." % (self.caller, to_cover.name, cover_with.name))
|
||||
to_cover.db.covered_by = cover_with
|
||||
|
||||
|
||||
|
||||
class CmdUncover(MuxCommand):
|
||||
"""
|
||||
Reveals a worn item of clothing that's currently covered up.
|
||||
|
||||
|
||||
Usage:
|
||||
uncover <obj>
|
||||
|
||||
|
||||
When you uncover an item of clothing, you allow it to appear in your
|
||||
description without having to take off the garment that's currently
|
||||
covering it. You can't uncover an item of clothing if the item covering
|
||||
|
|
@ -521,7 +500,7 @@ class CmdUncover(MuxCommand):
|
|||
"""
|
||||
This performs the actual command.
|
||||
"""
|
||||
|
||||
|
||||
if not self.args:
|
||||
self.caller.msg("Usage: uncover <worn clothing object>")
|
||||
return
|
||||
|
|
@ -541,7 +520,8 @@ class CmdUncover(MuxCommand):
|
|||
return
|
||||
self.caller.location.msg_contents("%s uncovers %s." % (self.caller, to_uncover.name))
|
||||
to_uncover.db.covered_by = None
|
||||
|
||||
|
||||
|
||||
class CmdDrop(MuxCommand):
|
||||
"""
|
||||
drop something
|
||||
|
|
@ -572,7 +552,7 @@ class CmdDrop(MuxCommand):
|
|||
multimatch_string="You carry more than one %s:" % self.args)
|
||||
if not obj:
|
||||
return
|
||||
|
||||
|
||||
# This part is new!
|
||||
# You can't drop clothing items that are covered.
|
||||
if obj.db.covered_by:
|
||||
|
|
@ -589,7 +569,8 @@ class CmdDrop(MuxCommand):
|
|||
exclude=caller)
|
||||
# Call the object script's at_drop() method.
|
||||
obj.at_drop(caller)
|
||||
|
||||
|
||||
|
||||
class CmdGive(MuxCommand):
|
||||
"""
|
||||
give away something to someone
|
||||
|
|
@ -623,7 +604,7 @@ class CmdGive(MuxCommand):
|
|||
if not to_give.location == caller:
|
||||
caller.msg("You are not holding %s." % to_give.key)
|
||||
return
|
||||
# This is new! Can't give away something that's worn.
|
||||
# This is new! Can't give away something that's worn.
|
||||
if to_give.db.covered_by:
|
||||
caller.msg("You can't give that away because it's covered by %s." % to_give.db.covered_by)
|
||||
return
|
||||
|
|
@ -637,7 +618,8 @@ class CmdGive(MuxCommand):
|
|||
target.msg("%s gives you %s." % (caller.key, to_give.key))
|
||||
# Call the object script's at_give() method.
|
||||
to_give.at_give(caller, target)
|
||||
|
||||
|
||||
|
||||
class CmdInventory(MuxCommand):
|
||||
"""
|
||||
view inventory
|
||||
|
|
@ -650,7 +632,7 @@ class CmdInventory(MuxCommand):
|
|||
"""
|
||||
# Alternate version of the inventory command which separates
|
||||
# worn and carried items.
|
||||
|
||||
|
||||
key = "inventory"
|
||||
aliases = ["inv", "i"]
|
||||
locks = "cmd:all()"
|
||||
|
|
@ -661,7 +643,7 @@ class CmdInventory(MuxCommand):
|
|||
if not self.caller.contents:
|
||||
self.caller.msg("You are not carrying or wearing anything.")
|
||||
return
|
||||
|
||||
|
||||
items = self.caller.contents
|
||||
|
||||
carry_table = evtable.EvTable(border="header")
|
||||
|
|
@ -679,3 +661,29 @@ class CmdInventory(MuxCommand):
|
|||
wear_table.add_row("|CNothing.|n", "")
|
||||
string += "|/|wYou are wearing:\n%s" % wear_table
|
||||
self.caller.msg(string)
|
||||
|
||||
|
||||
class ClothedCharacterCmdSet(default_cmds.CharacterCmdSet):
|
||||
"""
|
||||
Command set for clothing, including new versions of 'give' and 'drop'
|
||||
that take worn and covered clothing into account, as well as a new
|
||||
version of 'inventory' that differentiates between carried and worn
|
||||
items.
|
||||
"""
|
||||
key = "DefaultCharacter"
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
"""
|
||||
Populates the cmdset
|
||||
"""
|
||||
super(ClothedCharacterCmdSet, self).at_cmdset_creation()
|
||||
#
|
||||
# any commands you add below will overload the default ones.
|
||||
#
|
||||
self.add(CmdWear())
|
||||
self.add(CmdRemove())
|
||||
self.add(CmdCover())
|
||||
self.add(CmdUncover())
|
||||
self.add(CmdGive())
|
||||
self.add(CmdDrop())
|
||||
self.add(CmdInventory())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue