diff --git a/game/gamesrc/objects/examples/exit.py b/game/gamesrc/objects/examples/exit.py index 346441316c..888fe426c1 100644 --- a/game/gamesrc/objects/examples/exit.py +++ b/game/gamesrc/objects/examples/exit.py @@ -26,10 +26,11 @@ class Exit(DefaultExit): following methods: basetype_setup() - sets default exit locks (to change, use at_object_creation instead) - at_cmdset_get() - this auto-creates and caches a command and a command set on itself - with the same name as the Exit object. This - allows users to use the exit by only giving its - name alone on the command line. + at_cmdset_get(**kwargs) - this is called when the cmdset is accessed and should + rebuild the Exit cmdset along with a command matching the name + of the Exit object. Conventionally, a kwarg 'force_init' + should force a rebuild of the cmdset, this is triggered + by the @alias command when aliases are changed. at_failed_traverse() - gives a default error message ("You cannot go there") if exit traversal fails and an attribute err_traverse is not defined. diff --git a/game/gamesrc/objects/examples/object.py b/game/gamesrc/objects/examples/object.py index 2cc5a0f7eb..57dbc7024a 100644 --- a/game/gamesrc/objects/examples/object.py +++ b/game/gamesrc/objects/examples/object.py @@ -109,8 +109,10 @@ class Object(DefaultObject): at_init() - called whenever typeclass is cached from memory, at least once every server restart/reload - at_cmdset_get() - this is called just before the command handler - requests a cmdset from this object + at_cmdset_get(**kwargs) - this is called just before the command handler + requests a cmdset from this object. The kwargs are + not normally used unless the cmdset is created + dynamically (see e.g. Exits). at_pre_puppet(player)- (player-controlled objects only) called just before puppeting at_post_puppet() - (player-controlled objects only) called just diff --git a/game/gamesrc/objects/examples/player.py b/game/gamesrc/objects/examples/player.py index 5e587e035f..339e0994ef 100644 --- a/game/gamesrc/objects/examples/player.py +++ b/game/gamesrc/objects/examples/player.py @@ -78,7 +78,7 @@ class Player(DefaultPlayer): usually handled on the character level: at_init() - at_cmdset_get() + at_cmdset_get(**kwargs) at_first_login() at_post_login(sessid=None) at_disconnect() diff --git a/src/commands/default/building.py b/src/commands/default/building.py index ef1991e16b..075f631f0c 100644 --- a/src/commands/default/building.py +++ b/src/commands/default/building.py @@ -159,13 +159,20 @@ class CmdSetObjAlias(MuxCommand): old_aliases = obj.aliases.all() new_aliases = [alias.strip().lower() for alias in self.rhs.split(',') if alias.strip()] + # make the aliases only appear once old_aliases.extend(new_aliases) aliases = list(set(old_aliases)) + # save back to object. obj.aliases.add(aliases) - # we treat this as a re-caching (relevant for exits to re-build their - # exit commands with the correct aliases) + + # we need to trigger this here, since this will force + # (default) Exits to rebuild their Exit commands with the new + # aliases + obj.at_cmdset_get(force_init=True) + + # report all aliases on the object caller.msg("Alias(es) for '%s' set to %s." % (obj.key, str(obj.aliases))) diff --git a/src/objects/objects.py b/src/objects/objects.py index 7b48ec9c21..5fa5ef5d12 100644 --- a/src/objects/objects.py +++ b/src/objects/objects.py @@ -129,8 +129,9 @@ class Object(TypeClass): at_init() called whenever typeclass is cached from memory, at least once every server restart/reload - at_cmdset_get() - this is called just before the command - handler requests a cmdset from this objecth + at_cmdset_get(**kwargs) - this is called just before the command + handler requests a cmdset from this object, usually + without any kwargs at_pre_puppet(player)- (player-controlled objects only) called just before puppeting at_post_puppet() - (player-controlled objects only) called just @@ -576,12 +577,15 @@ class Object(TypeClass): pass - def at_cmdset_get(self): + def at_cmdset_get(self, **kwargs): """ Called just before cmdsets on this object are requested by the - command handler. If changes need to be done on the fly to the cmdset - before passing them on to the cmdhandler, this is the place to do it. - This is called also if the object currently have no cmdsets. + command handler. If changes need to be done on the fly to the + cmdset before passing them on to the cmdhandler, this is the + place to do it. This is called also if the object currently + have no cmdsets. **kwargs are usually not set but could be + used e.g. to force rebuilding of a dynamically created cmdset + or similar. """ pass @@ -1080,17 +1084,19 @@ class Exit(Object): if self.dbobj.location: self.destination = self.dbobj.location - def at_cmdset_get(self): + def at_cmdset_get(self, **kwargs): """ Called when the cmdset is requested from this object, just before the cmdset is actually extracted. If no Exit-cmdset is cached, create it now. + + kwargs: + force_init=True - force a re-build of the cmdset (for example to update aliases) """ - if self.ndb.exit_reset or not self.cmdset.has_cmdset("_exitset", must_be_default=True): + if "force_init" in kwargs or not self.cmdset.has_cmdset("_exitset", must_be_default=True): # we are resetting, or no exit-cmdset was set. Create one dynamically. self.cmdset.add_default(self.create_exit_cmdset(self.dbobj), permanent=False) - del self.ndb.exit_reset # this and other hooks are what usually can be modified safely. diff --git a/src/players/player.py b/src/players/player.py index 142f8187fb..4ce3c37be5 100644 --- a/src/players/player.py +++ b/src/players/player.py @@ -91,7 +91,7 @@ class Player(TypeClass): at_init() at_access() - at_cmdset_get() + at_cmdset_get(**kwargs) at_first_login() at_post_login(sessid=None) at_disconnect() @@ -315,12 +315,14 @@ class Player(TypeClass): """ pass - def at_cmdset_get(self): + def at_cmdset_get(self, **kwargs): """ Called just before cmdsets on this player are requested by the - command handler. If changes need to be done on the fly to the cmdset - before passing them on to the cmdhandler, this is the place to do it. - This is called also if the player currently have no cmdsets. + command handler. If changes need to be done on the fly to the + cmdset before passing them on to the cmdhandler, this is the + place to do it. This is called also if the player currently + have no cmdsets. kwargs are usually not used unless the + cmdset is generated dynamically. """ pass diff --git a/src/server/serversession.py b/src/server/serversession.py index 5e4132cdea..094098176b 100644 --- a/src/server/serversession.py +++ b/src/server/serversession.py @@ -280,7 +280,7 @@ class ServerSession(Session): # Dummy API hooks for use during non-loggedin operation - def at_cmdset_get(self): + def at_cmdset_get(self, **kwargs): "dummy hook all objects with cmdsets need to have" pass diff --git a/src/tests/test_objects_objects.py b/src/tests/test_objects_objects.py index 06a7a4917a..a09aa9eb52 100644 --- a/src/tests/test_objects_objects.py +++ b/src/tests/test_objects_objects.py @@ -62,7 +62,7 @@ class TestObject(unittest.TestCase): def test_at_cmdset_get(self): # object = Object(dbobj) - # self.assertEqual(expected, object.at_cmdset_get()) + # self.assertEqual(expected, object.at_cmdset_get(**kwargs)) assert True # TODO: implement your test here def test_at_desc(self): @@ -270,7 +270,7 @@ class TestExit(unittest.TestCase): def test_at_cmdset_get(self): # exit = Exit() - # self.assertEqual(expected, exit.at_cmdset_get()) + # self.assertEqual(expected, exit.at_cmdset_get(**kwargs)) assert True # TODO: implement your test here def test_at_failed_traverse(self): diff --git a/src/tests/test_server_serversession.py b/src/tests/test_server_serversession.py index 8696886f35..b5526b3a32 100644 --- a/src/tests/test_server_serversession.py +++ b/src/tests/test_server_serversession.py @@ -27,7 +27,7 @@ class TestServerSession(unittest.TestCase): def test_at_cmdset_get(self): # server_session = ServerSession() - # self.assertEqual(expected, server_session.at_cmdset_get()) + # self.assertEqual(expected, server_session.at_cmdset_get(**kwargs)) assert True # TODO: implement your test here def test_at_disconnect(self):