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

View file

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

View file

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

View file

@ -54,7 +54,8 @@ except Exception:
# malformed connection screen or no screen given # malformed connection screen or no screen given
pass pass
if not CONNECTION_SCREEN: 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): class CmdUnconnectedConnect(MuxCommand):
@ -108,8 +109,8 @@ class CmdUnconnectedConnect(MuxCommand):
or or
any(tup[2].match(session.address[0]) for tup in bans if tup[2])): any(tup[2].match(session.address[0]) for tup in bans if tup[2])):
# this is a banned IP or name! # this is a banned IP or name!
string = "{rYou have been banned and cannot continue from here." 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 += "\nIf you feel this ban is in error, please email an admin.|x"
session.msg(string) session.msg(string)
session.execute_cmd("quit") session.execute_cmd("quit")
return return
@ -117,6 +118,7 @@ class CmdUnconnectedConnect(MuxCommand):
# actually do the login. This will call all hooks. # actually do the login. This will call all hooks.
session.sessionhandler.login(session, player) session.sessionhandler.login(session, player)
class CmdUnconnectedCreate(MuxCommand): class CmdUnconnectedCreate(MuxCommand):
""" """
Create a new account. Create a new account.
@ -156,7 +158,7 @@ class CmdUnconnectedCreate(MuxCommand):
self.playerinfo = (playername, email, password) self.playerinfo = (playername, email, password)
def func(self): def func(self):
"Do checks and create account" """Do checks and create account"""
session = self.caller session = self.caller
@ -167,11 +169,11 @@ class CmdUnconnectedCreate(MuxCommand):
session.msg(string) session.msg(string)
return return
if not re.findall('^[\w. @+-]+$', playername) or not (0 < len(playername) <= 30): 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\ session.msg("\n\r Playername can be max 30 characters, or less. Letters, spaces,"
its and @/./+/-/_ only.") # this echoes the restrictions made by django's auth module. " digits and @/./+/-/_ only.") # this echoes the restrictions made by django's auth module.
return return
if not email or not password: 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 return
if not utils.validate_email_address(email): 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 permissions = settings.PERMISSION_PLAYER_DEFAULT
try: try:
new_player = create.create_player(playername, email, password, new_player = create.create_player(playername, email, password, permissions=permissions)
permissions=permissions)
except Exception as e: 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() logger.log_trace()
return 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 # 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) # (in mode 2, the character must be created manually once logging in)
new_character = create.create_object(typeclass, key=playername, new_character = create.create_object(typeclass, key=playername,
location=default_home, home=default_home, location=default_home, home=default_home,
permissions=permissions) permissions=permissions)
# set playable character list # set playable character list
new_player.db._playable_characters.append(new_character) 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.") session.msg("An error occurred. Please e-mail an admin if the problem persists.")
logger.log_trace() logger.log_trace()
class CmdUnconnectedQuit(MuxCommand): class CmdUnconnectedQuit(MuxCommand):
""" """
We maintain a different version of the `quit` command We maintain a different version of the `quit` command
@ -271,7 +274,7 @@ class CmdUnconnectedQuit(MuxCommand):
locks = "cmd:all()" locks = "cmd:all()"
def func(self): def func(self):
"Simply close the connection." """Simply close the connection."""
session = self.caller session = self.caller
session.msg("Good bye! Disconnecting ...") session.msg("Good bye! Disconnecting ...")
session.session_disconnect() session.session_disconnect()
@ -289,7 +292,7 @@ class CmdUnconnectedLook(MuxCommand):
locks = "cmd:all()" locks = "cmd:all()"
def func(self): def func(self):
"Show the connect screen." """Show the connect screen."""
self.caller.msg(CONNECTION_SCREEN) self.caller.msg(CONNECTION_SCREEN)
@ -303,34 +306,34 @@ class CmdUnconnectedHelp(MuxCommand):
locks = "cmd:all()" locks = "cmd:all()"
def func(self): def func(self):
"Shows help" """Shows help"""
string = \ string = \
""" """
You are not yet logged into the game. Commands available at this point: 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: 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: 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) 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 to not use a regular word for your password. Make it longer than
3 characters (ideally 6 or more) and mix numbers and capitalization 3 characters (ideally 6 or more) and mix numbers and capitalization
into it. into it.
{w2){n If you have an account already, either because you just created |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: 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! 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) self.caller.msg(string)
@ -345,7 +348,7 @@ class UnloggedinCmdSet(CmdSet):
priority = 0 priority = 0
def at_cmdset_creation(self): def at_cmdset_creation(self):
"Populate the cmdset" """Populate the cmdset"""
self.add(CmdUnconnectedConnect()) self.add(CmdUnconnectedConnect())
self.add(CmdUnconnectedCreate()) self.add(CmdUnconnectedCreate())
self.add(CmdUnconnectedQuit()) self.add(CmdUnconnectedQuit())

View file

