2
\$\begingroup\$

I'm making a small text-based adventure in Objective-C. I have a Player class with four properties which represent the player's attributes (strength, agility, stamina, and intelligence). I also have a Weapon class. My goal is to put a weapon in the game that will increase the player's stats as long as it is equipped. How can I achieve this in an object-oriented fashion?

I could add a method to the Weapon class that will increase the player's attributes, and call the method only when a flag is set to true (which I would set to true when initiating this particular weapon, and leave false for all other weapons I create), but that seems a bit messy and not particularly object-oriented. I recently learned about the decorator design pattern. Would I be able to accomplish my goal using decorators?

\$\endgroup\$
4
  • 2
    \$\begingroup\$ I wouldn't alter the stats of the character directly. You would create a method for calculating the stats, and it takes into account currently equipped items, spell effects, etc. The calculation method would probably live in the character class and the items and effects applied to the character would be "child" objects that the character class knows about. \$\endgroup\$
    – House
    Jul 19 '13 at 23:23
  • 4
    \$\begingroup\$ possible duplicate of How to implement buffs / debuffs / temporary stat changes in an RPG? \$\endgroup\$ Jul 19 '13 at 23:45
  • 1
    \$\begingroup\$ I think Sean is right, this is probably a duplicate of the linked (or its duplicate). \$\endgroup\$
    – House
    Jul 20 '13 at 3:35
  • \$\begingroup\$ This is something that made me appreciate C#'s properties a lot more. \$\endgroup\$ Sep 18 '13 at 8:06
2
\$\begingroup\$

Using decorators is not a good idea in this case, because you also want to un-equip items. When you wrap decorators in decorators in decorators and then want to remove a specific one inside that stack, it's a quite messy operation (especially because an object shouldn't be aware that an object it uses is just a decorator wrapping something else).

What you could do instead is have an abstract base class StatModifier with a modifier function for each stat a player can have. These modifiers receive a value (base value) and return a value of the same type (modified value). The default implementation in the base class would just return the value unchanged.

The Player class would then have a vector of StatModifiers which represents the currently active modifiers (equipment, buffs etc.). When, for example, the method Player.getStrength() is called, the implementation would call the modifyStrength method of each StatModifier to "filter" the result value.

I don't know objective-c, so this example should be considered pseudocode:

List<StatModifier> modifiers;

int getStrength() {
    int strength = this.baseStrength;
    foreach (modifier in this.modifiers) {
        strength = modifier.modifyStrength(val);
    }
    return strength;
} 
\$\endgroup\$
1
\$\begingroup\$

I would make a base class for weapons/armor in which all weapons/armor inherit and have the base class include the stats so you don't need to access a specific weapon/armor. Then when you need the stats just add up the weapon/armor stats and the players.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.