aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornea <nea@nea.moe>2023-02-05 22:55:27 +0100
committernea <nea@nea.moe>2023-02-05 22:55:27 +0100
commitea0d8c2c85e29f84ac59b86e20b6a7546db63dd8 (patch)
tree77c9bf3653aa0362170d2b10c4acaf6346d46ef4
parenta321287e85fb577745647d12049fc1d24997717c (diff)
parentd0f024a0cd2525bc4a79308c4f7275ea2a308ab2 (diff)
downloadNotEnoughUpdates-ea0d8c2c85e29f84ac59b86e20b6a7546db63dd8.tar.gz
NotEnoughUpdates-ea0d8c2c85e29f84ac59b86e20b6a7546db63dd8.tar.bz2
NotEnoughUpdates-ea0d8c2c85e29f84ac59b86e20b6a7546db63dd8.zip
Merge remote-tracking branch 'origin/master' into museumthing
-rw-r--r--.idea/copyright/NotEnoughUpdates.xml2
-rw-r--r--Update Notes/2.1.1.md1
-rw-r--r--annotations/build.gradle.kts44
-rw-r--r--annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSubscribe.kt24
-rw-r--r--annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessor.kt165
-rw-r--r--annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessorProvider.kt30
-rw-r--r--annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUEventSubscriber.kt34
-rw-r--r--annotations/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider20
-rw-r--r--build.gradle.kts70
-rw-r--r--buildSrc/src/main/kotlin/neubs/buildflags.kt23
-rw-r--r--gradle.properties3
-rw-r--r--oneconfigquarantine/build.gradle.kts9
-rw-r--r--settings.gradle.kts1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java20
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java94
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java19
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java36
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/help/SettingsCommand.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/BackgroundBlur.java10
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditor.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java6
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/GuiOptionEditorBlocked.java75
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java15
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/events/ReplaceItemEvent.java8
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/hooks/ThreadDownloadImageHook.java17
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java7
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/OldAnimationChecker.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/loader/KotlinLoadingTweaker.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AbiphoneContactHelper.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AbiphoneFavourites.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AbiphoneWarning.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AntiCoopAdd.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionBINWarning.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionProfit.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/BetterContainers.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DungeonNpcProfitOverlay.java6
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesWaypoints.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnchantingSolvers.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FishingHelper.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCustomizeManager.java21
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/MiningStuff.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NullzeeSphere.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java17
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PowerStoneStatsDisplay.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SlotLocking.java33
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SunTzu.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WardrobeMouseButtons.kt19
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WitherCloakChanger.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/CustomBiomes.java3
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/DwarvenMinesTextures.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/item/enchants/EnchantStyleCustomizer.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/world/EnderNodeHighlighter.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/world/FrozenTreasuresHighlighter.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/world/GlowingMushroomHighlighter.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/InventoryStorageSelector.java3
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/SignCalculator.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/StorageOverlay.java7
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/MinionHelperManager.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperChatLoader.java3
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlay.java70
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperPriceCalculation.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiUtils.java71
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinInventoryPlayer.java24
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinLayerDeadmau5Head.java38
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinThreadDownloadImageData.java17
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Mining.java23
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java8
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/StorageGUI.java22
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/TooltipTweaks.java11
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/overlays/EquipmentOverlay.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/overlays/FuelBar.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java121
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/overlays/PowderGrindingOverlay.java45
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java253
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CollectionsPage.java379
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CrimsonIslePage.java31
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java339
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java23
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java123
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java438
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryPage.java36
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/LevelPage.java229
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/CoreTaskLevel.java163
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/DungeonTaskLevel.java126
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/EssenceTaskLevel.java140
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/MiscTaskLevel.java200
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SkillRelatedTaskLevel.java225
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SlayingTaskLevel.java264
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/StoryTaskLevel.java76
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingOverlay.java3
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java24
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/TitleUtil.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java79
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/XPInformation.java2
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/EnforcedConfigValues.kt123
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumCheapestItemOverlay.kt3
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumItemHighlighter.kt2
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/util/PetLeveling.kt2
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/util/Shimmy.kt85
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/util/hypixelapi/Collection.kt159
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/util/kotlin/gson.kt33
-rw-r--r--src/main/resources/assets/notenoughupdates/pv_basic.pngbin2836 -> 2818 bytes
-rw-r--r--src/main/resources/assets/notenoughupdates/pv_levels.pngbin0 -> 3526 bytes
-rw-r--r--src/main/resources/assets/notenoughupdates/textures/gui/config_blocked.pngbin0 -> 898 bytes
-rw-r--r--src/main/resources/mixins.notenoughupdates.json2
122 files changed, 3825 insertions, 1140 deletions
diff --git a/.idea/copyright/NotEnoughUpdates.xml b/.idea/copyright/NotEnoughUpdates.xml
index c1c6368d..d3ac04b2 100644
--- a/.idea/copyright/NotEnoughUpdates.xml
+++ b/.idea/copyright/NotEnoughUpdates.xml
@@ -1,7 +1,7 @@
<component name="CopyrightManager">
<copyright>
<option name="allowReplaceRegexp" value="Copyright" />
- <option name="notice" value="Copyright (C) 2023 NotEnoughUpdates contributors&#10;&#10;This file is part of NotEnoughUpdates.&#10;&#10;NotEnoughUpdates is free software: you can redistribute it&#10;and/or modify it under the terms of the GNU Lesser General Public&#10;License as published by the Free Software Foundation, either&#10;version 3 of the License, or (at your option) any later version.&#10;&#10;NotEnoughUpdates is distributed in the hope that it will be useful,&#10;but WITHOUT ANY WARRANTY; without even the implied warranty of&#10;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU&#10;Lesser General Public License for more details.&#10;&#10;You should have received a copy of the GNU Lesser General Public License&#10;along with NotEnoughUpdates. If not, see &lt;https://www.gnu.org/licenses/&gt;." />
+ <option name="notice" value="Copyright (C) &amp;#36;originalComment.match(&quot;Copyright \(C\) (\d+)&quot;,1,&quot;-&quot;)&amp;#36;today.year NotEnoughUpdates contributors&#10;&#10;This file is part of NotEnoughUpdates.&#10;&#10;NotEnoughUpdates is free software: you can redistribute it&#10;and/or modify it under the terms of the GNU Lesser General Public&#10;License as published by the Free Software Foundation, either&#10;version 3 of the License, or (at your option) any later version.&#10;&#10;NotEnoughUpdates is distributed in the hope that it will be useful,&#10;but WITHOUT ANY WARRANTY; without even the implied warranty of&#10;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU&#10;Lesser General Public License for more details.&#10;&#10;You should have received a copy of the GNU Lesser General Public License&#10;along with NotEnoughUpdates. If not, see &lt;https://www.gnu.org/licenses/&gt;." />
<option name="myName" value="NotEnoughUpdates" />
</copyright>
</component>
diff --git a/Update Notes/2.1.1.md b/Update Notes/2.1.1.md
index 7e41860a..eb6fcc31 100644
--- a/Update Notes/2.1.1.md
+++ b/Update Notes/2.1.1.md
@@ -10,6 +10,7 @@
- Added Katsitting recipe upgrade - nea89
- Added cheapest museum item overlay - Lulonaut
- Added Frozen Treasure Highlighter - heyngra
+- Added SkyBlock levels to PV - efefury
### **Minor Changes:**
diff --git a/annotations/build.gradle.kts b/annotations/build.gradle.kts
new file mode 100644
index 00000000..c9e13173
--- /dev/null
+++ b/annotations/build.gradle.kts
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 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/>.
+ */
+
+plugins {
+ kotlin("jvm")
+ java
+}
+
+repositories {
+ mavenCentral()
+}
+
+tasks.withType<JavaCompile> {
+ if (JavaVersion.current().isJava9Compatible) {
+ options.release.set(8)
+ }
+}
+
+dependencies {
+ implementation(kotlin("stdlib-jdk8"))
+ implementation("com.google.devtools.ksp:symbol-processing-api:1.8.0-1.0.8")
+ implementation("com.squareup:kotlinpoet:1.12.0")
+ implementation("com.squareup:kotlinpoet-ksp:1.12.0")
+}
+
+
+
+
diff --git a/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSubscribe.kt b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSubscribe.kt
new file mode 100644
index 00000000..1ba6be99
--- /dev/null
+++ b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSubscribe.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 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.autosubscribe
+
+@Retention(AnnotationRetention.SOURCE)
+@Target(AnnotationTarget.CLASS)
+annotation class NEUAutoSubscribe
diff --git a/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessor.kt b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessor.kt
new file mode 100644
index 00000000..157749d0
--- /dev/null
+++ b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessor.kt
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2023 Linnea Gräf
+ *
+ * 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.autosubscribe
+
+import com.google.devtools.ksp.getDeclaredFunctions
+import com.google.devtools.ksp.getDeclaredProperties
+import com.google.devtools.ksp.processing.CodeGenerator
+import com.google.devtools.ksp.processing.KSPLogger
+import com.google.devtools.ksp.processing.Resolver
+import com.google.devtools.ksp.processing.SymbolProcessor
+import com.google.devtools.ksp.symbol.ClassKind
+import com.google.devtools.ksp.symbol.KSAnnotated
+import com.google.devtools.ksp.symbol.KSClassDeclaration
+import com.google.devtools.ksp.symbol.Modifier
+import com.google.devtools.ksp.validate
+import com.squareup.kotlinpoet.FileSpec
+import com.squareup.kotlinpoet.FunSpec
+import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
+import com.squareup.kotlinpoet.TypeSpec
+import com.squareup.kotlinpoet.asTypeName
+import com.squareup.kotlinpoet.ksp.toClassName
+import com.squareup.kotlinpoet.ksp.writeTo
+import java.util.function.Consumer
+import java.util.function.Supplier
+
+internal class NEUAutoSymbolProcessor(val codeGenerator: CodeGenerator, val logger: KSPLogger) : SymbolProcessor {
+ fun collectSubscribers(elements: List<KSAnnotated>): List<NEUEventSubscriber> = buildList {
+ for (element in elements) {
+ if (element !is KSClassDeclaration) {
+ logger.error("@NEUAutoSubscribe is only valid on class or object declarations", element)
+ continue
+ }
+ if (element.typeParameters.isNotEmpty()) {
+ logger.error("@NEUAutoSubscribe is not valid on generic classes", element)
+ continue
+ }
+ val name = element.qualifiedName
+ if (name == null) {
+ logger.error("@NEUAutoSubscribe could not find name", element)
+ continue
+ }
+ when (element.classKind) {
+ ClassKind.CLASS -> {
+ val instanceGetter = element.getDeclaredFunctions().find {
+ it.simpleName.asString() == "getInstance"
+ }
+ val instanceVariable = element.getDeclaredProperties().find {
+ it.simpleName.asString() == "INSTANCE"
+ }
+ if (instanceGetter != null) {
+ val returnType = instanceGetter.returnType
+ if (returnType == null || !element.asStarProjectedType().isAssignableFrom(returnType.resolve())) {
+ logger.error(
+ "getInstance() does not have the expected return type ${element.asStarProjectedType()}",
+ instanceGetter
+ )
+ continue
+ }
+ add(NEUEventSubscriber(InvocationKind.GET_INSTANCE, element))
+ } else if (instanceVariable != null) {
+ val variableType = instanceVariable.type
+ if (!element.asStarProjectedType().isAssignableFrom(variableType.resolve())) {
+ logger.error(
+ "INSTANCE does not have expected type ${element.asStarProjectedType()}",
+ instanceVariable
+ )
+ continue
+ }
+ add(NEUEventSubscriber(InvocationKind.ACCESS_INSTANCE, element))
+ } else {
+ add(NEUEventSubscriber(InvocationKind.DEFAULT_CONSTRUCTOR, element))
+ }
+ }
+
+ ClassKind.OBJECT -> {
+ add(NEUEventSubscriber(InvocationKind.OBJECT_INSTANCE, element))
+ }
+
+ else -> {
+ logger.error(
+ "@NEUAutoSubscribe is only valid on classes and objects, not on ${element.classKind}",
+ element
+ )
+ continue
+ }
+ }
+ }
+
+ }
+
+ val subscribers = mutableListOf<NEUEventSubscriber>()
+ override fun process(resolver: Resolver): List<KSAnnotated> {
+ val candidates = resolver.getSymbolsWithAnnotation(NEUAutoSubscribe::class.qualifiedName!!).toList()
+ val valid = candidates.filter { it.validate() }
+ val invalid = candidates.filter { !it.validate() }
+
+ subscribers.addAll(collectSubscribers(valid))
+ return invalid
+ }
+
+ override fun finish() {
+ if (subscribers.isEmpty()) return
+ val deps = subscribers.mapNotNull { it.declaration.containingFile }
+ logger.info("Dependencies: $deps")
+ FileSpec.builder("io.github.moulberry.notenoughupdates.autosubscribe", "AutoLoad")
+ .addFileComment("@generated by ${NEUAutoSymbolProcessor::class.simpleName}")
+ .addType(
+ TypeSpec.objectBuilder("AutoLoad")
+ .addFunction(
+ FunSpec.builder("provide")
+ .addParameter(
+ "consumer",
+ Consumer::class.asTypeName()
+ .parameterizedBy(Supplier::class.parameterizedBy(Any::class))
+ )
+ .apply {
+ subscribers.sortedBy { it.declaration.simpleName.asString() }.forEach { (invocationKind, declaration) ->
+ when (invocationKind) {
+ InvocationKind.GET_INSTANCE -> addStatement(
+ "consumer.accept { %T.getInstance() }",
+ declaration.toClassName()
+ )
+
+ InvocationKind.OBJECT_INSTANCE -> addStatement(
+ "consumer.accept { %T }",
+ declaration.toClassName()
+ )
+
+ InvocationKind.DEFAULT_CONSTRUCTOR -> addStatement(
+ "consumer.accept { %T() }",
+ declaration.toClassName()
+ )
+
+ InvocationKind.ACCESS_INSTANCE -> addStatement(
+ "consumer.accept { %T.INSTANCE }",
+ declaration.toClassName()
+ )
+ }
+ }
+ }
+ .build()
+ )
+ .build()
+ )
+ .build()
+ .writeTo(codeGenerator, aggregating = true, originatingKSFiles = deps)
+ }
+}
diff --git a/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessorProvider.kt b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessorProvider.kt
new file mode 100644
index 00000000..ef0edd88
--- /dev/null
+++ b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessorProvider.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 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.autosubscribe
+
+import com.google.devtools.ksp.processing.SymbolProcessor
+import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
+import com.google.devtools.ksp.processing.SymbolProcessorProvider
+
+class NEUAutoSymbolProcessorProvider : SymbolProcessorProvider {
+ override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
+ return NEUAutoSymbolProcessor(environment.codeGenerator, environment.logger)
+ }
+}
diff --git a/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUEventSubscriber.kt b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUEventSubscriber.kt
new file mode 100644
index 00000000..d17b6004
--- /dev/null
+++ b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUEventSubscriber.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 Linnea Gräf
+ *
+ * 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.autosubscribe
+
+import com.google.devtools.ksp.symbol.KSClassDeclaration
+
+internal data class NEUEventSubscriber(
+ val invocationKind: InvocationKind,
+ val declaration: KSClassDeclaration,
+)
+
+internal enum class InvocationKind {
+ GET_INSTANCE,
+ OBJECT_INSTANCE,
+ DEFAULT_CONSTRUCTOR,
+ ACCESS_INSTANCE,
+}
diff --git a/annotations/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider b/annotations/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider
new file mode 100644
index 00000000..eaad70ce
--- /dev/null
+++ b/annotations/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider
@@ -0,0 +1,20 @@
+#
+# Copyright (C) 2023 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/>.
+#
+
+io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSymbolProcessorProvider
diff --git a/build.gradle.kts b/build.gradle.kts
index e9e769a8..e41aa513 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -30,8 +30,8 @@ plugins {
id("com.github.johnrengelman.shadow") version "7.1.2"
id("io.github.juuxel.loom-quiltflower") version "1.7.3"
`maven-publish`
- id("io.freefair.lombok") version "6.5.1"
- kotlin("jvm") version "1.7.20"
+ kotlin("jvm") version "1.8.0"
+ id("com.google.devtools.ksp") version "1.8.0-1.0.8"
}
@@ -62,6 +62,7 @@ loom {
pack200Provider.set(dev.architectury.pack200.java.Pack200Adapter())
mixinConfig("mixins.notenoughupdates.json")
}
+ @Suppress("UnstableApiUsage")
mixin {
defaultRefmapName.set("mixins.notenoughupdates.refmap.json")
}
@@ -78,44 +79,43 @@ repositories {
maven("https://repo.polyfrost.cc/releases")
}
-lombok {
- version.set("1.18.24")
-}
-
-
-val shadowImplementation by configurations.creating {
+val shadowImplementation: Configuration by configurations.creating {
configurations.implementation.get().extendsFrom(this)
}
-val shadowOnly by configurations.creating {
+val shadowOnly: Configuration by configurations.creating {
}
-val shadowApi by configurations.creating {
+val shadowApi: Configuration by configurations.creating {
configurations.api.get().extendsFrom(this)
}
-val devEnv by configurations.creating {
+val devEnv: Configuration by configurations.creating {
configurations.runtimeClasspath.get().extendsFrom(this)
isCanBeResolved = false
isCanBeConsumed = false
isVisible = false
}
-val kotlinDependencies by configurations.creating {
+val kotlinDependencies: Configuration by configurations.creating {
configurations.implementation.get().extendsFrom(this)
}
-val oneconfigQuarantineSourceSet = sourceSets.create("oneconfig") {
+val oneconfigQuarantineSourceSet: SourceSet = sourceSets.create("oneconfig") {
java {
srcDir(layout.projectDirectory.dir("src/main/oneconfig"))
}
- kotlin {
+}
+
+configurations {
+ val main = getByName(sourceSets.main.get().compileClasspathConfigurationName)
+ "oneconfigImplementation" {
+ extendsFrom(main)
}
}
dependencies {
- implementation("org.projectlombok:lombok:1.18.22")
minecraft("com.mojang:minecraft:1.8.9")
mappings("de.oceanlabs.mcp:mcp_stable:22-1.8.9")
forge("net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9")
@@ -126,21 +126,27 @@ dependencies {
runtimeOnly("cc.polyfrost:oneconfig-wrapper-launchwrapper:1.0.0-alpha+") // Should be included in jar
}
- "oneconfigImplementation"(sourceSets.main.get().output)
- "oneconfigImplementation"(sourceSets.main.get().compileClasspath)
"oneconfigCompileOnly"(project(":oneconfigquarantine", configuration = "namedElements"))
+ "oneconfigImplementation"(sourceSets.main.get().output)
"runtimeOnly"(oneconfigQuarantineSourceSet.output)
// Please keep this version in sync with KotlinLoadingTweaker
- implementation(enforcedPlatform("org.jetbrains.kotlin:kotlin-bom:1.7.21"))
+ implementation(enforcedPlatform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))
kotlinDependencies(kotlin("stdlib"))
+ compileOnly(ksp(project(":annotations"))!!)
+ compileOnly("org.projectlombok:lombok:1.18.24")
+ annotationProcessor("org.projectlombok:lombok:1.18.24")
+ "oneconfigAnnotationProcessor"("org.projectlombok:lombok:1.18.24")
+
shadowImplementation("org.spongepowered:mixin:0.7.11-SNAPSHOT") {
isTransitive = false // Dependencies of mixin are already bundled by minecraft
}
annotationProcessor("org.spongepowered:mixin:0.8.4-SNAPSHOT")
+
+ @Suppress("VulnerableLibrariesLocal")
shadowApi("info.bliki.wiki:bliki-core:3.1.0")
- testImplementation("org.junit.jupiter:junit-jupiter:5.8.2")
+ testImplementation("org.junit.jupiter:junit-jupiter:5.9.2")
testAnnotationProcessor("org.spongepowered:mixin:0.8.4-SNAPSHOT")
// modImplementation("io.github.notenoughupdates:MoulConfig:0.0.1")
@@ -151,15 +157,24 @@ dependencies {
java {
withSourcesJar()
- toolchain.languageVersion.set(JavaLanguageVersion.of(8))
+// toolchain.languageVersion.set(JavaLanguageVersion.of(8))
}
// Tasks:
tasks.withType(JavaCompile::class) {
options.encoding = "UTF-8"
+ options.isFork = true
+ if (JavaVersion.current().isJava9Compatible)
+ options.release.set(8)
+}
+tasks.named("compileOneconfigJava", JavaCompile::class) {
+ doFirst {
+ println("oneconfig args: ${this@named.options.compilerArgs}")
+ }
}
+
tasks.named<Test>("test") {
useJUnitPlatform()
}
@@ -189,12 +204,16 @@ val remapJar by tasks.named<net.fabricmc.loom.task.RemapJarTask>("remapJar") {
}
}
+tasks.remapSourcesJar {
+ this.enabled = false
+}
+
/* Bypassing https://github.com/johnrengelman/shadow/issues/111 */
// Use Zip instead of Jar as to not include META-INF
val kotlinDependencyCollectionJar by tasks.creating(Zip::class) {
archiveFileName.set("kotlin-libraries-wrapped.jar")
destinationDirectory.set(project.layout.buildDirectory.dir("kotlinwrapper"))
- from(kotlinDependencies.files)
+ from(kotlinDependencies)
into("neu-kotlin-libraries-wrapped")
}
@@ -227,6 +246,15 @@ tasks.processResources {
}
}
+idea {
+ module {
+ // Not using += due to https://github.com/gradle/gradle/issues/8749
+ sourceDirs = sourceDirs + file("build/generated/ksp/main/kotlin") // or tasks["kspKotlin"].destination
+ testSourceDirs = testSourceDirs + file("build/generated/ksp/test/kotlin")
+ generatedSourceDirs = generatedSourceDirs + file("build/generated/ksp/main/kotlin") + file("build/generated/ksp/test/kotlin")
+ }
+}
+
sourceSets.main {
output.setResourcesDir(file("$buildDir/classes/java/main"))
}
diff --git a/buildSrc/src/main/kotlin/neubs/buildflags.kt b/buildSrc/src/main/kotlin/neubs/buildflags.kt
index 6b7ab489..27c4bbcf 100644
--- a/buildSrc/src/main/kotlin/neubs/buildflags.kt
+++ b/buildSrc/src/main/kotlin/neubs/buildflags.kt
@@ -19,8 +19,13 @@
package neubs
+import org.gradle.api.DefaultTask
import org.gradle.api.Plugin
import org.gradle.api.Project
+import org.gradle.api.file.RegularFileProperty
+import org.gradle.api.provider.MapProperty
+import org.gradle.api.tasks.*
+import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.the
import java.nio.charset.StandardCharsets
import java.util.*
@@ -28,22 +33,16 @@ import java.util.*
const val NEU_BUILDFLAGS_PREFIX = "neu.buildflags."
class NEUBuildFlags : Plugin<Project> {
+
override fun apply(target: Project) {
val props =
target.properties.filterKeys { it.startsWith(NEU_BUILDFLAGS_PREFIX) }.mapValues { it.value as String }
target.extensions.add("buildflags", Extension(props))
- target.tasks.create("generateBuildFlags") {
- outputs.upToDateWhen { false }
- val t = target.layout.buildDirectory.file("buildflags.properties")
- outputs.file(t)
- doLast {
- val p = Properties()
- p.putAll(props)
- t.get().asFile.writer(StandardCharsets.UTF_8).use {
- p.store(it, "Store build time configuration for NEU")
- }
- }
-
+ target.tasks.create<WriteProperties>("generateBuildFlags") {
+ this.encoding = StandardCharsets.UTF_8.name()
+ this.setProperties(props)
+ this.comment = "Store build time configuration for NEU"
+ this.setOutputFile(target.layout.buildDirectory.file("buildflags.properties"))
}
}
diff --git a/gradle.properties b/gradle.properties
index 0009739e..0eb2e107 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,7 @@
org.gradle.jvmargs=-Xmx2G
+org.gradle.parallel=true
+org.gradle.caching=true
+kotlin.incremental.useClasspathSnapshot=true
loom.platform=forge
# NEU Buildflags. Please keep these flags in a commented out form while checked into version control.
# See BuildFlags.java for usages of these values.
diff --git a/oneconfigquarantine/build.gradle.kts b/oneconfigquarantine/build.gradle.kts
index 32bc3b7c..15797e1e 100644
--- a/oneconfigquarantine/build.gradle.kts
+++ b/oneconfigquarantine/build.gradle.kts
@@ -1,3 +1,5 @@
+import net.fabricmc.loom.task.RemapJarTask
+
/*
* Copyright (C) 2022 NotEnoughUpdates contributors
*
@@ -43,3 +45,10 @@ dependencies {
modApi("cc.polyfrost:oneconfig-1.8.9-forge:0.1.0-alpha+") // Don't you just love 0.1.0-alpha+
}
+tasks.withType<JavaCompile> {
+ this.enabled = false
+}
+tasks.withType<RemapJarTask> {
+ println(this)
+ this.enabled = false
+}
diff --git a/settings.gradle.kts b/settings.gradle.kts
index a910edd3..86073a5b 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -40,4 +40,5 @@ pluginManagement {
}
include("oneconfigquarantine")
+include("annotations")
rootProject.name = "NotEnoughUpdates"
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java b/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java
index 754e2dc3..5c851211 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java
@@ -54,8 +54,8 @@ public class ItemPriceInformation {
private static final NumberFormat format = new DecimalFormat("#,##0.#", new DecimalFormatSymbols(Locale.US));
public static String STACKSIZE_OVERRIDE = "NEU_STACKSIZE_OVERRIDE";
- public static boolean addToTooltip(List<String> tooltip, String internalname, ItemStack stack) {
- return addToTooltip(tooltip, internalname, stack, true);
+ public static void addToTooltip(List<String> tooltip, String internalName, ItemStack stack) {
+ addToTooltip(tooltip, internalName, stack, true);
}
public static void init(File saveLocation, Gson neuGson) {
@@ -92,16 +92,16 @@ public class ItemPriceInformation {
}
}
- public static boolean addToTooltip(List<String> tooltip, String internalname, ItemStack stack, boolean useStackSize) {
+ public static void addToTooltip(List<String> tooltip, String internalname, ItemStack stack, boolean useStackSize) {
if (stack.getTagCompound().hasKey("disableNeuTooltip") && stack.getTagCompound().getBoolean("disableNeuTooltip")) {
- return false;
+ return;
}
if (NotEnoughUpdates.INSTANCE.config.tooltipTweaks.disablePriceKey &&
!KeybindHelper.isKeyDown(NotEnoughUpdates.INSTANCE.config.tooltipTweaks.disablePriceKeyKeybind)) {
- return false;
+ return;
}
if (internalname.equals("SKYBLOCK_MENU")) {
- return false;
+ return;
}
JsonObject auctionInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAuctionInfo(internalname);
JsonObject bazaarInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo(internalname);
@@ -207,8 +207,7 @@ public class ItemPriceInformation {
}
}
- return added;
- } else if (auctionItem) {
+ } else if (auctionItem && !auctionInfoErrored) {
List<Integer> lines = NotEnoughUpdates.INSTANCE.config.tooltipTweaks.priceInfoAuc;
boolean added = false;
@@ -366,21 +365,16 @@ public class ItemPriceInformation {
}
}
- return added;
} else if (auctionInfoErrored && NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) {
String message = EnumChatFormatting.RED.toString() + EnumChatFormatting.BOLD + "[NEU] API is down";
if (auctionableItems != null && !auctionableItems.isEmpty()) {
if (auctionableItems.contains(internalname)) {
tooltip.add(message);
- return true;
}
} else {
tooltip.add(message + " and no item data is cached");
- return true;
}
}
-
- return false;
}
private static String formatPrice(String label, double price) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
index 3ecf73c0..ce386b86 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
@@ -748,7 +748,7 @@ public class NEUManager {
}
}
- public String getUUIDFromNBT(NBTTagCompound tag) {
+ public static String getUUIDFromNBT(NBTTagCompound tag) {
String uuid = null;
if (tag != null && tag.hasKey("ExtraAttributes", 10)) {
NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes");
@@ -965,7 +965,7 @@ public class NEUManager {
.resolveInternalName();
}
- public String getUUIDForItem(ItemStack stack) {
+ public static String getUUIDForItem(ItemStack stack) {
if (stack == null) return null;
NBTTagCompound tag = stack.getTagCompound();
return getUUIDFromNBT(tag);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
index 6160ac8d..94c7cc2b 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
@@ -23,76 +23,35 @@ import com.google.common.collect.Sets;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.autosubscribe.AutoLoad;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.commands.Commands;
import io.github.moulberry.notenoughupdates.core.BackgroundBlur;
-import io.github.moulberry.notenoughupdates.cosmetics.CapeManager;
import io.github.moulberry.notenoughupdates.cosmetics.ShaderManager;
-import io.github.moulberry.notenoughupdates.dungeons.DungeonMap;
import io.github.moulberry.notenoughupdates.listener.ChatListener;
import io.github.moulberry.notenoughupdates.listener.ItemTooltipEssenceShopListener;
import io.github.moulberry.notenoughupdates.listener.ItemTooltipListener;
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.AbiphoneContactHelper;
-import io.github.moulberry.notenoughupdates.miscfeatures.AbiphoneFavourites;
-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.BetterContainers;
-import io.github.moulberry.notenoughupdates.miscfeatures.CrystalOverlay;
-import io.github.moulberry.notenoughupdates.miscfeatures.CrystalWishingCompassSolver;
-import io.github.moulberry.notenoughupdates.miscfeatures.CustomItemEffects;
import io.github.moulberry.notenoughupdates.miscfeatures.CustomSkulls;
-import io.github.moulberry.notenoughupdates.miscfeatures.DungeonNpcProfitOverlay;
-import io.github.moulberry.notenoughupdates.miscfeatures.DwarvenMinesWaypoints;
-import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers;
import io.github.moulberry.notenoughupdates.miscfeatures.FairySouls;
-import io.github.moulberry.notenoughupdates.miscfeatures.FishingHelper;
-import io.github.moulberry.notenoughupdates.miscfeatures.ItemCooldowns;
import io.github.moulberry.notenoughupdates.miscfeatures.ItemCustomizeManager;
-import io.github.moulberry.notenoughupdates.miscfeatures.MiningStuff;
import io.github.moulberry.notenoughupdates.miscfeatures.NPCRetexturing;
import io.github.moulberry.notenoughupdates.miscfeatures.Navigation;
-import io.github.moulberry.notenoughupdates.miscfeatures.NullzeeSphere;
import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay;
-import io.github.moulberry.notenoughupdates.miscfeatures.PowerStoneStatsDisplay;
import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking;
import io.github.moulberry.notenoughupdates.miscfeatures.StorageManager;
-import io.github.moulberry.notenoughupdates.miscfeatures.SunTzu;
-import io.github.moulberry.notenoughupdates.miscfeatures.WardrobeMouseButtons;
-import io.github.moulberry.notenoughupdates.miscfeatures.WitherCloakChanger;
-import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes;
import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBlockSounds;
-import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.DwarvenMinesTextures;
-import io.github.moulberry.notenoughupdates.miscfeatures.inventory.MuseumCheapestItemOverlay;
-import io.github.moulberry.notenoughupdates.miscfeatures.inventory.MuseumItemHighlighter;
-import io.github.moulberry.notenoughupdates.miscfeatures.item.enchants.EnchantStyleCustomizer;
import io.github.moulberry.notenoughupdates.miscfeatures.updater.AutoUpdater;
-import io.github.moulberry.notenoughupdates.miscfeatures.world.EnderNodeHighlighter;
-import io.github.moulberry.notenoughupdates.miscfeatures.world.FrozenTreasuresHighlighter;
-import io.github.moulberry.notenoughupdates.miscfeatures.world.GlowingMushroomHighlighter;
-import io.github.moulberry.notenoughupdates.miscgui.CalendarOverlay;
-import io.github.moulberry.notenoughupdates.miscgui.InventoryStorageSelector;
-import io.github.moulberry.notenoughupdates.miscgui.SignCalculator;
-import io.github.moulberry.notenoughupdates.miscgui.TrophyRewardOverlay;
-import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager;
import io.github.moulberry.notenoughupdates.mixins.AccessorMinecraft;
import io.github.moulberry.notenoughupdates.oneconfig.IOneConfigCompat;
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;
import io.github.moulberry.notenoughupdates.recipes.RecipeGenerator;
-import io.github.moulberry.notenoughupdates.util.Constants;
-import io.github.moulberry.notenoughupdates.util.SBInfo;
-import io.github.moulberry.notenoughupdates.util.TitleUtil;
import io.github.moulberry.notenoughupdates.util.Utils;
-import io.github.moulberry.notenoughupdates.util.XPInformation;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiScreen;
@@ -132,6 +91,7 @@ import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Set;
+@NEUAutoSubscribe
@Mod(
modid = NotEnoughUpdates.MODID, version = NotEnoughUpdates.VERSION, clientSideOnly = true, useMetadata = true,
guiFactory = "io.github.moulberry.notenoughupdates.core.config.MoulConfigGuiForgeInterop")
@@ -299,64 +259,18 @@ public class NotEnoughUpdates {
IOneConfigCompat.getInstance().ifPresent(it -> it.initConfig(config, this::saveConfig));
- MinecraftForge.EVENT_BUS.register(this);
MinecraftForge.EVENT_BUS.register(new NEUEventListener(this));
MinecraftForge.EVENT_BUS.register(new RecipeGenerator(this));
- MinecraftForge.EVENT_BUS.register(CapeManager.getInstance());
- //MinecraftForge.EVENT_BUS.register(new SBGamemodes());
- MinecraftForge.EVENT_BUS.register(new EnchantingSolvers());
- MinecraftForge.EVENT_BUS.register(new CalendarOverlay());
- MinecraftForge.EVENT_BUS.register(SBInfo.getInstance());
- MinecraftForge.EVENT_BUS.register(CustomItemEffects.INSTANCE);
- MinecraftForge.EVENT_BUS.register(new Constants());
- MinecraftForge.EVENT_BUS.register(new DungeonMap());
- MinecraftForge.EVENT_BUS.register(new SunTzu());
- MinecraftForge.EVENT_BUS.register(new WitherCloakChanger());
- MinecraftForge.EVENT_BUS.register(new MiningStuff());
- MinecraftForge.EVENT_BUS.register(FairySouls.getInstance());
- MinecraftForge.EVENT_BUS.register(new CrystalOverlay());
- MinecraftForge.EVENT_BUS.register(new ItemCooldowns());
- MinecraftForge.EVENT_BUS.register(new DwarvenMinesWaypoints());
- MinecraftForge.EVENT_BUS.register(new FuelBar());
- MinecraftForge.EVENT_BUS.register(new AuctionProfit());
- MinecraftForge.EVENT_BUS.register(new DungeonNpcProfitOverlay());
- MinecraftForge.EVENT_BUS.register(XPInformation.getInstance());
MinecraftForge.EVENT_BUS.register(OverlayManager.petInfoOverlay);
MinecraftForge.EVENT_BUS.register(OverlayManager.timersOverlay);
- MinecraftForge.EVENT_BUS.register(new NullzeeSphere());
- MinecraftForge.EVENT_BUS.register(InventoryStorageSelector.getInstance());
- MinecraftForge.EVENT_BUS.register(SlotLocking.getInstance());
- 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));
MinecraftForge.EVENT_BUS.register(new ItemTooltipRngListener(this));
MinecraftForge.EVENT_BUS.register(new ItemTooltipEssenceShopListener(this));
MinecraftForge.EVENT_BUS.register(new RenderListener(this));
- MinecraftForge.EVENT_BUS.register(new OldAnimationChecker());
- MinecraftForge.EVENT_BUS.register(new SignCalculator());
- MinecraftForge.EVENT_BUS.register(TrophyRewardOverlay.getInstance());
- MinecraftForge.EVENT_BUS.register(PowerStoneStatsDisplay.getInstance());
- MinecraftForge.EVENT_BUS.register(AntiCoopAdd.getInstance());
- MinecraftForge.EVENT_BUS.register(AbiphoneWarning.getInstance());
- MinecraftForge.EVENT_BUS.register(new BetterContainers());
- MinecraftForge.EVENT_BUS.register(AuctionBINWarning.getInstance());
- MinecraftForge.EVENT_BUS.register(MinionHelperManager.getInstance());
MinecraftForge.EVENT_BUS.register(navigation);
- MinecraftForge.EVENT_BUS.register(new GlowingMushroomHighlighter());
MinecraftForge.EVENT_BUS.register(new WorldListener(this));
- MinecraftForge.EVENT_BUS.register(EnchantStyleCustomizer.INSTANCE);
- MinecraftForge.EVENT_BUS.register(TitleUtil.getInstance());
- MinecraftForge.EVENT_BUS.register(EnderNodeHighlighter.getInstance());
- MinecraftForge.EVENT_BUS.register(FrozenTreasuresHighlighter.getInstance());
- MinecraftForge.EVENT_BUS.register(AbiphoneFavourites.getInstance());
- MinecraftForge.EVENT_BUS.register(AbiphoneContactHelper.getInstance());
- MinecraftForge.EVENT_BUS.register(MuseumItemHighlighter.INSTANCE);
- MinecraftForge.EVENT_BUS.register(MuseumCheapestItemOverlay.INSTANCE);
- MinecraftForge.EVENT_BUS.register(new WardrobeMouseButtons());
+ AutoLoad.INSTANCE.provide(supplier -> MinecraftForge.EVENT_BUS.register(supplier.get()));
if (Minecraft.getMinecraft().getResourceManager() instanceof IReloadableResourceManager) {
IReloadableResourceManager manager = (IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager();
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 e606fc49..5ec3724a 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java
@@ -731,7 +731,7 @@ public class APIManager {
public void updateBazaar() {
manager.apiUtils
- .newHypixelApiRequest("skyblock/bazaar")
+ .newAnonymousHypixelApiRequest("skyblock/bazaar")
.requestJson()
.thenAccept(jsonObject -> {
if (!jsonObject.get("success").getAsBoolean()) return;
@@ -744,7 +744,9 @@ public class APIManager {
JsonObject productInfo = new JsonObject();
JsonObject product = entry.getValue().getAsJsonObject();
- JsonObject quickStatus = product.get("quick_status").getAsJsonObject();
+ JsonObject quickStatus = product.getAsJsonObject("quick_status");
+ if (!hasData(quickStatus)) continue;
+
productInfo.addProperty("avg_buy", quickStatus.get("buyPrice").getAsFloat());
productInfo.addProperty("avg_sell", quickStatus.get("sellPrice").getAsFloat());
@@ -771,6 +773,19 @@ public class APIManager {
});
}
+ private static boolean hasData(JsonObject quickStatus) {
+ for (Map.Entry<String, JsonElement> e : quickStatus.entrySet()) {
+ String key = e.getKey();
+ if (!key.equals("productId")) {
+ double value = e.getValue().getAsDouble();
+ if (value != 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
public void updateAvgPrices() {
manager.apiUtils
.newMoulberryRequest("auction_averages/3day.json.gz")
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 cf266dca..0d882358 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
@@ -19,6 +19,9 @@
package io.github.moulberry.notenoughupdates.commands.dev;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.BuildFlags;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.commands.ClientCommandBase;
@@ -34,6 +37,7 @@ import io.github.moulberry.notenoughupdates.util.PronounDB;
import io.github.moulberry.notenoughupdates.util.SBInfo;
import io.github.moulberry.notenoughupdates.util.TabListUtils;
import io.github.moulberry.notenoughupdates.util.Utils;
+import io.github.moulberry.notenoughupdates.util.hypixelapi.ProfileCollectionInfo;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.command.CommandException;
@@ -122,6 +126,32 @@ public class DevTestCommand extends ClientCommandBase {
Utils.addChatMessage(EnumChatFormatting.RED + DEV_FAIL_STRINGS[devFailIndex++]);
return;
}
+ if (args.length == 1 && args[0].equalsIgnoreCase("testprofile")) {
+ NotEnoughUpdates.INSTANCE.manager.apiUtils.newHypixelApiRequest("skyblock/profiles")
+ .queryArgument(
+ "uuid",
+ "" + Minecraft.getMinecraft().thePlayer.getUniqueID()
+ )
+ .requestJson()
+ .thenApply(jsonObject -> {
+ JsonArray profiles = jsonObject.get("profiles").getAsJsonArray();
+ JsonObject cp = null;
+ for (JsonElement profile : profiles) {
+ JsonObject asJsonObject = profile.getAsJsonObject();
+ if ((asJsonObject.has("selected") &&
+ asJsonObject.get("selected").getAsBoolean()) || cp == null) {
+ cp = asJsonObject;
+ }
+ }
+ return cp;
+ })
+ .thenCompose(obj -> ProfileCollectionInfo.getCollectionData(
+ obj,
+ Minecraft.getMinecraft().thePlayer.getUniqueID().toString()
+ ))
+ .thenAccept(it ->
+ Utils.addChatMessage("Response: " + it));
+ }
if (args.length >= 1 && args[0].equalsIgnoreCase("profileinfo")) {
String currentProfile = SBInfo.getInstance().currentProfile;
SBInfo.Gamemode gamemode = SBInfo.getInstance().getGamemodeForProfile(currentProfile);
@@ -146,7 +176,8 @@ public class DevTestCommand extends ClientCommandBase {
Arrays.copyOfRange(args, 1, args.length)
);
}
- Utils.addChatMessage("§e[NEU] §fYour external editor is: §Z" + NotEnoughUpdates.INSTANCE.config.hidden.externalEditor);
+ Utils.addChatMessage(
+ "§e[NEU] §fYour external editor is: §Z" + NotEnoughUpdates.INSTANCE.config.hidden.externalEditor);
return;
}
if (args.length >= 1 && args[0].equalsIgnoreCase("pricetest")) {
@@ -181,7 +212,8 @@ public class DevTestCommand extends ClientCommandBase {
}
if (args.length == 1 && args[0].equalsIgnoreCase("dev")) {
NotEnoughUpdates.INSTANCE.config.hidden.dev = !NotEnoughUpdates.INSTANCE.config.hidden.dev;
- Utils.addChatMessage("§e[NEU] Dev mode " + (NotEnoughUpdates.INSTANCE.config.hidden.dev ? "§aenabled": "§cdisabled"));
+ Utils.addChatMessage(
+ "§e[NEU] Dev mode " + (NotEnoughUpdates.INSTANCE.config.hidden.dev ? "§aenabled" : "§cdisabled"));
return;
}
if (args.length == 1 && args[0].equalsIgnoreCase("saveconfig")) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/SettingsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/SettingsCommand.java
index 9964b739..1855a2b5 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/SettingsCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/SettingsCommand.java
@@ -47,7 +47,7 @@ public class SettingsCommand extends ClientCommandBase {
NotEnoughUpdates.INSTANCE.openGui =
new GuiScreenElementWrapper(new NEUConfigEditor(NotEnoughUpdates.INSTANCE.config, StringUtils.join(args, " ")));
} else {
- NotEnoughUpdates.INSTANCE.openGui = new GuiScreenElementWrapper(NEUConfigEditor.editor);
+ NotEnoughUpdates.INSTANCE.openGui = new GuiScreenElementWrapper(new NEUConfigEditor(NotEnoughUpdates.INSTANCE.config));
}
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/BackgroundBlur.java b/src/main/java/io/github/moulberry/notenoughupdates/core/BackgroundBlur.java
index fc2be97b..eaa733e4 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/core/BackgroundBlur.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/BackgroundBlur.java
@@ -120,8 +120,14 @@ public class BackgroundBlur {
for (Map.Entry<Float, OutputStuff> entry : blurOutput.entrySet()) {
if (remove.contains(entry.getKey())) {
entry.getValue().framebuffer.deleteFramebuffer();
- entry.getValue().blurShaderHorz.deleteShader();
- entry.getValue().blurShaderVert.deleteShader();
+ Shader blurShaderHorz = entry.getValue().blurShaderHorz;
+ if (blurShaderHorz != null) {
+ blurShaderHorz.deleteShader();
+ }
+ Shader blurShaderVert = entry.getValue().blurShaderVert;
+ if (blurShaderVert != null) {
+ blurShaderVert.deleteShader();
+ }
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditor.java
index c3969e35..9edad918 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditor.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditor.java
@@ -27,7 +27,7 @@ import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.GlStateManager;
public abstract class GuiOptionEditor {
- protected final ConfigProcessor.ProcessedOption option;
+ public final ConfigProcessor.ProcessedOption option;
private static final int HEIGHT = 45;
public GuiOptionEditor(ConfigProcessor.ProcessedOption option) {
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 9a75ec19..62b9b8e2 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
@@ -45,6 +45,7 @@ import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorFSR;
import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorKeybind;
import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorSlider;
import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorText;
+import io.github.moulberry.notenoughupdates.miscfeatures.EnforcedConfigValues;
import java.lang.reflect.Field;
import java.util.LinkedHashMap;
@@ -133,6 +134,7 @@ public class ConfigProcessor {
boolean optionPresent = optionField.isAnnotationPresent(ConfigOption.class);
if (optionPresent) {
+ String optionPath = categoryField.getName() + "." + optionField.getName();
ConfigOption optionAnnotation = optionField.getAnnotation(ConfigOption.class);
ProcessedOption option = new ProcessedOption(
optionAnnotation.name(),
@@ -231,6 +233,10 @@ public class ConfigProcessor {
//System.err.printf("Failed to load config option %s. Could not find suitable editor.\n", optionField.getName());
continue;
}
+ if (EnforcedConfigValues.INSTANCE.isBlockedFromEditing(optionPath)) {
+ editor = new GuiOptionEditorBlocked(editor);
+ }
+
option.editor = editor;
cat.options.put(optionField.getName(), option);
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/GuiOptionEditorBlocked.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/GuiOptionEditorBlocked.java
new file mode 100644
index 00000000..8415cf72
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/GuiOptionEditorBlocked.java
@@ -0,0 +1,75 @@
+/*
+ * 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.struct;
+
+import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditor;
+import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils;
+import io.github.moulberry.notenoughupdates.core.util.render.TextRenderUtils;
+import lombok.var;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.util.ResourceLocation;
+
+public class GuiOptionEditorBlocked extends GuiOptionEditor {
+ public static final ResourceLocation blockedTexture = new ResourceLocation(
+ "notenoughupdates:textures/gui/config_blocked.png");
+ private final GuiOptionEditor base;
+
+ public GuiOptionEditorBlocked(GuiOptionEditor base) {
+ super(base.option);
+ this.base = base;
+ }
+
+ @Override
+ public void render(int x, int y, int width) {
+ // No super. We delegate and overlay ourselves instead.
+ base.render(x, y, width);
+
+ var mc = Minecraft.getMinecraft();
+
+ // Depress original option
+ Gui.drawRect(x, y, x + width, y + getHeight(), 0x80000000);
+
+ GlStateManager.color(1, 1, 1, 1);
+ mc.getTextureManager().bindTexture(blockedTexture);
+
+ float iconWidth = getHeight() * 96F / 64;
+ RenderUtils.drawTexturedRect(x, y, iconWidth, getHeight());
+
+ TextRenderUtils.drawStringScaledMaxWidth(
+ "This option is currently not available.",
+ mc.fontRendererObj,
+ x + iconWidth,y + getHeight() / 2F - mc.fontRendererObj.FONT_HEIGHT / 2F,
+ true, (int) (width - iconWidth), 0xFFFF4444
+ );
+ GlStateManager.color(1, 1, 1, 1);
+ }
+
+ @Override
+ public boolean mouseInput(int x, int y, int width, int mouseX, int mouseY) {
+ return false;
+ }
+
+ @Override
+ public boolean keyboardInput() {
+ return false;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java
index c19c4826..c7c118bb 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java
@@ -24,6 +24,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Set;
@@ -71,7 +72,17 @@ public class StringUtils {
return shortNumberFormat(n, 0);
}
- private static final char[] c = new char[] { 'k', 'm', 'b', 't' };
+ private static final char[] sizeSuffix = new char[]{'k', 'm', 'b', 't'};
+
+ public static String shortNumberFormat(BigInteger bigInteger) {
+ BigInteger THOUSAND = BigInteger.valueOf(1000);
+ int i = -1;
+ while (bigInteger.compareTo(THOUSAND) > 0 && i < sizeSuffix.length) {
+ bigInteger = bigInteger.divide(THOUSAND);
+ i++;
+ }
+ return bigInteger.toString() + (i == -1 ? "" : sizeSuffix[i]);
+ }
public static String shortNumberFormat(double n, int iteration) {
if (n < 1000) {
@@ -84,7 +95,7 @@ public class StringUtils {
double d = ((long) n / 100) / 10.0;
boolean isRound = (d * 10) % 10 == 0;
- return d < 1000 ? (isRound || d > 9.99 ? (int) d * 10 / 10 : d + "") + "" + c[iteration] : shortNumberFormat(d, iteration + 1);
+ return d < 1000 ? (isRound || d > 9.99 ? (int) d * 10 / 10 : d + "") + "" + sizeSuffix[iteration] : shortNumberFormat(d, iteration + 1);
}
public static String urlEncode(String something) {
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 7a609a2a..4a7c1939 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java
@@ -24,6 +24,7 @@ import com.google.common.collect.HashBiMap;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.shader.Framebuffer;
@@ -44,6 +45,7 @@ import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+@NEUAutoSubscribe
public class CapeManager {
public static final CapeManager INSTANCE = new CapeManager();
public long lastCapeUpdate = 0;
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 e15168f5..686cef8e 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java
@@ -22,6 +22,7 @@ package io.github.moulberry.notenoughupdates.dungeons;
import com.google.common.collect.Iterables;
import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.core.BackgroundBlur;
import io.github.moulberry.notenoughupdates.core.config.Position;
import io.github.moulberry.notenoughupdates.util.NEUResourceManager;
@@ -73,6 +74,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
+@NEUAutoSubscribe
public class DungeonMap {
private static final ResourceLocation GREEN_CHECK = new ResourceLocation(
"notenoughupdates:dungeon_map/green_check.png");
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/events/ReplaceItemEvent.java b/src/main/java/io/github/moulberry/notenoughupdates/events/ReplaceItemEvent.java
index 2cdcf083..335d8fe0 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/events/ReplaceItemEvent.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/events/ReplaceItemEvent.java
@@ -19,17 +19,17 @@
package io.github.moulberry.notenoughupdates.events;
-import net.minecraft.inventory.InventoryBasic;
+import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
public class ReplaceItemEvent extends NEUEvent {
final ItemStack original;
- final InventoryBasic inventory;
+ final IInventory inventory;
final int slotNumber;
ItemStack replaceWith;
- public ReplaceItemEvent(ItemStack original, InventoryBasic inventory, int slotNumber) {
+ public ReplaceItemEvent(ItemStack original, IInventory inventory, int slotNumber) {
this.original = original;
this.inventory = inventory;
this.slotNumber = slotNumber;
@@ -40,7 +40,7 @@ public class ReplaceItemEvent extends NEUEvent {
return original;
}
- public InventoryBasic getInventory() {
+ public IInventory getInventory() {
return inventory;
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/hooks/ThreadDownloadImageHook.java b/src/main/java/io/github/moulberry/notenoughupdates/hooks/ThreadDownloadImageHook.java
index 4fa57360..e84fce11 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/hooks/ThreadDownloadImageHook.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/hooks/ThreadDownloadImageHook.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 Linnea Gräf
+ * Copyright (C) 2022-2023 Linnea Gräf
*
* This file is part of NotEnoughUpdates.
*
@@ -26,15 +26,22 @@ import javax.net.ssl.HttpsURLConnection;
import java.net.HttpURLConnection;
public class ThreadDownloadImageHook {
+ public static String hookThreadImageLink(String originalLink) {
+ if (!NotEnoughUpdates.INSTANCE.config.misc.fixSteveSkulls || originalLink == null || !originalLink.startsWith(
+ "http://textures.minecraft.net"))
+ return originalLink;
+ return originalLink.replace("http://", "https://");
+ }
+
public static void hookThreadImageConnection(HttpURLConnection connection) {
if ((connection instanceof HttpsURLConnection) && NotEnoughUpdates.INSTANCE.config.misc.fixSteveSkulls) {
ApiUtil.patchHttpsRequest((HttpsURLConnection) connection);
}
}
- public static String hookThreadImageLink(String originalLink) {
- if (!NotEnoughUpdates.INSTANCE.config.misc.fixSteveSkulls || originalLink == null)
- return originalLink;
- return originalLink.replace("http://", "https://");
+ public interface AccessorThreadDownloadImageData {
+ String getOriginalUrl();
+
+ String getPatchedUrl();
}
}
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 31930b01..8563189c 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java
@@ -61,7 +61,7 @@ public class ChatListener {
private static final Pattern SLAYER_EXP_PATTERN = Pattern.compile(
" (Spider|Zombie|Wolf|Enderman|Blaze) Slayer LVL (\\d) - (?:Next LVL in ([\\d,]+) XP!|LVL MAXED OUT!)");
private static final Pattern SKY_BLOCK_LEVEL_PATTERN = Pattern.compile("\\[(\\d{1,4})\\] .*");
- private final Pattern PARTY_FINDER_PATTERN = Pattern.compile("§dParty Finder §r§f> (.*)§ejoined the dungeon group!");
+ private final Pattern PARTY_FINDER_PATTERN = Pattern.compile("§dParty Finder §r§f> (.*)§ejoined the (dungeon )?group!");
private AtomicBoolean missingRecipe = new AtomicBoolean(false);
@@ -316,10 +316,7 @@ public class ChatListener {
}
}
- 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);
+ OverlayManager.powderGrindingOverlay.onMessage(unformatted);
if (unformatted.startsWith("ENDER NODE!"))
EnderNodeHighlighter.getInstance().highlightedBlocks.clear();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/OldAnimationChecker.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/OldAnimationChecker.java
index 7858918b..8d62c0aa 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/OldAnimationChecker.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/OldAnimationChecker.java
@@ -21,12 +21,14 @@ package io.github.moulberry.notenoughupdates.listener;
import com.google.common.collect.Lists;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.util.NotificationHandler;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+@NEUAutoSubscribe
public class OldAnimationChecker {
private void unregister() {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/loader/KotlinLoadingTweaker.java b/src/main/java/io/github/moulberry/notenoughupdates/loader/KotlinLoadingTweaker.java
index 0c63b17d..bf4e746f 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/loader/KotlinLoadingTweaker.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/loader/KotlinLoadingTweaker.java
@@ -82,7 +82,7 @@ public class KotlinLoadingTweaker implements ITweaker {
* Full version format: [1, 7, 20] (1.7.20)
* RC version format: [1, 7, 20, 1] (1.7.20-rc1)
*/
- public static final int[] BUNDLED_KOTLIN_VERSION = new int[]{1, 7, 20};
+ public static final int[] BUNDLED_KOTLIN_VERSION = new int[]{1, 8, 0};
@Override
public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AbiphoneContactHelper.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AbiphoneContactHelper.java
index d2a5fc84..3178d241 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AbiphoneContactHelper.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AbiphoneContactHelper.java
@@ -24,6 +24,7 @@ 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.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.events.SlotClickEvent;
import io.github.moulberry.notenoughupdates.util.Constants;
@@ -36,6 +37,7 @@ import org.lwjgl.input.Keyboard;
import java.util.List;
import java.util.Map;
+@NEUAutoSubscribe
public class AbiphoneContactHelper {
private static final AbiphoneContactHelper INSTANCE = new AbiphoneContactHelper();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AbiphoneFavourites.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AbiphoneFavourites.java
index e6a1399d..750e674d 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AbiphoneFavourites.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AbiphoneFavourites.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.core.config.KeybindHelper;
import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils;
@@ -45,6 +46,7 @@ import java.awt.*;
import java.util.ArrayList;
import java.util.List;
+@NEUAutoSubscribe
public class AbiphoneFavourites {
private static final AbiphoneFavourites INSTANCE = new AbiphoneFavourites();
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 67ac4f4c..2c28bcd1 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AbiphoneWarning.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AbiphoneWarning.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
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;
@@ -41,6 +42,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
+@NEUAutoSubscribe
public class AbiphoneWarning extends GuiElement {
private static final AbiphoneWarning INSTANCE = new AbiphoneWarning();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AntiCoopAdd.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AntiCoopAdd.java
index aaa13d39..40425560 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AntiCoopAdd.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AntiCoopAdd.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.events.SlotClickEvent;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
@@ -32,6 +33,7 @@ import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+@NEUAutoSubscribe
public class AntiCoopAdd {
private static final AntiCoopAdd INSTANCE = new AntiCoopAdd();
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 75813700..7282aad7 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionBINWarning.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionBINWarning.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.autosubscribe.NEUAutoSubscribe;
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;
@@ -43,6 +44,7 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+@NEUAutoSubscribe
public class AuctionBINWarning extends GuiElement {
private static final AuctionBINWarning INSTANCE = new AuctionBINWarning();
@@ -105,6 +107,8 @@ public class AuctionBINWarning extends GuiElement {
}
ItemStack sellStack = event.guiContainer.inventorySlots.getSlot(13).getStack();
+ if (sellStack == null) return;
+
String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(sellStack);
sellStackAmount = sellStack.stackSize;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionProfit.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionProfit.java
index 82c392e4..c0e40ec9 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionProfit.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionProfit.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer;
import io.github.moulberry.notenoughupdates.util.Utils;
@@ -39,6 +40,7 @@ import net.minecraftforge.client.event.GuiScreenEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.lwjgl.opengl.GL11;
+@NEUAutoSubscribe
public class AuctionProfit {
public static final ResourceLocation auctionProfitImage =
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 dc7b0e15..e7331378 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.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.events.SlotClickEvent;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiChest;
@@ -47,6 +48,7 @@ import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
+@NEUAutoSubscribe
public class BetterContainers {
private static final ResourceLocation TOGGLE_OFF = new ResourceLocation("notenoughupdates:dynamic_54/toggle_off.png");
private static final ResourceLocation TOGGLE_ON = new ResourceLocation("notenoughupdates:dynamic_54/toggle_on.png");
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java
index c0653742..047f3c99 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalOverlay.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.util.ReverseWorldRenderer;
import io.github.moulberry.notenoughupdates.util.SpecialColour;
import net.minecraft.client.Minecraft;
@@ -48,6 +49,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
+@NEUAutoSubscribe
public class CrystalOverlay {
private enum CrystalType {
FARMING_MINION(8, 0xDAA520),
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 50975af9..c6e714fe 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.core.util.Line;
import io.github.moulberry.notenoughupdates.core.util.Vec3Comparable;
import io.github.moulberry.notenoughupdates.events.SpawnParticleEvent;
@@ -52,6 +53,7 @@ import java.util.Locale;
import java.util.function.BooleanSupplier;
import java.util.function.LongSupplier;
+@NEUAutoSubscribe
public class CrystalWishingCompassSolver {
enum SolverState {
NOT_STARTED,
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 452f8a9b..e959c761 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CustomItemEffects.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.util.SBInfo;
import io.github.moulberry.notenoughupdates.util.SpecialColour;
import io.github.moulberry.notenoughupdates.util.Utils;
@@ -76,6 +77,7 @@ import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+@NEUAutoSubscribe
public class CustomItemEffects {
public static final CustomItemEffects INSTANCE = new CustomItemEffects();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DungeonNpcProfitOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DungeonNpcProfitOverlay.java
index 34a40c2f..711d5235 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DungeonNpcProfitOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DungeonNpcProfitOverlay.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 NotEnoughUpdates contributors
+ * Copyright (C) 2022-2023 NotEnoughUpdates contributors
*
* This file is part of NotEnoughUpdates.
*
@@ -22,6 +22,7 @@ package io.github.moulberry.notenoughupdates.miscfeatures;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer;
import io.github.moulberry.notenoughupdates.util.ItemUtils;
@@ -52,6 +53,7 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+@NEUAutoSubscribe
public class DungeonNpcProfitOverlay {
private static final ResourceLocation dungeonProfitResource =
@@ -334,7 +336,7 @@ public class DungeonNpcProfitOverlay {
}
}
}
- } else if (essenceMatcher.matches()) {
+ } else if (essenceMatcher.matches() && NotEnoughUpdates.INSTANCE.config.dungeons.useEssenceCostFromBazaar) {
String essenceType = essenceMatcher.group("essenceType");
String essenceAmount = essenceMatcher.group("essenceAmount");
if (essenceType == null || essenceAmount == null) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesWaypoints.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesWaypoints.java
index 6b2c9ac9..e2eb13b2 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesWaypoints.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DwarvenMinesWaypoints.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils;
import io.github.moulberry.notenoughupdates.options.NEUConfig;
import io.github.moulberry.notenoughupdates.overlays.MiningOverlay;
@@ -46,6 +47,7 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+@NEUAutoSubscribe
public class DwarvenMinesWaypoints {
private final HashMap<String, Vector3f> waypointsMap = new HashMap<String, Vector3f>() {{
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 d5cbfdde..695c9851 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.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.events.SlotClickEvent;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
@@ -45,6 +46,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
+@NEUAutoSubscribe
public class EnchantingSolvers {
public static SolverType currentSolver = SolverType.NONE;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java
index 9e3343a4..5a611178 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java
@@ -25,6 +25,7 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.commands.ClientCommandBase;
import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils;
@@ -64,6 +65,7 @@ import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
+@NEUAutoSubscribe
public class FairySouls {
private static FairySouls instance = null;
private static final String unknownProfile = "unknown";
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 a7c22b93..800e25b1 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FishingHelper.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FishingHelper.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.core.ChromaColour;
import io.github.moulberry.notenoughupdates.events.SpawnParticleEvent;
import io.github.moulberry.notenoughupdates.util.SpecialColour;
@@ -53,6 +54,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+@NEUAutoSubscribe
public class FishingHelper {
private static final FishingHelper INSTANCE = new FishingHelper();
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 e5ee40d0..5651a6ed 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.item.ItemStack;
@@ -36,6 +37,7 @@ import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+@NEUAutoSubscribe
public class ItemCooldowns {
private static final Pattern COOLDOWN_LORE = Pattern.compile("\\u00a78Cooldown: \\u00a7a(\\d+)s");
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCustomizeManager.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCustomizeManager.java
index 15fc8ef8..dad801ec 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCustomizeManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCustomizeManager.java
@@ -21,6 +21,7 @@ package io.github.moulberry.notenoughupdates.miscfeatures;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
+import io.github.moulberry.notenoughupdates.NEUManager;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.core.ChromaColour;
import net.minecraft.client.Minecraft;
@@ -67,8 +68,6 @@ public class ItemCustomizeManager {
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private static ItemDataMap itemDataMap = new ItemDataMap();
- private static final HashMap<Integer, String> itemUuidCache = new HashMap<>();
-
public static class ItemDataMap {
public HashMap<String, ItemData> itemData = new HashMap<>();
}
@@ -269,25 +268,10 @@ public class ItemCustomizeManager {
return CUSTOM_GLINT_TEXTURE;
}
- public static String getUuidForItem(ItemStack stack) {
- if (!stack.hasTagCompound()) return null;
-
- int nbtHash = stack.getTagCompound().hashCode();
-
- if (itemUuidCache.containsKey(nbtHash)) {
- return itemUuidCache.get(nbtHash);
- }
-
- String uuid = NotEnoughUpdates.INSTANCE.manager.getUUIDForItem(stack);
-
- itemUuidCache.put(nbtHash, uuid);
- return uuid;
- }
-
public static ItemData getDataForItem(ItemStack stack) {
if (stack == null) return null;
- String uuid = getUuidForItem(stack);
+ String uuid = NEUManager.getUUIDForItem(stack);
if (uuid == null) {
return null;
@@ -297,7 +281,6 @@ public class ItemCustomizeManager {
}
public static void tick() {
- itemUuidCache.clear();
disableTextureBinding = false;
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/MiningStuff.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/MiningStuff.java
index 12e0301b..2cbd3125 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/MiningStuff.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/MiningStuff.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.core.util.render.TextRenderUtils;
import io.github.moulberry.notenoughupdates.overlays.MiningOverlay;
import io.github.moulberry.notenoughupdates.util.SBInfo;
@@ -44,6 +45,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import java.util.Map;
+@NEUAutoSubscribe
public class MiningStuff {
private static BlockPos overlayLoc = null;
private static long titaniumNotifMillis = 0;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NullzeeSphere.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NullzeeSphere.java
index 6302343e..08d48962 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NullzeeSphere.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/NullzeeSphere.java
@@ -19,6 +19,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.util.ReverseWorldRenderer;
import io.github.moulberry.notenoughupdates.util.SpecialColour;
import net.minecraft.client.Minecraft;
@@ -41,6 +42,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
+@NEUAutoSubscribe
public class NullzeeSphere {
public static boolean enabled = false;
public static float size = 20;
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 37cb14b5..716fb37d 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java
@@ -447,13 +447,14 @@ public class PetInfoOverlay extends TextOverlay {
if (pet.petLevel.getCurrentLevel() >= pet.petLevel.getMaxLevel()) return 0;
if (validXpTypes == null)
- validXpTypes = Lists.newArrayList("mining", "foraging", "enchanting", "farming", "combat", "fishing", "alchemy");
+ validXpTypes = Lists.newArrayList("mining", "foraging", "enchanting", "farming", "combat", "fishing", "alchemy", "all");
if (!validXpTypes.contains(xpType.toLowerCase())) return 0;
float tamingPercent = 1.0f + (config.tamingLevel / 100f);
xp = xp * tamingPercent;
xp = xp + (xp * config.beastMultiplier / 100f);
- if (pet.petXpType != null && !pet.petXpType.equalsIgnoreCase(xpType)) {
+
+ if (pet.petXpType != null && !pet.petXpType.equalsIgnoreCase(xpType) && !pet.petXpType.equalsIgnoreCase("all")) {
xp = xp / 3f;
if (xpType.equalsIgnoreCase("alchemy") || xpType.equalsIgnoreCase("enchanting")) {
@@ -463,6 +464,7 @@ public class PetInfoOverlay extends TextOverlay {
if (xpType.equalsIgnoreCase("mining") || xpType.equalsIgnoreCase("fishing")) {
xp = xp * 1.5f;
}
+
if (pet.petItem != null) {
Matcher petItemMatcher = XP_BOOST_PATTERN.matcher(pet.petItem);
if ((petItemMatcher.matches() && petItemMatcher.group(1).equalsIgnoreCase(xpType))
@@ -470,6 +472,11 @@ public class PetInfoOverlay extends TextOverlay {
xp = xp * getBoostMultiplier(pet.petItem);
}
}
+ JsonObject pets = Constants.PETS;
+ if (pets != null && pets.has("custom_pet_leveling") && pets.get("custom_pet_leveling").getAsJsonObject().has(pet.petType.toUpperCase()) &&
+ pets.get("custom_pet_leveling").getAsJsonObject().get(pet.petType.toUpperCase()).getAsJsonObject().has("xp_multiplier")) {
+ xp *= pets.get("custom_pet_leveling").getAsJsonObject().get(pet.petType.toUpperCase()).getAsJsonObject().get("xp_multiplier").getAsFloat();
+ }
return xp;
}
@@ -721,16 +728,18 @@ public class PetInfoOverlay extends TextOverlay {
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, false);
+ Vector2f position = getPosition(overlayWidth, overlayHeight, true);
int x = (int) position.x;
- int y = (int) position.y + NotEnoughUpdates.INSTANCE.config.petOverlay.petOverlayText.size() * 10 + 10;
+ int y = (int) position.y + NotEnoughUpdates.INSTANCE.config.petOverlay.petOverlayText.size() * 10;
ItemStack stack = NotEnoughUpdates.INSTANCE.manager.jsonToStack(petItem2);
GlStateManager.enableDepth();
GlStateManager.pushMatrix();
+ Utils.pushGuiScale(NotEnoughUpdates.INSTANCE.config.locationedit.guiScale);
GlStateManager.translate(x - 2, y - 2, 0);
GlStateManager.scale(2, 2, 1);
Utils.drawItemStack(stack, 0, 0);
+ Utils.pushGuiScale(0);
GlStateManager.popMatrix();
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PowerStoneStatsDisplay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PowerStoneStatsDisplay.java
index 975bbe6e..31dd71eb 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PowerStoneStatsDisplay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PowerStoneStatsDisplay.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.options.NEUConfig;
import io.github.moulberry.notenoughupdates.util.ItemUtils;
@@ -39,6 +40,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
+@NEUAutoSubscribe
public class PowerStoneStatsDisplay {
private static PowerStoneStatsDisplay instance = null;
private final NumberFormat format = NumberFormat.getInstance(Locale.US);
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 8a487739..b447cf61 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SlotLocking.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SlotLocking.java
@@ -22,10 +22,13 @@ package io.github.moulberry.notenoughupdates.miscfeatures;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.core.config.KeybindHelper;
import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils;
+import io.github.moulberry.notenoughupdates.events.ReplaceItemEvent;
import io.github.moulberry.notenoughupdates.events.SlotClickEvent;
import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer;
+import io.github.moulberry.notenoughupdates.util.ItemUtils;
import io.github.moulberry.notenoughupdates.util.SBInfo;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.ISound;
@@ -39,7 +42,10 @@ import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
+import net.minecraft.entity.player.InventoryPlayer;
+import net.minecraft.init.Blocks;
import net.minecraft.inventory.Slot;
+import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.GuiScreenEvent;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
@@ -59,6 +65,7 @@ import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
+@NEUAutoSubscribe
public class SlotLocking {
private static final SlotLocking INSTANCE = new SlotLocking();
@@ -416,6 +423,9 @@ public class SlotLocking {
}
drawLinkArrow(x1, y1, x2, y2);
+ setTopHalfBarrier = true;
+ } else {
+ setTopHalfBarrier = false;
}
}
@@ -729,4 +739,27 @@ public class SlotLocking {
return locked != null &&
(locked.locked || (NotEnoughUpdates.INSTANCE.config.slotLocking.bindingAlsoLocks && locked.boundTo != -1));
}
+
+ boolean setTopHalfBarrier = false;
+ @SubscribeEvent
+ public void barrierInventory(ReplaceItemEvent event) {
+ if (event.getSlotNumber() < 9 ||
+ (pairingSlot != null && (event.getSlotNumber() == pairingSlot.slotNumber || isArmourSlot(event.getSlotNumber(), pairingSlot.slotNumber))) ||
+ !setTopHalfBarrier ||
+ !(event.getInventory() instanceof InventoryPlayer)) return;
+ ItemStack stack = new ItemStack(Blocks.barrier);
+ ItemUtils.getOrCreateTag(stack).setBoolean(
+ "NEUHIDETOOLIP",
+ true
+ );
+ event.replaceWith(stack);
+ }
+
+ boolean isArmourSlot(int eventSlotNumber, int pairingSlotNumber) {
+ if (eventSlotNumber == 39 && pairingSlotNumber == 5) return true;
+ if (eventSlotNumber == 38 && pairingSlotNumber == 6) return true;
+ if (eventSlotNumber == 37 && pairingSlotNumber == 7) return true;
+ if (eventSlotNumber == 36 && pairingSlotNumber == 8) return true;
+ return false;
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SunTzu.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SunTzu.java
index 7fc8beba..736d5058 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SunTzu.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/SunTzu.java
@@ -19,6 +19,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScaledResolution;
@@ -30,6 +31,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import java.util.Random;
+@NEUAutoSubscribe
public class SunTzu {
private static boolean enabled = false;
private static int quoteNum = 0;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WardrobeMouseButtons.kt b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WardrobeMouseButtons.kt
index 4e99f5a7..f38d3752 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WardrobeMouseButtons.kt
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WardrobeMouseButtons.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 NotEnoughUpdates contributors
+ * Copyright (C) 2022-2023 NotEnoughUpdates contributors
*
* This file is part of NotEnoughUpdates.
*
@@ -19,12 +19,14 @@
package io.github.moulberry.notenoughupdates.miscfeatures
import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe
import io.github.moulberry.notenoughupdates.core.config.KeybindHelper
import io.github.moulberry.notenoughupdates.util.Utils
import net.minecraft.client.gui.inventory.GuiChest
import net.minecraftforge.client.event.GuiScreenEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+@NEUAutoSubscribe
class WardrobeMouseButtons {
private val keybinds: List<Int> get() = listOf(
@@ -41,8 +43,17 @@ class WardrobeMouseButtons {
private var lastClick = -1L
@SubscribeEvent
- fun onGui(event: GuiScreenEvent) {
- if (!NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.enableWardrobeKeybinds) return
+ fun onGuiKeyboardInput(event: GuiScreenEvent.KeyboardInputEvent.Pre) {
+ checkKeybinds(event)
+ }
+
+ @SubscribeEvent
+ fun onGuiMouseInput(event: GuiScreenEvent.MouseInputEvent.Pre) {
+ checkKeybinds(event)
+ }
+
+ private fun checkKeybinds(event: GuiScreenEvent) {
+ if (!NotEnoughUpdates.INSTANCE.config.wardrobeKeybinds.enableWardrobeKeybinds || !NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return
val gui = event.gui as? GuiChest ?: return
if (!Utils.getOpenChestName().contains("Wardrobe")) return
@@ -51,9 +62,11 @@ class WardrobeMouseButtons {
if (System.currentTimeMillis() - lastClick > 300) {
Utils.sendLeftMouseClick(gui.inventorySlots.windowId, 36 + i)
lastClick = System.currentTimeMillis()
+ event.isCanceled = true
}
break
}
}
}
+
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WitherCloakChanger.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WitherCloakChanger.java
index 02d7bf7b..704606bf 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WitherCloakChanger.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/WitherCloakChanger.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
@@ -33,6 +34,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14;
+@NEUAutoSubscribe
public class WitherCloakChanger {
public static boolean isCloakActive = false;
/**
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/CustomBiomes.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/CustomBiomes.java
index 48a01187..dd97a1f0 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/CustomBiomes.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/CustomBiomes.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures.customblockzones;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.events.OnBlockBreakSoundEffect;
import io.github.moulberry.notenoughupdates.util.SBInfo;
import net.minecraft.block.BlockColored;
@@ -37,6 +38,8 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import java.util.HashMap;
import java.util.Map;
+
+@NEUAutoSubscribe
public class CustomBiomes {
public static final CustomBiomes INSTANCE = new CustomBiomes();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/DwarvenMinesTextures.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/DwarvenMinesTextures.java
index 1c6acc1d..df437fee 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/DwarvenMinesTextures.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/customblockzones/DwarvenMinesTextures.java
@@ -24,6 +24,7 @@ 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.autosubscribe.NEUAutoSubscribe;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Blocks;
@@ -46,6 +47,7 @@ import java.util.Set;
import static io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes.isMithril;
import static io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes.isTitanium;
+@NEUAutoSubscribe
public class DwarvenMinesTextures implements IslandZoneSubdivider {
private static class IgnoreColumn {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/item/enchants/EnchantStyleCustomizer.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/item/enchants/EnchantStyleCustomizer.java
index 47acfa60..82db0b30 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/item/enchants/EnchantStyleCustomizer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/item/enchants/EnchantStyleCustomizer.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures.item.enchants;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.util.LRUCache;
import io.github.moulberry.notenoughupdates.util.LateBindingChroma;
import io.github.moulberry.notenoughupdates.util.Utils;
@@ -33,6 +34,7 @@ import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
+@NEUAutoSubscribe
public class EnchantStyleCustomizer {
public static EnchantStyleCustomizer INSTANCE = new EnchantStyleCustomizer();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/world/EnderNodeHighlighter.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/world/EnderNodeHighlighter.java
index ce0e6a25..51fc950c 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/world/EnderNodeHighlighter.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/world/EnderNodeHighlighter.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures.world;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.events.SpawnParticleEvent;
import io.github.moulberry.notenoughupdates.util.SBInfo;
import io.github.moulberry.notenoughupdates.util.SpecialColour;
@@ -33,6 +34,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import static io.github.moulberry.notenoughupdates.util.MathUtil.basicallyEqual;
+@NEUAutoSubscribe
public class EnderNodeHighlighter extends GenericBlockHighlighter {
private static final EnderNodeHighlighter INSTANCE = new EnderNodeHighlighter();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/world/FrozenTreasuresHighlighter.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/world/FrozenTreasuresHighlighter.java
index a7a8706a..2f8071a0 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/world/FrozenTreasuresHighlighter.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/world/FrozenTreasuresHighlighter.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures.world;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.util.SBInfo;
import io.github.moulberry.notenoughupdates.util.SpecialColour;
import net.minecraft.block.Block;
@@ -34,6 +35,7 @@ import net.minecraftforge.fml.common.gameevent.TickEvent;
import java.util.List;
+@NEUAutoSubscribe
public class FrozenTreasuresHighlighter extends GenericBlockHighlighter {
private static final FrozenTreasuresHighlighter INSTANCE = new FrozenTreasuresHighlighter();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/world/GlowingMushroomHighlighter.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/world/GlowingMushroomHighlighter.java
index fa5794ea..17f5f527 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/world/GlowingMushroomHighlighter.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/world/GlowingMushroomHighlighter.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures.world;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.events.SpawnParticleEvent;
import io.github.moulberry.notenoughupdates.util.SBInfo;
import io.github.moulberry.notenoughupdates.util.SpecialColour;
@@ -33,6 +34,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import static io.github.moulberry.notenoughupdates.util.MathUtil.isDecimalPartApproximately;
+@NEUAutoSubscribe
public class GlowingMushroomHighlighter extends GenericBlockHighlighter {
@SubscribeEvent
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 5f5c4832..48d37f2f 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java
@@ -24,6 +24,7 @@ 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.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.core.BackgroundBlur;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
@@ -66,6 +67,7 @@ import java.util.regex.Pattern;
import static io.github.moulberry.notenoughupdates.util.GuiTextures.help;
+@NEUAutoSubscribe
public class CalendarOverlay {
private static final ResourceLocation BACKGROUND = new ResourceLocation("notenoughupdates:calendar/background.png");
private static final ResourceLocation DISPLAYBAR = new ResourceLocation("notenoughupdates:calendar/displaybar.png");
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java
index aa977413..e81834d3 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java
@@ -28,7 +28,6 @@ import io.github.moulberry.notenoughupdates.recipes.RecipeHistory;
import io.github.moulberry.notenoughupdates.recipes.RecipeSlot;
import io.github.moulberry.notenoughupdates.recipes.RecipeType;
import io.github.moulberry.notenoughupdates.util.Utils;
-import lombok.var;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
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 205dcd83..8ee68457 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/InventoryStorageSelector.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/InventoryStorageSelector.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscgui;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.core.config.KeybindHelper;
import io.github.moulberry.notenoughupdates.miscfeatures.StorageManager;
import io.github.moulberry.notenoughupdates.util.Utils;
@@ -39,7 +40,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
-
+@NEUAutoSubscribe
public class InventoryStorageSelector {
private static final InventoryStorageSelector INSTANCE = new InventoryStorageSelector();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/SignCalculator.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/SignCalculator.java
index ac676a98..4f01e551 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/SignCalculator.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/SignCalculator.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscgui;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.events.SignSubmitEvent;
import io.github.moulberry.notenoughupdates.mixins.AccessorGuiEditSign;
import io.github.moulberry.notenoughupdates.util.Calculator;
@@ -35,6 +36,7 @@ import java.text.DecimalFormat;
import java.math.BigDecimal;
import java.util.Objects;
+@NEUAutoSubscribe
public class SignCalculator {
String lastSource = null;
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 8878c284..5dd8bd9c 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/StorageOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/StorageOverlay.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 NotEnoughUpdates contributors
+ * Copyright (C) 2022-2023 NotEnoughUpdates contributors
*
* This file is part of NotEnoughUpdates.
*
@@ -55,7 +55,6 @@ 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;
@@ -392,6 +391,10 @@ public class StorageOverlay extends GuiElement {
searchTextColour = 0xa0a0a0;
}
+ if (NotEnoughUpdates.INSTANCE.config.storageGUI.useCustomTextColour) {
+ textColour = ChromaColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.storageGUI.customTextColour);
+ }
+
long currentTime = System.currentTimeMillis();
if (lastMillis > 0) {
long deltaTime = currentTime - lastMillis;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java
index 828e50b1..e13934e1 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java
@@ -22,6 +22,7 @@ package io.github.moulberry.notenoughupdates.miscgui;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent;
import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer;
import io.github.moulberry.notenoughupdates.util.Constants;
@@ -50,6 +51,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+@NEUAutoSubscribe
public class TrophyRewardOverlay {
private static TrophyRewardOverlay instance = null;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/MinionHelperManager.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/MinionHelperManager.java
index 512ebb8f..03eb227c 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/MinionHelperManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/MinionHelperManager.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscgui.minionhelper;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.miscgui.minionhelper.loaders.MinionHelperApiLoader;
import io.github.moulberry.notenoughupdates.miscgui.minionhelper.loaders.MinionHelperChatLoader;
import io.github.moulberry.notenoughupdates.miscgui.minionhelper.loaders.MinionHelperInventoryLoader;
@@ -41,6 +42,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+@NEUAutoSubscribe
public class MinionHelperManager {
private static MinionHelperManager instance = null;
private final Map<String, Minion> minions = new HashMap<>();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperChatLoader.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperChatLoader.java
index bef633d2..95277c6a 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperChatLoader.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperChatLoader.java
@@ -60,6 +60,7 @@ public class MinionHelperChatLoader {
String rawTier = ownMatcher.group(1);
int tier = Utils.parseRomanNumeral(rawTier);
String name = ownMatcher.group(2) + " Minion";
+ name = Utils.cleanColour(name);
setCrafted(manager.getMinionByName(name, tier));
}
@@ -80,7 +81,7 @@ public class MinionHelperChatLoader {
} catch (Exception e) {
Utils.addChatMessage(
- "[NEU] §cMinion Helper failed reading the minion upgrade message. See the logs for more info!");
+ "§c[NEU] Minion Helper failed reading the minion upgrade message. See the logs for more info!");
e.printStackTrace();
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlay.java
index 33753d6c..1a625794 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlay.java
@@ -19,6 +19,7 @@
package io.github.moulberry.notenoughupdates.miscgui.minionhelper.render;
+import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.core.util.ArrowPagesUtils;
@@ -28,6 +29,8 @@ import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion;
import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager;
import io.github.moulberry.notenoughupdates.miscgui.minionhelper.render.renderables.OverviewLine;
import io.github.moulberry.notenoughupdates.miscgui.minionhelper.render.renderables.OverviewText;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.MinionSource;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.NpcSource;
import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer;
import io.github.moulberry.notenoughupdates.util.ItemUtils;
import io.github.moulberry.notenoughupdates.util.NotificationHandler;
@@ -72,7 +75,7 @@ public class MinionHelperOverlay {
private boolean filterEnabled = true;
private boolean useInstantBuyPrice = true;
- private int maxPerPage = 8;
+ private int maxPerPage = 7;
private int currentPage = 0;
public MinionHelperOverlay(MinionHelperManager manager) {
@@ -262,18 +265,34 @@ public class MinionHelperOverlay {
for (Map.Entry<String, OverviewLine> entry : renderMap.entrySet()) {
String line = entry.getKey();
+ /*
+ * Renders the part of the string after '§6' and before '§7' with shadows.
+ *
+ * I don't know how to tell mixin to "only capture part x if part y is present"
+ * Therefore I use these bad splits. I'm Sorry!
+ */
if (line.contains("§6")) {
String[] split = line.split("§6");
line = split[0];
String price = "§6§l" + split[1];
+
+ if (price.contains("§8")) {
+ split = price.split("§8");
+ String newPrice = split[0];
+ String stuffBehindPricePart = "§8" + price.substring(newPrice.length() + 2);
+ price = newPrice;
+ int lineLen = Minecraft.getMinecraft().fontRendererObj.getStringWidth(line + price);
+ fontRendererObj.drawString(stuffBehindPricePart, x + lineLen, y, -1, false);
+ }
+
int lineLen = Minecraft.getMinecraft().fontRendererObj.getStringWidth(line);
fontRendererObj.drawString(price, x + lineLen, y, -1, true);
}
fontRendererObj.drawString(line, x, y, -1, false);
i++;
- if (i == 2) {
- y += 15;
+ if (i == 3) {
+ y += 13;
} else {
y += 10;
}
@@ -302,13 +321,14 @@ public class MinionHelperOverlay {
LinkedHashMap<String, OverviewLine> renderMap
) {
int neededForNextSlot = manager.getNeedForNextSlot();
- String color = "§8";
if (neededForNextSlot == -1) {
- renderMap.put(color + "Next slot: ?", new OverviewText(Collections.emptyList(), () -> {}));
+ renderMap.put("§8Next slot: ?", new OverviewText(Collections.emptyList(), () -> {}));
return;
}
double priceNeeded = 0;
+ int peltsNeeded = 0;
+ int northStarsNeeded = 0;
int xpGain = 0;
int index = 0;
for (Minion minion : TrophyRewardOverlay.sortByValue(prices).keySet()) {
@@ -316,12 +336,20 @@ public class MinionHelperOverlay {
priceNeeded += price;
xpGain += minion.getXpGain();
index++;
+ peltsNeeded += getSpecialItemNeeds(minion, "SKYBLOCK_PELT");
+ northStarsNeeded += getSpecialItemNeeds(minion, "SKYBLOCK_NORTH_STAR");
if (index == neededForNextSlot) break;
}
- String format = manager.getPriceCalculation().formatCoins(priceNeeded);
- format = format.replace(" coins", "");
- String text =
- color + "Next slot: §3" + neededForNextSlot + " minions §8- " + format;
+ String costFormat = manager.getPriceCalculation().formatCoins(priceNeeded);
+ costFormat = costFormat.replace(" coins", "");
+
+ if (peltsNeeded > 0) {
+ costFormat = costFormat + " §8+ §5" + peltsNeeded + " Pelts";
+ }
+ if (northStarsNeeded > 0) {
+ costFormat = costFormat + " §8+ §d" + northStarsNeeded + " North Stars";
+ }
+
List<String> lore;
if (xpGain == 0) {
if (index == 0) {
@@ -334,7 +362,25 @@ public class MinionHelperOverlay {
"§8DISCLAIMER: This only works if", "§8you follow the helper."
);
}
- renderMap.put(text, new OverviewText(lore, () -> {}));
+ OverviewText overviewText = new OverviewText(lore, () -> {});
+ renderMap.put("§8Next slot: §3" + neededForNextSlot + " minions", overviewText);
+ renderMap.put("§8Cost: " + costFormat, overviewText);
+ }
+
+ private static int getSpecialItemNeeds(Minion minion, String specialItem) {
+ int count = 0;
+ MinionSource minionSource = minion.getMinionSource();
+
+ if (minionSource instanceof NpcSource) {
+ NpcSource source = (NpcSource) minionSource;
+ ArrayListMultimap<String, Integer> items = source.getItems();
+ if (items.containsKey(specialItem)) {
+ for (Integer amount : items.get(specialItem)) {
+ count += amount;
+ }
+ }
+ }
+ return count;
}
private void addTitle(Map<Minion, Double> prices, LinkedHashMap<String, OverviewLine> renderMap) {
@@ -424,8 +470,8 @@ public class MinionHelperOverlay {
return entry.getValue();
}
i++;
- if (i == 2) {
- y += 15;
+ if (i == 3) {
+ y += 13;
} else {
y += 10;
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperPriceCalculation.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperPriceCalculation.java
index cb43100b..e3614627 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperPriceCalculation.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperPriceCalculation.java
@@ -80,13 +80,14 @@ public class MinionHelperPriceCalculation {
if (source instanceof NpcSource) {
ArrayListMultimap<String, Integer> items = ((NpcSource) source).getItems();
+ // Please hypixel never ever add a minion recipe with pelts and north stars at the same time! Thank you :)
if (items.containsKey("SKYBLOCK_PELT")) {
int amount = items.get("SKYBLOCK_PELT").get(0);
- result += " §7+ §5" + amount + " Pelts";
+ result += " §8+ §5" + amount + " Pelts";
}
if (items.containsKey("SKYBLOCK_NORTH_STAR")) {
int amount = items.get("SKYBLOCK_NORTH_STAR").get(0);
- result += " §7+ §d" + amount + " North Stars";
+ result += " §8+ §d" + amount + " North Stars";
}
}
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 bd1dff63..8aca73d1 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java
@@ -295,8 +295,9 @@ public abstract class MixinGuiContainer extends GuiScreen {
@Redirect(method = "drawScreen", at = @At(value = "INVOKE", target = TARGET_CANBEHOVERED))
public boolean drawScreen_canBeHovered(Slot slot) {
- if (NotEnoughUpdates.INSTANCE.config.improvedSBMenu.hideEmptyPanes &&
- BetterContainers.isOverriding() && BetterContainers.isBlankStack(slot.slotNumber, slot.getStack())) {
+ if ((NotEnoughUpdates.INSTANCE.config.improvedSBMenu.hideEmptyPanes &&
+ BetterContainers.isOverriding() && BetterContainers.isBlankStack(slot.slotNumber, slot.getStack())) ||
+ slot.getStack() != null && slot.getStack().hasTagCompound() && slot.getStack().getTagCompound().getBoolean("NEUHIDETOOLIP")) {
return false;
}
return slot.canBeHovered();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiUtils.java
new file mode 100644
index 00000000..0ad2a098
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiUtils.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023 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 io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraftforge.fml.client.config.GuiUtils;
+import org.lwjgl.input.Mouse;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.ModifyVariable;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import java.util.List;
+
+@Mixin(value = GuiUtils.class, remap = false)
+public class MixinGuiUtils {
+ @Inject(method = "drawHoveringText", at = @At("HEAD"))
+ private static void drawHoveringText_head(
+ List<String> textLines, int mouseX, int mouseY, int screenWidth, int screenHeight, int maxTextWidth, FontRenderer font, CallbackInfo ci) {
+ Utils.pushGuiScale(NotEnoughUpdates.INSTANCE.config.tooltipTweaks.guiScale);
+ }
+
+ @ModifyVariable(method = "drawHoveringText", at = @At(value = "HEAD"), ordinal = 0, argsOnly = true)
+ private static int drawHoveringText_modifyMouseX(int mouseX) {
+ return Mouse.getX() * Utils.pushGuiScale(NotEnoughUpdates.INSTANCE.config.tooltipTweaks.guiScale).getScaledWidth() / Minecraft.getMinecraft().displayWidth;
+ }
+
+ @ModifyVariable(method = "drawHoveringText", at = @At(value = "HEAD"), ordinal = 1, argsOnly = true)
+ private static int drawHoveringText_modifyMouseY(int mouseY) {
+ return Utils.pushGuiScale(NotEnoughUpdates.INSTANCE.config.tooltipTweaks.guiScale).getScaledHeight() -
+ Mouse.getY() * Utils.pushGuiScale(NotEnoughUpdates.INSTANCE.config.tooltipTweaks.guiScale).getScaledHeight() / Minecraft.getMinecraft().displayHeight;
+ }
+
+
+ @ModifyVariable(method = "drawHoveringText", at = @At(value = "HEAD"), ordinal = 2, argsOnly = true)
+ private static int drawHoveringText_modifyWidth(int width) {
+ return Utils.pushGuiScale(NotEnoughUpdates.INSTANCE.config.tooltipTweaks.guiScale).getScaledWidth();
+ }
+
+ @ModifyVariable(method = "drawHoveringText", at = @At(value = "HEAD"), ordinal = 3, argsOnly = true)
+ private static int drawHoveringText_modifyHeight(int height) {
+ return Utils.pushGuiScale(NotEnoughUpdates.INSTANCE.config.tooltipTweaks.guiScale).getScaledHeight();
+ }
+
+ @Inject(method = "drawHoveringText", at = @At("TAIL"))
+ private static void drawHoveringText_tail(
+ List<String> textLines, int mouseX, int mouseY, int screenWidth, int screenHeight, int maxTextWidth, FontRenderer font, CallbackInfo ci) {
+ Utils.resetGuiScale();
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinInventoryPlayer.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinInventoryPlayer.java
index de117002..22e53ae1 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinInventoryPlayer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinInventoryPlayer.java
@@ -19,13 +19,17 @@
package io.github.moulberry.notenoughupdates.mixins;
+import io.github.moulberry.notenoughupdates.events.ReplaceItemEvent;
import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking;
import io.github.moulberry.notenoughupdates.miscgui.InventoryStorageSelector;
import net.minecraft.entity.player.InventoryPlayer;
+import net.minecraft.item.ItemStack;
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;
@Mixin(InventoryPlayer.class)
public class MixinInventoryPlayer {
@@ -42,4 +46,24 @@ public class MixinInventoryPlayer {
SlotLocking.getInstance().changedSlot($this.currentItem);
}
+
+ @Shadow public ItemStack[] mainInventory;
+ @Shadow public ItemStack[] armorInventory;
+
+ @Inject(method = "getStackInSlot", at = @At("HEAD"), cancellable = true)
+ public void on(int index, CallbackInfoReturnable<ItemStack> cir) {
+ ItemStack itemStack =
+ index < mainInventory.length
+ ? this.mainInventory[index]
+ : this.armorInventory[index - mainInventory.length];
+ ReplaceItemEvent replaceItemEventInventory = new ReplaceItemEvent(
+ itemStack,
+ ((InventoryPlayer) (Object) this),
+ index
+ );
+ replaceItemEventInventory.post();
+ if (replaceItemEventInventory.getReplacement() != replaceItemEventInventory.getOriginal()) {
+ cir.setReturnValue(replaceItemEventInventory.getReplacement());
+ }
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinLayerDeadmau5Head.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinLayerDeadmau5Head.java
new file mode 100644
index 00000000..14ae9c74
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinLayerDeadmau5Head.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 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.miscfeatures.entityviewer.GUIClientPlayer;
+import net.minecraft.client.entity.AbstractClientPlayer;
+import net.minecraft.client.renderer.entity.layers.LayerDeadmau5Head;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(LayerDeadmau5Head.class)
+public class MixinLayerDeadmau5Head {
+
+ @Inject(method = "doRenderLayer(Lnet/minecraft/client/entity/AbstractClientPlayer;FFFFFFF)V", at = @At("HEAD"), cancellable = true)
+ public void doRenderLayer(
+ AbstractClientPlayer entitylivingbaseIn, float f, float g, float partialTicks, float h, float i, float j, float scale, CallbackInfo ci) {
+ if (entitylivingbaseIn instanceof GUIClientPlayer) ci.cancel();
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinThreadDownloadImageData.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinThreadDownloadImageData.java
index c6d25a9e..fd4ee495 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinThreadDownloadImageData.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinThreadDownloadImageData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 Linnea Gräf
+ * Copyright (C) 2022-2023 Linnea Gräf
*
* This file is part of NotEnoughUpdates.
*
@@ -30,12 +30,14 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ThreadDownloadImageData.class)
-public class MixinThreadDownloadImageData {
+public class MixinThreadDownloadImageData implements ThreadDownloadImageHook.AccessorThreadDownloadImageData{
@Mutable
@Shadow
@Final
private String imageUrl;
+ private String originalUrl;
+
@Redirect(
method = "<init>",
at = @At(
@@ -44,5 +46,16 @@ public class MixinThreadDownloadImageData {
opcode = Opcodes.PUTFIELD))
public void useHttpsDownloadLinks(ThreadDownloadImageData instance, String value) {
this.imageUrl = ThreadDownloadImageHook.hookThreadImageLink(value);
+ this.originalUrl = value;
+ }
+
+ @Override
+ public String getOriginalUrl() {
+ return originalUrl;
+ }
+
+ @Override
+ public String getPatchedUrl() {
+ return imageUrl;
}
}
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 b82b44c2..74400f59 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
@@ -233,12 +233,31 @@ public class Mining {
@ConfigOption(
name = "Star Cult Tab",
desc = "Only show the star cult timer when tab list is open\n" +
- "\u00A7cThis only works outside of Dwarven Caves!"
+ "§cThis only works outside of Dwarven Caves!"
)
@ConfigEditorBoolean
@ConfigAccordionId(id = 2)
public boolean starCultDisplayOnlyShowTab = false;
+ @Expose
+ @ConfigOption(
+ name = "Commission Task Tips",
+ desc = "Show tips to help complete commission tasks"
+ )
+ @ConfigEditorDropdown(
+ values = {"Off", "Only while sneaking", "Always"}
+ )
+ @ConfigAccordionId(id = 2)
+ public int commissionTaskTips = 0;
+
+ @Expose
+ @ConfigOption(
+ name = "Tips in New Line",
+ desc = "Show the Commission Task Tips in the next line.")
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 2)
+ public boolean commissionTaskTipNewLine = true;
+
@ConfigOption(
name = "Metal Detector Solver",
desc = ""
@@ -738,7 +757,7 @@ public class Mining {
@Expose
@ConfigOption(
name = "Enable Tracker",
- desc = "Show an Overlay with useful information related to Power Grinding"
+ desc = "Show an Overlay with useful information related to Powder Grinding"
)
@ConfigAccordionId(id = 9)
@ConfigEditorBoolean
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 b72610b8..47e51eec 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
@@ -305,8 +305,8 @@ public class Misc {
@Expose
@ConfigOption(
- name = "Dungeon Groups PV",
- desc = "View another player's profile by clicking on the chat message when they join in a dungeon group."
+ name = "Group Join PV",
+ desc = "View another player's profile by clicking on the chat message when they join in a dungeon or kuudra group."
)
@ConfigEditorBoolean
public boolean dungeonGroupsPV = true;
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 30915daa..42a52639 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
@@ -103,4 +103,12 @@ public class ProfileViewer {
)
@ConfigEditorBoolean
public boolean useSoopyNetworth = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Display Weight",
+ desc = "Display Lily and Senither Weight in the Basic PV page"
+ )
+ @ConfigEditorBoolean
+ public boolean displayWeight = true;
}
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 08c48945..131ac669 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
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 NotEnoughUpdates contributors
+ * Copyright (C) 2022-2023 NotEnoughUpdates contributors
*
* This file is part of NotEnoughUpdates.
*
@@ -155,6 +155,26 @@ public class StorageGUI {
@Expose
@ConfigOption(
+ name = "Custom Text Colour",
+ desc = "Use a custom default text colour.\nOverrides the colour set by the overlay style.\nCan be overridden by using colour codes in the page title.",
+ searchTags = "color"
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 1)
+ public boolean useCustomTextColour = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Custom Text Colour",
+ desc = "Requires the above option to be set to true",
+ searchTags = "color"
+ )
+ @ConfigEditorColour
+ @ConfigAccordionId(id = 1)
+ public String customTextColour = "0:255:144:144:144";
+
+ @Expose
+ @ConfigOption(
name = "Scrollable Tooltips",
desc = "Support for scrolling tooltips for users with small monitors\n" +
"This will prevent the menu from scrolling while holding the key, allowing you to scroll tooltips"
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 8539c3c4..45a96577 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
@@ -24,6 +24,7 @@ import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigAccord
import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorAccordion;
import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorBoolean;
import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorDraggableList;
+import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorDropdown;
import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorKeybind;
import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorSlider;
import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption;
@@ -147,6 +148,16 @@ public class TooltipTweaks {
@Expose
@ConfigOption(
+ name = "Resize tooltips",
+ desc = "Resizes tooltips to make them readable"
+ )
+ @ConfigEditorDropdown(
+ values = {"Default", "Small", "Normal", "Large", "Auto"}
+ )
+ public int guiScale = 0;
+
+ @Expose
+ @ConfigOption(
name = "Expand Pet Exp Requirement",
desc = "Show which the full amount of pet xp required"
)
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/EquipmentOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/EquipmentOverlay.java
index 5cd8f6b3..db81bfa4 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/EquipmentOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/EquipmentOverlay.java
@@ -24,6 +24,7 @@ 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.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.events.GuiInventoryBackgroundDrawnEvent;
import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay;
import io.github.moulberry.notenoughupdates.miscgui.GuiInvButtonEditor;
@@ -54,6 +55,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+@NEUAutoSubscribe
public class EquipmentOverlay {
public static EquipmentOverlay INSTANCE = new EquipmentOverlay();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FuelBar.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FuelBar.java
index f2e485f2..9212eb6f 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FuelBar.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FuelBar.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.overlays;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.core.config.Position;
import io.github.moulberry.notenoughupdates.core.config.gui.GuiPositionEditor;
import io.github.moulberry.notenoughupdates.util.SBInfo;
@@ -38,6 +39,7 @@ import org.lwjgl.opengl.GL14;
import java.awt.*;
+@NEUAutoSubscribe
public class FuelBar {
public static final ResourceLocation FUEL_BAR = new ResourceLocation("notenoughupdates:fuel_bar.png");
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 f25407b6..ea253e94 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java
@@ -31,7 +31,6 @@ import io.github.moulberry.notenoughupdates.util.StarCultCalculator;
import io.github.moulberry.notenoughupdates.util.TabListUtils;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.GuiChat;
import net.minecraft.client.gui.inventory.GuiChest;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.init.Items;
@@ -39,10 +38,6 @@ import net.minecraft.inventory.ContainerChest;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
-import net.minecraft.world.WorldSettings;
-import net.minecraftforge.fml.relauncher.Side;
-import net.minecraftforge.fml.relauncher.SideOnly;
-import org.lwjgl.input.Keyboard;
import org.lwjgl.util.vector.Vector2f;
import java.util.ArrayList;
@@ -379,22 +374,35 @@ public class MiningOverlay extends TextTabOverlay {
} else if (entry.getValue() >= 0.25) {
col = GOLD;
}
+ String tips = getTipPart(entry.getKey());
+ boolean newLine = NotEnoughUpdates.INSTANCE.config.mining.commissionTaskTipNewLine;
+ String newLineTip = null;
+ if (newLine) {
+ if (!tips.isEmpty()) {
+ newLineTip = " " + tips;
+ tips = "";
+ }
+ }
NEUConfig.HiddenLocationSpecific locationSpecific = NotEnoughUpdates.INSTANCE.config.getLocationSpecific();
int max;
if (-1 != (max = locationSpecific.commissionMaxes.getOrDefault(entry.getKey(), -1))) {
commissionsStrings.add(
- DARK_AQUA + entry.getKey() + ": " + col + Math.round(entry.getValue() * max) + "/" + max);
+ DARK_AQUA + entry.getKey() + ": " + col + Math.round(entry.getValue() * max) + "/" + max + tips);
} else {
String valS = Utils.floatToString(entry.getValue() * 100, 1);
- commissionsStrings.add(DARK_AQUA + entry.getKey() + ": " + col + valS + "%");
+ commissionsStrings.add(DARK_AQUA + entry.getKey() + ": " + col + valS + "%" + tips);
+ }
+ if (newLineTip != null) {
+ commissionsStrings.add(newLineTip);
}
}
}
if (ItemCooldowns.firstLoadMillis > 0) {
//set cooldown on first skyblock load.
- ItemCooldowns.pickaxeUseCooldownMillisRemaining = 60 * 1000 - (System.currentTimeMillis() - ItemCooldowns.firstLoadMillis);
+ ItemCooldowns.pickaxeUseCooldownMillisRemaining =
+ 60 * 1000 - (System.currentTimeMillis() - ItemCooldowns.firstLoadMillis);
ItemCooldowns.firstLoadMillis = 0;
}
@@ -449,7 +457,7 @@ public class MiningOverlay extends TextTabOverlay {
}
if (starCultDisplay) {
- if(overlayStrings == null) overlayStrings = new ArrayList<>();
+ if (overlayStrings == null) overlayStrings = new ArrayList<>();
if (!NotEnoughUpdates.INSTANCE.config.mining.starCultDisplayOnlyShowTab ||
lastTabState) {
@@ -467,7 +475,7 @@ public class MiningOverlay extends TextTabOverlay {
}
if (forgeDisplay) {
- if(overlayStrings == null) overlayStrings = new ArrayList<>();
+ if (overlayStrings == null) overlayStrings = new ArrayList<>();
if (!NotEnoughUpdates.INSTANCE.config.mining.forgeDisplayOnlyShowTab ||
lastTabState) {
@@ -484,14 +492,97 @@ public class MiningOverlay extends TextTabOverlay {
if (overlayStrings != null && overlayStrings.isEmpty()) overlayStrings = null;
}
+ private String getTipPart(String name) {
+ int settings = NotEnoughUpdates.INSTANCE.config.mining.commissionTaskTips;
+ if (settings == 0) return "";
+
+ if (!Minecraft.getMinecraft().thePlayer.isSneaking() && settings == 1) return "";
+
+ String tip = getTip(name);
+ if (tip == null) return " §4???";
+
+ return " §8§l>§7 " + tip;
+ }
+
+ private String getTip(String name) {
+ if (SBInfo.getInstance().getLocation().equals("mining_3")) { // Dwarven Mines
+ if (name.equals("First Event")) return "Participate in any §6Mining Event";
+
+ // During Event
+ if (name.equals("Lucky Raffle")) return "Collect 20 Raffle Tickets during §6Raffle Event";
+ if (name.equals("Goblin Raid Slayer")) return "Kill 20 Goblins during §6Goblin Raid Event";
+ if (name.equals("Raffle")) return "Participate in §6Raffle Event";
+ if (name.equals("Goblin Raid")) return "Participate in §6Goblin Raid event";
+ if (name.equals("2x Mithril Powder Collector")) return "Collect 500 Mithril Powder during §62x Powder event";
+
+ // Slay
+ if (name.equals("Ice Walker Slayer")) return "Kill 50 Ice Walkers §b(Great Ice Wall)";
+ if (name.equals("Goblin Slayer")) return "Kill 100 Goblins §b(Goblin Borrows)";
+ if (name.equals("Golden Goblin Slayer")) return "Kill 1 Golden Goblin (anywhere)";
+ if (name.equals("Star Sentry Puncher")) return "Damage Star Sentries 10 times (anywhere)";
+
+ // Mining
+ if (name.equals("Mithril Miner")) return "Break 500 Mithril (anywhere)";
+ if (name.equals("Titanium Miner")) return "Break 15 Titanium (anywhere)";
+
+ if (name.equals("Cliffside Veins Mithril")) return "Break 350 Mithril §b(Cliffside Veins)";
+ if (name.equals("Royal Mines Mithril")) return "Break 350 Mithril §b(Royal Mines)";
+ if (name.equals("Lava Springs Mithril")) return "Break 350 Mithril §b(Lava Springs)";
+ if (name.equals("Rampart's Quarry Mithril")) return "Break 350 Mithril §b(Rampart's Quarry)";
+ if (name.equals("Upper Mines Mithril")) return "Break 350 Mithril §b(Upper Mines)";
+
+ if (name.equals("Cliffside Veins Titanium")) return "Break 10 Titanium §b(Cliffside Veins)";
+ if (name.equals("Lava Springs Titanium")) return "Break 10 Titanium §b(Lava Springs)";
+ if (name.equals("Royal Mines Titanium")) return "Break 10 Titanium §b(Royal Mines)";
+ if (name.equals("Rampart's Quarry Titanium")) return "Break 10 Titanium §b(Rampart's Quarry)";
+ if (name.equals("Upper Mines Titanium")) return "Break 10 Titanium §b(Upper Mines)";
+
+ } else if (SBInfo.getInstance().getLocation().equals("crystal_hollows")) { // Crystal Hollows
+ if (name.equals("Chest Looter")) return "Open 3 chests";
+ if (name.equals("Hard Stone Miner")) return "Break 1,000 Hard Stone";
+
+ String jungle = " §a(Jungle)";
+ String goblin = " §6(Golbin Holdout)";
+ String mithril = " §b(Mithril Deposits)";
+ String precursor = " §8(Precursor Remenants)";
+ String magma = " §c(Magma Fields)";
+
+ if (name.equals("Goblin Slayer")) return "Kill 13 Goblins" + goblin;
+ if (name.equals("Sludge Slayer")) return "Kill 25 Sludges" + jungle;
+ if (name.equals("Thyst Slayer")) return "Kill 5 Thysts, when breaking Amethysts" + jungle;
+ if (name.equals("Boss Corleone Slayer")) return "Find and kill Corleone" + mithril;
+ if (name.equals("Yog Slayer")) return "Kill 13 Yogs" + magma;
+ if (name.equals("Automaton Slayer")) return "Kill 13 Automatons" + precursor;
+ if (name.equals("Team Treasurite Member Slayer")) return "Kill 13 Team Treasurite Members" + mithril;
+
+ if (name.endsWith("Crystal Hunter")) {
+ if (name.startsWith("Amethyst")) return "Temple Jump & Run" + jungle;
+ if (name.startsWith("Jade")) return "4 weapons from Mines of Divan" + mithril;
+ if (name.startsWith("Amber")) return "King and Queen" + goblin;
+ if (name.startsWith("Sapphire")) return "6 Robot Parts in Precursor City" + precursor;
+ if (name.startsWith("Topaz")) return "Kill Bal" + magma;
+ }
+
+ if (name.endsWith("Gemstone Collector")) {
+ if (name.startsWith("Amber")) return "Break orange glass" + goblin;
+ if (name.startsWith("Sapphire")) return "Break blue glass" + precursor;
+ if (name.startsWith("Jade")) return "Break green glass" + mithril;
+ if (name.startsWith("Amethyst")) return "Break purple glass" + jungle;
+ if (name.startsWith("Ruby")) return "Break red glass (anywhere)";
+ if (name.startsWith("Topaz")) return "Break yellow glass" + magma;
+ }
+ }
+
+ return null;
+ }
+
private static List<String> getForgeStrings(List<ForgeItem> forgeItems) {
List<String> forgeString = new ArrayList<>();
long currentTimeMillis = System.currentTimeMillis();
forgeIDLabel:
for (int i = 0; i < 5; i++) {
- for (ForgeItem forgeItem : forgeItems) {
- if (forgeItem.forgeID == i) {
- ForgeItem item = forgeItem;
+ for (ForgeItem item : forgeItems) {
+ if (item.forgeID == i) {
if (NotEnoughUpdates.INSTANCE.config.mining.forgeDisplay == 0) {
if (item.status == 2 && item.finishTime < currentTimeMillis) {
@@ -541,7 +632,6 @@ public class MiningOverlay extends TextTabOverlay {
}
}
forgeItems.add(item);
- return;
}
public static class ForgeItem {
@@ -617,6 +707,9 @@ public class MiningOverlay extends TextTabOverlay {
if (!NotEnoughUpdates.INSTANCE.config.mining.dwarvenOverlayIcons) return;
GlStateManager.enableDepth();
+ // No icon for the tip line
+ if (line.contains(">")) return;
+
ItemStack icon = null;
String cleaned = Utils.cleanColour(line);
String beforeColon = cleaned.split(":")[0];
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/PowderGrindingOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/PowderGrindingOverlay.java
index 50ecce90..ad8755e3 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/PowderGrindingOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/PowderGrindingOverlay.java
@@ -19,8 +19,6 @@
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;
@@ -28,26 +26,19 @@ 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;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
public class PowderGrindingOverlay extends TextTabOverlay {
private final static JsonParser PARSER = new JsonParser();
+ private final static Pattern pattern =
+ Pattern.compile("You received \\+([0-9]+(?:,\\d+)*) (Mithril|Gemstone) Powder\\.");
public int chestCount = 0;
public int openedChestCount = 0;
@@ -112,7 +103,8 @@ public class PowderGrindingOverlay extends TextTabOverlay {
overlayStrings.add("\u00a73Opened Chests: \u00a7a" + format.format(this.openedChestCount));
break;
case 2:
- overlayStrings.add("\u00a73Unopened Chests: \u00a7c" + format.format(this.chestCount - this.openedChestCount));
+ overlayStrings.add(
+ "\u00a73Unopened Chests: \u00a7c" + format.format(this.chestCount - this.openedChestCount));
break;
case 3:
overlayStrings.add("\u00a73Mithril Powder Found: \u00a72" +
@@ -141,21 +133,26 @@ public class PowderGrindingOverlay extends TextTabOverlay {
if (overlayStrings != null && overlayStrings.isEmpty()) overlayStrings = null;
}
- public void message(String message) {
+ public void onMessage(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();
+ Matcher matcher = pattern.matcher(message);
+ if (matcher.matches()) {
+ String rawNumber = matcher.group(1).replace(",", "");
+ try {
+ int amount = Integer.parseInt(rawNumber);
+ String type = matcher.group(2);
+ if (type.equals("Mithril")) {
+ this.mithrilPowderFound += amount;
+ } else if (type.equals("Gemstone")) {
+ this.gemstonePowderFound += amount;
+ }
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ }
}
}
}
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 873ee9f2..8a48dd2c 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java
@@ -19,13 +19,13 @@
package io.github.moulberry.notenoughupdates.profileviewer;
-import com.google.common.base.Splitter;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.mojang.authlib.GameProfile;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage;
import io.github.moulberry.notenoughupdates.profileviewer.weight.lily.LilyWeight;
import io.github.moulberry.notenoughupdates.profileviewer.weight.senither.SenitherWeight;
import io.github.moulberry.notenoughupdates.util.Constants;
@@ -53,11 +53,12 @@ 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.opengl.GL14;
import java.awt.*;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -72,6 +73,34 @@ import static io.github.moulberry.notenoughupdates.util.Utils.roundToNearestInt;
public class BasicPage extends GuiProfileViewerPage {
private static final ResourceLocation pv_basic = new ResourceLocation("notenoughupdates:pv_basic.png");
+
+ public static final ItemStack skull = Utils.createSkull(
+ "egirlefe",
+ "152de44a-43a3-46e1-badc-66cca2793471",
+ "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODdkODg1YjMyYjBkZDJkNmI3ZjFiNTgyYTM0MTg2ZjhhNTM3M2M0NjU4OWEyNzM0MjMxMzJiNDQ4YjgwMzQ2MiJ9fX0="
+ );
+
+ private static final LinkedHashMap<String, ItemStack> dungeonsModeIcons = new LinkedHashMap<String, ItemStack>() {
+ {
+ put(
+ "first_page",
+ Utils.editItemStackInfo(
+ new ItemStack(Items.paper),
+ EnumChatFormatting.GRAY + "Front Page",
+ true
+ )
+ );
+ put(
+ "second_page",
+ Utils.editItemStackInfo(
+ skull,
+ EnumChatFormatting.GRAY + "Level Page",
+ true
+ )
+ );
+ }
+ };
+
private static final ExecutorService profileLoader = Executors.newFixedThreadPool(1);
public EntityOtherPlayerMP entityPlayer = null;
private ResourceLocation playerLocationSkin = null;
@@ -88,9 +117,14 @@ public class BasicPage extends GuiProfileViewerPage {
private int backgroundClickedX = -1;
+ private boolean onSecondPage;
+
+ private final LevelPage levelPage;
+
public BasicPage(GuiProfileViewer instance) {
super(instance);
this.guiProfileViewer = instance;
+ this.levelPage = new LevelPage(guiProfileViewer, this);
}
@Override
@@ -101,6 +135,11 @@ public class BasicPage extends GuiProfileViewerPage {
int guiLeft = GuiProfileViewer.getGuiLeft();
int guiTop = GuiProfileViewer.getGuiTop();
+ if (onSecondPage) {
+ levelPage.drawPage(mouseX, mouseY);
+ return;
+ }
+
String location = null;
JsonObject status = profile.getPlayerStatus();
if (status != null && status.has("mode")) {
@@ -280,7 +319,7 @@ public class BasicPage extends GuiProfileViewerPage {
EnumChatFormatting.GREEN + "Net Worth: " + EnumChatFormatting.GOLD +
GuiProfileViewer.numberFormat.format(networth),
fr,
- guiLeft + 63,
+ guiLeft + 165,
guiTop + 38,
true,
0
@@ -297,11 +336,10 @@ public class BasicPage extends GuiProfileViewerPage {
);
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))
- ) {
- if (mouseY > guiTop + 32 && mouseY < guiTop + 32 + fr.FONT_HEIGHT) {
+
+ int fontWidth = fr.getStringWidth("Net Worth: " + GuiProfileViewer.numberFormat.format(networth));
+ if (mouseX > guiLeft + 165 - fontWidth / 2 && mouseX < guiLeft + 165 + fontWidth / 2) {
+ if (mouseY > guiTop + 32 && mouseY < guiTop + 38 + fr.FONT_HEIGHT) {
getInstance().tooltipToDisplay = new ArrayList<>();
getInstance()
.tooltipToDisplay.add(
@@ -349,7 +387,7 @@ public class BasicPage extends GuiProfileViewerPage {
Utils.drawStringCentered(
EnumChatFormatting.GREEN + "Net Worth: " + stateStr,
fr,
- guiLeft + 63,
+ guiLeft + 165,
guiTop + 38,
true,
0
@@ -534,116 +572,29 @@ public class BasicPage extends GuiProfileViewerPage {
);
}
- PlayerStats.Stats stats = profile.getStats(profileId);
+ // sb lvlL
- if (stats != null) {
- Splitter splitter = Splitter.on(" ").omitEmptyStrings().limit(2);
- for (int i = 0; i < PlayerStats.defaultStatNames.length; i++) {
- String statName = PlayerStats.defaultStatNames[i];
- //if (statName.equals("mining_fortune") || statName.equals("mining_speed")) continue;
- String statNamePretty = PlayerStats.defaultStatNamesPretty[i];
+ int sbLevelX = guiLeft + 162;
+ int sbLevelY = guiTop + 90;
- int val = Math.round(stats.get(statName));
+ double skyblockLevel = profile.getSkyblockLevel(profileId);
+ EnumChatFormatting skyblockLevelColour = profile.getSkyblockLevelColour(profileId);
- GlStateManager.color(1, 1, 1, 1);
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(
- GL11.GL_SRC_ALPHA,
- GL11.GL_ONE_MINUS_SRC_ALPHA,
- GL11.GL_ONE,
- GL11.GL_ONE_MINUS_SRC_ALPHA
- );
- Utils.renderAlignedString(
- statNamePretty,
- EnumChatFormatting.WHITE.toString() + val,
- guiLeft + 132,
- guiTop + 21 + 11f * i,
- 80
- );
+ GlStateManager.pushMatrix();
+ GlStateManager.translate(sbLevelX, sbLevelY, 0);
+ GlStateManager.scale(1.5f, 1.5f, 1);
+ Utils.drawItemStack(skull, 0, 0);
+ GlStateManager.popMatrix();
+ Utils.drawStringScaled(skyblockLevelColour.toString() + (int) skyblockLevel, fr,
+ sbLevelX - 2, sbLevelY - 15, true, 0, 1.5f
+ );
- if (mouseX > guiLeft + 132 && mouseX < guiLeft + 212) {
- if (mouseY > guiTop + 21 + 11f * i && mouseY < guiTop + 37 + 11f * i) {
- List<String> split = splitter.splitToList(statNamePretty);
- PlayerStats.Stats baseStats = PlayerStats.getBaseStats();
- getInstance().tooltipToDisplay = new ArrayList<>();
- getInstance().tooltipToDisplay.add(statNamePretty);
- int base = Math.round(baseStats.get(statName));
- getInstance()
- .tooltipToDisplay.add(
- EnumChatFormatting.GRAY +
- "Base " +
- split.get(1) +
- ": " +
- EnumChatFormatting.GREEN +
- base +
- " " +
- split.get(0)
- );
- int passive = Math.round(profile.getPassiveStats(profileId).get(statName) - baseStats.get(statName));
- getInstance()
- .tooltipToDisplay.add(
- EnumChatFormatting.GRAY +
- "Passive " +
- split.get(1) +
- " Bonus: +" +
- EnumChatFormatting.YELLOW +
- passive +
- " " +
- split.get(0)
- );
- int itemBonus = Math.round(stats.get(statName) - profile.getPassiveStats(profileId).get(statName));
- getInstance()
- .tooltipToDisplay.add(
- EnumChatFormatting.GRAY +
- "Item " +
- split.get(1) +
- " Bonus: +" +
- EnumChatFormatting.DARK_PURPLE +
- itemBonus +
- " " +
- split.get(0)
- );
- int finalStat = Math.round(stats.get(statName));
- getInstance()
- .tooltipToDisplay.add(
- EnumChatFormatting.GRAY +
- "Final " +
- split.get(1) +
- ": +" +
- EnumChatFormatting.RED +
- finalStat +
- " " +
- split.get(0)
- );
- }
- }
- }
- } else {
- Utils.drawStringCentered(
- EnumChatFormatting.RED + "Skill/Inv/Coll",
- Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 172,
- guiTop + 101 - 10,
- true,
- 0
- );
- Utils.drawStringCentered(
- EnumChatFormatting.RED + "APIs not",
- Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 172,
- guiTop + 101,
- true,
- 0
- );
- Utils.drawStringCentered(
- EnumChatFormatting.RED + "enabled!",
- Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 172,
- guiTop + 101 + 10,
- true,
- 0
- );
- }
+ float progress = (float) (skyblockLevel - (long) skyblockLevel);
+ getInstance().renderBar(sbLevelX - 30, sbLevelY + 30, 80, progress);
+
+ Utils.drawStringScaled(EnumChatFormatting.YELLOW.toString() + (int) (progress * 100) + "/100", fr,
+ sbLevelX - 30, sbLevelY + 20, true, 0, 0.9f
+ );
if (skyblockInfo != null) {
int position = 0;
@@ -672,6 +623,12 @@ public class BasicPage extends GuiProfileViewerPage {
getInstance().renderBar(x, y + 6, 80, level.level % 1);
}
+ if (mouseX >= guiLeft + 128 && mouseX <= guiLeft + 216) {
+ if (mouseY >= guiTop + 69 && mouseY <= guiTop + 131) {
+ if (Mouse.isButtonDown(0)) onSecondPage = true;
+ }
+ }
+
if (mouseX > x && mouseX < x + 80) {
if (mouseY > y - 4 && mouseY < y + 13) {
getInstance().tooltipToDisplay = new ArrayList<>();
@@ -691,7 +648,7 @@ public class BasicPage extends GuiProfileViewerPage {
"/" +
StringUtils.shortNumberFormat(maxXp));
}
- String totalXpS = GuiProfileViewer.numberFormat.format((int) level.totalXp);
+ String totalXpS = GuiProfileViewer.numberFormat.format((long) level.totalXp);
tooltipToDisplay.add(EnumChatFormatting.GRAY + "Total XP: " + EnumChatFormatting.DARK_PURPLE + totalXpS +
EnumChatFormatting.DARK_GRAY + " (" +
DECIMAL_FORMAT.format(guiProfileViewer.getPercentage(entry.getKey().toLowerCase(), level)) +
@@ -759,7 +716,8 @@ public class BasicPage extends GuiProfileViewerPage {
);
}
- renderWeight(mouseX, mouseY, skyblockInfo, profileInfo);
+ drawSideButtons();
+ if (NotEnoughUpdates.INSTANCE.config.profileViewer.displayWeight) renderWeight(mouseX, mouseY, skyblockInfo, profileInfo);
}
private String getIcon(String gameModeType) {
@@ -830,14 +788,13 @@ public class BasicPage extends GuiProfileViewerPage {
weight = profile.getSoopyWeightLeaderboardPosition();
}
-
Utils.drawStringCentered(
EnumChatFormatting.GREEN +
"Senither Weight: " +
EnumChatFormatting.GOLD +
GuiProfileViewer.numberFormat.format(roundToNearestInt(senitherWeight.getTotalWeight().getRaw())),
fr,
- guiLeft + 63,
+ guiLeft + 165,
guiTop + 18,
true,
0
@@ -847,7 +804,7 @@ public class BasicPage extends GuiProfileViewerPage {
"Senither Weight: " +
GuiProfileViewer.numberFormat.format(roundToNearestInt(senitherWeight.getTotalWeight().getRaw()))
);
- if (mouseX > guiLeft + 63 - textWidth / 2 && mouseX < guiLeft + 63 + textWidth / 2) {
+ if (mouseX > guiLeft + 165 - textWidth / 2 && mouseX < guiLeft + 165 + textWidth / 2) {
if (mouseY > guiTop + 12 && mouseY < guiTop + 12 + fr.FONT_HEIGHT) {
getInstance().tooltipToDisplay = new ArrayList<>();
getInstance()
@@ -905,7 +862,7 @@ public class BasicPage extends GuiProfileViewerPage {
EnumChatFormatting.GOLD +
GuiProfileViewer.numberFormat.format(roundToNearestInt(lilyWeight.getTotalWeight().getRaw())),
fr,
- guiLeft + 63,
+ guiLeft + 165,
guiTop + 28,
true,
0
@@ -914,7 +871,7 @@ public class BasicPage extends GuiProfileViewerPage {
int fontWidth = fr.getStringWidth(
"Lily Weight: " + GuiProfileViewer.numberFormat.format(roundToNearestInt(lilyWeight.getTotalWeight().getRaw()))
);
- if (mouseX > guiLeft + 63 - fontWidth / 2 && mouseX < guiLeft + 63 + fontWidth / 2) {
+ if (mouseX > guiLeft + 165 - fontWidth / 2 && mouseX < guiLeft + 165 + fontWidth / 2) {
if (mouseY > guiTop + 22 && mouseY < guiTop + 22 + fr.FONT_HEIGHT) {
getInstance().tooltipToDisplay = new ArrayList<>();
getInstance()
@@ -992,10 +949,62 @@ public class BasicPage extends GuiProfileViewerPage {
GlStateManager.setActiveTexture(OpenGlHelper.defaultTexUnit);
}
+ @Override
+ public boolean mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
+ super.mouseClicked(mouseX, mouseY, mouseButton);
+ int guiLeft = GuiProfileViewer.getGuiLeft();
+ int guiTop = GuiProfileViewer.getGuiTop();
+
+ int i = onSlotToChangePage(mouseX, mouseY, guiLeft, guiTop);
+ switch (i) {
+ case 1:
+ onSecondPage = false;
+ break;
+ case 2:
+ onSecondPage = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return false;
+ }
+
+ public int onSlotToChangePage(int mouseX, int mouseY, int guiLeft, int guiTop) {
+ if (mouseX >= guiLeft - 29 && mouseX <= guiLeft) {
+ if (mouseY >= guiTop && mouseY <= guiTop + 28) {
+ return 1;
+ } else if (mouseY + 28 >= guiTop && mouseY <= guiTop + 28 * 2) {
+ return 2;
+ }
+ }
+ return 0;
+ }
+
public String getGameModeType(JsonObject profileInfo) {
if (profileInfo != null && profileInfo.has("game_mode")) {
return profileInfo.get("game_mode").getAsString();
}
return "";
}
+
+ public void drawSideButtons() {
+ GlStateManager.enableDepth();
+ GlStateManager.translate(0, 0, 5);
+ if (onSecondPage) {
+ Utils.drawPvSideButton(1, dungeonsModeIcons.get("second_page"), true, guiProfileViewer);
+ } else {
+ Utils.drawPvSideButton(0, dungeonsModeIcons.get("first_page"), true, guiProfileViewer);
+ }
+ GlStateManager.translate(0, 0, -3);
+
+ GlStateManager.translate(0, 0, -2);
+ if (!onSecondPage) {
+ Utils.drawPvSideButton(1, dungeonsModeIcons.get("second_page"), false, guiProfileViewer);
+ } else {
+ Utils.drawPvSideButton(0, dungeonsModeIcons.get("first_page"), false, guiProfileViewer);
+ }
+ GlStateManager.disableDepth();
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CollectionsPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CollectionsPage.java
index 554e204c..45d9370b 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CollectionsPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CollectionsPage.java
@@ -24,6 +24,7 @@ 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;
+import io.github.moulberry.notenoughupdates.util.hypixelapi.ProfileCollectionInfo;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.item.ItemStack;
@@ -35,6 +36,9 @@ import org.lwjgl.opengl.GL11;
import java.awt.*;
import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Iterator;
@@ -87,7 +91,8 @@ public class CollectionsPage extends GuiProfileViewerPage {
Minecraft.getMinecraft().getTextureManager().bindTexture(pv_cols);
Utils.drawTexturedRect(guiLeft, guiTop, getInstance().sizeX, getInstance().sizeY, GL11.GL_NEAREST);
- JsonObject collectionInfo = GuiProfileViewer.getProfile().getCollectionInfo(GuiProfileViewer.getProfileId());
+ ProfileCollectionInfo collectionInfo =
+ GuiProfileViewer.getProfile().getCollectionInfo(GuiProfileViewer.getProfileId());
if (collectionInfo == null) {
Utils.drawStringCentered(
EnumChatFormatting.RED + "Collection API not enabled!",
@@ -197,110 +202,114 @@ public class CollectionsPage extends GuiProfileViewerPage {
4210752
);
- JsonObject minionTiers = collectionInfo.get("minion_tiers").getAsJsonObject();
- JsonObject collectionTiers = collectionInfo.get("collection_tiers").getAsJsonObject();
- JsonObject maxAmounts = collectionInfo.get("max_amounts").getAsJsonObject();
- JsonObject totalAmounts = collectionInfo.get("total_amounts").getAsJsonObject();
- JsonObject personalAmounts = collectionInfo.get("personal_amounts").getAsJsonObject();
-
if (collections != null) {
for (int i = page * 20, j = 0; i < Math.min((page + 1) * 20, collections.size()); i++, j++) {
String collection = collections.get(i);
- if (collection != null) {
- ItemStack collectionItem = ProfileViewer.getCollectionToCollectionDisplayMap().get(collection);
- if (collectionItem != null) {
- int xIndex = j % COLLS_XCOUNT;
- int yIndex = j / COLLS_XCOUNT;
-
- float x = 39 + COLLS_XPADDING + (COLLS_XPADDING + 20) * xIndex;
- float y = 7 + COLLS_YPADDING + (COLLS_YPADDING + 20) * yIndex;
-
- String tierString;
- int tier = (int) Utils.getElementAsFloat(collectionTiers.get(collection), 0);
- if (tier > 20 || tier < 0) {
- tierString = String.valueOf(tier);
- } else {
- tierString = romans[tier];
- }
- float amount = Utils.getElementAsFloat(totalAmounts.get(collection), 0);
- float maxAmount = Utils.getElementAsFloat(maxAmounts.get(collection), 0);
- Color color = new Color(128, 128, 128, 255);
- int tierStringColour = color.getRGB();
- float completedness = 0;
- if (maxAmount > 0) {
- completedness = amount / maxAmount;
- }
- completedness = Math.min(1, completedness);
- if (maxAmounts.has(collection) && completedness >= 1) {
- tierStringColour = new Color(255, 215, 0).getRGB();
- }
-
- GlStateManager.color(1, 1, 1, 1);
- Minecraft.getMinecraft().getTextureManager().bindTexture(pv_elements);
- Utils.drawTexturedRect(
- guiLeft + x,
- guiTop + y,
- 20,
- 20 * (1 - completedness),
- 0,
- 20 / 256f,
- 0,
- 20 * (1 - completedness) / 256f,
- GL11.GL_NEAREST
- );
- GlStateManager.color(1, 185 / 255f, 0, 1);
- Minecraft.getMinecraft().getTextureManager().bindTexture(pv_elements);
- Utils.drawTexturedRect(
- guiLeft + x,
- guiTop + y + 20 * (1 - completedness),
- 20,
- 20 * (completedness),
- 0,
- 20 / 256f,
- 20 * (1 - completedness) / 256f,
- 20 / 256f,
- GL11.GL_NEAREST
+ if (collection == null) {
+ continue;
+ }
+ ProfileCollectionInfo.CollectionInfo thisCollection = collectionInfo.getCollections().get(collection);
+ if (thisCollection == null) {
+ Utils.showOutdatedRepoNotification();
+ continue;
+ }
+ ItemStack collectionItem = ProfileViewer.getCollectionToCollectionDisplayMap().get(collection);
+ if (collectionItem == null) {
+ continue;
+ }
+ int xIndex = j % COLLS_XCOUNT;
+ int yIndex = j / COLLS_XCOUNT;
+
+ float x = 39 + COLLS_XPADDING + (COLLS_XPADDING + 20) * xIndex;
+ float y = 7 + COLLS_YPADDING + (COLLS_YPADDING + 20) * yIndex;
+
+ String tierString;
+ int tier = thisCollection.getUnlockedTiers().size();
+ if (tier > 20 || tier == 0) {
+ tierString = String.valueOf(tier);
+ } else {
+ tierString = romans[tier - 1];
+ }
+ BigInteger amount = thisCollection.getTotalCollectionCount();
+ BigInteger maxAmount = BigInteger.valueOf(thisCollection.getCollection().getTiers().get(thisCollection.getCollection().getTiers().size() - 1).getAmountRequired());
+ Color color = new Color(128, 128, 128, 255);
+ int tierStringColour = color.getRGB();
+ float completedness = 0;
+ if (maxAmount.compareTo(BigInteger.ZERO) > 0) {
+ if (amount.compareTo(maxAmount) > 0) {
+ completedness = 1;
+ } else {
+ completedness = amount.floatValue() / maxAmount.floatValue();
+ }
+ }
+ if (completedness >= 1) {
+ tierStringColour = new Color(255, 215, 0).getRGB();
+ }
+
+ GlStateManager.color(1, 1, 1, 1);
+ Minecraft.getMinecraft().getTextureManager().bindTexture(pv_elements);
+ Utils.drawTexturedRect(
+ guiLeft + x,
+ guiTop + y,
+ 20,
+ 20 * (1 - completedness),
+ 0,
+ 20 / 256f,
+ 0,
+ 20 * (1 - completedness) / 256f,
+ GL11.GL_NEAREST
+ );
+ GlStateManager.color(1, 185 / 255f, 0, 1);
+ Minecraft.getMinecraft().getTextureManager().bindTexture(pv_elements);
+ Utils.drawTexturedRect(
+ guiLeft + x,
+ guiTop + y + 20 * (1 - completedness),
+ 20,
+ 20 * (completedness),
+ 0,
+ 20 / 256f,
+ 20 * (1 - completedness) / 256f,
+ 20 / 256f,
+ GL11.GL_NEAREST
+ );
+ Utils.drawItemStack(collectionItem, guiLeft + (int) x + 2, guiTop + (int) y + 2);
+
+ if (mouseX > guiLeft + (int) x + 2 && mouseX < guiLeft + (int) x + 18) {
+ if (mouseY > guiTop + (int) y + 2 && mouseY < guiTop + (int) y + 18) {
+ tooltipToDisplay = new ArrayList<>();
+ tooltipToDisplay.add(
+ collectionItem.getDisplayName() +
+ " " +
+ (completedness >= 1 ? EnumChatFormatting.GOLD : EnumChatFormatting.GRAY) +
+ tierString
);
- Utils.drawItemStack(collectionItem, guiLeft + (int) x + 2, guiTop + (int) y + 2);
-
- if (mouseX > guiLeft + (int) x + 2 && mouseX < guiLeft + (int) x + 18) {
- if (mouseY > guiTop + (int) y + 2 && mouseY < guiTop + (int) y + 18) {
- tooltipToDisplay = new ArrayList<>();
- tooltipToDisplay.add(
- collectionItem.getDisplayName() +
- " " +
- (completedness >= 1 ? EnumChatFormatting.GOLD : EnumChatFormatting.GRAY) +
- tierString
- );
- tooltipToDisplay.add(
- "Collected: " + numberFormat.format(Utils.getElementAsFloat(personalAmounts.get(collection), 0))
- );
- tooltipToDisplay.add("Total Collected: " + numberFormat.format(amount));
- }
- }
-
- GlStateManager.color(1, 1, 1, 1);
- if (tier >= 0) {
- Utils.drawStringCentered(
- tierString,
- Minecraft.getMinecraft().fontRendererObj,
- guiLeft + x + 10,
- guiTop + y - 4,
- true,
- tierStringColour
- );
- }
-
- Utils.drawStringCentered(
- StringUtils.shortNumberFormat(amount) + "",
- Minecraft.getMinecraft().fontRendererObj,
- guiLeft + x + 10,
- guiTop + y + 26,
- true,
- color.getRGB()
+ tooltipToDisplay.add(
+ "Collected: " + numberFormat.format(thisCollection.getPersonalCollectionCount())
);
+ tooltipToDisplay.add("Total Collected: " + numberFormat.format(amount));
}
}
+
+ GlStateManager.color(1, 1, 1, 1);
+ if (tier >= 0) {
+ Utils.drawStringCentered(
+ tierString,
+ Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + x + 10,
+ guiTop + y - 4,
+ true,
+ tierStringColour
+ );
+ }
+
+ Utils.drawStringCentered(
+ StringUtils.shortNumberFormat(amount) + "",
+ Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + x + 10,
+ guiTop + y + 26,
+ true,
+ color.getRGB()
+ );
}
}
@@ -316,97 +325,99 @@ public class CollectionsPage extends GuiProfileViewerPage {
if (minions != null) {
for (int i = page * 20, j = 0; i < Math.min((page + 1) * 20, minions.size()); i++, j++) {
String minion = minions.get(i);
- if (minion != null) {
- JsonObject misc = Constants.MISC;
- float MAX_MINION_TIER = Utils.getElementAsFloat(Utils.getElement(misc, "minions." + minion + "_GENERATOR"), 11);
-
- int tier = (int) Utils.getElementAsFloat(minionTiers.get(minion), 0);
- JsonObject minionJson;
- if (tier == 0) {
- minionJson = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(minion + "_GENERATOR_1");
- } else {
- minionJson = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(minion + "_GENERATOR_" + tier);
- }
+ if (minion == null) {
+ continue;
+ }
+ JsonObject misc = Constants.MISC;
+ float MAX_MINION_TIER = Utils.getElementAsFloat(Utils.getElement(misc, "minions." + minion + "_GENERATOR"), 11);
- if (minionJson != null) {
- int xIndex = j % COLLS_XCOUNT;
- int yIndex = j / COLLS_XCOUNT;
-
- float x = 231 + COLLS_XPADDING + (COLLS_XPADDING + 20) * xIndex;
- float y = 7 + COLLS_YPADDING + (COLLS_YPADDING + 20) * yIndex;
-
- String tierString;
-
- if (tier - 1 >= romans.length || tier - 1 < 0) {
- tierString = String.valueOf(tier);
- } else {
- tierString = romans[tier - 1];
- }
-
- Color color = new Color(128, 128, 128, 255);
- int tierStringColour = color.getRGB();
- float completedness = tier / MAX_MINION_TIER;
-
- completedness = Math.min(1, completedness);
- if (completedness >= 1) {
- tierStringColour = new Color(255, 215, 0).getRGB();
- }
-
- GlStateManager.color(1, 1, 1, 1);
- Minecraft.getMinecraft().getTextureManager().bindTexture(pv_elements);
- Utils.drawTexturedRect(
- guiLeft + x,
- guiTop + y,
- 20,
- 20 * (1 - completedness),
- 0,
- 20 / 256f,
- 0,
- 20 * (1 - completedness) / 256f,
- GL11.GL_NEAREST
- );
- GlStateManager.color(1, 185 / 255f, 0, 1);
- Minecraft.getMinecraft().getTextureManager().bindTexture(pv_elements);
- Utils.drawTexturedRect(
- guiLeft + x,
- guiTop + y + 20 * (1 - completedness),
- 20,
- 20 * (completedness),
- 0,
- 20 / 256f,
- 20 * (1 - completedness) / 256f,
- 20 / 256f,
- GL11.GL_NEAREST
- );
+ int tier = collectionInfo.getCraftedGenerators().getOrDefault(minion, 0);
+ JsonObject minionJson;
+ if (tier == 0) {
+ minionJson = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(minion + "_GENERATOR_1");
+ } else {
+ minionJson = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(minion + "_GENERATOR_" + tier);
+ }
- Utils.drawItemStack(
- NotEnoughUpdates.INSTANCE.manager.jsonToStack(minionJson),
- guiLeft + (int) x + 2,
- guiTop + (int) y + 2
- );
+ if (minionJson == null) {
+ continue;
+ }
+ int xIndex = j % COLLS_XCOUNT;
+ int yIndex = j / COLLS_XCOUNT;
+
+ float x = 231 + COLLS_XPADDING + (COLLS_XPADDING + 20) * xIndex;
+ float y = 7 + COLLS_YPADDING + (COLLS_YPADDING + 20) * yIndex;
+
+ String tierString;
+
+ if (tier - 1 >= romans.length || tier - 1 < 0) {
+ tierString = String.valueOf(tier);
+ } else {
+ tierString = romans[tier - 1];
+ }
+
+ Color color = new Color(128, 128, 128, 255);
+ int tierStringColour = color.getRGB();
+ float completedness = tier / MAX_MINION_TIER;
+
+ completedness = Math.min(1, completedness);
+ if (completedness >= 1) {
+ tierStringColour = new Color(255, 215, 0).getRGB();
+ }
- if (mouseX > guiLeft + (int) x + 2 && mouseX < guiLeft + (int) x + 18) {
- if (mouseY > guiTop + (int) y + 2 && mouseY < guiTop + (int) y + 18) {
- tooltipToDisplay =
- NotEnoughUpdates.INSTANCE.manager
- .jsonToStack(minionJson)
- .getTooltip(Minecraft.getMinecraft().thePlayer, false);
- }
- }
-
- GlStateManager.color(1, 1, 1, 1);
- if (tier >= 0) {
- Utils.drawStringCentered(
- tierString,
- Minecraft.getMinecraft().fontRendererObj,
- guiLeft + x + 10,
- guiTop + y - 4,
- true,
- tierStringColour
- );
- }
+ GlStateManager.color(1, 1, 1, 1);
+ Minecraft.getMinecraft().getTextureManager().bindTexture(pv_elements);
+ Utils.drawTexturedRect(
+ guiLeft + x,
+ guiTop + y,
+ 20,
+ 20 * (1 - completedness),
+ 0,
+ 20 / 256f,
+ 0,
+ 20 * (1 - completedness) / 256f,
+ GL11.GL_NEAREST
+ );
+ GlStateManager.color(1, 185 / 255f, 0, 1);
+ Minecraft.getMinecraft().getTextureManager().bindTexture(pv_elements);
+ Utils.drawTexturedRect(
+ guiLeft + x,
+ guiTop + y + 20 * (1 - completedness),
+ 20,
+ 20 * (completedness),
+ 0,
+ 20 / 256f,
+ 20 * (1 - completedness) / 256f,
+ 20 / 256f,
+ GL11.GL_NEAREST
+ );
+
+ Utils.drawItemStack(
+ NotEnoughUpdates.INSTANCE.manager.jsonToStack(minionJson),
+ guiLeft + (int) x + 2,
+ guiTop + (int) y + 2
+ );
+
+ if (mouseX > guiLeft + (int) x + 2 && mouseX < guiLeft + (int) x + 18) {
+ if (mouseY > guiTop + (int) y + 2 && mouseY < guiTop + (int) y + 18) {
+ tooltipToDisplay =
+ NotEnoughUpdates.INSTANCE.manager
+ .jsonToStack(minionJson)
+ .getTooltip(Minecraft.getMinecraft().thePlayer, false);
}
}
+
+ GlStateManager.color(1, 1, 1, 1);
+ if (tier >= 0) {
+ Utils.drawStringCentered(
+ tierString,
+ Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + x + 10,
+ guiTop + y - 4,
+ true,
+ tierStringColour
+ );
+ }
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CrimsonIslePage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CrimsonIslePage.java
index 95009b1d..6460003a 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CrimsonIslePage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CrimsonIslePage.java
@@ -55,15 +55,12 @@ public class CrimsonIslePage extends GuiProfileViewerPage {
NotEnoughUpdates.INSTANCE.manager.createItem("KUUDRA_INFERNAL_TIER_KEY"),
};
- public static final String[] KUUDRA_TIERS = {
- "Basic",
- "Hot",
- "Burning",
- "Fiery",
- "Infernal"
- };
+ private static final String[] KUUDRA_TIERS_NAME = {"Basic", "Hot", "Burning", "Fiery", "Infernal"};
+
+ // This is different to the one above as these refer to the names of the tiers in the API
+ public static final String[] KUUDRA_TIERS = {"none", "hot", "burning", "fiery", "infernal"};
- private static final LinkedHashMap<String, String> apiDojoTestNames = new LinkedHashMap<String, String>() {{
+ public static final LinkedHashMap<String, String> apiDojoTestNames = new LinkedHashMap<String, String>() {{
put("mob_kb", EnumChatFormatting.GOLD + "Test of Force");
put("wall_jump", EnumChatFormatting.LIGHT_PURPLE + "Test of Stamina");
put("archer", EnumChatFormatting.YELLOW + "Test of Mastery");
@@ -73,7 +70,7 @@ public class CrimsonIslePage extends GuiProfileViewerPage {
put("fireball", EnumChatFormatting.GOLD + "Test of Tenacity");
}};
- private static final LinkedHashMap<Integer, String> dojoPointsToRank = new LinkedHashMap<Integer, String>() {{
+ public static final LinkedHashMap<Integer, String> dojoPointsToRank = new LinkedHashMap<Integer, String>() {{
put(0, EnumChatFormatting.GRAY + "None");
put(1000, EnumChatFormatting.YELLOW + "Yellow");
put(2000, EnumChatFormatting.GREEN + "Green");
@@ -151,21 +148,18 @@ public class CrimsonIslePage extends GuiProfileViewerPage {
JsonObject kuudraCompletedTiers = data.getAsJsonObject("kuudra_completed_tiers");
- // This is different to the one initialised at the start of the class as these refer to the names of the tiers in the API
- String[] kuudraTiers = {"none", "hot", "burning", "fiery", "infernal"};
-
RenderHelper.enableGUIStandardItemLighting();
for (int i = 0; i < 5; i++) {
// Checking the player has completions for each tier
// and get the number of completions if they do
int completions =
- kuudraCompletedTiers.has(kuudraTiers[i]) ? kuudraCompletedTiers.get(kuudraTiers[i]).getAsInt() : 0;
+ kuudraCompletedTiers.has(KUUDRA_TIERS[i]) ? kuudraCompletedTiers.get(KUUDRA_TIERS[i]).getAsInt() : 0;
// Get the highest wave for this tier of kuudra if they have completed a run
// since infernal kuudra was released
- int highestWaveCompleted = kuudraCompletedTiers.has("highest_wave_" + kuudraTiers[i]) ?
- kuudraCompletedTiers.get("highest_wave_" + kuudraTiers[i]).getAsInt() : 0;
+ int highestWaveCompleted = kuudraCompletedTiers.has("highest_wave_" + KUUDRA_TIERS[i]) ?
+ kuudraCompletedTiers.get("highest_wave_" + KUUDRA_TIERS[i]).getAsInt() : 0;
Minecraft.getMinecraft().getRenderItem().renderItemIntoGUI(
KUUDRA_KEYS[i],
@@ -174,7 +168,7 @@ public class CrimsonIslePage extends GuiProfileViewerPage {
);
Utils.renderAlignedString(
- EnumChatFormatting.RED + KUUDRA_TIERS[i] + ": ",
+ EnumChatFormatting.RED + KUUDRA_TIERS_NAME[i] + ": ",
EnumChatFormatting.WHITE + String.valueOf(completions),
guiLeft + 23,
guiTop + 30 + (i * 30),
@@ -190,7 +184,8 @@ public class CrimsonIslePage extends GuiProfileViewerPage {
);
if (highestWaveCompleted == 0) {
- if (mouseX > guiLeft + 23 && mouseX < guiLeft + 133 && mouseY < guiTop + 50 + (i*30) && mouseY > guiTop + 42 + (i*30)) {
+ if (mouseX > guiLeft + 23 && mouseX < guiLeft + 133 && mouseY < guiTop + 50 + (i * 30) &&
+ mouseY > guiTop + 42 + (i * 30)) {
getInstance().tooltipToDisplay = new ArrayList<>();
getInstance().tooltipToDisplay.add(EnumChatFormatting.RED + "N/A will only show for highest wave");
getInstance().tooltipToDisplay.add(EnumChatFormatting.RED + "if you have not completed a run for");
@@ -278,7 +273,7 @@ public class CrimsonIslePage extends GuiProfileViewerPage {
);
}
- public String getRank(int points) {
+ public static String getRank(int points) {
int lastRank = 0;
for (Map.Entry<Integer, String> rank : dojoPointsToRank.entrySet()) {
if (points < rank.getKey()) {
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 cbebb6f4..9d227daf 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java
@@ -42,7 +42,6 @@ import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
-import org.lwjgl.opengl.GL14;
import java.io.IOException;
import java.util.Base64;
@@ -54,7 +53,7 @@ public class DungeonPage extends GuiProfileViewerPage {
private static final ResourceLocation pv_dung = new ResourceLocation("notenoughupdates:pv_dung.png");
private static final ItemStack DEADBUSH = new ItemStack(Item.getItemFromBlock(Blocks.deadbush));
- private static final String[] dungSkillsName = { "Healer", "Mage", "Berserk", "Archer", "Tank" };
+ private static final String[] dungSkillsName = {"Healer", "Mage", "Berserk", "Archer", "Tank"};
private static final ItemStack[] BOSS_HEADS = new ItemStack[7];
private static final ItemStack[] dungSkillsStack = {
new ItemStack(Items.potionitem, 1, 16389),
@@ -63,7 +62,7 @@ public class DungeonPage extends GuiProfileViewerPage {
new ItemStack(Items.bow),
new ItemStack(Items.leather_chestplate),
};
- private static final String[] bossFloorArr = { "Bonzo", "Scarf", "Professor", "Thorn", "Livid", "Sadan", "Necron" };
+ private static final String[] bossFloorArr = {"Bonzo", "Scarf", "Professor", "Thorn", "Livid", "Sadan", "Necron"};
private static final String[] bossFloorHeads = {
"12716ecbf5b8da00b05f316ec6af61e8bd02805b21eb8e440151468dc656549c",
"7de7bbbdf22bfe17980d4e20687e386f11d59ee1db6f8b4762391b79a5ac532d",
@@ -145,7 +144,7 @@ public class DungeonPage extends GuiProfileViewerPage {
//Catacombs level thingy
{
if (levelObjCata == null) {
- float cataXp = Utils.getElementAsFloat(Utils.getElement(profileInfo, "dungeons.dungeon_types.catacombs.experience"), 0);
+ float cataXp = getElementAsFloat(profileInfo, "dungeons.dungeon_types.catacombs.experience");
levelObjCata =
ProfileViewer.getLevel(
Utils.getElementOrDefault(leveling, "catacombs", new JsonArray()).getAsJsonArray(),
@@ -181,11 +180,20 @@ public class DungeonPage extends GuiProfileViewerPage {
if (mouseX > x && mouseX < x + sectionWidth && mouseY > y + 16 && mouseY < y + 24 && !onMasterMode) {
float F5 =
- (Utils.getElementAsFloat(Utils.getElement(profileInfo, "dungeons.dungeon_types.catacombs.tier_completions." + 5), 0)); //this can prob be done better
+ (Utils.getElementAsFloat(Utils.getElement(
+ profileInfo,
+ "dungeons.dungeon_types.catacombs.tier_completions." + 5
+ ), 0)); //this can prob be done better
float F6 =
- (Utils.getElementAsFloat(Utils.getElement(profileInfo, "dungeons.dungeon_types.catacombs.tier_completions." + 6), 0));
+ (Utils.getElementAsFloat(Utils.getElement(
+ profileInfo,
+ "dungeons.dungeon_types.catacombs.tier_completions." + 6
+ ), 0));
float F7 =
- (Utils.getElementAsFloat(Utils.getElement(profileInfo, "dungeons.dungeon_types.catacombs.tier_completions." + 7), 0));
+ (Utils.getElementAsFloat(Utils.getElement(
+ profileInfo,
+ "dungeons.dungeon_types.catacombs.tier_completions." + 7
+ ), 0));
if (F5 > 150) {
F5 = 150;
}
@@ -208,43 +216,23 @@ public class DungeonPage extends GuiProfileViewerPage {
long runsF6 = (int) Math.ceil(floorLevelToXP / xpF6);
long runsF7 = (int) Math.ceil(floorLevelToXP / xpF7);
- float timeF5 = Utils.getElementAsFloat(
- Utils.getElement(profileInfo, "dungeons.dungeon_types.catacombs.fastest_time_s_plus.5"),
- 0
- );
- float timeF6 = Utils.getElementAsFloat(
- Utils.getElement(profileInfo, "dungeons.dungeon_types.catacombs.fastest_time_s_plus.6"),
- 0
- );
- float timeF7 = Utils.getElementAsFloat(
- Utils.getElement(profileInfo, "dungeons.dungeon_types.catacombs.fastest_time_s_plus.7"),
- 0
- );
+ float timeF5 = getElementAsFloat(profileInfo, "dungeons.dungeon_types.catacombs.fastest_time_s_plus.5");
+ float timeF6 = getElementAsFloat(profileInfo, "dungeons.dungeon_types.catacombs.fastest_time_s_plus.6");
+ float timeF7 = getElementAsFloat(profileInfo, "dungeons.dungeon_types.catacombs.fastest_time_s_plus.7");
getInstance().tooltipToDisplay =
Lists.newArrayList(
- EnumChatFormatting.YELLOW + "Remaining XP: " + EnumChatFormatting.GRAY + String.format("%,d", floorLevelToXP),
+ EnumChatFormatting.YELLOW + "Remaining XP: " + EnumChatFormatting.GRAY +
+ String.format("%,d", floorLevelToXP),
String.format("# F5 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpF5), runsF5),
String.format("# F6 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpF6), runsF6),
String.format("# F7 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpF7), runsF7),
""
);
boolean hasTime = false;
- if (timeF5 > 1000) {
- getInstance()
- .tooltipToDisplay.add(String.format("Expected Time (F5) : %s", Utils.prettyTime(runsF5 * (long) (timeF5 * 1.2))));
- hasTime = true;
- }
- if (timeF6 > 1000) {
- getInstance()
- .tooltipToDisplay.add(String.format("Expected Time (F6) : %s", Utils.prettyTime(runsF6 * (long) (timeF6 * 1.2))));
- hasTime = true;
- }
- if (timeF7 > 1000) {
- getInstance()
- .tooltipToDisplay.add(String.format("Expected Time (F7) : %s", Utils.prettyTime(runsF7 * (long) (timeF7 * 1.2))));
- hasTime = true;
- }
+ hasTime = isHasTime(timeF5, "Expected Time (F5) : %s", runsF5, hasTime);
+ hasTime = isHasTime(timeF6, "Expected Time (F6) : %s", runsF6, hasTime);
+ hasTime = isHasTime(timeF7, "Expected Time (F7) : %s", runsF7, hasTime);
if (hasTime) {
getInstance().tooltipToDisplay.add("");
}
@@ -261,19 +249,20 @@ public class DungeonPage extends GuiProfileViewerPage {
getInstance()
.tooltipToDisplay.add(
"The " +
- EnumChatFormatting.DARK_PURPLE +
- "Catacombs Expert Ring" +
- EnumChatFormatting.GRAY +
- " is assumed to be used, unless " +
- EnumChatFormatting.YELLOW +
- "SHIFT" +
- EnumChatFormatting.GRAY +
- " is held."
+ EnumChatFormatting.DARK_PURPLE +
+ "Catacombs Expert Ring" +
+ EnumChatFormatting.GRAY +
+ " is assumed to be used, unless " +
+ EnumChatFormatting.YELLOW +
+ "SHIFT" +
+ EnumChatFormatting.GRAY +
+ " is held."
);
getInstance().tooltipToDisplay.add("[Time per run] is calculated using Fastest S+ x 120%");
} else {
getInstance()
- .tooltipToDisplay.add("[Hold " + EnumChatFormatting.YELLOW + "CTRL" + EnumChatFormatting.GRAY + " to see details]");
+ .tooltipToDisplay.add(
+ "[Hold " + EnumChatFormatting.YELLOW + "CTRL" + EnumChatFormatting.GRAY + " to see details]");
}
}
@@ -348,63 +337,29 @@ public class DungeonPage extends GuiProfileViewerPage {
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"),
- 0
- );
- float timeM4 = Utils.getElementAsFloat(
- Utils.getElement(profileInfo, "dungeons.dungeon_types.master_catacombs.fastest_time_s_plus.4"),
- 0
- );
- float timeM5 = Utils.getElementAsFloat(
- Utils.getElement(profileInfo, "dungeons.dungeon_types.master_catacombs.fastest_time_s_plus.5"),
- 0
- );
- float timeM6 = Utils.getElementAsFloat(
- 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
- );
+ float timeM3 = getElementAsFloat(profileInfo, "dungeons.dungeon_types.master_catacombs.fastest_time_s_plus.3");
+ float timeM4 = getElementAsFloat(profileInfo, "dungeons.dungeon_types.master_catacombs.fastest_time_s_plus.4");
+ float timeM5 = getElementAsFloat(profileInfo, "dungeons.dungeon_types.master_catacombs.fastest_time_s_plus.5");
+ float timeM6 = getElementAsFloat(profileInfo, "dungeons.dungeon_types.master_catacombs.fastest_time_s_plus.6");
+ float timeM7 = getElementAsFloat(profileInfo, "dungeons.dungeon_types.master_catacombs.fastest_time_s_plus.7");
getInstance().tooltipToDisplay =
Lists.newArrayList(
- EnumChatFormatting.YELLOW + "Remaining XP: " + EnumChatFormatting.GRAY + String.format("%,d", floorLevelToXP),
+ EnumChatFormatting.YELLOW + "Remaining XP: " + EnumChatFormatting.GRAY +
+ String.format("%,d", floorLevelToXP),
String.format("# M3 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpM3), runsM3),
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),
+ String.format("# M7 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpM7), runsM7),
""
);
boolean hasTime = false;
- if (timeM3 > 1000) {
- getInstance()
- .tooltipToDisplay.add(String.format("Expected Time (M3) : %s", Utils.prettyTime(runsM3 * (long) (timeM3 * 1.2))));
- hasTime = true;
- }
- if (timeM4 > 1000) {
- getInstance()
- .tooltipToDisplay.add(String.format("Expected Time (M4) : %s", Utils.prettyTime(runsM4 * (long) (timeM4 * 1.2))));
- hasTime = true;
- }
- if (timeM5 > 1000) {
- getInstance()
- .tooltipToDisplay.add(String.format("Expected Time (M5) : %s", Utils.prettyTime(runsM5 * (long) (timeM5 * 1.2))));
- hasTime = true;
- }
- if (timeM6 > 1000) {
- getInstance()
- .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;
- }
+ hasTime = isHasTime(timeM3, "Expected Time (M3) : %s", runsM3, hasTime);
+ hasTime = isHasTime(timeM4, "Expected Time (M4) : %s", runsM4, hasTime);
+ hasTime = isHasTime(timeM5, "Expected Time (M5) : %s", runsM5, hasTime);
+ hasTime = isHasTime(timeM6, "Expected Time (M6) : %s", runsM6, hasTime);
+ hasTime = isHasTime(timeM7, "Expected Time (M7) : %s", runsM7, hasTime);
if (hasTime) {
getInstance().tooltipToDisplay.add("");
}
@@ -421,26 +376,32 @@ public class DungeonPage extends GuiProfileViewerPage {
getInstance()
.tooltipToDisplay.add(
"The " +
- EnumChatFormatting.DARK_PURPLE +
- "Catacombs Expert Ring" +
- EnumChatFormatting.GRAY +
- " is assumed to be used, unless " +
- EnumChatFormatting.YELLOW +
- "SHIFT" +
- EnumChatFormatting.GRAY +
- " is held."
+ EnumChatFormatting.DARK_PURPLE +
+ "Catacombs Expert Ring" +
+ EnumChatFormatting.GRAY +
+ " is assumed to be used, unless " +
+ EnumChatFormatting.YELLOW +
+ "SHIFT" +
+ EnumChatFormatting.GRAY +
+ " is held."
);
getInstance().tooltipToDisplay.add("[Time per run] is calculated using Fastest S+ x 120%");
} else {
getInstance()
- .tooltipToDisplay.add("[Hold " + EnumChatFormatting.YELLOW + "CTRL" + EnumChatFormatting.GRAY + " to see details]");
+ .tooltipToDisplay.add(
+ "[Hold " + EnumChatFormatting.YELLOW + "CTRL" + EnumChatFormatting.GRAY + " to see details]");
}
}
dungeonLevelTextField.setSize(20, 10);
dungeonLevelTextField.render(x + 22, y + 29);
int calcLen = fontRendererObj.getStringWidth("Calculate");
- Utils.renderShadowedString(EnumChatFormatting.WHITE + "Calculate", x + sectionWidth - 17 - calcLen / 2f, y + 30, 100);
+ Utils.renderShadowedString(
+ EnumChatFormatting.WHITE + "Calculate",
+ x + sectionWidth - 17 - calcLen / 2f,
+ y + 30,
+ 100
+ );
//Random stats
@@ -451,10 +412,7 @@ public class DungeonPage extends GuiProfileViewerPage {
float totalRunsF = 0;
float totalRunsF5 = 0;
for (int i = 1; i <= 7; i++) {
- float runs = Utils.getElementAsFloat(
- Utils.getElement(profileInfo, "dungeons.dungeon_types.catacombs.tier_completions." + i),
- 0
- );
+ float runs = getElementAsFloat(profileInfo, "dungeons.dungeon_types.catacombs.tier_completions." + i);
totalRunsF += runs;
if (i >= 5) {
totalRunsF5 += runs;
@@ -463,10 +421,7 @@ public class DungeonPage extends GuiProfileViewerPage {
float totalRunsM = 0;
float totalRunsM5 = 0;
for (int i = 1; i <= 7; i++) {
- float runs = Utils.getElementAsFloat(
- Utils.getElement(profileInfo, "dungeons.dungeon_types.master_catacombs.tier_completions." + i),
- 0
- );
+ float runs = getElementAsFloat(profileInfo, "dungeons.dungeon_types.master_catacombs.tier_completions." + i);
totalRunsM += runs;
if (i >= 5) {
totalRunsM5 += runs;
@@ -477,18 +432,12 @@ public class DungeonPage extends GuiProfileViewerPage {
float mobKills;
float mobKillsF = 0;
for (int i = 1; i <= 7; i++) {
- float kills = Utils.getElementAsFloat(
- Utils.getElement(profileInfo, "dungeons.dungeon_types.catacombs.mobs_killed." + i),
- 0
- );
+ float kills = getElementAsFloat(profileInfo, "dungeons.dungeon_types.catacombs.mobs_killed." + i);
mobKillsF += kills;
}
float mobKillsM = 0;
for (int i = 1; i <= 7; i++) {
- float kills = Utils.getElementAsFloat(
- Utils.getElement(profileInfo, "dungeons.dungeon_types.master_catacombs.mobs_killed." + i),
- 0
- );
+ float kills = getElementAsFloat(profileInfo, "dungeons.dungeon_types.master_catacombs.mobs_killed." + i);
mobKillsM += kills;
}
mobKills = mobKillsF + mobKillsM;
@@ -518,7 +467,8 @@ public class DungeonPage extends GuiProfileViewerPage {
);
Utils.renderAlignedString(
EnumChatFormatting.YELLOW + "Secrets (/Run) ",
- EnumChatFormatting.WHITE.toString() + (secrets == -1 ? "?" : (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
@@ -538,40 +488,16 @@ public class DungeonPage extends GuiProfileViewerPage {
int bx = x + sectionWidth * i / 8 - w / 2;
- boolean invert = i == floorTime;
- float uMin = 20 / 256f;
- float uMax = 29 / 256f;
- float vMin = 0 / 256f;
- float vMax = 11 / 256f;
-
GlStateManager.color(1, 1, 1, 1);
- Minecraft.getMinecraft().getTextureManager().bindTexture(GuiProfileViewer.pv_elements);
- Utils.drawTexturedRect(
- bx - 2,
- y3 - 2,
- 9,
- 11,
- invert ? uMax : uMin,
- invert ? uMin : uMax,
- invert ? vMax : vMin,
- invert ? vMin : vMax,
- GL11.GL_NEAREST
- );
Utils.renderShadowedString(EnumChatFormatting.WHITE.toString() + i, bx + w / 2, y3, 10);
}
- float timeNorm = Utils.getElementAsFloat(
- Utils.getElement(profileInfo, "dungeons.dungeon_types." + dungeonString + ".fastest_time." + floorTime),
- 0
- );
- float timeS = Utils.getElementAsFloat(
- Utils.getElement(profileInfo, "dungeons.dungeon_types." + dungeonString + ".fastest_time_s." + floorTime),
- 0
- );
- float timeSPLUS = Utils.getElementAsFloat(
- Utils.getElement(profileInfo, "dungeons.dungeon_types." + dungeonString + ".fastest_time_s_plus." + floorTime),
- 0
+ float timeNorm = getElementAsFloat(profileInfo, "dungeons.dungeon_types." + dungeonString + ".fastest_time." + floorTime);
+ float timeS = getElementAsFloat(profileInfo, "dungeons.dungeon_types." + dungeonString + ".fastest_time_s." + floorTime);
+ float timeSPLUS = getElementAsFloat(
+ profileInfo,
+ "dungeons.dungeon_types." + dungeonString + ".fastest_time_s_plus." + floorTime
);
String timeNormStr = timeNorm <= 0 ? "N/A" : Utils.prettyTime((long) timeNorm);
String timeSStr = timeS <= 0 ? "N/A" : Utils.prettyTime((long) timeS);
@@ -606,15 +532,13 @@ public class DungeonPage extends GuiProfileViewerPage {
Utils.renderShadowedString(EnumChatFormatting.RED + "Boss Collections", x + sectionWidth / 2, y, sectionWidth);
for (int i = 1; i <= 7; i++) {
- float compl = Utils.getElementAsFloat(
- Utils.getElement(profileInfo, "dungeons.dungeon_types." + dungeonString + ".tier_completions." + i),
- 0
- );
+ float compl = getElementAsFloat(profileInfo, "dungeons.dungeon_types." + dungeonString + ".tier_completions." + i);
if (BOSS_HEADS[i - 1] == null) {
String textureLink = bossFloorHeads[i - 1];
- String b64Decoded = "{\"textures\":{\"SKIN\":{\"url\":\"http://textures.minecraft.net/texture/" + textureLink + "\"}}}";
+ 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);
@@ -646,7 +570,11 @@ public class DungeonPage extends GuiProfileViewerPage {
GlStateManager.popMatrix();
Utils.renderAlignedString(
- String.format(EnumChatFormatting.YELLOW + "%s (" + (onMasterMode ? "M" : "F") + "%d) ", bossFloorArr[i - 1], i),
+ String.format(
+ EnumChatFormatting.YELLOW + "%s (" + (onMasterMode ? "M" : "F") + "%d) ",
+ bossFloorArr[i - 1],
+ i
+ ),
EnumChatFormatting.WHITE.toString() + (int) compl,
x + 16,
y + 18 + 20 * (i - 1),
@@ -662,7 +590,12 @@ public class DungeonPage extends GuiProfileViewerPage {
//Gui.drawRect(x, y, x+120, y+147, 0xffffffff);
- Utils.renderShadowedString(EnumChatFormatting.DARK_PURPLE + "Class Levels", x + sectionWidth / 2, y, sectionWidth);
+ Utils.renderShadowedString(
+ EnumChatFormatting.DARK_PURPLE + "Class Levels",
+ x + sectionWidth / 2,
+ y,
+ sectionWidth
+ );
JsonElement activeClassElement = Utils.getElement(profileInfo, "dungeons.selected_dungeon_class");
String activeClass = null;
@@ -675,12 +608,12 @@ public class DungeonPage extends GuiProfileViewerPage {
for (int i = 0; i < dungSkillsName.length; i++) {
String skillName = dungSkillsName[i];
- HashMap<String, ProfileViewer.Level> levelObjClasses = levelObjClasseses.computeIfAbsent(profileId, k -> new HashMap<>());
+ HashMap<String, ProfileViewer.Level> levelObjClasses = levelObjClasseses.computeIfAbsent(
+ profileId,
+ k -> new HashMap<>()
+ );
if (!levelObjClasses.containsKey(skillName)) {
- float cataXp = Utils.getElementAsFloat(
- Utils.getElement(profileInfo, "dungeons.player_classes." + skillName.toLowerCase() + ".experience"),
- 0
- );
+ float cataXp = getElementAsFloat(profileInfo, "dungeons.player_classes." + skillName.toLowerCase() + ".experience");
ProfileViewer.Level levelObj = ProfileViewer.getLevel(
Utils.getElementOrDefault(leveling, "catacombs", new JsonArray()).getAsJsonArray(),
cataXp,
@@ -708,7 +641,16 @@ public class DungeonPage extends GuiProfileViewerPage {
ProfileViewer.Level levelObj = levelObjClasses.get(skillName);
getInstance()
- .renderXpBar(colour + skillName, dungSkillsStack[i], x, y + 20 + 24 * i, sectionWidth, levelObj, mouseX, mouseY);
+ .renderXpBar(
+ colour + skillName,
+ dungSkillsStack[i],
+ x,
+ y + 20 + 24 * i,
+ sectionWidth,
+ levelObj,
+ mouseX,
+ mouseY
+ );
}
getInstance().renderXpBar(
@@ -718,12 +660,29 @@ public class DungeonPage extends GuiProfileViewerPage {
y + 20 + 24 * 5,
sectionWidth,
classAverage,
- mouseX, mouseY);
+ mouseX, mouseY
+ );
}
drawSideButtons();
}
+ private boolean isHasTime(float fastestTime, String format, long runsAmount, boolean hasTime) {
+ if (fastestTime > 1000) {
+ getInstance()
+ .tooltipToDisplay.add(String.format(
+ format,
+ Utils.prettyTime(runsAmount * (long) (fastestTime * 1.2))
+ ));
+ hasTime = true;
+ }
+ return hasTime;
+ }
+
+ private static float getElementAsFloat(JsonObject profileInfo, String path) {
+ return Utils.getElementAsFloat(Utils.getElement(profileInfo, path), 0);
+ }
+
@Override
public boolean mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
FontRenderer fontRendererObj = Minecraft.getMinecraft().fontRendererObj;
@@ -737,7 +696,8 @@ public class DungeonPage extends GuiProfileViewerPage {
}
int cW = fontRendererObj.getStringWidth("Calculate");
- if (mouseX >= guiLeft + 23 + 110 - 17 - cW && mouseX <= guiLeft + 23 + 110 - 17 && mouseY >= guiTop + 55 && mouseY <= guiTop + 65) {
+ if (mouseX >= guiLeft + 23 + 110 - 17 - cW && mouseX <= guiLeft + 23 + 110 - 17 && mouseY >= guiTop + 55 &&
+ mouseY <= guiTop + 65) {
calculateFloorLevelXP();
}
@@ -774,66 +734,21 @@ public class DungeonPage extends GuiProfileViewerPage {
GlStateManager.enableDepth();
GlStateManager.translate(0, 0, 5);
if (onMasterMode) {
- drawSideButton(1, dungeonsModeIcons.get("master_catacombs"), true);
+ Utils.drawPvSideButton(1, dungeonsModeIcons.get("master_catacombs"), true, getInstance());
} else {
- drawSideButton(0, dungeonsModeIcons.get("catacombs"), true);
+ Utils.drawPvSideButton(0, dungeonsModeIcons.get("catacombs"), true, getInstance());
}
GlStateManager.translate(0, 0, -3);
GlStateManager.translate(0, 0, -2);
if (!onMasterMode) {
- drawSideButton(1, dungeonsModeIcons.get("master_catacombs"), false);
+ Utils.drawPvSideButton(1, dungeonsModeIcons.get("master_catacombs"), false, getInstance());
} else {
- drawSideButton(0, dungeonsModeIcons.get("catacombs"), false);
+ Utils.drawPvSideButton(0, dungeonsModeIcons.get("catacombs"), false, getInstance());
}
GlStateManager.disableDepth();
}
- private void drawSideButton(int yIndex, ItemStack itemStack, boolean pressed) {
- int guiLeft = GuiProfileViewer.getGuiLeft();
- int guiTop = GuiProfileViewer.getGuiTop();
-
- GlStateManager.disableLighting();
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.enableAlpha();
- GlStateManager.alphaFunc(516, 0.1F);
-
- int x = guiLeft - 28;
- int y = guiTop + yIndex * 28;
-
- float uMin = 193 / 256f;
- float uMax = 223 / 256f;
- float vMin = 200 / 256f;
- float vMax = 228 / 256f;
- if (pressed) {
- uMin = 224 / 256f;
- uMax = 1f;
-
- if (yIndex != 0) {
- vMin = 228 / 256f;
- vMax = 1f;
- }
-
- getInstance().renderBlurredBackground(getInstance().width, getInstance().height, x + 2, y + 2, 30, 28 - 4);
- } else {
- getInstance().renderBlurredBackground(getInstance().width, getInstance().height, x + 2, y + 2, 28 - 2, 28 - 4);
- }
-
- GlStateManager.disableLighting();
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.enableAlpha();
- GlStateManager.alphaFunc(516, 0.1F);
-
- Minecraft.getMinecraft().getTextureManager().bindTexture(GuiProfileViewer.pv_elements);
-
- Utils.drawTexturedRect(x, y, pressed ? 32 : 28, 28, uMin, uMax, vMin, vMax, GL11.GL_NEAREST);
-
- GlStateManager.enableDepth();
- Utils.drawItemStack(itemStack, x + 8, y + 7);
- }
-
private void calculateFloorLevelXP() {
JsonObject leveling = Constants.LEVELING;
if (leveling == null) return;
@@ -852,7 +767,7 @@ public class DungeonPage extends GuiProfileViewerPage {
if (level < Math.floor(levelObjCata.level)) {
continue;
}
- remaining += levelingArray.get(level).getAsFloat();
+ remaining += levelingArray.get(level).getAsFloat();
}
if (remaining < 0) {
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 59c78dda..90ffd388 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java
@@ -94,7 +94,7 @@ public class ExtraPage extends GuiProfileViewerPage {
}
// pls update in the future tyvm !!!
- final static HashMap<String, Integer> slayers = new HashMap<String, Integer>() {
+ public final static HashMap<String, Integer> slayers = new HashMap<String, Integer>() {
{
put("zombie", 5);
put("spider", 4);
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 4bf65cc6..c379c7eb 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
@@ -171,7 +171,10 @@ public class GuiProfileViewer extends GuiScreen {
);
public final GuiElementTextField playerNameTextField;
public final GuiElementTextField inventoryTextField = new GuiElementTextField("", GuiElementTextField.SCALE_TEXT);
- public final GuiElementTextField killDeathSearchTextField = 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;
@@ -390,7 +393,7 @@ public class GuiProfileViewer extends GuiScreen {
GL11.GL_NEAREST
);
Utils.drawStringCenteredScaledMaxWidth(
- "Open in Skycrypt",
+ "Open in SkyCrypt",
Minecraft.getMinecraft().fontRendererObj,
guiLeft + 50 + 100 + 6,
guiTop + sizeY + 3 + 10,
@@ -838,8 +841,9 @@ public class GuiProfileViewer extends GuiScreen {
profileId != null
) {
if (mouseY > guiTop + sizeY + 3 && mouseY < guiTop + sizeY + 23) {
- String url = "https://sky.shiiyu.moe/stats/" + profile.getHypixelProfile().get("displayname").getAsString() + "/" +
- profileId;
+ String url =
+ "https://sky.shiiyu.moe/stats/" + profile.getHypixelProfile().get("displayname").getAsString() + "/" +
+ profileId;
Utils.openUrl(url);
Utils.playPressSound();
return;
@@ -960,14 +964,17 @@ public class GuiProfileViewer extends GuiScreen {
String totalXpStr = null;
if (skillName.contains("Catacombs")) {
totalXpStr = EnumChatFormatting.GRAY + "Total XP: " + EnumChatFormatting.DARK_PURPLE +
- numberFormat.format(levelObj.totalXp) + EnumChatFormatting.DARK_GRAY + " (" +
+ numberFormat.format(levelObj.totalXp) + EnumChatFormatting.DARK_GRAY + " (" +
DECIMAL_FORMAT.format(getPercentage(skillName.toLowerCase(), levelObj)) + "% to 50)";
}
- // Adds overflow level to each level object that is maxed, avoids hotm level as there is no overflow xp for it
+ // Adds overflow level to each level object that is maxed, avoids hotm level as there is no overflow xp for it
if (levelObj.maxed) {
levelStr = levelObj.maxLevel != 7 ?
- EnumChatFormatting.GOLD + "MAXED!" + EnumChatFormatting.GRAY + " (Overflow level: " + String.format("%.2f", levelObj.level) + ")" :
- EnumChatFormatting.GOLD + "MAXED!";
+ EnumChatFormatting.GOLD + "MAXED!" + EnumChatFormatting.GRAY + " (Overflow level: " + String.format(
+ "%.2f",
+ levelObj.level
+ ) + ")" :
+ EnumChatFormatting.GOLD + "MAXED!";
} else {
if (skillName.contains("Class Average")) {
levelStr = "Progress: " + EnumChatFormatting.DARK_PURPLE + String.format("%.1f", (level % 1 * 100)) + "%";
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 a981183a..164f5d78 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java
@@ -154,7 +154,7 @@ public class InventoriesPage extends GuiProfileViewerPage {
getInstance().tooltipToDisplay = entry.getValue().getTooltip(Minecraft.getMinecraft().thePlayer, false);
if (Objects.equals(entry.getKey(), "talisman_bag")) {
StringBuilder magicalPowerString = new StringBuilder(EnumChatFormatting.DARK_GRAY + "Magical Power: ");
- int magicalPower = PlayerStats.getMagicalPower(inventoryInfo, profileInformation);
+ int magicalPower = profile.getMagicalPower(profileId);
getInstance()
.tooltipToDisplay.add(
magicalPower == -1
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java
index 56ecd3a2..9be3eaf4 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java
@@ -170,12 +170,14 @@ public class PlayerStats {
return skillBonus;
}
- private static Stats getTamingBonus(JsonObject profile) {
+ public static int getPetScore(JsonObject profile) {
JsonObject bonuses = Constants.BONUSES;
- if (bonuses == null) return null;
-
+ if (bonuses == null) {
+ Utils.showOutdatedRepoNotification();
+ return 0;
+ }
JsonElement petsElement = Utils.getElement(profile, "pets");
- if (petsElement == null) return new Stats();
+ if (petsElement == null) return 0;
JsonArray pets = petsElement.getAsJsonArray();
@@ -190,11 +192,19 @@ public class PlayerStats {
for (String value : highestRarityMap.values()) {
petScore += Utils.getElementAsFloat(Utils.getElement(bonuses, "pet_value." + value.toUpperCase()), 0);
}
+ return petScore;
+ }
+
+ private static Stats getTamingBonus(JsonObject profile) {
+ JsonObject bonuses = Constants.BONUSES;
+ if (bonuses == null) return null;
JsonElement petRewardsElement = Utils.getElement(bonuses, "pet_rewards");
if (petRewardsElement == null) return null;
JsonObject petRewards = petRewardsElement.getAsJsonObject();
+ int petScore = getPetScore(profile);
+
Stats petBonus = new Stats();
for (int i = 0; i <= petScore; i++) {
if (petRewards.has("" + i)) {
@@ -287,7 +297,6 @@ public class PlayerStats {
private static Stats getSetBonuses(
Stats stats,
JsonObject inventoryInfo,
- JsonObject collectionInfo,
Map<String, ProfileViewer.Level> skyblockInfo,
JsonObject profile
) {
@@ -298,17 +307,11 @@ public class PlayerStats {
String fullset = getFullset(armor, -1);
if (fullset != null) {
+ // TODO @nea: repo based stat delivery? (with lisp)
switch (fullset) {
case "LAPIS_ARMOR_":
bonuses.addStat(HEALTH, 60);
break;
- case "EMERALD_ARMOR_":
- {
- int bonus = (int) Math.floor(Utils.getElementAsFloat(Utils.getElement(collectionInfo, "EMERALD"), 0) / 3000);
- bonuses.addStat(HEALTH, bonus);
- bonuses.addStat(DEFENCE, bonus);
- }
- break;
case "FAIRY_":
bonuses.addStat(HEALTH, Utils.getElementAsFloat(Utils.getElement(profile, "fairy_souls_collected"), 0));
break;
@@ -616,11 +619,10 @@ public class PlayerStats {
public static Stats getStats(
Map<String, ProfileViewer.Level> skyblockInfo,
JsonObject inventoryInfo,
- JsonObject collectionInfo,
JsonObject petsInfo,
JsonObject profile
) {
- if (skyblockInfo == null || inventoryInfo == null || collectionInfo == null || profile == null) return null;
+ if (skyblockInfo == null || inventoryInfo == null || profile == null) return null;
JsonArray armor = Utils.getElement(inventoryInfo, "inv_armor").getAsJsonArray();
JsonArray inventory = Utils.getElement(inventoryInfo, "inv_contents").getAsJsonArray();
@@ -645,7 +647,7 @@ public class PlayerStats {
stats = stats.add(passiveBonuses).add(armorBonuses).add(talismanBonuses).add(petBonus).add(hotmBonuses);
- stats.add(getSetBonuses(stats, inventoryInfo, collectionInfo, skyblockInfo, profile));
+ stats.add(getSetBonuses(stats, inventoryInfo, skyblockInfo, profile));
stats.scaleAll(getStatMult(inventoryInfo));
@@ -655,97 +657,6 @@ public class PlayerStats {
}
/**
- * Calculates the amount of Magical Power the player has using the list of accessories
- *
- * @param inventoryInfo inventory info object
- * @return the amount of Magical Power or -1
- * @see io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer.Profile#getInventoryInfo(String)
- */
- public static int getMagicalPower(JsonObject inventoryInfo, JsonObject profileInfo) {
- if (inventoryInfo == null || !inventoryInfo.has("talisman_bag") || !inventoryInfo.get("talisman_bag").isJsonArray()) {
- return -1;
- }
-
- Map<String, Integer> accessories = JsonUtils.getJsonArrayAsStream(inventoryInfo.get("talisman_bag").getAsJsonArray())
- .map(o -> {
- try {
- return JsonToNBT.getTagFromJson(o.getAsJsonObject().get("nbttag").getAsString());
- } catch (Exception ignored) {
- return null;
- }
- }).filter(Objects::nonNull).map(tag -> {
- NBTTagList loreTagList = tag.getCompoundTag("display").getTagList("Lore", 8);
- String lastElement = loreTagList.getStringTagAt(loreTagList.tagCount() - 1);
- if (lastElement.contains(EnumChatFormatting.OBFUSCATED.toString())) {
- lastElement = lastElement.substring(lastElement.indexOf(' ')).trim().substring(4);
- }
- JsonArray lastElementJsonArray = new JsonArray();
- lastElementJsonArray.add(new JsonPrimitive(lastElement));
- return new AbstractMap.SimpleEntry<>(
- tag.getCompoundTag("ExtraAttributes").getString("id"),
- Utils.getRarityFromLore(lastElementJsonArray)
- );
- }).sorted(Comparator.comparingInt(e -> -e.getValue())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2)->v1, LinkedHashMap::new));
-
- Set<String> ignoredTalismans = new HashSet<>();
- int powderAmount = 0;
- for (Map.Entry<String, Integer> entry : accessories.entrySet()) {
- if (ignoredTalismans.contains(entry.getKey())) {
- continue;
- }
-
- JsonArray children = Utils.getElementOrDefault(Constants.PARENTS, entry.getKey(), new JsonArray()).getAsJsonArray();
- for (JsonElement child : children) {
- ignoredTalismans.add(child.getAsString());
- }
-
- if (entry.getKey().equals("HEGEMONY_ARTIFACT")) {
- switch (entry.getValue()) {
- case 4:
- powderAmount += 16;
- break;
- case 5:
- powderAmount += 22;
- break;
- }
- }
- if (entry.getKey().equals("ABICASE")) {
- if (profileInfo.has("nether_island_player_data") &&
- profileInfo.get("nether_island_player_data").getAsJsonObject().has("abiphone") && profileInfo.get(
- "nether_island_player_data").getAsJsonObject().get("abiphone").getAsJsonObject().has("active_contacts")) { // BatChest
- int contact =
- profileInfo.get("nether_island_player_data").getAsJsonObject().get("abiphone").getAsJsonObject().get(
- "active_contacts").getAsJsonArray().size();
- powderAmount += Math.floor(contact / 2);
- }
- }
- switch (entry.getValue()) {
- case 0:
- case 6:
- powderAmount += 3;
- break;
- case 1:
- case 7:
- powderAmount += 5;
- break;
- case 2:
- powderAmount += 8;
- break;
- case 3:
- powderAmount += 12;
- break;
- case 4:
- powderAmount += 16;
- break;
- case 5:
- powderAmount += 22;
- break;
- }
- }
- return powderAmount;
- }
-
- /**
* Finds the Magical Power the player selected if applicable
*
* @param profileInfo profile information object
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 63c2435a..610e4090 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java
@@ -25,14 +25,18 @@ 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.profileviewer.bestiary.BestiaryData;
import io.github.moulberry.notenoughupdates.profileviewer.weight.senither.SenitherWeight;
import io.github.moulberry.notenoughupdates.util.Constants;
+import io.github.moulberry.notenoughupdates.util.JsonUtils;
import io.github.moulberry.notenoughupdates.util.Utils;
+import io.github.moulberry.notenoughupdates.util.hypixelapi.ProfileCollectionInfo;
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.JsonToNBT;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumChatFormatting;
@@ -40,19 +44,25 @@ import net.minecraft.util.EnumChatFormatting;
import javax.annotation.Nullable;
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.util.AbstractMap;
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.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
-import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
public class ProfileViewer {
@@ -247,7 +257,7 @@ public class ProfileViewer {
"REDSTONE",
"QUARTZ",
"OBSIDIAN",
- "GLOWSTONE",
+ "GLOWSTONE_DUST",
"GRAVEL",
"ICE",
null,
@@ -444,11 +454,15 @@ public class ProfileViewer {
);
}
};
+
+ public static final List<String> SLAYERS = Arrays.asList("zombie", "spider", "wolf", "enderman", "blaze");
+
private static final AtomicBoolean updatingResourceCollection = new AtomicBoolean(false);
private static JsonObject resourceCollection = null;
private final NEUManager manager;
private final HashMap<String, JsonObject> uuidToHypixelProfile = new HashMap<>();
private final HashMap<String, Profile> uuidToProfileMap = new HashMap<>();
+
private final HashMap<String, String> nameToUuid = new HashMap<>();
public ProfileViewer(NEUManager manager) {
@@ -643,11 +657,14 @@ public class ProfileViewer {
private final HashMap<String, List<JsonObject>> coopProfileMap = new HashMap<>();
private final HashMap<String, Map<String, Level>> skyblockInfoCache = new HashMap<>();
private final HashMap<String, JsonObject> inventoryCacheMap = new HashMap<>();
- private final HashMap<String, JsonObject> collectionInfoMap = new HashMap<>();
+ private final HashMap<String, CompletableFuture<ProfileCollectionInfo>> collectionInfoMap = new HashMap<>();
+ private final HashMap<String, Double> skyBlockExperience = new HashMap<>();
+ private final HashMap<String, EnumChatFormatting> skyBlockExperienceColour = new HashMap<>();
private final List<String> profileNames = new ArrayList<>();
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, Integer> magicalPower = new HashMap<>();
private final HashMap<String, SoopyNetworthData> soopyNetworth = new HashMap<>();
private final AtomicBoolean updatingSkyblockProfilesState = new AtomicBoolean(false);
private final AtomicBoolean updatingGuildInfoState = new AtomicBoolean(false);
@@ -671,6 +688,117 @@ public class ProfileViewer {
this.uuid = uuid;
}
+ /**
+ * Calculates the amount of Magical Power the player has using the list of accessories
+ *
+ * @return the amount of Magical Power or -1
+ * @see io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer.Profile#getInventoryInfo(String)
+ */
+ public int getMagicalPower(String profileId) {
+ JsonObject inventoryInfo = getInventoryInfo(profileId);
+ JsonObject profileInfo = getProfileInformation(profileId);
+ if (magicalPower.containsKey(profileId)) return magicalPower.get(profileId);
+ if (inventoryInfo == null || !inventoryInfo.has("talisman_bag") ||
+ !inventoryInfo.get("talisman_bag").isJsonArray()) {
+ return -1;
+ }
+
+ Map<String, Integer> accessories = JsonUtils.getJsonArrayAsStream(inventoryInfo
+ .get("talisman_bag")
+ .getAsJsonArray()).map(o -> {
+ try {
+ return JsonToNBT.getTagFromJson(o
+ .getAsJsonObject()
+ .get("nbttag")
+ .getAsString());
+ } catch (Exception ignored) {
+ return null;
+ }
+ }).filter(Objects::nonNull).map(tag -> {
+ NBTTagList loreTagList = tag.getCompoundTag("display").getTagList("Lore", 8);
+ String lastElement = loreTagList.getStringTagAt(loreTagList.tagCount() - 1);
+ if (lastElement.contains(EnumChatFormatting.OBFUSCATED.toString())) {
+ lastElement = lastElement.substring(lastElement.indexOf(' ')).trim().substring(4);
+ }
+ JsonArray lastElementJsonArray = new JsonArray();
+ lastElementJsonArray.add(new JsonPrimitive(lastElement));
+ return new AbstractMap.SimpleEntry<>(
+ tag.getCompoundTag("ExtraAttributes").getString("id"),
+ Utils.getRarityFromLore(lastElementJsonArray)
+ );
+ }).sorted(Comparator.comparingInt(e -> -e.getValue())).collect(Collectors.toMap(
+ Map.Entry::getKey,
+ Map.Entry::getValue,
+ (v1, v2) -> v1,
+ LinkedHashMap::new
+ ));
+
+ Set<String> ignoredTalismans = new HashSet<>();
+ int powerAmount = 0;
+ for (Map.Entry<String, Integer> entry : accessories.entrySet()) {
+ if (ignoredTalismans.contains(entry.getKey())) {
+ continue;
+ }
+
+ JsonArray children = Utils
+ .getElementOrDefault(Constants.PARENTS, entry.getKey(), new JsonArray())
+ .getAsJsonArray();
+ for (JsonElement child : children) {
+ ignoredTalismans.add(child.getAsString());
+ }
+
+ if (entry.getKey().equals("HEGEMONY_ARTIFACT")) {
+ switch (entry.getValue()) {
+ case 4:
+ powerAmount += 16;
+ break;
+ case 5:
+ powerAmount += 22;
+ break;
+ }
+ }
+ if (entry.getKey().equals("ABICASE")) {
+ if (profileInfo != null && profileInfo.has("nether_island_player_data") &&
+ profileInfo.get("nether_island_player_data").getAsJsonObject().has("abiphone") && profileInfo
+ .get(
+ "nether_island_player_data")
+ .getAsJsonObject()
+ .get("abiphone")
+ .getAsJsonObject()
+ .has("active_contacts")) { // BatChest
+ int contact =
+ profileInfo.get("nether_island_player_data").getAsJsonObject().get("abiphone").getAsJsonObject().get(
+ "active_contacts").getAsJsonArray().size();
+ powerAmount += Math.floor(contact / 2);
+ }
+ }
+ switch (entry.getValue()) {
+ case 0:
+ case 6:
+ powerAmount += 3;
+ break;
+ case 1:
+ case 7:
+ powerAmount += 5;
+ break;
+ case 2:
+ powerAmount += 8;
+ break;
+ case 3:
+ powerAmount += 12;
+ break;
+ case 4:
+ powerAmount += 16;
+ break;
+ case 5:
+ powerAmount += 22;
+ break;
+ }
+ }
+ magicalPower.put(profileId, powerAmount);
+ return powerAmount;
+ }
+
public JsonObject getPlayerStatus() {
if (playerStatus != null) return playerStatus;
if (updatingPlayerStatusState.get()) return null;
@@ -924,6 +1052,50 @@ public class ProfileViewer {
return null;
}
+ public EnumChatFormatting getSkyblockLevelColour(String profileName) {
+ if (Constants.SBLEVELS == null) return EnumChatFormatting.WHITE;
+ if (skyBlockExperienceColour.containsKey(profileName)) {
+ return skyBlockExperienceColour.get(profileName);
+ }
+
+ double skyblockLevel = getSkyblockLevel(profileName);
+
+ EnumChatFormatting previousColor = EnumChatFormatting.WHITE;
+ if (Constants.SBLEVELS == null || !Constants.SBLEVELS.has("sblevel_colours")) {
+ Utils.showOutdatedRepoNotification();
+ return EnumChatFormatting.WHITE;
+ }
+ JsonObject sblevelColours = Constants.SBLEVELS.getAsJsonObject("sblevel_colours");
+ try {
+ for (Map.Entry<String, JsonElement> stringJsonElementEntry : sblevelColours.entrySet()) {
+ int key = Integer.parseInt(stringJsonElementEntry.getKey());
+ EnumChatFormatting valueByName = EnumChatFormatting.getValueByName(stringJsonElementEntry
+ .getValue()
+ .getAsString());
+ if (skyblockLevel <= key) {
+ skyBlockExperienceColour.put(profileName, previousColor);
+ return previousColor;
+ }
+ previousColor = valueByName;
+ }
+ } catch (RuntimeException ignored) {
+ // catch both numberformat and getValueByName being wrong
+ }
+ skyBlockExperienceColour.put(profileName, EnumChatFormatting.WHITE);
+ return EnumChatFormatting.WHITE;
+ }
+
+ public double getSkyblockLevel(String profileName) {
+ if (skyBlockExperience.containsKey(profileName)) {
+ return skyBlockExperience.get(profileName);
+ }
+ final JsonObject profileInfo = getProfileInformation(profileName);
+ int element = Utils.getElementAsInt(Utils.getElement(profileInfo, "leveling.experience"), 0);
+ double level = (element / 100F);
+ skyBlockExperience.put(profileName, level);
+ return level;
+ }
+
public long getNetWorth(String profileName) {
if (profileName == null) profileName = latestProfile;
if (networth.get(profileName) != null) return networth.get(profileName);
@@ -1141,65 +1313,62 @@ public class ProfileViewer {
}
public JsonObject getProfileInformation(String profileName) {
+ if (profileName == null) profileName = latestProfile;
+ if (profileMap.containsKey(profileName)) return profileMap.get(profileName);
+ JsonObject profile = getRawProfileInformation(profileName);
+ if (profile == null) return null;
+ if (!profile.has("members")) return null;
+ JsonObject members = profile.get("members").getAsJsonObject();
+ if (!members.has(uuid)) return null;
+ JsonObject profileInfo = members.get(uuid).getAsJsonObject();
+ if (profile.has("banking")) {
+ profileInfo.add("banking", profile.get("banking").getAsJsonObject());
+ }
+ if (profile.has("game_mode")) {
+ profileInfo.add("game_mode", profile.get("game_mode"));
+ }
+ if (profile.has("community_upgrades")) {
+ profileInfo.add("community_upgrades", profile.get("community_upgrades"));
+ }
+ profileMap.put(profileName, profileInfo);
+ return profileInfo;
+ }
+
+ public JsonObject getRawProfileInformation(String profileName) {
JsonArray playerInfo = getSkyblockProfiles(() -> {});
if (playerInfo == null) return null;
if (profileName == null) profileName = latestProfile;
- if (profileMap.containsKey(profileName)) return profileMap.get(profileName);
- for (int i = 0; i < skyblockProfiles.size(); i++) {
- if (!skyblockProfiles.get(i).isJsonObject()) {
+ for (JsonElement skyblockProfile : skyblockProfiles) {
+ if (!skyblockProfile.isJsonObject()) {
skyblockProfiles = null;
return null;
}
- JsonObject profile = skyblockProfiles.get(i).getAsJsonObject();
- if (profile.get("cute_name").getAsString().equalsIgnoreCase(profileName)) {
- if (!profile.has("members")) return null;
- JsonObject members = profile.get("members").getAsJsonObject();
- if (!members.has(uuid)) continue;
- JsonObject profileInfo = members.get(uuid).getAsJsonObject();
- if (profile.has("banking")) {
- profileInfo.add("banking", profile.get("banking").getAsJsonObject());
- }
- if (profile.has("game_mode")) {
- profileInfo.add("game_mode", profile.get("game_mode"));
- }
- profileMap.put(profileName, profileInfo);
- return profileInfo;
- }
+ if (skyblockProfile.getAsJsonObject().get("cute_name").getAsString().equalsIgnoreCase(profileName))
+ return skyblockProfile.getAsJsonObject();
}
-
return null;
}
public List<JsonObject> getCoopProfileInformation(String profileName) {
- JsonArray playerInfo = getSkyblockProfiles(() -> {});
- if (playerInfo == null) return null;
if (profileName == null) profileName = latestProfile;
if (coopProfileMap.containsKey(profileName)) return coopProfileMap.get(profileName);
-
- for (int i = 0; i < skyblockProfiles.size(); i++) {
- if (!skyblockProfiles.get(i).isJsonObject()) {
- skyblockProfiles = null;
- return null;
- }
- JsonObject profile = skyblockProfiles.get(i).getAsJsonObject();
- if (profile.get("cute_name").getAsString().equalsIgnoreCase(profileName)) {
- if (!profile.has("members")) return null;
- JsonObject members = profile.get("members").getAsJsonObject();
- if (!members.has(uuid)) return null;
- List<JsonObject> coopList = new ArrayList<>();
- for (Map.Entry<String, JsonElement> islandMember : members.entrySet()) {
- if (!islandMember.getKey().equals(uuid)) {
- JsonObject coopProfileInfo = islandMember.getValue().getAsJsonObject();
- coopList.add(coopProfileInfo);
- }
- }
- coopProfileMap.put(profileName, coopList);
- return coopList;
+ JsonObject profile = getRawProfileInformation(profileName);
+ if (profile == null) return null;
+
+ if (!profile.has("members")) return null;
+ JsonObject members = profile.get("members").getAsJsonObject();
+ if (!members.has(uuid)) return null;
+ List<JsonObject> coopList = new ArrayList<>();
+ for (Map.Entry<String, JsonElement> islandMember : members.entrySet()) {
+ if (!islandMember.getKey().equals(uuid)) {
+ JsonObject coopProfileInfo = islandMember.getValue().getAsJsonObject();
+ coopList.add(coopProfileInfo);
}
}
+ coopProfileMap.put(profileName, coopList);
+ return coopList;
- return null;
}
public void resetCache() {
@@ -1216,6 +1385,9 @@ public class ProfileViewer {
inventoryCacheMap.clear();
collectionInfoMap.clear();
networth.clear();
+ magicalPower.clear();
+ skyBlockExperience.clear();
+ skyBlockExperienceColour.clear();
}
public int getCap(JsonObject leveling, String skillName) {
@@ -1225,6 +1397,40 @@ public class ProfileViewer {
: 50;
}
+ public int getBestiaryTiers(JsonObject profileInfo) {
+ int beLevel = 0;
+ for (ItemStack items : BestiaryData.getBestiaryLocations().keySet()) {
+ List<String> mobs = BestiaryData.getBestiaryLocations().get(items);
+ if (mobs != null) {
+ for (String mob : mobs) {
+ if (mob != null) {
+ float kills = Utils.getElementAsFloat(Utils.getElement(profileInfo, "bestiary.kills_" + mob), 0);
+ String type;
+ if (BestiaryData.getMobType().get(mob) != null) {
+ type = BestiaryData.getMobType().get(mob);
+ } else {
+ type = "MOB";
+ }
+ JsonObject leveling = Constants.LEVELING;
+ ProfileViewer.Level level = null;
+ if (leveling != null && Utils.getElement(leveling, "bestiary." + type) != null) {
+ JsonArray levelingArray = Utils.getElement(leveling, "bestiary." + type).getAsJsonArray();
+ int levelCap = Utils.getElementAsInt(Utils.getElement(leveling, "bestiary.caps." + type), 0);
+ level = ProfileViewer.getLevel(levelingArray, kills, levelCap, false);
+ }
+
+ float levelNum = 0;
+ if (level != null) {
+ levelNum = level.level;
+ }
+ beLevel += (int) Math.floor(levelNum);
+ }
+ }
+ }
+ }
+ return beLevel;
+ }
+
public Map<String, Level> getSkyblockInfo(String profileName) {
JsonObject profileInfo = getProfileInformation(profileName);
@@ -1329,9 +1535,7 @@ public class ProfileViewer {
)
);
}
-
- List<String> slayers = Arrays.asList("zombie", "spider", "wolf", "enderman", "blaze");
- for (String slayerName : slayers) {
+ for (String slayerName : SLAYERS) {
float slayerExperience = Utils.getElementAsFloat(Utils.getElement(
profileInfo,
"slayer_bosses." + slayerName + ".xp"
@@ -1560,134 +1764,15 @@ public class ProfileViewer {
return null;
}
- public JsonObject getCollectionInfo(String profileName) {
- JsonObject profileInfo = getProfileInformation(profileName);
- if (profileInfo == null) return null;
- JsonObject resourceCollectionInfo = getResourceCollectionInformation();
- if (resourceCollectionInfo == null) return null;
- if (profileName == null) profileName = latestProfile;
- if (collectionInfoMap.containsKey(profileName)) return collectionInfoMap.get(profileName);
-
- List<JsonObject> coopMembers = getCoopProfileInformation(profileName);
- JsonElement unlocked_coll_tiers_element = Utils.getElement(profileInfo, "unlocked_coll_tiers");
- JsonElement crafted_generators_element = Utils.getElement(profileInfo, "crafted_generators");
- JsonObject fakeMember = new JsonObject();
- fakeMember.add("crafted_generators", crafted_generators_element);
- coopMembers.add(coopMembers.size(), fakeMember);
- JsonElement collectionInfoElement = Utils.getElement(profileInfo, "collection");
-
- if (unlocked_coll_tiers_element == null || collectionInfoElement == null) {
- return null;
- }
-
- JsonObject collectionInfo = new JsonObject();
- JsonObject collectionTiers = new JsonObject();
- JsonObject minionTiers = new JsonObject();
- JsonObject personalAmounts = new JsonObject();
- JsonObject totalAmounts = new JsonObject();
-
- if (collectionInfoElement.isJsonObject()) {
- personalAmounts = collectionInfoElement.getAsJsonObject();
- }
-
- for (Map.Entry<String, JsonElement> entry : personalAmounts.entrySet()) {
- totalAmounts.addProperty(entry.getKey(), entry.getValue().getAsLong());
- }
-
- List<JsonObject> coopProfiles = getCoopProfileInformation(profileName);
- if (coopProfiles != null) {
- for (JsonObject coopProfile : coopProfiles) {
- JsonElement coopCollectionInfoElement = Utils.getElement(coopProfile, "collection");
- if (coopCollectionInfoElement != null && coopCollectionInfoElement.isJsonObject()) {
- for (Map.Entry<String, JsonElement> entry : coopCollectionInfoElement.getAsJsonObject().entrySet()) {
- float existing = Utils.getElementAsFloat(totalAmounts.get(entry.getKey()), 0);
- totalAmounts.addProperty(entry.getKey(), existing + entry.getValue().getAsLong());
- }
- }
- }
- }
-
- if (unlocked_coll_tiers_element.isJsonArray()) {
- JsonArray unlocked_coll_tiers = unlocked_coll_tiers_element.getAsJsonArray();
- for (int i = 0; i < unlocked_coll_tiers.size(); i++) {
- String unlocked = unlocked_coll_tiers.get(i).getAsString();
-
- Matcher matcher = COLL_TIER_PATTERN.matcher(unlocked);
-
- if (matcher.find()) {
- String tier_str = matcher.group(1);
- int tier = Integer.parseInt(tier_str);
- String coll = unlocked.substring(0, unlocked.length() - (matcher.group().length()));
- if (!collectionTiers.has(coll) || collectionTiers.get(coll).getAsInt() < tier) {
- collectionTiers.addProperty(coll, tier);
- }
- }
- }
- }
- for (JsonObject current_member_info : coopMembers) {
- if (
- !current_member_info.has("crafted_generators") || !current_member_info.get("crafted_generators").isJsonArray()
- ) continue;
- JsonArray crafted_generators = Utils.getElement(current_member_info, "crafted_generators").getAsJsonArray();
- for (int j = 0; j < crafted_generators.size(); j++) {
- String unlocked = crafted_generators.get(j).getAsString();
- Matcher matcher = COLL_TIER_PATTERN.matcher(unlocked);
- if (matcher.find()) {
- String tierString = matcher.group(1);
- int tier = Integer.parseInt(tierString);
- String coll = unlocked.substring(0, unlocked.length() - (matcher.group().length()));
- if (!minionTiers.has(coll) || minionTiers.get(coll).getAsInt() < tier) {
- minionTiers.addProperty(coll, tier);
- }
- }
- }
- }
-
- JsonObject maxAmount = new JsonObject();
- JsonObject updatedCollectionTiers = new JsonObject();
- for (Map.Entry<String, JsonElement> totalAmountsEntry : totalAmounts.entrySet()) {
- String collName = totalAmountsEntry.getKey();
- int collTier = (int) Utils.getElementAsFloat(collectionTiers.get(collName), 0);
-
- int currentAmount = (int) Utils.getElementAsFloat(totalAmounts.get(collName), 0);
- if (currentAmount > 0) {
- for (Map.Entry<String, JsonElement> resourceEntry : resourceCollectionInfo.entrySet()) {
- JsonElement tiersElement = Utils.getElement(resourceEntry.getValue(), "items." + collName + ".tiers");
- if (tiersElement != null && tiersElement.isJsonArray()) {
- JsonArray tiers = tiersElement.getAsJsonArray();
- int maxTierAcquired = -1;
- int maxAmountRequired = -1;
- for (int i = 0; i < tiers.size(); i++) {
- JsonObject tierInfo = tiers.get(i).getAsJsonObject();
- int tier = tierInfo.get("tier").getAsInt();
- int amountRequired = tierInfo.get("amountRequired").getAsInt();
- if (currentAmount >= amountRequired) {
- maxTierAcquired = tier;
- }
- maxAmountRequired = amountRequired;
- }
- if (maxTierAcquired >= 0 && maxTierAcquired > collTier) {
- updatedCollectionTiers.addProperty(collName, maxTierAcquired);
- }
- maxAmount.addProperty(collName, maxAmountRequired);
- }
- }
- }
- }
-
- for (Map.Entry<String, JsonElement> collectionTiersEntry : updatedCollectionTiers.entrySet()) {
- collectionTiers.add(collectionTiersEntry.getKey(), collectionTiersEntry.getValue());
- }
-
- collectionInfo.add("minion_tiers", minionTiers);
- collectionInfo.add("max_amounts", maxAmount);
- collectionInfo.add("personal_amounts", personalAmounts);
- collectionInfo.add("total_amounts", totalAmounts);
- collectionInfo.add("collection_tiers", collectionTiers);
-
- collectionInfoMap.put(profileName, collectionInfo);
-
- return collectionInfo;
+ public ProfileCollectionInfo getCollectionInfo(String profileName) {
+ JsonObject rawProfileInformation = getRawProfileInformation(profileName);
+ if (rawProfileInformation == null) return null;
+ CompletableFuture<ProfileCollectionInfo> future =
+ collectionInfoMap.computeIfAbsent(
+ profileName.toLowerCase(Locale.ROOT),
+ ignored -> ProfileCollectionInfo.getCollectionData(rawProfileInformation, uuid)
+ );
+ return future.getNow(null);
}
public PlayerStats.Stats getPassiveStats(String profileName) {
@@ -1716,7 +1801,6 @@ public class ProfileViewer {
PlayerStats.Stats stats = PlayerStats.getStats(
getSkyblockInfo(profileName),
getInventoryInfo(profileName),
- getCollectionInfo(profileName),
getPetsInfo(profileName),
profileInfo
);
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 70ea051a..7da6c627 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
@@ -117,7 +117,7 @@ public class BestiaryPage extends GuiProfileViewerPage {
Color color = new Color(128, 128, 128, 255);
Utils.renderAlignedString(
EnumChatFormatting.RED + "Bestiary Level: ",
- EnumChatFormatting.GRAY + "" + (float) getBestiaryTiers(profileInfo) / 10,
+ EnumChatFormatting.GRAY + "" + (float) GuiProfileViewer.getProfile().getBestiaryTiers(profileInfo) / 10,
guiLeft + 220,
guiTop + 50,
110
@@ -265,38 +265,4 @@ public class BestiaryPage extends GuiProfileViewerPage {
yIndex++;
}
}
-
- private int getBestiaryTiers(JsonObject profileInfo) {
- int beLevel = 0;
- for (ItemStack items : BestiaryData.getBestiaryLocations().keySet()) {
- List<String> mobs = BestiaryData.getBestiaryLocations().get(items);
- if (mobs != null) {
- for (String mob : mobs) {
- if (mob != null) {
- float kills = Utils.getElementAsFloat(Utils.getElement(profileInfo, "bestiary.kills_" + mob), 0);
- String type;
- if (BestiaryData.getMobType().get(mob) != null) {
- type = BestiaryData.getMobType().get(mob);
- } else {
- type = "MOB";
- }
- JsonObject leveling = Constants.LEVELING;
- ProfileViewer.Level level = null;
- if (leveling != null && Utils.getElement(leveling, "bestiary." + type) != null) {
- JsonArray levelingArray = Utils.getElement(leveling, "bestiary." + type).getAsJsonArray();
- int levelCap = Utils.getElementAsInt(Utils.getElement(leveling, "bestiary.caps." + type), 0);
- level = ProfileViewer.getLevel(levelingArray, kills, levelCap, false);
- }
-
- float levelNum = 0;
- if (level != null) {
- levelNum = level.level;
- }
- beLevel += (int) Math.floor(levelNum);
- }
- }
- }
- }
- return beLevel;
- }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/LevelPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/LevelPage.java
new file mode 100644
index 00000000..16abf251
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/LevelPage.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2023 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.profileviewer.level;
+
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.profileviewer.BasicPage;
+import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer;
+import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
+import io.github.moulberry.notenoughupdates.profileviewer.level.task.CoreTaskLevel;
+import io.github.moulberry.notenoughupdates.profileviewer.level.task.DungeonTaskLevel;
+import io.github.moulberry.notenoughupdates.profileviewer.level.task.EssenceTaskLevel;
+import io.github.moulberry.notenoughupdates.profileviewer.level.task.MiscTaskLevel;
+import io.github.moulberry.notenoughupdates.profileviewer.level.task.SkillRelatedTaskLevel;
+import io.github.moulberry.notenoughupdates.profileviewer.level.task.SlayingTaskLevel;
+import io.github.moulberry.notenoughupdates.profileviewer.level.task.StoryTaskLevel;
+import io.github.moulberry.notenoughupdates.util.Constants;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.ResourceLocation;
+import org.lwjgl.opengl.GL11;
+
+import java.text.NumberFormat;
+import java.util.Collections;
+import java.util.List;
+
+public class LevelPage {
+
+ private final GuiProfileViewer instance;
+ private final BasicPage basicPage;
+ private ProfileViewer.Profile profile;
+
+ private String profileId;
+
+ private final JsonObject constant;
+
+ private final CoreTaskLevel coreTaskLevel;
+ private final DungeonTaskLevel dungeonTaskLevel;
+ private final EssenceTaskLevel essenceTaskLevel;
+ private final MiscTaskLevel miscTaskLevel;
+ private final SkillRelatedTaskLevel skillRelatedTaskLevel;
+ private final SlayingTaskLevel slayingTaskLevel;
+ private final StoryTaskLevel storyTaskLevel;
+
+ private static final ResourceLocation pv_levels = new ResourceLocation("notenoughupdates:pv_levels.png");
+
+ public LevelPage(GuiProfileViewer instance, BasicPage basicPage) {
+ this.instance = instance;
+ this.basicPage = basicPage;
+ constant = Constants.SBLEVELS;
+
+ coreTaskLevel = new CoreTaskLevel(this);
+ dungeonTaskLevel = new DungeonTaskLevel(this);
+ essenceTaskLevel = new EssenceTaskLevel(this);
+ miscTaskLevel = new MiscTaskLevel(this);
+ skillRelatedTaskLevel = new SkillRelatedTaskLevel(this);
+ slayingTaskLevel = new SlayingTaskLevel(this);
+ storyTaskLevel = new StoryTaskLevel(this);
+ }
+
+ public void drawPage(int mouseX, int mouseY) {
+ int guiLeft = GuiProfileViewer.getGuiLeft();
+ int guiTop = GuiProfileViewer.getGuiTop();
+ this.profile = GuiProfileViewer.getProfile();
+ this.profileId = GuiProfileViewer.getProfileId();
+
+ basicPage.drawSideButtons();
+
+ if (constant == null) {
+ Utils.showOutdatedRepoNotification();
+ return;
+ }
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(pv_levels);
+ Utils.drawTexturedRect(guiLeft, guiTop, instance.sizeX, instance.sizeY, GL11.GL_NEAREST);
+
+ double skyblockLevel = profile.getSkyblockLevel(profileId);
+ JsonObject profileInfo = profile.getProfileInformation(profileId);
+
+ drawMainBar(skyblockLevel, mouseX, mouseY, guiLeft, guiTop);
+ coreTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop);
+ dungeonTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop);
+ essenceTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop);
+ miscTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop);
+ skillRelatedTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop);
+ slayingTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop);
+ storyTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop);
+ }
+
+ public void renderLevelBar(
+ String name,
+ ItemStack stack,
+ int x,
+ int y,
+ int xSize,
+ double level,
+ double xp,
+ double max,
+ int mouseX,
+ int mouseY,
+ boolean percentage,
+ List<String> tooltip
+ ) {
+
+ if (xp < 0) xp = 0;
+ double experienceRequired = (xp / max);
+
+ String second = EnumChatFormatting.WHITE.toString() + (int) level;
+ if (percentage) {
+ second = EnumChatFormatting.WHITE.toString() + (int) (experienceRequired * 100) + "%";
+ }
+ Utils.renderAlignedString(
+ EnumChatFormatting.RED + name,
+ second,
+ x + 14,
+ y - 4,
+ xSize - 20
+ );
+
+ if (xp >= max) {
+ getInstance().renderGoldBar(x, y + 6, xSize);
+ } else {
+ getInstance().renderBar(x, y + 6, xSize, (float) experienceRequired);
+ }
+ String levelStr;
+ if (mouseX > x && mouseX < x + 120) {
+ if (mouseY > y - 4 && mouseY < y + 13) {
+ NumberFormat numberFormat = NumberFormat.getInstance();
+ String xpFormatted = numberFormat.format((int) xp);
+ String maxFormatted = numberFormat.format((int) max);
+
+ levelStr =
+ EnumChatFormatting.GRAY + "Progress: " + EnumChatFormatting.DARK_PURPLE + (int) (experienceRequired * 100) +
+ "%" +
+ " §8(" + xpFormatted + "/" + maxFormatted + " XP)";
+ if (tooltip != null && !tooltip.isEmpty()) {
+ tooltip.add("");
+ tooltip.add(levelStr);
+ getInstance().tooltipToDisplay = tooltip;
+ } else {
+ getInstance().tooltipToDisplay = Utils.createList(levelStr);
+ }
+ }
+ }
+
+ GlStateManager.enableDepth();
+ GL11.glTranslatef((x), (y - 6f), 0);
+ GL11.glScalef(0.7f, 0.7f, 1);
+ Utils.drawItemStackLinear(stack, 0, 0);
+ GL11.glScalef(1 / 0.7f, 1 / 0.7f, 1);
+ GL11.glTranslatef(-(x), -(y - 6f), 0);
+ GlStateManager.disableDepth();
+ }
+
+ private void drawMainBar(double skyblockLevel, int mouseX, int mouseY, int guiLeft, int guiTop) {
+ renderLevelBar(
+ "Level",
+ BasicPage.skull,
+ guiLeft + 163,
+ guiTop + 30,
+ 110,
+ skyblockLevel,
+ (skyblockLevel - (long) skyblockLevel) * 100,
+ 100,
+ mouseX,
+ mouseY,
+ false,
+ Collections.emptyList()
+ );
+ }
+
+ public String buildLore(String name, double xpGotten, double xpGainful, boolean hasNoLimit) {
+ String xpGottenFormatted = NumberFormat.getInstance().format((int) xpGotten);
+ String xpGainfulFormatted = NumberFormat.getInstance().format((int) xpGainful);
+
+ if (xpGainful == 0 && xpGotten == 0 && !hasNoLimit) {
+ return EnumChatFormatting.GOLD + name + ": §c§lNOT DETECTABLE!";
+ }
+ if (hasNoLimit) {
+ return EnumChatFormatting.GOLD + name + ": " + EnumChatFormatting.YELLOW + xpGottenFormatted + " XP";
+ }
+ int percentage = (int) ((xpGotten / xpGainful) * 100);
+ if (xpGotten >= xpGainful) {
+ return EnumChatFormatting.GOLD + name + ": " + EnumChatFormatting.GREEN
+ + percentage + "%" + " §8(" + xpGottenFormatted + "/" + xpGainfulFormatted + " XP)";
+ } else if (xpGotten == -1) {
+ return EnumChatFormatting.GOLD + name + ": §c§lCOLLECTION DISABLED!";
+ } else {
+
+ return EnumChatFormatting.GOLD + name + ": " + EnumChatFormatting.YELLOW
+ + percentage + "%" + " §8(" + xpGottenFormatted + "/" + xpGainfulFormatted + " XP)";
+ }
+ }
+
+ public JsonObject getConstant() {
+ return constant;
+ }
+
+ public ProfileViewer.Profile getProfile() {
+ return profile;
+ }
+
+ public String getProfileId() {
+ return profileId;
+ }
+
+ public GuiProfileViewer getInstance() {
+ return instance;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/CoreTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/CoreTaskLevel.java
new file mode 100644
index 00000000..be333359
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/CoreTaskLevel.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2023 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.profileviewer.level.task;
+
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.profileviewer.PlayerStats;
+import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
+import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage;
+import io.github.moulberry.notenoughupdates.util.Constants;
+import io.github.moulberry.notenoughupdates.util.hypixelapi.ProfileCollectionInfo;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+public class CoreTaskLevel {
+
+ private final LevelPage levelPage;
+
+ public CoreTaskLevel(LevelPage levelPage) {this.levelPage = levelPage;}
+
+ private final List<String> skills = Arrays.asList(
+ "taming",
+ "mining",
+ "foraging",
+ "enchanting",
+ "carpentry",
+ "farming",
+ "combat",
+ "fishing",
+ "alchemy"
+ );
+
+ public void drawTask(JsonObject object, int mouseX, int mouseY, int guiLeft, int guiTop) {
+ JsonObject coreTask = levelPage.getConstant().get("core_task").getAsJsonObject();
+ // skills
+ Map<String, ProfileViewer.Level> skyblockInfo = levelPage.getProfile().getSkyblockInfo(levelPage.getProfileId());
+
+ int sbXpGainedSkillLVL = 0;
+ if (skyblockInfo != null) {
+ for (String skill : skills) {
+ ProfileViewer.Level level = skyblockInfo.get(skill);
+ for (int i = 1; i <= level.level; i++) {
+ if (i <= 10) {
+ sbXpGainedSkillLVL += 5;
+ }
+ if (i <= 25 && i > 10) {
+ sbXpGainedSkillLVL += 10;
+ }
+ if (i <= 50 && i > 25) {
+ sbXpGainedSkillLVL += 20;
+ }
+ if (i <= 60 && i > 50) {
+ sbXpGainedSkillLVL += 30;
+ }
+ }
+ }
+ } else {
+ sbXpGainedSkillLVL = -1;
+ }
+
+ // mp acc
+ int sbXpGainedMp = levelPage.getProfile().getMagicalPower(levelPage.getProfileId());
+
+ // pets
+
+ int petScore = PlayerStats.getPetScore(object);
+ int sbXpPetScore = petScore * coreTask.get("pet_score_xp").getAsInt();
+
+ // museum is not possible
+
+ // fairy soul
+ int fairySoulsCollected = object.get("fairy_souls_collected").getAsInt();
+ int sbXpGainedFairy = ((fairySoulsCollected / 5)) * coreTask.get("fairy_souls_xp").getAsInt();
+
+ int sbXpCollection = -1;
+ int sbXpMinionTier = -1; // keeping at -1 here because cobblestone 1 minion XP isn't included for some reason?
+ JsonObject minionXp = Constants.MISC.get("minionXp").getAsJsonObject();
+ int collectionsXp = coreTask.get("collections_xp").getAsInt();
+ ProfileCollectionInfo collection;
+ collection = levelPage.getProfile().getCollectionInfo(
+ levelPage.getProfileId()
+ );
+ if (collection != null) {
+ sbXpCollection = 0;
+ for (Map.Entry<String, ProfileCollectionInfo.CollectionInfo> stringCollectionInfoEntry : collection
+ .getCollections()
+ .entrySet()) {
+ ProfileCollectionInfo.CollectionInfo value = stringCollectionInfoEntry.getValue();
+ sbXpCollection += value.getUnlockedTiers().size() * collectionsXp;
+ }
+
+ for (int tier : collection.getCraftedGenerators().values()) {
+ for (int i = 1; i <= tier; i++) {
+ if (minionXp.has(i + "")) sbXpMinionTier += minionXp.get(i + "").getAsInt();
+ }
+ }
+ }
+ List<String> lore = new ArrayList<>();
+
+ lore.add(levelPage.buildLore("Skill Level Up",
+ sbXpGainedSkillLVL, coreTask.get("skill_level_up").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore("Museum Progression",
+ 0, 0, false
+ ));
+ lore.add(levelPage.buildLore(
+ "Fairy Soul",
+ sbXpGainedFairy, coreTask.get("fairy_souls").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore("Accessory Bag",
+ sbXpGainedMp, 0, true
+ ));
+ lore.add(levelPage.buildLore("Pet Score",
+ sbXpPetScore, 0, true
+ ));
+ lore.add(levelPage.buildLore("Collections",
+ sbXpCollection, coreTask.get("collections").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore("Craft Minions",
+ sbXpMinionTier, coreTask.get("craft_minions").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore("Bank Upgrade",
+ 0, 0, false
+ ));
+
+ levelPage.renderLevelBar(
+ "Core Task",
+ new ItemStack(Items.nether_star),
+ guiLeft + 23,
+ guiTop + 25,
+ 110,
+ 0,
+ sbXpGainedSkillLVL + sbXpGainedFairy +
+ sbXpCollection + sbXpMinionTier,
+ levelPage.getConstant().getAsJsonObject("category_xp").get("core_task").getAsInt(),
+ mouseX,
+ mouseY,
+ true,
+ lore
+ );
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/DungeonTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/DungeonTaskLevel.java
new file mode 100644
index 00000000..157c8362
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/DungeonTaskLevel.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2023 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.profileviewer.level.task;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
+import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage;
+import io.github.moulberry.notenoughupdates.util.Utils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+public class DungeonTaskLevel {
+
+ private final LevelPage levelPage;
+
+ public DungeonTaskLevel(LevelPage levelPage) {this.levelPage = levelPage;}
+
+ public void drawTask(JsonObject object, int mouseX, int mouseY, int guiLeft, int guiTop) {
+ JsonObject dungeonTask = levelPage.getConstant().get("dungeon_task").getAsJsonObject();
+
+ Map<String, ProfileViewer.Level> skyblockInfo =
+ levelPage.getProfile().getSkyblockInfo(levelPage.getProfileId());
+
+ double sbLevelGainedFloor = 0;
+ double sbXpGainedClass = 0;
+ double sbXpGainedLvl = 0;
+ int catacombsLvl = 0;
+ if (skyblockInfo != null && skyblockInfo.containsKey("catacombs")) {
+ ProfileViewer.Level catacombs = skyblockInfo.get("catacombs");
+
+ catacombsLvl = (int) catacombs.level;
+ for (int i = 1; i <= catacombs.level; i++) {
+ if (40 > i) {
+ sbXpGainedLvl += 20;
+ } else {
+ sbXpGainedLvl += 40;
+ }
+ }
+
+ List<String> dungeonClasses = Arrays.asList("healer", "tank", "mage", "archer", "berserk");
+ for (String dungeonClass : dungeonClasses) {
+ ProfileViewer.Level level = skyblockInfo.get(dungeonClass);
+ for (int i = 1; i <= level.level; i++) {
+ if (i <= 50) sbXpGainedClass += dungeonTask.get("class_xp").getAsInt();
+ }
+ }
+
+ JsonArray completeCatacombs = dungeonTask.get("complete_catacombs").getAsJsonArray();
+ int index = 0;
+ for (JsonElement completeCatacomb : completeCatacombs) {
+ int value = completeCatacomb.getAsInt();
+ JsonObject normalCompletions = Utils
+ .getElement(object, "dungeons.dungeon_types.catacombs.tier_completions")
+ .getAsJsonObject();
+ if (normalCompletions.has(index + "")) {
+ sbLevelGainedFloor = sbLevelGainedFloor + value;
+ }
+ index++;
+ }
+
+ int masterCatacombs = dungeonTask.get("complete_master_catacombs").getAsInt();
+ for (int i = 0; i <= 7; i++) {
+ JsonElement masterCompletions = Utils
+ .getElementOrDefault(object, "dungeons.dungeon_types.master_catacombs.tier_completions", null);
+ if (masterCompletions != null) {
+ if (masterCompletions.getAsJsonObject().has(i + "")) {
+ sbLevelGainedFloor = sbLevelGainedFloor + masterCatacombs;
+ }
+ }
+ }
+ }
+
+ int catacombsLevelUp = dungeonTask.get("catacombs_level_up").getAsInt();
+ int classLevelUp = dungeonTask.get("class_level_up").getAsInt();
+ int completeDungeon = dungeonTask.get("complete_dungeon").getAsInt();
+ int totalGainful = catacombsLevelUp + classLevelUp + completeDungeon;
+ double totalXp = sbXpGainedLvl + sbXpGainedClass + sbLevelGainedFloor;
+
+ List<String> lore = new ArrayList<>();
+
+ lore.add(levelPage.buildLore("Catacombs Level Up", sbXpGainedLvl, catacombsLevelUp, false));
+ lore.add(levelPage.buildLore("Class Level Up", sbXpGainedClass, classLevelUp, false));
+ lore.add(levelPage.buildLore("Complete Dungeons", sbLevelGainedFloor, completeDungeon, false));
+
+ levelPage.renderLevelBar(
+ "Dungeon",
+ NotEnoughUpdates.INSTANCE.manager
+ .createItemResolutionQuery()
+ .withKnownInternalName("WITHER_RELIC")
+ .resolveToItemStack(),
+ guiLeft + 23,
+ guiTop + 55,
+ 110,
+ catacombsLvl,
+ totalXp,
+ totalGainful,
+ mouseX,
+ mouseY,
+ true,
+ lore
+ );
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/EssenceTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/EssenceTaskLevel.java
new file mode 100644
index 00000000..d64f54c1
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/EssenceTaskLevel.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2023 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.profileviewer.level.task;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage;
+import io.github.moulberry.notenoughupdates.util.Constants;
+import net.minecraft.util.EnumChatFormatting;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class EssenceTaskLevel {
+
+ private final LevelPage levelPage;
+
+ public EssenceTaskLevel(LevelPage levelPage) {this.levelPage = levelPage;}
+
+ public void drawTask(JsonObject object, int mouseX, int mouseY, int guiLeft, int guiTop) {
+ List<String> lore = new ArrayList<>();
+
+ JsonObject categoryXp = levelPage.getConstant().get("category_xp").getAsJsonObject();
+ JsonObject essenceShopTask = levelPage.getConstant().get("essence_shop_task").getAsJsonObject();
+ JsonArray essenceSteps = essenceShopTask.get("essence_shop_xp").getAsJsonArray();
+ JsonObject essencePerks = object.get("perks").getAsJsonObject();
+
+ Map<String, EssenceShop> loreMap = new HashMap<>();
+ for (Map.Entry<String, JsonElement> stringJsonElementEntry : Constants.ESSENCESHOPS.entrySet()) {
+ String name = stringJsonElementEntry.getKey();
+ JsonObject individualObjects = stringJsonElementEntry.getValue().getAsJsonObject();
+ for (Map.Entry<String, JsonElement> jsonElementEntry : individualObjects.entrySet()) {
+ String key = jsonElementEntry.getKey();
+ if (!essencePerks.has(key)) {
+ continue;
+ }
+
+ int essenceAmount = essencePerks.get(key).getAsInt();
+
+ int amountReceivedForEach = 0;
+ for (int i = essenceAmount - 1; i >= 0; i--) {
+ amountReceivedForEach += essenceSteps.get(i).getAsInt();
+ }
+ if (!loreMap.containsKey(name)) {
+ EssenceShop value = new EssenceShop();
+ value.current += amountReceivedForEach;
+ value.name = name;
+ loreMap.put(name, value);
+ } else {
+ EssenceShop essenceShop = loreMap.get(name);
+ essenceShop.current += amountReceivedForEach;
+ }
+ }
+ }
+
+ // bad workaround (pls fix later maybe)
+ for (Map.Entry<String, JsonElement> stringJsonElementEntry : essenceShopTask.entrySet()) {
+ String key = stringJsonElementEntry.getKey();
+ if (!key.endsWith("_shop")) continue;
+ String name = key.split("_shop")[0].toUpperCase();
+ if (!loreMap.containsKey(name)) {
+ loreMap.put(name, new EssenceShop().setName(name).setCurrent(0));
+ }
+ }
+
+ int total = 0;
+ for (Map.Entry<String, EssenceShop> stringEssenceShopEntry : loreMap.entrySet()) {
+ String key = stringEssenceShopEntry.getKey();
+ EssenceShop value = stringEssenceShopEntry.getValue();
+ value.name = NotEnoughUpdates.INSTANCE.manager
+ .createItemResolutionQuery()
+ .withKnownInternalName(key)
+ .resolveToItemListJson()
+ .get("displayname")
+ .getAsString();
+ value.max = essenceShopTask.get(key.toLowerCase() + "_shop").getAsInt();
+ lore.add(levelPage.buildLore(
+ EnumChatFormatting.getTextWithoutFormattingCodes(value.name),
+ value.current,
+ value.max,
+ false
+ ));
+ total += value.current;
+ }
+
+ levelPage.renderLevelBar(
+ "Essence",
+ NotEnoughUpdates.INSTANCE.manager.createItemResolutionQuery()
+ .withKnownInternalName("ESSENCE_WITHER")
+ .resolveToItemStack(),
+ guiLeft + 299,
+ guiTop + 25,
+ 110,
+ total,
+ total,
+ categoryXp.get("essence_shop_task").getAsInt(),
+ mouseX,
+ mouseY,
+ true,
+ lore
+ );
+ }
+
+ class EssenceShop {
+ String name;
+ double max;
+ double current;
+
+ public EssenceShop setCurrent(double current) {
+ this.current = current;
+ return this;
+ }
+
+ public EssenceShop setName(String name) {
+ this.name = name;
+ return this;
+ }
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/MiscTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/MiscTaskLevel.java
new file mode 100644
index 00000000..a717664d
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/MiscTaskLevel.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2023 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.profileviewer.level.task;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.profileviewer.CrimsonIslePage;
+import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumChatFormatting;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class MiscTaskLevel {
+
+ private final LevelPage levelPage;
+
+ public MiscTaskLevel(LevelPage levelPage) {this.levelPage = levelPage;}
+
+ public void drawTask(JsonObject object, int mouseX, int mouseY, int guiLeft, int guiTop) {
+ JsonObject miscellaneousTask = levelPage.getConstant().getAsJsonObject("miscellaneous_task");
+ // I love doing this on god!!!
+
+ int sbXpAccessoryUpgrade = 0;
+ int sbXpReaperPeppers = 0;
+ int sbXpUnlockedPowers = 0;
+ int sbXpAbiphone = 0;
+ if (object.has("accessory_bag_storage")) {
+ JsonObject accessoryBagStorage = object.getAsJsonObject("accessory_bag_storage");
+
+ sbXpAccessoryUpgrade = Utils.getElementAsInt(Utils.getElement(
+ accessoryBagStorage,
+ "bag_upgrades_purchased"
+ ), 0) * miscellaneousTask.get("accessory_bag_upgrades_xp").getAsInt();
+ sbXpReaperPeppers =
+ miscellaneousTask.get("reaper_peppers_xp").getAsInt() * Utils.getElementAsInt(Utils.getElement(
+ object,
+ "reaper_peppers_eaten"
+ ), 0);
+ if (accessoryBagStorage.has("unlocked_powers")) sbXpUnlockedPowers = accessoryBagStorage.getAsJsonArray(
+ "unlocked_powers").size() * miscellaneousTask.get("unlocking_powers_xp").getAsInt();
+ }
+
+ int sbXpDojo = 0;
+ if (object.has("nether_island_player_data")) {
+ JsonObject netherIslandPlayerData = object.getAsJsonObject("nether_island_player_data");
+ if (netherIslandPlayerData.has("dojo")) {
+ JsonObject dojoScoresObj = netherIslandPlayerData.getAsJsonObject("dojo");
+
+ int pointsTotal = 0;
+ for (int i = 0; i < CrimsonIslePage.apiDojoTestNames.size(); i++) {
+ for (Map.Entry<String, JsonElement> dojoData : dojoScoresObj.entrySet()) {
+ if (dojoData.getKey().equals("dojo_points_" + CrimsonIslePage.apiDojoTestNames.keySet().toArray()[i])) {
+ pointsTotal += dojoData.getValue().getAsInt();
+ }
+ }
+ }
+ int index = getRankIndex(pointsTotal);
+ JsonArray theDojoXp = miscellaneousTask.getAsJsonArray("the_dojo_xp");
+ for (int i = 0; i < index; i++) {
+ sbXpDojo += theDojoXp.get(i).getAsInt();
+ }
+ }
+
+ // abiphone
+ if (netherIslandPlayerData.has("abiphone")) {
+ JsonObject abiphone = netherIslandPlayerData.getAsJsonObject("abiphone");
+ if (abiphone.has("active_contacts")) sbXpAbiphone =
+ abiphone.getAsJsonArray("active_contacts").size() * miscellaneousTask.get("abiphone_contacts_xp").getAsInt();
+ }
+ }
+
+ // harp
+ int sbXpGainedHarp = 0;
+ JsonObject harpSongsNames = miscellaneousTask.get("harp_songs_names").getAsJsonObject();
+ if (object.has("harp_quest")) {
+ JsonObject harpQuest = object.get("harp_quest").getAsJsonObject();
+ for (Map.Entry<String, JsonElement> stringJsonElementEntry : harpSongsNames.entrySet()) {
+ String key = stringJsonElementEntry.getKey();
+ int value = stringJsonElementEntry.getValue().getAsInt();
+ if (harpQuest.has(key)) {
+ sbXpGainedHarp += value;
+ }
+ }
+ }
+
+ // community upgrades
+ int sbXpCommunityUpgrade = 0;
+ JsonObject profileInformation = levelPage.getProfile().getProfileInformation(levelPage.getProfileId());
+ if (profileInformation != null && profileInformation.has("community_upgrades")) {
+ JsonObject communityUpgrades = profileInformation.getAsJsonObject("community_upgrades");
+ JsonArray upgradeStates = communityUpgrades.getAsJsonArray("upgrade_states");
+ JsonObject communityShopUpgradesMax = miscellaneousTask.getAsJsonObject("community_shop_upgrades_max");
+
+ int communityShopUpgradesXp = miscellaneousTask.get("community_shop_upgrades_xp").getAsInt();
+
+ for (
+ JsonElement upgradeState : upgradeStates) {
+ if (!upgradeState.isJsonObject()) continue;
+ JsonObject value = upgradeState.getAsJsonObject();
+ String upgrade = value.get("upgrade").getAsString();
+ int tier = value.get("tier").getAsInt();
+ if (communityShopUpgradesMax.has(upgrade)) {
+ int max = communityShopUpgradesMax.get(upgrade).getAsInt();
+ if (max >= tier) {
+ sbXpCommunityUpgrade += communityShopUpgradesXp;
+ }
+ }
+ }
+ }
+
+ // personal bank
+ int sbXpPersonalBank = 0;
+ if (object.has("personal_bank_upgrade")) {
+ int personalBankUpgrade = object.get("personal_bank_upgrade").getAsInt();
+ JsonArray personalBankUpgradesXpArr = miscellaneousTask.getAsJsonArray("personal_bank_upgrades_xp");
+ for (int i = 1; i <= personalBankUpgrade; i++) {
+ sbXpPersonalBank += personalBankUpgradesXpArr.get(i - 1).getAsInt();
+ }
+ }
+
+ List<String> lore = new ArrayList<>();
+
+ lore.add(levelPage.buildLore("Accessory Bag Upgrades",
+ sbXpAccessoryUpgrade, 0, true
+ ));
+ lore.add(levelPage.buildLore("Reaper Peppers",
+ sbXpReaperPeppers, miscellaneousTask.get("reaper_peppers").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore("Unlocking Powers",
+ sbXpUnlockedPowers, 0, true
+ ));
+ lore.add(levelPage.buildLore("The Dojo",
+ sbXpDojo, miscellaneousTask.get("the_dojo").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore(
+ EnumChatFormatting.ITALIC + "Harp Songs",
+ sbXpGainedHarp, miscellaneousTask.get("harp_songs").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore(EnumChatFormatting.ITALIC + "Abiphone Contacts",
+ sbXpAbiphone, miscellaneousTask.get("abiphone_contacts").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore("Community Shop Upgrades",
+ sbXpCommunityUpgrade, miscellaneousTask.get("community_shop_upgrades").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore("Personal Bank Upgrades",
+ sbXpPersonalBank, miscellaneousTask.get("personal_bank_upgrades").getAsInt(), false
+ ));
+
+ levelPage.renderLevelBar(
+ "Misc. Task",
+ new ItemStack(Items.map),
+ guiLeft + 299,
+ guiTop + 55,
+ 110,
+ 0,
+ sbXpReaperPeppers + sbXpDojo + sbXpGainedHarp + sbXpAbiphone +
+ sbXpCommunityUpgrade + sbXpPersonalBank,
+ levelPage.getConstant().getAsJsonObject("category_xp").get("miscellaneous_task").getAsInt(),
+ mouseX,
+ mouseY,
+ true,
+ lore
+ );
+
+ }
+
+ private int getRankIndex(int pointsTotal) {
+ AtomicInteger index = new AtomicInteger();
+ CrimsonIslePage.dojoPointsToRank.forEach((required, name) -> {
+ if (pointsTotal > required) {
+ index.getAndIncrement();
+ }
+ });
+ return index.get();
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SkillRelatedTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SkillRelatedTaskLevel.java
new file mode 100644
index 00000000..4ba7951c
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SkillRelatedTaskLevel.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2023 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.profileviewer.level.task;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
+import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage;
+import io.github.moulberry.notenoughupdates.util.Constants;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class SkillRelatedTaskLevel {
+
+ private final LevelPage levelPage;
+
+ public SkillRelatedTaskLevel(LevelPage levelPage) {this.levelPage = levelPage;}
+
+ public void drawTask(JsonObject object, int mouseX, int mouseY, int guiLeft, int guiTop) {
+ JsonObject skillRelatedTask = levelPage.getConstant().get("skill_related_task").getAsJsonObject();
+ JsonObject miningObj = skillRelatedTask.get("mining").getAsJsonObject();
+
+ float mithrilPowder = Utils.getElementAsFloat(Utils.getElement(object, "mining_core.powder_mithril"), 0);
+ float gemstonePowder = Utils.getElementAsFloat(Utils.getElement(object, "mining_core.powder_gemstone"), 0);
+ float mithril = Utils.getElementAsFloat(Utils.getElement(object, "mining_core.powder_spent_mithril"), 0) +
+ mithrilPowder;
+ float gemstone = (Utils.getElementAsFloat(Utils.getElement(object, "mining_core.powder_spent_gemstone"), 0)) +
+ gemstonePowder;
+
+ float hotmXp = Utils.getElementAsFloat(Utils.getElement(object, "mining_core.experience"), 0);
+ ProfileViewer.Level levelObjHotm =
+ ProfileViewer.getLevel(
+ Utils.getElementOrDefault(Constants.LEVELING, "HOTM", new JsonArray()).getAsJsonArray(),
+ hotmXp,
+ 7,
+ false
+ );
+
+ int hotmXP = 0;
+ float level = levelObjHotm.level;
+ JsonArray hotmXpArray = miningObj.get("hotm_xp").getAsJsonArray();
+ for (int i = 1; i <= level; i++) {
+ hotmXP += hotmXpArray.get(i - 1).getAsInt();
+ }
+
+ int gainByFirstMithrilThing;
+ if (mithril >= 350_000) {
+ gainByFirstMithrilThing = (int) (350000 / 2400d);
+ mithril -= 350_000;
+ } else {
+ gainByFirstMithrilThing = (int) (mithril / 2400d);
+ mithril = 0;
+ }
+
+ int gainByFirstGemstoneThing;
+ if (gemstone >= 350_000) {
+ gainByFirstGemstoneThing = (int) (350_000 / 2500d);
+ gemstone -= 350_000;
+ } else {
+ gainByFirstGemstoneThing = (int) (gemstone / 2500d);
+ gemstone = 0;
+ }
+
+ int sbXpMithrilPowder = (int) powder(3.75, mithril, 12_500_000);
+ int sbXpGemstonePowder = (int) powder(4.25, gemstone, 20_000_000);
+
+ double sbXpHotmTier =
+ (sbXpMithrilPowder + gainByFirstMithrilThing) + (sbXpGemstonePowder + gainByFirstGemstoneThing)
+ + hotmXP;
+
+ int sbXpPotmTier = 0;
+ JsonArray potmXpArray = miningObj.get("potm_xp").getAsJsonArray();
+
+ int potm = ((Utils.getElementAsInt(Utils.getElement(object, "mining_core.nodes.special_0"), 0)));
+ for (int i = 1; i <= potm; i++) {
+ sbXpPotmTier += potmXpArray.get(i - 1).getAsInt();
+ }
+
+ int sbXpCommissionMilestone = 0;
+ JsonArray tutorialArray = object.get("tutorial").getAsJsonArray();
+ JsonArray commissionMilestoneXpArray = miningObj.get("commission_milestone_xp").getAsJsonArray();
+ for (JsonElement jsonElement : tutorialArray) {
+ if (jsonElement.getAsJsonPrimitive().isString() && jsonElement.getAsString().startsWith(
+ "commission_milestone_reward_skyblock_xp_tier"))
+ for (int i = 1; i <= commissionMilestoneXpArray.size(); i++) {
+ int value = commissionMilestoneXpArray.get(i - 1).getAsInt();
+ if (jsonElement.getAsString().equals("commission_milestone_reward_skyblock_xp_tier_" + i)) {
+ sbXpCommissionMilestone += value;
+ }
+ }
+ }
+
+ // rock mines
+ float pet_milestone_ores_mined = Utils.getElementAsFloat(Utils.getElement(
+ object,
+ "stats.pet_milestone_ores_mined"
+ ), 0);
+
+ int sbXpRockPet = 0;
+ int rockMilestoneXp = miningObj.get("rock_milestone_xp").getAsInt();
+ JsonArray rockMilestoneRequired = miningObj.get("rock_milestone_required").getAsJsonArray();
+ for (JsonElement jsonElement : rockMilestoneRequired) {
+ int value = jsonElement.getAsInt();
+ if (pet_milestone_ores_mined >= value) {
+ sbXpRockPet += rockMilestoneXp;
+ }
+ }
+
+ // farming
+ JsonObject farmingObj = skillRelatedTask.get("farming").getAsJsonObject();
+ int anitaShopUpgradesXp = farmingObj.get("anita_shop_upgrades_xp").getAsInt();
+ int doubleDrops = Utils.getElementAsInt(Utils.getElement(object, "jacob2.perks.double_drops"), 0);
+ int farmingLevelCap = Utils.getElementAsInt(Utils.getElement(object, "jacob2.perks.farming_level_cap"), 0);
+
+ int sbXpGainedByAnita = (doubleDrops + farmingLevelCap) * anitaShopUpgradesXp;
+
+ // fishing
+ int sbXpTrophyFish = 0;
+ JsonObject fishingObj = skillRelatedTask.get("fishing").getAsJsonObject();
+
+ JsonArray trophyFishXpArr = fishingObj.get("trophy_fish_xp").getAsJsonArray();
+ if (object.has("trophy_fish")) {
+
+ JsonObject trophyFish = object.get("trophy_fish").getAsJsonObject();
+ for (Map.Entry<String, JsonElement> stringJsonElementEntry : trophyFish.entrySet()) {
+ String key = stringJsonElementEntry.getKey();
+ if (stringJsonElementEntry.getValue().isJsonPrimitive()) {
+ if (key.endsWith("_bronze")) sbXpTrophyFish += trophyFishXpArr.get(0).getAsInt();
+ if (key.endsWith("_silver")) sbXpTrophyFish += trophyFishXpArr.get(1).getAsInt();
+ if (key.endsWith("_gold")) sbXpTrophyFish += trophyFishXpArr.get(2).getAsInt();
+ if (key.endsWith("_diamond")) sbXpTrophyFish += trophyFishXpArr.get(3).getAsInt();
+ }
+ }
+
+ }
+ float petMilestoneKilled = Utils.getElementAsFloat(
+ Utils.getElement(object, "stats.pet_milestone_sea_creatures_killed"),
+ 0
+ );
+
+ int sbXpDolphinPet = 0;
+ int dolphinMilestoneXp = fishingObj.get("dolphin_milestone_xp").getAsInt();
+ JsonArray dolphinMilestoneRequired = fishingObj.get("dolphin_milestone_required").getAsJsonArray();
+ for (JsonElement jsonElement : dolphinMilestoneRequired) {
+ int value = jsonElement.getAsInt();
+ if (petMilestoneKilled >= value) {
+ sbXpDolphinPet += dolphinMilestoneXp;
+ }
+ }
+
+ List<String> lore = new ArrayList<>();
+ lore.add(levelPage.buildLore("Heart of the Mountain", sbXpHotmTier, miningObj.get("hotm").getAsInt(), false));
+ lore.add(levelPage.buildLore(
+ "Commission Milestones",
+ sbXpCommissionMilestone,
+ miningObj.get("commission_milestone").getAsInt(),
+ false
+ ));
+ lore.add(levelPage.buildLore("Crystal Nucleus", 0, 0, false));
+ lore.add(levelPage.buildLore(
+ "Anita's Shop Upgrade",
+ sbXpGainedByAnita,
+ farmingObj.get("anita_shop_upgrades").getAsInt(),
+ false
+ ));
+ lore.add(levelPage.buildLore("Peak of the Mountain", sbXpPotmTier, miningObj.get("potm").getAsInt(), false));
+ lore.add(levelPage.buildLore("Trophy Fish", sbXpTrophyFish, fishingObj.get("trophy_fish").getAsInt(), false));
+ lore.add(levelPage.buildLore("Rock Milestone", sbXpRockPet, miningObj.get("rock_milestone").getAsInt(), false));
+ lore.add(levelPage.buildLore(
+ "Dolphin Milestone",
+ sbXpDolphinPet,
+ fishingObj.get("dolphin_milestone").getAsInt(),
+ false
+ ));
+
+ levelPage.renderLevelBar(
+ "Skill Related Task",
+ new ItemStack(Items.diamond_sword),
+ guiLeft + 23,
+ guiTop + 115,
+ 110,
+ 0,
+ sbXpHotmTier + sbXpCommissionMilestone + sbXpGainedByAnita + sbXpPotmTier + sbXpTrophyFish + sbXpRockPet +
+ sbXpDolphinPet,
+ levelPage.getConstant().getAsJsonObject("category_xp").get("skill_related_task").getAsInt(),
+ mouseX,
+ mouseY,
+ true,
+ lore
+ );
+ }
+
+ private static double powder(double multiplier, float left, int CAP) {
+ double cons = 1758267;
+ if (left <= 0) return 0;
+
+ left = Math.min(CAP, left);
+
+ return multiplier * (Math.sqrt(1 + 8 * (Math.sqrt((cons / CAP) * left + 9))) - 3);
+ }
+
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SlayingTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SlayingTaskLevel.java
new file mode 100644
index 00000000..3aded435
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SlayingTaskLevel.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2023 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.profileviewer.level.task;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.profileviewer.CrimsonIslePage;
+import io.github.moulberry.notenoughupdates.profileviewer.ExtraPage;
+import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer;
+import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
+import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class SlayingTaskLevel {
+
+ private final LevelPage levelPage;
+ private final int[] bossLow = {25, 50, 100, 150, 250, 1000};
+ private final int[] thorn = {25, 50, 150, 250, 400, 1000};
+ private final int[] bossHigh = {50, 100, 150, 250, 500, 750, 1000};
+
+
+ public SlayingTaskLevel(LevelPage levelPage) {this.levelPage = levelPage;}
+
+ public void drawTask(JsonObject object, int mouseX, int mouseY, int guiLeft, int guiTop) {
+ // slayer
+ JsonObject slayingTask = levelPage.getConstant().get("slaying_task").getAsJsonObject();
+ JsonArray slayerLevelUpXp = slayingTask.get("slayer_level_up_xp").getAsJsonArray();
+ Map<String, ProfileViewer.Level> skyblockInfo = levelPage.getProfile().getSkyblockInfo(levelPage.getProfileId());
+
+ int sbXpGainedSlayer = 0;
+ if (skyblockInfo != null) {
+ for (String slayer : ProfileViewer.SLAYERS) {
+ ProfileViewer.Level level = skyblockInfo.get(slayer);
+ for (int i = 0; i < (int) level.level; i++) {
+ int asInt = slayerLevelUpXp.get(i).getAsInt();
+ sbXpGainedSlayer += asInt;
+ }
+ }
+ }
+
+ JsonObject bossCollectionsXp = slayingTask.getAsJsonObject("boss_collections_xp");
+
+ HashMap<String, Double> allComps = new HashMap<>();
+ JsonElement normalCompletions = Utils
+ .getElement(object, "dungeons.dungeon_types.catacombs.tier_completions");
+
+ JsonElement masterCompletions = Utils
+ .getElement(object, "dungeons.dungeon_types.master_catacombs.tier_completions");
+
+ if (normalCompletions != null) {
+ HashMap<String, Double> normalCompMap = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(
+ normalCompletions.getAsJsonObject(),
+ HashMap.class
+ );
+ normalCompMap.forEach((floor, value) -> {
+ if (allComps.containsKey(floor)) {
+ allComps.put(floor, allComps.get(floor) + value);
+ } else {
+ allComps.put(floor, value);
+ }
+ });
+ }
+ if (masterCompletions != null) {
+ HashMap<String, Double> masterCompMap = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(
+ masterCompletions.getAsJsonObject(),
+ HashMap.class
+ );
+
+ masterCompMap.forEach((floor, value) -> {
+ if (allComps.containsKey(floor)) {
+ allComps.put(floor, allComps.get(floor) + value);
+ } else {
+ allComps.put(floor, value);
+ }
+ });
+ }
+ // THIS SERVER IS AWESOME I LOVE CONSISTENCY!!!!!!!
+
+ int bossCollectionXp = 0;
+ JsonArray dungeonCollectionXp = bossCollectionsXp.getAsJsonArray("dungeon_collection_xp");
+ for (int i = 1; i <= 7; i++) {
+ if (!allComps.containsKey(i + "")) continue;
+ double value = allComps.get(i + "");
+ switch (i) {
+ case 1:
+ case 2:
+ case 3:
+ bossCollectionXp += loopThroughCollection(bossLow, value, dungeonCollectionXp);
+ break;
+ case 4:
+ bossCollectionXp += loopThroughCollection(thorn, value, dungeonCollectionXp);
+ break;
+ case 5:
+ case 6:
+ case 7:
+ bossCollectionXp += loopThroughCollection(bossHigh, value, dungeonCollectionXp);
+ break;
+ }
+ }
+
+ JsonArray defeatKuudraXp = slayingTask.get("defeat_kuudra_xp").getAsJsonArray();
+ // kuudra
+
+ int sbXpDefeatKuudra = 0;
+
+ int kuudraBossCollection = 0;
+ if (object.has("nether_island_player_data")) {
+ JsonObject jsonObject = object.getAsJsonObject("nether_island_player_data").getAsJsonObject(
+ "kuudra_completed_tiers");
+ for (Map.Entry<String, JsonElement> stringJsonElementEntry : jsonObject.entrySet()) {
+ String key = stringJsonElementEntry.getKey();
+ int value = stringJsonElementEntry.getValue().getAsInt();
+
+ int i = 0;
+ for (String kuudraTier : CrimsonIslePage.KUUDRA_TIERS) {
+ if (key.equals(kuudraTier)) {
+ sbXpDefeatKuudra += defeatKuudraXp.get(i).getAsInt();
+ kuudraBossCollection += (i + 1) * value;
+ }
+ i++;
+ }
+ }
+ if (kuudraBossCollection >= 10) bossCollectionXp += 10;
+ if (kuudraBossCollection >= 100) bossCollectionXp += 15;
+ if (kuudraBossCollection >= 500) bossCollectionXp += 20;
+ if (kuudraBossCollection >= 2000) bossCollectionXp += 25;
+ if (kuudraBossCollection >= 5000) bossCollectionXp += 30;
+ }
+
+ int sbXpBestiary = 0;
+ int bestiaryTiers = GuiProfileViewer.getProfile().getBestiaryTiers(object);
+ sbXpBestiary += bestiaryTiers;
+ sbXpBestiary = sbXpBestiary + (sbXpBestiary / 10) * 2;
+
+ int mythologicalKillsXp = 0;
+ if (object.has("stats")) {
+ JsonObject stats = object.get("stats").getAsJsonObject();
+ if (stats.has("mythos_kills")) mythologicalKillsXp += (stats.get("mythos_kills").getAsLong() / 100);
+ }
+
+ int mythologicalKillsMax = slayingTask.get("mythological_kills").getAsInt();
+ if (mythologicalKillsXp > mythologicalKillsMax) mythologicalKillsXp = mythologicalKillsMax;
+
+ // dragons
+ int sbXpFromDragonKills = 0;
+ JsonObject slayDragonsXp = slayingTask.getAsJsonObject("slay_dragons_xp");
+ for (Map.Entry<String, JsonElement> stringJsonElementEntry : slayDragonsXp.entrySet()) {
+ String key = stringJsonElementEntry.getKey();
+ int value = stringJsonElementEntry.getValue().getAsInt();
+ // kills_superior_dragon_100
+ float element = Utils.getElementAsFloat(Utils.getElement(object, "bestiary.kills_" + key + "_100"), 0);
+ if (element > 0) {
+ sbXpFromDragonKills += value;
+ }
+ }
+
+ // slayer kills
+ int sbXpFromSlayerDefeat = 0;
+
+ JsonArray defeatSlayersXp = slayingTask.get("defeat_slayers_xp").getAsJsonArray();
+ for (String s : ExtraPage.slayers.keySet()) {
+ int maxLevel = ExtraPage.slayers.get(s);
+ for (int i = 0; i < 5; i++) {
+ if (i >= maxLevel) break;
+ float tier = Utils.getElementAsFloat(
+ Utils.getElement(object, "slayer_bosses." + s + ".boss_kills_tier_" + i),
+ 0
+ );
+ if (tier != 0) {
+ int value = defeatSlayersXp.get(i).getAsInt();
+ sbXpFromSlayerDefeat += value;
+ }
+ }
+ }
+
+ // arachne
+ JsonArray defeatArachneXp = slayingTask.get("defeat_arachne_xp").getAsJsonArray();
+ int sbXpGainedArachne = 0;
+
+ JsonElement tier1 = Utils.getElement(object, "bestiary.kills_arachne_300");
+ if (tier1 != null) {
+ sbXpGainedArachne += defeatArachneXp.get(0).getAsInt();
+ }
+
+ JsonElement tier2 = Utils.getElement(object, "bestiary.kills_arachne_500");
+ if (tier2 != null) {
+ sbXpGainedArachne += defeatArachneXp.get(1).getAsInt();
+ }
+
+ List<String> lore = new ArrayList<>();
+
+ int slayerLevelUpMax = slayingTask.get("slayer_level_up").getAsInt();
+ int bossCollectionsMax = slayingTask.get("boss_collections").getAsInt();
+ int slayDragonsMax = slayingTask.get("slay_dragons").getAsInt();
+ int defeatSlayersMax = slayingTask.get("defeat_slayers").getAsInt();
+ int defeatKuudraMax = slayingTask.get("defeat_kuudra").getAsInt();
+ int defeatArachneMax = slayingTask.get("defeat_arachne").getAsInt();
+
+ lore.add(levelPage.buildLore("Slayer Level Up", sbXpGainedSlayer, slayerLevelUpMax, false));
+ lore.add(levelPage.buildLore("Boss Collections", bossCollectionXp, bossCollectionsMax, false));
+ lore.add(levelPage.buildLore("Bestiary Progress", sbXpBestiary, 0, true));
+ lore.add(levelPage.buildLore("Mythological Kills", mythologicalKillsXp, mythologicalKillsMax, false));
+ lore.add(levelPage.buildLore("Slay Dragons", sbXpFromDragonKills, slayDragonsMax, false));
+ lore.add(levelPage.buildLore("Defeat Slayers", sbXpFromSlayerDefeat, defeatSlayersMax, false));
+ lore.add(levelPage.buildLore("Defeat Kuudra", sbXpDefeatKuudra, defeatKuudraMax, false));
+ lore.add(levelPage.buildLore("Defeat Arachne", sbXpGainedArachne, defeatArachneMax, false));
+
+ int slayingTaskMax = levelPage.getConstant().getAsJsonObject("category_xp").get("slaying_task").getAsInt();
+
+ levelPage.renderLevelBar(
+ "Slaying Task",
+ new ItemStack(Items.golden_sword),
+ guiLeft + 23,
+ guiTop + 85,
+ 110,
+ 0, sbXpGainedSlayer + bossCollectionXp + mythologicalKillsXp +
+ sbXpFromDragonKills + sbXpFromSlayerDefeat + sbXpDefeatKuudra + sbXpGainedArachne,
+ slayingTaskMax,
+ mouseX,
+ mouseY,
+ true,
+ lore
+ );
+ }
+
+ private int loopThroughCollection(int[] array, double value, JsonArray jsonArray) {
+ int i = 0;
+ int gain = 0;
+ for (int bossReq : array) {
+ if (value >= bossReq) {
+ int gained = jsonArray.get(i).getAsInt();
+ gain += gained;
+ }
+ i++;
+ }
+ return gain;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/StoryTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/StoryTaskLevel.java
new file mode 100644
index 00000000..2b1b59cb
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/StoryTaskLevel.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2023 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.profileviewer.level.task;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class StoryTaskLevel {
+
+ private final LevelPage levelPage;
+
+ public StoryTaskLevel(LevelPage levelPage) {this.levelPage = levelPage;}
+
+ public void drawTask(JsonObject object, int mouseX, int mouseY, int guiLeft, int guiTop) {
+ JsonObject storyTask = levelPage.getConstant().getAsJsonObject("story_task");
+ JsonArray storyTaskNames = storyTask.getAsJsonArray("complete_objectives_names");
+
+ JsonObject objectives = object.getAsJsonObject("objectives");
+
+ int storyTaskXp = storyTask.get("complete_objectives_xp").getAsInt();
+ int sbXpStory = 0;
+ for (JsonElement storyTaskName : storyTaskNames) {
+ String value = storyTaskName.getAsString();
+ if (objectives.has(value)) {
+ JsonObject jsonObject = objectives.get(value).getAsJsonObject();
+ if (jsonObject.has("status") && jsonObject.get("status").getAsString().equals("COMPLETE")) {
+ sbXpStory += storyTaskXp;
+ }
+ }
+ }
+
+ List<String> lore = new ArrayList<>();
+ lore.add(levelPage.buildLore("Complete Objectives",
+ sbXpStory, storyTask.get("complete_objectives").getAsInt(), false
+ ));
+
+ levelPage.renderLevelBar(
+ "Story Task",
+ new ItemStack(Items.map),
+ guiLeft + 299,
+ guiTop + 85,
+ 110,
+ 0,
+ sbXpStory,
+ levelPage.getConstant().getAsJsonObject("category_xp").get("story_task").getAsInt(),
+ mouseX,
+ mouseY,
+ true,
+ lore
+ );
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingOverlay.java
index 004ea372..bd45f3e1 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingOverlay.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.recipes;
import io.github.moulberry.notenoughupdates.NEUManager;
+import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers;
import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
@@ -114,6 +115,8 @@ public class CraftingOverlay {
if (!Keyboard.getEventKeyState() ||
(Keyboard.getEventKey() != Keyboard.KEY_U && Keyboard.getEventKey() != Keyboard.KEY_R))
return;
+ if (EnchantingSolvers.currentSolver != EnchantingSolvers.SolverType.NONE) return;
+
runIfCraftingOverlayIsPresent(event.gui, (guiChest, chest) -> {
int mouseX = Utils.getMouseX();
int mouseY = Utils.getMouseY();
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 0105ba1f..6819ccc4 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java
@@ -30,6 +30,7 @@ import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent;
import io.github.moulberry.notenoughupdates.recipes.EssenceUpgrades;
import io.github.moulberry.notenoughupdates.recipes.NeuRecipe;
@@ -40,7 +41,9 @@ import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Pattern;
+@NEUAutoSubscribe
public class Constants {
+
private static class PatternSerializer implements JsonDeserializer<Pattern>, JsonSerializer<Pattern> {
@Override
public Pattern deserialize(
@@ -78,6 +81,7 @@ public class Constants {
public static JsonObject RNGSCORE;
public static JsonObject ABIPHONE;
public static JsonObject ESSENCESHOPS;
+ public static JsonObject SBLEVELS;
private static final ReentrantLock lock = new ReentrantLock();
@@ -102,6 +106,7 @@ public class Constants {
RNGSCORE = Utils.getConstant("rngscore", gson);
ABIPHONE = Utils.getConstant("abiphone", gson);
ESSENCESHOPS = Utils.getConstant("essenceshops", gson);
+ SBLEVELS = Utils.getConstant("sblevels", gson);
parseEssenceCosts();
} catch (Exception ex) {
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 bc44f656..f8f42b80 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java
@@ -287,16 +287,20 @@ public class ItemUtils {
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 (heldItemJson == null) {
+ petItemLore.add(EnumChatFormatting.RED + "Could not find held item in repo!");
+ } else {
+ 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;
+ }
}
}
}
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 ec7ec404..8ce765aa 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java
@@ -22,6 +22,7 @@ package io.github.moulberry.notenoughupdates.util;
import com.google.common.reflect.TypeToken;
import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.listener.ScoreboardLocationChangeListener;
import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent;
import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager;
@@ -65,6 +66,7 @@ import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+@NEUAutoSubscribe
public class SBInfo {
private static final SBInfo INSTANCE = new SBInfo();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/TitleUtil.java b/src/main/java/io/github/moulberry/notenoughupdates/util/TitleUtil.java
index 59db7cac..71b4e8dc 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/TitleUtil.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/TitleUtil.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.util;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.GlStateManager;
@@ -27,6 +28,7 @@ import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+@NEUAutoSubscribe
public class TitleUtil {
private static final TitleUtil INSTANCE = new TitleUtil();
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 571a43f9..952eb50f 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
@@ -28,6 +28,7 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking;
+import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord;
@@ -569,6 +570,70 @@ public class Utils {
drawTexturedRect(x, y, width, height, 0, 1, 0, 1);
}
+ public static void drawPvSideButton(
+ int yIndex,
+ ItemStack itemStack,
+ boolean pressed,
+ GuiProfileViewer guiProfileViewer
+ ) {
+ int guiLeft = GuiProfileViewer.getGuiLeft();
+ int guiTop = GuiProfileViewer.getGuiTop();
+
+ GlStateManager.disableLighting();
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.enableAlpha();
+ GlStateManager.alphaFunc(516, 0.1F);
+
+ int x = guiLeft - 28;
+ int y = guiTop + yIndex * 28;
+
+ float uMin = 193 / 256f;
+ float uMax = 223 / 256f;
+ float vMin = 200 / 256f;
+ float vMax = 228 / 256f;
+ if (pressed) {
+ uMin = 224 / 256f;
+ uMax = 1f;
+
+ if (yIndex != 0) {
+ vMin = 228 / 256f;
+ vMax = 1f;
+ }
+
+ guiProfileViewer.renderBlurredBackground(
+ guiProfileViewer.width,
+ guiProfileViewer.height,
+ x + 2,
+ y + 2,
+ 30,
+ 28 - 4
+ );
+ } else {
+ guiProfileViewer.renderBlurredBackground(
+ guiProfileViewer.width,
+ guiProfileViewer.height,
+ x + 2,
+ y + 2,
+ 28 - 2,
+ 28 - 4
+ );
+ }
+
+ GlStateManager.disableLighting();
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.enableAlpha();
+ GlStateManager.alphaFunc(516, 0.1F);
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(GuiProfileViewer.pv_elements);
+
+ Utils.drawTexturedRect(x, y, pressed ? 32 : 28, 28, uMin, uMax, vMin, vMax, GL11.GL_NEAREST);
+
+ GlStateManager.enableDepth();
+ Utils.drawItemStack(itemStack, x + 8, y + 7);
+ }
+
public static void drawTexturedRect(float x, float y, float width, float height, int filter) {
drawTexturedRect(x, y, width, height, 0, 1, 0, 1, filter);
}
@@ -1961,13 +2026,13 @@ public class Utils {
if (NotEnoughUpdates.INSTANCE.config.notifications.outdatedRepo) {
NotificationHandler.displayNotification(Lists.newArrayList(
EnumChatFormatting.RED + EnumChatFormatting.BOLD.toString() + "Missing repo data",
- EnumChatFormatting.RED +
- "Data used for many NEU features is not up to date, this should normally not be the case.",
- EnumChatFormatting.RED + "You can try " + EnumChatFormatting.BOLD + "/neuresetrepo" + EnumChatFormatting.RESET +
- EnumChatFormatting.RED + " and restart your game" +
- " to see if that fixes the issue.",
- EnumChatFormatting.RED + "If the problem persists please join " + EnumChatFormatting.BOLD +
- "discord.gg/moulberry" +
+ EnumChatFormatting.RED +
+ "Data used for many NEU features is not up to date, this should normally not be the case.",
+ EnumChatFormatting.RED + "You can try " + EnumChatFormatting.BOLD + "/neuresetrepo" + EnumChatFormatting.RESET +
+ EnumChatFormatting.RED + " and restart your game" +
+ " to see if that fixes the issue.",
+ EnumChatFormatting.RED + "If the problem persists please join " + EnumChatFormatting.BOLD +
+ "discord.gg/moulberry" +
EnumChatFormatting.RESET + EnumChatFormatting.RED + " and message in " + EnumChatFormatting.BOLD +
"#neu-support" + EnumChatFormatting.RESET + EnumChatFormatting.RED + " to get support"
),
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 81eea343..94bfbee8 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/XPInformation.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/XPInformation.java
@@ -22,6 +22,7 @@ package io.github.moulberry.notenoughupdates.util;
import com.google.common.base.Splitter;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
import net.minecraftforge.client.event.ClientChatReceivedEvent;
@@ -34,6 +35,7 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+@NEUAutoSubscribe
public class XPInformation {
private static final XPInformation INSTANCE = new XPInformation();
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/EnforcedConfigValues.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/EnforcedConfigValues.kt
new file mode 100644
index 00000000..7351a4a0
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/EnforcedConfigValues.kt
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2022 Linnea Gräf
+ *
+ * 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.JsonElement
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe
+import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent
+import io.github.moulberry.notenoughupdates.util.NotificationHandler
+import io.github.moulberry.notenoughupdates.util.Shimmy
+import io.github.moulberry.notenoughupdates.util.Utils
+import io.github.moulberry.notenoughupdates.util.kotlin.fromJson
+import net.minecraft.client.Minecraft
+import net.minecraftforge.client.event.GuiOpenEvent
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import net.minecraftforge.fml.common.gameevent.TickEvent
+
+@NEUAutoSubscribe
+object EnforcedConfigValues {
+
+ class EnforcedValue {
+ // lateinit var because we use gson (instead of kotlinx.serialization which can handle data classes)
+ lateinit var path: String
+ lateinit var value: JsonElement
+ }
+
+ class EnforcedValueData {
+ var enforcedValues: List<EnforcedValue> = listOf()
+ var notificationPSA: List<String>? = null
+ var chatPSA: List<String>? = null
+ lateinit var affectedVersions: List<Int>
+ }
+
+
+ var enforcedValues: List<EnforcedValueData> = listOf()
+
+ @SubscribeEvent
+ fun onRepoReload(event: RepositoryReloadEvent) {
+ val fixedValues = event.repositoryRoot.resolve("enforced_values")
+ enforcedValues = if (fixedValues.exists()) {
+ fixedValues.listFiles()
+ .filter {
+ it != null && it.isFile && it.canRead()
+ }
+ .map {
+ NotEnoughUpdates.INSTANCE.manager.gson.fromJson<EnforcedValueData>(it.readText())
+ }.filter {
+ NotEnoughUpdates.VERSION_ID in it.affectedVersions
+ }
+ } else {
+ listOf()
+ }
+ if (!event.isFirstLoad)
+ sendPSAs()
+ }
+
+ @SubscribeEvent
+ fun onGuiClose(event: GuiOpenEvent) {
+ enforceOntoConfig(NotEnoughUpdates.INSTANCE.config ?: return)
+ }
+
+ var hasSentPSAsOnce = false
+
+ @SubscribeEvent
+ fun onTick(tickEvent: TickEvent.ClientTickEvent) {
+ if (hasSentPSAsOnce || Minecraft.getMinecraft().thePlayer == null || !NotEnoughUpdates.INSTANCE.isOnSkyblock) return
+ hasSentPSAsOnce = true
+ sendPSAs()
+ enforceOntoConfig(NotEnoughUpdates.INSTANCE.config ?: return)
+ }
+
+ fun sendPSAs() {
+ val notification = enforcedValues.flatMap { it.notificationPSA ?: emptyList() }
+ if (notification.isNotEmpty()) {
+ NotificationHandler.displayNotification(notification, true)
+ }
+ val chat = enforcedValues.flatMap { it.chatPSA ?: emptyList() }
+ if (chat.isNotEmpty()) {
+ for (line in chat) {
+ Utils.addChatMessage(line)
+ }
+ }
+ }
+
+
+ fun enforceOntoConfig(config: Any) {
+ for (enforcedValue in enforcedValues.flatMap { it.enforcedValues }) {
+ val shimmy = Shimmy.makeShimmy(config, enforcedValue.path.split("."))
+ if (shimmy == null) {
+ println("Could not create shimmy for path ${enforcedValue.path}")
+ continue
+ }
+ val currentValue = shimmy.getJson()
+ if (currentValue != enforcedValue.value) {
+ println("Resetting ${enforcedValue.path} to ${enforcedValue.value} from $currentValue")
+ shimmy.setJson(enforcedValue.value)
+ }
+ }
+ }
+
+ fun isBlockedFromEditing(optionPath: String): Boolean {
+ return enforcedValues.flatMap { it.enforcedValues }.any { it.path == optionPath }
+ }
+
+
+}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumCheapestItemOverlay.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumCheapestItemOverlay.kt
index 7485f14d..ccaf5ad8 100644
--- a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumCheapestItemOverlay.kt
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumCheapestItemOverlay.kt
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures.inventory
import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe
import io.github.moulberry.notenoughupdates.core.util.ArrowPagesUtils
import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer
import io.github.moulberry.notenoughupdates.util.MuseumUtil
@@ -39,7 +40,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import org.lwjgl.input.Mouse
import org.lwjgl.opengl.GL11
-
+@NEUAutoSubscribe
object MuseumCheapestItemOverlay {
data class MuseumItem(
var name: String,
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumItemHighlighter.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumItemHighlighter.kt
index b809ee9f..945449ba 100644
--- a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumItemHighlighter.kt
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumItemHighlighter.kt
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures.inventory
import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe
import io.github.moulberry.notenoughupdates.core.ChromaColour
import io.github.moulberry.notenoughupdates.core.util.StringUtils
import io.github.moulberry.notenoughupdates.events.GuiContainerBackgroundDrawnEvent
@@ -37,6 +38,7 @@ import net.minecraft.item.EnumDyeColor
import net.minecraft.item.ItemStack
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+@NEUAutoSubscribe
object MuseumItemHighlighter {
private val manager get() = NotEnoughUpdates.INSTANCE.manager
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/PetLeveling.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/PetLeveling.kt
index 200aa3fa..99066e52 100644
--- a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/PetLeveling.kt
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/PetLeveling.kt
@@ -23,7 +23,9 @@ import com.google.gson.JsonObject
import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent
import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay.Rarity
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe
+@NEUAutoSubscribe
object PetLeveling {
data class ExpLadder(
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/Shimmy.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/Shimmy.kt
new file mode 100644
index 00000000..37cdd3ac
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/Shimmy.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2022 Linnea Gräf
+ *
+ * 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.JsonElement
+import java.lang.reflect.Field
+
+class Shimmy private constructor(
+ val source: Any,
+ val field: Field,
+) {
+ companion object {
+ val gson = Gson()
+ private fun shimmy(source: Any?, fieldName: String): Any? {
+ if (source == null) return null
+ return try {
+ val declaredField = source.javaClass.getDeclaredField(fieldName)
+ declaredField.isAccessible = true
+ declaredField.get(source)
+ } catch (e: NoSuchFieldException) {
+ null
+ }
+ }
+
+ @JvmStatic
+ fun makeShimmy(source: Any?, path: List<String>): Shimmy? {
+ if (path.isEmpty())
+ return null
+ var source = source
+ for (part in path.dropLast(1)) {
+ source = shimmy(source, part)
+ }
+ if (source == null) return null
+ val lastName = path.last()
+ return try {
+ val field = source.javaClass.getDeclaredField(lastName)
+ field.isAccessible = true
+ Shimmy(
+ source,
+ field,
+ )
+ } catch (e: NoSuchFieldException) {
+ null
+ }
+ }
+
+ }
+
+ val clazz: Class<*> = field.type
+ fun get(): Any? {
+ return field.get(source)
+ }
+
+ fun set(value: Any?) {
+ field.set(source, value)
+ }
+
+ fun getJson(): JsonElement {
+ return gson.toJsonTree(get())
+ }
+
+ fun setJson(element: JsonElement) {
+ set(gson.fromJson(element, clazz))
+ }
+
+
+}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/hypixelapi/Collection.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/hypixelapi/Collection.kt
new file mode 100644
index 00000000..b2c7fcec
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/hypixelapi/Collection.kt
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2023 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.hypixelapi
+
+import com.google.gson.JsonArray
+import com.google.gson.JsonObject
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+import java.math.BigInteger
+import java.util.concurrent.CompletableFuture
+import kotlin.collections.List
+import kotlin.collections.Map
+import kotlin.collections.component1
+import kotlin.collections.component2
+import kotlin.collections.filter
+import kotlin.collections.flatMap
+import kotlin.collections.groupBy
+import kotlin.collections.mapNotNull
+import kotlin.collections.mapValues
+import kotlin.collections.maxOf
+import kotlin.collections.sumOf
+import kotlin.collections.toList
+import kotlin.collections.toMap
+import kotlin.collections.toSet
+
+data class ProfileCollectionInfo(
+ val collections: Map<String, CollectionInfo>,
+ val craftedGenerators: Map<String, Int>,
+) {
+ data class CollectionInfo(
+ val collection: Collection,
+ val totalCollectionCount: BigInteger,
+ val personalCollectionCount: BigInteger,
+ val unlockedTiers: List<CollectionTier>,
+ )
+
+ class CollectionMetadata internal constructor() {
+ lateinit var collections: Map<String, CollectionCategory>
+ private set
+ val allCollections by lazy { collections.values.flatMap { it.items.toList() }.toMap() }
+ }
+
+ class CollectionCategory internal constructor() {
+ lateinit var items: Map<String, Collection>
+ private set
+ }
+
+ class Collection internal constructor() {
+ lateinit var name: String
+ private set
+ var maxTiers: Int = -1
+ private set
+ lateinit var tiers: List<CollectionTier>
+ private set
+
+ override fun toString(): String {
+ return "Collection(name=$name, maxTiers=$maxTiers, tiers=$tiers)"
+ }
+ }
+
+ class CollectionTier internal constructor() {
+ var tier: Int = -1
+ private set
+ var amountRequired: Int = -1
+ private set
+ lateinit var unlocks: List<String>
+ private set
+
+ override fun toString(): String {
+ return "CollectionTier(tier=$tier, amountRequired=$amountRequired, unlocks=$unlocks)"
+ }
+ }
+
+
+ companion object {
+
+
+ val generatorPattern = "^([^0-9]+)_([0-9]+)$".toRegex()
+
+ val hypixelCollectionInfo: CompletableFuture<CollectionMetadata> by lazy {
+ NotEnoughUpdates.INSTANCE.manager.apiUtils
+ .newHypixelApiRequest("resources/skyblock/collections")
+ .requestJson()
+ .thenApply {
+ NotEnoughUpdates.INSTANCE.manager.gson.fromJson(it, CollectionMetadata::class.java)
+ }
+ }
+
+ fun getCollectionData(
+ profileData: JsonObject,
+ mainPlayer: String,
+ collectionData: CollectionMetadata
+ ): ProfileCollectionInfo? {
+ val mainPlayerUUID = mainPlayer.replace("-", "")
+ val members = profileData["members"] as? JsonObject ?: return null
+ val mainPlayerData =
+ (members[mainPlayerUUID] as? JsonObject ?: return null)
+ val mainPlayerCollection = mainPlayerData["collection"] as? JsonObject ?: return null
+ val memberCollections = members.entrySet().mapNotNull { (uuid, data) ->
+ if (data !is JsonObject) return null
+ data["collection"] as? JsonObject
+ }
+ val generators = members.entrySet().mapNotNull { (uuid, data) ->
+ if (data !is JsonObject) return null
+ data["crafted_generators"] as? JsonArray
+ }.flatMap { it.toList() }
+ return ProfileCollectionInfo(
+ collectionData.allCollections.mapValues { (name, collection) ->
+ val totalCollection = memberCollections.sumOf { it[name]?.asBigInteger ?: BigInteger.ZERO }
+ val personalCollection = mainPlayerCollection[name]?.asBigInteger ?: BigInteger.ZERO
+ CollectionInfo(
+ collection,
+ totalCollection,
+ personalCollection,
+ collection.tiers.filter { BigInteger.valueOf(it.amountRequired.toLong()) <= totalCollection }
+ )
+ },
+ generators.toSet()
+ .mapNotNull {
+ val pattern = generatorPattern.matchEntire(it.asString) ?: return@mapNotNull null
+ pattern.groupValues[1] to pattern.groupValues[2].toInt()
+ }
+ .groupBy { it.first }
+ .mapValues {
+ it.value.maxOf { it.second }
+ }
+ .toMap()
+ )
+ }
+
+ /**
+ * This should be the json object returned by /skyblock/profiles at profiles.<somenumber>. (aka the root tag
+ * should contain profile_id, members, cute_name, etc.)
+ */
+ @JvmStatic
+ fun getCollectionData(profileData: JsonObject, mainPlayer: String): CompletableFuture<ProfileCollectionInfo?> {
+ return hypixelCollectionInfo.thenApply {
+ getCollectionData(profileData, mainPlayer, it)
+ }
+ }
+ }
+
+}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/kotlin/gson.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/kotlin/gson.kt
new file mode 100644
index 00000000..00c3d729
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/kotlin/gson.kt
@@ -0,0 +1,33 @@
+/*
+ * 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.kotlin
+
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import java.lang.reflect.Type
+
+
+inline fun <reified T : Any> typeToken(): Type {
+ return (object : TypeToken<T>() {}).type
+}
+
+inline fun <reified T : Any> Gson.fromJson(string: String): T {
+ return fromJson(string, typeToken<T>())
+}
diff --git a/src/main/resources/assets/notenoughupdates/pv_basic.png b/src/main/resources/assets/notenoughupdates/pv_basic.png
index 4d5236f5..de254644 100644
--- a/src/main/resources/assets/notenoughupdates/pv_basic.png
+++ b/src/main/resources/assets/notenoughupdates/pv_basic.png
Binary files differ
diff --git a/src/main/resources/assets/notenoughupdates/pv_levels.png b/src/main/resources/assets/notenoughupdates/pv_levels.png
new file mode 100644
index 00000000..21810476
--- /dev/null
+++ b/src/main/resources/assets/notenoughupdates/pv_levels.png
Binary files differ
diff --git a/src/main/resources/assets/notenoughupdates/textures/gui/config_blocked.png b/src/main/resources/assets/notenoughupdates/textures/gui/config_blocked.png
new file mode 100644
index 00000000..eb60da5f
--- /dev/null
+++ b/src/main/resources/assets/notenoughupdates/textures/gui/config_blocked.png
Binary files differ
diff --git a/src/main/resources/mixins.notenoughupdates.json b/src/main/resources/mixins.notenoughupdates.json
index d080d7f5..8877aed8 100644
--- a/src/main/resources/mixins.notenoughupdates.json
+++ b/src/main/resources/mixins.notenoughupdates.json
@@ -23,6 +23,7 @@
"MixinGuiIngame",
"MixinGuiInventory",
"MixinGuiScreen",
+ "MixinGuiUtils",
"MixinInventoryBasic",
"MixinInventoryEffectRenderer",
"MixinInventoryPlayer",
@@ -55,6 +56,7 @@
"MixinEntityChargedCreeper",
"MixinGuiEditSign",
"MixinGuiTextField",
+ "MixinLayerDeadmau5Head",
"MixinThreadDownloadImageData",
"MixinThreadDownloadImageDataThread"
]