dropped items merge
This commit is contained in:
@@ -4,10 +4,15 @@ import org.bukkit.Bukkit;
|
|||||||
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||||
import org.bukkit.event.player.PlayerPickupItemEvent;
|
import org.bukkit.event.player.PlayerPickupItemEvent;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class EntityItem extends Entity {
|
public class EntityItem extends Entity {
|
||||||
|
|
||||||
|
private static final double MERGE_RADIUS = 5.0D;
|
||||||
|
private static final double MERGE_RADIUS_SQUARED = MERGE_RADIUS * MERGE_RADIUS;
|
||||||
|
private static final int MERGE_INTERVAL_TICKS = 10;
|
||||||
|
|
||||||
public ItemStack itemStack;
|
public ItemStack itemStack;
|
||||||
private int e;
|
private int e;
|
||||||
public int b = 0;
|
public int b = 0;
|
||||||
@@ -100,6 +105,13 @@ public class EntityItem extends Entity {
|
|||||||
|
|
||||||
++this.e;
|
++this.e;
|
||||||
++this.b;
|
++this.b;
|
||||||
|
|
||||||
|
// Merge only settled items. This avoids combining drops while they are still
|
||||||
|
// being thrown, while keeping large piles from creating excess entities.
|
||||||
|
if (this.onGround && this.b % MERGE_INTERVAL_TICKS == 0) {
|
||||||
|
this.mergeNearbyItems();
|
||||||
|
}
|
||||||
|
|
||||||
if (this.b >= 6000) {
|
if (this.b >= 6000) {
|
||||||
//Project Poseidon Start
|
//Project Poseidon Start
|
||||||
if (CraftEventFactory.callItemDespawnEvent(this).isCancelled()) {
|
if (CraftEventFactory.callItemDespawnEvent(this).isCancelled()) {
|
||||||
@@ -111,6 +123,51 @@ public class EntityItem extends Entity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merges compatible, grounded item entities within {@link #MERGE_RADIUS} blocks.
|
||||||
|
* The item count is never allowed to exceed the item's normal stack limit.
|
||||||
|
*/
|
||||||
|
private void mergeNearbyItems() {
|
||||||
|
if (this.dead || !this.itemStack.isStackable() || this.itemStack.count >= this.itemStack.getMaxStackSize()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List nearbyItems = this.world.a(EntityItem.class, this.boundingBox.b(MERGE_RADIUS, MERGE_RADIUS, MERGE_RADIUS));
|
||||||
|
|
||||||
|
for (int i = 0; i < nearbyItems.size() && this.itemStack.count < this.itemStack.getMaxStackSize(); ++i) {
|
||||||
|
EntityItem nearbyItem = (EntityItem) nearbyItems.get(i);
|
||||||
|
|
||||||
|
if (nearbyItem == this || nearbyItem.dead || !nearbyItem.onGround
|
||||||
|
|| !this.itemStack.doMaterialsMatch(nearbyItem.itemStack)
|
||||||
|
|| !nearbyItem.itemStack.isStackable()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
double deltaX = this.locX - nearbyItem.locX;
|
||||||
|
double deltaY = this.locY - nearbyItem.locY;
|
||||||
|
double deltaZ = this.locZ - nearbyItem.locZ;
|
||||||
|
if (deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ > MERGE_RADIUS_SQUARED) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int transfer = Math.min(this.itemStack.getMaxStackSize() - this.itemStack.count, nearbyItem.itemStack.count);
|
||||||
|
if (transfer <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.itemStack.count += transfer;
|
||||||
|
nearbyItem.itemStack.count -= transfer;
|
||||||
|
|
||||||
|
// Preserve the stricter expiry and pickup delay when two piles combine.
|
||||||
|
this.b = Math.max(this.b, nearbyItem.b);
|
||||||
|
this.pickupDelay = Math.max(this.pickupDelay, nearbyItem.pickupDelay);
|
||||||
|
|
||||||
|
if (nearbyItem.itemStack.count <= 0) {
|
||||||
|
nearbyItem.die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean f_() {
|
public boolean f_() {
|
||||||
return this.world.a(this.boundingBox, Material.WATER, this);
|
return this.world.a(this.boundingBox, Material.WATER, this);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user