This paper will look at the com.sun.sgs.darkmud.locked package. It supplies
support for keys that can be used to unlock or lock doors that are lockable.
The following are classes that were added to support keys and lockable
As shown above and explained in Exercise 3 of the JavaOne 7400darkstar
Lab, everything in the game is based on the MudObject class that implement
the ManagedObject interface and is Serializable. This allows all game objects
to be managed by the PDS server database services to give the objects persistence.
NOTE: Game objects are passed around using their ManagedReference, not as ManagedObjects.
The MudObject class (1a) defines a minimal interface that allows all objects to have a description, maintain an inventory, support aliases of its name, and parse command the look command. For items that the Player can pick up, put down, and carry around, the GettableObject class (1b) is provided to support the take and drop commands.
The command parsing is where a lot of the game magic takes place and understanding it will be our holy grail.
Text sent from the Client is processed by the MudUser class object that was generated when the player logged in (see UnderstandingDarkMud01 for more details).
This parse() sends the command to the MudUser's overridden parseInnerCommand(). This method first sends the command to the MudCharacter's overridden parseInnerCommand() to see if it processes go commands. Since it doesn't the Command.type stays as null. The MudUser then checks to see it it processes go commands. It doesn't either., but it does register an interest in the command since a successful GO may send the player to a different location.
Since the player doesn't process GO commands, the command is
sent to the container of the player, usually a room, to see if it does.
NOTE: The player was placed into the room (container) by being added to the room's inventory when the player logged on.
Assuming that the Player is in a basic Room class room, its parseInnerCommand() method checkes to see if someone else handled the command. None have, but it only processes look commands. So again, the command type stays as null. The command is now sent to all other objects in the room to see if any of them can process the go command.
One of the objects in the room's inventory is a Door class object. The command is passed to the Door.parseOuterCommand() method for processing. It first sends the command to its inherited classes to see if the command is generic, then its checks for command specific to the Door class. The method sees that the command has not been handled and that the type is still null. It trys to parse the command text by pattern matching for go or walk text. Since it find go, it sets the command type to CommandType.GO and places the word after go into dirString and replaces the current command text with it for later processing. It also sets up an output for use should the command fail.
The Door.java now passes the command to Direction.toDirection() and to checks if the text has a valid direction (north, south, etc.) or an abreviation of a valid direction (n, s, etc.) and if so, sets the command as handled, generates the proper text output, and declares that it is interested in the outcome of the command. All that's left now is to actually move the player to the destination on the other side of the door. This is done by the MudObject.parse() calling MudObject.notifyInterestList() as its last step.
The MudObject.notifyInterestList() method first setup a List
of everyone that register interest during the parsing operation.
The object.notifyCommand() method is used to test it conditions have been met to successfully use the command. (see Rope.notifyCommand() as an example) It would seem that his logic was added after the Locked Door code was designed because it uses a different method of test.
NOTE: Fix LockedDoor.java to use this logic instead of catching it in parseOuterCommand(). Maybe later.
The last process is to commit the command by calling the commitCommand()
method for each object on the list.
The Door.commitCommand() adds the player to the Room indicated by the Door's destination property. The call to addToInventory() also removes the player from the previous Room's inventory. It also sets up an ArrivalTask to complete the process of displaying the Room description and notifying other players about the move.
AND that is how movement is done through the GO command. So how does a Door get Locked and Unlocked?
Looking a LockedDoor.java, the parseOuterCommand() has been overridden to test for the Door's state. Throw an exception if the Door state = locked and a GO command was issued. Simple enough, but this should be handled with the notify/commit logic outlined above. Maybe later.
Using the notify/commit logic the flow could be:
The Door parses the UNLOCK command and registers interest and the failure string "Can't unlock this door with that."
The Key (or other key like item) modifies the command to put the name of the Door the Key works on as the string for Command.UNLOCK.
During the commit phase, the Door.commit tests the command to see if the second word mathces the Door's name of aliases and changes its state as needed.
This notify/commit logic seems to be the more flexible way to get interaction in the game.