diff options
author | My-Name-Is-Jeff <37018278+My-Name-Is-Jeff@users.noreply.github.com> | 2021-04-09 18:50:32 -0400 |
---|---|---|
committer | My-Name-Is-Jeff <37018278+My-Name-Is-Jeff@users.noreply.github.com> | 2021-04-09 18:50:32 -0400 |
commit | 40bdb3ed489614eb134cc333b215b6b3d7dd7647 (patch) | |
tree | 69b4dc0c3ce1e66cfaa86396ccafaa1b1dff7074 /src/main | |
parent | b3e697792009399750faf67f515afc00b4ca67a3 (diff) | |
download | SkytilsMod-40bdb3ed489614eb134cc333b215b6b3d7dd7647.tar.gz SkytilsMod-40bdb3ed489614eb134cc333b215b6b3d7dd7647.tar.bz2 SkytilsMod-40bdb3ed489614eb134cc333b215b6b3d7dd7647.zip |
Better Auction Price Input
Diffstat (limited to 'src/main')
5 files changed, 345 insertions, 0 deletions
diff --git a/src/main/java/skytils/skytilsmod/Skytils.java b/src/main/java/skytils/skytilsmod/Skytils.java index 1f37f662..e0442ef1 100644 --- a/src/main/java/skytils/skytilsmod/Skytils.java +++ b/src/main/java/skytils/skytilsmod/Skytils.java @@ -54,6 +54,7 @@ import skytils.skytilsmod.features.impl.handlers.*; import skytils.skytilsmod.features.impl.mining.DarkModeMist; import skytils.skytilsmod.features.impl.mining.MiningFeatures; import skytils.skytilsmod.features.impl.misc.*; +import skytils.skytilsmod.features.impl.overlays.AuctionPriceOverlay; import skytils.skytilsmod.features.impl.spidersden.RelicWaypoints; import skytils.skytilsmod.features.impl.spidersden.SpidersDenFeatures; import skytils.skytilsmod.gui.LocationEditGui; @@ -121,6 +122,7 @@ public class Skytils { MinecraftForge.EVENT_BUS.register(new ArmorColor()); MinecraftForge.EVENT_BUS.register(new AuctionData()); + MinecraftForge.EVENT_BUS.register(new AuctionPriceOverlay()); MinecraftForge.EVENT_BUS.register(new BlazeSolver()); MinecraftForge.EVENT_BUS.register(new BlockAbility()); MinecraftForge.EVENT_BUS.register(new BossHPDisplays()); diff --git a/src/main/java/skytils/skytilsmod/core/Config.java b/src/main/java/skytils/skytilsmod/core/Config.java index e24d3a5d..9b723118 100644 --- a/src/main/java/skytils/skytilsmod/core/Config.java +++ b/src/main/java/skytils/skytilsmod/core/Config.java @@ -879,6 +879,15 @@ public class Config extends Vigilant { @Property( type = PropertyType.SWITCH, + name = "Custom Auction Price Input", + description = "Displays Skytils' own auction input GUI instead of a sign.", + category = "Miscellaneous", + subcategory = "Quality of Life" + ) + public boolean betterAuctionPriceInput = false; + + @Property( + type = PropertyType.SWITCH, name = "Boss Bar Fix", description = "Hides the Witherborn boss bars.", category = "Miscellaneous", diff --git a/src/main/java/skytils/skytilsmod/features/impl/overlays/AuctionPriceOverlay.java b/src/main/java/skytils/skytilsmod/features/impl/overlays/AuctionPriceOverlay.java new file mode 100644 index 00000000..c417a84d --- /dev/null +++ b/src/main/java/skytils/skytilsmod/features/impl/overlays/AuctionPriceOverlay.java @@ -0,0 +1,292 @@ +/* + * Skytils - Hypixel Skyblock Quality of Life Mod + * Copyright (C) 2021 Skytils + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package skytils.skytilsmod.features.impl.overlays; + +import com.google.common.collect.Lists; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.GuiTextField; +import net.minecraft.client.gui.inventory.GuiChest; +import net.minecraft.client.gui.inventory.GuiEditSign; +import net.minecraft.client.network.NetHandlerPlayClient; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.item.ItemStack; +import net.minecraft.network.play.client.C12PacketUpdateSign; +import net.minecraft.tileentity.TileEntitySign; +import net.minecraft.util.ChatComponentText; +import net.minecraftforge.client.event.GuiOpenEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import org.lwjgl.input.Keyboard; +import skytils.skytilsmod.Skytils; +import skytils.skytilsmod.events.GuiContainerEvent; +import skytils.skytilsmod.features.impl.handlers.AuctionData; +import skytils.skytilsmod.gui.commandaliases.elements.CleanButton; +import skytils.skytilsmod.mixins.AccessorGuiEditSign; +import skytils.skytilsmod.utils.ItemUtil; +import skytils.skytilsmod.utils.NumberUtil; +import skytils.skytilsmod.utils.SBInfo; +import skytils.skytilsmod.utils.Utils; +import skytils.skytilsmod.utils.graphics.ScreenRenderer; +import skytils.skytilsmod.utils.graphics.SmartFontRenderer; +import skytils.skytilsmod.utils.graphics.colors.CommonColors; + +import java.awt.*; +import java.io.IOException; +import java.util.ArrayList; + +public class AuctionPriceOverlay { + + private static ItemStack lastAuctionedStack; + private static boolean undercut = false; + + @SubscribeEvent + public void onGuiOpen(GuiOpenEvent event) { + if (!Utils.inSkyblock || !Skytils.config.betterAuctionPriceInput) return; + + if (event.gui instanceof GuiEditSign && Utils.equalsOneOf(SBInfo.getInstance().lastOpenContainerName, "Create Auction", "Create BIN Auction")) { + TileEntitySign sign = ((AccessorGuiEditSign) event.gui).getTileSign(); + if (sign != null && sign.getPos().getY() == 0 && sign.signText[1].getUnformattedText().equals("^^^^^^^^^^^^^^^") && sign.signText[2].getUnformattedText().equals("Your auction") && sign.signText[3].getUnformattedText().equals("starting bid")) { + event.gui = new AuctionPriceScreen((GuiEditSign) event.gui); + } + } + } + + @SubscribeEvent + public void onSlotClick(GuiContainerEvent.SlotClickEvent event) { + if (!Utils.inSkyblock || !Skytils.config.betterAuctionPriceInput) return; + + if (event.gui instanceof GuiChest) { + if (Utils.equalsOneOf(SBInfo.getInstance().lastOpenContainerName, "Create Auction", "Create BIN Auction") && event.slotId == 31) { + ItemStack auctionItem = event.container.getSlot(13).getStack(); + if (auctionItem != null) { + if (auctionItem.getDisplayName().equals("§a§l§nAUCTION FOR ITEM:")) { + lastAuctionedStack = auctionItem; + } + } + } + if (Utils.equalsOneOf(SBInfo.getInstance().lastOpenContainerName, "Confirm Auction", "Confirm BIN Auction")) { + if (event.slotId == 11) { + lastAuctionedStack = null; + } + } + } + } + + private static boolean isUndercut() { + if (!undercut || lastAuctionedStack == null) return false; + String id = AuctionData.getIdentifier(lastAuctionedStack); + return id != null && AuctionData.lowestBINs.containsKey(id); + } + + /** + * This code was modified and taken under CC BY-SA 3.0 license + * @link https://stackoverflow.com/a/44630965 + * @author Sachin Rao + */ + private static Double getActualValueFromCompactNumber(String value) { + String lastAlphabet = value.replaceAll("[^a-zA-Z]*$", "") + .replaceAll(".(?!$)", ""); + long multiplier = 1L; + + switch (lastAlphabet.toLowerCase()) { + case "k": + multiplier = 1_000L; + break; + case "m": + multiplier = 1_000_000L; + break; + case "b": + multiplier = 1_000_000_000L; + break; + case "t": + multiplier = 1_000_000_000_000L; + break; + default: + break; + } + + String[] values = value.split(lastAlphabet); + + if (multiplier == 1) { + return null; + } else { + double valueMultiplier = Double.parseDouble(values[0]); + double valueAdder; + try { + valueAdder = Double.parseDouble(values[1]); + } catch (ArrayIndexOutOfBoundsException ex) { + valueAdder = 0.0d; + } + double total = (valueMultiplier * multiplier) + valueAdder; + return total; + } + } + + /** + * This code was modified and taken under CC BY-SA 3.0 license + * @link https://stackoverflow.com/a/44630965 + * @author Sachin Rao + */ + private static boolean isProperCompactNumber(String value) { + value = value.replaceAll("\\s+", ""); + String count = value.replaceAll("[.0-9]+", ""); + return count.length() < 2; + } + + public static class AuctionPriceScreen extends GuiScreen { + + public CleanButton undercutButton; + public GuiTextField priceField; + public TileEntitySign sign; + public SmartFontRenderer fr = ScreenRenderer.fontRenderer; + + public AuctionPriceScreen(GuiEditSign oldScreen) { + this.sign = ((AccessorGuiEditSign) oldScreen).getTileSign(); + } + + @Override + public void initGui() { + this.buttonList.clear(); + Keyboard.enableRepeatEvents(true); + sign.setEditable(false); + priceField = new GuiTextField(0, fontRendererObj, width/2-135, height/2, 270, 20); + priceField.setMaxStringLength(15); + priceField.setValidator((text) -> text.toLowerCase().replaceAll("[^0-9.kmb]", "").length() == text.length()); + priceField.setFocused(true); + buttonList.add(undercutButton = new CleanButton(0, width/2 - 100, height/2 + 25, 200, 20, !isUndercut() ? "Mode: Normal" : "Mode: Undercut")); + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + drawGradientRect(0, 0, this.width, this.height, new Color(117, 115, 115, 25).getRGB(), new Color(0,0, 0,200).getRGB()); + priceField.drawTextBox(); + if (lastAuctionedStack != null) { + String auctionIdentifier = AuctionData.getIdentifier(lastAuctionedStack); + if (auctionIdentifier != null) { + // this might actually have multiple items as the price + Double valuePer = AuctionData.lowestBINs.get(auctionIdentifier); + if (valuePer != null) fr.drawString("Lowest BIN Price: §b" + NumberUtil.nf.format(valuePer * lastAuctionedStack.stackSize) + (lastAuctionedStack.stackSize > 1 ? " §7(" + NumberUtil.nf.format(valuePer) + " each§7)" : ""), this.width/2f, this.height/2f-50, CommonColors.ORANGE, SmartFontRenderer.TextAlignment.MIDDLE, SmartFontRenderer.TextShadow.NONE); + } + if (isUndercut()) { + String input = getInput(); + fr.drawString("Listing For: " + (input == null ? "§cInvalid Value" : input), this.width/2f, this.height/2f-25, CommonColors.ORANGE, SmartFontRenderer.TextAlignment.MIDDLE, SmartFontRenderer.TextShadow.NONE); + } + ArrayList<String> lore = Lists.newArrayList(ItemUtil.getItemLore(lastAuctionedStack)); + if (lore.size() > 3) { + lore.remove(0); + lore.remove(lore.size() - 1); + lore.remove(lore.size() - 1); + } + if (lore.size() > 0) { + int largestLen = 0; + for (String line : lore) { + int len = fr.getStringWidth(line); + if (len > largestLen) largestLen = len; + } + fr.drawString("You're selling: " + lastAuctionedStack.stackSize + "x", this.width/2f-200-largestLen, this.height/2f-100, CommonColors.ORANGE, SmartFontRenderer.TextAlignment.LEFT_RIGHT, SmartFontRenderer.TextShadow.NONE); + drawHoveringText(lore, this.width/2-200-largestLen-10, this.height/2-70, fr); + GlStateManager.disableLighting(); + } + } + + super.drawScreen(mouseX, mouseY, partialTicks); + } + + @Override + public void updateScreen() { + undercutButton.displayString = !isUndercut() ? "Mode: Normal" : "Mode: Undercut"; + priceField.updateCursorCounter(); + super.updateScreen(); + } + + @Override + protected void keyTyped(char typedChar, int keyCode) throws IOException { + if (keyCode == Keyboard.KEY_RETURN || keyCode == Keyboard.KEY_ESCAPE) { + sign.markDirty(); + mc.displayGuiScreen(null); + return; + } + priceField.textboxKeyTyped(typedChar, keyCode); + String input = getInput(); + if (input == null) { + sign.signText[0] = new ChatComponentText("Invalid Value"); + } else { + sign.signText[0] = new ChatComponentText(getInput()); + } + } + + @Override + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { + priceField.mouseClicked(mouseX, mouseY, mouseButton); + super.mouseClicked(mouseX, mouseY, mouseButton); + } + + @Override + protected void mouseReleased(int mouseX, int mouseY, int state) { + super.mouseReleased(mouseX, mouseY, state); + } + + @Override + protected void actionPerformed(GuiButton button) throws IOException { + if (button.id == 0) { + undercut = !undercut; + } + } + + @Override + public void onGuiClosed() { + Keyboard.enableRepeatEvents(false); + NetHandlerPlayClient nethandlerplayclient = mc.getNetHandler(); + + if (nethandlerplayclient != null) { + nethandlerplayclient.addToSendQueue(new C12PacketUpdateSign(sign.getPos(), sign.signText)); + } + + sign.setEditable(true); + } + + public String getInput() { + String input = priceField.getText(); + if (isUndercut()) { + double lbin = AuctionData.lowestBINs.get(AuctionData.getIdentifier(lastAuctionedStack)); + try { + double num = Double.parseDouble(input); + double actualValue = (lbin - num) * lastAuctionedStack.stackSize; + if (actualValue < 0) return null; + String stringified = Long.toString((long)actualValue); + return stringified.length() > 15 ? NumberUtil.format((long) actualValue) : stringified; + } catch(NumberFormatException ignored) { + } + if (isProperCompactNumber(input)) { + Double num = getActualValueFromCompactNumber(input); + if (num != null) { + double actualValue = (lbin - num) * lastAuctionedStack.stackSize; + if (actualValue < 0) return null; + String stringified = Long.toString((long)actualValue); + return stringified.length() > 15 ? NumberUtil.format((long) actualValue) : stringified; + } + } + return null; + } + return input; + } + } + +} diff --git a/src/main/java/skytils/skytilsmod/mixins/AccessorGuiEditSign.java b/src/main/java/skytils/skytilsmod/mixins/AccessorGuiEditSign.java new file mode 100644 index 00000000..ca7707f0 --- /dev/null +++ b/src/main/java/skytils/skytilsmod/mixins/AccessorGuiEditSign.java @@ -0,0 +1,41 @@ +/* + * Skytils - Hypixel Skyblock Quality of Life Mod + * Copyright (C) 2021 Skytils + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package skytils.skytilsmod.mixins; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.inventory.GuiEditSign; +import net.minecraft.tileentity.TileEntitySign; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(GuiEditSign.class) +public interface AccessorGuiEditSign { + /** Reference to the sign object. */ + @Accessor("tileSign") + TileEntitySign getTileSign(); + /** Counts the number of screen updates. */ + @Accessor("updateCounter") + int getUpdateCounter(); + /** The index of the line that is being edited. */ + @Accessor("editLine") + int getEditLine(); + /** "Done" button for the GUI. */ + @Accessor("doneBtn") + GuiButton getDoneBtn(); +} diff --git a/src/main/resources/mixins.skytils.json b/src/main/resources/mixins.skytils.json index 6d5548ae..d78584d5 100644 --- a/src/main/resources/mixins.skytils.json +++ b/src/main/resources/mixins.skytils.json @@ -4,6 +4,7 @@ "refmap": "mixins.skytils.refmap.json", "mixins": [ "AccessorCommandHandler", + "AccessorGuiEditSign", "AccessorGuiNewChat", "AccessorSettingsGui", "MixinBlockRendererDispatcher", |