diff options
Diffstat (limited to 'src/main/java/me/xmrvizzy/skyblocker')
64 files changed, 1837 insertions, 557 deletions
diff --git a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java index bfc5013b..add81791 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java +++ b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java @@ -1,14 +1,12 @@ package me.xmrvizzy.skyblocker; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import me.xmrvizzy.skyblocker.chat.ChatMessageListener; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; import me.xmrvizzy.skyblocker.discord.DiscordRPCManager; import me.xmrvizzy.skyblocker.gui.ContainerSolverManager; -import me.xmrvizzy.skyblocker.skyblock.BackpackPreview; -import me.xmrvizzy.skyblocker.skyblock.FishingHelper; -import me.xmrvizzy.skyblocker.skyblock.HotbarSlotLock; -import me.xmrvizzy.skyblocker.skyblock.StatusBarTracker; -import me.xmrvizzy.skyblocker.skyblock.api.RepositoryUpdate; +import me.xmrvizzy.skyblocker.skyblock.*; import me.xmrvizzy.skyblocker.skyblock.api.StatsCommand; import me.xmrvizzy.skyblocker.skyblock.dungeon.DungeonBlaze; import me.xmrvizzy.skyblocker.skyblock.dungeon.DungeonMap; @@ -20,14 +18,14 @@ import me.xmrvizzy.skyblocker.skyblock.itemlist.ItemRegistry; import me.xmrvizzy.skyblocker.skyblock.quicknav.QuickNav; import me.xmrvizzy.skyblocker.skyblock.tabhud.TabHud; import me.xmrvizzy.skyblocker.skyblock.tabhud.util.PlayerListMgr; -import me.xmrvizzy.skyblocker.utils.MessageScheduler; -import me.xmrvizzy.skyblocker.utils.Scheduler; -import me.xmrvizzy.skyblocker.utils.UpdateChecker; -import me.xmrvizzy.skyblocker.utils.Utils; +import me.xmrvizzy.skyblocker.utils.*; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.MinecraftClient; +import java.nio.file.Path; + /** * Main class for Skyblocker which initializes features, registers events, and * manages ticks. This class will be instantiated by Fabric. Do not instantiate @@ -35,6 +33,8 @@ import net.minecraft.client.MinecraftClient; */ public class SkyblockerMod implements ClientModInitializer { public static final String NAMESPACE = "skyblocker"; + public static final Path CONFIG_DIR = FabricLoader.getInstance().getConfigDir().resolve(NAMESPACE); + public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); private static SkyblockerMod INSTANCE; @SuppressWarnings("deprecation") @@ -63,12 +63,13 @@ public class SkyblockerMod implements ClientModInitializer { @Override public void onInitializeClient() { ClientTickEvents.END_CLIENT_TICK.register(this::tick); + Utils.init(); HotbarSlotLock.init(); SkyblockerConfig.init(); PriceInfoTooltip.init(); WikiLookup.init(); ItemRegistry.init(); - RepositoryUpdate.init(); + NEURepo.init(); BackpackPreview.init(); QuickNav.init(); StatsCommand.init(); @@ -78,11 +79,12 @@ public class SkyblockerMod implements ClientModInitializer { DiscordRPCManager.init(); LividColor.init(); FishingHelper.init(); + FairySouls.init(); TabHud.init(); - containerSolverManager.init(); DungeonMap.init(); - scheduler.scheduleCyclic(Utils::sbChecker, 20); - scheduler.scheduleCyclic(DiscordRPCManager::update, 100); + containerSolverManager.init(); + scheduler.scheduleCyclic(Utils::update, 20); + scheduler.scheduleCyclic(DiscordRPCManager::updateDataAndPresence, 100); scheduler.scheduleCyclic(DungeonBlaze::update, 4); scheduler.scheduleCyclic(LividColor::update, 10); scheduler.scheduleCyclic(BackpackPreview::tick, 50); diff --git a/src/main/java/me/xmrvizzy/skyblocker/chat/filters/AdFilter.java b/src/main/java/me/xmrvizzy/skyblocker/chat/filters/AdFilter.java index 5f9f463d..67734438 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/chat/filters/AdFilter.java +++ b/src/main/java/me/xmrvizzy/skyblocker/chat/filters/AdFilter.java @@ -9,30 +9,30 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class AdFilter extends ChatPatternListener { - private static final Pattern[] AD_FILTERS = new Pattern[]{ - Pattern.compile("^(?:i(?:m|'m| am)? |(?:is )?any(?: ?one|1) )?(?:buy|sell|lowball|trade?)(?:ing)?(?:\\W|$)", Pattern.CASE_INSENSITIVE), - Pattern.compile("(.)\\1{7,}"), - Pattern.compile("\\W(?:on|in|check|at) my (?:ah|bin)(?:\\W|$)", Pattern.CASE_INSENSITIVE), - }; + private static final Pattern[] AD_FILTERS = new Pattern[] { + Pattern.compile("^(?:i(?:m|'m| am)? |(?:is )?any(?: ?one|1) )?(?:buy|sell|lowball|trade?)(?:ing)?(?:\\W|$)", Pattern.CASE_INSENSITIVE), + Pattern.compile("(.)\\1{7,}"), + Pattern.compile("\\W(?:on|in|check|at) my (?:ah|bin)(?:\\W|$)", Pattern.CASE_INSENSITIVE), }; - public AdFilter() { - // Groups: - // 1. Player name - // 2. Message - super("^§[67ab](?:\\[(?:MVP|VIP)(?:§[0-9a-f]\\+{1,2}§[6ab])?] )?([a-zA-Z0-9_]{2,16})§[7f]: (.*)$"); - } + public AdFilter() { + // Groups: + // 1. Player name + // 2. Message + // (?:§8\[[§fadbc0-9]+§8\] )?§[67abc](?:\[[§A-Za-z0-9+]+\] )?([A-Za-z0-9_]+)§[f7]: (.+) + super("(?:§8\\[[§fadbc0-9]+§8\\] )?§[67abc](?:\\[[§A-Za-z0-9+]+\\] )?([A-Za-z0-9_]+)§[f7]: (.+)"); + } - @Override - public boolean onMatch(Text _message, Matcher matcher) { - String message = matcher.group(2); - for (Pattern adFilter : AD_FILTERS) - if (adFilter.matcher(message).find()) - return true; - return false; - } + @Override + public boolean onMatch(Text _message, Matcher matcher) { + String message = matcher.group(2); + for (Pattern adFilter : AD_FILTERS) + if (adFilter.matcher(message).find()) + return true; + return false; + } - @Override - protected ChatFilterResult state() { - return SkyblockerConfig.get().messages.hideAds; - } + @Override + protected ChatFilterResult state() { + return SkyblockerConfig.get().messages.hideAds; + } }
\ No newline at end of file diff --git a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java index ccf86eb2..833e4661 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java @@ -147,10 +147,18 @@ public class SkyblockerConfig implements ConfigData { @ConfigEntry.Gui.CollapsibleObject() public Bars bars = new Bars(); + @ConfigEntry.Category("experiments") + @ConfigEntry.Gui.CollapsibleObject() + public Experiments experiments = new Experiments(); + @ConfigEntry.Category("fishing") @ConfigEntry.Gui.CollapsibleObject() public Fishing fishing = new Fishing(); + @ConfigEntry.Category("fairySouls") + @ConfigEntry.Gui.CollapsibleObject() + public FairySouls fairySouls = new FairySouls(); + @ConfigEntry.Category("itemList") @ConfigEntry.Gui.CollapsibleObject() public ItemList itemList = new ItemList(); @@ -216,10 +224,20 @@ public class SkyblockerConfig implements ConfigData { } } + public static class Experiments { + public boolean enableChronomatronSolver = true; + public boolean enableSuperpairsSolver = true; + public boolean enableUltrasequencerSolver = true; + } + public static class Fishing { public boolean enableFishingHelper = true; } + public static class FairySouls { + public boolean enableFairySoulsHelper = false; + } + public static class Hitbox { public boolean oldFarmlandHitbox = true; public boolean oldLeverHitbox = false; diff --git a/src/main/java/me/xmrvizzy/skyblocker/discord/DiscordRPCManager.java b/src/main/java/me/xmrvizzy/skyblocker/discord/DiscordRPCManager.java index 4fa5265f..325f271a 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/discord/DiscordRPCManager.java +++ b/src/main/java/me/xmrvizzy/skyblocker/discord/DiscordRPCManager.java @@ -11,42 +11,89 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.text.DecimalFormat; +import java.util.concurrent.CompletableFuture; +/** + * Manages the discord rich presence. Automatically connects to discord and displays a customizable activity when playing Skyblock. + */ public class DiscordRPCManager { public static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("###,###.##"); public static final Logger LOGGER = LoggerFactory.getLogger("Skyblocker Discord RPC"); + /** + * The update task used to avoid multiple update tasks running simultaneously. + */ + public static CompletableFuture<Void> updateTask; public static long startTimeStamp; public static int cycleCount; - public static void init(){ - SkyblockEvents.LEAVE.register(DiscordIPC::stop); + public static void init() { + SkyblockEvents.LEAVE.register(DiscordRPCManager::initAndUpdatePresence); SkyblockEvents.JOIN.register(() -> { startTimeStamp = System.currentTimeMillis(); - if (DiscordIPC.start(934607927837356052L, null)) { - DiscordIPC.setActivity(buildPresence()); - LOGGER.info("Discord RPC started"); - } else { - LOGGER.error("Discord RPC failed to start"); - } + initAndUpdatePresence(true); }); } - public static void update(){ + /** + * Checks the {@link SkyblockerConfig.RichPresence#customMessage custom message}, updates {@link #cycleCount} if enabled, and updates rich presence. + */ + public static void updateDataAndPresence() { // If the custom message is empty, discord will keep the last message, this is can serve as a default if the user doesn't want a custom message if (SkyblockerConfig.get().richPresence.customMessage.isEmpty()) { SkyblockerConfig.get().richPresence.customMessage = "Playing Skyblock"; AutoConfig.getConfigHolder(SkyblockerConfig.class).save(); } - if ((!Utils.isOnSkyblock() || !SkyblockerConfig.get().richPresence.enableRichPresence) && DiscordIPC.isConnected()){ - DiscordIPC.stop(); - LOGGER.info("Discord RPC stopped"); - return; - } if (SkyblockerConfig.get().richPresence.cycleMode) cycleCount = (cycleCount + 1) % 3; - DiscordIPC.setActivity(buildPresence()); + initAndUpdatePresence(); + } + + /** + * @see #initAndUpdatePresence(boolean) + */ + private static void initAndUpdatePresence() { + initAndUpdatePresence(false); + } + + /** + * Updates discord presence asynchronously. + * <p> + * When the {@link #updateTask previous update} does not exist or {@link CompletableFuture#isDone() has completed}: + * <p> + * Connects to discord if {@link SkyblockerConfig.RichPresence#enableRichPresence rich presence is enabled}, + * the player {@link Utils#isOnSkyblock() is on Skyblock}, and {@link DiscordIPC#isConnected() discord is not already connected}. + * Updates the presence if {@link SkyblockerConfig.RichPresence#enableRichPresence rich presence is enabled} + * and the player {@link Utils#isOnSkyblock() is on Skyblock}. + * Stops the connection if {@link SkyblockerConfig.RichPresence#enableRichPresence rich presence is disabled} + * or the player {@link Utils#isOnSkyblock() is not on Skyblock} and {@link DiscordIPC#isConnected() discord is connected}. + * Saves the update task in {@link #updateTask} + * + * @param initialization whether this is the first time the presence is being updates. If {@code true}, a message will be logged + * if {@link SkyblockerConfig.RichPresence#enableRichPresence rich presence is disabled}. + */ + private static void initAndUpdatePresence(boolean initialization) { + if (updateTask == null || updateTask.isDone()) { + updateTask = CompletableFuture.runAsync(() -> { + if (SkyblockerConfig.get().richPresence.enableRichPresence && Utils.isOnSkyblock()) { + if (!DiscordIPC.isConnected()) { + if (DiscordIPC.start(934607927837356052L, null)) { + LOGGER.info("Discord RPC started successfully"); + } else { + LOGGER.error("Discord RPC failed to start"); + return; + } + } + DiscordIPC.setActivity(buildPresence()); + } else if (DiscordIPC.isConnected()) { + DiscordIPC.stop(); + LOGGER.info("Discord RPC stopped"); + } else if (initialization) { + LOGGER.info("Discord RPC is currently disabled"); + } + }); + } } - public static RichPresence buildPresence(){ + public static RichPresence buildPresence() { RichPresence presence = new RichPresence(); presence.setLargeImage("skyblocker-default", null); presence.setStart(startTimeStamp); @@ -55,19 +102,19 @@ public class DiscordRPCManager { return presence; } - public static String getInfo(){ + public static String getInfo() { String info = null; - if (!SkyblockerConfig.get().richPresence.cycleMode){ - switch (SkyblockerConfig.get().richPresence.info){ + if (!SkyblockerConfig.get().richPresence.cycleMode) { + switch (SkyblockerConfig.get().richPresence.info) { case BITS -> info = "Bits: " + DECIMAL_FORMAT.format(Utils.getBits()); case PURSE -> info = "Purse: " + DECIMAL_FORMAT.format(Utils.getPurse()); - case LOCATION -> info = "⏣ " + Utils.getLocation(); + case LOCATION -> info = Utils.getLocation(); } - } else if (SkyblockerConfig.get().richPresence.cycleMode){ - switch (cycleCount){ + } else if (SkyblockerConfig.get().richPresence.cycleMode) { + switch (cycleCount) { case 0 -> info = "Bits: " + DECIMAL_FORMAT.format(Utils.getBits()); case 1 -> info = "Purse: " + DECIMAL_FORMAT.format(Utils.getPurse()); - case 2 -> info = "⏣ " + Utils.getLocation(); + case 2 -> info = Utils.getLocation(); } } return info; diff --git a/src/main/java/me/xmrvizzy/skyblocker/gui/ColorHighlight.java b/src/main/java/me/xmrvizzy/skyblocker/gui/ColorHighlight.java index 5120ceac..4367e6e7 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/gui/ColorHighlight.java +++ b/src/main/java/me/xmrvizzy/skyblocker/gui/ColorHighlight.java @@ -1,4 +1,24 @@ package me.xmrvizzy.skyblocker.gui; public record ColorHighlight(int slot, int color) { + private static final int RED_HIGHLIGHT = 64 << 24 | 255 << 16; + private static final int YELLOW_HIGHLIGHT = 128 << 24 | 255 << 16 | 255 << 8; + private static final int GREEN_HIGHLIGHT = 128 << 24 | 64 << 16 | 196 << 8 | 64; + private static final int GRAY_HIGHLIGHT = 128 << 24 | 64 << 16 | 64 << 8 | 64; + + public static ColorHighlight red(int slot) { + return new ColorHighlight(slot, RED_HIGHLIGHT); + } + + public static ColorHighlight yellow(int slot) { + return new ColorHighlight(slot, YELLOW_HIGHLIGHT); + } + + public static ColorHighlight green(int slot) { + return new ColorHighlight(slot, GREEN_HIGHLIGHT); + } + + public static ColorHighlight gray(int slot) { + return new ColorHighlight(slot, GRAY_HIGHLIGHT); + } }
\ No newline at end of file diff --git a/src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolver.java b/src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolver.java index 84de64eb..c5e3cf09 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolver.java +++ b/src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolver.java @@ -1,5 +1,6 @@ package me.xmrvizzy.skyblocker.gui; +import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; import net.minecraft.item.ItemStack; import java.util.List; @@ -10,23 +11,27 @@ import java.util.regex.Pattern; * Abstract class for gui solvers. Extend this class to add a new gui solver, like terminal solvers or experiment solvers. */ public abstract class ContainerSolver { - private final Pattern CONTAINER_NAME; - protected final static int GREEN_HIGHLIGHT = 128 << 24 | 64 << 16 | 196 << 8 | 64; - protected final static int GRAY_HIGHLIGHT = 128 << 24 | 64 << 16 | 64 << 8 | 64; + private final Pattern containerName; - public ContainerSolver(String containerName) { - CONTAINER_NAME = Pattern.compile(containerName); + protected ContainerSolver(String containerName) { + this.containerName = Pattern.compile(containerName); } - public abstract boolean isEnabled(); + protected abstract boolean isEnabled(); public Pattern getName() { - return CONTAINER_NAME; + return containerName; } - public abstract List<ColorHighlight> getColors(String[] groups, Map<Integer, ItemStack> slots); + protected void start(GenericContainerScreen screen) { + } + + protected void reset() { + } + + protected abstract List<ColorHighlight> getColors(String[] groups, Map<Integer, ItemStack> slots); - public void trimEdges(Map<Integer, ItemStack> slots, int rows) { + protected void trimEdges(Map<Integer, ItemStack> slots, int rows) { for (int i = 0; i < rows; i++) { slots.remove(9 * i); slots.remove(9 * i + 8); diff --git a/src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolverManager.java b/src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolverManager.java index e4ff229d..0c27704d 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolverManager.java +++ b/src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolverManager.java @@ -6,9 +6,12 @@ import me.xmrvizzy.skyblocker.skyblock.dungeon.CroesusHelper; import me.xmrvizzy.skyblocker.skyblock.dungeon.terminal.ColorTerminal; import me.xmrvizzy.skyblocker.skyblock.dungeon.terminal.OrderTerminal; import me.xmrvizzy.skyblocker.skyblock.dungeon.terminal.StartsWithTerminal; +import me.xmrvizzy.skyblocker.skyblock.experiment.ChronomatronSolver; +import me.xmrvizzy.skyblocker.skyblock.experiment.SuperpairsSolver; +import me.xmrvizzy.skyblocker.skyblock.experiment.UltrasequencerSolver; import me.xmrvizzy.skyblocker.utils.Utils; import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; -import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemStack; @@ -24,7 +27,7 @@ import java.util.regex.Pattern; /** * Manager class for {@link ContainerSolver}s like terminal solvers and experiment solvers. To add a new gui solver, extend {@link ContainerSolver} and register it in {@link #ContainerSolverManager()}. */ -public class ContainerSolverManager extends DrawableHelper { +public class ContainerSolverManager { private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile(""); private final ContainerSolver[] solvers; private ContainerSolver currentSolver = null; @@ -36,19 +39,28 @@ public class ContainerSolverManager extends DrawableHelper { new ColorTerminal(), new OrderTerminal(), new StartsWithTerminal(), - new CroesusHelper() + new CroesusHelper(), + new ChronomatronSolver(), + new SuperpairsSolver(), + new UltrasequencerSolver() }; } + public ContainerSolver getCurrentSolver() { + return currentSolver; + } + public void init() { ScreenEvents.BEFORE_INIT.register((client, screen, scaledWidth, scaledHeight) -> { if (Utils.isOnSkyblock() && screen instanceof GenericContainerScreen genericContainerScreen) { - ScreenEvents.afterRender(screen).register((screen1, matrices, mouseX, mouseY, delta) -> { + ScreenEvents.afterRender(screen).register((screen1, context, mouseX, mouseY, delta) -> { + MatrixStack matrices = context.getMatrices(); matrices.push(); matrices.translate(((HandledScreenAccessor) genericContainerScreen).getX(), ((HandledScreenAccessor) genericContainerScreen).getY(), 300); - onDraw(matrices, genericContainerScreen.getScreenHandler().slots.subList(0, genericContainerScreen.getScreenHandler().getRows() * 9)); + onDraw(context, genericContainerScreen.getScreenHandler().slots.subList(0, genericContainerScreen.getScreenHandler().getRows() * 9)); matrices.pop(); }); + ScreenEvents.remove(screen).register(screen1 -> clearScreen()); onSetScreen(genericContainerScreen); } else { clearScreen(); @@ -66,24 +78,29 @@ public class ContainerSolverManager extends DrawableHelper { if (matcher.matches()) { currentSolver = solver; groups = new String[matcher.groupCount()]; - for (int i = 0; i < groups.length; i++) + for (int i = 0; i < groups.length; i++) { groups[i] = matcher.group(i + 1); + } + currentSolver.start(screen); return; } } } - currentSolver = null; + clearScreen(); } public void clearScreen() { - currentSolver = null; + if (currentSolver != null) { + currentSolver.reset(); + currentSolver = null; + } } public void markDirty() { highlights = null; } - public void onDraw(MatrixStack matrices, List<Slot> slots) { + public void onDraw(DrawContext context, List<Slot> slots) { if (currentSolver == null) return; if (highlights == null) @@ -93,7 +110,7 @@ public class ContainerSolverManager extends DrawableHelper { for (ColorHighlight highlight : highlights) { Slot slot = slots.get(highlight.slot()); int color = highlight.color(); - fillGradient(matrices, slot.x, slot.y, slot.x + 16, slot.y + 16, color, color); + context.fillGradient(slot.x, slot.y, slot.x + 16, slot.y + 16, color, color); } RenderSystem.colorMask(true, true, true, true); } diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/ItemRendererMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/DrawContextMixin.java index 26bafc14..a8a490b8 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/mixin/ItemRendererMixin.java +++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/DrawContextMixin.java @@ -5,6 +5,8 @@ import java.util.regex.Pattern; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -15,17 +17,23 @@ import me.xmrvizzy.skyblocker.config.SkyblockerConfig; import me.xmrvizzy.skyblocker.utils.ItemUtils; import me.xmrvizzy.skyblocker.utils.Utils; import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawableHelper; -import net.minecraft.client.render.item.ItemRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.render.RenderLayer; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; import net.minecraft.util.math.ColorHelper; -@Mixin(ItemRenderer.class) -public abstract class ItemRendererMixin { - @Inject(method = "renderGuiItemOverlay(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V", at = @At("HEAD")) - public void skyblocker$renderItemBar(MatrixStack matrices, TextRenderer renderer, ItemStack stack, int x, int y, @Nullable String countLabel, CallbackInfo ci) { +@Mixin(DrawContext.class) +public abstract class DrawContextMixin { + @Shadow @Final private MatrixStack matrices; + + @Shadow + public void fill(RenderLayer layer, int x1, int x2, int y1, int y2, int color) { + } + + @Inject(method = "drawItemInSlot(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V", at = @At("HEAD")) + public void skyblocker$renderItemBar(TextRenderer textRenderer, ItemStack stack, int x, int y, @Nullable String countOverride, CallbackInfo ci) { if (Utils.isOnSkyblock() && SkyblockerConfig.get().locations.dwarvenMines.enableDrillFuel) { if (!stack.isEmpty()) { @@ -44,13 +52,18 @@ public abstract class ItemRendererMixin { break; } } - + + matrices.push(); + matrices.translate(0f, 0f, 200f); RenderSystem.disableDepthTest(); + float hue = Math.max(0.0F, 1.0F - (max - current) / max); int width = Math.round(current / max * 13.0F); Color color = Color.getHSBColor(hue / 3.0F, 1.0F, 1.0F); - DrawableHelper.fill(matrices, x + 2, y + 13, x + 15, y + 15, 0xFF000000); - DrawableHelper.fill(matrices, x + 2, y + 13, x + 2 + width, y + 14, ColorHelper.Argb.getArgb(color.getAlpha(), color.getRed(), color.getGreen(), color.getBlue())); + this.fill(RenderLayer.getGuiOverlay(), x + 2, y + 13, x + 15, y + 15, 0xFF000000); + this.fill(RenderLayer.getGuiOverlay(), x + 2, y + 13, x + 2 + width, y + 14, ColorHelper.Argb.getArgb(color.getAlpha(), color.getRed(), color.getGreen(), color.getBlue())); + + matrices.pop(); RenderSystem.enableDepthTest(); } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java index 2d200a86..aefe11c6 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java +++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java @@ -1,18 +1,32 @@ package me.xmrvizzy.skyblocker.mixin; +import me.xmrvizzy.skyblocker.SkyblockerMod; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; +import me.xmrvizzy.skyblocker.gui.ContainerSolver; import me.xmrvizzy.skyblocker.skyblock.BackpackPreview; +import me.xmrvizzy.skyblocker.skyblock.experiment.ChronomatronSolver; +import me.xmrvizzy.skyblocker.skyblock.experiment.ExperimentSolver; +import me.xmrvizzy.skyblocker.skyblock.experiment.SuperpairsSolver; +import me.xmrvizzy.skyblocker.skyblock.experiment.UltrasequencerSolver; import me.xmrvizzy.skyblocker.skyblock.item.WikiLookup; +import me.xmrvizzy.skyblocker.utils.Utils; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.HandledScreen; -import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.inventory.SimpleInventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraft.screen.slot.Slot; +import net.minecraft.screen.slot.SlotActionType; import net.minecraft.text.Text; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @@ -28,20 +42,63 @@ public abstract class HandledScreenMixin extends Screen { @Inject(at = @At("HEAD"), method = "keyPressed") public void skyblocker$keyPressed(int keyCode, int scanCode, int modifiers, CallbackInfoReturnable<Boolean> cir) { - if (this.focusedSlot != null) { - if (keyCode != 256 && !this.client.options.inventoryKey.matchesKey(keyCode, scanCode)) { - if (WikiLookup.wikiLookup.matchesKey(keyCode, scanCode)) WikiLookup.openWiki(this.focusedSlot); - } + if (this.client != null && this.focusedSlot != null && keyCode != 256 && !this.client.options.inventoryKey.matchesKey(keyCode, scanCode) && WikiLookup.wikiLookup.matchesKey(keyCode, scanCode)) { + WikiLookup.openWiki(this.focusedSlot); } } @Inject(at = @At("HEAD"), method = "drawMouseoverTooltip", cancellable = true) - public void skyblocker$drawMouseOverTooltip(MatrixStack matrices, int x, int y, CallbackInfo ci) { - String title = this.getTitle().getString(); + public void skyblocker$drawMouseOverTooltip(DrawContext context, int x, int y, CallbackInfo ci) { + // Hide Empty Tooltips + if (Utils.isOnSkyblock() && SkyblockerConfig.get().general.hideEmptyTooltips && this.focusedSlot != null && focusedSlot.getStack().getName().getString().equals(" ")) { + ci.cancel(); + } + + // Backpack Preview boolean shiftDown = SkyblockerConfig.get().general.backpackPreviewWithoutShift ^ Screen.hasShiftDown(); - if (shiftDown && title.equals("Storage") && this.focusedSlot != null) { - if (this.focusedSlot.inventory == this.client.player.getInventory()) return; - if (BackpackPreview.renderPreview(matrices, this.focusedSlot.getIndex(), x, y)) ci.cancel(); + if (this.client != null && this.client.player != null && this.focusedSlot != null && shiftDown && this.getTitle().getString().equals("Storage") && this.focusedSlot.inventory != this.client.player.getInventory() && BackpackPreview.renderPreview(context, this.focusedSlot.getIndex(), x, y)) { + ci.cancel(); + } + } + + @Redirect(method = "drawMouseoverTooltip", at = @At(value = "INVOKE", target = "Lnet/minecraft/screen/slot/Slot;getStack()Lnet/minecraft/item/ItemStack;", ordinal = 0)) + private ItemStack skyblocker$experimentSolvers$replaceTooltipDisplayStack(Slot slot) { + return skyblocker$experimentSolvers$getStack(slot); + } + + @ModifyVariable(method = "drawSlot", at = @At(value = "LOAD", ordinal = 4), ordinal = 0) + private ItemStack skyblocker$experimentSolvers$replaceDisplayStack(ItemStack stack, DrawContext context, Slot slot) { + return skyblocker$experimentSolvers$getStack(slot); + } + + @Unique + private ItemStack skyblocker$experimentSolvers$getStack(Slot slot) { + ContainerSolver currentSolver = SkyblockerMod.getInstance().containerSolverManager.getCurrentSolver(); + if ((currentSolver instanceof SuperpairsSolver || currentSolver instanceof UltrasequencerSolver) && ((ExperimentSolver) currentSolver).getState() == ExperimentSolver.State.SHOW && slot.inventory instanceof SimpleInventory) { + ItemStack itemStack = ((ExperimentSolver) currentSolver).getSlots().get(slot.getIndex()); + return itemStack == null ? slot.getStack() : itemStack; + } + return slot.getStack(); + } + + @Inject(method = "onMouseClick(Lnet/minecraft/screen/slot/Slot;IILnet/minecraft/screen/slot/SlotActionType;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;clickSlot(IIILnet/minecraft/screen/slot/SlotActionType;Lnet/minecraft/entity/player/PlayerEntity;)V")) + private void skyblocker$experimentSolvers$onSlotClick(Slot slot, int slotId, int button, SlotActionType actionType, CallbackInfo ci) { + if (slot != null) { + ContainerSolver currentSolver = SkyblockerMod.getInstance().containerSolverManager.getCurrentSolver(); + if (currentSolver instanceof ExperimentSolver experimentSolver && experimentSolver.getState() == ExperimentSolver.State.SHOW && slot.inventory instanceof SimpleInventory) { + if (experimentSolver instanceof ChronomatronSolver chronomatronSolver) { + Item item = chronomatronSolver.getChronomatronSlots().get(chronomatronSolver.getChronomatronCurrentOrdinal()); + if ((slot.getStack().isOf(item) || ChronomatronSolver.TERRACOTTA_TO_GLASS.get(slot.getStack().getItem()) == item) && chronomatronSolver.incrementChronomatronCurrentOrdinal() >= chronomatronSolver.getChronomatronSlots().size()) { + chronomatronSolver.setState(ExperimentSolver.State.END); + } + } else if (experimentSolver instanceof SuperpairsSolver superpairsSolver) { + superpairsSolver.setSuperpairsPrevClickedSlot(slot.getIndex()); + superpairsSolver.setSuperpairsCurrentSlot(ItemStack.EMPTY); + } else if (experimentSolver instanceof UltrasequencerSolver ultrasequencerSolver && slot.getIndex() == ultrasequencerSolver.getUltrasequencerNextSlot()) { + int count = ultrasequencerSolver.getSlots().get(ultrasequencerSolver.getUltrasequencerNextSlot()).getCount() + 1; + ultrasequencerSolver.getSlots().entrySet().stream().filter(entry -> entry.getValue().getCount() == count).findAny().ifPresentOrElse((entry) -> ultrasequencerSolver.setUltrasequencerNextSlot(entry.getKey()), () -> ultrasequencerSolver.setState(ExperimentSolver.State.END)); + } + } } } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/InGameHudMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/InGameHudMixin.java index e17795ab..335737a1 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/mixin/InGameHudMixin.java +++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/InGameHudMixin.java @@ -1,6 +1,5 @@ package me.xmrvizzy.skyblocker.mixin; -import com.mojang.blaze3d.systems.RenderSystem; import me.xmrvizzy.skyblocker.SkyblockerMod; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; import me.xmrvizzy.skyblocker.skyblock.FancyStatusBars; @@ -10,13 +9,14 @@ import me.xmrvizzy.skyblocker.skyblock.dungeon.DungeonMap; import me.xmrvizzy.skyblocker.utils.Utils; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.hud.InGameHud; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.text.Text; import net.minecraft.util.Identifier; + import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; @@ -26,7 +26,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Environment(EnvType.CLIENT) @Mixin(InGameHud.class) -public abstract class InGameHudMixin extends DrawableHelper { +public abstract class InGameHudMixin { + //@Shadow + //@Final + //private static Identifier ICONS = new Identifier("textures/gui/icons.png"); @Unique private static final Identifier SLOT_LOCK = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/slot_lock.png"); @Unique @@ -35,7 +38,7 @@ public abstract class InGameHudMixin extends DrawableHelper { @Unique private final FancyStatusBars statusBars = new FancyStatusBars(); @Unique - private MatrixStack hotbarMatrices; + private DrawContext hotbarContext; @Unique private int hotbarSlotIndex; @@ -62,45 +65,44 @@ public abstract class InGameHudMixin extends DrawableHelper { } @Inject(method = "renderHotbar", at = @At("HEAD")) - public void skyblocker$renderHotbar(float f, MatrixStack matrices, CallbackInfo ci) { + public void skyblocker$renderHotbar(float f, DrawContext context, CallbackInfo ci) { if (Utils.isOnSkyblock()) { - hotbarMatrices = matrices; + hotbarContext = context; hotbarSlotIndex = 0; } } @Inject(method = "renderHotbarItem", at = @At("HEAD")) - public void skyblocker$renderHotbarItem(MatrixStack matrices, int i, int j, float f, PlayerEntity player, ItemStack stack, int seed, CallbackInfo ci) { + public void skyblocker$renderHotbarItem(DrawContext context, int i, int j, float f, PlayerEntity player, ItemStack stack, int seed, CallbackInfo ci) { if (Utils.isOnSkyblock()) { if (HotbarSlotLock.isLocked(hotbarSlotIndex)) { - RenderSystem.setShaderTexture(0, SLOT_LOCK); - DrawableHelper.drawTexture(hotbarMatrices, i, j, 0, 0, 16, 16); + hotbarContext.drawTexture(SLOT_LOCK, i, j, 0, 0, 16, 16); } hotbarSlotIndex++; } } @Inject(method = "renderExperienceBar", at = @At("HEAD"), cancellable = true) - private void skyblocker$renderExperienceBar(MatrixStack matrices, int x, CallbackInfo ci) { + private void skyblocker$renderExperienceBar(DrawContext context, int x, CallbackInfo ci) { if (Utils.isOnSkyblock() && SkyblockerConfig.get().general.bars.enableBars) ci.cancel(); } @Inject(method = "renderStatusBars", at = @At("HEAD"), cancellable = true) - private void skyblocker$renderStatusBars(MatrixStack matrices, CallbackInfo ci) { + private void skyblocker$renderStatusBars(DrawContext context, CallbackInfo ci) { if (!Utils.isOnSkyblock()) return; - if (statusBars.render(matrices, scaledWidth, scaledHeight)) + if (statusBars.render(context, scaledWidth, scaledHeight)) ci.cancel(); if (Utils.isInDungeons() && SkyblockerConfig.get().locations.dungeons.enableMap) - DungeonMap.render(matrices); + DungeonMap.render(context.getMatrices()); - RenderSystem.setShaderTexture(0, GUI_ICONS_TEXTURE); + //RenderSystem.setShaderTexture(0, ICONS); } @Inject(method = "renderMountHealth", at = @At("HEAD"), cancellable = true) - private void skyblocker$renderMountHealth(MatrixStack matrices, CallbackInfo ci) { + private void skyblocker$renderMountHealth(DrawContext context, CallbackInfo ci) { if (Utils.isOnSkyblock() && SkyblockerConfig.get().general.bars.enableBars) ci.cancel(); } diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/PlayerListHudMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/PlayerListHudMixin.java index b5403ae2..ef65190f 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/mixin/PlayerListHudMixin.java +++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/PlayerListHudMixin.java @@ -13,9 +13,9 @@ import me.xmrvizzy.skyblocker.utils.Utils; 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.hud.PlayerListHud; import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.client.util.math.MatrixStack; import net.minecraft.scoreboard.Scoreboard; import net.minecraft.scoreboard.ScoreboardObjective; import net.minecraft.text.Text; @@ -27,8 +27,8 @@ public class PlayerListHudMixin { @Shadow private Text footer; - @Inject(at = @At("HEAD"), method = "render(Lnet/minecraft/client/util/math/MatrixStack;ILnet/minecraft/scoreboard/Scoreboard;Lnet/minecraft/scoreboard/ScoreboardObjective;)V", cancellable = true) - public void skyblocker$renderTabHud(MatrixStack ms, int scaledW, Scoreboard sb, ScoreboardObjective sbo, + @Inject(at = @At("HEAD"), method = "render(Lnet/minecraft/client/gui/DrawContext;ILnet/minecraft/scoreboard/Scoreboard;Lnet/minecraft/scoreboard/ScoreboardObjective;)V", cancellable = true) + public void skyblocker$renderTabHud(DrawContext context, int scaledW, Scoreboard sb, ScoreboardObjective sbo, CallbackInfo info) { if (!Utils.isOnSkyblock() @@ -47,7 +47,7 @@ public class PlayerListHudMixin { int h = MinecraftClient.getInstance().getWindow().getScaledHeight(); try { Screen screen = Screen.getCorrect(w, h, footer); - screen.render(ms); + screen.render(context); info.cancel(); } catch (Exception e) { TabHud.LOGGER.error("Drawing default hud. Reason: Screen exception {}", e); diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/ScreenMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/ScreenMixin.java deleted file mode 100644 index 9389b792..00000000 --- a/src/main/java/me/xmrvizzy/skyblocker/mixin/ScreenMixin.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.xmrvizzy.skyblocker.mixin; - -import me.xmrvizzy.skyblocker.config.SkyblockerConfig; -import me.xmrvizzy.skyblocker.utils.Utils; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.item.ItemStack; -import net.minecraft.text.Text; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(Screen.class) -public abstract class ScreenMixin { - @Inject(at = @At("HEAD"), method = "renderTooltip(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/item/ItemStack;II)V", cancellable = true) - public void skyblocker$renderTooltip(MatrixStack matrices, ItemStack itemStack, int x, int y, CallbackInfo ci) { - Text stackName = itemStack.getName(); - String strName = stackName.getString(); - if (Utils.isOnSkyblock() && SkyblockerConfig.get().general.hideEmptyTooltips && strName.equals(" ")) { - ci.cancel(); - } - } -} diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/BeaconBlockEntityRendererInvoker.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/BeaconBlockEntityRendererInvoker.java new file mode 100644 index 00000000..ff7c7cbc --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/BeaconBlockEntityRendererInvoker.java @@ -0,0 +1,16 @@ +package me.xmrvizzy.skyblocker.mixin.accessor; + +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.block.entity.BeaconBlockEntityRenderer; +import net.minecraft.client.util.math.MatrixStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(BeaconBlockEntityRenderer.class) +public interface BeaconBlockEntityRendererInvoker { + @SuppressWarnings("unused") + @Invoker("renderBeam") + static void renderBeam(MatrixStack matrices, VertexConsumerProvider vertexConsumers, float tickDelta, long worldTime, int yOffset, int maxY, float[] color) { + throw new IllegalStateException("Mixin invoker failed to apply."); + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/BackpackPreview.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/BackpackPreview.java index 4820bc0f..d89a18e0 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/BackpackPreview.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/BackpackPreview.java @@ -7,7 +7,7 @@ import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.network.PlayerListEntry; @@ -27,7 +27,7 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class BackpackPreview extends DrawableHelper { +public class BackpackPreview { private static final Identifier TEXTURE = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/inventory_background.png"); private static final BackpackPreview instance = new BackpackPreview(); private static final Pattern PROFILE_PATTERN = Pattern.compile("Profile: ([a-zA-Z]+)"); @@ -50,7 +50,7 @@ public class BackpackPreview extends DrawableHelper { } public static void tick() { - Utils.sbChecker(); // force update isOnSkyblock to prevent crash on disconnect + Utils.update(); // force update isOnSkyblock to prevent crash on disconnect if (Utils.isOnSkyblock()) { // save all dirty storages saveStorage(); @@ -135,7 +135,7 @@ public class BackpackPreview extends DrawableHelper { } } - public static boolean renderPreview(MatrixStack matrices, int index, int mouseX, int mouseY) { + public static boolean renderPreview(DrawContext context, int index, int mouseX, int mouseY) { if (index >= 9 && index < 18) index -= 9; else if (index >= 27 && index < 45) index -= 18; else return false; @@ -149,12 +149,13 @@ public class BackpackPreview extends DrawableHelper { RenderSystem.disableDepthTest(); RenderSystem.setShaderTexture(0, TEXTURE); - BackpackPreview.drawTexture(matrices, x, y, 0, 0, 176, 7); + context.drawTexture(TEXTURE, x, y, 0, 0, 176, 7); for (int i = 0; i < rows; ++i) - BackpackPreview.drawTexture(matrices, x, y + i * 18 + 7, 0, 7, 176, 18); - BackpackPreview.drawTexture(matrices, x, y + rows * 18 + 7, 0, 25, 176, 7); + context.drawTexture(TEXTURE, x, y + i * 18 + 7, 0, 7, 176, 18); + context.drawTexture(TEXTURE, x, y + rows * 18 + 7, 0, 25, 176, 7); RenderSystem.enableDepthTest(); + MatrixStack matrices = context.getMatrices(); ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer(); TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; for (int i = 9; i < storage[index].size(); ++i) { @@ -162,8 +163,8 @@ public class BackpackPreview extends DrawableHelper { int itemY = y + (i - 9) / 9 * 18 + 8; matrices.push(); matrices.translate(0, 0, 200); - itemRenderer.renderInGui(matrices, storage[index].getStack(i), itemX, itemY); - itemRenderer.renderGuiItemOverlay(matrices, textRenderer, storage[index].getStack(i), itemX, itemY); + context.drawItem(storage[index].getStack(i), itemX, itemY); + context.drawItemInSlot(textRenderer, storage[index].getStack(i), itemX, itemY); matrices.pop(); } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/FairySouls.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/FairySouls.java new file mode 100644 index 00000000..ccffdcca --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/FairySouls.java @@ -0,0 +1,175 @@ +package me.xmrvizzy.skyblocker.skyblock; + +import com.google.common.collect.ImmutableSet; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import me.xmrvizzy.skyblocker.SkyblockerMod; +import me.xmrvizzy.skyblocker.config.SkyblockerConfig; +import me.xmrvizzy.skyblocker.utils.NEURepo; +import me.xmrvizzy.skyblocker.utils.RenderHelper; +import me.xmrvizzy.skyblocker.utils.Utils; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; +import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; +import net.minecraft.client.MinecraftClient; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.text.Text; +import net.minecraft.util.DyeColor; +import net.minecraft.util.math.BlockPos; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.util.*; +import java.util.concurrent.CompletableFuture; + +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; + +public class FairySouls { + private static final Logger LOGGER = LoggerFactory.getLogger(FairySouls.class); + private static CompletableFuture<Void> fairySoulsLoaded; + private static final Map<String, Set<BlockPos>> fairySouls = new HashMap<>(); + private static final Map<String, Map<String, Set<BlockPos>>> foundFairies = new HashMap<>(); + + public static void init() { + fairySoulsLoaded = NEURepo.runAsyncAfterLoad(() -> { + try { + BufferedReader reader = new BufferedReader(new FileReader(NEURepo.LOCAL_REPO_DIR.resolve("constants").resolve("fairy_souls.json").toFile())); + for (Map.Entry<String, JsonElement> fairySoulJson : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) { + if (fairySoulJson.getKey().equals("//") || fairySoulJson.getKey().equals("Max Souls")) { + continue; + } + ImmutableSet.Builder<BlockPos> fairySoulsForLocation = ImmutableSet.builder(); + for (JsonElement fairySoul : fairySoulJson.getValue().getAsJsonArray().asList()) { + fairySoulsForLocation.add(parseBlockPos(fairySoul)); + } + fairySouls.put(fairySoulJson.getKey(), fairySoulsForLocation.build()); + } + reader = new BufferedReader(new FileReader(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json").toFile())); + for (Map.Entry<String, JsonElement> foundFairiesForProfileJson : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) { + Map<String, Set<BlockPos>> foundFairiesForProfile = new HashMap<>(); + for (Map.Entry<String, JsonElement> foundFairiesForLocationJson : foundFairiesForProfileJson.getValue().getAsJsonObject().asMap().entrySet()) { + Set<BlockPos> foundFairiesForLocation = new HashSet<>(); + for (JsonElement foundFairy : foundFairiesForLocationJson.getValue().getAsJsonArray().asList()) { + foundFairiesForLocation.add(parseBlockPos(foundFairy)); + } + foundFairiesForProfile.put(foundFairiesForLocationJson.getKey(), foundFairiesForLocation); + } + foundFairies.put(foundFairiesForProfileJson.getKey(), foundFairiesForProfile); + } + reader.close(); + } catch (IOException e) { + LOGGER.error("Failed to load found fairy souls", e); + } catch (Exception e) { + LOGGER.error("Encountered unknown exception loading fairy souls", e); + } + }); + ClientLifecycleEvents.CLIENT_STOPPING.register(FairySouls::saveFoundFairySouls); + WorldRenderEvents.AFTER_TRANSLUCENT.register(FairySouls::render); + ClientReceiveMessageEvents.GAME.register(FairySouls::onChatMessage); + ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(literal(SkyblockerMod.NAMESPACE) + .then(literal("fairySouls") + .then(literal("markAllInCurrentIslandFound").executes(context -> { + FairySouls.markAllFairiesFound(); + context.getSource().sendFeedback(Text.translatable("skyblocker.fairySouls.markAllFound")); + return 1; + })) + .then(literal("markAllInCurrentIslandMissing").executes(context -> { + FairySouls.markAllFairiesNotFound(); + context.getSource().sendFeedback(Text.translatable("skyblocker.fairySouls.markAllMissing")); + return 1; + }))))); + } + + private static BlockPos parseBlockPos(JsonElement posJson) { + String[] posArray = posJson.getAsString().split(","); + return new BlockPos(Integer.parseInt(posArray[0]), Integer.parseInt(posArray[1]), Integer.parseInt(posArray[2])); + } + + public static void saveFoundFairySouls(MinecraftClient client) { + try { + BufferedWriter writer = new BufferedWriter(new FileWriter(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json").toFile())); + JsonObject foundFairiesJson = new JsonObject(); + for (Map.Entry<String, Map<String, Set<BlockPos>>> foundFairiesForProfile : foundFairies.entrySet()) { + JsonObject foundFairiesForProfileJson = new JsonObject(); + for (Map.Entry<String, Set<BlockPos>> foundFairiesForLocation : foundFairiesForProfile.getValue().entrySet()) { + JsonArray foundFairiesForLocationJson = new JsonArray(); + for (BlockPos foundFairy : foundFairiesForLocation.getValue()) { + foundFairiesForLocationJson.add(foundFairy.getX() + "," + foundFairy.getY() + "," + foundFairy.getZ()); + } + foundFairiesForProfileJson.add(foundFairiesForLocation.getKey(), foundFairiesForLocationJson); + } + foundFairiesJson.add(foundFairiesForProfile.getKey(), foundFairiesForProfileJson); + } + SkyblockerMod.GSON.toJson(foundFairiesJson, writer); + writer.close(); + } catch (IOException e) { + LOGGER.error("Failed to write found fairy souls to file."); + } + } + + public static void render(WorldRenderContext context) { + if (SkyblockerConfig.get().general.fairySouls.enableFairySoulsHelper && fairySoulsLoaded.isDone() && fairySouls.containsKey(Utils.getLocationRaw())) { + for (BlockPos fairySoul : fairySouls.get(Utils.getLocationRaw())) { + float[] colorComponents = isFairySoulNotFound(fairySoul) ? DyeColor.GREEN.getColorComponents() : DyeColor.RED.getColorComponents(); + RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, fairySoul, colorComponents, 0.5F); + } + } + } + + private static boolean isFairySoulNotFound(BlockPos fairySoul) { + Map<String, Set<BlockPos>> foundFairiesForProfile = foundFairies.get(Utils.getProfile()); + if (foundFairiesForProfile == null) { + return true; + } + Set<BlockPos> foundFairiesForProfileAndLocation = foundFairiesForProfile.get(Utils.getLocationRaw()); + if (foundFairiesForProfileAndLocation == null) { + return true; + } + return !foundFairiesForProfileAndLocation.contains(fairySoul); + } + + public static void onChatMessage(Text text, boolean overlay) { + String message = text.getString(); + if (message.equals("You have already found that Fairy Soul!") || message.equals("SOUL! You found a Fairy Soul!")) { + markClosestFairyFound(); + } + } + + private static void markClosestFairyFound() { + PlayerEntity player = MinecraftClient.getInstance().player; + if (player == null) { + LOGGER.warn("Failed to mark closest fairy soul as found because player is null."); + return; + } + fairySouls.get(Utils.getLocationRaw()).stream().filter(FairySouls::isFairySoulNotFound).min(Comparator.comparingDouble(fairySoul -> fairySoul.getSquaredDistance(player.getPos()))).ifPresent(fairySoul -> { + initializeFoundFairiesForCurrentProfileAndLocation(); + foundFairies.get(Utils.getProfile()).get(Utils.getLocationRaw()).add(fairySoul); + }); + } + + public static void markAllFairiesFound() { + initializeFoundFairiesForCurrentProfileAndLocation(); + foundFairies.get(Utils.getProfile()).get(Utils.getLocationRaw()).addAll(fairySouls.get(Utils.getLocationRaw())); + } + + public static void markAllFairiesNotFound() { + Map<String, Set<BlockPos>> foundFairiesForProfile = foundFairies.get(Utils.getProfile()); + if (foundFairiesForProfile != null) { + foundFairiesForProfile.remove(Utils.getLocationRaw()); + } + } + + private static void initializeFoundFairiesForCurrentProfileAndLocation() { + initializeFoundFairiesForProfileAndLocation(Utils.getProfile(), Utils.getLocationRaw()); + } + + private static void initializeFoundFairiesForProfileAndLocation(String profile, String location) { + foundFairies.computeIfAbsent(profile, profileKey -> new HashMap<>()); + foundFairies.get(profile).computeIfAbsent(location, locationKey -> new HashSet<>()); + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/FancyStatusBars.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/FancyStatusBars.java index 05b57410..6af06e6d 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/FancyStatusBars.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/FancyStatusBars.java @@ -1,15 +1,13 @@ package me.xmrvizzy.skyblocker.skyblock; -import com.mojang.blaze3d.systems.RenderSystem; import me.xmrvizzy.skyblocker.SkyblockerMod; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawableHelper; -import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.client.gui.DrawContext; import net.minecraft.util.Identifier; -public class FancyStatusBars extends DrawableHelper { +public class FancyStatusBars { private static final Identifier BARS = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/bars.png"); private final MinecraftClient client = MinecraftClient.getInstance(); @@ -39,7 +37,7 @@ public class FancyStatusBars extends DrawableHelper { return (100 * value) / max; } - public boolean render(MatrixStack matrices, int scaledWidth, int scaledHeight) { + public boolean render(DrawContext context, int scaledWidth, int scaledHeight) { var player = client.player; if (!SkyblockerConfig.get().general.bars.enableBars || player == null) return false; @@ -72,11 +70,10 @@ public class FancyStatusBars extends DrawableHelper { moveBar(i, configAnchorNum); } - RenderSystem.setShaderTexture(0, BARS); for (var bar : bars) - bar.draw(matrices); + bar.draw(context); for (var bar : bars) - bar.drawText(matrices); + bar.drawText(context); return true; } @@ -143,32 +140,32 @@ public class FancyStatusBars extends DrawableHelper { this.text = val; } - public void draw(MatrixStack matrices) { + public void draw(DrawContext context) { // Dont draw if anchorNum is outside of range if (anchorNum < 0 || anchorNum > 2) return; // Draw the icon for the bar - drawTexture(matrices, anchorsX[anchorNum] + offsetX, anchorsY[anchorNum], 0, v, 9, 9); + context.drawTexture(BARS, anchorsX[anchorNum] + offsetX, anchorsY[anchorNum], 0, v, 9, 9); // Draw the background for the bar - drawTexture(matrices, anchorsX[anchorNum] + offsetX + 10, anchorsY[anchorNum], 10, v, 2, 9); + context.drawTexture(BARS, anchorsX[anchorNum] + offsetX + 10, anchorsY[anchorNum], 10, v, 2, 9); for (int i = 2; i < bar_width - 2; i += 58) - drawTexture(matrices, anchorsX[anchorNum] + offsetX + 10 + i, anchorsY[anchorNum], 12, v, Math.min(58, bar_width - 2 - i), 9); - drawTexture(matrices, anchorsX[anchorNum] + offsetX + 10 + bar_width - 2, anchorsY[anchorNum], 70, v, 2, 9); + context.drawTexture(BARS, anchorsX[anchorNum] + offsetX + 10 + i, anchorsY[anchorNum], 12, v, Math.min(58, bar_width - 2 - i), 9); + context.drawTexture(BARS, anchorsX[anchorNum] + offsetX + 10 + bar_width - 2, anchorsY[anchorNum], 70, v, 2, 9); // Draw the filled part of the bar for (int i = 0; i < fill.length; i++) { int fill_width = this.fill[i] * (bar_width - 2) / 100; if (fill_width >= 1) - drawTexture(matrices, anchorsX[anchorNum] + offsetX + 11, anchorsY[anchorNum], 72 + i*60, v, 1, 9); + context.drawTexture(BARS, anchorsX[anchorNum] + offsetX + 11, anchorsY[anchorNum], 72 + i*60, v, 1, 9); for (int j = 1; j < fill_width - 1; j += 58) - drawTexture(matrices, anchorsX[anchorNum] + offsetX + 11 + j, anchorsY[anchorNum], 73 + i*60, v, Math.min(58, fill_width - 1 - j), 9); + context.drawTexture(BARS, anchorsX[anchorNum] + offsetX + 11 + j, anchorsY[anchorNum], 73 + i*60, v, Math.min(58, fill_width - 1 - j), 9); if (fill_width == bar_width - 2) - drawTexture(matrices, anchorsX[anchorNum] + offsetX + 11 + fill_width - 1, anchorsY[anchorNum], 131 + i*60, v, 1, 9); + context.drawTexture(BARS, anchorsX[anchorNum] + offsetX + 11 + fill_width - 1, anchorsY[anchorNum], 131 + i*60, v, 1, 9); } } - public void drawText(MatrixStack matrices) { + public void drawText(DrawContext context) { // Dont draw if anchorNum is outside of range if (anchorNum < 0 || anchorNum > 2) return; @@ -179,10 +176,10 @@ public class FancyStatusBars extends DrawableHelper { final int[] offsets = new int[]{-1, 1}; for (int i : offsets) { - textRenderer.draw(matrices, text, (float) (x + i), (float) y, 0); - textRenderer.draw(matrices, text, (float) x, (float) (y + i), 0); + context.drawText(textRenderer, text, x + i, y, 0, false); + context.drawText(textRenderer, text, x, y + i, 0, false); } - textRenderer.draw(matrices, text, (float) x, (float) y, text_color); + context.drawText(textRenderer, text, x, y, text_color, false); } } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/FishingHelper.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/FishingHelper.java index 790b27bf..d82464e1 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/FishingHelper.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/FishingHelper.java @@ -8,8 +8,10 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.FishingRodItem; import net.minecraft.item.ItemStack; import net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket; +import net.minecraft.sound.SoundEvent; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import net.minecraft.util.Identifier; import net.minecraft.util.TypedActionResult; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; @@ -51,6 +53,7 @@ public class FishingHelper { if (Math.abs(normalYawVector.x * soundToFishHook.z - normalYawVector.z * soundToFishHook.x) < 0.2D && Math.abs(normalYawVector.dotProduct(soundToFishHook)) < 4D && player.getPos().squaredDistanceTo(packet.getX(), packet.getY(), packet.getZ()) > 1D) { client.inGameHud.setTitleTicks(0, 10, 5); client.inGameHud.setTitle(Text.translatable("skyblocker.fishing.reelNow").formatted(Formatting.GREEN)); + player.playSound(SoundEvent.of(new Identifier("minecraft", "entity.experience_orb.pickup")), 100f, 0.1f); reset(); } } else { diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/api/RepositoryUpdate.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/api/RepositoryUpdate.java deleted file mode 100644 index e08cb1c0..00000000 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/api/RepositoryUpdate.java +++ /dev/null @@ -1,62 +0,0 @@ -package me.xmrvizzy.skyblocker.skyblock.api; - -import me.xmrvizzy.skyblocker.skyblock.itemlist.ItemRegistry; -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.text.Text; - -import java.io.File; -import java.nio.file.Files; -import java.util.concurrent.CompletableFuture; - -public class RepositoryUpdate { - public static final MinecraftClient client = MinecraftClient.getInstance(); - - /** - * Adds command to update repository manually from ingame. - * <p></p> - * TODO A button could be added to the settings menu that will trigger this command. - */ - public static void init(){ - ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register( - ClientCommandManager.literal("skyblocker") - .then(ClientCommandManager.literal("updaterepository") - .executes(context -> { - updateRepository(); - return 1; - }) - ) - ) - ); - - } - - public static void updateRepository() { - CompletableFuture.runAsync(() -> { - try { - ItemRegistry.filesImported = false; - File dir = ItemRegistry.LOCAL_ITEM_REPO_DIR.toFile(); - recursiveDelete(dir); - } catch (Exception ex) { - if (client.player != null) - client.player.sendMessage( - Text.translatable("skyblocker.updaterepository.failed") - , false - ); - return; - } - - ItemRegistry.init(); - }); - } - - private static void recursiveDelete(File dir) { - if (dir.isDirectory() && !Files.isSymbolicLink(dir.toPath())) { - for (File child : dir.listFiles()) { - recursiveDelete(child); - } - } - dir.delete(); - } -} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/CroesusHelper.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/CroesusHelper.java index ec3655f0..2d868782 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/CroesusHelper.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/CroesusHelper.java @@ -11,20 +11,23 @@ import java.util.Map; public class CroesusHelper extends ContainerSolver { - public CroesusHelper() { super("^Croesus$"); } + public CroesusHelper() { + super("^Croesus$"); + } @Override - public boolean isEnabled() { + protected boolean isEnabled() { return SkyblockerConfig.get().locations.dungeons.croesusHelper; } @Override - public List<ColorHighlight> getColors(String[] groups, Map<Integer, ItemStack> slots) { + protected List<ColorHighlight> getColors(String[] groups, Map<Integer, ItemStack> slots) { List<ColorHighlight> highlights = new ArrayList<>(); for (Map.Entry<Integer, ItemStack> entry : slots.entrySet()) { ItemStack stack = entry.getValue(); - if (stack != null && stack.getNbt() != null && stack.getNbt().toString().contains("opened")) - highlights.add(new ColorHighlight(entry.getKey(), GRAY_HIGHLIGHT)); + if (stack != null && stack.getNbt() != null && stack.getNbt().toString().contains("opened")) { + highlights.add(ColorHighlight.gray(entry.getKey())); + } } return highlights; } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMap.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMap.java index e5441b5c..2a97d0ee 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMap.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMap.java @@ -2,14 +2,13 @@ package me.xmrvizzy.skyblocker.skyblock.dungeon; import org.apache.commons.lang3.StringUtils; -import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.brigadier.Command; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; 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.gui.DrawableHelper; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.render.MapRenderer; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.util.math.MatrixStack; @@ -50,11 +49,10 @@ public class DungeonMap { } } - public static void renderHUDMap(MatrixStack matrices, int x, int y) { + public static void renderHUDMap(DrawContext context, int x, int y) { float scaling = SkyblockerConfig.get().locations.dungeons.mapScaling; int size = (int) (128 * scaling); - RenderSystem.setShaderTexture(0, MAP_BACKGROUND); - DrawableHelper.drawTexture(matrices, x, y, 0, 0, size, size, size, size); + context.drawTexture(MAP_BACKGROUND, x, y, 0, 0, size, size, size, size); } public static void init() { diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java index 8fba6a7a..ffd7a8b6 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java @@ -5,8 +5,8 @@ import java.awt.Color; import me.shedaniel.autoconfig.AutoConfig; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; import me.xmrvizzy.skyblocker.utils.RenderUtils; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.Text; public class DungeonMapConfigScreen extends Screen { @@ -19,11 +19,11 @@ public class DungeonMapConfigScreen extends Screen { } @Override - public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { - super.render(matrices, mouseX, mouseY, delta); - renderBackground(matrices); - DungeonMap.renderHUDMap(matrices, hudX, hudY); - drawCenteredTextWithShadow(matrices, textRenderer, "Right Click To Reset Position", width / 2, height / 2, Color.GRAY.getRGB()); + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + super.render(context, mouseX, mouseY, delta); + renderBackground(context); + DungeonMap.renderHUDMap(context, hudX, hudY); + context.drawCenteredTextWithShadow(textRenderer, "Right Click To Reset Position", width / 2, height / 2, Color.GRAY.getRGB()); } @Override diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/LividColor.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/LividColor.java index 276a41b6..4701c485 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/LividColor.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/LividColor.java @@ -11,11 +11,10 @@ public class LividColor { private static int tenTicks = 0; public static void init() { - ClientReceiveMessageEvents.ALLOW_GAME.register((message, overlay) -> { + ClientReceiveMessageEvents.GAME.register((message, overlay) -> { if (SkyblockerConfig.get().locations.dungeons.lividColor.enableLividColor && message.getString().equals("[BOSS] Livid: I respect you for making it to here, but I'll be your undoing.")) { tenTicks = 8; } - return true; }); } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/ColorTerminal.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/ColorTerminal.java index 0bfc0d60..add30907 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/ColorTerminal.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/ColorTerminal.java @@ -6,7 +6,6 @@ import me.xmrvizzy.skyblocker.gui.ContainerSolver; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; -// import net.minecraft.registry.Registry; import net.minecraft.registry.Registries; import net.minecraft.util.DyeColor; import net.minecraft.util.Identifier; @@ -27,27 +26,28 @@ public class ColorTerminal extends ContainerSolver { } @Override - public boolean isEnabled() { + protected boolean isEnabled() { targetColor = null; return SkyblockerConfig.get().locations.dungeons.terminals.solveColor; } @Override - public List<ColorHighlight> getColors(String[] groups, Map<Integer, ItemStack> slots) { + protected List<ColorHighlight> getColors(String[] groups, Map<Integer, ItemStack> slots) { trimEdges(slots, 6); List<ColorHighlight> highlights = new ArrayList<>(); String colorString = groups[0]; - if(targetColor == null) { + if (targetColor == null) { targetColor = colorFromName.get(colorString); - if(targetColor == null) { + if (targetColor == null) { LOGGER.error("[Skyblocker] Couldn't find dye color corresponding to \"" + colorString + "\""); return Collections.emptyList(); } } - for(Map.Entry<Integer, ItemStack> slot : slots.entrySet()) { + for (Map.Entry<Integer, ItemStack> slot : slots.entrySet()) { ItemStack itemStack = slot.getValue(); - if(!itemStack.hasEnchantments() && targetColor.equals(itemColor.get(itemStack.getItem()))) - highlights.add(new ColorHighlight(slot.getKey(), GREEN_HIGHLIGHT)); + if (!itemStack.hasEnchantments() && targetColor.equals(itemColor.get(itemStack.getItem()))) { + highlights.add(ColorHighlight.green(slot.getKey())); + } } return highlights; } @@ -63,7 +63,6 @@ public class ColorTerminal extends ContainerSolver { itemColor = new HashMap<>(); for (DyeColor color : DyeColor.values()) for (String item : new String[]{"dye", "wool", "stained_glass", "terracotta"}) - // itemColor.put(Registry.ITEM.get(new Identifier(color.getName() + '_' + item)), color); itemColor.put(Registries.ITEM.get(new Identifier(color.getName() + '_' + item)), color); itemColor.put(Items.BONE_MEAL, DyeColor.WHITE); itemColor.put(Items.LAPIS_LAZULI, DyeColor.BLUE); diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/OrderTerminal.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/OrderTerminal.java index 1cf0dcfc..3b4e1c50 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/OrderTerminal.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/OrderTerminal.java @@ -21,14 +21,14 @@ public class OrderTerminal extends ContainerSolver { } @Override - public boolean isEnabled() { + protected boolean isEnabled() { orderedSlots = null; currentNum = 0; return SkyblockerConfig.get().locations.dungeons.terminals.solveOrder; } @Override - public List<ColorHighlight> getColors(String[] groups, Map<Integer, ItemStack> slots) { + protected List<ColorHighlight> getColors(String[] groups, Map<Integer, ItemStack> slots) { if(orderedSlots == null && !orderSlots(slots)) return Collections.emptyList(); while(currentNum < PANES_NUM && Items.LIME_STAINED_GLASS_PANE.equals(slots.get(orderedSlots[currentNum]).getItem())) diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/StartsWithTerminal.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/StartsWithTerminal.java index 26d2a2c4..18326254 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/StartsWithTerminal.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/terminal/StartsWithTerminal.java @@ -15,19 +15,20 @@ public class StartsWithTerminal extends ContainerSolver { } @Override - public boolean isEnabled() { + protected boolean isEnabled() { return SkyblockerConfig.get().locations.dungeons.terminals.solveStartsWith; } @Override - public List<ColorHighlight> getColors(String[] groups, Map<Integer, ItemStack> slots) { + protected List<ColorHighlight> getColors(String[] groups, Map<Integer, ItemStack> slots) { trimEdges(slots, 6); String prefix = groups[0]; List<ColorHighlight> highlights = new ArrayList<>(); - for(Map.Entry<Integer, ItemStack> slot : slots.entrySet()) { + for (Map.Entry<Integer, ItemStack> slot : slots.entrySet()) { ItemStack stack = slot.getValue(); - if(!stack.hasEnchantments() && stack.getName().getString().startsWith(prefix)) - highlights.add(new ColorHighlight(slot.getKey(), GREEN_HIGHLIGHT)); + if (!stack.hasEnchantments() && stack.getName().getString().startsWith(prefix)) { + highlights.add(ColorHighlight.green(slot.getKey())); + } } return highlights; } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHud.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHud.java index 15f9e58b..122f6c6c 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHud.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHud.java @@ -6,7 +6,7 @@ import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.Text; import net.minecraft.util.Formatting; @@ -49,35 +49,35 @@ public class DwarvenHud { return 1; }))))); - HudRenderCallback.EVENT.register((matrixStack, tickDelta) -> { + HudRenderCallback.EVENT.register((context, tickDelta) -> { if (!SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.enabled || client.options.playerListKey.isPressed() || client.player == null || commissionList.isEmpty()) { return; } - render(matrixStack, SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.x, SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.y, commissionList); + render(context, SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.x, SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.y, commissionList); }); } - public static void render(MatrixStack matrixStack, int hudX, int hudY, List<Commission> commissions) { + public static void render(DrawContext context, int hudX, int hudY, List<Commission> commissions) { switch(SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.style) { - case SIMPLE -> renderSimple(matrixStack, hudX, hudY, commissions); - case FANCY -> renderFancy(matrixStack, hudX, hudY, commissions); - case CLASSIC -> renderClassic(matrixStack, hudX, hudY, commissions); + case SIMPLE -> renderSimple(context, hudX, hudY, commissions); + case FANCY -> renderFancy(context, hudX, hudY, commissions); + case CLASSIC -> renderClassic(context, hudX, hudY, commissions); } } - public static void renderClassic(MatrixStack matrixStack, int hudX, int hudY, List<Commission> commissions) { + public static void renderClassic(DrawContext context, int hudX, int hudY, List<Commission> commissions) { if (SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.enableBackground) { - DrawableHelper.fill(matrixStack, hudX, hudY, hudX + 200, hudY + (20 * commissions.size()), 0x64000000); + context.fill(hudX, hudY, hudX + 200, hudY + (20 * commissions.size()), 0x64000000); } int y = 0; for (Commission commission : commissions) { - client.textRenderer - .drawWithShadow(matrixStack, + context + .drawTextWithShadow(client.textRenderer, Text.literal(commission.commission + ": ") .styled(style -> style.withColor(Formatting.AQUA)) .append(Text.literal(commission.progression) @@ -87,18 +87,18 @@ public class DwarvenHud { } } - public static void renderSimple(MatrixStack matrixStack, int hudX, int hudY, List<Commission> commissions) { + public static void renderSimple(DrawContext context, int hudX, int hudY, List<Commission> commissions) { CommsWidget cw = new CommsWidget(commissions, false); cw.setX(hudX); cw.setY(hudY); - cw.render(matrixStack, SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.enableBackground); + cw.render(context, SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.enableBackground); } - public static void renderFancy(MatrixStack matrixStack, int hudX, int hudY, List<Commission> commissions) { + public static void renderFancy(DrawContext context, int hudX, int hudY, List<Commission> commissions) { CommsWidget cw = new CommsWidget(commissions, true); cw.setX(hudX); cw.setY(hudY); - cw.render(matrixStack, SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.enableBackground); + cw.render(context, SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.enableBackground); } public static void update() { @@ -121,4 +121,4 @@ public class DwarvenHud { // steamroller tactics to get visibility from outside classes (CommsWidget) public static record Commission(String commission, String progression){} -} +}
\ No newline at end of file diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java index 2d0ba892..f91ed921 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java @@ -3,6 +3,7 @@ package me.xmrvizzy.skyblocker.skyblock.dwarven; import me.shedaniel.autoconfig.AutoConfig; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; import me.xmrvizzy.skyblocker.utils.RenderUtils; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.Text; @@ -19,11 +20,11 @@ public class DwarvenHudConfigScreen extends Screen { } @Override - public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { - super.render(matrices, mouseX, mouseY, delta); - renderBackground(matrices); - DwarvenHud.render(matrices, hudX, hudY, List.of(new DwarvenHud.Commission("Test Commission 1", "1%"), new DwarvenHud.Commission("Test Commission 2", "2%"))); - drawCenteredTextWithShadow(matrices, textRenderer, "Right Click To Reset Position", width / 2, height / 2, Color.GRAY.getRGB()); + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + super.render(context, mouseX, mouseY, delta); + renderBackground(context); + DwarvenHud.render(context, hudX, hudY, List.of(new DwarvenHud.Commission("Test Commission 1", "1%"), new DwarvenHud.Commission("Test Commission 2", "2%"))); + context.drawCenteredTextWithShadow(textRenderer, "Right Click To Reset Position", width / 2, height / 2, Color.GRAY.getRGB()); } @Override diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/experiment/ChronomatronSolver.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/experiment/ChronomatronSolver.java new file mode 100644 index 00000000..40793169 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/experiment/ChronomatronSolver.java @@ -0,0 +1,128 @@ +package me.xmrvizzy.skyblocker.skyblock.experiment; + +import com.google.common.collect.ImmutableMap; +import me.xmrvizzy.skyblocker.config.SkyblockerConfig; +import me.xmrvizzy.skyblocker.gui.ColorHighlight; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; +import net.minecraft.inventory.Inventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; + +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class ChronomatronSolver extends ExperimentSolver { + public static final ImmutableMap<Item, Item> TERRACOTTA_TO_GLASS = ImmutableMap.ofEntries( + new AbstractMap.SimpleImmutableEntry<>(Items.RED_TERRACOTTA, Items.RED_STAINED_GLASS), + new AbstractMap.SimpleImmutableEntry<>(Items.ORANGE_TERRACOTTA, Items.ORANGE_STAINED_GLASS), + new AbstractMap.SimpleImmutableEntry<>(Items.YELLOW_TERRACOTTA, Items.YELLOW_STAINED_GLASS), + new AbstractMap.SimpleImmutableEntry<>(Items.LIME_TERRACOTTA, Items.LIME_STAINED_GLASS), + new AbstractMap.SimpleImmutableEntry<>(Items.GREEN_TERRACOTTA, Items.GREEN_STAINED_GLASS), + new AbstractMap.SimpleImmutableEntry<>(Items.CYAN_TERRACOTTA, Items.CYAN_STAINED_GLASS), + new AbstractMap.SimpleImmutableEntry<>(Items.LIGHT_BLUE_TERRACOTTA, Items.LIGHT_BLUE_STAINED_GLASS), + new AbstractMap.SimpleImmutableEntry<>(Items.BLUE_TERRACOTTA, Items.BLUE_STAINED_GLASS), + new AbstractMap.SimpleImmutableEntry<>(Items.PURPLE_TERRACOTTA, Items.PURPLE_STAINED_GLASS), + new AbstractMap.SimpleImmutableEntry<>(Items.PINK_TERRACOTTA, Items.PINK_STAINED_GLASS) + ); + + private final List<Item> chronomatronSlots = new ArrayList<>(); + private int chronomatronChainLengthCount; + private int chronomatronCurrentSlot; + private int chronomatronCurrentOrdinal; + + public ChronomatronSolver() { + super("^Chronomatron \\(\\w+\\)$"); + } + + public List<Item> getChronomatronSlots() { + return chronomatronSlots; + } + + public int getChronomatronCurrentOrdinal() { + return chronomatronCurrentOrdinal; + } + + public int incrementChronomatronCurrentOrdinal() { + return ++chronomatronCurrentOrdinal; + } + + @Override + protected boolean isEnabled(SkyblockerConfig.Experiments experimentsConfig) { + return experimentsConfig.enableChronomatronSolver; + } + + @Override + protected void tick(Screen screen) { + if (isEnabled() && screen instanceof GenericContainerScreen genericContainerScreen && genericContainerScreen.getTitle().getString().startsWith("Chronomatron (")) { + switch (getState()) { + case REMEMBER -> { + Inventory inventory = genericContainerScreen.getScreenHandler().getInventory(); + if (chronomatronCurrentSlot == 0) { + for (int index = 10; index < 43; index++) { + if (inventory.getStack(index).hasEnchantments()) { + if (chronomatronSlots.size() <= chronomatronChainLengthCount) { + chronomatronSlots.add(TERRACOTTA_TO_GLASS.get(inventory.getStack(index).getItem())); + setState(State.WAIT); + } else { + chronomatronChainLengthCount++; + } + chronomatronCurrentSlot = index; + return; + } + } + } else if (!inventory.getStack(chronomatronCurrentSlot).hasEnchantments()) { + chronomatronCurrentSlot = 0; + } + } + case WAIT -> { + if (genericContainerScreen.getScreenHandler().getInventory().getStack(49).getName().getString().startsWith("Timer: ")) { + setState(State.SHOW); + } + } + case END -> { + String name = genericContainerScreen.getScreenHandler().getInventory().getStack(49).getName().getString(); + if (!name.startsWith("Timer: ")) { + if (name.equals("Remember the pattern!")) { + chronomatronChainLengthCount = 0; + chronomatronCurrentOrdinal = 0; + setState(State.REMEMBER); + } else { + reset(); + } + } + } + } + } else { + reset(); + } + } + + @Override + protected List<ColorHighlight> getColors(String[] groups, Map<Integer, ItemStack> slots) { + List<ColorHighlight> highlights = new ArrayList<>(); + if (getState() == State.SHOW && chronomatronSlots.size() > chronomatronCurrentOrdinal) { + for (Map.Entry<Integer, ItemStack> indexStack : slots.entrySet()) { + int index = indexStack.getKey(); + ItemStack stack = indexStack.getValue(); + Item item = chronomatronSlots.get(chronomatronCurrentOrdinal); + if (stack.isOf(item) || TERRACOTTA_TO_GLASS.get(stack.getItem()) == item) { + highlights.add(ColorHighlight.green(index)); + } + } + } + return highlights; + } + + @Override + protected void reset() { + super.reset(); + chronomatronSlots.clear(); + chronomatronChainLengthCount = 0; + chronomatronCurrentSlot = 0; + chronomatronCurrentOrdinal = 0; + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/experiment/ExperimentSolver.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/experiment/ExperimentSolver.java new file mode 100644 index 00000000..5dad908e --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/experiment/ExperimentSolver.java @@ -0,0 +1,59 @@ +package me.xmrvizzy.skyblocker.skyblock.experiment; + +import me.xmrvizzy.skyblocker.config.SkyblockerConfig; +import me.xmrvizzy.skyblocker.gui.ContainerSolver; +import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; +import net.minecraft.item.ItemStack; + +import java.util.HashMap; +import java.util.Map; + +public abstract class ExperimentSolver extends ContainerSolver { + public enum State { + REMEMBER, WAIT, SHOW, END + } + + private State state = State.REMEMBER; + private final Map<Integer, ItemStack> slots = new HashMap<>(); + + protected ExperimentSolver(String containerName) { + super(containerName); + } + + public State getState() { + return state; + } + + public void setState(State state) { + this.state = state; + } + + public Map<Integer, ItemStack> getSlots() { + return slots; + } + + @Override + protected final boolean isEnabled() { + return isEnabled(SkyblockerConfig.get().general.experiments); + } + + protected abstract boolean isEnabled(SkyblockerConfig.Experiments experimentsConfig); + + @Override + protected void start(GenericContainerScreen screen) { + super.start(screen); + state = State.REMEMBER; + ScreenEvents.afterTick(screen).register(this::tick); + } + + @Override + protected void reset() { + super.reset(); + state = State.REMEMBER; + slots.clear(); + } + + protected abstract void tick(Screen screen); +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/experiment/SuperpairsSolver.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/experiment/SuperpairsSolver.java new file mode 100644 index 00000000..9f6e8b2a --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/experiment/SuperpairsSolver.java @@ -0,0 +1,81 @@ +package me.xmrvizzy.skyblocker.skyblock.experiment; + +import me.xmrvizzy.skyblocker.config.SkyblockerConfig; +import me.xmrvizzy.skyblocker.gui.ColorHighlight; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; + +import java.util.*; + +public class SuperpairsSolver extends ExperimentSolver { + private int superpairsPrevClickedSlot; + private ItemStack superpairsCurrentSlot; + private final Set<Integer> superpairsDuplicatedSlots = new HashSet<>(); + + public SuperpairsSolver() { + super("^Superpairs \\(\\w+\\)$"); + } + + public void setSuperpairsPrevClickedSlot(int superpairsPrevClickedSlot) { + this.superpairsPrevClickedSlot = superpairsPrevClickedSlot; + } + + public void setSuperpairsCurrentSlot(ItemStack superpairsCurrentSlot) { + this.superpairsCurrentSlot = superpairsCurrentSlot; + } + + @Override + protected boolean isEnabled(SkyblockerConfig.Experiments experimentsConfig) { + return experimentsConfig.enableSuperpairsSolver; + } + + @Override + protected void start(GenericContainerScreen screen) { + super.start(screen); + setState(State.SHOW); + } + + @Override + protected void tick(Screen screen) { + if (isEnabled() && screen instanceof GenericContainerScreen genericContainerScreen && genericContainerScreen.getTitle().getString().startsWith("Superpairs (")) { + if (getState() == State.SHOW) { + if (genericContainerScreen.getScreenHandler().getInventory().getStack(4).isOf(Items.CAULDRON)) { + reset(); + } else if (getSlots().get(superpairsPrevClickedSlot) == null) { + ItemStack itemStack = genericContainerScreen.getScreenHandler().getInventory().getStack(superpairsPrevClickedSlot); + if (!(itemStack.isOf(Items.CYAN_STAINED_GLASS) || itemStack.isOf(Items.BLACK_STAINED_GLASS_PANE) || itemStack.isOf(Items.AIR))) { + getSlots().entrySet().stream().filter((entry -> ItemStack.areEqual(entry.getValue(), itemStack))).findAny().ifPresent(entry -> superpairsDuplicatedSlots.add(entry.getKey())); + getSlots().put(superpairsPrevClickedSlot, itemStack); + superpairsCurrentSlot = itemStack; + } + } + } + } else { + reset(); + } + } + + @Override + protected List<ColorHighlight> getColors(String[] groups, Map<Integer, ItemStack> displaySlots) { + List<ColorHighlight> highlights = new ArrayList<>(); + if (getState() == State.SHOW) { + for (Map.Entry<Integer, ItemStack> indexStack : displaySlots.entrySet()) { + int index = indexStack.getKey(); + ItemStack displayStack = indexStack.getValue(); + ItemStack stack = getSlots().get(index); + if (stack != null && !ItemStack.areEqual(stack, displayStack)) { + if (ItemStack.areEqual(superpairsCurrentSlot, stack) && displayStack.getName().getString().equals("Click a second button!")) { + highlights.add(ColorHighlight.green(index)); + } else if (superpairsDuplicatedSlots.contains(index)) { + highlights.add(ColorHighlight.yellow(index)); + } else { + highlights.add(ColorHighlight.red(index)); + } + } + } + } + return highlights; + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/experiment/UltrasequencerSolver.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/experiment/UltrasequencerSolver.java new file mode 100644 index 00000000..45d6c0c6 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/experiment/UltrasequencerSolver.java @@ -0,0 +1,80 @@ +package me.xmrvizzy.skyblocker.skyblock.experiment; + +import me.xmrvizzy.skyblocker.config.SkyblockerConfig; +import me.xmrvizzy.skyblocker.gui.ColorHighlight; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; +import net.minecraft.inventory.Inventory; +import net.minecraft.item.ItemStack; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class UltrasequencerSolver extends ExperimentSolver { + private int ultrasequencerNextSlot; + + public UltrasequencerSolver() { + super("^Ultrasequencer \\(\\w+\\)$"); + } + + public int getUltrasequencerNextSlot() { + return ultrasequencerNextSlot; + } + + public void setUltrasequencerNextSlot(int ultrasequencerNextSlot) { + this.ultrasequencerNextSlot = ultrasequencerNextSlot; + } + + @Override + protected boolean isEnabled(SkyblockerConfig.Experiments experimentsConfig) { + return experimentsConfig.enableUltrasequencerSolver; + } + + @Override + protected void tick(Screen screen) { + if (isEnabled() && screen instanceof GenericContainerScreen genericContainerScreen && genericContainerScreen.getTitle().getString().startsWith("Ultrasequencer (")) { + switch (getState()) { + case REMEMBER -> { + Inventory inventory = genericContainerScreen.getScreenHandler().getInventory(); + if (inventory.getStack(49).getName().getString().equals("Remember the pattern!")) { + for (int index = 9; index < 45; index++) { + ItemStack itemStack = inventory.getStack(index); + String name = itemStack.getName().getString(); + if (name.matches("\\d+")) { + if (name.equals("1")) { + ultrasequencerNextSlot = index; + } + getSlots().put(index, itemStack); + } + } + setState(State.WAIT); + } + } + case WAIT -> { + if (genericContainerScreen.getScreenHandler().getInventory().getStack(49).getName().getString().startsWith("Timer: ")) { + setState(State.SHOW); + } + } + case END -> { + String name = genericContainerScreen.getScreenHandler().getInventory().getStack(49).getName().getString(); + if (!name.startsWith("Timer: ")) { + if (name.equals("Remember the pattern!")) { + getSlots().clear(); + setState(State.REMEMBER); + } else { + reset(); + } + } + } + } + } else { + reset(); + } + } + + @Override + protected List<ColorHighlight> getColors(String[] groups, Map<Integer, ItemStack> slots) { + return getState() == State.SHOW && ultrasequencerNextSlot != 0 ? List.of(ColorHighlight.green(ultrasequencerNextSlot)) : new ArrayList<>(); + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemListWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemListWidget.java index d9acc75c..3a1f91d3 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemListWidget.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemListWidget.java @@ -5,12 +5,11 @@ import me.xmrvizzy.skyblocker.mixin.RecipeBookWidgetAccessor; 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.Drawable; -import net.minecraft.client.gui.DrawableHelper; import net.minecraft.client.gui.Selectable; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.client.render.GameRenderer; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.screen.AbstractRecipeScreenHandler; import net.minecraft.text.Text; @@ -46,27 +45,26 @@ public class ItemListWidget extends RecipeBookWidget implements Drawable, Select } @Override - public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + public void render(DrawContext context, int mouseX, int mouseY, float delta) { if (this.isOpen()) { - matrices.push(); + MatrixStack matrices = context.getMatrices(); + matrices.push(); matrices.translate(0.0D, 0.0D, 100.0D); - RenderSystem.setShader(GameRenderer::getPositionTexProgram); - RenderSystem.setShaderTexture(0, TEXTURE); 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; - DrawableHelper.drawTexture(matrices, i, j, 1, 1, 147, 166); + context.drawTexture(TEXTURE, i, j, 1, 1, 147, 166); this.searchField = ((RecipeBookWidgetAccessor)this).getSearchField(); if (!ItemRegistry.filesImported && !this.searchField.isFocused() && this.searchField.getText().isEmpty()) { Text hintText = (Text.literal("Loading...")).formatted(Formatting.ITALIC).formatted(Formatting.GRAY); - drawTextWithShadow(matrices, this.client.textRenderer, hintText, i + 25, j + 14, -1); + 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); - drawTextWithShadow(matrices, this.client.textRenderer, hintText, i + 25, j + 14, -1); + context.drawTextWithShadow(this.client.textRenderer, hintText, i + 25, j + 14, -1); } else { - this.searchField.render(matrices, mouseX, mouseY, delta); + this.searchField.render(context, mouseX, mouseY, delta); } if (ItemRegistry.filesImported){ if (results == null) { @@ -75,16 +73,16 @@ public class ItemListWidget extends RecipeBookWidget implements Drawable, Select this.results = new SearchResultsWidget(this.client, x, y); } this.updateSearchResult(); - this.results.render(matrices, mouseX, mouseY, delta); + this.results.render(context, mouseX, mouseY, delta); } matrices.pop(); } } @Override - public void drawTooltip(MatrixStack matrices, int x, int y, int mouseX, int mouseY) { + public void drawTooltip(DrawContext context, int x, int y, int mouseX, int mouseY) { if (this.isOpen() && ItemRegistry.filesImported && results != null) { - this.results.drawTooltip(matrices, mouseX, mouseY); + this.results.drawTooltip(context, mouseX, mouseY); } } @@ -93,8 +91,10 @@ public class ItemListWidget extends RecipeBookWidget implements Drawable, Select if (this.isOpen() && !this.client.player.isSpectator() && ItemRegistry.filesImported && results != null) { if (this.searchField != null && 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); } else return false; diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemRegistry.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemRegistry.java index d9f3b473..dc63e351 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemRegistry.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemRegistry.java @@ -2,32 +2,23 @@ package me.xmrvizzy.skyblocker.skyblock.itemlist; import com.google.gson.JsonObject; import com.google.gson.JsonParser; - -import me.xmrvizzy.skyblocker.skyblock.api.RepositoryUpdate; -import net.fabricmc.loader.api.FabricLoader; +import me.xmrvizzy.skyblocker.utils.NEURepo; import net.minecraft.client.MinecraftClient; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.text.Text; -import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.api.PullResult; -import org.eclipse.jgit.errors.RepositoryNotFoundException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.*; -import java.util.concurrent.CompletableFuture; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class ItemRegistry { - private static final Logger LOGGER = LoggerFactory.getLogger(ItemRegistry.class); - protected static final String REMOTE_ITEM_REPO = "https://github.com/NotEnoughUpdates/NotEnoughUpdates-REPO"; - public static final Path LOCAL_ITEM_REPO_DIR = FabricLoader.getInstance().getConfigDir().resolve("skyblocker/item-repo"); - - protected static final Path ITEM_LIST_DIR = LOCAL_ITEM_REPO_DIR.resolve("items"); + protected static final Path ITEM_LIST_DIR = NEURepo.LOCAL_REPO_DIR.resolve("items"); protected static final List<ItemStack> items = new ArrayList<>(); protected static final Map<String, ItemStack> itemsMap = new HashMap<>(); @@ -36,52 +27,8 @@ public class ItemRegistry { public static boolean filesImported = false; public static void init() { - CompletableFuture.runAsync(ItemRegistry::updateItemRepo) - .whenComplete((result, ex) -> { - if (ex == null) { - ItemStackBuilder.init(); - importItemFiles(); - } - else { - LOGGER.error("[Skyblocker-ItemRegistry] " + ex); - } - }); - } - - private static void updateItemRepo() { - Git git; - if (!Files.isDirectory(LOCAL_ITEM_REPO_DIR)) { - try { - git = Git.cloneRepository() - .setURI(REMOTE_ITEM_REPO) - .setDirectory(LOCAL_ITEM_REPO_DIR.toFile()) - .setBranchesToClone(List.of("refs/heads/master")) - .setBranch("refs/heads/master") - .call(); - git.close(); - LOGGER.info("[Skyblocker Repository Update] Repository updated."); - } catch (Exception e) { - e.printStackTrace(); - } - } else { - try { - git = Git.open(LOCAL_ITEM_REPO_DIR.toFile()); - PullResult pull = git.pull().setRebase(true).call(); - git.close(); - - if (pull.getRebaseResult() == null) { - LOGGER.info("[Skyblocker Repository Update] No update result"); - } else if (pull.getRebaseResult().getStatus().isSuccessful()) { - LOGGER.info("[Skyblocker Repository Update] Status: " + pull.getRebaseResult().getStatus().name()); - } else if (!pull.getRebaseResult().getStatus().isSuccessful()) { - LOGGER.warn("[Skyblocker Repository Update] Status: " + pull.getRebaseResult().getStatus().name()); - } - } catch (RepositoryNotFoundException e) { - RepositoryUpdate.updateRepository(); - } catch (Exception e) { - e.printStackTrace(); - } - } + NEURepo.runAsyncAfterLoad(ItemStackBuilder::loadPetNums); + NEURepo.runAsyncAfterLoad(ItemRegistry::importItemFiles); } private static void importItemFiles() { @@ -89,7 +36,9 @@ public class ItemRegistry { File dir = ITEM_LIST_DIR.toFile(); File[] files = dir.listFiles(); - assert files != null; + if (files == null) { + return; + } for (File file : files) { Path path = ITEM_LIST_DIR.resolve(file.getName()); try { @@ -119,8 +68,7 @@ public class ItemRegistry { if (lhsFamilyName.equals(rhsFamilyName)) { if (lhsInternalName.length() != rhsInternalName.length()) return lhsInternalName.length() - rhsInternalName.length(); - else - return lhsInternalName.compareTo(rhsInternalName); + else return lhsInternalName.compareTo(rhsInternalName); } return lhsFamilyName.compareTo(rhsFamilyName); }); @@ -147,8 +95,7 @@ public class ItemRegistry { public static List<SkyblockCraftingRecipe> getRecipes(String internalName) { List<SkyblockCraftingRecipe> result = new ArrayList<>(); for (SkyblockCraftingRecipe recipe : recipes) - if (getInternalName(recipe.result).equals(internalName)) - result.add(recipe); + if (getInternalName(recipe.result).equals(internalName)) result.add(recipe); for (SkyblockCraftingRecipe recipe : recipes) for (ItemStack ingredient : recipe.grid) if (!ingredient.getItem().equals(Items.AIR) && getInternalName(ingredient).equals(internalName)) { diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemStackBuilder.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemStackBuilder.java index b2d909a8..d420d54f 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemStackBuilder.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemStackBuilder.java @@ -4,6 +4,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import me.xmrvizzy.skyblocker.utils.NEURepo; import net.minecraft.item.ItemStack; import net.minecraft.nbt.*; import net.minecraft.text.Text; @@ -16,10 +17,10 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class ItemStackBuilder { - private final static Path PETNUMS_PATH = ItemRegistry.LOCAL_ITEM_REPO_DIR.resolve("constants/petnums.json"); + private final static Path PETNUMS_PATH = NEURepo.LOCAL_REPO_DIR.resolve("constants/petnums.json"); private static JsonObject petNums; - public static void init() { + public static void loadPetNums() { try { petNums = JsonParser.parseString(Files.readString(PETNUMS_PATH)).getAsJsonObject(); } catch (Exception e) { diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ResultButtonWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ResultButtonWidget.java index 41e5469d..12636ce1 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ResultButtonWidget.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ResultButtonWidget.java @@ -1,17 +1,22 @@ package me.xmrvizzy.skyblocker.skyblock.itemlist; import java.util.List; +import java.util.function.Function; +import java.util.ArrayList; +import com.google.common.collect.Lists; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; import net.minecraft.client.gui.widget.ClickableWidget; import net.minecraft.client.render.GameRenderer; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; +import net.minecraft.text.OrderedText; import net.minecraft.text.Text; import net.minecraft.util.Identifier; @@ -36,23 +41,26 @@ public class ResultButtonWidget extends ClickableWidget { } @Override - public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float delta) { + public void renderButton(DrawContext context, int mouseX, int mouseY, float delta) { MinecraftClient client = MinecraftClient.getInstance(); - RenderSystem.setShader(GameRenderer::getPositionTexProgram); - RenderSystem.setShaderTexture(0, BACKGROUND_TEXTURE); // this.drawTexture(matrices, this.x, this.y, 29, 206, this.width, this.height); - DrawableHelper.drawTexture(matrices, this.getX(), this.getY(), 29, 206, this.getWidth(), this.getHeight()); + context.drawTexture(BACKGROUND_TEXTURE, this.getX(), this.getY(), 29, 206, this.getWidth(), this.getHeight()); // client.getItemRenderer().renderInGui(this.itemStack, this.x + 4, this.y + 4); - client.getItemRenderer().renderInGui(matrices, this.itemStack, this.getX() + 4, this.getY() + 4); + context.drawItem(this.itemStack, this.getX() + 4, this.getY() + 4); // client.getItemRenderer().renderGuiItemOverlay(client.textRenderer, itemStack, this.x + 4, this.y + 4); - client.getItemRenderer().renderGuiItemOverlay(matrices, client.textRenderer, itemStack, this.getX() + 4, this.getY() + 4); + context.drawItemInSlot(client.textRenderer, itemStack, this.getX() + 4, this.getY() + 4); } - public void renderTooltip(MatrixStack matrices, int mouseX, int mouseY) { + public void renderTooltip(DrawContext context, int mouseX, int mouseY) { MinecraftClient client = MinecraftClient.getInstance(); - List<Text> tooltip = client.currentScreen.getTooltipFromItem(this.itemStack); - // TODO : add null check with log error - client.currentScreen.renderTooltip(matrices, tooltip, mouseX, mouseY); + List<Text> tooltip = Screen.getTooltipFromItem(client, this.itemStack); + List<OrderedText> orderedTooltip = new ArrayList<>(); + + for(int i = 0; i < tooltip.size(); i++) { + orderedTooltip.add(tooltip.get(i).asOrderedText()); + } + + client.currentScreen.setTooltip(orderedTooltip); } @Override diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/SearchResultsWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/SearchResultsWidget.java index ce53112b..058495a2 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/SearchResultsWidget.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/SearchResultsWidget.java @@ -2,6 +2,8 @@ package me.xmrvizzy.skyblocker.skyblock.itemlist; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.Drawable; import net.minecraft.client.gui.widget.ToggleButtonWidget; import net.minecraft.client.util.math.MatrixStack; @@ -106,32 +108,33 @@ public class SearchResultsWidget implements Drawable { this.nextPageButton.active = this.currentPage < this.pageCount - 1; } - public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; RenderSystem.disableDepthTest(); if (this.displayRecipes) { String craftText = this.recipeResults.get(this.currentPage).craftText; - this.client.textRenderer.drawWithShadow(matrices, craftText, this.parentX + 11, this.parentY + 31, 0xffffffff); + context.drawTextWithShadow(textRenderer, craftText, this.parentX + 11, this.parentY + 31, 0xffffffff); Text resultText = this.recipeResults.get(this.currentPage).result.getName(); - this.client.textRenderer.drawWithShadow(matrices, resultText, this.parentX + 11, this.parentY + 43, 0xffffffff); - this.client.textRenderer.drawWithShadow(matrices, "▶", this.parentX + 96, this.parentY + 90, 0xaaffffff); + context.drawTextWithShadow(textRenderer, resultText, this.parentX + 11, this.parentY + 43, 0xffffffff); + context.drawTextWithShadow(textRenderer, "▶", this.parentX + 96, this.parentY + 90, 0xaaffffff); } for (ResultButtonWidget button : resultButtons) - button.render(matrices, mouseX, mouseY, delta); + button.render(context, mouseX, mouseY, delta); if (this.pageCount > 1) { String string = (this.currentPage + 1) + "/" + this.pageCount; int dx = this.client.textRenderer.getWidth(string) / 2; - this.client.textRenderer.draw(matrices, string, this.parentX - dx + 73, this.parentY + 141, -1); + context.drawText(textRenderer, string, this.parentX - dx + 73, this.parentY + 141, -1, false); } - if (this.prevPageButton.active) this.prevPageButton.render(matrices, mouseX, mouseY, delta); - if (this.nextPageButton.active) this.nextPageButton.render(matrices, mouseX, mouseY, delta); + if (this.prevPageButton.active) this.prevPageButton.render(context, mouseX, mouseY, delta); + if (this.nextPageButton.active) this.nextPageButton.render(context, mouseX, mouseY, delta); RenderSystem.enableDepthTest(); } - public void drawTooltip(MatrixStack matrices, int mouseX, int mouseY) { + public void drawTooltip(DrawContext context, int mouseX, int mouseY) { RenderSystem.disableDepthTest(); for (ResultButtonWidget button : resultButtons) if (button.isMouseOver(mouseX, mouseY)) - button.renderTooltip(matrices, mouseX, mouseY); + button.renderTooltip(context, mouseX, mouseY); RenderSystem.enableDepthTest(); } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/quicknav/QuickNavButton.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/quicknav/QuickNavButton.java index 7269840a..c02463a3 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/quicknav/QuickNavButton.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/quicknav/QuickNavButton.java @@ -7,7 +7,7 @@ import me.xmrvizzy.skyblocker.mixin.HandledScreenAccessor; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; @@ -64,41 +64,41 @@ public class QuickNavButton extends ClickableWidget { } @Override - public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float delta) { + public void renderButton(DrawContext context, int mouseX, int mouseY, float delta) { this.updateCoordinates(); - RenderSystem.setShaderTexture(0, BUTTON_TEXTURE); + MatrixStack matrices = context.getMatrices(); RenderSystem.disableDepthTest(); // render button background if (!this.toggled) { if (this.index >= 6) // this.drawTexture(matrices, this.x, this.y + 4, this.u, this.v + 4, this.width, this.height - 4); - DrawableHelper.drawTexture(matrices, this.getX(), this.getY() + 4, this.u, this.v + 4, this.width, this.height - 4); + context.drawTexture(BUTTON_TEXTURE, this.getX(), this.getY() + 4, this.u, this.v + 4, this.width, this.height - 4); else // this.drawTexture(matrices, this.x, this.y, this.u, this.v, this.width, this.height - 4); - DrawableHelper.drawTexture(matrices, this.getX(), this.getY() - 2, this.u, this.v, this.width, this.height - 4); + context.drawTexture(BUTTON_TEXTURE, this.getX(), this.getY() - 2, this.u, this.v, this.width, this.height - 4); // } else this.drawTexture(matrices, this.x, this.y, this.u, this.v, this.width, this.height); } else { matrices.push(); //Move the top buttons 2 pixels up if they're selected if (this.index < 6) matrices.translate(0f, -2f, 0f); - DrawableHelper.drawTexture(matrices, this.getX(), this.getY(), this.u, this.v, this.width, this.height); + context.drawTexture(BUTTON_TEXTURE, this.getX(), this.getY(), this.u, this.v, this.width, this.height); matrices.pop(); } // render button icon if (!this.toggled) { if (this.index >= 6) // CLIENT.getItemRenderer().renderInGui(this.icon,this.x + 6, this.y + 6); - CLIENT.getItemRenderer().renderInGui(matrices, this.icon,this.getX() + 5, this.getY() + 6); + context.drawItem(this.icon,this.getX() + 5, this.getY() + 6); else // CLIENT.getItemRenderer().renderInGui(this.icon,this.x + 6, this.y + 9); - CLIENT.getItemRenderer().renderInGui(matrices, this.icon,this.getX() + 5, this.getY() + 7); + context.drawItem(this.icon,this.getX() + 5, this.getY() + 7); } else { if (this.index >= 6) // CLIENT.getItemRenderer().renderInGui(this.icon,this.x + 6, this.y + 9); - CLIENT.getItemRenderer().renderInGui(matrices, this.icon,this.getX() + 5, this.getY() + 9); + context.drawItem(this.icon,this.getX() + 5, this.getY() + 9); else // CLIENT.getItemRenderer().renderInGui(this.icon,this.x + 6, this.y + 6); - CLIENT.getItemRenderer().renderInGui(matrices, this.icon,this.getX() + 5, this.getY() + 6); + context.drawItem(this.icon,this.getX() + 5, this.getY() + 6); } RenderSystem.enableDepthTest(); } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/screens/Screen.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/screens/Screen.java index 43b7f956..6d06c637 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/screens/Screen.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/screens/Screen.java @@ -6,6 +6,7 @@ import me.xmrvizzy.skyblocker.config.SkyblockerConfig; import me.xmrvizzy.skyblocker.skyblock.tabhud.TabHud; import me.xmrvizzy.skyblocker.skyblock.tabhud.screens.genericInfo.GardenInfoScreen; import me.xmrvizzy.skyblocker.skyblock.tabhud.screens.genericInfo.GenericInfoScreen; +import me.xmrvizzy.skyblocker.skyblock.tabhud.screens.genericInfo.GenericRiftInfoScreen; import me.xmrvizzy.skyblocker.skyblock.tabhud.screens.main.CrimsonIsleScreen; import me.xmrvizzy.skyblocker.skyblock.tabhud.screens.main.DungeonHubScreen; import me.xmrvizzy.skyblocker.skyblock.tabhud.screens.main.DungeonScreen; @@ -17,12 +18,14 @@ import me.xmrvizzy.skyblocker.skyblock.tabhud.screens.main.HomeServerScreen; import me.xmrvizzy.skyblocker.skyblock.tabhud.screens.main.HubServerScreen; import me.xmrvizzy.skyblocker.skyblock.tabhud.screens.main.MineServerScreen; import me.xmrvizzy.skyblocker.skyblock.tabhud.screens.main.ParkServerScreen; +import me.xmrvizzy.skyblocker.skyblock.tabhud.screens.main.RiftScreen; import me.xmrvizzy.skyblocker.skyblock.tabhud.screens.playerList.DungeonPlayerScreen; import me.xmrvizzy.skyblocker.skyblock.tabhud.screens.playerList.GuestPlayerScreen; import me.xmrvizzy.skyblocker.skyblock.tabhud.screens.playerList.HomePlayerScreen; import me.xmrvizzy.skyblocker.skyblock.tabhud.screens.playerList.PlayerListScreen; import me.xmrvizzy.skyblocker.skyblock.tabhud.util.PlayerLocator; import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.Widget; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.Text; @@ -50,6 +53,7 @@ public class Screen { private static Screen correctGenericScrn(int w, int h, Text footer) { return switch (PlayerLocator.getPlayerLocation()) { case GARDEN -> new GardenInfoScreen(w, h, footer); // ok + case THE_RIFT -> new GenericRiftInfoScreen(w, h, footer); case UNKNOWN -> new EmptyScreen(w, h, footer); // ok default -> new GenericInfoScreen(w, h, footer); // ok }; @@ -77,6 +81,7 @@ public class Screen { case DUNGEON -> new DungeonScreen(w, h, footer); // ok case CRIMSON_ISLE -> new CrimsonIsleScreen(w, h, footer); case GARDEN -> new GardenScreen(w, h, footer); // ok + case THE_RIFT -> new RiftScreen(w, h, footer); case UNKNOWN -> new EmptyScreen(w, h, footer); // ok default -> new GenericServerScreen(w, h, footer); // ok }; @@ -98,9 +103,9 @@ public class Screen { } } - public void render(MatrixStack ms) { + public void render(DrawContext context) { for (Widget w : widgets) { - w.render(ms); + w.render(context); } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/screens/genericInfo/GenericRiftInfoScreen.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/screens/genericInfo/GenericRiftInfoScreen.java new file mode 100644 index 00000000..9821b5a3 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/screens/genericInfo/GenericRiftInfoScreen.java @@ -0,0 +1,38 @@ +package me.xmrvizzy.skyblocker.skyblock.tabhud.screens.genericInfo; + +import me.xmrvizzy.skyblocker.skyblock.tabhud.screens.Screen; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.rift.RiftProfileWidget; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.rift.RiftStatsWidget; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.rift.ShenWidget; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.CookieWidget; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.rift.AdvertisementWidget; +import net.minecraft.text.Text; + +public class GenericRiftInfoScreen extends Screen { + + public GenericRiftInfoScreen(int w, int h, Text footer) { + super(w, h); + + String f = footer.getString(); + + RiftProfileWidget profile = new RiftProfileWidget(); + RiftStatsWidget stats = new RiftStatsWidget(); + ShenWidget shen = new ShenWidget(); + + CookieWidget cookie = new CookieWidget(f); + AdvertisementWidget advertisement = new AdvertisementWidget(); + + this.stackWidgetsH(stats, advertisement); + this.stackWidgetsH(profile, shen, cookie); + + this.offCenterL(stats); + this.offCenterL(advertisement); + + this.offCenterR(profile); + this.offCenterR(shen); + this.offCenterR(cookie); + + this.addWidgets(profile, stats, shen, cookie, advertisement); + } + +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/screens/main/RiftScreen.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/screens/main/RiftScreen.java new file mode 100644 index 00000000..d63bcf62 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/screens/main/RiftScreen.java @@ -0,0 +1,28 @@ +package me.xmrvizzy.skyblocker.skyblock.tabhud.screens.main; + +import me.xmrvizzy.skyblocker.skyblock.tabhud.screens.Screen; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.rift.RiftProgressWidget; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.rift.GoodToKnowWidget; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.rift.RiftServerInfoWidget; + + +import net.minecraft.text.Text; + +public class RiftScreen extends Screen { + + public RiftScreen(int w, int h, Text footer) { + super(w, h); + + RiftProgressWidget rftProg = new RiftProgressWidget(); + GoodToKnowWidget gtk = new GoodToKnowWidget(); + RiftServerInfoWidget si = new RiftServerInfoWidget(); + + this.stackWidgetsH(si, gtk); + this.stackWidgetsH(rftProg); + this.offCenterL(si); + this.offCenterL(gtk); + this.offCenterR(rftProg); + this.addWidgets(si, gtk, rftProg); + } + +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/Ico.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/Ico.java index ca767617..97237769 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/Ico.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/Ico.java @@ -52,4 +52,9 @@ public class Ico { public static final ItemStack SAPLING = new ItemStack(Items.OAK_SAPLING); public static final ItemStack MILESTONE = new ItemStack(Items.LODESTONE); public static final ItemStack PICKAXE = new ItemStack(Items.IRON_PICKAXE); + public static final ItemStack NETHER_STAR = new ItemStack(Items.NETHER_STAR); + public static final ItemStack HEART_OF_THE_SEA = new ItemStack(Items.HEART_OF_THE_SEA); + public static final ItemStack EXPERIENCE_BOTTLE = new ItemStack(Items.EXPERIENCE_BOTTLE); + public static final ItemStack PINK_DYE = new ItemStack(Items.PINK_DYE); + public static final ItemStack ENCHANTED_BOOK = new ItemStack(Items.ENCHANTED_BOOK); } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerListMgr.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerListMgr.java index 60915bc1..ee4319dc 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerListMgr.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerListMgr.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -13,99 +14,147 @@ import me.xmrvizzy.skyblocker.utils.Utils; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.PlayerListEntry; +import net.minecraft.text.MutableText; import net.minecraft.text.Text; /** - * This class may be used to get data from the player list. - * It doesn't get its data every frame, instead, a scheduler is used to - * update the data this class is holding periodically. - * The list is sorted like in the vanilla game. + * This class may be used to get data from the player list. It doesn't get its + * data every frame, instead, a scheduler is used to update the data this class + * is holding periodically. The list is sorted like in the vanilla game. */ public class PlayerListMgr { - public static final Logger LOGGER = LoggerFactory.getLogger("Skyblocker Regex"); - - private static List<PlayerListEntry> playerList; - - public static void updateList() { - - if (!Utils.isOnSkyblock()) { - return; - } - - ClientPlayNetworkHandler cpnwh = MinecraftClient.getInstance().getNetworkHandler(); - - // check is needed, else game crash on server leave - if (cpnwh != null) { - playerList = cpnwh.getPlayerList() - .stream() - .sorted(PlayerListHudAccessor.getOrdering()) - .toList(); - } - } - - /** - * Get the display name at some index of the player list and apply a pattern to - * it - * - * @return the matcher if p fully matches, else null - */ - public static Matcher regexAt(int idx, Pattern p) { - - String str = PlayerListMgr.strAt(idx); - - if (str == null) { - return null; - } - - Matcher m = p.matcher(str); - if (!m.matches()) { - LOGGER.error("no match: \"{}\" against \"{}\"", str, p); - return null; - } else { - return m; - } - } - - /** - * Get the display name at some index of the player list as string - * - * @return the string or null, if the display name is null, empty or whitespace - * only - */ - public static String strAt(int idx) { - - if (playerList == null) { - return null; - } - - if (playerList.size() <= idx) { - return null; - } - - Text txt = playerList.get(idx).getDisplayName(); - if (txt == null) { - return null; - } - String str = txt.getString().trim(); - if (str.length() == 0) { - return null; - } - return str; - } - - /** - * Get the display name at some index of the player list as Text as seen in the - * game - * - * @return the PlayerListEntry at that index - */ - public static PlayerListEntry getRaw(int idx) { - return playerList.get(idx); - } - - public static int getSize() { - return playerList.size(); - } + public static final Logger LOGGER = LoggerFactory.getLogger("Skyblocker Regex"); + + private static List<PlayerListEntry> playerList; + + public static void updateList() { + + if (!Utils.isOnSkyblock()) { + return; + } + + ClientPlayNetworkHandler cpnwh = MinecraftClient.getInstance().getNetworkHandler(); + + // check is needed, else game crash on server leave + if (cpnwh != null) { + playerList = cpnwh.getPlayerList().stream().sorted(PlayerListHudAccessor.getOrdering()).toList(); + } + } + + /** + * Get the display name at some index of the player list and apply a pattern to + * it + * + * @return the matcher if p fully matches, else null + */ + public static Matcher regexAt(int idx, Pattern p) { + + String str = PlayerListMgr.strAt(idx); + + if (str == null) { + return null; + } + + Matcher m = p.matcher(str); + if (!m.matches()) { + LOGGER.error("no match: \"{}\" against \"{}\"", str, p); + return null; + } else { + return m; + } + } + + /** + * Get the display name at some index of the player list as string + * + * @return the string or null, if the display name is null, empty or whitespace + * only + */ + public static String strAt(int idx) { + + if (playerList == null) { + return null; + } + + if (playerList.size() <= idx) { + return null; + } + + Text txt = playerList.get(idx).getDisplayName(); + if (txt == null) { + return null; + } + String str = txt.getString().trim(); + if (str.length() == 0) { + return null; + } + return str; + } + + /** + * Gets the display name at some index of the player list + * + * @return the text or null, if the display name is null + * + * @implNote currently designed specifically for crimson isles faction quests + * widget and the rift widgets, might not work correctly without + * modification for other stuff. you've been warned! + */ + public static Text textAt(int idx) { + + if (playerList == null) { + return null; + } + + if (playerList.size() <= idx) { + return null; + } + + Text txt = playerList.get(idx).getDisplayName(); + if (txt == null) { + return null; + } + + // Rebuild the text object to remove leading space thats in all faction quest + // stuff (also removes trailing space just in case) + MutableText newText = Text.empty(); + int size = txt.getSiblings().size(); + + for (int i = 0; i < size; i++) { + Text current = txt.getSiblings().get(i); + String textToAppend = current.getString(); + + // Trim leading & trailing space - this can only be done at the start and end + // otherwise it'll produce malformed results + if (i == 0) + textToAppend = textToAppend.stripLeading(); + if (i == size - 1) + textToAppend = textToAppend.stripTrailing(); + + newText.append(Text.literal(textToAppend).setStyle(current.getStyle())); + } + + // Avoid returning an empty component - Rift advertisements needed this + if (newText.getString().length() == 0) { + return null; + } + + return newText; + } + + /** + * Get the display name at some index of the player list as Text as seen in the + * game + * + * @return the PlayerListEntry at that index + */ + public static PlayerListEntry getRaw(int idx) { + return playerList.get(idx); + } + + public static int getSize() { + return playerList.size(); + } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerLocator.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerLocator.java index d7abdfc2..c2f14d3c 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerLocator.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerLocator.java @@ -25,6 +25,7 @@ public class PlayerLocator { JERRY, GARDEN, INSTANCED, + THE_RIFT, UNKNOWN } @@ -82,6 +83,8 @@ public class PlayerLocator { return Location.GARDEN; case "Instanced": return Location.INSTANCED; + case "The Rift": + return Location.THE_RIFT; default: return Location.UNKNOWN; } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/QuestWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/QuestWidget.java index 5c89964e..43b741ba 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/QuestWidget.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/QuestWidget.java @@ -1,6 +1,7 @@ package me.xmrvizzy.skyblocker.skyblock.tabhud.widget; import me.xmrvizzy.skyblocker.skyblock.tabhud.util.Ico; +import me.xmrvizzy.skyblocker.skyblock.tabhud.util.PlayerListMgr; import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component.IcoTextComponent; import net.minecraft.text.MutableText; @@ -18,7 +19,7 @@ public class QuestWidget extends Widget { super(TITLE, Formatting.AQUA.getColorValue()); for (int i = 51; i < 56; i++) { - Text q = Widget.plainEntryText(i); + Text q = PlayerListMgr.textAt(i); IcoTextComponent itc = new IcoTextComponent(Ico.BOOK, q); this.addComponent(itc); } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/ReputationWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/ReputationWidget.java index c0379623..3685e0ca 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/ReputationWidget.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/ReputationWidget.java @@ -54,8 +54,9 @@ public class ReputationWidget extends Widget { this.addComponent(new ProgressComponent()); } else { float pcnt = Float.parseFloat(prog.group("prog")); + Text reputationText = state.group("from").equals("Max") ? Text.literal("Max Reputation") : Text.literal(state.group("from") + " -> " + state.group("to")); ProgressComponent pc = new ProgressComponent(Ico.LANTERN, - Text.of(state.group("from") + " -> " + state.group("to")), rep, pcnt, + reputationText, rep, pcnt, Formatting.AQUA.getColorValue()); this.addComponent(pc); } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/Widget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/Widget.java index 6b96c151..33f77933 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/Widget.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/Widget.java @@ -10,7 +10,7 @@ import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component.Component; import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component.IcoTextComponent; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemStack; import net.minecraft.text.MutableText; @@ -103,14 +103,15 @@ public abstract class Widget { /** * Draw this widget with a background */ - public final void render(MatrixStack ms) { - this.render(ms, true); + public final void render(DrawContext context) { + this.render(context, true); } /** * Draw this widget, possibly with a background */ - public final void render(MatrixStack ms, boolean hasBG) { + public final void render(DrawContext context, boolean hasBG) { + MatrixStack ms = context.getMatrices(); // not sure if this is the way to go, but it fixes Z-layer issues // like blocks being rendered behind the BG and the hotbar clipping into things @@ -123,9 +124,9 @@ public abstract class Widget { // move above other UI elements ms.translate(0, 0, 200); if (hasBG) { - DrawableHelper.fill(ms, x + 1, y, x + w - 1, y + h, COL_BG_BOX); - DrawableHelper.fill(ms, x, y + 1, x + 1, y + h - 1, COL_BG_BOX); - DrawableHelper.fill(ms, x + w - 1, y + 1, x + w, y + h - 1, COL_BG_BOX); + context.fill(x + 1, y, x + w - 1, y + h, COL_BG_BOX); + context.fill(x, y + 1, x + 1, y + h - 1, COL_BG_BOX); + context.fill(x + w - 1, y + 1, x + w, y + h - 1, COL_BG_BOX); } // move above background (if exists) ms.translate(0, 0, 100); @@ -133,19 +134,19 @@ public abstract class Widget { int strHeightHalf = Widget.txtRend.fontHeight / 2; int strAreaWidth = Widget.txtRend.getWidth(title) + 4; - txtRend.draw(ms, title, x + 8, y + 2, this.color); + context.drawText(txtRend, title, x + 8, y + 2, this.color, false); - this.drawHLine(ms, x + 2, y + 1 + strHeightHalf, 4); - this.drawHLine(ms, x + 2 + strAreaWidth + 4, y + 1 + strHeightHalf, w - 4 - 4 - strAreaWidth); - this.drawHLine(ms, x + 2, y + h - 2, w - 4); + this.drawHLine(context, x + 2, y + 1 + strHeightHalf, 4); + this.drawHLine(context, x + 2 + strAreaWidth + 4, y + 1 + strHeightHalf, w - 4 - 4 - strAreaWidth); + this.drawHLine(context, x + 2, y + h - 2, w - 4); - this.drawVLine(ms, x + 1, y + 2 + strHeightHalf, h - 4 - strHeightHalf); - this.drawVLine(ms, x + w - 2, y + 2 + strHeightHalf, h - 4 - strHeightHalf); + this.drawVLine(context, x + 1, y + 2 + strHeightHalf, h - 4 - strHeightHalf); + this.drawVLine(context, x + w - 2, y + 2 + strHeightHalf, h - 4 - strHeightHalf); int yOffs = y + BORDER_SZE_N; for (Component c : components) { - c.render(ms, x + BORDER_SZE_W, yOffs); + c.render(context, x + BORDER_SZE_W, yOffs); yOffs += c.getHeight() + Component.PAD_L; } // pop manipulations above @@ -153,12 +154,12 @@ public abstract class Widget { RenderSystem.disableDepthTest(); } - private void drawHLine(MatrixStack ms, int xpos, int ypos, int width) { - DrawableHelper.fill(ms, xpos, ypos, xpos + width, ypos + 1, this.color); + private void drawHLine(DrawContext context, int xpos, int ypos, int width) { + context.fill(xpos, ypos, xpos + width, ypos + 1, this.color); } - private void drawVLine(MatrixStack ms, int xpos, int ypos, int height) { - DrawableHelper.fill(ms, xpos, ypos, xpos + 1, ypos + height, this.color); + private void drawVLine(DrawContext context, int xpos, int ypos, int height) { + context.fill(xpos, ypos, xpos + 1, ypos + height, this.color); } /** diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/Component.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/Component.java index 671b1f41..850cb3d2 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/Component.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/Component.java @@ -2,8 +2,8 @@ package me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.render.item.ItemRenderer; -import net.minecraft.client.util.math.MatrixStack; /** * Abstract base class for a component that may be added to a Widget. @@ -15,12 +15,11 @@ public abstract class Component { public static final int PAD_L = 4; static TextRenderer txtRend = MinecraftClient.getInstance().textRenderer; - static ItemRenderer itmRend = MinecraftClient.getInstance().getItemRenderer(); // these should always be the content dimensions without any padding. int width, height; - public abstract void render(MatrixStack ms, int x, int y); + public abstract void render(DrawContext context, int x, int y); public int getWidth() { return this.width; diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/IcoFatTextComponent.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/IcoFatTextComponent.java index f845eba5..afd05c26 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/IcoFatTextComponent.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/IcoFatTextComponent.java @@ -1,7 +1,7 @@ package me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component; import me.xmrvizzy.skyblocker.skyblock.tabhud.util.Ico; -import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.client.gui.DrawContext; import net.minecraft.item.ItemStack; import net.minecraft.text.Text; import net.minecraft.util.Formatting; @@ -36,10 +36,10 @@ public class IcoFatTextComponent extends Component { } @Override - public void render(MatrixStack ms, int x, int y) { - itmRend.renderGuiItemIcon(ms, ico, x, y + ICO_OFFS); - txtRend.draw(ms, line1, x + ICO_DIM + PAD_L, y, 0xffffffff); - txtRend.draw(ms, line2, x + ICO_DIM + PAD_L, y + txtRend.fontHeight + PAD_S, 0xffffffff); + public void render(DrawContext context, int x, int y) { + context.drawItem(ico, x, y + ICO_OFFS); + context.drawText(txtRend, line1, x + ICO_DIM + PAD_L, y, 0xffffffff, false); + context.drawText(txtRend, line2, x + ICO_DIM + PAD_L, y + txtRend.fontHeight + PAD_S, 0xffffffff, false); } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/IcoTextComponent.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/IcoTextComponent.java index 7a495a13..7ab92dd5 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/IcoTextComponent.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/IcoTextComponent.java @@ -1,7 +1,7 @@ package me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component; import me.xmrvizzy.skyblocker.skyblock.tabhud.util.Ico; -import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.client.gui.DrawContext; import net.minecraft.item.ItemStack; import net.minecraft.text.Text; import net.minecraft.util.Formatting; @@ -32,9 +32,9 @@ public class IcoTextComponent extends Component { } @Override - public void render(MatrixStack ms, int x, int y) { - itmRend.renderGuiItemIcon(ms, ico, x, y); - txtRend.draw(ms, text, x + ICO_DIM + PAD_L, y + 5, 0xffffffff); + public void render(DrawContext context, int x, int y) { + context.drawItem(ico, x, y); + context.drawText(txtRend, text, x + ICO_DIM + PAD_L, y + 5, 0xffffffff, false); } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/PlainTextComponent.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/PlainTextComponent.java index 265d11f1..34e0268b 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/PlainTextComponent.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/PlainTextComponent.java @@ -1,6 +1,6 @@ package me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component; -import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.client.gui.DrawContext; import net.minecraft.text.Text; import net.minecraft.util.Formatting; @@ -23,8 +23,8 @@ public class PlainTextComponent extends Component { } @Override - public void render(MatrixStack ms, int x, int y) { - txtRend.draw(ms, text, x + PAD_S, y, 0xffffffff); + public void render(DrawContext context, int x, int y) { + context.drawText(txtRend, text, x + PAD_S, y, 0xffffffff, false); } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/PlayerComponent.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/PlayerComponent.java index 18859080..fd66ec73 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/PlayerComponent.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/PlayerComponent.java @@ -1,10 +1,8 @@ package me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component; -import com.mojang.blaze3d.systems.RenderSystem; - +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.PlayerSkinDrawer; import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.Identifier; /** @@ -27,10 +25,9 @@ public class PlayerComponent extends Component { } @Override - public void render(MatrixStack ms, int x, int y) { - RenderSystem.setShaderTexture(0, tex); - PlayerSkinDrawer.draw(ms, x, y, SKIN_ICO_DIM); - txtRend.draw(ms, name, x + SKIN_ICO_DIM + PAD_S, y, 0xffffffff); + public void render(DrawContext context, int x, int y) { + PlayerSkinDrawer.draw(context, tex, x, y, SKIN_ICO_DIM); + context.drawText(txtRend, name, x + SKIN_ICO_DIM + PAD_S, y, 0xffffffff, false); } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/ProgressComponent.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/ProgressComponent.java index b9ebc0e9..a7cc8d12 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/ProgressComponent.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/ProgressComponent.java @@ -1,8 +1,7 @@ package me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component; import me.xmrvizzy.skyblocker.skyblock.tabhud.util.Ico; -import net.minecraft.client.gui.DrawableHelper; -import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.client.gui.DrawContext; import net.minecraft.item.ItemStack; import net.minecraft.text.Text; import net.minecraft.util.Formatting; @@ -55,16 +54,16 @@ public class ProgressComponent extends Component { } @Override - public void render(MatrixStack ms, int x, int y) { - itmRend.renderGuiItemIcon(ms, ico, x, y + ICO_OFFS); - txtRend.draw(ms, desc, x + ICO_DIM + PAD_L, y, 0xffffffff); + public void render(DrawContext context, int x, int y) { + context.drawItem(ico, x, y + ICO_OFFS); + context.drawText(txtRend, desc, x + ICO_DIM + PAD_L, y, 0xffffffff, false); int barX = x + ICO_DIM + PAD_L; int barY = y + txtRend.fontHeight + PAD_S; int endOffsX = ((int) (this.barW * (this.pcnt / 100f))); - DrawableHelper.fill(ms, barX + endOffsX, barY, barX + this.barW, barY + BAR_HEIGHT, COL_BG_BAR); - DrawableHelper.fill(ms, barX, barY, barX + endOffsX, barY + BAR_HEIGHT, + context.fill(barX + endOffsX, barY, barX + this.barW, barY + BAR_HEIGHT, COL_BG_BAR); + context.fill(barX, barY, barX + endOffsX, barY + BAR_HEIGHT, this.color); - txtRend.drawWithShadow(ms, bar, barX + 3, barY + 2, 0xffffffff); + context.drawTextWithShadow(txtRend, bar, barX + 3, barY + 2, 0xffffffff); } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/TableComponent.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/TableComponent.java index 5d49be2c..30287dc0 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/TableComponent.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/component/TableComponent.java @@ -1,7 +1,6 @@ package me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component; -import net.minecraft.client.gui.DrawableHelper; -import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.client.gui.DrawContext; /** * Meta-Component that consists of a grid of other components @@ -38,11 +37,11 @@ public class TableComponent extends Component { } @Override - public void render(MatrixStack ms, int xpos, int ypos) { + public void render(DrawContext context, int xpos, int ypos) { for (int x = 0; x < cols; x++) { for (int y = 0; y < rows; y++) { if (comps[x][y] != null) { - comps[x][y].render(ms, xpos + (x * cellW), ypos + y * cellH); + comps[x][y].render(context, xpos + (x * cellW), ypos + y * cellH); } } // add a line before the col if we're not drawing the first one @@ -51,7 +50,7 @@ public class TableComponent extends Component { int lineX2 = xpos + (x * cellW) - PAD_S; int lineY1 = ypos + 1; int lineY2 = ypos + this.height - PAD_S - 1; // not sure why but it looks correct - DrawableHelper.fill(ms, lineX1, lineY1, lineX2, lineY2, this.color); + context.fill(lineX1, lineY1, lineX2, lineY2, this.color); } } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/AdvertisementWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/AdvertisementWidget.java new file mode 100644 index 00000000..287b25b1 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/AdvertisementWidget.java @@ -0,0 +1,27 @@ +package me.xmrvizzy.skyblocker.skyblock.tabhud.widget.rift; + +import me.xmrvizzy.skyblocker.skyblock.tabhud.util.PlayerListMgr; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.Widget; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component.PlainTextComponent; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +public class AdvertisementWidget extends Widget { + + private static final MutableText TITLE = Text.literal("Advertisement").formatted(Formatting.DARK_AQUA, + Formatting.BOLD); + + public AdvertisementWidget() { + super(TITLE, Formatting.DARK_AQUA.getColorValue()); + + for (int i = 73; i < 80; i++) { + Text text = PlayerListMgr.textAt(i); + if (text != null) + this.addComponent(new PlainTextComponent(text)); + } + + this.pack(); + } + +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/GoodToKnowWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/GoodToKnowWidget.java new file mode 100644 index 00000000..667bc154 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/GoodToKnowWidget.java @@ -0,0 +1,55 @@ +package me.xmrvizzy.skyblocker.skyblock.tabhud.widget.rift; + +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component.IcoTextComponent; +import me.xmrvizzy.skyblocker.skyblock.tabhud.util.Ico; +import me.xmrvizzy.skyblocker.skyblock.tabhud.util.PlayerListMgr; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.Widget; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +public class GoodToKnowWidget extends Widget { + + private static final MutableText TITLE = Text.literal("Good To Know").formatted(Formatting.BLUE, Formatting.BOLD); + + public GoodToKnowWidget() { + super(TITLE, Formatting.BLUE.getColorValue()); + + // After you progress further the tab adds more info so we need to be careful of + // that + // In beginning it only shows montezuma, then timecharms and enigma souls are + // added + Text pos49 = PlayerListMgr.textAt(49); // Can be times visited rift + Text pos51 = PlayerListMgr.textAt(51); // Can be lifetime motes or visited rift + Text pos53 = PlayerListMgr.textAt(53); // Can be lifetime motes + + int visitedRiftPos = 0; + int lifetimeMotesPos = 0; + + // Check each position to see what is or isn't there so we don't try adding + // invalid components + if (pos49.getString().contains("times")) + visitedRiftPos = 49; + if (pos51.getString().contains("Motes")) + lifetimeMotesPos = 51; + if (pos51.getString().contains("times")) + visitedRiftPos = 51; + if (pos53.getString().contains("Motes")) + lifetimeMotesPos = 53; + + Text timesVisitedRift = (visitedRiftPos == 51) ? pos51 : (visitedRiftPos == 49) ? pos49 : null; + Text lifetimeMotesEarned = (lifetimeMotesPos == 53) ? pos53 : (lifetimeMotesPos == 51) ? pos51 : null; + + if (visitedRiftPos != 0) { + this.addComponent(new IcoTextComponent(Ico.EXPERIENCE_BOTTLE, + Text.literal("Visited Rift: ").append(timesVisitedRift))); + } + + if (lifetimeMotesPos != 0) { + this.addComponent( + new IcoTextComponent(Ico.PINK_DYE, Text.literal("Lifetime Earned: ").append(lifetimeMotesEarned))); + } + + this.pack(); + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/RiftProfileWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/RiftProfileWidget.java new file mode 100644 index 00000000..5460de49 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/RiftProfileWidget.java @@ -0,0 +1,19 @@ +package me.xmrvizzy.skyblocker.skyblock.tabhud.widget.rift; + +import me.xmrvizzy.skyblocker.skyblock.tabhud.util.Ico; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.Widget; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +public class RiftProfileWidget extends Widget { + + private static final MutableText TITLE = Text.literal("Profile").formatted(Formatting.DARK_AQUA, Formatting.BOLD); + + public RiftProfileWidget() { + super(TITLE, Formatting.DARK_AQUA.getColorValue()); + + this.addSimpleIcoText(Ico.SIGN, "Profile:", Formatting.GREEN, 61); + this.pack(); + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/RiftProgressWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/RiftProgressWidget.java new file mode 100644 index 00000000..9ce12e76 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/RiftProgressWidget.java @@ -0,0 +1,97 @@ +package me.xmrvizzy.skyblocker.skyblock.tabhud.widget.rift; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import me.xmrvizzy.skyblocker.skyblock.tabhud.util.Ico; +import me.xmrvizzy.skyblocker.skyblock.tabhud.util.PlayerListMgr; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.Widget; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component.ProgressComponent; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.math.MathHelper; + +public class RiftProgressWidget extends Widget { + + private static final MutableText TITLE = Text.literal("Rift Progress").formatted(Formatting.BLUE, Formatting.BOLD); + + private static final Pattern TIMECHARMS_PATTERN = Pattern.compile("Timecharms: (?<current>[0-9]+)\\/(?<total>[0-9]+)"); + private static final Pattern ENIGMA_SOULS_PATTERN = Pattern.compile("Enigma Souls: (?<current>[0-9]+)\\/(?<total>[0-9]+)"); + private static final Pattern MONTEZUMA_PATTERN = Pattern.compile("Montezuma: (?<current>[0-9]+)\\/(?<total>[0-9]+)"); + + public RiftProgressWidget() { + super(TITLE, Formatting.BLUE.getColorValue()); + + // After you progress further the tab adds more info so we need to be careful of + // that + // In beginning it only shows montezuma, then timecharms and enigma souls are + // added + String pos45 = PlayerListMgr.strAt(45); // Can be Montezuma or Timecharms + String pos46 = PlayerListMgr.strAt(46); // Can be Enigma Souls or Empty + String pos47 = PlayerListMgr.strAt(47); // Can be Montezuma or "Good to know" heading + + boolean hasTimecharms = false; + boolean hasEnigmaSouls = false; + int montezumaPos = 0; + + // Check each position to see what is or isn't there so we don't try adding + // invalid components + if (pos45.contains("Timecharms")) + hasTimecharms = true; + if (pos46.contains("Enigma Souls")) + hasEnigmaSouls = true; + + // Small ternary to account for positions, defaults to -1 if it for some reason + // does not exist (which shouldn't be the case!) + montezumaPos = (pos47.contains("Montezuma")) ? 47 : (pos45.contains("Montezuma")) ? 45 : -1; + + if (hasTimecharms) { + Matcher m = PlayerListMgr.regexAt(45, TIMECHARMS_PATTERN); + + int current = Integer.parseInt(m.group("current")); + int total = Integer.parseInt(m.group("total")); + float pcnt = ((float) current / (float) total) * 100f; + Text progressText = Text.literal(current + "/" + total); + + ProgressComponent pc = new ProgressComponent(Ico.NETHER_STAR, Text.literal("Timecharms"), progressText, + pcnt, pcntToCol(pcnt)); + + this.addComponent(pc); + } + + if (hasEnigmaSouls) { + Matcher m = PlayerListMgr.regexAt(46, ENIGMA_SOULS_PATTERN); + + int current = Integer.parseInt(m.group("current")); + int total = Integer.parseInt(m.group("total")); + float pcnt = ((float) current / (float) total) * 100f; + Text progressText = Text.literal(current + "/" + total); + + ProgressComponent pc = new ProgressComponent(Ico.HEART_OF_THE_SEA, Text.literal("Enigma Souls"), + progressText, pcnt, pcntToCol(pcnt)); + + this.addComponent(pc); + } + + if (montezumaPos != -1) { + Matcher m = PlayerListMgr.regexAt(montezumaPos, MONTEZUMA_PATTERN); + + int current = Integer.parseInt(m.group("current")); + int total = Integer.parseInt(m.group("total")); + float pcnt = ((float) current / (float) total) * 100f; + Text progressText = Text.literal(current + "/" + total); + + ProgressComponent pc = new ProgressComponent(Ico.BONE, Text.literal("Montezuma"), progressText, pcnt, + pcntToCol(pcnt)); + + this.addComponent(pc); + } + + this.pack(); + } + + private static int pcntToCol(float pcnt) { + return MathHelper.hsvToRgb(pcnt / 300f, 0.9f, 0.9f); + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/RiftServerInfoWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/RiftServerInfoWidget.java new file mode 100644 index 00000000..2ac2a35d --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/RiftServerInfoWidget.java @@ -0,0 +1,26 @@ +package me.xmrvizzy.skyblocker.skyblock.tabhud.widget.rift; + +import me.xmrvizzy.skyblocker.skyblock.tabhud.util.Ico; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.Widget; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +/** + * Special version of the server info widget for the rift! + * + */ +public class RiftServerInfoWidget extends Widget { + + private static final MutableText TITLE = Text.literal("Server Info").formatted(Formatting.LIGHT_PURPLE, Formatting.BOLD); + + public RiftServerInfoWidget() { + super(TITLE, Formatting.LIGHT_PURPLE.getColorValue()); + + this.addSimpleIcoText(Ico.MAP, "Area:", Formatting.LIGHT_PURPLE, 41); + this.addSimpleIcoText(Ico.NTAG, "Server ID:", Formatting.GRAY, 42); + + this.pack(); + } + +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/RiftStatsWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/RiftStatsWidget.java new file mode 100644 index 00000000..ef5876f2 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/RiftStatsWidget.java @@ -0,0 +1,41 @@ +package me.xmrvizzy.skyblocker.skyblock.tabhud.widget.rift; + +import me.xmrvizzy.skyblocker.skyblock.tabhud.util.Ico; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.Widget; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component.IcoTextComponent; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component.TableComponent; + +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +public class RiftStatsWidget extends Widget { + + private static final MutableText TITLE = Text.literal("Stats").formatted(Formatting.DARK_AQUA, Formatting.BOLD); + + public RiftStatsWidget() { + super(TITLE, Formatting.DARK_AQUA.getColorValue()); + + Text riftDamage = Widget.simpleEntryText(64, "RDG", Formatting.DARK_PURPLE); + IcoTextComponent rdg = new IcoTextComponent(Ico.DIASWORD, riftDamage); + + Text speed = Widget.simpleEntryText(65, "SPD", Formatting.WHITE); + IcoTextComponent spd = new IcoTextComponent(Ico.SUGAR, speed); + + Text intelligence = Widget.simpleEntryText(66, "INT", Formatting.AQUA); + IcoTextComponent intel = new IcoTextComponent(Ico.ENCHANTED_BOOK, intelligence); + + Text manaRegen = Widget.simpleEntryText(67, "MRG", Formatting.AQUA); + IcoTextComponent mrg = new IcoTextComponent(Ico.DIAMOND, manaRegen); + + TableComponent tc = new TableComponent(2, 2, Formatting.AQUA.getColorValue()); + tc.addToCell(0, 0, rdg); + tc.addToCell(0, 1, spd); + tc.addToCell(1, 0, intel); + tc.addToCell(1, 1, mrg); + + this.addComponent(tc); + this.pack(); + } + +}
\ No newline at end of file diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/ShenWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/ShenWidget.java new file mode 100644 index 00000000..5dcc08c0 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/rift/ShenWidget.java @@ -0,0 +1,20 @@ +package me.xmrvizzy.skyblocker.skyblock.tabhud.widget.rift; + +import me.xmrvizzy.skyblocker.skyblock.tabhud.util.PlayerListMgr; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.Widget; +import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component.PlainTextComponent; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +public class ShenWidget extends Widget { + + private static final MutableText TITLE = Text.literal("Shen's Countdown").formatted(Formatting.DARK_AQUA, Formatting.BOLD); + + public ShenWidget() { + super(TITLE, Formatting.DARK_AQUA.getColorValue()); + + this.addComponent(new PlainTextComponent(Text.literal(PlayerListMgr.strAt(70)))); + this.pack(); + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/NEURepo.java b/src/main/java/me/xmrvizzy/skyblocker/utils/NEURepo.java new file mode 100644 index 00000000..29b39aa3 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/utils/NEURepo.java @@ -0,0 +1,101 @@ +package me.xmrvizzy.skyblocker.utils; + +import me.xmrvizzy.skyblocker.SkyblockerMod; +import me.xmrvizzy.skyblocker.skyblock.itemlist.ItemRegistry; +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.text.Text; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.TransportException; +import org.eclipse.jgit.errors.RepositoryNotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * Initializes the NEU repo, which contains item metadata and fairy souls location data. Clones the repo if it does not exist and checks for updates. Use {@link #runAsyncAfterLoad(Runnable)} to run code after the repo is initialized. + */ +public class NEURepo { + private static final Logger LOGGER = LoggerFactory.getLogger(NEURepo.class); + public static final String REMOTE_REPO_URL = "https://github.com/NotEnoughUpdates/NotEnoughUpdates-REPO.git"; + public static final Path LOCAL_REPO_DIR = SkyblockerMod.CONFIG_DIR.resolve("item-repo"); + private static final CompletableFuture<Void> REPO_INITIALIZED = initRepository(); + + /** + * Adds command to update repository manually from ingame. + * <p></p> + * TODO A button could be added to the settings menu that will trigger this command. + */ + public static void init() { + ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> + dispatcher.register(ClientCommandManager.literal(SkyblockerMod.NAMESPACE) + .then(ClientCommandManager.literal("updaterepository").executes(context -> { + deleteAndDownloadRepository(); + return 1; + })))); + } + + private static CompletableFuture<Void> initRepository() { + return CompletableFuture.runAsync(() -> { + try { + if (Files.isDirectory(NEURepo.LOCAL_REPO_DIR)) { + try (Git localRepo = Git.open(NEURepo.LOCAL_REPO_DIR.toFile())) { + localRepo.pull().setRebase(true).call(); + LOGGER.info("[Skyblocker] NEU Repository Updated"); + } + } else { + Git.cloneRepository().setURI(REMOTE_REPO_URL).setDirectory(NEURepo.LOCAL_REPO_DIR.toFile()).setBranchesToClone(List.of("refs/heads/master")).setBranch("refs/heads/master").call().close(); + LOGGER.info("[Skyblocker] NEU Repository Downloaded"); + } + } catch (TransportException e){ + LOGGER.error("[Skyblocker] Transport operation failed. Most likely unable to connect to the remote NEU repo on github", e); + } catch (RepositoryNotFoundException e) { + LOGGER.warn("[Skyblocker] Local NEU Repository not found or corrupted, downloading new one", e); + deleteAndDownloadRepository(); + } catch (Exception e) { + LOGGER.error("[Skyblocker] Encountered unknown exception while initializing NEU Repository", e); + } + }); + } + + private static void deleteAndDownloadRepository() { + CompletableFuture.runAsync(() -> { + try { + ItemRegistry.filesImported = false; + File dir = NEURepo.LOCAL_REPO_DIR.toFile(); + recursiveDelete(dir); + } catch (Exception ex) { + if (MinecraftClient.getInstance().player != null) + MinecraftClient.getInstance().player.sendMessage(Text.translatable("skyblocker.updaterepository.failed"), false); + return; + } + initRepository(); + }); + } + + @SuppressWarnings("ResultOfMethodCallIgnored") + private static void recursiveDelete(File dir) { + File[] children; + if (dir.isDirectory() && !Files.isSymbolicLink(dir.toPath()) && (children = dir.listFiles()) != null) { + for (File child : children) { + recursiveDelete(child); + } + } + dir.delete(); + } + + /** + * Runs the given runnable after the NEU repo is initialized. + * @param runnable the runnable to run + * @return a completable future of the given runnable + */ + public static CompletableFuture<Void> runAsyncAfterLoad(Runnable runnable) { + return REPO_INITIALIZED.thenRunAsync(runnable); + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java b/src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java new file mode 100644 index 00000000..79308dc3 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java @@ -0,0 +1,30 @@ +package me.xmrvizzy.skyblocker.utils; + +import me.x150.renderer.render.Renderer3d; +import me.xmrvizzy.skyblocker.mixin.accessor.BeaconBlockEntityRendererInvoker; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.minecraft.client.render.block.entity.BeaconBlockEntityRenderer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +import java.awt.*; + +public class RenderHelper { + public static void renderFilledThroughWallsWithBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) { + renderFilledThroughWalls(context, pos, colorComponents, alpha); + renderBeaconBeam(context, pos, colorComponents); + } + + public static void renderFilledThroughWalls(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) { + Renderer3d.renderThroughWalls(); + Renderer3d.renderFilled(context.matrixStack(), new Color(colorComponents[0], colorComponents[1], colorComponents[2], alpha), Vec3d.of(pos), new Vec3d(1, 1, 1)); + Renderer3d.stopRenderThroughWalls(); + } + + public static void renderBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents) { + context.matrixStack().push(); + context.matrixStack().translate(pos.getX() - context.camera().getPos().x, pos.getY() - context.camera().getPos().y, pos.getZ() - context.camera().getPos().z); + BeaconBlockEntityRendererInvoker.renderBeam(context.matrixStack(), context.consumers(), context.tickDelta(), context.world().getTime(), 0, BeaconBlockEntityRenderer.MAX_BEAM_HEIGHT, colorComponents); + context.matrixStack().pop(); + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/ToastBuilder.java b/src/main/java/me/xmrvizzy/skyblocker/utils/ToastBuilder.java index 7a0ad754..919975b0 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/utils/ToastBuilder.java +++ b/src/main/java/me/xmrvizzy/skyblocker/utils/ToastBuilder.java @@ -3,11 +3,10 @@ package me.xmrvizzy.skyblocker.utils; import com.mojang.blaze3d.systems.RenderSystem; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.client.gui.DrawableHelper; -import net.minecraft.client.render.GameRenderer; +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.client.util.math.MatrixStack; import net.minecraft.text.Text; @Environment(value= EnvType.CLIENT) @@ -21,14 +20,13 @@ public class ToastBuilder implements Toast { } @Override - public Toast.Visibility draw(MatrixStack matrices, ToastManager manager, long startTime) { - RenderSystem.setShader(GameRenderer::getPositionTexProgram); - RenderSystem.setShaderTexture(0, TEXTURE); + public Toast.Visibility draw(DrawContext context, ToastManager manager, long startTime) { + TextRenderer textRenderer = manager.getClient().textRenderer; RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - DrawableHelper.drawTexture(matrices, 0, 0, 0, 0, this.getWidth(), this.getHeight()); - manager.getClient().textRenderer.draw(matrices, title, 7.0f, 7.0f, -11534256); - manager.getClient().textRenderer.draw(matrices, description, 7.0f, 18.0f, -16777216); + context.drawTexture(TEXTURE, 0, 0, 0, 0, this.getWidth(), this.getHeight()); + context.drawText(textRenderer, title, 7, 7, -11534256, false); + context.drawText(textRenderer, description, 7, 18, -16777216, false); return startTime >= 3000L ? Toast.Visibility.HIDE : Toast.Visibility.SHOW; } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java b/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java index 028386ab..d961ba7e 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java +++ b/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java @@ -1,13 +1,22 @@ package me.xmrvizzy.skyblocker.utils; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import me.xmrvizzy.skyblocker.SkyblockerMod; import me.xmrvizzy.skyblocker.skyblock.item.PriceInfoTooltip; import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback; +import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; +import net.fabricmc.fabric.api.networking.v1.PacketSender; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.client.network.PlayerListEntry; import net.minecraft.scoreboard.Scoreboard; import net.minecraft.scoreboard.ScoreboardObjective; import net.minecraft.scoreboard.ScoreboardPlayerScore; import net.minecraft.scoreboard.Team; +import net.minecraft.text.Text; import net.minecraft.util.Formatting; import java.util.ArrayList; @@ -18,9 +27,22 @@ import java.util.List; * Utility variables and methods for retrieving Skyblock related information. */ public class Utils { + private static final String PROFILE_PREFIX = "Profile: "; private static boolean isOnSkyblock = false; private static boolean isInDungeons = false; private static boolean isInjected = false; + /** + * The following fields store data returned from /locraw: {@link #profile}, {@link #server}, {@link #gameType}, {@link #locationRaw}, and {@link #map}. + */ + @SuppressWarnings("JavadocDeclaration") + private static String profile = ""; + private static String server = ""; + private static String gameType = ""; + private static String locationRaw = ""; + private static String map = ""; + private static long clientWorldJoinTime = 0; + private static boolean sentLocRaw = false; + private static long lastLocRaw = 0; public static boolean isOnSkyblock() { return isOnSkyblock; @@ -34,8 +56,61 @@ public class Utils { return isInjected; } - public static void sbChecker() { + /** + * @return the profile parsed from the player list. + */ + public static String getProfile() { + return profile; + } + + /** + * @return the server parsed from /locraw. + */ + public static String getServer() { + return server; + } + + /** + * @return the game type parsed from /locraw. + */ + public static String getGameType() { + return gameType; + } + + /** + * @return the location raw parsed from /locraw. + */ + public static String getLocationRaw() { + return locationRaw; + } + + /** + * @return the map parsed from /locraw. + */ + public static String getMap() { + return map; + } + + public static void init() { + ClientPlayConnectionEvents.JOIN.register(Utils::onClientWorldJoin); + ClientReceiveMessageEvents.ALLOW_GAME.register(Utils::onChatMessage); + ClientReceiveMessageEvents.GAME_CANCELED.register(Utils::onChatMessage); // Somehow this works even though onChatMessage returns a boolean + } + + /** + * Updates all the fields stored in this class from the sidebar, player list, and /locraw. + */ + public static void update() { MinecraftClient client = MinecraftClient.getInstance(); + updateFromScoreboard(client); + updateFromPlayerList(client); + updateLocRaw(); + } + + /** + * Updates {@link #isOnSkyblock}, {@link #isInDungeons}, and {@link #isInjected} from the scoreboard. + */ + public static void updateFromScoreboard(MinecraftClient client) { List<String> sidebar; if (client.world == null || client.isInSingleplayer() || (sidebar = getSidebar()) == null) { @@ -52,13 +127,13 @@ public class Utils { isInjected = true; ItemTooltipCallback.EVENT.register(PriceInfoTooltip::onInjectTooltip); } - SkyblockEvents.JOIN.invoker().onSkyblockJoin(); isOnSkyblock = true; + SkyblockEvents.JOIN.invoker().onSkyblockJoin(); } } else if (isOnSkyblock) { - SkyblockEvents.LEAVE.invoker().onSkyblockLeave(); isOnSkyblock = false; isInDungeons = false; + SkyblockEvents.LEAVE.invoker().onSkyblockLeave(); } isInDungeons = isOnSkyblock && string.contains("The Catacombs"); } @@ -67,12 +142,13 @@ public class Utils { String location = null; List<String> sidebarLines = getSidebar(); try { - if( sidebarLines != null) { + if (sidebarLines != null) { for (String sidebarLine : sidebarLines) { if (sidebarLine.contains("⏣")) location = sidebarLine; + if (sidebarLine.contains("ф")) location = sidebarLine; //Rift } if (location == null) location = "Unknown"; - location = location.replace('⏣', ' ').strip(); + location = location.strip(); } } catch (IndexOutOfBoundsException e) { e.printStackTrace(); @@ -149,4 +225,74 @@ public class Utils { return null; } } + + private static void updateFromPlayerList(MinecraftClient client) { + if (client.getNetworkHandler() == null) { + return; + } + for (PlayerListEntry playerListEntry : client.getNetworkHandler().getPlayerList()) { + if (playerListEntry.getDisplayName() == null) { + continue; + } + String name = playerListEntry.getDisplayName().getString(); + if (name.startsWith(PROFILE_PREFIX)) { + profile = name.substring(PROFILE_PREFIX.length()); + } + } + } + + public static void onClientWorldJoin(ClientPlayNetworkHandler handler, PacketSender sender, MinecraftClient client) { + clientWorldJoinTime = System.currentTimeMillis(); + resetLocRawInfo(); + } + + /** + * Sends /locraw to the server if the player is on skyblock and on a new island. + */ + private static void updateLocRaw() { + if (isOnSkyblock) { + long currentTime = System.currentTimeMillis(); + if (!sentLocRaw && currentTime > clientWorldJoinTime + 1000 && currentTime > lastLocRaw + 15000) { + SkyblockerMod.getInstance().messageScheduler.sendMessageAfterCooldown("/locraw"); + sentLocRaw = true; + lastLocRaw = currentTime; + } + } else { + resetLocRawInfo(); + } + } + + /** + * Parses the /locraw reply from the server + * + * @return not display the message in chat is the command is sent by the mod + */ + public static boolean onChatMessage(Text text, boolean overlay) { + String message = text.getString(); + if (message.startsWith("{\"server\":") && message.endsWith("}")) { + JsonObject locRaw = JsonParser.parseString(message).getAsJsonObject(); + if (locRaw.has("server")) { + server = locRaw.get("server").getAsString(); + if (locRaw.has("gameType")) { + gameType = locRaw.get("gameType").getAsString(); + } + if (locRaw.has("mode")) { + locationRaw = locRaw.get("mode").getAsString(); + } + if (locRaw.has("map")) { + map = locRaw.get("map").getAsString(); + } + return !sentLocRaw; + } + } + return true; + } + + private static void resetLocRawInfo() { + sentLocRaw = false; + server = ""; + gameType = ""; + locationRaw = ""; + map = ""; + } }
\ No newline at end of file |