Odd MetaData Bug

Started by EB5473, November 15, 2012, 00:25:14

Previous topic - Next topic

EB5473

Hello everyone!
I've been in the process of creating a 2D dungeon crawler for a little while now. I've been able to get entities working, and have started on implementing items/tools. However, i am encountering a small bug that i cannot seem to figure out. For some reason, my metadata variable (used to store damage for tools) is applying to ALL tools vs. just one.
Some code:
The actual "use" statment.
public void onUse(EntityPlayer ent)
	{
		System.out.println("DID SOMEONE CALL ME?");
		//if(ent.inventory.pInv[ent.inventory.selection].item.metadeta < toolMaterial.durability)
		//{
			ent.inventory.pInv[ent.inventory.selection].item.metadeta++;
			System.out.println(ent.inventory.pInv[ent.inventory.selection].item.metadeta);
		
			if(ent.inventory.pInv[ent.inventory.selection].item.metadeta == toolMaterial.durability)
			{
				onBreak();
			}
		//}
		
		//else {
			//onBreak();
		//}
	}

}

The supertype for Items (first deceleration of metadata variable)
package main;

import java.awt.Image;

public class Item {
	
	//public static Item[] itemL = new Item[256];
	public static Item emptyBottle = new ItemBottle(1,"Glass Bottle",0);
	public static Item healthPotion = new ItemBottle(2, "Health Potion", 1);
	public static Item manaPotion = new ItemBottle(3, "Mana Potion", 2);
	public static Item woodSword = new ItemSword(4, "Wood Sword",5,EnumToolMaterials.WOOD);
	public static Item stoneSword = new ItemSword(5, "Stone Sword",5,EnumToolMaterials.STONE);
	public static Item ironSword = new ItemSword(6, "Iron Sword",5,EnumToolMaterials.IRON);
	public static Item gemSword = new ItemSword(7, "Gem Sword",5,EnumToolMaterials.GEM);
	public static Item soulSword = new ItemSword(8, "Soul Sword",5,EnumToolMaterials.SOUL);
	public static Item testSword = new ItemSword(9, "TEST", 0, EnumToolMaterials.TEST);
	
	
	public String name;
	public int ID;
	int metadeta = 0;
	public int force;
	public int r,b,g;
	public static String prefix;
	public int damage;
	public boolean disposable;
	public int maxStack;
	public boolean destroy;

	
	public Item(int index,String name, String Prefix, int damage,int maxStack)
	{
		this.name = name;
		
		ID = index;
		force = 1;
		if(prefix == "")
		{
			prefix = "used";
		}
		else prefix = Prefix;
		destroy = false;
		
		/*itemL[1] = emptyBottle;
		itemL[2] = healthPotion;
		itemL[3] = manaPotion;*/
	}
	public Item(int index,String name,String Prefix) {
		this(index, name, Prefix, 0,64);
	}
	public Item(int index,String name) {
		this(index, name, "",0,64);
	}
	
	public void onUse(EntityPlayer ent) {
		
	}
	
}

Any other code can be provided upon request. Sorry if this isn't clear enough.

TL;DR: Having problems with variables carrying over to independent instances of declared entities!
Thank you very much!
-EB5473
Coder, Mastermind, Friend

Fool Running

Do you mean all tools or just tools of the same type (e.g. all Wood Swords)? If it's all tools of the same type, I can see that since you have statics for each tool which means that whenever you get a Wood Sword you are getting the single static Wood Sword for the entire engine instead of creating a new Wood Sword.
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

EB5473

Oh dear, you are more than likely right! I was using the static declaration as a definition of properties-would I need to create separate files for each type or can I somehow manipulate my current system to be give unique variables for each?
Coder, Mastermind, Friend

Fool Running

Based on the little bit of code I can see, it looks like your existing system should be able to handle it, just make sure that when you add an item to the world, you clone the static copy or create a new one with the same properties.
For example (using Wood Sword) when you add something to the inventory:
Instead of doing
ent.inventory.pInv[index].item = Item.woodSword;

you would instead do
ent.inventory.pInv[index].item = Item.woodSword.clone();

or
ent.inventory.pInv[index].item = new ItemSword(4, "Wood Sword",5,EnumToolMaterials.WOOD);
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

EB5473

I'm currently slightly booked with prior obligations, but as soon as Im finished with them I will try this! I'll post if I have any trouble. Thank you!
Coder, Mastermind, Friend

EB5473

I ran into a few complications.
1. The way the item is being put into the inventory is through a dropped item entity, which holds the "static" reference to the item.
2. I have tried to make a clone function, but it doesn't seem like it wants to cooperate.
My possibly stupid attempt at a clone function-
public Item clone(int ID)
	{
		return itemsl.get(ID);
	}

(twas the only way i could think of)
Sorry if i seem stupid  :-[
-EB5473
Coder, Mastermind, Friend

Fool Running

A clone() function usually makes a clone of the object you call the method on. I assume that the Item class is the base class for all your items (it maybe even should be abstract).
So what you want to do is define a clone() method in Item:
public class Item {

	// All your other code

	public Item clone() {
		Item newItem = new Item(ID, name, prefix, damage, maxStack);
		newItem.metadeta = metadeta;
		newItem.force = force;
		newItem.r = r;
		newItem.b = b;
		newItem.g = g;
		newItem.disposable = disposable;
		newItem.destroy = destroy;
		return newItem;
	}
}

In each of your subclasses (like ItemSword), you would override the clone() method:
public class ItemSword {

	// All your other code

	@Override
	public Item clone() {
		ItemSword newSword = new ItemSword(ID, name, damage, itemMaterial); // Or whatever your constructor takes
		newSword.metadeta = metadeta;
		newSword.force = force;
		newSword.r = r;
		newSword.b = b;
		newSword.g = g;
		newSword.disposable = disposable;
		newSword.destroy = destroy;
		// And whatever else you may need to copy from the ItemSword class
		return newSword;
	}
}


This will allow you to call item.clone() on any of the static items and get a duplicate item of the same type back without having to know what type item really is.
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

EB5473

Sorry it's taken me so long to reply-busy schedules...anyway, this solved the problem through and through. Thank you so much! ;D
Coder, Mastermind, Friend