From 4e82c974a7217824eab084fe43ce4385b6aae52d Mon Sep 17 00:00:00 2001 From: vicisacat Date: Sat, 20 Apr 2024 16:04:25 +0200 Subject: [PATCH 01/20] start event notifications --- .../de/hysky/skyblocker/SkyblockerMod.java | 1 + .../skyblock/EventNotifications.java | 103 ++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/EventNotifications.java diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index a9aab3b6eb..abf09032b5 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -177,6 +177,7 @@ public void onInitializeClient() { Kuudra.init(); RenderHelper.init(); FancyStatusBars.init(); + EventNotifications.init(); containerSolverManager.init(); statusBarTracker.init(); BeaconHighlighter.init(); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/EventNotifications.java b/src/main/java/de/hysky/skyblocker/skyblock/EventNotifications.java new file mode 100644 index 0000000000..5f3bae9036 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/EventNotifications.java @@ -0,0 +1,103 @@ +package de.hysky.skyblocker.skyblock; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.mojang.logging.LogUtils; +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.events.SkyblockEvents; +import de.hysky.skyblocker.utils.Http; +import de.hysky.skyblocker.utils.scheduler.Scheduler; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.toast.SystemToast; +import net.minecraft.text.Text; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; + +import java.util.*; +import java.util.concurrent.CompletableFuture; + +public class EventNotifications { + private static final Logger LOGGER = LogUtils.getLogger(); + + private static long currentTime = System.currentTimeMillis() / 1000; + + public static void init() { + Scheduler.INSTANCE.scheduleCyclic(EventNotifications::timeUpdate, 20); + + SkyblockEvents.JOIN.register(EventNotifications::refreshEvents); + } + + private static final Map> events = new Object2ObjectOpenHashMap<>(); + + public static void refreshEvents() { + CompletableFuture.supplyAsync(() -> { + try { + JsonArray jsonElements = SkyblockerMod.GSON.fromJson(Http.sendGetRequest("https://hysky.de/api/calendar"), JsonArray.class); + return jsonElements.asList().stream().map(JsonElement::getAsJsonObject).toList(); + } catch (Exception e) { + LOGGER.error("[Skyblocker] Failed to download warps list", e); + } + return List.of(); + }).thenAccept(eventsList -> { + events.clear(); + for (JsonObject object : eventsList) { + if (object.get("timestamp").getAsLong() + object.get("duration").getAsInt() < currentTime) continue; + SkyblockEvent skyblockEvent = SkyblockEvent.of(object); + events.computeIfAbsent(object.get("event").getAsString(), s -> new LinkedList<>()).add(skyblockEvent); + } + + for (Map.Entry> entry : events.entrySet()) { + entry.getValue().sort(Comparator.comparingLong(SkyblockEvent::start)); // Sort just in case it's not in order for some reason in API + LOGGER.info("Next {} is at {}", entry.getKey(), entry.getValue().peekFirst()); + } + }); + } + + + + private static void timeUpdate() { + long newTime = System.currentTimeMillis() / 1000; + LOGGER.info(String.valueOf(newTime)); + for (Map.Entry> entry : events.entrySet()) { + LinkedList nextEvents = entry.getValue(); + SkyblockEvent skyblockEvent = nextEvents.peekFirst(); + if (skyblockEvent == null) continue; + if (newTime > skyblockEvent.start() + skyblockEvent.duration()) { + nextEvents.pollFirst(); + skyblockEvent = nextEvents.peekFirst(); + if (skyblockEvent == null) continue; + } + if (currentTime + 60 < skyblockEvent.start() && newTime + 60 >= skyblockEvent.start()) { + MinecraftClient.getInstance().getToastManager().add(new SystemToast( + SystemToast.Type.PERIODIC_NOTIFICATION, + Text.literal(entry.getKey()), + Text.literal("Starting soon!"))); + } + } + currentTime = newTime; + } + + public record SkyblockEvent(long start, int duration, String[] extras, @Nullable String warpCommand) { + public static SkyblockEvent of(JsonObject jsonObject) { + String location = jsonObject.get("location").getAsString(); + location = location.isBlank() ? null: location; + return new SkyblockEvent(jsonObject.get("timestamp").getAsLong(), + jsonObject.get("duration").getAsInt(), + jsonObject.get("extras").getAsJsonArray().asList().stream().map(JsonElement::getAsString).toArray(String[]::new), + location); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .append("start", start) + .append("duration", duration) + .append("extras", extras) + .append("warpCommand", warpCommand) + .toString(); + } + } +} From cc4823e3646573d052ea36fef1ce6d9f9e9b90fd Mon Sep 17 00:00:00 2001 From: vicisacat Date: Sat, 20 Apr 2024 21:08:48 +0200 Subject: [PATCH 02/20] some more progress --- .../de/hysky/skyblocker/SkyblockerMod.java | 1 + .../{ => events}/EventNotifications.java | 5 +- .../skyblock/events/EventToast.java | 76 ++++++++++++++++++ .../assets/skyblocker/lang/en_us.json | 2 + .../textures/gui/sprites/notification.png | Bin 0 -> 157 bytes .../gui/sprites/notification.png.mcmeta | 10 +++ 6 files changed, 91 insertions(+), 3 deletions(-) rename src/main/java/de/hysky/skyblocker/skyblock/{ => events}/EventNotifications.java (96%) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/events/EventToast.java create mode 100644 src/main/resources/assets/skyblocker/textures/gui/sprites/notification.png create mode 100644 src/main/resources/assets/skyblocker/textures/gui/sprites/notification.png.mcmeta diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index abf09032b5..19eb395a09 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -26,6 +26,7 @@ import de.hysky.skyblocker.skyblock.end.TheEnd; import de.hysky.skyblocker.skyblock.entity.MobBoundingBoxes; import de.hysky.skyblocker.skyblock.fancybars.FancyStatusBars; +import de.hysky.skyblocker.skyblock.events.EventNotifications; import de.hysky.skyblocker.skyblock.garden.FarmingHud; import de.hysky.skyblocker.skyblock.garden.LowerSensitivity; import de.hysky.skyblocker.skyblock.garden.VisitorHelper; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/EventNotifications.java b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java similarity index 96% rename from src/main/java/de/hysky/skyblocker/skyblock/EventNotifications.java rename to src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java index 5f3bae9036..1d5761a533 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/EventNotifications.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java @@ -1,4 +1,4 @@ -package de.hysky.skyblocker.skyblock; +package de.hysky.skyblocker.skyblock.events; import com.google.gson.JsonArray; import com.google.gson.JsonElement; @@ -51,7 +51,7 @@ public static void refreshEvents() { for (Map.Entry> entry : events.entrySet()) { entry.getValue().sort(Comparator.comparingLong(SkyblockEvent::start)); // Sort just in case it's not in order for some reason in API - LOGGER.info("Next {} is at {}", entry.getKey(), entry.getValue().peekFirst()); + //LOGGER.info("Next {} is at {}", entry.getKey(), entry.getValue().peekFirst()); } }); } @@ -60,7 +60,6 @@ public static void refreshEvents() { private static void timeUpdate() { long newTime = System.currentTimeMillis() / 1000; - LOGGER.info(String.valueOf(newTime)); for (Map.Entry> entry : events.entrySet()) { LinkedList nextEvents = entry.getValue(); SkyblockEvent skyblockEvent = nextEvents.peekFirst(); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/EventToast.java b/src/main/java/de/hysky/skyblocker/skyblock/events/EventToast.java new file mode 100644 index 0000000000..4a0d139bb3 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/EventToast.java @@ -0,0 +1,76 @@ +package de.hysky.skyblocker.skyblock.events; + +import de.hysky.skyblocker.SkyblockerMod; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.toast.Toast; +import net.minecraft.client.toast.ToastManager; +import net.minecraft.item.ItemStack; +import net.minecraft.screen.ScreenTexts; +import net.minecraft.text.MutableText; +import net.minecraft.text.OrderedText; +import net.minecraft.text.Text; +import net.minecraft.util.Colors; +import net.minecraft.util.Formatting; +import net.minecraft.util.Identifier; + +import java.util.List; + +public class EventToast implements Toast { + private static final Identifier TEXTURE = new Identifier(SkyblockerMod.NAMESPACE, "notification"); + + private final long eventStartTime; + + private final List message; + private final ItemStack icon; + + public EventToast(long eventStartTime, String name, ItemStack icon) { + this.eventStartTime = eventStartTime; + MutableText formatted = Text.translatable("skyblocker.events.startsSoon", Text.literal(name).formatted(Formatting.YELLOW)).formatted(Formatting.WHITE); + message = MinecraftClient.getInstance().textRenderer.wrapLines(formatted, 200); + this.icon = icon; + + } + @Override + public Visibility draw(DrawContext context, ToastManager manager, long startTime) { + context.drawGuiTexture(TEXTURE, 0, 0, getWidth(), getHeight()); + + long currentTime = System.currentTimeMillis() / 1000; + int timeTillEvent = (int) (eventStartTime - currentTime); + + int seconds = timeTillEvent % 60; + int minutes = (timeTillEvent/60) % 60; + int hours = (timeTillEvent/3600) % 24; + + MutableText time = Text.empty(); + if (hours > 0) { + time.append(hours + "h").append(" "); + } + if (hours > 0 || minutes > 0) { + time.append(minutes + "m").append(" "); + } + time.append(seconds + "s"); + + int y = 4; + TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + for (OrderedText orderedText : message) { + context.drawText(textRenderer, orderedText, 30, y, Colors.WHITE, false); + y += textRenderer.fontHeight; + } + context.drawText(textRenderer, time, 30, y, Colors.LIGHT_YELLOW, false); + + context.drawItemWithoutEntity(icon, 8, getHeight()/2 - 8); + return startTime > 5_000 ? Visibility.HIDE: Visibility.SHOW; + } + + @Override + public int getWidth() { + return 200 + 30 + 5; + } + + @Override + public int getHeight() { + return 8 + 9 + message.size()*9; + } +} diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 57abdc46cf..8b549ac7a7 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -761,6 +761,8 @@ "skyblocker.itemProtection.noItemUuid": "§cYou must be holding an item that has a uuid in order to protect it!", "skyblocker.itemProtection.unableToProtect": "§cUnable to protect this item :( (Are you in skyblock?, are you holding an item?)", + "skyblocker.events.startsSoon": "%s starts soon!", + "skyblocker.tips.enabled": "§aEnabled Tips.", "skyblocker.tips.disabled": "§cDisabled Tips.", "skyblocker.tips.clickEnable": "§a[Click to Enable Tips]", diff --git a/src/main/resources/assets/skyblocker/textures/gui/sprites/notification.png b/src/main/resources/assets/skyblocker/textures/gui/sprites/notification.png new file mode 100644 index 0000000000000000000000000000000000000000..8f272cd7f92c38e71899775241f4bc56011c154e GIT binary patch literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^3xHUGi5W<~5S*O`q<8{+LR^6~5QK(?Dk>_@`D`&6 z$YCrA@(X5gcy Date: Sun, 21 Apr 2024 23:16:20 +0200 Subject: [PATCH 03/20] working notifications, probably I ain't waiting 50 hours waiting for notifications --- .../skyblock/events/EventNotifications.java | 63 ++++++++++++++-- .../skyblock/events/EventToast.java | 54 +++++++------- .../skyblock/events/JacobEventToast.java | 71 +++++++++++++++++++ .../java/de/hysky/skyblocker/utils/Utils.java | 17 +++++ .../utils/config/DurationController.java | 70 ++++++++++++++++++ .../config/DurationControllerWidget.java | 38 ++++++++++ 6 files changed, 280 insertions(+), 33 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java create mode 100644 src/main/java/de/hysky/skyblocker/utils/config/DurationController.java create mode 100644 src/main/java/de/hysky/skyblocker/utils/config/DurationControllerWidget.java diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java index 1d5761a533..ad85e7da67 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java @@ -3,15 +3,19 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.logging.LogUtils; import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.events.SkyblockEvents; import de.hysky.skyblocker.utils.Http; import de.hysky.skyblocker.utils.scheduler.Scheduler; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.toast.SystemToast; -import net.minecraft.text.Text; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; import org.apache.commons.lang3.builder.ToStringBuilder; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -24,10 +28,42 @@ public class EventNotifications { private static long currentTime = System.currentTimeMillis() / 1000; + public static final Map eventIcons = new Object2ObjectOpenHashMap<>(); + + static { + eventIcons.put("Dark Auction", new ItemStack(Items.NETHER_BRICK)); + eventIcons.put("Bonus Fishing Festival", new ItemStack(Items.FISHING_ROD)); + eventIcons.put("Bonus Mining Fiesta", new ItemStack(Items.IRON_PICKAXE)); + eventIcons.put("Jacob's Farming Contest", new ItemStack(Items.IRON_HOE)); + eventIcons.put("New Year Celebration", new ItemStack(Items.CAKE)); + eventIcons.put("Election Over!", new ItemStack(Items.JUKEBOX)); + eventIcons.put("Election Booth Opens", new ItemStack(Items.JUKEBOX)); + eventIcons.put("Spooky Festival", new ItemStack(Items.JACK_O_LANTERN)); + eventIcons.put("Season of Jerry", new ItemStack(Items.SNOWBALL)); + eventIcons.put("Jerry's Workshop Opens", new ItemStack(Items.SNOW_BLOCK)); + eventIcons.put("Traveling Zoo", new ItemStack(Items.HAY_BLOCK)); // change to the custom head one day + } + public static void init() { Scheduler.INSTANCE.scheduleCyclic(EventNotifications::timeUpdate, 20); SkyblockEvents.JOIN.register(EventNotifications::refreshEvents); + ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register( + ClientCommandManager.literal("skyblocker").then( + ClientCommandManager.literal("ye").then( + ClientCommandManager.argument("time", IntegerArgumentType.integer(6)).executes(context -> { + MinecraftClient.getInstance().getToastManager().add( + new EventToast(System.currentTimeMillis() / 1000 + context.getArgument("time", int.class), "Jacob's or something idk", new ItemStack(Items.PAPER)) + ); + return 0; + }) + ).executes(context -> { + MinecraftClient.getInstance().getToastManager().add( + new JacobEventToast(System.currentTimeMillis() / 1000 + 60, "Jacob's farming contest", new String[]{"Cactus","Cocoa Beans","Pumpkin"}) + ); + return 0;}) + ) + )); } private static final Map> events = new Object2ObjectOpenHashMap<>(); @@ -59,6 +95,9 @@ public static void refreshEvents() { private static void timeUpdate() { + List reminderTimes = SkyblockerConfigManager.get().general.eventNotifications.reminderTimes; + if (reminderTimes.isEmpty()) return; + long newTime = System.currentTimeMillis() / 1000; for (Map.Entry> entry : events.entrySet()) { LinkedList nextEvents = entry.getValue(); @@ -69,11 +108,21 @@ private static void timeUpdate() { skyblockEvent = nextEvents.peekFirst(); if (skyblockEvent == null) continue; } - if (currentTime + 60 < skyblockEvent.start() && newTime + 60 >= skyblockEvent.start()) { - MinecraftClient.getInstance().getToastManager().add(new SystemToast( - SystemToast.Type.PERIODIC_NOTIFICATION, - Text.literal(entry.getKey()), - Text.literal("Starting soon!"))); + String eventName = entry.getKey(); + + for (Integer reminderTime : reminderTimes) { + if (currentTime + reminderTime < skyblockEvent.start() && newTime + reminderTime >= skyblockEvent.start()) { + if (eventName.equals("Jacob's Farming Contest")) { + MinecraftClient.getInstance().getToastManager().add( + new JacobEventToast(skyblockEvent.start(), eventName, skyblockEvent.extras()) + ); + } + else { + MinecraftClient.getInstance().getToastManager().add( + new EventToast(skyblockEvent.start(), eventName, eventIcons.getOrDefault(eventName, new ItemStack(Items.PAPER))) + ); + } + } } } currentTime = newTime; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/EventToast.java b/src/main/java/de/hysky/skyblocker/skyblock/events/EventToast.java index 4a0d139bb3..bd44c0a553 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/EventToast.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/EventToast.java @@ -1,13 +1,13 @@ package de.hysky.skyblocker.skyblock.events; import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.utils.Utils; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.toast.Toast; import net.minecraft.client.toast.ToastManager; import net.minecraft.item.ItemStack; -import net.minecraft.screen.ScreenTexts; import net.minecraft.text.MutableText; import net.minecraft.text.OrderedText; import net.minecraft.text.Text; @@ -18,17 +18,20 @@ import java.util.List; public class EventToast implements Toast { - private static final Identifier TEXTURE = new Identifier(SkyblockerMod.NAMESPACE, "notification"); + protected static final Identifier TEXTURE = new Identifier(SkyblockerMod.NAMESPACE, "notification"); private final long eventStartTime; - private final List message; - private final ItemStack icon; + protected final List message; + protected final int messageWidth; + protected final ItemStack icon; public EventToast(long eventStartTime, String name, ItemStack icon) { this.eventStartTime = eventStartTime; MutableText formatted = Text.translatable("skyblocker.events.startsSoon", Text.literal(name).formatted(Formatting.YELLOW)).formatted(Formatting.WHITE); - message = MinecraftClient.getInstance().textRenderer.wrapLines(formatted, 200); + TextRenderer renderer = MinecraftClient.getInstance().textRenderer; + message = renderer.wrapLines(formatted, 150); + messageWidth = message.stream().mapToInt(renderer::getWidth).max().orElse(150); this.icon = icon; } @@ -36,41 +39,40 @@ public EventToast(long eventStartTime, String name, ItemStack icon) { public Visibility draw(DrawContext context, ToastManager manager, long startTime) { context.drawGuiTexture(TEXTURE, 0, 0, getWidth(), getHeight()); - long currentTime = System.currentTimeMillis() / 1000; - int timeTillEvent = (int) (eventStartTime - currentTime); + int y = 7; + y = 2 + drawMessage(context, 30, y, Colors.WHITE); + drawTimer(context, 30, y); - int seconds = timeTillEvent % 60; - int minutes = (timeTillEvent/60) % 60; - int hours = (timeTillEvent/3600) % 24; - - MutableText time = Text.empty(); - if (hours > 0) { - time.append(hours + "h").append(" "); - } - if (hours > 0 || minutes > 0) { - time.append(minutes + "m").append(" "); - } - time.append(seconds + "s"); + context.drawItemWithoutEntity(icon, 8, getHeight()/2 - 8); + return startTime > 5_000 ? Visibility.HIDE: Visibility.SHOW; + } - int y = 4; + protected int drawMessage(DrawContext context, int x, int y, int color) { TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; for (OrderedText orderedText : message) { - context.drawText(textRenderer, orderedText, 30, y, Colors.WHITE, false); + context.drawText(textRenderer, orderedText, x, y, color, false); y += textRenderer.fontHeight; } - context.drawText(textRenderer, time, 30, y, Colors.LIGHT_YELLOW, false); + return y; + } - context.drawItemWithoutEntity(icon, 8, getHeight()/2 - 8); - return startTime > 5_000 ? Visibility.HIDE: Visibility.SHOW; + protected void drawTimer(DrawContext context, int x, int y) { + long currentTime = System.currentTimeMillis() / 1000; + int timeTillEvent = (int) (eventStartTime - currentTime); + + Text time = timeTillEvent < 0 ? Text.literal("Starts now!"): Utils.getDurationText(timeTillEvent); + + TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + context.drawText(textRenderer, time, x, y, Colors.LIGHT_YELLOW, false); } @Override public int getWidth() { - return 200 + 30 + 5; + return messageWidth + 30 + 6; } @Override public int getHeight() { - return 8 + 9 + message.size()*9; + return 12 + 2 + (message.size()+1)*9; } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java b/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java new file mode 100644 index 0000000000..4f9c3fd7fe --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java @@ -0,0 +1,71 @@ +package de.hysky.skyblocker.skyblock.events; + +import com.mojang.blaze3d.platform.GlStateManager; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.toast.ToastManager; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.util.Colors; +import net.minecraft.util.math.MathHelper; + +import java.util.HashMap; +import java.util.Map; + +public class JacobEventToast extends EventToast{ + + private final String[] crops; + + private static final Map cropItems = new HashMap<>(); + + static { + cropItems.put("Wheat", new ItemStack(Items.WHEAT)); + cropItems.put("Mushroom", new ItemStack(Items.RED_MUSHROOM)); + cropItems.put("Pumpkin", new ItemStack(Items.CARVED_PUMPKIN)); + cropItems.put("Melon", new ItemStack(Items.MELON)); + cropItems.put("Sugar Cane", new ItemStack(Items.SUGAR_CANE)); + cropItems.put("Cactus", new ItemStack(Items.CACTUS)); + cropItems.put("Carrot", new ItemStack(Items.CARROT)); + cropItems.put("Cocoa Beans", new ItemStack(Items.COCOA_BEANS)); + cropItems.put("Potato", new ItemStack(Items.POTATO)); + cropItems.put("Nether Wart", new ItemStack(Items.NETHER_WART)); + } + + public JacobEventToast(long eventStartTime, String name, String[] crops) { + super(eventStartTime, name, new ItemStack(Items.IRON_HOE)); + this.crops = crops; + } + + @Override + public Visibility draw(DrawContext context, ToastManager manager, long startTime) { + context.drawGuiTexture(TEXTURE, 0, 0, getWidth(), getHeight()); + + int y = 7; + TextRenderer textRenderer = manager.getClient().textRenderer; + if (startTime < 3_000){ + int k = MathHelper.floor(MathHelper.clamp((3_000 - startTime) / 200.0f, 0.0f, 1.0f) * 255.0f) << 24 | 0x4000000; + y = 2 + drawMessage(context, 30, y, 0xFFFFFF | k); + } else { + int k = (~MathHelper.floor(MathHelper.clamp((startTime - 3_000) / 200.0f, 0.0f, 1.0f) * 255.0f)) << 24 | 0x4000000; + + + String s = "Crops:"; + int x = 30 + textRenderer.getWidth(s) + 4; + context.drawText(textRenderer, s, 30, 7 + (16 - textRenderer.fontHeight)/2, Colors.WHITE, false); + for (int i = 0; i < crops.length; i++) { + context.drawItem(cropItems.get(crops[i]), x + i * (16 + 8), 7); + } + context.fill(30, 6, 30 + messageWidth, 22, 400, 0x212121 | k); + y += textRenderer.fontHeight * message.size(); + } + drawTimer(context, 30, y); + + context.drawItemWithoutEntity(icon, 8, getHeight()/2 - 8); + return startTime > 5_000 ? Visibility.HIDE: Visibility.SHOW; + } + + @Override + public int getHeight() { + return Math.max(super.getHeight(), 32); + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/Utils.java b/src/main/java/de/hysky/skyblocker/utils/Utils.java index 62a3b8975a..8316bb9ca6 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Utils.java +++ b/src/main/java/de/hysky/skyblocker/utils/Utils.java @@ -19,6 +19,7 @@ import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.PlayerListEntry; import net.minecraft.scoreboard.*; +import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; import org.jetbrains.annotations.NotNull; @@ -355,6 +356,22 @@ private static void updateScoreboard(MinecraftClient client) { } } + public static Text getDurationText(int timeInSeconds) { + int seconds = timeInSeconds % 60; + int minutes = (timeInSeconds/60) % 60; + int hours = (timeInSeconds/3600) % 24; + + MutableText time = Text.empty(); + if (hours > 0) { + time.append(hours + "h").append(" "); + } + if (hours > 0 || minutes > 0) { + time.append(minutes + "m").append(" "); + } + time.append(seconds + "s"); + return time; + } + private static void updateFromPlayerList(MinecraftClient client) { if (client.getNetworkHandler() == null) { return; diff --git a/src/main/java/de/hysky/skyblocker/utils/config/DurationController.java b/src/main/java/de/hysky/skyblocker/utils/config/DurationController.java new file mode 100644 index 0000000000..09edcf3c91 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/config/DurationController.java @@ -0,0 +1,70 @@ +package de.hysky.skyblocker.utils.config; + +import de.hysky.skyblocker.utils.Utils; +import dev.isxander.yacl3.api.Option; +import dev.isxander.yacl3.api.utils.Dimension; +import dev.isxander.yacl3.gui.AbstractWidget; +import dev.isxander.yacl3.gui.YACLScreen; +import dev.isxander.yacl3.gui.controllers.string.IStringController; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public record DurationController(Option option) implements IStringController { + + private static final Pattern secondsPattern = Pattern.compile("(^|\\s)(\\d+)s(\\s|$)"); + private static final Pattern minutesPattern = Pattern.compile("(^|\\s)(\\d+)m(\\s|$)"); + private static final Pattern hoursPattern = Pattern.compile("(^|\\s)(\\d+)h(\\s|$)"); + + @Override + public String getString() { + return Utils.getDurationText(option.pendingValue()).getString(); + } + + + @Override + public void setFromString(String value) { + Matcher hoursMatcher = hoursPattern.matcher(value); + Matcher minutesMatcher = minutesPattern.matcher(value); + Matcher secondsMatcher = secondsPattern.matcher(value); + + int result = 0; + if (hoursMatcher.find()) { + result += Integer.parseInt(hoursMatcher.group(2)) * 3600; + } + if (minutesMatcher.find()) { + result += Integer.parseInt(minutesMatcher.group(2)) * 60; + } + if (secondsMatcher.find()) { + result += Integer.parseInt(secondsMatcher.group(2)); + } + option.requestSet(result); + } + + + @Override + public boolean isInputValid(String s) { + Matcher hoursMatcher = hoursPattern.matcher(s); + Matcher minutesMatcher = minutesPattern.matcher(s); + Matcher secondsMatcher = secondsPattern.matcher(s); + + int hoursCount = 0; + while (hoursMatcher.find()) hoursCount++; + int minutesCount = 0; + while (minutesMatcher.find()) minutesCount++; + int secondsCount = 0; + while (secondsMatcher.find()) secondsCount++; + + if (hoursCount == 0 && minutesCount == 0 && secondsCount == 0) return false; + if (hoursCount > 1 || minutesCount > 1 || secondsCount > 1) return false; + s = s.replaceAll(hoursPattern.pattern(), ""); + s = s.replaceAll(minutesPattern.pattern(), ""); + s = s.replaceAll(secondsPattern.pattern(), ""); + return s.isBlank(); + } + + @Override + public AbstractWidget provideWidget(YACLScreen screen, Dimension widgetDimension) { + return new DurationControllerWidget(this, screen, widgetDimension); + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/config/DurationControllerWidget.java b/src/main/java/de/hysky/skyblocker/utils/config/DurationControllerWidget.java new file mode 100644 index 0000000000..f25cd08826 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/config/DurationControllerWidget.java @@ -0,0 +1,38 @@ +package de.hysky.skyblocker.utils.config; + +import dev.isxander.yacl3.api.utils.Dimension; +import dev.isxander.yacl3.gui.YACLScreen; +import dev.isxander.yacl3.gui.controllers.string.IStringController; +import dev.isxander.yacl3.gui.controllers.string.StringControllerElement; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +import java.util.function.Consumer; + +public class DurationControllerWidget extends StringControllerElement { + + public DurationControllerWidget(IStringController control, YACLScreen screen, Dimension dim) { + super(control, screen, dim, false); + } + + @Override + public void unfocus() { + if (control.isInputValid(inputField)) super.unfocus(); + else modifyInput(stringBuilder -> stringBuilder.replace(0, stringBuilder.length(), control.getString())); + } + + @Override + public boolean modifyInput(Consumer consumer) { + StringBuilder temp = new StringBuilder(inputField); + consumer.accept(temp); + inputField = temp.toString(); + return true; + } + + @Override + protected Text getValueText() { + Text valueText = super.getValueText(); + boolean inputValid = control.isInputValid(valueText.getString()); + return valueText.copy().formatted(inputValid ? Formatting.WHITE: Formatting.RED); + } +} From 84ffa6d5f466a52b7927070447f71c816bcc6c94 Mon Sep 17 00:00:00 2001 From: vicisacat Date: Sun, 21 Apr 2024 23:17:39 +0200 Subject: [PATCH 04/20] unused import :D --- .../de/hysky/skyblocker/skyblock/events/JacobEventToast.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java b/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java index 4f9c3fd7fe..12590d09fe 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java @@ -1,6 +1,5 @@ package de.hysky.skyblocker.skyblock.events; -import com.mojang.blaze3d.platform.GlStateManager; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.toast.ToastManager; From c645892f94f9017b3685733c04520c47beedfed9 Mon Sep 17 00:00:00 2001 From: vicisacat Date: Tue, 23 Apr 2024 13:51:45 +0200 Subject: [PATCH 05/20] upcoming events tab!!! so cool --- .../auction/widgets/CategoryTabWidget.java | 28 +-- .../skyblock/events/EventNotifications.java | 8 +- .../skyblock/events/JacobEventToast.java | 2 +- .../skyblock/itemlist/ItemListTab.java | 89 ++++++++++ .../skyblock/itemlist/ItemListWidget.java | 128 +++++++------ .../itemlist/SearchResultsWidget.java | 15 +- .../skyblock/itemlist/UpcomingEventsTab.java | 168 ++++++++++++++++++ .../utils/render/gui/SideTabButtonWidget.java | 39 ++++ 8 files changed, 400 insertions(+), 77 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemListTab.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java create mode 100644 src/main/java/de/hysky/skyblocker/utils/render/gui/SideTabButtonWidget.java diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/CategoryTabWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/CategoryTabWidget.java index 02dbc1329e..a0b5f0b96f 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/CategoryTabWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/CategoryTabWidget.java @@ -1,42 +1,26 @@ package de.hysky.skyblocker.skyblock.auction.widgets; import de.hysky.skyblocker.skyblock.auction.SlotClickHandler; +import de.hysky.skyblocker.utils.render.gui.SideTabButtonWidget; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.ButtonTextures; -import net.minecraft.client.gui.widget.ToggleButtonWidget; import net.minecraft.client.item.TooltipType; import net.minecraft.item.Item.TooltipContext; import net.minecraft.item.ItemStack; -import net.minecraft.util.Identifier; import org.jetbrains.annotations.NotNull; -public class CategoryTabWidget extends ToggleButtonWidget { - private static final ButtonTextures TEXTURES = new ButtonTextures(new Identifier("recipe_book/tab"), new Identifier("recipe_book/tab_selected")); - - public void setIcon(@NotNull ItemStack icon) { - this.icon = icon.copy(); - } - - private @NotNull ItemStack icon; +public class CategoryTabWidget extends SideTabButtonWidget { private final SlotClickHandler slotClick; private int slotId = -1; public CategoryTabWidget(@NotNull ItemStack icon, SlotClickHandler slotClick) { - super(0, 0, 35, 27, false); - this.icon = icon.copy(); // copy prevents item disappearing on click + super(0, 0, false, icon); this.slotClick = slotClick; - setTextures(TEXTURES); } @Override public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { - if (textures == null) return; - Identifier identifier = textures.get(true, this.toggled); - int x = getX(); - if (toggled) x -= 2; - context.drawGuiTexture(identifier, x, this.getY(), this.width, this.height); - context.drawItem(icon, x + 9, getY() + 5); + super.renderWidget(context, mouseX, mouseY, delta); if (isMouseOver(mouseX, mouseY)) { context.getMatrices().push(); @@ -52,8 +36,8 @@ public void setSlotId(int slotId) { @Override public void onClick(double mouseX, double mouseY) { - if (this.toggled || slotId == -1) return; + if (isToggled() || slotId == -1) return; + super.onClick(mouseX, mouseY); slotClick.click(slotId); - this.setToggled(true); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java index ad85e7da67..d2f9904010 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java @@ -28,13 +28,15 @@ public class EventNotifications { private static long currentTime = System.currentTimeMillis() / 1000; + public static final String JACOBS = "Jacob's Farming Contest"; + public static final Map eventIcons = new Object2ObjectOpenHashMap<>(); static { eventIcons.put("Dark Auction", new ItemStack(Items.NETHER_BRICK)); eventIcons.put("Bonus Fishing Festival", new ItemStack(Items.FISHING_ROD)); eventIcons.put("Bonus Mining Fiesta", new ItemStack(Items.IRON_PICKAXE)); - eventIcons.put("Jacob's Farming Contest", new ItemStack(Items.IRON_HOE)); + eventIcons.put(JACOBS, new ItemStack(Items.IRON_HOE)); eventIcons.put("New Year Celebration", new ItemStack(Items.CAKE)); eventIcons.put("Election Over!", new ItemStack(Items.JUKEBOX)); eventIcons.put("Election Booth Opens", new ItemStack(Items.JUKEBOX)); @@ -68,6 +70,10 @@ public static void init() { private static final Map> events = new Object2ObjectOpenHashMap<>(); + public static Map> getEvents() { + return events; + } + public static void refreshEvents() { CompletableFuture.supplyAsync(() -> { try { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java b/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java index 12590d09fe..a7a5f9c0c3 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java @@ -15,7 +15,7 @@ public class JacobEventToast extends EventToast{ private final String[] crops; - private static final Map cropItems = new HashMap<>(); + public static final Map cropItems = new HashMap<>(); static { cropItems.put("Wheat", new ItemStack(Items.WHEAT)); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemListTab.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemListTab.java new file mode 100644 index 0000000000..4109246d2d --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemListTab.java @@ -0,0 +1,89 @@ +package de.hysky.skyblocker.skyblock.itemlist; + +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.widget.TextFieldWidget; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +import java.util.List; + +public class ItemListTab extends ItemListWidget.TabContainerWidget { + + private SearchResultsWidget results; + private final MinecraftClient client; + private TextFieldWidget searchField; + + public ItemListTab(int x, int y, MinecraftClient client, TextFieldWidget searchField) { + super(x, y, Text.literal("Item List Tab")); + this.client = client; + this.searchField = searchField; + if (ItemRepository.filesImported()) { + this.results = new SearchResultsWidget(this.client, x - 9, y - 9 ); + this.results.updateSearchResult(searchField == null ? "": this.searchField.getText()); + } + } + + @Override + public List children() { + return List.of(results, searchField); + } + + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + MatrixStack matrices = context.getMatrices(); + matrices.push(); + matrices.translate(0.0D, 0.0D, 100.0D); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + int x = getX(); + int y = getY(); + + // all coordinates offseted -9 + if (!ItemRepository.filesImported() && !this.searchField.isFocused() && this.searchField.getText().isEmpty()) { + Text hintText = (Text.literal("Loading...")).formatted(Formatting.ITALIC).formatted(Formatting.GRAY); + context.drawTextWithShadow(this.client.textRenderer, hintText, x + 16, y + 7, -1); + } else if (!this.searchField.isFocused() && this.searchField.getText().isEmpty()) { + Text hintText = (Text.translatable("gui.recipebook.search_hint")).formatted(Formatting.ITALIC).formatted(Formatting.GRAY); + context.drawTextWithShadow(this.client.textRenderer, hintText, x + 16, y + 7, -1); + } else { + this.searchField.render(context, mouseX, mouseY, delta); + } + if (ItemRepository.filesImported()) { + if (results == null) { + this.results = new SearchResultsWidget(this.client, x - 9, y - 9); + } + this.results.updateSearchResult(this.searchField.getText()); + this.results.render(context, mouseX, mouseY, delta); + } + matrices.pop(); + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) {} + + public void setSearchField(TextFieldWidget searchField) { + this.searchField = searchField; + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (!visible) return false; + if (this.searchField.mouseClicked(mouseX, mouseY, button)) { + this.results.closeRecipeView(); + this.searchField.setFocused(true); + return true; + } else { + this.searchField.setFocused(false); + return this.results.mouseClicked(mouseX, mouseY, button); + } + } + + @Override + public void drawTooltip(DrawContext context, int mouseX, int mouseY) { + if (this.results != null) this.results.drawTooltip(context, mouseX, mouseY); + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemListWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemListWidget.java index 6120528c47..4a258b9ed3 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemListWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemListWidget.java @@ -1,103 +1,127 @@ package de.hysky.skyblocker.skyblock.itemlist; -import com.mojang.blaze3d.systems.RenderSystem; - import de.hysky.skyblocker.mixins.accessors.RecipeBookWidgetAccessor; +import de.hysky.skyblocker.utils.render.gui.SideTabButtonWidget; +import it.unimi.dsi.fastutil.Pair; +import it.unimi.dsi.fastutil.objects.ObjectObjectImmutablePair; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; +import net.minecraft.client.gui.tooltip.Tooltip; +import net.minecraft.client.gui.widget.ContainerWidget; import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; import net.minecraft.screen.AbstractRecipeScreenHandler; import net.minecraft.text.Text; -import net.minecraft.util.Formatting; + +import java.util.ArrayList; +import java.util.List; @Environment(value = EnvType.CLIENT) public class ItemListWidget extends RecipeBookWidget { private int parentWidth; private int parentHeight; private int leftOffset; - private TextFieldWidget searchField; - private SearchResultsWidget results; + + private TabContainerWidget currentTabContent; + private final List> tabs = new ArrayList<>(2); + private ItemListTab itemListTab; public ItemListWidget() { super(); } - public void updateSearchResult() { - this.results.updateSearchResult(((RecipeBookWidgetAccessor) this).getSearchText()); - } - @Override public void initialize(int parentWidth, int parentHeight, MinecraftClient client, boolean narrow, AbstractRecipeScreenHandler craftingScreenHandler) { super.initialize(parentWidth, parentHeight, client, narrow, craftingScreenHandler); this.parentWidth = parentWidth; this.parentHeight = parentHeight; this.leftOffset = narrow ? 0 : 86; - this.searchField = ((RecipeBookWidgetAccessor) this).getSearchField(); - int x = (this.parentWidth - 147) / 2 - this.leftOffset; - int y = (this.parentHeight - 166) / 2; - if (ItemRepository.filesImported()) { - this.results = new SearchResultsWidget(this.client, x, y); - this.updateSearchResult(); - } + TextFieldWidget searchField = ((RecipeBookWidgetAccessor) this).getSearchField(); + int x = (parentWidth - 147) / 2 - leftOffset; + int y = (parentHeight - 166) / 2; + + // Init all the tabs, content and the tab button on the left + tabs.clear(); + itemListTab = new ItemListTab(x + 9, y + 9, this.client, searchField); + + SideTabButtonWidget itemListTabButton = new SideTabButtonWidget(x - 30, y + 3, true, new ItemStack(Items.CRAFTING_TABLE)); + itemListTabButton.setTooltip(Tooltip.of(Text.literal("Item List"))); + tabs.add(new ObjectObjectImmutablePair<>( + itemListTabButton, + this.currentTabContent = this.itemListTab)); + + SideTabButtonWidget eventsTabButtonWidget = new SideTabButtonWidget(x - 30, y + 3 + 27, false, new ItemStack(Items.CLOCK)); + eventsTabButtonWidget.setTooltip(Tooltip.of(Text.literal("Upcoming Events"))); + tabs.add(new ObjectObjectImmutablePair<>( + eventsTabButtonWidget, + new UpcomingEventsTab(x + 9, y + 9, this.client) + )); + + } + + @Override + public void reset() { + super.reset(); + if (itemListTab != null) itemListTab.setSearchField(((RecipeBookWidgetAccessor) this).getSearchField()); } @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { if (this.isOpen()) { - MatrixStack matrices = context.getMatrices(); - matrices.push(); - matrices.translate(0.0D, 0.0D, 100.0D); - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - this.searchField = ((RecipeBookWidgetAccessor) this).getSearchField(); int i = (this.parentWidth - 147) / 2 - this.leftOffset; int j = (this.parentHeight - 166) / 2; + // Draw the texture context.drawTexture(TEXTURE, i, j, 1, 1, 147, 166); - this.searchField = ((RecipeBookWidgetAccessor) this).getSearchField(); - - if (!ItemRepository.filesImported() && !this.searchField.isFocused() && this.searchField.getText().isEmpty()) { - Text hintText = (Text.literal("Loading...")).formatted(Formatting.ITALIC).formatted(Formatting.GRAY); - context.drawTextWithShadow(this.client.textRenderer, hintText, i + 25, j + 14, -1); - } else if (!this.searchField.isFocused() && this.searchField.getText().isEmpty()) { - Text hintText = (Text.translatable("gui.recipebook.search_hint")).formatted(Formatting.ITALIC).formatted(Formatting.GRAY); - context.drawTextWithShadow(this.client.textRenderer, hintText, i + 25, j + 14, -1); - } else { - this.searchField.render(context, mouseX, mouseY, delta); - } - if (ItemRepository.filesImported()) { - if (results == null) { - int x = (this.parentWidth - 147) / 2 - this.leftOffset; - int y = (this.parentHeight - 166) / 2; - this.results = new SearchResultsWidget(this.client, x, y); - } - this.updateSearchResult(); - this.results.render(context, mouseX, mouseY, delta); + // Draw the tab's content + if (currentTabContent != null) currentTabContent.render(context, mouseX, mouseY, delta); + // Draw the tab buttons + for (Pair tab : tabs) { + tab.left().render(context, mouseX, mouseY, delta); } - matrices.pop(); + } } @Override public void drawTooltip(DrawContext context, int x, int y, int mouseX, int mouseY) { - if (this.isOpen() && ItemRepository.filesImported() && results != null) { - this.results.drawTooltip(context, mouseX, mouseY); + if (this.isOpen() && currentTabContent != null) { + this.currentTabContent.drawTooltip(context, mouseX, mouseY); } } @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (this.isOpen() && this.client.player != null && !this.client.player.isSpectator() && ItemRepository.filesImported() && this.searchField != null && results != null) { - if (this.searchField.mouseClicked(mouseX, mouseY, button)) { - this.results.closeRecipeView(); - this.searchField.setFocused(true); - return true; - } else { - this.searchField.setFocused(false); - return this.results.mouseClicked(mouseX, mouseY, button); + if (this.isOpen() && this.client.player != null && !this.client.player.isSpectator()) { + // check if a tab is clicked + for (Pair tab : tabs) { + if (tab.first().mouseClicked(mouseX, mouseY, button) && currentTabContent != tab.right()) { + for (Pair tab2 : tabs) { + tab2.first().setToggled(false); + } + tab.first().setToggled(true); + currentTabContent = tab.right(); + return true; + } } + // click the tab content + if (currentTabContent != null) return currentTabContent.mouseClicked(mouseX, mouseY, button); + else return false; } else return false; } + + /** + * A container widget but with a fixed width and height and a drawTooltip method to implement + */ + public abstract static class TabContainerWidget extends ContainerWidget { + + public TabContainerWidget(int x, int y, Text text) { + super(x, y, 131, 150, text); + } + + public abstract void drawTooltip(DrawContext context, int mouseX, int mouseY); + } } \ No newline at end of file diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/SearchResultsWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/SearchResultsWidget.java index 1ef352e34c..48d3a8f6ee 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/SearchResultsWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/SearchResultsWidget.java @@ -6,6 +6,7 @@ import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.Drawable; +import net.minecraft.client.gui.Element; import net.minecraft.client.gui.screen.ButtonTextures; import net.minecraft.client.gui.widget.ToggleButtonWidget; import net.minecraft.component.DataComponentTypes; @@ -23,7 +24,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -public class SearchResultsWidget implements Drawable { +public class SearchResultsWidget implements Drawable, Element { private static final ButtonTextures PAGE_FORWARD_TEXTURES = new ButtonTextures(new Identifier("recipe_book/page_forward"), new Identifier("recipe_book/page_forward_highlighted")); private static final ButtonTextures PAGE_BACKWARD_TEXTURES = new ButtonTextures(new Identifier("recipe_book/page_backward"), new Identifier("recipe_book/page_backward_highlighted")); private static final int COLS = 5; @@ -225,4 +226,16 @@ public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) { return false; } + private boolean focused = false; + + @Override + public void setFocused(boolean focused) { + this.focused = focused; + } + + @Override + public boolean isFocused() { + return focused; + } + } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java new file mode 100644 index 0000000000..134c5d4d3d --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java @@ -0,0 +1,168 @@ +package de.hysky.skyblocker.skyblock.itemlist; + +import de.hysky.skyblocker.mixin.accessor.DrawContextInvoker; +import de.hysky.skyblocker.skyblock.events.EventNotifications; +import de.hysky.skyblocker.skyblock.events.JacobEventToast; +import de.hysky.skyblocker.utils.Utils; +import de.hysky.skyblocker.utils.scheduler.MessageScheduler; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.tooltip.HoveredTooltipPositioner; +import net.minecraft.client.gui.tooltip.TooltipComponent; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.text.MutableText; +import net.minecraft.text.Style; +import net.minecraft.text.Text; +import net.minecraft.util.Colors; +import net.minecraft.util.Formatting; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; + +public class UpcomingEventsTab extends ItemListWidget.TabContainerWidget { + private static final ItemStack CLOCK = new ItemStack(Items.CLOCK); + private final MinecraftClient client; + private final List events; + + public UpcomingEventsTab(int x, int y, MinecraftClient client) { + super(x, y, Text.literal("Upcoming Events Tab")); + this.client = client; + events = EventNotifications.getEvents().entrySet() + .stream() + .sorted(Comparator.comparingLong(a -> a.getValue().isEmpty() ? Long.MAX_VALUE : a.getValue().peekFirst().start())) + .map(stringLinkedListEntry -> new EventRenderer(stringLinkedListEntry.getKey(), stringLinkedListEntry.getValue())) + .toList(); + } + + @Override + public void drawTooltip(DrawContext context, int mouseX, int mouseY) { + if (hovered != null) { + ((DrawContextInvoker) context).invokeDrawTooltip(this.client.textRenderer, hovered.getTooltip(), mouseX, mouseY, HoveredTooltipPositioner.INSTANCE); + } + } + + @Override + public List children() { + return List.of(); + } + + private EventRenderer hovered = null; + + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + int x = getX(); + int y = getY(); + context.enableScissor(x, y, getRight(), getBottom()); + context.drawItem(CLOCK, x, y + 4); + context.drawText(this.client.textRenderer, "Upcoming Events", x + 17, y + 7, -1, true); + + int eventsY = y + 7 + 24; + hovered = null; + for (EventRenderer eventRenderer : events) { + eventRenderer.render(context, x + 1, eventsY, mouseX, mouseY); + if (eventRenderer.isMouseOver(mouseX, mouseY, x+1, eventsY)) hovered = eventRenderer; + eventsY += eventRenderer.getHeight(); + + } + context.disableScissor(); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (hovered != null && hovered.getWarpCommand() != null) { + MessageScheduler.INSTANCE.sendMessageAfterCooldown(hovered.getWarpCommand()); + return true; + } + return false; + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) { + + } + + public static class EventRenderer { + + private final LinkedList events; + private final String eventName; + + public EventRenderer(String eventName, LinkedList events) { + this.events = events; + this.eventName = eventName; + } + + public void render(DrawContext context, int x, int y, int mouseX, int mouseY) { + long time = System.currentTimeMillis() / 1000; + TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + context.drawText(textRenderer, Text.literal(eventName).fillStyle(Style.EMPTY.withUnderline(isMouseOver(mouseX, mouseY, x, y))), x, y, -1, true); + if (events.isEmpty()) { + context.drawText(textRenderer, " No more this year!", x, y + textRenderer.fontHeight, Colors.GRAY, false); + } else if (events.peekFirst().start() > time) { + MutableText formatted = Text.literal(" Starts in ").append(Utils.getDurationText((int) (events.peekFirst().start() - time))).formatted(Formatting.YELLOW); + context.drawText(textRenderer, formatted, x, y + textRenderer.fontHeight, -1, true); + } else { + MutableText formatted = Text.literal(" Ends in ").append(Utils.getDurationText((int) (events.peekFirst().start() + events.peekFirst().duration() - time))).formatted(Formatting.GREEN); + context.drawText(textRenderer, formatted, x, y + textRenderer.fontHeight, -1, true); + } + + } + + public int getHeight() { + return 20; + } + + public boolean isMouseOver(int mouseX, int mouseY, int x, int y) { + return mouseX >= x && mouseX <= x + 131 && mouseY >= y && mouseY <= y+getHeight(); + } + + public List getTooltip() { + List components = new ArrayList<>(); + if (events.peekFirst() == null) return components; + if (eventName.equals(EventNotifications.JACOBS)) { + components.add(new JacobsTooltip(events.peekFirst().extras())); + } + //noinspection DataFlowIssue + if (events.peekFirst().warpCommand() != null) { + components.add(TooltipComponent.of(Text.literal("Click to warp!").formatted(Formatting.ITALIC).asOrderedText())); + } + + return components; + } + + public @Nullable String getWarpCommand() { + if (events.isEmpty()) return null; + return events.peek().warpCommand(); + } + } + + private record JacobsTooltip(String[] crops) implements TooltipComponent { + + private static final ItemStack BARRIER = new ItemStack(Items.BARRIER); + + @Override + public int getHeight() { + return 20; + } + + @Override + public int getWidth(TextRenderer textRenderer) { + return 16 * 3 + 4; + } + + @Override + public void drawItems(TextRenderer textRenderer, int x, int y, DrawContext context) { + for (int i = 0; i < crops.length; i++) { + String crop = crops[i]; + context.drawItem(JacobEventToast.cropItems.getOrDefault(crop, BARRIER), x + 18 * i, y + 2); + } + } + + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/SideTabButtonWidget.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/SideTabButtonWidget.java new file mode 100644 index 0000000000..87da0d3666 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/render/gui/SideTabButtonWidget.java @@ -0,0 +1,39 @@ +package de.hysky.skyblocker.utils.render.gui; + +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.ButtonTextures; +import net.minecraft.client.gui.widget.ToggleButtonWidget; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.NotNull; + +public class SideTabButtonWidget extends ToggleButtonWidget { + private static final ButtonTextures TEXTURES = new ButtonTextures(new Identifier("recipe_book/tab"), new Identifier("recipe_book/tab_selected")); + protected @NotNull ItemStack icon; + + public void setIcon(@NotNull ItemStack icon) { + this.icon = icon.copy(); + } + + public SideTabButtonWidget(int x, int y, boolean toggled, @NotNull ItemStack icon) { + super(x, y, 35, 27, toggled); + this.icon = icon.copy(); + setTextures(TEXTURES); + } + + @Override + public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + if (textures == null) return; + Identifier identifier = textures.get(true, this.toggled); + int x = getX(); + if (toggled) x -= 2; + context.drawGuiTexture(identifier, x, this.getY(), this.width, this.height); + context.drawItem(icon, x + 9, getY() + 5); + } + + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + if (!isToggled()) this.setToggled(true); + } +} From 07a0b32d0d1eadce04963963975322a3a7a093cb Mon Sep 17 00:00:00 2001 From: vicisacat Date: Wed, 24 Apr 2024 15:48:28 +0200 Subject: [PATCH 06/20] epic config --- .../EventNotificationsCategory.java | 43 +++++++++++++++++++ .../skyblock/events/EventNotifications.java | 19 ++++++-- 2 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java diff --git a/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java new file mode 100644 index 0000000000..02be92a5ea --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java @@ -0,0 +1,43 @@ +package de.hysky.skyblocker.config.categories; + +import de.hysky.skyblocker.config.SkyblockerConfig; +import de.hysky.skyblocker.skyblock.events.EventNotifications; +import de.hysky.skyblocker.utils.config.DurationController; +import dev.isxander.yacl3.api.ConfigCategory; +import dev.isxander.yacl3.api.ListOption; +import dev.isxander.yacl3.api.OptionDescription; +import dev.isxander.yacl3.api.OptionGroup; +import net.minecraft.text.Text; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class EventNotificationsCategory { + + public static ConfigCategory create(SkyblockerConfig config) { + return ConfigCategory.createBuilder() + .name(Text.literal("Event Notifications")) + .groups(createGroups(config)) + .tooltip(Text.translatable("text.autoconfig.skyblocker.option.general.eventNotifications.@Tooltip[0]"), + Text.translatable("text.autoconfig.skyblocker.option.general.eventNotifications.@Tooltip[1]")) + .build(); + + } + + private static List createGroups(SkyblockerConfig config) { + Map> eventsReminderTimes = config.eventNotifications.eventsReminderTimes; + List groups = new ArrayList<>(eventsReminderTimes.size()); + for (Map.Entry> entry : eventsReminderTimes.entrySet()) { + groups.add(ListOption.createBuilder() + .name(Text.literal(entry.getKey())) + .binding(EventNotifications.DEFAULT_REMINDERS, entry::getValue, entry::setValue) + .controller(option -> () -> new DurationController(option)) // yea + .initial(60) + .collapsed(true) + .build() + ); + } + return groups; + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java index d2f9904010..0d2d4d4d33 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java @@ -30,6 +30,8 @@ public class EventNotifications { public static final String JACOBS = "Jacob's Farming Contest"; + public static final List DEFAULT_REMINDERS = List.of(60, 60*5); + public static final Map eventIcons = new Object2ObjectOpenHashMap<>(); static { @@ -80,7 +82,7 @@ public static void refreshEvents() { JsonArray jsonElements = SkyblockerMod.GSON.fromJson(Http.sendGetRequest("https://hysky.de/api/calendar"), JsonArray.class); return jsonElements.asList().stream().map(JsonElement::getAsJsonObject).toList(); } catch (Exception e) { - LOGGER.error("[Skyblocker] Failed to download warps list", e); + LOGGER.error("[Skyblocker] Failed to download events list", e); } return List.of(); }).thenAccept(eventsList -> { @@ -95,14 +97,21 @@ public static void refreshEvents() { entry.getValue().sort(Comparator.comparingLong(SkyblockEvent::start)); // Sort just in case it's not in order for some reason in API //LOGGER.info("Next {} is at {}", entry.getKey(), entry.getValue().peekFirst()); } - }); + + for (String s : events.keySet()) { + SkyblockerConfigManager.get().eventNotifications.eventsReminderTimes.computeIfAbsent(s, s1 -> DEFAULT_REMINDERS); + } + }).exceptionally(EventNotifications::itBorked); + } + + private static Void itBorked(Throwable throwable) { + LOGGER.error("[Skyblocker] Event loading borked, sowwy :(", throwable); + return null; } private static void timeUpdate() { - List reminderTimes = SkyblockerConfigManager.get().general.eventNotifications.reminderTimes; - if (reminderTimes.isEmpty()) return; long newTime = System.currentTimeMillis() / 1000; for (Map.Entry> entry : events.entrySet()) { @@ -115,6 +124,8 @@ private static void timeUpdate() { if (skyblockEvent == null) continue; } String eventName = entry.getKey(); + List reminderTimes = SkyblockerConfigManager.get().eventNotifications.eventsReminderTimes.getOrDefault(eventName, DEFAULT_REMINDERS); + if (reminderTimes.isEmpty()) return; for (Integer reminderTime : reminderTimes) { if (currentTime + reminderTime < skyblockEvent.start() && newTime + reminderTime >= skyblockEvent.start()) { From a781ad5c936f4307f70b191831701247976656f5 Mon Sep 17 00:00:00 2001 From: vicisacat Date: Wed, 24 Apr 2024 16:20:01 +0200 Subject: [PATCH 07/20] fixes and things --- .../config/categories/EventNotificationsCategory.java | 7 +++++-- .../skyblocker/skyblock/events/EventNotifications.java | 1 + .../skyblocker/skyblock/itemlist/UpcomingEventsTab.java | 2 +- src/main/java/de/hysky/skyblocker/utils/Utils.java | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java index 02be92a5ea..5b33f7cf52 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java @@ -19,8 +19,6 @@ public static ConfigCategory create(SkyblockerConfig config) { return ConfigCategory.createBuilder() .name(Text.literal("Event Notifications")) .groups(createGroups(config)) - .tooltip(Text.translatable("text.autoconfig.skyblocker.option.general.eventNotifications.@Tooltip[0]"), - Text.translatable("text.autoconfig.skyblocker.option.general.eventNotifications.@Tooltip[1]")) .build(); } @@ -33,6 +31,11 @@ private static List createGroups(SkyblockerConfig config) { .name(Text.literal(entry.getKey())) .binding(EventNotifications.DEFAULT_REMINDERS, entry::getValue, entry::setValue) .controller(option -> () -> new DurationController(option)) // yea + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.general.eventNotifications.@Tooltip[0]"), + Text.empty(), + Text.translatable("text.autoconfig.skyblocker.option.general.eventNotifications.@Tooltip[1]"), + Text.empty(), + Text.translatable("text.autoconfig.skyblocker.option.general.eventNotifications.@Tooltip[2]", entry.getKey()))) .initial(60) .collapsed(true) .build() diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java index 0d2d4d4d33..f7f82afbf9 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java @@ -139,6 +139,7 @@ private static void timeUpdate() { new EventToast(skyblockEvent.start(), eventName, eventIcons.getOrDefault(eventName, new ItemStack(Items.PAPER))) ); } + break; } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java index 134c5d4d3d..3459c47de5 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java @@ -67,7 +67,7 @@ protected void renderWidget(DrawContext context, int mouseX, int mouseY, float d hovered = null; for (EventRenderer eventRenderer : events) { eventRenderer.render(context, x + 1, eventsY, mouseX, mouseY); - if (eventRenderer.isMouseOver(mouseX, mouseY, x+1, eventsY)) hovered = eventRenderer; + if (isMouseOver(mouseX, mouseY) && eventRenderer.isMouseOver(mouseX, mouseY, x+1, eventsY)) hovered = eventRenderer; eventsY += eventRenderer.getHeight(); } diff --git a/src/main/java/de/hysky/skyblocker/utils/Utils.java b/src/main/java/de/hysky/skyblocker/utils/Utils.java index 8316bb9ca6..fa9292ca88 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Utils.java +++ b/src/main/java/de/hysky/skyblocker/utils/Utils.java @@ -359,7 +359,7 @@ private static void updateScoreboard(MinecraftClient client) { public static Text getDurationText(int timeInSeconds) { int seconds = timeInSeconds % 60; int minutes = (timeInSeconds/60) % 60; - int hours = (timeInSeconds/3600) % 24; + int hours = (timeInSeconds/3600); MutableText time = Text.empty(); if (hours > 0) { From a2c9ef1192f903c4aaf3e048da621e53b600ec5e Mon Sep 17 00:00:00 2001 From: vicisacat Date: Wed, 24 Apr 2024 16:48:14 +0200 Subject: [PATCH 08/20] localization --- .../skyblocker/skyblock/itemlist/UpcomingEventsTab.java | 8 ++++---- src/main/resources/assets/skyblocker/lang/en_us.json | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java index 3459c47de5..8d459242a5 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java @@ -103,12 +103,12 @@ public void render(DrawContext context, int x, int y, int mouseX, int mouseY) { TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; context.drawText(textRenderer, Text.literal(eventName).fillStyle(Style.EMPTY.withUnderline(isMouseOver(mouseX, mouseY, x, y))), x, y, -1, true); if (events.isEmpty()) { - context.drawText(textRenderer, " No more this year!", x, y + textRenderer.fontHeight, Colors.GRAY, false); + context.drawText(textRenderer, Text.literal(" ").append(Text.translatable("skyblocker.events.tab.noMore")), x, y + textRenderer.fontHeight, Colors.GRAY, false); } else if (events.peekFirst().start() > time) { - MutableText formatted = Text.literal(" Starts in ").append(Utils.getDurationText((int) (events.peekFirst().start() - time))).formatted(Formatting.YELLOW); + MutableText formatted = Text.literal(" ").append(Text.translatable("skyblocker.events.tab.startsIn", Utils.getDurationText((int) (events.peekFirst().start() - time)))).formatted(Formatting.YELLOW); context.drawText(textRenderer, formatted, x, y + textRenderer.fontHeight, -1, true); } else { - MutableText formatted = Text.literal(" Ends in ").append(Utils.getDurationText((int) (events.peekFirst().start() + events.peekFirst().duration() - time))).formatted(Formatting.GREEN); + MutableText formatted = Text.literal(" ").append(Text.translatable( "skyblocker.events.tab.endsIn", Utils.getDurationText((int) (events.peekFirst().start() + events.peekFirst().duration() - time)))).formatted(Formatting.GREEN); context.drawText(textRenderer, formatted, x, y + textRenderer.fontHeight, -1, true); } @@ -130,7 +130,7 @@ public List getTooltip() { } //noinspection DataFlowIssue if (events.peekFirst().warpCommand() != null) { - components.add(TooltipComponent.of(Text.literal("Click to warp!").formatted(Formatting.ITALIC).asOrderedText())); + components.add(TooltipComponent.of(Text.translatable("skyblocker.events.tab.clickToWarp").formatted(Formatting.ITALIC).asOrderedText())); } return components; diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 8b549ac7a7..f19b41b5fa 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -762,6 +762,10 @@ "skyblocker.itemProtection.unableToProtect": "§cUnable to protect this item :( (Are you in skyblock?, are you holding an item?)", "skyblocker.events.startsSoon": "%s starts soon!", + "skyblocker.events.tab.clickToWarp": "Click to warp!", + "skyblocker.events.tab.noMore": "No more this year!", + "skyblocker.events.tab.startsIn": "Starts in %s", + "skyblocker.events.tab.endsIn": "Ends in %s", "skyblocker.tips.enabled": "§aEnabled Tips.", "skyblocker.tips.disabled": "§cDisabled Tips.", From 0e55c9e00b406e8cec007e551e4661d80f6c1b2e Mon Sep 17 00:00:00 2001 From: vicisacat Date: Wed, 24 Apr 2024 18:28:11 +0200 Subject: [PATCH 09/20] GOAT HORN YEA BABY --- .../EventNotificationsCategory.java | 28 +++++++++++++++---- .../skyblock/events/EventNotifications.java | 9 ++++-- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java index 5b33f7cf52..af30f502ed 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java @@ -1,12 +1,12 @@ package de.hysky.skyblocker.config.categories; +import de.hysky.skyblocker.config.ConfigUtils; import de.hysky.skyblocker.config.SkyblockerConfig; import de.hysky.skyblocker.skyblock.events.EventNotifications; import de.hysky.skyblocker.utils.config.DurationController; -import dev.isxander.yacl3.api.ConfigCategory; -import dev.isxander.yacl3.api.ListOption; -import dev.isxander.yacl3.api.OptionDescription; -import dev.isxander.yacl3.api.OptionGroup; +import dev.isxander.yacl3.api.*; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.sound.PositionedSoundInstance; import net.minecraft.text.Text; import java.util.ArrayList; @@ -15,9 +15,27 @@ public class EventNotificationsCategory { - public static ConfigCategory create(SkyblockerConfig config) { + private static boolean shouldPlaySound = false; + + public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) { + shouldPlaySound = false; return ConfigCategory.createBuilder() .name(Text.literal("Event Notifications")) + .option(Option.createBuilder() + .binding(defaults.eventNotifications.reminderSound, + () -> config.eventNotifications.reminderSound, + sound -> config.eventNotifications.reminderSound = sound) + .controller(ConfigUtils::createEnumCyclingListController) + .name(Text.literal("Notification Sound")) + .listener((soundOption, sound) -> { + if (!shouldPlaySound) { + shouldPlaySound = true; + return; + } + if (sound.getSoundEvent() != null) + MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(sound.getSoundEvent(), 1f, 1f)); + }) + .build()) .groups(createGroups(config)) .build(); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java index f7f82afbf9..c62fed2178 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java @@ -14,8 +14,10 @@ import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.sound.PositionedSoundInstance; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; +import net.minecraft.sound.SoundEvent; import org.apache.commons.lang3.builder.ToStringBuilder; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -129,16 +131,19 @@ private static void timeUpdate() { for (Integer reminderTime : reminderTimes) { if (currentTime + reminderTime < skyblockEvent.start() && newTime + reminderTime >= skyblockEvent.start()) { + MinecraftClient instance = MinecraftClient.getInstance(); if (eventName.equals("Jacob's Farming Contest")) { - MinecraftClient.getInstance().getToastManager().add( + instance.getToastManager().add( new JacobEventToast(skyblockEvent.start(), eventName, skyblockEvent.extras()) ); } else { - MinecraftClient.getInstance().getToastManager().add( + instance.getToastManager().add( new EventToast(skyblockEvent.start(), eventName, eventIcons.getOrDefault(eventName, new ItemStack(Items.PAPER))) ); } + SoundEvent soundEvent = SkyblockerConfigManager.get().eventNotifications.reminderSound.getSoundEvent(); + if (soundEvent != null) instance.getSoundManager().play(PositionedSoundInstance.master(soundEvent, 1f, 1f)); break; } } From abd94904c0959b1cf2621fca7e4d9f5415e9407f Mon Sep 17 00:00:00 2001 From: vicisacat Date: Wed, 24 Apr 2024 18:57:00 +0200 Subject: [PATCH 10/20] reopen previous tab --- .../skyblock/itemlist/ItemListWidget.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemListWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemListWidget.java index 4a258b9ed3..a618f4df29 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemListWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemListWidget.java @@ -30,6 +30,8 @@ public class ItemListWidget extends RecipeBookWidget { private final List> tabs = new ArrayList<>(2); private ItemListTab itemListTab; + private static int currentTab = 0; + public ItemListWidget() { super(); } @@ -46,19 +48,24 @@ public void initialize(int parentWidth, int parentHeight, MinecraftClient client // Init all the tabs, content and the tab button on the left tabs.clear(); - itemListTab = new ItemListTab(x + 9, y + 9, this.client, searchField); - SideTabButtonWidget itemListTabButton = new SideTabButtonWidget(x - 30, y + 3, true, new ItemStack(Items.CRAFTING_TABLE)); + // Item List + itemListTab = new ItemListTab(x + 9, y + 9, this.client, searchField); + SideTabButtonWidget itemListTabButton = new SideTabButtonWidget(x - 30, y + 3, currentTab == 0, new ItemStack(Items.CRAFTING_TABLE)); itemListTabButton.setTooltip(Tooltip.of(Text.literal("Item List"))); + if (currentTab == 0) currentTabContent = itemListTab; tabs.add(new ObjectObjectImmutablePair<>( itemListTabButton, - this.currentTabContent = this.itemListTab)); + this.itemListTab)); - SideTabButtonWidget eventsTabButtonWidget = new SideTabButtonWidget(x - 30, y + 3 + 27, false, new ItemStack(Items.CLOCK)); + // Upcoming Events + UpcomingEventsTab upcomingEventsTab = new UpcomingEventsTab(x + 9, y + 9, this.client); + SideTabButtonWidget eventsTabButtonWidget = new SideTabButtonWidget(x - 30, y + 3 + 27, currentTab == 1, new ItemStack(Items.CLOCK)); eventsTabButtonWidget.setTooltip(Tooltip.of(Text.literal("Upcoming Events"))); + if (currentTab == 1) currentTabContent = upcomingEventsTab; tabs.add(new ObjectObjectImmutablePair<>( eventsTabButtonWidget, - new UpcomingEventsTab(x + 9, y + 9, this.client) + upcomingEventsTab )); } @@ -104,6 +111,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { } tab.first().setToggled(true); currentTabContent = tab.right(); + currentTab = tabs.indexOf(tab); return true; } } From db271cbea20bbf43892d33b3adc88819ba56a469 Mon Sep 17 00:00:00 2001 From: viciscat <51047087+viciscat@users.noreply.github.com> Date: Sun, 5 May 2024 19:13:22 +0200 Subject: [PATCH 11/20] little touches --- .../EventNotificationsCategory.java | 10 +++-- .../skyblock/events/EventNotifications.java | 44 +++++++++++-------- .../skyblock/events/EventToast.java | 25 ++++++++--- .../skyblock/events/JacobEventToast.java | 7 +-- .../skyblock/itemlist/UpcomingEventsTab.java | 2 +- 5 files changed, 54 insertions(+), 34 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java index af30f502ed..709c994e2e 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; public class EventNotificationsCategory { @@ -20,7 +21,7 @@ public class EventNotificationsCategory { public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) { shouldPlaySound = false; return ConfigCategory.createBuilder() - .name(Text.literal("Event Notifications")) + .name(Text.translatable("text.autoconfig.skyblocker.option.eventNotifications")) .option(Option.createBuilder() .binding(defaults.eventNotifications.reminderSound, () -> config.eventNotifications.reminderSound, @@ -44,16 +45,17 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig private static List createGroups(SkyblockerConfig config) { Map> eventsReminderTimes = config.eventNotifications.eventsReminderTimes; List groups = new ArrayList<>(eventsReminderTimes.size()); + if (eventsReminderTimes.isEmpty()) return List.of(OptionGroup.createBuilder().option(LabelOption.create(Text.translatable("text.autoconfig.skyblocker.option.eventNotifications.monologue"))).build()); for (Map.Entry> entry : eventsReminderTimes.entrySet()) { groups.add(ListOption.createBuilder() .name(Text.literal(entry.getKey())) .binding(EventNotifications.DEFAULT_REMINDERS, entry::getValue, entry::setValue) .controller(option -> () -> new DurationController(option)) // yea - .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.general.eventNotifications.@Tooltip[0]"), + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.eventNotifications.@Tooltip[0]"), Text.empty(), - Text.translatable("text.autoconfig.skyblocker.option.general.eventNotifications.@Tooltip[1]"), + Text.translatable("text.autoconfig.skyblocker.option.eventNotifications.@Tooltip[1]"), Text.empty(), - Text.translatable("text.autoconfig.skyblocker.option.general.eventNotifications.@Tooltip[2]", entry.getKey()))) + Text.translatable("text.autoconfig.skyblocker.option.eventNotifications.@Tooltip[2]", entry.getKey()))) .initial(60) .collapsed(true) .build() diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java index c62fed2178..662f6b12f0 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java @@ -3,6 +3,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import com.mojang.brigadier.arguments.BoolArgumentType; import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.logging.LogUtils; import de.hysky.skyblocker.SkyblockerMod; @@ -32,7 +33,7 @@ public class EventNotifications { public static final String JACOBS = "Jacob's Farming Contest"; - public static final List DEFAULT_REMINDERS = List.of(60, 60*5); + public static final List DEFAULT_REMINDERS = List.of(60, 60 * 5); public static final Map eventIcons = new Object2ObjectOpenHashMap<>(); @@ -56,18 +57,26 @@ public static void init() { SkyblockEvents.JOIN.register(EventNotifications::refreshEvents); ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register( ClientCommandManager.literal("skyblocker").then( - ClientCommandManager.literal("ye").then( - ClientCommandManager.argument("time", IntegerArgumentType.integer(6)).executes(context -> { - MinecraftClient.getInstance().getToastManager().add( - new EventToast(System.currentTimeMillis() / 1000 + context.getArgument("time", int.class), "Jacob's or something idk", new ItemStack(Items.PAPER)) - ); - return 0; - }) - ).executes(context -> { - MinecraftClient.getInstance().getToastManager().add( - new JacobEventToast(System.currentTimeMillis() / 1000 + 60, "Jacob's farming contest", new String[]{"Cactus","Cocoa Beans","Pumpkin"}) - ); - return 0;}) + ClientCommandManager.literal("debug").then( + ClientCommandManager.literal("toasts").then( + ClientCommandManager.argument("time", IntegerArgumentType.integer(0)) + .then(ClientCommandManager.argument("jacob", BoolArgumentType.bool()).executes(context -> { + long time = System.currentTimeMillis() / 1000 + context.getArgument("time", int.class); + if (context.getArgument("jacob", Boolean.class)) { + MinecraftClient.getInstance().getToastManager().add( + new JacobEventToast(time, "Jacob's farming contest", new String[]{"Cactus", "Cocoa Beans", "Pumpkin"}) + ); + } else { + MinecraftClient.getInstance().getToastManager().add( + new EventToast(time, "Jacob's or something idk", new ItemStack(Items.PAPER)) + ); + } + return 0; + } + ) + ) + ) + ) ) )); } @@ -112,7 +121,6 @@ private static Void itBorked(Throwable throwable) { } - private static void timeUpdate() { long newTime = System.currentTimeMillis() / 1000; @@ -136,14 +144,14 @@ private static void timeUpdate() { instance.getToastManager().add( new JacobEventToast(skyblockEvent.start(), eventName, skyblockEvent.extras()) ); - } - else { + } else { instance.getToastManager().add( new EventToast(skyblockEvent.start(), eventName, eventIcons.getOrDefault(eventName, new ItemStack(Items.PAPER))) ); } SoundEvent soundEvent = SkyblockerConfigManager.get().eventNotifications.reminderSound.getSoundEvent(); - if (soundEvent != null) instance.getSoundManager().play(PositionedSoundInstance.master(soundEvent, 1f, 1f)); + if (soundEvent != null) + instance.getSoundManager().play(PositionedSoundInstance.master(soundEvent, 1f, 1f)); break; } } @@ -154,7 +162,7 @@ private static void timeUpdate() { public record SkyblockEvent(long start, int duration, String[] extras, @Nullable String warpCommand) { public static SkyblockEvent of(JsonObject jsonObject) { String location = jsonObject.get("location").getAsString(); - location = location.isBlank() ? null: location; + location = location.isBlank() ? null : location; return new SkyblockEvent(jsonObject.get("timestamp").getAsLong(), jsonObject.get("duration").getAsInt(), jsonObject.get("extras").getAsJsonArray().asList().stream().map(JsonElement::getAsString).toArray(String[]::new), diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/EventToast.java b/src/main/java/de/hysky/skyblocker/skyblock/events/EventToast.java index bd44c0a553..567c800a99 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/EventToast.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/EventToast.java @@ -23,23 +23,32 @@ public class EventToast implements Toast { private final long eventStartTime; protected final List message; + protected final List messageNow; protected final int messageWidth; + protected final int messageNowWidth; protected final ItemStack icon; + protected boolean started; + public EventToast(long eventStartTime, String name, ItemStack icon) { this.eventStartTime = eventStartTime; MutableText formatted = Text.translatable("skyblocker.events.startsSoon", Text.literal(name).formatted(Formatting.YELLOW)).formatted(Formatting.WHITE); TextRenderer renderer = MinecraftClient.getInstance().textRenderer; message = renderer.wrapLines(formatted, 150); messageWidth = message.stream().mapToInt(renderer::getWidth).max().orElse(150); + + MutableText formattedNow = Text.translatable("skyblocker.events.startsNow", Text.literal(name).formatted(Formatting.YELLOW)).formatted(Formatting.WHITE); + messageNow = renderer.wrapLines(formattedNow, 150); + messageNowWidth = messageNow.stream().mapToInt(renderer::getWidth).max().orElse(150); this.icon = icon; + this.started = eventStartTime - System.currentTimeMillis() / 1000 < 0; } @Override public Visibility draw(DrawContext context, ToastManager manager, long startTime) { context.drawGuiTexture(TEXTURE, 0, 0, getWidth(), getHeight()); - int y = 7; + int y = (getHeight() - getInnerContentsHeight())/2; y = 2 + drawMessage(context, 30, y, Colors.WHITE); drawTimer(context, 30, y); @@ -49,7 +58,7 @@ public Visibility draw(DrawContext context, ToastManager manager, long startTime protected int drawMessage(DrawContext context, int x, int y, int color) { TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; - for (OrderedText orderedText : message) { + for (OrderedText orderedText : started ? messageNow: message) { context.drawText(textRenderer, orderedText, x, y, color, false); y += textRenderer.fontHeight; } @@ -59,8 +68,10 @@ protected int drawMessage(DrawContext context, int x, int y, int color) { protected void drawTimer(DrawContext context, int x, int y) { long currentTime = System.currentTimeMillis() / 1000; int timeTillEvent = (int) (eventStartTime - currentTime); + started = timeTillEvent < 0; + if (started) return; - Text time = timeTillEvent < 0 ? Text.literal("Starts now!"): Utils.getDurationText(timeTillEvent); + Text time = Utils.getDurationText(timeTillEvent); TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; context.drawText(textRenderer, time, x, y, Colors.LIGHT_YELLOW, false); @@ -68,11 +79,15 @@ protected void drawTimer(DrawContext context, int x, int y) { @Override public int getWidth() { - return messageWidth + 30 + 6; + return (started ? messageNowWidth: messageWidth) + 30 + 6; + } + + protected int getInnerContentsHeight() { + return message.size() * 9 + (started ? 0 : 9); } @Override public int getHeight() { - return 12 + 2 + (message.size()+1)*9; + return Math.max(getInnerContentsHeight() + 12 + 2, 32); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java b/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java index a7a5f9c0c3..58e571205e 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java @@ -39,7 +39,7 @@ public JacobEventToast(long eventStartTime, String name, String[] crops) { public Visibility draw(DrawContext context, ToastManager manager, long startTime) { context.drawGuiTexture(TEXTURE, 0, 0, getWidth(), getHeight()); - int y = 7; + int y = (getHeight() - getInnerContentsHeight())/2; TextRenderer textRenderer = manager.getClient().textRenderer; if (startTime < 3_000){ int k = MathHelper.floor(MathHelper.clamp((3_000 - startTime) / 200.0f, 0.0f, 1.0f) * 255.0f) << 24 | 0x4000000; @@ -62,9 +62,4 @@ public Visibility draw(DrawContext context, ToastManager manager, long startTime context.drawItemWithoutEntity(icon, 8, getHeight()/2 - 8); return startTime > 5_000 ? Visibility.HIDE: Visibility.SHOW; } - - @Override - public int getHeight() { - return Math.max(super.getHeight(), 32); - } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java index 8d459242a5..ce48018dce 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java @@ -1,6 +1,6 @@ package de.hysky.skyblocker.skyblock.itemlist; -import de.hysky.skyblocker.mixin.accessor.DrawContextInvoker; +import de.hysky.skyblocker.mixins.accessors.DrawContextInvoker; import de.hysky.skyblocker.skyblock.events.EventNotifications; import de.hysky.skyblocker.skyblock.events.JacobEventToast; import de.hysky.skyblocker.utils.Utils; From 8fdf8ca61535902b8644e39f846b9edb56e6865f Mon Sep 17 00:00:00 2001 From: viciscat <51047087+viciscat@users.noreply.github.com> Date: Mon, 6 May 2024 19:39:01 +0200 Subject: [PATCH 12/20] one more localization --- .../config/categories/EventNotificationsCategory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java index 709c994e2e..db94eb8a62 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java @@ -27,7 +27,7 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig () -> config.eventNotifications.reminderSound, sound -> config.eventNotifications.reminderSound = sound) .controller(ConfigUtils::createEnumCyclingListController) - .name(Text.literal("Notification Sound")) + .name(Text.translatable("text.autoconfig.skyblocker.option.eventNotifications.notificationSound")) .listener((soundOption, sound) -> { if (!shouldPlaySound) { shouldPlaySound = true; From c4688d4f5f43432114a9e3cc635140c6b6f565bb Mon Sep 17 00:00:00 2001 From: viciscat <51047087+viciscat@users.noreply.github.com> Date: Mon, 6 May 2024 19:54:03 +0200 Subject: [PATCH 13/20] clean or something idk --- .../skyblocker/config/categories/EventNotificationsCategory.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java index db94eb8a62..b6272403c9 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java @@ -12,7 +12,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Optional; public class EventNotificationsCategory { From 1ab1b64847378254f0ea5192c3c5939a9f65de9c Mon Sep 17 00:00:00 2001 From: viciscat <51047087+viciscat@users.noreply.github.com> Date: Fri, 10 May 2024 01:08:39 +0200 Subject: [PATCH 14/20] the config commit tm --- .../skyblocker/config/SkyblockerConfig.java | 3 ++ .../config/SkyblockerConfigManager.java | 3 +- .../EventNotificationsCategory.java | 15 ++++---- .../configs/EventNotificationsConfig.java | 35 +++++++++++++++++++ .../skyblock/events/JacobEventToast.java | 12 ++++++- .../assets/skyblocker/lang/en_us.json | 8 +++++ 6 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/config/configs/EventNotificationsConfig.java diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index 9c4953821b..a1f4fa2c12 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -45,4 +45,7 @@ public class SkyblockerConfig { @SerialEntry public MiscConfig misc = new MiscConfig(); + + @SerialEntry + public EventNotificationsConfig eventNotifications = new EventNotificationsConfig(); } diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java index dd406b8a0f..25da464e43 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java @@ -83,7 +83,8 @@ public static Screen createGUI(Screen parent) { .category(SlayersCategory.create(defaults, config)) .category(ChatCategory.create(defaults, config)) .category(QuickNavigationCategory.create(defaults, config)) - .category(MiscCategory.create(defaults, config))).generateScreen(parent); + .category(MiscCategory.create(defaults, config)) + .category(EventNotificationsCategory.create(defaults, config))).generateScreen(parent); } /** diff --git a/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java index b6272403c9..e353b5d1db 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java @@ -2,6 +2,7 @@ import de.hysky.skyblocker.config.ConfigUtils; import de.hysky.skyblocker.config.SkyblockerConfig; +import de.hysky.skyblocker.config.configs.EventNotificationsConfig; import de.hysky.skyblocker.skyblock.events.EventNotifications; import de.hysky.skyblocker.utils.config.DurationController; import dev.isxander.yacl3.api.*; @@ -20,13 +21,13 @@ public class EventNotificationsCategory { public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) { shouldPlaySound = false; return ConfigCategory.createBuilder() - .name(Text.translatable("text.autoconfig.skyblocker.option.eventNotifications")) - .option(Option.createBuilder() + .name(Text.translatable("skyblocker.config.eventNotifications")) + .option(Option.createBuilder() .binding(defaults.eventNotifications.reminderSound, () -> config.eventNotifications.reminderSound, sound -> config.eventNotifications.reminderSound = sound) .controller(ConfigUtils::createEnumCyclingListController) - .name(Text.translatable("text.autoconfig.skyblocker.option.eventNotifications.notificationSound")) + .name(Text.translatable("skyblocker.config.eventNotifications.notificationSound")) .listener((soundOption, sound) -> { if (!shouldPlaySound) { shouldPlaySound = true; @@ -44,17 +45,17 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig private static List createGroups(SkyblockerConfig config) { Map> eventsReminderTimes = config.eventNotifications.eventsReminderTimes; List groups = new ArrayList<>(eventsReminderTimes.size()); - if (eventsReminderTimes.isEmpty()) return List.of(OptionGroup.createBuilder().option(LabelOption.create(Text.translatable("text.autoconfig.skyblocker.option.eventNotifications.monologue"))).build()); + if (eventsReminderTimes.isEmpty()) return List.of(OptionGroup.createBuilder().option(LabelOption.create(Text.translatable("skyblocker.config.eventNotifications.monologue"))).build()); for (Map.Entry> entry : eventsReminderTimes.entrySet()) { groups.add(ListOption.createBuilder() .name(Text.literal(entry.getKey())) .binding(EventNotifications.DEFAULT_REMINDERS, entry::getValue, entry::setValue) .controller(option -> () -> new DurationController(option)) // yea - .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.eventNotifications.@Tooltip[0]"), + .description(OptionDescription.of(Text.translatable("skyblocker.config.eventNotifications.@Tooltip[0]"), Text.empty(), - Text.translatable("text.autoconfig.skyblocker.option.eventNotifications.@Tooltip[1]"), + Text.translatable("skyblocker.config.eventNotifications.@Tooltip[1]"), Text.empty(), - Text.translatable("text.autoconfig.skyblocker.option.eventNotifications.@Tooltip[2]", entry.getKey()))) + Text.translatable("skyblocker.config.eventNotifications.@Tooltip[2]", entry.getKey()))) .initial(60) .collapsed(true) .build() diff --git a/src/main/java/de/hysky/skyblocker/config/configs/EventNotificationsConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/EventNotificationsConfig.java new file mode 100644 index 0000000000..cc51e536a7 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/config/configs/EventNotificationsConfig.java @@ -0,0 +1,35 @@ +package de.hysky.skyblocker.config.configs; + +import dev.isxander.yacl3.config.v2.api.SerialEntry; +import net.minecraft.sound.SoundEvent; +import net.minecraft.sound.SoundEvents; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EventNotificationsConfig { + + @SerialEntry + public Sound reminderSound = Sound.PLING; + + @SerialEntry + public Map> eventsReminderTimes = new HashMap<>(); + + public enum Sound { + NONE(null), + BELL(SoundEvents.BLOCK_BELL_USE), + DING(SoundEvents.ENTITY_ARROW_HIT_PLAYER), + PLING(SoundEvents.BLOCK_NOTE_BLOCK_PLING.value()), + GOAT(SoundEvents.GOAT_HORN_SOUNDS.getFirst().value()); + + public SoundEvent getSoundEvent() { + return soundEvent; + } + + final SoundEvent soundEvent; + Sound(SoundEvent soundEvent) { + this.soundEvent = soundEvent; + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java b/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java index 58e571205e..18d9a7b211 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java @@ -1,5 +1,8 @@ package de.hysky.skyblocker.skyblock.events; +import com.mojang.blaze3d.systems.RenderSystem; +import de.hysky.skyblocker.utils.Utils; +import de.hysky.skyblocker.utils.render.RenderHelper; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.toast.ToastManager; @@ -54,12 +57,19 @@ public Visibility draw(DrawContext context, ToastManager manager, long startTime for (int i = 0; i < crops.length; i++) { context.drawItem(cropItems.get(crops[i]), x + i * (16 + 8), 7); } - context.fill(30, 6, 30 + messageWidth, 22, 400, 0x212121 | k); + // IDK how to make the items transparent, so I just redraw the texture on top + context.getMatrices().push(); + context.getMatrices().translate(0, 0, 400f); + RenderHelper.renderNineSliceColored(context, TEXTURE, 0, 0, getWidth(), getHeight(), 1f, 1f, 1f, (k >> 24)/ 255f); + context.getMatrices().pop(); y += textRenderer.fontHeight * message.size(); } + context.getMatrices().push(); + context.getMatrices().translate(0, 0, 400f); drawTimer(context, 30, y); context.drawItemWithoutEntity(icon, 8, getHeight()/2 - 8); + context.getMatrices().pop(); return startTime > 5_000 ? Visibility.HIDE: Visibility.SHOW; } } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index f19b41b5fa..52f72e371b 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -623,6 +623,13 @@ "skyblocker.config.uiAndVisuals.waypoints.waypointType.@Tooltip": "Waypoint: Displays a highlight and a beacon beam.\n\nOutlined Waypoint: Displays both a waypoint and an outline.\n\nHighlight: Only displays a highlight.\n\nOutlined Highlight: Displays both a highlight and an outline.\n\nOutline: Only displays an outline.", "skyblocker.config.uiAndVisuals.waypoints.waypointType.generalNote": "\n\n\nThis option does not apply to all waypoints. Some waypoints such as secret waypoints have their own waypoint type option.", + "skyblocker.config.eventNotifications": "Event Notifications", + "skyblocker.config.eventNotifications.notificationSound": "Notification Sound", + "skyblocker.config.eventNotifications.monologue": "can you pls log onto skyblock rq pls? that would be cool cuz like if you are seeing dis then it means that ur config either got cleared or that this is ur first time using the mod if so then thanks for choosing it and hopefully you enjoy it! so yea this is where you will be able to set reminders for all events in skyblock they will be added as you encounter so you first need to log onto skyblock so yea hope you enjoy the mod and all that", + "skyblocker.config.eventNotifications.@Tooltip[0]": "Configure how much time before an event you will be reminded with a notification toast! For example if you set '5m' and '30s' in the list, you will receive a notification 5 minutes before and another 30 seconds before an event starts.", + "skyblocker.config.eventNotifications.@Tooltip[1]": "The order doesn't matter. If you want to disable notifications, just empty the list.", + "skyblocker.config.eventNotifications.@Tooltip[2]": "This list will modify the '%s' event", + "skyblocker.itemTooltip.noData": "\u00a7cNo Data", "skyblocker.itemTooltip.nullMessage": "\u00a7cItem price information on tooltip will renew in max 60 seconds. If not, check latest.log", @@ -762,6 +769,7 @@ "skyblocker.itemProtection.unableToProtect": "§cUnable to protect this item :( (Are you in skyblock?, are you holding an item?)", "skyblocker.events.startsSoon": "%s starts soon!", + "skyblocker.events.startsNow": "%s starts now!", "skyblocker.events.tab.clickToWarp": "Click to warp!", "skyblocker.events.tab.noMore": "No more this year!", "skyblocker.events.tab.startsIn": "Starts in %s", From 35ec69b7d795b2229861389e4c4a08067299502c Mon Sep 17 00:00:00 2001 From: viciscat <51047087+viciscat@users.noreply.github.com> Date: Sat, 11 May 2024 14:39:49 +0200 Subject: [PATCH 15/20] hopefully do requested changes correctly --- .../skyblocker/config/SkyblockerConfig.java | 4 +- .../config/SkyblockerConfigManager.java | 4 +- .../skyblock/events/EventNotifications.java | 11 ------ .../skyblock/events/JacobEventToast.java | 39 +++++++++++-------- .../tabhud/widget/JacobsContestWidget.java | 2 +- .../assets/skyblocker/lang/en_us.json | 30 +++++++------- 6 files changed, 43 insertions(+), 47 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index a1f4fa2c12..c92465999f 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -44,8 +44,8 @@ public class SkyblockerConfig { public QuickNavigationConfig quickNav = new QuickNavigationConfig(); @SerialEntry - public MiscConfig misc = new MiscConfig(); + public EventNotificationsConfig eventNotifications = new EventNotificationsConfig(); @SerialEntry - public EventNotificationsConfig eventNotifications = new EventNotificationsConfig(); + public MiscConfig misc = new MiscConfig(); } diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java index 25da464e43..f519473cd8 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java @@ -83,8 +83,8 @@ public static Screen createGUI(Screen parent) { .category(SlayersCategory.create(defaults, config)) .category(ChatCategory.create(defaults, config)) .category(QuickNavigationCategory.create(defaults, config)) - .category(MiscCategory.create(defaults, config)) - .category(EventNotificationsCategory.create(defaults, config))).generateScreen(parent); + .category(EventNotificationsCategory.create(defaults, config)) + .category(MiscCategory.create(defaults, config))).generateScreen(parent); } /** diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java index 662f6b12f0..537ee360c1 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java @@ -19,7 +19,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.sound.SoundEvent; -import org.apache.commons.lang3.builder.ToStringBuilder; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -168,15 +167,5 @@ public static SkyblockEvent of(JsonObject jsonObject) { jsonObject.get("extras").getAsJsonArray().asList().stream().map(JsonElement::getAsString).toArray(String[]::new), location); } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("start", start) - .append("duration", duration) - .append("extras", extras) - .append("warpCommand", warpCommand) - .toString(); - } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java b/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java index 18d9a7b211..ca0f08c458 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java @@ -1,11 +1,13 @@ package de.hysky.skyblocker.skyblock.events; import com.mojang.blaze3d.systems.RenderSystem; +import de.hysky.skyblocker.skyblock.tabhud.widget.JacobsContestWidget; import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.render.RenderHelper; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.toast.ToastManager; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.util.Colors; @@ -14,10 +16,12 @@ import java.util.HashMap; import java.util.Map; -public class JacobEventToast extends EventToast{ +public class JacobEventToast extends EventToast { private final String[] crops; + private static final ItemStack DEFAULT_ITEM = new ItemStack(Items.IRON_HOE); + public static final Map cropItems = new HashMap<>(); static { @@ -42,34 +46,35 @@ public JacobEventToast(long eventStartTime, String name, String[] crops) { public Visibility draw(DrawContext context, ToastManager manager, long startTime) { context.drawGuiTexture(TEXTURE, 0, 0, getWidth(), getHeight()); - int y = (getHeight() - getInnerContentsHeight())/2; + int y = (getHeight() - getInnerContentsHeight()) / 2; TextRenderer textRenderer = manager.getClient().textRenderer; - if (startTime < 3_000){ - int k = MathHelper.floor(MathHelper.clamp((3_000 - startTime) / 200.0f, 0.0f, 1.0f) * 255.0f) << 24 | 0x4000000; + MatrixStack matrices = context.getMatrices(); + if (startTime < 3_000) { + int k = MathHelper.floor(Math.clamp((3_000 - startTime) / 200.0f, 0.0f, 1.0f) * 255.0f) << 24 | 0x4000000; y = 2 + drawMessage(context, 30, y, 0xFFFFFF | k); - } else { - int k = (~MathHelper.floor(MathHelper.clamp((startTime - 3_000) / 200.0f, 0.0f, 1.0f) * 255.0f)) << 24 | 0x4000000; + } else { + int k = (~MathHelper.floor(Math.clamp((startTime - 3_000) / 200.0f, 0.0f, 1.0f) * 255.0f)) << 24 | 0x4000000; String s = "Crops:"; int x = 30 + textRenderer.getWidth(s) + 4; - context.drawText(textRenderer, s, 30, 7 + (16 - textRenderer.fontHeight)/2, Colors.WHITE, false); + context.drawText(textRenderer, s, 30, 7 + (16 - textRenderer.fontHeight) / 2, Colors.WHITE, false); for (int i = 0; i < crops.length; i++) { - context.drawItem(cropItems.get(crops[i]), x + i * (16 + 8), 7); + context.drawItem(JacobsContestWidget.FARM_DATA.getOrDefault(crops[i], DEFAULT_ITEM), x + i * (16 + 8), 7); } // IDK how to make the items transparent, so I just redraw the texture on top - context.getMatrices().push(); - context.getMatrices().translate(0, 0, 400f); - RenderHelper.renderNineSliceColored(context, TEXTURE, 0, 0, getWidth(), getHeight(), 1f, 1f, 1f, (k >> 24)/ 255f); - context.getMatrices().pop(); + matrices.push(); + matrices.translate(0, 0, 400f); + RenderHelper.renderNineSliceColored(context, TEXTURE, 0, 0, getWidth(), getHeight(), 1f, 1f, 1f, (k >> 24) / 255f); + matrices.pop(); y += textRenderer.fontHeight * message.size(); } - context.getMatrices().push(); - context.getMatrices().translate(0, 0, 400f); + matrices.push(); + matrices.translate(0, 0, 400f); drawTimer(context, 30, y); - context.drawItemWithoutEntity(icon, 8, getHeight()/2 - 8); - context.getMatrices().pop(); - return startTime > 5_000 ? Visibility.HIDE: Visibility.SHOW; + context.drawItemWithoutEntity(icon, 8, getHeight() / 2 - 8); + matrices.pop(); + return startTime > 5_000 ? Visibility.HIDE : Visibility.SHOW; } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/JacobsContestWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/JacobsContestWidget.java index 24dcc229d2..c28c8679a7 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/JacobsContestWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/JacobsContestWidget.java @@ -26,7 +26,7 @@ public class JacobsContestWidget extends Widget { //TODO Properly match the contest placement and display it private static final Pattern CROP_PATTERN = Pattern.compile("(?[☘○]) (?[A-Za-z ]+).*"); - private static final Map FARM_DATA = Map.ofEntries( + public static final Map FARM_DATA = Map.ofEntries( entry("Wheat", new ItemStack(Items.WHEAT)), entry("Sugar Cane", new ItemStack(Items.SUGAR_CANE)), entry("Carrot", new ItemStack(Items.CARROT)), diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 52f72e371b..9361c941dd 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -396,6 +396,14 @@ "skyblocker.config.chat.filter.hideToggleSkyMall": "Hide Toggle Sky Mall Messages", "skyblocker.config.chat.filter.hideToggleSkyMall.@Tooltip": "Hides those pesky messages telling you to disable the Sky Mall HOTM perk when you want it enabled!", + "skyblocker.config.eventNotifications": "Event Notifications", + + "skyblocker.config.eventNotifications.monologue": "can you pls log onto skyblock rq pls? that would be cool cuz like if you are seeing dis then it means that ur config either got cleared or that this is ur first time using the mod if so then thanks for choosing it and hopefully you enjoy it! so yea this is where you will be able to set reminders for all events in skyblock they will be added as you encounter so you first need to log onto skyblock so yea hope you enjoy the mod and all that", + "skyblocker.config.eventNotifications.notificationSound": "Notification Sound", + "skyblocker.config.eventNotifications.@Tooltip[0]": "Configure how much time before an event you will be reminded with a notification toast! For example if you set '5m' and '30s' in the list, you will receive a notification 5 minutes before and another 30 seconds before an event starts.", + "skyblocker.config.eventNotifications.@Tooltip[1]": "The order doesn't matter. If you want to disable notifications, just empty the list.", + "skyblocker.config.eventNotifications.@Tooltip[2]": "This list will modify the '%s' event", + "skyblocker.config.mining": "Mining", "skyblocker.config.mining.commissionWaypoints": "Commission Waypoints", @@ -623,13 +631,6 @@ "skyblocker.config.uiAndVisuals.waypoints.waypointType.@Tooltip": "Waypoint: Displays a highlight and a beacon beam.\n\nOutlined Waypoint: Displays both a waypoint and an outline.\n\nHighlight: Only displays a highlight.\n\nOutlined Highlight: Displays both a highlight and an outline.\n\nOutline: Only displays an outline.", "skyblocker.config.uiAndVisuals.waypoints.waypointType.generalNote": "\n\n\nThis option does not apply to all waypoints. Some waypoints such as secret waypoints have their own waypoint type option.", - "skyblocker.config.eventNotifications": "Event Notifications", - "skyblocker.config.eventNotifications.notificationSound": "Notification Sound", - "skyblocker.config.eventNotifications.monologue": "can you pls log onto skyblock rq pls? that would be cool cuz like if you are seeing dis then it means that ur config either got cleared or that this is ur first time using the mod if so then thanks for choosing it and hopefully you enjoy it! so yea this is where you will be able to set reminders for all events in skyblock they will be added as you encounter so you first need to log onto skyblock so yea hope you enjoy the mod and all that", - "skyblocker.config.eventNotifications.@Tooltip[0]": "Configure how much time before an event you will be reminded with a notification toast! For example if you set '5m' and '30s' in the list, you will receive a notification 5 minutes before and another 30 seconds before an event starts.", - "skyblocker.config.eventNotifications.@Tooltip[1]": "The order doesn't matter. If you want to disable notifications, just empty the list.", - "skyblocker.config.eventNotifications.@Tooltip[2]": "This list will modify the '%s' event", - "skyblocker.itemTooltip.noData": "\u00a7cNo Data", "skyblocker.itemTooltip.nullMessage": "\u00a7cItem price information on tooltip will renew in max 60 seconds. If not, check latest.log", @@ -704,6 +705,14 @@ "skyblocker.end.hud.protectorLocations.rightFront": "Right Front", "skyblocker.end.hud.protectorLocations.rightBack": "Right Back", + "skyblocker.events.startsNow": "%s starts now!", + "skyblocker.events.startsSoon": "%s starts soon!", + "skyblocker.events.tab.endsIn": "Ends in %s", + "skyblocker.events.tab.clickToWarp": "Click to warp!", + "skyblocker.events.tab.noMore": "No more this year!", + "skyblocker.events.tab.startsIn": "Starts in %s", + + "skyblocker.garden.hud.mouseLocked": "Mouse locked.", "skyblocker.fishing.reelNow": "Reel in now!", @@ -768,13 +777,6 @@ "skyblocker.itemProtection.noItemUuid": "§cYou must be holding an item that has a uuid in order to protect it!", "skyblocker.itemProtection.unableToProtect": "§cUnable to protect this item :( (Are you in skyblock?, are you holding an item?)", - "skyblocker.events.startsSoon": "%s starts soon!", - "skyblocker.events.startsNow": "%s starts now!", - "skyblocker.events.tab.clickToWarp": "Click to warp!", - "skyblocker.events.tab.noMore": "No more this year!", - "skyblocker.events.tab.startsIn": "Starts in %s", - "skyblocker.events.tab.endsIn": "Ends in %s", - "skyblocker.tips.enabled": "§aEnabled Tips.", "skyblocker.tips.disabled": "§cDisabled Tips.", "skyblocker.tips.clickEnable": "§a[Click to Enable Tips]", From b121b6e4647b15591c7550ea29cd3829f3525a6e Mon Sep 17 00:00:00 2001 From: viciscat <51047087+viciscat@users.noreply.github.com> Date: Sat, 11 May 2024 14:41:16 +0200 Subject: [PATCH 16/20] requested changes part 2 --- .../skyblock/events/JacobEventToast.java | 20 ------------------- .../skyblock/itemlist/UpcomingEventsTab.java | 3 ++- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java b/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java index ca0f08c458..43ed7d128e 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/JacobEventToast.java @@ -1,8 +1,6 @@ package de.hysky.skyblocker.skyblock.events; -import com.mojang.blaze3d.systems.RenderSystem; import de.hysky.skyblocker.skyblock.tabhud.widget.JacobsContestWidget; -import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.render.RenderHelper; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; @@ -13,30 +11,12 @@ import net.minecraft.util.Colors; import net.minecraft.util.math.MathHelper; -import java.util.HashMap; -import java.util.Map; - public class JacobEventToast extends EventToast { private final String[] crops; private static final ItemStack DEFAULT_ITEM = new ItemStack(Items.IRON_HOE); - public static final Map cropItems = new HashMap<>(); - - static { - cropItems.put("Wheat", new ItemStack(Items.WHEAT)); - cropItems.put("Mushroom", new ItemStack(Items.RED_MUSHROOM)); - cropItems.put("Pumpkin", new ItemStack(Items.CARVED_PUMPKIN)); - cropItems.put("Melon", new ItemStack(Items.MELON)); - cropItems.put("Sugar Cane", new ItemStack(Items.SUGAR_CANE)); - cropItems.put("Cactus", new ItemStack(Items.CACTUS)); - cropItems.put("Carrot", new ItemStack(Items.CARROT)); - cropItems.put("Cocoa Beans", new ItemStack(Items.COCOA_BEANS)); - cropItems.put("Potato", new ItemStack(Items.POTATO)); - cropItems.put("Nether Wart", new ItemStack(Items.NETHER_WART)); - } - public JacobEventToast(long eventStartTime, String name, String[] crops) { super(eventStartTime, name, new ItemStack(Items.IRON_HOE)); this.crops = crops; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java index ce48018dce..64154af395 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java @@ -3,6 +3,7 @@ import de.hysky.skyblocker.mixins.accessors.DrawContextInvoker; import de.hysky.skyblocker.skyblock.events.EventNotifications; import de.hysky.skyblocker.skyblock.events.JacobEventToast; +import de.hysky.skyblocker.skyblock.tabhud.widget.JacobsContestWidget; import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.scheduler.MessageScheduler; import net.minecraft.client.MinecraftClient; @@ -160,7 +161,7 @@ public int getWidth(TextRenderer textRenderer) { public void drawItems(TextRenderer textRenderer, int x, int y, DrawContext context) { for (int i = 0; i < crops.length; i++) { String crop = crops[i]; - context.drawItem(JacobEventToast.cropItems.getOrDefault(crop, BARRIER), x + 18 * i, y + 2); + context.drawItem(JacobsContestWidget.FARM_DATA.getOrDefault(crop, BARRIER), x + 18 * i, y + 2); } } From 515704569c7e832de11cedc561ba4dfc7cddd579 Mon Sep 17 00:00:00 2001 From: viciscat <51047087+viciscat@users.noreply.github.com> Date: Sat, 11 May 2024 14:42:34 +0200 Subject: [PATCH 17/20] unused import --- .../de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java index 64154af395..9552ae87e5 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/UpcomingEventsTab.java @@ -2,7 +2,6 @@ import de.hysky.skyblocker.mixins.accessors.DrawContextInvoker; import de.hysky.skyblocker.skyblock.events.EventNotifications; -import de.hysky.skyblocker.skyblock.events.JacobEventToast; import de.hysky.skyblocker.skyblock.tabhud.widget.JacobsContestWidget; import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.scheduler.MessageScheduler; From 0512b07a5cbb3c8ec0504c4791b832bc9497194a Mon Sep 17 00:00:00 2001 From: viciscat <51047087+viciscat@users.noreply.github.com> Date: Sat, 18 May 2024 23:26:17 +0200 Subject: [PATCH 18/20] yea --- .../hysky/skyblocker/skyblock/events/EventNotifications.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java index 537ee360c1..e0bf16fc67 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java @@ -134,12 +134,12 @@ private static void timeUpdate() { } String eventName = entry.getKey(); List reminderTimes = SkyblockerConfigManager.get().eventNotifications.eventsReminderTimes.getOrDefault(eventName, DEFAULT_REMINDERS); - if (reminderTimes.isEmpty()) return; + if (reminderTimes.isEmpty()) continue; for (Integer reminderTime : reminderTimes) { if (currentTime + reminderTime < skyblockEvent.start() && newTime + reminderTime >= skyblockEvent.start()) { MinecraftClient instance = MinecraftClient.getInstance(); - if (eventName.equals("Jacob's Farming Contest")) { + if (eventName.equals(JACOBS)) { instance.getToastManager().add( new JacobEventToast(skyblockEvent.start(), eventName, skyblockEvent.extras()) ); From 90569c01c0160433beed7e452d710ab741a25e19 Mon Sep 17 00:00:00 2001 From: viciscat <51047087+viciscat@users.noreply.github.com> Date: Sun, 2 Jun 2024 13:44:08 +0200 Subject: [PATCH 19/20] requested changes YAY --- .../config/categories/EventNotificationsCategory.java | 8 +++++--- .../config/configs/EventNotificationsConfig.java | 3 ++- .../skyblocker/skyblock/events/EventNotifications.java | 5 ++++- src/main/java/de/hysky/skyblocker/utils/Utils.java | 1 + 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java index e353b5d1db..6fd01cf8e8 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/EventNotificationsCategory.java @@ -6,6 +6,8 @@ import de.hysky.skyblocker.skyblock.events.EventNotifications; import de.hysky.skyblocker.utils.config.DurationController; import dev.isxander.yacl3.api.*; +import it.unimi.dsi.fastutil.ints.IntImmutableList; +import it.unimi.dsi.fastutil.ints.IntList; import net.minecraft.client.MinecraftClient; import net.minecraft.client.sound.PositionedSoundInstance; import net.minecraft.text.Text; @@ -43,13 +45,13 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig } private static List createGroups(SkyblockerConfig config) { - Map> eventsReminderTimes = config.eventNotifications.eventsReminderTimes; + Map eventsReminderTimes = config.eventNotifications.eventsReminderTimes; List groups = new ArrayList<>(eventsReminderTimes.size()); if (eventsReminderTimes.isEmpty()) return List.of(OptionGroup.createBuilder().option(LabelOption.create(Text.translatable("skyblocker.config.eventNotifications.monologue"))).build()); - for (Map.Entry> entry : eventsReminderTimes.entrySet()) { + for (Map.Entry entry : eventsReminderTimes.entrySet()) { groups.add(ListOption.createBuilder() .name(Text.literal(entry.getKey())) - .binding(EventNotifications.DEFAULT_REMINDERS, entry::getValue, entry::setValue) + .binding(EventNotifications.DEFAULT_REMINDERS, entry::getValue, integers -> entry.setValue(new IntImmutableList(integers))) .controller(option -> () -> new DurationController(option)) // yea .description(OptionDescription.of(Text.translatable("skyblocker.config.eventNotifications.@Tooltip[0]"), Text.empty(), diff --git a/src/main/java/de/hysky/skyblocker/config/configs/EventNotificationsConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/EventNotificationsConfig.java index cc51e536a7..4cf47fa306 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/EventNotificationsConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/EventNotificationsConfig.java @@ -1,6 +1,7 @@ package de.hysky.skyblocker.config.configs; import dev.isxander.yacl3.config.v2.api.SerialEntry; +import it.unimi.dsi.fastutil.ints.IntList; import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvents; @@ -14,7 +15,7 @@ public class EventNotificationsConfig { public Sound reminderSound = Sound.PLING; @SerialEntry - public Map> eventsReminderTimes = new HashMap<>(); + public Map eventsReminderTimes = new HashMap<>(); public enum Sound { NONE(null), diff --git a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java index e0bf16fc67..0fd4196948 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/events/EventNotifications.java @@ -11,6 +11,7 @@ import de.hysky.skyblocker.events.SkyblockEvents; import de.hysky.skyblocker.utils.Http; import de.hysky.skyblocker.utils.scheduler.Scheduler; +import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; @@ -32,7 +33,7 @@ public class EventNotifications { public static final String JACOBS = "Jacob's Farming Contest"; - public static final List DEFAULT_REMINDERS = List.of(60, 60 * 5); + public static final IntList DEFAULT_REMINDERS = IntList.of(60, 60 * 5); public static final Map eventIcons = new Object2ObjectOpenHashMap<>(); @@ -127,6 +128,8 @@ private static void timeUpdate() { LinkedList nextEvents = entry.getValue(); SkyblockEvent skyblockEvent = nextEvents.peekFirst(); if (skyblockEvent == null) continue; + + // Remove finished event if (newTime > skyblockEvent.start() + skyblockEvent.duration()) { nextEvents.pollFirst(); skyblockEvent = nextEvents.peekFirst(); diff --git a/src/main/java/de/hysky/skyblocker/utils/Utils.java b/src/main/java/de/hysky/skyblocker/utils/Utils.java index fa9292ca88..7c28294ff8 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Utils.java +++ b/src/main/java/de/hysky/skyblocker/utils/Utils.java @@ -356,6 +356,7 @@ private static void updateScoreboard(MinecraftClient client) { } } + // TODO: Combine with `ChocolateFactorySolver.formatTime` and move into `SkyblockTime`. public static Text getDurationText(int timeInSeconds) { int seconds = timeInSeconds % 60; int minutes = (timeInSeconds/60) % 60; From 9054e87d9f5becea3addbdd60afeb6e3829143e8 Mon Sep 17 00:00:00 2001 From: viciscat <51047087+viciscat@users.noreply.github.com> Date: Sun, 2 Jun 2024 13:45:05 +0200 Subject: [PATCH 20/20] UNUSED IMPORT --- .../skyblocker/config/configs/EventNotificationsConfig.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/config/configs/EventNotificationsConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/EventNotificationsConfig.java index 4cf47fa306..c43ae7a69f 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/EventNotificationsConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/EventNotificationsConfig.java @@ -6,7 +6,6 @@ import net.minecraft.sound.SoundEvents; import java.util.HashMap; -import java.util.List; import java.util.Map; public class EventNotificationsConfig {