The problem is that âwarriors can only use swordsâ the restriction is not something that needs to be modeled in a type system.
You have "characters are things that have weapons"
abstract class Character { public Weapon weapon { get; set; } }
but you really want to say something like "characters are things that have weapons, but with some limitation." I would suggest not having specific types, such as âwarriorâ and âswordâ in general, but rather specific types should be instances:
sealed class Weapon { public string Name { get; set; } } sealed class Character { const int sSkillToUseWeapon = 50; readonly Dictionary<string, int> mWeaponSkills = new Dictionary<string, int>(); Weapon mCurrentWeapon; public Weapon CurrentWeapon { get { return mCurrentWeapon; } set { if (!mWeaponSkills.ContainsKey(value.Name)) return; if (mWeaponSkills[value.Name] < mSkillToUseWeapon) return; mCurrentWeapon = value; } } public void SetWeaponSkill(string pWeaponName, int pSkill) { if (mWeaponSkills.ContainsKey(pWeaponName)) mWeaponSkills[pWeaponName] = pSkill; else mWeaponSkill.Add(pWeaponName, pSkill); } }
Then you can declare instances of them for use and reuse:
var warrior = new Character(); warrior.SetWeaponSkill("Sword", 100); warrior.SetWeaponSkill("Bow", 25); var archer = new Character(); archer.SetWeaponSkill("Bow", 125); archer.SetWeaponSkill("Sword", 25); archer.SetWeaponSkill("Dagger", 55);
A Warrior is a case of a character with a specific set of weapon skills.
When you approach this path, another problem that you must solve is that there is a difference between, for example, "Rusty Sword" and "Rusty Sword". In other words, even if Rusty Sword is an instance of Weapons, there is still a difference between the general concept of Rusty Sword and a real rusty sword that lies on the ground. The same goes for Goblin or Warrior.
The terms I use for myself are "Stock____" and "Placed", so there is a difference between StockWeapon, which defines the "class" of weapons, and "Placed world", which is the actual "instance" of StockWeapon in the game world.
Placed objects then have the âpresenceâ of instances of stock objects that determine their common attributes (base damage, base strength, etc.) and have other attributes that determine their current state regardless of other similar items (location, etc.)
( Here is a good site about using OOP templates for game programming. (Unfortunately, I forgot halfway through writing that game programming part was just an analogy. Nevertheless, I really assumed that, hopefully, the explanation remains the same.))