From b3ac7b6afe7fe74e9d5caaa722ea031725a62877 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Sat, 28 Aug 2021 21:07:08 +0300 Subject: [PATCH] Item stack size is now defined by ItemSlot, not ItemData --- .../common/world/item/ItemData.java | 69 ++----------------- .../common/world/item/ItemDataSimple.java | 18 ++--- .../common/world/item/ItemSlot.java | 69 +++++++++++++++++-- .../progressia/server/PlayerManager.java | 13 +--- .../progressia/test/inv/InventoryScreen.java | 7 +- .../progressia/test/inv/SlotComponent.java | 18 ++--- 6 files changed, 97 insertions(+), 97 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/ItemData.java b/src/main/java/ru/windcorp/progressia/common/world/item/ItemData.java index dcd844e..6a7a45c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/item/ItemData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/item/ItemData.java @@ -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. - *

- * 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(); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/ItemDataSimple.java b/src/main/java/ru/windcorp/progressia/common/world/item/ItemDataSimple.java index 68a366e..f7c353f 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/item/ItemDataSimple.java +++ b/src/main/java/ru/windcorp/progressia/common/world/item/ItemDataSimple.java @@ -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; } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/item/ItemSlot.java b/src/main/java/ru/windcorp/progressia/common/world/item/ItemSlot.java index 1baa70a..390266c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/item/ItemSlot.java +++ b/src/main/java/ru/windcorp/progressia/common/world/item/ItemSlot.java @@ -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. + *

+ * 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. + *

+ * 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 { diff --git a/src/main/java/ru/windcorp/progressia/server/PlayerManager.java b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java index abcc8d6..dd07d60 100644 --- a/src/main/java/ru/windcorp/progressia/server/PlayerManager.java +++ b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java @@ -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)); diff --git a/src/main/java/ru/windcorp/progressia/test/inv/InventoryScreen.java b/src/main/java/ru/windcorp/progressia/test/inv/InventoryScreen.java index d227c91..dbbdce1 100644 --- a/src/main/java/ru/windcorp/progressia/test/inv/InventoryScreen.java +++ b/src/main/java/ru/windcorp/progressia/test/inv/InventoryScreen.java @@ -148,10 +148,13 @@ public class InventoryScreen extends Component { ItemSlot from = ((DecoratedSlotComponent) button).getSlot(); ItemData fromData = from.getContents(); + int fromAmount = from.getAmount(); + ItemData toData = to.getContents(); + int toAmount = to.getAmount(); - from.setContents(toData); - to.setContents(fromData); + from.setContents(toData, toAmount); + to.setContents(fromData, fromAmount); requestReassembly(); diff --git a/src/main/java/ru/windcorp/progressia/test/inv/SlotComponent.java b/src/main/java/ru/windcorp/progressia/test/inv/SlotComponent.java index 4e081e1..2cb13ba 100644 --- a/src/main/java/ru/windcorp/progressia/test/inv/SlotComponent.java +++ b/src/main/java/ru/windcorp/progressia/test/inv/SlotComponent.java @@ -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); } } }