Option to change crossbow sound

This commit is contained in:
Jules 2023-06-24 20:03:06 +02:00
parent 6026602f16
commit 2bea05b08c
12 changed files with 168 additions and 156 deletions

View File

@ -7,39 +7,40 @@ import net.Indyuce.mmoitems.util.MMOUtils;
import io.lumine.mythic.lib.version.VersionMaterial;
public enum CustomSound {
ON_ATTACK(Material.IRON_SWORD, 19, "Plays when attacking an entity."),
ON_RIGHT_CLICK(Material.STONE_HOE, 22, "Plays when item is right-clicked."),
ON_BLOCK_BREAK(Material.COBBLESTONE, 25, "Plays when a block is broken with the item."),
ON_PICKUP(Material.IRON_INGOT, 28, "Plays when you pickup the item from the ground."),
ON_LEFT_CLICK(Material.STONE_AXE, 31, "Plays when item is left-clicked."),
ON_CRAFT(VersionMaterial.CRAFTING_TABLE.toMaterial(), 34, "Plays when item is crafted in a crafting inventory", "or when smelted from someting in a furnace."),
ON_CONSUME(Material.APPLE, 37, "Plays when item has been consumed.", "(After eating/drinking animation)"),
ON_ITEM_BREAK(Material.FLINT, 40, "Plays when the item breaks."),
ON_PLACED(Material.STONE, 43, "Plays when the block is placed.");
private final ItemStack item;
private final String[] lore;
private final int slot;
ON_ATTACK(Material.IRON_SWORD, 19, "Plays when attacking an entity."),
ON_RIGHT_CLICK(Material.STONE_HOE, 22, "Plays when item is right-clicked."),
ON_BLOCK_BREAK(Material.COBBLESTONE, 25, "Plays when a block is broken with the item."),
ON_PICKUP(Material.IRON_INGOT, 28, "Plays when you pickup the item from the ground."),
ON_LEFT_CLICK(Material.STONE_AXE, 31, "Plays when item is left-clicked."),
ON_CRAFT(VersionMaterial.CRAFTING_TABLE.toMaterial(), 34, "Plays when item is crafted in a crafting inventory", "or when smelted from someting in a furnace."),
ON_CONSUME(Material.APPLE, 37, "Plays when item has been consumed.", "(After eating/drinking animation)"),
ON_ITEM_BREAK(Material.FLINT, 40, "Plays when the item breaks."),
ON_CROSSBOW(Material.ARROW, 38, "Plays when a crossbow shoots an arrow."),
ON_PLACED(Material.STONE, 43, "Plays when the block is placed.");
private CustomSound(Material material, int slot, String... lore) {
this.item = new ItemStack(material);
this.lore = lore;
this.slot = slot;
}
private final ItemStack item;
private final String[] lore;
private final int slot;
public ItemStack getItem() {
return item;
}
CustomSound(Material material, int slot, String... lore) {
this.item = new ItemStack(material);
this.lore = lore;
this.slot = slot;
}
public String getName() {
return MMOUtils.caseOnWords(name().toLowerCase().replace('_', ' '));
}
public String[] getLore() {
return lore;
}
public int getSlot() {
return slot;
}
public ItemStack getItem() {
return item;
}
public String getName() {
return MMOUtils.caseOnWords(name().toLowerCase().replace('_', ' '));
}
public String[] getLore() {
return lore;
}
public int getSlot() {
return slot;
}
}

View File

@ -6,6 +6,8 @@ import io.lumine.mythic.lib.player.PlayerMetadata;
import io.lumine.mythic.lib.skill.trigger.TriggerType;
import io.lumine.mythic.lib.util.CustomProjectile;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.CustomSound;
import net.Indyuce.mmoitems.listener.CustomSoundListener;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.Sound;
@ -36,7 +38,9 @@ public class Crossbow extends UntargetedWeapon {
final Arrow arrow = getPlayer().launchProjectile(Arrow.class);
arrow.setVelocity(getPlayer().getEyeLocation().getDirection().multiply(3 * requireNonZero(stats.getStat("ARROW_VELOCITY"), 1)));
getPlayer().setVelocity(getPlayer().getVelocity().setX(0).setZ(0));
getPlayer().getWorld().playSound(getPlayer().getLocation(), Sound.ENTITY_ARROW_HIT, 1, .5f);
// Play custom sound
CustomSoundListener.playSound(getNBTItem().getItem(), CustomSound.ON_CROSSBOW, player, Sound.ENTITY_ARROW_SHOOT);
// Register custom projectile
MMOItems.plugin.getEntities().registerCustomProjectile(getNBTItem(), stats, arrow, 1);

View File

@ -7,7 +7,6 @@ import io.lumine.mythic.lib.comp.interaction.InteractionType;
import io.lumine.mythic.lib.damage.DamageType;
import io.lumine.mythic.lib.player.PlayerMetadata;
import io.lumine.mythic.lib.version.VersionSound;
import net.Indyuce.mmoitems.ItemStats;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.util.SoundReader;
import net.Indyuce.mmoitems.stat.LuteAttackEffectStat.LuteAttackEffect;
@ -41,6 +40,7 @@ public class Lute extends UntargetedWeapon {
final Vector weight = new Vector(0, -.003 * stats.getStat("NOTE_WEIGHT"), 0);
final @Nullable LuteAttackEffect effect = LuteAttackEffect.get(getNBTItem());
@Deprecated
final SoundReader sound = new SoundReader(getNBTItem().getString("MMOITEMS_LUTE_ATTACK_SOUND"), VersionSound.BLOCK_NOTE_BLOCK_BELL.toSound());
final @NotNull ProjectileParticlesData projParticle = getNBTItem().hasTag("MMOITEMS_PROJECTILE_PARTICLES") ?
new ProjectileParticlesData(getNBTItem().getString("MMOITEMS_PROJECTILE_PARTICLES")) : ProjectileParticlesData.DEFAULT;

View File

@ -16,7 +16,6 @@ import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.List;
public class CircularLuteAttack implements LuteAttackHandler {

View File

@ -7,7 +7,6 @@ import net.Indyuce.mmoitems.stat.data.ProjectileParticlesData;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.Random;
public interface LuteAttackHandler {

View File

@ -3,59 +3,61 @@ package net.Indyuce.mmoitems.api.util;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class SoundReader {
private final Sound sound;
private final String soundKey;
@Nullable
private final Sound sound;
@Nullable
private final String soundKey;
public SoundReader(String tag, Sound defaultSound) {
if(tag.isEmpty()) {
this.sound = defaultSound;
this.soundKey = "";
return;
}
public SoundReader(@NotNull String tag, @NotNull Sound defaultSound) {
if (tag.isEmpty()) {
this.sound = defaultSound;
this.soundKey = "";
return;
}
Sound sound;
String soundKey;
try {
sound = Sound.valueOf(tag);
soundKey = "";
} catch (Exception e) {
sound = null;
soundKey = tag;
}
Sound sound;
String soundKey;
try {
sound = Sound.valueOf(tag);
soundKey = null;
} catch (Exception exception) {
sound = null;
soundKey = tag.toLowerCase();
}
this.sound = sound;
this.soundKey = soundKey.toLowerCase();
}
this.sound = sound;
this.soundKey = soundKey;
}
public Sound getSound() {
return sound;
}
@Nullable
public Sound getSound() {
return sound;
}
public String getSoundKey() {
return soundKey;
}
@NotNull
public String getSoundKey() {
return soundKey;
}
public void play(Player player) {
play(player, 1, 1);
}
public void play(@NotNull Player player) {
play(player, 1, 1);
}
public void play(Player player, float vol, float pitch) {
if(soundKey.isEmpty())
player.playSound(player.getLocation(), sound, vol, pitch);
else
player.playSound(player.getLocation(), soundKey, vol, pitch);
}
public void play(@NotNull Player player, float vol, float pitch) {
if (sound != null) player.playSound(player.getLocation(), sound, vol, pitch);
else player.playSound(player.getLocation(), soundKey, vol, pitch);
}
public void play(Location loc) {
play(loc, 1, 1);
}
public void play(@NotNull Location loc) {
play(loc, 1, 1);
}
public void play(Location loc, float vol, float pitch) {
if(soundKey.isEmpty())
loc.getWorld().playSound(loc, sound, vol, pitch);
else
loc.getWorld().playSound(loc, soundKey, vol, pitch);
}
public void play(@NotNull Location loc, float vol, float pitch) {
if (sound != null) loc.getWorld().playSound(loc, sound, vol, pitch);
else loc.getWorld().playSound(loc, soundKey, vol, pitch);
}
}

View File

@ -4,6 +4,7 @@ import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.api.item.NBTItem;
import io.lumine.mythic.lib.api.util.SmartGive;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.CustomSound;
import net.Indyuce.mmoitems.api.crafting.CraftingStation;
import net.Indyuce.mmoitems.api.crafting.CraftingStatus.CraftingQueue;
import net.Indyuce.mmoitems.api.crafting.CraftingStatus.CraftingQueue.CraftingInfo;
@ -194,7 +195,7 @@ public class CraftingStationView extends PluginInventory {
recipe.whenClaimed().forEach(trigger -> trigger.whenCrafting(playerData));
// Play sounds
CustomSoundListener.stationCrafting(result, player);
CustomSoundListener.playSound(result, CustomSound.ON_CRAFT, player);
if (!recipe.hasOption(Recipe.RecipeOption.SILENT_CRAFT))
player.playSound(player.getLocation(), station.getSound(), 1, 1);

View File

@ -23,11 +23,11 @@ import java.util.List;
import java.util.Map;
public class SoundsEdition extends EditionInventory {
public static final Map<Integer, String> correspondingSlot = new HashMap<>();
public static final Map<Integer, String> CORRESPONDING_SLOT = new HashMap<>();
static {
for (CustomSound sound : CustomSound.values())
correspondingSlot.put(sound.getSlot(), sound.getName().replace(" ", "-").toLowerCase());
CORRESPONDING_SLOT.put(sound.getSlot(), sound.name().replace("_", "-").toLowerCase());
}
public SoundsEdition(Player player, MMOItemTemplate template) {
@ -37,7 +37,6 @@ public class SoundsEdition extends EditionInventory {
@Override
public Inventory getInventory() {
Inventory inv = Bukkit.createInventory(this, 54, "Custom Sounds: " + template.getId());
int[] slots = { 19, 22, 25, 28, 31, 34, 37, 40, 43 };
int n = 0;
for (CustomSound sound : CustomSound.values()) {
@ -66,7 +65,7 @@ public class SoundsEdition extends EditionInventory {
soundEventMeta.setLore(eventLore);
soundEvent.setItemMeta(soundEventMeta);
inv.setItem(slots[n], soundEvent);
inv.setItem(sound.getSlot(), soundEvent);
n += 1;
}
@ -83,14 +82,14 @@ public class SoundsEdition extends EditionInventory {
if (event.getInventory() != event.getClickedInventory() || !MMOUtils.isMetaItem(item, false))
return;
if (correspondingSlot.containsKey(event.getSlot())) {
if (CORRESPONDING_SLOT.containsKey(event.getSlot())) {
if (event.getAction() == InventoryAction.PICKUP_ALL)
new StatEdition(this, ItemStats.CUSTOM_SOUNDS, correspondingSlot.get(event.getSlot())).enable("Write in the chat the custom sound you want to add.",
new StatEdition(this, ItemStats.CUSTOM_SOUNDS, CORRESPONDING_SLOT.get(event.getSlot())).enable("Write in the chat the custom sound you want to add.",
ChatColor.AQUA + "Format: [SOUND NAME] [VOLUME] [PITCH]",
ChatColor.AQUA + "Example: entity.generic.drink 1 1");
if (event.getAction() == InventoryAction.PICKUP_HALF) {
String soundPath = correspondingSlot.get(event.getSlot());
String soundPath = CORRESPONDING_SLOT.get(event.getSlot());
getEditedSection().set("sounds." + soundPath, null);
// clear sound config section

View File

@ -1,5 +1,6 @@
package net.Indyuce.mmoitems.listener;
import net.Indyuce.mmoitems.api.CustomSound;
import net.Indyuce.mmoitems.api.util.SoundReader;
import io.lumine.mythic.lib.api.item.NBTItem;
import org.bukkit.Location;
@ -21,85 +22,88 @@ import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemBreakEvent;
import org.bukkit.event.player.PlayerItemConsumeEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class CustomSoundListener implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void a(EntityDamageByEntityEvent event) {
if (!(event.getDamager() instanceof Player) || !(event.getEntity() instanceof LivingEntity))
return;
@EventHandler(priority = EventPriority.HIGH)
public void a(EntityDamageByEntityEvent event) {
if (!(event.getDamager() instanceof Player) || !(event.getEntity() instanceof LivingEntity)) return;
Player player = (Player) event.getDamager();
playSound(player.getInventory().getItemInMainHand(), "ON_ATTACK", player);
}
Player player = (Player) event.getDamager();
playSound(player.getInventory().getItemInMainHand(), CustomSound.ON_ATTACK, player);
}
@EventHandler(priority = EventPriority.HIGH)
public void b(EntityPickupItemEvent event) {
if (event.getEntityType().equals(EntityType.PLAYER))
playSound(event.getItem().getItemStack(), "ON_PICKUP", (Player) event.getEntity());
}
@EventHandler(priority = EventPriority.HIGH)
public void b(EntityPickupItemEvent event) {
if (event.getEntityType().equals(EntityType.PLAYER))
playSound(event.getItem().getItemStack(), CustomSound.ON_PICKUP, (Player) event.getEntity());
}
@EventHandler(priority = EventPriority.HIGH)
public void c(BlockBreakEvent event) {
playSound(event.getPlayer().getInventory().getItemInMainHand(), "ON_BLOCK_BREAK", event.getPlayer());
}
@EventHandler(priority = EventPriority.HIGH)
public void c(BlockBreakEvent event) {
playSound(event.getPlayer().getInventory().getItemInMainHand(), CustomSound.ON_BLOCK_BREAK, event.getPlayer());
}
@EventHandler
public void d(PlayerInteractEvent event) {
if (event.getAction() == Action.PHYSICAL || !event.hasItem())
return;
@EventHandler
public void d(PlayerInteractEvent event) {
if (event.getAction() == Action.PHYSICAL || !event.hasItem()) return;
if (event.getAction().name().contains("RIGHT_CLICK"))
playSound(event.getItem(), "ON_RIGHT_CLICK", event.getPlayer());
if (event.getAction().name().contains("RIGHT_CLICK"))
playSound(event.getItem(), CustomSound.ON_RIGHT_CLICK, event.getPlayer());
if (event.getAction().name().contains("LEFT_CLICK"))
playSound(event.getItem(), "ON_LEFT_CLICK", event.getPlayer());
}
if (event.getAction().name().contains("LEFT_CLICK"))
playSound(event.getItem(), CustomSound.ON_LEFT_CLICK, event.getPlayer());
}
@EventHandler(priority = EventPriority.HIGH)
public void e(CraftItemEvent event) {
playSound(event.getInventory().getResult(), "ON_CRAFT", event.getWhoClicked().getLocation());
}
@EventHandler(priority = EventPriority.HIGH)
public void e(CraftItemEvent event) {
playSound(event.getInventory().getResult(), CustomSound.ON_CRAFT, event.getWhoClicked().getLocation());
}
@EventHandler(priority = EventPriority.HIGH)
public void f(FurnaceSmeltEvent event) {
playSound(event.getResult(), "ON_CRAFT", event.getBlock().getLocation());
}
@EventHandler(priority = EventPriority.HIGH)
public void f(FurnaceSmeltEvent event) {
playSound(event.getResult(), CustomSound.ON_CRAFT, event.getBlock().getLocation());
}
@EventHandler(priority = EventPriority.HIGH)
public void g(PlayerItemConsumeEvent event) {
playSound(event.getItem(), "ON_CONSUME", event.getPlayer());
}
@EventHandler(priority = EventPriority.HIGH)
public void g(PlayerItemConsumeEvent event) {
playSound(event.getItem(), CustomSound.ON_CONSUME, event.getPlayer());
}
@EventHandler(priority = EventPriority.HIGH)
public void h1(PlayerItemBreakEvent event) {
playSound(event.getBrokenItem(), "ON_ITEM_BREAK", event.getPlayer());
}
@EventHandler(priority = EventPriority.HIGH)
public void h1(PlayerItemBreakEvent event) {
playSound(event.getBrokenItem(), CustomSound.ON_ITEM_BREAK, event.getPlayer());
}
@EventHandler(priority = EventPriority.MONITOR)
public void i(BlockPlaceEvent event) {
playSound(event.getItemInHand(), "ON_PLACED", event.getPlayer());
}
@EventHandler(priority = EventPriority.MONITOR)
public void i(BlockPlaceEvent event) {
playSound(event.getItemInHand(), CustomSound.ON_PLACED, event.getPlayer());
}
public static void stationCrafting(ItemStack item, Player player) {
playSound(item, "ON_CRAFT", player);
}
public static void playSound(@Nullable ItemStack item, @NotNull CustomSound type, @NotNull Player player) {
playSound(item, type, player.getLocation(), null);
}
public static void playConsumableSound(ItemStack item, Player player) {
playSound(item, "ON_CONSUME", player);
}
public static void playSound(@Nullable ItemStack item, @NotNull CustomSound type, @NotNull Player player, @Nullable Sound defaultSound) {
playSound(item, type, player.getLocation(), defaultSound);
}
private static void playSound(ItemStack item, String type, Player player) {
playSound(item, type, player.getLocation());
}
public static void playSound(@Nullable ItemStack item, @NotNull CustomSound type, @NotNull Location loc) {
playSound(item, type, loc, null);
}
private static void playSound(ItemStack item, String type, Location loc) {
if (item == null)
return;
public static void playSound(@Nullable ItemStack item, @NotNull CustomSound type, @NotNull Location loc, @Nullable Sound defaultSound) {
if (item == null) return;
NBTItem nbt = NBTItem.get(item);
if (nbt.hasTag("MMOITEMS_SOUND_" + type)) {
SoundReader sound = new SoundReader(nbt.getString("MMOITEMS_SOUND_" + type), Sound.ENTITY_PIG_AMBIENT);
sound.play(loc, (float) nbt.getDouble("MMOITEMS_SOUND_" + type + "_VOL"), (float) nbt.getDouble("MMOITEMS_SOUND_" + type + "_PIT"));
}
}
final NBTItem nbt = NBTItem.get(item);
final String soundName = nbt.getString("MMOITEMS_SOUND_" + type.name());
if (soundName == null || soundName.isEmpty()) {
if (defaultSound != null) loc.getWorld().playSound(loc, defaultSound, 1, 1);
return;
}
final SoundReader sound = new SoundReader(soundName, defaultSound);
sound.play(loc, (float) nbt.getDouble("MMOITEMS_SOUND_" + type.name() + "_VOL"), (float) nbt.getDouble("MMOITEMS_SOUND_" + type.name() + "_PIT"));
}
}

View File

@ -2,6 +2,7 @@ package net.Indyuce.mmoitems.stat;
import io.lumine.mythic.lib.api.item.NBTItem;
import net.Indyuce.mmoitems.ItemStats;
import net.Indyuce.mmoitems.api.CustomSound;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.interaction.Consumable;
import net.Indyuce.mmoitems.api.interaction.util.DurabilityItem;
@ -53,7 +54,7 @@ public class RepairPower extends DoubleStat implements ConsumableItemInteraction
Message.REPAIRED_ITEM
.format(ChatColor.YELLOW, "#item#", MMOUtils.getDisplayName(target.getItem()), "#amount#", String.valueOf(repairPower))
.send(player);
CustomSoundListener.playConsumableSound(consumable.getItem(), player);
CustomSoundListener.playSound(consumable.getItem(), CustomSound.ON_CONSUME, player);
}
return true;
}

View File

@ -2,6 +2,7 @@ package net.Indyuce.mmoitems.stat;
import io.lumine.mythic.lib.api.item.NBTItem;
import net.Indyuce.mmoitems.ItemStats;
import net.Indyuce.mmoitems.api.CustomSound;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.interaction.Consumable;
import net.Indyuce.mmoitems.api.interaction.util.DurabilityItem;
@ -58,7 +59,7 @@ public class RepairPowerPercent extends DoubleStat implements ConsumableItemInte
Message.REPAIRED_ITEM
.format(ChatColor.YELLOW, "#item#", MMOUtils.getDisplayName(target.getItem()), "#amount#", String.valueOf(repairAmount))
.send(player);
CustomSoundListener.playConsumableSound(consumable.getItem(), player);
CustomSoundListener.playSound(consumable.getItem(), CustomSound.ON_CONSUME, player);
}
return true;
}

View File

@ -1,6 +1,7 @@
package net.Indyuce.mmoitems.util;
import io.lumine.mythic.lib.api.item.NBTItem;
import net.Indyuce.mmoitems.api.CustomSound;
import net.Indyuce.mmoitems.api.event.item.RepairItemEvent;
import net.Indyuce.mmoitems.api.interaction.Consumable;
import net.Indyuce.mmoitems.api.player.PlayerData;
@ -52,10 +53,10 @@ public class RepairUtils {
meta.setDamage(Math.max(0, meta.getDamage() - repairAmount));
target.getItem().setItemMeta(meta);
Message.REPAIRED_ITEM.format(ChatColor.YELLOW,
"#item#", MMOUtils.getDisplayName(target.getItem()),
"#amount#", String.valueOf(repairAmount))
"#item#", MMOUtils.getDisplayName(target.getItem()),
"#amount#", String.valueOf(repairAmount))
.send(player);
CustomSoundListener.playConsumableSound(consumable.getItem(), player);
CustomSoundListener.playSound(consumable.getItem(), CustomSound.ON_CONSUME, player);
return true;
}
}