Fix merge conflicts against master branch.

This commit is contained in:
Griatch 2017-02-18 12:08:51 +01:00
commit 517ce93bb4
8 changed files with 394 additions and 374 deletions

View file

@ -38,10 +38,10 @@ B sees: You are now trading with A. Use 'trade help' for aid.
A: offer sword: This is a nice sword. I would need some rations in trade.
B sees: A says: "This is a nice sword. I would need some rations in trade."
[A offers Sword of might.]
B evalute sword
B evaluate sword
B sees: <Sword's description and possibly stats>
B: offer ration: This is a prime ration.
A sees: B says: "These is a prime ration."
A sees: B says: "This is a prime ration."
[B offers iron ration]
A: say Hey, this is a nice sword, I need something more for it.
B sees: A says: "Hey this is a nice sword, I need something more for it."
@ -136,7 +136,7 @@ class TradeHandler(object):
Objects of this class handles the ongoing trade, notably storing the current
offers from each side and wether both have accepted or not.
"""
def __init__(self, partA, partB):
def __init__(self, part_a, part_b):
"""
Initializes the trade. This is called when part A tries to
initiate a trade with part B. The trade will not start until
@ -144,8 +144,8 @@ class TradeHandler(object):
command)
Args:
partA (object): The party trying to start barter.
partB (object): The party asked to barter.
part_a (object): The party trying to start barter.
part_b (object): The party asked to barter.
Notes:
We also store the back-reference from the respective party
@ -153,17 +153,17 @@ class TradeHandler(object):
"""
# parties
self.partA = partA
self.partB = partB
self.part_a = part_a
self.part_b = part_b
self.partA.cmdset.add(CmdsetTrade())
self.part_a.cmdset.add(CmdsetTrade())
self.trade_started = False
self.partA.ndb.tradehandler = self
self.part_a.ndb.tradehandler = self
# trade variables
self.partA_offers = []
self.partB_offers = []
self.partA_accepted = False
self.partB_accepted = False
self.part_a_offers = []
self.part_b_offers = []
self.part_a_accepted = False
self.part_b_accepted = False
def msg_other(self, sender, string):
"""
@ -172,59 +172,59 @@ class TradeHandler(object):
have to worry about which party they are in the handler.
Args:
sender (object): One of partA or B. The method will figure
sender (object): One of A or B. The method will figure
out the *other* party to send to.
string (str): Text to send.
"""
if self.partA == sender:
self.partB.msg(string)
elif self.partB == sender:
self.partA.msg(string)
if self.part_a == sender:
self.part_b.msg(string)
elif self.part_b == sender:
self.part_a.msg(string)
else:
# no match, relay to oneself
sender.msg(string) if sender else self.partA.msg(string)
sender.msg(string) if sender else self.part_a.msg(string)
def get_other(self, party):
"""
Returns the other party of the trade
Args:
partyX (object): One of the parties of the negotiation
party (object): One of the parties of the negotiation
Returns:
partyY (object): The other party, not partyX.
party_other (object): The other party, not the first party.
"""
if self.partA == party:
return self.partB
if self.partB == party:
return self.partA
if self.part_a == party:
return self.part_b
if self.part_b == party:
return self.part_a
return None
def join(self, partB):
def join(self, part_b):
"""
This is used once B decides to join the trade
Args:
partB (object): The party accepting the barter.
part_b (object): The party accepting the barter.
"""
if self.partB == partB:
self.partB.ndb.tradehandler = self
self.partB.cmdset.add(CmdsetTrade())
if self.part_b == part_b:
self.part_b.ndb.tradehandler = self
self.part_b.cmdset.add(CmdsetTrade())
self.trade_started = True
return True
return False
def unjoin(self, partB):
def unjoin(self, part_b):
"""
This is used if B decides not to join the trade.
Args:
partB (object): The party leaving the barter.
part_b (object): The party leaving the barter.
"""
if self.partB == partB:
if self.part_b == part_b:
self.finish(force=True)
return True
return False
@ -242,12 +242,12 @@ class TradeHandler(object):
"""
if self.trade_started:
# reset accept statements whenever an offer changes
self.partA_accepted = False
self.partB_accepted = False
if party == self.partA:
self.partA_offers = list(args)
elif party == self.partB:
self.partB_offers = list(args)
self.part_a_accepted = False
self.part_b_accepted = False
if party == self.part_a:
self.part_a_offers = list(args)
elif party == self.part_b:
self.part_b_offers = list(args)
else:
raise ValueError
@ -259,7 +259,7 @@ class TradeHandler(object):
offers (tuple): A tuple with two lists, (A_offers, B_offers).
"""
return self.partA_offers, self.partB_offers
return self.part_a_offers, self.part_b_offers
def search(self, offername):
"""
@ -273,7 +273,7 @@ class TradeHandler(object):
offer (object): An object on offer, based on the search criterion.
"""
all_offers = self.partA_offers + self.partB_offers
all_offers = self.part_a_offers + self.part_b_offers
if isinstance(offername, int):
# an index to return
if 0 <= offername < len(all_offers):
@ -307,10 +307,10 @@ class TradeHandler(object):
"""
if self.trade_started:
if party == self.partA:
self.partA_accepted = True
elif party == self.partB:
self.partB_accepted = True
if party == self.part_a:
self.part_a_accepted = True
elif party == self.part_b:
self.part_b_accepted = True
else:
raise ValueError
return self.finish() # try to close the deal
@ -334,14 +334,14 @@ class TradeHandler(object):
"""
if self.trade_started:
if party == self.partA:
if self.partA_accepted:
self.partA_accepted = False
if party == self.part_a:
if self.part_a_accepted:
self.part_a_accepted = False
return True
return False
elif party == self.partB:
if self.partB_accepted:
self.partB_accepted = False
elif party == self.part_b:
if self.part_b_accepted:
self.part_b_accepted = False
return True
return False
else:
@ -361,24 +361,24 @@ class TradeHandler(object):
"""
fin = False
if self.trade_started and self.partA_accepted and self.partB_accepted:
if self.trade_started and self.part_a_accepted and self.part_b_accepted:
# both accepted - move objects before cleanup
for obj in self.partA_offers:
obj.location = self.partB
for obj in self.partB_offers:
obj.location = self.partA
for obj in self.part_a_offers:
obj.location = self.part_b
for obj in self.part_b_offers:
obj.location = self.part_a
fin = True
if fin or force:
# cleanup
self.partA.cmdset.delete("cmdset_trade")
self.partB.cmdset.delete("cmdset_trade")
self.partA_offers = None
self.partB_offers = None
self.partA.scripts.stop("trade_request_timeout")
# this will kill it also from partB
del self.partA.ndb.tradehandler
if self.partB.ndb.tradehandler:
del self.partB.ndb.tradehandler
self.part_a.cmdset.delete("cmdset_trade")
self.part_b.cmdset.delete("cmdset_trade")
self.part_a_offers = None
self.part_b_offers = None
self.part_a.scripts.stop("trade_request_timeout")
# this will kill it also from B
del self.part_a.ndb.tradehandler
if self.part_b.ndb.tradehandler:
del self.part_b.ndb.tradehandler
return True
return False
@ -398,8 +398,8 @@ class CmdTradeBase(Command):
"""
self.args = self.args.strip()
self.tradehandler = self.caller.ndb.tradehandler
self.partA = self.tradehandler.partA
self.partB = self.tradehandler.partB
self.part_a = self.tradehandler.part_a
self.part_b = self.tradehandler.part_b
self.other = self.tradehandler.get_other(self.caller)
self.msg_other = self.tradehandler.msg_other
@ -412,7 +412,7 @@ class CmdTradeBase(Command):
self.args, self.emote = [part.strip() for part in self.args.rsplit(":", 1)]
self.str_caller = 'You say, "' + self.emote + '"\n [%s]'
if self.caller.has_player:
self.str_other = '{c%s{n says, "' % self.caller.key + self.emote + '"\n [%s]'
self.str_other = '|c%s|n says, "' % self.caller.key + self.emote + '"\n [%s]'
else:
self.str_other = '%s says, "' % self.caller.key + self.emote + '"\n [%s]'
@ -429,35 +429,34 @@ class CmdTradeHelp(CmdTradeBase):
Displays help for the trade commands.
"""
key = "trade help"
#aliases = ["trade help"]
locks = "cmd:all()"
help_category = "Trade"
def func(self):
"Show the help"
"""Show the help"""
string = """
Trading commands
{woffer <objects> [:emote]{n
|woffer <objects> [:emote]|n
offer one or more objects for trade. The emote can be used for
RP/arguments. A new offer will require both parties to re-accept
it again.
{waccept [:emote]{n
|waccept [:emote]|n
accept the currently standing offer from both sides. Also 'agree'
works. Once both have accepted, the deal is finished and goods
will change hands.
{wdecline [:emote]{n
|wdecline [:emote]|n
change your mind and remove a previous accept (until other
has also accepted)
{wstatus{n
|wstatus|n
show the current offers on each side of the deal. Also 'offers'
and 'deal' works.
{wevaluate <nr> or <offer>{n
|wevaluate <nr> or <offer>|n
examine any offer in the deal. List them with the 'status' command.
{wend trade{n
|wend trade|n
end the negotiations prematurely. No trade will take place.
You can also use {wemote{n, {wsay{n etc to discuss
You can also use |wemote|n, |wsay|n etc to discuss
without making a decision or offer.
"""
self.caller.msg(string)
@ -480,7 +479,7 @@ class CmdOffer(CmdTradeBase):
help_category = "Trading"
def func(self):
"implement the offer"
"""implement the offer"""
caller = self.caller
if not self.args:
@ -502,9 +501,9 @@ class CmdOffer(CmdTradeBase):
# output
if len(offerobjs) > 1:
objnames = ", ".join("{w%s{n" % obj.key for obj in offerobjs[:-1]) + " and {w%s{n" % offerobjs[-1].key
objnames = ", ".join("|w%s|n" % obj.key for obj in offerobjs[:-1]) + " and |w%s|n" % offerobjs[-1].key
else:
objnames = "{w%s{n" % offerobjs[0].key
objnames = "|w%s|n" % offerobjs[0].key
caller.msg(self.str_caller % ("You offer %s" % objnames))
self.msg_other(caller, self.str_other % ("They offer %s" % objnames))
@ -531,19 +530,20 @@ class CmdAccept(CmdTradeBase):
help_category = "Trading"
def func(self):
"accept the offer"
"""accept the offer"""
caller = self.caller
if not self.trade_started:
caller.msg("Wait until the other party has accepted to trade with you.")
return
if self.tradehandler.accept(self.caller):
# deal finished. Trade ended and cleaned.
caller.msg(self.str_caller % "You {gaccept{n the deal. {gDeal is made and goods changed hands.{n")
self.msg_other(caller, self.str_other % "%s {gaccepts{n the deal. {gDeal is made and goods changed hands.{n" % caller.key)
caller.msg(self.str_caller % "You |gaccept|n the deal. |gDeal is made and goods changed hands.|n")
self.msg_other(caller, self.str_other % "%s |gaccepts|n the deal."
" |gDeal is made and goods changed hands.|n" % caller.key)
else:
# a one-sided accept.
caller.msg(self.str_caller % "You {Gaccept{n the offer. %s must now also accept." % self.other.key)
self.msg_other(caller, self.str_other % "%s {Gaccepts{n the offer. You must now also accept." % caller.key)
caller.msg(self.str_caller % "You |Gaccept|n the offer. %s must now also accept." % self.other.key)
self.msg_other(caller, self.str_other % "%s |Gaccepts|n the offer. You must now also accept." % caller.key)
# decline
@ -565,22 +565,23 @@ class CmdDecline(CmdTradeBase):
help_category = "Trading"
def func(self):
"decline the offer"
"""decline the offer"""
caller = self.caller
if not self.trade_started:
caller.msg("Wait until the other party has accepted to trade with you.")
return
offerA, offerB = self.tradehandler.list()
if not offerA or not offerB:
caller.msg("Noone has offered anything (yet) so there is nothing to decline.")
offer_a, offer_b = self.tradehandler.list()
if not offer_a or not offer_b:
caller.msg("No offers have been made yet, so there is nothing to decline.")
return
if self.tradehandler.decline(self.caller):
# changed a previous accept
caller.msg(self.str_caller % "You change your mind, {Rdeclining{n the current offer.")
self.msg_other(caller, self.str_other % "%s changes their mind, {Rdeclining{n the current offer." % caller.key)
caller.msg(self.str_caller % "You change your mind, |Rdeclining|n the current offer.")
self.msg_other(caller, self.str_other
% "%s changes their mind, |Rdeclining|n the current offer." % caller.key)
else:
# no acceptance to change
caller.msg(self.str_caller % "You {Rdecline{n the current offer.")
# no accept_ance to change
caller.msg(self.str_caller % "You |Rdecline|n the current offer.")
self.msg_other(caller, self.str_other % "%s declines the current offer." % caller.key)
@ -607,7 +608,7 @@ class CmdEvaluate(CmdTradeBase):
help_category = "Trading"
def func(self):
"evaluate an object"
"""evaluate an object"""
caller = self.caller
if not self.args:
caller.msg("Usage: evaluate <offered object>")
@ -650,31 +651,30 @@ class CmdStatus(CmdTradeBase):
help_category = "Trading"
def func(self):
"Show the current deal"
"""Show the current deal"""
caller = self.caller
partA_offers, partB_offers = self.tradehandler.list()
part_a_offers, part_b_offers = self.tradehandler.list()
count = 1
partA_offerlist = ""
for offer in partA_offers:
partA_offerlist += "\n {w%i{n %s" % (count, offer.key)
part_a_offerlist = []
for offer in part_a_offers:
part_a_offerlist.append("\n |w%i|n %s" % (count, offer.key))
count += 1
if not partA_offerlist:
partA_offerlist = "\n <nothing>"
partB_offerlist = ""
for offer in partB_offers:
partB_offerlist += "\n {w%i{n %s" % (count, offer.key)
if not part_a_offerlist:
part_a_offerlist = "\n <nothing>"
part_b_offerlist = []
for offer in part_b_offers:
part_b_offerlist.append("\n |w%i|n %s" % (count, offer.key))
count += 1
if not partB_offerlist:
partB_offerlist = "\n <nothing>"
if not part_b_offerlist:
part_b_offerlist = "\n <nothing>"
string = "{gOffered by %s:{n%s\n{yOffered by %s:{n%s" % (self.partA.key,
partA_offerlist,
self.partB.key,
partB_offerlist)
acceptA = self.tradehandler.partA_accepted and "{gYes{n" or "{rNo{n"
acceptB = self.tradehandler.partB_accepted and "{gYes{n" or "{rNo{n"
string += "\n\n%s agreed: %s, %s agreed: %s" % \
(self.partA.key, acceptA, self.partB.key, acceptB)
string = "|gOffered by %s:|n%s\n|yOffered by %s:|n%s" % (self.part_a.key,
"".join(part_a_offerlist),
self.part_b.key,
"".join(part_b_offerlist))
accept_a = self.tradehandler.part_a_accepted and "|gYes|n" or "|rNo|n"
accept_b = self.tradehandler.part_b_accepted and "|gYes|n" or "|rNo|n"
string += "\n\n%s agreed: %s, %s agreed: %s" % (self.part_a.key, accept_a, self.part_b.key, accept_b)
string += "\n Use 'offer', 'eval' and 'accept'/'decline' to trade. See also 'trade help'."
caller.msg(string)
@ -698,11 +698,11 @@ class CmdFinish(CmdTradeBase):
help_category = "Trading"
def func(self):
"end trade"
"""end trade"""
caller = self.caller
self.tradehandler.finish(force=True)
caller.msg(self.str_caller % "You {raborted{n trade. No deal was made.")
self.msg_other(caller, self.str_other % "%s {raborted{n trade. No deal was made." % caller.key)
caller.msg(self.str_caller % "You |raborted|n trade. No deal was made.")
self.msg_other(caller, self.str_other % "%s |raborted|n trade. No deal was made." % caller.key)
# custom Trading cmdset
@ -715,7 +715,7 @@ class CmdsetTrade(CmdSet):
key = "cmdset_trade"
def at_cmdset_creation(self):
"Called when cmdset is created"
"""Called when cmdset is created"""
self.add(CmdTradeHelp())
self.add(CmdOffer())
self.add(CmdAccept())
@ -750,7 +750,7 @@ class CmdTrade(Command):
help_category = "General"
def func(self):
"Initiate trade"
"""Initiate trade"""
if not self.args:
if self.caller.ndb.tradehandler and self.caller.ndb.tradeevent.trade_started:
@ -767,36 +767,36 @@ class CmdTrade(Command):
self.args, emote = [part.strip() for part in self.args.rsplit(":", 1)]
selfemote = 'You say, "%s"\n ' % emote
if self.caller.has_player:
theiremote = '{c%s{n says, "%s"\n ' % (self.caller.key, emote)
theiremote = '|c%s|n says, "%s"\n ' % (self.caller.key, emote)
else:
theiremote = '%s says, "%s"\n ' % (self.caller.key, emote)
# for the sake of this command, the caller is always partA; this
# for the sake of this command, the caller is always part_a; this
# might not match the actual name in tradehandler (in the case of
# using this command to accept/decline a trade invitation).
partA = self.caller
part_a = self.caller
accept = 'accept' in self.args
decline = 'decline' in self.args
if accept:
partB = self.args.rstrip('accept').strip()
part_b = self.args.rstrip('accept').strip()
elif decline:
partB = self.args.rstrip('decline').strip()
part_b = self.args.rstrip('decline').strip()
else:
partB = self.args
partB = self.caller.search(partB)
if not partB:
part_b = self.args
part_b = self.caller.search(part_b)
if not part_b:
return
if partA == partB:
partA.msg("You play trader with yourself.")
if part_a == part_b:
part_a.msg("You play trader with yourself.")
return
# messages
str_initA = "You ask to trade with %s. They need to accept within %s secs."
str_initB = "%s wants to trade with you. Use {wtrade %s accept/decline [:emote]{n to answer (within %s secs)."
str_noinitA = "%s declines the trade"
str_noinitB = "You decline trade with %s."
str_startA = "%s starts to trade with you. See {wtrade help{n for aid."
str_startB = "You start to trade with %s. See {wtrade help{n for aid."
str_init_a = "You ask to trade with %s. They need to accept within %s secs."
str_init_b = "%s wants to trade with you. Use |wtrade %s accept/decline [:emote]|n to answer (within %s secs)."
str_noinit_a = "%s declines the trade"
str_noinit_b = "You decline trade with %s."
str_start_a = "%s starts to trade with you. See |wtrade help|n for aid."
str_start_b = "You start to trade with %s. See |wtrade help|n for aid."
if not (accept or decline):
# initialization of trade
@ -806,42 +806,41 @@ class CmdTrade(Command):
string = "You are already in trade with %s. You need to end trade first."
else:
string = "You are already trying to initiate trade with %s. You need to decline that trade first."
self.caller.msg(string % partB.key)
elif partB.ndb.tradehandler and partB.ndb.tradehandler.partB == partA:
# this is equivalent to partA accepting a trade from partB (so roles are reversed)
partB.ndb.tradehandler.join(partA)
partB.msg(theiremote + str_startA % partA.key)
partA.msg(selfemote + str_startB % (partB.key))
self.caller.msg(string % part_b.key)
elif part_b.ndb.tradehandler and part_b.ndb.tradehandler.part_b == part_a:
# this is equivalent to part_a accepting a trade from part_b (so roles are reversed)
part_b.ndb.tradehandler.join(part_a)
part_b.msg(theiremote + str_start_a % part_a.key)
part_a.msg(selfemote + str_start_b % part_b.key)
else:
# initiate a new trade
TradeHandler(partA, partB)
partA.msg(selfemote + str_initA % (partB.key, TRADE_TIMEOUT))
partB.msg(theiremote + str_initB % (partA.key, partA.key, TRADE_TIMEOUT))
partA.scripts.add(TradeTimeout)
TradeHandler(part_a, part_b)
part_a.msg(selfemote + str_init_a % (part_b.key, TRADE_TIMEOUT))
part_b.msg(theiremote + str_init_b % (part_a.key, part_a.key, TRADE_TIMEOUT))
part_a.scripts.add(TradeTimeout)
return
elif accept:
# accept a trade proposal from partB (so roles are reversed)
if partA.ndb.tradehandler:
# accept a trade proposal from part_b (so roles are reversed)
if part_a.ndb.tradehandler:
# already in a trade
partA.msg("You are already in trade with %s. You need to end that first." % partB.key)
part_a.msg("You are already in trade with %s. You need to end that first." % part_b.key)
return
if partB.ndb.tradehandler.join(partA):
partB.msg(theiremote + str_startA % partA.key)
partA.msg(selfemote + str_startB % partB.key)
if part_b.ndb.tradehandler.join(part_a):
part_b.msg(theiremote + str_start_a % part_a.key)
part_a.msg(selfemote + str_start_b % part_b.key)
else:
partA.msg("No trade proposal to accept.")
part_a.msg("No trade proposal to accept.")
return
else:
# decline trade proposal from partB (so roles are reversed)
if partA.ndb.tradehandler and partA.ndb.tradehandler.partB == partA:
# decline trade proposal from part_b (so roles are reversed)
if part_a.ndb.tradehandler and part_a.ndb.tradehandler.part_b == part_a:
# stopping an invite
partA.ndb.tradehandler.finish(force=True)
partB.msg(theiremote + "%s aborted trade attempt with you." % partA)
partA.msg(selfemote + "You aborted the trade attempt with %s." % partB)
elif partB.ndb.tradehandler and partB.ndb.tradehandler.unjoin(partA):
partB.msg(theiremote + str_noinitA % partA.key)
partA.msg(selfemote + str_noinitB % partB.key)
part_a.ndb.tradehandler.finish(force=True)
part_b.msg(theiremote + "%s aborted trade attempt with you." % part_a)
part_a.msg(selfemote + "You aborted the trade attempt with %s." % part_b)
elif part_b.ndb.tradehandler and part_b.ndb.tradehandler.unjoin(part_a):
part_b.msg(theiremote + str_noinit_a % part_a.key)
part_a.msg(selfemote + str_noinit_b % part_b.key)
else:
partA.msg("No trade proposal to decline.")
part_a.msg("No trade proposal to decline.")
return

