1
\$\begingroup\$

I'm currently fiddling around with some RPG mechanics and I'm trying to implement a solid way to handle items that have different on use effects.

Currently, I have a base class called "Item" that consists of things that all items have such as ID, name, description, quality etc. Then I have some subtype classes that extend "Item" such as "Weapon", "Armour", "Consumable", "Material" and "Quest". "Item" also implements an interface called "Usable" that has a Use function.

These subclasses share the exact same qualities. Such as all armour has an armour value, all weapons have an attack value etc so that I don't need a different class for each item but I want the use effects to differ. An example is that I have an item of type "Consumable" which when the use function is called, restores player health, a different consumable may do this again, but heal a greater amount. Another consumable may teleport the player to a specific location. These items are being stored in a JSon file and there may be a thousand or more different items and effects.

So, firstly, What would be an effective way to implement this behaviour? Secondly, if the vast majority of items have a use effect in each category but a few don't, should it still be structured like this?

Thanks.

\$\endgroup\$
0

1 Answer 1

2
\$\begingroup\$

Similar to the answer to the question referenced by Philipp, you might consider using a general system of events and flags for every item:

  • CanEquip, OnEquip/OnDeEquip
  • CanConsume, OnConsume
  • IsQuestItem, OnCompleteQuest
  • etc.

This is a much more flexible approach as it allows items to serve multiple purposes as would be the case in, for example, the dry baguette which is both a blunt weapon and a food.

You can then use the OnEquip/OnDeequip to add and remove user actions, status effects, and so on. Imagine a cyborg character who needs to equip limbs. We might consider adding or removing the "Fight" option depending on whether they have their limbs equipped. The DeEquip event also supports having a thief-type character steal equipped items.

To make reusable records for each item, you can use composition. So you might use the Item class for everything, and include a list of components for each, ala:

Item: { Name: "Baguette", Aspects: [ Weapon: { ... }, Food: { ... }, ... ] ... }

Note that the Aspects member is an array. You would implement a base class for that like ItemAspect, and extend that for particulars to each idea, while every Item object could pass through events (OnConsume) and properties (CanConsume) to check in with its aspect members.

\$\endgroup\$
2
  • \$\begingroup\$ Wouldn't it make sense for things like armour/weapons to have an interface such as Equippable that they implement rather than having flag values on every item that aren't necessary or am I missing the point? Also, I'm still confused on where and how each item use effect would be as it could be majorly different for items of the same category and there could be a thousand or more, where would this event come from and for example if it was a healing effect, how would it know how much?. \$\endgroup\$ Jun 17, 2018 at 16:56
  • \$\begingroup\$ You could totally use the interface approach, I just prefer flags because of my own experience learning to use other people's systems. In the case of healing items, it isn't necessary for the caller to know what the item does. In your case, the item's consumable aspect handles the healing, not the caller. So you would assign the amount to the type of consumable, and when its "OnConsume" event was called with the character, it would apply that value to the character. The character, in turn, may need its own handling - say for undead creatures that take damage from healing. \$\endgroup\$
    – jzx
    Jun 24, 2018 at 14:19

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