简体   繁体   中英

Why does the stack size of an item in the inventory not change when used?

Problem :

I have a problem with my program where, when I want to decrease the stack size of an item in the inventory by 1, it doesn't change, when a certain button is pressed (eg 'space').

Expected Result :

What should happen is when 'space' is pressed, the stack size of the current item should change.

Code :

UseItem() :

if (coreEngine.getKeyManager().space) {
        useEnergy(Creature.DEFAULT_ENERGY_COST);
        inventory.useItem(inventory.getCurrentItem(), inventory.getCurrentSelection().getSlotID());
        CEMessage.printMessage("[stackSize]: " + inventory.getCurrentSelection().getCurrentStack());
        //stackSize of currentItem doesn't change when used
}

inventory.useItem() :

public void useItem(Item item, int slotIndex) {
    if (slotsList.get(slotIndex).getItem() == item) {
        slotsList.get(slotIndex).useItem(item); 
    }
}

slot.useItem() :

public void useItem(Item item) {
    currentStack = item.getStackSize();
    currentStack--;
}

getCurrentItem() :

public Item getCurrentItem() {
    return slotsList.get(currentSelection).getItem();
}

getCurrentSelection() :

public Slot getCurrentSelection() {
    return slotsList.get(currentSelection);
}

It is hard to answer without a little bit more of tests. in the following code :

public void useItem(Item item, int slotIndex) {
if (slotsList.get(slotIndex).getItem() == item) {
    System.out.println("reach here ?");
    slotsList.get(slotIndex).useItem(item); 
}}

If it does not print something on the console, it is surely because of slotsList.get(slotIndex).getItem() == item and it would mean that you are comparing two object of the same type but with different references (not the same instance of the class).


EDIT : Answer

Here is the right answer then. There are two steps. First, you go to your Item class and you create a methode like this :

public boolean equals(Item itemToCompare)

. In that method, what you have to do is to compare the value of the common attribute of all the Item objects that differenciate them. For example, if one item has a name, you have to do :

public boolean equals(Item itemToCompare) {
 if (this.name.equals(itemToCompare.name))
    return true;
 else
    return false;
  }

I believe the issue is here.

public void useItem(Item item) {
    currentStack = item.getStackSize();
    currentStack--;
}

Try this

public void useItem(Item item) {
    currentStack = item.getStackSize();
    item.setStackSize(currentStack - 1);
}

Integers are "immutable" which means once they are made they can't be altered. When you do i-- it's making a new Object or int value, not modifying the one that was there. So the stackSize value in item is still pointing at the old value.


Quick example of immutable versus mutable Objects

class MutableFoo {

    private Object bar;

    public void setBar(Object bar) {
        this.bar = bar;
    }

    public Object getBar() {
        return bar;
    }
}

In the above you can modify MutableFoo by using setBar .

class ImmutableFoo {

    private Object bar;

    ImmutableFoo(Object bar) {
        this.bar = bar;
    }

    public Object getBar() {
        return bar;
    }
}

In here however there is no way to modify ImmutableFoo , we can only use the constructor to set bar 's value so if we want to "modify" an ImmutableFoo we need to make a new one.

It's the difference between

Object bar = ...
MutableFoo mFoo = new MutableFoo();
mFoo.setBar(bar);
Object newBar = ...
mFoo.setBar(newBar);

and

Object bar = ...
ImmutableFoo iFoo = new ImmutableFoo(bar);
Object newBar = ...
iFoo = new ImmutableFoo(newBar); // Have to make a new ImmutableFoo.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM