From 348e0ac833f8de15f1d8c03eec079f2772f055ce Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Sun, 1 Sep 2024 00:30:27 +1000 Subject: [PATCH 1/6] Adds entity sound expression and test --- .../skript/expressions/ExprEntitySound.java | 154 ++++++++++++++++++ .../syntaxes/expressions/ExprEntitySound.sk | 19 +++ 2 files changed, 173 insertions(+) create mode 100644 src/main/java/ch/njol/skript/expressions/ExprEntitySound.java create mode 100644 src/test/skript/tests/syntaxes/expressions/ExprEntitySound.sk diff --git a/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java b/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java new file mode 100644 index 00000000000..47c836d55a9 --- /dev/null +++ b/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java @@ -0,0 +1,154 @@ +package ch.njol.skript.expressions; + +import ch.njol.skript.Skript; +import ch.njol.skript.aliases.ItemType; +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.Material; +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Event; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.HashSet; +import java.util.Set; + +public class ExprEntitySound extends SimpleExpression { + + static { + if (Skript.methodExists(LivingEntity.class, "getDeathSound")) { + Skript.registerExpression(ExprEntitySound.class, String.class, ExpressionType.COMBINED, + "[the] (damage|hurt) sound[s] of %livingentities%", + "%livingentities%'[s] (damage|hurt) sound[s]", + + "[the] death sound[s] of %livingentities%", + "%livingentities%'[s] death sound[s]", + + "[the] [high:(tall|high)|(low|normal)] fall [damage] sound[s] [from [[a] height [of]] %-number%] of %livingentities%", + "%livingentities%'[s] [high:(tall|high)|low:(low|normal)] fall [damage] sound[s] [from [[a] height [of]] %-number%]", + + "[the] swim[ming] sound[s] of %livingentities%", + "%livingentities%'[s] swim[ming] sound[s]", + + "[the] [fast:(fast|speedy)] splash sound[s] of %livingentities%", + "%livingentities%'[s] [fast:(fast|speedy)] splash sound[s]", + + "[the] eat[ing] sound of %livingentities% [(with|using|[while] eating [a]) %-itemtype%]", + "%livingentities%'[s] eat[ing] sound", + + "[the] drink[ing] sound of %livingentities% [(with|using|[while] drinking [a]) %-itemtype%]", + "%livingentities%'[s] drink[ing] sound"); + } + } + + private static final int DAMAGE = 0; + private static final int DEATH = 2; + private static final int FALL = 4; + private static final int SWIM = 6; + private static final int SPLASH = 8; + private static final int EAT_WITH_ITEM = 10; + private static final int EAT = 11; + private static final int DRINK_WITH_ITEM = 12; + private static final int DRINK = 13; + + private int sound; + private boolean big; + @SuppressWarnings("NotNullFieldNotInitialized") + private Expression height; + @SuppressWarnings("NotNullFieldNotInitialized") + private Expression entities; + @SuppressWarnings("NotNullFieldNotInitialized") + private Expression item; + + @Override + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + sound = matchedPattern; + big = parseResult.hasTag("high") || parseResult.hasTag("fast"); + if (matchedPattern == FALL || matchedPattern == FALL + 1) + height = (Expression) exprs[0]; + if (matchedPattern == EAT_WITH_ITEM || matchedPattern == DRINK_WITH_ITEM) + item = (Expression) exprs[1]; + entities = (Expression) ((matchedPattern == FALL) ? exprs[1] : exprs[0]); + return true; + } + + @Override + protected String @Nullable [] get(Event event) { + Set sounds = new HashSet<>(); + for (LivingEntity entity : entities.getArray(event)) { + Sound sound = getEntitySound(entity, event); + if (sound != null) + sounds.add(sound.name()); + } + return sounds.toArray(String[]::new); + } + + private @Nullable Sound getEntitySound(LivingEntity entity, Event event) { + Sound sound = null; + switch (this.sound) { + case DAMAGE, DAMAGE + 1 -> sound = entity.getHurtSound(); + case DEATH, DEATH + 1 -> sound = entity.getDeathSound(); + case FALL, FALL + 1 -> sound = getFallSound(entity, event); + case SWIM, SWIM + 1 -> sound = entity.getSwimSound(); + case SPLASH, SPLASH + 1 -> sound = big ? entity.getSwimHighSpeedSplashSound() : entity.getSwimSplashSound(); + case EAT_WITH_ITEM, DRINK_WITH_ITEM -> sound = getConsumeSound(entity, event); + case EAT -> sound = entity.getEatingSound(new ItemStack(Material.COOKED_BEEF)); + case DRINK -> sound = entity.getDrinkingSound(new ItemStack(Material.POTION)); + } + return sound; + } + + private Sound getFallSound(LivingEntity entity, Event event) { + //noinspection ConstantValue + int height = this.height == null ? -1 : this.height.getOptionalSingle(event).orElse(-1).intValue(); + return height != -1 ? entity.getFallDamageSound(height) : + (big ? entity.getFallDamageSoundBig() : entity.getFallDamageSoundSmall()); + } + + private Sound getConsumeSound(LivingEntity entity, Event event) { + ItemStack defaultItem = new ItemStack(sound == EAT_WITH_ITEM ? Material.COOKED_BEEF : Material.POTION); + //noinspection ConstantValue + ItemStack item = this.item == null ? defaultItem : this.item.getOptionalSingle(event).orElse(new ItemType(defaultItem)).getRandom(); + if (item == null) + item = defaultItem; + return sound == EAT_WITH_ITEM ? entity.getEatingSound(item) : entity.getDrinkingSound(item); + } + + @Override + public boolean isSingle() { + return entities.isSingle(); + } + + @Override + public Class getReturnType() { + return String.class; + } + + @Override + @SuppressWarnings("ConstantValue") + public String toString(@Nullable Event event, boolean debug) { + String name = "unknown"; + switch (sound) { + case DAMAGE, DAMAGE + 1 -> name = "damage"; + case DEATH, DEATH + 1 -> name = "death"; + case FALL, FALL + 1 -> { + if (this.height == null) { + name = big ? "high fall damage" : "normal fall damage"; + } else { + name = "fall damage from a height of " + this.height.toString(event, debug); + } + } + case SWIM, SWIM + 1 -> name = "swim"; + case SPLASH, SPLASH + 1 -> name = big ? "speedy splash" : "splash"; + case EAT_WITH_ITEM, DRINK_WITH_ITEM -> name = (sound == EAT_WITH_ITEM ? "eating" : "drinking") + (this.item == null ? " with default item" : " " + this.item.toString(event, debug)); + case EAT, DRINK -> name = sound == EAT ? "eating" : "drinking"; + } + return name + " sound of " + entities.toString(event, debug); + } + +} diff --git a/src/test/skript/tests/syntaxes/expressions/ExprEntitySound.sk b/src/test/skript/tests/syntaxes/expressions/ExprEntitySound.sk new file mode 100644 index 00000000000..87d737994f2 --- /dev/null +++ b/src/test/skript/tests/syntaxes/expressions/ExprEntitySound.sk @@ -0,0 +1,19 @@ +test "entity sounds": + spawn a zombie at (spawn of world "world"): + set {_z} to entity + + assert damage sound of {_z} is "ENTITY_ZOMBIE_HURT" with "damage sound of zombie should return ENTITY_ZOMBIE_HURT" + assert death sound of {_z} is "ENTITY_ZOMBIE_DEATH" with "death sound of zombie should return ENTITY_ZOMBIE_DEATH" + assert swim sound of {_z} is "ENTITY_HOSTILE_SWIM" with "swim sound of zombie should return ENTITY_HOSTILE_SWIM" + assert normal fall sound of {_z} is "ENTITY_HOSTILE_SMALL_FALL" with "fall sound of zombie should return ENTITY_HOSTILE_SMALL_FALL" + assert high fall sound of {_z} is "ENTITY_HOSTILE_BIG_FALL" with "high fall sound of zombie should return ENTITY_HOSTILE_BIG_FALL" + assert fall sound from a height of 10 of {_z} is "ENTITY_HOSTILE_BIG_FALL" with "fall sound from height of 10 sound of zombie should return ENTITY_HOSTILE_BIG_FALL" + assert fall sound from a height of {_none} of {_z} is "ENTITY_HOSTILE_SMALL_FALL" with "fall sound from invalid height sound of zombie should return ENTITY_HOSTILE_SMALL_FALL" + assert splash sound of {_z} is "ENTITY_HOSTILE_SPLASH" with "splash sound of zombie should return ENTITY_HOSTILE_SPLASH" + assert speedy splash sound of {_z} is "ENTITY_GENERIC_SPLASH" with "speedy splash sound of zombie should return ENTITY_GENERIC_SPLASH" + assert eating sound of {_z} is "ENTITY_GENERIC_EAT" with "eating sound of zombie should return ENTITY_GENERIC_EAT" + assert eating sound of {_z} using golden apple is "ENTITY_GENERIC_EAT" with "eating sound of zombie using golden apple should return ENTITY_GENERIC_EAT" + assert drinking sound of {_z} is "ENTITY_GENERIC_DRINK" with "drinking sound of zombie should return ENTITY_GENERIC_DRINK" + assert drinking sound of {_z} using potion is "ENTITY_GENERIC_DRINK" with "drinking sound of zombie using potion should return ENTITY_GENERIC_DRINK" + + delete entity within {_z} From a4c3f9704343a2ff827125bd174ff5a88f5b9b4c Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Sun, 1 Sep 2024 01:26:05 +1000 Subject: [PATCH 2/6] Apply suggestions from code review Co-authored-by: _tud <98935832+UnderscoreTud@users.noreply.github.com> --- src/main/java/ch/njol/skript/expressions/ExprEntitySound.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java b/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java index 47c836d55a9..85bfa9b0f32 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java +++ b/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java @@ -85,7 +85,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye if (sound != null) sounds.add(sound.name()); } - return sounds.toArray(String[]::new); + return sounds.toArray(new String[0]); } private @Nullable Sound getEntitySound(LivingEntity entity, Event event) { @@ -113,7 +113,7 @@ private Sound getFallSound(LivingEntity entity, Event event) { private Sound getConsumeSound(LivingEntity entity, Event event) { ItemStack defaultItem = new ItemStack(sound == EAT_WITH_ITEM ? Material.COOKED_BEEF : Material.POTION); //noinspection ConstantValue - ItemStack item = this.item == null ? defaultItem : this.item.getOptionalSingle(event).orElse(new ItemType(defaultItem)).getRandom(); + ItemStack item = this.item == null ? defaultItem : this.item.getOptionalSingle(event).map(ItemType::getRandom).orElse(defaultItem); if (item == null) item = defaultItem; return sound == EAT_WITH_ITEM ? entity.getEatingSound(item) : entity.getDrinkingSound(item); From 167309ccf9a4b293778b3583d67c5eada4699241 Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Sun, 1 Sep 2024 02:13:47 +1000 Subject: [PATCH 3/6] Suggestions and stuff --- .../skript/expressions/ExprEntitySound.java | 91 +++++++++---------- .../syntaxes/expressions/ExprEntitySound.sk | 31 +++---- 2 files changed, 55 insertions(+), 67 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java b/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java index 85bfa9b0f32..19652cbf903 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java +++ b/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java @@ -14,8 +14,7 @@ import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; -import java.util.HashSet; -import java.util.Set; +import java.util.Objects; public class ExprEntitySound extends SimpleExpression { @@ -55,7 +54,7 @@ public class ExprEntitySound extends SimpleExpression { private static final int DRINK_WITH_ITEM = 12; private static final int DRINK = 13; - private int sound; + private int soundPattern; private boolean big; @SuppressWarnings("NotNullFieldNotInitialized") private Expression height; @@ -67,7 +66,7 @@ public class ExprEntitySound extends SimpleExpression { @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { - sound = matchedPattern; + soundPattern = matchedPattern; big = parseResult.hasTag("high") || parseResult.hasTag("fast"); if (matchedPattern == FALL || matchedPattern == FALL + 1) height = (Expression) exprs[0]; @@ -78,45 +77,37 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } @Override + @SuppressWarnings("ConstantValue") protected String @Nullable [] get(Event event) { - Set sounds = new HashSet<>(); - for (LivingEntity entity : entities.getArray(event)) { - Sound sound = getEntitySound(entity, event); - if (sound != null) - sounds.add(sound.name()); - } - return sounds.toArray(new String[0]); - } + int height = this.height == null ? -1 : this.height.getOptionalSingle(event).orElse(-1).intValue(); - private @Nullable Sound getEntitySound(LivingEntity entity, Event event) { - Sound sound = null; - switch (this.sound) { - case DAMAGE, DAMAGE + 1 -> sound = entity.getHurtSound(); - case DEATH, DEATH + 1 -> sound = entity.getDeathSound(); - case FALL, FALL + 1 -> sound = getFallSound(entity, event); - case SWIM, SWIM + 1 -> sound = entity.getSwimSound(); - case SPLASH, SPLASH + 1 -> sound = big ? entity.getSwimHighSpeedSplashSound() : entity.getSwimSplashSound(); - case EAT_WITH_ITEM, DRINK_WITH_ITEM -> sound = getConsumeSound(entity, event); - case EAT -> sound = entity.getEatingSound(new ItemStack(Material.COOKED_BEEF)); - case DRINK -> sound = entity.getDrinkingSound(new ItemStack(Material.POTION)); - } - return sound; - } + ItemStack defaultItem = new ItemStack(soundPattern == EAT_WITH_ITEM ? Material.COOKED_BEEF : Material.POTION); + ItemStack item = this.item == null ? defaultItem : this.item.getOptionalSingle(event).map(ItemType::getRandom).orElse(defaultItem); - private Sound getFallSound(LivingEntity entity, Event event) { - //noinspection ConstantValue - int height = this.height == null ? -1 : this.height.getOptionalSingle(event).orElse(-1).intValue(); - return height != -1 ? entity.getFallDamageSound(height) : - (big ? entity.getFallDamageSoundBig() : entity.getFallDamageSoundSmall()); + return entities.stream(event) + .map(entity -> getEntitySound(entity, height, item)) + .filter(Objects::nonNull) + .distinct() + .map(Sound::name) + .toArray(String[]::new); } - private Sound getConsumeSound(LivingEntity entity, Event event) { - ItemStack defaultItem = new ItemStack(sound == EAT_WITH_ITEM ? Material.COOKED_BEEF : Material.POTION); - //noinspection ConstantValue - ItemStack item = this.item == null ? defaultItem : this.item.getOptionalSingle(event).map(ItemType::getRandom).orElse(defaultItem); - if (item == null) - item = defaultItem; - return sound == EAT_WITH_ITEM ? entity.getEatingSound(item) : entity.getDrinkingSound(item); + private @Nullable Sound getEntitySound(LivingEntity entity, int height, ItemStack item) { + return switch (this.soundPattern) { + case DAMAGE, DAMAGE + 1 -> entity.getHurtSound(); + case DEATH, DEATH + 1 -> entity.getDeathSound(); + case FALL, FALL + 1 -> { + if (height != -1) + yield entity.getFallDamageSound(height); + else + yield big ? entity.getFallDamageSoundBig() : entity.getFallDamageSoundSmall(); + } + case SWIM, SWIM + 1 -> entity.getSwimSound(); + case SPLASH, SPLASH + 1 -> big ? entity.getSwimHighSpeedSplashSound() : entity.getSwimSplashSound(); + case EAT, EAT_WITH_ITEM -> entity.getEatingSound(item); + case DRINK, DRINK_WITH_ITEM -> entity.getDrinkingSound(item); + default -> null; + }; } @Override @@ -132,23 +123,23 @@ public Class getReturnType() { @Override @SuppressWarnings("ConstantValue") public String toString(@Nullable Event event, boolean debug) { - String name = "unknown"; - switch (sound) { - case DAMAGE, DAMAGE + 1 -> name = "damage"; - case DEATH, DEATH + 1 -> name = "death"; + return switch (soundPattern) { + case DAMAGE, DAMAGE + 1 -> "damage"; + case DEATH, DEATH + 1 -> "death"; case FALL, FALL + 1 -> { if (this.height == null) { - name = big ? "high fall damage" : "normal fall damage"; + yield big ? "high fall damage" : "normal fall damage"; } else { - name = "fall damage from a height of " + this.height.toString(event, debug); + yield "fall damage from a height of " + this.height.toString(event, debug); } } - case SWIM, SWIM + 1 -> name = "swim"; - case SPLASH, SPLASH + 1 -> name = big ? "speedy splash" : "splash"; - case EAT_WITH_ITEM, DRINK_WITH_ITEM -> name = (sound == EAT_WITH_ITEM ? "eating" : "drinking") + (this.item == null ? " with default item" : " " + this.item.toString(event, debug)); - case EAT, DRINK -> name = sound == EAT ? "eating" : "drinking"; - } - return name + " sound of " + entities.toString(event, debug); + case SWIM, SWIM + 1 -> "swim"; + case SPLASH, SPLASH + 1 -> big ? "speedy splash" : "splash"; + case EAT_WITH_ITEM, DRINK_WITH_ITEM -> (soundPattern == EAT_WITH_ITEM ? "eating" : "drinking") + + (this.item == null ? " with default item" : " " + this.item.toString(event, debug)); + case EAT, DRINK -> soundPattern == EAT ? "eating" : "drinking"; + default -> "unknown"; + } + " sound of " + entities.toString(event, debug); } } diff --git a/src/test/skript/tests/syntaxes/expressions/ExprEntitySound.sk b/src/test/skript/tests/syntaxes/expressions/ExprEntitySound.sk index 87d737994f2..6df06ddc0ce 100644 --- a/src/test/skript/tests/syntaxes/expressions/ExprEntitySound.sk +++ b/src/test/skript/tests/syntaxes/expressions/ExprEntitySound.sk @@ -1,19 +1,16 @@ test "entity sounds": spawn a zombie at (spawn of world "world"): - set {_z} to entity - - assert damage sound of {_z} is "ENTITY_ZOMBIE_HURT" with "damage sound of zombie should return ENTITY_ZOMBIE_HURT" - assert death sound of {_z} is "ENTITY_ZOMBIE_DEATH" with "death sound of zombie should return ENTITY_ZOMBIE_DEATH" - assert swim sound of {_z} is "ENTITY_HOSTILE_SWIM" with "swim sound of zombie should return ENTITY_HOSTILE_SWIM" - assert normal fall sound of {_z} is "ENTITY_HOSTILE_SMALL_FALL" with "fall sound of zombie should return ENTITY_HOSTILE_SMALL_FALL" - assert high fall sound of {_z} is "ENTITY_HOSTILE_BIG_FALL" with "high fall sound of zombie should return ENTITY_HOSTILE_BIG_FALL" - assert fall sound from a height of 10 of {_z} is "ENTITY_HOSTILE_BIG_FALL" with "fall sound from height of 10 sound of zombie should return ENTITY_HOSTILE_BIG_FALL" - assert fall sound from a height of {_none} of {_z} is "ENTITY_HOSTILE_SMALL_FALL" with "fall sound from invalid height sound of zombie should return ENTITY_HOSTILE_SMALL_FALL" - assert splash sound of {_z} is "ENTITY_HOSTILE_SPLASH" with "splash sound of zombie should return ENTITY_HOSTILE_SPLASH" - assert speedy splash sound of {_z} is "ENTITY_GENERIC_SPLASH" with "speedy splash sound of zombie should return ENTITY_GENERIC_SPLASH" - assert eating sound of {_z} is "ENTITY_GENERIC_EAT" with "eating sound of zombie should return ENTITY_GENERIC_EAT" - assert eating sound of {_z} using golden apple is "ENTITY_GENERIC_EAT" with "eating sound of zombie using golden apple should return ENTITY_GENERIC_EAT" - assert drinking sound of {_z} is "ENTITY_GENERIC_DRINK" with "drinking sound of zombie should return ENTITY_GENERIC_DRINK" - assert drinking sound of {_z} using potion is "ENTITY_GENERIC_DRINK" with "drinking sound of zombie using potion should return ENTITY_GENERIC_DRINK" - - delete entity within {_z} + assert damage sound of entity is "ENTITY_ZOMBIE_HURT" with "damage sound of zombie should return ENTITY_ZOMBIE_HURT" + assert death sound of entity is "ENTITY_ZOMBIE_DEATH" with "death sound of zombie should return ENTITY_ZOMBIE_DEATH" + assert swim sound of entity is "ENTITY_HOSTILE_SWIM" with "swim sound of zombie should return ENTITY_HOSTILE_SWIM" + assert normal fall sound of entity is "ENTITY_HOSTILE_SMALL_FALL" with "fall sound of zombie should return ENTITY_HOSTILE_SMALL_FALL" + assert high fall sound of entity is "ENTITY_HOSTILE_BIG_FALL" with "high fall sound of zombie should return ENTITY_HOSTILE_BIG_FALL" + assert fall sound from a height of 10 of entity is "ENTITY_HOSTILE_BIG_FALL" with "fall sound from height of 10 sound of zombie should return ENTITY_HOSTILE_BIG_FALL" + assert fall sound from a height of {_none} of entity is "ENTITY_HOSTILE_SMALL_FALL" with "fall sound from invalid height sound of zombie should return ENTITY_HOSTILE_SMALL_FALL" + assert splash sound of entity is "ENTITY_HOSTILE_SPLASH" with "splash sound of zombie should return ENTITY_HOSTILE_SPLASH" + assert speedy splash sound of entity is "ENTITY_GENERIC_SPLASH" with "speedy splash sound of zombie should return ENTITY_GENERIC_SPLASH" + assert eating sound of entity is "ENTITY_GENERIC_EAT" with "eating sound of zombie should return ENTITY_GENERIC_EAT" + assert eating sound of entity using golden apple is "ENTITY_GENERIC_EAT" with "eating sound of zombie using golden apple should return ENTITY_GENERIC_EAT" + assert drinking sound of entity is "ENTITY_GENERIC_DRINK" with "drinking sound of zombie should return ENTITY_GENERIC_DRINK" + assert drinking sound of entity using potion is "ENTITY_GENERIC_DRINK" with "drinking sound of zombie using potion should return ENTITY_GENERIC_DRINK" + delete entity From 137f7d820d12e9107fb8f54f80dd52f7286f03e5 Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Fri, 6 Sep 2024 04:52:44 +1000 Subject: [PATCH 4/6] Some changes - Updates fall damage pattern to not conflict with new block sound PR - Fixes some other patterns missing some small details - Adds Skript doc annotations - Adds new ambient sound --- .../skript/expressions/ExprEntitySound.java | 30 +++++++++++++++---- .../syntaxes/expressions/ExprEntitySound.sk | 9 +++--- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java b/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java index 19652cbf903..b1f448862ec 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java +++ b/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java @@ -2,6 +2,11 @@ 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.RequiredPlugins; +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; @@ -10,12 +15,21 @@ import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Mob; import org.bukkit.event.Event; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; import java.util.Objects; +@Name("Entity Sound") +@Description("Gets the sound that a given entity will make in a specific scenario.") +@Examples({ + "play sound (hurt sound of player) at player", + "set {_sounds::*} to death sounds of (all mobs in radius 10 of player)" +}) +@Since("INSERT VERSION") +@RequiredPlugins("Spigot 1.19.2+") public class ExprEntitySound extends SimpleExpression { static { @@ -27,7 +41,7 @@ public class ExprEntitySound extends SimpleExpression { "[the] death sound[s] of %livingentities%", "%livingentities%'[s] death sound[s]", - "[the] [high:(tall|high)|(low|normal)] fall [damage] sound[s] [from [[a] height [of]] %-number%] of %livingentities%", + "[the] [high:(tall|high)|(low|normal)] fall damage sound[s] [from [[a] height [of]] %-number%] of %livingentities%", "%livingentities%'[s] [high:(tall|high)|low:(low|normal)] fall [damage] sound[s] [from [[a] height [of]] %-number%]", "[the] swim[ming] sound[s] of %livingentities%", @@ -36,11 +50,14 @@ public class ExprEntitySound extends SimpleExpression { "[the] [fast:(fast|speedy)] splash sound[s] of %livingentities%", "%livingentities%'[s] [fast:(fast|speedy)] splash sound[s]", - "[the] eat[ing] sound of %livingentities% [(with|using|[while] eating [a]) %-itemtype%]", - "%livingentities%'[s] eat[ing] sound", + "[the] eat[ing] sound[s] of %livingentities% [(with|using|[while] eating [a]) %-itemtype%]", + "%livingentities%'[s] eat[ing] sound[s]", - "[the] drink[ing] sound of %livingentities% [(with|using|[while] drinking [a]) %-itemtype%]", - "%livingentities%'[s] drink[ing] sound"); + "[the] drink[ing] sound[s] of %livingentities% [(with|using|[while] drinking [a]) %-itemtype%]", + "%livingentities%'[s] drink[ing] sound[s]", + + "[the] ambient sound[s] of %livingentities%", + "%livingentities%'[s] ambient sound[s]"); } } @@ -53,6 +70,7 @@ public class ExprEntitySound extends SimpleExpression { private static final int EAT = 11; private static final int DRINK_WITH_ITEM = 12; private static final int DRINK = 13; + private static final int AMBIENT = 14; private int soundPattern; private boolean big; @@ -106,6 +124,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye case SPLASH, SPLASH + 1 -> big ? entity.getSwimHighSpeedSplashSound() : entity.getSwimSplashSound(); case EAT, EAT_WITH_ITEM -> entity.getEatingSound(item); case DRINK, DRINK_WITH_ITEM -> entity.getDrinkingSound(item); + case AMBIENT -> entity instanceof Mob mob ? mob.getAmbientSound() : null; default -> null; }; } @@ -138,6 +157,7 @@ public String toString(@Nullable Event event, boolean debug) { case EAT_WITH_ITEM, DRINK_WITH_ITEM -> (soundPattern == EAT_WITH_ITEM ? "eating" : "drinking") + (this.item == null ? " with default item" : " " + this.item.toString(event, debug)); case EAT, DRINK -> soundPattern == EAT ? "eating" : "drinking"; + case AMBIENT -> "ambient"; default -> "unknown"; } + " sound of " + entities.toString(event, debug); } diff --git a/src/test/skript/tests/syntaxes/expressions/ExprEntitySound.sk b/src/test/skript/tests/syntaxes/expressions/ExprEntitySound.sk index 6df06ddc0ce..4a536367a55 100644 --- a/src/test/skript/tests/syntaxes/expressions/ExprEntitySound.sk +++ b/src/test/skript/tests/syntaxes/expressions/ExprEntitySound.sk @@ -3,14 +3,15 @@ test "entity sounds": assert damage sound of entity is "ENTITY_ZOMBIE_HURT" with "damage sound of zombie should return ENTITY_ZOMBIE_HURT" assert death sound of entity is "ENTITY_ZOMBIE_DEATH" with "death sound of zombie should return ENTITY_ZOMBIE_DEATH" assert swim sound of entity is "ENTITY_HOSTILE_SWIM" with "swim sound of zombie should return ENTITY_HOSTILE_SWIM" - assert normal fall sound of entity is "ENTITY_HOSTILE_SMALL_FALL" with "fall sound of zombie should return ENTITY_HOSTILE_SMALL_FALL" - assert high fall sound of entity is "ENTITY_HOSTILE_BIG_FALL" with "high fall sound of zombie should return ENTITY_HOSTILE_BIG_FALL" - assert fall sound from a height of 10 of entity is "ENTITY_HOSTILE_BIG_FALL" with "fall sound from height of 10 sound of zombie should return ENTITY_HOSTILE_BIG_FALL" - assert fall sound from a height of {_none} of entity is "ENTITY_HOSTILE_SMALL_FALL" with "fall sound from invalid height sound of zombie should return ENTITY_HOSTILE_SMALL_FALL" + assert normal fall damage sound of entity is "ENTITY_HOSTILE_SMALL_FALL" with "fall sound of zombie should return ENTITY_HOSTILE_SMALL_FALL" + assert high fall damage sound of entity is "ENTITY_HOSTILE_BIG_FALL" with "high fall sound of zombie should return ENTITY_HOSTILE_BIG_FALL" + assert fall damage sound from a height of 10 of entity is "ENTITY_HOSTILE_BIG_FALL" with "fall sound from height of 10 sound of zombie should return ENTITY_HOSTILE_BIG_FALL" + assert fall damage sound from a height of {_none} of entity is "ENTITY_HOSTILE_SMALL_FALL" with "fall sound from invalid height sound of zombie should return ENTITY_HOSTILE_SMALL_FALL" assert splash sound of entity is "ENTITY_HOSTILE_SPLASH" with "splash sound of zombie should return ENTITY_HOSTILE_SPLASH" assert speedy splash sound of entity is "ENTITY_GENERIC_SPLASH" with "speedy splash sound of zombie should return ENTITY_GENERIC_SPLASH" assert eating sound of entity is "ENTITY_GENERIC_EAT" with "eating sound of zombie should return ENTITY_GENERIC_EAT" assert eating sound of entity using golden apple is "ENTITY_GENERIC_EAT" with "eating sound of zombie using golden apple should return ENTITY_GENERIC_EAT" assert drinking sound of entity is "ENTITY_GENERIC_DRINK" with "drinking sound of zombie should return ENTITY_GENERIC_DRINK" assert drinking sound of entity using potion is "ENTITY_GENERIC_DRINK" with "drinking sound of zombie using potion should return ENTITY_GENERIC_DRINK" + assert ambient sound of entity is "ENTITY_ZOMBIE_AMBIENT" with "ambient sound of zombie should return ENTITY_ZOMBIE_AMBIENT" delete entity From 116850464025271d52ff7af4fde69640ec7f3cb8 Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Tue, 24 Sep 2024 00:37:33 +1000 Subject: [PATCH 5/6] Implements an enum to handle some logic in a nicer way and suggested changes --- .../skript/expressions/ExprEntitySound.java | 185 +++++++++++------- .../java/ch/njol/skript/util/Patterns.java | 20 +- 2 files changed, 111 insertions(+), 94 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java b/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java index b1f448862ec..903628b4476 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java +++ b/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java @@ -11,6 +11,7 @@ import ch.njol.skript.lang.ExpressionType; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; +import ch.njol.skript.util.Patterns; import ch.njol.util.Kleenean; import org.bukkit.Material; import org.bukkit.Sound; @@ -32,48 +33,96 @@ @RequiredPlugins("Spigot 1.19.2+") public class ExprEntitySound extends SimpleExpression { - static { - if (Skript.methodExists(LivingEntity.class, "getDeathSound")) { - Skript.registerExpression(ExprEntitySound.class, String.class, ExpressionType.COMBINED, - "[the] (damage|hurt) sound[s] of %livingentities%", - "%livingentities%'[s] (damage|hurt) sound[s]", + public enum SoundType { + DAMAGE { + @Override + public @Nullable Sound getSound(LivingEntity entity, int height, ItemStack item, boolean bigOrSpeedy) { + return entity.getHurtSound(); + } + }, + DEATH { + @Override + public @Nullable Sound getSound(LivingEntity entity, int height, ItemStack item, boolean bigOrSpeedy) { + return entity.getDeathSound(); + } + }, + FALL { + @Override + public Sound getSound(LivingEntity entity, int height, ItemStack item, boolean bigOrSpeedy) { + if (height != -1) + return entity.getFallDamageSound(height); + else + return bigOrSpeedy ? entity.getFallDamageSoundBig() : entity.getFallDamageSoundSmall(); + } + }, + SWIM { + @Override + public Sound getSound(LivingEntity entity, int height, ItemStack item, boolean bigOrSpeedy) { + return entity.getSwimSound(); + } + }, + SPLASH { + @Override + public Sound getSound(LivingEntity entity, int height, ItemStack item, boolean bigOrSpeedy) { + return bigOrSpeedy ? entity.getSwimHighSpeedSplashSound() : entity.getSwimSplashSound(); + } + }, + EAT { + @Override + public Sound getSound(LivingEntity entity, int height, ItemStack item, boolean bigOrSpeedy) { + return entity.getEatingSound(item); + } + }, + DRINK { + @Override + public Sound getSound(LivingEntity entity, int height, ItemStack item, boolean bigOrSpeedy) { + return entity.getDrinkingSound(item); + } + }, + AMBIENT { + @Override + public @Nullable Sound getSound(LivingEntity entity, int height, ItemStack item, boolean bigOrSpeedy) { + return entity instanceof Mob mob ? mob.getAmbientSound() : null; + } + }; - "[the] death sound[s] of %livingentities%", - "%livingentities%'[s] death sound[s]", + public abstract @Nullable Sound getSound(LivingEntity entity, int height, ItemStack item, boolean bigOrSpeedy); + } - "[the] [high:(tall|high)|(low|normal)] fall damage sound[s] [from [[a] height [of]] %-number%] of %livingentities%", - "%livingentities%'[s] [high:(tall|high)|low:(low|normal)] fall [damage] sound[s] [from [[a] height [of]] %-number%]", + private static final Patterns patterns = new Patterns<>(new Object[][]{ + {"[the] (damage|hurt) sound[s] of %livingentities%", SoundType.DAMAGE}, + {"%livingentities%'[s] (damage|hurt) sound[s]", SoundType.DAMAGE}, - "[the] swim[ming] sound[s] of %livingentities%", - "%livingentities%'[s] swim[ming] sound[s]", + {"[the] death sound[s] of %livingentities%", SoundType.DEATH}, + {"%livingentities%'[s] death sound[s]", SoundType.DEATH}, - "[the] [fast:(fast|speedy)] splash sound[s] of %livingentities%", - "%livingentities%'[s] [fast:(fast|speedy)] splash sound[s]", + {"[the] [high:(tall|high)|(low|normal)] fall damage sound[s] [from [[a] height [of]] %-number%] of %livingentities%", SoundType.FALL}, + {"%livingentities%'[s] [high:(tall|high)|low:(low|normal)] fall [damage] sound[s] [from [[a] height [of]] %-number%]", SoundType.FALL}, - "[the] eat[ing] sound[s] of %livingentities% [(with|using|[while] eating [a]) %-itemtype%]", - "%livingentities%'[s] eat[ing] sound[s]", + {"[the] swim[ming] sound[s] of %livingentities%", SoundType.SWIM}, + {"%livingentities%'[s] swim[ming] sound[s]", SoundType.SWIM}, - "[the] drink[ing] sound[s] of %livingentities% [(with|using|[while] drinking [a]) %-itemtype%]", - "%livingentities%'[s] drink[ing] sound[s]", + {"[the] [fast:(fast|speedy)] splash sound[s] of %livingentities%", SoundType.SPLASH}, + {"%livingentities%'[s] [fast:(fast|speedy)] splash sound[s]", SoundType.SPLASH}, - "[the] ambient sound[s] of %livingentities%", - "%livingentities%'[s] ambient sound[s]"); - } + {"[the] eat[ing] sound[s] of %livingentities% [(with|using|[while] eating [a]) %-itemtype%]", SoundType.EAT}, + {"%livingentities%'[s] eat[ing] sound[s]", SoundType.EAT}, + + {"[the] drink[ing] sound[s] of %livingentities% [(with|using|[while] drinking [a]) %-itemtype%]", SoundType.DRINK}, + {"%livingentities%'[s] drink[ing] sound[s]", SoundType.DRINK}, + + {"[the] ambient sound[s] of %livingentities%", SoundType.AMBIENT}, + {"%livingentities%'[s] ambient sound[s]", SoundType.AMBIENT} + }); + + static { + if (Skript.methodExists(LivingEntity.class, "getDeathSound")) + Skript.registerExpression(ExprEntitySound.class, String.class, ExpressionType.COMBINED, patterns.getPatterns()); } - private static final int DAMAGE = 0; - private static final int DEATH = 2; - private static final int FALL = 4; - private static final int SWIM = 6; - private static final int SPLASH = 8; - private static final int EAT_WITH_ITEM = 10; - private static final int EAT = 11; - private static final int DRINK_WITH_ITEM = 12; - private static final int DRINK = 13; - private static final int AMBIENT = 14; - - private int soundPattern; - private boolean big; + private boolean bigOrSpeedy; + @SuppressWarnings("NotNullFieldNotInitialized") + private SoundType soundType; @SuppressWarnings("NotNullFieldNotInitialized") private Expression height; @SuppressWarnings("NotNullFieldNotInitialized") @@ -84,51 +133,33 @@ public class ExprEntitySound extends SimpleExpression { @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { - soundPattern = matchedPattern; - big = parseResult.hasTag("high") || parseResult.hasTag("fast"); - if (matchedPattern == FALL || matchedPattern == FALL + 1) + soundType = patterns.getInfo(matchedPattern); + bigOrSpeedy = parseResult.hasTag("high") || parseResult.hasTag("fast"); + if (soundType == SoundType.FALL) height = (Expression) exprs[0]; - if (matchedPattern == EAT_WITH_ITEM || matchedPattern == DRINK_WITH_ITEM) + if (soundType == SoundType.EAT || soundType == SoundType.DRINK) item = (Expression) exprs[1]; - entities = (Expression) ((matchedPattern == FALL) ? exprs[1] : exprs[0]); + entities = (Expression) ((soundType == SoundType.FALL) ? exprs[1] : exprs[0]); return true; } @Override - @SuppressWarnings("ConstantValue") protected String @Nullable [] get(Event event) { + //noinspection ConstantValue int height = this.height == null ? -1 : this.height.getOptionalSingle(event).orElse(-1).intValue(); - ItemStack defaultItem = new ItemStack(soundPattern == EAT_WITH_ITEM ? Material.COOKED_BEEF : Material.POTION); + ItemStack defaultItem = new ItemStack(soundType == SoundType.EAT ? Material.COOKED_BEEF : Material.POTION); + //noinspection ConstantValue ItemStack item = this.item == null ? defaultItem : this.item.getOptionalSingle(event).map(ItemType::getRandom).orElse(defaultItem); return entities.stream(event) - .map(entity -> getEntitySound(entity, height, item)) + .map(entity -> soundType.getSound(entity, height, item, bigOrSpeedy)) .filter(Objects::nonNull) .distinct() .map(Sound::name) .toArray(String[]::new); } - private @Nullable Sound getEntitySound(LivingEntity entity, int height, ItemStack item) { - return switch (this.soundPattern) { - case DAMAGE, DAMAGE + 1 -> entity.getHurtSound(); - case DEATH, DEATH + 1 -> entity.getDeathSound(); - case FALL, FALL + 1 -> { - if (height != -1) - yield entity.getFallDamageSound(height); - else - yield big ? entity.getFallDamageSoundBig() : entity.getFallDamageSoundSmall(); - } - case SWIM, SWIM + 1 -> entity.getSwimSound(); - case SPLASH, SPLASH + 1 -> big ? entity.getSwimHighSpeedSplashSound() : entity.getSwimSplashSound(); - case EAT, EAT_WITH_ITEM -> entity.getEatingSound(item); - case DRINK, DRINK_WITH_ITEM -> entity.getDrinkingSound(item); - case AMBIENT -> entity instanceof Mob mob ? mob.getAmbientSound() : null; - default -> null; - }; - } - @Override public boolean isSingle() { return entities.isSingle(); @@ -140,26 +171,30 @@ public Class getReturnType() { } @Override - @SuppressWarnings("ConstantValue") public String toString(@Nullable Event event, boolean debug) { - return switch (soundPattern) { - case DAMAGE, DAMAGE + 1 -> "damage"; - case DEATH, DEATH + 1 -> "death"; - case FALL, FALL + 1 -> { + String soundDescription = "unknown"; + switch (soundType) { + case DAMAGE, DEATH, SWIM, AMBIENT -> soundDescription = soundType.name().toLowerCase(); + case FALL -> { + //noinspection ConstantValue if (this.height == null) { - yield big ? "high fall damage" : "normal fall damage"; + soundDescription = bigOrSpeedy ? "high fall damage" : "normal fall damage"; } else { - yield "fall damage from a height of " + this.height.toString(event, debug); + soundDescription = "fall damage from a height of " + this.height.toString(event, debug); } } - case SWIM, SWIM + 1 -> "swim"; - case SPLASH, SPLASH + 1 -> big ? "speedy splash" : "splash"; - case EAT_WITH_ITEM, DRINK_WITH_ITEM -> (soundPattern == EAT_WITH_ITEM ? "eating" : "drinking") + - (this.item == null ? " with default item" : " " + this.item.toString(event, debug)); - case EAT, DRINK -> soundPattern == EAT ? "eating" : "drinking"; - case AMBIENT -> "ambient"; - default -> "unknown"; - } + " sound of " + entities.toString(event, debug); + case SPLASH -> soundDescription = bigOrSpeedy ? "speedy splash" : "splash"; + case EAT, DRINK -> { + String action = soundType == SoundType.EAT ? "eating" : "drinking"; + //noinspection ConstantValue + if (this.item == null) { + soundDescription = action; + } else { + soundDescription = action + " " + this.item.toString(event, debug); + } + } + } + return soundDescription + " sound of " + entities.toString(event, debug); } } diff --git a/src/main/java/ch/njol/skript/util/Patterns.java b/src/main/java/ch/njol/skript/util/Patterns.java index e7b19194e9f..2239a921723 100644 --- a/src/main/java/ch/njol/skript/util/Patterns.java +++ b/src/main/java/ch/njol/skript/util/Patterns.java @@ -1,21 +1,3 @@ -/** - * This file is part of Skript. - * - * Skript is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Skript is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Skript. If not, see . - * - * Copyright Peter Güttinger, SkriptLang team and contributors - */ package ch.njol.skript.util; import ch.njol.skript.lang.Expression; @@ -24,7 +6,7 @@ import ch.njol.util.Kleenean; /** - * A helper class useful when a expression/condition/effect/etc. needs to associate additional data with each pattern. + * A helper class useful when an expression/condition/effect/etc. needs to associate additional data with each pattern. * * @author Peter Güttinger */ From 02e480e7761c161deecfc48fb4ca10eebf50f39e Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Tue, 24 Sep 2024 12:55:31 +1000 Subject: [PATCH 6/6] Just some small updates --- .../skript/expressions/ExprEntitySound.java | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java b/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java index 903628b4476..4dc05895640 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java +++ b/src/main/java/ch/njol/skript/expressions/ExprEntitySound.java @@ -121,13 +121,9 @@ public Sound getSound(LivingEntity entity, int height, ItemStack item, boolean b } private boolean bigOrSpeedy; - @SuppressWarnings("NotNullFieldNotInitialized") private SoundType soundType; - @SuppressWarnings("NotNullFieldNotInitialized") private Expression height; - @SuppressWarnings("NotNullFieldNotInitialized") private Expression entities; - @SuppressWarnings("NotNullFieldNotInitialized") private Expression item; @Override @@ -145,12 +141,10 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override protected String @Nullable [] get(Event event) { - //noinspection ConstantValue - int height = this.height == null ? -1 : this.height.getOptionalSingle(event).orElse(-1).intValue(); + int height = this.height == null ? -1 : this.height.getOptionalSingle(event).orElse(-1).intValue(); ItemStack defaultItem = new ItemStack(soundType == SoundType.EAT ? Material.COOKED_BEEF : Material.POTION); - //noinspection ConstantValue - ItemStack item = this.item == null ? defaultItem : this.item.getOptionalSingle(event).map(ItemType::getRandom).orElse(defaultItem); + ItemStack item = this.item == null ? defaultItem : this.item.getOptionalSingle(event).map(ItemType::getRandom).orElse(defaultItem); return entities.stream(event) .map(entity -> soundType.getSound(entity, height, item, bigOrSpeedy)) @@ -172,29 +166,27 @@ public Class getReturnType() { @Override public String toString(@Nullable Event event, boolean debug) { - String soundDescription = "unknown"; + String sound = "unknown"; switch (soundType) { - case DAMAGE, DEATH, SWIM, AMBIENT -> soundDescription = soundType.name().toLowerCase(); + case DAMAGE, DEATH, SWIM, AMBIENT -> sound = soundType.name().toLowerCase(); case FALL -> { - //noinspection ConstantValue - if (this.height == null) { - soundDescription = bigOrSpeedy ? "high fall damage" : "normal fall damage"; + if (this.height == null) { + sound = bigOrSpeedy ? "high fall damage" : "normal fall damage"; } else { - soundDescription = "fall damage from a height of " + this.height.toString(event, debug); + sound = "fall damage from a height of " + this.height.toString(event, debug); } } - case SPLASH -> soundDescription = bigOrSpeedy ? "speedy splash" : "splash"; + case SPLASH -> sound = bigOrSpeedy ? "speedy splash" : "splash"; case EAT, DRINK -> { String action = soundType == SoundType.EAT ? "eating" : "drinking"; - //noinspection ConstantValue - if (this.item == null) { - soundDescription = action; + if (this.item == null) { + sound = action; } else { - soundDescription = action + " " + this.item.toString(event, debug); + sound = action + " " + this.item.toString(event, debug); } } } - return soundDescription + " sound of " + entities.toString(event, debug); + return sound + " sound of " + entities.toString(event, debug); } }