diff options
author | vicisacat <victor.branchu@gmail.com> | 2024-03-23 21:19:33 +0100 |
---|---|---|
committer | vicisacat <victor.branchu@gmail.com> | 2024-04-12 17:18:23 +0200 |
commit | 8e487a87c51da89072c70f9c46e0b0e5d423d45f (patch) | |
tree | 7163407dbb3e6025dd5e142d7935289d382aaa9a /src | |
parent | 5b258a6cd798678b2cb98be029443c5048496a86 (diff) | |
download | Skyblocker-8e487a87c51da89072c70f9c46e0b0e5d423d45f.tar.gz Skyblocker-8e487a87c51da89072c70f9c46e0b0e5d423d45f.tar.bz2 Skyblocker-8e487a87c51da89072c70f9c46e0b0e5d423d45f.zip |
it works ain't that GREAT
Diffstat (limited to 'src')
9 files changed, 616 insertions, 48 deletions
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<T extends ScreenHandler> { 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<T extends ScreenHandler> { } 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<AuctionHouseScreenHandler> implements ScreenHandlerListener { +public class AuctionBrowserScreen extends AbstractCustomHypixelGUI<AuctionHouseScreenHandler> { 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<Sprite> UP_ARROW = () -> MinecraftClient.getInstance().getGuiAtlasManager().getSprite(up_arrow_tex); + public static final Supplier<Sprite> 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<AuctionHouseScreenHandle private RarityWidget rarityWidget; private ButtonWidget resetFiltersButton; private final List<CategoryTabWidget> 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<AuctionHouseScreenHandle x = (this.width - 176) / 2; y = (this.height - 187) / 2; sortWidget = new SortWidget(x + 25, y + 81, this::clickSlot); - sortWidget.setSlotId(50); + sortWidget.setSlotId(SORT_BUTTON_SLOT); addDrawableChild(sortWidget); auctionTypeWidget = new AuctionTypeWidget(x + 134, y + 77, this::clickSlot); - auctionTypeWidget.setSlotId(52); + auctionTypeWidget.setSlotId(AUCTION_TYPE_BUTTON_SLOT); addDrawableChild(auctionTypeWidget); rarityWidget = new RarityWidget(x + 73, y + 80, this::clickSlot); - rarityWidget.setSlotId(51); + rarityWidget.setSlotId(RARITY_BUTTON_SLOT); addDrawableChild(rarityWidget); resetFiltersButton = new ScaledTextButtonWidget(x + 10, y + 77, 12, 12, Text.literal("↻"), this::onResetPressed); addDrawableChild(resetFiltersButton); @@ -84,17 +100,9 @@ public class AuctionBrowserScreen extends HandledScreen<AuctionHouseScreenHandle } } - 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); + this.clickSlot(RESET_BUTTON_SLOT, 0); } @Override @@ -105,46 +113,168 @@ public class AuctionBrowserScreen extends HandledScreen<AuctionHouseScreenHandle @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { super.render(context, mouseX, mouseY, delta); + for (CategoryTabWidget categoryTabWidget : categoryTabWidgets) { + categoryTabWidget.render(context, mouseX, mouseY, delta); + } + if (isWaitingForServer) context.drawText(textRenderer, "Waiting...", 0, 0, Colors.WHITE, true); + + MatrixStack matrices = context.getMatrices(); + matrices.push(); + matrices.translate(x,y,0); + // Search + context.enableScissor(x+7, y+4, x+97, y+16); + context.drawText(textRenderer, Text.literal(search).fillStyle(Style.EMPTY.withUnderline(onSearchField(mouseX, mouseY))), 9, 6, Colors.WHITE, true); + context.disableScissor(); + + // Scrollbar + if (prevPageVisible) { + if (onScrollbarTop(mouseX, mouseY)) + context.drawSprite(159, 13, 0, 6, 3, UP_ARROW.get()); + else context.drawSprite(159, 13, 0, 6, 3, UP_ARROW.get(), 0.54f, 0.54f, 0.54f, 1); + } + + if (nextPageVisible) { + if (onScrollbarBottom(mouseX, mouseY)) + context.drawSprite(159, 72, 0, 6, 3, DOWN_ARROW.get()); + else context.drawSprite(159, 72, 0, 6, 3, DOWN_ARROW.get(), 0.54f, 0.54f, 0.54f, 1); + } + context.drawText(textRenderer, String.format("%d/%d", currentPage, totalPages), 99, 6, Colors.GRAY, false); + if (totalPages <= 1) + context.drawGuiTexture(SCROLLER_TEXTURE, 156, 18, 12, 15); + else + context.drawGuiTexture(SCROLLER_TEXTURE, 156, (int) (18 + (float)(Math.min(currentPage, totalPages)-1)/(totalPages-1)*37), 12, 15); + + matrices.pop(); + this.drawMouseoverTooltip(context, mouseX, mouseY); } - private static int getOrdinal(List<Text> 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<Text> 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<Text> 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<Text> 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<Text> 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<Text> 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<AuctionHouseScreenHandler> { + 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 + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + super.render(context, mouseX, mouseY, delta); + + MatrixStack matrices = context.getMatrices(); + + matrices.push(); + matrices.translate(x+77, y+14, 0); + matrices.scale(1.375f, 1.375f, 1.375f); + //matrices.translate(0, 0, 100f); + ItemStack stack = handler.getSlot(13).getStack(); + context.drawItem(stack, 0, 0); + context.drawItemInSlot(textRenderer, stack, 0, 0); + matrices.pop(); + + if (!isBinAuction) { + if (priceWidget.isMouseOver(mouseX, mouseY) && buyState != BuyState.CANT_AFFORD) { + priceWidget.setMessage(clickToEditBidText); + } else { + priceWidget.setMessage(priceText); + } + } + + drawMouseoverTooltip(context, mouseX, mouseY); + } + + @Override + protected void drawMouseoverTooltip(DrawContext context, int x, int y) { + super.drawMouseoverTooltip(context, x, y); + if (x>this.x+75 && x<this.x+75+26 && y>this.y+13 && y<this.y+13+26) { + context.drawTooltip(this.textRenderer, this.getTooltipFromItem(handler.getSlot(13).getStack()), x, y); + } + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (!isBinAuction && priceWidget.isMouseOver(mouseX, mouseY)) { + clickSlot(31); + return true; + } + return super.mouseClicked(mouseX, mouseY, button); + } + + @Override + public void onSlotChange(AuctionHouseScreenHandler handler, int slotId, ItemStack stack) { + if (stack.isOf(Items.BLACK_STAINED_GLASS_PANE) || slotId == 13) return; + assert client != null; + if (priceParsed) return; + if (stack.isOf(Items.POISONOUS_POTATO)) { + changeState(BuyState.CANT_AFFORD); + getPriceFromTooltip(stack.getTooltip(client.player, TooltipContext.BASIC)); + buySlotID = slotId; + } else if (stack.isOf(Items.GOLD_NUGGET)) { + changeState(BuyState.AFFORD); + getPriceFromTooltip(stack.getTooltip(client.player, TooltipContext.BASIC)); + buySlotID = slotId; + } else if (stack.isOf(Items.GOLD_BLOCK)) { + changeState(BuyState.TOP_BID); + getPriceFromTooltip(stack.getTooltip(client.player, TooltipContext.BASIC)); + buySlotID = slotId; + } + } + + private int buySlotID = -1; + private boolean priceParsed = false; + private void getPriceFromTooltip(List<Text> tooltip) { + if (priceParsed) return; + String minBid = null; + String priceString = "???"; + for (Text text : tooltip) { + String string = text.getString(); + String thingToLookFor = (isBinAuction) ? "price:" : "new bid:"; + if (string.toLowerCase().contains(thingToLookFor)) { + String[] split = string.split(":"); + if (split.length < 2) continue; + priceString = split[1].trim(); + break; + } else if (string.toLowerCase().contains("minimum bid:") && !isBinAuction) { + String[] split = string.split(":"); + if (split.length < 2) continue; + minBid = split[1].replace("coins", "").replace(",", "").trim(); + } + } + if (minBid != null) this.minBid = minBid; + else this.minBid = priceString; + priceText = Text.literal(priceString).setStyle(Style.EMPTY.withFormatting(Formatting.BOLD).withColor(Formatting.GOLD)); + priceWidget.setMessage(priceText); + int width = textRenderer.getWidth(priceText); + if (width > priceWidget.getWidth()) priceWidget.setWidth(width); + priceParsed = true; + updateLayout(); + } + + public PopupScreen getConfirmPurchasePopup(Text title) { + // This really shouldn't be possible to be null in its ACTUAL use case. + //noinspection DataFlowIssue + return new PopupScreen.Builder(this, title) + .button(Text.literal("Confirm"), popupScreen -> this.client.interactionManager.clickSlot(this.client.player.currentScreenHandler.syncId, 11, 0, SlotActionType.PICKUP, client.player)) + .button(Text.literal("Cancel"), popupScreen -> this.client.interactionManager.clickSlot(this.client.player.currentScreenHandler.syncId, 15, 0, SlotActionType.PICKUP, client.player)) + .message(Text.literal(isBinAuction ? "Price: " : "New Bid: ").append(priceText)).build(); + } + + private enum BuyState { + CANT_AFFORD, + AFFORD, + TOP_BID + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java new file mode 100644 index 00000000..ccdb7353 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java @@ -0,0 +1,99 @@ +package de.hysky.skyblocker.skyblock.auction; + +import de.hysky.skyblocker.utils.render.gui.BarebonesPopupScreen; +import net.minecraft.block.entity.SignBlockEntity; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.*; +import net.minecraft.network.packet.c2s.play.UpdateSignC2SPacket; +import net.minecraft.text.Style; +import net.minecraft.text.Text; +import org.jetbrains.annotations.NotNull; + +public class EditBidPopup extends BarebonesPopupScreen { + private DirectionalLayoutWidget layout = DirectionalLayoutWidget.vertical(); + private final String minimumBid; + private final SignBlockEntity signBlockEntity; + + private final boolean signFront; + + private TextFieldWidget textFieldWidget; + + private boolean packetSent = false; + + public EditBidPopup(AuctionViewScreen auctionViewScreen, @NotNull SignBlockEntity signBlockEntity, boolean signFront, String minimumBid) { + super(Text.literal("Edit Bid"), auctionViewScreen); + this.minimumBid = minimumBid; + this.signBlockEntity = signBlockEntity; + this.signFront = signFront; + } + + @Override + protected void init() { + super.init(); + layout = DirectionalLayoutWidget.vertical(); + layout.spacing(8).getMainPositioner().alignHorizontalCenter(); + textFieldWidget = new TextFieldWidget(textRenderer, 120, 15, Text.empty()); + textFieldWidget.setTextPredicate(this::isStringGood); + layout.add(new TextWidget(Text.literal("- Set Bid -").fillStyle(Style.EMPTY.withBold(true)), textRenderer)); + layout.add(textFieldWidget); + layout.add(new TextWidget(Text.literal("Minimum Bid: " + minimumBid), textRenderer)); + DirectionalLayoutWidget horizontal = DirectionalLayoutWidget.horizontal(); + ButtonWidget buttonWidget = ButtonWidget.builder(Text.literal("Set Minimum Bid"), this::buttonMinimumBid).width(80).build(); + buttonWidget.active = isStringGood(minimumBid); + horizontal.add(buttonWidget); + horizontal.add(ButtonWidget.builder(Text.literal("Done"), this::done).width(80).build()); + layout.add(horizontal); + layout.forEachChild(this::addDrawableChild); + this.layout.refreshPositions(); + SimplePositioningWidget.setPos(layout, this.getNavigationFocus()); + setInitialFocus(textFieldWidget); + } + + @Override + public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) { + super.renderBackground(context, mouseX, mouseY, delta); + drawPopupBackground(context, layout.getX(), layout.getY(), layout.getWidth(), layout.getHeight()); + } + + private boolean isStringGood(String s) { + assert this.client != null; + return this.client.textRenderer.getWidth(minimumBid) <= this.signBlockEntity.getMaxTextWidth(); + } + + private void buttonMinimumBid(ButtonWidget widget) { + if (!isStringGood(minimumBid)) return; + sendPacket(minimumBid); + this.close(); + } + + private void done(ButtonWidget widget) { + if(!isStringGood(textFieldWidget.getText().trim())) return; + sendPacket(textFieldWidget.getText().trim()); + this.close(); + } + + private void sendPacket(String string) { + assert MinecraftClient.getInstance().player != null; + MinecraftClient.getInstance().player.networkHandler.sendPacket(new UpdateSignC2SPacket(signBlockEntity.getPos(), signFront, + string, + "", + "", + "" + )); + packetSent = true; + } + + @Override + public void close() { + if (!packetSent) sendPacket(""); + this.client.setScreen(null); + } + + @Override + public void removed() { + if (!packetSent) sendPacket(""); + super.removed(); + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/AbstractCustomHypixelGUI.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/AbstractCustomHypixelGUI.java new file mode 100644 index 00000000..4f648b8c --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/render/gui/AbstractCustomHypixelGUI.java @@ -0,0 +1,56 @@ +package de.hysky.skyblocker.utils.render.gui; + +import de.hysky.skyblocker.mixin.accessor.HandledScreenAccessor; +import de.hysky.skyblocker.skyblock.auction.AuctionHouseScreenHandler; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.screen.ScreenHandlerListener; +import net.minecraft.screen.slot.SlotActionType; +import net.minecraft.text.Text; + +public abstract class AbstractCustomHypixelGUI<T extends ScreenHandler> extends HandledScreen<T> implements ScreenHandlerListener { + + public boolean isWaitingForServer = true; + public AbstractCustomHypixelGUI(T handler, PlayerInventory inventory, Text title) { + super(handler, inventory, title); + handler.addListener(this); + } + + 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); + handler.getCursorStack().setCount(0); + isWaitingForServer = true; + } + + protected void clickSlot(int slotID) { + clickSlot(slotID, 0); + } + + public void changeHandler(AuctionHouseScreenHandler newHandler) { + handler.removeListener(this); + ((HandledScreenAccessor) this).setHandler(newHandler); + handler.addListener(this); + } + + @Override + public void removed() { + super.removed(); + handler.removeListener(this); + } + + @Override + public final void onSlotUpdate(ScreenHandler handler, int slotId, ItemStack stack) { + onSlotChange(this.handler, slotId, stack); + isWaitingForServer = false; + } + + protected abstract void onSlotChange(T handler, int slotID, ItemStack stack); + + @Override + public void onPropertyUpdate(ScreenHandler handler, int property, int value) {} +} diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/BarebonesPopupScreen.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/BarebonesPopupScreen.java new file mode 100644 index 00000000..56b07966 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/render/gui/BarebonesPopupScreen.java @@ -0,0 +1,56 @@ +package de.hysky.skyblocker.utils.render.gui; + +import com.mojang.blaze3d.platform.GlConst; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +/** + * A more bare-bones version of Vanilla's Popup Screen. Meant to be extended. + */ +public class BarebonesPopupScreen extends Screen { + private static final Identifier BACKGROUND_TEXTURE = new Identifier("popup/background"); + private final Screen backgroundScreen; + + protected BarebonesPopupScreen(Text title, Screen backgroundScreen) { + super(title); + this.backgroundScreen = backgroundScreen; + } + + @Override + public void close() { + assert this.client != null; + this.client.setScreen(this.backgroundScreen); + } + + @Override + public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) { + this.backgroundScreen.render(context, -1, -1, delta); + context.draw(); + RenderSystem.clear(GlConst.GL_DEPTH_BUFFER_BIT, MinecraftClient.IS_SYSTEM_MAC); + this.renderInGameBackground(context); + } + + /** + * These are the inner positions and size of the popup, not outer + */ + public static void drawPopupBackground(DrawContext context, int x, int y, int width, int height) { + context.drawGuiTexture(BACKGROUND_TEXTURE, x - 18, y - 18, width + 36, height + 36); + } + + @Override + protected void init() { + super.init(); + this.backgroundScreen.resize(this.client, width, height); + + } + + @Override + public void onDisplayed() { + super.onDisplayed(); + this.backgroundScreen.blur(); + } +}
\ No newline at end of file |