Item stack size is now defined by ItemSlot, not ItemData

This commit is contained in:
OLEGSHA 2021-08-28 21:07:08 +03:00
parent 2fe84dc59e
commit b3ac7b6afe
Signed by: OLEGSHA
GPG Key ID: E57A4B08D64AFF7A
6 changed files with 97 additions and 97 deletions

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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 {

View File

@ -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));

View File

@ -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();

View File

@ -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);
}
}
}