EDIT: If you can't be bothered to read this mammoth question, I've put a summary at the bottom.
I'm currently working on a sort of "framework" for a text adventure I am going to make in C#, as a coding excercise. In this framework, possible actions are defined by an "Interaction" class.
The potential "Actionable" objects are Inventory Items (stick, gun, sword), Environmental Items (wall, door, window) and Characters (people, animals). Each of these has a property which is a List of Interactions. At the moment, an Interaction is basically an "action/response" name value pair. When you type "smash window", it looks through all possible actionable items that the Player has available and matches the subject (in this case, "Window"). It then works out that the action is "Smash" and looks up in the List of Interactions on the Window (Environmental Item) to get a response for the Smash action and then writes it to the console.
That is all done, but here is the point that I am stuck:
An action has any number of potential consequences, which differs by each potential interaction. These are:
- Returns a response describing the result of the action by looking it up on the interaction, possibly with a second subject
EITHER - The subject of the action (inventory item, environmental item or character) changes it's description EG. "punch wall" could change the wall's description to describe a dent in the wall OR - The subject of the action is replaced by another item EG. "smash bottle" results in "bottle" changing to "broken bottle" or "kill John" results in the character John being replaced by environmental item "John's corpse".
- Returns a response describing the preceeding change EG. "The broken pieces of the bottle are scattered across the floor."
- An area's description is changed. EG. "smash lightbulb" results in the room's description changing to describe a pitch black room
- Items are added/removed from the inventory or the environment EG. "pick up bottle". You now have a bottle in your inventory, and the bottle is removed from the environment.
- The directions available for movement and the areas which they lead to are changed EG. "unlock door with key" allows you to move East into another room
- The player is moved to a new area EG. "go north" takes you to another area.
I need to somehow determine in a generic way which of these consequences a particular Interaction should invoke, and invoke them. An action could potentially use a number of these consequences, or just one.
For example, if the item is a Bottle:
"fill bottle with water" would first return a response describing that you have filled the bottle with water. It would then replace the "bottle" item with a "bottle of water" item. That is two consequences, returning a response and replacing an item.
Say you were then to do "throw bottle of water at window". This is more complex. It would first return a response describing the events that take place, the bottle and the window would both smash and water would go everywhere. The bottle would be removed from the Player's inventory. Next, the "bottle of water" would be replaced by the "broken bottle" and the "Window" would be replaced with "Broken window". The area description would also change to reflect this. That is five consequences, returning a response, removing an item from inventory, replacing two items and updating the description of the current area.
As you can see, I need a generic way of being able to define on a per "Interaction" basis, what the consequences of that action will be and update other objects such as Item, Player (for inventory) and Area appropriately.
I'm sorry if this is unclear, and I will do my best to clarify if anyone has any questions.
EDIT: Is there a way for me to define a method on an Interaction that I can pass a number of methods to call (and their parameters) into? The initial response returned would be the default, mandatory consequence, and then there could be extra ones if specified.
For example, in the examples above, for the first interaction, "fill with water", I would tell it to return a response ("You have filled the bottle with water") and also to call a ReplaceItem method that would replace the "bottle" subject with a "bottle of water".
For the second interaction I would tell it to return a response ("The bottle hurtles through the air into..."), call RemoveFromInventory on the subject of the action, call UpdateStatus on the bottle ("the bottle is smashed") and the window ("the window is smashed") and call UpdateAreaDescription to change the current area's description ("You are standing in a room with a single window, the glass smashed to pieces").
Does that sound feasible? I'm trying to keep this as generic as possible, for the sake of all the different possible interactions.
EDIT 2: To clarify further, and to attempt to summarize the problem:
In my game, there are Actionable objects (a bottle, a wall, John). Each Actionable object has a list of Interaction objects which describe how a player can interact with them. At the moment, an Interaction has a "Name" property ("throw", "hit", "break") and returns a Response ("You throw the ").
The issue that I am trying to resolve is that an Interaction also needs to do a number of other things, varying by each particular Interaction. Let's take the example of a glass bottle.
"throw glass bottle"
- A response is returned ("You threw the glass bottle.")
- The "Bottle", is removed from the Player's inventory.
- The is replaced with a new to reflect the change. ("Bottle" replaced with "Broken bottle").
- A second response is returned ("The pieces of the glass bottle are scattered on the floor").
"throw glass bottle at window"
- A response is returned ("You threw the glass bottle at the window.")
- The object "Bottle", is removed from the Player's inventory.
- The object is replaced with a new object to reflect the change. ("Bottle" replaced with "Broken bottle").
- A second, optional object is replaced with a new to reflect the change. ("Window" replaced with "Broken window").
- The "Description" property of the current Area is updated. ("You are standing in a room, with a single broken window.").
When I create the Interactions, how can I vary the additional actions that they perform, such as status changes to the subject, or changes to the current Area's description?
If you need more examples of actions as above, let me know and I'll do a few more.