mirror of
https://github.com/PaperMC/Paper.git
synced 2025-08-01 04:32:11 -07:00
Part of block entities
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
--- a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
||||
@@ -21,6 +_,40 @@
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
|
||||
+ // CraftBukkit start - add fields and methods
|
||||
+ public java.util.List<org.bukkit.entity.HumanEntity> transaction = new java.util.ArrayList<>();
|
||||
+ private int maxStack = MAX_STACK;
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.List<ItemStack> getContents() {
|
||||
+ return this.items;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onOpen(org.bukkit.craftbukkit.entity.CraftHumanEntity who) {
|
||||
+ this.transaction.add(who);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onClose(org.bukkit.craftbukkit.entity.CraftHumanEntity who) {
|
||||
+ this.transaction.remove(who);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.List<org.bukkit.entity.HumanEntity> getViewers() {
|
||||
+ return this.transaction;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getMaxStackSize() {
|
||||
+ return this.maxStack;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setMaxStackSize(int i) {
|
||||
+ this.maxStack = i;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
private NonNullList<ItemStack> items = NonNullList.withSize(27, ItemStack.EMPTY);
|
||||
private final ContainerOpenersCounter openersCounter = new ContainerOpenersCounter() {
|
||||
@Override
|
@@ -0,0 +1,62 @@
|
||||
--- a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
|
||||
@@ -68,17 +_,44 @@
|
||||
protected abstract Component getDefaultName();
|
||||
|
||||
public boolean canOpen(Player player) {
|
||||
- return canUnlock(player, this.lockKey, this.getDisplayName());
|
||||
+ return canUnlock(player, this.lockKey, this.getDisplayName(), this); // Paper - Add BlockLockCheckEvent
|
||||
}
|
||||
|
||||
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - Add BlockLockCheckEvent
|
||||
public static boolean canUnlock(Player player, LockCode code, Component displayName) {
|
||||
+ // Paper start - Add BlockLockCheckEvent
|
||||
+ return canUnlock(player, code, displayName, null);
|
||||
+ }
|
||||
+ public static boolean canUnlock(Player player, LockCode code, Component displayName, @Nullable BlockEntity blockEntity) {
|
||||
+ if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer && blockEntity != null && blockEntity.getLevel() != null && blockEntity.getLevel().getBlockEntity(blockEntity.getBlockPos()) == blockEntity) {
|
||||
+ final org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(blockEntity.getLevel(), blockEntity.getBlockPos());
|
||||
+ net.kyori.adventure.text.Component lockedMessage = net.kyori.adventure.text.Component.translatable("container.isLocked", io.papermc.paper.adventure.PaperAdventure.asAdventure(displayName));
|
||||
+ net.kyori.adventure.sound.Sound lockedSound = net.kyori.adventure.sound.Sound.sound(org.bukkit.Sound.BLOCK_CHEST_LOCKED, net.kyori.adventure.sound.Sound.Source.BLOCK, 1.0F, 1.0F);
|
||||
+ final io.papermc.paper.event.block.BlockLockCheckEvent event = new io.papermc.paper.event.block.BlockLockCheckEvent(block, serverPlayer.getBukkitEntity(), lockedMessage, lockedSound);
|
||||
+ event.callEvent();
|
||||
+ if (event.getResult() == org.bukkit.event.Event.Result.ALLOW) {
|
||||
+ return true;
|
||||
+ } else if (event.getResult() == org.bukkit.event.Event.Result.DENY || (!player.isSpectator() && !code.unlocksWith(event.isUsingCustomKeyItemStack() ? org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getKeyItem()) : player.getMainHandItem()))) {
|
||||
+ if (event.getLockedMessage() != null) {
|
||||
+ event.getPlayer().sendActionBar(event.getLockedMessage());
|
||||
+ }
|
||||
+ if (event.getLockedSound() != null) {
|
||||
+ event.getPlayer().playSound(event.getLockedSound());
|
||||
+ }
|
||||
+ return false;
|
||||
+ } else {
|
||||
+ return true;
|
||||
+ }
|
||||
+ } else { // logic below is replaced by logic above
|
||||
+ // Paper end - Add BlockLockCheckEvent
|
||||
if (!player.isSpectator() && !code.unlocksWith(player.getMainHandItem())) {
|
||||
- player.displayClientMessage(Component.translatable("container.isLocked", displayName), true);
|
||||
+ player.displayClientMessage(Component.translatable("container.isLocked", displayName), true); // Paper - diff on change
|
||||
player.playNotifySound(SoundEvents.CHEST_LOCKED, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
+ } // Paper - Add BlockLockCheckEvent
|
||||
}
|
||||
|
||||
protected abstract NonNullList<ItemStack> getItems();
|
||||
@@ -166,4 +_,12 @@
|
||||
tag.remove("lock");
|
||||
tag.remove("Items");
|
||||
}
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+ @Override
|
||||
+ public org.bukkit.Location getLocation() {
|
||||
+ if (this.level == null) return null;
|
||||
+ return new org.bukkit.Location(this.level.getWorld(), this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ());
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
--- a/net/minecraft/world/level/block/entity/BellBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/BellBlockEntity.java
|
||||
@@ -60,6 +_,11 @@
|
||||
|
||||
if (blockEntity.ticks >= 50) {
|
||||
blockEntity.shaking = false;
|
||||
+ // Paper start - Fix bell block entity memory leak
|
||||
+ if (!blockEntity.resonating) {
|
||||
+ blockEntity.nearbyEntities.clear();
|
||||
+ }
|
||||
+ // Paper end - Fix bell block entity memory leak
|
||||
blockEntity.ticks = 0;
|
||||
}
|
||||
|
||||
@@ -73,6 +_,7 @@
|
||||
blockEntity.resonationTicks++;
|
||||
} else {
|
||||
resonationEndAction.run(level, pos, blockEntity.nearbyEntities);
|
||||
+ blockEntity.nearbyEntities.clear(); // Paper - Fix bell block entity memory leak
|
||||
blockEntity.resonating = false;
|
||||
}
|
||||
}
|
||||
@@ -113,6 +_,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+ this.nearbyEntities.removeIf(e -> !e.isAlive()); // Paper - Fix bell block entity memory leak
|
||||
}
|
||||
|
||||
private static boolean areRaidersNearby(BlockPos pos, List<LivingEntity> raiders) {
|
||||
@@ -129,7 +_,10 @@
|
||||
}
|
||||
|
||||
private static void makeRaidersGlow(Level level, BlockPos pos, List<LivingEntity> raiders) {
|
||||
- raiders.stream().filter(raider -> isRaiderWithinRange(pos, raider)).forEach(BellBlockEntity::glow);
|
||||
+ // Paper start - call bell resonate event and bell reveal raider event
|
||||
+ final List<org.bukkit.entity.LivingEntity> inRangeRaiders = raiders.stream().filter(raider -> isRaiderWithinRange(pos, raider)).map(e -> e.getBukkitEntity()).toList();
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBellResonateEvent(level, pos, inRangeRaiders).forEach(e -> glow(e, pos));
|
||||
+ // Paper end - call bell resonate event and bell reveal raider event
|
||||
}
|
||||
|
||||
private static void showBellParticles(Level level, BlockPos pos, List<LivingEntity> raiders) {
|
||||
@@ -159,7 +_,16 @@
|
||||
return raider.isAlive() && !raider.isRemoved() && pos.closerToCenterThan(raider.position(), 48.0) && raider.getType().is(EntityTypeTags.RAIDERS);
|
||||
}
|
||||
|
||||
+ @io.papermc.paper.annotation.DoNotUse // Paper - Add BellRevealRaiderEvent
|
||||
private static void glow(LivingEntity entity) {
|
||||
+ // Paper start - Add BellRevealRaiderEvent
|
||||
+ glow(entity, null);
|
||||
+ }
|
||||
+
|
||||
+ private static void glow(LivingEntity entity, @javax.annotation.Nullable BlockPos pos) {
|
||||
+ if (pos != null && !new io.papermc.paper.event.block.BellRevealRaiderEvent(org.bukkit.craftbukkit.block.CraftBlock.at(entity.level(), pos), (org.bukkit.entity.Raider) entity.getBukkitEntity()).callEvent())
|
||||
+ return;
|
||||
+ // Paper end - Add BellRevealRaiderEvent
|
||||
entity.addEffect(new MobEffectInstance(MobEffects.GLOWING, 60));
|
||||
}
|
||||
|
@@ -0,0 +1,39 @@
|
||||
--- a/net/minecraft/world/level/block/entity/ChestBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/ChestBlockEntity.java
|
||||
@@ -56,6 +_,36 @@
|
||||
};
|
||||
private final ChestLidController chestLidController = new ChestLidController();
|
||||
|
||||
+ // CraftBukkit start - add fields and methods
|
||||
+ public java.util.List<org.bukkit.entity.HumanEntity> transaction = new java.util.ArrayList<>();
|
||||
+ private int maxStack = MAX_STACK;
|
||||
+
|
||||
+ public java.util.List<net.minecraft.world.item.ItemStack> getContents() {
|
||||
+ return this.items;
|
||||
+ }
|
||||
+
|
||||
+ public void onOpen(org.bukkit.craftbukkit.entity.CraftHumanEntity who) {
|
||||
+ this.transaction.add(who);
|
||||
+ }
|
||||
+
|
||||
+ public void onClose(org.bukkit.craftbukkit.entity.CraftHumanEntity who) {
|
||||
+ this.transaction.remove(who);
|
||||
+ }
|
||||
+
|
||||
+ public java.util.List<org.bukkit.entity.HumanEntity> getViewers() {
|
||||
+ return this.transaction;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getMaxStackSize() {
|
||||
+ return this.maxStack;
|
||||
+ }
|
||||
+
|
||||
+ public void setMaxStackSize(int size) {
|
||||
+ this.maxStack = size;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
protected ChestBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState blockState) {
|
||||
super(type, pos, blockState);
|
||||
}
|
@@ -0,0 +1,72 @@
|
||||
--- a/net/minecraft/world/level/block/entity/ChiseledBookShelfBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/ChiseledBookShelfBlockEntity.java
|
||||
@@ -27,6 +_,42 @@
|
||||
private final NonNullList<ItemStack> items = NonNullList.withSize(6, ItemStack.EMPTY);
|
||||
private int lastInteractedSlot = -1;
|
||||
|
||||
+ // CraftBukkit start - add fields and methods
|
||||
+ public java.util.List<org.bukkit.entity.HumanEntity> transaction = new java.util.ArrayList<>();
|
||||
+ private int maxStack = 1;
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.List<net.minecraft.world.item.ItemStack> getContents() {
|
||||
+ return this.items;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onOpen(org.bukkit.craftbukkit.entity.CraftHumanEntity who) {
|
||||
+ this.transaction.add(who);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onClose(org.bukkit.craftbukkit.entity.CraftHumanEntity who) {
|
||||
+ this.transaction.remove(who);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<org.bukkit.entity.HumanEntity> getViewers() {
|
||||
+ return this.transaction;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setMaxStackSize(int size) {
|
||||
+ this.maxStack = size;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.Location getLocation() {
|
||||
+ if (this.level == null) return null;
|
||||
+ return io.papermc.paper.util.MCUtil.toLocation(this.level, this.worldPosition);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
public ChiseledBookShelfBlockEntity(BlockPos pos, BlockState state) {
|
||||
super(BlockEntityType.CHISELED_BOOKSHELF, pos, state);
|
||||
}
|
||||
@@ -93,7 +_,7 @@
|
||||
ItemStack itemStack = Objects.requireNonNullElse(this.items.get(slot), ItemStack.EMPTY);
|
||||
this.items.set(slot, ItemStack.EMPTY);
|
||||
if (!itemStack.isEmpty()) {
|
||||
- this.updateState(slot);
|
||||
+ if (this.level != null) this.updateState(slot); // CraftBukkit - SPIGOT-7381: check for null world
|
||||
}
|
||||
|
||||
return itemStack;
|
||||
@@ -108,7 +_,7 @@
|
||||
public void setItem(int slot, ItemStack stack) {
|
||||
if (stack.is(ItemTags.BOOKSHELF_BOOKS)) {
|
||||
this.items.set(slot, stack);
|
||||
- this.updateState(slot);
|
||||
+ if (this.level != null) this.updateState(slot); // CraftBukkit - SPIGOT-7381: check for null world
|
||||
} else if (stack.isEmpty()) {
|
||||
this.removeItem(slot, 1);
|
||||
}
|
||||
@@ -124,7 +_,7 @@
|
||||
|
||||
@Override
|
||||
public int getMaxStackSize() {
|
||||
- return 1;
|
||||
+ return this.maxStack; // CraftBukkit
|
||||
}
|
||||
|
||||
@Override
|
@@ -0,0 +1,25 @@
|
||||
--- a/net/minecraft/world/level/block/entity/CommandBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/CommandBlockEntity.java
|
||||
@@ -21,6 +_,13 @@
|
||||
private boolean auto;
|
||||
private boolean conditionMet;
|
||||
private final BaseCommandBlock commandBlock = new BaseCommandBlock() {
|
||||
+ // CraftBukkit start
|
||||
+ @Override
|
||||
+ public org.bukkit.command.CommandSender getBukkitSender(CommandSourceStack wrapper) {
|
||||
+ return new org.bukkit.craftbukkit.command.CraftBlockCommandSender(wrapper, CommandBlockEntity.this);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
@Override
|
||||
public void setCommand(String command) {
|
||||
super.setCommand(command);
|
||||
@@ -51,7 +_,7 @@
|
||||
Vec3.atCenterOf(CommandBlockEntity.this.worldPosition),
|
||||
new Vec2(0.0F, direction.toYRot()),
|
||||
this.getLevel(),
|
||||
- 2,
|
||||
+ this.getLevel().paperConfig().commandBlocks.permissionsLevel, // Paper - configurable command block perm level
|
||||
this.getName().getString(),
|
||||
this.getName(),
|
||||
this.getLevel().getServer(),
|
@@ -0,0 +1,303 @@
|
||||
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
@@ -37,6 +_,37 @@
|
||||
private long tickedGameTime;
|
||||
private Direction facing;
|
||||
|
||||
+ // CraftBukkit start - add fields and methods
|
||||
+ public List<org.bukkit.entity.HumanEntity> transaction = new java.util.ArrayList<>();
|
||||
+ private int maxStack = MAX_STACK;
|
||||
+
|
||||
+ public List<ItemStack> getContents() {
|
||||
+ return this.items;
|
||||
+ }
|
||||
+
|
||||
+ public void onOpen(org.bukkit.craftbukkit.entity.CraftHumanEntity who) {
|
||||
+ this.transaction.add(who);
|
||||
+ }
|
||||
+
|
||||
+ public void onClose(org.bukkit.craftbukkit.entity.CraftHumanEntity who) {
|
||||
+ this.transaction.remove(who);
|
||||
+ }
|
||||
+
|
||||
+ public List<org.bukkit.entity.HumanEntity> getViewers() {
|
||||
+ return this.transaction;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getMaxStackSize() {
|
||||
+ return this.maxStack;
|
||||
+ }
|
||||
+
|
||||
+ public void setMaxStackSize(int size) {
|
||||
+ this.maxStack = size;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+
|
||||
public HopperBlockEntity(BlockPos pos, BlockState blockState) {
|
||||
super(BlockEntityType.HOPPER, pos, blockState);
|
||||
this.facing = blockState.getValue(HopperBlock.FACING);
|
||||
@@ -97,7 +_,14 @@
|
||||
blockEntity.tickedGameTime = level.getGameTime();
|
||||
if (!blockEntity.isOnCooldown()) {
|
||||
blockEntity.setCooldown(0);
|
||||
- tryMoveItems(level, pos, state, blockEntity, () -> suckInItems(level, blockEntity));
|
||||
+ // Spigot start
|
||||
+ boolean result = tryMoveItems(level, pos, state, blockEntity, () -> {
|
||||
+ return suckInItems(level, blockEntity);
|
||||
+ });
|
||||
+ if (!result && blockEntity.level.spigotConfig.hopperCheck > 1) {
|
||||
+ blockEntity.setCooldown(blockEntity.level.spigotConfig.hopperCheck);
|
||||
+ }
|
||||
+ // Spigot end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +_,7 @@
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
- blockEntity.setCooldown(8);
|
||||
+ blockEntity.setCooldown(level.spigotConfig.hopperTransfer); // Spigot
|
||||
setChanged(level, pos, state);
|
||||
return true;
|
||||
}
|
||||
@@ -149,14 +_,47 @@
|
||||
ItemStack item = blockEntity.getItem(i);
|
||||
if (!item.isEmpty()) {
|
||||
int count = item.getCount();
|
||||
- ItemStack itemStack = addItem(blockEntity, attachedContainer, blockEntity.removeItem(i, 1), opposite);
|
||||
+ // CraftBukkit start - Call event when pushing items into other inventories
|
||||
+ ItemStack original = item.copy();
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(
|
||||
+ blockEntity.removeItem(i, level.spigotConfig.hopperAmount)
|
||||
+ ); // Spigot
|
||||
+
|
||||
+ org.bukkit.inventory.Inventory destinationInventory;
|
||||
+ // Have to special case large chests as they work oddly
|
||||
+ if (attachedContainer instanceof final CompoundContainer compoundContainer) {
|
||||
+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest(compoundContainer);
|
||||
+ } else if (attachedContainer.getOwner() != null) {
|
||||
+ destinationInventory = attachedContainer.getOwner().getInventory();
|
||||
+ } else {
|
||||
+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventory(attachedContainer);
|
||||
+ }
|
||||
+
|
||||
+ org.bukkit.event.inventory.InventoryMoveItemEvent event = new org.bukkit.event.inventory.InventoryMoveItemEvent(
|
||||
+ blockEntity.getOwner().getInventory(),
|
||||
+ oitemstack,
|
||||
+ destinationInventory,
|
||||
+ true
|
||||
+ );
|
||||
+ if (!event.callEvent()) {
|
||||
+ blockEntity.setItem(i, original);
|
||||
+ blockEntity.setCooldown(level.spigotConfig.hopperTransfer); // Delay hopper checks // Spigot
|
||||
+ return false;
|
||||
+ }
|
||||
+ int origCount = event.getItem().getAmount(); // Spigot
|
||||
+ ItemStack itemStack = HopperBlockEntity.addItem(blockEntity, attachedContainer, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem()), opposite);
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
if (itemStack.isEmpty()) {
|
||||
attachedContainer.setChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
item.setCount(count);
|
||||
- if (count == 1) {
|
||||
+ // Spigot start
|
||||
+ item.shrink(origCount - itemStack.getCount());
|
||||
+ if (count <= level.spigotConfig.hopperAmount) {
|
||||
+ // Spigot end
|
||||
blockEntity.setItem(i, item);
|
||||
}
|
||||
}
|
||||
@@ -219,7 +_,7 @@
|
||||
Direction direction = Direction.DOWN;
|
||||
|
||||
for (int i : getSlots(sourceContainer, direction)) {
|
||||
- if (tryTakeInItemFromSlot(hopper, sourceContainer, i, direction)) {
|
||||
+ if (tryTakeInItemFromSlot(hopper, sourceContainer, i, direction, level)) { // Spigot
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -239,18 +_,54 @@
|
||||
}
|
||||
}
|
||||
|
||||
- private static boolean tryTakeInItemFromSlot(Hopper hopper, Container container, int slot, Direction direction) {
|
||||
+ private static boolean tryTakeInItemFromSlot(Hopper hopper, Container container, int slot, Direction direction, Level level) { // Spigot
|
||||
ItemStack item = container.getItem(slot);
|
||||
if (!item.isEmpty() && canTakeItemFromContainer(hopper, container, item, slot, direction)) {
|
||||
int count = item.getCount();
|
||||
- ItemStack itemStack = addItem(container, hopper, container.removeItem(slot, 1), null);
|
||||
+ // CraftBukkit start - Call event on collection of items from inventories into the hopper
|
||||
+ ItemStack original = item.copy();
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(
|
||||
+ container.removeItem(slot, level.spigotConfig.hopperAmount) // Spigot
|
||||
+ );
|
||||
+
|
||||
+ org.bukkit.inventory.Inventory sourceInventory;
|
||||
+ // Have to special case large chests as they work oddly
|
||||
+ if (container instanceof final CompoundContainer compoundContainer) {
|
||||
+ sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest(compoundContainer);
|
||||
+ } else if (container.getOwner() != null) {
|
||||
+ sourceInventory = container.getOwner().getInventory();
|
||||
+ } else {
|
||||
+ sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventory(container);
|
||||
+ }
|
||||
+
|
||||
+ org.bukkit.event.inventory.InventoryMoveItemEvent event = new org.bukkit.event.inventory.InventoryMoveItemEvent(
|
||||
+ sourceInventory,
|
||||
+ oitemstack,
|
||||
+ hopper.getOwner().getInventory(),
|
||||
+ false
|
||||
+ );
|
||||
+
|
||||
+ if (!event.callEvent()) {
|
||||
+ container.setItem(slot, original);
|
||||
+
|
||||
+ if (hopper instanceof final HopperBlockEntity hopperBlockEntity) {
|
||||
+ hopperBlockEntity.setCooldown(level.spigotConfig.hopperTransfer); // Spigot
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+ }
|
||||
+ int origCount = event.getItem().getAmount(); // Spigot
|
||||
+ ItemStack itemStack = HopperBlockEntity.addItem(container, hopper, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem()), null);
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
if (itemStack.isEmpty()) {
|
||||
container.setChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
item.setCount(count);
|
||||
- if (count == 1) {
|
||||
+ item.shrink(origCount - itemStack.getCount());
|
||||
+ if (count <= level.spigotConfig.hopperAmount) {
|
||||
container.setItem(slot, item);
|
||||
}
|
||||
}
|
||||
@@ -260,12 +_,21 @@
|
||||
|
||||
public static boolean addItem(Container container, ItemEntity item) {
|
||||
boolean flag = false;
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.event.inventory.InventoryPickupItemEvent event = new org.bukkit.event.inventory.InventoryPickupItemEvent(
|
||||
+ container.getOwner().getInventory(), (org.bukkit.entity.Item) item.getBukkitEntity()
|
||||
+ );
|
||||
+ item.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
+ if (event.isCancelled()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
ItemStack itemStack = item.getItem().copy();
|
||||
ItemStack itemStack1 = addItem(null, container, itemStack, null);
|
||||
if (itemStack1.isEmpty()) {
|
||||
flag = true;
|
||||
item.setItem(ItemStack.EMPTY);
|
||||
- item.discard();
|
||||
+ item.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
|
||||
} else {
|
||||
item.setItem(itemStack1);
|
||||
}
|
||||
@@ -307,11 +_,18 @@
|
||||
boolean flag = false;
|
||||
boolean isEmpty = destination.isEmpty();
|
||||
if (item.isEmpty()) {
|
||||
+ // Spigot start - SPIGOT-6693, InventorySubcontainer#setItem
|
||||
+ ItemStack leftover = ItemStack.EMPTY; // Paper - Make hoppers respect inventory max stack size
|
||||
+ if (!stack.isEmpty() && stack.getCount() > destination.getMaxStackSize()) {
|
||||
+ leftover = stack; // Paper - Make hoppers respect inventory max stack size
|
||||
+ stack = stack.split(destination.getMaxStackSize());
|
||||
+ }
|
||||
+ // Spigot end
|
||||
destination.setItem(slot, stack);
|
||||
- stack = ItemStack.EMPTY;
|
||||
+ stack = leftover; // Paper - Make hoppers respect inventory max stack size
|
||||
flag = true;
|
||||
} else if (canMergeItems(item, stack)) {
|
||||
- int i = stack.getMaxStackSize() - item.getCount();
|
||||
+ int i = Math.min(stack.getMaxStackSize(), destination.getMaxStackSize()) - item.getCount(); // Paper - Make hoppers respect inventory max stack size
|
||||
int min = Math.min(stack.getCount(), i);
|
||||
stack.shrink(min);
|
||||
item.grow(min);
|
||||
@@ -325,7 +_,7 @@
|
||||
min = 1;
|
||||
}
|
||||
|
||||
- hopperBlockEntity.setCooldown(8 - min);
|
||||
+ hopperBlockEntity.setCooldown(hopperBlockEntity.level.spigotConfig.hopperTransfer - min); // Spigot
|
||||
}
|
||||
|
||||
destination.setChanged();
|
||||
@@ -335,14 +_,57 @@
|
||||
return stack;
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ @Nullable
|
||||
+ private static Container runHopperInventorySearchEvent(
|
||||
+ Container container,
|
||||
+ org.bukkit.craftbukkit.block.CraftBlock hopper,
|
||||
+ org.bukkit.craftbukkit.block.CraftBlock searchLocation,
|
||||
+ org.bukkit.event.inventory.HopperInventorySearchEvent.ContainerType containerType
|
||||
+ ) {
|
||||
+ org.bukkit.event.inventory.HopperInventorySearchEvent event = new org.bukkit.event.inventory.HopperInventorySearchEvent(
|
||||
+ (container != null) ? new org.bukkit.craftbukkit.inventory.CraftInventory(container) : null,
|
||||
+ containerType,
|
||||
+ hopper,
|
||||
+ searchLocation
|
||||
+ );
|
||||
+ event.callEvent();
|
||||
+ return (event.getInventory() != null) ? ((org.bukkit.craftbukkit.inventory.CraftInventory) event.getInventory()).getInventory() : null;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
@Nullable
|
||||
private static Container getAttachedContainer(Level level, BlockPos pos, HopperBlockEntity blockEntity) {
|
||||
- return getContainerAt(level, pos.relative(blockEntity.facing));
|
||||
+ // CraftBukkit start
|
||||
+ BlockPos searchPosition = pos.relative(blockEntity.facing);
|
||||
+ Container inventory = getContainerAt(level, searchPosition);
|
||||
+
|
||||
+ org.bukkit.craftbukkit.block.CraftBlock hopper = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
|
||||
+ org.bukkit.craftbukkit.block.CraftBlock searchBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, searchPosition);
|
||||
+ return HopperBlockEntity.runHopperInventorySearchEvent(
|
||||
+ inventory,
|
||||
+ hopper,
|
||||
+ searchBlock,
|
||||
+ org.bukkit.event.inventory.HopperInventorySearchEvent.ContainerType.DESTINATION
|
||||
+ );
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Container getSourceContainer(Level level, Hopper hopper, BlockPos pos, BlockState state) {
|
||||
- return getContainerAt(level, pos, state, hopper.getLevelX(), hopper.getLevelY() + 1.0, hopper.getLevelZ());
|
||||
+ // CraftBukkit start
|
||||
+ final Container inventory = HopperBlockEntity.getContainerAt(level, pos, state, hopper.getLevelX(), hopper.getLevelY() + 1.0D, hopper.getLevelZ());
|
||||
+
|
||||
+ final BlockPos blockPosition = BlockPos.containing(hopper.getLevelX(), hopper.getLevelY(), hopper.getLevelZ());
|
||||
+ org.bukkit.craftbukkit.block.CraftBlock hopperBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, blockPosition);
|
||||
+ org.bukkit.craftbukkit.block.CraftBlock containerBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, blockPosition.above());
|
||||
+ return HopperBlockEntity.runHopperInventorySearchEvent(
|
||||
+ inventory,
|
||||
+ hopperBlock,
|
||||
+ containerBlock,
|
||||
+ org.bukkit.event.inventory.HopperInventorySearchEvent.ContainerType.SOURCE
|
||||
+ );
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
public static List<ItemEntity> getItemsAtAndAbove(Level level, Hopper hopper) {
|
||||
@@ -367,6 +_,7 @@
|
||||
|
||||
@Nullable
|
||||
private static Container getBlockContainer(Level level, BlockPos pos, BlockState state) {
|
||||
+ if (!level.spigotConfig.hopperCanLoadChunks && !level.hasChunkAt(pos)) return null; // Spigot
|
||||
Block block = state.getBlock();
|
||||
if (block instanceof WorldlyContainerHolder) {
|
||||
return ((WorldlyContainerHolder)block).getContainer(state, level, pos);
|
@@ -0,0 +1,21 @@
|
||||
--- a/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
|
||||
@@ -34,8 +_,18 @@
|
||||
this.catalystListener = new SculkCatalystBlockEntity.CatalystListener(blockState, new BlockPositionSource(pos));
|
||||
}
|
||||
|
||||
+ // Paper start - Fix NPE in SculkBloomEvent world access
|
||||
+ @Override
|
||||
+ public void setLevel(Level level) {
|
||||
+ super.setLevel(level);
|
||||
+ this.catalystListener.sculkSpreader.level = level;
|
||||
+ }
|
||||
+ // Paper end - Fix NPE in SculkBloomEvent world access
|
||||
+
|
||||
public static void serverTick(Level level, BlockPos pos, BlockState state, SculkCatalystBlockEntity sculkCatalyst) {
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverride = sculkCatalyst.getBlockPos(); // CraftBukkit - SPIGOT-7068: Add source block override, not the most elegant way but better than passing down a BlockPosition up to five methods deep.
|
||||
sculkCatalyst.catalystListener.getSculkSpreader().updateCursors(level, pos, level.getRandom(), true);
|
||||
+ org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverride = null; // CraftBukkit
|
||||
}
|
||||
|
||||
@Override
|
@@ -0,0 +1,11 @@
|
||||
--- a/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
|
||||
@@ -131,7 +_,7 @@
|
||||
|
||||
@Nullable
|
||||
public Vec3 getPortalPosition(ServerLevel level, BlockPos pos) {
|
||||
- if (this.exitPortal == null && level.dimension() == Level.END) {
|
||||
+ if (this.exitPortal == null && level.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.END) { // CraftBukkit - work in alternate worlds
|
||||
BlockPos blockPos = findOrCreateValidTeleportPos(level, pos);
|
||||
blockPos = blockPos.above(10);
|
||||
LOGGER.debug("Creating portal at {}", blockPos);
|
Reference in New Issue
Block a user