diff options
author | nea <romangraef@gmail.com> | 2022-10-21 19:54:57 +0200 |
---|---|---|
committer | nea <romangraef@gmail.com> | 2022-10-21 19:54:57 +0200 |
commit | e7b513b5f4f8e41b2d207a74d9c0eeff6768436a (patch) | |
tree | 714392dd308687796bed2a881a2b21898b1e1776 | |
parent | b3e35831f989f996b0f2ea3cd975a8a2ab57a3fd (diff) | |
parent | 2f57d3891a25630a41323c029bbe0b0a87d2fd33 (diff) | |
download | NotEnoughUpdates-e7b513b5f4f8e41b2d207a74d9c0eeff6768436a.tar.gz NotEnoughUpdates-e7b513b5f4f8e41b2d207a74d9c0eeff6768436a.tar.bz2 NotEnoughUpdates-e7b513b5f4f8e41b2d207a74d9c0eeff6768436a.zip |
Merge remote-tracking branch 'origin/master' into feature/buckets
154 files changed, 10969 insertions, 3361 deletions
diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md deleted file mode 100644 index e91612f1..00000000 --- a/.github/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contributor Code of Conduct - -Don't be a jerk. diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4d6c2b23..d610b4d5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,6 +9,7 @@ on: - "COPYING" - "COPYING.LESSER" - ".gitignore" + - "Update Notes" pull_request: branches: - "*" @@ -17,6 +18,7 @@ on: - "COPYING" - "COPYING.LESSER" - ".gitignore" + - "Update Notes" workflow_dispatch: jobs: build: @@ -28,7 +30,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Send discord notification id: sendmsg if: ${{ env.WEBHOOK_URL }} @@ -37,14 +39,14 @@ jobs: env: STATUS: WORKING - name: Set up JDK 17 - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: 17 distribution: temurin cache: gradle - name: Build with Gradle run: chmod +x ./gradlew && ./gradlew clean test remapJar --no-daemon - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: path: build/libs/*-dep.jar - name: Update discord notification diff --git a/.github/workflows/infer.yml b/.github/workflows/infer.yml index 365e748b..7a035a42 100644 --- a/.github/workflows/infer.yml +++ b/.github/workflows/infer.yml @@ -8,12 +8,12 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 name: Checkout feature with: ref: ${{ github.event.pull_request.head.sha }} - name: Set up JDK 17 - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: 17 distribution: temurin @@ -27,7 +27,7 @@ jobs: infer capture -- ./gradlew clean test --no-daemon infer analyze cp infer-out/report.json ciwork/report-feature.json - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 name: Checkout base with: ref: ${{ github.event.pull_request.base.sha }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e7c4b379..f4840270 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,11 +1,14 @@ # Contributing +## Quick Note +Ever since Moulberry has stopped working on NEU, other contributors have been working on new features and fixes for the mod. If you are interested in contributing yourself, make a pull request to [NotEnoughUpdates/NotEnoughUpdates](https://github.com/NotEnoughUpdates/NotEnoughUpdates) to contribute to the prereleases, which eventually will be merged in bulk to [Moulberry/NotEnoughUpdates](https://github.com/Moulberry/NotEnoughUpdates) for major releases. + ## Before you contribute -- Please check your feature / bug isn't already fixed in one of our pre-releases or on [the development branch](https://github.com/NotEnoughUpdates/NotEnoughUpdates/tree/master/). +- Please check your feature / bug isn't already fixed in one of our pre-releases, on the [development branch](https://github.com/NotEnoughUpdates/NotEnoughUpdates/tree/master/) or in an open [pull request](https://github.com/NotEnoughUpdates/NotEnoughUpdates/pulls) - Consider joining our [Discord](https://discord.gg/moulberry) to check in on newest developments by other people, or to get help with problems you encounter. -- Please check that your feature idea complies with the [Hypixel Rules](https://hypixel.net/rules) -- Check that your feature idea isn't already done in other mods. (E.g. Dungeon Solver) +- Please check that your feature idea complies with the [Hypixel Rules](https://hypixel.net/rules). (See these Hypixel forum posts for extra information: [Mods in SkyBlock](https://hypixel.net/threads/regarding-the-recent-announcement-with-mods-in-skyblock.4045481/), [QoL Modifications](https://hypixel.net/threads/update-to-disallowed-modifications-qol-modifications.4043482/), [Modifications Sending Invalid Clicks](https://hypixel.net/threads/update-regarding-modifications-sending-invalid-clicks.5130489/)) +- Make sure that your feature idea is not already implemented in another non-paid mod. (E.g. Dungeon Solver) ## Setting up a development environment @@ -17,7 +20,11 @@ ### Software configuration -- Clone the NEU repository using `git clone https://github.com/NotEnoughUpdates/NotEnoughUpdates`. +- Fork the NEU repository using the fork button on top right of the page and name the repo NotEnoughUpdates. +- Clone the forked repository using `git clone https://github.com/<YourUserName>/NotEnoughUpdates`. +- Make sure to create new branches for features you are working on and not commit to the master branch of your repository. +- After you have committed all of the necessary changes make a pull request on that branch. +- Use the master branch as a way to pull the latest changes from the NEU repo. - Import that folder as a Gradle Project in your IDE (IntelliJ should autodetect it as gradle if you select the `NotEnoughUpdates` folder in the Open dialog) - Set your project SDK to your 1.8 JDK. This can be done in the modules settings (CTRL+ALT+SHIFT+S) in IntelliJ. - Set your gradle JVM to your 1.17 JDK. This can be done by searching for `gradle jvm` in the CTRL+SHIFT+A dialog in IntelliJ. diff --git a/Update Notes/2.1.1.md b/Update Notes/2.1.1.md index ac1d72ed..b87bf974 100644 --- a/Update Notes/2.1.1.md +++ b/Update Notes/2.1.1.md @@ -1,6 +1,22 @@ -# These are the change notes for NEU 2.1.1 +# These are the change notes for NEU 2.1 + + +### **Major Changes:** + + ### **Minor Changes:** - - Added Glowing Mushroom Highlighter - nea89 + - Fix /join command not working for uppercase floors - walker or whalker + - Remove custom option toggle textures in /neu - nopo + - Fix Pickaxe Cooldown not being correct on first join - Ascynx + - Fix social exp not being correct in /pv - Vixid + - Fix a crash when downgrading from future NEU versions - nopo + - Unify writing conventions for "SkyBlock" and similar - walker or whalker + - Add fishing helper to fishing in the main lobby - sharkey300 + - Allow custom delays until skill overlays pause - cobble8 + - Add exponent and percentage to calculator - u9g + - Add total trophy fish count to /pv - Vixid + - Allow hiding messages below a set skyblock level - nopo +- Added Glowing Mushroom Highlighter - nea89 diff --git a/Update Notes/2.1.md b/Update Notes/2.1.md index 050eaa93..359a56fe 100644 --- a/Update Notes/2.1.md +++ b/Update Notes/2.1.md @@ -7,9 +7,10 @@ - Added combat skill overlay - nopo - Added slayer overlay - nopo - Added blocking clicks back to the enchanting minigames (because apparently, it's not bannable?) -- [Donpireso replied to a sba dev's email about some of sba features, and it seems to imply that blocking clicks in guis aren't bannable](https://cdn.discordapp.com/attachments/823769568933576764/906101631861526559/unknown.png) + - [Donpireso replied to a sba dev's email about some of sba features, and it seems to imply that blocking clicks in guis aren't bannable](https://cdn.discordapp.com/attachments/823769568933576764/906101631861526559/unknown.png) - Made it if you hold shift in the enchant solvers it overrides prevent missclicks - nopo - Fixed pet overlay not updating when going into /pets - nopo +- Fixed pet overlay randomly going to level 100 - nopo - [Added an armor overlay for the new armor slots](https://cdn.discordapp.com/attachments/832652653292027904/922399046528794634/unknown.png) - Added a pet overlay that shows your active pet in your inventory - nopo - [Price graph for items on /ah and /bz](https://cdn.discordapp.com/attachments/896407218151366687/926968296929107999/unknown.png) - DeDiamondPro @@ -17,6 +18,7 @@ - Improved metal detector logic to solve using a single position in most cases using known locations based on Keeper coordinates - CraftyOldMiner - Added support for official Hypixel wiki, can be toggled in /neu misc - DeDiamondPro - Added a calculator (/neucalc help), that also works in the auction house / bazaar - nea89 +- Added an enchant table style gui for /hex - nopo - Added and fixed various things in the profile viewer: - [Added hotm tab](https://media.discordapp.net/attachments/659613194066722833/991115131507441724/unknown.png) - nopo - Big thanks to kwev1n for some math and jani for the texture @@ -40,6 +42,7 @@ - Added carpentry skill to skill average - hannibal2 - Fixed sort order of fishing rods in profile viewer page - hannibal2 - Changing sort logic from strength plus damage to bin price for best weapons in pv inventory page - hannibal2 + - Added pronouns to /pv - nea89 ### **Minor Changes:** @@ -110,13 +113,14 @@ - Added power stone feature - hannibal2 - Added abiphone warning - hannibal2 - Added blur limit at 100 - nopo -- Added bazaar sacks profit feature - hannibal2 - Added an option to disable etherwarp overlay when TP is denied - hannibal2 - Added bazaar search overlay - hannibal2 - Added fraction display instead of percentage in slayer and dungeon RNG meter inventory - hannibal2 - Added profit per score/XP to RNG meter - hannibal2 - Added showing the amount of dungeon runs or slayer bosses needed for the rng meter to fill up - hannibal2 - Added bazaar prices to enchants in the enchantment table - hannibal2 / nea89 +- Added an option to not open the item list when searching containers - Lulonaut +- Made config option in mod settings work - nea89 ### **Bug Fixes:** @@ -144,9 +148,22 @@ - Fixed crash with spamming remove enchant in /neuec - nopo - Fixed missing enchants not working with shiny items - nopo - Fixed golden dragon not working in pet overlay - CrypticPlasma +- Fixed enchant overlay - nopo - Fixed shortened damage - nopo - Fixed bazaar prices sorting order in neu item list - hannibal2 - Fixed priceless items showing first in the missing tab of the accessory bag overlay - nopo +- Fixed clicking outside of experimentation game causing it to go count that as a valid click - nopo +- Fixed storage gui when having locked backpack slots - nopo +- Fixed hyphens in /peek being the wrong color - whalker +- Fixed skill average calculation to include carpentry in /peek - whalker +- Fixed middle clicking on pets not registering pet swap - nopo +- Fixed middle clicking on an item with no id searching for it - nopo +- Fixed pets with decimal stats not showing in pv - nopo +- Changed click packets to act like vanilla - nea89/nopo +- Fixed custom trade menu - nopo +- Removed "Last Seen" from /pv as hypixel removed it from the api - jani +- Fixed profile selector in /pv if you have gui scale 5 - nopo +- Fixed Minecraft not going to be able to access the Hypixel api after 18/10/22 - nea89 ### **Other:** diff --git a/build.gradle.kts b/build.gradle.kts index deb740f5..defc1052 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -39,7 +39,7 @@ apply<NEUBuildFlags>() group = "io.github.moulberry" -setVersionFromEnvironment("2.1") +setVersionFromEnvironment("2.1.1") // Minecraft configuration: loom { diff --git a/buildSrc/generate-public-key.sh b/buildSrc/generate-public-key.sh new file mode 100755 index 00000000..3f778c53 --- /dev/null +++ b/buildSrc/generate-public-key.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright (C) 2022 NotEnoughUpdates contributors +# +# This file is part of NotEnoughUpdates. +# +# NotEnoughUpdates is free software: you can redistribute it +# and/or modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation, either +# version 3 of the License, or (at your option) any later version. +# +# NotEnoughUpdates 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. +# + + +output="$(dirname $(dirname $(readlink -f "$0")))/src/main/resources/moulberry.key" + +echo processing rsa input key from $1, and outputting to $output + +tempfile="$(mktemp)" +ssh-keygen -f "$1" -e -m pkcs8 > "$tempfile" +openssl rsa -pubin -in "$tempfile" -outform der > $output + +echo saved x509 public key at $output + diff --git a/buildSrc/moulsign.sh b/buildSrc/moulsign.sh new file mode 100755 index 00000000..dacb8ec3 --- /dev/null +++ b/buildSrc/moulsign.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright (C) 2022 NotEnoughUpdates contributors +# +# This file is part of NotEnoughUpdates. +# +# NotEnoughUpdates is free software: you can redistribute it +# and/or modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation, either +# version 3 of the License, or (at your option) any later version. +# +# NotEnoughUpdates 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. +# + +echo use key $1, signing file $2 +openssl dgst -sign "$1" "$2" > "$2.asc" +echo signature saved to "$2.asc" + + + diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java index 35385f38..34d87c5b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java @@ -29,13 +29,14 @@ import io.github.moulberry.notenoughupdates.auction.APIManager; import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent; import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe; import io.github.moulberry.notenoughupdates.miscgui.KatSitterOverlay; +import io.github.moulberry.notenoughupdates.options.customtypes.NEUDebugFlag; import io.github.moulberry.notenoughupdates.recipes.CraftingOverlay; import io.github.moulberry.notenoughupdates.recipes.CraftingRecipe; import io.github.moulberry.notenoughupdates.recipes.Ingredient; import io.github.moulberry.notenoughupdates.recipes.NeuRecipe; +import io.github.moulberry.notenoughupdates.util.ApiUtil; import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.HotmInformation; -import io.github.moulberry.notenoughupdates.util.HypixelApi; import io.github.moulberry.notenoughupdates.util.ItemResolutionQuery; import io.github.moulberry.notenoughupdates.util.ItemUtils; import io.github.moulberry.notenoughupdates.util.SBInfo; @@ -123,9 +124,7 @@ public class NEUManager { public String viewItemAttemptID = null; public long viewItemAttemptTime = 0; - private final String currentProfile = ""; - private final String currentProfileBackup = ""; - public final HypixelApi hypixelApi = new HypixelApi(); + public final ApiUtil apiUtils = new ApiUtil(); private final Map<String, ItemStack> itemstackCache = new HashMap<>(); @@ -394,29 +393,121 @@ public class NEUManager { return getUsagesFor(internalname).stream().filter(NeuRecipe::isAvailable).collect(Collectors.toList()); } + private static class DebugMatch { + int index; + String match; + + DebugMatch(int index, String match) { + this.index = index; + this.match = match; + } + } + + + private String searchDebug(String[] searchArray, ArrayList<DebugMatch> debugMatches) { + //splitToSearch, debugMatches and query + final String ANSI_RED = "\u001B[31m"; + final String ANSI_RESET = "\u001B[0m"; + final String ANSI_YELLOW = "\u001B[33m"; + + //create debug message + StringBuilder debugBuilder = new StringBuilder(); + for (int i = 0; i < searchArray.length; i++) { + final int fi = i; + Object[] matches = debugMatches.stream().filter((d) -> d.index == fi).toArray(); + + if (matches.length > 0) { + debugBuilder.append(ANSI_YELLOW + "[").append(((DebugMatch) matches[0]).match).append("]"); + debugBuilder.append(ANSI_RED + "[").append(searchArray[i]).append("]").append(ANSI_RESET).append(" "); + } else { + debugBuilder.append(searchArray[i]).append(" "); + } + } + + //yellow = query match and red = string match + return debugBuilder.toString(); + } + + /** + * SearchString but with AND | OR support + */ + + public boolean multiSearchString(String match, String query) { + boolean totalMatches = false; + + StringBuilder query2 = new StringBuilder(); + char lastOp = '|'; + for (char c : query.toCharArray()) { + if (c == '|' || c == '&') { + boolean matches = searchString(match, query2.toString()); + totalMatches = lastOp == '|' ? totalMatches || matches : totalMatches && matches; + + query2 = new StringBuilder(); + lastOp = c; + } else { + query2.append(c); + } + } + + boolean matches = searchString(match, query2.toString()); + totalMatches = lastOp == '|' ? totalMatches || matches : totalMatches && matches; + + return totalMatches; + } + /** * Searches a string for a query. This method is used to mimic the behaviour of the more complex map-based search * function. This method is used for the chest-item-search feature. */ public boolean searchString(String toSearch, String query) { - int lastMatch = -1; + final String ANSI_RESET = "\u001B[0m"; + final String ANSI_YELLOW = "\u001B[33m"; + + int lastStringMatch = -1; + ArrayList<DebugMatch> debugMatches = new ArrayList<>(); toSearch = clean(toSearch).toLowerCase(); query = clean(query).toLowerCase(); - String[] splitToSeach = toSearch.split(" "); - out: - for (String s : query.split(" ")) { - for (int i = 0; i < splitToSeach.length; i++) { - if (!(lastMatch == -1 || lastMatch == i - 1)) continue; - if (splitToSeach[i].startsWith(s)) { - lastMatch = i; - continue out; + String[] splitToSearch = toSearch.split(" "); + String[] queryArray = query.split(" "); + + { + String currentSearch = queryArray[0]; + int queryIndex = 0; + boolean matchedLastQueryItem = false; + + for (int k = 0; k < splitToSearch.length; k++) { + if (queryIndex - 1 != -1 && (queryArray.length - queryIndex) > (splitToSearch.length - k)) continue; + if (splitToSearch[k].startsWith(currentSearch)) { + if (((lastStringMatch != -1 ? lastStringMatch : k-1) == k-1)) { + debugMatches.add(new DebugMatch(k, currentSearch)); + lastStringMatch = k; + if (queryIndex+1 != queryArray.length) { + queryIndex++; + currentSearch = queryArray[queryIndex]; + } else { + matchedLastQueryItem = true; + } + } + } else if (queryIndex != 0) { + queryIndex = 0; + currentSearch = queryArray[queryIndex]; + lastStringMatch = -1; } } - return false; - } - return true; + if (matchedLastQueryItem) { + if (NEUDebugFlag.SEARCH.isSet()) { + NotEnoughUpdates.LOGGER.info("Found match for \"" + ANSI_YELLOW + query + ANSI_RESET + "\":\n\t" + searchDebug(splitToSearch, debugMatches)); + } + } else { + if (NEUDebugFlag.SEARCH.isSet() && lastStringMatch != -1) { + NotEnoughUpdates.LOGGER.info("Found partial match for \"" + ANSI_YELLOW + query + ANSI_RESET + "\":\n\t" + searchDebug(splitToSearch, debugMatches)); + } + } + + return matchedLastQueryItem; + } } /** @@ -426,7 +517,7 @@ public class NEUManager { public boolean doesStackMatchSearch(ItemStack stack, String query) { if (query.startsWith("title:")) { query = query.substring(6); - return searchString(stack.getDisplayName(), query); + return multiSearchString(stack.getDisplayName(), query); } else if (query.startsWith("desc:")) { query = query.substring(5); String lore = ""; @@ -440,7 +531,7 @@ public class NEUManager { } } } - return searchString(lore, query); + return multiSearchString(lore, query); } else if (query.startsWith("id:")) { query = query.substring(3); String internalName = getInternalNameForItem(stack); @@ -452,9 +543,11 @@ public class NEUManager { for (char c : query.toCharArray()) { sb.append(c).append(" "); } - result = result || searchString(stack.getDisplayName(), sb.toString()); + result = result || multiSearchString(stack.getDisplayName(), sb.toString()); } - result = result || searchString(stack.getDisplayName(), query); + + + result = result || multiSearchString(stack.getDisplayName(), query); String lore = ""; NBTTagCompound tag = stack.getTagCompound(); @@ -468,7 +561,7 @@ public class NEUManager { } } - result = result || searchString(lore, query); + result = result || multiSearchString(lore, query); return result; } @@ -1201,7 +1294,7 @@ public class NEUManager { } } - public HashMap<String, String> getLoreReplacements(String petname, String tier, int level) { + public HashMap<String, String> getPetLoreReplacements(String petname, String tier, int level) { JsonObject petnums = null; if (petname != null && tier != null) { petnums = Constants.PETNUMS; @@ -1314,7 +1407,7 @@ public class NEUManager { float statMax = entry.getValue().getAsFloat(); float statMin = min.get("statNums").getAsJsonObject().get(entry.getKey()).getAsFloat(); float val = statMin * minMix + statMax * maxMix; - String statStr = (statMin > 0 ? "+" : "") + (int) Math.floor(val); + String statStr = (statMin > 0 ? "+" : "") + removeUnusedDecimal(Math.floor(val * 10) / 10); replacements.put(entry.getKey(), statStr); } } @@ -1326,7 +1419,7 @@ public class NEUManager { return replacements; } - public HashMap<String, String> getLoreReplacements(NBTTagCompound tag, int level) { + public HashMap<String, String> getPetLoreReplacements(NBTTagCompound tag, int level) { String petname = null; String tier = null; if (tag != null && tag.hasKey("ExtraAttributes")) { @@ -1360,7 +1453,7 @@ public class NEUManager { } } } - return getLoreReplacements(petname, tier, level); + return getPetLoreReplacements(petname, tier, level); } public NBTTagList processLore(JsonArray lore, HashMap<String, String> replacements) { @@ -1391,6 +1484,7 @@ public class NEUManager { } public ItemStack jsonToStack(JsonObject json, boolean useCache, boolean useReplacements, boolean copyStack) { + if (useReplacements) useCache = false; if (json == null) return new ItemStack(Items.painting, 1, 10); String internalname = json.get("internalname").getAsString(); @@ -1430,7 +1524,7 @@ public class NEUManager { HashMap<String, String> replacements = new HashMap<>(); if (useReplacements) { - replacements = getLoreReplacements(stack.getTagCompound(), -1); + replacements = getPetLoreReplacements(stack.getTagCompound(), -1); String displayName = json.get("displayname").getAsString(); for (Map.Entry<String, String> entry : replacements.entrySet()) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java index 18be69e6..2f55c338 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java @@ -23,7 +23,6 @@ import com.google.common.collect.Lists; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; import io.github.moulberry.notenoughupdates.auction.CustomAHGui; import io.github.moulberry.notenoughupdates.core.BackgroundBlur; import io.github.moulberry.notenoughupdates.core.GuiScreenElementWrapper; @@ -37,7 +36,6 @@ import io.github.moulberry.notenoughupdates.mbgui.MBGuiElement; import io.github.moulberry.notenoughupdates.mbgui.MBGuiGroupAligned; import io.github.moulberry.notenoughupdates.mbgui.MBGuiGroupFloating; import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers; -import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay; import io.github.moulberry.notenoughupdates.miscfeatures.SunTzu; import io.github.moulberry.notenoughupdates.miscgui.GuiPriceGraph; import io.github.moulberry.notenoughupdates.miscgui.NeuSearchCalculator; @@ -46,17 +44,13 @@ import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.GuiTextures; import io.github.moulberry.notenoughupdates.util.LerpingFloat; import io.github.moulberry.notenoughupdates.util.NotificationHandler; -import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.SpecialColour; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; -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.GuiContainer; -import net.minecraft.client.gui.inventory.GuiInventory; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.RenderHelper; @@ -72,8 +66,6 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.Items; -import net.minecraft.inventory.ContainerChest; -import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Slot; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -101,7 +93,6 @@ import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; import java.util.TreeSet; import java.util.UUID; @@ -120,48 +111,6 @@ public class NEUOverlay extends Gui { private static final ResourceLocation SEARCH_BAR = new ResourceLocation("notenoughupdates:search_bar.png"); private static final ResourceLocation SEARCH_BAR_GOLD = new ResourceLocation("notenoughupdates:search_bar_gold.png"); - private static final ResourceLocation ARMOR_DISPLAY = new ResourceLocation( - "notenoughupdates:armordisplay/armordisplay.png"); - private static final ResourceLocation ARMOR_DISPLAY_GREY = new ResourceLocation( - "notenoughupdates:armordisplay/armordisplay_grey.png"); - private static final ResourceLocation ARMOR_DISPLAY_DARK = new ResourceLocation( - "notenoughupdates:armordisplay/armordisplay_phq_dark.png"); - private static final ResourceLocation ARMOR_DISPLAY_FSR = new ResourceLocation( - "notenoughupdates:armordisplay/armordisplay_fsr.png"); - private static final ResourceLocation ARMOR_DISPLAY_TRANSPARENT = new ResourceLocation( - "notenoughupdates:armordisplay/armordisplay_transparent.png"); - private static final ResourceLocation ARMOR_DISPLAY_TRANSPARENT_PET = new ResourceLocation( - "notenoughupdates:armordisplay/armordisplay_transparent_pet.png"); - - private static final ResourceLocation QUESTION_MARK = new ResourceLocation("notenoughupdates:pv_unknown.png"); - - private static final ResourceLocation PET_DISPLAY = new ResourceLocation( - "notenoughupdates:petdisplay/petdisplaysolo.png"); - private static final ResourceLocation PET_DISPLAY_GREY = new ResourceLocation( - "notenoughupdates:petdisplay/petdisplaysolo_dark.png"); - private static final ResourceLocation PET_DISPLAY_DARK = new ResourceLocation( - "notenoughupdates:petdisplay/petdisplaysolo_phqdark.png"); - private static final ResourceLocation PET_DISPLAY_FSR = new ResourceLocation( - "notenoughupdates:petdisplay/petdisplaysolo_fsr.png"); - private static final ResourceLocation PET_DISPLAY_TRANSPARENT = new ResourceLocation( - "notenoughupdates:petdisplay/petdisplaysolo_transparent.png"); - - private static final ResourceLocation PET_ARMOR_DISPLAY = new ResourceLocation( - "notenoughupdates:petdisplay/petdisplayarmor.png"); - private static final ResourceLocation PET_ARMOR_DISPLAY_GREY = new ResourceLocation( - "notenoughupdates:petdisplay/petdisplayarmor_dark.png"); - private static final ResourceLocation PET_ARMOR_DISPLAY_DARK = new ResourceLocation( - "notenoughupdates:petdisplay/petdisplayarmor_phqdark.png"); - private static final ResourceLocation PET_ARMOR_DISPLAY_FSR = new ResourceLocation( - "notenoughupdates:petdisplay/petdisplayarmor_fsr.png"); - private static final ResourceLocation PET_ARMOR_DISPLAY_TRANSPARENT = new ResourceLocation( - "notenoughupdates:petdisplay/petdisplayarmor_transparent.png"); - - private static boolean renderingArmorHud; - private static boolean renderingPetHud; - public static boolean shouldUseCachedPet; - public static long cachedPetTimer; - private final NEUManager manager; private final String mobRegex = ".*?((_MONSTER)|(_NPC)|(_ANIMAL)|(_MINIBOSS)|(_BOSS)|(_SC))$"; @@ -217,6 +166,7 @@ public class NEUOverlay extends Gui { private List<JsonObject> selectedItemGroup = null; private boolean itemPaneOpen = false; + private long itemPaneShouldOpen = -1; private int page = 0; @@ -292,12 +242,14 @@ public class NEUOverlay extends Gui { } if (Mouse.getEventButtonState()) { setSearchBarFocus(true); + if (Mouse.getEventButton() == 1) { //Right mouse button down textField.setText(""); updateSearch(); } else { if (System.currentTimeMillis() - millisLastLeftClick < 300) { searchMode = !searchMode; + itemPaneShouldOpen = -1; lastSearchMode = System.currentTimeMillis(); if (searchMode && NotEnoughUpdates.INSTANCE.config.hidden.firstTimeSearchFocus) { NotificationHandler.displayNotification(Lists.newArrayList( @@ -801,7 +753,9 @@ public class NEUOverlay extends Gui { if (slot != null) { ItemStack hover = slot.getStack(); if (hover != null) { - textField.setText("id:" + manager.getInternalNameForItem(hover)); + if (manager.getInternalNameForItem(hover) != null) { + textField.setText("id:" + manager.getInternalNameForItem(hover)); + } itemPaneOpen = true; updateSearch(); } @@ -1081,7 +1035,7 @@ public class NEUOverlay extends Gui { return false; } - if (Keyboard.isKeyDown(Keyboard.KEY_Y) && NotEnoughUpdates.INSTANCE.config.hidden.dev) { + if ((Keyboard.isKeyDown(Keyboard.KEY_Y) && !Keyboard.isKeyDown(Keyboard.KEY_LCONTROL)) && NotEnoughUpdates.INSTANCE.config.hidden.dev) { displayInformationPane(new DevInfoPane(this, manager)); } @@ -1506,7 +1460,7 @@ public class NEUOverlay extends Gui { if (index < getSlotsXSize() * getSlotsYSize()) { int actualIndex = index + getSlotsXSize() * getSlotsYSize() * page; List<JsonObject> searchedItems = getSearchedItems(); - if (actualIndex < searchedItems.size()) { + if (0 <= actualIndex && actualIndex < searchedItems.size()) { return searchedItems.get(actualIndex); } else { return null; @@ -1836,85 +1790,6 @@ public class NEUOverlay extends Gui { int guiScaleLast = 0; private boolean showVanillaLast = false; - - private boolean wardrobeOpen = false; - - private boolean isInNamedGui(String guiName) { - GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; - if (guiScreen instanceof GuiChest) { - GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; - ContainerChest container = (ContainerChest) chest.inventorySlots; - IInventory lower = container.getLowerChestInventory(); - String containerName = lower.getDisplayName().getUnformattedText(); - wardrobeOpen = containerName.contains(guiName); - } - if (guiScreen instanceof GuiInventory) { - wardrobeOpen = false; - } - return wardrobeOpen; - } - - private ItemStack getChestSlotsAsItemStack(int slot) { - GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; - if (guiScreen instanceof GuiChest) { - GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; - return chest.inventorySlots.getSlot(slot).getStack(); - } else { - return null; - } - } - - public ItemStack slot1 = null; - public ItemStack slot2 = null; - public ItemStack slot3 = null; - public ItemStack slot4 = null; - public ItemStack petSlot = null; - private String lastProfile; - - private ItemStack getWardrobeSlot(int armourSlot) { - if (SBInfo.getInstance().currentProfile == null) { - return null; - } - - if (!Objects.equals(SBInfo.getInstance().currentProfile, lastProfile)) { - lastProfile = SBInfo.getInstance().currentProfile; - slot1 = null; - slot2 = null; - slot3 = null; - slot4 = null; - petSlot = null; - } - - if (isInNamedGui("Your Equipment")) { - ItemStack itemStack = getChestSlotsAsItemStack(armourSlot); - if (itemStack != null) { - JsonObject itemToSave = NotEnoughUpdates.INSTANCE.manager.getJsonForItem(itemStack); - if (!itemToSave.has("internalname")) { - //would crash without internalName when trying to construct the ItemStack again - itemToSave.add("internalname", new JsonPrimitive("_")); - } - NotEnoughUpdates.INSTANCE.config.getProfileSpecific().savedEquipment.put(armourSlot, itemToSave); - return itemStack; - } - } else { - if (NotEnoughUpdates.INSTANCE.config.getProfileSpecific().savedEquipment.containsKey(armourSlot)) { - //don't use cache since the internalName is identical in most cases - return NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.config.getProfileSpecific().savedEquipment - .get(armourSlot) - .getAsJsonObject(), false); - } - } - return null; - } - - public static boolean isRenderingArmorHud() { - return renderingArmorHud; - } - - public static boolean isRenderingPetHud() { - return renderingPetHud; - } - /** * Renders the search bar, quick commands, item selection (right), item info (left) and armor hud gui elements. */ @@ -1922,8 +1797,6 @@ public class NEUOverlay extends Gui { if (disabled) { return; } - renderingArmorHud = false; - renderingPetHud = false; GlStateManager.enableDepth(); FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; @@ -1984,6 +1857,13 @@ public class NEUOverlay extends Gui { (int) (fgFavourite2.getBlue() * 0.8f), fgFavourite2.getAlpha() ); + if (!NotEnoughUpdates.INSTANCE.config.itemlist.openWhenSearching && searchMode) { + itemPaneOpen = false; + } + if (itemPaneShouldOpen != -1 && System.currentTimeMillis() > itemPaneShouldOpen) { + itemPaneOpen = true; + itemPaneShouldOpen = -1; + } if (itemPaneOpen) { if (itemPaneTabOffset.getValue() == 0) { if (itemPaneOffsetFactor.getTarget() != 2 / 3f) { @@ -2321,7 +2201,6 @@ public class NEUOverlay extends Gui { GlStateManager.enableAlpha(); GlStateManager.alphaFunc(516, 0.1F); GlStateManager.disableLighting(); - renderInfoHuds(); Utils.pushGuiScale(-1); if (System.currentTimeMillis() - lastSearchMode > 120000 && @@ -2331,303 +2210,6 @@ public class NEUOverlay extends Gui { } } - void renderInfoHuds() { - FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; - - Utils.resetGuiScale(); - Utils.pushGuiScale(Minecraft.getMinecraft().gameSettings.guiScale); - - int width = Utils.peekGuiScale().getScaledWidth(); - int height = Utils.peekGuiScale().getScaledHeight(); - int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth; - int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1; - GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; - - if (NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud && - NotEnoughUpdates.INSTANCE.config.misc.hidePotionEffect - && NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { - if (getWardrobeSlot(10) != null) { - slot1 = getWardrobeSlot(10); - slot2 = getWardrobeSlot(19); - slot3 = getWardrobeSlot(28); - slot4 = getWardrobeSlot(37); - } - if (guiScreen instanceof GuiInventory) { - renderingArmorHud = true; - - List<String> tooltipToDisplay = null; - if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 0) { - Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY); - } - if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 1) { - Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_GREY); - } - if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 2) { - Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_DARK); - } - if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 3) { - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 3 && - NotEnoughUpdates.INSTANCE.config.petOverlay.petInvDisplay && petSlot != null) { - Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_TRANSPARENT_PET); - } else { - Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_TRANSPARENT); - } - } - if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 4) { - Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_FSR); - } - - GlStateManager.color(1, 1, 1, 1); - GL11.glTranslatef(0, 0, 401); - float yNumber = (float) (height - 167) / 2f; - Utils.drawTexturedRect((float) ((width - 224.1) / 2f), yNumber, 31, 86, GL11.GL_NEAREST); - GlStateManager.bindTexture(0); - - Utils.drawItemStack(slot1, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105), true); - Utils.drawItemStack(slot2, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105) + 18, true); - Utils.drawItemStack(slot3, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105) + 36, true); - Utils.drawItemStack(slot4, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105) + 54, true); - if (slot1 == null) { - Minecraft.getMinecraft().getTextureManager().bindTexture(QUESTION_MARK); - GlStateManager.color(1, 1, 1, 1); - Utils.drawTexturedRect(((width - 208) / 2f), ((height + 60) / 2f - 105), 16, 16, GL11.GL_NEAREST); - GlStateManager.bindTexture(0); - - tooltipToDisplay = Lists.newArrayList( - EnumChatFormatting.RED + "Warning", - EnumChatFormatting.GREEN + "You need to open /equipment", - EnumChatFormatting.GREEN + "To cache your armour" - ); - if (mouseX >= ((width - 208) / 2f) && mouseX < ((width - 208) / 2f) + 16) { - if (mouseY >= ((height + 60) / 2f - 105) && mouseY <= ((height + 60) / 2f - 105) + 70 && - NotEnoughUpdates.INSTANCE.config.customArmour.sendWardrobeCommand) { - if (Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) { - if (Mouse.getEventButtonState()) { - if (ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/equipment") == - 0) { - NotEnoughUpdates.INSTANCE.sendChatMessage("/equipment"); - } - } - } - } - if (mouseY >= ((height + 60) / 2f - 105) && mouseY <= ((height + 60) / 2f - 105) + 16) { - Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); - } - } - GL11.glTranslatef(0, 0, -401); - } - if (slot1 != null && slot2 != null && slot3 != null && slot4 != null) { - if (mouseX >= ((width - 208) / 2f) && mouseX < ((width - 208) / 2f) + 16) { - if (mouseY >= ((height + 60) / 2f - 105) && mouseY <= ((height + 60) / 2f - 105) + 70 && - NotEnoughUpdates.INSTANCE.config.customArmour.sendWardrobeCommand) { - if (Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) { - if (Mouse.getEventButtonState()) { - if (ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/equipment") == - 0) { - NotEnoughUpdates.INSTANCE.sendChatMessage("/equipment"); - } - } - } - } - - if (mouseY >= ((height + 60) / 2f - 105) && mouseY <= ((height + 60) / 2f - 105) + 16) { - tooltipToDisplay = slot1.getTooltip(Minecraft.getMinecraft().thePlayer, false); - if (shouldShowEquipmentTooltip(tooltipToDisplay)) { - Utils.drawHoveringText( - tooltipToDisplay, - mouseX - calculateTooltipXOffset(tooltipToDisplay, fr), - mouseY, - width, - height, - -1, - fr - ); - } - } - if (mouseY >= ((height + 60) / 2f - 105) + 18 && mouseY <= ((height + 60) / 2f - 105) + 34) { - tooltipToDisplay = slot2.getTooltip(Minecraft.getMinecraft().thePlayer, false); - if (shouldShowEquipmentTooltip(tooltipToDisplay)) { - Utils.drawHoveringText( - tooltipToDisplay, - mouseX - calculateTooltipXOffset(tooltipToDisplay, fr), - mouseY, - width, - height, - -1, - fr - ); - } - } - if (mouseY >= ((height + 60) / 2f - 105) + 36 && mouseY <= ((height + 60) / 2f - 105) + 52) { - tooltipToDisplay = slot3.getTooltip(Minecraft.getMinecraft().thePlayer, false); - if (shouldShowEquipmentTooltip(tooltipToDisplay)) { - Utils.drawHoveringText( - tooltipToDisplay, - mouseX - calculateTooltipXOffset(tooltipToDisplay, fr), - mouseY, - width, - height, - -1, - fr - ); - } - } - if (mouseY >= ((height + 60) / 2f - 105) + 54 && mouseY <= ((height + 60) / 2f - 105) + 70) { - tooltipToDisplay = slot4.getTooltip(Minecraft.getMinecraft().thePlayer, false); - if (shouldShowEquipmentTooltip(tooltipToDisplay)) { - Utils.drawHoveringText( - tooltipToDisplay, - mouseX - calculateTooltipXOffset(tooltipToDisplay, fr), - mouseY, - width, - height, - -1, - fr - ); - } - } - } - GL11.glTranslatef(0, 0, -401); - } - } - } - if (PetInfoOverlay.getCurrentPet() != null) { - if (NotEnoughUpdates.INSTANCE.config.petOverlay.petInvDisplay - && (NotEnoughUpdates.INSTANCE.manager - .jsonToStack(NotEnoughUpdates.INSTANCE.manager - .getItemInformation() - .get(PetInfoOverlay.getCurrentPet().petType + ";" + PetInfoOverlay.getCurrentPet().rarity.petId)) - .hasDisplayName() - || NotEnoughUpdates.INSTANCE.manager - .jsonToStack(NotEnoughUpdates.INSTANCE.manager - .getItemInformation() - .get(PetInfoOverlay.getCurrentPet().petType + ";" + (PetInfoOverlay.getCurrentPet().rarity.petId - 1))) - .hasDisplayName()) - && NotEnoughUpdates.INSTANCE.config.misc.hidePotionEffect && - NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { - if (!NotEnoughUpdates.INSTANCE.manager - .jsonToStack( - NotEnoughUpdates.INSTANCE.manager - .getItemInformation() - .get(PetInfoOverlay.getCurrentPet().petType + ";" + PetInfoOverlay.getCurrentPet().rarity.petId)) - .hasDisplayName()) { - petSlot = NotEnoughUpdates.INSTANCE.manager.jsonToStack( - NotEnoughUpdates.INSTANCE.manager.getItemInformation().get( - PetInfoOverlay.getCurrentPet().petType + ";" + (PetInfoOverlay.getCurrentPet().rarity.petId - 1))); - } else { - petSlot = NotEnoughUpdates.INSTANCE.manager.jsonToStack( - NotEnoughUpdates.INSTANCE.manager.getItemInformation().get( - PetInfoOverlay.getCurrentPet().petType + ";" + PetInfoOverlay.getCurrentPet().rarity.petId)); - } - if (petSlot == null) { - return; - } - petSlot.getTagCompound().setBoolean( - "NEUHIDEPETTOOLTIP", - NotEnoughUpdates.INSTANCE.config.petOverlay.hidePetTooltip - ); - ItemStack petInfo = petSlot; - - if (guiScreen instanceof GuiInventory) { - GL11.glTranslatef(0, 0, 401); - if (!NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud) { - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 0) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY); - } - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 1) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY_GREY); - } - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 2) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY_DARK); - } - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 3) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY_TRANSPARENT); - } - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 4) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY_FSR); - } - } else { - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 0) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY); - } - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 1) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY_GREY); - } - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 2) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY_DARK); - } - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 3) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY_TRANSPARENT); - } - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 4) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY_FSR); - } - } - - GlStateManager.color(1, 1, 1, 1); - float yNumber = (float) (height - 23) / 2f; - Utils.drawTexturedRect((float) ((width - 224.1) / 2f), yNumber, 31, 32, GL11.GL_NEAREST); - GlStateManager.bindTexture(0); - - Utils.drawItemStack(petInfo, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105) + 72, true); - renderingPetHud = true; - - List<String> tooltipToDisplay = null; - if (petInfo != null) { - if (mouseX >= ((width - 208) / 2f) && mouseX < ((width - 208) / 2f) + 16) { - if (mouseY >= ((height + 60) / 2f - 105) + 72 && mouseY <= ((height + 60) / 2f - 105) + 88 && - NotEnoughUpdates.INSTANCE.config.petOverlay.sendPetsCommand) { - if (Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) { - if (Mouse.getEventButtonState()) { - if (ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/pets") == - 0) { - NotEnoughUpdates.INSTANCE.sendChatMessage("/pets"); - } - } - } - tooltipToDisplay = petInfo.getTooltip(Minecraft.getMinecraft().thePlayer, false); - Utils.drawHoveringText( - tooltipToDisplay, - mouseX - calculateTooltipXOffset(tooltipToDisplay, fr), - mouseY, - width, - height, - -1, - fr - ); - GL11.glTranslatef(0, 0, -80); - } - } - - } - } - } - } - } - - /** - * Calculates the width of the longest String in the tooltip, which can be used to offset the entire tooltip to the left more precisely - * - * @param tooltipToDisplay tooltip - * @param fr FontRenderer object - * @return offset to apply - */ - private int calculateTooltipXOffset(List<String> tooltipToDisplay, FontRenderer fr) { - int offset = 0; - if (tooltipToDisplay != null) { - for (String line : tooltipToDisplay) { - int lineWidth = fr.getStringWidth(line); - if (lineWidth > offset) { - offset = lineWidth; - } - } - } - return offset + 20; - } - - private boolean shouldShowEquipmentTooltip(List<String> toolTip) { - return !toolTip.get(0).equals("§o§7Empty Equipment Slot§r"); - } /** * Used in SettingsInfoPane to redraw the items when a setting changes. diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java index 6cb26350..308cbdc0 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java @@ -35,8 +35,12 @@ import io.github.moulberry.notenoughupdates.listener.ItemTooltipRngListener; import io.github.moulberry.notenoughupdates.listener.NEUEventListener; import io.github.moulberry.notenoughupdates.listener.OldAnimationChecker; import io.github.moulberry.notenoughupdates.listener.RenderListener; +import io.github.moulberry.notenoughupdates.listener.WorldListener; +import io.github.moulberry.notenoughupdates.miscfeatures.AbiphoneWarning; +import io.github.moulberry.notenoughupdates.miscfeatures.AntiCoopAdd; +import io.github.moulberry.notenoughupdates.miscfeatures.AuctionBINWarning; import io.github.moulberry.notenoughupdates.miscfeatures.AuctionProfit; -import io.github.moulberry.notenoughupdates.miscfeatures.BazaarSacksProfit; +import io.github.moulberry.notenoughupdates.miscfeatures.BetterContainers; import io.github.moulberry.notenoughupdates.miscfeatures.CrystalOverlay; import io.github.moulberry.notenoughupdates.miscfeatures.CrystalWishingCompassSolver; import io.github.moulberry.notenoughupdates.miscfeatures.CustomItemEffects; @@ -67,6 +71,7 @@ import io.github.moulberry.notenoughupdates.miscgui.SignCalculator; import io.github.moulberry.notenoughupdates.miscgui.TrophyRewardOverlay; import io.github.moulberry.notenoughupdates.mixins.AccessorMinecraft; import io.github.moulberry.notenoughupdates.options.NEUConfig; +import io.github.moulberry.notenoughupdates.overlays.EquipmentOverlay; import io.github.moulberry.notenoughupdates.overlays.FuelBar; import io.github.moulberry.notenoughupdates.overlays.OverlayManager; import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer; @@ -90,6 +95,7 @@ import net.minecraft.world.biome.BiomeGenHell; import net.minecraft.world.biome.BiomeGenJungle; import net.minecraft.world.biome.BiomeGenMesa; import net.minecraft.world.biome.BiomeGenSnow; +import net.minecraftforge.client.ClientCommandHandler; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.client.registry.ClientRegistry; @@ -98,6 +104,8 @@ import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.awt.*; import java.io.BufferedReader; @@ -111,13 +119,17 @@ import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Set; -@Mod(modid = NotEnoughUpdates.MODID, version = NotEnoughUpdates.VERSION, clientSideOnly = true) +@Mod( + modid = NotEnoughUpdates.MODID, version = NotEnoughUpdates.VERSION, clientSideOnly = true, useMetadata = true, + guiFactory = "io.github.moulberry.notenoughupdates.core.config.MoulConfigGuiForgeInterop") public class NotEnoughUpdates { public static final String MODID = "notenoughupdates"; public static final String VERSION = "2.1.0-REL"; - public static final int VERSION_ID = 20100; + public static final int VERSION_ID = 20101; //2.1.1 only so update notif works public static final int PRE_VERSION_ID = 0; public static final int HOTFIX_VERSION_ID = 0; + + public static final Logger LOGGER = LogManager.getLogger("NotEnoughUpdates"); /** * Registers the biomes for the crystal hollows here so optifine knows they exists */ @@ -244,7 +256,6 @@ public class NotEnoughUpdates { config.apiKey = null; } - //add the trophy fishing tab to the config if (config.profileViewer.pageLayout.size() == 8) { config.profileViewer.pageLayout.add(8); @@ -252,9 +263,19 @@ public class NotEnoughUpdates { if (config.profileViewer.pageLayout.size() == 9) { config.profileViewer.pageLayout.add(9); } + + // Remove after 2.1 ig + if ("dangerous".equals(config.apiData.repoBranch)) { + config.apiData.repoBranch = "master"; + } + saveConfig(); } + if (config != null) + if (config.mining.powderGrindingTrackerResetMode == 2) + OverlayManager.powderGrindingOverlay.load(); + MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.register(new NEUEventListener(this)); MinecraftForge.EVENT_BUS.register(new RecipeGenerator(this)); @@ -283,6 +304,7 @@ public class NotEnoughUpdates { MinecraftForge.EVENT_BUS.register(FishingHelper.getInstance()); MinecraftForge.EVENT_BUS.register(CrystalWishingCompassSolver.getInstance()); MinecraftForge.EVENT_BUS.register(new DwarvenMinesTextures()); + MinecraftForge.EVENT_BUS.register(EquipmentOverlay.INSTANCE); MinecraftForge.EVENT_BUS.register(CustomBiomes.INSTANCE); MinecraftForge.EVENT_BUS.register(new ChatListener(this)); MinecraftForge.EVENT_BUS.register(new ItemTooltipListener(this)); @@ -293,9 +315,13 @@ public class NotEnoughUpdates { MinecraftForge.EVENT_BUS.register(new SignCalculator()); MinecraftForge.EVENT_BUS.register(TrophyRewardOverlay.getInstance()); MinecraftForge.EVENT_BUS.register(PowerStoneStatsDisplay.getInstance()); - MinecraftForge.EVENT_BUS.register(BazaarSacksProfit.getInstance()); + MinecraftForge.EVENT_BUS.register(new AntiCoopAdd()); + MinecraftForge.EVENT_BUS.register(AbiphoneWarning.getInstance()); + MinecraftForge.EVENT_BUS.register(new BetterContainers()); + MinecraftForge.EVENT_BUS.register(AuctionBINWarning.getInstance()); MinecraftForge.EVENT_BUS.register(navigation); MinecraftForge.EVENT_BUS.register(new GlowingMushroomHighlighter()); + MinecraftForge.EVENT_BUS.register(new WorldListener(this)); if (Minecraft.getMinecraft().getResourceManager() instanceof IReloadableResourceManager) { IReloadableResourceManager manager = (IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager(); @@ -332,6 +358,11 @@ public class NotEnoughUpdates { public void saveConfig() { try { + OverlayManager.powderGrindingOverlay.save(); + } catch (Exception ignored) { + } + + try { configFile.createNewFile(); try ( @@ -382,6 +413,12 @@ public class NotEnoughUpdates { } } + public void trySendCommand(String message) { + if (ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, message) == 0) { + sendChatMessage(message); + } + } + public void displayLinks(JsonObject update, int totalWidth) { String discord_link = update.get("discord_link").getAsString(); String youtube_link = update.get("youtube_link").getAsString(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java index 2dc02b7e..1b6896db 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java @@ -287,23 +287,26 @@ public class APIManager { } public void updateLowestBin() { - manager.hypixelApi.getMyApiGZIPAsync("lowestbin.json.gz", (jsonObject) -> { - if (lowestBins == null) { - lowestBins = new JsonObject(); - } - if (!jsonObject.entrySet().isEmpty()) { - lastLowestBinUpdate = System.currentTimeMillis(); - } - for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) { - lowestBins.add(entry.getKey(), entry.getValue()); - } - if (!didFirstUpdate) { - ItemPriceInformation.updateAuctionableItemsList(); - didFirstUpdate = true; - } - GuiPriceGraph.addToCache(lowestBins, false); - }, () -> { - }); + manager.apiUtils + .newMoulberryRequest("lowestbin.json.gz") + .gunzip() + .requestJson() + .thenAccept(jsonObject -> { + if (lowestBins == null) { + lowestBins = new JsonObject(); + } + if (!jsonObject.entrySet().isEmpty()) { + lastLowestBinUpdate = System.currentTimeMillis(); + } + for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) { + lowestBins.add(entry.getKey(), entry.getValue()); + } + if (!didFirstUpdate) { + ItemPriceInformation.updateAuctionableItemsList(); + didFirstUpdate = true; + } + GuiPriceGraph.addToCache(lowestBins, false); + }); } private void ahNotification() { @@ -460,20 +463,23 @@ public class APIManager { } }; - manager.hypixelApi.getMyApiGZIPAsync("auctionLast.json.gz", process, () -> - System.out.println("Error downloading auction from Moulberry's jank API. :(")); + manager.apiUtils.newMoulberryRequest("auctionLast.json.gz") + .gunzip().requestJson().thenAccept(process); - manager.hypixelApi.getMyApiGZIPAsync("auction.json.gz", jsonObject -> { - if (jsonObject.get("success").getAsBoolean()) { - long apiUpdate = (long) jsonObject.get("time").getAsFloat(); - if (lastApiUpdate == apiUpdate) { - lastAuctionUpdate -= 30 * 1000; - } - lastApiUpdate = apiUpdate; + manager.apiUtils + .newMoulberryRequest("auction.json.gz") + .gunzip().requestJson() + .thenAccept(jsonObject -> { + if (jsonObject.get("success").getAsBoolean()) { + long apiUpdate = (long) jsonObject.get("time").getAsFloat(); + if (lastApiUpdate == apiUpdate) { + lastAuctionUpdate -= 30 * 1000; + } + lastApiUpdate = apiUpdate; - process.accept(jsonObject); - } - }, () -> System.out.println("Error downloading auction from Moulberry's jank API. :(")); + process.accept(jsonObject); + } + }); } @@ -673,8 +679,10 @@ public class APIManager { //System.out.println("Trying to update page: " + page); HashMap<String, String> args = new HashMap<>(); args.put("page", "" + page); - manager.hypixelApi.getHypixelApiAsync(null, "skyblock/auctions", - args, jsonObject -> { + manager.apiUtils + .newAnonymousHypixelApiRequest("skyblock/auctions") + .requestJson() + .thenAccept(jsonObject -> { if (jsonObject == null) return; if (jsonObject.get("success").getAsBoolean()) { @@ -701,8 +709,13 @@ public class APIManager { } else { pagesToDownload.addLast(page); } - }, () -> pagesToDownload.addLast(page) - ); + }) + .handle((ignored, ex) -> { + if (ex != null) { + pagesToDownload.addLast(page); + } + return null; + }); } private static final Pattern BAZAAR_ENCHANTMENT_PATTERN = Pattern.compile("ENCHANTMENT_(\\D*)_(\\d+)"); @@ -716,11 +729,10 @@ public class APIManager { } public void updateBazaar() { - manager.hypixelApi.getHypixelApiAsync( - NotEnoughUpdates.INSTANCE.config.apiData.apiKey, - "skyblock/bazaar", - new HashMap<>(), - (jsonObject) -> { + manager.apiUtils + .newHypixelApiRequest("skyblock/bazaar") + .requestJson() + .thenAccept(jsonObject -> { if (!jsonObject.get("success").getAsBoolean()) return; craftCost.clear(); @@ -755,20 +767,23 @@ public class APIManager { } } GuiPriceGraph.addToCache(bazaarJson, true); - } - ); + }); } public void updateAvgPrices() { - manager.hypixelApi.getMyApiGZIPAsync("auction_averages/3day.json.gz", (jsonObject) -> { - craftCost.clear(); - auctionPricesJson = jsonObject; - lastAuctionAvgUpdate = System.currentTimeMillis(); - }, () -> { - }); - manager.hypixelApi.getMyApiGZIPAsync("auction_averages_lbin/1day.json.gz", (jsonObject) -> - auctionPricesAvgLowestBinJson = jsonObject, () -> { - }); + manager.apiUtils + .newMoulberryRequest("auction_averages/3day.json.gz") + .gunzip().requestJson().thenAccept((jsonObject) -> { + craftCost.clear(); + auctionPricesJson = jsonObject; + lastAuctionAvgUpdate = System.currentTimeMillis(); + }); + manager.apiUtils + .newMoulberryRequest("auction_averages_lbin/1day.json.gz") + .gunzip().requestJson() + .thenAccept((jsonObject) -> { + auctionPricesAvgLowestBinJson = jsonObject; + }); } public Set<String> getItemAuctionInfoKeySet() { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java index fcb2aaf9..62981a30 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java @@ -23,6 +23,7 @@ import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.commands.dev.DevTestCommand; import io.github.moulberry.notenoughupdates.commands.dev.DiagCommand; import io.github.moulberry.notenoughupdates.commands.dev.DungeonWinTestCommand; +import io.github.moulberry.notenoughupdates.commands.dev.EnableStorageCommand; import io.github.moulberry.notenoughupdates.commands.dev.NullzeeSphereCommand; import io.github.moulberry.notenoughupdates.commands.dev.PackDevCommand; import io.github.moulberry.notenoughupdates.commands.dev.ReloadRepoCommand; @@ -74,6 +75,7 @@ public class Commands { ClientCommandHandler.instance.registerCommand(new DiagCommand()); ClientCommandHandler.instance.registerCommand(new ReloadRepoCommand()); ClientCommandHandler.instance.registerCommand(new ResetRepoCommand()); + ClientCommandHandler.instance.registerCommand(new EnableStorageCommand()); // Profile Commands ClientCommandHandler.instance.registerCommand(new PeekCommand()); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java index fdf59bb0..138486c3 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java @@ -34,6 +34,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; +import net.minecraft.launchwrapper.Launch; import net.minecraft.util.BlockPos; import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; @@ -48,16 +49,20 @@ public class DevTestCommand extends ClientCommandBase { private static final List<String> DEV_TESTERS = Arrays.asList( - "moulberry", - "lucycoconut", - "ironm00n", - "ariyio", - "throwpo", - "lrg89", - "dediamondpro", - "lulonaut", - "craftyoldminer", - "eisengolem" + "d0e05de7-6067-454d-beae-c6d19d886191", // moulberry + "66502b40-6ac1-4d33-950d-3df110297aab", // lucycoconut + "a5761ff3-c710-4cab-b4f4-3e7f017a8dbf", // ironm00n + "5d5c548a-790c-4fc8-bd8f-d25b04857f44", // ariyio + "53924f1a-87e6-4709-8e53-f1c7d13dc239", // throwpo + "d3cb85e2-3075-48a1-b213-a9bfb62360c1", // lrg89 + "0b4d470f-f2fb-4874-9334-1eaef8ba4804", // dediamondpro + "ebb28704-ed85-43a6-9e24-2fe9883df9c2", // lulonaut + "698e199d-6bd1-4b10-ab0c-52fedd1460dc", // craftyoldminer + "8a9f1841-48e9-48ed-b14f-76a124e6c9df", // eisengolem + "a7d6b3f1-8425-48e5-8acc-9a38ab9b86f7", // whalker + "0ce87d5a-fa5f-4619-ae78-872d9c5e07fe", // ascynx + "a049a538-4dd8-43f8-87d5-03f09d48b4dc", // egirlefe + "7a9dc802-d401-4d7d-93c0-8dd1bc98c70d" // efefury ); private static final String[] DEV_FAIL_STRINGS = { @@ -86,7 +91,8 @@ public class DevTestCommand extends ClientCommandBase { @Override public void processCommand(ICommandSender sender, String[] args) throws CommandException { - if (!DEV_TESTERS.contains(Minecraft.getMinecraft().thePlayer.getName().toLowerCase())) { + if (!DEV_TESTERS.contains(Minecraft.getMinecraft().thePlayer.getUniqueID().toString()) + && !(boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment")) { if (devFailIndex >= DEV_FAIL_STRINGS.length) { throw new Error("L") { @Override @@ -185,7 +191,7 @@ public class DevTestCommand extends ClientCommandBase { "Opening gui: " + NotEnoughUpdates.INSTANCE.openGui)); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | ClassCastException e) { e.printStackTrace(); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Failed to open this gui.")); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Failed to open this GUI.")); } } if (args.length == 1 && args[0].equalsIgnoreCase("center")) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java index 326c00b4..fb546efb 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java @@ -41,7 +41,8 @@ public class DiagCommand extends ClientCommandBase { " center=<off | on> Disable / enable using center\n" + "/neudiag wishing Wishing Compass Solver diagnostics\n" + "/neudiag debug\n" + - " <no sub-command> Show current flags\n" + + " <no sub-command> Show all enabled flags\n" + + " <list> Show all flags\n"+ " <enable | disable> <flag> Enable/disable flag\n"; private void showUsage(ICommandSender sender) { @@ -86,6 +87,10 @@ public class DiagCommand extends ClientCommandBase { boolean enablingFlag = true; String action = args[1]; switch (action) { + case "list": + sender.addChatMessage(new ChatComponentText( + EnumChatFormatting.YELLOW + "Here are all flags:\n" + NEUDebugFlag.getFlagList())); + return; case "disable": enablingFlag = false; // falls through @@ -93,7 +98,7 @@ public class DiagCommand extends ClientCommandBase { if (args.length != 3) { sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "You must specify a flag:\n" + - NEUDebugFlag.FLAG_LIST)); + NEUDebugFlag.getFlagList())); return; } @@ -108,7 +113,7 @@ public class DiagCommand extends ClientCommandBase { } catch (IllegalArgumentException e) { sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + flagName + " is invalid. Valid flags are:\n" + - NEUDebugFlag.FLAG_LIST)); + NEUDebugFlag.getFlagList())); return; } break; @@ -118,8 +123,8 @@ public class DiagCommand extends ClientCommandBase { } } - sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Effective debug flags: " + - NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.toString())); + sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Effective debug flags: \n" + + NEUDebugFlag.getEnabledFlags())); break; default: showUsage(sender); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/EnableStorageCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/EnableStorageCommand.java new file mode 100644 index 00000000..3415b030 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/EnableStorageCommand.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.commands.dev; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; + +public class EnableStorageCommand extends ClientCommandBase { + + public EnableStorageCommand() { + super("neuenablestorage"); + } + + @Override + public void processCommand(ICommandSender sender, String[] args) throws CommandException { + NotEnoughUpdates.INSTANCE.config.storageGUI.enableStorageGUI3 = true; + NotEnoughUpdates.INSTANCE.saveConfig(); + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java index 756afc88..e9d4eb44 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java @@ -31,6 +31,7 @@ import net.minecraft.util.BlockPos; import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; import net.minecraftforge.common.ForgeVersion; +import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.common.Loader; import org.lwjgl.opengl.Display; import org.lwjgl.opengl.GL11; @@ -164,9 +165,10 @@ public class StatsCommand extends ClientCommandBase { builder.append("FPS", String.valueOf(Minecraft.getDebugFPS())); builder.append("Loaded Mods", String.valueOf(activeModCount)); builder.append("Forge", ForgeVersion.getVersion()); + builder.append("Optifine", FMLClientHandler.instance().hasOptifine() ? "TRUE" : "FALSE"); builder.category("Neu Settings"); builder.append("API Key", NotEnoughUpdates.INSTANCE.config.apiData.apiKey.isEmpty() ? "FALSE" : "TRUE"); - builder.append("On Skyblock", NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() ? "TRUE" : "FALSE"); + builder.append("On SkyBlock", NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() ? "TRUE" : "FALSE"); builder.append( "Mod Version", Loader.instance().getIndexedModList().get(NotEnoughUpdates.MODID).getDisplayVersion() diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java index d69f86f3..c1f88942 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java @@ -44,7 +44,7 @@ public class JoinDungeonCommand extends ClientCommandBase { EnumChatFormatting.RED + "Example Usage: /join f7, /join m6 or /join 7")); } else { String cataPrefix = "catacombs"; - if (args[0].startsWith("m")) { + if (args[0].toLowerCase().startsWith("m")) { cataPrefix = "master_catacombs"; } String cmd = "/joindungeon " + cataPrefix + " " + args[0].charAt(args[0].length() - 1); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java index 7655f561..49123f45 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java @@ -38,7 +38,7 @@ public class HelpCommand extends ClientCommandBase { public void processCommand(ICommandSender sender, String[] args) { ArrayList<String> neuHelpMessages = Lists.newArrayList( "\u00a75\u00a7lNotEnoughUpdates commands", - "\u00a76/neu \u00a77- Opens the main neu GUI.", + "\u00a76/neu \u00a77- Opens the main NEU GUI.", "\u00a76/pv \u00a7b?{name} \u00a72\u2D35 \u00a7r\u00a77- Opens the profile viewer", "\u00a76/neusouls {on/off/clear/unclear} \u00a7r\u00a77- Shows waypoints to fairy souls.", "\u00a76/neubuttons \u00a7r\u00a77- Opens a GUI which allows you to customize inventory buttons.", @@ -46,19 +46,19 @@ public class HelpCommand extends ClientCommandBase { "\u00a76/join {floor} \u00a7r\u00a77- Short Command to join a Dungeon. \u00a7lNeed a Party of 5 People\u00a7r\u00a77 {4/f7/m5}.", "\u00a76/neucosmetics \u00a7r\u00a77- Opens the cosmetic GUI.", "\u00a76/neurename \u00a7r\u00a77- Opens the NEU Item Customizer.", - "\u00a76/cata \u00a7b?{name} \u00a72\u2D35 \u00a7r\u00a77- Opens the profile viewer's catacombs page.", - "\u00a76/neulinks \u00a7r\u00a77- Shows links to neu/moulberry.", + "\u00a76/cata \u00a7b?{name} \u00a72\u2D35 \u00a7r\u00a77- Opens the profile viewer's Catacombs page.", + "\u00a76/neulinks \u00a7r\u00a77- Shows links to NEU/Moulberry.", "\u00a76/neuoverlay \u00a7r\u00a77- Opens GUI Editor for quickcommands and searchbar.", - "\u00a76/neuah \u00a7r\u00a77- Opens neu's custom ah GUI.", - "\u00a76/neucalendar \u00a7r\u00a77- Opens neu's custom calendar GUI.", + "\u00a76/neuah \u00a7r\u00a77- Opens NEU's custom auction house GUI.", + "\u00a76/neucalendar \u00a7r\u00a77- Opens NEU's custom calendar GUI.", "\u00a76/neucalc \u00a7r\u00a77- Run calculations.", "", "\u00a76\u00a7lOld commands:", - "\u00a76/peek \u00a7b?{user} \u00a72\u2D35 \u00a7r\u00a77- Shows quickly stats for a user.", + "\u00a76/peek \u00a7b?{user} \u00a72\u2D35 \u00a7r\u00a77- Shows quick stats for a user.", "", "\u00a76\u00a7lDebug commands:", "\u00a76/neustats \u00a7r\u00a77- Copies helpful info to the clipboard.", - "\u00a76/neustats modlist \u00a7r\u00a77- Copies modlist info to clipboard.", + "\u00a76/neustats modlist \u00a7r\u00a77- Copies mod list info to clipboard.", "\u00a76/neuresetrepo \u00a7r\u00a77- Deletes all repo files.", "\u00a76/neureloadrepo \u00a7r\u00a77- Debug command with repo.", "", @@ -81,7 +81,7 @@ public class HelpCommand extends ClientCommandBase { } String[] helpInfo = { "", - "\u00a77Commands marked with a \u00a72\"\u2D35\"\u00a77 require are api key. You can set your api key via \"/api new\" or by manually putting it in the api field in \"/neu\"", + "\u00a77Commands marked with a \u00a72\"\u2D35\"\u00a77 require an api key. You can set your api key via \"/api new\" or by manually putting it in the api field in \"/neu\"", "", "\u00a77Arguments marked with a \u00a7b\"?\"\u00a77 are optional.", "", diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java index bd8abf1d..d51d4d2e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java @@ -39,11 +39,11 @@ public class AhCommand extends ClientCommandBase { public void processCommand(ICommandSender sender, String[] args) throws CommandException { if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "You must be on Skyblock to use this feature.")); + "You must be on SkyBlock to use this feature.")); } else if (NotEnoughUpdates.INSTANCE.config.apiData.apiKey == null || NotEnoughUpdates.INSTANCE.config.apiData.apiKey.trim().isEmpty()) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "Can't open NeuAH, apikey is not set. Run /api new and put the result in settings.")); + "Can't open NEU AH: an api key is not set. Run /api new and put the result in settings.")); } else { NotEnoughUpdates.INSTANCE.openGui = new CustomAHGui(); NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.lastOpen = System.currentTimeMillis(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java index f74b5813..67430ffa 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java @@ -39,7 +39,7 @@ public class CosmeticsCommand extends ClientCommandBase { public void processCommand(ICommandSender sender, String[] args) throws CommandException { if (!OpenGlHelper.isFramebufferEnabled() && NotEnoughUpdates.INSTANCE.config.notifications.doFastRenderNotif) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "NEU cosmetics do not work with OF Fast Render. Go to ESC > Options > Video Settings > Performance > Fast Render to disable it.")); + "NEU Cosmetics do not work with OptiFine Fast Render. Go to ESC > Options > Video Settings > Performance > Fast Render to disable it.")); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CustomizeCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CustomizeCommand.java index cca6535e..2b184fa0 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CustomizeCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CustomizeCommand.java @@ -54,7 +54,7 @@ public class CustomizeCommand extends ClientCommandBase { String heldUUID = NotEnoughUpdates.INSTANCE.manager.getUUIDForItem(held); if (heldUUID == null) { - sender.addChatMessage(new ChatComponentText("\u00a7cHeld item does not have UUID, cannot be customized")); + sender.addChatMessage(new ChatComponentText("\u00a7cHeld item does not have a UUID, so it cannot be customized")); return; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/PronounsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/PronounsCommand.java index 6d0ee88d..5a4f1400 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/PronounsCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/PronounsCommand.java @@ -25,7 +25,6 @@ import io.github.moulberry.notenoughupdates.util.MinecraftExecutor; import io.github.moulberry.notenoughupdates.util.PronounDB; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; -import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.gui.GuiNewChat; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; @@ -75,9 +74,9 @@ public class PronounsCommand extends ClientCommandBase { c.complete(Utils.parseDashlessUUID(uuidString)); } }); - pronouns = c.thenApplyAsync(PronounDB::getPronounsFor); + pronouns = c.thenCompose(PronounDB::getPronounsFor); } else { - pronouns = CompletableFuture.supplyAsync(() -> PronounDB.getPronounsFor(platform, user)); + pronouns = PronounDB.getPronounsFor(platform, user); } pronouns.handleAsync((pronounChoice, throwable) -> { if (throwable != null || !pronounChoice.isPresent()) { @@ -85,7 +84,8 @@ public class PronounsCommand extends ClientCommandBase { return null; } PronounDB.PronounChoice betterPronounChoice = pronounChoice.get(); - nc.printChatMessageWithOptionalDeletion(new ChatComponentText("§e[NEU] Pronouns for §b" + user + " §eon §b" + platform + "§e:"), id); + nc.printChatMessageWithOptionalDeletion(new ChatComponentText( + "§e[NEU] Pronouns for §b" + user + " §eon §b" + platform + "§e:"), id); betterPronounChoice.render().forEach(it -> nc.printChatMessage(new ChatComponentText("§e[NEU] §a" + it))); return null; }, MinecraftExecutor.INSTANCE); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/UpdateCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/UpdateCommand.java index 36443b27..1aeebda5 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/UpdateCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/UpdateCommand.java @@ -25,8 +25,6 @@ import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; import net.minecraft.util.ChatComponentText; -import java.net.MalformedURLException; -import java.net.URL; import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -49,10 +47,6 @@ public class UpdateCommand extends ClientCommandBase { "" + "§e[NEU] §b/neuupdate help - View help.\n" + "§e[NEU] §b/neuupdate check - Check for updates.\n" + - "§e[NEU] §b/neuupdate url <url> - Load an update from an direct download URL.\n" + - " §cONLY DO THIS WITH TRUSTED URLS OR IT MIGHT RESULT IN A RAT!\n" + - "§e[NEU] §b/neuupdate fromartifact <url> - Load an update from an artifact.\n" + - " §cIf you don't know what this is, don't use it.\n" + "" )); @@ -68,25 +62,11 @@ public class UpdateCommand extends ClientCommandBase { case "check": neu.autoUpdater.displayUpdateMessageIfOutOfDate(); break; - case "url": - if (args.length != 2) { - sender.addChatMessage(new ChatComponentText("§e[NEU] §cPlease provide an URL")); - } - URL url; - try { - url = new URL(args[1]); - } catch (MalformedURLException e) { - e.printStackTrace(); - sender.addChatMessage(new ChatComponentText("§e[NEU] §cInvalid URL")); - return; - } - neu.autoUpdater.updateFromURL(url); - break; case "scheduledownload": neu.autoUpdater.scheduleDownload(); break; case "updatemodes": - sender.addChatMessage(new ChatComponentText("§e[NEU] §bTo ensure we do not accidentally corrupt your mod folder, we can only offer support for autoupdates on system with certain capabilities for file deletions (specifically unix systems). You can still manually update your files")); + sender.addChatMessage(new ChatComponentText("§e[NEU] §bTo ensure we do not accidentally corrupt your mod folder, we can only offer support for auto-updates on system with certain capabilities for file deletions (specifically unix systems). You can still manually update your files")); break; default: displayHelp(sender); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java index 421f7c10..77377917 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java @@ -39,6 +39,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Random; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -68,22 +69,22 @@ public class PeekCommand extends ClientCommandBase { NotEnoughUpdates.profileViewer.getProfileByName(name, profile -> { if (profile == null) { Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessageWithOptionalDeletion(new ChatComponentText( - EnumChatFormatting.RED + "[PEEK] Unknown player or the api is down."), id); + EnumChatFormatting.RED + "[PEEK] Unknown player or the Hypixel API is down."), id); } else { profile.resetCache(); - if (peekCommandExecutorService == null) { + if (peekCommandExecutorService == null || peekCommandExecutorService.isTerminated()) { peekCommandExecutorService = Executors.newSingleThreadScheduledExecutor(); } if (peekScheduledFuture != null && !peekScheduledFuture.isDone()) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "[PEEK] New peek command run, cancelling old one.")); + EnumChatFormatting.RED + "[PEEK] New peek command was run, cancelling old one.")); peekScheduledFuture.cancel(true); } Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessageWithOptionalDeletion(new ChatComponentText( - EnumChatFormatting.YELLOW + "[PEEK] Getting the player's Skyblock profile(s)..."), id); + EnumChatFormatting.YELLOW + "[PEEK] Getting the player's SkyBlock profile(s)..."), id); long startTime = System.currentTimeMillis(); peekScheduledFuture = peekCommandExecutorService.schedule(new Runnable() { @@ -105,13 +106,32 @@ public class PeekCommand extends ClientCommandBase { boolean isMe = name.equalsIgnoreCase("moulberry"); PlayerStats.Stats stats = profile.getStats(null); - if (stats == null) return; + if (stats == null) { + peekScheduledFuture = peekCommandExecutorService.schedule(this, 200, TimeUnit.MILLISECONDS); + return; + } Map<String, ProfileViewer.Level> skyblockInfo = profile.getSkyblockInfo(null); + if (NotEnoughUpdates.INSTANCE.config.profileViewer.useSoopyNetworth) { + Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessageWithOptionalDeletion(new ChatComponentText( + EnumChatFormatting.YELLOW + "[PEEK] Getting the player's Skyblock networth..."), id); + + CountDownLatch countDownLatch = new CountDownLatch(1); + + profile.getSoopyNetworth(null, () -> countDownLatch.countDown()); + + try { //Wait for async network request + countDownLatch.await(10, TimeUnit.SECONDS); + } catch (InterruptedException e) {} + + //Now it's waited for network request the data should be cached (accessed in nw section) + } + Minecraft.getMinecraft().ingameGUI .getChatGUI() .printChatMessageWithOptionalDeletion(new ChatComponentText(EnumChatFormatting.GREEN + " " + - EnumChatFormatting.STRIKETHROUGH + "-=-" + EnumChatFormatting.RESET + EnumChatFormatting.GREEN + " " + + EnumChatFormatting.STRIKETHROUGH + "-=-" + EnumChatFormatting.RESET + EnumChatFormatting.GREEN + + " " + Utils.getElementAsString(profile.getHypixelProfile().get("displayname"), name) + "'s Info " + EnumChatFormatting.STRIKETHROUGH + "-=-"), id); @@ -122,7 +142,7 @@ public class PeekCommand extends ClientCommandBase { float totalSkillLVL = 0; float totalSkillCount = 0; - List<String> skills = Arrays.asList("taming", "mining", "foraging", "enchanting", "farming", "combat", "fishing", "alchemy"); + List<String> skills = Arrays.asList("taming", "mining", "foraging", "enchanting", "farming", "combat", "fishing", "alchemy", "carpentry"); for (String skillName : skills) { totalSkillLVL += skyblockInfo.get(skillName).level; totalSkillCount++; @@ -133,6 +153,7 @@ public class PeekCommand extends ClientCommandBase { float spider = skyblockInfo.get("spider").level; float wolf = skyblockInfo.get("wolf").level; float enderman = skyblockInfo.get("enderman").level; + float blaze = skyblockInfo.get("blaze").level; float avgSkillLVL = totalSkillLVL / totalSkillCount; @@ -143,6 +164,7 @@ public class PeekCommand extends ClientCommandBase { spider = 1; wolf = 2; enderman = 0; + blaze = 0; } EnumChatFormatting combatPrefix = combat > 20 @@ -161,6 +183,11 @@ public class PeekCommand extends ClientCommandBase { ? EnumChatFormatting.GREEN : EnumChatFormatting.YELLOW) : EnumChatFormatting.RED; + EnumChatFormatting blazePrefix = blaze > 3 + ? (blaze > 6 + ? EnumChatFormatting.GREEN + : EnumChatFormatting.YELLOW) + : EnumChatFormatting.RED; EnumChatFormatting avgPrefix = avgSkillLVL > 20 ? (avgSkillLVL > 35 ? EnumChatFormatting.GREEN @@ -171,6 +198,7 @@ public class PeekCommand extends ClientCommandBase { overallScore += spider * spider / 81f; overallScore += wolf * wolf / 81f; overallScore += enderman * enderman / 81f; + overallScore += blaze * blaze / 81f; overallScore += avgSkillLVL / 20f; int cata = (int) skyblockInfo.get("catacombs").level; @@ -187,8 +215,9 @@ public class PeekCommand extends ClientCommandBase { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( g + "Slayer: " + zombiePrefix + (int) Math.floor(zombie) + g + "-" + spiderPrefix + (int) Math.floor(spider) + g + "-" + - wolfPrefix + (int) Math.floor(wolf) + "-" + - endermanPrefix + (int) Math.floor(enderman))); + wolfPrefix + (int) Math.floor(wolf) + g + "-" + + endermanPrefix + (int) Math.floor(enderman) + g + "-" + + blazePrefix + (int) Math.floor(blaze))); } if (stats == null) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( @@ -229,7 +258,18 @@ public class PeekCommand extends ClientCommandBase { float bankBalance = Utils.getElementAsFloat(Utils.getElement(profileInfo, "banking.balance"), -1); float purseBalance = Utils.getElementAsFloat(Utils.getElement(profileInfo, "coin_purse"), 0); - long networth = profile.getNetWorth(null); + long networth; + if (NotEnoughUpdates.INSTANCE.config.profileViewer.useSoopyNetworth) { + ProfileViewer.Profile.SoopyNetworthData nwData = profile.getSoopyNetworth(null, () -> {}); + if (nwData == null) { + networth = -2l; + } else { + networth = nwData.getTotal(); + } + } else { + networth = profile.getNetWorth(null); + } + float money = Math.max(bankBalance + purseBalance, networth); EnumChatFormatting moneyPrefix = money > 50 * 1000 * 1000 ? (money > 200 * 1000 * 1000 @@ -278,7 +318,7 @@ public class PeekCommand extends ClientCommandBase { } else if (overallScore > 2) { overall = EnumChatFormatting.YELLOW + "Ender Non"; } else if (overallScore > 1) { - overall = EnumChatFormatting.RED + "Played Skyblock"; + overall = EnumChatFormatting.RED + "Played SkyBlock"; } Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(g + "Overall score: " + diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java index e4ca497c..887cd28f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java @@ -39,18 +39,18 @@ public class ViewProfileCommand extends ClientCommandBase { public static final Consumer<String[]> RUNNABLE = (args) -> { if (!OpenGlHelper.isFramebufferEnabled()) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "Some parts of the profile viewer do not work with OF Fast Render. Go to ESC > Options > Video Settings > Performance > Fast Render to disable it.")); + "Some parts of the profile viewer do not work with OptiFine Fast Render. Go to ESC > Options > Video Settings > Performance > Fast Render to disable it.")); } if (NotEnoughUpdates.INSTANCE.config.apiData.apiKey == null || NotEnoughUpdates.INSTANCE.config.apiData.apiKey.trim().isEmpty()) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "Can't view profile, apikey is not set. Run /api new and put the result in settings.")); + "Can't view profile, an API key is not set. Run /api new and put the result in settings.")); } else if (args.length == 0) { NotEnoughUpdates.profileViewer.getProfileByName(Minecraft.getMinecraft().thePlayer.getName(), profile -> { if (profile == null) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "Invalid player name/api key. Maybe api is down? Try /api new.")); + "Invalid player name/API key. Maybe the API is down? Try /api new.")); } else { profile.resetCache(); NotEnoughUpdates.INSTANCE.openGui = new GuiProfileViewer(profile); @@ -63,7 +63,7 @@ public class ViewProfileCommand extends ClientCommandBase { NotEnoughUpdates.profileViewer.getProfileByName(args[0], profile -> { if (profile == null) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + - "Invalid player name/api key. Maybe api is down? Try /api new.")); + "Invalid player name/api key. Maybe the API is down? Try /api new.")); } else { profile.resetCache(); NotEnoughUpdates.INSTANCE.openGui = new GuiProfileViewer(profile); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementBoolean.java b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementBoolean.java index b0586210..11547aaa 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementBoolean.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementBoolean.java @@ -26,7 +26,6 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.util.ResourceLocation; import org.lwjgl.input.Mouse; -import org.lwjgl.opengl.GL11; import java.util.function.Consumer; @@ -63,8 +62,10 @@ public class GuiElementBoolean extends GuiElement { @Override public void render() { GlStateManager.color(1, 1, 1, 1); + Minecraft.getMinecraft().getTextureManager().bindTexture(GuiTextures.BAR); + RenderUtils.drawTexturedRect(x, y, xSize, ySize); + ResourceLocation buttonLoc = GuiTextures.ON; - ResourceLocation barLoc = GuiTextures.BAR_ON; long currentMillis = System.currentTimeMillis(); long deltaMillis = currentMillis - lastMillis; lastMillis = currentMillis; @@ -101,25 +102,16 @@ public class GuiElementBoolean extends GuiElement { int animation = (int) (LerpUtils.sigmoidZeroOne(this.animation / 36f) * 36); if (animation < 3) { buttonLoc = GuiTextures.OFF; - barLoc = GuiTextures.BAR; } else if (animation < 13) { buttonLoc = GuiTextures.ONE; - barLoc = GuiTextures.BAR_ONE; } else if (animation < 23) { buttonLoc = GuiTextures.TWO; - barLoc = GuiTextures.BAR_TWO; } else if (animation < 33) { buttonLoc = GuiTextures.THREE; - barLoc = GuiTextures.BAR_THREE; } - GL11.glTranslatef(0, 0, 100); Minecraft.getMinecraft().getTextureManager().bindTexture(buttonLoc); RenderUtils.drawTexturedRect(x + animation, y, 12, 14); - GL11.glTranslatef(0, 0, -100); - - Minecraft.getMinecraft().getTextureManager().bindTexture(barLoc); - RenderUtils.drawTexturedRect(x, y, xSize, ySize); } @Override diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/MoulConfigGuiForgeInterop.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/MoulConfigGuiForgeInterop.java new file mode 100644 index 00000000..40887e54 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/MoulConfigGuiForgeInterop.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.core.config; + +import io.github.moulberry.notenoughupdates.core.GuiScreenElementWrapper; +import io.github.moulberry.notenoughupdates.options.NEUConfigEditor; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; +import net.minecraftforge.fml.client.IModGuiFactory; +import org.lwjgl.input.Keyboard; + +import java.io.IOException; +import java.util.Set; + +public class MoulConfigGuiForgeInterop implements IModGuiFactory { + @Override + public void initialize(Minecraft minecraft) {} + + @Override + public Class<? extends GuiScreen> mainConfigGuiClass() { + return WrappedMoulConfig.class; + } + + @Override + public Set<RuntimeOptionCategoryElement> runtimeGuiCategories() { + return null; + } + + @Override + public RuntimeOptionGuiHandler getHandlerFor(RuntimeOptionCategoryElement runtimeOptionCategoryElement) { + return null; + } + + public static class WrappedMoulConfig extends GuiScreenElementWrapper { + + private final GuiScreen parent; + + public WrappedMoulConfig(GuiScreen parent) { + super(NEUConfigEditor.editor); + this.parent = parent; + } + + @Override + public void handleKeyboardInput() throws IOException { + if (Keyboard.getEventKeyState() && Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) { + Minecraft.getMinecraft().displayGuiScreen(parent); + return; + } + super.handleKeyboardInput(); + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigOption.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigOption.java index d51294e7..920cb326 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigOption.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigOption.java @@ -30,6 +30,7 @@ public @interface ConfigOption { String name(); String desc(); + String[] searchTags() default ""; int subcategoryId() default -1; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDraggableList.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDraggableList.java index 63a932b5..d3b9c04d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDraggableList.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDraggableList.java @@ -72,6 +72,10 @@ public class GuiOptionEditorDraggableList extends GuiOptionEditor { int height = super.getHeight() + 13; for (int strIndex : activeText) { + if (strIndex >= exampleText.length) { + activeText.remove((Integer) strIndex); + break; + } String str = exampleText[strIndex]; height += 10 * str.split("\n").length; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java index 75862069..efdeab01 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java @@ -69,17 +69,19 @@ public class ConfigProcessor { public GuiOptionEditor editor; public int accordionId = -1; + public final String[] searchTags; private final Field field; private final Object container; - public ProcessedOption(String name, String desc, int subcategoryId, Field field, Object container) { + public ProcessedOption(String name, String desc, int subcategoryId, Field field, Object container, String[] searchTags) { this.name = name; this.desc = desc; this.subcategoryId = subcategoryId; this.field = field; this.container = container; + this.searchTags = searchTags; } public Object get() { @@ -137,7 +139,8 @@ public class ConfigProcessor { optionAnnotation.desc(), optionAnnotation.subcategoryId(), optionField, - categoryObj + categoryObj, + optionAnnotation.searchTags() ); if (optionField.isAnnotationPresent(ConfigAccordionId.class)) { ConfigAccordionId annotation = optionField.getAnnotation(ConfigAccordionId.class); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java index 293535e7..7a609a2a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java @@ -145,46 +145,53 @@ public class CapeManager { } private void updateCapes() { - NotEnoughUpdates.INSTANCE.manager.hypixelApi.getMyApiAsync("activecapes.json", (jsonObject) -> { - if (jsonObject.get("success").getAsBoolean()) { - lastJsonSync = jsonObject; - - lastCapeSynced = System.currentTimeMillis(); - capeMap.clear(); - for (JsonElement active : jsonObject.get("active").getAsJsonArray()) { - if (active.isJsonObject()) { - JsonObject activeObj = (JsonObject) active; - setCape(activeObj.get("_id").getAsString(), activeObj.get("capeType").getAsString(), false); + NotEnoughUpdates.INSTANCE.manager.apiUtils + .newMoulberryRequest("activecapes.json") + .requestJson() + .thenAccept(jsonObject -> { + if (jsonObject.get("success").getAsBoolean()) { + lastJsonSync = jsonObject; + + lastCapeSynced = System.currentTimeMillis(); + capeMap.clear(); + for (JsonElement active : jsonObject.get("active").getAsJsonArray()) { + if (active.isJsonObject()) { + JsonObject activeObj = (JsonObject) active; + setCape(activeObj.get("_id").getAsString(), activeObj.get("capeType").getAsString(), false); + } } } - } - }, () -> System.out.println("[MBAPI] Update capes errored")); + }); if (Minecraft.getMinecraft().thePlayer != null && permSyncTries > 0) { String uuid = Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", ""); permSyncTries--; - NotEnoughUpdates.INSTANCE.manager.hypixelApi.getMyApiAsync("permscapes.json", (jsonObject) -> { - if (!jsonObject.get("success").getAsBoolean()) return; - - permSyncTries = 0; - availableCapes.clear(); - for (JsonElement permPlayer : jsonObject.get("perms").getAsJsonArray()) { - if (!permPlayer.isJsonObject()) continue; - String playerUuid = permPlayer.getAsJsonObject().get("_id").getAsString(); - if (!(playerUuid != null && playerUuid.equals(uuid))) continue; - for (JsonElement perm : permPlayer.getAsJsonObject().get("perms").getAsJsonArray()) { - if (!perm.isJsonPrimitive()) continue; - String cape = perm.getAsString(); - if (cape.equals("*")) { - allAvailable = true; - } else { - availableCapes.add(cape); - } + NotEnoughUpdates.INSTANCE.manager.apiUtils + .newMoulberryRequest("permscapes.json") + .requestJson() + .thenAccept(jsonObject -> { + if (!jsonObject.get("success").getAsBoolean()) return; + + permSyncTries = 0; + availableCapes.clear(); + for (JsonElement permPlayer : jsonObject.get("perms").getAsJsonArray()) { + if (!permPlayer.isJsonObject()) continue; + String playerUuid = permPlayer.getAsJsonObject().get("_id").getAsString(); + if (!(playerUuid != null && playerUuid.equals(uuid))) continue; + for (JsonElement perm : permPlayer.getAsJsonObject().get("perms").getAsJsonArray()) { + if (!perm.isJsonPrimitive()) continue; + String cape = perm.getAsString(); + if (cape.equals("*")) { + allAvailable = true; + } else { + availableCapes.add(cape); + } + } + return; } - return; - } - }, () -> System.out.println("[MBAPI] Update capes errored - perms")); + + }); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/GuiCosmetics.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/GuiCosmetics.java index 0e37bed3..12d8c92d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/GuiCosmetics.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/GuiCosmetics.java @@ -404,21 +404,14 @@ public class GuiCosmetics extends GuiScreen { .getSession() .getProfile(), accessToken, serverId); - if (wantToEquipCape == null) { - NotEnoughUpdates.INSTANCE.manager.hypixelApi.getMyApiAsync( - "cgi-bin/changecape.py?capeType=null&serverId=" + - serverId + "&username=" + userName, - System.out::println, - () -> System.out.println("Change cape error") - ); - } else { - NotEnoughUpdates.INSTANCE.manager.hypixelApi.getMyApiAsync( - "cgi-bin/changecape.py?capeType=" + wantToEquipCape + "&serverId=" + - serverId + "&username=" + userName, - System.out::println, - () -> System.out.println("Change cape error") - ); - } + String toEquipName = wantToEquipCape == null ? "null" : wantToEquipCape; + NotEnoughUpdates.INSTANCE.manager.apiUtils + .newMoulberryRequest("cgi-bin/changecape.py") + .queryArgument("capeType", toEquipName) + .queryArgument("serverId", serverId) + .queryArgument("username", userName) + .requestString() + .thenAccept(System.out::println); } catch (Exception e) { System.out.println("Exception while generating mojang shared secret"); e.printStackTrace(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java index d4a728be..a4c5a60a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java @@ -726,7 +726,7 @@ public class DungeonMap { } GlStateManager.color(1, 1, 1, 1); if ((!NotEnoughUpdates.INSTANCE.config.dungeons.showOwnHeadAsMarker || - playerMarkerMapPositions.size() <= 1 || minU != 1 / 4f) && + playerMarkerMapPositions.size() < 1 || minU != 1 / 4f) && NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPlayerHeads >= 1 && playerSkinMap.containsKey(entry.getKey())) { Minecraft.getMinecraft().getTextureManager().bindTexture(playerSkinMap.get(entry.getKey())); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/events/GuiInventoryBackgroundDrawnEvent.java b/src/main/java/io/github/moulberry/notenoughupdates/events/GuiInventoryBackgroundDrawnEvent.java new file mode 100644 index 00000000..0b8bf126 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/events/GuiInventoryBackgroundDrawnEvent.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.events; + +import net.minecraft.client.gui.inventory.GuiContainer; + +public class GuiInventoryBackgroundDrawnEvent extends NEUEvent { + private final GuiContainer container; + private final float partialTicks; + + public GuiInventoryBackgroundDrawnEvent(GuiContainer container, float partialTicks) { + this.container = container; + this.partialTicks = partialTicks; + } + + public GuiContainer getContainer() { + return container; + } + + public float getPartialTicks() { + return partialTicks; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/events/SlotClickEvent.java b/src/main/java/io/github/moulberry/notenoughupdates/events/SlotClickEvent.java new file mode 100644 index 00000000..13c31b54 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/events/SlotClickEvent.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.events; + +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.inventory.Slot; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +@Cancelable +public class SlotClickEvent extends NEUEvent { + public final GuiContainer guiContainer; + public final Slot slot; + public final int slotId; + public int clickedButton; + public int clickType; + public boolean usePickblockInstead = false; + + public SlotClickEvent(GuiContainer guiContainer, Slot slot, int slotId, int clickedButton, int clickType) { + this.guiContainer = guiContainer; + this.slot = slot; + this.slotId = slotId; + this.clickedButton = clickedButton; + this.clickType = clickType; + } + + public void usePickblockInstead() { + usePickblockInstead = true; + } + + @Override + public void setCanceled(boolean cancel) { + super.setCanceled(cancel); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/infopanes/DevInfoPane.java b/src/main/java/io/github/moulberry/notenoughupdates/infopanes/DevInfoPane.java index a449919e..0b1963d6 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/infopanes/DevInfoPane.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/infopanes/DevInfoPane.java @@ -81,6 +81,7 @@ public class DevInfoPane extends TextInfoPane { for (String internalname : manager.auctionManager.getItemAuctionInfoKeySet()) { if (internalname.matches("^.*-[0-9]{1,3}$")) continue; if (!manager.getItemInformation().containsKey(internalname)) { + if (internalname.equals("RUNE") || internalname.contains("PARTY_HAT_CRAB")) continue; text += internalname + "\n"; } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java index b59eaf17..f85c165a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java @@ -33,6 +33,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.event.ClickEvent; import net.minecraft.util.ChatComponentText; import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.ChatStyle; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.IChatComponent; import net.minecraftforge.client.ClientCommandHandler; @@ -53,6 +54,8 @@ public class ChatListener { private final NotEnoughUpdates neu; private static final Pattern SLAYER_XP = Pattern.compile( " (Spider|Zombie|Wolf|Enderman|Blaze) Slayer LVL (\\d) - (?:Next LVL in ([\\d,]+) XP!|LVL MAXED OUT!)"); + + private static final Pattern SKYBLOCK_LVL_MESSAGE = Pattern.compile("\\[(\\d{1,4})\\] .*"); AtomicBoolean missingRecipe = new AtomicBoolean(false); public ChatListener(NotEnoughUpdates neu) { @@ -108,29 +111,67 @@ public class ChatListener { private IChatComponent replaceSocialControlsWithPV(IChatComponent chatComponent) { - if (NotEnoughUpdates.INSTANCE.config.misc.replaceSocialOptions1 > 0 && chatComponent.getChatStyle() != null && + if (NotEnoughUpdates.INSTANCE.config.misc.replaceSocialOptions1 > 0 && + ((chatComponent.getChatStyle() != null && chatComponent.getChatStyle().getChatClickEvent() != null && - chatComponent.getChatStyle().getChatClickEvent().getAction() == ClickEvent.Action.RUN_COMMAND && + chatComponent.getChatStyle().getChatClickEvent().getAction() == ClickEvent.Action.RUN_COMMAND) || + // Party and guild chat components are different from global chats, so need to check for them here + (!chatComponent.getSiblings().isEmpty() && chatComponent.getSiblings().get(0).getChatStyle() != null && + chatComponent.getSiblings().get(0).getChatStyle().getChatClickEvent() != null && + chatComponent.getSiblings().get(0).getChatStyle().getChatClickEvent().getAction() == ClickEvent.Action.RUN_COMMAND)) && NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { - if (chatComponent.getChatStyle().getChatClickEvent().getValue().startsWith("/socialoptions")) { - String username = chatComponent.getChatStyle().getChatClickEvent().getValue().substring(15); + + String startsWith = null; + boolean partyOrGuildChat = false; + + if (chatComponent.getSiblings().get(0).getChatStyle().getChatClickEvent().getValue().startsWith("/viewprofile")) { + startsWith = "/viewprofile"; + partyOrGuildChat = true; + } else { + ClickEvent chatClickEvent = chatComponent.getChatStyle().getChatClickEvent(); + if (chatClickEvent != null) { + if (chatClickEvent.getValue().startsWith("/socialoptions")) { + startsWith = "/socialoptions"; + } + } + } + + if (startsWith != null) { + String username = partyOrGuildChat ? + Utils.getNameFromChatComponent(chatComponent) : + chatComponent.getChatStyle().getChatClickEvent().getValue().substring(15); + if (NotEnoughUpdates.INSTANCE.config.misc.replaceSocialOptions1 == 1) { - chatComponent.setChatStyle(Utils.createClickStyle( + + ChatStyle pvClickStyle = Utils.createClickStyle( ClickEvent.Action.RUN_COMMAND, "/pv " + username, "" + EnumChatFormatting.YELLOW + "Click to open " + EnumChatFormatting.AQUA + EnumChatFormatting.BOLD + username + EnumChatFormatting.RESET + EnumChatFormatting.YELLOW + "'s profile in " + EnumChatFormatting.DARK_PURPLE + EnumChatFormatting.BOLD + "NEU's" + EnumChatFormatting.RESET + EnumChatFormatting.YELLOW + " profile viewer." - )); + ); + + if (partyOrGuildChat) { + chatComponent.getSiblings().get(0).setChatStyle(pvClickStyle); + } else { + chatComponent.setChatStyle(pvClickStyle); + } return chatComponent; } else if (NotEnoughUpdates.INSTANCE.config.misc.replaceSocialOptions1 == 2) { - chatComponent.setChatStyle(Utils.createClickStyle( + + ChatStyle ahClickStyle = Utils.createClickStyle( ClickEvent.Action.RUN_COMMAND, "/ah " + username, "" + EnumChatFormatting.YELLOW + "Click to open " + EnumChatFormatting.AQUA + EnumChatFormatting.BOLD + username + EnumChatFormatting.RESET + EnumChatFormatting.YELLOW + "'s /ah page" - )); + ); + + if (partyOrGuildChat) { + chatComponent.getSiblings().get(0).setChatStyle(ahClickStyle); + } else { + chatComponent.setChatStyle(ahClickStyle); + } return chatComponent; } } // wanted to add this for guild but guild uses uuid :sad: @@ -214,7 +255,7 @@ public class ChatListener { SlayerOverlay.unloadOverlayTimer = System.currentTimeMillis(); } else if (unformatted.startsWith("You consumed a Booster Cookie!")) { CookieWarning.resetNotification(); - } else if (unformatted.startsWith("QUICK MATHS! Solve:")) { + } else if (unformatted.startsWith("QUICK MATHS! Solve:") && NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { if (Math.random() < 0.2) { if (NotEnoughUpdates.INSTANCE.config.misc.calculationMode == 2) { ClientCommandHandler.instance.executeCommand( @@ -238,7 +279,7 @@ public class ChatListener { } missingRecipe.set(true); } - if (unformatted.startsWith("Sending to server") && neu.isOnSkyblock() && + if (unformatted.startsWith("Sending to server") && NotEnoughUpdates.INSTANCE.config.misc.streamerMode && e.message instanceof ChatComponentText) { String m = e.message.getFormattedText(); String m2 = StreamerMode.filterChat(e.message.getFormattedText()); @@ -254,5 +295,18 @@ public class ChatListener { unformatted.startsWith(" ") || unformatted.startsWith("✦") || unformatted.equals( " You've earned a Crystal Loot Bundle!")) OverlayManager.crystalHollowOverlay.message(unformatted); + + Matcher LvlMatcher = SKYBLOCK_LVL_MESSAGE.matcher(unformatted); + if (LvlMatcher.matches()) { + if (Integer.parseInt(LvlMatcher.group(1)) < NotEnoughUpdates.INSTANCE.config.misc.filterChatLevel && + NotEnoughUpdates.INSTANCE.config.misc.filterChatLevel != 0) { + e.setCanceled(true); + } + } + + if (unformatted.equals("You uncovered a treasure chest!") || + unformatted.equals("You have successfully picked the lock on this chest!") + || (unformatted.startsWith("You received +") && unformatted.endsWith(" Powder"))) + OverlayManager.powderGrindingOverlay.message(unformatted); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java index 3936ad74..d89e886f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java @@ -55,7 +55,6 @@ import java.awt.datatransfer.StringSelection; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -67,7 +66,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class ItemTooltipListener { - private static final String petToolTipRegex = + public static final String petToolTipRegex = "((Farming)|(Combat)|(Fishing)|(Mining)|(Foraging)|(Enchanting)|(Alchemy)) ((Mount)|(Pet)|(Morph)).*"; private final NotEnoughUpdates neu; private final Pattern xpLevelPattern = Pattern.compile("(.*) (\\xA7e(.*)\\xA76/\\xA7e(.*))"); @@ -382,6 +381,7 @@ public class ItemTooltipListener { } } if (hasEnchantments || hasAttributes) { + ArrayList<String> addedEnchants = new ArrayList<>(); for (String op : NotEnoughUpdates.INSTANCE.config.hidden.enchantColours) { List<String> colourOps = GuiEnchantColour.splitter.splitToList(op); String enchantName = GuiEnchantColour.getColourOpIndex(colourOps, 0); @@ -475,20 +475,22 @@ public class ItemTooltipListener { String extraMods = extraModifiersBuilder.toString(); if (!colourCode.equals("z")) { - line = line.replace("\u00A79" + enchantText, "\u00A7" + colourCode + extraMods + enchantText); - line = line.replace("\u00A7b" + enchantText, "\u00A7" + colourCode + extraMods + enchantText); - line = line.replace( - "\u00A79\u00A7d\u00A7l" + enchantText, - "\u00A7" + colourCode + extraMods + enchantText - ); - line = line.replace( - "\u00A7b\u00A7d\u00A7l" + enchantText, - "\u00A7" + colourCode + extraMods + enchantText - ); - line = line.replace( - "\u00A7l\u00A7d\u00A7l" + enchantText, - "\u00A7" + colourCode + extraMods + enchantText - ); + if (!addedEnchants.contains(enchantText)) { + line = line.replace("\u00A79" + enchantText, "\u00A7" + colourCode + extraMods + enchantText); + line = line.replace("\u00A7b" + enchantText, "\u00A7" + colourCode + extraMods + enchantText); + line = line.replace( + "\u00A79\u00A7d\u00A7l" + enchantText, + "\u00A7" + colourCode + extraMods + enchantText + ); + line = line.replace( + "\u00A7b\u00A7d\u00A7l" + enchantText, + "\u00A7" + colourCode + extraMods + enchantText + ); + line = line.replace( + "\u00A7l\u00A7d\u00A7l" + enchantText, + "\u00A7" + colourCode + extraMods + enchantText + ); + } } else { int offset = Minecraft.getMinecraft().fontRendererObj.getStringWidth(line.replaceAll( "\\u00A79" + enchantText + ".*", @@ -516,6 +518,7 @@ public class ItemTooltipListener { Utils.chromaString(enchantText, offset / 12f + index, true) ); } + addedEnchants.add(enchantText); } } } @@ -689,18 +692,6 @@ public class ItemTooltipListener { index++; } - for (int i = newTooltip.size() - 1; i >= 0; i--) { - String line = Utils.cleanColour(newTooltip.get(i)); - for (int i1 = 0; i1 < Utils.rarityArr.length; i1++) { - if (line.equals(Utils.rarityArr[i1])) { - if (i - 2 < 0) { - break; - } - newTooltip.addAll(i - 1, petToolTipXPExtend(event)); - break; - } - } - } pressedShiftLast = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT); pressedArrowLast = Keyboard.isKeyDown(Keyboard.KEY_LEFT) || Keyboard.isKeyDown(Keyboard.KEY_RIGHT); @@ -718,104 +709,45 @@ public class ItemTooltipListener { } } - private List<String> petToolTipXPExtend(ItemTooltipEvent event) { - List<String> tooltipText = new ArrayList<>(); - if (NotEnoughUpdates.INSTANCE.config.tooltipTweaks.petExtendExp) { - if (event.itemStack.getTagCompound().hasKey("DisablePetExp")) { - if (event.itemStack.getTagCompound().getBoolean("DisablePetExp")) { - return tooltipText; + private void petToolTipXPExtendPetMenu(ItemTooltipEvent event) { + if (!NotEnoughUpdates.INSTANCE.config.tooltipTweaks.petExtendExp) return; + //7 is just a random number i chose, prob no pets with less lines than 7 + if (event.toolTip.size() < 7) return; + if (event.itemStack.getTagCompound().hasKey("NEUHIDEPETTOOLTIP")) return; + if (Utils.cleanColour(event.toolTip.get(1)).matches(petToolTipRegex)) { + GuiProfileViewer.PetLevel petLevel; + + int xpLine = -1; + for (int i = event.toolTip.size() - 1; i >= 0; i--) { + Matcher matcher = xpLevelPattern.matcher(event.toolTip.get(i)); + if (matcher.matches()) { + xpLine = i; + event.toolTip.set(xpLine, matcher.group(1)); + break; + } else if (event.toolTip.get(i).matches("MAX LEVEL")) { + return; } } - //7 is just a random number i chose, prob no pets with less lines than 7 - if (event.toolTip.size() > 7) { - if (Utils.cleanColour(event.toolTip.get(1)).matches(petToolTipRegex)) { - - GuiProfileViewer.PetLevel petlevel = null; - - //this is the item itself - NBTTagCompound tag = event.itemStack.getTagCompound(); - if (tag.hasKey("ExtraAttributes")) { - if (tag.getCompoundTag("ExtraAttributes").hasKey("petInfo")) { - JsonObject petInfo = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(tag - .getCompoundTag("ExtraAttributes") - .getString("petInfo"), JsonObject.class); - if (petInfo.has("exp") && petInfo.get("exp").isJsonPrimitive()) { - JsonPrimitive exp = petInfo.getAsJsonPrimitive("exp"); - String petName = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(event.itemStack); - //Utils.getRarityFromInt(Utils.checkItemTypePet(event.toolTip))).getAsInt(); - petlevel = GuiProfileViewer.getPetLevel( - petName, - Utils.getRarityFromInt(Utils.checkItemTypePet(event.toolTip)), - exp.getAsLong() - ); - } - } - } - if (petlevel != null) { - tooltipText.add(""); - if (petlevel.totalXp > petlevel.maxXP) { - tooltipText.add(EnumChatFormatting.AQUA + "" + EnumChatFormatting.BOLD + "MAX LEVEL"); - } else { - tooltipText.add( - EnumChatFormatting.GRAY + "Progress to Level " + (int) Math.floor(petlevel.level + 1) + ": " + - EnumChatFormatting.YELLOW + Utils.round(petlevel.levelPercentage * 100, 1) + "%"); - int levelpercentage = Math.round(petlevel.levelPercentage * 20); - tooltipText.add( - EnumChatFormatting.DARK_GREEN + String.join("", Collections.nCopies(levelpercentage, "-")) + - EnumChatFormatting.WHITE + String.join("", Collections.nCopies(20 - levelpercentage, "-"))); - tooltipText.add( - EnumChatFormatting.GRAY + "EXP: " + EnumChatFormatting.YELLOW + myFormatter.format(petlevel.levelXp) + - EnumChatFormatting.GOLD + "/" + EnumChatFormatting.YELLOW + - myFormatter.format(petlevel.currentLevelRequirement) + " EXP"); - } - } - } + PetInfoOverlay.Pet pet = PetInfoOverlay.getPetFromStack( + event.itemStack.getTagCompound() + ); + if (pet == null) { + return; } - } - return tooltipText; - } + petLevel = pet.petLevel; - private void petToolTipXPExtendPetMenu(ItemTooltipEvent event) { - if (NotEnoughUpdates.INSTANCE.config.tooltipTweaks.petExtendExp) { - //7 is just a random number i chose, prob no pets with less lines than 7 - if (event.toolTip.size() > 7) { - if (Utils.cleanColour(event.toolTip.get(1)).matches(petToolTipRegex)) { - GuiProfileViewer.PetLevel petLevel; - - int xpLine = -1; - for (int i = event.toolTip.size() - 1; i >= 0; i--) { - Matcher matcher = xpLevelPattern.matcher(event.toolTip.get(i)); - if (matcher.matches()) { - xpLine = i; - event.toolTip.set(xpLine, matcher.group(1)); - break; - } else if (event.toolTip.get(i).matches("MAX LEVEL")) { - return; - } - } - - PetInfoOverlay.Pet pet = PetInfoOverlay.getPetFromStack( - event.itemStack.getTagCompound() - ); - if (pet == null) { - return; - } - petLevel = pet.petLevel; - - if (petLevel == null || xpLine == -1) { - return; - } + if (petLevel == null || xpLine == -1) { + return; + } - event.toolTip.add( - xpLine + 1, - EnumChatFormatting.GRAY + "EXP: " + EnumChatFormatting.YELLOW + myFormatter.format(petLevel.levelXp) + - EnumChatFormatting.GOLD + "/" + EnumChatFormatting.YELLOW + - myFormatter.format(petLevel.currentLevelRequirement) - ); + event.toolTip.add( + xpLine + 1, + EnumChatFormatting.GRAY + "EXP: " + EnumChatFormatting.YELLOW + myFormatter.format(petLevel.levelXp) + + EnumChatFormatting.GOLD + "/" + EnumChatFormatting.YELLOW + + myFormatter.format(petLevel.currentLevelRequirement) + ); - } - } } } @@ -911,6 +843,7 @@ public class ItemTooltipListener { MiscUtils.copyToClipboard(NotEnoughUpdates.INSTANCE.manager.getSkullValueForItem(event.itemStack)); } + event.toolTip.add( EnumChatFormatting.AQUA + "Internal Name: " + EnumChatFormatting.GRAY + internal + EnumChatFormatting.GOLD + " [K]"); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java index bbbb9049..fdae53ea 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java @@ -27,6 +27,8 @@ import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent; import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; import io.github.moulberry.notenoughupdates.util.Calculator; import io.github.moulberry.notenoughupdates.util.Constants; +import io.github.moulberry.notenoughupdates.util.ItemResolutionQuery; +import io.github.moulberry.notenoughupdates.util.ItemUtils; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.item.ItemStack; import net.minecraftforge.event.entity.player.ItemTooltipEvent; @@ -135,14 +137,18 @@ public class ItemTooltipRngListener { event.toolTip.addAll(newToolTip); } - private String getFormatCoinsPer(ItemStack stack, int needed, int multiplier, String name) { - String internalName = neu.manager.getInternalNameForItem(stack); - double bin = neu.manager.auctionManager.getBazaarOrBin(internalName); - if (bin <= 0) return null; + private String getFormatCoinsPer(ItemStack stack, int needed, int multiplier, String label) { + String internalName = neu.manager.createItemResolutionQuery().withItemStack(stack).resolveInternalName(); + double profit = neu.manager.auctionManager.getBazaarOrBin(internalName); + if (profit <= 0) return null; - double coinsPer = (bin / needed) * multiplier; + //ask hypixel nicely to release a 'chest price api' with 4 dimensions for us. the 4 dimensions needed are: item name, floor, normal/mm, s/s+ +// double chestPrice = grabChestPrice(stack, internalName); +// profit -= chestPrice; + + double coinsPer = (profit / needed) * multiplier; String format = StringUtils.shortNumberFormat(coinsPer); - return "§7Coins per " + name + ": §6" + format + " coins"; + return "§7Coins per " + label + ": §6" + format + " coins"; } private void fractionDisplay(List<String> newToolTip, String line) { @@ -256,10 +262,12 @@ public class ItemTooltipRngListener { Map<String, Integer> runsData; String labelPlural; String labelSingular; + String repoCategory; if (openChestName.contains("Catacombs")) { runsData = dungeonData; labelPlural = "Runs"; labelSingular = "Run"; + repoCategory = "catacombs"; } else { // Slayer Matcher matcher = SLAYER_INVENTORY_TITLE_PATTERN.matcher(openChestName); if (!matcher.matches()) { @@ -271,6 +279,12 @@ public class ItemTooltipRngListener { runsData = slayerData.get(slayerName); labelPlural = "Bosses"; labelSingular = "Boss"; + repoCategory = "slayer"; + } + + int repoScore = getRepoScore(stack, repoCategory); + if (repoScore != -1) { + needed = repoScore; } handleArrowKeys(runsData); @@ -282,7 +296,7 @@ public class ItemTooltipRngListener { String name = (String) runsData.keySet().toArray()[currentSelected]; int gainPerRun = runsData.get(name); - int runsNeeded = needed / gainPerRun; + int runsNeeded = (int) Math.floor((double) needed / (double) gainPerRun); int runsHaving = having / gainPerRun; String runsNeededFormat = GuiProfileViewer.numberFormat.format(runsNeeded); String runsHavingFormat = GuiProfileViewer.numberFormat.format(runsHaving); @@ -309,6 +323,49 @@ public class ItemTooltipRngListener { } } + private int getRepoScore(ItemStack stack, String repoCategory) { + ItemResolutionQuery query = + NotEnoughUpdates.INSTANCE.manager.createItemResolutionQuery().withItemStack(stack).withCurrentGuiContext(); + String internalName = query.resolveInternalName(); + + JsonObject jsonObject = Constants.RNGSCORE; + if (jsonObject == null) { + Utils.showOutdatedRepoNotification(); + return -1; + } + + String repoType = grabRepoType(stack); + if (!jsonObject.has(repoCategory)) return -1; + + JsonObject category = jsonObject.get(repoCategory).getAsJsonObject(); + if (!category.has(repoType)) return -1; + + JsonObject typeObject = category.get(repoType).getAsJsonObject(); + if (!typeObject.has(internalName)) return -1; + + return typeObject.get(internalName).getAsInt(); + } + + // Determines the floor or the slayer type from where the item can be obtained. E.g. F7, M3, Revenant Horror or Sven Packmaster + private String grabRepoType(ItemStack stack) { + String openChestName = Utils.getOpenChestName(); + if (openChestName.contains("Catacombs")) { + if (openChestName.equals("Catacombs RNG Meter")) { + List<String> list = ItemUtils.getLore(stack); + String line = list.get(4); + return line.substring(26, 28); + } else { + // supporting more pages (f7/m7) + if (openChestName.contains("(")) { + return openChestName.substring(17, 19); + } + return openChestName.substring(11, 13); + } + } else { + return openChestName.substring(0, openChestName.length() - 9); + } + } + private void handleArrowKeys(Map<String, Integer> runsData) { boolean left = Keyboard.isKeyDown(Keyboard.KEY_LEFT); boolean right = Keyboard.isKeyDown(Keyboard.KEY_RIGHT); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java index 305135fc..e202b828 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java @@ -34,6 +34,7 @@ import io.github.moulberry.notenoughupdates.miscfeatures.ItemCustomizeManager; import io.github.moulberry.notenoughupdates.miscfeatures.NPCRetexturing; import io.github.moulberry.notenoughupdates.miscgui.AccessoryBagOverlay; import io.github.moulberry.notenoughupdates.miscgui.GuiCustomEnchant; +import io.github.moulberry.notenoughupdates.miscgui.hex.GuiCustomHex; import io.github.moulberry.notenoughupdates.miscgui.StorageOverlay; import io.github.moulberry.notenoughupdates.overlays.OverlayManager; import io.github.moulberry.notenoughupdates.overlays.TextOverlay; @@ -144,6 +145,9 @@ public class NEUEventListener { if (GuiCustomEnchant.getInstance().shouldOverride(containerName)) { GuiCustomEnchant.getInstance().tick(); } + if (GuiCustomHex.getInstance().shouldOverride(containerName)) { + GuiCustomHex.getInstance().tick(containerName); + } } //MiningOverlay and TimersOverlay need real tick speed diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java index 166e46d0..2abb2ee8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java @@ -50,14 +50,17 @@ import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe; import io.github.moulberry.notenoughupdates.miscgui.StorageOverlay; import io.github.moulberry.notenoughupdates.miscgui.TradeWindow; import io.github.moulberry.notenoughupdates.miscgui.TrophyRewardOverlay; +import io.github.moulberry.notenoughupdates.miscgui.hex.GuiCustomHex; import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer; import io.github.moulberry.notenoughupdates.options.NEUConfig; import io.github.moulberry.notenoughupdates.overlays.AuctionSearchOverlay; import io.github.moulberry.notenoughupdates.overlays.BazaarSearchOverlay; +import io.github.moulberry.notenoughupdates.overlays.EquipmentOverlay; import io.github.moulberry.notenoughupdates.overlays.OverlayManager; import io.github.moulberry.notenoughupdates.overlays.RancherBootOverlay; import io.github.moulberry.notenoughupdates.overlays.TextOverlay; import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; +import io.github.moulberry.notenoughupdates.util.ItemUtils; import io.github.moulberry.notenoughupdates.util.NotificationHandler; import io.github.moulberry.notenoughupdates.util.RequestFocusListener; import io.github.moulberry.notenoughupdates.util.SBInfo; @@ -406,7 +409,7 @@ public class RenderListener { GL11.glTranslatef(0, 0, 10); } if (hoverInv) { - renderDungeonChestOverlay(event.gui); + renderDungKuudraChestOverlay(event.gui); if (NotEnoughUpdates.INSTANCE.config.accessoryBag.enableOverlay) { AccessoryBagOverlay.renderOverlay(); } @@ -444,12 +447,19 @@ public class RenderListener { containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); } + if (GuiCustomHex.getInstance().shouldOverride(containerName)) { + GuiCustomHex.getInstance().render(event.renderPartialTicks, containerName); + event.setCanceled(true); + return; + } + if (GuiCustomEnchant.getInstance().shouldOverride(containerName)) { GuiCustomEnchant.getInstance().render(event.renderPartialTicks); event.setCanceled(true); return; } + boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName); boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName); boolean customAhActive = @@ -534,12 +544,12 @@ public class RenderListener { x -= 68 - 200; } } - if (NEUOverlay.isRenderingArmorHud()) { + if (EquipmentOverlay.isRenderingArmorHud()) { if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop && y < guiTop + 84) { x -= 25; } } - if (NEUOverlay.isRenderingPetHud()) { + if (EquipmentOverlay.isRenderingPetHud()) { if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop + 60 && y < guiTop + 120) { x -= 25; } @@ -594,6 +604,7 @@ public class RenderListener { ContainerChest cc = (ContainerChest) eventGui.inventorySlots; containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); + if (GuiCustomHex.getInstance().shouldOverride(containerName)) return; if (GuiCustomEnchant.getInstance().shouldOverride(containerName)) return; } @@ -615,7 +626,7 @@ public class RenderListener { } if (NotificationHandler.shouldRenderOverlay(event.gui) && neu.isOnSkyblock() && !hoverInv) { - renderDungeonChestOverlay(event.gui); + renderDungKuudraChestOverlay(event.gui); if (NotEnoughUpdates.INSTANCE.config.accessoryBag.enableOverlay) { AccessoryBagOverlay.renderOverlay(); } @@ -661,12 +672,12 @@ public class RenderListener { x -= 68 - 200; } } - if (NEUOverlay.isRenderingArmorHud()) { + if (EquipmentOverlay.isRenderingArmorHud()) { if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop && y < guiTop + 84) { x -= 25; } } - if (NEUOverlay.isRenderingPetHud()) { + if (EquipmentOverlay.isRenderingPetHud()) { if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop + 60 && y < guiTop + 120) { x -= 25; } @@ -692,7 +703,7 @@ public class RenderListener { buttonHovered = button; } - if (currentTime - buttonHoveredMillis > 600) { + if (currentTime - buttonHoveredMillis > NotEnoughUpdates.INSTANCE.config.inventoryButtons.tooltipDelay) { String command = button.command.trim(); if (!command.startsWith("/")) { command = "/" + command; @@ -724,7 +735,7 @@ public class RenderListener { } } - private void renderDungeonChestOverlay(GuiScreen gui) { + private void renderDungKuudraChestOverlay(GuiScreen gui) { if (NotEnoughUpdates.INSTANCE.config.dungeons.profitDisplayLoc == 3) return; if (gui instanceof GuiChest && NotEnoughUpdates.INSTANCE.config.dungeons.profitDisplayLoc != 2) { try { @@ -761,7 +772,9 @@ public class RenderListener { HashMap<String, Double> itemValues = new HashMap<>(); for (int i = 0; i < 5; i++) { ItemStack item = lower.getStackInSlot(11 + i); - String internal = neu.manager.getInternalNameForItem(item); + if (ItemUtils.isSoulbound(item)) continue; + + String internal = neu.manager.createItemResolutionQuery().withItemStack(item).resolveInternalName(); String displayName = item.getDisplayName(); Matcher matcher = ESSENCE_PATTERN.matcher(displayName); if (neu.config.dungeons.useEssenceCostFromBazaar && matcher.matches()) { @@ -782,12 +795,16 @@ public class RenderListener { JsonObject bazaarInfo = neu.manager.auctionManager.getBazaarInfo(internal); if (bazaarInfo != null && bazaarInfo.has("curr_sell")) { bazaarPrice = bazaarInfo.get("curr_sell").getAsFloat(); + } else if (bazaarInfo != null) { + bazaarPrice = 0; } if (bazaarPrice < 5000000 && internal.equals("RECOMBOBULATOR_3000")) bazaarPrice = 5000000; double worth = -1; - if (bazaarPrice > 0) { + boolean isOnBz = false; + if (bazaarPrice >= 0) { worth = bazaarPrice; + isOnBz = true; } else { switch (NotEnoughUpdates.INSTANCE.config.dungeons.profitType) { case 1: @@ -825,7 +842,7 @@ public class RenderListener { } } - if (worth > 0 && totalValue >= 0) { + if ((worth >= 0 || isOnBz) && totalValue >= 0) { totalValue += worth; String display = item.getDisplayName(); @@ -1047,12 +1064,18 @@ public class RenderListener { } } + if (GuiCustomHex.getInstance().shouldOverride(containerName) && + GuiCustomHex.getInstance().mouseInput(mouseX, mouseY)) { + event.setCanceled(true); + return; + } if (GuiCustomEnchant.getInstance().shouldOverride(containerName) && GuiCustomEnchant.getInstance().mouseInput(mouseX, mouseY)) { event.setCanceled(true); return; } + boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName); boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName); boolean customAhActive = @@ -1126,12 +1149,12 @@ public class RenderListener { x -= 68 - 200; } } - if (NEUOverlay.isRenderingArmorHud()) { + if (EquipmentOverlay.isRenderingArmorHud()) { if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop && y < guiTop + 84) { x -= 25; } } - if (NEUOverlay.isRenderingPetHud()) { + if (EquipmentOverlay.isRenderingPetHud()) { if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop + 60 && y < guiTop + 120) { x -= 25; } @@ -1216,6 +1239,7 @@ public class RenderListener { if (stack.getTagCompound().getCompoundTag("display").hasKey("Lore", 9)) { int stars = Utils.getNumberOfStars(stack); if (stars == 0) continue; + String starsStr = "" + stars; NBTTagList lore = stack.getTagCompound().getCompoundTag("display").getTagList("Lore", 8); int costIndex = 10000; @@ -1228,38 +1252,39 @@ public class RenderListener { if (entry.equals("§7Cost")) { costIndex = j; } + if (j > costIndex) { entry = entry.trim(); - int index = entry.lastIndexOf('x'); - String item, amountString; - if (index < 0) { - item = entry.trim() + " x1"; - amountString = "x1"; - } else { - amountString = entry.substring(index); - item = entry.substring(0, index).trim(); + + int countIndex = entry.lastIndexOf(" §8x"); + + String upgradeName = entry; + String amount = "1"; + if (countIndex != -1) { + upgradeName = entry.substring(0, countIndex); + // +4 to account for " §8x" + amount = entry.substring(countIndex + 4); } - item = item.substring(0, item.length() - 3); - int amount = Integer.parseInt(amountString.trim().replace("x", "").replace(",", "")); - if (item.endsWith("Essence")) { - int index2 = entry.indexOf("Essence"); - String type = item.substring(0, index2).trim().substring(2); - newEntry.add("type", new JsonPrimitive(type)); - newEntry.add(String.valueOf(stars), new JsonPrimitive(amount)); + + if (upgradeName.endsWith(" Essence")) { + // First 2 chars are control code + // [EssenceCount, EssenceType, "Essence"] + String[] upgradeNameSplit = upgradeName.substring(2).split(" "); + newEntry.addProperty("type", upgradeNameSplit[1]); + newEntry.addProperty(starsStr, Integer.parseInt(upgradeNameSplit[0].replace(",", ""))); } else { - String itemString = item + " §8x" + amount; if (!newEntry.has("items")) { newEntry.add("items", new JsonObject()); } - if (!newEntry.get("items").getAsJsonObject().has(String.valueOf(stars))) { - newEntry.get("items").getAsJsonObject().add(String.valueOf(stars), new JsonArray()); + if (!newEntry.get("items").getAsJsonObject().has(starsStr)) { + newEntry.get("items").getAsJsonObject().add(starsStr, new JsonArray()); } newEntry .get("items") .getAsJsonObject() - .get(String.valueOf(stars)) + .get(starsStr) .getAsJsonArray() - .add(new JsonPrimitive(itemString)); + .add(new JsonPrimitive(upgradeName + (upgradeName.contains("Coins") ? "" : (" §8x" + amount)))); } } } @@ -1516,12 +1541,19 @@ public class RenderListener { .getUnformattedText(); } + if (GuiCustomHex.getInstance().shouldOverride(containerName) && + GuiCustomHex.getInstance().keyboardInput()) { + event.setCanceled(true); + return; + } + if (GuiCustomEnchant.getInstance().shouldOverride(containerName) && GuiCustomEnchant.getInstance().keyboardInput()) { event.setCanceled(true); return; } + boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName); boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName); boolean customAhActive = diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinSkyclientCosmetics.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/WorldListener.java index 32c9f418..365b96c5 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinSkyclientCosmetics.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/WorldListener.java @@ -17,23 +17,25 @@ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. */ -package io.github.moulberry.notenoughupdates.mixins; +package io.github.moulberry.notenoughupdates.listener; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.overlays.OverlayManager; import net.minecraftforge.event.world.WorldEvent; -import org.spongepowered.asm.mixin.Dynamic; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Pseudo; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -@Pseudo -@Mixin(targets = "co.skyclient.scc.SkyclientCosmetics") -public class MixinSkyclientCosmetics { +public class WorldListener { - @Dynamic - @Inject(method = "onWorldLoad", at = @At("HEAD"), cancellable = true, remap = false) - public void onWorldLoad(WorldEvent.Load event, CallbackInfo ci) { - ci.cancel(); + private final NotEnoughUpdates neu; + + public WorldListener(NotEnoughUpdates neu) { + this.neu = neu; + } + + @SubscribeEvent + public void onWorldLoad(WorldEvent.Load e) { + if (neu.config.mining.powderGrindingTrackerResetMode == 0) + OverlayManager.powderGrindingOverlay.reset(); } + } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AbiphoneWarning.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AbiphoneWarning.java index 254c891a..67ac4f4c 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AbiphoneWarning.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AbiphoneWarning.java @@ -23,6 +23,7 @@ import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.GuiElement; import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; import io.github.moulberry.notenoughupdates.core.util.render.TextRenderUtils; +import io.github.moulberry.notenoughupdates.events.SlotClickEvent; import io.github.moulberry.notenoughupdates.util.ItemUtils; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; @@ -33,6 +34,7 @@ import net.minecraft.client.renderer.GlStateManager; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumChatFormatting; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @@ -68,29 +70,28 @@ public class AbiphoneWarning extends GuiElement { return shouldPerformCheck() && showWarning; } - public boolean onMouseClick(Slot slotIn, int slotId, int clickedButton, int clickType) { - if (!shouldPerformCheck()) return false; - if (!NotEnoughUpdates.INSTANCE.config.misc.abiphoneWarning) return false; - if (slotId == -999) return false; - if (clickedButton == 0) return false; + @SubscribeEvent + public void onMouseClick(SlotClickEvent event) { + if (!shouldPerformCheck()) return; + if (!NotEnoughUpdates.INSTANCE.config.misc.abiphoneWarning) return; + if (event.slotId == -999) return; + if (event.clickedButton == 0) return; GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; - ItemStack clickedContact = chest.inventorySlots.getSlot(slotId).getStack(); - if (clickedContact == null) return false; + ItemStack clickedContact = chest.inventorySlots.getSlot(event.slotId).getStack(); + if (clickedContact == null) return; List<String> list = ItemUtils.getLore(clickedContact); - if (list.isEmpty()) return false; + if (list.isEmpty()) return; String last = list.get(list.size() - 1); if (last.contains("Right-click to remove contact!")) { showWarning = true; contactName = clickedContact.getDisplayName(); - contactSlot = slotId; - return true; + contactSlot = event.slotId; + event.setCanceled(true); } - - return false; } public void overrideIsMouseOverSlot(Slot slot, int mouseX, int mouseY, CallbackInfoReturnable<Boolean> cir) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AntiCoopAdd.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AntiCoopAdd.java new file mode 100644 index 00000000..70ac4489 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AntiCoopAdd.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.miscfeatures; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.events.SlotClickEvent; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.event.ClickEvent; +import net.minecraft.event.HoverEvent; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +public class AntiCoopAdd { + + @SubscribeEvent + public void onMouseClick(SlotClickEvent event) { + if (!NotEnoughUpdates.INSTANCE.config.misc.coopWarning) return; + if (event.slotId == -999) return; + if (!Utils.getOpenChestName().contains("Profile")) return; + + ItemStack stack = event.slot.getStack(); + if (stack == null) return; + if (stack.getItem() == Items.diamond && stack.getDisplayName() != null && stack.getDisplayName().contains( + "Co-op Request")) { + String ign = Utils.getOpenChestName().split("'s Profile")[0]; + ChatComponentText storageMessage = new ChatComponentText( + EnumChatFormatting.YELLOW + "[NEU] " + EnumChatFormatting.YELLOW + + "You just clicked on the Co-op add button. If you want to coop add this person, click this chat message"); + storageMessage.setChatStyle(Utils.createClickStyle(ClickEvent.Action.RUN_COMMAND, "/coopadd " + ign)); + storageMessage.setChatStyle(storageMessage.getChatStyle().setChatHoverEvent( + new HoverEvent( + HoverEvent.Action.SHOW_TEXT, + new ChatComponentText(EnumChatFormatting.YELLOW + "Click to add " + ign + " to your coop") + ))); + ChatComponentText storageChatMessage = new ChatComponentText(""); + storageChatMessage.appendSibling(storageMessage); + Minecraft.getMinecraft().thePlayer.addChatMessage(storageChatMessage); + event.setCanceled(true); + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionBINWarning.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionBINWarning.java index 3bd674dd..75813700 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionBINWarning.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionBINWarning.java @@ -24,6 +24,7 @@ import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.GuiElement; import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; import io.github.moulberry.notenoughupdates.core.util.render.TextRenderUtils; +import io.github.moulberry.notenoughupdates.events.SlotClickEvent; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; @@ -33,6 +34,7 @@ import net.minecraft.client.renderer.GlStateManager; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumChatFormatting; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @@ -79,75 +81,73 @@ public class AuctionBINWarning extends GuiElement { return shouldPerformCheck() && showWarning; } - public boolean onMouseClick(Slot slotIn, int slotId, int clickedButton, int clickType) { - if (!shouldPerformCheck()) return false; + @SubscribeEvent + public void onMouseClick(SlotClickEvent event) { + if (!shouldPerformCheck()) return; - if (slotId == 29) { - GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; + if (event.slotId != 29) { + return; + } - sellingPrice = -1; + sellingPrice = -1; - ItemStack priceStack = chest.inventorySlots.getSlot(31).getStack(); - if (priceStack != null) { - String displayName = priceStack.getDisplayName(); - Matcher priceMatcher = ITEM_PRICE_REGEX.matcher(displayName); + ItemStack priceStack = event.guiContainer.inventorySlots.getSlot(31).getStack(); + if (priceStack != null) { + String displayName = priceStack.getDisplayName(); + Matcher priceMatcher = ITEM_PRICE_REGEX.matcher(displayName); - if (priceMatcher.matches()) { - try { - sellingPrice = Long.parseLong(priceMatcher.group(1).replace(",", "")); - } catch (NumberFormatException ignored) { - } + if (priceMatcher.matches()) { + try { + sellingPrice = Long.parseLong(priceMatcher.group(1).replace(",", "")); + } catch (NumberFormatException ignored) { } } + } - ItemStack sellStack = chest.inventorySlots.getSlot(13).getStack(); - String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(sellStack); - sellStackAmount = sellStack.stackSize; + ItemStack sellStack = event.guiContainer.inventorySlots.getSlot(13).getStack(); + String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(sellStack); + sellStackAmount = sellStack.stackSize; - if (internalname == null) { - return false; - } + if (internalname == null) { + return; + } - JsonObject itemInfo = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(internalname); - if (itemInfo == null || !itemInfo.has("displayname")) { - sellingName = internalname; - } else { - sellingName = itemInfo.get("displayname").getAsString(); - } + JsonObject itemInfo = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(internalname); + if (itemInfo == null || !itemInfo.has("displayname")) { + sellingName = internalname; + } else { + sellingName = itemInfo.get("displayname").getAsString(); + } - sellingTooltip = sellStack.getTooltip( - Minecraft.getMinecraft().thePlayer, - Minecraft.getMinecraft().gameSettings.advancedItemTooltips - ); + sellingTooltip = sellStack.getTooltip( + Minecraft.getMinecraft().thePlayer, + Minecraft.getMinecraft().gameSettings.advancedItemTooltips + ); - lowestPrice = NotEnoughUpdates.INSTANCE.manager.auctionManager.getLowestBin(internalname); - if (lowestPrice <= 0) { - lowestPrice = (int) NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAvgBin(internalname); - } + lowestPrice = NotEnoughUpdates.INSTANCE.manager.auctionManager.getLowestBin(internalname); + if (lowestPrice <= 0) { + lowestPrice = (int) NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAvgBin(internalname); + } - float undercutFactor = 1 - NotEnoughUpdates.INSTANCE.config.ahTweaks.warningThreshold / 100; - if (undercutFactor < 0) undercutFactor = 0; - if (undercutFactor > 1) undercutFactor = 1; - float overcutFactor = 1 - NotEnoughUpdates.INSTANCE.config.ahTweaks.overcutWarningThreshold / 100; - if (overcutFactor < 0) overcutFactor = 0; - if (overcutFactor > 1) overcutFactor = 1; + float undercutFactor = 1 - NotEnoughUpdates.INSTANCE.config.ahTweaks.warningThreshold / 100; + if (undercutFactor < 0) undercutFactor = 0; + if (undercutFactor > 1) undercutFactor = 1; + float overcutFactor = 1 - NotEnoughUpdates.INSTANCE.config.ahTweaks.overcutWarningThreshold / 100; + if (overcutFactor < 0) overcutFactor = 0; + if (overcutFactor > 1) overcutFactor = 1; - if (lowestPrice == -1) { - return false; - } - if (NotEnoughUpdates.INSTANCE.config.ahTweaks.underCutWarning && - (sellingPrice > 0 && lowestPrice > 0 && sellingPrice < sellStackAmount * lowestPrice * undercutFactor)) { - showWarning = true; - return true; - } else if (NotEnoughUpdates.INSTANCE.config.ahTweaks.overCutWarning && - (sellingPrice > 0 && lowestPrice > 0 && sellingPrice > sellStackAmount * lowestPrice * (overcutFactor + 1))) { - showWarning = true; - return true; - } else { - return false; - } + if (lowestPrice == -1) { + return; + } + if (NotEnoughUpdates.INSTANCE.config.ahTweaks.underCutWarning && + (sellingPrice > 0 && lowestPrice > 0 && sellingPrice < sellStackAmount * lowestPrice * undercutFactor)) { + showWarning = true; + event.setCanceled(true); + } else if (NotEnoughUpdates.INSTANCE.config.ahTweaks.overCutWarning && + (sellingPrice > 0 && lowestPrice > 0 && sellingPrice > sellStackAmount * lowestPrice * (overcutFactor + 1))) { + showWarning = true; + event.setCanceled(true); } - return false; } public void overrideIsMouseOverSlot(Slot slot, int mouseX, int mouseY, CallbackInfoReturnable<Boolean> cir) { @@ -234,7 +234,7 @@ public class AuctionBINWarning extends GuiElement { ); TextRenderUtils.drawStringCenteredScaledMaxWidth( "\u00a76" + sellingPriceStr + "\u00a7r coins?" + - (lowestPrice > 0 ? "(\u00a7" + (isALoss ? "c-" : "a+") + buyPercentage + "%\u00a7r)" : ""), + (lowestPrice > 0 ? "(\u00a7" + (isALoss ? "c-" : "a+") + (buyPercentage >= 100 ? buyPercentage - 100 : buyPercentage) + "%\u00a7r)" : ""), Minecraft.getMinecraft().fontRendererObj, width / 2, height / 2 - 45 + 59, diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionSortModeWarning.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionSortModeWarning.java index 8ac0151a..ed05ee79 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionSortModeWarning.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionSortModeWarning.java @@ -45,50 +45,46 @@ public class AuctionSortModeWarning { } public void onPostGuiRender() { - if (isAuctionBrowser()) { - GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; - - ItemStack stack = chest.inventorySlots.getSlot(50).getStack(); - - if (stack != null) { - List<String> tooltip = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false); - - String selectedSort = null; - for (String line : tooltip) { - if (line.startsWith("\u00a75\u00a7o\u00a7b\u25B6 ")) { - selectedSort = Utils.cleanColour(line.substring("\u00a75\u00a7o\u00a7b\u25B6 ".length())); - } - } - - if (selectedSort != null) { - if (!selectedSort.trim().equals("Lowest Price")) { - GlStateManager.disableLighting(); - GlStateManager.pushMatrix(); - GlStateManager.translate(0, 0, 500); - - String selectedColour = "\u00a7e"; - - if (selectedSort.trim().equals("Highest Price")) { - selectedColour = "\u00a7c"; - } - - String warningText = "\u00a7aSort: " + selectedColour + selectedSort; - int warningLength = Minecraft.getMinecraft().fontRendererObj.getStringWidth(warningText); - - int centerX = - ((AccessorGuiContainer) chest).getGuiLeft() + ((AccessorGuiContainer) chest).getXSize() / 2 + 9; - int centerY = ((AccessorGuiContainer) chest).getGuiTop() + 26; - - RenderUtils.drawFloatingRectDark(centerX - warningLength / 2 - 4, centerY - 6, - warningLength + 8, 12, false - ); - TextRenderUtils.drawStringCenteredScaledMaxWidth(warningText, Minecraft.getMinecraft().fontRendererObj, - centerX, centerY, true, chest.width / 2, 0xffffffff - ); - GlStateManager.popMatrix(); - } - } + if (!isAuctionBrowser()) return; + GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; + + ItemStack stack = chest.inventorySlots.getSlot(50).getStack(); + + if (stack == null) return; + List<String> tooltip = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false); + + String selectedSort = null; + for (String line : tooltip) { + if (line.startsWith("\u00a75\u00a7o\u00a7b\u25B6 ")) { + selectedSort = Utils.cleanColour(line.substring("\u00a75\u00a7o\u00a7b\u25B6 ".length())); } } + + if (selectedSort == null) return; + if (selectedSort.trim().equals("Lowest Price")) return; + GlStateManager.disableLighting(); + GlStateManager.pushMatrix(); + GlStateManager.translate(0, 0, 500); + + String selectedColour = "\u00a7e"; + + if (selectedSort.trim().equals("Highest Price")) { + selectedColour = "\u00a7c"; + } + + String warningText = "\u00a7aSort: " + selectedColour + selectedSort; + int warningLength = Minecraft.getMinecraft().fontRendererObj.getStringWidth(warningText); + + int centerX = + ((AccessorGuiContainer) chest).getGuiLeft() + ((AccessorGuiContainer) chest).getXSize() / 2 + 9; + int centerY = ((AccessorGuiContainer) chest).getGuiTop() + 26; + + RenderUtils.drawFloatingRectDark(centerX - warningLength / 2 - 4, centerY - 6, + warningLength + 8, 12, false + ); + TextRenderUtils.drawStringCenteredScaledMaxWidth(warningText, Minecraft.getMinecraft().fontRendererObj, + centerX, centerY, true, chest.width / 2, 0xffffffff + ); + GlStateManager.popMatrix(); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BazaarSacksProfit.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BazaarSacksProfit.java deleted file mode 100644 index 7007f39b..00000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BazaarSacksProfit.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2022 NotEnoughUpdates contributors - * - * This file is part of NotEnoughUpdates. - * - * NotEnoughUpdates is free software: you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation, either - * version 3 of the License, or (at your option) any later version. - * - * NotEnoughUpdates 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. - */ - -package io.github.moulberry.notenoughupdates.miscfeatures; - -import com.google.gson.JsonObject; -import io.github.moulberry.notenoughupdates.NotEnoughUpdates; -import io.github.moulberry.notenoughupdates.core.util.StringUtils; -import io.github.moulberry.notenoughupdates.miscgui.TrophyRewardOverlay; -import io.github.moulberry.notenoughupdates.util.ItemUtils; -import net.minecraft.client.Minecraft; -import net.minecraft.inventory.Container; -import net.minecraft.inventory.ContainerChest; -import net.minecraft.item.ItemStack; -import net.minecraftforge.client.event.GuiOpenEvent; -import net.minecraftforge.event.entity.player.ItemTooltipEvent; -import net.minecraftforge.fml.common.eventhandler.EventPriority; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import org.lwjgl.input.Keyboard; - -import java.text.DecimalFormat; -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -public class BazaarSacksProfit { - - private static BazaarSacksProfit INSTANCE = null; - private boolean showSellOrderPrice = false; - private boolean pressedShiftLast = false; - - public static BazaarSacksProfit getInstance() { - if (INSTANCE == null) { - INSTANCE = new BazaarSacksProfit(); - } - return INSTANCE; - } - - private final Map<String, Integer> prices = new HashMap<>(); - private final Map<String, String> names = new HashMap<>(); - private final List<String> invalidNames = new ArrayList<>(); - private boolean dirty = true; - - @SubscribeEvent - public void onGuiOpen(GuiOpenEvent event) { - showSellOrderPrice = false; - dirty = true; - } - - @SubscribeEvent(priority = EventPriority.LOW) - public void onItemTooltipLow(ItemTooltipEvent event) { - if (!NotEnoughUpdates.INSTANCE.config.bazaarTweaks.bazaarSacksProfit) return; - if (!inBazaar()) return; - - ItemStack itemStack = event.itemStack; - String displayName = itemStack.getDisplayName(); - if (!displayName.equals("§bSell Sacks Now")) return; - - boolean shift = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT); - if (!pressedShiftLast && shift) { - showSellOrderPrice = !showSellOrderPrice; - } - pressedShiftLast = shift; - - if (dirty) { - dirty = false; - prices.clear(); - names.clear(); - invalidNames.clear(); - - out: - for (String line : ItemUtils.getLore(itemStack)) { - - if (line.equals("§8Loading...")) { - dirty = true; - return; - } - if (line.contains("§7x ")) { - String[] split = line.split("§7x "); - String rawAmount = StringUtils.cleanColour(split[0]).replace(",", "").substring(1); - int amount = Integer.parseInt(rawAmount); - String bazaarName = split[1].split(" §7for")[0]; - for (Map.Entry<String, JsonObject> entry : NotEnoughUpdates.INSTANCE.manager - .getItemInformation() - .entrySet()) { - String internalName = entry.getKey(); - JsonObject object = entry.getValue(); - if (object.has("displayname")) { - String name = object.get("displayname").getAsString(); - if (name.equals(bazaarName)) { - prices.put(internalName, amount); - names.put(internalName, bazaarName); - continue out; - } - } - } - System.err.println("no bazaar item in repo found for '" + bazaarName + "'"); - invalidNames.add(bazaarName); - } - } - } - - event.toolTip.removeIf(line -> line.contains("§7x ") || line.contains("You earn:")); - - Map<String, Float> map = new HashMap<>(); - DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ENGLISH); - formatter.applyPattern("#,##0"); - double totalPrice = 0; - for (Map.Entry<String, Integer> entry : prices.entrySet()) { - String internalName = entry.getKey(); - int amount = entry.getValue(); - String name = names.get(internalName); - - JsonObject bazaarInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo(internalName); - - float price = 0; - if (bazaarInfo != null) { - - if (showSellOrderPrice) { - if (bazaarInfo.has("curr_buy")) { - price = bazaarInfo.get("curr_buy").getAsFloat(); - } else { - System.err.println("curr_sell does not exist for '" + internalName + "'"); - } - } else { - if (bazaarInfo.has("curr_sell")) { - price = bazaarInfo.get("curr_sell").getAsFloat(); - } else { - System.err.println("curr_sell does not exist for '" + internalName + "'"); - } - } - } - float extraPrice = price * amount; - String priceFormat = formatter.format(extraPrice); - totalPrice += extraPrice; - map.put("§a" + formatter.format(amount) + "§7x §f" + name + " §7for §6" + priceFormat + " coins", extraPrice); - } - - event.toolTip.add(4, ""); - if (showSellOrderPrice) { - event.toolTip.add(4, "§7Sell order price: §6" + formatter.format(totalPrice)); - } else { - event.toolTip.add(4, "§7Instant sell price: §6" + formatter.format(totalPrice)); - } - - event.toolTip.add(4, ""); - event.toolTip.removeIf(line -> line.equals("§5§o")); - int index = 4; - for (String name : invalidNames) { - index++; - event.toolTip.add(4, name + " §c[NEU] Missing Repo data!"); - } - for (String text : TrophyRewardOverlay.sortByValue(map).keySet()) { - index++; - event.toolTip.add(4, text); - } - event.toolTip.add(index, ""); - - if (!showSellOrderPrice) { - event.toolTip.add("§8[Press SHIFT to show sell order price]"); - } else { - event.toolTip.add("§8[Press SHIFT to show instant sell price]"); - } - } - - public static boolean inBazaar() { - if (!NotEnoughUpdates.INSTANCE.isOnSkyblock()) return false; - - Minecraft minecraft = Minecraft.getMinecraft(); - if (minecraft == null || minecraft.thePlayer == null) return false; - - Container inventoryContainer = minecraft.thePlayer.openContainer; - if (!(inventoryContainer instanceof ContainerChest)) return false; - ContainerChest containerChest = (ContainerChest) inventoryContainer; - return containerChest.getLowerChestInventory().getDisplayName().getUnformattedText().startsWith("Bazaar "); - } -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BetterContainers.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BetterContainers.java index e51496e3..ad0b238a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BetterContainers.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BetterContainers.java @@ -21,6 +21,7 @@ package io.github.moulberry.notenoughupdates.miscfeatures; import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.events.SlotClickEvent; import io.github.moulberry.notenoughupdates.listener.RenderListener; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.inventory.GuiChest; @@ -37,6 +38,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import javax.imageio.ImageIO; import java.awt.*; @@ -563,4 +565,17 @@ public class BetterContainers { return 0; } } + + @SubscribeEvent + public void onMouseClick(SlotClickEvent event) { + if (!isOverriding()) return; + boolean isBlankStack = BetterContainers.isBlankStack(event.slot.slotNumber, event.slot.getStack()); + if (!(isBlankStack || + BetterContainers.isButtonStack(event.slot.slotNumber, event.slot.getStack()))) return; + clickSlot(event.slotId); + if (isBlankStack) { + event.usePickblockInstead(); + } + } + } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java index 167b6a2f..ab9345cb 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java @@ -170,7 +170,7 @@ public class CrystalMetalDetectorSolver { // falls through case FOUND: mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "[NEU] Found solution.")); - if (NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.contains(NEUDebugFlag.METAL) && + if (NEUDebugFlag.METAL.isSet() && (previousState == SolutionState.INVALID || previousState == SolutionState.FAILED)) { NEUDebugLogger.log( NEUDebugFlag.METAL, diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java index 36b58424..21d1d4a3 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java @@ -48,6 +48,7 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.EnumSet; import java.util.HashMap; +import java.util.Locale; import java.util.function.BooleanSupplier; import java.util.function.LongSupplier; @@ -510,7 +511,7 @@ public class CrystalWishingCompassSolver { for (String crystalName : crystals.keySet()) { Integer crystalState = crystals.get(crystalName); if (crystalState != null && crystalState > 0) { - foundCrystals.add(Crystal.valueOf(crystalName.toUpperCase())); + foundCrystals.add(Crystal.valueOf(crystalName.toUpperCase(Locale.US).replace("İ", "I"))); } } @@ -924,7 +925,7 @@ public class CrystalWishingCompassSolver { return; } - boolean wishingDebugFlagSet = NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.contains(NEUDebugFlag.WISHING); + boolean wishingDebugFlagSet = NEUDebugFlag.WISHING.isSet(); if (outputAlways || wishingDebugFlagSet) { NEUDebugLogger.logAlways(getDiagnosticMessage()); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java index c77a4b39..452f8a9b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java @@ -213,12 +213,14 @@ public class CustomItemEffects { @SubscribeEvent public void onGameTick(TickEvent.ClientTickEvent event) { if (event.phase != TickEvent.Phase.END) return; + EntityPlayerSP player = Minecraft.getMinecraft().thePlayer; + if (player == null) return; if (!usingEtherwarp && wasUsingEtherwarp) { - if (Minecraft.getMinecraft().thePlayer.rotationYaw > 0) { - Minecraft.getMinecraft().thePlayer.rotationYaw -= 0.000001; + if (player.rotationYaw > 0) { + player.rotationYaw -= 0.000001; } else { - Minecraft.getMinecraft().thePlayer.rotationYaw += 0.000001; + player.rotationYaw += 0.000001; } } wasUsingEtherwarp = usingEtherwarp; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DamageCommas.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DamageCommas.java index b1ab11c1..d8f7becd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DamageCommas.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DamageCommas.java @@ -27,7 +27,6 @@ import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.IChatComponent; -import java.text.NumberFormat; import java.util.WeakHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -88,7 +87,7 @@ public class DamageCommas { if (matcherNoCrit.matches()) { numbers = matcherNoCrit.group(2).replace(",", ""); prefix = matcherNoCrit.group(1); - suffix = "\u00A7r" + matcherNoCrit.group(3); + suffix = "\u00A7r" + (matcherNoCrit.group(3).contains("♞") ? "\u00A7d" + matcherNoCrit.group(3) : matcherNoCrit.group(3)); } else { replacementMap.put(entity, null); return name; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java index 558917fe..d5cbfdde 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java @@ -20,6 +20,7 @@ package io.github.moulberry.notenoughupdates.miscfeatures; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.events.SlotClickEvent; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.inventory.GuiChest; @@ -308,97 +309,88 @@ public class EnchantingSolvers { return false; } - public static boolean onStackClick(ItemStack stack, int windowId, int slotId, int mouseButtonClicked, int mode) { - if (!NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enableEnchantingSolvers) { - return false; + @SubscribeEvent + public void onStackClick(SlotClickEvent event) { + if (!NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enableEnchantingSolvers + || !NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { + return; } - if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { - return false; + ItemStack stack = event.slot.getStack(); + if (stack == null || stack.getDisplayName() == null) { + return; } + String displayName = stack.getDisplayName(); + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) { + return; + } + GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; + ContainerChest container = (ContainerChest) chest.inventorySlots; + IInventory lower = container.getLowerChestInventory(); + + if (currentSolver == SolverType.CHRONOMATRON) { + ItemStack timerStack = lower.getStackInSlot(lower.getSizeInventory() - 5); + if (timerStack == null) { + return; + } - if (stack != null && stack.getDisplayName() != null) { - String displayName = stack.getDisplayName(); - if (Minecraft.getMinecraft().currentScreen instanceof GuiChest) { - GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; - ContainerChest container = (ContainerChest) chest.inventorySlots; - IInventory lower = container.getLowerChestInventory(); - - if (currentSolver == SolverType.CHRONOMATRON) { - ItemStack timerStack = lower.getStackInSlot(lower.getSizeInventory() - 5); - if (timerStack == null) { - return false; - } - - boolean yepClock = timerStack.getItem() == Items.clock; - if (timerStack.getItem() == Item.getItemFromBlock(Blocks.glowstone) || - (yepClock && (!addToChronomatron || chronomatronOrder.size() < lastChronomatronSize + 1))) { - return true; - } else if (yepClock) { - long currentTime = System.currentTimeMillis(); - if (currentTime - millisLastClick < 150) { - return true; - } + boolean yepClock = timerStack.getItem() == Items.clock; + if (timerStack.getItem() == Item.getItemFromBlock(Blocks.glowstone) || + (yepClock && (!addToChronomatron || chronomatronOrder.size() < lastChronomatronSize + 1))) { + event.setCanceled(true); + return; + } + if (yepClock) { + long currentTime = System.currentTimeMillis(); + if (currentTime - millisLastClick < 150) { + event.setCanceled(true); + return; + } - if (chronomatronReplayIndex < chronomatronOrder.size()) { - String chronomatronCurrent = chronomatronOrder.get(chronomatronReplayIndex); - if (!NotEnoughUpdates.INSTANCE.config.enchantingSolvers.preventMisclicks1 || - chronomatronCurrent.equals(displayName) || Keyboard.getEventKey() == Keyboard.KEY_LSHIFT) { - chronomatronReplayIndex++; - Minecraft.getMinecraft().playerController.windowClick(windowId, slotId, - 2, mode, Minecraft.getMinecraft().thePlayer - ); - millisLastClick = currentTime; - } - /*if (chronomatronCurrent.equals(displayName)) { - chronomatronReplayIndex++; - } - Minecraft.getMinecraft().playerController.windowClick(windowId, slotId, - 2, mode, Minecraft.getMinecraft().thePlayer); - millisLastClick = currentTime;*/ - } - return true; - } - } else if (currentSolver == SolverType.ULTRASEQUENCER) { - ItemStack timerStack = lower.getStackInSlot(lower.getSizeInventory() - 5); - if (timerStack == null) { - return false; + if (chronomatronReplayIndex < chronomatronOrder.size()) { + String chronomatronCurrent = chronomatronOrder.get(chronomatronReplayIndex); + if ((!NotEnoughUpdates.INSTANCE.config.enchantingSolvers.preventMisclicks1 || + chronomatronCurrent.equals(displayName) || Keyboard.getEventKey() == Keyboard.KEY_LSHIFT) && + stack.getItem() != Item.getItemFromBlock(Blocks.stained_glass_pane) && event.slotId != 4 && + event.slotId != 49) { + chronomatronReplayIndex++; + millisLastClick = currentTime; + event.usePickblockInstead(); + return; } + } + event.setCanceled(true); + return; + } + } + if (currentSolver == SolverType.ULTRASEQUENCER) { + ItemStack timerStack = lower.getStackInSlot(lower.getSizeInventory() - 5); + if (timerStack == null) { + return; + } - boolean yepClock = timerStack.getItem() == Items.clock; - if (yepClock) { - UltrasequencerItem current = ultraSequencerOrder.get(ultrasequencerReplayIndex); - if (current == null) { - return true; - } - long currentTime = System.currentTimeMillis(); - if (currentTime - millisLastClick > 150 && - (!NotEnoughUpdates.INSTANCE.config.enchantingSolvers.preventMisclicks1 || - current.containerIndex == slotId || Keyboard.getEventKey() == Keyboard.KEY_LSHIFT)) { - ultrasequencerReplayIndex++; - Minecraft.getMinecraft().playerController.windowClick(windowId, slotId, - 2, mode, Minecraft.getMinecraft().thePlayer - ); - millisLastClick = currentTime; - } - /*if (currentTime - millisLastClick > 150) { - if (current.containerIndex == slotId) { - ultrasequencerReplayIndex++; - } - Minecraft.getMinecraft().playerController.windowClick(windowId, slotId, - 2, mode, Minecraft.getMinecraft().thePlayer); - millisLastClick = currentTime; - }*/ - return true; - } else { - return true; - } - } else if (currentSolver == SolverType.SUPERPAIRS) { - lastSlotClicked = slotId; + boolean yepClock = timerStack.getItem() == Items.clock; + if (yepClock) { + UltrasequencerItem current = ultraSequencerOrder.get(ultrasequencerReplayIndex); + long currentTime = System.currentTimeMillis(); + if (current == null) { + event.setCanceled(true); + return; + } + if (currentTime - millisLastClick > 150 && + (!NotEnoughUpdates.INSTANCE.config.enchantingSolvers.preventMisclicks1 || + current.containerIndex == event.slotId || Keyboard.getEventKey() == Keyboard.KEY_LSHIFT) && + (event.slotId < 45 && event.slotId > 8)) { + ultrasequencerReplayIndex++; + millisLastClick = currentTime; + event.usePickblockInstead(); + return; } } + event.setCanceled(true); + } else if (currentSolver == SolverType.SUPERPAIRS) { + lastSlotClicked = event.slotId; } - return false; } public static void processInventoryContents(boolean fromTick) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FishingHelper.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FishingHelper.java index 242bd443..e3afc73d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FishingHelper.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FishingHelper.java @@ -401,7 +401,7 @@ public class FishingHelper { return; } - if ((particleType == EnumParticleTypes.WATER_WAKE || particleType == EnumParticleTypes.SMOKE_NORMAL) && Math.abs( + if ((particleType == EnumParticleTypes.WATER_WAKE || particleType == EnumParticleTypes.SMOKE_NORMAL || particleType == EnumParticleTypes.FLAME) && Math.abs( yOffset - 0.01f) < 0.001f) { double angle1 = calculateAngleFromOffsets(xOffset, -zOffset); double angle2 = calculateAngleFromOffsets(-xOffset, zOffset); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java index f2b13abc..f68f3c58 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java @@ -40,6 +40,10 @@ public class ItemCooldowns { private static final Map<ItemStack, Float> durabilityOverrideMap = new HashMap<>(); public static long pickaxeUseCooldownMillisRemaining = -1; private static long treecapitatorCooldownMillisRemaining = -1; + + public static boolean firstLoad = true; + public static long firstLoadMillis = 0; + private static long lastMillis = 0; public static long pickaxeCooldown = -1; @@ -57,6 +61,11 @@ public class ItemCooldowns { } long currentTime = System.currentTimeMillis(); + if (firstLoad) { + firstLoadMillis = currentTime; + firstLoad = false; + } + Long key; while ((key = blocksClicked.floorKey(currentTime - 1500)) != null) { @@ -78,7 +87,7 @@ public class ItemCooldowns { } @SubscribeEvent - public void onWorldUnload(WorldEvent.Load event) { + public void onWorldLoad(WorldEvent.Load event) { blocksClicked.clear(); if (pickaxeCooldown > 0) pickaxeUseCooldownMillisRemaining = 60 * 1000; pickaxeCooldown = -1; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java index 541a76e8..6244c32c 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java @@ -208,6 +208,7 @@ public class Navigation { if (event.phase != TickEvent.Phase.START) return; if (Minecraft.getMinecraft().theWorld == null) return; if (Minecraft.getMinecraft().thePlayer == null) return; + if (neu.config.getProfileSpecific() == null) return; if (Minecraft.getMinecraft().currentScreen instanceof GuiChest && RenderListener.inventoryLoaded) { GuiChest currentScreen = (GuiChest) Minecraft.getMinecraft().currentScreen; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java index 90300bbc..776e3647 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java @@ -26,11 +26,11 @@ import com.google.gson.JsonElement; import com.google.gson.JsonNull; import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import io.github.moulberry.notenoughupdates.NEUOverlay; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.config.Position; import io.github.moulberry.notenoughupdates.core.util.StringUtils; import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils; +import io.github.moulberry.notenoughupdates.events.SlotClickEvent; import io.github.moulberry.notenoughupdates.listener.RenderListener; import io.github.moulberry.notenoughupdates.options.NEUConfig; import io.github.moulberry.notenoughupdates.overlays.TextOverlay; @@ -134,6 +134,13 @@ public class PetInfoOverlay extends TextOverlay { public String petXpType; public String petItem; public String skin; + public int candyUsed; + + public String getPetId(boolean withoutBoost) { + boolean shouldDecreaseRarity = withoutBoost && "PET_ITEM_TIER_BOOST".equals(petItem); + return petType + ";" + (shouldDecreaseRarity ? rarity.petId - 1 : rarity.petId); + } + } public static class PetConfig { @@ -243,7 +250,8 @@ public class PetInfoOverlay extends TextOverlay { } private static Pet getClosestPet(String petType, int petId, String petItem, float petLevel) { - Set<Pet> pets = config.petMap.values().stream().filter(pet -> pet.petType.equals(petType) && pet.rarity.petId == petId).collect( + Set<Pet> pets = config.petMap.values().stream().filter(pet -> pet.petType.equals(petType) && + pet.rarity.petId == petId).collect( Collectors.toSet()); if (pets.isEmpty()) { @@ -254,7 +262,10 @@ public class PetInfoOverlay extends TextOverlay { return pets.iterator().next(); } - Set<Pet> itemMatches = pets.stream().filter(pet -> Objects.equals(petItem, pet.petItem)).collect(Collectors.toSet()); + Set<Pet> itemMatches = pets + .stream() + .filter(pet -> Objects.equals(petItem, pet.petItem)) + .collect(Collectors.toSet()); if (itemMatches.size() == 1) { return itemMatches.iterator().next(); @@ -452,14 +463,15 @@ public class PetInfoOverlay extends TextOverlay { } } - if (currentPet.petLevel.level < (currentPet.petLevel.maxLevel - 1) || !NotEnoughUpdates.INSTANCE.config.petOverlay.petOverlayText.contains(6)) { + if (currentPet.petLevel.level < (currentPet.petLevel.maxLevel - 1) || + !NotEnoughUpdates.INSTANCE.config.petOverlay.petOverlayText.contains(6)) { float remainingMax = currentPet.petLevel.maxXP - currentPet.petLevel.totalXp; if (remaining > 0) { if (xpGain < 1000) { - etaMaxStr = EnumChatFormatting.AQUA + "Until L" + currentPet.petLevel.maxLevel + ": " + + etaMaxStr = EnumChatFormatting.AQUA + "Until L" + (int) currentPet.petLevel.maxLevel + ": " + EnumChatFormatting.YELLOW + "N/A"; } else { - etaMaxStr = EnumChatFormatting.AQUA + "Until L" + currentPet.petLevel.maxLevel + ": " + + etaMaxStr = EnumChatFormatting.AQUA + "Until L" + (int) currentPet.petLevel.maxLevel + ": " + EnumChatFormatting.YELLOW + Utils.prettyTime((long) (remainingMax) * 1000 * 60 * 60 / (long) xpGain); } } @@ -563,7 +575,7 @@ public class PetInfoOverlay extends TextOverlay { JsonObject petInfo = new JsonParser().parse(ea.getString("petInfo")).getAsJsonObject(); petType = petInfo.get("type").getAsString(); rarity = Rarity.valueOf(petInfo.get("tier").getAsString()); - level = GuiProfileViewer. getPetLevel( + level = GuiProfileViewer.getPetLevel( petType, rarity.name(), Utils.getElementAsFloat(petInfo.get("exp"), 0) // Should only default if from item list and repo missing exp:0 @@ -779,10 +791,14 @@ public class PetInfoOverlay extends TextOverlay { if (!NotEnoughUpdates.INSTANCE.config.petOverlay.petOverlayIcon) return; int mythicRarity = currentPet.rarity.petId; - if (currentPet.rarity.petId == 5) { - mythicRarity = 4; + JsonObject petItem = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get( + currentPet.skin != null ? currentPet.skin : (currentPet.petType + ";" + mythicRarity)); + + if (petItem == null && currentPet.rarity.petId == 5) { + petItem = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get( + currentPet.skin != null ? currentPet.skin : (currentPet.petType + ";" + 4)); } - JsonObject petItem = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(currentPet.skin != null ? currentPet.skin : (currentPet.petType + ";" + mythicRarity)); + if (petItem != null) { Vector2f position = getPosition(overlayWidth, overlayHeight); int x = (int) position.x; @@ -799,7 +815,8 @@ public class PetInfoOverlay extends TextOverlay { Pet currentPet2 = getCurrentPet2(); if (currentPet2 != null) { - JsonObject petItem2 = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(currentPet2.skin != null ? currentPet2.skin : (currentPet2.petType + ";" + currentPet2.rarity.petId)); + JsonObject petItem2 = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get( + currentPet2.skin != null ? currentPet2.skin : (currentPet2.petType + ";" + currentPet2.rarity.petId)); if (petItem2 != null) { Vector2f position = getPosition(overlayWidth, overlayHeight); int x = (int) position.x; @@ -846,19 +863,19 @@ public class PetInfoOverlay extends TextOverlay { "alchemy" ); - public static void onStackClick(ItemStack stack, int windowId, int slotId, int mouseButtonClicked, int mode) { - if (mode != 0) return; - if (mouseButtonClicked != 0 && mouseButtonClicked != 1) return; + @SubscribeEvent + public void onStackClick(SlotClickEvent event) { + if (event.clickedButton != 0 && event.clickedButton != 1 && event.clickedButton != 2) return; - int slotIdMod = (slotId - 10) % 9; - if (slotId >= 10 && slotId <= 43 && slotIdMod >= 0 && slotIdMod <= 6 && + int slotIdMod = (event.slotId - 10) % 9; + if (event.slotId >= 10 && event.slotId <= 43 && slotIdMod >= 0 && slotIdMod <= 6 && Minecraft.getMinecraft().currentScreen instanceof GuiChest) { GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; ContainerChest container = (ContainerChest) chest.inventorySlots; IInventory lower = container.getLowerChestInventory(); String containerName = lower.getDisplayName().getUnformattedText(); - if (lower.getSizeInventory() >= 54 && windowId == container.windowId) { + if (lower.getSizeInventory() >= 54 && event.guiContainer.inventorySlots.windowId == container.windowId) { int page = 0; boolean isPets = false; @@ -880,7 +897,7 @@ public class PetInfoOverlay extends TextOverlay { boolean isRemoving = removingStack != null && removingStack.getItem() == Items.dye && removingStack.getItemDamage() == 10; - int newSelected = (slotId - 10) - (slotId - 10) / 9 * 2 + page * 28; + int newSelected = (event.slotId - 10) - (event.slotId - 10) / 9 * 2 + page * 28; lastPetSelect = System.currentTimeMillis(); @@ -893,9 +910,11 @@ public class PetInfoOverlay extends TextOverlay { } else { setCurrentPet(newSelected); - Pet pet = getPetFromStack(stack.getTagCompound()); - if (pet != null) { - config.petMap.put(config.selectedPet, pet); + if (event.slot.getStack() != null && event.slot.getStack().getTagCompound() != null) { + Pet pet = getPetFromStack(event.slot.getStack().getTagCompound()); + if (pet != null) { + config.petMap.put(config.selectedPet, pet); + } } } } @@ -1031,18 +1050,12 @@ public class PetInfoOverlay extends TextOverlay { @SubscribeEvent(priority = EventPriority.HIGHEST) public void onChatReceived(ClientChatReceivedEvent event) { NEUConfig config = NotEnoughUpdates.INSTANCE.config; - if (NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() && - (config.petOverlay.enablePetInfo || config.itemOverlays.enableMonkeyCheck || config.petOverlay.petInvDisplay)) { + if (config.petOverlay.enablePetInfo || config.itemOverlays.enableMonkeyCheck || config.petOverlay.petInvDisplay) { if (event.type == 0) { String chatMessage = Utils.cleanColour(event.message.getUnformattedText()); Matcher autopetMatcher = AUTOPET_EQUIP.matcher(event.message.getFormattedText()); - if (event.message.getUnformattedText().startsWith("You summoned your") || - System.currentTimeMillis() - NEUOverlay.cachedPetTimer < 500) { - NEUOverlay.cachedPetTimer = System.currentTimeMillis(); - NEUOverlay.shouldUseCachedPet = false; - } else if (autopetMatcher.matches()) { - NEUOverlay.shouldUseCachedPet = false; + if (autopetMatcher.matches()) { try { lastLevelHovered = Integer.parseInt(autopetMatcher.group(1)); } catch (NumberFormatException ignored) { @@ -1069,9 +1082,13 @@ public class PetInfoOverlay extends TextOverlay { setCurrentPet(getClosestPetIndex(pet, rarity.petId, "", lastLevelHovered)); if (PetInfoOverlay.config.selectedPet == -1) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "[NEU] Can't find pet \u00a7" + petStringMatch + - EnumChatFormatting.RED + " try revisiting all pages of /pets.")); + setCurrentPet(getClosestPetIndex(pet, rarity.petId - 1, "", lastLevelHovered)); + if (!"PET_ITEM_TIER_BOOST".equals(getCurrentPet().petItem)) { + PetInfoOverlay.config.selectedPet = -1; + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( + EnumChatFormatting.RED + "[NEU] Can't find pet \u00a7" + petStringMatch + + EnumChatFormatting.RED + " try revisiting all pages of /pets.")); + } } } else if ((chatMessage.toLowerCase().startsWith("you despawned your")) || (chatMessage.toLowerCase().contains( "switching to profile")) diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SlotLocking.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SlotLocking.java index 3955c363..8a487739 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SlotLocking.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SlotLocking.java @@ -24,6 +24,7 @@ import com.google.gson.GsonBuilder; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.config.KeybindHelper; import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; +import io.github.moulberry.notenoughupdates.events.SlotClickEvent; import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer; import io.github.moulberry.notenoughupdates.util.SBInfo; import net.minecraft.client.Minecraft; @@ -43,7 +44,6 @@ import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.event.GuiScreenEvent; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import org.apache.commons.lang3.tuple.Triple; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; @@ -58,7 +58,6 @@ import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import java.util.HashMap; -import java.util.function.Consumer; public class SlotLocking { private static final SlotLocking INSTANCE = new SlotLocking(); @@ -455,22 +454,21 @@ public class SlotLocking { } } - public void onWindowClick( - Slot slotIn, - int slotId, - int clickedButton, - int clickType, - Consumer<Triple<Integer, Integer, Integer>> consumer - ) { - LockedSlot locked = getLockedSlot(slotIn); + @SubscribeEvent + public void onWindowClick(SlotClickEvent slotClickEvent) { + LockedSlot locked = getLockedSlot(slotClickEvent.slot); if (locked == null) { return; - } else if (locked.locked || (clickType == 2 && SlotLocking.getInstance().isSlotIndexLocked(clickedButton))) { - consumer.accept(null); - } else if (NotEnoughUpdates.INSTANCE.config.slotLocking.enableSlotBinding && clickType == 1 && + } + if (locked.locked || + (slotClickEvent.clickType == 2 && SlotLocking.getInstance().isSlotIndexLocked(slotClickEvent.clickedButton))) { + slotClickEvent.setCanceled(true); + return; + } + if (NotEnoughUpdates.INSTANCE.config.slotLocking.enableSlotBinding + && slotClickEvent.clickType == 1 && locked.boundTo != -1) { - GuiContainer container = (GuiContainer) Minecraft.getMinecraft().currentScreen; - Slot boundSlot = container.inventorySlots.getSlotFromInventory( + Slot boundSlot = slotClickEvent.guiContainer.inventorySlots.getSlotFromInventory( Minecraft.getMinecraft().thePlayer.inventory, locked.boundTo ); @@ -481,29 +479,41 @@ public class SlotLocking { LockedSlot boundLocked = getLockedSlot(boundSlot); - int id = slotIn.getSlotIndex(); - if (id >= 9 && locked.boundTo >= 0 && locked.boundTo < 8) { - if (!boundLocked.locked) { - consumer.accept(Triple.of(slotId, locked.boundTo, 2)); - if (boundLocked == DEFAULT_LOCKED_SLOT) { - LockedSlot[] lockedSlots = getDataForProfile(); - lockedSlots[locked.boundTo] = new LockedSlot(); - lockedSlots[locked.boundTo].boundTo = id; - } else { - boundLocked.boundTo = id; - } + int from, to; + int id = slotClickEvent.slot.getSlotIndex(); + if (id >= 9 && 0 <= locked.boundTo && locked.boundTo < 8 && !boundLocked.locked) { + from = id; + to = locked.boundTo; + if (boundLocked == DEFAULT_LOCKED_SLOT) { + LockedSlot[] lockedSlots = getDataForProfile(); + lockedSlots[locked.boundTo] = new LockedSlot(); + lockedSlots[locked.boundTo].boundTo = id; + } else { + boundLocked.boundTo = id; } - } else if (id >= 0 && id < 8 && locked.boundTo >= 9 && locked.boundTo <= 39) { + } else if (0 <= id && id < 8 && locked.boundTo >= 9 && locked.boundTo <= 39) { if (boundLocked.locked || boundLocked.boundTo != id) { locked.boundTo = -1; + return; } else { - int boundTo = boundSlot.slotNumber; - consumer.accept(Triple.of(boundTo, id, 2)); + from = boundSlot.slotNumber; + to = id; } + } else { + return; } + if (from == 39) from = 5; + if (from == 38) from = 6; + if (from == 37) from = 7; + if (from == 36) from = 8; + Minecraft.getMinecraft().playerController.windowClick( + slotClickEvent.guiContainer.inventorySlots.windowId, + from, to, 2, Minecraft.getMinecraft().thePlayer + ); + slotClickEvent.setCanceled(true); } else if (NotEnoughUpdates.INSTANCE.config.slotLocking.enableSlotBinding && locked.boundTo != -1 && NotEnoughUpdates.INSTANCE.config.slotLocking.bindingAlsoLocks) { - consumer.accept(null); + slotClickEvent.setCanceled(true); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/StorageManager.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/StorageManager.java index 680637f2..bef07399 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/StorageManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/StorageManager.java @@ -38,12 +38,14 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.gui.inventory.GuiChest; import net.minecraft.init.Blocks; +import net.minecraft.init.Items; import net.minecraft.inventory.ContainerChest; import net.minecraft.inventory.IInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.JsonToNBT; import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTException; import net.minecraft.nbt.NBTTagByte; import net.minecraft.nbt.NBTTagByteArray; import net.minecraft.nbt.NBTTagCompound; @@ -82,11 +84,12 @@ public class StorageManager { private static final StorageManager INSTANCE = new StorageManager(); private static final Gson GSON = new GsonBuilder() .registerTypeAdapter(ItemStack.class, new ItemStackSerializer()) - .registerTypeAdapter(ItemStack.class, new ItemStackDeserilizer()).create(); + .registerTypeAdapter(ItemStack.class, new ItemStackDeserializer()).create(); public static class ItemStackSerializer implements JsonSerializer<ItemStack> { @Override public JsonElement serialize(ItemStack src, Type typeOfSrc, JsonSerializationContext context) { + fixPetInfo(src); NBTTagCompound tag = src.serializeNBT(); return nbtToJson(tag); } @@ -94,7 +97,7 @@ public class StorageManager { private static final Pattern JSON_FIX_REGEX = Pattern.compile("\"([^,:]+)\":"); - public static class ItemStackDeserilizer implements JsonDeserializer<ItemStack> { + public static class ItemStackDeserializer implements JsonDeserializer<ItemStack> { @Override public ItemStack deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { @@ -134,6 +137,63 @@ public class StorageManager { return (JsonObject) loadJson(NBTTagCompound); } + private static class PetInfo { + String type; + Boolean active; + Double exp; + String tier; + Boolean hideInfo; + Integer candyUsed; + String uuid; + Boolean hideRightClick; + String heldItem; + String skin; + + private <T> void appendIfNotNull(StringBuilder builder, String key, T value) { + if (value != null) { + if (builder.indexOf("{") != builder.length()-1) { + builder.append(","); + } + builder.append(key).append(":"); + if (value instanceof String) { + builder.append("\"").append(value).append("\""); + } else { + builder.append(value); + } + } + } + + @Override + public String toString() { + StringBuilder object = new StringBuilder(); + object.append("{"); + appendIfNotNull(object, "type", type); + appendIfNotNull(object, "active", active); + appendIfNotNull(object, "exp", exp); + appendIfNotNull(object, "tier", tier); + appendIfNotNull(object, "hideInfo", hideInfo); + appendIfNotNull(object, "candyUsed", candyUsed); + appendIfNotNull(object, "uuid", uuid); + appendIfNotNull(object, "hideRightClick", hideRightClick); + appendIfNotNull(object, "heldItem", heldItem); + appendIfNotNull(object, "skin", skin); + object.append("}"); + return object.toString(); + } + } + + private static void fixPetInfo(ItemStack src) { + if (src.getTagCompound() == null || !src.getTagCompound().hasKey("ExtraAttributes") || !src.getTagCompound().getCompoundTag("ExtraAttributes").hasKey("petInfo")) return; + PetInfo oldPetInfo = GSON.fromJson(src.getTagCompound().getCompoundTag("ExtraAttributes").getString("petInfo"), PetInfo.class); + src.getTagCompound().getCompoundTag("ExtraAttributes").removeTag("petInfo"); + try { + src.getTagCompound().getCompoundTag("ExtraAttributes").setTag( + "petInfo", + JsonToNBT.getTagFromJson(oldPetInfo.toString()) + ); + } catch (NBTException | NullPointerException ignored) {} + } + private static JsonElement loadJson(NBTBase tag) { if (tag instanceof NBTTagCompound) { NBTTagCompound compoundTag = (NBTTagCompound) tag; @@ -234,7 +294,7 @@ public class StorageManager { private boolean shouldRenderStorageOverlayCached = false; - private static final Pattern WINDOW_REGEX = Pattern.compile(".+ Backpack (?:\u2726 )?\\((\\d+)/(\\d+)\\)"); + private static final Pattern WINDOW_REGEX = Pattern.compile(".+ Backpack (?:✦ )?\\(Slot #(\\d+)\\)"); private static final Pattern ECHEST_WINDOW_REGEX = Pattern.compile("Ender Chest \\((\\d+)/(\\d+)\\)"); public void loadConfig(File file) { @@ -555,8 +615,8 @@ public class StorageManager { int index = slot - 9; boolean changed = false; - if (stack.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane) && - stack.getMetadata() == 14) { + if ((stack.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane) && + stack.getMetadata() == 14) || (stack.getItem() == Items.dye && stack.getMetadata() == 8)) { if (storagePresent[index]) changed = true; storagePresent[index] = false; removePage(index); @@ -596,7 +656,8 @@ public class StorageManager { boolean changed = false; - if (stack.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane)) { + if (stack.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane) + || (stack.getItem() == Items.dye && stack.getMetadata() == 8)) { if (storagePresent[index]) changed = true; storagePresent[index] = false; removePage(index); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/EntityViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/EntityViewer.java index 367d62d3..2f091304 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/EntityViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/EntityViewer.java @@ -27,8 +27,10 @@ import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.gui.inventory.GuiInventory; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.boss.EntityDragon; import net.minecraft.entity.boss.EntityWither; @@ -63,6 +65,7 @@ import net.minecraft.entity.passive.EntitySquid; import net.minecraft.entity.passive.EntityVillager; import net.minecraft.entity.passive.EntityWolf; import net.minecraft.util.ResourceLocation; +import org.lwjgl.input.Keyboard; import java.io.IOException; import java.io.InputStreamReader; @@ -224,9 +227,23 @@ public class EntityViewer extends GuiScreen { float bottomOffset = 0F; EntityLivingBase stack = entity; while (true) { - + if (stack instanceof EntityDragon) { + if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) { + scale = 35; + bottomOffset = 0F; + } + else { + scale = 10; + bottomOffset = 2F; + } + } else if (stack instanceof EntityWither) { + scale = 20; + } else if (stack instanceof EntityGhast) { + scale = 8; + bottomOffset = 4F; + } stack.ticksExisted = Minecraft.getMinecraft().thePlayer.ticksExisted; - GuiInventory.drawEntityOnScreen( + drawEntityOnScreen( posX, (int) (posY - bottomOffset * scale), scale, @@ -242,4 +259,44 @@ public class EntityViewer extends GuiScreen { } } + + // Need this to flip the ender dragon and make it follow mouse correctly + public static void drawEntityOnScreen(int posX, int posY, int scale, float mouseX, float mouseY, EntityLivingBase ent) { + GlStateManager.enableColorMaterial(); + GlStateManager.pushMatrix(); + GlStateManager.translate((float)posX, (float)posY, 50.0F); + GlStateManager.scale((float)(-scale), (float)scale, (float)scale); + GlStateManager.rotate(180.0F, 0.0F, 0.0F, 1.0F); + float f = ent.renderYawOffset; + float g = ent.rotationYaw; + float h = ent.rotationPitch; + float i = ent.prevRotationYawHead; + float j = ent.rotationYawHead; + GlStateManager.rotate(135.0F, 0.0F, 1.0F, 0.0F); + RenderHelper.enableStandardItemLighting(); + GlStateManager.rotate((ent instanceof EntityDragon) ? 45.0F : -135.0F, 0.0F, 1.0F, 0.0F); + GlStateManager.rotate((ent instanceof EntityDragon) ? ((float)Math.atan(mouseY / 40.0F)) * 20.0F : -((float)Math.atan(mouseY / 40.0F)) * 20.0F, 1.0F, 0.0F, 0.0F); + ent.renderYawOffset = (float)Math.atan(mouseX / 40.0F) * 20.0F; + ent.rotationYaw = (float)Math.atan(mouseX / 40.0F) * 40.0F; + ent.rotationPitch = -((float)Math.atan(mouseY / 40.0F)) * 20.0F; + ent.rotationYawHead = ent.rotationYaw; + ent.prevRotationYawHead = ent.rotationYaw; + GlStateManager.translate(0.0F, 0.0F, 0.0F); + RenderManager renderManager = Minecraft.getMinecraft().getRenderManager(); + renderManager.setPlayerViewY(180.0F); + renderManager.setRenderShadow(false); + renderManager.renderEntityWithPosYaw(ent, 0.0D, 0.0D, 0.0D, 0.0F, 1.0F); + renderManager.setRenderShadow(true); + ent.renderYawOffset = f; + ent.rotationYaw = g; + ent.rotationPitch = h; + ent.prevRotationYawHead = i; + ent.rotationYawHead = j; + GlStateManager.popMatrix(); + RenderHelper.disableStandardItemLighting(); + GlStateManager.disableRescaleNormal(); + GlStateManager.setActiveTexture(OpenGlHelper.lightmapTexUnit); + GlStateManager.disableTexture2D(); + GlStateManager.setActiveTexture(OpenGlHelper.defaultTexUnit); + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/updater/AutoUpdater.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/updater/AutoUpdater.java index e7ada16f..54fcc204 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/updater/AutoUpdater.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/updater/AutoUpdater.java @@ -26,6 +26,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSyntaxException; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.util.MoulSigner; import io.github.moulberry.notenoughupdates.util.NotificationHandler; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; @@ -95,16 +96,6 @@ public class AutoUpdater { } updateLoader = getUpdateLoader(url); if (updateLoader == null) { - logProgress(new ChatComponentText( - "Your system does not support auto updates. Please download this update manually. Click here to read more about auto update compatibility (or the link above for manual downloads)") - .setChatStyle( - new ChatStyle() - .setChatHoverEvent(new HoverEvent( - HoverEvent.Action.SHOW_TEXT, - new ChatComponentText("Click here to read about auto update modalities") - )) - .setChatClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/neuupdate updatemodes")) - )); return; } updateLoader.greet(); @@ -181,6 +172,14 @@ public class AutoUpdater { File repo = neu.manager.repoLocation; File updateJson = new File(repo, "update.json"); if (updateJson.exists()) { + if (!MoulSigner.verifySignature(updateJson)) { + NotEnoughUpdates.LOGGER.error("update.json found without signature"); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( + "§e[NEU] §cThere has been an error checking for updates. Check the log or join the discord for more information.").setChatStyle( + Utils.createClickStyle( + ClickEvent.Action.OPEN_URL, "https://discord.gg/moulberry"))); + return; + } try { JsonObject o = neu.manager.getJsonFromFile(updateJson); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java index 2905a941..5f5c4832 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java @@ -75,6 +75,8 @@ public class CalendarOverlay { private static boolean enabled = false; + public static boolean ableToClickCalendar = true; + public static void setEnabled(boolean enabled) { CalendarOverlay.enabled = enabled; } @@ -479,8 +481,7 @@ public class CalendarOverlay { guiLeft = (width - xSize) / 2; guiTop = 5; - - if (mouseX >= guiLeft && mouseX <= guiLeft + xSize) { + if (mouseX >= guiLeft && mouseX <= guiLeft + xSize && ableToClickCalendar) { if (mouseY >= guiTop && mouseY <= guiTop + ySize) { ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/neucalendar"); } @@ -1331,7 +1332,7 @@ public class CalendarOverlay { if (mouseY >= guiTop + ySize + 2 && mouseY <= guiTop + ySize + 18) { tooltipToDisplay = new ArrayList<>(); tooltipToDisplay.add(EnumChatFormatting.AQUA + "NEU Calendar Help"); - tooltipToDisplay.add(EnumChatFormatting.YELLOW + "This calendar displays various skyblock events"); + tooltipToDisplay.add(EnumChatFormatting.YELLOW + "This calendar displays various SkyBlock events"); tooltipToDisplay.add(EnumChatFormatting.YELLOW + "'Daily' events are events that happen frequently"); tooltipToDisplay.add(EnumChatFormatting.YELLOW + "'Special' events are events that happen infrequently"); tooltipToDisplay.add(EnumChatFormatting.YELLOW + ""); @@ -1343,8 +1344,8 @@ public class CalendarOverlay { tooltipToDisplay.add(EnumChatFormatting.YELLOW + "is about to start and when it does start"); tooltipToDisplay.add(EnumChatFormatting.YELLOW + ""); tooltipToDisplay.add(EnumChatFormatting.DARK_GRAY + "In order to show crop types for Jacob's Farming"); - tooltipToDisplay.add(EnumChatFormatting.DARK_GRAY + "contest, visit the full skyblock calendar and go all"); - tooltipToDisplay.add(EnumChatFormatting.DARK_GRAY + "the way to the end of the skyblock year"); + tooltipToDisplay.add(EnumChatFormatting.DARK_GRAY + "contest, visit the full SkyBlock calendar and go all"); + tooltipToDisplay.add(EnumChatFormatting.DARK_GRAY + "the way to the end of the SkyBlock year"); Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); tooltipToDisplay = null; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiCustomEnchant.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiCustomEnchant.java index 8ba3a98a..6f190ada 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiCustomEnchant.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiCustomEnchant.java @@ -28,9 +28,11 @@ import io.github.moulberry.notenoughupdates.core.GuiElementTextField; import io.github.moulberry.notenoughupdates.core.util.lerp.LerpingFloat; import io.github.moulberry.notenoughupdates.core.util.lerp.LerpingInteger; import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking; +import io.github.moulberry.notenoughupdates.miscgui.util.OrbDisplay; import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer; import io.github.moulberry.notenoughupdates.options.NEUConfig; import io.github.moulberry.notenoughupdates.util.Constants; +import io.github.moulberry.notenoughupdates.util.ItemUtils; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; @@ -74,9 +76,9 @@ public class GuiCustomEnchant extends Gui { "textures/entity/enchanting_table_book.png"); private static final ModelBook MODEL_BOOK = new ModelBook(); - private static final int EXPERIENCE_ORB_COUNT = 30; - private static final Pattern XP_COST_PATTERN = Pattern.compile("\\u00a73(\\d+) Exp Levels"); + private static final Pattern ENCHANT_LEVEL_PATTERN = Pattern.compile("(.*)_(.*)"); + private static final Pattern ENCHANT_NAME_PATTERN = Pattern.compile("([^IVX]*) ([IVX]*)"); private enum EnchantState { NO_ITEM, @@ -105,6 +107,7 @@ public class GuiCustomEnchant extends Gui { this.enchId = enchId; this.displayLore = displayLore; this.level = level; + this.enchId = ItemUtils.fixEnchantId(enchId, true); if (Constants.ENCHANTS != null) { if (checkConflicts && Constants.ENCHANTS.has("enchant_pools")) { @@ -133,12 +136,18 @@ public class GuiCustomEnchant extends Gui { if (level >= 1 && Constants.ENCHANTS.has("enchants_xp_cost")) { JsonObject allCosts = Constants.ENCHANTS.getAsJsonObject("enchants_xp_cost"); - if (allCosts.has(enchId)) { - JsonArray costs = allCosts.getAsJsonArray(enchId); + JsonObject maxLevel = null; + if (Constants.ENCHANTS.has("max_xp_table_levels")) { + maxLevel = Constants.ENCHANTS.getAsJsonObject("max_xp_table_levels"); + } + + if (allCosts.has(this.enchId)) { + JsonArray costs = allCosts.getAsJsonArray(this.enchId); if (costs.size() >= 1) { if (useMaxLevelForCost) { - this.xpCost = costs.get(costs.size() - 1).getAsInt(); + int cost = (maxLevel != null && maxLevel.has(this.enchId) ? maxLevel.get(this.enchId).getAsInt() : costs.size()); + this.xpCost = costs.get(cost - 1).getAsInt(); } else if (level - 1 < costs.size()) { this.xpCost = costs.get(level - 1).getAsInt(); } else { @@ -152,21 +161,7 @@ public class GuiCustomEnchant extends Gui { } } - public static class ExperienceOrb { - public float x; - public float y; - public float xLast; - public float yLast; - public float xVel; - public float yVel; - - public int type; - public int rotationDeg; - } - - private final List<ExperienceOrb> orbs = new ArrayList<>(); - private int orbTargetX = 0; - private int orbTargetY = 0; + public OrbDisplay orbDisplay = new OrbDisplay(); private int guiLeft; private int guiTop; @@ -226,8 +221,15 @@ public class GuiCustomEnchant extends Gui { } public boolean shouldOverride(String containerName) { + if (containerName == null) { + shouldOverrideFast = false; + return false; + } shouldOverrideFast = NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enableTableGUI && - Objects.equals("Enchant Item", containerName) && + (containerName.length() >= 12 && Objects.equals( + "Enchant Item", + containerName.substring(0, "Enchant Item".length()) + )) && NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard(); if (!shouldOverrideFast) { currentState = EnchantState.NO_ITEM; @@ -235,6 +237,13 @@ public class GuiCustomEnchant extends Gui { removable.clear(); expectedMaxPage = 1; } + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + ContainerChest cc = (ContainerChest) chest.inventorySlots; + ItemStack hexStack = cc.getLowerChestInventory().getStackInSlot(50); + if (hexStack != null && hexStack.getItem() == Items.experience_bottle) { + shouldOverrideFast = false; + return false; + } return shouldOverrideFast; } @@ -245,13 +254,15 @@ public class GuiCustomEnchant extends Gui { ContainerChest cc = (ContainerChest) chest.inventorySlots; ItemStack stack = cc.getLowerChestInventory().getStackInSlot(23); - ItemStack enchantGuideStack = cc.getLowerChestInventory().getStackInSlot(50); + ItemStack arrowStack = cc.getLowerChestInventory().getStackInSlot(45); ItemStack enchantingItemStack = cc.getLowerChestInventory().getStackInSlot(19); + ItemStack hexStack = cc.getLowerChestInventory().getStackInSlot(50); int lastPage = currentPage; this.lastState = currentState; - if (enchantGuideStack != null && enchantGuideStack.getItem() != Items.book && enchantingItem != null) { + if (hexStack != null && hexStack.getItem() == Items.experience_bottle) return; + if (arrowStack != null && arrowStack.getItem() == Items.arrow && enchantingItem != null) { currentState = EnchantState.ADDING_ENCHANT; } else if (stack == null || enchantingItemStack == null) { if (currentState == EnchantState.SWITCHING_DONT_UPDATE || currentState == EnchantState.NO_ITEM) { @@ -305,30 +316,7 @@ public class GuiCustomEnchant extends Gui { } } - List<ExperienceOrb> toRemove = new ArrayList<>(); - for (ExperienceOrb orb : orbs) { - float targetDeltaX = guiLeft + orbTargetX - orb.x; - float targetDeltaY = guiTop + orbTargetY - orb.y; - - float length = (float) Math.sqrt(targetDeltaX * targetDeltaX + targetDeltaY * targetDeltaY); - - if (length < 8 && orb.xVel * orb.xVel + orb.yVel * orb.yVel < 20) { - toRemove.add(orb); - continue; - } - - orb.xVel += targetDeltaX * 2 / length; - orb.yVel += targetDeltaY * 2 / length; - - orb.xVel *= 0.90; - orb.yVel *= 0.90; - - orb.xLast = orb.x; - orb.yLast = orb.y; - orb.x += orb.xVel; - orb.y += orb.yVel; - } - orbs.removeAll(toRemove); + orbDisplay.physicsTickOrbs(); if (++tickCounter >= 20) { tickCounter = 0; @@ -389,40 +377,50 @@ public class GuiCustomEnchant extends Gui { if (ea != null) { NBTTagCompound enchantments = ea.getCompoundTag("enchantments"); if (enchantments != null) { - for (String enchId : enchantments.getKeySet()) { - String name = Utils.cleanColour(book.getDisplayName()); - if (name.equalsIgnoreCase("Bane of Arthropods")) { - name = "Bane of Arth."; - } else if (name.equalsIgnoreCase("Projectile Protection")) { - name = "Projectile Prot"; - } else if (name.equalsIgnoreCase("Blast Protection")) { - name = "Blast Prot"; - } - Enchantment enchantment = new Enchantment(slotIndex, name, enchId, - Utils.getRawTooltip(book), enchantments.getInteger(enchId), false, true - ); - enchantment.displayLore.remove(0); + String enchId = Utils + .cleanColour(book.getDisplayName()) + .toLowerCase() + .replace(" ", "_") + .replace("-", "_") + .replaceAll("[^a-z_]", ""); + String name = Utils.cleanColour(book.getDisplayName()); + int enchLevel = -1; + if (name.equalsIgnoreCase("Bane of Arthropods")) { + name = "Bane of Arth."; + } else if (name.equalsIgnoreCase("Projectile Protection")) { + name = "Projectile Prot"; + } else if (name.equalsIgnoreCase("Blast Protection")) { + name = "Blast Prot"; + } + Matcher levelMatcher = ENCHANT_LEVEL_PATTERN.matcher(enchId); + if (levelMatcher.matches()) { + enchLevel = Utils.parseRomanNumeral(levelMatcher.group(2).toUpperCase()); + enchId = levelMatcher.group(1); + } + Enchantment enchantment = new Enchantment(slotIndex, name, enchId, + Utils.getRawTooltip(book), enchLevel, false, true + ); + enchantment.displayLore.remove(0); - if (removingEnchantPlayerLevel == -1 && playerEnchantIds.containsKey(enchId)) { - removingEnchantPlayerLevel = playerEnchantIds.get(enchId); - } + if (removingEnchantPlayerLevel == -1 && playerEnchantIds.containsKey(enchId)) { + removingEnchantPlayerLevel = playerEnchantIds.get(enchId); + } - if (removingEnchantPlayerLevel >= 0 && enchantment.level < removingEnchantPlayerLevel) { - continue; - } + if (removingEnchantPlayerLevel >= 0 && enchantment.level < removingEnchantPlayerLevel) { + continue; + } - if (enchanterCurrentEnch == null) { + if (enchanterCurrentEnch == null) { + enchanterCurrentEnch = enchantment; + } else if (updateLevel) { + if (removingEnchantPlayerLevel < 0 && enchantment.level > enchanterCurrentEnch.level) { + enchanterCurrentEnch = enchantment; + } else if (removingEnchantPlayerLevel >= 0 && enchantment.level < enchanterCurrentEnch.level) { enchanterCurrentEnch = enchantment; - } else if (updateLevel) { - if (removingEnchantPlayerLevel < 0 && enchantment.level > enchanterCurrentEnch.level) { - enchanterCurrentEnch = enchantment; - } else if (removingEnchantPlayerLevel >= 0 && enchantment.level < enchanterCurrentEnch.level) { - enchanterCurrentEnch = enchantment; - } } - - enchanterEnchLevels.put(enchantment.level, enchantment); } + + enchanterEnchLevels.put(enchantment.level, enchantment); } } } @@ -455,43 +453,53 @@ public class GuiCustomEnchant extends Gui { if (ea != null) { NBTTagCompound enchantments = ea.getCompoundTag("enchantments"); if (enchantments != null) { - for (String enchId : enchantments.getKeySet()) { - String name = Utils.cleanColour(book.getDisplayName()); - - if (searchField.getText().trim().isEmpty() || - name.toLowerCase().contains(searchField.getText().trim().toLowerCase())) { - if (name.equalsIgnoreCase("Bane of Arthropods")) { - name = "Bane of Arth."; - } else if (name.equalsIgnoreCase("Projectile Protection")) { - name = "Projectile Prot"; - } else if (name.equalsIgnoreCase("Blast Protection")) { - name = "Blast Prot"; - } else if (name.equalsIgnoreCase("Luck of the Sea")) { - name = "Luck of Sea"; - } + String enchId = Utils + .cleanColour(book.getDisplayName()) + .toLowerCase() + .replace(" ", "_") + .replace("-", "_") + .replaceAll("[^a-z_]", ""); + if (enchId.equalsIgnoreCase("_")) continue; + enchId = ItemUtils.fixEnchantId(enchId, true); + String name = Utils.cleanColour(book.getDisplayName()); + + if (searchField.getText().trim().isEmpty() || + name.toLowerCase().contains(searchField.getText().trim().toLowerCase())) { + if (name.equalsIgnoreCase("Bane of Arthropods")) { + name = "Bane of Arth."; + } else if (name.equalsIgnoreCase("Projectile Protection")) { + name = "Projectile Prot"; + } else if (name.equalsIgnoreCase("Blast Protection")) { + name = "Blast Prot"; + } else if (name.equalsIgnoreCase("Luck of the Sea")) { + name = "Luck of Sea"; + } + Matcher nameMatcher = ENCHANT_NAME_PATTERN.matcher(name); + if (nameMatcher.matches()) { + name = nameMatcher.group(1); + } - if (playerEnchantIds.containsKey(enchId)) { - Enchantment enchantment = new Enchantment(slotIndex, name, enchId, - Utils.getRawTooltip(book), playerEnchantIds.get(enchId), false, false - ); - if (!enchantment.overMaxLevel) { - removable.add(enchantment); - } - } else { - Enchantment enchantment = new Enchantment(slotIndex, name, enchId, - Utils.getRawTooltip(book), enchantments.getInteger(enchId), true, true - ); - applicable.add(enchantment); + if (playerEnchantIds.containsKey(enchId)) { + Enchantment enchantment = new Enchantment(slotIndex, name, enchId, + Utils.getRawTooltip(book), playerEnchantIds.get(enchId), false, false + ); + if (!enchantment.overMaxLevel) { + removable.add(enchantment); } } else { - if (playerEnchantIds.containsKey(enchId)) { - searchRemovedFromRemovable = true; - } else { - searchRemovedFromApplicable = true; - } + Enchantment enchantment = new Enchantment(slotIndex, name, enchId, + Utils.getRawTooltip(book), 1, true, true + ); + applicable.add(enchantment); + } + } else { + if (playerEnchantIds.containsKey(enchId)) { + searchRemovedFromRemovable = true; + } else { + searchRemovedFromApplicable = true; } - } + } } } @@ -1065,7 +1073,9 @@ public class GuiCustomEnchant extends Gui { Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left + 8 - levelWidth / 2, top + 4, colour, false); //Enchant name - String name = WordUtils.capitalizeFully(enchanterCurrentEnch.enchId.replace("_", " ")); + String name = WordUtils.capitalizeFully(ItemUtils + .fixEnchantId(enchanterCurrentEnch.enchId, false) + .replace("_", " ")); if (name.equalsIgnoreCase("Bane of Arthropods")) { name = "Bane of Arth."; } else if (name.equalsIgnoreCase("Projectile Protection")) { @@ -1356,37 +1366,11 @@ public class GuiCustomEnchant extends Gui { //Orb animation Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); - GlStateManager.color(1, 1, 1, 1); GlStateManager.disableDepth(); - for (ExperienceOrb orb : orbs) { - int orbX = Math.round(orb.xLast + (orb.x - orb.xLast) * partialTicks); - int orbY = Math.round(orb.yLast + (orb.y - orb.yLast) * partialTicks); - GlStateManager.pushMatrix(); - GlStateManager.translate(orbX, orbY, 0); - GlStateManager.rotate(orb.rotationDeg, 0, 0, 1); - - float targetDeltaX = guiLeft + orbTargetX - orb.x; - float targetDeltaY = guiTop + orbTargetY - orb.y; - float length = (float) Math.sqrt(targetDeltaX * targetDeltaX + targetDeltaY * targetDeltaY); - float velSq = orb.xVel * orb.xVel + orb.yVel * orb.yVel; - float opacity = Math.min(2, Math.max(0.5f, length / 16)) * Math.min(2, Math.max(0.5f, velSq / 40)); - if (opacity > 1) opacity = 1; - opacity = (float) Math.sqrt(opacity); - GlStateManager.color(1, 1, 1, opacity); - - Utils.drawTexturedRect( - -8, - -8, - 16, - 16, - ((orb.type % 3) * 16) / 512f, - (16 + (orb.type % 3) * 16) / 512f, - (217 + orb.type / 3 * 16) / 512f, - (217 + 16 + orb.type / 3 * 16) / 512f, - GL11.GL_NEAREST - ); - GlStateManager.popMatrix(); - } + GlStateManager.pushMatrix(); + GlStateManager.translate(guiLeft, guiTop, 0); + orbDisplay.renderOrbs(partialTicks); + GlStateManager.popMatrix(); GlStateManager.enableDepth(); if (stackOnMouse != null) { @@ -1403,37 +1387,6 @@ public class GuiCustomEnchant extends Gui { GlStateManager.translate(0, 0, -300); } - private void spawnExperienceOrbs(int startX, int startY, int targetX, int targetY, int baseType) { - orbs.clear(); - - this.orbTargetX = targetX; - this.orbTargetY = targetY; - - Random rand = new Random(); - for (int i = 0; i < EXPERIENCE_ORB_COUNT; i++) { - ExperienceOrb orb = new ExperienceOrb(); - orb.x = startX; - orb.y = startY; - orb.xLast = startX; - orb.yLast = startY; - orb.xVel = rand.nextFloat() * 20 - 10; - orb.yVel = rand.nextFloat() * 20 - 10; - orb.type = baseType; - - float typeRand = rand.nextFloat(); - if (typeRand < 0.6) { - orb.type += 0; - } else if (typeRand < 0.9) { - orb.type += 1; - } else { - orb.type += 2; - } - orb.rotationDeg = rand.nextInt(4) * 90; - - orbs.add(orb); - } - } - private void renderEnchantBook(ScaledResolution scaledresolution, float partialTicks) { GlStateManager.enableDepth(); @@ -1540,9 +1493,9 @@ public class GuiCustomEnchant extends Gui { EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); - ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(48); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45); Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( - chest.inventorySlots.windowId, 48, 0, 0, stack, transactionID)); + chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID)); cancelButtonAnimTime = System.currentTimeMillis(); } @@ -1592,9 +1545,9 @@ public class GuiCustomEnchant extends Gui { EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); - ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(48); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45); Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( - chest.inventorySlots.windowId, 48, 0, 0, stack, transactionID)); + chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID)); cancelButtonAnimTime = System.currentTimeMillis(); } else if (!isChangingEnchLevel && enchanterCurrentEnch != null && @@ -1617,9 +1570,9 @@ public class GuiCustomEnchant extends Gui { int playerXpLevel = Minecraft.getMinecraft().thePlayer.experienceLevel; if (playerXpLevel >= enchanterCurrentEnch.xpCost) { if (removingEnchantPlayerLevel >= 0 && enchanterCurrentEnch.level == removingEnchantPlayerLevel) { - spawnExperienceOrbs(guiLeft + X_SIZE / 2, guiTop + 66, X_SIZE / 2, 36, 3); + orbDisplay.spawnExperienceOrbs(X_SIZE / 2, 66, X_SIZE / 2, 36, 3); } else { - spawnExperienceOrbs(mouseX, mouseY, X_SIZE / 2, 66, 0); + orbDisplay.spawnExperienceOrbs(mouseX - guiLeft, mouseY - guiTop, X_SIZE / 2, 66, 0); } } @@ -1790,9 +1743,9 @@ public class GuiCustomEnchant extends Gui { } else if (currentState == EnchantState.ADDING_ENCHANT) { EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); - ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(48); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45); Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( - chest.inventorySlots.windowId, 48, 0, 0, stack, transactionID)); + chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID)); cancelButtonAnimTime = System.currentTimeMillis(); } @@ -1830,9 +1783,9 @@ public class GuiCustomEnchant extends Gui { } else if (currentState == EnchantState.ADDING_ENCHANT) { EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); - ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(48); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45); Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( - chest.inventorySlots.windowId, 48, 0, 0, stack, transactionID)); + chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID)); cancelButtonAnimTime = System.currentTimeMillis(); } @@ -1877,9 +1830,9 @@ public class GuiCustomEnchant extends Gui { EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); - ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(48); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45); Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( - chest.inventorySlots.windowId, 48, 0, 0, stack, transactionID)); + chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID)); cancelButtonAnimTime = System.currentTimeMillis(); } @@ -1898,9 +1851,9 @@ public class GuiCustomEnchant extends Gui { EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); - ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(48); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45); Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( - chest.inventorySlots.windowId, 48, 0, 0, stack, transactionID)); + chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID)); cancelButtonAnimTime = System.currentTimeMillis(); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiEnchantColour.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiEnchantColour.java index 31713189..b90b1356 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiEnchantColour.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiEnchantColour.java @@ -271,17 +271,21 @@ public class GuiEnchantColour extends GuiScreen { } if (mouseX >= guiLeft + xSize + 3 && mouseX < guiLeft + xSize + 39) { + boolean renderingTooltip = false; + if (mouseY >= guiTopSidebar - 34 && mouseY <= guiTopSidebar - 18 && maxedBookFound == 1) { tooltipToDisplay = maxedBook.getTooltip(Minecraft.getMinecraft().thePlayer, false); Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); tooltipToDisplay = null; + renderingTooltip = true; } - if (mouseY >= guiTopSidebar - 52 && mouseY <= guiTopSidebar - 34 && maxedAttBookFound == 1) { + if (mouseY >= guiTopSidebar - 52 && mouseY <= guiTopSidebar - 34 && maxedAttBookFound == 1 && !renderingTooltip) { tooltipToDisplay = maxedAttBook.getTooltip(Minecraft.getMinecraft().thePlayer, false); Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); tooltipToDisplay = null; + renderingTooltip = true; } - if (mouseY >= guiTopSidebar - 18 && mouseY <= guiTopSidebar - 2) { + if (mouseY >= guiTopSidebar - 18 && mouseY <= guiTopSidebar - 2 && !renderingTooltip) { tooltipToDisplay = Lists.newArrayList( EnumChatFormatting.AQUA + "NEUEC Colouring Guide", EnumChatFormatting.GREEN + "", diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiInvButtonEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiInvButtonEditor.java index 40e12e35..7aa0d2ec 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiInvButtonEditor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiInvButtonEditor.java @@ -25,11 +25,13 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; +import io.github.moulberry.notenoughupdates.NEUOverlay; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.GlScissorStack; import io.github.moulberry.notenoughupdates.core.GuiElementTextField; import io.github.moulberry.notenoughupdates.core.util.lerp.LerpingInteger; import io.github.moulberry.notenoughupdates.options.NEUConfig; +import io.github.moulberry.notenoughupdates.overlays.EquipmentOverlay; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; @@ -83,6 +85,15 @@ public class GuiInvButtonEditor extends GuiScreen { private int guiLeft; private int guiTop; + //region getGuiCoordinates + public int getGuiLeft() { + return this.guiLeft; + } + public int getGuiTop() { + return this.guiTop; + } + //endregion + private static final int BACKGROUND_TYPES = 5; private static final int ICON_TYPES = 3; private int iconTypeIndex = 0; @@ -316,6 +327,13 @@ public class GuiInvButtonEditor extends GuiScreen { GlStateManager.color(1, 1, 1, 1); Utils.drawTexturedRect(guiLeft, guiTop, xSize, ySize, 0, xSize / 256f, 0, ySize / 256f, GL11.GL_NEAREST); + if (NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud) { + EquipmentOverlay.INSTANCE.renderPreviewArmorHud(); + } + if (NotEnoughUpdates.INSTANCE.config.petOverlay.petInvDisplay) { + EquipmentOverlay.INSTANCE.renderPreviewPetInvHud(); + } + for (NEUConfig.InventoryButton button : NotEnoughUpdates.INSTANCE.config.hidden.inventoryButtons) { int x = guiLeft + button.x; int y = guiTop + button.y; @@ -326,6 +344,17 @@ public class GuiInvButtonEditor extends GuiScreen { y += ySize; } + if (NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud) { + if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop && y < guiTop + 84) { + x -= 25; + } + } + if (NotEnoughUpdates.INSTANCE.config.petOverlay.petInvDisplay) { + if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop + 60 && y < guiTop + 120) { + x -= 25; + } + } + if (button.isActive()) { GlStateManager.color(1, 1, 1, 1f); } else { @@ -358,7 +387,7 @@ public class GuiInvButtonEditor extends GuiScreen { Minecraft.getMinecraft().getTextureManager().bindTexture(custom_ench_colour); GlStateManager.color(1, 1, 1, 1); Utils.drawTexturedRect( - guiLeft - 88 - 2 - 22, + guiLeft - 88 - 2 - 22 - (NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud ? 25 : 0), guiTop + 2, 88, 20, @@ -369,7 +398,7 @@ public class GuiInvButtonEditor extends GuiScreen { GL11.GL_NEAREST ); Utils.drawTexturedRect( - guiLeft - 88 - 2 - 22, + guiLeft - 88 - 2 - 22 - (NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud ? 25 : 0), guiTop + 2 + 24, 88, 20, @@ -382,7 +411,7 @@ public class GuiInvButtonEditor extends GuiScreen { Utils.drawStringCenteredScaledMaxWidth( "Load preset", fontRendererObj, - guiLeft - 44 - 2 - 22, + guiLeft - 44 - 2 - 22 - (NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud ? 25 : 0), guiTop + 8, false, 86, @@ -391,7 +420,7 @@ public class GuiInvButtonEditor extends GuiScreen { Utils.drawStringCenteredScaledMaxWidth( "from Clipboard", fontRendererObj, - guiLeft - 44 - 2 - 22, + guiLeft - 44 - 2 - 22 - (NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud ? 25 : 0), guiTop + 16, false, 86, @@ -400,7 +429,7 @@ public class GuiInvButtonEditor extends GuiScreen { Utils.drawStringCenteredScaledMaxWidth( "Save preset", fontRendererObj, - guiLeft - 44 - 2 - 22, + guiLeft - 44 - 2 - 22 - (NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud ? 25 : 0), guiTop + 8 + 24, false, 86, @@ -409,7 +438,7 @@ public class GuiInvButtonEditor extends GuiScreen { Utils.drawStringCenteredScaledMaxWidth( "to Clipboard", fontRendererObj, - guiLeft - 44 - 2 - 22, + guiLeft - 44 - 2 - 22 - (NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud ? 25 : 0), guiTop + 16 + 24, false, 86, @@ -417,7 +446,7 @@ public class GuiInvButtonEditor extends GuiScreen { ); if (!validShareContents()) { - Gui.drawRect(guiLeft - 88 - 2 - 22, guiTop + 2, guiLeft - 2 - 22, guiTop + 2 + 20, 0x80000000); + Gui.drawRect(guiLeft - 88 - 2 - 22 - (NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud ? 25 : 0), guiTop + 2, guiLeft - 2 - 22 - (NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud ? 25 : 0), guiTop + 2 + 20, 0x80000000); } GlStateManager.color(1, 1, 1, 1); @@ -461,6 +490,17 @@ public class GuiInvButtonEditor extends GuiScreen { y += ySize; } + if (NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud) { + if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop && y < guiTop + 84) { + x -= 25; + } + } + if (NotEnoughUpdates.INSTANCE.config.petOverlay.petInvDisplay) { + if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop + 60 && y < guiTop + 120) { + x -= 25; + } + } + GlStateManager.translate(0, 0, 300); editorLeft = x + 8 - editorXSize / 2; editorTop = y + 18 + 2; @@ -741,6 +781,17 @@ public class GuiInvButtonEditor extends GuiScreen { y += ySize; } + if (NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud) { + if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop && y < guiTop + 84) { + x -= 25; + } + } + if (NotEnoughUpdates.INSTANCE.config.petOverlay.petInvDisplay) { + if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop + 60 && y < guiTop + 120) { + x -= 25; + } + } + if (mouseX >= x && mouseY >= y && mouseX <= x + 18 && mouseY <= y + 18) { if (editingButton == button) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/InventoryStorageSelector.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/InventoryStorageSelector.java index 0abf3f11..572b0fbf 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/InventoryStorageSelector.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/InventoryStorageSelector.java @@ -83,24 +83,26 @@ public class InventoryStorageSelector { return; } - if (KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowLeftKey)) { - NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex--; - - int max = StorageManager.getInstance().storageConfig.displayToStorageIdMap.size() - 1; - if (NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex > max) - NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex = max; - if (NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex < 0) - NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex = 0; - } else if (KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowRightKey)) { - NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex++; - - int max = StorageManager.getInstance().storageConfig.displayToStorageIdMap.size() - 1; - if (NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex > max) - NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex = max; - if (NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex < 0) - NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex = 0; - } else if (KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowDownKey)) { - sendToPage(NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex); + if (NotEnoughUpdates.INSTANCE.config.storageGUI.arrowKeyBackpacks) { + if (KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowLeftKey)) { + NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex--; + + int max = StorageManager.getInstance().storageConfig.displayToStorageIdMap.size() - 1; + if (NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex > max) + NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex = max; + if (NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex < 0) + NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex = 0; + } else if (KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowRightKey)) { + NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex++; + + int max = StorageManager.getInstance().storageConfig.displayToStorageIdMap.size() - 1; + if (NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex > max) + NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex = max; + if (NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex < 0) + NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex = 0; + } else if (KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowDownKey)) { + sendToPage(NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex); + } } if (isSlotSelected()) { @@ -145,27 +147,29 @@ public class InventoryStorageSelector { return; } - if (KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.backpackHotkey)) { - Minecraft.getMinecraft().thePlayer.inventory.currentItem = 0; - isOverridingSlot = true; - } else if (KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowLeftKey)) { - NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex--; - - int max = StorageManager.getInstance().storageConfig.displayToStorageIdMap.size() - 1; - if (NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex > max) - NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex = max; - if (NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex < 0) - NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex = 0; - } else if (KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowRightKey)) { - NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex++; - - int max = StorageManager.getInstance().storageConfig.displayToStorageIdMap.size() - 1; - if (NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex > max) - NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex = max; - if (NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex < 0) - NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex = 0; - } else if (KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowDownKey)) { - sendToPage(NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex); + if (NotEnoughUpdates.INSTANCE.config.storageGUI.arrowKeyBackpacks) { + if (KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.backpackHotkey)) { + Minecraft.getMinecraft().thePlayer.inventory.currentItem = 0; + isOverridingSlot = true; + } else if (KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowLeftKey)) { + NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex--; + + int max = StorageManager.getInstance().storageConfig.displayToStorageIdMap.size() - 1; + if (NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex > max) + NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex = max; + if (NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex < 0) + NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex = 0; + } else if (KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowRightKey)) { + NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex++; + + int max = StorageManager.getInstance().storageConfig.displayToStorageIdMap.size() - 1; + if (NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex > max) + NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex = max; + if (NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex < 0) + NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex = 0; + } else if (KeybindHelper.isKeyPressed(NotEnoughUpdates.INSTANCE.config.storageGUI.arrowDownKey)) { + sendToPage(NotEnoughUpdates.INSTANCE.config.storageGUI.selectedIndex); + } } if (isSlotSelected()) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/StorageOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/StorageOverlay.java index 7e6b991c..8878c284 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/StorageOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/StorageOverlay.java @@ -45,13 +45,17 @@ import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.entity.RenderItem; import net.minecraft.client.shader.Framebuffer; +import net.minecraft.event.ClickEvent; +import net.minecraft.event.HoverEvent; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.inventory.ContainerChest; import net.minecraft.inventory.Slot; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IChatComponent; import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.ClientCommandHandler; import org.lwjgl.input.Keyboard; @@ -414,7 +418,7 @@ public class StorageOverlay extends GuiElement { if (stackOnMouse != null) { String stackDisplay = Utils.cleanColour(stackOnMouse.getDisplayName()); if (stackDisplay.startsWith("Backpack Slot ") || stackDisplay.startsWith("Empty Backpack Slot ") || - stackDisplay.startsWith("Ender Chest Page ")) { + stackDisplay.startsWith("Ender Chest Page ") || stackDisplay.startsWith("Locked Backpack Slot ")) { stackOnMouse = null; } } @@ -1966,6 +1970,16 @@ public class StorageOverlay extends GuiElement { switch (buttonIndex) { case 0: NotEnoughUpdates.INSTANCE.config.storageGUI.enableStorageGUI3 = false; + ChatComponentText storageMessage = new ChatComponentText( + EnumChatFormatting.YELLOW + "[NEU] " + EnumChatFormatting.YELLOW + + "You just disabled the custom storage gui, did you mean to do that? If not click this message to turn it back on."); + storageMessage.setChatStyle(Utils.createClickStyle(ClickEvent.Action.RUN_COMMAND, "/neuenablestorage")); + storageMessage.setChatStyle(storageMessage.getChatStyle().setChatHoverEvent( + new HoverEvent(HoverEvent.Action.SHOW_TEXT, + new ChatComponentText(EnumChatFormatting.YELLOW + "Click to enable the custom storage gui.")))); + ChatComponentText storageChatMessage = new ChatComponentText(""); + storageChatMessage.appendSibling(storageMessage); + Minecraft.getMinecraft().thePlayer.addChatMessage(storageChatMessage); break; case 1: int size = diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TradeWindow.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TradeWindow.java index 8a0353d3..16b5015b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TradeWindow.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TradeWindow.java @@ -1078,7 +1078,7 @@ public class TradeWindow { !SlotLocking.getInstance().isSlotLocked(slot)) { Minecraft.getMinecraft().playerController.windowClick( chest.inventorySlots.windowId, - slot.slotNumber, 2, 3, Minecraft.getMinecraft().thePlayer + slot.slotNumber, 0, 0, Minecraft.getMinecraft().thePlayer ); } return; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/hex/EnchantState.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/hex/EnchantState.java new file mode 100644 index 00000000..08e720a2 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/hex/EnchantState.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.miscgui.hex; + +enum EnchantState { + NO_ITEM, + ADDING_ENCHANT, + SWITCHING_DONT_UPDATE, + INVALID_ITEM, + HAS_ITEM, + HAS_ITEM_IN_HEX, + HAS_ITEM_IN_BOOKS, + ADDING_BOOK, + NO_ITEM_IN_HEX, + INVALID_ITEM_HEX, + HAS_ITEM_IN_GEMSTONE, + ADDING_GEMSTONE, + APPLYING_GEMSTONE + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/hex/GuiCustomHex.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/hex/GuiCustomHex.java new file mode 100644 index 00000000..5361ae89 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/hex/GuiCustomHex.java @@ -0,0 +1,4885 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.miscgui.hex; + +import com.google.common.collect.Lists; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.GlScissorStack; +import io.github.moulberry.notenoughupdates.core.GuiElementTextField; +import io.github.moulberry.notenoughupdates.core.util.lerp.LerpingFloat; +import io.github.moulberry.notenoughupdates.core.util.lerp.LerpingInteger; +import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking; +import io.github.moulberry.notenoughupdates.miscgui.CalendarOverlay; +import io.github.moulberry.notenoughupdates.miscgui.util.OrbDisplay; +import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer; +import io.github.moulberry.notenoughupdates.options.NEUConfig; +import io.github.moulberry.notenoughupdates.util.Constants; +import io.github.moulberry.notenoughupdates.util.ItemUtils; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.model.ModelBook; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.inventory.ContainerChest; +import net.minecraft.inventory.Slot; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.network.play.client.C0EPacketClickWindow; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import org.apache.commons.lang3.text.WordUtils; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.glu.Project; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.Random; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class GuiCustomHex extends Gui { + private static final GuiCustomHex INSTANCE = new GuiCustomHex(); + private static final ResourceLocation TEXTURE = new ResourceLocation("notenoughupdates:custom_enchant_gui.png"); + private static final ResourceLocation ENCHANTMENT_TABLE_BOOK_TEXTURE = new ResourceLocation( + "textures/entity/enchanting_table_book.png"); + private static final ModelBook MODEL_BOOK = new ModelBook(); + + private static final int EXPERIENCE_ORB_COUNT = 30; + + private static final Pattern XP_COST_PATTERN = Pattern.compile("\\u00a73(\\d+) Exp Levels"); + private static final Pattern ENCHANT_LEVEL_PATTERN = Pattern.compile("(.*)_(.*)"); + private static final Pattern ENCHANT_NAME_PATTERN = Pattern.compile("([^IVX]*) ([IVX]*)"); + + public static final NumberFormat numberFormat = NumberFormat.getInstance(Locale.US); + + public class Enchantment { + public int slotIndex; + public String enchantName; + public String enchId; + public List<String> displayLore; + public int level; + public int xpCost = -1; + public boolean overMaxLevel = false; + public boolean conflicts = false; + public int price = -1; + + public Enchantment( + int slotIndex, String enchantName, String enchId, List<String> displayLore, int level, + boolean useMaxLevelForCost, boolean checkConflicts + ) { + this.slotIndex = slotIndex; + this.enchantName = enchantName; + this.enchId = enchId; + this.displayLore = displayLore; + this.level = level; + boolean isUlt = false; + for (String lore : displayLore) { + if (lore.contains("§l")) isUlt = true; + break; + } + JsonObject bazaarInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo( + (isUlt ? "ULTIMATE_" : "") + enchId.toUpperCase() + ";" + level); + if (bazaarInfo != null && bazaarInfo.get("curr_buy") != null) { + this.price = bazaarInfo.get("curr_buy").getAsInt(); + } + this.enchId = ItemUtils.fixEnchantId(this.enchId, true); + + if (Constants.ENCHANTS != null) { + if (checkConflicts && Constants.ENCHANTS.has("enchant_pools")) { + JsonArray pools = Constants.ENCHANTS.getAsJsonArray("enchant_pools"); + out: + for (int i = 0; i < pools.size(); i++) { + JsonArray pool = pools.get(i).getAsJsonArray(); + + boolean hasThis = false; + boolean hasApplied = false; + + for (int j = 0; j < pool.size(); j++) { + String enchIdPoolElement = pool.get(j).getAsString(); + if (this.enchId.equalsIgnoreCase(enchIdPoolElement)) { + hasThis = true; + } else if (playerEnchantIds.containsKey(enchIdPoolElement)) { + hasApplied = true; + } + if (hasThis && hasApplied) { + this.conflicts = true; + break out; + } + } + } + } + + if (level >= 1 && Constants.ENCHANTS.has("enchants_xp_cost")) { + JsonObject allCosts = Constants.ENCHANTS.getAsJsonObject("enchants_xp_cost"); + JsonObject maxLevel = null; + if (NotEnoughUpdates.INSTANCE.config.enchantingSolvers.maxEnchLevel && Constants.ENCHANTS.has( + "max_xp_table_levels")) { + maxLevel = Constants.ENCHANTS.getAsJsonObject("max_xp_table_levels"); + } + + if (allCosts.has(this.enchId)) { + JsonArray costs = allCosts.getAsJsonArray(this.enchId); + + if (costs.size() >= 1) { + if (useMaxLevelForCost) { + int cost = + (maxLevel != null && maxLevel.has(this.enchId) ? maxLevel.get(this.enchId).getAsInt() : costs.size()); + this.xpCost = costs.get(cost - 1).getAsInt(); + } else if (level - 1 < costs.size()) { + this.xpCost = costs.get(level - 1).getAsInt(); + } else { + overMaxLevel = true; + } + } + } + + } + } + } + } + + public OrbDisplay orbDisplay = new OrbDisplay(); + + private int guiLeft; + private int guiTop; + private boolean shouldOverrideFast = false; + private boolean shouldOverrideET = false; + private boolean shouldOverrideGemstones = false; + private boolean shouldOverrideXp = false; + public float pageOpen; + public float pageOpenLast; + public float pageOpenRandom; + public float pageOpenVelocity; + public float bookOpen; + public float bookOpenLast; + + private int currentPage; + private int expectedMaxPage; + + private boolean isScrollingLeft = true; + + private ItemStack enchantingItem = null; + + private int removingEnchantPlayerLevel = -1; + + private final GuiElementTextField searchField = new GuiElementTextField("", GuiElementTextField.SCISSOR_TEXT); + + private final HashMap<String, Integer> playerEnchantIds = new HashMap<>(); + + private boolean searchRemovedFromApplicable = false; + private boolean searchRemovedFromRemovable = false; + private final List<Enchantment> applicable = new ArrayList<>(); + private final List<Enchantment> removable = new ArrayList<>(); + + private final List<HexItem> applicableItem = new ArrayList<>(); + private final List<HexItem> removableItem = new ArrayList<>(); + private final HashMap<Integer, Enchantment> enchanterEnchLevels = new HashMap<>(); + private final HashMap<Integer, HexItem> enchanterItemLevels = new HashMap<>(); + private Enchantment enchanterCurrentEnch = null; + private HexItem enchanterCurrentItem = null; + + public Random random = new Random(); + + private EnchantState currentState = EnchantState.NO_ITEM; + private EnchantState lastState = EnchantState.NO_ITEM; + + private final LerpingInteger leftScroll = new LerpingInteger(0, 150); + private final LerpingInteger rightScroll = new LerpingInteger(0, 150); + + private final LerpingFloat arrowAmount = new LerpingFloat(0, 100); + + private static final int X_SIZE = 364; + private static final int Y_SIZE = 215; + + private int clickedScrollOffset = -1; + private boolean isClickedScrollLeft = true; + + private boolean isChangingEnchLevel = false; + + private long cancelButtonAnimTime = 0; + private long confirmButtonAnimTime = 0; + + public static GuiCustomHex getInstance() { + return INSTANCE; + } + + public boolean shouldOverride(String containerName) { + CalendarOverlay.ableToClickCalendar = true; + if (containerName == null) { + shouldOverrideET = false; + shouldOverrideFast = false; + shouldOverrideGemstones = false; + shouldOverrideXp = false; + searchField.setText(""); + return false; + } + boolean config = NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enableHexGUI; + final List<String> gemList = new ArrayList<>(Arrays.asList( + "\u2764", + "\u2748", + "\u270e", + "\u2618", + "\u2e15", + "\u2727", + "\u2741", + "\u2742" + )); + shouldOverrideFast = config && + (containerName.length() >= 7 && Objects.equals("The Hex", containerName.substring(0, "The Hex".length()))) && + NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard(); + + shouldOverrideET = config && + (containerName.length() >= 12 && Objects.equals( + "Enchant Item", + containerName.substring(0, "Enchant Item".length()) + )) && NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard(); + + shouldOverrideGemstones = config && + (containerName.length() >= 12 && Objects.equals( + "Gemstones ➜", + containerName.substring(0, "Gemstones ➜".length()) + )) && NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard(); + if (shouldOverrideGemstones) { + for (String string : gemList) { + if (containerName.contains(string)) { + shouldOverrideGemstones = false; + break; + } + } + } + + shouldOverrideXp = config && + (containerName.length() >= 21 && Objects.equals( + "Bottles of Enchanting", + containerName.substring(0, "Bottles of Enchanting".length()) + )) && + NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard(); + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + ContainerChest cc = (ContainerChest) chest.inventorySlots; + ItemStack hexStack = cc.getLowerChestInventory().getStackInSlot(50); + CalendarOverlay.ableToClickCalendar = + !(shouldOverrideET || shouldOverrideFast || shouldOverrideGemstones || shouldOverrideXp); + if (hexStack != null && hexStack.getItem() == Items.experience_bottle) + return (shouldOverrideET || shouldOverrideFast); + if (!shouldOverrideFast && !shouldOverrideET && !shouldOverrideGemstones && !shouldOverrideXp) { + currentState = EnchantState.NO_ITEM; + applicable.clear(); + removable.clear(); + applicableItem.clear(); + removableItem.clear(); + expectedMaxPage = 1; + enchanterCurrentItem = null; + searchField.setText(""); + } + return (shouldOverrideFast || shouldOverrideGemstones || shouldOverrideXp); + } + + private int tickCounter = 0; + + public void tick(String containerName) { + if (containerName.equals("The Hex")) { + currentState = EnchantState.HAS_ITEM_IN_HEX; + tickHex(); + } else if (containerName.contains("Enchant Item")) { + tickEnchants(); + } else if (containerName.contains("Books") || containerName.contains("Modifiers") || containerName.contains( + "Reforges") || containerName.contains("Item Upgrades") || containerName.equals("Bottles of Enchanting")) { + tickBooks(); + } else if (containerName.contains("Gemstones")) { + tickGemstones(); + } else { + tickBooks(); + } + } + + private void tickEnchants() { + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + ContainerChest cc = (ContainerChest) chest.inventorySlots; + + //ItemStack hexStack = cc.getLowerChestInventory().getStackInSlot(12); + ItemStack enchantingItemStack = cc.getLowerChestInventory().getStackInSlot(19); + //ItemStack stack = cc.getLowerChestInventory().getStackInSlot(23); + ItemStack hopperStack = cc.getLowerChestInventory().getStackInSlot(51); + + int lastPage = currentPage; + + this.lastState = currentState; + + if (hopperStack != null && hopperStack.getItem() != Item.getItemFromBlock(Blocks.hopper) && + enchantingItem != null) { + currentState = EnchantState.ADDING_ENCHANT; + } else if (enchantingItemStack == null) { + if (currentState == EnchantState.SWITCHING_DONT_UPDATE || currentState == EnchantState.NO_ITEM) { + currentState = EnchantState.NO_ITEM; + } else { + currentState = EnchantState.SWITCHING_DONT_UPDATE; + } + } else { + ItemStack sanityCheckStack = cc.getLowerChestInventory().getStackInSlot(12); + if (sanityCheckStack == null || sanityCheckStack.getItem() == Items.enchanted_book) { + currentState = EnchantState.HAS_ITEM; + enchantingItem = enchantingItemStack; + } else { + currentState = EnchantState.SWITCHING_DONT_UPDATE; + } + } + + if (currentState == EnchantState.HAS_ITEM) { + ItemStack pageUpStack = cc.getLowerChestInventory().getStackInSlot(17); + ItemStack pageDownStack = cc.getLowerChestInventory().getStackInSlot(35); + if (pageUpStack != null && pageDownStack != null) { + currentPage = 0; + boolean upIsGlass = pageUpStack.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane); + boolean downIsGlass = pageDownStack.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane); + int page = -1; + + expectedMaxPage = 1; + if (!downIsGlass) { + try { + page = Integer.parseInt(Utils.getRawTooltip(pageDownStack).get(1).substring(11)) - 1; + expectedMaxPage = page + 1; + } catch (Exception ignored) { + } + } + if (page == -1 && !upIsGlass) { + try { + page = Integer.parseInt(Utils.getRawTooltip(pageUpStack).get(1).substring(11)) + 1; + expectedMaxPage = page; + } catch (Exception ignored) { + } + } + if (page == -1) { + currentPage = 1; + } else { + currentPage = page; + } + } + } + + orbDisplay.physicsTickOrbs(); + + if (++tickCounter >= 20) { + tickCounter = 0; + } + + boolean updateItems = tickCounter == 0; + + if (currentState == EnchantState.ADDING_ENCHANT) { + if (arrowAmount.getTarget() != 1) { + arrowAmount.setTarget(1); + arrowAmount.resetTimer(); + } + } else { + if (arrowAmount.getTarget() != 0) { + arrowAmount.setTarget(0); + arrowAmount.resetTimer(); + } + } + + // Set<EnchantState> allowedSwitchStates = Sets.newHashSet(EnchantState.ADDING_ENCHANT, EnchantState.HAS_ITEM, EnchantState.SWITCHING_DONT_UPDATE); + if (lastState != currentState || lastPage != currentPage) { + // if (!allowedSwitchStates.contains(lastState) || !allowedSwitchStates.contains(currentState)) { + leftScroll.setValue(0); + rightScroll.setValue(0); + // } + updateItems = true; + } + + if (updateItems && currentState != EnchantState.SWITCHING_DONT_UPDATE) { + enchanterEnchLevels.clear(); + + if (enchantingItem != null) { + playerEnchantIds.clear(); + NBTTagCompound tag = enchantingItem.getTagCompound(); + if (tag != null) { + NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes"); + if (ea != null) { + NBTTagCompound enchantments = ea.getCompoundTag("enchantments"); + if (enchantments != null) { + for (String enchId : enchantments.getKeySet()) { + playerEnchantIds.put(enchId, enchantments.getInteger(enchId)); + } + } + } + } + } + + if (currentState == EnchantState.ADDING_ENCHANT) { + removingEnchantPlayerLevel = -1; + boolean updateLevel = enchanterCurrentEnch == null; + boolean hasXpBottle = false; + for (int i = 0; i < 27; i++) { + int slotIndex = 9 + i; + ItemStack book = cc.getLowerChestInventory().getStackInSlot(slotIndex); + ItemStack xpBottle = cc.getLowerChestInventory().getStackInSlot(50); + if (!hasXpBottle && xpBottle != null && + xpBottle.getItem() == Items.experience_bottle) { + String name = "Buy Xp Bottles"; + String id = "XP_BOTTLE"; + Enchantment xpBottleEnch = new Enchantment(50, name, id, + Utils.getRawTooltip(xpBottle), 1, true, false + ); + boolean hasHasXpBottle = false; + for (Enchantment ench : applicable) { + if (ench.enchId.equals("XP_BOTTLE")) { + hasHasXpBottle = true; + break; + } + } + if (!hasHasXpBottle) applicable.add(xpBottleEnch); + hasXpBottle = true; + } + if (book != null && book.getItem() == Items.enchanted_book) { + NBTTagCompound tagBook = book.getTagCompound(); + if (tagBook != null) { + NBTTagCompound ea = tagBook.getCompoundTag("ExtraAttributes"); + if (ea != null) { + NBTTagCompound enchantments = ea.getCompoundTag("enchantments"); + if (enchantments != null) { + String enchId = Utils + .cleanColour(book.getDisplayName()) + .toLowerCase() + .replace(" ", "_") + .replace("-", "_") + .replaceAll("[^a-z_]", ""); + String name = Utils.cleanColour(book.getDisplayName()); + int enchLevel = -1; + if (name.equalsIgnoreCase("Bane of Arthropods")) { + name = "Bane of Arth."; + } else if (name.equalsIgnoreCase("Projectile Protection")) { + name = "Projectile Prot"; + } else if (name.equalsIgnoreCase("Blast Protection")) { + name = "Blast Prot"; + } else if (name.equalsIgnoreCase("Turbo-Mushrooms")) { + name = "Turbo-Mush"; + } + Matcher levelMatcher = ENCHANT_LEVEL_PATTERN.matcher(enchId); + if (levelMatcher.matches()) { + enchLevel = Utils.parseRomanNumeral(levelMatcher.group(2).toUpperCase()); + enchId = levelMatcher.group(1); + } + Enchantment enchantment = new Enchantment(slotIndex, name, enchId, + Utils.getRawTooltip(book), enchLevel, false, true + ); + int index = 0; + for (String lore : enchantment.displayLore) { + if (lore.contains("N/A") && enchantment.price > 0) { + String price = numberFormat.format(enchantment.price); + enchantment.displayLore.set(index, "\u00a76" + price + ".0 Coins"); + } + if (lore.contains("Loading...")) { + if (enchantment.price > 0) { + enchantment.displayLore.set(index, "\u00a7eClick to buy on the Bazaar!"); + } else { + enchantment.displayLore.set(index, "\u00a7cNot enough supply on the Bazaar!"); + } + } + index++; + } + enchantment.displayLore.remove(0); + + if (removingEnchantPlayerLevel == -1 && playerEnchantIds.containsKey(enchId)) { + removingEnchantPlayerLevel = playerEnchantIds.get(enchId); + } + + if (removingEnchantPlayerLevel >= 0 && enchantment.level < removingEnchantPlayerLevel) { + continue; + } + + boolean aboveMaxLevelFromEt = false; + if (NotEnoughUpdates.INSTANCE.config.enchantingSolvers.maxEnchLevel && Constants.ENCHANTS != null) { + JsonObject maxLevel = null; + if (Constants.ENCHANTS.has("max_xp_table_levels")) { + maxLevel = Constants.ENCHANTS.getAsJsonObject("max_xp_table_levels"); + } + if (maxLevel != null && maxLevel.has(enchId)) { + if (enchantment.level > maxLevel.get(enchId).getAsInt()) { + aboveMaxLevelFromEt = true; + } + } + } + + if (enchanterCurrentEnch == null) { + enchanterCurrentEnch = enchantment; + } else if (updateLevel) { + if (removingEnchantPlayerLevel < 0 && enchantment.level > enchanterCurrentEnch.level && !aboveMaxLevelFromEt) { + enchanterCurrentEnch = enchantment; + } else if (removingEnchantPlayerLevel >= 0 && enchantment.level < enchanterCurrentEnch.level) { + enchanterCurrentEnch = enchantment; + } + } + + enchanterEnchLevels.put(enchantment.level, enchantment); + } + } + } + } + } + if (enchanterCurrentEnch != null && removingEnchantPlayerLevel >= 0) { + for (String line : enchanterCurrentEnch.displayLore) { + Matcher matcher = XP_COST_PATTERN.matcher(line); + if (matcher.find()) { + enchanterCurrentEnch.xpCost = Integer.parseInt(matcher.group(1)); + } + } + } + } else { + isChangingEnchLevel = false; + enchanterCurrentEnch = null; + + searchRemovedFromRemovable = false; + searchRemovedFromApplicable = false; + applicable.clear(); + removable.clear(); + boolean hasXpBottle = false; + if (currentState == EnchantState.HAS_ITEM) { + for (int i = 0; i < 15; i++) { + int slotIndex = 12 + (i % 5) + (i / 5) * 9; + ItemStack book = cc.getLowerChestInventory().getStackInSlot(slotIndex); + ItemStack xpBottle = cc.getLowerChestInventory().getStackInSlot(50); + if (!hasXpBottle && xpBottle != null && + xpBottle.getItem() == Items.experience_bottle) { + String name = "Buy Xp Bottles"; + String id = "XP_BOTTLE"; + Enchantment xpBottleEnch = new Enchantment(50, name, id, + Utils.getRawTooltip(xpBottle), 1, true, false + ); + applicable.add(xpBottleEnch); + hasXpBottle = true; + } + if (book != null) { + NBTTagCompound tagBook = book.getTagCompound(); + if (tagBook != null) { + NBTTagCompound ea = tagBook.getCompoundTag("ExtraAttributes"); + if (ea != null) { + NBTTagCompound enchantments = ea.getCompoundTag("enchantments"); + if (enchantments != null) { + String enchId = Utils + .cleanColour(book.getDisplayName()) + .toLowerCase() + .replace(" ", "_") + .replace("-", "_") + .replaceAll("[^a-z_]", ""); + if (enchId.equalsIgnoreCase("_")) continue; + enchId = ItemUtils.fixEnchantId(enchId, true); + String name = Utils.cleanColour(book.getDisplayName()); + + if (searchField.getText().trim().isEmpty() || + name.toLowerCase().contains(searchField.getText().trim().toLowerCase())) { + if (name.equalsIgnoreCase("Bane of Arthropods")) { + name = "Bane of Arth."; + } else if (name.equalsIgnoreCase("Projectile Protection")) { + name = "Projectile Prot"; + } else if (name.equalsIgnoreCase("Blast Protection")) { + name = "Blast Prot"; + } else if (name.equalsIgnoreCase("Turbo-Mushrooms")) { + name = "Turbo-Mush"; + } + Matcher nameMatcher = ENCHANT_NAME_PATTERN.matcher(name); + if (nameMatcher.matches()) { + name = nameMatcher.group(1); + } + + if (playerEnchantIds.containsKey(enchId)) { + Enchantment enchantment = new Enchantment(slotIndex, name, enchId, + Utils.getRawTooltip(book), playerEnchantIds.get(enchId), false, false + ); + if (!enchantment.overMaxLevel) { + removable.add(enchantment); + } + } else { + Enchantment enchantment = new Enchantment(slotIndex, name, enchId, + Utils.getRawTooltip(book), 1, true, true + ); + applicable.add(enchantment); + } + } else { + if (playerEnchantIds.containsKey(enchId)) { + searchRemovedFromRemovable = true; + } else { + searchRemovedFromApplicable = true; + } + } + + } + } + } + } + } + NEUConfig cfg = NotEnoughUpdates.INSTANCE.config; + int mult = cfg.enchantingSolvers.enchantOrdering == 0 ? 1 : -1; + Comparator<Enchantment> comparator = cfg.enchantingSolvers.enchantSorting == 0 ? + Comparator.comparingInt(e -> mult * e.xpCost) : + (c1, c2) -> mult * + c1.enchId.toLowerCase().compareTo(c2.enchId.toLowerCase()); + removable.sort(comparator); + applicable.sort(comparator); + } + } + } + + //Update book model state + if (lastState != currentState) { + do { + this.pageOpenRandom += (float) (this.random.nextInt(4) - this.random.nextInt(4)); + + } while (!(this.pageOpen > this.pageOpenRandom + 1.0F) && !(this.pageOpen < this.pageOpenRandom - 1.0F)); + } + + this.pageOpenLast = this.pageOpen; + this.bookOpenLast = this.bookOpen; + + if (currentState == EnchantState.HAS_ITEM || currentState == EnchantState.ADDING_ENCHANT) { + this.bookOpen += 0.2F; + } else { + this.bookOpen -= 0.2F; + } + + this.bookOpen = MathHelper.clamp_float(this.bookOpen, 0.0F, 1.0F); + float f1 = (this.pageOpenRandom - this.pageOpen) * 0.4F; + f1 = MathHelper.clamp_float(f1, -0.2F, 0.2F); + this.pageOpenVelocity += (f1 - this.pageOpenVelocity) * 0.9F; + this.pageOpen += this.pageOpenVelocity; + } + + private void tickBooks() { + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + ContainerChest cc = (ContainerChest) chest.inventorySlots; + + ItemStack enchantingItemStack = cc.getLowerChestInventory().getStackInSlot(19); + ItemStack anvilStack = cc.getLowerChestInventory().getStackInSlot(28); + + this.lastState = currentState; + + if (anvilStack != null && anvilStack.getItem() == Item.getItemFromBlock(Blocks.anvil) && + currentState != EnchantState.ADDING_BOOK) { + currentState = EnchantState.HAS_ITEM_IN_BOOKS; + enchantingItem = enchantingItemStack; + } else if (currentState == EnchantState.HAS_ITEM_IN_BOOKS && enchantingItem == null && + enchantingItemStack != null) { + enchantingItem = enchantingItemStack; + } else if (anvilStack != null && anvilStack.getItem() == Item.getItemFromBlock(Blocks.enchanting_table) && + currentState != EnchantState.ADDING_BOOK) { + currentState = EnchantState.HAS_ITEM_IN_BOOKS; + enchantingItem = enchantingItemStack; + } + + orbDisplay.physicsTickOrbs(); + + if (++tickCounter >= 20) { + tickCounter = 0; + } + + if (currentState == EnchantState.ADDING_BOOK) { + if (arrowAmount.getTarget() != 1) { + arrowAmount.setTarget(1); + arrowAmount.resetTimer(); + } + } else { + if (arrowAmount.getTarget() != 0) { + arrowAmount.setTarget(0); + arrowAmount.resetTimer(); + } + } + + isChangingEnchLevel = false; + + searchRemovedFromRemovable = false; + searchRemovedFromApplicable = false; + if (applicableItem.size() < 6) leftScroll.setValue(0); + applicableItem.clear(); + removableItem.clear(); + if (currentState == EnchantState.HAS_ITEM_IN_BOOKS || currentState == EnchantState.ADDING_BOOK) { + boolean hasRandomReforge = false; + for (int i = 0; i < 15; i++) { + int slotIndex = 12 + (i % 5) + (i / 5) * 9; + ItemStack book = cc.getLowerChestInventory().getStackInSlot(slotIndex); + ItemStack randomReforge = cc.getLowerChestInventory().getStackInSlot(48); + if (!hasRandomReforge && randomReforge != null && + randomReforge.getItem() == Item.getItemFromBlock(Blocks.anvil)) { + String name = Utils.cleanColour(randomReforge.getDisplayName()); + String id = Utils.cleanColour(randomReforge.getDisplayName()); + if (name.equals("Convert to Dungeon Item")) { + name = "Dungeonize Item"; + id = "CONVERT_TO_DUNGEON"; + } else if (name.equals("Random Basic Reforge")) { + name = "Basic Reforge"; + id = "RANDOM_REFORGE"; + } + HexItem reforgeItem = new HexItem(48, name, id, + Utils.getRawTooltip(randomReforge), true, true + ); + boolean hasAdded = false; + for (String lore : reforgeItem.displayLore) { + if (lore.contains("This item is already a Dungeon")) { + removableItem.add(reforgeItem); + hasAdded = true; + break; + } + } + if (!hasAdded) applicableItem.add(reforgeItem); + hasRandomReforge = true; + } + if (book != null) { + NBTTagCompound tagBook = book.getTagCompound(); + if (tagBook != null) { + NBTTagCompound ea = tagBook.getCompoundTag("ExtraAttributes"); + if (ea != null) { + NBTTagCompound enchantments = ea.getCompoundTag("enchantments"); + if (enchantments != null) { + String itemId = Utils.cleanColour(book.getDisplayName()).toUpperCase().replace(" ", "_").replace( + "-", + "_" + ); + String name = Utils.cleanColour(book.getDisplayName()); + if (itemId.equalsIgnoreCase("_")) continue; + if (itemId.equalsIgnoreCase("Item_Maxed_Out")) continue; + if (searchField.getText().trim().isEmpty() || + name.toLowerCase().contains(searchField.getText().trim().toLowerCase())) { + if (name.equalsIgnoreCase("Hot Potato Book")) { + name = "Hot Potato"; + } else if (name.equalsIgnoreCase("Fuming Potato Book")) { + name = "Fuming Potato"; + } else if (name.equalsIgnoreCase("Recombobulator 3000")) { + name = "Recombobulator"; + } else if (name.contains("Power Scroll")) { + name = name.replace("Power ", ""); + } else if (name.contains("\u272a")) { + name = name.replaceAll("[^✪]*", ""); + } else if (name.equalsIgnoreCase("First Master Star")) { + name = "Master Star \u00a7c➊"; + } else if (name.equalsIgnoreCase("Second Master Star")) { + name = "Master Star \u00a7c➋"; + } else if (name.equalsIgnoreCase("Third Master Star")) { + name = "Master Star \u00a7c➌"; + } else if (name.equalsIgnoreCase("Fourth Master Star")) { + name = "Master Star \u00a7c➍"; + } else if (name.equalsIgnoreCase("Fifth Master Star")) { + name = "Master Star \u00a7c➎"; + } else if (name.equalsIgnoreCase("The Art Of Peace")) { + name = "Art Of Peace"; + } else if (name.equalsIgnoreCase("Mana Disintegrator")) { + name = "M Disintegrator"; + } + /*if (playerEnchantIds.containsKey(itemId)) { + HexItem item = new HexItem(slotIndex, name, itemId, + Utils.getRawTooltip(book), false, false + ); + if (!item.overMaxLevel) { + removableItem.add(item); + } + enchanterItemLevels.put(item.level, item); + } else */ + { + HexItem item = new HexItem(slotIndex, name, itemId, + Utils.getRawTooltip(book), true, true + ); + enchanterItemLevels.put(item.level, item); + if (item.itemType != ItemType.UNKNOWN) { + int potatoCount = 0; + int killCount = 0; + int warCount = 0; + int ffdCount = 0; + int recombCount = 0; + int effLevel = 0; + int starCount = 0; + int singularityCount = 0; + int tunerCount = 0; + int peaceCount = 0; + int manaDisintegratorCount = 0; + boolean shadowWarp = false; + boolean witherShield = false; + boolean implosion = false; + String reforge = ""; + if (enchantingItem != null) { + NBTTagCompound tagItem = enchantingItem.getTagCompound(); + if (tagItem != null) { + NBTTagCompound extra = tagItem.getCompoundTag("ExtraAttributes"); + if (extra != null) { + potatoCount = extra.getInteger("hot_potato_count"); + killCount = extra.getInteger("stats_book"); + warCount = extra.getInteger("art_of_war_count"); + ffdCount = extra.getInteger("farming_for_dummies_count"); + recombCount = extra.getInteger("rarity_upgrades"); + starCount = extra.getInteger("upgrade_level"); + singularityCount = extra.getInteger("wood_singularity_count"); + tunerCount = extra.getInteger("tuned_transmission"); + peaceCount = extra.getInteger("art_of_peace_count"); + manaDisintegratorCount = extra.getInteger("mana_disintegrator_count"); + reforge = extra.getString("modifier"); + NBTTagCompound enchs = extra.getCompoundTag("enchantments"); + NBTTagList scrolls = extra.getTagList("ability_scroll", 8); + if (enchs != null) { + effLevel = enchs.getInteger("efficiency"); + } + if (scrolls != null) { + for (int index = 0; index < scrolls.tagCount(); index++) { + if (scrolls.getStringTagAt(index).equals("IMPLOSION_SCROLL")) { + implosion = true; + } else if (scrolls.getStringTagAt(index).equals("SHADOW_WARP_SCROLL")) { + shadowWarp = true; + } else if (scrolls.getStringTagAt(index).equals("WITHER_SHIELD_SCROLL")) { + witherShield = true; + } + } + } + } + } + } + if (item.itemName.length() > 14) item.itemName = item.itemName.substring(0, 14); + + if (item.itemType == ItemType.HOT_POTATO) { + if (potatoCount < 10) applicableItem.add(item); + else removableItem.add(item); + + } else if (item.itemType == ItemType.FUMING_POTATO) { + if (potatoCount >= 10 && potatoCount < 15) applicableItem.add(item); + else if (potatoCount >= 15) removableItem.add(item); + + } else if (item.itemType == ItemType.BOOK_OF_STATS) { + if (killCount > 0) removableItem.add(item); + else applicableItem.add(item); + + } else if (item.itemType == ItemType.ART_OF_WAR) { + if (warCount > 0) removableItem.add(item); + else applicableItem.add(item); + + } else if (item.itemType == ItemType.FARMING_DUMMY) { + if (ffdCount < 5) applicableItem.add(item); + else removableItem.add(item); + + } else if (item.itemType == ItemType.RECOMB) { + if (recombCount > 0) removableItem.add(item); + else applicableItem.add(item); + + } else if (item.itemType == ItemType.SILEX) { + if (effLevel >= 5 && effLevel < 10) applicableItem.add(item); + else if (effLevel == 10) removableItem.add(item); + + } else if (item.isPowerScroll()) { + applicableItem.add(item); + + } else if (item.isMasterStar()) { + applicableItem.add(item); + + } else if (item.isDungeonStar()) { + if (starCount >= item.itemType.getStarLevel()) removableItem.add(item); + else applicableItem.add(item); + + } else if (item.itemType == ItemType.WOOD_SINGULARITY) { + if (singularityCount > 0) removableItem.add(item); + else applicableItem.add(item); + + } else if (item.isHypeScroll()) { + if (shadowWarp) removableItem.add(item); + else if (implosion) removableItem.add(item); + else if (witherShield) removableItem.add(item); + else applicableItem.add(item); + + } else if (item.itemType == ItemType.TUNER) { + if (tunerCount >= 4) removableItem.add(item); + else applicableItem.add(item); + + } else if (item.itemType == ItemType.REFORGE) { + if (item.getReforge().equalsIgnoreCase(reforge) && !reforge.equals("")) removableItem.add(item); + else applicableItem.add(item); + + } else if (item.itemType == ItemType.ART_OF_PEACE) { + if (peaceCount > 0) removableItem.add(item); + else applicableItem.add(item); + + } else if (item.itemType == ItemType.MANA_DISINTEGRATOR) { + if (manaDisintegratorCount >= 10) removableItem.add(item); + else applicableItem.add(item); + + } else { + applicableItem.add(item); + } + } else { + applicableItem.add(item); + } + } + } else { + if (playerEnchantIds.containsKey(itemId)) { + searchRemovedFromRemovable = true; + } else { + searchRemovedFromApplicable = true; + } + } + } + } + } + } + } + NEUConfig cfg = NotEnoughUpdates.INSTANCE.config; + int mult = cfg.enchantingSolvers.enchantOrdering == 0 ? 1 : -1; + Comparator<HexItem> comparator = cfg.enchantingSolvers.enchantSorting == 0 ? + Comparator.comparingInt(e -> (int) (mult * e.price)) : + (c1, c2) -> mult * + c1.itemId.toLowerCase().compareTo(c2.itemId.toLowerCase()); + removableItem.sort(comparator); + applicableItem.sort(comparator); + } + } + + private void tickHex() { + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + ContainerChest cc = (ContainerChest) chest.inventorySlots; + + ItemStack enchantingItemStack = cc.getLowerChestInventory().getStackInSlot(22); + ItemStack glassStack = cc.getLowerChestInventory().getStackInSlot(12); + //ItemStack anvilStack = cc.getLowerChestInventory().getStackInSlot(28); + + this.lastState = currentState; + + if (enchantingItemStack != null) { + if (glassStack.getItem() != null && glassStack.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane)) { + if (glassStack.getItemDamage() == 14) { + currentState = EnchantState.INVALID_ITEM_HEX; + } else if (glassStack.getItemDamage() == 10) { + currentState = EnchantState.HAS_ITEM_IN_HEX; + } else { + currentState = EnchantState.NO_ITEM_IN_HEX; + } + enchantingItem = enchantingItemStack; + } + } else { + currentState = EnchantState.NO_ITEM_IN_HEX; + } + + orbDisplay.physicsTickOrbs(); + + if (++tickCounter >= 20) { + tickCounter = 0; + } + + if (currentState == EnchantState.ADDING_BOOK) { + if (arrowAmount.getTarget() != 1) { + arrowAmount.setTarget(1); + arrowAmount.resetTimer(); + } + } else { + if (arrowAmount.getTarget() != 0) { + arrowAmount.setTarget(0); + arrowAmount.resetTimer(); + } + } + + isChangingEnchLevel = false; + + searchRemovedFromRemovable = false; + searchRemovedFromApplicable = false; + applicableItem.clear(); + removableItem.clear(); + boolean hasHexItem = false; + if (currentState == EnchantState.HAS_ITEM_IN_HEX) { + for (int i = 0; i < 9; i++) { + int slotIndex = 15 + (i % 3) + (i / 3) * 9; + ItemStack book = cc.getLowerChestInventory().getStackInSlot(slotIndex); + if (!hasHexItem && glassStack != null) { + HexItem item = new HexItem(slotIndex, "Total Upgrades", "TOTAL_UPGRADES", + Utils.getRawTooltip(glassStack), true, true + ); + removableItem.add(item); + hasHexItem = true; + } + if (book != null) { + NBTTagCompound tagBook = book.getTagCompound(); + if (tagBook != null) { + NBTTagCompound ea = tagBook.getCompoundTag("ExtraAttributes"); + if (ea != null) { + NBTTagCompound enchantments = ea.getCompoundTag("enchantments"); + if (enchantments != null) { + String itemId = Utils.cleanColour(book.getDisplayName()).toUpperCase().replace(" ", "_").replace( + "-", + "_" + ); + String name = Utils.cleanColour(book.getDisplayName()); + if (itemId.equalsIgnoreCase("_")) continue; + if (itemId.equalsIgnoreCase("Item_Maxed_Out")) continue; + if (searchField.getText().trim().isEmpty() || + name.toLowerCase().contains(searchField.getText().trim().toLowerCase())) { + if (name.equalsIgnoreCase("Ultimate Enchantments")) { + name = "Ult Enchants"; + } + /*if (playerEnchantIds.containsKey(itemId)) { + HexItem item = new HexItem(slotIndex, name, itemId, + Utils.getRawTooltip(book), false, false + ); + if (!item.overMaxLevel) { + removableItem.add(item); + } + enchanterItemLevels.put(item.level, item); + } else */ + { + HexItem item = new HexItem(slotIndex, name, "HEX_ITEM" + i, + Utils.getRawTooltip(book), true, true + ); + enchanterItemLevels.put(item.level, item); + applicableItem.add(item); + } + } else { + if (playerEnchantIds.containsKey(itemId)) { + searchRemovedFromRemovable = true; + } else { + searchRemovedFromApplicable = true; + } + } + } + } + } + } + } + NEUConfig cfg = NotEnoughUpdates.INSTANCE.config; + int mult = cfg.enchantingSolvers.enchantOrdering == 0 ? 1 : -1; + Comparator<HexItem> comparator = cfg.enchantingSolvers.enchantSorting == 0 ? + Comparator.comparingInt(e -> (int) (mult * e.price)) : + (c1, c2) -> mult * + c1.itemId.toLowerCase().compareTo(c2.itemId.toLowerCase()); + removableItem.sort(comparator); + applicableItem.sort(comparator); + } + } + + private void tickGemstones() { + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + ContainerChest cc = (ContainerChest) chest.inventorySlots; + + ItemStack enchantingItemStack = cc.getLowerChestInventory().getStackInSlot(19); + ItemStack portalStack = cc.getLowerChestInventory().getStackInSlot(28); + + int lastPage = currentPage; + this.lastState = currentState; + if (portalStack != null && portalStack.getItem() == Item.getItemFromBlock(Blocks.end_portal_frame) && + currentState != EnchantState.ADDING_GEMSTONE && !shouldOverrideGemstones && + currentState != EnchantState.APPLYING_GEMSTONE) { + currentState = EnchantState.HAS_ITEM_IN_GEMSTONE; + enchantingItem = enchantingItemStack; + } else if (portalStack != null && portalStack.getItem() == Item.getItemFromBlock(Blocks.end_portal_frame) && + shouldOverrideGemstones && currentState != EnchantState.APPLYING_GEMSTONE) { + currentState = EnchantState.ADDING_GEMSTONE; + } else if (currentState == EnchantState.HAS_ITEM_IN_GEMSTONE && enchantingItem == null && + enchantingItemStack != null) { + enchantingItem = enchantingItemStack; + } else if (currentState != EnchantState.APPLYING_GEMSTONE) { + currentState = EnchantState.HAS_ITEM_IN_GEMSTONE; + } + + if (currentState == EnchantState.APPLYING_GEMSTONE || currentState == EnchantState.ADDING_GEMSTONE) { + ItemStack pageUpStack = cc.getLowerChestInventory().getStackInSlot(17); + ItemStack pageDownStack = cc.getLowerChestInventory().getStackInSlot(35); + if (pageUpStack != null && pageDownStack != null) { + currentPage = 0; + boolean upIsGlass = pageUpStack.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane); + boolean downIsGlass = pageDownStack.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane); + int page = -1; + + expectedMaxPage = 1; + if (!downIsGlass) { + try { + page = Integer.parseInt(Utils.getRawTooltip(pageDownStack).get(1).substring(11)) - 1; + expectedMaxPage = page + 1; + } catch (Exception ignored) { + } + } + if (page == -1 && !upIsGlass) { + try { + page = Integer.parseInt(Utils.getRawTooltip(pageUpStack).get(1).substring(11)) + 1; + expectedMaxPage = page; + } catch (Exception ignored) { + } + } + if (page == -1) { + currentPage = 1; + } else { + currentPage = page; + } + } + } + + orbDisplay.physicsTickOrbs(); + + if (++tickCounter >= 20) { + tickCounter = 0; + } + + if (lastState != currentState || lastPage != currentPage) { + leftScroll.setValue(0); + rightScroll.setValue(0); + } + + if (currentState == EnchantState.APPLYING_GEMSTONE) { + if (arrowAmount.getTarget() != 1) { + arrowAmount.setTarget(1); + arrowAmount.resetTimer(); + } + } else { + if (arrowAmount.getTarget() != 0) { + arrowAmount.setTarget(0); + arrowAmount.resetTimer(); + } + } + + isChangingEnchLevel = false; + + searchRemovedFromRemovable = false; + searchRemovedFromApplicable = false; + applicableItem.clear(); + removableItem.clear(); + if (isInGemstones()) { + for (int i = 0; i < 15; i++) { + int slotIndex = 12 + (i % 5) + (i / 5) * 9; + ItemStack book = cc.getLowerChestInventory().getStackInSlot(slotIndex); + if (book != null) { + NBTTagCompound tagBook = book.getTagCompound(); + if (tagBook != null) { + NBTTagCompound ea = tagBook.getCompoundTag("ExtraAttributes"); + if (ea != null) { + NBTTagCompound enchantments = ea.getCompoundTag("enchantments"); + if (enchantments != null) { + String itemId = Utils.cleanColour(book.getDisplayName()).toUpperCase().replace(" ", "_").replace( + "-", + "_" + ); + String name = Utils.cleanColour(book.getDisplayName()); + if (itemId.equalsIgnoreCase("_")) continue; + if (itemId.equalsIgnoreCase("Item_Maxed_Out")) continue; + if (searchField.getText().trim().isEmpty() || + name.toLowerCase().contains(searchField.getText().trim().toLowerCase())) { + /*if (playerEnchantIds.containsKey(itemId)) { + HexItem item = new HexItem(slotIndex, name, itemId, + Utils.getRawTooltip(book), false, false + ); + if (!item.overMaxLevel) { + removableItem.add(item); + } + enchanterItemLevels.put(item.level, item); + } else */ + { + HexItem item = new HexItem(slotIndex, name, itemId, + Utils.getRawTooltip(book), true, true + ); + enchanterItemLevels.put(item.level, item); + if (item.isGemstone()) { + if (book.getItem() == Items.dye) { + item.conflicts = true; + } + boolean removed = false; + for (String lore : item.displayLore) { + if (lore.contains("Click to remove!")) { + removableItem.add(item); + removed = true; + break; + } + } + if (!removed) { + applicableItem.add(item); + } + if (item.itemName.length() > 14) item.itemName = item.itemName.substring(0, 14); + } else { + applicableItem.add(item); + } + } + } else { + if (playerEnchantIds.containsKey(itemId)) { + searchRemovedFromRemovable = true; + } else { + searchRemovedFromApplicable = true; + } + } + } + } + } + } + } + NEUConfig cfg = NotEnoughUpdates.INSTANCE.config; + int mult = cfg.enchantingSolvers.enchantOrdering == 0 ? 1 : -1; + Comparator<HexItem> comparator = cfg.enchantingSolvers.enchantSorting == 0 ? + Comparator.comparingInt(e -> (int) (mult * e.price)) : + (c1, c2) -> mult * + c1.itemId.toLowerCase().compareTo(c2.itemId.toLowerCase()); + removableItem.sort(comparator); + applicableItem.sort(comparator); + } + this.pageOpenLast = this.pageOpen; + } + + private List<String> createTooltip(String title, int selectedOption, String... options) { + String selPrefix = EnumChatFormatting.DARK_AQUA + " \u25b6 "; + String unselPrefix = EnumChatFormatting.GRAY.toString(); + + for (int i = 0; i < options.length; i++) { + if (i == selectedOption) { + options[i] = selPrefix + options[i]; + } else { + options[i] = unselPrefix + options[i]; + } + } + + List<String> list = Lists.newArrayList(options); + list.add(0, ""); + list.add(0, EnumChatFormatting.GREEN + title); + return list; + } + + public void render(float partialTicks, String containerName) { + if (containerName == null) return; + if (containerName.equals("The Hex")) { + renderHex(partialTicks); + } else if (containerName.contains("Enchant Item")) { + renderEnchantment(partialTicks); + } else if (containerName.contains("Books") || containerName.contains("Modifiers") || containerName.contains( + "Bottles of Enchanting")) { + renderBooks(partialTicks); + } else if (containerName.contains("Gemstones")) { + renderGemstones(partialTicks); + } else { + renderBooks(partialTicks); + } + } + + private void renderEnchantment(float partialTicks) { + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return; + + int playerXpLevel = Minecraft.getMinecraft().thePlayer.experienceLevel; + + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + ContainerChest cc = (ContainerChest) chest.inventorySlots; + + leftScroll.tick(); + rightScroll.tick(); + arrowAmount.tick(); + + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + int width = scaledResolution.getScaledWidth(); + int height = scaledResolution.getScaledHeight(); + int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth; + int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1; + + guiLeft = (width - X_SIZE) / 2; + guiTop = (height - Y_SIZE) / 2; + + List<String> tooltipToDisplay = null; + boolean disallowClick = false; + ItemStack stackOnMouse = Minecraft.getMinecraft().thePlayer.inventory.getItemStack(); + int itemHoverX = -1; + int itemHoverY = -1; + boolean hoverLocked = false; + + drawGradientRect(0, 0, width, height, 0xc0101010, 0xd0101010); + + renderBaseTexture(); + + Minecraft.getMinecraft().fontRendererObj.drawString("Applicable", guiLeft + 7, guiTop + 7, 0x404040, false); + Minecraft.getMinecraft().fontRendererObj.drawString("Removable", guiLeft + 247, guiTop + 7, 0x404040, false); + + //Page Text + if (currentState == EnchantState.HAS_ITEM || currentState == EnchantState.ADDING_ENCHANT) { + String pageStr = "Page: " + currentPage + "/" + expectedMaxPage; + int pageStrLen = Minecraft.getMinecraft().fontRendererObj.getStringWidth(pageStr); + Utils.drawStringCentered(pageStr, Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2, guiTop + 14, false, 0x404040 + ); + + //Page Arrows + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 - pageStrLen / 2 - 2 - 15, guiTop + 6, 15, 15, + 0, 15 / 512f, 372 / 512f, 387 / 512f, GL11.GL_NEAREST + ); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 + pageStrLen / 2 + 2, guiTop + 6, 15, 15, + 15 / 512f, 30 / 512f, 372 / 512f, 387 / 512f, GL11.GL_NEAREST + ); + } + + tooltipToDisplay = renderSettings(mouseX, mouseY, tooltipToDisplay); + + renderScrollBars(applicable, removable, mouseY); + + //Enchant book model + renderEnchantBook(scaledResolution, partialTicks); + + //Can't be enchanted text + if (currentState == EnchantState.INVALID_ITEM) { + GlStateManager.disableDepth(); + Utils.drawStringCentered("This item can't", Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2, guiTop + 88, true, 0xffff5555 + ); + Utils.drawStringCentered("be enchanted", Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2, guiTop + 98, true, 0xffff5555 + ); + GlStateManager.enableDepth(); + } + + renderArrow(); + + //Text if no enchants appear + if (currentState == EnchantState.HAS_ITEM || currentState == EnchantState.ADDING_ENCHANT) { + if (applicable.isEmpty() && removable.isEmpty() && searchRemovedFromApplicable) { + Utils.drawStringCentered("Can't find that", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 8 + 48, guiTop + 28, true, 0xffff5555 + ); + Utils.drawStringCentered("enchant, perhaps", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 8 + 48, guiTop + 38, true, 0xffff5555 + ); + Utils.drawStringCentered("it is on", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 8 + 48, guiTop + 48, true, 0xffff5555 + ); + Utils.drawStringCentered("another page?", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 8 + 48, guiTop + 58, true, 0xffff5555 + ); + } else if (applicable.isEmpty() && !searchRemovedFromApplicable) { + Utils.drawStringCentered("No applicable", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 8 + 48, guiTop + 28, true, 0xffff5555 + ); + Utils.drawStringCentered("enchants on", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 8 + 48, guiTop + 38, true, 0xffff5555 + ); + Utils.drawStringCentered("this page...", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 8 + 48, guiTop + 48, true, 0xffff5555 + ); + } + if (applicable.isEmpty() && removable.isEmpty() && searchRemovedFromRemovable) { + Utils.drawStringCentered("Can't find that", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 248 + 48, guiTop + 28, true, 0xffff5555 + ); + Utils.drawStringCentered("enchant, perhaps", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 248 + 48, guiTop + 38, true, 0xffff5555 + ); + Utils.drawStringCentered("it is on", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 248 + 48, guiTop + 48, true, 0xffff5555 + ); + Utils.drawStringCentered("another page?", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 248 + 48, guiTop + 58, true, 0xffff5555 + ); + } else if (removable.isEmpty() && !searchRemovedFromRemovable) { + Utils.drawStringCentered("No removable", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 248 + 48, guiTop + 28, true, 0xffff5555 + ); + Utils.drawStringCentered("enchants on", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 248 + 48, guiTop + 38, true, 0xffff5555 + ); + Utils.drawStringCentered("this page...", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 248 + 48, guiTop + 48, true, 0xffff5555 + ); + } + } + //Available enchants (left) + GlScissorStack.push(0, guiTop + 18, width, guiTop + 18 + 96, scaledResolution); + for (int i = 0; i < 7; i++) { + int index = i + leftScroll.getValue() / 16; + + if (applicable.size() <= index) break; + Enchantment ench = applicable.get(index); + + int top = guiTop - (leftScroll.getValue() % 16) + 18 + 16 * i; + int vOffset = enchanterCurrentEnch != null && enchanterCurrentEnch.enchId.equals(ench.enchId) ? 16 : 0; + int uOffset = ench.conflicts ? 112 : 0; + int textOffset = vOffset / 16; + + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + 8, top, 96, 16, + uOffset / 512f, (96 + uOffset) / 512f, (249 + vOffset) / 512f, (249 + 16 + vOffset) / 512f, GL11.GL_NEAREST + ); + + if (mouseX > guiLeft + 8 && mouseX <= guiLeft + 8 + 96 && + mouseY > top && mouseY <= top + 16) { + disallowClick = true; + if (ench.displayLore != null) { + tooltipToDisplay = ench.displayLore; + } + } + + String levelStr = "" + ench.xpCost; + int colour = 0xc8ff8f; + if (ench.xpCost > playerXpLevel) { + colour = 0xff5555; + } + + int levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2 - 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2 + 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2, + top + 4 - 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2, + top + 4 + 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2, + top + 4, + colour, + false + ); + + Minecraft.getMinecraft().fontRendererObj.drawString( + ench.enchantName, + guiLeft + 8 + 16 + 2 + textOffset, + top + 4 + textOffset, + 0xffffffdd, + true + ); + } + GlScissorStack.pop(scaledResolution); + + //Removable enchants (right) + GlScissorStack.push(0, guiTop + 18, width, guiTop + 18 + 96, scaledResolution); + for (int i = 0; i < 7; i++) { + int index = i + rightScroll.getValue() / 16; + + if (removable.size() <= index) break; + Enchantment ench = removable.get(index); + + int top = guiTop - (rightScroll.getValue() % 16) + 18 + 16 * i; + int vOffset = enchanterCurrentEnch != null && enchanterCurrentEnch.enchId.equals(ench.enchId) ? 16 : 0; + int textOffset = vOffset / 16; + + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + 248, top, 96, 16, + 0, 96 / 512f, (249 + vOffset) / 512f, (249 + 16 + vOffset) / 512f, GL11.GL_NEAREST + ); + + if (mouseX > guiLeft + 248 && mouseX <= guiLeft + 248 + 96 && + mouseY > top && mouseY <= top + 16) { + disallowClick = true; + if (ench.displayLore != null) { + tooltipToDisplay = ench.displayLore; + } + } + + String levelStr = "" + ench.xpCost; + if (ench.xpCost < 0) levelStr = "?"; + int colour = 0xc8ff8f; + if (ench.xpCost > playerXpLevel) { + colour = 0xff5555; + } + + int levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2 - 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2 + 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2, + top + 4 - 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2, + top + 4 + 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2, + top + 4, + colour, + false + ); + + Minecraft.getMinecraft().fontRendererObj.drawString(ench.enchantName, + guiLeft + 248 + 16 + 2 + textOffset, top + 4 + textOffset, 0xffffffdd, true + ); + } + GlScissorStack.pop(scaledResolution); + + //Player Inventory Items + Minecraft.getMinecraft().fontRendererObj.drawString(Minecraft.getMinecraft().thePlayer.inventory + .getDisplayName() + .getUnformattedText(), + guiLeft + 102, guiTop + Y_SIZE - 96 + 2, 0x404040 + ); + int inventoryStartIndex = cc.getLowerChestInventory().getSizeInventory(); + GlStateManager.enableDepth(); + for (int i = 0; i < 36; i++) { + int itemX = guiLeft + 102 + 18 * (i % 9); + int itemY = guiTop + 133 + 18 * (i / 9); + + if (i >= 27) { + itemY += 4; + } + + GlStateManager.pushMatrix(); + GlStateManager.translate(guiLeft + 102 - 8, guiTop + 191 - (inventoryStartIndex / 9 * 18 + 89), 0); + Slot slot = cc.getSlot(inventoryStartIndex + i); + ((AccessorGuiContainer) chest).doDrawSlot(slot); + GlStateManager.popMatrix(); + + if (mouseX >= itemX && mouseX < itemX + 18 && + mouseY >= itemY && mouseY < itemY + 18) { + itemHoverX = itemX; + itemHoverY = itemY; + hoverLocked = SlotLocking.getInstance().isSlotLocked(slot); + + if (slot.getHasStack()) { + tooltipToDisplay = slot.getStack().getTooltip( + Minecraft.getMinecraft().thePlayer, + Minecraft.getMinecraft().gameSettings.advancedItemTooltips + ); + } + } + } + + //Search bar + if (currentState == EnchantState.HAS_ITEM) { + if (searchField.getText().isEmpty() && !searchField.getFocus()) { + searchField.setSize(90, 14); + searchField.setPrependText("\u00a77Search..."); + } else { + if (searchField.getFocus()) { + int len = Minecraft.getMinecraft().fontRendererObj.getStringWidth(searchField.getTextDisplay()) + 10; + searchField.setSize(Math.max(90, len), 14); + } else { + searchField.setSize(90, 14); + } + searchField.setPrependText(""); + } + searchField.render(guiLeft + X_SIZE / 2 - searchField.getWidth() / 2, guiTop + 83); + } else if (currentState == EnchantState.ADDING_ENCHANT && + enchanterCurrentEnch != null && !enchanterEnchLevels.isEmpty()) { + int left = guiLeft + X_SIZE / 2 - 56; + int top = guiTop + 83; + + int uOffset = enchanterCurrentEnch.conflicts ? 112 : 0; + + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(left, top, 112, 16, + uOffset / 512f, (112 + uOffset) / 512f, 249 / 512f, (249 + 16) / 512f, GL11.GL_NEAREST + ); + + if (mouseX > left + 16 && mouseX <= left + 96 && + mouseY > top && mouseY <= top + 16) { + disallowClick = true; + if (enchanterCurrentEnch.displayLore != null) { + tooltipToDisplay = enchanterCurrentEnch.displayLore; + } + } + + //Enchant cost + String levelStr = "" + enchanterCurrentEnch.xpCost; + if (enchanterCurrentEnch.xpCost < 0) levelStr = "?"; + + int colour = 0xc8ff8f; + if (enchanterCurrentEnch.xpCost > playerXpLevel) { + colour = 0xff5555; + } + + int levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 8 - levelWidth / 2 - 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 8 - levelWidth / 2 + 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 8 - levelWidth / 2, + top + 4 - 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 8 - levelWidth / 2, + top + 4 + 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left + 8 - levelWidth / 2, top + 4, colour, false); + + String priceStr = "" + numberFormat.format(enchanterCurrentEnch.price) + " Coins"; + if (enchanterCurrentEnch.price < 0) priceStr = ""; + int priceWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(priceStr); + int priceTop = guiTop + 16; + int x = 180; + int color = 0x2d2102; + Minecraft.getMinecraft().fontRendererObj.drawString( + priceStr, + guiLeft + x - priceWidth / 2 - 1, + priceTop + 4, + color, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + priceStr, + guiLeft + x - priceWidth / 2 + 1, + priceTop + 4, + color, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + priceStr, + guiLeft + x - priceWidth / 2, + priceTop + 4 - 1, + color, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + priceStr, + guiLeft + x - priceWidth / 2, + priceTop + 4 + 1, + color, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + priceStr, + guiLeft + x - priceWidth / 2, + priceTop + 4, + 0xfcba03, + false + ); + + //Enchant name + String name = WordUtils.capitalizeFully(ItemUtils + .fixEnchantId(enchanterCurrentEnch.enchId, false) + .replace("_", " ")); + if (name.equalsIgnoreCase("Bane of Arthropods")) { + name = "Bane of Arth."; + } else if (name.equalsIgnoreCase("Projectile Protection")) { + name = "Projectile Prot"; + } else if (name.equalsIgnoreCase("Blast Protection")) { + name = "Blast Prot"; + } else if (name.equalsIgnoreCase("Luck of the Sea")) { + name = "Luck of Sea"; + } else if (name.equalsIgnoreCase("Turbo Mushrooms")) { + name = "Turbo-Mush"; + } + Utils.drawStringCentered( + name, + Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2, + top + 8, + true, + 0xffffffdd + ); + + if (isChangingEnchLevel) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(left + 96, top, 16, 16, + 96 / 512f, 112 / 512f, 265 / 512f, (265 + 16) / 512f, GL11.GL_NEAREST + ); + } + + //Enchant level + levelStr = "" + enchanterCurrentEnch.level; + if (enchanterCurrentEnch.xpCost < 0) levelStr = "?"; + levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 96 + 8 - levelWidth / 2 - 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 96 + 8 - levelWidth / 2 + 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 96 + 8 - levelWidth / 2, + top + 4 - 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 96 + 8 - levelWidth / 2, + top + 4 + 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 96 + 8 - levelWidth / 2, + top + 4, + 0xea82ff, + false + ); + + //Confirm button + + String confirmText = "Apply"; + if (removingEnchantPlayerLevel >= 0) { + if (removingEnchantPlayerLevel == enchanterCurrentEnch.level) { + confirmText = "Remove"; + } else if (enchanterCurrentEnch.level > removingEnchantPlayerLevel) { + confirmText = "Upgrade"; + } else { + confirmText = "Bad Level"; + } + } + if (System.currentTimeMillis() - confirmButtonAnimTime < 500 && !(playerXpLevel < enchanterCurrentEnch.xpCost)) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 - 1 - 48, top + 18, 48, 14, + 0, 48 / 512f, 342 / 512f, (342 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawStringCentered(confirmText, Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2 - 1 - 23, top + 18 + 9, false, 0x408040 + ); + } else { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 - 1 - 48, top + 18, 48, 14, + 0, 48 / 512f, 328 / 512f, (328 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawStringCentered(confirmText, Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2 - 1 - 24, top + 18 + 8, false, 0x408040 + ); + + if (playerXpLevel < enchanterCurrentEnch.xpCost) { + Gui.drawRect(guiLeft + X_SIZE / 2 - 1 - 48, top + 18, guiLeft + X_SIZE / 2 - 1, top + 18 + 14, 0x80000000); + } + } + + //Cancel button + if (System.currentTimeMillis() - cancelButtonAnimTime < 500) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 + 1, top + 18, 48, 14, + 0, 48 / 512f, 342 / 512f, (342 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawStringCentered("Cancel", Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2 + 1 + 25, top + 18 + 9, false, 0xa04040 + ); + } else { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 + 1, top + 18, 48, 14, + 0, 48 / 512f, 328 / 512f, (328 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawStringCentered("Cancel", Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2 + 1 + 24, top + 18 + 8, false, 0xa04040 + ); + } + + if (mouseY > top + 18 && mouseY <= top + 18 + 16) { + if (mouseX > guiLeft + X_SIZE / 2 - 1 - 48 && mouseX <= guiLeft + X_SIZE / 2 - 1) { + disallowClick = true; + if (enchanterCurrentEnch.displayLore != null) { + tooltipToDisplay = enchanterCurrentEnch.displayLore; + } + } else if (mouseX > guiLeft + X_SIZE / 2 + 1 && mouseX <= guiLeft + X_SIZE / 2 + 1 + 48) { + disallowClick = true; + tooltipToDisplay = Lists.newArrayList("\u00a7cCancel"); + } + } + + //Enchant level switcher + if (isChangingEnchLevel) { + tooltipToDisplay = null; + + List<Enchantment> before = new ArrayList<>(); + List<Enchantment> after = new ArrayList<>(); + + for (Enchantment ench : enchanterEnchLevels.values()) { + if (ench.level < enchanterCurrentEnch.level) { + before.add(ench); + } else if (ench.level > enchanterCurrentEnch.level) { + after.add(ench); + } + } + + before.sort(Comparator.comparingInt(o -> -o.level)); + after.sort(Comparator.comparingInt(o -> o.level)); + + int bSize = before.size(); + int aSize = after.size(); + GlStateManager.disableDepth(); + for (int i = 0; i < bSize + aSize; i++) { + Enchantment ench; + int yIndex; + if (i < bSize) { + ench = before.get(i); + yIndex = -i - 1; + } else { + ench = after.get(i - bSize); + yIndex = i - bSize + 1; + } + + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + + int type = 0; + if (i == bSize) { + type = 2; + } else if (i == 0) { + type = 1; + } + + if (mouseX > left + 96 && mouseX <= left + 96 + 16 && + mouseY > top + 16 * yIndex && mouseY <= top + 16 * yIndex + 16) { + tooltipToDisplay = new ArrayList<>(ench.displayLore); + if (tooltipToDisplay.size() > 2) { + tooltipToDisplay.remove(tooltipToDisplay.size() - 1); + tooltipToDisplay.remove(tooltipToDisplay.size() - 1); + } + itemHoverX = -1; + itemHoverY = -1; + } + + Utils.drawTexturedRect(left + 96, top + 16 * yIndex, 16, 16, + 16 * type / 512f, (16 + 16 * type) / 512f, 356 / 512f, (356 + 16) / 512f, GL11.GL_NEAREST + ); + + levelStr = "" + ench.level; + levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 96 + 8 - levelWidth / 2 - 1, + top + 16 * yIndex + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 96 + 8 - levelWidth / 2 + 1, + top + 16 * yIndex + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 96 + 8 - levelWidth / 2, + top + 16 * yIndex + 4 - 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 96 + 8 - levelWidth / 2, + top + 16 * yIndex + 4 + 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 96 + 8 - levelWidth / 2, + top + 16 * yIndex + 4, + 0xea82ff, + false + ); + } + GlStateManager.enableDepth(); + } + + if (mouseX > left + 96 && mouseX <= left + 96 + 16 && + mouseY > top && mouseY <= top + 16) { + if (isChangingEnchLevel) { + tooltipToDisplay = Lists.newArrayList("\u00a7cCancel level change"); + } else { + tooltipToDisplay = Lists.newArrayList("\u00a7aChange enchant level"); + } + } + } + + if (currentState == EnchantState.HAS_ITEM) { + renderCancel(); + } + + //Item enchant input + ItemStack itemEnchantInput; + if (currentState == EnchantState.HAS_ITEM_IN_HEX) { + itemEnchantInput = cc.getSlot(22).getStack(); + } else { + itemEnchantInput = cc.getSlot(19).getStack(); + } + if (itemEnchantInput != null && itemEnchantInput.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane)) { + itemEnchantInput = enchantingItem; + } + { + int itemX = guiLeft + 174; + int itemY = guiTop + 58; + + if (itemEnchantInput == null) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(itemX, itemY, 16, 16, + 0, 16 / 512f, 281 / 512f, (281 + 16) / 512f, GL11.GL_NEAREST + ); + } else { + Utils.drawItemStack(itemEnchantInput, itemX, itemY); + } + + if (mouseX >= itemX && mouseX < itemX + 18 && + mouseY >= itemY && mouseY < itemY + 18) { + itemHoverX = itemX; + itemHoverY = itemY; + + if (itemEnchantInput != null) { + tooltipToDisplay = itemEnchantInput.getTooltip( + Minecraft.getMinecraft().thePlayer, + Minecraft.getMinecraft().gameSettings.advancedItemTooltips + ); + } + } + } + + if (!isChangingEnchLevel && itemHoverX >= 0 && itemHoverY >= 0) { + GlStateManager.disableDepth(); + GlStateManager.colorMask(true, true, true, false); + Gui.drawRect(itemHoverX, itemHoverY, itemHoverX + 16, itemHoverY + 16, + hoverLocked ? 0x80ff8080 : 0x80ffffff + ); + GlStateManager.colorMask(true, true, true, true); + GlStateManager.enableDepth(); + } + + GlStateManager.translate(0, 0, 300); + + renderOrbAnim(partialTicks); + + renderMouseStack(stackOnMouse, disallowClick, mouseX, mouseY, + width, height, tooltipToDisplay + ); + GlStateManager.translate(0, 0, -300); + } + + private void renderBooks(float partialTicks) { + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return; + + int playerXpLevel = Minecraft.getMinecraft().thePlayer.experienceLevel; + + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + ContainerChest cc = (ContainerChest) chest.inventorySlots; + + leftScroll.tick(); + rightScroll.tick(); + arrowAmount.tick(); + + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + int width = scaledResolution.getScaledWidth(); + int height = scaledResolution.getScaledHeight(); + int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth; + int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1; + + guiLeft = (width - X_SIZE) / 2; + guiTop = (height - Y_SIZE) / 2; + + List<String> tooltipToDisplay = null; + boolean disallowClick = false; + ItemStack stackOnMouse = Minecraft.getMinecraft().thePlayer.inventory.getItemStack(); + int itemHoverX = -1; + int itemHoverY = -1; + boolean hoverLocked = false; + + drawGradientRect(0, 0, width, height, 0xc0101010, 0xd0101010); + + renderBaseTexture(); + + Minecraft.getMinecraft().fontRendererObj.drawString("Applicable", guiLeft + 7, guiTop + 7, 0x404040, false); + Minecraft.getMinecraft().fontRendererObj.drawString("Applied", guiLeft + 247, guiTop + 7, 0x404040, false); + + //Page Text + /*if (currentState == EnchantState.HAS_ITEM || currentState == EnchantState.ADDING_ENCHANT) { + String pageStr = "Page: " + currentPage + "/" + expectedMaxPage; + int pageStrLen = Minecraft.getMinecraft().fontRendererObj.getStringWidth(pageStr); + Utils.drawStringCentered(pageStr, Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2, guiTop + 14, false, 0x404040 + ); + + //Page Arrows + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 - pageStrLen / 2 - 2 - 15, guiTop + 6, 15, 15, + 0, 15 / 512f, 372 / 512f, 387 / 512f, GL11.GL_NEAREST + ); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 + pageStrLen / 2 + 2, guiTop + 6, 15, 15, + 15 / 512f, 30 / 512f, 372 / 512f, 387 / 512f, GL11.GL_NEAREST + ); + }*/ + + tooltipToDisplay = renderSettings(mouseX, mouseY, tooltipToDisplay); + + renderScrollBars(applicableItem, applicableItem, mouseY); + + //Enchant book model + renderEnchantBook(scaledResolution, partialTicks); + + //Can't be enchanted text + /*if (currentState == EnchantState.INVALID_ITEM) { + GlStateManager.disableDepth(); + Utils.drawStringCentered("This item can't", Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2, guiTop + 88, true, 0xffff5555 + ); + Utils.drawStringCentered("be enchanted", Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2, guiTop + 98, true, 0xffff5555 + ); + GlStateManager.enableDepth(); + }*/ + + renderArrow(); + + //Text if no enchants appear + if (currentState == EnchantState.HAS_ITEM || currentState == EnchantState.ADDING_ENCHANT || + currentState == EnchantState.HAS_ITEM_IN_BOOKS || currentState == EnchantState.ADDING_BOOK) { + if (applicableItem.isEmpty() && removableItem.isEmpty() && searchRemovedFromApplicable) { + Utils.drawStringCentered("Can't find that", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 8 + 48, guiTop + 28, true, 0xffff5555 + ); + Utils.drawStringCentered("enchant, perhaps", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 8 + 48, guiTop + 38, true, 0xffff5555 + ); + Utils.drawStringCentered("it is on", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 8 + 48, guiTop + 48, true, 0xffff5555 + ); + Utils.drawStringCentered("another page?", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 8 + 48, guiTop + 58, true, 0xffff5555 + ); + } else if (applicableItem.isEmpty() && !searchRemovedFromApplicable) { + Utils.drawStringCentered("No applicable", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 8 + 48, guiTop + 28, true, 0xffff5555 + ); + Utils.drawStringCentered("enchants on", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 8 + 48, guiTop + 38, true, 0xffff5555 + ); + Utils.drawStringCentered("this page...", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 8 + 48, guiTop + 48, true, 0xffff5555 + ); + } + if (applicableItem.isEmpty() && removableItem.isEmpty() && searchRemovedFromRemovable) { + Utils.drawStringCentered("Can't find that", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 248 + 48, guiTop + 28, true, 0xffff5555 + ); + Utils.drawStringCentered("enchant, perhaps", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 248 + 48, guiTop + 38, true, 0xffff5555 + ); + Utils.drawStringCentered("it is on", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 248 + 48, guiTop + 48, true, 0xffff5555 + ); + Utils.drawStringCentered("another page?", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 248 + 48, guiTop + 58, true, 0xffff5555 + ); + } else if (removableItem.isEmpty() && !searchRemovedFromRemovable) { + Utils.drawStringCentered("No removable", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 248 + 48, guiTop + 28, true, 0xffff5555 + ); + Utils.drawStringCentered("enchants on", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 248 + 48, guiTop + 38, true, 0xffff5555 + ); + Utils.drawStringCentered("this page...", Minecraft.getMinecraft().fontRendererObj, + guiLeft + 248 + 48, guiTop + 48, true, 0xffff5555 + ); + } + } + //Available enchants (left) + GlScissorStack.push(0, guiTop + 18, width, guiTop + 18 + 96, scaledResolution); + for (int i = 0; i < 7; i++) { + int index = i + leftScroll.getValue() / 16; + + if (applicableItem.size() <= index) break; + HexItem item = applicableItem.get(index); + + int top = guiTop - (leftScroll.getValue() % 16) + 18 + 16 * i; + int vOffset = enchanterCurrentItem != null && enchanterCurrentItem.itemId.equals(item.itemId) ? 16 : 0; + int uOffset = item.conflicts ? 112 : 0; + int textOffset = vOffset / 16; + + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + 8, top, 96, 16, + uOffset / 512f, (96 + uOffset) / 512f, (249 + vOffset) / 512f, (249 + 16 + vOffset) / 512f, GL11.GL_NEAREST + ); + + if (mouseX > guiLeft + 8 && mouseX <= guiLeft + 8 + 96 && + mouseY > top && mouseY <= top + 16) { + disallowClick = true; + if (item.displayLore != null) { + tooltipToDisplay = item.displayLore; + } + } + + String levelStr = getIconStr(item); + int colour = 0xc8ff8f; + if (item.price > playerXpLevel) { + colour = 0xff5555; + } + + int levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2 - 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2 + 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2, + top + 4 - 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2, + top + 4 + 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2, + top + 4, + colour, + false + ); + + Minecraft.getMinecraft().fontRendererObj.drawString( + item.itemName, + guiLeft + 8 + 16 + 2 + textOffset, + top + 4 + textOffset, + 0xffffffdd, + true + ); + } + GlScissorStack.pop(scaledResolution); + + //Removable enchants (right) + GlScissorStack.push(0, guiTop + 18, width, guiTop + 18 + 96, scaledResolution); + for (int i = 0; i < 7; i++) { + int index = i + rightScroll.getValue() / 16; + + if (removableItem.size() <= index) break; + HexItem item = removableItem.get(index); + + int top = guiTop - (rightScroll.getValue() % 16) + 18 + 16 * i; + int vOffset = enchanterCurrentItem != null && enchanterCurrentItem.itemId.equals(item.itemId) ? 16 : 0; + int textOffset = vOffset / 16; + + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + 248, top, 96, 16, + 0, 96 / 512f, (249 + vOffset) / 512f, (249 + 16 + vOffset) / 512f, GL11.GL_NEAREST + ); + + if (mouseX > guiLeft + 248 && mouseX <= guiLeft + 248 + 96 && + mouseY > top && mouseY <= top + 16) { + disallowClick = true; + if (item.displayLore != null) { + tooltipToDisplay = item.displayLore; + } + } + + String levelStr = getIconStr(item); + int colour = 0xc8ff8f; + /*if (item.price > playerXpLevel) { + colour = 0xff5555; + }*/ + + int levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2 - 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2 + 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2, + top + 4 - 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2, + top + 4 + 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2, + top + 4, + colour, + false + ); + + Minecraft.getMinecraft().fontRendererObj.drawString(item.itemName, + guiLeft + 248 + 16 + 2 + textOffset, top + 4 + textOffset, 0xffffffdd, true + ); + } + GlScissorStack.pop(scaledResolution); + + //Player Inventory Items + Minecraft.getMinecraft().fontRendererObj.drawString(Minecraft.getMinecraft().thePlayer.inventory + .getDisplayName() + .getUnformattedText(), + guiLeft + 102, guiTop + Y_SIZE - 96 + 2, 0x404040 + ); + int inventoryStartIndex = cc.getLowerChestInventory().getSizeInventory(); + GlStateManager.enableDepth(); + for (int i = 0; i < 36; i++) { + int itemX = guiLeft + 102 + 18 * (i % 9); + int itemY = guiTop + 133 + 18 * (i / 9); + + if (i >= 27) { + itemY += 4; + } + + GlStateManager.pushMatrix(); + GlStateManager.translate(guiLeft + 102 - 8, guiTop + 191 - (inventoryStartIndex / 9 * 18 + 89), 0); + Slot slot = cc.getSlot(inventoryStartIndex + i); + ((AccessorGuiContainer) chest).doDrawSlot(slot); + GlStateManager.popMatrix(); + + if (mouseX >= itemX && mouseX < itemX + 18 && + mouseY >= itemY && mouseY < itemY + 18) { + itemHoverX = itemX; + itemHoverY = itemY; + hoverLocked = SlotLocking.getInstance().isSlotLocked(slot); + + if (slot.getHasStack()) { + tooltipToDisplay = slot.getStack().getTooltip( + Minecraft.getMinecraft().thePlayer, + Minecraft.getMinecraft().gameSettings.advancedItemTooltips + ); + } + } + } + + //Search bar + if (currentState == EnchantState.HAS_ITEM) { + if (searchField.getText().isEmpty() && !searchField.getFocus()) { + searchField.setSize(90, 14); + searchField.setPrependText("\u00a77Search..."); + } else { + if (searchField.getFocus()) { + int len = Minecraft.getMinecraft().fontRendererObj.getStringWidth(searchField.getTextDisplay()) + 10; + searchField.setSize(Math.max(90, len), 14); + } else { + searchField.setSize(90, 14); + } + searchField.setPrependText(""); + } + searchField.render(guiLeft + X_SIZE / 2 - searchField.getWidth() / 2, guiTop + 83); + } else if (currentState == EnchantState.ADDING_BOOK && + enchanterCurrentItem != null /*&& !enchanterItemLevels.isEmpty()*/) { + int left = guiLeft + X_SIZE / 2 - 56; + int top = guiTop + 83; + + int uOffset = enchanterCurrentItem.conflicts ? 112 : 0; + + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(left, top, 112, 16, + uOffset / 512f, (112 + uOffset) / 512f, 249 / 512f, (249 + 16) / 512f, GL11.GL_NEAREST + ); + + if (mouseX > left + 16 && mouseX <= left + 96 && + mouseY > top && mouseY <= top + 16) { + disallowClick = true; + if (enchanterCurrentItem.displayLore != null) { + tooltipToDisplay = enchanterCurrentItem.displayLore; + } + } + + String priceStr = "" + numberFormat.format(enchanterCurrentItem.getPrice()) + " Coins"; + if (enchanterCurrentItem.price < 0) priceStr = ""; + int priceWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(priceStr); + int priceTop = guiTop + 10; + int x = 180; + int color = 0x2d2102; + Minecraft.getMinecraft().fontRendererObj.drawString( + priceStr, + guiLeft + x - priceWidth / 2 - 1, + priceTop + 4, + color, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + priceStr, + guiLeft + x - priceWidth / 2 + 1, + priceTop + 4, + color, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + priceStr, + guiLeft + x - priceWidth / 2, + priceTop + 4 - 1, + color, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + priceStr, + guiLeft + x - priceWidth / 2, + priceTop + 4 + 1, + color, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + priceStr, + guiLeft + x - priceWidth / 2, + priceTop + 4, + 0xfcba03, + false + ); + + //Enchant name + String name = WordUtils.capitalizeFully(enchanterCurrentItem.itemId.replace("_", " ")); + if (name.equalsIgnoreCase("Hot Potato Book")) { + name = "Hot Potato"; + } else if (name.equalsIgnoreCase("Fuming Potato Book")) { + name = "Fuming Potato"; + } else if (name.equalsIgnoreCase("Recombobulator 3000")) { + name = "Recombobulator"; + } else if (name.contains("Power Scroll")) { + name = name.replace("Power ", ""); + } else if (name.contains("\u272a")) { + name = name.replaceAll("[^✪]*", ""); + } else if (name.equalsIgnoreCase("First Master Star")) { + name = "Master Star \u00a7c➊"; + } else if (name.equalsIgnoreCase("Second Master Star")) { + name = "Master Star \u00a7c➋"; + } else if (name.equalsIgnoreCase("Third Master Star")) { + name = "Master Star \u00a7c➌"; + } else if (name.equalsIgnoreCase("Fourth Master Star")) { + name = "Master Star \u00a7c➍"; + } else if (name.equalsIgnoreCase("Fifth Master Star")) { + name = "Master Star \u00a7c➎"; + } else if (name.equalsIgnoreCase("The Art Of Peace")) { + name = "Art Of Peace"; + } else if (name.equalsIgnoreCase("Mana Disintegrator")) { + name = "M Disintegrator"; + } + Utils.drawStringCentered( + name, + Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2, + top + 8, + true, + 0xffffffdd + ); + + //Confirm button + String confirmText = "Apply"; + if (removingEnchantPlayerLevel >= 0) { + if (removingEnchantPlayerLevel == enchanterCurrentItem.level) { + confirmText = "Remove"; + } else if (enchanterCurrentItem.level > removingEnchantPlayerLevel) { + confirmText = "Upgrade"; + } else { + confirmText = "Bad Level"; + } + } + if (System.currentTimeMillis() - confirmButtonAnimTime < 500 && !(playerXpLevel < enchanterCurrentItem.price)) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 - 1 - 48, top + 18, 48, 14, + 0, 48 / 512f, 342 / 512f, (342 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawStringCentered(confirmText, Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2 - 1 - 23, top + 18 + 9, false, 0x408040 + ); + } else { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 - 1 - 48, top + 18, 48, 14, + 0, 48 / 512f, 328 / 512f, (328 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawStringCentered(confirmText, Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2 - 1 - 24, top + 18 + 8, false, 0x408040 + ); + + /*if (playerXpLevel < enchanterCurrentItem.price) { + Gui.drawRect(guiLeft + X_SIZE / 2 - 1 - 48, top + 18, guiLeft + X_SIZE / 2 - 1, top + 18 + 14, 0x80000000); + }*/ + } + + //Cancel button + if (System.currentTimeMillis() - cancelButtonAnimTime < 500) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 + 1, top + 18, 48, 14, + 0, 48 / 512f, 342 / 512f, (342 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawStringCentered("Cancel", Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2 + 1 + 25, top + 18 + 9, false, 0xa04040 + ); + } else { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 + 1, top + 18, 48, 14, + 0, 48 / 512f, 328 / 512f, (328 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawStringCentered("Cancel", Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2 + 1 + 24, top + 18 + 8, false, 0xa04040 + ); + } + + if (mouseY > top + 18 && mouseY <= top + 18 + 16) { + if (mouseX > guiLeft + X_SIZE / 2 - 1 - 48 && mouseX <= guiLeft + X_SIZE / 2 - 1) { + disallowClick = true; + if (enchanterCurrentItem.displayLore != null) { + tooltipToDisplay = enchanterCurrentItem.displayLore; + } + } else if (mouseX > guiLeft + X_SIZE / 2 + 1 && mouseX <= guiLeft + X_SIZE / 2 + 1 + 48) { + disallowClick = true; + tooltipToDisplay = Lists.newArrayList("\u00a7cCancel"); + } + } + } + + if (currentState == EnchantState.HAS_ITEM_IN_BOOKS || currentState == EnchantState.ADDING_BOOK) { + renderCancel(); + } + + //Item enchant input + ItemStack itemEnchantInput; + if (currentState == EnchantState.HAS_ITEM_IN_HEX) { + itemEnchantInput = cc.getSlot(22).getStack(); + } else { + itemEnchantInput = cc.getSlot(19).getStack(); + } + if (itemEnchantInput != null && itemEnchantInput.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane)) { + itemEnchantInput = enchantingItem; + } + { + int itemX = guiLeft + 174; + int itemY = guiTop + 58; + + if (itemEnchantInput == null) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(itemX, itemY, 16, 16, + 0, 16 / 512f, 281 / 512f, (281 + 16) / 512f, GL11.GL_NEAREST + ); + } else { + Utils.drawItemStack(itemEnchantInput, itemX, itemY); + } + + if (mouseX >= itemX && mouseX < itemX + 18 && + mouseY >= itemY && mouseY < itemY + 18) { + itemHoverX = itemX; + itemHoverY = itemY; + + if (itemEnchantInput != null) { + tooltipToDisplay = itemEnchantInput.getTooltip( + Minecraft.getMinecraft().thePlayer, + Minecraft.getMinecraft().gameSettings.advancedItemTooltips + ); + } + } + } + + if (!isChangingEnchLevel && itemHoverX >= 0 && itemHoverY >= 0) { + GlStateManager.disableDepth(); + GlStateManager.colorMask(true, true, true, false); + Gui.drawRect(itemHoverX, itemHoverY, itemHoverX + 16, itemHoverY + 16, + hoverLocked ? 0x80ff8080 : 0x80ffffff + ); + GlStateManager.colorMask(true, true, true, true); + GlStateManager.enableDepth(); + } + + GlStateManager.translate(0, 0, 300); + + renderOrbAnim(partialTicks); + + renderMouseStack(stackOnMouse, disallowClick, mouseX, mouseY, + width, height, tooltipToDisplay + ); + GlStateManager.translate(0, 0, -300); + } + + private void renderHex(float partialTicks) { + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return; + + int playerXpLevel = Minecraft.getMinecraft().thePlayer.experienceLevel; + + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + ContainerChest cc = (ContainerChest) chest.inventorySlots; + + leftScroll.tick(); + //rightScroll.tick(); + //arrowAmount.tick(); + + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + int width = scaledResolution.getScaledWidth(); + int height = scaledResolution.getScaledHeight(); + int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth; + int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1; + + guiLeft = (width - X_SIZE) / 2; + guiTop = (height - Y_SIZE) / 2; + + List<String> tooltipToDisplay = null; + boolean disallowClick = false; + ItemStack stackOnMouse = Minecraft.getMinecraft().thePlayer.inventory.getItemStack(); + int itemHoverX = -1; + int itemHoverY = -1; + boolean hoverLocked = false; + + drawGradientRect(0, 0, width, height, 0xc0101010, 0xd0101010); + + renderBaseTexture(); + + Minecraft.getMinecraft().fontRendererObj.drawString("The Hex", guiLeft + 7, guiTop + 7, 0x404040, false); + //Minecraft.getMinecraft().fontRendererObj.drawString("Applied", guiLeft + 247, guiTop + 7, 0x404040, false); + + tooltipToDisplay = renderSettings(mouseX, mouseY, tooltipToDisplay); + + renderScrollBars(applicableItem, applicableItem, mouseY); + + //Enchant book model + renderEnchantBook(scaledResolution, partialTicks); + + //Can't be enchanted text + if (currentState == EnchantState.INVALID_ITEM_HEX) { + GlStateManager.disableDepth(); + Utils.drawStringCentered("This item can't", Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2, guiTop + 88, true, 0xffff5555 + ); + Utils.drawStringCentered("be enchanted", Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2, guiTop + 98, true, 0xffff5555 + ); + GlStateManager.enableDepth(); + } + + renderArrow(); + + //Available enchants (left) + GlScissorStack.push(0, guiTop + 18, width, guiTop + 18 + 96, scaledResolution); + for (int i = 0; i < 7; i++) { + int index = i + leftScroll.getValue() / 16; + + if (applicableItem.size() <= index) break; + HexItem item = applicableItem.get(index); + + int top = guiTop - (leftScroll.getValue() % 16) + 18 + 16 * i; + int vOffset = enchanterCurrentItem != null && enchanterCurrentItem.itemId.equals(item.itemId) ? 16 : 0; + int uOffset = item.conflicts ? 112 : 0; + int textOffset = vOffset / 16; + + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + 8, top, 96, 16, + uOffset / 512f, (96 + uOffset) / 512f, (249 + vOffset) / 512f, (249 + 16 + vOffset) / 512f, GL11.GL_NEAREST + ); + + if (mouseX > guiLeft + 8 && mouseX <= guiLeft + 8 + 96 && + mouseY > top && mouseY <= top + 16) { + disallowClick = true; + if (item.displayLore != null) { + tooltipToDisplay = item.displayLore; + } + } + + String levelStr = getIconStr(item); + int colour = 0xc8ff8f; + if (item.price > playerXpLevel) { + colour = 0xff5555; + } + + int levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2 - 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2 + 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2, + top + 4 - 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2, + top + 4 + 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2, + top + 4, + colour, + false + ); + + Minecraft.getMinecraft().fontRendererObj.drawString( + item.itemName, + guiLeft + 8 + 16 + 2 + textOffset, + top + 4 + textOffset, + 0xffffffdd, + true + ); + } + GlScissorStack.pop(scaledResolution); + + //Removable enchants (right) + GlScissorStack.push(0, guiTop + 18, width, guiTop + 18 + 96, scaledResolution); + for (int i = 0; i < 7; i++) { + int index = i + rightScroll.getValue() / 16; + + if (removableItem.size() <= index) break; + HexItem item = removableItem.get(index); + + int top = guiTop - (rightScroll.getValue() % 16) + 18 + 16 * i; + int vOffset = enchanterCurrentItem != null && enchanterCurrentItem.itemId.equals(item.itemId) ? 16 : 0; + int textOffset = vOffset / 16; + + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + 248, top, 96, 16, + 0, 96 / 512f, (249 + vOffset) / 512f, (249 + 16 + vOffset) / 512f, GL11.GL_NEAREST + ); + + if (mouseX > guiLeft + 248 && mouseX <= guiLeft + 248 + 96 && + mouseY > top && mouseY <= top + 16) { + disallowClick = true; + if (item.displayLore != null) { + tooltipToDisplay = item.displayLore; + } + } + + String levelStr = getIconStr(item); + int colour = 0xc8ff8f; + if (item.price > playerXpLevel) { + colour = 0xff5555; + } + + int levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2 - 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2 + 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2, + top + 4 - 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2, + top + 4 + 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2, + top + 4, + colour, + false + ); + + Minecraft.getMinecraft().fontRendererObj.drawString(item.itemName, + guiLeft + 248 + 16 + 2 + textOffset, top + 4 + textOffset, 0xffffffdd, true + ); + } + GlScissorStack.pop(scaledResolution); + + //Player Inventory Items + Minecraft.getMinecraft().fontRendererObj.drawString(Minecraft.getMinecraft().thePlayer.inventory + .getDisplayName() + .getUnformattedText(), + guiLeft + 102, guiTop + Y_SIZE - 96 + 2, 0x404040 + ); + int inventoryStartIndex = cc.getLowerChestInventory().getSizeInventory(); + GlStateManager.enableDepth(); + for (int i = 0; i < 36; i++) { + int itemX = guiLeft + 102 + 18 * (i % 9); + int itemY = guiTop + 133 + 18 * (i / 9); + + if (i >= 27) { + itemY += 4; + } + + GlStateManager.pushMatrix(); + GlStateManager.translate(guiLeft + 102 - 8, guiTop + 191 - (inventoryStartIndex / 9 * 18 + 89), 0); + Slot slot = cc.getSlot(inventoryStartIndex + i); + ((AccessorGuiContainer) chest).doDrawSlot(slot); + GlStateManager.popMatrix(); + + if (mouseX >= itemX && mouseX < itemX + 18 && + mouseY >= itemY && mouseY < itemY + 18) { + itemHoverX = itemX; + itemHoverY = itemY; + hoverLocked = SlotLocking.getInstance().isSlotLocked(slot); + + if (slot.getHasStack()) { + tooltipToDisplay = slot.getStack().getTooltip( + Minecraft.getMinecraft().thePlayer, + Minecraft.getMinecraft().gameSettings.advancedItemTooltips + ); + } + } + } + + if (currentState == EnchantState.ADDING_BOOK && + enchanterCurrentItem != null /*&& !enchanterItemLevels.isEmpty()*/) { + int left = guiLeft + X_SIZE / 2 - 56; + int top = guiTop + 83; + + int uOffset = enchanterCurrentItem.conflicts ? 112 : 0; + + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(left, top, 112, 16, + uOffset / 512f, (112 + uOffset) / 512f, 249 / 512f, (249 + 16) / 512f, GL11.GL_NEAREST + ); + + if (mouseX > left + 16 && mouseX <= left + 96 && + mouseY > top && mouseY <= top + 16) { + disallowClick = true; + if (enchanterCurrentItem.displayLore != null) { + tooltipToDisplay = enchanterCurrentItem.displayLore; + } + } + + if (mouseY > top + 18 && mouseY <= top + 18 + 16) { + if (mouseX > guiLeft + X_SIZE / 2 - 1 - 48 && mouseX <= guiLeft + X_SIZE / 2 - 1) { + disallowClick = true; + if (enchanterCurrentItem.displayLore != null) { + tooltipToDisplay = enchanterCurrentItem.displayLore; + } + } else if (mouseX > guiLeft + X_SIZE / 2 + 1 && mouseX <= guiLeft + X_SIZE / 2 + 1 + 48) { + disallowClick = true; + tooltipToDisplay = Lists.newArrayList("\u00a7cCancel"); + } + } + } + + if (currentState == EnchantState.HAS_ITEM_IN_BOOKS || currentState == EnchantState.ADDING_BOOK) { + renderCancel(); + } + + //Item enchant input + ItemStack itemEnchantInput; + if (isInHex()) { + itemEnchantInput = cc.getSlot(22).getStack(); + } else { + itemEnchantInput = cc.getSlot(19).getStack(); + } + if (itemEnchantInput != null && itemEnchantInput.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane)) { + itemEnchantInput = enchantingItem; + } + { + int itemX = guiLeft + 174; + int itemY = guiTop + 58; + + if (itemEnchantInput == null) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(itemX, itemY, 16, 16, + 0, 16 / 512f, 281 / 512f, (281 + 16) / 512f, GL11.GL_NEAREST + ); + } else { + Utils.drawItemStack(itemEnchantInput, itemX, itemY); + } + + if (mouseX >= itemX && mouseX < itemX + 18 && + mouseY >= itemY && mouseY < itemY + 18) { + itemHoverX = itemX; + itemHoverY = itemY; + + if (itemEnchantInput != null) { + tooltipToDisplay = itemEnchantInput.getTooltip( + Minecraft.getMinecraft().thePlayer, + Minecraft.getMinecraft().gameSettings.advancedItemTooltips + ); + } + } + } + + if (!isChangingEnchLevel && itemHoverX >= 0 && itemHoverY >= 0) { + GlStateManager.disableDepth(); + GlStateManager.colorMask(true, true, true, false); + Gui.drawRect(itemHoverX, itemHoverY, itemHoverX + 16, itemHoverY + 16, + hoverLocked ? 0x80ff8080 : 0x80ffffff + ); + GlStateManager.colorMask(true, true, true, true); + GlStateManager.enableDepth(); + } + + GlStateManager.translate(0, 0, 300); + + renderOrbAnim(partialTicks); + + renderMouseStack(stackOnMouse, disallowClick, mouseX, mouseY, + width, height, tooltipToDisplay + ); + GlStateManager.translate(0, 0, -300); + } + + private void renderGemstones(float partialTicks) { + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return; + + int playerXpLevel = Minecraft.getMinecraft().thePlayer.experienceLevel; + + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + ContainerChest cc = (ContainerChest) chest.inventorySlots; + + leftScroll.tick(); + rightScroll.tick(); + arrowAmount.tick(); + + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + int width = scaledResolution.getScaledWidth(); + int height = scaledResolution.getScaledHeight(); + int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth; + int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1; + + guiLeft = (width - X_SIZE) / 2; + guiTop = (height - Y_SIZE) / 2; + + List<String> tooltipToDisplay = null; + boolean disallowClick = false; + ItemStack stackOnMouse = Minecraft.getMinecraft().thePlayer.inventory.getItemStack(); + int itemHoverX = -1; + int itemHoverY = -1; + boolean hoverLocked = false; + + drawGradientRect(0, 0, width, height, 0xc0101010, 0xd0101010); + + renderBaseTexture(); + + Minecraft.getMinecraft().fontRendererObj.drawString("Applicable", guiLeft + 7, guiTop + 7, 0x404040, false); + Minecraft.getMinecraft().fontRendererObj.drawString("Applied", guiLeft + 247, guiTop + 7, 0x404040, false); + + //Page Text + if (currentState == EnchantState.ADDING_GEMSTONE || currentState == EnchantState.APPLYING_GEMSTONE) { + String pageStr = "Page: " + currentPage + "/" + expectedMaxPage; + int pageStrLen = Minecraft.getMinecraft().fontRendererObj.getStringWidth(pageStr); + Utils.drawStringCentered(pageStr, Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2, guiTop + 14, false, 0x404040 + ); + + //Page Arrows + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 - pageStrLen / 2 - 2 - 15, guiTop + 6, 15, 15, + 0, 15 / 512f, 372 / 512f, 387 / 512f, GL11.GL_NEAREST + ); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 + pageStrLen / 2 + 2, guiTop + 6, 15, 15, + 15 / 512f, 30 / 512f, 372 / 512f, 387 / 512f, GL11.GL_NEAREST + ); + } + + //Confirm button + { + int top = guiTop + 83; + if (currentState == EnchantState.APPLYING_GEMSTONE) { + String confirmText = "Apply"; + if (removingEnchantPlayerLevel >= 0) { + if (removingEnchantPlayerLevel == enchanterCurrentItem.level) { + confirmText = "Remove"; + } else if (enchanterCurrentItem.level > removingEnchantPlayerLevel) { + confirmText = "Upgrade"; + } else { + confirmText = "Bad Level"; + } + } + if (System.currentTimeMillis() - confirmButtonAnimTime < 500) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 - 1 - 48, top + 18, 48, 14, + 0, 48 / 512f, 342 / 512f, (342 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawStringCentered(confirmText, Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2 - 1 - 23, top + 18 + 9, false, 0x408040 + ); + } else { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 - 1 - 48, top + 18, 48, 14, + 0, 48 / 512f, 328 / 512f, (328 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawStringCentered(confirmText, Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2 - 1 - 24, top + 18 + 8, false, 0x408040 + ); + } + } + + //Cancel button + + if (System.currentTimeMillis() - cancelButtonAnimTime < 500) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 + 1, top + 18, 48, 14, + 0, 48 / 512f, 342 / 512f, (342 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawStringCentered("Cancel", Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2 + 1 + 25, top + 18 + 9, false, 0xa04040 + ); + } else { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 + 1, top + 18, 48, 14, + 0, 48 / 512f, 328 / 512f, (328 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawStringCentered("Cancel", Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2 + 1 + 24, top + 18 + 8, false, 0xa04040 + ); + } + } + + tooltipToDisplay = renderSettings(mouseX, mouseY, tooltipToDisplay); + + renderScrollBars(applicableItem, applicableItem, mouseY); + + //Enchant book model + renderEnchantBook(scaledResolution, partialTicks); + + renderArrow(); + + //Available enchants (left) + GlScissorStack.push(0, guiTop + 18, width, guiTop + 18 + 96, scaledResolution); + for (int i = 0; i < 7; i++) { + int index = i + leftScroll.getValue() / 16; + + if (applicableItem.size() <= index) break; + HexItem item = applicableItem.get(index); + + int top = guiTop - (leftScroll.getValue() % 16) + 18 + 16 * i; + int vOffset = enchanterCurrentItem != null && enchanterCurrentItem.itemId.equals(item.itemId) ? 16 : 0; + int uOffset = item.conflicts ? 112 : 0; + int textOffset = vOffset / 16; + + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + 8, top, 96, 16, + uOffset / 512f, (96 + uOffset) / 512f, (249 + vOffset) / 512f, (249 + 16 + vOffset) / 512f, GL11.GL_NEAREST + ); + + if (mouseX > guiLeft + 8 && mouseX <= guiLeft + 8 + 96 && + mouseY > top && mouseY <= top + 16) { + disallowClick = true; + if (item.displayLore != null) { + tooltipToDisplay = item.displayLore; + } + } + + String levelStr = getIconStr(item); + int colour = 0xc8ff8f; + if (item.price > playerXpLevel) { + colour = 0xff5555; + } + + int levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2 - 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2 + 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2, + top + 4 - 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2, + top + 4 + 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 16 - levelWidth / 2, + top + 4, + colour, + false + ); + + Minecraft.getMinecraft().fontRendererObj.drawString( + item.itemName, + guiLeft + 8 + 16 + 2 + textOffset, + top + 4 + textOffset, + 0xffffffdd, + true + ); + } + GlScissorStack.pop(scaledResolution); + + //Removable enchants (right) + GlScissorStack.push(0, guiTop + 18, width, guiTop + 18 + 96, scaledResolution); + for (int i = 0; i < 7; i++) { + int index = i + rightScroll.getValue() / 16; + + if (removableItem.size() <= index) break; + HexItem item = removableItem.get(index); + + int top = guiTop - (rightScroll.getValue() % 16) + 18 + 16 * i; + int vOffset = enchanterCurrentItem != null && enchanterCurrentItem.itemId.equals(item.itemId) ? 16 : 0; + int textOffset = vOffset / 16; + + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + 248, top, 96, 16, + 0, 96 / 512f, (249 + vOffset) / 512f, (249 + 16 + vOffset) / 512f, GL11.GL_NEAREST + ); + + if (mouseX > guiLeft + 248 && mouseX <= guiLeft + 248 + 96 && + mouseY > top && mouseY <= top + 16) { + disallowClick = true; + if (item.displayLore != null) { + tooltipToDisplay = item.displayLore; + } + } + + String levelStr = getIconStr(item); + int colour = 0xc8ff8f; + if (item.price > playerXpLevel) { + colour = 0xff5555; + } + + int levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2 - 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2 + 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2, + top + 4 - 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2, + top + 4 + 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + guiLeft + 256 - levelWidth / 2, + top + 4, + colour, + false + ); + + Minecraft.getMinecraft().fontRendererObj.drawString(item.itemName, + guiLeft + 248 + 16 + 2 + textOffset, top + 4 + textOffset, 0xffffffdd, true + ); + } + GlScissorStack.pop(scaledResolution); + + //Player Inventory Items + Minecraft.getMinecraft().fontRendererObj.drawString(Minecraft.getMinecraft().thePlayer.inventory + .getDisplayName() + .getUnformattedText(), + guiLeft + 102, guiTop + Y_SIZE - 96 + 2, 0x404040 + ); + int inventoryStartIndex = cc.getLowerChestInventory().getSizeInventory(); + GlStateManager.enableDepth(); + for (int i = 0; i < 36; i++) { + int itemX = guiLeft + 102 + 18 * (i % 9); + int itemY = guiTop + 133 + 18 * (i / 9); + + if (i >= 27) { + itemY += 4; + } + + GlStateManager.pushMatrix(); + GlStateManager.translate(guiLeft + 102 - 8, guiTop + 191 - (inventoryStartIndex / 9 * 18 + 89), 0); + Slot slot = cc.getSlot(inventoryStartIndex + i); + ((AccessorGuiContainer) chest).doDrawSlot(slot); + GlStateManager.popMatrix(); + + if (mouseX >= itemX && mouseX < itemX + 18 && + mouseY >= itemY && mouseY < itemY + 18) { + itemHoverX = itemX; + itemHoverY = itemY; + hoverLocked = SlotLocking.getInstance().isSlotLocked(slot); + + if (slot.getHasStack()) { + tooltipToDisplay = slot.getStack().getTooltip( + Minecraft.getMinecraft().thePlayer, + Minecraft.getMinecraft().gameSettings.advancedItemTooltips + ); + } + } + } + + if (currentState == EnchantState.APPLYING_GEMSTONE && + enchanterCurrentItem != null /*&& !enchanterItemLevels.isEmpty()*/) { + int left = guiLeft + X_SIZE / 2 - 56; + int top = guiTop + 83; + + int uOffset = enchanterCurrentItem.conflicts ? 112 : 0; + + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(left, top, 112, 16, + uOffset / 512f, (112 + uOffset) / 512f, 249 / 512f, (249 + 16) / 512f, GL11.GL_NEAREST + ); + + if (mouseX > left + 16 && mouseX <= left + 96 && + mouseY > top && mouseY <= top + 16) { + disallowClick = true; + if (enchanterCurrentItem.displayLore != null) { + tooltipToDisplay = enchanterCurrentItem.displayLore; + } + } + + if (mouseY > top + 18 && mouseY <= top + 18 + 16) { + if (mouseX > guiLeft + X_SIZE / 2 - 1 - 48 && mouseX <= guiLeft + X_SIZE / 2 - 1) { + disallowClick = true; + if (enchanterCurrentItem.displayLore != null) { + tooltipToDisplay = enchanterCurrentItem.displayLore; + } + } else if (mouseX > guiLeft + X_SIZE / 2 + 1 && mouseX <= guiLeft + X_SIZE / 2 + 1 + 48) { + disallowClick = true; + tooltipToDisplay = Lists.newArrayList("\u00a7cCancel"); + } + } + } + + if (currentState == EnchantState.HAS_ITEM_IN_BOOKS || currentState == EnchantState.ADDING_BOOK) { + renderCancel(); + } + + //Item enchant input + ItemStack itemEnchantInput; + if (isInHex()) { + itemEnchantInput = cc.getSlot(22).getStack(); + } else { + itemEnchantInput = cc.getSlot(19).getStack(); + } + if (itemEnchantInput != null && itemEnchantInput.getItem() == Item.getItemFromBlock(Blocks.stained_glass_pane)) { + itemEnchantInput = enchantingItem; + } + { + int itemX = guiLeft + 174; + int itemY = guiTop + 58; + + if (itemEnchantInput == null) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(itemX, itemY, 16, 16, + 0, 16 / 512f, 281 / 512f, (281 + 16) / 512f, GL11.GL_NEAREST + ); + } else { + Utils.drawItemStack(itemEnchantInput, itemX, itemY); + } + + if (mouseX >= itemX && mouseX < itemX + 18 && + mouseY >= itemY && mouseY < itemY + 18) { + itemHoverX = itemX; + itemHoverY = itemY; + + if (itemEnchantInput != null) { + tooltipToDisplay = itemEnchantInput.getTooltip( + Minecraft.getMinecraft().thePlayer, + Minecraft.getMinecraft().gameSettings.advancedItemTooltips + ); + } + } + } + + if (currentState == EnchantState.APPLYING_GEMSTONE) { + int left = guiLeft + X_SIZE / 2 - 56; + int top = guiTop + 83; + //Enchant cost + String levelStr = getIconStr(enchanterCurrentItem); + + int colour = 0xc8ff8f; + if (enchanterCurrentItem.price > playerXpLevel) { + colour = 0xff5555; + } + + int levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 8 - levelWidth / 2 - 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 8 - levelWidth / 2 + 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 8 - levelWidth / 2, + top + 4 - 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 8 - levelWidth / 2, + top + 4 + 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString(levelStr, left + 8 - levelWidth / 2, top + 4, colour, false); + + //Enchant name + String name = WordUtils.capitalizeFully(enchanterCurrentItem.itemName); + if (name.equalsIgnoreCase("Bane of Arthropods")) { + name = "Bane of Arth."; + } else if (name.equalsIgnoreCase("Projectile Protection")) { + name = "Projectile Prot"; + } else if (name.equalsIgnoreCase("Blast Protection")) { + name = "Blast Prot"; + } else if (name.equalsIgnoreCase("Luck of the Sea")) { + name = "Luck of Sea"; + } else if (name.equalsIgnoreCase("Turbo Mushrooms")) { + name = "Turbo-Mush"; + } + Utils.drawStringCentered( + name, + Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2, + top + 8, + true, + 0xffffffdd + ); + + if (isChangingEnchLevel) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(left + 96, top, 16, 16, + 96 / 512f, 112 / 512f, 265 / 512f, (265 + 16) / 512f, GL11.GL_NEAREST + ); + } + + //Enchant level + levelStr = ""; + levelWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(levelStr); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 96 + 8 - levelWidth / 2 - 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 96 + 8 - levelWidth / 2 + 1, + top + 4, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 96 + 8 - levelWidth / 2, + top + 4 - 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 96 + 8 - levelWidth / 2, + top + 4 + 1, + 0x2d2102, + false + ); + Minecraft.getMinecraft().fontRendererObj.drawString( + levelStr, + left + 96 + 8 - levelWidth / 2, + top + 4, + 0xea82ff, + false + ); + } + + if (!isChangingEnchLevel && itemHoverX >= 0 && itemHoverY >= 0) { + GlStateManager.disableDepth(); + GlStateManager.colorMask(true, true, true, false); + Gui.drawRect(itemHoverX, itemHoverY, itemHoverX + 16, itemHoverY + 16, + hoverLocked ? 0x80ff8080 : 0x80ffffff + ); + GlStateManager.colorMask(true, true, true, true); + GlStateManager.enableDepth(); + } + + GlStateManager.translate(0, 0, 300); + + renderOrbAnim(partialTicks); + + renderMouseStack(stackOnMouse, disallowClick, mouseX, mouseY, + width, height, tooltipToDisplay + ); + GlStateManager.translate(0, 0, -300); + } + + private String getIconStr(HexItem item) { + String levelStr = ""; + if (item.itemType != ItemType.UNKNOWN) { + int potatoCount = 0; + int killCount = 0; + int warCount = 0; + int ffdCount = 0; + int recombCount = 0; + int effLevel = 0; + int starCount = 0; + int singularityCount = 0; + int tunerCount = 0; + int manaDisintegratorCount = 0; + int peaceCount = 0; + int dungeonItem = 0; + boolean shadowWarp = false; + boolean witherShield = false; + boolean implosion = false; + String reforge = ""; + if (enchantingItem != null) { + NBTTagCompound tagItem = enchantingItem.getTagCompound(); + if (tagItem != null) { + NBTTagCompound ea = tagItem.getCompoundTag("ExtraAttributes"); + if (ea != null) { + potatoCount = ea.getInteger("hot_potato_count"); + killCount = ea.getInteger("stats_book"); + warCount = ea.getInteger("art_of_war_count"); + ffdCount = ea.getInteger("farming_for_dummies_count"); + recombCount = ea.getInteger("rarity_upgrades"); + starCount = ea.getInteger("upgrade_level"); + singularityCount = ea.getInteger("wood_singularity_count"); + tunerCount = ea.getInteger("tuned_transmission"); + peaceCount = ea.getInteger("art_of_peace_count"); + manaDisintegratorCount = ea.getInteger("mana_disintegrator_count"); + dungeonItem = ea.getInteger("dungeon_item"); + reforge = ea.getString("modifier"); + NBTTagCompound enchs = ea.getCompoundTag("enchantments"); + NBTTagList scrolls = ea.getTagList("ability_scroll", 8); + if (enchs != null) { + effLevel = enchs.getInteger("efficiency"); + } + if (scrolls != null) { + for (int index = 0; index < scrolls.tagCount(); index++) { + if (scrolls.getStringTagAt(index).equals("IMPLOSION_SCROLL")) { + implosion = true; + } else if (scrolls.getStringTagAt(index).equals("SHADOW_WARP_SCROLL")) { + shadowWarp = true; + } else if (scrolls.getStringTagAt(index).equals("WITHER_SHIELD_SCROLL")) { + witherShield = true; + } + } + } + } + } + } + if (item.itemType == ItemType.HOT_POTATO) { + if (potatoCount < 10) levelStr = "" + potatoCount; + else levelStr = "✔"; + + } else if (item.itemType == ItemType.FUMING_POTATO) { + if (potatoCount <= 10) levelStr = "" + 0; + else if (potatoCount < 15) levelStr = "" + (potatoCount - 10); + else levelStr = "✔"; + + } else if (item.itemType == ItemType.BOOK_OF_STATS) { + if (killCount > 0) levelStr = "✔"; + else levelStr = "✖"; + + } else if (item.itemType == ItemType.ART_OF_WAR) { + if (warCount > 0) levelStr = "✔"; + else levelStr = "✖"; + + } else if (item.itemType == ItemType.FARMING_DUMMY) { + if (ffdCount < 5) levelStr = "" + ffdCount; + else levelStr = "✔"; + + } else if (item.itemType == ItemType.RECOMB) { + if (recombCount > 0) levelStr = "✔"; + else levelStr = "✖"; + + } else if (item.itemType == ItemType.SILEX) { + if (effLevel < 10) levelStr = "✖"; + else levelStr = "✔"; + + } else if (item.isPowerScroll()) { + levelStr = "✖"; + + } else if (item.isMasterStar()) { + levelStr = "✖"; + + } else if (item.isDungeonStar()) { + if (starCount >= item.itemType.getStarLevel()) levelStr = "✔"; + else levelStr = "✖"; + + } else if (item.itemType == ItemType.WOOD_SINGULARITY) { + if (singularityCount > 0) levelStr = "✔"; + else levelStr = "✖"; + + } else if (item.isHypeScroll()) { + if (shadowWarp) levelStr = "✔"; + else if (implosion) levelStr = "✔"; + else if (witherShield) levelStr = "✔"; + else levelStr = "✖"; + + } else if (item.itemType == ItemType.TUNER) { + if (tunerCount >= 4) levelStr = "✔"; + else levelStr = "✖"; + + } else if (item.itemType == ItemType.REFORGE) { + if (item.getReforge().equalsIgnoreCase(reforge)) levelStr = "✔"; + else levelStr = "✖"; + + } else if (item.itemType == ItemType.RANDOM_REFORGE) { + levelStr = "?"; + + } else if (item.itemType == ItemType.ART_OF_PEACE) { + if (peaceCount > 0) levelStr = "✔"; + else levelStr = "✖"; + + } else if (item.itemType == ItemType.MANA_DISINTEGRATOR) { + if (manaDisintegratorCount >= 10) levelStr = "✔"; + else levelStr = "✖"; + + } else if (item.itemType == ItemType.CONVERT_TO_DUNGEON) { + if (dungeonItem > 0) levelStr = "✔"; + else levelStr = "✖"; + + } else if (item.itemType == ItemType.RUBY_GEMSTONE) { + levelStr = "❤"; + + } else if (item.itemType == ItemType.AMETHYST_GEMSTONE) { + levelStr = "❈"; + + } else if (item.itemType == ItemType.SAPPHIRE_GEMSTONE) { + levelStr = "✎"; + + } else if (item.itemType == ItemType.JADE_GEMSTONE) { + levelStr = "☘"; + + } else if (item.itemType == ItemType.AMBER_GEMSTONE) { + levelStr = "⸕"; + + } else if (item.itemType == ItemType.TOPAZ_GEMSTONE) { + levelStr = "✧"; + + } else if (item.itemType == ItemType.JASPER_GEMSTONE) { + levelStr = "❁"; + + } else if (item.itemType == ItemType.OPAL_GEMSTONE) { + levelStr = "❂"; + } + } else { + levelStr = "?"; + } + return levelStr; + } + + private void renderBaseTexture() { + //Base Texture + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft, guiTop, X_SIZE, Y_SIZE, + 0, X_SIZE / 512f, 0, Y_SIZE / 512f, GL11.GL_NEAREST + ); + } + + private List<String> renderSettings(int mouseX, int mouseY, List<String> tooltipToDisplay) { + //Settings Buttons + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + //On Settings Button + Utils.drawTexturedRect(guiLeft + 295, guiTop + 147, 16, 16, + 0, 16 / 512f, 387 / 512f, (387 + 16) / 512f, GL11.GL_NEAREST + ); + //Sorting Settings Button + float sortingMinU = NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enchantSorting * 16 / 512f; + Utils.drawTexturedRect(guiLeft + 295, guiTop + 147 + 18, 16, 16, + sortingMinU, sortingMinU + 16 / 512f, 419 / 512f, (419 + 16) / 512f, GL11.GL_NEAREST + ); + //Ordering Settings Button + float orderingMinU = NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enchantOrdering * 16 / 512f; + Utils.drawTexturedRect(guiLeft + 295 + 18, guiTop + 147 + 18, 16, 16, + orderingMinU, orderingMinU + 16 / 512f, 435 / 512f, (435 + 16) / 512f, GL11.GL_NEAREST + ); + + if (mouseX >= guiLeft + 294 && mouseX < guiLeft + 294 + 36 && + mouseY >= guiTop + 146 && mouseY < guiTop + 146 + 36) { + int index = (mouseX - (guiLeft + 295)) / 18 + (mouseY - (guiTop + 147)) / 18 * 2; + switch (index) { + case 0: + Gui.drawRect(guiLeft + 295, guiTop + 147, guiLeft + 295 + 16, guiTop + 147 + 16, 0x80ffffff); + tooltipToDisplay = createTooltip("Enable GUI", 0, "On", "Off"); + break; + case 1: + Gui.drawRect(guiLeft + 295 + 18, guiTop + 147, guiLeft + 295 + 16 + 18, guiTop + 147 + 16, 0x80ffffff); + tooltipToDisplay = createTooltip("Max Level", + (NotEnoughUpdates.INSTANCE.config.enchantingSolvers.maxEnchLevel ? 0 : 1), + "Enabled", "Disabled"); + tooltipToDisplay.add(1, EnumChatFormatting.GRAY + "Show max level of enchant"); + tooltipToDisplay.add(2, EnumChatFormatting.GRAY + "from either hex or enchantment table"); + tooltipToDisplay.add(3, EnumChatFormatting.GRAY + "max level"); + break; + case 2: + Gui.drawRect(guiLeft + 295, guiTop + 147 + 18, guiLeft + 295 + 16, guiTop + 147 + 16 + 18, 0x80ffffff); + tooltipToDisplay = createTooltip("Sort enchants...", + NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enchantSorting, + "By Cost", "Alphabetically" + ); + break; + case 3: + Gui.drawRect( + guiLeft + 295 + 18, + guiTop + 147 + 18, + guiLeft + 295 + 16 + 18, + guiTop + 147 + 16 + 18, + 0x80ffffff + ); + tooltipToDisplay = createTooltip("Order enchants...", + NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enchantOrdering, + "Ascending", "Descending" + ); + break; + } + } + return tooltipToDisplay; + } + + private void renderScrollBars(List applicable, List removable, int mouseY) { + //Left scroll bar + { + int offset; + if (applicable.size() <= 6) { + offset = 0; + } else if (isScrollingLeft && clickedScrollOffset >= 0) { + offset = mouseY - clickedScrollOffset; + if (offset < 0) offset = 0; + if (offset > 96 - 15) offset = 96 - 15; + } else { + offset = Math.round((96 - 15) * (leftScroll.getValue() / (float) ((applicable.size() - 6) * 16))); + } + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + 104, guiTop + 18 + offset, 12, 15, + 0, 12 / 512f, 313 / 512f, (313 + 15) / 512f, GL11.GL_NEAREST + ); + } + //Right scroll bar + { + int offset; + if (removable.size() <= 6) { + offset = 0; + } else if (!isScrollingLeft && clickedScrollOffset >= 0) { + offset = mouseY - clickedScrollOffset; + if (offset < 0) offset = 0; + if (offset > 96 - 15) offset = 96 - 15; + } else { + offset = Math.round((96 - 15) * (rightScroll.getValue() / (float) ((removable.size() - 6) * 16))); + } + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + 344, guiTop + 18 + offset, 12, 15, + 0, 12 / 512f, 313 / 512f, (313 + 15) / 512f, GL11.GL_NEAREST + ); + } + } + + private void renderArrow() { + //Enchant arrow + if (arrowAmount.getValue() > 0) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + float w = 22 * arrowAmount.getValue(); + if (removingEnchantPlayerLevel < 0) { + Utils.drawTexturedRect(guiLeft + 134, guiTop + 58, w, 16, + 0, w / 512f, 297 / 512f, (297 + 16) / 512f, GL11.GL_NEAREST + ); + } else { + Utils.drawTexturedRect(guiLeft + 230 - w, guiTop + 58, w, 16, + (44 - w) / 512f, 44 / 512f, 297 / 512f, (297 + 16) / 512f, GL11.GL_NEAREST + ); + } + } + } + + private void renderCancel() { + int top = guiTop + 83; + //Cancel button + if (System.currentTimeMillis() - cancelButtonAnimTime < 500) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 + 1, top + 18, 48, 14, + 0, 48 / 512f, 342 / 512f, (342 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawStringCentered("Cancel", Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2 + 1 + 25, top + 18 + 9, false, 0xa04040 + ); + } else { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 + 1, top + 18, 48, 14, + 0, 48 / 512f, 328 / 512f, (328 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawStringCentered("Cancel", Minecraft.getMinecraft().fontRendererObj, + guiLeft + X_SIZE / 2 + 1 + 24, top + 18 + 8, false, 0xa04040 + ); + } + } + + private void renderOrbAnim(float partialTicks) { + //Orb animation + GlStateManager.pushMatrix(); + GlStateManager.translate(guiLeft, guiTop, 0); + orbDisplay.renderOrbs(partialTicks); + GlStateManager.popMatrix(); + } + + private void renderMouseStack( + ItemStack stackOnMouse, boolean disallowClick, + int mouseX, int mouseY, int width, int height, + List<String> tooltipToDisplay + ) { + if (stackOnMouse != null) { + if (disallowClick) { + Utils.drawItemStack(new ItemStack(Item.getItemFromBlock(Blocks.barrier)), mouseX - 8, mouseY - 8); + } else { + Utils.drawItemStack(stackOnMouse, mouseX - 8, mouseY - 8); + } + } else if (tooltipToDisplay != null) { + Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, + Minecraft.getMinecraft().fontRendererObj + ); + } + } + + private void renderEnchantBook(ScaledResolution scaledresolution, float partialTicks) { + GlStateManager.enableDepth(); + + GlStateManager.pushMatrix(); + GlStateManager.matrixMode(5889); + GlStateManager.pushMatrix(); + GlStateManager.loadIdentity(); + GlStateManager.viewport((scaledresolution.getScaledWidth() - 320) / 2 * scaledresolution.getScaleFactor(), + (scaledresolution.getScaledHeight() - 240) / 2 * scaledresolution.getScaleFactor(), + 320 * scaledresolution.getScaleFactor(), 240 * scaledresolution.getScaleFactor() + ); + GlStateManager.translate(0.0F, 0.33F, 0.0F); + Project.gluPerspective(90.0F, 1.3333334F, 9.0F, 80.0F); + GlStateManager.matrixMode(5888); + GlStateManager.loadIdentity(); + RenderHelper.enableStandardItemLighting(); + GlStateManager.translate(0.0F, 3.3F, -16.0F); + GlStateManager.scale(5, 5, 5); + GlStateManager.rotate(180.0F, 0.0F, 0.0F, 1.0F); + Minecraft.getMinecraft().getTextureManager().bindTexture(ENCHANTMENT_TABLE_BOOK_TEXTURE); + GlStateManager.rotate(20.0F, 1.0F, 0.0F, 0.0F); + float bookOpenAngle = this.bookOpenLast + (this.bookOpen - this.bookOpenLast) * partialTicks; + GlStateManager.translate( + (1.0F - bookOpenAngle) * 0.2F, + (1.0F - bookOpenAngle) * 0.1F, + (1.0F - bookOpenAngle) * 0.25F + ); + GlStateManager.rotate(-(1.0F - bookOpenAngle) * 90.0F - 90.0F, 0.0F, 1.0F, 0.0F); + GlStateManager.rotate(180.0F, 1.0F, 0.0F, 0.0F); + float pageAngle1 = this.pageOpenLast + (this.pageOpen - this.pageOpenLast) * partialTicks + 0.25F; + float pageAngle2 = this.pageOpenLast + (this.pageOpen - this.pageOpenLast) * partialTicks + 0.75F; + pageAngle1 = (pageAngle1 - (float) MathHelper.truncateDoubleToInt(pageAngle1)) * 1.6F - 0.3F; + pageAngle2 = (pageAngle2 - (float) MathHelper.truncateDoubleToInt(pageAngle2)) * 1.6F - 0.3F; + + if (pageAngle1 < 0.0F) pageAngle1 = 0.0F; + if (pageAngle1 > 1.0F) pageAngle1 = 1.0F; + if (pageAngle2 < 0.0F) pageAngle2 = 0.0F; + if (pageAngle2 > 1.0F) pageAngle2 = 1.0F; + + GlStateManager.enableRescaleNormal(); + MODEL_BOOK.render(null, 0.0F, pageAngle1, pageAngle2, bookOpenAngle, 0.0F, 0.0625F); + GlStateManager.disableRescaleNormal(); + RenderHelper.disableStandardItemLighting(); + GlStateManager.matrixMode(5889); + GlStateManager.viewport(0, 0, Minecraft.getMinecraft().displayWidth, Minecraft.getMinecraft().displayHeight); + GlStateManager.popMatrix(); + GlStateManager.matrixMode(5888); + GlStateManager.popMatrix(); + RenderHelper.disableStandardItemLighting(); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + + GlStateManager.enableDepth(); + } + + private boolean isInEnchanting() { + return currentState == EnchantState.ADDING_ENCHANT || currentState == EnchantState.HAS_ITEM || + currentState == EnchantState.SWITCHING_DONT_UPDATE; + } + + private boolean isInHex() { + return currentState == EnchantState.HAS_ITEM_IN_HEX || currentState == EnchantState.INVALID_ITEM_HEX || + currentState == EnchantState.NO_ITEM_IN_HEX; + } + + private boolean isInGemstones() { + return currentState == EnchantState.HAS_ITEM_IN_GEMSTONE || currentState == EnchantState.ADDING_GEMSTONE || + currentState == EnchantState.APPLYING_GEMSTONE; + } + + public void overrideIsMouseOverSlot(Slot slot, int mouseX, int mouseY, CallbackInfoReturnable<Boolean> cir) { + if ((shouldOverrideFast || shouldOverrideGemstones || shouldOverrideXp) && + currentState != EnchantState.ADDING_ENCHANT) { + boolean playerInv = slot.inventory == Minecraft.getMinecraft().thePlayer.inventory; + int slotId = slot.getSlotIndex(); + if (playerInv && slotId < 36) { + slotId -= 9; + if (slotId < 0) slotId += 36; + + int itemX = guiLeft + 102 + 18 * (slotId % 9); + int itemY = guiTop + 133 + 18 * (slotId / 9); + + if (slotId >= 27) { + itemY += 4; + } + + if (mouseX >= itemX && mouseX < itemX + 18 && + mouseY >= itemY && mouseY < itemY + 18) { + cir.setReturnValue(true); + } else { + cir.setReturnValue(false); + } + } else if ((slotId == 19 && !isInHex()) || (slotId == 22 && isInHex())) { + cir.setReturnValue(mouseX >= guiLeft + 173 && mouseX < guiLeft + 173 + 18 && + mouseY >= guiTop + 57 && mouseY < guiTop + 57 + 18); + } + } + } + + public boolean mouseInput(int mouseX, int mouseY) { + if (Mouse.getEventButtonState() && + (currentState == EnchantState.HAS_ITEM || currentState == EnchantState.ADDING_ENCHANT || + currentState == EnchantState.HAS_ITEM_IN_HEX || currentState == EnchantState.ADDING_BOOK || + currentState == EnchantState.ADDING_GEMSTONE || currentState == EnchantState.APPLYING_GEMSTONE)) { + if (mouseY > guiTop + 6 && mouseY < guiTop + 6 + 15) { + String pageStr = "Page: " + currentPage + "/" + expectedMaxPage; + int pageStrLen = Minecraft.getMinecraft().fontRendererObj.getStringWidth(pageStr); + + int click = -1; + if (mouseX > guiLeft + X_SIZE / 2 - pageStrLen / 2 - 2 - 15 && + mouseX <= guiLeft + X_SIZE / 2 - pageStrLen / 2 - 2) { + click = 17; + } else if (mouseX > guiLeft + X_SIZE / 2 + pageStrLen / 2 + 2 && + mouseX <= guiLeft + X_SIZE / 2 + pageStrLen / 2 + 2 + 15) { + click = 35; + } + + if (click >= 0) { + if (currentState == EnchantState.ADDING_ENCHANT || currentState == EnchantState.ADDING_BOOK) { + if (Mouse.getEventButtonState()) { + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID)); + + cancelButtonAnimTime = System.currentTimeMillis(); + } + } else { + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(click); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, click, 0, 0, stack, transactionID)); + } + return true; + } + } + } + + // Cancel button + if (currentState == EnchantState.HAS_ITEM || + currentState == EnchantState.HAS_ITEM_IN_BOOKS || currentState == EnchantState.HAS_ITEM_IN_GEMSTONE) { + if (Mouse.getEventButtonState()) { + int top = guiTop + 83; + + if (!isChangingEnchLevel && mouseX > guiLeft + X_SIZE / 2 + 1 && mouseX <= guiLeft + X_SIZE / 2 + 1 + 48 && + mouseY > top + 18 && mouseY <= top + 18 + 14) { + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + leftScroll.setValue(0); + rightScroll.setValue(0); + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + if (currentState != EnchantState.ADDING_BOOK) { + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID)); + if (isInGemstones()) { + currentState = EnchantState.HAS_ITEM_IN_GEMSTONE; + } + } else { + currentState = EnchantState.HAS_ITEM_IN_BOOKS; + } + searchField.setText(""); + cancelButtonAnimTime = System.currentTimeMillis(); + enchanterCurrentItem = null; + } + + if (mouseX > guiLeft + X_SIZE / 2 - searchField.getWidth() / 2 && + mouseX < guiLeft + X_SIZE / 2 + searchField.getWidth() / 2 && + mouseY > guiTop + 80 && mouseY < guiTop + 96) { + searchField.mouseClicked(mouseX, mouseY, Mouse.getEventButton()); + } else { + searchField.setFocus(false); + } + } else if (Mouse.getEventButton() < 0 && searchField.getFocus() && Mouse.isButtonDown(0)) { + searchField.mouseClickMove(mouseX, mouseY, 0, 0); + } + } else if (currentState == EnchantState.ADDING_ENCHANT && !enchanterEnchLevels.isEmpty()) { + if (Mouse.getEventButtonState()) { + int left = guiLeft + X_SIZE / 2 - 56; + int top = guiTop + 83; + + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 - 1 - 48, top + 18, 48, 14, + 0, 48 / 512f, 328 / 512f, (328 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 + 1, top + 18, 48, 14, + 0, 48 / 512f, 328 / 512f, (328 + 14) / 512f, GL11.GL_NEAREST + ); + + if (!isChangingEnchLevel && mouseX > guiLeft + X_SIZE / 2 + 1 && mouseX <= guiLeft + X_SIZE / 2 + 1 + 48 && + mouseY > top + 18 && mouseY <= top + 18 + 14) { + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID)); + + cancelButtonAnimTime = System.currentTimeMillis(); + } else if (!isChangingEnchLevel && enchanterCurrentEnch != null && + (mouseX > left + 16 && mouseX <= left + 96 && + mouseY > top && mouseY <= top + 16) || + (mouseX > guiLeft + X_SIZE / 2 - 1 - 48 && mouseX <= guiLeft + X_SIZE / 2 - 1 && + mouseY > top + 18 && mouseY <= top + 18 + 14)) { + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot( + enchanterCurrentEnch.slotIndex); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, + enchanterCurrentEnch.slotIndex, 0, 0, stack, transactionID + )); + + int playerXpLevel = Minecraft.getMinecraft().thePlayer.experienceLevel; + if (playerXpLevel >= enchanterCurrentEnch.xpCost) { + if (removingEnchantPlayerLevel >= 0 && enchanterCurrentEnch.level == removingEnchantPlayerLevel) { + orbDisplay.spawnExperienceOrbs(X_SIZE / 2, 66, X_SIZE / 2, 36, 3); + } else { + orbDisplay.spawnExperienceOrbs(mouseX - guiLeft, mouseY - guiTop, X_SIZE / 2, 66, 0); + } + } + + confirmButtonAnimTime = System.currentTimeMillis(); + } else if (mouseX > left + 96 && mouseX <= left + 96 + 16) { + if (!isChangingEnchLevel) { + if (mouseY > top && mouseY < top + 16) { + isChangingEnchLevel = true; + return true; + } + } else { + List<Enchantment> before = new ArrayList<>(); + List<Enchantment> after = new ArrayList<>(); + + for (Enchantment ench : enchanterEnchLevels.values()) { + if (ench.level < enchanterCurrentEnch.level) { + before.add(ench); + } else if (ench.level > enchanterCurrentEnch.level) { + after.add(ench); + } + } + + before.sort(Comparator.comparingInt(o -> -o.level)); + after.sort(Comparator.comparingInt(o -> o.level)); + + int bSize = before.size(); + int aSize = after.size(); + for (int i = 0; i < bSize + aSize; i++) { + Enchantment ench; + int yIndex; + if (i < bSize) { + yIndex = -i - 1; + ench = before.get(i); + } else { + yIndex = i - bSize + 1; + ench = after.get(i - bSize); + } + + if (mouseY > top + 16 * yIndex && mouseY <= top + 16 * yIndex + 16) { + enchanterCurrentEnch = ench; + isChangingEnchLevel = false; + return true; + } + } + } + } + + if (isChangingEnchLevel) { + isChangingEnchLevel = false; + return true; + } + } + } else if (currentState == EnchantState.ADDING_BOOK) { + if (Mouse.getEventButtonState()) { + int left = guiLeft + X_SIZE / 2 - 56; + int top = guiTop + 83; + + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 - 1 - 48, top + 18, 48, 14, + 0, 48 / 512f, 328 / 512f, (328 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 + 1, top + 18, 48, 14, + 0, 48 / 512f, 328 / 512f, (328 + 14) / 512f, GL11.GL_NEAREST + ); + + if (!isChangingEnchLevel && mouseX > guiLeft + X_SIZE / 2 + 1 && mouseX <= guiLeft + X_SIZE / 2 + 1 + 48 && + mouseY > top + 18 && mouseY <= top + 18 + 14) { + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + /*GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID));*/ + + cancelButtonAnimTime = System.currentTimeMillis(); + currentState = EnchantState.HAS_ITEM_IN_BOOKS; + enchanterCurrentItem = null; + } else if (!isChangingEnchLevel && enchanterCurrentItem != null && + (mouseX > left + 16 && mouseX <= left + 96 && + mouseY > top && mouseY <= top + 16) || + (mouseX > guiLeft + X_SIZE / 2 - 1 - 48 && mouseX <= guiLeft + X_SIZE / 2 - 1 && + mouseY > top + 18 && mouseY <= top + 18 + 14)) { + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot( + enchanterCurrentItem.slotIndex); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, + enchanterCurrentItem.slotIndex, 0, 0, stack, transactionID + )); + + if (removingEnchantPlayerLevel >= 0 && enchanterCurrentItem.level == removingEnchantPlayerLevel) { + orbDisplay.spawnExperienceOrbs(X_SIZE / 2, 66, X_SIZE / 2, 36, 3); + } else { + orbDisplay.spawnExperienceOrbs(mouseX - guiLeft, mouseY - guiTop, X_SIZE / 2, 66, 0); + } + + confirmButtonAnimTime = System.currentTimeMillis(); + enchanterCurrentItem = null; + currentState = EnchantState.HAS_ITEM_IN_BOOKS; + } else if (mouseX > left + 96 && mouseX <= left + 96 + 16) { + if (!isChangingEnchLevel) { + if (mouseY > top && mouseY < top + 16) { + isChangingEnchLevel = true; + return true; + } + } else { + List<HexItem> before = new ArrayList<>(); + List<HexItem> after = new ArrayList<>(); + + for (HexItem item : enchanterItemLevels.values()) { + if (item.level < enchanterCurrentItem.level) { + before.add(item); + } else if (item.level > enchanterCurrentItem.level) { + after.add(item); + } + } + + before.sort(Comparator.comparingInt(o -> -o.level)); + after.sort(Comparator.comparingInt(o -> o.level)); + + int bSize = before.size(); + int aSize = after.size(); + for (int i = 0; i < bSize + aSize; i++) { + HexItem item; + int yIndex; + if (i < bSize) { + yIndex = -i - 1; + item = before.get(i); + } else { + yIndex = i - bSize + 1; + item = after.get(i - bSize); + } + + if (mouseY > top + 16 * yIndex && mouseY <= top + 16 * yIndex + 16) { + enchanterCurrentItem = item; + isChangingEnchLevel = false; + return true; + } + } + } + } + + if (isChangingEnchLevel) { + isChangingEnchLevel = false; + return true; + } + } + } else if (currentState == EnchantState.HAS_ITEM_IN_HEX) { + if (Mouse.getEventButtonState()) { + int left = guiLeft + X_SIZE / 2 - 56; + int top = guiTop + 83; + + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 - 1 - 48, top + 18, 48, 14, + 0, 48 / 512f, 328 / 512f, (328 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 + 1, top + 18, 48, 14, + 0, 48 / 512f, 328 / 512f, (328 + 14) / 512f, GL11.GL_NEAREST + ); + + if (!isChangingEnchLevel && mouseX > guiLeft + X_SIZE / 2 + 1 && mouseX <= guiLeft + X_SIZE / 2 + 1 + 48 && + mouseY > top + 18 && mouseY <= top + 18 + 14) { + /*if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID)); + + cancelButtonAnimTime = System.currentTimeMillis(); + currentState = EnchantState.HAS_ITEM_IN_BOOKS; + enchanterCurrentItem = null;*/ + } else if (!isChangingEnchLevel && enchanterCurrentItem != null && + (mouseX > left + 16 && mouseX <= left + 96 && + mouseY > top && mouseY <= top + 16) || + (mouseX > guiLeft + X_SIZE / 2 - 1 - 48 && mouseX <= guiLeft + X_SIZE / 2 - 1 && + mouseY > top + 18 && mouseY <= top + 18 + 14)) { + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot( + enchanterCurrentItem.slotIndex); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, + enchanterCurrentItem.slotIndex, 0, 0, stack, transactionID + )); + enchantingItem = null; + if (removingEnchantPlayerLevel >= 0 && enchanterCurrentItem.level == removingEnchantPlayerLevel) { + orbDisplay.spawnExperienceOrbs(X_SIZE / 2, 66, X_SIZE / 2, 36, 3); + } else { + orbDisplay.spawnExperienceOrbs(mouseX - guiLeft, mouseY - guiTop, X_SIZE / 2, 66, 0); + } + + confirmButtonAnimTime = System.currentTimeMillis(); + //enchanterCurrentItem = null; + //currentState = EnchantState.HAS_ITEM_IN_BOOKS; + } else if (mouseX > left + 96 && mouseX <= left + 96 + 16) { + if (!isChangingEnchLevel) { + if (mouseY > top && mouseY < top + 16) { + isChangingEnchLevel = true; + return true; + } + } else { + List<HexItem> before = new ArrayList<>(); + List<HexItem> after = new ArrayList<>(); + + for (HexItem item : enchanterItemLevels.values()) { + if (item.level < enchanterCurrentItem.level) { + before.add(item); + } else if (item.level > enchanterCurrentItem.level) { + after.add(item); + } + } + + before.sort(Comparator.comparingInt(o -> -o.level)); + after.sort(Comparator.comparingInt(o -> o.level)); + + int bSize = before.size(); + int aSize = after.size(); + for (int i = 0; i < bSize + aSize; i++) { + HexItem item; + int yIndex; + if (i < bSize) { + yIndex = -i - 1; + item = before.get(i); + } else { + yIndex = i - bSize + 1; + item = after.get(i - bSize); + } + + if (mouseY > top + 16 * yIndex && mouseY <= top + 16 * yIndex + 16) { + enchanterCurrentItem = item; + isChangingEnchLevel = false; + return true; + } + } + } + } + + if (isChangingEnchLevel) { + isChangingEnchLevel = false; + return true; + } + } + } else if (currentState == EnchantState.ADDING_GEMSTONE || currentState == EnchantState.APPLYING_GEMSTONE) { + if (Mouse.getEventButtonState()) { + int left = guiLeft + X_SIZE / 2 - 56; + int top = guiTop + 83; + + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 - 1 - 48, top + 18, 48, 14, + 0, 48 / 512f, 328 / 512f, (328 + 14) / 512f, GL11.GL_NEAREST + ); + Utils.drawTexturedRect(guiLeft + X_SIZE / 2 + 1, top + 18, 48, 14, + 0, 48 / 512f, 328 / 512f, (328 + 14) / 512f, GL11.GL_NEAREST + ); + + if (!isChangingEnchLevel && mouseX > guiLeft + X_SIZE / 2 + 1 && mouseX <= guiLeft + X_SIZE / 2 + 1 + 48 && + mouseY > top + 18 && mouseY <= top + 18 + 14) { + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + if (currentState != EnchantState.APPLYING_GEMSTONE) { + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID)); + + cancelButtonAnimTime = System.currentTimeMillis(); + currentState = EnchantState.HAS_ITEM_IN_GEMSTONE; + enchanterCurrentItem = null; + } else { + currentState = EnchantState.ADDING_ENCHANT; + enchanterCurrentItem = null; + } + } else if (!isChangingEnchLevel && enchanterCurrentItem != null && + (mouseX > left + 16 && mouseX <= left + 96 && + mouseY > top && mouseY <= top + 16) || + (mouseX > guiLeft + X_SIZE / 2 - 1 - 48 && mouseX <= guiLeft + X_SIZE / 2 - 1 && + mouseY > top + 18 && mouseY <= top + 18 + 14) && currentState == EnchantState.APPLYING_GEMSTONE) { + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot( + enchanterCurrentItem.slotIndex); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, + enchanterCurrentItem.slotIndex, 0, 0, stack, transactionID + )); + enchantingItem = null; + if (removingEnchantPlayerLevel >= 0 && enchanterCurrentItem.level == removingEnchantPlayerLevel) { + orbDisplay.spawnExperienceOrbs(X_SIZE / 2, 66, X_SIZE / 2, 36, 3); + } else { + orbDisplay.spawnExperienceOrbs(mouseX - guiLeft, mouseY - guiTop, X_SIZE / 2, 66, 0); + } + + confirmButtonAnimTime = System.currentTimeMillis(); + enchanterCurrentItem = null; + currentState = EnchantState.ADDING_GEMSTONE; + } else if (mouseX > left + 96 && mouseX <= left + 96 + 16) { + if (!isChangingEnchLevel) { + if (mouseY > top && mouseY < top + 16) { + isChangingEnchLevel = true; + return true; + } + } else { + List<HexItem> before = new ArrayList<>(); + List<HexItem> after = new ArrayList<>(); + + for (HexItem item : enchanterItemLevels.values()) { + if (item.level < enchanterCurrentItem.level) { + before.add(item); + } else if (item.level > enchanterCurrentItem.level) { + after.add(item); + } + } + + before.sort(Comparator.comparingInt(o -> -o.level)); + after.sort(Comparator.comparingInt(o -> o.level)); + + int bSize = before.size(); + int aSize = after.size(); + for (int i = 0; i < bSize + aSize; i++) { + HexItem item; + int yIndex; + if (i < bSize) { + yIndex = -i - 1; + item = before.get(i); + } else { + yIndex = i - bSize + 1; + item = after.get(i - bSize); + } + + if (mouseY > top + 16 * yIndex && mouseY <= top + 16 * yIndex + 16) { + enchanterCurrentItem = item; + isChangingEnchLevel = false; + return true; + } + } + } + } + + if (isChangingEnchLevel) { + isChangingEnchLevel = false; + return true; + } + } + } + + if (!Mouse.getEventButtonState() && Mouse.getEventButton() < 0 && clickedScrollOffset != -1) { + if (isInEnchanting()) { + LerpingInteger lerpingInteger = isClickedScrollLeft ? leftScroll : rightScroll; + List<Enchantment> enchantsList = isClickedScrollLeft ? applicable : removable; + + if (enchantsList.size() > 6) { + int newOffset = mouseY - clickedScrollOffset; + + int newScroll = Math.round(newOffset * (float) ((enchantsList.size() - 6) * 16) / (96 - 15)); + int max = (enchantsList.size() - 6) * 16; + + if (newScroll > max) newScroll = max; + if (newScroll < 0) newScroll = 0; + + lerpingInteger.setValue(newScroll); + } + } else { + LerpingInteger lerpingInteger = isClickedScrollLeft ? leftScroll : rightScroll; + List<HexItem> itemsList = isClickedScrollLeft ? applicableItem : removableItem; + + if (itemsList.size() > 6) { + int newOffset = mouseY - clickedScrollOffset; + + int newScroll = Math.round(newOffset * (float) ((itemsList.size() - 6) * 16) / (96 - 15)); + int max = (itemsList.size() - 6) * 16; + + if (newScroll > max) newScroll = max; + if (newScroll < 0) newScroll = 0; + + lerpingInteger.setValue(newScroll); + } + } + } + + //Config options + if (Mouse.getEventButtonState()) { + if (mouseX >= guiLeft + 294 && mouseX < guiLeft + 294 + 36 && + mouseY >= guiTop + 146 && mouseY < guiTop + 146 + 36) { + int index = (mouseX - (guiLeft + 295)) / 18 + (mouseY - (guiTop + 147)) / 18 * 2; + + int direction = Mouse.getEventButton() == 0 ? 1 : -1; + + switch (index) { + case 0: { + NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enableHexGUI = false; + break; + } + case 1: { + NotEnoughUpdates.INSTANCE.config.enchantingSolvers.maxEnchLevel = !NotEnoughUpdates.INSTANCE.config.enchantingSolvers.maxEnchLevel; + break; + } + case 2: { + int val = NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enchantSorting; + val += direction; + if (val < 0) val = 1; + if (val > 1) val = 0; + NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enchantSorting = val; + break; + } + case 3: { + int val = NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enchantOrdering; + val += direction; + if (val < 0) val = 1; + if (val > 1) val = 0; + NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enchantOrdering = val; + break; + } + } + } + } + + if (Mouse.getEventButton() == 0) { + if (Mouse.getEventButtonState()) { + if (isInEnchanting()) { + if (mouseX > guiLeft + 104 && mouseX < guiLeft + 104 + 12) { + int offset; + if (applicable.size() <= 6) { + offset = 0; + } else { + offset = Math.round((96 - 15) * (leftScroll.getValue() / (float) ((applicable.size() - 6) * 16))); + } + if (mouseY >= guiTop + 18 + offset && mouseY < guiTop + 18 + offset + 15) { + isClickedScrollLeft = true; + clickedScrollOffset = mouseY - offset; + } + } else if (mouseX > guiLeft + 344 && mouseX < guiLeft + 344 + 12) { + int offset; + if (removable.size() <= 6) { + offset = 0; + } else { + offset = Math.round((96 - 15) * (rightScroll.getValue() / (float) ((removable.size() - 6) * 16))); + } + if (mouseY >= guiTop + 18 + offset && mouseY < guiTop + 18 + offset + 15) { + isClickedScrollLeft = false; + clickedScrollOffset = mouseY - offset; + } + } + } else { + if (mouseX > guiLeft + 104 && mouseX < guiLeft + 104 + 12) { + int offset; + if (applicableItem.size() <= 6) { + offset = 0; + } else { + offset = Math.round((96 - 15) * (leftScroll.getValue() / (float) ((applicableItem.size() - 6) * 16))); + } + if (mouseY >= guiTop + 18 + offset && mouseY < guiTop + 18 + offset + 15) { + isClickedScrollLeft = true; + clickedScrollOffset = mouseY - offset; + } + } else if (mouseX > guiLeft + 344 && mouseX < guiLeft + 344 + 12) { + int offset; + if (removableItem.size() <= 6) { + offset = 0; + } else { + offset = Math.round((96 - 15) * (rightScroll.getValue() / (float) ((removableItem.size() - 6) * 16))); + } + if (mouseY >= guiTop + 18 + offset && mouseY < guiTop + 18 + offset + 15) { + isClickedScrollLeft = false; + clickedScrollOffset = mouseY - offset; + } + } + } + } else { + clickedScrollOffset = -1; + } + } + + if (mouseY > guiTop + 18 && mouseY < guiTop + 18 + 96) { + if (mouseX > guiLeft + 8 && mouseX < guiLeft + 8 + 96) { + if (Mouse.getEventButton() == 0 && Mouse.getEventButtonState() && + Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) { + if (isInEnchanting()) { + for (int i = 0; i < 7; i++) { + int index = i + leftScroll.getValue() / 16; + if (applicable.size() <= index) break; + + int top = guiTop - (leftScroll.getValue() % 16) + 18 + 16 * i; + if (mouseX > guiLeft + 8 && mouseX <= guiLeft + 8 + 96 && + mouseY > top && mouseY <= top + 16) { + Enchantment ench = applicable.get(index); + + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + if (currentState == EnchantState.HAS_ITEM) { + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = + ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(ench.slotIndex); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, + ench.slotIndex, 0, 0, stack, transactionID + )); + } else if (currentState == EnchantState.ADDING_ENCHANT) { + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID)); + + cancelButtonAnimTime = System.currentTimeMillis(); + } + + return true; + } + } + } else if (!isInHex() && !isInGemstones()) { + for (int i = 0; i < 7; i++) { + int index = i + leftScroll.getValue() / 16; + if (applicableItem.size() <= index) break; + + int top = guiTop - (leftScroll.getValue() % 16) + 18 + 16 * i; + if (mouseX > guiLeft + 8 && mouseX <= guiLeft + 8 + 96 && + mouseY > top && mouseY <= top + 16) { + HexItem item = applicableItem.get(index); + + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + if (currentState == EnchantState.HAS_ITEM_IN_BOOKS) { + currentState = EnchantState.ADDING_BOOK; + enchanterCurrentItem = item; + } else if (currentState == EnchantState.ADDING_BOOK && enchanterCurrentItem == item) { + currentState = EnchantState.HAS_ITEM_IN_BOOKS; + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = + ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(item.slotIndex); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, + item.slotIndex, 0, 0, stack, transactionID + )); + + cancelButtonAnimTime = System.currentTimeMillis(); + } else { + currentState = EnchantState.HAS_ITEM_IN_BOOKS; + enchanterCurrentItem = null; + } + + return true; + } + } + } else if (isInHex() && !isInGemstones()) { + for (int i = 0; i < 7; i++) { + int index = i + leftScroll.getValue() / 16; + if (applicableItem.size() <= index) break; + + int top = guiTop - (leftScroll.getValue() % 16) + 18 + 16 * i; + if (mouseX > guiLeft + 8 && mouseX <= guiLeft + 8 + 96 && + mouseY > top && mouseY <= top + 16) { + HexItem item = applicableItem.get(index); + + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + currentState = EnchantState.HAS_ITEM_IN_BOOKS; + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = + ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(item.slotIndex); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, + item.slotIndex, 0, 0, stack, transactionID + )); + + //cancelButtonAnimTime = System.currentTimeMillis(); + + return true; + } + } + } else if (currentState == EnchantState.ADDING_GEMSTONE || currentState == EnchantState.APPLYING_GEMSTONE) { + for (int i = 0; i < 7; i++) { + int index = i + leftScroll.getValue() / 16; + if (applicableItem.size() <= index) break; + + int top = guiTop - (leftScroll.getValue() % 16) + 18 + 16 * i; + if (mouseX > guiLeft + 8 && mouseX <= guiLeft + 8 + 96 && + mouseY > top && mouseY <= top + 16) { + HexItem item = applicableItem.get(index); + + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + if (currentState == EnchantState.ADDING_GEMSTONE) { + currentState = EnchantState.APPLYING_GEMSTONE; + enchanterCurrentItem = item; + } else if (currentState == EnchantState.APPLYING_GEMSTONE && enchanterCurrentItem == item) { + currentState = EnchantState.ADDING_GEMSTONE; + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = + ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(item.slotIndex); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, + item.slotIndex, 0, 0, stack, transactionID + )); + + cancelButtonAnimTime = System.currentTimeMillis(); + } else { + currentState = EnchantState.ADDING_GEMSTONE; + enchanterCurrentItem = null; + } + + //cancelButtonAnimTime = System.currentTimeMillis(); + + return true; + } + } + } else if (currentState == EnchantState.HAS_ITEM_IN_GEMSTONE) { + for (int i = 0; i < 7; i++) { + int index = i + leftScroll.getValue() / 16; + if (applicableItem.size() <= index) break; + + int top = guiTop - (leftScroll.getValue() % 16) + 18 + 16 * i; + if (mouseX > guiLeft + 8 && mouseX <= guiLeft + 8 + 96 && + mouseY > top && mouseY <= top + 16) { + HexItem item = applicableItem.get(index); + + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = + ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(item.slotIndex); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, + item.slotIndex, 0, 0, stack, transactionID + )); + + cancelButtonAnimTime = System.currentTimeMillis(); + + //cancelButtonAnimTime = System.currentTimeMillis(); + + return true; + } + } + } + } + + isScrollingLeft = true; + } else if (mouseX > guiLeft + 248 && mouseX < guiLeft + 248 + 96) { + if (Mouse.getEventButton() == 0 && Mouse.getEventButtonState() && + Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) { + if (isInEnchanting()) { + for (int i = 0; i < 7; i++) { + int index = i + rightScroll.getValue() / 16; + if (removable.size() <= index) break; + + int top = guiTop - (rightScroll.getValue() % 16) + 18 + 16 * i; + if (mouseX > guiLeft + 248 && mouseX <= guiLeft + 248 + 96 && + mouseY > top && mouseY <= top + 16) { + Enchantment ench = removable.get(index); + + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + if (currentState == EnchantState.HAS_ITEM || currentState == EnchantState.HAS_ITEM_IN_HEX) { + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = + ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(ench.slotIndex); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, + ench.slotIndex, 0, 0, stack, transactionID + )); + } else if (currentState == EnchantState.ADDING_ENCHANT) { + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID)); + + cancelButtonAnimTime = System.currentTimeMillis(); + } + + return true; + } + } + } else if (currentState == EnchantState.ADDING_GEMSTONE) { + for (int i = 0; i < 7; i++) { + int index = i + rightScroll.getValue() / 16; + if (removableItem.size() <= index) break; + + int top = guiTop - (rightScroll.getValue() % 16) + 18 + 16 * i; + if (mouseX > guiLeft + 248 && mouseX <= guiLeft + 248 + 96 && + mouseY > top && mouseY <= top + 16) { + HexItem item = removableItem.get(index); + + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + if (currentState == EnchantState.ADDING_GEMSTONE) { + currentState = EnchantState.APPLYING_GEMSTONE; + enchanterCurrentItem = item; + } else if (currentState == EnchantState.APPLYING_GEMSTONE && enchanterCurrentItem == item) { + currentState = EnchantState.ADDING_GEMSTONE; + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = + ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(item.slotIndex); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, + item.slotIndex, 0, 0, stack, transactionID + )); + + cancelButtonAnimTime = System.currentTimeMillis(); + } else { + currentState = EnchantState.ADDING_GEMSTONE; + enchanterCurrentItem = null; + } + + return true; + } + } + + } else { + for (int i = 0; i < 7; i++) { + int index = i + rightScroll.getValue() / 16; + if (removableItem.size() <= index) break; + + int top = guiTop - (rightScroll.getValue() % 16) + 18 + 16 * i; + if (mouseX > guiLeft + 248 && mouseX <= guiLeft + 248 + 96 && + mouseY > top && mouseY <= top + 16) { + HexItem item = removableItem.get(index); + + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + if (currentState == EnchantState.HAS_ITEM_IN_BOOKS) { + currentState = EnchantState.ADDING_BOOK; + enchanterCurrentItem = item; + } else if (currentState == EnchantState.ADDING_BOOK && enchanterCurrentItem == item) { + currentState = EnchantState.HAS_ITEM_IN_BOOKS; + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = + ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(item.slotIndex); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, + item.slotIndex, 0, 0, stack, transactionID + )); + + cancelButtonAnimTime = System.currentTimeMillis(); + } else { + currentState = EnchantState.HAS_ITEM_IN_BOOKS; + enchanterCurrentItem = null; + } + + return true; + } + } + } + } + isScrollingLeft = false; + } + } + if (Mouse.getEventDWheel() != 0) { + int scroll = Mouse.getEventDWheel(); + if (scroll > 0) { + scroll = -16; + } else { + scroll = 16; + } + + LerpingInteger lerpingInteger = isScrollingLeft ? leftScroll : rightScroll; + int elementsCount; + if (isInEnchanting()) { + elementsCount = isScrollingLeft ? applicable.size() : removable.size(); + } else { + elementsCount = isScrollingLeft ? applicableItem.size() : removableItem.size(); + } + int max = (elementsCount - 6) * 16; + + int newTarget = lerpingInteger.getTarget() + scroll; + if (newTarget > max) newTarget = max; + if (newTarget < 0) newTarget = 0; + + if (newTarget != lerpingInteger.getTarget()) { + lerpingInteger.resetTimer(); + lerpingInteger.setTarget(newTarget); + } + } + + if (mouseX > guiLeft + 102 && mouseX < guiLeft + 102 + 160) { + if ((mouseY > guiTop + 133 && mouseY < guiTop + 133 + 54) || + (mouseY > guiTop + 133 + 54 + 4 && mouseY < guiTop + 133 + 54 + 4 + 18)) { + if (currentState == EnchantState.ADDING_ENCHANT) { + if (Mouse.getEventButtonState()) { + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID)); + + cancelButtonAnimTime = System.currentTimeMillis(); + } + return true; + } else { + return false; + } + } + } + if (mouseX >= guiLeft + 173 && mouseX < guiLeft + 173 + 18 && + mouseY >= guiTop + 57 && mouseY < guiTop + 57 + 18) { + if (currentState == EnchantState.ADDING_ENCHANT) { + if (Mouse.getEventButtonState()) { + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) return true; + GuiContainer chest = ((GuiContainer) Minecraft.getMinecraft().currentScreen); + + EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer; + short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory); + ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45); + Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow( + chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID)); + + cancelButtonAnimTime = System.currentTimeMillis(); + } + return true; + } else { + return false; + } + } + return true; + } + + public boolean keyboardInput() { + if (currentState == EnchantState.HAS_ITEM && searchField.getFocus()) { + if (Keyboard.getEventKeyState()) { + searchField.keyTyped(Keyboard.getEventCharacter(), Keyboard.getEventKey()); + } + return true; + } + if (Keyboard.getEventKey() == Minecraft.getMinecraft().gameSettings.keyBindScreenshot.getKeyCode()) { + return false; + } + + return Keyboard.getEventKey() != Keyboard.KEY_ESCAPE && + Keyboard.getEventKey() != Minecraft.getMinecraft().gameSettings.keyBindInventory.getKeyCode() && + (!NotEnoughUpdates.INSTANCE.config.slotLocking.enableSlotLocking || + Keyboard.getEventKey() != NotEnoughUpdates.INSTANCE.config.slotLocking.slotLockKey); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/hex/HexItem.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/hex/HexItem.java new file mode 100644 index 00000000..5b3b30ea --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/hex/HexItem.java @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.miscgui.hex; + +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.util.Constants; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.util.StringUtils; + +import java.util.List; + +public class HexItem { + public int slotIndex; + public String itemName; + public String itemId; + public List<String> displayLore; + public int level; + public int price = -1; + public boolean overMaxLevel = false; + public boolean conflicts = false; + public ItemType itemType; + public int gemstoneLevel = -1; + + public HexItem( + int slotIndex, String itemName, String itemId, List<String> displayLore, + boolean useMaxLevelForCost, boolean checkConflicts + ) { + this.slotIndex = slotIndex; + this.itemName = itemName; + this.itemId = itemId.replace("'S", ""); + this.displayLore = displayLore; + switch (itemId) { + default: + this.itemType = ItemType.UNKNOWN; + break; + case "HOT_POTATO_BOOK": + this.itemType = ItemType.HOT_POTATO; + break; + case "FUMING_POTATO_BOOK": + this.itemType = ItemType.FUMING_POTATO; + break; + case "BOOK_OF_STATS": + this.itemType = ItemType.BOOK_OF_STATS; + break; + case "THE_ART_OF_WAR": + this.itemType = ItemType.ART_OF_WAR; + break; + case "FARMING_FOR_DUMMIES": + this.itemType = ItemType.FARMING_DUMMY; + break; + case "THE_ART_OF_PEACE": + this.itemType = ItemType.ART_OF_PEACE; + break; + case "RECOMBOBULATOR_3000": + this.itemType = ItemType.RECOMB; + break; + case "SILEX": + this.itemId = "SIL_EX"; + this.itemType = ItemType.SILEX; + break; + case "RUBY_POWER_SCROLL": + this.itemType = ItemType.RUBY_SCROLL; + break; + case "SAPPHIRE_POWER_SCROLL": + this.itemType = ItemType.SAPPHIRE_SCROLL; + break; + case "JASPER_POWER_SCROLL": + this.itemType = ItemType.JASPER_SCROLL; + break; + case "AMETHYST_POWER_SCROLL": + this.itemType = ItemType.AMETHYST_SCROLL; + break; + case "AMBER_POWER_SCROLL": + this.itemType = ItemType.AMBER_SCROLL; + break; + case "OPAL_POWER_SCROLL": + this.itemType = ItemType.OPAL_SCROLL; + break; + case "FIRST_MASTER_STAR": + this.itemType = ItemType.FIRST_MASTER_STAR; + break; + case "SECOND_MASTER_STAR": + this.itemType = ItemType.SECOND_MASTER_STAR; + break; + case "THIRD_MASTER_STAR": + this.itemType = ItemType.THIRD_MASTER_STAR; + break; + case "FOURTH_MASTER_STAR": + this.itemType = ItemType.FOURTH_MASTER_STAR; + break; + case "FIFTH_MASTER_STAR": + this.itemType = ItemType.FIFTH_MASTER_STAR; + break; + case "WOOD_SINGULARITY": + this.itemType = ItemType.WOOD_SINGULARITY; + break; + case "IMPLOSION": + this.itemType = ItemType.IMPLOSION_SCROLL; + break; + case "WITHER_SHIELD": + this.itemType = ItemType.WITHER_SHIELD_SCROLL; + break; + case "SHADOW_WARP": + this.itemType = ItemType.SHADOW_WARP_SCROLL; + break; + case "TRANSMISSION_TUNER": + this.itemType = ItemType.TUNER; + break; + case "RANDOM_REFORGE": + this.itemType = ItemType.RANDOM_REFORGE; + break; + case "MANA_DISINTEGRATOR": + this.itemType = ItemType.MANA_DISINTEGRATOR; + break; + case "TOTAL_UPGRADES": + this.itemType = ItemType.TOTAL_UPGRADES; + break; + case "CONVERT_TO_DUNGEON": + this.itemType = ItemType.CONVERT_TO_DUNGEON; + break; + case "EXPERIENCE_BOTTLE": + this.itemType = ItemType.EXPERIENCE_BOTTLE; + break; + case "GRAND_EXPERIENCE_BOTTLE": + this.itemType = ItemType.GRAND_EXPERIENCE_BOTTLE; + break; + case "TITANIC_EXPERIENCE_BOTTLE": + this.itemType = ItemType.TITANIC_EXPERIENCE_BOTTLE; + break; + case "COLOSSAL_EXPERIENCE_BOTTLE": + this.itemType = ItemType.COLOSSAL_EXPERIENCE_BOTTLE; + break; + } + if (this.itemType == ItemType.UNKNOWN) { + for (String string : displayLore) { + if ((string.contains("Applies the") && string.contains("reforge")) || + string.contains("reforge when combined")) { + this.itemType = ItemType.REFORGE; + break; + } + } + } + if (!this.isMasterStar() && itemId.contains("✪")) { + if (itemId.contains("✪✪✪✪✪")) this.itemType = ItemType.FIFTH_STAR; + else if (itemId.contains("✪✪✪✪")) this.itemType = ItemType.FOURTH_STAR; + else if (itemId.contains("✪✪✪")) this.itemType = ItemType.THIRD_STAR; + else if (itemId.contains("✪✪")) this.itemType = ItemType.SECOND_STAR; + else if (itemId.contains("✪")) this.itemType = ItemType.FIRST_STAR; + } + if (this.itemId.contains("EXPERIENCE_BOTTLE")) { + this.itemId = this.itemId.replace("EXPERIENCE_BOTTLE", "EXP_BOTTLE"); + } + if (this.itemId.contains("END_STONE_GEODE")) { + this.itemId = this.itemId.replace("END_STONE_GEODE", "ENDSTONE_GEODE"); + } + if (itemId.contains("HEX_ITEM")) this.itemType = ItemType.HEX_ITEM; + JsonObject bazaarInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo(this.itemId); + if (bazaarInfo != null && bazaarInfo.get("curr_buy") != null) { + this.price = bazaarInfo.get("curr_buy").getAsInt(); + } + if ("SIL_EX".equals(this.itemId)) this.itemId = "SILEX"; + if (itemName.contains("Amethyst Gemstone")) this.itemType = ItemType.AMETHYST_GEMSTONE; + if (itemName.contains("Ruby Gemstone")) this.itemType = ItemType.RUBY_GEMSTONE; + if (itemName.contains("Sapphire Gemstone")) this.itemType = ItemType.SAPPHIRE_GEMSTONE; + if (itemName.contains("Jasper Gemstone")) this.itemType = ItemType.JASPER_GEMSTONE; + if (itemName.contains("Jade Gemstone")) this.itemType = ItemType.JADE_GEMSTONE; + if (itemName.contains("Amber Gemstone")) this.itemType = ItemType.AMBER_GEMSTONE; + if (itemName.contains("Opal Gemstone")) this.itemType = ItemType.OPAL_GEMSTONE; + if (itemName.contains("Topaz Gemstone")) this.itemType = ItemType.TOPAZ_GEMSTONE; + if (itemName.contains("Gemstone Slot")) this.itemType = ItemType.GEMSTONE_SLOT; + if (this.itemName.contains(" Gemstone")) { + this.itemName = this.itemName.replace(" Gemstone", "").substring(2); + } else if (this.itemName.contains(" Experience Bottle")) { + this.itemName = this.itemName.replace("Experience Bottle", ""); + } else if (this.itemName.equals("Experience Bottle")) { + this.itemName = "Exp Bottle"; + } + if (isGemstone()) { + if (this.itemName.contains("Rough")) this.gemstoneLevel = 0; + if (this.itemName.contains("Flawed")) this.gemstoneLevel = 1; + if (this.itemName.contains("Fine")) this.gemstoneLevel = 2; + if (this.itemName.contains("Flawless")) this.gemstoneLevel = 3; + if (this.itemName.contains("Perfect")) this.gemstoneLevel = 4; + } + } + + public boolean isPowerScroll() { + return itemType == ItemType.RUBY_SCROLL || itemType == ItemType.SAPPHIRE_SCROLL || + itemType == ItemType.JASPER_SCROLL || itemType == ItemType.AMETHYST_SCROLL || + itemType == ItemType.AMBER_SCROLL || itemType == ItemType.OPAL_SCROLL; + } + + public boolean isDungeonStar() { + return itemType == ItemType.FIRST_STAR || itemType == ItemType.SECOND_STAR || + itemType == ItemType.THIRD_STAR || itemType == ItemType.FOURTH_STAR || + itemType == ItemType.FIFTH_STAR; + } + + public boolean isMasterStar() { + return itemType == ItemType.FIRST_MASTER_STAR || itemType == ItemType.SECOND_MASTER_STAR || + itemType == ItemType.THIRD_MASTER_STAR || itemType == ItemType.FOURTH_MASTER_STAR || + itemType == ItemType.FIFTH_MASTER_STAR; + } + + public String getReforge() { + JsonObject reforgeStones = Constants.REFORGESTONES; + if (reforgeStones != null && reforgeStones.has(this.itemId.toUpperCase())) { + JsonObject reforgeInfo = reforgeStones.get(this.itemId.toUpperCase()).getAsJsonObject(); + if (reforgeInfo != null) { + return Utils.getElementAsString(reforgeInfo.get("reforgeName"), ""); + } + + } + return ""; + } + + public int getPrice() { + if (this.itemType == ItemType.RANDOM_REFORGE) { + for (String string : displayLore) { + if (string.contains("Coins")) { + try { + price = Integer.parseInt(StringUtils + .stripControlCodes(string) + .replace(" Coins", "") + .replace(",", "") + .trim()); + } catch (NumberFormatException ignored) { + } + } + } + } + return price; + } + + public boolean isHypeScroll() { + return itemType == ItemType.IMPLOSION_SCROLL || itemType == ItemType.WITHER_SHIELD_SCROLL || + itemType == ItemType.SHADOW_WARP_SCROLL; + } + + public boolean isGemstone() { + return itemType == ItemType.RUBY_GEMSTONE || itemType == ItemType.AMETHYST_GEMSTONE || + itemType == ItemType.SAPPHIRE_GEMSTONE || itemType == ItemType.JASPER_GEMSTONE || + itemType == ItemType.JADE_GEMSTONE || itemType == ItemType.AMBER_GEMSTONE || + itemType == ItemType.OPAL_GEMSTONE || itemType == ItemType.TOPAZ_GEMSTONE; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/hex/ItemType.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/hex/ItemType.java new file mode 100644 index 00000000..3b47a86d --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/hex/ItemType.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.miscgui.hex; + +enum ItemType { + HOT_POTATO, + FUMING_POTATO, + BOOK_OF_STATS, + ART_OF_WAR, + ART_OF_PEACE, + FARMING_DUMMY, + RECOMB, + SILEX, + RUBY_SCROLL, + SAPPHIRE_SCROLL, + JASPER_SCROLL, + AMETHYST_SCROLL, + AMBER_SCROLL, + OPAL_SCROLL, + FIRST_STAR(1), + SECOND_STAR(2), + THIRD_STAR(3), + FOURTH_STAR(4), + FIFTH_STAR(5), + FIRST_MASTER_STAR(6), + SECOND_MASTER_STAR(7), + THIRD_MASTER_STAR(8), + FOURTH_MASTER_STAR(9), + FIFTH_MASTER_STAR(10), + WOOD_SINGULARITY, + IMPLOSION_SCROLL, + SHADOW_WARP_SCROLL, + WITHER_SHIELD_SCROLL, + TUNER, + REFORGE, + RANDOM_REFORGE, + MANA_DISINTEGRATOR, + HEX_ITEM, + TOTAL_UPGRADES, + RUBY_GEMSTONE, + AMETHYST_GEMSTONE, + SAPPHIRE_GEMSTONE, + JASPER_GEMSTONE, + JADE_GEMSTONE, + AMBER_GEMSTONE, + OPAL_GEMSTONE, + TOPAZ_GEMSTONE, + CONVERT_TO_DUNGEON, + GEMSTONE_SLOT, + EXPERIENCE_BOTTLE, + GRAND_EXPERIENCE_BOTTLE, + TITANIC_EXPERIENCE_BOTTLE, + COLOSSAL_EXPERIENCE_BOTTLE, + UNKNOWN; + + private int starLevel = -1; + + ItemType() {} + + ItemType(int starLevel) { + this.starLevel = starLevel; + } + + public int getStarLevel() { + return starLevel; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/util/ExperienceOrb.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/util/ExperienceOrb.java new file mode 100644 index 00000000..9da4f553 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/util/ExperienceOrb.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.miscgui.util; + +import org.lwjgl.util.vector.Vector2f; + +public class ExperienceOrb { + public Vector2f position; + public Vector2f positionLast; + public Vector2f velocity; + public Vector2f target; + + public int type; + public int rotationDeg; +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/util/OrbDisplay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/util/OrbDisplay.java new file mode 100644 index 00000000..42e935f5 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/util/OrbDisplay.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.miscgui.util; + +import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.vector.Vector2f; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; +import java.util.Random; + +public class OrbDisplay { + private static final ResourceLocation TEXTURE = new ResourceLocation("notenoughupdates:custom_enchant_gui.png"); + private static final int DEFAULT_COUNT = 30; + + private final List<ExperienceOrb> experienceOrbList = new ArrayList<>(); + + public ExperienceOrb spawnExperienceOrb(Random random, Vector2f start, Vector2f target, int baseType) { + ExperienceOrb orb = new ExperienceOrb(); + orb.position = new Vector2f(start); + orb.positionLast = new Vector2f(orb.position); + orb.velocity = new Vector2f( + random.nextFloat() * 20 - 10, + random.nextFloat() * 20 - 10 + ); + orb.target = new Vector2f(target); + orb.type = baseType; + orb.rotationDeg = random.nextInt(4) * 90; + + float v = random.nextFloat(); + if (v > 0.6) { + orb.type += 1; + } + if (v > 0.9) { + orb.type += 1; + } + + experienceOrbList.add(orb); + + return orb; + } + + public void spawnExperienceOrbs(int startX, int startY, int targetX, int targetY, int baseType) { + spawnExperienceOrbs(new Random(),new Vector2f(startX, startY), new Vector2f(targetX, targetY), baseType, DEFAULT_COUNT); + } + + public void spawnExperienceOrbs(Random random, Vector2f start, Vector2f target, int baseType, int count) { + for (int i = 0; i < count; i++) { + spawnExperienceOrb(random, start, target, baseType); + } + } + + public void physicsTickOrbs() { + for (ListIterator<ExperienceOrb> it = experienceOrbList.listIterator(); it.hasNext(); ) { + ExperienceOrb orb = it.next(); + + Vector2f delta = Vector2f.sub(orb.target, orb.position, null); + float length = delta.length(); + + // Remove close Orbs + if (length < 8 && orb.velocity.lengthSquared() < 20) { + it.remove(); + continue; + } + + // Update velocity + Vector2f.add(orb.velocity, (Vector2f) delta.scale(2 / length), orb.velocity); + orb.velocity.scale(0.9F); + + // Update position + orb.positionLast.set(orb.position); + Vector2f.add(orb.position, orb.velocity, orb.position); + } + } + + public void renderOrbs(float partialTicks) { + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE); + GlStateManager.disableDepth(); + + for (ExperienceOrb orb : experienceOrbList) { + int orbX = Math.round(LerpUtils.lerp(orb.position.x, orb.positionLast.x, partialTicks)); + int orbY = Math.round(LerpUtils.lerp(orb.position.y, orb.positionLast.y, partialTicks)); + + GlStateManager.pushMatrix(); + + GlStateManager.translate(orbX, orbY, 0); + GlStateManager.rotate(orb.rotationDeg, 0, 0, 1); + + Vector2f delta = Vector2f.sub(orb.position, orb.target, null); + + float length = delta.length(); + float velocitySquared = orb.velocity.lengthSquared(); + float opacity = (float) Math.sqrt( + Math.min( + 1, + Math.min(2, Math.max(0.5F, length / 16)) + * Math.min(2, Math.max(0.5F, velocitySquared / 40)) + )); + GlStateManager.color(1, 1, 1, opacity); + + int orbU = (orb.type % 3) * 16; + int orbV = (orb.type / 3) * 16 + 217; + + Utils.drawTexturedRect( + -8, -8, 16, 16, + orbU / 512f, + (orbU + 16) / 512f, + orbV / 512f, + (orbV + 16) / 512f, + GL11.GL_NEAREST + ); + + GlStateManager.popMatrix(); + } + + GlStateManager.enableDepth(); + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java index 7c3414fa..81918939 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java @@ -21,16 +21,17 @@ package io.github.moulberry.notenoughupdates.mixins; import io.github.moulberry.notenoughupdates.NEUOverlay; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.events.SlotClickEvent; import io.github.moulberry.notenoughupdates.listener.RenderListener; import io.github.moulberry.notenoughupdates.miscfeatures.AbiphoneWarning; import io.github.moulberry.notenoughupdates.miscfeatures.AuctionBINWarning; import io.github.moulberry.notenoughupdates.miscfeatures.AuctionSortModeWarning; import io.github.moulberry.notenoughupdates.miscfeatures.BetterContainers; import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers; -import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay; import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking; import io.github.moulberry.notenoughupdates.miscgui.GuiCustomEnchant; import io.github.moulberry.notenoughupdates.miscgui.StorageOverlay; +import io.github.moulberry.notenoughupdates.miscgui.hex.GuiCustomHex; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; @@ -58,7 +59,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; @Mixin(GuiContainer.class) public abstract class MixinGuiContainer extends GuiScreen { @@ -96,7 +96,8 @@ public abstract class MixinGuiContainer extends GuiScreen { if (tag.hasKey("SkullOwner") && tag.getCompoundTag("SkullOwner").hasKey("Name")) { String tagName = tag.getCompoundTag("SkullOwner").getString("Name"); String displayName = Utils.cleanColour(cc.inventorySlots.get(22).getStack().getDisplayName()); - if (tagName.equals(displayName.substring(displayName.length() - tagName.length()))) { + if (displayName.length() - tagName.length() >= 0 && tagName.equals(displayName.substring( + displayName.length() - tagName.length()))) { ci.cancel(); this.zLevel = 100.0F; @@ -125,7 +126,8 @@ public abstract class MixinGuiContainer extends GuiScreen { else if (!($this instanceof GuiChest)) BetterContainers.profileViewerStackIndex = -1; - if (slot.getStack() == null && NotEnoughUpdates.INSTANCE.overlay.searchMode && RenderListener.drawingGuiScreen && NotEnoughUpdates.INSTANCE.isOnSkyblock()) { + if (slot.getStack() == null && NotEnoughUpdates.INSTANCE.overlay.searchMode && RenderListener.drawingGuiScreen && + NotEnoughUpdates.INSTANCE.isOnSkyblock()) { GlStateManager.pushMatrix(); GlStateManager.translate(0, 0, 100 + Minecraft.getMinecraft().getRenderItem().zLevel); GlStateManager.depthMask(false); @@ -189,6 +191,7 @@ public abstract class MixinGuiContainer extends GuiScreen { public void isMouseOverSlot(Slot slotIn, int mouseX, int mouseY, CallbackInfoReturnable<Boolean> cir) { StorageOverlay.getInstance().overrideIsMouseOverSlot(slotIn, mouseX, mouseY, cir); GuiCustomEnchant.getInstance().overrideIsMouseOverSlot(slotIn, mouseX, mouseY, cir); + GuiCustomHex.getInstance().overrideIsMouseOverSlot(slotIn, mouseX, mouseY, cir); AuctionBINWarning.getInstance().overrideIsMouseOverSlot(slotIn, mouseX, mouseY, cir); AbiphoneWarning.getInstance().overrideIsMouseOverSlot(slotIn, mouseX, mouseY, cir); } @@ -300,65 +303,20 @@ public abstract class MixinGuiContainer extends GuiScreen { @Inject(method = "handleMouseClick", at = @At(value = "HEAD"), cancellable = true) public void handleMouseClick(Slot slotIn, int slotId, int clickedButton, int clickType, CallbackInfo ci) { + if (slotIn == null) return; GuiContainer $this = (GuiContainer) (Object) this; - - if (AuctionBINWarning.getInstance().onMouseClick(slotIn, slotId, clickedButton, clickType)) { - ci.cancel(); - return; - } - - if (AbiphoneWarning.getInstance().onMouseClick(slotIn, slotId, clickedButton, clickType)) { + SlotClickEvent event = new SlotClickEvent($this, slotIn, slotId, clickedButton, clickType); + event.post(); + if (event.isCanceled()) { ci.cancel(); return; } - - AtomicBoolean ret = new AtomicBoolean(false); - SlotLocking.getInstance().onWindowClick(slotIn, slotId, clickedButton, clickType, (tuple) -> { + if (event.usePickblockInstead) { + $this.mc.playerController.windowClick( + $this.inventorySlots.windowId, + slotId, 2, 3, $this.mc.thePlayer + ); ci.cancel(); - - if (tuple == null) { - ret.set(true); - } else { - int newSlotId = tuple.getLeft(); - int newClickedButton = tuple.getMiddle(); - int newClickedType = tuple.getRight(); - - ret.set(true); - $this.mc.playerController.windowClick( - $this.inventorySlots.windowId, - newSlotId, - newClickedButton, - newClickedType, - $this.mc.thePlayer - ); - } - }); - if (ret.get()) return; - - if (slotIn != null && slotIn.getStack() != null) { - if (EnchantingSolvers.onStackClick(slotIn.getStack(), $this.inventorySlots.windowId, - slotId, clickedButton, clickType - )) { - ci.cancel(); - } else { - PetInfoOverlay.onStackClick(slotIn.getStack(), $this.inventorySlots.windowId, - slotId, clickedButton, clickType - ); - } - } - if (slotIn != null && BetterContainers.isOverriding() && (BetterContainers.isBlankStack( - slotIn.slotNumber, - slotIn.getStack() - ) || - BetterContainers.isButtonStack(slotIn.slotNumber, slotIn.getStack()))) { - BetterContainers.clickSlot(slotIn.getSlotIndex()); - - if (BetterContainers.isBlankStack(slotIn.slotNumber, slotIn.getStack())) { - $this.mc.playerController.windowClick($this.inventorySlots.windowId, slotId, 2, clickType, $this.mc.thePlayer); - ci.cancel(); - } else { - Utils.playPressSound(); - } } } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiIngame.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiIngame.java index 3856e2d5..381f5934 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiIngame.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiIngame.java @@ -43,7 +43,7 @@ public class MixinGuiIngame { @Redirect(method = "renderScoreboard", at = @At(value = "INVOKE", target = TARGET)) public String renderScoreboard_formatPlayerName(Team team, String name) { - if (NotEnoughUpdates.INSTANCE.isOnSkyblock() && NotEnoughUpdates.INSTANCE.config.misc.streamerMode) { + if (NotEnoughUpdates.INSTANCE.config.misc.streamerMode) { return StreamerMode.filterScoreboard(ScorePlayerTeam.formatPlayerName(team, name)); } return ScorePlayerTeam.formatPlayerName(team, name); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiInventory.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiInventory.java index bd712ec7..86ed9b8f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiInventory.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiInventory.java @@ -20,7 +20,9 @@ package io.github.moulberry.notenoughupdates.mixins; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.events.GuiInventoryBackgroundDrawnEvent; import io.github.moulberry.notenoughupdates.listener.RenderListener; +import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.gui.inventory.GuiInventory; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -36,4 +38,9 @@ public class MixinGuiInventory { ci.cancel(); } } + + @Inject(method = "drawGuiContainerBackgroundLayer", at = @At("TAIL")) + public void onDrawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY, CallbackInfo ci) { + new GuiInventoryBackgroundDrawnEvent((GuiContainer) (Object) this, partialTicks).post(); + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiTextField.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiTextField.java new file mode 100644 index 00000000..55a5a098 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiTextField.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.mixins; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import net.minecraft.client.gui.GuiTextField; +import org.lwjgl.input.Keyboard; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import java.util.ArrayList; + +@Mixin(GuiTextField.class) +public abstract class MixinGuiTextField { + + private final ArrayList<String> stringStack = new ArrayList<String>() { + { + //allows the ability to undo the entire textField + add(""); + } + }; + private int currentStringStackIndex = -1; + + @Shadow private int maxStringLength; + + @Shadow + private String text; + + @Shadow + public abstract void setCursorPositionEnd(); + + @Shadow + public abstract void setText(String string); + + private void addToStack(String string) { + if (currentStringStackIndex != -1 && currentStringStackIndex != stringStack.size() - 1) { + //did redo/undo before + stringStack.subList(currentStringStackIndex, stringStack.size()).clear(); + } + if (stringStack.size() > 20) { + stringStack.remove(0); + } + stringStack.add(string); + currentStringStackIndex = stringStack.size() - 1; + } + + @Inject(method = "setText", at = @At("TAIL"), locals = LocalCapture.CAPTURE_FAILSOFT) + public void setText_stringStack(String string, CallbackInfo ci) { + if (NotEnoughUpdates.INSTANCE.config.misc.textFieldTweaksEnabled) { + addToStack(string.length() > this.maxStringLength ? string.substring(0, this.maxStringLength) : string); + } + } + + @Inject(method = "writeText", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiTextField;moveCursorBy(I)V"), locals = LocalCapture.CAPTURE_FAILSOFT) + public void writeText_stringStack(String string, CallbackInfo ci, String string2, String string3, int i, int j, int l) { + if (NotEnoughUpdates.INSTANCE.config.misc.textFieldTweaksEnabled) { + addToStack(string2); + } + } + + @Inject(method = "deleteFromCursor", at = @At(value = "INVOKE", target = "Lcom/google/common/base/Predicate;apply(Ljava/lang/Object;)Z"), locals = LocalCapture.PRINT) + public void deleteFromCursor_stringStack(int i, CallbackInfo ci, boolean bl, int j, int k, String string) { + if (NotEnoughUpdates.INSTANCE.config.misc.textFieldTweaksEnabled) { + addToStack(string); + } + } + + @Inject(method = "textboxKeyTyped", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiScreen;isKeyComboCtrlA(I)Z"), cancellable = true) + public void textboxKeyTyped_stringStack(char c, int i, CallbackInfoReturnable<Boolean> cir) { + if (NotEnoughUpdates.INSTANCE.config.misc.textFieldTweaksEnabled) { + if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL)) { + if (currentStringStackIndex == -1 && stringStack.size() > 0) { + currentStringStackIndex = stringStack.size() - 1; + } + + if (Keyboard.isKeyDown(Keyboard.KEY_Y) || (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && Keyboard.isKeyDown( + Keyboard.KEY_Z))) { + //go forward in action stack + if (currentStringStackIndex != stringStack.size() - 1) { + text = stringStack.get(currentStringStackIndex + 1); + currentStringStackIndex += 1; + setCursorPositionEnd(); + } + cir.setReturnValue(true); + } else if (Keyboard.isKeyDown(Keyboard.KEY_Z)) { + //go back in action stack + if (!stringStack.isEmpty() && currentStringStackIndex > 0 && stringStack.get(currentStringStackIndex - 1) != + null) { + text = stringStack.get(currentStringStackIndex - 1); + currentStringStackIndex -= 1; + setCursorPositionEnd(); + } + cir.setReturnValue(true); + } + } + } + } + + @Inject(method = "setMaxStringLength", at = @At(value = "INVOKE", target = "Ljava/lang/String;length()I")) + public void setMaxStringLength_stringStack(int i, CallbackInfo ci) { + //will remove the possibility of creating a bug in the matrix (untested) + if (NotEnoughUpdates.INSTANCE.config.misc.textFieldTweaksEnabled) { + for (int j = 0; j < stringStack.size(); j++) { + String string = stringStack.get(j); + if (string.length() > i) { + stringStack.set(j, string.substring(0, j)); + if (j < currentStringStackIndex) { + currentStringStackIndex -= 1; + } + } + } + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java index dc59c0bb..7c2cfcbf 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinRenderItem.java @@ -25,6 +25,7 @@ import io.github.moulberry.notenoughupdates.core.ChromaColour; import io.github.moulberry.notenoughupdates.listener.RenderListener; import io.github.moulberry.notenoughupdates.miscfeatures.ItemCooldowns; import io.github.moulberry.notenoughupdates.miscfeatures.ItemCustomizeManager; +import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; @@ -195,7 +196,7 @@ public abstract class MixinRenderItem { @Inject(method = "renderItemIntoGUI", at = @At("HEAD")) public void renderItemHead(ItemStack stack, int x, int y, CallbackInfo ci) { - if (NotEnoughUpdates.INSTANCE.overlay.searchMode && RenderListener.drawingGuiScreen && NotEnoughUpdates.INSTANCE.isOnSkyblock()) { + if (NotEnoughUpdates.INSTANCE.overlay.searchMode && RenderListener.drawingGuiScreen && NotEnoughUpdates.INSTANCE.isOnSkyblock() && !(Minecraft.getMinecraft().currentScreen instanceof GuiProfileViewer)) { boolean matches = false; GuiTextField textField = NotEnoughUpdates.INSTANCE.overlay.getTextField(); @@ -221,7 +222,7 @@ public abstract class MixinRenderItem { @Inject(method = "renderItemIntoGUI", at = @At("RETURN")) public void renderItemReturn(ItemStack stack, int x, int y, CallbackInfo ci) { if (stack != null && stack.stackSize != 1) return; - if (NotEnoughUpdates.INSTANCE.overlay.searchMode && RenderListener.drawingGuiScreen && NotEnoughUpdates.INSTANCE.isOnSkyblock()) { + if (NotEnoughUpdates.INSTANCE.overlay.searchMode && RenderListener.drawingGuiScreen && NotEnoughUpdates.INSTANCE.isOnSkyblock() && !(Minecraft.getMinecraft().currentScreen instanceof GuiProfileViewer)) { boolean matches = false; GuiTextField textField = NotEnoughUpdates.INSTANCE.overlay.getTextField(); @@ -252,7 +253,7 @@ public abstract class MixinRenderItem { CallbackInfo ci ) { if (stack != null && stack.stackSize != 1) { - if (NotEnoughUpdates.INSTANCE.overlay.searchMode && RenderListener.drawingGuiScreen && NotEnoughUpdates.INSTANCE.isOnSkyblock()) { + if (NotEnoughUpdates.INSTANCE.overlay.searchMode && RenderListener.drawingGuiScreen && NotEnoughUpdates.INSTANCE.isOnSkyblock() && !(Minecraft.getMinecraft().currentScreen instanceof GuiProfileViewer)) { boolean matches = false; GuiTextField textField = NotEnoughUpdates.INSTANCE.overlay.getTextField(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java index 96e0ec29..8242c095 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -198,6 +198,12 @@ public class NEUConfig extends Config { NotEnoughUpdates.INSTANCE.openGui = new GuiScreenElementWrapper(new NEUConfigEditor(NotEnoughUpdates.INSTANCE.config, "apis")); return; + case 25: + editOverlay(activeConfigCategory, OverlayManager.powderGrindingOverlay, mining.powderGrindingTrackerPosition); + return; + case 26: + OverlayManager.powderGrindingOverlay.reset(); + return; default: System.err.printf("Unknown runnableId = %d in category %s%n", runnableId, activeConfigCategory); } @@ -581,9 +587,23 @@ public class NEUConfig extends Config { @Expose public long dailyHeavyPearlCompleted = 0L; @Expose + public long questBoardCompleted = 0L; + @Expose public HashMap<Integer, JsonObject> savedEquipment = new HashMap<>(); @Expose public int magicalPower = 0; + + @Expose + public int chestCount = 0; + + @Expose + public int openedChestCount = 0; + + @Expose + public int mithrilPowderFound = 0; + + @Expose + public int gemstonePowderFound = 0; } public HiddenLocationSpecific getLocationSpecific() { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java index 17bc57e9..cee994b7 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfigEditor.java @@ -46,6 +46,7 @@ import org.lwjgl.opengl.GL11; import java.awt.*; import java.net.URI; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -110,7 +111,8 @@ public class NEUConfigEditor extends GuiElement { for (ConfigProcessor.ProcessedOption option : category.options.values()) { categoryForOption.put(option, category); - String combined = category.name + " " + category.desc + " " + option.name + " " + option.desc; + String combined = category.name + " " + category.desc + " " + option.name + " " + option.desc + " " + + Arrays.toString(option.searchTags); combined = combined.replaceAll("[^a-zA-Z_ ]", "").toLowerCase(); for (String word : combined.split("[ _]")) { searchOptionMap.computeIfAbsent(word, k -> new HashSet<>()).add(option); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/customtypes/NEUDebugFlag.java b/src/main/java/io/github/moulberry/notenoughupdates/options/customtypes/NEUDebugFlag.java index 8e0e4c11..50f459c0 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/customtypes/NEUDebugFlag.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/customtypes/NEUDebugFlag.java @@ -19,13 +19,55 @@ package io.github.moulberry.notenoughupdates.options.customtypes; +import io.github.moulberry.notenoughupdates.util.NEUDebugLogger; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + public enum NEUDebugFlag { // NOTE: Removing enum values causes gson to remove all debugFlags on load if any removed value is present - METAL, - WISHING, + METAL("Metal Detector Solver"), + WISHING("Wishing Compass Solver"), + MAP("Dungeon Map Player Information"), + SEARCH("SearchString Matches"), ; - public static final String FLAG_LIST = - "METAL - Metal Detector Solver\n" + - "WISHING - Wishing Compass Solver"; + private final String description; + + NEUDebugFlag(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } + + public boolean isSet() { + return NEUDebugLogger.isFlagEnabled(this); + } + + public static String getFlagList() { + return renderFlagInformation(Arrays.asList(values())); + } + + public static String getEnabledFlags() { + return renderFlagInformation(Arrays.stream(values()) + .filter(NEUDebugFlag::isSet) + .collect(Collectors.toList())); + } + + public static String renderFlagInformation(List<NEUDebugFlag> flags) { + int maxNameLength = flags.stream() + .mapToInt(it -> it.name().length()) + .max() + .orElse(0); + return flags.stream() + .map(it -> (CharSequence) String.format( + "%-" + maxNameLength + "s" + " - %s", + it.name(), + it.getDescription() + )) + .collect(Collectors.joining("\n")); + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHGraph.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHGraph.java index ce931392..58c58e3c 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHGraph.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHGraph.java @@ -32,7 +32,8 @@ public class AHGraph { @Expose @ConfigOption( name = "Enable AH/BZ Price Graph", - desc = "Enable or disable the graph. Disabling this will also make it so that no price data is stored." + desc = "Enable or disable the graph. Disabling this will also make it so that no price data is stored.", + searchTags = {"auction", "bazaar"} ) @ConfigEditorBoolean public boolean graphEnabled = true; @@ -58,7 +59,8 @@ public class AHGraph { @Expose @ConfigOption( name = "Graph Colour", - desc = "Set a custom colour for the graph." + desc = "Set a custom colour for the graph.", + searchTags = "color" ) @ConfigEditorColour public String graphColor = "0:255:0:255:0"; @@ -66,7 +68,8 @@ public class AHGraph { @Expose @ConfigOption( name = "Secondary Graph Colour", - desc = "Set a custom colour for the second graph line." + desc = "Set a custom colour for the second graph line.", + searchTags = "color" ) @ConfigEditorColour public String graphColor2 = "0:255:255:255:0"; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHTweaks.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHTweaks.java index 298ddeda..f6aac507 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHTweaks.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHTweaks.java @@ -81,7 +81,7 @@ public class AHTweaks { @Expose @ConfigOption( name = "Enable Undercut BIN Warning", - desc = "Ask for confirmation when BINing an item for below X% of lowestbin" + desc = "Ask for confirmation when BINing an item for below X% of lowest bin" ) @ConfigEditorBoolean @ConfigAccordionId(id = 1) @@ -90,7 +90,7 @@ public class AHTweaks { @Expose @ConfigOption( name = "Enable Overcut BIN Warning", - desc = "Ask for confirmation when BINing an item for over X% of lowestbin" + desc = "Ask for confirmation when BINing an item for over X% of lowest bin" ) @ConfigEditorBoolean @ConfigAccordionId(id = 1) @@ -112,7 +112,7 @@ public class AHTweaks { @Expose @ConfigOption( name = "Overcut Warning Threshold", - desc = "Threshold for BIN warning\nExample: 50% means warn if sell price is 50% higher than lowest bin" + desc = "Threshold for BIN warning\nExample: 50% means warn if sell price is 50% higher than lowest bin\n\u00A7c\u00a7lWARNING: \u00A7r\u00A7c100% will if above lbin always trigger, 0% instead will never trigger" ) @ConfigEditorSlider( minValue = 0.0f, diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ApiData.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ApiData.java index 9ed09ac3..9802af89 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ApiData.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ApiData.java @@ -31,7 +31,8 @@ public class ApiData { @Expose @ConfigOption( name = "Api Key", - desc = "Hypixel api key\nYou can run §a/api new§r to autofill this value." + desc = "Hypixel API key\nYou can run §a/api new§r to autofill this value.", + searchTags = "apikey" ) @ConfigEditorText public String apiKey = ""; @@ -41,57 +42,87 @@ public class ApiData { public boolean repository = false; @Expose - @ConfigOption(name = "Automatically Update Repository", desc = "Update the repository on every startup") + @ConfigOption( + name = "Automatically Update Repository", + desc = "Update the repository on every startup" + ) @ConfigEditorBoolean() @ConfigAccordionId(id = 0) public boolean autoupdate = true; @ConfigAccordionId(id = 0) - @ConfigOption(name = "Update Repository now", desc = "Refresh your repository") + @ConfigOption( + name = "Update Repository now", + desc = "Refresh your repository" + ) @ConfigEditorButton(runnableId = 22, buttonText = "Update") public int updateRepositoryButton = 0; @ConfigEditorAccordion(id = 1) @ConfigAccordionId(id = 0) - @ConfigOption(name = "Repository Location", desc = "") + @ConfigOption( + name = "Repository Location", + desc = "" + ) public boolean repositoryLocation = false; @ConfigAccordionId(id = 1) - @ConfigOption(name = "Use default repository", desc = "The latest, most up to date item list for the official NEU releases.") + @ConfigOption( + name = "Use default repository", + desc = "The latest, most up to date item list for the official NEU releases." + ) @ConfigEditorButton(runnableId = 23, buttonText = "Reset") public int setRepositoryToDefaultButton = 0; @ConfigAccordionId(id = 1) - @ConfigOption(name = "Use pre-release repository", desc = "The latest, most up to date item list for the NEU pre-releases.\n§4Use §lonly§r§4 with the pre-releases.") + @ConfigOption( + name = "Use pre-release repository", + desc = "The latest, most up to date item list for the NEU pre-releases.\n§4Use §lonly§r§4 with the pre-releases." + ) @ConfigEditorButton(runnableId = 24, buttonText = "Use") public int setRepositoryToDangerousButton = 0; @Expose @ConfigAccordionId(id = 1) - @ConfigOption(name = "Repository User", desc = "Repository User") + @ConfigOption( + name = "Repository User", + desc = "Repository User" + ) @ConfigEditorText public String repoUser = "NotEnoughUpdates"; @Expose @ConfigAccordionId(id = 1) - @ConfigOption(name = "Repository Name", desc = "Repository Name") + @ConfigOption( + name = "Repository Name", + desc = "Repository Name" + ) @ConfigEditorText public String repoName = "NotEnoughUpdates-REPO"; @Expose @ConfigAccordionId(id = 1) - @ConfigOption(name = "Repository Branch", desc = "Repository Branch") + @ConfigOption( + name = "Repository Branch", + desc = "Repository Branch" + ) @ConfigEditorText public String repoBranch = "master"; @Expose @ConfigAccordionId(id = 0) - @ConfigOption(name = "Edit Mode", desc = "Enables you to edit items in the item list.\n§4Recommended for repository maintainers only.\n§4§lRemember: §rTurn off auto update as well") + @ConfigOption( + name = "Edit Mode", + desc = "Enables you to edit items in the item list.\n§4Recommended for repository maintainers only.\n§4§lRemember: §rTurn off auto update as well" + ) @ConfigEditorBoolean public boolean repositoryEditing = false; @Expose - @ConfigOption(name = "Lowestbin API", desc = "§4Do §lNOT §r§4change this, unless you know exactly what you are doing\n§fDefault: §amoulberry.codes") + @ConfigOption( + name = "Lowestbin API", + desc = "§4Do §lNOT §r§4change this, unless you know exactly what you are doing\n§fDefault: §amoulberry.codes" + ) @ConfigEditorText public String moulberryCodesApi = "moulberry.codes"; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/BazaarTweaks.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/BazaarTweaks.java index 2ba0b718..954af02d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/BazaarTweaks.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/BazaarTweaks.java @@ -70,12 +70,4 @@ public class BazaarTweaks { @ConfigEditorBoolean @ConfigAccordionId(id = 0) public boolean escFullClose = true; - - @Expose - @ConfigOption( - name = "Bazaar Sacks Profit", - desc = "Orders the items in your sacks in the bazaar inventory and adding buy order toggle" - ) - @ConfigEditorBoolean - public boolean bazaarSacksProfit = true; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Calendar.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Calendar.java index fe593f56..8aef92d8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Calendar.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Calendar.java @@ -28,7 +28,8 @@ public class Calendar { @Expose @ConfigOption( name = "Event Notifications", - desc = "Display notifications for skyblock calendar events" + desc = "Display notifications for SkyBlock calendar events", + searchTags = {"jacob", "dark", "farming"} ) @ConfigEditorBoolean public boolean eventNotifications = true; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/CustomArmour.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/CustomArmour.java index 6c47b7a6..0d33172d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/CustomArmour.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/CustomArmour.java @@ -29,7 +29,9 @@ public class CustomArmour { @Expose @ConfigOption( name = "Enable Equipment Hud", - desc = "Shows an overlay in your inventory showing your 4 extra armour slots" + desc = "Shows an overlay in your inventory showing your 4 extra armour slots\n" + + "\u00A7cRequires Hide Potion Effects to be enabled", + searchTags = "armor" ) @ConfigEditorBoolean public boolean enableArmourHud = true; @@ -45,7 +47,8 @@ public class CustomArmour { @Expose @ConfigOption( name = "GUI Style", - desc = "Change the colour of the GUI" + desc = "Change the colour of the GUI", + searchTags = "color" ) @ConfigEditorDropdown( values = {"Minecraft", "Grey", "PacksHQ Dark", "Transparent", "FSR"} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/DungeonMapConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/DungeonMapConfig.java index 4397c02e..eb7bdca1 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/DungeonMapConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/DungeonMapConfig.java @@ -73,7 +73,7 @@ public class DungeonMapConfig { name = "Show Dungeon Map", desc = "Show/hide the NEU dungeon map" ) - public boolean dmEnable = false; + public boolean dmEnable = true; @Expose @ConfigOption( @@ -127,14 +127,16 @@ public class DungeonMapConfig { @Expose @ConfigOption( name = "Background Colour", - desc = "Colour of the map background. Supports opacity & chroma" + desc = "Colour of the map background. Supports opacity & chroma", + searchTags = "color" ) public String dmBackgroundColour = "00:170:75:75:75"; @Expose @ConfigOption( name = "Border Colour", - desc = "Colour of the map border. Supports opacity & chroma. Turn off custom borders to see" + desc = "Colour of the map border. Supports opacity & chroma. Turn off custom borders to see", + searchTags = "color" ) public String dmBorderColour = "00:0:0:0:0"; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Dungeons.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Dungeons.java index c94bd181..cf5635ec 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Dungeons.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Dungeons.java @@ -54,7 +54,7 @@ public class Dungeons { @Expose @ConfigOption( name = "Edit Dungeon Map", - desc = "The NEU dungeon map has it's own editor (/neumap).\n" + + desc = "The NEU dungeon map has its own editor (/neumap).\n" + "Click the button on the left to open it" ) @ConfigEditorButton( @@ -183,7 +183,8 @@ public class Dungeons { @Expose @ConfigOption( name = "Enable Block Overlay", - desc = "Change the colour of certain blocks / entities while inside dungeons, but keeps the normal texture outside of dungeons" + desc = "Change the colour of certain blocks / entities while inside dungeons, but keeps the normal texture outside of dungeons", + searchTags = "color" ) @ConfigEditorBoolean @ConfigAccordionId(id = 2) @@ -203,7 +204,8 @@ public class Dungeons { name = "Slow Update", desc = "Updates the colour every second instead of every tick.\n" + "\u00A7cWARNING: This will cause all texture animations (eg. flowing water) to update slowly.\n" + - "This should only be used on low-end machines" + "This should only be used on low-end machines", + searchTags = "color" ) @ConfigEditorBoolean @ConfigAccordionId(id = 2) @@ -212,7 +214,8 @@ public class Dungeons { @Expose @ConfigOption( name = "Cracked Bricks", - desc = "Change the colour of: Cracked Bricks" + desc = "Change the colour of: Cracked Bricks", + searchTags = "color" ) @ConfigEditorColour @ConfigAccordionId(id = 2) @@ -221,7 +224,8 @@ public class Dungeons { @Expose @ConfigOption( name = "Dispensers", - desc = "Change the colour of: Dispensers" + desc = "Change the colour of: Dispensers", + searchTags = "color" ) @ConfigEditorColour @ConfigAccordionId(id = 2) @@ -230,7 +234,8 @@ public class Dungeons { @Expose @ConfigOption( name = "Levers", - desc = "Change the colour of: Levers" + desc = "Change the colour of: Levers", + searchTags = "color" ) @ConfigEditorColour @ConfigAccordionId(id = 2) @@ -239,7 +244,8 @@ public class Dungeons { @Expose @ConfigOption( name = "Tripwire String", - desc = "Change the colour of: Tripwire String" + desc = "Change the colour of: Tripwire String", + searchTags = "color" ) @ConfigEditorColour @ConfigAccordionId(id = 2) @@ -248,7 +254,8 @@ public class Dungeons { @Expose @ConfigOption( name = "Normal Chests", - desc = "Change the colour of: Normal Chests" + desc = "Change the colour of: Normal Chests", + searchTags = "color" ) @ConfigEditorColour @ConfigAccordionId(id = 2) @@ -257,7 +264,8 @@ public class Dungeons { @Expose @ConfigOption( name = "Trapped Chests", - desc = "Change the colour of: Trapped Chests" + desc = "Change the colour of: Trapped Chests", + searchTags = "color" ) @ConfigEditorColour @ConfigAccordionId(id = 2) @@ -266,7 +274,8 @@ public class Dungeons { @Expose @ConfigOption( name = "Bats", - desc = "Change the colour of: Bats" + desc = "Change the colour of: Bats", + searchTags = "color" ) @ConfigEditorColour @ConfigAccordionId(id = 2) diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Enchanting.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Enchanting.java index 2f3ffa36..c2ac4bb4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Enchanting.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Enchanting.java @@ -28,8 +28,9 @@ import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption public class Enchanting { @ConfigOption( - name = "Enchant Table GUI", - desc = "" + name = "Enchant Table / Hex GUI", + desc = "", + searchTags = "et" ) @ConfigEditorAccordion(id = 1) public boolean tableGUIAccordion = false; @@ -43,6 +44,15 @@ public class Enchanting { @ConfigAccordionId(id = 1) public boolean enableTableGUI = true; + @Expose + @ConfigOption( + name = "Enable Hex GUI", + desc = "Show a custom GUI when using the Hex" + ) + @ConfigEditorBoolean + @ConfigAccordionId(id = 1) + public boolean enableHexGUI = true; + /*@Expose @ConfigOption( name = "Incompatible Enchants", @@ -76,6 +86,15 @@ public class Enchanting { @ConfigAccordionId(id = 1) public int enchantOrdering = 0; + @Expose + @ConfigOption( + name = "Use highest level from /et in /hex", + desc = "Show max level from /et in hex instead of highest possible" + ) + @ConfigEditorBoolean() + @ConfigAccordionId(id = 1) + public boolean maxEnchLevel = false; + @ConfigOption( name = "Enchanting Solvers", desc = "" @@ -114,7 +133,7 @@ public class Enchanting { @Expose @ConfigOption( name = "Ultrasequencer Numbers", - desc = "Replace the items in the supersequencer with only numbers" + desc = "Replace the items in the Ultrasequencer with only numbers" ) @ConfigEditorBoolean @ConfigAccordionId(id = 0) @@ -141,7 +160,8 @@ public class Enchanting { @Expose @ConfigOption( name = "Ultrasequencer Next", - desc = "Set the colour of the glass pane shown behind the element in the ultrasequencer which is next" + desc = "Set the colour of the glass pane shown behind the element in the ultrasequencer which is next", + searchTags = "color" ) @ConfigEditorDropdown( values = { @@ -155,7 +175,8 @@ public class Enchanting { @Expose @ConfigOption( name = "Ultrasequencer Upcoming", - desc = "Set the colour of the glass pane shown behind the element in the ultrasequencer which is coming after \"next\"" + desc = "Set the colour of the glass pane shown behind the element in the ultrasequencer which is coming after \"next\"", + searchTags = "color" ) @ConfigEditorDropdown( values = { @@ -169,7 +190,8 @@ public class Enchanting { @Expose @ConfigOption( name = "Superpairs Matched", - desc = "Set the colour of the glass pane shown behind successfully matched pairs" + desc = "Set the colour of the glass pane shown behind successfully matched pairs", + searchTags = "color" ) @ConfigEditorDropdown( values = { @@ -183,7 +205,8 @@ public class Enchanting { @Expose @ConfigOption( name = "Superpairs Possible", - desc = "Set the colour of the glass pane shown behind pairs which can be matched, but have not yet" + desc = "Set the colour of the glass pane shown behind pairs which can be matched, but have not yet", + searchTags = "color" ) @ConfigEditorDropdown( values = { @@ -197,7 +220,8 @@ public class Enchanting { @Expose @ConfigOption( name = "Superpairs Unmatched", - desc = "Set the colour of the glass pane shown behind pairs which have been previously uncovered" + desc = "Set the colour of the glass pane shown behind pairs which have been previously uncovered", + searchTags = "color" ) @ConfigEditorDropdown( values = { @@ -211,7 +235,8 @@ public class Enchanting { @Expose @ConfigOption( name = "Superpairs Powerups", - desc = "Set the colour of the glass pane shown behind powerups" + desc = "Set the colour of the glass pane shown behind powerups", + searchTags = "color" ) @ConfigEditorDropdown( values = { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Fishing.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Fishing.java index b6075794..10a4de0e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Fishing.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Fishing.java @@ -144,7 +144,8 @@ public class Fishing { name = "Particle Type", desc = "Change the type of the particle that is spawned\n" + "Particle types with (RGB) support custom colours\n" + - "Set to 'NONE' to disable particles" + "Set to 'NONE' to disable particles", + searchTags = "color" ) @ConfigEditorDropdown( values = {"Default", "None", "Spark (RGB)", "Swirl (RGB)", "Dust (RGB)", "Flame", "Crit", "Magic Crit"} @@ -156,7 +157,8 @@ public class Fishing { @ConfigOption( name = "Custom Colour", desc = "Set a custom colour for the particle\n" + - "Only works for particle types with (RGB)" + "Only works for particle types with (RGB)", + searchTags = "color" ) @ConfigEditorColour @ConfigAccordionId(id = 1) @@ -175,7 +177,8 @@ public class Fishing { name = "Particle Type", desc = "Change the type of the particle that is spawned\n" + "Particle types with (RGB) support custom colours\n" + - "Set to 'NONE' to disable particles" + "Set to 'NONE' to disable particles", + searchTags = "color" ) @ConfigEditorDropdown( values = {"Default", "None", "Spark (RGB)", "Swirl (RGB)", "Dust (RGB)", "Flame", "Crit", "Magic Crit"} @@ -187,7 +190,8 @@ public class Fishing { @ConfigOption( name = "Custom Colour", desc = "Set a custom colour for the particle\n" + - "Only works for particle types with (RGB)" + "Only works for particle types with (RGB)", + searchTags = "color" ) @ConfigEditorColour @ConfigAccordionId(id = 2) @@ -195,7 +199,8 @@ public class Fishing { @ConfigOption( name = "Rod Line Colours", - desc = "" + desc = "", + searchTags = "color" ) @ConfigEditorAccordion(id = 4) public boolean rodAccordion = false; @@ -248,8 +253,9 @@ public class Fishing { @Expose @ConfigOption( - name = "Fishing timer color", - desc = "Color of the fishing timer" + name = "Fishing timer colour", + desc = "Colour of the fishing timer", + searchTags = "color" ) @ConfigEditorColour @ConfigAccordionId(id = 6) @@ -257,8 +263,9 @@ public class Fishing { @Expose @ConfigOption( - name = "Fishing timer color (30s)", - desc = "Color of the fishing timer after 30 seconds or more have passed" + name = "Fishing timer colour (30s)", + desc = "Colour of the fishing timer after 30 seconds or more have passed", + searchTags = "color" ) @ConfigEditorColour @ConfigAccordionId(id = 6) diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ImprovedSBMenu.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ImprovedSBMenu.java index 8216c892..bdb73fa9 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ImprovedSBMenu.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ImprovedSBMenu.java @@ -28,7 +28,7 @@ public class ImprovedSBMenu { @Expose @ConfigOption( name = "Enable Improved SB Menus", - desc = "Change the way that skyblock menus (eg. /sbmenu) look" + desc = "Change the way that SkyBlock menus (eg. /sbmenu) look" ) @ConfigEditorBoolean public boolean enableSbMenus = true; @@ -36,7 +36,7 @@ public class ImprovedSBMenu { @Expose @ConfigOption( name = "Menu Background Style", - desc = "Change the style of the background of skyblock menus" + desc = "Change the style of the background of SkyBlock menus" ) @ConfigEditorDropdown( values = { @@ -49,7 +49,7 @@ public class ImprovedSBMenu { @Expose @ConfigOption( name = "Button Background Style", - desc = "Change the style of the foreground elements in skyblock menus" + desc = "Change the style of the foreground elements in SkyBlock menus" ) @ConfigEditorDropdown( values = { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/InventoryButtons.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/InventoryButtons.java index 685aeb98..36dd1a01 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/InventoryButtons.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/InventoryButtons.java @@ -23,6 +23,7 @@ import com.google.gson.annotations.Expose; import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorBoolean; import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorButton; import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorDropdown; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorSlider; import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption; public class InventoryButtons { @@ -51,4 +52,16 @@ public class InventoryButtons { values = {"Mouse Down", "Mouse Up"} ) public int clickType = 0; + + @Expose + @ConfigOption( + name = "Tooltip Delay", + desc = "Change the Tooltip Delay in milliseconds" + ) + @ConfigEditorSlider( + minValue = 0, + maxValue = 1500, + minStep = 50 + ) + public int tooltipDelay = 600; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ItemOverlays.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ItemOverlays.java index 5fde76a5..3222ce46 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ItemOverlays.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ItemOverlays.java @@ -38,7 +38,8 @@ import java.util.List; public class ItemOverlays { @ConfigOption( name = "Treecapitator Overlay", - desc = "" + desc = "", + searchTags = "jungle" ) @ConfigEditorAccordion(id = 0) public boolean treecapAccordion = false; @@ -64,7 +65,8 @@ public class ItemOverlays { @Expose @ConfigOption( name = "Overlay Colour", - desc = "Change the colour of the overlay" + desc = "Change the colour of the overlay", + searchTags = "color" ) @ConfigEditorColour @ConfigAccordionId(id = 0) @@ -107,7 +109,8 @@ public class ItemOverlays { @Expose @ConfigOption( name = "Overlay Colour", - desc = "Change the colour of the ghost block outline" + desc = "Change the colour of the ghost block outline", + searchTags = "color" ) @ConfigEditorColour @ConfigAccordionId(id = 1) @@ -132,7 +135,8 @@ public class ItemOverlays { @Expose @ConfigOption( name = "Overlay Colour", - desc = "Change the colour of the ghost block outline" + desc = "Change the colour of the ghost block outline", + searchTags = "color" ) @ConfigEditorColour @ConfigAccordionId(id = 6) @@ -244,7 +248,8 @@ public class ItemOverlays { @Expose @ConfigOption( name = "Highlight Colour", - desc = "Change the colour of the etherwarp target block outline" + desc = "Change the colour of the etherwarp target block outline", + searchTags = "color" ) @ConfigEditorColour @ConfigAccordionId(id = 7) diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Itemlist.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Itemlist.java index c83f370f..17ac7acd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Itemlist.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Itemlist.java @@ -53,6 +53,15 @@ public class Itemlist { @Expose @ConfigOption( + name = "Open when searching", + desc = "Open the Itemlist when in container search mode by double clicking the search bar" + ) + @ConfigEditorBoolean + public boolean openWhenSearching = true; + + + @Expose + @ConfigOption( name = "Item Style", desc = "Sets the style of the background behind items" ) @@ -110,7 +119,8 @@ public class Itemlist { @Expose @ConfigOption( name = "Foreground Colour", - desc = "Change the colour of foreground elements in the Itemlist" + desc = "Change the colour of foreground elements in the Itemlist", + searchTags = "color" ) @ConfigEditorColour public String foregroundColour = "00:255:100:100:100"; @@ -118,7 +128,8 @@ public class Itemlist { @Expose @ConfigOption( name = "Favourite Colour", - desc = "Change the colour of favourited elements in the Itemlist" + desc = "Change the colour of favourited elements in the Itemlist", + searchTags = "color" ) @ConfigEditorColour public String favouriteColour = "00:255:200:150:50"; @@ -126,7 +137,8 @@ public class Itemlist { @Expose @ConfigOption( name = "Pane Background Colour", - desc = "Change the colour of the Itemlist background" + desc = "Change the colour of the Itemlist background", + searchTags = "color" ) @ConfigEditorColour public String backgroundColour = "15:6:0:0:255"; @@ -134,7 +146,8 @@ public class Itemlist { @Expose @ConfigOption( name = "Always show Monsters", - desc = "Always show Monster Items in the item list" + desc = "Always show Monster Items in the item list", + searchTags = "mob" ) @ConfigEditorBoolean( runnableId = 21 diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/LocationEdit.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/LocationEdit.java index 42316592..78b4cfd4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/LocationEdit.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/LocationEdit.java @@ -19,7 +19,6 @@ package io.github.moulberry.notenoughupdates.options.seperateSections; -import com.google.gson.annotations.Expose; import io.github.moulberry.notenoughupdates.core.config.Position; import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigAccordionId; import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorAccordion; @@ -27,7 +26,6 @@ import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditor import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption; public class LocationEdit { - @Expose @ConfigOption( name = "Edit Dungeon Map", desc = "The NEU dungeon map has it's own editor (/neumap).\n" + @@ -39,7 +37,6 @@ public class LocationEdit { ) public int editDungeonMap = 0; - @Expose @ConfigOption( name = "Edit Pet Info Position", desc = "Change the position of the pet info overlay" @@ -50,7 +47,6 @@ public class LocationEdit { ) public Position petInfoPosition = new Position(-1, -1); - @Expose @ConfigOption( name = "Edit Todo Position", desc = "Change the position of the Todo overlay" @@ -61,7 +57,6 @@ public class LocationEdit { ) public Position todoPosition = new Position(100, 0); - @Expose @ConfigOption( name = "Edit Bonemerang Overlay Position", desc = "Change the position of the Bonemerang overlay" @@ -72,7 +67,6 @@ public class LocationEdit { ) public Position bonemerangPosition = new Position(-1, -1); - @Expose @ConfigOption( name = "Edit Slayer Overlay Position", desc = "Change the position of the Slayer overlay" @@ -90,7 +84,6 @@ public class LocationEdit { @ConfigEditorAccordion(id = 1) public boolean inventoryAccordion = false; - @Expose @ConfigOption( name = "Edit Toolbar Positions", desc = "Change the position of the QuickCommands / Search Bar" @@ -99,7 +92,6 @@ public class LocationEdit { @ConfigEditorButton(runnableId = 6, buttonText = "Edit") public boolean positionButton = true; - @Expose @ConfigOption( name = "Open Button Editor", desc = "Open button editor GUI (/neubuttons)" @@ -115,10 +107,9 @@ public class LocationEdit { @ConfigEditorAccordion(id = 2) public boolean miningoverlayAccordion = false; - @Expose @ConfigOption( name = "Edit Dwarven Overlay Position", - desc = "Change the position of the Dwarven Mines information Overlay (commisions, powder & forge statuses)" + desc = "Change the position of the Dwarven Mines information Overlay (commissions, powder & forge statuses)" ) @ConfigEditorButton( runnableId = 1, @@ -127,7 +118,6 @@ public class LocationEdit { @ConfigAccordionId(id = 2) public Position overlayPosition = new Position(10, 100); - @Expose @ConfigOption( name = "Edit Crystal Overlay Position", desc = "Change the position of the Crystal Hollows Overlay" @@ -139,7 +129,6 @@ public class LocationEdit { @ConfigAccordionId(id = 2) public Position crystalHollowOverlayPosition = new Position(200, 0); - @Expose @ConfigOption( name = "Edit Fuel Bar Position", desc = "Change the position of the drill fuel bar" @@ -152,13 +141,23 @@ public class LocationEdit { public Position drillFuelBarPosition = new Position(0, -100, true, false); @ConfigOption( + name = "Edit Tracker Position", + desc = "Change the position of the Powder Grinding Tracker Overlay (chests and gained powder)" + ) + @ConfigEditorButton( + runnableId = 25, + buttonText = "Edit" + ) + @ConfigAccordionId(id = 2) + public Position powderGrindingTrackerPosition = new Position(10, 265); + + @ConfigOption( name = "Skill Overlays", desc = "" ) @ConfigEditorAccordion(id = 3) public boolean skilloverlayAccordion = false; - @Expose @ConfigOption( name = "Edit Farming Overlay Position", desc = "Change the position of the Farming overlay" @@ -170,7 +169,6 @@ public class LocationEdit { @ConfigAccordionId(id = 3) public Position farmingPosition = new Position(10, 200); - @Expose @ConfigOption( name = "Edit Mining Overlay Position", desc = "Change the position of the Mining overlay" @@ -182,7 +180,6 @@ public class LocationEdit { @ConfigAccordionId(id = 3) public Position miningPosition = new Position(10, 200); - @Expose @ConfigOption( name = "Edit Fishing Overlay Position", desc = "Change the position of the Fishing overlay" @@ -194,7 +191,6 @@ public class LocationEdit { @ConfigAccordionId(id = 3) public Position fishingPosition = new Position(10, 200); - @Expose @ConfigOption( name = "Edit Combat Overlay Position", desc = "Change the position of the Combat overlay" diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java index 727ad329..7a6b07fd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java @@ -156,7 +156,7 @@ public class Mining { @Expose @ConfigOption( name = "Edit Dwarven Overlay Position", - desc = "Change the position of the Dwarven Mines information Overlay (commisions, powder & forge statuses)" + desc = "Change the position of the Dwarven Mines information Overlay (commissions, powder & forge statuses)" ) @ConfigEditorButton( runnableId = 1, @@ -388,7 +388,8 @@ public class Mining { @ConfigOption( name = "Colours", - desc = "" + desc = "", + searchTags = "color" ) @ConfigEditorAccordion(id = 6) @ConfigAccordionId(id = 4) @@ -426,7 +427,8 @@ public class Mining { @Expose @ConfigOption( name = "Done Color", - desc = "Change the colour when the part is given to the NPC." + desc = "Change the colour when the part is given to the NPC.", + searchTags = "color" ) @ConfigEditorDropdown( @@ -713,6 +715,79 @@ public class Mining { ) public int wishingCompassWaypointNames = 0; + @ConfigOption( + name = "Powder Grinding Tracker", + desc = "" + ) + @ConfigEditorAccordion(id = 9) + public boolean powderGrindingTrackerAccordion = false; + + + @Expose + @ConfigOption( + name = "Enable Tracker", + desc = "Show an Overlay with useful information related to Power Grinding" + ) + @ConfigAccordionId(id = 9) + @ConfigEditorBoolean + public boolean powderGrindingTrackerEnabled = false; + + @Expose + @ConfigOption( + name = "Tracker Text", + desc = "\u00a7eDrag text to change the appearance of the Overlay\n" + + "\u00a7rGo to the Crystal Hollows to show this Overlay with useful information" + ) + @ConfigEditorDraggableList( + exampleText = { + "\u00a73Chests Found: \u00a7a13", + "\u00a73Opened Chests: \u00a7a11", + "\u00a73Unopened Chests: \u00a7c2", + "\u00a73Mithril Powder Found: \u00a726,243", + "\u00a73Average Mithril Powder/Chest: \u00a72568", + "\u00a73Gemstone Powder Found: \u00a7d6,243", + "\u00a73Average Gemstone Powder/Chest: \u00a7d568" + } + ) + @ConfigAccordionId(id = 9) + public List<Integer> powderGrindingTrackerText = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6)); + + @Expose + @ConfigOption( + name = "Edit Tracker Position", + desc = "Change the position of the Powder Grinding Tracker Overlay (chests and gained powder)" + ) + @ConfigEditorButton( + runnableId = 25, + buttonText = "Edit" + ) + @ConfigAccordionId(id = 9) + public Position powderGrindingTrackerPosition = new Position(10, 265); + + @Expose + @ConfigOption( + name = "Tracker Reset Mode", + desc = "When the Powder Grinding Tracker should be reset" + ) + @ConfigEditorDropdown( + values = {"On World Change", "On Restart", "Never"}, + initialIndex = 2 + ) + @ConfigAccordionId(id = 9) + public int powderGrindingTrackerResetMode = 2; + + @Expose + @ConfigOption( + name = "Reset Tracker", + desc = "Reset all stats for Powder Grinding Tracker" + ) + @ConfigEditorButton( + runnableId = 26, + buttonText = "Reset" + ) + @ConfigAccordionId(id = 9) + public int resetPowderGrindingTracker = 0; + @Expose @ConfigOption( name = "Puzzler Solver", diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java index 84e2322e..ededb5da 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java @@ -33,8 +33,8 @@ import org.lwjgl.input.Keyboard; public class Misc { @Expose @ConfigOption( - name = "Only Show on Skyblock", - desc = "The item list and some other GUI elements will only show on skyblock" + name = "Only Show on SkyBlock", + desc = "The item list and some other GUI elements will only show on SkyBlock" ) @ConfigEditorBoolean public boolean onlyShowOnSkyblock = true; @@ -42,7 +42,7 @@ public class Misc { @Expose @ConfigOption( name = "Hide Potion Effects", - desc = "Hide the potion effects inside your inventory while on skyblock" + desc = "Hide the potion effects inside your inventory while on SkyBlock" ) @ConfigEditorBoolean public boolean hidePotionEffect = true; @@ -126,7 +126,7 @@ public class Misc { @Expose @ConfigOption( name = "Damage Indicator Style", - desc = "Change Skyblock damage indicators to use shortened numbers\n" + + desc = "Change SkyBlock damage indicators to use shortened numbers\n" + "\u00A7cSome old animations mods break this feature" ) @ConfigEditorBoolean @@ -145,7 +145,8 @@ public class Misc { @ConfigOption( name = "Edit Enchant Colours", - desc = "Change the colours of certain skyblock enchants (/neuec)" + desc = "Change the colours of certain SkyBlock enchants (/neuec)", + searchTags = "color" ) @ConfigEditorButton(runnableId = 8, buttonText = "Open") public boolean editEnchantColoursButton = true; @@ -153,7 +154,8 @@ public class Misc { @Expose @ConfigOption( name = "Chroma Text Speed", - desc = "Change the speed of chroma text for items names (/neucustomize) and enchant colours (/neuec) with the chroma colour code (&z)" + desc = "Change the speed of chroma text for items names (/neucustomize) and enchant colours (/neuec) with the chroma colour code (&z)", + searchTags = "color" ) @ConfigEditorSlider( minValue = 10, @@ -229,4 +231,32 @@ public class Misc { @ConfigEditorBoolean public boolean abiphoneWarning = true; + @Expose + @ConfigOption( + name = "Enable Coop Warning", + desc = "Asks for confirmation when clicking the coop diamond in profile menu" + ) + @ConfigEditorBoolean + public boolean coopWarning = true; + + @Expose + @ConfigOption( + name = "Filter Skyblock Levels in Chat", + desc = "Requires the \"SkyBlock Levels in Chat\" skyblock setting to be on" + ) + @ConfigEditorSlider( + minValue = 0, + maxValue = 300, + minStep = 10 + ) + public int filterChatLevel = 0; + + @Expose + @ConfigOption( + name = "Enable text field tweaks", + desc = "Allows the use of ctrl + z, ctrl + y and ctrl + Lshift + z in text fields" + ) + @ConfigEditorBoolean + public boolean textFieldTweaksEnabled = true; + } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MiscOverlays.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MiscOverlays.java index 18b89733..e73614d1 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MiscOverlays.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MiscOverlays.java @@ -77,10 +77,11 @@ public class MiscOverlays { "\u00a73Mithril Powder: \u00a7e3h38m", "\u00a73Gemstone Powder: \u00a7e3h38m", "\u00a73Heavy Pearls: \u00a7e3h38m", + "\u00a73Crimson Isle Quests: \u00a7e3h38m", } ) @ConfigAccordionId(id = 0) - public List<Integer> todoText2 = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)); + public List<Integer> todoText2 = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); @ConfigOption( name = "Show Only If Soon", @@ -211,9 +212,22 @@ public class MiscOverlays { public int dailyHeavyPearlDisplay = 0; + @Expose + @ConfigOption( + name = "Crimson Isle Quests Display", + desc = "Change the way the crimson isle quests display\n" + + "Only when ready, When very Soon, When soon, When kinda soon or always." + ) + @ConfigAccordionId(id = 1) + @ConfigEditorDropdown( + values = {"Only when ready", "When very Soon", "When soon", "When Kinda Soon", "Always"} + ) + public int questBoardDisplay = 0; + @ConfigOption( name = "Colours", - desc = "" + desc = "", + searchTags = "color" ) @ConfigEditorAccordion(id = 2) diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/PetOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/PetOverlay.java index 353c4e08..6f0d5341 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/PetOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/PetOverlay.java @@ -108,7 +108,8 @@ public class PetOverlay { @Expose @ConfigOption( name = "GUI Style", - desc = "Change the colour of the GUI" + desc = "Change the colour of the GUI", + searchTags = "color" ) @ConfigEditorDropdown( values = {"Minecraft", "Grey", "PacksHQ Dark", "Transparent", "FSR"} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java index 673e1015..951438fb 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java @@ -94,4 +94,12 @@ public class ProfileViewer { ) @ConfigEditorBoolean public boolean showPronounsInPv = BuildFlags.ENABLE_PRONOUNS_IN_PV_BY_DEFAULT; + + @Expose + @ConfigOption( + name = "Use Soopy Networth", + desc = "Replaces NEU networth with Soopy networth in /pv and /peek" + ) + @ConfigEditorBoolean + public boolean useSoopyNetworth = true; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SkillOverlays.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SkillOverlays.java index 943417e6..2925887f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SkillOverlays.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/SkillOverlays.java @@ -92,7 +92,7 @@ public class SkillOverlays { @Expose @ConfigOption( name = "Use BZ Price For Coins/m", - desc = "Uses the bazzar price instead of NPC price for coins/m" + desc = "Uses the bazaar price instead of NPC price for coins/m" ) @ConfigEditorBoolean @ConfigAccordionId(id = 0) @@ -100,6 +100,19 @@ public class SkillOverlays { @Expose @ConfigOption( + name = "Pause Timer", + desc = "How many seconds does it wait before pausing" + ) + @ConfigAccordionId(id = 0) + @ConfigEditorSlider( + minValue = 1, + maxValue = 20, + minStep = 1 + ) + public int farmingPauseTimer = 3; + + @Expose + @ConfigOption( name = "Edit Farming Overlay Position", desc = "Change the position of the Farming overlay" ) @@ -159,6 +172,19 @@ public class SkillOverlays { @Expose @ConfigOption( + name = "Pause Timer", + desc = "How many seconds does it wait before pausing" + ) + @ConfigAccordionId(id = 1) + @ConfigEditorSlider( + minValue = 1, + maxValue = 20, + minStep = 1 + ) + public int miningPauseTimer = 3; + + @Expose + @ConfigOption( name = "Edit Mining Overlay Position", desc = "Change the position of the Mining overlay" ) @@ -220,6 +246,19 @@ public class SkillOverlays { @Expose @ConfigOption( + name = "Pause Timer", + desc = "How many seconds does it wait before pausing" + ) + @ConfigAccordionId(id = 3) + @ConfigEditorSlider( + minValue = 1, + maxValue = 20, + minStep = 1 + ) + public int fishingPauseTimer = 3; + + @Expose + @ConfigOption( name = "Edit Fishing Overlay Position", desc = "Change the position of the Fishing overlay" ) @@ -286,7 +325,8 @@ public class SkillOverlays { @Expose @ConfigOption( name = "Enable Combat Overlay", - desc = "Show an overlay while Combat with useful information" + desc = "Show an overlay while Combat with useful information", + searchTags = "champion" ) @ConfigEditorBoolean @ConfigAccordionId(id = 4) @@ -314,6 +354,19 @@ public class SkillOverlays { @Expose @ConfigOption( + name = "Pause Timer", + desc = "How many seconds does it wait before pausing" + ) + @ConfigAccordionId(id = 4) + @ConfigEditorSlider( + minValue = 1, + maxValue = 20, + minStep = 1 + ) + public int combatPauseTimer = 3; + + @Expose + @ConfigOption( name = "Edit Combat Overlay Position", desc = "Change the position of the Combat overlay" ) diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/StorageGUI.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/StorageGUI.java index e43fa5cf..08c48945 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/StorageGUI.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/StorageGUI.java @@ -34,7 +34,8 @@ import org.lwjgl.input.Keyboard; public class StorageGUI { @ConfigOption( name = "Storage Overlay", - desc = "" + desc = "", + searchTags = {"ec", "enderchest", "st", "backpack"} ) @ConfigEditorAccordion(id = 1) public boolean storageOverlayAccordion = false; @@ -145,7 +146,8 @@ public class StorageGUI { @Expose @ConfigOption( name = "Selected Storage Colour", - desc = "Change the colour used to draw the selected backpack border" + desc = "Change the colour used to draw the selected backpack border", + searchTags = "color" ) @ConfigEditorColour @ConfigAccordionId(id = 1) @@ -163,7 +165,8 @@ public class StorageGUI { @ConfigOption( name = "Inventory Backpacks", - desc = "" + desc = "", + searchTags = "hotbar" ) @ConfigEditorAccordion(id = 0) public boolean inventorySlotAccordion = false; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/TooltipTweaks.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/TooltipTweaks.java index 1edc0921..1697098e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/TooltipTweaks.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/TooltipTweaks.java @@ -156,7 +156,8 @@ public class TooltipTweaks { @Expose @ConfigOption( name = "Tooltip Border Colours", - desc = "Make the borders of tooltips match the rarity of the item (NEU Tooltips Only)" + desc = "Make the borders of tooltips match the rarity of the item (NEU Tooltips Only)", + searchTags = "color" ) @ConfigEditorBoolean public boolean tooltipBorderColours = true; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/TradeMenu.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/TradeMenu.java index d2b4e0bb..88f713c4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/TradeMenu.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/TradeMenu.java @@ -27,7 +27,7 @@ public class TradeMenu { @Expose @ConfigOption( name = "Enable Custom Trade Menu", - desc = "When trading with other players in skyblock, display a special GUI designed to prevent scamming" + desc = "When trading with other players in SkyBlock, display a special GUI designed to prevent scamming" ) @ConfigEditorBoolean public boolean enableCustomTrade = true; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java index 4ad6767d..45ce0098 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java @@ -82,6 +82,7 @@ public class CombatSkillOverlay public void update() { if (!NotEnoughUpdates.INSTANCE.config.skillOverlays.combatSkillOverlay) { kill = -1; + championXp = -1; overlayStrings = null; return; } @@ -91,6 +92,7 @@ public class CombatSkillOverlay championXpLast = championXp; xpGainHourLast = xpGainHour; kill = -1; + championXp = -1; if (Minecraft.getMinecraft().thePlayer == null) return; @@ -177,7 +179,7 @@ public class CombatSkillOverlay float delta = totalXp - lastTotalXp; if (delta > 0 && delta < 1000) { - xpGainTimer = 3; + xpGainTimer = NotEnoughUpdates.INSTANCE.config.skillOverlays.combatPauseTimer; xpGainQueue.add(0, delta); while (xpGainQueue.size() > 30) { @@ -216,7 +218,7 @@ public class CombatSkillOverlay killQueue.removeLast(); } - if (kill != -1) { + if (kill != -1 || championXp != -1) { overlayStrings = new ArrayList<>(); } else { overlayStrings = null; @@ -228,7 +230,7 @@ public class CombatSkillOverlay public void updateFrequent() { super.updateFrequent(); - if ((kill < 0 || championXp < 0) && !NotEnoughUpdates.INSTANCE.config.skillOverlays.alwaysShowCombatOverlay) { + if ((kill < 0 && championXp < 0) && !NotEnoughUpdates.INSTANCE.config.skillOverlays.alwaysShowCombatOverlay) { overlayStrings = null; } else { HashMap<Integer, String> lineMap = new HashMap<>(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/EquipmentOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/EquipmentOverlay.java new file mode 100644 index 00000000..5cd8f6b3 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/EquipmentOverlay.java @@ -0,0 +1,461 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.overlays; + +import com.google.common.collect.Lists; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import io.github.moulberry.notenoughupdates.NEUManager; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.events.GuiInventoryBackgroundDrawnEvent; +import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay; +import io.github.moulberry.notenoughupdates.miscgui.GuiInvButtonEditor; +import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer; +import io.github.moulberry.notenoughupdates.options.NEUConfig; +import io.github.moulberry.notenoughupdates.util.ItemUtils; +import io.github.moulberry.notenoughupdates.util.SBInfo; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.inventory.GuiChest; +import net.minecraft.client.gui.inventory.GuiInventory; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.inventory.ContainerChest; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.event.GuiScreenEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import net.minecraftforge.fml.relauncher.Side; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class EquipmentOverlay { + public static EquipmentOverlay INSTANCE = new EquipmentOverlay(); + + // <editor-fold desc="resources"> + private static final ResourceLocation ARMOR_DISPLAY = new ResourceLocation( + "notenoughupdates:armordisplay/armordisplay.png"); + private static final ResourceLocation ARMOR_DISPLAY_GREY = new ResourceLocation( + "notenoughupdates:armordisplay/armordisplay_grey.png"); + private static final ResourceLocation ARMOR_DISPLAY_DARK = new ResourceLocation( + "notenoughupdates:armordisplay/armordisplay_phq_dark.png"); + private static final ResourceLocation ARMOR_DISPLAY_FSR = new ResourceLocation( + "notenoughupdates:armordisplay/armordisplay_fsr.png"); + private static final ResourceLocation ARMOR_DISPLAY_TRANSPARENT = new ResourceLocation( + "notenoughupdates:armordisplay/armordisplay_transparent.png"); + private static final ResourceLocation ARMOR_DISPLAY_TRANSPARENT_PET = new ResourceLocation( + "notenoughupdates:armordisplay/armordisplay_transparent_pet.png"); + + private static final ResourceLocation QUESTION_MARK = new ResourceLocation("notenoughupdates:pv_unknown.png"); + + private static final ResourceLocation PET_DISPLAY = new ResourceLocation( + "notenoughupdates:petdisplay/petdisplaysolo.png"); + private static final ResourceLocation PET_DISPLAY_GREY = new ResourceLocation( + "notenoughupdates:petdisplay/petdisplaysolo_dark.png"); + private static final ResourceLocation PET_DISPLAY_DARK = new ResourceLocation( + "notenoughupdates:petdisplay/petdisplaysolo_phqdark.png"); + private static final ResourceLocation PET_DISPLAY_FSR = new ResourceLocation( + "notenoughupdates:petdisplay/petdisplaysolo_fsr.png"); + private static final ResourceLocation PET_DISPLAY_TRANSPARENT = new ResourceLocation( + "notenoughupdates:petdisplay/petdisplaysolo_transparent.png"); + + private static final ResourceLocation PET_ARMOR_DISPLAY = new ResourceLocation( + "notenoughupdates:petdisplay/petdisplayarmor.png"); + private static final ResourceLocation PET_ARMOR_DISPLAY_GREY = new ResourceLocation( + "notenoughupdates:petdisplay/petdisplayarmor_dark.png"); + private static final ResourceLocation PET_ARMOR_DISPLAY_DARK = new ResourceLocation( + "notenoughupdates:petdisplay/petdisplayarmor_phqdark.png"); + private static final ResourceLocation PET_ARMOR_DISPLAY_FSR = new ResourceLocation( + "notenoughupdates:petdisplay/petdisplayarmor_fsr.png"); + private static final ResourceLocation PET_ARMOR_DISPLAY_TRANSPARENT = new ResourceLocation( + "notenoughupdates:petdisplay/petdisplayarmor_transparent.png"); + //</editor-fold> + + //<editor-fold desc="dynamic resources"> + public ResourceLocation getCustomEquipmentTexture(boolean isPetRendering) { + switch (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle) { + case 0: + return ARMOR_DISPLAY; + case 1: + return ARMOR_DISPLAY_GREY; + case 2: + return ARMOR_DISPLAY_DARK; + case 3: + return NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 3 && isPetRendering ? ARMOR_DISPLAY_TRANSPARENT_PET : ARMOR_DISPLAY_TRANSPARENT; + case 4: + return ARMOR_DISPLAY_FSR; + } + return null; + } + + public ResourceLocation getCustomPetTexture(boolean isArmorRendering) { + switch (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle) { + case 0: + return isArmorRendering ? PET_ARMOR_DISPLAY : PET_DISPLAY; + case 1: + return isArmorRendering ? PET_ARMOR_DISPLAY_GREY : PET_DISPLAY_GREY; + case 2: + return isArmorRendering ? PET_ARMOR_DISPLAY_DARK : PET_DISPLAY_DARK; + case 3: + return isArmorRendering ? PET_ARMOR_DISPLAY_TRANSPARENT : PET_DISPLAY_TRANSPARENT; + case 4: + return isArmorRendering ? PET_ARMOR_DISPLAY_FSR : PET_DISPLAY_FSR; + } + return null; + } + //</editor-fold> + + //<editor-fold desc="pixel constants"> + public static final int EQUIPMENT_SLOT_OFFSET_Y = 8; + public static final int ARMOR_OVERLAY_OVERHAND_WIDTH = 24; + public static final int ARMOR_OVERLAY_HEIGHT = 86; + public static final int ARMOR_OVERLAY_WIDTH = 31; + final static int PET_OVERLAY_HEIGHT = 32; + final static int PET_OVERLAY_WIDTH = 31; + public static final int PET_OVERLAY_OFFSET_Y = ARMOR_OVERLAY_HEIGHT - 14 /* overlaying pixels */; + //</editor-fold> + + + public boolean shouldRenderPets; + public boolean shouldRenderArmorHud; + + public ItemStack petStack; + + //<editor-fold desc="events"> + + @SubscribeEvent + public void onGuiTick(TickEvent.ClientTickEvent event) { + if (event.phase != TickEvent.Phase.START || event.side != Side.CLIENT) return; + updateGuiInfo(Minecraft.getMinecraft().currentScreen); + } + + @SubscribeEvent + public void onGuiInit(GuiScreenEvent.InitGuiEvent event) { + updateGuiInfo(event.gui); + } + + @SubscribeEvent + public void onRenderGuiPost(GuiInventoryBackgroundDrawnEvent event) { + if (!(event.getContainer() instanceof GuiInventory)) return; + GuiInventory inventory = ((GuiInventory) event.getContainer()); + renderGuis(inventory); + } + + //</editor-fold> + + public void renderGuis(GuiInventory inventory) { + int width = Utils.peekGuiScale().getScaledWidth(); + int height = Utils.peekGuiScale().getScaledHeight(); + int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth; + int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1; + + GL11.glColor4f(1F, 1F, 1F, 1F); + if (shouldRenderArmorHud) { + renderEquipmentGui(inventory, mouseX, mouseY, width, height); + } + + if (shouldRenderPets) { + renderPets(inventory, mouseX, mouseY, width, height); + } + } + + public void renderEquipmentGui(GuiInventory guiScreen, int mouseX, int mouseY, int width, int height) { + AccessorGuiContainer container = ((AccessorGuiContainer) guiScreen); + + int overlayLeft = container.getGuiLeft() - ARMOR_OVERLAY_OVERHAND_WIDTH; + int overlayTop = container.getGuiTop(); + + ResourceLocation equipmentTexture = getCustomEquipmentTexture(shouldRenderPets); + Minecraft.getMinecraft().getTextureManager().bindTexture(equipmentTexture); + + Utils.drawTexturedRect(overlayLeft, overlayTop, ARMOR_OVERLAY_WIDTH, ARMOR_OVERLAY_HEIGHT, GL11.GL_NEAREST); + + List<String> tooltipToDisplay = new ArrayList<>(); + drawSlot(slot1, overlayLeft + 8, overlayTop + EQUIPMENT_SLOT_OFFSET_Y, mouseX, mouseY, tooltipToDisplay); + drawSlot(slot2, overlayLeft + 8, overlayTop + EQUIPMENT_SLOT_OFFSET_Y + 18, mouseX, mouseY, tooltipToDisplay); + drawSlot(slot3, overlayLeft + 8, overlayTop + EQUIPMENT_SLOT_OFFSET_Y + 36, mouseX, mouseY, tooltipToDisplay); + drawSlot(slot4, overlayLeft + 8, overlayTop + EQUIPMENT_SLOT_OFFSET_Y + 54, mouseX, mouseY, tooltipToDisplay); + + if (slot1 == null) { + Minecraft.getMinecraft().getTextureManager().bindTexture(QUESTION_MARK); + GlStateManager.color(1, 1, 1, 1); + Utils.drawTexturedRect(overlayLeft + 8, overlayTop + EQUIPMENT_SLOT_OFFSET_Y, 16, 16, GL11.GL_NEAREST); + + tooltipToDisplay = Lists.newArrayList( + EnumChatFormatting.RED + "Warning", + EnumChatFormatting.GREEN + "You need to open /equipment", + EnumChatFormatting.GREEN + "to cache your armour" + ); + if (Utils.isWithinRect(mouseX, mouseY, overlayLeft + 8, overlayTop + 8, 16, 16) + && NotEnoughUpdates.INSTANCE.config.customArmour.sendWardrobeCommand + && Mouse.getEventButtonState() + && Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) { + NotEnoughUpdates.INSTANCE.trySendCommand("/equipment"); + } + + } + if (tooltipToDisplay.size() > 0 && + Utils.isWithinRect( + mouseX, mouseY, + overlayLeft, overlayTop, + ARMOR_OVERLAY_OVERHAND_WIDTH, ARMOR_OVERLAY_HEIGHT + )) { + Utils.drawHoveringText( + tooltipToDisplay, + mouseX - calculateTooltipXOffset(tooltipToDisplay, Minecraft.getMinecraft().fontRendererObj), + mouseY, + width, + height, + -1, + Minecraft.getMinecraft().fontRendererObj + ); + } + + } + + private ItemStack getRepoPetStack() { + NEUManager manager = NotEnoughUpdates.INSTANCE.manager; + PetInfoOverlay.Pet currentPet = PetInfoOverlay.getCurrentPet(); + if (currentPet == null) return null; + + ItemStack item = ItemUtils.createPetItemstackFromPetInfo(currentPet); + item = ItemUtils.petToolTipXPExtendPetOverlay(item); + + if (item != null) { + return item; + } + item = manager.createItem(currentPet.getPetId(true)); + return item; + } + + private void updateGuiInfo(GuiScreen screen) { + if (getWardrobeSlot(10) != null) { + slot1 = getWardrobeSlot(10); + slot2 = getWardrobeSlot(19); + slot3 = getWardrobeSlot(28); + slot4 = getWardrobeSlot(37); + } + + if ((screen instanceof GuiChest || screen instanceof GuiInventory) && NotEnoughUpdates.INSTANCE.config.petOverlay.petInvDisplay){ + petStack = getRepoPetStack(); + } + if ((!(screen instanceof GuiInventory) && !(screen instanceof GuiInvButtonEditor)) + || !NotEnoughUpdates.INSTANCE.config.misc.hidePotionEffect + || !NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { + shouldRenderPets = shouldRenderArmorHud = false; + return; + } + shouldRenderPets = NotEnoughUpdates.INSTANCE.config.petOverlay.petInvDisplay && petStack != null; + shouldRenderArmorHud = NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud; + } + + private void drawSlot(ItemStack stack, int x, int y, int mouseX, int mouseY, List<String> tooltip) { + if (stack == null) return; + Utils.drawItemStack(stack, x, y, true); + if (Utils.isWithinRect(mouseX, mouseY, x, y, 16, 16)) { + List<String> tt = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false); + if (shouldShowEquipmentTooltip(tt)) + tooltip.addAll(tt); + if (NotEnoughUpdates.INSTANCE.config.customArmour.sendWardrobeCommand + && Mouse.getEventButtonState()) { + NotEnoughUpdates.INSTANCE.trySendCommand("/equipment"); + } + } + } + + public void renderPets(GuiInventory inventory, int mouseX, int mouseY, int width, int height) { + ItemUtils.getOrCreateTag(petStack).setBoolean( + "NEUHIDEPETTOOLTIP", + NotEnoughUpdates.INSTANCE.config.petOverlay.hidePetTooltip + ); + ItemStack petInfo = petStack; + + ResourceLocation customPetTexture = getCustomPetTexture(isRenderingArmorHud()); + Minecraft.getMinecraft().getTextureManager().bindTexture(customPetTexture); + GlStateManager.color(1, 1, 1, 1); + + AccessorGuiContainer container = ((AccessorGuiContainer) inventory); + + int overlayLeft = container.getGuiLeft() - ARMOR_OVERLAY_OVERHAND_WIDTH; + int overlayTop = container.getGuiTop() + PET_OVERLAY_OFFSET_Y; + + Utils.drawTexturedRect(overlayLeft, overlayTop, PET_OVERLAY_WIDTH, PET_OVERLAY_HEIGHT, GL11.GL_NEAREST); + GlStateManager.bindTexture(0); + + Utils.drawItemStack(petInfo, overlayLeft + 8, overlayTop + 8, true); + + List<String> tooltipToDisplay; + if (Utils.isWithinRect(mouseX, mouseY, overlayLeft + 8, overlayTop + 8, 16, 16)) { + if (NotEnoughUpdates.INSTANCE.config.petOverlay.sendPetsCommand + && Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null + && Mouse.getEventButtonState()) { + NotEnoughUpdates.INSTANCE.trySendCommand("/pets"); + } + tooltipToDisplay = petInfo.getTooltip(Minecraft.getMinecraft().thePlayer, false); + Utils.drawHoveringText( + tooltipToDisplay, + mouseX - calculateTooltipXOffset(tooltipToDisplay, Minecraft.getMinecraft().fontRendererObj), + mouseY, + width, + height, + -1, + Minecraft.getMinecraft().fontRendererObj + ); + } + } + + private ItemStack getWardrobeSlot(int armourSlot) { + if (SBInfo.getInstance().currentProfile == null) { + return null; + } + + if (!Objects.equals(SBInfo.getInstance().currentProfile, lastProfile)) { + lastProfile = SBInfo.getInstance().currentProfile; + slot1 = null; + slot2 = null; + slot3 = null; + slot4 = null; + } + + NEUConfig.HiddenProfileSpecific profileSpecific = NotEnoughUpdates.INSTANCE.config.getProfileSpecific(); + if (profileSpecific == null) return null; + + if (isInNamedGui("Your Equipment")) { + ItemStack itemStack = getChestSlotsAsItemStack(armourSlot); + if (itemStack != null) { + JsonObject itemToSave = NotEnoughUpdates.INSTANCE.manager.getJsonForItem(itemStack); + if (!itemToSave.has("internalname")) { + //would crash without internalName when trying to construct the ItemStack again + itemToSave.add("internalname", new JsonPrimitive("_")); + } + profileSpecific.savedEquipment.put(armourSlot, itemToSave); + return itemStack; + } + } else { + if (profileSpecific.savedEquipment.containsKey(armourSlot)) { + //don't use cache since the internalName is identical in most cases + JsonObject jsonObject = profileSpecific.savedEquipment + .get(armourSlot); + if (jsonObject != null) return NotEnoughUpdates.INSTANCE.manager.jsonToStack(jsonObject + .getAsJsonObject(), false); + } + } + return null; + } + + private boolean wardrobeOpen = false; + + private boolean isInNamedGui(String guiName) { + GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; + if (guiScreen instanceof GuiChest) { + GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; + ContainerChest container = (ContainerChest) chest.inventorySlots; + IInventory lower = container.getLowerChestInventory(); + String containerName = lower.getDisplayName().getUnformattedText(); + wardrobeOpen = containerName.contains(guiName); + } + if (guiScreen instanceof GuiInventory) { + wardrobeOpen = false; + } + return wardrobeOpen; + } + + private ItemStack getChestSlotsAsItemStack(int slot) { + GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; + if (guiScreen instanceof GuiChest) { + GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; + return chest.inventorySlots.getSlot(slot).getStack(); + } else { + return null; + } + } + + public static boolean isRenderingArmorHud() { + return INSTANCE.shouldRenderArmorHud; + } + + public static boolean isRenderingPetHud() { + return INSTANCE.shouldRenderPets; + } + + private boolean shouldShowEquipmentTooltip(List<String> toolTip) { + return !toolTip.get(0).equals("§o§7Empty Equipment Slot§r"); + } + + /** + * Calculates the width of the longest String in the tooltip, which can be used to offset the entire tooltip to the left more precisely + * + * @param tooltipToDisplay tooltip + * @param fr FontRenderer object + * @return offset to apply + */ + private int calculateTooltipXOffset(List<String> tooltipToDisplay, FontRenderer fr) { + int offset = 0; + if (tooltipToDisplay != null) { + for (String line : tooltipToDisplay) { + int lineWidth = fr.getStringWidth(line); + if (lineWidth > offset) { + offset = lineWidth; + } + } + } + return offset + 20; + } + + public void renderPreviewArmorHud() { + if (!NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud || !(Minecraft.getMinecraft().currentScreen instanceof GuiInvButtonEditor)) return; + GuiInvButtonEditor container = (GuiInvButtonEditor) Minecraft.getMinecraft().currentScreen; + + int overlayLeft = container.getGuiLeft() - ARMOR_OVERLAY_OVERHAND_WIDTH; + int overlayTop = container.getGuiTop(); + + ResourceLocation equipmentTexture = getCustomEquipmentTexture(shouldRenderPets); + Minecraft.getMinecraft().getTextureManager().bindTexture(equipmentTexture); + + Utils.drawTexturedRect(overlayLeft, overlayTop, ARMOR_OVERLAY_WIDTH, ARMOR_OVERLAY_HEIGHT, GL11.GL_NEAREST); + } + + public void renderPreviewPetInvHud() { + if (!NotEnoughUpdates.INSTANCE.config.petOverlay.petInvDisplay || !(Minecraft.getMinecraft().currentScreen instanceof GuiInvButtonEditor)) return; + GuiInvButtonEditor container = (GuiInvButtonEditor) Minecraft.getMinecraft().currentScreen; + int overlayLeft = container.getGuiLeft() - ARMOR_OVERLAY_OVERHAND_WIDTH; + int overlayTop = container.getGuiTop() + PET_OVERLAY_OFFSET_Y; + + ResourceLocation petHudTexture = getCustomPetTexture(shouldRenderArmorHud); + Minecraft.getMinecraft().getTextureManager().bindTexture(petHudTexture); + + Utils.drawTexturedRect(overlayLeft, overlayTop, PET_OVERLAY_WIDTH, PET_OVERLAY_HEIGHT, GL11.GL_NEAREST); + } + + public ItemStack slot1 = null; + public ItemStack slot2 = null; + public ItemStack slot3 = null; + public ItemStack slot4 = null; + private String lastProfile; + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingSkillOverlay.java index 970c74ab..08cbb189 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingSkillOverlay.java @@ -37,7 +37,7 @@ import java.util.LinkedList; import java.util.List; import java.util.function.Supplier; -public class FarmingOverlay extends TextOverlay { +public class FarmingSkillOverlay extends TextOverlay { private long lastUpdate = -1; private int counterLast = -1; private int counter = -1; @@ -45,9 +45,9 @@ public class FarmingOverlay extends TextOverlay { private int cultivating = -1; private int cultivatingTier = -1; private String cultivatingTierAmount = "1"; - private int Farming = -1; - private int Alch = -1; - private int Foraging = -1; + private int Farming = 1; + private int Alch = 0; + private int Foraging = 0; private double Coins = -1; private float cropsPerSecondLast = 0; private float cropsPerSecond = 0; @@ -62,11 +62,13 @@ public class FarmingOverlay extends TextOverlay { private float xpGainHourLast = -1; private float xpGainHour = -1; + private final int ENCH_SIZE = 160; + private final int ENCH_BLOCK_SIZE = 1296; private int xpGainTimer = 0; private String skillType = "Farming"; - public FarmingOverlay( + public FarmingSkillOverlay( Position position, Supplier<List<String>> dummyStrings, Supplier<TextOverlayStyle> styleSupplier @@ -84,6 +86,14 @@ public class FarmingOverlay extends TextOverlay { return interp; } + private double getCoinsBz(String enchCropName, int numItemsForEnch) { + JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo(enchCropName); + if (crop != null && crop.has("curr_sell")) { + return crop.get("curr_sell").getAsFloat() / numItemsForEnch; + } + return 0; + } + @Override public void update() { if (!NotEnoughUpdates.INSTANCE.config.skillOverlays.farmingOverlay) { @@ -121,169 +131,100 @@ public class FarmingOverlay extends TextOverlay { if (cultivating < 1000) { cultivatingTier = 1; + cultivatingTierAmount = "1,000"; } else if (cultivating < 5000) { cultivatingTier = 2; + cultivatingTierAmount = "5,000"; } else if (cultivating < 25000) { cultivatingTier = 3; + cultivatingTierAmount = "25,000"; } else if (cultivating < 100000) { cultivatingTier = 4; + cultivatingTierAmount = "100,000"; } else if (cultivating < 300000) { cultivatingTier = 5; + cultivatingTierAmount = "300,000"; } else if (cultivating < 1500000) { cultivatingTier = 6; + cultivatingTierAmount = "1,500,000"; } else if (cultivating < 5000000) { cultivatingTier = 7; + cultivatingTierAmount = "5,000,000"; } else if (cultivating < 20000000) { cultivatingTier = 8; + cultivatingTierAmount = "20,000,000"; } else if (cultivating < 100000000) { cultivatingTier = 9; + cultivatingTierAmount = "100,000,000"; } else if (cultivating > 100000000) { cultivatingTier = 10; - } - - switch (cultivatingTier) { - case 1: - cultivatingTierAmount = "1,000"; - break; - case 2: - cultivatingTierAmount = "5,000"; - break; - case 3: - cultivatingTierAmount = "25,000"; - break; - case 4: - cultivatingTierAmount = "100,000"; - break; - case 5: - cultivatingTierAmount = "300,000"; - break; - case 6: - cultivatingTierAmount = "1,500,000"; - break; - case 7: - cultivatingTierAmount = "5,000,000"; - break; - case 8: - cultivatingTierAmount = "20,000,000"; - break; - case 9: - cultivatingTierAmount = "100,000,000"; - break; - case 10: - cultivatingTierAmount = "Maxed"; - break; + cultivatingTierAmount = "Maxed"; } String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack); - if (internalname != null && internalname.startsWith("THEORETICAL_HOE_WARTS")) { - skillType = "Alchemy"; - Farming = 0; - Alch = 1; - Foraging = 0; - } else if (internalname != null && internalname.startsWith("TREECAPITATOR_AXE") || - (internalname != null && internalname.startsWith("JUNGLE_AXE"))) { - skillType = "Foraging"; - Farming = 0; - Alch = 0; - Foraging = 1; - } else { + if (internalname != null) { + + //Set default skilltype to Farming and get BZprice config value + boolean useBZPrice = NotEnoughUpdates.INSTANCE.config.skillOverlays.useBZPrice; skillType = "Farming"; - Farming = 1; - Alch = 0; - Foraging = 0; - } - if (!NotEnoughUpdates.INSTANCE.config.skillOverlays.useBZPrice || internalname != null && (internalname.equals( - "TREECAPITATOR_AXE")) || internalname != null && (internalname.equals("JUNGLE_AXE"))) { - if ((internalname != null && internalname.equals("COCO_CHOPPER"))) { - Coins = 3; - } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_POTATO") || - (internalname != null && internalname.startsWith("THEORETICAL_HOE_CARROT")) || - (internalname != null && internalname.equals("CACTUS_KNIFE")) || - (internalname != null && internalname.startsWith("THEORETICAL_HOE_WHEAT"))) { - Coins = 1; - } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_CANE") - || (internalname != null && internalname.equals("TREECAPITATOR_AXE")) - || (internalname != null && internalname.startsWith("THEORETICAL_HOE_WARTS")) - || (internalname != null && internalname.equals("JUNGLE_AXE"))) { + //WARTS + if (internalname.startsWith("THEORETICAL_HOE_WARTS")) { + skillType = "Alchemy"; + Farming = 0; + Alch = 1; + Foraging = 0; + Coins = useBZPrice ? getCoinsBz("ENCHANTED_NETHER_STALK", ENCH_SIZE) : 2; + + //WOOD + } else if (internalname.equals("TREECAPITATOR_AXE") || internalname.equalsIgnoreCase("JUNGLE_AXE")) { + skillType = "Foraging"; + Farming = 0; + Alch = 0; + Foraging = 1; Coins = 2; - } else if ((internalname != null && internalname.equals("PUMPKIN_DICER")) || - (internalname != null && internalname.equals("FUNGI_CUTTER"))) { - Coins = 4; - } else if ((internalname != null && internalname.equals("MELON_DICER"))) { - Coins = 0.5; + + //COCOA + } else if (internalname.equals("COCO_CHOPPER")) { + Coins = useBZPrice ? getCoinsBz("ENCHANTED_COCOA", ENCH_SIZE) : 3; + + //CACTUS + } else if (internalname.equals("CACTUS_KNIFE")) { + Coins = useBZPrice ? getCoinsBz("ENCHANTED_CACTUS_GREEN", ENCH_SIZE) : 2; + + //CANE + } else if (internalname.startsWith("THEORETICAL_HOE_CANE")) { + Coins = useBZPrice ? getCoinsBz("ENCHANTED_SUGAR", ENCH_SIZE) : 2; + + //CARROT + } else if (internalname.startsWith("THEORETICAL_HOE_CARROT")) { + Coins = useBZPrice ? getCoinsBz("ENCHANTED_CARROT", ENCH_SIZE) : 1; + + //POTATO + } else if (internalname.startsWith("THEORETICAL_HOE_POTATO")) { + Coins = useBZPrice ? getCoinsBz("ENCHANTED_POTATO", ENCH_SIZE) : 1; + + //MUSHROOM + } else if (internalname.equals("FUNGI_CUTTER")) { + Coins = useBZPrice ? ((getCoinsBz("ENCHANTED_RED_MUSHROOM", ENCH_SIZE) + + getCoinsBz("ENCHANTED_BROWN_MUSHROOM", ENCH_SIZE))/2) : 4; + + //PUMPKIN + } else if (internalname.equals("PUMPKIN_DICER")) { + Coins = useBZPrice ? getCoinsBz("ENCHANTED_PUMPKIN", ENCH_SIZE) : 4; + + //MELON + } else if (internalname.equals("MELON_DICER")) { + Coins = useBZPrice ? getCoinsBz("ENCHANTED_MELON", ENCH_SIZE) : 0.5; + + //WHEAT + } else if (internalname.startsWith("THEORETICAL_HOE_WHEAT")) { + Coins = useBZPrice ? getCoinsBz("ENCHANTED_HAY_BLOCK", ENCH_BLOCK_SIZE) : 1; + } else { Coins = 0; } } - if (NotEnoughUpdates.INSTANCE.config.skillOverlays.useBZPrice) { - if (internalname != null && internalname.startsWith("THEORETICAL_HOE_WARTS")) { - JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_NETHER_STALK"); - if (crop != null) { - if (crop.has("curr_sell")) { - Coins = crop.get("curr_sell").getAsFloat() / 160; - } - } - } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_POTATO")) { - JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_POTATO"); - if (crop != null) { - if (crop.has("curr_sell")) { - Coins = crop.get("curr_sell").getAsFloat() / 160; - } - } - } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_CARROT")) { - JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_CARROT"); - if (crop != null) { - if (crop.has("curr_sell")) { - Coins = crop.get("curr_sell").getAsFloat() / 160; - } - } - } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_CANE")) { - JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_SUGAR"); - if (crop != null) { - if (crop.has("curr_sell")) { - Coins = crop.get("curr_sell").getAsFloat() / 160; - } - } - } else if (internalname != null && internalname.startsWith("PUMPKIN_DICER")) { - JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_PUMPKIN"); - if (crop != null) { - if (crop.has("curr_sell")) { - Coins = crop.get("curr_sell").getAsFloat() / 160; - } - } - } else if (internalname != null && internalname.startsWith("FUNGI_CUTTER")) { - JsonObject red = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_RED_MUSHROOM"); - JsonObject brown = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_BROWN_MUSHROOM"); - if (red != null && brown != null) { - if (red.has("curr_sell") && (brown.has("curr_sell"))) { - double crop = (red.get("curr_sell").getAsFloat() + red.get("curr_sell").getAsFloat()) / 2; - Coins = crop / 160; - } - } - } else if (internalname != null && internalname.startsWith("MELON_DICER")) { - JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_MELON"); - if (crop != null) { - if (crop.has("curr_sell")) { - Coins = crop.get("curr_sell").getAsFloat() / 160; - } - } - } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_WHEAT")) { - JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_HAY_BLOCK"); - if (crop != null) { - if (crop.has("curr_sell")) { - Coins = crop.get("curr_sell").getAsFloat() / 1296; - } - } - } else if (internalname != null && internalname.startsWith("CACTUS_KNIFE")) { - JsonObject crop = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("ENCHANTED_CACTUS_GREEN"); - if (crop != null) { - if (crop.has("curr_sell")) { - Coins = crop.get("curr_sell").getAsFloat() / 160; - } - } - } - } skillInfoLast = skillInfo; skillInfo = XPInformation.getInstance().getSkillInfo(skillType); @@ -294,7 +235,8 @@ public class FarmingOverlay extends TextOverlay { float delta = totalXp - lastTotalXp; if (delta > 0 && delta < 1000) { - xpGainTimer = 3; + + xpGainTimer = NotEnoughUpdates.INSTANCE.config.skillOverlays.farmingPauseTimer; xpGainQueue.add(0, delta); while (xpGainQueue.size() > 30) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FishingSkillOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FishingSkillOverlay.java index 717ff944..b1143042 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FishingSkillOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FishingSkillOverlay.java @@ -180,7 +180,7 @@ public class FishingSkillOverlay float delta = totalXp - lastTotalXp; if (delta > 0 && delta < 1000) { - xpGainTimer = 3; + xpGainTimer = NotEnoughUpdates.INSTANCE.config.skillOverlays.fishingPauseTimer; xpGainQueue.add(0, delta); while (xpGainQueue.size() > 30) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java index d24f005d..60d9b607 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java @@ -258,7 +258,7 @@ public class MiningOverlay extends TextTabOverlay { // These strings will be displayed one after the other when the player list is disabled String mithrilPowder = RED + "[NEU] Failed to get data from your tablist"; - String gemstonePowder = RED + "Please enable player list info in your skyblock settings"; + String gemstonePowder = RED + "Please enable player list info in your SkyBlock settings"; int forgeInt = 0; boolean commissions = false; @@ -397,6 +397,12 @@ public class MiningOverlay extends TextTabOverlay { } } + if (ItemCooldowns.firstLoadMillis > 0) { + //set cooldown on first skyblock load. + ItemCooldowns.pickaxeUseCooldownMillisRemaining = 60 * 1000 - (System.currentTimeMillis() - ItemCooldowns.firstLoadMillis); + ItemCooldowns.firstLoadMillis = 0; + } + String pickaxeCooldown; if (ItemCooldowns.pickaxeUseCooldownMillisRemaining <= 0) { pickaxeCooldown = DARK_AQUA + "Pickaxe CD: \u00a7aReady"; @@ -806,6 +812,7 @@ public class MiningOverlay extends TextTabOverlay { .getItemInformation() .get("ANVIL")) ); + put("First Event", new ItemStack(Items.fireworks, 1, 0)); }}; } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningSkillOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningSkillOverlay.java index a20b1d27..4422e3ad 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningSkillOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningSkillOverlay.java @@ -172,7 +172,7 @@ public class MiningSkillOverlay float delta = totalXp - lastTotalXp; if (delta > 0 && delta < 1000) { - xpGainTimer = 3; + xpGainTimer = NotEnoughUpdates.INSTANCE.config.skillOverlays.miningPauseTimer; xpGainQueue.add(0, delta); while (xpGainQueue.size() > 30) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/OverlayManager.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/OverlayManager.java index fef11a45..5047882d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/OverlayManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/OverlayManager.java @@ -30,7 +30,8 @@ public class OverlayManager { public static Class<? extends TextOverlay> dontRenderOverlay = null; public static MiningOverlay miningOverlay; - public static FarmingOverlay farmingOverlay; + public static PowderGrindingOverlay powderGrindingOverlay; + public static FarmingSkillOverlay farmingOverlay; public static FishingSkillOverlay fishingSkillOverlay; public static MiningSkillOverlay miningSkillOverlay; public static CombatSkillOverlay combatSkillOverlay; @@ -60,7 +61,8 @@ public class OverlayManager { "\u00a73Commissions: \u00a7e3h38m", "\u00a73Experiments: \u00a7e3h38m", "\u00a73Mithril Powder: \u00a7e3h38m", - "\u00a73Gemstone Powder: \u00a7e3h38m" + "\u00a73Gemstone Powder: \u00a7e3h38m", + "\u00a73Crimson Isle Quests: \u00a7e3h38m" ); textOverlays.add( timersOverlay = new TimersOverlay(NotEnoughUpdates.INSTANCE.config.miscOverlays.todoPosition, () -> { @@ -97,6 +99,23 @@ public class OverlayManager { return TextOverlayStyle.BACKGROUND; }); + List<String> powderGrindingDummy = Lists.newArrayList( + "\u00a73Chests Found: \u00a7a13", + "\u00a73Opened Chests: \u00a7a11", + "\u00a73Unopened Chests: \u00a7c2", + "\u00a73Mithril Powder Found: \u00a726,243", + "\u00a73Average Mithril Powder/Chest: \u00a72568", + "\u00a73Gemstone Powder Found: \u00a7d6,243", + "\u00a73Average Gemstone Powder/Chest: \u00a7d568" + ); + powderGrindingOverlay = new PowderGrindingOverlay(NotEnoughUpdates.INSTANCE.config.mining.powderGrindingTrackerPosition, () -> { + List<String> strings = new ArrayList<>(); + for (int i : NotEnoughUpdates.INSTANCE.config.mining.powderGrindingTrackerText) { + if (i >= 0 && i < powderGrindingDummy.size()) strings.add(powderGrindingDummy.get(i)); + } + return strings; + }, () -> TextOverlayStyle.BACKGROUND); + List<String> farmingDummy = Lists.newArrayList( "\u00a7bCounter: \u00a7e37,547,860", "\u00a7bCrops/m: \u00a7e38.29", @@ -106,7 +125,7 @@ public class OverlayManager { "\u00a7bXP/h: \u00a7e238,129", "\u00a7bYaw: \u00a7e68.25\u00a7l\u1D52" ); - farmingOverlay = new FarmingOverlay(NotEnoughUpdates.INSTANCE.config.skillOverlays.farmingPosition, () -> { + farmingOverlay = new FarmingSkillOverlay(NotEnoughUpdates.INSTANCE.config.skillOverlays.farmingPosition, () -> { List<String> strings = new ArrayList<>(); for (int i : NotEnoughUpdates.INSTANCE.config.skillOverlays.farmingText) { if (i >= 0 && i < farmingDummy.size()) strings.add(farmingDummy.get(i)); @@ -295,6 +314,7 @@ public class OverlayManager { }); textOverlays.add(miningOverlay); + textOverlays.add(powderGrindingOverlay); textOverlays.add(farmingOverlay); textOverlays.add(miningSkillOverlay); textOverlays.add(combatSkillOverlay); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/PowderGrindingOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/PowderGrindingOverlay.java new file mode 100644 index 00000000..50ecce90 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/PowderGrindingOverlay.java @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.overlays; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.config.Position; +import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils; +import io.github.moulberry.notenoughupdates.options.NEUConfig; +import io.github.moulberry.notenoughupdates.util.SBInfo; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +public class PowderGrindingOverlay extends TextTabOverlay { + + private final static JsonParser PARSER = new JsonParser(); + + + public int chestCount = 0; + public int openedChestCount = 0; + public int mithrilPowderFound = 0; + public float lastMithrilPowderFound = 0; + public float lastMithrilPowderAverage = 0; + public int gemstonePowderFound = 0; + public float lastGemstonePowderFound = 0; + public float lastGemstonePowderAverage = 0; + private long lastUpdate = -1; + + public PowderGrindingOverlay( + Position position, + Supplier<List<String>> dummyStrings, + Supplier<TextOverlayStyle> styleSupplier + ) { + super(position, dummyStrings, styleSupplier); + } + + private float interp(float now, float last) { + float interp = now; + if (last >= 0 && last != now) { + float factor = (System.currentTimeMillis() - lastUpdate) / 1000f; + factor = LerpUtils.clampZeroOne(factor); + interp = last + (now - last) * factor; + } + return interp; + } + + @Override + public void update() { + if (NotEnoughUpdates.INSTANCE.config.mining.powderGrindingTrackerEnabled) { + lastUpdate = System.currentTimeMillis(); + lastMithrilPowderFound = this.mithrilPowderFound; + lastMithrilPowderAverage = this.openedChestCount > 0 ? + 1f * this.mithrilPowderFound / this.openedChestCount : + 0; + lastGemstonePowderFound = this.gemstonePowderFound; + lastGemstonePowderAverage = this.openedChestCount > 0 ? + 1f * this.gemstonePowderFound / this.openedChestCount : + 0; + } else overlayStrings = null; + } + + @Override + public void updateFrequent() { + overlayStrings = null; + if (!NotEnoughUpdates.INSTANCE.config.mining.powderGrindingTrackerEnabled) return; + + String location = SBInfo.getInstance().getLocation(); + if (location == null) return; + if (location.equals("crystal_hollows")) { + + overlayStrings = new ArrayList<>(); + for (int index : NotEnoughUpdates.INSTANCE.config.mining.powderGrindingTrackerText) { + NumberFormat format = NumberFormat.getIntegerInstance(); + switch (index) { + case 0: + overlayStrings.add("\u00a73Chests Found: \u00a7a" + format.format(this.chestCount)); + break; + case 1: + overlayStrings.add("\u00a73Opened Chests: \u00a7a" + format.format(this.openedChestCount)); + break; + case 2: + overlayStrings.add("\u00a73Unopened Chests: \u00a7c" + format.format(this.chestCount - this.openedChestCount)); + break; + case 3: + overlayStrings.add("\u00a73Mithril Powder Found: \u00a72" + + format.format(interp(this.mithrilPowderFound, lastMithrilPowderFound))); + break; + case 4: + overlayStrings.add("\u00a73Average Mithril Powder/Chest: \u00a72" + format.format(interp( + (this.openedChestCount > 0 ? + 1f * this.mithrilPowderFound / this.openedChestCount : + 0), lastMithrilPowderAverage))); + break; + case 5: + overlayStrings.add("\u00a73Gemstone Powder Found: \u00a7d" + + format.format(interp(this.gemstonePowderFound, lastGemstonePowderFound))); + break; + case 6: + overlayStrings.add("\u00a73Average Gemstone Powder/Chest: \u00a7d" + format.format(interp( + (this.openedChestCount > 0 ? + 1f * this.gemstonePowderFound / this.openedChestCount : + 0), lastGemstonePowderAverage))); + break; + } + } + } + + if (overlayStrings != null && overlayStrings.isEmpty()) overlayStrings = null; + } + + public void message(String message) { + if (message.equals("You uncovered a treasure chest!")) { + this.chestCount++; + } else if (message.equals("You have successfully picked the lock on this chest!")) { + this.openedChestCount++; + } else { + boolean mithril = message.endsWith(" Mithril Powder"); + boolean gemstone = message.endsWith(" Gemstone Powder"); + if (!(mithril || gemstone)) return; + try { + int amount = Integer.parseInt(message.split(" ")[2].replaceAll("\\+", "")); + if (mithril) this.mithrilPowderFound += amount; + else this.gemstonePowderFound += amount; + } catch (NumberFormatException | IndexOutOfBoundsException e) { + e.printStackTrace(); + } + } + } + + public void load() { + NEUConfig.HiddenProfileSpecific profileSpecific = NotEnoughUpdates.INSTANCE.config.getProfileSpecific(); + if (profileSpecific == null) return; + this.chestCount = profileSpecific.chestCount; + this.openedChestCount = profileSpecific.openedChestCount; + this.mithrilPowderFound = profileSpecific.mithrilPowderFound; + this.gemstonePowderFound = profileSpecific.gemstonePowderFound; + } + + public void save() { + NEUConfig.HiddenProfileSpecific profileSpecific = NotEnoughUpdates.INSTANCE.config.getProfileSpecific(); + if (profileSpecific == null) return; + profileSpecific.chestCount = this.chestCount; + profileSpecific.openedChestCount = this.openedChestCount; + profileSpecific.mithrilPowderFound = this.mithrilPowderFound; + profileSpecific.gemstonePowderFound = this.gemstonePowderFound; + } + + public void reset() { + this.chestCount = 0; + this.openedChestCount = 0; + this.mithrilPowderFound = 0; + this.gemstonePowderFound = 0; + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TextTabOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TextTabOverlay.java index 69a0cd00..fa263db7 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TextTabOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TextTabOverlay.java @@ -21,6 +21,7 @@ package io.github.moulberry.notenoughupdates.overlays; import io.github.moulberry.notenoughupdates.core.config.Position; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiChat; import org.lwjgl.input.Keyboard; import java.util.List; @@ -36,12 +37,43 @@ public abstract class TextTabOverlay extends TextOverlay { } private boolean lastTabState = false; + private boolean shouldUpdateOverlay = true; - public void realTick() { - boolean currentTabState = Keyboard.isKeyDown(Minecraft.getMinecraft().gameSettings.keyBindPlayerList.getKeyCode()); - if (lastTabState != currentTabState) { - lastTabState = currentTabState; + @Override + public void tick() { + if (shouldUpdateOverlay) { update(); } } + + public void realTick() { + shouldUpdateOverlay = shouldUpdate(); + if (shouldUpdateOverlay) { + int keycode = Minecraft.getMinecraft().gameSettings.keyBindPlayerList.getKeyCode(); + boolean currentTabState; + if (keycode > 0) { + currentTabState = Keyboard.isKeyDown(keycode); + } else { + currentTabState = false; + } + if (lastTabState != currentTabState) { + lastTabState = currentTabState; + update(); + } + } + } + + private boolean shouldUpdate() { + //prevent rendering when tab completing a command + if (Minecraft.getMinecraft().currentScreen instanceof GuiChat) { + return false; + } + + //prevent rendering when tab completing in ah search overlay + if (AuctionSearchOverlay.shouldReplace()) { + return false; + } + + return true; + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java index 86df47ff..730cb17f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java @@ -130,6 +130,7 @@ public class TimersOverlay extends TextTabOverlay { private static final ItemStack COMMISSIONS_ICON = new ItemStack(Items.iron_pickaxe); private static final ItemStack EXPERIMENTS_ICON = new ItemStack(Items.enchanted_book); private static final ItemStack COOKIE_ICON = new ItemStack(Items.cookie); + private static final ItemStack QUEST_ICON = new ItemStack(Items.sign); @Override protected void renderLine(String line, Vector2f position, boolean dummy) { @@ -212,6 +213,9 @@ public class TimersOverlay extends TextTabOverlay { .getItemInformation() .get("HEAVY_PEARL")); break; + case "Crimson Isle Quests": + icon = QUEST_ICON; + break; } if (icon != null) { @@ -388,6 +392,10 @@ public class TimersOverlay extends TextTabOverlay { hidden.godPotionDuration = 0; } + if (SBInfo.getInstance().completedQuests != null && SBInfo.getInstance().completedQuests.size() == 5) { + hidden.questBoardCompleted = currentTime; + } + if (!NotEnoughUpdates.INSTANCE.config.miscOverlays.todoOverlay2) { overlayStrings = null; return; @@ -660,7 +668,7 @@ public class TimersOverlay extends TextTabOverlay { 6, DARK_AQUA + "Experiments: " + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.verySoonColour] + - Utils.prettyTime(catacombsReset) + Utils.prettyTime(catacombsReset + 86400000 - currentTime) ); } else if (NotEnoughUpdates.INSTANCE.config.miscOverlays.experimentationDisplay >= DISPLAYTYPE.SOON.ordinal() && (hidden.experimentsCompleted < (midnightReset - TimeEnums.HOUR.time))) { @@ -668,7 +676,7 @@ public class TimersOverlay extends TextTabOverlay { 6, DARK_AQUA + "Experiments: " + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.soonColour] + - Utils.prettyTime(catacombsReset) + Utils.prettyTime(catacombsReset + 86400000 - currentTime) ); } else if ( NotEnoughUpdates.INSTANCE.config.miscOverlays.experimentationDisplay >= DISPLAYTYPE.KINDASOON.ordinal() && @@ -677,14 +685,14 @@ public class TimersOverlay extends TextTabOverlay { 6, DARK_AQUA + "Experiments: " + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.kindaSoonColour] + - Utils.prettyTime(catacombsReset) + Utils.prettyTime(catacombsReset + 86400000 - currentTime) ); } else if (NotEnoughUpdates.INSTANCE.config.miscOverlays.experimentationDisplay >= DISPLAYTYPE.ALWAYS.ordinal()) { map.put( 6, DARK_AQUA + "Experiments: " + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.defaultColour] + - Utils.prettyTime(catacombsReset) + Utils.prettyTime(catacombsReset + 86400000 - currentTime) ); } @@ -819,6 +827,47 @@ public class TimersOverlay extends TextTabOverlay { ); } + if (hidden.questBoardCompleted < midnightReset) { + map.put( + 10, + DARK_AQUA + "Crimson Isle Quests: " + + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.readyColour] + "Ready!" + ); + } else if ( + NotEnoughUpdates.INSTANCE.config.miscOverlays.questBoardDisplay >= DISPLAYTYPE.VERYSOON.ordinal() && + (hidden.questBoardCompleted < (midnightReset - TimeEnums.HALFANHOUR.time))) { + map.put( + 10, + DARK_AQUA + "Crimson Isle Quests: " + + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.verySoonColour] + + Utils.prettyTime(timeDiffMidnightNow) + ); + } else if (NotEnoughUpdates.INSTANCE.config.miscOverlays.questBoardDisplay >= DISPLAYTYPE.SOON.ordinal() && + (hidden.questBoardCompleted < (midnightReset - TimeEnums.HOUR.time))) { + map.put( + 10, + DARK_AQUA + "Crimson Isle Quests: " + + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.soonColour] + + Utils.prettyTime(timeDiffMidnightNow) + ); + } else if ( + NotEnoughUpdates.INSTANCE.config.miscOverlays.questBoardDisplay >= DISPLAYTYPE.KINDASOON.ordinal() && + (hidden.questBoardCompleted < (midnightReset - (TimeEnums.HOUR.time * 3)))) { + map.put( + 10, + DARK_AQUA + "Crimson Isle Quests: " + + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.kindaSoonColour] + + Utils.prettyTime(timeDiffMidnightNow) + ); + } else if (NotEnoughUpdates.INSTANCE.config.miscOverlays.questBoardDisplay >= DISPLAYTYPE.ALWAYS.ordinal()) { + map.put( + 10, + DARK_AQUA + "Crimson Isle Quests: " + + EnumChatFormatting.values()[NotEnoughUpdates.INSTANCE.config.miscOverlays.defaultColour] + + Utils.prettyTime(timeDiffMidnightNow) + ); + } + overlayStrings = new ArrayList<>(); for (int index : NotEnoughUpdates.INSTANCE.config.miscOverlays.todoText2) { if (map.containsKey(index)) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java index a72e0a24..9ef9e474 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java @@ -49,6 +49,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.ResourceLocation; +import org.apache.commons.lang3.text.WordUtils; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; @@ -65,6 +66,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; +import static io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer.DECIMAL_FORMAT; import static io.github.moulberry.notenoughupdates.util.Utils.roundToNearestInt; public class BasicPage extends GuiProfileViewerPage { @@ -73,6 +75,13 @@ public class BasicPage extends GuiProfileViewerPage { private static final ExecutorService profileLoader = Executors.newFixedThreadPool(1); public EntityOtherPlayerMP entityPlayer = null; private ResourceLocation playerLocationSkin = null; + private final GuiProfileViewer guiProfileViewer; + + private final String[] medalNames = { + "§cBronze", + "§fSilver", + "§6Gold" + }; private ResourceLocation playerLocationCape = null; private String skinType = null; private boolean loadingProfile = false; @@ -81,6 +90,7 @@ public class BasicPage extends GuiProfileViewerPage { public BasicPage(GuiProfileViewer instance) { super(instance); + this.guiProfileViewer = instance; } @Override @@ -153,6 +163,8 @@ public class BasicPage extends GuiProfileViewerPage { Minecraft.getMinecraft().getTextureManager().bindTexture(pv_basic); Utils.drawTexturedRect(guiLeft, guiTop, getInstance().sizeX, getInstance().sizeY, GL11.GL_NEAREST); + JsonObject profileInfo = profile.getProfileInformation(profileId); + if (profileInfo == null) return; if (entityPlayer != null && profile.getHypixelProfile() != null) { String playerName = null; @@ -200,8 +212,11 @@ public class BasicPage extends GuiProfileViewerPage { playerName = EnumChatFormatting.GRAY + name; if (rankName != null) { + String icon = getIcon(getGameModeType(profileInfo)); playerName = - "\u00A7" + rankColor + "[" + rankName + rankPlusColor + rankPlus + "\u00A7" + rankColor + "] " + name; + "\u00A7" + rankColor + "[" + rankName + rankPlusColor + rankPlus + "\u00A7" + rankColor + "] " + name + + (icon.equals("") ? "" : " " + icon); + ; } } } @@ -225,7 +240,31 @@ public class BasicPage extends GuiProfileViewerPage { } } - long networth = profile.getNetWorth(profileId); + long networth; + ArrayList<String> nwCategoryHover = new ArrayList<>(); + if (NotEnoughUpdates.INSTANCE.config.profileViewer.useSoopyNetworth) { + ProfileViewer.Profile.SoopyNetworthData nwData = profile.getSoopyNetworth(profileId, () -> {}); + if (nwData == null) { + networth = -2l; + } else { + networth = nwData.getTotal(); + + for (String category : nwData.getCategories()) { + if (nwData.getCategory(category) == 0) continue; + + nwCategoryHover.add(EnumChatFormatting.GREEN + + WordUtils.capitalizeFully(category.replace("_", " ")) + + ": " + + EnumChatFormatting.GOLD + + GuiProfileViewer.numberFormat.format(nwData.getCategory(category))); + } + + nwCategoryHover.add(""); + } + } else { + networth = profile.getNetWorth(profileId); + } + if (networth > 0) { Utils.drawStringCentered( EnumChatFormatting.GREEN + "Net Worth: " + EnumChatFormatting.GOLD + @@ -245,7 +284,7 @@ public class BasicPage extends GuiProfileViewerPage { .get("avg_buy") .getAsDouble() ); - String networthIRLMoney = Long.toString(Math.round(((networthInCookies * 325) / 675) * 4.99)); + String networthIRLMoney = GuiProfileViewer.numberFormat.format(Math.round(((networthInCookies * 325) / 675) * 4.99)); if ( mouseX > guiLeft + 8 && mouseX < guiLeft + 8 + fr.getStringWidth("Net Worth: " + GuiProfileViewer.numberFormat.format(networth)) @@ -262,7 +301,9 @@ public class BasicPage extends GuiProfileViewerPage { networthIRLMoney ); getInstance().tooltipToDisplay.add(""); + if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) { + getInstance().tooltipToDisplay.addAll(nwCategoryHover); getInstance().tooltipToDisplay.add(EnumChatFormatting.RED + "This is calculated using the current"); getInstance().tooltipToDisplay.add( EnumChatFormatting.RED + "price of booster cookies on bazaar and the price"); @@ -271,7 +312,7 @@ public class BasicPage extends GuiProfileViewerPage { getInstance().tooltipToDisplay.add( EnumChatFormatting.RED + "is where we get the amount of IRL money you"); getInstance().tooltipToDisplay.add( - EnumChatFormatting.RED + "theoretically have on skyblock in net worth."); + EnumChatFormatting.RED + "theoretically have on SkyBlock in net worth."); } else { getInstance().tooltipToDisplay.add(EnumChatFormatting.GRAY + "[SHIFT for Info]"); } @@ -282,7 +323,26 @@ public class BasicPage extends GuiProfileViewerPage { } } } catch (Exception ignored) { + ignored.printStackTrace(); + } + } else { + //Networth is under 0 + //If = -1 -> an error occured + //If = -2 -> still loading networth + + String stateStr = EnumChatFormatting.RED + "An error occured"; + if (networth == -2) { + stateStr = EnumChatFormatting.YELLOW + "Loading..."; } + + Utils.drawStringCentered( + EnumChatFormatting.GREEN + "Net Worth: " + stateStr, + fr, + guiLeft + 63, + guiTop + 38, + true, + 0 + ); } if (status != null) { @@ -358,9 +418,6 @@ public class BasicPage extends GuiProfileViewerPage { entityPlayer.getDataWatcher().updateObject(10, b); } - JsonObject profileInfo = profile.getProfileInformation(profileId); - if (profileInfo == null) return; - Map<String, ProfileViewer.Level> skyblockInfo = profile.getSkyblockInfo(profileId); JsonObject inventoryInfo = profile.getInventoryInfo(profileId); @@ -590,42 +647,85 @@ public class BasicPage extends GuiProfileViewerPage { String skillName = entry.getValue().getDisplayName(); - float level = skyblockInfo.get(entry.getKey()).level; - int levelFloored = (int) Math.floor(level); + ProfileViewer.Level level = skyblockInfo.get(entry.getKey()); + int levelFloored = (int) Math.floor(level.level); int x = guiLeft + 237 + 86 * xPosition; int y = guiTop + 24 + 21 * yPosition; Utils.renderAlignedString(skillName, EnumChatFormatting.WHITE.toString() + levelFloored, x + 14, y - 4, 60); - if (skyblockInfo.get(entry.getKey()).maxed) { + if (level.maxed) { getInstance().renderGoldBar(x, y + 6, 80); } else { - getInstance().renderBar(x, y + 6, 80, level % 1); + getInstance().renderBar(x, y + 6, 80, level.level % 1); } if (mouseX > x && mouseX < x + 80) { if (mouseY > y - 4 && mouseY < y + 13) { getInstance().tooltipToDisplay = new ArrayList<>(); - getInstance().tooltipToDisplay.add(skillName); - if (skyblockInfo.get(entry.getKey()).maxed) { - getInstance().tooltipToDisplay.add( + List<String> tooltipToDisplay = getInstance().tooltipToDisplay; + tooltipToDisplay.add(skillName); + if (level.maxed) { + tooltipToDisplay.add( EnumChatFormatting.GRAY + "Progress: " + EnumChatFormatting.GOLD + "MAXED!"); } else { - int maxXp = (int) skyblockInfo.get(entry.getKey()).maxXpForLevel; + int maxXp = (int) level.maxXpForLevel; getInstance() .tooltipToDisplay.add( EnumChatFormatting.GRAY + "Progress: " + EnumChatFormatting.DARK_PURPLE + - StringUtils.shortNumberFormat(Math.round((level % 1) * maxXp)) + + StringUtils.shortNumberFormat(Math.round((level.level % 1) * maxXp)) + "/" + - StringUtils.shortNumberFormat(maxXp) + StringUtils.shortNumberFormat(maxXp)); + } + String totalXpS = GuiProfileViewer.numberFormat.format((int) level.totalXp); + tooltipToDisplay.add(EnumChatFormatting.GRAY + "Total XP: " + EnumChatFormatting.DARK_PURPLE + totalXpS + + EnumChatFormatting.DARK_GRAY + " (" + + DECIMAL_FORMAT.format(guiProfileViewer.getPercentage(entry.getKey().toLowerCase(), level)) + + "% to " + level.maxLevel + ")"); + if (entry.getKey().equals("farming")) { + // double drops + pelts + int doubleDrops = Utils.getElementAsInt(Utils.getElement(profileInfo, "jacob2.perks.double_drops"), 0); + int peltCount = Utils.getElementAsInt(Utils.getElement(profileInfo, "trapper_quest.pelt_count"), 0); + + if (doubleDrops == 15) { + tooltipToDisplay.add("§7Double Drops: §6" + (doubleDrops * 2) + "%"); + } else tooltipToDisplay.add("§7Double Drops: §5" + (doubleDrops * 2) + "%"); + + tooltipToDisplay.add("§7Pelts: §e" + peltCount); + + // medals + JsonObject medals_inv = Utils.getElement(profileInfo, "jacob2.medals_inv").getAsJsonObject(); + tooltipToDisplay.add(" "); + for (String medalName : medalNames) { + String textWithoutFormattingCodes = + EnumChatFormatting.getTextWithoutFormattingCodes(medalName.toLowerCase()); + if (medals_inv.has(textWithoutFormattingCodes)) { + int medalAmount = medals_inv.get(textWithoutFormattingCodes).getAsInt(); + tooltipToDisplay.add(EnumChatFormatting.GRAY + WordUtils.capitalize(medalName) + ": " + + EnumChatFormatting.WHITE + medalAmount); + } else { + tooltipToDisplay.add(EnumChatFormatting.GRAY + WordUtils.capitalize(medalName) + ": " + + EnumChatFormatting.WHITE + "0"); + } + } + } + + String slayerNameLower = entry.getKey().toLowerCase(); + if (ExtraPage.slayers.containsKey(slayerNameLower)) { + int maxLevel = ExtraPage.slayers.get(slayerNameLower); + for (int i = 0; i < 5; i++) { + if (i >= maxLevel) break; + float tier = Utils.getElementAsFloat( + Utils.getElement(profileInfo, "slayer_bosses." + slayerNameLower + ".boss_kills_tier_" + i), + 0 ); + tooltipToDisplay.add(EnumChatFormatting.GRAY + "T" + (i + 1) + " Kills: " + + EnumChatFormatting.RED + (int) tier); + } } - String totalXpS = GuiProfileViewer.numberFormat.format((int) skyblockInfo.get(entry.getKey()).totalXp); - getInstance() - .tooltipToDisplay.add(EnumChatFormatting.GRAY + "Total XP: " + EnumChatFormatting.DARK_PURPLE + totalXpS); } } @@ -651,6 +751,19 @@ public class BasicPage extends GuiProfileViewerPage { renderWeight(mouseX, mouseY, skyblockInfo, profileInfo); } + private String getIcon(String gameModeType) { + switch (gameModeType) { + case "island": + return "§a☀"; + case "bingo": + return "§7Ⓑ"; + case "ironman": + return "§7♲"; + default: + return ""; + } + } + @Override public void resetCache() { entityPlayer = null; @@ -802,6 +915,9 @@ public class BasicPage extends GuiProfileViewerPage { } private void drawEntityOnScreen(int posX, int posY, int scale, float mouseX, float mouseY, EntityLivingBase ent) { + + ent.onUpdate(); + GlStateManager.enableColorMaterial(); GlStateManager.pushMatrix(); GlStateManager.translate((float) posX, (float) posY, 50.0F); @@ -838,4 +954,11 @@ public class BasicPage extends GuiProfileViewerPage { GlStateManager.disableTexture2D(); GlStateManager.setActiveTexture(OpenGlHelper.defaultTexUnit); } + + public String getGameModeType(JsonObject profileInfo) { + if (profileInfo != null && profileInfo.has("game_mode")) { + return profileInfo.get("game_mode").getAsString(); + } + return ""; + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BingoPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BingoPage.java index 27b9b363..ab80afab 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BingoPage.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BingoPage.java @@ -24,9 +24,6 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.util.Utils; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.GlStateManager; @@ -39,6 +36,9 @@ import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.ResourceLocation; import org.lwjgl.opengl.GL11; +import java.util.ArrayList; +import java.util.List; + public class BingoPage extends GuiProfileViewerPage { private static final ResourceLocation BINGO_GUI_TEXTURE = new ResourceLocation("notenoughupdates:pv_bingo_tab.png"); @@ -153,16 +153,23 @@ public class BingoPage extends GuiProfileViewerPage { } else { personalGoalsString = EnumChatFormatting.AQUA + - "Personal Goals: " + - EnumChatFormatting.WHITE + - completedGoals.size() + - EnumChatFormatting.GOLD + - "/" + - EnumChatFormatting.WHITE + - 20; + "Personal Goals: " + + EnumChatFormatting.WHITE + + completedGoals.size() + + EnumChatFormatting.GOLD + + "/" + + EnumChatFormatting.WHITE + + 20; } Utils.drawStringF(totalPointsString, Minecraft.getMinecraft().fontRendererObj, guiLeft + 22, guiTop + 19, true, 0); - Utils.drawStringF(personalGoalsString, Minecraft.getMinecraft().fontRendererObj, guiLeft + 22, guiTop + 31, true, 0); + Utils.drawStringF( + personalGoalsString, + Minecraft.getMinecraft().fontRendererObj, + guiLeft + 22, + guiTop + 31, + true, + 0 + ); GlStateManager.enableLighting(); } @@ -218,7 +225,9 @@ public class BingoPage extends GuiProfileViewerPage { } finalTier++; } - double nextTier = finalTier < totalTiers ? tiers.get(totalTiers - 1).getAsLong() : tiers.get(finalTier - 1).getAsLong(); + double nextTier = finalTier < totalTiers ? tiers.get(totalTiers - 1).getAsLong() : tiers + .get(finalTier - 1) + .getAsLong(); int progressToNextTier = (int) Math.round(progress / nextTier * 100); if (progressToNextTier > 100) progressToNextTier = 100; String progressBar = generateProgressIndicator(progress, nextTier); @@ -232,34 +241,37 @@ public class BingoPage extends GuiProfileViewerPage { tooltip.add(""); tooltip.add( EnumChatFormatting.GRAY + - "Progress to " + - name + - " " + - nextTierNum + - ": " + - EnumChatFormatting.YELLOW + - progressToNextTier + - EnumChatFormatting.GOLD + - "%" + "Progress to " + + name + + " " + + nextTierNum + + ": " + + EnumChatFormatting.YELLOW + + progressToNextTier + + EnumChatFormatting.GOLD + + "%" ); tooltip.add( progressBar + - EnumChatFormatting.YELLOW + - " " + - progressString + - EnumChatFormatting.GOLD + - "/" + - EnumChatFormatting.YELLOW + - nextTierString + EnumChatFormatting.YELLOW + + " " + + progressString + + EnumChatFormatting.GOLD + + "/" + + EnumChatFormatting.YELLOW + + nextTierString ); tooltip.add(""); tooltip.add(EnumChatFormatting.DARK_GRAY.toString() + EnumChatFormatting.ITALIC + "Community Goals are"); - tooltip.add(EnumChatFormatting.DARK_GRAY.toString() + EnumChatFormatting.ITALIC + "collaborative - anyone with a"); - tooltip.add(EnumChatFormatting.DARK_GRAY.toString() + EnumChatFormatting.ITALIC + "Bingo profile can help to reach"); + tooltip.add( + EnumChatFormatting.DARK_GRAY.toString() + EnumChatFormatting.ITALIC + "collaborative - anyone with a"); + tooltip.add( + EnumChatFormatting.DARK_GRAY.toString() + EnumChatFormatting.ITALIC + "Bingo profile can help to reach"); tooltip.add(EnumChatFormatting.DARK_GRAY.toString() + EnumChatFormatting.ITALIC + "the goal!"); tooltip.add(""); tooltip.add(EnumChatFormatting.DARK_GRAY.toString() + EnumChatFormatting.ITALIC + "The more you contribute"); - tooltip.add(EnumChatFormatting.DARK_GRAY.toString() + EnumChatFormatting.ITALIC + "towards the goal, the more you"); + tooltip.add( + EnumChatFormatting.DARK_GRAY.toString() + EnumChatFormatting.ITALIC + "towards the goal, the more you"); tooltip.add(EnumChatFormatting.DARK_GRAY.toString() + EnumChatFormatting.ITALIC + "will be rewarded"); if (finalTier == totalTiers) { @@ -287,7 +299,14 @@ public class BingoPage extends GuiProfileViewerPage { private void showMissingDataMessage(int guiLeft, int guiTop) { String message = EnumChatFormatting.RED + "No Bingo data for current event!"; - Utils.drawStringCentered(message, Minecraft.getMinecraft().fontRendererObj, guiLeft + 431 / 2f, guiTop + 101, true, 0); + Utils.drawStringCentered( + message, + Minecraft.getMinecraft().fontRendererObj, + guiLeft + 431 / 2f, + guiTop + 101, + true, + 0 + ); } private List<String> jsonArrayToStringList(JsonArray completedGoals) { @@ -314,18 +333,14 @@ public class BingoPage extends GuiProfileViewerPage { if (currentTime - lastResourceRequest < 120 * 1000 && bingoGoals != null) return; lastResourceRequest = currentTime; - HashMap<String, String> args = new HashMap<>(); - NotEnoughUpdates.INSTANCE.manager.hypixelApi.getHypixelApiAsync( - NotEnoughUpdates.INSTANCE.config.apiData.apiKey, - "resources/skyblock/bingo", - args, - jsonObject -> { + NotEnoughUpdates.INSTANCE.manager.apiUtils + .newAnonymousHypixelApiRequest("resources/skyblock/bingo") + .requestJson() + .thenAccept(jsonObject -> { if (jsonObject.has("success") && jsonObject.get("success").getAsBoolean()) { bingoGoals = jsonArrayToJsonObjectList(jsonObject.get("goals").getAsJsonArray()); currentEventId = jsonObject.get("id").getAsInt(); } - }, - () -> {} - ); + }); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java index c707f7fc..6d59db27 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java @@ -124,7 +124,6 @@ public class DungeonPage extends GuiProfileViewerPage { ProfileViewer.Profile profile = GuiProfileViewer.getProfile(); String profileId = GuiProfileViewer.getProfileId(); JsonObject hypixelInfo = profile.getHypixelProfile(); - if (hypixelInfo == null) return; JsonObject profileInfo = profile.getProfileInformation(profileId); if (profileInfo == null) return; @@ -196,9 +195,9 @@ public class DungeonPage extends GuiProfileViewerPage { if (F7 > 50) { F7 = 50; } - float xpF5 = 2000 * (F5 / 100 + 1); - float xpF6 = 4000 * (F6 / 100 + 1); - float xpF7 = 20000 * (F7 / 100 + 1); + float xpF5 = 2400 * (F5 / 100 + 1); + float xpF6 = 4880 * (F6 / 100 + 1); + float xpF7 = 28000 * (F7 / 100 + 1); if (!Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) { xpF5 *= 1.1; xpF6 *= 1.1; @@ -306,6 +305,13 @@ public class DungeonPage extends GuiProfileViewerPage { 0 ) ); + float M7 = + ( + Utils.getElementAsFloat( + Utils.getElement(profileInfo, "dungeons.dungeon_types.master_catacombs.tier_completions." + 7), + 0 + ) + ); if (M3 > 50) { M3 = 50; } @@ -318,22 +324,28 @@ public class DungeonPage extends GuiProfileViewerPage { if (M6 > 50) { M6 = 50; } - float xpM3 = 36500 * (M3 / 100 + 1); - float xpM4 = 48500 * (M4 / 100 + 1); + if (M7 > 50) { + M7 = 50; + } + float xpM3 = 35000 * (M3 / 100 + 1); + float xpM4 = 55000 * (M4 / 100 + 1); float xpM5 = 70000 * (M5 / 100 + 1); float xpM6 = 100000 * (M6 / 100 + 1); + float xpM7 = 300000 * (M7 / 100 + 1); //No clue if M3 or M4 xp values are right if (!Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) { xpM3 *= 1.1; xpM4 *= 1.1; xpM5 *= 1.1; xpM6 *= 1.1; + xpM7 *= 1.1; } long runsM3 = (int) Math.ceil(floorLevelToXP / xpM3); long runsM4 = (int) Math.ceil(floorLevelToXP / xpM4); long runsM5 = (int) Math.ceil(floorLevelToXP / xpM5); long runsM6 = (int) Math.ceil(floorLevelToXP / xpM6); + long runsM7 = (int) Math.ceil(floorLevelToXP / xpM7); float timeM3 = Utils.getElementAsFloat( Utils.getElement(profileInfo, "dungeons.dungeon_types.master_catacombs.fastest_time_s_plus.3"), @@ -351,6 +363,10 @@ public class DungeonPage extends GuiProfileViewerPage { Utils.getElement(profileInfo, "dungeons.dungeon_types.master_catacombs.fastest_time_s_plus.6"), 0 ); + float timeM7 = Utils.getElementAsFloat( + Utils.getElement(profileInfo, "dungeons.dungeon_types.master_catacombs.fastest_time_s_plus.7"), + 0 + ); getInstance().tooltipToDisplay = Lists.newArrayList( @@ -358,6 +374,7 @@ public class DungeonPage extends GuiProfileViewerPage { String.format("# M4 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpM4), runsM4), String.format("# M5 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpM5), runsM5), String.format("# M6 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpM6), runsM6), + String.format("# M7 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpM7), runsM7), "" ); boolean hasTime = false; @@ -381,6 +398,11 @@ public class DungeonPage extends GuiProfileViewerPage { .tooltipToDisplay.add(String.format("Expected Time (M6) : %s", Utils.prettyTime(runsM6 * (long) (timeM6 * 1.2)))); hasTime = true; } + if (timeM7 > 1000) { + getInstance() + .tooltipToDisplay.add(String.format("Expected Time (M7) : %s", Utils.prettyTime(runsM7 * (long) (timeM7 * 1.2)))); + hasTime = true; + } if (hasTime) { getInstance().tooltipToDisplay.add(""); } @@ -420,7 +442,10 @@ public class DungeonPage extends GuiProfileViewerPage { //Random stats - float secrets = Utils.getElementAsFloat(Utils.getElement(hypixelInfo, "achievements.skyblock_treasure_hunter"), 0); + float secrets = -1; + if (hypixelInfo != null) { + secrets = Utils.getElementAsFloat(Utils.getElement(hypixelInfo, "achievements.skyblock_treasure_hunter"), 0); + } float totalRunsF = 0; float totalRunsF5 = 0; for (int i = 1; i <= 7; i++) { @@ -484,14 +509,14 @@ public class DungeonPage extends GuiProfileViewerPage { ); Utils.renderAlignedString( EnumChatFormatting.YELLOW + "Secrets (Total) ", - EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(secrets), + EnumChatFormatting.WHITE + (secrets == -1 ? "?" : StringUtils.shortNumberFormat(secrets)), x, miscTopY + 20, sectionWidth ); Utils.renderAlignedString( EnumChatFormatting.YELLOW + "Secrets (/Run) ", - EnumChatFormatting.WHITE.toString() + (Math.round(secrets / Math.max(1, totalRuns) * 100) / 100f), + EnumChatFormatting.WHITE.toString() + (secrets == -1 ? "?" : (Math.round(secrets / Math.max(1, totalRuns) * 100) / 100f)), x, miscTopY + 30, sectionWidth diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java index 63a4df2c..a0af254c 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java @@ -19,9 +19,11 @@ package io.github.moulberry.notenoughupdates.profileviewer; +import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.util.StringUtils; import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.Utils; @@ -29,15 +31,19 @@ import net.minecraft.client.Minecraft; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.ResourceLocation; import org.apache.commons.lang3.text.WordUtils; +import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; +import java.io.IOException; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.TimeZone; @@ -48,9 +54,95 @@ public class ExtraPage extends GuiProfileViewerPage { private static final ResourceLocation pv_extra = new ResourceLocation("notenoughupdates:pv_extra.png"); private TreeMap<Integer, Set<String>> topKills = null; private TreeMap<Integer, Set<String>> topDeaths = null; + private int deathScroll = 0; + private int killScroll = 0; + private int mouseDWheel = 0; + public ExtraPage(GuiProfileViewer instance) { super(instance); + getInstance().killDeathSearchTextField.setSize(80, 12); + } + + @Override + public void keyTyped(char typedChar, int keyCode) throws IOException { + super.keyTyped(typedChar, keyCode); + if (getInstance().killDeathSearchTextField.getFocus()) { + getInstance().killDeathSearchTextField.keyTyped(typedChar, keyCode); + killScroll = 0; + deathScroll = 0; + } + } + + @Override + public boolean mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { + super.mouseClicked(mouseX, mouseY, mouseButton); + //Note: don't know why it made me make it return a boolean, but it fixed the error, so I left it alone. + + //Dimensions: X: guiLeft + xStart + xOffset * 3, Y: guiTop + yStartBottom + 77, Width: 80, Height: 12 + if (mouseX >= GuiProfileViewer.getGuiLeft() + 22 + 103 * 3 && + mouseX <= GuiProfileViewer.getGuiLeft() + 22 + 103 * 3 + 80 && + mouseY >= GuiProfileViewer.getGuiTop() + 105 + 77 && mouseY <= GuiProfileViewer.getGuiTop() + 105 + 77 + 12) { + getInstance().killDeathSearchTextField.mouseClicked(mouseX, mouseY, mouseButton); + getInstance().playerNameTextField.otherComponentClick(); + return true; + } + + getInstance().killDeathSearchTextField.otherComponentClick(); + + return false; + } + + // pls update in the future tyvm !!! + final static HashMap<String, Integer> slayers = new HashMap<String, Integer>() { + { + put("zombie", 5); + put("spider", 4); + put("wolf", 4); + put("enderman", 4); + put("blaze", 4); + } + }; + + public void drawEssence( + JsonObject profileInfo, + float xStart, + float yStartTop, + float xOffset, + float yOffset) { + int guiLeft = GuiProfileViewer.getGuiLeft(); + int guiTop = GuiProfileViewer.getGuiTop(); + yStartTop = yStartTop + 78; + if (Constants.PARENTS == null || !Constants.PARENTS.has("ESSENCE_WITHER")) { + Utils.showOutdatedRepoNotification(); + return; + } + JsonObject parents = Constants.PARENTS; + JsonArray essenceArray = parents.get("ESSENCE_WITHER").getAsJsonArray(); + + for (int i = 0; i < essenceArray.size(); i++) { + + JsonElement jsonElement = essenceArray.get(i); + String essenceName = jsonElement.getAsString(); + + TreeMap<String, JsonObject> itemInformation = NotEnoughUpdates.INSTANCE.manager.getItemInformation(); + if (!itemInformation.containsKey(essenceName)) { + Utils.showOutdatedRepoNotification(); + return; + } + String displayName = itemInformation.get(essenceName).getAsJsonObject().get("displayname").getAsString(); + if (profileInfo.has(essenceName.toLowerCase())) { + int essenceNumber = profileInfo.get(essenceName.toLowerCase()).getAsInt(); + + Utils.renderAlignedString( + EnumChatFormatting.GOLD + displayName, + EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(essenceNumber, 0), + guiLeft + xStart + xOffset, + guiTop + yStartTop + yOffset * i, + 76 + ); + } + } } @Override @@ -92,25 +184,13 @@ public class ExtraPage extends GuiProfileViewerPage { ); { - String lastSaveText = getTimeSinceString(profileInfo, "last_save"); - if (lastSaveText != null) { - Utils.renderAlignedString( - EnumChatFormatting.AQUA + "Last Seen", - EnumChatFormatting.WHITE + lastSaveText, - guiLeft + xStart, - guiTop + yStartTop + yOffset * 2, - 76 - ); - } - } - { String first_join = getTimeSinceString(profileInfo, "first_join"); if (first_join != null) { Utils.renderAlignedString( EnumChatFormatting.AQUA + "Joined", EnumChatFormatting.WHITE + first_join, guiLeft + xStart, - guiTop + yStartTop + yOffset * 3, + guiTop + yStartTop + yOffset * 2, 76 ); } @@ -123,7 +203,7 @@ public class ExtraPage extends GuiProfileViewerPage { EnumChatFormatting.AQUA + "Guild", EnumChatFormatting.WHITE + guildInfo.get("name").getAsString(), guiLeft + xStart, - guiTop + yStartTop + yOffset * 4, + guiTop + yStartTop + yOffset * 3, 76 ); } @@ -133,7 +213,7 @@ public class ExtraPage extends GuiProfileViewerPage { EnumChatFormatting.GREEN + "Pronouns", EnumChatFormatting.WHITE + String.join(" / ", choice.render()), guiLeft + xStart, - guiTop + yStartTop + yOffset * (shouldRenderGuild ? 5 : 4), + guiTop + yStartTop + yOffset * (shouldRenderGuild ? 4 : 3), 76 )); } @@ -171,14 +251,13 @@ public class ExtraPage extends GuiProfileViewerPage { "alchemy", "carpentry" ); - List<String> slayers = Arrays.asList("zombie", "spider", "wolf", "enderman", "blaze"); for (Map.Entry<String, ProfileViewer.Level> entry : skyblockInfo.entrySet()) { if (skills.contains(entry.getKey())) { totalSkillLVL += entry.getValue().level; totalTrueSkillLVL += Math.floor(entry.getValue().level); totalSkillCount++; - } else if (slayers.contains(entry.getKey())) { + } else if (slayers.containsKey(entry.getKey())) { totalSlayerLVL += entry.getValue().level; totalSlayerCount++; totalSlayerXP += entry.getValue().totalXp; @@ -278,131 +357,6 @@ public class ExtraPage extends GuiProfileViewerPage { 76 ); - //Slayer values - float zombie_boss_kills_tier_2 = Utils.getElementAsFloat( - Utils.getElement(profileInfo, "slayer_bosses.zombie.boss_kills_tier_2"), - 0 - ); - float zombie_boss_kills_tier_3 = Utils.getElementAsFloat( - Utils.getElement(profileInfo, "slayer_bosses.zombie.boss_kills_tier_3"), - 0 - ); - float zombie_boss_kills_tier_4 = Utils.getElementAsFloat( - Utils.getElement(profileInfo, "slayer_bosses.zombie.boss_kills_tier_4"), - 0 - ); - float wolf_boss_kills_tier_2 = Utils.getElementAsFloat(Utils.getElement( - profileInfo, - "slayer_bosses.wolf.boss_kills_tier_2" - ), 0); - float wolf_boss_kills_tier_3 = Utils.getElementAsFloat(Utils.getElement( - profileInfo, - "slayer_bosses.wolf.boss_kills_tier_3" - ), 0); - float spider_boss_kills_tier_2 = Utils.getElementAsFloat( - Utils.getElement(profileInfo, "slayer_bosses.spider.boss_kills_tier_2"), - 0 - ); - float spider_boss_kills_tier_3 = Utils.getElementAsFloat( - Utils.getElement(profileInfo, "slayer_bosses.spider.boss_kills_tier_3"), - 0 - ); - float enderman_boss_kills_tier_2 = Utils.getElementAsFloat( - Utils.getElement(profileInfo, "slayer_bosses.enderman.boss_kills_tier_2"), - 0 - ); - float enderman_boss_kills_tier_3 = Utils.getElementAsFloat( - Utils.getElement(profileInfo, "slayer_bosses.enderman.boss_kills_tier_3"), - 0 - ); - float blaze_boss_kills_tier_2 = Utils.getElementAsFloat(Utils.getElement( - profileInfo, - "slayer_bosses.blaze.boss_kills_tier_2" - ), 0); - float blaze_boss_kills_tier_3 = Utils.getElementAsFloat(Utils.getElement( - profileInfo, - "slayer_bosses.blaze.boss_kills_tier_3" - ), 0); - - Utils.renderAlignedString( - EnumChatFormatting.DARK_AQUA + "Revenant T3", - EnumChatFormatting.WHITE.toString() + (int) zombie_boss_kills_tier_2, - guiLeft + xStart + xOffset, - guiTop + yStartBottom, - 76 - ); - Utils.renderAlignedString( - EnumChatFormatting.DARK_AQUA + "Revenant T4", - EnumChatFormatting.WHITE.toString() + (int) zombie_boss_kills_tier_3, - guiLeft + xStart + xOffset, - guiTop + yStartBottom + yOffset, - 76 - ); - Utils.renderAlignedString( - EnumChatFormatting.DARK_AQUA + "Revenant T5", - EnumChatFormatting.WHITE.toString() + (int) zombie_boss_kills_tier_4, - guiLeft + xStart + xOffset, - guiTop + yStartBottom + yOffset * 2, - 76 - ); - Utils.renderAlignedString( - EnumChatFormatting.DARK_AQUA + "Tarantula T3", - EnumChatFormatting.WHITE.toString() + (int) spider_boss_kills_tier_2, - guiLeft + xStart + xOffset, - guiTop + yStartBottom + yOffset * 3, - 76 - ); - Utils.renderAlignedString( - EnumChatFormatting.DARK_AQUA + "Tarantula T4", - EnumChatFormatting.WHITE.toString() + (int) spider_boss_kills_tier_3, - guiLeft + xStart + xOffset, - guiTop + yStartBottom + yOffset * 4, - 76 - ); - - Utils.renderAlignedString( - EnumChatFormatting.DARK_AQUA + "Sven T3", - EnumChatFormatting.WHITE.toString() + (int) wolf_boss_kills_tier_2, - guiLeft + xStart + xOffset * 2, - guiTop + yStartBottom + yOffset * 0, - 76 - ); - Utils.renderAlignedString( - EnumChatFormatting.DARK_AQUA + "Sven T4", - EnumChatFormatting.WHITE.toString() + (int) wolf_boss_kills_tier_3, - guiLeft + xStart + xOffset * 2, - guiTop + yStartBottom + yOffset * 1, - 76 - ); - Utils.renderAlignedString( - EnumChatFormatting.DARK_AQUA + "Voidgloom T3", - EnumChatFormatting.WHITE.toString() + (int) enderman_boss_kills_tier_2, - guiLeft + xStart + xOffset * 2, - guiTop + yStartBottom + yOffset * 2, - 76 - ); - Utils.renderAlignedString( - EnumChatFormatting.DARK_AQUA + "Voidgloom T4", - EnumChatFormatting.WHITE.toString() + (int) enderman_boss_kills_tier_3, - guiLeft + xStart + xOffset * 2, - guiTop + yStartBottom + yOffset * 3, - 76 - ); - Utils.renderAlignedString( - EnumChatFormatting.DARK_AQUA + "Inferno T3", - EnumChatFormatting.WHITE.toString() + (int) blaze_boss_kills_tier_2, - guiLeft + xStart + xOffset * 2, - guiTop + yStartBottom + yOffset * 4, - 76 - ); - Utils.renderAlignedString( - EnumChatFormatting.DARK_AQUA + "Inferno T4", - EnumChatFormatting.WHITE.toString() + (int) blaze_boss_kills_tier_3, - guiLeft + xStart + xOffset * 2, - guiTop + yStartBottom + yOffset * 5, - 76 - ); - float pet_milestone_ores_mined = Utils.getElementAsFloat(Utils.getElement( profileInfo, "stats.pet_milestone_ores_mined" @@ -459,6 +413,8 @@ public class ExtraPage extends GuiProfileViewerPage { 76 ); + drawEssence(profileInfo, xStart, yStartTop, xOffset, yOffset); + if (topKills == null) { topKills = new TreeMap<>(); JsonObject stats = profileInfo.get("stats").getAsJsonObject(); @@ -492,35 +448,59 @@ public class ExtraPage extends GuiProfileViewerPage { } } + getInstance().killDeathSearchTextField.render((int) (guiLeft + xStart + xOffset * 3), (int) (guiTop + yStartBottom + 77)); + + float killDeathX = guiLeft + xStart + xOffset * 3; + if(mouseX >= killDeathX && mouseX <= killDeathX+76) { + if(mouseY >= guiTop + yStartTop && mouseY <= guiTop + yStartTop + 65) { + if(mouseDWheel != 0) {if(mouseDWheel > 0) {killScroll-=1;} else {killScroll+=1;}} mouseDWheel = Mouse.getDWheel(); + if(killScroll < 0) {killScroll = 0;} + } else if(mouseY >= guiTop + yStartBottom && mouseY <= guiTop + yStartBottom + 65) { + if(mouseDWheel != 0) {if(mouseDWheel > 0) {deathScroll-=1;} else {deathScroll+=1;}} mouseDWheel = Mouse.getDWheel(); + if(deathScroll < 0) {deathScroll = 0;} + } + + } + int index = 0; + int skipCount = 0; for (int killCount : topKills.descendingKeySet()) { - if (index >= 6) break; Set<String> kills = topKills.get(killCount); for (String killType : kills) { - if (index >= 6) break; - Utils.renderAlignedString( - EnumChatFormatting.YELLOW + killType + " Kills", - EnumChatFormatting.WHITE.toString() + killCount, - guiLeft + xStart + xOffset * 3, - guiTop + yStartTop + yOffset * index, - 76 - ); + boolean isSearch = getInstance().killDeathSearchTextField.getText().isEmpty() || killType.toLowerCase(Locale.ROOT).contains(getInstance().killDeathSearchTextField.getText().toLowerCase(Locale.ROOT)); + float killY = guiTop + yStartTop + yOffset * ((index-skipCount) - killScroll); + if(!isSearch) skipCount++; + if(isSearch && killY+6 < guiTop+yStartTop+65 && killY >= guiTop + yStartTop) { + Utils.renderAlignedString( + EnumChatFormatting.YELLOW + killType + " Kills", + EnumChatFormatting.WHITE.toString() + killCount, + killDeathX, + killY, + 76 + ); + } + + index++; } } index = 0; + skipCount = 0; for (int deathCount : topDeaths.descendingKeySet()) { - if (index >= 6) break; Set<String> deaths = topDeaths.get(deathCount); for (String deathType : deaths) { - if (index >= 6) break; - Utils.renderAlignedString( - EnumChatFormatting.YELLOW + "Deaths: " + deathType, - EnumChatFormatting.WHITE.toString() + deathCount, - guiLeft + xStart + xOffset * 3, - guiTop + yStartBottom + yOffset * index, - 76 - ); + boolean isSearch = getInstance().killDeathSearchTextField.getText().isEmpty() || deathType.toLowerCase(Locale.ROOT).contains(getInstance().killDeathSearchTextField.getText().toLowerCase(Locale.ROOT)); + float deathY = guiTop + yStartBottom + yOffset * ((index-skipCount) - deathScroll); + if(!isSearch) skipCount++; + if(isSearch && deathY+6 < guiTop+yStartBottom+65 && deathY >= guiTop + yStartBottom) { + Utils.renderAlignedString( + EnumChatFormatting.YELLOW + "Deaths: " + deathType, + EnumChatFormatting.WHITE.toString() + deathCount, + killDeathX, + deathY, + 76 + ); + } index++; } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java index 0f9d1b4a..f327dae5 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java @@ -29,6 +29,8 @@ import io.github.moulberry.notenoughupdates.itemeditor.GuiElementTextField; import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay; import io.github.moulberry.notenoughupdates.profileviewer.bestiary.BestiaryPage; import io.github.moulberry.notenoughupdates.profileviewer.trophy.TrophyFishPage; +import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.DungeonsWeight; +import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.SkillsWeight; import io.github.moulberry.notenoughupdates.util.AsyncDependencyLoader; import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.PronounDB; @@ -55,12 +57,13 @@ import org.lwjgl.opengl.GL14; import org.lwjgl.opengl.GL20; import java.awt.*; -import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -76,6 +79,8 @@ public class GuiProfileViewer extends GuiScreen { public static final ResourceLocation pv_elements = new ResourceLocation("notenoughupdates:pv_elements.png"); public static final ResourceLocation pv_ironman = new ResourceLocation("notenoughupdates:pv_ironman.png"); public static final ResourceLocation pv_bingo = new ResourceLocation("notenoughupdates:pv_bingo.png"); + + public final static DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.#"); public static final ResourceLocation pv_stranded = new ResourceLocation("notenoughupdates:pv_stranded.png"); public static final ResourceLocation pv_unknown = new ResourceLocation("notenoughupdates:pv_unknown.png"); public static final ResourceLocation resource_packs = @@ -165,10 +170,13 @@ public class GuiProfileViewer extends GuiScreen { NotEnoughUpdates.INSTANCE.config.profileViewer.showPronounsInPv ? Optional.ofNullable(profile).map(it -> Utils.parseDashlessUUID(it.getUuid())) : Optional.<UUID>empty(), - uuid -> CompletableFuture.supplyAsync(() -> uuid.flatMap(PronounDB::getPronounsFor)) + uuid -> uuid.isPresent() + ? PronounDB.getPronounsFor(uuid.get()) + : CompletableFuture.completedFuture(Optional.empty()) ); public final GuiElementTextField playerNameTextField; public final GuiElementTextField inventoryTextField = new GuiElementTextField("", GuiElementTextField.SCALE_TEXT); + public final GuiElementTextField killDeathSearchTextField = new GuiElementTextField("", GuiElementTextField.SCALE_TEXT); private final Map<ProfileViewerPage, GuiProfileViewerPage> pages = new HashMap<>(); public int sizeX; public int sizeY; @@ -457,7 +465,7 @@ public class GuiProfileViewer extends GuiScreen { new Color(63, 224, 208, 255).getRGB() ); - if (profileDropdownSelected && !profile.getProfileNames().isEmpty() && scaledResolution.getScaleFactor() != 4) { + if (profileDropdownSelected && !profile.getProfileNames().isEmpty() && scaledResolution.getScaleFactor() < 4) { int dropdownOptionSize = scaledResolution.getScaleFactor() == 3 ? 10 : 20; int numProfiles = profile.getProfileNames().size(); @@ -736,7 +744,7 @@ public class GuiProfileViewer extends GuiScreen { break; case NO_SKYBLOCK: Utils.drawStringCentered( - EnumChatFormatting.RED + "No skyblock data found!", + EnumChatFormatting.RED + "No SkyBlock data found!", Minecraft.getMinecraft().fontRendererObj, guiLeft + sizeX / 2f, guiTop + 101, @@ -749,6 +757,34 @@ public class GuiProfileViewer extends GuiScreen { lastTime = currentTime; + if (currentPage != ProfileViewerPage.LOADING && currentPage != ProfileViewerPage.INVALID_NAME) { + int ignoredTabs = 0; + List<Integer> configList = NotEnoughUpdates.INSTANCE.config.profileViewer.pageLayout; + for (int i = 0; i < configList.size(); i++) { + ProfileViewerPage iPage = ProfileViewerPage.getById(configList.get(i)); + if (iPage == null) continue; + if (iPage.stack == null || (iPage == ProfileViewerPage.BINGO && !showBingoPage)) { + ignoredTabs++; + continue; + } + int i2 = i - ignoredTabs; + int x = guiLeft + i2 * 28; + int y = guiTop - 28; + + if (mouseX > x && mouseX < x + 28) { + if (mouseY > y && mouseY < y + 32) { + if (!iPage.stack + .getTooltip(Minecraft.getMinecraft().thePlayer, false) + .isEmpty()) { + tooltipToDisplay = Collections.singletonList(iPage.stack + .getTooltip(Minecraft.getMinecraft().thePlayer, false) + .get(0)); + } + } + } + } + } + if (tooltipToDisplay != null) { List<String> grayTooltip = new ArrayList<>(tooltipToDisplay.size()); for (String line : tooltipToDisplay) { @@ -839,6 +875,7 @@ public class GuiProfileViewer extends GuiScreen { currentPage = page; inventoryTextField.otherComponentClick(); playerNameTextField.otherComponentClick(); + killDeathSearchTextField.otherComponentClick(); return; } } @@ -855,6 +892,7 @@ public class GuiProfileViewer extends GuiScreen { if (mouseY > guiTop + sizeY + 5 && mouseY < guiTop + sizeY + 25) { playerNameTextField.mouseClicked(mouseX, mouseY, mouseButton); inventoryTextField.otherComponentClick(); + killDeathSearchTextField.otherComponentClick(); return; } } @@ -887,7 +925,7 @@ public class GuiProfileViewer extends GuiScreen { if (mouseX > guiLeft && mouseX < guiLeft + 100 && profile != null && !profile.getProfileNames().isEmpty()) { ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); if (mouseY > guiTop + sizeY + 3 && mouseY < guiTop + sizeY + 23) { - if (scaledResolution.getScaleFactor() == 4) { + if (scaledResolution.getScaleFactor() >= 4) { profileDropdownSelected = false; int profileNum = 0; for (int index = 0; index < profile.getProfileNames().size(); index++) { @@ -912,7 +950,7 @@ public class GuiProfileViewer extends GuiScreen { } else { profileDropdownSelected = !profileDropdownSelected; } - } else if (scaledResolution.getScaleFactor() != 4 && profileDropdownSelected) { + } else if (scaledResolution.getScaleFactor() < 4 && profileDropdownSelected) { int dropdownOptionSize = scaledResolution.getScaleFactor() == 3 ? 10 : 20; int extraY = mouseY - (guiTop + sizeY + 23); int index = extraY / dropdownOptionSize; @@ -926,11 +964,13 @@ public class GuiProfileViewer extends GuiScreen { } playerNameTextField.otherComponentClick(); inventoryTextField.otherComponentClick(); + killDeathSearchTextField.otherComponentClick(); return; } profileDropdownSelected = false; playerNameTextField.otherComponentClick(); inventoryTextField.otherComponentClick(); + killDeathSearchTextField.otherComponentClick(); } @Override @@ -994,9 +1034,11 @@ public class GuiProfileViewer extends GuiScreen { if (mouseY > y - 4 && mouseY < y + 13) { String levelStr; String totalXpStr = null; - if (skillName.contains("Catacombs")) totalXpStr = - EnumChatFormatting.GRAY + "Total XP: " + EnumChatFormatting.DARK_PURPLE + - numberFormat.format(levelObj.totalXp); + if (skillName.contains("Catacombs")) { + totalXpStr = EnumChatFormatting.GRAY + "Total XP: " + EnumChatFormatting.DARK_PURPLE + + numberFormat.format(levelObj.totalXp) + EnumChatFormatting.DARK_GRAY + " (" + + DECIMAL_FORMAT.format(getPercentage(skillName.toLowerCase(), levelObj)) + "% to 50)"; + } if (levelObj.maxed) { levelStr = EnumChatFormatting.GOLD + "MAXED!"; } else { @@ -1208,6 +1250,25 @@ public class GuiProfileViewer extends GuiScreen { } } + public float getPercentage(String skillName, ProfileViewer.Level level) { + if (level.maxed) { + return 100; + } + if (skillName.contains("catacombs")) { + return (level.totalXp / DungeonsWeight.CATACOMBS_LEVEL_50_XP) * 100; + } else if (ExtraPage.slayers.containsKey(skillName)) { + return (level.totalXp / 1000000) * 100; + } else if (skillName.equalsIgnoreCase("social")) { + return (level.totalXp / 272800) * 100; + } else { + if (level.maxLevel == 60) { + return (level.totalXp / SkillsWeight.SKILLS_LEVEL_60) * 100; + } else { + return (level.totalXp / SkillsWeight.SKILLS_LEVEL_50) * 100; + } + } + } + /** * Renders a subsection of the blurred framebuffer on to the corresponding section of the screen. * Essentially, this method will "blur" the background inside the bounds specified by [x->x+blurWidth, y->y+blurHeight] @@ -1232,16 +1293,16 @@ public class GuiProfileViewer extends GuiScreen { LOADING(), INVALID_NAME(), NO_SKYBLOCK(), - BASIC(0, Items.paper, "Your Skills"), - DUNGEON(1, Item.getItemFromBlock(Blocks.deadbush), "Dungeoneering"), - EXTRA(2, Items.book, "Profile Stats"), - INVENTORIES(3, Item.getItemFromBlock(Blocks.ender_chest), "Storage"), - COLLECTIONS(4, Items.painting, "Collections"), - PETS(5, Items.bone, "Pets"), - MINING(6, Items.iron_pickaxe, "Heart of the Mountain"), - BINGO(7, Items.filled_map, "Bingo"), - TROPHY_FISH(8, Items.fishing_rod, "Trophy Fish"), - BESTIARY(9, Items.iron_sword, "Bestiary"); + BASIC(0, Items.paper, "§9Skills"), + DUNGEON(1, Item.getItemFromBlock(Blocks.deadbush), "§eDungeoneering"), + EXTRA(2, Items.book, "§7Profile Stats"), + INVENTORIES(3, Item.getItemFromBlock(Blocks.ender_chest), "§bStorage"), + COLLECTIONS(4, Items.painting, "§6Collections"), + PETS(5, Items.bone, "§aPets"), + MINING(6, Items.iron_pickaxe, "§5Heart of the Mountain"), + BINGO(7, Items.filled_map, "§zBingo"), + TROPHY_FISH(8, Items.fishing_rod, "§3Trophy Fish"), + BESTIARY(9, Items.iron_sword, "§cBestiary"); public final ItemStack stack; public final int id; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java index c98792ee..b4f1da30 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java @@ -240,28 +240,6 @@ public class InventoriesPage extends GuiProfileViewerPage { if (currentInventoryIndex < 0) currentInventoryIndex = 0; ItemStack[][] inventory = inventories[currentInventoryIndex]; - if (inventory == null) { - if (selectedInventory.equalsIgnoreCase("personal_vault_contents")) { - Utils.drawStringCentered( - EnumChatFormatting.RED + "Personal Vault API not enabled!", - Minecraft.getMinecraft().fontRendererObj, - guiLeft + 317, - guiTop + 101, - true, - 0 - ); - } else { - Utils.drawStringCentered( - EnumChatFormatting.RED + "Inventory API not enabled!", - Minecraft.getMinecraft().fontRendererObj, - guiLeft + 317, - guiTop + 101, - true, - 0 - ); - } - return; - } if (bestWeapons == null) { bestWeapons = @@ -363,6 +341,32 @@ public class InventoriesPage extends GuiProfileViewerPage { } } + if (inventory == null) { + String strToRender = "Inventory API not enabled!"; + if (selectedInventory.equalsIgnoreCase("personal_vault_contents")) { + strToRender = "Personal Vault API not enabled!"; + } else if (selectedInventory.equalsIgnoreCase("backpack_contents")) { + strToRender = "Inventory API not enabled"; + Utils.drawStringCentered( + EnumChatFormatting.RED + "Or has no backpacks!", + Minecraft.getMinecraft().fontRendererObj, + guiLeft + 317, + guiTop + 112, + true, + 0 + ); + } + Utils.drawStringCentered( + EnumChatFormatting.RED + strToRender, + Minecraft.getMinecraft().fontRendererObj, + guiLeft + 317, + guiTop + 101, + true, + 0 + ); + return; + } + int inventoryRows = inventory.length; GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/MiningPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/MiningPage.java index c32310b7..d3b43e20 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/MiningPage.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/MiningPage.java @@ -75,7 +75,12 @@ public class MiningPage extends GuiProfileViewerPage { if (levelObjhotm == null) { float hotmXp = Utils.getElementAsFloat(Utils.getElement(profileInfo, "mining_core.experience"), 0); levelObjhotm = - ProfileViewer.getLevel(Utils.getElementOrDefault(leveling, "HOTM", new JsonArray()).getAsJsonArray(), hotmXp, 7, false); + ProfileViewer.getLevel( + Utils.getElementOrDefault(leveling, "HOTM", new JsonArray()).getAsJsonArray(), + hotmXp, + 7, + false + ); levelObjhotms.put(profileId, levelObjhotm); } @@ -83,37 +88,63 @@ public class MiningPage extends GuiProfileViewerPage { //The stats that show float mithrilPowder = Utils.getElementAsFloat(Utils.getElement(profileInfo, "mining_core.powder_mithril"), 0); float gemstonePowder = Utils.getElementAsFloat(Utils.getElement(profileInfo, "mining_core.powder_gemstone"), 0); - float mithrilPowderTotal = Utils.getElementAsFloat(Utils.getElement(profileInfo, "mining_core.powder_spent_mithril"), 0); - float gemstonePowderTotal = (Utils.getElementAsFloat(Utils.getElement(profileInfo, "mining_core.powder_spent_gemstone"), 0)); + float mithrilPowderTotal = Utils.getElementAsFloat(Utils.getElement( + profileInfo, + "mining_core.powder_spent_mithril" + ), 0); + float gemstonePowderTotal = (Utils.getElementAsFloat(Utils.getElement( + profileInfo, + "mining_core.powder_spent_gemstone" + ), 0)); String jadeCrystal = (Utils.getElementAsString(Utils.getElement(profileInfo, "mining_core.crystals.jade_crystal.state"), "Not Found")); float crystalPlacedAmount = (Utils.getElementAsFloat(Utils.getElement(profileInfo, "mining_core.crystals.jade_crystal.total_placed"), 0)); String jadeCrystalString = "§c✖"; String amethystCrystal = - (Utils.getElementAsString(Utils.getElement(profileInfo, "mining_core.crystals.amethyst_crystal.state"), "Not Found")); + (Utils.getElementAsString( + Utils.getElement(profileInfo, "mining_core.crystals.amethyst_crystal.state"), + "Not Found" + )); String amethystCrystalString = "§c✖"; String amberCrystal = - (Utils.getElementAsString(Utils.getElement(profileInfo, "mining_core.crystals.amber_crystal.state"), "Not Found")); + (Utils.getElementAsString( + Utils.getElement(profileInfo, "mining_core.crystals.amber_crystal.state"), + "Not Found" + )); String amberCrystalString = "§c✖"; String sapphireCrystal = - (Utils.getElementAsString(Utils.getElement(profileInfo, "mining_core.crystals.sapphire_crystal.state"), "Not Found")); + (Utils.getElementAsString( + Utils.getElement(profileInfo, "mining_core.crystals.sapphire_crystal.state"), + "Not Found" + )); String sapphireCrystalString = "§c✖"; String topazCrystal = - (Utils.getElementAsString(Utils.getElement(profileInfo, "mining_core.crystals.topaz_crystal.state"), "Not Found")); + (Utils.getElementAsString( + Utils.getElement(profileInfo, "mining_core.crystals.topaz_crystal.state"), + "Not Found" + )); String topazCrystalString = "§c✖"; String jasperCrystal = - (Utils.getElementAsString(Utils.getElement(profileInfo, "mining_core.crystals.jasper_crystal.state"), "Not Found")); + (Utils.getElementAsString( + Utils.getElement(profileInfo, "mining_core.crystals.jasper_crystal.state"), + "Not Found" + )); String jasperCrystalString = "§c✖"; String rubyCrystal = (Utils.getElementAsString(Utils.getElement(profileInfo, "mining_core.crystals.ruby_crystal.state"), "Not Found")); String rubyCrystalString = "§c✖"; int miningFortune = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.mining_fortune"), 0))); - int miningFortuneStat = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.mining_fortune"), 0)) * 5); + int miningFortuneStat = ((Utils.getElementAsInt( + Utils.getElement(profileInfo, "mining_core.nodes.mining_fortune"), + 0 + )) * 5); int miningSpeed = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.mining_speed"), 0))); - int miningSpeedStat = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.mining_speed"), 0)) * 20); + int miningSpeedStat = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.mining_speed"), 0)) * + 20); int dailyPowder = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.daily_powder"), 0))); - int dailyPowderStat = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.daily_powder"), 0)) * 36 + 364); + int dailyPowderStat = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.daily_powder"), 0)) * + 36 + 364); int effMiner = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.efficient_miner"), 0))); float effMinerStat = (float) ( (Utils.getElementAsFloat(Utils.getElement(profileInfo, "mining_core.nodes.efficient_miner"), 0)) * 0.4 + 10.4 @@ -121,7 +152,10 @@ public class MiningPage extends GuiProfileViewerPage { float effMinerStat2 = (float) ( (Utils.getElementAsFloat(Utils.getElement(profileInfo, "mining_core.nodes.efficient_miner"), 0)) * .06 + 0.31 ); - int tittyInsane = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.titanium_insanium"), 0))); + int tittyInsane = ((Utils.getElementAsInt( + Utils.getElement(profileInfo, "mining_core.nodes.titanium_insanium"), + 0 + ))); float tittyInsaneStat = (float) ( (Utils.getElementAsFloat(Utils.getElement(profileInfo, "mining_core.nodes.titanium_insanium"), 0)) * .1 + 2 ); @@ -143,23 +177,48 @@ public class MiningPage extends GuiProfileViewerPage { float orbitStat = (float) ( (Utils.getElementAsFloat(Utils.getElement(profileInfo, "mining_core.nodes.experience_orbs"), 0)) * .01 + 0.2 ); - int crystallized = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.fallen_star_bonus"), 0))); - int crystallizedStat = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.fallen_star_bonus"), 0)) * 6 + 14); + int crystallized = ((Utils.getElementAsInt( + Utils.getElement(profileInfo, "mining_core.nodes.fallen_star_bonus"), + 0 + ))); + int crystallizedStat = ((Utils.getElementAsInt( + Utils.getElement(profileInfo, "mining_core.nodes.fallen_star_bonus"), + 0 + )) * 6 + 14); int professional = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.professional"), 0))); - int professionalStat = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.professional"), 0)) * 5 + 50); + int professionalStat = ((Utils.getElementAsInt( + Utils.getElement(profileInfo, "mining_core.nodes.professional"), + 0 + )) * 5 + 50); int greatExplorer = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.great_explorer"), 0))); - int greatExplorerStat = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.great_explorer"), 0)) * 4 + 16); + int greatExplorerStat = ((Utils.getElementAsInt( + Utils.getElement(profileInfo, "mining_core.nodes.great_explorer"), + 0 + )) * 4 + 16); int fortunate = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.fortunate"), 0))); - int fortunateStat = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.fortunate"), 0)) * 4 + 20); + int fortunateStat = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.fortunate"), 0)) * 4 + + 20); int lonesomeMiner = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.lonesome_miner"), 0))); float lonesomeMinerStat = (float) ( (Utils.getElementAsFloat(Utils.getElement(profileInfo, "mining_core.nodes.lonesome_miner"), 0)) * .5 + 5 ); - int miningFortune2 = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.mining_fortune_2"), 0))); - int miningFortune2Stat = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.mining_fortune_2"), 0)) * 5); + int miningFortune2 = ((Utils.getElementAsInt( + Utils.getElement(profileInfo, "mining_core.nodes.mining_fortune_2"), + 0 + ))); + int miningFortune2Stat = ((Utils.getElementAsInt(Utils.getElement( + profileInfo, + "mining_core.nodes.mining_fortune_2" + ), 0)) * 5); int miningSpeed2 = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.mining_speed_2"), 0))); - int miningSpeed2Stat = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.mining_speed_2"), 0)) * 40); - int miningSpeedBoost = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.mining_speed_boost"), 0))); + int miningSpeed2Stat = ((Utils.getElementAsInt( + Utils.getElement(profileInfo, "mining_core.nodes.mining_speed_2"), + 0 + )) * 40); + int miningSpeedBoost = ((Utils.getElementAsInt(Utils.getElement( + profileInfo, + "mining_core.nodes.mining_speed_boost" + ), 0))); int veinSeeker = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.vein_seeker"), 0))); int powderBuff = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.powder_buff"), 0))); int potm = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.special_0"), 0))); @@ -172,7 +231,8 @@ public class MiningPage extends GuiProfileViewerPage { effMinerStat2 = 1; } int mole = ((Utils.getElementAsInt(Utils.getElement(profileInfo, "mining_core.nodes.mole"), 0))); - float moleStat = (float) ((Utils.getElementAsFloat(Utils.getElement(profileInfo, "mining_core.nodes.mole"), 0)) * 0.051); + float moleStat = (float) ((Utils.getElementAsFloat(Utils.getElement(profileInfo, "mining_core.nodes.mole"), 0)) * + 0.051); double moleperkstat = (double) mole / 20 - 0.55 + 50; double moleperkstat2 = (double) Math.round(moleperkstat * 100) / 100; @@ -320,35 +380,35 @@ public class MiningPage extends GuiProfileViewerPage { () -> miningSpeed != 50 && miningSpeed != 0 ? Lists.newArrayList( - "Mining Speed", - EnumChatFormatting.GRAY + "Level " + miningSpeed + EnumChatFormatting.DARK_GRAY + "/50", - "", - EnumChatFormatting.GRAY + + "Mining Speed", + EnumChatFormatting.GRAY + "Level " + miningSpeed + EnumChatFormatting.DARK_GRAY + "/50", + "", + EnumChatFormatting.GRAY + "Grants " + EnumChatFormatting.GREEN + "+" + miningSpeedStat + EnumChatFormatting.GOLD + " ⸕ Mining", - EnumChatFormatting.GOLD + "Speed" + EnumChatFormatting.GRAY + ".", - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.DARK_GREEN + + EnumChatFormatting.GOLD + "Speed" + EnumChatFormatting.GRAY + ".", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + GuiProfileViewer.numberFormat.format(Math.pow(miningSpeed + 2, 3)) + " Mithril Powder" - ) + ) : Lists.newArrayList( "Mining Speed", EnumChatFormatting.GRAY + "Level " + miningSpeed + EnumChatFormatting.DARK_GRAY + "/50", "", EnumChatFormatting.GRAY + - "Grants " + - EnumChatFormatting.GREEN + - "+" + - miningSpeedStat + - EnumChatFormatting.GOLD + - " ⸕ Mining", + "Grants " + + EnumChatFormatting.GREEN + + "+" + + miningSpeedStat + + EnumChatFormatting.GOLD + + " ⸕ Mining", EnumChatFormatting.GOLD + "Speed" + EnumChatFormatting.GRAY + "." ), 50 @@ -363,35 +423,35 @@ public class MiningPage extends GuiProfileViewerPage { () -> miningFortune != 0 && miningFortune != 50 ? Lists.newArrayList( - "Mining Fortune", - EnumChatFormatting.GRAY + "Level " + miningFortune + EnumChatFormatting.DARK_GRAY + "/50", - "", - EnumChatFormatting.GRAY + + "Mining Fortune", + EnumChatFormatting.GRAY + "Level " + miningFortune + EnumChatFormatting.DARK_GRAY + "/50", + "", + EnumChatFormatting.GRAY + "Grants " + EnumChatFormatting.GREEN + "+" + miningFortuneStat + EnumChatFormatting.GOLD + " ☘ Mining", - EnumChatFormatting.GOLD + "Fortune" + EnumChatFormatting.GRAY + ".", - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.DARK_GREEN + + EnumChatFormatting.GOLD + "Fortune" + EnumChatFormatting.GRAY + ".", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + GuiProfileViewer.numberFormat.format(Math.pow(miningFortune + 2, 3)) + " Mithril Powder" - ) + ) : Lists.newArrayList( "Mining Fortune", EnumChatFormatting.GRAY + "Level " + miningFortune + EnumChatFormatting.DARK_GRAY + "/50", "", EnumChatFormatting.GRAY + - "Grants " + - EnumChatFormatting.GREEN + - "+" + - miningFortuneStat + - EnumChatFormatting.GOLD + - " ☘ Mining", + "Grants " + + EnumChatFormatting.GREEN + + "+" + + miningFortuneStat + + EnumChatFormatting.GOLD + + " ☘ Mining", EnumChatFormatting.GOLD + "Fortune" + EnumChatFormatting.GRAY + "." ), 50 @@ -406,38 +466,38 @@ public class MiningPage extends GuiProfileViewerPage { () -> tittyInsane != 0 && tittyInsane != 50 ? Lists.newArrayList( - "Titanium Insanium", - EnumChatFormatting.GRAY + "Level " + tittyInsane + EnumChatFormatting.DARK_GRAY + "/50", - "", - EnumChatFormatting.GRAY + "When mining Mithril Ore, you", - EnumChatFormatting.GRAY + + "Titanium Insanium", + EnumChatFormatting.GRAY + "Level " + tittyInsane + EnumChatFormatting.DARK_GRAY + "/50", + "", + EnumChatFormatting.GRAY + "When mining Mithril Ore, you", + EnumChatFormatting.GRAY + "have a " + EnumChatFormatting.GREEN + tittyInsaneStat + "% " + EnumChatFormatting.GRAY + "chance to", - EnumChatFormatting.GRAY + "convert the block into Titanium", - EnumChatFormatting.GRAY + "Ore.", - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.DARK_GREEN + + EnumChatFormatting.GRAY + "convert the block into Titanium", + EnumChatFormatting.GRAY + "Ore.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + GuiProfileViewer.numberFormat.format((int) Math.pow(tittyInsane + 2, 3)) + " Mithril Powder" - ) + ) : Lists.newArrayList( "Titanium Insanium", EnumChatFormatting.GRAY + "Level " + tittyInsane + EnumChatFormatting.DARK_GRAY + "/50", "", EnumChatFormatting.GRAY + "When mining Mithril Ore, you", EnumChatFormatting.GRAY + - "have a " + - EnumChatFormatting.GREEN + - tittyInsaneStat + - "% " + - EnumChatFormatting.GRAY + - "chance to", + "have a " + + EnumChatFormatting.GREEN + + tittyInsaneStat + + "% " + + EnumChatFormatting.GRAY + + "chance to", EnumChatFormatting.GRAY + "convert the block into Titanium", EnumChatFormatting.GRAY + "Ore." ), @@ -453,31 +513,33 @@ public class MiningPage extends GuiProfileViewerPage { () -> potm == 0 ? Lists.newArrayList( // Peak of the mountain == 0 - "Mining Speed Boost", - "", - EnumChatFormatting.GRAY + "Pickaxe Ability: Mining Speed Boost", - EnumChatFormatting.GRAY + "Grants " + EnumChatFormatting.GREEN + "200% " + EnumChatFormatting.GOLD + "⸕ Mining", - EnumChatFormatting.GOLD + + "Mining Speed Boost", + "", + EnumChatFormatting.GRAY + "Pickaxe Ability: Mining Speed Boost", + EnumChatFormatting.GRAY + "Grants " + EnumChatFormatting.GREEN + "200% " + EnumChatFormatting.GOLD + + "⸕ Mining", + EnumChatFormatting.GOLD + "Speed " + EnumChatFormatting.GRAY + "for " + EnumChatFormatting.GREEN + "15s" + EnumChatFormatting.GRAY, - EnumChatFormatting.DARK_GRAY + "Cooldown: " + EnumChatFormatting.GREEN + "120s" - ) + EnumChatFormatting.DARK_GRAY + "Cooldown: " + EnumChatFormatting.GREEN + "120s" + ) : Lists.newArrayList( // Peak of the mountain > 0 "Mining Speed Boost", "", EnumChatFormatting.GRAY + "Pickaxe Ability: Mining Speed Boost", - EnumChatFormatting.GRAY + "Grants " + EnumChatFormatting.GREEN + "300% " + EnumChatFormatting.GOLD + "⸕ Mining", + EnumChatFormatting.GRAY + "Grants " + EnumChatFormatting.GREEN + "300% " + EnumChatFormatting.GOLD + + "⸕ Mining", EnumChatFormatting.GOLD + - "Speed " + - EnumChatFormatting.GRAY + - "for " + - EnumChatFormatting.GREEN + - "20s" + - EnumChatFormatting.GRAY, + "Speed " + + EnumChatFormatting.GRAY + + "for " + + EnumChatFormatting.GREEN + + "20s" + + EnumChatFormatting.GRAY, EnumChatFormatting.DARK_GRAY + "Cooldown: " + EnumChatFormatting.GREEN + "120s" ) ); @@ -509,19 +571,19 @@ public class MiningPage extends GuiProfileViewerPage { () -> luckofcave != 0 && luckofcave != 45 ? Lists.newArrayList( - "Luck of the Cave", - "§7Level " + luckofcave + EnumChatFormatting.DARK_GRAY + "/45", - "", - "§7Increases the chance for you to", - "§7trigger rare occurrences im", - "§2Dwarven Mines " + EnumChatFormatting.GRAY + "by " + EnumChatFormatting.GREEN + luckofcaveStat + "%§7.", - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.DARK_GREEN + + "Luck of the Cave", + "§7Level " + luckofcave + EnumChatFormatting.DARK_GRAY + "/45", + "", + "§7Increases the chance for you to", + "§7trigger rare occurrences im", + "§2Dwarven Mines " + EnumChatFormatting.GRAY + "by " + EnumChatFormatting.GREEN + luckofcaveStat + "%§7.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + GuiProfileViewer.numberFormat.format((int) Math.pow(luckofcave + 2, 3.07)) + " Mithril Powder" - ) + ) : Lists.newArrayList( "Luck of the Cave", "§7Level " + luckofcave + EnumChatFormatting.DARK_GRAY + "/45", @@ -542,33 +604,33 @@ public class MiningPage extends GuiProfileViewerPage { () -> dailyPowder != 0 && dailyPowder != 100 ? Lists.newArrayList( - "Daily Powder", - EnumChatFormatting.GRAY + "Level " + dailyPowder + EnumChatFormatting.DARK_GRAY + "/100", - "", - EnumChatFormatting.GRAY + + "Daily Powder", + EnumChatFormatting.GRAY + "Level " + dailyPowder + EnumChatFormatting.DARK_GRAY + "/100", + "", + EnumChatFormatting.GRAY + "Gains " + EnumChatFormatting.GREEN + dailyPowderStat + " Powder" + EnumChatFormatting.GRAY + " from the", - EnumChatFormatting.GRAY + "first ore you mine every day.", - EnumChatFormatting.GRAY + "Works for all Powder types.", - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.DARK_GREEN + "" + (200 + ((dailyPowder) * 18)) + " Mithril Powder" - ) + EnumChatFormatting.GRAY + "first ore you mine every day.", + EnumChatFormatting.GRAY + "Works for all Powder types.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + (200 + ((dailyPowder) * 18)) + " Mithril Powder" + ) : Lists.newArrayList( "Daily Powder", EnumChatFormatting.GRAY + "Level " + dailyPowder + EnumChatFormatting.DARK_GRAY + "/100", "", EnumChatFormatting.GRAY + - "Gains " + - EnumChatFormatting.GREEN + - dailyPowderStat + - " Powder" + - EnumChatFormatting.GRAY + - " from the", + "Gains " + + EnumChatFormatting.GREEN + + dailyPowderStat + + " Powder" + + EnumChatFormatting.GRAY + + " from the", EnumChatFormatting.GRAY + "first ore you mine every day.", EnumChatFormatting.GRAY + "Works for all Powder types." ), @@ -585,11 +647,11 @@ public class MiningPage extends GuiProfileViewerPage { () -> effMiner != 0 && effMiner != 100 ? Lists.newArrayList( - "Efficient Miner", - EnumChatFormatting.GRAY + "Level " + effMiner + EnumChatFormatting.DARK_GRAY + "/100", - "", - EnumChatFormatting.GRAY + "When mining ores, you have a", - EnumChatFormatting.GREEN + + "Efficient Miner", + EnumChatFormatting.GRAY + "Level " + effMiner + EnumChatFormatting.DARK_GRAY + "/100", + "", + EnumChatFormatting.GRAY + "When mining ores, you have a", + EnumChatFormatting.GREEN + "" + effMinerStat + "%" + @@ -597,27 +659,27 @@ public class MiningPage extends GuiProfileViewerPage { " chance to mine " + EnumChatFormatting.GREEN + Math.round(finalEffMinerStat2), - EnumChatFormatting.GRAY + "adjacent ores.", - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.DARK_GREEN + + EnumChatFormatting.GRAY + "adjacent ores.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + GuiProfileViewer.numberFormat.format((int) Math.pow(effMiner + 2, 2.6)) + " Mithril Powder" - ) + ) : Lists.newArrayList( "Efficient Miner", EnumChatFormatting.GRAY + "Level " + effMiner + EnumChatFormatting.DARK_GRAY + "/100", "", EnumChatFormatting.GRAY + "When mining ores, you have a", EnumChatFormatting.GREEN + - "" + - effMinerStat + - "%" + - EnumChatFormatting.GRAY + - " chance to mine " + - EnumChatFormatting.GREEN + - Math.round(finalEffMinerStat2), + "" + + effMinerStat + + "%" + + EnumChatFormatting.GRAY + + " chance to mine " + + EnumChatFormatting.GREEN + + Math.round(finalEffMinerStat2), EnumChatFormatting.GRAY + "adjacent ores." ), 100 @@ -634,38 +696,38 @@ public class MiningPage extends GuiProfileViewerPage { case 0: return Lists.newArrayList( EnumChatFormatting.RED + "Peak of the Mountain", - EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/5", + EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/7", "", EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.DARK_GREEN + "50000 Mithril Powder" + EnumChatFormatting.DARK_GREEN + "50,000 Mithril Powder" ); case 1: return Lists.newArrayList( EnumChatFormatting.YELLOW + "Peak of the Mountain", - EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/5", + EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/7", "", "§7§8+§c1 Pickaxe Ability Level", "§7§8+§51 Token of the Mountain", "", EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.DARK_GREEN + "50000 Mithril Powder" + EnumChatFormatting.DARK_GREEN + "50,000 Mithril Powder" ); case 2: return Lists.newArrayList( EnumChatFormatting.YELLOW + "Peak of the Mountain", - EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/5", + EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/7", "", "§7§8+§c1 Pickaxe Ability Level", "§7§8+§51 Token of the Mountain", "§7§8+§a1 Forge Slot", "", EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.DARK_GREEN + "75000 Mithril Powder" + EnumChatFormatting.DARK_GREEN + "75,000 Mithril Powder" ); case 3: return Lists.newArrayList( EnumChatFormatting.YELLOW + "Peak of the Mountain", - EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/5", + EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/7", "", "§7§8+§c1 Pickaxe Ability Level", "§7§8+§51 Token of the Mountain", @@ -673,12 +735,12 @@ public class MiningPage extends GuiProfileViewerPage { "§7§8+§a1 Commission Slot", "", EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.DARK_GREEN + "100000 Mithril Powder" + EnumChatFormatting.DARK_GREEN + "100,000 Mithril Powder" ); case 4: return Lists.newArrayList( EnumChatFormatting.YELLOW + "Peak of the Mountain", - EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/5", + EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/7", "", "§7§8+§c1 Pickaxe Ability Level", "§7§8+§51 Token of the Mountain", @@ -688,12 +750,46 @@ public class MiningPage extends GuiProfileViewerPage { "§7mining §fMithril", "", EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.DARK_GREEN + "125000 Mithril Powder" + EnumChatFormatting.DARK_GREEN + "125,000 Mithril Powder" ); case 5: return Lists.newArrayList( EnumChatFormatting.GREEN + "Peak of the Mountain", - EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/5", + EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/7", + "", + "§7§8+§c1 Pickaxe Ability Level", + "§7§8+§51 Token of the Mountain", + "§7§8+§a1 Forge Slot", + "§7§8+§a1 Commission Slot", + "§7§8+§21 Mithril Powder §7when", + "§7mining §fMithril", + "§7§8+§51 Token of the Mountain", + "", + "§7Cost", + "§d500,000 Gemstone Powder" + ); + case 6: + return Lists.newArrayList( + EnumChatFormatting.GREEN + "Peak of the Mountain", + EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/7", + "", + "§7§8+§c1 Pickaxe Ability Level", + "§7§8+§51 Token of the Mountain", + "§7§8+§a1 Forge Slot", + "§7§8+§a1 Commission Slot", + "§7§8+§21 Mithril Powder §7when", + "§7mining §fMithril", + "§7§8+§51 Token of the Mountain", + "§7§8+§d2 Gemstone Powder §7when", + "§7mining §dGemstones", + "", + "§7Cost", + "§d750,000 Gemstone Powder" + ); + case 7: + return Lists.newArrayList( + EnumChatFormatting.GREEN + "Peak of the Mountain", + EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/7", "", "§7§8+§c1 Pickaxe Ability Level", "§7§8+§51 Token of the Mountain", @@ -701,10 +797,18 @@ public class MiningPage extends GuiProfileViewerPage { "§7§8+§a1 Commission Slot", "§7§8+§21 Mithril Powder §7when", "§7mining §fMithril", + "§7§8+§51 Token of the Mountain", + "§7§8+§d2 Gemstone Powder §7when", + "§7mining §dGemstones", "§7§8+§51 Token of the Mountain" ); } - return null; + return Lists.newArrayList( + EnumChatFormatting.GREEN + "Peak of the Mountain", + EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/???", + EnumChatFormatting.RED + "It looks like your NEU doesn't understand your peak of the mountain perks.", + EnumChatFormatting.RED + "Please patiently await an update to your NEU installation." + ); }, potm > 0 ? new ItemStack(Blocks.redstone_block) : new ItemStack(Blocks.bedrock), true // A redstone block or bedrock is being rendered, so standard GUI item lighting needs to be enabled. @@ -720,11 +824,11 @@ public class MiningPage extends GuiProfileViewerPage { () -> mole != 0 && mole != 190 ? Lists.newArrayList( - "Mole", - EnumChatFormatting.GRAY + "Level " + mole + EnumChatFormatting.DARK_GRAY + "/190", - "", - EnumChatFormatting.GRAY + "When mining hard stone, you have", - EnumChatFormatting.GRAY + + "Mole", + EnumChatFormatting.GRAY + "Level " + mole + EnumChatFormatting.DARK_GRAY + "/190", + "", + EnumChatFormatting.GRAY + "When mining hard stone, you have", + EnumChatFormatting.GRAY + "a " + EnumChatFormatting.GREEN + finalOutput + @@ -732,38 +836,38 @@ public class MiningPage extends GuiProfileViewerPage { EnumChatFormatting.GRAY + "chance to mine " + EnumChatFormatting.GREEN, - EnumChatFormatting.GREEN + + EnumChatFormatting.GREEN + "" + Math.round(moleStat) + EnumChatFormatting.GRAY + " adjacent hard stone block" + (moleStat == 1.0 ? "." : "s."), - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.LIGHT_PURPLE + + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.LIGHT_PURPLE + "" + GuiProfileViewer.numberFormat.format((int) Math.pow(mole + 2, 2.2)) + " Gemstone Powder" - ) + ) : Lists.newArrayList( "Mole", EnumChatFormatting.GRAY + "Level " + mole + EnumChatFormatting.DARK_GRAY + "/190", "", EnumChatFormatting.GRAY + "When mining hard stone, you have", EnumChatFormatting.GRAY + - "a " + - EnumChatFormatting.GREEN + - finalOutput + - "% " + - EnumChatFormatting.GRAY + - "chance to mine " + - EnumChatFormatting.GREEN, + "a " + + EnumChatFormatting.GREEN + + finalOutput + + "% " + + EnumChatFormatting.GRAY + + "chance to mine " + + EnumChatFormatting.GREEN, EnumChatFormatting.GREEN + - "" + - Math.round(moleStat) + - EnumChatFormatting.GRAY + - " adjacent hard stone block" + - (moleStat == 1.0 ? "." : "s.") + "" + + Math.round(moleStat) + + EnumChatFormatting.GRAY + + " adjacent hard stone block" + + (moleStat == 1.0 ? "." : "s.") ), 190 ); @@ -777,35 +881,35 @@ public class MiningPage extends GuiProfileViewerPage { () -> powderBuff != 0 && powderBuff != 50 ? Lists.newArrayList( - "Powder Buff", - EnumChatFormatting.GRAY + "Level " + powderBuff + EnumChatFormatting.DARK_GRAY + "/50", - "", - EnumChatFormatting.GRAY + + "Powder Buff", + EnumChatFormatting.GRAY + "Level " + powderBuff + EnumChatFormatting.DARK_GRAY + "/50", + "", + EnumChatFormatting.GRAY + "Gain " + EnumChatFormatting.GREEN + powderBuff + "% " + EnumChatFormatting.GRAY + "more Mithril", - EnumChatFormatting.GRAY + "Powder and Gemstone Powder§7.", - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.LIGHT_PURPLE + + EnumChatFormatting.GRAY + "Powder and Gemstone Powder§7.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.LIGHT_PURPLE + "" + GuiProfileViewer.numberFormat.format((int) Math.pow(powderBuff + 2, 3.2)) + " Gemstone Powder" - ) + ) : Lists.newArrayList( "Powder Buff", EnumChatFormatting.GRAY + "Level " + powderBuff + EnumChatFormatting.DARK_GRAY + "/50", "", EnumChatFormatting.GRAY + - "Gain " + - EnumChatFormatting.GREEN + - powderBuff + - "% " + - EnumChatFormatting.GRAY + - "more Mithril", + "Gain " + + EnumChatFormatting.GREEN + + powderBuff + + "% " + + EnumChatFormatting.GRAY + + "more Mithril", EnumChatFormatting.GRAY + "Powder and Gemstone Powder§7." ), 50 @@ -865,24 +969,22 @@ public class MiningPage extends GuiProfileViewerPage { () -> seasonMine != 0 && seasonMine != 100 ? Lists.newArrayList( - "Seasoned Mineman", - "§7Level " + seasonMine + "§8/100", - "", - "§7Increases your Mining", - "§7experience gain by " + EnumChatFormatting.GREEN + seasonMineStat + "%§7.", - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.DARK_GREEN + + "Seasoned Mineman", + "§7Level " + seasonMine + "§8/100", + "", + "§7Grants §3+" + EnumChatFormatting.DARK_AQUA + seasonMineStat + "☯ Mining Wisdom§7.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + GuiProfileViewer.numberFormat.format((int) Math.pow(seasonMine + 2, 2.3)) + " Mithril Powder" - ) + ) : Lists.newArrayList( "Seasoned Mineman", "§7Level " + seasonMine + "§8/100", "", - "§7Increases your Mining", - "§7experience gain by " + EnumChatFormatting.GREEN + seasonMineStat + "%§7." + "§7Grants §3+" + EnumChatFormatting.DARK_AQUA + seasonMineStat + "☯ Mining Wisdom§7." ), 100 ); @@ -906,21 +1008,21 @@ public class MiningPage extends GuiProfileViewerPage { () -> lonesomeMiner != 0 && lonesomeMiner != 45 ? Lists.newArrayList( - "Lonesome Miner", - "§7Level " + lonesomeMiner + EnumChatFormatting.DARK_GRAY + "/45", - "", - "§7Increases §c❁ Strength, §9☣ Crit", - "§9Chance, §9☠ Crit Damage, §a❈", - "§aDefense, and §c❤ Health", - "§c§7statistics gain by " + EnumChatFormatting.GREEN + lonesomeMinerStat + "%§7", - "§7while in the Crystal Hollows.", - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.LIGHT_PURPLE + + "Lonesome Miner", + "§7Level " + lonesomeMiner + EnumChatFormatting.DARK_GRAY + "/45", + "", + "§7Increases §c❁ Strength, §9☣ Crit", + "§9Chance, §9☠ Crit Damage, §a❈", + "§aDefense, and §c❤ Health", + "§c§7statistics gain by " + EnumChatFormatting.GREEN + lonesomeMinerStat + "%§7", + "§7while in the Crystal Hollows.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.LIGHT_PURPLE + "" + GuiProfileViewer.numberFormat.format((int) Math.pow(lonesomeMiner + 2, 3.07)) + " Gemstone Powder" - ) + ) : Lists.newArrayList( "Lonesome Miner", "§7Level " + lonesomeMiner + EnumChatFormatting.DARK_GRAY + "/45", @@ -942,18 +1044,18 @@ public class MiningPage extends GuiProfileViewerPage { () -> professional != 0 && professional != 140 ? Lists.newArrayList( - "Professional", - "§7Level " + professional + EnumChatFormatting.DARK_GRAY + "/140", - "", - "§7Gain §a+" + professionalStat + "§6 ⸕ Mining", - "§6Speed§7 when mining Gemstones.", - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.LIGHT_PURPLE + + "Professional", + "§7Level " + professional + EnumChatFormatting.DARK_GRAY + "/140", + "", + "§7Gain §a+" + professionalStat + "§6 ⸕ Mining", + "§6Speed§7 when mining Gemstones.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.LIGHT_PURPLE + "" + GuiProfileViewer.numberFormat.format((int) Math.pow(professional + 2, 2.3)) + " Gemstone Powder" - ) + ) : Lists.newArrayList( "Professional", "§7Level " + professional + EnumChatFormatting.DARK_GRAY + "/140", @@ -973,18 +1075,18 @@ public class MiningPage extends GuiProfileViewerPage { () -> miningSpeed2 != 0 && miningSpeed2 != 50 ? Lists.newArrayList( - "Mining Speed 2", - "§7Level " + miningSpeed2 + EnumChatFormatting.DARK_GRAY + "/50", - "", - "§7Grants " + EnumChatFormatting.GREEN + "+" + miningSpeed2Stat + EnumChatFormatting.GOLD + " ⸕ Mining", - "§6Speed§7.", - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.LIGHT_PURPLE + + "Mining Speed 2", + "§7Level " + miningSpeed2 + EnumChatFormatting.DARK_GRAY + "/50", + "", + "§7Grants " + EnumChatFormatting.GREEN + "+" + miningSpeed2Stat + EnumChatFormatting.GOLD + " ⸕ Mining", + "§6Speed§7.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.LIGHT_PURPLE + "" + GuiProfileViewer.numberFormat.format(Math.pow(miningSpeed2 + 2, 3)) + " Gemstone Powder" - ) + ) : Lists.newArrayList( "Mining Speed 2", "§7Level " + miningSpeed2 + EnumChatFormatting.DARK_GRAY + "/50", @@ -1004,18 +1106,18 @@ public class MiningPage extends GuiProfileViewerPage { () -> quickForge != 0 && quickForge != 20 ? Lists.newArrayList( - "Quick Forge", - "§7Level " + quickForge + EnumChatFormatting.DARK_GRAY + "/20", - "", - "§7Decreases the time it takes to", - "§7forge by §a" + (quickForgeStat < 20 ? quickForgeStat : 30) + "%§7.", - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.DARK_GREEN + + "Quick Forge", + "§7Level " + quickForge + EnumChatFormatting.DARK_GRAY + "/20", + "", + "§7Decreases the time it takes to", + "§7forge by §a" + (quickForgeStat < 20 ? quickForgeStat : 30) + "%§7.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + GuiProfileViewer.numberFormat.format((int) Math.pow(quickForge + 2, 4)) + " Mithril Powder" - ) + ) : Lists.newArrayList( "Quick Forge", "§7Level " + quickForge + EnumChatFormatting.DARK_GRAY + "/20", @@ -1035,18 +1137,18 @@ public class MiningPage extends GuiProfileViewerPage { () -> fortunate != 0 && fortunate != 20 ? Lists.newArrayList( - "Fortunate", - "§7Level " + fortunate + EnumChatFormatting.DARK_GRAY + "/20", - "", - "§7Gain " + EnumChatFormatting.GREEN + "+" + fortunateStat + " §6☘ Mining", - "§6Fortune§7 when mining Gemstone.", - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.DARK_GREEN + + "Fortunate", + "§7Level " + fortunate + EnumChatFormatting.DARK_GRAY + "/20", + "", + "§7Gain " + EnumChatFormatting.GREEN + "+" + fortunateStat + " §6☘ Mining", + "§6Fortune§7 when mining Gemstone.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + GuiProfileViewer.numberFormat.format((int) Math.pow(fortunate + 2, 3.05)) + " Mithril Powder" - ) + ) : Lists.newArrayList( "Fortunate", "§7Level " + fortunate + EnumChatFormatting.DARK_GRAY + "/20", @@ -1066,23 +1168,25 @@ public class MiningPage extends GuiProfileViewerPage { () -> greatExplorer != 0 && greatExplorer != 20 ? Lists.newArrayList( - "Great Explorer", - "§7Level " + greatExplorer + EnumChatFormatting.DARK_GRAY + "/20", - "", - "§7Grants " + EnumChatFormatting.GREEN + "+" + greatExplorerStat + "% " + EnumChatFormatting.GRAY + "chance to", - "§7find treasure.", - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.LIGHT_PURPLE + + "Great Explorer", + "§7Level " + greatExplorer + EnumChatFormatting.DARK_GRAY + "/20", + "", + "§7Grants " + EnumChatFormatting.GREEN + "+" + greatExplorerStat + "% " + EnumChatFormatting.GRAY + + "chance to", + "§7find treasure.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.LIGHT_PURPLE + "" + GuiProfileViewer.numberFormat.format((int) Math.pow(greatExplorer + 2, 4)) + " Gemstone Powder" - ) + ) : Lists.newArrayList( "Great Explorer", "§7Level " + greatExplorer + EnumChatFormatting.DARK_GRAY + "/20", "", - "§7Grants " + EnumChatFormatting.GREEN + "+" + greatExplorerStat + "% " + EnumChatFormatting.GRAY + "chance to", + "§7Grants " + EnumChatFormatting.GREEN + "+" + greatExplorerStat + "% " + EnumChatFormatting.GRAY + + "chance to", "§7find treasure." ), 20 @@ -1097,18 +1201,18 @@ public class MiningPage extends GuiProfileViewerPage { () -> miningFortune2 != 0 && miningFortune2 != 50 ? Lists.newArrayList( - "Mining Fortune 2", - "§7Level " + miningFortune2 + EnumChatFormatting.DARK_GRAY + "/50", - "", - "§7Grants §a+§a" + miningFortune2Stat + "§7 §6☘ Mining", - "§6Fortune§7.", - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.LIGHT_PURPLE + + "Mining Fortune 2", + "§7Level " + miningFortune2 + EnumChatFormatting.DARK_GRAY + "/50", + "", + "§7Grants §a+§a" + miningFortune2Stat + "§7 §6☘ Mining", + "§6Fortune§7.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.LIGHT_PURPLE + "" + GuiProfileViewer.numberFormat.format((int) Math.pow(miningFortune2 + 2, 3.2)) + " Gemstone Powder" - ) + ) : Lists.newArrayList( "Mining Fortune 2", "§7Level " + miningFortune2 + EnumChatFormatting.DARK_GRAY + "/50", @@ -1128,16 +1232,16 @@ public class MiningPage extends GuiProfileViewerPage { () -> orbit != 0 && orbit != 80 ? Lists.newArrayList( - "Orbiter", - "§7Level " + orbit + EnumChatFormatting.DARK_GRAY + "/80", - "", - "§7When mining ores, you have a", - EnumChatFormatting.GREEN + "" + orbitStat + "%" + EnumChatFormatting.GRAY + " chance to get a random", - "§7amount of experience orbs.", - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.DARK_GREEN + "" + ((orbit + 1) * 70) + " Mithril Powder" - ) + "Orbiter", + "§7Level " + orbit + EnumChatFormatting.DARK_GRAY + "/80", + "", + "§7When mining ores, you have a", + EnumChatFormatting.GREEN + "" + orbitStat + "%" + EnumChatFormatting.GRAY + " chance to get a random", + "§7amount of experience orbs.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + ((orbit + 1) * 70) + " Mithril Powder" + ) : Lists.newArrayList( "Orbiter", "§7Level " + orbit + EnumChatFormatting.DARK_GRAY + "/80", @@ -1208,20 +1312,20 @@ public class MiningPage extends GuiProfileViewerPage { () -> crystallized != 0 && crystallized != 30 ? Lists.newArrayList( - "Crystallized", - "§7Level " + crystallized + EnumChatFormatting.DARK_GRAY + "/30", - "", - "§7Grants §a+§a" + crystallizedStat + "§7 §6⸕ Mining", - "§6Speed §7and a §a" + crystallizedStat + "%§7 §7chance", - "§7to deal §a+1 §7extra damage near", - "§7§5Fallen Stars§7.", - "", - EnumChatFormatting.GRAY + "Cost", - EnumChatFormatting.DARK_GREEN + + "Crystallized", + "§7Level " + crystallized + EnumChatFormatting.DARK_GRAY + "/30", + "", + "§7Grants §a+§a" + crystallizedStat + "§7 §6⸕ Mining", + "§6Speed §7and a §a" + crystallizedStat + "%§7 §7chance", + "§7to deal §a+1 §7extra damage near", + "§7§5Fallen Stars§7.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + GuiProfileViewer.numberFormat.format((int) Math.pow(crystallized + 2, 2.4)) + " Mithril Powder" - ) + ) : Lists.newArrayList( "Crystallized", "§7Level " + crystallized + EnumChatFormatting.DARK_GRAY + "/30", @@ -1322,7 +1426,9 @@ public class MiningPage extends GuiProfileViewerPage { ItemStack itemStack; if (isPickaxeAbility) { RenderHelper.enableGUIStandardItemLighting(); // GUI standard item lighting must be enabled for items that are rendered as blocks, like emerald blocks. - itemStack = new ItemStack(unlocked ? Blocks.emerald_block : Blocks.coal_block); // Pickaxe abilities are rendered as blocks + itemStack = new ItemStack(unlocked + ? Blocks.emerald_block + : Blocks.coal_block); // Pickaxe abilities are rendered as blocks } else { // Non-pickaxe abilities are rendered as items itemStack = new ItemStack(unlocked ? (perkLevel >= maxLevel ? Items.diamond : Items.emerald) : Items.coal); } @@ -1331,8 +1437,10 @@ public class MiningPage extends GuiProfileViewerPage { // Prepend the green, yellow, or red color on the first line of each tooltip depending on if the perk is unlocked tooltip.set( 0, - (unlocked ? (perkLevel >= maxLevel ? EnumChatFormatting.GREEN : EnumChatFormatting.YELLOW) : EnumChatFormatting.RED) + - tooltip.get(0) + (unlocked + ? (perkLevel >= maxLevel ? EnumChatFormatting.GREEN : EnumChatFormatting.YELLOW) + : EnumChatFormatting.RED) + + tooltip.get(0) ); NBTTagCompound nbt = new NBTTagCompound(); //Adding NBT Data for Custom Resource Packs diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PetsPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PetsPage.java index 25751ab8..cb85bf79 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PetsPage.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PetsPage.java @@ -22,22 +22,17 @@ package io.github.moulberry.notenoughupdates.profileviewer; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.util.StringUtils; +import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay; import io.github.moulberry.notenoughupdates.util.Constants; +import io.github.moulberry.notenoughupdates.util.ItemUtils; import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.init.Items; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.JsonToNBT; -import net.minecraft.nbt.NBTException; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.nbt.NBTTagString; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.ResourceLocation; import org.lwjgl.input.Mouse; @@ -46,11 +41,7 @@ import org.lwjgl.opengl.GL11; import java.awt.*; import java.io.IOException; import java.util.ArrayList; -import java.util.Base64; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.UUID; public class PetsPage extends GuiProfileViewerPage { @@ -91,7 +82,8 @@ public class PetsPage extends GuiProfileViewerPage { String panoramaIdentifier = "day"; if (SBInfo.getInstance().currentTimeDate != null) { - if (SBInfo.getInstance().currentTimeDate.getHours() <= 6 || SBInfo.getInstance().currentTimeDate.getHours() >= 20) { + if (SBInfo.getInstance().currentTimeDate.getHours() <= 6 || + SBInfo.getInstance().currentTimeDate.getHours() >= 20) { panoramaIdentifier = "night"; } } @@ -123,201 +115,22 @@ public class PetsPage extends GuiProfileViewerPage { } }); for (JsonObject pet : sortedPets) { - String petname = pet.get("type").getAsString(); - String tier = pet.get("tier").getAsString(); - String heldItem = Utils.getElementAsString(pet.get("heldItem"), null); - String skin = Utils.getElementAsString(pet.get("skin"), null); - int candy = pet.get("candyUsed").getAsInt(); - JsonObject heldItemJson = heldItem == null ? null : NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(heldItem); - String tierNum = GuiProfileViewer.MINION_RARITY_TO_NUM.get(tier); - float exp = pet.get("exp").getAsFloat(); - if (tierNum == null) continue; - - if ( - pet.has("heldItem") && - !pet.get("heldItem").isJsonNull() && - pet.get("heldItem").getAsString().equals("PET_ITEM_TIER_BOOST") - ) { - tierNum = "" + (Integer.parseInt(tierNum) + 1); - } - - GuiProfileViewer.PetLevel levelObj = GuiProfileViewer.getPetLevel(petname, tier, exp); - - float level = levelObj.level; - float currentLevelRequirement = levelObj.currentLevelRequirement; - float maxXP = levelObj.maxXP; - pet.addProperty("level", level); - pet.addProperty("currentLevelRequirement", currentLevelRequirement); - pet.addProperty("maxXP", maxXP); - - JsonObject petItem = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(petname + ";" + tierNum); - ItemStack stack; - if (petItem == null) { - stack = getQuestionmarkSkull(); - NBTTagCompound display = new NBTTagCompound(); - if (stack.getTagCompound() != null && stack.getTagCompound().hasKey("display")) { - display = stack.getTagCompound().getCompoundTag("display"); - } - NBTTagList lore = new NBTTagList(); - lore.appendTag(new NBTTagString(EnumChatFormatting.RED + "This pet is not saved in the repository")); - lore.appendTag(new NBTTagString("")); - lore.appendTag(new NBTTagString(EnumChatFormatting.RED + "If you expected it to be there please send a message in")); - lore.appendTag( - new NBTTagString( - EnumChatFormatting.RED.toString() + - EnumChatFormatting.BOLD + - "#neu-support " + - EnumChatFormatting.RESET + - EnumChatFormatting.RED + - "on " + - EnumChatFormatting.BOLD + - "discord.gg/moulberry" - ) - ); - - display.setTag("Lore", lore); - NBTTagCompound tag = stack.getTagCompound() != null ? stack.getTagCompound() : new NBTTagCompound(); - tag.setTag("display", display); - stack.setTagCompound(tag); - } else { - stack = NotEnoughUpdates.INSTANCE.manager.jsonToStack(petItem, false, false); - HashMap<String, String> replacements = NotEnoughUpdates.INSTANCE.manager.getLoreReplacements( - petname, - tier, - (int) Math.floor(level) - ); - - if (heldItem != null) { - HashMap<String, Float> petStatBoots = GuiProfileViewer.PET_STAT_BOOSTS.get(heldItem); - HashMap<String, Float> petStatBootsMult = GuiProfileViewer.PET_STAT_BOOSTS_MULT.get(heldItem); - if (petStatBoots != null) { - for (Map.Entry<String, Float> entryBoost : petStatBoots.entrySet()) { - try { - float value = Float.parseFloat(replacements.get(entryBoost.getKey())); - replacements.put(entryBoost.getKey(), String.valueOf((int) Math.floor(value + entryBoost.getValue()))); - } catch (Exception ignored) {} - } - } - if (petStatBootsMult != null) { - for (Map.Entry<String, Float> entryBoost : petStatBootsMult.entrySet()) { - try { - float value = Float.parseFloat(replacements.get(entryBoost.getKey())); - replacements.put(entryBoost.getKey(), String.valueOf((int) Math.floor(value * entryBoost.getValue()))); - } catch (Exception ignored) {} - } - } - } - - NBTTagCompound tag = stack.getTagCompound() == null ? new NBTTagCompound() : stack.getTagCompound(); - if (tag.hasKey("display", 10)) { - NBTTagCompound display = tag.getCompoundTag("display"); - if (display.hasKey("Lore", 9)) { - NBTTagList newLore = new NBTTagList(); - NBTTagList lore = display.getTagList("Lore", 8); - HashMap<Integer, Integer> blankLocations = new HashMap<>(); - for (int j = 0; j < lore.tagCount(); j++) { - String line = lore.getStringTagAt(j); - if (line.trim().isEmpty()) { - blankLocations.put(blankLocations.size(), j); - } - for (Map.Entry<String, String> replacement : replacements.entrySet()) { - line = line.replace("{" + replacement.getKey() + "}", replacement.getValue()); - } - newLore.appendTag(new NBTTagString(line)); - } - Integer secondLastBlank = blankLocations.get(blankLocations.size() - 2); - if (skin != null) { - JsonObject petSkin = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get("PET_SKIN_" + skin); - if (petSkin != null) { - try { - NBTTagCompound nbt = JsonToNBT.getTagFromJson(petSkin.get("nbttag").getAsString()); - tag.setTag("SkullOwner", nbt.getTag("SkullOwner")); - String name = petSkin.get("displayname").getAsString(); - if (name != null) { - name = Utils.cleanColour(name); - newLore.set(0, new NBTTagString(newLore.get(0).toString().replace("\"", "") + ", " + name)); - } - } catch (NBTException e) { - e.printStackTrace(); - } - } - } - for (int i = 0; i < newLore.tagCount(); i++) { - String cleaned = Utils.cleanColour(newLore.get(i).toString()); - if (cleaned.equals("\"Right-click to add this pet to\"")) { - newLore.removeTag(i + 1); - newLore.removeTag(i); - secondLastBlank = i - 1; - break; - } - } - NBTTagList temp = new NBTTagList(); - for (int i = 0; i < newLore.tagCount(); i++) { - temp.appendTag(newLore.get(i)); - if (secondLastBlank != null && i == secondLastBlank) { - if (heldItem != null) { - temp.appendTag( - new NBTTagString( - EnumChatFormatting.GOLD + "Held Item: " + heldItemJson.get("displayname").getAsString() - ) - ); - int blanks = 0; - JsonArray heldItemLore = heldItemJson.get("lore").getAsJsonArray(); - for (int k = 0; k < heldItemLore.size(); k++) { - String heldItemLine = heldItemLore.get(k).getAsString(); - if (heldItemLine.trim().isEmpty()) { - blanks++; - } else if (blanks == 2) { - temp.appendTag(new NBTTagString(heldItemLine)); - } else if (blanks > 2) { - break; - } - } - temp.appendTag(new NBTTagString()); - } - if (candy != 0) { - temp.appendTag(new NBTTagString(EnumChatFormatting.GREEN + "(" + candy + "/10) Pet Candy Used")); - temp.appendTag(new NBTTagString()); - } - temp.removeTag(temp.tagCount() - 1); - } - } - newLore = temp; - display.setTag("Lore", newLore); - } - if (display.hasKey("Name", 8)) { - String displayName = display.getString("Name"); - for (Map.Entry<String, String> replacement : replacements.entrySet()) { - displayName = displayName.replace("{" + replacement.getKey() + "}", replacement.getValue()); - } - display.setTag("Name", new NBTTagString(displayName)); - } - tag.setTag("display", display); - } - - // Adds the missing pet fields to the tag - NBTTagCompound extraAttributes = new NBTTagCompound(); - JsonObject petInfo = new JsonObject(); - if(tag.hasKey("ExtraAttributes", 10)) { - extraAttributes = tag.getCompoundTag("ExtraAttributes"); - if (extraAttributes.hasKey("petInfo", 8)) { - petInfo = new JsonParser().parse(extraAttributes.getString("petInfo")).getAsJsonObject(); - } - } - petInfo.addProperty("exp", exp); - petInfo.addProperty("tier", tier); - petInfo.addProperty("type", petname); - if (heldItem != null) { - petInfo.addProperty("heldItem", heldItem); - } - if (skin != null) { - petInfo.addProperty("skin", skin); - } - extraAttributes.setString("petInfo", petInfo.toString()); - tag.setTag("ExtraAttributes", extraAttributes); - stack.setTagCompound(tag); - } - sortedPetsStack.add(stack); + PetInfoOverlay.Pet parsedPet = new PetInfoOverlay.Pet(); + parsedPet.petType = pet.get("type").getAsString(); + parsedPet.rarity = PetInfoOverlay.Rarity.valueOf(pet.get("tier").getAsString()); + parsedPet.petLevel = GuiProfileViewer.getPetLevel( + parsedPet.petType, + parsedPet.rarity.name(), + pet.get("exp").getAsFloat() + ); + parsedPet.petXpType = "unknown"; + parsedPet.petItem = Utils.getElementAsString(pet.get("heldItem"), null); + parsedPet.skin = Utils.getElementAsString(pet.get("skin"), null); + parsedPet.candyUsed = pet.get("candyUsed").getAsInt(); + sortedPetsStack.add(ItemUtils.createPetItemstackFromPetInfo(parsedPet)); + pet.addProperty("level", parsedPet.petLevel.level); + pet.addProperty("currentLevelRequirement", parsedPet.petLevel.currentLevelRequirement); + pet.addProperty("maxXP", parsedPet.petLevel.maxXP); } } @@ -396,7 +209,11 @@ public class PetsPage extends GuiProfileViewerPage { ); } - for (int i = petsPage * 20; i < Math.min(petsPage * 20 + 20, Math.min(sortedPetsStack.size(), sortedPets.size())); i++) { + for ( + int i = petsPage * 20; + i < Math.min(petsPage * 20 + 20, Math.min(sortedPetsStack.size(), sortedPets.size())); + i++ + ) { JsonObject pet = sortedPets.get(i); ItemStack stack = sortedPetsStack.get(i); @@ -433,7 +250,7 @@ public class PetsPage extends GuiProfileViewerPage { if (selectedPet >= 0) { ItemStack petStack; if (sortedPetsStack.size() <= selectedPet) { - petStack = getQuestionmarkSkull(); + petStack = ItemUtils.createQuestionMarkSkull("§cInvalid pet selection"); } else { petStack = sortedPetsStack.get(selectedPet); } @@ -441,7 +258,8 @@ public class PetsPage extends GuiProfileViewerPage { JsonObject pet = sortedPets.get(selectedPet); int x = guiLeft + 280; - float y = guiTop + 67 + 15 * (float) Math.sin(((getInstance().currentTime - getInstance().startTime) / 800f) % (2 * Math.PI)); + float y = guiTop + 67 + 15 * (float) Math.sin( + ((getInstance().currentTime - getInstance().startTime) / 800f) % (2 * Math.PI)); int displayLen = Minecraft.getMinecraft().fontRendererObj.getStringWidth(display); int halfDisplayLen = displayLen / 2; @@ -568,32 +386,4 @@ public class PetsPage extends GuiProfileViewerPage { sortedPetsStack = null; selectedPet = -1; } - - private ItemStack getQuestionmarkSkull() { - String textureLink = "bc8ea1f51f253ff5142ca11ae45193a4ad8c3ab5e9c6eec8ba7a4fcb7bac40"; - - String b64Decoded = "{\"textures\":{\"SKIN\":{\"url\":\"http://textures.minecraft.net/texture/" + textureLink + "\"}}}"; - String b64Encoded = new String(Base64.getEncoder().encode(b64Decoded.getBytes())); - - ItemStack stack = new ItemStack(Items.skull, 1, 3); - NBTTagCompound nbt = new NBTTagCompound(); - NBTTagCompound skullOwner = new NBTTagCompound(); - NBTTagCompound properties = new NBTTagCompound(); - NBTTagList textures = new NBTTagList(); - NBTTagCompound textures_0 = new NBTTagCompound(); - - String uuid = UUID.nameUUIDFromBytes(b64Encoded.getBytes()).toString(); - skullOwner.setString("Id", uuid); - skullOwner.setString("Name", uuid); - - textures_0.setString("Value", b64Encoded); - textures.appendTag(textures_0); - - properties.setTag("textures", textures); - skullOwner.setTag("Properties", properties); - nbt.setTag("SkullOwner", skullOwner); - stack.setTagCompound(nbt); - stack.setStackDisplayName(EnumChatFormatting.RED + "Unknown Pet"); - return stack; - } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java index b6e56743..b32d3648 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java @@ -27,12 +27,23 @@ import io.github.moulberry.notenoughupdates.NEUManager; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.EnumChatFormatting; + +import javax.annotation.Nullable; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -41,15 +52,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.annotation.Nullable; -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.CompressedStreamTools; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.util.EnumChatFormatting; public class ProfileViewer { @@ -63,311 +65,384 @@ public class ProfileViewer { put("MYTHIC", "5"); } }; - private static final LinkedHashMap<String, ItemStack> skillToSkillDisplayMap = new LinkedHashMap<String, ItemStack>() { - { - put("taming", Utils.createItemStack(Items.spawn_egg, EnumChatFormatting.LIGHT_PURPLE + "Taming")); - put("mining", Utils.createItemStack(Items.stone_pickaxe, EnumChatFormatting.GRAY + "Mining")); - put("foraging", Utils.createItemStack(Item.getItemFromBlock(Blocks.sapling), EnumChatFormatting.DARK_GREEN + "Foraging")); - put( - "enchanting", - Utils.createItemStack(Item.getItemFromBlock(Blocks.enchanting_table), EnumChatFormatting.GREEN + "Enchanting") - ); - put( - "carpentry", - Utils.createItemStack(Item.getItemFromBlock(Blocks.crafting_table), EnumChatFormatting.DARK_RED + "Carpentry") - ); - put("farming", Utils.createItemStack(Items.golden_hoe, EnumChatFormatting.YELLOW + "Farming")); - put("combat", Utils.createItemStack(Items.stone_sword, EnumChatFormatting.RED + "Combat")); - put("fishing", Utils.createItemStack(Items.fishing_rod, EnumChatFormatting.AQUA + "Fishing")); - put("alchemy", Utils.createItemStack(Items.brewing_stand, EnumChatFormatting.BLUE + "Alchemy")); - put("runecrafting", Utils.createItemStack(Items.magma_cream, EnumChatFormatting.DARK_PURPLE + "Runecrafting")); - put("social", Utils.createItemStack(Items.emerald, EnumChatFormatting.DARK_GREEN + "Social")); - // put("catacombs", Utils.createItemStack(Item.getItemFromBlock(Blocks.deadbush), EnumChatFormatting.GOLD+"Catacombs")); - put("zombie", Utils.createItemStack(Items.rotten_flesh, EnumChatFormatting.GOLD + "Rev Slayer")); - put("spider", Utils.createItemStack(Items.spider_eye, EnumChatFormatting.GOLD + "Tara Slayer")); - put("wolf", Utils.createItemStack(Items.bone, EnumChatFormatting.GOLD + "Sven Slayer")); - put("enderman", Utils.createItemStack(Items.ender_pearl, EnumChatFormatting.GOLD + "Ender Slayer")); - put("blaze", Utils.createItemStack(Items.blaze_rod, EnumChatFormatting.GOLD + "Blaze Slayer")); - } - }; - private static final ItemStack CAT_FARMING = Utils.createItemStack(Items.golden_hoe, EnumChatFormatting.YELLOW + "Farming"); - private static final ItemStack CAT_MINING = Utils.createItemStack(Items.stone_pickaxe, EnumChatFormatting.GRAY + "Mining"); - private static final ItemStack CAT_COMBAT = Utils.createItemStack(Items.stone_sword, EnumChatFormatting.RED + "Combat"); + private static final LinkedHashMap<String, ItemStack> skillToSkillDisplayMap = + new LinkedHashMap<String, ItemStack>() { + { + put("taming", Utils.createItemStack(Items.spawn_egg, EnumChatFormatting.LIGHT_PURPLE + "Taming")); + put("mining", Utils.createItemStack(Items.stone_pickaxe, EnumChatFormatting.GRAY + "Mining")); + put( + "foraging", + Utils.createItemStack(Item.getItemFromBlock(Blocks.sapling), EnumChatFormatting.DARK_GREEN + "Foraging") + ); + put( + "enchanting", + Utils.createItemStack(Item.getItemFromBlock(Blocks.enchanting_table), EnumChatFormatting.GREEN + "Enchanting") + ); + put( + "carpentry", + Utils.createItemStack(Item.getItemFromBlock(Blocks.crafting_table), EnumChatFormatting.DARK_RED + "Carpentry") + ); + put("farming", Utils.createItemStack(Items.golden_hoe, EnumChatFormatting.YELLOW + "Farming")); + put("combat", Utils.createItemStack(Items.stone_sword, EnumChatFormatting.RED + "Combat")); + put("fishing", Utils.createItemStack(Items.fishing_rod, EnumChatFormatting.AQUA + "Fishing")); + put("alchemy", Utils.createItemStack(Items.brewing_stand, EnumChatFormatting.BLUE + "Alchemy")); + put("runecrafting", Utils.createItemStack(Items.magma_cream, EnumChatFormatting.DARK_PURPLE + "Runecrafting")); + put("social", Utils.createItemStack(Items.emerald, EnumChatFormatting.DARK_GREEN + "Social")); + // put("catacombs", Utils.createItemStack(Item.getItemFromBlock(Blocks.deadbush), EnumChatFormatting.GOLD+"Catacombs")); + put("zombie", Utils.createItemStack(Items.rotten_flesh, EnumChatFormatting.GOLD + "Rev Slayer")); + put("spider", Utils.createItemStack(Items.spider_eye, EnumChatFormatting.GOLD + "Tara Slayer")); + put("wolf", Utils.createItemStack(Items.bone, EnumChatFormatting.GOLD + "Sven Slayer")); + put("enderman", Utils.createItemStack(Items.ender_pearl, EnumChatFormatting.GOLD + "Ender Slayer")); + put("blaze", Utils.createItemStack(Items.blaze_rod, EnumChatFormatting.GOLD + "Blaze Slayer")); + } + }; + private static final ItemStack CAT_FARMING = Utils.createItemStack( + Items.golden_hoe, + EnumChatFormatting.YELLOW + "Farming" + ); + private static final ItemStack CAT_MINING = Utils.createItemStack( + Items.stone_pickaxe, + EnumChatFormatting.GRAY + "Mining" + ); + private static final ItemStack CAT_COMBAT = Utils.createItemStack( + Items.stone_sword, + EnumChatFormatting.RED + "Combat" + ); private static final ItemStack CAT_FORAGING = Utils.createItemStack( Item.getItemFromBlock(Blocks.sapling), EnumChatFormatting.DARK_GREEN + "Foraging" ); - private static final ItemStack CAT_FISHING = Utils.createItemStack(Items.fishing_rod, EnumChatFormatting.AQUA + "Fishing"); - private static final LinkedHashMap<ItemStack, List<String>> collectionCatToCollectionMap = new LinkedHashMap<ItemStack, List<String>>() { - { - put( - CAT_FARMING, - Utils.createList( - "WHEAT", - "CARROT_ITEM", - "POTATO_ITEM", + private static final ItemStack CAT_FISHING = Utils.createItemStack( + Items.fishing_rod, + EnumChatFormatting.AQUA + "Fishing" + ); + private static final LinkedHashMap<ItemStack, List<String>> collectionCatToCollectionMap = + new LinkedHashMap<ItemStack, List<String>>() { + { + put( + CAT_FARMING, + Utils.createList( + "WHEAT", + "CARROT_ITEM", + "POTATO_ITEM", + "PUMPKIN", + "MELON", + "SEEDS", + "MUSHROOM_COLLECTION", + "INK_SACK:3", + "CACTUS", + "SUGAR_CANE", + "FEATHER", + "LEATHER", + "PORK", + "RAW_CHICKEN", + "MUTTON", + "RABBIT", + "NETHER_STALK" + ) + ); + put( + CAT_MINING, + Utils.createList( + "COBBLESTONE", + "COAL", + "IRON_INGOT", + "GOLD_INGOT", + "DIAMOND", + "INK_SACK:4", + "EMERALD", + "REDSTONE", + "QUARTZ", + "OBSIDIAN", + "GLOWSTONE_DUST", + "GRAVEL", + "ICE", + "NETHERRACK", + "SAND", + "ENDER_STONE", + null, + "MITHRIL_ORE", + "HARD_STONE", + "GEMSTONE_COLLECTION", + "MYCEL", + "SAND:1", + "SULPHUR_ORE" + ) + ); + put( + CAT_COMBAT, + Utils.createList( + "ROTTEN_FLESH", + "BONE", + "STRING", + "SPIDER_EYE", + "SULPHUR", + "ENDER_PEARL", + "GHAST_TEAR", + "SLIME_BALL", + "BLAZE_ROD", + "MAGMA_CREAM", + null, + null, + null, + null, + "CHILI_PEPPER" + ) + ); + put(CAT_FORAGING, Utils.createList("LOG", "LOG:1", "LOG:2", "LOG_2:1", "LOG_2", "LOG:3", null)); + put( + CAT_FISHING, + Utils.createList( + "RAW_FISH", + "RAW_FISH:1", + "RAW_FISH:2", + "RAW_FISH:3", + "PRISMARINE_SHARD", + "PRISMARINE_CRYSTALS", + "CLAY_BALL", + "WATER_LILY", + "INK_SACK", + "SPONGE", + "MAGMA_FISH" + ) + ); + } + }; + private static final LinkedHashMap<ItemStack, List<String>> collectionCatToMinionMap = + new LinkedHashMap<ItemStack, List<String>>() { + { + put( + CAT_FARMING, + Utils.createList( + "WHEAT", + "CARROT", + "POTATO", + "PUMPKIN", + "MELON", + null, + "MUSHROOM", + "COCOA", + "CACTUS", + "SUGAR_CANE", + "CHICKEN", + "COW", + "PIG", + null, + "SHEEP", + "RABBIT", + "NETHER_WARTS" + ) + ); + put( + CAT_MINING, + Utils.createList( + "COBBLESTONE", + "COAL", + "IRON", + "GOLD", + "DIAMOND", + "LAPIS", + "EMERALD", + "REDSTONE", + "QUARTZ", + "OBSIDIAN", + "GLOWSTONE", + "GRAVEL", + "ICE", + null, + "SAND", + "ENDER_STONE", + "SNOW", + "MITHRIL", + "HARD_STONE", + null, + "MYCELIUM", + "RED_SAND", + null + ) + ); + put( + CAT_COMBAT, + Utils.createList( + "ZOMBIE", + "SKELETON", + "SPIDER", + "CAVESPIDER", + "CREEPER", + "ENDERMAN", + "GHAST", + "SLIME", + "BLAZE", + "MAGMA_CUBE", + "REVENANT", + "TARANTULA", + "VOIDLING", + "INFERNO" + ) + ); + put(CAT_FORAGING, Utils.createList("OAK", "SPRUCE", "BIRCH", "DARK_OAK", "ACACIA", "JUNGLE", "FLOWER")); + put(CAT_FISHING, Utils.createList("FISHING", null, null, null, null, null, "CLAY", null, null, null)); + } + }; + private static final LinkedHashMap<String, ItemStack> collectionToCollectionDisplayMap = + new LinkedHashMap<String, ItemStack>() { + { + /* FARMING COLLECTIONS */ + put("WHEAT", Utils.createItemStack(Items.wheat, EnumChatFormatting.YELLOW + "Wheat")); + put("CARROT_ITEM", Utils.createItemStack(Items.carrot, EnumChatFormatting.YELLOW + "Carrot")); + put("POTATO_ITEM", Utils.createItemStack(Items.potato, EnumChatFormatting.YELLOW + "Potato")); + put( "PUMPKIN", - "MELON", - "SEEDS", + Utils.createItemStack(Item.getItemFromBlock(Blocks.pumpkin), EnumChatFormatting.YELLOW + "Pumpkin") + ); + put("MELON", Utils.createItemStack(Items.melon, EnumChatFormatting.YELLOW + "Melon")); + put("SEEDS", Utils.createItemStack(Items.wheat_seeds, EnumChatFormatting.YELLOW + "Seeds")); + put( "MUSHROOM_COLLECTION", - "INK_SACK:3", + Utils.createItemStack(Item.getItemFromBlock(Blocks.red_mushroom), EnumChatFormatting.YELLOW + "Mushroom") + ); + put("INK_SACK:3", Utils.createItemStack(Items.dye, EnumChatFormatting.YELLOW + "Cocoa Beans", 3)); + put( "CACTUS", - "SUGAR_CANE", - "FEATHER", - "LEATHER", - "PORK", - "RAW_CHICKEN", - "MUTTON", - "RABBIT", - "NETHER_STALK" - ) - ); - put( - CAT_MINING, - Utils.createList( + Utils.createItemStack(Item.getItemFromBlock(Blocks.cactus), EnumChatFormatting.YELLOW + "Cactus") + ); + put("SUGAR_CANE", Utils.createItemStack(Items.reeds, EnumChatFormatting.YELLOW + "Sugar Cane")); + put("FEATHER", Utils.createItemStack(Items.feather, EnumChatFormatting.YELLOW + "Feather")); + put("LEATHER", Utils.createItemStack(Items.leather, EnumChatFormatting.YELLOW + "Leather")); + put("PORK", Utils.createItemStack(Items.porkchop, EnumChatFormatting.YELLOW + "Raw Porkchop")); + put("RAW_CHICKEN", Utils.createItemStack(Items.chicken, EnumChatFormatting.YELLOW + "Raw Chicken")); + put("MUTTON", Utils.createItemStack(Items.mutton, EnumChatFormatting.YELLOW + "Mutton")); + put("RABBIT", Utils.createItemStack(Items.rabbit, EnumChatFormatting.YELLOW + "Raw Rabbit")); + put("NETHER_STALK", Utils.createItemStack(Items.nether_wart, EnumChatFormatting.YELLOW + "Nether Wart")); + + /* MINING COLLECTIONS */ + put( "COBBLESTONE", - "COAL", - "IRON_INGOT", - "GOLD_INGOT", - "DIAMOND", - "INK_SACK:4", - "EMERALD", - "REDSTONE", - "QUARTZ", + Utils.createItemStack(Item.getItemFromBlock(Blocks.cobblestone), EnumChatFormatting.GRAY + "Cobblestone") + ); + put("COAL", Utils.createItemStack(Items.coal, EnumChatFormatting.GRAY + "Coal")); + put("IRON_INGOT", Utils.createItemStack(Items.iron_ingot, EnumChatFormatting.GRAY + "Iron Ingot")); + put("GOLD_INGOT", Utils.createItemStack(Items.gold_ingot, EnumChatFormatting.GRAY + "Gold Ingot")); + put("DIAMOND", Utils.createItemStack(Items.diamond, EnumChatFormatting.GRAY + "Diamond")); + put("INK_SACK:4", Utils.createItemStack(Items.dye, EnumChatFormatting.GRAY + "Lapis Lazuli", 4)); + put("EMERALD", Utils.createItemStack(Items.emerald, EnumChatFormatting.GRAY + "Emerald")); + put("REDSTONE", Utils.createItemStack(Items.redstone, EnumChatFormatting.GRAY + "Redstone")); + put("QUARTZ", Utils.createItemStack(Items.quartz, EnumChatFormatting.GRAY + "Nether Quartz")); + put( "OBSIDIAN", - "GLOWSTONE_DUST", - "GRAVEL", - "ICE", + Utils.createItemStack(Item.getItemFromBlock(Blocks.obsidian), EnumChatFormatting.GRAY + "Obsidian") + ); + put("GLOWSTONE_DUST", Utils.createItemStack(Items.glowstone_dust, EnumChatFormatting.GRAY + "Glowstone Dust")); + put("GRAVEL", Utils.createItemStack(Item.getItemFromBlock(Blocks.gravel), EnumChatFormatting.GRAY + "Gravel")); + put("ICE", Utils.createItemStack(Item.getItemFromBlock(Blocks.ice), EnumChatFormatting.GRAY + "Ice")); + put( "NETHERRACK", - "SAND", + Utils.createItemStack(Item.getItemFromBlock(Blocks.netherrack), EnumChatFormatting.GRAY + "Netherrack") + ); + put("SAND", Utils.createItemStack(Item.getItemFromBlock(Blocks.sand), EnumChatFormatting.GRAY + "Sand")); + put( "ENDER_STONE", - null, - "MITHRIL_ORE", + Utils.createItemStack(Item.getItemFromBlock(Blocks.end_stone), EnumChatFormatting.GRAY + "End Stone") + ); + put("MITHRIL_ORE", Utils.createItemStack(Items.prismarine_crystals, EnumChatFormatting.GRAY + "Mithril")); + put( "HARD_STONE", + Utils.createItemStack(Item.getItemFromBlock(Blocks.stone), EnumChatFormatting.GRAY + "Hard Stone") + ); + put( "GEMSTONE_COLLECTION", + Utils.createSkull( + EnumChatFormatting.GRAY + "Gemstone", + "e942eb66-a350-38e5-aafa-0dfc3e17b4ac", + "ewogICJ0aW1lc3RhbXAiIDogMTYxODA4Mzg4ODc3MSwKICAicHJvZmlsZUlkIiA6ICJjNTBhZmE4YWJlYjk0ZTQ1OTRiZjFiNDI1YTk4MGYwMiIsCiAgInByb2ZpbGVOYW1lIiA6ICJUd29FQmFlIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2FhYzE1ZjZmY2YyY2U5NjNlZjRjYTcxZjFhODY4NWFkYjk3ZWI3NjllMWQxMTE5NGNiYmQyZTk2NGE4ODk3OGMiCiAgICB9CiAgfQp9" + ) + ); + put( "MYCEL", + Utils.createItemStack(Item.getItemFromBlock(Blocks.mycelium), EnumChatFormatting.GRAY + "Mycelium") + ); + put( "SAND:1", - "SULPHUR_ORE" - ) - ); - put( - CAT_COMBAT, - Utils.createList( - "ROTTEN_FLESH", - "BONE", - "STRING", - "SPIDER_EYE", - "SULPHUR", - "ENDER_PEARL", - "GHAST_TEAR", - "SLIME_BALL", - "BLAZE_ROD", - "MAGMA_CREAM", - null, - null, - null, - null, - "CHILI_PEPPER" - ) - ); - put(CAT_FORAGING, Utils.createList("LOG", "LOG:1", "LOG:2", "LOG_2:1", "LOG_2", "LOG:3", null)); - put( - CAT_FISHING, - Utils.createList( - "RAW_FISH", - "RAW_FISH:1", - "RAW_FISH:2", - "RAW_FISH:3", + Utils.createItemStack(Item.getItemFromBlock(Blocks.sand), EnumChatFormatting.GRAY + "Red Sand", 1) + ); + put("SULPHUR_ORE", Utils.createItemStack(Items.glowstone_dust, EnumChatFormatting.GRAY + "Sulphur")); + + /* COMBAT COLLECTIONS */ + put("ROTTEN_FLESH", Utils.createItemStack(Items.rotten_flesh, EnumChatFormatting.RED + "Rotten Flesh")); + put("BONE", Utils.createItemStack(Items.bone, EnumChatFormatting.RED + "Bone")); + put("STRING", Utils.createItemStack(Items.string, EnumChatFormatting.RED + "String")); + put("SPIDER_EYE", Utils.createItemStack(Items.spider_eye, EnumChatFormatting.RED + "Spider Eye")); + put("SULPHUR", Utils.createItemStack(Items.gunpowder, EnumChatFormatting.RED + "Gunpowder")); + put("ENDER_PEARL", Utils.createItemStack(Items.ender_pearl, EnumChatFormatting.RED + "Ender Pearl")); + put("GHAST_TEAR", Utils.createItemStack(Items.ghast_tear, EnumChatFormatting.RED + "Ghast Tear")); + put("SLIME_BALL", Utils.createItemStack(Items.slime_ball, EnumChatFormatting.RED + "Slimeball")); + put("BLAZE_ROD", Utils.createItemStack(Items.blaze_rod, EnumChatFormatting.RED + "Blaze Rod")); + put("MAGMA_CREAM", Utils.createItemStack(Items.magma_cream, EnumChatFormatting.RED + "Magma Cream")); + put( + "CHILI_PEPPER", + Utils.createSkull( + EnumChatFormatting.RED + "Chili Pepper", + "3d47abaa-b40b-3826-b20c-d83a7f053bd9", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZjg1OWM4ZGYxMTA5YzA4YTc1NjI3NWYxZDI4ODdjMjc0ODA0OWZlMzM4Nzc3NjlhN2I0MTVkNTZlZGE0NjlkOCJ9fX0" + ) + ); + + /* FORAGING COLLECTIONS */ + put( + "LOG", + Utils.createItemStack(Item.getItemFromBlock(Blocks.log), EnumChatFormatting.DARK_GREEN + "Oak Wood") + ); + put( + "LOG:1", + Utils.createItemStack(Item.getItemFromBlock(Blocks.log), EnumChatFormatting.DARK_GREEN + "Spruce Wood", 1) + ); + put( + "LOG:2", + Utils.createItemStack(Item.getItemFromBlock(Blocks.log), EnumChatFormatting.DARK_GREEN + "Birch Wood", 2) + ); + put( + "LOG_2:1", + Utils.createItemStack(Item.getItemFromBlock(Blocks.log2), EnumChatFormatting.DARK_GREEN + "Dark Oak Wood", 1) + ); + put( + "LOG_2", + Utils.createItemStack(Item.getItemFromBlock(Blocks.log2), EnumChatFormatting.DARK_GREEN + "Acacia Wood") + ); + put( + "LOG:3", + Utils.createItemStack(Item.getItemFromBlock(Blocks.log), EnumChatFormatting.DARK_GREEN + "Jungle Wood", 3) + ); + + /* FISHING COLLECTIONS */ + put("RAW_FISH", Utils.createItemStack(Items.fish, EnumChatFormatting.AQUA + "Raw Fish")); + put("RAW_FISH:1", Utils.createItemStack(Items.fish, EnumChatFormatting.AQUA + "Raw Salmon", 1)); + put("RAW_FISH:2", Utils.createItemStack(Items.fish, EnumChatFormatting.AQUA + "Clownfish", 2)); + put("RAW_FISH:3", Utils.createItemStack(Items.fish, EnumChatFormatting.AQUA + "Pufferfish", 3)); + put( "PRISMARINE_SHARD", + Utils.createItemStack(Items.prismarine_shard, EnumChatFormatting.AQUA + "Prismarine Shard") + ); + put( "PRISMARINE_CRYSTALS", - "CLAY_BALL", + Utils.createItemStack(Items.prismarine_crystals, EnumChatFormatting.AQUA + "Prismarine Crystals") + ); + put("CLAY_BALL", Utils.createItemStack(Items.clay_ball, EnumChatFormatting.AQUA + "Clay")); + put( "WATER_LILY", - "INK_SACK", - "SPONGE", - "MAGMA_FISH" - ) - ); - } - }; - private static final LinkedHashMap<ItemStack, List<String>> collectionCatToMinionMap = new LinkedHashMap<ItemStack, List<String>>() { - { - put( - CAT_FARMING, - Utils.createList( - "WHEAT", - "CARROT", - "POTATO", - "PUMPKIN", - "MELON", - null, - "MUSHROOM", - "COCOA", - "CACTUS", - "SUGAR_CANE", - "CHICKEN", - "COW", - "PIG", - null, - "SHEEP", - "RABBIT", - "NETHER_WARTS" - ) - ); - put( - CAT_MINING, - Utils.createList( - "COBBLESTONE", - "COAL", - "IRON", - "GOLD", - "DIAMOND", - "LAPIS", - "EMERALD", - "REDSTONE", - "QUARTZ", - "OBSIDIAN", - "GLOWSTONE", - "GRAVEL", - "ICE", - null, - "SAND", - "ENDER_STONE", - "SNOW", - "MITHRIL", - "HARD_STONE", - null, - "MYCELIUM", - "RED_SAND", - null - ) - ); - put( - CAT_COMBAT, - Utils.createList( - "ZOMBIE", - "SKELETON", - "SPIDER", - "CAVESPIDER", - "CREEPER", - "ENDERMAN", - "GHAST", - "SLIME", - "BLAZE", - "MAGMA_CUBE", - "REVENANT", - "TARANTULA", - "VOIDLING", - "INFERNO" - ) - ); - put(CAT_FORAGING, Utils.createList("OAK", "SPRUCE", "BIRCH", "DARK_OAK", "ACACIA", "JUNGLE", "FLOWER")); - put(CAT_FISHING, Utils.createList("FISHING", null, null, null, null, null, "CLAY", null, null, null)); - } - }; - private static final LinkedHashMap<String, ItemStack> collectionToCollectionDisplayMap = new LinkedHashMap<String, ItemStack>() { - { - /* FARMING COLLECTIONS */ - put("WHEAT", Utils.createItemStack(Items.wheat, EnumChatFormatting.YELLOW + "Wheat")); - put("CARROT_ITEM", Utils.createItemStack(Items.carrot, EnumChatFormatting.YELLOW + "Carrot")); - put("POTATO_ITEM", Utils.createItemStack(Items.potato, EnumChatFormatting.YELLOW + "Potato")); - put("PUMPKIN", Utils.createItemStack(Item.getItemFromBlock(Blocks.pumpkin), EnumChatFormatting.YELLOW + "Pumpkin")); - put("MELON", Utils.createItemStack(Items.melon, EnumChatFormatting.YELLOW + "Melon")); - put("SEEDS", Utils.createItemStack(Items.wheat_seeds, EnumChatFormatting.YELLOW + "Seeds")); - put( - "MUSHROOM_COLLECTION", - Utils.createItemStack(Item.getItemFromBlock(Blocks.red_mushroom), EnumChatFormatting.YELLOW + "Mushroom") - ); - put("INK_SACK:3", Utils.createItemStack(Items.dye, EnumChatFormatting.YELLOW + "Cocoa Beans", 3)); - put("CACTUS", Utils.createItemStack(Item.getItemFromBlock(Blocks.cactus), EnumChatFormatting.YELLOW + "Cactus")); - put("SUGAR_CANE", Utils.createItemStack(Items.reeds, EnumChatFormatting.YELLOW + "Sugar Cane")); - put("FEATHER", Utils.createItemStack(Items.feather, EnumChatFormatting.YELLOW + "Feather")); - put("LEATHER", Utils.createItemStack(Items.leather, EnumChatFormatting.YELLOW + "Leather")); - put("PORK", Utils.createItemStack(Items.porkchop, EnumChatFormatting.YELLOW + "Porkchop")); - put("RAW_CHICKEN", Utils.createItemStack(Items.chicken, EnumChatFormatting.YELLOW + "Chicken")); - put("MUTTON", Utils.createItemStack(Items.mutton, EnumChatFormatting.YELLOW + "Mutton")); - put("RABBIT", Utils.createItemStack(Items.rabbit, EnumChatFormatting.YELLOW + "Rabbit")); - put("NETHER_STALK", Utils.createItemStack(Items.nether_wart, EnumChatFormatting.YELLOW + "Nether Wart")); - - /* MINING COLLECTIONS */ - put("COBBLESTONE", Utils.createItemStack(Item.getItemFromBlock(Blocks.cobblestone), EnumChatFormatting.GRAY + "Cobblestone")); - put("COAL", Utils.createItemStack(Items.coal, EnumChatFormatting.GRAY + "Coal")); - put("IRON_INGOT", Utils.createItemStack(Items.iron_ingot, EnumChatFormatting.GRAY + "Iron Ingot")); - put("GOLD_INGOT", Utils.createItemStack(Items.gold_ingot, EnumChatFormatting.GRAY + "Gold Ingot")); - put("DIAMOND", Utils.createItemStack(Items.diamond, EnumChatFormatting.GRAY + "Diamond")); - put("INK_SACK:4", Utils.createItemStack(Items.dye, EnumChatFormatting.GRAY + "Lapis Lazuli", 4)); - put("EMERALD", Utils.createItemStack(Items.emerald, EnumChatFormatting.GRAY + "Emerald")); - put("REDSTONE", Utils.createItemStack(Items.redstone, EnumChatFormatting.GRAY + "Redstone")); - put("QUARTZ", Utils.createItemStack(Items.quartz, EnumChatFormatting.GRAY + "Nether Quartz")); - put("OBSIDIAN", Utils.createItemStack(Item.getItemFromBlock(Blocks.obsidian), EnumChatFormatting.GRAY + "Obsidian")); - put("GLOWSTONE_DUST", Utils.createItemStack(Items.glowstone_dust, EnumChatFormatting.GRAY + "Glowstone")); - put("GRAVEL", Utils.createItemStack(Item.getItemFromBlock(Blocks.gravel), EnumChatFormatting.GRAY + "Gravel")); - put("ICE", Utils.createItemStack(Item.getItemFromBlock(Blocks.ice), EnumChatFormatting.GRAY + "Ice")); - put("NETHERRACK", Utils.createItemStack(Item.getItemFromBlock(Blocks.netherrack), EnumChatFormatting.GRAY + "Netherrack")); - put("SAND", Utils.createItemStack(Item.getItemFromBlock(Blocks.sand), EnumChatFormatting.GRAY + "Sand")); - put("ENDER_STONE", Utils.createItemStack(Item.getItemFromBlock(Blocks.end_stone), EnumChatFormatting.GRAY + "End Stone")); - put("MITHRIL_ORE", Utils.createItemStack(Items.prismarine_crystals, EnumChatFormatting.GRAY + "Mithril")); - put("HARD_STONE", Utils.createItemStack(Item.getItemFromBlock(Blocks.stone), EnumChatFormatting.GRAY + "Hard Stone")); - put( - "GEMSTONE_COLLECTION", - Utils.createSkull( - EnumChatFormatting.GRAY + "Gemstone", - "e942eb66-a350-38e5-aafa-0dfc3e17b4ac", - "ewogICJ0aW1lc3RhbXAiIDogMTYxODA4Mzg4ODc3MSwKICAicHJvZmlsZUlkIiA6ICJjNTBhZmE4YWJlYjk0ZTQ1OTRiZjFiNDI1YTk4MGYwMiIsCiAgInByb2ZpbGVOYW1lIiA6ICJUd29FQmFlIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2FhYzE1ZjZmY2YyY2U5NjNlZjRjYTcxZjFhODY4NWFkYjk3ZWI3NjllMWQxMTE5NGNiYmQyZTk2NGE4ODk3OGMiCiAgICB9CiAgfQp9" - ) - ); - put("MYCEL", Utils.createItemStack(Item.getItemFromBlock(Blocks.mycelium), EnumChatFormatting.GRAY + "Mycelium")); - put("SAND:1", Utils.createItemStack(Item.getItemFromBlock(Blocks.sand), EnumChatFormatting.GRAY + "Red Sand", 1)); - put("SULPHUR_ORE", Utils.createItemStack(Items.glowstone_dust, EnumChatFormatting.GRAY + "Sulphur")); - - /* COMBAT COLLECTIONS */ - put("ROTTEN_FLESH", Utils.createItemStack(Items.rotten_flesh, EnumChatFormatting.RED + "Rotten Flesh")); - put("BONE", Utils.createItemStack(Items.bone, EnumChatFormatting.RED + "Bone")); - put("STRING", Utils.createItemStack(Items.string, EnumChatFormatting.RED + "String")); - put("SPIDER_EYE", Utils.createItemStack(Items.spider_eye, EnumChatFormatting.RED + "Spider Eye")); - put("SULPHUR", Utils.createItemStack(Items.gunpowder, EnumChatFormatting.RED + "Gunpowder")); - put("ENDER_PEARL", Utils.createItemStack(Items.ender_pearl, EnumChatFormatting.RED + "Ender Pearl")); - put("GHAST_TEAR", Utils.createItemStack(Items.ghast_tear, EnumChatFormatting.RED + "Ghast Tear")); - put("SLIME_BALL", Utils.createItemStack(Items.slime_ball, EnumChatFormatting.RED + "Slimeball")); - put("BLAZE_ROD", Utils.createItemStack(Items.blaze_rod, EnumChatFormatting.RED + "Blaze Rod")); - put("MAGMA_CREAM", Utils.createItemStack(Items.magma_cream, EnumChatFormatting.RED + "Magma Cream")); - put( - "CHILI_PEPPER", - Utils.createSkull( - EnumChatFormatting.RED + "Chili Pepper", - "3d47abaa-b40b-3826-b20c-d83a7f053bd9", - "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZjg1OWM4ZGYxMTA5YzA4YTc1NjI3NWYxZDI4ODdjMjc0ODA0OWZlMzM4Nzc3NjlhN2I0MTVkNTZlZGE0NjlkOCJ9fX0" - ) - ); - - /* FORAGING COLLECTIONS */ - put("LOG", Utils.createItemStack(Item.getItemFromBlock(Blocks.log), EnumChatFormatting.DARK_GREEN + "Oak")); - put("LOG:1", Utils.createItemStack(Item.getItemFromBlock(Blocks.log), EnumChatFormatting.DARK_GREEN + "Spruce", 1)); - put("LOG:2", Utils.createItemStack(Item.getItemFromBlock(Blocks.log), EnumChatFormatting.DARK_GREEN + "Birch", 2)); - put("LOG_2:1", Utils.createItemStack(Item.getItemFromBlock(Blocks.log2), EnumChatFormatting.DARK_GREEN + "Dark Oak", 1)); - put("LOG_2", Utils.createItemStack(Item.getItemFromBlock(Blocks.log2), EnumChatFormatting.DARK_GREEN + "Acacia")); - put("LOG:3", Utils.createItemStack(Item.getItemFromBlock(Blocks.log), EnumChatFormatting.DARK_GREEN + "Jungle", 3)); - - /* FISHING COLLECTIONS */ - put("RAW_FISH", Utils.createItemStack(Items.fish, EnumChatFormatting.AQUA + "Fish")); - put("RAW_FISH:1", Utils.createItemStack(Items.fish, EnumChatFormatting.AQUA + "Salmon", 1)); - put("RAW_FISH:2", Utils.createItemStack(Items.fish, EnumChatFormatting.AQUA + "Clownfish", 2)); - put("RAW_FISH:3", Utils.createItemStack(Items.fish, EnumChatFormatting.AQUA + "Pufferfish", 3)); - put("PRISMARINE_SHARD", Utils.createItemStack(Items.prismarine_shard, EnumChatFormatting.AQUA + "Prismarine Shard")); - put("PRISMARINE_CRYSTALS", Utils.createItemStack(Items.prismarine_crystals, EnumChatFormatting.AQUA + "Prismarine Crystals")); - put("CLAY_BALL", Utils.createItemStack(Items.clay_ball, EnumChatFormatting.AQUA + "Clay")); - put("WATER_LILY", Utils.createItemStack(Item.getItemFromBlock(Blocks.waterlily), EnumChatFormatting.AQUA + "Lilypad")); - put("INK_SACK", Utils.createItemStack(Items.dye, EnumChatFormatting.AQUA + "Ink Sack")); - put("SPONGE", Utils.createItemStack(Item.getItemFromBlock(Blocks.sponge), EnumChatFormatting.AQUA + "Sponge")); - put( - "MAGMA_FISH", - Utils.createSkull( - EnumChatFormatting.AQUA + "Magmafish", - "5c53195c-5b98-3476-9731-c32647b22723", - "ewogICJ0aW1lc3RhbXAiIDogMTY0MjQ4ODA3MDY2NiwKICAicHJvZmlsZUlkIiA6ICIzNDkxZjJiOTdjMDE0MWE2OTM2YjFjMjJhMmEwMGZiNyIsCiAgInByb2ZpbGVOYW1lIiA6ICJKZXNzc3N1aGgiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZjU2YjU5NTViMjk1NTIyYzk2ODk0ODE5NjBjMDFhOTkyY2ExYzc3NTRjZjRlZTMxM2M4ZGQwYzM1NmQzMzVmIgogICAgfQogIH0KfQ" - ) - ); - } - }; + Utils.createItemStack(Item.getItemFromBlock(Blocks.waterlily), EnumChatFormatting.AQUA + "Lily Pad") + ); + put("INK_SACK", Utils.createItemStack(Items.dye, EnumChatFormatting.AQUA + "Ink Sac")); + put("SPONGE", Utils.createItemStack(Item.getItemFromBlock(Blocks.sponge), EnumChatFormatting.AQUA + "Sponge")); + put( + "MAGMA_FISH", + Utils.createSkull( + EnumChatFormatting.AQUA + "Magmafish", + "5c53195c-5b98-3476-9731-c32647b22723", + "ewogICJ0aW1lc3RhbXAiIDogMTY0MjQ4ODA3MDY2NiwKICAicHJvZmlsZUlkIiA6ICIzNDkxZjJiOTdjMDE0MWE2OTM2YjFjMjJhMmEwMGZiNyIsCiAgInByb2ZpbGVOYW1lIiA6ICJKZXNzc3N1aGgiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZjU2YjU5NTViMjk1NTIyYzk2ODk0ODE5NjBjMDFhOTkyY2ExYzc3NTRjZjRlZTMxM2M4ZGQwYzM1NmQzMzVmIgogICAgfQogIH0KfQ" + ) + ); + } + }; private static final AtomicBoolean updatingResourceCollection = new AtomicBoolean(false); private static JsonObject resourceCollection = null; private final NEUManager manager; @@ -437,49 +512,42 @@ public class ProfileViewer { updatingResourceCollection.set(true); - HashMap<String, String> args = new HashMap<>(); - NotEnoughUpdates.INSTANCE.manager.hypixelApi.getHypixelApiAsync( - NotEnoughUpdates.INSTANCE.config.apiData.apiKey, - "resources/skyblock/collections", - args, - jsonObject -> { + NotEnoughUpdates.INSTANCE.manager.apiUtils + .newHypixelApiRequest("resources/skyblock/collections") + .requestJson() + .thenAccept(jsonObject -> { updatingResourceCollection.set(false); if (jsonObject != null && jsonObject.has("success") && jsonObject.get("success").getAsBoolean()) { resourceCollection = jsonObject.get("collections").getAsJsonObject(); } - }, - () -> updatingResourceCollection.set(false) - ); - + }); return null; } public void getHypixelProfile(String name, Consumer<JsonObject> callback) { String nameF = name.toLowerCase(); - HashMap<String, String> args = new HashMap<>(); - args.put("name", "" + nameF); - manager.hypixelApi.getHypixelApiAsync( - NotEnoughUpdates.INSTANCE.config.apiData.apiKey, - "player", - args, - jsonObject -> { - if ( - jsonObject != null && - jsonObject.has("success") && - jsonObject.get("success").getAsBoolean() && - jsonObject.get("player").isJsonObject() - ) { - nameToUuid.put(nameF, jsonObject.get("player").getAsJsonObject().get("uuid").getAsString()); - uuidToHypixelProfile.put( - jsonObject.get("player").getAsJsonObject().get("uuid").getAsString(), - jsonObject.get("player").getAsJsonObject() - ); - if (callback != null) callback.accept(jsonObject); - } else { - if (callback != null) callback.accept(null); + manager.apiUtils + .newHypixelApiRequest("player") + .queryArgument("name", nameF) + .requestJson() + .thenAccept(jsonObject -> { + if ( + jsonObject != null && + jsonObject.has("success") && + jsonObject.get("success").getAsBoolean() && + jsonObject.get("player").isJsonObject() + ) { + nameToUuid.put(nameF, jsonObject.get("player").getAsJsonObject().get("uuid").getAsString()); + uuidToHypixelProfile.put( + jsonObject.get("player").getAsJsonObject().get("uuid").getAsString(), + jsonObject.get("player").getAsJsonObject() + ); + if (callback != null) callback.accept(jsonObject); + } else { + if (callback != null) callback.accept(null); + } } - } - ); + ); } public void putNameUuid(String name, String uuid) { @@ -493,19 +561,20 @@ public class ProfileViewer { return; } - manager.hypixelApi.getApiAsync( - "https://api.mojang.com/users/profiles/minecraft/" + nameF, - jsonObject -> { - if (jsonObject.has("id") && jsonObject.get("id").isJsonPrimitive() && ((JsonPrimitive) jsonObject.get("id")).isString()) { + manager.apiUtils + .request() + .url("https://api.mojang.com/users/profiles/minecraft/" + nameF) + .requestJson() + .thenAccept(jsonObject -> { + if (jsonObject.has("id") && jsonObject.get("id").isJsonPrimitive() && + ((JsonPrimitive) jsonObject.get("id")).isString()) { String uuid = jsonObject.get("id").getAsString(); nameToUuid.put(nameF, uuid); uuidCallback.accept(uuid); return; } uuidCallback.accept(null); - }, - () -> uuidCallback.accept(null) - ); + }); } public void getProfileByName(String name, Consumer<Profile> callback) { @@ -578,9 +647,11 @@ public class ProfileViewer { private final HashMap<String, PlayerStats.Stats> stats = new HashMap<>(); private final HashMap<String, PlayerStats.Stats> passiveStats = new HashMap<>(); private final HashMap<String, Long> networth = new HashMap<>(); + private final HashMap<String, SoopyNetworthData> soopyNetworth = new HashMap<>(); private final AtomicBoolean updatingSkyblockProfilesState = new AtomicBoolean(false); private final AtomicBoolean updatingGuildInfoState = new AtomicBoolean(false); private final AtomicBoolean updatingPlayerStatusState = new AtomicBoolean(false); + private final AtomicBoolean updatingSoopyNetworth = new AtomicBoolean(false); private final AtomicBoolean updatingBingoInfo = new AtomicBoolean(false); private final Pattern COLL_TIER_PATTERN = Pattern.compile("_(-?\\d+)"); private String latestProfile = null; @@ -608,20 +679,18 @@ public class ProfileViewer { HashMap<String, String> args = new HashMap<>(); args.put("uuid", "" + uuid); - manager.hypixelApi.getHypixelApiAsync( - NotEnoughUpdates.INSTANCE.config.apiData.apiKey, - "status", - args, - jsonObject -> { + manager.apiUtils + .newHypixelApiRequest("status") + .queryArgument("uuid", "" + uuid) + .requestJson() + .handle((jsonObject, ex) -> { updatingPlayerStatusState.set(false); if (jsonObject != null && jsonObject.has("success") && jsonObject.get("success").getAsBoolean()) { playerStatus = jsonObject.get("session").getAsJsonObject(); } - }, - () -> updatingPlayerStatusState.set(false) - ); - + return null; + }); return null; } @@ -634,13 +703,11 @@ public class ProfileViewer { lastBingoInfoState = currentTime; updatingBingoInfo.set(true); - HashMap<String, String> args = new HashMap<>(); - args.put("uuid", "" + uuid); - NotEnoughUpdates.INSTANCE.manager.hypixelApi.getHypixelApiAsync( - NotEnoughUpdates.INSTANCE.config.apiData.apiKey, - "skyblock/bingo", - args, - jsonObject -> { + NotEnoughUpdates.INSTANCE.manager.apiUtils + .newHypixelApiRequest("skyblock/bingo") + .queryArgument("uuid", "" + uuid) + .requestJson() + .handle(((jsonObject, throwable) -> { updatingBingoInfo.set(false); if (jsonObject != null && jsonObject.has("success") && jsonObject.get("success").getAsBoolean()) { @@ -648,12 +715,130 @@ public class ProfileViewer { } else { bingoInformation = null; } - }, - () -> updatingBingoInfo.set(false) - ); + return null; + })); return bingoInformation != null ? bingoInformation : null; } + public class SoopyNetworthData { + private HashMap<String, Long> categoryWorth; + private Long totalWorth; + private String[] keys; + + SoopyNetworthData(JsonObject nwData) { + categoryWorth = new HashMap<>(); + + if (nwData == null || nwData.isJsonNull()) { + totalWorth = -1l; + keys = new String[0]; + return; + } + if (nwData.get("total").isJsonNull()) { + totalWorth = -1l; + keys = new String[0]; + return; + } + + totalWorth = nwData.get("total").getAsLong(); + for (Map.Entry<String, JsonElement> entry : nwData.get("categories").getAsJsonObject().entrySet()) { + if (entry.getValue().isJsonNull()) { + continue; + } + categoryWorth.put(entry.getKey(), entry.getValue().getAsLong()); + } + + //Sort keys based on category value + keys = categoryWorth.keySet().stream().sorted(Comparator.comparingLong(k->getCategory((String) k)).reversed()).toArray(String[]::new); + } + + private SoopyNetworthData setLoading() { + totalWorth = -2l; + return this; + } + + public long getTotal() { + return totalWorth; + } + + public long getCategory(String name) { + if (categoryWorth.containsKey(name)) return categoryWorth.get(name); + return 0; + } + + public String[] getCategories() { + return keys; + } + } + + /** + * Returns SoopyNetworthData with total = -1 if error + * Returns null if still loading + */ + public SoopyNetworthData getSoopyNetworth(String profileName, Runnable callback) { + if (profileName == null) profileName = latestProfile; + if (soopyNetworth.get(profileName) != null) { + callback.run(); + return soopyNetworth.get(profileName); + } + + JsonArray playerInfo = getSkyblockProfiles(() -> {}); + if (playerInfo == null) return null; //Not sure how to support the callback in these cases + if (updatingSoopyNetworth.get()) return new SoopyNetworthData(null).setLoading(); //It shouldent really matter tho as these should never occur in /peek + updatingSoopyNetworth.set(true); + + manager.apiUtils + .request() + .url("https://soopy.dev/api/v2/player_networth/" + this.uuid) + .method("POST") + .postData("application/json", skyblockProfiles.toString()) + .requestJson() + .handle((jsonObject, throwable) -> { + if (throwable != null) throwable.printStackTrace(); + if (throwable != null || !jsonObject.has("success") || !jsonObject.get("success").getAsBoolean()) { + //Something went wrong + //Set profile networths to null to indicate that + for (int i = 0; i < skyblockProfiles.size(); i++) { + if (!skyblockProfiles.get(i).isJsonObject()) { + return null; + } + JsonObject profile = skyblockProfiles.get(i).getAsJsonObject(); + + String cuteName = profile.get("cute_name").getAsString(); + + soopyNetworth.put(cuteName, new SoopyNetworthData(null)); + } + updatingSoopyNetworth.set(false); + callback.run(); + return null; + } + + //Success, update networth data + for (int i = 0; i < skyblockProfiles.size(); i++) { + if (!skyblockProfiles.get(i).isJsonObject()) { + return null; + } + JsonObject profile = skyblockProfiles.get(i).getAsJsonObject(); + + String cuteName = profile.get("cute_name").getAsString(); + String profileId = profile.get("profile_id").getAsString(); + + SoopyNetworthData networth; + if (jsonObject.getAsJsonObject("data").get(profileId).isJsonNull()) { + networth = new SoopyNetworthData(null); + } else { + networth = new SoopyNetworthData(jsonObject.getAsJsonObject("data").get(profileId).getAsJsonObject()); + } + + soopyNetworth.put(cuteName, networth); + } + + updatingSoopyNetworth.set(false); + callback.run(); + return null; + }); + return null; + } + public long getNetWorth(String profileName) { if (profileName == null) profileName = latestProfile; if (networth.get(profileName) != null) return networth.get(profileName); @@ -726,7 +911,8 @@ public class ProfileViewer { } } } - } catch (IOException ignored) {} + } catch (IOException ignored) { + } int count = 1; if (element.getAsJsonObject().has("count")) { @@ -791,17 +977,15 @@ public class ProfileViewer { lastPlayerInfoState = currentTime; updatingSkyblockProfilesState.set(true); - HashMap<String, String> args = new HashMap<>(); - args.put("uuid", "" + uuid); - manager.hypixelApi.getHypixelApiAsync( - NotEnoughUpdates.INSTANCE.config.apiData.apiKey, - "skyblock/profiles", - args, - jsonObject -> { + manager.apiUtils + .newHypixelApiRequest("skyblock/profiles") + .queryArgument("uuid", "" + uuid) + .requestJson() + .handle((jsonObject, throwable) -> { updatingSkyblockProfilesState.set(false); if (jsonObject != null && jsonObject.has("success") && jsonObject.get("success").getAsBoolean()) { - if (!jsonObject.has("profiles")) return; + if (!jsonObject.has("profiles")) return null; skyblockProfiles = jsonObject.get("profiles").getAsJsonArray(); String lastCuteName = null; @@ -825,8 +1009,12 @@ public class ProfileViewer { } String cuteName = profile.get("cute_name").getAsString(); - if (lastCuteName == null) lastCuteName = cuteName; profileNames.add(cuteName); + if (profile.has("selected") && profile.get("selected").getAsBoolean()) { + lastCuteName = cuteName; + break; + } + if (lastCuteName == null) lastCuteName = cuteName; if (member.has("last_save")) { long lastSave = member.get("last_save").getAsLong(); if (lastSave > lastLastSave) { @@ -840,10 +1028,8 @@ public class ProfileViewer { if (runnable != null) runnable.run(); } - }, - () -> updatingSkyblockProfilesState.set(false) - ); - + return null; + }); return null; } @@ -856,26 +1042,22 @@ public class ProfileViewer { lastGuildInfoState = currentTime; updatingGuildInfoState.set(true); - HashMap<String, String> args = new HashMap<>(); - args.put("player", "" + uuid); - manager.hypixelApi.getHypixelApiAsync( - NotEnoughUpdates.INSTANCE.config.apiData.apiKey, - "guild", - args, - jsonObject -> { + manager.apiUtils + .newHypixelApiRequest("guild") + .queryArgument("player", "" + uuid) + .requestJson() + .handle((jsonObject, ex) -> { updatingGuildInfoState.set(false); if (jsonObject != null && jsonObject.has("success") && jsonObject.get("success").getAsBoolean()) { - if (!jsonObject.has("guild")) return; + if (!jsonObject.has("guild")) return null; guildInformation = jsonObject.get("guild").getAsJsonObject(); if (runnable != null) runnable.run(); } - }, - () -> updatingGuildInfoState.set(false) - ); - + return null; + }); return null; } @@ -973,6 +1155,7 @@ public class ProfileViewer { if (profileInfo == null) return null; if (profileName == null) profileName = latestProfile; + List<JsonObject> coopProfileInfo = getCoopProfileInformation(profileName); if (skyblockInfoCache.containsKey(profileName)) return skyblockInfoCache.get(profileName); JsonObject leveling = Constants.LEVELING; @@ -1002,6 +1185,15 @@ public class ProfileViewer { Utils.getElement(profileInfo, "experience_skill_" + (skillName.equals("social") ? "social2" : skillName)), 0 ); + // Get the coop's social skill experience since social is a shared skill + if (skillName.equals("social")) { + for (JsonObject coopProfile : coopProfileInfo) { + skillExperience += Utils.getElementAsFloat( + Utils.getElement(coopProfile, "experience_skill_social2"), + 0 + ); + } + } totalSkillXP += skillExperience; JsonArray levelingArray = Utils.getElement(leveling, "leveling_xp").getAsJsonArray(); @@ -1013,11 +1205,11 @@ public class ProfileViewer { int maxLevel = getCap(leveling, skillName) + - ( - skillName.equals("farming") - ? Utils.getElementAsInt(Utils.getElement(profileInfo, "jacob2.perks.farming_level_cap"), 0) - : 0 - ); + ( + skillName.equals("farming") + ? Utils.getElementAsInt(Utils.getElement(profileInfo, "jacob2.perks.farming_level_cap"), 0) + : 0 + ); out.put(skillName, getLevel(levelingArray, skillExperience, maxLevel, false)); } @@ -1065,7 +1257,10 @@ public class ProfileViewer { List<String> slayers = Arrays.asList("zombie", "spider", "wolf", "enderman", "blaze"); for (String slayerName : slayers) { - float slayerExperience = Utils.getElementAsFloat(Utils.getElement(profileInfo, "slayer_bosses." + slayerName + ".xp"), 0); + float slayerExperience = Utils.getElementAsFloat(Utils.getElement( + profileInfo, + "slayer_bosses." + slayerName + ".xp" + ), 0); out.put( slayerName, getLevel(Utils.getElement(leveling, "slayer_xp." + slayerName).getAsJsonArray(), slayerExperience, 9, true) @@ -1135,7 +1330,7 @@ public class ProfileViewer { JsonObject inventoryInfo = new JsonObject(); - String[] inv_names = new String[] { + String[] inv_names = new String[]{ "inv_armor", "fishing_bag", "quiver", @@ -1149,7 +1344,7 @@ public class ProfileViewer { "candy_inventory_contents", "equippment_contents", }; - String[] inv_bytes = new String[] { + String[] inv_bytes = new String[]{ inv_armor_bytes, fishing_bag_bytes, quiver_bytes, @@ -1244,7 +1439,8 @@ public class ProfileViewer { JsonObject item = manager.getJsonFromNBTEntry(items.getCompoundTagAt(j)); contents.add(item); } - } catch (IOException ignored) {} + } catch (IOException ignored) { + } } JsonObject bundledReturn = new JsonObject(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryPage.java index efa94ee5..70ea051a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryPage.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryPage.java @@ -71,6 +71,11 @@ public class BestiaryPage extends GuiProfileViewerPage { int yIndex = 0; for (ItemStack stack : BestiaryData.getBestiaryLocations().keySet()) { Minecraft.getMinecraft().getTextureManager().bindTexture(pv_elements); + if (mouseX > guiLeft + 30 + bestiaryXSize * yIndex && mouseX < guiLeft + 30 + bestiaryXSize * yIndex + 20) { + if (mouseY > guiTop + 10 && mouseY < guiTop + 10 + 20) { + tooltipToDisplay = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false); + } + } if (stack == selectedBestiaryLocation) { Utils.drawTexturedRect( guiLeft + 30 + bestiaryXSize * yIndex, @@ -109,10 +114,6 @@ public class BestiaryPage extends GuiProfileViewerPage { Utils.drawTexturedRect(guiLeft, guiTop, 431, 202, GL11.GL_NEAREST); GlStateManager.color(1, 1, 1, 1); - GlStateManager.disableLighting(); - RenderHelper.enableGUIStandardItemLighting(); - - List<String> mobs = BestiaryData.getBestiaryLocations().get(selectedBestiaryLocation); Color color = new Color(128, 128, 128, 255); Utils.renderAlignedString( EnumChatFormatting.RED + "Bestiary Level: ", @@ -121,6 +122,10 @@ public class BestiaryPage extends GuiProfileViewerPage { guiTop + 50, 110 ); + + GlStateManager.disableLighting(); + RenderHelper.enableGUIStandardItemLighting(); + List<String> mobs = BestiaryData.getBestiaryLocations().get(selectedBestiaryLocation); if (mobs != null) { for (int i = 0; i < mobs.size(); i++) { String mob = mobs.get(i); @@ -148,7 +153,7 @@ public class BestiaryPage extends GuiProfileViewerPage { 20 * (1 - completedness) / 256f, GL11.GL_NEAREST ); - GlStateManager.color(1, 185 / 255f, 0, 1); + //GlStateManager.color(1, 185 / 255f, 0, 1); Minecraft.getMinecraft().getTextureManager().bindTexture(pv_elements); Utils.drawTexturedRect( guiLeft + x, @@ -202,7 +207,7 @@ public class BestiaryPage extends GuiProfileViewerPage { if (level.maxed) { progressStr = EnumChatFormatting.GOLD + "MAXED!"; } else { - progressStr =EnumChatFormatting.AQUA + + progressStr = EnumChatFormatting.AQUA + StringUtils.shortNumberFormat(Math.round((levelNum % 1) * level.maxXpForLevel)) + "/" + StringUtils.shortNumberFormat(level.maxXpForLevel); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/trophy/TrophyFishPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/trophy/TrophyFishPage.java index e6c69649..1db53267 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/trophy/TrophyFishPage.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/trophy/TrophyFishPage.java @@ -26,11 +26,6 @@ import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewerPage; import io.github.moulberry.notenoughupdates.util.Utils; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.GlStateManager; @@ -43,6 +38,14 @@ import org.apache.commons.lang3.text.WordUtils; import org.apache.commons.lang3.tuple.Pair; import org.lwjgl.opengl.GL11; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + public class TrophyFishPage extends GuiProfileViewerPage { public static final ResourceLocation pv_elements = new ResourceLocation("notenoughupdates:pv_elements.png"); @@ -119,6 +122,7 @@ public class TrophyFishPage extends GuiProfileViewerPage { } }; private static final ResourceLocation TROPHY_FISH_TEXTURE = new ResourceLocation("notenoughupdates:pv_trophy_fish_tab.png"); + private static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance(Locale.US); private static final String checkX = "§c✖"; private static final String check = "§a✔"; private final Map<String, Integer> total = new HashMap<>(); @@ -339,9 +343,9 @@ public class TrophyFishPage extends GuiProfileViewerPage { private List<String> getTooltip(String name, Map<TrophyFish.TrophyFishRarity, Integer> trophyFishRarityIntegerMap) { List<String> tooltip = new ArrayList<>(); - tooltip.add(internalTrophyFish.get(name.toLowerCase().replace(" ", "_")) + WordUtils.capitalize(name.replace("_", " "))); + tooltip.add(internalTrophyFish.get(name.toLowerCase(Locale.US).replace(" ", "_")) + WordUtils.capitalize(name.replace("_", " "))); - List<String> lore = readLoreFromRepo(name.toUpperCase()); + List<String> lore = readLoreFromRepo(name.toUpperCase(Locale.US)); List<String> description = readDescriptionFromLore(lore); tooltip.addAll(description); tooltip.add(" "); @@ -355,6 +359,11 @@ public class TrophyFishPage extends GuiProfileViewerPage { tooltip.add(display(trophyFishRarityIntegerMap, TrophyFish.TrophyFishRarity.GOLD, EnumChatFormatting.GOLD)); tooltip.add(display(trophyFishRarityIntegerMap, TrophyFish.TrophyFishRarity.SILVER, EnumChatFormatting.GRAY)); tooltip.add(display(trophyFishRarityIntegerMap, TrophyFish.TrophyFishRarity.BRONZE, EnumChatFormatting.DARK_GRAY)); + if (trophyFishList.get(name) != null) { + tooltip.add(" "); + tooltip.add(EnumChatFormatting.GRAY + "Total: " + EnumChatFormatting.GOLD + + NUMBER_FORMAT.format(trophyFishList.get(name).getTotal())); + } return tooltip; } @@ -363,20 +372,20 @@ public class TrophyFishPage extends GuiProfileViewerPage { TrophyFish.TrophyFishRarity rarity, EnumChatFormatting color ) { - String name = WordUtils.capitalize(rarity.name().toLowerCase()); + String name = WordUtils.capitalize(rarity.name().toLowerCase(Locale.US)); if (trophyFishRarityIntegerMap == null) { return color + name + ": " + checkX; } if (trophyFishRarityIntegerMap.containsKey(rarity)) { - return color + name + ": " + EnumChatFormatting.GOLD + trophyFishRarityIntegerMap.get(rarity); + return color + name + ": " + EnumChatFormatting.GOLD + NUMBER_FORMAT.format(trophyFishRarityIntegerMap.get(rarity)); } else { return color + name + ": " + checkX; } } private ItemStack getItem(String name) { - String repoName = name.toUpperCase().replace(" ", "_") + "_BRONZE"; + String repoName = name.toUpperCase(Locale.US).replace(" ", "_") + "_BRONZE"; JsonObject jsonItem = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(repoName); return NotEnoughUpdates.INSTANCE.manager.jsonToStack(jsonItem); } @@ -402,7 +411,7 @@ public class TrophyFishPage extends GuiProfileViewerPage { type = s[2]; } try { - trophyFishRarity = TrophyFish.TrophyFishRarity.valueOf(type.toUpperCase()); + trophyFishRarity = TrophyFish.TrophyFishRarity.valueOf(type.toUpperCase(Locale.US)); } catch (IllegalArgumentException ignored) { total.put(WordUtils.capitalize(key), value); continue; @@ -441,7 +450,7 @@ public class TrophyFishPage extends GuiProfileViewerPage { private List<String> fixStringName(List<String> list) { List<String> fixedList = new ArrayList<>(); for (String s : list) { - fixedList.add(s.toLowerCase().replace(" ", "_")); + fixedList.add(s.toLowerCase(Locale.US).replace(" ", "_")); } return fixedList; } @@ -463,7 +472,7 @@ public class TrophyFishPage extends GuiProfileViewerPage { } private List<String> readLoreFromRepo(String name) { - String repoName = name.toUpperCase().replace(" ", "_") + "_BRONZE"; + String repoName = name.toUpperCase(Locale.US).replace(" ", "_") + "_BRONZE"; JsonObject jsonItem = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(repoName); List<String> list = new ArrayList<>(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/DungeonsWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/DungeonsWeight.java index 39e743aa..9c233554 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/DungeonsWeight.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/DungeonsWeight.java @@ -24,7 +24,7 @@ import java.util.Map; public abstract class DungeonsWeight { - protected static final long CATACOMBS_LEVEL_50_XP = 569809640; + public static final long CATACOMBS_LEVEL_50_XP = 569809640; protected final Map<String, ProfileViewer.Level> player; protected final WeightStruct weightStruct; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SkillsWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SkillsWeight.java index 55669f7b..5c372591 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SkillsWeight.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SkillsWeight.java @@ -24,8 +24,8 @@ import java.util.Map; public abstract class SkillsWeight { - protected static final long SKILLS_LEVEL_50 = 55172425; - protected static final long SKILLS_LEVEL_60 = 111672425; + public static final long SKILLS_LEVEL_50 = 55172425; + public static final long SKILLS_LEVEL_60 = 111672425; protected final Map<String, ProfileViewer.Level> player; protected final WeightStruct weightStruct; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java new file mode 100644 index 00000000..7818c3c0 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.util; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import org.apache.commons.io.IOUtils; +import org.apache.http.NameValuePair; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.message.BasicNameValuePair; + +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.zip.GZIPInputStream; + +public class ApiUtil { + private static final Gson gson = new Gson(); + private static final ExecutorService executorService = Executors.newFixedThreadPool(3); + private static final String USER_AGENT = "NotEnoughUpdates/" + NotEnoughUpdates.VERSION; + private static SSLContext ctx; + + static { + try { + KeyStore letsEncryptStore = KeyStore.getInstance("JKS"); + letsEncryptStore.load(ApiUtil.class.getResourceAsStream("/neukeystore.jks"), "neuneu".toCharArray()); + ctx = SSLContext.getInstance("TLS"); + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + kmf.init(letsEncryptStore, null); + tmf.init(letsEncryptStore); + ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + } catch (KeyStoreException | NoSuchAlgorithmException | KeyManagementException | UnrecoverableKeyException | + IOException | CertificateException e) { + System.out.println("Failed to load NEU keystore. A lot of API requests won't work"); + e.printStackTrace(); + } + } + + public static class Request { + + private final List<NameValuePair> queryArguments = new ArrayList<>(); + private String baseUrl = null; + private boolean shouldGunzip = false; + private String method = "GET"; + private String postData = null; + private String postContentType = null; + + public Request method(String method) { + this.method = method; + return this; + } + + public Request url(String baseUrl) { + this.baseUrl = baseUrl; + return this; + } + + public Request queryArgument(String key, String value) { + queryArguments.add(new BasicNameValuePair(key, value)); + return this; + } + + public Request queryArguments(Collection<NameValuePair> queryArguments) { + this.queryArguments.addAll(queryArguments); + return this; + } + + public Request gunzip() { + shouldGunzip = true; + return this; + } + + public Request postData(String contentType, String data) { + this.postContentType = contentType; + this.postData = data; + return this; + } + + private CompletableFuture<URL> buildUrl() { + CompletableFuture<URL> fut = new CompletableFuture<>(); + try { + fut.complete(new URIBuilder(baseUrl) + .addParameters(queryArguments) + .build() + .toURL()); + } catch (URISyntaxException | + MalformedURLException | + NullPointerException e) { // Using CompletableFuture as an exception monad, isn't that exiting? + fut.completeExceptionally(e); + } + return fut; + } + + public CompletableFuture<String> requestString() { + return buildUrl().thenApplyAsync(url -> { + try { + InputStream inputStream = null; + URLConnection conn = null; + try { + conn = url.openConnection(); + if (conn instanceof HttpsURLConnection && ctx != null) { + HttpsURLConnection sslConn = (HttpsURLConnection) conn; + sslConn.setSSLSocketFactory(ctx.getSocketFactory()); + } + if (conn instanceof HttpURLConnection) { + ((HttpURLConnection) conn).setRequestMethod(method); + } + conn.setConnectTimeout(10000); + conn.setReadTimeout(10000); + conn.setRequestProperty("User-Agent", USER_AGENT); + if (this.postContentType != null) { + conn.setRequestProperty("Content-Type", this.postContentType); + } + if (this.postData != null) { + conn.setDoOutput(true); + OutputStream os = conn.getOutputStream(); + try { + os.write(this.postData.getBytes("utf-8")); + } finally { + os.close(); + } + } + + inputStream = conn.getInputStream(); + + if (shouldGunzip) { + inputStream = new GZIPInputStream(inputStream); + } + + // While the assumption of UTF8 isn't always true; it *should* always be true. + // Not in the sense that this will hold in most cases (although that as well), + // but in the sense that any violation of this better have a good reason. + return IOUtils.toString(inputStream, StandardCharsets.UTF_8); + } finally { + try { + if (inputStream != null) { + inputStream.close(); + } + } finally { + if (conn instanceof HttpURLConnection) { + ((HttpURLConnection) conn).disconnect(); + } + } + } + } catch (IOException e) { + throw new RuntimeException(e); // We can rethrow, since supplyAsync catches exceptions. + } + }, executorService); + } + + public CompletableFuture<JsonObject> requestJson() { + return requestJson(JsonObject.class); + } + + public <T> CompletableFuture<T> requestJson(Class<? extends T> clazz) { + return requestString().thenApply(str -> gson.fromJson(str, clazz)); + } + + } + + public Request request() { + return new Request(); + } + + public Request newHypixelApiRequest(String apiPath) { + return newAnonymousHypixelApiRequest(apiPath) + .queryArgument("key", NotEnoughUpdates.INSTANCE.config.apiData.apiKey); + } + + public Request newAnonymousHypixelApiRequest(String apiPath) { + return new Request() + .url("https://api.hypixel.net/" + apiPath); + } + + public Request newMoulberryRequest(String path) { + return new Request() + .url(getMyApiURL() + path); + } + + private String getMyApiURL() { + return String.format("https://%s/", NotEnoughUpdates.INSTANCE.config.apiData.moulberryCodesApi); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java index 10bfa6a9..221b5023 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java @@ -48,8 +48,8 @@ public class Calculator { int tokenLength; } - static String binops = "+-*/x"; - static String postops = "mkbts"; + static String binops = "+-*/^x"; + static String postops = "mkbts%"; static String digits = "0123456789"; static void readDigitsInto(Token token, String source, boolean decimals) { @@ -101,6 +101,10 @@ public class Calculator { token.tokenLength = 1; token.type = TokenType.BINOP; token.operatorValue = c + ""; + if (c == '*' && i + 1 < source.length() && source.charAt(i + 1) == '*') { + token.tokenLength++; + token.operatorValue = "^"; + } } else if (postops.indexOf(c) != -1) { token.tokenLength = 1; token.type = TokenType.POSTOP; @@ -150,6 +154,8 @@ public class Calculator { case "/": case "x": return 1; + case "^": + return 2; } throw new CalculatorException("Unknown operator " + token.operatorValue, token.tokenStart, token.tokenLength); } @@ -230,6 +236,18 @@ public class Calculator { BigDecimal right = values.pop().setScale(2, RoundingMode.HALF_UP); BigDecimal left = values.pop().setScale(2, RoundingMode.HALF_UP); switch (command.operatorValue.intern()) { + case "^": + if (right.compareTo(new BigDecimal(1000)) >= 0) { + Token rightToken = rpnTokens.get(rpnTokens.indexOf(command) - 1); + throw new CalculatorException(right + " is too large, pick a power less than 1000", rightToken.tokenStart, rightToken.tokenLength); + } + + if (right.doubleValue() != right.intValue()) { + Token rightToken = rpnTokens.get(rpnTokens.indexOf(command) - 1); + throw new CalculatorException(right + " has a decimal, pick a power that is non-decimal", rightToken.tokenStart, rightToken.tokenLength); + } + values.push(left.pow(right.intValue()).setScale(2, RoundingMode.HALF_UP)); + break; case "x": case "*": values.push(left.multiply(right).setScale(2, RoundingMode.HALF_UP)); @@ -280,6 +298,9 @@ public class Calculator { case "t": values.push(p.multiply(new BigDecimal("1000000000000")).setScale(2, RoundingMode.HALF_UP)); break; + case "%": + values.push(p.setScale(3, RoundingMode.HALF_UP).divide(new BigDecimal(100), RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP)); + break; default: throw new CalculatorException( "Unknown operation " + command.operatorValue, diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java index 1d226dc8..ef030367 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java @@ -71,6 +71,7 @@ public class Constants { public static JsonObject REFORGESTONES; public static JsonObject TROPHYFISH; public static JsonObject WEIGHT; + public static JsonObject RNGSCORE; private static final ReentrantLock lock = new ReentrantLock(); @@ -92,6 +93,7 @@ public class Constants { REFORGESTONES = Utils.getConstant("reforgestones", gson); TROPHYFISH = Utils.getConstant("trophyfish", gson); WEIGHT = Utils.getConstant("weight", gson); + RNGSCORE = Utils.getConstant("rngscore", gson); } catch (Exception ex) { ex.printStackTrace(); } finally { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/GuiTextures.java b/src/main/java/io/github/moulberry/notenoughupdates/util/GuiTextures.java index 3ead5a56..062e65e2 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/GuiTextures.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/GuiTextures.java @@ -101,10 +101,6 @@ public class GuiTextures { new ResourceLocation("notenoughupdates:descending_overlay.png"); public static final ResourceLocation BAR = new ResourceLocation("notenoughupdates:core/bar.png"); - public static final ResourceLocation BAR_ONE = new ResourceLocation("notenoughupdates:core/bar_1.png"); - public static final ResourceLocation BAR_TWO = new ResourceLocation("notenoughupdates:core/bar_2.png"); - public static final ResourceLocation BAR_THREE = new ResourceLocation("notenoughupdates:core/bar_3.png"); - public static final ResourceLocation BAR_ON = new ResourceLocation("notenoughupdates:core/bar_on.png"); public static final ResourceLocation OFF = new ResourceLocation("notenoughupdates:core/toggle_off.png"); public static final ResourceLocation ONE = new ResourceLocation("notenoughupdates:core/toggle_1.png"); public static final ResourceLocation TWO = new ResourceLocation("notenoughupdates:core/toggle_2.png"); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java b/src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java index 5d7bfa6d..1968b51e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java @@ -159,13 +159,11 @@ public class HotmInformation { public synchronized void requestUpdate(boolean force) { if (updateTask.isDone() || force) { - updateTask = neu.manager.hypixelApi.getHypixelApiAsync( - neu.config.apiData.apiKey, - "skyblock/profiles", - new HashMap<String, String>() {{ - put("uuid", Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", "")); - }} - ).thenAccept(this::updateInformation); + updateTask = neu.manager.apiUtils + .newHypixelApiRequest("skyblock/profiles") + .queryArgument("uuid", Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", "")) + .requestJson() + .thenAccept(this::updateInformation); } } @@ -195,7 +193,10 @@ public class HotmInformation { Tree tree = new Tree(); JsonObject nodes = miningCore.getAsJsonObject("nodes"); for (Map.Entry<String, JsonElement> node : nodes.entrySet()) { - tree.levels.put(node.getKey(), node.getValue().getAsInt()); + String key = node.getKey(); + if (!key.startsWith("toggle_")) { + tree.levels.put(key, node.getValue().getAsInt()); + } } if (miningCore.has("powder_mithril_total")) { tree.totalMithrilPowder = miningCore.get("powder_mithril_total").getAsInt(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java b/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java deleted file mode 100644 index 3e38fd2e..00000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 2022 NotEnoughUpdates contributors - * - * This file is part of NotEnoughUpdates. - * - * NotEnoughUpdates is free software: you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation, either - * version 3 of the License, or (at your option) any later version. - * - * NotEnoughUpdates 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. - */ - -package io.github.moulberry.notenoughupdates.util; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import io.github.moulberry.notenoughupdates.NotEnoughUpdates; -import org.apache.commons.io.IOUtils; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.ConnectException; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Consumer; -import java.util.zip.GZIPInputStream; - -public class HypixelApi { - private final Gson gson = new Gson(); - private final ExecutorService es = Executors.newFixedThreadPool(3); - - public CompletableFuture<JsonObject> getHypixelApiAsync(String apiKey, String method, HashMap<String, String> args) { - return getApiAsync(generateApiUrl(apiKey, method, args)); - } - - public void getHypixelApiAsync( - String apiKey, - String method, - HashMap<String, String> args, - Consumer<JsonObject> consumer - ) { - getHypixelApiAsync(apiKey, method, args, consumer, () -> { - }); - } - - public void getHypixelApiAsync( - String apiKey, - String method, - HashMap<String, String> args, - Consumer<JsonObject> consumer, - Runnable error - ) { - getApiAsync(generateApiUrl(apiKey, method, args), consumer, error); - } - - private String getMyApiURL() { - return String.format("https://%s/", NotEnoughUpdates.INSTANCE.config.apiData.moulberryCodesApi); - } - - public CompletableFuture<JsonObject> getApiAsync(String urlS) { - CompletableFuture<JsonObject> result = new CompletableFuture<>(); - es.submit(() -> { - try { - result.complete(getApiSync(urlS)); - } catch (Exception e) { - result.completeExceptionally(e); - } - }); - return result; - } - - public void getApiAsync(String urlS, Consumer<JsonObject> consumer, Runnable error) { - es.submit(() -> { - try { - consumer.accept(getApiSync(urlS)); - } catch (Exception e) { - error.run(); - } - }); - } - - public void getMyApiAsync(String urlS, Consumer<JsonObject> consumer, Runnable error) { - es.submit(() -> { - try { - consumer.accept(getApiSync(getMyApiURL() + urlS)); - } catch (Exception e) { - if (NotEnoughUpdates.INSTANCE.config.hidden.dev) { - e.printStackTrace(); - } - error.run(); - } - }); - } - - public void getMyApiGZIPAsync(String urlS, Consumer<JsonObject> consumer, Runnable error) { - es.submit(() -> { - try { - consumer.accept(getApiGZIPSync(getMyApiURL() + urlS)); - } catch (Exception e) { - error.run(); - } - }); - } - - public void getApiGZIPAsync(String urlS, Consumer<JsonObject> consumer, Runnable error) { - es.submit(() -> { - try { - consumer.accept(getApiGZIPSync(urlS)); - } catch (Exception e) { - error.run(); - } - }); - } - - public JsonObject getApiSync(String urlS) throws IOException { - URL url = new URL(urlS); - URLConnection connection = url.openConnection(); - connection.setConnectTimeout(10000); - connection.setReadTimeout(10000); - - String response = IOUtils.toString(connection.getInputStream(), StandardCharsets.UTF_8); - - JsonObject json = gson.fromJson(response, JsonObject.class); - if (json == null) throw new ConnectException("Invalid JSON"); - return json; - } - - public JsonObject getApiGZIPSync(String urlS) throws IOException { - URL url = new URL(urlS); - URLConnection connection = url.openConnection(); - connection.setConnectTimeout(10000); - connection.setReadTimeout(10000); - - String response = IOUtils.toString(new GZIPInputStream(connection.getInputStream()), StandardCharsets.UTF_8); - - JsonObject json = gson.fromJson(response, JsonObject.class); - return json; - } - - public String generateApiUrl(String apiKey, String method, HashMap<String, String> args) { - if (apiKey != null) - args.put("key", apiKey.trim()); - StringBuilder url = new StringBuilder("https://api.hypixel.net/" + method); - boolean first = true; - for (Map.Entry<String, String> entry : args.entrySet()) { - if (first) { - url.append("?"); - first = false; - } else { - url.append("&"); - } - try { - url.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8.name())).append("=") - .append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8.name())); - } catch (UnsupportedEncodingException e) { - } - } - return url.toString(); - } -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java index 48eb6fad..3692602a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java @@ -19,10 +19,11 @@ package io.github.moulberry.notenoughupdates.util; -import com.google.common.collect.Iterables; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import io.github.moulberry.notenoughupdates.NEUManager; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.util.StringUtils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.inventory.GuiChest; @@ -37,6 +38,7 @@ import javax.annotation.Nullable; import java.util.Arrays; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -136,6 +138,13 @@ public class ItemResolutionQuery { return manager.jsonToStack(jsonObject); } + @Nullable + public ItemStack resolveToItemStack(boolean useReplacements) { + JsonObject jsonObject = resolveToItemListJson(); + if (jsonObject == null) return null; + return manager.jsonToStack(jsonObject, false, useReplacements); + } + // <editor-fold desc="Resolution Helpers"> private boolean isBazaar(IInventory chest) { if (chest.getDisplayName().getFormattedText().startsWith("Bazaar ➜ ")) { @@ -170,6 +179,40 @@ public class ItemResolutionQuery { } return null; } + if (guiName.equals("Catacombs RNG Meter")) { + return resolveItemInCatacombsRngMeter(); + } + return null; + } + + private String resolveItemInCatacombsRngMeter() { + List<String> lore = ItemUtils.getLore(compound); + if (lore.size() > 16) { + String s = lore.get(15); + if (s.equals("§7Selected Drop")) { + String displayName = lore.get(16); + return getInternalNameByDisplayName(displayName); + } + } + + return null; + } + + private String getInternalNameByDisplayName(String displayName) { + String cleanDisplayName = StringUtils.cleanColour(displayName); + for (Map.Entry<String, JsonObject> entry : NotEnoughUpdates.INSTANCE.manager + .getItemInformation() + .entrySet()) { + + JsonObject object = entry.getValue(); + if (object.has("displayname")) { + String name = object.get("displayname").getAsString(); + if (StringUtils.cleanColour(name).equals(cleanDisplayName)) { + return entry.getKey(); + } + } + } + return null; } @@ -231,7 +274,7 @@ public class ItemResolutionQuery { private String resolveFromSkyblock() { String internalName = getExtraAttributes().getString("id"); if (internalName == null || internalName.isEmpty()) return null; - return internalName.toUpperCase(Locale.ROOT); + return internalName.toUpperCase(Locale.ROOT).replace(':', '-'); } // </editor-fold> diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java index cffdd164..6187495c 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java @@ -19,16 +19,32 @@ package io.github.moulberry.notenoughupdates.util; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.listener.ItemTooltipListener; +import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay; +import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.JsonToNBT; +import net.minecraft.nbt.NBTException; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagString; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.MathHelper; +import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.Map; +import java.util.function.BiFunction; public class ItemUtils { @@ -57,6 +73,21 @@ public class ItemUtils { return skull; } + public static ItemStack createQuestionMarkSkull(String label) { + return Utils.createSkull( + label, + "00000000-0000-0000-0000-000000000000", + "bc8ea1f51f253ff5142ca11ae45193a4ad8c3ab5e9c6eec8ba7a4fcb7bac40" + ); + } + + public static NBTTagCompound getOrCreateTag(ItemStack is) { + if (is.hasTagCompound()) return is.getTagCompound(); + NBTTagCompound nbtTagCompound = new NBTTagCompound(); + is.setTagCompound(nbtTagCompound); + return nbtTagCompound; + } + public static void appendLore(ItemStack is, List<String> moreLore) { NBTTagCompound tagCompound = is.getTagCompound(); if (tagCompound == null) { @@ -96,4 +127,278 @@ public class ItemUtils { return string; } + public static String fixEnchantId(String enchId, boolean useId) { + if (Constants.ENCHANTS != null && Constants.ENCHANTS.has("enchant_mapping_id") && + Constants.ENCHANTS.has("enchant_mapping_item")) { + JsonArray mappingFrom = Constants.ENCHANTS.getAsJsonArray("enchant_mapping_" + (useId ? "id" : "item")); + JsonArray mappingTo = Constants.ENCHANTS.getAsJsonArray("enchant_mapping_" + (useId ? "item" : "id")); + + for (int i = 0; i < mappingFrom.size(); i++) { + if (mappingFrom.get(i).getAsString().equals(enchId)) { + return mappingTo.get(i).getAsString(); + } + } + + } + return enchId; + } + + /** + * Mutates baseValues + */ + public static <T> void modifyReplacement( + Map<String, String> baseValues, + Map<String, T> modifiers, + BiFunction<String, T, String> mapper + ) { + if (modifiers == null || baseValues == null) return; + for (Map.Entry<String, T> modifier : modifiers.entrySet()) { + String baseValue = baseValues.get(modifier.getKey()); + if (baseValue == null) continue; + try { + baseValues.put(modifier.getKey(), mapper.apply(baseValue, modifier.getValue())); + } catch (Exception e) { + System.out.println("Exception during replacement mapping: "); + e.printStackTrace(); + } + } + } + + public static String applyReplacements(Map<String, String> replacements, String text) { + for (Map.Entry<String, String> replacement : replacements.entrySet()) { + String search = "{" + replacement.getKey() + "}"; + text = text.replace(search, replacement.getValue()); + } + return text; + } + + public static ItemStack createPetItemstackFromPetInfo(PetInfoOverlay.Pet currentPet) { + String petname = currentPet.petType; + String tier = Utils.getRarityFromInt(currentPet.rarity.petId).toUpperCase(); + String heldItem = currentPet.petItem; + String skin = currentPet.skin; + JsonObject heldItemJson = heldItem == null ? null : NotEnoughUpdates.INSTANCE.manager.getItemInformation().get( + heldItem); + String petId = currentPet.getPetId(false); + float exp = currentPet.petLevel.totalXp; + + GuiProfileViewer.PetLevel levelObj = GuiProfileViewer.getPetLevel(petname, tier, exp); + + float level = levelObj.level; + + ItemStack petItemstack = NotEnoughUpdates.INSTANCE.manager + .createItemResolutionQuery() + .withKnownInternalName(petId) + .resolveToItemStack(false); + if (petItemstack == null) { + petItemstack = ItemUtils.createQuestionMarkSkull(EnumChatFormatting.RED + "Unknown Pet"); + appendLore(petItemstack, Arrays.asList( + "§cThis pet is not saved in the repository", + "", + "§cIf you expected it to be there please send a message in", + "§c§l#neu-support §r§con §ldiscord.gg/moulberry" + )); + } + Map<String, String> replacements = NotEnoughUpdates.INSTANCE.manager.getPetLoreReplacements( + petname, + tier, + MathHelper.floor_float(level) + ); + + if (heldItem != null) { + modifyReplacement(replacements, GuiProfileViewer.PET_STAT_BOOSTS.get(heldItem), (original, modifier) -> + "" + MathHelper.floor_float(Float.parseFloat(original) + modifier)); + modifyReplacement(replacements, GuiProfileViewer.PET_STAT_BOOSTS_MULT.get(heldItem), (original, modifier) -> + "" + MathHelper.floor_float(Float.parseFloat(original) * modifier)); + } + + NBTTagCompound tag = getOrCreateTag(petItemstack); + if (tag.hasKey("display", 10)) { + NBTTagCompound displayTag = tag.getCompoundTag("display"); + if (displayTag.hasKey("Lore", 9)) { + List<String> newLore = new ArrayList<>(); + NBTTagList lore = displayTag.getTagList("Lore", 8); + int secondLastBlankLine = -1, lastBlankLine = -1; + for (int j = 0; j < lore.tagCount(); j++) { + String line = lore.getStringTagAt(j); + if (line.trim().isEmpty()) { + secondLastBlankLine = lastBlankLine; + lastBlankLine = j; + } + line = applyReplacements(replacements, line); + newLore.add(line); + } + if (skin != null) { + JsonObject petSkin = NotEnoughUpdates.INSTANCE.manager + .createItemResolutionQuery() + .withKnownInternalName("PET_SKIN_" + skin) + .resolveToItemListJson(); + if (petSkin != null) { + try { + NBTTagCompound nbt = JsonToNBT.getTagFromJson(petSkin.get("nbttag").getAsString()); + tag.setTag("SkullOwner", nbt.getTag("SkullOwner")); + String name = petSkin.get("displayname").getAsString(); + if (name != null) { + name = Utils.cleanColour(name); + newLore.set(0, newLore.get(0) + ", " + name); + } + } catch (NBTException e) { + e.printStackTrace(); + } + } + } + for (int i = 0; i < newLore.size(); i++) { + String cleaned = Utils.cleanColour(newLore.get(i)); + if (cleaned.equals("Right-click to add this pet to")) { + if (heldItem == null) newLore.remove(i + 2); + newLore.remove(i + 1); + newLore.remove(i); + secondLastBlankLine = i - 1; + break; + } + } + if (secondLastBlankLine != -1) { + List<String> petItemLore = new ArrayList<>(); + if (heldItem != null) { + petItemLore.add(EnumChatFormatting.GOLD + "Held Item: " + heldItemJson.get("displayname").getAsString()); + List<String> heldItemLore = JsonUtils.getJsonArrayOrEmpty(heldItemJson, "lore", JsonElement::getAsString); + int blanks = 0; + for (String heldItemLoreLine : heldItemLore) { + if (heldItemLoreLine.trim().isEmpty()) { + blanks++; + } else if (blanks == 2) { + petItemLore.add(heldItemLoreLine); + } else if (blanks > 2) { + break; + } + } + } + if (currentPet.candyUsed > 0) { + if (petItemLore.size() > 0) { + petItemLore.add(""); + } + petItemLore.add("§a(" + currentPet.candyUsed + "/10) Pet Candy Used"); + if (heldItem == null) petItemLore.add(""); + } + newLore.addAll(secondLastBlankLine + 1, petItemLore); + } + NBTTagList temp = new NBTTagList(); + for (String loreLine : newLore) { + temp.appendTag(new NBTTagString(loreLine)); + } + displayTag.setTag("Lore", temp); + } + + if (displayTag.hasKey("Name", 8)) { + String displayName = displayTag.getString("Name"); + displayName = applyReplacements(replacements, displayName); + displayTag.setTag("Name", new NBTTagString(displayName)); + } + tag.setTag("display", displayTag); + } + + // Adds the missing pet fields to the tag + NBTTagCompound extraAttributes = new NBTTagCompound(); + JsonObject petInfo = new JsonObject(); + if (tag.hasKey("ExtraAttributes", 10)) { + extraAttributes = tag.getCompoundTag("ExtraAttributes"); + if (extraAttributes.hasKey("petInfo", 8)) { + petInfo = new JsonParser().parse(extraAttributes.getString("petInfo")).getAsJsonObject(); + } + } + petInfo.addProperty("exp", exp); + petInfo.addProperty("tier", tier); + petInfo.addProperty("type", petname); + if (heldItem != null) { + petInfo.addProperty("heldItem", heldItem); + } + if (skin != null) { + petInfo.addProperty("skin", skin); + } + extraAttributes.setString("petInfo", petInfo.toString()); + tag.setTag("ExtraAttributes", extraAttributes); + petItemstack.setTagCompound(tag); + return petItemstack; + } + + private static final DecimalFormat decimalFormatter = new DecimalFormat("#,###,###.###"); + + public static ItemStack petToolTipXPExtendPetOverlay(ItemStack stack) { + NBTTagCompound tag = stack.getTagCompound() == null ? new NBTTagCompound() : stack.getTagCompound(); + if (tag.hasKey("display", 10)) { + NBTTagCompound display = tag.getCompoundTag("display"); + if (display.hasKey("Lore", 9)) { + NBTTagList lore = display.getTagList("Lore", 8); + if (Utils.cleanColour(lore.getStringTagAt(0)).matches(ItemTooltipListener.petToolTipRegex) && + lore.tagCount() > 7) { + + GuiProfileViewer.PetLevel petLevel; + + PetInfoOverlay.Pet pet = PetInfoOverlay.getPetFromStack( + stack.getTagCompound() + ); + if (pet == null) return stack; + petLevel = pet.petLevel; + if (petLevel == null) return stack; + + NBTTagList newLore = new NBTTagList(); + int maxLvl = 100; + if (Constants.PETS != null && Constants.PETS.has("custom_pet_leveling") && + Constants.PETS.getAsJsonObject("custom_pet_leveling").has(pet.petType.toUpperCase()) && + Constants.PETS.getAsJsonObject("custom_pet_leveling").getAsJsonObject(pet.petType.toUpperCase()).has( + "max_level")) { + maxLvl = + Constants.PETS + .getAsJsonObject("custom_pet_leveling") + .getAsJsonObject(pet.petType.toUpperCase()) + .get("max_level") + .getAsInt(); + } + for (int i = 0; i < lore.tagCount(); i++) { + if (i == lore.tagCount() - 2) { + newLore.appendTag(new NBTTagString("")); + if (petLevel.level >= maxLvl) { + newLore.appendTag(new NBTTagString( + EnumChatFormatting.AQUA + "" + EnumChatFormatting.BOLD + "MAX LEVEL")); + } else { + double levelPercent = (Math.round(petLevel.levelPercentage * 1000) / 10.0); + newLore.appendTag(new NBTTagString( + EnumChatFormatting.GRAY + "Progress to Level " + (int) (petLevel.level + 1) + ": " + + EnumChatFormatting.YELLOW + levelPercent + "%")); + StringBuilder sb = new StringBuilder(); + + for (int j = 0; j < 20; j++) { + if (j < (levelPercent / 5)) { + sb.append(EnumChatFormatting.DARK_GREEN); + } else { + sb.append(EnumChatFormatting.WHITE); + } + sb.append(EnumChatFormatting.BOLD + "" + EnumChatFormatting.STRIKETHROUGH + " "); + } + newLore.appendTag(new NBTTagString(sb.toString())); + newLore.appendTag(new NBTTagString( + EnumChatFormatting.GRAY + "EXP: " + EnumChatFormatting.YELLOW + + decimalFormatter.format(petLevel.levelXp) + + EnumChatFormatting.GOLD + "/" + EnumChatFormatting.YELLOW + + decimalFormatter.format(petLevel.currentLevelRequirement) + )); + } + } + newLore.appendTag(lore.get(i)); + } + display.setTag("Lore", newLore); + tag.setTag("display", display); + } + } + } + stack.setTagCompound(tag); + return stack; + } + + public static boolean isSoulbound(ItemStack item) { + return ItemUtils.getLore(item).stream() + .anyMatch(line -> line.equals("§8§l* §8Co-op Soulbound §8§l*") || + line.equals("§8§l* Soulbound §8§l*")); + } + } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/MoulSigner.java b/src/main/java/io/github/moulberry/notenoughupdates/util/MoulSigner.java new file mode 100644 index 00000000..6510bc20 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/MoulSigner.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.util; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import org.apache.commons.io.IOUtils; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.Signature; +import java.security.SignatureException; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +public class MoulSigner { + private MoulSigner() {} + + static PublicKey publicKey; + + static { + try (InputStream is = MoulSigner.class.getResourceAsStream("/moulberry.key")) { + byte[] publicKeyBytes = IOUtils.toByteArray(is); + X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKeyBytes); + publicKey = KeyFactory.getInstance("RSA").generatePublic(x509EncodedKeySpec); + } catch (IOException | NullPointerException | NoSuchAlgorithmException | InvalidKeySpecException e) { + NotEnoughUpdates.LOGGER.error("Cannot initialize MoulSigner", e); + } + } + + public static boolean verifySignature(byte[] data, byte[] signatureBytes) { + if (Boolean.getBoolean("neu.noverifysignature")) return true; + if (publicKey == null) { + NotEnoughUpdates.LOGGER.warn("MoulSigner could not be initialized, will fail this request"); + return false; + } + try { + Signature signature = Signature.getInstance("SHA256withRSA"); + signature.initVerify(publicKey); + signature.update(data); + return signature.verify(signatureBytes); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { + NotEnoughUpdates.LOGGER.error("Error while verifying signature. Considering this as invalid signature", e); + return false; + } + } + + public static boolean verifySignature(File file) { + try { + return verifySignature( + IOUtils.toByteArray(file.toURI()), + IOUtils.toByteArray(new File(file.getParentFile(), file.getName() + ".asc").toURI()) + ); + } catch (IOException e) { + NotEnoughUpdates.LOGGER.error("Ran into an IOException while verifying a signature", e); + return false; + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/PronounDB.java b/src/main/java/io/github/moulberry/notenoughupdates/util/PronounDB.java index e7286721..4c0b73eb 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/PronounDB.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/PronounDB.java @@ -21,50 +21,17 @@ package io.github.moulberry.notenoughupdates.util; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; -import io.github.moulberry.notenoughupdates.core.util.StringUtils; - -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManagerFactory; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URL; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; + import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.UUID; +import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; public class PronounDB { - static SSLContext ctx; - - static { - try { - KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(PronounDB.class.getResourceAsStream("/pronoundb.jks"), "pronoundb".toCharArray()); - ctx = SSLContext.getInstance("TLS"); - KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - kmf.init(ks, null); - tmf.init(ks); - ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); - } catch (KeyStoreException | NoSuchAlgorithmException | KeyManagementException | UnrecoverableKeyException | - IOException | CertificateException e) { - System.out.println("Failed to load keystore. PronounDB requests will probably not work"); - e.printStackTrace(); - } - } - private static boolean isDisabled() { JsonObject disabled = Constants.DISABLE; return disabled != null && disabled.has("pronoundb"); @@ -73,29 +40,22 @@ public class PronounDB { /** * Returns an Optional, since JVMs can be *very* funky with KeyStore loading */ - public static Optional<JsonObject> performPronouning(String platform, String id) { - if (isDisabled()) return Optional.empty(); - try { - URL url = new URL("https://pronoundb.org/api/v1/lookup" + - "?platform=" + StringUtils.urlEncode(platform) + - "&id=" + StringUtils.urlEncode(id)); - HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); - urlConnection.setSSLSocketFactory(ctx.getSocketFactory()); - return Optional.of(NotEnoughUpdates.INSTANCE.manager.gson.fromJson( - new InputStreamReader(urlConnection.getInputStream()), - JsonObject.class - )); - } catch (ClassCastException | IOException | JsonParseException e) { - System.out.println("Failed to contact PronounDB: " + e); - return Optional.empty(); - } + public static CompletableFuture<Optional<JsonObject>> performPronouning(String platform, String id) { + if (isDisabled()) return CompletableFuture.completedFuture(Optional.empty()); + return NotEnoughUpdates.INSTANCE.manager.apiUtils + .request() + .url("https://pronoundb.org/api/v1/lookup") + .queryArgument("platform", platform) + .queryArgument("id", id) + .requestJson() + .handle((result, ex) -> Optional.ofNullable(result)); } public enum Pronoun { HE("he", "him", "his"), IT("it", "it", "its"), SHE("she", "her", "hers"), - THEY("they", "they", "theirs"); + THEY("they", "them", "theirs"); private final String subject; private final String object; @@ -199,23 +159,20 @@ public class PronounDB { return Optional.empty(); } - public static Optional<PronounChoice> getPronounsFor(String platform, String name) { - return performPronouning(platform, name).flatMap(PronounDB::parsePronouns); + public static CompletableFuture<Optional<PronounChoice>> getPronounsFor(String platform, String name) { + return performPronouning(platform, name).thenApply(it -> it.flatMap(PronounDB::parsePronouns)); } - public static Optional<PronounChoice> getPronounsFor(UUID minecraftPlayer) { - return performPronouning("minecraft", minecraftPlayer.toString() /* dashed UUID */) - .flatMap(PronounDB::parsePronouns); + public static CompletableFuture<Optional<PronounChoice>> getPronounsFor(UUID minecraftPlayer) { + return getPronounsFor("minecraft", minecraftPlayer.toString() /* dashed UUID */); } public static void test() { - try { - System.out.println("Pronouning..."); - PronounChoice pronounsFor = getPronounsFor(UUID.fromString("842204e6-6880-487b-ae5a-0595394f9948")).get(); + System.out.println("Pronouning..."); + getPronounsFor(UUID.fromString("842204e6-6880-487b-ae5a-0595394f9948")).thenAccept(it -> { + PronounChoice pronounsFor = it.get(); pronounsFor.render().forEach(System.out::println); - } catch (Exception e) { - e.printStackTrace(); - } + }); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java index 35c836b5..b5e6c391 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java @@ -24,6 +24,7 @@ import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.listener.ScoreboardLocationChangeListener; import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent; +import io.github.moulberry.notenoughupdates.overlays.OverlayManager; import io.github.moulberry.notenoughupdates.overlays.SlayerOverlay; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.inventory.GuiChest; @@ -61,8 +62,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -290,6 +289,8 @@ public class SBInfo { private static final String profilePrefix = "\u00a7r\u00a7e\u00a7lProfile: \u00a7r\u00a7a"; private static final String skillsPrefix = "\u00a7r\u00a7e\u00a7lSkills: \u00a7r\u00a7a"; + private static final String completedFactionQuests = "\u00a7r \u00a7r\u00a7a"; + public ArrayList<String> completedQuests = new ArrayList<>(); private static final Pattern SKILL_LEVEL_PATTERN = Pattern.compile("([^0-9:]+) (\\d{1,2})"); @@ -306,15 +307,21 @@ public class SBInfo { lastLocRaw = System.currentTimeMillis(); NotEnoughUpdates.INSTANCE.sendChatMessage("/locraw"); } - if (currentTime - lastMayorUpdate > 300 * 1000) { - updateMayor(); - lastMayorUpdate = currentTime; - } + if (currentTime - lastMayorUpdate > 300 * 1000) { + updateMayor(); + lastMayorUpdate = currentTime; + } try { for (NetworkPlayerInfo info : Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap()) { String name = Minecraft.getMinecraft().ingameGUI.getTabList().getPlayerName(info); if (name.startsWith(profilePrefix)) { - currentProfile = Utils.cleanColour(name.substring(profilePrefix.length())); + String newProfile = Utils.cleanColour(name.substring(profilePrefix.length())); + if (!Objects.equals(currentProfile, newProfile)) { + currentProfile = newProfile; + if (NotEnoughUpdates.INSTANCE.config != null) + if (NotEnoughUpdates.INSTANCE.config.mining.powderGrindingTrackerResetMode == 2) + OverlayManager.powderGrindingOverlay.load(); + } hasNewTab = true; } else if (name.startsWith(skillsPrefix)) { String levelInfo = name.substring(skillsPrefix.length()).trim(); @@ -326,6 +333,12 @@ public class SBInfo { } catch (Exception ignored) { } } + } else if (name.startsWith(completedFactionQuests)) { + if (completedQuests.isEmpty()) { + completedQuests.add(name); + } else if (!completedQuests.contains(name)) { + completedQuests.add(name); + } } } } catch (Exception e) { @@ -435,11 +448,10 @@ public class SBInfo { } public void updateMayor() { - NotEnoughUpdates.INSTANCE.manager.hypixelApi.getHypixelApiAsync( - NotEnoughUpdates.INSTANCE.config.apiData.apiKey, - "resources/skyblock/election", - new HashMap<>() - ).thenAcceptAsync(newJson -> mayorJson = newJson); + NotEnoughUpdates.INSTANCE.manager.apiUtils + .newHypixelApiRequest("resources/skyblock/election") + .requestJson() + .thenAccept(newJson -> mayorJson = newJson); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java index 2267cbea..1ee24ec8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java @@ -57,6 +57,7 @@ import net.minecraft.network.play.client.C0DPacketCloseWindow; import net.minecraft.util.ChatComponentText; import net.minecraft.util.ChatStyle; import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IChatComponent; import net.minecraft.util.Matrix4f; import net.minecraft.util.ResourceLocation; import net.minecraft.util.StatCollector; @@ -1999,4 +2000,20 @@ public class Utils { public static String getLastOpenChestName() { return SBInfo.getInstance().lastOpenChestName; } + + public static String getNameFromChatComponent(IChatComponent chatComponent) { + String unformattedText = cleanColour(chatComponent.getSiblings().get(0).getUnformattedText()); + String username = unformattedText.substring(unformattedText.indexOf(">") + 2, unformattedText.indexOf(":")); + // If the first character is a square bracket the user has a rank + // So we get the username from the space after the closing square bracket (end of their rank) + if (username.charAt(0) == '[') { + username = username.substring(unformattedText.indexOf(" ") + 2); + } + // If we still get any square brackets it means the user was talking in guild chat with a guild rank + // So we get the username up to the space before the guild rank + if (username.contains("[") || username.contains("]")) { + username = username.substring(0, unformattedText.indexOf(" ")); + } + return username; + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/XPInformation.java b/src/main/java/io/github/moulberry/notenoughupdates/util/XPInformation.java index 58794e07..81eea343 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/XPInformation.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/XPInformation.java @@ -187,6 +187,7 @@ public class XPInformation { skillInfo.currentXp += updateWithPercentage.get(skill) / 100f * cap; skillInfo.totalXp += skillInfo.currentXp; skillInfo.currentXpMax = cap; + break; } else { skillInfo.totalXp += cap; } diff --git a/src/main/resources/assets/notenoughupdates/core/bar_1.png b/src/main/resources/assets/notenoughupdates/core/bar_1.png Binary files differdeleted file mode 100644 index 664c0f32..00000000 --- a/src/main/resources/assets/notenoughupdates/core/bar_1.png +++ /dev/null diff --git a/src/main/resources/assets/notenoughupdates/core/bar_2.png b/src/main/resources/assets/notenoughupdates/core/bar_2.png Binary files differdeleted file mode 100644 index 664c0f32..00000000 --- a/src/main/resources/assets/notenoughupdates/core/bar_2.png +++ /dev/null diff --git a/src/main/resources/assets/notenoughupdates/core/bar_3.png b/src/main/resources/assets/notenoughupdates/core/bar_3.png Binary files differdeleted file mode 100644 index 664c0f32..00000000 --- a/src/main/resources/assets/notenoughupdates/core/bar_3.png +++ /dev/null diff --git a/src/main/resources/assets/notenoughupdates/core/bar_on.png b/src/main/resources/assets/notenoughupdates/core/bar_on.png Binary files differdeleted file mode 100644 index 664c0f32..00000000 --- a/src/main/resources/assets/notenoughupdates/core/bar_on.png +++ /dev/null diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index 70f63a48..55b5f9c6 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -2,7 +2,7 @@ { "modid": "notenoughupdates", "name": "NotEnoughUpdates", - "description": "Mod that shows recipes and useful info for Hypixel's Skyblock gamemode.", + "description": "Mod that shows recipes and useful info for Hypixel's SkyBlock gamemode.", "version": "${version}", "mcversion": "${mcversion}", "url": "https://github.com/NotEnoughUpdates/NotEnoughUpdates/", diff --git a/src/main/resources/mixins.notenoughupdates.json b/src/main/resources/mixins.notenoughupdates.json index 0a547b4b..53595874 100644 --- a/src/main/resources/mixins.notenoughupdates.json +++ b/src/main/resources/mixins.notenoughupdates.json @@ -40,7 +40,6 @@ "MixinRenderGlobal", "MixinRenderItem", "MixinRenderList", - "MixinSkyclientCosmetics", "MixinTextureManager", "MixinTileEntitySkullRenderer", "MixinTileEntitySpecialRenderer", @@ -52,6 +51,7 @@ "AccessorGuiContainer", "AccessorGuiEditSign", "AccessorMinecraft", - "MixinGuiEditSign" + "MixinGuiEditSign", + "MixinGuiTextField" ] } diff --git a/src/main/resources/moulberry.key b/src/main/resources/moulberry.key Binary files differnew file mode 100644 index 00000000..5a7a3307 --- /dev/null +++ b/src/main/resources/moulberry.key diff --git a/src/main/resources/neukeystore.jks b/src/main/resources/neukeystore.jks Binary files differnew file mode 100644 index 00000000..3a5a23b6 --- /dev/null +++ b/src/main/resources/neukeystore.jks diff --git a/src/main/resources/neukeystore.txt b/src/main/resources/neukeystore.txt new file mode 100644 index 00000000..5616f69b --- /dev/null +++ b/src/main/resources/neukeystore.txt @@ -0,0 +1,17 @@ +neukeystore.jks +=============== + +This file should only ever be handled by a `keytool` binary from jdk 1.8u51 or below, as to be compatible with old java versions. + +The password to the keystore is `neuneu` and it contains every certificate from jdk 1.8u51 and the Let's Encrypt root CAs. + +Example for adding a new certificate: + + ~/.jdks/jdk1.8.0_51/bin/keytool -keystore neukeystore.jks -storepass neuneu -alias ISRGROOTX1 -import -file isrgrootx1.der + +Please keep a list of added aliases below: + + - ISRGROOTX1 (Let's Encrypt) + - ISRGROOTX2 (Let's Encrypt) + + diff --git a/src/main/resources/pronoundb.jks b/src/main/resources/pronoundb.jks Binary files differdeleted file mode 100644 index 1c279333..00000000 --- a/src/main/resources/pronoundb.jks +++ /dev/null |