From e3ed61ff6845ec3fb8cf533fd1e82ab8efafb39f Mon Sep 17 00:00:00 2001 From: "Josiah (Gaming32) Glosson" Date: Mon, 22 May 2023 21:09:56 -0500 Subject: [PATCH] Toast sound effects --- .../github/gaming32/worldhost/WorldHost.java | 3 +- .../protocol/WorldHostS2CMessage.java | 4 +- .../worldhost/toast/ToastBuilder.java | 14 +++++- .../worldhost/toast/ToastInstance.java | 7 ++- .../gaming32/worldhost/toast/WHToast.java | 45 +++++++++++++++++-- .../resources/assets/world-host/sounds.json | 26 +++++++++++ 6 files changed, 88 insertions(+), 11 deletions(-) create mode 100644 src/main/resources/assets/world-host/sounds.json diff --git a/src/main/java/io/github/gaming32/worldhost/WorldHost.java b/src/main/java/io/github/gaming32/worldhost/WorldHost.java index 4c5e6f7..7aa2605 100644 --- a/src/main/java/io/github/gaming32/worldhost/WorldHost.java +++ b/src/main/java/io/github/gaming32/worldhost/WorldHost.java @@ -478,7 +478,7 @@ public static boolean isFriend(UUID user) { return CONFIG.isEnableFriends() && CONFIG.getFriends().contains(user); } - public static void showProfileToast(UUID user, String title, String description, int ticks, Runnable clickAction) { + public static void showFriendOrOnlineToast(UUID user, String title, String description, int ticks, Runnable clickAction) { Util.backgroundExecutor().execute(() -> { final GameProfile profile = Minecraft.getInstance() .getMinecraftSessionService() @@ -495,6 +495,7 @@ public static void showProfileToast(UUID user, String title, String description, }) .clickAction(clickAction) .ticks(ticks) + .important() .show(); }); }); diff --git a/src/main/java/io/github/gaming32/worldhost/protocol/WorldHostS2CMessage.java b/src/main/java/io/github/gaming32/worldhost/protocol/WorldHostS2CMessage.java index 4fd6402..89b1564 100644 --- a/src/main/java/io/github/gaming32/worldhost/protocol/WorldHostS2CMessage.java +++ b/src/main/java/io/github/gaming32/worldhost/protocol/WorldHostS2CMessage.java @@ -82,7 +82,7 @@ record FriendRequest(UUID fromUser) implements WorldHostS2CMessage { public void handle(ProtocolClient client) { if (!WorldHost.CONFIG.isEnableFriends()) return; final boolean isFriend = WorldHost.isFriend(fromUser); - WorldHost.showProfileToast( + WorldHost.showFriendOrOnlineToast( fromUser, isFriend ? "world-host.friend_added_you.already" : "world-host.friend_added_you", isFriend ? "world-host.friend_added_you.already.desc" : "world-host.need_add_back", @@ -107,7 +107,7 @@ public void handle(ProtocolClient client) { Minecraft.getInstance().execute(() -> { WorldHost.ONLINE_FRIENDS.put(user, connectionId); WorldHost.ONLINE_FRIEND_UPDATES.forEach(FriendsListUpdate::friendsListUpdate); - WorldHost.showProfileToast( + WorldHost.showFriendOrOnlineToast( user, "world-host.went_online", "world-host.went_online.desc", 200, () -> WorldHost.join(connectionId, null) ); diff --git a/src/main/java/io/github/gaming32/worldhost/toast/ToastBuilder.java b/src/main/java/io/github/gaming32/worldhost/toast/ToastBuilder.java index 0b6eaf2..b7a3463 100644 --- a/src/main/java/io/github/gaming32/worldhost/toast/ToastBuilder.java +++ b/src/main/java/io/github/gaming32/worldhost/toast/ToastBuilder.java @@ -14,6 +14,7 @@ public class ToastBuilder { private IconRenderer iconRenderer = null; @Nullable private Runnable clickAction = null; + private boolean important = false; private int ticks = 100; ToastBuilder(@NotNull Component title) { @@ -35,12 +36,23 @@ public ToastBuilder clickAction(Runnable clickAction) { return this; } + public ToastBuilder important() { + return important(true); + } + + public ToastBuilder important(boolean important) { + this.important = important; + return this; + } + public ToastBuilder ticks(int ticks) { this.ticks = ticks; return this; } public void show() { - Minecraft.getInstance().execute(() -> WHToast.TOASTS.add(new ToastInstance(title, description, iconRenderer, clickAction, ticks))); + Minecraft.getInstance().execute(() -> WHToast.add( + new ToastInstance(title, description, iconRenderer, clickAction, important, ticks) + )); } } diff --git a/src/main/java/io/github/gaming32/worldhost/toast/ToastInstance.java b/src/main/java/io/github/gaming32/worldhost/toast/ToastInstance.java index bcd60c2..33acebe 100644 --- a/src/main/java/io/github/gaming32/worldhost/toast/ToastInstance.java +++ b/src/main/java/io/github/gaming32/worldhost/toast/ToastInstance.java @@ -46,6 +46,7 @@ class ToastInstance { public final IconRenderer iconRenderer; @Nullable public final Runnable clickAction; + public final boolean important; public final int width; public int height; @@ -67,21 +68,19 @@ public ToastInstance( @Nullable Component description, @Nullable IconRenderer iconRenderer, @Nullable Runnable clickAction, + boolean important, int ticks ) { this.title = title; this.description = description; this.iconRenderer = iconRenderer; this.clickAction = clickAction; + this.important = important; width = TEXT_WIDTH + 2 * BORDER_SIZE + (iconRenderer != null ? ICON_SIZE + BORDER_SIZE : 0); - if (WHToast.ready) { - calculateText(); - } - ticksRemaining = ticksTotal = ticks; } diff --git a/src/main/java/io/github/gaming32/worldhost/toast/WHToast.java b/src/main/java/io/github/gaming32/worldhost/toast/WHToast.java index c4d6889..68ddc47 100644 --- a/src/main/java/io/github/gaming32/worldhost/toast/WHToast.java +++ b/src/main/java/io/github/gaming32/worldhost/toast/WHToast.java @@ -4,7 +4,10 @@ import com.mojang.blaze3d.vertex.PoseStack; import io.github.gaming32.worldhost.versions.Components; import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.sounds.SimpleSoundInstance; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundEvent; import org.jetbrains.annotations.NotNull; import java.util.ArrayDeque; @@ -15,8 +18,12 @@ public class WHToast { private static final int X_OFFSET = 4; private static final int Y_OFFSET = 4; - static boolean ready = false; - static final Deque TOASTS = new ArrayDeque<>(); + private static final SoundEvent IMPORTANT = newSoundEvent("important"); + private static final SoundEvent REGULAR = newSoundEvent("regular"); + private static final SoundEvent REMOVED = newSoundEvent("removed"); + + private static boolean ready = false; + private static final Deque TOASTS = new ArrayDeque<>(); public static ToastBuilder builder(@NotNull Component title) { return new ToastBuilder(title); @@ -28,9 +35,24 @@ public static ToastBuilder builder(@NotNull String titleKey) { public static void ready() { TOASTS.forEach(ToastInstance::calculateText); + if (!TOASTS.isEmpty()) { + if (TOASTS.stream().anyMatch(t -> t.important)) { + playSound(IMPORTANT); + } else { + playSound(REGULAR); + } + } ready = true; } + static void add(ToastInstance toast) { + if (ready) { + toast.calculateText(); + playSound(toast.important ? IMPORTANT : REGULAR); + } + TOASTS.add(toast); + } + public static void tick() { if (!ready) return; @@ -40,7 +62,10 @@ public static void tick() { final ToastInstance toast = it.next(); toast.yShift += shift; shift = 0; - if (--toast.ticksRemaining <= 0) { + toast.ticksRemaining--; + if (toast.ticksRemaining == 19) { + playSound(REMOVED); + } else if (toast.ticksRemaining <= 0) { it.remove(); shift = toast.height + GAP + toast.yShift; } @@ -97,4 +122,18 @@ public static boolean click(double mouseX, double mouseY, int button) { return false; } + + private static SoundEvent newSoundEvent(String location) { + //#if MC >= 11904 + return SoundEvent.createVariableRangeEvent( + //#else + //$$ return new SoundEvent( + //#endif + new ResourceLocation("world-host:toast/" + location) + ); + } + + private static void playSound(SoundEvent event) { + Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(event, 1f, 1f)); + } } diff --git a/src/main/resources/assets/world-host/sounds.json b/src/main/resources/assets/world-host/sounds.json new file mode 100644 index 0000000..9d8ad8b --- /dev/null +++ b/src/main/resources/assets/world-host/sounds.json @@ -0,0 +1,26 @@ +{ + "toast/important": { + "sounds": [ + { + "name": "minecraft:note/icechime", + "volume": 0.5 + } + ] + }, + "toast/regular": { + "sounds": [ + { + "name": "minecraft:ui.toast.in", + "type": "event" + } + ] + }, + "toast/removed": { + "sounds": [ + { + "name": "minecraft:ui.toast.out", + "type": "event" + } + ] + } +} \ No newline at end of file