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\$
  • \$\begingroup\$ Why bother creating fruit weapons? Why dont you use normal weapon, sword for example, but draw a fruit instead? \$\endgroup\$ – wondra Sep 20 '14 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\$ – Bernardo Sulzbach Sep 20 '14 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 Sep 20 '14 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\$ – Bernardo Sulzbach Sep 20 '14 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 Sep 20 '14 at 19:18
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\$
  • \$\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\$ – Bernardo Sulzbach Sep 21 '14 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 Sep 21 '14 at 2:10
  • \$\begingroup\$ @mafagafogigante yep, that's basically what I'm suggesting. \$\endgroup\$ – Eben Sep 21 '14 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\$ – Bernardo Sulzbach Sep 21 '14 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 Sep 21 '14 at 15:31

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.