@ -108,7 +108,7 @@ class ExtendedRoom(DefaultRoom):
look command. look command.
""" """
def at_object_creation(self): 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.spring_desc = ""
self.db.summer_desc = "" self.db.summer_desc = ""
self.db.autumn_desc = "" self.db.autumn_desc = ""
@ -367,12 +367,12 @@ class CmdExtendedDesc(default_cmds.CmdDesc):
aliases = ["@describe", "@detail"] aliases = ["@describe", "@detail"]
def reset_times(self, obj): 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_season = None
obj.ndb.last_timeslot = None obj.ndb.last_timeslot = None
def func(self): def func(self):
"Define extended command" """Define extended command"""
caller = self.caller caller = self.caller
location = caller.location location = caller.location
if self.cmdname == 'detail': if self.cmdname == 'detail':
@ -393,13 +393,14 @@ class CmdExtendedDesc(default_cmds.CmdDesc):
if not self.args: if not self.args:
# No args given. Return all details on location # No args given. Return all details on location
string = "|wDetails on %s|n:" % 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) caller.msg("%s\n%s" % (string, details) if details else "%s None." % string)
return return
if not self.rhs: if not self.rhs:
# no '=' used - list content of given detail # no '=' used - list content of given detail
if self.args in location.db.details: 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]) string += str(location.db.details[self.args])
caller.msg(string) caller.msg(string)
else: else:
@ -414,18 +415,15 @@ class CmdExtendedDesc(default_cmds.CmdDesc):
# we are doing a @desc call # we are doing a @desc call
if not self.args: if not self.args:
if location: if location:
string = "{wDescriptions on %s{n:\n" % location.key string = "|wDescriptions on %s|n:\n" % location.key
string += " {wspring:{n %s\n" % location.db.spring_desc string += " |wspring:|n %s\n" % location.db.spring_desc
string += " {wsummer:{n %s\n" % location.db.summer_desc string += " |wsummer:|n %s\n" % location.db.summer_desc
string += " {wautumn:{n %s\n" % location.db.autumn_desc string += " |wautumn:|n %s\n" % location.db.autumn_desc
string += " {wwinter:{n %s\n" % location.db.winter_desc string += " |wwinter:|n %s\n" % location.db.winter_desc
string += " {wgeneral:{n %s" % location.db.general_desc string += " |wgeneral:|n %s" % location.db.general_desc
caller.msg(string) caller.msg(string)
return return
if self.switches and self.switches[0] in ("spring", if self.switches and self.switches[0] in ("spring", "summer", "autumn", "winter"):
"summer",
"autumn",
"winter"):
# a seasonal switch was given # a seasonal switch was given
if self.rhs: if self.rhs:
caller.msg("Seasonal descs only works with rooms, not objects.") caller.msg("Seasonal descs only works with rooms, not objects.")
@ -455,7 +453,7 @@ class CmdExtendedDesc(default_cmds.CmdDesc):
else: else:
text = self.args text = self.args
obj = location obj = location
obj.db.desc = text # a compatibility fallback obj.db.desc = text # a compatibility fallback
if obj.attributes.has("general_desc"): if obj.attributes.has("general_desc"):
obj.db.general_desc = text obj.db.general_desc = text
self.reset_times(obj) self.reset_times(obj)
@ -481,7 +479,7 @@ class CmdGameTime(default_cmds.MuxCommand):
help_category = "General" help_category = "General"
def func(self): def func(self):
"Reads time info from current room" """Reads time info from current room"""
location = self.caller.location location = self.caller.location
if not location or not hasattr(location, "get_time_and_season"): if not location or not hasattr(location, "get_time_and_season"):
self.caller.msg("No location available - you are outside time.") 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 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"] atrans = ["An", "automated", "advantageous", "repeatable", "faster"]
text = "Automated testing is advantageous for a number of reasons:" \ text = "Automated testing is advantageous for a number of reasons:" \
"tests may be executed Continuously without the need for human " \ "tests may be executed Continuously without the need for human " \
"intervention, They are easily repeatable, and often faster." "intervention, They are easily repeatable, and often faster."
class TestLanguage(EvenniaTest): class TestLanguage(EvenniaTest):
def setUp(self): def setUp(self):
super(TestLanguage, self).setUp() super(TestLanguage, self).setUp()
@ -29,6 +30,7 @@ class TestLanguage(EvenniaTest):
manual_translations=mtrans, manual_translations=mtrans,
auto_translations=atrans, auto_translations=atrans,
force=True) force=True)
def tearDown(self): def tearDown(self):
super(TestLanguage, self).tearDown() super(TestLanguage, self).tearDown()
rplanguage._LANGUAGE_HANDLER.delete() rplanguage._LANGUAGE_HANDLER.delete()
@ -70,6 +72,7 @@ recog02 = "Mr Receiver2"
recog10 = "Mr Sender" recog10 = "Mr Sender"
emote = "With a flair, /me looks at /first and /colliding sdesc-guy. She says \"This is a test.\"" emote = "With a flair, /me looks at /first and /colliding sdesc-guy. She says \"This is a test.\""
class TestRPSystem(EvenniaTest): class TestRPSystem(EvenniaTest):
def setUp(self): def setUp(self):
super(TestRPSystem, self).setUp() super(TestRPSystem, self).setUp()
@ -79,12 +82,13 @@ class TestRPSystem(EvenniaTest):
self.receiver2 = create_object(rpsystem.ContribRPCharacter, key="Receiver2", location=self.room) self.receiver2 = create_object(rpsystem.ContribRPCharacter, key="Receiver2", location=self.room)
def test_ordered_permutation_regex(self): def test_ordered_permutation_regex(self):
self.assertEqual(rpsystem.ordered_permutation_regex(sdesc0), self.assertEqual(
'/[0-9]*-*A\\ nice\\ sender\\ of\\ emotes(?=\\W|$)+|/[0-9]*-*nice\\ sender\\ ' \ rpsystem.ordered_permutation_regex(sdesc0),
'of\\ emotes(?=\\W|$)+|/[0-9]*-*A\\ nice\\ sender\\ of(?=\\W|$)+|/[0-9]*-*sender\\ ' \ '/[0-9]*-*A\\ nice\\ sender\\ of\\ emotes(?=\\W|$)+|/[0-9]*-*nice\\ sender\\ '
'of\\ emotes(?=\\W|$)+|/[0-9]*-*nice\\ sender\\ of(?=\\W|$)+|/[0-9]*-*A\\ nice\\ ' \ 'of\\ emotes(?=\\W|$)+|/[0-9]*-*A\\ nice\\ sender\\ of(?=\\W|$)+|/[0-9]*-*sender\\ '
'sender(?=\\W|$)+|/[0-9]*-*nice\\ sender(?=\\W|$)+|/[0-9]*-*of\\ emotes(?=\\W|$)+' \ 'of\\ emotes(?=\\W|$)+|/[0-9]*-*nice\\ sender\\ of(?=\\W|$)+|/[0-9]*-*A\\ nice\\ '
'|/[0-9]*-*sender\\ of(?=\\W|$)+|/[0-9]*-*A\\ nice(?=\\W|$)+|/[0-9]*-*sender(?=\\W|$)+' \ '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|$)+') '|/[0-9]*-*emotes(?=\\W|$)+|/[0-9]*-*nice(?=\\W|$)+|/[0-9]*-*of(?=\\W|$)+|/[0-9]*-*A(?=\\W|$)+')
def test_sdesc_handler(self): def test_sdesc_handler(self):
@ -93,10 +97,11 @@ class TestRPSystem(EvenniaTest):
self.speaker.sdesc.add("This is {#324} ignored") self.speaker.sdesc.add("This is {#324} ignored")
self.assertEqual(self.speaker.sdesc.get(), "This is 324 ignored") self.assertEqual(self.speaker.sdesc.get(), "This is 324 ignored")
self.speaker.sdesc.add("Testing three words") self.speaker.sdesc.add("Testing three words")
self.assertEqual(self.speaker.sdesc.get_regex_tuple()[0].pattern, self.assertEqual(
'/[0-9]*-*Testing\\ three\\ words(?=\\W|$)+|/[0-9]*-*Testing\\ ' \ self.speaker.sdesc.get_regex_tuple()[0].pattern,
'three(?=\\W|$)+|/[0-9]*-*three\\ words(?=\\W|$)+|/[0-9]*-*Testing'\ '/[0-9]*-*Testing\\ three\\ words(?=\\W|$)+|/[0-9]*-*Testing\\ '
'(?=\\W|$)+|/[0-9]*-*three(?=\\W|$)+|/[0-9]*-*words(?=\\W|$)+') 'three(?=\\W|$)+|/[0-9]*-*three\\ words(?=\\W|$)+|/[0-9]*-*Testing'
'(?=\\W|$)+|/[0-9]*-*three(?=\\W|$)+|/[0-9]*-*words(?=\\W|$)+')
def test_recog_handler(self): def test_recog_handler(self):
self.speaker.sdesc.add(sdesc0) self.speaker.sdesc.add(sdesc0)
@ -105,15 +110,17 @@ class TestRPSystem(EvenniaTest):
self.speaker.recog.add(self.receiver2, recog02) self.speaker.recog.add(self.receiver2, recog02)
self.assertEqual(self.speaker.recog.get(self.receiver1), recog01) self.assertEqual(self.speaker.recog.get(self.receiver1), recog01)
self.assertEqual(self.speaker.recog.get(self.receiver2), recog02) self.assertEqual(self.speaker.recog.get(self.receiver2), recog02)
self.assertEqual(self.speaker.recog.get_regex_tuple(self.receiver1)[0].pattern, self.assertEqual(
'/[0-9]*-*Mr\\ Receiver(?=\\W|$)+|/[0-9]*-*Receiver(?=\\W|$)+|/[0-9]*-*Mr(?=\\W|$)+') 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.speaker.recog.remove(self.receiver1)
self.assertEqual(self.speaker.recog.get(self.receiver1), sdesc1) self.assertEqual(self.speaker.recog.get(self.receiver1), sdesc1)
def test_parse_language(self): def test_parse_language(self):
self.assertEqual(rpsystem.parse_language(self.speaker, emote), self.assertEqual(
('With a flair, /me looks at /first and /colliding sdesc-guy. She says {##0}', rpsystem.parse_language(self.speaker, emote),
{'##0': (None, '"This is a test."')}) ) ('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): def parse_sdescs_and_recogs(self):
speaker = self.speaker speaker = self.speaker
@ -122,8 +129,8 @@ class TestRPSystem(EvenniaTest):
self.receiver2.sdesc.add(sdesc2) self.receiver2.sdesc.add(sdesc2)
candidates = (self.receiver1, self.receiver2) candidates = (self.receiver1, self.receiver2)
result = ('With a flair, {#9} looks at {#10} and {#11}. She says "This is a test."', 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': {'#11': 'Another nice colliding sdesc-guy for tests', '#10':
'The first receiver of emotes.', '#9': 'A nice sender of emotes'}) 'The first receiver of emotes.', '#9': 'A nice sender of emotes'})
self.assertEqual(rpsystem.parse_sdescs_and_recogs(speaker, candidates, emote), result) self.assertEqual(rpsystem.parse_sdescs_and_recogs(speaker, candidates, emote), result)
self.speaker.recog.add(self.receiver1, recog01) self.speaker.recog.add(self.receiver1, recog01)
self.assertEqual(rpsystem.parse_sdescs_and_recogs(speaker, candidates, emote), result) 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) receiver1.msg = lambda text, **kwargs: setattr(self, "out1", text)
receiver2.msg = lambda text, **kwargs: setattr(self, "out2", text) receiver2.msg = lambda text, **kwargs: setattr(self, "out2", text)
rpsystem.send_emote(speaker, receivers, emote) rpsystem.send_emote(speaker, receivers, emote)
self.assertEqual(self.out0, 'With a flair, |bSender|n looks at |bThe first receiver of emotes.|n ' \ self.assertEqual(
'and |bAnother nice colliding sdesc-guy for tests|n. She says |w"This is a test."|n') self.out0, 'With a flair, |bSender|n looks at |bThe first receiver of emotes.|n '
self.assertEqual(self.out1, 'With a flair, |bA nice sender of emotes|n looks at |bReceiver1|n and ' \ 'and |bAnother nice colliding sdesc-guy for tests|n. She says |w"This is a test."|n')
'|bAnother nice colliding sdesc-guy for tests|n. She says |w"This is a test."|n') self.assertEqual(
self.assertEqual(self.out2, 'With a flair, |bA nice sender of emotes|n looks at |bThe first ' \ self.out1, 'With a flair, |bA nice sender of emotes|n looks at |bReceiver1|n and '
'receiver of emotes.|n and |bReceiver2|n. She says |w"This is a test."|n') '|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): def test_rpsearch(self):
self.speaker.sdesc.add(sdesc0) self.speaker.sdesc.add(sdesc0)
@ -195,7 +205,7 @@ class TestExtendedRoom(CommandTest):
self.assertEqual(self.DETAIL_DESC, self.room1.return_detail("testdetail")) self.assertEqual(self.DETAIL_DESC, self.room1.return_detail("testdetail"))
def test_cmdextendedlook(self): 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(), "testdetail", self.DETAIL_DESC)
self.call(extended_room.CmdExtendedLook(), "nonexistent", "Could not find 'nonexistent'.") self.call(extended_room.CmdExtendedLook(), "nonexistent", "Could not find 'nonexistent'.")
@ -214,7 +224,6 @@ class TestExtendedRoom(CommandTest):
# Test the contrib barter system # Test the contrib barter system
from evennia import create_object
from evennia.contrib import barter from evennia.contrib import barter
class TestBarter(CommandTest): class TestBarter(CommandTest):
@ -230,8 +239,8 @@ class TestBarter(CommandTest):
self.char2.msg = Mock() self.char2.msg = Mock()
# test all methods of the tradehandler # test all methods of the tradehandler
handler = barter.TradeHandler(self.char1, self.char2) handler = barter.TradeHandler(self.char1, self.char2)
self.assertEqual(handler.partA, self.char1) self.assertEqual(handler.part_a, self.char1)
self.assertEqual(handler.partB, self.char2) self.assertEqual(handler.part_b, self.char2)
handler.msg_other(self.char1, "Want to trade?") handler.msg_other(self.char1, "Want to trade?")
handler.msg_other(self.char2, "Yes!") handler.msg_other(self.char2, "Yes!")
handler.msg_other(None, "Talking to myself...") handler.msg_other(None, "Talking to myself...")
@ -253,19 +262,19 @@ class TestBarter(CommandTest):
handler = barter.TradeHandler(self.char1, self.char2) handler = barter.TradeHandler(self.char1, self.char2)
handler.join(self.char2) handler.join(self.char2)
handler.offer(self.char1, self.tradeitem1, self.tradeitem2) handler.offer(self.char1, self.tradeitem1, self.tradeitem2)
self.assertEqual(handler.partA_offers, [self.tradeitem1, self.tradeitem2]) self.assertEqual(handler.part_a_offers, [self.tradeitem1, self.tradeitem2])
self.assertFalse(handler.partA_accepted) self.assertFalse(handler.part_a_accepted)
self.assertFalse(handler.partB_accepted) self.assertFalse(handler.part_b_accepted)
handler.offer(self.char2, self.tradeitem3) handler.offer(self.char2, self.tradeitem3)
self.assertEqual(handler.list(), ([self.tradeitem1, self.tradeitem2], [self.tradeitem3])) self.assertEqual(handler.list(), ([self.tradeitem1, self.tradeitem2], [self.tradeitem3]))
self.assertEqual(handler.search("TradeItem2"), self.tradeitem2) self.assertEqual(handler.search("TradeItem2"), self.tradeitem2)
self.assertEqual(handler.search("TradeItem3"), self.tradeitem3) self.assertEqual(handler.search("TradeItem3"), self.tradeitem3)
self.assertEqual(handler.search("nonexisting"), None) 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.accept(self.char1)
handler.decline(self.char1) handler.decline(self.char1)
handler.accept(self.char2) 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.tradeitem1.location, self.char2)
self.assertEqual(self.tradeitem2.location, self.char2) self.assertEqual(self.tradeitem2.location, self.char2)
self.assertEqual(self.tradeitem3.location, self.char1) 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.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.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.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) " [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.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]") 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) self.assertEquals(len(exits), 3)
exitsok = ["north", "northeast", "east"] exitsok = ["north", "northeast", "east"]
for exit in exitsok: for each_exit in exitsok:
self.assertTrue(any([e for e in exits if e.key == exit])) 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 # If we move to another location not on an edge, then all directions
# should be visible / traversable # should be visible / traversable
@ -370,8 +379,8 @@ class TestWilderness(EvenniaTest):
self.assertEquals(len(exits), 8) self.assertEquals(len(exits), 8)
exitsok = ["north", "northeast", "east", "southeast", "south", exitsok = ["north", "northeast", "east", "southeast", "south",
"southwest", "west", "northwest"] "southwest", "west", "northwest"]
for exit in exitsok: for each_exit in exitsok:
self.assertTrue(any([e for e in exits if e.key == exit])) self.assertTrue(any([e for e in exits if e.key == each_exit]))
def test_room_creation(self): def test_room_creation(self):
# Pretend that both char1 and char2 are connected... # Pretend that both char1 and char2 are connected...
@ -414,6 +423,6 @@ class TestWilderness(EvenniaTest):
"southwest": (0, 0), "southwest": (0, 0),
"west": (0, 1), "west": (0, 1),
"northwest": (0, 2)} "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) new_loc = wilderness.get_new_coordinates(loc, direction)
self.assertEquals(new_loc, correct_loc, direction) self.assertEquals(new_loc, correct_loc, direction)

