Fundamentally you're looking at creating a mapping from some piece of data (the "key") to some instance of your effect classes (ChangeHealth
, SetPosition
, et cetera). A straightforward way to accomplish this is to use
- some kind of delegate (
Func<...>
in C#, for example) to manage the generic creation of effect instances and
- some kind of associative array (
Dictionary<K, V>
in C#) to map from effect to delegate.
To do this you'd decide on a data representation for your traps. For simplicity's sake, I'll suggest you start with something text-based because it's easy to author, consume, and reason about. More complex ("binary") formats for your data may be an option you want to look at in the future, but aren't directly relevant to the mechanics of the technique I'm suggesting.
So, let's say each trap type is just a simple text file with a list of the effects it will apply, one per line. The effect name (a string like "teleport"
or "poison"
for example) becomes your dictionary's key.
Your dictionary's value is a Func<T>
. T
is the base class or interface shared by all your effect strategy classes. So your dictionary might look like:
Dictionary<string, Func<IEffect>> m_effectCreators;
When you define new effects in code, you can register them with this dictionary, supplying a delegate that creates a new instance of the appropriate effect:
m_effectCreators.Add("teleport", () => new SetPosition());
m_effectCreators.Add("poison", () => new ChangeHealth(-100));
m_effectCreators.Add("heal", () => new ChangeHealth(100));
Then, when you parse the trap, you read the trap's effect strings and, for each one, look it up in the dictionary to invoke the function to create the appropriate effect instance.
foreach(var effectName in trapData) {
var creator = m_effectCreators[effectName];
var effect = creator();
actualTrap.AddEffect(effect); // ...or however you store the instances.
}
Hopefully you can see how you could even extend this to allow the trap text data to supply parameters. For example, instead of hard-coding the damage of a heal or poison trap as I did above, you could write "heal(30)" and have your code parse the "parameters" between the (
and )
and supply them so that the delegate can in turn pass them to the constructors of the effects.