From af46b0c6b8d38d876e59e523d4af4c939053a988 Mon Sep 17 00:00:00 2001 From: vicisacat Date: Fri, 22 Mar 2024 08:43:08 +0100 Subject: start --- .../skyblocker/mixin/accessor/SlotAccessor.java | 14 +++ .../skyblock/auction/AuctionBrowserScreen.java | 20 ++++ .../auction/AuctionHouseScreenHandler.java | 40 ++++++++ .../skyblock/auction/SlotClickHandler.java | 11 +++ .../auction/widgets/AuctionTypeWidget.java | 66 +++++++++++++ .../auction/widgets/CategoryTabWidget.java | 61 ++++++++++++ .../skyblock/auction/widgets/SliderWidget.java | 110 +++++++++++++++++++++ .../skyblock/auction/widgets/SortWidget.java | 66 +++++++++++++ 8 files changed, 388 insertions(+) create mode 100644 src/main/java/de/hysky/skyblocker/mixin/accessor/SlotAccessor.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionHouseScreenHandler.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/auction/SlotClickHandler.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/AuctionTypeWidget.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/CategoryTabWidget.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/SliderWidget.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/SortWidget.java (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/mixin/accessor/SlotAccessor.java b/src/main/java/de/hysky/skyblocker/mixin/accessor/SlotAccessor.java new file mode 100644 index 00000000..2a0a418f --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/mixin/accessor/SlotAccessor.java @@ -0,0 +1,14 @@ +package de.hysky.skyblocker.mixin.accessor; + +import net.minecraft.screen.slot.Slot; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(Slot.class) +public interface SlotAccessor { + + @Accessor("x") + void setX(int x); + @Accessor("y") + void setY(int y); +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java new file mode 100644 index 00000000..48b528ee --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java @@ -0,0 +1,20 @@ +package de.hysky.skyblocker.skyblock.auction; + +import de.hysky.skyblocker.SkyblockerMod; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +public class AuctionBrowserScreen extends HandledScreen { + protected static final Identifier TEXTURE = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/auctions_gui/browser/background.png"); + public AuctionBrowserScreen(AuctionHouseScreenHandler handler, PlayerInventory inventory, Text title) { + super(handler, inventory, title); + } + + @Override + protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) { + context.drawTexture(TEXTURE, this.x, this.y, 0, 0, this.backgroundWidth, this.backgroundHeight); + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionHouseScreenHandler.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionHouseScreenHandler.java new file mode 100644 index 00000000..58adfc6c --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionHouseScreenHandler.java @@ -0,0 +1,40 @@ +package de.hysky.skyblocker.skyblock.auction; + +import de.hysky.skyblocker.mixin.accessor.SlotAccessor; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.Inventory; +import net.minecraft.screen.GenericContainerScreenHandler; +import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.screen.slot.Slot; + +public class AuctionHouseScreenHandler extends GenericContainerScreenHandler { + public AuctionHouseScreenHandler(ScreenHandlerType type, int syncId, PlayerInventory playerInventory, Inventory inventory, int rows, boolean isView) { + super(type, syncId, playerInventory, inventory, rows); + + int yOffset = (rows - 4) * 18; + // Shift player inventory by 2 pixels and also remove the yOffset + for (int i = rows*9; i < slots.size(); i++) { + SlotAccessor slotAccessor = (SlotAccessor) slots.get(i); + slotAccessor.setY(2-yOffset); + } + + if (isView) return; + // disable ALL THE OTHER SLOTS MWAHAHAHA and also move the good ones around and stuff + for (int i = 9; i < (rows-1)*9; i++) { + int lineI = i % 9; + Slot slot = slots.get(i); + if (lineI > 1 && lineI < 8) { + SlotAccessor slotAccessor = (SlotAccessor) slot; + slotAccessor.setX(8+ lineI * 18); + slotAccessor.setY(18 + (i/9 -1) * 18); + } else { + slots.set(i, new Slot(slot.inventory, slot.getIndex(), slot.x, slot.y){ + @Override + public boolean isEnabled() { + return false; + } + }); + } + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/SlotClickHandler.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/SlotClickHandler.java new file mode 100644 index 00000000..b64a4583 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/SlotClickHandler.java @@ -0,0 +1,11 @@ +package de.hysky.skyblocker.skyblock.auction; + +@FunctionalInterface +public interface SlotClickHandler { + + void click(int slot, int button); + + default void click(int slot) { + click(slot, 0); + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/AuctionTypeWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/AuctionTypeWidget.java new file mode 100644 index 00000000..64410d72 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/AuctionTypeWidget.java @@ -0,0 +1,66 @@ +package de.hysky.skyblocker.skyblock.auction.widgets; + +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.skyblock.auction.SlotClickHandler; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.MathHelper; + +public class AuctionTypeWidget extends SliderWidget { + + /** + * @param x x position + * @param y y position + * @param slotClick IDK figure it out + */ + public AuctionTypeWidget(int x, int y, SlotClickHandler slotClick) { + super(x, y, 17, 17, Text.literal("Auction Type Widget"), slotClick, Option.ALL); + } + + public enum Option implements OptionInfo { + ALL("all.png"), + BIN("bin.png"), + AUC("auctions.png"); + + private final Identifier texture; + private static final String prefix = "textures/gui/auctions_gui/auction_type_widget/"; + private static final Identifier HOVER_TEXTURE = new Identifier(SkyblockerMod.NAMESPACE, prefix + "hover.png"); + private static final Identifier BACK_TEXTURE = new Identifier(SkyblockerMod.NAMESPACE,prefix + "back.png"); + + Option(String textureName) { + texture = new Identifier(SkyblockerMod.NAMESPACE, prefix + textureName); + } + private static final AuctionTypeWidget.Option[] values = values(); + public static AuctionTypeWidget.Option get(int ordinal) {return values[MathHelper.clamp(ordinal, 0, values.length-1)];} + + @Override + public boolean isVertical() { + return true; + } + + @Override + public int getOffset() { + return 4 * ordinal(); + } + + @Override + public int[] getOptionSize() { + return new int[]{17, 9}; + } + + @Override + public Identifier getOptionTexture() { + return texture; + } + + @Override + public Identifier getBackTexture() { + return BACK_TEXTURE; + } + + @Override + public Identifier getHoverTexture() { + return HOVER_TEXTURE; + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/CategoryTabWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/CategoryTabWidget.java new file mode 100644 index 00000000..6c515e50 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/CategoryTabWidget.java @@ -0,0 +1,61 @@ +package de.hysky.skyblocker.skyblock.auction.widgets; + +import de.hysky.skyblocker.skyblock.auction.SlotClickHandler; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.ButtonTextures; +import net.minecraft.client.gui.widget.ToggleButtonWidget; +import net.minecraft.client.item.TooltipContext; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.NotNull; + +public class CategoryTabWidget extends ToggleButtonWidget { + private static final ButtonTextures TEXTURES = new ButtonTextures(new Identifier("recipe_book/tab"), new Identifier("recipe_book/tab_selected")); + + public void setIcon(@NotNull ItemStack icon) { + this.icon = icon.copy(); + } + + private @NotNull ItemStack icon; + private final SlotClickHandler slotClick; + private int slotId = -1; + + public CategoryTabWidget(@NotNull ItemStack icon, SlotClickHandler slotClick) { + super(0, 0, 35, 27, false); + this.icon = icon.copy(); // copy prevents item disappearing on click + this.slotClick = slotClick; + setTextures(TEXTURES); + } + + @Override + public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + if (textures == null) return; + Identifier identifier = textures.get(true, this.toggled); + int x = getX(); + if (toggled) x-=2; + //RenderSystem.disableDepthTest(); + context.drawGuiTexture(identifier, x, this.getY(), this.width, this.height); + //RenderSystem.enableDepthTest(); + context.drawItem(icon, x+9, getY()+5); + + if (isMouseOver(mouseX, mouseY)) { + context.getMatrices().push(); + //context.getMatrices().translate(0, 0, 500f); + context.drawTooltip(MinecraftClient.getInstance().textRenderer, icon.getTooltip(MinecraftClient.getInstance().player, TooltipContext.BASIC), mouseX, mouseY); + context.getMatrices().pop(); + } + + } + + public void setSlotId(int slotId) { + this.slotId = slotId; + } + + @Override + public void onClick(double mouseX, double mouseY) { + if (this.toggled || slotId == -1) return; + slotClick.click(slotId); + this.setToggled(true); + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/SliderWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/SliderWidget.java new file mode 100644 index 00000000..97543d23 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/SliderWidget.java @@ -0,0 +1,110 @@ +package de.hysky.skyblocker.skyblock.auction.widgets; + +import de.hysky.skyblocker.skyblock.auction.SlotClickHandler; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.widget.ClickableWidget; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +import java.util.function.Consumer; +import java.util.function.DoubleConsumer; + +// This is kinda excessive, but I thought it was a good idea +public class SliderWidget & SliderWidget.OptionInfo> extends ClickableWidget { + private final SlotClickHandler clickSlot; + private int button = 0; + private int slotId = -1; + + protected E current; + + float posProgress; + + /** + * + * @param x x position + * @param y y position + * @param width width + * @param height height + * @param message probably useless, just put the widget name + * @param clickSlot the parent AuctionsBrowser + * @param defaultOption the default option should be the one at ordinal 0 + */ + public SliderWidget(int x, int y, int width, int height, Text message, SlotClickHandler clickSlot, E defaultOption) { + super(x, y, width, height, message); + this.clickSlot = clickSlot; + this.current = defaultOption; + posProgress = current.getOffset(); + } + + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + if (posProgress < current.getOffset()) { + posProgress += delta * 5; + if (posProgress > current.getOffset()) posProgress = current.getOffset(); + } else if (posProgress > current.getOffset()) { + posProgress -= delta * 5; + if (posProgress < current.getOffset()) posProgress = current.getOffset(); + } + + + context.getMatrices().push(); + context.getMatrices().translate(getX(), getY(), 0); + + int x = current.isVertical() ? 0: Math.round(posProgress); + int y = current.isVertical() ? Math.round(posProgress): 0; + + int optionWidth = current.getOptionSize()[0]; + int optionHeight = current.getOptionSize()[1]; + + //context.drawText(parent.getTextRender(), String.valueOf(slotId), 0, -9, Colors.RED, true); + context.drawTexture(current.getBackTexture(), 0, 0, 0, 0, getWidth(), getHeight(), getWidth(), getHeight()); + context.drawTexture(current.getOptionTexture(), x, y, 0, 0, optionWidth, optionHeight, optionWidth, optionHeight); + if (isHovered()) { + context.drawTexture(current.getHoverTexture(), x, y, 0, 0, optionWidth, optionHeight, optionWidth, optionHeight); + + } + context.getMatrices().pop(); + } + + @Override + public void onClick(double mouseX, double mouseY) { + if (slotId == -1) return; + clickSlot.click(slotId, button); + super.onClick(mouseX, mouseY); + } + + @Override + protected boolean isValidClickButton(int button) { + this.button = button; + return super.isValidClickButton(button) || button == 1; + } + + public void setSlotId(int slotId) { + this.slotId = slotId; + } + + public void setCurrent(E current) { + this.current = current; + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) {} + public interface OptionInfo { + boolean isVertical(); + + /** + * @return The current option's position offset from the first option's position + */ + int getOffset(); + + int[] getOptionSize(); + + Identifier getOptionTexture(); + + Identifier getBackTexture(); + + Identifier getHoverTexture(); + + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/SortWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/SortWidget.java new file mode 100644 index 00000000..62c3a497 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/SortWidget.java @@ -0,0 +1,66 @@ +package de.hysky.skyblocker.skyblock.auction.widgets; + +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.skyblock.auction.SlotClickHandler; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.MathHelper; + +public class SortWidget extends SliderWidget { + + /** + * @param x x position + * @param y y position + * @param clickSlot the parent AuctionsBrowser + */ + public SortWidget(int x, int y, SlotClickHandler clickSlot) { + super(x, y, 36, 9, Text.literal("Sort Widget"), clickSlot, Option.HIGH); + } + + public enum Option implements OptionInfo { + HIGH("high.png"), + LOW("low.png"), + SOON("soon.png"), + RAND("rand.png"); + + private final Identifier texture; + private static final String prefix = "textures/gui/auctions_gui/sort_widget/"; + private static final Identifier HOVER_TEXTURE = new Identifier(SkyblockerMod.NAMESPACE, prefix + "hover.png"); + private static final Identifier BACK_TEXTURE = new Identifier(SkyblockerMod.NAMESPACE,prefix + "back.png"); + + Option(String textureName) { + texture = new Identifier(SkyblockerMod.NAMESPACE, prefix + textureName); + } + public Identifier getOptionTexture() { + return texture; + } + + private static final Option[] values = values(); + public static Option get(int ordinal) {return values[MathHelper.clamp(ordinal, 0, values.length-1)];} + + @Override + public boolean isVertical() { + return false; + } + + @Override + public int getOffset() { + return 5 * ordinal(); + } + + @Override + public int[] getOptionSize() { + return new int[]{21, 9}; + } + + @Override + public Identifier getBackTexture() { + return BACK_TEXTURE; + } + + @Override + public Identifier getHoverTexture() { + return HOVER_TEXTURE; + } + } +} -- cgit From 5b258a6cd798678b2cb98be029443c5048496a86 Mon Sep 17 00:00:00 2001 From: vicisacat Date: Fri, 22 Mar 2024 22:02:46 +0100 Subject: rebasing1 --- .../mixin/HandledScreenProviderMixin.java | 10 ++ .../skyblocker/mixin/accessor/SlotAccessor.java | 3 + .../skyblock/auction/AuctionBrowserScreen.java | 155 ++++++++++++++++++++- .../auction/AuctionHouseScreenHandler.java | 31 ++++- .../skyblock/auction/widgets/RarityWidget.java | 94 +++++++++++++ 5 files changed, 284 insertions(+), 9 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/RarityWidget.java (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/mixin/HandledScreenProviderMixin.java b/src/main/java/de/hysky/skyblocker/mixin/HandledScreenProviderMixin.java index 975c9c51..cd2baa4b 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/HandledScreenProviderMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixin/HandledScreenProviderMixin.java @@ -2,6 +2,8 @@ package de.hysky.skyblocker.mixin; import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.skyblock.auction.AuctionBrowserScreen; +import de.hysky.skyblocker.skyblock.auction.AuctionHouseScreenHandler; import de.hysky.skyblocker.skyblock.dungeon.partyfinder.PartyFinderScreen; import de.hysky.skyblocker.skyblock.item.SkyblockCraftingTableScreenHandler; import de.hysky.skyblocker.skyblock.item.SkyblockCraftingTableScreen; @@ -26,6 +28,8 @@ public interface HandledScreenProviderMixin { if (player == null) return; if (!Utils.isOnSkyblock()) return; T screenHandler = type.create(id, player.getInventory()); + if (!(screenHandler instanceof GenericContainerScreenHandler containerScreenHandler)) return; + if (PartyFinderScreen.possibleInventoryNames.contains(name.getString().toLowerCase())) { if (SkyblockerConfigManager.get().general.betterPartyFinder && screenHandler instanceof GenericContainerScreenHandler containerScreenHandler && PartyFinderScreen.possibleInventoryNames.contains(name.getString().toLowerCase())) { if (client.currentScreen != null) { String lowerCase = client.currentScreen.getTitle().getString().toLowerCase(); @@ -44,6 +48,12 @@ public interface HandledScreenProviderMixin { client.setScreen(new PartyFinderScreen(containerScreenHandler, player.getInventory(), name)); } + ci.cancel(); + } else if (name.getString().toLowerCase().contains("auctions browser")) { + System.out.println("another one"); + AuctionHouseScreenHandler auctionHouseScreenHandler = AuctionHouseScreenHandler.of(containerScreenHandler, false); + client.player.currentScreenHandler = auctionHouseScreenHandler; + client.setScreen(new AuctionBrowserScreen(auctionHouseScreenHandler, client.player.getInventory())); ci.cancel(); } else if (SkyblockerConfigManager.get().general.fancyCraftingTable && screenHandler instanceof GenericContainerScreenHandler containerScreenHandler && name.getString().toLowerCase().contains("craft item")) { SkyblockCraftingTableScreenHandler skyblockCraftingTableScreenHandler = new SkyblockCraftingTableScreenHandler(containerScreenHandler, player.getInventory()); diff --git a/src/main/java/de/hysky/skyblocker/mixin/accessor/SlotAccessor.java b/src/main/java/de/hysky/skyblocker/mixin/accessor/SlotAccessor.java index 2a0a418f..b8c5618f 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/accessor/SlotAccessor.java +++ b/src/main/java/de/hysky/skyblocker/mixin/accessor/SlotAccessor.java @@ -2,13 +2,16 @@ package de.hysky.skyblocker.mixin.accessor; import net.minecraft.screen.slot.Slot; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.gen.Accessor; @Mixin(Slot.class) public interface SlotAccessor { + @Mutable @Accessor("x") void setX(int x); + @Mutable @Accessor("y") void setY(int y); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java index 48b528ee..a06b9649 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java @@ -1,20 +1,169 @@ package de.hysky.skyblocker.skyblock.auction; import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.skyblock.auction.widgets.AuctionTypeWidget; +import de.hysky.skyblocker.skyblock.auction.widgets.CategoryTabWidget; +import de.hysky.skyblocker.skyblock.auction.widgets.RarityWidget; +import de.hysky.skyblocker.skyblock.auction.widgets.SortWidget; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.client.gui.tooltip.Tooltip; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.item.TooltipContext; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.screen.ScreenHandlerListener; +import net.minecraft.screen.slot.SlotActionType; import net.minecraft.text.Text; import net.minecraft.util.Identifier; +import net.minecraft.util.math.MathHelper; -public class AuctionBrowserScreen extends HandledScreen { +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +public class AuctionBrowserScreen extends HandledScreen implements ScreenHandlerListener { protected static final Identifier TEXTURE = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/auctions_gui/browser/background.png"); - public AuctionBrowserScreen(AuctionHouseScreenHandler handler, PlayerInventory inventory, Text title) { - super(handler, inventory, title); + + // WIDGETS + private SortWidget sortWidget; + private AuctionTypeWidget auctionTypeWidget; + private RarityWidget rarityWidget; + private ButtonWidget resetFiltersButton; + private final List categoryTabWidgets = new ArrayList<>(6); + + public static int RESET_SLOT_ID = 45; + + + boolean isWaitingForServer = false; + + public AuctionBrowserScreen(AuctionHouseScreenHandler handler, PlayerInventory inventory) { + super(handler, inventory, Text.literal("Auctions Browser")); + this.backgroundHeight = 187; + this.playerInventoryTitleY = 92; + this.titleX = 999; + handler.addListener(this); + } + + @Override + protected void init() { + super.init(); + x = (this.width - 176) / 2; + y = (this.height - 187) / 2; + sortWidget = new SortWidget(x + 25, y + 81, this::clickSlot); + sortWidget.setSlotId(50); + addDrawableChild(sortWidget); + auctionTypeWidget = new AuctionTypeWidget(x + 134, y + 77, this::clickSlot); + auctionTypeWidget.setSlotId(52); + addDrawableChild(auctionTypeWidget); + rarityWidget = new RarityWidget(x + 73, y + 80, this::clickSlot); + rarityWidget.setSlotId(51); + addDrawableChild(rarityWidget); + resetFiltersButton = new ScaledTextButtonWidget(x + 10, y + 77, 12, 12, Text.literal("↻"), this::onResetPressed); + addDrawableChild(resetFiltersButton); + resetFiltersButton.setTooltip(Tooltip.of(Text.literal("Reset Filters"))); + resetFiltersButton.setTooltipDelay(500); + if (categoryTabWidgets.isEmpty()) + for (int i = 0; i < 6; i++) { + CategoryTabWidget categoryTabWidget = new CategoryTabWidget(new ItemStack(Items.SPONGE), this::clickSlot); + categoryTabWidgets.add(categoryTabWidget); + addSelectableChild(categoryTabWidget); // This method only makes it clickable, does not add it to the drawables list + // manually rendered in the render method to have it not render behind the durability bars + categoryTabWidget.setPosition(x - 30, y + 3 + i * 28); + } + else + for (int i = 0; i < categoryTabWidgets.size(); i++) { + CategoryTabWidget categoryTabWidget = categoryTabWidgets.get(i); + categoryTabWidget.setPosition(x - 30, y + 3 + i * 28); + + } + } + + protected void clickSlot(int slotID, int button) { + if (isWaitingForServer) return; + if (client == null) return; + assert this.client.interactionManager != null; + this.client.interactionManager.clickSlot(handler.syncId, slotID, button, SlotActionType.PICKUP, client.player); + } + + private void onResetPressed(ButtonWidget buttonWidget) { + buttonWidget.setFocused(false); // Annoying. + if (RESET_SLOT_ID == -1) return; + this.clickSlot(RESET_SLOT_ID, 0); } @Override protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) { context.drawTexture(TEXTURE, this.x, this.y, 0, 0, this.backgroundWidth, this.backgroundHeight); } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + super.render(context, mouseX, mouseY, delta); + this.drawMouseoverTooltip(context, mouseX, mouseY); + } + + private static int getOrdinal(List tooltip) { + int ordinal = 0; + for (int j = 0; j < tooltip.size()-3; j++) { + if (j+2 >= tooltip.size()) break; + if (tooltip.get(j+2).getString().contains("▶")) { + ordinal = j; + break; + } + } + return ordinal; + } + + @Override + public void onSlotUpdate(ScreenHandler handler, int slotId, ItemStack stack) { + if (client == null || stack.isEmpty()) return; + if (slotId == 50) { + sortWidget.setCurrent(SortWidget.Option.get(getOrdinal(stack.getTooltip(client.player, TooltipContext.BASIC)))); + } else if (slotId == 52) { + auctionTypeWidget.setCurrent(AuctionTypeWidget.Option.get(getOrdinal(stack.getTooltip(client.player, TooltipContext.BASIC)))); + } else if (slotId == 51) { + List tooltip = stack.getTooltip(client.player, TooltipContext.BASIC); + int ordinal = getOrdinal(tooltip); + String split = tooltip.get(ordinal+2).getString().substring(2); + rarityWidget.setText(tooltip.subList(1, tooltip.size()-3), split); + } else if (slotId == 45) { + if (resetFiltersButton != null) resetFiltersButton.active = handler.getSlot(slotId).getStack().isOf(Items.ANVIL); + } + } + + @Override + public void removed() { + super.removed(); + handler.removeListener(this); + } + + @Override + public void onPropertyUpdate(ScreenHandler handler, int property, int value) {} + + private static class ScaledTextButtonWidget extends ButtonWidget { + + protected ScaledTextButtonWidget(int x, int y, int width, int height, Text message, PressAction onPress) { + super(x, y, width, height, message, onPress, Supplier::get); + } + + // Code taken mostly from YACL by isxander. Love you <3 + @Override + public void drawMessage(DrawContext graphics, TextRenderer textRenderer, int color) { + TextRenderer font = MinecraftClient.getInstance().textRenderer; + MatrixStack pose = graphics.getMatrices(); + float textScale = 2.f; + + pose.push(); + pose.translate(((this.getX() + this.width / 2f) - font.getWidth(getMessage()) * textScale / 2) + 1, (float)this.getY() + (this.height - font.fontHeight * textScale) / 2f - 1, 0); + pose.scale(textScale, textScale, 1); + graphics.drawText(font, getMessage(), 0, 0, color | MathHelper.ceil(this.alpha * 255.0F) << 24, true); + pose.pop(); + } + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionHouseScreenHandler.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionHouseScreenHandler.java index 58adfc6c..7df3cef5 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionHouseScreenHandler.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionHouseScreenHandler.java @@ -1,8 +1,10 @@ package de.hysky.skyblocker.skyblock.auction; import de.hysky.skyblocker.mixin.accessor.SlotAccessor; +import net.minecraft.client.MinecraftClient; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.Inventory; +import net.minecraft.item.ItemStack; import net.minecraft.screen.GenericContainerScreenHandler; import net.minecraft.screen.ScreenHandlerType; import net.minecraft.screen.slot.Slot; @@ -14,19 +16,21 @@ public class AuctionHouseScreenHandler extends GenericContainerScreenHandler { int yOffset = (rows - 4) * 18; // Shift player inventory by 2 pixels and also remove the yOffset for (int i = rows*9; i < slots.size(); i++) { - SlotAccessor slotAccessor = (SlotAccessor) slots.get(i); - slotAccessor.setY(2-yOffset); + Slot slot = slots.get(i); + SlotAccessor slotAccessor = (SlotAccessor) slot; + slotAccessor.setY(slot.y+2-yOffset); } if (isView) return; // disable ALL THE OTHER SLOTS MWAHAHAHA and also move the good ones around and stuff - for (int i = 9; i < (rows-1)*9; i++) { + for (int i = 0; i < rows*9; i++) { int lineI = i % 9; Slot slot = slots.get(i); - if (lineI > 1 && lineI < 8) { + if (i>9 && i<(rows-1)*9 && lineI > 1 && lineI < 8) { + int miniInventorySlot = lineI - 2 + (i/9 - 1)*6; SlotAccessor slotAccessor = (SlotAccessor) slot; - slotAccessor.setX(8+ lineI * 18); - slotAccessor.setY(18 + (i/9 -1) * 18); + slotAccessor.setX(8 + miniInventorySlot%8 * 18); + slotAccessor.setY(18 + miniInventorySlot/8 * 18); } else { slots.set(i, new Slot(slot.inventory, slot.getIndex(), slot.x, slot.y){ @Override @@ -37,4 +41,19 @@ public class AuctionHouseScreenHandler extends GenericContainerScreenHandler { } } } + + public static AuctionHouseScreenHandler of(GenericContainerScreenHandler original, boolean isView) { + return new AuctionHouseScreenHandler(original.getType(), + original.syncId, + MinecraftClient.getInstance().player.getInventory(), + original.getInventory(), + original.getRows(), + isView); + } + + @Override + public void setStackInSlot(int slot, int revision, ItemStack stack) { + super.setStackInSlot(slot, revision, stack); + onContentChanged(slots.get(slot).inventory); + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/RarityWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/RarityWidget.java new file mode 100644 index 00000000..1affdc0c --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/widgets/RarityWidget.java @@ -0,0 +1,94 @@ +package de.hysky.skyblocker.skyblock.auction.widgets; + +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.skyblock.auction.SlotClickHandler; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.widget.ClickableWidget; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +import java.util.List; + +public class RarityWidget extends ClickableWidget { + + private static final Identifier HOVER_TEXTURE = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/auctions_gui/rarity_widget/hover.png"); + private static final Identifier TEXTURE = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/auctions_gui/rarity_widget/background.png"); + private final SlotClickHandler onClick; + private int slotId = -1; + + public RarityWidget(int x, int y, SlotClickHandler onClick) { + super(x, y, 48, 11, Text.literal("rarity selector thing, hi mom")); + this.onClick = onClick; + } + + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { + MatrixStack matrices = context.getMatrices(); + matrices.push(); + matrices.translate(getX(), getY(), 0); + //context.drawText(parent.getTextRender(), String.valueOf(slotId), 0, -9, Colors.RED, true); + boolean onLeftArrow = isOnLeftArrow(mouseX); + boolean onRightArrow = isOnRightArrow(mouseX); + context.drawTexture(TEXTURE, 0, 0, 0, 0, 48, 11, 48, 11); + if (onLeftArrow) context.drawTexture(HOVER_TEXTURE, 0, 0, 0, 0, 6, 11, 6, 11); + if (onRightArrow) context.drawTexture(HOVER_TEXTURE, 42, 0, 0, 0, 6, 11, 6, 11); + + // Text + TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + int textWidth = textRenderer.getWidth(current); + int color = 0xFFEAEAEA; + if (textWidth > 34) { + matrices.push(); + //matrices.translate(-7-getX(), -5.5f-getY(), 0); + matrices.translate(7, 5.5f, 0); + matrices.scale(34.f/textWidth, 34.f/textWidth, 1.f); + context.drawText(textRenderer, current, 0, -textRenderer.fontHeight/2, color, false); + matrices.pop(); + } else { + context.drawText(textRenderer, current, 7, 2, color, false); + } + + matrices.pop(); + if (!onLeftArrow && !onRightArrow && isHovered()) context.drawTooltip(textRenderer, tooltip, mouseX, mouseY); + + } + + private boolean isOnRightArrow(int mouseX) { + return isHovered() && mouseX - getX() > 40; + } + + private boolean isOnLeftArrow(int mouseX) { + return isHovered() && mouseX - getX() < 7; + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) { + + } + + public void setSlotId(int slotId) { + this.slotId = slotId; + } + + private List tooltip = List.of(); + private String current = "?"; + + public void setText(List tooltip, String current) { + this.tooltip = tooltip; + this.current = current; + } + + @Override + public void onClick(double mouseX, double mouseY) { + if (slotId == -1) return; + if (isOnLeftArrow((int) mouseX)) { + onClick.click(slotId, 1); + } else if (isOnRightArrow((int) mouseX)) { + onClick.click(slotId, 0); + } + } +} -- cgit From 8e487a87c51da89072c70f9c46e0b0e5d423d45f Mon Sep 17 00:00:00 2001 From: vicisacat Date: Sat, 23 Mar 2024 21:19:33 +0100 Subject: it works ain't that GREAT --- .../skyblocker/mixin/ClientPlayerEntityMixin.java | 7 + .../mixin/HandledScreenProviderMixin.java | 23 ++- .../mixin/accessor/HandledScreenAccessor.java | 6 + .../skyblock/auction/AuctionBrowserScreen.java | 212 +++++++++++++++++---- .../auction/AuctionHouseScreenHandler.java | 4 +- .../skyblock/auction/AuctionViewScreen.java | 201 +++++++++++++++++++ .../skyblocker/skyblock/auction/EditBidPopup.java | 99 ++++++++++ .../utils/render/gui/AbstractCustomHypixelGUI.java | 56 ++++++ .../utils/render/gui/BarebonesPopupScreen.java | 56 ++++++ 9 files changed, 616 insertions(+), 48 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionViewScreen.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java create mode 100644 src/main/java/de/hysky/skyblocker/utils/render/gui/AbstractCustomHypixelGUI.java create mode 100644 src/main/java/de/hysky/skyblocker/utils/render/gui/BarebonesPopupScreen.java (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayerEntityMixin.java b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayerEntityMixin.java index ceda9ed4..049443f7 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayerEntityMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayerEntityMixin.java @@ -2,6 +2,8 @@ package de.hysky.skyblocker.mixin; import com.mojang.authlib.GameProfile; import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.skyblock.auction.AuctionViewScreen; +import de.hysky.skyblocker.skyblock.auction.EditBidPopup; import de.hysky.skyblocker.skyblock.dungeon.partyfinder.PartyFinderScreen; import de.hysky.skyblocker.skyblock.item.HotbarSlotLock; import de.hysky.skyblocker.skyblock.item.ItemProtection; @@ -58,6 +60,11 @@ public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity return; } + if (client.currentScreen instanceof AuctionViewScreen auctionViewScreen) { + this.client.setScreen(new EditBidPopup(auctionViewScreen, sign, front, auctionViewScreen.minBid)); + callbackInfo.cancel(); + } + // Search Overlay if (client.currentScreen != null) { if (SkyblockerConfigManager.get().general.searchOverlay.enableAuctionHouse && client.currentScreen.getTitle().getString().toLowerCase().contains("auction")) { diff --git a/src/main/java/de/hysky/skyblocker/mixin/HandledScreenProviderMixin.java b/src/main/java/de/hysky/skyblocker/mixin/HandledScreenProviderMixin.java index cd2baa4b..10d65669 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/HandledScreenProviderMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixin/HandledScreenProviderMixin.java @@ -2,8 +2,10 @@ package de.hysky.skyblocker.mixin; import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.mixin.accessor.HandledScreenAccessor; import de.hysky.skyblocker.skyblock.auction.AuctionBrowserScreen; import de.hysky.skyblocker.skyblock.auction.AuctionHouseScreenHandler; +import de.hysky.skyblocker.skyblock.auction.AuctionViewScreen; import de.hysky.skyblocker.skyblock.dungeon.partyfinder.PartyFinderScreen; import de.hysky.skyblocker.skyblock.item.SkyblockCraftingTableScreenHandler; import de.hysky.skyblocker.skyblock.item.SkyblockCraftingTableScreen; @@ -29,7 +31,8 @@ public interface HandledScreenProviderMixin { if (!Utils.isOnSkyblock()) return; T screenHandler = type.create(id, player.getInventory()); if (!(screenHandler instanceof GenericContainerScreenHandler containerScreenHandler)) return; - if (PartyFinderScreen.possibleInventoryNames.contains(name.getString().toLowerCase())) { + String nameLowercase = name.getString().toLowerCase(); + if (PartyFinderScreen.possibleInventoryNames.contains(nameLowercase)) { if (SkyblockerConfigManager.get().general.betterPartyFinder && screenHandler instanceof GenericContainerScreenHandler containerScreenHandler && PartyFinderScreen.possibleInventoryNames.contains(name.getString().toLowerCase())) { if (client.currentScreen != null) { String lowerCase = client.currentScreen.getTitle().getString().toLowerCase(); @@ -49,11 +52,23 @@ public interface HandledScreenProviderMixin { } ci.cancel(); - } else if (name.getString().toLowerCase().contains("auctions browser")) { - System.out.println("another one"); + } else if (nameLowercase.contains("auctions browser") || nameLowercase.contains("auctions: ")) { AuctionHouseScreenHandler auctionHouseScreenHandler = AuctionHouseScreenHandler.of(containerScreenHandler, false); client.player.currentScreenHandler = auctionHouseScreenHandler; - client.setScreen(new AuctionBrowserScreen(auctionHouseScreenHandler, client.player.getInventory())); + if (client.currentScreen instanceof AuctionBrowserScreen auctionBrowserScreen) { + auctionBrowserScreen.changeHandler(auctionHouseScreenHandler); + } else client.setScreen(new AuctionBrowserScreen(auctionHouseScreenHandler, client.player.getInventory())); + ci.cancel(); + } else if (nameLowercase.contains("auction view")) { + AuctionHouseScreenHandler auctionHouseScreenHandler = AuctionHouseScreenHandler.of(containerScreenHandler, true); + client.player.currentScreenHandler = auctionHouseScreenHandler; + if (client.currentScreen instanceof AuctionViewScreen auctionViewScreen) { + auctionViewScreen.changeHandler(auctionHouseScreenHandler); + } else client.setScreen(new AuctionViewScreen(auctionHouseScreenHandler, client.player.getInventory(), name)); + ci.cancel(); + } else if ((nameLowercase.contains("confirm purchase") || nameLowercase.contains("confirm bid")) && client.currentScreen instanceof AuctionViewScreen auctionViewScreen) { + client.setScreen(auctionViewScreen.getConfirmPurchasePopup(name)); + client.player.currentScreenHandler = containerScreenHandler; ci.cancel(); } else if (SkyblockerConfigManager.get().general.fancyCraftingTable && screenHandler instanceof GenericContainerScreenHandler containerScreenHandler && name.getString().toLowerCase().contains("craft item")) { SkyblockCraftingTableScreenHandler skyblockCraftingTableScreenHandler = new SkyblockCraftingTableScreenHandler(containerScreenHandler, player.getInventory()); diff --git a/src/main/java/de/hysky/skyblocker/mixin/accessor/HandledScreenAccessor.java b/src/main/java/de/hysky/skyblocker/mixin/accessor/HandledScreenAccessor.java index d82422cb..5b84072d 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/accessor/HandledScreenAccessor.java +++ b/src/main/java/de/hysky/skyblocker/mixin/accessor/HandledScreenAccessor.java @@ -1,7 +1,9 @@ package de.hysky.skyblocker.mixin.accessor; import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.screen.ScreenHandler; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.gen.Accessor; @Mixin(HandledScreen.class) @@ -17,4 +19,8 @@ public interface HandledScreenAccessor { @Accessor int getBackgroundHeight(); + + @Mutable + @Accessor("handler") + void setHandler(ScreenHandler handler); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java index a06b9649..11a41d0c 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionBrowserScreen.java @@ -5,21 +5,23 @@ import de.hysky.skyblocker.skyblock.auction.widgets.AuctionTypeWidget; import de.hysky.skyblocker.skyblock.auction.widgets.CategoryTabWidget; import de.hysky.skyblocker.skyblock.auction.widgets.RarityWidget; import de.hysky.skyblocker.skyblock.auction.widgets.SortWidget; +import de.hysky.skyblocker.utils.render.gui.AbstractCustomHypixelGUI; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.gui.tooltip.Tooltip; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.item.TooltipContext; +import net.minecraft.client.texture.Sprite; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; -import net.minecraft.screen.ScreenHandler; -import net.minecraft.screen.ScreenHandlerListener; +import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.SlotActionType; +import net.minecraft.text.Style; import net.minecraft.text.Text; +import net.minecraft.util.Colors; import net.minecraft.util.Identifier; import net.minecraft.util.math.MathHelper; @@ -27,8 +29,27 @@ import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; -public class AuctionBrowserScreen extends HandledScreen implements ScreenHandlerListener { +public class AuctionBrowserScreen extends AbstractCustomHypixelGUI { protected static final Identifier TEXTURE = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/auctions_gui/browser/background.png"); + private static final Identifier SCROLLER_TEXTURE = new Identifier("container/creative_inventory/scroller"); + + private static final Identifier up_arrow_tex = new Identifier(SkyblockerMod.NAMESPACE, "up_arrow_even"); // Put them in their own fields to avoid object allocation on each frame + private static final Identifier down_arrow_tex = new Identifier(SkyblockerMod.NAMESPACE, "down_arrow_even"); + public static final Supplier UP_ARROW = () -> MinecraftClient.getInstance().getGuiAtlasManager().getSprite(up_arrow_tex); + public static final Supplier DOWN_ARROW = () -> MinecraftClient.getInstance().getGuiAtlasManager().getSprite(down_arrow_tex); + + + // SLOTS + public static final int RESET_BUTTON_SLOT = 47; + public static final int SEARCH_BUTTON_SLOT = 48; + public static final int BACK_BUTTON_SLOT = 49; + public static final int SORT_BUTTON_SLOT = 50; + public static final int RARITY_BUTTON_SLOT = 51; + public static final int AUCTION_TYPE_BUTTON_SLOT = 52; + + public static final int PREV_PAGE_BUTTON = 46; + public static final int NEXT_PAGE_BUTTON = 53; + // WIDGETS private SortWidget sortWidget; @@ -36,18 +57,13 @@ public class AuctionBrowserScreen extends HandledScreen categoryTabWidgets = new ArrayList<>(6); - - public static int RESET_SLOT_ID = 45; - - - boolean isWaitingForServer = false; + private String search; public AuctionBrowserScreen(AuctionHouseScreenHandler handler, PlayerInventory inventory) { super(handler, inventory, Text.literal("Auctions Browser")); this.backgroundHeight = 187; this.playerInventoryTitleY = 92; this.titleX = 999; - handler.addListener(this); } @Override @@ -56,13 +72,13 @@ public class AuctionBrowserScreen extends HandledScreen tooltip) { - int ordinal = 0; - for (int j = 0; j < tooltip.size()-3; j++) { - if (j+2 >= tooltip.size()) break; - if (tooltip.get(j+2).getString().contains("▶")) { - ordinal = j; - break; - } + @Override + protected void onMouseClick(Slot slot, int slotId, int button, SlotActionType actionType) { + if (slotId >= handler.getRows()*9) return; + super.onMouseClick(slot, slotId, button, actionType); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (isWaitingForServer) return super.mouseClicked(mouseX, mouseY, button); + if (onScrollbarTop((int)mouseX, (int) mouseY) && prevPageVisible) { + clickSlot(PREV_PAGE_BUTTON); + return true; } - return ordinal; + if (onScrollbarBottom((int)mouseX, (int) mouseY) && nextPageVisible) { + clickSlot(NEXT_PAGE_BUTTON); + return true; + } + + if (onSearchField((int)mouseX, (int) mouseY)) { + clickSlot(SEARCH_BUTTON_SLOT); + return true; + } + return super.mouseClicked(mouseX, mouseY, button); + } + + private boolean onScrollbarTop(int mouseX, int mouseY) { + int localX = mouseX - x; + int localY = mouseY - y; + return localX > 154 && localX < 169 && localY > 6 && localY < 44; + } + + private boolean onScrollbarBottom(int mouseX, int mouseY) { + int localX = mouseX - x; + int localY = mouseY - y; + return localX > 154 && localX < 169 && localY > 43 && localY < 80; + } + private boolean onSearchField(int mouseX, int mouseY) { + int localX = mouseX - x; + int localY = mouseY - y; + return localX > 6 && localX < 97 && localY > 3 && localY < 16; } @Override - public void onSlotUpdate(ScreenHandler handler, int slotId, ItemStack stack) { + public void onSlotChange(AuctionHouseScreenHandler handler, int slotId, ItemStack stack) { if (client == null || stack.isEmpty()) return; - if (slotId == 50) { + isWaitingForServer = false; + if (slotId == PREV_PAGE_BUTTON) prevPageVisible = false; + if (slotId == NEXT_PAGE_BUTTON) nextPageVisible = false; + if (slotId == SORT_BUTTON_SLOT) { sortWidget.setCurrent(SortWidget.Option.get(getOrdinal(stack.getTooltip(client.player, TooltipContext.BASIC)))); - } else if (slotId == 52) { + } else if (slotId == AUCTION_TYPE_BUTTON_SLOT) { auctionTypeWidget.setCurrent(AuctionTypeWidget.Option.get(getOrdinal(stack.getTooltip(client.player, TooltipContext.BASIC)))); - } else if (slotId == 51) { + } else if (slotId == RARITY_BUTTON_SLOT) { List tooltip = stack.getTooltip(client.player, TooltipContext.BASIC); int ordinal = getOrdinal(tooltip); String split = tooltip.get(ordinal+2).getString().substring(2); rarityWidget.setText(tooltip.subList(1, tooltip.size()-3), split); - } else if (slotId == 45) { + } else if (slotId == RESET_BUTTON_SLOT) { if (resetFiltersButton != null) resetFiltersButton.active = handler.getSlot(slotId).getStack().isOf(Items.ANVIL); + } else if (slotId < this.handler.getRows()*9 && slotId%9 == 0) { + CategoryTabWidget categoryTabWidget = categoryTabWidgets.get(slotId / 9); + categoryTabWidget.setSlotId(slotId); + categoryTabWidget.setIcon(handler.getSlot(slotId).getStack()); + List tooltip = handler.getSlot(slotId).getStack().getTooltip(client.player, TooltipContext.BASIC); + for (int j = tooltip.size() - 1; j >= 0; j--) { + String lowerCase = tooltip.get(j).getString().toLowerCase(); + if (lowerCase.contains("currently")) { + categoryTabWidget.setToggled(true); + break; + } else if (lowerCase.contains("click")) { + categoryTabWidget.setToggled(false); + break; + } else categoryTabWidget.setToggled(false); + } + } else if (slotId == PREV_PAGE_BUTTON && stack.isOf(Items.ARROW)) { + prevPageVisible = true; + parsePage(stack); + } else if (slotId == NEXT_PAGE_BUTTON && stack.isOf(Items.ARROW)) { + nextPageVisible = true; + parsePage(stack); + } else if (slotId == SEARCH_BUTTON_SLOT) { + List tooltip = stack.getTooltip(client.player, TooltipContext.BASIC); + for (Text text : tooltip) { + String string = text.getString(); + if (string.contains("Filtered:")) { + String[] split = string.split(":"); + if (split.length < 2) { + search = ""; + } else search = split[1].trim(); + break; + } + } } } - @Override - public void removed() { - super.removed(); - handler.removeListener(this); + private static int getOrdinal(List tooltip) { + int ordinal = 0; + for (int j = 0; j < tooltip.size()-3; j++) { + if (j+2 >= tooltip.size()) break; + if (tooltip.get(j+2).getString().contains("▶")) { + ordinal = j; + break; + } + } + return ordinal; + } + + int currentPage = 0; + int totalPages = 1; + private boolean prevPageVisible = false; + private boolean nextPageVisible = false; + private void parsePage(ItemStack stack) { + List tooltip = stack.getTooltip(client.player, TooltipContext.BASIC); + String str = tooltip.get(1).getString().trim(); + str = str.substring(1, str.length() - 1); // remove parentheses + String[] parts = str.split("/"); // split the string + try { + currentPage = Integer.parseInt(parts[0].replace(",", "")); // parse current page + totalPages = Integer.parseInt(parts[1].replace(",", "")); // parse total + } catch (NumberFormatException ignored) {} } @Override - public void onPropertyUpdate(ScreenHandler handler, int property, int value) {} + protected boolean isClickOutsideBounds(double mouseX, double mouseY, int left, int top, int button) { + return mouseX < (double)left - 32 || mouseY < (double)top || mouseX >= (double)(left + this.backgroundWidth) || mouseY >= (double)(top + this.backgroundHeight); + } private static class ScaledTextButtonWidget extends ButtonWidget { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionHouseScreenHandler.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionHouseScreenHandler.java index 7df3cef5..fbc9fb17 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionHouseScreenHandler.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionHouseScreenHandler.java @@ -20,13 +20,11 @@ public class AuctionHouseScreenHandler extends GenericContainerScreenHandler { SlotAccessor slotAccessor = (SlotAccessor) slot; slotAccessor.setY(slot.y+2-yOffset); } - - if (isView) return; // disable ALL THE OTHER SLOTS MWAHAHAHA and also move the good ones around and stuff for (int i = 0; i < rows*9; i++) { int lineI = i % 9; Slot slot = slots.get(i); - if (i>9 && i<(rows-1)*9 && lineI > 1 && lineI < 8) { + if (!isView && i>9 && i<(rows-1)*9 && lineI > 1 && lineI < 8) { int miniInventorySlot = lineI - 2 + (i/9 - 1)*6; SlotAccessor slotAccessor = (SlotAccessor) slot; slotAccessor.setX(8 + miniInventorySlot%8 * 18); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionViewScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionViewScreen.java new file mode 100644 index 00000000..d482ccd8 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/AuctionViewScreen.java @@ -0,0 +1,201 @@ +package de.hysky.skyblocker.skyblock.auction; + +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.utils.render.gui.AbstractCustomHypixelGUI; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.PopupScreen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.DirectionalLayoutWidget; +import net.minecraft.client.gui.widget.SimplePositioningWidget; +import net.minecraft.client.gui.widget.TextWidget; +import net.minecraft.client.item.TooltipContext; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.screen.slot.SlotActionType; +import net.minecraft.text.MutableText; +import net.minecraft.text.Style; +import net.minecraft.text.Text; +import net.minecraft.util.Colors; +import net.minecraft.util.Formatting; +import net.minecraft.util.Identifier; + +import java.util.List; + +public class AuctionViewScreen extends AbstractCustomHypixelGUI { + protected static final Identifier BACKGROUND_TEXTURE = new Identifier(SkyblockerMod.NAMESPACE,"textures/gui/auctions_gui/browser/background_view.png"); + + DirectionalLayoutWidget verticalLayout = DirectionalLayoutWidget.vertical(); + + public final boolean isBinAuction; + private TextWidget priceWidget; + private final Text clickToEditBidText = Text.literal("Click to edit Bid!").setStyle(Style.EMPTY.withUnderline(true)); + + private TextWidget cantAffordText; + public String minBid = ""; + + private BuyState buyState = BuyState.CANT_AFFORD; + private MutableText priceText = Text.literal("?"); + + public AuctionViewScreen(AuctionHouseScreenHandler handler, PlayerInventory inventory, Text title) { + super(handler, inventory, title); + backgroundHeight = 187; + isBinAuction = this.getTitle().getString().toLowerCase().contains("bin"); + playerInventoryTitleY = 93; + } + + @Override + protected void init() { + super.init(); + verticalLayout.spacing(2).getMainPositioner().alignHorizontalCenter(); + verticalLayout.add(new TextWidget(Text.literal(isBinAuction ? "Price:" : "New Bid:"), textRenderer).alignCenter()); + + priceWidget = new TextWidget(Text.literal("?"), textRenderer).alignCenter(); + priceWidget.setWidth(textRenderer.getWidth(clickToEditBidText)); + priceWidget.active = true; + verticalLayout.add(priceWidget); + + cantAffordText = new TextWidget(Text.literal("Can't Afford"), textRenderer).alignCenter(); + verticalLayout.add(cantAffordText); + + verticalLayout.add(ButtonWidget.builder(Text.literal(isBinAuction?"Buy!":"Bid!"), button -> { + if (buySlotID == -1) return; + clickSlot(buySlotID); + }).size(50, 12).build()); + verticalLayout.forEachChild(this::addDrawableChild); + updateLayout(); + + + } + + private void changeState(BuyState newState) { + if (newState == buyState) return; + buyState = newState; + switch (buyState) { + case CANT_AFFORD -> cantAffordText.setMessage(Text.literal("Can't Afford!").withColor(Colors.RED)); + case TOP_BID -> cantAffordText.setMessage(Text.literal("Already top bid!").withColor(Colors.LIGHT_YELLOW)); + case AFFORD -> cantAffordText.setMessage(Text.empty()); + } + cantAffordText.setWidth(textRenderer.getWidth(cantAffordText.getMessage())); + updateLayout(); + } + + private void updateLayout() { + verticalLayout.refreshPositions(); + SimplePositioningWidget.setPos(verticalLayout, x, y+36, backgroundWidth, 60); + } + + @Override + protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) { + context.drawTexture(BACKGROUND_TEXTURE, this.x, this.y, 0, 0, this.backgroundWidth, this.backgroundHeight); + } + + @Override +