Item stack size is now defined by ItemSlot, not ItemData
This commit is contained in:
parent
2fe84dc59e
commit
b3ac7b6afe
@ -17,87 +17,32 @@
|
||||
*/
|
||||
package ru.windcorp.progressia.common.world.item;
|
||||
|
||||
import ru.windcorp.progressia.common.state.IntStateField;
|
||||
import ru.windcorp.progressia.common.state.StatefulObject;
|
||||
import ru.windcorp.progressia.common.world.generic.ItemGeneric;
|
||||
|
||||
/**
|
||||
* A collection of identical items identified by their ID, properties and
|
||||
* amount, able to reside in a slot. Also known as an item stack.
|
||||
* <p>
|
||||
* An empty stack does not have an {@code ItemData} representation; stack size
|
||||
* is at least 1.
|
||||
* An item identified by its ID and properties, able to reside in a slot.
|
||||
*/
|
||||
public abstract class ItemData extends StatefulObject implements ItemGeneric {
|
||||
|
||||
private final IntStateField size = field("Core:Size").setShared().ofInt().build();
|
||||
|
||||
public ItemData(String id) {
|
||||
super(ItemDataRegistry.getInstance(), id);
|
||||
size.setNow(this, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of individual items represented by this item stack.
|
||||
* Computes and returns the mass of a single unit (single item) of this
|
||||
* item.
|
||||
*
|
||||
* @return the size of this stack
|
||||
* @return the mass of this item
|
||||
*/
|
||||
public final int getSize() {
|
||||
return size.get(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount of items represented by this item stack.
|
||||
*
|
||||
* @param size the new size of this stack, strictly positive
|
||||
*/
|
||||
public final void setSizeNow(int size) {
|
||||
if (size <= 0) {
|
||||
throw new IllegalArgumentException("size cannot be negative, given size " + size);
|
||||
}
|
||||
this.size.setNow(this, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes and returns the total mass of this item stack. It is defined as
|
||||
* the item's unit mass (see {@link #getUnitMass()}) multiplied by the
|
||||
* amount of items in the stack.
|
||||
*
|
||||
* @return the mass of this stack
|
||||
* @see #getUnitMass()
|
||||
*/
|
||||
public final float getMass() {
|
||||
return getUnitMass() * getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes and returns the mass of a single unit (single item) of this item
|
||||
* stack.
|
||||
*
|
||||
* @return the mass of a single item in this stack
|
||||
* @see #getMass()
|
||||
*/
|
||||
public abstract float getUnitMass();
|
||||
|
||||
/**
|
||||
* Computes and returns the total volume of this item stack. It is defined
|
||||
* as the item's unit volume (see {@link #getUnitVolume()}) multiplied by
|
||||
* the amount of items in the stack.
|
||||
*
|
||||
* @return the mass of this stack
|
||||
* @see #getUnitVolume()
|
||||
*/
|
||||
public final float getVolume() {
|
||||
return getUnitVolume() * getSize();
|
||||
}
|
||||
public abstract float getMass();
|
||||
|
||||
/**
|
||||
* Computes and returns the volume of a single unit (single item) of this
|
||||
* item stack.
|
||||
*
|
||||
* @return the volume of a single item in this stack
|
||||
* @see #getVolume()
|
||||
* @return the volume of this item
|
||||
*/
|
||||
public abstract float getUnitVolume();
|
||||
public abstract float getVolume();
|
||||
|
||||
}
|
||||
|
@ -19,23 +19,23 @@ package ru.windcorp.progressia.common.world.item;
|
||||
|
||||
public class ItemDataSimple extends ItemData {
|
||||
|
||||
private final float unitMass;
|
||||
private final float unitVolume;
|
||||
private final float mass;
|
||||
private final float volume;
|
||||
|
||||
public ItemDataSimple(String id, float unitMass, float unitVolume) {
|
||||
public ItemDataSimple(String id, float mass, float volume) {
|
||||
super(id);
|
||||
this.unitMass = unitMass;
|
||||
this.unitVolume = unitVolume;
|
||||
this.mass = mass;
|
||||
this.volume = volume;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getUnitMass() {
|
||||
return unitMass;
|
||||
public float getMass() {
|
||||
return mass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getUnitVolume() {
|
||||
return unitVolume;
|
||||
public float getVolume() {
|
||||
return volume;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ import ru.windcorp.progressia.common.state.IOContext;
|
||||
public class ItemSlot implements Encodable {
|
||||
|
||||
private ItemData contents;
|
||||
private int amount;
|
||||
|
||||
/**
|
||||
* Retrieves the contents of this slot.
|
||||
@ -43,29 +44,87 @@ public class ItemSlot implements Encodable {
|
||||
|
||||
/**
|
||||
* Sets the new contents of this slot. If an item stack was present
|
||||
* previously, it is discarded.
|
||||
* previously, it is discarded. If the contents are {@code null}, the slot
|
||||
* is emptied.
|
||||
* <p>
|
||||
* When the slot receives non-null contents, the new amount must be a
|
||||
* positive integer. When the slot is emptied, {@code amount} must be 0.
|
||||
*
|
||||
* @param contents the new contents of this slot or {@code null} to clear
|
||||
* the slot
|
||||
* @param amount the amount of items to set.
|
||||
* {@code (amount == 0) == (contents == null)} must be true.
|
||||
*/
|
||||
public synchronized final void setContents(ItemData contents) {
|
||||
public synchronized final void setContents(ItemData contents, int amount) {
|
||||
this.contents = contents;
|
||||
this.amount = amount;
|
||||
|
||||
checkState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount of items stored in this slot.
|
||||
* <p>
|
||||
* Setting the amount to zero also erases the slot's contents.
|
||||
*
|
||||
* @param amount the new amount
|
||||
*/
|
||||
public synchronized void setAmount(int amount) {
|
||||
setContents(amount == 0 ? null : contents, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears this slot
|
||||
*/
|
||||
public synchronized void clear() {
|
||||
setContents(null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the amount of items stored in this slot. If not items are
|
||||
* present, this returns 0.
|
||||
*
|
||||
* @return the amount of items stored
|
||||
*/
|
||||
public synchronized int getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public synchronized boolean isEmpty() {
|
||||
return amount == 0;
|
||||
}
|
||||
|
||||
private synchronized void checkState() {
|
||||
if ((contents == null) != (amount == 0)) {
|
||||
if (contents == null) {
|
||||
throw new IllegalArgumentException("Contents is null but amount (" + amount + ") != 0");
|
||||
} else {
|
||||
throw new IllegalArgumentException("Contents is " + contents + " but amount is zero");
|
||||
}
|
||||
}
|
||||
|
||||
if (amount < 0) {
|
||||
throw new IllegalArgumentException("amount is negative: " + amount);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void read(DataInput input, IOContext context) throws IOException {
|
||||
if (input.readBoolean()) {
|
||||
amount = input.readInt();
|
||||
if (amount != 0) {
|
||||
String id = input.readUTF();
|
||||
contents = ItemDataRegistry.getInstance().create(id);
|
||||
contents.read(input, context);
|
||||
} else {
|
||||
contents = null;
|
||||
}
|
||||
|
||||
checkState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void write(DataOutput output, IOContext context) throws IOException {
|
||||
output.writeBoolean(contents != null);
|
||||
output.writeInt(amount);
|
||||
if (contents != null) {
|
||||
output.writeUTF(contents.getId());
|
||||
contents.write(output, context);
|
||||
@ -76,6 +135,8 @@ public class ItemSlot implements Encodable {
|
||||
public void copy(Encodable destination) {
|
||||
ItemSlot slot = (ItemSlot) destination;
|
||||
|
||||
slot.amount = this.amount;
|
||||
|
||||
if (this.contents == null) {
|
||||
slot.contents = null;
|
||||
} else {
|
||||
|
@ -27,7 +27,6 @@ import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||
import ru.windcorp.progressia.common.world.entity.EntityDataPlayer;
|
||||
import ru.windcorp.progressia.common.world.entity.EntityDataRegistry;
|
||||
import ru.windcorp.progressia.common.world.item.ItemData;
|
||||
import ru.windcorp.progressia.common.world.item.ItemDataRegistry;
|
||||
import ru.windcorp.progressia.server.events.PlayerJoinedEvent;
|
||||
import ru.windcorp.progressia.test.TestContent;
|
||||
@ -66,16 +65,8 @@ public class PlayerManager {
|
||||
|
||||
player.getInventory().addSlots(10);
|
||||
|
||||
ItemData stack = ItemDataRegistry.getInstance().create("Test:MoonTypeIceCream");
|
||||
stack.setSizeNow(5);
|
||||
player.getInventory().getSlot(3).setContents(stack);
|
||||
|
||||
player.getInventory().getSlot(6).setContents(ItemDataRegistry.getInstance().create("Test:MoonTypeIceCream"));
|
||||
|
||||
player.getLeftHand().getSlot(0).setContents(ItemDataRegistry.getInstance().create("Test:MoonTypeIceCream"));
|
||||
stack = ItemDataRegistry.getInstance().create("Test:MoonTypeIceCream");
|
||||
stack.setSizeNow(64);
|
||||
player.getRightHand().getSlot(0).setContents(stack);
|
||||
player.getInventory().getSlot(3).setContents(ItemDataRegistry.getInstance().create("Test:MoonTypeIceCream"), 5);
|
||||
player.getInventory().getSlot(6).setContents(ItemDataRegistry.getInstance().create("Test:MoonTypeIceCream"), 1);
|
||||
|
||||
player.setPosition(getServer().getWorld().getGenerator().suggestSpawnLocation());
|
||||
player.setUpVector(new Vec3(0, 0, 1));
|
||||
|
@ -148,10 +148,13 @@ public class InventoryScreen extends Component {
|
||||
ItemSlot from = ((DecoratedSlotComponent) button).getSlot();
|
||||
|
||||
ItemData fromData = from.getContents();
|
||||
ItemData toData = to.getContents();
|
||||
int fromAmount = from.getAmount();
|
||||
|
||||
from.setContents(toData);
|
||||
to.setContents(fromData);
|
||||
ItemData toData = to.getContents();
|
||||
int toAmount = to.getAmount();
|
||||
|
||||
from.setContents(toData, toAmount);
|
||||
to.setContents(fromData, fromAmount);
|
||||
|
||||
requestReassembly();
|
||||
|
||||
|
@ -39,8 +39,8 @@ public class SlotComponent extends Component {
|
||||
|
||||
private ItemRenderable itemRenderer = null;
|
||||
|
||||
private int sizeDisplayInt = 0;
|
||||
private String sizeDisplayString = "";
|
||||
private int amountDisplayInt = 0;
|
||||
private String amountDisplayString = "";
|
||||
|
||||
public SlotComponent(String name, ItemContainer container, int index) {
|
||||
super(name);
|
||||
@ -51,7 +51,7 @@ public class SlotComponent extends Component {
|
||||
setPreferredSize(side, side);
|
||||
|
||||
Font sizeFont = new Font().deriveOutlined().withScale(1);
|
||||
addChild(new DynamicLabel(name + ".Size", sizeFont, () -> sizeDisplayString, side));
|
||||
addChild(new DynamicLabel(name + ".Size", sizeFont, () -> amountDisplayString, side));
|
||||
|
||||
setLayout(new LayoutAlign(0, 0, 0));
|
||||
}
|
||||
@ -74,17 +74,17 @@ public class SlotComponent extends Component {
|
||||
|
||||
if (contents == null) {
|
||||
itemRenderer = null;
|
||||
sizeDisplayInt = 0;
|
||||
sizeDisplayString = "";
|
||||
amountDisplayInt = 0;
|
||||
amountDisplayString = "";
|
||||
} else {
|
||||
if (itemRenderer == null || itemRenderer.getData() != contents) {
|
||||
itemRenderer = ItemRenderRegistry.getInstance().get(contents.getId()).createRenderable(contents);
|
||||
}
|
||||
|
||||
int newSize = contents.getSize();
|
||||
if (newSize != sizeDisplayInt) {
|
||||
sizeDisplayInt = newSize;
|
||||
sizeDisplayString = newSize == 1 ? "" : Integer.toString(newSize);
|
||||
int newAmount = getSlot().getAmount();
|
||||
if (newAmount != amountDisplayInt) {
|
||||
amountDisplayInt = newAmount;
|
||||
amountDisplayString = newAmount == 1 ? "" : Integer.toString(newAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user