From 606af7b8e76a320bea1fa0f52bcc8a328229bfd9 Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Fri, 6 Sep 2024 04:22:20 +1000 Subject: [PATCH 1/5] Adds block sound syntax - Allows getting the break, fall, hit, place, and step sound of a block/blockdata/itemtype --- .../skript/expressions/ExprBlockSound.java | 125 ++++++++++++++++++ .../syntaxes/expressions/ExprBlockSound.sk | 22 +++ 2 files changed, 147 insertions(+) create mode 100644 src/main/java/ch/njol/skript/expressions/ExprBlockSound.java create mode 100644 src/test/skript/tests/syntaxes/expressions/ExprBlockSound.sk diff --git a/src/main/java/ch/njol/skript/expressions/ExprBlockSound.java b/src/main/java/ch/njol/skript/expressions/ExprBlockSound.java new file mode 100644 index 00000000000..e9c7b065755 --- /dev/null +++ b/src/main/java/ch/njol/skript/expressions/ExprBlockSound.java @@ -0,0 +1,125 @@ +package ch.njol.skript.expressions; + +import ch.njol.skript.Skript; +import ch.njol.skript.aliases.ItemType; +import ch.njol.skript.doc.Description; +import ch.njol.skript.doc.Examples; +import ch.njol.skript.doc.Name; +import ch.njol.skript.doc.Since; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.ExpressionType; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.lang.util.SimpleExpression; +import ch.njol.util.Kleenean; +import org.bukkit.Sound; +import org.bukkit.SoundGroup; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.bukkit.event.Event; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; + +@Name("Block Sound") +@Description("Gets the sound that a given block, blockdata, or itemtype will use in a specific scenario.") +@Examples({ + "play sound (break sound of dirt) at all players", + "set {_sounds::*} to place sounds of dirt, grass block, blue wool and stone" +}) +@Since("INSERT VERSION") +public class ExprBlockSound extends SimpleExpression { + + static { + Skript.registerExpression(ExprBlockSound.class, String.class, ExpressionType.COMBINED, + "[the] break sound[s] of %blocks/blockdatas/itemtypes%", + "%blocks/blockdatas/itemtypes%'[s] break sound[s]", + + "[the] fall sound[s] of %blocks/blockdatas/itemtypes%", + "%blocks/blockdatas/itemtypes%'[s] fall sound[s]", + + "[the] hit sound[s] of %blocks/blockdatas/itemtypes%", + "%blocks/blockdatas/itemtypes%'[s] hit sound[s]", + + "[the] place sound[s] of %blocks/blockdatas/itemtypes%", + "%blocks/blockdatas/itemtypes%'[s] place sound[s]", + + "[the] step sound[s] of %blocks/blockdatas/itemtypes%", + "%blocks/blockdatas/itemtypes%'[s] step sound[s]"); + } + + private static final int BREAK = 0; + private static final int FALL = 2; + private static final int HIT = 4; + private static final int PLACE = 6; + private static final int STEP = 8; + + private int soundPattern; + @SuppressWarnings("NotNullFieldNotInitialized") + private Expression objects; + + @Override + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + soundPattern = matchedPattern; + objects = exprs[0]; + return true; + } + + @Override + protected String @Nullable [] get(Event event) { + return objects.stream(event) + .map(this::convertAndGetSound) + .filter(Objects::nonNull) + .distinct() + .map(Sound::name) + .toArray(String[]::new); + } + + private @Nullable Sound convertAndGetSound(Object object) { + SoundGroup group = null; + + if (object instanceof Block block) { + group = block.getBlockData().getSoundGroup(); + } else if (object instanceof BlockData data) { + group = data.getSoundGroup(); + } else if (object instanceof ItemType item) { + if (item.hasBlock()) + group = item.getMaterial().createBlockData().getSoundGroup(); + } + + if (group == null) + return null; + + return switch (this.soundPattern) { + case BREAK, BREAK + 1 -> group.getBreakSound(); + case FALL, FALL + 1 -> group.getFallSound(); + case HIT, HIT + 1 -> group.getHitSound(); + case PLACE, PLACE + 1 -> group.getPlaceSound(); + case STEP, STEP + 1 -> group.getStepSound(); + default -> null; + }; + } + + @Override + public boolean isSingle() { + return objects.isSingle(); + } + + @Override + public @NotNull Class getReturnType() { + return String.class; + } + + @Override + public @NotNull String toString(@Nullable Event event, boolean debug) { + return switch (this.soundPattern) { + case BREAK, BREAK + 1 -> "break"; + case FALL, FALL + 1 -> "fall"; + case HIT, HIT + 1 -> "hit"; + case PLACE, PLACE + 1 -> "place"; + case STEP, STEP + 1 -> "step"; + default -> null; + } + " sound of " + objects.toString(event, debug); + } + +} diff --git a/src/test/skript/tests/syntaxes/expressions/ExprBlockSound.sk b/src/test/skript/tests/syntaxes/expressions/ExprBlockSound.sk new file mode 100644 index 00000000000..a8f6e670352 --- /dev/null +++ b/src/test/skript/tests/syntaxes/expressions/ExprBlockSound.sk @@ -0,0 +1,22 @@ +test "block sounds": + + # === SETUP === + + set {_block} to block at (spawn of world "world") + set {_before} to blockdata of {_block} + set blockdata of {_block} to stone[] + set {_data} to blockdata of {_block} + + set {_itemtype} to stone + + # === TESTS === + + assert break sound of {_block}, {_data} and {_itemtype} is "BLOCK_STONE_BREAK" with "break sound of stone wasn't BLOCK_STONE_BREAK" + assert fall sound of {_block}, {_data} and {_itemtype} is "BLOCK_STONE_FALL" with "fall sound of stone wasn't BLOCK_STONE_FALL" + assert hit sound of {_block}, {_data} and {_itemtype} is "BLOCK_STONE_HIT" with "hit sound of stone wasn't BLOCK_STONE_HIT" + assert place sound of {_block}, {_data} and {_itemtype} is "BLOCK_STONE_PLACE" with "place sound of stone wasn't BLOCK_STONE_PLACE" + assert step sound of {_block}, {_data} and {_itemtype} is "BLOCK_STONE_STEP" with "step sound of stone wasn't BLOCK_STONE_STEP" + + # === CLEANUP === + + set blockdata of {_block} to {_before} From 0e71063612e87289cec81aa61e8f68d3fef48222 Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Fri, 6 Sep 2024 22:01:11 +1000 Subject: [PATCH 2/5] Suggestions --- .../skript/expressions/ExprBlockSound.java | 63 ++++++++----------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprBlockSound.java b/src/main/java/ch/njol/skript/expressions/ExprBlockSound.java index e9c7b065755..e4b13dca8d9 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprBlockSound.java +++ b/src/main/java/ch/njol/skript/expressions/ExprBlockSound.java @@ -1,13 +1,12 @@ package ch.njol.skript.expressions; -import ch.njol.skript.Skript; import ch.njol.skript.aliases.ItemType; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; import ch.njol.skript.doc.Since; +import ch.njol.skript.expressions.base.SimplePropertyExpression; import ch.njol.skript.lang.Expression; -import ch.njol.skript.lang.ExpressionType; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.util.Kleenean; @@ -22,7 +21,13 @@ import java.util.Objects; @Name("Block Sound") -@Description("Gets the sound that a given block, blockdata, or itemtype will use in a specific scenario.") +@Description({ + "Gets the sound that a given block, blockdata, or itemtype will use in a specific scenario.", + "This will actually return a string, in the form of \"SOUND_EXAMPLE\", which can be used in Skript syntax.", + "", + "Check out this website for a list of sounds in Minecraft (Java Edition), " + + "or this one to go to the sounds wiki page." +}) @Examples({ "play sound (break sound of dirt) at all players", "set {_sounds::*} to place sounds of dirt, grass block, blue wool and stone" @@ -30,37 +35,19 @@ @Since("INSERT VERSION") public class ExprBlockSound extends SimpleExpression { - static { - Skript.registerExpression(ExprBlockSound.class, String.class, ExpressionType.COMBINED, - "[the] break sound[s] of %blocks/blockdatas/itemtypes%", - "%blocks/blockdatas/itemtypes%'[s] break sound[s]", - - "[the] fall sound[s] of %blocks/blockdatas/itemtypes%", - "%blocks/blockdatas/itemtypes%'[s] fall sound[s]", - - "[the] hit sound[s] of %blocks/blockdatas/itemtypes%", - "%blocks/blockdatas/itemtypes%'[s] hit sound[s]", + private static final int BREAK = 1, FALL = 2, HIT = 3, PLACE = 4, STEP = 5; - "[the] place sound[s] of %blocks/blockdatas/itemtypes%", - "%blocks/blockdatas/itemtypes%'[s] place sound[s]", - - "[the] step sound[s] of %blocks/blockdatas/itemtypes%", - "%blocks/blockdatas/itemtypes%'[s] step sound[s]"); + static { + SimplePropertyExpression.register(ExprBlockSound.class, String.class, "(1:break|2:fall|3:hit|4:place|5:step) sound[s]", "blocks/blockdatas/itemtypes"); } - private static final int BREAK = 0; - private static final int FALL = 2; - private static final int HIT = 4; - private static final int PLACE = 6; - private static final int STEP = 8; - - private int soundPattern; + private int soundType; @SuppressWarnings("NotNullFieldNotInitialized") private Expression objects; @Override public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { - soundPattern = matchedPattern; + soundType = parseResult.mark; objects = exprs[0]; return true; } @@ -90,12 +77,12 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye if (group == null) return null; - return switch (this.soundPattern) { - case BREAK, BREAK + 1 -> group.getBreakSound(); - case FALL, FALL + 1 -> group.getFallSound(); - case HIT, HIT + 1 -> group.getHitSound(); - case PLACE, PLACE + 1 -> group.getPlaceSound(); - case STEP, STEP + 1 -> group.getStepSound(); + return switch (this.soundType) { + case BREAK -> group.getBreakSound(); + case FALL -> group.getFallSound(); + case HIT -> group.getHitSound(); + case PLACE -> group.getPlaceSound(); + case STEP -> group.getStepSound(); default -> null; }; } @@ -112,12 +99,12 @@ public boolean isSingle() { @Override public @NotNull String toString(@Nullable Event event, boolean debug) { - return switch (this.soundPattern) { - case BREAK, BREAK + 1 -> "break"; - case FALL, FALL + 1 -> "fall"; - case HIT, HIT + 1 -> "hit"; - case PLACE, PLACE + 1 -> "place"; - case STEP, STEP + 1 -> "step"; + return switch (this.soundType) { + case BREAK -> "break"; + case FALL -> "fall"; + case HIT -> "hit"; + case PLACE -> "place"; + case STEP -> "step"; default -> null; } + " sound of " + objects.toString(event, debug); } From 1454a2acb9e3c5b6a5df137053fc58d44ffdb259 Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Sun, 8 Sep 2024 16:32:01 +1000 Subject: [PATCH 3/5] Suggestion Co-authored-by: sovdee <10354869+sovdeeth@users.noreply.github.com> --- src/main/java/ch/njol/skript/expressions/ExprBlockSound.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprBlockSound.java b/src/main/java/ch/njol/skript/expressions/ExprBlockSound.java index e4b13dca8d9..99b6da39cba 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprBlockSound.java +++ b/src/main/java/ch/njol/skript/expressions/ExprBlockSound.java @@ -23,7 +23,7 @@ @Name("Block Sound") @Description({ "Gets the sound that a given block, blockdata, or itemtype will use in a specific scenario.", - "This will actually return a string, in the form of \"SOUND_EXAMPLE\", which can be used in Skript syntax.", + "This will return a string in the form of \"SOUND_EXAMPLE\", which can be used in the play sound syntax.", "", "Check out this website for a list of sounds in Minecraft (Java Edition), " + "or this one to go to the sounds wiki page." From f6e441a686dadbbfbae33d9b23c182f0cad6ccef Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Mon, 9 Sep 2024 03:50:45 +1000 Subject: [PATCH 4/5] Implements SoundType enum to get a sound given a group, and makes tests better - This also reduces some annoying switch stuff with the soundType from before --- .../skript/expressions/ExprBlockSound.java | 81 ++++++++++++------- .../syntaxes/expressions/ExprBlockSound.sk | 44 +++++++--- 2 files changed, 86 insertions(+), 39 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprBlockSound.java b/src/main/java/ch/njol/skript/expressions/ExprBlockSound.java index e4b13dca8d9..f94cc2f7b60 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprBlockSound.java +++ b/src/main/java/ch/njol/skript/expressions/ExprBlockSound.java @@ -25,8 +25,8 @@ "Gets the sound that a given block, blockdata, or itemtype will use in a specific scenario.", "This will actually return a string, in the form of \"SOUND_EXAMPLE\", which can be used in Skript syntax.", "", - "Check out this website for a list of sounds in Minecraft (Java Edition), " + - "or this one to go to the sounds wiki page." + "Check out this website for a list of sounds in Minecraft, " + + "or this one to go to the Sounds wiki page." }) @Examples({ "play sound (break sound of dirt) at all players", @@ -35,19 +35,57 @@ @Since("INSERT VERSION") public class ExprBlockSound extends SimpleExpression { - private static final int BREAK = 1, FALL = 2, HIT = 3, PLACE = 4, STEP = 5; + public enum SoundType { + BREAK { + @Override + public Sound getSound(SoundGroup group) { + return group.getBreakSound(); + } + }, + + FALL { + @Override + public Sound getSound(SoundGroup group) { + return group.getFallSound(); + } + }, + + HIT { + @Override + public Sound getSound(SoundGroup group) { + return group.getHitSound(); + } + }, + + PLACE { + @Override + public Sound getSound(SoundGroup group) { + return group.getPlaceSound(); + } + }, + + STEP { + @Override + public Sound getSound(SoundGroup group) { + return group.getStepSound(); + } + }; + + public abstract @Nullable Sound getSound(SoundGroup group); + } static { SimplePropertyExpression.register(ExprBlockSound.class, String.class, "(1:break|2:fall|3:hit|4:place|5:step) sound[s]", "blocks/blockdatas/itemtypes"); } - private int soundType; + @SuppressWarnings("NotNullFieldNotInitialized") + private SoundType soundType; @SuppressWarnings("NotNullFieldNotInitialized") private Expression objects; @Override public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { - soundType = parseResult.mark; + soundType = SoundType.values()[parseResult.mark - 1]; objects = exprs[0]; return true; } @@ -62,29 +100,23 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye .toArray(String[]::new); } - private @Nullable Sound convertAndGetSound(Object object) { - SoundGroup group = null; - + private @Nullable SoundGroup getSoundGroup(Object object) { if (object instanceof Block block) { - group = block.getBlockData().getSoundGroup(); + return block.getBlockData().getSoundGroup(); } else if (object instanceof BlockData data) { - group = data.getSoundGroup(); + return data.getSoundGroup(); } else if (object instanceof ItemType item) { if (item.hasBlock()) - group = item.getMaterial().createBlockData().getSoundGroup(); + return item.getMaterial().createBlockData().getSoundGroup(); } + return null; + } + private @Nullable Sound convertAndGetSound(Object object) { + SoundGroup group = getSoundGroup(object); if (group == null) return null; - - return switch (this.soundType) { - case BREAK -> group.getBreakSound(); - case FALL -> group.getFallSound(); - case HIT -> group.getHitSound(); - case PLACE -> group.getPlaceSound(); - case STEP -> group.getStepSound(); - default -> null; - }; + return this.soundType.getSound(group); } @Override @@ -99,14 +131,7 @@ public boolean isSingle() { @Override public @NotNull String toString(@Nullable Event event, boolean debug) { - return switch (this.soundType) { - case BREAK -> "break"; - case FALL -> "fall"; - case HIT -> "hit"; - case PLACE -> "place"; - case STEP -> "step"; - default -> null; - } + " sound of " + objects.toString(event, debug); + return this.soundType.name().toLowerCase() + " sound of " + objects.toString(event, debug); } } diff --git a/src/test/skript/tests/syntaxes/expressions/ExprBlockSound.sk b/src/test/skript/tests/syntaxes/expressions/ExprBlockSound.sk index a8f6e670352..14aaae265cc 100644 --- a/src/test/skript/tests/syntaxes/expressions/ExprBlockSound.sk +++ b/src/test/skript/tests/syntaxes/expressions/ExprBlockSound.sk @@ -2,21 +2,43 @@ test "block sounds": # === SETUP === - set {_block} to block at (spawn of world "world") - set {_before} to blockdata of {_block} - set blockdata of {_block} to stone[] - set {_data} to blockdata of {_block} - - set {_itemtype} to stone + set {_before} to blockdata of (block at (spawn of world "world")) # === TESTS === - assert break sound of {_block}, {_data} and {_itemtype} is "BLOCK_STONE_BREAK" with "break sound of stone wasn't BLOCK_STONE_BREAK" - assert fall sound of {_block}, {_data} and {_itemtype} is "BLOCK_STONE_FALL" with "fall sound of stone wasn't BLOCK_STONE_FALL" - assert hit sound of {_block}, {_data} and {_itemtype} is "BLOCK_STONE_HIT" with "hit sound of stone wasn't BLOCK_STONE_HIT" - assert place sound of {_block}, {_data} and {_itemtype} is "BLOCK_STONE_PLACE" with "place sound of stone wasn't BLOCK_STONE_PLACE" - assert step sound of {_block}, {_data} and {_itemtype} is "BLOCK_STONE_STEP" with "step sound of stone wasn't BLOCK_STONE_STEP" + set {_stone::*} to getObjects(stone) + assert break sound of {_stone::*} is "BLOCK_STONE_BREAK" with "break sound of stone wasn't BLOCK_STONE_BREAK" + assert fall sound of {_stone::*} is "BLOCK_STONE_FALL" with "fall sound of stone wasn't BLOCK_STONE_FALL" + assert hit sound of {_stone::*} is "BLOCK_STONE_HIT" with "hit sound of stone wasn't BLOCK_STONE_HIT" + assert place sound of {_stone::*} is "BLOCK_STONE_PLACE" with "place sound of stone wasn't BLOCK_STONE_PLACE" + assert step sound of {_stone::*} is "BLOCK_STONE_STEP" with "step sound of stone wasn't BLOCK_STONE_STEP" + + set {_wool::*} to getObjects(wool) + assert break sound of {_wool::*} is "BLOCK_WOOL_BREAK" with "break sound of stone wasn't BLOCK_WOOL_BREAK" + assert fall sound of {_wool::*} is "BLOCK_WOOL_FALL" with "fall sound of stone wasn't BLOCK_WOOL_FALL" + assert hit sound of {_wool::*} is "BLOCK_WOOL_HIT" with "hit sound of stone wasn't BLOCK_WOOL_HIT" + assert place sound of {_wool::*} is "BLOCK_WOOL_PLACE" with "place sound of stone wasn't BLOCK_WOOL_PLACE" + assert step sound of {_wool::*} is "BLOCK_WOOL_STEP" with "step sound of stone wasn't BLOCK_WOOL_STEP" + + assert break sound of (water, lava and bubble column) is "INTENTIONALLY_EMPTY" with "break sound of water, lava, or bubble column wasn't INTENTIONALLY_EMPTY" + assert fall sound of (water, lava and bubble column) is "INTENTIONALLY_EMPTY" with "fall sound of water, lava, or bubble column wasn't INTENTIONALLY_EMPTY" + assert hit sound of (water, lava and bubble column) is "INTENTIONALLY_EMPTY" with "hit sound of water, lava, or bubble column wasn't INTENTIONALLY_EMPTY" + assert place sound of (water, lava and bubble column) is "INTENTIONALLY_EMPTY" with "place sound of water, lava, or bubble column wasn't INTENTIONALLY_EMPTY" + assert step sound of (water, lava and bubble column) is "INTENTIONALLY_EMPTY" with "step sound of water, lava, or bubble column wasn't INTENTIONALLY_EMPTY" + + assert break sound of (diamond, diamond sword and {_none}) is not set with "break sound of non-block item shouldn't be set" + assert fall sound of (diamond, diamond sword and {_none}) is not set with "fall sound of non-block item shouldn't be set" + assert hit sound of (diamond, diamond sword and {_none}) is not set with "hit sound of non-block item shouldn't be set" + assert place sound of (diamond, diamond sword and {_none}) is not set with "place sound of non-block item shouldn't be set" + assert step sound of (diamond, diamond sword and {_none}) is not set with "step sound of non-block item shouldn't be set" # === CLEANUP === set blockdata of {_block} to {_before} + +local function getObjects(i: itemtype) :: objects: + if (block at (spawn of world "world")) is not {_i}: + set block at (spawn of world "world") to {_i} + set {_block} to block at (spawn of world "world") + set {_data} to blockdata of {_block} + return {_block}, {_data} and {_i} From af7eb72f741e7318bb79906e85884210a78c3a50 Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Mon, 9 Sep 2024 04:08:51 +1000 Subject: [PATCH 5/5] Fixes tests failing due to 1.19 not using INTENTIONALLY_EMPTY sound --- .../tests/syntaxes/expressions/ExprBlockSound.sk | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/test/skript/tests/syntaxes/expressions/ExprBlockSound.sk b/src/test/skript/tests/syntaxes/expressions/ExprBlockSound.sk index 14aaae265cc..133ea5a7e7c 100644 --- a/src/test/skript/tests/syntaxes/expressions/ExprBlockSound.sk +++ b/src/test/skript/tests/syntaxes/expressions/ExprBlockSound.sk @@ -1,8 +1,10 @@ -test "block sounds": +test "block sounds (1.20+)": # === SETUP === set {_before} to blockdata of (block at (spawn of world "world")) + set {_20} to whether running minecraft "1.20" + set {_empty} to "INTENTIONALLY_EMPTY" if running minecraft "1.20" else "BLOCK_STONE_PLACE" # === TESTS === @@ -20,11 +22,11 @@ test "block sounds": assert place sound of {_wool::*} is "BLOCK_WOOL_PLACE" with "place sound of stone wasn't BLOCK_WOOL_PLACE" assert step sound of {_wool::*} is "BLOCK_WOOL_STEP" with "step sound of stone wasn't BLOCK_WOOL_STEP" - assert break sound of (water, lava and bubble column) is "INTENTIONALLY_EMPTY" with "break sound of water, lava, or bubble column wasn't INTENTIONALLY_EMPTY" - assert fall sound of (water, lava and bubble column) is "INTENTIONALLY_EMPTY" with "fall sound of water, lava, or bubble column wasn't INTENTIONALLY_EMPTY" - assert hit sound of (water, lava and bubble column) is "INTENTIONALLY_EMPTY" with "hit sound of water, lava, or bubble column wasn't INTENTIONALLY_EMPTY" - assert place sound of (water, lava and bubble column) is "INTENTIONALLY_EMPTY" with "place sound of water, lava, or bubble column wasn't INTENTIONALLY_EMPTY" - assert step sound of (water, lava and bubble column) is "INTENTIONALLY_EMPTY" with "step sound of water, lava, or bubble column wasn't INTENTIONALLY_EMPTY" + assert break sound of (water, lava and bubble column) is ("INTENTIONALLY_EMPTY" if {_20} is true else "BLOCK_STONE_BREAK") with "break sound of water, lava, or bubble column wasn't INTENTIONALLY_EMPTY" + assert fall sound of (water, lava and bubble column) is ("INTENTIONALLY_EMPTY" if {_20} is true else "BLOCK_STONE_FALL") with "fall sound of water, lava, or bubble column wasn't INTENTIONALLY_EMPTY" + assert hit sound of (water, lava and bubble column) is ("INTENTIONALLY_EMPTY" if {_20} is true else "BLOCK_STONE_HIT") with "hit sound of water, lava, or bubble column wasn't INTENTIONALLY_EMPTY" + assert place sound of (water, lava and bubble column) is ("INTENTIONALLY_EMPTY" if {_20} is true else "BLOCK_STONE_PLACE") with "place sound of water, lava, or bubble column wasn't INTENTIONALLY_EMPTY" + assert step sound of (water, lava and bubble column) is ("INTENTIONALLY_EMPTY" if {_20} is true else "BLOCK_STONE_STEP") with "step sound of water, lava, or bubble column wasn't INTENTIONALLY_EMPTY" assert break sound of (diamond, diamond sword and {_none}) is not set with "break sound of non-block item shouldn't be set" assert fall sound of (diamond, diamond sword and {_none}) is not set with "fall sound of non-block item shouldn't be set"