Correct for PEP8 compliance. Add contrib entry to README.

This commit is contained in:
Griatch 2017-04-17 08:43:01 +02:00
parent 011ba18d5b
commit 0fb7d13d63
2 changed files with 116 additions and 106 deletions

View file

@ -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.

View file

@ -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())