I am working on a role playing game for fun and to practice design patterns. I would like players to be able to transform themselves into different animals. For example, a Druid might be able to shape shift into a cheetah. Right now I'm planning on using the decorator pattern to do this but my question is - how do I make it so that when a druid is in the cheetah form, they can only access skills for the cheetah? In other words, they should not be able to access their normal Druid skills.
Using the decorator pattern it appears that even in the cheetah form my druid will be able to access their normal druid skills.
class Druid : Character
{
// many cool druid skills and spells
void LightHeal(Character target) { }
}
abstract class CharacterDecorator : Character
{
Character DecoratedCharacter;
}
class CheetahForm : CharacterDecorator
{
Character DecoratedCharacter;
public CheetahForm(Character decoratedCharacter)
{
DecoratedCharacter= decoratedCharacter;
}
// many cool cheetah related skills
void CheetahRun()
{
// let player move very fast
}
}
now using the classes
Druid myDruid = new Druid();
myDruid.LightHeal(myDruid); // casting light heal here is fine
myDruid = new CheetahForm(myDruid);
myDruid.LightHeal(myDruid); // casting here should not be allowed
Hmmmm...now that I think about it, will myDruid be unable to us the Druid
class spells/skills unless the class is down-casted? But even if that's the case, is there a better way to ensure that myDruid
at this point is locked out from all Druid
related spells/skills until it is cast back to a Druid
(since currently it's in CheetahForm
)
You should not have your spells and skills as method in the class. They should be a collection of Spell and Skill objects which are accessible through the Character (or possibly Creature) interface. Then your CheetaForm could override the getSkills getSpells methods to return a new modified collection of appropriate skills.
Maybe rather than placing the skill set for a Druid into the Druid class, you could move this skill set into a decorator itself.
Druid myDruid = new Druid();
myDruid = new StandardDruid(myDruid);
Ignoring the horribly named "StandardDruid" class, I'm hoping you can see where I'm going with this :)
There are upsides to this arrangement, namely that all of your skill based code will be contained consistently inside of decorators, rather than half inside the original Druid class, and the remaining skills in decorators. If you were to have another class that could morph into a Druid, you could easily do this without any code duplication.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With