From 8fb65851f12f78c26ca979377370395e64c8a61f Mon Sep 17 00:00:00 2001 From: jameslfc19 Date: Wed, 29 Jul 2020 19:41:00 +1000 Subject: [PATCH] #660: Add support to change block's lid state --- nms-patches/TileEntityBarrel.patch | 26 +++++++++- nms-patches/TileEntityChest.patch | 48 ++++++++++++++++--- nms-patches/TileEntityShulkerBox.patch | 28 ++++++++++- .../bukkit/craftbukkit/block/CraftBarrel.java | 24 ++++++++++ .../bukkit/craftbukkit/block/CraftChest.java | 23 +++++++++ .../craftbukkit/block/CraftShulkerBox.java | 25 ++++++++++ 6 files changed, 165 insertions(+), 9 deletions(-) diff --git a/nms-patches/TileEntityBarrel.patch b/nms-patches/TileEntityBarrel.patch index 9445480e53..44a6fdec8e 100644 --- a/nms-patches/TileEntityBarrel.patch +++ b/nms-patches/TileEntityBarrel.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/TileEntityBarrel.java +++ b/net/minecraft/server/TileEntityBarrel.java -@@ -1,7 +1,54 @@ +@@ -1,7 +1,55 @@ package net.minecraft.server; +// CraftBukkit start @@ -21,6 +21,7 @@ + // CraftBukkit start - add fields and methods + public List transaction = new ArrayList<>(); + private int maxStack = MAX_STACK; ++ public boolean opened; + + @Override + public List getContents() { @@ -55,3 +56,26 @@ private NonNullList items; private int b; +@@ -100,7 +148,7 @@ + return; + } + +- boolean flag = (Boolean) iblockdata.get(BlockBarrel.b); ++ boolean flag = (Boolean) iblockdata.get(BlockBarrel.b) && !opened; // CraftBukkit - only set flag if Barrel isn't set open by API. + + if (flag) { + this.a(iblockdata, SoundEffects.BLOCK_BARREL_CLOSE); +@@ -118,11 +166,11 @@ + + } + +- private void a(IBlockData iblockdata, boolean flag) { ++ public void a(IBlockData iblockdata, boolean flag) { // PAIL private -> public, rename setFlag + this.world.setTypeAndData(this.getPosition(), (IBlockData) iblockdata.set(BlockBarrel.b, flag), 3); + } + +- private void a(IBlockData iblockdata, SoundEffect soundeffect) { ++ public void a(IBlockData iblockdata, SoundEffect soundeffect) { // PAIL private -> public, rename playSound + BaseBlockPosition baseblockposition = ((EnumDirection) iblockdata.get(BlockBarrel.a)).p(); + double d0 = (double) this.position.getX() + 0.5D + (double) baseblockposition.getX() / 2.0D; + double d1 = (double) this.position.getY() + 0.5D + (double) baseblockposition.getY() / 2.0D; diff --git a/nms-patches/TileEntityChest.patch b/nms-patches/TileEntityChest.patch index 987839a055..4629fee75b 100644 --- a/nms-patches/TileEntityChest.patch +++ b/nms-patches/TileEntityChest.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/TileEntityChest.java +++ b/net/minecraft/server/TileEntityChest.java -@@ -2,6 +2,10 @@ +@@ -2,15 +2,50 @@ import java.util.Iterator; import java.util.List; @@ -11,13 +11,17 @@ public class TileEntityChest extends TileEntityLootable implements ITickable { -@@ -11,6 +15,36 @@ - protected int viewingCount; + private NonNullList items; + protected float a; + protected float b; +- protected int viewingCount; ++ public int viewingCount; // PAIL protected -> public private int j; + // CraftBukkit start - add fields and methods + public List transaction = new java.util.ArrayList(); + private int maxStack = MAX_STACK; ++ public boolean opened; + + public List getContents() { + return this.items; @@ -48,7 +52,30 @@ protected TileEntityChest(TileEntityTypes tileentitytypes) { super(tileentitytypes); this.items = NonNullList.a(27, ItemStack.b); -@@ -155,8 +189,20 @@ +@@ -61,6 +96,13 @@ + this.b = this.a; + float f = 0.1F; + ++ // CraftBukkit start - If chest is forced open by API, remove a viewer due to playBlockAction() call and don't tick to prevent sound effects. ++ if (opened) { ++ this.viewingCount--; ++ return; ++ } ++ // CraftBukkit end ++ + if (this.viewingCount > 0 && this.a == 0.0F) { + this.a(SoundEffects.BLOCK_CHEST_OPEN); + } +@@ -120,7 +162,7 @@ + return l; + } + +- private void a(SoundEffect soundeffect) { ++ public void a(SoundEffect soundeffect) { // PAIL private -> public, rename playSound + BlockPropertyChestType blockpropertychesttype = (BlockPropertyChestType) this.getBlock().get(BlockChest.c); + + if (blockpropertychesttype != BlockPropertyChestType.LEFT) { +@@ -155,8 +197,20 @@ if (this.viewingCount < 0) { this.viewingCount = 0; } @@ -69,7 +96,7 @@ this.onOpen(); } -@@ -165,7 +211,18 @@ +@@ -165,7 +219,18 @@ @Override public void closeContainer(EntityHuman entityhuman) { if (!entityhuman.isSpectator()) { @@ -88,7 +115,16 @@ this.onOpen(); } -@@ -216,4 +273,11 @@ +@@ -175,7 +240,7 @@ + Block block = this.getBlock().getBlock(); + + if (block instanceof BlockChest) { +- this.world.playBlockAction(this.position, block, 1, this.viewingCount); ++ if (!opened) this.world.playBlockAction(this.position, block, 1, this.viewingCount); // CraftBukkit + this.world.applyPhysics(this.position, block); + } + +@@ -216,4 +281,11 @@ protected Container createContainer(int i, PlayerInventory playerinventory) { return ContainerChest.a(i, playerinventory, this); } diff --git a/nms-patches/TileEntityShulkerBox.patch b/nms-patches/TileEntityShulkerBox.patch index 81300bdd47..caebc970a7 100644 --- a/nms-patches/TileEntityShulkerBox.patch +++ b/nms-patches/TileEntityShulkerBox.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/TileEntityShulkerBox.java +++ b/net/minecraft/server/TileEntityShulkerBox.java -@@ -3,6 +3,10 @@ +@@ -3,12 +3,16 @@ import java.util.List; import java.util.stream.IntStream; import javax.annotation.Nullable; @@ -11,13 +11,21 @@ public class TileEntityShulkerBox extends TileEntityLootable implements IWorldInventory, ITickable { -@@ -16,6 +20,36 @@ + private static final int[] a = IntStream.range(0, 27).toArray(); + private NonNullList contents; +- private int c; ++ public int c; // PAIL private -> public, rename viewerCount + private TileEntityShulkerBox.AnimationPhase i; + private float j; + private float k; +@@ -16,6 +20,37 @@ private EnumColor l; private boolean m; + // CraftBukkit start - add fields and methods + public List transaction = new java.util.ArrayList(); + private int maxStack = MAX_STACK; ++ public boolean opened; + + public List getContents() { + return this.contents; @@ -48,3 +56,19 @@ public TileEntityShulkerBox(@Nullable EnumColor enumcolor) { super(TileEntityTypes.SHULKER_BOX); this.contents = NonNullList.a(27, ItemStack.b); +@@ -178,6 +213,7 @@ + } + + ++this.c; ++ if (opened) return; // CraftBukkit - only animate if the ShulkerBox hasn't been forced open already by an API call. + this.world.playBlockAction(this.position, this.getBlock().getBlock(), 1, this.c); + if (this.c == 1) { + this.world.playSound((EntityHuman) null, this.position, SoundEffects.BLOCK_SHULKER_BOX_OPEN, SoundCategory.BLOCKS, 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); +@@ -190,6 +226,7 @@ + public void closeContainer(EntityHuman entityhuman) { + if (!entityhuman.isSpectator()) { + --this.c; ++ if (opened) return; // CraftBukkit - only animate if the ShulkerBox hasn't been forced open already by an API call. + this.world.playBlockAction(this.position, this.getBlock().getBlock(), 1, this.c); + if (this.c <= 0) { + this.world.playSound((EntityHuman) null, this.position, SoundEffects.BLOCK_SHULKER_BOX_CLOSE, SoundCategory.BLOCKS, 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBarrel.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBarrel.java index cb5ac0f098..6378a0a6e0 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBarrel.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBarrel.java @@ -1,5 +1,7 @@ package org.bukkit.craftbukkit.block; +import net.minecraft.server.IBlockData; +import net.minecraft.server.SoundEffects; import net.minecraft.server.TileEntityBarrel; import org.bukkit.Material; import org.bukkit.block.Barrel; @@ -30,4 +32,26 @@ public class CraftBarrel extends CraftLootable implements Barr return new CraftInventory(this.getTileEntity()); } + + @Override + public void open() { + requirePlaced(); + if (!getTileEntity().opened) { + IBlockData blockData = getTileEntity().getBlock(); + getTileEntity().a(blockData, true); + getTileEntity().a(blockData, SoundEffects.BLOCK_BARREL_OPEN); + } + getTileEntity().opened = true; + } + + @Override + public void close() { + requirePlaced(); + if (getTileEntity().opened) { + IBlockData blockData = getTileEntity().getBlock(); + getTileEntity().a(blockData, false); + getTileEntity().a(blockData, SoundEffects.BLOCK_BARREL_CLOSE); + } + getTileEntity().opened = false; + } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java index 6beb992622..941cb98cc2 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java @@ -3,6 +3,7 @@ package org.bukkit.craftbukkit.block; import net.minecraft.server.BlockChest; import net.minecraft.server.Blocks; import net.minecraft.server.ITileInventory; +import net.minecraft.server.SoundEffects; import net.minecraft.server.TileEntityChest; import org.bukkit.Material; import org.bukkit.block.Block; @@ -54,4 +55,26 @@ public class CraftChest extends CraftLootable implements Chest } return inventory; } + + @Override + public void open() { + requirePlaced(); + if (!getTileEntity().opened) { + net.minecraft.server.Block block = getTileEntity().getBlock().getBlock(); + getTileEntity().getWorld().playBlockAction(getTileEntity().getPosition(), block, 1, getTileEntity().viewingCount + 1); + getTileEntity().a(SoundEffects.BLOCK_CHEST_OPEN); + } + getTileEntity().opened = true; + } + + @Override + public void close() { + requirePlaced(); + if (getTileEntity().opened) { + net.minecraft.server.Block block = getTileEntity().getBlock().getBlock(); + getTileEntity().getWorld().playBlockAction(getTileEntity().getPosition(), block, 1, 0); + getTileEntity().a(SoundEffects.BLOCK_CHEST_CLOSE); + } + getTileEntity().opened = false; + } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftShulkerBox.java b/src/main/java/org/bukkit/craftbukkit/block/CraftShulkerBox.java index c029a12441..10bc0b0944 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftShulkerBox.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftShulkerBox.java @@ -1,7 +1,10 @@ package org.bukkit.craftbukkit.block; import net.minecraft.server.BlockShulkerBox; +import net.minecraft.server.SoundCategory; +import net.minecraft.server.SoundEffects; import net.minecraft.server.TileEntityShulkerBox; +import net.minecraft.server.World; import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.block.Block; @@ -40,4 +43,26 @@ public class CraftShulkerBox extends CraftLootable impleme return DyeColor.getByWoolData((byte) ((BlockShulkerBox) block).color.getColorIndex()); } + + @Override + public void open() { + requirePlaced(); + if (!getTileEntity().opened) { + World world = getTileEntity().getWorld(); + world.playBlockAction(getPosition(), getTileEntity().getBlock().getBlock(), 1, 1); + world.playSound(null, getPosition(), SoundEffects.BLOCK_SHULKER_BOX_OPEN, SoundCategory.BLOCKS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F); + } + getTileEntity().opened = true; + } + + @Override + public void close() { + requirePlaced(); + if (getTileEntity().opened) { + World world = getTileEntity().getWorld(); + world.playBlockAction(getPosition(), getTileEntity().getBlock().getBlock(), 1, 0); + world.playSound(null, getPosition(), SoundEffects.BLOCK_SHULKER_BOX_OPEN, SoundCategory.BLOCKS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F); + } + getTileEntity().opened = false; + } }