Hello everyone!
I am remaking my game’s inventory and items system. I tried another aproach than what i was using and now i have one big problem.
I am loading the items from a XML file (template items) into an arraylist. Every item has some properties (stored in an 2D String arrray). Everytime i want to create a new item (like if i kill a mob and he drops an item) i copy the item (based on an item id) from the templates arraylist, i modify some properties (if needed) and add it to the inventory arraylist.
The problem is that when i modify, let’s say, the name of an item, all the items (with it’s id, based on same template item) change their names.
Here is how i load the items:
package com.game.util;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.newdawn.slick.util.ResourceLoader;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import com.game.items.Item;
import java.io.InputStream;
import java.util.ArrayList;
public class ItemsLoader {
public static ArrayList<Item> itemsList = new ArrayList<Item>();
public static NodeList nodeList;
public static void loadItems(String location) {
try {
InputStream fXmlFile = ResourceLoader.getResourceAsStream(location);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
nodeList = doc.getElementsByTagName("item");
for (int i = 0; i < nodeList.getLength(); i++) {
Element element = (Element) nodeList.item(i);
Item item = new Item(Integer.parseInt(element.getAttribute("id")));
for(int j = 0; j < element.getAttributes().getLength(); j++) {
Node attribute = element.getAttributes().item(j);
String attributeName = attribute.getNodeName();
String attributeValue = attribute.getNodeValue();
item.addProperty(attributeName, attributeValue);
}
itemsList.add(item);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static Item searchItemByItemID(int itemID) {
for(Item item : itemsList)
if(item.getItemID() == itemID)
return item;
return null;
}
}
Item class:
package com.game.items;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.geom.Polygon;
import com.game.util.ResourceLoader;
public class Item {
private int x, y, width, height;
private int itemID;
private Image dropedImage, inventoryImage;
private String[] properties, propertiesValue;
private int propertiesNumber;
private Polygon hitBox;
public Item(int itemID) {
this.setProperties(new String[10]);
this.setPropertiesValue(new String[10]);
this.setPropertiesNumber(0);
this.setItemID(itemID);
this.setDropedImage(ResourceLoader.dropSheet.getSprite(this.getItemID() % ResourceLoader.dropSheet.getHorizontalCount(), this.getItemID() / ResourceLoader.dropSheet.getHorizontalCount()));
this.setInventoryImage(ResourceLoader.inventorySheet.getSprite(this.getItemID() % ResourceLoader.inventorySheet.getHorizontalCount(), this.getItemID() / ResourceLoader.inventorySheet.getHorizontalCount()));
}
public Item(Item item) {
this.setProperties(item.getProperties());
this.setPropertiesValue(item.getPropertiesValue());
this.setPropertiesNumber(item.getPropertiesNumber());
this.setItemID(item.getItemID());
this.setDropedImage(item.getDropedImage());
this.setInventoryImage(item.getInventoryImage());
}
public void addProperty(String property, String propertyValue) {
this.getProperties()[getPropertiesNumber()] = property;
this.getPropertiesValue()[getPropertiesNumber()] = propertyValue;
this.setPropertiesNumber(this.getPropertiesNumber() + 1);
}
public void setProperty(String property, String propertyValue) {
boolean found = false;
for(int i = 0; i < getPropertiesNumber(); i++) {
if(this.getProperties()[i] == property) {
this.getPropertiesValue()[i] = propertyValue;
found = true;
break;
}
}
if(!found) {
this.getProperties()[getPropertiesNumber()] = property;
this.getPropertiesValue()[getPropertiesNumber()] = propertyValue;
this.setPropertiesNumber(this.getPropertiesNumber() + 1);
}
}
public String getValueOfProperty(String property) {
for(int i = 0; i < this.getPropertiesNumber(); i++) {
if(this.getProperties()[i].equals(property))
return this.getPropertiesValue()[i];
}
return property;
}
public void render(Graphics g, boolean inInventory) {
if(inInventory) g.drawImage(getInventoryImage(), this.x, this.y);
else g.drawImage(getDropedImage(), this.x, this.y);
}
//GETTERS AND SETTERS
public int getX() { return x; }
public int getY() { return y; }
public void setX(int x) { this.x = x; }
public void setY(int y) { this.y = y; }
public int getWidth() { return width; }
public int getHeight() { return height; }
public int getItemID() { return itemID; }
public String[] getProperties() { return properties; }
public Polygon getHitBox() { return hitBox; }
public void setWidth(int width) { this.width = width; }
public void setHeight(int height) { this.height = height; }
public Image getDropedImage() { return dropedImage; }
public void setHitBox(Polygon hitBox) { this.hitBox = hitBox; }
public void setProperties(String[] properties) { this.properties = properties; }
public int getPropertiesNumber() { return propertiesNumber; }
public void setPropertiesNumber(int propertiesNumber) { this.propertiesNumber = propertiesNumber; }
public String[] getPropertiesValue() { return propertiesValue; }
public void setPropertiesValue(String[] propertiesValue) { this.propertiesValue = propertiesValue; }
public void setItemID(int itemID) { this.itemID = itemID; }
public void setDropedImage(Image dropedImage) { this.dropedImage = dropedImage; }
public Image getInventoryImage() { return inventoryImage; }
public void setInventoryImage(Image inventoryImage) { this.inventoryImage = inventoryImage; }
}
ItemFactory:
package com.game.items;
import org.newdawn.slick.geom.Polygon;
import com.game.util.ItemsLoader;
public class ItemFactory {
public static Item createNewDropItem(int itemID, int x, int y) {
Item source = ItemsLoader.searchItemByItemID(itemID);
Item item = new Item(source.getItemID());
item.setProperties(source.getProperties());
item.setPropertiesValue(source.getPropertiesValue());
item.setPropertiesNumber(source.getPropertiesNumber());
item.setItemID(source.getItemID());
item.setDropedImage(source.getDropedImage());
item.setInventoryImage(source.getInventoryImage());
item.setX(x);
item.setY(y);
item.setWidth(item.getDropedImage().getWidth());
item.setHeight(item.getDropedImage().getHeight());
item.setHitBox(new Polygon(new float[]{
(float) item.getX(), (float) item.getY(),
(float) (item.getX() + item.getWidth()), (float) item.getY(),
(float) (item.getX() + item.getWidth()), (float) (item.getY() + item.getHeight()),
(float) item.getX(), (float) (item.getY() + item.getHeight())
}));
return item;
}
public static Item createNewInventoryItem(Item sourceItem) {
Item item = new Item(sourceItem.getItemID());
item.setProperties(sourceItem.getProperties());
item.setPropertiesValue(sourceItem.getPropertiesValue());
item.setPropertiesNumber(sourceItem.getPropertiesNumber());
item.setItemID(sourceItem.getItemID());
item.setDropedImage(sourceItem.getDropedImage());
item.setInventoryImage(sourceItem.getInventoryImage());
return item;
}
}
private void dropItem() {
if(this instanceof Enemy) {
Random rand = new Random();
EntityManager.getEnemies().remove(this);
if(rand.nextInt(6) > 3) {
if(this instanceof Slime) {
Item dropItem = ItemFactory.createNewDropItem(rand.nextInt(ItemsLoader.itemsList.size()), (int) this.x,(int) this.y + this.height);
dropItem.setProperty("name", "Test 1");
EntityManager.getDropedItems().add(dropItem);
}
}
}
}
public void getItem(Item item) {
Item inventoryItem = ItemFactory.createNewInventoryItem(item);
boolean search = false, alreadyExist = false;
switch(inventoryItem.getValueOfProperty("type")) {
case "weapon": case "head": case "chest": case "legs": case "boots": case "hands": search = false; break;
default : search = true;
}
if(search)
for(ItemSlot itemSlot : itemSlots) {
if(itemSlot.getItemID() == inventoryItem.getItemID()) {
itemSlot.setQuantity(itemSlot.getQuantity() + 1);
itemSlot.updateItem();
alreadyExist = true;
break;
}
}
if(!search || !alreadyExist)
for(ItemSlot itemSlot : itemSlots) {
if(itemSlot.getItemID() == -1) {
itemSlot.setItem(inventoryItem, 1);
itemSlot.updateItem();
break;
}
}
}