Sword
, Axe
, et cetera as subclasses of Weapon
sound like inheritance abuse to me. Fundamentally these types of weapon differ only in data (how much damage they do, what type of damage it is, what sprites or animations or effects are associated with the weapon, and so on). Consequently I'd advocate for an approach where you flatten this hierarchy away, leaving just the Weapon
class.
This provides more impetus for your suggested approach of giving weapons a type
flag and giving classes a set of types they can legally equip. If you implement this type flag as an enumeration organized like a bitfield
enum WeaponType {
None = 0,
Dagger = 1,
Sword = 2,
Axe = 4,
Spear = 8,
Bow = 16,
Boomerang = 32,
Gun = 64,
};
then you can give the CharacterClass
type a field called, for example, equippableWeaponMask
. This can be a bitwise combination of the weapon type flags that are valid for the class to wear:
CharacterClass warrior;
warrior.equippableWeaponMask = Dagger | Sword | Axe | Spear;
CharacterClass mage;
mage.equippableWeaponMask = Dagger | Gun;
CharacterClass hunter;
hunter.equippableWeaponMask = Spear | Bow | Gun;
Then, the query to see if a character class can equip a certain weapon is:
bool CharacterClass::canEquip (const Weapon & weapon) {
return (weapon.type & equippableWeaponMask) != 0;
}
Note that this also suggests you don't need distinct subclasses for CharacterClass
either, but can also represent their capabilities purely in data.