1

So I'm making a game in which the player will have a number of units with different "job classes", say a Knight, Paige, Alchemist etc... I'm currently making an inventory system and have run into a small problem with respect to code modularity and maintaining good code. Here's the layout of my code so far:

I have an equip class, an instance for every weapon, and each equip has a type; let's say "shortsword" and "greatsword" are types of equipment. Furthermore, a character of class Knight can equip greatsword and shortsword, but a character of type Paige can only equip shortswords

Jobs are organized using a Job class which each character owns (using a List which is stored in character class). The Inventory class should access the character and get the Job and then request all items that the job can equip.

My current prototype utilizes a string field in the Equip class called EquipType which will store these "shortsword/greatsword" strings. Job class will then have a List field which will be sent to Inventory class and get items using string matching.

However, this is annoying in terms of maintaining code since I'm retyping strings for both Equip and Job classes, not very elegant. I was thinking of using enums since that will allow me to get items by enum type, but that will compromise modularity of code and couple things that (maybe??) shouldn't be coupled - and global enums are bad practice anyway. In addition, the enum will then be quite big (15-20 elements).

Are there cleaner and more elegant methods to such an inventory system?

Jer J
  • 85
  • 6

2 Answers2

0

Since you are using C#, you will probably want to adopt a more object-oriented design approach. Instead of using strings or enum values, create types which represent the equipment items and the characters. The objects of each type (instances) are the things themselves that keep track of what they are, not strings or enums (though they may have a string property which is "Name", for example). Each type will then have methods which allow the objects to interact. For example, you might have:

public class Equipment { }
public class Sword : Equipment { }
public class GreatSword : Sword { }

public class Character
{
    public virtual Boolean Wield(Equipment e)
    {
        // do wield logic...
        return true;
    }
}

public class Paige : Character
{
    public override Boolean Wield(Equipment e)
    {
        if (e is GreatSword)
        {
            return false;
        }

        return base.Wield(e);
    }
}

This allows you to add new types and customize behavior in each character class. The problem you will next face is that your wield logic doesn't just depend on the equipment type, but both the equipment and character types. This is a well known problem classified as "double dispatch". One approach to get around this in C# is the design pattern known as the Visitor Pattern.

After this, there are several well documented issues with implementing player state and world state. This StackOverflow question deals with creating a RPG with these design patterns in mind, and would be worth your reading it.

Community
  • 1
  • 1
codekaizen
  • 26,990
  • 7
  • 84
  • 140
  • 1
    I like this method and it meets my need for good, organized code. My situation is slightly different but nonetheless I can manage with the excellent example you've provided. Thanks for the help! – Jer J Sep 15 '15 at 01:11
0

I am not a C# person but in terms of OO concepts you should have Two abstract classes 1. Equipment 2. Character

Each equipment type should be a class inheriting parent class Equipment Each Character type should be inheriting Parent class Character.

As business logic is not very clear so I can thought of 2 options: Option 1: Character can have a list of type Equipment & every time you instantiate character, you can also decide which equipments are allowed for this character & add it to the list.

Option2: Can create association class which would store the relationship between character & equipment.