From eff1743b9c4e4833d02eda4327cdd1f84464ba4b Mon Sep 17 00:00:00 2001 From: Parker Hawke Date: Wed, 29 Mar 2023 19:23:41 +1100 Subject: [PATCH] SPIGOT-7313: More accurately edit data on Jukeboxes --- .../block/entity/TileEntityJukeBox.patch | 14 ++-- .../craftbukkit/block/CraftJukebox.java | 71 +++++++++++++++---- 2 files changed, 65 insertions(+), 20 deletions(-) diff --git a/nms-patches/net/minecraft/world/level/block/entity/TileEntityJukeBox.patch b/nms-patches/net/minecraft/world/level/block/entity/TileEntityJukeBox.patch index 2a83db905..a31d7eb84 100644 --- a/nms-patches/net/minecraft/world/level/block/entity/TileEntityJukeBox.patch +++ b/nms-patches/net/minecraft/world/level/block/entity/TileEntityJukeBox.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/TileEntityJukeBox.java +++ b/net/minecraft/world/level/block/entity/TileEntityJukeBox.java -@@ -24,6 +24,13 @@ +@@ -24,14 +24,57 @@ import net.minecraft.world.phys.Vec3D; import net.minecraft.world.ticks.ContainerSingleItem; @@ -14,10 +14,14 @@ public class TileEntityJukeBox extends TileEntity implements Clearable, ContainerSingleItem { private static final int SONG_END_PADDING = 20; -@@ -32,6 +39,42 @@ - private long tickCount; - private long recordStartedTick; - private boolean isPlaying; + private final NonNullList items; + private int ticksSinceLastEvent; +- private long tickCount; +- private long recordStartedTick; +- private boolean isPlaying; ++ public long tickCount; ++ public long recordStartedTick; ++ public boolean isPlaying; + // CraftBukkit start - add fields and methods + public List transaction = new java.util.ArrayList(); + private int maxStack = MAX_STACK; diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java b/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java index 76f492945..dfb2db3e2 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java @@ -2,7 +2,6 @@ package org.bukkit.craftbukkit.block; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.BlockJukeBox; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.TileEntity; import net.minecraft.world.level.block.entity.TileEntityJukeBox; import org.bukkit.Effect; @@ -40,14 +39,19 @@ public class CraftJukebox extends CraftBlockEntityState imple boolean result = super.update(force, applyPhysics); if (result && this.isPlaced() && this.getType() == Material.JUKEBOX) { - CraftWorld world = (CraftWorld) this.getWorld(); Material record = this.getPlaying(); - if (record == Material.AIR) { - getWorldHandle().setBlock(this.getPosition(), Blocks.JUKEBOX.defaultBlockState().setValue(BlockJukeBox.HAS_RECORD, false), 3); - } else { - getWorldHandle().setBlock(this.getPosition(), Blocks.JUKEBOX.defaultBlockState().setValue(BlockJukeBox.HAS_RECORD, true), 3); + getWorldHandle().setBlock(this.getPosition(), data, 3); + + TileEntity tileEntity = this.getTileEntityFromWorld(); + if (tileEntity instanceof TileEntityJukeBox jukebox) { + CraftWorld world = (CraftWorld) this.getWorld(); + if (record.isAir()) { + jukebox.setRecordWithoutPlaying(ItemStack.EMPTY); + world.playEffect(this.getLocation(), Effect.IRON_DOOR_CLOSE, 0); // TODO: Fix this enum constant. This stops jukeboxes + } else { + world.playEffect(this.getLocation(), Effect.RECORD_PLAY, record); + } } - world.playEffect(this.getLocation(), Effect.RECORD_PLAY, record); } return result; @@ -67,6 +71,11 @@ public class CraftJukebox extends CraftBlockEntityState imple setRecord(new org.bukkit.inventory.ItemStack(record)); } + @Override + public boolean hasRecord() { + return getHandle().getValue(BlockJukeBox.HAS_RECORD) && !getPlaying().isAir(); + } + @Override public org.bukkit.inventory.ItemStack getRecord() { ItemStack record = this.getSnapshot().getFirstItem(); @@ -76,22 +85,54 @@ public class CraftJukebox extends CraftBlockEntityState imple @Override public void setRecord(org.bukkit.inventory.ItemStack record) { ItemStack nms = CraftItemStack.asNMSCopy(record); - this.getSnapshot().setRecordWithoutPlaying(nms); - if (nms.isEmpty()) { - this.data = this.data.setValue(BlockJukeBox.HAS_RECORD, false); - } else { - this.data = this.data.setValue(BlockJukeBox.HAS_RECORD, true); - } + + TileEntityJukeBox snapshot = this.getSnapshot(); + snapshot.setRecordWithoutPlaying(nms); + snapshot.recordStartedTick = snapshot.tickCount; + snapshot.isPlaying = !nms.isEmpty(); + + this.data = this.data.setValue(BlockJukeBox.HAS_RECORD, !nms.isEmpty()); } @Override public boolean isPlaying() { - return getHandle().getValue(BlockJukeBox.HAS_RECORD); + requirePlaced(); + + TileEntity tileEntity = this.getTileEntityFromWorld(); + return tileEntity instanceof TileEntityJukeBox jukebox && jukebox.isRecordPlaying(); + } + + @Override + public boolean startPlaying() { + requirePlaced(); + + TileEntity tileEntity = this.getTileEntityFromWorld(); + if (!(tileEntity instanceof TileEntityJukeBox jukebox)) { + return false; + } + + ItemStack record = jukebox.getFirstItem(); + if (record.isEmpty() || isPlaying()) { + return false; + } + + jukebox.isPlaying = true; + jukebox.recordStartedTick = jukebox.tickCount; + getWorld().playEffect(getLocation(), Effect.RECORD_PLAY, CraftMagicNumbers.getMaterial(record.getItem())); + return true; } @Override public void stopPlaying() { - getWorld().playEffect(getLocation(), Effect.RECORD_PLAY, Material.AIR); + requirePlaced(); + + TileEntity tileEntity = this.getTileEntityFromWorld(); + if (!(tileEntity instanceof TileEntityJukeBox jukebox)) { + return; + } + + jukebox.isPlaying = false; + getWorld().playEffect(getLocation(), Effect.IRON_DOOR_CLOSE, 0); // TODO: Fix this enum constant. This stops jukeboxes } @Override