7
\$\begingroup\$

Should static weapons (ie.. Iron Sword, Mythril Axe) be their own (static) classes that derive from something like ItemWeapon, which itself is derived from a standard Item class with their own (inherited) methods?

Or possibly should there be just a standard Item class, an ItemWeapon class, and then every weapon is just an ItemWeapon instance loaded in at the start of the game?

If I was going to do that approach, where would I be loading all the items and weapons into the game? init?

If some weapons have special properties such as doing multiple attacks or a different effect, would it be beneficial to make them the separate classes to do it on an as-is basis instead of having every Weapon in the game have that function except it doesn't do anything?

\$\endgroup\$
11
\$\begingroup\$

Weapons are data. You shouldn't really ever keep data hardcoded. Your structs / classes should accommodate all necessary parameters to build a weapon's data from scratch, e.g.:

struct Weapon
{
    string name;
    int damageMin;
    int damageMax;
    bool entangle;
    bool canHitNoncorporeal;
    float resistFire;
    float resistElec; 
    float attackSpeed;
    //etc. ad nauseam
}

And then say in text / .CSV:

Mithril Sword,15,30,false,true,0,10,4.5
Leather Whip,2,6,true,false,0,0,11 

And yes, you would typically load via a LoadItems function called in Init, but remember to make it separate since you may also have to call LoadItems from elsewhere, such as LoadGame.

If some weapons have special properties such as doing multiple attacks or a different effect would it be benefitial to make them the separate classes to do it on an as-is basis instead of having every Weapon in the game have that function except it doesn't do anything?

Nope. You should do it as a single class, as ultimately it's a finite set of options across all weapons in a given game, and doing it this way makes entering items easy (exception could be delegation much later; for now, do it as one class, factor out later according to SRP). The other reason is that dealing with combinations of static classes quickly becomes tricky for reasons I won't go into here. There really is nothing wrong with storing a bit of extra data for weapons, that is what CPU cache is for. And at worst, you could always compact your data, bitwise, later on.

If you're going to change options (members) often, you'll need to use a named format such as JSON / XML / YAML, otherwise you'll have to worry about changing order as in the CSV above, which does not mention WHAT each entry is, but only supplies them in-order (this is safer):

[
    {
        "name": "Mithril Sword",
        "damageMin": 15,
        "damageMax": 30,
        "entangle": false,
        ...
    },
    {
        "name": "Leather Whip",
        ...
    }
]
\$\endgroup\$
2
  • \$\begingroup\$ say for resistances/weaknesses should it actually be an array of floats with the index's being specific resistances such as 0 being fire, 1 being ice, 2 being lightning, etc. \$\endgroup\$
    – baiomu
    Feb 15 '18 at 6:37
  • \$\begingroup\$ @baiomu An array would be ideal, yes. If you then use #define FIRE 0 or public const int FIRE = 0; and so on for the various elements/resistances, you can easily ref them from the array in code like so: if (resistances[FIRE]) > 20.0f) {...}. \$\endgroup\$
    – Engineer
    Feb 15 '18 at 7:35
1
\$\begingroup\$

For the most part, it's really going to be up to personal preference and how you view it. Personally, I would view it as Item being the top base class, and Weapon extending it. Maybe with Equipment in between, something like:

Item <- Equipment <- Armor
Item <- Equipment <- Weapon
Item <- Food
Item <- Medicine

Then, I would have configuration files that specify all the weapons and their common parts such as damage, attack speed, maybe endurance.

If you have something really unique, you might consider a class that inherits from weapon, or you could just have it in as a field in the configuration files as true/false whether or not each weapon has that capability.

I would stay away from every weapon having it's own class. If you did that, there would be a ton of duplicated code or a ton of classes that inherit everything and have no real code in them.

\$\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.