View file

@ -37,6 +37,7 @@ from evennia import default_cmds, managers
CHARACTER_TYPECLASS = settings.BASE_CHARACTER_TYPECLASS
class CmdOOCLook(default_cmds.CmdLook):
"""
ooc look
@ -96,7 +97,6 @@ class CmdOOCLook(default_cmds.CmdLook):
return
# not inspecting a character. Show the OOC info.
charobjs = []
charnames = []
if self.caller.db._character_dbrefs:
dbrefs = self.caller.db._character_dbrefs
@ -104,18 +104,18 @@ class CmdOOCLook(default_cmds.CmdLook):
charnames = [charobj.key for charobj in charobjs if charobj]
if charnames:
charlist = "The following Character(s) are available:\n\n"
charlist += "\n\r".join(["{w %s{n" % charname for charname in charnames])
charlist += "\n\n Use {w@ic <character name>{n to switch to that Character."
charlist += "\n\r".join(["|w %s|n" % charname for charname in charnames])
charlist += "\n\n Use |w@ic <character name>|n to switch to that Character."
else:
charlist = "You have no Characters."
string = \
""" You, %s, are an {wOOC ghost{n without form. The world is hidden
""" You, %s, are an |wOOC ghost|n without form. The world is hidden
from you and besides chatting on channels your options are limited.
You need to have a Character in order to interact with the world.
%s
Use {wcreate <name>{n to create a new character and {whelp{n for a
Use |wcreate <name>|n to create a new character and |whelp|n for a
list of available commands.""" % (self.caller.key, charlist)
self.caller.msg(string)
@ -160,13 +160,13 @@ class CmdOOCCharacterCreate(Command):
charname = self.args.strip()
old_char = managers.objects.get_objs_with_key_and_typeclass(charname, CHARACTER_TYPECLASS)
if old_char:
self.caller.msg("Character {c%s{n already exists." % charname)
self.caller.msg("Character |c%s|n already exists." % charname)
return
# create the character
new_character = create_object(CHARACTER_TYPECLASS, key=charname)
if not new_character:
self.caller.msg("{rThe Character couldn't be created. This is a bug. Please contact an admin.")
self.caller.msg("|rThe Character couldn't be created. This is a bug. Please contact an admin.")
return
# make sure to lock the character to only be puppeted by this player
new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Developer) or pperm(Developer)" %
@ -179,7 +179,7 @@ class CmdOOCCharacterCreate(Command):
else:
avail_chars = [new_character.id]
self.caller.db._character_dbrefs = avail_chars
self.caller.msg("{gThe Character {c%s{g was successfully created!" % charname)
self.caller.msg("|gThe Character |c%s|g was successfully created!" % charname)
class OOCCmdSetCharGen(default_cmds.PlayerCmdSet):
@ -187,7 +187,6 @@ class OOCCmdSetCharGen(default_cmds.PlayerCmdSet):
Extends the default OOC cmdset.
"""
def at_cmdset_creation(self):
"Install everything from the default set, then overload"
#super(OOCCmdSetCharGen, self).at_cmdset_creation()
"""Install everything from the default set, then overload"""
self.add(CmdOOCLook())
self.add(CmdOOCCharacterCreate())

View file

@ -97,7 +97,7 @@ def roll_dice(dicenum, dicetype, modifier=None, conditional=None, return_tuple=F
if modifier:
# make sure to check types well before eval
mod, modvalue = modifier
if not mod in ('+', '-', '*', '/'):
if mod not in ('+', '-', '*', '/'):
raise TypeError("Non-supported dice modifier: %s" % mod)
modvalue = int(modvalue) # for safety
result = eval("%s %s %s" % (result, mod, modvalue))
@ -105,13 +105,13 @@ def roll_dice(dicenum, dicetype, modifier=None, conditional=None, return_tuple=F
if conditional:
# make sure to check types well before eval
cond, condvalue = conditional
if not cond in ('>', '<', '>=', '<=', '!=', '=='):
if cond not in ('>', '<', '>=', '<=', '!=', '=='):
raise TypeError("Non-supported dice result conditional: %s" % conditional)
condvalue = int(condvalue) # for safety
outcome = eval("%s %s %s" % (result, cond, condvalue)) # True/False
diff = abs(result - condvalue)
if return_tuple:
return (result, outcome, diff, rolls)
return result, outcome, diff, rolls
else:
if conditional:
return outcome
@ -155,7 +155,7 @@ class CmdDice(default_cmds.MuxCommand):
locks = "cmd:all()"
def func(self):
"Mostly parsing for calling the dice roller function"
"""Mostly parsing for calling the dice roller function"""
if not self.args:
self.caller.msg("Usage: @dice <nr>d<sides> [modifier] [conditional]")
@ -163,35 +163,33 @@ class CmdDice(default_cmds.MuxCommand):
argstring = "".join(str(arg) for arg in self.args)
parts = [part for part in RE_PARTS.split(self.args) if part]
lparts = len(parts)
ndice = 0
nsides = 0
len_parts = len(parts)
modifier = None
conditional = None
if lparts < 3 or parts[1] != 'd':
self.caller.msg("You must specify the die roll(s) as <nr>d<sides>. For example, 2d6 means rolling a 6-sided die 2 times.")
if len_parts < 3 or parts[1] != 'd':
self.caller.msg("You must specify the die roll(s) as <nr>d<sides>."
" For example, 2d6 means rolling a 6-sided die 2 times.")
return
# Limit the number of dice and sides a character can roll to prevent server slow down and crashes
ndicelimit = 10000 # Maximum number of dice
nsidelimit = 10000 # Maximum number of sides
ndicelimit = 10000 # Maximum number of dice
nsidelimit = 10000 # Maximum number of sides
if int(parts[0]) > ndicelimit or int(parts[2]) > nsidelimit:
self.caller.msg("The maximum roll allowed is %sd%s." % (ndicelimit, nsidelimit))
return
ndice, nsides = parts[0], parts[2]
if lparts == 3:
if len_parts == 3:
# just something like 1d6
pass
elif lparts == 5:
elif len_parts == 5:
# either e.g. 1d6 + 3 or something like 1d6 > 3
if parts[3] in ('+', '-', '*', '/'):
modifier = (parts[3], parts[4])
else: # assume it is a conditional
conditional = (parts[3], parts[4])
elif lparts == 7:
elif len_parts == 7:
# the whole sequence, e.g. 1d6 + 3 > 5
modifier = (parts[3], parts[4])
conditional = (parts[5], parts[6])
@ -207,7 +205,8 @@ class CmdDice(default_cmds.MuxCommand):
conditional=conditional,
return_tuple=True)
except ValueError:
self.caller.msg("You need to enter valid integer numbers, modifiers and operators. {w%s{n was not understood." % self.args)
self.caller.msg("You need to enter valid integer numbers, modifiers and operators."
" |w%s|n was not understood." % self.args)
return
# format output
if len(rolls) > 1:
@ -217,12 +216,12 @@ class CmdDice(default_cmds.MuxCommand):
if outcome is None:
outcomestring = ""
elif outcome:
outcomestring = " This is a {gsuccess{n (by %s)." % diff
outcomestring = " This is a |gsuccess|n (by %s)." % diff
else:
outcomestring = " This is a {rfailure{n (by %s)." % diff
outcomestring = " This is a |rfailure|n (by %s)." % diff
yourollstring = "You roll %s%s."
roomrollstring = "%s rolls %s%s."
resultstring = " Roll(s): %s. Total result is {w%s{n."
resultstring = " Roll(s): %s. Total result is |w%s|n."
if 'secret' in self.switches:
# don't echo to the room at all
@ -250,11 +249,12 @@ class CmdDice(default_cmds.MuxCommand):
string += outcomestring
self.caller.location.msg_contents(string)
class DiceCmdSet(CmdSet):
"""
a small cmdset for testing purposes.
Add with @py self.cmdset.add("contrib.dice.DiceCmdSet")
"""
def at_cmdset_creation(self):
"Called when set is created"
"""Called when set is created"""
self.add(CmdDice())

View file

@ -54,7 +54,8 @@ except Exception:
# malformed connection screen or no screen given
pass
if not CONNECTION_SCREEN:
CONNECTION_SCREEN = "\nEvennia: Error in CONNECTION_SCREEN MODULE (randomly picked connection screen variable is not a string). \nEnter 'help' for aid."
CONNECTION_SCREEN = "\nEvennia: Error in CONNECTION_SCREEN MODULE" \
" (randomly picked connection screen variable is not a string). \nEnter 'help' for aid."
class CmdUnconnectedConnect(MuxCommand):
@ -108,8 +109,8 @@ class CmdUnconnectedConnect(MuxCommand):
or
any(tup[2].match(session.address[0]) for tup in bans if tup[2])):
# this is a banned IP or name!
string = "{rYou have been banned and cannot continue from here."
string += "\nIf you feel this ban is in error, please email an admin.{x"
string = "|rYou have been banned and cannot continue from here."
string += "\nIf you feel this ban is in error, please email an admin.|x"
session.msg(string)
session.execute_cmd("quit")
return
@ -117,6 +118,7 @@ class CmdUnconnectedConnect(MuxCommand):
# actually do the login. This will call all hooks.
session.sessionhandler.login(session, player)
class CmdUnconnectedCreate(MuxCommand):
"""
Create a new account.
@ -156,7 +158,7 @@ class CmdUnconnectedCreate(MuxCommand):
self.playerinfo = (playername, email, password)
def func(self):
"Do checks and create account"
"""Do checks and create account"""
session = self.caller
@ -167,11 +169,11 @@ class CmdUnconnectedCreate(MuxCommand):
session.msg(string)
return
if not re.findall('^[\w. @+-]+$', playername) or not (0 < len(playername) <= 30):
session.msg("\n\r Playername can be max 30 characters, or less. Letters, spaces, dig\
its and @/./+/-/_ only.") # this echoes the restrictions made by django's auth module.
session.msg("\n\r Playername can be max 30 characters, or less. Letters, spaces,"
" digits and @/./+/-/_ only.") # this echoes the restrictions made by django's auth module.
return
if not email or not password:
session.msg("\n\r You have to supply an e-mail address followed by a password." )
session.msg("\n\r You have to supply an e-mail address followed by a password.")
return
if not utils.validate_email_address(email):
@ -205,11 +207,11 @@ its and @/./+/-/_ only.") # this echoes the restrictions made by django's auth m
permissions = settings.PERMISSION_PLAYER_DEFAULT
try:
new_player = create.create_player(playername, email, password,
permissions=permissions)
new_player = create.create_player(playername, email, password, permissions=permissions)
except Exception as e:
session.msg("There was an error creating the default Player/Character:\n%s\n If this problem persists, contact an admin." % e)
session.msg("There was an error creating the default Player/Character:\n%s\n"
" If this problem persists, contact an admin." % e)
logger.log_trace()
return
@ -230,8 +232,8 @@ its and @/./+/-/_ only.") # this echoes the restrictions made by django's auth m
# if we only allow one character, create one with the same name as Player
# (in mode 2, the character must be created manually once logging in)
new_character = create.create_object(typeclass, key=playername,
location=default_home, home=default_home,
permissions=permissions)
location=default_home, home=default_home,
permissions=permissions)
# set playable character list
new_player.db._playable_characters.append(new_character)
@ -260,6 +262,7 @@ its and @/./+/-/_ only.") # this echoes the restrictions made by django's auth m
session.msg("An error occurred. Please e-mail an admin if the problem persists.")
logger.log_trace()
class CmdUnconnectedQuit(MuxCommand):
"""
We maintain a different version of the `quit` command
@ -271,7 +274,7 @@ class CmdUnconnectedQuit(MuxCommand):
locks = "cmd:all()"
def func(self):
"Simply close the connection."
"""Simply close the connection."""
session = self.caller
session.msg("Good bye! Disconnecting ...")
session.session_disconnect()
@ -289,7 +292,7 @@ class CmdUnconnectedLook(MuxCommand):
locks = "cmd:all()"
def func(self):
"Show the connect screen."
"""Show the connect screen."""
self.caller.msg(CONNECTION_SCREEN)
@ -303,34 +306,34 @@ class CmdUnconnectedHelp(MuxCommand):
locks = "cmd:all()"
def func(self):
"Shows help"
"""Shows help"""
string = \
"""
You are not yet logged into the game. Commands available at this point:
{wcreate, connect, look, help, quit{n
|wcreate, connect, look, help, quit|n
To login to the system, you need to do one of the following:
{w1){n If you have no previous account, you need to use the 'create'
|w1)|n If you have no previous account, you need to use the 'create'
command like this:
{wcreate "Anna the Barbarian" anna@myemail.com c67jHL8p{n
|wcreate "Anna the Barbarian" anna@myemail.com c67jHL8p|n
It's always a good idea (not only here, but everywhere on the net)
to not use a regular word for your password. Make it longer than
3 characters (ideally 6 or more) and mix numbers and capitalization
into it.
{w2){n If you have an account already, either because you just created
one in {w1){n above or you are returning, use the 'connect' command:
|w2)|n If you have an account already, either because you just created
one in |w1)|n above or you are returning, use the 'connect' command:
{wconnect anna@myemail.com c67jHL8p{n
|wconnect anna@myemail.com c67jHL8p|n
This should log you in. Run {whelp{n again once you're logged in
This should log you in. Run |whelp|n again once you're logged in
to get more aid. Hope you enjoy your stay!
You can use the {wlook{n command if you want to see the connect screen again.
You can use the |wlook|n command if you want to see the connect screen again.
"""
self.caller.msg(string)
@ -345,7 +348,7 @@ class UnloggedinCmdSet(CmdSet):
priority = 0
def at_cmdset_creation(self):
"Populate the cmdset"
"""Populate the cmdset"""
self.add(CmdUnconnectedConnect())
self.add(CmdUnconnectedCreate())
self.add(CmdUnconnectedQuit())

View file

@ -108,7 +108,7 @@ class ExtendedRoom(DefaultRoom):
look command.
"""
def at_object_creation(self):
"Called when room is first created only."
"""Called when room is first created only."""
self.db.spring_desc = ""
self.db.summer_desc = ""
self.db.autumn_desc = ""
@ -367,12 +367,12 @@ class CmdExtendedDesc(default_cmds.CmdDesc):
aliases = ["@describe", "@detail"]
def reset_times(self, obj):
"By deleteting the caches we force a re-load."
"""By deleteting the caches we force a re-load."""
obj.ndb.last_season = None
obj.ndb.last_timeslot = None
def func(self):
"Define extended command"
"""Define extended command"""
caller = self.caller
location = caller.location
if self.cmdname == 'detail':
@ -393,13 +393,14 @@ class CmdExtendedDesc(default_cmds.CmdDesc):
if not self.args:
# No args given. Return all details on location
string = "|wDetails on %s|n:" % location
details = "\n".join(" |w%s|n: %s" % (key, utils.crop(text)) for key, text in location.db.details.items())
details = "\n".join(" |w%s|n: %s"
% (key, utils.crop(text)) for key, text in location.db.details.items())
caller.msg("%s\n%s" % (string, details) if details else "%s None." % string)
return
if not self.rhs:
# no '=' used - list content of given detail
if self.args in location.db.details:
string = "{wDetail '%s' on %s:\n{n" % (self.args, location)
string = "|wDetail '%s' on %s:\n|n" % (self.args, location)
string += str(location.db.details[self.args])
caller.msg(string)
else:
@ -414,18 +415,15 @@ class CmdExtendedDesc(default_cmds.CmdDesc):
# we are doing a @desc call
if not self.args:
if location:
string = "{wDescriptions on %s{n:\n" % location.key
string += " {wspring:{n %s\n" % location.db.spring_desc
string += " {wsummer:{n %s\n" % location.db.summer_desc
string += " {wautumn:{n %s\n" % location.db.autumn_desc
string += " {wwinter:{n %s\n" % location.db.winter_desc
string += " {wgeneral:{n %s" % location.db.general_desc
string = "|wDescriptions on %s|n:\n" % location.key
string += " |wspring:|n %s\n" % location.db.spring_desc
string += " |wsummer:|n %s\n" % location.db.summer_desc
string += " |wautumn:|n %s\n" % location.db.autumn_desc
string += " |wwinter:|n %s\n" % location.db.winter_desc
string += " |wgeneral:|n %s" % location.db.general_desc
caller.msg(string)
return
if self.switches and self.switches[0] in ("spring",
"summer",
"autumn",
"winter"):
if self.switches and self.switches[0] in ("spring", "summer", "autumn", "winter"):
# a seasonal switch was given
if self.rhs:
caller.msg("Seasonal descs only works with rooms, not objects.")
@ -455,7 +453,7 @@ class CmdExtendedDesc(default_cmds.CmdDesc):
else:
text = self.args
obj = location
obj.db.desc = text # a compatibility fallback
obj.db.desc = text # a compatibility fallback
if obj.attributes.has("general_desc"):
obj.db.general_desc = text
self.reset_times(obj)
@ -481,7 +479,7 @@ class CmdGameTime(default_cmds.MuxCommand):
help_category = "General"
def func(self):
"Reads time info from current room"
"""Reads time info from current room"""
location = self.caller.location
if not location or not hasattr(location, "get_time_and_season"):
self.caller.msg("No location available - you are outside time.")

View file

@ -12,13 +12,14 @@ from mock import Mock
from evennia.contrib import rplanguage
mtrans = {"testing":"1", "is": "2", "a": "3", "human": "4"}
mtrans = {"testing": "1", "is": "2", "a": "3", "human": "4"}
atrans = ["An", "automated", "advantageous", "repeatable", "faster"]
text = "Automated testing is advantageous for a number of reasons:" \
"tests may be executed Continuously without the need for human " \
"intervention, They are easily repeatable, and often faster."
class TestLanguage(EvenniaTest):
def setUp(self):
super(TestLanguage, self).setUp()
@ -29,6 +30,7 @@ class TestLanguage(EvenniaTest):
manual_translations=mtrans,
auto_translations=atrans,
force=True)
def tearDown(self):
super(TestLanguage, self).tearDown()
rplanguage._LANGUAGE_HANDLER.delete()
@ -70,6 +72,7 @@ recog02 = "Mr Receiver2"
recog10 = "Mr Sender"
emote = "With a flair, /me looks at /first and /colliding sdesc-guy. She says \"This is a test.\""
class TestRPSystem(EvenniaTest):
def setUp(self):
super(TestRPSystem, self).setUp()
@ -79,12 +82,13 @@ class TestRPSystem(EvenniaTest):
self.receiver2 = create_object(rpsystem.ContribRPCharacter, key="Receiver2", location=self.room)
def test_ordered_permutation_regex(self):
self.assertEqual(rpsystem.ordered_permutation_regex(sdesc0),
'/[0-9]*-*A\\ nice\\ sender\\ of\\ emotes(?=\\W|$)+|/[0-9]*-*nice\\ sender\\ ' \
'of\\ emotes(?=\\W|$)+|/[0-9]*-*A\\ nice\\ sender\\ of(?=\\W|$)+|/[0-9]*-*sender\\ ' \
'of\\ emotes(?=\\W|$)+|/[0-9]*-*nice\\ sender\\ of(?=\\W|$)+|/[0-9]*-*A\\ nice\\ ' \
'sender(?=\\W|$)+|/[0-9]*-*nice\\ sender(?=\\W|$)+|/[0-9]*-*of\\ emotes(?=\\W|$)+' \
'|/[0-9]*-*sender\\ of(?=\\W|$)+|/[0-9]*-*A\\ nice(?=\\W|$)+|/[0-9]*-*sender(?=\\W|$)+' \
self.assertEqual(
rpsystem.ordered_permutation_regex(sdesc0),
'/[0-9]*-*A\\ nice\\ sender\\ of\\ emotes(?=\\W|$)+|/[0-9]*-*nice\\ sender\\ '
'of\\ emotes(?=\\W|$)+|/[0-9]*-*A\\ nice\\ sender\\ of(?=\\W|$)+|/[0-9]*-*sender\\ '
'of\\ emotes(?=\\W|$)+|/[0-9]*-*nice\\ sender\\ of(?=\\W|$)+|/[0-9]*-*A\\ nice\\ '
'sender(?=\\W|$)+|/[0-9]*-*nice\\ sender(?=\\W|$)+|/[0-9]*-*of\\ emotes(?=\\W|$)+'
'|/[0-9]*-*sender\\ of(?=\\W|$)+|/[0-9]*-*A\\ nice(?=\\W|$)+|/[0-9]*-*sender(?=\\W|$)+'
'|/[0-9]*-*emotes(?=\\W|$)+|/[0-9]*-*nice(?=\\W|$)+|/[0-9]*-*of(?=\\W|$)+|/[0-9]*-*A(?=\\W|$)+')
def test_sdesc_handler(self):
@ -93,10 +97,11 @@ class TestRPSystem(EvenniaTest):
self.speaker.sdesc.add("This is {#324} ignored")
self.assertEqual(self.speaker.sdesc.get(), "This is 324 ignored")
self.speaker.sdesc.add("Testing three words")
self.assertEqual(self.speaker.sdesc.get_regex_tuple()[0].pattern,
'/[0-9]*-*Testing\\ three\\ words(?=\\W|$)+|/[0-9]*-*Testing\\ ' \
'three(?=\\W|$)+|/[0-9]*-*three\\ words(?=\\W|$)+|/[0-9]*-*Testing'\
'(?=\\W|$)+|/[0-9]*-*three(?=\\W|$)+|/[0-9]*-*words(?=\\W|$)+')
self.assertEqual(
self.speaker.sdesc.get_regex_tuple()[0].pattern,
'/[0-9]*-*Testing\\ three\\ words(?=\\W|$)+|/[0-9]*-*Testing\\ '
'three(?=\\W|$)+|/[0-9]*-*three\\ words(?=\\W|$)+|/[0-9]*-*Testing'
'(?=\\W|$)+|/[0-9]*-*three(?=\\W|$)+|/[0-9]*-*words(?=\\W|$)+')
def test_recog_handler(self):
self.speaker.sdesc.add(sdesc0)
@ -105,15 +110,17 @@ class TestRPSystem(EvenniaTest):
self.speaker.recog.add(self.receiver2, recog02)
self.assertEqual(self.speaker.recog.get(self.receiver1), recog01)
self.assertEqual(self.speaker.recog.get(self.receiver2), recog02)
self.assertEqual(self.speaker.recog.get_regex_tuple(self.receiver1)[0].pattern,
'/[0-9]*-*Mr\\ Receiver(?=\\W|$)+|/[0-9]*-*Receiver(?=\\W|$)+|/[0-9]*-*Mr(?=\\W|$)+')
self.assertEqual(
self.speaker.recog.get_regex_tuple(self.receiver1)[0].pattern,
'/[0-9]*-*Mr\\ Receiver(?=\\W|$)+|/[0-9]*-*Receiver(?=\\W|$)+|/[0-9]*-*Mr(?=\\W|$)+')
self.speaker.recog.remove(self.receiver1)
self.assertEqual(self.speaker.recog.get(self.receiver1), sdesc1)
def test_parse_language(self):
self.assertEqual(rpsystem.parse_language(self.speaker, emote),
('With a flair, /me looks at /first and /colliding sdesc-guy. She says {##0}',
{'##0': (None, '"This is a test."')}) )
self.assertEqual(
rpsystem.parse_language(self.speaker, emote),
('With a flair, /me looks at /first and /colliding sdesc-guy. She says {##0}',
{'##0': (None, '"This is a test."')}))
def parse_sdescs_and_recogs(self):
speaker = self.speaker
@ -122,8 +129,8 @@ class TestRPSystem(EvenniaTest):
self.receiver2.sdesc.add(sdesc2)
candidates = (self.receiver1, self.receiver2)
result = ('With a flair, {#9} looks at {#10} and {#11}. She says "This is a test."',
{'#11': 'Another nice colliding sdesc-guy for tests', '#10':
'The first receiver of emotes.', '#9': 'A nice sender of emotes'})
{'#11': 'Another nice colliding sdesc-guy for tests', '#10':
'The first receiver of emotes.', '#9': 'A nice sender of emotes'})
self.assertEqual(rpsystem.parse_sdescs_and_recogs(speaker, candidates, emote), result)
self.speaker.recog.add(self.receiver1, recog01)
self.assertEqual(rpsystem.parse_sdescs_and_recogs(speaker, candidates, emote), result)
@ -140,12 +147,15 @@ class TestRPSystem(EvenniaTest):
receiver1.msg = lambda text, **kwargs: setattr(self, "out1", text)
receiver2.msg = lambda text, **kwargs: setattr(self, "out2", text)
rpsystem.send_emote(speaker, receivers, emote)
self.assertEqual(self.out0, 'With a flair, |bSender|n looks at |bThe first receiver of emotes.|n ' \
'and |bAnother nice colliding sdesc-guy for tests|n. She says |w"This is a test."|n')
self.assertEqual(self.out1, 'With a flair, |bA nice sender of emotes|n looks at |bReceiver1|n and ' \
'|bAnother nice colliding sdesc-guy for tests|n. She says |w"This is a test."|n')
self.assertEqual(self.out2, 'With a flair, |bA nice sender of emotes|n looks at |bThe first ' \
'receiver of emotes.|n and |bReceiver2|n. She says |w"This is a test."|n')
self.assertEqual(
self.out0, 'With a flair, |bSender|n looks at |bThe first receiver of emotes.|n '
'and |bAnother nice colliding sdesc-guy for tests|n. She says |w"This is a test."|n')
self.assertEqual(
self.out1, 'With a flair, |bA nice sender of emotes|n looks at |bReceiver1|n and '
'|bAnother nice colliding sdesc-guy for tests|n. She says |w"This is a test."|n')
self.assertEqual(
self.out2, 'With a flair, |bA nice sender of emotes|n looks at |bThe first '
'receiver of emotes.|n and |bReceiver2|n. She says |w"This is a test."|n')
def test_rpsearch(self):
self.speaker.sdesc.add(sdesc0)
@ -195,7 +205,7 @@ class TestExtendedRoom(CommandTest):
self.assertEqual(self.DETAIL_DESC, self.room1.return_detail("testdetail"))
def test_cmdextendedlook(self):
self.call(extended_room.CmdExtendedLook(), "here","Room(#1)\n%s" % self.SUMMER_DESC)
self.call(extended_room.CmdExtendedLook(), "here", "Room(#1)\n%s" % self.SUMMER_DESC)
self.call(extended_room.CmdExtendedLook(), "testdetail", self.DETAIL_DESC)
self.call(extended_room.CmdExtendedLook(), "nonexistent", "Could not find 'nonexistent'.")
@ -214,7 +224,6 @@ class TestExtendedRoom(CommandTest):
# Test the contrib barter system
from evennia import create_object
from evennia.contrib import barter
class TestBarter(CommandTest):
@ -230,8 +239,8 @@ class TestBarter(CommandTest):
self.char2.msg = Mock()
# test all methods of the tradehandler
handler = barter.TradeHandler(self.char1, self.char2)
self.assertEqual(handler.partA, self.char1)
self.assertEqual(handler.partB, self.char2)
self.assertEqual(handler.part_a, self.char1)
self.assertEqual(handler.part_b, self.char2)
handler.msg_other(self.char1, "Want to trade?")
handler.msg_other(self.char2, "Yes!")
handler.msg_other(None, "Talking to myself...")
@ -253,19 +262,19 @@ class TestBarter(CommandTest):
handler = barter.TradeHandler(self.char1, self.char2)
handler.join(self.char2)
handler.offer(self.char1, self.tradeitem1, self.tradeitem2)
self.assertEqual(handler.partA_offers, [self.tradeitem1, self.tradeitem2])
self.assertFalse(handler.partA_accepted)
self.assertFalse(handler.partB_accepted)
self.assertEqual(handler.part_a_offers, [self.tradeitem1, self.tradeitem2])
self.assertFalse(handler.part_a_accepted)
self.assertFalse(handler.part_b_accepted)
handler.offer(self.char2, self.tradeitem3)
self.assertEqual(handler.list(), ([self.tradeitem1, self.tradeitem2], [self.tradeitem3]))
self.assertEqual(handler.search("TradeItem2"), self.tradeitem2)
self.assertEqual(handler.search("TradeItem3"), self.tradeitem3)
self.assertEqual(handler.search("nonexisting"), None)
self.assertFalse(handler.finish()) # should fail since offer not yet accepted
self.assertFalse(handler.finish()) # should fail since offer not yet accepted
handler.accept(self.char1)
handler.decline(self.char1)
handler.accept(self.char2)
handler.accept(self.char1) # should trigger handler.finish() automatically
handler.accept(self.char1) # should trigger handler.finish() automatically
self.assertEqual(self.tradeitem1.location, self.char2)
self.assertEqual(self.tradeitem2.location, self.char2)
self.assertEqual(self.tradeitem3.location, self.char1)
@ -279,7 +288,7 @@ class TestBarter(CommandTest):
self.call(barter.CmdOffer(), "TradeItem1 : Here's my offer.", "You say, \"Here's my offer.\"\n [You offer TradeItem1]")
self.call(barter.CmdAccept(), "", "Your trade action: You accept the offer. Char2 must now also accept")
self.call(barter.CmdDecline(), "", "Your trade action: You change your mind, declining the current offer.")
self.call(barter.CmdAccept(),": Sounds good.", "You say, \"Sounds good.\"\n"
self.call(barter.CmdAccept(), ": Sounds good.", "You say, \"Sounds good.\"\n"
" [You accept the offer. Char must now also accept.", caller=self.char2)
self.call(barter.CmdDecline(), ":No way!", "You say, \"No way!\"\n [You change your mind, declining the current offer.]", caller=self.char2)
self.call(barter.CmdOffer(), "TradeItem1, TradeItem2 : My final offer!", "You say, \"My final offer!\"\n [You offer TradeItem1 and TradeItem2]")
@ -357,8 +366,8 @@ class TestWilderness(EvenniaTest):
self.assertEquals(len(exits), 3)
exitsok = ["north", "northeast", "east"]
for exit in exitsok:
self.assertTrue(any([e for e in exits if e.key == exit]))
for each_exit in exitsok:
self.assertTrue(any([e for e in exits if e.key == each_exit]))
# If we move to another location not on an edge, then all directions
# should be visible / traversable
@ -370,8 +379,8 @@ class TestWilderness(EvenniaTest):
self.assertEquals(len(exits), 8)
exitsok = ["north", "northeast", "east", "southeast", "south",
"southwest", "west", "northwest"]
for exit in exitsok:
self.assertTrue(any([e for e in exits if e.key == exit]))
for each_exit in exitsok:
self.assertTrue(any([e for e in exits if e.key == each_exit]))
def test_room_creation(self):
# Pretend that both char1 and char2 are connected...
@ -414,6 +423,6 @@ class TestWilderness(EvenniaTest):
"southwest": (0, 0),
"west": (0, 1),
"northwest": (0, 2)}
for direction, correct_loc in directions.iteritems():
for direction, correct_loc in directions.iteritems(): # Not compatible with Python 3
new_loc = wilderness.get_new_coordinates(loc, direction)
self.assertEquals(new_loc, correct_loc, direction)

View file

@ -94,7 +94,7 @@
# describe the tutorial exit
#
@desc tutorial =
This starts the {gEvennia tutorial{n, using a small solo game to show off
This starts the |gEvennia tutorial|n, using a small solo game to show off
some of the server's possibilities.
#
# now we actually go to the tutorial
@ -104,13 +104,13 @@ tutorial
# ... and describe it.
#
@desc
{gWelcome to the Evennia tutorial!{n
|gWelcome to the Evennia tutorial!|n
The following tutorial consists of a small single-player quest
area. The various rooms are designed to show off some of the power
and possibilities of the Evennia mud creation system. At any time
during this tutorial you can use the {wtutorial{n (or {wtut{n)
during this tutorial you can use the |wtutorial|n (or |wtut|n)
command to get some background info about the room or certain objects
to see what is going on "behind the scenes".
@ -127,8 +127,8 @@ tutorial
along a high, rocky coast ...
{g(write 'start' or 'begin' to start the tutorial. Try 'tutorial'
to get behind-the-scenes help anywhere.){n
|g(write 'start' or 'begin' to start the tutorial. Try 'tutorial'
to get behind-the-scenes help anywhere.)|n
#
# Show that the tutorial command works ...
#
@ -203,12 +203,12 @@ start
used for all tutorial rooms can display.
#
@desc
You stand on the high coast line overlooking a stormy {wsea{n far
You stand on the high coast line overlooking a stormy |wsea|n far
below. Around you the ground is covered in low gray-green grass,
pushed flat by wind and rain. Inland, the vast dark moors begin, only
here and there covered in patches of low trees and brushes.
To the east, you glimpse the ragged outline of a castle {wruin{n. It sits
To the east, you glimpse the ragged outline of a castle |wruin|n. It sits
perched on a sheer cliff out into the water, isolated from the
shore. The only way to reach it seems by way of an old hanging bridge,
anchored not far east from here.
@ -327,9 +327,9 @@ start
The branches are wet and slippery but can easily carry your
weight. From this high vantage point you can see far and wide.
... In fact, you notice {Ya faint yellowish light{n not far to the north,
... In fact, you notice |Ya faint yellowish light|n not far to the north,
beyond the trees. It looks like some sort of building. From this angle
you can make out a {wfaint footpath{n leading in that direction, all
you can make out a |wfaint footpath|n leading in that direction, all
but impossible to make out from ground level. You mentally register
where the footpath starts and will now be able to find it again.
@ -376,7 +376,7 @@ north
@desc
You stand outside a one-story sturdy wooden building. Light flickers
behind closed storm shutters. Over the door a sign creaks in the wind
- the writing says {cEvennia Inn{n and the curly letters are
- the writing says |cEvennia Inn|n and the curly letters are
surrounded by a painted image of some sort of snake. From inside you
hear the sound of laughter, singing and loud conversation.
#
@ -413,12 +413,12 @@ north
Soon you have a beer in hand and are chatting with the locals. Your
eye falls on a {wbarrel{n in a corner with a few old rusty weapons
sticking out. There is a sign next to it: {wFree to take{n. A patron
eye falls on a |wbarrel|n in a corner with a few old rusty weapons
sticking out. There is a sign next to it: |wFree to take|n. A patron
tells you cheerfully that it's the leftovers from those foolish
adventurers that challenged the old ruin before you ...
(to get a weapon from the barrel, use {wget weapon{n)
(to get a weapon from the barrel, use |wget weapon|n)
#
@desc barrel =
This barrel has the air of leftovers - it contains an assorted
@ -544,11 +544,11 @@ bridge
@desc
You are on a narrow ledge protruding from the side of the cliff,
about halfway down. The air is saturated with salty sea water,
sprays hitting your face from the crashing waves {wbelow{n.
sprays hitting your face from the crashing waves |wbelow|n.
The ledge is covered with a few black-grey brushes. Not far from you
the cliff-face is broken down to reveal a narrow natural opening into
the cliff. High above you the {wbridge{n sways and creaks in the wind.
the cliff. High above you the |wbridge|n sways and creaks in the wind.
#
@detail brush;brushes =
The brushes covering the ledge are gray and dwarfed from constantly
@ -662,7 +662,7 @@ hole
# light source.
#
@desc
{YThe {yflickering light{Y of your makeshift light reveals a small square
|YThe |yflickering light|Y of your makeshift light reveals a small square
cell. It does not seem like you are still in the castle, for the
stone of the walls are chiseled crudely and drip with water and mold.
@ -671,7 +671,7 @@ hole
been a bed or a bench but is now nothing more than a pile of splinters,
one of which you are using for light. One of the walls is covered with a
thick cover of black roots having broken through the cracks from the
outside.{n
outside.|n
#
@detail iron-cast door;iron;door;iron-cast =
The door is very solid and clad in iron. No matter how much you push
@ -740,9 +740,9 @@ hole
portcullis, formerly blocking off the inner castle from attack, is
sprawled over the ground together with most of its frame.
{wEast{n the gatehouse leads out to a small open area surrounded by
|wEast|n the gatehouse leads out to a small open area surrounded by
the remains of the castle. There is also a standing archway
offering passage to a path along the old {wsouth{nern inner wall.
offering passage to a path along the old |wsouth|nern inner wall.
#
@detail portoculis;fall;fallen;grating =
This heavy iron grating used to block off the inner part of the gate house, now it has fallen
@ -784,9 +784,9 @@ archway
against the outer wall. The whole scene is directly open to the sky.
The buildings make a half-circle along the main wall, here and there
broken by falling stone and rubble. At one end (the {wnorth{nern) of
broken by falling stone and rubble. At one end (the |wnorth|nern) of
this half-circle is the entrance to the castle, the ruined
gatehoue. {wEast{nwards from here is some sort of open courtyard.
gatehoue. |wEast|nwards from here is some sort of open courtyard.
#------------------------------------------------------------
#
@ -802,13 +802,13 @@ archway
#
@desc
The ruins opens up to the sky in a small open area, lined by
columns. The open area is dominated by a huge stone {wobelisk{n in its
columns. The open area is dominated by a huge stone |wobelisk|n in its
center, an ancient ornament miraculously still standing.
Previously one could probably continue past the obelisk and eastward
into the castle keep itself, but that way is now completely blocked
by fallen rubble. To the {wwest{n is the gatehouse and entrance to
the castle, whereas {wsouth{nwards the collumns make way for a wide
by fallen rubble. To the |wwest|n is the gatehouse and entrance to
the castle, whereas |wsouth|nwards the collumns make way for a wide
open courtyard.
#
@set here/tutorial_info =
@ -829,7 +829,7 @@ archway
# Set the puzzle clues on the obelisk. The order should correspond
# to the ids later checked by the antechamber puzzle.
#
@set obelisk/puzzle_descs = ("You can briefly make out the image of {ba woman with a blue bird{n.", "You for a moment see the visage of {ba woman on a horse{n.", "For the briefest moment you make out an engraving of {ba regal woman wearing a crown{n.", "You think you can see the outline of {ba flaming shield{n in the stone.", "The surface for a moment seems to portray {ba sharp-faced woman with white hair{n.")
@set obelisk/puzzle_descs = ("You can briefly make out the image of |ba woman with a blue bird|n.", "You for a moment see the visage of |ba woman on a horse|n.", "For the briefest moment you make out an engraving of |ba regal woman wearing a crown|n.", "You think you can see the outline of |ba flaming shield|n in the stone.", "The surface for a moment seems to portray |ba sharp-faced woman with white hair|n.")
# Create the mobile. This is its start location.
@create/drop Ghostly apparition;ghost;apparition;fog : tutorial_world.mob.Mob
@ -942,9 +942,9 @@ mobon ghost
overgrown with low grass and patches of thorny vines. There is a
collapsed structure close to the gatehouse that looks like a stable.
{wNorth{nwards is a smaller area cornered in the debris, adorned with
a large obelisk-like thing. To the {wwest{n the castle walls loom
over a mess of collapsed buildings. On the opposite, {weast{nern side
|wNorth|nwards is a smaller area cornered in the debris, adorned with
a large obelisk-like thing. To the |wwest|n the castle walls loom
over a mess of collapsed buildings. On the opposite, |weast|nern side
of the yard is a large building with a curved roof that seem to have
withstood the test of time better than many of those around it, it
looks like some sort of temple.
@ -1009,7 +1009,7 @@ stairs down
close to great power.
The sides of the chamber are lined with stone archways, these are
entrances to the {wtombs{n of what must have been influential
entrances to the |wtombs|n of what must have been influential
families or individual heroes of the realm. Each is adorned by a
stone statue or symbol of fine make. They do not seem to be ordered
in any particular order or rank.
@ -1050,8 +1050,8 @@ Blue bird tomb
make out a coffin in front of you in the gloom.
{rSuddenly you hear a distinct 'click' and the ground abruptly
disappears under your feet! You fall ... things go dark. {n
|rSuddenly you hear a distinct 'click' and the ground abruptly
disappears under your feet! You fall ... things go dark. |n
...
@ -1097,8 +1097,8 @@ Tomb of woman on horse
make out a coffin in front of you in the gloom.
{rSuddenly you hear a distinct 'click' and the ground abruptly
disappears under your feet! You fall ... things go dark. {n
|rSuddenly you hear a distinct 'click' and the ground abruptly
disappears under your feet! You fall ... things go dark. |n
...
@ -1143,8 +1143,8 @@ Tomb of the crowned queen
make out a coffin in front of you in the gloom.
{rSuddenly you hear a distinct 'click' and the ground abruptly
disappears under your feet! You fall ... things go dark. {n
|rSuddenly you hear a distinct 'click' and the ground abruptly
disappears under your feet! You fall ... things go dark. |n
...
@ -1190,8 +1190,8 @@ Tomb of the shield
make out a coffin in front of you in the gloom.
{rSuddenly you hear a distinct 'click' and the ground abruptly
disappears under your feet! You fall ... things go dark. {n
|rSuddenly you hear a distinct 'click' and the ground abruptly
disappears under your feet! You fall ... things go dark. |n
...
@ -1238,8 +1238,8 @@ Tomb of the hero
make out a coffin in front of you in the gloom.
{rSuddenly you hear a distinct 'click' and the ground abruptly
disappears under your feet! You fall ... things go dark. {n
|rSuddenly you hear a distinct 'click' and the ground abruptly
disappears under your feet! You fall ... things go dark. |n
...
@ -1304,7 +1304,7 @@ The weapon held by the stone hands looks very realistic ...
rather than one in stone. This must be the hero's legendary weapon!
The prize you have been looking for!
(try {wget weapon{n)
(try |wget weapon|n)
#
@set sarcophagus/rack_id = rack_sarcophagus
#
@ -1317,14 +1317,14 @@ The prize you have been looking for!
Trembling you carefully release the weapon from the stone to test
its weight. You are finally holding your prize,
The {c%s{n
The |c%s|n
in your hands!
{gThis concludes the Evennia tutorial. From here you can either
|gThis concludes the Evennia tutorial. From here you can either
continue to explore the castle (hint: this weapon works better
against the castle guardian than any you might have found earlier) or
you can choose to exit.{n
you can choose to exit.|n
#------------------------------------------------------------
#
@ -1353,14 +1353,14 @@ The prize you have been looking for!
#
# this room quits the tutorial and cleans up all variables that were set.
@desc
{gThanks for trying out this little Evennia tutorial!
|gThanks for trying out this little Evennia tutorial!
The game play given here is of course just scraping the surface of
what can be done with Evennia. The tutorial focuses more on showing
various techniques than to supply any sort of novel storytelling or
gaming challenge. The full README and source code for the tutorial
world can be found under {wcontrib/tutorial_world{g.
world can be found under |wcontrib/tutorial_world|g.
If you went through the tutorial quest once, it can be interesting to
@ -1368,7 +1368,7 @@ The prize you have been looking for!
not have come across yet, maybe with the source/build code next to
you. If you play as superuser (user #1) the mobile will ignore you
and teleport rooms etc will not affect you (this will also disable all
locks, so keep that in mind when checking functionality).{n
locks, so keep that in mind when checking functionality).|n
#
@set here/tutorial_info =
This room cleans up all temporary attributes and tags that were put

View file

@ -23,7 +23,7 @@ from evennia.contrib.tutorial_world.objects import LightSource
from django.conf import settings
_SEARCH_AT_RESULT = utils.object_from_module(settings.SEARCH_AT_RESULT)
#------------------------------------------------------------
# -------------------------------------------------------------
#
# Tutorial room - parent room class
#
@ -31,11 +31,11 @@ _SEARCH_AT_RESULT = utils.object_from_module(settings.SEARCH_AT_RESULT)
# It defines a tutorial command on itself (available to
# all those who are in a tutorial room).
#
#------------------------------------------------------------
# -------------------------------------------------------------
#
# Special command available in all tutorial rooms
#
class CmdTutorial(Command):
"""
@ -62,16 +62,16 @@ class CmdTutorial(Command):
caller = self.caller
if not self.args:
target = self.obj # this is the room the command is defined on
target = self.obj # this is the room the command is defined on
else:
target = caller.search(self.args.strip())
if not target:
return
helptext = target.db.tutorial_info
if helptext:
caller.msg("{G%s{n" % helptext)
caller.msg("|G%s|n" % helptext)
else:
caller.msg("{RSorry, there is no tutorial help available here.{n")
caller.msg("|RSorry, there is no tutorial help available here.|n")
# for the @detail command we inherit from MuxCommand, since
@ -204,7 +204,7 @@ class TutorialRoomCmdSet(CmdSet):
priority = 1
def at_cmdset_creation(self):
"add the tutorial-room commands"
"""add the tutorial-room commands"""
self.add(CmdTutorial())
self.add(CmdTutorialSetDetail())
self.add(CmdTutorialLook())
@ -216,7 +216,7 @@ class TutorialRoom(DefaultRoom):
It defines a cmdset on itself for reading tutorial info about the location.
"""
def at_object_creation(self):
"Called when room is first created"
"""Called when room is first created"""
self.db.tutorial_info = "This is a tutorial room. It allows you to use the 'tutorial' command."
self.cmdset.add_default(TutorialRoomCmdSet)
@ -270,11 +270,11 @@ class TutorialRoom(DefaultRoom):
self.db.details = {detailkey.lower(): description}
#------------------------------------------------------------
# -------------------------------------------------------------
#
# Weather room - room with a ticker
#
#------------------------------------------------------------
# -------------------------------------------------------------
# These are rainy weather strings
WEATHER_STRINGS = (
@ -290,6 +290,7 @@ WEATHER_STRINGS = (
"You hear the distant howl of what sounds like some sort of dog or wolf.",
"Large clouds rush across the sky, throwing their load of rain over the world.")
class WeatherRoom(TutorialRoom):
"""
This should probably better be called a rainy room...
@ -328,8 +329,7 @@ class WeatherRoom(TutorialRoom):
"""
if random.random() < 0.2:
# only update 20 % of the time
self.msg_contents("{w%s{n" % random.choice(WEATHER_STRINGS))
self.msg_contents("|w%s|n" % random.choice(WEATHER_STRINGS))
SUPERUSER_WARNING = "\nWARNING: You are playing as a superuser ({name}). Use the {quell} command to\n" \
@ -338,14 +338,15 @@ SUPERUSER_WARNING = "\nWARNING: You are playing as a superuser ({name}). Use the
"the scenes later).\n" \
#-----------------------------------------------------------
# ------------------------------------------------------------
#
# Intro Room - unique room
#
# This room marks the start of the tutorial. It sets up properties on
# the player char that is needed for the tutorial.
#
#------------------------------------------------------------
# -------------------------------------------------------------
class IntroRoom(TutorialRoom):
"""
@ -377,10 +378,10 @@ class IntroRoom(TutorialRoom):
if character.is_superuser:
string = "-"*78 + SUPERUSER_WARNING + "-"*78
character.msg("{r%s{n" % string.format(name=character.key, quell="{w@quell{r"))
character.msg("|r%s|n" % string.format(name=character.key, quell="|w@quell|r"))
#------------------------------------------------------------
# -------------------------------------------------------------
#
# Bridge - unique room
#
@ -394,7 +395,7 @@ class IntroRoom(TutorialRoom):
# divided into five steps:
# westroom <- 0 1 2 3 4 -> eastroom
#
#------------------------------------------------------------
# -------------------------------------------------------------
class CmdEast(Command):
@ -419,7 +420,7 @@ class CmdEast(Command):
help_category = "TutorialWorld"
def func(self):
"move one step eastwards"
"""move one step eastwards"""
caller = self.caller
bridge_step = min(5, caller.db.tutorial_bridge_position + 1)
@ -463,7 +464,7 @@ class CmdWest(Command):
help_category = "TutorialWorld"
def func(self):
"move one step westwards"
"""move one step westwards"""
caller = self.caller
bridge_step = max(-1, caller.db.tutorial_bridge_position - 1)
@ -484,25 +485,31 @@ class CmdWest(Command):
caller.execute_cmd("look")
BRIDGE_POS_MESSAGES = ("You are standing {wvery close to the the bridge's western foundation{n. If you go west you will be back on solid ground ...",
"The bridge slopes precariously where it extends eastwards towards the lowest point - the center point of the hang bridge.",
"You are {whalfways{n out on the unstable bridge.",
"The bridge slopes precariously where it extends westwards towards the lowest point - the center point of the hang bridge.",
"You are standing {wvery close to the bridge's eastern foundation{n. If you go east you will be back on solid ground ...")
BRIDGE_POS_MESSAGES = ("You are standing |wvery close to the the bridge's western foundation|n."
" If you go west you will be back on solid ground ...",
"The bridge slopes precariously where it extends eastwards"
" towards the lowest point - the center point of the hang bridge.",
"You are |whalfways|n out on the unstable bridge.",
"The bridge slopes precariously where it extends westwards"
" towards the lowest point - the center point of the hang bridge.",
"You are standing |wvery close to the bridge's eastern foundation|n."
" If you go east you will be back on solid ground ...")
BRIDGE_MOODS = ("The bridge sways in the wind.", "The hanging bridge creaks dangerously.",
"You clasp the ropes firmly as the bridge sways and creaks under you.",
"From the castle you hear a distant howling sound, like that of a large dog or other beast.",
"The bridge creaks under your feet. Those planks does not seem very sturdy.",
"Far below you the ocean roars and throws its waves against the cliff, as if trying its best to reach you.",
"Far below you the ocean roars and throws its waves against the cliff,"
" as if trying its best to reach you.",
"Parts of the bridge come loose behind you, falling into the chasm far below!",
"A gust of wind causes the bridge to sway precariously.",
"Under your feet a plank comes loose, tumbling down. For a moment you dangle over the abyss ...",
"The section of rope you hold onto crumble in your hands, parts of it breaking apart. You sway trying to regain balance.")
"The section of rope you hold onto crumble in your hands,"
" parts of it breaking apart. You sway trying to regain balance.")
FALL_MESSAGE = "Suddenly the plank you stand on gives way under your feet! You fall!" \
"\nYou try to grab hold of an adjoining plank, but all you manage to do is to " \
"divert your fall westwards, towards the cliff face. This is going to hurt ... " \
"\n ... The world goes dark ...\n\n" \
"\n ... The world goes dark ...\n\n"
class CmdLookBridge(Command):
@ -520,20 +527,20 @@ class CmdLookBridge(Command):
help_category = "TutorialWorld"
def func(self):
"Looking around, including a chance to fall."
"""Looking around, including a chance to fall."""
caller = self.caller
bridge_position = self.caller.db.tutorial_bridge_position
# this command is defined on the room, so we get it through self.obj
location = self.obj
# randomize the look-echo
message = "{c%s{n\n%s\n%s" % (location.key,
message = "|c%s|n\n%s\n%s" % (location.key,
BRIDGE_POS_MESSAGES[bridge_position],
random.choice(BRIDGE_MOODS))
chars = [obj for obj in self.obj.contents_get(exclude=caller) if obj.has_player]
if chars:
# we create the You see: message manually here
message += "\n You see: %s" % ", ".join("{c%s{n" % char.key for char in chars)
message += "\n You see: %s" % ", ".join("|c%s|n" % char.key for char in chars)
self.caller.msg(message)
# there is a chance that we fall if we are on the western or central
@ -542,10 +549,10 @@ class CmdLookBridge(Command):
# we fall 5% of time.
fall_exit = search_object(self.obj.db.fall_exit)
if fall_exit:
self.caller.msg("{r%s{n" % FALL_MESSAGE)
self.caller.msg("|r%s|n" % FALL_MESSAGE)
self.caller.move_to(fall_exit[0], quiet=True)
# inform others on the bridge
self.obj.msg_contents("A plank gives way under %s's feet and " \
self.obj.msg_contents("A plank gives way under %s's feet and "
"they fall from the bridge!" % self.caller.key)
@ -555,24 +562,25 @@ class CmdBridgeHelp(Command):
Overwritten help command while on the bridge.
"""
key = "help"
aliases = ["h"]
aliases = ["h", "?"]
locks = "cmd:all()"
help_category = "Tutorial world"
def func(self):
"Implements the command."
string = "You are trying hard not to fall off the bridge ..."
string += "\n\nWhat you can do is trying to cross the bridge {weast{n "
string += "or try to get back to the mainland {wwest{n)."
"""Implements the command."""
string = "You are trying hard not to fall off the bridge ..." \
"\n\nWhat you can do is trying to cross the bridge |weast|n" \
" or try to get back to the mainland |wwest|n)."
self.caller.msg(string)
class BridgeCmdSet(CmdSet):
"This groups the bridge commands. We will store it on the room."
"""This groups the bridge commands. We will store it on the room."""
key = "Bridge commands"
priority = 1 # this gives it precedence over the normal look/help commands.
priority = 1 # this gives it precedence over the normal look/help commands.
def at_cmdset_creation(self):
"Called at first cmdset creation"
"""Called at first cmdset creation"""
self.add(CmdTutorial())
self.add(CmdEast())
self.add(CmdWest())
@ -618,7 +626,7 @@ class BridgeRoom(WeatherRoom):
"""
def at_object_creation(self):
"Setups the room"
"""Setups the room"""
# this will start the weather room's ticker and tell
# it to call update_weather regularly.
super(BridgeRoom, self).at_object_creation()
@ -644,7 +652,7 @@ class BridgeRoom(WeatherRoom):
"""
if random.random() < 80:
# send a message most of the time
self.msg_contents("{w%s{n" % random.choice(BRIDGE_WEATHER))
self.msg_contents("|w%s|n" % random.choice(BRIDGE_WEATHER))
def at_object_receive(self, character, source_location):
"""
@ -658,7 +666,7 @@ class BridgeRoom(WeatherRoom):
eexit = search_object(self.db.east_exit)
fexit = search_object(self.db.fall_exit)
if not (wexit and eexit and fexit):
character.msg("The bridge's exits are not properly configured. "\
character.msg("The bridge's exits are not properly configured. "
"Contact an admin. Forcing west-end placement.")
character.db.tutorial_bridge_position = 0
return
@ -679,7 +687,7 @@ class BridgeRoom(WeatherRoom):
del character.db.tutorial_bridge_position
#------------------------------------------------------------------------------
# -------------------------------------------------------------------------------
#
# Dark Room - a room with states
#
@ -687,7 +695,7 @@ class BridgeRoom(WeatherRoom):
# LightSource object (LightSource is defined in
# tutorialworld.objects.LightSource)
#
#------------------------------------------------------------------------------
# -------------------------------------------------------------------------------
DARK_MESSAGES = ("It is pitch black. You are likely to be eaten by a grue.",
@ -695,16 +703,20 @@ DARK_MESSAGES = ("It is pitch black. You are likely to be eaten by a grue.",
"You don't see a thing. You feel around, managing to bump your fingers hard against something. Ouch!",
"You don't see a thing! Blindly grasping the air around you, you find nothing.",
"It's totally dark here. You almost stumble over some un-evenness in the ground.",
"You are completely blind. For a moment you think you hear someone breathing nearby ... \n ... surely you must be mistaken.",
"You are completely blind. For a moment you think you hear someone breathing nearby ... "
"\n ... surely you must be mistaken.",
"Blind, you think you find some sort of object on the ground, but it turns out to be just a stone.",
"Blind, you bump into a wall. The wall seems to be covered with some sort of vegetation, but its too damp to burn.",
"Blind, you bump into a wall. The wall seems to be covered with some sort of vegetation,"
" but its too damp to burn.",
"You can't see anything, but the air is damp. It feels like you are far underground.")
ALREADY_LIGHTSOURCE = "You don't want to stumble around in blindness anymore. You already " \
"found what you need. Let's get light already!"
FOUND_LIGHTSOURCE = "Your fingers bump against a splinter of wood in a corner. It smells of resin and seems dry enough to burn! " \
"You pick it up, holding it firmly. Now you just need to {wlight{n it using the flint and steel you carry with you."
FOUND_LIGHTSOURCE = "Your fingers bump against a splinter of wood in a corner." \
" It smells of resin and seems dry enough to burn! " \
"You pick it up, holding it firmly. Now you just need to" \
" |wlight|n it using the flint and steel you carry with you."
class CmdLookDark(Command):
@ -774,7 +786,7 @@ class CmdDarkNoMatch(Command):
locks = "cmd:all()"
def func(self):
"Implements the command."
"""Implements the command."""
self.caller.msg("Until you find some light, there's not much you can do. Try feeling around.")
@ -793,7 +805,7 @@ class DarkCmdSet(CmdSet):
priority = 2
def at_cmdset_creation(self):
"populate the cmdset."
"""populate the cmdset."""
self.add(CmdTutorial())
self.add(CmdLookDark())
self.add(CmdDarkHelp())
@ -901,7 +913,7 @@ class DarkRoom(TutorialRoom):
self.check_light_state(exclude=obj)
#------------------------------------------------------------
# -------------------------------------------------------------
#
# Teleport room - puzzles solution
#
@ -914,7 +926,7 @@ class DarkRoom(TutorialRoom):
# oneself, and then pick the grave chamber with the
# matching imagery for this attribute.
#
#------------------------------------------------------------
# -------------------------------------------------------------
class TeleportRoom(TutorialRoom):
@ -931,7 +943,7 @@ class TeleportRoom(TutorialRoom):
"""
def at_object_creation(self):
"Called at first creation"
"""Called at first creation"""
super(TeleportRoom, self).at_object_creation()
# what character.db.puzzle_clue must be set to, to avoid teleportation.
self.db.puzzle_value = 1
@ -977,13 +989,13 @@ class TeleportRoom(TutorialRoom):
results[0].at_object_receive(character, self)
#------------------------------------------------------------
# -------------------------------------------------------------
#
# Outro room - unique exit room
#
# Cleans up the character from all tutorial-related properties.
#
#------------------------------------------------------------
# -------------------------------------------------------------
class OutroRoom(TutorialRoom):
"""