1
\$\begingroup\$

This question already has an answer here:

I'm currently trying to get my head around how to create an item class which contains data for multiple purposes.

As for example I would like to have an Axe which could be used as weapon, but also as a tool to chop trees. The class should contain the following:

Durability, weight, damage vs npcs/players (when attacking), damage vs trees (when chopping), attack speed, chop speed and some enum in which equipment slot the axe fits (e.g. melee slot).

What would be the typical approach?

I stumbled about this answer, but I'm not 100% sure if I'm understanding him right. Is it something like:

public class Item {

    public int durability;
    public float weight;

    public Weapon weapon;
    public Tool tool;

    public class Weapon {
        public int damage; // damage vs players
        public int speed; // attack speed
    }

    public class Tool {
        public int damage; // damage vs trees
        public int speed; // chop speed
    }
}

?

\$\endgroup\$

marked as duplicate by DMGregory, Josh Dec 22 '16 at 4:54

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • \$\begingroup\$ Related Meta \$\endgroup\$ – Gnemlock Dec 21 '16 at 20:27
  • \$\begingroup\$ Hi. If you're not familiar with how SE sites work, you might want to read the help center. The question you've asked is essentially the same question asked in the link you provided, which is something we tried to avoid. If you need to ask a new question seeking clarification about an existing answer, which seems to the be the case here, you should word the question in a way that really emphasizes that you are looking for helping understanding a specific pre-existing answer. The way you worded this question makes it look like a re-hash of the original. \$\endgroup\$ – Josh Dec 22 '16 at 5:04
  • \$\begingroup\$ Normally I'd make such an edit for you, but in this case your question has already attracted answers that would become invalid if I did, so at this point it may be better for you to re-post a new question. You can read the "related meta" link from the first comment above for more information. \$\endgroup\$ – Josh Dec 22 '16 at 5:06
3
\$\begingroup\$

A common approach which is quite popular among game developers is the Entity-Component-System.

Each Entity (class Item) only contains the most basic functionality and data which is common to all items, plus a List<ItemComponent>. ItemComponent is an abstract class with sub-classes like WeaponItemComponent, ToolItemComponent and any other features you only want to have on some of your items. These components contain the data and code which is relevant for performing that feature. Each Item can have one of each of these components (or more than one, if you want to allow that), but doesn't have to.

One way to interact with components is by using an event system. Your item class would have a method HandleEvent(event) which then calls component.HandleEvent(event) for all components. The internal implementation of each component decides if it needs to do something for that event.

Another way is by explicitly getting a component from an item:

WeaponItemComponent wic = item.GetComponent<WeaponItemComponent>();
if (wic != null) {
    enemy.hp -= wic.damage;
}
\$\endgroup\$
  • \$\begingroup\$ We're discussing this question on Meta, and whether it may be more appropriate to post expanded answers to the original question linked above, rather than split the answers between the original and a duplicate. What do you think? \$\endgroup\$ – DMGregory Dec 22 '16 at 1:00
0
\$\begingroup\$

It seems right but it doesn't allow for as much future-proofing if you decide to add further items that the item can interact with to your game at a later date.

Maybe try something like:

public enum ItemType {Weapon, Tool}

public struct ItemInfo
{
     public ItemType itemType;
     public int damage;
     public int speed;
}

public class Item
{
    private int durability;
    private float weight;
    private List<ItemInfo> _itemInfo = new <itemInfo>();
}

This allows you to keep a simple list of all of the interactions your item may have.

\$\endgroup\$
  • 3
    \$\begingroup\$ What would you do in that architecture when you later decide to add more item types which have different properties than just damage and speed? \$\endgroup\$ – Philipp Dec 21 '16 at 15:30

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