mirror of
https://github.com/Minestom/Minestom.git
synced 2025-02-05 15:01:46 +01:00
ItemEntity can now be merged/stacked together
This commit is contained in:
parent
17856c36cf
commit
889e9c5e2b
@ -690,7 +690,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
|||||||
sendPacketToViewersAndSelf(metaDataPacket);
|
sendPacketToViewersAndSelf(metaDataPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillMetadataIndex(PacketWriter packet, int index) {
|
protected void fillMetadataIndex(PacketWriter packet, int index) {
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0:
|
case 0:
|
||||||
fillStateMetadata(packet);
|
fillStateMetadata(packet);
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
package net.minestom.server.entity;
|
package net.minestom.server.entity;
|
||||||
|
|
||||||
|
import net.minestom.server.event.entity.EntityItemMergeEvent;
|
||||||
|
import net.minestom.server.instance.Chunk;
|
||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
|
import net.minestom.server.item.StackingRule;
|
||||||
import net.minestom.server.network.packet.PacketWriter;
|
import net.minestom.server.network.packet.PacketWriter;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class ItemEntity extends ObjectEntity {
|
public class ItemEntity extends ObjectEntity {
|
||||||
|
|
||||||
private ItemStack itemStack;
|
private ItemStack itemStack;
|
||||||
|
|
||||||
private boolean pickable = true;
|
private boolean pickable = true;
|
||||||
|
|
||||||
private long spawnTime;
|
private long spawnTime;
|
||||||
@ -22,7 +27,51 @@ public class ItemEntity extends ObjectEntity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
|
Chunk chunk = instance.getChunkAt(getPosition());
|
||||||
|
Set<Entity> entities = instance.getChunkEntities(chunk);
|
||||||
|
for (Entity entity : entities) {
|
||||||
|
if (entity instanceof ItemEntity) {
|
||||||
|
|
||||||
|
// Do not merge with itself
|
||||||
|
if (entity == this)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ItemEntity itemEntity = (ItemEntity) entity;
|
||||||
|
if (!itemEntity.isPickable())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Too far, do not merge
|
||||||
|
if (getDistance(itemEntity) > 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
|
synchronized (itemEntity) {
|
||||||
|
ItemStack itemStackEntity = itemEntity.getItemStack();
|
||||||
|
|
||||||
|
StackingRule stackingRule = itemStack.getStackingRule();
|
||||||
|
boolean canStack = stackingRule.canBeStacked(itemStack, itemStackEntity);
|
||||||
|
|
||||||
|
if (!canStack)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int totalAmount = stackingRule.getAmount(itemStack) + stackingRule.getAmount(itemStackEntity);
|
||||||
|
boolean canApply = stackingRule.canApply(itemStack, totalAmount);
|
||||||
|
|
||||||
|
if (!canApply)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
EntityItemMergeEvent entityItemMergeEvent = new EntityItemMergeEvent(this, itemEntity);
|
||||||
|
callCancellableEvent(EntityItemMergeEvent.class, entityItemMergeEvent, () -> {
|
||||||
|
ItemStack result = stackingRule.apply(itemStack.clone(), totalAmount);
|
||||||
|
setItemStack(result);
|
||||||
|
itemEntity.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -39,10 +88,19 @@ public class ItemEntity extends ObjectEntity {
|
|||||||
public Consumer<PacketWriter> getMetadataConsumer() {
|
public Consumer<PacketWriter> getMetadataConsumer() {
|
||||||
return packet -> {
|
return packet -> {
|
||||||
super.getMetadataConsumer().accept(packet);
|
super.getMetadataConsumer().accept(packet);
|
||||||
|
fillMetadataIndex(packet, 7);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void fillMetadataIndex(PacketWriter packet, int index) {
|
||||||
|
super.fillMetadataIndex(packet, index);
|
||||||
|
if (index == 7) {
|
||||||
packet.writeByte((byte) 7);
|
packet.writeByte((byte) 7);
|
||||||
packet.writeByte(METADATA_SLOT);
|
packet.writeByte(METADATA_SLOT);
|
||||||
packet.writeItemStack(itemStack);
|
packet.writeItemStack(itemStack);
|
||||||
};
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -110,6 +110,16 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
|||||||
public Consumer<PacketWriter> getMetadataConsumer() {
|
public Consumer<PacketWriter> getMetadataConsumer() {
|
||||||
return packet -> {
|
return packet -> {
|
||||||
super.getMetadataConsumer().accept(packet);
|
super.getMetadataConsumer().accept(packet);
|
||||||
|
fillMetadataIndex(packet, 7);
|
||||||
|
|
||||||
|
// TODO all remaining metadata
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void fillMetadataIndex(PacketWriter packet, int index) {
|
||||||
|
super.fillMetadataIndex(packet, index);
|
||||||
|
if (index == 7) {
|
||||||
packet.writeByte((byte) 7);
|
packet.writeByte((byte) 7);
|
||||||
packet.writeByte(METADATA_BYTE);
|
packet.writeByte(METADATA_BYTE);
|
||||||
byte activeHandValue = 0;
|
byte activeHandValue = 0;
|
||||||
@ -121,9 +131,7 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
|||||||
activeHandValue += 4;
|
activeHandValue += 4;
|
||||||
}
|
}
|
||||||
packet.writeByte(activeHandValue);
|
packet.writeByte(activeHandValue);
|
||||||
|
}
|
||||||
// TODO all remaining metadata
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package net.minestom.server.event.entity;
|
||||||
|
|
||||||
|
import net.minestom.server.entity.ItemEntity;
|
||||||
|
import net.minestom.server.event.CancellableEvent;
|
||||||
|
|
||||||
|
public class EntityItemMergeEvent extends CancellableEvent {
|
||||||
|
|
||||||
|
private ItemEntity source;
|
||||||
|
private ItemEntity merged;
|
||||||
|
|
||||||
|
public EntityItemMergeEvent(ItemEntity source, ItemEntity merged) {
|
||||||
|
this.source = source;
|
||||||
|
this.merged = merged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemEntity getSource() {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemEntity getMerged() {
|
||||||
|
return merged;
|
||||||
|
}
|
||||||
|
}
|
@ -8,12 +8,36 @@ public abstract class StackingRule {
|
|||||||
this.maxSize = maxSize;
|
this.maxSize = maxSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param item1 the first item
|
||||||
|
* @param item2 the second item
|
||||||
|
* @return true if both item can be stacked together (do not take their amount in consideration)
|
||||||
|
*/
|
||||||
public abstract boolean canBeStacked(ItemStack item1, ItemStack item2);
|
public abstract boolean canBeStacked(ItemStack item1, ItemStack item2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param item the item to check
|
||||||
|
* @param newAmount the desired new amount
|
||||||
|
* @return true if item can have its stack size set to newAmount
|
||||||
|
*/
|
||||||
public abstract boolean canApply(ItemStack item, int newAmount);
|
public abstract boolean canApply(ItemStack item, int newAmount);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* At this point we know that the item can have this stack size
|
||||||
|
*
|
||||||
|
* @param item
|
||||||
|
* @param newAmount
|
||||||
|
* @return the new ItemStack with the new amount
|
||||||
|
*/
|
||||||
public abstract ItemStack apply(ItemStack item, int newAmount);
|
public abstract ItemStack apply(ItemStack item, int newAmount);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to determine the current stack size of an item
|
||||||
|
* It is possible to have it stored in its Data object, lore, etc...
|
||||||
|
*
|
||||||
|
* @param itemStack
|
||||||
|
* @return the correct size of itemStack
|
||||||
|
*/
|
||||||
public abstract int getAmount(ItemStack itemStack);
|
public abstract int getAmount(ItemStack itemStack);
|
||||||
|
|
||||||
public int getMaxSize() {
|
public int getMaxSize() {
|
||||||
|
Loading…
Reference in New Issue
Block a user