0
\$\begingroup\$

In my RPG, all Food objects should be possible weapons. For instance, I want the player to be able to to try kill bunnies with a cherry or a watermelon.

The problem is that the easiest way to do this is a bit counter-intuitive (and ugly, IMHO):

Item < Weapon < Food

(superclass < subclass)

I wrote an interface (IWeapon) and made Weapon and Food implement it, but the amount of repeated code was ridiculously huge (what indicates that they should share a common class, right?).

I do not think that I want Potions, for instance, to be usable as weapons (I don't want to let the player hit the target with a filled vial).

How should I solve my current problem? Should I use inheritance or program to the interface?

What about extensibility? Does it make sense to let all items have attributes such as damage, hitRate, integrity, etc.?

\$\endgroup\$
7
  • \$\begingroup\$ Why bother creating fruit weapons? Why dont you use normal weapon, sword for example, but draw a fruit instead? \$\endgroup\$
    – wondra
    Commented Sep 20, 2014 at 18:40
  • \$\begingroup\$ @wondra a sword will break after 100 hits against a leather shield. An apple will only last 10. Apples can be consumed to regenerate HP and to feed the hero. They are distinct enough to be objects of different classes. The "goal" of the apple is not being a weapon. \$\endgroup\$ Commented Sep 20, 2014 at 19:06
  • \$\begingroup\$ Then set correct "breaks in x hits" to the apple sword. The apple can still remain where it is - in inventory just unequip your apple sword if eaten. \$\endgroup\$
    – wondra
    Commented Sep 20, 2014 at 19:10
  • \$\begingroup\$ I still consider this unsatisfactory. What if swords in the future get sword-specific characteristics that an apple should not have? Will you suggest an apple mace instead? It should not be done that way. All food will have the is-a relationship with the Weapon class, I just asked if this was acceptable or if I should use a common interface between ([common weapon classes], Food, Miscellaneous, ...) to enable them as weapons. \$\endgroup\$ Commented Sep 20, 2014 at 19:14
  • 1
    \$\begingroup\$ A weapon is set of stats, damage, range, speed etc., right? Set those stats to your liking and then draw apple instead of sword, pole, mace or whatever. You are overcomplicating things - appearance and behavior are two different things(and should be separated), it is not relevant for weapon if it looks like a sword or an apple. In eyes of engine it is(should be) the same. \$\endgroup\$
    – wondra
    Commented Sep 20, 2014 at 19:18

1 Answer 1

1
\$\begingroup\$

@wondra's comment that anything that does damage is a Weapon is spot-on. Don't get confused by having the class name be restrictive when it's not the right word. Perhaps in this case you want the class to be DamageDealer instead of Weapon.

Another, and better, option is to use interfaces for the object types. This way you get a broad hierarchy instead of a deep one, which is easier to manage when it gets large.

A third, and even better, option is to use composition. In this case your Item class would have objects for DamageDealing and Edible and Wearable and each individual object may or may not have those objects exist. This gives you the advantage of being able to at run time decide that jello can't ever be a weapon but flan is both a weapon and wearable.

The third option is what I've done in my overly-complex rpg in which anything can potentially be a weapon, or container, or wearable. It's worked out quite well for me as the complexity has grown.

\$\endgroup\$
6
  • \$\begingroup\$ So I should define damage dealing objects that are a field of Item and then check for null (for instance, to see if jello can be used as a weapon)? Wouldn't that make Item a huge class? So Item has-a DD, has-a Edible, has-a Wearable, has-a Throwable, etc? \$\endgroup\$ Commented Sep 21, 2014 at 1:56
  • 1
    \$\begingroup\$ Don't fear a big fat base class. The alternative you started with is much worse. If you want complete flexibility perhaps you should consider an entity component system but tbh this way should work just fine anyway. \$\endgroup\$
    – user40079
    Commented Sep 21, 2014 at 2:10
  • \$\begingroup\$ @mafagafogigante yep, that's basically what I'm suggesting. \$\endgroup\$
    – Eben
    Commented Sep 21, 2014 at 7:52
  • \$\begingroup\$ @user40079 This way = inheritance tree + some interfaces? About "big fat base class", does the compile time of a class (approximately) increase linearly as its size grows? Or a class with 10K sloc will take more than (again, approximately) twice the time a class with 5K sloc will take to compile? \$\endgroup\$ Commented Sep 21, 2014 at 15:29
  • \$\begingroup\$ Interesting, the third option is getting close to the entity system approach, which follows this idea to the logical extreme while avoiding a fat base class. \$\endgroup\$
    – 31eee384
    Commented Sep 21, 2014 at 15:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .