Skip to content

01 Game and Store Commands Refactor

Marc Johnston edited this page Jul 20, 2022 · 8 revisions

GAME COMMANDS The first round of refactoring was to convert the SWITCH statement in the CommandHandler to use objects for commands. During the conversion process, it became evident that the ActivationHandler and the CastingHandler were similar objects performing the same objective; so the ActivationHandler and CastingHandler classes were converted into the ICommand interface and all command actions were converted into class objects that implements the ICommand interface. The parameters into the handler class constructors (player and level) are passed as objects to the command execution.

COMMAND OBJECTS The "Commands" folder was created and all of the command objects have been placed into this folder. Also, note that the ICommand and IStoreCommand interfaces were placed into the same folder.

STORE COMMANDS During the conversion, it was noticed that the store also referenced these same commands. To accommodate this, an IStoreCommand interface was also added. The IStoreCommand interface defines the same Execute method, but does not pass the Level object because stores should not be able to interact with items outside of the store. All game command objects that also serve as store commands were updated to also implement the IStoreCommand interface. During this process, a flaw was exposed where the store needed to pass the current Level object to the command. This flaw is apparent when the command needs the player to select an object using the GetItem method. The GetItem method requires a Level object to allow the player to select an object from the floor.

There are two avenues to absolve this deficiency.

  1. Refactor the IStoreCommand.Execute(Player) into IStoreCommand.Execute(Player, SaveGame.Instance.Level) but that would allow the store access to items in the Town.
  2. Refactor the GetItem method. This is the avenue we will take. Once the GetItem framework objects are created, a base class should be able to implement the GetItem that is limited to the player inventory.

ENABLED PROPERTY A logic statement was found that appeared to disable several commands.

        if (CommandArgument <= 0 && !shopping)
        {
            if ("TBDocs+".Contains(CurrentCommand.ToString()))
            {
                CommandArgument = 99;
            }
        }

This logic statement appears to disable these commands:

  • Tunnel
  • Bash
  • Disarm
  • Open
  • Close
  • Alter This was resolved by adding the IsEnabled property and setting the property to false for the applicable commands. Since the store uses a separate interface, the IsEnabled can be applied to either the Game or Shopping interface.

REPEATABLE PROPERTY Several commands support the ability to be performed multiple times. The code that identified this functionality was: if (Gui.CommandArgument != 0) { CommandRepeat = Gui.CommandArgument - 1; Player.RedrawNeeded.Set(RedrawFlag.PrState); Gui.CommandArgument = 0; }

This functionality was added to the below properties.

  • Alter
  • Bash
  • Close
  • Disarm
  • Open
  • Tunnel
  • Walk
  • Search
  • Stay

DYNAMIC LOADING AND COMMAND MANAGER To ensure all command objects are loaded, a dynamic loading process was created. Upon startup, using reflection, all objects are scanned to determine if they implement in the ICommand and/or IStoreCommand interfaces. If so, they are added to an appropriate list and made available in the CommandManager static class.

TECH DEBT

  1. A couple areas of tech debt were created and exposed during this process. There were a few commands where the execute method is being called by other parts of the application (e.g. Save game). To accommodate the additional references, the execute method for several of the commands was converted into a static method.

These commands were affected:

  • Feeling command
  • Stay command
  • Store command ... used by SaveGame to start in store
  • CastCommand.GetSpell
  • Walk command ... two pickup variations
  • Throw command ... used by MutationLauncher
  1. A couple of the commands made use of a "pickup" parameter. To resolve this, the command objects were inherited and the properties were made virtual with an override.
Clone this wiki locally