I am trying to figure out a good component design for my item classes since otherwise it probably ends up in a hierarchy disaster. I will just be just using this to define my items in a data driven way. My items do not have a position or interact with the map, they are either on a character or on a tile in the map and that is where they are stored. So I created a blank interface and a couple implementations, nothing is set in stone but I think my concept is pretty solid and I'm looking for feedback from people with more experience on the topic since it would not be the first time I burry myself into something I cannot climb out of :).
public interface ItemComponent {
}
public class WeaponComponent implements ItemComponent{
int damage;
int range;
float attackSpeed;
String damageType;
}
public class ArmorComponent implements ItemComponent {
int defense;
String armorType;
String bodyPart;
}
Easy enough, like most component systems they only add data the system in my case are the characters using the items, I could add functionality but that will probably complicate things once more components are added. When the character uses any item with the corresponding component I have access to the data, and that is all I currently need. A shield that could also be used as a weapon should be easy to model in. To know and find a specific type of item I implemented a Map that maps a String to a ItemComponent.
public class Item {
private String name;
private int weight;
private Map<String, ItemComponent> itemComponents = new HashMap<>();
public Item() {
}
public void addComponent(ItemComponent component) {
itemComponents.put(component.getClass().toString(), component);
}
}
A basic item that is used for crafting only would not have any components. For easy lookup I added a couple methods.
public boolean hasComponent(Class c) {
return itemComponents.containsKey(c.toString());
}
public boolean isWeapon() {
return hasComponent(WeaponComponent.class);
}
public boolean isArmor() {
return hasComponent(ArmorComponent.class);
}
To instantiate items I will import all JSON data in a Factory pattern and clone the items. Since crafting is a thing I will add another Map to this that maps the items name to the recipe.
public Item clone() {
return new Item(name, weight, itemComponents);
}
public class ItemPrototype {
private Item item;
private Recipe recipe;
public Item cloneItem(){
return item.clone();
}
public Item createItem(List<Item> ingredients) {
// Todo: Check ingredients.
// Todo: Remove ingredients.
return cloneItem();
}
}
public class ItemFactory {
private static Map<String, ItemPrototype> itemPrototypes = new HashMap<>();
static {
// Todo: Import items from JSON
}
public static Item createItem(String name, List<Item> ingredients) {
// TODO: Error handling
return itemPrototypes.get(name).createItem(ingredients);
}
public static Item createItem(String name) {
// TODO: Error handling
return itemPrototypes.get(name).cloneItem();
}
}
Here is how an item would look inside a JSON file. A simple rock would truncate everything except for it's name and weight unless it I decide it can be used as a weapon too.
"Rifle" : {
"item" : {
"name" : "Rifle",
"weight" : 3500,
"itemComponents" : {
"WeaponComponent" : {
"damage" : 18,
"range" : 20,
"attackSpeed" : 10.0,
"damageType" : "Piercing"
}
}
},
"recipe" : {
"ingredients" : {
"Wood" : 1,
"lense" : 1,
"Steel Plate" : 4
}
}
}
I love to hear what more experienced people have to say about this. There are not much examples to look at on internet except for a couple that go all the way down to engine level where basically everything is a entity. If I have success with this structure I definitely write a article about it.