In my little text game I have an Item class that loads it’s objects from a .txt file and then adds the object to an ArrayList of type Item. I’m trying to upgrade using an upgrade() method in the Item class. It works but if I have two of the same items in my inventory, since they reference the same item if I upgrade one, I upgrade all items of that type.
Is there a way to create a new Item (Bronze Helmet) that when created will be the same as the Bronze Helmet loaded from the text file, but when upgraded it doesn’t change the original object in the static helmet ArrayList in Item.java.
openInventory() method from Player class:
public void openInventory(){
//newWindow();
int selection;
boolean upgraded = false;
backPack.printInventory(this);
println("[1] UseItem [2] Upgrade Item [3] Item Details");
selection = getInt();
if(selection == 1){
println("Type the number of the corresponding Item Slot you would like to use.");
int itemNum = (getInt() - 1);
Item itemSelection = backPack.itemSlot[itemNum].oi;
if(backPack.itemSlot[itemNum].stack.size() > 0){
itemSelection = backPack.itemSlot[itemNum].stack.get(0);
}
itemSelection.printStats();
this.useItem(itemSelection);
}
if(selection == 2){
int sInt;
Item scroll = new Item();
Item item = new Item();
while(upgraded == false){
println("Pick a scroll");
sInt = getInt();
if(backPack.itemSlot[sInt - 1].oi.type.equals("scroll")){
scroll = backPack.itemSlot[sInt - 1].oi;
}
else
println("Not a Scroll");
println("Pick which " + scroll.category + " to upgrade.");
sInt = getInt();
if(backPack.itemSlot[sInt - 1].oi.type.equals(scroll.category)){
item = backPack.itemSlot[sInt - 1].oi;
}
else
println("Wrong type of Item");
if(scroll.name != "None" && item.name != "None"){
backPack.itemSlot[sInt - 1].oi.upgrade(scroll);
upgraded = true;
}
}
}
if(selection == 3){
println("Pick item to display details.");
int i = getInt();
backPack.itemSlot[i - 1].oi.printStats();
}
}
Inventory after upgrading one of the ‘Bronze Helmets’
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
[1] Bronze Helmet [+1] [2] Bronze Helmet [+1] [3] Helmet Def Scroll [4] None [5] None
[6] None [7] None [8] None [9] None [10] None
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
[Gold]: $50
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
Item.java:
import static com.projects.aoa.Print.*;
import static com.projects.aoa.Input.*;
import java.util.*;
import java.io.*;
class Item {
//Item
String name, type, category, statUpgrade;
int remSlots, maxSlots, upgraded, probability, statIncrease;
int hp, mp, str, def, atk, dex, duration;
Area shopPurchased;
//Inventory
public boolean filled;
public int count, stackLimit;
public static List<Item> helmets = new ArrayList<Item>();
public static List<Item> potions = new ArrayList<Item>();
public static List<Item> swords = new ArrayList<Item>();
public static List<Item> scrolls = new ArrayList<Item>();
Item(){
name = "None";
maxSlots = 5;
remSlots = 5;
}
public String toString(){
return (name);
}
static void loadItems(){
try {
//System.out.println(System.getProperty("user.dir"));
FileInputStream fstream = new FileInputStream(System.getProperty("user.dir")
+ "/LoadFiles/" + "itemLoad.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line, itemType = "none";
int counter = 0;
Item newItem = new Item();
while((line = br.readLine()) != null) {
if(line.length() == 0){
newItem.printStats();
if(itemType.equals("helmet")){
helmets.add(newItem);
}
if(itemType.equals("potion")){
potions.add(newItem);
}
if(itemType.equals("sword")){
swords.add(newItem);
}
if(itemType.equals("scroll")){
scrolls.add(newItem);
}
counter = -1;
}
if(line.equals("#"))
break;
switch(counter) {
case -1:
counter++;
break;
case 0:
itemType = line;
counter++;
break;
case 1:
if(itemType.equals("helmet")){
//tempName = line;
newItem = new Helmet(line);
newItem.type = itemType;
}
if(itemType.equals("potion")){
newItem = new Potion(line);
newItem.type = itemType;
}
if(itemType.equals("sword")){
newItem = new Sword(line);
newItem.type = itemType;
}
if(itemType.equals("scroll")){
newItem = new Scroll(line);
newItem.type = itemType;
counter = 9;
}
counter++;
break;
case 2:
newItem.hp = Integer.parseInt(line);
counter++;
break;
case 3:
newItem.mp = Integer.parseInt(line);
counter++;
break;
case 4:
newItem.def = Integer.parseInt(line);
counter++;
break;
case 5:
newItem.str = Integer.parseInt(line);
counter++;
break;
case 6:
newItem.atk = Integer.parseInt(line);
counter++;
break;
case 7:
newItem.dex = Integer.parseInt(line);
counter++;
break;
case 8:
newItem.stackLimit = Integer.parseInt(line);
counter++;
break;
case 9:
newItem.duration = Integer.parseInt(line);
counter++;
break;
case 10:
newItem.category = line;
counter++;
break;
case 11:
newItem.statUpgrade = line;
counter++;
break;
case 12:
newItem.statIncrease = Integer.parseInt(line);
counter++;
break;
case 13:
newItem.probability = Integer.parseInt(line);
counter++;
break;
}
}
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
void printStats(){
line();
println("[" + name + "]");
println("Type: " + type);
println("Stack Limit: " + stackLimit);
println("Duration: " + duration);
println("HP: " + hp);
println("MP: " + mp);
println("Def: " + def);
println("Str: " + str);
println("Atk: " + atk);
println("Dex: " + dex);
}
void upgrade(Item scroll){
Random rand = new Random();
int geti;
if(remSlots > 0){
if(this.type.equals(scroll.category)){
int prob = rand.nextInt(99);
println("Prob: " + prob);
if(prob < scroll.probability){
if(scroll.statUpgrade.equals("def")){
this.def += scroll.statIncrease;
this.upgraded++;
println("Upgraded: " + this.upgraded);
}
}
remSlots--;
println("Slots: " + this.remSlots + " / " + this.maxSlots);
}
}
else
println("No slots remaining.");
}
static Item getItem(String searchedName){
Item item = new Item();
for(int i = 0; i < potions.size(); i++){
if(potions.get(i).name.equals(searchedName)){
item = potions.get(i);
return item;
}
}
for(int i = 0; i < helmets.size(); i++){
if(helmets.get(i).name.equals(searchedName)){
item = helmets.get(i);
return item;
}
}
for(int i = 0; i < swords.size(); i++){
if(swords.get(i).name.equals(searchedName)){
item = swords.get(i);
return item;
}
}
for(int i = 0; i < scrolls.size(); i++){
if(scrolls.get(i).name.equals(searchedName)){
item = scrolls.get(i);
return item;
}
}
return item;
}
}
Inventory:
public class Inventory {
int useableSlots, slots = 50;
Itemslot[] itemSlot = new Itemslot[slots];
Inventory(int slots){
this.useableSlots = slots;
}
public void printInventory(Player playerOne){
newWindow(5);
int excess, lineTotal = 0, invSlotSize = 25, maxLineLength = 125;
String invItem, difference = "";
String inventoryTitle = "[" + playerOne.name + "'s BackPack]";
String invTitleIndent = "";
for(int i = 0; i < (maxLineLength - inventoryTitle.length()) / 2; i++){
invTitleIndent += " ";
}
println(invTitleIndent + inventoryTitle);
printMult("—", maxLineLength);
line();
for(int i = 0; i < useableSlots; i++){
if(lineTotal >= maxLineLength){
line();
lineTotal = 0;
line();
}
if(i < 9){
difference = " ";
}
else{
difference = "";
}
invItem = ("[" + (i + 1) + "] " + difference);
if(itemSlot[i].stack.size() > 0){
invItem += (itemSlot[i].stack.get(0).name + "(" + itemSlot[i].stack.size() + ")");
}
else {
invItem += itemSlot[i].oi.name;
if(itemSlot[i].oi.upgraded > 0){
invItem += " [+" + itemSlot[i].oi.upgraded + "]";
}
}
excess = (invSlotSize - invItem.length());
for(int v = 0; v < excess; v++){
invItem += " ";
}
//print(invItem.length());
print(invItem);
lineTotal += invItem.length();
}
line();
printMult("—", maxLineLength);
line();
String printGold = "[Gold]: $" + playerOne.gold;
String goldIndent = "";
for(int i = 0; i < (maxLineLength - printGold.length()) / 2; i++){
goldIndent += " ";
}
println(goldIndent + printGold);
printMult("—", maxLineLength);
line();
line(2);
}
void addItem(Item item){
for (int i = 0; i < useableSlots; i++){
if (itemSlot[i].occupied == false) {
itemSlot[i].oi = item;
itemSlot[i].occupied = true;
break;
}
}
}
ItemSlot:
public class Itemslot extends Item{
List<Item> stack = new ArrayList<Item>();
Item oi = new Item();
boolean occupied;
}
It could very likely just be me being stupid but any help on solving this, or what direction to take would be appreciated.
EDIT: Solved
added copy constructor to Item
Item(Item item){
this.name = item.name;
this.type = item.type;
this.category = item.category;
this.statUpgrade = item.statUpgrade;
this.remSlots = item.remSlots;
this.maxSlots = item.maxSlots;
this.upgraded = item.upgraded;
this.probability = item.probability;
this.statIncrease = item.statIncrease;
this.hp = item.hp;
this.mp = item.mp;
this.str = item.str;
this.def = item.def;
this.atk = item.atk;
this.dex = item.dex;
this.duration = item.duration;
}
changed addItem
void addItem(Item item){
Item newItem = new Item(item);
for (int i = 0; i < useableSlots; i++){
if (itemSlot[i].occupied == false) {
itemSlot[i].oi = newItem;
itemSlot[i].occupied = true;
break;
}
}
}
The recommended way for copying objects according to Effective Java 2 is provide a copy constructor
Note that the
clonemethod is broken in Java, according to the same book.I think that your approach is wrong, instead you can write your object to a data file using ObjectInputStream and ObjectOutputStream