From dc0ef5812b06749384eec0847df3805e858d337d Mon Sep 17 00:00:00 2001 From: Griatch Date: Wed, 6 Mar 2019 16:47:09 +0100 Subject: [PATCH 1/6] Fix aliases for gender command --- evennia/contrib/gendersub.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evennia/contrib/gendersub.py b/evennia/contrib/gendersub.py index 205f9a991d..0c43ee572c 100644 --- a/evennia/contrib/gendersub.py +++ b/evennia/contrib/gendersub.py @@ -64,7 +64,7 @@ class SetGender(Command): """ key = "@gender" - alias = "@sex" + aliases = "@sex" locks = "call:all()" def func(self): From 26258a13ff7f08649a4b61fec15c3861cf713810 Mon Sep 17 00:00:00 2001 From: David Reichard Date: Sun, 10 Mar 2019 15:58:39 -0400 Subject: [PATCH 2/6] Fix lockcmd bug not ignoring superuser when using switches. Resolves #1796. --- evennia/commands/default/building.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evennia/commands/default/building.py b/evennia/commands/default/building.py index 53b710d97c..04e432540a 100644 --- a/evennia/commands/default/building.py +++ b/evennia/commands/default/building.py @@ -1972,7 +1972,7 @@ class CmdLock(ObjManipCommand): caller.msg("You need 'control' access to change this type of lock.") return - if not has_control_access or obj.access(caller, "edit"): + if not (has_control_access or obj.access(caller, "edit")): caller.msg("You are not allowed to do that.") return From c4abddf707bdbf54f5c90563a53d56ade1cb8cde Mon Sep 17 00:00:00 2001 From: Vincent Le Goff Date: Wed, 13 Mar 2019 11:34:43 +0100 Subject: [PATCH 3/6] Fix #1577 --- evennia/contrib/extended_room.py | 239 +++++++++++++++++++------------ evennia/contrib/tests.py | 28 ++-- 2 files changed, 165 insertions(+), 102 deletions(-) diff --git a/evennia/contrib/extended_room.py b/evennia/contrib/extended_room.py index 6cacca980c..72048cc41b 100644 --- a/evennia/contrib/extended_room.py +++ b/evennia/contrib/extended_room.py @@ -45,13 +45,14 @@ at, without there having to be a database object created for it. The Details are simply stored in a dictionary on the room and if the look command cannot find an object match for a `look ` command it will also look through the available details at the current location -if applicable. An extended `desc` command is used to set details. +if applicable. The `@detail` command is used to change details. 4) Extra commands CmdExtendedLook - look command supporting room details - CmdExtendedDesc - desc command allowing to add seasonal descs and details, + CmdExtendedDesc - desc command allowing to add seasonal descs, + CmdSetDetail - command allowing to manipulate details in this room as well as listing them CmdGameTime - A simple `time` command, displaying the current time and season. @@ -59,7 +60,7 @@ if applicable. An extended `desc` command is used to set details. Installation/testing: -1) Add `CmdExtendedLook`, `CmdExtendedDesc` and `CmdGameTime` to the default `cmdset` +1) Add `CmdExtendedLook`, `CmdExtendedDesc`, `CmdDetail` and `CmdGameTime` to the default `cmdset` (see Wiki for how to do this). 2) `@dig` a room of type `contrib.extended_room.ExtendedRoom` (or make it the default room type) @@ -213,6 +214,42 @@ class ExtendedRoom(DefaultRoom): return detail return None + def set_detail(self, detailkey, description): + """ + This sets a new detail, using an Attribute "details". + + Args: + detailkey (str): The detail identifier to add (for + aliases you need to add multiple keys to the + same description). Case-insensitive. + description (str): The text to return when looking + at the given detailkey. + + """ + if self.db.details: + self.db.details[detailkey.lower()] = description + else: + self.db.details = {detailkey.lower(): description} + + def del_detail(self, detailkey, description): + """ + Delete a detail. + + The description is ignored. + + Args: + detailkey (str): the detail to remove (case-insensitive). + description (str, ignored): the description. + + The description is only included for compliance but is completely + ignored. Note that this method doesn't raise any exception if + the detail doesn't exist in this room. + + """ + if self.db.details and detailkey.lower() in self.db.details: + del self.db.details[detailkey.lower()] + + def return_appearance(self, looker, **kwargs): """ This is called when e.g. the look command wants to retrieve @@ -335,8 +372,6 @@ class CmdExtendedDesc(default_cmds.CmdDesc): Usage: desc[/switch] [ =] - detail[/del] [ = ] - Switches for `desc`: spring - set description for in current room. @@ -344,15 +379,9 @@ class CmdExtendedDesc(default_cmds.CmdDesc): autumn winter - Switch for `detail`: - del - delete a named detail. - Sets the "desc" attribute on an object. If an object is not given, describe the current room. - The alias `detail` allows to assign a "detail" (a non-object - target for the `look` command) to the current room (only). - You can also embed special time markers in your room description, like this: ``` @@ -362,11 +391,11 @@ class CmdExtendedDesc(default_cmds.CmdDesc): Text marked this way will only display when the server is truly at the given timeslot. The available times are night, morning, afternoon and evening. - Note that `detail`, seasons and time-of-day slots only work on rooms in this + Note that seasons and time-of-day slots only work on rooms in this version of the `desc` command. """ - aliases = ["describe", "detail"] + aliases = ["describe"] switch_options = () # Inherits from default_cmds.CmdDesc, but unused here def reset_times(self, obj): @@ -378,92 +407,116 @@ class CmdExtendedDesc(default_cmds.CmdDesc): """Define extended command""" caller = self.caller location = caller.location - if self.cmdname == 'detail': - # switch to detailing mode. This operates only on current location + if not self.args: + if location: + string = "|wDescriptions on %s|n:\n" % location.key + string += " |wspring:|n %s\n" % location.db.spring_desc + string += " |wsummer:|n %s\n" % location.db.summer_desc + string += " |wautumn:|n %s\n" % location.db.autumn_desc + string += " |wwinter:|n %s\n" % location.db.winter_desc + string += " |wgeneral:|n %s" % location.db.general_desc + caller.msg(string) + return + if self.switches and self.switches[0] in ("spring", "summer", "autumn", "winter"): + # a seasonal switch was given + if self.rhs: + caller.msg("Seasonal descs only work with rooms, not objects.") + return + switch = self.switches[0] if not location: - caller.msg("No location to detail!") + caller.msg("No location was found!") return - if location.db.details is None: - caller.msg("|rThis location does not support details.|n") - return - if self.switches and self.switches[0] in 'del': - # removing a detail. - if self.lhs in location.db.details: - del location.db.details[self.lhs] - caller.msg("Detail %s deleted, if it existed." % self.lhs) - self.reset_times(location) - return - if not self.args: - # No args given. Return all details on location - string = "|wDetails on %s|n:" % location - details = "\n".join(" |w%s|n: %s" - % (key, utils.crop(text)) for key, text in location.db.details.items()) - caller.msg("%s\n%s" % (string, details) if details else "%s None." % string) - return - if not self.rhs: - # no '=' used - list content of given detail - if self.args in location.db.details: - string = "|wDetail '%s' on %s:\n|n" % (self.args, location) - string += str(location.db.details[self.args]) - caller.msg(string) - else: - caller.msg("Detail '%s' not found." % self.args) - return - # setting a detail - location.db.details[self.lhs] = self.rhs - caller.msg("Set Detail %s to '%s'." % (self.lhs, self.rhs)) + if switch == 'spring': + location.db.spring_desc = self.args + elif switch == 'summer': + location.db.summer_desc = self.args + elif switch == 'autumn': + location.db.autumn_desc = self.args + elif switch == 'winter': + location.db.winter_desc = self.args + # clear flag to force an update self.reset_times(location) - return + caller.msg("Seasonal description was set on %s." % location.key) else: - # we are doing a desc call - if not self.args: - if location: - string = "|wDescriptions on %s|n:\n" % location.key - string += " |wspring:|n %s\n" % location.db.spring_desc - string += " |wsummer:|n %s\n" % location.db.summer_desc - string += " |wautumn:|n %s\n" % location.db.autumn_desc - string += " |wwinter:|n %s\n" % location.db.winter_desc - string += " |wgeneral:|n %s" % location.db.general_desc - caller.msg(string) + # No seasonal desc set, maybe this is not an extended room + if self.rhs: + text = self.rhs + obj = caller.search(self.lhs) + if not obj: return - if self.switches and self.switches[0] in ("spring", "summer", "autumn", "winter"): - # a seasonal switch was given - if self.rhs: - caller.msg("Seasonal descs only work with rooms, not objects.") - return - switch = self.switches[0] - if not location: - caller.msg("No location was found!") - return - if switch == 'spring': - location.db.spring_desc = self.args - elif switch == 'summer': - location.db.summer_desc = self.args - elif switch == 'autumn': - location.db.autumn_desc = self.args - elif switch == 'winter': - location.db.winter_desc = self.args - # clear flag to force an update - self.reset_times(location) - caller.msg("Seasonal description was set on %s." % location.key) else: - # No seasonal desc set, maybe this is not an extended room - if self.rhs: - text = self.rhs - obj = caller.search(self.lhs) - if not obj: - return - else: - text = self.args - obj = location - obj.db.desc = text # a compatibility fallback - if obj.attributes.has("general_desc"): - obj.db.general_desc = text - self.reset_times(obj) - caller.msg("General description was set on %s." % obj.key) - else: - # this is not an ExtendedRoom. - caller.msg("The description was set on %s." % obj.key) + text = self.args + obj = location + obj.db.desc = text # a compatibility fallback + if obj.attributes.has("general_desc"): + obj.db.general_desc = text + self.reset_times(obj) + caller.msg("General description was set on %s." % obj.key) + else: + # this is not an ExtendedRoom. + caller.msg("The description was set on %s." % obj.key) + + +class CmdSetDetail(default_cmds.MuxCommand): + + """ + sets a detail on a room + + Usage: + @detail[/del] [= ] + @detail ;;... = description + + Example: + @detail + @detail walls = The walls are covered in ... + @detail castle;ruin;tower = The distant ruin ... + @detail/del wall + @detail/del castle;ruin;tower + + This command allows to show the current room details if you enter it + without any argument. Otherwise, sets or deletes a detail on the current + room, if this room supports details like an extended room. To add new + detail, just use the @detail command, specifying the key, an equal sign + and the description. You can assign the same description to several + details using the alias syntax (replace key by alias1;alias2;alias3;...). + To remove one or several details, use the @detail/del switch. + + """ + key = "@detail" + locks = "cmd:perm(Builder)" + help_category = "Building" + + def func(self): + location = self.caller.location + if not self.args: + details = location.db.details + if not details: + self.msg("|rThe room {} doesn't have any detail set.|n".format(location)) + else: + details = sorted(["|y{}|n: {}".format(key, desc) for key, desc in details.items()]) + self.msg("Details on Room:\n" + "\n".join(details)) + return + + if not self.rhs and "del" not in self.switches: + detail = location.return_detail(self.lhs) + if detail: + self.msg("Detail '|y{}|n' on Room:\n{}".format(self.lhs, detail)) + else: + self.msg("Detail '{}' not found.".format(self.lhs)) + return + + method = "set_detail" if "del" not in self.switches else "del_detail" + if not hasattr(location, method): + self.caller.msg("Details cannot be set on %s." % location) + return + for key in self.lhs.split(";"): + # loop over all aliases, if any (if not, this will just be + # the one key to loop over) + getattr(location, method)(key, self.rhs) + if "del" in self.switches: + self.caller.msg("Detail %s deleted, if it existed." % self.lhs) + else: + self.caller.msg("Detail set '%s': '%s'" % (self.lhs, self.rhs)) # Simple command to view the current time and season diff --git a/evennia/contrib/tests.py b/evennia/contrib/tests.py index 1086c8776e..152c29def7 100644 --- a/evennia/contrib/tests.py +++ b/evennia/contrib/tests.py @@ -242,14 +242,24 @@ class TestExtendedRoom(CommandTest): self.call(extended_room.CmdExtendedLook(), "testdetail", self.DETAIL_DESC) self.call(extended_room.CmdExtendedLook(), "nonexistent", "Could not find 'nonexistent'.") - def test_cmdextendeddesc(self): - self.call(extended_room.CmdExtendedDesc(), "", "Details on Room", cmdstring="detail") - self.call(extended_room.CmdExtendedDesc(), "thingie = newdetail with spaces", - "Set Detail thingie to 'newdetail with spaces'.", cmdstring="detail") - self.call(extended_room.CmdExtendedDesc(), "thingie", "Detail 'thingie' on Room:\n", cmdstring="detail") - self.call(extended_room.CmdExtendedDesc(), "/del thingie", "Detail thingie deleted, if it existed.", cmdstring="detail") - self.call(extended_room.CmdExtendedDesc(), "thingie", "Detail 'thingie' not found.", cmdstring="detail") - self.call(extended_room.CmdExtendedDesc(), "", "Descriptions on Room:") + def test_cmdsetdetail(self): + self.call(extended_room.CmdSetDetail(), "", "Details on Room") + self.call(extended_room.CmdSetDetail(), "thingie = newdetail with spaces", + "Detail set 'thingie': 'newdetail with spaces'") + self.call(extended_room.CmdSetDetail(), "thingie", "Detail 'thingie' on Room:\n") + self.call(extended_room.CmdSetDetail(), "/del thingie", "Detail thingie deleted, if it existed.", cmdstring="detail") + self.call(extended_room.CmdSetDetail(), "thingie", "Detail 'thingie' not found.") + + # Test with aliases + self.call(extended_room.CmdSetDetail(), "", "Details on Room") + self.call(extended_room.CmdSetDetail(), "thingie;other;stuff = newdetail with spaces", + "Detail set 'thingie;other;stuff': 'newdetail with spaces'") + self.call(extended_room.CmdSetDetail(), "thingie", "Detail 'thingie' on Room:\n") + self.call(extended_room.CmdSetDetail(), "other", "Detail 'other' on Room:\n") + self.call(extended_room.CmdSetDetail(), "stuff", "Detail 'stuff' on Room:\n") + self.call(extended_room.CmdSetDetail(), "/del other;stuff", "Detail other;stuff deleted, if it existed.") + self.call(extended_room.CmdSetDetail(), "other", "Detail 'other' not found.") + self.call(extended_room.CmdSetDetail(), "stuff", "Detail 'stuff' not found.") def test_cmdgametime(self): self.call(extended_room.CmdGameTime(), "", "It's a spring day, in the evening.") @@ -1596,7 +1606,7 @@ class TestFieldFillFunc(EvenniaTest): def test_field_functions(self): self.assertTrue(fieldfill.form_template_to_dict(FIELD_TEST_TEMPLATE) == FIELD_TEST_DATA) - + # Test of the unixcommand module from evennia.contrib.unixcommand import UnixCommand From 5bde7a5ac100356b7ce21f25f0a146fe72aa1713 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 17 Mar 2019 13:36:03 +0100 Subject: [PATCH 4/6] Some fixes and cleanups --- CHANGELOG.md | 9 +++++ evennia/contrib/extended_room.py | 60 ++++++++++++++++++++++++-------- 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b56c29d85..724e0db578 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -111,6 +111,15 @@ - `tb_items` - Extends `tb_equip` with item use with conditions/status effects. - `tb_magic` - Extends `tb_equip` with spellcasting. - `tb_range` - Adds system for abstract positioning and movement. + - The `extended_room` contrib saw some backwards-incompatible refactoring: + - All commands now begin with `CmdExtendedRoom`. So before it was `CmdExtendedLook`, now + it's `CmdExtendedRoomLook` etc. + - The `detail` command was broken out of the `desc` command and is now a new, stand-alone command + `CmdExtendedRoomDetail`. This was done to make things easier to extend and to mimic how the detail + command works in the tutorial-world. + - The `detail` command now also supports deleting details (like the tutorial-world version). + - The new `ExtendedRoomCmdSet` includes all the extended-room commands and is now the recommended way + to install the extended-room contrib. - Updates and some cleanup of existing contribs. # Overviews diff --git a/evennia/contrib/extended_room.py b/evennia/contrib/extended_room.py index 72048cc41b..3db4a6f1d6 100644 --- a/evennia/contrib/extended_room.py +++ b/evennia/contrib/extended_room.py @@ -1,7 +1,7 @@ """ Extended Room -Evennia Contribution - Griatch 2012 +Evennia Contribution - Griatch 2012, vincent-lg 2019 This is an extended Room typeclass for Evennia. It is supported by an extended `Look` command and an extended `desc` command, also @@ -50,21 +50,36 @@ if applicable. The `@detail` command is used to change details. 4) Extra commands - CmdExtendedLook - look command supporting room details - CmdExtendedDesc - desc command allowing to add seasonal descs, - CmdSetDetail - command allowing to manipulate details in this room + CmdExtendedRoomLook - look command supporting room details + CmdExtendedRoomDesc - desc command allowing to add seasonal descs, + CmdExtendedRoomDetail - command allowing to manipulate details in this room as well as listing them - CmdGameTime - A simple `time` command, displaying the current + CmdExtendedRoomGameTime - A simple `time` command, displaying the current time and season. Installation/testing: -1) Add `CmdExtendedLook`, `CmdExtendedDesc`, `CmdDetail` and `CmdGameTime` to the default `cmdset` - (see Wiki for how to do this). -2) `@dig` a room of type `contrib.extended_room.ExtendedRoom` (or make it the - default room type) -3) Use `desc` and `detail` to customize the room, then play around! +Adding the `ExtendedRoomCmdset` to the default character cmdset will add all +new commands for use. + +In more detail, in mygame/commands/default_cmdsets.py: + +``` +... +from evennia.contrib import extended_room # <-new + +class CharacterCmdset(default_cmds.Character_CmdSet): + ... + def at_cmdset_creation(self): + ... + self.add(extended_room.ExtendedRoomCmdSet) # <-new + +``` + +Then reload to make the bew commands available. Note that they only work +on rooms with the typeclass `ExtendedRoom`. Create new rooms with the right +typeclass or use the `typeclass` command to swap existing rooms. """ from __future__ import division @@ -76,6 +91,7 @@ from evennia import DefaultRoom from evennia import gametime from evennia import default_cmds from evennia import utils +from evennia import CmdSet # error return function, needed by Extended Look command _AT_SEARCH_RESULT = utils.variable_from_module(*settings.SEARCH_AT_RESULT.rsplit('.', 1)) @@ -305,7 +321,7 @@ class ExtendedRoom(DefaultRoom): # Custom Look command supporting Room details. Add this to # the Default cmdset to use. -class CmdExtendedLook(default_cmds.CmdLook): +class CmdExtendedRoomLook(default_cmds.CmdLook): """ look @@ -366,7 +382,7 @@ class CmdExtendedLook(default_cmds.CmdLook): # Custom build commands for setting seasonal descriptions # and detailing extended rooms. -class CmdExtendedDesc(default_cmds.CmdDesc): +class CmdExtendedRoomDesc(default_cmds.CmdDesc): """ `desc` - describe an object or room. @@ -457,7 +473,7 @@ class CmdExtendedDesc(default_cmds.CmdDesc): caller.msg("The description was set on %s." % obj.key) -class CmdSetDetail(default_cmds.MuxCommand): +class CmdExtendedRoomDetail(default_cmds.MuxCommand): """ sets a detail on a room @@ -505,7 +521,7 @@ class CmdSetDetail(default_cmds.MuxCommand): self.msg("Detail '{}' not found.".format(self.lhs)) return - method = "set_detail" if "del" not in self.switches else "del_detail" + method = "set_detail" if "del" not in self.switches else "del_detail" if not hasattr(location, method): self.caller.msg("Details cannot be set on %s." % location) return @@ -521,7 +537,7 @@ class CmdSetDetail(default_cmds.MuxCommand): # Simple command to view the current time and season -class CmdGameTime(default_cmds.MuxCommand): +class CmdExtendedRoomGameTime(default_cmds.MuxCommand): """ Check the game time @@ -545,3 +561,17 @@ class CmdGameTime(default_cmds.MuxCommand): if season == "autumn": prep = "an" self.caller.msg("It's %s %s day, in the %s." % (prep, season, timeslot)) + + +# CmdSet for easily install all commands + +class ExtendedRoomCmdSet(CmdSet): + """ + Groups the extended-room commands. + + """ + def at_cmdset_creation(self): + self.add(CmdExtendedRoomLook) + self.add(CmdExtendedRoomDesc) + self.add(CmdExtendedRoomDetail) + self.add(CmdExtendedRoomGameTime) From 86bcc8b37b4115620802b7dea5e63d974c78fb6a Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 17 Mar 2019 13:38:31 +0100 Subject: [PATCH 5/6] Update CHANGELOG --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48b7087cc9..0b9e907def 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -90,6 +90,19 @@ Web/Django standard initiative (@strikaco) - Added many more unit tests. +### Contribs +- The `extended_room` contrib saw some backwards-incompatible refactoring: + + All commands now begin with `CmdExtendedRoom`. So before it was `CmdExtendedLook`, now + it's `CmdExtendedRoomLook` etc. + + The `detail` command was broken out of the `desc` command and is now a new, stand-alone command + `CmdExtendedRoomDetail`. This was done to make things easier to extend and to mimic how the detail + command works in the tutorial-world. + + The `detail` command now also supports deleting details (like the tutorial-world version). + + The new `ExtendedRoomCmdSet` includes all the extended-room commands and is now the recommended way + to install the extended-room contrib. + + + ## Evennia 0.8 (2018) ### Requirements From 477963ba28ee2ca89b47d4d5e27e972291372de2 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 17 Mar 2019 13:52:46 +0100 Subject: [PATCH 6/6] Update contrib unit tests --- evennia/contrib/tests.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/evennia/contrib/tests.py b/evennia/contrib/tests.py index 987d42c4e1..12119ae892 100644 --- a/evennia/contrib/tests.py +++ b/evennia/contrib/tests.py @@ -238,31 +238,31 @@ class TestExtendedRoom(CommandTest): self.assertEqual(self.DETAIL_DESC, self.room1.return_detail("testdetail")) def test_cmdextendedlook(self): - self.call(extended_room.CmdExtendedLook(), "here", "Room(#1)\n%s" % self.SPRING_DESC) - self.call(extended_room.CmdExtendedLook(), "testdetail", self.DETAIL_DESC) - self.call(extended_room.CmdExtendedLook(), "nonexistent", "Could not find 'nonexistent'.") + self.call(extended_room.CmdExtendedRoomLook(), "here", "Room(#1)\n%s" % self.SPRING_DESC) + self.call(extended_room.CmdExtendedRoomLook(), "testdetail", self.DETAIL_DESC) + self.call(extended_room.CmdExtendedRoomLook(), "nonexistent", "Could not find 'nonexistent'.") def test_cmdsetdetail(self): - self.call(extended_room.CmdSetDetail(), "", "Details on Room") - self.call(extended_room.CmdSetDetail(), "thingie = newdetail with spaces", + self.call(extended_room.CmdExtendedRoomDetail(), "", "Details on Room") + self.call(extended_room.CmdExtendedRoomDetail(), "thingie = newdetail with spaces", "Detail set 'thingie': 'newdetail with spaces'") - self.call(extended_room.CmdSetDetail(), "thingie", "Detail 'thingie' on Room:\n") - self.call(extended_room.CmdSetDetail(), "/del thingie", "Detail thingie deleted, if it existed.", cmdstring="detail") - self.call(extended_room.CmdSetDetail(), "thingie", "Detail 'thingie' not found.") + self.call(extended_room.CmdExtendedRoomDetail(), "thingie", "Detail 'thingie' on Room:\n") + self.call(extended_room.CmdExtendedRoomDetail(), "/del thingie", "Detail thingie deleted, if it existed.", cmdstring="detail") + self.call(extended_room.CmdExtendedRoomDetail(), "thingie", "Detail 'thingie' not found.") # Test with aliases - self.call(extended_room.CmdSetDetail(), "", "Details on Room") - self.call(extended_room.CmdSetDetail(), "thingie;other;stuff = newdetail with spaces", + self.call(extended_room.CmdExtendedRoomDetail(), "", "Details on Room") + self.call(extended_room.CmdExtendedRoomDetail(), "thingie;other;stuff = newdetail with spaces", "Detail set 'thingie;other;stuff': 'newdetail with spaces'") - self.call(extended_room.CmdSetDetail(), "thingie", "Detail 'thingie' on Room:\n") - self.call(extended_room.CmdSetDetail(), "other", "Detail 'other' on Room:\n") - self.call(extended_room.CmdSetDetail(), "stuff", "Detail 'stuff' on Room:\n") - self.call(extended_room.CmdSetDetail(), "/del other;stuff", "Detail other;stuff deleted, if it existed.") - self.call(extended_room.CmdSetDetail(), "other", "Detail 'other' not found.") - self.call(extended_room.CmdSetDetail(), "stuff", "Detail 'stuff' not found.") + self.call(extended_room.CmdExtendedRoomDetail(), "thingie", "Detail 'thingie' on Room:\n") + self.call(extended_room.CmdExtendedRoomDetail(), "other", "Detail 'other' on Room:\n") + self.call(extended_room.CmdExtendedRoomDetail(), "stuff", "Detail 'stuff' on Room:\n") + self.call(extended_room.CmdExtendedRoomDetail(), "/del other;stuff", "Detail other;stuff deleted, if it existed.") + self.call(extended_room.CmdExtendedRoomDetail(), "other", "Detail 'other' not found.") + self.call(extended_room.CmdExtendedRoomDetail(), "stuff", "Detail 'stuff' not found.") def test_cmdgametime(self): - self.call(extended_room.CmdGameTime(), "", "It's a spring day, in the evening.") + self.call(extended_room.CmdExtendedRoomGameTime(), "", "It's a spring day, in the evening.") # Test the contrib barter system