View file

@ -94,7 +94,7 @@
# describe the tutorial exit # describe the tutorial exit
# #
@desc tutorial = @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. some of the server's possibilities.
# #
# now we actually go to the tutorial # now we actually go to the tutorial
@ -104,13 +104,13 @@ tutorial
# ... and describe it. # ... and describe it.
# #
@desc @desc
{gWelcome to the Evennia tutorial!{n |gWelcome to the Evennia tutorial!|n
The following tutorial consists of a small single-player quest The following tutorial consists of a small single-player quest
area. The various rooms are designed to show off some of the power area. The various rooms are designed to show off some of the power
and possibilities of the Evennia mud creation system. At any time 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 command to get some background info about the room or certain objects
to see what is going on "behind the scenes". to see what is going on "behind the scenes".
@ -127,8 +127,8 @@ tutorial
along a high, rocky coast ... along a high, rocky coast ...
{g(write 'start' or 'begin' to start the tutorial. Try 'tutorial' |g(write 'start' or 'begin' to start the tutorial. Try 'tutorial'
to get behind-the-scenes help anywhere.){n to get behind-the-scenes help anywhere.)|n
# #
# Show that the tutorial command works ... # Show that the tutorial command works ...
# #
@ -203,12 +203,12 @@ start
used for all tutorial rooms can display. used for all tutorial rooms can display.
# #
@desc @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, 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 pushed flat by wind and rain. Inland, the vast dark moors begin, only
here and there covered in patches of low trees and brushes. 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 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, shore. The only way to reach it seems by way of an old hanging bridge,
anchored not far east from here. anchored not far east from here.
@ -327,9 +327,9 @@ start
The branches are wet and slippery but can easily carry your The branches are wet and slippery but can easily carry your
weight. From this high vantage point you can see far and wide. 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 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 but impossible to make out from ground level. You mentally register
where the footpath starts and will now be able to find it again. where the footpath starts and will now be able to find it again.
@ -376,7 +376,7 @@ north
@desc @desc
You stand outside a one-story sturdy wooden building. Light flickers You stand outside a one-story sturdy wooden building. Light flickers
behind closed storm shutters. Over the door a sign creaks in the wind 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 surrounded by a painted image of some sort of snake. From inside you
hear the sound of laughter, singing and loud conversation. 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 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 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 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 tells you cheerfully that it's the leftovers from those foolish
adventurers that challenged the old ruin before you ... 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 = @desc barrel =
This barrel has the air of leftovers - it contains an assorted This barrel has the air of leftovers - it contains an assorted
@ -544,11 +544,11 @@ bridge
@desc @desc
You are on a narrow ledge protruding from the side of the cliff, You are on a narrow ledge protruding from the side of the cliff,
about halfway down. The air is saturated with salty sea water, 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 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-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 = @detail brush;brushes =
The brushes covering the ledge are gray and dwarfed from constantly The brushes covering the ledge are gray and dwarfed from constantly
@ -662,7 +662,7 @@ hole
# light source. # light source.
# #
@desc @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 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. 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, 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 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 thick cover of black roots having broken through the cracks from the
outside.{n outside.|n
# #
@detail iron-cast door;iron;door;iron-cast = @detail iron-cast door;iron;door;iron-cast =
The door is very solid and clad in iron. No matter how much you push 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 portcullis, formerly blocking off the inner castle from attack, is
sprawled over the ground together with most of its frame. 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 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 = @detail portoculis;fall;fallen;grating =
This heavy iron grating used to block off the inner part of the gate house, now it has fallen 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. 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 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 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 @desc
The ruins opens up to the sky in a small open area, lined by 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. center, an ancient ornament miraculously still standing.
Previously one could probably continue past the obelisk and eastward Previously one could probably continue past the obelisk and eastward
into the castle keep itself, but that way is now completely blocked 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 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 the castle, whereas |wsouth|nwards the collumns make way for a wide
open courtyard. open courtyard.
# #
@set here/tutorial_info = @set here/tutorial_info =
@ -829,7 +829,7 @@ archway
# Set the puzzle clues on the obelisk. The order should correspond # Set the puzzle clues on the obelisk. The order should correspond
# to the ids later checked by the antechamber puzzle. # 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 the mobile. This is its start location.
@create/drop Ghostly apparition;ghost;apparition;fog : tutorial_world.mob.Mob @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 overgrown with low grass and patches of thorny vines. There is a
collapsed structure close to the gatehouse that looks like a stable. collapsed structure close to the gatehouse that looks like a stable.
{wNorth{nwards is a smaller area cornered in the debris, adorned with |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 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 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 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 withstood the test of time better than many of those around it, it
looks like some sort of temple. looks like some sort of temple.
@ -1009,7 +1009,7 @@ stairs down
close to great power. close to great power.
The sides of the chamber are lined with stone archways, these are 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 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 stone statue or symbol of fine make. They do not seem to be ordered
in any particular order or rank. in any particular order or rank.
@ -1050,8 +1050,8 @@ Blue bird tomb
make out a coffin in front of you in the gloom. make out a coffin in front of you in the gloom.
{rSuddenly you hear a distinct 'click' and the ground abruptly |rSuddenly you hear a distinct 'click' and the ground abruptly
disappears under your feet! You fall ... things go dark. {n 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. make out a coffin in front of you in the gloom.
{rSuddenly you hear a distinct 'click' and the ground abruptly |rSuddenly you hear a distinct 'click' and the ground abruptly
disappears under your feet! You fall ... things go dark. {n 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. make out a coffin in front of you in the gloom.
{rSuddenly you hear a distinct 'click' and the ground abruptly |rSuddenly you hear a distinct 'click' and the ground abruptly
disappears under your feet! You fall ... things go dark. {n 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. make out a coffin in front of you in the gloom.
{rSuddenly you hear a distinct 'click' and the ground abruptly |rSuddenly you hear a distinct 'click' and the ground abruptly
disappears under your feet! You fall ... things go dark. {n 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. make out a coffin in front of you in the gloom.
{rSuddenly you hear a distinct 'click' and the ground abruptly |rSuddenly you hear a distinct 'click' and the ground abruptly
disappears under your feet! You fall ... things go dark. {n 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! rather than one in stone. This must be the hero's legendary weapon!
The prize you have been looking for! The prize you have been looking for!
(try {wget weapon{n) (try |wget weapon|n)
# #
@set sarcophagus/rack_id = rack_sarcophagus @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 Trembling you carefully release the weapon from the stone to test
its weight. You are finally holding your prize, its weight. You are finally holding your prize,
The {c%s{n The |c%s|n
in your hands! 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 continue to explore the castle (hint: this weapon works better
against the castle guardian than any you might have found earlier) or 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. # this room quits the tutorial and cleans up all variables that were set.
@desc @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 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 what can be done with Evennia. The tutorial focuses more on showing
various techniques than to supply any sort of novel storytelling or various techniques than to supply any sort of novel storytelling or
gaming challenge. The full README and source code for the tutorial 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 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 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 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 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 = @set here/tutorial_info =
This room cleans up all temporary attributes and tags that were put 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 from django.conf import settings
_SEARCH_AT_RESULT = utils.object_from_module(settings.SEARCH_AT_RESULT) _SEARCH_AT_RESULT = utils.object_from_module(settings.SEARCH_AT_RESULT)
#------------------------------------------------------------ # -------------------------------------------------------------
# #
# Tutorial room - parent room class # 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 # It defines a tutorial command on itself (available to
# all those who are in a tutorial room). # all those who are in a tutorial room).
# #
#------------------------------------------------------------ # -------------------------------------------------------------
# #
# Special command available in all tutorial rooms # Special command available in all tutorial rooms
#
class CmdTutorial(Command): class CmdTutorial(Command):
""" """
@ -62,16 +62,16 @@ class CmdTutorial(Command):
caller = self.caller caller = self.caller
if not self.args: 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: else:
target = caller.search(self.args.strip()) target = caller.search(self.args.strip())
if not target: if not target:
return return
helptext = target.db.tutorial_info helptext = target.db.tutorial_info
if helptext: if helptext:
caller.msg("{G%s{n" % helptext) caller.msg("|G%s|n" % helptext)
else: 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 # for the @detail command we inherit from MuxCommand, since
@ -204,7 +204,7 @@ class TutorialRoomCmdSet(CmdSet):
priority = 1 priority = 1
def at_cmdset_creation(self): def at_cmdset_creation(self):
"add the tutorial-room commands" """add the tutorial-room commands"""
self.add(CmdTutorial()) self.add(CmdTutorial())
self.add(CmdTutorialSetDetail()) self.add(CmdTutorialSetDetail())
self.add(CmdTutorialLook()) self.add(CmdTutorialLook())
@ -216,7 +216,7 @@ class TutorialRoom(DefaultRoom):
It defines a cmdset on itself for reading tutorial info about the location. It defines a cmdset on itself for reading tutorial info about the location.
""" """
def at_object_creation(self): 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.db.tutorial_info = "This is a tutorial room. It allows you to use the 'tutorial' command."
self.cmdset.add_default(TutorialRoomCmdSet) self.cmdset.add_default(TutorialRoomCmdSet)
@ -270,11 +270,11 @@ class TutorialRoom(DefaultRoom):
self.db.details = {detailkey.lower(): description} self.db.details = {detailkey.lower(): description}
#------------------------------------------------------------ # -------------------------------------------------------------
# #
# Weather room - room with a ticker # Weather room - room with a ticker
# #
#------------------------------------------------------------ # -------------------------------------------------------------
# These are rainy weather strings # These are rainy weather strings
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.", "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.") "Large clouds rush across the sky, throwing their load of rain over the world.")
class WeatherRoom(TutorialRoom): class WeatherRoom(TutorialRoom):
""" """
This should probably better be called a rainy room... This should probably better be called a rainy room...
@ -328,8 +329,7 @@ class WeatherRoom(TutorialRoom):
""" """
if random.random() < 0.2: if random.random() < 0.2:
# only update 20 % of the time # 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" \ 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" \ "the scenes later).\n" \
#----------------------------------------------------------- # ------------------------------------------------------------
# #
# Intro Room - unique room # Intro Room - unique room
# #
# This room marks the start of the tutorial. It sets up properties on # This room marks the start of the tutorial. It sets up properties on
# the player char that is needed for the tutorial. # the player char that is needed for the tutorial.
# #
#------------------------------------------------------------ # -------------------------------------------------------------
class IntroRoom(TutorialRoom): class IntroRoom(TutorialRoom):
""" """
@ -377,10 +378,10 @@ class IntroRoom(TutorialRoom):
if character.is_superuser: if character.is_superuser:
string = "-"*78 + SUPERUSER_WARNING + "-"*78 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 # Bridge - unique room
# #
@ -394,7 +395,7 @@ class IntroRoom(TutorialRoom):
# divided into five steps: # divided into five steps:
# westroom <- 0 1 2 3 4 -> eastroom # westroom <- 0 1 2 3 4 -> eastroom
# #
#------------------------------------------------------------ # -------------------------------------------------------------
class CmdEast(Command): class CmdEast(Command):
@ -419,7 +420,7 @@ class CmdEast(Command):
help_category = "TutorialWorld" help_category = "TutorialWorld"
def func(self): def func(self):
"move one step eastwards" """move one step eastwards"""
caller = self.caller caller = self.caller
bridge_step = min(5, caller.db.tutorial_bridge_position + 1) bridge_step = min(5, caller.db.tutorial_bridge_position + 1)
@ -463,7 +464,7 @@ class CmdWest(Command):
help_category = "TutorialWorld" help_category = "TutorialWorld"
def func(self): def func(self):
"move one step westwards" """move one step westwards"""
caller = self.caller caller = self.caller
bridge_step = max(-1, caller.db.tutorial_bridge_position - 1) bridge_step = max(-1, caller.db.tutorial_bridge_position - 1)
@ -484,25 +485,31 @@ class CmdWest(Command):
caller.execute_cmd("look") 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 ...", BRIDGE_POS_MESSAGES = ("You are standing |wvery close to the the bridge's western foundation|n."
"The bridge slopes precariously where it extends eastwards towards the lowest point - the center point of the hang bridge.", " If you go west you will be back on solid ground ...",
"You are {whalfways{n out on the unstable bridge.", "The bridge slopes precariously where it extends eastwards"
"The bridge slopes precariously where it extends westwards towards the lowest point - the center point of the hang bridge.", " 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 ...") "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.", 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.", "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.", "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.", "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!", "Parts of the bridge come loose behind you, falling into the chasm far below!",
"A gust of wind causes the bridge to sway precariously.", "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 ...", "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!" \ 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 " \ "\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 ... " \ "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): class CmdLookBridge(Command):
@ -520,20 +527,20 @@ class CmdLookBridge(Command):
help_category = "TutorialWorld" help_category = "TutorialWorld"
def func(self): def func(self):
"Looking around, including a chance to fall." """Looking around, including a chance to fall."""
caller = self.caller caller = self.caller
bridge_position = self.caller.db.tutorial_bridge_position bridge_position = self.caller.db.tutorial_bridge_position
# this command is defined on the room, so we get it through self.obj # this command is defined on the room, so we get it through self.obj
location = self.obj location = self.obj
# randomize the look-echo # 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], BRIDGE_POS_MESSAGES[bridge_position],
random.choice(BRIDGE_MOODS)) random.choice(BRIDGE_MOODS))
chars = [obj for obj in self.obj.contents_get(exclude=caller) if obj.has_player] chars = [obj for obj in self.obj.contents_get(exclude=caller) if obj.has_player]
if chars: if chars:
# we create the You see: message manually here # 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) self.caller.msg(message)
# there is a chance that we fall if we are on the western or central # 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. # we fall 5% of time.
fall_exit = search_object(self.obj.db.fall_exit) fall_exit = search_object(self.obj.db.fall_exit)
if 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) self.caller.move_to(fall_exit[0], quiet=True)
# inform others on the bridge # 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) "they fall from the bridge!" % self.caller.key)
@ -555,24 +562,25 @@ class CmdBridgeHelp(Command):
Overwritten help command while on the bridge. Overwritten help command while on the bridge.
""" """
key = "help" key = "help"
aliases = ["h"] aliases = ["h", "?"]
locks = "cmd:all()" locks = "cmd:all()"
help_category = "Tutorial world" help_category = "Tutorial world"
def func(self): def func(self):
"Implements the command." """Implements the command."""
string = "You are trying hard not to fall off the bridge ..." 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 " "\n\nWhat you can do is trying to cross the bridge |weast|n" \
string += "or try to get back to the mainland {wwest{n)." " or try to get back to the mainland |wwest|n)."
self.caller.msg(string) self.caller.msg(string)
class BridgeCmdSet(CmdSet): 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" 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): def at_cmdset_creation(self):
"Called at first cmdset creation" """Called at first cmdset creation"""
self.add(CmdTutorial()) self.add(CmdTutorial())
self.add(CmdEast()) self.add(CmdEast())
self.add(CmdWest()) self.add(CmdWest())
@ -618,7 +626,7 @@ class BridgeRoom(WeatherRoom):
""" """
def at_object_creation(self): def at_object_creation(self):
"Setups the room" """Setups the room"""
# this will start the weather room's ticker and tell # this will start the weather room's ticker and tell
# it to call update_weather regularly. # it to call update_weather regularly.
super(BridgeRoom, self).at_object_creation() super(BridgeRoom, self).at_object_creation()
@ -644,7 +652,7 @@ class BridgeRoom(WeatherRoom):
""" """
if random.random() < 80: if random.random() < 80:
# send a message most of the time # 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): def at_object_receive(self, character, source_location):
""" """
@ -658,7 +666,7 @@ class BridgeRoom(WeatherRoom):
eexit = search_object(self.db.east_exit) eexit = search_object(self.db.east_exit)
fexit = search_object(self.db.fall_exit) fexit = search_object(self.db.fall_exit)
if not (wexit and eexit and fexit): 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.") "Contact an admin. Forcing west-end placement.")
character.db.tutorial_bridge_position = 0 character.db.tutorial_bridge_position = 0
return return
@ -679,7 +687,7 @@ class BridgeRoom(WeatherRoom):
del character.db.tutorial_bridge_position del character.db.tutorial_bridge_position
#------------------------------------------------------------------------------ # -------------------------------------------------------------------------------
# #
# Dark Room - a room with states # Dark Room - a room with states
# #
@ -687,7 +695,7 @@ class BridgeRoom(WeatherRoom):
# LightSource object (LightSource is defined in # LightSource object (LightSource is defined in
# tutorialworld.objects.LightSource) # tutorialworld.objects.LightSource)
# #
#------------------------------------------------------------------------------ # -------------------------------------------------------------------------------
DARK_MESSAGES = ("It is pitch black. You are likely to be eaten by a grue.", 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. 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.", "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.", "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 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.") "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 " \ ALREADY_LIGHTSOURCE = "You don't want to stumble around in blindness anymore. You already " \
"found what you need. Let's get light 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! " \ FOUND_LIGHTSOURCE = "Your fingers bump against a splinter of wood in a corner." \
"You pick it up, holding it firmly. Now you just need to {wlight{n it using the flint and steel you carry with you." " 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): class CmdLookDark(Command):
@ -774,7 +786,7 @@ class CmdDarkNoMatch(Command):
locks = "cmd:all()" locks = "cmd:all()"
def func(self): 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.") 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 priority = 2
def at_cmdset_creation(self): def at_cmdset_creation(self):
"populate the cmdset." """populate the cmdset."""
self.add(CmdTutorial()) self.add(CmdTutorial())
self.add(CmdLookDark()) self.add(CmdLookDark())
self.add(CmdDarkHelp()) self.add(CmdDarkHelp())
@ -901,7 +913,7 @@ class DarkRoom(TutorialRoom):
self.check_light_state(exclude=obj) self.check_light_state(exclude=obj)
#------------------------------------------------------------ # -------------------------------------------------------------
# #
# Teleport room - puzzles solution # Teleport room - puzzles solution
# #
@ -914,7 +926,7 @@ class DarkRoom(TutorialRoom):
# oneself, and then pick the grave chamber with the # oneself, and then pick the grave chamber with the
# matching imagery for this attribute. # matching imagery for this attribute.
# #
#------------------------------------------------------------ # -------------------------------------------------------------
class TeleportRoom(TutorialRoom): class TeleportRoom(TutorialRoom):
@ -931,7 +943,7 @@ class TeleportRoom(TutorialRoom):
""" """
def at_object_creation(self): def at_object_creation(self):
"Called at first creation" """Called at first creation"""
super(TeleportRoom, self).at_object_creation() super(TeleportRoom, self).at_object_creation()
# what character.db.puzzle_clue must be set to, to avoid teleportation. # what character.db.puzzle_clue must be set to, to avoid teleportation.
self.db.puzzle_value = 1 self.db.puzzle_value = 1
@ -977,13 +989,13 @@ class TeleportRoom(TutorialRoom):
results[0].at_object_receive(character, self) results[0].at_object_receive(character, self)
#------------------------------------------------------------ # -------------------------------------------------------------
# #
# Outro room - unique exit room # Outro room - unique exit room
# #
# Cleans up the character from all tutorial-related properties. # Cleans up the character from all tutorial-related properties.
# #
#------------------------------------------------------------ # -------------------------------------------------------------
class OutroRoom(TutorialRoom): class OutroRoom(TutorialRoom):
""" """